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