http://sofia-sip.sourceforge.net/refdocs/nua/index.html,翻译自官网的这张网页。
模块元信息
nua模块是一个用户代理库,主要提供基本的SIP用户代理功能。它的功能包括呼叫管理,消息和事件获取。
-
联系人:
- Pekka Pessi < Pekka.Pessi@nokia-email.address.hidden>
-
状态:
- Sofia SIP Core library
-
许可:
- LGPL
-
贡献者:
-
- Pekka Pessi <Pekka.Pessi@nokia-email.address.hidden>
- Pasi Rinne-Rahkola <Pasi.Rinne-Rahkola@nokia-email.address.hidden>
- Kai Vehmanen <Kai.Vehmanen@nokia-email.address.hidden>
- Martti Mela <Martti.Mela@nokia-email.address.hidden>
概述
The NUA API提供给高层应用开发人员一套透明并且完全控制的底层SIP协议引擎。NUA提供的呼叫语义基于nta模块内的事务语义。使用NUA可以创建各类不同的SIP用户代理,例如终端、网关或者MCU。
nua引擎对开发人员而言隐藏了很多底层的信令和媒体管理操作。在一种完全透明的方式下可以使用各类媒体接口。
应用程序和用户代理库内的协议引擎可以分处不同的线程内。协议引擎和应用程序使用事件进行通信,主要通过应用程序提供的回调函数。回调函数在应用程序线程上下文环境下被调用,会向其传递su_root_t对象。
NUA User下的Sofia概念
介绍
Sofia软件包基于一些特定基本的观点和概念。它们中的很多在Sofia工具库(su)内实现,并且针对最重要的操作功能和工具提供统一的接口。
下面这些章节包括创建一个基于NUA库的可工作应用程序的所有概念的描述。对应用程序开发人员而言SU库内以及Sofia软件包其他库内的工具接口都非常有用,但开发人员必须非常小心地使用它们,因为不正确地使用NUA库将会改变Sofia软件包的行为。请至su库查看更多的SU功能细节描述。
事件循环 - root对象
The NUA为事件驱动系统使用了反应器模式(也可以称为发布器模式或通知者模式)。Sofia在编程模型中采用了任务作为基本的执行单元。程序可以要求当一个特定的事件发生时,事件循环调用一个回调函数。事件可以是IO操作,计时器,或者其他任务发来的异步消息。
在应用程序中root对象是一个代表任务的句柄。同样,root对象还可以代表任务的主事件循环。通过root对象,任务代码可访问到它自身的上下文信息以及线程同步特性对象,例如等待对象、定时器和消息。
使用NUA功能的应用程序创建一个root对象,以及一个处理NUA事件的回调函数。可以用su_root_create()函数创建root对象,在nua_create()函数中注册回调函数。
root对象的类型是su_root_t。
请查看<sofia-sip/su_wait.h>和<su_root.c>两个源代码文件获得root对象的更多信息。
请查看nua_event_e章节获得更多的回调函数信息:http://sofia-sip.sourceforge.net/refdocs/nua/nua_8h.html#abca36033336ce16e538a279413d2ca51。
Magic
magic是可以绑定到任何对象的上下文指针术语。主事件循环负责调用回调函数,并且将这个指针传递给回调函数。Sofia栈维持这个上下文信息在通话和回调函数之间。应用程序可以使用上下文用来保存任何需要的信息。
内存处理
当为给定的任务分配很多内存块时,home-based内存管理非常有用。所有的内存分配均通过home内存,它维护着所有已分配内存的参考。当home内存被释放时,它将释放所有它参考的内存块。这将简化应用程序处理逻辑,因为应用程序不再需要保持监视每个已分配的内存块、不再需要再单独释放每块已分配的内存块。
使用NUA功能的应用程序可以使用su库提供的内存管理功能,但不使用这个功能也可以。
请参考<sofia-sip/su_alloc.h>文档以获得更多内存管理功能方面的信息。
Tags
Tagging是Sofia软件包中的一项将参数打包给函数的机制。它允许将具备不固定类型的可变个数参数传递给函数。对应用程序开发人员而言,tagging以宏的形式出现用来封装参数。展开tagging宏后将得到一个包含tag(说明参数的类型)和值(不透明数据的指针)的结构体。Sofia软件包内的各个层检查是否该由他们自身来处理这些参数还是应当传递给更低一层处理。
下面这些tag有着特殊的含义:
- TAG_NULL() (与TAG_END()含义一致) tag列表的尾端
- TAG_SKIP() 空tag元素
- TAG_NEXT() 指向另一个tag列表的tag元素,并且结束当前tag列表
- TAG_ANY() 可接收任意tag的过滤器tag
- TAG_IF() 条件tag元素
可向NUA函数提供tag值列表,但在参数列表的尾端必须如下图所示的参数:
tag_type_t tag, tag_value_t value, ...);
参数列表中最后一个tag值必须是TAG_NULL()(或者TAG_END(),与TAG_NULL()一致)。
每个tag有两个版本:
NUTAG_<tagname>
它接受一个值参数
NUTAG_<tagname>_REF
它接受一个引用参数。后者与tl_gets()函数一块使用可以获取tag列表内的tag值。
对SIP头来说,还有额外的tag版本:
SIPTAG_<tagname>_STR
这个tag版本接受C-语言类型的字符串作为参数。相应无_STR后缀版本接受解析过的结构体作为参数。
下面是一个包含tag值的NUA函数调用示例:
nua_unregister(op->op_handle, TAG_IF(use_registrar, NUTAG_REGISTRAR(registrar)), SIPTAG_CONTACT_STR("*"), SIPTAG_EXPIRES_STR("0"), TAG_NULL());
使用NUA功能的应用程序必须使用tag机制向函数传递参数。请参考nua_invite()函数的说明获得更多如何通过tag机制生成SIP消息的内容:http://sofia-sip.sourceforge.net/refdocs/nua/nua_8h.html#a8162fd7f0f1c693f2d49bb18f36acf52。
请参考<sofia-sip/su_tag.h>源代码文件获得更多tag方面的信息,和Sofia软件包内各个模块内针对本模块特定的tag信息。
调试和日志
Sofia软件包具备可配置的调试和日志功能,基于头文件中定义的功能。调试和日志细节(例如输出内容等级以及输出文件名)可通过环境变量、配置文件中的指令以及源代码文件中的编译指令决定。
指令和环境变量包括:
- SOFIA_DEBUG 缺省调试等级(0..9)
- NUA_DEBUG NUA调试等级(0..9)
- NTA_DEBUG 事务引擎调试等级(0..9)
- TPORT_DEBUG 传输事件调试等级(0..9)
- TPORT_LOG 如果设置了,打印所有传输层使用的解析过的SIP消息
- TPORT_DUMP 保存传输层中所有未解析消息的转储文件名
预定义的调试输出等级:
- 0 非常严重的错误
- 1 严重错误,子系统层次最简化进度消息
- 2 非严重错误
- 3 告警,进度消息
- 5 信令协议动作(呼入包...)
- 7 媒体协议动作(呼入包...)
- 9 进入/退出函数,极细致的进度消息
使用NUA功能的应用程序也可以使用Sofia软件包提供的调试和日志服务。但不使用调试和日志服务也可以。
请查看<sofia-sip/su_log.h>头文件获得更多的调试和日志功能。
NUA概念
NUA Stack对象
Stack对象表示一个SIP stack和媒体引擎实例。它包括stack根对象的引用,用户代理特殊配置,以及SIP事务引擎的引用。
nua_create()函数用来创建一个NUA stack对象,nua_destroy() 函数删除它。nua_shutdown()函数优雅地释放nua引擎维护着的活动状态的会话。
NUA stack对象的类型是nua_t。
NUA Operation Handle操作句柄
Operation handle表示一个抽象的SIP call/会话。它包括SIP对话和媒体会话的信息,call的状态机,高层SDP offer-answer协议,注册,订阅,发布,和简单的SIP事务。Operation handle也可以包含NUA创建的SIP消息中使用的tags列表。
一个operation handle由应用程序通过函数nua_handle()显示创建用来发送消息,或由栈在收到INVITE或MESSAGE消息后创建。应用程序通过调用nua_handle_destroy()函数删除它。
指示或响应事件与某一个特定的operation handle相关。
NUA operation handle的类型是nua_handle_t。
栈线程和消息传递
栈线程与应用程序线程是分开的,它提供了实时的协议栈操作以便应用程序线程可以做其它事情。
栈线程和应用程序线程之间的通信是异步方式的。大部分的NUA API将引起一条发给栈线程处理的消息,同样当栈线程发生了一些事它将向应用程序线程发送一条消息。提供给应用程序线程的消息将通过回调函数发送,回调函数是在应用程序调用su_root_run()或su_root_step()函数时提供的。
SIP消息和头操作
使用SIPTAG_ tags操作SIP消息。每个SIP tag有三个版本:
- SIPTAG_<tagname>()接受解析过后的值作为参数。
- SIPTAG_<tagname>_STR()接受未解析的字串作为参数。
- SIPTAG_<tagname>_REF()接受一个引用作为参数,与tl_gets()函数一道使用从tag列表内取出tag值。
- SIPTA