260 lines
6.4 KiB
C++
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;
|
|
}
|
|
|
|
|
|
|
|
|