Index of /download/exosip2/,这里选择libeXosip2-3.5.0.tar.gz和libosip2-3.5.0.tar.gz
cd libosip2-3.5.0/
./configure --enable-static
make
make install
cd libeXosip2-3.5.0/
./configure --enable-static
make
make install
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define LISTEN_ADDR ("192.168.50.57")
#define UACPORT ("5061")
#define UACPORTINT (5061)
#define UACCODE ("100110000201000000")
#define UACPWD ("12345")
#define UAS_ADDR ("192.168.50.57")
#define UAS_PORT ("5060")
#define EXPIS 300
static int iCurrentStatus;
static int iHandle = -1;
class CSipFromToHeader
{
public:
CSipFromToHeader()
{
}
~CSipFromToHeader()
{
}
void SetHeader(string addrCod, string addrI, string addrPor)
{
addrCode = addrCod;
addrIp = addrI;
addrPort = addrPor;
}
string GetFormatHeader()
{
std::stringstream stream;
stream << "sip: " << addrCode << "@" << addrIp << ":" << addrPort;
return stream.str();
}
string GetCode()
{
std::stringstream stream;
stream << addrCode;
return stream.str();
}
string GetAddr()
{
std::stringstream stream;
stream << addrIp;
return stream.str();
}
string GetPort()
{
std::stringstream stream;
stream << addrPort;
return stream.str();
}
private:
string addrCode;
string addrIp;
string addrPort;
};
class CContractHeader: public CSipFromToHeader
{
public:
CContractHeader()
{
}
~CContractHeader()
{
}
void SetContractHeader(string addrCod, string addrI, string addrPor)
{
SetHeader(addrCod, addrI, addrPor);
}
string GetContractFormatHeader()
{
std::stringstream stream;
stream << "";
return stream.str();
}
};
int SendRegister(int& registerId, CSipFromToHeader &from, CSipFromToHeader &to,
CContractHeader &contact, const string& userName, const string& pwd,
const int expires, int iType)
{
cout << "=============================================" << endl;
if (iType == 0)
{
cout << "注册请求信息:" << endl;
}
else if (iType == 1)
{
cout << "刷新注册信息:" << endl;
}
else
{
cout << "注销信息:" << endl;
}
cout << "registerId " << registerId << endl;
cout << "from " << from.GetFormatHeader() << endl;
cout << "to " << to.GetFormatHeader() << endl;
cout << "contact" << contact.GetContractFormatHeader() << endl;
cout << "userName" << userName << endl;
cout << "pwd" << pwd << endl;
cout << "expires" << expires << endl;
cout << "=============================================" << endl;
static osip_message_t *regMsg = 0;
int ret;
::eXosip_add_authentication_info(userName.c_str(), userName.c_str(),
pwd.c_str(), "MD5", NULL);
eXosip_lock();
if (0 == registerId)
{
registerId = ::eXosip_register_build_initial_register(
from.GetFormatHeader().c_str(), to.GetFormatHeader().c_str(),
contact.GetContractFormatHeader().c_str(), expires, ®Msg);
if (registerId <= 0)
{
return -1;
}
}
else
{
ret = ::eXosip_register_build_register(registerId, expires, ®Msg);
if (ret != OSIP_SUCCESS)
{
return ret;
}
if (expires == 0)
{
osip_contact_t *contact = NULL;
char tmp[128];
osip_message_get_contact(regMsg, 0, &contact);
{
sprintf(tmp, ";expires=0",
contact->url->username, contact->url->host,
contact->url->port);
}
//osip_contact_free(contact);
//reset contact header
osip_list_remove(®Msg->contacts, 0);
osip_message_set_contact(regMsg, tmp);
osip_message_set_header(regMsg, "Logout-Reason", "logout");
}
}
ret = ::eXosip_register_send_register(registerId, regMsg);
if (ret != OSIP_SUCCESS)
{
registerId = 0;
}eXosip_unlock();
return ret;
}
//注册
void Register()
{
if (iCurrentStatus == 1)
{
cout << "当前已经注册" << endl;
return;
}
CSipFromToHeader stFrom;
stFrom.SetHeader(UACCODE, UAS_ADDR, UAS_PORT);
CSipFromToHeader stTo;
stTo.SetHeader(UACCODE, UAS_ADDR, UAS_PORT);
CContractHeader stContract;
stContract.SetContractHeader(UACCODE, LISTEN_ADDR, UACPORT);
//发送注册信息
int registerId = 0;
if (0 > SendRegister(registerId, stFrom, stTo, stContract, UACCODE, UACPWD,
3000, 0))
{
cout << "发送注册失败" << endl;
return;
}
iCurrentStatus = 1;
iHandle = registerId;
}
//刷新注册
void RefreshRegister()
{
if (iCurrentStatus == 0)
{
cout << "当前未注册,不允许刷新" << endl;
return;
}
CSipFromToHeader stFrom;
stFrom.SetHeader(UACCODE, UAS_ADDR, UAS_PORT);
CSipFromToHeader stTo;
stTo.SetHeader(UACCODE, UAS_ADDR, UAS_PORT);
CContractHeader stContract;
stContract.SetContractHeader(UACCODE, LISTEN_ADDR, UACPORT);
//发送注册信息
if (0 > SendRegister(iHandle, stFrom, stTo, stContract, UACCODE, UACPWD,
3000, 1))
{
cout << "发送刷新注册失败" << endl;
return;
}
}
//注销
void UnRegister()
{
if (iCurrentStatus == 0)
{
cout << "当前未注册,不允许注销" << endl;
return;
}
CSipFromToHeader stFrom;
stFrom.SetHeader(UACCODE, UAS_ADDR, UAS_PORT);
CSipFromToHeader stTo;
stTo.SetHeader(UACCODE, UAS_ADDR, UAS_PORT);
CContractHeader stContract;
stContract.SetContractHeader(UACCODE, LISTEN_ADDR, UACPORT);
//发送注册信息
269 if (0 > SendRegister( iHandle, stFrom, stTo, stContract, UACCODE, UACPWD,
0, 2))
{
cout << "发送注销失败" << endl;
return;
}
iCurrentStatus = 0;
iHandle = -1;
}
static void help()
{
const char
*b =
"-------------------------------------------------------------------------------\n"
"SIP Library test process - uac v 1.0 (June 13, 2014)\n\n"
"SIP UAC端 注册,刷新注册,注销实现\n\n"
"Author: 程序人生\n\n"
"博客地址:http://blog.csdn.net/hiwubihe QQ:1269122125\n\n"
"-------------------------------------------------------------------------------\n"
"\n"
" 0:Register\n"
" 1:RefreshRegister\n"
" 2:UnRegister\n"
" 3:clear scream\n"
" 4:exit\n"
"-------------------------------------------------------------------------------\n"
"\n";
fprintf(stderr, b, strlen(b));
cout << "please select method :";
}
//服务处理线程
void *serverHandle(void *pUser)
{
sleep(3);
help();
char ch = getchar();
getchar();
while (1)
{
switch (ch)
{
case '0':
//注册
Register();
break;
case '1':
//刷新注册
RefreshRegister();
break;
case '2':
//注销
UnRegister();
break;
case '3':
if (system("clear") < 0)
{
cout << "clear scream error" << endl;
exit(1);
}
break;
case '4':
cout << "exit sipserver......" << endl;
getchar();
exit(0);
default:
cout << "select error" << endl;
break;
}
cout << "press any key to continue......" << endl;
getchar();
help();
ch = getchar();
getchar();
}
return NULL;
}
//事件处理线程
void *eventHandle(void *pUser)
{
eXosip_event_t* osipEventPtr = (eXosip_event_t*) pUser;
switch (osipEventPtr->type)
{
//需要继续验证REGISTER是什么类型
case EXOSIP_REGISTRATION_SUCCESS:
case EXOSIP_REGISTRATION_FAILURE:
{
cout<<"收到状态码:"<response->status_code<<"报文"<response->status_code == 401)
{
cout<<"发送鉴权报文"<response->status_code == 200)
{
cout<<"接收成功"<type << endl;
break;
}
eXosip_event_free(osipEventPtr);
return NULL;
}
int main()
{
iCurrentStatus = 0;
//库处理结果
int result = OSIP_SUCCESS;
//初始化库
if (OSIP_SUCCESS != (result = eXosip_init()))
{
printf("eXosip_init failure.\n");
return 1;
}
cout << "eXosip_init success." << endl;
eXosip_set_user_agent(NULL);
//监听
if (OSIP_SUCCESS != eXosip_listen_addr(IPPROTO_UDP, NULL, UACPORTINT,
AF_INET, 0))
{
printf("eXosip_listen_addr failure.\n");
return 1;
}
//设置监听网卡
if (OSIP_SUCCESS != eXosip_set_option(
EXOSIP_OPT_SET_IPV4_FOR_GATEWAY,
LISTEN_ADDR))
{
return -1;
}
//开启服务线程
pthread_t pthser;
if (0 != pthread_create(&pthser, NULL, serverHandle, NULL))
{
printf("创建主服务失败\n");
return -1;
}
//事件用于等待
eXosip_event_t* osipEventPtr = NULL;
//开启事件循环
while (true)
{
//等待事件 0的单位是秒,500是毫秒
osipEventPtr = ::eXosip_event_wait(0, 200);
//处理eXosip库默认处理
{
usleep(500 * 1000);
eXosip_lock();
//一般处理401/407采用库默认处理
eXosip_default_action(osipEventPtr);
eXosip_unlock();
}
//事件空继续等待
if (NULL == osipEventPtr)
{
continue;
}
//开启线程处理事件并在事件处理完毕将事件指针释放
pthread_t pth;
if (0 != pthread_create(&pth, NULL, eventHandle, (void*) osipEventPtr))
{
printf("创建线程处理事件失败\n");
continue;
}
osipEventPtr = NULL;
}
}
g++ test_cli.cpp -o test_cli -I/usr/local/include -L/usr/local/lib -losipparser2 -losip2 -lpthread -leXosip2
四、eXosip2服务端
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define LISTEN_ADDR ("192.168.50.57")
#define UASPORT (5060)
//该系数是由UAS维护的,UAS在接收到UAC的未鉴权报文后,给UAC回复401,在该报文中必须要带相关认证系数和认证方法
//UAS赋值的认证随机数
#define NONCE "9bd055"
//UAS默认加密算法
#define ALGORITHTHM "MD5"
eXosip_t *m_exosip_t;
//SIP From头部
class CSipFromHeader
{
public:
CSipFromHeader()
{
}
~CSipFromHeader()
{
}
void SetHeader(string addrCod, string addrI, string addrPor)
{
addrCode = addrCod;
addrIp = addrI;
addrPort = addrPor;
}
string GetFormatHeader()
{
std::stringstream stream;
stream << "";
return stream.str();
}
//主机名称
string GetRealName()
{
std::stringstream stream;
stream << addrIp;
return stream.str();
}
private:
string addrCode;
string addrIp;
string addrPort;
};
//SIP Contract头部
class CContractHeader: public CSipFromHeader
{
public:
CContractHeader()
{
}
~CContractHeader()
{
}
void SetContractHeader(string addrCod, string addrI, string addrPor,
int expire)
{
SetHeader(addrCod, addrI, addrPor);
expires = expire;
}
string GetContractFormatHeader(bool bExpires)
{
if (!bExpires)
{
return GetFormatHeader();
}
else
{
string sTmp = GetFormatHeader();
std::stringstream stream;
stream << ";" << "expires=" << expires;
sTmp += stream.str();
return sTmp;
}
}
private:
int expires;
};
struct SipContextInfo
{
//Sip层返回的请求的标志 响应时返回即可
int sipRequestId;
//维护一次注册
string callId;
//消息所属的功能方法名字符串
string method;
//地址编码@域名或IP地址:连接端口,例如sip:[email protected]:5060
CSipFromHeader from;
//地址编码@域名或IP地址:连接端口,例如sip:[email protected]:5060
CSipFromHeader proxy;
//地址编码@域名或IP地址:连接端口,例如sip:[email protected]:5060
CContractHeader contact;
//消息内容,一般为DDCP消息体XML文档,或者具体协议帧要求的其他字符串文本
string content;
//响应状态信息
string status;
//超时,时间单位为秒
int expires;
};
struct SipAuthInfo
{
//平台主机名
string digestRealm;
//平台提供的随机数
string nonce;
//用户名
string userName;
//密码
string response;
//“sip:平台地址”,不需要uac赋值
string uri;
//加密算法MD5
string algorithm;
};
struct sipRegisterInfo
{
SipContextInfo baseInfo;
SipAuthInfo authInfo;
bool isAuthNull;
};
void parserRegisterInfo(osip_message_t*request, int iReqId,
sipRegisterInfo ®Info)
{
std::stringstream stream;
regInfo.baseInfo.method = request->sip_method;
regInfo.baseInfo.from.SetHeader(request->from->url->username,
request->from->url->host, request->from->url->port);
regInfo.baseInfo.proxy.SetHeader(request->to->url->username,
request->to->url->host, request->to->url->port);
//获取expires
osip_header_t* header = NULL;
{
osip_message_header_get_byname(request, "expires",
0, &header);
if (NULL != header && NULL != header->hvalue)
{
regInfo.baseInfo.expires = atoi(header->hvalue);
}
}
//contact字段
osip_contact_t* contact = NULL;
osip_message_get_contact(request, 0, &contact);
if (NULL != contact)
{
regInfo.baseInfo.contact.SetContractHeader(contact->url->username,
contact->url->host, contact->url->port,
regInfo.baseInfo.expires);
}
//注册返回 由发送方维护的请求ID 接收方接收后原样返回即可
regInfo.baseInfo.sipRequestId = iReqId;
//CALL_ID
{
stream.str("");
stream << request->call_id->number;
regInfo.baseInfo.callId = stream.str();
}
//解析content消息
osip_body_t * body = NULL;
osip_message_get_body(request, 0, &body);
if (body != NULL)
{
stream.str("");
stream << body->body;
regInfo.baseInfo.content = stream.str();
}
//鉴权信息
osip_authorization_t* authentication = NULL;
{
osip_message_get_authorization(request, 0, &authentication);
if (NULL == authentication)
{
regInfo.isAuthNull = true;
}
else
{
regInfo.isAuthNull = false;
stream.str("");
stream << authentication->username;
regInfo.authInfo.userName = stream.str();
stream.str("");
stream << authentication->algorithm;
regInfo.authInfo.algorithm = stream.str();
stream.str("");
stream << authentication->realm;
regInfo.authInfo.digestRealm = stream.str();
stream.str("");
stream << authentication->nonce;
regInfo.authInfo.nonce = stream.str();
stream.str("");
stream << authentication->response;
regInfo.authInfo.response = stream.str();
stream.str("");
stream << authentication->uri;
regInfo.authInfo.uri = stream.str();
}
}
authentication = NULL;
}
//打印接收到的响应报文
void printRegisterPkt( sipRegisterInfo&info)
{
cout<<"接收到报文:"<request, osipEvent->tid, regInfo);
//打印报文
printRegisterPkt(regInfo);
//发送应答报文
sendRegisterAnswer(regInfo);
}
int main()
{
int result = OSIP_SUCCESS;
m_exosip_t = eXosip_malloc();
// init exosip.
if (OSIP_SUCCESS != (result = eXosip_init(m_exosip_t)))
{
printf("eXosip_init failure.\n");
return 1;
}
cout << "eXosip_init success." << endl;
//
// if (null_ptr != this->receiveSipMessageCallback || null_ptr
// != this->sendSipMessageCallback)
// {
// if (OSIP_SUCCESS != (result = ::eXosip_set_cbsip_message(
// &Sip::MessageCallback)))
// {
// return;
// }
// }
eXosip_set_user_agent(m_exosip_t,NULL);
if (OSIP_SUCCESS != eXosip_listen_addr(m_exosip_t, IPPROTO_UDP, NULL, UASPORT, AF_INET,
0))
{
printf("eXosip_listen_addr failure.\n");
return 1;
}
if (OSIP_SUCCESS != eXosip_set_option(m_exosip_t,
EXOSIP_OPT_SET_IPV4_FOR_GATEWAY,
LISTEN_ADDR))
{
return -1;
}
//开启循环消息,实际应用中可以开启多线程同时接收信号
eXosip_event_t* osipEventPtr = NULL;
while (true)
{
// Wait the osip event.
osipEventPtr = ::eXosip_event_wait(m_exosip_t, 0, 200);// 0的单位是秒,500是毫秒
// If get nothing osip event,then continue the loop.
if (NULL == osipEventPtr)
{
continue;
}
// 事件处理
switch (osipEventPtr->type)
{
//需要继续验证REGISTER是什么类型
//case EXOSIP_REGISTRATION_NEW:
//OnRegister(osipEventPtr);
//break;
case EXOSIP_MESSAGE_NEW:
{
if (!strncmp(osipEventPtr->request->sip_method, "REGISTER",
strlen("REGISTER")))
{
OnRegister(osipEventPtr);
}
else if (!strncmp(osipEventPtr->request->sip_method, "MESSAGE",
strlen("MESSAGE")))
{
//
}
}
break;
default:
cout
<< "The sip event type that not be precessed.the event "
"type is : "
<< osipEventPtr->type;
break;
}
//ProcessSipEvent(this->osipEventPtrParam);
eXosip_event_free(osipEventPtr);
osipEventPtr = NULL;
}
return 0;
}
g++ test_srv.cpp -o test_srv -I/usr/local/include -L/usr/local/lib -losipparser2 -losip2 -lpthread -leXosip2