sip 网络电话

来源:互联网 发布:约束优化问题 编辑:程序博客网 时间:2024/05/17 00:06

原创  sip网络电话

sip网络电话,经过了一个月的时间,终于把网络电话做出来了,其实功能也不是很完善,不过正常沟通是没有问题的,想把这一个月所学的东西都记录下来,分享给大家,也留给自己。
    我是一个即将毕业的学生,来北京找工作,找到了一个公司,比较小,在实习阶段老板让我作这个sip的网络电话,刚开始就觉得莫名其妙,一个新来的,什么都没学过,就做sip,我连什么是sip都不知道,可是没办法,金融危机,工作不好找,有个工作就干吧,而且这个公司跟我学的专业也挺对口的(嵌入式),不过眼前的这个任务确实有点偏。
    刚开始就在网上找这方面的资料,一点一点学,慢慢的了解,想想第一天知道网络电话要先注册的时候就挺好笑的。我的想法就是现在网上找找这方面的资源,然后再找个QQ群去沟通,如果有人带,那就会很快的完成任务阿。
我加过一个QQ群,高手很多,我是菜鸟,很多人都不屑理睬我,追着人家文问题的时候确实很让人烦,时间长了,老在群里面问问题,就说不定会惹到谁,也因为这个闹了一点小矛盾,最后退群了。
    在学习的过程中得到过很多人的帮助,在这里谢谢 颓废 heeb osip(QQ名字,我在群里面的名字叫小饭团)等,还有很多人,不好意思,记不请了,对我的帮助都很大的。
    言归正传开始说事儿:
    首先要配置环境,需要这么几个库,libosip,libeXosip2,ortp,mediastreamer2.
    libosip,libeXosip2这两个库是负责信令部分的,ortp,medastreamer2是负责媒体流传输的。如果想了解更多的关于这些库方面的信息,可以去网上搜索,会有很多相关的信息,总之学习不要怕麻烦。是师傅令进门,修行在个人。学习sip要看rfc3261 3265 3550 4353 ,还有eXosip,osip,ortp,mediastreamer2的帮助手册等。资料多了才好学习嘛。

sipAPI:http://www.gnu.org/software/osip/doc/html/group__oSIP__MESSAGE.html
eXosipAPI:http://www.antisip.com/doc/exosip2/group__eXosip2__sdp.html#gdab1e84d04b387ada72e0d548444f3c0
ortpAPI:http://download.savannah.gnu.org/releases-noredirect/linphone/ortp/docs/ortp_8h.html
mediastreamerAPI:http://www.antisip.com/doc/mediastreamer2/mscommon_8h.html
以上紧紧作为参考,并不是很全,如果想细细的研究分析,建议自己去看源码。哈,虽然会很累,但是效果很好

下面这段是注册代码:

 

view plaincopy to clipboardprint?
  1. #include <eXosip2/eXosip.h>  
  2. #include <osip2/osip_mt.h>  
  3.   
  4. #include <stdio.h>  
  5. #include <stdlib.h>  
  6. #include <sys/types.h>  
  7. #include <netinet/in.h>  
  8. #include <sys/socket.h>  
  9.   
  10. // ip_url 为服务器ip,  
  11. int myregister(char *ip_url,char *port,char *username,char * password)  
  12. {  
  13.     int i;  
  14.     char identity[50];  
  15.     char registerer[50];  
  16.     char localip[128];  
  17.     static int flag = 0;  
  18.     int id;  
  19.     eXosip_guess_localip (AF_INET, localip, 128);  
  20.   
  21.     sprintf(identity,"sip:%s@%s",username,localip);  
  22.     sprintf(registerer,"sip:%s:%s",ip_url,port);  
  23.   
  24. //初始化  
  25. if( flag == 0)  
  26. {  
  27.     i = eXosip_init();  
  28.     if (i != 0)  
  29.     {  
  30.     return -1;  
  31.     }  
  32.     printf("eXosip_init success/n");  
  33.     flag ++;  
  34.     i = eXosip_listen_addr(IPPROTO_UDP, NULL, 5060, AF_INET, 0);  
  35.     if (i != 0)  
  36.     {  
  37.     eXosip_quit();  
  38.     fprintf(stderr, "could not initialize transport layer/n");  
  39.     return -1;  
  40.     }  
  41.     printf("eXosip_listen_addr success/n");  
  42. }  
  43.     osip_message_t *reg = NULL;  
  44.   
  45.     eXosip_lock();  
  46.     id = eXosip_register_build_initial_register (identity,registerer, NULL, 1800, ®);  
  47.     printf("id = %d", id);  
  48.    
  49.     if (id < 0)  
  50.     {  
  51.     eXosip_unlock();  
  52.     fprintf (stderr, "eXosip_register_build_initial_register failed:(bad arguments?)/n");  
  53.     return 0;  
  54.     }  
  55.     eXosip_lock();  
  56.     i = eXosip_register_send_register(id, reg);  
  57.     if (i != 0)  
  58.     {  
  59.     fprintf (stderr, "eXosip_register_send_register failed: (bad arguments?)/n");  
  60.     return 0;  
  61.     }  
  62.     eXosip_unlock ();  
  63.   
  64.     printf("eXosip_register_send_register OK/n");  
  65.     
  66.     eXosip_event_t *je;  
  67.     for (;;)  
  68.     {  
  69.     je = eXosip_event_wait (0, 50);  
  70.   
  71.     eXosip_lock();  
  72.     eXosip_automatic_action ();  
  73.     eXosip_unlock();  
  74.   
  75.     if (je == NULL)  
  76.     {  
  77.         continue;  
  78.     }  
  79.   
  80.     if (je->type == EXOSIP_REGISTRATION_SUCCESS)  
  81.     {  
  82.         printf("textinfo is %s/n", je->textinfo);  
  83.         return 1;  
  84.         break;  
  85.     }  
  86.     if(je->type == EXOSIP_REGISTRATION_FAILURE)  
  87.     {  
  88.         //注册失败之后,再次提交授权信息, 也可放在上面  
  89.         eXosip_add_authentication_info(username, username,password, NULL, NULL);  
  90.     }  
  91.     if(je->type == EXOSIP_REGISTRATION_REFRESHED)  
  92.     {  
  93.         printf("refreshed");  
  94.         return 0;  
  95.     }  
  96.     }  
  97.     eXosip_quit();  
  98. }  

 

ps:注册其实挺简单的,代码是用eXosip实现的,帮助手册上面都有,只要细细分析就能看明白,网上有pdf版本的,csdn上也有,英文的。

继续,下面这段是拨号的代码:

 

view plaincopy to clipboardprint?
  1. #include <eXosip2/eXosip.h>  
  2. #include <osip2/osip_mt.h>  
  3.   
  4. #include <stdio.h>  
  5. #include <stdlib.h>  
  6. #include <sys/types.h>  
  7. #include <netinet/in.h>  
  8. #include <sys/socket.h>  
  9.   
  10. int call(char *telNum)  
  11. {  
  12.     eXosip_event_t *je;  
  13.   
  14.     osip_message_t *invite = NULL;  
  15.     osip_message_t *ack = NULL;  
  16.   
  17.     // int call_id, dialog_id;  
  18.     int i,flag;  
  19.     char tmp[4096];  
  20.     char localip[128];  
  21.   
  22.     char source_call[100];  
  23.     char dest_call[100];  
  24.   
  25.     sprintf(source_call,"sip:%s@%s:%s",s_username,s_ip,s_port);  
  26.     sprintf(dest_call,"sip:%s@%s:%s",telNum,s_ip,s_port);  
  27.   
  28.     i = eXosip_call_build_initial_invite (&invite, dest_call, source_call, NULL, "This si a call for a conversation");  
  29.     if (i != 0)  
  30.     {  
  31.     printf ("Intial INVITE failed!/n");  
  32.     return -1;  
  33.     }  
  34.   
  35.     eXosip_guess_localip (AF_INET, localip, 128);  
  36.     snprintf (tmp, 4096,  
  37.         "v=0/r/n"  
  38.         "o=josua 0 0 IN IP4 %s/r/n"  
  39.         "s=conversation/r/n"  
  40.         "c=IN IP4 %s/r/n"  
  41.         "t=0 0/r/n"  
  42.         "m=audio %s RTP/AVP 0 8 101/r/n"  
  43.         "a=rtpmap:0 PCMU/8000/r/n"  
  44.         "a=rtpmap:8 PCMA/8000/r/n"  
  45.         "a=rtpmap:101 telephone-event/8000/r/n"  
  46.         "a=fmtp:101 0-11/r/n", localip, localip, "9900");  
  47.   
  48.   
  49.     osip_message_set_body (invite, tmp, strlen (tmp));  
  50.     osip_message_set_content_type (invite, "application/sdp");  
  51.   
  52.     eXosip_lock ();  
  53.     i = eXosip_call_send_initial_invite (invite);  
  54.     eXosip_unlock ();  
  55.     flag = 1;  
  56.   
  57.     while (flag)  
  58.     {  
  59.     je = eXosip_event_wait (0, 200);  
  60.   
  61.     if (je == NULL)  
  62.     {  
  63.         printf ("No response or the time is over!/n");  
  64.         break;  
  65.     }  
  66.   
  67.     eXosip_lock ();  
  68.     eXosip_default_action(je);   
  69.     eXosip_unlock ();  
  70.   
  71.     switch (je->type)  
  72.     {  
  73.         case EXOSIP_CALL_INVITE:  
  74.         printf ("a new invite reveived!/n");  
  75.         break;  
  76.         case EXOSIP_CALL_PROCEEDING:  
  77.         printf ("proceeding!/n");  
  78.         call_id = je->cid;  
  79.         break;  
  80.         case EXOSIP_CALL_RINGING:  
  81.         printf ("ringing!/n");  
  82.         printf ("call_id is %d, dialog_id is %d /n", je->cid, je->did);  
  83.         break;  
  84.         case EXOSIP_CALL_ANSWERED:  
  85.         printf ("ok! connected!/n");  
  86.   
  87.         call_id = je->cid;  
  88.         dialog_id = je->did;  
  89.         printf ("call_id is %d, dialog_id is %d /n", je->cid, je->did);  
  90.   
  91.         eXosip_call_build_ack (je->did, &ack);  
  92.         eXosip_call_send_ack (je->did, ack);  
  93.                  
  94.         break;  
  95.         case EXOSIP_CALL_CLOSED:  
  96.         printf ("the other sid closed!/n");  
  97.         return -1;//对方挂断  
  98.         break;  
  99.         case EXOSIP_CALL_ACK:  
  100.         printf ("ACK received!/n");  
  101.         break;  
  102.         default:break;  
  103.     }  
  104.     eXosip_event_free (je);  
  105.   
  106.     }  
  107.     return 0;  
  108. }  

 

ps: 初学者可能不了解格式,所以程序会调不通,学的不好给大家随便说一下,别见怪阿。

 

view plaincopy to clipboardprint?
  1. sprintf(source_call,"sip:%s@%s:%s",s_username,s_ip,s_port);  
  2.     sprintf(dest_call,"sip:%s@%s:%s",telNum,s_ip,s_port);  
  3.     i = eXosip_call_build_initial_invite (&invite, dest_call, source_call, NULL, "This si a call for a conversation");  

 

用户名: 77001234
   密码: 987654321
   要呼叫的号码:12340602252
   服务器ip:192.168.8.24
   端口:5060
   》》  source_call为 77001234@192.168.8.24:5060
   》》  dest_call  为  12340602252@192.168.8.24:5060
   密码没有涉及到,因为注册的时候已经提供密码

原创粉丝点击