FreeSWITCH API Documentation  1.7.0
switch_core_media.c
Go to the documentation of this file.
1 /*
2  * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3  * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
4  *
5  * Version: MPL 1.1
6  *
7  * The contents of this file are subject to the Mozilla Public License Version
8  * 1.1 (the "License"); you may not use this file except in compliance with
9  * the License. You may obtain a copy of the License at
10  * http://www.mozilla.org/MPL/
11  *
12  * Software distributed under the License is distributed on an "AS IS" basis,
13  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14  * for the specific language governing rights and limitations under the
15  * License.
16  *
17  * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
18  *
19  * The Initial Developer of the Original Code is
20  * Anthony Minessale II <anthm@freeswitch.org>
21  * Portions created by the Initial Developer are Copyright (C)
22  * the Initial Developer. All Rights Reserved.
23  *
24  * Contributor(s):
25  *
26  * Anthony Minessale II <anthm@freeswitch.org>
27  *
28  * switch_core_media.c -- Core Media
29  *
30  */
31 
32 #include <switch.h>
33 #include <switch_ssl.h>
34 #include <switch_stun.h>
35 #include <switch_nat.h>
37 #include <switch_curl.h>
38 #include <errno.h>
39 #include <sofia-sip/sdp.h>
40 #include <sofia-sip/su.h>
41 
42 static switch_t38_options_t * switch_core_media_process_udptl(switch_core_session_t *session, sdp_session_t *sdp, sdp_media_t *m);
43 static void switch_core_media_find_zrtp_hash(switch_core_session_t *session, sdp_session_t *sdp);
44 static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *session, const char *codec_string, sdp_session_t *sdp, switch_sdp_type_t sdp_type);
45 static void gen_ice(switch_core_session_t *session, switch_media_type_t type, const char *ip, switch_port_t port);
46 //#define GOOGLE_ICE
47 #define RTCP_MUX
48 #define MAX_CODEC_CHECK_FRAMES 50//x:mod_sofia.h
49 #define MAX_MISMATCH_FRAMES 5//x:mod_sofia.h
50 #define type2str(type) type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio"
51 #define VIDEO_REFRESH_FREQ 1000000
52 
53 typedef enum {
54  SMF_INIT = (1 << 0),
55  SMF_READY = (1 << 1),
56  SMF_JB_PAUSED = (1 << 2)
57 } smh_flag_t;
58 
59 
60 typedef struct secure_settings_s {
68 
69 typedef struct core_video_globals_s {
70  int cpu_count;
71  int cur_cpu;
74  uint32_t fps;
75  uint32_t synced;
77 
79 
80 struct media_helper {
86  int up;
87 };
88 
89 typedef enum {
94 
95 typedef struct switch_rtp_engine_s {
98 
100 
105 
108 
111  uint32_t check_frames;
112  uint32_t mismatch_count;
113  uint32_t last_codec_ms;
117  uint32_t ssrc;
118  uint32_t remote_ssrc;
121 
122 
125  char *adv_sdp_ip;
129 
130 
131  /** ZRTP **/
134 
138 
139  uint32_t timestamp_send;
140 
143 
146 
147  int8_t rtcp_mux;
148 
151 
154 
157 
158  struct media_helper mh;
160 
161 
162  uint8_t reset_codec;
164 
165  uint8_t fir;
166  uint8_t pli;
167  uint8_t nack;
168  uint8_t tmmbr;
169  uint8_t no_crypto;
175  uint8_t new_ice;
176  uint8_t new_dtls;
177  uint32_t sdp_bw;
178  uint8_t reject_avp;
180 
192 
194  char *origin;
195 
199 
207 
209  uint32_t num_rates;
210 
211  uint32_t owner_id;
212  uint32_t session_id;
213 
215 
216  char *msid;
217  char *cname;
218 
232 
233  uint64_t vid_frames;
234  time_t vid_started;
236 
239 };
240 
242  { "AEAD_AES_256_GCM_8", AEAD_AES_256_GCM_8, 44},
243  { "AEAD_AES_128_GCM_8", AEAD_AES_128_GCM_8, 28},
244  { "AES_CM_256_HMAC_SHA1_80", AES_CM_256_HMAC_SHA1_80, 46},
245  { "AES_CM_192_HMAC_SHA1_80", AES_CM_192_HMAC_SHA1_80, 38},
246  { "AES_CM_128_HMAC_SHA1_80", AES_CM_128_HMAC_SHA1_80, 30},
247  { "AES_CM_256_HMAC_SHA1_32", AES_CM_256_HMAC_SHA1_32, 46},
248  { "AES_CM_192_HMAC_SHA1_32", AES_CM_192_HMAC_SHA1_32, 38},
249  { "AES_CM_128_HMAC_SHA1_32", AES_CM_128_HMAC_SHA1_32, 30},
250  { "AES_CM_128_NULL_AUTH", AES_CM_128_NULL_AUTH, 30}
251 };
252 
254 {
255  int i;
256 
257  for (i = 0; i < CRYPTO_INVALID; i++) {
258  if (!strncasecmp(str, SUITES[i].name, strlen(SUITES[i].name))) {
259  return SUITES[i].type;
260  }
261  }
262 
263  return CRYPTO_INVALID;
264 }
265 
266 
268 {
270  return SUITES[type].name;
271 }
272 
273 
275 {
277  return SUITES[type].keylen;
278 }
279 
280 static inline switch_media_flow_t sdp_media_flow(unsigned in)
281 {
282  switch(in) {
283  case sdp_sendonly:
285  case sdp_recvonly:
287  case sdp_sendrecv:
289  case sdp_inactive:
291  }
292 
294 }
295 
296 static int get_channels(const char *name, int dft)
297 {
298 
299  if (!zstr(name) && !switch_true(switch_core_get_variable("NDLB_broken_opus_sdp")) && !strcasecmp(name, "opus")) {
300  return 2; /* IKR???*/
301  }
302 
303  return dft ? dft : 1;
304 }
305 
307 {
308  switch_rtp_engine_t *aleg_engine;
309  switch_rtp_engine_t *bleg_engine;
310 
311  if (!aleg_session->media_handle || !bleg_session->media_handle) return;
312  aleg_engine = &aleg_session->media_handle->engines[type];
313  bleg_engine = &bleg_session->media_handle->engines[type];
314 
315 
316 
318  "Deciding whether to pass zrtp-hash between a-leg and b-leg\n");
319 
320  if (!(switch_channel_test_flag(aleg_session->channel, CF_ZRTP_PASSTHRU_REQ))) {
322  "CF_ZRTP_PASSTHRU_REQ not set on a-leg, so not propagating zrtp-hash\n");
323  return;
324  }
325 
326  if (aleg_engine->remote_sdp_zrtp_hash) {
327  switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(aleg_session->channel), SWITCH_LOG_DEBUG, "Passing a-leg remote zrtp-hash (audio) to b-leg\n");
328  bleg_engine->local_sdp_zrtp_hash = switch_core_session_strdup(bleg_session, aleg_engine->remote_sdp_zrtp_hash);
329  switch_channel_set_variable(bleg_session->channel, "l_sdp_audio_zrtp_hash", bleg_engine->local_sdp_zrtp_hash);
330  }
331 
332  if (bleg_engine->remote_sdp_zrtp_hash) {
333  switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(aleg_session->channel), SWITCH_LOG_DEBUG, "Passing b-leg remote zrtp-hash (audio) to a-leg\n");
334  aleg_engine->local_sdp_zrtp_hash = switch_core_session_strdup(aleg_session, bleg_engine->remote_sdp_zrtp_hash);
335  switch_channel_set_variable(aleg_session->channel, "l_sdp_audio_zrtp_hash", aleg_engine->local_sdp_zrtp_hash);
336  }
337 }
338 
340 {
342  time_t now;
343  uint32_t fps;
344 
345  switch_assert(session);
346 
347  if (!(smh = session->media_handle)) {
348  return SWITCH_STATUS_FALSE;
349  }
350 
351  if (!switch_channel_test_flag(session->channel, CF_VIDEO)) {
352  return 0;
353  }
354 
355  now = switch_epoch_time_now(NULL);
356 
357  if (!(smh->vid_started && smh->vid_frames && smh->vid_started < now)) {
358  return 0;
359  }
360 
361  fps = switch_round_to_step(smh->vid_frames / (now - smh->vid_started), 5);
362 
363  if (smh->vid_frames > 1000) {
364  smh->vid_started = switch_epoch_time_now(NULL);
365  smh->vid_frames = 1;
366  }
367 
368  if (fps > 0) {
369  video_globals.fps = fps;
370 
371  if (smh->vid_params.fps != fps) {
372  switch_channel_set_variable_printf(session->channel, "video_fps", "%d", fps);
373  smh->vid_params.fps = fps;
374  }
375  }
376 
377  return fps;
378 }
379 
381 {
382  _switch_core_media_pass_zrtp_hash2(aleg_session, bleg_session, SWITCH_MEDIA_TYPE_AUDIO);
383  _switch_core_media_pass_zrtp_hash2(aleg_session, bleg_session, SWITCH_MEDIA_TYPE_VIDEO);
384 }
385 
386 
388 {
390 
391  switch_core_session_t *other_session;
392  switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG1, "Deciding whether to pass zrtp-hash between legs\n");
394  switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG1, "CF_ZRTP_PASSTHRU_REQ not set, so not propagating zrtp-hash\n");
395  return;
396  } else if (!(switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS)) {
397  switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG1, "No partner channel found, so not propagating zrtp-hash\n");
398  return;
399  } else {
400  switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG1, "Found peer channel; propagating zrtp-hash if set\n");
401  switch_core_media_pass_zrtp_hash2(session, other_session);
402  switch_core_session_rwunlock(other_session);
403  }
404 }
405 
407 {
408  switch_rtp_engine_t *engine;
409  if (!session->media_handle) return NULL;
410 
411  engine = &session->media_handle->engines[type];
412 
413  if (local) {
414  return engine->local_sdp_zrtp_hash;
415  }
416 
417 
418  return engine->remote_sdp_zrtp_hash;
419 
420 }
421 
422 static void switch_core_media_find_zrtp_hash(switch_core_session_t *session, sdp_session_t *sdp)
423 {
425  switch_rtp_engine_t *audio_engine;
426  switch_rtp_engine_t *video_engine;
427  sdp_media_t *m;
428  sdp_attribute_t *attr;
429  int got_audio = 0, got_video = 0;
430 
431  if (!session->media_handle) return;
432 
433  audio_engine = &session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO];
434  video_engine = &session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO];
435 
436 
437  switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG1, "Looking for zrtp-hash\n");
438  for (m = sdp->sdp_media; m; m = m->m_next) {
439  if (got_audio && got_video) break;
440  if (m->m_port && ((m->m_type == sdp_media_audio && !got_audio)
441  || (m->m_type == sdp_media_video && !got_video))) {
442  for (attr = m->m_attributes; attr; attr = attr->a_next) {
443  if (zstr(attr->a_name)) continue;
444  if (strcasecmp(attr->a_name, "zrtp-hash") || !(attr->a_value)) continue;
445  if (m->m_type == sdp_media_audio) {
447  "Found audio zrtp-hash; setting r_sdp_audio_zrtp_hash=%s\n", attr->a_value);
448  switch_channel_set_variable(channel, "r_sdp_audio_zrtp_hash", attr->a_value);
449  audio_engine->remote_sdp_zrtp_hash = switch_core_session_strdup(session, attr->a_value);
450  got_audio++;
451  } else if (m->m_type == sdp_media_video) {
453  "Found video zrtp-hash; setting r_sdp_video_zrtp_hash=%s\n", attr->a_value);
454  switch_channel_set_variable(channel, "r_sdp_video_zrtp_hash", attr->a_value);
455  video_engine->remote_sdp_zrtp_hash = switch_core_session_strdup(session, attr->a_value);
456  got_video++;
457  }
459  break;
460  }
461  }
462  }
463 }
464 
465 
466 static switch_t38_options_t * switch_core_media_process_udptl(switch_core_session_t *session, sdp_session_t *sdp, sdp_media_t *m)
467 {
468  switch_t38_options_t *t38_options = switch_channel_get_private(session->channel, "t38_options");
469  sdp_attribute_t *attr;
470 
471  switch_assert(sdp);
472 
473  if (!t38_options) {
474  t38_options = switch_core_session_alloc(session, sizeof(switch_t38_options_t));
475 
476  // set some default value
477  t38_options->T38FaxVersion = 0;
478  t38_options->T38MaxBitRate = 14400;
479  t38_options->T38FaxRateManagement = switch_core_session_strdup(session, "transferredTCF");
480  t38_options->T38FaxUdpEC = switch_core_session_strdup(session, "t38UDPRedundancy");
481  t38_options->T38FaxMaxBuffer = 500;
482  t38_options->T38FaxMaxDatagram = 500;
483  }
484 
485  t38_options->remote_port = (switch_port_t)m->m_port;
486 
487  if (sdp->sdp_origin) {
488  t38_options->sdp_o_line = switch_core_session_strdup(session, sdp->sdp_origin->o_username);
489  } else {
490  t38_options->sdp_o_line = "unknown";
491  }
492 
493  if (m->m_connections && m->m_connections->c_address) {
494  t38_options->remote_ip = switch_core_session_strdup(session, m->m_connections->c_address);
495  } else if (sdp->sdp_connection && sdp->sdp_connection->c_address) {
496  t38_options->remote_ip = switch_core_session_strdup(session, sdp->sdp_connection->c_address);
497  }
498 
499  for (attr = m->m_attributes; attr; attr = attr->a_next) {
500  if (!strcasecmp(attr->a_name, "T38FaxVersion") && attr->a_value) {
501  t38_options->T38FaxVersion = (uint16_t) atoi(attr->a_value);
502  } else if (!strcasecmp(attr->a_name, "T38MaxBitRate") && attr->a_value) {
503  t38_options->T38MaxBitRate = (uint32_t) atoi(attr->a_value);
504  } else if (!strcasecmp(attr->a_name, "T38FaxFillBitRemoval")) {
505  t38_options->T38FaxFillBitRemoval = switch_safe_atoi(attr->a_value, 1);
506  } else if (!strcasecmp(attr->a_name, "T38FaxTranscodingMMR")) {
507  t38_options->T38FaxTranscodingMMR = switch_safe_atoi(attr->a_value, 1);
508  } else if (!strcasecmp(attr->a_name, "T38FaxTranscodingJBIG")) {
509  t38_options->T38FaxTranscodingJBIG = switch_safe_atoi(attr->a_value, 1);
510  } else if (!strcasecmp(attr->a_name, "T38FaxRateManagement") && attr->a_value) {
511  t38_options->T38FaxRateManagement = switch_core_session_strdup(session, attr->a_value);
512  } else if (!strcasecmp(attr->a_name, "T38FaxMaxBuffer") && attr->a_value) {
513  t38_options->T38FaxMaxBuffer = (uint32_t) atoi(attr->a_value);
514  } else if (!strcasecmp(attr->a_name, "T38FaxMaxDatagram") && attr->a_value) {
515  t38_options->T38FaxMaxDatagram = (uint32_t) atoi(attr->a_value);
516  } else if (!strcasecmp(attr->a_name, "T38FaxUdpEC") && attr->a_value) {
517  t38_options->T38FaxUdpEC = switch_core_session_strdup(session, attr->a_value);
518  } else if (!strcasecmp(attr->a_name, "T38VendorInfo") && attr->a_value) {
519  t38_options->T38VendorInfo = switch_core_session_strdup(session, attr->a_value);
520  }
521  }
522 
523  switch_channel_set_variable(session->channel, "has_t38", "true");
524  switch_channel_set_private(session->channel, "t38_options", t38_options);
526 
527  switch_channel_execute_on(session->channel, "sip_execute_on_image");
528  switch_channel_api_on(session->channel, "sip_api_on_image");
529 
530  return t38_options;
531 }
532 
534 {
535  switch_rtp_engine_t *a_engine;
536  switch_rtp_engine_t *v_engine;
538  const char *val;
539  int x = 0;
540 
541  switch_assert(session);
542 
543  if (!(smh = session->media_handle)) {
544  return SWITCH_STATUS_FALSE;
545  }
546 
547  a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
548  v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
549 
551  !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")) && switch_true(val)) &&
552  !switch_channel_test_flag(session->channel, CF_AVPF)) {
553  /* Reactivate the NAT buster flag. */
554 
555  if (a_engine->rtp_session) {
557  x++;
558  }
559 
560  if (v_engine->rtp_session) {
562  x++;
563  }
564  }
565 
567 }
568 
570 {
572 
573  switch_assert(session);
574 
575  if (!(smh = session->media_handle)) {
576  return SWITCH_STATUS_FALSE;
577  }
578 
579  *vid_params = smh->vid_params;
580 
581  return SWITCH_STATUS_SUCCESS;
582 }
583 
585 {
586  sdp_media_t *m;
587  sdp_parser_t *parser = NULL;
588  sdp_session_t *sdp;
589  switch_t38_options_t *t38_options = NULL;
590 
591  if (!(parser = sdp_parse(NULL, r_sdp, (int) strlen(r_sdp), 0))) {
592  return NULL;
593  }
594 
595  if (!(sdp = sdp_session(parser))) {
596  sdp_parser_free(parser);
597  return NULL;
598  }
599 
600  for (m = sdp->sdp_media; m; m = m->m_next) {
601  if (m->m_proto == sdp_proto_udptl && m->m_type == sdp_media_image && m->m_port) {
602  t38_options = switch_core_media_process_udptl(session, sdp, m);
603  break;
604  }
605  }
606 
607  sdp_parser_free(parser);
608 
609  return t38_options;
610 
611 }
612 
613 
614 
615 //?
617  switch_core_session_t *other_session, switch_t38_options_t *t38_options)
618 {
619  char *remote_host;
620  switch_port_t remote_port;
621  char tmp[32] = "";
622  switch_rtp_engine_t *a_engine;
624 
625  switch_assert(session);
626 
627  if (!(smh = session->media_handle)) {
628  return SWITCH_STATUS_FALSE;
629  }
630 
631  a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
632 
633  remote_host = switch_rtp_get_remote_host(a_engine->rtp_session);
634  remote_port = switch_rtp_get_remote_port(a_engine->rtp_session);
635 
636  a_engine->cur_payload_map->remote_sdp_ip = switch_core_session_strdup(session, t38_options->remote_ip);
637  a_engine->cur_payload_map->remote_sdp_port = t38_options->remote_port;
638 
639  if (remote_host && remote_port && !strcmp(remote_host, a_engine->cur_payload_map->remote_sdp_ip) &&
640  remote_port == a_engine->cur_payload_map->remote_sdp_port) {
642  "Audio params are unchanged for %s.\n",
643  switch_channel_get_name(session->channel));
644  } else {
645  const char *err = NULL;
646 
648  "Audio params changed for %s from %s:%d to %s:%d\n",
649  switch_channel_get_name(session->channel),
650  remote_host, remote_port, a_engine->cur_payload_map->remote_sdp_ip, a_engine->cur_payload_map->remote_sdp_port);
651 
652  switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->cur_payload_map->remote_sdp_port);
657  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", err);
659  }
660  }
661 
662  switch_core_media_copy_t38_options(t38_options, other_session);
663 
664  return SWITCH_STATUS_SUCCESS;
665 
666 }
667 
669  switch_media_type_t type,
670  const char *iananame,
671  uint32_t rate,
672  switch_payload_t *ptP,
673  switch_payload_t *recv_ptP,
674  char **fmtpP)
675 {
676  payload_map_t *pmap;
678  switch_rtp_engine_t *engine;
679  switch_payload_t pt = 0, recv_pt = 0;
680  int found = 0;
681  char *fmtp = NULL;
682 
683  switch_assert(session);
684 
685  if (!(smh = session->media_handle)) {
686  return SWITCH_STATUS_FALSE;
687  }
688 
689  engine = &smh->engines[type];
690 
692  for (pmap = engine->payload_map; pmap ; pmap = pmap->next) {
693 
694  if (!pmap->allocated) continue;
695 
696  if (!strcasecmp(pmap->iananame, iananame) && (!rate || (rate == pmap->rate))) {
697  pt = pmap->pt;
698  recv_pt = pmap->recv_pt;
699  fmtp = pmap->rm_fmtp;
700  found++;
701  break;
702  }
703  }
705 
706  if (found) {
707  if (ptP) {
708  *ptP = pt;
709  }
710  if (recv_ptP) {
711  *recv_ptP = recv_pt;
712  }
713 
714  if (!zstr(fmtp) && fmtpP) {
715  *fmtpP = fmtp;
716  }
717 
718  return SWITCH_STATUS_SUCCESS;
719  }
720 
721  return SWITCH_STATUS_FALSE;
722 
723 }
724 
725 
727  switch_media_type_t type,
728  const char *name,
729  const char *modname,
730  const char *fmtp,
731  switch_sdp_type_t sdp_type,
732  uint32_t pt,
733  uint32_t rate,
734  uint32_t ptime,
735  uint32_t channels,
736  uint8_t negotiated)
737 {
738  payload_map_t *pmap;
739  int exists = 0;
741  switch_rtp_engine_t *engine;
742  int local_pt = 0;
743 
744  switch_assert(session);
745 
746  if (!(smh = session->media_handle)) {
747  return NULL;
748  }
749 
750  engine = &smh->engines[type];
751 
753 
754  for (pmap = engine->payload_map; pmap && pmap->allocated; pmap = pmap->next) {
755  exists = (!strcasecmp(name, pmap->iananame) && pmap->pt == pt && (!pmap->rate || rate == pmap->rate) && (!pmap->ptime || pmap->ptime == ptime));
756 
757  if (exists) {
758 
759  if (!zstr(fmtp) && !zstr(pmap->rm_fmtp)) {
760  if (strcmp(pmap->rm_fmtp, fmtp)) {
761  exists = 0;
762  local_pt = pmap->pt;
763  continue;
764  }
765  }
766 
767  break;
768  }
769  }
770 
771 
772  if (!exists) {
773  switch_ssize_t hlen = -1;
774 
775  if (engine->payload_map && !engine->payload_map->allocated) {
776  pmap = engine->payload_map;
777  } else {
778  pmap = switch_core_alloc(session->pool, sizeof(*pmap));
779  }
780 
781  pmap->type = type;
782  pmap->iananame = switch_core_strdup(session->pool, name);
783  pmap->rm_encoding = pmap->iananame;
784  pmap->hash = switch_ci_hashfunc_default(pmap->iananame, &hlen);
785  pmap->channels = 1;
786  }
787 
788  pmap->sdp_type = sdp_type;
789 
790  if (ptime) {
791  pmap->ptime = ptime;
792  }
793 
794  if (rate) {
795  pmap->rate = rate;
796  }
797 
798  if (channels) {
799  pmap->channels = channels;
800  }
801 
802  if (modname) {
803  pmap->modname = switch_core_strdup(session->pool, modname);
804  }
805 
806  if (!zstr(fmtp) && (zstr(pmap->rm_fmtp) || strcmp(pmap->rm_fmtp, fmtp))) {
807  pmap->rm_fmtp = switch_core_strdup(session->pool, fmtp);
808  }
809 
810  pmap->allocated = 1;
811 
812  pmap->recv_pt = (switch_payload_t) pt;
813 
814 
815  if (sdp_type == SDP_TYPE_REQUEST || !exists) {
816  pmap->pt = (switch_payload_t) (local_pt ? local_pt : pt);
817  }
818 
819  if (negotiated) {
820  pmap->negotiated = negotiated;
821  }
822 
823  if (!exists) {
824  if (pmap == engine->payload_map) {
825  engine->pmap_tail = pmap;
826  } else if (!engine->payload_map) {
827  engine->payload_map = engine->pmap_tail = pmap;
828  } else {
829  engine->pmap_tail->next = pmap;
830  engine->pmap_tail = engine->pmap_tail->next;
831  }
832  }
833 
835 
836  return pmap;
837 }
838 
839 
840 
841 
843 {
844  const char *preferred = NULL, *fallback = NULL;
846 
847  switch_assert(session);
848 
849  if (!(smh = session->media_handle)) {
850  preferred = "PCMU";
851  fallback = "PCMU";
852  } else {
853 
854  if (!(preferred = switch_channel_get_variable(session->channel, "absolute_codec_string"))) {
855  preferred = switch_channel_get_variable(session->channel, "codec_string");
856  }
857 
858  if (!preferred) {
859  if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
860  preferred = smh->mparams->outbound_codec_string;
861  fallback = smh->mparams->inbound_codec_string;
862 
863  } else {
864  preferred = smh->mparams->inbound_codec_string;
865  fallback = smh->mparams->outbound_codec_string;
866  }
867  }
868  }
869 
870  return !zstr(preferred) ? preferred : fallback;
871 }
872 
874 {
875  int i;
877 
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  "rtp_secure_media",
886  "rtp_secure_media_inbound",
887  "rtp_secure_media_outbound",
888  NULL};
889 
890  for(i = 0; vars[i] ;i++) {
891  switch_channel_set_variable(session->channel, vars[i], NULL);
892  }
893 
894  if (!(smh = session->media_handle)) {
895  return;
896  }
897  for (i = 0; i < CRYPTO_INVALID; i++) {
900  }
901 
902 }
903 
905 {
906  if (!session->media_handle) {
907  return NULL;
908  }
909 
910  return session->media_handle->engines[type].ssec[session->media_handle->engines[type].crypto_type].local_crypto_key;
911 }
912 
913 
914 
916 {
917 
918  if (switch_stristr("clear", str)) {
919  *flag_pole = 0;
920  }
921 
922  if (switch_stristr("CISCO_SKIP_MARK_BIT_2833", str)) {
923  *flag_pole |= RTP_BUG_CISCO_SKIP_MARK_BIT_2833;
924  }
925 
926  if (switch_stristr("~CISCO_SKIP_MARK_BIT_2833", str)) {
927  *flag_pole &= ~RTP_BUG_CISCO_SKIP_MARK_BIT_2833;
928  }
929 
930  if (switch_stristr("SONUS_SEND_INVALID_TIMESTAMP_2833", str)) {
932  }
933 
934  if (switch_stristr("~SONUS_SEND_INVALID_TIMESTAMP_2833", str)) {
936  }
937 
938  if (switch_stristr("IGNORE_MARK_BIT", str)) {
939  *flag_pole |= RTP_BUG_IGNORE_MARK_BIT;
940  }
941 
942  if (switch_stristr("~IGNORE_MARK_BIT", str)) {
943  *flag_pole &= ~RTP_BUG_IGNORE_MARK_BIT;
944  }
945 
946  if (switch_stristr("SEND_LINEAR_TIMESTAMPS", str)) {
947  *flag_pole |= RTP_BUG_SEND_LINEAR_TIMESTAMPS;
948  }
949 
950  if (switch_stristr("~SEND_LINEAR_TIMESTAMPS", str)) {
951  *flag_pole &= ~RTP_BUG_SEND_LINEAR_TIMESTAMPS;
952  }
953 
954  if (switch_stristr("START_SEQ_AT_ZERO", str)) {
955  *flag_pole |= RTP_BUG_START_SEQ_AT_ZERO;
956  }
957 
958  if (switch_stristr("~START_SEQ_AT_ZERO", str)) {
959  *flag_pole &= ~RTP_BUG_START_SEQ_AT_ZERO;
960  }
961 
962  if (switch_stristr("NEVER_SEND_MARKER", str)) {
963  *flag_pole |= RTP_BUG_NEVER_SEND_MARKER;
964  }
965 
966  if (switch_stristr("~NEVER_SEND_MARKER", str)) {
967  *flag_pole &= ~RTP_BUG_NEVER_SEND_MARKER;
968  }
969 
970  if (switch_stristr("IGNORE_DTMF_DURATION", str)) {
971  *flag_pole |= RTP_BUG_IGNORE_DTMF_DURATION;
972  }
973 
974  if (switch_stristr("~IGNORE_DTMF_DURATION", str)) {
975  *flag_pole &= ~RTP_BUG_IGNORE_DTMF_DURATION;
976  }
977 
978  if (switch_stristr("ACCEPT_ANY_PACKETS", str)) {
979  *flag_pole |= RTP_BUG_ACCEPT_ANY_PACKETS;
980  }
981 
982  if (switch_stristr("~ACCEPT_ANY_PACKETS", str)) {
983  *flag_pole &= ~RTP_BUG_ACCEPT_ANY_PACKETS;
984  }
985 
986  if (switch_stristr("ACCEPT_ANY_PAYLOAD", str)) {
987  *flag_pole |= RTP_BUG_ACCEPT_ANY_PAYLOAD;
988  }
989 
990  if (switch_stristr("~ACCEPT_ANY_PAYLOAD", str)) {
991  *flag_pole &= ~RTP_BUG_ACCEPT_ANY_PAYLOAD;
992  }
993 
994  if (switch_stristr("GEN_ONE_GEN_ALL", str)) {
995  *flag_pole |= RTP_BUG_GEN_ONE_GEN_ALL;
996  }
997 
998  if (switch_stristr("~GEN_ONE_GEN_ALL", str)) {
999  *flag_pole &= ~RTP_BUG_GEN_ONE_GEN_ALL;
1000  }
1001 
1002  if (switch_stristr("CHANGE_SSRC_ON_MARKER", str)) {
1003  *flag_pole |= RTP_BUG_CHANGE_SSRC_ON_MARKER;
1004  }
1005 
1006  if (switch_stristr("~CHANGE_SSRC_ON_MARKER", str)) {
1007  *flag_pole &= ~RTP_BUG_CHANGE_SSRC_ON_MARKER;
1008  }
1009 
1010  if (switch_stristr("FLUSH_JB_ON_DTMF", str)) {
1011  *flag_pole |= RTP_BUG_FLUSH_JB_ON_DTMF;
1012  }
1013 
1014  if (switch_stristr("~FLUSH_JB_ON_DTMF", str)) {
1015  *flag_pole &= ~RTP_BUG_FLUSH_JB_ON_DTMF;
1016  }
1017 
1018  if (switch_stristr("ALWAYS_AUTO_ADJUST", str)) {
1020  }
1021 
1022  if (switch_stristr("~ALWAYS_AUTO_ADJUST", str)) {
1024  }
1025 }
1026 
1027 
1029  switch_media_type_t type,
1030  int index, switch_rtp_crypto_key_type_t ctype, switch_rtp_crypto_direction_t direction, int force)
1031 {
1032  unsigned char b64_key[512] = "";
1033  unsigned char *key;
1034  const char *val;
1035  switch_channel_t *channel;
1036  char *p;
1037  switch_rtp_engine_t *engine;
1038 
1039  switch_assert(smh);
1040  channel = switch_core_session_get_channel(smh->session);
1041 
1042  engine = &smh->engines[type];
1043 
1044  if (!force && engine->ssec[ctype].local_raw_key[0]) {
1045  return SWITCH_STATUS_SUCCESS;
1046  }
1047 
1048 
1049 
1050 //#define SAME_KEY
1051 #ifdef SAME_KEY
1052  if (switch_channel_test_flag(channel, CF_AVPF) && type == SWITCH_MEDIA_TYPE_VIDEO) {
1053  if (direction == SWITCH_RTP_CRYPTO_SEND) {
1054  memcpy(engine->ssec[ctype].local_raw_key, smh->engines[SWITCH_MEDIA_TYPE_AUDIO].ssec.local_raw_key, SUITES[ctype].keylen);
1055  key = engine->ssec[ctype].local_raw_key;
1056  } else {
1057  memcpy(engine->ssec[ctype].remote_raw_key, smh->engines[SWITCH_MEDIA_TYPE_AUDIO].ssec.remote_raw_key, SUITES[ctype].keylen);
1058  key = engine->ssec[ctype].remote_raw_key;
1059  }
1060  } else {
1061 #endif
1062  if (direction == SWITCH_RTP_CRYPTO_SEND) {
1063  key = engine->ssec[ctype].local_raw_key;
1064  } else {
1065  key = engine->ssec[ctype].remote_raw_key;
1066  }
1067 
1068  switch_rtp_get_random(key, SUITES[ctype].keylen);
1069 #ifdef SAME_KEY
1070  }
1071 #endif
1072 
1073  switch_b64_encode(key, SUITES[ctype].keylen, b64_key, sizeof(b64_key));
1074  p = strrchr((char *) b64_key, '=');
1075 
1076  while (p && *p && *p == '=') {
1077  *p-- = '\0';
1078  }
1079 
1080  if (index == SWITCH_NO_CRYPTO_TAG) index = ctype + 1;
1081 
1082  engine->ssec[ctype].local_crypto_key = switch_core_session_sprintf(smh->session, "%d %s inline:%s", index, SUITES[ctype].name, b64_key);
1083  switch_channel_set_variable_name_printf(smh->session->channel, engine->ssec[ctype].local_crypto_key, "rtp_last_%s_local_crypto_key", type2str(type));
1085 
1086  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG, "Set Local %s crypto Key [%s]\n",
1087  type2str(type),
1088  engine->ssec[ctype].local_crypto_key);
1089 
1090  if (!(smh->mparams->ndlb & SM_NDLB_DISABLE_SRTP_AUTH) &&
1091  !((val = switch_channel_get_variable(channel, "NDLB_support_asterisk_missing_srtp_auth")) && switch_true(val))) {
1092  engine->ssec[ctype].crypto_type = ctype;
1093  } else {
1094  engine->ssec[ctype].crypto_type = AES_CM_128_NULL_AUTH;
1095  }
1096 
1097  return SWITCH_STATUS_SUCCESS;
1098 }
1099 
1100 
1101 
1102 
1103 
1105 {
1106  unsigned char key[SWITCH_RTP_MAX_CRYPTO_LEN];
1108  char *p;
1109 
1110 
1111  p = strchr(key_str, ' ');
1112 
1113  if (p && *p && *(p + 1)) {
1114  p++;
1115 
1117 
1118  if (type == CRYPTO_INVALID) {
1119  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error near [%s]\n", p);
1120  goto bad;
1121  }
1122 
1123  p = strchr(p, ' ');
1124  if (p && *p && *(p + 1)) {
1125  p++;
1126  if (strncasecmp(p, "inline:", 7)) {
1127  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error near [%s]\n", p);
1128  goto bad;
1129  }
1130 
1131  p += 7;
1132  switch_b64_decode(p, (char *) key, sizeof(key));
1133 
1134  if (direction == SWITCH_RTP_CRYPTO_SEND) {
1135  memcpy(ssec->local_raw_key, key, SUITES[type].keylen);
1136  } else {
1137  memcpy(ssec->remote_raw_key, key, SUITES[type].keylen);
1138  }
1139  return SWITCH_STATUS_SUCCESS;
1140  }
1141 
1142  }
1143 
1144  bad:
1145 
1147  return SWITCH_STATUS_FALSE;
1148 
1149 }
1150 
1152 {
1153  switch_rtp_engine_t *engine;
1154  if (!session->media_handle) return;
1155  engine = &session->media_handle->engines[type];
1156  engine->rtp_session = rtp_session;
1157  engine->type = type;
1158 }
1159 
1160 
1162 {
1163  const char *tmp;
1164  switch_rtp_engine_t *engine;
1165  char *keyvar, *tagvar, *ctypevar;
1166 
1167  if (!session->media_handle) return;
1168  engine = &session->media_handle->engines[type];
1169 
1170  if (type == SWITCH_MEDIA_TYPE_AUDIO) {
1171  keyvar = "srtp_remote_audio_crypto_key";
1172  tagvar = "srtp_remote_audio_crypto_tag";
1173  ctypevar = "srtp_remote_audio_crypto_type";
1174  } else {
1175  keyvar = "srtp_remote_video_crypto_key";
1176  tagvar = "srtp_remote_video_crypto_tag";
1177  ctypevar = "srtp_remote_video_crypto_type";
1178  }
1179 
1180  if ((tmp = switch_channel_get_variable(session->channel, keyvar))) {
1181  if ((tmp = switch_channel_get_variable(session->channel, ctypevar))) {
1183  }
1184 
1185  engine->ssec[engine->crypto_type].remote_crypto_key = switch_core_session_strdup(session, tmp);
1186 
1187  if ((tmp = switch_channel_get_variable(session->channel, tagvar))) {
1188  int tv = atoi(tmp);
1189  engine->ssec[engine->crypto_type].crypto_tag = tv;
1190  } else {
1191  engine->ssec[engine->crypto_type].crypto_tag = 1;
1192  }
1193 
1195  }
1196 }
1197 
1198 
1200 {
1201  switch_rtp_engine_t *engine;
1202  const char *varname;
1203 
1204  if (type == SWITCH_MEDIA_TYPE_AUDIO) {
1205  varname = "rtp_secure_audio_confirmed";
1206  } else {
1207  varname = "rtp_secure_video_confirmed";
1208  }
1209 
1210  if (!session->media_handle) return;
1211 
1212  engine = &session->media_handle->engines[type];
1213 
1215  return;
1216  }
1217 
1218  if (engine->ssec[engine->crypto_type].remote_crypto_key && switch_channel_test_flag(session->channel, CF_SECURE)) {
1220 
1221 
1223  engine->ssec[engine->crypto_type].crypto_type,
1224  engine->ssec[engine->crypto_type].local_raw_key,
1225  SUITES[engine->ssec[engine->crypto_type].crypto_type].keylen);
1226 
1228  engine->ssec[engine->crypto_type].crypto_tag,
1229  engine->ssec[engine->crypto_type].crypto_type,
1230  engine->ssec[engine->crypto_type].remote_raw_key,
1231  SUITES[engine->ssec[engine->crypto_type].crypto_type].keylen);
1232 
1233  switch_channel_set_variable(session->channel, varname, "true");
1234 
1235 
1236  switch_channel_set_variable(session->channel, "rtp_secure_media_negotiated", SUITES[engine->crypto_type].name);
1237 
1238  }
1239 
1240 }
1241 
1243 {
1244  const char *var = NULL;
1245  const char *val = NULL;
1246  char *suites = NULL;
1247  switch_media_handle_t *smh;
1248  char *fields[CRYPTO_INVALID+1];
1249  int argc = 0, i = 0, j = 0, k = 0;
1250 
1251  if (!(smh = session->media_handle)) {
1252  return;
1253  }
1254 
1255  if (switch_channel_test_flag(session->channel, CF_AVPF)) {
1256  return;
1257  }
1258 
1260  var = "rtp_secure_media_inbound";
1261  } else {
1262  var = "rtp_secure_media_outbound";
1263  }
1264 
1265  if (!(val = switch_channel_get_variable(session->channel, var))) {
1266  var = "rtp_secure_media";
1267  val = switch_channel_get_variable(session->channel, var);
1268  }
1269 
1270  if (!zstr(val) && (suites = strchr(val, ':'))) {
1271  *suites++ = '\0';
1272  }
1273 
1274  if (zstr(suites)) {
1275  suites = (char *) switch_channel_get_variable(session->channel, "rtp_secure_media_suites");
1276  }
1277 
1278  if (zstr(val)) {
1280  val = "optional";
1281  } else {
1282  val = "forbidden";
1283  }
1284  }
1285 
1286  if (!strcasecmp(val, "optional")) {
1288  } else if (switch_true(val) || !strcasecmp(val, "mandatory")) {
1290  } else {
1292  if (!switch_false(val) && strcasecmp(val, "forbidden")) {
1293  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "INVALID VALUE FOR %s defaulting to 'forbidden'\n", var);
1294  }
1295  }
1296 
1297  if (smh->crypto_mode != CRYPTO_MODE_FORBIDDEN && !zstr(suites)) {
1298  argc = switch_split((char *)suites, ':', fields);
1299 
1300  for (i = 0; i < argc; i++) {
1301  int ok = 0;
1302 
1303  for (j = 0; j < CRYPTO_INVALID; j++) {
1304  if (!strcasecmp(fields[i], SUITES[j].name)) {
1305  smh->crypto_suite_order[k++] = SUITES[j].type;
1306  ok++;
1307  break;
1308  }
1309  }
1310 
1311  if (!ok) {
1312  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "INVALID SUITE SUPPLIED\n");
1313  }
1314 
1315  }
1316  } else {
1317  for (i = 0; i < CRYPTO_INVALID; i++) {
1318  smh->crypto_suite_order[k++] = SUITES[i].type;
1319  }
1320  }
1321 }
1322 
1323 
1324 
1326  const char *varname,
1327  switch_media_type_t type, const char *crypto, int crypto_tag, switch_sdp_type_t sdp_type)
1328 {
1329  int got_crypto = 0;
1330  int i = 0;
1331  int ctype = 0;
1332  const char *vval = NULL;
1333  switch_rtp_engine_t *engine;
1334  switch_media_handle_t *smh;
1335 
1336  if (!(smh = session->media_handle)) {
1337  return 0;
1338  }
1339 
1340  if (smh->crypto_mode == CRYPTO_MODE_FORBIDDEN) {
1341  return -1;
1342  }
1343 
1344  if (switch_channel_test_flag(session->channel, CF_AVPF)) {
1345  return 0;
1346  }
1347 
1348  engine = &session->media_handle->engines[type];
1349 
1350  for (i = 0; smh->crypto_suite_order[i] != CRYPTO_INVALID; i++) {
1352 
1353  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,"looking for crypto suite [%s] in [%s]\n", SUITES[j].name, crypto);
1354 
1355  if (switch_stristr(SUITES[j].name, crypto)) {
1356  ctype = SUITES[j].type;
1357  vval = SUITES[j].name;
1358  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Found suite %s\n", vval);
1359  switch_channel_set_variable(session->channel, "rtp_secure_media_negotiated", vval);
1360  break;
1361  }
1362  }
1363 
1364  if (engine->ssec[engine->crypto_type].remote_crypto_key && switch_rtp_ready(engine->rtp_session)) {
1365  /* Compare all the key. The tag may remain the same even if key changed */
1366  if (crypto && engine->crypto_type != CRYPTO_INVALID && !strcmp(crypto, engine->ssec[engine->crypto_type].remote_crypto_key)) {
1367  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Existing key is still valid.\n");
1368  got_crypto = 1;
1369  } else {
1370  const char *a = switch_stristr("AE", engine->ssec[engine->crypto_type].remote_crypto_key);
1371  const char *b = switch_stristr("AE", crypto);
1372 
1373  if (sdp_type == SDP_TYPE_REQUEST) {
1374  if (!vval) {
1375  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Unsupported Crypto [%s]\n", crypto);
1376  goto end;
1377  }
1378  switch_channel_set_variable(session->channel, varname, vval);
1379 
1380  switch_core_media_build_crypto(session->media_handle, type, crypto_tag, ctype, SWITCH_RTP_CRYPTO_SEND, 1);
1382  engine->ssec[engine->crypto_type].local_raw_key, SUITES[ctype].keylen);
1383  }
1384 
1385  if (a && b && !strncasecmp(a, b, 23)) {
1386  engine->crypto_type = ctype;
1387 
1388  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Change Remote key to [%s]\n", crypto);
1389  engine->ssec[engine->crypto_type].remote_crypto_key = switch_core_session_strdup(session, crypto);
1390 
1391  if (engine->type == SWITCH_MEDIA_TYPE_AUDIO) {
1392  switch_channel_set_variable(session->channel, "srtp_remote_audio_crypto_key", crypto);
1393  switch_channel_set_variable_printf(session->channel, "srtp_remote_audio_crypto_tag", "%d", crypto_tag);
1394  switch_channel_set_variable_printf(session->channel, "srtp_remote_audio_crypto_type", "%s", switch_core_media_crypto_type2str(ctype));
1395  } else if (engine->type == SWITCH_MEDIA_TYPE_VIDEO) {
1396  switch_channel_set_variable(session->channel, "srtp_remote_video_crypto_key", crypto);
1397  switch_channel_set_variable_printf(session->channel, "srtp_remote_video_crypto_tag", "%d", crypto_tag);
1398  switch_channel_set_variable_printf(session->channel, "srtp_remote_video_crypto_type", "%s", switch_core_media_crypto_type2str(ctype));
1399  }
1400 
1401  engine->ssec[engine->crypto_type].crypto_tag = crypto_tag;
1402 
1403 
1404  if (switch_rtp_ready(engine->rtp_session) && switch_channel_test_flag(session->channel, CF_SECURE)) {
1407  engine->ssec[engine->crypto_type].crypto_type, engine->ssec[engine->crypto_type].remote_raw_key, SUITES[engine->ssec[engine->crypto_type].crypto_type].keylen);
1408  }
1409  got_crypto++;
1410 
1411  } else {
1412  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Ignoring unacceptable key\n");
1413  }
1414  }
1415  } else if (!switch_rtp_ready(engine->rtp_session)) {
1416 
1417  if (!vval) {
1418  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Unsupported Crypto [%s]\n", crypto);
1419  goto end;
1420  }
1421 
1422  engine->crypto_type = ctype;
1423  engine->ssec[engine->crypto_type].remote_crypto_key = switch_core_session_strdup(session, crypto);
1424  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set Remote Key [%s]\n", engine->ssec[engine->crypto_type].remote_crypto_key);
1425  if (engine->type == SWITCH_MEDIA_TYPE_AUDIO) {
1426  switch_channel_set_variable(session->channel, "srtp_remote_audio_crypto_key", crypto);
1427  switch_channel_set_variable_printf(session->channel, "srtp_remote_audio_crypto_type", "%s", switch_core_media_crypto_type2str(ctype));
1428  } else if (engine->type == SWITCH_MEDIA_TYPE_VIDEO) {
1429  switch_channel_set_variable(session->channel, "srtp_remote_video_crypto_key", crypto);
1430  switch_channel_set_variable_printf(session->channel, "srtp_remote_video_crypto_type", "%s", switch_core_media_crypto_type2str(ctype));
1431  }
1432 
1433  engine->ssec[engine->crypto_type].crypto_tag = crypto_tag;
1434  got_crypto++;
1435 
1436  switch_channel_set_variable(session->channel, varname, vval);
1438 
1439  if (zstr(engine->ssec[engine->crypto_type].local_crypto_key)) {
1440  switch_core_media_build_crypto(session->media_handle, type, crypto_tag, ctype, SWITCH_RTP_CRYPTO_SEND, 1);
1441  }
1442  }
1443 
1444  end:
1445 
1446  return got_crypto;
1447 }
1448 
1449 
1451 {
1453  switch_media_handle_t *smh;
1454  int i;
1455 
1457  return;
1458  }
1459 
1460  if (!(smh = session->media_handle)) {
1461  return;
1462  }
1463 
1465  return;
1466  }
1467 
1468  if (switch_channel_test_flag(session->channel, CF_AVPF)) {
1469  return;
1470  }
1471 
1473 
1474  for (i = 0; smh->crypto_suite_order[i] != CRYPTO_INVALID; i++) {
1475  switch_core_media_build_crypto(session->media_handle,
1477 
1478  switch_core_media_build_crypto(session->media_handle,
1480  }
1481 
1482 }
1483 
1484 #define add_stat(_i, _s) \
1485  switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", switch_str_nil(prefix), _s) ; \
1486  switch_snprintf(var_val, sizeof(var_val), "%" SWITCH_SIZE_T_FMT, _i); \
1487  switch_channel_set_variable(channel, var_name, var_val)
1488 
1489 #define add_stat_double(_i, _s) \
1490  switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", switch_str_nil(prefix), _s) ; \
1491  switch_snprintf(var_val, sizeof(var_val), "%0.2f", _i); \
1492  switch_channel_set_variable(channel, var_name, var_val)
1493 
1494 static void set_stats(switch_core_session_t *session, switch_media_type_t type, const char *prefix)
1495 {
1496  switch_rtp_stats_t *stats = switch_core_media_get_stats(session, type, NULL);
1498 
1499  char var_name[256] = "", var_val[35] = "";
1500 
1501  if (stats) {
1502  stats->inbound.std_deviation = sqrt(stats->inbound.variance);
1503 
1504  add_stat(stats->inbound.raw_bytes, "in_raw_bytes");
1505  add_stat(stats->inbound.media_bytes, "in_media_bytes");
1506  add_stat(stats->inbound.packet_count, "in_packet_count");
1507  add_stat(stats->inbound.media_packet_count, "in_media_packet_count");
1508  add_stat(stats->inbound.skip_packet_count, "in_skip_packet_count");
1509  add_stat(stats->inbound.jb_packet_count, "in_jitter_packet_count");
1510  add_stat(stats->inbound.dtmf_packet_count, "in_dtmf_packet_count");
1511  add_stat(stats->inbound.cng_packet_count, "in_cng_packet_count");
1512  add_stat(stats->inbound.flush_packet_count, "in_flush_packet_count");
1513  add_stat(stats->inbound.largest_jb_size, "in_largest_jb_size");
1514  add_stat_double(stats->inbound.min_variance, "in_jitter_min_variance");
1515  add_stat_double(stats->inbound.max_variance, "in_jitter_max_variance");
1516  add_stat_double(stats->inbound.lossrate, "in_jitter_loss_rate");
1517  add_stat_double(stats->inbound.burstrate, "in_jitter_burst_rate");
1518  add_stat_double(stats->inbound.mean_interval, "in_mean_interval");
1519  add_stat(stats->inbound.flaws, "in_flaw_total");
1520  add_stat_double(stats->inbound.R, "in_quality_percentage");
1521  add_stat_double(stats->inbound.mos, "in_mos");
1522 
1523 
1524  add_stat(stats->outbound.raw_bytes, "out_raw_bytes");
1525  add_stat(stats->outbound.media_bytes, "out_media_bytes");
1526  add_stat(stats->outbound.packet_count, "out_packet_count");
1527  add_stat(stats->outbound.media_packet_count, "out_media_packet_count");
1528  add_stat(stats->outbound.skip_packet_count, "out_skip_packet_count");
1529  add_stat(stats->outbound.dtmf_packet_count, "out_dtmf_packet_count");
1530  add_stat(stats->outbound.cng_packet_count, "out_cng_packet_count");
1531 
1532  add_stat(stats->rtcp.packet_count, "rtcp_packet_count");
1533  add_stat(stats->rtcp.octet_count, "rtcp_octet_count");
1534 
1535  }
1536 }
1537 
1539 {
1540  switch_media_handle_t *smh;
1541  switch_rtp_engine_t *a_engine, *v_engine;
1542 
1543  switch_assert(session);
1544 
1545  if (!(smh = session->media_handle)) {
1546  return;
1547  }
1548 
1549  a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
1550  v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
1551 
1552  if (a_engine->rtp_session) {
1554  }
1555 
1556  if (v_engine->rtp_session) {
1558  }
1559 
1560 }
1561 
1563 {
1564 
1565  if (!session->media_handle) {
1566  return;
1567  }
1568 
1570 
1571  set_stats(session, SWITCH_MEDIA_TYPE_AUDIO, "audio");
1572  set_stats(session, SWITCH_MEDIA_TYPE_VIDEO, "video");
1573 }
1574 
1575 
1576 
1578 {
1579  switch_media_handle_t *smh;
1580  switch_rtp_engine_t *a_engine, *v_engine;
1581 
1582  switch_assert(session);
1583 
1584  if (!(smh = session->media_handle)) {
1585  return;
1586  }
1587 
1588  a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
1589  v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
1590 
1591 
1592  if (smh->video_timer.timer_interface) {
1594  }
1595 
1596  if (switch_core_codec_ready(&a_engine->read_codec)) {
1598  }
1599 
1600  if (switch_core_codec_ready(&a_engine->write_codec)) {
1602  }
1603 
1604  if (switch_core_codec_ready(&v_engine->read_codec)) {
1606  }
1607 
1608  if (switch_core_codec_ready(&v_engine->write_codec)) {
1610  }
1611 
1615 
1616 
1617 
1618 }
1619 
1620 
1622 {
1624  switch_media_handle_t *smh = NULL;
1625  int i;
1626 
1627  *smhp = NULL;
1628 
1629  if (zstr(params->sdp_username)) {
1630  params->sdp_username = "FreeSWITCH";
1631  }
1632 
1633 
1634  if ((session->media_handle = switch_core_session_alloc(session, (sizeof(*smh))))) {
1635  session->media_handle->session = session;
1636 
1637 
1638  *smhp = session->media_handle;
1639  switch_set_flag(session->media_handle, SMF_INIT);
1640  session->media_handle->media_flags[SCMF_RUNNING] = 1;
1641  session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].read_frame.buflen = SWITCH_RTP_MAX_BUF_LEN;
1642  session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].type = SWITCH_MEDIA_TYPE_AUDIO;
1643  session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].crypto_type = CRYPTO_INVALID;
1644 
1645  for (i = 0; i < CRYPTO_INVALID; i++) {
1646  session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].ssec[i].crypto_type = i;
1647  }
1648 
1649  session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].read_frame.buflen = SWITCH_RTP_MAX_BUF_LEN;
1650  session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].type = SWITCH_MEDIA_TYPE_VIDEO;
1651  session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].crypto_type = CRYPTO_INVALID;
1652 
1653 
1654  switch_channel_set_variable(session->channel, "video_media_flow", "sendrecv");
1655  switch_channel_set_variable(session->channel, "audio_media_flow", "sendrecv");
1656 
1657  session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].smode = SWITCH_MEDIA_FLOW_SENDRECV;
1658  session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].smode = SWITCH_MEDIA_FLOW_SENDRECV;
1659 
1660  for (i = 0; i < CRYPTO_INVALID; i++) {
1661  session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].ssec[i].crypto_type = i;
1662  }
1663 
1664  session->media_handle->mparams = params;
1665 
1666  if (!session->media_handle->mparams->video_key_freq) {
1667  session->media_handle->mparams->video_key_freq = 10000000;
1668  }
1669 
1670  if (!session->media_handle->mparams->video_key_first) {
1671  session->media_handle->mparams->video_key_first = 1000000;
1672  }
1673 
1674 
1675  for (i = 0; i <= CRYPTO_INVALID; i++) {
1676  session->media_handle->crypto_suite_order[i] = CRYPTO_INVALID;
1677  }
1678 
1679  switch_mutex_init(&session->media_handle->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
1680  switch_mutex_init(&session->media_handle->sdp_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
1681  switch_mutex_init(&session->media_handle->control_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
1682 
1683  session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].ssrc =
1684  (uint32_t) ((intptr_t) &session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO] + (uint32_t) time(NULL));
1685 
1686  session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].ssrc =
1687  (uint32_t) ((intptr_t) &session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO] + (uint32_t) time(NULL) / 2);
1688 
1689  session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].payload_map = switch_core_alloc(session->pool, sizeof(payload_map_t));
1690  session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].cur_payload_map = session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].payload_map;
1691  session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].cur_payload_map->current = 1;
1692  session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].payload_map = switch_core_alloc(session->pool, sizeof(payload_map_t));
1693  session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].cur_payload_map = session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].payload_map;
1694  session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].cur_payload_map->current = 1;
1695  session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].codec_settings.video.try_hardware_encoder = 1;
1696 
1697  switch_channel_set_flag(session->channel, CF_DTLS_OK);
1698 
1699  status = SWITCH_STATUS_SUCCESS;
1700  }
1701 
1702 
1703  return status;
1704 }
1705 
1707 {
1708  switch_assert(smh);
1709 
1710  smh->media_flags[flag] = 1;
1711 
1712 }
1713 
1715 {
1716  int i;
1717  switch_assert(smh);
1718 
1719  for(i = 0; i < SCMF_MAX; i++) {
1720  if (flags[i]) {
1721  smh->media_flags[i] = flags[i];
1722  }
1723  }
1724 
1725 }
1726 
1728 {
1729  switch_assert(smh);
1730 
1731  smh->media_flags[flag] = 0;
1732 }
1733 
1735 {
1736  switch_assert(smh);
1737  return smh->media_flags[flag];
1738 }
1739 
1741 {
1743  switch_media_handle_t *smh;
1744  switch_rtp_engine_t *engine = NULL;
1745 
1746  switch_assert(session);
1747 
1748  if (!(smh = session->media_handle)) {
1749  goto end;
1750  }
1751 
1752  if (!smh->media_flags[SCMF_RUNNING]) {
1753  goto end;
1754  }
1755 
1756  engine = &smh->engines[type];
1757  flow = engine->smode;
1758 
1759  end:
1760 
1761  return flow;
1762 }
1763 
1765 {
1766  if (session->media_handle && switch_test_flag(session->media_handle, SMF_INIT)) {
1767  return SWITCH_STATUS_SUCCESS;
1768  }
1769 
1770  return SWITCH_STATUS_FALSE;
1771 }
1772 
1773 
1774 
1776 {
1778  return session->media_handle;
1779  }
1780 
1781  return NULL;
1782 }
1783 
1785 {
1786  if (!session->media_handle) {
1787  return SWITCH_STATUS_FALSE;
1788  }
1789 
1790  return SWITCH_STATUS_SUCCESS;
1791 }
1792 
1794 {
1795  switch_assert(smh);
1796  return smh->mparams;
1797 }
1798 
1800 {
1801  const char *abs, *codec_string = NULL;
1802  const char *ocodec = NULL, *val;
1803  switch_media_handle_t *smh;
1804  char *tmp_codec_string;
1805 
1806  switch_assert(session);
1807 
1808  if (!(smh = session->media_handle)) {
1809  return;
1810  }
1811 
1812  if (!force && (switch_channel_test_flag(session->channel, CF_PROXY_MODE) || switch_channel_test_flag(session->channel, CF_PROXY_MEDIA))) {
1813  return;
1814  }
1815 
1816  if (force) {
1817  smh->mparams->num_codecs = 0;
1818  }
1819 
1820  if (smh->mparams->num_codecs) {
1821  return;
1822  }
1823 
1824  smh->payload_space = 0;
1825 
1826  switch_assert(smh->session != NULL);
1827 
1828  if ((abs = switch_channel_get_variable(session->channel, "absolute_codec_string"))) {
1829  codec_string = abs;
1830  goto ready;
1831  }
1832 
1833  val = switch_channel_get_variable_dup(session->channel, "media_mix_inbound_outbound_codecs", SWITCH_FALSE, -1);
1834  if (!val || !switch_true(val)) {
1835  if ((ocodec = switch_channel_get_variable(session->channel, SWITCH_ORIGINATOR_CODEC_VARIABLE))) {
1836  codec_string = ocodec;
1837  goto ready;
1838  }
1839  }
1840 
1841  if (!(codec_string = switch_channel_get_variable(session->channel, "codec_string"))) {
1842  codec_string = switch_core_media_get_codec_string(smh->session);
1843  }
1844 
1845  if (codec_string && *codec_string == '=') {
1846  codec_string++;
1847  goto ready;
1848  }
1849 
1850  if (ocodec) {
1851  if (!codec_string || (smh->media_flags[SCMF_DISABLE_TRANSCODING])) {
1852  codec_string = ocodec;
1853  } else {
1854  if (!(codec_string = switch_core_session_sprintf(smh->session, "%s,%s", ocodec, codec_string))) {
1855  codec_string = ocodec;
1856  }
1857  }
1858  }
1859 
1860  ready:
1861 
1862  if (!codec_string) {
1863  codec_string = "PCMU@20i,PCMA@20i,speex@20i";
1864  }
1865 
1866  tmp_codec_string = switch_core_session_strdup(smh->session, codec_string);
1867  switch_channel_set_variable(session->channel, "rtp_use_codec_string", codec_string);
1868  smh->codec_order_last = switch_separate_string(tmp_codec_string, ',', smh->codec_order, SWITCH_MAX_CODECS);
1870 
1871 }
1872 
1873 
1874 
1875 static void check_jb(switch_core_session_t *session, const char *input, int32_t jb_msec, int32_t maxlen, switch_bool_t silent)
1876 {
1877  const char *val;
1878  switch_media_handle_t *smh;
1879  switch_rtp_engine_t *a_engine = NULL, *v_engine = NULL;
1880 
1881  switch_assert(session);
1882 
1883  if (!(smh = session->media_handle)) {
1884  return;
1885  }
1886 
1887  a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
1888  v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
1889 
1890 
1891  if (!zstr(input)) {
1892  const char *s;
1893  if (a_engine->rtp_session) {
1894  if (!strcasecmp(input, "pause")) {
1896  return;
1897  } else if (!strcasecmp(input, "resume")) {
1899  return;
1900  } else if (!strcasecmp(input, "stop")) {
1902  return;
1903  } else if (!strncasecmp(input, "debug:", 6)) {
1904  s = input + 6;
1905  if (s && !strcmp(s, "off")) {
1906  s = NULL;
1907  }
1909  return;
1910  }
1911 
1912  switch_channel_set_variable(session->channel, "jitterbuffer_msec", input);
1913  }
1914 
1915  if (v_engine->rtp_session) {
1916  if (!strncasecmp(input, "vbsize:", 7)) {
1917  int frames = 0, max_frames = 0;
1918  s = input + 7;
1919 
1920  frames = atoi(s);
1921 
1922  if ((s = strchr(s, ':')) && *(s+1) != '\0') {
1923  max_frames = atoi(s+1);
1924  }
1925 
1926  if (frames > 0) {
1927  switch_rtp_set_video_buffer_size(v_engine->rtp_session, frames, max_frames);
1928  }
1929  return;
1930  } else if (!strncasecmp(input, "vdebug:", 7)) {
1931  s = input + 7;
1932 
1933  if (s && !strcmp(s, "off")) {
1934  s = NULL;
1935  }
1936  switch_rtp_debug_jitter_buffer(v_engine->rtp_session, s);
1937  return;
1938  }
1939  }
1940  }
1941 
1942 
1943  if (jb_msec || (val = switch_channel_get_variable(session->channel, "jitterbuffer_msec")) || (val = smh->mparams->jb_msec)) {
1944  char *p;
1945 
1946  if (!jb_msec) {
1947  jb_msec = atoi(val);
1948 
1949  if (strchr(val, 'p') && jb_msec > 0) {
1950  jb_msec *= -1;
1951  }
1952 
1953  if ((p = strchr(val, ':'))) {
1954  p++;
1955  maxlen = atoi(p);
1956 
1957  if (strchr(p, 'p') && maxlen > 0) {
1958  maxlen *= -1;
1959  }
1960  }
1961  }
1962 
1963  if (jb_msec < 0 && jb_msec > -1000) {
1964  jb_msec = (a_engine->read_codec.implementation->microseconds_per_packet / 1000) * abs(jb_msec);
1965  }
1966 
1967  if (maxlen < 0 && maxlen > -1000) {
1968  maxlen = (a_engine->read_codec.implementation->microseconds_per_packet / 1000) * abs(maxlen);
1969  }
1970 
1971  if (jb_msec < 10 || jb_msec > 10000) {
1973  "Invalid Jitterbuffer spec [%d] must be between 10 and 10000\n", jb_msec);
1974  } else {
1975  int qlen, maxqlen = 50;
1976 
1977  qlen = jb_msec / (a_engine->read_impl.microseconds_per_packet / 1000);
1978 
1979  if (maxlen) {
1980  maxqlen = maxlen / (a_engine->read_impl.microseconds_per_packet / 1000);
1981  }
1982 
1983  if (maxqlen < qlen) {
1984  maxqlen = qlen * 5;
1985  }
1986  if (switch_rtp_activate_jitter_buffer(a_engine->rtp_session, qlen, maxqlen,
1987  a_engine->read_impl.samples_per_packet,
1989  if (!silent) {
1991  SWITCH_LOG_DEBUG, "Setting Jitterbuffer to %dms (%d frames) (%d max frames)\n",
1992  jb_msec, qlen, maxqlen);
1993  }
1995  if (!switch_false(switch_channel_get_variable(session->channel, "rtp_jitter_buffer_plc"))) {
1997  }
1998  } else if (!silent) {
2000  SWITCH_LOG_WARNING, "Error Setting Jitterbuffer to %dms (%d frames)\n", jb_msec, qlen);
2001  }
2002 
2003  }
2004  }
2005 
2006 }
2007 
2009 {
2010  int32_t jb_sync_msec = 0;
2011  uint32_t fps = 0, frames = 0;
2012  uint32_t min_frames = 0;
2013  uint32_t max_frames = 0;
2014  uint32_t cur_frames = 0;
2015  switch_media_handle_t *smh;
2016  switch_rtp_engine_t *v_engine = NULL;
2017  int sync_audio = 0, sync_video = 0;
2018 
2019  const char *var;
2020 
2021  switch_assert(session);
2022 
2023  if (!switch_channel_test_flag(session->channel, CF_VIDEO)) {
2024  return;
2025  }
2026 
2027  if (!(smh = session->media_handle)) {
2028  return;
2029  }
2030 
2031  v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
2032 
2033  if ((var = switch_channel_get_variable_dup(session->channel, "jb_av_sync_msec", SWITCH_FALSE, -1))) {
2034  int tmp;
2035  char *p;
2036 
2037  if (!strcasecmp(var, "disabled")) {
2038  return;
2039  }
2040 
2041  tmp = atol(var);
2042 
2043  if (tmp && tmp > -50 && tmp < 10000) {
2044  jb_sync_msec = tmp;
2045  }
2046 
2047  if ((p = strchr(var, ':'))) {
2048  p++;
2049  frames = atoi(p);
2050  }
2051  }
2052 
2053  fps = switch_core_media_get_video_fps(session);
2054 
2055  switch_rtp_get_video_buffer_size(v_engine->rtp_session, &min_frames, &max_frames, &cur_frames, NULL);
2056 
2057  if (!frames) {
2058  if (cur_frames != min_frames) {
2059  frames = cur_frames;
2060  } else {
2061  frames = fps / 7.5;
2062  if (frames < 1) frames = 1;
2063  sync_audio = 1;
2064  }
2065  }
2066 
2067  if (!jb_sync_msec) {
2068  jb_sync_msec = frames * 75;
2069  }
2070 
2071 
2072  if (frames != cur_frames) {
2073  switch_rtp_set_video_buffer_size(v_engine->rtp_session, frames, 0);
2074  sync_audio = 1;
2075  sync_video = 1;
2076  }
2077 
2079  SWITCH_LOG_DEBUG1, "%s %s \"%s\" Sync A/V JB to %dms %u VFrames FPS %u a:%s v:%s\n",
2081  switch_channel_get_name(session->channel),
2082  switch_channel_get_variable_dup(session->channel, "caller_id_name", SWITCH_FALSE, -1),
2083  jb_sync_msec, frames, video_globals.fps, sync_audio ? "yes" : "no", sync_video ? "yes" : "no");
2084 
2085  if (sync_audio) {
2086  check_jb(session, NULL, jb_sync_msec, 0, SWITCH_TRUE);
2087  }
2088 
2089  video_globals.synced++;
2090 }
2091 
2092 
2093 //?
2095 {
2096  switch_rtp_engine_t *engine;
2097  switch_media_handle_t *smh;
2098 
2099  switch_assert(session);
2100 
2101  if (!(smh = session->media_handle)) {
2102  return SWITCH_STATUS_FALSE;
2103  }
2104 
2105  if (!smh->media_flags[SCMF_RUNNING]) {
2106  return SWITCH_STATUS_FALSE;
2107  }
2108 
2109  engine = &smh->engines[type];
2110 
2111  if (!engine->read_codec.implementation || !switch_core_codec_ready(&engine->read_codec)) {
2112  return SWITCH_STATUS_FALSE;
2113  }
2114 
2115  switch_assert(engine->rtp_session != NULL);
2116 
2117 
2118  if (!switch_channel_up_nosig(session->channel) || !switch_rtp_ready(engine->rtp_session) || switch_channel_test_flag(session->channel, CF_NOT_READY)) {
2119  return SWITCH_STATUS_FALSE;
2120  }
2121 
2122  if (lock) {
2123  if (smh->read_mutex[type] && switch_mutex_trylock(smh->read_mutex[type]) != SWITCH_STATUS_SUCCESS) {
2124  /* return CNG, another thread is already reading */
2125  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "%s is already being read for %s\n",
2126  switch_channel_get_name(session->channel), type2str(type));
2127  return SWITCH_STATUS_INUSE;
2128  }
2129  } else {
2130  switch_mutex_unlock(smh->read_mutex[type]);
2131  }
2132 
2133  return SWITCH_STATUS_SUCCESS;
2134 }
2135 
2136 
2137 //?
2139  switch_io_flag_t flags, int stream_id, switch_media_type_t type)
2140 {
2141  switch_rtcp_frame_t rtcp_frame;
2142  switch_rtp_engine_t *engine;
2143  switch_status_t status;
2144  switch_media_handle_t *smh;
2145  int do_cng = 0;
2146 
2147  switch_assert(session);
2148 
2149  if (!(smh = session->media_handle)) {
2150  return SWITCH_STATUS_FALSE;
2151  }
2152 
2153  if (!smh->media_flags[SCMF_RUNNING]) {
2154  return SWITCH_STATUS_FALSE;
2155  }
2156 
2157  engine = &smh->engines[type];
2158 
2159  if (!engine->read_codec.implementation || !switch_core_codec_ready(&engine->read_codec)) {
2160  return SWITCH_STATUS_FALSE;
2161  }
2162 
2163  if (!switch_channel_up_nosig(session->channel) || !switch_rtp_ready(engine->rtp_session) || switch_channel_test_flag(session->channel, CF_NOT_READY)) {
2164  return SWITCH_STATUS_FALSE;
2165  }
2166 
2167  if (smh->read_mutex[type] && switch_mutex_trylock(smh->read_mutex[type]) != SWITCH_STATUS_SUCCESS) {
2168  /* return CNG, another thread is already reading */
2169  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "%s is already being read for %s\n",
2170  switch_channel_get_name(session->channel), type2str(type));
2171  return SWITCH_STATUS_INUSE;
2172  }
2173 
2174 
2175  engine->read_frame.datalen = 0;
2176  engine->read_frame.flags = SFF_NONE;
2177  engine->read_frame.m = SWITCH_FALSE;
2178  engine->read_frame.img = NULL;
2179 
2180  while (smh->media_flags[SCMF_RUNNING] && engine->read_frame.datalen == 0) {
2181  engine->read_frame.flags = SFF_NONE;
2182  status = switch_rtp_zerocopy_read_frame(engine->rtp_session, &engine->read_frame, flags);
2183  if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
2184  if (status == SWITCH_STATUS_TIMEOUT) {
2185 
2186  if (switch_channel_get_variable(session->channel, "execute_on_media_timeout")) {
2187  *frame = &engine->read_frame;
2188  switch_set_flag((*frame), SFF_CNG);
2189  (*frame)->datalen = engine->read_impl.encoded_bytes_per_packet;
2190  memset((*frame)->data, 0, (*frame)->datalen);
2191  switch_channel_execute_on(session->channel, "execute_on_media_timeout");
2193  }
2194 
2195 
2197  }
2198  goto end;
2199  }
2200 
2201  if (switch_channel_test_flag(session->channel, CF_LEG_HOLDING)) {
2202  status = SWITCH_STATUS_INUSE;
2203  goto end;
2204  }
2205 
2206  if (status == SWITCH_STATUS_BREAK) {
2207  goto end;
2208  }
2209 
2210  if (type == SWITCH_MEDIA_TYPE_VIDEO && engine->read_frame.m) {
2211 
2212  if (!smh->vid_started) {
2213  smh->vid_started = switch_epoch_time_now(NULL);
2214  }
2215  smh->vid_frames++;
2216 
2217  if ((smh->vid_frames % 15) == 0) {
2219  }
2220 
2221  if (smh->vid_frames == 1 || ((smh->vid_frames % 300) == 0)) {
2222  check_jb_sync(session);
2223  }
2224  }
2225 
2226 
2227  /* re-set codec if necessary */
2228  if (engine->reset_codec > 0) {
2229  const char *val;
2230  int rtp_timeout_sec = 0;
2231  int rtp_hold_timeout_sec = 0;
2232 
2233  engine->reset_codec = 0;
2234 
2235  if (switch_rtp_ready(engine->rtp_session)) {
2236  if (type == SWITCH_MEDIA_TYPE_VIDEO) {
2238  } else {
2240  *frame = NULL;
2242  }
2243  }
2244 
2245  if (type == SWITCH_MEDIA_TYPE_AUDIO && engine->read_impl.samples_per_second) {
2246  if ((val = switch_channel_get_variable(session->channel, "rtp_timeout_sec"))) {
2247  int v = atoi(val);
2248  if (v >= 0) {
2249  rtp_timeout_sec = v;
2250  }
2251  }
2252 
2253  if ((val = switch_channel_get_variable(session->channel, "rtp_hold_timeout_sec"))) {
2254  int v = atoi(val);
2255  if (v >= 0) {
2256  rtp_hold_timeout_sec = v;
2257  }
2258  }
2259 
2260  if (rtp_timeout_sec) {
2261  engine->max_missed_packets = (engine->read_impl.samples_per_second * rtp_timeout_sec) /
2262  engine->read_impl.samples_per_packet;
2263 
2265  if (!rtp_hold_timeout_sec) {
2266  rtp_hold_timeout_sec = rtp_timeout_sec * 10;
2267  }
2268  }
2269 
2270  if (rtp_hold_timeout_sec) {
2271  engine->max_missed_hold_packets = (engine->read_impl.samples_per_second * rtp_hold_timeout_sec) /
2272  engine->read_impl.samples_per_packet;
2273  }
2274  }
2275  }
2276 
2277  check_jb(session, NULL, 0, 0, SWITCH_FALSE);
2278 
2279  engine->check_frames = 0;
2280  engine->last_ts = 0;
2281  engine->last_seq = 0;
2282 
2283  do_cng = 1;
2284  }
2285 
2286  if (do_cng) {
2287  /* return CNG for now */
2288  *frame = &engine->read_frame;
2289  switch_set_flag((*frame), SFF_CNG);
2290  (*frame)->datalen = engine->read_impl.encoded_bytes_per_packet;
2291  memset((*frame)->data, 0, (*frame)->datalen);
2293  }
2294 
2295 
2296  /* Try to read an RTCP frame, if successful raise an event */
2297  if (switch_rtcp_zerocopy_read_frame(engine->rtp_session, &rtcp_frame) == SWITCH_STATUS_SUCCESS) {
2298  switch_event_t *event;
2299 
2301  char value[30];
2302  char header[50];
2303  int i;
2304 
2305  char *uuid = switch_core_session_get_uuid(session);
2306  if (uuid) {
2308  }
2309 
2310  snprintf(value, sizeof(value), "%.8x", rtcp_frame.ssrc);
2311  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SSRC", value);
2312 
2313  snprintf(value, sizeof(value), "%u", rtcp_frame.ntp_msw);
2314  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "NTP-Most-Significant-Word", value);
2315 
2316  snprintf(value, sizeof(value), "%u", rtcp_frame.ntp_lsw);
2317  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "NTP-Least-Significant-Word", value);
2318 
2319  snprintf(value, sizeof(value), "%u", rtcp_frame.timestamp);
2320  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "RTP-Timestamp", value);
2321 
2322  snprintf(value, sizeof(value), "%u", rtcp_frame.packet_count);
2323  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Sender-Packet-Count", value);
2324 
2325  snprintf(value, sizeof(value), "%u", rtcp_frame.octect_count);
2326  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Octect-Packet-Count", value);
2327 
2328  snprintf(value, sizeof(value), "%u", engine->read_frame.timestamp);
2329  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Last-RTP-Timestamp", value);
2330 
2331  snprintf(value, sizeof(value), "%u", engine->read_frame.rate);
2332  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "RTP-Rate", value);
2333 
2334  snprintf(value, sizeof(value), "%" SWITCH_TIME_T_FMT, switch_time_now());
2335  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Capture-Time", value);
2336 
2337  // Add sources info
2338  for (i = 0; i < rtcp_frame.report_count; i++) {
2339  snprintf(header, sizeof(header), "Source%u-SSRC", i);
2340  snprintf(value, sizeof(value), "%.8x", rtcp_frame.reports[i].ssrc);
2341  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, header, value);
2342  snprintf(header, sizeof(header), "Source%u-Fraction", i);
2343  snprintf(value, sizeof(value), "%u", rtcp_frame.reports[i].fraction);
2344  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, header, value);
2345  snprintf(header, sizeof(header), "Source%u-Lost", i);
2346  snprintf(value, sizeof(value), "%u", rtcp_frame.reports[i].lost);
2347  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, header, value);
2348  snprintf(header, sizeof(header), "Source%u-Loss-Avg", i);
2349  snprintf(value, sizeof(value), "%u", rtcp_frame.reports[i].loss_avg);
2350  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, header, value);
2351  snprintf(header, sizeof(header), "Source%u-Highest-Sequence-Number-Received", i);
2352  snprintf(value, sizeof(value), "%u", rtcp_frame.reports[i].highest_sequence_number_received);
2353  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, header, value);
2354  snprintf(header, sizeof(header), "Source%u-Jitter", i);
2355  snprintf(value, sizeof(value), "%u", rtcp_frame.reports[i].jitter);
2356  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, header, value);
2357  snprintf(header, sizeof(header), "Source%u-LSR", i);
2358  snprintf(value, sizeof(value), "%u", rtcp_frame.reports[i].lsr);
2359  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, header, value);
2360  snprintf(header, sizeof(header), "Source%u-DLSR", i);
2361  snprintf(value, sizeof(value), "%u", rtcp_frame.reports[i].dlsr);
2362  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, header, value);
2363  }
2364 
2365  switch_event_fire(&event);
2366  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG10, "Dispatched RTCP event\n");
2367  }
2368  }
2369 
2370  /* Fast PASS! */
2371  if (switch_test_flag((&engine->read_frame), SFF_PROXY_PACKET)) {
2372  *frame = &engine->read_frame;
2374  }
2375 
2376  if (switch_rtp_has_dtmf(engine->rtp_session)) {
2377  switch_dtmf_t dtmf = { 0 };
2378  switch_rtp_dequeue_dtmf(engine->rtp_session, &dtmf);
2379  switch_channel_queue_dtmf(session->channel, &dtmf);
2380  }
2381 
2382  if (engine->read_frame.datalen > 0) {
2383  uint32_t bytes = 0;
2384  int frames = 1;
2385 
2386  /* autofix timing */
2387  if (!switch_test_flag((&engine->read_frame), SFF_CNG)) {
2388  if (!engine->read_codec.implementation || !switch_core_codec_ready(&engine->read_codec)) {
2389  *frame = NULL;
2391  }
2392 
2393  /* check for timing issues */
2395 
2396 
2397  engine->check_frames++;
2398 
2399  if (!engine->read_impl.encoded_bytes_per_packet) {
2401  goto skip;
2402  }
2403 
2404  if (smh->media_flags[SCMF_AUTOFIX_TIMING] && (engine->read_frame.datalen % 10) == 0) {
2405 
2406  if (engine->last_ts && engine->read_frame.datalen != engine->read_impl.encoded_bytes_per_packet) {
2407 
2408  uint32_t codec_ms = (int) (engine->read_frame.timestamp -
2409  engine->last_ts) / (engine->read_impl.samples_per_second / 1000);
2410 
2411  if (engine->last_seq && (int) (engine->read_frame.seq - engine->last_seq) > 1) {
2412  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Correcting calculated ptime value from %d to %d to compensate for %d lost packet(s)\n", codec_ms, codec_ms / (int) (engine->read_frame.seq - engine->last_seq), (int) (engine->read_frame.seq - engine->last_seq - 1));
2413  codec_ms = codec_ms / (int) (engine->read_frame.seq - engine->last_seq);
2414  }
2415 
2416  if ((codec_ms % 10) != 0 || codec_ms > engine->read_impl.samples_per_packet * 10) {
2417  engine->last_ts = 0;
2418  engine->last_seq = 0;
2419  goto skip;
2420  }
2421 
2422 
2423  if (engine->last_codec_ms && engine->last_codec_ms == codec_ms) {
2424  engine->mismatch_count++;
2425  }
2426 
2427  engine->last_codec_ms = codec_ms;
2428 
2429  if (engine->mismatch_count > MAX_MISMATCH_FRAMES) {
2430  if (codec_ms != engine->cur_payload_map->codec_ms) {
2431 
2432  if (codec_ms > 120) { /* yeah right */
2434  "Your phone is trying to send timestamps that suggest an increment of %dms per packet\n"
2435  "That seems hard to believe so I am going to go on ahead and um ignore that, mmkay?\n",
2436  (int) codec_ms);
2438  goto skip;
2439  }
2440 
2441  engine->read_frame.datalen = 0;
2442 
2443  if (codec_ms != engine->cur_payload_map->codec_ms) {
2445  "Asynchronous PTIME not supported, changing our end from %d to %d\n",
2446  (int) engine->cur_payload_map->codec_ms,
2447  (int) codec_ms
2448  );
2449 
2450  switch_channel_set_variable_printf(session->channel, "rtp_h_X-Broken-PTIME", "Adv=%d;Sent=%d",
2451  (int) engine->cur_payload_map->codec_ms, (int) codec_ms);
2452 
2453  engine->cur_payload_map->codec_ms = codec_ms;
2454 
2455  /* mark to re-set codec */
2456  engine->reset_codec = 2;
2457  }
2458  }
2459  }
2460 
2461  } else {
2462  engine->mismatch_count = 0;
2463  }
2464 
2465  engine->last_ts = engine->read_frame.timestamp;
2466  engine->last_seq = engine->read_frame.seq;
2467 
2468 
2469  } else {
2470  engine->mismatch_count = 0;
2471  engine->last_ts = 0;
2472  engine->last_seq = 0;
2473  }
2474  }
2475 
2476  /* autofix payload type */
2477 
2478  if (!engine->reset_codec &&
2479  engine->codec_negotiated &&
2480  (!smh->mparams->cng_pt || engine->read_frame.payload != smh->mparams->cng_pt) &&
2481  (!smh->mparams->recv_te || engine->read_frame.payload != smh->mparams->recv_te) &&
2482  (!smh->mparams->te || engine->read_frame.payload != smh->mparams->te) &&
2483  engine->read_frame.payload != engine->cur_payload_map->recv_pt &&
2484  engine->read_frame.payload != engine->cur_payload_map->agreed_pt &&
2485  engine->read_frame.payload != engine->cur_payload_map->pt) {
2486 
2487  payload_map_t *pmap;
2488 
2489 
2491  "alternate payload received (received %d, expecting %d)\n",
2492  (int) engine->read_frame.payload, (int) engine->cur_payload_map->agreed_pt);
2493 
2494 
2495  /* search for payload type */
2497  for (pmap = engine->payload_map; pmap; pmap = pmap->next) {
2498  if (engine->read_frame.payload == pmap->recv_pt && pmap->negotiated) {
2499  engine->cur_payload_map = pmap;
2500  engine->cur_payload_map->current = 1;
2502  "Changing current codec to %s (payload type %d).\n",
2503  pmap->iananame, pmap->pt);
2504 
2505  /* mark to re-set codec */
2506  engine->reset_codec = 1;
2507  break;
2508  }
2509  }
2511 
2512  if (!engine->reset_codec) {
2514  "Could not change to payload type %d, ignoring...\n",
2515  (int) engine->read_frame.payload);
2516  }
2517  }
2518 
2519  skip:
2520 
2521  if ((bytes = engine->read_impl.encoded_bytes_per_packet)) {
2522  frames = (engine->read_frame.datalen / bytes);
2523  }
2524  engine->read_frame.samples = (int) (frames * engine->read_impl.samples_per_packet);
2525 
2526  if (engine->read_frame.datalen == 0) {
2527  continue;
2528  }
2529  }
2530  break;
2531  }
2532  }
2533 
2534  if (engine->read_frame.datalen == 0) {
2535  *frame = NULL;
2536  }
2537 
2538  *frame = &engine->read_frame;
2539 
2540  status = SWITCH_STATUS_SUCCESS;
2541 
2542  end:
2543 
2544  if (smh->read_mutex[type]) {
2545  switch_mutex_unlock(smh->read_mutex[type]);
2546  }
2547 
2548  return status;
2549 }
2550 
2551 //?
2553  switch_frame_t *frame, switch_io_flag_t flags, int stream_id, switch_media_type_t type)
2554 {
2556  int bytes = 0, samples = 0, frames = 0;
2557  switch_rtp_engine_t *engine;
2558  switch_media_handle_t *smh;
2559 
2560  switch_assert(session);
2561 
2562  if (!(smh = session->media_handle)) {
2563  return SWITCH_STATUS_FALSE;
2564  }
2565 
2566  if (!smh->media_flags[SCMF_RUNNING]) {
2567  return SWITCH_STATUS_FALSE;
2568  }
2569 
2570  engine = &smh->engines[type];
2571 
2572 
2573  if (switch_channel_test_flag(session->channel, CF_VIDEO_ONLY) && type == SWITCH_MEDIA_TYPE_AUDIO) {
2574  return SWITCH_STATUS_SUCCESS;
2575  }
2576 
2577  while (!(engine->read_codec.implementation && switch_rtp_ready(engine->rtp_session))) {
2578  if (switch_channel_ready(session->channel)) {
2579  switch_yield(10000);
2580  } else {
2581  return SWITCH_STATUS_GENERR;
2582  }
2583  }
2584 
2585  if (!engine->read_codec.implementation || !switch_core_codec_ready(&engine->read_codec)) {
2586  return SWITCH_STATUS_GENERR;
2587  }
2588 
2589 
2590  if (!engine->read_codec.implementation || !switch_core_codec_ready(&engine->read_codec)) {
2591  return SWITCH_STATUS_FALSE;
2592  }
2593 
2594  if (!switch_test_flag(frame, SFF_CNG) && !switch_test_flag(frame, SFF_PROXY_PACKET)) {
2595  if (engine->read_impl.encoded_bytes_per_packet) {
2596  bytes = engine->read_impl.encoded_bytes_per_packet;
2597  frames = ((int) frame->datalen / bytes);
2598  } else
2599  frames = 1;
2600 
2601  samples = frames * engine->read_impl.samples_per_packet;
2602  }
2603 
2604  engine->timestamp_send += samples;
2605 
2606  if (switch_rtp_write_frame(engine->rtp_session, frame) < 0) {
2607  status = SWITCH_STATUS_FALSE;
2608  }
2609 
2610 
2611  return status;
2612 }
2613 
2614 
2615 //?
2617 {
2619  switch_t38_options_t *local_t38_options = switch_channel_get_private(channel, "t38_options");
2620 
2621  switch_assert(t38_options);
2622 
2623  if (!local_t38_options) {
2624  local_t38_options = switch_core_session_alloc(session, sizeof(switch_t38_options_t));
2625  }
2626 
2627  local_t38_options->T38MaxBitRate = t38_options->T38MaxBitRate;
2628  local_t38_options->T38FaxFillBitRemoval = t38_options->T38FaxFillBitRemoval;
2629  local_t38_options->T38FaxTranscodingMMR = t38_options->T38FaxTranscodingMMR;
2630  local_t38_options->T38FaxTranscodingJBIG = t38_options->T38FaxTranscodingJBIG;
2631  local_t38_options->T38FaxRateManagement = switch_core_session_strdup(session, t38_options->T38FaxRateManagement);
2632  local_t38_options->T38FaxMaxBuffer = t38_options->T38FaxMaxBuffer;
2633  local_t38_options->T38FaxMaxDatagram = t38_options->T38FaxMaxDatagram;
2634  local_t38_options->T38FaxUdpEC = switch_core_session_strdup(session, t38_options->T38FaxUdpEC);
2635  local_t38_options->T38VendorInfo = switch_core_session_strdup(session, t38_options->T38VendorInfo);
2636  local_t38_options->remote_ip = switch_core_session_strdup(session, t38_options->remote_ip);
2637  local_t38_options->remote_port = t38_options->remote_port;
2638 
2639 
2640  switch_channel_set_private(channel, "t38_options", local_t38_options);
2641 
2642 }
2643 
2644 //?
2646 {
2647  int i = 0;
2648  switch_media_handle_t *smh;
2649 
2650  switch_assert(session);
2651 
2652  if (!(smh = session->media_handle) || !mimp) {
2653  return SWITCH_STATUS_FALSE;
2654  }
2655 
2656 
2657  for (i = 0; i < smh->mparams->num_codecs; i++) {
2658  const switch_codec_implementation_t *imp = smh->codecs[i];
2659 
2660  if (!strcasecmp(imp->iananame, mimp->iananame) && imp->actual_samples_per_second == mimp->actual_samples_per_second) {
2661  *pt = smh->ianacodes[i];
2662 
2663  return SWITCH_STATUS_SUCCESS;
2664  }
2665  }
2666 
2667  return SWITCH_STATUS_FALSE;
2668 }
2669 
2670 //#define get_int_value(_var, _set) { const char *__v = switch_channel_get_variable(session->channel, _var); if (__v) { _set = atol(__v);} }
2671 //?
2673 {
2674  switch_media_handle_t *smh;
2675  switch_rtp_engine_t *engine;
2676 
2677  switch_assert(session);
2678 
2679  if (!(smh = session->media_handle)) {
2680  return;
2681  }
2682 
2683  if (!(engine = &smh->engines[type])) return;
2684 
2685  switch(type) {
2687  break;
2688  case SWITCH_MEDIA_TYPE_VIDEO: {
2689  uint32_t system_bw = 0;
2690  const char *var = NULL, *bwv;
2691 
2692  if ((var = switch_channel_get_variable(session->channel, "video_try_hardware_encoder"))) {
2694  }
2695 
2696  if (!(bwv = switch_channel_get_variable(session->channel, "rtp_video_max_bandwidth"))) {
2697  bwv = switch_channel_get_variable(session->channel, "rtp_video_max_bandwidth_out");
2698  }
2699 
2700  if (!bwv) {
2701  bwv = "1mb";
2702  }
2703 
2704  system_bw = switch_parse_bandwidth_string(bwv);
2705 
2706  if (engine->sdp_bw && engine->sdp_bw <= system_bw) {
2707  engine->codec_settings.video.bandwidth = engine->sdp_bw;
2708  } else {
2709  engine->codec_settings.video.bandwidth = system_bw;
2710  }
2711  }
2712  break;
2713  default:
2714  break;
2715  }
2716 }
2717 
2718 
2719 //?
2721 {
2722  switch_media_handle_t *smh;
2723  switch_rtp_engine_t *v_engine;
2724 
2725  switch_assert(session);
2726 
2727  if (!(smh = session->media_handle)) {
2728  return SWITCH_STATUS_FALSE;
2729  }
2730  v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
2731 
2732 
2733  if (!v_engine->codec_negotiated) {
2734  return SWITCH_STATUS_FALSE;
2735  }
2736 
2737  if (v_engine->read_codec.implementation && switch_core_codec_ready(&v_engine->read_codec)) {
2738  if (!force) {
2739  return SWITCH_STATUS_SUCCESS;
2740  }
2741  if (strcasecmp(v_engine->read_codec.implementation->iananame, v_engine->cur_payload_map->rm_encoding) ||
2743 
2744  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Changing Codec from %s to %s\n",
2748  } else {
2749  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Already using %s\n",
2750  v_engine->read_codec.implementation->iananame);
2751  return SWITCH_STATUS_SUCCESS;
2752  }
2753  }
2754 
2756 
2757  if (switch_core_codec_init(&v_engine->read_codec,
2758  v_engine->cur_payload_map->rm_encoding,
2759  v_engine->cur_payload_map->modname,
2760  v_engine->cur_payload_map->rm_fmtp,
2761  v_engine->cur_payload_map->rm_rate,
2762  0,
2763  1,
2766  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't load codec?\n");
2767  return SWITCH_STATUS_FALSE;
2768  } else {
2769  if (switch_core_codec_init(&v_engine->write_codec,
2770  v_engine->cur_payload_map->rm_encoding,
2771  v_engine->cur_payload_map->modname,
2772  v_engine->cur_payload_map->rm_fmtp,
2773  v_engine->cur_payload_map->rm_rate,
2774  0,
2775  1,
2778  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't load codec?\n");
2779  return SWITCH_STATUS_FALSE;
2780  } else {
2781  v_engine->read_frame.rate = v_engine->cur_payload_map->rm_rate;
2782  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set VIDEO Codec %s %s/%ld %d ms\n",
2783  switch_channel_get_name(session->channel), v_engine->cur_payload_map->rm_encoding,
2784  v_engine->cur_payload_map->rm_rate, v_engine->cur_payload_map->codec_ms);
2785  v_engine->read_frame.codec = &v_engine->read_codec;
2786 
2787  v_engine->write_codec.fmtp_out = switch_core_session_strdup(session, v_engine->write_codec.fmtp_out);
2788 
2789  v_engine->write_codec.agreed_pt = v_engine->cur_payload_map->agreed_pt;
2790  v_engine->read_codec.agreed_pt = v_engine->cur_payload_map->agreed_pt;
2793 
2794 
2795  switch_channel_set_variable_printf(session->channel, "rtp_last_video_codec_string", "%s@%dh",
2796  v_engine->cur_payload_map->rm_encoding, v_engine->cur_payload_map->rm_rate);
2797 
2798 
2799  if (switch_rtp_ready(v_engine->rtp_session)) {
2800  switch_core_session_message_t msg = { 0 };
2801 
2802  msg.from = __FILE__;
2804 
2806 
2807  //XX
2808 
2809  switch_core_session_receive_message(session, &msg);
2810 
2811 
2812  }
2813 
2814  switch_channel_set_variable(session->channel, "rtp_use_video_codec_name", v_engine->cur_payload_map->rm_encoding);
2815  switch_channel_set_variable(session->channel, "rtp_use_video_codec_fmtp", v_engine->cur_payload_map->rm_fmtp);
2816  switch_channel_set_variable_printf(session->channel, "rtp_use_video_codec_rate", "%d", v_engine->cur_payload_map->rm_rate);
2817  switch_channel_set_variable_printf(session->channel, "rtp_use_video_codec_ptime", "%d", 0);
2818  }
2819  }
2820  return SWITCH_STATUS_SUCCESS;
2821 }
2822 
2823 
2824 //?
2826 {
2828  int resetting = 0;
2829  switch_media_handle_t *smh;
2830  switch_rtp_engine_t *a_engine;
2831 
2832  switch_assert(session);
2833 
2834  if (!(smh = session->media_handle)) {
2835  return SWITCH_STATUS_FALSE;
2836  }
2837  a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
2838 
2839  if (!a_engine->cur_payload_map->iananame) {
2840  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No audio codec available\n");
2842  }
2843 
2844  if (switch_core_codec_ready(&a_engine->read_codec)) {
2845  if (!force) {
2847  }
2848 
2849  if (strcasecmp(a_engine->read_impl.iananame, a_engine->cur_payload_map->iananame) ||
2850  (uint32_t) a_engine->read_impl.microseconds_per_packet / 1000 != a_engine->cur_payload_map->codec_ms ||
2851  a_engine->read_impl.samples_per_second != a_engine->cur_payload_map->rm_rate ) {
2852 
2853  if (session->read_resampler) {
2854  switch_mutex_lock(session->resample_mutex);
2855  switch_resample_destroy(&session->read_resampler);
2856  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating read resampler\n");
2857  switch_mutex_unlock(session->resample_mutex);
2858  }
2859 
2860  if (session->write_resampler) {
2861  switch_mutex_lock(session->resample_mutex);
2862  switch_resample_destroy(&session->write_resampler);
2863  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating write resampler\n");
2864  switch_mutex_unlock(session->resample_mutex);
2865  }
2866 
2867  switch_core_session_reset(session, 0, 0);
2868  switch_channel_audio_sync(session->channel);
2869 
2871  "Changing Codec from %s@%dms@%dhz to %s@%dms@%luhz\n",
2872  a_engine->read_impl.iananame,
2873  a_engine->read_impl.microseconds_per_packet / 1000,
2875 
2876  a_engine->cur_payload_map->iananame,
2877  a_engine->cur_payload_map->codec_ms,
2878  a_engine->cur_payload_map->rm_rate);
2879 
2883  resetting = 1;
2887  switch_channel_audio_sync(session->channel);
2888  } else {
2889  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Already using %s\n", a_engine->read_impl.iananame);
2891  }
2892  }
2893 
2894 
2896 
2898  a_engine->cur_payload_map->iananame,
2899  a_engine->cur_payload_map->modname,
2900  a_engine->cur_payload_map->rm_fmtp,
2901  a_engine->cur_payload_map->rm_rate,
2902  a_engine->cur_payload_map->codec_ms,
2903  a_engine->cur_payload_map->channels,
2904  a_engine->cur_payload_map->bitrate,
2907  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't load codec?\n");
2910  }
2911 
2912  a_engine->read_codec.session = session;
2913 
2914 
2916  a_engine->cur_payload_map->iananame,
2917  a_engine->cur_payload_map->modname,
2918  a_engine->cur_payload_map->rm_fmtp,
2919  a_engine->cur_payload_map->rm_rate,
2920  a_engine->cur_payload_map->codec_ms,
2921  a_engine->cur_payload_map->channels,
2922  a_engine->cur_payload_map->bitrate,
2925  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't load codec?\n");
2928  }
2929 
2930  a_engine->write_codec.session = session;
2931 
2932  if (switch_rtp_ready(a_engine->rtp_session)) {
2933  switch_channel_audio_sync(session->channel);
2934  switch_rtp_reset_jb(a_engine->rtp_session);
2935  }
2936 
2937  switch_channel_set_variable(session->channel, "rtp_use_codec_name", a_engine->cur_payload_map->iananame);
2938  switch_channel_set_variable(session->channel, "rtp_use_codec_fmtp", a_engine->cur_payload_map->rm_fmtp);
2939  switch_channel_set_variable_printf(session->channel, "rtp_use_codec_rate", "%d", a_engine->cur_payload_map->rm_rate);
2940  switch_channel_set_variable_printf(session->channel, "rtp_use_codec_ptime", "%d", a_engine->cur_payload_map->codec_ms);
2941  switch_channel_set_variable_printf(session->channel, "rtp_use_codec_channels", "%d", a_engine->cur_payload_map->channels);
2942  switch_channel_set_variable_printf(session->channel, "rtp_last_audio_codec_string", "%s@%dh@%di@%dc",
2943  a_engine->cur_payload_map->iananame, a_engine->cur_payload_map->rm_rate, a_engine->cur_payload_map->codec_ms, a_engine->cur_payload_map->channels);
2944 
2947 
2948  a_engine->read_impl = *a_engine->read_codec.implementation;
2949  a_engine->write_impl = *a_engine->write_codec.implementation;
2950 
2953 
2954  if (switch_rtp_ready(a_engine->rtp_session)) {
2956 
2962  }
2963  }
2964 
2965  a_engine->read_frame.rate = a_engine->cur_payload_map->rm_rate;
2966 
2967  if (!switch_core_codec_ready(&a_engine->read_codec)) {
2968  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't load codec?\n");
2970  }
2971 
2972  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set Codec %s %s/%ld %d ms %d samples %d bits %d channels\n",
2973  switch_channel_get_name(session->channel), a_engine->cur_payload_map->iananame, a_engine->cur_payload_map->rm_rate,
2974  a_engine->cur_payload_map->codec_ms,
2976  a_engine->read_frame.codec = &a_engine->read_codec;
2977  a_engine->read_frame.channels = a_engine->read_impl.number_of_channels;
2978  a_engine->write_codec.agreed_pt = a_engine->cur_payload_map->agreed_pt;
2979  a_engine->read_codec.agreed_pt = a_engine->cur_payload_map->agreed_pt;
2980 
2981  if (force != 2) {
2983  switch_core_session_set_write_codec(session, &a_engine->write_codec);
2984  }
2985 
2986  a_engine->cur_payload_map->fmtp_out = switch_core_session_strdup(session, a_engine->write_codec.fmtp_out);
2987 
2988  if (switch_rtp_ready(a_engine->rtp_session)) {
2990  }
2991 
2992  end:
2993 
2994  if (resetting) {
2997  }
2998 
2999  return status;
3000 }
3002 {
3003  switch_media_handle_t *smh;
3004  switch_rtp_engine_t *engine;
3005 
3006  switch_assert(session);
3007 
3008  if (!(smh = session->media_handle)) {
3009  return;
3010  }
3011 
3012  engine = &smh->engines[type];
3013 
3014  engine->ice_in.chosen[0] = 0;
3015  engine->ice_in.chosen[1] = 0;
3016  engine->ice_in.is_chosen[0] = 0;
3017  engine->ice_in.is_chosen[1] = 0;
3018  engine->ice_in.cand_idx[0] = 0;
3019  engine->ice_in.cand_idx[1] = 0;
3020  memset(&engine->ice_in, 0, sizeof(engine->ice_in));
3021  engine->remote_rtcp_port = 0;
3022 
3023  if (engine->rtp_session) {
3024  switch_rtp_reset(engine->rtp_session);
3025  }
3026 
3027 }
3028 
3029 //?
3031 {
3034 
3035 }
3036 
3038 {
3039  switch_rtp_engine_t *a_engine, *v_engine;
3040  switch_media_handle_t *smh;
3041 
3042  switch_assert(session);
3043 
3044  if (!(smh = session->media_handle)) {
3045  return;
3046  }
3047 
3048  a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
3049  v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
3050 
3051  if (a_engine->rtp_session) {
3053  }
3054 
3055  if (v_engine->rtp_session) {
3057  }
3058 }
3059 
3061 {
3062  switch_rtp_engine_t *a_engine, *v_engine;
3063  switch_media_handle_t *smh;
3064 
3065  switch_assert(session);
3066 
3067  if (!(smh = session->media_handle)) {
3068  return;
3069  }
3070 
3071  a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
3072  v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
3073 
3074  if (a_engine->rtp_session) {
3076  }
3077 
3078  if (v_engine->rtp_session) {
3080  }
3081 }
3082 
3083 
3084 //?
3086 {
3087  switch_media_handle_t *smh;
3088  switch_rtp_engine_t *engine;
3089 
3090  switch_assert(session);
3091 
3092  if (!(smh = session->media_handle)) {
3093  return SWITCH_STATUS_FALSE;
3094  }
3095 
3096  engine = &smh->engines[type];
3097 
3098  if (engine->cand_acl_count < SWITCH_MAX_CAND_ACL) {
3099  engine->cand_acl[engine->cand_acl_count++] = switch_core_session_strdup(session, acl_name);
3100  return SWITCH_STATUS_SUCCESS;
3101  }
3102 
3103  return SWITCH_STATUS_FALSE;
3104 }
3105 
3106 //?
3108 {
3109  switch_media_handle_t *smh;
3110 
3111  switch_assert(session);
3112 
3113  if (!(smh = session->media_handle)) {
3114  return;
3115  }
3116 
3117  if (smh->mparams->num_codecs && !switch_channel_test_flag(session->channel, CF_VIDEO_POSSIBLE)) {
3118  int i;
3119  smh->video_count = 0;
3120  for (i = 0; i < smh->mparams->num_codecs; i++) {
3121 
3122  if (smh->codecs[i]->codec_type == SWITCH_CODEC_TYPE_VIDEO) {
3123  if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_INBOUND &&
3124  switch_channel_test_flag(session->channel, CF_NOVIDEO)) {
3125  continue;
3126  }
3127  smh->video_count++;
3128  }
3129  }
3130  if (smh->video_count) {
3131  switch_channel_set_flag(session->channel, CF_VIDEO_POSSIBLE);
3132  }
3133  }
3134 }
3135 
3136 //?
3138 {
3139  switch_rtp_engine_t *engine = &smh->engines[type];
3140 
3141  if (!engine->local_dtls_fingerprint.len) {
3142  if (engine->remote_dtls_fingerprint.type) {
3144  } else {
3145  engine->local_dtls_fingerprint.type = "sha-256";
3146  }
3148  }
3149 }
3150 
3151 //?
3152 static int dtls_ok(switch_core_session_t *session)
3153 {
3154  return switch_channel_test_flag(session->channel, CF_DTLS_OK);
3155 }
3156 
3157 #ifdef _MSC_VER
3158 /* remove this if the break is removed from the following for loop which causes unreachable code loop */
3159 /* for (i = 0; i < engine->cand_acl_count; i++) { */
3160 #pragma warning(push)
3161 #pragma warning(disable:4702)
3162 #endif
3163 
3164 //?
3166 {
3167  switch_call_direction_t r = switch_channel_direction(session->channel);
3168 
3169  if (switch_channel_test_flag(session->channel, CF_3PCC)) {
3171  }
3172 
3173  if ((switch_channel_test_flag(session->channel, CF_REINVITE) || switch_channel_test_flag(session->channel, CF_RECOVERING))
3174  && switch_channel_test_flag(session->channel, CF_AVPF)) {
3176  }
3177 
3178  return r;
3179 }
3180 
3181 
3182 //?
3184 {
3186 
3187  if (zstr(ip)) {
3188  return status;
3189  }
3190 
3191  if (strchr(ip, ':')) {
3192  if (!zstr(smh->mparams->rtpip6)) {
3193  smh->mparams->rtpip = smh->mparams->rtpip6;
3194  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG, "%s choosing family v6\n",
3196  status = SWITCH_STATUS_SUCCESS;
3197  }
3198  } else {
3199  if (!zstr(smh->mparams->rtpip4)) {
3200  smh->mparams->rtpip = smh->mparams->rtpip4;
3201  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG, "%s choosing family v4\n",
3203  status = SWITCH_STATUS_SUCCESS;
3204  }
3205  }
3206 
3207  return status;
3208 }
3209 
3210 //?
3212 {
3214 
3215  if (zstr(ip)) {
3216  return r;
3217  }
3218 
3219  if (strchr(ip, ':')) {
3220  r = (switch_bool_t) !zstr(smh->mparams->rtpip6);
3221  } else {
3222  r = (switch_bool_t) !zstr(smh->mparams->rtpip4);
3223  }
3224 
3225  return r;
3226 }
3227 
3228 //?
3229 static switch_status_t check_ice(switch_media_handle_t *smh, switch_media_type_t type, sdp_session_t *sdp, sdp_media_t *m)
3230 {
3231  switch_rtp_engine_t *engine = &smh->engines[type];
3232  sdp_attribute_t *attr;
3233  int i = 0, got_rtcp_mux = 0;
3234  const char *val;
3235  int ice_seen = 0, cid = 0, ai = 0;
3236 
3237  //if (engine->ice_in.is_chosen[0] && engine->ice_in.is_chosen[1]) {
3238  //return SWITCH_STATUS_SUCCESS;
3239  //}
3240 
3241  engine->ice_in.chosen[0] = 0;
3242  engine->ice_in.chosen[1] = 0;
3243  engine->ice_in.is_chosen[0] = 0;
3244  engine->ice_in.is_chosen[1] = 0;
3245  engine->ice_in.cand_idx[0] = 0;
3246  engine->ice_in.cand_idx[1] = 0;
3247  engine->remote_ssrc = 0;
3248 
3249  if (m) {
3250  attr = m->m_attributes;
3251  } else {
3252  attr = sdp->sdp_attributes;
3253  }
3254 
3255  for (; attr; attr = attr->a_next) {
3256  char *data;
3257  char *fields[15];
3258  int argc = 0, j = 0;
3259 
3260  if (zstr(attr->a_name)) {
3261  continue;
3262  }
3263 
3264  if (!strcasecmp(attr->a_name, "ice-ufrag")) {
3265  if (engine->ice_in.ufrag && !strcmp(engine->ice_in.ufrag, attr->a_value)) {
3266  engine->new_ice = 0;
3267  } else {
3268  engine->ice_in.ufrag = switch_core_session_strdup(smh->session, attr->a_value);
3269  engine->new_ice = 1;
3270  }
3271  ice_seen++;
3272  } else if (!strcasecmp(attr->a_name, "ice-pwd")) {
3273  if (!engine->ice_in.pwd || strcmp(engine->ice_in.pwd, attr->a_value)) {
3274  engine->ice_in.pwd = switch_core_session_strdup(smh->session, attr->a_value);
3275  }
3276  } else if (!strcasecmp(attr->a_name, "ice-options")) {
3277  engine->ice_in.options = switch_core_session_strdup(smh->session, attr->a_value);
3278  } else if (!strcasecmp(attr->a_name, "setup")) {
3279  if (!strcasecmp(attr->a_value, "passive") || !strcasecmp(attr->a_value, "actpass")) {
3280  if (!engine->dtls_controller) {
3281  engine->new_dtls = 1;
3282  engine->new_ice = 1;
3283  }
3284  engine->dtls_controller = 1;
3285  } else if (!strcasecmp(attr->a_value, "active")) {
3286  if (engine->dtls_controller) {
3287  engine->new_dtls = 1;
3288  engine->new_ice = 1;
3289  }
3290  engine->dtls_controller = 0;
3291  }
3292  } else if (switch_rtp_has_dtls() && dtls_ok(smh->session) && !strcasecmp(attr->a_name, "fingerprint") && !zstr(attr->a_value)) {
3293  char *p;
3294 
3295  engine->remote_dtls_fingerprint.type = switch_core_session_strdup(smh->session, attr->a_value);
3296 
3297  if ((p = strchr(engine->remote_dtls_fingerprint.type, ' '))) {
3298  *p++ = '\0';
3299 
3301  !zstr(engine->remote_dtls_fingerprint.str) && !strcmp(engine->remote_dtls_fingerprint.str, p)) {
3302  engine->new_dtls = 0;
3303  } else {
3305  engine->new_dtls = 1;
3306  engine->new_ice = 1;
3307  }
3308  }
3309 
3310 
3311  //if (strcasecmp(engine->remote_dtls_fingerprint.type, "sha-256")) {
3312  // switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_WARNING, "Unsupported fingerprint type.\n");
3313  //engine->local_dtls_fingerprint.type = NULL;
3314  //engine->remote_dtls_fingerprint.type = NULL;
3315  //}
3316 
3317 
3318  generate_local_fingerprint(smh, type);
3320 
3321  } else if (!engine->remote_ssrc && !strcasecmp(attr->a_name, "ssrc") && attr->a_value) {
3322  engine->remote_ssrc = (uint32_t) atol(attr->a_value);
3323 
3324  if (engine->rtp_session && engine->remote_ssrc) {
3326  }
3327 
3328 
3329 #ifdef RTCP_MUX
3330  } else if (!strcasecmp(attr->a_name, "rtcp-mux")) {
3331  engine->rtcp_mux = SWITCH_TRUE;
3333  got_rtcp_mux++;
3334 #endif
3335  } else if (!strcasecmp(attr->a_name, "candidate")) {
3337 
3338  if (!engine->cand_acl_count) {
3339  engine->cand_acl[engine->cand_acl_count++] = "wan.auto";
3340  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_WARNING, "NO candidate ACL defined, Defaulting to wan.auto\n");
3341  }
3342 
3343 
3344  if (!switch_stristr(" udp ", attr->a_value)) {
3345  continue;
3346  }
3347 
3348  data = switch_core_session_strdup(smh->session, attr->a_value);
3349 
3350  argc = switch_split(data, ' ', fields);
3351 
3352  cid = fields[1] ? atoi(fields[1]) - 1 : 0;
3353 
3354  if (argc < 5 || engine->ice_in.cand_idx[cid] >= MAX_CAND - 1) {
3356  continue;
3357  }
3358 
3359  for (i = 0; i < argc; i++) {
3360  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG1, "CAND %d [%s]\n", i, fields[i]);
3361  }
3362 
3363  if (!ip_possible(smh, fields[4])) {
3365  "Drop %s Candidate cid: %d proto: %s type: %s addr: %s:%s (no network path)\n",
3366  type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio",
3367  cid+1, fields[2], fields[7], fields[4], fields[5]);
3368  continue;
3369  } else {
3371  "Save %s Candidate cid: %d proto: %s type: %s addr: %s:%s\n",
3372  type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio",
3373  cid+1, fields[2], fields[7], fields[4], fields[5]);
3374  }
3375 
3376 
3377  engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].foundation = switch_core_session_strdup(smh->session, fields[0]);
3378  engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].component_id = atoi(fields[1]);
3379  engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].transport = switch_core_session_strdup(smh->session, fields[2]);
3380  engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].priority = atol(fields[3]);
3381  engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].con_addr = switch_core_session_strdup(smh->session, fields[4]);
3382  engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].con_port = (switch_port_t)atoi(fields[5]);
3383 
3384  j = 6;
3385 
3386  while(j < argc && fields[j+1]) {
3387  if (!strcasecmp(fields[j], "typ")) {
3388  engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].cand_type = switch_core_session_strdup(smh->session, fields[j+1]);
3389  } else if (!strcasecmp(fields[j], "raddr")) {
3390  engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].raddr = switch_core_session_strdup(smh->session, fields[j+1]);
3391  } else if (!strcasecmp(fields[j], "rport")) {
3392  engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].rport = (switch_port_t)atoi(fields[j+1]);
3393  } else if (!strcasecmp(fields[j], "generation")) {
3394  engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].generation = switch_core_session_strdup(smh->session, fields[j+1]);
3395  }
3396 
3397  j += 2;
3398  }
3399 
3400  engine->ice_in.cand_idx[cid]++;
3401  }
3402  }
3403 
3404  if (!ice_seen) {
3405  return SWITCH_STATUS_SUCCESS;
3406  }
3407 
3408 
3409  for (cid = 0; cid < 2; cid++) {
3410  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG, "Searching for %s candidate.\n", cid ? "rtcp" : "rtp");
3411 
3412  for (ai = 0; ai < engine->cand_acl_count; ai++) {
3413  for (i = 0; i < engine->ice_in.cand_idx[cid]; i++) {
3414  if (switch_check_network_list_ip(engine->ice_in.cands[i][cid].con_addr, engine->cand_acl[ai])) {
3416  "Choose %s candidate, index %d, %s:%d\n", cid ? "rtcp" : "rtp", i,
3417  engine->ice_in.cands[i][cid].con_addr, engine->ice_in.cands[i][cid].con_port);
3418 
3419  engine->ice_in.chosen[cid] = i;
3420  engine->ice_in.is_chosen[cid] = 1;
3421  engine->ice_in.cands[i][cid].ready++;
3422  ip_choose_family(smh, engine->ice_in.cands[i][cid].con_addr);
3423 
3424  if (cid == 0 && got_rtcp_mux && engine->ice_in.cand_idx[1] < MAX_CAND) {
3425 
3427  "Choose same candidate, index %d, for rtcp based on rtcp-mux attribute %s:%d\n", engine->ice_in.cand_idx[1],
3428  engine->ice_in.cands[i][cid].con_addr, engine->ice_in.cands[i][cid].con_port);
3429 
3430 
3431  engine->ice_in.cands[engine->ice_in.cand_idx[1]][1] = engine->ice_in.cands[i][0];
3432  engine->ice_in.chosen[1] = engine->ice_in.cand_idx[1];
3433  engine->ice_in.is_chosen[1] = 1;
3434  engine->ice_in.cand_idx[1]++;
3435 
3436  goto done_choosing;
3437  }
3438 
3439  goto next_cid;
3440  }
3441  }
3442  }
3443 
3444  next_cid:
3445 
3446  continue;
3447  }
3448 
3449  done_choosing:
3450 
3451 
3452  if (!engine->ice_in.is_chosen[0] || !engine->ice_in.is_chosen[1]) {
3453  /* PUNT */
3454  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG, "%s no suitable candidates found.\n",
3456  return SWITCH_STATUS_FALSE;
3457  }
3458 
3459  for (i = 0; i < 2; i++) {
3460  if (engine->ice_in.cands[engine->ice_in.chosen[i]][i].ready) {
3461  if (zstr(engine->ice_in.ufrag) || zstr(engine->ice_in.pwd)) {
3462  engine->ice_in.cands[engine->ice_in.chosen[i]][i].ready = 0;
3463  }
3464  }
3465  }
3466 
3467 
3468  if (engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr && engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port) {
3469  char tmp[80] = "";
3470  engine->cur_payload_map->remote_sdp_ip = switch_core_session_strdup(smh->session, (char *) engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr);
3472  "setting remote %s ice addr to index %d %s:%d based on candidate\n", type2str(type), engine->ice_in.chosen[0],
3473  engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr, engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port);
3474  engine->ice_in.cands[engine->ice_in.chosen[0]][0].ready++;
3475 
3476  engine->remote_rtp_ice_port = (switch_port_t) engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port;
3477  engine->remote_rtp_ice_addr = switch_core_session_strdup(smh->session, engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr);
3478 
3479  engine->cur_payload_map->remote_sdp_ip = switch_core_session_strdup(smh->session, (char *) engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr);
3480  engine->cur_payload_map->remote_sdp_port = (switch_port_t) engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port;
3481 
3482  if (!smh->mparams->remote_ip) {
3484  }
3485 
3486  switch_snprintf(tmp, sizeof(tmp), "%d", engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port);
3489  }
3490 
3491  if (engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port) {
3493  "Setting remote rtcp %s addr to %s:%d based on candidate\n", type2str(type),
3494  engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_addr, engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port);
3495  engine->remote_rtcp_ice_port = engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port;
3496  engine->remote_rtcp_ice_addr = switch_core_session_strdup(smh->session, engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_addr);
3497 
3498  engine->remote_rtcp_port = engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port;
3499  }
3500 
3501 
3502  if (m && !got_rtcp_mux) {
3503  engine->rtcp_mux = -1;
3504  }
3505 
3507  if (switch_rtp_ready(engine->rtp_session) && engine->ice_in.cands[engine->ice_in.chosen[0]][0].ready && engine->new_ice) {
3508  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_INFO, "RE-Activating %s ICE\n", type2str(type));
3509 
3511  engine->ice_in.ufrag,
3512  engine->ice_out.ufrag,
3513  engine->ice_out.pwd,
3514  engine->ice_in.pwd,
3515  IPR_RTP,
3516 #ifdef GOOGLE_ICE
3518  NULL
3519 #else
3520  switch_ice_direction(smh->session) ==
3522  &engine->ice_in
3523 #endif
3524  );
3525 
3526 
3527  engine->new_ice = 0;
3528  }
3529 
3530 
3531  if (engine->rtp_session && ((val = switch_channel_get_variable(smh->session->channel,
3532  type == SWITCH_MEDIA_TYPE_VIDEO ?
3533  "rtcp_video_interval_msec" : "rtcp_audio_interval_msec"))
3534  || (val = type == SWITCH_MEDIA_TYPE_VIDEO ?
3536 
3537  switch_port_t remote_rtcp_port = engine->remote_rtcp_port;
3538 
3539  if (remote_rtcp_port) {
3540  if (!strcasecmp(val, "passthru")) {
3541  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_INFO, "Activating %s RTCP PASSTHRU PORT %d\n",
3542  type2str(type), remote_rtcp_port);
3543  switch_rtp_activate_rtcp(engine->rtp_session, -1, remote_rtcp_port, engine->rtcp_mux > 0);
3544  } else {
3545  int interval = atoi(val);
3546  if (interval < 100 || interval > 500000) {
3548  "Invalid rtcp interval spec [%d] must be between 100 and 500000\n", interval);
3549  interval = 5000;
3550  }
3551 
3552  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_INFO, "Activating %s RTCP PORT %d\n", type2str(type), remote_rtcp_port);
3553  switch_rtp_activate_rtcp(engine->rtp_session, interval, remote_rtcp_port, engine->rtcp_mux > 0);
3554  }
3555  }
3556  }
3557 
3558  if (engine->rtp_session && engine->ice_in.cands[engine->ice_in.chosen[1]][1].ready) {
3559  if (engine->rtcp_mux > 0 && !strcmp(engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_addr, engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr)
3560  && engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port == engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port) {
3561  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_INFO, "Skipping %s RTCP ICE (Same as RTP)\n", type2str(type));
3562  } else {
3563  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_INFO, "Activating %s RTCP ICE\n", type2str(type));
3564 
3566  engine->ice_in.ufrag,
3567  engine->ice_out.ufrag,
3568  engine->ice_out.pwd,
3569  engine->ice_in.pwd,
3570  IPR_RTCP,
3571 #ifdef GOOGLE_ICE
3573  NULL
3574 #else
3575  switch_ice_direction(smh->session) ==
3577  &engine->ice_in
3578 #endif
3579  );
3580  }
3581 
3582  }
3583 
3584  }
3585 
3586  return ice_seen ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_BREAK;
3587 }
3588 #ifdef _MSC_VER
3589 #pragma warning(pop)
3590 #endif
3591 
3593 {
3594  switch_media_handle_t *smh;
3595 
3596  switch_assert(session);
3597 
3598  if (!(smh = session->media_handle)) {
3599  return;
3600  }
3601 
3602  switch_channel_set_flag(session->channel, CF_VERBOSE_SDP);
3603  switch_channel_set_flag(session->channel, CF_AVPF);
3604  switch_channel_set_flag(session->channel, CF_ICE);
3607 
3608 }
3609 
3610 #define MAX_MATCHES 30
3611 struct matches {
3613  sdp_rtpmap_t *map;
3614  int rate;
3616 };
3617 
3618 static void greedy_sort(switch_media_handle_t *smh, struct matches *matches, int m_idx, const switch_codec_implementation_t **codec_array, int total_codecs)
3619 {
3620  int j = 0, f = 0, g;
3621  struct matches mtmp[MAX_MATCHES] = { { 0 } };
3622  for(j = 0; j < m_idx; j++) {
3623  *&mtmp[j] = *&matches[j];
3624  }
3625  for (g = 0; g < smh->mparams->num_codecs && g < total_codecs; g++) {
3626  const switch_codec_implementation_t *imp = codec_array[g];
3627 
3628  for(j = 0; j < m_idx; j++) {
3629  if (mtmp[j].imp == imp) {
3630  *&matches[f++] = *&mtmp[j];
3631  }
3632  }
3633  }
3634 }
3635 
3636 static void clear_pmaps(switch_rtp_engine_t *engine)
3637 {
3638  payload_map_t *pmap;
3639 
3640  for (pmap = engine->payload_map; pmap && pmap->allocated; pmap = pmap->next) {
3641  pmap->negotiated = 0;
3642  pmap->current = 0;
3643  }
3644 }
3645 
3646 //?
3647 SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *session, const char *r_sdp, uint8_t *proceed, switch_sdp_type_t sdp_type)
3648 {
3649  uint8_t match = 0;
3650  uint8_t vmatch = 0;
3651  switch_payload_t best_te = 0, cng_pt = 0;
3652  unsigned long best_te_rate = 8000, cng_rate = 8000;
3653  sdp_media_t *m;
3654  sdp_attribute_t *attr;
3655  int ptime = 0, dptime = 0, maxptime = 0, dmaxptime = 0;
3656  int sendonly = 0, recvonly = 0;
3657  int greedy = 0, x = 0, skip = 0;
3659  const char *val;
3660  const char *crypto = NULL;
3661  int got_crypto = 0, got_video_crypto = 0, got_audio = 0, saw_audio = 0, got_avp = 0, got_video_avp = 0, got_video_savp = 0, got_savp = 0, got_udptl = 0, got_webrtc = 0;
3662  int scrooge = 0;
3663  sdp_parser_t *parser = NULL;
3664  sdp_session_t *sdp;
3665  int reneg = 1;
3666  const switch_codec_implementation_t **codec_array;
3667  int total_codecs;
3668  switch_rtp_engine_t *a_engine, *v_engine;
3669  switch_media_handle_t *smh;
3670  uint32_t near_rate = 0;
3671  const switch_codec_implementation_t *mimp = NULL, *near_match = NULL;
3672  sdp_rtpmap_t *mmap = NULL, *near_map = NULL;
3673  struct matches matches[MAX_MATCHES] = { { 0 } };
3674  struct matches near_matches[MAX_MATCHES] = { { 0 } };
3675  int codec_ms = 0;
3676  uint32_t remote_codec_rate = 0, fmtp_remote_codec_rate = 0;
3677  const char *tmp;
3678  int m_idx = 0;
3679  int nm_idx = 0;
3680 
3681  switch_assert(session);
3682 
3683  if (!(smh = session->media_handle)) {
3684  return 0;
3685  }
3686 
3687  a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
3688  v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
3689 
3690  codec_array = smh->codecs;
3691  total_codecs = smh->mparams->num_codecs;
3692 
3693  if (!(parser = sdp_parse(NULL, r_sdp, (int) strlen(r_sdp), 0))) {
3694  return 0;
3695  }
3696 
3697  if (!(sdp = sdp_session(parser))) {
3698  sdp_parser_free(parser);
3699  return 0;
3700  }
3701 
3703 
3704  if (dtls_ok(session) && (tmp = switch_channel_get_variable(smh->session->channel, "webrtc_enable_dtls")) && switch_false(tmp)) {
3707  }
3708 
3709  v_engine->new_dtls = 1;
3710  v_engine->new_ice = 1;
3711  a_engine->new_dtls = 1;
3712  a_engine->new_ice = 1;
3713  a_engine->reject_avp = 0;
3714 
3716 
3717  clear_pmaps(a_engine);
3718  clear_pmaps(v_engine);
3719 
3720  if (proceed) *proceed = 1;
3721 
3724 
3725  if ((val = switch_channel_get_variable(channel, "rtp_codec_negotiation"))) {
3726  if (!strcasecmp(val, "generous")) {
3727  greedy = 0;
3728  scrooge = 0;
3729  } else if (!strcasecmp(val, "greedy")) {
3730  greedy = 1;
3731  scrooge = 0;
3732  } else if (!strcasecmp(val, "scrooge")) {
3733  scrooge = 1;
3734  greedy = 1;
3735  } else {
3736  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "rtp_codec_negotiation ignored invalid value : '%s' \n", val );
3737  }
3738  }
3739 
3740  if ((smh->origin = switch_core_session_strdup(session, (char *) sdp->sdp_origin->o_username))) {
3741 
3743 
3744  if (strstr(smh->origin, "CiscoSystemsSIP-GW-UserAgent")) {
3746  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Activate Buggy RFC2833 Mode!\n");
3747  }
3748  }
3749 
3751  if (strstr(smh->origin, "Sonus_UAC")) {
3754  "Hello,\nI see you have a Sonus!\n"
3755  "FYI, Sonus cannot follow the RFC on the proper way to send DTMF.\n"
3756  "Sadly, my creator had to spend several hours figuring this out so I thought you'd like to know that!\n"
3757  "Don't worry, DTMF will work but you may want to ask them to fix it......\n");
3758  }
3759  }
3760  }
3761 
3762  if ((val = switch_channel_get_variable(session->channel, "rtp_liberal_dtmf")) && switch_true(val)) {
3763  switch_channel_set_flag(session->channel, CF_LIBERAL_DTMF);
3764  }
3765 
3766  if (switch_stristr("T38FaxFillBitRemoval:", r_sdp) || switch_stristr("T38FaxTranscodingMMR:", r_sdp) ||
3767  switch_stristr("T38FaxTranscodingJBIG:", r_sdp)) {
3768  switch_channel_set_variable(session->channel, "t38_broken_boolean", "true");
3769  }
3770 
3771  switch_core_media_find_zrtp_hash(session, sdp);
3773 
3774  check_ice(smh, SWITCH_MEDIA_TYPE_AUDIO, sdp, NULL);
3775  check_ice(smh, SWITCH_MEDIA_TYPE_VIDEO, sdp, NULL);
3776 
3777  if ((sdp->sdp_connection && sdp->sdp_connection->c_address && !strcmp(sdp->sdp_connection->c_address, "0.0.0.0"))) {
3778  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "RFC2543 from March 1999 called; They want their 0.0.0.0 hold method back.....\n");
3779  sendonly = 2; /* global sendonly always wins */
3780  }
3781 
3782  for (m = sdp->sdp_media; m; m = m->m_next) {
3783  sdp_connection_t *connection;
3784  switch_core_session_t *other_session;
3785 
3786  if (!m->m_port) {
3787  continue;
3788  }
3789 
3790  if (m->m_type == sdp_media_audio) {
3791  saw_audio = 1;
3792  }
3793 
3794  ptime = dptime;
3795  maxptime = dmaxptime;
3796 
3797  if (m->m_proto == sdp_proto_extended_srtp || m->m_proto == sdp_proto_extended_rtp) {
3798  got_webrtc++;
3799  switch_core_session_set_ice(session);
3800  }
3801 
3802  if (m->m_proto_name && !strcasecmp(m->m_proto_name, "UDP/TLS/RTP/SAVPF")) {
3803  switch_channel_set_flag(session->channel, CF_AVPF_MOZ);
3804  }
3805 
3806  if (m->m_proto_name && !strcasecmp(m->m_proto_name, "UDP/RTP/AVPF")) {
3807  switch_channel_set_flag(session->channel, CF_AVPF_MOZ);
3808  }
3809 
3810  if (m->m_proto == sdp_proto_srtp || m->m_proto == sdp_proto_extended_srtp) {
3811  if (m->m_type == sdp_media_audio) {
3812  got_savp++;
3813  } else {
3814  got_video_savp++;
3815  }
3816  } else if (m->m_proto == sdp_proto_rtp) {
3817  if (m->m_type == sdp_media_audio) {
3818  got_avp++;
3819  } else {
3820  got_video_avp++;
3821  }
3822  } else if (m->m_proto == sdp_proto_udptl) {
3823  got_udptl++;
3824  }
3825 
3826  if (got_udptl && m->m_type == sdp_media_image && m->m_port) {
3827  switch_t38_options_t *t38_options = switch_core_media_process_udptl(session, sdp, m);
3828 
3829  if (switch_channel_test_app_flag_key("T38", session->channel, CF_APP_T38_NEGOTIATED)) {
3830  match = 1;
3831  goto done;
3832  }
3833 
3834  if (switch_true(switch_channel_get_variable(channel, "refuse_t38"))) {
3835  switch_channel_clear_app_flag_key("T38", session->channel, CF_APP_T38);
3836  match = 0;
3837  goto done;
3838  } else {
3839  const char *var = switch_channel_get_variable(channel, "t38_passthru");
3841 
3842 
3843  if (switch_channel_test_app_flag_key("T38", session->channel, CF_APP_T38)) {
3844  if (proceed) *proceed = 0;
3845  }
3846 
3847  if (var) {
3848  if (!(pass = switch_true(var))) {
3849  if (!strcasecmp(var, "once")) {
3850  pass = 2;
3851  }
3852  }
3853  }
3854 
3855  if ((pass == 2 && switch_channel_test_flag(smh->session->channel, CF_T38_PASSTHRU))
3856  || !switch_channel_test_flag(session->channel, CF_REINVITE) ||
3857 
3858  switch_channel_test_flag(session->channel, CF_PROXY_MODE) ||
3859  switch_channel_test_flag(session->channel, CF_PROXY_MEDIA) ||
3860  !switch_rtp_ready(a_engine->rtp_session)) {
3861  pass = 0;
3862  }
3863 
3864  if (pass && switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
3865  switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
3867  char *remote_host = switch_rtp_get_remote_host(a_engine->rtp_session);
3868  switch_port_t remote_port = switch_rtp_get_remote_port(a_engine->rtp_session);
3869  char tmp[32] = "";
3870 
3871 
3872  if (!switch_channel_test_flag(other_channel, CF_ANSWERED)) {
3874  SWITCH_LOG_WARNING, "%s Error Passing T.38 to unanswered channel %s\n",
3875  switch_channel_get_name(session->channel), switch_channel_get_name(other_channel));
3876  switch_core_session_rwunlock(other_session);
3877 
3878  pass = 0;
3879  match = 0;
3880  goto done;
3881  }
3882 
3883 
3884  if (switch_true(switch_channel_get_variable(session->channel, "t38_broken_boolean")) &&
3885  switch_true(switch_channel_get_variable(session->channel, "t38_pass_broken_boolean"))) {
3886  switch_channel_set_variable(other_channel, "t38_broken_boolean", "true");
3887  }
3888 
3889  a_engine->cur_payload_map->remote_sdp_ip = switch_core_session_strdup(session, t38_options->remote_ip);
3890  a_engine->cur_payload_map->remote_sdp_port = t38_options->remote_port;
3891 
3892  if (remote_host && remote_port && !strcmp(remote_host, a_engine->cur_payload_map->remote_sdp_ip) && remote_port == a_engine->cur_payload_map->remote_sdp_port) {
3893  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio params are unchanged for %s.\n",
3894  switch_channel_get_name(session->channel));
3895  } else {
3896  const char *err = NULL;
3897 
3898  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio params changed for %s from %s:%d to %s:%d\n",
3899  switch_channel_get_name(session->channel),
3900  remote_host, remote_port, a_engine->cur_payload_map->remote_sdp_ip, a_engine->cur_payload_map->remote_sdp_port);
3901 
3902  switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->cur_payload_map->remote_sdp_port);
3905 
3908  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", err);
3910  }
3911 
3913  }
3914 
3915 
3916 
3917  switch_core_media_copy_t38_options(t38_options, other_session);
3918 
3921 
3922  msg = switch_core_session_alloc(other_session, sizeof(*msg));
3924  msg->from = __FILE__;
3925  msg->string_arg = switch_core_session_strdup(other_session, r_sdp);
3926  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Passing T38 req to other leg.\n%s\n", r_sdp);
3927  switch_core_session_queue_message(other_session, msg);
3928  switch_core_session_rwunlock(other_session);
3929  }
3930  }
3931 
3932 
3933  /* do nothing here, mod_fax will trigger a response (if it's listening =/) */
3934  match = 1;
3935  goto done;
3936  } else if (m->m_type == sdp_media_audio && m->m_port && got_audio && got_savp) {
3937  a_engine->reject_avp = 1;
3938  } else if (m->m_type == sdp_media_audio && m->m_port && !got_audio) {
3939  sdp_rtpmap_t *map;
3940  int ice = 0;
3941 
3942  nm_idx = 0;
3943  m_idx = 0;
3944  memset(matches, 0, sizeof(matches[0]) * MAX_MATCHES);
3945  memset(near_matches, 0, sizeof(near_matches[0]) * MAX_MATCHES);
3946 
3947  if (!sendonly && (m->m_mode == sdp_sendonly || m->m_mode == sdp_inactive)) {
3948  sendonly = 1;
3949  }
3950 
3951  if (!sendonly && m->m_connections && m->m_connections->c_address && !strcmp(m->m_connections->c_address, "0.0.0.0")) {
3952  sendonly = 1;
3953  }
3954 
3955 
3956  a_engine->rmode = sdp_media_flow(m->m_mode);
3957 
3958  if (sdp_type == SDP_TYPE_REQUEST) {
3959  switch(a_engine->rmode) {
3961  switch_channel_set_variable(smh->session->channel, "audio_media_flow", "sendonly");
3962  a_engine->smode = SWITCH_MEDIA_FLOW_SENDONLY;
3963  break;
3965  switch_channel_set_variable(smh->session->channel, "audio_media_flow", "recvonly");
3966  a_engine->smode = SWITCH_MEDIA_FLOW_RECVONLY;
3967  break;
3968  default:
3969  switch_channel_set_variable(smh->session->channel, "audio_media_flow", "sendrecv");
3970  a_engine->smode = SWITCH_MEDIA_FLOW_SENDRECV;
3971  break;
3972  }
3973  }
3974 
3975  for (attr = sdp->sdp_attributes; attr; attr = attr->a_next) {
3976  if (zstr(attr->a_name)) {
3977  continue;
3978  }
3979 
3980 
3981  if (!strncasecmp(attr->a_name, "ice", 3)) {
3982  ice++;
3983  } else if (sendonly < 2 && !strcasecmp(attr->a_name, "sendonly")) {
3984  sendonly = 1;
3985  switch_channel_set_variable(session->channel, "media_audio_mode", "recvonly");
3986  } else if (sendonly < 2 && !strcasecmp(attr->a_name, "inactive")) {
3987  sendonly = 1;
3988  switch_channel_set_variable(session->channel, "media_audio_mode", "inactive");
3989  } else if (!strcasecmp(attr->a_name, "recvonly")) {
3990  switch_channel_set_variable(session->channel, "media_audio_mode", "sendonly");
3991  recvonly = 1;
3992 
3993  if (switch_rtp_ready(a_engine->rtp_session)) {
3995  a_engine->max_missed_hold_packets = 0;
3996  a_engine->max_missed_packets = 0;
3997  } else {
3998  switch_channel_set_variable(session->channel, "rtp_timeout_sec", "0");
3999  switch_channel_set_variable(session->channel, "rtp_hold_timeout_sec", "0");
4000  }
4001  } else if (sendonly < 2 && !strcasecmp(attr->a_name, "sendrecv")) {
4002  sendonly = 0;
4003  } else if (!strcasecmp(attr->a_name, "ptime")) {
4004  ptime = dptime = atoi(attr->a_value);
4005  } else if (!strcasecmp(attr->a_name, "maxptime")) {
4006  maxptime = dmaxptime = atoi(attr->a_value);
4007  }
4008  }
4009 
4010  if (sendonly == 2 && ice) {
4011  sendonly = 0;
4012  }
4013 
4014 
4015  if (sendonly != 1 && recvonly != 1) {
4016  switch_channel_set_variable(session->channel, "media_audio_mode", NULL);
4017  }
4018 
4019  if (sdp_type == SDP_TYPE_RESPONSE) {
4020  if (sendonly) {
4021  a_engine->smode = sdp_media_flow(sdp_sendonly);
4022  } else if (recvonly) {
4023  a_engine->smode = sdp_media_flow(sdp_recvonly);
4024  }
4025  }
4026 
4027 
4029  || ((val = switch_channel_get_variable(session->channel, "rtp_disable_hold"))
4030  && switch_true(val)))
4031  && !smh->mparams->hold_laps) {
4032  smh->mparams->hold_laps++;
4033  if (switch_core_media_toggle_hold(session, sendonly)) {
4035  if ((val = switch_channel_get_variable(session->channel, "rtp_renegotiate_codec_on_hold"))) {
4036  reneg = switch_true(val);
4037  }
4038  }
4039  }
4040 
4041  if (reneg) {
4043 
4044  if ((val = switch_channel_get_variable(session->channel, "rtp_renegotiate_codec_on_reinvite"))) {
4045  reneg = switch_true(val);
4046  }
4047  }
4048 
4049  if (session->bugs) {
4051  "Session is connected to a media bug. "
4052  "Re-Negotiation implicitly disabled.\n");
4053  reneg = 0;
4054  }
4055 
4056  if (switch_channel_test_flag(session->channel, CF_RECOVERING)) {
4057  reneg = 0;
4058  }
4059 
4060  if (sdp_type == SDP_TYPE_RESPONSE && smh->num_negotiated_codecs) {
4061  /* response to re-invite or update, only negotiated codecs are valid */
4062  reneg = 0;
4063  }
4064 
4065 
4066  if (!reneg && smh->num_negotiated_codecs) {
4067  codec_array = smh->negotiated_codecs;
4068  total_codecs = smh->num_negotiated_codecs;
4069  } else if (reneg) {
4070  smh->mparams->num_codecs = 0;
4072  codec_array = smh->codecs;
4073  total_codecs = smh->mparams->num_codecs;
4074  }
4075 
4076 
4077  if (switch_rtp_has_dtls() && dtls_ok(session)) {
4078  for (attr = m->m_attributes; attr; attr = attr->a_next) {
4079 
4080  if (!strcasecmp(attr->a_name, "fingerprint") && !zstr(attr->a_value)) {
4081  got_crypto = 1;
4082  }
4083  }
4084  }
4085 
4086  for (attr = m->m_attributes; attr; attr = attr->a_next) {
4087 
4088  if (!strcasecmp(attr->a_name, "rtcp") && attr->a_value) {
4089  switch_channel_set_variable(session->channel, "rtp_remote_audio_rtcp_port", attr->a_value);
4090  a_engine->remote_rtcp_port = (switch_port_t)atoi(attr->a_value);
4091  if (!smh->mparams->rtcp_audio_interval_msec) {
4093  }
4094  } else if (!strcasecmp(attr->a_name, "ptime") && attr->a_value) {
4095  ptime = atoi(attr->a_value);
4096  } else if (!strcasecmp(attr->a_name, "maxptime") && attr->a_value) {
4097  maxptime = atoi(attr->a_value);
4098  } else if (got_crypto < 1 && !strcasecmp(attr->a_name, "crypto") && !zstr(attr->a_value)) {
4099  int crypto_tag;
4100 
4101  if (!(smh->mparams->ndlb & SM_NDLB_ALLOW_CRYPTO_IN_AVP) &&
4102  !switch_true(switch_channel_get_variable(session->channel, "rtp_allow_crypto_in_avp"))) {
4103  if (m->m_proto != sdp_proto_srtp && !got_webrtc) {
4104  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "a=crypto in RTP/AVP, refer to rfc3711\n");
4105  match = 0;
4106  goto done;
4107  }
4108  }
4109 
4110  crypto = attr->a_value;
4111  crypto_tag = atoi(crypto);
4112  got_crypto = switch_core_session_check_incoming_crypto(session,
4113  "rtp_has_crypto", SWITCH_MEDIA_TYPE_AUDIO, crypto, crypto_tag, sdp_type);
4114 
4115  }
4116  }
4117 
4118  if (got_crypto == -1 && got_savp && !got_avp && !got_webrtc) {
4119  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Declining invite with only SAVP because secure media is administratively disabled\n");
4120  match = 0;
4121  break;
4122  }
4123 
4124  connection = sdp->sdp_connection;
4125  if (m->m_connections) {
4126  connection = m->m_connections;
4127  }
4128 
4129  if (!connection) {
4130  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot find a c= line in the sdp at media or session level!\n");
4131  match = 0;
4132  break;
4133  }
4134 
4135  x = 0;
4136 
4137  for (map = m->m_rtpmaps; map; map = map->rm_next) {
4138  int32_t i;
4139  const char *rm_encoding;
4140  uint32_t map_bit_rate = 0;
4141  switch_codec_fmtp_t codec_fmtp = { 0 };
4142  int map_channels = map->rm_params ? atoi(map->rm_params) : 1;
4143 
4144  if (!(rm_encoding = map->rm_encoding)) {
4145  rm_encoding = "";
4146  }
4147 
4148 
4149  if (!strcasecmp(rm_encoding, "telephone-event")) {
4150  if (!best_te || map->rm_rate == a_engine->cur_payload_map->rm_rate) {
4151  best_te = (switch_payload_t) map->rm_pt;
4152  best_te_rate = map->rm_rate;
4153  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set telephone-event payload to %u@%ld\n", best_te, best_te_rate);
4154  }
4155  continue;
4156  }
4157 
4158  if (!switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG) && !cng_pt && !strcasecmp(rm_encoding, "CN")) {
4159  cng_pt = (switch_payload_t) map->rm_pt;
4160  if (a_engine->rtp_session) {
4161  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set comfort noise payload to %u\n", cng_pt);
4162  switch_rtp_set_cng_pt(a_engine->rtp_session, smh->mparams->cng_pt);
4163  }
4164  continue;
4165  }
4166 
4167 
4168  if (x++ < skip) {
4169  continue;
4170  }
4171 
4172  if (match) {
4173  continue;
4174  }
4175 
4176  codec_ms = ptime;
4177 
4178  if (switch_channel_get_variable(session->channel, "rtp_h_X-Broken-PTIME") && a_engine->read_impl.microseconds_per_packet) {
4179  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Overwriting ptime from a known broken endpoint with the currently used value of %d ms\n", a_engine->read_impl.microseconds_per_packet / 1000);
4180  codec_ms = a_engine->read_impl.microseconds_per_packet / 1000;
4181  }
4182 
4183  if (maxptime && (!codec_ms || codec_ms > maxptime)) {
4184  codec_ms = maxptime;
4185  }
4186 
4187  if (!codec_ms) {
4188  codec_ms = switch_default_ptime(rm_encoding, map->rm_pt);
4189  }
4190 
4191  map_bit_rate = switch_known_bitrate((switch_payload_t)map->rm_pt);
4192 
4193  if (!ptime && !strcasecmp(map->rm_encoding, "g723")) {
4194  codec_ms = 30;
4195  }
4196 
4197  remote_codec_rate = map->rm_rate;
4198  fmtp_remote_codec_rate = 0;
4199  memset(&codec_fmtp, 0, sizeof(codec_fmtp));
4200 
4201  if (zstr(map->rm_fmtp)) {
4202  if (!strcasecmp(map->rm_encoding, "ilbc")) {
4203  codec_ms = 30;
4204  map_bit_rate = 13330;
4205  } else if (!strcasecmp(map->rm_encoding, "isac")) {
4206  codec_ms = 30;
4207  map_bit_rate = 32000;
4208  }
4209  } else {
4210  if ((switch_core_codec_parse_fmtp(map->rm_encoding, map->rm_fmtp, map->rm_rate, &codec_fmtp)) == SWITCH_STATUS_SUCCESS) {
4211  if (codec_fmtp.bits_per_second) {
4212  map_bit_rate = codec_fmtp.bits_per_second;
4213  }
4214  if (codec_fmtp.microseconds_per_packet) {
4215  codec_ms = (codec_fmtp.microseconds_per_packet / 1000);
4216  }
4217  if (codec_fmtp.actual_samples_per_second) {
4218  fmtp_remote_codec_rate = codec_fmtp.actual_samples_per_second;
4219  }
4220  if (codec_fmtp.stereo) {
4221  map_channels = 2;
4222  } else if (!strcasecmp(map->rm_encoding, "opus")) {
4223  map_channels = 1;
4224  }
4225  }
4226  }
4227 
4228  for (i = 0; i < smh->mparams->num_codecs && i < total_codecs; i++) {
4229  const switch_codec_implementation_t *imp = codec_array[i];
4230  uint32_t bit_rate = imp->bits_per_second;
4231  uint32_t codec_rate = imp->samples_per_second;
4232 
4233  if (imp->codec_type != SWITCH_CODEC_TYPE_AUDIO) {
4234  continue;
4235  }
4236 
4237  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio Codec Compare [%s:%d:%u:%d:%u:%d]/[%s:%d:%u:%d:%u:%d]\n",
4238  rm_encoding, map->rm_pt, (int) remote_codec_rate, codec_ms, map_bit_rate, map_channels,
4239  imp->iananame, imp->ianacode, codec_rate, imp->microseconds_per_packet / 1000, bit_rate, imp->number_of_channels);
4240  if ((zstr(map->rm_encoding) || (smh->mparams->ndlb & SM_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) {
4241  match = (map->rm_pt == imp->ianacode) ? 1 : 0;
4242  } else {
4243  match = (!strcasecmp(rm_encoding, imp->iananame) &&
4244  ((map->rm_pt < 96 && imp->ianacode < 96) || (map->rm_pt > 95 && imp->ianacode > 95)) &&
4245  (remote_codec_rate == codec_rate || fmtp_remote_codec_rate == imp->actual_samples_per_second)) ? 1 : 0;
4246  if (fmtp_remote_codec_rate) {
4247  remote_codec_rate = fmtp_remote_codec_rate;
4248  }
4249  }
4250 
4251  if (match && bit_rate && map_bit_rate && map_bit_rate != bit_rate && strcasecmp(map->rm_encoding, "ilbc") &&
4252  strcasecmp(map->rm_encoding, "isac")) {
4253  /* if a bit rate is specified and doesn't match, this is not a codec match, except for ILBC */
4254  match = 0;
4255  }
4256 
4257  if (match && remote_codec_rate && codec_rate && remote_codec_rate != codec_rate && (!strcasecmp(map->rm_encoding, "pcma") ||
4258  !strcasecmp(map->rm_encoding, "pcmu"))) {
4259  /* if the sampling rate is specified and doesn't match, this is not a codec match for G.711 */
4260  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "sampling rates have to match for G.711\n");
4261  match = 0;
4262  }
4263 
4264  if (match) {
4265  if (scrooge) {
4267  "Bah HUMBUG! Sticking with %s@%uh@%ui\n",
4268  imp->iananame, imp->samples_per_second, imp->microseconds_per_packet / 1000);
4269  } else if ((ptime && codec_ms && codec_ms * 1000 != imp->microseconds_per_packet) || remote_codec_rate != codec_rate) {
4270  /* ptime does not match */
4271  match = 0;
4272 
4274  "Audio Codec Compare [%s:%d:%u:%d:%u:%d] is saved as a near-match\n",
4275  imp->iananame, imp->ianacode, codec_rate, imp->microseconds_per_packet / 1000, bit_rate, imp->number_of_channels);
4276 
4277  near_matches[nm_idx].codec_idx = i;
4278  near_matches[nm_idx].rate = remote_codec_rate;
4279  near_matches[nm_idx].imp = imp;
4280  near_matches[nm_idx].map = map;
4281  nm_idx++;
4282 
4283  continue;
4284  }
4285 
4286  matches[m_idx].codec_idx = i;
4287  matches[m_idx].rate = codec_rate;
4288  matches[m_idx].imp = imp;
4289  matches[m_idx].map = map;
4290  m_idx++;
4291 
4293  "Audio Codec Compare [%s:%d:%u:%d:%u:%d] ++++ is saved as a match\n",
4294  imp->iananame, imp->ianacode, codec_rate, imp->microseconds_per_packet / 1000, bit_rate, imp->number_of_channels);
4295 
4296  if (m_idx >= MAX_MATCHES) {
4297  break;
4298  }
4299 
4300  match = 0;
4301  }
4302  }
4303 
4304  if (m_idx >= MAX_MATCHES) {
4305  break;
4306  }
4307  }
4308 
4309  if (smh->crypto_mode == CRYPTO_MODE_MANDATORY && got_crypto < 1) {
4310  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Crypto not negotiated but required.\n");
4311  match = 0;
4312  m_idx = nm_idx = 0;
4313  }
4314 
4315 
4316  if (!m_idx && nm_idx) {
4317  int j;
4318 
4319  for(j = 0; j < nm_idx; j++) {
4320  const switch_codec_implementation_t *search[1];
4321  char *prefs[1];
4322  char tmp[80];
4323  int num;
4324  const switch_codec_implementation_t *timp = NULL;
4325 
4326  near_rate = near_matches[j].rate;
4327  near_match = near_matches[j].imp;
4328  near_map = near_matches[j].map;
4329 
4330  switch_snprintf(tmp, sizeof(tmp), "%s@%uh@%ui%dc", near_match->iananame, near_rate ? near_rate : near_match->samples_per_second,
4331  codec_ms, near_match->number_of_channels);
4332 
4333  prefs[0] = tmp;
4334  num = switch_loadable_module_get_codecs_sorted(search, 1, prefs, 1);
4335 
4336  if (num) {
4337  timp = search[0];
4338  } else {
4339  timp = near_match;
4340  }
4341 
4342  if (!maxptime || timp->microseconds_per_packet / 1000 <= maxptime) {
4343  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Substituting codec %s@%ui@%uh@%dc\n",
4345  match = 1;
4346 
4347  matches[m_idx].codec_idx = near_matches[j].codec_idx;
4348  matches[m_idx].rate = near_rate;
4349  matches[m_idx].imp = timp;
4350  matches[m_idx].map = near_map;
4351  m_idx++;
4352 
4353  break;
4354  }
4355  }
4356  }
4357 
4358  if (m_idx) {
4359  int j;
4360 
4361  if (greedy) { /* sort in favor of mine */
4362  greedy_sort(smh, matches, m_idx, codec_array, total_codecs);
4363  }
4364 
4365  match = 1;
4366  a_engine->codec_negotiated = 1;
4367  smh->num_negotiated_codecs = 0;
4368 
4369  for(j = 0; j < m_idx; j++) {
4372  matches[j].map->rm_encoding,
4373  matches[j].imp->modname,
4374  matches[j].map->rm_fmtp,
4375  sdp_type,
4376  matches[j].map->rm_pt,
4377  matches[j].imp->samples_per_second,
4378  matches[j].imp->microseconds_per_packet / 1000,
4379  matches[j].imp->number_of_channels,
4380  SWITCH_TRUE);
4381 
4382  mimp = matches[j].imp;
4383  mmap = matches[j].map;
4384 
4385  if (j == 0) {
4386  a_engine->cur_payload_map = pmap;
4387  a_engine->cur_payload_map->current = 1;
4388  if (a_engine->rtp_session) {
4389  switch_rtp_set_default_payload(a_engine->rtp_session, pmap->pt);
4390  }
4391  }
4392 
4393  pmap->rm_encoding = switch_core_session_strdup(session, (char *) mmap->rm_encoding);
4394  pmap->iananame = switch_core_session_strdup(session, (char *) mimp->iananame);
4395  pmap->recv_pt = (switch_payload_t) mmap->rm_pt;
4396  pmap->rm_rate = mimp->samples_per_second;
4397  pmap->adv_rm_rate = mimp->samples_per_second;
4398  if (strcasecmp(mimp->iananame, "g722")) {
4399  pmap->rm_rate = mimp->actual_samples_per_second;
4400  }
4401  pmap->codec_ms = mimp->microseconds_per_packet / 1000;
4402  pmap->bitrate = mimp->bits_per_second;
4403  pmap->channels = mmap->rm_params ? atoi(mmap->rm_params) : 1;
4404 
4405  if (!strcasecmp((char *) mmap->rm_encoding, "opus")) {
4406  if (pmap->channels == 1) {
4407  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Invalid SDP for opus. Don't ask.. but it needs a /2\n");
4408  pmap->adv_channels = 1;
4409  } else {
4410  pmap->adv_channels = 2; /* IKR ???*/
4411  }
4412  if (!zstr((char *) mmap->rm_fmtp) && switch_stristr("stereo=1", (char *) mmap->rm_fmtp)) {
4413  pmap->channels = 2;
4414  } else {
4415  pmap->channels = 1;
4416  }
4417  } else {