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

oSIP开发者手册

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

第三部分:扩展API
此部分的参数是很多字段的组成部分,例如”To”、”From”、”Contact”、”Route”、”Record-Route”和”Conten-Type”。
To结构和generic_param_t结构
typedef struct _generic_param_t{
char *gname;
char *gvalue;
}generic_param_t
 
typedef _to_t{
char *displayname;
url_t *url;
list_t *gen_params;
}to_t;
提供一个样例:
to:”chenshx”<sip:chenshx@192.168.25.47>;tag=ae56fr-dz-23
 
generic_param_init
[功能描述]
对generic_param_t结构进行初始化。
[参数描述]
int generic_param_init(generic_param_t *gen_param)
成功返回0。
 
generic_param_free
[功能描述]
释放generic_param_t结构。
[参数描述]
void generic_param_free(generic_param_t *gen_param);
 
generic_param_set
[功能描述]
将pname和pvalue设定到generic_param_t结构中去。
[参数描述]
void generic_param_set(generic_param_t *gen_param,char *pname,char *pvalue);
 
generic_param_getname
generic_param-setname
generic_param_getvalue
generic_param_setvalue
[功能描述]
此四个函数主要操作generic_param_t结构,对结构中的gname和gvalue进行取值和赋值操作。
[参数描述]
char *generic_param_getname(generic_param_t *gen_param)
void generic_param-setname(generic_param_t *gen_param,char *gname)
char *generic_param_getvalue(generic_param_t *gen_param)
void generic_param_setvalue(generic_param_t *gen_param,char *gvalue)
成功返回char *,否则返回NULL。
 
generic_param_add
[功能描述]
将name和其对应的value赋值到gen_params列表当中。
[参数描述]
int generic_param_add(list_t *gen_params,char *name,char *value);
成功返回0。
 
generic_param_getbyname
[功能描述]
在list_t列表的gen_params中寻找参数名为name的值,并返回到generic_param_t结构当中。
[参数描述]
int generic_param_getbyname(list_t *gen_params,char *name,generic_param_t **gen_param);
成功返回0。
 
generic_param_freelist
[功能描述]
释放掉list_t结构中的gen_params
[参数描述]
void generic_param_freelist(list_t *gen_params);
 
SIP Message操作的API
SIP Message结构定义分三部分:第一部分是一行,其为request的request-uri或response的status code,其结构单独定义为startline_t;第二部分是一些列的字段;最后一部分是一些列的其他头部字段和附件或配属。
目前sip_t结构还没有完成,非”From”、”To”、”Call-id”、”CSeq”、”Via”、”Contact”、”Route”、”Record-Route”、”MIME-Version”、”Content-Type”、”Conten-Length”被存贮成一系列的通用头部。
结构定义如下:
typedef struct _sip_t{
startline_t *strtline;
 
/*for all header fully implemented by oSIP*/
from_t *from;
to_t *to;
call_id_t *call_id;
cseq_t *cseq;
list_t *vias;
list_t *contacts;
list_t *record_routes;
list_t *routes;
content_type_t *content_type;
content_length_t *contentlength;
mime_version_t *mime_version;
 
/*for all other headers*/
list_t *headers;
 
/*for all attachments*/
list_t *bodies;
}sip_t;
 
msg_init
[功能描述]
对sip_t结构进行初始化。
[参数描述]
int msg_init(sip_t **msg);
成功返回0。
 
msg_free
[功能描述]
对sip_t结构的信息进行释放。
[参数描述]
void msg_free(sip_t *msg);
 
msg_parse
[功能描述]
分解字符串并将其赋值到sip_t结构体的实例当中。
[参数描述]
int msg_parse(sip_t *msg,char *field_value);
成功返回0,失败返回-1。
 
msg_2char
[功能描述]
将sip_t结构的信息转化为字符串。
[参数描述]
int msg_2char(sip_t *msg,char **field_value);
成功返回0,失败返回-1。
 
msg_clone
[功能描述]
为sip_t结构的实例创建副本,还没有实现。
[参数描述]
 
msg_setheader
[功能描述]
在sip_t添加一个字段。
[参数描述]
int msg_setheader(sip_t *sip,char *hname,char *hvalue);
成功返回0,失败返回-1。
 
msg_getheader
[功能描述]
取在sip_t结构当header部分中的第pos个字段,并赋值给header_t结构。
[参数描述]
int msg_getheader(sip_t *sip,int pos,header_t **dest);
成功返回0,失败返回-1。
 
msg_header_getbyname
[功能描述]
找到sip_t结构当中header部分,取名字为hname的字段的第pos个的值,并将此字段赋值给header_t结构。
[参数描述]
int msg_header_getbyname(char *hname,sip_t *sip,int pos,header_t **dest);
成功返回pos,失败返回-1。
 
msg_setcall_id
[功能描述]
设定sip_t结构当中的call_id的值。
[参数描述]
int msg_setcall_id(sip_t *sip,char *hvalue);
成功返回0,失败返回-1。
 
msg_getcall_id
[功能描述]
返回在sip_t结构当中call_id的值。
[参数描述]
call_id_t *msg_getcall_id(sip_t *sip);
成功返回sip_t结构当中的call_id的值。
 
msg_setcseq
[功能描述]
设定sip_t结构当中的cseq的值。
[参数描述]
int msg_setcseq(sip_t *sip,char *hvalue);
成功返回0,失败返回-1。
 
msg_getcseq
[功能描述]
取sip_t结构当中的cseq的值。
[参数描述]
cseq_t *msg_getcseq(sip_t *sip);
 
msg_setcontact
[功能描述]
设定sip_t结构当中的contact的值。
[参数描述]
int msg_setcontact(sip_t *sip,char *hvalue);
成功返回0,失败返回-1。
 
msg_getcontact
[功能描述]
取sip_t结构当中的contact的值。
[参数描述]
int msg_getcontact(sip_t *sip,int pos,contact_t **contact);
成功返回0,失败返回-1。
 
msg_setfrom
[功能描述]
设定sip_t结构当中from字段得值。
[参数描述]
int msg_setfrom(sip_t *sip,char *hvalue);
成功返回0,失败返回-1。
 
msg_getfrom
[功能描述]
读去sip_t结构当中from字锻的值。
[参数描述]
from_t *msg_getfrom(sip_t *sip);
 
msg_setto
[功能描述]
设定sip_t结构当中to字段的值。
[参数描述]
int msg_setto(sip_t *sip,char *hvalue);
成功返回0,失败返回-1。
 
msg_getto
[功能描述]
读去sip_t结构当中to字段的值。
[参数描述]
to_t *msg_getto(sip_t *sip);
 
msg_setvia
[功能描述]
在sip_t结构末尾增加一个via字段。
[参数描述]
int msg_setvia(sip_t *sip,char *hvalue);
成功返回0,失败返回-1。
 
msg_appendvia
[功能描述]
在sip_t结构开始增加一个via字段。
[参数描述]
int msg_appendvia(sip_t *sip,char *hvalue);
成功返回0,失败返回-1。
 
msg_getvia
[功能描述]
读取sip_t结构当中via字段的第pos的值。
[参数描述]
int msg_getvia(sip_t *sip,int pos,via_t **via);
成功返回0,失败返回-1。
 
msg_setrecord_route
[功能描述]
在sip_t结构当中增加一个新的record route字段。
[参数描述]
int msg_setrecord_route(sip_t *sip,char *hvalue);
成功返回0,失败返回-1。
 
msg_getrecord_route
[功能描述]
读取sip_t结构当中record_route字段的第pos的值。
[参数描述]
int msg_getrecord_route(sip_t sip,int pos,record_route_t **dest);
成功返回0,失败返回-1。
 
msg_setroute
[功能描述]
向sip_t结构中添加一个route字段。
[参数描述]
int msg_setroute(sip_t *sip,char *hvalue);
成功返回0,失败返回-1。
 
msg_getroute
[功能描述]
在sip_t结构当中读取route字段的第pos的值。
[参数描述]
int msg_getroute(sip_t *sip,int pos,route_t **route);
成功返回0,失败返回-1。
 
msg_setcontent_length
[功能描述]
设定sip_t结构当中content_length字段的值。
[参数描述]
int msg_setcontent_length(sip_t *sip,char *hvalue);
成功返回0,失败返回-1。
 
msg_getcontent_length
[功能描述]
返回sip_t结构当中content_length的值。
[参数描述]
content_length_t *msg_getcontent_length(sip_t *sip);
 
msg_setcontent_type
[功能描述]
设定sip_t结构当中content_type字段的值。
[参数描述]
int msg_setcontent_type(sip_t *sip,char *hvalue);
成功返回0,失败返回-1。
 
msg_getcontent_type
[功能描述]
读取sip_t结构当中content_type字段的值。
[参数描述]
content_type_t *msg_getcontent_type(sip_t *sip);
 
msg_setmime_version
[功能描述]
设定sip_t结构当中mime_version字段的值。
[参数描述]
int msg_setmime_version(sip_t *sip,char *hvalue);
成功返回0,失败返回-1。
 
msg_getmime_version
[功能描述]
读取sip_t结构当中的mime_version字段的值。
[参数描述]
mime_version_t *msg_getmime_version(sip_t *sip);
 
语法分析部分样例程序
一些有益于开发的宏定义,其被用于测试消息中带有标志消息本身的字符串,例如消息的类型、请求的方法和应答的状态码。
#define MSG_IS_RESPONSE(resp)     (resp->strtline->statuscode!=NULL)
#define MSG_IS_REQUEST(req)       (req->strtline->statuscode==NULL)
 
#define MSG_IS_INVITE(msg) (0==strncmp(msg->strtline->sipmethod,"INVITE",6))
#define MSG_IS_ACK(msg)     (0==strncmp(msg->strtline->sipmethod,"ACK",6))
#define MSG_IS_BYE(msg)     (0==strncmp(msg->strtline->sipmethod,"BYE",6))
#define MSG_IS_REGISTER(msg) (0==strncmp(msg->strtline->sipmethod,"REGISTER",6))
#define MSG_IS_CANCEL(msg) (0==strncmp(msg->strtline->sipmethod,"CANCEL",6))
#define MSG_IS_OPTIONS(msg) (0==strncmp(msg->strtline->sipmethod,"OPTIONS",6))
#define MSG_IS_INFO(msg)    (0==strncmp(msg->strtline->sipmethod,"INFO",6))
#define MSG_IS_PRACK(msg)   (0==strncmp(msg->strtline->sipmethod,"PRACK",6))
 
#define MSG_IS_STATUS_1XX(msg)    (0==strncmp(msg->strtline->statuscode,"1",1))
#define MSG_IS_STATUS_2XX(msg)    (0==strncmp(msg->strtline->statuscode,"2",1))
#define MSG_IS_STATUS_3XX(msg)    (0==strncmp(msg->strtline->statuscode,"3",1))
#define MSG_IS_STATUS_4XX(msg)    (0==strncmp(msg->strtline->statuscode,"4",1))
#define MSG_IS_STATUS_5XX(msg)    (0==strncmp(msg->strtline->statuscode,"5",1))
#define MSG_IS_STATUS_6XX(msg)    (0==strncmp(msg->strtline->statuscode,"6",1))
#define MSG_TEST_CODE(resp, code) (resp->strtline->statuscode!=NULL \
                                      && code==(int)satoi(resp->strtline->statuscode))
#define MSG_IS_RESPONSEFOR(resp,requestname) \
                                  (0==strcmp(resp->cseq->method,requestname))
对于其他相关操作的API,请务必参阅osip/smsg.h空的内容。
此库的语法分析需要在运行之前做以下初始化工作,下面的的函数必须被使用,且只能运作一次!
int parser_init();
对于定义结构的处理,你是可以调用所谓的标准函数。例如sip_t和from_t结构,你可以使用xxx_init函数对结构进行初始化(这其中包括初赋值和内存分配等等)。你必须调用相对于初始化函数的释放结构函数xxx_free进行释放操作,以防止内存漏洞。
sip_t *msg;
msg_init(&msg);
 
msg_free(msg);
sfree(msg);
 
url_t *url;
url_init(&url)
 
url_free(url);
sfree(url);
如何创建一个url和request-uri,下面的流程就是答案。这里有一个样例,我们就对利用此值进行设定。
INVITE sip:chenshx@sip.datang.com SIP/2.0
 
url_t *url;
url_init(&url);
url_setscheme(url,”sip”);
url_setusername(url,”chenshx”);
url_sethost(url,”sip.datang.com”);
 
msg_setmethod(msg,”INVITE”);
msg_seturi(msg,url);
msg_setversion(msg,”2.0”);
如何在消息体中增加字段?
我提供给您两条思路,一个看下面的样例,另一个是看rfc2543。
下面的头部是强制的,请牢记于心。
Via
Cseq
Call-Id
To
From
Contact
Content-length
Conten-Type
之后就是body
{
 url_t    *url;
 to_t     *to;
 url_init(&url);
 url_setusername(url,sstrdup("jack"));
 url_sethost(url,sstrdup("atosc.org"));
 
 to_init(&to);
 to_seturl(to,url);
 to_setdisplayname(to,sstrdup("jack..."));
 
 msg_setto(msg, to);
 }
 
 /* the same API is available for the from_t structure */
 {
 from_t   *from;
 /* allocate a url_t */
 url_init(&url);
 url_setusername(url,sstrdup("cha"));
 url_sethost(url,sstrdup("anywhere.org"));
 
 /* allocate a from_t */
 from_init(&from);
 from_seturl(from,url);
 from_setdisplayname(from,sstrdup("My love"));
 from_set_tag(from,sstrdup("a48a"));
 
 msg_setfrom(msg, from);
 }
 
 {
 via_t    *via;
 via_init(&via);
 
 via_setversion(via,sstrdup("2.0"));
 via_setprotocol(via,sstrdup("UDP"));
 via_sethost(via,sstrdup("137.137.137.137"));
 via_set_branch(via,sstrdup("branch"),sstrdup("a7c6a8dlze.1"));
 
 msg_setvia(msg, via);
 }
 
 {
 cseq_t   *cseq;
 cseq_init(&cseq);
 ...
 
 msg_setcseq(msg, cseq);
 }
 
 {
 callid_t *callid;
 callid_init(&callid);
 
 callid_setnumber(callid,sstrdup("f81d4"));
 callid_sethost(callid,sstrdup("foo.atosc.org"));
 
 msg_setcallid(msg, callid);
 }
 
 /* this API can also be used, but it is much more time consuming! */
 msg_setcontact(msg,"sip:jacK@office.atosc.org");
 
 /* Let's add some headers */
 msg_setheader(msg,sstrdup("SuBjecT"),sstrdup("Need support for oSIP!"));
 
 /* add a body */
 msg_setbody(msg,"v=0\r\no=user1 53655765 2353687637 IN IP4 128.3.4.5\r\ns=Mbone Audio\r\ni=Discussion of Mbone Engineering Issues\r\ne=mbone@somewhere.com\r\nc=IN IP4 128.3.4.5\r\nt=0 0\r\nm=audio 3456 RTP/AVP 0\r\na=rtpmap:0 PCMU/8000\r\n");
结构信息转化成字符串
将一个定义的结构转化为串,这在处理完信息之后要发送这个动作时必须调用的。之后就是释放掉结构初始化所占用的资源。
sip_t *msg;
char *dest;
msg_init(&msg);
对msg的操作;
if(msg_2char(msg,&dest)!=0)
{
 printf(“\nmsg_2char调用失败。\n”);
 continue;
}
msg_free(msg);
sfree(msg);
sfree(dest);
 
提醒:
语法分析器过于容忍一些我们的一些失误,例如可能在display name中加入了逗号,虽然这是不允许的,但分析器却“容忍”了。这就使你必须时刻警惕可能发生的一切,擦亮你的眼睛,关注每一问题。
如何提高语法分析器的性能
    提高栈的性能,你可以通过配置语法分析在连接时选取一些头部必须完全解码。(在运行时进行少量工作也是被允许的)在执行代理服务器时,你可以发现这对于性能提高很有用。
 

[1] [2] [3]

编辑 webmaster

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