785 lines
18 KiB
C++
785 lines
18 KiB
C++
/***************************************************************************************
|
|
*
|
|
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
|
*
|
|
* By downloading, copying, installing or using the software you agree to this license.
|
|
* If you do not agree to this license, do not download, install,
|
|
* copy or use the software.
|
|
*
|
|
* Copyright (C) 2014-2022, Happytimesoft Corporation, all rights reserved.
|
|
*
|
|
* Redistribution and use in binary forms, with or without modification, are permitted.
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed
|
|
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
|
|
* language governing permissions and limitations under the License.
|
|
*
|
|
****************************************************************************************/
|
|
|
|
#include "sys_inc.h"
|
|
#include "hsip.h"
|
|
#include "sua.h"
|
|
#include "sip_parse.h"
|
|
#include "sip_rx.h"
|
|
#include "sip_tx.h"
|
|
#include "sip_timer.h"
|
|
#include "sip_reg.h"
|
|
#include "sip_pstate.h"
|
|
#include "gb28181_cfg.h"
|
|
|
|
|
|
/***********************************************************************/
|
|
HSIP_CLASS hsip;
|
|
HSIP_USER g_user;
|
|
|
|
/***********************************************************************/
|
|
BOOL is_local_if_ip(uint32 dst_ip)
|
|
{
|
|
return (dst_ip == hsip.local_ip);
|
|
}
|
|
|
|
/***********************************************************************\
|
|
检查域名或者ip地址是否是自己
|
|
1.如果是ip,检查是否是本机地址,或者是对外映射的ip地址
|
|
2.如果是名称,检查是否是本域名,或者是本机主机名
|
|
\***********************************************************************/
|
|
BOOL is_local_domain(char * domain)
|
|
{
|
|
if (is_ip_address(domain) && is_local_if_ip(inet_addr(domain)))
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
if (strcasecmp(hsip.host_name, domain) == 0)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
if (is_local_if_ip(get_address_by_name(domain)))
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL init_local_net()
|
|
{
|
|
if (gethostname(hsip.host_name, sizeof(hsip.host_name)-1) == 0)
|
|
{
|
|
log_print(HT_LOG_INFO, "%s, %s\r\n", __FUNCTION__, hsip.host_name);
|
|
|
|
struct in_addr addr;
|
|
addr.s_addr = get_default_if_ip();
|
|
strcpy(hsip.local_ipstr, inet_ntoa(addr));
|
|
|
|
log_print(HT_LOG_INFO, "%s, hsip.local_ipstr = %s\r\n", __FUNCTION__, hsip.local_ipstr);
|
|
}
|
|
|
|
hsip.local_ip = inet_addr(hsip.local_ipstr);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/***********************************************************************\
|
|
系统数据结构初始化,必要的任务初始化
|
|
\***********************************************************************/
|
|
BOOL sip_init_bufs()
|
|
{
|
|
if (sys_buf_init(MAX_NUM_SUA * 4) == FALSE)
|
|
{
|
|
log_print(HT_LOG_ERR, "%s, sys_buf_init failed!!!\r\n", __FUNCTION__);
|
|
return FALSE;
|
|
}
|
|
|
|
if (sip_parse_buf_init(MAX_NUM_SUA * 4) == FALSE)
|
|
{
|
|
log_print(HT_LOG_ERR, "%s, sip_parse_buf_init failed!!!\r\n", __FUNCTION__);
|
|
return FALSE;
|
|
}
|
|
|
|
hsip.msg_queue = hqCreate(MAX_NUM_SUA * 4, sizeof(SIPTM), HQ_GET_WAIT);
|
|
if (hsip.msg_queue == NULL)
|
|
{
|
|
log_print(HT_LOG_ERR, "%s, create sip task queue failed!!!\r\n", __FUNCTION__);
|
|
return FALSE;
|
|
}
|
|
|
|
sua_proxy_init();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/***********************************************************************\
|
|
用户网络初始化
|
|
\***********************************************************************/
|
|
BOOL sip_user_socket_init(HSIP_USER * p_user)
|
|
{
|
|
if (p_user->sip_fd > 0)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
// 清空接收缓冲区
|
|
p_user->rcv_dlen = 0;
|
|
p_user->sip_len = 0;
|
|
p_user->sdp_len = 0;
|
|
|
|
if (p_user->dyn_recv_buf)
|
|
{
|
|
free(p_user->dyn_recv_buf);
|
|
p_user->dyn_recv_buf = NULL;
|
|
}
|
|
p_user->p_rbuf = NULL;
|
|
|
|
if (p_user->usrf_tcp_sip == 1)
|
|
{
|
|
p_user->sip_fd = socket(AF_INET, SOCK_STREAM, 0);
|
|
if (p_user->sip_fd <= 0)
|
|
{
|
|
log_print(HT_LOG_ERR, "%s, socket init fail\r\n", __FUNCTION__);
|
|
return FALSE;
|
|
}
|
|
|
|
struct sockaddr_in addr;
|
|
int addr_len = sizeof(addr);
|
|
|
|
addr.sin_family = AF_INET;
|
|
addr.sin_addr.s_addr = hsip.local_ip;
|
|
addr.sin_port = htons(g_gb28181_cfg.local_port);
|
|
|
|
if (bind(p_user->sip_fd, (struct sockaddr *)&addr, addr_len) != 0)
|
|
{
|
|
log_print(HT_LOG_ERR, "%s, Bind tcp socket fail,error = %s\r\n",
|
|
__FUNCTION__, sys_os_get_socket_error());
|
|
closesocket(p_user->sip_fd);
|
|
return FALSE;
|
|
}
|
|
|
|
addr.sin_family = AF_INET;
|
|
addr.sin_addr.s_addr = inet_addr(p_user->server_ipstr);
|
|
addr.sin_port = htons(p_user->server_port);
|
|
|
|
if (connect(p_user->sip_fd, (struct sockaddr *)&addr, addr_len) != 0)
|
|
{
|
|
log_print(HT_LOG_ERR, "%s, connect srv[%s,%u] fail,error = %s\r\n", __FUNCTION__,
|
|
p_user->server_ipstr, p_user->server_port, sys_os_get_socket_error());
|
|
closesocket(p_user->sip_fd);
|
|
return FALSE;
|
|
}
|
|
|
|
if (getsockname(p_user->sip_fd, (struct sockaddr *)&addr, (socklen_t*)&addr_len) == 0)
|
|
{
|
|
p_user->user_port = p_user->sip_port = ntohs(addr.sin_port);
|
|
log_print(HT_LOG_INFO, "%s, sip local port %u\r\n", __FUNCTION__, p_user->sip_port);
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
p_user->sip_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
|
if (p_user->sip_fd <= 0)
|
|
{
|
|
log_print(HT_LOG_ERR, "%s, socket init fail\r\n", __FUNCTION__);
|
|
return FALSE;
|
|
}
|
|
|
|
struct sockaddr_in addr;
|
|
int addr_len = sizeof(addr);
|
|
|
|
addr.sin_family = AF_INET;
|
|
addr.sin_addr.s_addr = hsip.local_ip;
|
|
addr.sin_port = htons(g_gb28181_cfg.local_port);
|
|
|
|
if (bind(p_user->sip_fd, (struct sockaddr *)&addr, addr_len) != 0)
|
|
{
|
|
log_print(HT_LOG_ERR, "%s, Bind udp socket fail,error = %s\r\n",
|
|
__FUNCTION__, sys_os_get_socket_error());
|
|
closesocket(p_user->sip_fd);
|
|
return FALSE;
|
|
}
|
|
|
|
if (getsockname(p_user->sip_fd, (struct sockaddr *)&addr, (socklen_t*)&addr_len) == 0)
|
|
{
|
|
p_user->user_port = p_user->sip_port = ntohs(addr.sin_port);
|
|
log_print(HT_LOG_INFO, "%s, sip local port %u\r\n", __FUNCTION__, p_user->sip_port);
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
int sip_pkt_find_end(char * p_buf)
|
|
{
|
|
int end_off = 0;
|
|
int sip_pkt_finish = 0; // SIP包是否完整(不包括SDP)标识
|
|
|
|
while (p_buf[end_off] != '\0')
|
|
{
|
|
if ((p_buf[end_off+0] == '\r' && p_buf[end_off+1] == '\n') &&
|
|
(p_buf[end_off+2] == '\r' && p_buf[end_off+3] == '\n'))
|
|
{
|
|
sip_pkt_finish = 1;
|
|
break;
|
|
}
|
|
|
|
end_off++;
|
|
}
|
|
|
|
if (sip_pkt_finish)
|
|
{
|
|
return(end_off + 4);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void sip_commit_rx_msg(HSIP_USER * p_user, HSIP_MSG * rx_msg)
|
|
{
|
|
// 下面三行是为兼容UDP模式处理代码
|
|
rx_msg->local_port = p_user->sip_port;
|
|
rx_msg->remote_ip = inet_addr(p_user->server_ipstr);
|
|
rx_msg->remote_port = htons(p_user->server_port);
|
|
|
|
// 将信令消息打包,发送到状态机处理任务
|
|
SIPTM stm;
|
|
memset(&stm, 0, sizeof(SIPTM));
|
|
|
|
stm.msg_len = (rx_msg ? rx_msg->buf_mlen : 0);
|
|
stm.msg_src = SIP_PMSG_SRC;
|
|
stm.msg_buf = (char *)rx_msg;
|
|
|
|
if (hqBufPut(hsip.msg_queue, (char *)&stm) == FALSE)
|
|
{
|
|
sip_free_msg(rx_msg);
|
|
log_print(HT_LOG_ERR, "%s, hqBufPut return fail!!!\r\n", __FUNCTION__);
|
|
}
|
|
}
|
|
|
|
BOOL sip_tcp_rx(HSIP_USER * p_user)
|
|
{
|
|
if (p_user->p_rbuf == NULL) // 接收缓冲初始化
|
|
{
|
|
p_user->p_rbuf = p_user->rcv_buf;
|
|
p_user->mlen = sizeof(p_user->rcv_buf)-1;
|
|
p_user->rcv_dlen = 0;
|
|
p_user->sdp_len = 0;
|
|
p_user->sip_len = 0;
|
|
}
|
|
|
|
int rlen = recv(p_user->sip_fd, p_user->p_rbuf+p_user->rcv_dlen, p_user->mlen-p_user->rcv_dlen, 0);
|
|
if (rlen <= 0)
|
|
{
|
|
// 接收出错,可能是连接断开了
|
|
|
|
log_print(HT_LOG_ERR, "%s, recv return = %d, dlen[%d], mlen[%d]\r\n",
|
|
__FUNCTION__, rlen, p_user->rcv_dlen, p_user->mlen);
|
|
closesocket(p_user->sip_fd);
|
|
p_user->sip_fd = 0;
|
|
return FALSE;
|
|
}
|
|
|
|
p_user->rcv_dlen += rlen;
|
|
p_user->p_rbuf[p_user->rcv_dlen] = '\0';
|
|
|
|
//if(memcmp(p_user->p_rbuf, "MESSAGE", strlen("MESSAGE")) == 0)
|
|
//{
|
|
// log_print(HT_LOG_DBG, "rcv tcp message, rlen=%d\r\n", rlen);
|
|
// log_print(HT_LOG_DBG, "%s\r\n", p_user->p_rbuf+(p_user->rcv_dlen-rlen));
|
|
//}
|
|
|
|
rx_analyse_point:
|
|
|
|
if (p_user->rcv_dlen < 16)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
if (sip_is_sip_msg(p_user->p_rbuf) == FALSE) // 判断是否是SIP包
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
HSIP_MSG * rx_msg = NULL;
|
|
|
|
if (p_user->sip_len == 0)
|
|
{
|
|
int sip_pkt_len = sip_pkt_find_end(p_user->p_rbuf);
|
|
if (sip_pkt_len == 0)
|
|
{
|
|
// 没有接收全, 等下次接收
|
|
return TRUE;
|
|
}
|
|
|
|
p_user->sip_len = sip_pkt_len;
|
|
|
|
rx_msg = sip_get_msg_buf();
|
|
if (rx_msg == NULL)
|
|
{
|
|
log_print(HT_LOG_ERR, "%s, sip_get_msg_buf ret null!!!\r\n", __FUNCTION__);
|
|
return FALSE;
|
|
}
|
|
|
|
memcpy(rx_msg->msg_buf, p_user->p_rbuf, sip_pkt_len);
|
|
rx_msg->msg_buf[sip_pkt_len] = '\0';
|
|
|
|
log_print(HT_LOG_DBG, "%s\r\n", rx_msg->msg_buf);
|
|
|
|
int parse_len = sip_msg_parse_part1(rx_msg->msg_buf, sip_pkt_len, rx_msg);
|
|
if (parse_len != sip_pkt_len)
|
|
{
|
|
// 解析出错
|
|
|
|
log_print(HT_LOG_ERR, "%s, sip_msg_parse_part1=%d, sip_pkt_len=%d!!!\r\n", __FUNCTION__, parse_len, sip_pkt_len);
|
|
sip_free_msg(rx_msg);
|
|
return FALSE;
|
|
}
|
|
|
|
p_user->sdp_len = rx_msg->ctx_len;
|
|
}
|
|
|
|
if ((p_user->sdp_len + p_user->sip_len) > p_user->mlen)
|
|
{
|
|
if (p_user->dyn_recv_buf)
|
|
{
|
|
// 不应该出现这种情况
|
|
|
|
log_print(HT_LOG_WARN, "%s, dyn_recv_buf=%p, mlen=%d!!!\r\n", __FUNCTION__, p_user->dyn_recv_buf, p_user->mlen);
|
|
free(p_user->dyn_recv_buf);
|
|
}
|
|
|
|
p_user->dyn_recv_buf = (char *)malloc(p_user->sdp_len + p_user->sip_len + 1);
|
|
if (p_user->dyn_recv_buf)
|
|
{
|
|
memcpy(p_user->dyn_recv_buf, p_user->rcv_buf, p_user->rcv_dlen);
|
|
p_user->p_rbuf = p_user->dyn_recv_buf;
|
|
p_user->mlen = p_user->sdp_len + p_user->sip_len;
|
|
}
|
|
|
|
if (rx_msg)
|
|
{
|
|
sip_free_msg(rx_msg);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
if (p_user->rcv_dlen >= (p_user->sdp_len + p_user->sip_len))
|
|
{
|
|
if (rx_msg == NULL)
|
|
{
|
|
// 属于第二次进入接收
|
|
|
|
int nlen = p_user->sdp_len + p_user->sip_len;
|
|
rx_msg = sip_get_msg_large_buf(nlen+1);
|
|
if (NULL == rx_msg)
|
|
{
|
|
log_print(HT_LOG_ERR, "%s, get message buffer failed\r\n", __FUNCTION__);
|
|
return FALSE;
|
|
}
|
|
|
|
memcpy(rx_msg->msg_buf, p_user->p_rbuf, p_user->sip_len);
|
|
rx_msg->msg_buf[p_user->sip_len] = '\0';
|
|
|
|
log_print(HT_LOG_DBG, "%s\r\n", rx_msg->msg_buf);
|
|
|
|
int parse_len = sip_msg_parse_part1(rx_msg->msg_buf, p_user->sip_len, rx_msg);
|
|
if (parse_len != p_user->sip_len)
|
|
{
|
|
// 解析出错
|
|
|
|
log_print(HT_LOG_ERR, "%s, sip_msg_parse_part1=%d, sip_pkt_len=%d!!!\r\n", __FUNCTION__, parse_len, p_user->sip_len);
|
|
sip_free_msg(rx_msg);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
if (p_user->sdp_len > 0)
|
|
{
|
|
memcpy(rx_msg->msg_buf+p_user->sip_len, p_user->p_rbuf+p_user->sip_len, p_user->sdp_len);
|
|
rx_msg->msg_buf[p_user->sip_len + p_user->sdp_len] = '\0';
|
|
|
|
log_print(HT_LOG_DBG, "%s\r\n", rx_msg->msg_buf+p_user->sip_len);
|
|
|
|
int parse_len = sip_msg_parse_part2(rx_msg->msg_buf+p_user->sip_len, p_user->sdp_len, rx_msg);
|
|
if (parse_len != p_user->sdp_len)
|
|
{
|
|
log_print(HT_LOG_ERR, "%s, sip_msg_parse_part2=%d, sdp_pkt_len=%d!!!\r\n", __FUNCTION__, parse_len, p_user->sdp_len);
|
|
sip_free_msg(rx_msg);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
// 整个消息接收完成, 提交 rx_msg 到主任务
|
|
sip_commit_rx_msg(p_user, rx_msg);
|
|
p_user->rcv_dlen -= p_user->sip_len + p_user->sdp_len;
|
|
|
|
if (p_user->dyn_recv_buf == NULL)
|
|
{
|
|
if (p_user->rcv_dlen > 0)
|
|
{
|
|
memmove(p_user->rcv_buf, p_user->rcv_buf+p_user->sip_len + p_user->sdp_len, p_user->rcv_dlen);
|
|
p_user->rcv_buf[p_user->rcv_dlen] = '\0';
|
|
}
|
|
|
|
p_user->p_rbuf = p_user->rcv_buf;
|
|
p_user->mlen = sizeof(p_user->rcv_buf)-1;
|
|
p_user->sip_len = 0;
|
|
p_user->sdp_len = 0;
|
|
|
|
if (p_user->rcv_dlen > 16)
|
|
{
|
|
goto rx_analyse_point;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
free(p_user->dyn_recv_buf);
|
|
p_user->dyn_recv_buf = NULL;
|
|
p_user->sip_len = 0;
|
|
p_user->sdp_len = 0;
|
|
p_user->p_rbuf = 0;
|
|
p_user->rcv_dlen = 0;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/***********************************************************************\
|
|
SIP系统任务
|
|
\***********************************************************************/
|
|
void * sip_task(void * argv)
|
|
{
|
|
SIPTM stm;
|
|
|
|
while (hsip.net_rx_flag == 1)
|
|
{
|
|
if (hqBufGet(hsip.msg_queue, (char *)&stm))
|
|
{
|
|
switch (stm.msg_src)
|
|
{
|
|
case SIP_MSG_SRC:
|
|
sip_msg_rx(stm.msg_buf, stm.msg_len, stm.src_ip, stm.src_port, stm.dst_port);
|
|
break;
|
|
|
|
case SIP_PMSG_SRC:
|
|
sip_pmsg_rx((HSIP_MSG *)stm.msg_buf, &g_user);
|
|
sip_free_msg((HSIP_MSG *)stm.msg_buf);
|
|
break;
|
|
|
|
case SIP_TIMER_SRC:
|
|
sip_timer();
|
|
break;
|
|
|
|
case SUA_DEL_SRC:
|
|
sua_del_native(stm.msg_param, stm.dst_port);
|
|
break;
|
|
|
|
case SUA_CMD_SRC:
|
|
sua_emsg_recv((PUACMD)stm.msg_param, sua_get_by_index(stm.dst_port));
|
|
if (stm.msg_lock)
|
|
{
|
|
sys_os_mutex_leave(stm.msg_lock);
|
|
}
|
|
break;
|
|
|
|
case MEDIA_VIDEO_SRC:
|
|
sip_notify_emsg(NULL, (PUAEVT)stm.msg_param);
|
|
break;
|
|
|
|
case SIP_MSG_EXIT:
|
|
goto sip_task_exit;
|
|
break;
|
|
|
|
case SIP_RETCP_SRC:
|
|
sip_user_socket_init(&g_user);
|
|
g_user.user_state = HSIP_AUTH_IDLE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
sip_task_exit:
|
|
|
|
hsip.sip_task_tid = 0;
|
|
return 0;
|
|
}
|
|
|
|
void * sip_net_rx(void * argv)
|
|
{
|
|
HSIP_USER * p_user = &g_user;
|
|
|
|
struct sockaddr_in addr;
|
|
int addr_len = sizeof(struct sockaddr_in);
|
|
|
|
while (hsip.net_rx_flag == 1)
|
|
{
|
|
fd_set fdr;
|
|
FD_ZERO(&fdr);
|
|
|
|
if (p_user->sip_fd > 0)
|
|
{
|
|
FD_SET(p_user->sip_fd, &fdr);
|
|
}
|
|
else
|
|
{
|
|
usleep(100*1000);
|
|
continue;
|
|
}
|
|
|
|
struct timeval tv;
|
|
tv.tv_sec = 1;
|
|
tv.tv_usec = 0;
|
|
|
|
select(p_user->sip_fd+1, &fdr, NULL, NULL, &tv);
|
|
|
|
if (FD_ISSET(p_user->sip_fd, &fdr))
|
|
{
|
|
if (p_user->usrf_tcp_sip == 1)
|
|
{
|
|
sip_tcp_rx(p_user);
|
|
}
|
|
else
|
|
{
|
|
char buff[SIP_MAX_BUFF];
|
|
int rlen = recvfrom(p_user->sip_fd, buff, sizeof(buff), 0, (struct sockaddr *)&addr, (socklen_t*)&addr_len);
|
|
if (rlen < 16)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
int retry_cnt = 0;
|
|
SIPTM stm;
|
|
|
|
memset(&stm, 0, sizeof(SIPTM));
|
|
|
|
while (stm.msg_buf == NULL)
|
|
{
|
|
if (rlen >= (int)net_buf_get_size())
|
|
{
|
|
stm.msg_buf = (char *)malloc(rlen+8);
|
|
}
|
|
else
|
|
{
|
|
stm.msg_buf = net_buf_get_idle();
|
|
}
|
|
|
|
if (stm.msg_buf == NULL)
|
|
{
|
|
if (retry_cnt++ > 3)
|
|
{
|
|
log_print(HT_LOG_ERR, "%s, get idle net buf retry times > 3 !!!\r\n", __FUNCTION__);
|
|
goto net_rx_exit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
memcpy(stm.msg_buf, buff, rlen);
|
|
stm.msg_len = rlen;
|
|
stm.msg_src = SIP_MSG_SRC;
|
|
stm.src_ip = addr.sin_addr.s_addr;
|
|
stm.src_port = addr.sin_port;
|
|
stm.dst_port = p_user->sip_port;
|
|
|
|
stm.msg_buf[stm.msg_len] = '\0';
|
|
|
|
if (hqBufPut(hsip.msg_queue, (char *)&stm) == FALSE)
|
|
{
|
|
net_buf_free(stm.msg_buf);
|
|
log_print(HT_LOG_ERR, "%s, hqBufPut return fail!!!\r\n", __FUNCTION__);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
net_rx_exit:
|
|
|
|
hsip.net_rx_tid = 0;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
BOOL sip_tcp_reconnect_commit()
|
|
{
|
|
SIPTM stm;
|
|
memset(&stm, 0, sizeof(SIPTM));
|
|
stm.msg_src = SIP_RETCP_SRC;
|
|
|
|
if (hqBufPut(hsip.msg_queue, (char *)&stm) == FALSE)
|
|
{
|
|
log_print(HT_LOG_ERR, "%s, hqBufPut fail\r\n", __FUNCTION__);
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/***********************************************************************\
|
|
系统入口
|
|
\***********************************************************************/
|
|
BOOL sip_init()
|
|
{
|
|
strcpy(hsip.ver, "IP Camera");
|
|
hsip.user_expires_sec = 3600;
|
|
|
|
if (init_local_net() == FALSE)
|
|
{
|
|
log_print(HT_LOG_ERR, "%s, init_local_net fail\r\n", __FUNCTION__);
|
|
return FALSE;
|
|
}
|
|
|
|
hsip.user_expires_sec = g_gb28181_cfg.reg_expires;
|
|
|
|
srand((unsigned)time(NULL));
|
|
|
|
hsip.crypt_mode = HCRPTY_NULL;
|
|
|
|
sip_gs_cbcom_init();
|
|
sip_hsp_crypt_init();
|
|
|
|
return sip_init_bufs();
|
|
}
|
|
|
|
BOOL sip_start()
|
|
{
|
|
// 缺省rtp类型定义
|
|
sua_default_rtp_map_init();
|
|
|
|
memset(&hsip, 0, sizeof(HSIP_CLASS));
|
|
memset(&g_user, 0, sizeof(HSIP_USER));
|
|
|
|
if (sip_init() == FALSE)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// 初始化事务管理器
|
|
sip_trans_init(&(hsip.sip_trans), 100);
|
|
|
|
hsip.mutex_cb = sys_os_create_mutex();
|
|
|
|
hsip.net_rx_flag = 1;
|
|
hsip.net_rx_tid = sys_os_create_thread((void *)sip_net_rx, NULL);
|
|
if (hsip.net_rx_tid == 0)
|
|
{
|
|
log_print(HT_LOG_ERR, "%s, sys_os_create_thread sip_net_rx\r\n", __FUNCTION__);
|
|
return FALSE;
|
|
}
|
|
|
|
log_print(HT_LOG_INFO, "%s, create net rx thread sucessful\r\n", __FUNCTION__);
|
|
|
|
hsip.sip_task_tid = sys_os_create_thread((void *)sip_task, NULL);
|
|
if (hsip.sip_task_tid == 0)
|
|
{
|
|
log_print(HT_LOG_ERR, "%s, sys_os_create_thread sip_task\r\n", __FUNCTION__);
|
|
return FALSE;
|
|
}
|
|
|
|
log_print(HT_LOG_INFO, "%s, create sip main thread sucessful\r\n", __FUNCTION__);
|
|
|
|
sip_timer_init();
|
|
|
|
hsip.sys_init_flag = 1;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void sip_stop()
|
|
{
|
|
HSIP_USER * p_user = &g_user;
|
|
|
|
if (p_user->usrf_tcp_sip == 0)
|
|
{
|
|
// tcp模式不发注销包
|
|
|
|
p_user->expires_time = 0;
|
|
|
|
HSIP_MSG * tx_msg = sip_build_register_normal_msg(&g_user, inet_addr(p_user->server_ipstr), htons(p_user->server_port));
|
|
user_tx_free_msg(p_user,tx_msg);
|
|
}
|
|
|
|
hsip.sys_init_flag = 0;
|
|
|
|
// 停止sip timer
|
|
log_print(HT_LOG_INFO, "%s, sip_timer_deinit.\r\n", __FUNCTION__);
|
|
sip_timer_deinit();
|
|
|
|
// 停止网络接收任务
|
|
hsip.net_rx_flag = 0;
|
|
log_print(HT_LOG_INFO, "%s, stop net rx.\r\n", __FUNCTION__);
|
|
|
|
while (hsip.net_rx_tid != 0)
|
|
{
|
|
usleep(100*1000);
|
|
}
|
|
|
|
// 停止sip_task
|
|
log_print(HT_LOG_INFO, "%s, stop sip task.\r\n", __FUNCTION__);
|
|
|
|
SIPTM stm;
|
|
memset(&stm, 0, sizeof(SIPTM));
|
|
stm.msg_src = SIP_MSG_EXIT;
|
|
|
|
log_print(HT_LOG_INFO, "%s, send exit message to sip task.\r\n", __FUNCTION__);
|
|
|
|
hqBufPut(hsip.msg_queue, (char *)&stm);
|
|
|
|
usleep(100*1000);
|
|
|
|
while (hsip.sip_task_tid != 0)
|
|
{
|
|
usleep(100*1000);
|
|
}
|
|
|
|
log_print(HT_LOG_INFO, "%s, closesocket.\r\n", __FUNCTION__);
|
|
|
|
if (g_user.sip_fd > 0)
|
|
{
|
|
closesocket(g_user.sip_fd);
|
|
g_user.sip_fd = -1;
|
|
}
|
|
|
|
log_print(HT_LOG_INFO, "%s, sua_proxy_deinit.\r\n", __FUNCTION__);
|
|
sua_proxy_deinit();
|
|
|
|
// 停止消息队列
|
|
|
|
log_print(HT_LOG_INFO, "%s, sip msg queue delete.\r\n", __FUNCTION__);
|
|
|
|
if (hsip.msg_queue)
|
|
{
|
|
hqDelete(hsip.msg_queue);
|
|
hsip.msg_queue = NULL;
|
|
}
|
|
|
|
sip_trans_uninit(&(hsip.sip_trans));
|
|
|
|
sys_os_destroy_sig_mutex(hsip.mutex_cb);
|
|
|
|
// 释放缓冲区
|
|
|
|
log_print(HT_LOG_INFO, "%s, sip_parse_buf_deinit.\r\n", __FUNCTION__);
|
|
|
|
sip_parse_buf_deinit();
|
|
sys_buf_deinit();
|
|
|
|
log_print(HT_LOG_INFO, "%s, sip stop finish.\r\n", __FUNCTION__);
|
|
}
|
|
|
|
|
|
|
|
|