您的位置:首页 > 其它

exosip的安装与使用(原创)/SDP的解析

2010-10-11 20:35 441 查看
转载请注明 http://hi.csdn.net/hust_ch

exosip是对osip的又一次封装,使得用户可以比较简单的构建自己的SIP协议栈,实现SIP协议。

下载和编译不说了,网上有很多的例子。

下面简要说下exosip的调用流程。

1) eXosip_init(),主要是进行网络的一些初始化,如判定本机地址,网络初始化等。

2) eXosip_set_user_agent() 设置user_agent(),可以不写,主要是在SIP request/response里填写user_agent字段用的。

3)eXosip_listen_addr()创建监听地址,可以直接写成 eXosip_listen_addr(IPPROTO_UDP,0,0,AF_INET,0);

4)创建事件线程,用于接受处理sip消息

CreateThread(0,0,SIP_Event_Thread,this,0,0)

这里创建了一个SIP_Event_Thread线程并用于接受参数,传入一个this参数。

5) 在下面的SIP线程里处理,类似的函数很多。

DWORD SIP_Event_Handler::PTC_SIP_Event_Thread(LPVOID param)

有关exosip需要注意的是

1) 本机多网卡或多IP时,exosip猜测本机地址时经常会猜错,比如本机有一个公网的PPPOE的IP,另外配有一个私网IP如192.168.1.22 ,则exosip_guess_local_ip会一直返回PPPOE的IP,所以当exosip登陆私网的SIP服务器时,在后续的SIP处理中会一直出错。这里可以通过判断用户输入的SIP服务器是否位于公网,来设置正确的自己的IP地址。

2) eXosip_event_wait(0, WAIT_TIME );中的WAIT_TIME不要过小,否则在exosip工作时的定时器时间偏差会越来越大,没有太深入看过exosip和osip的源码,感觉可能是频繁的中断造成误差。

3) exosip处理有关401和407的错误,可以简单的用下面的函数:

eXosip_lock();

eXosip_default_action(je);

eXosip_unlock();

或者是

eXosip_lock();

eXosip_automatic_refresh();

eXosip_unlock();

下面这段代码示范了如何用exosip提取SDP里想要的值

SDP是会话初始协议,不仅用于SIP协议,也广泛用于如RTSP等多媒体描述协议。

bool get_audiog729_param(const eXosip_event_t *event,

string &audio_ip,

string &audio_port,

string &rtp_pt_type,

string &bitrate,

string &encode_type)

{

int dlgid = event->did;

sdp_message_t *sdp_msg = eXosip_get_remote_sdp(dlgid);

if ( !sdp_msg )

return false;

sdp_connection_t *connection = eXosip_get_audio_connection(sdp_msg);

if ( !connection )

return false;

audio_ip = connection->c_addr; //audio_ip

sdp_media_t * audio_sdp = eXosip_get_audio_media(sdp_msg);

if ( !audio_sdp )

return false;

audio_port = audio_sdp->m_port; //audio_port

for ( int i = 0 ; i < audio_sdp->a_attributes.nb_elt; i ++ )

{

sdp_attribute_t *attr = (sdp_attribute_t*)osip_list_get(&audio_sdp->a_attributes,i);

if ( attr )

{

string audio_filed = attr->a_att_field;

if ( audio_filed == "rtpmap")

{

string g726_value = attr->a_att_value;

if ( ! strstr(g726_value.c_str(),"726"))

continue;

string::size_type pt_idx = g726_value.find_first_of(0x20);

if ( pt_idx == string::npos )

return false;

rtp_pt_type = g726_value.substr(0,pt_idx);

string::size_type bitrate_idx = g726_value.find_first_of('/');

if (bitrate_idx == string::npos )

return false;

bitrate = g726_value.substr( bitrate_idx+ 1 );

encode_type = g726_value.substr(pt_idx+1,bitrate_idx - pt_idx -1);

return true;

}

}

}

return true;

}

其中event是在SIP_Event_Thread里得到的事件,其他的形参也作为结果传出来供调用者用。

对于SDP,重点了解以下几个字段的含义即可。

o= 表示发起者

c= 表示connector,比较重要

m = 表示媒体信息,每个media对应多个attribute("也就是a=")字段

a= 是m=的子属性
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: