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
以上紧紧作为参考,并不是很全,如果想细细的研究分析,建议自己去看源码。哈,虽然会很累,但是效果很好

下面这段是注册代码:

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

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

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

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

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

  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");  
  1. sprintf(source_call,"sip:%s@%s:%s",s_username,s_ip,s_port);  
  2.   
  3.     sprintf(dest_call,"sip:%s@%s:%s",telNum,s_ip,s_port);  
  4.     i = eXosip_call_build_initial_invite (&invite, dest_call,   
  5. 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
   密码没有涉及到,因为注册的时候已经提供密码

 

 

http://blog.csdn.net/ll0553/archive/2010/08/10/5801879.aspx

转载于:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值