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

1143 lines
26 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/***************************************************************************************
*
* 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"
/******************************************************************/
extern HSIP_CLASS hsip;
extern HSIP_USER g_user;
/******************************************************************/
static RTPMAPE default_rtp_map[96];
/******************************************************************/
void sua_rtp_map_entry_set(RTPMAPE * p_map, int index, const char * name, int channel, int hz, int mtype, int sdp_index)
{
p_map[index].pt = (uint8)index;
strncpy(p_map[index].name, name, sizeof(p_map[index].name) - 1);
p_map[index].channel = channel;
p_map[index].hz = hz;
p_map[index].mtype = mtype;
p_map[index].sdp_index = sdp_index;
}
void sua_default_rtp_map_init()
{
memset(default_rtp_map, 0, sizeof(default_rtp_map));
// 音频缺省定义
sua_rtp_map_entry_set(default_rtp_map, 0, "PCMU", 1, 8000, SDP_MEDIA_AUDIO, -1);
sua_rtp_map_entry_set(default_rtp_map, 3, "GSM", 1, 8000, SDP_MEDIA_AUDIO, -1);
sua_rtp_map_entry_set(default_rtp_map, 4, "G723", 1, 8000, SDP_MEDIA_AUDIO, -1);
sua_rtp_map_entry_set(default_rtp_map, 5, "DVI4", 1, 8000, SDP_MEDIA_AUDIO, -1);
sua_rtp_map_entry_set(default_rtp_map, 6, "DVI4", 1, 16000, SDP_MEDIA_AUDIO, -1);
sua_rtp_map_entry_set(default_rtp_map, 7, "LPC", 1, 8000, SDP_MEDIA_AUDIO, -1);
sua_rtp_map_entry_set(default_rtp_map, 8, "PCMA", 1, 8000, SDP_MEDIA_AUDIO, -1);
sua_rtp_map_entry_set(default_rtp_map, 9, "G722", 1, 8000, SDP_MEDIA_AUDIO, -1);
sua_rtp_map_entry_set(default_rtp_map, 10, "L16", 2, 44100, SDP_MEDIA_AUDIO, -1);
sua_rtp_map_entry_set(default_rtp_map, 11, "L16", 1, 44100, SDP_MEDIA_AUDIO, -1);
sua_rtp_map_entry_set(default_rtp_map, 12, "QCELP", 1, 8000, SDP_MEDIA_AUDIO, -1);
sua_rtp_map_entry_set(default_rtp_map, 13, "CN", 1, 8000, SDP_MEDIA_AUDIO, -1);
sua_rtp_map_entry_set(default_rtp_map, 14, "MPA", 1, 90000, SDP_MEDIA_AUDIO, -1); // The RTP timestamp clock rate is always 90, 000, independent of the sampling rate
sua_rtp_map_entry_set(default_rtp_map, 15, "G728", 1, 8000, SDP_MEDIA_AUDIO, -1);
sua_rtp_map_entry_set(default_rtp_map, 16, "DVI4", 1, 11025, SDP_MEDIA_AUDIO, -1);
sua_rtp_map_entry_set(default_rtp_map, 17, "DVI4", 1, 22050, SDP_MEDIA_AUDIO, -1);
sua_rtp_map_entry_set(default_rtp_map, 18, "G729", 1, 8000, SDP_MEDIA_AUDIO, -1);
// 视频缺省定义
sua_rtp_map_entry_set(default_rtp_map, 25, "CelB", 1, 90000, SDP_MEDIA_VIDEO, -1);
sua_rtp_map_entry_set(default_rtp_map, 26, "JPEG", 1, 90000, SDP_MEDIA_VIDEO, -1);
sua_rtp_map_entry_set(default_rtp_map, 28, "nv", 1, 90000, SDP_MEDIA_VIDEO, -1);
sua_rtp_map_entry_set(default_rtp_map, 31, "H261", 1, 90000, SDP_MEDIA_VIDEO, -1);
sua_rtp_map_entry_set(default_rtp_map, 32, "MPV", 1, 90000, SDP_MEDIA_VIDEO, -1);
sua_rtp_map_entry_set(default_rtp_map, 33, "MP2T", 1, 90000, SDP_MEDIA_VIDEO, -1);
sua_rtp_map_entry_set(default_rtp_map, 34, "H263", 1, 90000, SDP_MEDIA_VIDEO, -1);
}
void sua_r_rtp_map_init(SUA * p_sua)
{
// 复制缺省的rtp payload type定义动态类型在sdp解析时填写
memset(p_sua->r_rtp_map, 0, sizeof(p_sua->r_rtp_map));
memcpy(p_sua->r_rtp_map, default_rtp_map, sizeof(default_rtp_map));
}
void sua_r_map_update(SUA * p_sua)
{
int i;
for (i = 0; i < p_sua->r_a_cap_cnt; i++)
{
SDPINFO * p_sdp = &(p_sua->r_a_sdp[i]);
p_sua->r_rtp_map[p_sdp->pt].mtype = SDP_MEDIA_AUDIO;
p_sua->r_rtp_map[p_sdp->pt].sdp_index = i;
p_sua->r_rtp_map[p_sdp->pt].hz = p_sdp->hz;
strncpy(p_sua->r_rtp_map[p_sdp->pt].name, p_sdp->encoder, sizeof(p_sua->r_rtp_map[p_sdp->pt].name) - 1);
p_sua->r_rtp_map[p_sdp->pt].pt = p_sdp->pt;
p_sua->r_rtp_map[p_sdp->pt].channel = p_sdp->chn;
}
for (i = 0; i < p_sua->r_v_cap_cnt; i++)
{
SDPINFO * p_sdp = &(p_sua->r_v_sdp[i]);
p_sua->r_rtp_map[p_sdp->pt].mtype = SDP_MEDIA_VIDEO;
p_sua->r_rtp_map[p_sdp->pt].sdp_index = i;
p_sua->r_rtp_map[p_sdp->pt].hz = p_sdp->hz;
strncpy(p_sua->r_rtp_map[p_sdp->pt].name, p_sdp->encoder, sizeof(p_sua->r_rtp_map[p_sdp->pt].name) - 1);
p_sua->r_rtp_map[p_sdp->pt].pt = p_sdp->pt;
p_sua->r_rtp_map[p_sdp->pt].channel = p_sdp->chn;
}
}
BOOL sua_build_sdp_msg(SUA * p_sua, HSIP_MSG * tx_msg)
{
char tmp_buf[128];
int offset;
int index;
if (tx_msg == NULL)
{
return FALSE;
}
sip_add_tx_msg_sdp_line(tx_msg, "v", "0");
sip_add_tx_msg_sdp_line(tx_msg, "o", "%s 0 0 IN IP4 %s", p_sua->sua_deviceid, p_sua->sua_ipstr);
if (p_sua->s_name[0] == '\0')
{
sip_add_tx_msg_sdp_line(tx_msg, "s", "Play");
}
else
{
sip_add_tx_msg_sdp_line(tx_msg, "s", p_sua->s_name);
}
if (p_sua->uaf_multicast == 1)
{
struct in_addr in;
in.s_addr = p_sua->multicast_addr;
sip_add_tx_msg_sdp_line(tx_msg, "c", "IN IP4 %s", inet_ntoa(in));
}
else
{
sip_add_tx_msg_sdp_line(tx_msg, "c", "IN IP4 %s", p_sua->sua_ipstr);
}
// if(stricmp(p_sua->s_name, "Playback") == 0 || stricmp(p_sua->s_name, "Download") == 0)
if (p_sua->u_name[0] != '\0')
{
// SDP 带有u=xxxx,海康平台发送ACK之后会立即发送BYE消息断开连接
// sip_add_tx_msg_sdp_line(tx_msg, "u", "%s", p_sua->u_name);
sip_add_tx_msg_sdp_line(tx_msg, "t", "%u %u", (uint32)p_sua->st, (uint32)p_sua->et);
}
else
{
sip_add_tx_msg_sdp_line(tx_msg, "t", "0 0");
}
if (p_sua->uaf_rtp_mux == 1)
{
if (p_sua->l_mux_id == 0)
{
p_sua->l_mux_id = 4321; // rand() | sys_os_get_ms();
}
if (p_sua->mux_lport == 0)
{
p_sua->mux_lport = 10010; // p_sua->audio_rtp_media.local_port;
}
sip_add_tx_msg_sdp_line(tx_msg, "a", "rtpport-mux");
sip_add_tx_msg_sdp_line(tx_msg, "a", "muxid:%u", p_sua->l_mux_id);
}
if ((p_sua->uaf_uac == 1 && p_sua->l_a_cap_cnt > 0) || // 主叫
(p_sua->l_a_cap_cnt > 0 && p_sua->r_a_cap_cnt > 0)) // 被叫
{
offset = 0;
for (index = 0; index<p_sua->l_a_cap_cnt; index++)
{
offset += sprintf(tmp_buf + offset, "%u ", p_sua->l_a_cap[index]);
}
if (offset > 0)
{
tmp_buf[offset - 1] = '\0'; // 去掉后面的空格
}
if (p_sua->uaf_a_tcp_rtp == 1)
{
sip_add_tx_msg_sdp_line(tx_msg, "m", "audio %u TCP/RTP/AVP %s", p_sua->audio_rtp_media.local_port, tmp_buf);
if (p_sua->s_a_mode) // 对端主动模式
{
sip_add_tx_msg_sdp_line(tx_msg, "a", "setup:passive");
}
else
{
sip_add_tx_msg_sdp_line(tx_msg, "a", "setup:active");
}
sip_add_tx_msg_sdp_line(tx_msg, "a", "connection:new");
}
else
{
if (p_sua->uaf_rtp_mux == 1)
{
sip_add_tx_msg_sdp_line(tx_msg, "m", "audio %u RTP/AVP %s", p_sua->mux_lport, tmp_buf);
}
else
{
if (p_sua->uaf_uas == 1 && p_sua->uaf_multicast == 1)
{
sip_add_tx_msg_sdp_line(tx_msg, "m", "audio %u RTP/AVP %s", p_sua->audio_rtp_media.remote_port, tmp_buf);
}
else
{
sip_add_tx_msg_sdp_line(tx_msg, "m", "audio %u RTP/AVP %s", p_sua->audio_rtp_media.local_port, tmp_buf);
}
}
}
int sendrecv = -1;
for (index = 0; index<p_sua->l_a_cap_cnt; index++)
{
SDPINFO * p_sdp = &(p_sua->l_a_sdp[index]);
if (p_sdp->is_valid)
{
if (p_sdp->chn > 1)
{
sip_add_tx_msg_sdp_line(tx_msg, "a", "rtpmap:%u %s/%d/%d", p_sdp->pt, p_sdp->encoder, p_sdp->hz, p_sdp->chn);
}
else
{
sip_add_tx_msg_sdp_line(tx_msg, "a", "rtpmap:%u %s/%d", p_sdp->pt, p_sdp->encoder, p_sdp->hz);
}
if (p_sdp->desc[0] != '\0')
{
sip_add_tx_msg_sdp_line(tx_msg, "", "%s", p_sdp->desc);
}
if (p_sdp->ptime > 0)
{
sip_add_tx_msg_sdp_line(tx_msg, "a", "ptime:%u", p_sdp->ptime);
}
if (p_sdp->bps > 0)
{
sip_add_tx_msg_sdp_line(tx_msg, "b", "TIAS:%u", p_sdp->bps);
}
if (sendrecv < 0)
{
sendrecv = p_sdp->sendrecv;
}
}
}
if (sendrecv == SDP_SENDRECV_TXONLY)
{
sip_add_tx_msg_sdp_line(tx_msg, "a", "sendonly");
}
else if (sendrecv == SDP_SENDRECV_RXONLY)
{
sip_add_tx_msg_sdp_line(tx_msg, "a", "recvonly");
}
else
{
}
}
if ((p_sua->uaf_uac == 1 && p_sua->l_v_cap_cnt > 0) || // 主叫
(p_sua->l_v_cap_cnt > 0 && p_sua->r_v_cap_cnt > 0)) // 被叫
{
offset = 0;
for (index = 0; index<p_sua->l_v_cap_cnt; index++)
{
offset += sprintf(tmp_buf + offset, "%u ", p_sua->l_v_cap[index]);
}
if (offset > 0)
{
tmp_buf[offset - 1] = '\0'; // 去掉后面的空格
}
if (p_sua->uaf_v_tcp_rtp == 1)
{
sip_add_tx_msg_sdp_line(tx_msg, "m", "video %u TCP/RTP/AVP %s", p_sua->video_rtp_media.local_port, tmp_buf);
if (p_sua->s_v_mode) // 对端主动模式
{
sip_add_tx_msg_sdp_line(tx_msg, "a", "setup:passive");
}
else
{
sip_add_tx_msg_sdp_line(tx_msg, "a", "setup:active");
}
sip_add_tx_msg_sdp_line(tx_msg, "a", "connection:new");
}
else
{
if (p_sua->uaf_rtp_mux == 1)
{
sip_add_tx_msg_sdp_line(tx_msg, "m", "video %u RTP/AVP %s", p_sua->mux_lport, tmp_buf);
}
else
{
if (p_sua->uaf_uas == 1 && p_sua->uaf_multicast == 1)
{
sip_add_tx_msg_sdp_line(tx_msg, "m", "video %u RTP/AVP %s", p_sua->video_rtp_media.remote_port, tmp_buf);
}
else
{
sip_add_tx_msg_sdp_line(tx_msg, "m", "video %u RTP/AVP %s", p_sua->video_rtp_media.local_port, tmp_buf);
}
}
}
int sendrecv = -1;
for (index = 0; index<p_sua->l_v_cap_cnt; index++)
{
SDPINFO * p_sdp = &(p_sua->l_v_sdp[index]);
if (p_sdp->is_valid)
{
sip_add_tx_msg_sdp_line(tx_msg, "a", "rtpmap:%u %s/%d", p_sdp->pt, p_sdp->encoder, p_sdp->hz);
if (p_sdp->desc[0] != '\0')
{
sip_add_tx_msg_sdp_line(tx_msg, "", "%s", p_sdp->desc);
}
if (p_sdp->ptime > 0)
{
sip_add_tx_msg_sdp_line(tx_msg, "a", "ptime:%u", p_sdp->ptime);
}
if (p_sdp->bps > 0)
{
sip_add_tx_msg_sdp_line(tx_msg, "b", "TIAS:%u", p_sdp->bps);
}
if (sendrecv < 0)
{
sendrecv = p_sdp->sendrecv;
}
}
}
if (sendrecv == SDP_SENDRECV_TXONLY)
{
sip_add_tx_msg_sdp_line(tx_msg, "a", "sendonly");
}
else if (sendrecv == SDP_SENDRECV_RXONLY)
{
sip_add_tx_msg_sdp_line(tx_msg, "a", "recvonly");
}
else
{
}
}
if (p_sua->y_name[0] != '\0')
{
sip_add_tx_msg_sdp_line(tx_msg, "y", "%s", p_sua->y_name);
}
return TRUE;
}
int sua_calc_sdp_length(HSIP_MSG * tx_msg)
{
if (tx_msg == NULL)
{
return 0;
}
int offset = 0;
// 填写SDP消息内容
HDRV * pHdrV = (HDRV *)pps_lookup_start(&(tx_msg->sdp_ctx));
while (pHdrV != NULL)
{
if (pHdrV->header[0] != '\0')
{
offset += strlen(pHdrV->header) + strlen(pHdrV->value_string) + 3;
}
else
{
offset += strlen(pHdrV->value_string) + 2;
}
pHdrV = (HDRV *)pps_lookup_next(&(tx_msg->sdp_ctx), pHdrV);
}
pps_lookup_end(&(tx_msg->sdp_ctx));
return offset;
}
/******************************************************************\
从消息获取对端媒体信息写入SUA中
\******************************************************************/
BOOL sua_get_msg_media_info(SUA * p_sua, HSIP_MSG * rx_msg)
{
if (rx_msg == NULL || p_sua == NULL)
{
return FALSE;
}
if (sip_msg_with_sdp(rx_msg) == FALSE) // 判断是否消息带SDP
{
return FALSE;
}
sip_get_sdp_session_name(rx_msg, p_sua->s_name, sizeof(p_sua->s_name));
// 记录媒体信息
if (sip_get_remote_media_ip(rx_msg, &p_sua->remote_media_ip) == FALSE)
{
return FALSE;
}
// 组播地址
if (ntohl(p_sua->remote_media_ip) > ntohl(inet_addr("224.0.0.0")) && ntohl(p_sua->remote_media_ip) < ntohl(inet_addr("239.255.255.255")))
{
p_sua->uaf_multicast = 1;
p_sua->multicast_addr = p_sua->remote_media_ip;
}
else
{
p_sua->uaf_multicast = 0;
}
// UDP端口复用信息
if (sip_get_remote_rtp_mux_info(rx_msg, &p_sua->r_mux_id))
{
p_sua->uaf_rtp_mux = 1;
}
else
{
p_sua->uaf_rtp_mux = 0;
}
int i = 0;
int is_tcp = 0;
uint32 ipv4 = 0;
while (1)
{
BOOL ret;
int r_a_cap_cnt;
uint8 r_a_cap[MAX_AVN];
SDPINFO r_a_sdp[MAX_AVN];
memset(&r_a_sdp, 0, sizeof(SDPINFO) * MAX_AVN);
ret = sip_get_remote_cap(rx_msg, i, "audio", &r_a_cap_cnt, r_a_cap, &(p_sua->audio_rtp_media.remote_port), &is_tcp);
if (!ret)
{
break;
}
ret = sip_sdp_media_desc_parse(rx_msg, i, "audio", r_a_cap_cnt, r_a_cap, &r_a_sdp[0], &ipv4);
if (!ret)
{
break;
}
p_sua->audio_rtp_media.conn_addr = ipv4;
for (int j = 0; j < r_a_cap_cnt; j++)
{
sua_add_remote_sdp(p_sua, &r_a_sdp[j]);
}
i++;
}
if (ipv4)
{
// 组播地址判断
if (ntohl(ipv4) > ntohl(inet_addr("224.0.0.0")) && ntohl(ipv4) < ntohl(inet_addr("239.255.255.255")))
{
p_sua->uaf_multicast = 1;
p_sua->multicast_addr = ipv4;
}
else
{
p_sua->uaf_multicast = 0;
}
}
p_sua->uaf_a_tcp_rtp = is_tcp;
if (is_tcp)
{
sip_get_sdp_setup_mode(rx_msg, "audio", &p_sua->s_a_mode);
}
i = 0;
is_tcp = 0;
ipv4 = 0;
while (1)
{
BOOL ret;
int r_v_cap_cnt;
uint8 r_v_cap[MAX_AVN];
SDPINFO r_v_sdp[MAX_AVN];
memset(&r_v_sdp, 0, sizeof(SDPINFO) * MAX_AVN);
ret = sip_get_remote_cap(rx_msg, i, "video", &r_v_cap_cnt, r_v_cap, &(p_sua->video_rtp_media.remote_port), &is_tcp);
if (!ret)
{
break;
}
ret = sip_sdp_media_desc_parse(rx_msg, i, "video", r_v_cap_cnt, r_v_cap, &r_v_sdp[0], &ipv4);
if (!ret)
{
break;
}
p_sua->video_rtp_media.conn_addr = ipv4;
for (int j = 0; j < r_v_cap_cnt; j++)
{
sua_add_remote_sdp(p_sua, &r_v_sdp[j]);
}
i++;
}
if (ipv4)
{
// 组播地址判断
if (ntohl(ipv4) > ntohl(inet_addr("224.0.0.0")) && ntohl(ipv4) < ntohl(inet_addr("239.255.255.255")))
{
p_sua->uaf_multicast = 1;
p_sua->multicast_addr = ipv4;
}
else
{
p_sua->uaf_multicast = 0;
}
}
p_sua->uaf_v_tcp_rtp = is_tcp;
if (is_tcp)
{
sip_get_sdp_setup_mode(rx_msg, "video", &p_sua->s_v_mode);
}
// 处理组播媒体方向,被叫方向必须等于主叫的方向,主叫收到应该判断是否与其相等
// Similarly, the directionality information in the answer(sendonly, recvonly, or sendrecv) MUST equal that of the offer.
if (p_sua->uaf_multicast == 1 && p_sua->uaf_uas == 1)
{
if (p_sua->r_v_cap_cnt > 0)
{
for (i = 0; i<p_sua->l_v_cap_cnt; i++) p_sua->l_v_sdp[i].sendrecv = p_sua->r_v_sdp[0].sendrecv;
}
if (p_sua->r_a_cap_cnt > 0)
{
for (i = 0; i<p_sua->l_a_cap_cnt; i++) p_sua->l_a_sdp[i].sendrecv = p_sua->r_a_sdp[0].sendrecv;
}
}
// 复制解析的动态类型到相应的RTP映射单元
for (i = 0; i < p_sua->r_v_cap_cnt; i++)
{
uint8 pt = p_sua->r_v_cap[i];
if (pt < 96 && p_sua->r_v_sdp[i].encoder[0] == '\0')
{
// 对方没有填写固定pt的描述取缺省描述
if (default_rtp_map[pt].pt == pt && default_rtp_map[pt].name[0])
{
strcpy(p_sua->r_v_sdp[i].encoder, default_rtp_map[pt].name);
p_sua->r_v_sdp[i].hz = default_rtp_map[pt].hz;
p_sua->r_v_sdp[i].chn = default_rtp_map[pt].channel;
}
}
}
for (i = 0; i < p_sua->r_a_cap_cnt; i++)
{
uint8 pt = p_sua->r_a_cap[i];
if (pt < 96 && p_sua->r_a_sdp[i].encoder[0] == '\0')
{
// 对方没有填写固定pt的描述取缺省描述
if (default_rtp_map[pt].pt == pt && default_rtp_map[pt].name[0])
{
strcpy(p_sua->r_a_sdp[i].encoder, default_rtp_map[pt].name);
p_sua->r_a_sdp[i].hz = default_rtp_map[pt].hz;
p_sua->r_a_sdp[i].chn = default_rtp_map[pt].channel;
}
}
}
sip_get_sdp_uname(rx_msg, p_sua->u_name, sizeof(p_sua->u_name));
uint32 st, et;
if (sip_get_sdp_ttime(rx_msg, &st, &et))
{
p_sua->st = st;
p_sua->et = et;
}
if (sip_get_sdp_yname(rx_msg, p_sua->y_name, sizeof(p_sua->y_name)))
{
if (strlen(p_sua->y_name) > 0)
{
p_sua->v_rtp_info.rtp_ssrc = p_sua->a_rtp_info.rtp_ssrc = atoi(p_sua->y_name);
}
}
return TRUE;
}
/******************************************************************\
设置本身能力集
\******************************************************************/
void sua_clear_self_sdp(SUA * p_sua, const char * cap_name)
{
if (strcasecmp(cap_name, "audio") == 0)
{
p_sua->l_a_cap_cnt = 0;
memset(p_sua->l_a_sdp, 0, sizeof(p_sua->l_a_sdp));
}
else if (strcasecmp(cap_name, "video") == 0)
{
p_sua->l_v_cap_cnt = 0;
memset(p_sua->l_v_sdp, 0, sizeof(p_sua->l_v_sdp));
}
else
{
}
}
int sua_add_self_sdp(SUA * p_sua, SDPINFO * p_sdp)
{
int index = -1;
if (p_sua == NULL || p_sdp == NULL)
{
return index;
}
if (p_sdp->mtype == SDP_MEDIA_AUDIO)
{
int i;
// 查找重复的能力描述
for (i = 0; i < p_sua->l_a_cap_cnt; i++)
{
if (strcasecmp(p_sdp->encoder, p_sua->l_a_sdp[i].encoder) == 0)
{
return i;
}
}
// 添加到数组中
if (p_sua->l_a_cap_cnt < MAX_AVN)
{
index = p_sua->l_a_cap_cnt;
memcpy(&p_sua->l_a_sdp[index], p_sdp, sizeof(SDPINFO));
p_sua->l_a_sdp[index].is_valid = 1;
p_sua->l_a_cap[index] = p_sdp->pt;
p_sua->l_a_cap_cnt++;
}
}
else if (p_sdp->mtype == SDP_MEDIA_VIDEO)
{
int i;
// 查找重复的能力描述
for (i = 0; i < p_sua->l_v_cap_cnt; i++)
{
if (strcasecmp(p_sdp->encoder, p_sua->l_v_sdp[i].encoder) == 0)
{
return i;
}
}
// 添加到数组中
if (p_sua->l_v_cap_cnt < MAX_AVN)
{
index = p_sua->l_v_cap_cnt;
memcpy(&p_sua->l_v_sdp[index], p_sdp, sizeof(SDPINFO));
p_sua->l_v_sdp[index].is_valid = 1;
p_sua->l_v_cap[index] = p_sdp->pt;
p_sua->l_v_cap_cnt++;
}
}
return index;
}
int sua_add_remote_sdp(SUA * p_sua, SDPINFO * p_sdp)
{
int index = -1;
if (p_sua == NULL || p_sdp == NULL)
{
return index;
}
if (p_sdp->mtype == SDP_MEDIA_AUDIO)
{
int i;
// 查找重复的能力描述
for (i = 0; i < p_sua->r_a_cap_cnt; i++)
{
if (strcasecmp(p_sdp->encoder, p_sua->r_a_sdp[i].encoder) == 0)
{
p_sua->r_a_sdp[i].sendrecv |= p_sdp->sendrecv;
return i;
}
}
// 添加到数组中
if (p_sua->r_a_cap_cnt < MAX_AVN)
{
index = p_sua->r_a_cap_cnt;
memcpy(&p_sua->r_a_sdp[index], p_sdp, sizeof(SDPINFO));
p_sua->r_a_sdp[index].is_valid = 1;
p_sua->r_a_cap[index] = p_sdp->pt;
p_sua->r_a_cap_cnt++;
}
}
else if (p_sdp->mtype == SDP_MEDIA_VIDEO)
{
int i;
// 查找重复的能力描述
for (i = 0; i < p_sua->r_v_cap_cnt; i++)
{
if (strcasecmp(p_sdp->encoder, p_sua->r_v_sdp[i].encoder) == 0)
{
p_sua->r_v_sdp[i].sendrecv |= p_sdp->sendrecv;
return i;
}
}
// 添加到数组中
if (p_sua->r_v_cap_cnt < MAX_AVN)
{
index = p_sua->r_v_cap_cnt;
memcpy(&p_sua->r_v_sdp[index], p_sdp, sizeof(SDPINFO));
p_sua->r_v_sdp[index].is_valid = 1;
p_sua->r_v_cap[index] = p_sdp->pt;
p_sua->r_v_cap_cnt++;
}
}
return index;
}
/******************************************************************\
获取本身音频/视频能力集index为索引号
\******************************************************************/
int sua_get_video_sdp_cnt(SUA * p_sua, int lr)
{
if (p_sua == NULL)
{
return -1;
}
if (pps_safe_node(hsip.sua_fl, p_sua) == FALSE)
{
log_print(HT_LOG_ERR, "%s, param p_sua[%p] err!!!\r\n", __FUNCTION__, p_sua);
return -1;
}
if (lr == 0)
{
return p_sua->l_v_cap_cnt;
}
else
{
return p_sua->r_v_cap_cnt;
}
}
int sua_get_video_sdp(SUA * p_sua, int lr, int index, SDPINFO * p_sdp)
{
if (p_sua == NULL || p_sdp == NULL || index < 0)
{
return -1;
}
if (pps_safe_node(hsip.sua_fl, p_sua) == FALSE)
{
log_print(HT_LOG_ERR, "%s, param p_sua[%p] err!!!\r\n", __FUNCTION__, p_sua);
return -1;
}
if (lr == 0)
{
if (index >= p_sua->l_v_cap_cnt)
{
return -1;
}
memcpy(p_sdp, &p_sua->l_v_sdp[index], sizeof(SDPINFO));
return 0;
}
else
{
if (index >= p_sua->r_v_cap_cnt)
{
return -1;
}
memcpy(p_sdp, &p_sua->r_v_sdp[index], sizeof(SDPINFO));
return 0;
}
}
int sua_get_audio_sdp_cnt(SUA * p_sua, int lr)
{
if (p_sua == NULL)
{
return -1;
}
if (pps_safe_node(hsip.sua_fl, p_sua) == FALSE)
{
log_print(HT_LOG_ERR, "%s, param p_sua[%p] err!!!\r\n", __FUNCTION__, p_sua);
return -1;
}
if (lr == 0)
{
return p_sua->l_a_cap_cnt;
}
else
{
return p_sua->r_a_cap_cnt;
}
}
int sua_get_audio_sdp(SUA * p_sua, int lr, int index, SDPINFO * p_sdp)
{
if (p_sua == NULL || p_sdp == NULL || index < 0)
{
return -1;
}
if (pps_safe_node(hsip.sua_fl, p_sua) == FALSE)
{
log_print(HT_LOG_ERR, "%s, param p_sua[%p] err!!!\r\n", __FUNCTION__, p_sua);
return -1;
}
if (lr == 0)
{
if (index >= p_sua->l_a_cap_cnt)
{
return -1;
}
memcpy(p_sdp, &p_sua->l_a_sdp[index], sizeof(SDPINFO));
return 0;
}
else
{
if (index >= p_sua->r_a_cap_cnt)
{
return -1;
}
memcpy(p_sdp, &p_sua->r_a_sdp[index], sizeof(SDPINFO));
return 0;
}
}
/******************************************************************\
获取编码名称对应的rtp类型,例如H264 --> 96PCMA --> 8
\******************************************************************/
SDPINFO * sua_get_sdp_by_codec(SUA * p_sua, const char * codec_name)
{
int i;
SDPINFO * p_sdp = NULL;
for (i = 0; i < p_sua->l_a_cap_cnt; i++)
{
if (strcasecmp(p_sua->l_a_sdp[i].encoder, codec_name) == 0)
{
p_sdp = &p_sua->l_a_sdp[i];
return p_sdp;
}
}
for (i = 0; i < p_sua->l_v_cap_cnt; i++)
{
if (strcasecmp(p_sua->l_v_sdp[i].encoder, codec_name) == 0)
{
p_sdp = &p_sua->l_v_sdp[i];
return p_sdp;
}
}
return NULL;
}
uint8 sua_get_rtp_pt(SUA * p_sua, const char * codec_name)
{
SDPINFO * p_sdp = sua_get_sdp_by_codec(p_sua, codec_name);
if (p_sdp)
{
return p_sdp->pt;
}
else
{
return 255;
}
}
SDPINFO * sua_get_l_sdp_by_pt(SUA * p_sua, const uint8 rtp_pt)
{
int i;
SDPINFO * p_sdp = NULL;
for (i = 0; i < p_sua->l_a_cap_cnt; i++)
{
if (p_sua->l_a_sdp[i].pt == rtp_pt)
{
p_sdp = &p_sua->l_a_sdp[i];
return p_sdp;
}
}
for (i = 0; i < p_sua->l_v_cap_cnt; i++)
{
if (p_sua->l_v_sdp[i].pt == rtp_pt)
{
p_sdp = &p_sua->l_v_sdp[i];
return p_sdp;
}
}
return NULL;
}
SDPINFO * sua_get_r_sdp_by_pt(SUA * p_sua, const uint8 rtp_pt)
{
int i;
SDPINFO * p_sdp = NULL;
for (i = 0; i < p_sua->r_a_cap_cnt; i++)
{
if (p_sua->r_a_sdp[i].pt == rtp_pt)
{
p_sdp = &p_sua->r_a_sdp[i];
return p_sdp;
}
}
for (i = 0; i < p_sua->r_v_cap_cnt; i++)
{
if (p_sua->r_v_sdp[i].pt == rtp_pt)
{
p_sdp = &p_sua->r_v_sdp[i];
return p_sdp;
}
}
return NULL;
}
int sua_call_in_sdp_parse(SUA * p_sua, HSIP_MSG * rx_msg)
{
memset(p_sua->r_a_sdp, 0, sizeof(SDPINFO) * MAX_AVN);
memset(p_sua->r_v_sdp, 0, sizeof(SDPINFO) * MAX_AVN);
if (sua_get_msg_media_info(p_sua, rx_msg) == FALSE)
{
return -1;
}
sua_r_map_update(p_sua);
int i;
for (i = 0; i<MAX_AVN; i++)
{
if (p_sua->r_a_sdp[i].is_valid == 1)
{
log_print(HT_LOG_INFO, "%s, audio{encoder[%s], hz[%d], chn[%d]}\r\n", __FUNCTION__,
p_sua->r_a_sdp[i].encoder, p_sua->r_a_sdp[i].hz, p_sua->r_a_sdp[i].chn);
}
}
for (i = 0; i<MAX_AVN; i++)
{
if (p_sua->r_v_sdp[i].is_valid == 1)
{
log_print(HT_LOG_INFO, "%s, video{encoder[%s], hz[%d], chn[%d]}\r\n", __FUNCTION__,
p_sua->r_v_sdp[i].encoder, p_sua->r_v_sdp[i].hz, p_sua->r_v_sdp[i].chn);
}
}
return 0;
}
/******************************************************************\
判断相同的音频和视频能力,返回相同能力的总数
\******************************************************************/
int sua_check_same_cap(SUA * p_sua)
{
int i, j, v_cnt, a_cnt;
v_cnt = 0;
for (i = 0; i < p_sua->l_v_cap_cnt; i++)
{
for (j = 0; j < p_sua->r_v_cap_cnt; j++)
{
if (strcasecmp(p_sua->l_v_sdp[i].encoder, p_sua->r_v_sdp[j].encoder) == 0)
{
p_sua->same_video_cap[v_cnt] = p_sua->l_v_cap[i];
v_cnt++;
break;
}
}
}
p_sua->same_video_cap_count = v_cnt;
a_cnt = 0;
for (i = 0; i < p_sua->l_a_cap_cnt; i++)
{
for (j = 0; j < p_sua->r_a_cap_cnt; j++)
{
if (strcasecmp(p_sua->l_a_sdp[i].encoder, p_sua->r_a_sdp[j].encoder) == 0)
{
p_sua->same_audio_cap[v_cnt] = p_sua->l_a_cap[i];
a_cnt++;
break;
}
}
}
p_sua->same_audio_cap_count = a_cnt;
return (v_cnt + a_cnt);
}
int sua_adjust_l_sdp_set(SUA * p_sua)
{
int i, j, match = 0;
for (i = 0; i < p_sua->l_v_cap_cnt; i++)
{
match = 0;
for (j = 0; j < p_sua->r_v_cap_cnt; j++)
{
if (strcasecmp(p_sua->l_v_sdp[i].encoder, p_sua->r_v_sdp[j].encoder) == 0)
{
p_sua->l_v_sdp[i].pt = p_sua->r_v_sdp[j].pt;
p_sua->l_v_cap[i] = p_sua->l_v_sdp[i].pt;
match = 1;
break;
}
}
// 删除没有匹配上的本地能力
if (match == 0)
{
p_sua->l_v_sdp[i].is_valid = 0;
if (p_sua->l_v_cap_cnt > 1)
{
memmove(&(p_sua->l_v_cap[i]), &(p_sua->l_v_cap[i + 1]), (p_sua->l_v_cap_cnt - 1)*sizeof(uint8));
memmove(&(p_sua->l_v_sdp[i]), &(p_sua->l_v_sdp[i + 1]), (p_sua->l_v_cap_cnt - 1)*sizeof(SDPINFO));
}
p_sua->l_v_cap_cnt--;
i--;
}
}
for (i = 0; i < p_sua->l_a_cap_cnt; i++)
{
match = 0;
for (j = 0; j < p_sua->r_a_cap_cnt; j++)
{
if (strcasecmp(p_sua->l_a_sdp[i].encoder, p_sua->r_a_sdp[j].encoder) == 0)
{
p_sua->l_a_sdp[i].pt = p_sua->r_a_sdp[j].pt;
p_sua->l_a_cap[i] = p_sua->l_a_sdp[i].pt;
match = 1;
break;
}
}
// 删除没有匹配上的本地能力
if (match == 0)
{
p_sua->l_a_sdp[i].is_valid = 0;
if (p_sua->l_a_cap_cnt > 1)
{
memmove(&(p_sua->l_a_cap[i]), &(p_sua->l_a_cap[i + 1]), (p_sua->l_a_cap_cnt - 1)*sizeof(uint8));
memmove(&(p_sua->l_a_sdp[i]), &(p_sua->l_a_sdp[i + 1]), (p_sua->l_a_cap_cnt - 1)*sizeof(SDPINFO));
}
p_sua->l_a_cap_cnt--;
i--;
}
}
if (p_sua->l_v_cap_cnt > 0 || p_sua->l_a_cap_cnt > 0)
{
return 0;
}
return -1;
}