公司要对接一个平台,采用GB28181协议,由于以前没有接触过sip协议,所以在网上查找了一些资料后大概对注册过程有一点点了解后就写了一个注册程序,由于只懂得一些大概的sip协议所以测试程序很快写好后就遇到了问题,注册程序第一次返回401后又添加验证信息再次注册结果却给我返回404,当看到不是预期的200 ok时我就懵了,不知道哪里出错了,然后又是大量的查找资料网上很多说是sip服务器找不到用户,但是具体的又说的不清楚,所以我这个小菜鸟就查了整整两天的资料,这里把很有用的几篇文章贴出了给大家参考:http://blog.csdn.net/love_xunmeng/article/details/46008567
参考:
http://wenku.baidu.com/link?url=GwUIFHp8Ri2Z32K-4VkEZ9wvOC1VC_GDbXOuVdot1kRsgcI3UCN9Up0nbQmba-DVGmEqyD8fz7XA-KJEG8nVZms-yMPA6ZekU6tGo5Jzj0i
通过这些资料我大概知道是我uri出问题了,于是我就查看我的代码,
`sprintf(from, “sip:%s@%s”, “123456789”, “192.168.230.97”);
sprintf(proxy, “sip:%s@%s:%d”,”34020000002000000001”,”192.168.230.205”, 5060);
sprintf(contact, “sip:%s@%s:5080”, “123456789”,”192.168.230.97”); 发现是在填写from这个参数时把这里的IP地址填写成了sip服务器的ip地址而导致Request-URI 出错,这里应该填写终端的ip,下面附带我自己的测试代码和网上下载的sip服务器,这个服务器也是摸索了好久才会用。(sip服务器不会上传,我上传到我的资源里面大家下载吧)
#include <stdio.h>
#include "eXosip2/eXosip.h"
#include "osip2/osip_mt.h"
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <unistd.h>
#include <netdb.h>
#include <netinet/tcp.h>
int main( )
{
int ret = 0;
char from[100];/*sip:主叫用户名@被叫IP地址*/
char proxy[100];/*sip:被叫IP地址:被叫IP端口*/
char contact[100];
osip_message_t *reg = NULL;
eXosip_event_t *msg = NULL;
int reg_id = 0;
int reg_status = 0;
/*初始化*/
ret = eXosip_init();/*初始化osip和eXosip协议栈*/
if (0 != ret)
{
printf("eXosip_init failed ...\n");;
return -1;
}
/*监听sip端口*/
ret = eXosip_listen_addr(IPPROTO_UDP, NULL, 5080, AF_INET, 0);
if (0 != ret)/*传输层初始化失败*/
{
eXosip_quit();
printf("eXosip_listen_addr error!\r\n");
return -1;
}
sprintf(from, "sip:%s@%s", "123456789", "192.168.230.97");
sprintf(proxy, "sip:%s@%s:%d","34020000002000000001","192.168.230.205", 5060);
sprintf(contact, "sip:%s@%s:5080", "123456789","192.168.230.97");
/*构建一个register*/
eXosip_lock();
reg_id = eXosip_register_build_initial_register(from, proxy, contact, 3600, ®);
if (reg_id < 0)
{
eXosip_unlock();
printf("eXosip_register_build_initial_register error!\r\n");
return -1;
}
//osip_message_set_authorization(reg, "Capability algorithm=\"H:MD5\"");
/*发送register*/
ret = eXosip_register_send_register(reg_id, reg);
eXosip_unlock();
if (0 != ret)
{
printf("eXosip_register_send_register no authorization error!\r\n");
return -1;
}
printf("send reg msg \n");
for( ; ; )
{
msg = eXosip_event_wait(0, 50);/*侦听消息的到来*/
if (NULL == msg)/*没有接收到消息*/
{
sleep(1);
printf("msg is null\n ");
continue;
}
printf("type = %d \n",msg->type);
switch(msg->type)
{
/*注册成功*/
case EXOSIP_REGISTRATION_SUCCESS:
{
printf("reg sussess \n");
reg_status = 1;
}
break;
/*注册失败*/
case EXOSIP_REGISTRATION_FAILURE:
{
printf("status_code = %d \n",msg->response->status_code);
#if 1
/*收到服务器返回的注册失败/401未认证状态*/
if ((NULL != msg->response)&&(401 == msg->response->status_code))
{
/*发送携带认证信息的注册请求*/
eXosip_lock();
eXosip_clear_authentication_info();/*清除认证信息*/
/*添加主叫用户的认证信息*/
eXosip_add_authentication_info("zjf", "zjf", "12345678", "MD5", NULL);
eXosip_register_build_register(msg->rid, 3600, ®);
ret = eXosip_register_send_register(msg->rid, reg);
eXosip_unlock();
if (0 != ret)
{
printf("eXosip_register_send_register authorization error!\r\n");
return -1;
}
}
else
{
printf("reg failed \n");
}
#endif
}
break;
default:
printf("err msg type = %d \n",msg->type);
}
if(reg_status == 1)
{
break;
}
}
eXosip_event_free (msg);
return 0;
}