当前位置: 首页 >> 程序设计 >> oSIP开发者手册
 

oSIP开发者手册

作者:      来源:zz     发表时间:2007-01-16     浏览次数:      字号:    

——本手册指导开发者利用oSIP栈开发用户代理
原文标题:oSIP User Manual
原文作者:Aymeric Moizard
联系方法:jack@atosc.org
版权保护:GNU Free Documentation License
项目网站:http://osip.atosc.org/
译文作者:陈善学
联系方法:chenshanxue@263.net
 
摘要
“会话发起协议(Session Initiation Protocol-SIP)是一个应用层的信令控制协议。用于创建、修改和终止一个或多个参与者的会话。这些会话可以是Internet多媒体会议、IP电话或多媒体分发(例如:语音信箱)。会话的参与者可以通过组播(multicast)、网状单播(unicast)或两者的混合体进行通信。”
"The Session Initiation Protocol (SIP) is an application-layer control (signaling) protocol for creating, modifying and terminating sessions with one or more participants. These sessions include Internet multimedia conferences, Internet telephone calls and multimedia distribution. Members in a session can communicate via multicast or via a mesh of unicast relations, or a combination of these."
版权
本文的版权归Aymeric Moizard所有。允许拷贝、分发和在”GNU Free Documentation License”(版本1.1或由自由软件基金会最近发布的任何版本)下的定制。需要注意的是,本文档的任何章节的引用(包括本中文翻译)需列出它们的标题、开始的文本和结尾文本,并且标明文档受”GNU Free Documentation Licence”保护。
Copyright (c) 2001 Aymeric MOIZARD. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with the Invariant Sections being LIST THEIR TITLES, with the Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. A copy of the license is included in the section entitled "GNU Free Documentation License".
前言
译者修正了原文中一些细微的错误。本文档是由译者独立完成,未免有翻译不妥之处,因此任何的建议和指正都是非常欢迎的。联系的方式是通过电子邮件至 chenshanxue@263.net
索引
摘要. 1
版权. 1
前言. 1
索引. 2
正文. 3
第一章 SIP协议. 3
SIP独立与媒体. 3
SIP独立于传输层. 3
SIP有很好的扩展性. 3
SIP和最终用户服务. 3
第二章 SIP协议概述. 4
SIP语法. 4
SIP事务. 5
SIP会话. 5
Server 行为. 7
第三章 oSIP开发库. 7
目标. 7
开发的层次. 7
语法分析器. 7
有限状态机. 8
事务管理. 8
谁将受益于oSIP8
允许的平台. 8
第四章 oSIP语法分析器. 8
文件. 8
SIP-URL(SIP地址). 9
URL定义的语法结构和设计目标. 9
url_t结构体操作的API9
url_param_t和url_header_t操作的API11
SIP headers操作的API13
SIP Message操作的API17
语法分析部分样例程序. 23
结构信息转化成字符串. 26
如何提高语法分析器的性能. 27
第五章 有限状态机. 27
事务处理和事件(Events)27
事务处理的定义和目的. 27
事件的定义和目的. 28
事务处理的API28
回叫. 31
一些有用的宏(MACROs)32
有限状态机的指引. 33
初始化oSIP栈. 33
分配和初始化osip_t结构. 33
发送事件(events)控制事物(transaction)34
Proxy开发的注意点. 36
建造自己的体系结构. 36
后记. 36
 
正文
第一章 SIP协议
SIP协议是用于发起、控制和终结多媒体会话的信令协议。它被IETF( http://www.ietf.org/ )rfc2543发表。
SIPIETF致力于将电话服务带入IP网络众多协议的一个组成部分(它与SDPRTPRTCPRTSPRSVPTRIP等众多协议构成SIP系统协议栈)。其将要变成正在发展的IP电话——这个朝气蓬勃的电信工业——的标准之一。正如同电子邮件协议一样,SIP将会变得越来越普及和大众化… …
SIP独立与媒体
传统电话使用一种媒体编码个师通讯(正如被我所熟知的时隙和PCM概念)。现在,这种方式将被终结。我们的电话可以以不同的质量保证和不同的编码方法连接电视、连接摄像机、连接其他电话进行通信。SIP具有媒体协商等功能。任何多媒体应用(例如:游戏、远程教学)都可以使用SIP来建立会话。
SIP独立于传输层
SIP并不和任何的传输层紧密结合。这一构思将使得SIP在第三代网络中受到最小的互操作影响。无线电话的要求(例如漫游功能)同样被关心。SIP完美的构思,使得其适合作为新蜂窝电话时代的信令协议。
SIP有很好的扩展性
rfc2543中定义了6种类型的事务(INVITE,BYE,CANCEL… …)。这些事务被用于媒体协商、创建、修改和终结呼叫。许多其它的服务已经提供这些方式(例如H.323系统),但SIP以其为扩展性为目的设计和事务模型重用(对于服务器是透明的,被用于使用新类型事务创建辅助服务)。下面是可能的服务列表,其中的一些已经被实现。
短信,用于实时信息
预定或通告,用于会议管理
委托,用于呼叫转移等管理
SIP和最终用户服务
    SIP透明支持名字映射和重定向服务,提供ISDN和智能网络电话服务同样的一些功能。这些特性也使得个人移动成为可能。”
参考阅读:rfc2543.txt(章节1.1
SIP服务器被用于定位用户和分发请求的用户定位信息。这些途径,使得最终用户代理发起很少的请求,并能获得多种多样的服务。
许多扩展性在建议文档中定义(查询SIP相关的draft)。我们也可以增加个性化的电话功能并和现有已存在的服务器保持交互。
第二章 SIP协议概述
    本章目的并不是为了细致的描述rfc(我们必须通过阅读rfc获取协议细节),其紧紧提供快速、不完整的协议语法和行为概述。
SIP语法
SIP是一个基于utf8文本编码格式的协议(这使其消息具有很好的可读性,并易于调试)。SIP协议中描述了请求、地址(URL)、应答和个个头部字段的语法信息。整个语法信息以扩展巴克斯范式的形式描述,可以在Columbia获得。
这些语法定义参考了MailHTTP的定义方式。SIP定义了6种请求的类型。最基础的方法有:
INVITE ACK CANCEL BYE INFO OPTIONS
正如我们在请求的BNF定义中看到的(参考rfc2543第三章节),SIP不限定于在规范中已定义的简短的方法列表,扩展性被充分的考虑了。不限定于上面的列表,任何其他类型的请求都可以被oSIP处理。当然这一切的一切,依赖于大家的通知和贡献新的可能方法的样例程序等等。目前的开发库没有太多的努力,以便明确的支持用于提供开发SIP电话的能力。
INVITE sip:jacK@atosc.org SIP/2.0
Via: SIP/2.0/UDP home.sipworld.org
To: sip:jacK@atosc.org
From: sip:cha@sipworld.org
Call-ID: 35778645354@home.sipworld.org
CSeq: 1 INVITE
Contact: sip:cha@home.sipworld.org
Content-type: application/sdp
Content-length: 267
 
v=0
o=user1 53655765 2353687637 IN IP4 128.3.4.5
s=Mbone Audio
i=Discussion of Mbone Engineering Issues
e=mbone@somewhere.com
c=IN IP4 128.3.4.5
t=0 0
m=audio 3456 RTP/AVP 0
a=rtpmap:0 PCMU/8000
    样例2-1 INVITE请求消息内容
INVITE请求被用于初始化和定制会话。现在,chasipword.com呼叫在atos.orgjack。这个请求将被发送到由atosc.org管理的SIP代理服务器,其将被前转到jack的通讯设备,设备拥有真正IP地址。
SIP事务
SIP使用事物控制和管理会话。事务(INVITE,CANCEL,BYE… …)通常是当前会话进展的记忆体。一些其它的事物(SUBSCRIBE,NOTIFY… …)对会话来讲并不必要。一个事物是由请求和应答(一些的中间应答和最终应答)构成。以下头部字段:TOFromCall-IDCseq被用于在一个事务中识别相关联的消息。
因为SIP可以使用不可靠的传输层协议(在IP网络中推荐使用UDP),SIP也定义了在一个事务中消息重传的规则。
UAC1               UAS2
 
 jacks   |   INVITE         |
initiate a|----------------->|   Bob's
 call    |                  | Phone starts
|       180 Ringing|   ringing
|<-----------------|
|       180 Ringing|
|<-----------------|
|           200 OK |
|<-----------------|
|   ACK            |
|----------------->|
样例2-2 INVITE事务
这是一个最基本的点对点的信令呼叫流程的展示。仅有两个SIP用户代理(UAC/UAS)之间进行的呼叫过程。(重传的情况没有被展示)
SIP会话
事务(Transactions)被用户代理用于控制会话。一个会话总是有INVITE消息发起的。SIP定义了一系列的应答状态码。一个代理服务器可以应答你一个非常知名的”404 User Not Found”(我们在使用HTTP的时候,也经常遇到“ HTTP 404 - 未找到文件”)。错误也分不同的等级。一个事物呼叫失败了,但可能仍在尝试新的定位,进行新的事务呼叫。应答3XX用于重定向机制;4XX、5XX、6XX应答各自用于标识终端错误、服务器错误和全局错误。
 
         BOB           home.net    Jack (atosc.org)
         UA1           Redirect           UA2
          | REGISTER      |               .
          |-------------->|               .
          |        200 OK |               .
          |<--------------|               .
          .               .               .
later... .               .               .
          .               .               .
          .               |      REGISTER |
          .               |<--------------|
          .               | 200 OK        |
          .               |-------------->|
          .               .               .
later... .               .               .
          | INVITE jack@home.net          .
          |-------------->|               .
          |302 Moved temporarily         .
          |<--------------|               .
          | ACK           |               .
          |-------------->|               .
          | INVITE jack@office.atosc.org |
          | audio                         |
          |------------------------------>|
          |                  180 Ringing |
          |<------------------------------|
          |                  180 Ringing |
          |<------------------------------|
          |                       200 OK |
          |<------------------------------|
          | ACK jack@office.atosc.org     |
          |------------------------------>|
          .                               .
later     .                               .
          .                               .
          |      INVITE bob@bob.home.net |
          |      audio + video            |
          |<------------------------------|
          |    200 OK                     |
          |------------------------------>|
          |     ACK bob@bob.home.org      |
         |<------------------------------|
          .                               .
later     .                               .
          .                               .
          | BYE jack@office.atosc.org     |
          |------------------------------>|
          |                       200 OK |
          |<------------------------------|
          |                               |
样例2-3 一个完整的会话
首先,所有的用户代理向注册服务器(在这个样例中,重定向服务器具有注册服务功能。注册服务器也就是定位服务器)。
会话由INVITE事务发起,联系在jack@home.net。一个重定向服务器使用重定向功能将找到的jack办公室的地址信息反馈给发起呼叫端UA1。UA1获取了新的目标地址的信息,发起对jack@atosc.org的呼叫。UA2首先振铃,jack接起电话发回200 OK成功应答。过了几分钟,jack和bob向使用他们的摄像头,以便能看到对方的视频信息。新的会话媒体参数修改由jack发起INVITE而进行交互协商,最终结束由bob发起。
Server 行为
SIP为代理、重定向和注册服务器定义了行为描述(我将其理解为有限状态机),具体还要阅读rfc… …
通常,一个用户代理向本域管理的代理服务器发起请求。例如我们并不知其将要互相之间的通讯者的具体位置,我们以用户@域名格式的SIP地址呼叫对方。本域代理服务器(出于安全的考虑,其中可以加入防火墙功能)使用DNS查询,从而定位对方在哪个域里面。一旦对方的域服务器被找寻到,并是安全的(出于安全考虑,可能使用Ipsec认证),请求被前转。对方域代理服务器进行具体定位。如果对方可用(也就是说对方已经在他的域注册服务器注册),所以对方域服务器前转请求到真正的用户。在本地网络中,其他协议标准被用于找寻最终被叫用户(例如finger… …)
第三章 oSIP开发库
在本节中,希望你已经具备SIP系统很好的知识基础,单纯的指就是SIP rfc文档。如果你打算使用SIP,你一个要仔细阅读rfc2543。
目标
oSIP项目启动于2000年7月,第一个发布的版本是在2001年5月(0.5.0)。
oSIP开发库是第一个自由软件项目。在第三代网络体系中,越来越多的电信运营商将要使用IP电话(Linux也成为支撑平台的幸运儿)。发展的一个侧面是在不久的将来,Linux将更多支持多媒体工具。oSIP,作为SIP开发库,将允许建造互操作的注册服务器、用户代理(软件电话)和代理服务器。所有的这些都平添了Linux将作为下一代电话产品的机会。
但oSIP的目标并非仅仅在PC应用。OSIP具有足够的灵活和微小,以便在小的操作系统(例如手持设备)满足其特定要求。从0.7.0版本发布,线程的支持作为可选项。作为开发者的我们,可以在应用程序设计时进行选择。OSIP在将来会完美的适用于蜂窝设备和嵌入式系统当中。oSIP被众所周知应用于实时操作系统VxWorks当中,并且其他支持将是简单的事情。
开发的层次
语法分析器
oSIP现在支持utf8和完整的SIP语法。0.7.0版本包含一个有很小例外、很好适应性的SIP语法分析器。并且,新的语法分析器在2001年7月25日被公布,可能还有一些bug。如果发现了,请务必报告到osip@atosc.org,我将修正他们。
OSIP中包含一个语法分析器,其能够读写任何在rfc中描述的SIP消息。目前oSIP能够分析很小一部分头部,例如Via、Call-ID、To、From、Contact、Cseq、Route、Record-Route、mime-version、Content-Type和Content-length。所有其他头部以字符串的格式存储。更多的头部将会被增加进来。
现在,SIP语法分析器以MIME格式支持多种属性(这一部分还未被测试)。
有时不希望的行为可能发生。oSIP分析之后的消息可能有一些变化。oSIP不能维持如下可靠性:(不过,oSIP保持完整的适应性)
头部字段的顺序
一行中出现多个头部
字段中出现额外的空格
出现LWS(内部的CRLF)
在to,from,contact…字段中出现引号
有限状态机
4个有限状态机已经被测试过。并且在第八次加的夫SIPit中,与大约30个设备进行互通测试,表现得很稳定。
事务管理
oSIP公布了一个易于使用的用户界面。事务是通过使用4个有限状态机定型的,这些都是oSIP库的核心。每一个事物使用独立的FIFO,这些队列被外部模块填充。事件(events)一经用户请求便被列入队列。一系列的动态回叫注册,用于应用程序得知每一个事物的进展情况。
在oSIP上建造一个应用程序需要许多的模块。
首先,我们建造一个管理传输层特性的模块。这样使得oSIP独立于传输层。
之后,我们将需要建造时钟管理的模块(一个简单的,远没有达到优秀得一个样例已经被提供)。这个模块将负责重传和决定何时删除事务上下文是安全的。
最后,我们需要建造多媒体应用部分。这一部分将不得不维持和更新会话(会话是依赖于事务的)的状态。
事务管理已经被测试,表现的很稳定。并且oSIP不需要太多的内存便运行得很快。自从0.7.0,开发库能够被用于多线程模式或者不使用,这完全由开发者决定。
谁将受益于oSIP
oSIP提供一个简单的界面,用于为SIP增加多媒体应用。并且,oSIP并不和任何SIP开发商和操作系统紧密结合。我们可以建造最终用户代理、无状态的代理服务器、重定向服务器和网关。如果你像开发stateful proxy,应阅读最后的“Proxy开发的注意点”和前面的事务管理。
允许的平台
    开发库建造初便考虑了可移植性,其可以被很快应用于支持POSIX的任何系统当中。它已经在Solaris,HP unix,RT OS VxWorks和Windows。GNU/Linux(2.2.16和2.4.7)被用于最初的开发。
第四章 oSIP语法分析器
文件
./libosip-x.x.x/parser是SIP语法分析器的源代码目录。
./libosip-x.x.x是开发库的目录。
#inlcude<osip/smsg.h>是一个包含SIP语法分析API的库文件。
SIP-URL(SIP地址)
URL定义的语法结构和设计目标
URL被用于描述分布在SIP网络中的每一个实体:SIP用户代理、定位服务器、SIP代理服务器、SIP重定向服务器等等。这些实体都要有他们完整的SIP URL进行标识。在开发库中用url_t格式去定义如下字段:”To”、”From”、”Contact”、”Route”和”Record-Route”;list_t扩展定义了url中包含的固定参数和不固定的头部值。
SIP URL的结构定义:
typedef struct _sipurl_t{
char *scheme;
char *username;
char *password;
char *host;
char *port;
list_t *url_params;
list_t *url_headers;
}url_t
url_t结构体操作的API
url_init
[功能描述]
分配内存,并对结构体作初始化。(在下面的API中将会有很多的初始化函数。一般而言,分配内存调用malloc,释放内存调用free,由于作者做了改写使的调用的函数分别为smalloc和sfree,初赋值做的就是将一些变量赋值为0或NULL)。
[参数描述]
int url_init(url_t **url);
成功返回0,失败会使程序自动退出。
 
url_free
[功能描述]
释放操作完成的url_t结构,并对url_t结构中的变量赋值为空。
[参数描述]
void url_free(url_t *url);
 
url_parse
[功能描述]
分解输入的串信息,并赋值到已定义的url_t结构变量当中。
[参数描述]
int url_parse(url_t *url,char *filed_value);
成功返回0,失败返回-1,后面函数返回值大体如此定义。
 
url_2char
[功能描述]
将一个url_t中的结构化信息转化并组合赋值给一个字符串。
[参数描述]
int url_2char(url_t *url,char **field_value);
成功返回0。
char **field_value会在url_2char中做初始化。
 
url_clone
[功能描述]
进行两个url_t结构实例的复制(使用标准函数memcpy也可以完成,但对于链表不一定可以,未曾测试)。
[参数描述]
int url_clone(url_t *url,url_t **dest);
成功返回0,失败返回-1。
 
url_setscheme
url_setusername
url_setpassword
url_sethost
url_setport
[功能描述]
设定url当中的摘要部分、用户名、密码、主机和端口
[参数描述]
void url_setscheme(url_t *url, char *scheme);
void url_setusername(url_t *url, char *username);
void url_setpassword(url_t *url, char *password);
void url_sethost(url_t *url, char *host);
void url_setport(url_t *url, char *port);
 
url_getscheme
url_getusername
url_getpassword
url_gethost
url_getport
[功能描述]
获取url当中的一些特定部分的值,并返回。
[参数描述]
char* url_getscheme(url_t *url);
char* url_getusername(url_t *url);
char* url_getpassword(url_t *url);
char* url_gethost(url_t *url);
char* url_getport(url_t *url);
 
其它相关有用的函数API
#define url_set_transport_udp(U)   url_param_add(U->url_params, "transport", "udp")
#define url_set_transport_tcp(U)   url_param_add(U->url_params, "transport", "tcp")
#define url_set_transport_sctp(U) url_param_add(U->url_params, "transport", "sctp")
#define url_set_transport_tls(U)   url_param_add(U->url_params, "transport", "tls")
#define url_set_transport(U,T)     url_param_add(U->url_params, "transport", T)
 
#define url_set_user_phone(U)     url_param_add(U->url_params, "user", "phone")
#define url_set_user_ip(U)        url_param_add(U->url_params, "user", "ip")
#define url_set_user(U, USER)     url_param_add(U->url_params, "user", USER)
 
#define url_set_method_invite(U) url_param_add(U->url_params, "method", "INVITE")
#define url_set_method_ack(U)     url_param_add(U->url_params, "method", "ACK")
#define url_set_method_options(U) url_param_add(U->url_params, "method", "OPTIONS")
#define url_set_method_bye(U)     url_param_add(U->url_params, "method", "BYE")
#define url_set_method_cancel(U) url_param_add(U->url_params, "method", "CANCEL")
#define url_set_method_register(U) url_param_add(U->url_params,"method", "REGISTER")
#define url_set_method(U, M)      url_param_add(U->url_params, "method", M)
#define url_set_ttl(U, T)         url_param_add(U->url_params, "ttl", T)
#define url_set_maddr(U, M)       url_param_add(U->url_params, "maddr", M)
这些函数都是必要理解的(参照osip/urls.h)
 
url_param_t和url_header_t操作的API
你可以参考前面细述的关于参数和头部值之间的区别。在下面的描述的param的函数中,你只要将param换为header,即可完成对url_header_t的操作。这些函数完成了对结构的初始化、分解、设定和克隆等操作。
param参数的结构定义如下:
typedef struct _url_parm_t{
char *gname;
char *gvalue;
}url_param_t;
header参数的结构定义如下:
typedef struct _url_parm_t{
char *gname;
char *gvalue;
}url_header_t
 
url_param_init
[功能描述]
初始化url_param_t结构。
[参数描述]
int url_param_init(url_param_t **url_param);
成功返回0。
 
url_param_free
[功能描述]
释放url_param所对应url_param_t结构实例。
[参数描述]
int url_param_free(url_param_t *url_param);
成功返回0。
 
url_param_set
[功能描述]
将字符串pname(参数名)和pvalue(参数名所对应的值)赋值到url_param_t结构当中。
[参数描述]
void url_param_set(url_param_t *url_param,char *pname,char *pvalue);
 
url_param_add
[功能描述]
添加一个赋值好的url_param_t结构到url_t里面的参数列表当中。
[参数描述]
int url_param_add(list_t *url_params,char *pname,char *pvalue);
成功返回0,失败返回-1。
 
url_param_freelist
[功能描述]
释放url_t中的参数列表结构。
[参数描述]
void url_param_freelist(list_t *url_params);
 
url_param_getbyname
[功能描述]
在list_t列表中寻找含有pname的url_param,并将此参数对应关系值赋给url_param_t **url_param。最终结果存放在url_param_t **url_param中。
[参数描述]
void url_param_getbyname(list_t *url_params,char *pname,url_param_t **url_param)
       
下面给出两个对于参数和头部值非常重要的操作函数:
int url_uparam_add(url_t *url,char *pname,char *pvalue)
#define url_uparam_add(F,N,V) url_param_add(F->url_params,N,V)
int url_uparam_getbyname(url_t *url,char *pname,url_param_t **url_param)
#define url_uparam_getbyname(F,N,UH) url_param_getbyname(F->url_params, N,UH)
对于使用param,请仔细参考标准rfc2543。
SIP headers操作的API
在rfc2543中定义了大约40个字段。SIP Message(SIP消息)就是由这一系列的字段排列构成的。在下面的API定义分三部分划分并阐述,第一部分API用于创建、分配、分析和打印SIP的头部元素;第二部分展示某头部特有的API,在这里我仅仅展示”to”所特有的函数;第三部分是一些扩展的API,其不仅适合于”to”字段,同样适合于”From”、”Contact”、”Route”、”Record-Route”和其他头部,着提供了头部的扩展性。
To的结构定义如下:
typedef struct _to_t{
char *displayname;
url_t *url;
list_t *gen_params;
}to_t;
SIP语法分析器能够分析如下头部:Via、To、From、Cseq、Call-Id、Contact、Route、Record-Route、Content-Type、Content-Length、Mime-Version。其他头部通过特殊的API以串的格式存取。
你可以潜意识的将”to_”替换为下面的值”via_”、”from_”、”cseq_”、”call_id_”、”contact_”、”route_”、”record_route_”、”content_type_”、”content_length_”、”mime_version_”。
如果你想细致了解每一个字段的结构定义,请阅读osip/smsgtypes.h;想了解字段对应的函数,请阅读osip/smsg.h库文件,其对于功能描述、参数描述和使用描述都会有深入的理解。
第一部分:创建、分配、分析和打印SIP的头部元素
to_init
[功能描述]
对to字段进行初始化。
[参数描述]
int to_init(to_t **to);
成功返回0,不必做失败判断处理。
 
to_free
[功能描述]
释放to字段。
[参数描述]
void to_free(to_t *to);
 
to_2char
[功能描述]
将to结构转化赋值给一个字符串。
[参数描述]
int to_2char(to_t *to,char *filed_value);
成功返回0,失败返回-1。
 
to_clone
[功能描述]
将to信息克隆到目标
[参数描述]
int to_clone(to_t *to,to_t **dest);
 
第二部分:To特有的API
to_setdisplayname
[功能描述]
设定to字段里面的display name。
[参数描述]
void to_setdisplayname(to_t *to,char *value);
 
to_getdisplayname
[功能描述]
从to字段中提取display name并返回。
[参数描述]
char *to_getdisplayname(to_t *to);
 
to_seturl
[功能描述]
在to字段当中设定url值。
[参数描述]
void to_seturl(to_t *to,url_t *url);
 
to_geturl
[功能描述]
从to字段中提取url值。
[参数描述]
url_t *to_geturl(to_t *to);
 
to_param_add
[功能描述]
在to字段中增加一个gen_param
[参数描述]
int to_param_add(to_t *to,char *name,char *value);
成功返回0,失败返回-1。
注意:
#define to_param_add(T,N,V) generic_param_add((T)->gen_params,N,V)
 
to_param_get
[功能描述]
选取to结构里面list_t的第pos的内容。
[参数描述]
int to_param_get(to_t *to,int pos,generic_param_t **gp);
成功返回pos,失败返回-1;
注意:
#define to_param_get(T,I,GP) from_param_get((from_t*)T, I, GP)
 
to_settag
[功能描述]
在to字段内设定tag的值。
[参数描述]
void to_settag(to_t *to,char *tag)
注意:
#define to_set_tag(T,V) generic_param_add((T)->gen_params, "tag",V)
 
to_gettag
[功能描述]
将to结构中的tag值,返回成generic_param_t结构
[参数描述]
void to_gettag(to_t *to,generic_param_t **dest);
#define to_gettag(T,GP) generic_param_getbyname((T)->gen_params, sgetcopy("tag"),GP)
 
to_param_getbyname
[功能描述]
在to字段中寻取参数名为pname的值
[参数描述]
        int to_param_getbyname(to_t *to,char *pname,generic_param_t **dest)
        成功返回0
#define to_param_getbyname(T,N,GP) generic_param_getbyname((T)->gen_params,N,GP)

[1] [2] [3]

责任编辑 webmaster

 
 
 
 
 
评论更多>>
 
 
 
发表
 
姓名: QQ:
性别: MSN:
E-mail: 主页:
评分: 1 2 3 4 5
评论内容:
验证码:
  
  • 请遵守《互联网电子公告服务管理规定》及中华人民共和国其他各项有关法律法规。
  • 严禁发表危害国家安全、损害国家利益、破坏民族团结、破坏国家宗教政策、破坏社会稳定、侮辱、诽谤、教唆、淫秽等内容的评论 。
  • 用户需对自己在使用本站服务过程中的行为承担法律责任(直接或间接导致的)。
  • 本站管理员有权保留或删除评论内容。
  • 评论内容只代表网友个人观点,与本网站立场无关。
  •