/*************************************************************************************** * * 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; }