39 #include <sofia-sip/sdp.h>
40 #include <sofia-sip/su.h>
48 #define MAX_CODEC_CHECK_FRAMES 50//x:mod_sofia.h
49 #define MAX_MISMATCH_FRAMES 5//x:mod_sofia.h
50 #define type2str(type) type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio"
51 #define VIDEO_REFRESH_FREQ 1000000
258 if (!strncasecmp(str, SUITES[i].name, strlen(SUITES[i].name))) {
259 return SUITES[i].
type;
270 return SUITES[type].
name;
277 return SUITES[type].
keylen;
303 return dft ? dft : 1;
318 "Deciding whether to pass zrtp-hash between a-leg and b-leg\n");
322 "CF_ZRTP_PASSTHRU_REQ not set on a-leg, so not propagating zrtp-hash\n");
347 if (!(smh = session->media_handle)) {
369 video_globals.
fps = fps;
409 if (!session->media_handle)
return NULL;
411 engine = &session->media_handle->engines[type];
428 sdp_attribute_t *attr;
429 int got_audio = 0, got_video = 0;
438 for (m = sdp->sdp_media; m; m = m->m_next) {
439 if (got_audio && got_video)
break;
440 if (m->m_port && ((m->m_type == sdp_media_audio && !got_audio)
441 || (m->m_type == sdp_media_video && !got_video))) {
442 for (attr = m->m_attributes; attr; attr = attr->a_next) {
443 if (
zstr(attr->a_name))
continue;
444 if (strcasecmp(attr->a_name,
"zrtp-hash") || !(attr->a_value))
continue;
445 if (m->m_type == sdp_media_audio) {
447 "Found audio zrtp-hash; setting r_sdp_audio_zrtp_hash=%s\n", attr->a_value);
451 }
else if (m->m_type == sdp_media_video) {
453 "Found video zrtp-hash; setting r_sdp_video_zrtp_hash=%s\n", attr->a_value);
469 sdp_attribute_t *attr;
487 if (sdp->sdp_origin) {
493 if (m->m_connections && m->m_connections->c_address) {
495 }
else if (sdp->sdp_connection && sdp->sdp_connection->c_address) {
499 for (attr = m->m_attributes; attr; attr = attr->a_next) {
500 if (!strcasecmp(attr->a_name,
"T38FaxVersion") && attr->a_value) {
502 }
else if (!strcasecmp(attr->a_name,
"T38MaxBitRate") && attr->a_value) {
504 }
else if (!strcasecmp(attr->a_name,
"T38FaxFillBitRemoval")) {
506 }
else if (!strcasecmp(attr->a_name,
"T38FaxTranscodingMMR")) {
508 }
else if (!strcasecmp(attr->a_name,
"T38FaxTranscodingJBIG")) {
510 }
else if (!strcasecmp(attr->a_name,
"T38FaxRateManagement") && attr->a_value) {
512 }
else if (!strcasecmp(attr->a_name,
"T38FaxMaxBuffer") && attr->a_value) {
514 }
else if (!strcasecmp(attr->a_name,
"T38FaxMaxDatagram") && attr->a_value) {
516 }
else if (!strcasecmp(attr->a_name,
"T38FaxUdpEC") && attr->a_value) {
518 }
else if (!strcasecmp(attr->a_name,
"T38VendorInfo") && attr->a_value) {
543 if (!(smh = session->media_handle)) {
575 if (!(smh = session->media_handle)) {
587 sdp_parser_t *parser = NULL;
591 if (!(parser = sdp_parse(NULL, r_sdp, (
int) strlen(r_sdp), 0))) {
595 if (!(sdp = sdp_session(parser))) {
596 sdp_parser_free(parser);
600 for (m = sdp->sdp_media; m; m = m->m_next) {
601 if (m->m_proto == sdp_proto_udptl && m->m_type == sdp_media_image && m->m_port) {
607 sdp_parser_free(parser);
627 if (!(smh = session->media_handle)) {
642 "Audio params are unchanged for %s.\n",
645 const char *err = NULL;
648 "Audio params changed for %s from %s:%d to %s:%d\n",
670 const
char *iananame,
685 if (!(smh = session->media_handle)) {
696 if (!strcasecmp(pmap->
iananame, iananame) && (!rate || (rate == pmap->
rate))) {
714 if (!
zstr(fmtp) && fmtpP) {
746 if (!(smh = session->media_handle)) {
755 exists = (!strcasecmp(name, pmap->
iananame) && pmap->
pt == pt && (!pmap->
rate || rate == pmap->
rate) && (!pmap->
ptime || pmap->
ptime == ptime));
760 if (strcmp(pmap->
rm_fmtp, fmtp)) {
844 const char *preferred = NULL, *fallback = NULL;
849 if (!(smh = session->media_handle)) {
870 return !
zstr(preferred) ? preferred : fallback;
878 const char *vars[] = {
"rtp_last_audio_local_crypto_key",
879 "srtp_remote_audio_crypto_key",
880 "srtp_remote_audio_crypto_tag",
881 "srtp_remote_audio_crypto_type",
882 "srtp_remote_video_crypto_key",
883 "srtp_remote_video_crypto_tag",
884 "srtp_remote_video_crypto_type",
886 "rtp_secure_media_inbound",
887 "rtp_secure_media_outbound",
890 for(i = 0; vars[i] ;i++) {
894 if (!(smh = session->media_handle)) {
906 if (!session->media_handle) {
910 return session->media_handle->engines[type].ssec[session->media_handle->engines[type].crypto_type].local_crypto_key;
1032 unsigned char b64_key[512] =
"";
1074 p = strrchr((
char *) b64_key,
'=');
1076 while (p && *p && *p ==
'=') {
1111 p = strchr(key_str,
' ');
1113 if (p && *p && *(p + 1)) {
1124 if (p && *p && *(p + 1)) {
1126 if (strncasecmp(p,
"inline:", 7)) {
1154 if (!session->media_handle)
return;
1155 engine = &session->media_handle->engines[type];
1157 engine->
type = type;
1165 char *keyvar, *tagvar, *ctypevar;
1171 keyvar =
"srtp_remote_audio_crypto_key";
1172 tagvar =
"srtp_remote_audio_crypto_tag";
1173 ctypevar =
"srtp_remote_audio_crypto_type";
1175 keyvar =
"srtp_remote_video_crypto_key";
1176 tagvar =
"srtp_remote_video_crypto_tag";
1177 ctypevar =
"srtp_remote_video_crypto_type";
1202 const char *varname;
1205 varname =
"rtp_secure_audio_confirmed";
1207 varname =
"rtp_secure_video_confirmed";
1244 const char *var = NULL;
1245 const char *val = NULL;
1246 char *suites = NULL;
1249 int argc = 0, i = 0, j = 0, k = 0;
1260 var =
"rtp_secure_media_inbound";
1262 var =
"rtp_secure_media_outbound";
1266 var =
"rtp_secure_media";
1270 if (!
zstr(val) && (suites = strchr(val,
':'))) {
1286 if (!strcasecmp(val,
"optional")) {
1288 }
else if (
switch_true(val) || !strcasecmp(val,
"mandatory")) {
1292 if (!
switch_false(val) && strcasecmp(val,
"forbidden")) {
1300 for (i = 0; i < argc; i++) {
1304 if (!strcasecmp(fields[i], SUITES[j].name)) {
1326 const
char *varname,
1332 const char *vval = NULL;
1336 if (!(smh = session->media_handle)) {
1348 engine = &session->media_handle->engines[type];
1356 ctype = SUITES[j].
type;
1357 vval = SUITES[j].
name;
1385 if (a && b && !strncasecmp(a, b, 23)) {
1460 if (!(smh = session->media_handle)) {
1484 #define add_stat(_i, _s) \
1485 switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", switch_str_nil(prefix), _s) ; \
1486 switch_snprintf(var_val, sizeof(var_val), "%" SWITCH_SIZE_T_FMT, _i); \
1487 switch_channel_set_variable(channel, var_name, var_val)
1489 #define add_stat_double(_i, _s) \
1490 switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", switch_str_nil(prefix), _s) ; \
1491 switch_snprintf(var_val, sizeof(var_val), "%0.2f", _i); \
1492 switch_channel_set_variable(channel, var_name, var_val)
1499 char var_name[256] =
"", var_val[35] =
"";
1545 if (!(smh = session->media_handle)) {
1565 if (!session->media_handle) {
1584 if (!(smh = session->media_handle)) {
1629 if (
zstr(params->sdp_username)) {
1630 params->sdp_username =
"FreeSWITCH";
1635 session->media_handle->
session = session;
1664 session->media_handle->mparams = params;
1666 if (!session->media_handle->mparams->video_key_freq) {
1667 session->media_handle->mparams->video_key_freq = 10000000;
1670 if (!session->media_handle->mparams->video_key_first) {
1671 session->media_handle->mparams->video_key_first = 1000000;
1710 smh->media_flags[flag] = 1;
1721 smh->media_flags[i] = flags[i];
1731 smh->media_flags[flag] = 0;
1737 return smh->media_flags[flag];
1748 if (!(smh = session->media_handle)) {
1757 flow = engine->
smode;
1778 return session->media_handle;
1786 if (!session->media_handle) {
1796 return smh->mparams;
1801 const char *abs, *codec_string = NULL;
1802 const char *ocodec = NULL, *val;
1804 char *tmp_codec_string;
1808 if (!(smh = session->media_handle)) {
1836 codec_string = ocodec;
1845 if (codec_string && *codec_string ==
'=') {
1852 codec_string = ocodec;
1855 codec_string = ocodec;
1862 if (!codec_string) {
1863 codec_string =
"PCMU@20i,PCMA@20i,speex@20i";
1894 if (!strcasecmp(input,
"pause")) {
1897 }
else if (!strcasecmp(input,
"resume")) {
1900 }
else if (!strcasecmp(input,
"stop")) {
1903 }
else if (!strncasecmp(input,
"debug:", 6)) {
1905 if (s && !strcmp(s,
"off")) {
1915 if (v_engine->rtp_session) {
1916 if (!strncasecmp(input,
"vbsize:", 7)) {
1917 int frames = 0, max_frames = 0;
1922 if ((s = strchr(s,
':')) && *(s+1) !=
'\0') {
1923 max_frames = atoi(s+1);
1930 }
else if (!strncasecmp(input,
"vdebug:", 7)) {
1933 if (s && !strcmp(s,
"off")) {
1947 jb_msec = atoi(val);
1949 if (strchr(val,
'p') && jb_msec > 0) {
1953 if ((p = strchr(val,
':'))) {
1957 if (strchr(p,
'p') && maxlen > 0) {
1963 if (jb_msec < 0 && jb_msec > -1000) {
1967 if (maxlen < 0 && maxlen > -1000) {
1971 if (jb_msec < 10 || jb_msec > 10000) {
1973 "Invalid Jitterbuffer spec [%d] must be between 10 and 10000\n", jb_msec);
1975 int qlen, maxqlen = 50;
1983 if (maxqlen < qlen) {
1991 SWITCH_LOG_DEBUG,
"Setting Jitterbuffer to %dms (%d frames) (%d max frames)\n",
1992 jb_msec, qlen, maxqlen);
1998 }
else if (!silent) {
2000 SWITCH_LOG_WARNING,
"Error Setting Jitterbuffer to %dms (%d frames)\n", jb_msec, qlen);
2010 int32_t jb_sync_msec = 0;
2011 uint32_t fps = 0, frames = 0;
2012 uint32_t min_frames = 0;
2013 uint32_t max_frames = 0;
2014 uint32_t cur_frames = 0;
2017 int sync_audio = 0, sync_video = 0;
2037 if (!strcasecmp(var,
"disabled")) {
2043 if (tmp && tmp > -50 && tmp < 10000) {
2047 if ((p = strchr(var,
':'))) {
2058 if (cur_frames != min_frames) {
2059 frames = cur_frames;
2062 if (frames < 1) frames = 1;
2067 if (!jb_sync_msec) {
2068 jb_sync_msec = frames * 75;
2072 if (frames != cur_frames) {
2079 SWITCH_LOG_DEBUG1,
"%s %s \"%s\" Sync A/V JB to %dms %u VFrames FPS %u a:%s v:%s\n",
2083 jb_sync_msec, frames, video_globals.
fps, sync_audio ?
"yes" :
"no", sync_video ?
"yes" :
"no");
2101 if (!(smh = session->media_handle)) {
2149 if (!(smh = session->media_handle)) {
2190 memset((*frame)->data, 0, (*frame)->datalen);
2230 int rtp_timeout_sec = 0;
2231 int rtp_hold_timeout_sec = 0;
2249 rtp_timeout_sec = v;
2256 rtp_hold_timeout_sec = v;
2260 if (rtp_timeout_sec) {
2265 if (!rtp_hold_timeout_sec) {
2266 rtp_hold_timeout_sec = rtp_timeout_sec * 10;
2270 if (rtp_hold_timeout_sec) {
2291 memset((*frame)->data, 0, (*frame)->datalen);
2310 snprintf(value,
sizeof(value),
"%.8x", rtcp_frame.
ssrc);
2313 snprintf(value,
sizeof(value),
"%u", rtcp_frame.
ntp_msw);
2316 snprintf(value,
sizeof(value),
"%u", rtcp_frame.
ntp_lsw);
2319 snprintf(value,
sizeof(value),
"%u", rtcp_frame.
timestamp);
2322 snprintf(value,
sizeof(value),
"%u", rtcp_frame.
packet_count);
2325 snprintf(value,
sizeof(value),
"%u", rtcp_frame.
octect_count);
2339 snprintf(header,
sizeof(header),
"Source%u-SSRC", i);
2340 snprintf(value,
sizeof(value),
"%.8x", rtcp_frame.
reports[i].
ssrc);
2342 snprintf(header,
sizeof(header),
"Source%u-Fraction", i);
2345 snprintf(header,
sizeof(header),
"Source%u-Lost", i);
2346 snprintf(value,
sizeof(value),
"%u", rtcp_frame.
reports[i].
lost);
2348 snprintf(header,
sizeof(header),
"Source%u-Loss-Avg", i);
2351 snprintf(header,
sizeof(header),
"Source%u-Highest-Sequence-Number-Received", i);
2354 snprintf(header,
sizeof(header),
"Source%u-Jitter", i);
2355 snprintf(value,
sizeof(value),
"%u", rtcp_frame.
reports[i].
jitter);
2357 snprintf(header,
sizeof(header),
"Source%u-LSR", i);
2358 snprintf(value,
sizeof(value),
"%u", rtcp_frame.
reports[i].
lsr);
2360 snprintf(header,
sizeof(header),
"Source%u-DLSR", i);
2361 snprintf(value,
sizeof(value),
"%u", rtcp_frame.
reports[i].
dlsr);
2432 if (codec_ms > 120) {
2434 "Your phone is trying to send timestamps that suggest an increment of %dms per packet\n"
2435 "That seems hard to believe so I am going to go on ahead and um ignore that, mmkay?\n",
2445 "Asynchronous PTIME not supported, changing our end from %d to %d\n",
2491 "alternate payload received (received %d, expecting %d)\n",
2502 "Changing current codec to %s (payload type %d).\n",
2514 "Could not change to payload type %d, ignoring...\n",
2556 int bytes = 0, samples = 0, frames = 0;
2562 if (!(smh = session->media_handle)) {
2597 frames = ((int) frame->datalen / bytes);
2623 if (!local_t38_options) {
2627 local_t38_options->
T38MaxBitRate = t38_options->T38MaxBitRate;
2637 local_t38_options->
remote_port = t38_options->remote_port;
2652 if (!(smh = session->media_handle) || !mimp) {
2683 if (!(engine = &smh->
engines[type]))
return;
2689 uint32_t system_bw = 0;
2690 const char *var = NULL, *bwv;
2727 if (!(smh = session->media_handle)) {
2802 msg.
from = __FILE__;
2834 if (!(smh = session->media_handle)) {
2853 if (session->read_resampler) {
2860 if (session->write_resampler) {
2871 "Changing Codec from %s@%dms@%dhz to %s@%dms@%luhz\n",
3044 if (!(smh = session->media_handle)) {
3067 if (!(smh = session->media_handle)) {
3092 if (!(smh = session->media_handle)) {
3113 if (!(smh = session->media_handle)) {
3160 #pragma warning(push)
3161 #pragma warning(disable:4702)
3191 if (strchr(ip,
':')) {
3219 if (strchr(ip,
':')) {
3232 sdp_attribute_t *attr;
3233 int i = 0, got_rtcp_mux = 0;
3235 int ice_seen = 0, cid = 0, ai = 0;
3250 attr = m->m_attributes;
3252 attr = sdp->sdp_attributes;
3255 for (; attr; attr = attr->a_next) {
3258 int argc = 0, j = 0;
3260 if (
zstr(attr->a_name)) {
3264 if (!strcasecmp(attr->a_name,
"ice-ufrag")) {
3272 }
else if (!strcasecmp(attr->a_name,
"ice-pwd")) {
3276 }
else if (!strcasecmp(attr->a_name,
"ice-options")) {
3278 }
else if (!strcasecmp(attr->a_name,
"setup")) {
3279 if (!strcasecmp(attr->a_value,
"passive") || !strcasecmp(attr->a_value,
"actpass")) {
3285 }
else if (!strcasecmp(attr->a_value,
"active")) {
3321 }
else if (!engine->
remote_ssrc && !strcasecmp(attr->a_name,
"ssrc") && attr->a_value) {
3322 engine->
remote_ssrc = (uint32_t) atol(attr->a_value);
3330 }
else if (!strcasecmp(attr->a_name,
"rtcp-mux")) {
3335 }
else if (!strcasecmp(attr->a_name,
"candidate")) {
3352 cid = fields[1] ? atoi(fields[1]) - 1 : 0;
3354 if (argc < 5 || engine->ice_in.cand_idx[cid] >=
MAX_CAND - 1) {
3359 for (i = 0; i < argc; i++) {
3365 "Drop %s Candidate cid: %d proto: %s type: %s addr: %s:%s (no network path)\n",
3367 cid+1, fields[2], fields[7], fields[4], fields[5]);
3371 "Save %s Candidate cid: %d proto: %s type: %s addr: %s:%s\n",
3373 cid+1, fields[2], fields[7], fields[4], fields[5]);
3386 while(j < argc && fields[j+1]) {
3387 if (!strcasecmp(fields[j],
"typ")) {
3389 }
else if (!strcasecmp(fields[j],
"raddr")) {
3391 }
else if (!strcasecmp(fields[j],
"rport")) {
3393 }
else if (!strcasecmp(fields[j],
"generation")) {
3409 for (cid = 0; cid < 2; cid++) {
3416 "Choose %s candidate, index %d, %s:%d\n", cid ?
"rtcp" :
"rtp", i,
3427 "Choose same candidate, index %d, for rtcp based on rtcp-mux attribute %s:%d\n", engine->
ice_in.
cand_idx[1],
3459 for (i = 0; i < 2; i++) {
3472 "setting remote %s ice addr to index %d %s:%d based on candidate\n",
type2str(type), engine->
ice_in.
chosen[0],
3493 "Setting remote rtcp %s addr to %s:%d based on candidate\n",
type2str(type),
3502 if (m && !got_rtcp_mux) {
3533 "rtcp_video_interval_msec" :
"rtcp_audio_interval_msec"))
3539 if (remote_rtcp_port) {
3540 if (!strcasecmp(val,
"passthru")) {
3545 int interval = atoi(val);
3546 if (interval < 100 || interval > 500000) {
3548 "Invalid rtcp interval spec [%d] must be between 100 and 500000\n", interval);
3589 #pragma warning(pop)
3598 if (!(smh = session->media_handle)) {
3610 #define MAX_MATCHES 30
3620 int j = 0, f = 0, g;
3621 struct matches mtmp[MAX_MATCHES] = { { 0 } };
3622 for(j = 0; j < m_idx; j++) {
3623 *&mtmp[j] = *&matches[j];
3628 for(j = 0; j < m_idx; j++) {
3629 if (mtmp[j].imp == imp) {
3630 *&matches[f++] = *&mtmp[j];
3652 unsigned long best_te_rate = 8000, cng_rate = 8000;
3654 sdp_attribute_t *attr;
3655 int ptime = 0, dptime = 0, maxptime = 0, dmaxptime = 0;
3656 int sendonly = 0, recvonly = 0;
3657 int greedy = 0, x = 0,
skip = 0;
3660 const char *crypto = NULL;
3661 int got_crypto = 0, got_video_crypto = 0, got_audio = 0, saw_audio = 0, got_avp = 0, got_video_avp = 0, got_video_savp = 0, got_savp = 0, got_udptl = 0, got_webrtc = 0;
3663 sdp_parser_t *parser = NULL;
3670 uint32_t near_rate = 0;
3672 sdp_rtpmap_t *mmap = NULL, *near_map = NULL;
3673 struct matches matches[MAX_MATCHES] = { { 0 } };
3674 struct matches near_matches[MAX_MATCHES] = { { 0 } };
3676 uint32_t remote_codec_rate = 0, fmtp_remote_codec_rate = 0;
3683 if (!(smh = session->media_handle)) {
3690 codec_array = smh->
codecs;
3693 if (!(parser = sdp_parse(NULL, r_sdp, (
int) strlen(r_sdp), 0))) {
3697 if (!(sdp = sdp_session(parser))) {
3698 sdp_parser_free(parser);
3720 if (proceed) *proceed = 1;
3726 if (!strcasecmp(val,
"generous")) {
3729 }
else if (!strcasecmp(val,
"greedy")) {
3732 }
else if (!strcasecmp(val,
"scrooge")) {
3744 if (strstr(smh->
origin,
"CiscoSystemsSIP-GW-UserAgent")) {
3751 if (strstr(smh->
origin,
"Sonus_UAC")) {
3754 "Hello,\nI see you have a Sonus!\n"
3755 "FYI, Sonus cannot follow the RFC on the proper way to send DTMF.\n"
3756 "Sadly, my creator had to spend several hours figuring this out so I thought you'd like to know that!\n"
3757 "Don't worry, DTMF will work but you may want to ask them to fix it......\n");
3777 if ((sdp->sdp_connection && sdp->sdp_connection->c_address && !strcmp(sdp->sdp_connection->c_address,
"0.0.0.0"))) {
3782 for (m = sdp->sdp_media; m; m = m->m_next) {
3783 sdp_connection_t *connection;
3790 if (m->m_type == sdp_media_audio) {
3795 maxptime = dmaxptime;
3797 if (m->m_proto == sdp_proto_extended_srtp || m->m_proto == sdp_proto_extended_rtp) {
3802 if (m->m_proto_name && !strcasecmp(m->m_proto_name,
"UDP/TLS/RTP/SAVPF")) {
3806 if (m->m_proto_name && !strcasecmp(m->m_proto_name,
"UDP/RTP/AVPF")) {
3810 if (m->m_proto == sdp_proto_srtp || m->m_proto == sdp_proto_extended_srtp) {
3811 if (m->m_type == sdp_media_audio) {
3816 }
else if (m->m_proto == sdp_proto_rtp) {
3817 if (m->m_type == sdp_media_audio) {
3822 }
else if (m->m_proto == sdp_proto_udptl) {
3826 if (got_udptl && m->m_type == sdp_media_image && m->m_port) {
3844 if (proceed) *proceed = 0;
3849 if (!strcasecmp(var,
"once")) {
3896 const char *err = NULL;
3924 msg->
from = __FILE__;
3936 }
else if (m->m_type == sdp_media_audio && m->m_port && got_audio && got_savp) {
3938 }
else if (m->m_type == sdp_media_audio && m->m_port && !got_audio) {
3944 memset(matches, 0,
sizeof(matches[0]) * MAX_MATCHES);
3945 memset(near_matches, 0,
sizeof(near_matches[0]) * MAX_MATCHES);
3947 if (!sendonly && (m->m_mode == sdp_sendonly || m->m_mode == sdp_inactive)) {
3951 if (!sendonly && m->m_connections && m->m_connections->c_address && !strcmp(m->m_connections->c_address,
"0.0.0.0")) {
3959 switch(a_engine->
rmode) {
3975 for (attr = sdp->sdp_attributes; attr; attr = attr->a_next) {
3976 if (
zstr(attr->a_name)) {
3981 if (!strncasecmp(attr->a_name,
"ice", 3)) {
3983 }
else if (sendonly < 2 && !strcasecmp(attr->a_name,
"sendonly")) {
3986 }
else if (sendonly < 2 && !strcasecmp(attr->a_name,
"inactive")) {
3989 }
else if (!strcasecmp(attr->a_name,
"recvonly")) {
4001 }
else if (sendonly < 2 && !strcasecmp(attr->a_name,
"sendrecv")) {
4003 }
else if (!strcasecmp(attr->a_name,
"ptime")) {
4004 ptime = dptime = atoi(attr->a_value);
4005 }
else if (!strcasecmp(attr->a_name,
"maxptime")) {
4006 maxptime = dmaxptime = atoi(attr->a_value);
4010 if (sendonly == 2 && ice) {
4015 if (sendonly != 1 && recvonly != 1) {
4022 }
else if (recvonly) {
4049 if (session->bugs) {
4051 "Session is connected to a media bug. "
4052 "Re-Negotiation implicitly disabled.\n");
4072 codec_array = smh->
codecs;
4078 for (attr = m->m_attributes; attr; attr = attr->a_next) {
4080 if (!strcasecmp(attr->a_name,
"fingerprint") && !
zstr(attr->a_value)) {
4086 for (attr = m->m_attributes; attr; attr = attr->a_next) {
4088 if (!strcasecmp(attr->a_name,
"rtcp") && attr->a_value) {
4094 }
else if (!strcasecmp(attr->a_name,
"ptime") && attr->a_value) {
4095 ptime = atoi(attr->a_value);
4096 }
else if (!strcasecmp(attr->a_name,
"maxptime") && attr->a_value) {
4097 maxptime = atoi(attr->a_value);
4098 }
else if (got_crypto < 1 && !strcasecmp(attr->a_name,
"crypto") && !
zstr(attr->a_value)) {
4103 if (m->m_proto != sdp_proto_srtp && !got_webrtc) {
4110 crypto = attr->a_value;
4111 crypto_tag = atoi(crypto);
4118 if (got_crypto == -1 && got_savp && !got_avp && !got_webrtc) {
4124 connection = sdp->sdp_connection;
4125 if (m->m_connections) {
4126 connection = m->m_connections;
4137 for (map = m->m_rtpmaps; map; map = map->rm_next) {
4139 const char *rm_encoding;
4140 uint32_t map_bit_rate = 0;
4142 int map_channels = map->rm_params ? atoi(map->rm_params) : 1;
4144 if (!(rm_encoding = map->rm_encoding)) {
4149 if (!strcasecmp(rm_encoding,
"telephone-event")) {
4152 best_te_rate = map->rm_rate;
4183 if (maxptime && (!codec_ms || codec_ms > maxptime)) {
4184 codec_ms = maxptime;
4193 if (!ptime && !strcasecmp(map->rm_encoding,
"g723")) {
4197 remote_codec_rate = map->rm_rate;
4198 fmtp_remote_codec_rate = 0;
4199 memset(&codec_fmtp, 0,
sizeof(codec_fmtp));
4201 if (
zstr(map->rm_fmtp)) {
4202 if (!strcasecmp(map->rm_encoding,
"ilbc")) {
4204 map_bit_rate = 13330;
4205 }
else if (!strcasecmp(map->rm_encoding,
"isac")) {
4207 map_bit_rate = 32000;
4222 }
else if (!strcasecmp(map->rm_encoding,
"opus")) {
4238 rm_encoding, map->rm_pt, (
int) remote_codec_rate, codec_ms, map_bit_rate, map_channels,
4241 match = (map->rm_pt == imp->
ianacode) ? 1 : 0;
4243 match = (!strcasecmp(rm_encoding, imp->
iananame) &&
4244 ((map->rm_pt < 96 && imp->
ianacode < 96) || (map->rm_pt > 95 && imp->
ianacode > 95)) &&
4246 if (fmtp_remote_codec_rate) {
4247 remote_codec_rate = fmtp_remote_codec_rate;
4251 if (match && bit_rate && map_bit_rate && map_bit_rate != bit_rate && strcasecmp(map->rm_encoding,
"ilbc") &&
4252 strcasecmp(map->rm_encoding,
"isac")) {
4257 if (match && remote_codec_rate && codec_rate && remote_codec_rate != codec_rate && (!strcasecmp(map->rm_encoding,
"pcma") ||
4258 !strcasecmp(map->rm_encoding,
"pcmu"))) {
4267 "Bah HUMBUG! Sticking with %s@%uh@%ui\n",
4269 }
else if ((ptime && codec_ms && codec_ms * 1000 != imp->
microseconds_per_packet) || remote_codec_rate != codec_rate) {
4274 "Audio Codec Compare [%s:%d:%u:%d:%u:%d] is saved as a near-match\n",
4278 near_matches[nm_idx].
rate = remote_codec_rate;
4279 near_matches[nm_idx].
imp =
imp;
4280 near_matches[nm_idx].
map =
map;
4287 matches[m_idx].
rate = codec_rate;
4288 matches[m_idx].
imp =
imp;
4289 matches[m_idx].
map =
map;
4293 "Audio Codec Compare [%s:%d:%u:%d:%u:%d] ++++ is saved as a match\n",
4296 if (m_idx >= MAX_MATCHES) {
4304 if (m_idx >= MAX_MATCHES) {
4316 if (!m_idx && nm_idx) {
4319 for(j = 0; j < nm_idx; j++) {
4326 near_rate = near_matches[j].
rate;
4327 near_match = near_matches[j].
imp;
4328 near_map = near_matches[j].
map;
4330 switch_snprintf(tmp,
sizeof(tmp),
"%s@%uh@%ui%dc", near_match->iananame, near_rate ? near_rate : near_match->samples_per_second,
4331 codec_ms, near_match->number_of_channels);
4348 matches[m_idx].
rate = near_rate;
4349 matches[m_idx].
imp = timp;
4350 matches[m_idx].
map = near_map;
4362 greedy_sort(smh, matches, m_idx, codec_array, total_codecs);
4369 for(j = 0; j < m_idx; j++) {
4372 matches[j].map->rm_encoding,
4374 matches[j].
map->rm_fmtp,
4376 matches[j].
map->rm_pt,
4382 mimp = matches[j].
imp;
4383 mmap = matches[j].
map;
4403 pmap->
channels = mmap->rm_params ? atoi(mmap->rm_params) : 1;
4405 if (!strcasecmp((
char *) mmap->rm_encoding,
"opus")) {
4412 if (!
zstr((
char *) mmap->rm_fmtp) &&
switch_stristr(
"stereo=1", (
char *) mmap->rm_fmtp)) {