1 /*
2 * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3 * Copyright (C) 2005-2018, 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 * Seven Du <dujinfang@gmail.com>
28 *
29 * switch_core_media.c -- Core Media
30 *
31 */
32
33 #include <switch.h>
34 #include <switch_ssl.h>
35 #include <switch_stun.h>
36 #include <switch_nat.h>
37 #include "private/switch_core_pvt.h"
38 #include <switch_curl.h>
39 #include <errno.h>
40 #include <sofia-sip/sdp.h>
41 #include <sofia-sip/su.h>
42
43 static switch_t38_options_t * switch_core_media_process_udptl(switch_core_session_t *session, sdp_session_t *sdp, sdp_media_t *m);
44 static void switch_core_media_find_zrtp_hash(switch_core_session_t *session, sdp_session_t *sdp);
45 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);
46 static void gen_ice(switch_core_session_t *session, switch_media_type_t type, const char *ip, switch_port_t port);
47 //#define GOOGLE_ICE
48 #define RTCP_MUX
49 #define MAX_CODEC_CHECK_FRAMES 50//x:mod_sofia.h
50 #define MAX_MISMATCH_FRAMES 5//x:mod_sofia.h
51 #define type2str(type) type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : (type == SWITCH_MEDIA_TYPE_AUDIO ? "audio" : "text")
52 #define VIDEO_REFRESH_FREQ 1000000
53
54 #define TEXT_TIMER_MS 100
55 #define TEXT_TIMER_SAMPLES 10
56 #define TEXT_PERIOD_TIMEOUT 3000
57 #define MAX_RED_FRAMES 25
58 #define RED_PACKET_SIZE 100
59
60 typedef enum {
61 SMF_INIT = (1 << 0),
62 SMF_READY = (1 << 1),
63 SMF_JB_PAUSED = (1 << 2),
64 SMF_VB_PAUSED = (1 << 3)
65 } smh_flag_t;
66
67 typedef struct core_video_globals_s {
68 int cpu_count;
69 int cur_cpu;
70 switch_memory_pool_t *pool;
71 switch_mutex_t *mutex;
72 uint32_t fps;
73 uint32_t synced;
74 } core_video_globals_t;
75
76 static core_video_globals_t video_globals = { 0 };
77
78 struct media_helper {
79 switch_core_session_t *session;
80 switch_thread_cond_t *cond;
81 switch_mutex_t *cond_mutex;
82 switch_mutex_t *file_read_mutex;
83 switch_mutex_t *file_write_mutex;
84 int up;
85 int ready;
86 };
87
88 typedef enum {
89 CRYPTO_MODE_OPTIONAL,
90 CRYPTO_MODE_MANDATORY,
91 CRYPTO_MODE_FORBIDDEN
92 } switch_rtp_crypto_mode_t;
93
94 struct switch_rtp_text_factory_s {
95 switch_memory_pool_t *pool;
96 switch_frame_t text_frame;
97 int red_level;
98 switch_byte_t *text_write_frame_data;
99 switch_frame_t text_write_frame;
100 switch_buffer_t *write_buffer;
101 int write_empty;
102 switch_byte_t *red_buf[MAX_RED_FRAMES];
103 int red_bufsize;
104 int red_buflen[MAX_RED_FRAMES];
105 uint32_t red_ts[MAX_RED_FRAMES];
106 int red_pos;
107 int red_max;
108 switch_timer_t timer;
109 };
110
111
112 typedef struct switch_rtp_engine_s {
113 switch_secure_settings_t ssec[CRYPTO_INVALID+1];
114 switch_rtp_crypto_key_type_t crypto_type;
115
116 switch_media_type_t type;
117
118 switch_rtp_t *rtp_session;
119 switch_frame_t read_frame;
120 switch_codec_t read_codec;
121 switch_codec_t write_codec;
122
123 switch_codec_implementation_t read_impl;
124 switch_codec_implementation_t write_impl;
125
126 switch_size_t last_ts;
127 switch_size_t last_seq;
128 uint32_t check_frames;
129 uint32_t mismatch_count;
130 uint32_t last_codec_ms;
131 uint8_t codec_reinvites;
132 uint32_t max_missed_packets;
133 uint32_t max_missed_hold_packets;
134 uint32_t media_timeout;
135 uint32_t media_hold_timeout;
136 uint32_t ssrc;
137 uint32_t remote_ssrc;
138 switch_port_t remote_rtcp_port;
139 switch_rtp_bug_flag_t rtp_bugs;
140
141
142 char *local_sdp_ip;
143 switch_port_t local_sdp_port;
144 char *adv_sdp_ip;
145 switch_port_t adv_sdp_port;
146 char *proxy_sdp_ip;
147 switch_port_t proxy_sdp_port;
148
149
150 /** ZRTP **/
151 char *local_sdp_zrtp_hash;
152 char *remote_sdp_zrtp_hash;
153
154 payload_map_t *cur_payload_map;
155 payload_map_t *payload_map;
156 payload_map_t *pmap_tail;
157
158 uint32_t timestamp_send;
159
160 char *cand_acl[SWITCH_MAX_CAND_ACL];
161 int cand_acl_count;
162
163 ice_t ice_in;
164 ice_t ice_out;
165
166 int8_t rtcp_mux;
167
168 dtls_fingerprint_t local_dtls_fingerprint;
169 dtls_fingerprint_t remote_dtls_fingerprint;
170
171 char *remote_rtp_ice_addr;
172 switch_port_t remote_rtp_ice_port;
173
174 char *remote_rtcp_ice_addr;
175 switch_port_t remote_rtcp_ice_port;
176
177 struct media_helper mh;
178 switch_thread_t *media_thread;
179
180
181 uint8_t reset_codec;
182 uint8_t codec_negotiated;
183
184 uint8_t fir;
185 uint8_t pli;
186 uint8_t nack;
187 uint8_t tmmbr;
188 uint8_t no_crypto;
189 uint8_t dtls_controller;
190 uint8_t pass_codecs;
191 switch_codec_settings_t codec_settings;
192 switch_media_flow_t rmode;
193 switch_media_flow_t smode;
194 switch_thread_id_t thread_id;
195 switch_thread_id_t thread_write_lock;
196 uint8_t new_ice;
197 uint8_t new_dtls;
198 uint32_t sdp_bw;
199 uint32_t orig_bitrate;
200 float bw_mult;
201 uint8_t reject_avp;
202 int t140_pt;
203 int red_pt;
204 switch_rtp_text_factory_t *tf;
205
206 switch_engine_function_t engine_function;
207 void *engine_user_data;
208 int8_t engine_function_running;
209 switch_frame_buffer_t *write_fb;
210 } switch_rtp_engine_t;
211
212 #define MAX_REJ_STREAMS 10
213
214 struct switch_media_handle_s {
215 switch_core_session_t *session;
216 switch_channel_t *channel;
217 switch_core_media_flag_t media_flags[SCMF_MAX];
218 smh_flag_t flags;
219 switch_rtp_engine_t engines[SWITCH_MEDIA_TYPE_TOTAL];
220 switch_msrp_session_t *msrp_session;
221 switch_mutex_t *read_mutex[SWITCH_MEDIA_TYPE_TOTAL];
222 switch_mutex_t *write_mutex[SWITCH_MEDIA_TYPE_TOTAL];
223 char *codec_order[SWITCH_MAX_CODECS];
224 int codec_order_last;
225 const switch_codec_implementation_t *codecs[SWITCH_MAX_CODECS];
226 char fmtp[SWITCH_MAX_CODECS][MAX_FMTP_LEN];
227 int payload_space;
228 char *origin;
229
230 sdp_media_e rejected_streams[MAX_REJ_STREAMS];
231 int rej_idx;
232
233 switch_mutex_t *mutex;
234 switch_mutex_t *sdp_mutex;
235 switch_mutex_t *control_mutex;
236
237 const switch_codec_implementation_t *negotiated_codecs[SWITCH_MAX_CODECS];
238 int num_negotiated_codecs;
239 switch_payload_t ianacodes[SWITCH_MAX_CODECS];
240 switch_payload_t dtmf_ianacodes[SWITCH_MAX_CODECS];
241 switch_payload_t cng_ianacodes[SWITCH_MAX_CODECS];
242 char *fmtps[SWITCH_MAX_CODECS];
243 int video_count;
244
245 int rates[SWITCH_MAX_CODECS];
246 uint32_t num_rates;
247
248 uint32_t owner_id;
249 uint32_t session_id;
250
251 switch_core_media_params_t *mparams;
252
253 char *msid;
254 char *cname;
255
256 switch_rtp_crypto_mode_t crypto_mode;
257 switch_rtp_crypto_key_type_t crypto_suite_order[CRYPTO_INVALID+1];
258 switch_time_t video_last_key_time;
259 switch_time_t video_init;
260 switch_time_t last_codec_refresh;
261 switch_time_t last_video_refresh_req;
262 switch_timer_t video_timer;
263
264
265 switch_vid_params_t vid_params;
266 switch_file_handle_t *video_read_fh;
267 switch_file_handle_t *video_write_fh;
268
269 uint64_t vid_frames;
270 time_t vid_started;
271 int ready_loops;
272
273 switch_thread_t *video_write_thread;
274 int video_write_thread_running;
275
276 switch_time_t last_text_frame;
277
278 };
279
280 switch_srtp_crypto_suite_t SUITES[CRYPTO_INVALID] = {
281 { "AEAD_AES_256_GCM_8", "", AEAD_AES_256_GCM_8, 44, 12},
282 { "AEAD_AES_128_GCM_8", "", AEAD_AES_128_GCM_8, 28, 12},
283 { "AES_256_CM_HMAC_SHA1_80", "AES_CM_256_HMAC_SHA1_80", AES_CM_256_HMAC_SHA1_80, 46, 14},
284 { "AES_192_CM_HMAC_SHA1_80", "AES_CM_192_HMAC_SHA1_80", AES_CM_192_HMAC_SHA1_80, 38, 14},
285 { "AES_CM_128_HMAC_SHA1_80", "", AES_CM_128_HMAC_SHA1_80, 30, 14},
286 { "AES_256_CM_HMAC_SHA1_32", "AES_CM_256_HMAC_SHA1_32", AES_CM_256_HMAC_SHA1_32, 46, 14},
287 { "AES_192_CM_HMAC_SHA1_32", "AES_CM_192_HMAC_SHA1_32", AES_CM_192_HMAC_SHA1_32, 38, 14},
288 { "AES_CM_128_HMAC_SHA1_32", "", AES_CM_128_HMAC_SHA1_32, 30, 14},
289 { "AES_CM_128_NULL_AUTH", "", AES_CM_128_NULL_AUTH, 30, 14}
290 };
291
switch_core_media_crypto_str2type(const char * str)292 SWITCH_DECLARE(switch_rtp_crypto_key_type_t) switch_core_media_crypto_str2type(const char *str)
293 {
294 int i;
295
296 for (i = 0; i < CRYPTO_INVALID; i++) {
297 if (!strncasecmp(str, SUITES[i].name, strlen(SUITES[i].name)) || (SUITES[i].alias && strlen(SUITES[i].alias) && !strncasecmp(str, SUITES[i].alias, strlen(SUITES[i].alias)))) {
298 return SUITES[i].type;
299 }
300 }
301
302 return CRYPTO_INVALID;
303 }
304
305
switch_core_media_crypto_type2str(switch_rtp_crypto_key_type_t type)306 SWITCH_DECLARE(const char *) switch_core_media_crypto_type2str(switch_rtp_crypto_key_type_t type)
307 {
308 switch_assert(type < CRYPTO_INVALID);
309 return SUITES[type].name;
310 }
311
312
switch_core_media_crypto_keysalt_len(switch_rtp_crypto_key_type_t type)313 SWITCH_DECLARE(int) switch_core_media_crypto_keysalt_len(switch_rtp_crypto_key_type_t type)
314 {
315 switch_assert(type < CRYPTO_INVALID);
316 return SUITES[type].keysalt_len;
317 }
318
switch_core_media_crypto_salt_len(switch_rtp_crypto_key_type_t type)319 SWITCH_DECLARE(int) switch_core_media_crypto_salt_len(switch_rtp_crypto_key_type_t type)
320 {
321 switch_assert(type < CRYPTO_INVALID);
322 return SUITES[type].salt_len;
323 }
324
325 static const char* CRYPTO_KEY_PARAM_METHOD[CRYPTO_KEY_PARAM_METHOD_INVALID] = {
326 [CRYPTO_KEY_PARAM_METHOD_INLINE] = "inline",
327 };
328
sdp_media_flow(unsigned in)329 static inline switch_media_flow_t sdp_media_flow(unsigned in)
330 {
331 switch(in) {
332 case sdp_sendonly:
333 return SWITCH_MEDIA_FLOW_SENDONLY;
334 case sdp_recvonly:
335 return SWITCH_MEDIA_FLOW_RECVONLY;
336 case sdp_sendrecv:
337 return SWITCH_MEDIA_FLOW_SENDRECV;
338 case sdp_inactive:
339 return SWITCH_MEDIA_FLOW_INACTIVE;
340 }
341
342 return SWITCH_MEDIA_FLOW_SENDRECV;
343 }
344
get_channels(const char * name,int dft)345 static int get_channels(const char *name, int dft)
346 {
347
348 if (!zstr(name) && !switch_true(switch_core_get_variable("NDLB_broken_opus_sdp")) && !strcasecmp(name, "opus")) {
349 return 2; /* IKR???*/
350 }
351
352 return dft ? dft : 1;
353 }
354
_switch_core_media_pass_zrtp_hash2(switch_core_session_t * aleg_session,switch_core_session_t * bleg_session,switch_media_type_t type)355 static void _switch_core_media_pass_zrtp_hash2(switch_core_session_t *aleg_session, switch_core_session_t *bleg_session, switch_media_type_t type)
356 {
357 switch_rtp_engine_t *aleg_engine;
358 switch_rtp_engine_t *bleg_engine;
359
360 if (!aleg_session->media_handle || !bleg_session->media_handle) return;
361 aleg_engine = &aleg_session->media_handle->engines[type];
362 bleg_engine = &bleg_session->media_handle->engines[type];
363
364
365
366 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(aleg_session->channel), SWITCH_LOG_DEBUG1,
367 "Deciding whether to pass zrtp-hash between a-leg and b-leg\n");
368
369 if (!(switch_channel_test_flag(aleg_session->channel, CF_ZRTP_PASSTHRU_REQ))) {
370 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(aleg_session->channel), SWITCH_LOG_DEBUG1,
371 "CF_ZRTP_PASSTHRU_REQ not set on a-leg, so not propagating zrtp-hash\n");
372 return;
373 }
374
375 if (aleg_engine->remote_sdp_zrtp_hash) {
376 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(aleg_session->channel), SWITCH_LOG_DEBUG, "Passing a-leg remote zrtp-hash (audio) to b-leg\n");
377 bleg_engine->local_sdp_zrtp_hash = switch_core_session_strdup(bleg_session, aleg_engine->remote_sdp_zrtp_hash);
378 switch_channel_set_variable(bleg_session->channel, "l_sdp_audio_zrtp_hash", bleg_engine->local_sdp_zrtp_hash);
379 }
380
381 if (bleg_engine->remote_sdp_zrtp_hash) {
382 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(aleg_session->channel), SWITCH_LOG_DEBUG, "Passing b-leg remote zrtp-hash (audio) to a-leg\n");
383 aleg_engine->local_sdp_zrtp_hash = switch_core_session_strdup(aleg_session, bleg_engine->remote_sdp_zrtp_hash);
384 switch_channel_set_variable(aleg_session->channel, "l_sdp_audio_zrtp_hash", aleg_engine->local_sdp_zrtp_hash);
385 }
386 }
387
switch_core_media_get_video_fps(switch_core_session_t * session)388 SWITCH_DECLARE(uint32_t) switch_core_media_get_video_fps(switch_core_session_t *session)
389 {
390 switch_media_handle_t *smh;
391 time_t now;
392 uint32_t fps, elapsed = 0;
393
394 switch_assert(session);
395
396 if (!(smh = session->media_handle)) {
397 return SWITCH_STATUS_FALSE;
398 }
399
400 if (!switch_channel_test_flag(session->channel, CF_VIDEO)) {
401 return 0;
402 }
403
404 now = switch_epoch_time_now(NULL);
405
406 elapsed = now - smh->vid_started;
407
408 if (!(smh->vid_started && smh->vid_frames && elapsed > 0)) {
409 return 0;
410 }
411
412 fps = switch_round_to_step(smh->vid_frames / (elapsed), 5);
413
414 if (smh->vid_frames > 1000) {
415 smh->vid_started = switch_epoch_time_now(NULL);
416 smh->vid_frames = 1;
417 }
418
419 if (fps > 0) {
420 video_globals.fps = fps;
421
422 if (smh->vid_params.fps != fps) {
423 switch_channel_set_variable_printf(session->channel, "video_fps", "%d", fps);
424 smh->vid_params.fps = fps;
425 }
426 }
427
428 return fps;
429 }
430
switch_core_media_pass_zrtp_hash2(switch_core_session_t * aleg_session,switch_core_session_t * bleg_session)431 SWITCH_DECLARE(void) switch_core_media_pass_zrtp_hash2(switch_core_session_t *aleg_session, switch_core_session_t *bleg_session)
432 {
433 _switch_core_media_pass_zrtp_hash2(aleg_session, bleg_session, SWITCH_MEDIA_TYPE_AUDIO);
434 _switch_core_media_pass_zrtp_hash2(aleg_session, bleg_session, SWITCH_MEDIA_TYPE_VIDEO);
435 _switch_core_media_pass_zrtp_hash2(aleg_session, bleg_session, SWITCH_MEDIA_TYPE_TEXT);
436 }
437
438
switch_core_media_pass_zrtp_hash(switch_core_session_t * session)439 SWITCH_DECLARE(void) switch_core_media_pass_zrtp_hash(switch_core_session_t *session)
440 {
441 switch_channel_t *channel = switch_core_session_get_channel(session);
442
443 switch_core_session_t *other_session;
444 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG1, "Deciding whether to pass zrtp-hash between legs\n");
445 if (!(switch_channel_test_flag(channel, CF_ZRTP_PASSTHRU_REQ))) {
446 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG1, "CF_ZRTP_PASSTHRU_REQ not set, so not propagating zrtp-hash\n");
447 return;
448 } else if (!(switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS)) {
449 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG1, "No partner channel found, so not propagating zrtp-hash\n");
450 return;
451 } else {
452 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG1, "Found peer channel; propagating zrtp-hash if set\n");
453 switch_core_media_pass_zrtp_hash2(session, other_session);
454 switch_core_session_rwunlock(other_session);
455 }
456 }
457
switch_core_media_get_zrtp_hash(switch_core_session_t * session,switch_media_type_t type,switch_bool_t local)458 SWITCH_DECLARE(const char *) switch_core_media_get_zrtp_hash(switch_core_session_t *session, switch_media_type_t type, switch_bool_t local)
459 {
460 switch_rtp_engine_t *engine;
461 if (!session->media_handle) return NULL;
462
463 engine = &session->media_handle->engines[type];
464
465 if (local) {
466 return engine->local_sdp_zrtp_hash;
467 }
468
469
470 return engine->remote_sdp_zrtp_hash;
471
472 }
473
switch_core_media_find_zrtp_hash(switch_core_session_t * session,sdp_session_t * sdp)474 static void switch_core_media_find_zrtp_hash(switch_core_session_t *session, sdp_session_t *sdp)
475 {
476 switch_channel_t *channel = switch_core_session_get_channel(session);
477 switch_rtp_engine_t *audio_engine;
478 switch_rtp_engine_t *video_engine;
479 switch_rtp_engine_t *text_engine;
480 sdp_media_t *m;
481 sdp_attribute_t *attr;
482 int got_audio = 0, got_video = 0, got_text = 0;
483
484 if (!session->media_handle) return;
485
486 audio_engine = &session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO];
487 video_engine = &session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO];
488 text_engine = &session->media_handle->engines[SWITCH_MEDIA_TYPE_TEXT];
489
490
491 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG1, "Looking for zrtp-hash\n");
492 for (m = sdp->sdp_media; m; m = m->m_next) {
493 if (got_audio && got_video && got_text) break;
494 if (m->m_port && ((m->m_type == sdp_media_audio && !got_audio)
495 || (m->m_type == sdp_media_video && !got_video))) {
496 for (attr = m->m_attributes; attr; attr = attr->a_next) {
497 if (zstr(attr->a_name)) continue;
498 if (strcasecmp(attr->a_name, "zrtp-hash") || !(attr->a_value)) continue;
499 if (m->m_type == sdp_media_audio) {
500 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG,
501 "Found audio zrtp-hash; setting r_sdp_audio_zrtp_hash=%s\n", attr->a_value);
502 switch_channel_set_variable(channel, "r_sdp_audio_zrtp_hash", attr->a_value);
503 audio_engine->remote_sdp_zrtp_hash = switch_core_session_strdup(session, attr->a_value);
504 got_audio++;
505 } else if (m->m_type == sdp_media_video) {
506 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG,
507 "Found video zrtp-hash; setting r_sdp_video_zrtp_hash=%s\n", attr->a_value);
508 switch_channel_set_variable(channel, "r_sdp_video_zrtp_hash", attr->a_value);
509 video_engine->remote_sdp_zrtp_hash = switch_core_session_strdup(session, attr->a_value);
510 got_video++;
511 } else if (m->m_type == sdp_media_text) {
512 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG,
513 "Found text zrtp-hash; setting r_sdp_video_zrtp_hash=%s\n", attr->a_value);
514 switch_channel_set_variable(channel, "r_sdp_text_zrtp_hash", attr->a_value);
515 text_engine->remote_sdp_zrtp_hash = switch_core_session_strdup(session, attr->a_value);
516 got_text++;
517 }
518 switch_channel_set_flag(channel, CF_ZRTP_HASH);
519 break;
520 }
521 }
522 }
523 }
524
525
switch_core_media_process_udptl(switch_core_session_t * session,sdp_session_t * sdp,sdp_media_t * m)526 static switch_t38_options_t * switch_core_media_process_udptl(switch_core_session_t *session, sdp_session_t *sdp, sdp_media_t *m)
527 {
528 switch_t38_options_t *t38_options = switch_channel_get_private(session->channel, "t38_options");
529 sdp_attribute_t *attr;
530
531 switch_assert(sdp);
532
533 if (!t38_options) {
534 t38_options = switch_core_session_alloc(session, sizeof(switch_t38_options_t));
535
536 // set some default value
537 t38_options->T38FaxVersion = 0;
538 t38_options->T38MaxBitRate = 14400;
539 t38_options->T38FaxRateManagement = switch_core_session_strdup(session, "transferredTCF");
540 t38_options->T38FaxUdpEC = switch_core_session_strdup(session, "t38UDPRedundancy");
541 t38_options->T38FaxMaxBuffer = 500;
542 t38_options->T38FaxMaxDatagram = 500;
543 }
544
545 t38_options->remote_port = (switch_port_t)m->m_port;
546
547 if (sdp->sdp_origin) {
548 t38_options->sdp_o_line = switch_core_session_strdup(session, sdp->sdp_origin->o_username);
549 } else {
550 t38_options->sdp_o_line = "unknown";
551 }
552
553 if (m->m_connections && m->m_connections->c_address) {
554 t38_options->remote_ip = switch_core_session_strdup(session, m->m_connections->c_address);
555 } else if (sdp->sdp_connection && sdp->sdp_connection->c_address) {
556 t38_options->remote_ip = switch_core_session_strdup(session, sdp->sdp_connection->c_address);
557 }
558
559 for (attr = m->m_attributes; attr; attr = attr->a_next) {
560 if (!strcasecmp(attr->a_name, "T38FaxVersion") && attr->a_value) {
561 t38_options->T38FaxVersion = (uint16_t) atoi(attr->a_value);
562 } else if (!strcasecmp(attr->a_name, "T38MaxBitRate") && attr->a_value) {
563 t38_options->T38MaxBitRate = (uint32_t) atoi(attr->a_value);
564 } else if (!strcasecmp(attr->a_name, "T38FaxFillBitRemoval")) {
565 t38_options->T38FaxFillBitRemoval = switch_safe_atoi(attr->a_value, 1);
566 } else if (!strcasecmp(attr->a_name, "T38FaxTranscodingMMR")) {
567 t38_options->T38FaxTranscodingMMR = switch_safe_atoi(attr->a_value, 1);
568 } else if (!strcasecmp(attr->a_name, "T38FaxTranscodingJBIG")) {
569 t38_options->T38FaxTranscodingJBIG = switch_safe_atoi(attr->a_value, 1);
570 } else if (!strcasecmp(attr->a_name, "T38FaxRateManagement") && attr->a_value) {
571 t38_options->T38FaxRateManagement = switch_core_session_strdup(session, attr->a_value);
572 } else if (!strcasecmp(attr->a_name, "T38FaxMaxBuffer") && attr->a_value) {
573 t38_options->T38FaxMaxBuffer = (uint32_t) atoi(attr->a_value);
574 } else if (!strcasecmp(attr->a_name, "T38FaxMaxDatagram") && attr->a_value) {
575 t38_options->T38FaxMaxDatagram = (uint32_t) atoi(attr->a_value);
576 } else if (!strcasecmp(attr->a_name, "T38FaxUdpEC") && attr->a_value) {
577 t38_options->T38FaxUdpEC = switch_core_session_strdup(session, attr->a_value);
578 } else if (!strcasecmp(attr->a_name, "T38VendorInfo") && attr->a_value) {
579 t38_options->T38VendorInfo = switch_core_session_strdup(session, attr->a_value);
580 }
581 }
582
583 switch_channel_set_variable(session->channel, "has_t38", "true");
584 switch_channel_set_private(session->channel, "t38_options", t38_options);
585 switch_channel_set_app_flag_key("T38", session->channel, CF_APP_T38);
586
587 switch_channel_execute_on(session->channel, "sip_execute_on_image");
588 switch_channel_api_on(session->channel, "sip_api_on_image");
589
590 return t38_options;
591 }
592
switch_core_media_check_autoadj(switch_core_session_t * session)593 SWITCH_DECLARE(switch_status_t) switch_core_media_check_autoadj(switch_core_session_t *session)
594 {
595 switch_rtp_engine_t *a_engine;
596 switch_rtp_engine_t *v_engine;
597 switch_rtp_engine_t *t_engine;
598 switch_media_handle_t *smh;
599 const char *val;
600 int x = 0;
601
602 switch_assert(session);
603
604 if (!(smh = session->media_handle)) {
605 return SWITCH_STATUS_FALSE;
606 }
607
608 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
609 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
610 t_engine = &smh->engines[SWITCH_MEDIA_TYPE_TEXT];
611
612 if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) &&
613 !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")) && switch_true(val)) &&
614 !switch_channel_test_flag(session->channel, CF_AVPF)) {
615 /* Reactivate the NAT buster flag. */
616
617 if (a_engine->rtp_session) {
618 switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_AUTOADJ);
619 x++;
620 }
621
622 if (v_engine->rtp_session) {
623 switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_AUTOADJ);
624 x++;
625 }
626
627 if (t_engine->rtp_session) {
628 switch_rtp_set_flag(t_engine->rtp_session, SWITCH_RTP_FLAG_AUTOADJ);
629 x++;
630 }
631 }
632
633 return x ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
634 }
635
switch_core_media_get_vid_params(switch_core_session_t * session,switch_vid_params_t * vid_params)636 SWITCH_DECLARE(switch_status_t) switch_core_media_get_vid_params(switch_core_session_t *session, switch_vid_params_t *vid_params)
637 {
638 switch_media_handle_t *smh;
639
640 switch_assert(session);
641
642 if (!(smh = session->media_handle)) {
643 return SWITCH_STATUS_FALSE;
644 }
645
646 switch_mutex_lock(smh->control_mutex);
647 *vid_params = smh->vid_params;
648 switch_mutex_unlock(smh->control_mutex);
649
650 return SWITCH_STATUS_SUCCESS;
651 }
652
switch_core_media_extract_t38_options(switch_core_session_t * session,const char * r_sdp)653 SWITCH_DECLARE(switch_t38_options_t *) switch_core_media_extract_t38_options(switch_core_session_t *session, const char *r_sdp)
654 {
655 sdp_media_t *m;
656 sdp_parser_t *parser = NULL;
657 sdp_session_t *sdp;
658 switch_t38_options_t *t38_options = NULL;
659
660 if (!(parser = sdp_parse(NULL, r_sdp, (int) strlen(r_sdp), 0))) {
661 return NULL;
662 }
663
664 if (!(sdp = sdp_session(parser))) {
665 sdp_parser_free(parser);
666 return NULL;
667 }
668
669 for (m = sdp->sdp_media; m; m = m->m_next) {
670 if (m->m_proto == sdp_proto_udptl && m->m_type == sdp_media_image && m->m_port) {
671 t38_options = switch_core_media_process_udptl(session, sdp, m);
672 break;
673 }
674 }
675
676 sdp_parser_free(parser);
677
678 return t38_options;
679
680 }
681
682
683
684 //?
switch_core_media_process_t38_passthru(switch_core_session_t * session,switch_core_session_t * other_session,switch_t38_options_t * t38_options)685 SWITCH_DECLARE(switch_status_t) switch_core_media_process_t38_passthru(switch_core_session_t *session,
686 switch_core_session_t *other_session, switch_t38_options_t *t38_options)
687 {
688 char *remote_host;
689 switch_port_t remote_port;
690 char tmp[32] = "";
691 switch_rtp_engine_t *a_engine;
692 switch_media_handle_t *smh;
693
694 switch_assert(session);
695
696 if (!(smh = session->media_handle)) {
697 return SWITCH_STATUS_FALSE;
698 }
699
700 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
701
702 remote_host = switch_rtp_get_remote_host(a_engine->rtp_session);
703 remote_port = switch_rtp_get_remote_port(a_engine->rtp_session);
704
705 a_engine->cur_payload_map->remote_sdp_ip = switch_core_session_strdup(session, t38_options->remote_ip);
706 a_engine->cur_payload_map->remote_sdp_port = t38_options->remote_port;
707
708 if (remote_host && remote_port && !strcmp(remote_host, a_engine->cur_payload_map->remote_sdp_ip) &&
709 remote_port == a_engine->cur_payload_map->remote_sdp_port) {
710 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
711 "Audio params are unchanged for %s.\n",
712 switch_channel_get_name(session->channel));
713 } else {
714 const char *err = NULL;
715
716 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
717 "Audio params changed for %s from %s:%d to %s:%d\n",
718 switch_channel_get_name(session->channel),
719 remote_host, remote_port, a_engine->cur_payload_map->remote_sdp_ip, a_engine->cur_payload_map->remote_sdp_port);
720
721 switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->cur_payload_map->remote_sdp_port);
722 switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, a_engine->cur_payload_map->remote_sdp_ip);
723 switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp);
724 if (switch_rtp_set_remote_address(a_engine->rtp_session, a_engine->cur_payload_map->remote_sdp_ip,
725 a_engine->cur_payload_map->remote_sdp_port, 0, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
726 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", err);
727 switch_channel_hangup(session->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
728 }
729 switch_channel_execute_on(session->channel, "execute_on_audio_change");
730 }
731
732 switch_core_media_copy_t38_options(t38_options, other_session);
733
734 return SWITCH_STATUS_SUCCESS;
735
736 }
737
switch_core_session_get_payload_code(switch_core_session_t * session,switch_media_type_t type,const char * iananame,uint32_t rate,const char * fmtp_in,switch_payload_t * ptP,switch_payload_t * recv_ptP,char ** fmtpP)738 SWITCH_DECLARE(switch_status_t) switch_core_session_get_payload_code(switch_core_session_t *session,
739 switch_media_type_t type,
740 const char *iananame,
741 uint32_t rate,
742 const char *fmtp_in,
743 switch_payload_t *ptP,
744 switch_payload_t *recv_ptP,
745 char **fmtpP)
746 {
747 payload_map_t *pmap;
748 switch_media_handle_t *smh;
749 switch_rtp_engine_t *engine;
750 switch_payload_t pt = 0, recv_pt = 0;
751 int found = 0;
752 char *fmtp = NULL;
753
754 switch_assert(session);
755
756 if (!(smh = session->media_handle)) {
757 return SWITCH_STATUS_FALSE;
758 }
759
760 engine = &smh->engines[type];
761
762 switch_mutex_lock(smh->sdp_mutex);
763 for (pmap = engine->payload_map; pmap ; pmap = pmap->next) {
764 char *fmtp_a = pmap->rm_fmtp;
765
766 if (!pmap->allocated) continue;
767
768 if (!fmtp_a) fmtp_a = "";
769 if (!fmtp_in) fmtp_in = "";
770
771
772 if (!strcasecmp(pmap->iananame, iananame) && !strcasecmp(fmtp_a, fmtp_in) && (!rate || (rate == pmap->rate))) {
773 pt = pmap->pt;
774 recv_pt = pmap->recv_pt;
775 fmtp = pmap->rm_fmtp;
776 found++;
777 break;
778 }
779 }
780 switch_mutex_unlock(smh->sdp_mutex);
781
782 if (found) {
783 if (ptP) {
784 *ptP = pt;
785 }
786 if (recv_ptP) {
787 *recv_ptP = recv_pt;
788 }
789
790 if (!zstr(fmtp) && fmtpP) {
791 *fmtpP = fmtp;
792 }
793
794 return SWITCH_STATUS_SUCCESS;
795 }
796
797 return SWITCH_STATUS_FALSE;
798
799 }
800
801
switch_core_media_add_payload_map(switch_core_session_t * session,switch_media_type_t type,const char * name,const char * modname,const char * fmtp,switch_sdp_type_t sdp_type,uint32_t pt,uint32_t rate,uint32_t ptime,uint32_t channels,uint8_t negotiated)802 SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_session_t *session,
803 switch_media_type_t type,
804 const char *name,
805 const char *modname,
806 const char *fmtp,
807 switch_sdp_type_t sdp_type,
808 uint32_t pt,
809 uint32_t rate,
810 uint32_t ptime,
811 uint32_t channels,
812 uint8_t negotiated)
813 {
814 payload_map_t *pmap;
815 int exists = 0;
816 switch_media_handle_t *smh;
817 switch_rtp_engine_t *engine;
818
819 switch_assert(session);
820
821 if (!(smh = session->media_handle)) {
822 return NULL;
823 }
824
825 engine = &smh->engines[type];
826
827 switch_mutex_lock(smh->sdp_mutex);
828
829
830 for (pmap = engine->payload_map; pmap && pmap->allocated; pmap = pmap->next) {
831
832 if (sdp_type == SDP_TYPE_RESPONSE) {
833 switch(type) {
834 case SWITCH_MEDIA_TYPE_TEXT:
835 exists = (type == pmap->type && !strcasecmp(name, pmap->iananame));
836 break;
837 case SWITCH_MEDIA_TYPE_AUDIO:
838 exists = (type == pmap->type && !strcasecmp(name, pmap->iananame) && pmap->pt == pt && (!pmap->rate || rate == pmap->rate) && (!pmap->ptime || pmap->ptime == ptime));
839 break;
840 case SWITCH_MEDIA_TYPE_VIDEO:
841 if (sdp_type == SDP_TYPE_RESPONSE) {
842 exists = (pmap->sdp_type == SDP_TYPE_REQUEST && type == pmap->type && !strcasecmp(name, pmap->iananame));
843 } else {
844 exists = (type == pmap->type && !strcasecmp(name, pmap->iananame));
845 }
846 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "CHECK PMAP %s:%s %d %s:%s %d ... %d\n",
847 name, sdp_type == SDP_TYPE_REQUEST ? "REQ" : "RES", pt,
848 pmap->iananame, pmap->sdp_type == SDP_TYPE_REQUEST ? "REQ" : "RES", pmap->pt, exists);
849
850
851 break;
852 }
853
854 if (exists) {
855
856 if (!zstr(fmtp) && !zstr(pmap->rm_fmtp)) {
857 if (strcmp(pmap->rm_fmtp, fmtp)) {
858 exists = 0;
859 continue;
860 }
861 }
862
863 break;
864 }
865
866 } else {
867 if (type == SWITCH_MEDIA_TYPE_TEXT) {
868 exists = (type == pmap->type && !strcasecmp(name, pmap->iananame) && pmap->pt == pt);
869 } else {
870 exists = (type == pmap->type && !strcasecmp(name, pmap->iananame) && pmap->pt == pt && (!pmap->rate || rate == pmap->rate) && (!pmap->ptime || pmap->ptime == ptime));
871 }
872
873 if (exists) {
874 if (type != SWITCH_MEDIA_TYPE_TEXT && !zstr(fmtp) && !zstr(pmap->rm_fmtp)) {
875 if (strcmp(pmap->rm_fmtp, fmtp)) {
876 exists = 0;
877 continue;
878 }
879 }
880
881 break;
882 }
883 }
884 }
885
886 if (!exists) {
887 switch_ssize_t hlen = -1;
888
889 if (engine->payload_map && !engine->payload_map->allocated) {
890 pmap = engine->payload_map;
891 } else {
892 pmap = switch_core_alloc(session->pool, sizeof(*pmap));
893 }
894
895 pmap->type = type;
896 pmap->iananame = switch_core_strdup(session->pool, name);
897 pmap->rm_encoding = pmap->iananame;
898 pmap->hash = switch_ci_hashfunc_default(pmap->iananame, &hlen);
899 pmap->channels = 1;
900 }
901
902 if (ptime) {
903 pmap->ptime = ptime;
904 }
905
906 if (rate) {
907 pmap->rate = rate;
908 }
909
910 if (channels) {
911 pmap->channels = channels;
912 }
913
914 if (modname) {
915 pmap->modname = switch_core_strdup(session->pool, modname);
916 }
917
918 if (!zstr(fmtp)) {
919 if (sdp_type == SDP_TYPE_REQUEST || !exists) {
920 pmap->rm_fmtp = switch_core_strdup(session->pool, fmtp);
921 }
922 }
923
924 pmap->allocated = 1;
925
926 pmap->recv_pt = (switch_payload_t) pt;
927
928
929 if (sdp_type == SDP_TYPE_REQUEST || !exists) {
930 pmap->pt = (switch_payload_t) pt;
931 }
932
933 if (negotiated) {
934 pmap->negotiated = negotiated;
935 }
936
937 if (!exists) {
938 pmap->sdp_type = sdp_type;
939
940 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "ADD PMAP %s %s %d\n", sdp_type == SDP_TYPE_REQUEST ? "REQ" : "RES", name, pt);
941
942 if (pmap == engine->payload_map) {
943 engine->pmap_tail = pmap;
944 } else if (!engine->payload_map) {
945 engine->payload_map = engine->pmap_tail = pmap;
946 } else {
947 engine->pmap_tail->next = pmap;
948 engine->pmap_tail = engine->pmap_tail->next;
949 }
950 }
951
952 switch_mutex_unlock(smh->sdp_mutex);
953
954 return pmap;
955 }
956
957
958
959
switch_core_media_get_codec_string(switch_core_session_t * session)960 SWITCH_DECLARE(const char *)switch_core_media_get_codec_string(switch_core_session_t *session)
961 {
962 const char *preferred = NULL, *fallback = NULL;
963 switch_media_handle_t *smh;
964
965 switch_assert(session);
966
967 if (!(smh = session->media_handle)) {
968 preferred = "PCMU";
969 fallback = "PCMU";
970 } else {
971
972 if (!(preferred = switch_channel_get_variable(session->channel, "absolute_codec_string"))) {
973 preferred = switch_channel_get_variable(session->channel, "codec_string");
974 }
975
976 if (!preferred) {
977 if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
978 preferred = smh->mparams->outbound_codec_string;
979 fallback = smh->mparams->inbound_codec_string;
980
981 } else {
982 preferred = smh->mparams->inbound_codec_string;
983 fallback = smh->mparams->outbound_codec_string;
984 }
985 }
986 }
987
988 return !zstr(preferred) ? preferred : fallback;
989 }
990
switch_core_session_clear_crypto(switch_core_session_t * session)991 SWITCH_DECLARE(void) switch_core_session_clear_crypto(switch_core_session_t *session)
992 {
993 int i;
994 switch_media_handle_t *smh;
995
996 const char *vars[] = { "rtp_last_audio_local_crypto_key",
997 "srtp_remote_audio_crypto_key",
998 "srtp_remote_audio_crypto_tag",
999 "srtp_remote_audio_crypto_type",
1000 "srtp_remote_video_crypto_key",
1001 "srtp_remote_video_crypto_tag",
1002 "srtp_remote_video_crypto_type",
1003 "srtp_remote_text_crypto_key",
1004 "srtp_remote_text_crypto_tag",
1005 "srtp_remote_text_crypto_type",
1006 "rtp_secure_media",
1007 "rtp_secure_media_inbound",
1008 "rtp_secure_media_outbound",
1009 NULL};
1010
1011 for(i = 0; vars[i] ;i++) {
1012 switch_channel_set_variable(session->channel, vars[i], NULL);
1013 }
1014
1015 if (!(smh = session->media_handle)) {
1016 return;
1017 }
1018 for (i = 0; i < CRYPTO_INVALID; i++) {
1019 memset(&smh->engines[SWITCH_MEDIA_TYPE_AUDIO].ssec[i], 0, sizeof(smh->engines[SWITCH_MEDIA_TYPE_AUDIO].ssec[i]));
1020 memset(&smh->engines[SWITCH_MEDIA_TYPE_VIDEO].ssec[i], 0, sizeof(smh->engines[SWITCH_MEDIA_TYPE_VIDEO].ssec[i]));
1021 memset(&smh->engines[SWITCH_MEDIA_TYPE_TEXT].ssec[i], 0, sizeof(smh->engines[SWITCH_MEDIA_TYPE_TEXT].ssec[i]));
1022 }
1023
1024 }
1025
switch_core_session_local_crypto_key(switch_core_session_t * session,switch_media_type_t type)1026 SWITCH_DECLARE(const char *) switch_core_session_local_crypto_key(switch_core_session_t *session, switch_media_type_t type)
1027 {
1028 if (!session->media_handle) {
1029 return NULL;
1030 }
1031
1032 return session->media_handle->engines[type].ssec[session->media_handle->engines[type].crypto_type].local_crypto_key;
1033 }
1034
1035
1036
switch_core_media_parse_rtp_bugs(switch_rtp_bug_flag_t * flag_pole,const char * str)1037 SWITCH_DECLARE(void) switch_core_media_parse_rtp_bugs(switch_rtp_bug_flag_t *flag_pole, const char *str)
1038 {
1039
1040 if (switch_stristr("clear", str)) {
1041 *flag_pole = 0;
1042 }
1043
1044 if (switch_stristr("CISCO_SKIP_MARK_BIT_2833", str)) {
1045 *flag_pole |= RTP_BUG_CISCO_SKIP_MARK_BIT_2833;
1046 }
1047
1048 if (switch_stristr("~CISCO_SKIP_MARK_BIT_2833", str)) {
1049 *flag_pole &= ~RTP_BUG_CISCO_SKIP_MARK_BIT_2833;
1050 }
1051
1052 if (switch_stristr("SONUS_SEND_INVALID_TIMESTAMP_2833", str)) {
1053 *flag_pole |= RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833;
1054 }
1055
1056 if (switch_stristr("~SONUS_SEND_INVALID_TIMESTAMP_2833", str)) {
1057 *flag_pole &= ~RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833;
1058 }
1059
1060 if (switch_stristr("IGNORE_MARK_BIT", str)) {
1061 *flag_pole |= RTP_BUG_IGNORE_MARK_BIT;
1062 }
1063
1064 if (switch_stristr("~IGNORE_MARK_BIT", str)) {
1065 *flag_pole &= ~RTP_BUG_IGNORE_MARK_BIT;
1066 }
1067
1068 if (switch_stristr("SEND_LINEAR_TIMESTAMPS", str)) {
1069 *flag_pole |= RTP_BUG_SEND_LINEAR_TIMESTAMPS;
1070 }
1071
1072 if (switch_stristr("~SEND_LINEAR_TIMESTAMPS", str)) {
1073 *flag_pole &= ~RTP_BUG_SEND_LINEAR_TIMESTAMPS;
1074 }
1075
1076 if (switch_stristr("START_SEQ_AT_ZERO", str)) {
1077 *flag_pole |= RTP_BUG_START_SEQ_AT_ZERO;
1078 }
1079
1080 if (switch_stristr("~START_SEQ_AT_ZERO", str)) {
1081 *flag_pole &= ~RTP_BUG_START_SEQ_AT_ZERO;
1082 }
1083
1084 if (switch_stristr("NEVER_SEND_MARKER", str)) {
1085 *flag_pole |= RTP_BUG_NEVER_SEND_MARKER;
1086 }
1087
1088 if (switch_stristr("~NEVER_SEND_MARKER", str)) {
1089 *flag_pole &= ~RTP_BUG_NEVER_SEND_MARKER;
1090 }
1091
1092 if (switch_stristr("IGNORE_DTMF_DURATION", str)) {
1093 *flag_pole |= RTP_BUG_IGNORE_DTMF_DURATION;
1094 }
1095
1096 if (switch_stristr("~IGNORE_DTMF_DURATION", str)) {
1097 *flag_pole &= ~RTP_BUG_IGNORE_DTMF_DURATION;
1098 }
1099
1100 if (switch_stristr("ACCEPT_ANY_PACKETS", str)) {
1101 *flag_pole |= RTP_BUG_ACCEPT_ANY_PACKETS;
1102 }
1103
1104 if (switch_stristr("~ACCEPT_ANY_PACKETS", str)) {
1105 *flag_pole &= ~RTP_BUG_ACCEPT_ANY_PACKETS;
1106 }
1107
1108 if (switch_stristr("ACCEPT_ANY_PAYLOAD", str)) {
1109 *flag_pole |= RTP_BUG_ACCEPT_ANY_PAYLOAD;
1110 }
1111
1112 if (switch_stristr("~ACCEPT_ANY_PAYLOAD", str)) {
1113 *flag_pole &= ~RTP_BUG_ACCEPT_ANY_PAYLOAD;
1114 }
1115
1116 if (switch_stristr("GEN_ONE_GEN_ALL", str)) {
1117 *flag_pole |= RTP_BUG_GEN_ONE_GEN_ALL;
1118 }
1119
1120 if (switch_stristr("~GEN_ONE_GEN_ALL", str)) {
1121 *flag_pole &= ~RTP_BUG_GEN_ONE_GEN_ALL;
1122 }
1123
1124 if (switch_stristr("CHANGE_SSRC_ON_MARKER", str)) {
1125 *flag_pole |= RTP_BUG_CHANGE_SSRC_ON_MARKER;
1126 }
1127
1128 if (switch_stristr("~CHANGE_SSRC_ON_MARKER", str)) {
1129 *flag_pole &= ~RTP_BUG_CHANGE_SSRC_ON_MARKER;
1130 }
1131
1132 if (switch_stristr("FLUSH_JB_ON_DTMF", str)) {
1133 *flag_pole |= RTP_BUG_FLUSH_JB_ON_DTMF;
1134 }
1135
1136 if (switch_stristr("~FLUSH_JB_ON_DTMF", str)) {
1137 *flag_pole &= ~RTP_BUG_FLUSH_JB_ON_DTMF;
1138 }
1139
1140 if (switch_stristr("ALWAYS_AUTO_ADJUST", str)) {
1141 *flag_pole |= (RTP_BUG_ALWAYS_AUTO_ADJUST | RTP_BUG_ACCEPT_ANY_PACKETS);
1142 }
1143
1144 if (switch_stristr("~ALWAYS_AUTO_ADJUST", str)) {
1145 *flag_pole &= ~(RTP_BUG_ALWAYS_AUTO_ADJUST | RTP_BUG_ACCEPT_ANY_PACKETS);
1146 }
1147 }
1148
1149 /**
1150 * If @use_alias != 0 then send crypto with alias name instead of name.
1151 */
switch_core_media_build_crypto(switch_media_handle_t * smh,switch_media_type_t type,int index,switch_rtp_crypto_key_type_t ctype,switch_rtp_crypto_direction_t direction,int force,int use_alias)1152 static switch_status_t switch_core_media_build_crypto(switch_media_handle_t *smh,
1153 switch_media_type_t type,
1154 int index, switch_rtp_crypto_key_type_t ctype, switch_rtp_crypto_direction_t direction, int force, int use_alias)
1155 {
1156 unsigned char b64_key[512] = "";
1157 unsigned char *key;
1158 const char *val;
1159 switch_channel_t *channel;
1160 char *p;
1161 switch_rtp_engine_t *engine;
1162
1163 switch_assert(smh);
1164 channel = switch_core_session_get_channel(smh->session);
1165
1166 engine = &smh->engines[type];
1167
1168 if (!force && engine->ssec[ctype].local_raw_key[0]) {
1169 return SWITCH_STATUS_SUCCESS;
1170 }
1171
1172 //#define SAME_KEY
1173 #ifdef SAME_KEY
1174 if (switch_channel_test_flag(channel, CF_AVPF) && type == SWITCH_MEDIA_TYPE_VIDEO) {
1175 if (direction == SWITCH_RTP_CRYPTO_SEND) {
1176 memcpy(engine->ssec[ctype].local_raw_key, smh->engines[SWITCH_MEDIA_TYPE_AUDIO].ssec.local_raw_key, SUITES[ctype].keysalt_len);
1177 key = engine->ssec[ctype].local_raw_key;
1178 } else {
1179 memcpy(engine->ssec[ctype].remote_raw_key, smh->engines[SWITCH_MEDIA_TYPE_AUDIO].ssec.remote_raw_key, SUITES[ctype].keysalt_len);
1180 key = engine->ssec[ctype].remote_raw_key;
1181 }
1182 } else {
1183 #endif
1184 if (direction == SWITCH_RTP_CRYPTO_SEND) {
1185 key = engine->ssec[ctype].local_raw_key;
1186 } else {
1187 key = engine->ssec[ctype].remote_raw_key;
1188 }
1189
1190 switch_rtp_get_random(key, SUITES[ctype].keysalt_len);
1191 #ifdef SAME_KEY
1192 }
1193 #endif
1194
1195 switch_b64_encode(key, SUITES[ctype].keysalt_len, b64_key, sizeof(b64_key));
1196 if (switch_channel_var_false(channel, "rtp_pad_srtp_keys")) {
1197 p = strrchr((char *) b64_key, '=');
1198
1199 while (p && *p && *p == '=') {
1200 *p-- = '\0';
1201 }
1202 }
1203
1204 if (index == SWITCH_NO_CRYPTO_TAG) index = ctype + 1;
1205
1206 if (switch_channel_var_true(channel, "rtp_secure_media_mki")) {
1207 engine->ssec[ctype].local_crypto_key = switch_core_session_sprintf(smh->session, "%d %s inline:%s|2^31|1:1", index, (use_alias ? SUITES[ctype].alias : SUITES[ctype].name), b64_key);
1208 } else {
1209 engine->ssec[ctype].local_crypto_key = switch_core_session_sprintf(smh->session, "%d %s inline:%s", index, (use_alias ? SUITES[ctype].alias : SUITES[ctype].name), b64_key);
1210 }
1211
1212 switch_channel_set_variable_name_printf(smh->session->channel, engine->ssec[ctype].local_crypto_key, "rtp_last_%s_local_crypto_key", type2str(type));
1213 switch_channel_set_flag(smh->session->channel, CF_SECURE);
1214
1215 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG, "Set Local %s crypto Key [%s]\n",
1216 type2str(type),
1217 engine->ssec[ctype].local_crypto_key);
1218
1219 if (!(smh->mparams->ndlb & SM_NDLB_DISABLE_SRTP_AUTH) &&
1220 !((val = switch_channel_get_variable(channel, "NDLB_support_asterisk_missing_srtp_auth")) && switch_true(val))) {
1221 engine->ssec[ctype].crypto_type = ctype;
1222 } else {
1223 engine->ssec[ctype].crypto_type = AES_CM_128_NULL_AUTH;
1224 }
1225
1226 return SWITCH_STATUS_SUCCESS;
1227 }
1228
1229 #define CRYPTO_KEY_MATERIAL_LIFETIME_MKI_ERR 0x0u
1230 #define CRYPTO_KEY_MATERIAL_MKI 0x1u
1231 #define CRYPTO_KEY_MATERIAL_LIFETIME 0x2u
1232
1233 #define RAW_BITS_PER_64_ENCODED_CHAR 6
1234
1235 /* Return uint32_t which contains all the info about the field found:
1236 * XXXXXXXa | YYYYYYYY | YYYYYYYY | ZZZZZZZZ
1237 * where:
1238 * a - CRYPTO_KEY_MATERIAL_LIFETIME if LIFETIME, CRYPTO_KEY_MATERIAL_MKI if MKI
1239 * YYYYYYYY and ZZZZZZZZ - depend on 'a':
1240 * if a is LIFETIME then YYYYYYYY is decimal Base, ZZZZZZZZ is decimal Exponent
1241 * if a is MKI, then YYYYYYYY is decimal MKI_ID, ZZZZZZZZ is decimal MKI_SIZE
1242 */
parse_lifetime_mki(const char ** p,const char * end)1243 static uint32_t parse_lifetime_mki(const char **p, const char *end)
1244 {
1245 const char *field_begin;
1246 const char *field_end;
1247 const char *sep, *space;
1248 uint32_t res = 0;
1249
1250 uint32_t val = 0;
1251 int i;
1252
1253 switch_assert(*p != NULL);
1254 switch_assert(end != NULL);
1255
1256 field_begin = strchr(*p, '|');
1257
1258 if (field_begin && (field_begin + 1 < end)) {
1259 space = strchr(field_begin, ' ');
1260 field_end = strchr(field_begin + 2, '|');
1261
1262 if (!field_end) {
1263 field_end = end;
1264 }
1265
1266 if (space) {
1267 if ((field_end == NULL) || (space < field_end)) {
1268 field_end = space;
1269 }
1270 }
1271
1272 if (field_end) {
1273 /* Closing '|' found. */
1274 sep = strchr(field_begin, ':'); /* The lifetime field never includes a colon, whereas the third field always does. (RFC 4568) */
1275 if (sep && (sep + 1 < field_end) && isdigit(*(sep + 1))) {
1276 res |= (CRYPTO_KEY_MATERIAL_MKI << 24);
1277
1278 for (i = 1, *p = sep - 1; *p != field_begin; --(*p), i *= 10) {
1279 val += ((**p) - '0') * i;
1280 }
1281
1282 res |= ((val << 8) & 0x00ffff00); /* MKI_ID */
1283
1284 val = 0;
1285 for (i = 1, *p = field_end - 1; *p != sep; --(*p), i *= 10) {
1286 val += ((**p) - '0') * i;
1287 }
1288 res |= (val & 0x000000ff); /* MKI_SIZE */
1289 } else if (isdigit(*(field_begin + 1)) && (field_begin + 2) && (*(field_begin + 2) == '^') && (field_begin + 3) && isdigit(*(field_begin + 3))) {
1290 res |= (CRYPTO_KEY_MATERIAL_LIFETIME << 24);
1291 val = ((uint32_t) (*(field_begin + 1) - '0')) << 8;
1292 res |= val; /* LIFETIME base. */
1293
1294 val = 0;
1295 for (i = 1, *p = field_end - 1; *p != (field_begin + 2); --(*p), i *= 10) {
1296 val += ((**p) - '0') * i;
1297 }
1298
1299 res |= (val & 0x000000ff); /* LIFETIME exponent. */
1300 }
1301 }
1302
1303 *p = field_end;
1304 }
1305
1306 return res;
1307 }
1308
switch_core_media_crypto_append_key_material(switch_core_session_t * session,switch_crypto_key_material_t * tail,switch_rtp_crypto_key_param_method_type_t method,unsigned char raw_key[SWITCH_RTP_MAX_CRYPTO_LEN],int raw_key_len,const char * key_material,int key_material_len,uint64_t lifetime,unsigned int mki_id,unsigned int mki_size)1309 static switch_crypto_key_material_t* switch_core_media_crypto_append_key_material(
1310 switch_core_session_t *session,
1311 switch_crypto_key_material_t *tail,
1312 switch_rtp_crypto_key_param_method_type_t method,
1313 unsigned char raw_key[SWITCH_RTP_MAX_CRYPTO_LEN],
1314 int raw_key_len,
1315 const char *key_material,
1316 int key_material_len,
1317 uint64_t lifetime,
1318 unsigned int mki_id,
1319 unsigned int mki_size)
1320 {
1321 struct switch_crypto_key_material_s *new_key_material;
1322
1323 new_key_material = switch_core_session_alloc(session, (sizeof(*new_key_material)));
1324 if (new_key_material == NULL) {
1325 return NULL;
1326 }
1327
1328 new_key_material->method = method;
1329 memcpy(new_key_material->raw_key, raw_key, raw_key_len);
1330 new_key_material->crypto_key = switch_core_session_strdup(session, key_material);
1331 new_key_material->lifetime = lifetime;
1332 new_key_material->mki_id = mki_id;
1333 new_key_material->mki_size = mki_size;
1334
1335 new_key_material->next = tail;
1336
1337 return new_key_material;
1338 }
1339
1340 /*
1341 * Skip all space and return pointer to the '\0' terminator of the char string candidate to be a key-material
1342 * or pointer to first ' ' in the candidate string.
1343 */
switch_core_media_crypto_find_key_material_candidate_end(const char * p)1344 static const char* switch_core_media_crypto_find_key_material_candidate_end(const char *p)
1345 {
1346 const char *end = NULL;
1347
1348 switch_assert(p != NULL);
1349
1350 if (p) {
1351 end = strchr(p, ' '); /* find the end of the continuous string of characters in the candidate string */
1352 if (end == NULL)
1353 end = p + strlen(p);
1354 }
1355
1356 return end;
1357 }
1358
switch_core_media_add_crypto(switch_core_session_t * session,switch_secure_settings_t * ssec,switch_rtp_crypto_direction_t direction)1359 SWITCH_DECLARE(switch_status_t) switch_core_media_add_crypto(switch_core_session_t *session, switch_secure_settings_t *ssec, switch_rtp_crypto_direction_t direction)
1360 {
1361 unsigned char key[SWITCH_RTP_MAX_CRYPTO_LEN];
1362 switch_rtp_crypto_key_type_t type;
1363
1364 const char *p, *delimit;
1365 const char *key_material_begin;
1366 const char *key_material_end = NULL; /* begin and end of the current key material candidate */
1367 int method_len;
1368 int keysalt_len;
1369
1370 const char *opts;
1371 uint32_t opt_field; /* LIFETIME or MKI */
1372 switch_rtp_crypto_key_param_method_type_t method = CRYPTO_KEY_PARAM_METHOD_INLINE;
1373 uint64_t lifetime = 0;
1374 uint16_t lifetime_base = 0;
1375 uint16_t lifetime_exp = 0;
1376 uint16_t mki_id = 0;
1377 uint16_t mki_size = 0;
1378 switch_crypto_key_material_t *key_material = NULL;
1379 unsigned long *key_material_n = NULL;
1380
1381 bool multiple_keys = false;
1382
1383 const char *key_param;
1384
1385
1386 if (direction == SWITCH_RTP_CRYPTO_SEND || direction == SWITCH_RTP_CRYPTO_SEND_RTCP) {
1387 key_param = ssec->local_crypto_key;
1388 key_material = ssec->local_key_material_next;
1389 key_material_n = &ssec->local_key_material_n;
1390 } else {
1391 key_param = ssec->remote_crypto_key;
1392 key_material = ssec->remote_key_material_next;
1393 key_material_n = &ssec->remote_key_material_n;
1394 }
1395
1396 if (zstr(key_param)) {
1397 goto no_crypto_found;
1398 }
1399
1400 *key_material_n = 0;
1401
1402 p = strchr(key_param, ' ');
1403
1404 if (!(p && *p && *(p + 1))) {
1405 goto no_crypto_found;
1406 }
1407
1408 p++;
1409
1410 type = switch_core_media_crypto_str2type(p);
1411
1412 if (type == CRYPTO_INVALID) {
1413 goto bad_crypto;
1414 }
1415
1416 p = strchr(p, ' '); /* skip the crypto suite description */
1417 if (p == NULL) {
1418 goto bad_crypto;
1419 }
1420
1421 do {
1422 if (*key_material_n == SWITCH_CRYPTO_MKI_MAX) {
1423 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Skipping excess of MKIs due to max number of suppoerted MKIs %d exceeded\n", SWITCH_CRYPTO_MKI_MAX);
1424 break;
1425 }
1426
1427 p = switch_strip_spaces((char*) p, 0);
1428 if (!p) {
1429 break;
1430 }
1431
1432 key_material_begin = p;
1433 key_material_end = switch_core_media_crypto_find_key_material_candidate_end(p);
1434
1435 /* Parsing the key material candidate within [begin, end). */
1436
1437 if ((delimit = strchr(p, ':')) == NULL) {
1438 goto bad_error_parsing_near;
1439 }
1440
1441 method_len = delimit - p;
1442
1443 if (strncasecmp(p, CRYPTO_KEY_PARAM_METHOD[CRYPTO_KEY_PARAM_METHOD_INLINE], method_len)) {
1444 goto bad_key_param_method;
1445 }
1446
1447 method = CRYPTO_KEY_PARAM_METHOD_INLINE;
1448
1449 /* Valid key-material found. Save as default key in secure_settings_s. */
1450
1451 p = delimit + 1; /* skip ':' */
1452 if (!(p && *p && *(p + 1))) {
1453 goto bad_keysalt;
1454 }
1455
1456 /* Check if '|' is present in currently considered key-material. */
1457 if ((opts = strchr(p, '|')) && (opts < key_material_end)) {
1458 keysalt_len = opts - p;
1459 } else {
1460 keysalt_len = key_material_end - p;
1461 }
1462
1463 if (keysalt_len > sizeof(key)) {
1464 goto bad_keysalt_len;
1465 }
1466
1467 switch_b64_decode(p, (char *) key, keysalt_len);
1468
1469 if (!multiple_keys) { /* First key becomes default (used in case no MKI is found). */
1470 if (direction == SWITCH_RTP_CRYPTO_SEND) {
1471 memcpy(ssec->local_raw_key, key, SUITES[type].keysalt_len);
1472 } else {
1473 memcpy(ssec->remote_raw_key, key, SUITES[type].keysalt_len);
1474 }
1475 multiple_keys = true;
1476 }
1477
1478 p += keysalt_len;
1479
1480 if (!(p < key_material_end)) {
1481 continue;
1482 }
1483
1484 if (opts) { /* if opts != NULL then opts points to first '|' in current key-material cadidate, parse it as LIFETIME or MKI */
1485
1486 lifetime = 0;
1487 mki_id = 0;
1488 mki_size = 0;
1489
1490 for (int i = 0; i < 2 && (*opts == '|'); ++i) {
1491
1492 opt_field = parse_lifetime_mki(&opts, key_material_end);
1493
1494 switch ((opt_field >> 24) & 0x3) {
1495
1496 case CRYPTO_KEY_MATERIAL_LIFETIME:
1497
1498 lifetime_base = ((opt_field & 0x00ffff00) >> 8) & 0xffff;
1499 lifetime_exp = (opt_field & 0x000000ff) & 0xffff;
1500 lifetime = pow(lifetime_base, lifetime_exp);
1501 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "LIFETIME found in %s, base %u exp %u\n", p, lifetime_base, lifetime_exp);
1502 break;
1503
1504 case CRYPTO_KEY_MATERIAL_MKI:
1505
1506 mki_id = ((opt_field & 0x00ffff00) >> 8) & 0xffff;
1507 mki_size = (opt_field & 0x000000ff) & 0xffff;
1508 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "MKI found in %s, id %u size %u\n", p, mki_id, mki_size);
1509 break;
1510
1511 default:
1512 goto bad_key_lifetime_or_mki;
1513 }
1514 }
1515
1516 if (mki_id == 0 && lifetime == 0) {
1517 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Bad MKI found in %s, (parsed as: id %u size %u lifetime base %u exp %u\n", p, mki_id, mki_size, lifetime_base, lifetime_exp);
1518 return SWITCH_STATUS_FALSE;
1519 } else if (mki_id == 0 || lifetime == 0) {
1520 if (mki_id == 0) {
1521 if (key_material)
1522 goto bad_key_no_mki_index;
1523
1524 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Skipping MKI due to empty index\n");
1525 } else {
1526 if (mki_size == 0)
1527 goto bad_key_no_mki_size;
1528
1529 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Skipping MKI due to empty lifetime\n");
1530 }
1531 continue;
1532 }
1533 }
1534
1535 if (key_material) {
1536 if (mki_id == 0) {
1537 goto bad_key_no_mki_index;
1538 }
1539
1540 if (mki_size != key_material->mki_size) {
1541 goto bad_key_mki_size;
1542 }
1543 }
1544
1545 key_material = switch_core_media_crypto_append_key_material(session, key_material, method, (unsigned char*) key,
1546 SUITES[type].keysalt_len, (char*) key_material_begin, key_material_end - key_material_begin, lifetime, mki_id, mki_size);
1547 *key_material_n = *key_material_n + 1;
1548 } while ((p = switch_strip_spaces((char*) key_material_end, 0)) && (*p != '\0'));
1549
1550 if (direction == SWITCH_RTP_CRYPTO_SEND || direction == SWITCH_RTP_CRYPTO_SEND_RTCP) {
1551 ssec->local_key_material_next = key_material;
1552 } else {
1553 ssec->remote_key_material_next = key_material;
1554 }
1555
1556 return SWITCH_STATUS_SUCCESS;
1557
1558
1559 no_crypto_found:
1560 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error! No crypto to parse\n");
1561 return SWITCH_STATUS_FALSE;
1562
1563 bad_error_parsing_near:
1564 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error! Parsing near %s\n", p);
1565 return SWITCH_STATUS_FALSE;
1566
1567 bad_crypto:
1568 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error! SRTP: Invalid format of crypto attribute %s\n", key_param);
1569 return SWITCH_STATUS_FALSE;
1570
1571 bad_keysalt:
1572 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error! SRTP: Invalid keysalt in the crypto attribute %s\n", key_param);
1573 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error! Parsing near %s\n", p);
1574 return SWITCH_STATUS_FALSE;
1575
1576 bad_keysalt_len:
1577 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error! SRTP: Invalid keysalt length in the crypto attribute %s\n", key_param);
1578 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error! Parsing near %s\n", p);
1579 return SWITCH_STATUS_FALSE;
1580
1581 bad_key_lifetime_or_mki:
1582 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error! SRTP: Invalid key param MKI or LIFETIME in the crypto attribute %s\n", key_param);
1583 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error! Parsing near %s\n", p);
1584 return SWITCH_STATUS_FALSE;
1585
1586 bad_key_no_mki_index:
1587 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Crypto invalid: multiple keys in a single crypto MUST all have MKI indices, %s\n", key_param);
1588 return SWITCH_STATUS_FALSE;
1589
1590 bad_key_no_mki_size:
1591 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Crypto invalid: MKI index with no MKI size in %s\n", key_param);
1592 return SWITCH_STATUS_FALSE;
1593
1594 bad_key_mki_size:
1595 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Crypto invalid: MKI sizes differ in %s\n", key_param);
1596 return SWITCH_STATUS_FALSE;
1597
1598 bad_key_param_method:
1599 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error! SRTP: Invalid key param method type in %s\n", key_param);
1600 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error! Parsing near %s\n", p);
1601 return SWITCH_STATUS_FALSE;
1602 }
1603
switch_core_media_set_rtp_session(switch_core_session_t * session,switch_media_type_t type,switch_rtp_t * rtp_session)1604 SWITCH_DECLARE(void) switch_core_media_set_rtp_session(switch_core_session_t *session, switch_media_type_t type, switch_rtp_t *rtp_session)
1605 {
1606 switch_rtp_engine_t *engine;
1607 if (!session->media_handle) return;
1608 engine = &session->media_handle->engines[type];
1609 engine->rtp_session = rtp_session;
1610 engine->type = type;
1611 }
1612
1613
switch_core_session_get_recovery_crypto_key(switch_core_session_t * session,switch_media_type_t type)1614 static void switch_core_session_get_recovery_crypto_key(switch_core_session_t *session, switch_media_type_t type)
1615 {
1616 const char *tmp;
1617 switch_rtp_engine_t *engine;
1618 char *keyvar, *tagvar, *ctypevar;
1619
1620 if (!session->media_handle) return;
1621 engine = &session->media_handle->engines[type];
1622
1623 if (type == SWITCH_MEDIA_TYPE_AUDIO) {
1624 keyvar = "srtp_remote_audio_crypto_key";
1625 tagvar = "srtp_remote_audio_crypto_tag";
1626 ctypevar = "srtp_remote_audio_crypto_type";
1627 } else if (type == SWITCH_MEDIA_TYPE_VIDEO) {
1628 keyvar = "srtp_remote_video_crypto_key";
1629 tagvar = "srtp_remote_video_crypto_tag";
1630 ctypevar = "srtp_remote_video_crypto_type";
1631 } else if (type == SWITCH_MEDIA_TYPE_TEXT) {
1632 keyvar = "srtp_remote_text_crypto_key";
1633 tagvar = "srtp_remote_text_crypto_tag";
1634 ctypevar = "srtp_remote_text_crypto_type";
1635 } else return;
1636
1637 if ((tmp = switch_channel_get_variable(session->channel, keyvar))) {
1638 if ((tmp = switch_channel_get_variable(session->channel, ctypevar))) {
1639 engine->crypto_type = switch_core_media_crypto_str2type(tmp);
1640 }
1641
1642 engine->ssec[engine->crypto_type].remote_crypto_key = switch_core_session_strdup(session, tmp);
1643
1644 if ((tmp = switch_channel_get_variable(session->channel, tagvar))) {
1645 int tv = atoi(tmp);
1646 engine->ssec[engine->crypto_type].crypto_tag = tv;
1647 } else {
1648 engine->ssec[engine->crypto_type].crypto_tag = 1;
1649 }
1650
1651 switch_channel_set_flag(session->channel, CF_SECURE);
1652 }
1653 }
1654
1655
switch_core_session_apply_crypto(switch_core_session_t * session,switch_media_type_t type)1656 static void switch_core_session_apply_crypto(switch_core_session_t *session, switch_media_type_t type)
1657 {
1658 switch_rtp_engine_t *engine;
1659 const char *varname;
1660
1661 if (type == SWITCH_MEDIA_TYPE_AUDIO) {
1662 varname = "rtp_secure_audio_confirmed";
1663 } else if (type == SWITCH_MEDIA_TYPE_VIDEO) {
1664 varname = "rtp_secure_video_confirmed";
1665 } else if (type == SWITCH_MEDIA_TYPE_TEXT) {
1666 varname = "rtp_secure_text_confirmed";
1667 } else {
1668 return;
1669 }
1670
1671 if (!session->media_handle) return;
1672
1673 engine = &session->media_handle->engines[type];
1674
1675 if (switch_channel_test_flag(session->channel, CF_RECOVERING)) {
1676 return;
1677 }
1678
1679 if (engine->ssec[engine->crypto_type].remote_crypto_key && switch_channel_test_flag(session->channel, CF_SECURE)) {
1680
1681 if (switch_channel_var_true(session->channel, "rtp_secure_media_mki"))
1682 switch_core_media_add_crypto(session, &engine->ssec[engine->crypto_type], SWITCH_RTP_CRYPTO_SEND);
1683
1684 switch_core_media_add_crypto(session, &engine->ssec[engine->crypto_type], SWITCH_RTP_CRYPTO_RECV);
1685
1686
1687 switch_rtp_add_crypto_key(engine->rtp_session, SWITCH_RTP_CRYPTO_SEND, 1, &engine->ssec[engine->crypto_type]);
1688
1689 switch_rtp_add_crypto_key(engine->rtp_session, SWITCH_RTP_CRYPTO_RECV, engine->ssec[engine->crypto_type].crypto_tag, &engine->ssec[engine->crypto_type]);
1690
1691 switch_channel_set_variable(session->channel, varname, "true");
1692
1693
1694 switch_channel_set_variable(session->channel, "rtp_secure_media_negotiated", SUITES[engine->crypto_type].name);
1695
1696 }
1697
1698 }
1699
switch_core_session_parse_crypto_prefs(switch_core_session_t * session)1700 static void switch_core_session_parse_crypto_prefs(switch_core_session_t *session)
1701 {
1702 const char *var = NULL;
1703 const char *val = NULL;
1704 char *suites = NULL;
1705 switch_media_handle_t *smh;
1706 char *fields[CRYPTO_INVALID+1];
1707 int argc = 0, i = 0, j = 0, k = 0;
1708
1709 if (!(smh = session->media_handle)) {
1710 return;
1711 }
1712
1713 if (switch_channel_test_flag(session->channel, CF_AVPF)) {
1714 return;
1715 }
1716
1717 if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
1718 var = "rtp_secure_media_inbound";
1719 } else {
1720 var = "rtp_secure_media_outbound";
1721 }
1722
1723 if (!(val = switch_channel_get_variable(session->channel, var))) {
1724 var = "rtp_secure_media";
1725 val = switch_channel_get_variable(session->channel, var);
1726 }
1727
1728 if (!zstr(val) && (suites = strchr(val, ':'))) {
1729 *suites++ = '\0';
1730 }
1731
1732 if (zstr(suites)) {
1733 suites = (char *) switch_channel_get_variable(session->channel, "rtp_secure_media_suites");
1734 }
1735
1736 if (zstr(val)) {
1737 if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_INBOUND && !switch_channel_test_flag(session->channel, CF_RECOVERING)) {
1738 val = "optional";
1739 } else {
1740 val = "forbidden";
1741 }
1742 }
1743
1744 if (!strcasecmp(val, "optional")) {
1745 smh->crypto_mode = CRYPTO_MODE_OPTIONAL;
1746 } else if (switch_true(val) || !strcasecmp(val, "mandatory")) {
1747 smh->crypto_mode = CRYPTO_MODE_MANDATORY;
1748 } else {
1749 smh->crypto_mode = CRYPTO_MODE_FORBIDDEN;
1750 if (!switch_false(val) && strcasecmp(val, "forbidden")) {
1751 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "INVALID VALUE FOR %s defaulting to 'forbidden'\n", var);
1752 }
1753 }
1754
1755 if (smh->crypto_mode != CRYPTO_MODE_FORBIDDEN && !zstr(suites)) {
1756 argc = switch_split((char *)suites, ':', fields);
1757
1758 for (i = 0; i < argc; i++) {
1759 int ok = 0;
1760
1761 for (j = 0; j < CRYPTO_INVALID; j++) {
1762 if (!strcasecmp(fields[i], SUITES[j].name)) {
1763 smh->crypto_suite_order[k++] = SUITES[j].type;
1764 ok++;
1765 break;
1766 }
1767 }
1768
1769 if (!ok) {
1770 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "INVALID SUITE SUPPLIED\n");
1771 }
1772
1773 }
1774 } else {
1775 for (i = 0; i < CRYPTO_INVALID; i++) {
1776 smh->crypto_suite_order[k++] = SUITES[i].type;
1777 }
1778 }
1779 }
1780
switch_core_session_check_incoming_crypto(switch_core_session_t * session,const char * varname,switch_media_type_t type,const char * crypto,int crypto_tag,switch_sdp_type_t sdp_type)1781 SWITCH_DECLARE(int) switch_core_session_check_incoming_crypto(switch_core_session_t *session,
1782 const char *varname,
1783 switch_media_type_t type, const char *crypto, int crypto_tag, switch_sdp_type_t sdp_type)
1784 {
1785 int got_crypto = 0;
1786 int i = 0;
1787 int ctype = 0;
1788 const char *vval = NULL;
1789 int use_alias = 0;
1790 switch_rtp_engine_t *engine;
1791 switch_media_handle_t *smh;
1792
1793 if (!(smh = session->media_handle)) {
1794 return 0;
1795 }
1796
1797 if (smh->crypto_mode == CRYPTO_MODE_FORBIDDEN) {
1798 return -1;
1799 }
1800
1801 if (switch_channel_test_flag(session->channel, CF_AVPF)) {
1802 return 0;
1803 }
1804
1805 if (!crypto) {
1806 return 0;
1807 }
1808 engine = &session->media_handle->engines[type];
1809
1810 for (i = 0; smh->crypto_suite_order[i] != CRYPTO_INVALID; i++) {
1811 switch_rtp_crypto_key_type_t j = SUITES[smh->crypto_suite_order[i]].type;
1812
1813 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "looking for crypto suite [%s]alias=[%s] in [%s]\n", SUITES[j].name, SUITES[j].alias, crypto);
1814
1815 if (switch_stristr(SUITES[j].alias, crypto)) {
1816 use_alias = 1;
1817 }
1818
1819 if (use_alias || switch_stristr(SUITES[j].name, crypto)) {
1820 ctype = SUITES[j].type;
1821 vval = use_alias ? SUITES[j].alias : SUITES[j].name;
1822 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Found suite %s\n", vval);
1823 switch_channel_set_variable(session->channel, "rtp_secure_media_negotiated", vval);
1824 break;
1825 }
1826
1827 use_alias = 0;
1828 }
1829
1830 if (engine->ssec[engine->crypto_type].remote_crypto_key && switch_rtp_ready(engine->rtp_session)) {
1831 /* Compare all the key. The tag may remain the same even if key changed */
1832 if (engine->crypto_type != CRYPTO_INVALID && !strcmp(crypto, engine->ssec[engine->crypto_type].remote_crypto_key)) {
1833 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Existing key is still valid.\n");
1834 got_crypto = 1;
1835 } else {
1836 const char *a = switch_stristr("AE", engine->ssec[engine->crypto_type].remote_crypto_key);
1837 const char *b = switch_stristr("AE", crypto);
1838
1839 if (sdp_type == SDP_TYPE_REQUEST) {
1840 if (!vval) {
1841 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Unsupported Crypto [%s]\n", crypto);
1842 goto end;
1843 }
1844 switch_channel_set_variable(session->channel, varname, vval);
1845
1846 switch_core_media_build_crypto(session->media_handle, type, crypto_tag, ctype, SWITCH_RTP_CRYPTO_SEND, 1, use_alias);
1847 switch_rtp_add_crypto_key(engine->rtp_session, SWITCH_RTP_CRYPTO_SEND, atoi(crypto), &engine->ssec[engine->crypto_type]);
1848 }
1849
1850 if (a && b && !strncasecmp(a, b, 23)) {
1851 engine->crypto_type = ctype;
1852
1853 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Change Remote key to [%s]\n", crypto);
1854 engine->ssec[engine->crypto_type].remote_crypto_key = switch_core_session_strdup(session, crypto);
1855
1856 if (engine->type == SWITCH_MEDIA_TYPE_AUDIO) {
1857 switch_channel_set_variable(session->channel, "srtp_remote_audio_crypto_key", crypto);
1858 switch_channel_set_variable_printf(session->channel, "srtp_remote_audio_crypto_tag", "%d", crypto_tag);
1859 switch_channel_set_variable_printf(session->channel, "srtp_remote_audio_crypto_type", "%s", switch_core_media_crypto_type2str(ctype));
1860 } else if (engine->type == SWITCH_MEDIA_TYPE_VIDEO) {
1861 switch_channel_set_variable(session->channel, "srtp_remote_video_crypto_key", crypto);
1862 switch_channel_set_variable_printf(session->channel, "srtp_remote_video_crypto_tag", "%d", crypto_tag);
1863 switch_channel_set_variable_printf(session->channel, "srtp_remote_video_crypto_type", "%s", switch_core_media_crypto_type2str(ctype));
1864 } else if (engine->type == SWITCH_MEDIA_TYPE_TEXT) {
1865 switch_channel_set_variable(session->channel, "srtp_remote_text_crypto_key", crypto);
1866 switch_channel_set_variable_printf(session->channel, "srtp_remote_text_crypto_tag", "%d", crypto_tag);
1867 switch_channel_set_variable_printf(session->channel, "srtp_remote_text_crypto_type", "%s", switch_core_media_crypto_type2str(ctype));
1868 }
1869
1870 engine->ssec[engine->crypto_type].crypto_tag = crypto_tag;
1871
1872
1873 if (switch_rtp_ready(engine->rtp_session) && switch_channel_test_flag(session->channel, CF_SECURE)) {
1874 switch_core_media_add_crypto(session, &engine->ssec[engine->crypto_type], SWITCH_RTP_CRYPTO_RECV);
1875 switch_rtp_add_crypto_key(engine->rtp_session, SWITCH_RTP_CRYPTO_RECV, engine->ssec[engine->crypto_type].crypto_tag, &engine->ssec[engine->crypto_type]);
1876 }
1877 got_crypto++;
1878
1879 } else {
1880 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Ignoring unacceptable key\n");
1881 }
1882 }
1883 } else if (!switch_rtp_ready(engine->rtp_session)) {
1884
1885 if (!vval) {
1886 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Unsupported Crypto [%s]\n", crypto);
1887 goto end;
1888 }
1889
1890 engine->crypto_type = ctype;
1891 engine->ssec[engine->crypto_type].remote_crypto_key = switch_core_session_strdup(session, crypto);
1892 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set Remote Key [%s]\n", engine->ssec[engine->crypto_type].remote_crypto_key);
1893 if (engine->type == SWITCH_MEDIA_TYPE_AUDIO) {
1894 switch_channel_set_variable(session->channel, "srtp_remote_audio_crypto_key", crypto);
1895 switch_channel_set_variable_printf(session->channel, "srtp_remote_audio_crypto_type", "%s", switch_core_media_crypto_type2str(ctype));
1896 } else if (engine->type == SWITCH_MEDIA_TYPE_VIDEO) {
1897 switch_channel_set_variable(session->channel, "srtp_remote_video_crypto_key", crypto);
1898 switch_channel_set_variable_printf(session->channel, "srtp_remote_video_crypto_type", "%s", switch_core_media_crypto_type2str(ctype));
1899 } else if (engine->type == SWITCH_MEDIA_TYPE_TEXT) {
1900 switch_channel_set_variable(session->channel, "srtp_remote_text_crypto_key", crypto);
1901 switch_channel_set_variable_printf(session->channel, "srtp_remote_text_crypto_type", "%s", switch_core_media_crypto_type2str(ctype));
1902 }
1903
1904 engine->ssec[engine->crypto_type].crypto_tag = crypto_tag;
1905 got_crypto++;
1906
1907 switch_channel_set_variable(session->channel, varname, vval);
1908 switch_channel_set_flag(smh->session->channel, CF_SECURE);
1909
1910 if (zstr(engine->ssec[engine->crypto_type].local_crypto_key)) {
1911 switch_core_media_build_crypto(session->media_handle, type, crypto_tag, ctype, SWITCH_RTP_CRYPTO_SEND, 1, use_alias);
1912 }
1913 }
1914
1915 end:
1916
1917 return got_crypto;
1918 }
1919
1920
switch_core_session_check_outgoing_crypto(switch_core_session_t * session)1921 SWITCH_DECLARE(void) switch_core_session_check_outgoing_crypto(switch_core_session_t *session)
1922 {
1923 switch_channel_t *channel = switch_core_session_get_channel(session);
1924 switch_media_handle_t *smh;
1925 int i;
1926
1927 if (switch_core_session_media_handle_ready(session) != SWITCH_STATUS_SUCCESS) {
1928 return;
1929 }
1930
1931 if (!(smh = session->media_handle)) {
1932 return;
1933 }
1934
1935 if (!(smh->crypto_mode == CRYPTO_MODE_OPTIONAL || smh->crypto_mode == CRYPTO_MODE_MANDATORY)) {
1936 return;
1937 }
1938
1939 if (switch_channel_test_flag(session->channel, CF_AVPF)) {
1940 return;
1941 }
1942
1943 switch_channel_set_flag(channel, CF_SECURE);
1944
1945 for (i = 0; smh->crypto_suite_order[i] != CRYPTO_INVALID; i++) {
1946 switch_core_media_build_crypto(session->media_handle,
1947 SWITCH_MEDIA_TYPE_AUDIO, SWITCH_NO_CRYPTO_TAG, smh->crypto_suite_order[i], SWITCH_RTP_CRYPTO_SEND, 0, 0);
1948
1949 switch_core_media_build_crypto(session->media_handle,
1950 SWITCH_MEDIA_TYPE_VIDEO, SWITCH_NO_CRYPTO_TAG, smh->crypto_suite_order[i], SWITCH_RTP_CRYPTO_SEND, 0, 0);
1951
1952 switch_core_media_build_crypto(session->media_handle,
1953 SWITCH_MEDIA_TYPE_TEXT, SWITCH_NO_CRYPTO_TAG, smh->crypto_suite_order[i], SWITCH_RTP_CRYPTO_SEND, 0, 0);
1954 }
1955
1956 }
1957
1958 #define add_stat(_i, _s) \
1959 switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", switch_str_nil(prefix), _s) ; \
1960 switch_snprintf(var_val, sizeof(var_val), "%" SWITCH_SIZE_T_FMT, _i); \
1961 switch_channel_set_variable(channel, var_name, var_val)
1962
1963 #define add_stat_double(_i, _s) \
1964 switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", switch_str_nil(prefix), _s) ; \
1965 switch_snprintf(var_val, sizeof(var_val), "%0.2f", _i); \
1966 switch_channel_set_variable(channel, var_name, var_val)
1967
set_stats(switch_core_session_t * session,switch_media_type_t type,const char * prefix)1968 static void set_stats(switch_core_session_t *session, switch_media_type_t type, const char *prefix)
1969 {
1970 switch_rtp_stats_t *stats = switch_core_media_get_stats(session, type, NULL);
1971 switch_channel_t *channel = switch_core_session_get_channel(session);
1972
1973 char var_name[256] = "", var_val[35] = "";
1974
1975 if (stats) {
1976 stats->inbound.std_deviation = sqrt(stats->inbound.variance);
1977
1978 add_stat(stats->inbound.raw_bytes, "in_raw_bytes");
1979 add_stat(stats->inbound.media_bytes, "in_media_bytes");
1980 add_stat(stats->inbound.packet_count, "in_packet_count");
1981 add_stat(stats->inbound.media_packet_count, "in_media_packet_count");
1982 add_stat(stats->inbound.skip_packet_count, "in_skip_packet_count");
1983 add_stat(stats->inbound.jb_packet_count, "in_jitter_packet_count");
1984 add_stat(stats->inbound.dtmf_packet_count, "in_dtmf_packet_count");
1985 add_stat(stats->inbound.cng_packet_count, "in_cng_packet_count");
1986 add_stat(stats->inbound.flush_packet_count, "in_flush_packet_count");
1987 add_stat(stats->inbound.largest_jb_size, "in_largest_jb_size");
1988 add_stat_double(stats->inbound.min_variance, "in_jitter_min_variance");
1989 add_stat_double(stats->inbound.max_variance, "in_jitter_max_variance");
1990 add_stat_double(stats->inbound.lossrate, "in_jitter_loss_rate");
1991 add_stat_double(stats->inbound.burstrate, "in_jitter_burst_rate");
1992 add_stat_double(stats->inbound.mean_interval, "in_mean_interval");
1993 add_stat(stats->inbound.flaws, "in_flaw_total");
1994 add_stat_double(stats->inbound.R, "in_quality_percentage");
1995 add_stat_double(stats->inbound.mos, "in_mos");
1996
1997
1998 add_stat(stats->outbound.raw_bytes, "out_raw_bytes");
1999 add_stat(stats->outbound.media_bytes, "out_media_bytes");
2000 add_stat(stats->outbound.packet_count, "out_packet_count");
2001 add_stat(stats->outbound.media_packet_count, "out_media_packet_count");
2002 add_stat(stats->outbound.skip_packet_count, "out_skip_packet_count");
2003 add_stat(stats->outbound.dtmf_packet_count, "out_dtmf_packet_count");
2004 add_stat(stats->outbound.cng_packet_count, "out_cng_packet_count");
2005
2006 add_stat(stats->rtcp.packet_count, "rtcp_packet_count");
2007 add_stat(stats->rtcp.octet_count, "rtcp_octet_count");
2008
2009 }
2010 }
2011
switch_core_media_sync_stats(switch_core_session_t * session)2012 SWITCH_DECLARE(void) switch_core_media_sync_stats(switch_core_session_t *session)
2013 {
2014 switch_media_handle_t *smh;
2015 switch_rtp_engine_t *a_engine, *v_engine, *t_engine;
2016
2017 switch_assert(session);
2018
2019 if (!(smh = session->media_handle)) {
2020 return;
2021 }
2022
2023 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
2024 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
2025 t_engine = &smh->engines[SWITCH_MEDIA_TYPE_TEXT];
2026
2027 if (a_engine->rtp_session) {
2028 switch_rtp_sync_stats(a_engine->rtp_session);
2029 }
2030
2031 if (v_engine->rtp_session) {
2032 switch_rtp_sync_stats(v_engine->rtp_session);
2033 }
2034
2035 if (t_engine->rtp_session) {
2036 switch_rtp_sync_stats(t_engine->rtp_session);
2037 }
2038
2039 }
2040
switch_core_media_set_stats(switch_core_session_t * session)2041 SWITCH_DECLARE(void) switch_core_media_set_stats(switch_core_session_t *session)
2042 {
2043
2044 if (!session->media_handle) {
2045 return;
2046 }
2047
2048 switch_core_media_sync_stats(session);
2049
2050 set_stats(session, SWITCH_MEDIA_TYPE_AUDIO, "audio");
2051 set_stats(session, SWITCH_MEDIA_TYPE_VIDEO, "video");
2052 set_stats(session, SWITCH_MEDIA_TYPE_TEXT, "text");
2053 }
2054
2055
2056
switch_media_handle_destroy(switch_core_session_t * session)2057 SWITCH_DECLARE(void) switch_media_handle_destroy(switch_core_session_t *session)
2058 {
2059 switch_media_handle_t *smh;
2060 switch_rtp_engine_t *a_engine, *v_engine;//, *t_engine;
2061
2062 switch_assert(session);
2063
2064 if (!(smh = session->media_handle)) {
2065 return;
2066 }
2067
2068 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
2069 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
2070 //t_engine = &smh->engines[SWITCH_MEDIA_TYPE_TEXT];
2071
2072
2073 if (smh->video_timer.timer_interface) {
2074 switch_core_timer_destroy(&smh->video_timer);
2075 }
2076
2077 if (switch_core_codec_ready(&a_engine->read_codec)) {
2078 switch_core_codec_destroy(&a_engine->read_codec);
2079 }
2080
2081 if (switch_core_codec_ready(&a_engine->write_codec)) {
2082 switch_core_codec_destroy(&a_engine->write_codec);
2083 }
2084
2085 if (switch_core_codec_ready(&v_engine->read_codec)) {
2086 switch_core_codec_destroy(&v_engine->read_codec);
2087 }
2088
2089 if (switch_core_codec_ready(&v_engine->write_codec)) {
2090 switch_core_codec_destroy(&v_engine->write_codec);
2091 }
2092
2093 switch_core_session_unset_read_codec(session);
2094 switch_core_session_unset_write_codec(session);
2095 switch_core_media_deactivate_rtp(session);
2096
2097 if (a_engine->write_fb) switch_frame_buffer_destroy(&a_engine->write_fb);
2098
2099 if (smh->msrp_session) switch_msrp_session_destroy(&smh->msrp_session);
2100 }
2101
2102
switch_media_handle_create(switch_media_handle_t ** smhp,switch_core_session_t * session,switch_core_media_params_t * params)2103 SWITCH_DECLARE(switch_status_t) switch_media_handle_create(switch_media_handle_t **smhp, switch_core_session_t *session, switch_core_media_params_t *params)
2104 {
2105 switch_status_t status = SWITCH_STATUS_FALSE;
2106 switch_media_handle_t *smh = NULL;
2107 int i;
2108
2109 *smhp = NULL;
2110
2111 if (zstr(params->sdp_username)) {
2112 params->sdp_username = "FreeSWITCH";
2113 }
2114
2115
2116 if ((session->media_handle = switch_core_session_alloc(session, (sizeof(*smh))))) {
2117 session->media_handle->session = session;
2118
2119
2120 *smhp = session->media_handle;
2121 switch_set_flag(session->media_handle, SMF_INIT);
2122 session->media_handle->media_flags[SCMF_RUNNING] = 1;
2123
2124 session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].read_frame.buflen = SWITCH_RTP_MAX_BUF_LEN;
2125 session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].type = SWITCH_MEDIA_TYPE_AUDIO;
2126 session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].crypto_type = CRYPTO_INVALID;
2127
2128 for (i = 0; i < CRYPTO_INVALID; i++) {
2129 session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].ssec[i].crypto_type = i;
2130 }
2131
2132
2133
2134 session->media_handle->engines[SWITCH_MEDIA_TYPE_TEXT].read_frame.buflen = SWITCH_RTP_MAX_BUF_LEN;
2135 session->media_handle->engines[SWITCH_MEDIA_TYPE_TEXT].type = SWITCH_MEDIA_TYPE_TEXT;
2136 session->media_handle->engines[SWITCH_MEDIA_TYPE_TEXT].crypto_type = CRYPTO_INVALID;
2137
2138 for (i = 0; i < CRYPTO_INVALID; i++) {
2139 session->media_handle->engines[SWITCH_MEDIA_TYPE_TEXT].ssec[i].crypto_type = i;
2140 }
2141
2142
2143
2144 session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].read_frame.buflen = SWITCH_RTP_MAX_BUF_LEN;
2145 session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].type = SWITCH_MEDIA_TYPE_VIDEO;
2146 session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].crypto_type = CRYPTO_INVALID;
2147
2148
2149 switch_channel_set_variable(session->channel, "video_media_flow", "disabled");
2150 switch_channel_set_variable(session->channel, "audio_media_flow", "disabled");
2151 switch_channel_set_variable(session->channel, "text_media_flow", "disabled");
2152
2153 session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].smode = SWITCH_MEDIA_FLOW_DISABLED;
2154 session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].smode = SWITCH_MEDIA_FLOW_DISABLED;
2155 session->media_handle->engines[SWITCH_MEDIA_TYPE_TEXT].smode = SWITCH_MEDIA_FLOW_DISABLED;
2156
2157 for (i = 0; i < CRYPTO_INVALID; i++) {
2158 session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].ssec[i].crypto_type = i;
2159 }
2160
2161 session->media_handle->mparams = params;
2162
2163 //if (!session->media_handle->mparams->video_key_freq) {
2164 // session->media_handle->mparams->video_key_freq = 10000000;
2165 //}
2166
2167 if (!session->media_handle->mparams->video_key_first) {
2168 session->media_handle->mparams->video_key_first = 1000000;
2169 }
2170
2171
2172 for (i = 0; i <= CRYPTO_INVALID; i++) {
2173 session->media_handle->crypto_suite_order[i] = CRYPTO_INVALID;
2174 }
2175
2176 switch_mutex_init(&session->media_handle->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
2177 switch_mutex_init(&session->media_handle->sdp_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
2178 switch_mutex_init(&session->media_handle->control_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
2179
2180 session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].ssrc =
2181 (uint32_t) ((intptr_t) &session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO] + (uint32_t) time(NULL));
2182
2183 session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].ssrc =
2184 (uint32_t) ((intptr_t) &session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO] + (uint32_t) time(NULL) / 2);
2185
2186 session->media_handle->engines[SWITCH_MEDIA_TYPE_TEXT].ssrc =
2187 (uint32_t) ((intptr_t) &session->media_handle->engines[SWITCH_MEDIA_TYPE_TEXT] + (uint32_t) time(NULL) / 2);
2188
2189
2190
2191 session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].payload_map = switch_core_alloc(session->pool, sizeof(payload_map_t));
2192 session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].cur_payload_map = session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].payload_map;
2193 session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].cur_payload_map->current = 1;
2194
2195 session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].payload_map = switch_core_alloc(session->pool, sizeof(payload_map_t));
2196 session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].cur_payload_map = session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].payload_map;
2197 session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].cur_payload_map->current = 1;
2198 session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].codec_settings.video.try_hardware_encoder = 1;
2199
2200
2201 session->media_handle->engines[SWITCH_MEDIA_TYPE_TEXT].payload_map = switch_core_alloc(session->pool, sizeof(payload_map_t));
2202 session->media_handle->engines[SWITCH_MEDIA_TYPE_TEXT].cur_payload_map = session->media_handle->engines[SWITCH_MEDIA_TYPE_TEXT].payload_map;
2203 session->media_handle->engines[SWITCH_MEDIA_TYPE_TEXT].cur_payload_map->current = 1;
2204
2205 switch_channel_set_flag(session->channel, CF_DTLS_OK);
2206
2207 status = SWITCH_STATUS_SUCCESS;
2208 }
2209
2210
2211 return status;
2212 }
2213
switch_media_handle_set_media_flag(switch_media_handle_t * smh,switch_core_media_flag_t flag)2214 SWITCH_DECLARE(void) switch_media_handle_set_media_flag(switch_media_handle_t *smh, switch_core_media_flag_t flag)
2215 {
2216 switch_assert(smh);
2217
2218 smh->media_flags[flag] = 1;
2219
2220 }
2221
switch_media_handle_set_media_flags(switch_media_handle_t * smh,switch_core_media_flag_t flags[SCMF_MAX])2222 SWITCH_DECLARE(void) switch_media_handle_set_media_flags(switch_media_handle_t *smh, switch_core_media_flag_t flags[SCMF_MAX])
2223 {
2224 int i;
2225 switch_assert(smh);
2226
2227 for(i = 0; i < SCMF_MAX; i++) {
2228 if (flags[i]) {
2229 smh->media_flags[i] = flags[i];
2230 }
2231 }
2232
2233 }
2234
switch_media_handle_clear_media_flag(switch_media_handle_t * smh,switch_core_media_flag_t flag)2235 SWITCH_DECLARE(void) switch_media_handle_clear_media_flag(switch_media_handle_t *smh, switch_core_media_flag_t flag)
2236 {
2237 switch_assert(smh);
2238
2239 smh->media_flags[flag] = 0;
2240 }
2241
switch_media_handle_test_media_flag(switch_media_handle_t * smh,switch_core_media_flag_t flag)2242 SWITCH_DECLARE(int32_t) switch_media_handle_test_media_flag(switch_media_handle_t *smh, switch_core_media_flag_t flag)
2243 {
2244 switch_assert(smh);
2245 return smh->media_flags[flag];
2246 }
2247
switch_core_session_media_flow(switch_core_session_t * session,switch_media_type_t type)2248 SWITCH_DECLARE(switch_media_flow_t) switch_core_session_media_flow(switch_core_session_t *session, switch_media_type_t type)
2249 {
2250 switch_media_flow_t flow = SWITCH_MEDIA_FLOW_SENDRECV;
2251 switch_media_handle_t *smh;
2252 switch_rtp_engine_t *engine = NULL;
2253
2254 switch_assert(session);
2255
2256 if (!(smh = session->media_handle)) {
2257 goto end;
2258 }
2259
2260 if (!smh->media_flags[SCMF_RUNNING]) {
2261 goto end;
2262 }
2263
2264 engine = &smh->engines[type];
2265 flow = engine->smode;
2266
2267 end:
2268
2269 return flow;
2270 }
2271
2272
switch_core_session_remote_media_flow(switch_core_session_t * session,switch_media_type_t type)2273 SWITCH_DECLARE(switch_media_flow_t) switch_core_session_remote_media_flow(switch_core_session_t *session, switch_media_type_t type)
2274 {
2275 switch_media_flow_t flow = SWITCH_MEDIA_FLOW_SENDRECV;
2276 switch_media_handle_t *smh;
2277 switch_rtp_engine_t *engine = NULL;
2278
2279 switch_assert(session);
2280
2281 if (!(smh = session->media_handle)) {
2282 goto end;
2283 }
2284
2285 if (!smh->media_flags[SCMF_RUNNING]) {
2286 goto end;
2287 }
2288
2289 engine = &smh->engines[type];
2290 flow = engine->rmode;
2291
2292 end:
2293
2294 return flow;
2295 }
2296
switch_core_session_media_handle_ready(switch_core_session_t * session)2297 SWITCH_DECLARE(switch_status_t) switch_core_session_media_handle_ready(switch_core_session_t *session)
2298 {
2299 if (session->media_handle && switch_test_flag(session->media_handle, SMF_INIT)) {
2300 return SWITCH_STATUS_SUCCESS;
2301 }
2302
2303 return SWITCH_STATUS_FALSE;
2304 }
2305
2306
2307
switch_core_session_get_media_handle(switch_core_session_t * session)2308 SWITCH_DECLARE(switch_media_handle_t *) switch_core_session_get_media_handle(switch_core_session_t *session)
2309 {
2310 if (switch_core_session_media_handle_ready(session) == SWITCH_STATUS_SUCCESS) {
2311 return session->media_handle;
2312 }
2313
2314 return NULL;
2315 }
2316
switch_core_session_clear_media_handle(switch_core_session_t * session)2317 SWITCH_DECLARE(switch_status_t) switch_core_session_clear_media_handle(switch_core_session_t *session)
2318 {
2319 if (!session->media_handle) {
2320 return SWITCH_STATUS_FALSE;
2321 }
2322
2323 return SWITCH_STATUS_SUCCESS;
2324 }
2325
switch_core_media_get_mparams(switch_media_handle_t * smh)2326 SWITCH_DECLARE(switch_core_media_params_t *) switch_core_media_get_mparams(switch_media_handle_t *smh)
2327 {
2328 switch_assert(smh);
2329 return smh->mparams;
2330 }
2331
switch_core_media_prepare_codecs(switch_core_session_t * session,switch_bool_t force)2332 SWITCH_DECLARE(void) switch_core_media_prepare_codecs(switch_core_session_t *session, switch_bool_t force)
2333 {
2334 const char *abs, *codec_string = NULL;
2335 const char *ocodec = NULL, *val;
2336 switch_media_handle_t *smh;
2337 char *tmp_codec_string;
2338
2339 switch_assert(session);
2340
2341 if (!(smh = session->media_handle)) {
2342 return;
2343 }
2344
2345 if (!force && (switch_channel_test_flag(session->channel, CF_PROXY_MODE) || switch_channel_test_flag(session->channel, CF_PROXY_MEDIA))) {
2346 return;
2347 }
2348
2349 if (force) {
2350 smh->mparams->num_codecs = 0;
2351 }
2352
2353 if (smh->mparams->num_codecs) {
2354 return;
2355 }
2356
2357 ocodec = switch_channel_get_variable(session->channel, SWITCH_ORIGINATOR_CODEC_VARIABLE);
2358
2359 smh->payload_space = 0;
2360
2361 switch_assert(smh->session != NULL);
2362
2363 if ((abs = switch_channel_get_variable(session->channel, "absolute_codec_string"))) {
2364 codec_string = abs;
2365 goto ready;
2366 }
2367
2368 val = switch_channel_get_variable_dup(session->channel, "media_mix_inbound_outbound_codecs", SWITCH_FALSE, -1);
2369
2370 if (!switch_channel_test_flag(session->channel, CF_ANSWERED) && (!val || !switch_true(val) || smh->media_flags[SCMF_DISABLE_TRANSCODING]) && ocodec) {
2371 codec_string = ocodec;
2372 goto ready;
2373 }
2374
2375 if (!(codec_string = switch_channel_get_variable(session->channel, "codec_string"))) {
2376 codec_string = switch_core_media_get_codec_string(smh->session);
2377 }
2378
2379 if (codec_string && *codec_string == '=') {
2380 codec_string++;
2381 goto ready;
2382 }
2383
2384 if (ocodec) {
2385 codec_string = switch_core_session_sprintf(smh->session, "%s,%s", ocodec, codec_string);
2386 }
2387
2388 ready:
2389
2390 if (!codec_string) {
2391 codec_string = "PCMU@20i,PCMA@20i,speex@20i";
2392 }
2393
2394 tmp_codec_string = switch_core_session_strdup(smh->session, codec_string);
2395 switch_channel_set_variable(session->channel, "rtp_use_codec_string", codec_string);
2396 smh->codec_order_last = switch_separate_string(tmp_codec_string, ',', smh->codec_order, SWITCH_MAX_CODECS);
2397 smh->mparams->num_codecs = switch_loadable_module_get_codecs_sorted(smh->codecs, smh->fmtp, SWITCH_MAX_CODECS, smh->codec_order, smh->codec_order_last);
2398 }
2399
check_jb(switch_core_session_t * session,const char * input,int32_t jb_msec,int32_t maxlen,switch_bool_t silent)2400 static void check_jb(switch_core_session_t *session, const char *input, int32_t jb_msec, int32_t maxlen, switch_bool_t silent)
2401 {
2402 const char *val;
2403 switch_media_handle_t *smh;
2404 switch_rtp_engine_t *a_engine = NULL, *v_engine = NULL, *t_engine = NULL;
2405
2406 switch_assert(session);
2407
2408 if (!(smh = session->media_handle)) {
2409 return;
2410 }
2411
2412 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
2413 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
2414 t_engine = &smh->engines[SWITCH_MEDIA_TYPE_TEXT];
2415
2416
2417 if (!zstr(input)) {
2418 const char *s;
2419 if (a_engine->rtp_session) {
2420 if (!strcasecmp(input, "pause")) {
2421 switch_rtp_pause_jitter_buffer(a_engine->rtp_session, SWITCH_TRUE);
2422 return;
2423 } else if (!strcasecmp(input, "resume")) {
2424 switch_rtp_pause_jitter_buffer(a_engine->rtp_session, SWITCH_FALSE);
2425 return;
2426 } else if (!strcasecmp(input, "stop")) {
2427 switch_rtp_deactivate_jitter_buffer(a_engine->rtp_session);
2428 return;
2429 } else if (!strncasecmp(input, "debug:", 6)) {
2430 s = input + 6;
2431 if (s && !strcmp(s, "off")) {
2432 s = NULL;
2433 }
2434 switch_rtp_debug_jitter_buffer(a_engine->rtp_session, s);
2435 return;
2436 }
2437
2438 switch_channel_set_variable(session->channel, "jitterbuffer_msec", input);
2439 }
2440
2441 if (v_engine->rtp_session) {
2442 if (!strncasecmp(input, "vbsize:", 7)) {
2443 int frames = 0, max_frames = 0;
2444 s = input + 7;
2445
2446 frames = atoi(s);
2447
2448 if ((s = strchr(s, ':')) && *(s+1) != '\0') {
2449 max_frames = atoi(s+1);
2450 }
2451
2452 if (frames > 0) {
2453 switch_rtp_set_video_buffer_size(v_engine->rtp_session, frames, max_frames);
2454 } else {
2455 switch_rtp_deactivate_jitter_buffer(v_engine->rtp_session);
2456 }
2457 return;
2458 } else if (!strncasecmp(input, "vdebug:", 7)) {
2459 s = input + 7;
2460
2461 if (s && !strcmp(s, "off")) {
2462 s = NULL;
2463 }
2464 switch_rtp_debug_jitter_buffer(v_engine->rtp_session, s);
2465 return;
2466 }
2467 }
2468
2469 if (t_engine->rtp_session) {
2470 if (!strncasecmp(input, "tbsize:", 7)) {
2471 int frames = 0, max_frames = 0;
2472 s = input + 7;
2473
2474 frames = atoi(s);
2475
2476 if ((s = strchr(s, ':')) && *(s+1) != '\0') {
2477 max_frames = atoi(s+1);
2478 }
2479
2480 if (frames > 0) {
2481 switch_rtp_set_video_buffer_size(t_engine->rtp_session, frames, max_frames);
2482 }
2483 return;
2484 } else if (!strncasecmp(input, "tdebug:", 7)) {
2485 s = input + 7;
2486
2487 if (s && !strcmp(s, "off")) {
2488 s = NULL;
2489 }
2490 switch_rtp_debug_jitter_buffer(t_engine->rtp_session, s);
2491 return;
2492 }
2493 }
2494 }
2495
2496
2497 if (jb_msec || (val = switch_channel_get_variable(session->channel, "jitterbuffer_msec")) || (val = smh->mparams->jb_msec)) {
2498 char *p;
2499
2500 if (!jb_msec) {
2501 jb_msec = atoi(val);
2502
2503 if (strchr(val, 'p') && jb_msec > 0) {
2504 jb_msec *= -1;
2505 if (!maxlen) maxlen = jb_msec * 50;
2506 }
2507
2508 if ((p = strchr(val, ':'))) {
2509 p++;
2510 maxlen = atoi(p);
2511
2512 if (strchr(p, 'p') && maxlen > 0) {
2513 maxlen *= -1;
2514 }
2515 }
2516 }
2517
2518 if (!maxlen) maxlen = jb_msec * 50;
2519
2520 if (jb_msec < 0 && jb_msec > -1000) {
2521 jb_msec = (a_engine->read_codec.implementation->microseconds_per_packet / 1000) * abs(jb_msec);
2522 }
2523
2524 if (maxlen < 0 && maxlen > -1000) {
2525 maxlen = (a_engine->read_codec.implementation->microseconds_per_packet / 1000) * abs(maxlen);
2526 }
2527
2528
2529 if (jb_msec < 10 || jb_msec > 10000) {
2530 //switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,
2531 //"Invalid Jitterbuffer spec [%d] must be between 10 and 10000\n", jb_msec);
2532 jb_msec = (a_engine->read_codec.implementation->microseconds_per_packet / 1000) * 1;
2533 maxlen = jb_msec * 100;
2534 }
2535
2536 if (jb_msec && maxlen) {
2537 int qlen, maxqlen = 50;
2538
2539 qlen = jb_msec / (a_engine->read_impl.microseconds_per_packet / 1000);
2540
2541 if (maxlen) {
2542 maxqlen = maxlen / (a_engine->read_impl.microseconds_per_packet / 1000);
2543 }
2544
2545 if (maxqlen < qlen) {
2546 maxqlen = qlen * 5;
2547 }
2548 if (switch_rtp_activate_jitter_buffer(a_engine->rtp_session, qlen, maxqlen,
2549 a_engine->read_impl.samples_per_packet,
2550 a_engine->read_impl.samples_per_second) == SWITCH_STATUS_SUCCESS) {
2551 if (!silent) {
2552 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session),
2553 SWITCH_LOG_DEBUG, "Setting Jitterbuffer to %dms (%d frames) (%d max frames)\n",
2554 jb_msec, qlen, maxqlen);
2555 }
2556 switch_channel_set_flag(session->channel, CF_JITTERBUFFER);
2557 if (!switch_false(switch_channel_get_variable(session->channel, "rtp_jitter_buffer_plc"))) {
2558 switch_channel_set_flag(session->channel, CF_JITTERBUFFER_PLC);
2559 }
2560 } else if (!silent) {
2561 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session),
2562 SWITCH_LOG_WARNING, "Error Setting Jitterbuffer to %dms (%d frames)\n", jb_msec, qlen);
2563 }
2564
2565 }
2566 }
2567
2568 }
2569
check_jb_sync(switch_core_session_t * session)2570 static void check_jb_sync(switch_core_session_t *session)
2571 {
2572 int32_t jb_sync_msec = 0;
2573 uint32_t fps = 0, frames = 0;
2574 uint32_t min_frames = 0;
2575 uint32_t max_frames = 0;
2576 uint32_t cur_frames = 0;
2577 switch_media_handle_t *smh;
2578 switch_rtp_engine_t *v_engine = NULL;
2579 int sync_audio = 0;
2580
2581 const char *var;
2582
2583 switch_assert(session);
2584
2585 if (!switch_channel_test_flag(session->channel, CF_VIDEO)) {
2586 return;
2587 }
2588
2589 if (!(smh = session->media_handle)) {
2590 return;
2591 }
2592
2593 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
2594
2595 if ((var = switch_channel_get_variable_dup(session->channel, "jb_av_sync_msec", SWITCH_FALSE, -1))) {
2596 int tmp;
2597 char *p;
2598
2599 if (!strcasecmp(var, "disabled")) {
2600 return;
2601 }
2602
2603 tmp = atol(var);
2604
2605 if (tmp && tmp > -50 && tmp < 10000) {
2606 jb_sync_msec = tmp;
2607 }
2608
2609 if ((p = strchr(var, ':'))) {
2610 p++;
2611 frames = atoi(p);
2612 }
2613 }
2614
2615 switch_rtp_get_video_buffer_size(v_engine->rtp_session, &min_frames, &max_frames, &cur_frames, NULL);
2616
2617 fps = video_globals.fps;
2618
2619 if (fps < 15) return;
2620
2621 sync_audio = 1;
2622
2623 if (!frames) {
2624 if (cur_frames && min_frames && cur_frames >= min_frames) {
2625 frames = cur_frames;
2626 } else if (min_frames) {
2627 frames = min_frames;
2628 } else {
2629 frames = 0;
2630 sync_audio = 0;
2631 }
2632 }
2633
2634 if (!jb_sync_msec && frames) {
2635 jb_sync_msec = (double)(1000 / fps) * frames;
2636 }
2637
2638 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session),
2639 SWITCH_LOG_DEBUG1, "%s %s \"%s\" Sync A/V JB to %dms %u VFrames, FPS %u a:%s sync_ms:%d\n",
2640 switch_core_session_get_uuid(session),
2641 switch_channel_get_name(session->channel),
2642 switch_channel_get_variable_dup(session->channel, "caller_id_name", SWITCH_FALSE, -1),
2643 jb_sync_msec, frames, video_globals.fps, sync_audio ? "yes" : "no", jb_sync_msec);
2644
2645 if (sync_audio) {
2646 check_jb(session, NULL, jb_sync_msec, jb_sync_msec * 2, SWITCH_TRUE);
2647 }
2648
2649 video_globals.synced++;
2650 }
2651
2652
2653 //?
switch_core_media_read_lock_unlock(switch_core_session_t * session,switch_media_type_t type,switch_bool_t lock)2654 SWITCH_DECLARE(switch_status_t) switch_core_media_read_lock_unlock(switch_core_session_t *session, switch_media_type_t type, switch_bool_t lock)
2655 {
2656 switch_rtp_engine_t *engine;
2657 switch_media_handle_t *smh;
2658
2659 switch_assert(session);
2660
2661 if (!(smh = session->media_handle)) {
2662 return SWITCH_STATUS_FALSE;
2663 }
2664
2665 if (!smh->media_flags[SCMF_RUNNING]) {
2666 return SWITCH_STATUS_FALSE;
2667 }
2668
2669 engine = &smh->engines[type];
2670
2671 if (!engine->read_codec.implementation || !switch_core_codec_ready(&engine->read_codec)) {
2672 return SWITCH_STATUS_FALSE;
2673 }
2674
2675 switch_assert(engine->rtp_session != NULL);
2676
2677
2678 if (!switch_channel_up_nosig(session->channel) || !switch_rtp_ready(engine->rtp_session) || switch_channel_test_flag(session->channel, CF_NOT_READY)) {
2679 return SWITCH_STATUS_FALSE;
2680 }
2681
2682 if (lock) {
2683 if (smh->read_mutex[type] && switch_mutex_trylock(smh->read_mutex[type]) != SWITCH_STATUS_SUCCESS) {
2684 /* return CNG, another thread is already reading */
2685 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "%s is already being read for %s\n",
2686 switch_channel_get_name(session->channel), type2str(type));
2687 return SWITCH_STATUS_INUSE;
2688 }
2689 } else {
2690 switch_mutex_unlock(smh->read_mutex[type]);
2691 }
2692
2693 return SWITCH_STATUS_SUCCESS;
2694 }
2695
2696
2697
2698
2699 //?
switch_rtp_text_factory_create(switch_rtp_text_factory_t ** tfP,switch_memory_pool_t * pool)2700 SWITCH_DECLARE(switch_status_t) switch_rtp_text_factory_create(switch_rtp_text_factory_t **tfP, switch_memory_pool_t *pool)
2701 {
2702 int x;
2703
2704 *tfP = switch_core_alloc(pool, sizeof(**tfP));
2705
2706 switch_buffer_create_dynamic(&(*tfP)->write_buffer, 512, 1024, 0);
2707 (*tfP)->pool = pool;
2708 (*tfP)->text_write_frame_data = switch_core_alloc(pool, SWITCH_RTP_MAX_BUF_LEN);
2709 (*tfP)->text_write_frame.packet = (*tfP)->text_write_frame_data;
2710 (*tfP)->text_write_frame.data = (switch_byte_t *)(*tfP)->text_write_frame.packet + 12;
2711 (*tfP)->text_write_frame.buflen = SWITCH_RTP_MAX_BUF_LEN - 12;
2712
2713 (*tfP)->red_max = 5;
2714 (*tfP)->red_bufsize = SWITCH_RTP_MAX_BUF_LEN;
2715
2716 switch_core_timer_init(&(*tfP)->timer, "soft", TEXT_TIMER_MS, TEXT_TIMER_SAMPLES, pool);
2717
2718 for(x = 0; x < (*tfP)->red_max; x++) {
2719 (*tfP)->red_buf[x] = switch_core_alloc(pool, SWITCH_RTP_MAX_BUF_LEN);
2720 }
2721
2722 return SWITCH_STATUS_SUCCESS;
2723 }
2724
switch_rtp_text_factory_destroy(switch_rtp_text_factory_t ** tfP)2725 SWITCH_DECLARE(switch_status_t) switch_rtp_text_factory_destroy(switch_rtp_text_factory_t **tfP)
2726 {
2727 switch_core_timer_destroy(&(*tfP)->timer);
2728 switch_buffer_destroy(&(*tfP)->write_buffer);
2729
2730 return SWITCH_STATUS_SUCCESS;;
2731 }
2732
2733 #include <wchar.h>
2734
get_rtt_red_seq(int want_seq,void * data,switch_size_t datalen,int seq,switch_payload_t * new_payload,void * new_data,uint32_t * new_datalen)2735 static int get_rtt_red_seq(int want_seq, void *data, switch_size_t datalen, int seq, switch_payload_t *new_payload, void *new_data, uint32_t *new_datalen)
2736 {
2737 unsigned char *buf = data;
2738 int count = 0;
2739 unsigned char *e = (buf + datalen);
2740
2741 int len[MAX_RED_FRAMES] = { 0 };
2742 int pt[MAX_RED_FRAMES] = { 0 };
2743 int idx = 0, x = 0;
2744
2745 *new_datalen = datalen;
2746
2747 *(buf + datalen) = '\0';
2748
2749 while (*buf & 0x80) {
2750 if (buf + 3 > e) {
2751 *new_datalen = 0;
2752 return 0;
2753 }
2754
2755 pt[count] = *buf & 0x7F;
2756 len[count] = (ntohs(*(uint16_t *)(buf + 2)) & 0x03ff);
2757 buf += 4;
2758 count++;
2759 }
2760
2761 buf++;
2762
2763 idx = count - (seq - want_seq);
2764
2765 if (idx < 0) {
2766 *new_datalen = 0;
2767 return 0;
2768 }
2769
2770 if (!len[idx]) {
2771 *new_datalen = len[idx];
2772 return 0;
2773 }
2774
2775 for(x = 0; x < idx; x++) {
2776 buf += len[x];
2777 }
2778
2779 *new_datalen = len[idx];
2780 *new_payload = pt[idx];
2781
2782 memcpy(new_data, buf, len[idx]);
2783
2784 *(((char *)new_data) + len[idx]) = '\0';
2785
2786 return 1;
2787
2788 }
2789
get_rtt_payload(void * data,switch_size_t datalen,switch_payload_t * new_payload,uint32_t * new_datalen,int * red_level)2790 static void *get_rtt_payload(void *data, switch_size_t datalen, switch_payload_t *new_payload, uint32_t *new_datalen, int *red_level)
2791 {
2792 unsigned char *buf = data;
2793 int bytes = 0, count = 0, pt = 0, len = 0;//, ts = 0;
2794 unsigned char *e = (buf + datalen);
2795
2796 *new_datalen = datalen;
2797 *red_level = 1;
2798
2799 while (*buf & 0x80) {
2800 if (buf + 3 > e) {
2801 *new_datalen = 0;
2802 return NULL;
2803 }
2804 count++;
2805 pt = *buf & 0x7F;
2806 //ts = ntohs(*(uint16_t *)(buf + 1)) >> 2;
2807 len = (ntohs(*(uint16_t *)(buf + 2)) & 0x03ff);
2808 buf += 4;
2809 bytes += len;
2810 }
2811
2812 *new_datalen = datalen - bytes - 1 - (count *4);
2813 *new_payload = pt;
2814 buf += bytes + 1;
2815
2816 if (buf > e) {
2817 *new_datalen = 0;
2818 return NULL;
2819 }
2820
2821 return buf;
2822 }
2823
2824 //?
2825
check_media_timeout_params(switch_core_session_t * session,switch_rtp_engine_t * engine)2826 static void check_media_timeout_params(switch_core_session_t *session, switch_rtp_engine_t *engine)
2827 {
2828 switch_media_type_t type = engine->type;
2829 const char *val;
2830
2831 if ((val = switch_channel_get_variable(session->channel, "media_hold_timeout"))) {
2832 engine->media_hold_timeout = atoi(val);
2833 }
2834
2835 if ((val = switch_channel_get_variable(session->channel, "media_timeout"))) {
2836 engine->media_timeout = atoi(val);
2837 }
2838
2839 if (type == SWITCH_MEDIA_TYPE_VIDEO) {
2840 if ((val = switch_channel_get_variable(session->channel, "media_hold_timeout_video"))) {
2841 engine->media_hold_timeout = atoi(val);
2842 }
2843
2844 if ((val = switch_channel_get_variable(session->channel, "media_timeout_video"))) {
2845 engine->media_timeout = atoi(val);
2846 }
2847 } else {
2848
2849 if ((val = switch_channel_get_variable(session->channel, "media_hold_timeout_audio"))) {
2850 engine->media_hold_timeout = atoi(val);
2851 }
2852
2853 if ((val = switch_channel_get_variable(session->channel, "media_timeout_audio"))) {
2854 engine->media_timeout = atoi(val);
2855 }
2856 }
2857
2858 if (switch_rtp_ready(engine->rtp_session) && engine->media_timeout) {
2859 switch_rtp_set_media_timeout(engine->rtp_session, engine->media_timeout);
2860 }
2861
2862 }
2863
switch_core_media_read_frame(switch_core_session_t * session,switch_frame_t ** frame,switch_io_flag_t flags,int stream_id,switch_media_type_t type)2864 SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session_t *session, switch_frame_t **frame,
2865 switch_io_flag_t flags, int stream_id, switch_media_type_t type)
2866 {
2867 switch_rtcp_frame_t rtcp_frame;
2868 switch_rtp_engine_t *engine;
2869 switch_status_t status;
2870 switch_media_handle_t *smh;
2871 int do_cng = 0;
2872
2873 switch_assert(session);
2874
2875 if (!(smh = session->media_handle)) {
2876 return SWITCH_STATUS_FALSE;
2877 }
2878
2879 if (!smh->media_flags[SCMF_RUNNING]) {
2880 return SWITCH_STATUS_FALSE;
2881 }
2882
2883 engine = &smh->engines[type];
2884
2885 if (type == SWITCH_MEDIA_TYPE_AUDIO && ! switch_channel_test_flag(session->channel, CF_AUDIO)) {
2886 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "%s Reading audio from a non-audio session.\n", switch_channel_get_name(session->channel));
2887 switch_yield(50000);
2888 return SWITCH_STATUS_INUSE;
2889 }
2890
2891 if (type != SWITCH_MEDIA_TYPE_TEXT && (!engine->read_codec.implementation || !switch_core_codec_ready(&engine->read_codec))) {
2892 switch_yield(50000);
2893 return SWITCH_STATUS_FALSE;
2894 }
2895
2896 if (!switch_channel_up_nosig(session->channel) || !switch_rtp_ready(engine->rtp_session) || switch_channel_test_flag(session->channel, CF_NOT_READY)) {
2897 switch_yield(50000);
2898 return SWITCH_STATUS_FALSE;
2899 }
2900
2901 if (smh->read_mutex[type] && switch_mutex_trylock(smh->read_mutex[type]) != SWITCH_STATUS_SUCCESS) {
2902 /* return CNG, another thread is already reading */
2903 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "%s is already being read for %s\n",
2904 switch_channel_get_name(session->channel), type2str(type));
2905 return SWITCH_STATUS_INUSE;
2906 }
2907
2908
2909 engine->read_frame.datalen = 0;
2910 engine->read_frame.flags = SFF_NONE;
2911 engine->read_frame.m = SWITCH_FALSE;
2912 engine->read_frame.img = NULL;
2913 engine->read_frame.payload = 0;
2914
2915 while (smh->media_flags[SCMF_RUNNING] && engine->read_frame.datalen == 0) {
2916 engine->read_frame.flags = SFF_NONE;
2917 status = switch_rtp_zerocopy_read_frame(engine->rtp_session, &engine->read_frame, flags);
2918
2919
2920 if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
2921 if (status == SWITCH_STATUS_TIMEOUT) {
2922
2923 if (switch_channel_get_variable(session->channel, "execute_on_media_timeout")) {
2924 *frame = &engine->read_frame;
2925 switch_set_flag((*frame), SFF_CNG);
2926 (*frame)->datalen = engine->read_impl.encoded_bytes_per_packet;
2927 memset((*frame)->data, 0, (*frame)->datalen);
2928 switch_channel_execute_on(session->channel, "execute_on_media_timeout");
2929 switch_goto_status(SWITCH_STATUS_SUCCESS, end);
2930 }
2931
2932
2933 switch_channel_hangup(session->channel, SWITCH_CAUSE_MEDIA_TIMEOUT);
2934 }
2935 goto end;
2936 }
2937
2938 if (switch_channel_test_flag(session->channel, CF_LEG_HOLDING)) {
2939 status = SWITCH_STATUS_INUSE;
2940 goto end;
2941 }
2942
2943 if (status == SWITCH_STATUS_BREAK) {
2944 goto end;
2945 }
2946
2947 if (type == SWITCH_MEDIA_TYPE_VIDEO) {
2948 if (engine->read_frame.m) {
2949 if (!smh->vid_started) {
2950 smh->vid_started = switch_epoch_time_now(NULL);
2951 }
2952 smh->vid_frames++;
2953
2954 if ((smh->vid_frames % 5) == 0) {
2955 switch_core_media_get_video_fps(session);
2956 }
2957
2958 if (video_globals.fps && (!video_globals.synced || ((smh->vid_frames % 300) == 0))) {
2959 check_jb_sync(session);
2960 }
2961 }
2962 }
2963
2964 /* re-set codec if necessary */
2965 if (type != SWITCH_MEDIA_TYPE_TEXT && engine->reset_codec > 0) {
2966 const char *val;
2967 int rtp_timeout_sec = 0;
2968 int rtp_hold_timeout_sec = 0;
2969
2970 engine->reset_codec = 0;
2971
2972 if (switch_rtp_ready(engine->rtp_session)) {
2973
2974 check_media_timeout_params(session, engine);
2975
2976 if (type == SWITCH_MEDIA_TYPE_VIDEO) {
2977 switch_core_media_set_video_codec(session, 1);
2978 } else {
2979
2980 if (switch_core_media_set_codec(session, 1, smh->mparams->codec_flags) != SWITCH_STATUS_SUCCESS) {
2981 *frame = NULL;
2982 switch_goto_status(SWITCH_STATUS_GENERR, end);
2983 }
2984 }
2985
2986 if (type == SWITCH_MEDIA_TYPE_AUDIO && engine->read_impl.samples_per_second) {
2987 if ((val = switch_channel_get_variable(session->channel, "rtp_timeout_sec"))) {
2988 int v = atoi(val);
2989 if (v >= 0) {
2990 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
2991 "rtp_timeout_sec deprecated use media_timeout variable.\n");
2992 rtp_timeout_sec = v;
2993 }
2994 }
2995
2996 if ((val = switch_channel_get_variable(session->channel, "rtp_hold_timeout_sec"))) {
2997 int v = atoi(val);
2998 if (v >= 0) {
2999 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
3000 "rtp_hold_timeout_sec deprecated use media_timeout variable.\n");
3001 rtp_hold_timeout_sec = v;
3002 }
3003 }
3004
3005 if (rtp_timeout_sec) {
3006 engine->max_missed_packets = (engine->read_impl.samples_per_second * rtp_timeout_sec) /
3007 engine->read_impl.samples_per_packet;
3008
3009 switch_rtp_set_max_missed_packets(engine->rtp_session, engine->max_missed_packets);
3010 if (!rtp_hold_timeout_sec) {
3011 rtp_hold_timeout_sec = rtp_timeout_sec * 10;
3012 }
3013 }
3014
3015 if (rtp_hold_timeout_sec) {
3016 engine->max_missed_hold_packets = (engine->read_impl.samples_per_second * rtp_hold_timeout_sec) /
3017 engine->read_impl.samples_per_packet;
3018 }
3019 }
3020 }
3021
3022 check_jb(session, NULL, 0, 0, SWITCH_FALSE);
3023
3024 engine->check_frames = 0;
3025 engine->last_ts = 0;
3026 engine->last_seq = 0;
3027
3028 do_cng = 1;
3029 }
3030
3031
3032 if (do_cng) {
3033 /* return CNG for now */
3034 *frame = &engine->read_frame;
3035 switch_set_flag((*frame), SFF_CNG);
3036 (*frame)->datalen = engine->read_impl.encoded_bytes_per_packet;
3037 memset((*frame)->data, 0, (*frame)->datalen);
3038 switch_goto_status(SWITCH_STATUS_SUCCESS, end);
3039 }
3040
3041
3042 /* Try to read an RTCP frame, if successful raise an event */
3043 if (switch_rtcp_zerocopy_read_frame(engine->rtp_session, &rtcp_frame) == SWITCH_STATUS_SUCCESS) {
3044 switch_event_t *event;
3045
3046 if (switch_event_create(&event, SWITCH_EVENT_RECV_RTCP_MESSAGE) == SWITCH_STATUS_SUCCESS) {
3047 char value[30];
3048 char header[50];
3049 int i;
3050
3051 char *uuid = switch_core_session_get_uuid(session);
3052 if (uuid) {
3053 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(session));
3054 }
3055
3056 snprintf(value, sizeof(value), "%.8x", rtcp_frame.ssrc);
3057 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SSRC", value);
3058
3059 snprintf(value, sizeof(value), "%u", rtcp_frame.ntp_msw);
3060 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "NTP-Most-Significant-Word", value);
3061
3062 snprintf(value, sizeof(value), "%u", rtcp_frame.ntp_lsw);
3063 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "NTP-Least-Significant-Word", value);
3064
3065 snprintf(value, sizeof(value), "%u", rtcp_frame.timestamp);
3066 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "RTP-Timestamp", value);
3067
3068 snprintf(value, sizeof(value), "%u", rtcp_frame.packet_count);
3069 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Sender-Packet-Count", value);
3070
3071 snprintf(value, sizeof(value), "%u", rtcp_frame.octect_count);
3072 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Octect-Packet-Count", value);
3073
3074 snprintf(value, sizeof(value), "%u", engine->read_frame.timestamp);
3075 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Last-RTP-Timestamp", value);
3076
3077 snprintf(value, sizeof(value), "%u", engine->read_frame.rate);
3078 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "RTP-Rate", value);
3079
3080 snprintf(value, sizeof(value), "%" SWITCH_TIME_T_FMT, switch_time_now());
3081 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Capture-Time", value);
3082
3083 // Add sources info
3084 for (i = 0; i < rtcp_frame.report_count; i++) {
3085 snprintf(header, sizeof(header), "Source%u-SSRC", i);
3086 snprintf(value, sizeof(value), "%.8x", rtcp_frame.reports[i].ssrc);
3087 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, header, value);
3088 snprintf(header, sizeof(header), "Source%u-Fraction", i);
3089 snprintf(value, sizeof(value), "%u", rtcp_frame.reports[i].fraction);
3090 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, header, value);
3091 snprintf(header, sizeof(header), "Source%u-Lost", i);
3092 snprintf(value, sizeof(value), "%u", rtcp_frame.reports[i].lost);
3093 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, header, value);
3094 snprintf(header, sizeof(header), "Source%u-Loss-Avg", i);
3095 snprintf(value, sizeof(value), "%u", rtcp_frame.reports[i].loss_avg);
3096 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, header, value);
3097 snprintf(header, sizeof(header), "Source%u-Highest-Sequence-Number-Received", i);
3098 snprintf(value, sizeof(value), "%u", rtcp_frame.reports[i].highest_sequence_number_received);
3099 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, header, value);
3100 snprintf(header, sizeof(header), "Source%u-Jitter", i);
3101 snprintf(value, sizeof(value), "%u", rtcp_frame.reports[i].jitter);
3102 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, header, value);
3103 snprintf(header, sizeof(header), "Source%u-LSR", i);
3104 snprintf(value, sizeof(value), "%u", rtcp_frame.reports[i].lsr);
3105 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, header, value);
3106 snprintf(header, sizeof(header), "Source%u-DLSR", i);
3107 snprintf(value, sizeof(value), "%u", rtcp_frame.reports[i].dlsr);
3108 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, header, value);
3109 snprintf(header, sizeof(header), "Rtt%u-Avg", i);
3110 snprintf(value, sizeof(value), "%f", rtcp_frame.reports[i].rtt_avg);
3111 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, header, value);
3112 }
3113
3114 switch_event_fire(&event);
3115 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG10, "Dispatched RTCP event\n");
3116 }
3117 }
3118
3119 /* Fast PASS! */
3120 if (switch_test_flag((&engine->read_frame), SFF_PROXY_PACKET)) {
3121 *frame = &engine->read_frame;
3122 switch_goto_status(SWITCH_STATUS_SUCCESS, end);
3123 }
3124
3125 if (switch_rtp_has_dtmf(engine->rtp_session)) {
3126 switch_dtmf_t dtmf = { 0 };
3127 switch_rtp_dequeue_dtmf(engine->rtp_session, &dtmf);
3128 switch_channel_queue_dtmf(session->channel, &dtmf);
3129 }
3130
3131 if (type != SWITCH_MEDIA_TYPE_TEXT && engine->read_frame.datalen > 0) {
3132 uint32_t bytes = 0;
3133 int frames = 1;
3134
3135 /* autofix timing */
3136 if (!switch_test_flag((&engine->read_frame), SFF_CNG)) {
3137 if (!engine->read_codec.implementation || !switch_core_codec_ready(&engine->read_codec)) {
3138 *frame = NULL;
3139 switch_goto_status(SWITCH_STATUS_GENERR, end);
3140 }
3141
3142 /* check for timing issues */
3143 if (smh->media_flags[SCMF_AUTOFIX_TIMING] && type == SWITCH_MEDIA_TYPE_AUDIO && engine->read_impl.samples_per_second) {
3144 char is_vbr;
3145 is_vbr = engine->read_impl.encoded_bytes_per_packet?0:1;
3146
3147 engine->check_frames++;
3148 /* CBR */
3149 if ((smh->media_flags[SCMF_AUTOFIX_TIMING] && (engine->read_frame.datalen % 10) == 0)
3150 && (engine->check_frames < MAX_CODEC_CHECK_FRAMES) && !is_vbr) {
3151 engine->check_frames++;
3152
3153 if (engine->last_ts && engine->read_frame.datalen != engine->read_impl.encoded_bytes_per_packet) {
3154
3155 uint32_t codec_ms = (int) (engine->read_frame.timestamp -
3156 engine->last_ts) / (engine->read_impl.samples_per_second / 1000);
3157 if (engine->last_seq && (int) (engine->read_frame.seq - engine->last_seq) > 1) {
3158 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "[%s]: Correcting calculated ptime value from [%d] to [%d] to compensate for [%d] lost packet(s). \n", is_vbr?"VBR":"CBR", codec_ms, codec_ms / (int) (engine->read_frame.seq - engine->last_seq), (int) (engine->read_frame.seq - engine->last_seq - 1));
3159 codec_ms = codec_ms / (int) (engine->read_frame.seq - engine->last_seq);
3160 }
3161
3162 if ((codec_ms % 10) != 0 || codec_ms > engine->read_impl.samples_per_packet * 10) {
3163 engine->last_ts = 0;
3164 engine->last_seq = 0;
3165 goto skip;
3166 }
3167
3168 if (engine->last_codec_ms && engine->last_codec_ms == codec_ms) {
3169 engine->mismatch_count++;
3170 } else {
3171 engine->mismatch_count = 0;
3172 }
3173
3174 engine->last_codec_ms = codec_ms;
3175
3176 if (engine->mismatch_count > MAX_MISMATCH_FRAMES) {
3177 if (codec_ms != engine->cur_payload_map->codec_ms) {
3178
3179 if (codec_ms > 120) { /* yeah right */
3180 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
3181 "[%s]: Your phone is trying to send timestamps that suggest an increment of %dms per packet\n"
3182 "That seems hard to believe so I am going to go on ahead and um ignore that, mmkay?\n",
3183 is_vbr?"VBR":"CBR",
3184 (int) codec_ms);
3185 engine->check_frames = MAX_CODEC_CHECK_FRAMES;
3186 goto skip;
3187 }
3188
3189 engine->read_frame.datalen = 0;
3190
3191 if (codec_ms != engine->cur_payload_map->codec_ms) {
3192 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
3193 "[%s]: Asynchronous PTIME not supported, changing our end from %d to %d\n",
3194 is_vbr?"VBR":"CBR",
3195 (int) engine->cur_payload_map->codec_ms,
3196 (int) codec_ms
3197 );
3198
3199 switch_channel_set_variable_printf(session->channel, "rtp_h_X-Broken-PTIME", "Adv=%d;Sent=%d",
3200 (int) engine->cur_payload_map->codec_ms, (int) codec_ms);
3201
3202 engine->cur_payload_map->codec_ms = codec_ms;
3203
3204 /* mark to re-set codec */
3205 engine->reset_codec = 2;
3206 }
3207 }
3208 }
3209
3210 } else {
3211 engine->mismatch_count = 0;
3212 }
3213
3214 engine->last_ts = engine->read_frame.timestamp;
3215 engine->last_seq = engine->read_frame.seq;
3216
3217 } else if (smh->media_flags[SCMF_AUTOFIX_TIMING] && is_vbr && switch_rtp_get_jitter_buffer(engine->rtp_session)
3218 && type == SWITCH_MEDIA_TYPE_AUDIO
3219 && engine->read_frame.timestamp && engine->read_frame.seq && engine->read_impl.samples_per_second) {
3220 uint32_t codec_ms = (int) (engine->read_frame.timestamp -
3221 engine->last_ts) / (engine->read_impl.samples_per_second / 1000);
3222
3223 if (engine->last_seq && (int) (engine->read_frame.seq - engine->last_seq) > 1) {
3224 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "[%s]: Correcting calculated ptime value from [%d] to [%d] to compensate for [%d] lost packet(s)\n", is_vbr?"VBR":"CBR", codec_ms, codec_ms / (int) (engine->read_frame.seq - engine->last_seq), (int) (engine->read_frame.seq - engine->last_seq - 1));
3225 codec_ms = codec_ms / (int) (engine->read_frame.seq - engine->last_seq);
3226 }
3227
3228 if (codec_ms && codec_ms != engine->cur_payload_map->codec_ms) {
3229 if (engine->last_codec_ms && engine->last_codec_ms == codec_ms) {
3230 engine->mismatch_count++;
3231 }
3232 } else {
3233 engine->mismatch_count = 0;
3234 }
3235
3236 engine->last_codec_ms = codec_ms;
3237
3238 if (engine->mismatch_count > MAX_MISMATCH_FRAMES) {
3239
3240 if (codec_ms > 120) {
3241 /*will show too many times with packet loss*/
3242 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG3,
3243 "[%s]: Remote party is trying to send timestamps that suggest an increment of [%d] ms per packet, which is too high. Ignoring.\n",
3244 is_vbr?"VBR":"CBR",
3245 (int) codec_ms);
3246 engine->last_ts = engine->read_frame.timestamp;
3247 engine->last_seq = engine->read_frame.seq;
3248 goto skip;
3249 }
3250
3251 if (codec_ms != engine->cur_payload_map->codec_ms) {
3252 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
3253 "[%s]: Packet size change detected. Remote PTIME changed from [%d] to [%d]\n",
3254 is_vbr?"VBR":"CBR",
3255 (int) engine->cur_payload_map->codec_ms,
3256 (int) codec_ms
3257 );
3258 engine->cur_payload_map->codec_ms = codec_ms;
3259 engine->reset_codec = 2;
3260
3261 if (switch_channel_test_flag(session->channel, CF_CONFERENCE)) {
3262 switch_channel_set_flag(session->channel, CF_CONFERENCE_RESET_MEDIA);
3263 }
3264 }
3265 }
3266
3267 engine->last_ts = engine->read_frame.timestamp;
3268 engine->last_seq = engine->read_frame.seq;
3269
3270 } else {
3271 engine->mismatch_count = 0;
3272 engine->last_ts = 0;
3273 engine->last_seq = 0;
3274 }
3275 }
3276
3277 /* autofix payload type */
3278
3279 if (!engine->reset_codec &&
3280 engine->codec_negotiated &&
3281 (!smh->mparams->cng_pt || engine->read_frame.payload != smh->mparams->cng_pt) &&
3282 (!smh->mparams->recv_te || engine->read_frame.payload != smh->mparams->recv_te) &&
3283 (!smh->mparams->te || engine->read_frame.payload != smh->mparams->te) &&
3284 !switch_test_flag((&engine->read_frame), SFF_CNG) &&
3285 !switch_test_flag((&engine->read_frame), SFF_PLC) &&
3286 engine->read_frame.payload != engine->cur_payload_map->recv_pt &&
3287 engine->read_frame.payload != engine->cur_payload_map->pt) {
3288
3289 payload_map_t *pmap;
3290
3291
3292 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
3293 "alternate payload received (received %d, expecting %d)\n",
3294 (int) engine->read_frame.payload, (int) engine->cur_payload_map->pt);
3295
3296
3297 /* search for payload type */
3298 switch_mutex_lock(smh->sdp_mutex);
3299 for (pmap = engine->payload_map; pmap; pmap = pmap->next) {
3300 if (engine->read_frame.payload == pmap->recv_pt && pmap->negotiated) {
3301 engine->cur_payload_map = pmap;
3302 engine->cur_payload_map->current = 1;
3303 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
3304 "Changing current codec to %s (payload type %d).\n",
3305 pmap->iananame, pmap->pt);
3306
3307 /* mark to re-set codec */
3308 engine->reset_codec = 1;
3309 break;
3310 }
3311 }
3312 switch_mutex_unlock(smh->sdp_mutex);
3313
3314 if (!engine->reset_codec) {
3315 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
3316 "Could not change to payload type %d, ignoring...\n",
3317 (int) engine->read_frame.payload);
3318 }
3319 }
3320
3321 skip:
3322
3323 if ((bytes = engine->read_impl.encoded_bytes_per_packet)) {
3324 frames = (engine->read_frame.datalen / bytes);
3325 }
3326 engine->read_frame.samples = (int) (frames * engine->read_impl.samples_per_packet);
3327
3328 if (engine->read_frame.datalen == 0) {
3329 continue;
3330 }
3331 }
3332 break;
3333 }
3334 }
3335
3336 if (engine->read_frame.datalen == 0) {
3337 *frame = NULL;
3338 }
3339
3340
3341 if (type == SWITCH_MEDIA_TYPE_TEXT && !switch_test_flag((&engine->read_frame), SFF_CNG)) {
3342 if (engine->red_pt) {
3343 unsigned char *p = engine->read_frame.data;
3344
3345 *(p + engine->read_frame.datalen) = '\0';
3346 engine->tf->text_frame = engine->read_frame;
3347
3348 if (switch_test_flag((&engine->read_frame), SFF_PLC)) {
3349 switch_jb_t *jb = switch_core_session_get_jb(session, SWITCH_MEDIA_TYPE_TEXT);
3350 int i = 0;
3351
3352 engine->tf->text_frame.datalen = 0;
3353
3354 for (i = 1; i < 3; i++) {
3355 switch_frame_t frame = { 0 };
3356 uint8_t buf[SWITCH_RTP_MAX_BUF_LEN];
3357 frame.data = buf;
3358 frame.buflen = sizeof(buf);
3359
3360 if (switch_jb_peek_frame(jb, 0, engine->read_frame.seq, i, &frame) == SWITCH_STATUS_SUCCESS) {
3361 if (get_rtt_red_seq(engine->read_frame.seq,
3362 frame.data,
3363 frame.datalen,
3364 frame.seq,
3365 &engine->tf->text_frame.payload,
3366 engine->tf->text_frame.data,
3367 &engine->tf->text_frame.datalen)) {
3368 break;
3369
3370 }
3371 }
3372
3373 }
3374
3375 if (engine->tf->text_frame.datalen == 0) {
3376 engine->tf->text_frame.data = "� ";
3377 engine->tf->text_frame.datalen = strlen(engine->tf->text_frame.data);
3378 }
3379
3380 } else {
3381 if (!(engine->tf->text_frame.data = get_rtt_payload(engine->read_frame.data,
3382 engine->tf->text_frame.datalen,
3383 &engine->tf->text_frame.payload,
3384 &engine->tf->text_frame.datalen,
3385 &engine->tf->red_level))) {
3386 engine->tf->text_frame.datalen = 0;
3387 }
3388 }
3389
3390 *frame = &engine->tf->text_frame;
3391
3392 if ((*frame)->datalen == 0) {
3393 (*frame)->flags |= SFF_CNG;
3394 (*frame)->data = "";
3395 }
3396 }
3397
3398 } else {
3399 *frame = &engine->read_frame;
3400 }
3401
3402 status = SWITCH_STATUS_SUCCESS;
3403
3404 end:
3405
3406 if (smh->read_mutex[type]) {
3407 switch_mutex_unlock(smh->read_mutex[type]);
3408 }
3409
3410 return status;
3411 }
3412
3413 //?
switch_core_media_write_frame(switch_core_session_t * session,switch_frame_t * frame,switch_io_flag_t flags,int stream_id,switch_media_type_t type)3414 SWITCH_DECLARE(switch_status_t) switch_core_media_write_frame(switch_core_session_t *session,
3415 switch_frame_t *frame, switch_io_flag_t flags, int stream_id, switch_media_type_t type)
3416 {
3417 switch_status_t status = SWITCH_STATUS_SUCCESS;
3418 int bytes = 0, samples = 0, frames = 0;
3419 switch_rtp_engine_t *engine;
3420 switch_media_handle_t *smh;
3421
3422 switch_assert(session);
3423
3424 if (!(smh = session->media_handle)) {
3425 return SWITCH_STATUS_FALSE;
3426 }
3427
3428 if (!smh->media_flags[SCMF_RUNNING]) {
3429 return SWITCH_STATUS_FALSE;
3430 }
3431
3432 engine = &smh->engines[type];
3433
3434 if (type == SWITCH_MEDIA_TYPE_VIDEO) {
3435 if (engine->thread_write_lock && engine->thread_write_lock != switch_thread_self()) {
3436 return SWITCH_STATUS_SUCCESS;
3437 }
3438 }
3439
3440 if (switch_channel_test_flag(session->channel, CF_VIDEO_ONLY) && type == SWITCH_MEDIA_TYPE_AUDIO) {
3441 return SWITCH_STATUS_SUCCESS;
3442 }
3443
3444 if (type != SWITCH_MEDIA_TYPE_TEXT) {
3445
3446 while (!(engine->read_codec.implementation && switch_rtp_ready(engine->rtp_session))) {
3447 if (switch_channel_ready(session->channel)) {
3448 switch_yield(10000);
3449 } else {
3450 return SWITCH_STATUS_GENERR;
3451 }
3452 }
3453
3454 if (!engine->read_codec.implementation || !switch_core_codec_ready(&engine->read_codec)) {
3455 return SWITCH_STATUS_GENERR;
3456 }
3457
3458 if (!switch_test_flag(frame, SFF_CNG) && !switch_test_flag(frame, SFF_PROXY_PACKET)) {
3459 if (engine->read_impl.encoded_bytes_per_packet) {
3460 bytes = engine->read_impl.encoded_bytes_per_packet;
3461 frames = ((int) frame->datalen / bytes);
3462 } else
3463 frames = 1;
3464
3465 samples = frames * engine->read_impl.samples_per_packet;
3466 }
3467 }
3468
3469 engine->timestamp_send += samples;
3470
3471 if (switch_rtp_write_frame(engine->rtp_session, frame) < 0) {
3472 status = SWITCH_STATUS_FALSE;
3473 }
3474
3475
3476 return status;
3477 }
3478
3479
3480 //?
switch_core_media_copy_t38_options(switch_t38_options_t * t38_options,switch_core_session_t * session)3481 SWITCH_DECLARE(void) switch_core_media_copy_t38_options(switch_t38_options_t *t38_options, switch_core_session_t *session)
3482 {
3483 switch_channel_t *channel = switch_core_session_get_channel(session);
3484 switch_t38_options_t *local_t38_options = switch_channel_get_private(channel, "t38_options");
3485
3486 switch_assert(t38_options);
3487
3488 if (!local_t38_options) {
3489 local_t38_options = switch_core_session_alloc(session, sizeof(switch_t38_options_t));
3490 }
3491
3492 local_t38_options->T38MaxBitRate = t38_options->T38MaxBitRate;
3493 local_t38_options->T38FaxFillBitRemoval = t38_options->T38FaxFillBitRemoval;
3494 local_t38_options->T38FaxTranscodingMMR = t38_options->T38FaxTranscodingMMR;
3495 local_t38_options->T38FaxTranscodingJBIG = t38_options->T38FaxTranscodingJBIG;
3496 local_t38_options->T38FaxRateManagement = switch_core_session_strdup(session, t38_options->T38FaxRateManagement);
3497 local_t38_options->T38FaxMaxBuffer = t38_options->T38FaxMaxBuffer;
3498 local_t38_options->T38FaxMaxDatagram = t38_options->T38FaxMaxDatagram;
3499 local_t38_options->T38FaxUdpEC = switch_core_session_strdup(session, t38_options->T38FaxUdpEC);
3500 local_t38_options->T38VendorInfo = switch_core_session_strdup(session, t38_options->T38VendorInfo);
3501 local_t38_options->remote_ip = switch_core_session_strdup(session, t38_options->remote_ip);
3502 local_t38_options->remote_port = t38_options->remote_port;
3503
3504
3505 switch_channel_set_private(channel, "t38_options", local_t38_options);
3506
3507 }
3508
3509 //?
switch_core_media_get_offered_pt(switch_core_session_t * session,const switch_codec_implementation_t * mimp,switch_payload_t * pt)3510 SWITCH_DECLARE(switch_status_t) switch_core_media_get_offered_pt(switch_core_session_t *session, const switch_codec_implementation_t *mimp, switch_payload_t *pt)
3511 {
3512 int i = 0;
3513 switch_media_handle_t *smh;
3514
3515 switch_assert(session);
3516
3517 if (!(smh = session->media_handle) || !mimp) {
3518 return SWITCH_STATUS_FALSE;
3519 }
3520
3521
3522 for (i = 0; i < smh->mparams->num_codecs; i++) {
3523 const switch_codec_implementation_t *imp = smh->codecs[i];
3524
3525 if (!strcasecmp(imp->iananame, mimp->iananame) && imp->actual_samples_per_second == mimp->actual_samples_per_second) {
3526 *pt = smh->ianacodes[i];
3527
3528 return SWITCH_STATUS_SUCCESS;
3529 }
3530 }
3531
3532 return SWITCH_STATUS_FALSE;
3533 }
3534
3535 //#define get_int_value(_var, _set) { const char *__v = switch_channel_get_variable(session->channel, _var); if (__v) { _set = atol(__v);} }
3536 //?
switch_core_session_parse_codec_settings(switch_core_session_t * session,switch_media_type_t type)3537 static void switch_core_session_parse_codec_settings(switch_core_session_t *session, switch_media_type_t type)
3538 {
3539 switch_media_handle_t *smh;
3540 switch_rtp_engine_t *engine;
3541
3542 switch_assert(session);
3543
3544 if (!(smh = session->media_handle)) {
3545 return;
3546 }
3547
3548 if (!(engine = &smh->engines[type])) return;
3549
3550 switch(type) {
3551 case SWITCH_MEDIA_TYPE_AUDIO:
3552 break;
3553 case SWITCH_MEDIA_TYPE_VIDEO: {
3554 uint32_t system_bw = 0;
3555 const char *var = NULL, *bwv;
3556
3557 if ((var = switch_channel_get_variable(session->channel, "video_try_hardware_encoder"))) {
3558 engine->codec_settings.video.try_hardware_encoder = switch_true(var);
3559 }
3560
3561 if (!(bwv = switch_channel_get_variable(session->channel, "rtp_video_max_bandwidth"))) {
3562 bwv = switch_channel_get_variable(session->channel, "rtp_video_max_bandwidth_out");
3563 }
3564
3565 if (!bwv) {
3566 bwv = "1mb";
3567 }
3568
3569 system_bw = switch_parse_bandwidth_string(bwv);
3570
3571 if (engine->sdp_bw && engine->sdp_bw <= system_bw) {
3572 engine->codec_settings.video.bandwidth = engine->sdp_bw;
3573 } else {
3574 engine->codec_settings.video.bandwidth = system_bw;
3575 }
3576 }
3577 break;
3578 default:
3579 break;
3580 }
3581 }
3582
3583
3584 //?
switch_core_media_set_video_codec(switch_core_session_t * session,int force)3585 SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_codec(switch_core_session_t *session, int force)
3586 {
3587 switch_media_handle_t *smh;
3588 switch_rtp_engine_t *v_engine;
3589
3590 switch_assert(session);
3591
3592 if (!(smh = session->media_handle)) {
3593 return SWITCH_STATUS_FALSE;
3594 }
3595 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
3596
3597
3598 if (!v_engine->codec_negotiated) {
3599 return SWITCH_STATUS_FALSE;
3600 }
3601
3602 if (v_engine->read_codec.implementation && switch_core_codec_ready(&v_engine->read_codec)) {
3603 if (!force) {
3604 return SWITCH_STATUS_SUCCESS;
3605 }
3606 if (strcasecmp(v_engine->read_codec.implementation->iananame, v_engine->cur_payload_map->rm_encoding) ||
3607 v_engine->read_codec.implementation->samples_per_second != v_engine->cur_payload_map->rm_rate) {
3608
3609 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Changing Codec from %s to %s\n",
3610 v_engine->read_codec.implementation->iananame, v_engine->cur_payload_map->rm_encoding);
3611 switch_core_codec_destroy(&v_engine->read_codec);
3612 switch_core_codec_destroy(&v_engine->write_codec);
3613 } else {
3614 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Already using %s\n",
3615 v_engine->read_codec.implementation->iananame);
3616 return SWITCH_STATUS_SUCCESS;
3617 }
3618 }
3619
3620 switch_core_session_parse_codec_settings(session, SWITCH_MEDIA_TYPE_VIDEO);
3621
3622 if (switch_core_codec_init(&v_engine->read_codec,
3623 v_engine->cur_payload_map->rm_encoding,
3624 v_engine->cur_payload_map->modname,
3625 v_engine->cur_payload_map->rm_fmtp,
3626 v_engine->cur_payload_map->rm_rate,
3627 0,
3628 1,
3629 SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
3630 &v_engine->codec_settings, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
3631 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't load codec?\n");
3632 return SWITCH_STATUS_FALSE;
3633 } else {
3634 if (switch_core_codec_init(&v_engine->write_codec,
3635 v_engine->cur_payload_map->rm_encoding,
3636 v_engine->cur_payload_map->modname,
3637 v_engine->cur_payload_map->rm_fmtp,
3638 v_engine->cur_payload_map->rm_rate,
3639 0,
3640 1,
3641 SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
3642 &v_engine->codec_settings, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
3643 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't load codec?\n");
3644 return SWITCH_STATUS_FALSE;
3645 } else {
3646 v_engine->read_frame.rate = v_engine->cur_payload_map->rm_rate;
3647 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set VIDEO Codec %s %s/%ld %d ms\n",
3648 switch_channel_get_name(session->channel), v_engine->cur_payload_map->rm_encoding,
3649 v_engine->cur_payload_map->rm_rate, v_engine->cur_payload_map->codec_ms);
3650 v_engine->read_frame.codec = &v_engine->read_codec;
3651
3652 v_engine->write_codec.fmtp_out = switch_core_session_strdup(session, v_engine->write_codec.fmtp_out);
3653
3654 v_engine->write_codec.agreed_pt = v_engine->cur_payload_map->pt;
3655 v_engine->read_codec.agreed_pt = v_engine->cur_payload_map->pt;
3656 switch_core_session_set_video_read_codec(session, &v_engine->read_codec);
3657 switch_core_session_set_video_write_codec(session, &v_engine->write_codec);
3658
3659
3660 switch_channel_set_variable_printf(session->channel, "rtp_last_video_codec_string", "%s@%dh",
3661 v_engine->cur_payload_map->rm_encoding, v_engine->cur_payload_map->rm_rate);
3662
3663
3664 if (switch_rtp_ready(v_engine->rtp_session)) {
3665 switch_core_session_message_t msg = { 0 };
3666
3667 msg.from = __FILE__;
3668 msg.message_id = SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ;
3669
3670 switch_rtp_set_default_payload(v_engine->rtp_session, v_engine->cur_payload_map->pt);
3671
3672 //XX
3673
3674 switch_core_session_receive_message(session, &msg);
3675
3676
3677 }
3678
3679 switch_channel_set_variable(session->channel, "rtp_use_video_codec_name", v_engine->cur_payload_map->rm_encoding);
3680 switch_channel_set_variable(session->channel, "rtp_use_video_codec_fmtp", v_engine->cur_payload_map->rm_fmtp);
3681 switch_channel_set_variable_printf(session->channel, "rtp_use_video_codec_rate", "%d", v_engine->cur_payload_map->rm_rate);
3682 switch_channel_set_variable_printf(session->channel, "rtp_use_video_codec_ptime", "%d", 0);
3683 }
3684 }
3685 return SWITCH_STATUS_SUCCESS;
3686 }
3687
3688
3689 //?
switch_core_media_set_codec(switch_core_session_t * session,int force,uint32_t codec_flags)3690 SWITCH_DECLARE(switch_status_t) switch_core_media_set_codec(switch_core_session_t *session, int force, uint32_t codec_flags)
3691 {
3692 switch_status_t status = SWITCH_STATUS_SUCCESS;
3693 int resetting = 0;
3694 switch_media_handle_t *smh;
3695 switch_rtp_engine_t *a_engine;
3696
3697 switch_assert(session);
3698
3699 if (!(smh = session->media_handle)) {
3700 return SWITCH_STATUS_FALSE;
3701 }
3702 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
3703
3704 if (!a_engine->cur_payload_map->iananame) {
3705 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No audio codec available\n");
3706 switch_goto_status(SWITCH_STATUS_FALSE, end);
3707 }
3708
3709 if (switch_core_codec_ready(&a_engine->read_codec)) {
3710 if (!force) {
3711 switch_goto_status(SWITCH_STATUS_SUCCESS, end);
3712 }
3713
3714 if (strcasecmp(a_engine->read_impl.iananame, a_engine->cur_payload_map->iananame) ||
3715 (uint32_t) a_engine->read_impl.microseconds_per_packet / 1000 != a_engine->cur_payload_map->codec_ms ||
3716 a_engine->read_impl.samples_per_second != a_engine->cur_payload_map->rm_rate ) {
3717
3718 if (session->read_resampler) {
3719 switch_mutex_lock(session->resample_mutex);
3720 switch_resample_destroy(&session->read_resampler);
3721 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating read resampler\n");
3722 switch_mutex_unlock(session->resample_mutex);
3723 }
3724
3725 if (session->write_resampler) {
3726 switch_mutex_lock(session->resample_mutex);
3727 switch_resample_destroy(&session->write_resampler);
3728 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating write resampler\n");
3729 switch_mutex_unlock(session->resample_mutex);
3730 }
3731
3732 switch_core_session_reset(session, 0, 0);
3733 switch_channel_audio_sync(session->channel);
3734
3735 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
3736 "Changing Codec from %s@%dms@%dhz to %s@%dms@%luhz\n",
3737 a_engine->read_impl.iananame,
3738 a_engine->read_impl.microseconds_per_packet / 1000,
3739 a_engine->read_impl.actual_samples_per_second,
3740
3741 a_engine->cur_payload_map->iananame,
3742 a_engine->cur_payload_map->codec_ms,
3743 a_engine->cur_payload_map->rm_rate);
3744
3745 switch_yield(a_engine->read_impl.microseconds_per_packet);
3746 switch_core_session_lock_codec_write(session);
3747 switch_core_session_lock_codec_read(session);
3748 resetting = 1;
3749 switch_yield(a_engine->read_impl.microseconds_per_packet);
3750 switch_core_codec_destroy(&a_engine->read_codec);
3751 switch_core_codec_destroy(&a_engine->write_codec);
3752 switch_channel_audio_sync(session->channel);
3753 } else {
3754 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Already using %s\n", a_engine->read_impl.iananame);
3755 switch_goto_status(SWITCH_STATUS_SUCCESS, end);
3756 }
3757 }
3758
3759
3760 switch_core_session_parse_codec_settings(session, SWITCH_MEDIA_TYPE_AUDIO);
3761
3762 if (switch_core_codec_init_with_bitrate(&a_engine->read_codec,
3763 a_engine->cur_payload_map->iananame,
3764 a_engine->cur_payload_map->modname,
3765 a_engine->cur_payload_map->rm_fmtp,
3766 a_engine->cur_payload_map->rm_rate,
3767 a_engine->cur_payload_map->codec_ms,
3768 a_engine->cur_payload_map->channels,
3769 a_engine->cur_payload_map->bitrate,
3770 SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE | codec_flags,
3771 &a_engine->codec_settings, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
3772 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't load codec?\n");
3773 switch_channel_hangup(session->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
3774 switch_goto_status(SWITCH_STATUS_FALSE, end);
3775 }
3776
3777 a_engine->read_codec.session = session;
3778
3779
3780 if (switch_core_codec_init_with_bitrate(&a_engine->write_codec,
3781 a_engine->cur_payload_map->iananame,
3782 a_engine->cur_payload_map->modname,
3783 a_engine->cur_payload_map->rm_fmtp,
3784 a_engine->cur_payload_map->rm_rate,
3785 a_engine->cur_payload_map->codec_ms,
3786 a_engine->cur_payload_map->channels,
3787 a_engine->cur_payload_map->bitrate,
3788 SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE | codec_flags,
3789 &a_engine->codec_settings, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
3790 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't load codec?\n");
3791 switch_channel_hangup(session->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
3792 switch_goto_status(SWITCH_STATUS_FALSE, end);
3793 }
3794
3795 a_engine->write_codec.session = session;
3796
3797 if (switch_rtp_ready(a_engine->rtp_session)) {
3798 switch_channel_audio_sync(session->channel);
3799 switch_rtp_reset_jb(a_engine->rtp_session);
3800 }
3801
3802 switch_channel_set_variable(session->channel, "rtp_use_codec_name", a_engine->cur_payload_map->iananame);
3803 switch_channel_set_variable(session->channel, "rtp_use_codec_fmtp", a_engine->cur_payload_map->rm_fmtp);
3804 switch_channel_set_variable_printf(session->channel, "rtp_use_codec_rate", "%d", a_engine->cur_payload_map->rm_rate);
3805 switch_channel_set_variable_printf(session->channel, "rtp_use_codec_ptime", "%d", a_engine->cur_payload_map->codec_ms);
3806 switch_channel_set_variable_printf(session->channel, "rtp_use_codec_channels", "%d", a_engine->cur_payload_map->channels);
3807 switch_channel_set_variable_printf(session->channel, "rtp_last_audio_codec_string", "%s@%dh@%di@%dc",
3808 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);
3809
3810 switch_assert(a_engine->read_codec.implementation);
3811 switch_assert(a_engine->write_codec.implementation);
3812
3813 a_engine->read_impl = *a_engine->read_codec.implementation;
3814 a_engine->write_impl = *a_engine->write_codec.implementation;
3815
3816 switch_core_session_set_read_impl(session, a_engine->read_codec.implementation);
3817 switch_core_session_set_write_impl(session, a_engine->write_codec.implementation);
3818
3819 if (switch_rtp_ready(a_engine->rtp_session)) {
3820 switch_assert(a_engine->read_codec.implementation);
3821
3822 if (switch_rtp_change_interval(a_engine->rtp_session,
3823 a_engine->read_impl.microseconds_per_packet,
3824 a_engine->read_impl.samples_per_packet) != SWITCH_STATUS_SUCCESS) {
3825 switch_channel_hangup(session->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
3826 switch_goto_status(SWITCH_STATUS_FALSE, end);
3827 }
3828 }
3829
3830 a_engine->read_frame.rate = a_engine->cur_payload_map->rm_rate;
3831
3832 if (!switch_core_codec_ready(&a_engine->read_codec)) {
3833 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't load codec?\n");
3834 switch_goto_status(SWITCH_STATUS_FALSE, end);
3835 }
3836
3837 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",
3838 switch_channel_get_name(session->channel), a_engine->cur_payload_map->iananame, a_engine->cur_payload_map->rm_rate,
3839 a_engine->cur_payload_map->codec_ms,
3840 a_engine->read_impl.samples_per_packet, a_engine->read_impl.bits_per_second, a_engine->read_impl.number_of_channels);
3841 a_engine->read_frame.codec = &a_engine->read_codec;
3842 a_engine->read_frame.channels = a_engine->read_impl.number_of_channels;
3843 a_engine->write_codec.agreed_pt = a_engine->cur_payload_map->pt;
3844 a_engine->read_codec.agreed_pt = a_engine->cur_payload_map->pt;
3845
3846 if (force != 2) {
3847 switch_core_session_set_real_read_codec(session, &a_engine->read_codec);
3848 switch_core_session_set_write_codec(session, &a_engine->write_codec);
3849 }
3850
3851 a_engine->cur_payload_map->fmtp_out = switch_core_session_strdup(session, a_engine->write_codec.fmtp_out);
3852
3853 if (switch_rtp_ready(a_engine->rtp_session)) {
3854 switch_rtp_set_default_payload(a_engine->rtp_session, a_engine->cur_payload_map->pt);
3855 }
3856
3857 end:
3858
3859 if (resetting) {
3860 switch_core_session_unlock_codec_write(session);
3861 switch_core_session_unlock_codec_read(session);
3862 }
3863
3864 return status;
3865 }
clear_ice(switch_core_session_t * session,switch_media_type_t type)3866 static void clear_ice(switch_core_session_t *session, switch_media_type_t type)
3867 {
3868 switch_media_handle_t *smh;
3869 switch_rtp_engine_t *engine;
3870
3871 switch_assert(session);
3872
3873 if (!(smh = session->media_handle)) {
3874 return;
3875 }
3876
3877 engine = &smh->engines[type];
3878
3879 engine->ice_in.chosen[0] = 0;
3880 engine->ice_in.chosen[1] = 0;
3881 engine->ice_in.is_chosen[0] = 0;
3882 engine->ice_in.is_chosen[1] = 0;
3883 engine->ice_in.cand_idx[0] = 0;
3884 engine->ice_in.cand_idx[1] = 0;
3885 memset(&engine->ice_in, 0, sizeof(engine->ice_in));
3886 engine->remote_rtcp_port = 0;
3887
3888 if (engine->rtp_session) {
3889 switch_rtp_reset(engine->rtp_session);
3890 }
3891
3892 }
3893
3894 //?
switch_core_media_clear_ice(switch_core_session_t * session)3895 SWITCH_DECLARE(void) switch_core_media_clear_ice(switch_core_session_t *session)
3896 {
3897 clear_ice(session, SWITCH_MEDIA_TYPE_AUDIO);
3898 clear_ice(session, SWITCH_MEDIA_TYPE_VIDEO);
3899
3900 }
3901
switch_core_media_pause(switch_core_session_t * session)3902 SWITCH_DECLARE(void) switch_core_media_pause(switch_core_session_t *session)
3903 {
3904 switch_rtp_engine_t *a_engine, *v_engine, *t_engine;
3905 switch_media_handle_t *smh;
3906
3907 switch_assert(session);
3908
3909 if (!(smh = session->media_handle)) {
3910 return;
3911 }
3912
3913 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
3914 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
3915 t_engine = &smh->engines[SWITCH_MEDIA_TYPE_TEXT];
3916
3917 if (a_engine->rtp_session) {
3918 switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PAUSE);
3919 }
3920
3921 if (v_engine->rtp_session) {
3922 switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_PAUSE);
3923 }
3924
3925 if (t_engine->rtp_session) {
3926 switch_rtp_set_flag(t_engine->rtp_session, SWITCH_RTP_FLAG_PAUSE);
3927 }
3928 }
3929
switch_core_media_resume(switch_core_session_t * session)3930 SWITCH_DECLARE(void) switch_core_media_resume(switch_core_session_t *session)
3931 {
3932 switch_rtp_engine_t *a_engine, *v_engine, *t_engine;
3933 switch_media_handle_t *smh;
3934
3935 switch_assert(session);
3936
3937 if (!(smh = session->media_handle)) {
3938 return;
3939 }
3940
3941 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
3942 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
3943 t_engine = &smh->engines[SWITCH_MEDIA_TYPE_TEXT];
3944
3945 if (a_engine->rtp_session) {
3946 switch_rtp_clear_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PAUSE);
3947 }
3948
3949 if (v_engine->rtp_session) {
3950 switch_rtp_clear_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_PAUSE);
3951 }
3952
3953 if (t_engine->rtp_session) {
3954 switch_rtp_clear_flag(t_engine->rtp_session, SWITCH_RTP_FLAG_PAUSE);
3955 }
3956 }
3957
3958
3959 //?
switch_core_media_add_ice_acl(switch_core_session_t * session,switch_media_type_t type,const char * acl_name)3960 SWITCH_DECLARE(switch_status_t) switch_core_media_add_ice_acl(switch_core_session_t *session, switch_media_type_t type, const char *acl_name)
3961 {
3962 switch_media_handle_t *smh;
3963 switch_rtp_engine_t *engine;
3964
3965 switch_assert(session);
3966
3967 if (!(smh = session->media_handle)) {
3968 return SWITCH_STATUS_FALSE;
3969 }
3970
3971 engine = &smh->engines[type];
3972
3973 if (engine->cand_acl_count < SWITCH_MAX_CAND_ACL) {
3974 engine->cand_acl[engine->cand_acl_count++] = switch_core_session_strdup(session, acl_name);
3975 return SWITCH_STATUS_SUCCESS;
3976 }
3977
3978 return SWITCH_STATUS_FALSE;
3979 }
3980
3981 //?
switch_core_media_check_video_codecs(switch_core_session_t * session)3982 SWITCH_DECLARE(void) switch_core_media_check_video_codecs(switch_core_session_t *session)
3983 {
3984 switch_media_handle_t *smh;
3985
3986 switch_assert(session);
3987
3988 if (!(smh = session->media_handle)) {
3989 return;
3990 }
3991
3992 if (smh->mparams->num_codecs && !switch_channel_test_flag(session->channel, CF_VIDEO_POSSIBLE)) {
3993 int i;
3994 smh->video_count = 0;
3995 for (i = 0; i < smh->mparams->num_codecs; i++) {
3996
3997 if (smh->codecs[i]->codec_type == SWITCH_CODEC_TYPE_VIDEO) {
3998 if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_INBOUND &&
3999 switch_channel_test_flag(session->channel, CF_NOVIDEO)) {
4000 continue;
4001 }
4002 smh->video_count++;
4003 }
4004 }
4005 if (smh->video_count) {
4006 switch_channel_set_flag(session->channel, CF_VIDEO_POSSIBLE);
4007 }
4008 }
4009 }
4010
4011 //?
generate_local_fingerprint(switch_media_handle_t * smh,switch_media_type_t type)4012 static void generate_local_fingerprint(switch_media_handle_t *smh, switch_media_type_t type)
4013 {
4014 switch_rtp_engine_t *engine = &smh->engines[type];
4015
4016 if (!engine->local_dtls_fingerprint.len) {
4017 if (engine->remote_dtls_fingerprint.type) {
4018 engine->local_dtls_fingerprint.type = engine->remote_dtls_fingerprint.type;
4019 } else {
4020 engine->local_dtls_fingerprint.type = "sha-256";
4021 }
4022 switch_core_cert_gen_fingerprint(DTLS_SRTP_FNAME, &engine->local_dtls_fingerprint);
4023 }
4024 }
4025
4026 //?
dtls_ok(switch_core_session_t * session)4027 static int dtls_ok(switch_core_session_t *session)
4028 {
4029 return switch_channel_test_flag(session->channel, CF_DTLS_OK);
4030 }
4031
4032 #ifdef _MSC_VER
4033 /* remove this if the break is removed from the following for loop which causes unreachable code loop */
4034 /* for (i = 0; i < engine->cand_acl_count; i++) { */
4035 #pragma warning(push)
4036 #pragma warning(disable:4702)
4037 #endif
4038
4039 //?
switch_ice_direction(switch_rtp_engine_t * engine,switch_core_session_t * session)4040 static switch_call_direction_t switch_ice_direction(switch_rtp_engine_t *engine, switch_core_session_t *session)
4041 {
4042 switch_call_direction_t r = switch_channel_direction(session->channel);
4043 switch_media_handle_t *smh;
4044
4045 switch_assert(session);
4046
4047 if (!(smh = session->media_handle)) {
4048 return SWITCH_CALL_DIRECTION_OUTBOUND;
4049 }
4050
4051 if (switch_channel_test_flag(session->channel, CF_3PCC)) {
4052 r = (r == SWITCH_CALL_DIRECTION_INBOUND) ? SWITCH_CALL_DIRECTION_OUTBOUND : SWITCH_CALL_DIRECTION_INBOUND;
4053 }
4054
4055 if (switch_rtp_has_dtls() && dtls_ok(smh->session)) {
4056 r = engine->dtls_controller ? SWITCH_CALL_DIRECTION_INBOUND : SWITCH_CALL_DIRECTION_OUTBOUND;
4057 } else {
4058 if ((switch_channel_test_flag(session->channel, CF_REINVITE) || switch_channel_test_flag(session->channel, CF_RECOVERING))
4059 && switch_channel_test_flag(session->channel, CF_AVPF)) {
4060 r = SWITCH_CALL_DIRECTION_OUTBOUND;
4061 }
4062 }
4063
4064 return r;
4065 }
4066
switch_determine_ice_type(switch_rtp_engine_t * engine,switch_core_session_t * session)4067 static switch_core_media_ice_type_t switch_determine_ice_type(switch_rtp_engine_t *engine, switch_core_session_t *session) {
4068 switch_core_media_ice_type_t ice_type = ICE_VANILLA;
4069
4070 if (switch_channel_var_true(session->channel, "ice_lite")) {
4071 ice_type |= ICE_CONTROLLED;
4072 ice_type |= ICE_LITE;
4073 } else {
4074 switch_call_direction_t direction = switch_ice_direction(engine, session);
4075 if (direction == SWITCH_CALL_DIRECTION_INBOUND) {
4076 ice_type |= ICE_CONTROLLED;
4077 }
4078 }
4079
4080 return ice_type;
4081 }
4082
4083 //?
ip_choose_family(switch_media_handle_t * smh,const char * ip)4084 static switch_status_t ip_choose_family(switch_media_handle_t *smh, const char *ip)
4085 {
4086 switch_status_t status = SWITCH_STATUS_FALSE;
4087
4088 if (zstr(ip)) {
4089 return status;
4090 }
4091
4092 if (strchr(ip, ':')) {
4093 if (!zstr(smh->mparams->rtpip6)) {
4094 smh->mparams->rtpip = smh->mparams->rtpip6;
4095 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG, "%s choosing family v6\n",
4096 switch_channel_get_name(smh->session->channel));
4097 status = SWITCH_STATUS_SUCCESS;
4098 }
4099 } else {
4100 if (!zstr(smh->mparams->rtpip4)) {
4101 smh->mparams->rtpip = smh->mparams->rtpip4;
4102 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG, "%s choosing family v4\n",
4103 switch_channel_get_name(smh->session->channel));
4104 status = SWITCH_STATUS_SUCCESS;
4105 }
4106 }
4107
4108 return status;
4109 }
4110
4111 //?
ip_possible(switch_media_handle_t * smh,const char * ip)4112 static switch_bool_t ip_possible(switch_media_handle_t *smh, const char *ip)
4113 {
4114 switch_bool_t r = SWITCH_FALSE;
4115
4116 if (zstr(ip)) {
4117 return r;
4118 }
4119
4120 if (strchr(ip, ':')) {
4121 r = (switch_bool_t) !zstr(smh->mparams->rtpip6);
4122 } else {
4123 r = (switch_bool_t) !zstr(smh->mparams->rtpip4);
4124 }
4125
4126 return r;
4127 }
4128
4129 //?
check_ice(switch_media_handle_t * smh,switch_media_type_t type,sdp_session_t * sdp,sdp_media_t * m)4130 static switch_status_t check_ice(switch_media_handle_t *smh, switch_media_type_t type, sdp_session_t *sdp, sdp_media_t *m)
4131 {
4132 switch_rtp_engine_t *engine = &smh->engines[type];
4133 sdp_attribute_t *attr = NULL, *attrs[2] = { 0 };
4134 int i = 0, got_rtcp_mux = 0;
4135 const char *val;
4136 int ice_seen = 0, cid = 0, ai = 0, attr_idx = 0, cand_seen = 0, relay_ok = 0;
4137
4138 if (switch_true(switch_channel_get_variable_dup(smh->session->channel, "ignore_sdp_ice", SWITCH_FALSE, -1))) {
4139 return SWITCH_STATUS_BREAK;
4140 }
4141
4142 //if (engine->ice_in.is_chosen[0] && engine->ice_in.is_chosen[1]) {
4143 //return SWITCH_STATUS_SUCCESS;
4144 //}
4145
4146 engine->ice_in.chosen[0] = 0;
4147 engine->ice_in.chosen[1] = 0;
4148 engine->ice_in.is_chosen[0] = 0;
4149 engine->ice_in.is_chosen[1] = 0;
4150 engine->ice_in.cand_idx[0] = 0;
4151 engine->ice_in.cand_idx[1] = 0;
4152 engine->remote_ssrc = 0;
4153
4154 if (m) {
4155 attrs[0] = m->m_attributes;
4156 attrs[1] = sdp->sdp_attributes;
4157 } else {
4158 attrs[0] = sdp->sdp_attributes;
4159 }
4160
4161 for (attr_idx = 0; attr_idx < 2 && !(ice_seen && cand_seen); attr_idx++) {
4162 for (attr = attrs[attr_idx]; attr; attr = attr->a_next) {
4163 char *data;
4164 char *fields[32] = {0};
4165 int argc = 0, j = 0;
4166
4167 if (zstr(attr->a_name)) {
4168 continue;
4169 }
4170
4171 if (!strcasecmp(attr->a_name, "ice-ufrag")) {
4172 if (engine->ice_in.ufrag && !strcmp(engine->ice_in.ufrag, attr->a_value)) {
4173 engine->new_ice = 0;
4174 } else {
4175 engine->ice_in.ufrag = switch_core_session_strdup(smh->session, attr->a_value);
4176 engine->new_ice = 1;
4177 }
4178 ice_seen++;
4179 } else if (!strcasecmp(attr->a_name, "ice-pwd")) {
4180 if (!engine->ice_in.pwd || strcmp(engine->ice_in.pwd, attr->a_value)) {
4181 engine->ice_in.pwd = switch_core_session_strdup(smh->session, attr->a_value);
4182 }
4183 } else if (!strcasecmp(attr->a_name, "ice-options")) {
4184 engine->ice_in.options = switch_core_session_strdup(smh->session, attr->a_value);
4185 } else if (!strcasecmp(attr->a_name, "setup")) {
4186 if (!strcasecmp(attr->a_value, "passive") ||
4187 (!strcasecmp(attr->a_value, "actpass") && !switch_channel_test_flag(smh->session->channel, CF_REINVITE))) {
4188 if (!engine->dtls_controller) {
4189 engine->new_dtls = 1;
4190 engine->new_ice = 1;
4191 }
4192 engine->dtls_controller = 1;
4193 } else if (!strcasecmp(attr->a_value, "active")) {
4194 if (engine->dtls_controller) {
4195 engine->new_dtls = 1;
4196 engine->new_ice = 1;
4197 }
4198 engine->dtls_controller = 0;
4199 }
4200 } else if (switch_rtp_has_dtls() && dtls_ok(smh->session) && !strcasecmp(attr->a_name, "fingerprint") && !zstr(attr->a_value)) {
4201 char *p;
4202
4203 engine->remote_dtls_fingerprint.type = switch_core_session_strdup(smh->session, attr->a_value);
4204
4205 if ((p = strchr(engine->remote_dtls_fingerprint.type, ' '))) {
4206 *p++ = '\0';
4207
4208 if (switch_channel_test_flag(smh->session->channel, CF_REINVITE) && !switch_channel_test_flag(smh->session->channel, CF_RECOVERING) &&
4209 !zstr(engine->remote_dtls_fingerprint.str) && !strcmp(engine->remote_dtls_fingerprint.str, p)) {
4210 engine->new_dtls = 0;
4211 } else {
4212 switch_set_string(engine->remote_dtls_fingerprint.str, p);
4213 engine->new_dtls = 1;
4214 engine->new_ice = 1;
4215 }
4216 }
4217
4218
4219 //if (strcasecmp(engine->remote_dtls_fingerprint.type, "sha-256")) {
4220 // switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_WARNING, "Unsupported fingerprint type.\n");
4221 //engine->local_dtls_fingerprint.type = NULL;
4222 //engine->remote_dtls_fingerprint.type = NULL;
4223 //}
4224
4225
4226 generate_local_fingerprint(smh, type);
4227 switch_channel_set_flag(smh->session->channel, CF_DTLS);
4228
4229 } else if (!engine->remote_ssrc && !strcasecmp(attr->a_name, "ssrc") && attr->a_value) {
4230 engine->remote_ssrc = (uint32_t) atol(attr->a_value);
4231
4232 if (engine->rtp_session && engine->remote_ssrc) {
4233 switch_rtp_set_remote_ssrc(engine->rtp_session, engine->remote_ssrc);
4234 }
4235
4236
4237 #ifdef RTCP_MUX
4238 } else if (!strcasecmp(attr->a_name, "rtcp-mux")) {
4239 engine->rtcp_mux = SWITCH_TRUE;
4240 engine->remote_rtcp_port = engine->cur_payload_map->remote_sdp_port;
4241 got_rtcp_mux++;
4242
4243 if (!smh->mparams->rtcp_audio_interval_msec) {
4244 smh->mparams->rtcp_audio_interval_msec = SWITCH_RTCP_AUDIO_INTERVAL_MSEC;
4245 }
4246 #endif
4247 } else if (!strcasecmp(attr->a_name, "candidate")) {
4248 switch_channel_set_flag(smh->session->channel, CF_ICE);
4249
4250 if (!engine->cand_acl_count) {
4251 engine->cand_acl[engine->cand_acl_count++] = "wan.auto";
4252 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_WARNING, "NO candidate ACL defined, Defaulting to wan.auto\n");
4253 }
4254
4255
4256 if (!switch_stristr(" udp ", attr->a_value)) {
4257 continue;
4258 }
4259
4260 data = switch_core_session_strdup(smh->session, attr->a_value);
4261
4262 argc = switch_split(data, ' ', fields);
4263
4264 cid = fields[1] ? atoi(fields[1]) - 1 : 0;
4265
4266 if (argc < 6 || engine->ice_in.cand_idx[cid] >= MAX_CAND - 1) {
4267 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_WARNING, "Invalid data\n");
4268 continue;
4269 }
4270
4271 for (i = 0; i < argc; i++) {
4272 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG1, "CAND %d [%s]\n", i, fields[i]);
4273 }
4274
4275 if (!ip_possible(smh, fields[4])) {
4276 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG,
4277 "Drop %s Candidate cid: %d proto: %s type: %s addr: %s:%s (no network path)\n",
4278 type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio",
4279 cid+1, fields[2], fields[7] ? fields[7] : "N/A", fields[4], fields[5]);
4280 continue;
4281 } else {
4282 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG,
4283 "Save %s Candidate cid: %d proto: %s type: %s addr: %s:%s\n",
4284 type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio",
4285 cid+1, fields[2], fields[7] ? fields[7] : "N/A", fields[4], fields[5]);
4286 }
4287
4288
4289 engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].foundation = switch_core_session_strdup(smh->session, fields[0]);
4290 engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].component_id = atoi(fields[1]);
4291 engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].transport = switch_core_session_strdup(smh->session, fields[2]);
4292 engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].priority = atol(fields[3]);
4293 engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].con_addr = switch_core_session_strdup(smh->session, fields[4]);
4294 engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].con_port = (switch_port_t)atoi(fields[5]);
4295
4296 j = 6;
4297
4298 while(j < argc && j <= sizeof(fields)/sizeof(char*) && fields[j+1] && engine->ice_in.cand_idx[cid] < MAX_CAND - 1) {
4299 if (!strcasecmp(fields[j], "typ")) {
4300 engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].cand_type = switch_core_session_strdup(smh->session, fields[j+1]);
4301 } else if (!strcasecmp(fields[j], "raddr")) {
4302 engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].raddr = switch_core_session_strdup(smh->session, fields[j+1]);
4303 } else if (!strcasecmp(fields[j], "rport")) {
4304 engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].rport = (switch_port_t)atoi(fields[j+1]);
4305 } else if (!strcasecmp(fields[j], "generation")) {
4306 engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].generation = switch_core_session_strdup(smh->session, fields[j+1]);
4307 }
4308
4309 j += 2;
4310 }
4311
4312 cand_seen++;
4313 engine->ice_in.cand_idx[cid]++;
4314 }
4315 }
4316 }
4317
4318 if (!ice_seen) {
4319 return SWITCH_STATUS_SUCCESS;
4320 }
4321
4322 relay_ok = 0;
4323
4324 relay:
4325
4326 for (cid = 0; cid < 2; cid++) {
4327 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG, "Searching for %s candidate.\n", cid ? "rtcp" : "rtp");
4328
4329 for (ai = 0; ai < engine->cand_acl_count; ai++) {
4330 for (i = 0; i < engine->ice_in.cand_idx[cid]; i++) {
4331 int is_relay = engine->ice_in.cands[i][cid].cand_type && !strcmp(engine->ice_in.cands[i][cid].cand_type, "relay");
4332
4333 if (relay_ok != is_relay) continue;
4334
4335 if (switch_check_network_list_ip(engine->ice_in.cands[i][cid].con_addr, engine->cand_acl[ai])) {
4336 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG,
4337 "Choose %s candidate, index %d, %s:%d\n", cid ? "rtcp" : "rtp", i,
4338 engine->ice_in.cands[i][cid].con_addr, engine->ice_in.cands[i][cid].con_port);
4339
4340 engine->ice_in.chosen[cid] = i;
4341 engine->ice_in.is_chosen[cid] = 1;
4342 engine->ice_in.cands[i][cid].ready++;
4343 ip_choose_family(smh, engine->ice_in.cands[i][cid].con_addr);
4344
4345 if (cid == 0 && got_rtcp_mux && engine->ice_in.cand_idx[1] < MAX_CAND) {
4346
4347 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG,
4348 "Choose same candidate, index %d, for rtcp based on rtcp-mux attribute %s:%d\n", engine->ice_in.cand_idx[1],
4349 engine->ice_in.cands[i][cid].con_addr, engine->ice_in.cands[i][cid].con_port);
4350
4351
4352 engine->ice_in.cands[engine->ice_in.cand_idx[1]][1] = engine->ice_in.cands[i][0];
4353 engine->ice_in.chosen[1] = engine->ice_in.cand_idx[1];
4354 engine->ice_in.is_chosen[1] = 1;
4355 engine->ice_in.cand_idx[1]++;
4356
4357 goto done_choosing;
4358 }
4359
4360 goto next_cid;
4361 }
4362 }
4363 }
4364
4365 next_cid:
4366
4367 continue;
4368 }
4369
4370 done_choosing:
4371
4372 if (!engine->ice_in.is_chosen[0]) {
4373 if (!relay_ok) {
4374 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG, "Look for Relay Candidates as last resort\n");
4375 relay_ok = 1;
4376 goto relay;
4377 }
4378
4379 /* PUNT */
4380 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG, "%s no suitable candidates found.\n",
4381 switch_channel_get_name(smh->session->channel));
4382 return SWITCH_STATUS_FALSE;
4383 }
4384
4385 for (i = 0; i < 2; i++) {
4386 if (engine->ice_in.cands[engine->ice_in.chosen[i]][i].ready) {
4387 if (zstr(engine->ice_in.ufrag) || zstr(engine->ice_in.pwd)) {
4388 engine->ice_in.cands[engine->ice_in.chosen[i]][i].ready = 0;
4389 }
4390 }
4391 }
4392
4393
4394 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) {
4395 char tmp[80] = "";
4396 const char *media_varname = NULL, *port_varname = NULL;
4397
4398 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);
4399 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG,
4400 "setting remote %s ice addr to index %d %s:%d based on candidate\n", type2str(type), engine->ice_in.chosen[0],
4401 engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr, engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port);
4402 engine->ice_in.cands[engine->ice_in.chosen[0]][0].ready++;
4403
4404 engine->remote_rtp_ice_port = (switch_port_t) engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port;
4405 engine->remote_rtp_ice_addr = switch_core_session_strdup(smh->session, engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr);
4406
4407 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);
4408 engine->cur_payload_map->remote_sdp_port = (switch_port_t) engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port;
4409
4410 if (!smh->mparams->remote_ip) {
4411 smh->mparams->remote_ip = engine->cur_payload_map->remote_sdp_ip;
4412 }
4413
4414 if (engine->type == SWITCH_MEDIA_TYPE_VIDEO) {
4415 media_varname = "remote_video_ip";
4416 port_varname = "remote_video_port";
4417 } else if (engine->type == SWITCH_MEDIA_TYPE_AUDIO) {
4418 media_varname = "remote_audio_ip";
4419 port_varname = "remote_audio_port";
4420 } else if (engine->type == SWITCH_MEDIA_TYPE_TEXT) {
4421 media_varname = "remote_text_ip";
4422 port_varname = "remote_text_port";
4423 }
4424
4425 switch_snprintf(tmp, sizeof(tmp), "%d", engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port);
4426 switch_channel_set_variable(smh->session->channel, media_varname, engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr);
4427 switch_channel_set_variable(smh->session->channel, port_varname, tmp);
4428 }
4429
4430 if (engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port) {
4431 const char *media_varname = NULL, *port_varname = NULL;
4432 char tmp[35] = "";
4433
4434 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG,
4435 "Setting remote rtcp %s addr to %s:%d based on candidate\n", type2str(type),
4436 engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_addr, engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port);
4437 engine->remote_rtcp_ice_port = engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port;
4438 engine->remote_rtcp_ice_addr = switch_core_session_strdup(smh->session, engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_addr);
4439
4440 engine->remote_rtcp_port = engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port;
4441
4442
4443 if (engine->type == SWITCH_MEDIA_TYPE_VIDEO) {
4444 media_varname = "remote_video_rtcp_ip";
4445 port_varname = "remote_video_rtcp_port";
4446 } else if (engine->type == SWITCH_MEDIA_TYPE_AUDIO) {
4447 media_varname = "remote_audio_rtcp_ip";
4448 port_varname = "remote_audio_rtcp_port";
4449 } else if (engine->type == SWITCH_MEDIA_TYPE_TEXT) {
4450 media_varname = "remote_text_rtcp_ip";
4451 port_varname = "remote_text_rtcp_port";
4452 }
4453
4454 switch_snprintf(tmp, sizeof(tmp), "%d", engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port);
4455 switch_channel_set_variable(smh->session->channel, media_varname, engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_addr);
4456 switch_channel_set_variable(smh->session->channel, port_varname, tmp);
4457
4458 }
4459
4460
4461 if (m && !got_rtcp_mux) {
4462 engine->rtcp_mux = -1;
4463 }
4464
4465 if (engine->new_ice) {
4466 if (switch_rtp_ready(engine->rtp_session) && engine->ice_in.cands[engine->ice_in.chosen[0]][0].ready) {
4467 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_INFO, "RE-Activating %s ICE\n", type2str(type));
4468
4469 switch_rtp_activate_ice(engine->rtp_session,
4470 engine->ice_in.ufrag,
4471 engine->ice_out.ufrag,
4472 engine->ice_out.pwd,
4473 engine->ice_in.pwd,
4474 IPR_RTP,
4475 #ifdef GOOGLE_ICE
4476 ICE_GOOGLE_JINGLE,
4477 NULL
4478 #else
4479 switch_determine_ice_type(engine, smh->session),
4480 &engine->ice_in
4481 #endif
4482 );
4483
4484
4485 engine->new_ice = 0;
4486 }
4487
4488
4489 if (engine->rtp_session && ((val = switch_channel_get_variable(smh->session->channel,
4490 type == SWITCH_MEDIA_TYPE_VIDEO ?
4491 "rtcp_video_interval_msec" : "rtcp_audio_interval_msec"))
4492 || (val = type == SWITCH_MEDIA_TYPE_VIDEO ?
4493 smh->mparams->rtcp_video_interval_msec : smh->mparams->rtcp_audio_interval_msec))) {
4494
4495 switch_port_t remote_rtcp_port = engine->remote_rtcp_port;
4496
4497 if (remote_rtcp_port) {
4498 if (!strcasecmp(val, "passthru")) {
4499 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_INFO, "Activating %s RTCP PASSTHRU PORT %d\n",
4500 type2str(type), remote_rtcp_port);
4501 switch_rtp_activate_rtcp(engine->rtp_session, -1, remote_rtcp_port, engine->rtcp_mux > 0);
4502 } else {
4503 int interval = atoi(val);
4504 if (interval < 100 || interval > 500000) {
4505 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_ERROR,
4506 "Invalid rtcp interval spec [%d] must be between 100 and 500000\n", interval);
4507 interval = 5000;
4508 }
4509
4510 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_INFO, "Activating %s RTCP PORT %d\n", type2str(type), remote_rtcp_port);
4511 switch_rtp_activate_rtcp(engine->rtp_session, interval, remote_rtcp_port, engine->rtcp_mux > 0);
4512 }
4513 }
4514 }
4515
4516 if (engine->rtp_session && engine->ice_in.cands[engine->ice_in.chosen[1]][1].ready) {
4517 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)
4518 && engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port == engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port) {
4519 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_INFO, "Skipping %s RTCP ICE (Same as RTP)\n", type2str(type));
4520 } else {
4521 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_INFO, "Activating %s RTCP ICE\n", type2str(type));
4522
4523 switch_rtp_activate_ice(engine->rtp_session,
4524 engine->ice_in.ufrag,
4525 engine->ice_out.ufrag,
4526 engine->ice_out.pwd,
4527 engine->ice_in.pwd,
4528 IPR_RTCP,
4529 #ifdef GOOGLE_ICE
4530 ICE_GOOGLE_JINGLE,
4531 NULL
4532 #else
4533 switch_determine_ice_type(engine, smh->session),
4534 &engine->ice_in
4535 #endif
4536 );
4537 }
4538
4539 }
4540
4541 }
4542
4543 return ice_seen ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_BREAK;
4544 }
4545 #ifdef _MSC_VER
4546 #pragma warning(pop)
4547 #endif
4548
switch_core_session_set_ice(switch_core_session_t * session)4549 SWITCH_DECLARE(void) switch_core_session_set_ice(switch_core_session_t *session)
4550 {
4551 switch_media_handle_t *smh;
4552
4553 switch_assert(session);
4554
4555 if (!(smh = session->media_handle)) {
4556 return;
4557 }
4558
4559 switch_channel_set_flag(session->channel, CF_VERBOSE_SDP);
4560 switch_channel_set_flag(session->channel, CF_AVPF);
4561 switch_channel_set_flag(session->channel, CF_ICE);
4562 smh->mparams->rtcp_audio_interval_msec = SWITCH_RTCP_AUDIO_INTERVAL_MSEC;
4563 smh->mparams->rtcp_video_interval_msec = SWITCH_RTCP_VIDEO_INTERVAL_MSEC;
4564
4565 }
4566
4567 #define MAX_MATCHES 30
4568 struct matches {
4569 const switch_codec_implementation_t *imp;
4570 sdp_rtpmap_t *map;
4571 int rate;
4572 int codec_idx;
4573 };
4574
greedy_sort(switch_media_handle_t * smh,struct matches * matches,int m_idx,const switch_codec_implementation_t ** codec_array,int total_codecs)4575 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)
4576 {
4577 int j = 0, f = 0, g;
4578 struct matches mtmp[MAX_MATCHES] = { { 0 } };
4579 for(j = 0; j < m_idx; j++) {
4580 *&mtmp[j] = *&matches[j];
4581 }
4582 for (g = 0; g < smh->mparams->num_codecs && g < total_codecs; g++) {
4583 const switch_codec_implementation_t *imp = codec_array[g];
4584
4585 for(j = 0; j < m_idx; j++) {
4586 if (mtmp[j].imp == imp) {
4587 *&matches[f++] = *&mtmp[j];
4588 }
4589 }
4590 }
4591 }
4592
clear_pmaps(switch_rtp_engine_t * engine)4593 static void clear_pmaps(switch_rtp_engine_t *engine)
4594 {
4595 payload_map_t *pmap;
4596
4597 for (pmap = engine->payload_map; pmap && pmap->allocated; pmap = pmap->next) {
4598 pmap->negotiated = 0;
4599 pmap->current = 0;
4600 }
4601 }
4602
restore_pmaps(switch_rtp_engine_t * engine)4603 static void restore_pmaps(switch_rtp_engine_t *engine)
4604 {
4605 payload_map_t *pmap;
4606 int top = 0;
4607
4608 for (pmap = engine->payload_map; pmap && pmap->allocated; pmap = pmap->next) {
4609 pmap->negotiated = 1;
4610 if (!top++) pmap->current = 1;
4611 }
4612 }
4613
media_flow_varname(switch_media_type_t type)4614 static const char *media_flow_varname(switch_media_type_t type)
4615 {
4616 const char *varname = "invalid";
4617
4618 switch(type) {
4619 case SWITCH_MEDIA_TYPE_AUDIO:
4620 varname = "audio_media_flow";
4621 break;
4622 case SWITCH_MEDIA_TYPE_VIDEO:
4623 varname = "video_media_flow";
4624 break;
4625 case SWITCH_MEDIA_TYPE_TEXT:
4626 varname = "text_media_flow";
4627 break;
4628 }
4629
4630 return varname;
4631 }
4632
remote_media_flow_varname(switch_media_type_t type)4633 static const char *remote_media_flow_varname(switch_media_type_t type)
4634 {
4635 const char *varname = "invalid";
4636
4637 switch(type) {
4638 case SWITCH_MEDIA_TYPE_AUDIO:
4639 varname = "remote_audio_media_flow";
4640 break;
4641 case SWITCH_MEDIA_TYPE_VIDEO:
4642 varname = "remote_video_media_flow";
4643 break;
4644 case SWITCH_MEDIA_TYPE_TEXT:
4645 varname = "remote_text_media_flow";
4646 break;
4647 }
4648
4649 return varname;
4650 }
4651
media_flow_get_mode(switch_media_flow_t smode,const char ** mode_str,switch_media_flow_t * opp_mode)4652 static void media_flow_get_mode(switch_media_flow_t smode, const char **mode_str, switch_media_flow_t *opp_mode)
4653 {
4654 const char *smode_str = "";
4655 switch_media_flow_t opp_smode = smode;
4656
4657 switch(smode) {
4658 case SWITCH_MEDIA_FLOW_SENDONLY:
4659 opp_smode = SWITCH_MEDIA_FLOW_RECVONLY;
4660 smode_str = "sendonly";
4661 break;
4662 case SWITCH_MEDIA_FLOW_RECVONLY:
4663 opp_smode = SWITCH_MEDIA_FLOW_SENDONLY;
4664 smode_str = "recvonly";
4665 break;
4666 case SWITCH_MEDIA_FLOW_INACTIVE:
4667 smode_str = "inactive";
4668 break;
4669 case SWITCH_MEDIA_FLOW_DISABLED:
4670 smode_str = "disabled";
4671 break;
4672 case SWITCH_MEDIA_FLOW_SENDRECV:
4673 smode_str = "sendrecv";
4674 break;
4675 }
4676
4677 *mode_str = smode_str;
4678 *opp_mode = opp_smode;
4679
4680 }
4681
check_stream_changes(switch_core_session_t * session,const char * r_sdp,switch_sdp_type_t sdp_type)4682 static void check_stream_changes(switch_core_session_t *session, const char *r_sdp, switch_sdp_type_t sdp_type)
4683 {
4684 switch_core_session_t *other_session = NULL;
4685 switch_core_session_message_t *msg;
4686
4687 switch_core_session_get_partner(session, &other_session);
4688
4689
4690 if (switch_channel_test_flag(session->channel, CF_STREAM_CHANGED)) {
4691 switch_channel_clear_flag(session->channel, CF_STREAM_CHANGED);
4692
4693 if (other_session) {
4694 switch_channel_set_flag(other_session->channel, CF_PROCESSING_STREAM_CHANGE);
4695 switch_channel_set_flag(session->channel, CF_AWAITING_STREAM_CHANGE);
4696
4697 if (sdp_type == SDP_TYPE_REQUEST && r_sdp) {
4698 const char *filter_codec_string = switch_channel_get_variable(session->channel, "filter_codec_string");
4699
4700 switch_channel_set_variable(session->channel, "codec_string", NULL);
4701 switch_core_media_merge_sdp_codec_string(session, r_sdp, sdp_type, filter_codec_string);
4702 }
4703
4704 if (switch_channel_test_flag(session->channel, CF_SECURE)) {
4705 other_session->media_handle->crypto_mode = session->media_handle->crypto_mode;
4706 switch_core_session_check_outgoing_crypto(other_session);
4707 }
4708
4709 msg = switch_core_session_alloc(other_session, sizeof(*msg));
4710 msg->message_id = SWITCH_MESSAGE_INDICATE_MEDIA_RENEG;
4711 msg->string_arg = switch_core_session_sprintf(other_session, "=%s", switch_channel_get_variable(session->channel, "ep_codec_string"));
4712 msg->from = __FILE__;
4713 switch_core_session_queue_message(other_session, msg);
4714 }
4715 }
4716
4717 if (other_session) {
4718 if (sdp_type == SDP_TYPE_RESPONSE && switch_channel_test_flag(session->channel, CF_PROCESSING_STREAM_CHANGE)) {
4719 switch_channel_clear_flag(session->channel, CF_PROCESSING_STREAM_CHANGE);
4720
4721 if (switch_channel_test_flag(other_session->channel, CF_AWAITING_STREAM_CHANGE)) {
4722 uint8_t proceed = 1;
4723 const char *sdp_in, *other_ep;
4724
4725 if ((other_ep = switch_channel_get_variable(session->channel, "ep_codec_string"))) {
4726 switch_channel_set_variable(other_session->channel, "codec_string", other_ep);
4727 }
4728
4729 sdp_in = switch_channel_get_variable(other_session->channel, SWITCH_R_SDP_VARIABLE);
4730 switch_core_media_negotiate_sdp(other_session, sdp_in, &proceed, SDP_TYPE_REQUEST);
4731 switch_core_media_activate_rtp(other_session);
4732 msg = switch_core_session_alloc(other_session, sizeof(*msg));
4733 msg->message_id = SWITCH_MESSAGE_INDICATE_RESPOND;
4734 msg->from = __FILE__;
4735
4736 switch_channel_set_flag(other_session->channel, CF_AWAITING_STREAM_CHANGE);
4737 switch_core_session_queue_message(other_session, msg);
4738 }
4739 }
4740
4741 switch_core_session_rwunlock(other_session);
4742 }
4743 }
4744
switch_core_media_set_smode(switch_core_session_t * session,switch_media_type_t type,switch_media_flow_t smode,switch_sdp_type_t sdp_type)4745 SWITCH_DECLARE(void) switch_core_media_set_smode(switch_core_session_t *session, switch_media_type_t type, switch_media_flow_t smode, switch_sdp_type_t sdp_type)
4746 {
4747 switch_media_handle_t *smh;
4748 switch_rtp_engine_t *engine;
4749 const char *varname = NULL, *smode_str = NULL;
4750 switch_media_flow_t old_smode, opp_smode = smode;
4751 switch_core_session_t *other_session;
4752 int pass_codecs = 0;
4753
4754 if (!(smh = session->media_handle)) {
4755 return;
4756 }
4757
4758 engine = &smh->engines[type];
4759
4760 varname = media_flow_varname(type);
4761
4762 media_flow_get_mode(smode, &smode_str, &opp_smode);
4763
4764 old_smode = engine->smode;
4765
4766 engine->smode = smode;
4767
4768 switch_channel_set_variable(session->channel, varname, smode_str);
4769
4770 if (switch_channel_var_true(session->channel, "rtp_pass_codecs_on_reinvite") || engine->pass_codecs) {
4771 pass_codecs = 1;
4772 }
4773
4774 engine->pass_codecs = 0;
4775
4776 if (switch_channel_var_true(session->channel, "rtp_pass_codecs_on_stream_change")) {
4777 if (sdp_type == SDP_TYPE_REQUEST && switch_channel_test_flag(session->channel, CF_REINVITE) &&
4778 switch_channel_media_up(session->channel) && (pass_codecs || old_smode != smode)) {
4779
4780 if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
4781 switch_core_media_set_smode(other_session, type, opp_smode, SDP_TYPE_REQUEST);
4782 switch_channel_set_flag(session->channel, CF_STREAM_CHANGED);
4783 switch_core_session_rwunlock(other_session);
4784 }
4785 }
4786 }
4787 }
4788
switch_core_media_set_rmode(switch_core_session_t * session,switch_media_type_t type,switch_media_flow_t rmode,switch_sdp_type_t sdp_type)4789 static void switch_core_media_set_rmode(switch_core_session_t *session, switch_media_type_t type, switch_media_flow_t rmode, switch_sdp_type_t sdp_type)
4790 {
4791 switch_media_handle_t *smh;
4792 switch_rtp_engine_t *engine;
4793 const char *varname = NULL, *rmode_str = NULL;
4794 switch_media_flow_t opp_rmode = rmode;
4795 switch_core_session_t *other_session = NULL;
4796
4797 if (!(smh = session->media_handle)) {
4798 return;
4799 }
4800
4801 engine = &smh->engines[type];
4802
4803 varname = remote_media_flow_varname(type);
4804 media_flow_get_mode(rmode, &rmode_str, &opp_rmode);
4805
4806 if (engine->rmode != rmode) {
4807 engine->pass_codecs = 1;
4808 }
4809
4810 engine->rmode = rmode;
4811
4812 if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
4813
4814 if (!switch_channel_media_up(session->channel) && sdp_type == SDP_TYPE_REQUEST) {
4815 engine->rmode = switch_core_session_remote_media_flow(other_session, type);
4816
4817 media_flow_get_mode(engine->rmode, &rmode_str, &opp_rmode);
4818 } else if (sdp_type == SDP_TYPE_RESPONSE && (switch_channel_test_flag(other_session->channel, CF_REINVITE) || switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND)) {
4819 switch_core_media_set_smode(other_session, type, rmode, sdp_type);
4820 }
4821
4822 switch_core_session_rwunlock(other_session);
4823 }
4824
4825 switch_channel_set_variable(session->channel, varname, rmode_str);
4826 }
4827
4828 //?
switch_core_media_negotiate_sdp(switch_core_session_t * session,const char * r_sdp,uint8_t * proceed,switch_sdp_type_t sdp_type)4829 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)
4830 {
4831 uint8_t match = 0, vmatch = 0, almost_vmatch = 0, tmatch = 0, fmatch = 0;
4832 switch_payload_t best_te = 0, cng_pt = 0;
4833 unsigned long best_te_rate = 8000, cng_rate = 8000;
4834 sdp_media_t *m;
4835 sdp_attribute_t *attr;
4836 int ptime = 0, dptime = 0, maxptime = 0, dmaxptime = 0;
4837 int sendonly = 0, recvonly = 0, inactive = 0;
4838 int greedy = 0, x = 0, skip = 0;
4839 switch_channel_t *channel = switch_core_session_get_channel(session);
4840 const char *val;
4841 const char *crypto = NULL;
4842 int got_crypto = 0, got_video_crypto = 0, got_audio = 0, saw_audio = 0, saw_video = 0, got_avp = 0, got_video_avp = 0, got_video_savp = 0, got_savp = 0, got_udptl = 0, got_webrtc = 0, got_text = 0, got_text_crypto = 0, got_msrp = 0;
4843 int scrooge = 0;
4844 sdp_parser_t *parser = NULL;
4845 sdp_session_t *sdp;
4846 const switch_codec_implementation_t **codec_array;
4847 int total_codecs;
4848 switch_rtp_engine_t *a_engine, *v_engine, *t_engine;
4849 switch_media_handle_t *smh;
4850 uint32_t near_rate = 0;
4851 const switch_codec_implementation_t *mimp = NULL, *near_match = NULL;
4852 sdp_rtpmap_t *mmap = NULL, *near_map = NULL;
4853 struct matches matches[MAX_MATCHES] = { { 0 } };
4854 struct matches near_matches[MAX_MATCHES] = { { 0 } };
4855 int codec_ms = 0;
4856 uint32_t remote_codec_rate = 0, fmtp_remote_codec_rate = 0;
4857 const char *tmp;
4858 int m_idx = 0, skip_rtcp = 0, skip_video_rtcp = 0, got_rtcp_mux = 0, got_video_rtcp_mux = 0;
4859 int nm_idx = 0;
4860 int vmatch_pt = 1, consider_video_fmtp = 1;
4861 int rtcp_auto_audio = 0, rtcp_auto_video = 0;
4862 int got_audio_rtcp = 0, got_video_rtcp = 0;
4863 switch_port_t audio_port = 0, video_port = 0;
4864
4865 switch_assert(session);
4866
4867 if (!r_sdp) {
4868 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Tried to negotiate a blank SDP?\n");
4869 return 0;
4870 }
4871
4872 if (!(smh = session->media_handle)) {
4873 return 0;
4874 }
4875
4876 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
4877 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
4878 t_engine = &smh->engines[SWITCH_MEDIA_TYPE_TEXT];
4879
4880 smh->mparams->num_codecs = 0;
4881 smh->num_negotiated_codecs = 0;
4882 switch_core_media_prepare_codecs(session, SWITCH_TRUE);
4883 codec_array = smh->codecs;
4884 total_codecs = smh->mparams->num_codecs;
4885
4886 if (!(parser = sdp_parse(NULL, r_sdp, (int) strlen(r_sdp), 0))) {
4887 return 0;
4888 }
4889
4890 if (!(sdp = sdp_session(parser))) {
4891 sdp_parser_free(parser);
4892 return 0;
4893 }
4894
4895 switch_channel_clear_flag(channel, CF_AUDIO_PAUSE_READ);
4896 switch_channel_clear_flag(channel, CF_AUDIO_PAUSE_WRITE);
4897
4898 if (dtls_ok(session) && (tmp = switch_channel_get_variable(smh->session->channel, "webrtc_enable_dtls")) && switch_false(tmp)) {
4899 switch_channel_clear_flag(smh->session->channel, CF_DTLS_OK);
4900 switch_channel_clear_flag(smh->session->channel, CF_DTLS);
4901 }
4902
4903 if (switch_true(switch_channel_get_variable_dup(session->channel, "rtp_assume_rtcp", SWITCH_FALSE, -1))) {
4904 rtcp_auto_video = 1;
4905 rtcp_auto_audio = 1;
4906 }
4907
4908 v_engine->new_dtls = 1;
4909 v_engine->new_ice = 1;
4910 a_engine->new_dtls = 1;
4911 a_engine->new_ice = 1;
4912 a_engine->reject_avp = 0;
4913
4914 switch_media_handle_set_media_flag(smh, SCMF_RECV_SDP);
4915
4916 switch_core_session_parse_crypto_prefs(session);
4917
4918 clear_pmaps(a_engine);
4919 clear_pmaps(v_engine);
4920
4921 if (proceed) *proceed = 1;
4922
4923 greedy = !!switch_media_handle_test_media_flag(smh, SCMF_CODEC_GREEDY);
4924 scrooge = !!switch_media_handle_test_media_flag(smh, SCMF_CODEC_SCROOGE);
4925
4926 if ((val = switch_channel_get_variable(channel, "rtp_codec_negotiation"))) {
4927 if (!strcasecmp(val, "generous")) {
4928 greedy = 0;
4929 scrooge = 0;
4930 } else if (!strcasecmp(val, "greedy")) {
4931 greedy = 1;
4932 scrooge = 0;
4933 } else if (!strcasecmp(val, "scrooge")) {
4934 scrooge = 1;
4935 greedy = 1;
4936 } else {
4937 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "rtp_codec_negotiation ignored invalid value : '%s' \n", val );
4938 }
4939 }
4940
4941 if ((smh->origin = switch_core_session_strdup(session, (char *) sdp->sdp_origin->o_username))) {
4942
4943 if ((smh->mparams->auto_rtp_bugs & RTP_BUG_CISCO_SKIP_MARK_BIT_2833)) {
4944
4945 if (strstr(smh->origin, "CiscoSystemsSIP-GW-UserAgent")) {
4946 a_engine->rtp_bugs |= RTP_BUG_CISCO_SKIP_MARK_BIT_2833;
4947 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Activate Buggy RFC2833 Mode!\n");
4948 }
4949 }
4950
4951 if ((smh->mparams->auto_rtp_bugs & RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833)) {
4952 if (strstr(smh->origin, "Sonus_UAC")) {
4953 a_engine->rtp_bugs |= RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833;
4954 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
4955 "Hello,\nI see you have a Sonus!\n"
4956 "FYI, Sonus cannot follow the RFC on the proper way to send DTMF.\n"
4957 "Sadly, my creator had to spend several hours figuring this out so I thought you'd like to know that!\n"
4958 "Don't worry, DTMF will work but you may want to ask them to fix it......\n");
4959 }
4960 }
4961 }
4962
4963 /* check dtmf_type variable */
4964 switch_core_media_check_dtmf_type(session);
4965
4966 if ((val = switch_channel_get_variable(session->channel, "rtp_liberal_dtmf")) && switch_true(val)) {
4967 switch_channel_set_flag(session->channel, CF_LIBERAL_DTMF);
4968 }
4969
4970 if (switch_stristr("T38FaxFillBitRemoval:", r_sdp) || switch_stristr("T38FaxTranscodingMMR:", r_sdp) ||
4971 switch_stristr("T38FaxTranscodingJBIG:", r_sdp)) {
4972 switch_channel_set_variable(session->channel, "t38_broken_boolean", "true");
4973 }
4974
4975 switch_core_media_find_zrtp_hash(session, sdp);
4976 switch_core_media_pass_zrtp_hash(session);
4977
4978 check_ice(smh, SWITCH_MEDIA_TYPE_AUDIO, sdp, NULL);
4979 check_ice(smh, SWITCH_MEDIA_TYPE_VIDEO, sdp, NULL);
4980 check_ice(smh, SWITCH_MEDIA_TYPE_TEXT, sdp, NULL);
4981
4982 if ((sdp->sdp_connection && sdp->sdp_connection->c_address && !strcmp(sdp->sdp_connection->c_address, "0.0.0.0"))) {
4983 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");
4984 sendonly = 2; /* global sendonly always wins */
4985 }
4986
4987 memset(smh->rejected_streams, 0, sizeof(smh->rejected_streams));
4988 smh->rej_idx = 0;
4989
4990 switch_core_media_set_rmode(smh->session, SWITCH_MEDIA_TYPE_VIDEO, SWITCH_MEDIA_FLOW_INACTIVE, sdp_type);
4991 switch_core_media_set_rmode(smh->session, SWITCH_MEDIA_TYPE_TEXT, SWITCH_MEDIA_FLOW_INACTIVE, sdp_type);
4992
4993 for (m = sdp->sdp_media; m; m = m->m_next) {
4994 sdp_connection_t *connection;
4995 switch_core_session_t *other_session;
4996
4997 if (!m->m_port && smh->rej_idx < MAX_REJ_STREAMS - 1) {
4998
4999 switch(m->m_type) {
5000 case sdp_media_audio:
5001 smh->rejected_streams[smh->rej_idx++] = sdp_media_audio;
5002 continue;
5003 case sdp_media_video:
5004 smh->rejected_streams[smh->rej_idx++] = sdp_media_video;
5005 continue;
5006 case sdp_media_image:
5007 smh->rejected_streams[smh->rej_idx++] = sdp_media_image;
5008 continue;
5009 default:
5010 break;
5011 }
5012 }
5013
5014 if (m->m_type == sdp_media_audio) {
5015 saw_audio = 1;
5016 }
5017
5018 if (m->m_type == sdp_media_video) {
5019 saw_video = 1;
5020 }
5021
5022 ptime = dptime;
5023 maxptime = dmaxptime;
5024
5025 if (m->m_proto == sdp_proto_extended_srtp || m->m_proto == sdp_proto_extended_rtp) {
5026 got_webrtc++;
5027 switch_core_session_set_ice(session);
5028 }
5029
5030 if (m->m_proto_name && !strcasecmp(m->m_proto_name, "UDP/TLS/RTP/SAVPF")) {
5031 switch_channel_set_flag(session->channel, CF_AVPF_MOZ);
5032 }
5033
5034 if (m->m_proto_name && !strcasecmp(m->m_proto_name, "UDP/RTP/AVPF")) {
5035 switch_channel_set_flag(session->channel, CF_AVPF_MOZ);
5036 }
5037
5038 if (m->m_proto == sdp_proto_srtp || m->m_proto == sdp_proto_extended_srtp) {
5039 if (m->m_type == sdp_media_audio) {
5040 got_savp++;
5041 } else {
5042 got_video_savp++;
5043 }
5044 } else if (m->m_proto == sdp_proto_rtp) {
5045 if (m->m_type == sdp_media_audio) {
5046 got_avp++;
5047 } else {
5048 got_video_avp++;
5049 }
5050 } else if (m->m_proto == sdp_proto_udptl) {
5051 got_udptl++;
5052 } else if (m->m_proto == sdp_proto_msrp || m->m_proto == sdp_proto_msrps){
5053 got_msrp++;
5054 }
5055
5056 if (got_msrp && m->m_type == sdp_media_message) {
5057 if (!smh->msrp_session) {
5058 smh->msrp_session = switch_msrp_session_new(switch_core_session_get_pool(session), switch_core_session_get_uuid(session), m->m_proto == sdp_proto_msrps);
5059 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "MSRP session created %s\n", smh->msrp_session->call_id);
5060 }
5061
5062 switch_assert(smh->msrp_session);
5063
5064 for (attr = m->m_attributes; attr; attr = attr->a_next) {
5065 // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "[%s]=[%s]\n", attr->a_name, attr->a_value);
5066 if (!strcasecmp(attr->a_name, "path") && attr->a_value) {
5067 smh->msrp_session->remote_path = switch_core_session_strdup(session, attr->a_value);
5068 switch_channel_set_variable(session->channel, "sip_msrp_remote_path", attr->a_value);
5069 } else if (!strcasecmp(attr->a_name, "accept-types") && attr->a_value) {
5070 smh->msrp_session->remote_accept_types = switch_core_session_strdup(session, attr->a_value);
5071 switch_channel_set_variable(session->channel, "sip_msrp_remote_accept_types", attr->a_value);
5072 } else if (!strcasecmp(attr->a_name, "accept-wrapped-types") && attr->a_value) {
5073 smh->msrp_session->remote_accept_wrapped_types = switch_core_session_strdup(session, attr->a_value);
5074 switch_channel_set_variable(session->channel, "sip_msrp_remote_accept_wrapped_types", attr->a_value);
5075 } else if (!strcasecmp(attr->a_name, "setup") && attr->a_value) {
5076 smh->msrp_session->remote_setup = switch_core_session_strdup(session, attr->a_value);
5077 switch_channel_set_variable(session->channel, "sip_msrp_remote_setup", attr->a_value);
5078 if (!strcmp(attr->a_value, "passive")) {
5079 smh->msrp_session->active = 1;
5080 }
5081 } else if (!strcasecmp(attr->a_name, "file-selector") && attr->a_value) {
5082 char *tmp = switch_mprintf("%s", attr->a_value);
5083 char *argv[4] = { 0 };
5084 int argc;
5085 int i;
5086
5087 smh->msrp_session->remote_file_selector = switch_core_session_strdup(session, attr->a_value);
5088 switch_channel_set_variable(session->channel, "sip_msrp_remote_file_selector", attr->a_value);
5089
5090 argc = switch_separate_string(tmp, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
5091
5092 for(i = 0; i<argc; i++) {
5093 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "::::%s\n", switch_str_nil(argv[i]));
5094 if (zstr(argv[i])) {
5095 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERRRRRRR\n");
5096 continue;
5097 }
5098 if (!strncasecmp(argv[i], "name:", 5)) {
5099 char *p = argv[i] + 5;
5100 int len = strlen(p);
5101
5102 if (*p == '"') {
5103 *(p + len - 1) = '\0';
5104 p++;
5105 }
5106 switch_channel_set_variable(session->channel, "sip_msrp_file_name", p);
5107 } else if (!strncasecmp(argv[i], "type:", 5)) {
5108 switch_channel_set_variable(session->channel, "sip_msrp_file_type", argv[i] + 5);
5109 }
5110 if (!strncasecmp(argv[i], "size:", 5)) {
5111 switch_channel_set_variable(session->channel, "sip_msrp_file_size", argv[i] + 5);
5112 }
5113 if (!strncasecmp(argv[i], "hash:", 5)) {
5114 switch_channel_set_variable(session->channel, "sip_msrp_file_hash", argv[i] + 5);
5115 }
5116 }
5117 switch_safe_free(tmp);
5118 } else if (!strcasecmp(attr->a_name, "file-transfer-id") && attr->a_value) {
5119 switch_channel_set_variable(session->channel, "sip_msrp_file_transfer_id", attr->a_value);
5120 } else if (!strcasecmp(attr->a_name, "file-disposition") && attr->a_value) {
5121 switch_channel_set_variable(session->channel, "sip_msrp_file_disposition", attr->a_value);
5122 } else if (!strcasecmp(attr->a_name, "file-date") && attr->a_value) {
5123 switch_channel_set_variable(session->channel, "sip_msrp_file_date", attr->a_value);
5124 } else if (!strcasecmp(attr->a_name, "file-icon") && attr->a_value) {
5125 switch_channel_set_variable(session->channel, "sip_msrp_file_icon", attr->a_value);
5126 } else if (!strcasecmp(attr->a_name, "file-range") && attr->a_value) {
5127 switch_channel_set_variable(session->channel, "sip_msrp_file_range", attr->a_value);
5128 }
5129 }
5130
5131 smh->msrp_session->local_accept_types = smh->msrp_session->remote_accept_types;
5132 smh->msrp_session->local_accept_wrapped_types = smh->msrp_session->remote_accept_types;
5133 smh->msrp_session->local_setup = smh->msrp_session->remote_setup;
5134
5135 switch_channel_set_flag(session->channel, CF_HAS_TEXT);
5136 switch_channel_set_flag(session->channel, CF_TEXT_POSSIBLE);
5137 switch_channel_set_flag(session->channel, CF_TEXT_LINE_BASED);
5138 switch_channel_set_flag(session->channel, CF_MSRP);
5139
5140 if (m->m_proto == sdp_proto_msrps) {
5141 switch_channel_set_flag(session->channel, CF_MSRPS);
5142 }
5143
5144 if (smh->msrp_session->active) {
5145 const char *ip = switch_msrp_listen_ip();
5146
5147 smh->msrp_session->local_path = switch_core_session_sprintf(session,
5148 "msrp%s://%s:%d/%s;tcp",
5149 smh->msrp_session->secure ? "s" : "",
5150 ip, smh->msrp_session->local_port, smh->msrp_session->call_id);
5151
5152 switch_msrp_start_client(smh->msrp_session);
5153 }
5154
5155 switch_core_session_start_text_thread(session);
5156 tmatch = 1;
5157 }
5158
5159 if (got_udptl && m->m_type == sdp_media_image) {
5160 switch_channel_set_flag(session->channel, CF_IMAGE_SDP);
5161
5162 if (m->m_port) {
5163 if (switch_channel_test_app_flag_key("T38", session->channel, CF_APP_T38_NEGOTIATED)) {
5164 fmatch = 1;
5165 goto done;
5166 }
5167
5168 if (switch_channel_var_true(channel, "refuse_t38") || !switch_channel_var_true(channel, "fax_enable_t38")) {
5169 switch_channel_clear_app_flag_key("T38", session->channel, CF_APP_T38);
5170 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s T38 REFUSE on %s\n",
5171 switch_channel_get_name(channel),
5172 sdp_type == SDP_TYPE_RESPONSE ? "response" : "request");
5173
5174 restore_pmaps(a_engine);
5175 fmatch = 0;
5176
5177 goto t38_done;
5178 } else {
5179 switch_t38_options_t *t38_options = switch_core_media_process_udptl(session, sdp, m);
5180 const char *var = switch_channel_get_variable(channel, "t38_passthru");
5181 int pass = switch_channel_test_flag(smh->session->channel, CF_T38_PASSTHRU);
5182
5183 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s T38 ACCEPT on %s\n",
5184 switch_channel_get_name(channel),
5185 sdp_type == SDP_TYPE_RESPONSE ? "response" : "request");
5186
5187 if (switch_channel_test_app_flag_key("T38", session->channel, CF_APP_T38)) {
5188 if (proceed) *proceed = 0;
5189 }
5190
5191 if (var) {
5192 if (!(pass = switch_true(var))) {
5193 if (!strcasecmp(var, "once")) {
5194 pass = 2;
5195 }
5196 }
5197 }
5198
5199 if ((pass == 2 && switch_channel_test_flag(smh->session->channel, CF_T38_PASSTHRU))
5200 || !switch_channel_test_flag(session->channel, CF_REINVITE) ||
5201
5202 switch_channel_test_flag(session->channel, CF_PROXY_MODE) ||
5203 switch_channel_test_flag(session->channel, CF_PROXY_MEDIA) ||
5204 !switch_rtp_ready(a_engine->rtp_session)) {
5205 pass = 0;
5206 }
5207
5208 if (pass && switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
5209 switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
5210 switch_core_session_message_t *msg;
5211 char *remote_host = switch_rtp_get_remote_host(a_engine->rtp_session);
5212 switch_port_t remote_port = switch_rtp_get_remote_port(a_engine->rtp_session);
5213 char tmp[32] = "";
5214
5215
5216 if (!switch_channel_test_flag(other_channel, CF_ANSWERED)) {
5217 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session),
5218 SWITCH_LOG_WARNING, "%s Error Passing T.38 to unanswered channel %s\n",
5219 switch_channel_get_name(session->channel), switch_channel_get_name(other_channel));
5220 switch_core_session_rwunlock(other_session);
5221
5222 match = 0;
5223 fmatch = 0;
5224 goto done;
5225 }
5226
5227 switch_channel_set_app_flag_key("T38", channel, CF_APP_T38_POSSIBLE);
5228 switch_channel_set_app_flag_key("T38", other_channel, CF_APP_T38_POSSIBLE);
5229
5230 if (switch_true(switch_channel_get_variable(session->channel, "t38_broken_boolean")) &&
5231 switch_true(switch_channel_get_variable(session->channel, "t38_pass_broken_boolean"))) {
5232 switch_channel_set_variable(other_channel, "t38_broken_boolean", "true");
5233 }
5234
5235 a_engine->cur_payload_map->remote_sdp_ip = switch_core_session_strdup(session, t38_options->remote_ip);
5236 a_engine->cur_payload_map->remote_sdp_port = t38_options->remote_port;
5237
5238 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) {
5239 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio params are unchanged for %s.\n",
5240 switch_channel_get_name(session->channel));
5241 } else {
5242 const char *err = NULL;
5243
5244 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio params changed for %s from %s:%d to %s:%d\n",
5245 switch_channel_get_name(session->channel),
5246 remote_host, remote_port, a_engine->cur_payload_map->remote_sdp_ip, a_engine->cur_payload_map->remote_sdp_port);
5247
5248 switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->cur_payload_map->remote_sdp_port);
5249 switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, a_engine->cur_payload_map->remote_sdp_ip);
5250 switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp);
5251
5252 if (switch_rtp_set_remote_address(a_engine->rtp_session, a_engine->cur_payload_map->remote_sdp_ip,
5253 a_engine->cur_payload_map->remote_sdp_port, 0, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
5254 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", err);
5255 switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
5256 }
5257
5258 switch_core_media_check_autoadj(session);
5259 switch_channel_execute_on(session->channel, "execute_on_audio_change");
5260 }
5261
5262
5263
5264 switch_core_media_copy_t38_options(t38_options, other_session);
5265
5266 switch_channel_set_flag(smh->session->channel, CF_T38_PASSTHRU);
5267 switch_channel_set_flag(other_session->channel, CF_T38_PASSTHRU);
5268
5269 msg = switch_core_session_alloc(other_session, sizeof(*msg));
5270 msg->message_id = SWITCH_MESSAGE_INDICATE_REQUEST_IMAGE_MEDIA;
5271 msg->from = __FILE__;
5272 msg->string_arg = switch_core_session_strdup(other_session, r_sdp);
5273 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Passing T38 req to other leg.\n%s\n", r_sdp);
5274 switch_core_session_queue_message(other_session, msg);
5275 switch_core_session_rwunlock(other_session);
5276 }
5277 }
5278
5279 /* do nothing here, mod_fax will trigger a response (if it's listening =/) */
5280 if (switch_channel_wait_for_app_flag(channel, CF_APP_T38_POSSIBLE, "T38", SWITCH_TRUE, 2000)) {
5281 fmatch = 1;
5282 } else {
5283
5284 fmatch = 0;
5285 }
5286
5287 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s T38 %s POSSIBLE on %s\n",
5288 switch_channel_get_name(channel),
5289 fmatch ? "IS" : "IS NOT",
5290 sdp_type == SDP_TYPE_RESPONSE ? "response" : "request");
5291
5292
5293 goto done;
5294 }
5295 } else if (m->m_type == sdp_media_audio && m->m_port && got_audio && got_savp) {
5296 a_engine->reject_avp = 1;
5297 } else if (m->m_type == sdp_media_audio && m->m_port && !got_audio) {
5298 sdp_rtpmap_t *map;
5299 int ice = 0;
5300
5301 nm_idx = 0;
5302 m_idx = 0;
5303 memset(matches, 0, sizeof(matches[0]) * MAX_MATCHES);
5304 memset(near_matches, 0, sizeof(near_matches[0]) * MAX_MATCHES);
5305
5306 audio_port = m->m_port;
5307
5308 if (!sendonly && (m->m_mode == sdp_sendonly || m->m_mode == sdp_inactive)) {
5309 sendonly = 1;
5310 if (m->m_mode == sdp_inactive) {
5311 inactive = 1;
5312 }
5313 }
5314
5315 if (!sendonly && m->m_connections && m->m_connections->c_address && !strcmp(m->m_connections->c_address, "0.0.0.0")) {
5316 sendonly = 1;
5317 }
5318
5319
5320 switch_core_media_set_rmode(smh->session, SWITCH_MEDIA_TYPE_AUDIO, sdp_media_flow(m->m_mode), sdp_type);
5321
5322 if (sdp_type == SDP_TYPE_REQUEST) {
5323 switch(a_engine->rmode) {
5324 case SWITCH_MEDIA_FLOW_RECVONLY:
5325 switch_core_media_set_smode(smh->session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_MEDIA_FLOW_SENDONLY, sdp_type);
5326 break;
5327 case SWITCH_MEDIA_FLOW_SENDONLY:
5328 switch_core_media_set_smode(smh->session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_MEDIA_FLOW_RECVONLY, sdp_type);
5329 break;
5330 case SWITCH_MEDIA_FLOW_INACTIVE:
5331 switch_core_media_set_smode(smh->session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_MEDIA_FLOW_INACTIVE, sdp_type);
5332 break;
5333 default:
5334 switch_core_media_set_smode(smh->session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_MEDIA_FLOW_SENDRECV, sdp_type);
5335 break;
5336 }
5337 }
5338
5339 for (attr = sdp->sdp_attributes; attr; attr = attr->a_next) {
5340 if (zstr(attr->a_name)) {
5341 continue;
5342 }
5343
5344
5345 if (!strncasecmp(attr->a_name, "ice", 3)) {
5346 ice++;
5347 } else if (sendonly < 2 && !strcasecmp(attr->a_name, "sendonly")) {
5348 sendonly = 1;
5349 switch_channel_set_variable(session->channel, "media_audio_mode", "recvonly");
5350 } else if (sendonly < 2 && !strcasecmp(attr->a_name, "inactive")) {
5351 switch_channel_set_variable(session->channel, "media_audio_mode", "inactive");
5352 } else if (!strcasecmp(attr->a_name, "recvonly")) {
5353 switch_channel_set_variable(session->channel, "media_audio_mode", "sendonly");
5354 recvonly = 1;
5355
5356 a_engine->media_timeout = 0;
5357 a_engine->media_hold_timeout = 0;
5358
5359 if (switch_rtp_ready(a_engine->rtp_session)) {
5360 switch_rtp_set_max_missed_packets(a_engine->rtp_session, 0);
5361 a_engine->max_missed_hold_packets = 0;
5362 a_engine->max_missed_packets = 0;
5363 switch_rtp_set_media_timeout(a_engine->rtp_session, a_engine->media_timeout);
5364 } else {
5365 switch_channel_set_variable(session->channel, "media_timeout_audio", "0");
5366 switch_channel_set_variable(session->channel, "media_hold_timeout_audio", "0");
5367 switch_channel_set_variable(session->channel, "rtp_timeout_sec", "0");
5368 switch_channel_set_variable(session->channel, "rtp_hold_timeout_sec", "0");
5369 }
5370 } else if (sendonly < 2 && !strcasecmp(attr->a_name, "sendrecv")) {
5371 sendonly = 0;
5372 } else if (!strcasecmp(attr->a_name, "ptime")) {
5373 ptime = dptime = atoi(attr->a_value);
5374 } else if (!strcasecmp(attr->a_name, "maxptime")) {
5375 maxptime = dmaxptime = atoi(attr->a_value);
5376 }
5377 }
5378
5379 if (sendonly == 2 && ice) {
5380 sendonly = 0;
5381 }
5382
5383
5384 if (sendonly != 1 && recvonly != 1 && inactive != 1) {
5385 switch_channel_set_variable(session->channel, "media_audio_mode", NULL);
5386 }
5387
5388 if (sdp_type == SDP_TYPE_RESPONSE) {
5389 if (inactive) {
5390 // When freeswitch had previously sent inactive in sip request. it should remain inactive otherwise smode should be sendrecv
5391 if (a_engine->smode==SWITCH_MEDIA_FLOW_INACTIVE) {
5392 switch_core_media_set_smode(smh->session, SWITCH_MEDIA_TYPE_AUDIO, sdp_media_flow(sdp_inactive), sdp_type);
5393 } else {
5394 switch_core_media_set_smode(smh->session, SWITCH_MEDIA_TYPE_AUDIO, sdp_media_flow(sdp_sendrecv), sdp_type);
5395 }
5396 } else if (sendonly) {
5397 switch_core_media_set_smode(smh->session, SWITCH_MEDIA_TYPE_AUDIO, sdp_media_flow(sdp_sendonly), sdp_type);
5398 } else if (recvonly) {
5399 switch_core_media_set_smode(smh->session, SWITCH_MEDIA_TYPE_AUDIO, sdp_media_flow(sdp_recvonly), sdp_type);
5400 }
5401 }
5402
5403
5404 if (!(switch_media_handle_test_media_flag(smh, SCMF_DISABLE_HOLD)
5405 || ((val = switch_channel_get_variable(session->channel, "rtp_disable_hold"))
5406 && switch_true(val)))
5407 && !smh->mparams->hold_laps) {
5408 smh->mparams->hold_laps++;
5409 switch_core_media_toggle_hold(session, sendonly);
5410 }
5411
5412
5413 if (switch_rtp_has_dtls() && dtls_ok(session)) {
5414 for (attr = m->m_attributes; attr; attr = attr->a_next) {
5415
5416 if (!strcasecmp(attr->a_name, "fingerprint") && !zstr(attr->a_value)) {
5417 got_crypto = 1;
5418 }
5419 }
5420 }
5421
5422 skip_rtcp = 0;
5423 got_rtcp_mux = 0;
5424 for (attr = m->m_attributes; attr; attr = attr->a_next) {
5425 if (!strcasecmp(attr->a_name, "rtcp-mux")) {
5426 got_rtcp_mux = 1;
5427 skip_rtcp = 1;
5428 if (!smh->mparams->rtcp_video_interval_msec) {
5429 smh->mparams->rtcp_video_interval_msec = SWITCH_RTCP_VIDEO_INTERVAL_MSEC;
5430 }
5431 } else if (!strcasecmp(attr->a_name, "ice-ufrag")) {
5432 skip_rtcp = 1;
5433 }
5434 }
5435
5436 if (!got_rtcp_mux) {
5437 a_engine->rtcp_mux = -1;
5438 }
5439
5440 for (attr = m->m_attributes; attr; attr = attr->a_next) {
5441 if (!strcasecmp(attr->a_name, "rtcp") && attr->a_value && !skip_rtcp) {
5442 a_engine->remote_rtcp_port = (switch_port_t)atoi(attr->a_value);
5443 switch_channel_set_variable_printf(session->channel, "rtp_remote_audio_rtcp_port", "%d", a_engine->remote_rtcp_port);
5444
5445 if (!smh->mparams->rtcp_audio_interval_msec) {
5446 smh->mparams->rtcp_audio_interval_msec = SWITCH_RTCP_AUDIO_INTERVAL_MSEC;
5447 }
5448 got_audio_rtcp = 1;
5449 } else if (!strcasecmp(attr->a_name, "ptime") && attr->a_value) {
5450 ptime = atoi(attr->a_value);
5451 } else if (!strcasecmp(attr->a_name, "maxptime") && attr->a_value) {
5452 maxptime = atoi(attr->a_value);
5453 } else if (got_crypto < 1 && !strcasecmp(attr->a_name, "crypto") && !zstr(attr->a_value)) {
5454 int crypto_tag;
5455
5456 if (!(smh->mparams->ndlb & SM_NDLB_ALLOW_CRYPTO_IN_AVP) &&
5457 !switch_true(switch_channel_get_variable(session->channel, "rtp_allow_crypto_in_avp"))) {
5458 if (m->m_proto != sdp_proto_srtp && !got_webrtc) {
5459 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "a=crypto in RTP/AVP, refer to rfc3711\n");
5460 match = 0;
5461 goto done;
5462 }
5463 }
5464
5465 crypto = attr->a_value;
5466 crypto_tag = atoi(crypto);
5467 got_crypto = switch_core_session_check_incoming_crypto(session,
5468 "rtp_has_crypto", SWITCH_MEDIA_TYPE_AUDIO, crypto, crypto_tag, sdp_type);
5469
5470 }
5471 }
5472
5473 if (got_crypto == -1 && got_savp && !got_avp && !got_webrtc) {
5474 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Received invite with SAVP but secure media is administratively disabled\n");
5475 match = 0;
5476 continue;
5477 }
5478
5479 connection = sdp->sdp_connection;
5480 if (m->m_connections) {
5481 connection = m->m_connections;
5482 }
5483
5484 if (!connection) {
5485 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");
5486 match = 0;
5487 break;
5488 }
5489
5490 x = 0;
5491
5492 for (map = m->m_rtpmaps; map; map = map->rm_next) {
5493 int32_t i;
5494 const char *rm_encoding;
5495 uint32_t map_bit_rate = 0;
5496 switch_codec_fmtp_t codec_fmtp = { 0 };
5497 int map_channels = map->rm_params ? atoi(map->rm_params) : 1;
5498
5499 if (!(rm_encoding = map->rm_encoding)) {
5500 rm_encoding = "";
5501 }
5502
5503
5504 if (!strcasecmp(rm_encoding, "telephone-event")) {
5505 if (!best_te || map->rm_rate == a_engine->cur_payload_map->rm_rate) {
5506 best_te = (switch_payload_t) map->rm_pt;
5507 best_te_rate = map->rm_rate;
5508 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set telephone-event payload to %u@%ld\n", best_te, best_te_rate);
5509 }
5510 continue;
5511 }
5512
5513 if (!switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG) && !cng_pt && !strcasecmp(rm_encoding, "CN")) {
5514 cng_pt = (switch_payload_t) map->rm_pt;
5515 if (a_engine->rtp_session) {
5516 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set comfort noise payload to %u\n", cng_pt);
5517 switch_rtp_set_cng_pt(a_engine->rtp_session, cng_pt);
5518 }
5519 continue;
5520 }
5521
5522
5523 if (x++ < skip) {
5524 continue;
5525 }
5526
5527 if (match) {
5528 continue;
5529 }
5530
5531 codec_ms = ptime;
5532
5533 if (switch_channel_get_variable(session->channel, "rtp_h_X-Broken-PTIME") && a_engine->read_impl.microseconds_per_packet) {
5534 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);
5535 codec_ms = a_engine->read_impl.microseconds_per_packet / 1000;
5536 }
5537
5538 if (maxptime && (!codec_ms || codec_ms > maxptime)) {
5539 codec_ms = maxptime;
5540 }
5541
5542 if (!codec_ms) {
5543 codec_ms = switch_default_ptime(rm_encoding, map->rm_pt);
5544 }
5545
5546 map_bit_rate = switch_known_bitrate((switch_payload_t)map->rm_pt);
5547
5548 if (!ptime && !strcasecmp(map->rm_encoding, "g723")) {
5549 codec_ms = 30;
5550 }
5551
5552 remote_codec_rate = map->rm_rate;
5553 fmtp_remote_codec_rate = 0;
5554 memset(&codec_fmtp, 0, sizeof(codec_fmtp));
5555
5556 if (zstr(map->rm_fmtp)) {
5557 if (!strcasecmp(map->rm_encoding, "ilbc")) {
5558 codec_ms = 30;
5559 map_bit_rate = 13330;
5560 } else if (!strcasecmp(map->rm_encoding, "isac")) {
5561 codec_ms = 30;
5562 map_bit_rate = 32000;
5563 }
5564 } else {
5565 if ((switch_core_codec_parse_fmtp(map->rm_encoding, map->rm_fmtp, map->rm_rate, &codec_fmtp)) == SWITCH_STATUS_SUCCESS) {
5566 if (codec_fmtp.bits_per_second) {
5567 map_bit_rate = codec_fmtp.bits_per_second;
5568 }
5569 if (codec_fmtp.microseconds_per_packet) {
5570 codec_ms = (codec_fmtp.microseconds_per_packet / 1000);
5571 }
5572 if (codec_fmtp.actual_samples_per_second) {
5573 fmtp_remote_codec_rate = codec_fmtp.actual_samples_per_second;
5574 }
5575 if (codec_fmtp.stereo) {
5576 map_channels = 2;
5577 } else if (!strcasecmp(map->rm_encoding, "opus")) {
5578 map_channels = 1;
5579 }
5580 }
5581 }
5582
5583 for (i = 0; i < smh->mparams->num_codecs && i < total_codecs; i++) {
5584 const switch_codec_implementation_t *imp = codec_array[i];
5585 uint32_t bit_rate = imp->bits_per_second;
5586 uint32_t codec_rate = imp->samples_per_second;
5587
5588 if (imp->codec_type != SWITCH_CODEC_TYPE_AUDIO) {
5589 continue;
5590 }
5591
5592 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",
5593 rm_encoding, map->rm_pt, (int) remote_codec_rate, codec_ms, map_bit_rate, map_channels,
5594 imp->iananame, imp->ianacode, codec_rate, imp->microseconds_per_packet / 1000, bit_rate, imp->number_of_channels);
5595 if ((zstr(map->rm_encoding) || (smh->mparams->ndlb & SM_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) {
5596 match = (map->rm_pt == imp->ianacode) ? 1 : 0;
5597 } else {
5598 match = (!strcasecmp(rm_encoding, imp->iananame) &&
5599 ((map->rm_pt < 96 && imp->ianacode < 96) || (map->rm_pt > 95 && imp->ianacode > 95)) &&
5600 (remote_codec_rate == codec_rate || fmtp_remote_codec_rate == imp->actual_samples_per_second)) ? 1 : 0;
5601 if (fmtp_remote_codec_rate) {
5602 remote_codec_rate = fmtp_remote_codec_rate;
5603 }
5604 }
5605
5606 if (match && bit_rate && map_bit_rate && map_bit_rate != bit_rate && strcasecmp(map->rm_encoding, "ilbc") &&
5607 strcasecmp(map->rm_encoding, "isac")) {
5608 /* if a bit rate is specified and doesn't match, this is not a codec match, except for ILBC */
5609 match = 0;
5610 }
5611
5612 if (match && remote_codec_rate && codec_rate && remote_codec_rate != codec_rate && (!strcasecmp(map->rm_encoding, "pcma") ||
5613 !strcasecmp(map->rm_encoding, "pcmu"))) {
5614 /* if the sampling rate is specified and doesn't match, this is not a codec match for G.711 */
5615 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "sampling rates have to match for G.711\n");
5616 match = 0;
5617 }
5618
5619 if (match) {
5620 if (scrooge) {
5621 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
5622 "Bah HUMBUG! Sticking with %s@%uh@%ui\n",
5623 imp->iananame, imp->samples_per_second, imp->microseconds_per_packet / 1000);
5624 } else if ((ptime && codec_ms && codec_ms * 1000 != imp->microseconds_per_packet) || remote_codec_rate != codec_rate) {
5625 /* ptime does not match */
5626 match = 0;
5627
5628 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
5629 "Audio Codec Compare [%s:%d:%u:%d:%u:%d] is saved as a near-match\n",
5630 imp->iananame, imp->ianacode, codec_rate, imp->microseconds_per_packet / 1000, bit_rate, imp->number_of_channels);
5631
5632 near_matches[nm_idx].codec_idx = i;
5633 near_matches[nm_idx].rate = remote_codec_rate;
5634 near_matches[nm_idx].imp = imp;
5635 near_matches[nm_idx].map = map;
5636 nm_idx++;
5637
5638 continue;
5639 }
5640
5641 matches[m_idx].codec_idx = i;
5642 matches[m_idx].rate = codec_rate;
5643 matches[m_idx].imp = imp;
5644 matches[m_idx].map = map;
5645 m_idx++;
5646
5647 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
5648 "Audio Codec Compare [%s:%d:%u:%d:%u:%d] ++++ is saved as a match\n",
5649 imp->iananame, imp->ianacode, codec_rate, imp->microseconds_per_packet / 1000, bit_rate, imp->number_of_channels);
5650
5651 if (m_idx >= MAX_MATCHES) {
5652 break;
5653 }
5654
5655 match = 0;
5656 }
5657 }
5658
5659 if (m_idx >= MAX_MATCHES) {
5660 break;
5661 }
5662 }
5663
5664 if (smh->crypto_mode == CRYPTO_MODE_MANDATORY && got_crypto < 1) {
5665 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Crypto not negotiated but required.\n");
5666 match = 0;
5667 m_idx = nm_idx = 0;
5668 }
5669
5670
5671 if (!m_idx && nm_idx) {
5672 int j;
5673
5674 for(j = 0; j < nm_idx; j++) {
5675 const switch_codec_implementation_t *search[1];
5676 char *prefs[1];
5677 char tmp[80];
5678 char fmtp[SWITCH_MAX_CODECS][MAX_FMTP_LEN];
5679 int num;
5680 const switch_codec_implementation_t *timp = NULL;
5681
5682 near_rate = near_matches[j].rate;
5683 near_match = near_matches[j].imp;
5684 near_map = near_matches[j].map;
5685
5686 switch_snprintf(tmp, sizeof(tmp), "%s@%uh@%ui%dc", near_match->iananame, near_rate ? near_rate : near_match->samples_per_second,
5687 codec_ms, near_match->number_of_channels);
5688
5689 prefs[0] = tmp;
5690 num = switch_loadable_module_get_codecs_sorted(search, fmtp, 1, prefs, 1);
5691
5692 if (num) {
5693 timp = search[0];
5694 } else {
5695 timp = near_match;
5696 }
5697
5698 if (!maxptime || timp->microseconds_per_packet / 1000 <= maxptime) {
5699 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Substituting codec %s@%ui@%uh@%dc\n",
5700 timp->iananame, timp->microseconds_per_packet / 1000, timp->actual_samples_per_second, timp->number_of_channels);
5701 match = 1;
5702
5703 matches[m_idx].codec_idx = near_matches[j].codec_idx;
5704 matches[m_idx].rate = near_rate;
5705 matches[m_idx].imp = timp;
5706 matches[m_idx].map = near_map;
5707 m_idx++;
5708
5709 break;
5710 }
5711 }
5712 }
5713
5714 if (m_idx) {
5715 int j;
5716
5717 if (greedy) { /* sort in favor of mine */
5718 greedy_sort(smh, matches, m_idx, codec_array, total_codecs);
5719 }
5720
5721 match = 1;
5722 a_engine->codec_negotiated = 1;
5723
5724 for(j = 0; j < m_idx && smh->num_negotiated_codecs < SWITCH_MAX_CODECS; j++) {
5725 payload_map_t *pmap = switch_core_media_add_payload_map(session,
5726 SWITCH_MEDIA_TYPE_AUDIO,
5727 matches[j].map->rm_encoding,
5728 matches[j].imp->modname,
5729 matches[j].map->rm_fmtp,
5730 sdp_type,
5731 matches[j].map->rm_pt,
5732 matches[j].imp->samples_per_second,
5733 matches[j].imp->microseconds_per_packet / 1000,
5734 matches[j].imp->number_of_channels,
5735 SWITCH_TRUE);
5736
5737 mimp = matches[j].imp;
5738 mmap = matches[j].map;
5739
5740 if (j == 0) {
5741 a_engine->cur_payload_map = pmap;
5742 a_engine->cur_payload_map->current = 1;
5743 if (a_engine->rtp_session) {
5744 switch_rtp_set_default_payload(a_engine->rtp_session, pmap->pt);
5745 }
5746 }
5747
5748 pmap->rm_encoding = switch_core_session_strdup(session, (char *) mmap->rm_encoding);
5749 pmap->iananame = switch_core_session_strdup(session, (char *) mimp->iananame);
5750 pmap->recv_pt = (switch_payload_t) mmap->rm_pt;
5751 pmap->rm_rate = mimp->samples_per_second;
5752 pmap->adv_rm_rate = mimp->samples_per_second;
5753 if (strcasecmp(mimp->iananame, "g722")) {
5754 pmap->rm_rate = mimp->actual_samples_per_second;
5755 }
5756 pmap->codec_ms = mimp->microseconds_per_packet / 1000;
5757 pmap->bitrate = mimp->bits_per_second;
5758 pmap->channels = mmap->rm_params ? atoi(mmap->rm_params) : 1;
5759
5760 if (!strcasecmp((char *) mmap->rm_encoding, "opus")) {
5761 if (pmap->channels == 1) {
5762 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Invalid SDP for opus. Don't ask.. but it needs a /2\n");
5763 pmap->adv_channels = 1;
5764 } else {
5765 pmap->adv_channels = 2; /* IKR ???*/
5766 }
5767 if (!zstr((char *) mmap->rm_fmtp) && switch_stristr("stereo=1", (char *) mmap->rm_fmtp)) {
5768 pmap->channels = 2;
5769 } else {
5770 pmap->channels = 1;
5771 }
5772 } else {
5773 pmap->adv_channels = pmap->channels;
5774 }
5775
5776 pmap->remote_sdp_ip = switch_core_session_strdup(session, (char *) connection->c_address);
5777 pmap->remote_sdp_port = (switch_port_t) m->m_port;
5778 pmap->rm_fmtp = switch_core_session_strdup(session, (char *) mmap->rm_fmtp);
5779
5780 smh->negotiated_codecs[smh->num_negotiated_codecs++] = mimp;
5781 pmap->recv_pt = (switch_payload_t)mmap->rm_pt;
5782
5783 }
5784 }
5785
5786 if (match) {
5787 char tmp[50];
5788 //const char *mirror = switch_channel_get_variable(session->channel, "rtp_mirror_remote_audio_codec_payload");
5789
5790
5791 switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->cur_payload_map->remote_sdp_port);
5792 switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, a_engine->cur_payload_map->remote_sdp_ip);
5793 switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp);
5794
5795
5796 if (a_engine->cur_payload_map->pt == smh->mparams->te) {
5797 switch_payload_t pl = 0;
5798 payload_map_t *pmap;
5799
5800 switch_mutex_lock(smh->sdp_mutex);
5801 for (pmap = a_engine->cur_payload_map; pmap && pmap->allocated; pmap = pmap->next) {
5802 if (pmap->pt > pl) {
5803 pl = pmap->pt;
5804 }
5805 }
5806 switch_mutex_unlock(smh->sdp_mutex);
5807
5808 smh->mparams->te = (switch_payload_t) ++pl;
5809 }
5810
5811
5812
5813 switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->cur_payload_map->recv_pt);
5814 switch_channel_set_variable(session->channel, "rtp_audio_recv_pt", tmp);
5815
5816 if (a_engine->read_impl.iananame) {
5817 if (!switch_core_codec_ready(&a_engine->read_codec) ||
5818 ((strcasecmp(matches[0].imp->iananame, a_engine->read_impl.iananame) ||
5819 matches[0].imp->microseconds_per_packet != a_engine->read_impl.microseconds_per_packet ||
5820 matches[0].imp->samples_per_second != a_engine->read_impl.samples_per_second
5821 ))) {
5822
5823 a_engine->reset_codec = 1;
5824 }
5825 } else if (switch_core_media_set_codec(session, 0, smh->mparams->codec_flags) != SWITCH_STATUS_SUCCESS) {
5826 match = 0;
5827 }
5828
5829 if (match) {
5830 if (check_ice(smh, SWITCH_MEDIA_TYPE_AUDIO, sdp, m) == SWITCH_STATUS_FALSE) {
5831 match = 0;
5832 got_audio = 0;
5833 } else {
5834 got_audio = 1;
5835 }
5836 }
5837
5838 }
5839
5840 for (map = m->m_rtpmaps; map; map = map->rm_next) {
5841 const char *rm_encoding;
5842
5843 if (!(rm_encoding = map->rm_encoding)) {
5844 rm_encoding = "";
5845 }
5846
5847 if (!strcasecmp(rm_encoding, "telephone-event")) {
5848 if (!best_te || map->rm_rate == a_engine->cur_payload_map->adv_rm_rate) {
5849 best_te = (switch_payload_t) map->rm_pt;
5850 best_te_rate = map->rm_rate;
5851 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set telephone-event payload to %u@%lu\n", best_te, best_te_rate);
5852 }
5853 continue;
5854 }
5855
5856 if (!switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG) && !strcasecmp(rm_encoding, "CN")) {
5857
5858 if (!cng_pt || map->rm_rate == a_engine->cur_payload_map->adv_rm_rate) {
5859 cng_pt = (switch_payload_t) map->rm_pt;
5860 cng_rate = map->rm_rate;
5861
5862 if (a_engine->rtp_session) {
5863 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set comfort noise payload to %u@%lu\n", cng_pt, cng_rate);
5864 switch_rtp_set_cng_pt(a_engine->rtp_session, cng_pt);
5865 }
5866 }
5867 continue;
5868 }
5869 }
5870
5871 if (cng_rate != a_engine->cur_payload_map->adv_rm_rate) {
5872 cng_rate = 8000;
5873 }
5874
5875 if (best_te_rate != a_engine->cur_payload_map->adv_rm_rate) {
5876 best_te_rate = 8000;
5877 }
5878
5879 if (!best_te && (switch_channel_test_flag(session->channel, CF_LIBERAL_DTMF))) {
5880 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
5881 "No 2833 in SDP. Liberal DTMF mode adding %d as telephone-event.\n", smh->mparams->te);
5882 best_te = smh->mparams->te;
5883 }
5884
5885 if (best_te) {
5886 smh->mparams->te_rate = best_te_rate;
5887
5888 if (smh->mparams->dtmf_type == DTMF_AUTO || smh->mparams->dtmf_type == DTMF_2833 ||
5889 switch_channel_test_flag(session->channel, CF_LIBERAL_DTMF)) {
5890 if (sdp_type == SDP_TYPE_REQUEST) {
5891 smh->mparams->te = smh->mparams->recv_te = (switch_payload_t) best_te;
5892 switch_channel_set_variable(session->channel, "dtmf_type", "rfc2833");
5893 smh->mparams->dtmf_type = DTMF_2833;
5894 } else {
5895 smh->mparams->te = (switch_payload_t) best_te;
5896 switch_channel_set_variable(session->channel, "dtmf_type", "rfc2833");
5897 smh->mparams->dtmf_type = DTMF_2833;
5898 }
5899 }
5900
5901 if (a_engine->rtp_session) {
5902 switch_rtp_set_telephony_event(a_engine->rtp_session, smh->mparams->te);
5903 switch_channel_set_variable_printf(session->channel, "rtp_2833_send_payload", "%d", smh->mparams->te);
5904 switch_rtp_set_telephony_recv_event(a_engine->rtp_session, smh->mparams->recv_te);
5905 switch_channel_set_variable_printf(session->channel, "rtp_2833_recv_payload", "%d", smh->mparams->recv_te);
5906 }
5907
5908
5909 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Set 2833 dtmf send payload to %u recv payload to %u\n",
5910 switch_channel_get_name(session->channel), smh->mparams->te, smh->mparams->recv_te);
5911
5912
5913 } else {
5914 /* by default, use SIP INFO if 2833 is not in the SDP */
5915 if (!switch_false(switch_channel_get_variable(channel, "rtp_info_when_no_2833"))) {
5916 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No 2833 in SDP. Disable 2833 dtmf and switch to INFO\n");
5917 switch_channel_set_variable(session->channel, "dtmf_type", "info");
5918 smh->mparams->dtmf_type = DTMF_INFO;
5919 smh->mparams->recv_te = smh->mparams->te = 0;
5920 } else {
5921 switch_channel_set_variable(session->channel, "dtmf_type", "none");
5922 smh->mparams->dtmf_type = DTMF_NONE;
5923 smh->mparams->recv_te = smh->mparams->te = 0;
5924 }
5925 }
5926
5927 } else if (!got_text && m->m_type == sdp_media_text && m->m_port) {
5928 sdp_rtpmap_t *map;
5929 payload_map_t *red_pmap = NULL;
5930
5931 switch_channel_set_flag(session->channel, CF_RTT);
5932
5933 connection = sdp->sdp_connection;
5934 if (m->m_connections) {
5935 connection = m->m_connections;
5936 }
5937
5938 if (!connection) {
5939 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");
5940 match = 0;
5941 break;
5942 }
5943
5944 switch_channel_set_variable(session->channel, "text_possible", "true");
5945 switch_channel_set_flag(session->channel, CF_TEXT_SDP_RECVD);
5946 switch_channel_set_flag(session->channel, CF_TEXT_POSSIBLE);
5947
5948 got_text++;
5949
5950 for (map = m->m_rtpmaps; map; map = map->rm_next) {
5951 payload_map_t *pmap;
5952
5953 pmap = switch_core_media_add_payload_map(session,
5954 SWITCH_MEDIA_TYPE_TEXT,
5955 map->rm_encoding,
5956 NULL,
5957 NULL,
5958 SDP_TYPE_REQUEST,
5959 map->rm_pt,
5960 1000,
5961 0,
5962 1,
5963 SWITCH_TRUE);
5964
5965
5966 pmap->remote_sdp_ip = switch_core_session_strdup(session, (char *) connection->c_address);
5967 pmap->remote_sdp_port = (switch_port_t) m->m_port;
5968 if (map->rm_fmtp) {
5969 pmap->rm_fmtp = switch_core_session_strdup(session, (char *) map->rm_fmtp);
5970 }
5971
5972
5973 t_engine->cur_payload_map = pmap;
5974
5975 if (!strcasecmp(map->rm_encoding, "red")) {
5976 red_pmap = pmap;
5977 }
5978 }
5979
5980 if (red_pmap) {
5981 t_engine->cur_payload_map = red_pmap;
5982 }
5983
5984 for (attr = m->m_attributes; attr; attr = attr->a_next) {
5985 if (!strcasecmp(attr->a_name, "rtcp") && attr->a_value) {
5986 switch_channel_set_variable(session->channel, "sip_remote_text_rtcp_port", attr->a_value);
5987
5988 } else if (!got_text_crypto && !strcasecmp(attr->a_name, "crypto") && !zstr(attr->a_value)) {
5989 int crypto_tag;
5990
5991 if (!(smh->mparams->ndlb & SM_NDLB_ALLOW_CRYPTO_IN_AVP) &&
5992 !switch_true(switch_channel_get_variable(session->channel, "rtp_allow_crypto_in_avp"))) {
5993 if (m->m_proto != sdp_proto_srtp && !got_webrtc) {
5994 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "a=crypto in RTP/AVP, refer to rfc3711\n");
5995 match = 0;
5996 goto done;
5997 }
5998 }
5999
6000 crypto = attr->a_value;
6001 crypto_tag = atoi(crypto);
6002
6003 got_text_crypto = switch_core_session_check_incoming_crypto(session,
6004 "rtp_has_text_crypto",
6005 SWITCH_MEDIA_TYPE_TEXT, crypto, crypto_tag, sdp_type);
6006
6007 }
6008 }
6009
6010
6011 //map->rm_encoding
6012 //map->rm_fmtp
6013 //map->rm_pt
6014 //t_engine->cur_payload_map = pmap;
6015
6016 t_engine->codec_negotiated = 1;
6017 tmatch = 1;
6018
6019
6020 if (!t_engine->local_sdp_port) {
6021 switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_TEXT, 1);
6022 }
6023
6024 check_ice(smh, SWITCH_MEDIA_TYPE_TEXT, sdp, m);
6025 //parse rtt
6026
6027 } else if (m->m_type == sdp_media_video) {
6028 sdp_rtpmap_t *map;
6029 const char *rm_encoding;
6030 const switch_codec_implementation_t *mimp = NULL;
6031 int i;
6032 const char *inherit_video_fmtp = NULL;
6033
6034 switch_core_media_set_rmode(smh->session, SWITCH_MEDIA_TYPE_VIDEO, sdp_media_flow(m->m_mode), sdp_type);
6035
6036 if (sdp_type == SDP_TYPE_REQUEST) {
6037 sdp_bandwidth_t *bw;
6038 int tias = 0;
6039
6040 for (bw = m->m_bandwidths; bw; bw = bw->b_next) {
6041 if (bw->b_modifier == sdp_bw_as && !tias) {
6042 v_engine->sdp_bw = bw->b_value;
6043 } else if (bw->b_modifier == sdp_bw_tias) {
6044 tias = 1;
6045 v_engine->sdp_bw = bw->b_value / 1024;
6046 }
6047 }
6048
6049 switch(v_engine->rmode) {
6050 case SWITCH_MEDIA_FLOW_RECVONLY:
6051 switch_core_media_set_smode(smh->session, SWITCH_MEDIA_TYPE_VIDEO, SWITCH_MEDIA_FLOW_SENDONLY, sdp_type);
6052 switch_channel_set_flag(smh->session->channel, CF_VIDEO_READY);
6053 break;
6054 case SWITCH_MEDIA_FLOW_SENDONLY:
6055 switch_core_media_set_smode(smh->session, SWITCH_MEDIA_TYPE_VIDEO, SWITCH_MEDIA_FLOW_RECVONLY, sdp_type);
6056 break;
6057 case SWITCH_MEDIA_FLOW_INACTIVE:
6058 switch_core_media_set_smode(smh->session, SWITCH_MEDIA_TYPE_VIDEO, SWITCH_MEDIA_FLOW_INACTIVE, sdp_type);
6059 break;
6060 default:
6061 switch_core_media_set_smode(smh->session, SWITCH_MEDIA_TYPE_VIDEO, SWITCH_MEDIA_FLOW_SENDRECV, sdp_type);
6062 break;
6063 }
6064 }
6065
6066 if (!m->m_port) {
6067 goto endsdp;
6068 }
6069
6070 vmatch = 0;
6071 almost_vmatch = 0;
6072 m_idx = 0;
6073 memset(matches, 0, sizeof(matches[0]) * MAX_MATCHES);
6074 memset(near_matches, 0, sizeof(near_matches[0]) * MAX_MATCHES);
6075
6076 switch_channel_set_variable(session->channel, "video_possible", "true");
6077 switch_channel_set_flag(session->channel, CF_VIDEO_POSSIBLE);
6078 switch_channel_set_flag(session->channel, CF_VIDEO_SDP_RECVD);
6079
6080 connection = sdp->sdp_connection;
6081 if (m->m_connections) {
6082 connection = m->m_connections;
6083 }
6084
6085 if (!connection) {
6086 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");
6087 match = 0;
6088 break;
6089 }
6090
6091
6092
6093 skip_video_rtcp = 0;
6094 got_video_rtcp_mux = 0;
6095 for (attr = m->m_attributes; attr; attr = attr->a_next) {
6096 if (!strcasecmp(attr->a_name, "rtcp-mux")) {
6097 got_video_rtcp_mux = 1;
6098 skip_video_rtcp = 1;
6099 } else if (!strcasecmp(attr->a_name, "ice-ufrag")) {
6100 skip_video_rtcp = 1;
6101 }
6102 }
6103
6104 if (!got_video_rtcp_mux) {
6105 v_engine->rtcp_mux = -1;
6106 }
6107
6108 for (attr = m->m_attributes; attr; attr = attr->a_next) {
6109 if (!strcasecmp(attr->a_name, "framerate") && attr->a_value) {
6110 //framerate = atoi(attr->a_value);
6111 } else if (!strcasecmp(attr->a_name, "rtcp-fb")) {
6112 if (!zstr(attr->a_value)) {
6113 if (switch_stristr("fir", attr->a_value)) {
6114 v_engine->fir++;
6115 }
6116
6117 if (switch_stristr("pli", attr->a_value)) {
6118 v_engine->pli++;
6119 }
6120
6121 if (switch_stristr("nack", attr->a_value)) {
6122 v_engine->nack++;
6123 }
6124
6125 if (switch_stristr("tmmbr", attr->a_value)) {
6126 v_engine->tmmbr++;
6127 }
6128
6129 rtcp_auto_video = 1;
6130 smh->mparams->rtcp_video_interval_msec = SWITCH_RTCP_VIDEO_INTERVAL_MSEC;
6131 }
6132 } else if (!strcasecmp(attr->a_name, "rtcp") && attr->a_value && !skip_video_rtcp) {
6133 v_engine->remote_rtcp_port = (switch_port_t)atoi(attr->a_value);
6134 switch_channel_set_variable_printf(session->channel, "rtp_remote_video_rtcp_port", "%d", v_engine->remote_rtcp_port);
6135 if (!smh->mparams->rtcp_video_interval_msec) {
6136 smh->mparams->rtcp_video_interval_msec = SWITCH_RTCP_VIDEO_INTERVAL_MSEC;
6137 }
6138 got_video_rtcp = 1;
6139 } else if (!got_video_crypto && !strcasecmp(attr->a_name, "crypto") && !zstr(attr->a_value)) {
6140 int crypto_tag;
6141
6142 if (!(smh->mparams->ndlb & SM_NDLB_ALLOW_CRYPTO_IN_AVP) &&
6143 !switch_true(switch_channel_get_variable(session->channel, "rtp_allow_crypto_in_avp"))) {
6144 if (m->m_proto != sdp_proto_srtp && !got_webrtc) {
6145 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "a=crypto in RTP/AVP, refer to rfc3711\n");
6146 match = 0;
6147 goto done;
6148 }
6149 }
6150
6151 crypto = attr->a_value;
6152 crypto_tag = atoi(crypto);
6153
6154 got_video_crypto = switch_core_session_check_incoming_crypto(session,
6155 "rtp_has_video_crypto",
6156 SWITCH_MEDIA_TYPE_VIDEO, crypto, crypto_tag, sdp_type);
6157
6158 }
6159 }
6160
6161
6162 if (switch_true(switch_channel_get_variable_dup(session->channel, "inherit_codec", SWITCH_FALSE, -1))) {
6163 vmatch_pt = 1;
6164 }
6165
6166 compare:
6167
6168 for (map = m->m_rtpmaps; map; map = map->rm_next) {
6169
6170 if (switch_rtp_has_dtls() && dtls_ok(session)) {
6171 for (attr = m->m_attributes; attr; attr = attr->a_next) {
6172 if (!strcasecmp(attr->a_name, "fingerprint") && !zstr(attr->a_value)) {
6173 got_video_crypto = 1;
6174 }
6175 }
6176 }
6177
6178 if (!(rm_encoding = map->rm_encoding)) {
6179 rm_encoding = "";
6180 }
6181
6182 for (i = 0; i < total_codecs; i++) {
6183 const switch_codec_implementation_t *imp = codec_array[i];
6184
6185 if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO) {
6186 continue;
6187 }
6188
6189 if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_INBOUND &&
6190 switch_channel_test_flag(session->channel, CF_NOVIDEO)) {
6191 continue;
6192 }
6193
6194 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Video Codec Compare [%s:%d]/[%s:%d]\n",
6195 rm_encoding, map->rm_pt, imp->iananame, imp->ianacode);
6196 if ((zstr(map->rm_encoding) || (smh->mparams->ndlb & SM_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) {
6197 vmatch = (map->rm_pt == imp->ianacode) ? 1 : 0;
6198 } else {
6199 vmatch = strcasecmp(rm_encoding, imp->iananame) ? 0 : 1;
6200 }
6201
6202 if (sdp_type == SDP_TYPE_RESPONSE && consider_video_fmtp && vmatch && !zstr(map->rm_fmtp) && !zstr(smh->fmtps[i])) {
6203 almost_vmatch = 1;
6204 vmatch = !strcasecmp(smh->fmtps[i], map->rm_fmtp);
6205 }
6206
6207 if (vmatch && vmatch_pt) {
6208 const char *other_pt = switch_channel_get_variable_partner(channel, "rtp_video_pt");
6209
6210 if (other_pt) {
6211 int opt = atoi(other_pt);
6212 if (map->rm_pt != opt) {
6213 vmatch = 0;
6214 } else {
6215 if (switch_channel_var_true(channel, "inherit_video_fmtp")) {
6216 inherit_video_fmtp = switch_channel_get_variable_partner(channel, "rtp_video_fmtp");
6217 }
6218 }
6219 }
6220 }
6221
6222 if (vmatch) {
6223 matches[m_idx].imp = imp;
6224 matches[m_idx].map = map;
6225
6226 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Video Codec Compare [%s:%d] +++ is saved as a match\n",
6227 imp->iananame, map->rm_pt);
6228
6229 m_idx++;
6230 }
6231
6232 vmatch = 0;
6233 }
6234 }
6235
6236 if (consider_video_fmtp && (!m_idx || almost_vmatch)) {
6237 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No matches with FTMP, fallback to ignoring FMTP\n");
6238 almost_vmatch = 0;
6239 m_idx = 0;
6240 consider_video_fmtp = 0;
6241 goto compare;
6242 }
6243
6244 if (vmatch_pt && !m_idx) {
6245 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No matches with inherit_codec, fallback to ignoring PT\n");
6246 vmatch_pt = 0;
6247 goto compare;
6248 }
6249
6250 if (smh->crypto_mode == CRYPTO_MODE_MANDATORY && got_video_crypto < 1) {
6251 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Crypto not negotiated but required.\n");
6252 vmatch = 0;
6253 m_idx = 0;
6254 }
6255
6256 if (m_idx) {
6257 char tmp[50];
6258 //const char *mirror = switch_channel_get_variable(session->channel, "rtp_mirror_remote_video_codec_payload");
6259 int j = 0;
6260
6261 if (greedy) { /* sort in favor of mine */
6262 greedy_sort(smh, matches, m_idx, codec_array, total_codecs);
6263 }
6264
6265 vmatch = 1;
6266 v_engine->codec_negotiated = 1;
6267 v_engine->payload_map = NULL;
6268
6269 for(j = 0; j < m_idx && smh->num_negotiated_codecs < SWITCH_MAX_CODECS; j++) {
6270 payload_map_t *pmap = switch_core_media_add_payload_map(session,
6271 SWITCH_MEDIA_TYPE_VIDEO,
6272 matches[j].map->rm_encoding,
6273 matches[j].imp->modname,
6274 consider_video_fmtp ? matches[j].map->rm_fmtp : NULL,
6275 sdp_type,
6276 matches[j].map->rm_pt,
6277 matches[j].imp->samples_per_second,
6278 matches[j].imp->microseconds_per_packet / 1000,
6279 matches[j].imp->number_of_channels,
6280 SWITCH_TRUE);
6281
6282 if (j == 0) {
6283 v_engine->cur_payload_map = pmap;
6284 v_engine->cur_payload_map->current = 1;
6285 if (v_engine->rtp_session) {
6286 switch_rtp_set_default_payload(v_engine->rtp_session, pmap->pt);
6287 }
6288 }
6289
6290 mimp = matches[j].imp;
6291 map = matches[j].map;
6292
6293 pmap->rm_encoding = switch_core_session_strdup(session, (char *) map->rm_encoding);
6294 pmap->recv_pt = (switch_payload_t) map->rm_pt;
6295 pmap->rm_rate = map->rm_rate;
6296 pmap->codec_ms = mimp->microseconds_per_packet / 1000;
6297
6298
6299 pmap->remote_sdp_ip = switch_core_session_strdup(session, (char *) connection->c_address);
6300 pmap->remote_sdp_port = (switch_port_t) m->m_port;
6301 pmap->rm_fmtp = switch_core_session_strdup(session, (char *) inherit_video_fmtp ? inherit_video_fmtp : map->rm_fmtp);
6302 smh->negotiated_codecs[smh->num_negotiated_codecs++] = mimp;
6303
6304 #if 0
6305 if (j == 0 && (!switch_true(mirror) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND)) {
6306 switch_core_media_get_offered_pt(session, mimp, &pmap->recv_pt);
6307 }
6308 #endif
6309 }
6310
6311 switch_snprintf(tmp, sizeof(tmp), "%d", v_engine->cur_payload_map->remote_sdp_port);
6312 switch_channel_set_variable(session->channel, SWITCH_REMOTE_VIDEO_IP_VARIABLE, v_engine->cur_payload_map->remote_sdp_ip);
6313 switch_channel_set_variable(session->channel, SWITCH_REMOTE_VIDEO_PORT_VARIABLE, tmp);
6314 switch_channel_set_variable(session->channel, "rtp_video_fmtp", v_engine->cur_payload_map->rm_fmtp);
6315 switch_snprintf(tmp, sizeof(tmp), "%d", v_engine->cur_payload_map->pt);
6316 switch_channel_set_variable(session->channel, "rtp_video_pt", tmp);
6317 switch_core_media_check_video_codecs(session);
6318 switch_snprintf(tmp, sizeof(tmp), "%d", v_engine->cur_payload_map->recv_pt);
6319 switch_channel_set_variable(session->channel, "rtp_video_recv_pt", tmp);
6320
6321 if (switch_core_codec_ready(&v_engine->read_codec) && strcasecmp(matches[0].imp->iananame, v_engine->read_codec.implementation->iananame)) {
6322 v_engine->reset_codec = 1;
6323 }
6324
6325 if (switch_core_media_set_video_codec(session, 0) == SWITCH_STATUS_SUCCESS) {
6326 if (check_ice(smh, SWITCH_MEDIA_TYPE_VIDEO, sdp, m) == SWITCH_STATUS_FALSE) {
6327 vmatch = 0;
6328 }
6329 }
6330 }
6331
6332 video_port = m->m_port;
6333 }
6334 }
6335
6336 endsdp:
6337
6338 if (rtcp_auto_audio || rtcp_auto_video) {
6339 if (rtcp_auto_audio && !skip_rtcp && !got_audio_rtcp && audio_port) {
6340 switch_channel_set_variable_printf(session->channel, "rtp_remote_audio_rtcp_port", "%d", audio_port + 1);
6341 a_engine->remote_rtcp_port = audio_port + 1;
6342
6343 if (!smh->mparams->rtcp_audio_interval_msec) {
6344 smh->mparams->rtcp_audio_interval_msec = SWITCH_RTCP_AUDIO_INTERVAL_MSEC;
6345 }
6346 }
6347 if (rtcp_auto_video && !skip_video_rtcp && !got_video_rtcp && video_port) {
6348 switch_channel_set_variable_printf(session->channel, "rtp_remote_video_rtcp_port", "%d", video_port + 1);
6349 v_engine->remote_rtcp_port = video_port + 1;
6350 if (!smh->mparams->rtcp_video_interval_msec) {
6351 smh->mparams->rtcp_video_interval_msec = SWITCH_RTCP_VIDEO_INTERVAL_MSEC;
6352 }
6353 }
6354 }
6355
6356
6357 if (!saw_audio) {
6358 payload_map_t *pmap;
6359
6360 a_engine->rmode = SWITCH_MEDIA_FLOW_DISABLED;
6361 switch_channel_set_variable(smh->session->channel, "audio_media_flow", "inactive");
6362
6363
6364 pmap = switch_core_media_add_payload_map(session,
6365 SWITCH_MEDIA_TYPE_AUDIO,
6366 "L16",
6367 NULL,
6368 NULL,
6369 SDP_TYPE_REQUEST,
6370 97,
6371 8000,
6372 20,
6373 1,
6374 SWITCH_TRUE);
6375
6376 pmap->remote_sdp_ip = "127.0.0.1";
6377 pmap->remote_sdp_port = 9999;
6378 pmap->pt = 97;
6379 pmap->recv_pt = 97;
6380 pmap->codec_ms = 20;
6381 a_engine->cur_payload_map = pmap;
6382 switch_channel_set_flag(channel, CF_AUDIO_PAUSE_READ);
6383 switch_channel_set_flag(channel, CF_AUDIO_PAUSE_WRITE);
6384 }
6385
6386 done:
6387
6388 if (v_engine->rtp_session) {
6389 if (v_engine->fir) {
6390 switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_FIR);
6391 } else {
6392 switch_rtp_clear_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_FIR);
6393 }
6394
6395 if (v_engine->pli) {
6396 switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_PLI);
6397 } else {
6398 switch_rtp_clear_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_PLI);
6399 }
6400
6401 if (v_engine->nack) {
6402 switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_NACK);
6403 } else {
6404 switch_rtp_clear_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_NACK);
6405 }
6406
6407 if (v_engine->tmmbr) {
6408 switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_TMMBR);
6409 } else {
6410 switch_rtp_clear_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_TMMBR);
6411 }
6412 }
6413
6414 if (match) {
6415 switch_channel_set_flag(channel, CF_AUDIO);
6416 } else {
6417 switch_channel_clear_flag(channel, CF_AUDIO);
6418 }
6419
6420 if (vmatch) {
6421 switch_channel_set_flag(channel, CF_VIDEO);
6422 } else {
6423 if (switch_channel_test_flag(channel, CF_VIDEO) && !saw_video) {
6424 //switch_core_media_set_rmode(smh->session, SWITCH_MEDIA_TYPE_VIDEO, SWITCH_MEDIA_FLOW_INACTIVE, sdp_type);
6425
6426 if (sdp_type == SDP_TYPE_REQUEST) {
6427 switch_core_media_set_smode(smh->session, SWITCH_MEDIA_TYPE_VIDEO, SWITCH_MEDIA_FLOW_INACTIVE, sdp_type);
6428 }
6429 }
6430 }
6431
6432 if (tmatch) {
6433 switch_channel_set_flag(channel, CF_HAS_TEXT);
6434 } else {
6435 switch_channel_clear_flag(channel, CF_HAS_TEXT);
6436 }
6437
6438 if (fmatch) {
6439 switch_channel_set_flag(channel, CF_IMAGE_SDP);
6440 switch_channel_set_flag(channel, CF_AUDIO);
6441 } else {
6442 switch_channel_clear_flag(channel, CF_IMAGE_SDP);
6443 }
6444
6445 t38_done:
6446
6447 if (parser) {
6448 sdp_parser_free(parser);
6449 }
6450
6451 smh->mparams->cng_pt = cng_pt;
6452 smh->mparams->cng_rate = cng_rate;
6453
6454 check_stream_changes(session, r_sdp, sdp_type);
6455
6456 return match || vmatch || tmatch || fmatch;
6457 }
6458
6459 //?
switch_core_media_reset_t38(switch_core_session_t * session)6460 SWITCH_DECLARE(void) switch_core_media_reset_t38(switch_core_session_t *session)
6461 {
6462 switch_rtp_engine_t *a_engine;
6463 switch_media_handle_t *smh;
6464 switch_channel_t *channel = switch_core_session_get_channel(session);
6465
6466 switch_assert(session);
6467
6468 if (!(smh = session->media_handle)) {
6469 return;
6470 }
6471
6472 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
6473
6474 restore_pmaps(a_engine);
6475
6476 switch_channel_set_private(channel, "t38_options", NULL);
6477 switch_channel_clear_flag(channel, CF_T38_PASSTHRU);
6478 switch_channel_clear_app_flag_key("T38", channel, CF_APP_T38);
6479 switch_channel_clear_app_flag_key("T38", channel, CF_APP_T38_REQ);
6480 switch_channel_set_app_flag_key("T38", channel, CF_APP_T38_FAIL);
6481 }
6482
6483 //?
6484
switch_core_media_toggle_hold(switch_core_session_t * session,int sendonly)6485 SWITCH_DECLARE(int) switch_core_media_toggle_hold(switch_core_session_t *session, int sendonly)
6486 {
6487 int changed = 0;
6488 switch_rtp_engine_t *a_engine, *v_engine;
6489 switch_media_handle_t *smh;
6490 switch_core_session_t *b_session = NULL;
6491 switch_channel_t *b_channel = NULL;
6492
6493 switch_assert(session);
6494
6495 if (!(smh = session->media_handle)) {
6496 return 0;
6497 }
6498
6499 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
6500 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
6501
6502
6503 if (switch_core_session_get_partner(session, &b_session) == SWITCH_STATUS_SUCCESS) {
6504 b_channel = switch_core_session_get_channel(b_session);
6505 }
6506
6507 if (sendonly && switch_channel_test_flag(session->channel, CF_ANSWERED)) {
6508 if (!switch_channel_test_flag(session->channel, CF_PROTO_HOLD)) {
6509 const char *stream;
6510 const char *msg = "hold";
6511 const char *info;
6512
6513 if ((switch_channel_test_flag(session->channel, CF_SLA_BARGE) || switch_channel_test_flag(session->channel, CF_SLA_BARGING)) &&
6514 (!b_channel || switch_channel_test_flag(b_channel, CF_EVENT_LOCK_PRI))) {
6515 switch_channel_mark_hold(session->channel, sendonly);
6516 switch_channel_set_flag(session->channel, CF_PROTO_HOLD);
6517 changed = 0;
6518 goto end;
6519 }
6520
6521 info = switch_channel_get_variable(session->channel, "presence_call_info");
6522
6523 if (info) {
6524 if (switch_stristr("private", info)) {
6525 msg = "hold-private";
6526 }
6527 }
6528
6529 if (a_engine->rtp_session) {
6530 switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PAUSE);
6531 }
6532
6533 if (v_engine->rtp_session) {
6534 switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_PAUSE);
6535 }
6536
6537 switch_channel_set_flag(session->channel, CF_PROTO_HOLD);
6538 switch_channel_mark_hold(session->channel, SWITCH_TRUE);
6539 switch_channel_presence(session->channel, "unknown", msg, NULL);
6540 changed = 1;
6541
6542 if (a_engine->max_missed_hold_packets && a_engine->rtp_session) {
6543 switch_rtp_set_max_missed_packets(a_engine->rtp_session, a_engine->max_missed_hold_packets);
6544 }
6545
6546 if (a_engine->media_hold_timeout) {
6547 switch_rtp_set_media_timeout(a_engine->rtp_session, a_engine->media_hold_timeout);
6548 }
6549
6550 if (v_engine->media_hold_timeout) {
6551 switch_rtp_set_media_timeout(v_engine->rtp_session, v_engine->media_hold_timeout);
6552 }
6553
6554
6555 if (!(stream = switch_channel_get_hold_music(session->channel))) {
6556 stream = "local_stream://moh";
6557 }
6558
6559
6560 if (stream && strcasecmp(stream, "silence") && (!b_channel || !switch_channel_test_flag(b_channel, CF_EVENT_LOCK_PRI))) {
6561 if (!strcasecmp(stream, "indicate_hold")) {
6562 switch_channel_set_flag(session->channel, CF_SUSPEND);
6563 switch_channel_set_flag(session->channel, CF_HOLD);
6564 switch_ivr_hold_uuid(switch_core_session_get_uuid(b_session), NULL, 0);
6565 } else {
6566 switch_ivr_broadcast(switch_core_session_get_uuid(b_session), stream,
6567 SMF_ECHO_ALEG | SMF_LOOP | SMF_PRIORITY);
6568 switch_yield(250000);
6569 }
6570 }
6571
6572 }
6573 } else {
6574 if (switch_channel_test_flag(session->channel, CF_HOLD_LOCK)) {
6575 switch_channel_set_flag(session->channel, CF_PROTO_HOLD);
6576 switch_channel_mark_hold(session->channel, SWITCH_TRUE);
6577
6578 if (a_engine->rtp_session) {
6579 switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PAUSE);
6580 }
6581
6582 if (v_engine->rtp_session) {
6583 switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_PAUSE);
6584 }
6585
6586 changed = 1;
6587 }
6588
6589 switch_channel_clear_flag(session->channel, CF_HOLD_LOCK);
6590
6591 if (switch_channel_test_flag(session->channel, CF_PROTO_HOLD)) {
6592 int media_on_hold_a = switch_true(switch_channel_get_variable_dup(session->channel, "bypass_media_resume_on_hold", SWITCH_FALSE, -1));
6593 int media_on_hold_b = 0;
6594 int bypass_after_hold_a = 0;
6595 int bypass_after_hold_b = 0;
6596
6597 if (media_on_hold_a) {
6598 bypass_after_hold_a = switch_true(switch_channel_get_variable_dup(session->channel, "bypass_media_after_hold", SWITCH_FALSE, -1));
6599 }
6600
6601 if (b_channel) {
6602 if ((media_on_hold_b = switch_true(switch_channel_get_variable_dup(b_channel, "bypass_media_resume_on_hold", SWITCH_FALSE, -1)))) {
6603 bypass_after_hold_b = switch_true(switch_channel_get_variable_dup(b_channel, "bypass_media_after_hold", SWITCH_FALSE, -1));
6604 }
6605 }
6606
6607 switch_yield(250000);
6608
6609 if (b_channel && (switch_channel_test_flag(session->channel, CF_BYPASS_MEDIA_AFTER_HOLD) ||
6610 switch_channel_test_flag(b_channel, CF_BYPASS_MEDIA_AFTER_HOLD) || bypass_after_hold_a || bypass_after_hold_b)) {
6611 /* try to stay out from media stream */
6612 switch_ivr_bg_media(switch_core_session_get_uuid(session), SMF_REBRIDGE, SWITCH_FALSE, SWITCH_TRUE, 200);
6613 }
6614
6615 if (a_engine->rtp_session) {
6616 switch_rtp_reset_media_timer(a_engine->rtp_session);
6617
6618 if (a_engine->max_missed_packets) {
6619 switch_rtp_set_max_missed_packets(a_engine->rtp_session, a_engine->max_missed_packets);
6620 }
6621
6622 if (a_engine->media_hold_timeout) {
6623 switch_rtp_set_media_timeout(a_engine->rtp_session, a_engine->media_timeout);
6624 }
6625 }
6626
6627 if (v_engine->rtp_session) {
6628 switch_rtp_reset_media_timer(v_engine->rtp_session);
6629
6630 if (v_engine->media_hold_timeout) {
6631 switch_rtp_set_media_timeout(v_engine->rtp_session, v_engine->media_timeout);
6632 }
6633 }
6634
6635 if (b_channel) {
6636 if (switch_channel_test_flag(session->channel, CF_HOLD)) {
6637 switch_ivr_unhold(b_session);
6638 switch_channel_clear_flag(session->channel, CF_SUSPEND);
6639 switch_channel_clear_flag(session->channel, CF_HOLD);
6640 } else {
6641 switch_channel_stop_broadcast(b_channel);
6642 switch_channel_wait_for_flag(b_channel, CF_BROADCAST, SWITCH_FALSE, 5000, NULL);
6643 }
6644 }
6645
6646 switch_core_media_check_autoadj(session);
6647
6648 switch_channel_clear_flag(session->channel, CF_PROTO_HOLD);
6649 switch_channel_mark_hold(session->channel, SWITCH_FALSE);
6650 switch_channel_presence(session->channel, "unknown", "unhold", NULL);
6651
6652 if (a_engine->rtp_session) {
6653 switch_rtp_clear_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PAUSE);
6654 }
6655
6656 if (v_engine->rtp_session) {
6657 switch_rtp_clear_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_PAUSE);
6658 }
6659
6660 changed = 1;
6661 }
6662 }
6663
6664
6665 end:
6666 switch_core_session_request_video_refresh(session);
6667
6668
6669 if (b_session) {
6670 switch_core_session_request_video_refresh(b_session);
6671 switch_core_session_rwunlock(b_session);
6672 }
6673
6674
6675 return changed;
6676 }
6677
6678
switch_core_media_get_video_file(switch_core_session_t * session,switch_rw_t rw)6679 SWITCH_DECLARE(switch_file_handle_t *) switch_core_media_get_video_file(switch_core_session_t *session, switch_rw_t rw)
6680 {
6681 switch_media_handle_t *smh;
6682 switch_rtp_engine_t *v_engine;
6683 switch_file_handle_t *fh;
6684
6685 switch_assert(session);
6686
6687 if (!switch_channel_test_flag(session->channel, CF_VIDEO)) {
6688 return NULL;
6689 }
6690
6691 if (!(smh = session->media_handle)) {
6692 return NULL;
6693 }
6694
6695 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
6696
6697
6698
6699 if (rw == SWITCH_RW_READ) {
6700 switch_mutex_lock(v_engine->mh.file_read_mutex);
6701 fh = smh->video_read_fh;
6702 switch_mutex_unlock(v_engine->mh.file_read_mutex);
6703 } else {
6704 switch_mutex_lock(v_engine->mh.file_write_mutex);
6705 fh = smh->video_write_fh;
6706 switch_mutex_unlock(v_engine->mh.file_write_mutex);
6707 }
6708
6709
6710
6711 return fh;
6712 }
6713
switch_core_session_write_blank_video(switch_core_session_t * session,uint32_t ms)6714 SWITCH_DECLARE(void) switch_core_session_write_blank_video(switch_core_session_t *session, uint32_t ms)
6715 {
6716 switch_frame_t fr = { 0 };
6717 int i = 0;
6718 switch_rgb_color_t bgcolor = { 0 };
6719 int buflen = SWITCH_RTP_MAX_BUF_LEN;
6720 unsigned char buf[SWITCH_RTP_MAX_BUF_LEN];
6721 switch_media_handle_t *smh;
6722 switch_image_t *blank_img = NULL;
6723 uint32_t frames = 0, frame_ms = 0;
6724 uint32_t fps, width, height;
6725 switch_assert(session != NULL);
6726
6727 if (!(smh = session->media_handle)) {
6728 return;
6729 }
6730
6731 fps = smh->vid_params.fps;
6732 width = smh->vid_params.width;
6733 height = smh->vid_params.height;
6734
6735 if (!width) width = 352;
6736 if (!height) height = 288;
6737 if (!fps) fps = 15;
6738
6739 if (!(width && height && fps)) {
6740 return;
6741 }
6742
6743 fr.packet = buf;
6744 fr.packetlen = buflen;
6745 fr.data = buf + 12;
6746 fr.buflen = buflen - 12;
6747
6748
6749 blank_img = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, width, height, 1);
6750 switch_color_set_rgb(&bgcolor, "#000000");
6751 switch_img_fill(blank_img, 0, 0, blank_img->d_w, blank_img->d_h, &bgcolor);
6752
6753 if (fps < 15) fps = 15;
6754 frame_ms = (uint32_t) 1000 / fps;
6755 if (frame_ms <= 0) frame_ms = 66;
6756 frames = (uint32_t) ms / frame_ms;
6757
6758 switch_core_media_gen_key_frame(session);
6759 for (i = 0; i < frames; i++) {
6760 fr.img = blank_img;
6761 switch_core_session_write_video_frame(session, &fr, SWITCH_IO_FLAG_NONE, 0);
6762 switch_yield(frame_ms * 1000);
6763 }
6764 switch_core_media_gen_key_frame(session);
6765
6766 switch_img_free(&blank_img);
6767
6768 }
6769
video_write_thread(switch_thread_t * thread,void * obj)6770 static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void *obj)
6771 {
6772 switch_core_session_t *session = (switch_core_session_t *) obj;
6773 switch_media_handle_t *smh;
6774 unsigned char *buf = NULL;
6775 switch_frame_t fr = { 0 };
6776 switch_rtp_engine_t *v_engine;
6777 int buflen = SWITCH_RTP_MAX_BUF_LEN;
6778 switch_timer_t timer = { 0 };
6779 switch_video_read_flag_t read_flags = SVR_BLOCK;
6780 switch_core_session_t *b_session = NULL;
6781 switch_fps_t fps_data = { 0 };
6782 float fps;
6783 switch_image_t *last_frame = NULL;
6784
6785 if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) {
6786 return NULL;
6787 }
6788
6789 if (!(smh = session->media_handle)) {
6790 return NULL;
6791 }
6792
6793 switch_core_session_get_partner(session, &b_session);
6794
6795 switch_channel_set_flag(session->channel, CF_VIDEO_WRITING);
6796
6797 if (b_session) {
6798 switch_channel_set_flag(b_session->channel, CF_VIDEO_BLANK);
6799 }
6800
6801 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
6802
6803 switch_mutex_lock(smh->write_mutex[SWITCH_MEDIA_TYPE_VIDEO]);
6804 v_engine->thread_write_lock = switch_thread_self();
6805
6806
6807 buf = switch_core_session_alloc(session, buflen);
6808 fr.packet = buf;
6809 fr.packetlen = buflen;
6810 fr.data = buf + 12;
6811 fr.buflen = buflen - 12;
6812 switch_core_media_gen_key_frame(session);
6813
6814
6815 if (smh->video_write_fh && smh->video_write_fh->mm.source_fps) {
6816 fps = smh->video_write_fh->mm.source_fps;
6817 } else if (video_globals.fps) {
6818 fps = video_globals.fps;
6819 } else {
6820 fps = 15;
6821 }
6822 switch_calc_video_fps(&fps_data, fps);
6823
6824 switch_core_timer_init(&timer, "soft", fps_data.ms, fps_data.samples, switch_core_session_get_pool(session));
6825
6826 while (smh->video_write_thread_running > 0 &&
6827 switch_channel_up_nosig(session->channel) && smh->video_write_fh && switch_test_flag(smh->video_write_fh, SWITCH_FILE_OPEN)) {
6828 switch_status_t wstatus = SWITCH_STATUS_FALSE;
6829
6830 switch_core_timer_next(&timer);
6831 switch_mutex_lock(v_engine->mh.file_write_mutex);
6832
6833 //if (smh->video_write_fh && smh->video_write_fh->mm.source_fps && smh->video_write_fh->mm.source_fps != fps) {
6834 // switch_core_timer_destroy(&timer);
6835 // switch_calc_video_fps(&fps_data, fps);
6836 // switch_core_timer_init(&timer, "soft", fps_data.ms, fps_data.samples, switch_core_session_get_pool(session));
6837 //}
6838
6839 if (smh->video_write_fh && !switch_test_flag(smh->video_write_fh, SWITCH_FILE_FLAG_VIDEO_EOF)) {
6840 wstatus = switch_core_file_read_video(smh->video_write_fh, &fr, read_flags);
6841
6842 if (wstatus == SWITCH_STATUS_SUCCESS) {
6843 fr.timestamp = timer.samplecount;
6844 fr.flags = SFF_USE_VIDEO_TIMESTAMP|SFF_RAW_RTP|SFF_RAW_RTP_PARSE_FRAME;
6845
6846 if (smh->vid_params.d_width && smh->vid_params.d_height) {
6847 switch_img_fit(&fr.img, smh->vid_params.d_width, smh->vid_params.d_height, SWITCH_FIT_SIZE);
6848 }
6849
6850 switch_core_session_write_video_frame(session, &fr, SWITCH_IO_FLAG_FORCE, 0);
6851
6852 switch_img_free(&last_frame);
6853 last_frame = fr.img;
6854 fr.img = NULL;
6855
6856 } else if (wstatus != SWITCH_STATUS_BREAK && wstatus != SWITCH_STATUS_IGNORE) {
6857 switch_set_flag_locked(smh->video_write_fh, SWITCH_FILE_FLAG_VIDEO_EOF);
6858 }
6859 }
6860 switch_mutex_unlock(v_engine->mh.file_write_mutex);
6861 }
6862
6863 if (last_frame) {
6864 int x = 0;
6865 switch_rgb_color_t bgcolor;
6866 switch_color_set_rgb(&bgcolor, "#000000");
6867 switch_img_fill(last_frame, 0, 0, last_frame->d_w, last_frame->d_h, &bgcolor);
6868 fr.img = last_frame;
6869
6870 for (x = 0; x < (int)(fps_data.fps / 2); x++) {
6871 switch_core_timer_next(&timer);
6872 fr.timestamp = timer.samplecount;
6873 fr.flags = SFF_USE_VIDEO_TIMESTAMP|SFF_RAW_RTP|SFF_RAW_RTP_PARSE_FRAME;
6874 switch_core_session_write_video_frame(session, &fr, SWITCH_IO_FLAG_FORCE, 0);
6875 }
6876 switch_core_media_gen_key_frame(session);
6877 switch_core_session_request_video_refresh(session);
6878 switch_img_free(&last_frame);
6879 }
6880
6881
6882 switch_core_timer_destroy(&timer);
6883
6884 switch_core_session_rwunlock(session);
6885
6886 if (b_session) {
6887 switch_channel_clear_flag(b_session->channel, CF_VIDEO_BLANK);
6888 switch_core_session_rwunlock(b_session);
6889 }
6890
6891
6892 v_engine->thread_write_lock = 0;
6893 switch_mutex_unlock(smh->write_mutex[SWITCH_MEDIA_TYPE_VIDEO]);
6894
6895 switch_channel_clear_flag(session->channel, CF_VIDEO_WRITING);
6896 smh->video_write_thread_running = 0;
6897
6898 return NULL;
6899 }
6900
switch_core_media_lock_video_file(switch_core_session_t * session,switch_rw_t rw)6901 SWITCH_DECLARE(switch_status_t) switch_core_media_lock_video_file(switch_core_session_t *session, switch_rw_t rw)
6902 {
6903 switch_media_handle_t *smh;
6904 switch_rtp_engine_t *v_engine;
6905
6906 switch_assert(session);
6907
6908 if (!switch_channel_test_flag(session->channel, CF_VIDEO)) {
6909 return SWITCH_STATUS_FALSE;
6910 }
6911
6912 if (!(smh = session->media_handle)) {
6913 return SWITCH_STATUS_FALSE;
6914 }
6915
6916 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
6917
6918 if (rw == SWITCH_RW_READ) {
6919 switch_mutex_lock(v_engine->mh.file_read_mutex);
6920 } else {
6921 switch_mutex_lock(v_engine->mh.file_write_mutex);
6922 }
6923
6924 return SWITCH_STATUS_SUCCESS;
6925
6926 }
6927
switch_core_media_unlock_video_file(switch_core_session_t * session,switch_rw_t rw)6928 SWITCH_DECLARE(switch_status_t) switch_core_media_unlock_video_file(switch_core_session_t *session, switch_rw_t rw)
6929 {
6930 switch_media_handle_t *smh;
6931 switch_rtp_engine_t *v_engine;
6932
6933 switch_assert(session);
6934
6935 if (!switch_channel_test_flag(session->channel, CF_VIDEO)) {
6936 return SWITCH_STATUS_FALSE;
6937 }
6938
6939 if (!(smh = session->media_handle)) {
6940 return SWITCH_STATUS_FALSE;
6941 }
6942
6943 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
6944
6945 if (rw == SWITCH_RW_READ) {
6946 switch_mutex_unlock(v_engine->mh.file_read_mutex);
6947 } else {
6948 switch_mutex_unlock(v_engine->mh.file_write_mutex);
6949 }
6950
6951 return SWITCH_STATUS_SUCCESS;
6952 }
6953
switch_core_media_set_video_file(switch_core_session_t * session,switch_file_handle_t * fh,switch_rw_t rw)6954 SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_file(switch_core_session_t *session, switch_file_handle_t *fh, switch_rw_t rw)
6955 {
6956 switch_media_handle_t *smh;
6957 switch_rtp_engine_t *v_engine;
6958
6959 switch_assert(session);
6960
6961 if (!(smh = session->media_handle)) {
6962 return SWITCH_STATUS_FALSE;
6963 }
6964
6965 if (!smh->video_read_fh && !smh->video_write_fh && !switch_channel_test_flag(session->channel, CF_VIDEO)) {
6966 return SWITCH_STATUS_FALSE;
6967 }
6968
6969 if (fh && !switch_core_file_has_video(fh, SWITCH_TRUE)) {
6970 return SWITCH_STATUS_FALSE;
6971 }
6972
6973 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
6974
6975 switch_core_session_start_video_thread(session);
6976
6977 //if (!v_engine->media_thread) {
6978 // return SWITCH_STATUS_FALSE;
6979 //}
6980
6981
6982
6983 if (rw == SWITCH_RW_READ) {
6984 switch_mutex_lock(v_engine->mh.file_read_mutex);
6985
6986 if (fh && smh->video_read_fh) {
6987 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "File is already open\n");
6988 switch_mutex_unlock(v_engine->mh.file_read_mutex);
6989 return SWITCH_STATUS_FALSE;
6990 }
6991
6992
6993 if (fh) {
6994 switch_channel_set_flag_recursive(session->channel, CF_VIDEO_DECODED_READ);
6995 switch_channel_set_flag(session->channel, CF_VIDEO_READ_FILE_ATTACHED);
6996 } else if (smh->video_read_fh) {
6997 switch_channel_clear_flag_recursive(session->channel, CF_VIDEO_DECODED_READ);
6998 switch_core_session_video_reset(session);
6999 }
7000
7001 if (!fh) {
7002 switch_channel_clear_flag(session->channel, CF_VIDEO_READ_FILE_ATTACHED);
7003 }
7004
7005 smh->video_read_fh = fh;
7006
7007 switch_mutex_unlock(v_engine->mh.file_read_mutex);
7008
7009 } else {
7010 if (!fh && smh->video_write_thread) {
7011 if (smh->video_write_thread_running > 0) {
7012 smh->video_write_thread_running = -1;
7013 }
7014 }
7015
7016 switch_mutex_lock(v_engine->mh.file_write_mutex);
7017
7018 if (fh && smh->video_write_fh) {
7019 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "File is already open\n");
7020 smh->video_write_fh = fh;
7021 switch_mutex_unlock(v_engine->mh.file_write_mutex);
7022 return SWITCH_STATUS_SUCCESS;
7023 }
7024
7025 if (fh) {
7026 switch_channel_set_flag(session->channel, CF_VIDEO_WRITE_FILE_ATTACHED);
7027 } else {
7028 switch_channel_clear_flag(session->channel, CF_VIDEO_WRITE_FILE_ATTACHED);
7029 }
7030
7031 switch_core_media_gen_key_frame(session);
7032 switch_core_session_request_video_refresh(session);
7033
7034 if (fh) {
7035 switch_threadattr_t *thd_attr = NULL;
7036 //switch_core_session_write_blank_video(session, 500);
7037 switch_threadattr_create(&thd_attr, switch_core_session_get_pool(session));
7038 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
7039 smh->video_write_thread_running = 1;
7040 switch_thread_create(&smh->video_write_thread, thd_attr, video_write_thread, session, switch_core_session_get_pool(session));
7041 }
7042
7043 if (!fh && smh->video_write_thread) {
7044 switch_status_t st;
7045
7046 if (smh->video_write_thread_running > 0) {
7047 smh->video_write_thread_running = -1;
7048 }
7049 switch_mutex_unlock(v_engine->mh.file_write_mutex);
7050 switch_thread_join(&st, smh->video_write_thread);
7051 switch_mutex_lock(v_engine->mh.file_write_mutex);
7052 smh->video_write_thread = NULL;
7053 //switch_core_session_write_blank_video(session, 500);
7054 }
7055
7056 smh->video_write_fh = fh;
7057
7058 switch_mutex_unlock(v_engine->mh.file_write_mutex);
7059 }
7060
7061 if (!fh) switch_channel_video_sync(session->channel);
7062
7063 switch_core_session_wake_video_thread(session);
7064
7065
7066 return SWITCH_STATUS_SUCCESS;
7067 }
7068
next_cpu(void)7069 int next_cpu(void)
7070 {
7071 int x = 0;
7072
7073 switch_mutex_lock(video_globals.mutex);
7074 x = video_globals.cur_cpu++;
7075 if (video_globals.cur_cpu == video_globals.cpu_count) {
7076 video_globals.cur_cpu = 0;
7077 }
7078 switch_mutex_unlock(video_globals.mutex);
7079 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Binding to CPU %d\n", x);
7080
7081 return x;
7082 }
7083
switch_core_autobind_cpu(void)7084 SWITCH_DECLARE(void) switch_core_autobind_cpu(void)
7085 {
7086 if (video_globals.cpu_count > 1) {
7087 switch_core_thread_set_cpu_affinity(next_cpu());
7088 }
7089 }
7090
perform_write(switch_core_session_t * session,switch_frame_t * frame,switch_io_flag_t flags,int stream_id)7091 static switch_status_t perform_write(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
7092 {
7093 switch_io_event_hook_write_frame_t *ptr;
7094 switch_status_t status = SWITCH_STATUS_FALSE;
7095 switch_media_handle_t *smh;
7096
7097 switch_assert(session != NULL);
7098
7099 if ((smh = session->media_handle)) {
7100 switch_rtp_engine_t *a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
7101
7102 if (a_engine && a_engine->write_fb && !(flags & SWITCH_IO_FLAG_QUEUED)) {
7103 switch_frame_t *dupframe = NULL;
7104
7105 if (switch_frame_buffer_dup(a_engine->write_fb, frame, &dupframe) == SWITCH_STATUS_SUCCESS) {
7106 switch_frame_buffer_push(a_engine->write_fb, dupframe);
7107 dupframe = NULL;
7108 return SWITCH_STATUS_SUCCESS;
7109 }
7110 }
7111 }
7112
7113 if (session->bugs && !(frame->flags & SFF_NOT_AUDIO)) {
7114 switch_media_bug_t *bp;
7115 switch_bool_t ok = SWITCH_TRUE;
7116 int prune = 0;
7117
7118 switch_thread_rwlock_rdlock(session->bug_rwlock);
7119
7120 for (bp = session->bugs; bp; bp = bp->next) {
7121 ok = SWITCH_TRUE;
7122
7123 if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) {
7124 continue;
7125 }
7126
7127 if (!switch_channel_test_flag(session->channel, CF_ANSWERED) && switch_core_media_bug_test_flag(bp, SMBF_ANSWER_REQ)) {
7128 continue;
7129 }
7130 if (switch_test_flag(bp, SMBF_PRUNE)) {
7131 prune++;
7132 continue;
7133 }
7134
7135 if (bp->ready) {
7136 if (switch_test_flag(bp, SMBF_TAP_NATIVE_WRITE)) {
7137 if (bp->callback) {
7138 bp->native_write_frame = frame;
7139 ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_TAP_NATIVE_WRITE);
7140 bp->native_write_frame = NULL;
7141 }
7142 }
7143 }
7144
7145 if ((bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL)) || ok == SWITCH_FALSE) {
7146 switch_set_flag(bp, SMBF_PRUNE);
7147 prune++;
7148 }
7149 }
7150 switch_thread_rwlock_unlock(session->bug_rwlock);
7151
7152 if (prune) {
7153 switch_core_media_bug_prune(session);
7154 }
7155 }
7156
7157
7158 if (session->endpoint_interface->io_routines->write_frame) {
7159 if ((status = session->endpoint_interface->io_routines->write_frame(session, frame, flags, stream_id)) == SWITCH_STATUS_SUCCESS) {
7160 for (ptr = session->event_hooks.write_frame; ptr; ptr = ptr->next) {
7161 if ((status = ptr->write_frame(session, frame, flags, stream_id)) != SWITCH_STATUS_SUCCESS) {
7162 break;
7163 }
7164 }
7165 }
7166 }
7167
7168 return status;
7169 }
7170
7171
audio_write_thread(switch_thread_t * thread,void * obj)7172 static void *SWITCH_THREAD_FUNC audio_write_thread(switch_thread_t *thread, void *obj)
7173 {
7174 struct media_helper *mh = obj;
7175 switch_core_session_t *session = mh->session;
7176 switch_media_handle_t *smh;
7177 switch_rtp_engine_t *a_engine = NULL;
7178 switch_codec_implementation_t write_impl;
7179 switch_timer_t timer = {0};
7180
7181 if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) {
7182 return NULL;
7183 }
7184
7185 if (!(smh = session->media_handle)) {
7186 switch_core_session_rwunlock(session);
7187 return NULL;
7188 }
7189
7190 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
7191 a_engine->thread_id = switch_thread_self();
7192
7193
7194 write_impl = session->write_impl;
7195
7196 switch_core_timer_init(&timer, "soft", write_impl.microseconds_per_packet / 1000,
7197 write_impl.samples_per_packet, switch_core_session_get_pool(session));
7198
7199 mh->up = 1;
7200
7201 switch_frame_buffer_create(&a_engine->write_fb, 500);
7202
7203 while(switch_channel_up_nosig(session->channel) && mh->up == 1) {
7204 void *pop;
7205
7206 if (session->write_impl.microseconds_per_packet != write_impl.microseconds_per_packet ||
7207 session->write_impl.samples_per_packet != write_impl.samples_per_packet) {
7208
7209
7210 write_impl = session->write_impl;
7211 switch_core_timer_destroy(&timer);
7212 switch_core_timer_init(&timer, "soft", write_impl.microseconds_per_packet / 1000,
7213 write_impl.samples_per_packet, switch_core_session_get_pool(session));
7214
7215 }
7216
7217 switch_core_timer_next(&timer);
7218
7219 if (switch_frame_buffer_trypop(a_engine->write_fb, &pop) == SWITCH_STATUS_SUCCESS && pop) {
7220 switch_frame_t *frame = (switch_frame_t *)pop;
7221
7222 if ((switch_size_t)pop == 1) {
7223 break;
7224 }
7225
7226 perform_write(session, frame, SWITCH_IO_FLAG_QUEUED, 0);
7227 switch_frame_buffer_free(a_engine->write_fb, &frame);
7228 }
7229 }
7230
7231 switch_mutex_lock(smh->control_mutex);
7232 mh->up = 0;
7233 switch_mutex_unlock(smh->control_mutex);
7234
7235 switch_core_timer_destroy(&timer);
7236
7237 switch_core_session_rwunlock(session);
7238 return NULL;
7239 }
7240
switch_core_session_start_audio_write_thread(switch_core_session_t * session)7241 SWITCH_DECLARE(switch_status_t) switch_core_session_start_audio_write_thread(switch_core_session_t *session)
7242 {
7243 switch_threadattr_t *thd_attr = NULL;
7244 switch_memory_pool_t *pool = switch_core_session_get_pool(session);
7245 switch_rtp_engine_t *a_engine = NULL;
7246 switch_media_handle_t *smh;
7247
7248 if (!switch_channel_test_flag(session->channel, CF_AUDIO)) {
7249 return SWITCH_STATUS_NOTIMPL;
7250 }
7251
7252 if (!(smh = session->media_handle)) {
7253 return SWITCH_STATUS_FALSE;
7254 }
7255
7256 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
7257
7258 if (a_engine->media_thread) {
7259 return SWITCH_STATUS_INUSE;
7260 }
7261
7262 switch_mutex_lock(smh->control_mutex);
7263
7264 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Starting Audio write thread\n", switch_core_session_get_name(session));
7265
7266 a_engine->mh.session = session;
7267 switch_threadattr_create(&thd_attr, pool);
7268 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
7269
7270 switch_thread_cond_create(&a_engine->mh.cond, pool);
7271 switch_mutex_init(&a_engine->mh.cond_mutex, SWITCH_MUTEX_NESTED, pool);
7272 switch_thread_create(&a_engine->media_thread, thd_attr, audio_write_thread, &a_engine->mh, switch_core_session_get_pool(session));
7273
7274 switch_mutex_unlock(smh->control_mutex);
7275 return SWITCH_STATUS_SUCCESS;
7276 }
7277
7278
7279
text_helper_thread(switch_thread_t * thread,void * obj)7280 static void *SWITCH_THREAD_FUNC text_helper_thread(switch_thread_t *thread, void *obj)
7281 {
7282 struct media_helper *mh = obj;
7283 switch_core_session_t *session;
7284 switch_channel_t *channel;
7285 switch_status_t status;
7286 switch_frame_t *read_frame = NULL;
7287 switch_media_handle_t *smh;
7288 switch_rtp_engine_t *t_engine = NULL;
7289 unsigned char CR[] = TEXT_UNICODE_LINEFEED;
7290 switch_frame_t cr_frame = { 0 };
7291
7292
7293 session = mh->session;
7294
7295 if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) {
7296 mh->ready = -1;
7297 return NULL;
7298 }
7299
7300 mh->ready = 1;
7301
7302 if (!(smh = session->media_handle)) {
7303 return NULL;
7304 }
7305
7306 channel = switch_core_session_get_channel(session);
7307
7308 if (switch_channel_var_true(session->channel, "fire_text_events")) {
7309 switch_channel_set_flag(session->channel, CF_FIRE_TEXT_EVENTS);
7310 }
7311
7312 cr_frame.data = CR;
7313 cr_frame.datalen = 3;
7314
7315 t_engine = &smh->engines[SWITCH_MEDIA_TYPE_TEXT];
7316 t_engine->thread_id = switch_thread_self();
7317
7318 mh->up = 1;
7319
7320 switch_core_media_check_dtls(session, SWITCH_MEDIA_TYPE_TEXT);
7321
7322 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Text thread started.\n", switch_channel_get_name(session->channel));
7323
7324 if (!switch_channel_test_flag(channel, CF_MSRP)) {
7325 switch_core_session_write_text_frame(session, &cr_frame, 0, 0);
7326 }
7327
7328 while (switch_channel_up_nosig(channel)) {
7329
7330 if (t_engine->engine_function) {
7331 int run = 0;
7332
7333 switch_mutex_lock(smh->control_mutex);
7334 if (t_engine->engine_function_running == 0) {
7335 t_engine->engine_function_running = 1;
7336 run = 1;
7337 }
7338 switch_mutex_unlock(smh->control_mutex);
7339
7340 if (run) {
7341 t_engine->engine_function(session, t_engine->engine_user_data);
7342 switch_mutex_lock(smh->control_mutex);
7343 t_engine->engine_function = NULL;
7344 t_engine->engine_user_data = NULL;
7345 t_engine->engine_function_running = 0;
7346 switch_mutex_unlock(smh->control_mutex);
7347 }
7348 }
7349
7350 if (!switch_channel_test_flag(session->channel, CF_TEXT_PASSIVE)) {
7351
7352 status = switch_core_session_read_text_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
7353
7354 if (!SWITCH_READ_ACCEPTABLE(status)) {
7355 switch_cond_next();
7356 continue;
7357 }
7358
7359 if (!switch_test_flag(read_frame, SFF_CNG)) {
7360 if (switch_channel_test_flag(session->channel, CF_TEXT_ECHO)) {
7361 switch_core_session_write_text_frame(session, read_frame, 0, 0);
7362 }
7363 }
7364 }
7365
7366 switch_core_session_write_text_frame(session, NULL, 0, 0);
7367
7368
7369 }
7370
7371 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Text thread ended\n", switch_channel_get_name(session->channel));
7372
7373 switch_core_session_rwunlock(session);
7374
7375 mh->up = 0;
7376 return NULL;
7377 }
7378
7379
switch_core_session_start_text_thread(switch_core_session_t * session)7380 SWITCH_DECLARE(switch_status_t) switch_core_session_start_text_thread(switch_core_session_t *session)
7381 {
7382 switch_threadattr_t *thd_attr = NULL;
7383 switch_memory_pool_t *pool = switch_core_session_get_pool(session);
7384 switch_rtp_engine_t *t_engine = NULL;
7385 switch_media_handle_t *smh;
7386
7387 if (!switch_channel_test_flag(session->channel, CF_HAS_TEXT)) {
7388 return SWITCH_STATUS_NOTIMPL;
7389 }
7390
7391 if (!(smh = session->media_handle)) {
7392 return SWITCH_STATUS_FALSE;
7393 }
7394
7395 t_engine = &smh->engines[SWITCH_MEDIA_TYPE_TEXT];
7396
7397 switch_mutex_lock(smh->control_mutex);
7398
7399 if (t_engine->media_thread) {
7400 switch_mutex_unlock(smh->control_mutex);
7401 return SWITCH_STATUS_FALSE;
7402 }
7403
7404 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Starting Text thread\n", switch_core_session_get_name(session));
7405
7406 if (t_engine->rtp_session) {
7407 switch_rtp_set_default_payload(t_engine->rtp_session, t_engine->cur_payload_map->pt);
7408 }
7409
7410 t_engine->mh.session = session;
7411 switch_threadattr_create(&thd_attr, pool);
7412 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
7413
7414 switch_thread_cond_create(&t_engine->mh.cond, pool);
7415 switch_mutex_init(&t_engine->mh.cond_mutex, SWITCH_MUTEX_NESTED, pool);
7416 //switch_mutex_init(&t_engine->mh.file_read_mutex, SWITCH_MUTEX_NESTED, pool);
7417 //switch_mutex_init(&t_engine->mh.file_write_mutex, SWITCH_MUTEX_NESTED, pool);
7418 //switch_mutex_init(&smh->read_mutex[SWITCH_MEDIA_TYPE_TEXT], SWITCH_MUTEX_NESTED, pool);
7419 //switch_mutex_init(&smh->write_mutex[SWITCH_MEDIA_TYPE_TEXT], SWITCH_MUTEX_NESTED, pool);
7420
7421 t_engine->mh.ready = 0;
7422
7423 if (switch_thread_create(&t_engine->media_thread, thd_attr, text_helper_thread, &t_engine->mh,
7424 switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) {
7425 while(!t_engine->mh.ready) {
7426 switch_cond_next();
7427 }
7428 }
7429
7430 switch_mutex_unlock(smh->control_mutex);
7431 return SWITCH_STATUS_SUCCESS;
7432 }
7433
video_helper_thread(switch_thread_t * thread,void * obj)7434 static void *SWITCH_THREAD_FUNC video_helper_thread(switch_thread_t *thread, void *obj)
7435 {
7436 struct media_helper *mh = obj;
7437 switch_core_session_t *session;
7438 switch_channel_t *channel;
7439 switch_status_t status;
7440 switch_frame_t *read_frame = NULL;
7441 switch_media_handle_t *smh;
7442 uint32_t loops = 0, xloops = 0, vloops = 0;
7443 switch_image_t *blank_img = NULL;
7444 switch_frame_t fr = { 0 };
7445 unsigned char *buf = NULL;
7446 switch_rgb_color_t bgcolor;
7447 switch_rtp_engine_t *v_engine = NULL;
7448 const char *var;
7449 int buflen = SWITCH_RTP_MAX_BUF_LEN;
7450 int blank_enabled = 1;
7451
7452 session = mh->session;
7453
7454 if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) {
7455 mh->ready = -1;
7456 return NULL;
7457 }
7458
7459 mh->ready = 1;
7460
7461 if (!(smh = session->media_handle)) {
7462 return NULL;
7463 }
7464
7465 channel = switch_core_session_get_channel(session);
7466
7467 switch_core_autobind_cpu();
7468
7469 if ((var = switch_channel_get_variable(session->channel, "core_video_blank_image"))) {
7470 if (switch_false(var)) {
7471 blank_enabled = 0;
7472 } else {
7473 blank_img = switch_img_read_png(var, SWITCH_IMG_FMT_I420);
7474 }
7475 }
7476
7477 if (!blank_img) {
7478 switch_color_set_rgb(&bgcolor, "#000000");
7479 if ((blank_img = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, 352, 288, 1))) {
7480 switch_img_fill(blank_img, 0, 0, blank_img->d_w, blank_img->d_h, &bgcolor);
7481 }
7482 }
7483
7484
7485
7486 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
7487 v_engine->thread_id = switch_thread_self();
7488
7489 mh->up = 1;
7490 switch_mutex_lock(mh->cond_mutex);
7491
7492 switch_core_media_check_dtls(session, SWITCH_MEDIA_TYPE_VIDEO);
7493
7494 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Video thread started. Echo is %s\n",
7495 switch_channel_get_name(session->channel), switch_channel_test_flag(channel, CF_VIDEO_ECHO) ? "on" : "off");
7496 switch_core_session_request_video_refresh(session);
7497
7498 buf = switch_core_session_alloc(session, buflen);
7499 fr.packet = buf;
7500 fr.packetlen = buflen;
7501 fr.data = buf + 12;
7502 fr.buflen = buflen - 12;
7503
7504 switch_core_media_gen_key_frame(session);
7505
7506 while (switch_channel_up_nosig(channel)) {
7507 int send_blank = 0;
7508
7509 if (!switch_channel_test_flag(channel, CF_VIDEO)) {
7510 if ((++loops % 100) == 0) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Waiting for video......\n");
7511 switch_yield(20000);
7512 continue;
7513 }
7514
7515 if (!switch_channel_test_flag(channel, CF_VIDEO_READY) &&
7516 switch_channel_test_flag(channel, CF_VIDEO_DECODED_READ) && (++xloops > 10 || switch_channel_test_flag(channel, CF_VIDEO_PASSIVE))) {
7517 switch_channel_set_flag(channel, CF_VIDEO_READY);
7518 }
7519
7520 if (switch_channel_test_flag(channel, CF_VIDEO_PASSIVE)) {
7521 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Video thread paused. Echo is %s\n",
7522 switch_channel_get_name(session->channel), switch_channel_test_flag(channel, CF_VIDEO_ECHO) ? "on" : "off");
7523 switch_thread_cond_wait(mh->cond, mh->cond_mutex);
7524 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Video thread resumed Echo is %s\n",
7525 switch_channel_get_name(session->channel), switch_channel_test_flag(channel, CF_VIDEO_ECHO) ? "on" : "off");
7526 switch_core_session_request_video_refresh(session);
7527 }
7528
7529 if (switch_channel_test_flag(channel, CF_VIDEO_PASSIVE)) {
7530 continue;
7531 }
7532
7533 if (!switch_channel_media_up(session->channel)) {
7534 switch_yield(10000);
7535 continue;
7536 }
7537
7538 if (v_engine->engine_function) {
7539 int run = 0;
7540
7541 switch_mutex_lock(smh->control_mutex);
7542 if (v_engine->engine_function_running == 0) {
7543 v_engine->engine_function_running = 1;
7544 run = 1;
7545 }
7546 switch_mutex_unlock(smh->control_mutex);
7547
7548 if (run) {
7549 v_engine->engine_function(session, v_engine->engine_user_data);
7550 switch_mutex_lock(smh->control_mutex);
7551 v_engine->engine_function = NULL;
7552 v_engine->engine_user_data = NULL;
7553 v_engine->engine_function_running = 0;
7554 switch_mutex_unlock(smh->control_mutex);
7555 }
7556 }
7557
7558 status = switch_core_session_read_video_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
7559
7560 if (!SWITCH_READ_ACCEPTABLE(status)) {
7561 switch_cond_next();
7562 continue;
7563 }
7564
7565 vloops++;
7566
7567 send_blank = blank_enabled || switch_channel_test_flag(channel, CF_VIDEO_ECHO);
7568
7569 if (switch_channel_test_flag(channel, CF_VIDEO_READY) && !switch_test_flag(read_frame, SFF_CNG)) {
7570 switch_mutex_lock(mh->file_read_mutex);
7571 if (smh->video_read_fh && switch_test_flag(smh->video_read_fh, SWITCH_FILE_OPEN) && read_frame->img) {
7572 smh->video_read_fh->mm.fps = smh->vid_params.fps;
7573 switch_core_file_write_video(smh->video_read_fh, read_frame);
7574 }
7575 switch_mutex_unlock(mh->file_read_mutex);
7576 }
7577
7578 if ((switch_channel_test_flag(channel, CF_VIDEO_WRITING) || session->video_read_callback) && !switch_channel_test_flag(channel, CF_VIDEO_BLANK)) {
7579 send_blank = 0;
7580 }
7581
7582 if (send_blank) {
7583 if (read_frame && (switch_channel_test_flag(channel, CF_VIDEO_ECHO))) {
7584 switch_core_session_write_video_frame(session, read_frame, SWITCH_IO_FLAG_NONE, 0);
7585 } else if (blank_img) {
7586 fr.img = blank_img;
7587 switch_yield(10000);
7588 switch_core_session_write_video_frame(session, &fr, SWITCH_IO_FLAG_FORCE, 0);
7589 }
7590 }
7591 }
7592
7593 switch_img_free(&blank_img);
7594
7595 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Video thread ended\n", switch_channel_get_name(session->channel));
7596
7597 switch_mutex_unlock(mh->cond_mutex);
7598 switch_core_session_rwunlock(session);
7599
7600 mh->up = 0;
7601 return NULL;
7602 }
7603
switch_core_session_start_video_thread(switch_core_session_t * session)7604 SWITCH_DECLARE(switch_status_t) switch_core_session_start_video_thread(switch_core_session_t *session)
7605 {
7606 switch_threadattr_t *thd_attr = NULL;
7607 switch_memory_pool_t *pool = switch_core_session_get_pool(session);
7608 switch_rtp_engine_t *v_engine = NULL;
7609 switch_media_handle_t *smh;
7610
7611 if (!switch_channel_test_flag(session->channel, CF_VIDEO)) {
7612 return SWITCH_STATUS_NOTIMPL;
7613 }
7614
7615 if (!(smh = session->media_handle)) {
7616 return SWITCH_STATUS_FALSE;
7617 }
7618
7619 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
7620
7621 switch_mutex_lock(smh->control_mutex);
7622
7623 if (v_engine->media_thread) {
7624 switch_mutex_unlock(smh->control_mutex);
7625 return SWITCH_STATUS_FALSE;
7626 }
7627
7628 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Starting Video thread\n", switch_core_session_get_name(session));
7629
7630 if (v_engine->rtp_session) {
7631 switch_rtp_set_default_payload(v_engine->rtp_session, v_engine->cur_payload_map->pt);
7632 }
7633
7634 v_engine->mh.session = session;
7635 switch_threadattr_create(&thd_attr, pool);
7636 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
7637
7638 switch_thread_cond_create(&v_engine->mh.cond, pool);
7639 switch_mutex_init(&v_engine->mh.cond_mutex, SWITCH_MUTEX_NESTED, pool);
7640 switch_mutex_init(&v_engine->mh.file_read_mutex, SWITCH_MUTEX_NESTED, pool);
7641 switch_mutex_init(&v_engine->mh.file_write_mutex, SWITCH_MUTEX_NESTED, pool);
7642 switch_mutex_init(&smh->read_mutex[SWITCH_MEDIA_TYPE_VIDEO], SWITCH_MUTEX_NESTED, pool);
7643 switch_mutex_init(&smh->write_mutex[SWITCH_MEDIA_TYPE_VIDEO], SWITCH_MUTEX_NESTED, pool);
7644 v_engine->mh.ready = 0;
7645
7646 if (switch_thread_create(&v_engine->media_thread, thd_attr, video_helper_thread, &v_engine->mh,
7647 switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) {
7648 while(!v_engine->mh.ready) {
7649 switch_cond_next();
7650 }
7651 }
7652
7653 switch_mutex_unlock(smh->control_mutex);
7654 return SWITCH_STATUS_SUCCESS;
7655 }
7656
switch_core_media_start_engine_function(switch_core_session_t * session,switch_media_type_t type,switch_engine_function_t engine_function,void * user_data)7657 SWITCH_DECLARE(void) switch_core_media_start_engine_function(switch_core_session_t *session, switch_media_type_t type, switch_engine_function_t engine_function, void *user_data)
7658 {
7659 switch_media_handle_t *smh;
7660 switch_rtp_engine_t *engine;
7661
7662 if (!(smh = session->media_handle)) {
7663 return;
7664 }
7665
7666 engine = &smh->engines[type];
7667
7668 if (type == SWITCH_MEDIA_TYPE_VIDEO) {
7669 switch_core_session_start_video_thread(session);
7670 }
7671
7672 if (type == SWITCH_MEDIA_TYPE_TEXT) {
7673 switch_core_session_start_text_thread(session);
7674 }
7675
7676 switch_mutex_lock(smh->control_mutex);
7677 if (!engine->engine_function_running) {
7678 engine->engine_function = engine_function;
7679 engine->engine_user_data = user_data;
7680 switch_core_session_video_reset(session);
7681 }
7682 switch_mutex_unlock(smh->control_mutex);
7683 }
7684
switch_core_media_check_engine_function(switch_core_session_t * session,switch_media_type_t type)7685 SWITCH_DECLARE(int) switch_core_media_check_engine_function(switch_core_session_t *session, switch_media_type_t type)
7686 {
7687 switch_media_handle_t *smh;
7688 int r;
7689 switch_rtp_engine_t *engine;
7690
7691 if (!(smh = session->media_handle)) {
7692 return 0;
7693 }
7694
7695 engine = &smh->engines[type];
7696
7697 switch_mutex_lock(smh->control_mutex);
7698 r = (engine->engine_function_running > 0);
7699 switch_mutex_unlock(smh->control_mutex);
7700
7701 return r;
7702 }
7703
switch_core_media_end_engine_function(switch_core_session_t * session,switch_media_type_t type)7704 SWITCH_DECLARE(void) switch_core_media_end_engine_function(switch_core_session_t *session, switch_media_type_t type)
7705 {
7706 switch_media_handle_t *smh;
7707 switch_rtp_engine_t *engine;
7708
7709 if (!(smh = session->media_handle)) {
7710 return;
7711 }
7712
7713 engine = &smh->engines[type];
7714
7715 switch_mutex_lock(smh->control_mutex);
7716 if (engine->engine_function_running > 0) {
7717 engine->engine_function_running = -1;
7718 }
7719 switch_mutex_unlock(smh->control_mutex);
7720
7721 while(engine->engine_function_running != 0) {
7722 switch_yield(10000);
7723 }
7724 }
7725
switch_core_session_in_video_thread(switch_core_session_t * session)7726 SWITCH_DECLARE(switch_bool_t) switch_core_session_in_video_thread(switch_core_session_t *session)
7727 {
7728 switch_rtp_engine_t *v_engine;
7729 switch_media_handle_t *smh;
7730
7731 switch_assert(session);
7732
7733 if (!(smh = session->media_handle)) {
7734 return SWITCH_FALSE;
7735 }
7736
7737 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
7738
7739 return switch_thread_equal(switch_thread_self(), v_engine->thread_id) ? SWITCH_TRUE : SWITCH_FALSE;
7740 }
7741
7742
switch_core_media_parse_media_flags(switch_core_session_t * session)7743 SWITCH_DECLARE(void) switch_core_media_parse_media_flags(switch_core_session_t *session)
7744 {
7745 const char *var;
7746 switch_media_handle_t *smh;
7747
7748 if (!(smh = session->media_handle)) {
7749 return;
7750 }
7751
7752 if ((var = switch_channel_get_variable(session->channel, "rtp_media_autofix_timing"))) {
7753 if (switch_true(var)) {
7754 switch_media_handle_set_media_flag(smh, SCMF_AUTOFIX_TIMING);
7755 } else {
7756 switch_media_handle_clear_media_flag(smh, SCMF_AUTOFIX_TIMING);
7757 }
7758 }
7759 }
7760
7761 //?
7762 #define RA_PTR_LEN 512
switch_core_media_proxy_remote_addr(switch_core_session_t * session,const char * sdp_str)7763 SWITCH_DECLARE(switch_status_t) switch_core_media_proxy_remote_addr(switch_core_session_t *session, const char *sdp_str)
7764 {
7765 const char *err;
7766 char rip[RA_PTR_LEN] = "";
7767 char rp[RA_PTR_LEN] = "";
7768 char rvp[RA_PTR_LEN] = "";
7769 char rtp[RA_PTR_LEN] = "";
7770 char *p, *ip_ptr = NULL, *port_ptr = NULL, *vid_port_ptr = NULL, *text_port_ptr = NULL, *pe;
7771 int x;
7772 const char *val;
7773 switch_status_t status = SWITCH_STATUS_FALSE;
7774 switch_rtp_engine_t *a_engine, *v_engine, *t_engine;
7775 switch_media_handle_t *smh;
7776
7777 switch_assert(session);
7778
7779 if (!(smh = session->media_handle)) {
7780 return SWITCH_STATUS_FALSE;
7781 }
7782
7783 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
7784 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
7785 t_engine = &smh->engines[SWITCH_MEDIA_TYPE_TEXT];
7786
7787 if (zstr(sdp_str)) {
7788 sdp_str = smh->mparams->remote_sdp_str;
7789 }
7790
7791 if (zstr(sdp_str)) {
7792 goto end;
7793 }
7794
7795 if ((p = (char *) switch_stristr("c=IN IP4 ", sdp_str)) || (p = (char *) switch_stristr("c=IN IP6 ", sdp_str))) {
7796 ip_ptr = p + 9;
7797 }
7798
7799 if ((p = (char *) switch_stristr("m=audio ", sdp_str))) {
7800 port_ptr = p + 8;
7801 }
7802
7803 if ((p = (char *) switch_stristr("m=image ", sdp_str))) {
7804 char *tmp = p + 8;
7805
7806 if (tmp && atoi(tmp)) {
7807 port_ptr = tmp;
7808 }
7809 }
7810
7811 if ((p = (char *) switch_stristr("m=video ", sdp_str))) {
7812 vid_port_ptr = p + 8;
7813 }
7814
7815 if ((p = (char *) switch_stristr("m=text ", sdp_str))) {
7816 text_port_ptr = p + 7;
7817 }
7818
7819 if (!(ip_ptr && port_ptr)) {
7820 goto end;
7821 }
7822
7823 p = ip_ptr;
7824 pe = p + strlen(p);
7825 x = 0;
7826 while (x < sizeof(rip) - 1 && p && *p && ((*p >= '0' && *p <= '9') || *p == '.' || *p == ':' || (*p >= 'a' && *p <= 'f') || (*p >= 'A' && *p <= 'F'))) {
7827 rip[x++] = *p;
7828 p++;
7829 if (p >= pe) {
7830 goto end;
7831 }
7832 }
7833
7834 if (port_ptr) {
7835 p = port_ptr;
7836 x = 0;
7837 while (x < sizeof(rp) - 1 && p && *p && (*p >= '0' && *p <= '9')) {
7838 rp[x++] = *p;
7839 p++;
7840 if (p >= pe) {
7841 goto end;
7842 }
7843 }
7844 }
7845
7846 if (vid_port_ptr) {
7847 p = vid_port_ptr;
7848 x = 0;
7849 while (x < sizeof(rvp) - 1 && p && *p && (*p >= '0' && *p <= '9')) {
7850 rvp[x++] = *p;
7851 p++;
7852 if (p >= pe) {
7853 goto end;
7854 }
7855 }
7856 }
7857
7858 if (text_port_ptr) {
7859 p = text_port_ptr;
7860 x = 0;
7861 while (x < sizeof(rtp) - 1 && p && *p && (*p >= '0' && *p <= '9')) {
7862 rtp[x++] = *p;
7863 p++;
7864 if (p >= pe) {
7865 goto end;
7866 }
7867 }
7868 }
7869
7870 if (!(*rip && *rp)) {
7871 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "invalid SDP\n");
7872 goto end;
7873 }
7874
7875 a_engine->cur_payload_map->remote_sdp_ip = switch_core_session_strdup(session, rip);
7876 a_engine->cur_payload_map->remote_sdp_port = (switch_port_t) atoi(rp);
7877
7878 if (*rvp) {
7879 v_engine->cur_payload_map->remote_sdp_ip = switch_core_session_strdup(session, rip);
7880 v_engine->cur_payload_map->remote_sdp_port = (switch_port_t) atoi(rvp);
7881 switch_channel_set_flag(session->channel, CF_VIDEO_POSSIBLE);
7882 switch_channel_set_flag(session->channel, CF_VIDEO);
7883 }
7884
7885 if (*rtp) {
7886 t_engine->cur_payload_map->remote_sdp_ip = switch_core_session_strdup(session, rip);
7887 t_engine->cur_payload_map->remote_sdp_port = (switch_port_t) atoi(rtp);
7888 switch_channel_set_flag(session->channel, CF_HAS_TEXT);
7889 switch_channel_set_flag(session->channel, CF_TEXT_POSSIBLE);
7890 }
7891
7892 if (v_engine->cur_payload_map && v_engine->cur_payload_map->remote_sdp_ip && v_engine->cur_payload_map->remote_sdp_port) {
7893 if (!strcmp(v_engine->cur_payload_map->remote_sdp_ip, rip) && atoi(rvp) == v_engine->cur_payload_map->remote_sdp_port) {
7894 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Remote video address:port [%s:%d] has not changed.\n",
7895 v_engine->cur_payload_map->remote_sdp_ip, v_engine->cur_payload_map->remote_sdp_port);
7896 } else {
7897 switch_channel_set_flag(session->channel, CF_VIDEO_POSSIBLE);
7898 switch_channel_set_flag(session->channel, CF_VIDEO);
7899 if (switch_rtp_ready(v_engine->rtp_session)) {
7900 const char *rport = NULL;
7901 switch_port_t remote_rtcp_port = v_engine->remote_rtcp_port;
7902
7903 if (!remote_rtcp_port) {
7904 if ((rport = switch_channel_get_variable(session->channel, "rtp_remote_video_rtcp_port"))) {
7905 remote_rtcp_port = (switch_port_t)atoi(rport);
7906 }
7907 }
7908
7909
7910 if (switch_rtp_set_remote_address(v_engine->rtp_session, v_engine->cur_payload_map->remote_sdp_ip,
7911 v_engine->cur_payload_map->remote_sdp_port, remote_rtcp_port, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
7912 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "VIDEO RTP REPORTS ERROR: [%s]\n", err);
7913 } else {
7914 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "VIDEO RTP CHANGING DEST TO: [%s:%d]\n",
7915 v_engine->cur_payload_map->remote_sdp_ip, v_engine->cur_payload_map->remote_sdp_port);
7916 if (switch_media_handle_test_media_flag(smh, SCMF_AUTOFIX_TIMING)) {
7917 v_engine->check_frames = 0;
7918 }
7919 }
7920 }
7921 }
7922 if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) && !switch_channel_test_flag(session->channel, CF_PROXY_MODE) &&
7923 !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")) && switch_true(val)) &&
7924 v_engine->rtp_session &&
7925 !switch_channel_test_flag(session->channel, CF_AVPF)) {
7926 /* Reactivate the NAT buster flag. */
7927 switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_AUTOADJ);
7928 }
7929 }
7930
7931 if (t_engine->cur_payload_map && t_engine->cur_payload_map->remote_sdp_ip && t_engine->cur_payload_map->remote_sdp_port) {
7932 if (!strcmp(t_engine->cur_payload_map->remote_sdp_ip, rip) && atoi(rvp) == t_engine->cur_payload_map->remote_sdp_port) {
7933 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Remote text address:port [%s:%d] has not changed.\n",
7934 t_engine->cur_payload_map->remote_sdp_ip, t_engine->cur_payload_map->remote_sdp_port);
7935 } else {
7936 switch_channel_set_flag(session->channel, CF_HAS_TEXT);
7937 switch_channel_set_flag(session->channel, CF_TEXT_POSSIBLE);
7938 if (switch_rtp_ready(t_engine->rtp_session)) {
7939 const char *rport = NULL;
7940 switch_port_t remote_rtcp_port = t_engine->remote_rtcp_port;
7941
7942 if (!remote_rtcp_port) {
7943 if ((rport = switch_channel_get_variable(session->channel, "rtp_remote_text_rtcp_port"))) {
7944 remote_rtcp_port = (switch_port_t)atoi(rport);
7945 }
7946 }
7947
7948
7949 if (switch_rtp_set_remote_address(t_engine->rtp_session, t_engine->cur_payload_map->remote_sdp_ip,
7950 t_engine->cur_payload_map->remote_sdp_port, remote_rtcp_port, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
7951 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "TEXT RTP REPORTS ERROR: [%s]\n", err);
7952 } else {
7953 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "TEXT RTP CHANGING DEST TO: [%s:%d]\n",
7954 t_engine->cur_payload_map->remote_sdp_ip, t_engine->cur_payload_map->remote_sdp_port);
7955 if (switch_media_handle_test_media_flag(smh, SCMF_AUTOFIX_TIMING)) {
7956 t_engine->check_frames = 0;
7957 }
7958 }
7959 }
7960 }
7961 if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) && !switch_channel_test_flag(session->channel, CF_PROXY_MODE) &&
7962 !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")) && switch_true(val)) &&
7963 t_engine->rtp_session &&
7964 !switch_channel_test_flag(session->channel, CF_AVPF)) {
7965 /* Reactivate the NAT buster flag. */
7966 switch_rtp_set_flag(t_engine->rtp_session, SWITCH_RTP_FLAG_AUTOADJ);
7967 }
7968 }
7969
7970 if (switch_rtp_ready(a_engine->rtp_session)) {
7971 char *remote_host = switch_rtp_get_remote_host(a_engine->rtp_session);
7972 switch_port_t remote_port = switch_rtp_get_remote_port(a_engine->rtp_session);
7973 const char *rport = NULL;
7974 switch_port_t remote_rtcp_port = 0;
7975
7976 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) {
7977 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Remote address:port [%s:%d] has not changed.\n",
7978 a_engine->cur_payload_map->remote_sdp_ip, a_engine->cur_payload_map->remote_sdp_port);
7979 switch_goto_status(SWITCH_STATUS_BREAK, end);
7980 } else if (remote_host && ( (strcmp(remote_host, "0.0.0.0") == 0) ||
7981 (strcmp(a_engine->cur_payload_map->remote_sdp_ip, "0.0.0.0") == 0))) {
7982
7983 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
7984 "Remote address changed from [%s] to [%s]. Ignoring...\n",
7985 a_engine->cur_payload_map->remote_sdp_ip, remote_host);
7986 switch_goto_status(SWITCH_STATUS_BREAK, end);
7987 }
7988
7989 if ((rport = switch_channel_get_variable(session->channel, "rtp_remote_audio_rtcp_port"))) {
7990 remote_rtcp_port = (switch_port_t)atoi(rport);
7991 }
7992
7993
7994 if (switch_rtp_set_remote_address(a_engine->rtp_session, a_engine->cur_payload_map->remote_sdp_ip,
7995 a_engine->cur_payload_map->remote_sdp_port, remote_rtcp_port, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
7996 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", err);
7997 status = SWITCH_STATUS_GENERR;
7998 } else {
7999 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "AUDIO RTP CHANGING DEST TO: [%s:%d]\n",
8000 a_engine->cur_payload_map->remote_sdp_ip, a_engine->cur_payload_map->remote_sdp_port);
8001 if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) &&
8002 !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")) && switch_true(val)) &&
8003 !switch_channel_test_flag(session->channel, CF_AVPF)) {
8004 /* Reactivate the NAT buster flag. */
8005 switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_AUTOADJ);
8006 }
8007 if (switch_media_handle_test_media_flag(smh, SCMF_AUTOFIX_TIMING)) {
8008 a_engine->check_frames = 0;
8009 }
8010 status = SWITCH_STATUS_SUCCESS;
8011 }
8012 }
8013
8014 end:
8015
8016 return status;
8017 }
8018
8019 //?
switch_core_media_check_nat(switch_media_handle_t * smh,const char * network_ip)8020 SWITCH_DECLARE(int) switch_core_media_check_nat(switch_media_handle_t *smh, const char *network_ip)
8021 {
8022 switch_assert(network_ip);
8023
8024 return (smh->mparams->extsipip &&
8025 !switch_check_network_list_ip(network_ip, "loopback.auto") &&
8026 !switch_check_network_list_ip(network_ip, smh->mparams->local_network));
8027 }
8028
8029 //?
switch_core_media_ext_address_lookup(switch_core_session_t * session,char ** ip,switch_port_t * port,const char * sourceip)8030 SWITCH_DECLARE(switch_status_t) switch_core_media_ext_address_lookup(switch_core_session_t *session, char **ip, switch_port_t *port, const char *sourceip)
8031
8032 {
8033 char *error = "";
8034 switch_status_t status = SWITCH_STATUS_FALSE;
8035 int x;
8036 switch_port_t myport = *port;
8037 switch_port_t stun_port = SWITCH_STUN_DEFAULT_PORT;
8038 char *stun_ip = NULL;
8039 switch_media_handle_t *smh;
8040 switch_memory_pool_t *pool = switch_core_session_get_pool(session);
8041
8042 switch_assert(session);
8043
8044 if (!(smh = session->media_handle)) {
8045 return SWITCH_STATUS_FALSE;
8046 }
8047
8048 if (!sourceip) {
8049 return status;
8050 }
8051
8052 if (!strncasecmp(sourceip, "host:", 5)) {
8053 status = (*ip = switch_stun_host_lookup(sourceip + 5, pool)) ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
8054 } else if (!strncasecmp(sourceip, "stun:", 5)) {
8055 char *p;
8056
8057 stun_ip = strdup(sourceip + 5);
8058
8059 if ((p = strchr(stun_ip, ':'))) {
8060 int iport;
8061 *p++ = '\0';
8062 iport = atoi(p);
8063 if (iport > 0 && iport < 0xFFFF) {
8064 stun_port = (switch_port_t) iport;
8065 }
8066 }
8067
8068 if (zstr(stun_ip)) {
8069 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "STUN Failed! NO STUN SERVER\n");
8070 goto out;
8071 }
8072
8073 for (x = 0; x < 5; x++) {
8074 if ((status = switch_stun_lookup(ip, port, stun_ip, stun_port, &error, pool)) != SWITCH_STATUS_SUCCESS) {
8075 switch_yield(100000);
8076 } else {
8077 break;
8078 }
8079 }
8080 if (status != SWITCH_STATUS_SUCCESS) {
8081 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "STUN Failed! %s:%d [%s]\n", stun_ip, stun_port, error);
8082 goto out;
8083 }
8084 if (!*ip) {
8085 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "STUN Failed! No IP returned\n");
8086 goto out;
8087 }
8088 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "STUN Success [%s]:[%d]\n", *ip, *port);
8089 status = SWITCH_STATUS_SUCCESS;
8090
8091 if (myport == *port && !strcmp(*ip, smh->mparams->rtpip)) {
8092 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "STUN Not Required ip and port match. [%s]:[%d]\n", *ip, *port);
8093 } else {
8094 smh->mparams->stun_ip = switch_core_session_strdup(session, stun_ip);
8095 smh->mparams->stun_port = stun_port;
8096 smh->mparams->stun_flags |= STUN_FLAG_SET;
8097 }
8098 } else {
8099 *ip = (char *) sourceip;
8100 status = SWITCH_STATUS_SUCCESS;
8101 }
8102
8103 out:
8104
8105 switch_safe_free(stun_ip);
8106
8107 return status;
8108 }
8109
8110 //?
switch_core_media_reset_autofix(switch_core_session_t * session,switch_media_type_t type)8111 SWITCH_DECLARE(void) switch_core_media_reset_autofix(switch_core_session_t *session, switch_media_type_t type)
8112 {
8113 switch_rtp_engine_t *engine;
8114 switch_media_handle_t *smh;
8115
8116 switch_assert(session);
8117
8118 if (!(smh = session->media_handle)) {
8119 return;
8120 }
8121
8122 engine = &smh->engines[type];
8123
8124 engine->check_frames = 0;
8125 engine->last_ts = 0;
8126 engine->last_seq = 0;
8127 }
8128
8129
8130
8131 //?
switch_core_media_choose_port(switch_core_session_t * session,switch_media_type_t type,int force)8132 SWITCH_DECLARE(switch_status_t) switch_core_media_choose_port(switch_core_session_t *session, switch_media_type_t type, int force)
8133 {
8134 char *lookup_rtpip; /* Pointer to externally looked up address */
8135 switch_port_t sdp_port; /* The external port to be sent in the SDP */
8136 const char *use_ip = NULL; /* The external IP to be sent in the SDP */
8137 switch_rtp_engine_t *engine;
8138 switch_media_handle_t *smh;
8139 const char *tstr = switch_media_type2str(type);
8140 char vname[128] = "";
8141
8142 switch_assert(session);
8143
8144 if (!(smh = session->media_handle)) {
8145 return SWITCH_STATUS_FALSE;
8146 }
8147
8148 engine = &smh->engines[type];
8149
8150 lookup_rtpip = smh->mparams->rtpip;
8151
8152 if (!lookup_rtpip) {
8153 return SWITCH_STATUS_FALSE;
8154 }
8155
8156 /* Don't do anything if we're in proxy mode or if a (remote) port already has been found */
8157 if (!force) {
8158 if (switch_channel_test_flag(session->channel, CF_PROXY_MODE) ||
8159 switch_channel_test_flag(session->channel, CF_PROXY_MEDIA) || engine->adv_sdp_port) {
8160 return SWITCH_STATUS_SUCCESS;
8161 }
8162 }
8163
8164 /* Always too late when RTP has already started */
8165 if (engine->rtp_session) {
8166 return SWITCH_STATUS_SUCCESS;
8167 }
8168
8169 /* Release the local sdp port */
8170 if (engine->local_sdp_port) {
8171 switch_rtp_release_port(smh->mparams->rtpip, engine->local_sdp_port);
8172 }
8173
8174 /* Request a local port from the core's allocator */
8175 if (!(engine->local_sdp_port = switch_rtp_request_port(smh->mparams->rtpip))) {
8176 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "No %s RTP ports available!\n", tstr);
8177 return SWITCH_STATUS_FALSE;
8178 }
8179
8180 engine->local_sdp_ip = smh->mparams->rtpip;
8181
8182
8183 sdp_port = engine->local_sdp_port;
8184
8185 /* Check if NAT is detected */
8186 if (!zstr(smh->mparams->remote_ip) && switch_core_media_check_nat(smh, smh->mparams->remote_ip)) {
8187 /* Yes, map the port through switch_nat */
8188 switch_nat_add_mapping(engine->local_sdp_port, SWITCH_NAT_UDP, &sdp_port, SWITCH_FALSE);
8189
8190 switch_snprintf(vname, sizeof(vname), "rtp_adv_%s_ip", tstr);
8191
8192 /* Find an IP address to use */
8193 if (!(use_ip = switch_channel_get_variable(session->channel, vname))
8194 && !zstr(smh->mparams->extrtpip)) {
8195 use_ip = smh->mparams->extrtpip;
8196 }
8197
8198 if (use_ip) {
8199 if (switch_core_media_ext_address_lookup(session, &lookup_rtpip, &sdp_port, use_ip) != SWITCH_STATUS_SUCCESS) {
8200 /* Address lookup was required and fail (external ip was "host:..." or "stun:...") */
8201 return SWITCH_STATUS_FALSE;
8202 } else {
8203 /* Address properly resolved, use it as external ip */
8204 use_ip = lookup_rtpip;
8205 }
8206 } else {
8207 /* No external ip found, use the profile's rtp ip */
8208 use_ip = smh->mparams->rtpip;
8209 }
8210 } else {
8211 /* No NAT traversal required, use the profile's rtp ip */
8212 use_ip = smh->mparams->rtpip;
8213 }
8214
8215 if (zstr(smh->mparams->remote_ip)) { /* no remote_ip, we're originating */
8216 if (!zstr(smh->mparams->extrtpip)) { /* and we've got an ext-rtp-ip, eg, from verto config */
8217 use_ip = smh->mparams->extrtpip; /* let's use it for composing local sdp to send to client */
8218 /*
8219 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,
8220 "%s will use %s instead of %s in SDP, because we're originating and we have an ext-rtp-ip setting\n",
8221 switch_channel_get_name(smh->session->channel), smh->mparams->extrtpip, smh->mparams->rtpip);
8222 */
8223 }
8224 }
8225 engine->adv_sdp_port = sdp_port;
8226 engine->adv_sdp_ip = smh->mparams->adv_sdp_audio_ip = smh->mparams->extrtpip = switch_core_session_strdup(session, use_ip);
8227
8228 if (type == SWITCH_MEDIA_TYPE_AUDIO) {
8229 switch_channel_set_variable(session->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE, engine->local_sdp_ip);
8230 switch_channel_set_variable_printf(session->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE, "%d", sdp_port);
8231 switch_channel_set_variable(session->channel, SWITCH_ADVERTISED_MEDIA_IP_VARIABLE, engine->adv_sdp_ip);
8232 } else if (type == SWITCH_MEDIA_TYPE_VIDEO) {
8233 switch_channel_set_variable(session->channel, SWITCH_LOCAL_VIDEO_IP_VARIABLE, engine->adv_sdp_ip);
8234 switch_channel_set_variable_printf(session->channel, SWITCH_LOCAL_VIDEO_PORT_VARIABLE, "%d", sdp_port);
8235 } else if (type == SWITCH_MEDIA_TYPE_TEXT) {
8236 switch_channel_set_variable(session->channel, SWITCH_LOCAL_TEXT_IP_VARIABLE, engine->adv_sdp_ip);
8237 switch_channel_set_variable_printf(session->channel, SWITCH_LOCAL_TEXT_PORT_VARIABLE, "%d", sdp_port);
8238 }
8239
8240
8241 return SWITCH_STATUS_SUCCESS;
8242 }
8243
switch_core_media_choose_ports(switch_core_session_t * session,switch_bool_t audio,switch_bool_t video)8244 SWITCH_DECLARE(switch_status_t) switch_core_media_choose_ports(switch_core_session_t *session, switch_bool_t audio, switch_bool_t video)
8245 {
8246 switch_status_t status = SWITCH_STATUS_SUCCESS;
8247 switch_media_handle_t *smh;
8248
8249 if (!(smh = session->media_handle)) {
8250 return SWITCH_STATUS_FALSE;
8251 }
8252
8253 if (zstr(smh->mparams->rtpip)) {
8254
8255 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s has no media ip\n",
8256 switch_channel_get_name(smh->session->channel));
8257 switch_channel_hangup(smh->session->channel, SWITCH_CAUSE_BEARERCAPABILITY_NOTAVAIL);
8258
8259 return SWITCH_STATUS_FALSE;
8260 }
8261
8262 if (audio && (status = switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_AUDIO, 0)) == SWITCH_STATUS_SUCCESS) {
8263 if (video) {
8264 switch_core_media_check_video_codecs(session);
8265 if (switch_channel_test_flag(session->channel, CF_VIDEO_POSSIBLE)) {
8266 switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_VIDEO, 0);
8267 }
8268 }
8269 }
8270
8271 return status;
8272 }
8273
8274
8275
8276 //?
switch_core_media_deactivate_rtp(switch_core_session_t * session)8277 SWITCH_DECLARE(void) switch_core_media_deactivate_rtp(switch_core_session_t *session)
8278 {
8279 switch_rtp_engine_t *a_engine, *v_engine, *t_engine;
8280 switch_media_handle_t *smh;
8281
8282 switch_assert(session);
8283
8284 if (!(smh = session->media_handle)) {
8285 return;
8286 }
8287
8288 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
8289 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
8290 t_engine = &smh->engines[SWITCH_MEDIA_TYPE_TEXT];
8291
8292 if (t_engine->tf) {
8293 switch_rtp_text_factory_destroy(&t_engine->tf);
8294 }
8295
8296 if (a_engine->media_thread) {
8297 switch_status_t st;
8298
8299 switch_mutex_lock(smh->control_mutex);
8300 if (a_engine->mh.up && a_engine->write_fb) {
8301 switch_frame_buffer_push(a_engine->write_fb, (void *) 1);
8302 }
8303 a_engine->mh.up = 0;
8304 switch_mutex_unlock(smh->control_mutex);
8305
8306 switch_thread_join(&st, a_engine->media_thread);
8307 a_engine->media_thread = NULL;
8308 }
8309
8310 if (v_engine->media_thread) {
8311 switch_status_t st;
8312 switch_channel_clear_flag(session->channel, CF_VIDEO_PASSIVE);
8313
8314 v_engine->mh.up = 0;
8315 switch_thread_join(&st, v_engine->media_thread);
8316 v_engine->media_thread = NULL;
8317 }
8318
8319 if (v_engine->rtp_session) {
8320 switch_rtp_destroy(&v_engine->rtp_session);
8321 } else if (v_engine->local_sdp_port) {
8322 switch_rtp_release_port(smh->mparams->rtpip, v_engine->local_sdp_port);
8323 }
8324
8325
8326 if (v_engine->local_sdp_port > 0 && !zstr(smh->mparams->remote_ip) &&
8327 switch_core_media_check_nat(smh, smh->mparams->remote_ip)) {
8328 switch_nat_del_mapping((switch_port_t) v_engine->local_sdp_port, SWITCH_NAT_UDP);
8329 switch_nat_del_mapping((switch_port_t) v_engine->local_sdp_port + 1, SWITCH_NAT_UDP);
8330 }
8331
8332
8333 if (t_engine->media_thread) {
8334 switch_status_t st;
8335
8336 t_engine->mh.up = 0;
8337 switch_thread_join(&st, t_engine->media_thread);
8338 t_engine->media_thread = NULL;
8339 }
8340
8341
8342 if (t_engine->rtp_session) {
8343 switch_rtp_destroy(&t_engine->rtp_session);
8344 } else if (t_engine->local_sdp_port) {
8345 switch_rtp_release_port(smh->mparams->rtpip, t_engine->local_sdp_port);
8346 }
8347
8348
8349 if (t_engine->local_sdp_port > 0 && !zstr(smh->mparams->remote_ip) &&
8350 switch_core_media_check_nat(smh, smh->mparams->remote_ip)) {
8351 switch_nat_del_mapping((switch_port_t) t_engine->local_sdp_port, SWITCH_NAT_UDP);
8352 switch_nat_del_mapping((switch_port_t) t_engine->local_sdp_port + 1, SWITCH_NAT_UDP);
8353 }
8354
8355
8356 if (a_engine->rtp_session) {
8357 switch_rtp_destroy(&a_engine->rtp_session);
8358 } else if (a_engine->local_sdp_port) {
8359 switch_rtp_release_port(smh->mparams->rtpip, a_engine->local_sdp_port);
8360 }
8361
8362 if (a_engine->local_sdp_port > 0 && !zstr(smh->mparams->remote_ip) &&
8363 switch_core_media_check_nat(smh, smh->mparams->remote_ip)) {
8364 switch_nat_del_mapping((switch_port_t) a_engine->local_sdp_port, SWITCH_NAT_UDP);
8365 switch_nat_del_mapping((switch_port_t) a_engine->local_sdp_port + 1, SWITCH_NAT_UDP);
8366 }
8367
8368 }
8369
8370
8371 //?
gen_ice(switch_core_session_t * session,switch_media_type_t type,const char * ip,switch_port_t port)8372 static void gen_ice(switch_core_session_t *session, switch_media_type_t type, const char *ip, switch_port_t port)
8373 {
8374 switch_media_handle_t *smh;
8375 switch_rtp_engine_t *engine;
8376 char tmp[33] = "";
8377
8378 switch_assert(session);
8379
8380 if (!(smh = session->media_handle)) {
8381 return;
8382 }
8383
8384 engine = &smh->engines[type];
8385
8386 //#ifdef RTCP_MUX
8387 //if (!engine->rtcp_mux) {// && type == SWITCH_MEDIA_TYPE_AUDIO) {
8388 // engine->rtcp_mux = SWITCH_TRUE;
8389 //}
8390 //#endif
8391
8392 if (!smh->msid) {
8393 switch_stun_random_string(tmp, 32, NULL);
8394 tmp[32] = '\0';
8395 smh->msid = switch_core_session_strdup(session, tmp);
8396 }
8397
8398 if (!smh->cname) {
8399 switch_stun_random_string(tmp, 16, NULL);
8400 tmp[16] = '\0';
8401 smh->cname = switch_core_session_strdup(session, tmp);
8402 }
8403
8404 if (!engine->ice_out.ufrag) {
8405 switch_stun_random_string(tmp, 16, NULL);
8406 tmp[16] = '\0';
8407 engine->ice_out.ufrag = switch_core_session_strdup(session, tmp);
8408 }
8409
8410 if (!engine->ice_out.pwd) {
8411 switch_stun_random_string(tmp, 24, NULL);
8412 tmp[24] = '\0';
8413 engine->ice_out.pwd = switch_core_session_strdup(session, tmp);
8414 }
8415
8416 if (!engine->ice_out.cands[0][0].foundation) {
8417 switch_stun_random_string(tmp, 10, "0123456789");
8418 tmp[10] = '\0';
8419 engine->ice_out.cands[0][0].foundation = switch_core_session_strdup(session, tmp);
8420 }
8421
8422 engine->ice_out.cands[0][0].transport = "udp";
8423
8424 if (!engine->ice_out.cands[0][0].component_id) {
8425 engine->ice_out.cands[0][0].component_id = 1;
8426 engine->ice_out.cands[0][0].priority = (2^24)*126 + (2^8)*65535 + (2^0)*(256 - engine->ice_out.cands[0][0].component_id);
8427 }
8428
8429 if (!zstr(ip)) {
8430 engine->ice_out.cands[0][0].con_addr = switch_core_session_strdup(session, ip);
8431 }
8432
8433 if (port) {
8434 engine->ice_out.cands[0][0].con_port = port;
8435 }
8436
8437 engine->ice_out.cands[0][0].generation = "0";
8438 //add rport stuff later
8439
8440 engine->ice_out.cands[0][0].ready = 1;
8441
8442
8443 }
8444
switch_core_session_wake_video_thread(switch_core_session_t * session)8445 SWITCH_DECLARE(void) switch_core_session_wake_video_thread(switch_core_session_t *session)
8446 {
8447 switch_media_handle_t *smh;
8448 switch_rtp_engine_t *v_engine;
8449
8450 if (!(smh = session->media_handle)) {
8451 return;
8452 }
8453
8454 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
8455
8456 if ((!smh->mparams->external_video_source) && (!v_engine->rtp_session)) {
8457 return;
8458 }
8459
8460 if (!v_engine->media_thread) {
8461 return;
8462 }
8463
8464 if (!v_engine->mh.cond_mutex) {
8465 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Channel %s has no cond?\n",
8466 switch_channel_get_name(session->channel));
8467 return;
8468 }
8469
8470 if (switch_mutex_trylock(v_engine->mh.cond_mutex) == SWITCH_STATUS_SUCCESS) {
8471 switch_thread_cond_broadcast(v_engine->mh.cond);
8472 switch_mutex_unlock(v_engine->mh.cond_mutex);
8473 }
8474 }
8475
check_dtls_reinvite(switch_core_session_t * session,switch_rtp_engine_t * engine)8476 static void check_dtls_reinvite(switch_core_session_t *session, switch_rtp_engine_t *engine)
8477 {
8478 if (switch_channel_test_flag(session->channel, CF_REINVITE) && engine->new_dtls) {
8479
8480 if (!zstr(engine->local_dtls_fingerprint.str) && switch_rtp_has_dtls() && dtls_ok(session)) {
8481
8482 #ifdef HAVE_OPENSSL_DTLSv1_2_method
8483 uint8_t want_DTLSv1_2 = 1;
8484 #else
8485 uint8_t want_DTLSv1_2 = 0;
8486 #endif // HAVE_OPENSSL_DTLSv1_2_method
8487
8488 dtls_type_t xtype, dtype = engine->dtls_controller ? DTLS_TYPE_CLIENT : DTLS_TYPE_SERVER;
8489
8490 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "RE-SETTING %s DTLS\n", type2str(engine->type));
8491
8492 xtype = DTLS_TYPE_RTP;
8493 if (engine->rtcp_mux > 0) xtype |= DTLS_TYPE_RTCP;
8494
8495 if (switch_channel_var_true(session->channel, "legacyDTLS")) {
8496 switch_channel_clear_flag(session->channel, CF_WANT_DTLSv1_2);
8497 want_DTLSv1_2 = 0;
8498 }
8499
8500 switch_rtp_add_dtls(engine->rtp_session, &engine->local_dtls_fingerprint, &engine->remote_dtls_fingerprint, dtype | xtype, want_DTLSv1_2);
8501
8502 if (engine->rtcp_mux < 1) {
8503 xtype = DTLS_TYPE_RTCP;
8504 switch_rtp_add_dtls(engine->rtp_session, &engine->local_dtls_fingerprint, &engine->remote_dtls_fingerprint, dtype | xtype, want_DTLSv1_2);
8505 }
8506
8507 }
8508 engine->new_dtls = 0;
8509 }
8510 }
8511
8512 //?
switch_core_media_activate_rtp(switch_core_session_t * session)8513 SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_session_t *session)
8514
8515 {
8516 const char *err = NULL;
8517 const char *val = NULL;
8518 switch_rtp_flag_t flags[SWITCH_RTP_FLAG_INVALID] = {0};
8519 switch_status_t status = SWITCH_STATUS_SUCCESS;
8520 char tmp[50];
8521 char *timer_name = NULL;
8522 const char *var;
8523 switch_rtp_engine_t *a_engine, *v_engine, *t_engine;
8524 switch_media_handle_t *smh;
8525 int is_reinvite = 0;
8526
8527 #ifdef HAVE_OPENSSL_DTLSv1_2_method
8528 uint8_t want_DTLSv1_2 = 1;
8529 #else
8530 uint8_t want_DTLSv1_2 = 0;
8531 #endif
8532
8533 switch_assert(session);
8534
8535 if (!(smh = session->media_handle)) {
8536 return SWITCH_STATUS_FALSE;
8537 }
8538
8539 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
8540 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
8541 t_engine = &smh->engines[SWITCH_MEDIA_TYPE_TEXT];
8542
8543 if (a_engine->rtp_session || v_engine->rtp_session || t_engine->rtp_session || switch_channel_test_flag(session->channel, CF_REINVITE)) {
8544 is_reinvite = 1;
8545 }
8546
8547
8548 if (switch_channel_down(session->channel)) {
8549 return SWITCH_STATUS_FALSE;
8550 }
8551
8552 switch_core_media_parse_media_flags(session);
8553
8554 if (switch_rtp_ready(a_engine->rtp_session)) {
8555 switch_rtp_reset_media_timer(a_engine->rtp_session);
8556 check_media_timeout_params(session, a_engine);
8557 check_media_timeout_params(session, v_engine);
8558 }
8559
8560 if (a_engine->crypto_type != CRYPTO_INVALID) {
8561 switch_channel_set_flag(session->channel, CF_SECURE);
8562 }
8563
8564 if (want_DTLSv1_2) {
8565 switch_channel_set_flag(session->channel, CF_WANT_DTLSv1_2);
8566 }
8567
8568 if (switch_channel_test_flag(session->channel, CF_PROXY_MODE)) {
8569 status = SWITCH_STATUS_SUCCESS;
8570 goto end;
8571 }
8572
8573 if (!is_reinvite) {
8574 if (switch_rtp_ready(a_engine->rtp_session)) {
8575 if (switch_channel_test_flag(session->channel, CF_TEXT_POSSIBLE) && !switch_rtp_ready(t_engine->rtp_session)) {
8576 goto text;
8577 }
8578
8579 if (switch_channel_test_flag(session->channel, CF_VIDEO_POSSIBLE) && !switch_rtp_ready(v_engine->rtp_session)) {
8580 goto video;
8581 }
8582
8583 status = SWITCH_STATUS_SUCCESS;
8584 goto end;
8585 }
8586 }
8587
8588 if ((status = switch_core_media_set_codec(session, 0, smh->mparams->codec_flags)) != SWITCH_STATUS_SUCCESS) {
8589 goto end;
8590 }
8591
8592 switch_core_media_set_video_codec(session, 0);
8593
8594
8595 memset(flags, 0, sizeof(flags));
8596 flags[SWITCH_RTP_FLAG_DATAWAIT]++;
8597
8598 if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) && !switch_channel_test_flag(session->channel, CF_AVPF) &&
8599 !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")) && switch_true(val))) {
8600 flags[SWITCH_RTP_FLAG_AUTOADJ]++;
8601 }
8602
8603 if (switch_media_handle_test_media_flag(smh, SCMF_PASS_RFC2833)
8604 || ((val = switch_channel_get_variable(session->channel, "pass_rfc2833")) && switch_true(val))) {
8605 switch_channel_set_flag(session->channel, CF_PASS_RFC2833);
8606 }
8607
8608
8609 if (switch_media_handle_test_media_flag(smh, SCMF_AUTOFLUSH)
8610 || ((val = switch_channel_get_variable(session->channel, "rtp_autoflush")) && switch_true(val))) {
8611 flags[SWITCH_RTP_FLAG_AUTOFLUSH]++;
8612 }
8613
8614 if (!(switch_media_handle_test_media_flag(smh, SCMF_REWRITE_TIMESTAMPS) ||
8615 ((val = switch_channel_get_variable(session->channel, "rtp_rewrite_timestamps")) && switch_true(val)))) {
8616 flags[SWITCH_RTP_FLAG_RAW_WRITE]++;
8617 }
8618
8619 if (switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG)) {
8620 smh->mparams->cng_pt = 0;
8621 } else if (smh->mparams->cng_pt) {
8622 flags[SWITCH_RTP_FLAG_AUTO_CNG]++;
8623 }
8624
8625 #if __BYTE_ORDER == __LITTLE_ENDIAN
8626 if (!strcasecmp(a_engine->read_impl.iananame, "L16")) {
8627 flags[SWITCH_RTP_FLAG_BYTESWAP]++;
8628 }
8629 #endif
8630
8631 if ((flags[SWITCH_RTP_FLAG_BYTESWAP]) && (val = switch_channel_get_variable(session->channel, "rtp_disable_byteswap")) && switch_true(val)) {
8632 flags[SWITCH_RTP_FLAG_BYTESWAP] = 0;
8633 }
8634
8635 if (a_engine->rtp_session && is_reinvite) {
8636 //const char *ip = switch_channel_get_variable(session->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE);
8637 //const char *port = switch_channel_get_variable(session->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE);
8638 char *remote_host = switch_rtp_get_remote_host(a_engine->rtp_session);
8639 switch_port_t remote_port = switch_rtp_get_remote_port(a_engine->rtp_session);
8640
8641 if (remote_host && remote_port && !strcmp(remote_host, a_engine->cur_payload_map->remote_sdp_ip) &&
8642 remote_port == a_engine->cur_payload_map->remote_sdp_port) {
8643 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio params are unchanged for %s.\n",
8644 switch_channel_get_name(session->channel));
8645 a_engine->cur_payload_map->negotiated = 1;
8646 //XX
8647 goto video;
8648 } else {
8649 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio params changed for %s from %s:%d to %s:%d\n",
8650 switch_channel_get_name(session->channel),
8651 remote_host, remote_port, a_engine->cur_payload_map->remote_sdp_ip, a_engine->cur_payload_map->remote_sdp_port);
8652
8653 switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->cur_payload_map->remote_sdp_port);
8654 switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, a_engine->cur_payload_map->remote_sdp_ip);
8655 switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp);
8656 switch_channel_execute_on(session->channel, "execute_on_audio_change");
8657 }
8658 }
8659
8660 if (!switch_channel_test_flag(session->channel, CF_PROXY_MEDIA)) {
8661 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "AUDIO RTP [%s] %s port %d -> %s port %d codec: %u ms: %d\n",
8662 switch_channel_get_name(session->channel),
8663 a_engine->local_sdp_ip,
8664 a_engine->local_sdp_port,
8665 a_engine->cur_payload_map->remote_sdp_ip,
8666 a_engine->cur_payload_map->remote_sdp_port, a_engine->cur_payload_map->pt, a_engine->read_impl.microseconds_per_packet / 1000);
8667
8668 //XX
8669 }
8670
8671 switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->local_sdp_port);
8672 switch_channel_set_variable(session->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE, a_engine->local_sdp_ip);
8673 switch_channel_set_variable(session->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE, tmp);
8674 switch_channel_set_variable(session->channel, SWITCH_ADVERTISED_MEDIA_IP_VARIABLE, a_engine->adv_sdp_ip);
8675
8676 if (a_engine->rtp_session && is_reinvite) {
8677 const char *rport = NULL;
8678 switch_port_t remote_rtcp_port = a_engine->remote_rtcp_port;
8679
8680 if (!remote_rtcp_port) {
8681 if ((rport = switch_channel_get_variable(session->channel, "rtp_remote_audio_rtcp_port"))) {
8682 remote_rtcp_port = (switch_port_t)atoi(rport);
8683 }
8684 }
8685
8686 if (switch_rtp_set_remote_address(a_engine->rtp_session, a_engine->cur_payload_map->remote_sdp_ip, a_engine->cur_payload_map->remote_sdp_port,
8687 remote_rtcp_port, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
8688 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", err);
8689 } else {
8690 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "AUDIO RTP CHANGING DEST TO: [%s:%d]\n",
8691 a_engine->cur_payload_map->remote_sdp_ip, a_engine->cur_payload_map->remote_sdp_port);
8692
8693 //if (switch_channel_test_flag(session->channel, CF_PROTO_HOLD) && strcmp(a_engine->cur_payload_map->remote_sdp_ip, "0.0.0.0")) {
8694 // switch_core_media_toggle_hold(session, 0);
8695 //}
8696
8697
8698 if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) &&
8699 !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")) && switch_true(val)) &&
8700 !switch_channel_test_flag(session->channel, CF_AVPF)) {
8701 /* Reactivate the NAT buster flag. */
8702 switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_AUTOADJ);
8703 }
8704 }
8705
8706 if (session && a_engine) {
8707 check_dtls_reinvite(session, a_engine);
8708 }
8709
8710 goto video;
8711 }
8712
8713 if (switch_channel_test_flag(session->channel, CF_PROXY_MEDIA)) {
8714 switch_core_media_proxy_remote_addr(session, NULL);
8715
8716 memset(flags, 0, sizeof(flags));
8717 flags[SWITCH_RTP_FLAG_DATAWAIT]++;
8718 flags[SWITCH_RTP_FLAG_PROXY_MEDIA]++;
8719
8720 if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) && !switch_channel_test_flag(session->channel, CF_AVPF) &&
8721 !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")) && switch_true(val))) {
8722 flags[SWITCH_RTP_FLAG_AUTOADJ]++;
8723 }
8724
8725 timer_name = NULL;
8726
8727 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
8728 "PROXY AUDIO RTP [%s] %s:%d->%s:%d codec: %u ms: %d\n",
8729 switch_channel_get_name(session->channel),
8730 a_engine->cur_payload_map->remote_sdp_ip,
8731 a_engine->cur_payload_map->remote_sdp_port,
8732 a_engine->cur_payload_map->remote_sdp_ip,
8733 a_engine->cur_payload_map->remote_sdp_port, a_engine->cur_payload_map->pt, a_engine->read_impl.microseconds_per_packet / 1000);
8734
8735 if (switch_rtp_ready(a_engine->rtp_session)) {
8736 switch_rtp_set_default_payload(a_engine->rtp_session, a_engine->cur_payload_map->pt);
8737 }
8738
8739 } else {
8740 timer_name = smh->mparams->timer_name;
8741
8742 if ((var = switch_channel_get_variable(session->channel, "rtp_timer_name"))) {
8743 timer_name = (char *) var;
8744 }
8745 }
8746
8747
8748 if (switch_channel_up(session->channel)) {
8749 switch_channel_set_variable(session->channel, "rtp_use_timer_name", timer_name);
8750
8751
8752
8753 a_engine->rtp_session = switch_rtp_new(a_engine->local_sdp_ip,
8754 a_engine->local_sdp_port,
8755 a_engine->cur_payload_map->remote_sdp_ip,
8756 a_engine->cur_payload_map->remote_sdp_port,
8757 a_engine->cur_payload_map->pt,
8758 a_engine->read_impl.samples_per_packet,
8759 a_engine->cur_payload_map->codec_ms * 1000,
8760 flags, timer_name, &err, switch_core_session_get_pool(session),
8761 0, 0);
8762
8763 if (switch_rtp_ready(a_engine->rtp_session)) {
8764 switch_rtp_set_payload_map(a_engine->rtp_session, &a_engine->payload_map);
8765 }
8766 }
8767
8768 if (switch_rtp_ready(a_engine->rtp_session)) {
8769 uint8_t vad_in = (smh->mparams->vflags & VAD_IN);
8770 uint8_t vad_out = (smh->mparams->vflags & VAD_OUT);
8771 uint8_t inb = switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_INBOUND;
8772 const char *ssrc;
8773
8774 switch_mutex_init(&smh->read_mutex[SWITCH_MEDIA_TYPE_AUDIO], SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
8775 switch_mutex_init(&smh->write_mutex[SWITCH_MEDIA_TYPE_AUDIO], SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
8776
8777 //switch_core_media_set_rtp_session(session, SWITCH_MEDIA_TYPE_AUDIO, a_engine->rtp_session);
8778
8779 if ((ssrc = switch_channel_get_variable(session->channel, "rtp_use_ssrc"))) {
8780 uint32_t ssrc_ul = (uint32_t) strtoul(ssrc, NULL, 10);
8781 switch_rtp_set_ssrc(a_engine->rtp_session, ssrc_ul);
8782 a_engine->ssrc = ssrc_ul;
8783 } else {
8784 switch_rtp_set_ssrc(a_engine->rtp_session, a_engine->ssrc);
8785 }
8786
8787 if (a_engine->remote_ssrc) {
8788 switch_rtp_set_remote_ssrc(a_engine->rtp_session, a_engine->remote_ssrc);
8789 }
8790
8791 check_media_timeout_params(session, a_engine);
8792
8793 switch_channel_set_flag(session->channel, CF_FS_RTP);
8794
8795 switch_channel_set_variable_printf(session->channel, "rtp_use_pt", "%d", a_engine->cur_payload_map->pt);
8796
8797 if ((val = switch_channel_get_variable(session->channel, "rtp_enable_vad_in")) && switch_true(val)) {
8798 vad_in = 1;
8799 }
8800 if ((val = switch_channel_get_variable(session->channel, "rtp_enable_vad_out")) && switch_true(val)) {
8801 vad_out = 1;
8802 }
8803
8804 if ((val = switch_channel_get_variable(session->channel, "rtp_disable_vad_in")) && switch_true(val)) {
8805 vad_in = 0;
8806 }
8807 if ((val = switch_channel_get_variable(session->channel, "rtp_disable_vad_out")) && switch_true(val)) {
8808 vad_out = 0;
8809 }
8810
8811
8812 a_engine->ssrc = switch_rtp_get_ssrc(a_engine->rtp_session);
8813 switch_channel_set_variable_printf(session->channel, "rtp_use_ssrc", "%u", a_engine->ssrc);
8814
8815
8816
8817 if (smh->mparams->auto_rtp_bugs & RTP_BUG_IGNORE_MARK_BIT) {
8818 a_engine->rtp_bugs |= RTP_BUG_IGNORE_MARK_BIT;
8819 }
8820
8821 if ((val = switch_channel_get_variable(session->channel, "rtp_manual_rtp_bugs"))) {
8822 switch_core_media_parse_rtp_bugs(&a_engine->rtp_bugs, val);
8823 }
8824
8825 //if (switch_channel_test_flag(session->channel, CF_AVPF)) {
8826 // smh->mparams->manual_rtp_bugs = RTP_BUG_SEND_LINEAR_TIMESTAMPS;
8827 //}
8828
8829 switch_rtp_intentional_bugs(a_engine->rtp_session, a_engine->rtp_bugs | smh->mparams->manual_rtp_bugs);
8830
8831 if ((vad_in && inb) || (vad_out && !inb)) {
8832 switch_rtp_enable_vad(a_engine->rtp_session, session, &a_engine->read_codec, SWITCH_VAD_FLAG_TALKING | SWITCH_VAD_FLAG_EVENTS_TALK | SWITCH_VAD_FLAG_EVENTS_NOTALK);
8833
8834 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "AUDIO RTP Engage VAD for %s ( %s %s )\n",
8835 switch_channel_get_name(switch_core_session_get_channel(session)), vad_in ? "in" : "", vad_out ? "out" : "");
8836 }
8837
8838
8839 if (a_engine->ice_in.cands[a_engine->ice_in.chosen[0]][0].ready) {
8840
8841 gen_ice(session, SWITCH_MEDIA_TYPE_AUDIO, NULL, 0);
8842
8843 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating Audio ICE\n");
8844
8845 switch_rtp_activate_ice(a_engine->rtp_session,
8846 a_engine->ice_in.ufrag,
8847 a_engine->ice_out.ufrag,
8848 a_engine->ice_out.pwd,
8849 a_engine->ice_in.pwd,
8850 IPR_RTP,
8851 #ifdef GOOGLE_ICE
8852 ICE_GOOGLE_JINGLE,
8853 NULL
8854 #else
8855 switch_determine_ice_type(a_engine, session),
8856 &a_engine->ice_in
8857 #endif
8858 );
8859
8860
8861
8862 }
8863
8864 if ((val = switch_channel_get_variable(session->channel, "rtcp_audio_interval_msec")) || (val = smh->mparams->rtcp_audio_interval_msec)) {
8865 const char *rport = switch_channel_get_variable(session->channel, "rtp_remote_audio_rtcp_port");
8866 switch_port_t remote_rtcp_port = a_engine->remote_rtcp_port;
8867
8868 if (!remote_rtcp_port && rport) {
8869 remote_rtcp_port = (switch_port_t)atoi(rport);
8870 }
8871
8872 if (!strcasecmp(val, "passthru")) {
8873 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating RTCP PASSTHRU PORT %d\n", remote_rtcp_port);
8874 switch_rtp_activate_rtcp(a_engine->rtp_session, -1, remote_rtcp_port, a_engine->rtcp_mux > 0);
8875 } else {
8876 int interval = atoi(val);
8877 if (interval < 100 || interval > 500000) {
8878 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,
8879 "Invalid rtcp interval spec [%d] must be between 100 and 500000\n", interval);
8880 interval = 5000;
8881 }
8882
8883 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Activating RTCP PORT %d\n", remote_rtcp_port);
8884 switch_rtp_activate_rtcp(a_engine->rtp_session, interval, remote_rtcp_port, a_engine->rtcp_mux > 0);
8885
8886 }
8887
8888 if (a_engine->ice_in.cands[a_engine->ice_in.chosen[1]][1].ready && a_engine->ice_in.cands[a_engine->ice_in.chosen[0]][0].ready &&
8889 !zstr(a_engine->ice_in.cands[a_engine->ice_in.chosen[1]][1].con_addr) &&
8890 !zstr(a_engine->ice_in.cands[a_engine->ice_in.chosen[0]][0].con_addr)) {
8891 if (a_engine->rtcp_mux > 0 &&
8892 !strcmp(a_engine->ice_in.cands[a_engine->ice_in.chosen[1]][1].con_addr, a_engine->ice_in.cands[a_engine->ice_in.chosen[0]][0].con_addr)
8893 && a_engine->ice_in.cands[a_engine->ice_in.chosen[1]][1].con_port == a_engine->ice_in.cands[a_engine->ice_in.chosen[0]][0].con_port) {
8894 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Skipping RTCP ICE (Same as RTP)\n");
8895 } else {
8896 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating RTCP ICE\n");
8897
8898 switch_rtp_activate_ice(a_engine->rtp_session,
8899 a_engine->ice_in.ufrag,
8900 a_engine->ice_out.ufrag,
8901 a_engine->ice_out.pwd,
8902 a_engine->ice_in.pwd,
8903 IPR_RTCP,
8904 #ifdef GOOGLE_ICE
8905 ICE_GOOGLE_JINGLE,
8906 NULL
8907 #else
8908 switch_determine_ice_type(a_engine, session),
8909 &a_engine->ice_in
8910 #endif
8911 );
8912 }
8913
8914 }
8915 }
8916
8917 if (!zstr(a_engine->local_dtls_fingerprint.str) && switch_rtp_has_dtls() && dtls_ok(smh->session)) {
8918 dtls_type_t xtype, dtype = a_engine->dtls_controller ? DTLS_TYPE_CLIENT : DTLS_TYPE_SERVER;
8919
8920 //if (switch_channel_test_flag(smh->session->channel, CF_3PCC)) {
8921 // dtype = (dtype == DTLS_TYPE_CLIENT) ? DTLS_TYPE_SERVER : DTLS_TYPE_CLIENT;
8922 //}
8923
8924 xtype = DTLS_TYPE_RTP;
8925 if (a_engine->rtcp_mux > 0 && smh->mparams->rtcp_audio_interval_msec) xtype |= DTLS_TYPE_RTCP;
8926
8927 if (switch_channel_var_true(session->channel, "legacyDTLS")) {
8928 switch_channel_clear_flag(session->channel, CF_WANT_DTLSv1_2);
8929 want_DTLSv1_2 = 0;
8930 }
8931
8932 switch_rtp_add_dtls(a_engine->rtp_session, &a_engine->local_dtls_fingerprint, &a_engine->remote_dtls_fingerprint, dtype | xtype, want_DTLSv1_2);
8933
8934 if (a_engine->rtcp_mux < 1 && smh->mparams->rtcp_audio_interval_msec) {
8935 xtype = DTLS_TYPE_RTCP;
8936 switch_rtp_add_dtls(a_engine->rtp_session, &a_engine->local_dtls_fingerprint, &a_engine->remote_dtls_fingerprint, dtype | xtype, want_DTLSv1_2);
8937 }
8938
8939 }
8940
8941 check_jb(session, NULL, 0, 0, SWITCH_FALSE);
8942
8943 if ((val = switch_channel_get_variable(session->channel, "rtp_timeout_sec"))) {
8944 int v = atoi(val);
8945 if (v >= 0) {
8946 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
8947 "rtp_timeout_sec deprecated use media_timeout variable.\n");
8948 smh->mparams->rtp_timeout_sec = v;
8949 }
8950 }
8951
8952 if ((val = switch_channel_get_variable(session->channel, "rtp_hold_timeout_sec"))) {
8953 int v = atoi(val);
8954 if (v >= 0) {
8955 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
8956 "rtp_hold_timeout_sec deprecated use media_hold_timeout variable.\n");
8957 smh->mparams->rtp_hold_timeout_sec = v;
8958 }
8959 }
8960
8961 if (smh->mparams->rtp_timeout_sec) {
8962 a_engine->max_missed_packets = (a_engine->read_impl.samples_per_second * smh->mparams->rtp_timeout_sec) / a_engine->read_impl.samples_per_packet;
8963
8964 switch_rtp_set_max_missed_packets(a_engine->rtp_session, a_engine->max_missed_packets);
8965 if (!smh->mparams->rtp_hold_timeout_sec) {
8966 smh->mparams->rtp_hold_timeout_sec = smh->mparams->rtp_timeout_sec * 10;
8967 }
8968 }
8969
8970 if (smh->mparams->rtp_hold_timeout_sec) {
8971 a_engine->max_missed_hold_packets = (a_engine->read_impl.samples_per_second * smh->mparams->rtp_hold_timeout_sec) / a_engine->read_impl.samples_per_packet;
8972 }
8973
8974 if (smh->mparams->te) {
8975 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Set 2833 dtmf send payload to %u\n",
8976 switch_channel_get_name(session->channel), smh->mparams->te);
8977 switch_rtp_set_telephony_event(a_engine->rtp_session, smh->mparams->te);
8978 switch_channel_set_variable_printf(session->channel, "rtp_2833_send_payload", "%d", smh->mparams->te);
8979 }
8980
8981 if (smh->mparams->recv_te) {
8982 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Set 2833 dtmf receive payload to %u\n",
8983 switch_channel_get_name(session->channel), smh->mparams->recv_te);
8984 switch_rtp_set_telephony_recv_event(a_engine->rtp_session, smh->mparams->recv_te);
8985 switch_channel_set_variable_printf(session->channel, "rtp_2833_recv_payload", "%d", smh->mparams->recv_te);
8986 }
8987
8988 //XX
8989
8990 if (switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG) ||
8991 ((val = switch_channel_get_variable(session->channel, "supress_cng")) && switch_true(val)) ||
8992 ((val = switch_channel_get_variable(session->channel, "suppress_cng")) && switch_true(val))) {
8993 smh->mparams->cng_pt = 0;
8994 }
8995
8996 if (((val = switch_channel_get_variable(session->channel, "rtp_digit_delay")))) {
8997 int delayi = atoi(val);
8998 if (delayi < 0) delayi = 0;
8999 smh->mparams->dtmf_delay = (uint32_t) delayi;
9000 }
9001
9002
9003 if (smh->mparams->dtmf_delay) {
9004 switch_rtp_set_interdigit_delay(a_engine->rtp_session, smh->mparams->dtmf_delay);
9005 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
9006 "%s Set rtp dtmf delay to %u\n", switch_channel_get_name(session->channel), smh->mparams->dtmf_delay);
9007
9008 }
9009
9010 if (smh->mparams->cng_pt && !switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG)) {
9011 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set comfort noise payload to %u\n", smh->mparams->cng_pt);
9012 switch_rtp_set_cng_pt(a_engine->rtp_session, smh->mparams->cng_pt);
9013 }
9014
9015 switch_core_session_apply_crypto(session, SWITCH_MEDIA_TYPE_AUDIO);
9016
9017 switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->cur_payload_map->remote_sdp_port);
9018 switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, a_engine->cur_payload_map->remote_sdp_ip);
9019 switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp);
9020
9021
9022 if (switch_channel_test_flag(session->channel, CF_ZRTP_PASSTHRU)) {
9023 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating ZRTP PROXY MODE\n");
9024 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Disable NOTIMER_DURING_BRIDGE\n");
9025 switch_channel_clear_flag(session->channel, CF_NOTIMER_DURING_BRIDGE);
9026 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Activating audio UDPTL mode\n");
9027 switch_rtp_udptl_mode(a_engine->rtp_session);
9028 }
9029
9030
9031
9032 text:
9033
9034 //if (switch_channel_test_flag(session->channel, CF_MSRP)) { // skip RTP RTT
9035 // goto video;
9036 //}
9037
9038 if (switch_channel_test_flag(session->channel, CF_TEXT_POSSIBLE) && t_engine->cur_payload_map->rm_encoding && t_engine->cur_payload_map->remote_sdp_port) {
9039 /******************************************************************************************/
9040 if (t_engine->rtp_session && is_reinvite) {
9041 //const char *ip = switch_channel_get_variable(session->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE);
9042 //const char *port = switch_channel_get_variable(session->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE);
9043 char *remote_host = switch_rtp_get_remote_host(t_engine->rtp_session);
9044 switch_port_t remote_port = switch_rtp_get_remote_port(t_engine->rtp_session);
9045
9046
9047
9048 if (remote_host && remote_port && !strcmp(remote_host, t_engine->cur_payload_map->remote_sdp_ip) && remote_port == t_engine->cur_payload_map->remote_sdp_port) {
9049 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Text params are unchanged for %s.\n",
9050 switch_channel_get_name(session->channel));
9051 t_engine->cur_payload_map->negotiated = 1;
9052 goto text_up;
9053 } else {
9054 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Text params changed for %s from %s:%d to %s:%d\n",
9055 switch_channel_get_name(session->channel),
9056 remote_host, remote_port, t_engine->cur_payload_map->remote_sdp_ip, t_engine->cur_payload_map->remote_sdp_port);
9057 }
9058 }
9059
9060 if (!switch_channel_test_flag(session->channel, CF_PROXY_MEDIA)) {
9061 if (switch_rtp_ready(t_engine->rtp_session)) {
9062 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
9063 "TEXT RTP [%s] %s port %d -> %s port %d codec: %u\n", switch_channel_get_name(session->channel),
9064 t_engine->local_sdp_ip, t_engine->local_sdp_port, t_engine->cur_payload_map->remote_sdp_ip,
9065 t_engine->cur_payload_map->remote_sdp_port, t_engine->cur_payload_map->pt);
9066
9067 switch_rtp_set_default_payload(t_engine->rtp_session, t_engine->cur_payload_map->pt);
9068 }
9069 }
9070
9071 switch_snprintf(tmp, sizeof(tmp), "%d", t_engine->local_sdp_port);
9072 switch_channel_set_variable(session->channel, SWITCH_LOCAL_TEXT_IP_VARIABLE, a_engine->adv_sdp_ip);
9073 switch_channel_set_variable(session->channel, SWITCH_LOCAL_TEXT_PORT_VARIABLE, tmp);
9074
9075
9076 if (t_engine->rtp_session && is_reinvite) {
9077 const char *rport = NULL;
9078 switch_port_t remote_rtcp_port = t_engine->remote_rtcp_port;
9079
9080 //switch_channel_clear_flag(session->channel, CF_REINVITE);
9081
9082 if (!remote_rtcp_port) {
9083 if ((rport = switch_channel_get_variable(session->channel, "rtp_remote_text_rtcp_port"))) {
9084 remote_rtcp_port = (switch_port_t)atoi(rport);
9085 }
9086 }
9087
9088 if (switch_rtp_set_remote_address
9089 (t_engine->rtp_session, t_engine->cur_payload_map->remote_sdp_ip, t_engine->cur_payload_map->remote_sdp_port, remote_rtcp_port, SWITCH_TRUE,
9090 &err) != SWITCH_STATUS_SUCCESS) {
9091 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "TEXT RTP REPORTS ERROR: [%s]\n", err);
9092 } else {
9093 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "TEXT RTP CHANGING DEST TO: [%s:%d]\n",
9094 t_engine->cur_payload_map->remote_sdp_ip, t_engine->cur_payload_map->remote_sdp_port);
9095 if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) && !switch_channel_test_flag(session->channel, CF_AVPF) &&
9096 !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")) && switch_true(val))) {
9097 /* Reactivate the NAT buster flag. */
9098 switch_rtp_set_flag(t_engine->rtp_session, SWITCH_RTP_FLAG_AUTOADJ);
9099 }
9100
9101 }
9102 goto text_up;
9103 }
9104
9105 if (switch_channel_test_flag(session->channel, CF_PROXY_MEDIA)) {
9106 switch_core_media_proxy_remote_addr(session, NULL);
9107
9108 memset(flags, 0, sizeof(flags));
9109 flags[SWITCH_RTP_FLAG_PROXY_MEDIA]++;
9110 flags[SWITCH_RTP_FLAG_DATAWAIT]++;
9111
9112 if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) && !switch_channel_test_flag(session->channel, CF_AVPF) &&
9113 !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")) && switch_true(val))) {
9114 flags[SWITCH_RTP_FLAG_AUTOADJ]++;
9115 }
9116
9117 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
9118 "PROXY TEXT RTP [%s] %s:%d->%s:%d codec: %u ms: %d\n",
9119 switch_channel_get_name(session->channel),
9120 a_engine->cur_payload_map->remote_sdp_ip,
9121 t_engine->local_sdp_port,
9122 t_engine->cur_payload_map->remote_sdp_ip,
9123 t_engine->cur_payload_map->remote_sdp_port, t_engine->cur_payload_map->pt, t_engine->read_impl.microseconds_per_packet / 1000);
9124
9125 if (switch_rtp_ready(t_engine->rtp_session)) {
9126 switch_rtp_set_default_payload(t_engine->rtp_session, t_engine->cur_payload_map->pt);
9127 }
9128 }
9129
9130 /******************************************************************************************/
9131
9132 if (t_engine->rtp_session) {
9133 goto text_up;
9134 }
9135
9136
9137 if (!t_engine->local_sdp_port) {
9138 switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_TEXT, 1);
9139 }
9140
9141 memset(flags, 0, sizeof(flags));
9142 flags[SWITCH_RTP_FLAG_DATAWAIT]++;
9143 flags[SWITCH_RTP_FLAG_RAW_WRITE]++;
9144
9145 if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) && !switch_channel_test_flag(session->channel, CF_PROXY_MODE) &&
9146 !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")) && switch_true(val)) &&
9147 !switch_channel_test_flag(session->channel, CF_AVPF)) {
9148 flags[SWITCH_RTP_FLAG_AUTOADJ]++;
9149 }
9150
9151 if (switch_channel_test_flag(session->channel, CF_PROXY_MEDIA)) {
9152 flags[SWITCH_RTP_FLAG_PROXY_MEDIA]++;
9153 }
9154 //TEXT switch_core_media_set_text_codec(session, 0);
9155
9156 flags[SWITCH_RTP_FLAG_USE_TIMER] = 1;
9157 flags[SWITCH_RTP_FLAG_NOBLOCK] = 0;
9158 flags[SWITCH_RTP_FLAG_TEXT]++;
9159 //flags[SWITCH_RTP_FLAG_VIDEO]++;
9160
9161 t_engine->rtp_session = switch_rtp_new(a_engine->local_sdp_ip,
9162 t_engine->local_sdp_port,
9163 t_engine->cur_payload_map->remote_sdp_ip,
9164 t_engine->cur_payload_map->remote_sdp_port,
9165 t_engine->cur_payload_map->pt,
9166 TEXT_TIMER_SAMPLES, TEXT_TIMER_MS * 1000, flags, NULL, &err, switch_core_session_get_pool(session),
9167 0, 0);
9168
9169
9170 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%sTEXT RTP [%s] %s:%d->%s:%d codec: %u ms: %d [%s]\n",
9171 switch_channel_test_flag(session->channel, CF_PROXY_MEDIA) ? "PROXY " : "",
9172 switch_channel_get_name(session->channel),
9173 a_engine->local_sdp_ip,
9174 t_engine->local_sdp_port,
9175 t_engine->cur_payload_map->remote_sdp_ip,
9176 t_engine->cur_payload_map->remote_sdp_port, t_engine->cur_payload_map->pt,
9177 0, switch_rtp_ready(t_engine->rtp_session) ? "SUCCESS" : err);
9178
9179
9180 if (switch_rtp_ready(t_engine->rtp_session)) {
9181 const char *ssrc;
9182
9183
9184 if (!t_engine->tf) {
9185 switch_rtp_text_factory_create(&t_engine->tf, switch_core_session_get_pool(session));
9186 }
9187
9188 switch_rtp_set_video_buffer_size(t_engine->rtp_session, 2, 2048);
9189
9190 switch_rtp_set_payload_map(t_engine->rtp_session, &t_engine->payload_map);
9191 switch_channel_set_flag(session->channel, CF_HAS_TEXT);
9192 switch_core_session_start_text_thread(session);
9193
9194 if ((ssrc = switch_channel_get_variable(session->channel, "rtp_use_text_ssrc"))) {
9195 uint32_t ssrc_ul = (uint32_t) strtoul(ssrc, NULL, 10);
9196 switch_rtp_set_ssrc(t_engine->rtp_session, ssrc_ul);
9197 t_engine->ssrc = ssrc_ul;
9198 } else {
9199 switch_rtp_set_ssrc(t_engine->rtp_session, t_engine->ssrc);
9200 }
9201
9202 if (t_engine->remote_ssrc) {
9203 switch_rtp_set_remote_ssrc(t_engine->rtp_session, t_engine->remote_ssrc);
9204 }
9205
9206 if (t_engine->ice_in.cands[t_engine->ice_in.chosen[0]][0].ready) {
9207
9208 gen_ice(session, SWITCH_MEDIA_TYPE_TEXT, NULL, 0);
9209
9210 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating Text ICE\n");
9211
9212 switch_rtp_activate_ice(t_engine->rtp_session,
9213 t_engine->ice_in.ufrag,
9214 t_engine->ice_out.ufrag,
9215 t_engine->ice_out.pwd,
9216 t_engine->ice_in.pwd,
9217 IPR_RTP,
9218 #ifdef GOOGLE_ICE
9219 ICE_GOOGLE_JINGLE,
9220 NULL
9221 #else
9222 switch_determine_ice_type(t_engine, session),
9223 &t_engine->ice_in
9224 #endif
9225 );
9226
9227
9228 }
9229
9230 if ((val = switch_channel_get_variable(session->channel, "rtcp_text_interval_msec")) || (val = smh->mparams->rtcp_text_interval_msec)) {
9231 const char *rport = switch_channel_get_variable(session->channel, "rtp_remote_text_rtcp_port");
9232 switch_port_t remote_port = t_engine->remote_rtcp_port;
9233
9234 if (rport) {
9235 remote_port = (switch_port_t)atoi(rport);
9236 }
9237 if (!strcasecmp(val, "passthru")) {
9238 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating TEXT RTCP PASSTHRU PORT %d\n", remote_port);
9239 switch_rtp_activate_rtcp(t_engine->rtp_session, -1, remote_port, t_engine->rtcp_mux > 0);
9240 } else {
9241 int interval = atoi(val);
9242 if (interval < 100 || interval > 500000) {
9243 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,
9244 "Invalid rtcp interval spec [%d] must be between 100 and 500000\n", interval);
9245 interval = 5000;
9246 }
9247 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO,
9248 "Activating TEXT RTCP PORT %d interval %d mux %d\n", remote_port, interval, t_engine->rtcp_mux);
9249 switch_rtp_activate_rtcp(t_engine->rtp_session, interval, remote_port, t_engine->rtcp_mux > 0);
9250
9251 }
9252
9253
9254 if (t_engine->ice_in.cands[t_engine->ice_in.chosen[1]][1].ready && t_engine->ice_in.cands[t_engine->ice_in.chosen[0]][0].ready &&
9255 !zstr(t_engine->ice_in.cands[t_engine->ice_in.chosen[1]][1].con_addr) &&
9256 !zstr(t_engine->ice_in.cands[t_engine->ice_in.chosen[0]][0].con_addr)) {
9257 if (t_engine->rtcp_mux > 0 && !strcmp(t_engine->ice_in.cands[t_engine->ice_in.chosen[1]][1].con_addr,
9258 t_engine->ice_in.cands[t_engine->ice_in.chosen[0]][0].con_addr) &&
9259 t_engine->ice_in.cands[t_engine->ice_in.chosen[1]][1].con_port == t_engine->ice_in.cands[t_engine->ice_in.chosen[0]][0].con_port) {
9260 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Skipping TEXT RTCP ICE (Same as TEXT RTP)\n");
9261 } else {
9262 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating TEXT RTCP ICE\n");
9263 switch_rtp_activate_ice(t_engine->rtp_session,
9264 t_engine->ice_in.ufrag,
9265 t_engine->ice_out.ufrag,
9266 t_engine->ice_out.pwd,
9267 t_engine->ice_in.pwd,
9268 IPR_RTCP,
9269 #ifdef GOOGLE_ICE
9270 ICE_GOOGLE_JINGLE,
9271 NULL
9272 #else
9273 switch_determine_ice_type(t_engine, session),
9274 &t_engine->ice_in
9275 #endif
9276 );
9277
9278
9279
9280 }
9281
9282 }
9283 }
9284
9285 if (!zstr(t_engine->local_dtls_fingerprint.str) && switch_rtp_has_dtls() && dtls_ok(smh->session)) {
9286 dtls_type_t xtype,
9287 dtype = t_engine->dtls_controller ? DTLS_TYPE_CLIENT : DTLS_TYPE_SERVER;
9288 xtype = DTLS_TYPE_RTP;
9289 if (t_engine->rtcp_mux > 0 && smh->mparams->rtcp_text_interval_msec) xtype |= DTLS_TYPE_RTCP;
9290
9291 if (switch_channel_var_true(session->channel, "legacyDTLS")) {
9292 switch_channel_clear_flag(session->channel, CF_WANT_DTLSv1_2);
9293 want_DTLSv1_2 = 0;
9294 }
9295
9296 switch_rtp_add_dtls(t_engine->rtp_session, &t_engine->local_dtls_fingerprint, &t_engine->remote_dtls_fingerprint, dtype | xtype, want_DTLSv1_2);
9297
9298 if (t_engine->rtcp_mux < 1 && smh->mparams->rtcp_text_interval_msec) {
9299 xtype = DTLS_TYPE_RTCP;
9300 switch_rtp_add_dtls(t_engine->rtp_session, &t_engine->local_dtls_fingerprint, &t_engine->remote_dtls_fingerprint, dtype | xtype, want_DTLSv1_2);
9301 }
9302 }
9303
9304
9305 if ((val = switch_channel_get_variable(session->channel, "rtp_manual_text_rtp_bugs"))) {
9306 switch_core_media_parse_rtp_bugs(&t_engine->rtp_bugs, val);
9307 }
9308
9309
9310 //if (switch_channel_test_flag(session->channel, CF_AVPF)) {
9311 //smh->mparams->manual_video_rtp_bugs = RTP_BUG_SEND_LINEAR_TIMESTAMPS;
9312 //}
9313
9314 switch_rtp_intentional_bugs(t_engine->rtp_session, t_engine->rtp_bugs | smh->mparams->manual_text_rtp_bugs);
9315
9316 //XX
9317
9318
9319 switch_channel_set_variable_printf(session->channel, "rtp_use_text_pt", "%d", t_engine->cur_payload_map->pt);
9320 t_engine->ssrc = switch_rtp_get_ssrc(t_engine->rtp_session);
9321 switch_channel_set_variable_printf(session->channel, "rtp_use_text_ssrc", "%u", t_engine->ssrc);
9322
9323 switch_core_session_apply_crypto(session, SWITCH_MEDIA_TYPE_TEXT);
9324
9325
9326 if (switch_channel_test_flag(session->channel, CF_ZRTP_PASSTHRU)) {
9327 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Activating text UDPTL mode\n");
9328 switch_rtp_udptl_mode(t_engine->rtp_session);
9329 }
9330
9331 } else {
9332 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "TEXT RTP REPORTS ERROR: [%s]\n", switch_str_nil(err));
9333 switch_channel_hangup(session->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
9334 goto end;
9335 }
9336 }
9337
9338
9339 text_up:
9340 video:
9341
9342 if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
9343 switch_core_media_check_video_codecs(session);
9344 }
9345
9346 if (switch_channel_test_flag(session->channel, CF_VIDEO_POSSIBLE) && v_engine->cur_payload_map->rm_encoding && v_engine->cur_payload_map->remote_sdp_port) {
9347 /******************************************************************************************/
9348 if (v_engine->rtp_session && is_reinvite) {
9349 //const char *ip = switch_channel_get_variable(session->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE);
9350 //const char *port = switch_channel_get_variable(session->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE);
9351 char *remote_host = switch_rtp_get_remote_host(v_engine->rtp_session);
9352 switch_port_t remote_port = switch_rtp_get_remote_port(v_engine->rtp_session);
9353
9354
9355
9356 if (remote_host && remote_port && !strcmp(remote_host, v_engine->cur_payload_map->remote_sdp_ip) && remote_port == v_engine->cur_payload_map->remote_sdp_port) {
9357 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Video params are unchanged for %s.\n",
9358 switch_channel_get_name(session->channel));
9359 v_engine->cur_payload_map->negotiated = 1;
9360 goto video_up;
9361 } else {
9362 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Video params changed for %s from %s:%d to %s:%d\n",
9363 switch_channel_get_name(session->channel),
9364 remote_host, remote_port, v_engine->cur_payload_map->remote_sdp_ip, v_engine->cur_payload_map->remote_sdp_port);
9365 }
9366 }
9367
9368 if (!switch_channel_test_flag(session->channel, CF_PROXY_MEDIA)) {
9369 if (switch_rtp_ready(v_engine->rtp_session)) {
9370 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
9371 "VIDEO RTP [%s] %s port %d -> %s port %d codec: %u\n", switch_channel_get_name(session->channel),
9372 v_engine->local_sdp_ip, v_engine->local_sdp_port, v_engine->cur_payload_map->remote_sdp_ip,
9373 v_engine->cur_payload_map->remote_sdp_port, v_engine->cur_payload_map->pt);
9374
9375 switch_rtp_set_default_payload(v_engine->rtp_session, v_engine->cur_payload_map->pt);
9376 }
9377 }
9378
9379 switch_snprintf(tmp, sizeof(tmp), "%d", v_engine->local_sdp_port);
9380 switch_channel_set_variable(session->channel, SWITCH_LOCAL_VIDEO_IP_VARIABLE, a_engine->adv_sdp_ip);
9381 switch_channel_set_variable(session->channel, SWITCH_LOCAL_VIDEO_PORT_VARIABLE, tmp);
9382
9383
9384 if (v_engine->rtp_session && is_reinvite) {
9385 const char *rport = NULL;
9386 switch_port_t remote_rtcp_port = v_engine->remote_rtcp_port;
9387
9388 //switch_channel_clear_flag(session->channel, CF_REINVITE);
9389
9390 if (!remote_rtcp_port) {
9391 if ((rport = switch_channel_get_variable(session->channel, "rtp_remote_video_rtcp_port"))) {
9392 remote_rtcp_port = (switch_port_t)atoi(rport);
9393 }
9394 }
9395
9396 if (switch_rtp_set_remote_address
9397 (v_engine->rtp_session, v_engine->cur_payload_map->remote_sdp_ip, v_engine->cur_payload_map->remote_sdp_port, remote_rtcp_port, SWITCH_TRUE,
9398 &err) != SWITCH_STATUS_SUCCESS) {
9399 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "VIDEO RTP REPORTS ERROR: [%s]\n", err);
9400 } else {
9401 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "VIDEO RTP CHANGING DEST TO: [%s:%d]\n",
9402 v_engine->cur_payload_map->remote_sdp_ip, v_engine->cur_payload_map->remote_sdp_port);
9403 if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) && !switch_channel_test_flag(session->channel, CF_AVPF) &&
9404 !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")) && switch_true(val))) {
9405 /* Reactivate the NAT buster flag. */
9406 switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_AUTOADJ);
9407 }
9408
9409 }
9410 goto video_up;
9411 }
9412
9413 if (switch_channel_test_flag(session->channel, CF_PROXY_MEDIA)) {
9414 switch_core_media_proxy_remote_addr(session, NULL);
9415
9416 memset(flags, 0, sizeof(flags));
9417 flags[SWITCH_RTP_FLAG_PROXY_MEDIA]++;
9418 flags[SWITCH_RTP_FLAG_DATAWAIT]++;
9419
9420 if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) && !switch_channel_test_flag(session->channel, CF_AVPF) &&
9421 !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")) && switch_true(val))) {
9422 flags[SWITCH_RTP_FLAG_AUTOADJ]++;
9423 }
9424
9425 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
9426 "PROXY VIDEO RTP [%s] %s:%d->%s:%d codec: %u ms: %d\n",
9427 switch_channel_get_name(session->channel),
9428 a_engine->cur_payload_map->remote_sdp_ip,
9429 v_engine->local_sdp_port,
9430 v_engine->cur_payload_map->remote_sdp_ip,
9431 v_engine->cur_payload_map->remote_sdp_port, v_engine->cur_payload_map->pt, v_engine->read_impl.microseconds_per_packet / 1000);
9432
9433 if (switch_rtp_ready(v_engine->rtp_session)) {
9434 switch_rtp_set_default_payload(v_engine->rtp_session, v_engine->cur_payload_map->pt);
9435 }
9436 }
9437
9438 /******************************************************************************************/
9439
9440 if (v_engine->rtp_session) {
9441 goto video_up;
9442 }
9443
9444
9445 if (!v_engine->local_sdp_port) {
9446 switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_VIDEO, 1);
9447 }
9448
9449 memset(flags, 0, sizeof(flags));
9450 flags[SWITCH_RTP_FLAG_DATAWAIT]++;
9451 flags[SWITCH_RTP_FLAG_RAW_WRITE]++;
9452
9453 if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) && !switch_channel_test_flag(session->channel, CF_PROXY_MODE) &&
9454 !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")) && switch_true(val)) &&
9455 !switch_channel_test_flag(session->channel, CF_AVPF)) {
9456 flags[SWITCH_RTP_FLAG_AUTOADJ]++;
9457 }
9458
9459 if (switch_channel_test_flag(session->channel, CF_PROXY_MEDIA)) {
9460 flags[SWITCH_RTP_FLAG_PROXY_MEDIA]++;
9461 }
9462 switch_core_media_set_video_codec(session, 0);
9463
9464 flags[SWITCH_RTP_FLAG_USE_TIMER] = 0;
9465 flags[SWITCH_RTP_FLAG_NOBLOCK] = 0;
9466 flags[SWITCH_RTP_FLAG_VIDEO]++;
9467
9468 if (v_engine->fir) {
9469 flags[SWITCH_RTP_FLAG_FIR]++;
9470 }
9471
9472 if (v_engine->pli) {
9473 flags[SWITCH_RTP_FLAG_PLI]++;
9474 }
9475
9476 if ((v_engine->nack) && !switch_channel_var_true(session->channel, "rtp_video_nack_disable")) {
9477 flags[SWITCH_RTP_FLAG_NACK]++;
9478 }
9479
9480 if (v_engine->tmmbr) {
9481 flags[SWITCH_RTP_FLAG_TMMBR]++;
9482 }
9483
9484 v_engine->rtp_session = switch_rtp_new(a_engine->local_sdp_ip,
9485 v_engine->local_sdp_port,
9486 v_engine->cur_payload_map->remote_sdp_ip,
9487 v_engine->cur_payload_map->remote_sdp_port,
9488 v_engine->cur_payload_map->pt,
9489 1, 90000, flags, NULL, &err, switch_core_session_get_pool(session),
9490 0, 0);
9491
9492
9493 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%sVIDEO RTP [%s] %s:%d->%s:%d codec: %u ms: %d [%s]\n",
9494 switch_channel_test_flag(session->channel, CF_PROXY_MEDIA) ? "PROXY " : "",
9495 switch_channel_get_name(session->channel),
9496 a_engine->local_sdp_ip,
9497 v_engine->local_sdp_port,
9498 v_engine->cur_payload_map->remote_sdp_ip,
9499 v_engine->cur_payload_map->remote_sdp_port, v_engine->cur_payload_map->pt,
9500 0, switch_rtp_ready(v_engine->rtp_session) ? "SUCCESS" : err);
9501
9502
9503 if (switch_rtp_ready(v_engine->rtp_session)) {
9504 const char *ssrc;
9505
9506 if (v_engine->fir) {
9507 switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_FIR);
9508 }
9509
9510 if (v_engine->pli) {
9511 switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_PLI);
9512 }
9513
9514 switch_rtp_set_payload_map(v_engine->rtp_session, &v_engine->payload_map);
9515 switch_channel_set_flag(session->channel, CF_VIDEO);
9516 switch_core_session_start_video_thread(session);
9517
9518 switch_rtp_set_video_buffer_size(v_engine->rtp_session, 1, 0);
9519 if ((ssrc = switch_channel_get_variable(session->channel, "rtp_use_video_ssrc"))) {
9520 uint32_t ssrc_ul = (uint32_t) strtoul(ssrc, NULL, 10);
9521 switch_rtp_set_ssrc(v_engine->rtp_session, ssrc_ul);
9522 v_engine->ssrc = ssrc_ul;
9523 } else {
9524 switch_rtp_set_ssrc(v_engine->rtp_session, v_engine->ssrc);
9525 }
9526
9527 if (v_engine->remote_ssrc) {
9528 switch_rtp_set_remote_ssrc(v_engine->rtp_session, v_engine->remote_ssrc);
9529 }
9530
9531 check_media_timeout_params(session, v_engine);
9532
9533 if (v_engine->ice_in.cands[v_engine->ice_in.chosen[0]][0].ready) {
9534
9535 gen_ice(session, SWITCH_MEDIA_TYPE_VIDEO, NULL, 0);
9536
9537 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating Video ICE\n");
9538
9539 switch_rtp_activate_ice(v_engine->rtp_session,
9540 v_engine->ice_in.ufrag,
9541 v_engine->ice_out.ufrag,
9542 v_engine->ice_out.pwd,
9543 v_engine->ice_in.pwd,
9544 IPR_RTP,
9545 #ifdef GOOGLE_ICE
9546 ICE_GOOGLE_JINGLE,
9547 NULL
9548 #else
9549 switch_determine_ice_type(v_engine, session),
9550 &v_engine->ice_in
9551 #endif
9552 );
9553
9554
9555 }
9556
9557 if ((val = switch_channel_get_variable(session->channel, "rtcp_video_interval_msec")) || (val = smh->mparams->rtcp_video_interval_msec)) {
9558 const char *rport = switch_channel_get_variable(session->channel, "rtp_remote_video_rtcp_port");
9559 switch_port_t remote_port = v_engine->remote_rtcp_port;
9560
9561 if (rport) {
9562 remote_port = (switch_port_t)atoi(rport);
9563 }
9564 if (!strcasecmp(val, "passthru")) {
9565 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating VIDEO RTCP PASSTHRU PORT %d\n", remote_port);
9566 switch_rtp_activate_rtcp(v_engine->rtp_session, -1, remote_port, v_engine->rtcp_mux > 0);
9567 } else {
9568 int interval = atoi(val);
9569 if (interval < 100 || interval > 500000) {
9570 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,
9571 "Invalid rtcp interval spec [%d] must be between 100 and 500000\n", interval);
9572 interval = 5000;
9573 }
9574 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO,
9575 "Activating VIDEO RTCP PORT %d interval %d mux %d\n", remote_port, interval, v_engine->rtcp_mux);
9576 switch_rtp_activate_rtcp(v_engine->rtp_session, interval, remote_port, v_engine->rtcp_mux > 0);
9577
9578 }
9579
9580
9581 if (v_engine->ice_in.cands[v_engine->ice_in.chosen[1]][1].ready && v_engine->ice_in.cands[v_engine->ice_in.chosen[0]][0].ready &&
9582 !zstr(v_engine->ice_in.cands[v_engine->ice_in.chosen[1]][1].con_addr) &&
9583 !zstr(v_engine->ice_in.cands[v_engine->ice_in.chosen[0]][0].con_addr)) {
9584
9585 if (v_engine->rtcp_mux > 0 && !strcmp(v_engine->ice_in.cands[v_engine->ice_in.chosen[1]][1].con_addr, v_engine->ice_in.cands[v_engine->ice_in.chosen[0]][0].con_addr)
9586 && v_engine->ice_in.cands[v_engine->ice_in.chosen[1]][1].con_port == v_engine->ice_in.cands[v_engine->ice_in.chosen[0]][0].con_port) {
9587 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Skipping VIDEO RTCP ICE (Same as VIDEO RTP)\n");
9588 } else {
9589
9590 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating VIDEO RTCP ICE\n");
9591 switch_rtp_activate_ice(v_engine->rtp_session,
9592 v_engine->ice_in.ufrag,
9593 v_engine->ice_out.ufrag,
9594 v_engine->ice_out.pwd,
9595 v_engine->ice_in.pwd,
9596 IPR_RTCP,
9597 #ifdef GOOGLE_ICE
9598 ICE_GOOGLE_JINGLE,
9599 NULL
9600 #else
9601 switch_determine_ice_type(v_engine, session),
9602 &v_engine->ice_in
9603 #endif
9604 );
9605
9606
9607
9608 }
9609
9610 }
9611 }
9612
9613 if (!zstr(v_engine->local_dtls_fingerprint.str) && switch_rtp_has_dtls() && dtls_ok(smh->session)) {
9614 dtls_type_t xtype,
9615 dtype = v_engine->dtls_controller ? DTLS_TYPE_CLIENT : DTLS_TYPE_SERVER;
9616 xtype = DTLS_TYPE_RTP;
9617 if (v_engine->rtcp_mux > 0 && smh->mparams->rtcp_video_interval_msec) xtype |= DTLS_TYPE_RTCP;
9618
9619
9620 if (switch_channel_var_true(session->channel, "legacyDTLS")) {
9621 switch_channel_clear_flag(session->channel, CF_WANT_DTLSv1_2);
9622 want_DTLSv1_2 = 0;
9623 }
9624
9625 switch_rtp_add_dtls(v_engine->rtp_session, &v_engine->local_dtls_fingerprint, &v_engine->remote_dtls_fingerprint, dtype | xtype, want_DTLSv1_2);
9626
9627 if (v_engine->rtcp_mux < 1 && smh->mparams->rtcp_video_interval_msec) {
9628 xtype = DTLS_TYPE_RTCP;
9629 switch_rtp_add_dtls(v_engine->rtp_session, &v_engine->local_dtls_fingerprint, &v_engine->remote_dtls_fingerprint, dtype | xtype, want_DTLSv1_2);
9630 }
9631 }
9632
9633
9634 if ((val = switch_channel_get_variable(session->channel, "rtp_manual_video_rtp_bugs"))) {
9635 switch_core_media_parse_rtp_bugs(&v_engine->rtp_bugs, val);
9636 }
9637
9638 if (switch_channel_test_flag(session->channel, CF_AVPF)) {
9639 smh->mparams->manual_video_rtp_bugs = RTP_BUG_SEND_LINEAR_TIMESTAMPS;
9640 }
9641
9642 switch_rtp_intentional_bugs(v_engine->rtp_session, v_engine->rtp_bugs | smh->mparams->manual_video_rtp_bugs);
9643
9644 //XX
9645
9646
9647 switch_channel_set_variable_printf(session->channel, "rtp_use_video_pt", "%d", v_engine->cur_payload_map->pt);
9648 v_engine->ssrc = switch_rtp_get_ssrc(v_engine->rtp_session);
9649 switch_channel_set_variable_printf(session->channel, "rtp_use_video_ssrc", "%u", v_engine->ssrc);
9650
9651 switch_core_session_apply_crypto(session, SWITCH_MEDIA_TYPE_VIDEO);
9652
9653
9654 if (switch_channel_test_flag(session->channel, CF_ZRTP_PASSTHRU)) {
9655 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Activating video UDPTL mode\n");
9656 switch_rtp_udptl_mode(v_engine->rtp_session);
9657 }
9658
9659 } else {
9660 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "VIDEO RTP REPORTS ERROR: [%s]\n", switch_str_nil(err));
9661 switch_channel_hangup(session->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
9662 goto end;
9663 }
9664 }
9665
9666 } else {
9667 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", switch_str_nil(err));
9668 switch_channel_hangup(session->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
9669 status = SWITCH_STATUS_FALSE;
9670 goto end;
9671 }
9672
9673 video_up:
9674
9675 if (session && v_engine) {
9676 check_dtls_reinvite(session, v_engine);
9677 }
9678
9679 status = SWITCH_STATUS_SUCCESS;
9680
9681 end:
9682
9683 switch_channel_clear_flag(session->channel, CF_REINVITE);
9684
9685 switch_core_recovery_track(session);
9686
9687 return status;
9688
9689 }
9690
get_media_profile_name(switch_core_session_t * session,int secure)9691 static const char *get_media_profile_name(switch_core_session_t *session, int secure)
9692 {
9693 switch_assert(session);
9694
9695 if (switch_channel_test_flag(session->channel, CF_AVPF)) {
9696 if (switch_channel_test_flag(session->channel, CF_DTLS) || secure) {
9697 if (switch_channel_test_flag(session->channel, CF_AVPF_MOZ)) {
9698 return "UDP/TLS/RTP/SAVPF";
9699 } else {
9700 return "RTP/SAVPF";
9701 }
9702 } else {
9703 if (switch_channel_test_flag(session->channel, CF_AVPF_MOZ)) {
9704 return "UDP/AVPF";
9705 } else {
9706 return "RTP/AVPF";
9707 }
9708 }
9709 }
9710
9711 if (secure) {
9712 return "RTP/SAVP";
9713 }
9714
9715 return "RTP/AVP";
9716
9717 }
9718
get_setup(switch_rtp_engine_t * engine,switch_core_session_t * session,switch_sdp_type_t sdp_type)9719 static char *get_setup(switch_rtp_engine_t *engine, switch_core_session_t *session, switch_sdp_type_t sdp_type)
9720 {
9721
9722 if (sdp_type == SDP_TYPE_REQUEST) {
9723 engine->dtls_controller = 0;
9724 engine->new_dtls = 1;
9725 engine->new_ice = 1;
9726 return "actpass";
9727 } else {
9728 return engine->dtls_controller ? "active" : "passive";
9729 }
9730 }
9731
9732
9733 //?
generate_m(switch_core_session_t * session,char * buf,size_t buflen,switch_port_t port,const char * family,const char * ip,int cur_ptime,const char * append_audio,const char * sr,int use_cng,int cng_type,switch_event_t * map,int secure,switch_sdp_type_t sdp_type)9734 static void generate_m(switch_core_session_t *session, char *buf, size_t buflen,
9735 switch_port_t port, const char *family, const char *ip,
9736 int cur_ptime, const char *append_audio, const char *sr, int use_cng, int cng_type, switch_event_t *map, int secure,
9737 switch_sdp_type_t sdp_type)
9738 {
9739 int i = 0;
9740 int rate;
9741 int already_did[128] = { 0 };
9742 int ptime = 0, noptime = 0;
9743 const char *local_sdp_audio_zrtp_hash;
9744 switch_media_handle_t *smh;
9745 switch_rtp_engine_t *a_engine;
9746 int include_external;
9747
9748 switch_assert(session);
9749
9750 if (!(smh = session->media_handle)) {
9751 return;
9752 }
9753
9754 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
9755
9756 //switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "m=audio %d RTP/%sAVP%s",
9757 //port, secure ? "S" : "", switch_channel_test_flag(session->channel, CF_AVPF) ? "F" : "");
9758
9759 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "m=audio %d %s", port,
9760 get_media_profile_name(session, secure || a_engine->crypto_type != CRYPTO_INVALID));
9761
9762 include_external = switch_channel_var_true(session->channel, "include_external_ip");
9763
9764 for (i = 0; i < smh->mparams->num_codecs; i++) {
9765 const switch_codec_implementation_t *imp = smh->codecs[i];
9766 int this_ptime = (imp->microseconds_per_packet / 1000);
9767
9768 if (!strcasecmp(imp->iananame, "ilbc") || !strcasecmp(imp->iananame, "isac") ) {
9769 this_ptime = 20;
9770 }
9771
9772 if (imp->codec_type != SWITCH_CODEC_TYPE_AUDIO) {
9773 continue;
9774 }
9775
9776 if (!noptime) {
9777 if (!cur_ptime) {
9778 if (!ptime) {
9779 ptime = this_ptime;
9780 }
9781 } else {
9782 if (this_ptime != cur_ptime) {
9783 continue;
9784 }
9785 }
9786 }
9787
9788 if (smh->ianacodes[i] < 128) {
9789 if (already_did[smh->ianacodes[i]]) {
9790 continue;
9791 }
9792
9793 already_did[smh->ianacodes[i]] = 1;
9794 }
9795
9796
9797 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), " %d", smh->ianacodes[i]);
9798 }
9799
9800 if (smh->mparams->dtmf_type == DTMF_2833 && smh->mparams->te > 95) {
9801 int i;
9802 for (i = 0; i < smh->num_rates; i++) {
9803 if (smh->dtmf_ianacodes[i]) {
9804 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), " %d", smh->dtmf_ianacodes[i]);
9805 }
9806 if (smh->cng_ianacodes[i] && !switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG) && cng_type && use_cng) {
9807 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), " %d", smh->cng_ianacodes[i]);
9808 }
9809 }
9810 }
9811
9812 //if (!switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG) && cng_type && use_cng) {
9813 //switch_snprintf(buf + strlen(buf), buflen - strlen(buf), " %d", cng_type);
9814 //}
9815
9816 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "\r\n");
9817
9818
9819 memset(already_did, 0, sizeof(already_did));
9820
9821
9822 for (i = 0; i < smh->mparams->num_codecs; i++) {
9823 const switch_codec_implementation_t *imp = smh->codecs[i];
9824 char *fmtp = imp->fmtp;
9825 int this_ptime = imp->microseconds_per_packet / 1000;
9826
9827 if (imp->codec_type != SWITCH_CODEC_TYPE_AUDIO) {
9828 continue;
9829 }
9830
9831 if (!strcasecmp(imp->iananame, "ilbc") || !strcasecmp(imp->iananame, "isac")) {
9832 this_ptime = 20;
9833 }
9834
9835 if (!noptime) {
9836 if (!cur_ptime) {
9837 if (!ptime) {
9838 ptime = this_ptime;
9839 }
9840 } else {
9841 if (this_ptime != cur_ptime) {
9842 continue;
9843 }
9844 }
9845 }
9846
9847 if (smh->ianacodes[i] < 128) {
9848 if (already_did[smh->ianacodes[i]]) {
9849 continue;
9850 }
9851
9852 already_did[smh->ianacodes[i]] = 1;
9853 }
9854
9855 rate = imp->samples_per_second;
9856
9857 if (map) {
9858 char key[128] = "";
9859 char *check = NULL;
9860 switch_snprintf(key, sizeof(key), "%s:%u", imp->iananame, imp->bits_per_second);
9861
9862 if ((check = switch_event_get_header(map, key)) || (check = switch_event_get_header(map, imp->iananame))) {
9863 fmtp = check;
9864 }
9865 }
9866
9867 if (smh->fmtps[i]) {
9868 fmtp = smh->fmtps[i];
9869 }
9870
9871
9872 if (smh->ianacodes[i] > 95 || switch_channel_test_flag(session->channel, CF_VERBOSE_SDP)) {
9873 int channels = get_channels(imp->iananame, imp->number_of_channels);
9874
9875 if (channels > 1) {
9876 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtpmap:%d %s/%d/%d\r\n", smh->ianacodes[i], imp->iananame, rate, channels);
9877
9878 } else {
9879 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtpmap:%d %s/%d\r\n", smh->ianacodes[i], imp->iananame, rate);
9880 }
9881 }
9882
9883 if (fmtp) {
9884 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=fmtp:%d %s\r\n", smh->ianacodes[i], fmtp);
9885 }
9886 }
9887
9888
9889 if ((smh->mparams->dtmf_type == DTMF_2833 || switch_channel_test_flag(session->channel, CF_LIBERAL_DTMF)) && smh->mparams->te > 95) {
9890
9891 for (i = 0; i < smh->num_rates; i++) {
9892 if (switch_channel_test_flag(session->channel, CF_AVPF)) {
9893 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtpmap:%d telephone-event/%d\r\n",
9894 smh->dtmf_ianacodes[i], smh->rates[i]);
9895 } else {
9896 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtpmap:%d telephone-event/%d\r\na=fmtp:%d 0-16\r\n",
9897 smh->dtmf_ianacodes[i], smh->rates[i], smh->dtmf_ianacodes[i]);
9898 }
9899 }
9900 }
9901
9902 if (!zstr(a_engine->local_dtls_fingerprint.type) && secure) {
9903 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=fingerprint:%s %s\r\na=setup:%s\r\n", a_engine->local_dtls_fingerprint.type,
9904 a_engine->local_dtls_fingerprint.str, get_setup(a_engine, session, sdp_type));
9905 }
9906
9907 if (smh->mparams->rtcp_audio_interval_msec) {
9908 if (a_engine->rtcp_mux > 0) {
9909 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtcp-mux\r\n");
9910 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtcp:%d IN %s %s\r\n", port, family, ip);
9911 } else {
9912 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtcp:%d IN %s %s\r\n", port + 1, family, ip);
9913 }
9914 }
9915
9916 //switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u\r\n", a_engine->ssrc);
9917
9918 if (a_engine->ice_out.cands[0][0].ready) {
9919 char tmp1[11] = "";
9920 char tmp2[11] = "";
9921 char tmp3[11] = "";
9922 uint32_t c1 = (2^24)*126 + (2^8)*65535 + (2^0)*(256 - 1);
9923 uint32_t c2 = c1 - 1;
9924
9925 //uint32_t c2 = (2^24)*126 + (2^8)*65535 + (2^0)*(256 - 2);
9926 //uint32_t c3 = (2^24)*126 + (2^8)*65534 + (2^0)*(256 - 1);
9927 //uint32_t c4 = (2^24)*126 + (2^8)*65534 + (2^0)*(256 - 2);
9928 ice_t *ice_out;
9929
9930 tmp1[10] = '\0';
9931 tmp2[10] = '\0';
9932 tmp3[10] = '\0';
9933 switch_stun_random_string(tmp1, 10, "0123456789");
9934 switch_stun_random_string(tmp2, 10, "0123456789");
9935 switch_stun_random_string(tmp3, 10, "0123456789");
9936
9937 gen_ice(session, SWITCH_MEDIA_TYPE_AUDIO, NULL, 0);
9938
9939 ice_out = &a_engine->ice_out;
9940
9941 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=ssrc:%u cname:%s\r\n", a_engine->ssrc, smh->cname);
9942 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=ssrc:%u msid:%s a0\r\n", a_engine->ssrc, smh->msid);
9943 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=ssrc:%u mslabel:%s\r\n", a_engine->ssrc, smh->msid);
9944 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=ssrc:%u label:%sa0\r\n", a_engine->ssrc, smh->msid);
9945
9946
9947 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=ice-ufrag:%s\r\n", ice_out->ufrag);
9948 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=ice-pwd:%s\r\n", ice_out->pwd);
9949
9950
9951 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=candidate:%s 1 %s %u %s %d typ host generation 0\r\n",
9952 tmp1, ice_out->cands[0][0].transport, c1,
9953 ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port
9954 );
9955
9956 if (include_external && !zstr(smh->mparams->extsipip)) {
9957 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=candidate:%s 1 %s %u %s %d typ host generation 0\r\n",
9958 tmp3, ice_out->cands[0][0].transport, c1,
9959 smh->mparams->extsipip, ice_out->cands[0][0].con_port
9960 );
9961 }
9962
9963 if (!zstr(a_engine->local_sdp_ip) && !zstr(ice_out->cands[0][0].con_addr) &&
9964 strcmp(a_engine->local_sdp_ip, ice_out->cands[0][0].con_addr)
9965 && a_engine->local_sdp_port != ice_out->cands[0][0].con_port) {
9966
9967 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=candidate:%s 1 %s %u %s %d typ srflx raddr %s rport %d generation 0\r\n",
9968 tmp2, ice_out->cands[0][0].transport, c2,
9969 ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port,
9970 a_engine->local_sdp_ip, a_engine->local_sdp_port
9971 );
9972 }
9973
9974 if (a_engine->rtcp_mux < 1 || switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND || switch_channel_test_flag(session->channel, CF_RECOVERING)) {
9975
9976
9977 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ host generation 0\r\n",
9978 tmp1, ice_out->cands[0][0].transport, c1,
9979 ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port + (a_engine->rtcp_mux > 0 ? 0 : 1)
9980 );
9981
9982 if (include_external && !zstr(smh->mparams->extsipip)) {
9983 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ host generation 0\r\n",
9984 tmp3, ice_out->cands[0][0].transport, c1,
9985 smh->mparams->extsipip, ice_out->cands[0][0].con_port
9986 );
9987 }
9988
9989 if (!zstr(a_engine->local_sdp_ip) && !zstr(ice_out->cands[0][1].con_addr) &&
9990 strcmp(a_engine->local_sdp_ip, ice_out->cands[0][1].con_addr)
9991 && a_engine->local_sdp_port != ice_out->cands[0][1].con_port) {
9992
9993 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ srflx raddr %s rport %d generation 0\r\n",
9994 tmp2, ice_out->cands[0][0].transport, c2,
9995 ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port + (a_engine->rtcp_mux > 0 ? 0 : 1),
9996 a_engine->local_sdp_ip, a_engine->local_sdp_port + (a_engine->rtcp_mux > 0 ? 0 : 1)
9997 );
9998 }
9999 }
10000
10001
10002
10003 #ifdef GOOGLE_ICE
10004 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=ice-options:google-ice\r\n");
10005 #endif
10006 }
10007
10008
10009 if (secure && !switch_channel_test_flag(session->channel, CF_DTLS)) {
10010 int i;
10011
10012 for (i = 0; smh->crypto_suite_order[i] != CRYPTO_INVALID; i++) {
10013 switch_rtp_crypto_key_type_t j = SUITES[smh->crypto_suite_order[i]].type;
10014
10015 if ((a_engine->crypto_type == j || a_engine->crypto_type == CRYPTO_INVALID) && !zstr(a_engine->ssec[j].local_crypto_key)) {
10016 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=crypto:%s\r\n", a_engine->ssec[j].local_crypto_key);
10017 }
10018 }
10019 //switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=encryption:optional\r\n");
10020 }
10021
10022 if (cng_type) {
10023 for (i = 0; i < smh->num_rates; i++) {
10024 //if (smh->rates[i] == 8000) {
10025 // switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtpmap:%d CN/%d\r\n", cng_type, smh->rates[i]);
10026 //} else {
10027 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtpmap:%d CN/%d\r\n", smh->cng_ianacodes[i], smh->rates[i]);
10028 //}
10029 }
10030 } else {
10031 if (switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG)) {
10032 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=silenceSupp:off - - - -\r\n");
10033 }
10034 }
10035
10036 if (append_audio) {
10037 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "%s%s", append_audio, end_of(append_audio) == '\n' ? "" : "\r\n");
10038 }
10039
10040 if (!cur_ptime) {
10041 cur_ptime = ptime;
10042 }
10043
10044 if (!noptime && cur_ptime) {
10045 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=ptime:%d\r\n", cur_ptime);
10046 }
10047
10048 local_sdp_audio_zrtp_hash = switch_core_media_get_zrtp_hash(session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_TRUE);
10049
10050 if (local_sdp_audio_zrtp_hash) {
10051 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Adding audio a=zrtp-hash:%s\n", local_sdp_audio_zrtp_hash);
10052 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=zrtp-hash:%s\r\n", local_sdp_audio_zrtp_hash);
10053 }
10054
10055 if (!zstr(sr)) {
10056 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=%s\r\n", sr);
10057 }
10058 }
10059
10060 //?
switch_core_media_check_dtmf_type(switch_core_session_t * session)10061 SWITCH_DECLARE(void) switch_core_media_check_dtmf_type(switch_core_session_t *session)
10062 {
10063 const char *val;
10064 switch_media_handle_t *smh;
10065
10066 switch_assert(session);
10067
10068 if (!(smh = session->media_handle)) {
10069 return;
10070 }
10071
10072 if ((val = switch_channel_get_variable(session->channel, "dtmf_type"))) {
10073 if (!strcasecmp(val, "rfc2833")) {
10074 smh->mparams->dtmf_type = DTMF_2833;
10075 } else if (!strcasecmp(val, "info")) {
10076 smh->mparams->dtmf_type = DTMF_INFO;
10077 } else if (!strcasecmp(val, "none")) {
10078 smh->mparams->dtmf_type = DTMF_NONE;
10079 }
10080 }
10081 }
10082
10083 //?
switch_core_media_sdp_map(const char * r_sdp,switch_event_t ** fmtp,switch_event_t ** pt)10084 switch_status_t switch_core_media_sdp_map(const char *r_sdp, switch_event_t **fmtp, switch_event_t **pt)
10085 {
10086 sdp_media_t *m;
10087 sdp_parser_t *parser = NULL;
10088 sdp_session_t *sdp;
10089
10090 if (!(parser = sdp_parse(NULL, r_sdp, (int) strlen(r_sdp), 0))) {
10091 return SWITCH_STATUS_FALSE;
10092 }
10093
10094 if (!(sdp = sdp_session(parser))) {
10095 sdp_parser_free(parser);
10096 return SWITCH_STATUS_FALSE;
10097 }
10098
10099 switch_event_create(&(*fmtp), SWITCH_EVENT_REQUEST_PARAMS);
10100 switch_event_create(&(*pt), SWITCH_EVENT_REQUEST_PARAMS);
10101
10102 for (m = sdp->sdp_media; m; m = m->m_next) {
10103 if (m->m_proto == sdp_proto_rtp) {
10104 sdp_rtpmap_t *map;
10105
10106 for (map = m->m_rtpmaps; map; map = map->rm_next) {
10107 if (map->rm_encoding) {
10108 char buf[25] = "";
10109 char key[128] = "";
10110 char *br = NULL;
10111
10112 if (map->rm_fmtp) {
10113 if ((br = strstr(map->rm_fmtp, "bitrate="))) {
10114 br += 8;
10115 }
10116 }
10117
10118 switch_snprintf(buf, sizeof(buf), "%d", map->rm_pt);
10119
10120 if (br) {
10121 switch_snprintf(key, sizeof(key), "%s:%s", map->rm_encoding, br);
10122 } else {
10123 switch_snprintf(key, sizeof(key), "%s", map->rm_encoding);
10124 }
10125
10126 switch_event_add_header_string(*pt, SWITCH_STACK_BOTTOM, key, buf);
10127
10128 if (map->rm_fmtp) {
10129 switch_event_add_header_string(*fmtp, SWITCH_STACK_BOTTOM, key, map->rm_fmtp);
10130 }
10131 }
10132 }
10133 }
10134 }
10135
10136 sdp_parser_free(parser);
10137
10138 return SWITCH_STATUS_SUCCESS;
10139
10140 }
10141
10142 //?
switch_core_media_set_local_sdp(switch_core_session_t * session,const char * sdp_str,switch_bool_t dup)10143 SWITCH_DECLARE(void)switch_core_media_set_local_sdp(switch_core_session_t *session, const char *sdp_str, switch_bool_t dup)
10144 {
10145 switch_media_handle_t *smh;
10146
10147 switch_assert(session);
10148
10149 if (!(smh = session->media_handle)) {
10150 return;
10151 }
10152
10153 if (smh->sdp_mutex) switch_mutex_lock(smh->sdp_mutex);
10154 smh->mparams->local_sdp_str = dup ? switch_core_session_strdup(session, sdp_str) : (char *) sdp_str;
10155 switch_channel_set_variable(session->channel, "rtp_local_sdp_str", smh->mparams->local_sdp_str);
10156 if (smh->sdp_mutex) switch_mutex_unlock(smh->sdp_mutex);
10157 }
10158
add_fb(char * buf,uint32_t buflen,int pt,int fir,int nack,int pli,int tmmbr)10159 static void add_fb(char *buf, uint32_t buflen, int pt, int fir, int nack, int pli, int tmmbr)
10160 {
10161 if (fir) {
10162 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtcp-fb:%d ccm fir\r\n", pt);
10163 }
10164
10165 if (tmmbr) {
10166 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtcp-fb:%d ccm tmmbr\r\n", pt);
10167 }
10168
10169 if (nack) {
10170 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtcp-fb:%d nack\r\n", pt);
10171 }
10172
10173 if (pli) {
10174 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtcp-fb:%d nack pli\r\n", pt);
10175 }
10176
10177 }
10178
10179 //?
10180 #define SDPBUFLEN 65536
switch_core_media_gen_local_sdp(switch_core_session_t * session,switch_sdp_type_t sdp_type,const char * ip,switch_port_t port,const char * sr,int force)10181 SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *session, switch_sdp_type_t sdp_type, const char *ip, switch_port_t port, const char *sr, int force)
10182 {
10183 char *buf;
10184 int ptime = 0;
10185 uint32_t rate = 0;
10186 uint32_t v_port, t_port;
10187 int use_cng = 1;
10188 const char *val;
10189 const char *family;
10190 const char *pass_fmtp = switch_channel_get_variable(session->channel, "rtp_video_fmtp");
10191 const char *ov_fmtp = switch_channel_get_variable(session->channel, "rtp_force_video_fmtp");
10192 const char *append_audio = switch_channel_get_variable(session->channel, "rtp_append_audio_sdp");
10193 const char *append_video = switch_channel_get_variable(session->channel, "rtp_append_video_sdp");
10194 char srbuf[128] = "";
10195 const char *var_val;
10196 const char *username;
10197 const char *fmtp_out;
10198 const char *fmtp_out_var = switch_channel_get_variable(session->channel, "rtp_force_audio_fmtp");
10199 switch_event_t *map = NULL, *ptmap = NULL;
10200 //const char *b_sdp = NULL;
10201 //const char *local_audio_crypto_key = switch_core_session_local_crypto_key(session, SWITCH_MEDIA_TYPE_AUDIO);
10202 const char *local_sdp_audio_zrtp_hash = switch_core_media_get_zrtp_hash(session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_TRUE);
10203 const char *local_sdp_video_zrtp_hash = switch_core_media_get_zrtp_hash(session, SWITCH_MEDIA_TYPE_VIDEO, SWITCH_TRUE);
10204 const char *local_sdp_text_zrtp_hash = switch_core_media_get_zrtp_hash(session, SWITCH_MEDIA_TYPE_TEXT, SWITCH_TRUE);
10205 const char *tmp;
10206 switch_rtp_engine_t *a_engine, *v_engine, *t_engine;
10207 switch_media_handle_t *smh;
10208 ice_t *ice_out;
10209 //int vp8 = 0;
10210 //int red = 0;
10211 payload_map_t *pmap;
10212 int is_outbound = switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND;
10213 const char *vbw;
10214 int bw = 256, i = 0;
10215 uint8_t fir = 0, nack = 0, pli = 0, tmmbr = 0, has_vid = 0;
10216 const char *use_rtcp_mux = NULL;
10217 int include_external;
10218
10219 switch_assert(session);
10220
10221 if (!(smh = session->media_handle)) {
10222 return;
10223 }
10224
10225 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
10226 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
10227 t_engine = &smh->engines[SWITCH_MEDIA_TYPE_TEXT];
10228
10229 include_external = switch_channel_var_true(session->channel, "include_external_ip");
10230
10231 use_rtcp_mux = switch_channel_get_variable(session->channel, "rtcp_mux");
10232
10233 if (use_rtcp_mux && switch_false(use_rtcp_mux)) {
10234 a_engine->rtcp_mux = -1;
10235 v_engine->rtcp_mux = -1;
10236 }
10237
10238 if ((a_engine->rtcp_mux != -1 && v_engine->rtcp_mux != -1) && (sdp_type == SDP_TYPE_REQUEST)) {
10239 a_engine->rtcp_mux = 1;
10240 v_engine->rtcp_mux = 1;
10241 }
10242
10243 if (!smh->mparams->rtcp_audio_interval_msec) {
10244 smh->mparams->rtcp_audio_interval_msec = (char *)switch_channel_get_variable(session->channel, "rtcp_audio_interval_msec");
10245 }
10246
10247 if (!smh->mparams->rtcp_video_interval_msec) {
10248 smh->mparams->rtcp_video_interval_msec = (char *)switch_channel_get_variable(session->channel, "rtcp_video_interval_msec");
10249 }
10250
10251 if (dtls_ok(session) && (tmp = switch_channel_get_variable(smh->session->channel, "webrtc_enable_dtls")) && switch_false(tmp)) {
10252 switch_channel_clear_flag(smh->session->channel, CF_DTLS_OK);
10253 switch_channel_clear_flag(smh->session->channel, CF_DTLS);
10254 }
10255
10256 if (switch_channel_test_flag(session->channel, CF_PROXY_OFF) && (tmp = switch_channel_get_variable(smh->session->channel, "uuid_media_secure_media"))) {
10257 switch_channel_set_variable(smh->session->channel, "rtp_secure_media", tmp);
10258 switch_core_session_parse_crypto_prefs(session);
10259 switch_core_session_check_outgoing_crypto(session);
10260 }
10261
10262 if (is_outbound || switch_channel_test_flag(session->channel, CF_RECOVERING) ||
10263 switch_channel_test_flag(session->channel, CF_3PCC)) {
10264 if (!switch_channel_test_flag(session->channel, CF_AVPF) &&
10265 switch_true(switch_channel_get_variable(session->channel, "media_webrtc"))) {
10266 switch_channel_set_flag(session->channel, CF_AVPF);
10267 switch_channel_set_flag(session->channel, CF_ICE);
10268 smh->mparams->rtcp_audio_interval_msec = SWITCH_RTCP_AUDIO_INTERVAL_MSEC;
10269 smh->mparams->rtcp_video_interval_msec = SWITCH_RTCP_VIDEO_INTERVAL_MSEC;
10270 }
10271
10272 if (switch_true(switch_channel_get_variable(session->channel, "add_ice_candidates"))) {
10273 switch_channel_set_flag(session->channel, CF_ICE);
10274 }
10275
10276 if ( switch_rtp_has_dtls() && dtls_ok(session)) {
10277 if (switch_channel_test_flag(session->channel, CF_AVPF) ||
10278 switch_true(switch_channel_get_variable(smh->session->channel, "rtp_use_dtls"))) {
10279 switch_channel_set_flag(smh->session->channel, CF_DTLS);
10280 switch_channel_set_flag(smh->session->channel, CF_SECURE);
10281 generate_local_fingerprint(smh, SWITCH_MEDIA_TYPE_AUDIO);
10282 }
10283 }
10284 switch_core_session_parse_crypto_prefs(session);
10285 switch_core_session_check_outgoing_crypto(session);
10286 }
10287
10288 fmtp_out = a_engine->cur_payload_map->fmtp_out;
10289 username = smh->mparams->sdp_username;
10290
10291
10292 switch_zmalloc(buf, SDPBUFLEN);
10293
10294 switch_core_media_check_dtmf_type(session);
10295
10296 if (switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG) ||
10297 ((val = switch_channel_get_variable(session->channel, "supress_cng")) && switch_true(val)) ||
10298 ((val = switch_channel_get_variable(session->channel, "suppress_cng")) && switch_true(val))) {
10299 use_cng = 0;
10300 smh->mparams->cng_pt = 0;
10301 }
10302
10303
10304
10305
10306 if (!smh->payload_space) {
10307 /* it could be 98 but chrome reserves 98 and 99 for some internal stuff even though they should not.
10308 Everyone expects dtmf to be at 101 and Its not worth the trouble so we'll start at 102 */
10309 smh->payload_space = 102;
10310 memset(smh->rates, 0, sizeof(smh->rates));
10311 smh->num_rates = 0;
10312
10313 for (i = 0; i < smh->mparams->num_codecs; i++) {
10314 int j;
10315 smh->ianacodes[i] = smh->codecs[i]->ianacode;
10316
10317 if (smh->codecs[i]->codec_type != SWITCH_CODEC_TYPE_AUDIO) {
10318 continue;
10319 }
10320
10321 if (sdp_type == SDP_TYPE_REQUEST) {
10322 for (j = 0; j < SWITCH_MAX_CODECS; j++) {
10323 if (smh->rates[j] == 0) {
10324 break;
10325 }
10326
10327 if (smh->rates[j] == smh->codecs[i]->samples_per_second) {
10328 goto do_next;
10329 }
10330 }
10331
10332 smh->rates[smh->num_rates++] = smh->codecs[i]->samples_per_second;
10333 }
10334
10335 do_next:
10336 continue;
10337 }
10338
10339 if (sdp_type == SDP_TYPE_REQUEST) {
10340 switch_core_session_t *orig_session = NULL;
10341
10342 switch_core_session_get_partner(session, &orig_session);
10343
10344 if (orig_session && !switch_channel_test_flag(session->channel, CF_ANSWERED)) {
10345 switch_core_media_set_smode(smh->session, SWITCH_MEDIA_TYPE_AUDIO,
10346 switch_core_session_remote_media_flow(orig_session, SWITCH_MEDIA_TYPE_AUDIO), sdp_type);
10347 switch_core_media_set_smode(smh->session, SWITCH_MEDIA_TYPE_VIDEO,
10348 switch_core_session_remote_media_flow(orig_session, SWITCH_MEDIA_TYPE_VIDEO), sdp_type);
10349 }
10350
10351 for (i = 0; i < smh->mparams->num_codecs; i++) {
10352 const switch_codec_implementation_t *imp = smh->codecs[i];
10353 switch_payload_t orig_pt = 0;
10354 char *orig_fmtp = NULL;
10355
10356 if (smh->ianacodes[i] > 64) {
10357 if (smh->mparams->dtmf_type == DTMF_2833 && smh->mparams->te > 95 && smh->mparams->te == smh->payload_space) {
10358 smh->payload_space++;
10359 }
10360 if (!switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG) &&
10361 smh->mparams->cng_pt && use_cng && smh->mparams->cng_pt == smh->payload_space) {
10362 smh->payload_space++;
10363 }
10364
10365 if (orig_session &&
10366 switch_core_session_get_payload_code(orig_session,
10367 imp->codec_type == SWITCH_CODEC_TYPE_AUDIO ? SWITCH_MEDIA_TYPE_AUDIO : SWITCH_MEDIA_TYPE_VIDEO,
10368 imp->iananame, imp->samples_per_second, smh->fmtp[i], &orig_pt, NULL, &orig_fmtp) == SWITCH_STATUS_SUCCESS) {
10369
10370 if (orig_pt == smh->mparams->te) {
10371 smh->mparams->te = (switch_payload_t)smh->payload_space++;
10372 }
10373
10374 smh->ianacodes[i] = orig_pt;
10375
10376 if (!zstr(orig_fmtp)) {
10377 smh->fmtps[i] = switch_core_session_strdup(session, orig_fmtp);
10378 }
10379 } else {
10380 smh->ianacodes[i] = (switch_payload_t)smh->payload_space++;
10381 }
10382 }
10383
10384 switch_core_media_add_payload_map(session,
10385 imp->codec_type == SWITCH_CODEC_TYPE_AUDIO ? SWITCH_MEDIA_TYPE_AUDIO : SWITCH_MEDIA_TYPE_VIDEO,
10386 imp->iananame,
10387 imp->modname,
10388 smh->fmtps[i],
10389 sdp_type,
10390 smh->ianacodes[i],
10391 imp->samples_per_second,
10392 imp->microseconds_per_packet / 1000,
10393 imp->number_of_channels,
10394 SWITCH_FALSE);
10395 }
10396
10397 for (i = 0; i < smh->num_rates; i++) {
10398 if (smh->rates[i] == 8000 || smh->num_rates == 1) {
10399 smh->dtmf_ianacodes[i] = smh->mparams->te;
10400 smh->cng_ianacodes[i] = smh->mparams->cng_pt;
10401 } else {
10402 int j = 0;
10403
10404 for (j = 0; j < smh->mparams->num_codecs; j++) {
10405 if (smh->ianacodes[j] == smh->payload_space) {
10406 smh->payload_space++;
10407 break;
10408 }
10409 }
10410
10411 smh->dtmf_ianacodes[i] = (switch_payload_t)smh->payload_space++;
10412 smh->cng_ianacodes[i] = (switch_payload_t)smh->payload_space++;
10413 }
10414 }
10415
10416
10417 if (orig_session) {
10418 switch_core_session_rwunlock(orig_session);
10419 }
10420 }
10421 }
10422
10423 if (fmtp_out_var) {
10424 fmtp_out = fmtp_out_var;
10425 }
10426
10427 val = switch_channel_get_variable(session->channel, "verbose_sdp");
10428
10429 if (!val || switch_true(val)) {
10430 switch_channel_set_flag(session->channel, CF_VERBOSE_SDP);
10431 }
10432
10433 if (!force && !ip && zstr(sr)
10434 && (switch_channel_test_flag(session->channel, CF_PROXY_MODE) || switch_channel_test_flag(session->channel, CF_PROXY_MEDIA))) {
10435 switch_safe_free(buf);
10436 return;
10437 }
10438
10439 if (!ip) {
10440 if (!(ip = a_engine->adv_sdp_ip)) {
10441 ip = a_engine->proxy_sdp_ip;
10442 }
10443 }
10444
10445 if (!ip) {
10446 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "%s NO IP!\n", switch_channel_get_name(session->channel));
10447 switch_safe_free(buf);
10448 return;
10449 }
10450
10451 if (!port) {
10452 if (!(port = a_engine->adv_sdp_port)) {
10453 port = a_engine->proxy_sdp_port;
10454 }
10455 }
10456
10457 if (!port) {
10458 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "%s NO PORT!\n", switch_channel_get_name(session->channel));
10459 switch_safe_free(buf);
10460 return;
10461 }
10462
10463 //if (!a_engine->cur_payload_map->rm_encoding && (b_sdp = switch_channel_get_variable(session->channel, SWITCH_B_SDP_VARIABLE))) {
10464 //switch_core_media_sdp_map(b_sdp, &map, &ptmap);
10465 //}
10466
10467 for (i = 0; i < smh->mparams->num_codecs; i++) {
10468 const switch_codec_implementation_t *imp = smh->codecs[i];
10469
10470 if (imp->codec_type == SWITCH_CODEC_TYPE_AUDIO && a_engine->smode == SWITCH_MEDIA_FLOW_DISABLED) {
10471 switch_core_media_set_smode(smh->session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_MEDIA_FLOW_SENDRECV, sdp_type);
10472 break;
10473 }
10474 }
10475
10476 if (zstr(sr)) {
10477 if (a_engine->smode == SWITCH_MEDIA_FLOW_SENDONLY) {
10478 sr = "sendonly";
10479 } else if (a_engine->smode == SWITCH_MEDIA_FLOW_RECVONLY) {
10480 sr = "recvonly";
10481 } else if (a_engine->smode == SWITCH_MEDIA_FLOW_INACTIVE) {
10482 sr = "inactive";
10483 } else {
10484 sr = "sendrecv";
10485 }
10486
10487 if ((var_val = switch_channel_get_variable(session->channel, "origination_audio_mode"))) {
10488 if (!strcasecmp(sr, "sendonly") || !strcasecmp(sr, "recvonly") || !strcasecmp(sr, "sendrecv") || !strcasecmp(sr, "inactive")) {
10489 sr = var_val;
10490 }
10491 switch_channel_set_variable(session->channel, "origination_audio_mode", NULL);
10492 }
10493
10494 if (zstr(sr)) {
10495 sr = "sendrecv";
10496 }
10497 }
10498
10499 if (!smh->owner_id) {
10500 smh->owner_id = (uint32_t) switch_epoch_time_now(NULL) - port;
10501 }
10502
10503 if (!smh->session_id) {
10504 smh->session_id = smh->owner_id;
10505 }
10506
10507 if (switch_true(switch_channel_get_variable_dup(session->channel, "drop_dtmf", SWITCH_FALSE, -1))) {
10508 switch_channel_set_flag(session->channel, CF_DROP_DTMF);
10509 }
10510
10511 smh->session_id++;
10512
10513 if ((smh->mparams->ndlb & SM_NDLB_SENDRECV_IN_SESSION) ||
10514 ((var_val = switch_channel_get_variable(session->channel, "ndlb_sendrecv_in_session")) && switch_true(var_val))) {
10515 if (!zstr(sr)) {
10516 switch_snprintf(srbuf, sizeof(srbuf), "a=%s\r\n", sr);
10517 }
10518 sr = NULL;
10519 }
10520
10521 family = strchr(ip, ':') ? "IP6" : "IP4";
10522 switch_snprintf(buf, SDPBUFLEN,
10523 "v=0\r\n"
10524 "o=%s %010u %010u IN %s %s\r\n"
10525 "s=%s\r\n"
10526 "c=IN %s %s\r\n"
10527 "t=0 0\r\n"
10528 "%s",
10529 username, smh->owner_id, smh->session_id, family, ip, username, family, ip, srbuf);
10530
10531 if (switch_channel_test_flag(smh->session->channel, CF_ICE) && switch_channel_var_true(session->channel, "ice_lite")) {
10532 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ice-lite\r\n");
10533 }
10534
10535 if (a_engine->rmode == SWITCH_MEDIA_FLOW_DISABLED) {
10536 goto video;
10537 }
10538
10539 if (switch_channel_test_flag(smh->session->channel, CF_ICE)) {
10540 gen_ice(session, SWITCH_MEDIA_TYPE_AUDIO, ip, port);
10541 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=msid-semantic: WMS %s\r\n", smh->msid);
10542 }
10543
10544 if (a_engine->codec_negotiated) {
10545 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "m=audio %d %s", port,
10546 get_media_profile_name(session, !a_engine->no_crypto &&
10547 (switch_channel_test_flag(session->channel, CF_DTLS) || a_engine->crypto_type != CRYPTO_INVALID)));
10548
10549
10550 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), " %d", a_engine->cur_payload_map->pt);
10551
10552
10553 if (switch_media_handle_test_media_flag(smh, SCMF_MULTI_ANSWER_AUDIO)) {
10554 switch_mutex_lock(smh->sdp_mutex);
10555 for (pmap = a_engine->cur_payload_map; pmap && pmap->allocated; pmap = pmap->next) {
10556 if (pmap->pt != a_engine->cur_payload_map->pt) {
10557 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), " %d", pmap->pt);
10558 }
10559 }
10560 switch_mutex_unlock(smh->sdp_mutex);
10561 }
10562
10563 if ((smh->mparams->dtmf_type == DTMF_2833 || switch_channel_test_flag(session->channel, CF_LIBERAL_DTMF)) && smh->mparams->te > 95) {
10564 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), " %d", smh->mparams->te);
10565 }
10566
10567 if (!switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG) && smh->mparams->cng_pt && use_cng) {
10568 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), " %d", smh->mparams->cng_pt);
10569 }
10570
10571 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "\r\n");
10572
10573
10574 rate = a_engine->cur_payload_map->adv_rm_rate;
10575
10576 if (!a_engine->cur_payload_map->adv_channels) {
10577 a_engine->cur_payload_map->adv_channels = get_channels(a_engine->cur_payload_map->rm_encoding, 1);
10578 }
10579
10580 if (a_engine->cur_payload_map->adv_channels > 1) {
10581 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d %s/%d/%d\r\n",
10582 a_engine->cur_payload_map->pt, a_engine->cur_payload_map->rm_encoding, rate, a_engine->cur_payload_map->adv_channels);
10583 } else {
10584 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d %s/%d\r\n",
10585 a_engine->cur_payload_map->pt, a_engine->cur_payload_map->rm_encoding, rate);
10586 }
10587
10588 if (fmtp_out) {
10589 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=fmtp:%d %s\r\n", a_engine->cur_payload_map->pt, fmtp_out);
10590 }
10591
10592 if (switch_media_handle_test_media_flag(smh, SCMF_MULTI_ANSWER_AUDIO)) {
10593 switch_mutex_lock(smh->sdp_mutex);
10594 for (pmap = a_engine->cur_payload_map; pmap && pmap->allocated; pmap = pmap->next) {
10595 if (pmap->pt != a_engine->cur_payload_map->pt) {
10596 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d %s/%ld\r\n",
10597 pmap->pt, pmap->iananame,
10598 pmap->rate);
10599 }
10600 }
10601 switch_mutex_unlock(smh->sdp_mutex);
10602 }
10603
10604
10605 if (a_engine->read_codec.implementation && !ptime) {
10606 ptime = a_engine->read_codec.implementation->microseconds_per_packet / 1000;
10607 }
10608
10609
10610 if ((smh->mparams->dtmf_type == DTMF_2833 || switch_channel_test_flag(session->channel, CF_LIBERAL_DTMF))
10611 && smh->mparams->te > 95) {
10612
10613 if (switch_channel_test_flag(session->channel, CF_AVPF)) {
10614 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d telephone-event/%d\r\n",
10615 smh->mparams->te, smh->mparams->te_rate);
10616 } else {
10617 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d telephone-event/%d\r\na=fmtp:%d 0-16\r\n",
10618 smh->mparams->te, smh->mparams->te_rate, smh->mparams->te);
10619 }
10620 }
10621
10622 if (switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG)) {
10623 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=silenceSupp:off - - - -\r\n");
10624 } else if (smh->mparams->cng_pt && use_cng) {
10625 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d CN/%lu\r\n", smh->mparams->cng_pt, smh->mparams->cng_rate);
10626
10627 if (!a_engine->codec_negotiated) {
10628 smh->mparams->cng_pt = 0;
10629 }
10630 }
10631
10632 if (append_audio) {
10633 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "%s%s", append_audio, end_of(append_audio) == '\n' ? "" : "\r\n");
10634 }
10635
10636 if (ptime) {
10637 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ptime:%d\r\n", ptime);
10638 }
10639
10640
10641 if (local_sdp_audio_zrtp_hash) {
10642 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Adding audio a=zrtp-hash:%s\r\n",
10643 local_sdp_audio_zrtp_hash);
10644 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=zrtp-hash:%s\r\n",
10645 local_sdp_audio_zrtp_hash);
10646 }
10647
10648 if (!zstr(sr)) {
10649 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=%s\r\n", sr);
10650 }
10651
10652
10653 if (!zstr(a_engine->local_dtls_fingerprint.type)) {
10654 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=fingerprint:%s %s\r\na=setup:%s\r\n",
10655 a_engine->local_dtls_fingerprint.type,
10656 a_engine->local_dtls_fingerprint.str, get_setup(a_engine, session, sdp_type));
10657 }
10658
10659 if (smh->mparams->rtcp_audio_interval_msec) {
10660 if (a_engine->rtcp_mux > 0) {
10661 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtcp-mux\r\n");
10662 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtcp:%d IN %s %s\r\n", port, family, ip);
10663 } else {
10664 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtcp:%d IN %s %s\r\n", port + 1, family, ip);
10665 }
10666 }
10667
10668 //switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u\r\n", a_engine->ssrc);
10669
10670 if (a_engine->ice_out.cands[0][0].ready) {
10671 char tmp1[11] = "";
10672 char tmp2[11] = "";
10673 char tmp3[11] = "";
10674 uint32_t c1 = (2^24)*126 + (2^8)*65535 + (2^0)*(256 - 1);
10675 //uint32_t c2 = (2^24)*126 + (2^8)*65535 + (2^0)*(256 - 2);
10676 //uint32_t c3 = (2^24)*126 + (2^8)*65534 + (2^0)*(256 - 1);
10677 //uint32_t c4 = (2^24)*126 + (2^8)*65534 + (2^0)*(256 - 2);
10678
10679 uint32_t c2 = c1 - 1;
10680 uint32_t c3 = c1 - 2;
10681 uint32_t c4 = c1 - 3;
10682
10683 tmp1[10] = '\0';
10684 tmp2[10] = '\0';
10685 tmp3[10] = '\0';
10686 switch_stun_random_string(tmp1, 10, "0123456789");
10687 switch_stun_random_string(tmp2, 10, "0123456789");
10688 switch_stun_random_string(tmp3, 10, "0123456789");
10689
10690 ice_out = &a_engine->ice_out;
10691
10692
10693 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ice-ufrag:%s\r\n", ice_out->ufrag);
10694 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ice-pwd:%s\r\n", ice_out->pwd);
10695
10696
10697 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 1 %s %u %s %d typ host generation 0\r\n",
10698 tmp1, ice_out->cands[0][0].transport, c1,
10699 ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port
10700 );
10701
10702 if (include_external && !zstr(smh->mparams->extsipip)) {
10703 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 1 %s %u %s %d typ host generation 0\r\n",
10704 tmp3, ice_out->cands[0][0].transport, c1,
10705 smh->mparams->extsipip, ice_out->cands[0][0].con_port
10706 );
10707 }
10708
10709 if (!zstr(a_engine->local_sdp_ip) && !zstr(ice_out->cands[0][0].con_addr) &&
10710 strcmp(a_engine->local_sdp_ip, ice_out->cands[0][0].con_addr)
10711 && a_engine->local_sdp_port != ice_out->cands[0][0].con_port) {
10712
10713 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 1 %s %u %s %d typ srflx raddr %s rport %d generation 0\r\n",
10714 tmp2, ice_out->cands[0][0].transport, c3,
10715 ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port,
10716 a_engine->local_sdp_ip, a_engine->local_sdp_port
10717 );
10718 }
10719
10720
10721 if (a_engine->rtcp_mux < 1 || is_outbound || switch_channel_test_flag(session->channel, CF_RECOVERING)) {
10722
10723 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ host generation 0\r\n",
10724 tmp1, ice_out->cands[0][0].transport, c2,
10725 ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port + (a_engine->rtcp_mux > 0 ? 0 : 1)
10726 );
10727
10728 if (include_external && !zstr(smh->mparams->extsipip)) {
10729 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ host generation 0\r\n",
10730 tmp3, ice_out->cands[0][0].transport, c2,
10731 smh->mparams->extsipip, ice_out->cands[0][0].con_port + (a_engine->rtcp_mux > 0 ? 0 : 1)
10732 );
10733 }
10734
10735
10736
10737 if (!zstr(a_engine->local_sdp_ip) && !zstr(ice_out->cands[0][0].con_addr) &&
10738 strcmp(a_engine->local_sdp_ip, ice_out->cands[0][0].con_addr)
10739 && a_engine->local_sdp_port != ice_out->cands[0][0].con_port) {
10740
10741 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ srflx raddr %s rport %d generation 0\r\n",
10742 tmp2, ice_out->cands[0][0].transport, c4,
10743 ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port + (a_engine->rtcp_mux > 0 ? 0 : 1),
10744 a_engine->local_sdp_ip, a_engine->local_sdp_port + (a_engine->rtcp_mux > 0 ? 0 : 1)
10745 );
10746 }
10747 }
10748
10749 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=end-of-candidates\r\n");
10750
10751 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u cname:%s\r\n", a_engine->ssrc, smh->cname);
10752 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u msid:%s a0\r\n", a_engine->ssrc, smh->msid);
10753 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u mslabel:%s\r\n", a_engine->ssrc, smh->msid);
10754 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u label:%sa0\r\n", a_engine->ssrc, smh->msid);
10755
10756
10757 #ifdef GOOGLE_ICE
10758 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ice-options:google-ice\r\n");
10759 #endif
10760 }
10761
10762 if (a_engine->crypto_type != CRYPTO_INVALID && !switch_channel_test_flag(session->channel, CF_DTLS) &&
10763 !zstr(a_engine->ssec[a_engine->crypto_type].local_crypto_key) && switch_channel_test_flag(session->channel, CF_SECURE)) {
10764
10765 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=crypto:%s\r\n", a_engine->ssec[a_engine->crypto_type].local_crypto_key);
10766 //switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=encryption:optional\r\n");
10767 }
10768
10769 if (a_engine->reject_avp) {
10770 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "m=audio 0 RTP/AVP 19\r\n");
10771 }
10772
10773 } else if (smh->mparams->num_codecs) {
10774 int cur_ptime = 0, this_ptime = 0, cng_type = 0;
10775 const char *mult;
10776
10777
10778 if (!switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG) && smh->mparams->cng_pt && use_cng) {
10779 cng_type = smh->mparams->cng_pt;
10780
10781 if (!a_engine->codec_negotiated) {
10782 smh->mparams->cng_pt = 0;
10783 }
10784 }
10785
10786 mult = switch_channel_get_variable(session->channel, "sdp_m_per_ptime");
10787
10788 if (switch_channel_test_flag(session->channel, CF_AVPF) || (mult && switch_false(mult))) {
10789 char *bp = buf;
10790 int both = (switch_channel_test_flag(session->channel, CF_AVPF) || switch_channel_test_flag(session->channel, CF_DTLS)) ? 0 : 1;
10791
10792 if ((!a_engine->no_crypto && switch_channel_test_flag(session->channel, CF_SECURE)) ||
10793 switch_channel_test_flag(session->channel, CF_DTLS)) {
10794 generate_m(session, buf, SDPBUFLEN, port, family, ip, 0, append_audio, sr, use_cng, cng_type, map, 1, sdp_type);
10795 bp = (buf + strlen(buf));
10796
10797 if (smh->crypto_mode == CRYPTO_MODE_MANDATORY) {
10798 both = 0;
10799 }
10800
10801 }
10802
10803 if (both) {
10804 generate_m(session, bp, SDPBUFLEN - strlen(buf), port, family, ip, 0, append_audio, sr, use_cng, cng_type, map, 0, sdp_type);
10805 }
10806
10807 } else {
10808
10809 for (i = 0; i < smh->mparams->num_codecs; i++) {
10810 const switch_codec_implementation_t *imp = smh->codecs[i];
10811
10812 if (imp->codec_type != SWITCH_CODEC_TYPE_AUDIO) {
10813 continue;
10814 }
10815
10816 this_ptime = imp->microseconds_per_packet / 1000;
10817
10818 if (!strcasecmp(imp->iananame, "ilbc") || !strcasecmp(imp->iananame, "isac")) {
10819 this_ptime = 20;
10820 }
10821
10822 if (cur_ptime != this_ptime) {
10823 char *bp = buf;
10824 int both = 1;
10825
10826 cur_ptime = this_ptime;
10827
10828 if ((!a_engine->no_crypto && switch_channel_test_flag(session->channel, CF_SECURE)) ||
10829 switch_channel_test_flag(session->channel, CF_DTLS)) {
10830 generate_m(session, bp, SDPBUFLEN - strlen(buf), port, family, ip, cur_ptime, append_audio, sr, use_cng, cng_type, map, 1, sdp_type);
10831 bp = (buf + strlen(buf));
10832
10833 if (smh->crypto_mode == CRYPTO_MODE_MANDATORY) {
10834 both = 0;
10835 }
10836 }
10837
10838 if (switch_channel_test_flag(session->channel, CF_AVPF) || switch_channel_test_flag(session->channel, CF_DTLS)) {
10839 both = 0;
10840 }
10841
10842 if (both) {
10843 generate_m(session, bp, SDPBUFLEN - strlen(buf), port, family, ip, cur_ptime, append_audio, sr, use_cng, cng_type, map, 0, sdp_type);
10844 }
10845 }
10846
10847 }
10848 }
10849
10850 }
10851
10852 if (switch_channel_test_flag(session->channel, CF_IMAGE_SDP)) {
10853 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "m=image 0 UDPTL T38\r\n", SWITCH_VA_NONE);
10854
10855 }
10856
10857
10858 video:
10859
10860
10861 if (!switch_channel_test_flag(session->channel, CF_VIDEO_POSSIBLE) && switch_media_handle_test_media_flag(smh, SCMF_RECV_SDP)) {
10862 has_vid = 0;
10863 } else {
10864 for (i = 0; i < smh->mparams->num_codecs; i++) {
10865 const switch_codec_implementation_t *imp = smh->codecs[i];
10866
10867
10868 if (imp->codec_type == SWITCH_CODEC_TYPE_VIDEO) {
10869 has_vid = 1;
10870 break;
10871 }
10872 }
10873
10874 }
10875
10876
10877 if (!has_vid) {
10878 if (switch_channel_test_flag(session->channel, CF_VIDEO_SDP_RECVD)) {
10879 switch_channel_clear_flag(session->channel, CF_VIDEO_SDP_RECVD);
10880 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "m=video 0 %s 19\r\n",
10881 get_media_profile_name(session,
10882 (switch_channel_test_flag(session->channel, CF_SECURE)
10883 && switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) ||
10884 a_engine->crypto_type != CRYPTO_INVALID || switch_channel_test_flag(session->channel, CF_DTLS)));
10885 }
10886 } else {
10887 if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
10888 if (switch_channel_test_flag(smh->session->channel, CF_DTLS)) {
10889 v_engine->no_crypto = 1;
10890 }
10891 }
10892
10893
10894 if (!v_engine->local_sdp_port) {
10895 switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_VIDEO, 0);
10896 }
10897
10898 //if (switch_channel_test_flag(session->channel, CF_AVPF)) {
10899 // switch_media_handle_set_media_flag(smh, SCMF_MULTI_ANSWER_VIDEO);
10900 //}
10901
10902 if ((v_port = v_engine->adv_sdp_port)) {
10903 int loops;
10904 int got_vid = 0;
10905
10906 for (loops = 0; loops < 2; loops++) {
10907
10908 if (switch_channel_test_flag(smh->session->channel, CF_ICE)) {
10909 gen_ice(session, SWITCH_MEDIA_TYPE_VIDEO, ip, (switch_port_t)v_port);
10910 }
10911
10912
10913 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "m=video %d %s",
10914 v_port,
10915 get_media_profile_name(session,
10916 (loops == 0 && switch_channel_test_flag(session->channel, CF_SECURE)
10917 && switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) ||
10918 a_engine->crypto_type != CRYPTO_INVALID || switch_channel_test_flag(session->channel, CF_DTLS)));
10919
10920
10921
10922
10923 /*****************************/
10924 if (v_engine->codec_negotiated) {
10925 payload_map_t *pmap;
10926 switch_core_media_set_video_codec(session, 0);
10927 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), " %d", v_engine->cur_payload_map->pt);
10928
10929 if (switch_media_handle_test_media_flag(smh, SCMF_MULTI_ANSWER_VIDEO)) {
10930 switch_mutex_lock(smh->sdp_mutex);
10931 for (pmap = v_engine->cur_payload_map; pmap && pmap->allocated; pmap = pmap->next) {
10932 if (pmap->pt != v_engine->cur_payload_map->pt && pmap->negotiated) {
10933 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), " %d", pmap->pt);
10934 }
10935 }
10936 switch_mutex_unlock(smh->sdp_mutex);
10937 }
10938
10939 } else if (smh->mparams->num_codecs) {
10940 int already_did[128] = { 0 };
10941 for (i = 0; i < smh->mparams->num_codecs; i++) {
10942 const switch_codec_implementation_t *imp = smh->codecs[i];
10943
10944
10945 if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO) {
10946 continue;
10947 }
10948
10949 if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_INBOUND &&
10950 switch_channel_test_flag(session->channel, CF_NOVIDEO)) {
10951 continue;
10952 }
10953
10954 if (smh->ianacodes[i] < 128) {
10955 if (already_did[smh->ianacodes[i]]) {
10956 continue;
10957 }
10958 already_did[smh->ianacodes[i]] = 1;
10959 }
10960
10961 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), " %d", smh->ianacodes[i]);
10962
10963 if (!ptime) {
10964 ptime = imp->microseconds_per_packet / 1000;
10965 }
10966
10967 got_vid++;
10968 }
10969 }
10970 if (got_vid && v_engine->smode == SWITCH_MEDIA_FLOW_DISABLED) {
10971 switch_core_media_set_smode(smh->session, SWITCH_MEDIA_TYPE_VIDEO, SWITCH_MEDIA_FLOW_SENDRECV, sdp_type);
10972 }
10973
10974 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "\r\n");
10975
10976
10977 if (!(vbw = switch_channel_get_variable(smh->session->channel, "rtp_video_max_bandwidth"))) {
10978 vbw = switch_channel_get_variable(smh->session->channel, "rtp_video_max_bandwidth_in");
10979 }
10980
10981 if (!vbw) {
10982 vbw = "1mb";
10983 }
10984
10985 bw = switch_parse_bandwidth_string(vbw);
10986
10987 if (bw > 0) {
10988 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "b=AS:%d\r\n", bw);
10989 //switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "b=TIAS:%d\r\n", bw);
10990 }
10991
10992
10993
10994 if (v_engine->codec_negotiated) {
10995 payload_map_t *pmap;
10996
10997 //if (!strcasecmp(v_engine->cur_payload_map->rm_encoding, "VP8")) {
10998 // vp8 = v_engine->cur_payload_map->pt;
10999 //}
11000
11001 //if (!strcasecmp(v_engine->cur_payload_map->rm_encoding, "red")) {
11002 // red = v_engine->cur_payload_map->pt;
11003 //}
11004
11005 rate = v_engine->cur_payload_map->rm_rate;
11006 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d %s/%ld\r\n",
11007 v_engine->cur_payload_map->pt, v_engine->cur_payload_map->rm_encoding,
11008 v_engine->cur_payload_map->rm_rate);
11009
11010 if (switch_channel_test_flag(session->channel, CF_RECOVERING)) {
11011 pass_fmtp = v_engine->cur_payload_map->rm_fmtp;
11012 } else {
11013
11014 pass_fmtp = NULL;
11015
11016 if (ov_fmtp) {
11017 pass_fmtp = ov_fmtp;
11018 } else {
11019
11020 pass_fmtp = v_engine->cur_payload_map->fmtp_out;
11021
11022 if (!pass_fmtp || switch_true(switch_channel_get_variable_dup(session->channel, "rtp_mirror_fmtp", SWITCH_FALSE, -1))) {
11023 pass_fmtp = switch_channel_get_variable(session->channel, "rtp_video_fmtp");
11024 }
11025 }
11026 }
11027
11028
11029 if (pass_fmtp) {
11030 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=fmtp:%d %s\r\n", v_engine->cur_payload_map->pt, pass_fmtp);
11031 }
11032
11033
11034 if (switch_media_handle_test_media_flag(smh, SCMF_MULTI_ANSWER_VIDEO)) {
11035 switch_mutex_lock(smh->sdp_mutex);
11036 for (pmap = v_engine->cur_payload_map; pmap && pmap->allocated; pmap = pmap->next) {
11037 if (pmap->pt != v_engine->cur_payload_map->pt && pmap->negotiated) {
11038 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d %s/%ld\r\n",
11039 pmap->pt, pmap->iananame, pmap->rate);
11040 }
11041 }
11042 switch_mutex_unlock(smh->sdp_mutex);
11043 }
11044
11045
11046 if (append_video) {
11047 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "%s%s", append_video, end_of(append_video) == '\n' ? "" : "\r\n");
11048 }
11049
11050 } else if (smh->mparams->num_codecs) {
11051 int already_did[128] = { 0 };
11052
11053 for (i = 0; i < smh->mparams->num_codecs; i++) {
11054 const switch_codec_implementation_t *imp = smh->codecs[i];
11055 char *fmtp = NULL;
11056 uint32_t ianacode = smh->ianacodes[i];
11057 int channels;
11058
11059 if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO) {
11060 continue;
11061 }
11062
11063 if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_INBOUND &&
11064 switch_channel_test_flag(session->channel, CF_NOVIDEO)) {
11065 continue;
11066 }
11067
11068 if (ianacode < 128) {
11069 if (already_did[ianacode]) {
11070 continue;
11071 }
11072 already_did[ianacode] = 1;
11073 }
11074
11075 if (!rate) {
11076 rate = imp->samples_per_second;
11077 }
11078
11079 channels = get_channels(imp->iananame, imp->number_of_channels);
11080
11081 //if (!strcasecmp(imp->iananame, "VP8")) {
11082 // vp8 = ianacode;
11083 //}
11084
11085 //if (!strcasecmp(imp->iananame, "red")) {
11086 // red = ianacode;
11087 //}
11088
11089 if (channels > 1) {
11090 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d %s/%d/%d\r\n", ianacode, imp->iananame,
11091 imp->samples_per_second, channels);
11092 } else {
11093 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d %s/%d\r\n", ianacode, imp->iananame,
11094 imp->samples_per_second);
11095 }
11096
11097
11098
11099 if (!zstr(ov_fmtp)) {
11100 fmtp = (char *) ov_fmtp;
11101 } else {
11102
11103 if (map) {
11104 fmtp = switch_event_get_header(map, imp->iananame);
11105 }
11106
11107 if (!zstr(smh->fmtp[i])) {
11108 fmtp = smh->fmtp[i];
11109 } else if (smh->fmtps[i]) {
11110 fmtp = smh->fmtps[i];
11111 }
11112
11113 if (zstr(fmtp)) fmtp = imp->fmtp;
11114
11115 if (zstr(fmtp)) fmtp = (char *) pass_fmtp;
11116 }
11117
11118 if (!zstr(fmtp) && strcasecmp(fmtp, "_blank_")) {
11119 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=fmtp:%d %s\r\n", ianacode, fmtp);
11120 }
11121 }
11122
11123 }
11124
11125 if (v_engine->smode == SWITCH_MEDIA_FLOW_SENDRECV) {
11126 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "%s", "a=sendrecv\r\n");
11127 } else if (v_engine->smode == SWITCH_MEDIA_FLOW_SENDONLY) {
11128 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "%s", "a=sendonly\r\n");
11129 } else if (v_engine->smode == SWITCH_MEDIA_FLOW_RECVONLY) {
11130 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "%s", "a=recvonly\r\n");
11131 } else if (v_engine->smode == SWITCH_MEDIA_FLOW_INACTIVE) {
11132 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "%s", "a=inactive\r\n");
11133 }
11134
11135
11136 if ((is_outbound || switch_channel_test_flag(session->channel, CF_RECOVERING))
11137 && switch_channel_test_flag(smh->session->channel, CF_DTLS)) {
11138 generate_local_fingerprint(smh, SWITCH_MEDIA_TYPE_VIDEO);
11139 }
11140
11141
11142 if (!zstr(v_engine->local_dtls_fingerprint.type)) {
11143 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=fingerprint:%s %s\r\na=setup:%s\r\n",
11144 v_engine->local_dtls_fingerprint.type, v_engine->local_dtls_fingerprint.str, get_setup(v_engine, session, sdp_type));
11145 }
11146
11147
11148 if (smh->mparams->rtcp_video_interval_msec) {
11149 if (v_engine->rtcp_mux > 0) {
11150 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtcp-mux\r\n");
11151 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtcp:%d IN %s %s\r\n", v_port, family, ip);
11152 } else {
11153 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtcp:%d IN %s %s\r\n", v_port + 1, family, ip);
11154 }
11155 }
11156
11157 if (sdp_type == SDP_TYPE_REQUEST) {
11158 fir++;
11159 pli++;
11160 nack++;
11161 tmmbr++;
11162 }
11163
11164 /* DFF nack pli etc */
11165 //nack = v_engine->nack = 0;
11166 //pli = v_engine->pli = 0;
11167
11168
11169 if (v_engine->codec_negotiated) {
11170 add_fb(buf, SDPBUFLEN, v_engine->cur_payload_map->pt, v_engine->fir || fir,
11171 v_engine->nack || nack, v_engine->pli || pli, v_engine->tmmbr || tmmbr);
11172
11173 if (switch_media_handle_test_media_flag(smh, SCMF_MULTI_ANSWER_VIDEO)) {
11174 switch_mutex_lock(smh->sdp_mutex);
11175 for (pmap = v_engine->cur_payload_map; pmap && pmap->allocated; pmap = pmap->next) {
11176 if (pmap->pt != v_engine->cur_payload_map->pt && pmap->negotiated) {
11177 add_fb(buf, SDPBUFLEN, pmap->pt, v_engine->fir || fir, v_engine->nack || nack, v_engine->pli || pli, v_engine->tmmbr || tmmbr);
11178 }
11179 }
11180 switch_mutex_unlock(smh->sdp_mutex);
11181 }
11182
11183 } else if (smh->mparams->num_codecs) {
11184 int already_did[128] = { 0 };
11185 for (i = 0; i < smh->mparams->num_codecs; i++) {
11186 const switch_codec_implementation_t *imp = smh->codecs[i];
11187
11188
11189 if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO) {
11190 continue;
11191 }
11192
11193 if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_INBOUND &&
11194 switch_channel_test_flag(session->channel, CF_NOVIDEO)) {
11195 continue;
11196 }
11197
11198 if (smh->ianacodes[i] < 128) {
11199 if (already_did[smh->ianacodes[i]]) {
11200 continue;
11201 }
11202 already_did[smh->ianacodes[i]] = 1;
11203 }
11204
11205 add_fb(buf, SDPBUFLEN, smh->ianacodes[i], v_engine->fir || fir, v_engine->nack || nack, v_engine->pli || pli, v_engine->pli || pli);
11206 }
11207
11208 }
11209
11210 //switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u\r\n", v_engine->ssrc);
11211
11212 if (v_engine->ice_out.cands[0][0].ready) {
11213 char tmp1[11] = "";
11214 char tmp2[11] = "";
11215 char tmp3[11] = "";
11216 uint32_t c1 = (2^24)*126 + (2^8)*65535 + (2^0)*(256 - 1);
11217 //uint32_t c2 = (2^24)*126 + (2^8)*65535 + (2^0)*(256 - 2);
11218 //uint32_t c3 = (2^24)*126 + (2^8)*65534 + (2^0)*(256 - 1);
11219 //uint32_t c4 = (2^24)*126 + (2^8)*65534 + (2^0)*(256 - 2);
11220
11221 uint32_t c2 = c1 - 1;
11222 uint32_t c3 = c1 - 2;
11223 uint32_t c4 = c1 - 3;
11224
11225 tmp1[10] = '\0';
11226 tmp2[10] = '\0';
11227 tmp3[10] = '\0';
11228 switch_stun_random_string(tmp1, 10, "0123456789");
11229 switch_stun_random_string(tmp2, 10, "0123456789");
11230 switch_stun_random_string(tmp3, 10, "0123456789");
11231
11232 ice_out = &v_engine->ice_out;
11233
11234
11235 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u cname:%s\r\n", v_engine->ssrc, smh->cname);
11236 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u msid:%s v0\r\n", v_engine->ssrc, smh->msid);
11237 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u mslabel:%s\r\n", v_engine->ssrc, smh->msid);
11238 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u label:%sv0\r\n", v_engine->ssrc, smh->msid);
11239
11240
11241
11242 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ice-ufrag:%s\r\n", ice_out->ufrag);
11243 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ice-pwd:%s\r\n", ice_out->pwd);
11244
11245
11246 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 1 %s %u %s %d typ host generation 0\r\n",
11247 tmp1, ice_out->cands[0][0].transport, c1,
11248 ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port
11249 );
11250
11251 if (include_external && !zstr(smh->mparams->extsipip)) {
11252 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 1 %s %u %s %d typ host generation 0\r\n",
11253 tmp3, ice_out->cands[0][0].transport, c1,
11254 smh->mparams->extsipip, ice_out->cands[0][0].con_port
11255 );
11256 }
11257
11258 if (!zstr(v_engine->local_sdp_ip) && !zstr(ice_out->cands[0][0].con_addr) &&
11259 strcmp(v_engine->local_sdp_ip, ice_out->cands[0][0].con_addr)
11260 && v_engine->local_sdp_port != ice_out->cands[0][0].con_port) {
11261
11262 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 1 %s %u %s %d typ srflx raddr %s rport %d generation 0\r\n",
11263 tmp2, ice_out->cands[0][0].transport, c3,
11264 ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port,
11265 v_engine->local_sdp_ip, v_engine->local_sdp_port
11266 );
11267 }
11268
11269
11270 if (v_engine->rtcp_mux < 1 || is_outbound || switch_channel_test_flag(session->channel, CF_RECOVERING)) {
11271
11272 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ host generation 0\r\n",
11273 tmp1, ice_out->cands[0][0].transport, c2,
11274 ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port + (v_engine->rtcp_mux > 0 ? 0 : 1)
11275 );
11276
11277 if (include_external && !zstr(smh->mparams->extsipip)) {
11278 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ host generation 0\r\n",
11279 tmp3, ice_out->cands[0][0].transport, c2,
11280 smh->mparams->extsipip, ice_out->cands[0][0].con_port + (v_engine->rtcp_mux > 0 ? 0 : 1)
11281 );
11282 }
11283
11284
11285 if (!zstr(v_engine->local_sdp_ip) && !zstr(ice_out->cands[0][1].con_addr) &&
11286 strcmp(v_engine->local_sdp_ip, ice_out->cands[0][1].con_addr)
11287 && v_engine->local_sdp_port != ice_out->cands[0][1].con_port) {
11288
11289 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ srflx generation 0\r\n",
11290 tmp2, ice_out->cands[0][0].transport, c4,
11291 ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port + (v_engine->rtcp_mux > 0 ? 0 : 1),
11292 v_engine->local_sdp_ip, v_engine->local_sdp_port + (v_engine->rtcp_mux > 0 ? 0 : 1)
11293 );
11294 }
11295 }
11296
11297
11298
11299 #ifdef GOOGLE_ICE
11300 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ice-options:google-ice\r\n");
11301 #endif
11302 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=end-of-candidates\r\n");
11303
11304 }
11305
11306
11307
11308 if (loops == 0 && switch_channel_test_flag(session->channel, CF_SECURE) && !switch_channel_test_flag(session->channel, CF_DTLS)) {
11309
11310 for (i = 0; smh->crypto_suite_order[i] != CRYPTO_INVALID; i++) {
11311 switch_rtp_crypto_key_type_t j = SUITES[smh->crypto_suite_order[i]].type;
11312
11313 if ((a_engine->crypto_type == j || a_engine->crypto_type == CRYPTO_INVALID) && !zstr(a_engine->ssec[j].local_crypto_key)) {
11314 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=crypto:%s\r\n", v_engine->ssec[j].local_crypto_key);
11315 }
11316 }
11317 //switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=encryption:optional\r\n");
11318 }
11319
11320
11321 if (local_sdp_video_zrtp_hash) {
11322 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Adding video a=zrtp-hash:%s\n", local_sdp_video_zrtp_hash);
11323 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=zrtp-hash:%s\r\n", local_sdp_video_zrtp_hash);
11324 }
11325
11326
11327 if (switch_channel_test_flag(session->channel, CF_DTLS) ||
11328 !switch_channel_test_flag(session->channel, CF_SECURE) ||
11329 smh->crypto_mode == CRYPTO_MODE_MANDATORY || smh->crypto_mode == CRYPTO_MODE_FORBIDDEN) {
11330 break;
11331 }
11332 }
11333 }
11334
11335 }
11336
11337 if (switch_channel_test_cap(session->channel, CC_MSRP) && !smh->msrp_session) {
11338 int want_msrp = switch_channel_var_true(session->channel, "sip_enable_msrp");
11339 int want_msrps = switch_channel_var_true(session->channel, "sip_enable_msrps");
11340
11341 if (!want_msrp) {
11342 want_msrp = switch_channel_test_flag(session->channel, CF_WANT_MSRP);
11343 }
11344
11345 if (!want_msrps) {
11346 want_msrps = switch_channel_test_flag(session->channel, CF_WANT_MSRPS);
11347 }
11348
11349 if (want_msrp || want_msrps) {
11350 smh->msrp_session = switch_msrp_session_new(switch_core_session_get_pool(session), switch_core_session_get_uuid(session), want_msrps);
11351
11352 switch_assert(smh->msrp_session);
11353 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "MSRP session created %s\n", smh->msrp_session->call_id);
11354
11355 switch_channel_set_flag(session->channel, CF_HAS_TEXT);
11356 switch_channel_set_flag(session->channel, CF_TEXT_POSSIBLE);
11357 switch_channel_set_flag(session->channel, CF_TEXT_LINE_BASED);
11358 switch_channel_set_flag(session->channel, CF_MSRP);
11359
11360 if (want_msrps) {
11361 switch_channel_set_flag(session->channel, CF_MSRPS);
11362 }
11363
11364 switch_core_session_start_text_thread(session);
11365 }
11366 }
11367
11368 if (smh->msrp_session) {
11369 switch_msrp_session_t *msrp_session = smh->msrp_session;
11370
11371 if (!zstr(msrp_session->remote_path)) {
11372 if (zstr(msrp_session->local_path)) {
11373 msrp_session->local_path = switch_core_session_sprintf(session,
11374 "msrp%s://%s:%d/%s;tcp",
11375 msrp_session->secure ? "s" : "",
11376 ip, msrp_session->local_port, msrp_session->call_id);
11377 }
11378
11379 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf),
11380 "m=message %d TCP/%sMSRP *\r\n"
11381 "a=path:%s\r\n"
11382 "a=accept-types:%s\r\n"
11383 "a=accept-wrapped-types:%s\r\n"
11384 "a=setup:%s\r\n",
11385 msrp_session->local_port,
11386 msrp_session->secure ? "TLS/" : "",
11387 msrp_session->local_path,
11388 msrp_session->local_accept_types,
11389 msrp_session->local_accept_wrapped_types,
11390 msrp_session->active ? "active" : "passive");
11391 } else {
11392 char *uuid = switch_core_session_get_uuid(session);
11393 const char *file_selector = switch_channel_get_variable(session->channel, "sip_msrp_local_file_selector");
11394 const char *msrp_offer_active = switch_channel_get_variable(session->channel, "sip_msrp_offer_active");
11395
11396 if (switch_true(msrp_offer_active)) {
11397 msrp_session->active = 1;
11398 // switch_msrp_start_client(msrp_session);
11399 }
11400
11401 if (zstr(msrp_session->local_path)) {
11402 msrp_session->local_path = switch_core_session_sprintf(session,
11403 "msrp%s://%s:%d/%s;tcp",
11404 msrp_session->secure ? "s" : "",
11405 ip, msrp_session->local_port, uuid);
11406 }
11407
11408 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf),
11409 "m=message %d TCP/%sMSRP *\r\n"
11410 "a=path:%s\r\n"
11411 "a=accept-types:message/cpim text/* application/im-iscomposing+xml\r\n"
11412 "a=accept-wrapped-types:*\r\n"
11413 "a=setup:%s\r\n",
11414 msrp_session->local_port,
11415 msrp_session->secure ? "TLS/" : "",
11416 msrp_session->local_path,
11417 msrp_session->active ? "active" : "passive");
11418
11419 if (!zstr(file_selector)) {
11420 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf),
11421 "a=sendonly\r\na=file-selector:%s\r\n", file_selector);
11422 }
11423 }
11424 }
11425
11426 // RTP TEXT
11427
11428 if (sdp_type == SDP_TYPE_RESPONSE && !switch_channel_test_flag(session->channel, CF_RTT)) {
11429 if (switch_channel_test_flag(session->channel, CF_TEXT_SDP_RECVD)) {
11430 switch_channel_clear_flag(session->channel, CF_TEXT_SDP_RECVD);
11431 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "m=text 0 %s 19\r\n",
11432 get_media_profile_name(session,
11433 (switch_channel_test_flag(session->channel, CF_SECURE)
11434 && switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) ||
11435 a_engine->crypto_type != CRYPTO_INVALID || switch_channel_test_flag(session->channel, CF_DTLS)));
11436 }
11437 } else if ((switch_channel_test_flag(session->channel, CF_WANT_RTT) || switch_channel_test_flag(session->channel, CF_RTT) ||
11438 switch_channel_var_true(session->channel, "rtp_enable_text")) &&
11439 switch_channel_test_cap(session->channel, CC_RTP_RTT)) {
11440 t_engine->t140_pt = 0;
11441 t_engine->red_pt = 0;
11442
11443 if (sdp_type == SDP_TYPE_REQUEST) {
11444 t_engine->t140_pt = 96;
11445 t_engine->red_pt = 97;
11446
11447 switch_core_media_add_payload_map(session,
11448 SWITCH_MEDIA_TYPE_TEXT,
11449 "red",
11450 NULL,
11451 NULL,
11452 SDP_TYPE_REQUEST,
11453 t_engine->red_pt,
11454 1000,
11455 0,
11456 1,
11457 SWITCH_TRUE);
11458
11459 switch_core_media_add_payload_map(session,
11460 SWITCH_MEDIA_TYPE_TEXT,
11461 "t140",
11462 NULL,
11463 NULL,
11464 SDP_TYPE_REQUEST,
11465 t_engine->t140_pt,
11466 1000,
11467 0,
11468 1,
11469 SWITCH_TRUE);
11470
11471 t_engine->codec_negotiated = 1;
11472 }
11473
11474 if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
11475 if (switch_channel_test_flag(smh->session->channel, CF_DTLS)) {
11476 t_engine->no_crypto = 1;
11477 }
11478 }
11479
11480
11481 if (!t_engine->local_sdp_port) {
11482 switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_TEXT, 0);
11483 }
11484
11485 if ((t_port = t_engine->adv_sdp_port)) {
11486 int loops;
11487
11488 for (loops = 0; loops < 2; loops++) {
11489
11490 if (switch_channel_test_flag(smh->session->channel, CF_ICE)) {
11491 gen_ice(session, SWITCH_MEDIA_TYPE_TEXT, ip, (switch_port_t)t_port);
11492 }
11493
11494
11495 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "m=text %d %s",
11496 t_port,
11497 get_media_profile_name(session,
11498 (loops == 0 && switch_channel_test_flag(session->channel, CF_SECURE)
11499 && switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) ||
11500 a_engine->crypto_type != CRYPTO_INVALID || switch_channel_test_flag(session->channel, CF_DTLS)));
11501
11502
11503 /*****************************/
11504 if (t_engine->codec_negotiated) {
11505
11506 switch_mutex_lock(smh->sdp_mutex);
11507 for (pmap = t_engine->payload_map; pmap && pmap->allocated; pmap = pmap->next) {
11508
11509 if (pmap->type != SWITCH_MEDIA_TYPE_TEXT || !pmap->negotiated) {
11510 continue;
11511 }
11512
11513 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), " %d", pmap->pt);
11514
11515 }
11516 switch_mutex_unlock(smh->sdp_mutex);
11517 } else {
11518 switch_core_media_set_smode(smh->session, SWITCH_MEDIA_TYPE_TEXT, SWITCH_MEDIA_FLOW_SENDRECV, sdp_type);
11519 }
11520
11521 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "\r\n");
11522
11523 if (t_engine->codec_negotiated) {
11524 switch_mutex_lock(smh->sdp_mutex);
11525 for (pmap = t_engine->payload_map; pmap && pmap->allocated; pmap = pmap->next) {
11526
11527 if (pmap->type != SWITCH_MEDIA_TYPE_TEXT || !pmap->negotiated) {
11528 continue;
11529 }
11530
11531 if (!strcasecmp(pmap->iananame, "t140")) {
11532 t_engine->t140_pt = pmap->pt;
11533 }
11534
11535 if (!strcasecmp(pmap->iananame, "red")) {
11536 t_engine->red_pt = pmap->pt;
11537 }
11538
11539 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d %s/%ld\r\n",
11540 pmap->pt, pmap->iananame, pmap->rate);
11541
11542 }
11543 switch_mutex_unlock(smh->sdp_mutex);
11544
11545
11546 if (t_engine->t140_pt && t_engine->red_pt) {
11547 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=fmtp:%d %d/%d/%d\r\n", t_engine->red_pt, t_engine->t140_pt, t_engine->t140_pt, t_engine->t140_pt);
11548 }
11549
11550
11551 if (t_engine->smode == SWITCH_MEDIA_FLOW_SENDONLY) {
11552 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "%s", "a=sendonly\r\n");
11553 } else if (t_engine->smode == SWITCH_MEDIA_FLOW_RECVONLY) {
11554 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "%s", "a=recvonly\r\n");
11555 }
11556
11557 }
11558
11559 if ((is_outbound || switch_channel_test_flag(session->channel, CF_RECOVERING))
11560 && switch_channel_test_flag(smh->session->channel, CF_DTLS)) {
11561 generate_local_fingerprint(smh, SWITCH_MEDIA_TYPE_TEXT);
11562 }
11563
11564
11565 if (!zstr(t_engine->local_dtls_fingerprint.type)) {
11566 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=fingerprint:%s %s\r\na=setup:%s\r\n", t_engine->local_dtls_fingerprint.type,
11567 t_engine->local_dtls_fingerprint.str, get_setup(t_engine, session, sdp_type));
11568 }
11569
11570
11571 if (smh->mparams->rtcp_text_interval_msec) {
11572 if (t_engine->rtcp_mux > 0) {
11573 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtcp-mux\r\n");
11574 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtcp:%d IN %s %s\r\n", t_port, family, ip);
11575 } else {
11576 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtcp:%d IN %s %s\r\n", t_port + 1, family, ip);
11577 }
11578 }
11579
11580 //switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u\r\n", t_engine->ssrc);
11581
11582 if (t_engine->ice_out.cands[0][0].ready) {
11583 char tmp1[11] = "";
11584 char tmp2[11] = "";
11585 uint32_t c1 = (2^24)*126 + (2^8)*65535 + (2^0)*(256 - 1);
11586 //uint32_t c2 = (2^24)*126 + (2^8)*65535 + (2^0)*(256 - 2);
11587 //uint32_t c3 = (2^24)*126 + (2^8)*65534 + (2^0)*(256 - 1);
11588 //uint32_t c4 = (2^24)*126 + (2^8)*65534 + (2^0)*(256 - 2);
11589
11590 uint32_t c2 = c1 - 1;
11591 uint32_t c3 = c1 - 2;
11592 uint32_t c4 = c1 - 3;
11593
11594 tmp1[10] = '\0';
11595 tmp2[10] = '\0';
11596 switch_stun_random_string(tmp1, 10, "0123456789");
11597 switch_stun_random_string(tmp2, 10, "0123456789");
11598
11599 ice_out = &t_engine->ice_out;
11600
11601
11602 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u cname:%s\r\n", t_engine->ssrc, smh->cname);
11603 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u msid:%s v0\r\n", t_engine->ssrc, smh->msid);
11604 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u mslabel:%s\r\n", t_engine->ssrc, smh->msid);
11605 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u label:%sv0\r\n", t_engine->ssrc, smh->msid);
11606
11607
11608
11609 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ice-ufrag:%s\r\n", ice_out->ufrag);
11610 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ice-pwd:%s\r\n", ice_out->pwd);
11611
11612
11613 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 1 %s %u %s %d typ host generation 0\r\n",
11614 tmp1, ice_out->cands[0][0].transport, c1,
11615 ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port
11616 );
11617
11618 if (!zstr(t_engine->local_sdp_ip) && !zstr(ice_out->cands[0][0].con_addr) &&
11619 strcmp(t_engine->local_sdp_ip, ice_out->cands[0][0].con_addr)
11620 && t_engine->local_sdp_port != ice_out->cands[0][0].con_port) {
11621
11622 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 1 %s %u %s %d typ srflx raddr %s rport %d generation 0\r\n",
11623 tmp2, ice_out->cands[0][0].transport, c3,
11624 ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port,
11625 t_engine->local_sdp_ip, t_engine->local_sdp_port
11626 );
11627 }
11628
11629
11630 if (t_engine->rtcp_mux < 1 || is_outbound || switch_channel_test_flag(session->channel, CF_RECOVERING)) {
11631
11632 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ host generation 0\r\n",
11633 tmp1, ice_out->cands[0][0].transport, c2,
11634 ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port + (t_engine->rtcp_mux > 0 ? 0 : 1)
11635 );
11636
11637
11638 if (!zstr(t_engine->local_sdp_ip) && !zstr(ice_out->cands[0][1].con_addr) &&
11639 strcmp(t_engine->local_sdp_ip, ice_out->cands[0][1].con_addr)
11640 && t_engine->local_sdp_port != ice_out->cands[0][1].con_port) {
11641
11642 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ srflx generation 0\r\n",
11643 tmp2, ice_out->cands[0][0].transport, c4,
11644 ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port + (t_engine->rtcp_mux > 0 ? 0 : 1),
11645 t_engine->local_sdp_ip, t_engine->local_sdp_port + (t_engine->rtcp_mux > 0 ? 0 : 1)
11646 );
11647 }
11648 }
11649
11650
11651
11652 #ifdef GOOGLE_ICE
11653 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ice-options:google-ice\r\n");
11654 #endif
11655 }
11656
11657
11658
11659 if (loops == 0 && switch_channel_test_flag(session->channel, CF_SECURE) && !switch_channel_test_flag(session->channel, CF_DTLS)) {
11660
11661 for (i = 0; smh->crypto_suite_order[i] != CRYPTO_INVALID; i++) {
11662 switch_rtp_crypto_key_type_t j = SUITES[smh->crypto_suite_order[i]].type;
11663
11664 if ((t_engine->crypto_type == j || t_engine->crypto_type == CRYPTO_INVALID) && !zstr(t_engine->ssec[j].local_crypto_key)) {
11665 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=crypto:%s\r\n", t_engine->ssec[j].local_crypto_key);
11666 }
11667 }
11668 //switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=encryption:optional\r\n");
11669 }
11670
11671
11672 if (local_sdp_text_zrtp_hash) {
11673 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Adding text a=zrtp-hash:%s\n", local_sdp_text_zrtp_hash);
11674 switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=zrtp-hash:%s\r\n", local_sdp_text_zrtp_hash);
11675 }
11676
11677
11678 if (switch_channel_test_flag(session->channel, CF_DTLS) ||
11679 !switch_channel_test_flag(session->channel, CF_SECURE) ||
11680 smh->crypto_mode == CRYPTO_MODE_MANDATORY || smh->crypto_mode == CRYPTO_MODE_FORBIDDEN) {
11681 break;
11682 }
11683 }
11684 }
11685
11686 }
11687
11688 if (map) {
11689 switch_event_destroy(&map);
11690 }
11691
11692 if (ptmap) {
11693 switch_event_destroy(&ptmap);
11694 }
11695
11696 switch_core_media_set_local_sdp(session, buf, SWITCH_TRUE);
11697
11698 check_stream_changes(session, NULL, sdp_type);
11699
11700 switch_safe_free(buf);
11701 }
11702
11703
11704
11705 //?
switch_core_media_absorb_sdp(switch_core_session_t * session)11706 SWITCH_DECLARE(void) switch_core_media_absorb_sdp(switch_core_session_t *session)
11707 {
11708 const char *sdp_str;
11709 switch_rtp_engine_t *a_engine;
11710 switch_media_handle_t *smh;
11711
11712 switch_assert(session);
11713
11714 if (!(smh = session->media_handle)) {
11715 return;
11716 }
11717
11718 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
11719
11720 if ((sdp_str = switch_channel_get_variable(session->channel, SWITCH_B_SDP_VARIABLE))) {
11721 sdp_parser_t *parser;
11722 sdp_session_t *sdp;
11723 sdp_media_t *m;
11724 sdp_connection_t *connection;
11725
11726 if ((parser = sdp_parse(NULL, sdp_str, (int) strlen(sdp_str), 0))) {
11727 if ((sdp = sdp_session(parser))) {
11728 for (m = sdp->sdp_media; m; m = m->m_next) {
11729 if (m->m_type != sdp_media_audio || !m->m_port) {
11730 continue;
11731 }
11732
11733 connection = sdp->sdp_connection;
11734 if (m->m_connections) {
11735 connection = m->m_connections;
11736 }
11737
11738 if (connection) {
11739 a_engine->proxy_sdp_ip = switch_core_session_strdup(session, connection->c_address);
11740 }
11741 a_engine->proxy_sdp_port = (switch_port_t) m->m_port;
11742 if (a_engine->proxy_sdp_ip && a_engine->proxy_sdp_port) {
11743 break;
11744 }
11745 }
11746 }
11747 sdp_parser_free(parser);
11748 }
11749 switch_core_media_set_local_sdp(session, sdp_str, SWITCH_TRUE);
11750 }
11751 }
11752
stream_rejected(switch_media_handle_t * smh,sdp_media_e st)11753 static switch_bool_t stream_rejected(switch_media_handle_t *smh, sdp_media_e st)
11754 {
11755 int x;
11756
11757 for (x = 0; x < smh->rej_idx; x++) {
11758 if (smh->rejected_streams[x] == st) {
11759 return SWITCH_TRUE;
11760 }
11761 }
11762
11763 return SWITCH_FALSE;
11764 }
11765
11766 //?
switch_core_media_set_udptl_image_sdp(switch_core_session_t * session,switch_t38_options_t * t38_options,int insist)11767 SWITCH_DECLARE(void) switch_core_media_set_udptl_image_sdp(switch_core_session_t *session, switch_t38_options_t *t38_options, int insist)
11768 {
11769 char buf[2048] = "";
11770 char max_buf[128] = "";
11771 char max_data[128] = "";
11772 const char *ip;
11773 uint32_t port;
11774 const char *family = "IP4";
11775 const char *username;
11776 const char *bit_removal_on = "a=T38FaxFillBitRemoval\r\n";
11777 const char *bit_removal_off = "";
11778
11779 const char *mmr_on = "a=T38FaxTranscodingMMR\r\n";
11780 const char *mmr_off = "";
11781
11782 const char *jbig_on = "a=T38FaxTranscodingJBIG\r\n";
11783 const char *jbig_off = "";
11784 const char *var;
11785 int broken_boolean;
11786 switch_media_handle_t *smh;
11787 switch_rtp_engine_t *a_engine;
11788
11789 switch_assert(session);
11790
11791 if (!(smh = session->media_handle)) {
11792 return;
11793 }
11794
11795 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
11796
11797 switch_channel_clear_flag(session->channel, CF_IMAGE_SDP);
11798
11799 switch_assert(t38_options);
11800
11801 ip = t38_options->local_ip;
11802 port = t38_options->local_port;
11803 username = smh->mparams->sdp_username;
11804
11805 var = switch_channel_get_variable(session->channel, "t38_broken_boolean");
11806
11807 broken_boolean = switch_true(var);
11808
11809
11810 if (!ip) {
11811 if (!(ip = a_engine->adv_sdp_ip)) {
11812 ip = a_engine->proxy_sdp_ip;
11813 }
11814 }
11815
11816 if (!ip) {
11817 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "%s NO IP!\n", switch_channel_get_name(session->channel));
11818 return;
11819 }
11820
11821 if (!port) {
11822 if (!(port = a_engine->adv_sdp_port)) {
11823 port = a_engine->proxy_sdp_port;
11824 }
11825 }
11826
11827 if (!port) {
11828 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "%s NO PORT!\n", switch_channel_get_name(session->channel));
11829 return;
11830 }
11831
11832 if (!smh->owner_id) {
11833 smh->owner_id = (uint32_t) switch_epoch_time_now(NULL) - port;
11834 }
11835
11836 if (!smh->session_id) {
11837 smh->session_id = smh->owner_id;
11838 }
11839
11840 smh->session_id++;
11841
11842 family = strchr(ip, ':') ? "IP6" : "IP4";
11843
11844
11845 switch_snprintf(buf, sizeof(buf),
11846 "v=0\r\n"
11847 "o=%s %010u %010u IN %s %s\r\n"
11848 "s=%s\r\n" "c=IN %s %s\r\n" "t=0 0\r\n", username, smh->owner_id, smh->session_id, family, ip, username, family, ip);
11849
11850 if (t38_options->T38FaxMaxBuffer) {
11851 switch_snprintf(max_buf, sizeof(max_buf), "a=T38FaxMaxBuffer:%d\r\n", t38_options->T38FaxMaxBuffer);
11852 };
11853
11854 if (t38_options->T38FaxMaxDatagram) {
11855 switch_snprintf(max_data, sizeof(max_data), "a=T38FaxMaxDatagram:%d\r\n", t38_options->T38FaxMaxDatagram);
11856 };
11857
11858
11859
11860
11861 if (broken_boolean) {
11862 bit_removal_on = "a=T38FaxFillBitRemoval:1\r\n";
11863 bit_removal_off = "a=T38FaxFillBitRemoval:0\r\n";
11864
11865 mmr_on = "a=T38FaxTranscodingMMR:1\r\n";
11866 mmr_off = "a=T38FaxTranscodingMMR:0\r\n";
11867
11868 jbig_on = "a=T38FaxTranscodingJBIG:1\r\n";
11869 jbig_off = "a=T38FaxTranscodingJBIG:0\r\n";
11870
11871 }
11872
11873 if (stream_rejected(smh, sdp_media_audio)) {
11874 switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
11875 "m=audio 0 RTP/AVP 0\r\n");
11876 }
11877
11878 switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
11879 "m=image %d udptl t38\r\n"
11880 "a=T38FaxVersion:%d\r\n"
11881 "a=T38MaxBitRate:%d\r\n"
11882 "%s"
11883 "%s"
11884 "%s"
11885 "a=T38FaxRateManagement:%s\r\n"
11886 "%s"
11887 "%s"
11888 "a=T38FaxUdpEC:%s\r\n",
11889 //"a=T38VendorInfo:%s\r\n",
11890 port,
11891 t38_options->T38FaxVersion,
11892 t38_options->T38MaxBitRate,
11893 t38_options->T38FaxFillBitRemoval ? bit_removal_on : bit_removal_off,
11894 t38_options->T38FaxTranscodingMMR ? mmr_on : mmr_off,
11895 t38_options->T38FaxTranscodingJBIG ? jbig_on : jbig_off,
11896 t38_options->T38FaxRateManagement,
11897 max_buf,
11898 max_data,
11899 t38_options->T38FaxUdpEC
11900 //t38_options->T38VendorInfo ? t38_options->T38VendorInfo : "0 0 0"
11901 );
11902
11903
11904
11905 if (insist) {
11906 switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "m=audio 0 RTP/AVP 19\r\n");
11907 }
11908
11909 switch_core_media_set_local_sdp(session, buf, SWITCH_TRUE);
11910
11911
11912 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s image media sdp:\n%s\n",
11913 switch_channel_get_name(session->channel), smh->mparams->local_sdp_str);
11914
11915
11916 }
11917
11918
11919
11920 //?
switch_core_media_patch_sdp(switch_core_session_t * session)11921 SWITCH_DECLARE(void) switch_core_media_patch_sdp(switch_core_session_t *session)
11922 {
11923 switch_size_t len;
11924 char *p, *q, *pe, *qe;
11925 int has_video = 0, has_audio = 0, has_text = 0, has_ip = 0;
11926 char port_buf[25] = "";
11927 char vport_buf[25] = "";
11928 char tport_buf[25] = "";
11929 char *new_sdp;
11930 int bad = 0;
11931 switch_media_handle_t *smh;
11932 switch_rtp_engine_t *a_engine, *v_engine, *t_engine;
11933 payload_map_t *pmap;
11934
11935 switch_assert(session);
11936
11937 if (!(smh = session->media_handle)) {
11938 return;
11939 }
11940
11941 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
11942 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
11943 t_engine = &smh->engines[SWITCH_MEDIA_TYPE_TEXT];
11944
11945 if (zstr(smh->mparams->local_sdp_str)) {
11946 return;
11947 }
11948
11949 len = strlen(smh->mparams->local_sdp_str) * 2;
11950
11951 if (!(smh->mparams->ndlb & SM_NDLB_NEVER_PATCH_REINVITE)) {
11952 if (switch_channel_test_flag(session->channel, CF_ANSWERED) &&
11953 (switch_stristr("sendonly", smh->mparams->local_sdp_str) || switch_stristr("inactive", smh->mparams->local_sdp_str) || switch_stristr("0.0.0.0", smh->mparams->local_sdp_str))) {
11954 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Skip patch on hold SDP\n");
11955 return;
11956 }
11957 }
11958
11959 if (zstr(a_engine->local_sdp_ip) || !a_engine->local_sdp_port) {// || switch_channel_test_flag(session->channel, CF_PROXY_MEDIA)) {
11960 if (switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_AUDIO, 1) != SWITCH_STATUS_SUCCESS) {
11961 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s I/O Error\n",
11962 switch_channel_get_name(session->channel));
11963 return;
11964 }
11965
11966 clear_pmaps(a_engine);
11967
11968 switch_channel_set_flag(session->channel, CF_AUDIO);
11969
11970 pmap = switch_core_media_add_payload_map(session,
11971 SWITCH_MEDIA_TYPE_AUDIO,
11972 "PROXY",
11973 NULL,
11974 NULL,
11975 SDP_TYPE_RESPONSE,
11976 0,
11977 8000,
11978 20,
11979 1,
11980 SWITCH_TRUE);
11981
11982 a_engine->cur_payload_map = pmap;
11983
11984 }
11985
11986 new_sdp = switch_core_session_alloc(session, len);
11987 switch_snprintf(port_buf, sizeof(port_buf), "%u", a_engine->local_sdp_port);
11988
11989
11990 p = smh->mparams->local_sdp_str;
11991 q = new_sdp;
11992 pe = p + strlen(p);
11993 qe = q + len - 1;
11994
11995
11996 while (p && *p) {
11997 if (p >= pe) {
11998 bad = 1;
11999 goto end;
12000 }
12001
12002 if (q >= qe) {
12003 bad = 2;
12004 goto end;
12005 }
12006
12007 if (a_engine->local_sdp_ip && !strncmp("c=IN IP", p, 7)) {
12008 strncpy(q, p, 7);
12009 p += 7;
12010 q += 7;
12011 memcpy(q, strchr(a_engine->adv_sdp_ip, ':') ? "6 " : "4 ", 2);
12012 p +=2;
12013 q +=2;
12014 snprintf(q, qe - q, "%s", a_engine->adv_sdp_ip);
12015 q += strlen(a_engine->adv_sdp_ip);
12016
12017 while (p && *p && ((*p >= '0' && *p <= '9') || *p == '.' || *p == ':' || (*p >= 'A' && *p <= 'F') || (*p >= 'a' && *p <= 'f'))) {
12018 if (p >= pe) {
12019 bad = 3;
12020 goto end;
12021 }
12022 p++;
12023 }
12024
12025 has_ip++;
12026
12027 } else if (!strncmp("o=", p, 2)) {
12028 char *oe = strchr(p, '\n');
12029 switch_size_t len;
12030
12031 if (oe) {
12032 const char *family = "IP4";
12033 char o_line[1024] = "";
12034
12035 if (oe >= pe) {
12036 bad = 5;
12037 goto end;
12038 }
12039
12040 len = (oe - p);
12041 p += len;
12042
12043
12044 family = strchr(smh->mparams->sipip, ':') ? "IP6" : "IP4";
12045
12046 if (!smh->owner_id) {
12047 smh->owner_id = (uint32_t) switch_epoch_time_now(NULL) * 31821U + 13849U;
12048 }
12049
12050 if (!smh->session_id) {
12051 smh->session_id = smh->owner_id;
12052 }
12053
12054 smh->session_id++;
12055
12056
12057 snprintf(o_line, sizeof(o_line), "o=%s %010u %010u IN %s %s\r\n",
12058 smh->mparams->sdp_username, smh->owner_id, smh->session_id, family, smh->mparams->sipip);
12059
12060 snprintf(q, qe-q, "%s", o_line);
12061 q += strlen(o_line) - 1;
12062
12063 }
12064
12065 } else if (!strncmp("s=", p, 2)) {
12066 char *se = strchr(p, '\n');
12067 switch_size_t len;
12068
12069 if (se) {
12070 char s_line[1024] = "";
12071
12072 if (se >= pe) {
12073 bad = 5;
12074 goto end;
12075 }
12076
12077 len = (se - p);
12078 p += len;
12079
12080 snprintf(s_line, sizeof(s_line), "s=%s\r\n", smh->mparams->sdp_username);
12081 snprintf(q, qe-q, "%s", s_line);
12082
12083 q += strlen(s_line) - 1;
12084
12085 }
12086
12087 } else if ((!strncmp("m=audio ", p, 8) && *(p + 8) != '0') || (!strncmp("m=image ", p, 8) && *(p + 8) != '0')) {
12088 strncpy(q, p, 8);
12089 p += 8;
12090
12091 if (p >= pe) {
12092 bad = 4;
12093 goto end;
12094 }
12095
12096
12097 q += 8;
12098
12099 if (q >= qe) {
12100 bad = 5;
12101 goto end;
12102 }
12103
12104
12105 snprintf(q, qe - q, "%s", port_buf);
12106 q += strlen(port_buf);
12107
12108 if (q >= qe) {
12109 bad = 6;
12110 goto end;
12111 }
12112
12113 while (p && *p && (*p >= '0' && *p <= '9')) {
12114 if (p >= pe) {
12115 bad = 7;
12116 goto end;
12117 }
12118 p++;
12119 }
12120
12121 has_audio++;
12122
12123 } else if (!strncmp("m=video ", p, 8) && *(p + 8) != '0') {
12124 if (!has_video) {
12125 switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_VIDEO, 1);
12126 clear_pmaps(v_engine);
12127 pmap = switch_core_media_add_payload_map(session,
12128 SWITCH_MEDIA_TYPE_VIDEO,
12129 "PROXY-VID",
12130 NULL,
12131 NULL,
12132 SDP_TYPE_RESPONSE,
12133 0,
12134 90000,
12135 90000,
12136 1,
12137 SWITCH_TRUE);
12138 v_engine->cur_payload_map = pmap;
12139
12140 switch_snprintf(vport_buf, sizeof(vport_buf), "%u", v_engine->adv_sdp_port);
12141
12142 if (switch_channel_media_ready(session->channel) && !switch_rtp_ready(v_engine->rtp_session)) {
12143 switch_channel_set_flag(session->channel, CF_VIDEO_POSSIBLE);
12144 switch_channel_set_flag(session->channel, CF_REINVITE);
12145 switch_core_media_activate_rtp(session);
12146 }
12147
12148 v_engine->codec_negotiated = 1;
12149 switch_core_media_set_video_codec(session, SWITCH_FALSE);
12150 }
12151
12152 strncpy(q, p, 8);
12153 p += 8;
12154
12155 if (p >= pe) {
12156 bad = 8;
12157 goto end;
12158 }
12159
12160 q += 8;
12161
12162 if (q >= qe) {
12163 bad = 9;
12164 goto end;
12165 }
12166
12167 snprintf(q, qe-q, "%s", vport_buf);
12168 q += strlen(vport_buf);
12169
12170 if (q >= qe) {
12171 bad = 10;
12172 goto end;
12173 }
12174
12175 while (p && *p && (*p >= '0' && *p <= '9')) {
12176
12177 if (p >= pe) {
12178 bad = 11;
12179 goto end;
12180 }
12181
12182 p++;
12183 }
12184
12185 has_video++;
12186 } else if (!strncmp("m=text ", p, 8) && *(p + 8) != '0') {
12187 if (!has_text) {
12188 switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_TEXT, 1);
12189 clear_pmaps(t_engine);
12190 pmap = switch_core_media_add_payload_map(session,
12191 SWITCH_MEDIA_TYPE_TEXT,
12192 "PROXY-TXT",
12193 NULL,
12194 NULL,
12195 SDP_TYPE_RESPONSE,
12196 0,
12197 90000,
12198 90000,
12199 1,
12200 SWITCH_TRUE);
12201 t_engine->cur_payload_map = pmap;
12202
12203 switch_snprintf(tport_buf, sizeof(tport_buf), "%u", t_engine->adv_sdp_port);
12204
12205 if (switch_channel_media_ready(session->channel) && !switch_rtp_ready(t_engine->rtp_session)) {
12206 switch_channel_set_flag(session->channel, CF_TEXT_POSSIBLE);
12207 switch_channel_set_flag(session->channel, CF_REINVITE);
12208 switch_core_media_activate_rtp(session);
12209 }
12210
12211 t_engine->codec_negotiated = 1;
12212 //TEXT switch_core_media_set_text_codec(session, SWITCH_FALSE);
12213 }
12214
12215 strncpy(q, p, 8);
12216 p += 8;
12217
12218 if (p >= pe) {
12219 bad = 8;
12220 goto end;
12221 }
12222
12223 q += 8;
12224
12225 if (q >= qe) {
12226 bad = 9;
12227 goto end;
12228 }
12229
12230 snprintf(q, qe-q, "%s", tport_buf);
12231 q += strlen(tport_buf);
12232
12233 if (q >= qe) {
12234 bad = 10;
12235 goto end;
12236 }
12237
12238 while (p && *p && (*p >= '0' && *p <= '9')) {
12239
12240 if (p >= pe) {
12241 bad = 11;
12242 goto end;
12243 }
12244
12245 p++;
12246 }
12247
12248 has_text++;
12249 }
12250
12251
12252 while (p && *p && *p != '\n') {
12253
12254 if (p >= pe) {
12255 bad = 12;
12256 goto end;
12257 }
12258
12259 if (q >= qe) {
12260 bad = 13;
12261 goto end;
12262 }
12263
12264 *q++ = *p++;
12265 }
12266
12267 if (p >= pe) {
12268 bad = 14;
12269 goto end;
12270 }
12271
12272 if (q >= qe) {
12273 bad = 15;
12274 goto end;
12275 }
12276
12277 *q++ = *p++;
12278
12279 }
12280
12281 end:
12282
12283 if (bad) {
12284 return;
12285 }
12286
12287
12288 if (switch_channel_down(session->channel)) {
12289 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s too late.\n", switch_channel_get_name(session->channel));
12290 return;
12291 }
12292
12293
12294 if (!has_ip && !has_audio) {
12295 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s SDP has no audio in it.\n%s\n",
12296 switch_channel_get_name(session->channel), smh->mparams->local_sdp_str);
12297 return;
12298 }
12299
12300
12301 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Patched SDP\n---\n%s\n+++\n%s\n",
12302 switch_channel_get_name(session->channel), smh->mparams->local_sdp_str, new_sdp);
12303
12304 switch_core_media_set_local_sdp(session, new_sdp, SWITCH_FALSE);
12305
12306 }
12307
12308 //?
switch_core_media_start_udptl(switch_core_session_t * session,switch_t38_options_t * t38_options)12309 SWITCH_DECLARE(void) switch_core_media_start_udptl(switch_core_session_t *session, switch_t38_options_t *t38_options)
12310 {
12311 switch_media_handle_t *smh;
12312 switch_rtp_engine_t *a_engine;
12313
12314 switch_assert(session);
12315
12316 if (!(smh = session->media_handle)) {
12317 return;
12318 }
12319
12320 if (switch_channel_down(session->channel)) {
12321 return;
12322 }
12323
12324 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
12325
12326
12327 if (switch_rtp_ready(a_engine->rtp_session)) {
12328 char *remote_host = switch_rtp_get_remote_host(a_engine->rtp_session);
12329 switch_port_t remote_port = switch_rtp_get_remote_port(a_engine->rtp_session);
12330 const char *err, *val;
12331
12332 switch_channel_clear_flag(session->channel, CF_NOTIMER_DURING_BRIDGE);
12333 switch_rtp_udptl_mode(a_engine->rtp_session);
12334
12335 if (!t38_options || !t38_options->remote_ip) {
12336 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No remote address\n");
12337 return;
12338 }
12339
12340 if (remote_host && remote_port && remote_port == t38_options->remote_port && !strcmp(remote_host, t38_options->remote_ip)) {
12341 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Remote address:port [%s:%d] has not changed.\n",
12342 t38_options->remote_ip, t38_options->remote_port);
12343 return;
12344 }
12345
12346 if (switch_rtp_set_remote_address(a_engine->rtp_session, t38_options->remote_ip,
12347 t38_options->remote_port, 0, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
12348 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "IMAGE UDPTL REPORTS ERROR: [%s]\n", err);
12349 } else {
12350 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "IMAGE UDPTL CHANGING DEST TO: [%s:%d]\n",
12351 t38_options->remote_ip, t38_options->remote_port);
12352 if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) && !switch_channel_test_flag(session->channel, CF_AVPF) &&
12353 !((val = switch_channel_get_variable(session->channel, "disable_udptl_auto_adjust")) && switch_true(val))) {
12354 /* Reactivate the NAT buster flag. */
12355 switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_AUTOADJ);
12356 }
12357 }
12358 }
12359 }
12360
12361 //?
switch_core_media_hard_mute(switch_core_session_t * session,switch_bool_t on)12362 SWITCH_DECLARE(void) switch_core_media_hard_mute(switch_core_session_t *session, switch_bool_t on)
12363 {
12364 switch_core_session_message_t msg = { 0 };
12365
12366 msg.from = __FILE__;
12367
12368 msg.message_id = SWITCH_MESSAGE_INDICATE_HARD_MUTE;
12369 msg.numeric_arg = on;
12370 switch_core_session_receive_message(session, &msg);
12371 }
12372
check_engine(switch_rtp_engine_t * engine)12373 static int check_engine(switch_rtp_engine_t *engine)
12374 {
12375 dtls_state_t dtls_state = switch_rtp_dtls_state(engine->rtp_session, DTLS_TYPE_RTP);
12376 int flags = 0;
12377 switch_status_t status;
12378
12379 if (dtls_state == DS_READY || dtls_state >= DS_FAIL) return 0;
12380
12381 status = switch_rtp_zerocopy_read_frame(engine->rtp_session, &engine->read_frame, flags);
12382
12383 if (!SWITCH_READ_ACCEPTABLE(status)) {
12384 return 0;
12385 }
12386
12387 return 1;
12388 }
12389
switch_core_media_check_dtls(switch_core_session_t * session,switch_media_type_t type)12390 SWITCH_DECLARE(switch_bool_t) switch_core_media_check_dtls(switch_core_session_t *session, switch_media_type_t type)
12391 {
12392 switch_media_handle_t *smh;
12393 switch_rtp_engine_t *engine;
12394 int checking = 0;
12395
12396 switch_assert(session);
12397
12398 if (!(smh = session->media_handle)) {
12399 return SWITCH_FALSE;
12400 }
12401
12402 if (!switch_channel_media_up(session->channel)) {
12403 return SWITCH_FALSE;
12404 }
12405
12406 if (!switch_channel_test_flag(session->channel, CF_DTLS)) {
12407 return SWITCH_TRUE;
12408 }
12409
12410 engine = &smh->engines[type];
12411
12412 if (engine->rmode == SWITCH_MEDIA_FLOW_DISABLED) {
12413 return SWITCH_TRUE;
12414 }
12415
12416 do {
12417 if (engine->rtp_session) checking = check_engine(engine);
12418 } while (switch_channel_ready(session->channel) && checking);
12419
12420 if (!checking) {
12421 return SWITCH_TRUE;
12422 }
12423
12424 return SWITCH_FALSE;
12425 }
12426
switch_core_media_get_orig_bitrate(switch_core_session_t * session,switch_media_type_t type)12427 SWITCH_DECLARE(uint32_t) switch_core_media_get_orig_bitrate(switch_core_session_t *session, switch_media_type_t type)
12428 {
12429 switch_media_handle_t *smh;
12430 switch_rtp_engine_t *engine;
12431
12432 if (!(smh = session->media_handle)) {
12433 return 0;
12434 }
12435
12436 if (switch_channel_down(session->channel)) {
12437 return 0;
12438 }
12439
12440 engine = &smh->engines[type];
12441
12442 if (engine) {
12443 return engine->orig_bitrate;
12444 } else {
12445 return 0;
12446 }
12447 }
12448
switch_core_media_set_outgoing_bitrate(switch_core_session_t * session,switch_media_type_t type,uint32_t bitrate)12449 SWITCH_DECLARE(switch_status_t) switch_core_media_set_outgoing_bitrate(switch_core_session_t *session, switch_media_type_t type, uint32_t bitrate)
12450 {
12451 switch_media_handle_t *smh;
12452 switch_rtp_engine_t *engine;
12453 switch_status_t status = SWITCH_STATUS_FALSE;
12454 uint32_t new_bitrate;
12455
12456 if (!(smh = session->media_handle)) {
12457 return SWITCH_STATUS_FALSE;
12458 }
12459
12460 if (switch_channel_down(session->channel)) {
12461 return SWITCH_STATUS_FALSE;
12462 }
12463
12464 engine = &smh->engines[type];
12465
12466 new_bitrate = bitrate - bitrate * engine->bw_mult;
12467 if (switch_core_codec_ready(&engine->write_codec)) {
12468 status = switch_core_codec_control(&engine->write_codec, SCC_VIDEO_BANDWIDTH,
12469 SCCT_INT, &new_bitrate, SCCT_NONE, NULL, NULL, NULL);
12470 }
12471 engine->orig_bitrate = bitrate;
12472
12473 return status;
12474 }
12475
switch_core_media_get_media_bw_mult(switch_core_session_t * session)12476 SWITCH_DECLARE(float) switch_core_media_get_media_bw_mult(switch_core_session_t *session)
12477 {
12478 switch_media_handle_t *smh;
12479 switch_rtp_engine_t *engine;
12480
12481 if (!(smh = session->media_handle)) {
12482 return 0;
12483 }
12484
12485 if (switch_channel_down(session->channel)) {
12486 return 0;
12487 }
12488
12489 engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
12490
12491 if (engine) {
12492 return engine->bw_mult;
12493 }
12494 return 0;
12495 }
12496
switch_core_media_set_media_bw_mult(switch_core_session_t * session,float mult)12497 SWITCH_DECLARE(void) switch_core_media_set_media_bw_mult(switch_core_session_t *session, float mult)
12498 {
12499 switch_media_handle_t *smh;
12500 switch_rtp_engine_t *engine;
12501
12502 if (!(smh = session->media_handle)) {
12503 return;
12504 }
12505
12506 if (switch_channel_down(session->channel)) {
12507 return;
12508 }
12509
12510 engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
12511
12512 if (engine) {
12513 engine->bw_mult = mult;
12514 }
12515 }
12516
12517 //?
switch_core_media_reset_jb(switch_core_session_t * session,switch_media_type_t type)12518 SWITCH_DECLARE(switch_status_t) switch_core_media_reset_jb(switch_core_session_t *session, switch_media_type_t type)
12519 {
12520 switch_media_handle_t *smh;
12521 switch_rtp_engine_t *engine;
12522
12523 switch_assert(session);
12524
12525 if (!(smh = session->media_handle)) {
12526 return SWITCH_STATUS_FALSE;
12527 }
12528
12529 engine = &smh->engines[type];
12530
12531 if (switch_rtp_ready(engine->rtp_session)) {
12532 switch_rtp_reset_jb(engine->rtp_session);
12533 return SWITCH_STATUS_SUCCESS;
12534 }
12535
12536 return SWITCH_STATUS_FALSE;
12537 }
12538
12539 //?
switch_core_media_receive_message(switch_core_session_t * session,switch_core_session_message_t * msg)12540 SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg)
12541 {
12542 switch_media_handle_t *smh;
12543 switch_rtp_engine_t *a_engine, *v_engine, *t_engine;
12544 switch_status_t status = SWITCH_STATUS_SUCCESS;
12545
12546 switch_assert(session);
12547
12548 if (!(smh = session->media_handle)) {
12549 return SWITCH_STATUS_FALSE;
12550 }
12551
12552 if (switch_channel_down(session->channel)) {
12553 return SWITCH_STATUS_FALSE;
12554 }
12555
12556 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
12557 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
12558 t_engine = &smh->engines[SWITCH_MEDIA_TYPE_TEXT];
12559
12560 switch (msg->message_id) {
12561
12562 case SWITCH_MESSAGE_RESAMPLE_EVENT:
12563 {
12564 if (switch_rtp_ready(a_engine->rtp_session)) {
12565 switch_channel_audio_sync(session->channel);
12566 switch_rtp_reset_jb(a_engine->rtp_session);
12567 }
12568
12569 if (switch_channel_test_flag(session->channel, CF_CONFERENCE)) {
12570 switch_channel_set_flag(session->channel, CF_CONFERENCE_RESET_MEDIA);
12571 }
12572 }
12573 break;
12574
12575 case SWITCH_MESSAGE_INDICATE_HOLD:
12576 {
12577 if (a_engine && a_engine->rtp_session) {
12578 switch_rtp_set_max_missed_packets(a_engine->rtp_session, a_engine->max_missed_hold_packets);
12579 switch_rtp_set_media_timeout(a_engine->rtp_session, a_engine->media_hold_timeout);
12580 }
12581
12582 if (v_engine && v_engine->rtp_session) {
12583 switch_rtp_set_media_timeout(v_engine->rtp_session, v_engine->media_hold_timeout);
12584 }
12585 }
12586 break;
12587
12588 case SWITCH_MESSAGE_INDICATE_UNHOLD:
12589 {
12590 if (a_engine && a_engine->rtp_session) {
12591 switch_rtp_set_max_missed_packets(a_engine->rtp_session, a_engine->max_missed_packets);
12592 switch_rtp_set_media_timeout(a_engine->rtp_session, a_engine->media_timeout);
12593 }
12594
12595 if (v_engine && v_engine->rtp_session) {
12596 switch_rtp_set_media_timeout(v_engine->rtp_session, v_engine->media_timeout);
12597 }
12598 }
12599 break;
12600
12601 case SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ:
12602 {
12603 if (v_engine->rtp_session) {
12604 if (msg->numeric_arg || !switch_channel_test_flag(session->channel, CF_MANUAL_VID_REFRESH)) {
12605 if (switch_rtp_test_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_FIR)) {
12606 switch_rtp_video_refresh(v_engine->rtp_session);
12607 }// else {
12608 if (switch_rtp_test_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_PLI)) {
12609 switch_rtp_video_loss(v_engine->rtp_session);
12610 }
12611 //}
12612 }
12613 }
12614 }
12615
12616 break;
12617
12618 case SWITCH_MESSAGE_INDICATE_PROXY_MEDIA:
12619 {
12620 if (switch_rtp_ready(a_engine->rtp_session)) {
12621 if (msg->numeric_arg) {
12622 switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA);
12623 } else {
12624 switch_rtp_clear_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA);
12625 }
12626 }
12627 }
12628 break;
12629
12630 case SWITCH_MESSAGE_INDICATE_JITTER_BUFFER:
12631 {
12632 if (switch_rtp_ready(a_engine->rtp_session)) {
12633 check_jb(session, msg->string_arg, 0, 0, SWITCH_FALSE);
12634 }
12635 }
12636 break;
12637
12638 case SWITCH_MESSAGE_INDICATE_HARD_MUTE:
12639 if (a_engine->rtp_session) {
12640 a_engine->last_seq = 0;
12641
12642 if (session->bugs && msg->numeric_arg) {
12643 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
12644 "%s has a media bug, hard mute not allowed.\n", switch_channel_get_name(session->channel));
12645 } else {
12646 if (msg->numeric_arg) {
12647 switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_MUTE);
12648 } else {
12649 switch_rtp_clear_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_MUTE);
12650 }
12651
12652 rtp_flush_read_buffer(a_engine->rtp_session, SWITCH_RTP_FLUSH_ONCE);
12653 }
12654 }
12655
12656 break;
12657
12658 case SWITCH_MESSAGE_INDICATE_BITRATE_REQ:
12659 {
12660 if (v_engine->rtp_session) {
12661 switch_rtp_req_bitrate(v_engine->rtp_session, msg->numeric_arg);
12662 }
12663 }
12664 break;
12665
12666 case SWITCH_MESSAGE_INDICATE_BITRATE_ACK:
12667 {
12668 if (v_engine->rtp_session) {
12669 switch_rtp_ack_bitrate(v_engine->rtp_session, msg->numeric_arg);
12670 }
12671 }
12672 break;
12673
12674 case SWITCH_MESSAGE_INDICATE_CODEC_DEBUG_REQ:
12675 {
12676 switch_rtp_engine_t *engine = &smh->engines[msg->numeric_reply];
12677 uint32_t level = (uint32_t) msg->numeric_arg;
12678
12679 if (engine->rtp_session) {
12680 switch_core_codec_control(&engine->read_codec, SCC_DEBUG, SCCT_INT, (void *)&level, SCCT_NONE, NULL, NULL, NULL);
12681 switch_core_codec_control(&engine->write_codec, SCC_DEBUG, SCCT_INT, (void *)&level, SCCT_NONE, NULL, NULL, NULL);
12682 }
12683 }
12684 break;
12685
12686 case SWITCH_MESSAGE_INDICATE_CODEC_SPECIFIC_REQ:
12687 {
12688 switch_rtp_engine_t *engine;
12689 switch_io_type_t iotype = SWITCH_IO_READ;
12690 switch_media_type_t type = SWITCH_MEDIA_TYPE_AUDIO;
12691 switch_codec_control_type_t reply_type = SCCT_NONE;
12692 void *reply = NULL;
12693
12694 if (!strcasecmp(msg->string_array_arg[0], "video")) {
12695 type = SWITCH_MEDIA_TYPE_VIDEO;
12696 }
12697
12698 if (!strcasecmp(msg->string_array_arg[1], "write")) {
12699 iotype = SWITCH_IO_WRITE;
12700 }
12701
12702 engine = &smh->engines[type];
12703
12704 if (engine->rtp_session) {
12705 if (iotype == SWITCH_IO_READ) {
12706 switch_core_codec_control(&engine->read_codec, SCC_CODEC_SPECIFIC,
12707 SCCT_STRING, (void *)msg->string_array_arg[2],
12708 SCCT_STRING, (void *)msg->string_array_arg[3], &reply_type, &reply);
12709 } else {
12710 switch_core_codec_control(&engine->write_codec, SCC_CODEC_SPECIFIC,
12711 SCCT_STRING, (void *)msg->string_array_arg[2],
12712 SCCT_STRING, (void *)msg->string_array_arg[3], &reply_type, &reply);
12713 }
12714
12715
12716 if (reply_type == SCCT_STRING) {
12717 msg->string_array_arg[4] = (char *)reply;
12718 }
12719 }
12720 }
12721 break;
12722
12723 case SWITCH_MESSAGE_INDICATE_DEBUG_MEDIA:
12724 {
12725 switch_rtp_t *rtp = a_engine->rtp_session;
12726 const char *direction = msg->string_array_arg[0];
12727
12728 if (direction && *direction == 'v') {
12729 direction++;
12730 rtp = v_engine->rtp_session;
12731 } else if (direction && *direction == 't' && t_engine) {
12732 direction++;
12733 rtp = t_engine->rtp_session;
12734 }
12735
12736 if (switch_rtp_ready(rtp) && !zstr(direction) && !zstr(msg->string_array_arg[1])) {
12737 switch_rtp_flag_t flags[SWITCH_RTP_FLAG_INVALID] = {0};
12738 int both = !strcasecmp(direction, "both");
12739 int set = 0;
12740
12741 if (both || !strcasecmp(direction, "read")) {
12742 flags[SWITCH_RTP_FLAG_DEBUG_RTP_READ]++;
12743 set++;
12744 }
12745
12746 if (both || !strcasecmp(direction, "write")) {
12747 flags[SWITCH_RTP_FLAG_DEBUG_RTP_WRITE]++;
12748 set++;
12749 }
12750
12751 if (set) {
12752 if (switch_true(msg->string_array_arg[1])) {
12753 switch_rtp_set_flags(rtp, flags);
12754 } else {
12755 switch_rtp_clear_flags(rtp, flags);
12756 }
12757 } else {
12758 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid Options\n");
12759 }
12760 }
12761 }
12762 goto end;
12763 case SWITCH_MESSAGE_INDICATE_TRANSCODING_NECESSARY:
12764 if (a_engine->rtp_session && switch_rtp_test_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PASS_RFC2833)) {
12765 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Pass 2833 mode may not work on a transcoded call.\n");
12766 }
12767 goto end;
12768
12769 case SWITCH_MESSAGE_INDICATE_BRIDGE:
12770 {
12771
12772 #if 0
12773 if (switch_rtp_ready(v_engine->rtp_session)) {
12774 const char *val;
12775
12776 if ((!(val = switch_channel_get_variable(session->channel, "rtp_jitter_buffer_during_bridge")) || switch_false(val))) {
12777 if (switch_rtp_get_jitter_buffer(v_engine->rtp_session) && switch_channel_test_cap_partner(session->channel, CC_FS_RTP)) {
12778 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
12779 "%s PAUSE Jitterbuffer\n", switch_channel_get_name(session->channel));
12780 switch_rtp_pause_jitter_buffer(v_engine->rtp_session, SWITCH_TRUE);
12781 switch_set_flag(smh, SMF_VB_PAUSED);
12782 }
12783 }
12784 }
12785 #endif
12786
12787 if (switch_rtp_ready(a_engine->rtp_session)) {
12788 const char *val;
12789 int ok = 0;
12790
12791 if (!switch_channel_test_flag(session->channel, CF_VIDEO_READY) &&
12792 (!(val = switch_channel_get_variable(session->channel, "rtp_jitter_buffer_during_bridge")) || switch_false(val))) {
12793 if (switch_channel_test_flag(session->channel, CF_JITTERBUFFER) && switch_channel_test_cap_partner(session->channel, CC_FS_RTP)) {
12794 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
12795 "%s PAUSE Jitterbuffer\n", switch_channel_get_name(session->channel));
12796 switch_rtp_pause_jitter_buffer(a_engine->rtp_session, SWITCH_TRUE);
12797 switch_set_flag(smh, SMF_JB_PAUSED);
12798 }
12799 }
12800
12801 if (switch_channel_test_flag(session->channel, CF_PASS_RFC2833) && switch_channel_test_flag_partner(session->channel, CF_FS_RTP)) {
12802 switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PASS_RFC2833);
12803 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
12804 "%s activate passthru 2833 mode.\n", switch_channel_get_name(session->channel));
12805 }
12806
12807
12808 if ((val = switch_channel_get_variable(session->channel, "rtp_notimer_during_bridge"))) {
12809 ok = switch_true(val);
12810 } else {
12811 ok = switch_channel_test_flag(session->channel, CF_RTP_NOTIMER_DURING_BRIDGE);
12812 }
12813
12814 if (ok && !switch_rtp_test_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_USE_TIMER)) {
12815 ok = 0;
12816 }
12817
12818 if (ok) {
12819 switch_rtp_clear_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_USE_TIMER);
12820 //switch_rtp_clear_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_NOBLOCK);
12821 switch_channel_set_flag(session->channel, CF_NOTIMER_DURING_BRIDGE);
12822 }
12823
12824 if (ok && switch_channel_test_flag(session->channel, CF_NOTIMER_DURING_BRIDGE)) {
12825 /* these are not compat */
12826 ok = 0;
12827 } else {
12828 if ((val = switch_channel_get_variable(session->channel, "rtp_autoflush_during_bridge"))) {
12829 ok = switch_true(val);
12830 } else {
12831 ok = smh->media_flags[SCMF_RTP_AUTOFLUSH_DURING_BRIDGE];
12832 }
12833 }
12834
12835 if (ok) {
12836 rtp_flush_read_buffer(a_engine->rtp_session, SWITCH_RTP_FLUSH_STICK);
12837 switch_channel_set_flag(session->channel, CF_AUTOFLUSH_DURING_BRIDGE);
12838 } else {
12839 rtp_flush_read_buffer(a_engine->rtp_session, SWITCH_RTP_FLUSH_ONCE);
12840 }
12841
12842 }
12843 }
12844 goto end;
12845 case SWITCH_MESSAGE_INDICATE_UNBRIDGE:
12846
12847 #if 0
12848 if (switch_rtp_ready(v_engine->rtp_session)) {
12849
12850 if (switch_test_flag(smh, SMF_VB_PAUSED)) {
12851 switch_clear_flag(smh, SMF_VB_PAUSED);
12852 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
12853 "%s RESUME Video Jitterbuffer\n", switch_channel_get_name(session->channel));
12854 switch_rtp_pause_jitter_buffer(v_engine->rtp_session, SWITCH_FALSE);
12855
12856 }
12857 }
12858 #endif
12859
12860 if (switch_rtp_ready(a_engine->rtp_session)) {
12861
12862 if (switch_test_flag(smh, SMF_JB_PAUSED)) {
12863 switch_clear_flag(smh, SMF_JB_PAUSED);
12864 if (switch_channel_test_flag(session->channel, CF_JITTERBUFFER)) {
12865 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
12866 "%s RESUME Jitterbuffer\n", switch_channel_get_name(session->channel));
12867 switch_rtp_pause_jitter_buffer(a_engine->rtp_session, SWITCH_FALSE);
12868 }
12869 }
12870
12871
12872 if (switch_rtp_test_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PASS_RFC2833)) {
12873 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s deactivate passthru 2833 mode.\n",
12874 switch_channel_get_name(session->channel));
12875 switch_rtp_clear_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PASS_RFC2833);
12876 }
12877
12878 if (switch_channel_test_flag(session->channel, CF_NOTIMER_DURING_BRIDGE)) {
12879 if (!switch_rtp_test_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_UDPTL) &&
12880 !switch_rtp_test_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA)) {
12881 switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_USE_TIMER);
12882 //switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_NOBLOCK);
12883 }
12884 switch_channel_clear_flag(session->channel, CF_NOTIMER_DURING_BRIDGE);
12885 }
12886
12887 if (switch_channel_test_flag(session->channel, CF_AUTOFLUSH_DURING_BRIDGE)) {
12888 rtp_flush_read_buffer(a_engine->rtp_session, SWITCH_RTP_FLUSH_UNSTICK);
12889 switch_channel_clear_flag(session->channel, CF_AUTOFLUSH_DURING_BRIDGE);
12890 } else {
12891 rtp_flush_read_buffer(a_engine->rtp_session, SWITCH_RTP_FLUSH_ONCE);
12892 }
12893
12894 }
12895 goto end;
12896 case SWITCH_MESSAGE_INDICATE_AUDIO_SYNC:
12897 if (switch_rtp_ready(a_engine->rtp_session)) {
12898 rtp_flush_read_buffer(a_engine->rtp_session, SWITCH_RTP_FLUSH_ONCE);
12899 //switch_rtp_reset_jb(a_engine->rtp_session);
12900 }
12901 goto end;
12902
12903 case SWITCH_MESSAGE_INDICATE_VIDEO_SYNC:
12904 if (switch_rtp_ready(v_engine->rtp_session)) {
12905 switch_rtp_flush(v_engine->rtp_session);
12906 //switch_rtp_reset_jb(v_engine->rtp_session);
12907 }
12908 goto end;
12909 case SWITCH_MESSAGE_INDICATE_3P_MEDIA:
12910 case SWITCH_MESSAGE_INDICATE_MEDIA:
12911 {
12912
12913 a_engine->codec_negotiated = 0;
12914 v_engine->codec_negotiated = 0;
12915
12916 if (session->track_duration) {
12917 switch_core_session_enable_heartbeat(session, session->track_duration);
12918 }
12919 }
12920 break;
12921
12922 case SWITCH_MESSAGE_INDICATE_3P_NOMEDIA:
12923 switch_channel_set_flag(session->channel, CF_PROXY_MODE);
12924 switch_core_media_set_local_sdp(session, NULL, SWITCH_FALSE);
12925 break;
12926 case SWITCH_MESSAGE_INDICATE_NOMEDIA:
12927 {
12928 const char *uuid;
12929 switch_core_session_t *other_session;
12930 switch_channel_t *other_channel;
12931 const char *ip = NULL, *port = NULL;
12932
12933 switch_channel_set_flag(session->channel, CF_PROXY_MODE);
12934
12935 switch_core_media_set_local_sdp(session, NULL, SWITCH_FALSE);
12936
12937 if (switch_true(switch_channel_get_variable(session->channel, "bypass_keep_codec"))) {
12938 switch_channel_set_variable(session->channel, "absolute_codec_string", switch_channel_get_variable(session->channel, "ep_codec_string"));
12939 }
12940
12941
12942 if ((uuid = switch_channel_get_partner_uuid(session->channel))
12943 && (other_session = switch_core_session_locate(uuid))) {
12944 other_channel = switch_core_session_get_channel(other_session);
12945 ip = switch_channel_get_variable(other_channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE);
12946 port = switch_channel_get_variable(other_channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE);
12947 switch_core_session_rwunlock(other_session);
12948
12949 if (ip && port) {
12950 switch_core_media_prepare_codecs(session, 1);
12951 clear_pmaps(a_engine);
12952 clear_pmaps(v_engine);
12953 switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, ip, (switch_port_t)atoi(port), NULL, 1);
12954 }
12955 }
12956
12957
12958 if (!smh->mparams->local_sdp_str) {
12959 switch_core_media_absorb_sdp(session);
12960 }
12961
12962 if (session->track_duration) {
12963 switch_core_session_enable_heartbeat(session, session->track_duration);
12964 }
12965
12966 }
12967 break;
12968
12969
12970 default:
12971 break;
12972 }
12973
12974
12975 if (smh->mutex) switch_mutex_lock(smh->mutex);
12976
12977
12978 if (switch_channel_down(session->channel)) {
12979 status = SWITCH_STATUS_FALSE;
12980 goto end_lock;
12981 }
12982
12983 switch (msg->message_id) {
12984 case SWITCH_MESSAGE_INDICATE_MEDIA_RENEG:
12985 {
12986 switch_core_session_t *nsession;
12987
12988 if (msg->string_arg) {
12989 switch_channel_set_variable(session->channel, "absolute_codec_string", NULL);
12990
12991 if (*msg->string_arg == '=') {
12992 switch_channel_set_variable(session->channel, "codec_string", msg->string_arg);
12993 } else {
12994 switch_channel_set_variable_printf(session->channel,
12995 "codec_string", "=%s", switch_channel_get_variable(session->channel, "ep_codec_string"));
12996 }
12997
12998 a_engine->codec_negotiated = 0;
12999 v_engine->codec_negotiated = 0;
13000 smh->num_negotiated_codecs = 0;
13001 switch_channel_clear_flag(session->channel, CF_VIDEO_POSSIBLE);
13002 switch_core_media_prepare_codecs(session, SWITCH_TRUE);
13003 switch_core_media_check_video_codecs(session);
13004
13005 switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 1);
13006 }
13007
13008 if (msg->numeric_arg && switch_core_session_get_partner(session, &nsession) == SWITCH_STATUS_SUCCESS) {
13009 msg->numeric_arg = 0;
13010 switch_core_session_receive_message(nsession, msg);
13011 switch_core_session_rwunlock(nsession);
13012 }
13013
13014 }
13015 break;
13016
13017 case SWITCH_MESSAGE_INDICATE_AUDIO_DATA:
13018 {
13019 if (switch_rtp_ready(a_engine->rtp_session)) {
13020 if (msg->numeric_arg) {
13021 if (switch_channel_test_flag(session->channel, CF_JITTERBUFFER)) {
13022 switch_rtp_pause_jitter_buffer(a_engine->rtp_session, SWITCH_TRUE);
13023 switch_set_flag(smh, SMF_JB_PAUSED);
13024 }
13025
13026 rtp_flush_read_buffer(a_engine->rtp_session, SWITCH_RTP_FLUSH_UNSTICK);
13027
13028 } else {
13029 if (switch_test_flag(smh, SMF_JB_PAUSED)) {
13030 switch_clear_flag(smh, SMF_JB_PAUSED);
13031 if (switch_channel_test_flag(session->channel, CF_JITTERBUFFER)) {
13032 switch_rtp_pause_jitter_buffer(a_engine->rtp_session, SWITCH_FALSE);
13033 }
13034 }
13035 }
13036 }
13037 }
13038 break;
13039
13040 case SWITCH_MESSAGE_INDICATE_UDPTL_MODE:
13041 {
13042 switch_t38_options_t *t38_options = switch_channel_get_private(session->channel, "t38_options");
13043
13044 if (t38_options) {
13045 switch_core_media_start_udptl(session, t38_options);
13046 }
13047
13048 }
13049
13050
13051 default:
13052 break;
13053 }
13054
13055
13056 end_lock:
13057
13058 if (smh->mutex) switch_mutex_unlock(smh->mutex);
13059
13060 end:
13061
13062 if (switch_channel_down(session->channel)) {
13063 status = SWITCH_STATUS_FALSE;
13064 }
13065
13066 return status;
13067
13068 }
13069
13070 //?
switch_core_media_break(switch_core_session_t * session,switch_media_type_t type)13071 SWITCH_DECLARE(void) switch_core_media_break(switch_core_session_t *session, switch_media_type_t type)
13072 {
13073 switch_media_handle_t *smh;
13074
13075 switch_assert(session);
13076
13077 if (!(smh = session->media_handle)) {
13078 return;
13079 }
13080
13081 if (switch_rtp_ready(smh->engines[type].rtp_session)) {
13082 switch_rtp_break(smh->engines[type].rtp_session);
13083 }
13084 }
13085
13086 //?
switch_core_media_kill_socket(switch_core_session_t * session,switch_media_type_t type)13087 SWITCH_DECLARE(void) switch_core_media_kill_socket(switch_core_session_t *session, switch_media_type_t type)
13088 {
13089 switch_media_handle_t *smh;
13090
13091 switch_assert(session);
13092
13093 if (!(smh = session->media_handle)) {
13094 return;
13095 }
13096
13097 if (switch_rtp_ready(smh->engines[type].rtp_session)) {
13098 switch_rtp_kill_socket(smh->engines[type].rtp_session);
13099 }
13100 }
13101
13102 //?
switch_core_media_queue_rfc2833(switch_core_session_t * session,switch_media_type_t type,const switch_dtmf_t * dtmf)13103 SWITCH_DECLARE(switch_status_t) switch_core_media_queue_rfc2833(switch_core_session_t *session, switch_media_type_t type, const switch_dtmf_t *dtmf)
13104 {
13105 switch_media_handle_t *smh;
13106
13107 switch_assert(session);
13108
13109 if (!(smh = session->media_handle)) {
13110 return SWITCH_STATUS_FALSE;
13111 }
13112
13113 if (switch_rtp_ready(smh->engines[type].rtp_session)) {
13114 return switch_rtp_queue_rfc2833(smh->engines[type].rtp_session, dtmf);
13115 }
13116
13117 return SWITCH_STATUS_FALSE;
13118 }
13119
13120 //?
switch_core_media_queue_rfc2833_in(switch_core_session_t * session,switch_media_type_t type,const switch_dtmf_t * dtmf)13121 SWITCH_DECLARE(switch_status_t) switch_core_media_queue_rfc2833_in(switch_core_session_t *session, switch_media_type_t type, const switch_dtmf_t *dtmf)
13122 {
13123 switch_media_handle_t *smh;
13124
13125 switch_assert(session);
13126
13127 if (!(smh = session->media_handle)) {
13128 return SWITCH_STATUS_FALSE;
13129 }
13130
13131 if (switch_rtp_ready(smh->engines[type].rtp_session)) {
13132 return switch_rtp_queue_rfc2833_in(smh->engines[type].rtp_session, dtmf);
13133 }
13134
13135 return SWITCH_STATUS_FALSE;
13136 }
13137
13138 //?
switch_core_media_ready(switch_core_session_t * session,switch_media_type_t type)13139 SWITCH_DECLARE(uint8_t) switch_core_media_ready(switch_core_session_t *session, switch_media_type_t type)
13140 {
13141 switch_media_handle_t *smh;
13142
13143 switch_assert(session);
13144
13145 if (!(smh = session->media_handle)) {
13146 return 0;
13147 }
13148
13149 return switch_rtp_ready(smh->engines[type].rtp_session);
13150 }
13151
13152 //?
switch_core_media_set_rtp_flag(switch_core_session_t * session,switch_media_type_t type,switch_rtp_flag_t flag)13153 SWITCH_DECLARE(void) switch_core_media_set_rtp_flag(switch_core_session_t *session, switch_media_type_t type, switch_rtp_flag_t flag)
13154 {
13155 switch_media_handle_t *smh;
13156
13157 switch_assert(session);
13158
13159 if (!(smh = session->media_handle)) {
13160 return;
13161 }
13162
13163 if (switch_rtp_ready(smh->engines[type].rtp_session)) {
13164 switch_rtp_set_flag(smh->engines[type].rtp_session, flag);
13165 }
13166 }
13167
13168 //?
switch_core_media_clear_rtp_flag(switch_core_session_t * session,switch_media_type_t type,switch_rtp_flag_t flag)13169 SWITCH_DECLARE(void) switch_core_media_clear_rtp_flag(switch_core_session_t *session, switch_media_type_t type, switch_rtp_flag_t flag)
13170 {
13171 switch_media_handle_t *smh;
13172
13173 switch_assert(session);
13174
13175 if (!(smh = session->media_handle)) {
13176 return;
13177 }
13178
13179 if (switch_rtp_ready(smh->engines[type].rtp_session)) {
13180 switch_rtp_clear_flag(smh->engines[type].rtp_session, flag);
13181 }
13182 }
13183
13184 //?
switch_core_media_set_telephony_event(switch_core_session_t * session,switch_media_type_t type,switch_payload_t te)13185 SWITCH_DECLARE(void) switch_core_media_set_telephony_event(switch_core_session_t *session, switch_media_type_t type, switch_payload_t te)
13186 {
13187 switch_media_handle_t *smh;
13188
13189 switch_assert(session);
13190
13191 if (!(smh = session->media_handle)) {
13192 return;
13193 }
13194
13195 if (switch_rtp_ready(smh->engines[type].rtp_session)) {
13196 switch_rtp_set_telephony_event(smh->engines[type].rtp_session, te);
13197 }
13198 }
13199
13200 //?
switch_core_media_set_telephony_recv_event(switch_core_session_t * session,switch_media_type_t type,switch_payload_t te)13201 SWITCH_DECLARE(void) switch_core_media_set_telephony_recv_event(switch_core_session_t *session, switch_media_type_t type, switch_payload_t te)
13202 {
13203 switch_media_handle_t *smh;
13204
13205 switch_assert(session);
13206
13207 if (!(smh = session->media_handle)) {
13208 return;
13209 }
13210
13211 if (switch_rtp_ready(smh->engines[type].rtp_session)) {
13212 switch_rtp_set_telephony_recv_event(smh->engines[type].rtp_session, te);
13213 }
13214 }
13215
13216 //?
switch_core_media_get_stats(switch_core_session_t * session,switch_media_type_t type,switch_memory_pool_t * pool)13217 SWITCH_DECLARE(switch_rtp_stats_t *) switch_core_media_get_stats(switch_core_session_t *session, switch_media_type_t type, switch_memory_pool_t *pool)
13218 {
13219 switch_media_handle_t *smh;
13220
13221 switch_assert(session);
13222
13223 if (!(smh = session->media_handle)) {
13224 return NULL;
13225 }
13226
13227 if (smh->engines[type].rtp_session) {
13228 return switch_rtp_get_stats(smh->engines[type].rtp_session, pool);
13229 }
13230
13231 return NULL;
13232 }
13233
13234 //?
switch_core_media_check_udptl_mode(switch_core_session_t * session,switch_media_type_t type)13235 SWITCH_DECLARE(switch_bool_t) switch_core_media_check_udptl_mode(switch_core_session_t *session, switch_media_type_t type)
13236 {
13237 switch_media_handle_t *smh;
13238
13239 switch_assert(session);
13240
13241 if (!(smh = session->media_handle)) {
13242 return SWITCH_FALSE;
13243 }
13244
13245 if (switch_rtp_ready(smh->engines[type].rtp_session)) {
13246 return switch_rtp_test_flag(smh->engines[type].rtp_session, SWITCH_RTP_FLAG_UDPTL) ? SWITCH_TRUE : SWITCH_FALSE;
13247 }
13248
13249 return SWITCH_FALSE;
13250 }
13251
13252 //?
switch_core_media_udptl_mode(switch_core_session_t * session,switch_media_type_t type)13253 SWITCH_DECLARE(switch_status_t) switch_core_media_udptl_mode(switch_core_session_t *session, switch_media_type_t type)
13254 {
13255 switch_media_handle_t *smh;
13256
13257 switch_assert(session);
13258
13259 if (!(smh = session->media_handle)) {
13260 return SWITCH_STATUS_FALSE;
13261 }
13262
13263 if (switch_rtp_ready(smh->engines[type].rtp_session)) {
13264 return switch_rtp_udptl_mode(smh->engines[type].rtp_session);
13265 }
13266
13267 return SWITCH_STATUS_FALSE;
13268 }
13269
13270 //?
switch_core_media_get_jb(switch_core_session_t * session,switch_media_type_t type)13271 SWITCH_DECLARE(switch_jb_t *) switch_core_media_get_jb(switch_core_session_t *session, switch_media_type_t type)
13272 {
13273 switch_media_handle_t *smh;
13274
13275 switch_assert(session);
13276
13277 if (!(smh = session->media_handle)) {
13278 return NULL;
13279 }
13280
13281 if (switch_rtp_ready(smh->engines[type].rtp_session)) {
13282 return switch_rtp_get_jitter_buffer(smh->engines[type].rtp_session);
13283 }
13284
13285 return NULL;
13286 }
13287
13288
13289 //?
switch_core_media_set_sdp_codec_string(switch_core_session_t * session,const char * r_sdp,switch_sdp_type_t sdp_type)13290 SWITCH_DECLARE(void) switch_core_media_set_sdp_codec_string(switch_core_session_t *session, const char *r_sdp, switch_sdp_type_t sdp_type)
13291 {
13292 switch_core_media_merge_sdp_codec_string(session, r_sdp, sdp_type, switch_core_media_get_codec_string(session));
13293 }
13294
switch_core_media_merge_sdp_codec_string(switch_core_session_t * session,const char * r_sdp,switch_sdp_type_t sdp_type,const char * codec_string)13295 SWITCH_DECLARE(void) switch_core_media_merge_sdp_codec_string(switch_core_session_t *session, const char *r_sdp,
13296 switch_sdp_type_t sdp_type, const char *codec_string)
13297 {
13298
13299
13300
13301 sdp_parser_t *parser;
13302 sdp_session_t *sdp;
13303 switch_media_handle_t *smh;
13304
13305 switch_assert(session);
13306
13307 if (!(smh = session->media_handle)) {
13308 return;
13309 }
13310
13311 if (!r_sdp) {
13312 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Setting NULL SDP is invalid\n");
13313 return;
13314 }
13315
13316 if (zstr(codec_string)) {
13317 codec_string = switch_core_media_get_codec_string(session);
13318 }
13319
13320 if ((parser = sdp_parse(NULL, r_sdp, (int) strlen(r_sdp), 0))) {
13321
13322 if ((sdp = sdp_session(parser))) {
13323 switch_core_media_set_r_sdp_codec_string(session, codec_string, sdp, sdp_type);
13324 }
13325
13326 sdp_parser_free(parser);
13327 }
13328
13329 }
13330
13331
add_audio_codec(sdp_rtpmap_t * map,const switch_codec_implementation_t * imp,int ptime,char * buf,switch_size_t buflen)13332 static void add_audio_codec(sdp_rtpmap_t *map, const switch_codec_implementation_t *imp, int ptime, char *buf, switch_size_t buflen)
13333 {
13334 int codec_ms = ptime;
13335 uint32_t map_bit_rate = 0, map_channels = 1;
13336 char ptstr[20] = "";
13337 char ratestr[20] = "";
13338 char bitstr[20] = "";
13339 switch_codec_fmtp_t codec_fmtp = { 0 };
13340
13341 if (!codec_ms) {
13342 codec_ms = switch_default_ptime(map->rm_encoding, map->rm_pt);
13343 }
13344
13345 map_channels = map->rm_params ? atoi(map->rm_params) : 1;
13346 map_bit_rate = switch_known_bitrate((switch_payload_t)map->rm_pt);
13347
13348 if (!ptime && !strcasecmp(map->rm_encoding, "g723")) {
13349 codec_ms = 30;
13350 }
13351
13352 if (zstr(map->rm_fmtp)) {
13353 if (!strcasecmp(map->rm_encoding, "ilbc")) {
13354 codec_ms = 30;
13355 map_bit_rate = 13330;
13356 } else if (!strcasecmp(map->rm_encoding, "isac")) {
13357 codec_ms = 30;
13358 map_bit_rate = 32000;
13359 }
13360 } else {
13361 if ((switch_core_codec_parse_fmtp(map->rm_encoding, map->rm_fmtp, map->rm_rate, &codec_fmtp)) == SWITCH_STATUS_SUCCESS) {
13362 if (codec_fmtp.bits_per_second) {
13363 map_bit_rate = codec_fmtp.bits_per_second;
13364 }
13365 if (codec_fmtp.microseconds_per_packet) {
13366 codec_ms = (codec_fmtp.microseconds_per_packet / 1000);
13367 }
13368 }
13369 }
13370
13371 if (map->rm_rate) {
13372 switch_snprintf(ratestr, sizeof(ratestr), "@%uh", (unsigned int) map->rm_rate);
13373 }
13374
13375 if (codec_ms) {
13376 switch_snprintf(ptstr, sizeof(ptstr), "@%di", codec_ms);
13377 }
13378
13379 if (map_bit_rate) {
13380 switch_snprintf(bitstr, sizeof(bitstr), "@%db", map_bit_rate);
13381 }
13382
13383 if (map_channels > 1) {
13384 switch_snprintf(bitstr, sizeof(bitstr), "@%dc", map_channels);
13385 }
13386
13387 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), ",%s.%s%s%s%s", imp->modname, map->rm_encoding, ratestr, ptstr, bitstr);
13388
13389 }
13390
13391
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)13392 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)
13393 {
13394 char buf[1024] = { 0 };
13395 sdp_media_t *m;
13396 sdp_attribute_t *attr;
13397 int ptime = 0, dptime = 0;
13398 sdp_connection_t *connection;
13399 sdp_rtpmap_t *map;
13400 short int match = 0;
13401 int i;
13402 int already_did[128] = { 0 };
13403 int num_codecs = 0;
13404 char *codec_order[SWITCH_MAX_CODECS];
13405 const switch_codec_implementation_t *codecs[SWITCH_MAX_CODECS] = { 0 };
13406 char fmtp[SWITCH_MAX_CODECS][MAX_FMTP_LEN];
13407
13408 switch_channel_t *channel = switch_core_session_get_channel(session);
13409 int prefer_sdp = 0;
13410 const char *var;
13411 switch_media_handle_t *smh;
13412
13413 switch_assert(session);
13414
13415 if (!(smh = session->media_handle)) {
13416 return;
13417 }
13418
13419
13420 if ((var = switch_channel_get_variable(channel, "ep_codec_prefer_sdp")) && switch_true(var)) {
13421 prefer_sdp = 1;
13422 }
13423
13424
13425 if (!zstr(codec_string)) {
13426 char *tmp_codec_string;
13427
13428 if (*codec_string == '=') codec_string++;
13429
13430 if ((tmp_codec_string = strdup(codec_string))) {
13431 num_codecs = switch_separate_string(tmp_codec_string, ',', codec_order, SWITCH_MAX_CODECS);
13432 num_codecs = switch_loadable_module_get_codecs_sorted(codecs, fmtp, SWITCH_MAX_CODECS, codec_order, num_codecs);
13433 switch_safe_free(tmp_codec_string);
13434 }
13435 } else {
13436 num_codecs = switch_loadable_module_get_codecs(codecs, SWITCH_MAX_CODECS);
13437 }
13438
13439 if (!channel || !num_codecs) {
13440 return;
13441 }
13442
13443 for (attr = sdp->sdp_attributes; attr; attr = attr->a_next) {
13444 if (zstr(attr->a_name)) {
13445 continue;
13446 }
13447 if (!strcasecmp(attr->a_name, "ptime")) {
13448 dptime = atoi(attr->a_value);
13449 break;
13450 }
13451 }
13452
13453 switch_core_media_find_zrtp_hash(session, sdp);
13454 switch_core_media_pass_zrtp_hash(session);
13455
13456 for (m = sdp->sdp_media; m; m = m->m_next) {
13457 ptime = dptime;
13458
13459 if ((m->m_type == sdp_media_audio || m->m_type == sdp_media_video) && m->m_port) {
13460 for (map = m->m_rtpmaps; map; map = map->rm_next) {
13461 int found = 0;
13462 for (attr = m->m_attributes; attr && found < 2; attr = attr->a_next) {
13463 if (zstr(attr->a_name)) {
13464 continue;
13465 }
13466 if (!strcasecmp(attr->a_name, "ptime") && attr->a_value) {
13467 ptime = atoi(attr->a_value);
13468 found++;
13469 }
13470 if (!strcasecmp(attr->a_name, "rtcp-mux")) {
13471 if (switch_channel_var_true(channel, "rtcp_mux_auto_detect")) {
13472 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "setting rtcp-mux from sdp\n");
13473 switch_channel_set_variable(channel, "rtcp_mux", "true");
13474 }
13475 found++;
13476 }
13477 }
13478 switch_core_media_add_payload_map(session,
13479 m->m_type == sdp_media_audio ? SWITCH_MEDIA_TYPE_AUDIO : SWITCH_MEDIA_TYPE_VIDEO,
13480 map->rm_encoding,
13481 NULL,
13482 map->rm_fmtp,
13483 sdp_type,
13484 map->rm_pt,
13485 map->rm_rate,
13486 ptime,
13487 map->rm_params ? atoi(map->rm_params) : 1,
13488 SWITCH_FALSE);
13489 }
13490 }
13491 }
13492
13493 for (m = sdp->sdp_media; m; m = m->m_next) {
13494 ptime = dptime;
13495
13496 if (m->m_type == sdp_media_image && m->m_port) {
13497 switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ",t38");
13498 } else if (m->m_type == sdp_media_audio && m->m_port) {
13499 for (attr = m->m_attributes; attr; attr = attr->a_next) {
13500 if (zstr(attr->a_name)) {
13501 continue;
13502 }
13503 if (!strcasecmp(attr->a_name, "ptime") && attr->a_value) {
13504 ptime = atoi(attr->a_value);
13505 break;
13506 }
13507 }
13508 connection = sdp->sdp_connection;
13509 if (m->m_connections) {
13510 connection = m->m_connections;
13511 }
13512
13513 if (!connection) {
13514 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_ERROR, "Cannot find a c= line in the sdp at media or session level!\n");
13515 break;
13516 }
13517
13518 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND || prefer_sdp) {
13519 for (map = m->m_rtpmaps; map; map = map->rm_next) {
13520
13521 if (map->rm_pt > 127 || already_did[map->rm_pt]) {
13522 continue;
13523 }
13524
13525 for (i = 0; i < num_codecs; i++) {
13526 const switch_codec_implementation_t *imp = codecs[i];
13527
13528 if ((zstr(map->rm_encoding) || (smh->mparams->ndlb & SM_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) {
13529 match = (map->rm_pt == imp->ianacode) ? 1 : 0;
13530 } else {
13531 if (map->rm_encoding) {
13532 match = !strcasecmp(map->rm_encoding, imp->iananame) &&
13533 ((map->rm_pt < 96 && imp->ianacode < 96) || (map->rm_pt > 95 && imp->ianacode > 95));
13534 } else {
13535 match = 0;
13536 }
13537 }
13538
13539 if (match) {
13540 add_audio_codec(map, imp, ptime, buf, sizeof(buf));
13541 }
13542
13543 }
13544 }
13545
13546 } else {
13547 for (i = 0; i < num_codecs; i++) {
13548 const switch_codec_implementation_t *imp = codecs[i];
13549 if (imp->codec_type != SWITCH_CODEC_TYPE_AUDIO || imp->ianacode > 127 || already_did[imp->ianacode]) {
13550 continue;
13551 }
13552 for (map = m->m_rtpmaps; map; map = map->rm_next) {
13553
13554 if (map->rm_pt > 127 || already_did[map->rm_pt]) {
13555 continue;
13556 }
13557
13558 if ((zstr(map->rm_encoding) || (smh->mparams->ndlb & SM_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) {
13559 match = (map->rm_pt == imp->ianacode) ? 1 : 0;
13560 } else {
13561 if (map->rm_encoding) {
13562 match = !strcasecmp(map->rm_encoding, imp->iananame) &&
13563 ((map->rm_pt < 96 && imp->ianacode < 96) || (map->rm_pt > 95 && imp->ianacode > 95));
13564 } else {
13565 match = 0;
13566 }
13567 }
13568
13569 if (match) {
13570 add_audio_codec(map, imp, ptime, buf, sizeof(buf));
13571 }
13572 }
13573 }
13574 }
13575
13576 } else if (m->m_type == sdp_media_video && m->m_port) {
13577 connection = sdp->sdp_connection;
13578 if (m->m_connections) {
13579 connection = m->m_connections;
13580 }
13581
13582 if (!connection) {
13583 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_ERROR, "Cannot find a c= line in the sdp at media or session level!\n");
13584 break;
13585 }
13586
13587
13588 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND || prefer_sdp) {
13589 for (map = m->m_rtpmaps; map; map = map->rm_next) {
13590
13591 if (map->rm_pt > 127 || already_did[map->rm_pt]) {
13592 continue;
13593 }
13594
13595 for (i = 0; i < num_codecs; i++) {
13596 const switch_codec_implementation_t *imp = codecs[i];
13597
13598 if ((zstr(map->rm_encoding) || (smh->mparams->ndlb & SM_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) {
13599 match = (map->rm_pt == imp->ianacode) ? 1 : 0;
13600 } else {
13601 if (map->rm_encoding) {
13602 match = !strcasecmp(map->rm_encoding, imp->iananame) &&
13603 ((map->rm_pt < 96 && imp->ianacode < 96) || (map->rm_pt > 95 && imp->ianacode > 95));
13604 } else {
13605 match = 0;
13606 }
13607 }
13608
13609 if (match) {
13610 if (map->rm_fmtp) {
13611 switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ",%s.%s~%s", imp->modname, imp->iananame, map->rm_fmtp);
13612 } else {
13613 switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ",%s.%s", imp->modname, imp->iananame);
13614 }
13615 already_did[imp->ianacode] = 1;
13616 }
13617 }
13618 }
13619
13620 } else {
13621 for (i = 0; i < num_codecs; i++) {
13622 const switch_codec_implementation_t *imp = codecs[i];
13623
13624 if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO || imp->ianacode > 127 || already_did[imp->ianacode]) {
13625 continue;
13626 }
13627
13628 if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_INBOUND &&
13629 switch_channel_test_flag(session->channel, CF_NOVIDEO)) {
13630 continue;
13631 }
13632
13633 for (map = m->m_rtpmaps; map; map = map->rm_next) {
13634
13635 if (map->rm_pt > 127 || already_did[map->rm_pt]) {
13636 continue;
13637 }
13638
13639 if ((zstr(map->rm_encoding) || (smh->mparams->ndlb & SM_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) {
13640 match = (map->rm_pt == imp->ianacode) ? 1 : 0;
13641 } else {
13642 if (map->rm_encoding) {
13643 match = !strcasecmp(map->rm_encoding, imp->iananame) &&
13644 ((map->rm_pt < 96 && imp->ianacode < 96) || (map->rm_pt > 95 && imp->ianacode > 95));
13645 } else {
13646 match = 0;
13647 }
13648 }
13649
13650 if (match) {
13651 if (map->rm_fmtp) {
13652 switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ",%s.%s~%s", imp->modname, imp->iananame, map->rm_fmtp);
13653 } else {
13654 switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ",%s.%s", imp->modname, imp->iananame);
13655 }
13656 already_did[imp->ianacode] = 1;
13657 }
13658 }
13659 }
13660 }
13661 } else if (m->m_proto == sdp_proto_msrp) {
13662 switch_channel_set_flag(channel, CF_WANT_MSRP);
13663 } else if (m->m_proto == sdp_proto_msrps) {
13664 switch_channel_set_flag(channel, CF_WANT_MSRPS);
13665 } else if (m->m_type == sdp_media_text) {
13666 switch_channel_set_flag(channel, CF_WANT_RTT);
13667 }
13668 }
13669
13670 if (buf[0] == ',') {
13671 switch_channel_set_variable(channel, "ep_codec_string", buf + 1);
13672 }
13673 }
13674
13675 //?
switch_core_media_codec_chosen(switch_core_session_t * session,switch_media_type_t type)13676 SWITCH_DECLARE(switch_status_t) switch_core_media_codec_chosen(switch_core_session_t *session, switch_media_type_t type)
13677 {
13678 switch_rtp_engine_t *engine;
13679 switch_media_handle_t *smh;
13680
13681 switch_assert(session);
13682
13683 if (!(smh = session->media_handle)) {
13684 return SWITCH_STATUS_FALSE;
13685 }
13686
13687 engine = &smh->engines[type];
13688
13689 if (engine->cur_payload_map->iananame) {
13690 return SWITCH_STATUS_SUCCESS;
13691 }
13692
13693 return SWITCH_STATUS_FALSE;
13694 }
13695
switch_core_session_stop_media(switch_core_session_t * session)13696 SWITCH_DECLARE(void) switch_core_session_stop_media(switch_core_session_t *session)
13697 {
13698 switch_rtp_engine_t *a_engine, *v_engine, *t_engine;
13699 switch_media_handle_t *smh;
13700 int type;
13701
13702 switch_assert(session);
13703
13704 if (!(smh = session->media_handle)) {
13705 return;
13706 }
13707
13708 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
13709 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
13710 t_engine = &smh->engines[SWITCH_MEDIA_TYPE_TEXT];
13711
13712 if (switch_core_codec_ready(&v_engine->read_codec)) {
13713 type = 1;
13714 switch_core_codec_control(&v_engine->read_codec, SCC_VIDEO_RESET, SCCT_INT, (void *)&type, SCCT_NONE, NULL, NULL, NULL);
13715 }
13716
13717 if (switch_core_codec_ready(&v_engine->write_codec)) {
13718 type = 2;
13719 switch_core_codec_control(&v_engine->write_codec, SCC_VIDEO_RESET, SCCT_INT, (void *)&type, SCCT_NONE, NULL, NULL, NULL);
13720 }
13721
13722 if (a_engine->rtp_session) {
13723 switch_rtp_reset(a_engine->rtp_session);
13724 }
13725
13726 if (v_engine->rtp_session) {
13727 switch_rtp_reset(v_engine->rtp_session);
13728 }
13729
13730 if (t_engine->rtp_session) {
13731 switch_rtp_reset(t_engine->rtp_session);
13732 }
13733
13734
13735 smh->msid = NULL;
13736 smh->cname = NULL;
13737 v_engine->ice_out.ufrag = NULL;
13738 v_engine->ice_out.pwd = NULL;
13739 v_engine->ice_out.cands[0][0].foundation = NULL;
13740 v_engine->ice_out.cands[0][0].component_id = 0;
13741
13742 t_engine->ice_out.ufrag = NULL;
13743 t_engine->ice_out.pwd = NULL;
13744 t_engine->ice_out.cands[0][0].foundation = NULL;
13745 t_engine->ice_out.cands[0][0].component_id = 0;
13746
13747
13748 a_engine->ice_out.ufrag = NULL;
13749 a_engine->ice_out.pwd = NULL;
13750 a_engine->ice_out.cands[0][0].foundation = NULL;
13751 a_engine->ice_out.cands[0][0].component_id = 0;
13752
13753 if (v_engine->ice_in.cands[v_engine->ice_in.chosen[0]][0].ready) {
13754 gen_ice(smh->session, SWITCH_MEDIA_TYPE_VIDEO, NULL, 0);
13755 }
13756
13757 if (t_engine->ice_in.cands[t_engine->ice_in.chosen[0]][0].ready) {
13758 gen_ice(smh->session, SWITCH_MEDIA_TYPE_TEXT, NULL, 0);
13759 }
13760
13761 if (a_engine->ice_in.cands[a_engine->ice_in.chosen[0]][0].ready) {
13762 gen_ice(smh->session, SWITCH_MEDIA_TYPE_AUDIO, NULL, 0);
13763 }
13764
13765 smh->owner_id = 0;
13766 smh->session_id = 0;
13767
13768 a_engine->local_dtls_fingerprint.len = 0;
13769 v_engine->local_dtls_fingerprint.len = 0;
13770 t_engine->local_dtls_fingerprint.len = 0;
13771
13772 a_engine->remote_ssrc = 0;
13773 v_engine->remote_ssrc = 0;
13774 t_engine->remote_ssrc = 0;
13775
13776 switch_channel_clear_flag(smh->session->channel, CF_VIDEO_READY);
13777 switch_core_session_wake_video_thread(smh->session);
13778 switch_core_session_request_video_refresh(smh->session);
13779 }
13780
13781
13782
13783 //?
switch_core_media_check_outgoing_proxy(switch_core_session_t * session,switch_core_session_t * o_session)13784 SWITCH_DECLARE(void) switch_core_media_check_outgoing_proxy(switch_core_session_t *session, switch_core_session_t *o_session)
13785 {
13786 switch_rtp_engine_t *a_engine, *v_engine, *t_engine;
13787 switch_media_handle_t *smh;
13788 const char *r_sdp = NULL;
13789 payload_map_t *pmap;
13790
13791 switch_assert(session);
13792
13793 if (!switch_channel_test_flag(o_session->channel, CF_PROXY_MEDIA)) {
13794 return;
13795 }
13796
13797 if (!(smh = session->media_handle)) {
13798 return;
13799 }
13800
13801 r_sdp = switch_channel_get_variable(o_session->channel, SWITCH_R_SDP_VARIABLE);
13802
13803 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
13804 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
13805 t_engine = &smh->engines[SWITCH_MEDIA_TYPE_TEXT];
13806
13807 switch_channel_set_flag(session->channel, CF_PROXY_MEDIA);
13808
13809 clear_pmaps(a_engine);
13810 clear_pmaps(v_engine);
13811
13812 pmap = switch_core_media_add_payload_map(session,
13813 SWITCH_MEDIA_TYPE_AUDIO,
13814 "PROXY",
13815 NULL,
13816 NULL,
13817 SDP_TYPE_RESPONSE,
13818 0,
13819 8000,
13820 20,
13821 1,
13822 SWITCH_TRUE);
13823
13824 a_engine->cur_payload_map = pmap;
13825
13826 if (switch_stristr("m=video", r_sdp)) {
13827 switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_VIDEO, 1);
13828 pmap = switch_core_media_add_payload_map(session,
13829 SWITCH_MEDIA_TYPE_AUDIO,
13830 "PROXY-VID",
13831 NULL,
13832 NULL,
13833 SDP_TYPE_RESPONSE,
13834 0,
13835 90000,
13836 90000,
13837 1,
13838 SWITCH_TRUE);
13839
13840 v_engine->cur_payload_map = pmap;
13841
13842 switch_channel_set_flag(session->channel, CF_VIDEO);
13843 switch_channel_set_flag(session->channel, CF_VIDEO_POSSIBLE);
13844 }
13845
13846
13847 if (switch_stristr("m=text", r_sdp)) {
13848 switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_VIDEO, 1);
13849 pmap = switch_core_media_add_payload_map(session,
13850 SWITCH_MEDIA_TYPE_AUDIO,
13851 "PROXY-TXT",
13852 NULL,
13853 NULL,
13854 SDP_TYPE_RESPONSE,
13855 0,
13856 1000,
13857 1000,
13858 1,
13859 SWITCH_TRUE);
13860
13861 t_engine->cur_payload_map = pmap;
13862
13863 switch_channel_set_flag(session->channel, CF_HAS_TEXT);
13864 switch_channel_set_flag(session->channel, CF_TEXT_POSSIBLE);
13865 }
13866 }
13867
13868
switch_core_media_recover_session(switch_core_session_t * session)13869 SWITCH_DECLARE (void) switch_core_media_recover_session(switch_core_session_t *session)
13870 {
13871 const char *ip;
13872 const char *port;
13873 const char *a_ip;
13874 const char *r_ip;
13875 const char *r_port;
13876 const char *tmp;
13877 switch_rtp_engine_t *a_engine, *v_engine;
13878 switch_media_handle_t *smh;
13879
13880 switch_assert(session);
13881
13882 if (!(smh = session->media_handle)) {
13883 return;
13884 }
13885
13886 ip = switch_channel_get_variable(session->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE);
13887 port = switch_channel_get_variable(session->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE);
13888
13889 if (switch_channel_test_flag(session->channel, CF_PROXY_MODE) || !(ip && port)) {
13890 return;
13891 } else {
13892 a_ip = switch_channel_get_variable(session->channel, SWITCH_ADVERTISED_MEDIA_IP_VARIABLE);
13893 r_ip = switch_channel_get_variable(session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE);
13894 r_port = switch_channel_get_variable(session->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE);
13895 }
13896
13897 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
13898 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
13899
13900 a_engine->cur_payload_map->iananame = a_engine->cur_payload_map->rm_encoding = (char *) switch_channel_get_variable(session->channel, "rtp_use_codec_name");
13901 a_engine->cur_payload_map->rm_fmtp = (char *) switch_channel_get_variable(session->channel, "rtp_use_codec_fmtp");
13902
13903 if ((tmp = switch_channel_get_variable(session->channel, SWITCH_R_SDP_VARIABLE))) {
13904 smh->mparams->remote_sdp_str = switch_core_session_strdup(session, tmp);
13905 }
13906
13907 if ((tmp = switch_channel_get_variable(session->channel, "rtp_use_timer_name"))) {
13908 smh->mparams->timer_name = switch_core_session_strdup(session, tmp);
13909 }
13910
13911 if ((tmp = switch_channel_get_variable(session->channel, "rtp_last_audio_codec_string"))) {
13912 const char *vtmp = switch_channel_get_variable(session->channel, "rtp_last_video_codec_string");
13913 switch_channel_set_variable_printf(session->channel, "rtp_use_codec_string", "%s%s%s", tmp, vtmp ? "," : "", vtmp ? vtmp : "");
13914 }
13915
13916 if ((tmp = switch_channel_get_variable(session->channel, "rtp_use_codec_string"))) {
13917 char *tmp_codec_string = switch_core_session_strdup(smh->session, tmp);
13918 smh->codec_order_last = switch_separate_string(tmp_codec_string, ',', smh->codec_order, SWITCH_MAX_CODECS);
13919 smh->mparams->num_codecs = switch_loadable_module_get_codecs_sorted(smh->codecs, smh->fmtp, SWITCH_MAX_CODECS, smh->codec_order, smh->codec_order_last);
13920 }
13921
13922 if ((tmp = switch_channel_get_variable(session->channel, "rtp_2833_send_payload"))) {
13923 smh->mparams->te = (switch_payload_t)atoi(tmp);
13924 }
13925
13926 if ((tmp = switch_channel_get_variable(session->channel, "rtp_2833_recv_payload"))) {
13927 smh->mparams->recv_te = (switch_payload_t)atoi(tmp);
13928 }
13929
13930 if ((tmp = switch_channel_get_variable(session->channel, "rtp_use_codec_rate"))) {
13931 a_engine->cur_payload_map->rm_rate = atoi(tmp);
13932 a_engine->cur_payload_map->adv_rm_rate = a_engine->cur_payload_map->rm_rate;
13933 }
13934
13935 if ((tmp = switch_channel_get_variable(session->channel, "rtp_use_codec_ptime"))) {
13936 a_engine->cur_payload_map->codec_ms = atoi(tmp);
13937 }
13938
13939 if ((tmp = switch_channel_get_variable(session->channel, "rtp_use_codec_channels"))) {
13940 a_engine->cur_payload_map->channels = atoi(tmp);
13941 }
13942
13943 if ((tmp = switch_channel_get_variable(session->channel, "rtp_use_pt"))) {
13944 a_engine->cur_payload_map->pt = (switch_payload_t)(smh->payload_space = atoi(tmp));
13945 }
13946
13947 if ((tmp = switch_channel_get_variable(session->channel, "rtp_audio_recv_pt"))) {
13948 a_engine->cur_payload_map->recv_pt = (switch_payload_t)atoi(tmp);
13949 }
13950
13951 switch_core_media_set_codec(session, 0, smh->mparams->codec_flags);
13952
13953 a_engine->adv_sdp_ip = smh->mparams->extrtpip = (char *) ip;
13954 a_engine->adv_sdp_port = a_engine->local_sdp_port = (switch_port_t)atoi(port);
13955 a_engine->codec_negotiated = 1;
13956
13957 if (!zstr(ip)) {
13958 a_engine->local_sdp_ip = switch_core_session_strdup(session, ip);
13959 smh->mparams->rtpip = a_engine->local_sdp_ip;
13960 }
13961
13962 if (!zstr(a_ip)) {
13963 a_engine->adv_sdp_ip = switch_core_session_strdup(session, a_ip);
13964 }
13965
13966 if (r_ip && r_port) {
13967 a_engine->cur_payload_map->remote_sdp_ip = (char *) r_ip;
13968 a_engine->cur_payload_map->remote_sdp_port = (switch_port_t)atoi(r_port);
13969 }
13970
13971 if (switch_channel_test_flag(session->channel, CF_VIDEO)) {
13972 if ((tmp = switch_channel_get_variable(session->channel, "rtp_use_video_pt"))) {
13973 v_engine->cur_payload_map->pt = (switch_payload_t)atoi(tmp);
13974 }
13975
13976 if ((tmp = switch_channel_get_variable(session->channel, "rtp_video_recv_pt"))) {
13977 v_engine->cur_payload_map->recv_pt = (switch_payload_t)atoi(tmp);
13978 }
13979
13980 v_engine->cur_payload_map->rm_encoding = (char *) switch_channel_get_variable(session->channel, "rtp_use_video_codec_name");
13981 v_engine->cur_payload_map->rm_fmtp = (char *) switch_channel_get_variable(session->channel, "rtp_use_video_codec_fmtp");
13982 v_engine->codec_negotiated = 1;
13983
13984 port = switch_channel_get_variable(session->channel, SWITCH_LOCAL_VIDEO_PORT_VARIABLE);
13985 r_ip = switch_channel_get_variable(session->channel, SWITCH_REMOTE_VIDEO_IP_VARIABLE);
13986 r_port = switch_channel_get_variable(session->channel, SWITCH_REMOTE_VIDEO_PORT_VARIABLE);
13987
13988 switch_channel_set_flag(session->channel, CF_VIDEO_POSSIBLE);
13989
13990 if ((tmp = switch_channel_get_variable(session->channel, "rtp_use_video_codec_rate"))) {
13991 v_engine->cur_payload_map->rm_rate = atoi(tmp);
13992 v_engine->cur_payload_map->adv_rm_rate = v_engine->cur_payload_map->rm_rate;
13993 }
13994
13995 if ((tmp = switch_channel_get_variable(session->channel, "rtp_use_video_codec_ptime"))) {
13996 v_engine->cur_payload_map->codec_ms = atoi(tmp);
13997 }
13998
13999 v_engine->adv_sdp_port = v_engine->local_sdp_port = (switch_port_t)atoi(port);
14000 v_engine->local_sdp_ip = smh->mparams->rtpip;
14001
14002 if (r_ip && r_port) {
14003 v_engine->cur_payload_map->remote_sdp_ip = (char *) r_ip;
14004 v_engine->cur_payload_map->remote_sdp_port = (switch_port_t)atoi(r_port);
14005 }
14006 }
14007
14008 switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 1);
14009 switch_core_media_set_video_codec(session, 1);
14010
14011 if (switch_core_media_activate_rtp(session) != SWITCH_STATUS_SUCCESS) {
14012 return;
14013 }
14014
14015 switch_core_session_get_recovery_crypto_key(session, SWITCH_MEDIA_TYPE_AUDIO);
14016 switch_core_session_get_recovery_crypto_key(session, SWITCH_MEDIA_TYPE_VIDEO);
14017
14018
14019 if ((tmp = switch_channel_get_variable(session->channel, "rtp_last_audio_local_crypto_key")) && a_engine->ssec[a_engine->crypto_type].remote_crypto_key) {
14020 int idx = atoi(tmp);
14021
14022 a_engine->ssec[a_engine->crypto_type].local_crypto_key = switch_core_session_strdup(session, tmp);
14023 switch_core_media_add_crypto(session, &a_engine->ssec[a_engine->crypto_type],SWITCH_RTP_CRYPTO_SEND);
14024 switch_core_media_add_crypto(session, &a_engine->ssec[a_engine->crypto_type],SWITCH_RTP_CRYPTO_RECV);
14025 switch_channel_set_flag(smh->session->channel, CF_SECURE);
14026
14027 switch_rtp_add_crypto_key(a_engine->rtp_session, SWITCH_RTP_CRYPTO_SEND, idx, &a_engine->ssec[a_engine->crypto_type]);
14028
14029 switch_rtp_add_crypto_key(a_engine->rtp_session, SWITCH_RTP_CRYPTO_RECV, a_engine->ssec[a_engine->crypto_type].crypto_tag, &a_engine->ssec[a_engine->crypto_type]);
14030 }
14031
14032
14033 if (switch_core_media_ready(session, SWITCH_MEDIA_TYPE_AUDIO)) {
14034 switch_rtp_set_telephony_event(a_engine->rtp_session, smh->mparams->te);
14035 switch_rtp_set_telephony_recv_event(a_engine->rtp_session, smh->mparams->recv_te);
14036 }
14037
14038 }
14039
14040
switch_core_media_init(void)14041 SWITCH_DECLARE(void) switch_core_media_init(void)
14042 {
14043 switch_core_gen_certs(DTLS_SRTP_FNAME ".pem");
14044
14045 video_globals.cpu_count = switch_core_cpu_count();
14046 video_globals.cur_cpu = 0;
14047
14048 switch_core_new_memory_pool(&video_globals.pool);
14049 switch_mutex_init(&video_globals.mutex, SWITCH_MUTEX_NESTED, video_globals.pool);
14050
14051 }
14052
switch_core_media_deinit(void)14053 SWITCH_DECLARE(void) switch_core_media_deinit(void)
14054 {
14055 if (video_globals.pool) {
14056 switch_core_destroy_memory_pool(&video_globals.pool);
14057 }
14058 }
14059
payload_number(const char * name)14060 static int payload_number(const char *name)
14061 {
14062 if (!strcasecmp(name, "pcmu")) {
14063 return 0;
14064 }
14065
14066 if (!strcasecmp(name, "pcma")) {
14067 return 8;
14068 }
14069
14070 if (!strcasecmp(name, "gsm")) {
14071 return 3;
14072 }
14073
14074 if (!strcasecmp(name, "g722")) {
14075 return 9;
14076 }
14077
14078 if (!strcasecmp(name, "g729")) {
14079 return 18;
14080 }
14081
14082 if (!strcasecmp(name, "dvi4")) {
14083 return 5;
14084 }
14085
14086 if (!strcasecmp(name, "h261")) {
14087 return 31;
14088 }
14089
14090 if (!strcasecmp(name, "h263")) {
14091 return 34;
14092 }
14093
14094 return -1;
14095 }
14096
find_pt(const char * sdp,const char * name)14097 static int find_pt(const char *sdp, const char *name)
14098 {
14099 const char *p;
14100
14101 if ((p = switch_stristr(name, sdp))) {
14102 if (p < end_of_p(sdp) && *(p+strlen(name)) == '/' && *(p-1) == ' ') {
14103 p -= 2;
14104
14105 while(*p > 47 && *p < 58) {
14106 p--;
14107 }
14108 p++;
14109
14110 if (p) {
14111 return atoi(p);
14112 }
14113 }
14114 }
14115
14116 return -1;
14117 }
14118
14119
switch_core_media_filter_sdp(const char * sdp_str,const char * cmd,const char * arg)14120 SWITCH_DECLARE(char *) switch_core_media_filter_sdp(const char *sdp_str, const char *cmd, const char *arg)
14121 {
14122 char *new_sdp = NULL;
14123 int pt = -1, te = -1;
14124 switch_size_t len;
14125 const char *i;
14126 char *o;
14127 int in_m = 0, m_tally = 0, slash = 0;
14128 int number = 0, skip = 0;
14129 int remove = !strcasecmp(cmd, "remove");
14130 int only = !strcasecmp(cmd, "only");
14131 char *end = end_of_p((char *)sdp_str);
14132 int tst;
14133 end++;
14134
14135
14136 if (remove || only) {
14137 pt = payload_number(arg);
14138
14139 if (pt < 0) {
14140 pt = find_pt(sdp_str, arg);
14141 }
14142 } else {
14143 return NULL;
14144 }
14145
14146 if (only) {
14147 te = find_pt(sdp_str, "telephone-event");
14148 }
14149
14150
14151 len = strlen(sdp_str) + 2;
14152 new_sdp = malloc(len);
14153 o = new_sdp;
14154 i = sdp_str;
14155
14156
14157 while(i && *i && i < end) {
14158
14159 if (*i == 'm' && *(i+1) == '=') {
14160 in_m = 1;
14161 m_tally++;
14162 }
14163
14164 if (in_m) {
14165 if (*i == '\r' || *i == '\n') {
14166 in_m = 0;
14167 slash = 0;
14168 } else {
14169 if (*i == '/') {
14170 slash++;
14171 while(*i != ' ' && i < end) {
14172 *o++ = *i++;
14173 }
14174
14175 *o++ = *i++;
14176 }
14177
14178 if (slash && switch_is_leading_number(i)) {
14179
14180
14181 number = atoi(i);
14182
14183 while(i < end && ((*i > 47 && *i < 58) || *i == ' ')) {
14184
14185 if (remove) {
14186 tst = (number != pt);
14187 } else {
14188 tst = (number == pt || number == te);
14189 }
14190
14191 if (tst) {
14192 *o++ = *i;
14193 }
14194 i++;
14195
14196 if (*i == ' ') {
14197 break;
14198 }
14199
14200 }
14201
14202 if (remove) {
14203 tst = (number == pt);
14204 } else {
14205 tst = (number != pt && number != te);
14206 }
14207
14208 if (tst) {
14209 skip++;
14210 }
14211 }
14212 }
14213 }
14214
14215 while (i < end && !strncasecmp(i, "a=rtpmap:", 9)) {
14216 const char *t = i + 9;
14217
14218 number = atoi(t);
14219
14220 if (remove) {
14221 tst = (number == pt);
14222 } else {
14223 tst = (number != pt && number != te);
14224 }
14225
14226 while(i < end && (*i != '\r' && *i != '\n')) {
14227 if (!tst) *o++ = *i;
14228 i++;
14229 }
14230
14231 while(i < end && (*i == '\r' || *i == '\n')) {
14232 if (!tst) *o++ = *i;
14233 i++;
14234 }
14235 }
14236
14237 while (i < end && !strncasecmp(i, "a=fmtp:", 7)) {
14238 const char *t = i + 7;
14239
14240 number = atoi(t);
14241
14242 if (remove) {
14243 tst = (number == pt);
14244 } else {
14245 tst = (number != pt && number != te);
14246 }
14247
14248 while(i < end && (*i != '\r' && *i != '\n')) {
14249 if (!tst) *o++ = *i;
14250 i++;
14251 }
14252
14253 while(i < end && (*i == '\r' || *i == '\n')) {
14254 if (!tst) *o++ = *i;
14255 i++;
14256 }
14257 }
14258
14259 if (!skip) {
14260 *o++ = *i;
14261 }
14262
14263 skip = 0;
14264
14265 i++;
14266 }
14267
14268 *o = '\0';
14269
14270 return new_sdp;
14271 }
14272
switch_core_media_process_sdp_filter(const char * sdp,const char * cmd_buf,switch_core_session_t * session)14273 SWITCH_DECLARE(char *) switch_core_media_process_sdp_filter(const char *sdp, const char *cmd_buf, switch_core_session_t *session)
14274 {
14275 switch_channel_t *channel = switch_core_session_get_channel(session);
14276 char *cmd = switch_core_session_strdup(session, cmd_buf);
14277 int argc = 0;
14278 char *argv[50];
14279 int x = 0;
14280 char *patched_sdp = NULL;
14281
14282 argc = switch_split(cmd, '|', argv);
14283
14284 for (x = 0; x < argc; x++) {
14285 char *command = argv[x];
14286 char *arg = strchr(command, '(');
14287
14288 if (arg) {
14289 char *e = switch_find_end_paren(arg, '(', ')');
14290 *arg++ = '\0';
14291 if (e) *e = '\0';
14292 }
14293
14294 if (zstr(command) || zstr(arg)) {
14295 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_WARNING, "%s SDP FILTER PARSE ERROR\n", switch_channel_get_name(channel));
14296 } else {
14297 char *tmp_sdp = NULL;
14298
14299 if (patched_sdp) {
14300 tmp_sdp = switch_core_media_filter_sdp(patched_sdp, command, arg);
14301 } else {
14302 tmp_sdp = switch_core_media_filter_sdp(sdp, command, arg);
14303 }
14304
14305
14306 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG,
14307 "%s Filter command %s(%s)\nFROM:\n==========\n%s\nTO:\n==========\n%s\n\n",
14308 switch_channel_get_name(channel),
14309 command, arg, patched_sdp ? patched_sdp : sdp, tmp_sdp);
14310
14311
14312 if (tmp_sdp) {
14313 switch_safe_free(patched_sdp);
14314 patched_sdp = tmp_sdp;
14315 }
14316 }
14317 }
14318
14319 return patched_sdp;
14320
14321 }
14322
14323
switch_core_media_get_timer(switch_core_session_t * session,switch_media_type_t mtype)14324 SWITCH_DECLARE(switch_timer_t *) switch_core_media_get_timer(switch_core_session_t *session, switch_media_type_t mtype)
14325 {
14326 switch_rtp_engine_t *engine = NULL;
14327 switch_media_handle_t *smh = NULL;
14328
14329 switch_assert(session);
14330
14331 if (!(smh = session->media_handle)) {
14332 return NULL;
14333 }
14334
14335 if (!(engine = &smh->engines[mtype])) {
14336 return NULL;
14337 }
14338
14339 return switch_rtp_get_media_timer(engine->rtp_session);
14340
14341 }
14342
_switch_core_session_request_video_refresh(switch_core_session_t * session,int force,const char * file,const char * func,int line)14343 SWITCH_DECLARE(switch_status_t) _switch_core_session_request_video_refresh(switch_core_session_t *session, int force, const char *file, const char *func, int line)
14344 {
14345 switch_channel_t *channel = switch_core_session_get_channel(session);
14346 switch_media_handle_t *smh = NULL;
14347
14348 switch_assert(session);
14349
14350 if (!(smh = session->media_handle)) {
14351 return SWITCH_STATUS_FALSE;
14352 }
14353
14354 if (switch_channel_media_up(channel) && switch_channel_test_flag(channel, CF_VIDEO)) {
14355 switch_core_session_message_t msg = { 0 };
14356 switch_time_t now = switch_micro_time_now();
14357
14358 if (!force && (smh->last_video_refresh_req && (now - smh->last_video_refresh_req) < VIDEO_REFRESH_FREQ)) {
14359 return SWITCH_STATUS_BREAK;
14360 }
14361
14362 smh->last_video_refresh_req = now;
14363
14364 if (force) {
14365 msg.numeric_arg = 1;
14366 }
14367
14368 msg._file = file;
14369 msg._func = func;
14370 msg._line = line;
14371 switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_core_session_get_uuid(session),
14372 SWITCH_LOG_DEBUG1, "%s Video refresh requested.\n", switch_channel_get_name(session->channel));
14373 msg.from = __FILE__;
14374 msg.message_id = SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ;
14375 switch_core_session_receive_message(session, &msg);
14376 return SWITCH_STATUS_SUCCESS;
14377 }
14378
14379 return SWITCH_STATUS_FALSE;
14380 }
14381
switch_core_session_send_and_request_video_refresh(switch_core_session_t * session)14382 SWITCH_DECLARE(switch_status_t) switch_core_session_send_and_request_video_refresh(switch_core_session_t *session)
14383 {
14384 if (switch_channel_test_flag(session->channel, CF_VIDEO)) {
14385 switch_core_session_request_video_refresh(session);
14386 switch_core_media_gen_key_frame(session);
14387 return SWITCH_STATUS_SUCCESS;
14388 }
14389
14390 return SWITCH_STATUS_FALSE;
14391 }
14392
14393
switch_core_media_codec_control(switch_core_session_t * session,switch_media_type_t mtype,switch_io_type_t iotype,switch_codec_control_command_t cmd,switch_codec_control_type_t ctype,void * cmd_data,switch_codec_control_type_t atype,void * cmd_arg,switch_codec_control_type_t * rtype,void ** ret_data)14394 SWITCH_DECLARE(switch_status_t) switch_core_media_codec_control(switch_core_session_t *session,
14395 switch_media_type_t mtype,
14396 switch_io_type_t iotype,
14397 switch_codec_control_command_t cmd,
14398 switch_codec_control_type_t ctype,
14399 void *cmd_data,
14400 switch_codec_control_type_t atype,
14401 void *cmd_arg,
14402 switch_codec_control_type_t *rtype,
14403 void **ret_data)
14404 {
14405 switch_rtp_engine_t *engine = NULL;
14406 switch_media_handle_t *smh = NULL;
14407 switch_codec_t *codec = NULL;
14408
14409 switch_assert(session);
14410
14411 if (!(smh = session->media_handle)) {
14412 return SWITCH_STATUS_FALSE;
14413 }
14414
14415 if (!(engine = &smh->engines[mtype])) {
14416 return SWITCH_STATUS_NOTIMPL;
14417 }
14418
14419 if (iotype == SWITCH_IO_READ) {
14420 codec = &engine->read_codec;
14421 } else {
14422 codec = &engine->write_codec;
14423 }
14424
14425 if (!switch_core_codec_ready(codec)) {
14426 return SWITCH_STATUS_FALSE;
14427 }
14428
14429 if (mtype == SWITCH_MEDIA_TYPE_VIDEO) {
14430 if (!switch_channel_test_flag(session->channel, CF_VIDEO)) {
14431 return SWITCH_STATUS_FALSE;
14432 }
14433 }
14434
14435 if (codec) {
14436 return switch_core_codec_control(codec, cmd, ctype, cmd_data, atype, cmd_arg, rtype, ret_data);
14437 }
14438
14439 return SWITCH_STATUS_FALSE;
14440 }
14441
switch_core_media_codec_get_cap(switch_core_session_t * session,switch_media_type_t mtype,switch_codec_flag_t flag)14442 SWITCH_DECLARE(switch_bool_t) switch_core_media_codec_get_cap(switch_core_session_t *session,
14443 switch_media_type_t mtype,
14444 switch_codec_flag_t flag) {
14445 switch_rtp_engine_t *engine = NULL;
14446 switch_media_handle_t *smh = NULL;
14447 switch_codec_t *codec = NULL;
14448
14449 switch_assert(session);
14450
14451 if (!(smh = session->media_handle)) {
14452 return SWITCH_FALSE;
14453 }
14454
14455 if (!(engine = &smh->engines[mtype])) {
14456 return SWITCH_FALSE;
14457 }
14458
14459 codec = &engine->write_codec;
14460
14461 if (!switch_core_codec_ready(codec)) {
14462 return SWITCH_FALSE;
14463 }
14464
14465 if (switch_test_flag(codec, flag)){
14466 return SWITCH_TRUE;
14467 }
14468
14469 return SWITCH_FALSE;
14470 }
14471
switch_core_session_write_encoded_video_frame(switch_core_session_t * session,switch_frame_t * frame,switch_io_flag_t flags,int stream_id)14472 SWITCH_DECLARE(switch_status_t) switch_core_session_write_encoded_video_frame(switch_core_session_t *session,
14473 switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
14474 {
14475 switch_io_event_hook_video_write_frame_t *ptr;
14476 switch_status_t status = SWITCH_STATUS_FALSE;
14477
14478 if (switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) {
14479 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG3, "Writing video to RECVONLY/INACTIVE session\n");
14480 return SWITCH_STATUS_SUCCESS;
14481 }
14482
14483 if (session->endpoint_interface->io_routines->write_video_frame) {
14484 if ((status = session->endpoint_interface->io_routines->write_video_frame(session, frame, flags, stream_id)) == SWITCH_STATUS_SUCCESS) {
14485 for (ptr = session->event_hooks.video_write_frame; ptr; ptr = ptr->next) {
14486 if ((status = ptr->video_write_frame(session, frame, flags, stream_id)) != SWITCH_STATUS_SUCCESS) {
14487 break;
14488 }
14489 }
14490 }
14491 }
14492
14493 return status;
14494 }
14495
switch_core_session_video_reinit(switch_core_session_t * session)14496 SWITCH_DECLARE(void) switch_core_session_video_reinit(switch_core_session_t *session)
14497 {
14498 switch_media_handle_t *smh;
14499 int type;
14500
14501 switch_assert(session);
14502
14503 if (!(smh = session->media_handle)) {
14504 return;
14505 }
14506
14507 if (switch_channel_down(session->channel)) {
14508 return;
14509 }
14510
14511 smh->video_init = 0;
14512 smh->video_last_key_time = 0;
14513 switch_core_session_send_and_request_video_refresh(session);
14514
14515 type = 1;
14516 switch_core_media_codec_control(session, SWITCH_MEDIA_TYPE_VIDEO, SWITCH_IO_READ, SCC_VIDEO_RESET, SCCT_INT, (void *)&type, SCCT_NONE, NULL, NULL, NULL);
14517 switch_core_session_request_video_refresh(session);
14518
14519 }
14520
switch_core_session_write_video_frame(switch_core_session_t * session,switch_frame_t * frame,switch_io_flag_t flags,int stream_id)14521 SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags,
14522 int stream_id)
14523 {
14524 switch_status_t status = SWITCH_STATUS_FALSE;
14525 switch_time_t now = switch_micro_time_now();
14526 switch_codec_t *codec = switch_core_session_get_video_write_codec(session);
14527 switch_timer_t *timer;
14528 switch_media_handle_t *smh;
14529 switch_image_t *dup_img = NULL, *img = frame->img;
14530 switch_status_t encode_status;
14531 switch_frame_t write_frame = {0};
14532 switch_rtp_engine_t *v_engine = NULL;
14533 switch_bool_t need_free = SWITCH_FALSE;
14534 switch_assert(session);
14535
14536 if (!(smh = session->media_handle)) {
14537 return SWITCH_STATUS_FALSE;
14538 }
14539
14540 if (switch_channel_down(session->channel)) {
14541 return SWITCH_STATUS_FALSE;
14542 }
14543
14544 if (!codec) {
14545 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s has no video codec\n", switch_core_session_get_name(session));
14546 return SWITCH_STATUS_FALSE;
14547 }
14548
14549
14550 if (switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) {
14551 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG3, "Writing video to RECVONLY/INACTIVE session\n");
14552 return SWITCH_STATUS_SUCCESS;
14553 }
14554
14555 if (switch_channel_test_flag(session->channel, CF_VIDEO_PAUSE_WRITE)) {
14556 return SWITCH_STATUS_SUCCESS;
14557 }
14558
14559 if (!(switch_channel_test_flag(session->channel, CF_VIDEO_READY) || (flags & SWITCH_IO_FLAG_FORCE))) {
14560 return SWITCH_STATUS_SUCCESS;
14561 }
14562
14563 if (smh->write_mutex[SWITCH_MEDIA_TYPE_VIDEO] && switch_mutex_trylock(smh->write_mutex[SWITCH_MEDIA_TYPE_VIDEO]) != SWITCH_STATUS_SUCCESS) {
14564 /* return CNG, another thread is already writing */
14565 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "%s is already being written to for %s\n",
14566 switch_channel_get_name(session->channel), type2str(SWITCH_MEDIA_TYPE_VIDEO));
14567 return SWITCH_STATUS_INUSE;
14568 }
14569
14570 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
14571 if (v_engine->thread_write_lock && v_engine->thread_write_lock != switch_thread_self()) {
14572 switch_goto_status(SWITCH_STATUS_SUCCESS, done);
14573 }
14574
14575 if (!smh->video_init && smh->mparams->video_key_first && (now - smh->video_last_key_time) > smh->mparams->video_key_first) {
14576 switch_core_media_gen_key_frame(session);
14577
14578 if (smh->video_last_key_time) {
14579 smh->video_init = 1;
14580 }
14581
14582 smh->video_last_key_time = now;
14583 }
14584
14585 if (smh->mparams->video_key_freq && (now - smh->video_last_key_time) > smh->mparams->video_key_freq) {
14586 switch_core_media_gen_key_frame(smh->session);
14587 smh->video_last_key_time = now;
14588 }
14589
14590 if (!img) {
14591 switch_status_t vstatus;
14592
14593 vstatus = switch_core_session_write_encoded_video_frame(session, frame, flags, stream_id);
14594 switch_goto_status(vstatus, done);
14595 }
14596
14597
14598 /* When desired, scale video to match the input signal (if output is bigger) */
14599 if (switch_channel_test_flag(session->channel, CF_VIDEO_READY) &&
14600 switch_channel_test_flag(session->channel, CF_VIDEO_MIRROR_INPUT)) {
14601 switch_vid_params_t vid_params = { 0 };
14602
14603 switch_core_media_get_vid_params(session, &vid_params);
14604
14605 if (vid_params.width && vid_params.height && ((vid_params.width != img->d_w) || (vid_params.height != img->d_h))) {
14606 switch_img_letterbox(img, &dup_img, vid_params.width, vid_params.height, "#000000f");
14607 if (!(img = dup_img)) {
14608 switch_goto_status(SWITCH_STATUS_INUSE, done);
14609 }
14610 }
14611 }
14612
14613 if (!switch_channel_test_flag(session->channel, CF_VIDEO_WRITING)) {
14614 smh->vid_params.d_width = img->d_w;
14615 smh->vid_params.d_height = img->d_h;
14616 }
14617
14618 if (session->bugs) {
14619 switch_media_bug_t *bp;
14620 int prune = 0;
14621 int patched = 0;
14622
14623 switch_thread_rwlock_rdlock(session->bug_rwlock);
14624 for (bp = session->bugs; bp; bp = bp->next) {
14625 switch_bool_t ok = SWITCH_TRUE;
14626
14627 if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) {
14628 continue;
14629 }
14630
14631 if (!switch_channel_test_flag(session->channel, CF_ANSWERED) && switch_core_media_bug_test_flag(bp, SMBF_ANSWER_REQ)) {
14632 continue;
14633 }
14634
14635 if (switch_test_flag(bp, SMBF_PRUNE)) {
14636 prune++;
14637 continue;
14638 }
14639
14640 if (bp->ready && switch_test_flag(bp, SMBF_WRITE_VIDEO_STREAM)) {
14641 switch_image_t *dimg = NULL;
14642
14643 switch_img_copy(img, &dimg);
14644 switch_queue_push(bp->write_video_queue, dimg);
14645
14646 if (switch_core_media_bug_test_flag(bp, SMBF_SPY_VIDEO_STREAM_BLEG)) {
14647 switch_core_media_bug_patch_spy_frame(bp, img, SWITCH_RW_WRITE);
14648 patched = 1;
14649 }
14650
14651 }
14652
14653 if (bp->ready && img &&
14654 (switch_test_flag(bp, SMBF_WRITE_VIDEO_PING) || (switch_core_media_bug_test_flag(bp, SMBF_SPY_VIDEO_STREAM) && !patched))) {
14655 switch_frame_t bug_frame = { 0 };
14656
14657 bug_frame.img = img;
14658
14659 if (bp->callback && switch_test_flag(bp, SMBF_WRITE_VIDEO_PING)) {
14660 bp->video_ping_frame = &bug_frame;
14661 if (bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_WRITE_VIDEO_PING) == SWITCH_FALSE
14662 || (bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL))) {
14663 ok = SWITCH_FALSE;
14664 }
14665 bp->video_ping_frame = NULL;
14666 }
14667
14668 if (bug_frame.img && bug_frame.img != img) {
14669 need_free = SWITCH_TRUE;
14670 img = bug_frame.img;
14671 }
14672
14673 if (switch_core_media_bug_test_flag(bp, SMBF_SPY_VIDEO_STREAM_BLEG) && !patched) {
14674 switch_core_media_bug_patch_spy_frame(bp, img, SWITCH_RW_WRITE);
14675 }
14676
14677
14678 }
14679
14680 if (ok == SWITCH_FALSE) {
14681 switch_set_flag(bp, SMBF_PRUNE);
14682 prune++;
14683 }
14684
14685 }
14686
14687 switch_thread_rwlock_unlock(session->bug_rwlock);
14688
14689 if (prune) {
14690 switch_core_media_bug_prune(session);
14691 }
14692
14693 }
14694
14695 write_frame = *frame;
14696 frame = &write_frame;
14697 frame->img = img;
14698
14699 if (!switch_test_flag(frame, SFF_USE_VIDEO_TIMESTAMP)) {
14700
14701 if (!(timer = switch_core_media_get_timer(session, SWITCH_MEDIA_TYPE_VIDEO))) {
14702
14703 if (!smh->video_timer.timer_interface) {
14704 switch_core_timer_init(&smh->video_timer, "soft", 1, 90, switch_core_session_get_pool(session));
14705 }
14706 switch_core_timer_sync(&smh->video_timer);
14707 timer = &smh->video_timer;
14708 }
14709
14710 frame->timestamp = timer->samplecount;
14711 }
14712
14713 switch_clear_flag(frame, SFF_SAME_IMAGE);
14714 frame->m = 0;
14715
14716 do {
14717 frame->datalen = SWITCH_DEFAULT_VIDEO_SIZE;
14718 encode_status = switch_core_codec_encode_video(codec, frame);
14719
14720 if (encode_status == SWITCH_STATUS_SUCCESS || encode_status == SWITCH_STATUS_MORE_DATA) {
14721
14722 switch_assert((encode_status == SWITCH_STATUS_SUCCESS && frame->m) || !frame->m);
14723
14724 if (frame->flags & SFF_PICTURE_RESET) {
14725 switch_core_session_video_reinit(session);
14726 frame->flags &= ~SFF_PICTURE_RESET;
14727 }
14728
14729 if (frame->datalen == 0) break;
14730
14731 switch_set_flag(frame, SFF_RAW_RTP_PARSE_FRAME);
14732 status = switch_core_session_write_encoded_video_frame(session, frame, flags, stream_id);
14733 }
14734
14735 } while(status == SWITCH_STATUS_SUCCESS && encode_status == SWITCH_STATUS_MORE_DATA);
14736
14737 done:
14738
14739 if (smh->write_mutex[SWITCH_MEDIA_TYPE_VIDEO]) {
14740 switch_mutex_unlock(smh->write_mutex[SWITCH_MEDIA_TYPE_VIDEO]);
14741 }
14742
14743 switch_img_free(&dup_img);
14744
14745 if (need_free) {
14746 switch_img_free(&frame->img);
14747 }
14748
14749 return status;
14750 }
14751
switch_core_session_wait_for_video_input_params(switch_core_session_t * session,uint32_t timeout_ms)14752 SWITCH_DECLARE(switch_status_t) switch_core_session_wait_for_video_input_params(switch_core_session_t *session, uint32_t timeout_ms)
14753 {
14754 switch_media_handle_t *smh;
14755 switch_codec_implementation_t read_impl = { 0 };
14756 switch_rtp_engine_t *v_engine = NULL;
14757
14758 switch_assert(session != NULL);
14759
14760 if (!(smh = session->media_handle)) {
14761 return SWITCH_STATUS_FALSE;
14762 }
14763
14764 if (!switch_channel_test_flag(session->channel, CF_VIDEO_DECODED_READ)) {
14765 return SWITCH_STATUS_GENERR;
14766 }
14767
14768 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
14769
14770 if (v_engine->smode == SWITCH_MEDIA_FLOW_SENDONLY) {
14771 return SWITCH_STATUS_NOTIMPL;
14772 }
14773
14774 switch_core_session_get_read_impl(session, &read_impl);
14775
14776 while(switch_channel_ready(session->channel) && timeout_ms > 0) {
14777 switch_frame_t *read_frame;
14778 switch_status_t status;
14779
14780 if (video_globals.synced &&
14781 switch_channel_test_flag(session->channel, CF_VIDEO_READY) && smh->vid_params.width && smh->vid_params.height && smh->vid_params.fps) {
14782 return SWITCH_STATUS_SUCCESS;
14783 }
14784
14785 switch_core_session_request_video_refresh(session);
14786 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
14787
14788 if (!SWITCH_READ_ACCEPTABLE(status)) {
14789 return SWITCH_STATUS_FALSE;
14790 }
14791
14792 timeout_ms -= (read_impl.microseconds_per_packet / 1000);
14793 }
14794
14795 return SWITCH_STATUS_TIMEOUT;
14796
14797 }
14798
switch_core_session_transcoding(switch_core_session_t * session_a,switch_core_session_t * session_b,switch_media_type_t type)14799 SWITCH_DECLARE(switch_bool_t) switch_core_session_transcoding(switch_core_session_t *session_a, switch_core_session_t *session_b, switch_media_type_t type)
14800 {
14801 switch_bool_t transcoding = SWITCH_FALSE;
14802
14803 switch(type) {
14804 case SWITCH_MEDIA_TYPE_AUDIO:
14805 {
14806 switch_codec_implementation_t read_impl_a = { 0 }, read_impl_b = { 0 };
14807
14808 switch_core_session_get_read_impl(session_a, &read_impl_a);
14809 switch_core_session_get_read_impl(session_b, &read_impl_b);
14810
14811 if (read_impl_a.impl_id && read_impl_b.impl_id) {
14812 transcoding = (read_impl_a.impl_id != read_impl_b.impl_id || read_impl_a.decoded_bytes_per_packet != read_impl_b.decoded_bytes_per_packet);
14813 }
14814 }
14815 break;
14816 case SWITCH_MEDIA_TYPE_VIDEO:
14817 transcoding = (switch_channel_test_flag(session_a->channel, CF_VIDEO_DECODED_READ) ||
14818 switch_channel_test_flag(session_b->channel, CF_VIDEO_DECODED_READ));
14819 break;
14820 default:
14821 break;
14822 }
14823
14824 return transcoding;
14825
14826 }
14827
switch_core_session_passthru(switch_core_session_t * session,switch_media_type_t type,switch_bool_t on)14828 SWITCH_DECLARE(void) switch_core_session_passthru(switch_core_session_t *session, switch_media_type_t type, switch_bool_t on)
14829 {
14830 switch_rtp_engine_t *engine;
14831
14832 if (!session->media_handle) return;
14833
14834 engine = &session->media_handle->engines[type];
14835
14836
14837 if (switch_rtp_ready(engine->rtp_session)) {
14838 char var[50] = "";
14839 switch_snprintf(var, sizeof(var), "disable_%s_jb_during_passthru", type2str(type));
14840
14841 if (switch_channel_var_true(session->channel, var)) {
14842 if (on) {
14843 switch_rtp_set_flag(engine->rtp_session, SWITCH_RTP_FLAG_PASSTHRU);
14844 } else {
14845 switch_rtp_clear_flag(engine->rtp_session, SWITCH_RTP_FLAG_PASSTHRU);
14846 }
14847 }
14848
14849 if (type == SWITCH_MEDIA_TYPE_VIDEO) {
14850 switch_core_session_request_video_refresh(session);
14851 if (!on) {
14852 switch_core_media_gen_key_frame(session);
14853 }
14854 }
14855
14856 }
14857
14858 }
14859
switch_core_session_read_video_frame(switch_core_session_t * session,switch_frame_t ** frame,switch_io_flag_t flags,int stream_id)14860 SWITCH_DECLARE(switch_status_t) switch_core_session_read_video_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags,
14861 int stream_id)
14862 {
14863 switch_status_t status = SWITCH_STATUS_FALSE;
14864 switch_io_event_hook_video_read_frame_t *ptr;
14865 uint32_t loops = 0;
14866 switch_media_handle_t *smh;
14867 int is_keyframe = 0;
14868
14869 switch_assert(session != NULL);
14870
14871 if (!(smh = session->media_handle)) {
14872 return SWITCH_STATUS_FALSE;
14873 }
14874
14875 top:
14876
14877 loops++;
14878
14879 if (switch_channel_down_nosig(session->channel)) {
14880 return SWITCH_STATUS_FALSE;
14881 }
14882
14883 if (session->endpoint_interface->io_routines->read_video_frame) {
14884 if ((status = session->endpoint_interface->io_routines->read_video_frame(session, frame, flags, stream_id)) == SWITCH_STATUS_SUCCESS) {
14885 for (ptr = session->event_hooks.video_read_frame; ptr; ptr = ptr->next) {
14886 if ((status = ptr->video_read_frame(session, frame, flags, stream_id)) != SWITCH_STATUS_SUCCESS) {
14887 break;
14888 }
14889 }
14890 }
14891 }
14892
14893 if (switch_channel_test_flag(session->channel, CF_VIDEO_PAUSE_READ)) {
14894 *frame = &runtime.dummy_cng_frame;
14895 switch_cond_next();
14896 return SWITCH_STATUS_SUCCESS;
14897 }
14898
14899 if (status == SWITCH_STATUS_INUSE) {
14900 *frame = &runtime.dummy_cng_frame;
14901 switch_cond_next();
14902 return SWITCH_STATUS_SUCCESS;
14903 }
14904
14905 if (status != SWITCH_STATUS_SUCCESS) {
14906 goto done;
14907 }
14908
14909 if (!(*frame)) {
14910 goto done;
14911 }
14912
14913 if (switch_channel_test_flag(session->channel, CF_VIDEO_DEBUG_READ)) {
14914 if (switch_test_flag((*frame), SFF_CNG)) {
14915 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "VIDEO: CNG\n");
14916 } else {
14917 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,
14918 "VIDEO: seq: %d ts: %u len: %4d %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x mark: %d\n",
14919 (*frame)->seq, (*frame)->timestamp, (*frame)->datalen,
14920 *((uint8_t *)(*frame)->data), *((uint8_t *)(*frame)->data + 1),
14921 *((uint8_t *)(*frame)->data + 2), *((uint8_t *)(*frame)->data + 3),
14922 *((uint8_t *)(*frame)->data + 4), *((uint8_t *)(*frame)->data + 5),
14923 *((uint8_t *)(*frame)->data + 6), *((uint8_t *)(*frame)->data + 7),
14924 *((uint8_t *)(*frame)->data + 8), *((uint8_t *)(*frame)->data + 9),
14925 *((uint8_t *)(*frame)->data + 10), (*frame)->m);
14926 }
14927 }
14928
14929
14930 if (switch_test_flag(*frame, SFF_CNG)) {
14931 status = SWITCH_STATUS_SUCCESS;
14932 goto done;
14933 }
14934
14935 if (switch_channel_test_flag(session->channel, CF_VIDEO_DECODED_READ) && (*frame)->img == NULL) {
14936 switch_status_t decode_status;
14937
14938 (*frame)->img = NULL;
14939
14940 decode_status = switch_core_codec_decode_video((*frame)->codec, *frame);
14941 if (switch_test_flag(*frame, SFF_IS_KEYFRAME)) {
14942 is_keyframe++;
14943 }
14944 if ((*frame)->img && switch_channel_test_flag(session->channel, CF_VIDEO_DEBUG_READ)) {
14945 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "IMAGE %dx%d %dx%d\n",
14946 (*frame)->img->w, (*frame)->img->h, (*frame)->img->d_w, (*frame)->img->d_h);
14947 }
14948
14949 if ((*frame)->img && (*frame)->img->d_w && (*frame)->img->d_h) {
14950 int new_w = 0, new_h = 0;
14951
14952 if ((*frame)->img->d_w != smh->vid_params.width || (*frame)->img->d_h != smh->vid_params.height) {
14953 new_w = (*frame)->img->d_w;
14954 new_h = (*frame)->img->d_h;
14955
14956 if (new_w && new_h) {
14957 switch_mutex_lock(smh->control_mutex);
14958 smh->vid_params.width = new_w;
14959 smh->vid_params.height = new_h;
14960 switch_channel_set_variable_printf(session->channel, "video_width", "%d", new_w);
14961 switch_channel_set_variable_printf(session->channel, "video_height", "%d", new_h);
14962 switch_mutex_unlock(smh->control_mutex);
14963 }
14964 }
14965 }
14966
14967 if (switch_test_flag((*frame), SFF_WAIT_KEY_FRAME)) {
14968 switch_core_session_request_video_refresh(session);
14969 switch_clear_flag((*frame), SFF_WAIT_KEY_FRAME);
14970
14971 if (!(*frame)->img) {
14972 *frame = &runtime.dummy_cng_frame;
14973 switch_cond_next();
14974 return SWITCH_STATUS_SUCCESS;
14975 }
14976 }
14977
14978 if (decode_status == SWITCH_STATUS_MORE_DATA || !(*frame)->img) {
14979 goto top;
14980 }
14981 }
14982
14983 if (!switch_channel_test_flag(session->channel, CF_VIDEO_READY) && *frame) {
14984 if (switch_channel_test_flag(session->channel, CF_VIDEO_DECODED_READ)) {
14985 if ((*frame)->img) {
14986 switch_channel_set_flag(session->channel, CF_VIDEO_READY);
14987 }
14988 } else if ((*frame)->m || ++smh->ready_loops > 5) {
14989 switch_channel_set_flag(session->channel, CF_VIDEO_READY);
14990 }
14991 }
14992
14993 done:
14994
14995 if (*frame && is_keyframe) {
14996 switch_set_flag(*frame, SFF_IS_KEYFRAME);
14997 }
14998
14999 if (session->bugs) {
15000 switch_media_bug_t *bp;
15001 int prune = 0;
15002 int patched = 0;
15003
15004 switch_thread_rwlock_rdlock(session->bug_rwlock);
15005 for (bp = session->bugs; bp; bp = bp->next) {
15006 switch_bool_t ok = SWITCH_TRUE;
15007
15008 if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) {
15009 continue;
15010 }
15011
15012 if (!switch_channel_test_flag(session->channel, CF_ANSWERED) && switch_core_media_bug_test_flag(bp, SMBF_ANSWER_REQ)) {
15013 continue;
15014 }
15015
15016 if (switch_test_flag(bp, SMBF_PRUNE)) {
15017 prune++;
15018 continue;
15019 }
15020
15021 if (bp->ready && switch_test_flag(bp, SMBF_READ_VIDEO_STREAM)) {
15022 if ((*frame) && (*frame)->img) {
15023 switch_image_t *img = NULL;
15024 switch_img_copy((*frame)->img, &img);
15025 switch_queue_push(bp->read_video_queue, img);
15026 if (switch_core_media_bug_test_flag(bp, SMBF_SPY_VIDEO_STREAM)) {
15027 switch_core_media_bug_patch_spy_frame(bp, (*frame)->img, SWITCH_RW_READ);
15028 patched = 1;
15029 }
15030 }
15031 }
15032
15033 if (bp->ready && (*frame) && (*frame)->img &&
15034 (switch_test_flag(bp, SMBF_READ_VIDEO_PING) || (switch_core_media_bug_test_flag(bp, SMBF_SPY_VIDEO_STREAM) && !patched))) {
15035
15036
15037 if (bp->callback && switch_test_flag(bp, SMBF_READ_VIDEO_PING)) {
15038 bp->video_ping_frame = *frame;
15039
15040 if (bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ_VIDEO_PING) == SWITCH_FALSE
15041 || (bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL))) {
15042 ok = SWITCH_FALSE;
15043 }
15044 bp->video_ping_frame = NULL;
15045 }
15046
15047 if (switch_core_media_bug_test_flag(bp, SMBF_SPY_VIDEO_STREAM) && !patched) {
15048 switch_core_media_bug_patch_spy_frame(bp, (*frame)->img, SWITCH_RW_READ);
15049 }
15050 }
15051
15052 if (ok == SWITCH_FALSE) {
15053 switch_set_flag(bp, SMBF_PRUNE);
15054 prune++;
15055 }
15056 }
15057
15058 switch_thread_rwlock_unlock(session->bug_rwlock);
15059
15060 if (prune) {
15061 switch_core_media_bug_prune(session);
15062 }
15063 }
15064
15065 if ((*frame) && (*frame)->codec) {
15066 (*frame)->pmap = NULL;
15067 }
15068
15069 if (status == SWITCH_STATUS_SUCCESS) {
15070 switch_core_session_video_read_callback(session, *frame);
15071 }
15072
15073 return status;
15074 }
15075
15076
switch_core_session_set_video_read_callback(switch_core_session_t * session,switch_core_video_thread_callback_func_t func,void * user_data)15077 SWITCH_DECLARE(switch_status_t) switch_core_session_set_video_read_callback(switch_core_session_t *session,
15078 switch_core_video_thread_callback_func_t func, void *user_data)
15079 {
15080 switch_status_t status = SWITCH_STATUS_SUCCESS;
15081 switch_media_handle_t *smh;
15082
15083 if (!(smh = session->media_handle)) {
15084 return SWITCH_STATUS_FALSE;
15085 }
15086
15087 switch_mutex_lock(smh->control_mutex);
15088 if (!func) {
15089 session->video_read_callback = NULL;
15090 session->video_read_user_data = NULL;
15091 } else if (session->video_read_callback) {
15092 status = SWITCH_STATUS_FALSE;
15093 } else {
15094 session->video_read_callback = func;
15095 session->video_read_user_data = user_data;
15096 }
15097
15098 switch_core_session_start_video_thread(session);
15099 switch_mutex_unlock(smh->control_mutex);
15100
15101 return status;
15102 }
15103
switch_core_session_video_read_callback(switch_core_session_t * session,switch_frame_t * frame)15104 SWITCH_DECLARE(switch_status_t) switch_core_session_video_read_callback(switch_core_session_t *session, switch_frame_t *frame)
15105 {
15106 switch_media_handle_t *smh;
15107 switch_status_t status = SWITCH_STATUS_CONTINUE;
15108
15109 if (!(smh = session->media_handle)) {
15110 return SWITCH_STATUS_FALSE;
15111 }
15112
15113 switch_mutex_lock(smh->control_mutex);
15114
15115 if (session->video_read_callback) {
15116 status = session->video_read_callback(session, frame, session->video_read_user_data);
15117 }
15118
15119 switch_mutex_unlock(smh->control_mutex);
15120
15121 return status;
15122 }
15123
15124
15125
switch_core_session_set_text_read_callback(switch_core_session_t * session,switch_core_text_thread_callback_func_t func,void * user_data)15126 SWITCH_DECLARE(switch_status_t) switch_core_session_set_text_read_callback(switch_core_session_t *session,
15127 switch_core_text_thread_callback_func_t func, void *user_data)
15128 {
15129 switch_status_t status = SWITCH_STATUS_SUCCESS;
15130 switch_media_handle_t *smh;
15131
15132 if (!(smh = session->media_handle)) {
15133 return SWITCH_STATUS_FALSE;
15134 }
15135
15136 switch_mutex_lock(smh->control_mutex);
15137 if (!func) {
15138 session->text_read_callback = NULL;
15139 session->text_read_user_data = NULL;
15140 } else if (session->text_read_callback) {
15141 status = SWITCH_STATUS_FALSE;
15142 } else {
15143 session->text_read_callback = func;
15144 session->text_read_user_data = user_data;
15145 }
15146
15147 switch_core_session_start_text_thread(session);
15148 switch_mutex_unlock(smh->control_mutex);
15149
15150 return status;
15151 }
15152
15153
15154
switch_core_session_text_read_callback(switch_core_session_t * session,switch_frame_t * frame)15155 SWITCH_DECLARE(switch_status_t) switch_core_session_text_read_callback(switch_core_session_t *session, switch_frame_t *frame)
15156 {
15157 switch_media_handle_t *smh;
15158 switch_status_t status = SWITCH_STATUS_CONTINUE;
15159
15160 if (!(smh = session->media_handle)) {
15161 return SWITCH_STATUS_FALSE;
15162 }
15163
15164 switch_mutex_lock(smh->control_mutex);
15165
15166 if (session->text_read_callback) {
15167 status = session->text_read_callback(session, frame, session->text_read_user_data);
15168 }
15169
15170 switch_mutex_unlock(smh->control_mutex);
15171
15172 return status;
15173 }
15174
15175
15176
switch_core_session_read_text_frame(switch_core_session_t * session,switch_frame_t ** frame,switch_io_flag_t flags,int stream_id)15177 SWITCH_DECLARE(switch_status_t) switch_core_session_read_text_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags,
15178 int stream_id)
15179 {
15180 switch_status_t status = SWITCH_STATUS_FALSE;
15181 switch_io_event_hook_text_read_frame_t *ptr;
15182 switch_media_handle_t *smh;
15183 switch_io_read_text_frame_t read_text_frame = NULL;
15184 switch_time_t now;
15185
15186 switch_assert(session != NULL);
15187
15188 if (!(smh = session->media_handle)) {
15189 return SWITCH_STATUS_FALSE;
15190 }
15191
15192 if (switch_channel_down_nosig(session->channel)) {
15193 return SWITCH_STATUS_FALSE;
15194 }
15195
15196 if (!(read_text_frame = session->endpoint_interface->io_routines->read_text_frame)) {
15197 if (session->io_override) {
15198 read_text_frame = session->io_override->read_text_frame;
15199 }
15200 }
15201
15202 if (read_text_frame) {
15203 if ((status = read_text_frame(session, frame, flags, stream_id)) == SWITCH_STATUS_SUCCESS) {
15204 for (ptr = session->event_hooks.text_read_frame; ptr; ptr = ptr->next) {
15205 if ((status = ptr->text_read_frame(session, frame, flags, stream_id)) != SWITCH_STATUS_SUCCESS) {
15206 break;
15207 }
15208 }
15209 }
15210 }
15211
15212 if (status == SWITCH_STATUS_INUSE) {
15213 *frame = &runtime.dummy_cng_frame;
15214 switch_cond_next();
15215 return SWITCH_STATUS_SUCCESS;
15216 }
15217
15218 if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
15219 goto done;
15220 }
15221
15222 if (!(*frame)) {
15223 goto done;
15224 }
15225
15226 now = switch_micro_time_now();
15227
15228 if (switch_test_flag((*frame), SFF_CNG)) {
15229 if (smh->last_text_frame && now - smh->last_text_frame > TEXT_PERIOD_TIMEOUT * 1000) {
15230 switch_channel_set_flag(session->channel, CF_TEXT_IDLE);
15231 switch_channel_clear_flag(session->channel, CF_TEXT_ACTIVE);
15232 smh->last_text_frame = 0;
15233 }
15234 } else {
15235 unsigned char *p = (*frame)->data;
15236
15237 smh->last_text_frame = now;
15238 switch_channel_set_flag(session->channel, CF_TEXT_ACTIVE);
15239 switch_channel_clear_flag(session->channel, CF_TEXT_IDLE);
15240
15241 while(p && *p) {
15242 if (*p == '\r' || *p == '\n') {
15243 switch_set_flag((*frame), SFF_TEXT_LINE_BREAK);
15244 break;
15245 }
15246
15247 if (*p == 0xE2 && *(p+1) == 0x80 && *(p+2) == 0xA8) {
15248 switch_set_flag((*frame), SFF_TEXT_LINE_BREAK);
15249 break;
15250 }
15251
15252 p++;
15253 }
15254 }
15255
15256 if ((*frame)->data && (*frame)->datalen && !((*frame)->flags & SFF_CNG)) {
15257 if (!session->text_buffer) {
15258 switch_mutex_init(&session->text_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
15259 switch_buffer_create_dynamic(&session->text_buffer, 512, 1024, 0);
15260 }
15261 switch_buffer_write(session->text_buffer, (*frame)->data, (*frame)->datalen);
15262 }
15263
15264 if (session->bugs) {
15265 switch_media_bug_t *bp;
15266 int prune = 0;
15267
15268 switch_thread_rwlock_rdlock(session->bug_rwlock);
15269 for (bp = session->bugs; bp; bp = bp->next) {
15270 switch_bool_t ok = SWITCH_TRUE;
15271
15272 if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) {
15273 continue;
15274 }
15275
15276 if (!switch_channel_test_flag(session->channel, CF_ANSWERED) && switch_core_media_bug_test_flag(bp, SMBF_ANSWER_REQ)) {
15277 continue;
15278 }
15279
15280 if (switch_test_flag(bp, SMBF_PRUNE)) {
15281 prune++;
15282 continue;
15283 }
15284
15285 if (bp->ready && switch_test_flag(bp, SMBF_READ_TEXT_STREAM)) {
15286 int bytes = 0;
15287
15288 if ((*frame)) {
15289 switch_size_t inuse = 0;
15290
15291 if ((*frame)->data && (*frame)->datalen && !((*frame)->flags & SFF_CNG)) {
15292 switch_mutex_lock(session->text_mutex);
15293 switch_buffer_write(bp->text_buffer, (char *)(*frame)->data, (*frame)->datalen);
15294 switch_mutex_unlock(session->text_mutex);
15295 }
15296
15297 inuse = switch_buffer_inuse(bp->text_buffer);
15298
15299 if (zstr(bp->text_framedata) && inuse &&
15300 (switch_channel_test_flag(session->channel, CF_TEXT_IDLE) || switch_test_flag((*frame), SFF_TEXT_LINE_BREAK))) {
15301
15302 if (inuse + 1 > bp->text_framesize) {
15303 void *tmp = malloc(inuse + 1024);
15304 memcpy(tmp, bp->text_framedata, bp->text_framesize);
15305
15306 switch_assert(tmp);
15307
15308 bp->text_framesize = inuse + 1024;
15309
15310 free(bp->text_framedata);
15311 bp->text_framedata = tmp;
15312
15313 }
15314
15315
15316 bytes = switch_buffer_read(bp->text_buffer, bp->text_framedata, inuse);
15317 *(bp->text_framedata + bytes) = '\0';
15318
15319 ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ_TEXT);
15320 bp->text_framedata[0] = '\0';
15321 } else ok = SWITCH_TRUE;
15322 }
15323 }
15324
15325 if (ok == SWITCH_FALSE) {
15326 switch_set_flag(bp, SMBF_PRUNE);
15327 prune++;
15328 }
15329 }
15330
15331 switch_thread_rwlock_unlock(session->bug_rwlock);
15332
15333 if (prune) {
15334 switch_core_media_bug_prune(session);
15335 }
15336 }
15337
15338 if (status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK) {
15339 if ((switch_channel_test_flag(session->channel, CF_QUEUE_TEXT_EVENTS) || switch_channel_test_flag(session->channel, CF_FIRE_TEXT_EVENTS)) &&
15340 (*frame)->datalen && !switch_test_flag((*frame), SFF_CNG)) {
15341 int ok = 1;
15342 switch_event_t *event;
15343 void *data = (*frame)->data;
15344 char eof[1] = {'\0'};
15345
15346 //uint32_t datalen = (*frame)->datalen;
15347
15348 if (!switch_channel_test_flag(session->channel, CF_TEXT_LINE_BASED)) {
15349 if (!session->text_line_buffer) {
15350 switch_buffer_create_dynamic(&session->text_line_buffer, 512, 1024, 0);
15351 }
15352 switch_buffer_write(session->text_line_buffer, (*frame)->data, (*frame)->datalen);
15353
15354
15355 if (switch_channel_test_flag(session->channel, CF_TEXT_IDLE) || switch_test_flag((*frame), SFF_TEXT_LINE_BREAK)) {
15356 switch_buffer_write(session->text_line_buffer, eof, 1);
15357 data = switch_buffer_get_head_pointer(session->text_line_buffer);
15358 //datalen = strlen((char *)smh->line_text_frame.data);
15359 } else {
15360 ok = 0;
15361 }
15362 }
15363
15364
15365 if (ok) {
15366 if (switch_event_create(&event, SWITCH_EVENT_TEXT) == SWITCH_STATUS_SUCCESS) {
15367 switch_channel_event_set_data(session->channel, event);
15368
15369 switch_event_add_body(event, "%s", (char *)data);
15370
15371 if (switch_channel_test_flag(session->channel, CF_QUEUE_TEXT_EVENTS)) {
15372 switch_event_t *q_event = NULL;
15373
15374 if (switch_channel_test_flag(session->channel, CF_FIRE_TEXT_EVENTS)) {
15375 switch_event_dup(&q_event, event);
15376 } else {
15377 q_event = event;
15378 event = NULL;
15379 }
15380
15381 switch_core_session_queue_event(session, &q_event);
15382 }
15383
15384 if (switch_channel_test_flag(session->channel, CF_FIRE_TEXT_EVENTS)) {
15385 switch_event_fire(&event);
15386 }
15387 }
15388 if (session->text_line_buffer) {
15389 switch_buffer_zero(session->text_line_buffer);
15390 }
15391 }
15392 }
15393 switch_core_session_text_read_callback(session, *frame);
15394 }
15395
15396 done:
15397
15398 return status;
15399 }
15400
build_red_packet(switch_rtp_engine_t * t_engine)15401 static void build_red_packet(switch_rtp_engine_t *t_engine)
15402 {
15403 int pos;
15404 switch_frame_t *frame = &t_engine->tf->text_write_frame;
15405 switch_byte_t *buf = (switch_byte_t *) frame->data;
15406 uint32_t plen = 0, loops = 0;
15407 uint16_t *u16;
15408
15409 pos = t_engine->tf->red_pos + 1;
15410
15411 if (pos == t_engine->tf->red_max) pos = 0;
15412
15413 for (;;) {
15414 uint16_t ts = frame->timestamp - t_engine->tf->red_ts[pos];
15415 uint16_t len = t_engine->tf->red_buflen[pos];
15416
15417 loops++;
15418
15419 //1
15420 *buf = t_engine->t140_pt & 0x7f;
15421
15422 if (pos != t_engine->tf->red_pos) {
15423 *buf |= 0x80;
15424
15425 buf++; //2
15426 u16 = (uint16_t *) buf;
15427 *u16 = htons(ts << 2);
15428 buf++;//3
15429 *buf += (len & 0x300) >> 8;
15430 buf++;//4
15431 *buf = len & 0xff;
15432 }
15433
15434 buf++;
15435
15436 if (pos == t_engine->tf->red_pos) break;
15437
15438
15439 pos++;
15440
15441 if (pos == t_engine->tf->red_max) pos = 0;
15442 }
15443
15444
15445 plen = ((loops - 1) * 4) + 1;
15446 pos = t_engine->tf->red_pos + 1;
15447
15448 if (pos == t_engine->tf->red_max) pos = 0;
15449
15450 for (;;) {
15451 if (t_engine->tf->red_buflen[pos]) {
15452 memcpy(buf, t_engine->tf->red_buf[pos], t_engine->tf->red_buflen[pos]);
15453 plen += t_engine->tf->red_buflen[pos];
15454 buf += t_engine->tf->red_buflen[pos];
15455 }
15456
15457 if (pos == t_engine->tf->red_pos) break;
15458
15459 pos++;
15460
15461 if (pos == t_engine->tf->red_max) pos = 0;
15462 }
15463
15464
15465 buf = frame->data;
15466 *(buf+plen) = '\0';
15467
15468 frame->datalen = plen;
15469 frame->payload = t_engine->red_pt;
15470 }
15471
switch_core_session_write_text_frame(switch_core_session_t * session,switch_frame_t * frame,switch_io_flag_t flags,int stream_id)15472 SWITCH_DECLARE(switch_status_t) switch_core_session_write_text_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags,
15473 int stream_id)
15474 {
15475 switch_status_t status = SWITCH_STATUS_FALSE;
15476 switch_media_handle_t *smh;
15477 switch_io_event_hook_text_write_frame_t *ptr;
15478 switch_rtp_engine_t *t_engine;
15479 switch_io_write_text_frame_t write_text_frame = NULL;
15480 int is_msrp = switch_channel_test_flag(session->channel, CF_MSRP);
15481
15482 switch_assert(session);
15483
15484 if (!(smh = session->media_handle)) {
15485 return SWITCH_STATUS_FALSE;
15486 }
15487
15488 if (switch_channel_down(session->channel)) {
15489 return SWITCH_STATUS_FALSE;
15490 }
15491
15492 if (switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_TEXT) == SWITCH_MEDIA_FLOW_RECVONLY || switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_TEXT) == SWITCH_MEDIA_FLOW_INACTIVE) {
15493 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG3, "Writing text to RECVONLY/INACTIVE session\n");
15494 return SWITCH_STATUS_SUCCESS;
15495 }
15496
15497 //if (switch_channel_test_flag(session->channel, CF_TEXT_PAUSE_WRITE)) {
15498 // return SWITCH_STATUS_SUCCESS;
15499 //}
15500
15501 if (smh->write_mutex[SWITCH_MEDIA_TYPE_TEXT] && switch_mutex_trylock(smh->write_mutex[SWITCH_MEDIA_TYPE_TEXT]) != SWITCH_STATUS_SUCCESS) {
15502 /* return CNG, another thread is already writing */
15503 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "%s is already being written to for %s\n",
15504 switch_channel_get_name(session->channel), type2str(SWITCH_MEDIA_TYPE_TEXT));
15505 goto done;
15506 }
15507
15508 t_engine = &smh->engines[SWITCH_MEDIA_TYPE_TEXT];
15509
15510 if (!is_msrp && switch_channel_test_cap(session->channel, CC_RTP_RTT)) {
15511
15512 if (frame) {
15513 char *str = (char *) frame->data;
15514 switch_buffer_write(t_engine->tf->write_buffer, str, frame->datalen);
15515 }
15516
15517 if (!switch_buffer_inuse(t_engine->tf->write_buffer)) {
15518 t_engine->tf->write_empty++;
15519 switch_goto_status(SWITCH_STATUS_BREAK, done);
15520 }
15521
15522 frame = &t_engine->tf->text_write_frame;
15523 switch_core_timer_sync(&t_engine->tf->timer);
15524 frame->timestamp = t_engine->tf->timer.samplecount;
15525
15526 if (t_engine->red_pt) {
15527 t_engine->tf->red_ts[t_engine->tf->red_pos] = frame->timestamp;
15528
15529 if (t_engine->tf->write_empty > TEXT_PERIOD_TIMEOUT / TEXT_TIMER_MS) {
15530 int pos;
15531
15532 for(pos = 0; pos < t_engine->tf->red_max; pos++) {
15533 t_engine->tf->red_ts[pos] = 0;
15534 t_engine->tf->red_buf[pos][0] = '\0';
15535 t_engine->tf->red_buflen[pos] = 0;
15536 }
15537
15538 frame->m = 1;
15539 t_engine->tf->write_empty = 0;
15540
15541 } else {
15542 frame->m = 0;
15543 }
15544
15545 t_engine->tf->red_buflen[t_engine->tf->red_pos] =
15546 switch_buffer_read(t_engine->tf->write_buffer, t_engine->tf->red_buf[t_engine->tf->red_pos], RED_PACKET_SIZE);
15547
15548 *(t_engine->tf->red_buf[t_engine->tf->red_pos] + t_engine->tf->red_buflen[t_engine->tf->red_pos]) = '\0';
15549
15550 build_red_packet(t_engine);
15551 } else {
15552 frame->datalen = switch_buffer_read(t_engine->tf->write_buffer, t_engine->tf->text_write_frame.data, RED_PACKET_SIZE);
15553 frame->payload = t_engine->t140_pt;
15554 }
15555 }
15556
15557 if (!(write_text_frame = session->endpoint_interface->io_routines->write_text_frame)) {
15558 if (session->io_override) {
15559 write_text_frame = session->io_override->write_text_frame;
15560 }
15561 }
15562
15563 if (write_text_frame) {
15564 if ((status = write_text_frame(session, frame, flags, stream_id)) == SWITCH_STATUS_SUCCESS) {
15565 for (ptr = session->event_hooks.text_write_frame; ptr; ptr = ptr->next) {
15566 if ((status = ptr->text_write_frame(session, frame, flags, stream_id)) != SWITCH_STATUS_SUCCESS) {
15567 break;
15568 }
15569 }
15570 }
15571 }
15572
15573
15574 if (!is_msrp && switch_channel_test_cap(session->channel, CC_RTP_RTT)) {
15575 if (t_engine->red_pt) {
15576 t_engine->tf->red_pos++;
15577 if (t_engine->tf->red_pos == t_engine->tf->red_max) {
15578 t_engine->tf->red_pos = 0;
15579 }
15580 }
15581 }
15582
15583 done:
15584
15585 if (smh->write_mutex[SWITCH_MEDIA_TYPE_TEXT]) {
15586 switch_mutex_unlock(smh->write_mutex[SWITCH_MEDIA_TYPE_TEXT]);
15587 }
15588
15589 return status;
15590 }
15591
switch_core_session_printf(switch_core_session_t * session,const char * fmt,...)15592 SWITCH_DECLARE(switch_status_t) switch_core_session_printf(switch_core_session_t *session, const char *fmt, ...)
15593 {
15594 char *data = NULL;
15595 int ret = 0;
15596 va_list ap;
15597 switch_frame_t frame = { 0 };
15598 unsigned char CR[] = TEXT_UNICODE_LINEFEED;
15599
15600 va_start(ap, fmt);
15601 ret = switch_vasprintf(&data, fmt, ap);
15602 va_end(ap);
15603
15604 if (ret == -1) {
15605 abort();
15606 }
15607
15608 frame.data = data;
15609 frame.datalen = strlen(data);
15610
15611 switch_core_session_write_text_frame(session, &frame, 0, 0);
15612
15613 frame.data = CR;
15614 frame.datalen = 3;
15615
15616 switch_core_session_write_text_frame(session, &frame, 0, 0);
15617
15618 switch_safe_free(data);
15619
15620 return SWITCH_STATUS_SUCCESS;
15621 }
15622
15623
switch_core_session_print(switch_core_session_t * session,const char * data)15624 SWITCH_DECLARE(switch_status_t) switch_core_session_print(switch_core_session_t *session, const char *data)
15625 {
15626 switch_frame_t frame = { 0 };
15627
15628 if (!switch_channel_test_flag(session->channel, CF_HAS_TEXT)) {
15629 return SWITCH_STATUS_NOTIMPL;
15630 }
15631
15632 frame.data = (char *) data;
15633 frame.datalen = strlen(data);
15634
15635 switch_core_session_write_text_frame(session, &frame, 0, 0);
15636
15637 return SWITCH_STATUS_SUCCESS;
15638 }
15639
switch_core_media_get_msrp_session(switch_core_session_t * session)15640 SWITCH_DECLARE(switch_msrp_session_t *) switch_core_media_get_msrp_session(switch_core_session_t *session)
15641 {
15642 if (!session->media_handle) return NULL;
15643
15644 return session->media_handle->msrp_session;
15645 }
15646
15647
switch_core_session_write_frame(switch_core_session_t * session,switch_frame_t * frame,switch_io_flag_t flags,int stream_id)15648 SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags,
15649 int stream_id)
15650 {
15651
15652 switch_status_t status = SWITCH_STATUS_FALSE;
15653 switch_frame_t *enc_frame = NULL, *write_frame = frame;
15654 unsigned int flag = 0, need_codec = 0, perfect = 0, do_bugs = 0, do_write = 0, do_resample = 0, ptime_mismatch = 0, pass_cng = 0, resample = 0;
15655 int did_write_resample = 0;
15656
15657 switch_assert(session != NULL);
15658 switch_assert(frame != NULL);
15659
15660 if (!switch_channel_up_nosig(session->channel)) {
15661 return SWITCH_STATUS_FALSE;
15662 }
15663
15664 if (switch_mutex_trylock(session->codec_write_mutex) == SWITCH_STATUS_SUCCESS) {
15665 switch_mutex_unlock(session->codec_write_mutex);
15666 } else {
15667 return SWITCH_STATUS_SUCCESS;
15668 }
15669
15670 if (switch_test_flag(frame, SFF_CNG)) {
15671 if (switch_channel_test_flag(session->channel, CF_ACCEPT_CNG)) {
15672 pass_cng = 1;
15673 } else {
15674 return SWITCH_STATUS_SUCCESS;
15675 }
15676 }
15677
15678 if (switch_channel_test_flag(session->channel, CF_AUDIO_PAUSE_WRITE)) {
15679 return SWITCH_STATUS_SUCCESS;
15680 }
15681
15682 if (!(session->write_codec && switch_core_codec_ready(session->write_codec)) && !pass_cng) {
15683 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s has no write codec.\n", switch_channel_get_name(session->channel));
15684 switch_channel_hangup(session->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
15685 return SWITCH_STATUS_FALSE;
15686 }
15687
15688 if (switch_channel_test_flag(session->channel, CF_HOLD)) {
15689 return SWITCH_STATUS_SUCCESS;
15690 }
15691
15692 if (switch_test_flag(frame, SFF_PROXY_PACKET) || pass_cng) {
15693 /* Fast PASS! */
15694 switch_mutex_lock(session->codec_write_mutex);
15695 status = perform_write(session, frame, flag, stream_id);
15696 switch_mutex_unlock(session->codec_write_mutex);
15697 return status;
15698 }
15699
15700 switch_mutex_lock(session->codec_write_mutex);
15701
15702 if (!(frame->codec && frame->codec->implementation)) {
15703 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s has received a bad frame with no codec!\n",
15704 switch_channel_get_name(session->channel));
15705 switch_channel_hangup(session->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
15706 switch_mutex_unlock(session->codec_write_mutex);
15707 return SWITCH_STATUS_FALSE;
15708 }
15709
15710 switch_assert(frame->codec != NULL);
15711 switch_assert(frame->codec->implementation != NULL);
15712
15713 if (!(switch_core_codec_ready(session->write_codec) && frame->codec) ||
15714 !switch_channel_ready(session->channel) || !switch_channel_media_ready(session->channel)) {
15715 switch_mutex_unlock(session->codec_write_mutex);
15716 return SWITCH_STATUS_FALSE;
15717 }
15718
15719 switch_mutex_lock(session->write_codec->mutex);
15720 switch_mutex_lock(frame->codec->mutex);
15721
15722 if (!(switch_core_codec_ready(session->write_codec) && switch_core_codec_ready(frame->codec))) goto error;
15723
15724 if ((session->write_codec && frame->codec && session->write_codec->implementation != frame->codec->implementation)) {
15725 if (session->write_impl.codec_id == frame->codec->implementation->codec_id ||
15726 session->write_impl.microseconds_per_packet != frame->codec->implementation->microseconds_per_packet) {
15727 ptime_mismatch = TRUE;
15728
15729 if ((switch_test_flag(frame->codec, SWITCH_CODEC_FLAG_PASSTHROUGH) || switch_test_flag(session->read_codec, SWITCH_CODEC_FLAG_PASSTHROUGH)) ||
15730 switch_channel_test_flag(session->channel, CF_PASSTHRU_PTIME_MISMATCH)) {
15731 status = perform_write(session, frame, flags, stream_id);
15732 goto error;
15733 }
15734
15735 if (session->write_impl.microseconds_per_packet < frame->codec->implementation->microseconds_per_packet) {
15736 switch_core_session_start_audio_write_thread(session);
15737 }
15738 }
15739 need_codec = TRUE;
15740 }
15741
15742 if (session->write_codec && !frame->codec) {
15743 need_codec = TRUE;
15744 }
15745
15746 if (session->bugs && !need_codec && !switch_test_flag(session, SSF_MEDIA_BUG_TAP_ONLY)) {
15747 do_bugs = TRUE;
15748 need_codec = TRUE;
15749 }
15750
15751 if (frame->codec->implementation->actual_samples_per_second != session->write_impl.actual_samples_per_second) {
15752 need_codec = TRUE;
15753 do_resample = TRUE;
15754 }
15755
15756
15757 if ((frame->flags & SFF_NOT_AUDIO)) {
15758 do_resample = 0;
15759 do_bugs = 0;
15760 need_codec = 0;
15761 }
15762
15763 if (switch_test_flag(session, SSF_WRITE_TRANSCODE) && !need_codec && switch_core_codec_ready(session->write_codec)) {
15764 switch_core_session_t *other_session;
15765 const char *uuid = switch_channel_get_partner_uuid(switch_core_session_get_channel(session));
15766
15767 if (uuid && (other_session = switch_core_session_locate(uuid))) {
15768 switch_set_flag(other_session, SSF_READ_CODEC_RESET);
15769 switch_set_flag(other_session, SSF_READ_CODEC_RESET);
15770 switch_set_flag(other_session, SSF_WRITE_CODEC_RESET);
15771 switch_core_session_rwunlock(other_session);
15772 }
15773
15774 switch_clear_flag(session, SSF_WRITE_TRANSCODE);
15775 }
15776
15777
15778 if (switch_test_flag(session, SSF_WRITE_CODEC_RESET)) {
15779 switch_core_codec_reset(session->write_codec);
15780 switch_clear_flag(session, SSF_WRITE_CODEC_RESET);
15781 }
15782
15783 if (!need_codec) {
15784 do_write = TRUE;
15785 write_frame = frame;
15786 goto done;
15787 }
15788
15789 if (!switch_test_flag(session, SSF_WARN_TRANSCODE)) {
15790 switch_core_session_message_t msg = { 0 };
15791
15792 msg.message_id = SWITCH_MESSAGE_INDICATE_TRANSCODING_NECESSARY;
15793 switch_core_session_receive_message(session, &msg);
15794 switch_set_flag(session, SSF_WARN_TRANSCODE);
15795 }
15796
15797 if (frame->codec) {
15798 session->raw_write_frame.datalen = session->raw_write_frame.buflen;
15799 frame->codec->cur_frame = frame;
15800 session->write_codec->cur_frame = frame;
15801 status = switch_core_codec_decode(frame->codec,
15802 session->write_codec,
15803 frame->data,
15804 frame->datalen,
15805 session->write_impl.actual_samples_per_second,
15806 session->raw_write_frame.data, &session->raw_write_frame.datalen, &session->raw_write_frame.rate, &frame->flags);
15807 frame->codec->cur_frame = NULL;
15808 session->write_codec->cur_frame = NULL;
15809 if (do_resample && status == SWITCH_STATUS_SUCCESS) {
15810 status = SWITCH_STATUS_RESAMPLE;
15811 }
15812
15813 /* mux or demux to match */
15814 if (session->write_impl.number_of_channels != frame->codec->implementation->number_of_channels) {
15815 uint32_t rlen = session->raw_write_frame.datalen / 2 / frame->codec->implementation->number_of_channels;
15816 switch_mux_channels((int16_t *) session->raw_write_frame.data, rlen,
15817 frame->codec->implementation->number_of_channels, session->write_impl.number_of_channels);
15818 session->raw_write_frame.datalen = rlen * 2 * session->write_impl.number_of_channels;
15819 }
15820
15821 switch (status) {
15822 case SWITCH_STATUS_RESAMPLE:
15823 resample++;
15824 write_frame = &session->raw_write_frame;
15825 write_frame->rate = frame->codec->implementation->actual_samples_per_second;
15826 if (!session->write_resampler) {
15827 switch_mutex_lock(session->resample_mutex);
15828 status = switch_resample_create(&session->write_resampler,
15829 frame->codec->implementation->actual_samples_per_second,
15830 session->write_impl.actual_samples_per_second,
15831 session->write_impl.decoded_bytes_per_packet, SWITCH_RESAMPLE_QUALITY, session->write_impl.number_of_channels);
15832
15833
15834 switch_mutex_unlock(session->resample_mutex);
15835 if (status != SWITCH_STATUS_SUCCESS) {
15836 goto done;
15837 } else {
15838 switch_core_session_message_t msg = { 0 };
15839 msg.numeric_arg = 1;
15840 msg.message_id = SWITCH_MESSAGE_RESAMPLE_EVENT;
15841 switch_core_session_receive_message(session, &msg);
15842
15843 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Activating write resampler\n");
15844 }
15845 }
15846 break;
15847 case SWITCH_STATUS_SUCCESS:
15848 session->raw_write_frame.samples = session->raw_write_frame.datalen / sizeof(int16_t) / session->write_impl.number_of_channels;
15849 session->raw_write_frame.channels = session->write_impl.number_of_channels;
15850 session->raw_write_frame.timestamp = frame->timestamp;
15851 session->raw_write_frame.rate = frame->rate;
15852 session->raw_write_frame.m = frame->m;
15853 session->raw_write_frame.ssrc = frame->ssrc;
15854 session->raw_write_frame.seq = frame->seq;
15855 session->raw_write_frame.payload = frame->payload;
15856 session->raw_write_frame.flags = 0;
15857 if (switch_test_flag(frame, SFF_PLC)) {
15858 session->raw_write_frame.flags |= SFF_PLC;
15859 }
15860
15861 write_frame = &session->raw_write_frame;
15862 break;
15863 case SWITCH_STATUS_BREAK:
15864 status = SWITCH_STATUS_SUCCESS;
15865 goto error;
15866 case SWITCH_STATUS_NOOP:
15867 if (session->write_resampler) {
15868 switch_mutex_lock(session->resample_mutex);
15869 switch_resample_destroy(&session->write_resampler);
15870 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating write resampler\n");
15871 switch_mutex_unlock(session->resample_mutex);
15872
15873 {
15874 switch_core_session_message_t msg = { 0 };
15875 msg.numeric_arg = 0;
15876 msg.message_id = SWITCH_MESSAGE_RESAMPLE_EVENT;
15877 switch_core_session_receive_message(session, &msg);
15878 }
15879
15880 }
15881 write_frame = frame;
15882 status = SWITCH_STATUS_SUCCESS;
15883 break;
15884 default:
15885
15886 if (status == SWITCH_STATUS_NOT_INITALIZED) {
15887 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec init error!\n");
15888 goto error;
15889 }
15890 if (ptime_mismatch && status != SWITCH_STATUS_GENERR) {
15891 perform_write(session, frame, flags, stream_id);
15892 status = SWITCH_STATUS_SUCCESS;
15893 goto error;
15894 }
15895
15896 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec %s decoder error!\n",
15897 frame->codec->codec_interface->interface_name);
15898 goto error;
15899 }
15900 }
15901
15902
15903
15904 if (session->write_resampler) {
15905 short *data = write_frame->data;
15906
15907 switch_mutex_lock(session->resample_mutex);
15908 if (session->write_resampler) {
15909
15910 if (switch_resample_calc_buffer_size(session->write_resampler->to_rate, session->write_resampler->from_rate,
15911 write_frame->datalen / 2 / session->write_resampler->channels) > SWITCH_RECOMMENDED_BUFFER_SIZE) {
15912
15913 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "%s not enough buffer space for required resample operation!\n",
15914 switch_channel_get_name(session->channel));
15915 switch_channel_hangup(session->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
15916 switch_mutex_unlock(session->resample_mutex);
15917 goto error;
15918 }
15919
15920
15921 switch_resample_process(session->write_resampler, data, write_frame->datalen / 2 / session->write_resampler->channels);
15922
15923 memcpy(data, session->write_resampler->to, session->write_resampler->to_len * 2 * session->write_resampler->channels);
15924
15925 write_frame->samples = session->write_resampler->to_len;
15926 write_frame->channels = session->write_resampler->channels;
15927 write_frame->datalen = write_frame->samples * 2 * session->write_resampler->channels;
15928
15929 write_frame->rate = session->write_resampler->to_rate;
15930
15931 did_write_resample = 1;
15932 }
15933 switch_mutex_unlock(session->resample_mutex);
15934 }
15935
15936
15937
15938 if (session->bugs) {
15939 switch_media_bug_t *bp;
15940 int prune = 0;
15941
15942 switch_thread_rwlock_rdlock(session->bug_rwlock);
15943 for (bp = session->bugs; bp; bp = bp->next) {
15944 switch_bool_t ok = SWITCH_TRUE;
15945
15946 if (!bp->ready) {
15947 continue;
15948 }
15949
15950 if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) {
15951 continue;
15952 }
15953
15954 if (!switch_channel_test_flag(session->channel, CF_ANSWERED) && switch_core_media_bug_test_flag(bp, SMBF_ANSWER_REQ)) {
15955 continue;
15956 }
15957
15958 if (switch_test_flag(bp, SMBF_PRUNE)) {
15959 prune++;
15960 continue;
15961 }
15962
15963 if (switch_test_flag(bp, SMBF_WRITE_STREAM)) {
15964 switch_mutex_lock(bp->write_mutex);
15965 switch_buffer_write(bp->raw_write_buffer, write_frame->data, write_frame->datalen);
15966 switch_mutex_unlock(bp->write_mutex);
15967
15968 if (bp->callback) {
15969 ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_WRITE);
15970 }
15971 }
15972
15973 if (switch_test_flag(bp, SMBF_WRITE_REPLACE)) {
15974 do_bugs = 0;
15975 if (bp->callback) {
15976 bp->write_replace_frame_in = write_frame;
15977 bp->write_replace_frame_out = write_frame;
15978 if ((ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_WRITE_REPLACE)) == SWITCH_TRUE) {
15979 write_frame = bp->write_replace_frame_out;
15980 }
15981 }
15982 }
15983
15984 if (bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL)) {
15985 ok = SWITCH_FALSE;
15986 }
15987
15988
15989 if (ok == SWITCH_FALSE) {
15990 switch_set_flag(bp, SMBF_PRUNE);
15991 prune++;
15992 }
15993 }
15994 switch_thread_rwlock_unlock(session->bug_rwlock);
15995 if (prune) {
15996 switch_core_media_bug_prune(session);
15997 }
15998 }
15999
16000 if (do_bugs) {
16001 do_write = TRUE;
16002 write_frame = frame;
16003 goto done;
16004 }
16005
16006 if (session->write_codec) {
16007 if (!ptime_mismatch && write_frame->codec && write_frame->codec->implementation &&
16008 write_frame->codec->implementation->decoded_bytes_per_packet == session->write_impl.decoded_bytes_per_packet) {
16009 perfect = TRUE;
16010 }
16011
16012
16013
16014 if (perfect) {
16015
16016 if (write_frame->datalen < session->write_impl.decoded_bytes_per_packet) {
16017 memset(write_frame->data, 255, session->write_impl.decoded_bytes_per_packet - write_frame->datalen);
16018 write_frame->datalen = session->write_impl.decoded_bytes_per_packet;
16019 }
16020
16021 enc_frame = write_frame;
16022 session->enc_write_frame.datalen = session->enc_write_frame.buflen;
16023 session->write_codec->cur_frame = frame;
16024 frame->codec->cur_frame = frame;
16025 switch_assert(enc_frame->datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE);
16026 switch_assert(session->enc_read_frame.datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE);
16027 status = switch_core_codec_encode(session->write_codec,
16028 frame->codec,
16029 enc_frame->data,
16030 enc_frame->datalen,
16031 session->write_impl.actual_samples_per_second,
16032 session->enc_write_frame.data, &session->enc_write_frame.datalen, &session->enc_write_frame.rate, &flag);
16033
16034 switch_assert(session->enc_read_frame.datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE);
16035
16036 session->write_codec->cur_frame = NULL;
16037 frame->codec->cur_frame = NULL;
16038 switch (status) {
16039 case SWITCH_STATUS_RESAMPLE:
16040 resample++;
16041 /* switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Fixme 2\n"); */
16042 case SWITCH_STATUS_SUCCESS:
16043 session->enc_write_frame.codec = session->write_codec;
16044 session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t) / session->write_impl.number_of_channels;
16045 session->enc_write_frame.channels = session->write_impl.number_of_channels;
16046 if (frame->codec->implementation->samples_per_packet != session->write_impl.samples_per_packet) {
16047 session->enc_write_frame.timestamp = 0;
16048 } else {
16049 session->enc_write_frame.timestamp = frame->timestamp;
16050 }
16051 session->enc_write_frame.payload = session->write_impl.ianacode;
16052 session->enc_write_frame.m = frame->m;
16053 session->enc_write_frame.ssrc = frame->ssrc;
16054 session->enc_write_frame.seq = frame->seq;
16055 session->enc_write_frame.flags = 0;
16056 write_frame = &session->enc_write_frame;
16057 break;
16058 case SWITCH_STATUS_NOOP:
16059 enc_frame->codec = session->write_codec;
16060 enc_frame->samples = enc_frame->datalen / sizeof(int16_t) / session->write_impl.number_of_channels;
16061 enc_frame->channels = session->write_impl.number_of_channels;
16062 enc_frame->timestamp = frame->timestamp;
16063 enc_frame->m = frame->m;
16064 enc_frame->seq = frame->seq;
16065 enc_frame->ssrc = frame->ssrc;
16066 enc_frame->payload = enc_frame->codec->implementation->ianacode;
16067 write_frame = enc_frame;
16068 break;
16069 case SWITCH_STATUS_NOT_INITALIZED:
16070 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec init error!\n");
16071 write_frame = NULL;
16072 goto error;
16073 default:
16074 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec %s encoder error!\n",
16075 session->read_codec->codec_interface->interface_name);
16076 write_frame = NULL;
16077 goto error;
16078 }
16079 if (flag & SFF_CNG) {
16080 switch_set_flag(write_frame, SFF_CNG);
16081 }
16082
16083 status = perform_write(session, write_frame, flags, stream_id);
16084 goto error;
16085 } else {
16086 if (!session->raw_write_buffer) {
16087 switch_size_t bytes_per_packet = session->write_impl.decoded_bytes_per_packet;
16088 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
16089 "Engaging Write Buffer at %u bytes to accommodate %u->%u\n",
16090 (uint32_t) bytes_per_packet, write_frame->datalen, session->write_impl.decoded_bytes_per_packet);
16091 if ((status = switch_buffer_create_dynamic(&session->raw_write_buffer,
16092 bytes_per_packet * SWITCH_BUFFER_BLOCK_FRAMES,
16093 bytes_per_packet * SWITCH_BUFFER_START_FRAMES, 0)) != SWITCH_STATUS_SUCCESS) {
16094 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Write Buffer Failed!\n");
16095 goto error;
16096 }
16097
16098 /* Need to retrain the recording data */
16099 switch_core_media_bug_flush_all(session);
16100 }
16101
16102 if (!(switch_buffer_write(session->raw_write_buffer, write_frame->data, write_frame->datalen))) {
16103 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Write Buffer %u bytes Failed!\n", write_frame->datalen);
16104 status = SWITCH_STATUS_MEMERR;
16105 goto error;
16106 }
16107
16108 status = SWITCH_STATUS_SUCCESS;
16109
16110 while (switch_buffer_inuse(session->raw_write_buffer) >= session->write_impl.decoded_bytes_per_packet) {
16111 int rate;
16112
16113 if (switch_channel_down(session->channel) || !session->raw_write_buffer) {
16114 goto error;
16115 }
16116 if ((session->raw_write_frame.datalen = (uint32_t)
16117 switch_buffer_read(session->raw_write_buffer, session->raw_write_frame.data, session->write_impl.decoded_bytes_per_packet)) == 0) {
16118 goto error;
16119 }
16120
16121 enc_frame = &session->raw_write_frame;
16122 session->raw_write_frame.rate = session->write_impl.actual_samples_per_second;
16123 session->enc_write_frame.datalen = session->enc_write_frame.buflen;
16124 session->enc_write_frame.timestamp = 0;
16125
16126
16127 if (frame->codec && frame->codec->implementation && switch_core_codec_ready(frame->codec)) {
16128 rate = frame->codec->implementation->actual_samples_per_second;
16129 } else {
16130 rate = session->write_impl.actual_samples_per_second;
16131 }
16132
16133 session->write_codec->cur_frame = frame;
16134 frame->codec->cur_frame = frame;
16135 switch_assert(enc_frame->datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE);
16136 switch_assert(session->enc_read_frame.datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE);
16137 status = switch_core_codec_encode(session->write_codec,
16138 frame->codec,
16139 enc_frame->data,
16140 enc_frame->datalen,
16141 rate,
16142 session->enc_write_frame.data, &session->enc_write_frame.datalen, &session->enc_write_frame.rate, &flag);
16143
16144 switch_assert(session->enc_read_frame.datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE);
16145
16146 session->write_codec->cur_frame = NULL;
16147 frame->codec->cur_frame = NULL;
16148 switch (status) {
16149 case SWITCH_STATUS_RESAMPLE:
16150 resample++;
16151 session->enc_write_frame.codec = session->write_codec;
16152 session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t) / session->write_impl.number_of_channels;
16153 session->enc_write_frame.channels = session->write_impl.number_of_channels;
16154 session->enc_write_frame.m = frame->m;
16155 session->enc_write_frame.ssrc = frame->ssrc;
16156 session->enc_write_frame.payload = session->write_impl.ianacode;
16157 write_frame = &session->enc_write_frame;
16158 if (!session->write_resampler) {
16159 switch_mutex_lock(session->resample_mutex);
16160 if (!session->write_resampler) {
16161 status = switch_resample_create(&session->write_resampler,
16162 frame->codec->implementation->actual_samples_per_second,
16163 session->write_impl.actual_samples_per_second,
16164 session->write_impl.decoded_bytes_per_packet, SWITCH_RESAMPLE_QUALITY,
16165 session->write_impl.number_of_channels);
16166 }
16167 switch_mutex_unlock(session->resample_mutex);
16168
16169
16170
16171 if (status != SWITCH_STATUS_SUCCESS) {
16172 goto done;
16173 } else {
16174 switch_core_session_message_t msg = { 0 };
16175 msg.numeric_arg = 1;
16176 msg.message_id = SWITCH_MESSAGE_RESAMPLE_EVENT;
16177 switch_core_session_receive_message(session, &msg);
16178
16179
16180 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Activating write resampler\n");
16181 }
16182 }
16183 break;
16184 case SWITCH_STATUS_SUCCESS:
16185 session->enc_write_frame.codec = session->write_codec;
16186 session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t) / session->write_impl.number_of_channels;
16187 session->enc_write_frame.channels = session->write_impl.number_of_channels;
16188 session->enc_write_frame.m = frame->m;
16189 session->enc_write_frame.ssrc = frame->ssrc;
16190 session->enc_write_frame.payload = session->write_impl.ianacode;
16191 session->enc_write_frame.flags = 0;
16192 write_frame = &session->enc_write_frame;
16193 break;
16194 case SWITCH_STATUS_NOOP:
16195 if (session->write_resampler) {
16196 switch_core_session_message_t msg = { 0 };
16197 int ok = 0;
16198
16199 switch_mutex_lock(session->resample_mutex);
16200 if (session->write_resampler) {
16201 switch_resample_destroy(&session->write_resampler);
16202 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating write resampler\n");
16203 ok = 1;
16204 }
16205 switch_mutex_unlock(session->resample_mutex);
16206
16207 if (ok) {
16208 msg.numeric_arg = 0;
16209 msg.message_id = SWITCH_MESSAGE_RESAMPLE_EVENT;
16210 switch_core_session_receive_message(session, &msg);
16211 }
16212
16213 }
16214 enc_frame->codec = session->write_codec;
16215 enc_frame->samples = enc_frame->datalen / sizeof(int16_t) / session->read_impl.number_of_channels;
16216 enc_frame->channels = session->read_impl.number_of_channels;
16217 enc_frame->m = frame->m;
16218 enc_frame->ssrc = frame->ssrc;
16219 enc_frame->payload = enc_frame->codec->implementation->ianacode;
16220 write_frame = enc_frame;
16221 break;
16222 case SWITCH_STATUS_NOT_INITALIZED:
16223 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec init error!\n");
16224 write_frame = NULL;
16225 goto error;
16226 default:
16227 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec %s encoder error %d!\n",
16228 session->read_codec->codec_interface->interface_name, status);
16229 write_frame = NULL;
16230 goto error;
16231 }
16232
16233 if (!did_write_resample && session->read_resampler) {
16234 short *data = write_frame->data;
16235 switch_mutex_lock(session->resample_mutex);
16236 if (session->read_resampler) {
16237 switch_resample_process(session->read_resampler, data, write_frame->datalen / 2 / session->read_resampler->channels);
16238 memcpy(data, session->read_resampler->to, session->read_resampler->to_len * 2 * session->read_resampler->channels);
16239 write_frame->samples = session->read_resampler->to_len;
16240 write_frame->channels = session->read_resampler->channels;
16241 write_frame->datalen = session->read_resampler->to_len * 2 * session->read_resampler->channels;
16242 write_frame->rate = session->read_resampler->to_rate;
16243 }
16244 switch_mutex_unlock(session->resample_mutex);
16245
16246 }
16247
16248 if (flag & SFF_CNG) {
16249 switch_set_flag(write_frame, SFF_CNG);
16250 }
16251
16252 if (ptime_mismatch || resample) {
16253 write_frame->timestamp = 0;
16254 }
16255
16256 if ((status = perform_write(session, write_frame, flags, stream_id)) != SWITCH_STATUS_SUCCESS) {
16257 break;
16258 }
16259
16260 }
16261
16262 goto error;
16263 }
16264 }
16265
16266
16267
16268
16269
16270 done:
16271
16272 if (ptime_mismatch || resample) {
16273 write_frame->timestamp = 0;
16274 }
16275
16276 if (do_write) {
16277 status = perform_write(session, write_frame, flags, stream_id);
16278 }
16279
16280 error:
16281
16282 switch_mutex_unlock(session->write_codec->mutex);
16283 switch_mutex_unlock(frame->codec->mutex);
16284 switch_mutex_unlock(session->codec_write_mutex);
16285
16286 return status;
16287 }
16288
16289
16290
16291 /* For Emacs:
16292 * Local Variables:
16293 * mode:c
16294 * indent-tabs-mode:t
16295 * tab-width:4
16296 * c-basic-offset:4
16297 * End:
16298 * For VIM:
16299 * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
16300 */
16301