callrouter.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. #include "stdafx.h"
  2. #include "callrouter.h"
  3. #include "strutil.h"
  4. #include "callroute_request.h"
  5. #include "callroute_nodelist.h"
  6. #include "SpBase.h"
  7. #include "Event.h"
  8. #ifdef RVC_OS_WIN
  9. #include <process.h>
  10. #include <DbgHelp.h>
  11. #pragma comment(lib, "dbghelp.lib")
  12. #else
  13. #include <sys/socket.h>
  14. #include <fcntl.h>
  15. #include <errno.h>
  16. #include <unistd.h>
  17. #include <pthread.h>
  18. #include <netinet/in.h>
  19. #include <string.h>
  20. #include <arpa/inet.h>
  21. #include <sys/ioctl.h>
  22. #include <sys/types.h>
  23. typedef int SOCKET;
  24. #ifndef INVALID_SOCKET
  25. #define INVALID_SOCKET (SOCKET)(~0)
  26. #endif
  27. #ifndef SOCKET_ERROR
  28. #define SOCKET_ERROR (-1)
  29. #endif
  30. #endif // RVC_WIN32
  31. static int get_sys_time(char* pDst, size_t iLen)
  32. {
  33. int iret = 0;
  34. if (NULL == pDst) {
  35. return iret;
  36. }
  37. #ifdef RVC_OS_WIN
  38. SYSTEMTIME sys;
  39. GetLocalTime( &sys );
  40. _snprintf(pDst, iLen, "%04d%02d%02d%02d%02d%02d",sys.wYear, sys.wMonth, sys.wDay, sys.wHour, sys.wMinute, sys.wSecond);
  41. #else
  42. struct tm* t;
  43. time_t tt;
  44. time(&tt);
  45. t = localtime(&tt);
  46. snprintf(pDst, iLen, "%04d%02d%02d%02d%02d%02d", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
  47. #endif
  48. iret = strlen(pDst);
  49. return iret;
  50. }
  51. #if defined(RVC_OS_WIN)
  52. static int set_socket_attribute(SOCKET client_socket, int timeout)
  53. {
  54. int ret = -1;
  55. if (setsockopt(client_socket, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof(timeout)) == SOCKET_ERROR) {
  56. closesocket(client_socket);
  57. return ret;
  58. }
  59. if (setsockopt(client_socket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)) == SOCKET_ERROR) {
  60. closesocket(client_socket);
  61. return ret;
  62. }
  63. ret = 0;
  64. return ret;
  65. }
  66. #else
  67. static int set_socket_attribute(SOCKET client_socket, struct timeval timeout)
  68. {
  69. int ret = -1;
  70. if (setsockopt(client_socket, SOL_SOCKET, SO_SNDTIMEO, (const void*)&timeout, sizeof(timeout)) == SOCKET_ERROR) {
  71. close(client_socket);
  72. return ret;
  73. }
  74. if (setsockopt(client_socket, SOL_SOCKET, SO_RCVTIMEO, (const void*)&timeout, sizeof(timeout)) == SOCKET_ERROR) {
  75. close(client_socket);
  76. return ret;
  77. }
  78. ret = 0;
  79. return ret;
  80. }
  81. #endif //RVC_OS_WIN
  82. static int request_voipgateway_address(call_info_t *call_info, proxy_rsp_packet_t* rsp_packet, const size_t rsp_len)
  83. {
  84. int ret = -1;
  85. //套接字控制模式
  86. u_long mode = 1;
  87. //请求包结构体
  88. proxy_req_packet_t req_info = {0};
  89. size_t len = sizeof(proxy_req_packet_t);
  90. char strtime[RVC_DATALEN] = {0};
  91. BOOL bconnected = FALSE;
  92. int itimelen = 0;
  93. SOCKET client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  94. #if defined(RVC_OS_WIN)
  95. if (set_socket_attribute(client_socket, 2000)) {
  96. #else
  97. struct timeval timeout = { 2,0 };
  98. if (set_socket_attribute(client_socket, timeout)) {
  99. #endif //RVC_OS_WIN
  100. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("request_voipgateway_address set_socket_attribute failed.");
  101. return ret;
  102. }
  103. if (INVALID_SOCKET != client_socket){
  104. struct sockaddr_in sa;
  105. sa.sin_family = AF_INET;
  106. #ifdef RVC_OS_WIN
  107. sa.sin_addr.S_un.S_addr = inet_addr(call_info->callroute_server_ip);
  108. sa.sin_port = htons(call_info->callroute_server_port);
  109. memset(sa.sin_zero, 0, sizeof(sa.sin_zero));
  110. ioctlsocket(client_socket, FIONBIO, &mode);
  111. #else
  112. sa.sin_addr.s_addr = inet_addr(call_info->callroute_server_ip.GetData());
  113. sa.sin_port = htons(call_info->callroute_server_port);
  114. memset(sa.sin_zero, 0, sizeof(sa.sin_zero));
  115. char strmsg[256] = { 0 };
  116. snprintf(strmsg, 256, "dest route addr is %s:%d.", call_info->callroute_server_ip.GetData(), call_info->callroute_server_port);
  117. LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_CALLROUTE_ADDRESS, strmsg);
  118. //控制为非阻塞方式
  119. ioctl(client_socket, FIONBIO, &mode);
  120. #endif // RVC_OS_WIN
  121. ret = connect(client_socket, (struct sockaddr *)&sa, sizeof(struct sockaddr));
  122. if (0 == ret){
  123. bconnected = TRUE;
  124. }
  125. else{
  126. #if defined(RVC_OS_WIN)
  127. fd_set set;
  128. struct timeval timeout;
  129. FD_ZERO(&set);
  130. FD_SET(client_socket, &set);
  131. timeout.tv_sec = 2;
  132. timeout.tv_usec = 0;
  133. if (select(NULL, NULL, &set, NULL, &timeout) > 0) {
  134. bconnected = TRUE;
  135. }
  136. #else
  137. if (EINPROGRESS == errno) {
  138. fd_set writeset;
  139. struct timeval timeout;
  140. FD_ZERO(&writeset);
  141. FD_SET(client_socket, &writeset);
  142. timeout.tv_sec = 2;
  143. timeout.tv_usec = 0;
  144. if (select(client_socket + 1, NULL, &writeset, NULL, &timeout) > 0) {
  145. if (FD_ISSET(client_socket, &writeset)) {
  146. bconnected = TRUE;
  147. }
  148. }
  149. }
  150. #endif //RVC_OS_WIN
  151. }
  152. //控制为阻塞方式
  153. mode = 0;
  154. #ifdef RVC_OS_WIN
  155. ioctlsocket(client_socket, FIONBIO, &mode);
  156. #else
  157. ioctl(client_socket, FIONBIO, &mode);
  158. #endif // RVC_OS_WIN
  159. if (!bconnected){ //连接失败
  160. #ifdef RVC_OS_WIN
  161. closesocket(client_socket);
  162. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("request_voipgateway_address connect callroute server timeout.");
  163. #else
  164. close(client_socket);
  165. char strerror[256];
  166. snprintf(strerror, 256, "request_voipgateway_address connect callroute server timeout(%d).", errno);
  167. LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_CALLROUTE_CONNECT_FAILED, strerror);
  168. #endif // RVC_OS_WIN
  169. return ret; //超时
  170. }
  171. reset_buffer(&req_info, 0x20, sizeof(proxy_req_packet_t));
  172. itimelen = get_sys_time(strtime, RVC_DATALEN);
  173. if (0 < itimelen){
  174. fill_packet(&req_info, call_info->szdest_num, call_info->szcaller_num, call_info->szbranchno, strtime);
  175. }
  176. ret = send(client_socket, (const char*)(&req_info), len, 0);
  177. if (ret <= 0){
  178. #ifdef RVC_OS_WIN
  179. closesocket(client_socket);
  180. #else
  181. close(client_socket);
  182. #endif // RVC_OS_WIN
  183. LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_CALLROUTE_FAILED, "request_voipgateway_address send to callroute server failed.");
  184. return ret;
  185. }
  186. ret = recv(client_socket, (char*)rsp_packet, rsp_len, 0);
  187. #ifdef RVC_OS_WIN
  188. closesocket(client_socket);
  189. #else
  190. close(client_socket);
  191. #endif // RVC_OS_WIN
  192. if (ret <= 0){
  193. LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_CALLROUTE_FAILED, "request_voipgateway_address recv from callroute server failed.");
  194. return ret;
  195. }
  196. }
  197. return ret;
  198. }
  199. static bool is_response_packet_valid(proxy_rsp_packet_t* packet_info)
  200. {
  201. bool bret = false;
  202. if (NULL != packet_info){
  203. char strflag[] = {0x33, 0x37, 0x37, 0x20, 0x0};
  204. size_t uflaglen = strlen(strflag);
  205. if (0 != memcmp(packet_info->req_hdr.packgelen, strflag, uflaglen)){
  206. char packgelen[5] = {0};
  207. char tradefrom[4] = {0};
  208. char requestcode[17] = {0};
  209. memcpy(packgelen, packet_info->req_hdr.packgelen, 4);
  210. memcpy(tradefrom, packet_info->req_hdr.tradefrom, 3);
  211. memcpy(requestcode, packet_info->req_hdr.requestcode, 16);
  212. char strmsg[256] = { 0 };
  213. snprintf(strmsg, 256, "get mediaserver address from callroute server failed, rsp packgelen:%s, tradefrom:%s, requestcode:%s!",
  214. packgelen,tradefrom, requestcode);
  215. LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_CALLROUTE_FAILED, strmsg);
  216. }else{
  217. bret = true;
  218. }
  219. }
  220. return bret;
  221. }
  222. static int fifter_sparate_flag(proxy_rsp_packet_t* packet_info)
  223. {
  224. int ret = -1;
  225. if (NULL != packet_info){
  226. rend_string(packet_info->rsp_body.audio_centent, 0x20);
  227. rend_string(packet_info->rsp_body.video_content_ip, 0x20);
  228. rend_string(packet_info->rsp_body.video_content_port, 0x20);
  229. ret = 0;
  230. }
  231. return ret;
  232. }
  233. static unsigned int separate_string_string(char *buf, const char *delim, char **array, unsigned int arraylen)
  234. {
  235. unsigned int count = 0;
  236. char *d;
  237. size_t dlen = strlen(delim);
  238. array[count++] = buf;
  239. while (count < arraylen && array[count - 1]) {
  240. if ((d = strstr(array[count - 1], delim))) {
  241. *d = '\0';
  242. d += dlen;
  243. array[count++] = d;
  244. } else
  245. break;
  246. }
  247. return count;
  248. }
  249. static node_list_head_t *create_node_list_by_callernum(call_info_t *call_info, proxy_rsp_packet_t* packet_info)
  250. {
  251. node_list_head_t *phead = NULL;
  252. char new_touri[RVC_DATALEN]={0};
  253. char strinterip[RVC_DATALEN]={0};
  254. char new_caller_number[RVC_DATALEN]={0};
  255. if (NULL == call_info || NULL == packet_info){
  256. return NULL;
  257. }
  258. if (is_response_packet_valid(packet_info)){
  259. if (0 == fifter_sparate_flag(packet_info)){
  260. char *dp[10] = {NULL};
  261. int argc, x = 0;
  262. argc = separate_string_string(packet_info->rsp_body.audio_centent, ",", dp, (sizeof(dp) / sizeof(dp[0])));
  263. if (argc < 1){
  264. return NULL;
  265. }
  266. phead = create_node_list_head(call_info->szcaller_num);
  267. for (x = 0; x < argc; x++) {
  268. char *dpname = dp[x];
  269. if (dpname) {
  270. //去掉'号
  271. char to_uri[RVC_DATALEN]={0};
  272. fifter_string(to_uri, RVC_DATALEN, dpname, '\'');
  273. //to url 前面+8
  274. if ('8' == dpname[0]){
  275. snprintf(new_touri, RVC_DATALEN, "%s%s", "sip:", to_uri);
  276. }
  277. else{
  278. snprintf(new_touri, RVC_DATALEN, "%s%s%s", "sip:", "8", to_uri);
  279. }
  280. //new new_caller_id_number=callernum#assist_int_ip
  281. get_interger_netaddr(strinterip, RVC_DATALEN, packet_info->rsp_body.video_content_ip);
  282. snprintf(new_caller_number, RVC_DATALEN, "%s%s%s",
  283. call_info->szcaller_num.GetData(), "#", strinterip);
  284. char strmsg[256] = { 0 };
  285. snprintf(strmsg, 256,"new callroute node: new_caller_number:%s new_touri:%s, assist_ip:%s, assist_port:%s!",
  286. new_caller_number, new_touri, packet_info->rsp_body.video_content_ip, packet_info->rsp_body.video_content_port);
  287. LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_CALLROUTE_FAILED, strmsg);
  288. add_node_to_list(phead, new_caller_number, new_touri, packet_info->rsp_body.video_content_ip, packet_info->rsp_body.video_content_port);
  289. }
  290. }
  291. }
  292. }else{
  293. char strerror[256] = { 0 };
  294. snprintf(strerror, 256, "create_node_list_by_callernum failed. szbranchno:%s, szcaller_num:%s, szdest_num:%s.", call_info->szbranchno.GetData(), call_info->szcaller_num.GetData(), call_info->szdest_num.GetData());
  295. LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_CALLROUTE_FAILED, strerror);
  296. }
  297. return phead;
  298. }
  299. node_list_head_t *get_callroute_list(call_info_t *call_info)
  300. {
  301. int ret;
  302. proxy_rsp_packet_t rsp_info = {0};
  303. size_t recvlen = sizeof(proxy_rsp_packet_t);
  304. if (call_info->callroute_server_ip.GetLength() == 0 ||
  305. call_info->callroute_server_port == 0 ||
  306. call_info->szdest_num.GetLength() == 0 ||
  307. call_info->szcaller_num.GetLength() == 0 ||
  308. call_info->szbranchno.GetLength() == 0) {
  309. LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_CALLROUTE_FAILED, "get_callroute_list failed call_info param is null.");
  310. return NULL;
  311. }
  312. reset_buffer(&rsp_info, 0x20, sizeof(proxy_rsp_packet_t));
  313. ret = request_voipgateway_address(call_info, &rsp_info, recvlen);
  314. if (ret <= 0){
  315. char strmsg[256] = { 0 };
  316. snprintf(strmsg, 256, "get_callroute_list failed szbranchno:%s, szcaller_num:%s, szdest_num:%s.", call_info->szbranchno.GetData(), call_info->szcaller_num.GetData(), call_info->szdest_num.GetData());
  317. LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_CALLROUTE_FAILED, strmsg);
  318. return NULL;
  319. }
  320. return create_node_list_by_callernum(call_info, &rsp_info);
  321. }