今天开始了SIP开源库的学习,我选择了osip和eXosip,但是这两个库的编译使用有些麻烦,源码下来之后编译会出现很多问题,网上也没有找到完整的编译介绍,只能一步一步的找办法解决,最后终于编译成功!先大概记录下编译过程,后面还要再整理下。
期间还向CSDN论坛求助了下,但是还没有反应:http://bbs.csdn.net/topics/390499635?page=1#post-394866714
描述:error LNK2019: 无法解析的外部符号 _osip_transaction_set_naptr_record,该符号在函数 __eXosip_transaction_init 中被引用
原因:开源代码的库有些函数没有导出,需要手动在def文件中添加
解决方法:第二步的2,3两小步就是为了解决这个问题。
第一步,下载osip和eXosip
osip: http://ftp./Unix/NonGNU//osip/libosip2-3.6.0.tar.gz eXosip: http://download.savannah./releases/exosip/libeXosip2-3.6.0.tar.gz
第二步,解压,编译osip:
1.进入libosip2-3.6.0\platform\vsnet目录,用VS2010直接打开osip.sln文件,项目自动转换
2.更改libosip2-3.6.0\platform\vsnet\osip2.def 文件,在文件末尾追加 osip_transaction_set_naptr_record @138
3.更改libosip2-3.6.0\platform\vsnet\osipparser2.def 文件,在文件末尾追加
osip_realloc @416 osip_strcasestr @417 __osip_uri_escape_userinfo @418
4.先编译osipparser2,再编译osip2,最后在libosip2-3.6.0\platform\vsnet\Debug DLL下生成库文件:
osip2.lib
osip2.dll osipparser2.lib osipparser2.dll
第三步,解压,编译eXosip
进入libeXosip2-3.6.0\platform\vsnet目录,用VS2010直接打开eXosip.sln文件,项目自动转换:
1.将osip2.lib,osip2.dll,osipparser2.lib,osipparser2.dll拷贝到Debug目录下 2.C/C++ --> 预处理器 --> 预处理器定义: 删除HAVE_OPENSSL_SSL_H 3.C/C++ --> 常规 --> 附加包含目录: 将osip的头文件libosip2-3.6.0\include包含进来
4.编译,生成eXosip.lib
第四步,新建UAC例子项目
1.链接器 --> 输入 --> 附加依赖项:增加静态库引用:Dnsapi.lib;Iphlpapi.lib;Ws2_32.lib;osip2.lib;osipparser2.lib;exosip.lib;
2.C/C++ -->常规 -->附加包含目录: 将osip和eXosip的头文件libosip2-3.6.0\include、libeXosip2-3.6.0\include包含进来
3.链接器 --> 常规 --> 附加库目录:将osip和eXosip的库包含进来,libeXosip2-3.6.0\platform\vsnet\Debug
4.编译UAC代码:
- <span style="font-family:SimSun;">#include <eXosip2/eXosip.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <winsock2.h>
-
- int main(int argc,char *argv[])
- {
-
- struct eXosip_t *context_eXosip;
-
- eXosip_event_t *je;
- osip_message_t *reg=NULL;
- osip_message_t *invite=NULL;
- osip_message_t *ack=NULL;
- osip_message_t *info=NULL;
- osip_message_t *message=NULL;
-
- int call_id,dialog_id;
- int i,flag;
- int flag1=1;
-
- char *identity="sip:140@127.0.0.1";
- char *registar="sip:133@127.0.0.1:15061";
- char *source_call="sip:140@127.0.0.1";
- char *dest_call="sip:133@127.0.0.1:15061";
-
-
- char command;
- char tmp[4096];
-
- printf("r 向服务器注册\n\n");
- printf("c 取消注册\n\n");
- printf("i 发起呼叫请求\n\n");
- printf("h 挂断\n\n");
- printf("q 推出程序\n\n");
- printf("s 执行方法INFO\n\n");
- printf("m 执行方法MESSAGE\n\n");
-
-
- i=eXosip_init();
-
- if(i!=0)
- {
- printf("Couldn't initialize eXosip!\n");
- return -1;
- }
- else
- {
- printf("eXosip_init successfully!\n");
- }
-
-
- i=eXosip_listen_addr(IPPROTO_UDP,NULL,15060,AF_INET,0);
- if(i!=0)
- {
- eXosip_quit();
- fprintf(stderr,"Couldn't initialize transport layer!\n");
- return -1;
- }
- flag=1;
-
- while(flag)
- {
-
- printf("Please input the command:\n");
- scanf("%c",&command);
- getchar();
-
- switch(command)
- {
- case 'r':
- printf("This modal is not completed!\n");
- break;
- case 'i':
- i=eXosip_call_build_initial_invite(&invite,dest_call,source_call,NULL,"This is a call for conversation");
- if(i!=0)
- {
- printf("Initial INVITE failed!\n");
- break;
- }
-
-
-
- _snprintf(tmp,4096,
- "v=0\r\n"
- "o=anonymous 0 0 IN IP4 0.0.0.0\r\n"
- "t=1 10\r\n"
- "a=username:rainfish\r\n"
- "a=password:123\r\n");
-
- osip_message_set_body(invite,tmp,strlen(tmp));
- osip_message_set_content_type(invite,"application/sdp");
-
- eXosip_lock();
- i=eXosip_call_send_initial_invite(invite);
- eXosip_unlock();
-
-
- flag1=1;
- while(flag1)
- {
- je=eXosip_event_wait(0,200);
-
- if(je==NULL)
- {
- printf("No response or the time is over!\n");
- break;
- }
- switch(je->type)
- {
- case EXOSIP_CALL_INVITE:
- printf("a new invite received!\n");
- break;
- case EXOSIP_CALL_PROCEEDING:
- printf("proceeding!\n");
- break;
- case EXOSIP_CALL_RINGING:
- printf("ringing!\n");
- printf("call_id is %d,dialog_id is %d \n",je->cid,je->did);
- break;
- case EXOSIP_CALL_ANSWERED:
- printf("ok!connected!\n");
- call_id=je->cid;
- dialog_id=je->did;
- printf("call_id is %d,dialog_id is %d \n",je->cid,je->did);
-
-
- eXosip_call_build_ack(je->did,&ack);
- eXosip_call_send_ack(je->did,ack);
- flag1=0;
- break;
- case EXOSIP_CALL_CLOSED:
- printf("the other sid closed!\n");
- break;
- case EXOSIP_CALL_ACK:
- printf("ACK received!\n");
- break;
- default:
- printf("other response!\n");
- break;
- }
- eXosip_event_free(je);
- }
- break;
-
- case 'h':
- printf("Holded!\n");
-
- eXosip_lock();
- eXosip_call_terminate(call_id,dialog_id);
- eXosip_unlock();
- break;
-
- case 'c':
- printf("This modal is not commpleted!\n");
- break;
-
- case 's':
- eXosip_call_build_info(dialog_id,&info);
- _snprintf(tmp,4096,"\nThis is a sip message(Method:INFO)");
- osip_message_set_body(info,tmp,strlen(tmp));
-
- osip_message_set_content_type(info,"text/plain");
- eXosip_call_send_request(dialog_id,info);
- break;
-
- case 'm':
-
-
- printf("the method : MESSAGE\n");
- eXosip_message_build_request(&message,"MESSAGE",dest_call,source_call,NULL);
-
- _snprintf(tmp,4096,"This is a sip message(Method:MESSAGE)");
- osip_message_set_body(message,tmp,strlen(tmp));
-
- osip_message_set_content_type(message,"text/xml");
- eXosip_message_send_request(message);
- break;
-
- case 'q':
- eXosip_quit();
- printf("Exit the setup!\n");
- flag=0;
- break;
- }
- }
-
- return(0);
- }</span>
第五步,编译UAS项目:
与UAC同样的设置后,编译
- <span style="font-family:SimSun;"># include <eXosip2/eXosip.h>
- # include <stdio.h>
- # include <stdlib.h>
- # include <Winsock2.h>
-
-
- int main (int argc, char *argv[])
- {
- eXosip_event_t *je = NULL;
- osip_message_t *ack = NULL;
- osip_message_t *invite = NULL;
- osip_message_t *answer = NULL;
- sdp_message_t *remote_sdp = NULL;
- int call_id, dialog_id;
- int i,j;
- int id;
- char *sour_call = "sip:140@127.0.0.1";
- char *dest_call = "sip:133@127.0.0.1:15060";
- char command;
- char tmp[4096];
- char localip[128];
- int pos = 0;
-
- i = eXosip_init ();
- if (i != 0)
- {
- printf ("Can't initialize eXosip!\n");
- return -1;
- }
- else
- {
- printf ("eXosip_init successfully!\n");
- }
- i = eXosip_listen_addr (IPPROTO_UDP, NULL, 15061, AF_INET, 0);
- if (i != 0)
- {
- eXosip_quit ();
- fprintf (stderr, "eXosip_listen_addr error!\nCouldn't initialize transport layer!\n");
- }
- for(;;)
- {
-
- je = eXosip_event_wait (0,50);
-
- eXosip_lock ();
- eXosip_default_action (je);
- eXosip_automatic_refresh ();
- eXosip_unlock ();
- if (je == NULL)
- continue;
-
- switch (je->type)
- {
- case EXOSIP_MESSAGE_NEW:
- printf (" EXOSIP_MESSAGE_NEW!\n");
- if (MSG_IS_MESSAGE (je->request))
- {
- {
- osip_body_t *body;
- osip_message_get_body (je->request, 0, &body);
- printf ("I get the msg is: %s\n", body->body);
-
- }
-
- eXosip_message_build_answer (je->tid, 200,&answer);
- eXosip_message_send_answer (je->tid, 200,answer);
- }
- break;
- case EXOSIP_CALL_INVITE:
-
- printf ("Received a INVITE msg from %s:%s, UserName is %s, password is %s\n",je->request->req_uri->host,
- je->request->req_uri->port, je->request->req_uri->username, je->request->req_uri->password);
-
- remote_sdp = eXosip_get_remote_sdp (je->did);
- call_id = je->cid;
- dialog_id = je->did;
-
- eXosip_lock ();
- eXosip_call_send_answer (je->tid, 180, NULL);
- i = eXosip_call_build_answer (je->tid, 200, &answer);
- if (i != 0)
- {
- printf ("This request msg is invalid!Cann't response!\n");
- eXosip_call_send_answer (je->tid, 400, NULL);
- }
- else
- {
- snprintf (tmp, 4096,
- "v=0\r\n"
- "o=anonymous 0 0 IN IP4 0.0.0.0\r\n"
- "t=1 10\r\n"
- "a=username:rainfish\r\n"
- "a=password:123\r\n");
-
-
-
- osip_message_set_body (answer, tmp, strlen(tmp));
- osip_message_set_content_type (answer, "application/sdp");
-
- eXosip_call_send_answer (je->tid, 200, answer);
- printf ("send 200 over!\n");
- }
- eXosip_unlock ();
-
-
- printf ("the INFO is :\n");
- while (!osip_list_eol ( &(remote_sdp->a_attributes), pos))
- {
- sdp_attribute_t *at;
-
- at = (sdp_attribute_t *) osip_list_get ( &remote_sdp->a_attributes, pos);
- printf ("%s : %s\n", at->a_att_field, at->a_att_value);
-
- pos ++;
- }
- break;
- case EXOSIP_CALL_ACK:
- printf ("ACK recieved!\n");
-
- break;
- case EXOSIP_CALL_CLOSED:
- printf ("the remote hold the session!\n");
-
-
- i = eXosip_call_build_answer (je->tid, 200, &answer);
- if (i != 0)
- {
- printf ("This request msg is invalid!Cann't response!\n");
- eXosip_call_send_answer (je->tid, 400, NULL);
-
- }
- else
- {
- eXosip_call_send_answer (je->tid, 200, answer);
- printf ("bye send 200 over!\n");
- }
- break;
- case EXOSIP_CALL_MESSAGE_NEW:
-
-
-
-
-
-
-
-
-
- printf(" EXOSIP_CALL_MESSAGE_NEW\n");
- if (MSG_IS_INFO(je->request) )
- {
- eXosip_lock ();
- i = eXosip_call_build_answer (je->tid, 200, &answer);
- if (i == 0)
- {
- eXosip_call_send_answer (je->tid, 200, answer);
- }
- eXosip_unlock ();
- {
- osip_body_t *body;
- osip_message_get_body (je->request, 0, &body);
- printf ("the body is %s\n", body->body);
- }
- }
- break;
- default:
- printf ("Could not parse the msg!\n");
- }
- }
- }
- </span>
例子已经上传:http://download.csdn.net/detail/longlong530/5647749
运行示意图:
|