Commit 3a5bc7be623ddf1066b8738a40a4813ef6103191

Authored by Hu Chunming
1 parent 83754e4c

添加无鉴权;支持摄像头直连

sip/Message/CatalogParser.cpp
... ... @@ -632,6 +632,45 @@ std::vector< DeviceInfo > CCatalogParser::DecodeCatlog(const char* body)
632 632 return cat_list;
633 633 }
634 634  
  635 +DeviceInfo CCatalogParser::DecodeDeviceInfo(const char* body)
  636 +{
  637 + DeviceInfo info;
  638 +
  639 + tinyxml2::XMLDocument doc;
  640 + doc.Parse(body);
  641 + tinyxml2::XMLElement* pRoot = doc.RootElement();
  642 + if (pRoot == NULL) {
  643 + return info;
  644 + }
  645 +
  646 + tinyxml2::XMLNode* pChild = 0;
  647 + std::vector< tinyxml2::XMLNode* > nodes;
  648 + for (tinyxml2::XMLNode* pNode = pRoot->FirstChild(); pNode != 0; pNode = pNode->NextSibling())
  649 + {
  650 + std::string value = pNode->Value();
  651 + pChild = pNode->FirstChild();
  652 + if (value == "DeviceID")
  653 + {
  654 + info.id = pChild->Value();
  655 + info.parentid = info.id;
  656 + }
  657 + else if (value == "DeviceName")
  658 + {
  659 + info.name = pChild->Value();
  660 + }
  661 + else if (value == "Manufacturer")
  662 + {
  663 + info.manufacturer = pChild->Value();
  664 + }
  665 + else if (value == "Model")
  666 + {
  667 + info.model = pChild->Value();
  668 + }
  669 + }
  670 +
  671 + return info;
  672 +}
  673 +
635 674 string CCatalogParser::getItemValue(tinyxml2::XMLNode *pItem) {
636 675  
637 676 tinyxml2::XMLNode *pValue = pItem->FirstChild();
... ...
sip/Message/CatalogParser.h
... ... @@ -18,6 +18,8 @@ public:
18 18  
19 19 std::vector<DeviceInfo> DecodeCatlog(const char* body);
20 20  
  21 + DeviceInfo DecodeDeviceInfo(const char* body);
  22 +
21 23 ServerInfo DecodeServerConfig(const char* body);
22 24  
23 25 static std::string GetStrName(EEventType eType)
... ...
sip/SipServer.cpp
... ... @@ -22,8 +22,6 @@
22 22 #include <sstream>
23 23 #include <algorithm>
24 24  
25   -#include "WebSocketServer.h"
26   -
27 25  
28 26 using namespace std;
29 27  
... ... @@ -132,7 +130,11 @@ int SipServer::sip_event_handle(eXosip_event_t *evtp) {
132 130 // LOG_INFO("EXOSIP_MESSAGE_NEW type={}",evtp->type);
133 131  
134 132 if (MSG_IS_REGISTER(evtp->request)) {
135   - this->response_register(evtp);
  133 + if (mInfo.isNoAuth()) {
  134 + response_register_noauth(evtp);
  135 + } else {
  136 + response_register(evtp);
  137 + }
136 138 }
137 139 else if (MSG_IS_MESSAGE(evtp->request)) {
138 140 this->response_message(evtp);
... ... @@ -250,9 +252,12 @@ int SipServer::init_sip_server() {
250 252 return -1;
251 253 }
252 254 eXosip_set_user_agent(mSipCtx, mInfo.getUa().c_str());
253   - if (eXosip_add_authentication_info(mSipCtx, mInfo.getSipId().c_str(), mInfo.getSipId().c_str(), mInfo.getSipPass().c_str(), NULL, mInfo.getSipRealm().c_str())) {
254   - LOG_ERROR("eXosip_add_authentication_info error");
255   - return -1;
  255 +
  256 + if (!mInfo.isNoAuth()) {
  257 + if (eXosip_add_authentication_info(mSipCtx, mInfo.getSipId().c_str(), mInfo.getSipId().c_str(), mInfo.getSipPass().c_str(), NULL, mInfo.getSipRealm().c_str())) {
  258 + LOG_ERROR("eXosip_add_authentication_info error");
  259 + return -1;
  260 + }
256 261 }
257 262  
258 263 return 0;
... ... @@ -325,12 +330,38 @@ void SipServer::response_message_answer(eXosip_event_t *evtp,int code){
325 330 else{
326 331 LOG_ERROR("code={},returnCode={},bRegister={}",code,returnCode,bRegister);
327 332 }
  333 +}
  334 +
  335 +void SipServer::response_register_noauth(eXosip_event_t *evtp) {
  336 + int expire = -1;
  337 + osip_header_t* header = NULL;
  338 + osip_message_header_get_byname(evtp->request, "expires", 0, &header);
  339 + if (NULL != header && NULL != header->hvalue) {
  340 + expire = atoi(header->hvalue);
  341 + }
  342 +
  343 + osip_contact_t *contact = nullptr;
  344 + osip_message_get_contact (evtp->request, 0, &contact);
  345 + if (!(contact && contact->url)) {
  346 + LOG_WARN("contact is null.");
  347 + return ;
  348 + }
  349 +
  350 + if (expire <= 0) {
  351 + std::lock_guard<std::mutex> l(m_client_map_mtx);
  352 + string sip_id = strdup(contact->url->username);
  353 + deleteClientByDevice(sip_id);
  354 + LOG_INFO("unregister succeed:{}", sip_id);
  355 + return ;
  356 + }
  357 +
  358 + dump_request(evtp);
328 359  
  360 + response_message_answer(evtp,200);
  361 + cacheClient(contact->url, expire);
329 362 }
330   -void SipServer::response_register(eXosip_event_t *evtp) {
331 363  
332   - osip_authorization_t * auth = nullptr;
333   - osip_message_get_authorization(evtp->request, 0, &auth);
  364 +void SipServer::response_register(eXosip_event_t *evtp) {
334 365  
335 366 int expire = -1;
336 367 osip_header_t* header = NULL;
... ... @@ -347,13 +378,18 @@ void SipServer::response_register(eXosip_event_t *evtp) {
347 378 }
348 379  
349 380 if (expire <= 0) {
  381 + std::lock_guard<std::mutex> l(m_client_map_mtx);
350 382 string sip_id = strdup(contact->url->username);
351 383 deleteClientByDevice(sip_id);
352 384 LOG_INFO("unregister succeed:{}", sip_id);
353 385 return ;
354 386 }
355 387  
356   - if(auth && auth->username){
  388 + dump_request(evtp);
  389 +
  390 + osip_authorization_t * auth = nullptr;
  391 + osip_message_get_authorization(evtp->request, 0, &auth);
  392 + if(auth && auth->uri){
357 393  
358 394 char *method = NULL, // REGISTER
359 395 *algorithm = NULL, // MD5
... ... @@ -405,30 +441,63 @@ void SipServer::response_register(eXosip_event_t *evtp) {
405 441 }
406 442 }
407 443  
  444 +int SipServer::check_device_type(string sip_id) {
  445 + if (sip_id.length() != 20) {
  446 + LOG_ERROR("sip id error:{}", sip_id);
  447 + return -1;
  448 + }
  449 + string strType = sip_id.substr(10, 3);
  450 +
  451 + int type = atoi(strType.c_str());
  452 +
  453 + LOG_DEBUG("device type: {}", type);
  454 +
  455 + return type;
  456 +}
  457 +
408 458 void SipServer::cacheClient(osip_uri_t *url, int expiry) {
409 459  
410 460 string sip_id = strdup(url->username);
411 461  
  462 + int type = check_device_type(sip_id);
  463 + if (-1 == type) {
  464 + return;
  465 + }
  466 +
412 467 long cur_ts = Utools::get_cur_time_ms();
413 468  
414 469 // 已经注册的不再注册
415 470 std::lock_guard<std::mutex> l(m_client_map_mtx);
416 471 auto it = mClientMap.find(sip_id);
417 472 if (it != mClientMap.end()) {
418   - it->second->setExpiry(expiry);
419   - it->second->updateHeartBeat(cur_ts);
420   - return ;
  473 + if (cur_ts - it->second->getHeartBeat() < 5*60*1000) {
  474 + it->second->setExpiry(expiry);
  475 + it->second->updateHeartBeat(cur_ts);
  476 + return ;
  477 + } else {
  478 + deleteClientByDevice(sip_id);
  479 + LOG_INFO("与上次注册时间超过5分钟,重新缓存:{}", sip_id);
  480 + }
421 481 }
422 482  
423   - Client* client = new Client(strdup(url->host), atoi(url->port), strdup(url->username));
  483 + Client* client = new Client(strdup(url->host), atoi(url->port), sip_id);
424 484 client->setExpiry(expiry);
425 485 client->updateHeartBeat(cur_ts);
426 486  
427 487 LOG_INFO("Camera registration succee,ip={},port={},device={}",client->getIp(),client->getPort(),client->getDevice());
428 488  
429 489 mClientMap.insert(std::make_pair(client->getDevice(),client));
430   - // NVR注册成功,立即请求设备目录
431   - RequestCatalog(client);
  490 +
  491 + if (type >= 111 && type <= 130) {
  492 + // NVR注册成功,立即请求设备目录
  493 + RequestCatalog(client);
  494 + } else if (type >= 131 && type <= 199) {
  495 + RequestDeviceInfo(client);
  496 + }
  497 + else {
  498 + LOG_WARN("device type is not supported:{}",type);
  499 + }
  500 +
432 501 }
433 502  
434 503 void SipServer::response_register_401unauthorized(eXosip_event_t *evtp) {
... ... @@ -475,6 +544,11 @@ void SipServer::response_message(eXosip_event_t *evtp) {
475 544 parse_xml(body->body, "<CmdType>", false, "</CmdType>", false, CmdType);
476 545 parse_xml(body->body, "<DeviceID>", false, "</DeviceID>", false, DeviceID);
477 546 }
  547 + else {
  548 + return;
  549 + }
  550 +
  551 + // std::cout << CmdType << std::endl;
478 552  
479 553 if(!strcmp(CmdType, "Catalog")) {
480 554 this->response_message_answer(evtp,200);
... ... @@ -488,8 +562,17 @@ void SipServer::response_message(eXosip_event_t *evtp) {
488 562 DeviceInfo info = vec_device[i];
489 563 m_device_map[info.id] = info;
490 564 }
491   - }
492   - else if(!strcmp(CmdType, "Keepalive")){
  565 + } else if (!strcmp(CmdType, "DeviceInfo")) {
  566 + this->response_message_answer(evtp, 200);
  567 + // 需要根据对方的Catelog请求,做一些相应的应答请求
  568 + CCatalogParser catPaser;
  569 + DeviceInfo info = catPaser.DecodeDeviceInfo(body->body);
  570 + info.status = "on"; // 有值返回就已经可以表明设备状态在线了
  571 +
  572 + std::lock_guard<std::mutex> l(m_device_map_mtx);
  573 + m_device_map[info.id] = info;
  574 +
  575 + } else if(!strcmp(CmdType, "Keepalive")){
493 576 this->response_message_answer(evtp,200);
494 577 // LOG_INFO("CmdType={},DeviceID={}", CmdType, DeviceID);
495 578 std::lock_guard<std::mutex> l_c(m_client_map_mtx);
... ... @@ -616,7 +699,7 @@ int SipServer::reInvite(int cid) {
616 699  
617 700 if (ret <= 0) {
618 701 LOG_ERROR("reInvite failed!");
619   - m_pWsServer->response_client(strChannelId, iPort, cmd, ret);
  702 + //m_pWsServer->response_client(strChannelId, iPort, cmd, ret);
620 703 }
621 704 }
622 705 }
... ... @@ -624,10 +707,6 @@ int SipServer::reInvite(int cid) {
624 707 return -1;
625 708 }
626 709  
627   -int SipServer::inviteFailedResponse(int cid) {
628   -
629   -}
630   -
631 710 int SipServer::RequestInvite_UDP(const char* dst_channel, const char* rtpIp, int rtpPort) {
632 711  
633 712 // 检查设备是否在线
... ... @@ -765,9 +844,44 @@ void SipServer::cacheCatalog() {
765 844 return ;
766 845 }
767 846  
  847 + long cur_ts = Utools::get_cur_time_ms();
  848 +
  849 + vector<string> vec_sip_id;
  850 +
768 851 LOG_INFO("client size:{}", mClientMap.size());
769 852 for (auto it = mClientMap.begin(); it != mClientMap.end(); it++) {
770   - RequestCatalog(it->second);
  853 + //RequestCatalog(it->second);
  854 + Client* client = it->second;
  855 + if (!client) {
  856 + continue;
  857 + }
  858 +
  859 + string sip_id = client->getDevice();
  860 +
  861 + unsigned long gap = client->getHeartBeatGap();
  862 + if (gap > 0 && (cur_ts - client->getHeartBeat()) > 10 * gap) {
  863 + LOG_WARN("{}:超过10个心跳周期未收到心跳", sip_id);
  864 + vec_sip_id.push_back(sip_id);
  865 + continue;
  866 + }
  867 +
  868 + int type = check_device_type(sip_id);
  869 + if (-1 == type) {
  870 + continue;
  871 + }
  872 +
  873 + if (type >= 111 && type <= 130) {
  874 + // NVR注册成功,立即请求设备目录
  875 + RequestCatalog(client);
  876 + }
  877 + else if (type >= 131 && type <= 199) {
  878 + RequestDeviceInfo(client);
  879 + }
  880 + }
  881 +
  882 + // 超过10个心跳周期未收到心跳,做下线处理
  883 + for (size_t i = 0; i < vec_sip_id.size(); i++) {
  884 + deleteClientByDevice(vec_sip_id[i]);
771 885 }
772 886 }
773 887  
... ... @@ -803,6 +917,37 @@ void SipServer::RequestCatalog(Client* client) {
803 917 eXosip_unlock(mSipCtx);
804 918 }
805 919  
  920 +void SipServer::RequestDeviceInfo(Client* client) {
  921 + eXosip_lock(mSipCtx);
  922 +
  923 + osip_message_t* catlog_msg = NULL;
  924 + char to[100];/*sip:主叫用户名@被叫IP地址*/
  925 + char from[100];/*sip:被叫IP地址:被叫IP端口*/
  926 + char xml_body[4096];
  927 +
  928 + memset(to, 0, 100);
  929 + memset(from, 0, 100);
  930 + memset(xml_body, 0, 4096);
  931 +
  932 + sprintf(from, "sip:%s@%s:%d", mInfo.getSipId().c_str(), mInfo.getIp().c_str(), mInfo.getPort());
  933 + sprintf(to, "sip:%s@%s:%d", client->getDevice().c_str(), client->getIp().c_str(), client->getPort());
  934 + eXosip_message_build_request(mSipCtx, &catlog_msg, "MESSAGE", to, from, NULL);/*构建"MESSAGE"请求*/
  935 +
  936 + snprintf(xml_body, 4096,
  937 + "<?xml version=\"1.0\"?>"
  938 + "<Query>"
  939 + "<CmdType>DeviceInfo</CmdType>"
  940 + "<SN>%d</SN>"
  941 + "<DeviceID>%s</DeviceID>"
  942 + "</Query>", rand() % (99999 - 10000 + 1) + 10000, client->getDevice().c_str());
  943 +
  944 + osip_message_set_body(catlog_msg, xml_body, strlen(xml_body));
  945 + osip_message_set_content_type(catlog_msg, "Application/MANSCDP+xml");
  946 + eXosip_message_send_request(mSipCtx, catlog_msg);
  947 +
  948 + eXosip_unlock(mSipCtx);
  949 +}
  950 +
806 951 int SipServer::clearClientMap(){
807 952 std::lock_guard<std::mutex> l(m_client_map_mtx);
808 953 for (auto iter=mClientMap.begin(); iter!=mClientMap.end(); iter++) {
... ... @@ -815,7 +960,7 @@ int SipServer::clearClientMap(){
815 960 }
816 961  
817 962 void SipServer::deleteClientByDevice(string device) {
818   - std::lock_guard<std::mutex> l(m_client_map_mtx);
  963 + // std::lock_guard<std::mutex> l(m_client_map_mtx); 外部调用函数的时候注意加锁,这里去掉加锁
819 964 auto it = mClientMap.find(device);
820 965 if (it == mClientMap.end()) {
821 966 return ;
... ...
sip/SipServer.h
... ... @@ -53,6 +53,18 @@ public:
53 53  
54 54 void updateHeartBeat(unsigned long ts) {
55 55 mHeartBeatTime = ts;
  56 + mHeartBeatCount++;
  57 + if (mHeartBeatFirst <= 0){
  58 + mHeartBeatFirst = ts;
  59 + }
  60 + }
  61 +
  62 + unsigned long getHeartBeatGap() {
  63 + if (mHeartBeatCount >= 2)
  64 + {
  65 + return (mHeartBeatTime - mHeartBeatFirst)/mHeartBeatCount ;
  66 + }
  67 + return 0;
56 68 }
57 69  
58 70 long getExpiry() {
... ... @@ -70,6 +82,9 @@ private:
70 82 bool mIsReg;
71 83 int mRtpPort;
72 84 unsigned long mHeartBeatTime{0};
  85 + unsigned long mHeartBeatFirst{0};
  86 + unsigned long mHeartBeatGap{1};
  87 + unsigned long mHeartBeatCount{0};
73 88 long mExipry{0};
74 89 };
75 90  
... ... @@ -102,10 +117,13 @@ private:
102 117 void RequestCatalog(Client* client);
103 118 void cacheCatalog();
104 119  
  120 + void RequestDeviceInfo(Client* client);
  121 +
105 122 void cacheClient(osip_uri_t *url, int expiry);
106 123  
107 124 void response_message_answer(eXosip_event_t *evtp,int code);
108 125 void response_register(eXosip_event_t *evtp);
  126 + void response_register_noauth(eXosip_event_t *evtp);
109 127 void response_register_401unauthorized(eXosip_event_t *evt);
110 128 void response_message(eXosip_event_t *evtp);
111 129 void response_invite_ack(eXosip_event_t *evtp);
... ... @@ -124,7 +142,7 @@ private:
124 142  
125 143 int reInvite(int cid);
126 144  
127   - int inviteFailedResponse(int cid);
  145 + int check_device_type(string sip_id);
128 146  
129 147 private:
130 148 bool mQuit{ false };
... ...
sip/WebSocketServer.cpp
... ... @@ -30,9 +30,8 @@ int WebSocketServer::parse_invite(vector&lt;string&gt;&amp; vec_msg, std::string ip) {
30 30 int ret = -100;
31 31 if ("udp" == net_type) {
32 32 ret = sip_server.RequestInvite_UDP(vec_msg[2].c_str(), ip.c_str(), atoi(vec_msg[3].c_str()));
33   - } else if ("tcp" == net_type)
34   - {
35   - /* code */
  33 + } else if ("tcp" == net_type) {
  34 + ret = sip_server.RequestInvite_TCP_a(vec_msg[2].c_str(), ip.c_str(), atoi(vec_msg[3].c_str()));
36 35 }
37 36  
38 37 return ret;
... ...
sip/sip_header.h
... ... @@ -21,7 +21,7 @@ enum EEventType
21 21 struct DeviceInfo
22 22 {
23 23 EEventType event;
24   - std::string id;
  24 + std::string id{""};
25 25 std::string name;
26 26 std::string manufacturer;
27 27 std::string model;
... ... @@ -109,6 +109,14 @@ public:
109 109 void setSipPass(string s) {
110 110 mSipPass = s;
111 111 }
  112 +
  113 + bool isNoAuth() {
  114 + if (mSipPass.empty()) {
  115 + return true;
  116 + }
  117 + return false;
  118 + }
  119 +
112 120 int getTimeout() const {
113 121 return mSipTimeout;
114 122 }
... ... @@ -147,7 +155,7 @@ private:
147 155 int mPort{0};//SIP服务端口
148 156 string mSipId; //SIP服务器ID
149 157 string mSipRealm;//SIP服务器域
150   - string mSipPass;//SIP password
  158 + string mSipPass{""};//SIP password
151 159 int mSipTimeout; //SIP timeout
152 160 int mSipExpiry;// SIP到期
153 161 int mMinRtpPort;
... ...