oSIP开发者手册 (三)
第三部分:扩展API此部分的参数是很多字段的组成部分,例如”To”、”From”、”Contact”、”Route”、”Record-Route”和”Conten-Type”。To结构和generic_param_t结构typedef struct _generic_param_t{char *gname;char *gvalu...
第三部分:扩展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中加入了逗号,虽然这是不允许的,但分析器却“容忍”了。这就使你必须时刻警惕可能发生的一切,擦亮你的眼睛,关注每一问题。
[内容来自网络]
更多推荐
所有评论(0)