1、获取 libeXosip2-4.1.0.tar.gz、 libosip2-4.1.0.tar.gz
下载地址为:http://www.antisip.com/download/exosip2/
2、获取c-ares-1.11.0.tar.gz
下载地址为:http://c-ares.haxx.se/
3、新建一个src目录
解压 libeXosip2-4.1.0.tar.gz、libosip2-4.1.0.tar.gz、c-ares-1.11.0.tar.gz得到libeXosip2-4.1.0、libosip2-4.1.0、c-ares-1.11.0文件夹,把libeXosip2-4.1.0、libosip2-4.1.0、c-ares-1.11.0分加改名得到eXosip、osip、c-ares三个文件夹。
4、打开解决方案
libosip2-4.1.0等默认的几个工程是VS2012的工程。
使用VS2015打开eXosip\platform\vsnet\eXosip.sln解决方案后,
会弹出[升级VC++编译器和库]的窗口。点击确定后,工程会自动升级到VS2015。
5、编译osip2:
<1>使用VS2015打开libosip2-4.1.0/platform/vsnet/osip.sln
<2>使用VS2015打开osip/platform/vsnet/osip.sln,会弹出[升级VC++编译器和库]的窗口。点击确定后,工程会自动升级到VS2015。
<3>选择《生成解决方案》进行一起编译生Debug(使用静态库)
<4>从v140/Win32/Debug文件夹中得到osip2.lib和osipparser2.lib库
<5>编译过程出现以下错误:
错误1:
error “fatal error C1189: #error: Macro definition of snprintfconflicts with Standard Library function declaration”
解决办法:
在osip2目录里打开port_condv.c 和 internal.h文件,注释掉defined(WIN32)下的 #define snprintf _snprintf
错误2:
error C2011: “timespec”:“struct”类型重定义
解决办法:
在项目属性-c/c++-预处理器-预处理器定义里增加宏 HAVE_STRUCT_TIMESPEC
警告1:
在WIN10系统中编译出现如下警告:
osip\include\osipparser2/internal.h(71):warning C4067: 预处理器指令后有意外标记 - 应输入换行符
osip\include\osip2/internal.h(163):warning C4067: 预处理器指令后有意外标记 - 应输入换行符
解决办法:
在internal.h文件中找到如下内容:
#if(_MSC_VER >= 1700) && !defined(_USING_V110_SDK71_)
#include<winapifamily.h>
#endif
在#include<winapifamily.h>后面增加宏定义如下
#defineWINAPI_FAMILY_ONE_PARTITION(PartitionSet, Partition) ((WINAPI_FAMILY &PartitionSet) == Partition)
6、编译eXosip2:
由于eXosip依赖于libcares、osip2、osipparser2这3个库。按上面的目录结构,工程不需要特别配置。
直接编译eXosip
在vsnet/v140/Win32/Debug下得到eXosip.lib、libcares.lib、osip2.lib、osipparser2.lib四个静态库。
7、编译过程出现以下错误:
错误1:
C:\ProgramFiles(x86)\MSBuild\Microsoft.Cpp\v4.0\Platforms\Win32\Microsoft.Cpp.Win32.
Targets(511,5): errorMSB8008:指定的平台工具集(v100)未安装或无效。请确保选择受支持的 PlatformToolset 值。
解决办法:
这个问题主要是在工程序转换的时候,c-ares项目默认为VS2012工程, 在c-ares项目点击右键-属性-配置属性-常规-平台工作集把V110改为V140。
错误2:
fatal error C1083: 无法打开包括文件: “nameser.h”: Nosuch file or directory
解决办法:
在项目属性-c/c++-预处理器-预处理器定义里去掉宏SRV_RECORD
错误3:
fatal error C1083: 无法打开包括文件: “tsc_socket_api.h”:No such file or directory
解决办法:
在项目属性-c/c++-预处理器-预处理器定义里去掉宏TSC_SUPPORT
错误4:
error “fatal error C1189: #error: Macro definition of snprintfconflicts with Standard Library function declaration”
解决办法:
在eXosip目录里打开eXosip2.h文件,注释掉defined(WIN32)下的 #define snprintf _snprintf
错误5:
error C2011: “timespec”:“struct”类型重定义
解决办法:
在项目属性-c/c++-预处理器-预处理器定义里增加宏 HAVE_STRUCT_TIMESPEC
错误6 :
找不到 eXrefer_api.c
解决方法:
在编译 libexosip2-5.0.0.tar.gz 这个版本时出现一个缺失文件的问题,后来发现时这个版本中就是缺失了“eXrefer_api.c”这个文件,而在其配置文件中添加了这个文件,导致找不到这个文件。后来在前面的版本中找到了这个文件加进去后就没问题了。
参考:
http://blog.csdn.net/dgyanyong/article/details/50818101
http://blog.csdn.net/htbsoft0556/article/details/19540333
#include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h>
#include <ws2tcpip.h>
#include <eXosip2/eXosip.h>
#include <string.h>
#define BUFFSIZE 1024
#define DEST_CALL "sip:172.16.2.13"
#define SOURCE_CALL "sip:172.16.5.30:5060"
#define DEST_PORT 5061
//发送subscribe数据包
int SendSubscribe()
{
eXosip_event_t *je;
int i = 0;
osip_message_t *subscribe;
char tmp[BUFFSIZE];
//初始化
i = eXosip_init();
if (i != 0)
{
printf("Can not initialize eXosip!\n");
return -1;
}
else
{
printf("eXosip_init successfully!\n");
}
//绑定端口
i = eXosip_listen_addr(IPPROTO_UDP, NULL, 5061, AF_INET, 0);
if (i != 0)
{
eXosip_quit();
printf("eXosip_listen_addr failed!\n");
}
else
{
printf("eXosip_listen_addr sucess\n");
}
//subscribe,发起呼叫请求
i=eXosip_subscribe_build_initial_request(&subscribe, DEST_CALL, SOURCE_CALL, NULL, "SE-INFO", 3600);
if(i != 0)
{
fprintf(stderr, "Initial INVITE failed!, %s\n", strerror(errno));
}
else
{
printf("Initial INVITE sucess!\n");
}
snprintf (tmp, 1024,
"GET:FirmwareVer\r\n" //话机的版本
"GET:MacAddress\r\n" //话机的MAC地址
"GET:ConfigVer\r\n" //配置文件的版本
//"SET:Telnet ip=192.168.3.108 port=5060\r\n"
//"SET:Reboot\r\n"
);
osip_message_set_body(subscribe,tmp,strlen(tmp));
osip_message_set_content_type(subscribe,"application/SEM-TEXT");
eXosip_lock();
i=eXosip_subscribe_send_initial_request(subscribe);
eXosip_unlock();
while (1)
{
je = eXosip_event_wait (0, 200);
if (je == NULL)
{
continue;
}
else
{
switch(je->type) //可能会到来的事件类型
{
case EXOSIP_SUBSCRIPTION_ANSWERED: //announce a 200ok
printf("收到200 OK!!\n");
break;
case EXOSIP_SUBSCRIPTION_NOTIFY: //announce new NOTIFY
{
printf("收到EXOSIP_SUBSCRIPTION_NOTIFY!\n");
osip_body_t *body;
osip_message_get_body (je->request, 0, &body);
printf("%s\n", body->body);
}
break;
case EXOSIP_SUBSCRIPTION_REQUESTFAILURE: // announce a request failure
printf("EXOSIP_SUBSCRIPTION_REQUESTFAILURE!\n");
break;
case EXOSIP_CALL_ANSWERED: //收到200 OK,表示请求已经被成功接受,用户应答
printf("收到200 OK!\n");
//int call_id=je->cid;
//int dialog_id=je->did;
printf("call_id is %d,dialog_id is %d, je_status is %s, %s\n",je->cid,je->did, je->ss_status, je->ss_reason);
//回送ack应答消息
//eXosip_call_build_ack(je->did,&ack);
//eXosip_call_send_ack(je->did,ack);
break;
case EXOSIP_SUBSCRIPTION_PROCEEDING:
{
printf("EXOSIP_SUBSCRIPTION_PROCEEDING!\n");
break;
}
case EXOSIP_SUBSCRIPTION_REDIRECTED:
{
printf("EXOSIP_SUBSCRIPTION_REDIRECTED!\n");
break;
}
case EXOSIP_SUBSCRIPTION_SERVERFAILURE:
{
printf("EXOSIP_SUBSCRIPTION_SERVERFAILURE!\n");
printf("call_id is %d,dialog_id is %d, je_status is %s, %s\n",je->cid,je->did, je->ss_status, je->ss_reason);
break;
}
case EXOSIP_SUBSCRIPTION_GLOBALFAILURE:
{
printf("EXOSIP_SUBSCRIPTION_GLOBALFAILURE!\n");
break;
}
case EXOSIP_IN_SUBSCRIPTION_NEW:
{
printf("EXOSIP_IN_SUBSCRIPTION_NEW!\n");
break;
}
default: //收到其他应答
printf("other response!\n");
if (je->textinfo[0]!='/0')
{
printf( "(%i %i %i %i) %s", je->cid, je->sid, je->nid, je->did, je->textinfo);
}
break;
}
}
}
eXosip_event_free(je); //Free ressource in an eXosip event
}