Commit 2a17578fb3cd2ade95f0cfc20d40641332da8042
1 parent
8735837d
添加tcp_p支持;
客户端断连后,不再reinvite
Showing
4 changed files
with
87 additions
and
19 deletions
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<string>& 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 | ... | ... |