callrouter.cpp 9.8 KB

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