41 #include <sofia-sip/sdp.h> 42 #include <sofia-sip/su.h> 51 #define MAX_CODEC_CHECK_FRAMES 50//x:mod_sofia.h 52 #define MAX_MISMATCH_FRAMES 5//x:mod_sofia.h 53 #define type2str(type) type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : (type == SWITCH_MEDIA_TYPE_AUDIO ? "audio" : "text") 54 #define VIDEO_REFRESH_FREQ 1000000 56 #define TEXT_TIMER_MS 100 57 #define TEXT_TIMER_SAMPLES 10 58 #define TEXT_PERIOD_TIMEOUT 3000 59 #define MAX_RED_FRAMES 25 60 #define RED_PACKET_SIZE 100 210 #define MAX_REJ_STREAMS 10 296 ice_resolve_candidate = resolve_ice;
310 if (!strncasecmp(str, SUITES[i].
name, strlen(SUITES[i].name)) || (SUITES[i].alias && strlen(SUITES[i].alias) && !strncasecmp(str, SUITES[i].alias, strlen(SUITES[i].alias)))) {
311 return SUITES[i].
type;
322 return SUITES[type].
name;
365 return dft ? dft : 1;
372 uint32_t
fps, elapsed = 0;
414 sdp_attribute_t *attr;
432 if (sdp->sdp_origin) {
438 if (m->m_connections && m->m_connections->c_address) {
440 }
else if (sdp->sdp_connection && sdp->sdp_connection->c_address) {
444 for (attr = m->m_attributes; attr; attr = attr->a_next) {
445 if (!strcasecmp(attr->a_name,
"T38FaxVersion") && attr->a_value) {
447 }
else if (!strcasecmp(attr->a_name,
"T38MaxBitRate") && attr->a_value) {
449 }
else if (!strcasecmp(attr->a_name,
"T38FaxFillBitRemoval")) {
451 }
else if (!strcasecmp(attr->a_name,
"T38FaxTranscodingMMR")) {
453 }
else if (!strcasecmp(attr->a_name,
"T38FaxTranscodingJBIG")) {
455 }
else if (!strcasecmp(attr->a_name,
"T38FaxRateManagement") && attr->a_value) {
457 }
else if (!strcasecmp(attr->a_name,
"T38FaxMaxBuffer") && attr->a_value) {
459 }
else if (!strcasecmp(attr->a_name,
"T38FaxMaxDatagram") && attr->a_value) {
461 }
else if (!strcasecmp(attr->a_name,
"T38FaxUdpEC") && attr->a_value) {
463 }
else if (!strcasecmp(attr->a_name,
"T38VendorInfo") && attr->a_value) {
541 sdp_parser_t *parser = NULL;
545 if (!(parser = sdp_parse(NULL, r_sdp, (
int) strlen(r_sdp), 0))) {
549 if (!(sdp = sdp_session(parser))) {
550 sdp_parser_free(parser);
554 for (m = sdp->sdp_media; m; m = m->m_next) {
555 if (m->m_proto == sdp_proto_udptl && m->m_type == sdp_media_image && m->m_port) {
561 sdp_parser_free(parser);
596 "Audio params are unchanged for %s.\n",
599 const char *err = NULL;
602 "Audio params changed for %s from %s:%d to %s:%d\n",
625 const char *iananame,
653 if (!fmtp_a) fmtp_a =
"";
654 if (!fmtp_in) fmtp_in =
"";
657 if (!strcasecmp(pmap->
iananame, iananame) && !strcasecmp(fmtp_a, fmtp_in) && (!rate || (rate == pmap->
rate))) {
675 if (!
zstr(fmtp) && fmtpP) {
720 exists = (type == pmap->
type && !strcasecmp(name, pmap->
iananame));
723 exists = (type == pmap->
type && !strcasecmp(name, pmap->
iananame) && pmap->
pt == pt && (!pmap->
rate || rate == pmap->
rate) && (!pmap->
ptime || pmap->
ptime == ptime));
739 if (strcmp(pmap->
rm_fmtp, fmtp)) {
750 exists = (type == pmap->
type && !strcasecmp(name, pmap->
iananame) && pmap->
pt == pt);
752 exists = (type == pmap->
type && !strcasecmp(name, pmap->
iananame) && pmap->
pt == pt && (!pmap->
rate || rate == pmap->
rate) && (!pmap->
ptime || pmap->
ptime == ptime));
757 if (strcmp(pmap->
rm_fmtp, fmtp)) {
844 const char *preferred = NULL, *fallback = NULL;
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",
885 "srtp_remote_text_crypto_key",
886 "srtp_remote_text_crypto_tag",
887 "srtp_remote_text_crypto_type",
889 "rtp_secure_media_inbound",
890 "rtp_secure_media_outbound",
893 for(i = 0; vars[i] ;i++) {
1038 unsigned char b64_key[512] =
"";
1079 p = strrchr((
char *) b64_key,
'=');
1081 while (p && *p && *p ==
'=') {
1111 #define CRYPTO_KEY_MATERIAL_LIFETIME_MKI_ERR 0x0u 1112 #define CRYPTO_KEY_MATERIAL_MKI 0x1u 1113 #define CRYPTO_KEY_MATERIAL_LIFETIME 0x2u 1115 #define RAW_BITS_PER_64_ENCODED_CHAR 6 1127 const char *field_begin;
1128 const char *field_end;
1129 const char *sep, *space;
1138 field_begin = strchr(*p,
'|');
1140 if (field_begin && (field_begin + 1 < end)) {
1141 space = strchr(field_begin,
' ');
1142 field_end = strchr(field_begin + 2,
'|');
1149 if ((field_end == NULL) || (space < field_end)) {
1156 sep = strchr(field_begin,
':');
1157 if (sep && (sep + 1 < field_end) && isdigit(*(sep + 1))) {
1160 for (i = 1, *p = sep - 1; *p != field_begin; --(*p), i *= 10) {
1161 val += ((**p) -
'0') * i;
1164 res |= ((val << 8) & 0x00ffff00);
1167 for (i = 1, *p = field_end - 1; *p != sep; --(*p), i *= 10) {
1168 val += ((**p) -
'0') * i;
1170 res |= (val & 0x000000ff);
1171 }
else if (isdigit(*(field_begin + 1)) && (*(field_begin + 2) ==
'^') && isdigit(*(field_begin + 3))) {
1173 val = ((uint32_t) (*(field_begin + 1) -
'0')) << 8;
1177 for (i = 1, *p = field_end - 1; *p != (field_begin + 2); --(*p), i *= 10) {
1178 val += ((**p) -
'0') * i;
1181 res |= (val & 0x000000ff);
1197 const char *key_material,
1198 int key_material_len,
1200 unsigned int mki_id,
1201 unsigned int mki_size)
1206 if (new_key_material == NULL) {
1217 new_key_material->
next = tail;
1219 return new_key_material;
1228 const char *end = NULL;
1233 end = strchr(p,
' ');
1235 end = p + strlen(p);
1246 const char *p, *delimit;
1247 const char *key_material_begin;
1248 const char *key_material_end = NULL;
1256 uint16_t lifetime_base = 0;
1257 uint16_t lifetime_exp = 0;
1261 unsigned long *key_material_n = NULL;
1263 bool multiple_keys =
false;
1265 const char *key_param;
1278 if (
zstr(key_param)) {
1279 goto no_crypto_found;
1282 *key_material_n = 0;
1284 p = strchr(key_param,
' ');
1286 if (!(p && *p && *(p + 1))) {
1287 goto no_crypto_found;
1314 key_material_begin = p;
1319 if ((delimit = strchr(p,
':')) == NULL) {
1320 goto bad_error_parsing_near;
1323 method_len = delimit - p;
1326 goto bad_key_param_method;
1334 if (!(p && *p && *(p + 1))) {
1339 if ((opts = strchr(p,
'|')) && (opts < key_material_end)) {
1340 keysalt_len = opts - p;
1342 keysalt_len = key_material_end - p;
1345 if (keysalt_len >
sizeof(key)) {
1346 goto bad_keysalt_len;
1351 if (!multiple_keys) {
1357 multiple_keys =
true;
1362 if (!(p < key_material_end)) {
1372 for (
int i = 0; i < 2 && (*opts ==
'|'); ++i) {
1376 switch ((opt_field >> 24) & 0x3) {
1380 lifetime_base = ((opt_field & 0x00ffff00) >> 8) & 0xffff;
1381 lifetime_exp = (opt_field & 0x000000ff) & 0xffff;
1382 lifetime = pow(lifetime_base, lifetime_exp);
1388 mki_id = ((opt_field & 0x00ffff00) >> 8) & 0xffff;
1389 mki_size = (opt_field & 0x000000ff) & 0xffff;
1394 goto bad_key_lifetime_or_mki;
1398 if (mki_id == 0 && lifetime == 0) {
1401 }
else if (mki_id == 0 || lifetime == 0) {
1404 goto bad_key_no_mki_index;
1409 goto bad_key_no_mki_size;
1419 goto bad_key_no_mki_index;
1422 if (mki_size != key_material->
mki_size) {
1423 goto bad_key_mki_size;
1428 SUITES[type].keysalt_len, (
char*) key_material_begin, key_material_end - key_material_begin, lifetime, mki_id, mki_size);
1429 *key_material_n = *key_material_n + 1;
1445 bad_error_parsing_near:
1463 bad_key_lifetime_or_mki:
1468 bad_key_no_mki_index:
1472 bad_key_no_mki_size:
1480 bad_key_param_method:
1492 engine->
type = type;
1506 char *keyvar, *tagvar, *ctypevar;
1512 keyvar =
"srtp_remote_audio_crypto_key";
1513 tagvar =
"srtp_remote_audio_crypto_tag";
1514 ctypevar =
"srtp_remote_audio_crypto_type";
1516 keyvar =
"srtp_remote_video_crypto_key";
1517 tagvar =
"srtp_remote_video_crypto_tag";
1518 ctypevar =
"srtp_remote_video_crypto_type";
1520 keyvar =
"srtp_remote_text_crypto_key";
1521 tagvar =
"srtp_remote_text_crypto_tag";
1522 ctypevar =
"srtp_remote_text_crypto_type";
1548 const char *varname;
1551 varname =
"rtp_secure_audio_confirmed";
1553 varname =
"rtp_secure_video_confirmed";
1555 varname =
"rtp_secure_text_confirmed";
1591 const char *var = NULL;
1592 const char *val = NULL;
1593 char *suites = NULL;
1596 int argc = 0, i = 0, j = 0, k = 0;
1607 var =
"rtp_secure_media_inbound";
1609 var =
"rtp_secure_media_outbound";
1613 var =
"rtp_secure_media";
1617 if (!
zstr(val) && (suites = strchr(val,
':'))) {
1633 if (!strcasecmp(val,
"optional")) {
1635 }
else if (
switch_true(val) || !strcasecmp(val,
"mandatory")) {
1639 if (!
switch_false(val) && strcasecmp(val,
"forbidden")) {
1647 for (i = 0; i < argc; i++) {
1651 if (!strcasecmp(fields[i], SUITES[j].
name)) {
1671 const char *varname,
1677 const char *vval = NULL;
1709 ctype = SUITES[j].
type;
1710 vval = use_alias ? SUITES[j].
alias : SUITES[j].
name;
1739 if (a && b && !strncasecmp(a, b, 23)) {
1847 #define add_stat(_i, _s) \ 1848 switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", switch_str_nil(prefix), _s) ; \ 1849 switch_snprintf(var_val, sizeof(var_val), "%" SWITCH_SIZE_T_FMT, _i); \ 1850 switch_channel_set_variable(channel, var_name, var_val) 1852 #define add_stat_double(_i, _s) \ 1853 switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", switch_str_nil(prefix), _s) ; \ 1854 switch_snprintf(var_val, sizeof(var_val), "%0.2f", _i); \ 1855 switch_channel_set_variable(channel, var_name, var_val) 1862 char var_name[256] =
"", var_val[35] =
"";
2154 flow = engine->
smode;
2179 flow = engine->
rmode;
2201 if (!engine)
return 0;
2210 if (!engine)
return NULL;
2241 const char *abs, *codec_string = NULL;
2242 const char *ocodec = NULL, *val;
2244 char *tmp_codec_string;
2278 codec_string = ocodec;
2286 if (codec_string && *codec_string ==
'=') {
2297 if (!codec_string) {
2298 codec_string =
"PCMU@20i,PCMA@20i,speex@20i";
2328 if (!strcasecmp(input,
"pause")) {
2331 }
else if (!strcasecmp(input,
"resume")) {
2334 }
else if (!strcasecmp(input,
"stop")) {
2337 }
else if (!strncasecmp(input,
"debug:", 6)) {
2339 if (s && !strcmp(s,
"off")) {
2349 if (v_engine->rtp_session) {
2350 if (!strncasecmp(input,
"vbsize:", 7)) {
2351 int frames = 0, max_frames = 0;
2356 if ((s = strchr(s,
':')) && *(s+1) !=
'\0') {
2357 max_frames = atoi(s+1);
2366 }
else if (!strncasecmp(input,
"vdebug:", 7)) {
2369 if (s && !strcmp(s,
"off")) {
2377 if (t_engine->rtp_session) {
2378 if (!strncasecmp(input,
"tbsize:", 7)) {
2379 int frames = 0, max_frames = 0;
2384 if ((s = strchr(s,
':')) && *(s+1) !=
'\0') {
2385 max_frames = atoi(s+1);
2392 }
else if (!strncasecmp(input,
"tdebug:", 7)) {
2395 if (s && !strcmp(s,
"off")) {
2409 jb_msec = atoi(val);
2411 if (strchr(val,
'p') && jb_msec > 0) {
2413 if (!maxlen) maxlen = jb_msec * 50;
2416 if ((p = strchr(val,
':'))) {
2420 if (strchr(p,
'p') && maxlen > 0) {
2426 if (!maxlen) maxlen = jb_msec * 50;
2428 if (jb_msec < 0 && jb_msec > -1000) {
2432 if (maxlen < 0 && maxlen > -1000) {
2437 if (jb_msec < 10 || jb_msec > 10000) {
2441 maxlen = jb_msec * 100;
2444 if (jb_msec && maxlen) {
2445 int qlen, maxqlen = 50;
2453 if (maxqlen < qlen) {
2461 SWITCH_LOG_DEBUG,
"Setting Jitterbuffer to %dms (%d frames) (%d max frames)\n",
2462 jb_msec, qlen, maxqlen);
2468 }
else if (!silent) {
2470 SWITCH_LOG_WARNING,
"Error Setting Jitterbuffer to %dms (%d frames)\n", jb_msec, qlen);
2480 int32_t jb_sync_msec = 0;
2481 uint32_t
fps = 0, frames = 0;
2482 uint32_t min_frames = 0;
2483 uint32_t max_frames = 0;
2484 uint32_t cur_frames = 0;
2507 if (!strcasecmp(var,
"disabled")) {
2513 if (tmp && tmp > -50 && tmp < 10000) {
2517 if ((p = strchr(var,
':'))) {
2525 fps = video_globals.
fps;
2527 if (fps < 15)
return;
2532 if (cur_frames && min_frames && cur_frames >= min_frames) {
2533 frames = cur_frames;
2534 }
else if (min_frames) {
2535 frames = min_frames;
2542 if (!jb_sync_msec && frames) {
2543 jb_sync_msec = ((double)1000 / fps) * frames;
2547 SWITCH_LOG_DEBUG1,
"%s %s \"%s\" Sync A/V JB to %dms %u VFrames, FPS %u a:%s sync_ms:%d\n",
2551 jb_sync_msec, frames, video_globals.
fps, sync_audio ?
"yes" :
"no", jb_sync_msec);
2615 (*tfP)->pool =
pool;
2617 (*tfP)->text_write_frame.packet = (*tfP)->text_write_frame_data;
2618 (*tfP)->text_write_frame.data = (
switch_byte_t *)(*tfP)->text_write_frame.packet + 12;
2621 (*tfP)->red_max = 5;
2626 for(x = 0; x < (*tfP)->red_max; x++) {
2645 unsigned char *
buf = data;
2647 unsigned char *e = (buf + datalen);
2653 *new_datalen = datalen;
2655 *(buf + datalen) =
'\0';
2657 while (*buf & 0x80) {
2663 pt[
count] = *buf & 0x7F;
2664 len[
count] = (ntohs(*(uint16_t *)(buf + 2)) & 0x03ff);
2671 idx = count - (seq - want_seq);
2679 *new_datalen = len[idx];
2683 for(x = 0; x < idx; x++) {
2687 *new_datalen = len[idx];
2688 *new_payload = pt[idx];
2690 memcpy(new_data, buf, len[idx]);
2692 *(((
char *)new_data) + len[idx]) =
'\0';
2700 unsigned char *
buf = data;
2701 int bytes = 0,
count = 0, pt = 0, len = 0;
2702 unsigned char *e = (buf + datalen);
2704 *new_datalen = datalen;
2707 while (*buf & 0x80) {
2715 len = (ntohs(*(uint16_t *)(buf + 2)) & 0x03ff);
2720 *new_datalen = datalen - bytes - 1 - (
count *4);
2845 memset((*frame)->data, 0, (*frame)->datalen);
2885 int rtp_timeout_sec = 0;
2886 int rtp_hold_timeout_sec = 0;
2909 "rtp_timeout_sec deprecated use media_timeout variable.\n");
2910 rtp_timeout_sec = v;
2918 "rtp_hold_timeout_sec deprecated use media_timeout variable.\n");
2919 rtp_hold_timeout_sec = v;
2923 if (rtp_timeout_sec) {
2928 if (!rtp_hold_timeout_sec) {
2929 rtp_hold_timeout_sec = rtp_timeout_sec * 10;
2933 if (rtp_hold_timeout_sec) {
2955 memset((*frame)->data, 0, (*frame)->datalen);
2974 snprintf(value,
sizeof(value),
"%.8x", rtcp_frame.
ssrc);
2977 snprintf(value,
sizeof(value),
"%u", rtcp_frame.
ntp_msw);
2980 snprintf(value,
sizeof(value),
"%u", rtcp_frame.
ntp_lsw);
2983 snprintf(value,
sizeof(value),
"%u", rtcp_frame.
timestamp);
2986 snprintf(value,
sizeof(value),
"%u", rtcp_frame.
packet_count);
2989 snprintf(value,
sizeof(value),
"%u", rtcp_frame.
octect_count);
3003 snprintf(header,
sizeof(header),
"Source%u-SSRC", i);
3004 snprintf(value,
sizeof(value),
"%.8x", rtcp_frame.
reports[i].
ssrc);
3006 snprintf(header,
sizeof(header),
"Source%u-Fraction", i);
3009 snprintf(header,
sizeof(header),
"Source%u-Lost", i);
3010 snprintf(value,
sizeof(value),
"%u", rtcp_frame.
reports[i].
lost);
3012 snprintf(header,
sizeof(header),
"Source%u-Loss-Avg", i);
3015 snprintf(header,
sizeof(header),
"Source%u-Highest-Sequence-Number-Received", i);
3018 snprintf(header,
sizeof(header),
"Source%u-Jitter", i);
3019 snprintf(value,
sizeof(value),
"%u", rtcp_frame.
reports[i].
jitter);
3021 snprintf(header,
sizeof(header),
"Source%u-LSR", i);
3022 snprintf(value,
sizeof(value),
"%u", rtcp_frame.
reports[i].
lsr);
3024 snprintf(header,
sizeof(header),
"Source%u-DLSR", i);
3025 snprintf(value,
sizeof(value),
"%u", rtcp_frame.
reports[i].
dlsr);
3027 snprintf(header,
sizeof(header),
"Rtt%u-Avg", i);
3028 snprintf(value,
sizeof(value),
"%f", rtcp_frame.
reports[i].
rtt_avg);
3097 if (codec_ms > 120) {
3099 "[CBR]: Your phone is trying to send timestamps that suggest an increment of %dms per packet\n" 3100 "That seems hard to believe so I am going to go on ahead and um ignore that, mmkay?\n",
3110 "[CBR]: Asynchronous PTIME not supported, changing our end from %d to %d\n",
3156 if (codec_ms > 120) {
3159 "[VBR]: Remote party is trying to send timestamps that suggest an increment of [%d] ms per packet, which is too high. Ignoring.\n",
3168 "[VBR]: Packet size change detected. Remote PTIME changed from [%d] to [%d]\n",
3207 "alternate payload received (received %d, expecting %d)\n",
3218 "Changing current codec to %s (payload type %d).\n",
3230 "Could not change to payload type %d, ignoring...\n",
3268 for (i = 1; i < 3; i++) {
3306 if ((*frame)->datalen == 0) {
3308 (*frame)->data =
"";
3332 int bytes = 0, samples = 0, frames = 0;
3379 frames = ((int) frame->
datalen / bytes);
3406 if (!local_t38_options) {
3466 if (!(engine = &smh->
engines[type]))
return;
3472 uint32_t system_bw = 0;
3473 const char *var = NULL, *bwv;
3587 msg.
from = __FILE__;
3652 "Changing Codec from %s@%dms@%dhz to %s@%dms@%luhz\n",
3952 #pragma warning(push) 3953 #pragma warning(disable:4702) 4009 if (strchr(ip,
':')) {
4037 if (strchr(ip,
':')) {
4050 sdp_attribute_t *attr = NULL, *attrs[2] = { 0 };
4051 int i = 0, got_rtcp_mux = 0;
4053 int ice_seen = 0, cid = 0, ai = 0, attr_idx = 0, cand_seen = 0, relay_ok = 0;
4055 int ice_resolve = 0;
4075 attrs[0] = m->m_attributes;
4076 attrs[1] = sdp->sdp_attributes;
4078 attrs[0] = sdp->sdp_attributes;
4083 for (attr_idx = 0; attr_idx < 2 && !(ice_seen && cand_seen); attr_idx++) {
4084 for (attr = attrs[attr_idx]; attr; attr = attr->a_next) {
4086 char *fields[32] = {0};
4087 int argc = 0, j = 0;
4089 if (
zstr(attr->a_name)) {
4093 if (!strcasecmp(attr->a_name,
"ice-ufrag")) {
4101 }
else if (!strcasecmp(attr->a_name,
"ice-pwd")) {
4105 }
else if (!strcasecmp(attr->a_name,
"ice-options")) {
4107 }
else if (!strcasecmp(attr->a_name,
"setup")) {
4108 if (!strcasecmp(attr->a_value,
"passive") ||
4115 }
else if (!strcasecmp(attr->a_value,
"active")) {
4151 }
else if (!engine->
remote_ssrc && !strcasecmp(attr->a_name,
"ssrc") && attr->a_value) {
4152 engine->
remote_ssrc = (uint32_t) atol(attr->a_value);
4160 }
else if (!strcasecmp(attr->a_name,
"rtcp-mux")) {
4169 }
else if (!strcasecmp(attr->a_name,
"candidate")) {
4191 cid = fields[1] ? atoi(fields[1]) - 1 : 0;
4198 for (i = 0; i < argc; i++) {
4205 }
else if (fields[4] && ice_resolve) {
4210 "Drop %s Candidate cid: %d proto: %s type: %s addr: %s:%s (cannot resolve)\n",
4212 cid+1, fields[2], fields[7], fields[4], fields[5]);
4217 "Drop %s Candidate cid: %d proto: %s type: %s addr: %s:%s (not an IP address)\n",
4219 cid+1, fields[2], fields[7], fields[4] ? fields[4] :
"(null)", fields[5]);
4225 "Drop %s Candidate cid: %d proto: %s type: %s addr: %s:%s (no network path)\n",
4227 cid+1, fields[2], fields[7] ? fields[7] :
"N/A", con_addr, fields[5]);
4231 "Save %s Candidate cid: %d proto: %s type: %s addr: %s:%s\n",
4233 cid+1, fields[2], fields[7] ? fields[7] :
"N/A", con_addr, fields[5]);
4246 while(j < argc && j <=
sizeof(fields)/
sizeof(
char*) && fields[j+1] && engine->
ice_in.
cand_idx[cid] <
MAX_CAND - 1) {
4247 if (!strcasecmp(fields[j],
"typ")) {
4249 }
else if (!strcasecmp(fields[j],
"raddr")) {
4251 }
else if (!strcasecmp(fields[j],
"rport")) {
4253 }
else if (!strcasecmp(fields[j],
"generation")) {
4281 if (relay_ok != is_relay)
continue;
4285 "Choose %s candidate, index %d, %s:%d\n", cid ?
"rtcp" :
"rtp", i,
4296 "Choose same candidate, index %d, for rtcp based on rtcp-mux attribute %s:%d\n", engine->
ice_in.
cand_idx[1],
4337 for (i = 0; i < 2; i++) {
4348 const char *media_varname = NULL, *port_varname = NULL;
4352 "setting remote %s ice addr to index %d %s:%d based on candidate\n",
type2str(type), engine->
ice_in.
chosen[0],
4367 media_varname =
"remote_video_ip";
4368 port_varname =
"remote_video_port";
4370 media_varname =
"remote_audio_ip";
4371 port_varname =
"remote_audio_port";
4373 media_varname =
"remote_text_ip";
4374 port_varname =
"remote_text_port";
4383 const char *media_varname = NULL, *port_varname = NULL;
4387 "Setting remote rtcp %s addr to %s:%d based on candidate\n",
type2str(type),
4396 media_varname =
"remote_video_rtcp_ip";
4397 port_varname =
"remote_video_rtcp_port";
4399 media_varname =
"remote_audio_rtcp_ip";
4400 port_varname =
"remote_audio_rtcp_port";
4402 media_varname =
"remote_text_rtcp_ip";
4403 port_varname =
"remote_text_rtcp_port";
4413 if (m && !got_rtcp_mux) {
4443 "rtcp_video_interval_msec" :
"rtcp_audio_interval_msec"))
4449 if (remote_rtcp_port) {
4450 if (!strcasecmp(val,
"passthru")) {
4455 int interval = atoi(val);
4456 if (interval < 100 || interval > 500000) {
4458 "Invalid rtcp interval spec [%d] must be between 100 and 500000\n", interval);
4498 #pragma warning(pop) 4519 #define MAX_MATCHES 30 4528 #define MIN(a,b) (((a) < (b)) ? (a) : (b)) 4533 int j = 0, f = 0, g;
4534 struct matches mtmp[MAX_MATCHES] = { { 0 } };
4536 m_idx =
MIN(m_idx, MAX_MATCHES);
4538 for(j = 0; j < m_idx; j++) {
4539 *&mtmp[j] = *&matches[j];
4545 for(j = 0; j < m_idx; j++) {
4546 if (mtmp[j].imp && mtmp[j].imp == imp) {
4547 *&matches[f++] = *&mtmp[j];
4571 if (!top++) pmap->
current = 1;
4577 const char *varname =
"invalid";
4581 varname =
"audio_media_flow";
4584 varname =
"video_media_flow";
4587 varname =
"text_media_flow";
4596 const char *varname =
"invalid";
4600 varname =
"remote_audio_media_flow";
4603 varname =
"remote_video_media_flow";
4606 varname =
"remote_text_media_flow";
4615 const char *smode_str =
"";
4621 smode_str =
"sendonly";
4625 smode_str =
"recvonly";
4628 smode_str =
"inactive";
4631 smode_str =
"disabled";
4634 smode_str =
"sendrecv";
4638 *mode_str = smode_str;
4639 *opp_mode = opp_smode;
4655 if (other_session) {
4674 msg->
from = __FILE__;
4679 if (other_session) {
4684 uint8_t proceed = 1;
4685 const char *sdp_in, *other_ep;
4698 msg->
from = __FILE__;
4713 const char *varname = NULL, *smode_str = NULL;
4716 int pass_codecs = 0;
4728 old_smode = engine->
smode;
4730 engine->
smode = smode;
4757 const char *varname = NULL, *rmode_str = NULL;
4770 if (engine->
rmode != rmode) {
4774 engine->
rmode = rmode;
4791 uint8_t match = 0, vmatch = 0, almost_vmatch = 0, tmatch = 0, fmatch = 0;
4793 unsigned long best_te_rate = 8000, cng_rate = 8000;
4795 sdp_attribute_t *attr;
4796 int ptime = 0, dptime = 0, maxptime = 0, dmaxptime = 0;
4797 int sendonly = 0, recvonly = 0, inactive = 0;
4798 int greedy = 0, x = 0, skip = 0;
4801 const char *crypto = NULL;
4802 int got_crypto = 0, got_video_crypto = 0, got_audio = 0, saw_audio = 0, saw_video = 0, got_avp = 0, got_savp = 0, got_udptl = 0, got_webrtc = 0, got_text = 0, got_text_crypto = 0, got_msrp = 0;
4804 sdp_parser_t *parser = NULL;
4810 uint32_t near_rate = 0;
4812 sdp_rtpmap_t *mmap = NULL, *near_map = NULL;
4813 struct matches matches[MAX_MATCHES] = { { 0 } };
4814 struct matches near_matches[MAX_MATCHES] = { { 0 } };
4816 uint32_t remote_codec_rate = 0, fmtp_remote_codec_rate = 0;
4818 int m_idx = 0, skip_rtcp = 0, skip_video_rtcp = 0, got_rtcp_mux = 0, got_video_rtcp_mux = 0;
4820 int vmatch_pt = 1, consider_video_fmtp = 1;
4821 int rtcp_auto_audio = 0, rtcp_auto_video = 0;
4822 int got_audio_rtcp = 0, got_video_rtcp = 0;
4843 codec_array = smh->
codecs;
4846 if (!(parser = sdp_parse(NULL, r_sdp, (
int) strlen(r_sdp), 0))) {
4850 if (!(sdp = sdp_session(parser))) {
4851 sdp_parser_free(parser);
4864 rtcp_auto_video = 1;
4865 rtcp_auto_audio = 1;
4881 if (proceed) *proceed = 1;
4887 if (!strcasecmp(val,
"generous")) {
4890 }
else if (!strcasecmp(val,
"greedy")) {
4893 }
else if (!strcasecmp(val,
"scrooge")) {
4905 if (strstr(smh->
origin,
"CiscoSystemsSIP-GW-UserAgent")) {
4912 if (strstr(smh->
origin,
"Sonus_UAC")) {
4915 "Hello,\nI see you have a Sonus!\n" 4916 "FYI, Sonus cannot follow the RFC on the proper way to send DTMF.\n" 4917 "Sadly, my creator had to spend several hours figuring this out so I thought you'd like to know that!\n" 4918 "Don't worry, DTMF will work but you may want to ask them to fix it......\n");
4939 if ((sdp->sdp_connection && sdp->sdp_connection->c_address && !strcmp(sdp->sdp_connection->c_address,
"0.0.0.0"))) {
4950 for (m = sdp->sdp_media; m; m = m->m_next) {
4951 sdp_connection_t *connection;
4957 case sdp_media_audio:
4960 case sdp_media_video:
4963 case sdp_media_image:
4971 if (m->m_type == sdp_media_audio) {
4975 if (m->m_type == sdp_media_video) {
4980 maxptime = dmaxptime;
4982 if (m->m_proto == sdp_proto_extended_srtp || m->m_proto == sdp_proto_extended_rtp) {
4987 if (m->m_proto_name && !strcasecmp(m->m_proto_name,
"UDP/TLS/RTP/SAVPF")) {
4991 if (m->m_proto_name && !strcasecmp(m->m_proto_name,
"UDP/RTP/AVPF")) {
4995 if (m->m_proto == sdp_proto_srtp || m->m_proto == sdp_proto_extended_srtp) {
4996 if (m->m_type == sdp_media_audio) {
4999 }
else if (m->m_proto == sdp_proto_rtp) {
5000 if (m->m_type == sdp_media_audio) {
5003 }
else if (m->m_proto == sdp_proto_udptl) {
5005 }
else if (m->m_proto == sdp_proto_msrp || m->m_proto == sdp_proto_msrps){
5009 if (got_msrp && m->m_type == sdp_media_message) {
5017 for (attr = m->m_attributes; attr; attr = attr->a_next) {
5019 if (!strcasecmp(attr->a_name,
"path") && attr->a_value) {
5022 }
else if (!strcasecmp(attr->a_name,
"accept-types") && attr->a_value) {
5025 }
else if (!strcasecmp(attr->a_name,
"accept-wrapped-types") && attr->a_value) {
5028 }
else if (!strcasecmp(attr->a_name,
"setup") && attr->a_value) {
5031 if (!strcmp(attr->a_value,
"passive")) {
5034 }
else if (!strcasecmp(attr->a_name,
"file-selector") && attr->a_value) {
5036 char *argv[4] = { 0 };
5045 for(i = 0; i<argc; i++) {
5047 if (
zstr(argv[i])) {
5051 if (!strncasecmp(argv[i],
"name:", 5)) {
5052 char *p = argv[i] + 5;
5053 int len = strlen(p);
5056 *(p + len - 1) =
'\0';
5060 }
else if (!strncasecmp(argv[i],
"type:", 5)) {
5063 if (!strncasecmp(argv[i],
"size:", 5)) {
5066 if (!strncasecmp(argv[i],
"hash:", 5)) {
5071 }
else if (!strcasecmp(attr->a_name,
"file-transfer-id") && attr->a_value) {
5073 }
else if (!strcasecmp(attr->a_name,
"file-disposition") && attr->a_value) {
5075 }
else if (!strcasecmp(attr->a_name,
"file-date") && attr->a_value) {
5077 }
else if (!strcasecmp(attr->a_name,
"file-icon") && attr->a_value) {
5079 }
else if (!strcasecmp(attr->a_name,
"file-range") && attr->a_value) {
5093 if (m->m_proto == sdp_proto_msrps) {
5101 "msrp%s://%s:%d/%s;tcp",
5112 if (got_udptl && m->m_type == sdp_media_image) {
5141 if (proceed) *proceed = 0;
5146 if (!strcasecmp(var,
"once")) {
5195 const char *err = NULL;
5224 msg->
from = __FILE__;
5242 fmatch ?
"IS" :
"IS NOT",
5248 }
else if (m->m_type == sdp_media_audio && m->m_port && got_audio && got_savp) {
5250 }
else if (m->m_type == sdp_media_audio && m->m_port && !got_audio) {
5256 memset(matches, 0,
sizeof(matches[0]) * MAX_MATCHES);
5257 memset(near_matches, 0,
sizeof(near_matches[0]) * MAX_MATCHES);
5259 audio_port = m->m_port;
5261 if (!sendonly && (m->m_mode == sdp_sendonly || m->m_mode == sdp_inactive)) {
5263 if (m->m_mode == sdp_inactive) {
5268 if (!sendonly && m->m_connections && m->m_connections->c_address && !strcmp(m->m_connections->c_address,
"0.0.0.0")) {
5276 switch(a_engine->
rmode) {
5292 for (attr = sdp->sdp_attributes; attr; attr = attr->a_next) {
5293 if (
zstr(attr->a_name)) {
5298 if (!strncasecmp(attr->a_name,
"ice", 3)) {
5300 }
else if (sendonly < 2 && !strcasecmp(attr->a_name,
"sendonly")) {
5303 }
else if (sendonly < 2 && !strcasecmp(attr->a_name,
"inactive")) {
5305 }
else if (!strcasecmp(attr->a_name,
"recvonly")) {
5323 }
else if (sendonly < 2 && !strcasecmp(attr->a_name,
"sendrecv")) {
5325 }
else if (!strcasecmp(attr->a_name,
"ptime")) {
5326 ptime = dptime = atoi(attr->a_value);
5327 }
else if (!strcasecmp(attr->a_name,
"maxptime")) {
5328 maxptime = dmaxptime = atoi(attr->a_value);
5332 if (sendonly == 2 && ice) {
5337 if (sendonly != 1 && recvonly != 1 && inactive != 1) {
5349 }
else if (sendonly) {
5351 }
else if (recvonly) {
5367 for (attr = m->m_attributes; attr; attr = attr->a_next) {
5369 if (!strcasecmp(attr->a_name,
"fingerprint") && !
zstr(attr->a_value)) {
5377 for (attr = m->m_attributes; attr; attr = attr->a_next) {
5378 if (!strcasecmp(attr->a_name,
"rtcp-mux")) {
5384 }
else if (!strcasecmp(attr->a_name,
"ice-ufrag")) {
5389 if (!got_rtcp_mux) {
5393 for (attr = m->m_attributes; attr; attr = attr->a_next) {
5394 if (!strcasecmp(attr->a_name,
"rtcp") && attr->a_value && !skip_rtcp) {
5402 }
else if (!strcasecmp(attr->a_name,
"ptime") && attr->a_value) {
5403 ptime = atoi(attr->a_value);
5404 }
else if (!strcasecmp(attr->a_name,
"maxptime") && attr->a_value) {
5405 maxptime = atoi(attr->a_value);
5406 }
else if (got_crypto < 1 && !strcasecmp(attr->a_name,
"crypto") && !
zstr(attr->a_value)) {
5411 if (m->m_proto != sdp_proto_srtp && !got_webrtc) {
5418 crypto = attr->a_value;
5419 crypto_tag = atoi(crypto);
5426 if (got_crypto == -1 && got_savp && !got_avp && !got_webrtc) {
5432 connection = sdp->sdp_connection;
5433 if (m->m_connections) {
5434 connection = m->m_connections;
5445 for (map = m->m_rtpmaps; map; map = map->rm_next) {
5447 const char *rm_encoding;
5448 uint32_t map_bit_rate = 0;
5450 int map_channels = map->rm_params ? atoi(map->rm_params) : 1;
5452 if (!(rm_encoding = map->rm_encoding)) {
5457 if (!strcasecmp(rm_encoding,
"telephone-event")) {
5460 best_te_rate = map->rm_rate;
5491 if (maxptime && (!codec_ms || codec_ms > maxptime)) {
5492 codec_ms = maxptime;
5501 if (!ptime && !strcasecmp(map->rm_encoding,
"g723")) {
5505 remote_codec_rate = map->rm_rate;
5506 fmtp_remote_codec_rate = 0;
5507 memset(&codec_fmtp, 0,
sizeof(codec_fmtp));
5509 if (
zstr(map->rm_fmtp)) {
5510 if (!strcasecmp(map->rm_encoding,
"ilbc")) {
5512 map_bit_rate = 13330;
5513 }
else if (!strcasecmp(map->rm_encoding,
"isac")) {
5515 map_bit_rate = 32000;
5530 }
else if (!strcasecmp(map->rm_encoding,
"opus")) {
5550 rm_encoding, map->rm_pt, (
int) remote_codec_rate, codec_ms, map_bit_rate, map_channels,
5553 match = (map->rm_pt == imp->
ianacode) ? 1 : 0;
5555 match = (!strcasecmp(rm_encoding, imp->
iananame) &&
5556 ((map->rm_pt < 96 && imp->
ianacode < 96) || (map->rm_pt > 95 && imp->
ianacode > 95)) &&
5558 if (fmtp_remote_codec_rate) {
5559 remote_codec_rate = fmtp_remote_codec_rate;
5563 if (match && bit_rate && map_bit_rate && map_bit_rate != bit_rate && strcasecmp(map->rm_encoding,
"ilbc") &&
5564 strcasecmp(map->rm_encoding,
"isac")) {
5569 if (match && remote_codec_rate && codec_rate && remote_codec_rate != codec_rate && (!strcasecmp(map->rm_encoding,
"pcma") ||
5570 !strcasecmp(map->rm_encoding,
"pcmu"))) {
5579 "Bah HUMBUG! Sticking with %s@%uh@%ui\n",
5581 }
else if ((ptime && codec_ms && codec_ms * 1000 != imp->
microseconds_per_packet) || remote_codec_rate != codec_rate) {
5585 if (nm_idx >= MAX_MATCHES) {
5587 "Audio Codec Compare [%s:%d:%u:%u:%d:%u:%d] was not saved as a near-match. Too many. Ignoring.\n",
5593 "Audio Codec Compare [%s:%d:%u:%d:%u:%d] is saved as a near-match\n",
5597 near_matches[nm_idx].
rate = remote_codec_rate;
5598 near_matches[nm_idx].
imp =
imp;
5599 near_matches[nm_idx].
map =
map;
5606 matches[m_idx].
rate = codec_rate;
5607 matches[m_idx].
imp =
imp;
5608 matches[m_idx].
map =
map;
5612 "Audio Codec Compare [%s:%d:%u:%d:%u:%d] ++++ is saved as a match\n",
5615 if (m_idx >= MAX_MATCHES) {
5623 if (m_idx >= MAX_MATCHES) {
5635 if (!m_idx && nm_idx) {
5638 for(j = 0; j < nm_idx; j++) {
5646 near_rate = near_matches[j].
rate;
5647 near_match = near_matches[j].
imp;
5648 near_map = near_matches[j].
map;
5650 switch_snprintf(tmp,
sizeof(tmp),
"%s@%uh@%ui%dc", near_match->iananame, near_rate ? near_rate : near_match->samples_per_second,
5651 codec_ms, near_match->number_of_channels);
5668 matches[m_idx].
rate = near_rate;
5669 matches[m_idx].
imp = timp;
5670 matches[m_idx].
map = near_map;
5682 greedy_sort(smh, matches, m_idx, codec_array, total_codecs);
5691 matches[j].map->rm_encoding,
5693 matches[j].
map->rm_fmtp,
5695 matches[j].
map->rm_pt,
5701 mimp = matches[j].
imp;
5702 mmap = matches[j].
map;
5722 pmap->
channels = mmap->rm_params ? atoi(mmap->rm_params) : 1;
5724 if (!strcasecmp((
char *) mmap->rm_encoding,
"opus")) {
5731 if (!
zstr((
char *) mmap->rm_fmtp) &&
switch_stristr(
"stereo=1", (
char *) mmap->rm_fmtp)) {
5733 if (!allow_channels || allow_channels >= 2) {
5772 if (pmap->
pt > pl) {
5810 for (map = m->m_rtpmaps; map; map = map->rm_next) {
5811 const char *rm_encoding;
5813 if (!(rm_encoding = map->rm_encoding)) {
5817 if (!strcasecmp(rm_encoding,
"telephone-event")) {
5820 best_te_rate = map->rm_rate;
5830 cng_rate = map->rm_rate;
5846 best_te_rate = 8000;
5851 "No 2833 in SDP. Liberal DTMF mode adding %d as telephone-event.\n", smh->
mparams->
te);
5897 }
else if (!got_text && m->m_type == sdp_media_text && m->m_port) {
5903 connection = sdp->sdp_connection;
5904 if (m->m_connections) {
5905 connection = m->m_connections;
5920 for (map = m->m_rtpmaps; map; map = map->rm_next) {
5945 if (!strcasecmp(map->rm_encoding,
"red")) {
5954 for (attr = m->m_attributes; attr; attr = attr->a_next) {
5955 if (!strcasecmp(attr->a_name,
"rtcp") && attr->a_value) {
5958 }
else if (!got_text_crypto && !strcasecmp(attr->a_name,
"crypto") && !
zstr(attr->a_value)) {
5963 if (m->m_proto != sdp_proto_srtp && !got_webrtc) {
5970 crypto = attr->a_value;
5971 crypto_tag = atoi(crypto);
5974 "rtp_has_text_crypto",
5997 }
else if (m->m_type == sdp_media_video) {
5999 const char *rm_encoding;
6002 const char *inherit_video_fmtp = NULL;
6007 sdp_bandwidth_t *bw;
6010 for (bw = m->m_bandwidths; bw; bw = bw->b_next) {
6011 if (bw->b_modifier == sdp_bw_as && !tias) {
6012 v_engine->
sdp_bw = bw->b_value;
6013 }
else if (bw->b_modifier == sdp_bw_tias) {
6015 v_engine->
sdp_bw = bw->b_value / 1024;
6019 switch(v_engine->
rmode) {
6043 memset(matches, 0,
sizeof(matches[0]) * MAX_MATCHES);
6044 memset(near_matches, 0,
sizeof(near_matches[0]) * MAX_MATCHES);
6050 connection = sdp->sdp_connection;
6051 if (m->m_connections) {
6052 connection = m->m_connections;
6063 skip_video_rtcp = 0;
6064 got_video_rtcp_mux = 0;
6065 for (attr = m->m_attributes; attr; attr = attr->a_next) {
6066 if (!strcasecmp(attr->a_name,
"rtcp-mux")) {
6067 got_video_rtcp_mux = 1;
6068 skip_video_rtcp = 1;
6069 }
else if (!strcasecmp(attr->a_name,
"ice-ufrag")) {
6070 skip_video_rtcp = 1;
6074 if (!got_video_rtcp_mux) {
6078 for (attr = m->m_attributes; attr; attr = attr->a_next) {
6079 if (!strcasecmp(attr->a_name,
"framerate") && attr->a_value) {
6081 }
else if (!strcasecmp(attr->a_name,
"rtcp-fb")) {
6082 if (!
zstr(attr->a_value)) {
6099 rtcp_auto_video = 1;
6102 }
else if (!strcasecmp(attr->a_name,
"rtcp") && attr->a_value && !skip_video_rtcp) {
6109 }
else if (!got_video_crypto && !strcasecmp(attr->a_name,
"crypto") && !
zstr(attr->a_value)) {
6114 if (m->m_proto != sdp_proto_srtp && !got_webrtc) {
6121 crypto = attr->a_value;
6122 crypto_tag = atoi(crypto);
6125 "rtp_has_video_crypto",
6138 for (map = m->m_rtpmaps; map; map = map->rm_next) {
6141 for (attr = m->m_attributes; attr; attr = attr->a_next) {
6142 if (!strcasecmp(attr->a_name,
"fingerprint") && !
zstr(attr->a_value)) {
6143 got_video_crypto = 1;
6148 if (!(rm_encoding = map->rm_encoding)) {
6152 for (i = 0; i < total_codecs; i++) {
6167 vmatch = (map->rm_pt == imp->
ianacode) ? 1 : 0;
6169 vmatch = strcasecmp(rm_encoding, imp->
iananame) ? 0 : 1;
6174 vmatch = !strcasecmp(smh->
fmtps[i], map->rm_fmtp);
6177 if (vmatch && vmatch_pt) {
6181 int opt = atoi(other_pt);
6182 if (map->rm_pt != opt) {
6193 matches[m_idx].
imp =
imp;
6194 matches[m_idx].
map =
map;
6201 if (m_idx >= MAX_MATCHES) {
6209 if (m_idx >= MAX_MATCHES) {
6214 if (consider_video_fmtp && (!m_idx || almost_vmatch)) {
6218 consider_video_fmtp = 0;
6222 if (vmatch_pt && !m_idx) {
6240 greedy_sort(smh, matches, m_idx, codec_array, total_codecs);
6250 matches[j].map->rm_encoding,
6252 consider_video_fmtp ? matches[j].
map->rm_fmtp : NULL,
6254 matches[j].
map->rm_pt,
6268 mimp = matches[j].
imp;
6269 map = matches[j].
map;
6310 video_port = m->m_port;
6316 if (rtcp_auto_audio || rtcp_auto_video) {
6317 if (rtcp_auto_audio && !skip_rtcp && !got_audio_rtcp && audio_port) {
6325 if (rtcp_auto_video && !skip_video_rtcp && !got_video_rtcp && video_port) {
6367 if (v_engine->
fir) {
6373 if (v_engine->
pli) {
6379 if (v_engine->
nack) {
6385 if (v_engine->
tmmbr) {
6426 sdp_parser_free(parser);
6434 return match || vmatch || tmatch || fmatch;
6488 const char *msg =
"hold";
6503 msg =
"hold-private";
6534 stream =
"local_stream://moh";
6539 if (!strcasecmp(stream,
"indicate_hold")) {
6571 int bypass_after_hold_a = 0;
6572 int bypass_after_hold_b = 0;
6574 if (media_on_hold_a) {
6700 uint32_t frames = 0, frame_ms = 0;
6701 uint32_t
fps, width, height;
6712 if (!width) width = 352;
6713 if (!height) height = 288;
6726 if (fps < 15) fps = 15;
6727 frame_ms = (uint32_t) 1000 / fps;
6728 if (frame_ms <= 0) frame_ms = 66;
6729 frames = (uint32_t) ms / frame_ms;
6732 for (i = 0; i < frames; i++) {
6747 unsigned char *
buf = NULL;
6757 int last_w = 0, last_h = 0, kps = 0;
6798 }
else if (video_globals.
fps) {
6799 fps = video_globals.
fps;
6806 int min = 0, max = 10000000;
6813 if (min < 0) min = 0;
6818 if (max < 0) max = 10000000;
6821 if (min && kps < min) kps = min;
6822 if (max != 10000000 && kps > max) kps = max;
6849 if (!kps && fr.
img && (last_w != fr.
img->
d_w || last_h != fr.
img->
d_h)) {
6866 last_frame = fr.
img;
6883 fr.
img = last_frame;
6885 for (x = 0; x < (int)(fps_data.
fps / 2); x++) {
7134 for (bp = session->
bugs; bp; bp = bp->
next) {
7458 uint32_t loops = 0, xloops = 0;
7461 unsigned char *
buf = NULL;
7466 int blank_enabled = 1;
7601 }
else if (blank_img) {
7778 #define RA_PTR_LEN 512 7786 char *p, *ip_ptr = NULL, *port_ptr = NULL, *vid_port_ptr = NULL, *text_port_ptr = NULL, *pe;
7803 if (
zstr(sdp_str)) {
7807 if (
zstr(sdp_str)) {
7822 if (tmp && atoi(tmp)) {
7828 vid_port_ptr = p + 8;
7832 text_port_ptr = p + 7;
7835 if (!(ip_ptr && port_ptr)) {
7842 while (x <
sizeof(rip) - 1 && p && *p && ((*p >=
'0' && *p <=
'9') || *p ==
'.' || *p ==
':' || (*p >=
'a' && *p <=
'f') || (*p >=
'A' && *p <=
'F'))) {
7853 while (x <
sizeof(rp) - 1 && p && *p && (*p >=
'0' && *p <=
'9')) {
7865 while (x <
sizeof(rvp) - 1 && p && *p && (*p >=
'0' && *p <=
'9')) {
7874 if (text_port_ptr) {
7877 while (x <
sizeof(rtp) - 1 && p && *p && (*p >=
'0' && *p <=
'9')) {
7886 if (!(*rip && *rp)) {
7916 const char *rport = NULL;
7919 if (!remote_rtcp_port) {
7955 const char *rport = NULL;
7958 if (!remote_rtcp_port) {
7989 const char *rport = NULL;
7996 }
else if (remote_host && ( (strcmp(remote_host,
"0.0.0.0") == 0) ||
8000 "Remote address changed from [%s] to [%s]. Ignoring...\n",
8054 char *stun_ip = NULL;
8068 if (!strncasecmp(sourceip,
"host:", 5)) {
8070 }
else if (!strncasecmp(sourceip,
"stun:", 5)) {
8073 stun_ip = strdup(sourceip + 5);
8075 if ((p = strchr(stun_ip,
':'))) {
8079 if (iport > 0 && iport < 0xFFFF) {
8084 if (
zstr(stun_ip)) {
8089 for (x = 0; x < 5; x++) {
8107 if (myport == *port && !strcmp(*ip, smh->
mparams->
rtpip)) {
8115 *ip = (
char *) sourceip;
8152 const char *use_ip = NULL;
8156 char vname[128] =
"";
8168 if (!lookup_rtpip) {
8220 use_ip = lookup_rtpip;
8319 a_engine->
mh.
up = 0;
8330 v_engine->
mh.
up = 0;
8352 t_engine->
mh.
up = 0;
8510 #ifdef HAVE_OPENSSL_DTLSv1_2_method 8511 uint8_t want_DTLSv1_2 = 1;
8513 uint8_t want_DTLSv1_2 = 0;
8514 #endif // HAVE_OPENSSL_DTLSv1_2_method 8544 const char *err = NULL;
8545 const char *val = NULL;
8549 char *timer_name = NULL;
8553 int is_reinvite = 0;
8555 #ifdef HAVE_OPENSSL_DTLSv1_2_method 8556 uint8_t want_DTLSv1_2 = 1;
8558 uint8_t want_DTLSv1_2 = 0;
8592 if (want_DTLSv1_2) {
8659 #if __BYTE_ORDER == __LITTLE_ENDIAN 8711 const char *rport = NULL;
8714 if (!remote_rtcp_port) {
8740 if (session && a_engine) {
8750 memset(flags, 0,
sizeof(flags));
8762 "PROXY AUDIO RTP [%s] %s:%d->%s:%d codec: %u ms: %d\n",
8777 timer_name = (
char *) var;
8813 uint32_t ssrc_ul = (uint32_t) strtoul(ssrc, NULL, 10);
8815 a_engine->
ssrc = ssrc_ul;
8864 if ((vad_in && inb) || (vad_out && !inb)) {
8901 if (!remote_rtcp_port && rport) {
8905 if (!strcasecmp(val,
"passthru")) {
8909 int interval = atoi(val);
8910 if (interval < 100 || interval > 500000) {
8912 "Invalid rtcp interval spec [%d] must be between 100 and 500000\n", interval);
8980 "rtp_timeout_sec deprecated use media_timeout variable.\n");
8989 "rtp_hold_timeout_sec deprecated use media_hold_timeout variable.\n");
9030 int delayi = atoi(val);
9031 if (delayi < 0) delayi = 0;
9104 const char *rport = NULL;
9109 if (!remote_rtcp_port) {
9135 memset(flags, 0,
sizeof(flags));
9145 "PROXY TEXT RTP [%s] %s:%d->%s:%d codec: %u ms: %d\n",
9168 memset(flags, 0,
sizeof(flags));
9211 if (!t_engine->
tf) {
9222 uint32_t ssrc_ul = (uint32_t) strtoul(ssrc, NULL, 10);
9224 t_engine->
ssrc = ssrc_ul;
9264 if (!strcasecmp(val,
"passthru")) {
9268 int interval = atoi(val);
9269 if (interval < 100 || interval > 500000) {
9271 "Invalid rtcp interval spec [%d] must be between 100 and 500000\n", interval);
9275 "Activating TEXT RTCP PORT %d interval %d mux %d\n", remote_port, interval, t_engine->
rtcp_mux);
9406 const char *rport = NULL;
9411 if (!remote_rtcp_port) {
9437 memset(flags, 0,
sizeof(flags));
9447 "PROXY VIDEO RTP [%s] %s:%d->%s:%d codec: %u ms: %d\n",
9470 memset(flags, 0,
sizeof(flags));
9489 if (v_engine->
fir) {
9493 if (v_engine->
pli) {
9501 if (v_engine->
tmmbr) {
9527 if (v_engine->
fir) {
9531 if (v_engine->
pli) {
9541 uint32_t ssrc_ul = (uint32_t) strtoul(ssrc, NULL, 10);
9543 v_engine->
ssrc = ssrc_ul;
9585 if (!strcasecmp(val,
"passthru")) {
9589 int interval = atoi(val);
9590 if (interval < 100 || interval > 500000) {
9592 "Invalid rtcp interval spec [%d] must be between 100 and 500000\n", interval);
9596 "Activating VIDEO RTCP PORT %d interval %d mux %d\n", remote_port, interval, v_engine->
rtcp_mux);
9691 if (session && v_engine) {
9714 return "UDP/TLS/RTP/SAVPF";
9760 int cur_ptime,
const char *append_audio,
const char *sr,
int use_cng,
int cng_type,
switch_event_t *map,
int secure,
9765 int already_did[128] = { 0 };
9766 int ptime = 0, noptime = 0;
9769 int include_external;
9797 switch_snprintf(buf + strlen(buf), buflen - strlen(buf),
"m=audio %d %s", port,
9807 if (!strcasecmp(imp->
iananame,
"ilbc") || !strcasecmp(imp->
iananame,
"isac") ) {
9821 if (this_ptime != cur_ptime) {
9852 if (pmap->
pt >= 128 || already_did[pmap->
pt]) {
9856 if (!strncasecmp(pmap->
iananame,
"telephone-event", 15)) {
9858 already_did[pmap->
pt] = 1;
9885 memset(already_did, 0,
sizeof(already_did));
9890 char *fmtp = imp->
fmtp;
9897 if (!strcasecmp(imp->
iananame,
"ilbc") || !strcasecmp(imp->
iananame,
"isac")) {
9907 if (this_ptime != cur_ptime) {
9930 if (smh->
fmtps[i]) {
9931 fmtp = smh->
fmtps[i];
9958 if (!strncasecmp(pmap->
iananame,
"telephone-event", 15)) {
9959 switch_snprintf(buf + strlen(buf), buflen - strlen(buf),
"a=rtpmap:%d telephone-event/%d\r\n",
9969 switch_snprintf(buf + strlen(buf), buflen - strlen(buf),
"a=rtpmap:%d telephone-event/%d\r\n",
9973 switch_snprintf(buf + strlen(buf), buflen - strlen(buf),
"a=rtpmap:%d telephone-event/%d\r\na=fmtp:%d 0-%d\r\n",
9987 switch_snprintf(buf + strlen(buf), buflen - strlen(buf),
"a=rtcp-mux\r\n");
9988 switch_snprintf(buf + strlen(buf), buflen - strlen(buf),
"a=rtcp:%d IN %s %s\r\n", port, family, ip);
9990 switch_snprintf(buf + strlen(buf), buflen - strlen(buf),
"a=rtcp:%d IN %s %s\r\n", port + 1, family, ip);
10000 uint32_t c1 = (1<<24)*126 + (1<<8)*65535 + (1<<0)*(256 - 1);
10001 uint32_t c2 = c1 - 1;
10013 ice_out = &a_engine->
ice_out;
10016 switch_snprintf(buf + strlen(buf), buflen - strlen(buf),
"a=ssrc:%u msid:%s a0\r\n", a_engine->
ssrc, smh->
msid);
10017 switch_snprintf(buf + strlen(buf), buflen - strlen(buf),
"a=ssrc:%u mslabel:%s\r\n", a_engine->
ssrc, smh->
msid);
10018 switch_snprintf(buf + strlen(buf), buflen - strlen(buf),
"a=ssrc:%u label:%sa0\r\n", a_engine->
ssrc, smh->
msid);
10021 switch_snprintf(buf + strlen(buf), buflen - strlen(buf),
"a=ice-ufrag:%s\r\n", ice_out->
ufrag);
10022 switch_snprintf(buf + strlen(buf), buflen - strlen(buf),
"a=ice-pwd:%s\r\n", ice_out->
pwd);
10025 switch_snprintf(buf + strlen(buf), buflen - strlen(buf),
"a=candidate:%s 1 %s %u %s %d typ host generation 0\r\n",
10031 switch_snprintf(buf + strlen(buf), buflen - strlen(buf),
"a=candidate:%s 1 %s %u %s %d typ host generation 0\r\n",
10041 switch_snprintf(buf + strlen(buf), buflen - strlen(buf),
"a=candidate:%s 1 %s %u %s %d typ srflx raddr %s rport %d generation 0\r\n",
10051 switch_snprintf(buf + strlen(buf), buflen - strlen(buf),
"a=candidate:%s 2 %s %u %s %d typ host generation 0\r\n",
10057 switch_snprintf(buf + strlen(buf), buflen - strlen(buf),
"a=candidate:%s 2 %s %u %s %d typ host generation 0\r\n",
10067 switch_snprintf(buf + strlen(buf), buflen - strlen(buf),
"a=candidate:%s 2 %s %u %s %d typ srflx raddr %s rport %d generation 0\r\n",
10078 switch_snprintf(buf + strlen(buf), buflen - strlen(buf),
"a=ice-options:google-ice\r\n");
10106 switch_snprintf(buf + strlen(buf), buflen - strlen(buf),
"a=silenceSupp:off - - - -\r\n");
10110 if (append_audio) {
10111 switch_snprintf(buf + strlen(buf), buflen - strlen(buf),
"%s%s", append_audio,
end_of(append_audio) ==
'\n' ?
"" :
"\r\n");
10118 if (!noptime && cur_ptime) {
10119 switch_snprintf(buf + strlen(buf), buflen - strlen(buf),
"a=ptime:%d\r\n", cur_ptime);
10123 switch_snprintf(buf + strlen(buf), buflen - strlen(buf),
"a=%s\r\n", sr);
10140 if (!strcasecmp(val,
"rfc2833")) {
10142 }
else if (!strcasecmp(val,
"info")) {
10144 }
else if (!strcasecmp(val,
"none")) {
10154 sdp_parser_t *parser = NULL;
10155 sdp_session_t *sdp;
10157 if (!(parser = sdp_parse(NULL, r_sdp, (
int) strlen(r_sdp), 0))) {
10161 if (!(sdp = sdp_session(parser))) {
10162 sdp_parser_free(parser);
10169 for (m = sdp->sdp_media; m; m = m->m_next) {
10170 if (m->m_proto == sdp_proto_rtp) {
10173 for (map = m->m_rtpmaps; map; map = map->rm_next) {
10174 if (map->rm_encoding) {
10176 char key[128] =
"";
10179 if (map->rm_fmtp) {
10180 if ((br = strstr(map->rm_fmtp,
"bitrate="))) {
10195 if (map->rm_fmtp) {
10203 sdp_parser_free(parser);
10229 switch_snprintf(buf + strlen(buf), buflen - strlen(buf),
"a=rtcp-fb:%d ccm fir\r\n", pt);
10233 switch_snprintf(buf + strlen(buf), buflen - strlen(buf),
"a=rtcp-fb:%d ccm tmmbr\r\n", pt);
10237 switch_snprintf(buf + strlen(buf), buflen - strlen(buf),
"a=rtcp-fb:%d nack\r\n", pt);
10241 switch_snprintf(buf + strlen(buf), buflen - strlen(buf),
"a=rtcp-fb:%d nack pli\r\n", pt);
10247 #define SDPBUFLEN 65536 10253 uint32_t v_port, t_port;
10256 const char *family;
10261 char srbuf[128] =
"";
10262 const char *var_val;
10263 const char *username;
10264 const char *fmtp_out;
10278 int bw = 256, i = 0;
10279 uint8_t fir = 0, nack = 0, pli = 0, tmmbr = 0, has_vid = 0;
10280 const char *use_rtcp_mux = NULL;
10281 int include_external;
10387 if (smh->
rates[j] == 0) {
10418 char *orig_fmtp = NULL;
10429 if (orig_session &&
10440 if (!
zstr(orig_fmtp)) {
10481 if (orig_session) {
10487 if (fmtp_out_var) {
10488 fmtp_out = fmtp_out_var;
10497 if (!force && !ip &&
zstr(sr)
10552 if (!strcasecmp(sr,
"sendonly") || !strcasecmp(sr,
"recvonly") || !strcasecmp(sr,
"sendrecv") || !strcasecmp(sr,
"inactive")) {
10585 family = strchr(ip,
':') ?
"IP6" :
"IP4";
10588 "o=%s %010u %010u IN %s %s\r\n" 10681 switch_snprintf(buf + strlen(buf),
SDPBUFLEN - strlen(buf),
"a=rtpmap:%d telephone-event/%d\r\na=fmtp:%d 0-%d\r\n",
10696 if (append_audio) {
10728 char tmp1[11] =
"";
10729 char tmp2[11] =
"";
10730 char tmp3[11] =
"";
10731 uint32_t c1 = (1<<24)*126 + (1<<8)*65535 + (1<<0)*(256 - 1);
10732 uint32_t c2 = c1 - 1;
10733 uint32_t c3 = c1 - 2;
10734 uint32_t c4 = c1 - 3;
10743 ice_out = &a_engine->
ice_out;
10750 switch_snprintf(buf + strlen(buf),
SDPBUFLEN - strlen(buf),
"a=candidate:%s 1 %s %u %s %d typ host generation 0\r\n",
10756 switch_snprintf(buf + strlen(buf),
SDPBUFLEN - strlen(buf),
"a=candidate:%s 1 %s %u %s %d typ host generation 0\r\n",
10766 switch_snprintf(buf + strlen(buf),
SDPBUFLEN - strlen(buf),
"a=candidate:%s 1 %s %u %s %d typ srflx raddr %s rport %d generation 0\r\n",
10776 switch_snprintf(buf + strlen(buf),
SDPBUFLEN - strlen(buf),
"a=candidate:%s 2 %s %u %s %d typ host generation 0\r\n",
10782 switch_snprintf(buf + strlen(buf),
SDPBUFLEN - strlen(buf),
"a=candidate:%s 2 %s %u %s %d typ host generation 0\r\n",
10794 switch_snprintf(buf + strlen(buf),
SDPBUFLEN - strlen(buf),
"a=candidate:%s 2 %s %u %s %d typ srflx raddr %s rport %d generation 0\r\n",
10827 int cur_ptime = 0, this_ptime = 0, cng_type = 0;
10847 generate_m(session, buf,
SDPBUFLEN, port, family, ip, 0, append_audio, sr, use_cng, cng_type, map, 1, sdp_type);
10848 bp = (buf + strlen(buf));
10857 generate_m(session, bp,
SDPBUFLEN - strlen(buf), port, family, ip, 0, append_audio, sr, use_cng, cng_type, map, 0, sdp_type);
10871 if (!strcasecmp(imp->
iananame,
"ilbc") || !strcasecmp(imp->
iananame,
"isac")) {
10875 if (cur_ptime != this_ptime) {
10879 cur_ptime = this_ptime;
10883 generate_m(session, bp,
SDPBUFLEN - strlen(buf), port, family, ip, cur_ptime, append_audio, sr, use_cng, cng_type, map, 1, sdp_type);
10884 bp = (buf + strlen(buf));
10896 generate_m(session, bp,
SDPBUFLEN - strlen(buf), port, family, ip, cur_ptime, append_audio, sr, use_cng, cng_type, map, 0, sdp_type);
10959 for (loops = 0; loops < 2; loops++) {
10993 int already_did[128] = { 0 };
11078 pass_fmtp = ov_fmtp;
11107 if (append_video) {
11112 int already_did[128] = { 0 };
11129 if (ianacode < 128) {
11130 if (already_did[ianacode]) {
11133 already_did[ianacode] = 1;
11150 if (channels > 1) {
11160 if (!
zstr(ov_fmtp)) {
11161 fmtp = (
char *) ov_fmtp;
11169 fmtp = smh->
fmtp[i];
11170 }
else if (smh->
fmtps[i]) {
11171 fmtp = smh->
fmtps[i];
11176 if (
zstr(fmtp)) fmtp = (
char *) pass_fmtp;
11179 if (!
zstr(fmtp) && strcasecmp(fmtp,
"_blank_")) {
11232 v_engine->
nack || nack, v_engine->
pli || pli, v_engine->
tmmbr || tmmbr);
11245 int already_did[128] = { 0 };
11274 char tmp1[11] =
"";
11275 char tmp2[11] =
"";
11276 char tmp3[11] =
"";
11277 uint32_t c1 = (1<<24)*126 + (1<<8)*65535 + (1<<0)*(256 - 1);
11278 uint32_t c2 = c1 - 1;
11279 uint32_t c3 = c1 - 2;
11280 uint32_t c4 = c1 - 3;
11289 ice_out = &v_engine->
ice_out;
11303 switch_snprintf(buf + strlen(buf),
SDPBUFLEN - strlen(buf),
"a=candidate:%s 1 %s %u %s %d typ host generation 0\r\n",
11309 switch_snprintf(buf + strlen(buf),
SDPBUFLEN - strlen(buf),
"a=candidate:%s 1 %s %u %s %d typ host generation 0\r\n",
11319 switch_snprintf(buf + strlen(buf),
SDPBUFLEN - strlen(buf),
"a=candidate:%s 1 %s %u %s %d typ srflx raddr %s rport %d generation 0\r\n",
11329 switch_snprintf(buf + strlen(buf),
SDPBUFLEN - strlen(buf),
"a=candidate:%s 2 %s %u %s %d typ host generation 0\r\n",
11335 switch_snprintf(buf + strlen(buf),
SDPBUFLEN - strlen(buf),
"a=candidate:%s 2 %s %u %s %d typ host generation 0\r\n",
11346 switch_snprintf(buf + strlen(buf),
SDPBUFLEN - strlen(buf),
"a=candidate:%s 2 %s %u %s %d typ srflx generation 0\r\n",
11400 if (want_msrp || want_msrps) {
11425 "msrp%s://%s:%d/%s;tcp",
11426 msrp_session->
secure ?
"s" :
"",
11431 "m=message %d TCP/%sMSRP *\r\n" 11433 "a=accept-types:%s\r\n" 11434 "a=accept-wrapped-types:%s\r\n" 11437 msrp_session->
secure ?
"TLS/" :
"",
11441 msrp_session->
active ?
"active" :
"passive");
11448 msrp_session->
active = 1;
11454 "msrp%s://%s:%d/%s;tcp",
11455 msrp_session->
secure ?
"s" :
"",
11460 "m=message %d TCP/%sMSRP *\r\n" 11462 "a=accept-types:message/cpim text/* application/im-iscomposing+xml\r\n" 11463 "a=accept-wrapped-types:*\r\n" 11466 msrp_session->
secure ?
"TLS/" :
"",
11468 msrp_session->
active ?
"active" :
"passive");
11470 if (!
zstr(file_selector)) {
11472 "a=sendonly\r\na=file-selector:%s\r\n", file_selector);
11539 for (loops = 0; loops < 2; loops++) {
11582 if (!strcasecmp(pmap->
iananame,
"t140")) {
11586 if (!strcasecmp(pmap->
iananame,
"red")) {
11634 char tmp1[11] =
"";
11635 char tmp2[11] =
"";
11636 uint32_t c1 = (1<<24)*126 + (1<<8)*65535 + (1<<0)*(256 - 1);
11637 uint32_t c2 = c1 - 1;
11638 uint32_t c3 = c1 - 2;
11639 uint32_t c4 = c1 - 3;
11646 ice_out = &t_engine->
ice_out;
11660 switch_snprintf(buf + strlen(buf),
SDPBUFLEN - strlen(buf),
"a=candidate:%s 1 %s %u %s %d typ host generation 0\r\n",
11669 switch_snprintf(buf + strlen(buf),
SDPBUFLEN - strlen(buf),
"a=candidate:%s 1 %s %u %s %d typ srflx raddr %s rport %d generation 0\r\n",
11679 switch_snprintf(buf + strlen(buf),
SDPBUFLEN - strlen(buf),
"a=candidate:%s 2 %s %u %s %d typ host generation 0\r\n",
11689 switch_snprintf(buf + strlen(buf),
SDPBUFLEN - strlen(buf),
"a=candidate:%s 2 %s %u %s %d typ srflx generation 0\r\n",
11749 const char *sdp_str;
11762 sdp_parser_t *parser;
11763 sdp_session_t *sdp;
11765 sdp_connection_t *connection;
11767 if ((parser = sdp_parse(NULL, sdp_str, (
int) strlen(sdp_str), 0))) {
11768 if ((sdp = sdp_session(parser))) {
11769 for (m = sdp->sdp_media; m; m = m->m_next) {
11770 if (m->m_type != sdp_media_audio || !m->m_port) {
11774 connection = sdp->sdp_connection;
11775 if (m->m_connections) {
11776 connection = m->m_connections;
11788 sdp_parser_free(parser);
11798 for (x = 0; x < smh->
rej_idx; x++) {
11810 char buf[2048] =
"";
11811 char max_buf[128] =
"";
11812 char max_data[128] =
"";
11815 const char *family =
"IP4";
11816 const char *username;
11817 const char *bit_removal_on =
"a=T38FaxFillBitRemoval\r\n";
11818 const char *bit_removal_off =
"";
11820 const char *mmr_on =
"a=T38FaxTranscodingMMR\r\n";
11821 const char *mmr_off =
"";
11823 const char *jbig_on =
"a=T38FaxTranscodingJBIG\r\n";
11824 const char *jbig_off =
"";
11826 int broken_boolean;
11883 family = strchr(ip,
':') ?
"IP6" :
"IP4";
11888 "o=%s %010u %010u IN %s %s\r\n" 11889 "s=%s\r\n" "c=IN %s %s\r\n" "t=0 0\r\n", username, smh->
owner_id, smh->
session_id, family, ip, username, family, ip);
11902 if (broken_boolean) {
11903 bit_removal_on =
"a=T38FaxFillBitRemoval:1\r\n";
11904 bit_removal_off =
"a=T38FaxFillBitRemoval:0\r\n";
11906 mmr_on =
"a=T38FaxTranscodingMMR:1\r\n";
11907 mmr_off =
"a=T38FaxTranscodingMMR:0\r\n";
11909 jbig_on =
"a=T38FaxTranscodingJBIG:1\r\n";
11910 jbig_off =
"a=T38FaxTranscodingJBIG:0\r\n";
11916 "m=audio 0 RTP/AVP 0\r\n");
11920 "m=image %d udptl t38\r\n" 11921 "a=T38FaxVersion:%d\r\n" 11922 "a=T38MaxBitRate:%d\r\n" 11926 "a=T38FaxRateManagement:%s\r\n" 11929 "a=T38FaxUdpEC:%s\r\n",
11947 switch_snprintf(buf + strlen(buf),
sizeof(buf) - strlen(buf),
"m=audio 0 RTP/AVP 19\r\n");
11965 char *p, *q, *pe, *qe;
11966 int has_video = 0, has_audio = 0, has_text = 0, has_ip = 0;
11967 char port_buf[25] =
"";
11968 char vport_buf[25] =
"";
11969 char tport_buf[25] =
"";
12033 pe = p + strlen(p);
12048 if (a_engine->
local_sdp_ip && !strncmp(
"c=IN IP", p, 7)) {
12052 memcpy(q, strchr(a_engine->
adv_sdp_ip,
':') ?
"6 " :
"4 ", 2);
12055 snprintf(q, qe - q,
"%s", a_engine->
adv_sdp_ip);
12058 while (p && *p && ((*p >=
'0' && *p <=
'9') || *p ==
'.' || *p ==
':' || (*p >=
'A' && *p <=
'F') || (*p >=
'a' && *p <=
'f'))) {
12068 }
else if (!strncmp(
"o=", p, 2)) {
12069 char *oe = strchr(p,
'\n');
12073 const char *family =
"IP4";
12074 char o_line[1024] =
"";
12085 family = strchr(smh->
mparams->
sipip,
':') ?
"IP6" :
"IP4";
12098 snprintf(o_line,
sizeof(o_line),
"o=%s %010u %010u IN %s %s\r\n",
12101 snprintf(q, qe-q,
"%s", o_line);
12102 q += strlen(o_line) - 1;
12106 }
else if (!strncmp(
"s=", p, 2)) {
12107 char *se = strchr(p,
'\n');
12111 char s_line[1024] =
"";
12122 snprintf(q, qe-q,
"%s", s_line);
12124 q += strlen(s_line) - 1;
12128 }
else if ((!strncmp(
"m=audio ", p, 8) && *(p + 8) !=
'0') || (!strncmp(
"m=image ", p, 8) && *(p + 8) !=
'0')) {
12146 snprintf(q, qe - q,
"%s", port_buf);
12147 q += strlen(port_buf);
12154 while (p && *p && (*p >=
'0' && *p <=
'9')) {
12164 }
else if (!strncmp(
"m=video ", p, 8) && *(p + 8) !=
'0') {
12208 snprintf(q, qe-q,
"%s", vport_buf);
12209 q += strlen(vport_buf);
12216 while (p && *p && (*p >=
'0' && *p <=
'9')) {
12227 }
else if (!strncmp(
"m=text ", p, 7) && *(p + 7) !=
'0') {
12271 snprintf(q, qe-q,
"%s", tport_buf);
12272 q += strlen(tport_buf);
12279 while (p && *p && (*p >=
'0' && *p <=
'9')) {
12293 while (p && *p && *p !=
'\n') {
12335 if (!has_ip && !has_audio) {
12371 const char *err, *val;
12376 if (!t38_options || !t38_options->
remote_ip) {
12381 if (remote_host && remote_port && remote_port == t38_options->
remote_port && !strcmp(remote_host, t38_options->
remote_ip)) {
12407 msg.
from = __FILE__;
12416 cJSON *ret = NULL, *n = NULL;
12418 if ((!ideal && !max)) {
12419 ret = cJSON_CreateNumber(min);
12421 ret = cJSON_CreateObject();
12422 n = cJSON_CreateNumber(min);
12423 cJSON_AddItemToObject(ret,
"min", n);
12426 n = cJSON_CreateNumber(ideal);
12427 cJSON_AddItemToObject(ret,
"ideal", n);
12431 n = cJSON_CreateNumber(max);
12432 cJSON_AddItemToObject(ret,
"max", n);
12442 float min = 0, ideal = 0, max = 0;
12447 min = atof(argv[0]);
12451 ideal = atof(argv[1]);
12455 max = atof(argv[2]);
12465 char *parse = NULL;
12470 char *aspect = NULL, *
fps = NULL, *width = NULL, *height = NULL, *jtmp = NULL;
12482 parse = strdup(json);
12485 for(i = 0; i < argc; i++) {
12487 if ((val = strchr(name,
'='))) {
12492 if (!strcmp(name,
"aspect")) {
12495 }
else if (!strcmp(name,
"fps")) {
12498 }
else if (!strcmp(name,
"width")) {
12501 }
else if (!strcmp(name,
"height")) {
12508 obj = cJSON_CreateObject();
12511 video = cJSON_CreateObject();
12515 cJSON_AddItemToObject(video,
"frameRate", p);
12520 cJSON_AddItemToObject(video,
"width", p);
12525 cJSON_AddItemToObject(video,
"height", p);
12529 p = cJSON_CreateNumber(atof(aspect));
12530 cJSON_AddItemToObject(video,
"aspectRatio", p);
12533 cJSON_AddItemToObject(obj,
"video", video);
12536 jtmp = cJSON_PrintUnformatted(obj);
12542 msg.
from = __FILE__;
12594 engine = &smh->
engines[type];
12624 engine = &smh->
engines[type];
12638 uint32_t new_bitrate;
12648 engine = &smh->
engines[type];
12650 new_bitrate = bitrate - bitrate * engine->
bw_mult;
12713 engine = &smh->
engines[type];
12876 void *reply = NULL;
12886 engine = &smh->
engines[type];
12912 if (direction && *direction ==
'v') {
12915 }
else if (direction && *direction ==
't' && t_engine) {
12922 int both = !strcasecmp(direction,
"both");
12925 if (both || !strcasecmp(direction,
"read")) {
12930 if (both || !strcasecmp(direction,
"write")) {
13115 const char *
ip = NULL, *port = NULL;
13482 sdp_parser_t *parser;
13483 sdp_session_t *sdp;
13496 if (
zstr(codec_string)) {
13500 if ((parser = sdp_parse(NULL, r_sdp, (
int) strlen(r_sdp), 0))) {
13502 if ((sdp = sdp_session(parser))) {
13506 sdp_parser_free(parser);
13513 int codec_ms = ptime;
13514 uint32_t map_bit_rate = 0, map_channels = 1;
13515 char ptstr[20] =
"";
13516 char ratestr[20] =
"";
13517 char bitstr[20] =
"";
13524 map_channels = map->rm_params ? atoi(map->rm_params) : 1;
13527 if (!ptime && !strcasecmp(map->rm_encoding,
"g723")) {
13531 if (
zstr(map->rm_fmtp)) {
13532 if (!strcasecmp(map->rm_encoding,
"ilbc")) {
13534 map_bit_rate = 13330;
13535 }
else if (!strcasecmp(map->rm_encoding,
"isac")) {
13537 map_bit_rate = 32000;
13550 if (map->rm_rate) {
13551 switch_snprintf(ratestr,
sizeof(ratestr),
"@%uh", (
unsigned int) map->rm_rate);
13558 if (map_bit_rate) {
13562 if (map_channels > 1) {
13566 switch_snprintf(buf + strlen(buf), buflen - strlen(buf),
",%s.%s%s%s%s", imp->
modname, map->rm_encoding, ratestr, ptstr, bitstr);
13573 char buf[1024] = { 0 };
13575 sdp_attribute_t *attr;
13576 int ptime = 0, dptime = 0;
13577 sdp_connection_t *connection;
13579 short int match = 0;
13581 int already_did[128] = { 0 };
13582 int num_codecs = 0;
13588 int prefer_sdp = 0;
13604 if (!
zstr(codec_string)) {
13605 char *tmp_codec_string;
13607 if (*codec_string ==
'=') codec_string++;
13609 if ((tmp_codec_string = strdup(codec_string))) {
13618 if (!channel || !num_codecs) {
13622 for (attr = sdp->sdp_attributes; attr; attr = attr->a_next) {
13623 if (
zstr(attr->a_name)) {
13627 if (!strcasecmp(attr->a_name,
"ptime")) {
13628 dptime = atoi(attr->a_value);
13633 for (m = sdp->sdp_media; m; m = m->m_next) {
13636 if ((m->m_type == sdp_media_audio || m->m_type == sdp_media_video) && m->m_port) {
13637 for (map = m->m_rtpmaps; map; map = map->rm_next) {
13640 for (attr = m->m_attributes; attr && found < 2; attr = attr->a_next) {
13641 if (
zstr(attr->a_name)) {
13645 if (!strcasecmp(attr->a_name,
"ptime") && attr->a_value) {
13646 ptime = atoi(attr->a_value);
13650 if (!strcasecmp(attr->a_name,
"rtcp-mux")) {
13669 map->rm_params ? atoi(map->rm_params) : 1,
13675 for (m = sdp->sdp_media; m; m = m->m_next) {
13678 if (m->m_type == sdp_media_image && m->m_port) {
13679 switch_snprintf(buf + strlen(buf),
sizeof(buf) - strlen(buf),
",t38");
13680 }
else if (m->m_type == sdp_media_audio && m->m_port) {
13681 for (attr = m->m_attributes; attr; attr = attr->a_next) {
13682 if (
zstr(attr->a_name)) {
13686 if (!strcasecmp(attr->a_name,
"ptime") && attr->a_value) {
13687 ptime = atoi(attr->a_value);
13692 connection = sdp->sdp_connection;
13693 if (m->m_connections) {
13694 connection = m->m_connections;
13703 for (map = m->m_rtpmaps; map; map = map->rm_next) {
13705 if (already_did[map->rm_pt]) {
13709 for (i = 0; i < num_codecs; i++) {
13713 match = (map->rm_pt == imp->
ianacode) ? 1 : 0;
13715 if (map->rm_encoding) {
13716 match = !strcasecmp(map->rm_encoding, imp->
iananame) &&
13717 ((map->rm_pt < 96 && imp->
ianacode < 96) || (map->rm_pt > 95 && imp->
ianacode > 95));
13730 for (i = 0; i < num_codecs; i++) {
13737 for (map = m->m_rtpmaps; map; map = map->rm_next) {
13739 if (already_did[map->rm_pt]) {
13744 match = (map->rm_pt == imp->
ianacode) ? 1 : 0;
13746 if (map->rm_encoding) {
13747 match = !strcasecmp(map->rm_encoding, imp->
iananame) &&
13748 ((map->rm_pt < 96 && imp->
ianacode < 96) || (map->rm_pt > 95 && imp->
ianacode > 95));
13761 }
else if (m->m_type == sdp_media_video && m->m_port) {
13762 connection = sdp->sdp_connection;
13763 if (m->m_connections) {
13764 connection = m->m_connections;
13773 for (map = m->m_rtpmaps; map; map = map->rm_next) {
13775 if (already_did[map->rm_pt]) {
13779 for (i = 0; i < num_codecs; i++) {
13783 match = (map->rm_pt == imp->
ianacode) ? 1 : 0;
13785 if (map->rm_encoding) {
13786 match = !strcasecmp(map->rm_encoding, imp->
iananame) &&
13787 ((map->rm_pt < 96 && imp->
ianacode < 96) || (map->rm_pt > 95 && imp->
ianacode > 95));
13794 if (map->rm_fmtp) {
13805 for (i = 0; i < num_codecs; i++) {
13817 for (map = m->m_rtpmaps; map; map = map->rm_next) {
13819 if (already_did[map->rm_pt]) {
13824 match = (map->rm_pt == imp->
ianacode) ? 1 : 0;
13826 if (map->rm_encoding) {
13827 match = !strcasecmp(map->rm_encoding, imp->
iananame) &&
13828 ((map->rm_pt < 96 && imp->
ianacode < 96) || (map->rm_pt > 95 && imp->
ianacode > 95));
13835 if (map->rm_fmtp) {
13846 }
else if (m->m_proto == sdp_proto_msrp) {
13848 }
else if (m->m_proto == sdp_proto_msrps) {
13850 }
else if (m->m_type == sdp_media_text) {
13855 if (buf[0] ==
',') {
13872 engine = &smh->
engines[type];
13973 const char *r_sdp = NULL;
14060 const char *r_port;
14151 if (r_ip && r_port) {
14187 if (r_ip && r_port) {
14205 int idx = atoi(tmp);
14242 if (video_globals.
pool) {
14249 if (!strcasecmp(name,
"pcmu")) {
14253 if (!strcasecmp(name,
"pcma")) {
14257 if (!strcasecmp(name,
"gsm")) {
14261 if (!strcasecmp(name,
"g722")) {
14265 if (!strcasecmp(name,
"g729")) {
14269 if (!strcasecmp(name,
"dvi4")) {
14273 if (!strcasecmp(name,
"h261")) {
14277 if (!strcasecmp(name,
"h263")) {
14289 if (p <
end_of_p(sdp) && *(p+strlen(name)) ==
'/' && *(p-1) ==
' ') {
14292 while(*p > 47 && *p < 58) {
14309 char *new_sdp = NULL;
14310 int pt = -1, te = -1;
14314 int in_m = 0, slash = 0;
14315 int number = 0, skip = 0;
14316 int remove = !strcasecmp(cmd,
"remove");
14317 int only = !strcasecmp(cmd,
"only");
14318 char *end =
end_of_p((
char *)sdp_str);
14323 if (
remove || only) {
14334 te =
find_pt(sdp_str,
"telephone-event");
14338 len = strlen(sdp_str) + 2;
14339 new_sdp = malloc(len);
14344 while(i && *i && i < end) {
14346 if (*i ==
'm' && *(i+1) ==
'=') {
14351 if (*i ==
'\r' || *i ==
'\n') {
14357 while(*i !=
' ' && i < end) {
14369 while(i < end && ((*i > 47 && *i < 58) || *i ==
' ')) {
14372 tst = (number != pt);
14374 tst = (number == pt || number == te);
14389 tst = (number == pt);
14391 tst = (number != pt && number != te);
14401 while (i < end && !strncasecmp(i,
"a=rtpmap:", 9)) {
14402 const char *t = i + 9;
14407 tst = (number == pt);
14409 tst = (number != pt && number != te);
14412 while(i < end && (*i !=
'\r' && *i !=
'\n')) {
14413 if (!tst) *o++ = *i;
14417 while(i < end && (*i ==
'\r' || *i ==
'\n')) {
14418 if (!tst) *o++ = *i;
14423 while (i < end && !strncasecmp(i,
"a=fmtp:", 7)) {
14424 const char *t = i + 7;
14429 tst = (number == pt);
14431 tst = (number != pt && number != te);
14434 while(i < end && (*i !=
'\r' && *i !=
'\n')) {
14435 if (!tst) *o++ = *i;
14439 while(i < end && (*i ==
'\r' || *i ==
'\n')) {
14440 if (!tst) *o++ = *i;
14466 char *patched_sdp = NULL;
14470 for (x = 0; x < argc; x++) {
14471 char *command = argv[x];
14472 char *arg = strchr(command,
'(');
14483 char *tmp_sdp = NULL;
14493 "%s Filter command %s(%s)\nFROM:\n==========\n%s\nTO:\n==========\n%s\n\n",
14495 command, arg, patched_sdp ? patched_sdp : sdp, tmp_sdp);
14500 patched_sdp = tmp_sdp;
14505 return patched_sdp;
14521 if (!(engine = &smh->
engines[mtype])) {
14559 msg.
from = __FILE__;
14601 if (!(engine = &smh->
engines[mtype])) {
14641 if (!(engine = &smh->
engines[mtype])) {
14671 for (ptr = session->
event_hooks.video_write_frame; ptr; ptr = ptr->
next) {
14791 if (vid_params.
width && vid_params.
height && ((vid_params.
width != img->d_w) || (vid_params.
height != img->d_h))) {
14793 if (!(img = dup_img)) {
14804 if (session->
bugs) {
14810 for (bp = session->
bugs; bp; bp = bp->
next) {
14839 if (bp->
ready && img &&
14843 bug_frame.
img = img;
14854 if (bug_frame.
img && bug_frame.
img != img) {
14856 img = bug_frame.
img;
14881 write_frame = *frame;
14882 frame = &write_frame;
14915 if (frame->
datalen == 0)
break;
14966 if (video_globals.
synced &&
14997 if (read_impl_a.
impl_id && read_impl_b.impl_id) {
15010 return transcoding;
15052 int is_keyframe = 0;
15068 for (ptr = session->
event_hooks.video_read_frame; ptr; ptr = ptr->
next) {
15101 "VIDEO: seq: %d ts: %u len: %4d %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x mark: %d\n",
15102 (*frame)->seq, (*frame)->timestamp, (*frame)->datalen,
15103 *((uint8_t *)(*frame)->data), *((uint8_t *)(*frame)->data + 1),
15104 *((uint8_t *)(*frame)->data + 2), *((uint8_t *)(*frame)->data + 3),
15105 *((uint8_t *)(*frame)->data + 4), *((uint8_t *)(*frame)->data + 5),
15106 *((uint8_t *)(*frame)->data + 6), *((uint8_t *)(*frame)->data + 7),
15107 *((uint8_t *)(*frame)->data + 8), *((uint8_t *)(*frame)->data + 9),
15108 *((uint8_t *)(*frame)->data + 10), (*frame)->m);
15121 (*frame)->img = NULL;
15129 (*frame)->img->w, (*frame)->img->h, (*frame)->img->d_w, (*frame)->img->d_h);
15132 if ((*frame)->img && (*frame)->img->d_w && (*frame)->img->d_h) {
15133 int new_w = 0, new_h = 0;
15136 new_w = (*frame)->img->d_w;
15137 new_h = (*frame)->img->d_h;
15139 if (new_w && new_h) {
15154 if (!(*frame)->img) {
15168 if ((*frame)->img) {
15171 }
else if ((*frame)->m || ++smh->
ready_loops > 5) {
15178 if (*frame && is_keyframe) {
15182 if (session->
bugs) {
15188 for (bp = session->
bugs; bp; bp = bp->
next) {
15205 if ((*frame) && (*frame)->img) {
15216 if (bp->
ready && (*frame) && (*frame)->img &&
15248 if ((*frame) && (*frame)->codec) {
15249 (*frame)->pmap = NULL;
15385 if (read_text_frame) {
15387 for (ptr = session->
event_hooks.text_read_frame; ptr; ptr = ptr->
next) {
15418 unsigned char *p = (*frame)->data;
15425 if (*p ==
'\r' || *p ==
'\n') {
15430 if (*p == 0xE2 && *(p+1) == 0x80 && *(p+2) == 0xA8) {
15439 if ((*frame)->data && (*frame)->datalen && !((*frame)->flags &
SFF_CNG)) {
15447 if (session->
bugs) {
15452 for (bp = session->
bugs; bp; bp = bp->
next) {
15474 if ((*frame)->data && (*frame)->datalen && !((*frame)->flags &
SFF_CNG)) {
15486 void *tmp = malloc(inuse + 1024);
15526 void *data = (*frame)->data;
15527 char eof[1] = {
'\0'};
15589 uint32_t plen = 0, loops = 0;
15603 *buf = t_engine->
t140_pt & 0x7f;
15609 u16 = (uint16_t *) buf;
15610 *u16 = htons(ts << 2);
15612 *buf += (len & 0x300) >> 8;
15619 if (pos == t_engine->
tf->
red_pos)
break;
15624 if (pos == t_engine->
tf->
red_max) pos = 0;
15628 plen = ((loops - 1) * 4) + 1;
15631 if (pos == t_engine->
tf->
red_max) pos = 0;
15640 if (pos == t_engine->
tf->
red_pos)
break;
15644 if (pos == t_engine->
tf->
red_max) pos = 0;
15649 *(buf+plen) =
'\0';
15695 if (!t_engine || !t_engine->
tf) {
15701 char *str = (
char *) frame->
data;
15720 for(pos = 0; pos < t_engine->
tf->
red_max; pos++) {
15751 if (write_text_frame) {
15753 for (ptr = session->
event_hooks.text_write_frame; ptr; ptr = ptr->
next) {
15763 if (!t_engine || (t_engine->
red_pt && !t_engine->
tf)) {
15802 frame.
datalen = strlen(data);
15825 frame.
data = (
char *) data;
15826 frame.
datalen = strlen(data);
15847 unsigned int flag = 0, need_codec = 0, perfect = 0, do_bugs = 0, do_write = 0, do_resample = 0, ptime_mismatch = 0, pass_cng = 0, resample = 0;
15848 int did_write_resample = 0;
15920 ptime_mismatch =
TRUE;
15946 do_resample =
TRUE;
15978 write_frame = frame;
15990 if (frame->
codec) {
16074 write_frame = frame;
16098 short *data = write_frame->data;
16124 did_write_resample = 1;
16131 if (session->
bugs) {
16136 for (bp = session->
bugs; bp; bp = bp->
next) {
16195 write_frame = frame;
16200 if (!ptime_mismatch && write_frame->codec && write_frame->codec->implementation &&
16214 enc_frame = write_frame;
16256 enc_frame->
m = frame->
m;
16257 enc_frame->
seq = frame->
seq;
16260 write_frame = enc_frame;
16264 write_frame = NULL;
16269 write_frame = NULL;
16276 status =
perform_write(session, write_frame, flags, stream_id);
16282 "Engaging Write Buffer at %u bytes to accommodate %u->%u\n",
16410 enc_frame->
m = frame->
m;
16413 write_frame = enc_frame;
16417 write_frame = NULL;
16422 write_frame = NULL;
16427 short *data = write_frame->data;
16445 if (ptime_mismatch || resample) {
16446 write_frame->timestamp = 0;
16465 if (ptime_mismatch || resample) {
16466 write_frame->timestamp = 0;
16470 status =
perform_write(session, write_frame, flags, stream_id);
16484 if (!session)
return NULL;
16493 if (!engine)
return NULL;
struct switch_video_codec_settings video
switch_status_t switch_channel_set_variable_printf(switch_channel_t *channel, const char *varname, const char *fmt,...)
switch_mutex_t * codec_init_mutex
switch_status_t switch_core_codec_decode_video(switch_codec_t *codec, switch_frame_t *frame)
Decode video data using a codec handle.
#define SWITCH_MAX_CODECS
switch_core_session_t * session
switch_time_t switch_micro_time_now(void)
Get the current epoch time in microseconds.
#define switch_event_fire(event)
Fire an event filling in most of the arguements with obvious values.
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it's state machine to end.
switch_status_t switch_channel_execute_on(switch_channel_t *channel, const char *variable_prefix)
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core's master pool.
void switch_channel_set_flag_recursive(switch_channel_t *channel, switch_channel_flag_t flag)
uint32_t T38FaxMaxDatagram
switch_status_t switch_thread_rwlock_unlock(switch_thread_rwlock_t *rwlock)
switch_status_t switch_rtp_activate_rtcp(switch_rtp_t *rtp_session, int send_rate, switch_port_t remote_port, switch_bool_t mux)
Activate sending RTCP Sender Reports (SR's)
char * switch_core_session_sprintf(_In_ switch_core_session_t *session, _In_z_ _Printf_format_string_ const char *fmt,...)
printf-style style printing routine. The data is output to a string allocated from the session ...
unsigned char remote_raw_key[SWITCH_RTP_MAX_CRYPTO_LEN]
switch_status_t switch_msrp_session_destroy(switch_msrp_session_t **ms)
switch_status_t switch_thread_cond_create(switch_thread_cond_t **cond, switch_memory_pool_t *pool)
switch_audio_resampler_t * write_resampler
switch_frame_t dummy_cng_frame
#define SWITCH_BUFFER_START_FRAMES
static switch_bool_t switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
void switch_ivr_bg_media(const char *uuid, switch_media_flag_t flags, switch_bool_t on, switch_bool_t is3p, uint32_t delay)
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_status_t switch_core_codec_parse_fmtp(const char *codec_name, const char *fmtp, uint32_t rate, switch_codec_fmtp_t *codec_fmtp)
void switch_rtp_set_media_timeout(switch_rtp_t *rtp_session, uint32_t ms)
switch_thread_rwlock_t * bug_rwlock
#define switch_set_flag(obj, flag)
Set a flag on an arbitrary object.
switch_rtp_numbers_t inbound
uint8_t switch_rtp_ready(switch_rtp_t *rtp_session)
Test if an RTP session is ready.
switch_status_t switch_core_timer_init(switch_timer_t *timer, const char *timer_name, int interval, int samples, switch_memory_pool_t *pool)
Request a timer handle using given time module.
switch_core_session_message_types_t message_id
switch_status_t switch_frame_buffer_free(switch_frame_buffer_t *fb, switch_frame_t **frameP)
#define SWITCH_CHANNEL_LOG
void switch_core_session_reset(_In_ switch_core_session_t *session, switch_bool_t flush_dtmf, switch_bool_t reset_read_codec)
Reset the buffers and resampler on a session.
switch_size_t switch_buffer_read(_In_ switch_buffer_t *buffer, _In_ void *data, _In_ switch_size_t datalen)
Read data from a switch_buffer_t up to the ammount of datalen if it is available. Remove read data fr...
switch_rtp_crypto_key_type_t
void switch_core_session_passthru(switch_core_session_t *session, switch_media_type_t type, switch_bool_t on)
switch_status_t switch_mutex_trylock(switch_mutex_t *lock)
switch_status_t switch_channel_set_variable_name_printf(switch_channel_t *channel, const char *val, const char *fmt,...)
const char *const const double number
switch_status_t switch_channel_queue_dtmf(_In_ switch_channel_t *channel, _In_ const switch_dtmf_t *dtmf)
Queue DTMF on a given channel.
uint32_t switch_channel_test_flag_partner(switch_channel_t *channel, switch_channel_flag_t flag)
char * local_accept_types
struct switch_io_event_hook_text_write_frame * next
char * switch_find_end_paren(const char *s, char open, char close)
void switch_img_free(switch_image_t **img)
Close an image descriptor.
const char * switch_msrp_listen_ip(void)
switch_mutex_t * codec_write_mutex
const char * switch_channel_get_partner_uuid(switch_channel_t *channel)
switch_status_t switch_channel_set_private(switch_channel_t *channel, const char *key, const void *private_info)
Set private data on channel.
switch_status_t switch_core_session_set_video_read_callback(switch_core_session_t *session, switch_core_video_thread_callback_func_t func, void *user_data)
void switch_rtp_reset(switch_rtp_t *rtp_session)
switch_status_t switch_buffer_create_dynamic(_Out_ switch_buffer_t **buffer, _In_ switch_size_t blocksize, _In_ switch_size_t start_len, _In_ switch_size_t max_len)
Allocate a new dynamic switch_buffer.
uint32_t switch_io_flag_t
char * remote_rtcp_ice_addr
switch_status_t switch_rtp_ack_bitrate(switch_rtp_t *rtp_session, uint32_t bps)
switch_video_write_frame_hook_t text_write_frame
int switch_loadable_module_get_codecs_sorted(const switch_codec_implementation_t **array, char fmtp_array[SWITCH_MAX_CODECS][MAX_FMTP_LEN], int arraylen, char **prefs, int preflen)
Retrieve the list of loaded codecs into an array based on another array showing the sorted order...
switch_size_t switch_b64_decode(const char *in, char *out, switch_size_t olen)
switch_buffer_t * raw_write_buffer
switch_read_frame_hook_t video_read_frame
switch_status_t switch_frame_buffer_trypop(switch_frame_buffer_t *fb, void **ptr)
#define switch_channel_stop_broadcast(_channel)
switch_status_t switch_core_session_set_video_read_codec(_In_ switch_core_session_t *session, switch_codec_t *codec)
Assign the video_read codec to a given session.
switch_rtp_t * switch_rtp_new(const char *rx_host, switch_port_t rx_port, const char *tx_host, switch_port_t tx_port, switch_payload_t payload, uint32_t samples_per_interval, uint32_t ms_per_packet, switch_rtp_flag_t flags[SWITCH_RTP_FLAG_INVALID], char *timer_name, const char **err, switch_memory_pool_t *pool, switch_port_t bundle_internal_ports, switch_port_t bundle_external_port)
prepare a new RTP session handle and fully initilize it
#define switch_channel_up(_channel)
#define SWITCH_RECOMMENDED_BUFFER_SIZE
switch_status_t switch_jb_peek_frame(switch_jb_t *jb, uint32_t ts, uint16_t seq, int peek, switch_frame_t *frame)
void switch_channel_event_set_data(_In_ switch_channel_t *channel, _In_ switch_event_t *event)
Add information about a given channel to an event object.
switch_bool_t switch_is_leading_number(const char *str)
unsigned long adv_rm_rate
#define switch_channel_presence(_a, _b, _c, _d)
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
switch_status_t switch_core_codec_encode(switch_codec_t *codec, switch_codec_t *other_codec, void *decoded_data, uint32_t decoded_data_len, uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate, unsigned int *flag)
Encode data using a codec handle.
switch_size_t largest_jb_size
uint32_t media_hold_timeout
#define switch_split(_data, _delim, _array)
switch_status_t switch_core_session_set_read_impl(switch_core_session_t *session, const switch_codec_implementation_t *impp)
switch_status_t switch_ivr_broadcast(const char *uuid, const char *path, switch_media_flag_t flags)
Signal the session to broadcast audio.
switch_status_t switch_core_session_set_video_write_codec(_In_ switch_core_session_t *session, switch_codec_t *codec)
Assign the video_write codec to a given session.
#define TEXT_UNICODE_LINEFEED
switch_thread_id_t thread_write_lock
switch_status_t switch_threadattr_stacksize_set(switch_threadattr_t *attr, switch_size_t stacksize)
Node in which to store custom video_write_frame channel callback hooks.
switch_status_t switch_core_media_bug_flush_all(_In_ switch_core_session_t *session)
Flush the read/write buffers for all media bugs on the session.
switch_bool_t switch_is_uint_in_range(const char *str, unsigned int from, unsigned int to)
Check if a 32 bit unsigned number is in a range.
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
#define SWITCH_LOCAL_VIDEO_IP_VARIABLE
uint32_t decoded_bytes_per_packet
switch_codec_t * read_codec
Representation of an event.
Node in which to store custom read frame channel callback hooks.
switch_read_frame_hook_t text_read_frame
#define switch_channel_ready(_channel)
switch_status_t switch_event_add_body(switch_event_t *event, const char *fmt,...) PRINTF_FUNCTION(2
Add a body to an event.
switch_frame_t * cur_frame
switch_io_routines_t * io_routines
struct switch_io_event_hook_video_read_frame * next
struct switch_rtcp_report_block_frame reports[MAX_REPORT_BLOCKS]
const char *const const char *const const cJSON *const value
switch_status_t switch_core_session_read_lock(_In_ switch_core_session_t *session)
Acquire a read lock on the session.
#define SWITCH_RTP_MAX_BUF_LEN
switch_rtp_crypto_direction_t
static int switch_channel_var_false(switch_channel_t *channel, const char *variable)
switch_media_flow_t smode
switch_buffer_t * write_buffer
switch_status_t switch_rtp_pause_jitter_buffer(switch_rtp_t *rtp_session, switch_bool_t pause)
switch_bool_t T38FaxTranscodingMMR
#define switch_channel_media_ready(_channel)
switch_rtp_crypto_key_param_method_type_t
const char * T38FaxRateManagement
Node in which to store custom read frame channel callback hooks.
dtls_state_t switch_rtp_dtls_state(switch_rtp_t *rtp_session, dtls_type_t type)
switch_status_t switch_core_session_video_read_callback(switch_core_session_t *session, switch_frame_t *frame)
switch_status_t switch_nat_add_mapping(switch_port_t port, switch_nat_ip_proto_t proto, switch_port_t *external_port, switch_bool_t sticky)
Maps a port through the NAT Traversal System.
unsigned int switch_ci_hashfunc_default(const char *char_key, switch_ssize_t *klen)
switch_status_t switch_rtp_set_payload_map(switch_rtp_t *rtp_session, payload_map_t **pmap)
switch_engine_function_t engine_function
switch_status_t switch_core_codec_decode(switch_codec_t *codec, switch_codec_t *other_codec, void *encoded_data, uint32_t encoded_data_len, uint32_t encoded_rate, void *decoded_data, uint32_t *decoded_data_len, uint32_t *decoded_rate, unsigned int *flag)
Decode data using a codec handle.
void switch_core_session_lock_codec_read(_In_ switch_core_session_t *session)
#define SWITCH_RESAMPLE_QUALITY
switch_video_write_frame_hook_t video_write_frame
switch_codec_settings_t codec_settings
switch_codec_implementation_t read_impl
void switch_rtp_intentional_bugs(switch_rtp_t *rtp_session, switch_rtp_bug_flag_t bugs)
switch_status_t switch_core_codec_destroy(switch_codec_t *codec)
Destroy an initalized codec handle.
switch_status_t switch_thread_cond_wait(switch_thread_cond_t *cond, switch_mutex_t *mutex)
const char * switch_channel_get_variable_dup(switch_channel_t *channel, const char *varname, switch_bool_t dup, int idx)
Retrieve a variable from a given channel.
const char * string_array_arg[MESSAGE_STRING_ARG_MAX]
#define switch_calc_video_fps(fpsP, fps)
#define switch_core_session_get_name(_s)
struct switch_io_event_hook_video_write_frame * next
uint32_t switch_core_cpu_count(void)
switch_status_t switch_core_session_queue_message(_In_ switch_core_session_t *session, _In_ switch_core_session_message_t *message)
Queue a message on a session.
char * switch_stun_host_lookup(const char *host, switch_memory_pool_t *pool)
#define switch_resample_calc_buffer_size(_to, _from, _srclen)
switch_bool_t T38FaxTranscodingJBIG
switch_frame_buffer_t * write_fb
switch_size_t media_bytes
#define SWITCH_LOCAL_VIDEO_PORT_VARIABLE
void switch_rtp_set_telephony_recv_event(switch_rtp_t *rtp_session, switch_payload_t te)
switch_status_t switch_core_media_bug_patch_spy_frame(switch_media_bug_t *bug, switch_image_t *img, switch_rw_t rw)
struct switch_crypto_key_material_s * local_key_material_next
switch_status_t switch_event_dup(switch_event_t **event, switch_event_t *todup)
Duplicate an event.
static int32_t switch_calc_bitrate(int w, int h, float quality, double fps)
icand_t cands[MAX_CAND][MAX_CAND_IDX_COUNT]
uint32_t max_missed_hold_packets
Abstract handler to a timer module.
#define SWITCH_DEFAULT_VIDEO_SIZE
switch_size_t dtmf_packet_count
void switch_resample_destroy(switch_audio_resampler_t **resampler)
Destroy an existing resampler handle.
static switch_thread_t * thread
int switch_snprintf(_Out_z_cap_(len) char *buf, _In_ switch_size_t len, _In_z_ _Printf_format_string_ const char *format,...)
switch_size_t switch_buffer_write(_In_ switch_buffer_t *buffer, _In_bytecount_(datalen) const void *data, _In_ switch_size_t datalen)
Write data into a switch_buffer_t up to the length of datalen.
struct switch_runtime runtime
switch_status_t switch_frame_buffer_dup(switch_frame_buffer_t *fb, switch_frame_t *orig, switch_frame_t **clone)
uint32_t switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Test for presence of given flag on a given channel.
static int32_t switch_parse_bandwidth_string(const char *bwv)
struct switch_crypto_key_material_s * next
switch_thread_id_t thread_id
switch_secure_settings_t ssec[CRYPTO_INVALID+1]
#define switch_check_network_list_ip(_ip_str, _list_name)
payload_map_t * payload_map
switch_status_t switch_frame_buffer_destroy(switch_frame_buffer_t **fbP)
switch_status_t(* switch_io_write_text_frame_t)(switch_core_session_t *, switch_frame_t *, switch_io_flag_t, int)
switch_io_read_text_frame_t read_text_frame
switch_status_t switch_core_session_read_frame(_In_ switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
Read a frame from a session.
static uint32_t switch_known_bitrate(switch_payload_t payload)
switch_buffer_t * text_buffer
#define SWITCH_ADVERTISED_MEDIA_IP_VARIABLE
A message object designed to allow unlike technologies to exchange data.
switch_image_t * switch_img_alloc(switch_image_t *img, switch_img_fmt_t fmt, unsigned int d_w, unsigned int d_h, unsigned int align)
Open a descriptor, allocating storage for the underlying image.
Node in which to store custom write_frame channel callback hooks.
#define SWITCH_LOCAL_TEXT_PORT_VARIABLE
void switch_rtp_set_max_missed_packets(switch_rtp_t *rtp_session, uint32_t max)
switch_port_t switch_rtp_get_remote_port(switch_rtp_t *rtp_session)
struct payload_map_s * next
switch_media_handle_t * media_handle
void rtp_flush_read_buffer(switch_rtp_t *rtp_session, switch_rtp_flush_t flush)
switch_status_t switch_core_thread_set_cpu_affinity(int cpu)
void switch_core_session_unset_write_codec(_In_ switch_core_session_t *session)
#define SWITCH_LOCAL_MEDIA_PORT_VARIABLE
static int switch_safe_atoi(const char *nptr, int dft)
Turn a string into an integer (default if NULL)
uint32_t switch_codec_flag_t
switch_status_t switch_rtp_udptl_mode(switch_rtp_t *rtp_session)
switch_status_t switch_resolve_host(const char *host, char *buf, size_t buflen)
void switch_rtp_reset_media_timer(switch_rtp_t *rtp_session)
void switch_rtp_set_telephony_event(switch_rtp_t *rtp_session, switch_payload_t te)
Set the payload type to consider RFC2833 DTMF.
switch_status_t switch_core_codec_reset(switch_codec_t *codec)
switch_io_event_hooks_t event_hooks
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
struct switch_io_event_hook_text_read_frame * next
switch_status_t switch_thread_rwlock_rdlock(switch_thread_rwlock_t *rwlock)
switch_status_t switch_core_session_get_read_impl(switch_core_session_t *session, switch_codec_implementation_t *impp)
switch_frame_t read_frame
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
switch_codec_control_command_t
void switch_rtp_destroy(switch_rtp_t **rtp_session)
Destroy an RTP session.
void switch_core_recovery_track(switch_core_session_t *session)
#define SWITCH_ORIGINATOR_CODEC_VARIABLE
void switch_channel_clear_app_flag_key(const char *app, switch_channel_t *channel, uint32_t flags)
#define switch_clear_flag(obj, flag)
Clear a flag on an arbitrary object while locked.
unsigned char local_raw_key[SWITCH_RTP_MAX_CRYPTO_LEN]
int switch_core_cert_gen_fingerprint(const char *prefix, dtls_fingerprint_t *fp)
void switch_channel_mark_hold(switch_channel_t *channel, switch_bool_t on)
switch_codec_implementation_t write_impl
#define SWITCH_MUTEX_NESTED
#define SWITCH_RTCP_AUDIO_INTERVAL_MSEC
switch_status_t switch_rtp_deactivate_jitter_buffer(switch_rtp_t *rtp_session)
switch_jb_t * switch_rtp_get_jitter_buffer(switch_rtp_t *rtp_session)
void switch_core_session_enable_heartbeat(switch_core_session_t *session, uint32_t seconds)
char * remote_accept_types
switch_codec_t write_codec
switch_status_t switch_rtp_zerocopy_read_frame(switch_rtp_t *rtp_session, switch_frame_t *frame, switch_io_flag_t io_flags)
Read data from a given RTP session without copying.
switch_memory_pool_t * pool
switch_codec_control_type_t
void(* switch_engine_function_t)(switch_core_session_t *session, void *user_data)
const switch_codec_implementation_t * implementation
#define SWITCH_REMOTE_MEDIA_IP_VARIABLE
switch_port_t remote_rtp_ice_port
switch_rtcp_numbers_t rtcp
switch_byte_t switch_byte_t * buf
#define SWITCH_STUN_DEFAULT_PORT
int microseconds_per_packet
if((uint32_t)(unpack->cur - unpack->buf) > unpack->buflen)
#define switch_yield(ms)
Wait a desired number of microseconds and yield the CPU.
uint32_t switch_core_media_bug_prune(switch_core_session_t *session)
#define switch_channel_audio_sync(_c)
unsigned int switch_separate_string(_In_ char *buf, char delim, _Post_count_(return) char **array, unsigned int arraylen)
Separate a string into an array based on a character delimiter.
switch_channel_t * channel
switch_rtp_t * rtp_session
switch_write_frame_hook_t write_frame
switch_audio_resampler_t * read_resampler
uint32_t highest_sequence_number_received
void switch_stun_random_string(char *buf, uint16_t len, char *set)
Writes random characters into a buffer.
const char * switch_channel_get_hold_music(switch_channel_t *channel)
switch_codec_interface_t * codec_interface
switch_timer_interface_t * timer_interface
switch_status_t switch_rtp_activate_jitter_buffer(switch_rtp_t *rtp_session, uint32_t queue_frames, uint32_t max_queue_frames, uint32_t samples_per_packet, uint32_t samples_per_second)
Acvite a jitter buffer on an RTP session.
int switch_rtp_has_dtls(void)
switch_codec_t read_codec
switch_frame_flag_t flags
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
switch_media_flow_t rmode
switch_status_t switch_b64_encode(unsigned char *in, switch_size_t ilen, unsigned char *out, switch_size_t olen)
switch_status_t switch_rtp_get_video_buffer_size(switch_rtp_t *rtp_session, uint32_t *min_frame_len, uint32_t *max_frame_len, uint32_t *cur_frame_len, uint32_t *highest_frame_len)
uint32_t red_ts[MAX_RED_FRAMES]
#define switch_core_session_request_video_refresh(_s)
switch_codec_type_t codec_type
unsigned long local_key_material_n
uint32_t switch_channel_test_cap_partner(switch_channel_t *channel, switch_channel_cap_t cap)
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
uint32_t actual_samples_per_second
switch_status_t switch_rtp_activate_ice(switch_rtp_t *rtp_session, char *login, char *rlogin, const char *password, const char *rpassword, ice_proto_t proto, switch_core_media_ice_type_t type, ice_t *ice_params)
Acvite ICE on an RTP session.
#define switch_channel_get_variable(_c, _v)
#define SWITCH_THREAD_STACKSIZE
#define switch_channel_video_sync(_c)
void * video_read_user_data
void switch_rtp_set_flags(switch_rtp_t *rtp_session, switch_rtp_flag_t flags[SWITCH_RTP_FLAG_INVALID])
switch_status_t switch_event_add_header_string(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *data)
Add a string header to an event.
#define switch_zmalloc(ptr, len)
char * remote_accept_wrapped_types
void switch_img_copy(switch_image_t *img, switch_image_t **new_img)
Copy image to a new image.
payload_map_t * cur_payload_map
#define SWITCH_RTP_MAX_CRYPTO_LEN
switch_codec_t * write_codec
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
switch_rtp_numbers_t outbound
switch_status_t switch_img_fit(switch_image_t **srcP, int width, int height, switch_img_fit_t fit)
switch_core_video_thread_callback_func_t text_read_callback
void switch_rtp_video_loss(switch_rtp_t *rtp_session)
dtls_fingerprint_t local_dtls_fingerprint
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
switch_status_t switch_rtp_set_remote_ssrc(switch_rtp_t *rtp_session, uint32_t ssrc)
switch_rtp_text_factory_t * tf
switch_status_t switch_thread_join(switch_status_t *retval, switch_thread_t *thd)
switch_image_t * switch_img_read_png(const char *file_name, switch_img_fmt_t img_fmt)
switch_media_bug_t * bugs
int switch_loadable_module_get_codecs(const switch_codec_implementation_t **array, int arraylen)
Retrieve the list of loaded codecs into an array.
switch_status_t switch_rtp_set_ssrc(switch_rtp_t *rtp_session, uint32_t ssrc)
void switch_buffer_zero(_In_ switch_buffer_t *buffer)
Remove all data from the buffer.
switch_mutex_t * resample_mutex
#define switch_channel_down_nosig(_channel)
switch_sdp_type_t sdp_type
switch_mutex_t * text_mutex
uint32_t switch_core_max_audio_channels(uint32_t limit)
switch_io_routines_t * io_override
An abstraction of a data frame.
switch_status_t switch_rtp_add_dtls(switch_rtp_t *rtp_session, dtls_fingerprint_t *local_fp, dtls_fingerprint_t *remote_fp, dtls_type_t type, uint8_t want_DTLSv1_2)
int switch_vasprintf(_Out_opt_ char **buf, _In_z_ _Printf_format_string_ const char *format, _In_ va_list ap)
#define switch_set_flag_locked(obj, flag)
Set a flag on an arbitrary object while locked.
uint32_t switch_default_ptime(const char *name, uint32_t number)
switch_status_t switch_channel_wait_for_app_flag(switch_channel_t *channel, uint32_t app_flag, const char *key, switch_bool_t pres, uint32_t to)
const char * T38VendorInfo
switch_codec_t * switch_core_session_get_video_write_codec(_In_ switch_core_session_t *session)
Retrieve the video_write codec from a given session.
switch_size_t switch_rtp_has_dtmf(switch_rtp_t *rtp_session)
Test for presence of DTMF on a given RTP session.
switch_byte_t switch_byte_t uint32_t buflen
#define switch_core_codec_init(_codec, _codec_name, _modname, _fmtp, _rate, _ms, _channels, _flags, _codec_settings, _pool)
Initialize a codec handle.
switch_port_t local_sdp_port
pthread_t switch_thread_id_t
int switch_inet_pton(int af, const char *src, void *dst)
void switch_cond_next(void)
#define switch_core_session_get_partner(_session, _partner)
switch_status_t switch_img_letterbox(switch_image_t *img, switch_image_t **imgP, int width, int height, const char *color)
switch_payload_t agreed_pt
int microseconds_per_packet
char * switch_core_get_variable(_In_z_ const char *varname)
Retrieve a global variable from the core.
char * switch_copy_string(_Out_z_cap_(dst_size) char *dst, _In_z_ const char *src, _In_ switch_size_t dst_size)
switch_status_t switch_nat_del_mapping(switch_port_t port, switch_nat_ip_proto_t proto)
Deletes a NAT mapping.
switch_size_t packet_count
switch_status_t switch_core_session_queue_event(_In_ switch_core_session_t *session, _Inout_ switch_event_t **event)
Queue an event on a given session.
switch_status_t switch_rtp_set_remote_address(switch_rtp_t *rtp_session, const char *host, switch_port_t port, switch_port_t remote_rtcp_port, switch_bool_t change_adv_addr, const char **err)
Assign a remote address to the RTP session.
payload_map_t * pmap_tail
switch_memory_pool_t * pool
void switch_color_set_rgb(switch_rgb_color_t *color, const char *color_str)
Set RGB color with a string.
void * text_read_user_data
unsigned long remote_key_material_n
switch_status_t switch_core_timer_destroy(switch_timer_t *timer)
Destroy an allocated timer.
uint32_t actual_samples_per_second
int cand_idx[MAX_CAND_IDX_COUNT]
#define switch_core_session_receive_message(_session, _message)
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.
void switch_core_session_video_reset(switch_core_session_t *session)
char * switch_core_session_get_uuid(_In_ switch_core_session_t *session)
Retrieve the unique identifier from a session.
switch_size_t jb_packet_count
#define SWITCH_RTCP_VIDEO_INTERVAL_MSEC
uint32_t switch_channel_test_cap(switch_channel_t *channel, switch_channel_cap_t cap)
switch_status_t switch_core_codec_encode_video(switch_codec_t *codec, switch_frame_t *frame)
Encode video data using a codec handle.
switch_size_t skip_packet_count
void switch_rtp_set_cng_pt(switch_rtp_t *rtp_session, switch_payload_t pt)
Set the payload type for comfort noise.
void switch_channel_set_app_flag_key(const char *app, switch_channel_t *channel, uint32_t flags)
#define SWITCH_LOCAL_MEDIA_IP_VARIABLE
#define switch_str_nil(s)
Make a null string a blank string instead.
struct fspr_thread_mutex_t switch_mutex_t
void switch_mux_channels(int16_t *data, switch_size_t samples, uint32_t orig_channels, uint32_t channels)
switch_status_t switch_core_timer_next(switch_timer_t *timer)
Wait for one cycle on an existing timer.
switch_bool_t switch_core_session_transcoding(switch_core_session_t *session_a, switch_core_session_t *session_b, switch_media_type_t type)
static int switch_channel_var_true(switch_channel_t *channel, const char *variable)
switch_status_t switch_core_codec_init_with_bitrate(switch_codec_t *codec, const char *codec_name, const char *fmtp, const char *modname, uint32_t rate, int ms, int channels, uint32_t bitrate, uint32_t flags, const switch_codec_settings_t *codec_settings, switch_memory_pool_t *pool)
int switch_thread_equal(switch_thread_id_t tid1, switch_thread_id_t tid2)
Compare two thread ids.
void switch_rtp_clear_flag(switch_rtp_t *rtp_session, switch_rtp_flag_t flag)
Clear an RTP Flag.
const char * switch_channel_get_variable_partner(switch_channel_t *channel, const char *varname)
switch_core_video_thread_callback_func_t video_read_callback
dtls_fingerprint_t remote_dtls_fingerprint
switch_status_t switch_frame_buffer_push(switch_frame_buffer_t *fb, void *ptr)
switch_port_t switch_rtp_request_port(const char *ip)
Request a new port to be used for media.
#define SWITCH_R_SDP_VARIABLE
switch_io_write_frame_t write_frame
uint32_t samples_per_packet
void switch_rtp_set_flag(switch_rtp_t *rtp_session, switch_rtp_flag_t flag)
Set an RTP Flag.
char * remote_file_selector
#define switch_channel_down(_channel)
uint8_t number_of_channels
uint32_t samples_per_second
#define SWITCH_CRYPTO_MKI_MAX
char * switch_rtp_get_remote_host(switch_rtp_t *rtp_session)
switch_memory_pool_t * pool
char * local_accept_wrapped_types
switch_status_t
Common return values.
switch_timer_t * switch_rtp_get_media_timer(switch_rtp_t *rtp_session)
void * switch_channel_get_private(switch_channel_t *channel, const char *key)
Retrieve private from a given channel.
#define switch_goto_status(_status, _label)
uint32_t switch_rtp_get_ssrc(switch_rtp_t *rtp_session)
Retrieve the SSRC from a given RTP session.
switch_size_t switch_rtp_dequeue_dtmf(switch_rtp_t *rtp_session, switch_dtmf_t *dtmf)
Retrieve DTMF digits from a given RTP session.
void switch_rtp_flush(switch_rtp_t *rtp_session)
switch_status_t switch_ivr_unhold(switch_core_session_t *session)
Signal the session with a protocol specific unhold message.
switch_status_t switch_core_session_write_encoded_video_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
const switch_codec_implementation_t * imp
void switch_core_session_lock_codec_write(_In_ switch_core_session_t *session)
switch_status_t switch_frame_buffer_create(switch_frame_buffer_t **fbP, switch_size_t qlen)
int8_t engine_function_running
char * remote_rtp_ice_addr
switch_frame_t text_frame
void switch_rtp_break(switch_rtp_t *rtp_session)
void switch_rtp_reset_jb(switch_rtp_t *rtp_session)
void switch_img_fill(switch_image_t *img, int x, int y, int w, int h, switch_rgb_color_t *color)
Fill image with color.
An abstraction of a rtcp frame.
switch_payload_t ianacode
#define switch_core_session_locate(uuid_str)
Locate a session based on it's uuid.
switch_rtp_flag_t
RTP Related Flags.
#define SWITCH_B_SDP_VARIABLE
void switch_rtp_get_random(void *buf, uint32_t len)
switch_status_t switch_rtp_queue_rfc2833(switch_rtp_t *rtp_session, const switch_dtmf_t *dtmf)
Queue RFC2833 DTMF data into an RTP Session.
#define MAX_CAND_IDX_COUNT
void switch_rtp_set_default_payload(switch_rtp_t *rtp_session, switch_payload_t payload)
Set the default payload number for a given RTP session.
#define switch_event_create(event, id)
Create a new event assuming it will not be custom event and therefore hiding the unused parameters...
uint32_t encoded_bytes_per_packet
char * cand_acl[SWITCH_MAX_CAND_ACL]
switch_size_t flush_packet_count
switch_byte_t * text_write_frame_data
Node in which to store custom video_write_frame channel callback hooks.
switch_port_t adv_sdp_port
switch_frame_t enc_write_frame
struct fspr_thread_cond_t switch_thread_cond_t
#define switch_event_get_header(_e, _h)
#define SWITCH_REMOTE_VIDEO_PORT_VARIABLE
#define switch_channel_set_flag(_c, _f)
#define SWITCH_IMG_FMT_I420
switch_thread_t * media_thread
#define SWITCH_MEDIA_TYPE_TOTAL
void switch_rtp_clear_flags(switch_rtp_t *rtp_session, switch_rtp_flag_t flags[SWITCH_RTP_FLAG_INVALID])
uint32_t max_missed_packets
switch_status_t(* switch_core_video_thread_callback_func_t)(switch_core_session_t *session, switch_frame_t *frame, void *user_data)
switch_io_read_video_frame_t read_video_frame
int switch_rtp_write_frame(switch_rtp_t *rtp_session, switch_frame_t *frame)
Write data to a given RTP session.
switch_size_t media_packet_count
switch_rtp_stats_t * switch_rtp_get_stats(switch_rtp_t *rtp_session, switch_memory_pool_t *pool)
switch_call_direction_t switch_channel_direction(switch_channel_t *channel)
switch_codec_implementation_t read_impl
#define switch_set_string(_dst, _src)
const char * interface_name
#define SWITCH_REMOTE_MEDIA_PORT_VARIABLE
switch_status_t switch_rtp_set_video_buffer_size(switch_rtp_t *rtp_session, uint32_t frames, uint32_t max_frames)
switch_port_t remote_rtcp_port
switch_status_t(* switch_core_text_thread_callback_func_t)(switch_core_session_t *session, switch_frame_t *frame, void *user_data)
switch_status_t switch_rtp_change_interval(switch_rtp_t *rtp_session, uint32_t ms_per_packet, uint32_t samples_per_interval)
struct switch_io_event_hook_write_frame * next
int is_chosen[MAX_CAND_IDX_COUNT]
switch_status_t switch_rtp_debug_jitter_buffer(switch_rtp_t *rtp_session, const char *name)
time_t switch_epoch_time_now(time_t *t)
Get the current epoch time.
switch_rtp_bug_flag_t rtp_bugs
switch_status_t switch_core_session_set_write_codec(_In_ switch_core_session_t *session, switch_codec_t *codec)
Assign the write codec to a given session.
#define switch_core_session_alloc(_session, _memory)
Allocate memory from a session's pool.
switch_status_t switch_queue_push(switch_queue_t *queue, void *data)
switch_status_t switch_rtp_enable_vad(switch_rtp_t *rtp_session, switch_core_session_t *session, switch_codec_t *codec, switch_vad_flag_t flags)
Enable VAD on an RTP Session.
void switch_rtp_release_port(const char *ip, switch_port_t port)
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
void switch_channel_clear_flag_recursive(switch_channel_t *channel, switch_channel_flag_t flag)
static switch_bool_t switch_core_codec_ready(switch_codec_t *codec)
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
const char * switch_stristr(const char *instr, const char *str)
void switch_core_session_unset_read_codec(_In_ switch_core_session_t *session)
uint32_t switch_rtp_test_flag(switch_rtp_t *rtp_session, switch_rtp_flag_t flags)
Test an RTP Flag.
switch_status_t switch_threadattr_create(switch_threadattr_t **new_attr, switch_memory_pool_t *pool)
switch_status_t switch_thread_create(switch_thread_t **new_thread, switch_threadattr_t *attr, switch_thread_start_t func, void *data, switch_memory_pool_t *cont)
A table of settings and callbacks that define a paticular implementation of a codec.
switch_io_write_video_frame_t write_video_frame
switch_msrp_session_t * switch_msrp_session_new(switch_memory_pool_t *pool, const char *call_id, switch_bool_t secure)
switch_bool_t T38FaxFillBitRemoval
switch_port_t remote_sdp_port
void switch_core_session_unlock_codec_write(_In_ switch_core_session_t *session)
switch_endpoint_interface_t * endpoint_interface
unsigned char raw_key[SWITCH_RTP_MAX_CRYPTO_LEN]
static int switch_false(const char *expr)
Evaluate the falsefullness of a string expression.
struct fspr_pool_t switch_memory_pool_t
uint32_t switch_core_media_bug_test_flag(_In_ switch_media_bug_t *bug, _In_ uint32_t flag)
Test for the existance of a flag on an media bug.
#define switch_channel_up_nosig(_channel)
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session's pool.
int chosen[MAX_CAND_IDX_COUNT]
switch_thread_id_t switch_thread_self(void)
void switch_event_destroy(switch_event_t **event)
Destroy an event.
switch_port_t remote_rtcp_ice_port
switch_status_t switch_thread_cond_broadcast(switch_thread_cond_t *cond)
int red_buflen[MAX_RED_FRAMES]
switch_port_t proxy_sdp_port
switch_bool_t switch_core_check_dtls_pem(const char *file)
switch_status_t switch_rtp_queue_rfc2833_in(switch_rtp_t *rtp_session, const switch_dtmf_t *dtmf)
Queue RFC2833 DTMF data into an RTP Session.
switch_rtp_crypto_key_param_method_type_t method
void switch_rtp_kill_socket(switch_rtp_t *rtp_session)
Kill the socket on an existing RTP session.
int switch_core_gen_certs(const char *prefix)
static uint32_t switch_round_to_step(uint32_t num, uint32_t step)
switch_status_t switch_channel_wait_for_flag(switch_channel_t *channel, switch_channel_flag_t want_flag, switch_bool_t pres, uint32_t to, switch_channel_t *super_channel)
void switch_channel_clear_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Clear given flag(s) from a channel.
switch_core_media_ice_type_t
int switch_channel_test_app_flag_key(const char *app, switch_channel_t *channel, uint32_t flags)
struct fspr_thread_t switch_thread_t
#define SWITCH_LOCAL_TEXT_IP_VARIABLE
#define switch_channel_set_variable(_channel, _var, _val)
void switch_rtp_video_refresh(switch_rtp_t *rtp_session)
switch_time_t switch_time_now(void)
switch_frame_t raw_write_frame
static switch_status_t ice_out(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, switch_bool_t force)
char * switch_strip_spaces(char *str, switch_bool_t dup)
switch_codec_implementation_t write_impl
switch_rtp_crypto_key_type_t crypto_type
#define SWITCH_BUFFER_BLOCK_FRAMES
switch_size_t switch_buffer_inuse(_In_ switch_buffer_t *buffer)
Get the in use amount of a switch_buffer_t.
switch_status_t switch_channel_api_on(switch_channel_t *channel, const char *variable_prefix)
void switch_buffer_destroy(switch_buffer_t **buffer)
Destroy the buffer.
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.
switch_status_t switch_ivr_hold_uuid(const char *uuid, const char *message, switch_bool_t moh)
Signal the session with a protocol specific hold message.
switch_status_t switch_rtp_req_bitrate(switch_rtp_t *rtp_session, uint32_t bps)
SWITCH_BEGIN_EXTERN_C char * switch_mprintf(const char *zFormat,...)
#define SWITCH_READ_ACCEPTABLE(status)
switch_status_t switch_stun_lookup(char **ip, switch_port_t *port, char *stunip, switch_port_t stunport, char **err, switch_memory_pool_t *pool)
Perform a stun lookup.
switch_status_t switch_rtcp_zerocopy_read_frame(switch_rtp_t *rtp_session, switch_rtcp_frame_t *frame)
Read RTCP data from a given RTP session without copying.
void switch_rtp_set_interdigit_delay(switch_rtp_t *rtp_session, uint32_t delay)
switch_status_t(* switch_io_read_text_frame_t)(switch_core_session_t *, switch_frame_t **, switch_io_flag_t, int)
switch_status_t switch_core_session_set_write_impl(switch_core_session_t *session, const switch_codec_implementation_t *impp)
#define switch_channel_media_up(_channel)
void * switch_buffer_get_head_pointer(switch_buffer_t *buffer)
switch_status_t switch_rtp_sync_stats(switch_rtp_t *rtp_session)
switch_buffer_t * text_line_buffer
#define SWITCH_CHANNEL_CHANNEL_LOG(x)
switch_memory_pool_t * switch_core_session_get_pool(_In_ switch_core_session_t *session)
Retrieve the memory pool from a session.
switch_status_t switch_rtp_add_crypto_key(switch_rtp_t *rtp_session, switch_rtp_crypto_direction_t direction, uint32_t index, switch_secure_settings_t *ssec)
#define switch_resample_create(_n, _fr, _tr, _ts, _q, _c)
void switch_core_session_unlock_codec_read(_In_ switch_core_session_t *session)
uint32_t switch_resample_process(switch_audio_resampler_t *resampler, int16_t *src, uint32_t srclen)
Resample one float buffer into another using specifications of a given handle.
switch_status_t switch_msrp_start_client(switch_msrp_session_t *msrp_session)
uint8_t try_hardware_encoder
switch_io_write_text_frame_t write_text_frame
#define SWITCH_REMOTE_VIDEO_IP_VARIABLE
switch_byte_t * red_buf[MAX_RED_FRAMES]
switch_status_t switch_core_codec_control(switch_codec_t *codec, switch_codec_control_command_t cmd, switch_codec_control_type_t ctype, void *cmd_data, switch_codec_control_type_t atype, void *cmd_arg, switch_codec_control_type_t *rtype, void **ret_data)
send control data using a codec handle
switch_status_t switch_core_session_set_real_read_codec(_In_ switch_core_session_t *session, switch_codec_t *codec)
Assign the original read codec to a given session. This is the read codec used by an endpoint...
switch_status_t switch_core_timer_sync(switch_timer_t *timer)
switch_size_t cng_packet_count
switch_rtp_crypto_key_type_t type
switch_frame_t text_write_frame
switch_jb_t * switch_core_session_get_jb(switch_core_session_t *session, switch_media_type_t type)
switch_rtp_crypto_key_type_t crypto_type
struct switch_crypto_key_material_s * remote_key_material_next