| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367 |
- #include "stdafx.h"
- #include "callrouter.h"
- #include "strutil.h"
- #include "callroute_request.h"
- #include "callroute_nodelist.h"
- #include "SpBase.h"
- #include "Event.h"
- #ifdef RVC_OS_WIN
- #include <process.h>
- #include <DbgHelp.h>
- #pragma comment(lib, "dbghelp.lib")
- #else
- #include <sys/socket.h>
- #include <fcntl.h>
- #include <errno.h>
- #include <unistd.h>
- #include <pthread.h>
- #include <netinet/in.h>
- #include <string.h>
- #include <arpa/inet.h>
- #include <sys/ioctl.h>
- #include <sys/types.h>
- typedef int SOCKET;
- #ifndef INVALID_SOCKET
- #define INVALID_SOCKET (SOCKET)(~0)
- #endif
- #ifndef SOCKET_ERROR
- #define SOCKET_ERROR (-1)
- #endif
- #endif // RVC_WIN32
- static int get_sys_time(char* pDst, size_t iLen)
- {
- int iret = 0;
- if (NULL == pDst) {
- return iret;
- }
- #ifdef RVC_OS_WIN
- SYSTEMTIME sys;
- GetLocalTime( &sys );
- _snprintf(pDst, iLen, "%04d%02d%02d%02d%02d%02d",sys.wYear, sys.wMonth, sys.wDay, sys.wHour, sys.wMinute, sys.wSecond);
- #else
- struct tm* t;
- time_t tt;
- time(&tt);
- t = localtime(&tt);
- 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);
- #endif
- iret = strlen(pDst);
- return iret;
- }
- #if defined(RVC_OS_WIN)
- static int set_socket_attribute(SOCKET client_socket, int timeout)
- {
- int ret = -1;
- if (setsockopt(client_socket, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof(timeout)) == SOCKET_ERROR) {
- closesocket(client_socket);
- return ret;
- }
- if (setsockopt(client_socket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)) == SOCKET_ERROR) {
- closesocket(client_socket);
- return ret;
- }
- ret = 0;
- return ret;
- }
- #else
- static int set_socket_attribute(SOCKET client_socket, struct timeval timeout)
- {
- int ret = -1;
- if (setsockopt(client_socket, SOL_SOCKET, SO_SNDTIMEO, (const void*)&timeout, sizeof(timeout)) == SOCKET_ERROR) {
- close(client_socket);
- return ret;
- }
- if (setsockopt(client_socket, SOL_SOCKET, SO_RCVTIMEO, (const void*)&timeout, sizeof(timeout)) == SOCKET_ERROR) {
- close(client_socket);
- return ret;
- }
- ret = 0;
- return ret;
- }
- #endif //RVC_OS_WIN
- static int request_voipgateway_address(call_info_t *call_info, proxy_rsp_packet_t* rsp_packet, const size_t rsp_len)
- {
- int ret = -1;
- //套接字控制模式
- u_long mode = 1;
- //请求包结构体
- proxy_req_packet_t req_info = {0};
- size_t len = sizeof(proxy_req_packet_t);
- char strtime[RVC_DATALEN] = {0};
- BOOL bconnected = FALSE;
- int itimelen = 0;
- SOCKET client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- #if defined(RVC_OS_WIN)
- if (set_socket_attribute(client_socket, 2000)) {
- #else
- struct timeval timeout = { 2,0 };
- if (set_socket_attribute(client_socket, timeout)) {
- #endif //RVC_OS_WIN
- DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("request_voipgateway_address set_socket_attribute failed.");
- return ret;
- }
- if (INVALID_SOCKET != client_socket){
- struct sockaddr_in sa;
- sa.sin_family = AF_INET;
- #ifdef RVC_OS_WIN
- sa.sin_addr.S_un.S_addr = inet_addr(call_info->callroute_server_ip);
- sa.sin_port = htons(call_info->callroute_server_port);
- memset(sa.sin_zero, 0, sizeof(sa.sin_zero));
- ioctlsocket(client_socket, FIONBIO, &mode);
- #else
- sa.sin_addr.s_addr = inet_addr(call_info->callroute_server_ip.GetData());
- sa.sin_port = htons(call_info->callroute_server_port);
- memset(sa.sin_zero, 0, sizeof(sa.sin_zero));
- char strmsg[256] = { 0 };
- snprintf(strmsg, 256, "dest route addr is %s:%d.", call_info->callroute_server_ip.GetData(), call_info->callroute_server_port);
- LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_CALLROUTE_ADDRESS, strmsg);
- //控制为非阻塞方式
- ioctl(client_socket, FIONBIO, &mode);
- #endif // RVC_OS_WIN
- ret = connect(client_socket, (struct sockaddr *)&sa, sizeof(struct sockaddr));
- if (0 == ret){
- bconnected = TRUE;
- }
- else{
- #if defined(RVC_OS_WIN)
- fd_set set;
- struct timeval timeout;
- FD_ZERO(&set);
- FD_SET(client_socket, &set);
- timeout.tv_sec = 2;
- timeout.tv_usec = 0;
- if (select(NULL, NULL, &set, NULL, &timeout) > 0) {
- bconnected = TRUE;
- }
- #else
- if (EINPROGRESS == errno) {
- fd_set writeset;
- struct timeval timeout;
- FD_ZERO(&writeset);
- FD_SET(client_socket, &writeset);
- timeout.tv_sec = 2;
- timeout.tv_usec = 0;
- if (select(client_socket + 1, NULL, &writeset, NULL, &timeout) > 0) {
- if (FD_ISSET(client_socket, &writeset)) {
- bconnected = TRUE;
- }
- }
- }
- #endif //RVC_OS_WIN
- }
- //控制为阻塞方式
- mode = 0;
- #ifdef RVC_OS_WIN
- ioctlsocket(client_socket, FIONBIO, &mode);
- #else
- ioctl(client_socket, FIONBIO, &mode);
- #endif // RVC_OS_WIN
- if (!bconnected){ //连接失败
- #ifdef RVC_OS_WIN
- closesocket(client_socket);
- DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("request_voipgateway_address connect callroute server timeout.");
- #else
- close(client_socket);
- char strerror[256];
- snprintf(strerror, 256, "request_voipgateway_address connect callroute server timeout(%d).", errno);
- LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_CALLROUTE_CONNECT_FAILED, strerror);
- #endif // RVC_OS_WIN
- return ret; //超时
- }
- reset_buffer(&req_info, 0x20, sizeof(proxy_req_packet_t));
- itimelen = get_sys_time(strtime, RVC_DATALEN);
- if (0 < itimelen){
- fill_packet(&req_info, call_info->szdest_num, call_info->szcaller_num, call_info->szbranchno, strtime);
- }
- ret = send(client_socket, (const char*)(&req_info), len, 0);
- if (ret <= 0){
- #ifdef RVC_OS_WIN
- closesocket(client_socket);
- #else
- close(client_socket);
- #endif // RVC_OS_WIN
- LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_CALLROUTE_FAILED, "request_voipgateway_address send to callroute server failed.");
- return ret;
- }
- ret = recv(client_socket, (char*)rsp_packet, rsp_len, 0);
- #ifdef RVC_OS_WIN
- closesocket(client_socket);
- #else
- close(client_socket);
- #endif // RVC_OS_WIN
- if (ret <= 0){
- LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_CALLROUTE_FAILED, "request_voipgateway_address recv from callroute server failed.");
- return ret;
- }
- }
- return ret;
- }
- static bool is_response_packet_valid(proxy_rsp_packet_t* packet_info)
- {
- bool bret = false;
- if (NULL != packet_info){
- char strflag[] = {0x33, 0x37, 0x37, 0x20, 0x0};
- size_t uflaglen = strlen(strflag);
- if (0 != memcmp(packet_info->req_hdr.packgelen, strflag, uflaglen)){
- char packgelen[5] = {0};
- char tradefrom[4] = {0};
- char requestcode[17] = {0};
- memcpy(packgelen, packet_info->req_hdr.packgelen, 4);
- memcpy(tradefrom, packet_info->req_hdr.tradefrom, 3);
- memcpy(requestcode, packet_info->req_hdr.requestcode, 16);
- char strmsg[256] = { 0 };
- snprintf(strmsg, 256, "get mediaserver address from callroute server failed, rsp packgelen:%s, tradefrom:%s, requestcode:%s!",
- packgelen,tradefrom, requestcode);
- LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_CALLROUTE_FAILED, strmsg);
- }else{
- bret = true;
- }
- }
- return bret;
- }
- static int fifter_sparate_flag(proxy_rsp_packet_t* packet_info)
- {
- int ret = -1;
- if (NULL != packet_info){
- rend_string(packet_info->rsp_body.audio_centent, 0x20);
- rend_string(packet_info->rsp_body.video_content_ip, 0x20);
- rend_string(packet_info->rsp_body.video_content_port, 0x20);
- ret = 0;
- }
- return ret;
- }
- static unsigned int separate_string_string(char *buf, const char *delim, char **array, unsigned int arraylen)
- {
- unsigned int count = 0;
- char *d;
- size_t dlen = strlen(delim);
- array[count++] = buf;
- while (count < arraylen && array[count - 1]) {
- if ((d = strstr(array[count - 1], delim))) {
- *d = '\0';
- d += dlen;
- array[count++] = d;
- } else
- break;
- }
- return count;
- }
- static node_list_head_t *create_node_list_by_callernum(call_info_t *call_info, proxy_rsp_packet_t* packet_info)
- {
-
- node_list_head_t *phead = NULL;
- char new_touri[RVC_DATALEN]={0};
- char strinterip[RVC_DATALEN]={0};
- char new_caller_number[RVC_DATALEN]={0};
-
- if (NULL == call_info || NULL == packet_info){
- return NULL;
- }
- if (is_response_packet_valid(packet_info)){
- if (0 == fifter_sparate_flag(packet_info)){
- char *dp[10] = {NULL};
- int argc, x = 0;
- argc = separate_string_string(packet_info->rsp_body.audio_centent, ",", dp, (sizeof(dp) / sizeof(dp[0])));
- if (argc < 1){
- return NULL;
- }
- phead = create_node_list_head(call_info->szcaller_num);
- for (x = 0; x < argc; x++) {
- char *dpname = dp[x];
- if (dpname) {
- //去掉'号
- char to_uri[RVC_DATALEN]={0};
- fifter_string(to_uri, RVC_DATALEN, dpname, '\'');
- //to url 前面+8
- if ('8' == dpname[0]){
- snprintf(new_touri, RVC_DATALEN, "%s%s", "sip:", to_uri);
- }
- else{
- snprintf(new_touri, RVC_DATALEN, "%s%s%s", "sip:", "8", to_uri);
- }
- //new new_caller_id_number=callernum#assist_int_ip
- get_interger_netaddr(strinterip, RVC_DATALEN, packet_info->rsp_body.video_content_ip);
- snprintf(new_caller_number, RVC_DATALEN, "%s%s%s",
- call_info->szcaller_num.GetData(), "#", strinterip);
- char strmsg[256] = { 0 };
- snprintf(strmsg, 256,"new callroute node: new_caller_number:%s new_touri:%s, assist_ip:%s, assist_port:%s!",
- new_caller_number, new_touri, packet_info->rsp_body.video_content_ip, packet_info->rsp_body.video_content_port);
- LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_CALLROUTE_FAILED, strmsg);
- add_node_to_list(phead, new_caller_number, new_touri, packet_info->rsp_body.video_content_ip, packet_info->rsp_body.video_content_port);
- }
- }
- }
- }else{
- char strerror[256] = { 0 };
- 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());
- LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_CALLROUTE_FAILED, strerror);
- }
- return phead;
- }
- node_list_head_t *get_callroute_list(call_info_t *call_info)
- {
- int ret;
- proxy_rsp_packet_t rsp_info = {0};
- size_t recvlen = sizeof(proxy_rsp_packet_t);
- if (call_info->callroute_server_ip.GetLength() == 0 ||
- call_info->callroute_server_port == 0 ||
- call_info->szdest_num.GetLength() == 0 ||
- call_info->szcaller_num.GetLength() == 0 ||
- call_info->szbranchno.GetLength() == 0) {
- LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_CALLROUTE_FAILED, "get_callroute_list failed call_info param is null.");
- return NULL;
- }
- reset_buffer(&rsp_info, 0x20, sizeof(proxy_rsp_packet_t));
- ret = request_voipgateway_address(call_info, &rsp_info, recvlen);
- if (ret <= 0){
- char strmsg[256] = { 0 };
- 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());
- LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_CALLROUTE_FAILED, strmsg);
- return NULL;
- }
- return create_node_list_by_callernum(call_info, &rsp_info);
- }
|