Commit 2a17578fb3cd2ade95f0cfc20d40641332da8042

Authored by Hu Chunming
1 parent 8735837d

添加tcp_p支持;

客户端断连后,不再reinvite
sip/SipServer.cpp
... ... @@ -110,6 +110,7 @@ int SipServer::sip_event_handle(eXosip_event_t *evtp) {
110 110  
111 111 case EXOSIP_CALL_CLOSED://21
112 112 LOG_INFO("EXOSIP_CALL_CLOSED type={}",evtp->type);
  113 + // response_message_answer(evtp,200);
113 114 // this->dump_request(evtp);
114 115 // this->dump_response(evtp);
115 116 break;
... ... @@ -168,12 +169,14 @@ int SipServer::sip_event_handle(eXosip_event_t *evtp) {
168 169 break;
169 170 case EXOSIP_CALL_SERVERFAILURE:
170 171 LOG_INFO("EXOSIP_CALL_SERVERFAILURE cid={}", evtp->cid);
  172 + response_message_answer(evtp,200);
171 173 break;
172 174 case EXOSIP_IN_SUBSCRIPTION_NEW:
173 175 LOG_INFO("EXOSIP_IN_SUBSCRIPTION_NEW cid={}", evtp->cid);
174 176 break;
175 177 case EXOSIP_CALL_MESSAGE_ANSWERED:
176 178 LOG_INFO("EXOSIP_CALL_MESSAGE_ANSWERED cid={}", evtp->cid);
  179 + response_message_answer(evtp,200);
177 180 break;
178 181 default:
179 182 LOG_INFO("type={} unknown", evtp->type);
... ... @@ -296,16 +299,16 @@ void SipServer::Close() {
296 299 void SipServer::response_message_answer(eXosip_event_t *evtp,int code){
297 300  
298 301 int returnCode = 0 ;
299   - osip_message_t * pRegister = nullptr;
300   - returnCode = eXosip_message_build_answer (mSipCtx,evtp->tid,code,&pRegister);
  302 + osip_message_t * pMsg = nullptr;
  303 + returnCode = eXosip_message_build_answer (mSipCtx,evtp->tid,code,&pMsg);
301 304 bool bRegister = false;
302   - if(pRegister){
  305 + if(pMsg){
303 306 bRegister = true;
304 307 }
305 308 if (returnCode == 0 && bRegister)
306 309 {
307 310 eXosip_lock(mSipCtx);
308   - eXosip_message_send_answer (mSipCtx,evtp->tid,code,pRegister);
  311 + eXosip_message_send_answer (mSipCtx,evtp->tid,code,pMsg);
309 312 eXosip_unlock(mSipCtx);
310 313 }
311 314 else{
... ... @@ -705,9 +708,9 @@ int SipServer::reInvite(int cid) {
705 708 int ret = -1;
706 709 string cmd = it_cmd->second;
707 710 if (cmd == "udp") {
708   - ret = RequestInvite_UDP(strChannelId.c_str(), strIp.c_str(), iPort);
709   - } else if (cmd == "tcp_a") {
710   - ret = RequestInvite_TCP_a(strChannelId.c_str(), strIp.c_str(), iPort);
  711 + ret = invite_UDP_nolock(strChannelId.c_str(), strIp.c_str(), iPort);
  712 + } else if (cmd == "tcp_p") {
  713 + ret = invite_TCP_p_nolock(strChannelId.c_str(), strIp.c_str(), iPort);
711 714 }
712 715  
713 716 if (ret <= 0) {
... ... @@ -721,6 +724,14 @@ int SipServer::reInvite(int cid) {
721 724 }
722 725  
723 726 int SipServer::RequestInvite_UDP(const char* dst_channel, const char* rtpIp, int rtpPort) {
  727 + std::lock_guard<std::mutex> l_cmd(m_invite_cmd_map_mtx);
  728 + return invite_UDP_nolock(dst_channel, rtpIp, rtpPort);
  729 +}
  730 +
  731 +int SipServer::invite_UDP_nolock(const char* dst_channel, const char* rtpIp, int rtpPort) {
  732 +
  733 + // rtpIp = "192.168.70.1";
  734 + // rtpPort = 10000;
724 735  
725 736 // 检查设备是否在线
726 737 if (!check_device_status(dst_channel)) {
... ... @@ -755,7 +766,6 @@ int SipServer::RequestInvite_UDP(const char* dst_channel, const char* rtpIp, int
755 766 "a=rtpmap:96 PS/90000\r\n"
756 767 "a=rtpmap:98 H264/90000\r\n"
757 768 "a=rtpmap:97 MPEG4/90000\r\n"
758   - "a=setup:passive\r\n"
759 769 "a=connection:new\r\n"
760 770 "y=0100000001\r\n"
761 771 "f=\r\n", mInfo.getSipId().c_str(), rtpIp, rtpIp, rtpPort);
... ... @@ -785,18 +795,30 @@ int SipServer::RequestInvite_UDP(const char* dst_channel, const char* rtpIp, int
785 795 return call_id;
786 796 }
787 797  
788   -int SipServer::RequestInvite_TCP_a(const char* dst_channel, const char* rtpIp, int rtpPort) {
  798 +int SipServer::RequestInvite_TCP_p(const char* dst_channel, const char* rtpIp, int rtpPort) {
  799 + std::lock_guard<std::mutex> l_cmd(m_invite_cmd_map_mtx);
  800 + return invite_TCP_p_nolock(dst_channel, rtpIp, rtpPort);
  801 +}
  802 +
  803 +int SipServer::invite_TCP_p_nolock(const char* dst_channel, const char* rtpIp, int rtpPort) {
  804 +
  805 + //测试
  806 + // rtpIp = "192.168.70.1";
  807 + // rtpPort = 10000;
  808 +
789 809 // 检查设备是否在线
790 810 if (!check_device_status(dst_channel)) {
  811 + LOG_ERROR("{} is not online!", dst_channel);
791 812 return -2;
792 813 }
793 814  
794 815 Client* client = get_parent_by_id(dst_channel);
795 816 if (client == nullptr) {
  817 + LOG_ERROR("do not get parent device:{}", dst_channel);
796 818 return -1;
797 819 }
798 820  
799   - LOG_INFO("INVITE TCP active");
  821 + LOG_INFO("INVITE TCP Passive: {} {}:{}", dst_channel, rtpIp, rtpPort);
800 822  
801 823 char session_exp[1024] = { 0 };
802 824 osip_message_t* msg = nullptr;
... ... @@ -804,8 +826,6 @@ int SipServer::RequestInvite_TCP_a(const char* dst_channel, const char* rtpIp, i
804 826 char to[1024] = { 0 };
805 827 char sdp[2048] = { 0 };
806 828  
807   - // const char* dst_channel = "34020000001320000001";
808   -
809 829 sprintf(from, "sip:%s@%s:%d", mInfo.getSipId().c_str(), mInfo.getIp().c_str(), mInfo.getPort());
810 830 sprintf(to, "sip:%s@%s:%d", dst_channel, client->getIp().c_str(), client->getPort());
811 831 snprintf(sdp, 2048,
... ... @@ -819,10 +839,10 @@ int SipServer::RequestInvite_TCP_a(const char* dst_channel, const char* rtpIp, i
819 839 "a=rtpmap:96 PS/90000\r\n"
820 840 "a=rtpmap:98 H264/90000\r\n"
821 841 "a=rtpmap:97 MPEG4/90000\r\n"
822   - "a=setup:active\r\n"
  842 + "a=setup:passive\r\n"
823 843 "a=connection:new\r\n"
824   - "y=0100000001\r\n"
825   - "f=\r\n", mInfo.getSipId().c_str(), mInfo.getIp().c_str(), mInfo.getIp().c_str(), rtpPort);
  844 + "y=0200002494\r\n"
  845 + "f=\r\n", mInfo.getSipId().c_str(), rtpIp, rtpIp, rtpPort);
826 846  
827 847 int ret = eXosip_call_build_initial_invite(mSipCtx, &msg, to, from, nullptr, nullptr);
828 848 if (ret) {
... ... @@ -840,14 +860,20 @@ int SipServer::RequestInvite_TCP_a(const char* dst_channel, const char* rtpIp, i
840 860 if (call_id > 0) {
841 861 LOG_INFO("eXosip_call_send_initial_invite success: call_id={}", call_id);
842 862 auto key = std::make_tuple(string(dst_channel), string(rtpIp), rtpPort);
843   - m_invite_cmd_map[key] = "tcp_a";
  863 + m_invite_cmd_map[key] = "tcp_p";
844 864 }
845 865 else {
846 866 LOG_ERROR("eXosip_call_send_initial_invite error: call_id={}", call_id);
847 867 }
  868 +
848 869 return call_id;
849 870 }
850 871  
  872 +void SipServer::RemoveInviteTask(tuple<std::string, std::string, int> key) {
  873 + std::lock_guard<std::mutex> l_cmd(m_invite_cmd_map_mtx);
  874 + m_invite_cmd_map.erase(key);
  875 +}
  876 +
851 877 void SipServer::RequestCatalog(Client* client) {
852 878  
853 879 eXosip_lock(mSipCtx);
... ...
sip/SipServer.h
... ... @@ -115,14 +115,23 @@ public:
115 115  
116 116 bool Init(ServerInfo* pInfo, WebSocketServer* pServer);
117 117  
  118 + /*
  119 + GB28181流传输几种模式
  120 + UDP:服务端监听UDP端口,通过INVITE信令告知设备端口,设备主动向服务端发起流传输
  121 + TCP被动:服务端监听TCP端口,通过INVITE信令告知设备端口,设备向服务端发起流传输
  122 + TCP主动:设备端告知服务端监听的TCP端口情况,服务端主动向设备拉流,此种场景较少,且设备所在网络可以被服务所在网络访问(如下级设备与上级GB28181服务在同一个局域网,或者都在公网上能相互访问)。
  123 + */
  124 +
118 125 int RequestInvite_UDP(const char* dst_channel, const char* rtpIp, int rtpPort);
119 126  
120   - int RequestInvite_TCP_a(const char* dst_channel, const char* rtpIp, int rtpPort);
  127 + int RequestInvite_TCP_p(const char* dst_channel, const char* rtpIp, int rtpPort);
121 128  
122 129 int ByeInvite(std::string channel_id, string ip, int rtpPort);
123 130  
124 131 void Close();
125 132  
  133 + void RemoveInviteTask(tuple<std::string, std::string, int>);
  134 +
126 135 public:
127 136 void event_loop();
128 137  
... ... @@ -159,6 +168,10 @@ private:
159 168  
160 169 int check_device_type(string sip_id);
161 170  
  171 + int invite_UDP_nolock(const char* dst_channel, const char* rtpIp, int rtpPort);
  172 +
  173 + int invite_TCP_p_nolock(const char* dst_channel, const char* rtpIp, int rtpPort);
  174 +
162 175 private:
163 176 bool mQuit{ false };
164 177 eXosip_t *mSipCtx;
... ...
sip/WebSocketServer.cpp
... ... @@ -31,7 +31,7 @@ int WebSocketServer::parse_invite(vector&lt;string&gt;&amp; vec_msg, std::string ip) {
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 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()));
  34 + ret = sip_server.RequestInvite_TCP_p(vec_msg[2].c_str(), ip.c_str(), atoi(vec_msg[3].c_str()));
35 35 }
36 36  
37 37 return ret;
... ... @@ -54,6 +54,8 @@ int WebSocketServer::msg_parser(websocketpp::connection_hdl hdl, string msg) {
54 54  
55 55 string ip = get_ip_from_hdl(hdl);
56 56  
  57 + auto task_key = std::make_tuple(vec_msg[2], ip, atoi(vec_msg[3].c_str()));
  58 +
57 59 string response_msg = "";
58 60 int ret = -100;
59 61 if ( StringTools::to_lower(vec_msg[0]) == "invite") {
... ... @@ -62,6 +64,10 @@ int WebSocketServer::msg_parser(websocketpp::connection_hdl hdl, string msg) {
62 64 if (ret > 0) {
63 65 std::lock_guard<std::mutex> l_hdl(m_channelport_hdl_map_mtx);
64 66 m_channelport_hdl_map[strKey] = hdl;
  67 +
  68 + std::lock_guard<std::mutex> l_task(m_hdl_task_mtx);
  69 + auto conn = ws_server.get_con_from_hdl(hdl);
  70 + m_hdl_task.emplace(conn, task_key);
65 71 }
66 72  
67 73 response_msg = strKey +"|" + vec_msg[0] + "|" + vec_msg[1] + "|" + to_string(ret);
... ... @@ -78,6 +84,15 @@ int WebSocketServer::msg_parser(websocketpp::connection_hdl hdl, string msg) {
78 84 }
79 85  
80 86 ret = sip_server.ByeInvite(vec_msg[2], ip, atoi(vec_msg[3].c_str()));
  87 + if (ret == 0) {
  88 + std::lock_guard<std::mutex> l_task(m_hdl_task_mtx);
  89 + for(auto it_task = m_hdl_task.begin(); it_task != m_hdl_task.end(); it_task++) {
  90 + if(it_task->second == task_key) {
  91 + m_hdl_task.erase(it_task);
  92 + break;
  93 + }
  94 + }
  95 + }
81 96 }
82 97 } else {
83 98 LOG_ERROR("on_message called with hdl: {} and message:{}", hdl.lock().get(), msg);
... ... @@ -136,16 +151,27 @@ void WebSocketServer::on_close(websocketpp::connection_hdl h){
136 151  
137 152 std::lock_guard<std::mutex> l_hdl(m_channelport_hdl_map_mtx);
138 153  
  154 + server::connection_ptr con_std = ws_server.get_con_from_hdl(h);
139 155 for (auto it = m_channelport_hdl_map.begin(); it != m_channelport_hdl_map.end(); )
140 156 {
141 157 server::connection_ptr con = ws_server.get_con_from_hdl(it->second);
142   - server::connection_ptr con_std = ws_server.get_con_from_hdl(h);
  158 +
143 159 if (con == con_std) {
144 160 it = m_channelport_hdl_map.erase(it);
145 161 } else {
146 162 it++;
147 163 }
148 164 }
  165 +
  166 + std::lock_guard<std::mutex> l_task(m_hdl_task_mtx);
  167 + for(auto it_task = m_hdl_task.begin(); it_task != m_hdl_task.end(); ) {
  168 + if(it_task->first == con_std) {
  169 + sip_server.RemoveInviteTask(it_task->second);
  170 + it_task = m_hdl_task.erase(it_task);
  171 + } else {
  172 + it_task++ ;
  173 + }
  174 + }
149 175 }
150 176  
151 177  
... ...
sip/WebSocketServer.h
... ... @@ -43,6 +43,9 @@ private:
43 43  
44 44 std::map<string, websocketpp::connection_hdl> m_channelport_hdl_map;
45 45 std::mutex m_channelport_hdl_map_mtx;
  46 +
  47 + std::multimap<server::connection_ptr, tuple<std::string, std::string, int> > m_hdl_task;
  48 + std::mutex m_hdl_task_mtx;
46 49 };
47 50  
48 51 #endif // __WEB_SOCKET_SERVER__
49 52 \ No newline at end of file
... ...