Files
gb28181/GB28181Device/sip/sip_tx.cpp
2024-12-15 20:42:32 +08:00

260 lines
6.4 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 "word_analyse.h"
#include "hsip.h"
#include "sua.h"
#include "sip_parse.h"
#include "sip_tx.h"
/*******************************************************/
extern HSIP_CLASS hsip;
/*******************************************************\
消息发送处理
\*******************************************************/
int sip_user_net_tx(HSIP_USER * p_user, char * p_data, int len, uint32 rip, uint16 rport)
{
int slen = 0;
if (p_user->usrf_tcp_sip == 1)
{
if (p_user->sip_fd <= 0)
{
sip_tcp_reconnect_commit();
}
if (p_user->sip_fd <= 0)
{
log_print(HT_LOG_ERR, "%s, sip_fd = %d!!!\r\n", __FUNCTION__);
return -1;
}
slen = send(p_user->sip_fd, p_data, len, 0);
}
else
{
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = rip;
addr.sin_port = rport;
slen = sendto(p_user->sip_fd, p_data, len, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
}
return slen;
}
void sip_send_msg(HSIP_USER * p_user, SUA * p_sua, HSIP_MSG * tx_msg)
{
int offset = 0;
int buflen;
char sip_tx_buffer[SIP_MAX_BUFF];
char * tx_buf;
if (tx_msg == NULL || p_user == NULL)
{
return;
}
if (p_sua)
{
tx_buf = p_sua->last_tx_packet;
buflen = sizeof(p_sua->last_tx_packet);
}
else
{
tx_buf = sip_tx_buffer;
buflen = sizeof(sip_tx_buffer);
}
// 填写SIP消息头
offset += snprintf(tx_buf+offset, buflen-offset, "%s %s\r\n", tx_msg->first_line.header, tx_msg->first_line.value_string);
// 填写Via信息
HSIP_VIAH * via_hdr = (HSIP_VIAH *)pps_lookup_start(&(tx_msg->via_ctx));
while (via_hdr != NULL)
{
offset += snprintf(tx_buf+offset, buflen-offset, "Via: %s\r\n", via_hdr->via_string);
via_hdr = (HSIP_VIAH *)pps_lookup_next(&(tx_msg->via_ctx), via_hdr);
}
pps_lookup_end(&(tx_msg->via_ctx));
// 填写SIP消息内容
HDRV * pHdrV = (HDRV *)pps_lookup_start(&(tx_msg->sip_ctx));
while (pHdrV != NULL)
{
offset += snprintf(tx_buf+offset, buflen-offset, "%s: %s\r\n", pHdrV->header, pHdrV->value_string);
pHdrV = (HDRV *)pps_lookup_next(&(tx_msg->sip_ctx), pHdrV);
}
pps_lookup_end(&(tx_msg->sip_ctx));
offset += snprintf(tx_buf+offset, buflen-offset, "\r\n");
// 填写SDP消息内容
if (tx_msg->sdp_ctx.node_num != 0)
{
HDRV * pHdrV = (HDRV *)pps_lookup_start(&(tx_msg->sdp_ctx));
while (pHdrV != NULL)
{
if ((strcmp(pHdrV->header, "pidf") == 0) || (strcmp(pHdrV->header, "text/html") == 0))
{
offset += snprintf(tx_buf+offset, buflen-offset, "%s\r\n", pHdrV->value_string);
}
else
{
if (pHdrV->header[0] != '\0')
{
offset += snprintf(tx_buf+offset, buflen-offset, "%s=%s\r\n", pHdrV->header, pHdrV->value_string);
}
else
{
offset += snprintf(tx_buf+offset, buflen-offset, "%s\r\n", pHdrV->value_string);
}
}
pHdrV = (HDRV *)pps_lookup_next(&(tx_msg->sdp_ctx), pHdrV);
}
pps_lookup_end(&(tx_msg->sdp_ctx));
}
// 记录最近发送的消息,以便超时重传
if (p_sua != NULL)
{
p_sua->last_tx_packet_len = offset;
p_sua->last_tx_time = sys_os_get_uptime();
p_sua->state_retx_count = 0;
}
switch (tx_msg->msg_crpty_mode)
{
case HCRPTY_GS:
sip_gs_msg_crypt_all(tx_buf, offset);
break;
case HCRPTY_HSP:
sip_hsp_msg_crypt_all(tx_buf, offset);
break;
case HCRPTY_NULL:
break;
}
log_print(HT_LOG_DBG, "%s, client-->server : \r\n%s\r\n", __FUNCTION__, tx_buf);
int slen = sip_user_net_tx(p_user, tx_buf, offset, tx_msg->remote_ip, tx_msg->remote_port);
if (slen <= 0 || slen != offset)
{
log_print(HT_LOG_ERR, "%s, failed[%s]!!!\r\n", __FUNCTION__, strerror(errno));
}
p_user->last_tx_time = sys_os_get_uptime();
}
void sip_sua_send_msg(SUA * p_sua, HSIP_MSG * tx_msg)
{
if (p_sua == NULL)
{
return;
}
HSIP_USER * p_user = p_sua->p_user;
if (p_user == NULL)
{
return;
}
sip_send_msg(p_user, p_sua, tx_msg);
}
void sip_user_send_msg(HSIP_USER * p_user, HSIP_MSG * tx_msg)
{
sip_send_msg(p_user, NULL, tx_msg);
}
/*******************************************************\
重传消息
\*******************************************************/
void sip_resend_sua_msg(SUA * p_sua)
{
int tx_len;
char * tx_buf;
p_sua->last_tx_time = sys_os_get_uptime();
p_sua->state_retx_count++;
if (p_sua->last_tx_packet_len == 0)
{
return;
}
tx_buf = p_sua->last_tx_packet;
tx_len = p_sua->last_tx_packet_len;
int slen = sip_user_net_tx(p_sua->p_user, tx_buf, tx_len, p_sua->remote_real_ip, p_sua->remote_real_port);
if (slen != tx_len)
{
log_print(HT_LOG_WARN, "%s, slen=%d, tx_len=%d\r\n", __FUNCTION__, slen, tx_len);
}
}
/*******************************************************\
SIP实用消息发送:404,180,...
\*******************************************************/
HSIP_MSG * sip_build_call_response(HSIP_MSG * rx_msg, const char * response_hdr)
{
if (rx_msg == NULL)
{
return NULL;
}
HSIP_MSG * tx_msg = sip_get_msg_buf();
if (NULL == tx_msg)
{
log_print(HT_LOG_ERR, "%s, get message buffer failed\r\n", __FUNCTION__);
return NULL;
}
tx_msg->msg_type = 1;
tx_msg->msg_sub_type = 200;
tx_msg->local_port = rx_msg->local_port;
sip_add_tx_msg_fline(tx_msg, "SIP/2.0", response_hdr);
sip_copy_msg_via(rx_msg, tx_msg);
sip_copy_msg_line(rx_msg, tx_msg, "From");
sip_copy_msg_line(rx_msg, tx_msg, "To");
sip_copy_msg_line(rx_msg, tx_msg, "Call-ID");
sip_copy_msg_line(rx_msg, tx_msg, "CSeq");
sip_add_tx_msg_line(tx_msg, "User-Agent", hsip.ver);
sip_add_tx_msg_line(tx_msg, "Content-Length", "0");
tx_msg->remote_ip = rx_msg->remote_ip;
tx_msg->remote_port = rx_msg->remote_port;
return tx_msg;
}