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 <iostream>
- #include <string>
- #include <sstream>
- #include <osipparser2/osip_message.h>
- #include <osipparser2/osip_parser.h>
- #include <osipparser2/osip_port.h>
-
- #include <eXosip2/eXosip.h>
- #include <eXosip2/eX_setup.h>
- #include <eXosip2/eX_register.h>
- #include <eXosip2/eX_options.h>
- #include <eXosip2/eX_message.h>
- #include <arpa/inet.h>
- #include <sys/types.h>
- #include <sys/socket.h>
-
- 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 << "
<< GetCode() << "@" << GetAddr() << ":" << GetPort() - << ">";
- 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<<"收到状态码:"<<osipEventPtr->response->status_code<<"报文"<<endl;
- if(osipEventPtr->response->status_code == 401)
- {
- cout<<"发送鉴权报文"<<endl;
- }
- else if(osipEventPtr->response->status_code == 200)
- {
- cout<<"接收成功"<<endl;
- }
- else
- {}
- }
- break;
- default:
- cout << "The sip event type that not be precessed.the event "
- "type is : " << osipEventPtr->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 <string.h>
- #include <iostream>
- #include <string>
- #include <sstream>
- #include <osipparser2/osip_message.h>
- #include <osipparser2/osip_parser.h>
- #include <osipparser2/osip_port.h>
-
- #include <eXosip2/eXosip.h>
- #include <eXosip2/eX_setup.h>
- #include <eXosip2/eX_register.h>
- #include <eXosip2/eX_options.h>
- #include <eXosip2/eX_message.h>
- #include <arpa/inet.h>
- #include <sys/types.h>
- #include <sys/socket.h>
-
- 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 << "
<< addrCode << "@" << addrIp << ":" << addrPort - << ">";
- 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:1111@127.0.0.1:5060
- CSipFromHeader from;
- //地址编码@域名或IP地址:连接端口,例如sip:1111@127.0.0.1:5060
- CSipFromHeader proxy;
- //地址编码@域名或IP地址:连接端口,例如sip:1111@127.0.0.1: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<<"接收到报文:"<<endl;
- cout<<"=============================================="
- "=================="<<endl;
- cout << "method:" << info.baseInfo.method << endl;
- cout << "from: " << info.baseInfo.from.GetFormatHeader() << endl;
- cout << "to:" << info.baseInfo.proxy.GetFormatHeader() << endl;
- cout << "contact:" << info.baseInfo.contact.GetContractFormatHeader(false)
- << endl;
-
- //注册返回 由发送方维护的请求ID 接收方接收后原样返回即可
- cout << "sipRequestId:" << info.baseInfo.sipRequestId << endl;
- //CALL_ID
- cout << "CallId:" << info.baseInfo.callId << endl;
- //解析content消息
- cout << "body:" << info.baseInfo.content << endl;
- //获取expires
- cout << "expires:" << info.baseInfo.expires << endl;
- //鉴权信息
- if (info.isAuthNull)
- {
- cout << "当前报文未提供鉴权信息!!!" << endl;
- }
- else
- {
- cout << "当前报文鉴权信息如下:" << endl;
- cout << "username:" << info.authInfo.userName << endl;
- cout << "algorithm:" << info.authInfo.algorithm << endl;
- cout << "Realm:" << info.authInfo.digestRealm << endl;
- cout << "nonce:" << info.authInfo.nonce << endl;
- cout << "response:" << info.authInfo.response << endl;
- cout << "uri:" << info.authInfo.uri << endl;
- }
- cout<<"=================================================="
- "=============="<<endl;
- return;
- }
- void sendRegisterAnswer( sipRegisterInfo&info)
- {
- osip_message_t* answer = NULL;
- int iStatus;
- if (info.isAuthNull)
- {
- iStatus = 401;
- }
- else
- {
- iStatus = 200;
- }
- eXosip_lock(m_exosip_t);
- {
- int result = ::eXosip_message_build_answer(m_exosip_t, info.baseInfo.sipRequestId,
- iStatus, &answer);
- if (iStatus == 401)
- {
- //由SIP库生成认证方法和认证参数发送客户端
- std::stringstream stream;
- string nonce=NONCE;
- string algorithm=ALGORITHTHM;
- stream << "Digest realm=\"" << info.baseInfo.from.GetRealName()
- << "\",nonce=\"" << nonce
- << "\",algorithm=" << algorithm;
-
- osip_message_set_header(answer, "WWW-Authenticate",
- stream.str().c_str());
- cout<<"======================================================="
- "========="<<endl;
- cout<<"发送401报文"<<endl;
- cout<<"========================================================"
- "========"<<endl;
- }
- else if (iStatus == 200)
- {
- osip_message_set_header(answer, "Contact",
- info.baseInfo.contact.GetContractFormatHeader(true).c_str());
- cout<<"========================================================="
- "======="<<endl;
- cout<<"发送200报文"<<endl;
- cout<<"=========================================================="
- "======"<<endl;
- //string_t b = "
;expires=600" ; - //osip_message_set_header(answer, "Contact", b.c_str());
- }
- else
- {
- //Do nothing
- }
-
- if (OSIP_SUCCESS != result)
- {
- ::eXosip_message_send_answer(m_exosip_t, info.baseInfo.sipRequestId, 400, NULL);
- }
- else
- {
- //发送消息体
- ::eXosip_message_send_answer(m_exosip_t, info.baseInfo.sipRequestId, iStatus,
- answer);
- }
- if (0 == info.baseInfo.expires)
- {
- eXosip_register_remove(m_exosip_t, info.baseInfo.sipRequestId);
- }
- }
- eXosip_unlock(m_exosip_t);
- }
- void OnRegister(eXosip_event_t *osipEvent)
- {
- sipRegisterInfo regInfo;
- parserRegisterInfo(osipEvent->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