Bug Summary

File:src/switch_core_media.c
Location:line 3906, column 6
Description:Value stored to 'te' is never read

Annotated Source Code

1/*
2 * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3 * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
4 *
5 * Version: MPL 1.1
6 *
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
16 *
17 * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
18 *
19 * The Initial Developer of the Original Code is
20 * Anthony Minessale II <anthm@freeswitch.org>
21 * Portions created by the Initial Developer are Copyright (C)
22 * the Initial Developer. All Rights Reserved.
23 *
24 * Contributor(s):
25 *
26 * Anthony Minessale II <anthm@freeswitch.org>
27 *
28 * switch_core_media.c -- Core Media
29 *
30 */
31
32#include <switch.h>
33#include <switch_ssl.h>
34#include <switch_stun.h>
35#include <switch_nat.h>
36#include "private/switch_core_pvt.h"
37#include <switch_curl.h>
38#include <errno(*__errno_location ()).h>
39#include <sofia-sip/sdp.h>
40#include <sofia-sip/su.h>
41
42static switch_t38_options_t * switch_core_media_process_udptl(switch_core_session_t *session, sdp_session_t *sdp, sdp_media_t *m);
43static void switch_core_media_find_zrtp_hash(switch_core_session_t *session, sdp_session_t *sdp);
44static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *session, const char *codec_string, sdp_session_t *sdp, switch_sdp_type_t sdp_type);
45
46//#define GOOGLE_ICE
47#define RTCP_MUX
48#define MAX_CODEC_CHECK_FRAMES50 50//x:mod_sofia.h
49#define MAX_MISMATCH_FRAMES5 5//x:mod_sofia.h
50#define type2str(type)type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio" type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio"
51
52typedef enum {
53 SMF_INIT = (1 << 0),
54 SMF_READY = (1 << 1),
55 SMF_JB_PAUSED = (1 << 2)
56} smh_flag_t;
57
58
59typedef struct secure_settings_s {
60 int crypto_tag;
61 unsigned char local_raw_key[SWITCH_RTP_MAX_CRYPTO_LEN64];
62 unsigned char remote_raw_key[SWITCH_RTP_MAX_CRYPTO_LEN64];
63 switch_rtp_crypto_key_type_t crypto_type;
64 char *local_crypto_key;
65 char *remote_crypto_key;
66} switch_secure_settings_t;
67
68
69
70struct media_helper {
71 switch_core_session_t *session;
72 switch_thread_cond_t *cond;
73 switch_mutex_t *cond_mutex;
74 int up;
75};
76
77typedef enum {
78 CRYPTO_MODE_OPTIONAL,
79 CRYPTO_MODE_MANDATORY,
80 CRYPTO_MODE_FORBIDDEN
81} switch_rtp_crypto_mode_t;
82
83typedef struct switch_rtp_engine_s {
84 switch_secure_settings_t ssec[CRYPTO_INVALID+1];
85 switch_rtp_crypto_key_type_t crypto_type;
86
87 switch_media_type_t type;
88
89 switch_rtp_t *rtp_session;
90 switch_frame_t read_frame;
91 switch_codec_t read_codec;
92 switch_codec_t write_codec;
93
94 switch_codec_implementation_t read_impl;
95 switch_codec_implementation_t write_impl;
96
97 switch_size_t last_ts;
98 switch_size_t last_seq;
99 uint32_t check_frames;
100 uint32_t mismatch_count;
101 uint32_t last_codec_ms;
102 uint8_t codec_reinvites;
103 uint32_t max_missed_packets;
104 uint32_t max_missed_hold_packets;
105 uint32_t ssrc;
106 uint32_t remote_ssrc;
107 switch_port_t remote_rtcp_port;
108 switch_rtp_bug_flag_t rtp_bugs;
109
110
111 char *local_sdp_ip;
112 switch_port_t local_sdp_port;
113 char *adv_sdp_ip;
114 switch_port_t adv_sdp_port;
115 char *proxy_sdp_ip;
116 switch_port_t proxy_sdp_port;
117
118
119 /** ZRTP **/
120 char *local_sdp_zrtp_hash;
121 char *remote_sdp_zrtp_hash;
122
123 payload_map_t *cur_payload_map;
124 payload_map_t *payload_map;
125 payload_map_t *pmap_tail;
126
127 uint32_t timestamp_send;
128
129 char *cand_acl[SWITCH_MAX_CAND_ACL25];
130 int cand_acl_count;
131
132 ice_t ice_in;
133 ice_t ice_out;
134
135 int8_t rtcp_mux;
136
137 dtls_fingerprint_t local_dtls_fingerprint;
138 dtls_fingerprint_t remote_dtls_fingerprint;
139
140 char *remote_rtp_ice_addr;
141 switch_port_t remote_rtp_ice_port;
142
143 char *remote_rtcp_ice_addr;
144 switch_port_t remote_rtcp_ice_port;
145
146 struct media_helper mh;
147 switch_thread_t *media_thread;
148 switch_mutex_t *read_mutex[2];
149
150 uint8_t reset_codec;
151 uint8_t codec_negotiated;
152
153 uint8_t fir;
154 uint8_t pli;
155 uint8_t no_crypto;
156} switch_rtp_engine_t;
157
158
159struct switch_media_handle_s {
160 switch_core_session_t *session;
161 switch_channel_t *channel;
162 switch_core_media_flag_t media_flags[SCMF_MAX];
163 smh_flag_t flags;
164 switch_rtp_engine_t engines[SWITCH_MEDIA_TYPE_TOTAL2];
165
166 char *codec_order[SWITCH_MAX_CODECS50];
167 int codec_order_last;
168 const switch_codec_implementation_t *codecs[SWITCH_MAX_CODECS50];
169
170 int payload_space;
171 char *origin;
172
173 switch_mutex_t *mutex;
174 switch_mutex_t *sdp_mutex;
175
176 const switch_codec_implementation_t *negotiated_codecs[SWITCH_MAX_CODECS50];
177 int num_negotiated_codecs;
178 switch_payload_t ianacodes[SWITCH_MAX_CODECS50];
179 char *fmtps[SWITCH_MAX_CODECS50];
180 int video_count;
181
182 uint32_t owner_id;
183 uint32_t session_id;
184
185 switch_core_media_params_t *mparams;
186
187 char *msid;
188 char *cname;
189
190 switch_rtp_crypto_mode_t crypto_mode;
191 switch_rtp_crypto_key_type_t crypto_suite_order[CRYPTO_INVALID+1];
192};
193
194
195static switch_srtp_crypto_suite_t SUITES[CRYPTO_INVALID] = {
196 { "AEAD_AES_256_GCM_8", AEAD_AES_256_GCM_8, 44},
197 { "AEAD_AES_128_GCM_8", AEAD_AES_128_GCM_8, 28},
198 { "AES_CM_256_HMAC_SHA1_80", AES_CM_256_HMAC_SHA1_80, 46},
199 { "AES_CM_192_HMAC_SHA1_80", AES_CM_192_HMAC_SHA1_80, 38},
200 { "AES_CM_128_HMAC_SHA1_80", AES_CM_128_HMAC_SHA1_80, 30},
201 { "AES_CM_256_HMAC_SHA1_32", AES_CM_256_HMAC_SHA1_32, 46},
202 { "AES_CM_192_HMAC_SHA1_32", AES_CM_192_HMAC_SHA1_32, 38},
203 { "AES_CM_128_HMAC_SHA1_32", AES_CM_128_HMAC_SHA1_32, 30},
204 { "AES_CM_128_NULL_AUTH", AES_CM_128_NULL_AUTH, 30}
205};
206
207SWITCH_DECLARE(switch_rtp_crypto_key_type_t)__attribute__((visibility("default"))) switch_rtp_crypto_key_type_t switch_core_media_crypto_str2type(const char *str)
208{
209 int i;
210
211 for (i = 0; i < CRYPTO_INVALID; i++) {
212 if (!strncasecmp(str, SUITES[i].name, strlen(SUITES[i].name))) {
213 return SUITES[i].type;
214 }
215 }
216
217 return CRYPTO_INVALID;
218}
219
220
221SWITCH_DECLARE(const char *)__attribute__((visibility("default"))) const char * switch_core_media_crypto_type2str(switch_rtp_crypto_key_type_t type)
222{
223 switch_assert(type < CRYPTO_INVALID)((type < CRYPTO_INVALID) ? (void) (0) : __assert_fail ("type < CRYPTO_INVALID"
, "src/switch_core_media.c", 223, __PRETTY_FUNCTION__))
;
224 return SUITES[type].name;
225}
226
227
228SWITCH_DECLARE(int)__attribute__((visibility("default"))) int switch_core_media_crypto_keylen(switch_rtp_crypto_key_type_t type)
229{
230 switch_assert(type < CRYPTO_INVALID)((type < CRYPTO_INVALID) ? (void) (0) : __assert_fail ("type < CRYPTO_INVALID"
, "src/switch_core_media.c", 230, __PRETTY_FUNCTION__))
;
231 return SUITES[type].keylen;
232}
233
234
235static int get_channels(const char *name, int dft)
236{
237
238 if (!zstr(name)_zstr(name) && !switch_true(switch_core_get_variable("NDLB_broken_opus_sdp")) && !strcasecmp(name, "opus")) {
239 return 2; /* IKR???*/
240 }
241
242 return dft ? dft : 1;
243}
244
245static void _switch_core_media_pass_zrtp_hash2(switch_core_session_t *aleg_session, switch_core_session_t *bleg_session, switch_media_type_t type)
246{
247 switch_rtp_engine_t *aleg_engine;
248 switch_rtp_engine_t *bleg_engine;
249
250 if (!aleg_session->media_handle || !bleg_session->media_handle) return;
251 aleg_engine = &aleg_session->media_handle->engines[type];
252 bleg_engine = &bleg_session->media_handle->engines[type];
253
254
255
256 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(aleg_session->channel)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 256, (const char*)switch_channel_get_session(aleg_session
->channel)
, SWITCH_LOG_DEBUG1,
257 "Deciding whether to pass zrtp-hash between a-leg and b-leg\n");
258
259 if (!(switch_channel_test_flag(aleg_session->channel, CF_ZRTP_PASSTHRU_REQ))) {
260 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(aleg_session->channel)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 260, (const char*)switch_channel_get_session(aleg_session
->channel)
, SWITCH_LOG_DEBUG1,
261 "CF_ZRTP_PASSTHRU_REQ not set on a-leg, so not propagating zrtp-hash\n");
262 return;
263 }
264
265 if (aleg_engine->remote_sdp_zrtp_hash) {
266 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(aleg_session->channel)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 266, (const char*)switch_channel_get_session(aleg_session
->channel)
, SWITCH_LOG_DEBUG, "Passing a-leg remote zrtp-hash (audio) to b-leg\n");
267 bleg_engine->local_sdp_zrtp_hash = switch_core_session_strdup(bleg_session, aleg_engine->remote_sdp_zrtp_hash)switch_core_perform_session_strdup(bleg_session, aleg_engine->
remote_sdp_zrtp_hash, "src/switch_core_media.c", (const char *
)__func__, 267)
;
268 switch_channel_set_variable(bleg_session->channel, "l_sdp_audio_zrtp_hash", bleg_engine->local_sdp_zrtp_hash)switch_channel_set_variable_var_check(bleg_session->channel
, "l_sdp_audio_zrtp_hash", bleg_engine->local_sdp_zrtp_hash
, SWITCH_TRUE)
;
269 }
270
271 if (bleg_engine->remote_sdp_zrtp_hash) {
272 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(aleg_session->channel)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 272, (const char*)switch_channel_get_session(aleg_session
->channel)
, SWITCH_LOG_DEBUG, "Passing b-leg remote zrtp-hash (audio) to a-leg\n");
273 aleg_engine->local_sdp_zrtp_hash = switch_core_session_strdup(aleg_session, bleg_engine->remote_sdp_zrtp_hash)switch_core_perform_session_strdup(aleg_session, bleg_engine->
remote_sdp_zrtp_hash, "src/switch_core_media.c", (const char *
)__func__, 273)
;
274 switch_channel_set_variable(aleg_session->channel, "l_sdp_audio_zrtp_hash", aleg_engine->local_sdp_zrtp_hash)switch_channel_set_variable_var_check(aleg_session->channel
, "l_sdp_audio_zrtp_hash", aleg_engine->local_sdp_zrtp_hash
, SWITCH_TRUE)
;
275 }
276}
277
278SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_pass_zrtp_hash2(switch_core_session_t *aleg_session, switch_core_session_t *bleg_session)
279{
280 _switch_core_media_pass_zrtp_hash2(aleg_session, bleg_session, SWITCH_MEDIA_TYPE_AUDIO);
281 _switch_core_media_pass_zrtp_hash2(aleg_session, bleg_session, SWITCH_MEDIA_TYPE_VIDEO);
282}
283
284
285SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_pass_zrtp_hash(switch_core_session_t *session)
286{
287 switch_channel_t *channel = switch_core_session_get_channel(session);
288
289 switch_core_session_t *other_session;
290 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 290, (const char*)switch_channel_get_session(channel
)
, SWITCH_LOG_DEBUG1, "Deciding whether to pass zrtp-hash between legs\n");
291 if (!(switch_channel_test_flag(channel, CF_ZRTP_PASSTHRU_REQ))) {
292 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 292, (const char*)switch_channel_get_session(channel
)
, SWITCH_LOG_DEBUG1, "CF_ZRTP_PASSTHRU_REQ not set, so not propagating zrtp-hash\n");
293 return;
294 } else if (!(switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "src/switch_core_media.c", (const char *)__func__, 294)
== SWITCH_STATUS_SUCCESS)) {
295 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 295, (const char*)switch_channel_get_session(channel
)
, SWITCH_LOG_DEBUG1, "No partner channel found, so not propagating zrtp-hash\n");
296 return;
297 } else {
298 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 298, (const char*)switch_channel_get_session(channel
)
, SWITCH_LOG_DEBUG1, "Found peer channel; propagating zrtp-hash if set\n");
299 switch_core_media_pass_zrtp_hash2(session, other_session);
300 switch_core_session_rwunlock(other_session);
301 }
302}
303
304SWITCH_DECLARE(const char *)__attribute__((visibility("default"))) const char * switch_core_media_get_zrtp_hash(switch_core_session_t *session, switch_media_type_t type, switch_bool_t local)
305{
306 switch_rtp_engine_t *engine;
307 if (!session->media_handle) return NULL((void*)0);
308
309 engine = &session->media_handle->engines[type];
310
311 if (local) {
312 return engine->local_sdp_zrtp_hash;
313 }
314
315
316 return engine->remote_sdp_zrtp_hash;
317
318}
319
320static void switch_core_media_find_zrtp_hash(switch_core_session_t *session, sdp_session_t *sdp)
321{
322 switch_channel_t *channel = switch_core_session_get_channel(session);
323 switch_rtp_engine_t *audio_engine;
324 switch_rtp_engine_t *video_engine;
325 sdp_media_t *m;
326 sdp_attribute_t *attr;
327 int got_audio = 0, got_video = 0;
328
329 if (!session->media_handle) return;
330
331 audio_engine = &session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO];
332 video_engine = &session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO];
333
334
335 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 335, (const char*)switch_channel_get_session(channel
)
, SWITCH_LOG_DEBUG1, "Looking for zrtp-hash\n");
336 for (m = sdp->sdp_media; m; m = m->m_next) {
337 if (got_audio && got_video) break;
338 if (m->m_port && ((m->m_type == sdp_media_audio && !got_audio)
339 || (m->m_type == sdp_media_video && !got_video))) {
340 for (attr = m->m_attributes; attr; attr = attr->a_next) {
341 if (zstr(attr->a_name)_zstr(attr->a_name)) continue;
342 if (strcasecmp(attr->a_name, "zrtp-hash") || !(attr->a_value)) continue;
343 if (m->m_type == sdp_media_audio) {
344 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 344, (const char*)switch_channel_get_session(channel
)
, SWITCH_LOG_DEBUG,
345 "Found audio zrtp-hash; setting r_sdp_audio_zrtp_hash=%s\n", attr->a_value);
346 switch_channel_set_variable(channel, "r_sdp_audio_zrtp_hash", attr->a_value)switch_channel_set_variable_var_check(channel, "r_sdp_audio_zrtp_hash"
, attr->a_value, SWITCH_TRUE)
;
347 audio_engine->remote_sdp_zrtp_hash = switch_core_session_strdup(session, attr->a_value)switch_core_perform_session_strdup(session, attr->a_value,
"src/switch_core_media.c", (const char *)__func__, 347)
;
348 got_audio++;
349 } else if (m->m_type == sdp_media_video) {
350 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 350, (const char*)switch_channel_get_session(channel
)
, SWITCH_LOG_DEBUG,
351 "Found video zrtp-hash; setting r_sdp_video_zrtp_hash=%s\n", attr->a_value);
352 switch_channel_set_variable(channel, "r_sdp_video_zrtp_hash", attr->a_value)switch_channel_set_variable_var_check(channel, "r_sdp_video_zrtp_hash"
, attr->a_value, SWITCH_TRUE)
;
353 video_engine->remote_sdp_zrtp_hash = switch_core_session_strdup(session, attr->a_value)switch_core_perform_session_strdup(session, attr->a_value,
"src/switch_core_media.c", (const char *)__func__, 353)
;
354 got_video++;
355 }
356 switch_channel_set_flag(channel, CF_ZRTP_HASH)switch_channel_set_flag_value(channel, CF_ZRTP_HASH, 1);
357 break;
358 }
359 }
360 }
361}
362
363
364static switch_t38_options_t * switch_core_media_process_udptl(switch_core_session_t *session, sdp_session_t *sdp, sdp_media_t *m)
365{
366 switch_t38_options_t *t38_options = switch_channel_get_private(session->channel, "t38_options");
367 sdp_attribute_t *attr;
368
369 if (!t38_options) {
370 t38_options = switch_core_session_alloc(session, sizeof(switch_t38_options_t))switch_core_perform_session_alloc(session, sizeof(switch_t38_options_t
), "src/switch_core_media.c", (const char *)__func__, 370)
;
371
372 // set some default value
373 t38_options->T38FaxVersion = 0;
374 t38_options->T38MaxBitRate = 14400;
375 t38_options->T38FaxRateManagement = switch_core_session_strdup(session, "transferredTCF")switch_core_perform_session_strdup(session, "transferredTCF",
"src/switch_core_media.c", (const char *)__func__, 375)
;
376 t38_options->T38FaxUdpEC = switch_core_session_strdup(session, "t38UDPRedundancy")switch_core_perform_session_strdup(session, "t38UDPRedundancy"
, "src/switch_core_media.c", (const char *)__func__, 376)
;
377 t38_options->T38FaxMaxBuffer = 500;
378 t38_options->T38FaxMaxDatagram = 500;
379 }
380
381 t38_options->remote_port = (switch_port_t)m->m_port;
382
383 if (sdp->sdp_origin) {
384 t38_options->sdp_o_line = switch_core_session_strdup(session, sdp->sdp_origin->o_username)switch_core_perform_session_strdup(session, sdp->sdp_origin
->o_username, "src/switch_core_media.c", (const char *)__func__
, 384)
;
385 } else {
386 t38_options->sdp_o_line = "unknown";
387 }
388
389 if (m->m_connections && m->m_connections->c_address) {
390 t38_options->remote_ip = switch_core_session_strdup(session, m->m_connections->c_address)switch_core_perform_session_strdup(session, m->m_connections
->c_address, "src/switch_core_media.c", (const char *)__func__
, 390)
;
391 } else if (sdp && sdp->sdp_connection && sdp->sdp_connection->c_address) {
392 t38_options->remote_ip = switch_core_session_strdup(session, sdp->sdp_connection->c_address)switch_core_perform_session_strdup(session, sdp->sdp_connection
->c_address, "src/switch_core_media.c", (const char *)__func__
, 392)
;
393 }
394
395 for (attr = m->m_attributes; attr; attr = attr->a_next) {
396 if (!strcasecmp(attr->a_name, "T38FaxVersion") && attr->a_value) {
397 t38_options->T38FaxVersion = (uint16_t) atoi(attr->a_value);
398 } else if (!strcasecmp(attr->a_name, "T38MaxBitRate") && attr->a_value) {
399 t38_options->T38MaxBitRate = (uint32_t) atoi(attr->a_value);
400 } else if (!strcasecmp(attr->a_name, "T38FaxFillBitRemoval")) {
401 t38_options->T38FaxFillBitRemoval = switch_safe_atoi(attr->a_value, 1);
402 } else if (!strcasecmp(attr->a_name, "T38FaxTranscodingMMR")) {
403 t38_options->T38FaxTranscodingMMR = switch_safe_atoi(attr->a_value, 1);
404 } else if (!strcasecmp(attr->a_name, "T38FaxTranscodingJBIG")) {
405 t38_options->T38FaxTranscodingJBIG = switch_safe_atoi(attr->a_value, 1);
406 } else if (!strcasecmp(attr->a_name, "T38FaxRateManagement") && attr->a_value) {
407 t38_options->T38FaxRateManagement = switch_core_session_strdup(session, attr->a_value)switch_core_perform_session_strdup(session, attr->a_value,
"src/switch_core_media.c", (const char *)__func__, 407)
;
408 } else if (!strcasecmp(attr->a_name, "T38FaxMaxBuffer") && attr->a_value) {
409 t38_options->T38FaxMaxBuffer = (uint32_t) atoi(attr->a_value);
410 } else if (!strcasecmp(attr->a_name, "T38FaxMaxDatagram") && attr->a_value) {
411 t38_options->T38FaxMaxDatagram = (uint32_t) atoi(attr->a_value);
412 } else if (!strcasecmp(attr->a_name, "T38FaxUdpEC") && attr->a_value) {
413 t38_options->T38FaxUdpEC = switch_core_session_strdup(session, attr->a_value)switch_core_perform_session_strdup(session, attr->a_value,
"src/switch_core_media.c", (const char *)__func__, 413)
;
414 } else if (!strcasecmp(attr->a_name, "T38VendorInfo") && attr->a_value) {
415 t38_options->T38VendorInfo = switch_core_session_strdup(session, attr->a_value)switch_core_perform_session_strdup(session, attr->a_value,
"src/switch_core_media.c", (const char *)__func__, 415)
;
416 }
417 }
418
419 switch_channel_set_variable(session->channel, "has_t38", "true")switch_channel_set_variable_var_check(session->channel, "has_t38"
, "true", SWITCH_TRUE)
;
420 switch_channel_set_private(session->channel, "t38_options", t38_options);
421 switch_channel_set_app_flag_key("T38", session->channel, CF_APP_T38);
422
423 switch_channel_execute_on(session->channel, "sip_execute_on_image");
424 switch_channel_api_on(session->channel, "sip_api_on_image");
425
426 return t38_options;
427}
428
429
430
431
432
433SWITCH_DECLARE(switch_t38_options_t *)__attribute__((visibility("default"))) switch_t38_options_t * switch_core_media_extract_t38_options(switch_core_session_t *session, const char *r_sdp)
434{
435 sdp_media_t *m;
436 sdp_parser_t *parser = NULL((void*)0);
437 sdp_session_t *sdp;
438 switch_t38_options_t *t38_options = NULL((void*)0);
439
440 if (!(parser = sdp_parse(NULL((void*)0), r_sdp, (int) strlen(r_sdp), 0))) {
441 return NULL((void*)0);
442 }
443
444 if (!(sdp = sdp_session(parser))) {
445 sdp_parser_free(parser);
446 return NULL((void*)0);
447 }
448
449 for (m = sdp->sdp_media; m; m = m->m_next) {
450 if (m->m_proto == sdp_proto_udptl && m->m_type == sdp_media_image && m->m_port) {
451 t38_options = switch_core_media_process_udptl(session, sdp, m);
452 break;
453 }
454 }
455
456 sdp_parser_free(parser);
457
458 return t38_options;
459
460}
461
462
463
464//?
465SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_media_process_t38_passthru(switch_core_session_t *session,
466 switch_core_session_t *other_session, switch_t38_options_t *t38_options)
467{
468 char *remote_host;
469 switch_port_t remote_port;
470 char tmp[32] = "";
471 switch_rtp_engine_t *a_engine;
472 switch_media_handle_t *smh;
473
474 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 474, __PRETTY_FUNCTION__))
;
475
476 if (!(smh = session->media_handle)) {
477 return SWITCH_STATUS_FALSE;
478 }
479
480 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
481
482 remote_host = switch_rtp_get_remote_host(a_engine->rtp_session);
483 remote_port = switch_rtp_get_remote_port(a_engine->rtp_session);
484
485 a_engine->cur_payload_map->remote_sdp_ip = switch_core_session_strdup(session, t38_options->remote_ip)switch_core_perform_session_strdup(session, t38_options->remote_ip
, "src/switch_core_media.c", (const char *)__func__, 485)
;
486 a_engine->cur_payload_map->remote_sdp_port = t38_options->remote_port;
487
488 if (remote_host && remote_port && !strcmp(remote_host, a_engine->cur_payload_map->remote_sdp_ip)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(remote_host) && __builtin_constant_p (a_engine->
cur_payload_map->remote_sdp_ip) && (__s1_len = __builtin_strlen
(remote_host), __s2_len = __builtin_strlen (a_engine->cur_payload_map
->remote_sdp_ip), (!((size_t)(const void *)((remote_host) +
1) - (size_t)(const void *)(remote_host) == 1) || __s1_len >=
4) && (!((size_t)(const void *)((a_engine->cur_payload_map
->remote_sdp_ip) + 1) - (size_t)(const void *)(a_engine->
cur_payload_map->remote_sdp_ip) == 1) || __s2_len >= 4)
) ? __builtin_strcmp (remote_host, a_engine->cur_payload_map
->remote_sdp_ip) : (__builtin_constant_p (remote_host) &&
((size_t)(const void *)((remote_host) + 1) - (size_t)(const void
*)(remote_host) == 1) && (__s1_len = __builtin_strlen
(remote_host), __s1_len < 4) ? (__builtin_constant_p (a_engine
->cur_payload_map->remote_sdp_ip) && ((size_t)(
const void *)((a_engine->cur_payload_map->remote_sdp_ip
) + 1) - (size_t)(const void *)(a_engine->cur_payload_map->
remote_sdp_ip) == 1) ? __builtin_strcmp (remote_host, a_engine
->cur_payload_map->remote_sdp_ip) : (__extension__ ({ const
unsigned char *__s2 = (const unsigned char *) (const char *)
(a_engine->cur_payload_map->remote_sdp_ip); int __result
= (((const unsigned char *) (const char *) (remote_host))[0]
- __s2[0]); if (__s1_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) (remote_host))[1]
- __s2[1]); if (__s1_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) (remote_host))[2]
- __s2[2]); if (__s1_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) (remote_host))[3]
- __s2[3]); } } __result; }))) : (__builtin_constant_p (a_engine
->cur_payload_map->remote_sdp_ip) && ((size_t)(
const void *)((a_engine->cur_payload_map->remote_sdp_ip
) + 1) - (size_t)(const void *)(a_engine->cur_payload_map->
remote_sdp_ip) == 1) && (__s2_len = __builtin_strlen (
a_engine->cur_payload_map->remote_sdp_ip), __s2_len <
4) ? (__builtin_constant_p (remote_host) && ((size_t
)(const void *)((remote_host) + 1) - (size_t)(const void *)(remote_host
) == 1) ? __builtin_strcmp (remote_host, a_engine->cur_payload_map
->remote_sdp_ip) : (- (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) (remote_host)
; int __result = (((const unsigned char *) (const char *) (a_engine
->cur_payload_map->remote_sdp_ip))[0] - __s2[0]); if (__s2_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (a_engine->cur_payload_map->remote_sdp_ip
))[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (a_engine
->cur_payload_map->remote_sdp_ip))[2] - __s2[2]); if (__s2_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) (a_engine->cur_payload_map->remote_sdp_ip
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (remote_host
, a_engine->cur_payload_map->remote_sdp_ip)))); })
&&
489 remote_port == a_engine->cur_payload_map->remote_sdp_port) {
490 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 490, (const char*)(session)
, SWITCH_LOG_DEBUG,
491 "Audio params are unchanged for %s.\n",
492 switch_channel_get_name(session->channel));
493 } else {
494 const char *err = NULL((void*)0);
495
496 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 496, (const char*)(session)
, SWITCH_LOG_DEBUG,
497 "Audio params changed for %s from %s:%d to %s:%d\n",
498 switch_channel_get_name(session->channel),
499 remote_host, remote_port, a_engine->cur_payload_map->remote_sdp_ip, a_engine->cur_payload_map->remote_sdp_port);
500
501 switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->cur_payload_map->remote_sdp_port);
502 switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, a_engine->cur_payload_map->remote_sdp_ip)switch_channel_set_variable_var_check(session->channel, "remote_media_ip"
, a_engine->cur_payload_map->remote_sdp_ip, SWITCH_TRUE
)
;
503 switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp)switch_channel_set_variable_var_check(session->channel, "remote_media_port"
, tmp, SWITCH_TRUE)
;
504 if (switch_rtp_set_remote_address(a_engine->rtp_session, a_engine->cur_payload_map->remote_sdp_ip,
505 a_engine->cur_payload_map->remote_sdp_port, 0, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
506 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 506, (const char*)(session)
, SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", err);
507 switch_channel_hangup(session->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)switch_channel_perform_hangup(session->channel, "src/switch_core_media.c"
, (const char *)__func__, 507, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION
)
;
508 }
509 }
510
511 switch_core_media_copy_t38_options(t38_options, other_session);
512
513 return SWITCH_STATUS_SUCCESS;
514
515}
516
517SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_get_payload_code(switch_core_session_t *session,
518 switch_media_type_t type,
519 const char *iananame,
520 uint32_t rate,
521 switch_payload_t *ptP,
522 switch_payload_t *recv_ptP,
523 char **fmtpP)
524{
525 payload_map_t *pmap;
526 switch_media_handle_t *smh;
527 switch_rtp_engine_t *engine;
528 switch_payload_t pt = 0, recv_pt = 0;
529 int found = 0;
530 char *fmtp = NULL((void*)0);
531
532 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 532, __PRETTY_FUNCTION__))
;
533
534 if (!(smh = session->media_handle)) {
535 return SWITCH_STATUS_FALSE;
536 }
537
538 engine = &smh->engines[type];
539
540 switch_mutex_lock(smh->sdp_mutex);
541 for (pmap = engine->payload_map; pmap ; pmap = pmap->next) {
542
543 if (!pmap->allocated) continue;
544
545 if (!strcasecmp(pmap->iananame, iananame) && (!rate || (rate == pmap->rate))) {
546 pt = pmap->pt;
547 recv_pt = pmap->recv_pt;
548 fmtp = pmap->rm_fmtp;
549 found++;
550 break;
551 }
552 }
553 switch_mutex_unlock(smh->sdp_mutex);
554
555 if (found) {
556 if (ptP) {
557 *ptP = pt;
558 }
559 if (recv_ptP) {
560 *recv_ptP = recv_pt;
561 }
562
563 if (!zstr(fmtp)_zstr(fmtp) && fmtpP) {
564 *fmtpP = fmtp;
565 }
566
567 return SWITCH_STATUS_SUCCESS;
568 }
569
570 return SWITCH_STATUS_FALSE;
571
572}
573
574
575SWITCH_DECLARE(payload_map_t *)__attribute__((visibility("default"))) payload_map_t * switch_core_media_add_payload_map(switch_core_session_t *session,
576 switch_media_type_t type,
577 const char *name,
578 const char *fmtp,
579 switch_sdp_type_t sdp_type,
580 uint32_t pt,
581 uint32_t rate,
582 uint32_t ptime,
583 uint32_t channels,
584 uint8_t negotiated)
585{
586 payload_map_t *pmap;
587 int exists = 0;
588 switch_media_handle_t *smh;
589 switch_rtp_engine_t *engine;
590 int local_pt = 0;
591
592 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 592, __PRETTY_FUNCTION__))
;
593
594 if (!(smh = session->media_handle)) {
595 return NULL((void*)0);
596 }
597
598 engine = &smh->engines[type];
599
600 switch_mutex_lock(smh->sdp_mutex);
601
602
603 for (pmap = engine->payload_map; pmap && pmap->allocated; pmap = pmap->next) {
604 exists = (!strcasecmp(name, pmap->iananame) && (!pmap->rate || rate == pmap->rate) && (!pmap->ptime || pmap->ptime == ptime));
605
606 if (exists) {
607
608 if (!zstr(fmtp)_zstr(fmtp) && !zstr(pmap->rm_fmtp)_zstr(pmap->rm_fmtp)) {
609 if (strcmp(pmap->rm_fmtp, fmtp)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(pmap->rm_fmtp) && __builtin_constant_p (fmtp) &&
(__s1_len = __builtin_strlen (pmap->rm_fmtp), __s2_len = __builtin_strlen
(fmtp), (!((size_t)(const void *)((pmap->rm_fmtp) + 1) - (
size_t)(const void *)(pmap->rm_fmtp) == 1) || __s1_len >=
4) && (!((size_t)(const void *)((fmtp) + 1) - (size_t
)(const void *)(fmtp) == 1) || __s2_len >= 4)) ? __builtin_strcmp
(pmap->rm_fmtp, fmtp) : (__builtin_constant_p (pmap->rm_fmtp
) && ((size_t)(const void *)((pmap->rm_fmtp) + 1) -
(size_t)(const void *)(pmap->rm_fmtp) == 1) && (__s1_len
= __builtin_strlen (pmap->rm_fmtp), __s1_len < 4) ? (__builtin_constant_p
(fmtp) && ((size_t)(const void *)((fmtp) + 1) - (size_t
)(const void *)(fmtp) == 1) ? __builtin_strcmp (pmap->rm_fmtp
, fmtp) : (__extension__ ({ const unsigned char *__s2 = (const
unsigned char *) (const char *) (fmtp); int __result = (((const
unsigned char *) (const char *) (pmap->rm_fmtp))[0] - __s2
[0]); if (__s1_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) (pmap->rm_fmtp
))[1] - __s2[1]); if (__s1_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (pmap
->rm_fmtp))[2] - __s2[2]); if (__s1_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) (pmap
->rm_fmtp))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(fmtp) && ((size_t)(const void *)((fmtp) + 1) - (size_t
)(const void *)(fmtp) == 1) && (__s2_len = __builtin_strlen
(fmtp), __s2_len < 4) ? (__builtin_constant_p (pmap->rm_fmtp
) && ((size_t)(const void *)((pmap->rm_fmtp) + 1) -
(size_t)(const void *)(pmap->rm_fmtp) == 1) ? __builtin_strcmp
(pmap->rm_fmtp, fmtp) : (- (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (pmap->
rm_fmtp); int __result = (((const unsigned char *) (const char
*) (fmtp))[0] - __s2[0]); if (__s2_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
fmtp))[1] - __s2[1]); if (__s2_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
fmtp))[2] - __s2[2]); if (__s2_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) (fmtp
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (pmap
->rm_fmtp, fmtp)))); })
) {
610 exists = 0;
611 local_pt = pmap->pt;
612 continue;
613 }
614 }
615
616 break;
617 }
618 }
619
620
621 if (!exists) {
622 switch_ssize_t hlen = -1;
623
624 if (engine->payload_map && !engine->payload_map->allocated) {
625 pmap = engine->payload_map;
626 } else {
627 pmap = switch_core_alloc(session->pool, sizeof(*pmap))switch_core_perform_alloc(session->pool, sizeof(*pmap), "src/switch_core_media.c"
, (const char *)__func__, 627)
;
628 }
629
630 pmap->type = type;
631 pmap->iananame = switch_core_strdup(session->pool, name)switch_core_perform_strdup(session->pool, name, "src/switch_core_media.c"
, (const char *)__func__, 631)
;
632 pmap->rm_encoding = pmap->iananame;
633 pmap->hash = switch_ci_hashfunc_default(pmap->iananame, &hlen);
634 pmap->channels = 1;
635 }
636
637 pmap->sdp_type = sdp_type;
638
639 if (ptime) {
640 pmap->ptime = ptime;
641 }
642
643 if (rate) {
644 pmap->rate = rate;
645 }
646
647 if (channels) {
648 pmap->channels = channels;
649 }
650
651 if (!zstr(fmtp)_zstr(fmtp) && (zstr(pmap->rm_fmtp)_zstr(pmap->rm_fmtp) || strcmp(pmap->rm_fmtp, fmtp)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(pmap->rm_fmtp) && __builtin_constant_p (fmtp) &&
(__s1_len = __builtin_strlen (pmap->rm_fmtp), __s2_len = __builtin_strlen
(fmtp), (!((size_t)(const void *)((pmap->rm_fmtp) + 1) - (
size_t)(const void *)(pmap->rm_fmtp) == 1) || __s1_len >=
4) && (!((size_t)(const void *)((fmtp) + 1) - (size_t
)(const void *)(fmtp) == 1) || __s2_len >= 4)) ? __builtin_strcmp
(pmap->rm_fmtp, fmtp) : (__builtin_constant_p (pmap->rm_fmtp
) && ((size_t)(const void *)((pmap->rm_fmtp) + 1) -
(size_t)(const void *)(pmap->rm_fmtp) == 1) && (__s1_len
= __builtin_strlen (pmap->rm_fmtp), __s1_len < 4) ? (__builtin_constant_p
(fmtp) && ((size_t)(const void *)((fmtp) + 1) - (size_t
)(const void *)(fmtp) == 1) ? __builtin_strcmp (pmap->rm_fmtp
, fmtp) : (__extension__ ({ const unsigned char *__s2 = (const
unsigned char *) (const char *) (fmtp); int __result = (((const
unsigned char *) (const char *) (pmap->rm_fmtp))[0] - __s2
[0]); if (__s1_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) (pmap->rm_fmtp
))[1] - __s2[1]); if (__s1_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (pmap
->rm_fmtp))[2] - __s2[2]); if (__s1_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) (pmap
->rm_fmtp))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(fmtp) && ((size_t)(const void *)((fmtp) + 1) - (size_t
)(const void *)(fmtp) == 1) && (__s2_len = __builtin_strlen
(fmtp), __s2_len < 4) ? (__builtin_constant_p (pmap->rm_fmtp
) && ((size_t)(const void *)((pmap->rm_fmtp) + 1) -
(size_t)(const void *)(pmap->rm_fmtp) == 1) ? __builtin_strcmp
(pmap->rm_fmtp, fmtp) : (- (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (pmap->
rm_fmtp); int __result = (((const unsigned char *) (const char
*) (fmtp))[0] - __s2[0]); if (__s2_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
fmtp))[1] - __s2[1]); if (__s2_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
fmtp))[2] - __s2[2]); if (__s2_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) (fmtp
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (pmap
->rm_fmtp, fmtp)))); })
)) {
652 pmap->rm_fmtp = switch_core_strdup(session->pool, fmtp)switch_core_perform_strdup(session->pool, fmtp, "src/switch_core_media.c"
, (const char *)__func__, 652)
;
653 }
654
655 pmap->allocated = 1;
656
657
658 pmap->recv_pt = (switch_payload_t) pt;
659
660
661 if (sdp_type == SDP_TYPE_REQUEST || !exists) {
662 pmap->pt = (switch_payload_t) (local_pt ? local_pt : pt);
663 }
664
665 if (negotiated) {
666 pmap->negotiated = negotiated;
667 }
668
669 if (!exists) {
670 if (pmap == engine->payload_map) {
671 engine->pmap_tail = pmap;
672 } else if (!engine->payload_map) {
673 engine->payload_map = engine->pmap_tail = pmap;
674 } else {
675 engine->pmap_tail->next = pmap;
676 engine->pmap_tail = engine->pmap_tail->next;
677 }
678 }
679
680 switch_mutex_unlock(smh->sdp_mutex);
681
682 return pmap;
683}
684
685
686
687
688SWITCH_DECLARE(const char *)__attribute__((visibility("default"))) const char *switch_core_media_get_codec_string(switch_core_session_t *session)
689{
690 const char *preferred = NULL((void*)0), *fallback = NULL((void*)0);
691 switch_media_handle_t *smh;
692
693 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 693, __PRETTY_FUNCTION__))
;
694
695 if (!(smh = session->media_handle)) {
696 preferred = "PCMU";
697 fallback = "PCMU";
698 } else {
699
700 if (!(preferred = switch_channel_get_variable(session->channel, "absolute_codec_string")switch_channel_get_variable_dup(session->channel, "absolute_codec_string"
, SWITCH_TRUE, -1)
)) {
701 preferred = switch_channel_get_variable(session->channel, "codec_string")switch_channel_get_variable_dup(session->channel, "codec_string"
, SWITCH_TRUE, -1)
;
702 }
703
704 if (!preferred) {
705 if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
706 preferred = smh->mparams->outbound_codec_string;
707 fallback = smh->mparams->inbound_codec_string;
708
709 } else {
710 preferred = smh->mparams->inbound_codec_string;
711 fallback = smh->mparams->outbound_codec_string;
712 }
713 }
714 }
715
716 return !zstr(preferred)_zstr(preferred) ? preferred : fallback;
717}
718
719SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_session_clear_crypto(switch_core_session_t *session)
720{
721 int i;
722 switch_media_handle_t *smh;
723
724 const char *vars[] = { "rtp_last_audio_local_crypto_key",
725 "srtp_remote_audio_crypto_key",
726 "srtp_remote_audio_crypto_tag",
727 "srtp_remote_audio_crypto_type",
728 "srtp_remote_video_crypto_key",
729 "srtp_remote_video_crypto_tag",
730 "srtp_remote_video_crypto_type",
731 "rtp_secure_media",
732 "rtp_secure_media_inbound",
733 "rtp_secure_media_outbound",
734 NULL((void*)0)};
735
736 for(i = 0; vars[i] ;i++) {
737 switch_channel_set_variable(session->channel, vars[i], NULL)switch_channel_set_variable_var_check(session->channel, vars
[i], ((void*)0), SWITCH_TRUE)
;
738 }
739
740 if (!(smh = session->media_handle)) {
741 return;
742 }
743 for (i = 0; i < CRYPTO_INVALID; i++) {
744 memset(&smh->engines[SWITCH_MEDIA_TYPE_AUDIO].ssec[i], 0, sizeof(smh->engines[SWITCH_MEDIA_TYPE_AUDIO].ssec[i]));
745 memset(&smh->engines[SWITCH_MEDIA_TYPE_VIDEO].ssec[i], 0, sizeof(smh->engines[SWITCH_MEDIA_TYPE_VIDEO].ssec[i]));
746 }
747
748}
749
750SWITCH_DECLARE(const char *)__attribute__((visibility("default"))) const char * switch_core_session_local_crypto_key(switch_core_session_t *session, switch_media_type_t type)
751{
752 if (!session->media_handle) {
753 return NULL((void*)0);
754 }
755
756 return session->media_handle->engines[type].ssec[session->media_handle->engines[type].crypto_type].local_crypto_key;
757}
758
759
760
761SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_parse_rtp_bugs(switch_rtp_bug_flag_t *flag_pole, const char *str)
762{
763
764 if (switch_stristr("clear", str)) {
765 *flag_pole = 0;
766 }
767
768 if (switch_stristr("CISCO_SKIP_MARK_BIT_2833", str)) {
769 *flag_pole |= RTP_BUG_CISCO_SKIP_MARK_BIT_2833;
770 }
771
772 if (switch_stristr("~CISCO_SKIP_MARK_BIT_2833", str)) {
773 *flag_pole &= ~RTP_BUG_CISCO_SKIP_MARK_BIT_2833;
774 }
775
776 if (switch_stristr("SONUS_SEND_INVALID_TIMESTAMP_2833", str)) {
777 *flag_pole |= RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833;
778 }
779
780 if (switch_stristr("~SONUS_SEND_INVALID_TIMESTAMP_2833", str)) {
781 *flag_pole &= ~RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833;
782 }
783
784 if (switch_stristr("IGNORE_MARK_BIT", str)) {
785 *flag_pole |= RTP_BUG_IGNORE_MARK_BIT;
786 }
787
788 if (switch_stristr("~IGNORE_MARK_BIT", str)) {
789 *flag_pole &= ~RTP_BUG_IGNORE_MARK_BIT;
790 }
791
792 if (switch_stristr("SEND_LINEAR_TIMESTAMPS", str)) {
793 *flag_pole |= RTP_BUG_SEND_LINEAR_TIMESTAMPS;
794 }
795
796 if (switch_stristr("~SEND_LINEAR_TIMESTAMPS", str)) {
797 *flag_pole &= ~RTP_BUG_SEND_LINEAR_TIMESTAMPS;
798 }
799
800 if (switch_stristr("START_SEQ_AT_ZERO", str)) {
801 *flag_pole |= RTP_BUG_START_SEQ_AT_ZERO;
802 }
803
804 if (switch_stristr("~START_SEQ_AT_ZERO", str)) {
805 *flag_pole &= ~RTP_BUG_START_SEQ_AT_ZERO;
806 }
807
808 if (switch_stristr("NEVER_SEND_MARKER", str)) {
809 *flag_pole |= RTP_BUG_NEVER_SEND_MARKER;
810 }
811
812 if (switch_stristr("~NEVER_SEND_MARKER", str)) {
813 *flag_pole &= ~RTP_BUG_NEVER_SEND_MARKER;
814 }
815
816 if (switch_stristr("IGNORE_DTMF_DURATION", str)) {
817 *flag_pole |= RTP_BUG_IGNORE_DTMF_DURATION;
818 }
819
820 if (switch_stristr("~IGNORE_DTMF_DURATION", str)) {
821 *flag_pole &= ~RTP_BUG_IGNORE_DTMF_DURATION;
822 }
823
824 if (switch_stristr("ACCEPT_ANY_PACKETS", str)) {
825 *flag_pole |= RTP_BUG_ACCEPT_ANY_PACKETS;
826 }
827
828 if (switch_stristr("~ACCEPT_ANY_PACKETS", str)) {
829 *flag_pole &= ~RTP_BUG_ACCEPT_ANY_PACKETS;
830 }
831
832 if (switch_stristr("ACCEPT_ANY_PAYLOAD", str)) {
833 *flag_pole |= RTP_BUG_ACCEPT_ANY_PAYLOAD;
834 }
835
836 if (switch_stristr("~ACCEPT_ANY_PAYLOAD", str)) {
837 *flag_pole &= ~RTP_BUG_ACCEPT_ANY_PAYLOAD;
838 }
839
840 if (switch_stristr("GEN_ONE_GEN_ALL", str)) {
841 *flag_pole |= RTP_BUG_GEN_ONE_GEN_ALL;
842 }
843
844 if (switch_stristr("~GEN_ONE_GEN_ALL", str)) {
845 *flag_pole &= ~RTP_BUG_GEN_ONE_GEN_ALL;
846 }
847
848 if (switch_stristr("CHANGE_SSRC_ON_MARKER", str)) {
849 *flag_pole |= RTP_BUG_CHANGE_SSRC_ON_MARKER;
850 }
851
852 if (switch_stristr("~CHANGE_SSRC_ON_MARKER", str)) {
853 *flag_pole &= ~RTP_BUG_CHANGE_SSRC_ON_MARKER;
854 }
855
856 if (switch_stristr("FLUSH_JB_ON_DTMF", str)) {
857 *flag_pole |= RTP_BUG_FLUSH_JB_ON_DTMF;
858 }
859
860 if (switch_stristr("~FLUSH_JB_ON_DTMF", str)) {
861 *flag_pole &= ~RTP_BUG_FLUSH_JB_ON_DTMF;
862 }
863
864 if (switch_stristr("ALWAYS_AUTO_ADJUST", str)) {
865 *flag_pole |= (RTP_BUG_ALWAYS_AUTO_ADJUST | RTP_BUG_ACCEPT_ANY_PACKETS);
866 }
867
868 if (switch_stristr("~ALWAYS_AUTO_ADJUST", str)) {
869 *flag_pole &= ~(RTP_BUG_ALWAYS_AUTO_ADJUST | RTP_BUG_ACCEPT_ANY_PACKETS);
870 }
871}
872
873
874static switch_status_t switch_core_media_build_crypto(switch_media_handle_t *smh,
875 switch_media_type_t type,
876 int index, switch_rtp_crypto_key_type_t ctype, switch_rtp_crypto_direction_t direction, int force)
877{
878 unsigned char b64_key[512] = "";
879 unsigned char *key;
880 const char *val;
881 switch_channel_t *channel;
882 char *p;
883 switch_rtp_engine_t *engine;
884
885 switch_assert(smh)((smh) ? (void) (0) : __assert_fail ("smh", "src/switch_core_media.c"
, 885, __PRETTY_FUNCTION__))
;
886 channel = switch_core_session_get_channel(smh->session);
887
888 engine = &smh->engines[type];
889
890 if (!force && engine->ssec[ctype].local_raw_key[0]) {
891 return SWITCH_STATUS_SUCCESS;
892 }
893
894
895
896//#define SAME_KEY
897#ifdef SAME_KEY
898 if (switch_channel_test_flag(channel, CF_WEBRTC) && type == SWITCH_MEDIA_TYPE_VIDEO) {
899 if (direction == SWITCH_RTP_CRYPTO_SEND) {
900 memcpy(engine->ssec[ctype].local_raw_key, smh->engines[SWITCH_MEDIA_TYPE_AUDIO].ssec.local_raw_key, SUITES[ctype].keylen);
901 key = engine->ssec[ctype].local_raw_key;
902 } else {
903 memcpy(engine->ssec[ctype].remote_raw_key, smh->engines[SWITCH_MEDIA_TYPE_AUDIO].ssec.remote_raw_key, SUITES[ctype].keylen);
904 key = engine->ssec[ctype].remote_raw_key;
905 }
906 } else {
907#endif
908 if (direction == SWITCH_RTP_CRYPTO_SEND) {
909 key = engine->ssec[ctype].local_raw_key;
910 } else {
911 key = engine->ssec[ctype].remote_raw_key;
912 }
913
914 switch_rtp_get_random(key, SUITES[ctype].keylen);
915#ifdef SAME_KEY
916 }
917#endif
918
919 switch_b64_encode(key, SUITES[ctype].keylen, b64_key, sizeof(b64_key));
920 p = strrchr((char *) b64_key, '=');
921
922 while (p && *p && *p == '=') {
923 *p-- = '\0';
924 }
925
926 if (!index) index = ctype + 1;
927
928 engine->ssec[ctype].local_crypto_key = switch_core_session_sprintf(smh->session, "%d %s inline:%s", index, SUITES[ctype].name, b64_key);
929 switch_channel_set_variable_name_printf(smh->session->channel, engine->ssec[ctype].local_crypto_key, "rtp_last_%s_local_crypto_key", type2str(type)type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio");
930 switch_channel_set_flag(smh->session->channel, CF_SECURE)switch_channel_set_flag_value(smh->session->channel, CF_SECURE
, 1)
;
931
932 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 932, (const char*)(smh->session)
, SWITCH_LOG_DEBUG, "Set Local %s crypto Key [%s]\n",
933 type2str(type)type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio",
934 engine->ssec[ctype].local_crypto_key);
935
936 if (!(smh->mparams->ndlb & SM_NDLB_DISABLE_SRTP_AUTH) &&
937 !((val = switch_channel_get_variable(channel, "NDLB_support_asterisk_missing_srtp_auth")switch_channel_get_variable_dup(channel, "NDLB_support_asterisk_missing_srtp_auth"
, SWITCH_TRUE, -1)
) && switch_true(val))) {
938 engine->ssec[ctype].crypto_type = ctype;
939 } else {
940 engine->ssec[ctype].crypto_type = AES_CM_128_NULL_AUTH;
941 }
942
943 return SWITCH_STATUS_SUCCESS;
944}
945
946
947
948
949
950switch_status_t switch_core_media_add_crypto(switch_secure_settings_t *ssec, const char *key_str, switch_rtp_crypto_direction_t direction)
951{
952 unsigned char key[SWITCH_RTP_MAX_CRYPTO_LEN64];
953 switch_rtp_crypto_key_type_t type;
954 char *p;
955
956
957 p = strchr(key_str, ' ')(__extension__ (__builtin_constant_p (' ') && !__builtin_constant_p
(key_str) && (' ') == '\0' ? (char *) __rawmemchr (key_str
, ' ') : __builtin_strchr (key_str, ' ')))
;
958
959 if (p && *p && *(p + 1)) {
960 p++;
961
962 type = switch_core_media_crypto_str2type(p);
963
964 if (type == CRYPTO_INVALID) {
965 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_media.c", (const char
*)__func__, 965, ((void*)0)
, SWITCH_LOG_ERROR, "Parse Error near [%s]\n", p);
966 goto bad;
967 }
968
969 p = strchr(p, ' ')(__extension__ (__builtin_constant_p (' ') && !__builtin_constant_p
(p) && (' ') == '\0' ? (char *) __rawmemchr (p, ' ')
: __builtin_strchr (p, ' ')))
;
970 if (p && *p && *(p + 1)) {
971 p++;
972 if (strncasecmp(p, "inline:", 7)) {
973 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_media.c", (const char
*)__func__, 973, ((void*)0)
, SWITCH_LOG_ERROR, "Parse Error near [%s]\n", p);
974 goto bad;
975 }
976
977 p += 7;
978 switch_b64_decode(p, (char *) key, sizeof(key));
979
980 if (direction == SWITCH_RTP_CRYPTO_SEND) {
981 memcpy(ssec->local_raw_key, key, SUITES[type].keylen);
982 } else {
983 memcpy(ssec->remote_raw_key, key, SUITES[type].keylen);
984 }
985 return SWITCH_STATUS_SUCCESS;
986 }
987
988 }
989
990 bad:
991
992 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_media.c", (const char
*)__func__, 992, ((void*)0)
, SWITCH_LOG_ERROR, "Error!\n");
993 return SWITCH_STATUS_FALSE;
994
995}
996
997SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_set_rtp_session(switch_core_session_t *session, switch_media_type_t type, switch_rtp_t *rtp_session)
998{
999 switch_rtp_engine_t *engine;
1000 if (!session->media_handle) return;
1001 engine = &session->media_handle->engines[type];
1002 engine->rtp_session = rtp_session;
1003 engine->type = type;
1004}
1005
1006
1007static void switch_core_session_get_recovery_crypto_key(switch_core_session_t *session, switch_media_type_t type)
1008{
1009 const char *tmp;
1010 switch_rtp_engine_t *engine;
1011 char *keyvar, *tagvar, *ctypevar;
1012
1013 if (!session->media_handle) return;
1014 engine = &session->media_handle->engines[type];
1015
1016 if (type == SWITCH_MEDIA_TYPE_AUDIO) {
1017 keyvar = "srtp_remote_audio_crypto_key";
1018 tagvar = "srtp_remote_audio_crypto_tag";
1019 ctypevar = "srtp_remote_audio_crypto_type";
1020 } else {
1021 keyvar = "srtp_remote_video_crypto_key";
1022 tagvar = "srtp_remote_video_crypto_tag";
1023 ctypevar = "srtp_remote_video_crypto_type";
1024 }
1025
1026 if ((tmp = switch_channel_get_variable(session->channel, keyvar)switch_channel_get_variable_dup(session->channel, keyvar, SWITCH_TRUE
, -1)
)) {
1027 if ((tmp = switch_channel_get_variable(session->channel, ctypevar)switch_channel_get_variable_dup(session->channel, ctypevar
, SWITCH_TRUE, -1)
)) {
1028 engine->crypto_type = switch_core_media_crypto_str2type(tmp);
1029 }
1030
1031 engine->ssec[engine->crypto_type].remote_crypto_key = switch_core_session_strdup(session, tmp)switch_core_perform_session_strdup(session, tmp, "src/switch_core_media.c"
, (const char *)__func__, 1031)
;
1032
1033 if ((tmp = switch_channel_get_variable(session->channel, tagvar)switch_channel_get_variable_dup(session->channel, tagvar, SWITCH_TRUE
, -1)
)) {
1034 int tv = atoi(tmp);
1035 engine->ssec[engine->crypto_type].crypto_tag = tv;
1036 } else {
1037 engine->ssec[engine->crypto_type].crypto_tag = 1;
1038 }
1039
1040 switch_channel_set_flag(session->channel, CF_SECURE)switch_channel_set_flag_value(session->channel, CF_SECURE,
1)
;
1041 }
1042}
1043
1044
1045static void switch_core_session_apply_crypto(switch_core_session_t *session, switch_media_type_t type)
1046{
1047 switch_rtp_engine_t *engine;
1048 const char *varname;
1049
1050 if (type == SWITCH_MEDIA_TYPE_AUDIO) {
1051 varname = "rtp_secure_audio_confirmed";
1052 } else {
1053 varname = "rtp_secure_video_confirmed";
1054 }
1055
1056 if (!session->media_handle) return;
1057
1058 engine = &session->media_handle->engines[type];
1059
1060 if (switch_channel_test_flag(session->channel, CF_RECOVERING)) {
1061 return;
1062 }
1063
1064 if (engine->ssec[engine->crypto_type].remote_crypto_key && switch_channel_test_flag(session->channel, CF_SECURE)) {
1065 switch_core_media_add_crypto(&engine->ssec[engine->crypto_type], engine->ssec[engine->crypto_type].remote_crypto_key, SWITCH_RTP_CRYPTO_RECV);
1066
1067
1068 switch_rtp_add_crypto_key(engine->rtp_session, SWITCH_RTP_CRYPTO_SEND, 1,
1069 engine->ssec[engine->crypto_type].crypto_type,
1070 engine->ssec[engine->crypto_type].local_raw_key,
1071 SUITES[engine->ssec[engine->crypto_type].crypto_type].keylen);
1072
1073 switch_rtp_add_crypto_key(engine->rtp_session, SWITCH_RTP_CRYPTO_RECV,
1074 engine->ssec[engine->crypto_type].crypto_tag,
1075 engine->ssec[engine->crypto_type].crypto_type,
1076 engine->ssec[engine->crypto_type].remote_raw_key,
1077 SUITES[engine->ssec[engine->crypto_type].crypto_type].keylen);
1078
1079 switch_channel_set_variable(session->channel, varname, "true")switch_channel_set_variable_var_check(session->channel, varname
, "true", SWITCH_TRUE)
;
1080
1081
1082 switch_channel_set_variable(session->channel, "rtp_secure_media_negotiated", SUITES[engine->crypto_type].name)switch_channel_set_variable_var_check(session->channel, "rtp_secure_media_negotiated"
, SUITES[engine->crypto_type].name, SWITCH_TRUE)
;
1083
1084 }
1085
1086}
1087
1088static void switch_core_session_parse_crypto_prefs(switch_core_session_t *session)
1089{
1090 const char *var = NULL((void*)0);
1091 const char *val = NULL((void*)0);
1092 char *suites = NULL((void*)0);
1093 switch_media_handle_t *smh;
1094 char *fields[CRYPTO_INVALID+1];
1095 int argc = 0, i = 0, j = 0, k = 0;
1096
1097 if (!(smh = session->media_handle)) {
1098 return;
1099 }
1100
1101 if (switch_channel_test_flag(session->channel, CF_WEBRTC)) {
1102 return;
1103 }
1104
1105 if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
1106 var = "rtp_secure_media_inbound";
1107 } else {
1108 var = "rtp_secure_media_outbound";
1109 }
1110
1111 if (!(val = switch_channel_get_variable(session->channel, var)switch_channel_get_variable_dup(session->channel, var, SWITCH_TRUE
, -1)
)) {
1112 var = "rtp_secure_media";
1113 val = switch_channel_get_variable(session->channel, var)switch_channel_get_variable_dup(session->channel, var, SWITCH_TRUE
, -1)
;
1114 }
1115
1116 if (!zstr(val)_zstr(val) && (suites = strchr(val, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(val) && (':') == '\0' ? (char *) __rawmemchr (val, ':'
) : __builtin_strchr (val, ':')))
)) {
1117 *suites++ = '\0';
1118 }
1119
1120 if (zstr(suites)_zstr(suites)) {
1121 suites = (char *) switch_channel_get_variable(session->channel, "rtp_secure_media_suites")switch_channel_get_variable_dup(session->channel, "rtp_secure_media_suites"
, SWITCH_TRUE, -1)
;
1122 }
1123
1124 if (zstr(val)_zstr(val)) {
1125 if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_INBOUND && !switch_channel_test_flag(session->channel, CF_RECOVERING)) {
1126 val = "optional";
1127 } else {
1128 val = "forbidden";
1129 }
1130 }
1131
1132 if (!strcasecmp(val, "optional")) {
1133 smh->crypto_mode = CRYPTO_MODE_OPTIONAL;
1134 } else if (switch_true(val) || !strcasecmp(val, "mandatory")) {
1135 smh->crypto_mode = CRYPTO_MODE_MANDATORY;
1136 } else {
1137 smh->crypto_mode = CRYPTO_MODE_FORBIDDEN;
1138 if (!switch_false(val) && strcasecmp(val, "forbidden")) {
1139 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 1139, (const char*)(session)
, SWITCH_LOG_WARNING, "INVALID VALUE FOR %s defaulting to 'forbidden'\n", var);
1140 }
1141 }
1142
1143 if (smh->crypto_mode != CRYPTO_MODE_FORBIDDEN && !zstr(suites)_zstr(suites)) {
1144 argc = switch_split((char *)suites, ':', fields)switch_separate_string((char *)suites, ':', fields, (sizeof(fields
) / sizeof(fields[0])))
;
1145
1146 for (i = 0; i < argc; i++) {
1147 int ok = 0;
1148
1149 for (j = 0; j < CRYPTO_INVALID; j++) {
1150 if (!strcasecmp(fields[i], SUITES[j].name)) {
1151 smh->crypto_suite_order[k++] = SUITES[j].type;
1152 ok++;
1153 break;
1154 }
1155 }
1156
1157 if (!ok) {
1158 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 1158, (const char*)(session)
, SWITCH_LOG_WARNING, "INVALID SUITE SUPPLIED\n");
1159 }
1160
1161 }
1162 } else {
1163 for (i = 0; i < CRYPTO_INVALID; i++) {
1164 smh->crypto_suite_order[k++] = SUITES[i].type;
1165 }
1166 }
1167}
1168
1169
1170
1171SWITCH_DECLARE(int)__attribute__((visibility("default"))) int switch_core_session_check_incoming_crypto(switch_core_session_t *session,
1172 const char *varname,
1173 switch_media_type_t type, const char *crypto, int crypto_tag, switch_sdp_type_t sdp_type)
1174{
1175 int got_crypto = 0;
1176 int i = 0;
1177 int ctype = 0;
1178 const char *vval = NULL((void*)0);
1179 switch_rtp_engine_t *engine;
1180 switch_media_handle_t *smh;
1181
1182 if (!(smh = session->media_handle)) {
1183 return 0;
1184 }
1185
1186 if (smh->crypto_mode == CRYPTO_MODE_FORBIDDEN) {
1187 return -1;
1188 }
1189
1190 engine = &session->media_handle->engines[type];
1191
1192 for (i = 0; smh->crypto_suite_order[i] != CRYPTO_INVALID; i++) {
1193 switch_rtp_crypto_key_type_t j = SUITES[smh->crypto_suite_order[i]].type;
1194
1195 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 1195, (const char*)(session)
, SWITCH_LOG_DEBUG,"looking for crypto suite [%s] in [%s]\n", SUITES[j].name, crypto);
1196
1197 if (switch_stristr(SUITES[j].name, crypto)) {
1198 ctype = SUITES[j].type;
1199 vval = SUITES[j].name;
1200 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 1200, (const char*)(session)
, SWITCH_LOG_DEBUG, "Found suite %s\n", vval);
1201 switch_channel_set_variable(session->channel, "rtp_secure_media_negotiated", vval)switch_channel_set_variable_var_check(session->channel, "rtp_secure_media_negotiated"
, vval, SWITCH_TRUE)
;
1202 break;
1203 }
1204 }
1205
1206 if (engine->ssec[engine->crypto_type].remote_crypto_key && switch_rtp_ready(engine->rtp_session)) {
1207 /* Compare all the key. The tag may remain the same even if key changed */
1208 if (crypto && engine->crypto_type != CRYPTO_INVALID && !strcmp(crypto, engine->ssec[engine->crypto_type].remote_crypto_key)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(crypto) && __builtin_constant_p (engine->ssec[engine
->crypto_type].remote_crypto_key) && (__s1_len = __builtin_strlen
(crypto), __s2_len = __builtin_strlen (engine->ssec[engine
->crypto_type].remote_crypto_key), (!((size_t)(const void *
)((crypto) + 1) - (size_t)(const void *)(crypto) == 1) || __s1_len
>= 4) && (!((size_t)(const void *)((engine->ssec
[engine->crypto_type].remote_crypto_key) + 1) - (size_t)(const
void *)(engine->ssec[engine->crypto_type].remote_crypto_key
) == 1) || __s2_len >= 4)) ? __builtin_strcmp (crypto, engine
->ssec[engine->crypto_type].remote_crypto_key) : (__builtin_constant_p
(crypto) && ((size_t)(const void *)((crypto) + 1) - (
size_t)(const void *)(crypto) == 1) && (__s1_len = __builtin_strlen
(crypto), __s1_len < 4) ? (__builtin_constant_p (engine->
ssec[engine->crypto_type].remote_crypto_key) && ((
size_t)(const void *)((engine->ssec[engine->crypto_type
].remote_crypto_key) + 1) - (size_t)(const void *)(engine->
ssec[engine->crypto_type].remote_crypto_key) == 1) ? __builtin_strcmp
(crypto, engine->ssec[engine->crypto_type].remote_crypto_key
) : (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (engine->ssec[engine->crypto_type
].remote_crypto_key); int __result = (((const unsigned char *
) (const char *) (crypto))[0] - __s2[0]); if (__s1_len > 0
&& __result == 0) { __result = (((const unsigned char
*) (const char *) (crypto))[1] - __s2[1]); if (__s1_len >
1 && __result == 0) { __result = (((const unsigned char
*) (const char *) (crypto))[2] - __s2[2]); if (__s1_len >
2 && __result == 0) __result = (((const unsigned char
*) (const char *) (crypto))[3] - __s2[3]); } } __result; }))
) : (__builtin_constant_p (engine->ssec[engine->crypto_type
].remote_crypto_key) && ((size_t)(const void *)((engine
->ssec[engine->crypto_type].remote_crypto_key) + 1) - (
size_t)(const void *)(engine->ssec[engine->crypto_type]
.remote_crypto_key) == 1) && (__s2_len = __builtin_strlen
(engine->ssec[engine->crypto_type].remote_crypto_key),
__s2_len < 4) ? (__builtin_constant_p (crypto) &&
((size_t)(const void *)((crypto) + 1) - (size_t)(const void *
)(crypto) == 1) ? __builtin_strcmp (crypto, engine->ssec[engine
->crypto_type].remote_crypto_key) : (- (__extension__ ({ const
unsigned char *__s2 = (const unsigned char *) (const char *)
(crypto); int __result = (((const unsigned char *) (const char
*) (engine->ssec[engine->crypto_type].remote_crypto_key
))[0] - __s2[0]); if (__s2_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) (engine
->ssec[engine->crypto_type].remote_crypto_key))[1] - __s2
[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) (engine->ssec[
engine->crypto_type].remote_crypto_key))[2] - __s2[2]); if
(__s2_len > 2 && __result == 0) __result = (((const
unsigned char *) (const char *) (engine->ssec[engine->
crypto_type].remote_crypto_key))[3] - __s2[3]); } } __result;
})))) : __builtin_strcmp (crypto, engine->ssec[engine->
crypto_type].remote_crypto_key)))); })
) {
1209 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 1209, (const char*)(session)
, SWITCH_LOG_DEBUG, "Existing key is still valid.\n");
1210 got_crypto = 1;
1211 } else {
1212 const char *a = switch_stristr("AE", engine->ssec[engine->crypto_type].remote_crypto_key);
1213 const char *b = switch_stristr("AE", crypto);
1214
1215 if (sdp_type == SDP_TYPE_REQUEST) {
1216 if (!vval) {
1217 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 1217, (const char*)(session)
, SWITCH_LOG_DEBUG, "Unsupported Crypto [%s]\n", crypto);
1218 goto end;
1219 }
1220 switch_channel_set_variable(session->channel, varname, vval)switch_channel_set_variable_var_check(session->channel, varname
, vval, SWITCH_TRUE)
;
1221
1222 switch_core_media_build_crypto(session->media_handle, type, crypto_tag, ctype, SWITCH_RTP_CRYPTO_SEND, 1);
1223 switch_rtp_add_crypto_key(engine->rtp_session, SWITCH_RTP_CRYPTO_SEND, atoi(crypto), engine->ssec[engine->crypto_type].crypto_type,
1224 engine->ssec[engine->crypto_type].local_raw_key, SUITES[ctype].keylen);
1225 }
1226
1227 if (a && b && !strncasecmp(a, b, 23)) {
1228 engine->crypto_type = ctype;
1229
1230 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 1230, (const char*)(session)
, SWITCH_LOG_DEBUG, "Change Remote key to [%s]\n", crypto);
1231 engine->ssec[engine->crypto_type].remote_crypto_key = switch_core_session_strdup(session, crypto)switch_core_perform_session_strdup(session, crypto, "src/switch_core_media.c"
, (const char *)__func__, 1231)
;
1232
1233 if (engine->type == SWITCH_MEDIA_TYPE_AUDIO) {
1234 switch_channel_set_variable(session->channel, "srtp_remote_audio_crypto_key", crypto)switch_channel_set_variable_var_check(session->channel, "srtp_remote_audio_crypto_key"
, crypto, SWITCH_TRUE)
;
1235 switch_channel_set_variable_printf(session->channel, "srtp_remote_audio_crypto_tag", "%d", crypto_tag);
1236 switch_channel_set_variable_printf(session->channel, "srtp_remote_audio_crypto_type", "%s", switch_core_media_crypto_type2str(ctype));
1237 } else if (engine->type == SWITCH_MEDIA_TYPE_VIDEO) {
1238 switch_channel_set_variable(session->channel, "srtp_remote_video_crypto_key", crypto)switch_channel_set_variable_var_check(session->channel, "srtp_remote_video_crypto_key"
, crypto, SWITCH_TRUE)
;
1239 switch_channel_set_variable_printf(session->channel, "srtp_remote_video_crypto_tag", "%d", crypto_tag);
1240 switch_channel_set_variable_printf(session->channel, "srtp_remote_video_crypto_type", "%s", switch_core_media_crypto_type2str(ctype));
1241 }
1242
1243 engine->ssec[engine->crypto_type].crypto_tag = crypto_tag;
1244
1245
1246 if (switch_rtp_ready(engine->rtp_session) && switch_channel_test_flag(session->channel, CF_SECURE)) {
1247 switch_core_media_add_crypto(&engine->ssec[engine->crypto_type], engine->ssec[engine->crypto_type].remote_crypto_key, SWITCH_RTP_CRYPTO_RECV);
1248 switch_rtp_add_crypto_key(engine->rtp_session, SWITCH_RTP_CRYPTO_RECV, engine->ssec[engine->crypto_type].crypto_tag,
1249 engine->ssec[engine->crypto_type].crypto_type, engine->ssec[engine->crypto_type].remote_raw_key, SUITES[engine->ssec[engine->crypto_type].crypto_type].keylen);
1250 }
1251 got_crypto++;
1252
1253 } else {
1254 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 1254, (const char*)(session)
, SWITCH_LOG_DEBUG, "Ignoring unacceptable key\n");
1255 }
1256 }
1257 } else if (!switch_rtp_ready(engine->rtp_session)) {
1258
1259 if (!vval) {
1260 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 1260, (const char*)(session)
, SWITCH_LOG_DEBUG, "Unsupported Crypto [%s]\n", crypto);
1261 goto end;
1262 }
1263
1264 engine->crypto_type = ctype;
1265 engine->ssec[engine->crypto_type].remote_crypto_key = switch_core_session_strdup(session, crypto)switch_core_perform_session_strdup(session, crypto, "src/switch_core_media.c"
, (const char *)__func__, 1265)
;
1266 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 1266, (const char*)(session)
, SWITCH_LOG_DEBUG, "Set Remote Key [%s]\n", engine->ssec[engine->crypto_type].remote_crypto_key);
1267 if (engine->type == SWITCH_MEDIA_TYPE_AUDIO) {
1268 switch_channel_set_variable(session->channel, "srtp_remote_audio_crypto_key", crypto)switch_channel_set_variable_var_check(session->channel, "srtp_remote_audio_crypto_key"
, crypto, SWITCH_TRUE)
;
1269 switch_channel_set_variable_printf(session->channel, "srtp_remote_audio_crypto_type", "%s", switch_core_media_crypto_type2str(ctype));
1270 } else if (engine->type == SWITCH_MEDIA_TYPE_VIDEO) {
1271 switch_channel_set_variable(session->channel, "srtp_remote_video_crypto_key", crypto)switch_channel_set_variable_var_check(session->channel, "srtp_remote_video_crypto_key"
, crypto, SWITCH_TRUE)
;
1272 switch_channel_set_variable_printf(session->channel, "srtp_remote_video_crypto_type", "%s", switch_core_media_crypto_type2str(ctype));
1273 }
1274
1275 engine->ssec[engine->crypto_type].crypto_tag = crypto_tag;
1276 got_crypto++;
1277
1278 switch_channel_set_variable(session->channel, varname, vval)switch_channel_set_variable_var_check(session->channel, varname
, vval, SWITCH_TRUE)
;
1279 switch_channel_set_flag(smh->session->channel, CF_SECURE)switch_channel_set_flag_value(smh->session->channel, CF_SECURE
, 1)
;
1280
1281 if (zstr(engine->ssec[engine->crypto_type].local_crypto_key)_zstr(engine->ssec[engine->crypto_type].local_crypto_key
)
) {
1282 switch_core_media_build_crypto(session->media_handle, type, crypto_tag, ctype, SWITCH_RTP_CRYPTO_SEND, 1);
1283 }
1284 }
1285
1286 end:
1287
1288 return got_crypto;
1289}
1290
1291
1292SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_session_check_outgoing_crypto(switch_core_session_t *session)
1293{
1294 switch_channel_t *channel = switch_core_session_get_channel(session);
1295 switch_media_handle_t *smh;
1296 int i;
1297
1298 if (!switch_core_session_media_handle_ready(session) == SWITCH_STATUS_SUCCESS) {
1299 return;
1300 }
1301
1302 if (!(smh = session->media_handle)) {
1303 return;
1304 }
1305
1306 if (!(smh->crypto_mode == CRYPTO_MODE_OPTIONAL || smh->crypto_mode == CRYPTO_MODE_MANDATORY)) {
1307 return;
1308 }
1309
1310 switch_channel_set_flag(channel, CF_SECURE)switch_channel_set_flag_value(channel, CF_SECURE, 1);
1311
1312 for (i = 0; smh->crypto_suite_order[i] != CRYPTO_INVALID; i++) {
1313 switch_core_media_build_crypto(session->media_handle,
1314 SWITCH_MEDIA_TYPE_AUDIO, 0, smh->crypto_suite_order[i], SWITCH_RTP_CRYPTO_SEND, 0);
1315
1316 switch_core_media_build_crypto(session->media_handle,
1317 SWITCH_MEDIA_TYPE_VIDEO, 0, smh->crypto_suite_order[i], SWITCH_RTP_CRYPTO_SEND, 0);
1318 }
1319
1320}
1321
1322#define add_stat(_i, _s)switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", (prefix
? prefix : ""), _s) ; switch_snprintf(var_val, sizeof(var_val
), "%" "ld", _i); switch_channel_set_variable_var_check(channel
, var_name, var_val, SWITCH_TRUE)
\
1323 switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", switch_str_nil(prefix)(prefix ? prefix : ""), _s) ; \
1324 switch_snprintf(var_val, sizeof(var_val), "%" SWITCH_SIZE_T_FMT"ld", _i); \
1325 switch_channel_set_variable(channel, var_name, var_val)switch_channel_set_variable_var_check(channel, var_name, var_val
, SWITCH_TRUE)
1326
1327#define add_stat_double(_i, _s)switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", (prefix
? prefix : ""), _s) ; switch_snprintf(var_val, sizeof(var_val
), "%0.2f", _i); switch_channel_set_variable_var_check(channel
, var_name, var_val, SWITCH_TRUE)
\
1328 switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", switch_str_nil(prefix)(prefix ? prefix : ""), _s) ; \
1329 switch_snprintf(var_val, sizeof(var_val), "%0.2f", _i); \
1330 switch_channel_set_variable(channel, var_name, var_val)switch_channel_set_variable_var_check(channel, var_name, var_val
, SWITCH_TRUE)
1331
1332static void set_stats(switch_core_session_t *session, switch_media_type_t type, const char *prefix)
1333{
1334 switch_rtp_stats_t *stats = switch_core_media_get_stats(session, type, NULL((void*)0));
1335 switch_channel_t *channel = switch_core_session_get_channel(session);
1336
1337 char var_name[256] = "", var_val[35] = "";
1338
1339 if (stats) {
1340 stats->inbound.std_deviation = sqrt(stats->inbound.variance);
1341
1342 add_stat(stats->inbound.raw_bytes, "in_raw_bytes")switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", (prefix
? prefix : ""), "in_raw_bytes") ; switch_snprintf(var_val, sizeof
(var_val), "%" "ld", stats->inbound.raw_bytes); switch_channel_set_variable_var_check
(channel, var_name, var_val, SWITCH_TRUE)
;
1343 add_stat(stats->inbound.media_bytes, "in_media_bytes")switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", (prefix
? prefix : ""), "in_media_bytes") ; switch_snprintf(var_val,
sizeof(var_val), "%" "ld", stats->inbound.media_bytes); switch_channel_set_variable_var_check
(channel, var_name, var_val, SWITCH_TRUE)
;
1344 add_stat(stats->inbound.packet_count, "in_packet_count")switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", (prefix
? prefix : ""), "in_packet_count") ; switch_snprintf(var_val
, sizeof(var_val), "%" "ld", stats->inbound.packet_count);
switch_channel_set_variable_var_check(channel, var_name, var_val
, SWITCH_TRUE)
;
1345 add_stat(stats->inbound.media_packet_count, "in_media_packet_count")switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", (prefix
? prefix : ""), "in_media_packet_count") ; switch_snprintf(var_val
, sizeof(var_val), "%" "ld", stats->inbound.media_packet_count
); switch_channel_set_variable_var_check(channel, var_name, var_val
, SWITCH_TRUE)
;
1346 add_stat(stats->inbound.skip_packet_count, "in_skip_packet_count")switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", (prefix
? prefix : ""), "in_skip_packet_count") ; switch_snprintf(var_val
, sizeof(var_val), "%" "ld", stats->inbound.skip_packet_count
); switch_channel_set_variable_var_check(channel, var_name, var_val
, SWITCH_TRUE)
;
1347 add_stat(stats->inbound.jb_packet_count, "in_jitter_packet_count")switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", (prefix
? prefix : ""), "in_jitter_packet_count") ; switch_snprintf(
var_val, sizeof(var_val), "%" "ld", stats->inbound.jb_packet_count
); switch_channel_set_variable_var_check(channel, var_name, var_val
, SWITCH_TRUE)
;
1348 add_stat(stats->inbound.dtmf_packet_count, "in_dtmf_packet_count")switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", (prefix
? prefix : ""), "in_dtmf_packet_count") ; switch_snprintf(var_val
, sizeof(var_val), "%" "ld", stats->inbound.dtmf_packet_count
); switch_channel_set_variable_var_check(channel, var_name, var_val
, SWITCH_TRUE)
;
1349 add_stat(stats->inbound.cng_packet_count, "in_cng_packet_count")switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", (prefix
? prefix : ""), "in_cng_packet_count") ; switch_snprintf(var_val
, sizeof(var_val), "%" "ld", stats->inbound.cng_packet_count
); switch_channel_set_variable_var_check(channel, var_name, var_val
, SWITCH_TRUE)
;
1350 add_stat(stats->inbound.flush_packet_count, "in_flush_packet_count")switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", (prefix
? prefix : ""), "in_flush_packet_count") ; switch_snprintf(var_val
, sizeof(var_val), "%" "ld", stats->inbound.flush_packet_count
); switch_channel_set_variable_var_check(channel, var_name, var_val
, SWITCH_TRUE)
;
1351 add_stat(stats->inbound.largest_jb_size, "in_largest_jb_size")switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", (prefix
? prefix : ""), "in_largest_jb_size") ; switch_snprintf(var_val
, sizeof(var_val), "%" "ld", stats->inbound.largest_jb_size
); switch_channel_set_variable_var_check(channel, var_name, var_val
, SWITCH_TRUE)
;
1352 add_stat_double(stats->inbound.min_variance, "in_jitter_min_variance")switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", (prefix
? prefix : ""), "in_jitter_min_variance") ; switch_snprintf(
var_val, sizeof(var_val), "%0.2f", stats->inbound.min_variance
); switch_channel_set_variable_var_check(channel, var_name, var_val
, SWITCH_TRUE)
;
1353 add_stat_double(stats->inbound.max_variance, "in_jitter_max_variance")switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", (prefix
? prefix : ""), "in_jitter_max_variance") ; switch_snprintf(
var_val, sizeof(var_val), "%0.2f", stats->inbound.max_variance
); switch_channel_set_variable_var_check(channel, var_name, var_val
, SWITCH_TRUE)
;
1354 add_stat_double(stats->inbound.lossrate, "in_jitter_loss_rate")switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", (prefix
? prefix : ""), "in_jitter_loss_rate") ; switch_snprintf(var_val
, sizeof(var_val), "%0.2f", stats->inbound.lossrate); switch_channel_set_variable_var_check
(channel, var_name, var_val, SWITCH_TRUE)
;
1355 add_stat_double(stats->inbound.burstrate, "in_jitter_burst_rate")switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", (prefix
? prefix : ""), "in_jitter_burst_rate") ; switch_snprintf(var_val
, sizeof(var_val), "%0.2f", stats->inbound.burstrate); switch_channel_set_variable_var_check
(channel, var_name, var_val, SWITCH_TRUE)
;
1356 add_stat_double(stats->inbound.mean_interval, "in_mean_interval")switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", (prefix
? prefix : ""), "in_mean_interval") ; switch_snprintf(var_val
, sizeof(var_val), "%0.2f", stats->inbound.mean_interval);
switch_channel_set_variable_var_check(channel, var_name, var_val
, SWITCH_TRUE)
;
1357 add_stat(stats->inbound.flaws, "in_flaw_total")switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", (prefix
? prefix : ""), "in_flaw_total") ; switch_snprintf(var_val, sizeof
(var_val), "%" "ld", stats->inbound.flaws); switch_channel_set_variable_var_check
(channel, var_name, var_val, SWITCH_TRUE)
;
1358 add_stat_double(stats->inbound.R, "in_quality_percentage")switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", (prefix
? prefix : ""), "in_quality_percentage") ; switch_snprintf(var_val
, sizeof(var_val), "%0.2f", stats->inbound.R); switch_channel_set_variable_var_check
(channel, var_name, var_val, SWITCH_TRUE)
;
1359 add_stat_double(stats->inbound.mos, "in_mos")switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", (prefix
? prefix : ""), "in_mos") ; switch_snprintf(var_val, sizeof(
var_val), "%0.2f", stats->inbound.mos); switch_channel_set_variable_var_check
(channel, var_name, var_val, SWITCH_TRUE)
;
1360
1361
1362 add_stat(stats->outbound.raw_bytes, "out_raw_bytes")switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", (prefix
? prefix : ""), "out_raw_bytes") ; switch_snprintf(var_val, sizeof
(var_val), "%" "ld", stats->outbound.raw_bytes); switch_channel_set_variable_var_check
(channel, var_name, var_val, SWITCH_TRUE)
;
1363 add_stat(stats->outbound.media_bytes, "out_media_bytes")switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", (prefix
? prefix : ""), "out_media_bytes") ; switch_snprintf(var_val
, sizeof(var_val), "%" "ld", stats->outbound.media_bytes);
switch_channel_set_variable_var_check(channel, var_name, var_val
, SWITCH_TRUE)
;
1364 add_stat(stats->outbound.packet_count, "out_packet_count")switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", (prefix
? prefix : ""), "out_packet_count") ; switch_snprintf(var_val
, sizeof(var_val), "%" "ld", stats->outbound.packet_count)
; switch_channel_set_variable_var_check(channel, var_name, var_val
, SWITCH_TRUE)
;
1365 add_stat(stats->outbound.media_packet_count, "out_media_packet_count")switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", (prefix
? prefix : ""), "out_media_packet_count") ; switch_snprintf(
var_val, sizeof(var_val), "%" "ld", stats->outbound.media_packet_count
); switch_channel_set_variable_var_check(channel, var_name, var_val
, SWITCH_TRUE)
;
1366 add_stat(stats->outbound.skip_packet_count, "out_skip_packet_count")switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", (prefix
? prefix : ""), "out_skip_packet_count") ; switch_snprintf(var_val
, sizeof(var_val), "%" "ld", stats->outbound.skip_packet_count
); switch_channel_set_variable_var_check(channel, var_name, var_val
, SWITCH_TRUE)
;
1367 add_stat(stats->outbound.dtmf_packet_count, "out_dtmf_packet_count")switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", (prefix
? prefix : ""), "out_dtmf_packet_count") ; switch_snprintf(var_val
, sizeof(var_val), "%" "ld", stats->outbound.dtmf_packet_count
); switch_channel_set_variable_var_check(channel, var_name, var_val
, SWITCH_TRUE)
;
1368 add_stat(stats->outbound.cng_packet_count, "out_cng_packet_count")switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", (prefix
? prefix : ""), "out_cng_packet_count") ; switch_snprintf(var_val
, sizeof(var_val), "%" "ld", stats->outbound.cng_packet_count
); switch_channel_set_variable_var_check(channel, var_name, var_val
, SWITCH_TRUE)
;
1369
1370 add_stat(stats->rtcp.packet_count, "rtcp_packet_count")switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", (prefix
? prefix : ""), "rtcp_packet_count") ; switch_snprintf(var_val
, sizeof(var_val), "%" "ld", stats->rtcp.packet_count); switch_channel_set_variable_var_check
(channel, var_name, var_val, SWITCH_TRUE)
;
1371 add_stat(stats->rtcp.octet_count, "rtcp_octet_count")switch_snprintf(var_name, sizeof(var_name), "rtp_%s_%s", (prefix
? prefix : ""), "rtcp_octet_count") ; switch_snprintf(var_val
, sizeof(var_val), "%" "ld", stats->rtcp.octet_count); switch_channel_set_variable_var_check
(channel, var_name, var_val, SWITCH_TRUE)
;
1372
1373 }
1374}
1375
1376SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_set_stats(switch_core_session_t *session)
1377{
1378
1379 if (!session->media_handle) {
1380 return;
1381 }
1382
1383 set_stats(session, SWITCH_MEDIA_TYPE_AUDIO, "audio");
1384 set_stats(session, SWITCH_MEDIA_TYPE_VIDEO, "video");
1385}
1386
1387
1388
1389SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_media_handle_destroy(switch_core_session_t *session)
1390{
1391 switch_media_handle_t *smh;
1392 switch_rtp_engine_t *a_engine, *v_engine;
1393
1394 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 1394, __PRETTY_FUNCTION__))
;
1395
1396 if (!(smh = session->media_handle)) {
1397 return;
1398 }
1399
1400 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
1401 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
1402
1403
1404 if (switch_core_codec_ready(&a_engine->read_codec)) {
1405 switch_core_codec_destroy(&a_engine->read_codec);
1406 }
1407
1408 if (switch_core_codec_ready(&a_engine->write_codec)) {
1409 switch_core_codec_destroy(&a_engine->write_codec);
1410 }
1411
1412 if (switch_core_codec_ready(&v_engine->read_codec)) {
1413 switch_core_codec_destroy(&v_engine->read_codec);
1414 }
1415
1416 if (switch_core_codec_ready(&v_engine->write_codec)) {
1417 switch_core_codec_destroy(&v_engine->write_codec);
1418 }
1419
1420 switch_core_session_unset_read_codec(session);
1421 switch_core_session_unset_write_codec(session);
1422 switch_core_media_deactivate_rtp(session);
1423
1424
1425
1426}
1427
1428
1429SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_media_handle_create(switch_media_handle_t **smhp, switch_core_session_t *session, switch_core_media_params_t *params)
1430{
1431 switch_status_t status = SWITCH_STATUS_FALSE;
1432 switch_media_handle_t *smh = NULL((void*)0);
1433 int i;
1434
1435 *smhp = NULL((void*)0);
1436
1437 if (zstr(params->sdp_username)_zstr(params->sdp_username)) {
1438 params->sdp_username = "FreeSWITCH";
1439 }
1440
1441
1442 if ((session->media_handle = switch_core_session_alloc(session, (sizeof(*smh)))switch_core_perform_session_alloc(session, (sizeof(*smh)), "src/switch_core_media.c"
, (const char *)__func__, 1442)
)) {
1443 session->media_handle->session = session;
1444
1445
1446 *smhp = session->media_handle;
1447 switch_set_flag(session->media_handle, SMF_INIT)(session->media_handle)->flags |= (SMF_INIT);
1448 session->media_handle->media_flags[SCMF_RUNNING] = 1;
1449 session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].read_frame.buflen = SWITCH_RTP_MAX_BUF_LEN16384;
1450 session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].type = SWITCH_MEDIA_TYPE_AUDIO;
1451 session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].crypto_type = CRYPTO_INVALID;
1452
1453 for (i = 0; i < CRYPTO_INVALID; i++) {
1454 session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].ssec[i].crypto_type = i;
1455 }
1456
1457 session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].read_frame.buflen = SWITCH_RTP_MAX_BUF_LEN16384;
1458 session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].type = SWITCH_MEDIA_TYPE_VIDEO;
1459 session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].crypto_type = CRYPTO_INVALID;
1460
1461 for (i = 0; i < CRYPTO_INVALID; i++) {
1462 session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].ssec[i].crypto_type = i;
1463 }
1464
1465 session->media_handle->mparams = params;
1466
1467 for (i = 0; i <= CRYPTO_INVALID; i++) {
1468 session->media_handle->crypto_suite_order[i] = CRYPTO_INVALID;
1469 }
1470
1471 switch_mutex_init(&session->media_handle->mutex, SWITCH_MUTEX_NESTED0x1, switch_core_session_get_pool(session));
1472 switch_mutex_init(&session->media_handle->sdp_mutex, SWITCH_MUTEX_NESTED0x1, switch_core_session_get_pool(session));
1473
1474 session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].ssrc =
1475 (uint32_t) ((intptr_t) &session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO] + (uint32_t) time(NULL((void*)0)));
1476
1477 session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].ssrc =
1478 (uint32_t) ((intptr_t) &session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO] + (uint32_t) time(NULL((void*)0)) / 2);
1479
1480 session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].payload_map = switch_core_alloc(session->pool, sizeof(payload_map_t))switch_core_perform_alloc(session->pool, sizeof(payload_map_t
), "src/switch_core_media.c", (const char *)__func__, 1480)
;
1481 session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].cur_payload_map = session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].payload_map;
1482 session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].cur_payload_map->current = 1;
1483 session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].payload_map = switch_core_alloc(session->pool, sizeof(payload_map_t))switch_core_perform_alloc(session->pool, sizeof(payload_map_t
), "src/switch_core_media.c", (const char *)__func__, 1483)
;
1484 session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].cur_payload_map = session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].payload_map;
1485 session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].cur_payload_map->current = 1;
1486
1487 switch_channel_set_flag(session->channel, CF_DTLS_OK)switch_channel_set_flag_value(session->channel, CF_DTLS_OK
, 1)
;
1488
1489 status = SWITCH_STATUS_SUCCESS;
1490 }
1491
1492
1493 return status;
1494}
1495
1496SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_media_handle_set_media_flag(switch_media_handle_t *smh, switch_core_media_flag_t flag)
1497{
1498 switch_assert(smh)((smh) ? (void) (0) : __assert_fail ("smh", "src/switch_core_media.c"
, 1498, __PRETTY_FUNCTION__))
;
1499
1500 smh->media_flags[flag] = 1;
1501
1502}
1503
1504SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_media_handle_set_media_flags(switch_media_handle_t *smh, switch_core_media_flag_t flags[SCMF_MAX])
1505{
1506 int i;
1507 switch_assert(smh)((smh) ? (void) (0) : __assert_fail ("smh", "src/switch_core_media.c"
, 1507, __PRETTY_FUNCTION__))
;
1508
1509 for(i = 0; i < SCMF_MAX; i++) {
1510 if (flags[i]) {
1511 smh->media_flags[i] = flags[i];
1512 }
1513 }
1514
1515}
1516
1517SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_media_handle_clear_media_flag(switch_media_handle_t *smh, switch_core_media_flag_t flag)
1518{
1519 switch_assert(smh)((smh) ? (void) (0) : __assert_fail ("smh", "src/switch_core_media.c"
, 1519, __PRETTY_FUNCTION__))
;
1520
1521 smh->media_flags[flag] = 0;
1522}
1523
1524SWITCH_DECLARE(int32_t)__attribute__((visibility("default"))) int32_t switch_media_handle_test_media_flag(switch_media_handle_t *smh, switch_core_media_flag_t flag)
1525{
1526 switch_assert(smh)((smh) ? (void) (0) : __assert_fail ("smh", "src/switch_core_media.c"
, 1526, __PRETTY_FUNCTION__))
;
1527 return smh->media_flags[flag];
1528}
1529
1530SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_media_handle_ready(switch_core_session_t *session)
1531{
1532 if (session->media_handle && switch_test_flag(session->media_handle, SMF_INIT)((session->media_handle)->flags & SMF_INIT)) {
1533 return SWITCH_STATUS_SUCCESS;
1534 }
1535
1536 return SWITCH_STATUS_FALSE;
1537}
1538
1539
1540
1541SWITCH_DECLARE(switch_media_handle_t *)__attribute__((visibility("default"))) switch_media_handle_t * switch_core_session_get_media_handle(switch_core_session_t *session)
1542{
1543 if (switch_core_session_media_handle_ready(session) == SWITCH_STATUS_SUCCESS) {
1544 return session->media_handle;
1545 }
1546
1547 return NULL((void*)0);
1548}
1549
1550SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_session_clear_media_handle(switch_core_session_t *session)
1551{
1552 if (!session->media_handle) {
1553 return SWITCH_STATUS_FALSE;
1554 }
1555
1556 return SWITCH_STATUS_SUCCESS;
1557}
1558
1559SWITCH_DECLARE(switch_core_media_params_t *)__attribute__((visibility("default"))) switch_core_media_params_t
*
switch_core_media_get_mparams(switch_media_handle_t *smh)
1560{
1561 switch_assert(smh)((smh) ? (void) (0) : __assert_fail ("smh", "src/switch_core_media.c"
, 1561, __PRETTY_FUNCTION__))
;
1562 return smh->mparams;
1563}
1564
1565SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_prepare_codecs(switch_core_session_t *session, switch_bool_t force)
1566{
1567 const char *abs, *codec_string = NULL((void*)0);
1568 const char *ocodec = NULL((void*)0);
1569 switch_media_handle_t *smh;
1570
1571 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 1571, __PRETTY_FUNCTION__))
;
1572
1573 if (!(smh = session->media_handle)) {
1574 return;
1575 }
1576
1577 if (!force && (switch_channel_test_flag(session->channel, CF_PROXY_MODE) || switch_channel_test_flag(session->channel, CF_PROXY_MEDIA))) {
1578 return;
1579 }
1580
1581 if (force) {
1582 smh->mparams->num_codecs = 0;
1583 }
1584
1585 if (smh->mparams->num_codecs) {
1586 return;
1587 }
1588
1589 smh->payload_space = 0;
1590
1591 switch_assert(smh->session != NULL)((smh->session != ((void*)0)) ? (void) (0) : __assert_fail
("smh->session != ((void*)0)", "src/switch_core_media.c",
1591, __PRETTY_FUNCTION__))
;
1592
1593 if ((abs = switch_channel_get_variable(session->channel, "absolute_codec_string")switch_channel_get_variable_dup(session->channel, "absolute_codec_string"
, SWITCH_TRUE, -1)
)) {
1594 codec_string = abs;
1595 goto ready;
1596 }
1597
1598 if (!(codec_string = switch_channel_get_variable(session->channel, "codec_string")switch_channel_get_variable_dup(session->channel, "codec_string"
, SWITCH_TRUE, -1)
)) {
1599 codec_string = switch_core_media_get_codec_string(smh->session);
1600 }
1601
1602 if (codec_string && *codec_string == '=') {
1603 codec_string++;
1604 goto ready;
1605 }
1606
1607 if ((ocodec = switch_channel_get_variable(session->channel, SWITCH_ORIGINATOR_CODEC_VARIABLE)switch_channel_get_variable_dup(session->channel, "originator_codec"
, SWITCH_TRUE, -1)
)) {
1608 if (!codec_string || (smh->media_flags[SCMF_DISABLE_TRANSCODING])) {
1609 codec_string = ocodec;
1610 } else {
1611 if (!(codec_string = switch_core_session_sprintf(smh->session, "%s,%s", ocodec, codec_string))) {
1612 codec_string = ocodec;
1613 }
1614 }
1615 }
1616
1617 ready:
1618 if (codec_string) {
1619 char *tmp_codec_string = switch_core_session_strdup(smh->session, codec_string)switch_core_perform_session_strdup(smh->session, codec_string
, "src/switch_core_media.c", (const char *)__func__, 1619)
;
1620
1621
1622 switch_channel_set_variable(session->channel, "rtp_use_codec_string", codec_string)switch_channel_set_variable_var_check(session->channel, "rtp_use_codec_string"
, codec_string, SWITCH_TRUE)
;
1623 smh->codec_order_last = switch_separate_string(tmp_codec_string, ',', smh->codec_order, SWITCH_MAX_CODECS50);
1624 smh->mparams->num_codecs = switch_loadable_module_get_codecs_sorted(smh->codecs, SWITCH_MAX_CODECS50, smh->codec_order, smh->codec_order_last);
1625 } else {
1626 smh->mparams->num_codecs = switch_loadable_module_get_codecs(smh->codecs, sizeof(smh->codecs) / sizeof(smh->codecs[0]));
1627 }
1628}
1629
1630
1631static void check_jb(switch_core_session_t *session, const char *input)
1632{
1633 const char *val;
1634 switch_media_handle_t *smh;
1635 switch_rtp_engine_t *a_engine;
1636
1637 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 1637, __PRETTY_FUNCTION__))
;
1638
1639 if (!(smh = session->media_handle)) {
1640 return;
1641 }
1642
1643 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
1644
1645 if (!a_engine->rtp_session) return;
1646
1647
1648 if (!zstr(input)_zstr(input)) {
1649 const char *s;
1650
1651 if (!strcasecmp(input, "pause")) {
1652 switch_rtp_pause_jitter_buffer(a_engine->rtp_session, SWITCH_TRUE);
1653 return;
1654 } else if (!strcasecmp(input, "resume")) {
1655 switch_rtp_pause_jitter_buffer(a_engine->rtp_session, SWITCH_FALSE);
1656 return;
1657 } else if (!strcasecmp(input, "stop")) {
1658 switch_rtp_deactivate_jitter_buffer(a_engine->rtp_session);
1659 return;
1660 } else if (!strncasecmp(input, "debug:", 6)) {
1661 s = input + 6;
1662 if (s && !strcmp(s, "off")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(s) && __builtin_constant_p ("off") && (__s1_len
= __builtin_strlen (s), __s2_len = __builtin_strlen ("off"),
(!((size_t)(const void *)((s) + 1) - (size_t)(const void *)(
s) == 1) || __s1_len >= 4) && (!((size_t)(const void
*)(("off") + 1) - (size_t)(const void *)("off") == 1) || __s2_len
>= 4)) ? __builtin_strcmp (s, "off") : (__builtin_constant_p
(s) && ((size_t)(const void *)((s) + 1) - (size_t)(const
void *)(s) == 1) && (__s1_len = __builtin_strlen (s)
, __s1_len < 4) ? (__builtin_constant_p ("off") &&
((size_t)(const void *)(("off") + 1) - (size_t)(const void *
)("off") == 1) ? __builtin_strcmp (s, "off") : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) ("off"); int __result = (((const unsigned char *) (const
char *) (s))[0] - __s2[0]); if (__s1_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
s))[1] - __s2[1]); if (__s1_len > 1 && __result ==
0) { __result = (((const unsigned char *) (const char *) (s)
)[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (s))[3]
- __s2[3]); } } __result; }))) : (__builtin_constant_p ("off"
) && ((size_t)(const void *)(("off") + 1) - (size_t)(
const void *)("off") == 1) && (__s2_len = __builtin_strlen
("off"), __s2_len < 4) ? (__builtin_constant_p (s) &&
((size_t)(const void *)((s) + 1) - (size_t)(const void *)(s)
== 1) ? __builtin_strcmp (s, "off") : (- (__extension__ ({ const
unsigned char *__s2 = (const unsigned char *) (const char *)
(s); int __result = (((const unsigned char *) (const char *)
("off"))[0] - __s2[0]); if (__s2_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
"off"))[1] - __s2[1]); if (__s2_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
"off"))[2] - __s2[2]); if (__s2_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) ("off"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (s, "off"
)))); })
) {
1663 s = NULL((void*)0);
1664 }
1665 switch_rtp_debug_jitter_buffer(a_engine->rtp_session, s);
1666 return;
1667 }
1668
1669 switch_channel_set_variable(session->channel, "jitterbuffer_msec", input)switch_channel_set_variable_var_check(session->channel, "jitterbuffer_msec"
, input, SWITCH_TRUE)
;
1670 }
1671
1672
1673 if ((val = switch_channel_get_variable(session->channel, "jitterbuffer_msec")switch_channel_get_variable_dup(session->channel, "jitterbuffer_msec"
, SWITCH_TRUE, -1)
) || (val = smh->mparams->jb_msec)) {
1674 int jb_msec = atoi(val);
1675 int maxlen = 0, max_drift = 0;
1676 char *p, *q;
1677
1678
1679 if ((p = strchr(val, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(val) && (':') == '\0' ? (char *) __rawmemchr (val, ':'
) : __builtin_strchr (val, ':')))
)) {
1680 p++;
1681 maxlen = atoi(p);
1682 if ((q = strchr(p, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(p) && (':') == '\0' ? (char *) __rawmemchr (p, ':')
: __builtin_strchr (p, ':')))
)) {
1683 q++;
1684 max_drift = abs(atoi(q));
1685 }
1686 }
1687
1688 if (jb_msec < 0 && jb_msec > -20) {
1689 jb_msec = (a_engine->read_codec.implementation->microseconds_per_packet / 1000) * abs(jb_msec);
1690 }
1691
1692 if (maxlen < 0 && maxlen > -20) {
1693 maxlen = (a_engine->read_codec.implementation->microseconds_per_packet / 1000) * abs(maxlen);
1694 }
1695
1696 if (jb_msec < 10 || jb_msec > 10000) {
1697 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 1697, (const char*)(session)
, SWITCH_LOG_ERROR,
1698 "Invalid Jitterbuffer spec [%d] must be between 10 and 10000\n", jb_msec);
1699 } else {
1700 int qlen, maxqlen = 10;
1701
1702 qlen = jb_msec / (a_engine->read_impl.microseconds_per_packet / 1000);
1703
1704 if (maxlen) {
1705 maxqlen = maxlen / (a_engine->read_impl.microseconds_per_packet / 1000);
1706 }
1707
1708 if (maxqlen < qlen) {
1709 maxqlen = qlen * 5;
1710 }
1711 if (switch_rtp_activate_jitter_buffer(a_engine->rtp_session, qlen, maxqlen,
1712 a_engine->read_impl.samples_per_packet,
1713 a_engine->read_impl.samples_per_second, max_drift) == SWITCH_STATUS_SUCCESS) {
1714 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 1714, (const char*)(session)
,
1715 SWITCH_LOG_DEBUG, "Setting Jitterbuffer to %dms (%d frames) (%d max frames) (%d max drift)\n",
1716 jb_msec, qlen, maxqlen, max_drift);
1717 switch_channel_set_flag(session->channel, CF_JITTERBUFFER)switch_channel_set_flag_value(session->channel, CF_JITTERBUFFER
, 1)
;
1718 if (!switch_false(switch_channel_get_variable(session->channel, "rtp_jitter_buffer_plc")switch_channel_get_variable_dup(session->channel, "rtp_jitter_buffer_plc"
, SWITCH_TRUE, -1)
)) {
1719 switch_channel_set_flag(session->channel, CF_JITTERBUFFER_PLC)switch_channel_set_flag_value(session->channel, CF_JITTERBUFFER_PLC
, 1)
;
1720 }
1721 } else {
1722 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 1722, (const char*)(session)
,
1723 SWITCH_LOG_WARNING, "Error Setting Jitterbuffer to %dms (%d frames)\n", jb_msec, qlen);
1724 }
1725
1726 }
1727 }
1728
1729}
1730
1731//?
1732SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_media_read_frame(switch_core_session_t *session, switch_frame_t **frame,
1733 switch_io_flag_t flags, int stream_id, switch_media_type_t type)
1734{
1735 switch_rtcp_frame_t rtcp_frame;
1736 switch_rtp_engine_t *engine;
1737 switch_status_t status;
1738 switch_media_handle_t *smh;
1739 int do_cng = 0;
1740
1741 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 1741, __PRETTY_FUNCTION__))
;
1742
1743 if (!(smh = session->media_handle)) {
1744 return SWITCH_STATUS_FALSE;
1745 }
1746
1747 if (!smh->media_flags[SCMF_RUNNING]) {
1748 return SWITCH_STATUS_FALSE;
1749 }
1750
1751 engine = &smh->engines[type];
1752
1753 engine->read_frame.datalen = 0;
1754
1755 if (!engine->read_codec.implementation || !switch_core_codec_ready(&engine->read_codec)) {
1756 return SWITCH_STATUS_FALSE;
1757 }
1758
1759 switch_assert(engine->rtp_session != NULL)((engine->rtp_session != ((void*)0)) ? (void) (0) : __assert_fail
("engine->rtp_session != ((void*)0)", "src/switch_core_media.c"
, 1759, __PRETTY_FUNCTION__))
;
1760 engine->read_frame.datalen = 0;
1761
1762 if (!switch_channel_up_nosig(session->channel)(switch_channel_get_state(session->channel) < CS_HANGUP
)
|| !switch_rtp_ready(engine->rtp_session) || switch_channel_test_flag(session->channel, CF_NOT_READY)) {
1763 return SWITCH_STATUS_FALSE;
1764 }
1765
1766 if (engine->read_mutex[type] && switch_mutex_trylock(engine->read_mutex[type]) != SWITCH_STATUS_SUCCESS) {
1767 /* return CNG, another thread is already reading */
1768 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 1768, (const char*)(session)
, SWITCH_LOG_DEBUG1, "%s is already being read for %s\n",
1769 switch_channel_get_name(session->channel), type2str(type)type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio");
1770 return SWITCH_STATUS_INUSE;
1771 }
1772
1773
1774 while (smh->media_flags[SCMF_RUNNING] && engine->read_frame.datalen == 0) {
1775 engine->read_frame.flags = SFF_NONE;
1776
1777 status = switch_rtp_zerocopy_read_frame(engine->rtp_session, &engine->read_frame, flags);
1778
1779 if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
1780 if (status == SWITCH_STATUS_TIMEOUT) {
1781
1782 if (switch_channel_get_variable(session->channel, "execute_on_media_timeout")switch_channel_get_variable_dup(session->channel, "execute_on_media_timeout"
, SWITCH_TRUE, -1)
) {
1783 *frame = &engine->read_frame;
1784 switch_set_flag((*frame), SFF_CNG)((*frame))->flags |= (SFF_CNG);
1785 (*frame)->datalen = engine->read_impl.encoded_bytes_per_packet;
1786 memset((*frame)->data, 0, (*frame)->datalen);
1787 switch_channel_execute_on(session->channel, "execute_on_media_timeout");
1788 switch_goto_status(SWITCH_STATUS_SUCCESS, end)status = SWITCH_STATUS_SUCCESS; goto end;
1789 }
1790
1791
1792 switch_channel_hangup(session->channel, SWITCH_CAUSE_MEDIA_TIMEOUT)switch_channel_perform_hangup(session->channel, "src/switch_core_media.c"
, (const char *)__func__, 1792, SWITCH_CAUSE_MEDIA_TIMEOUT)
;
1793 }
1794 goto end;
1795 }
1796
1797 /* re-set codec if necessary */
1798 if (engine->reset_codec > 0) {
1799 const char *val;
1800 int rtp_timeout_sec = 0;
1801 int rtp_hold_timeout_sec = 0;
1802
1803 engine->reset_codec = 0;
1804
1805 if (switch_rtp_ready(engine->rtp_session)) {
1806 if (type == SWITCH_MEDIA_TYPE_VIDEO) {
1807 switch_core_media_set_video_codec(session, 1);
1808 } else {
1809 if (switch_core_media_set_codec(session, 1, 0) != SWITCH_STATUS_SUCCESS) {
1810 *frame = NULL((void*)0);
1811 switch_goto_status(SWITCH_STATUS_GENERR, end)status = SWITCH_STATUS_GENERR; goto end;
1812 }
1813 }
1814
1815 if ((val = switch_channel_get_variable(session->channel, "rtp_timeout_sec")switch_channel_get_variable_dup(session->channel, "rtp_timeout_sec"
, SWITCH_TRUE, -1)
)) {
1816 int v = atoi(val);
1817 if (v >= 0) {
1818 rtp_timeout_sec = v;
1819 }
1820 }
1821
1822 if ((val = switch_channel_get_variable(session->channel, "rtp_hold_timeout_sec")switch_channel_get_variable_dup(session->channel, "rtp_hold_timeout_sec"
, SWITCH_TRUE, -1)
)) {
1823 int v = atoi(val);
1824 if (v >= 0) {
1825 rtp_hold_timeout_sec = v;
1826 }
1827 }
1828
1829 if (rtp_timeout_sec) {
1830 engine->max_missed_packets = (engine->read_impl.samples_per_second * rtp_timeout_sec) /
1831 engine->read_impl.samples_per_packet;
1832
1833 switch_rtp_set_max_missed_packets(engine->rtp_session, engine->max_missed_packets);
1834 if (!rtp_hold_timeout_sec) {
1835 rtp_hold_timeout_sec = rtp_timeout_sec * 10;
1836 }
1837 }
1838
1839 if (rtp_hold_timeout_sec) {
1840 engine->max_missed_hold_packets = (engine->read_impl.samples_per_second * rtp_hold_timeout_sec) /
1841 engine->read_impl.samples_per_packet;
1842 }
1843 }
1844
1845 check_jb(session, NULL((void*)0));
1846
1847 engine->check_frames = 0;
1848 engine->last_ts = 0;
1849 engine->last_seq = 0;
1850
1851 do_cng = 1;
1852 }
1853
1854 if (do_cng) {
1855 /* return CNG for now */
1856 *frame = &engine->read_frame;
1857 switch_set_flag((*frame), SFF_CNG)((*frame))->flags |= (SFF_CNG);
1858 (*frame)->datalen = engine->read_impl.encoded_bytes_per_packet;
1859 memset((*frame)->data, 0, (*frame)->datalen);
1860 switch_goto_status(SWITCH_STATUS_SUCCESS, end)status = SWITCH_STATUS_SUCCESS; goto end;
1861 }
1862
1863
1864 /* Try to read an RTCP frame, if successful raise an event */
1865 if (switch_rtcp_zerocopy_read_frame(engine->rtp_session, &rtcp_frame) == SWITCH_STATUS_SUCCESS) {
1866 switch_event_t *event;
1867
1868 if (switch_event_create(&event, SWITCH_EVENT_RECV_RTCP_MESSAGE)switch_event_create_subclass_detailed("src/switch_core_media.c"
, (const char * )(const char *)__func__, 1868, &event, SWITCH_EVENT_RECV_RTCP_MESSAGE
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1869 char value[30];
1870 char header[50];
1871 int i;
1872
1873 char *uuid = switch_core_session_get_uuid(session);
1874 if (uuid) {
1875 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(session));
1876 }
1877
1878 snprintf(value, sizeof(value), "%.8x", rtcp_frame.ssrc);
1879 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SSRC", value);
1880
1881 snprintf(value, sizeof(value), "%u", rtcp_frame.ntp_msw);
1882 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "NTP-Most-Significant-Word", value);
1883
1884 snprintf(value, sizeof(value), "%u", rtcp_frame.ntp_lsw);
1885 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "NTP-Least-Significant-Word", value);
1886
1887 snprintf(value, sizeof(value), "%u", rtcp_frame.timestamp);
1888 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "RTP-Timestamp", value);
1889
1890 snprintf(value, sizeof(value), "%u", rtcp_frame.packet_count);
1891 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Sender-Packet-Count", value);
1892
1893 snprintf(value, sizeof(value), "%u", rtcp_frame.octect_count);
1894 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Octect-Packet-Count", value);
1895
1896 snprintf(value, sizeof(value), "%" SWITCH_SIZE_T_FMT"ld", engine->read_frame.timestamp);
1897 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Last-RTP-Timestamp", value);
1898
1899 snprintf(value, sizeof(value), "%u", engine->read_frame.rate);
1900 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "RTP-Rate", value);
1901
1902 snprintf(value, sizeof(value), "%" SWITCH_TIME_T_FMT"ld", switch_time_now());
1903 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Capture-Time", value);
1904
1905 // Add sources info
1906 for (i = 0; i < rtcp_frame.report_count; i++) {
1907 snprintf(header, sizeof(header), "Source%u-SSRC", i);
1908 snprintf(value, sizeof(value), "%.8x", rtcp_frame.reports[i].ssrc);
1909 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, header, value);
1910 snprintf(header, sizeof(header), "Source%u-Fraction", i);
1911 snprintf(value, sizeof(value), "%u", rtcp_frame.reports[i].fraction);
1912 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, header, value);
1913 snprintf(header, sizeof(header), "Source%u-Lost", i);
1914 snprintf(value, sizeof(value), "%u", rtcp_frame.reports[i].lost);
1915 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, header, value);
1916 snprintf(header, sizeof(header), "Source%u-Highest-Sequence-Number-Received", i);
1917 snprintf(value, sizeof(value), "%u", rtcp_frame.reports[i].highest_sequence_number_received);
1918 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, header, value);
1919 snprintf(header, sizeof(header), "Source%u-Jitter", i);
1920 snprintf(value, sizeof(value), "%u", rtcp_frame.reports[i].jitter);
1921 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, header, value);
1922 snprintf(header, sizeof(header), "Source%u-LSR", i);
1923 snprintf(value, sizeof(value), "%u", rtcp_frame.reports[i].lsr);
1924 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, header, value);
1925 snprintf(header, sizeof(header), "Source%u-DLSR", i);
1926 snprintf(value, sizeof(value), "%u", rtcp_frame.reports[i].dlsr);
1927 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, header, value);
1928 }
1929
1930 switch_event_fire(&event)switch_event_fire_detailed("src/switch_core_media.c", (const char
* )(const char *)__func__, 1930, &event, ((void*)0))
;
1931 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 1931, (const char*)(session)
, SWITCH_LOG_DEBUG10, "Dispatched RTCP event\n");
1932 }
1933 }
1934
1935 /* Fast PASS! */
1936 if (switch_test_flag((&engine->read_frame), SFF_PROXY_PACKET)(((&engine->read_frame))->flags & SFF_PROXY_PACKET
)
) {
1937 *frame = &engine->read_frame;
1938 switch_goto_status(SWITCH_STATUS_SUCCESS, end)status = SWITCH_STATUS_SUCCESS; goto end;
1939 }
1940
1941 if (switch_rtp_has_dtmf(engine->rtp_session)) {
1942 switch_dtmf_t dtmf = { 0 };
1943 switch_rtp_dequeue_dtmf(engine->rtp_session, &dtmf);
1944 switch_channel_queue_dtmf(session->channel, &dtmf);
1945 }
1946
1947 if (engine->read_frame.datalen > 0) {
1948 uint32_t bytes = 0;
1949 int frames = 1;
1950
1951 /* autofix timing */
1952 if (!switch_test_flag((&engine->read_frame), SFF_CNG)(((&engine->read_frame))->flags & SFF_CNG)) {
1953 if (!engine->read_codec.implementation || !switch_core_codec_ready(&engine->read_codec)) {
1954 *frame = NULL((void*)0);
1955 switch_goto_status(SWITCH_STATUS_GENERR, end)status = SWITCH_STATUS_GENERR; goto end;
1956 }
1957
1958 /* check for timing issues */
1959 if (smh->media_flags[SCMF_AUTOFIX_TIMING] && engine->check_frames < MAX_CODEC_CHECK_FRAMES50) {
1960
1961
1962 engine->check_frames++;
1963
1964 if (!engine->read_impl.encoded_bytes_per_packet) {
1965 engine->check_frames = MAX_CODEC_CHECK_FRAMES50;
1966 goto skip;
1967 }
1968
1969 if (smh->media_flags[SCMF_AUTOFIX_TIMING] && (engine->read_frame.datalen % 10) == 0) {
1970
1971 if (engine->last_ts && engine->read_frame.datalen != engine->read_impl.encoded_bytes_per_packet) {
1972
1973 uint32_t codec_ms = (int) (engine->read_frame.timestamp -
1974 engine->last_ts) / (engine->read_impl.samples_per_second / 1000);
1975
1976 if (engine->last_seq && (int) (engine->read_frame.seq - engine->last_seq) > 1) {
1977 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 1977, (const char*)(session)
, SWITCH_LOG_DEBUG, "Correcting calculated ptime value from %d to %d to compensate for %d lost packet(s)\n", codec_ms, codec_ms / (int) (engine->read_frame.seq - engine->last_seq), (int) (engine->read_frame.seq - engine->last_seq - 1));
1978 codec_ms = codec_ms / (int) (engine->read_frame.seq - engine->last_seq);
1979 }
1980
1981 if ((codec_ms % 10) != 0 || codec_ms > engine->read_impl.samples_per_packet * 10) {
1982 engine->last_ts = 0;
1983 engine->last_seq = 0;
1984 goto skip;
1985 }
1986
1987
1988 if (engine->last_codec_ms && engine->last_codec_ms == codec_ms) {
1989 engine->mismatch_count++;
1990 }
1991
1992 engine->last_codec_ms = codec_ms;
1993
1994 if (engine->mismatch_count > MAX_MISMATCH_FRAMES5) {
1995 if (codec_ms != engine->cur_payload_map->codec_ms) {
1996
1997 if (codec_ms > 120) { /* yeah right */
1998 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 1998, (const char*)(session)
, SWITCH_LOG_WARNING,
1999 "Your phone is trying to send timestamps that suggest an increment of %dms per packet\n"
2000 "That seems hard to believe so I am going to go on ahead and um ignore that, mmkay?\n",
2001 (int) codec_ms);
2002 engine->check_frames = MAX_CODEC_CHECK_FRAMES50;
2003 goto skip;
2004 }
2005
2006 engine->read_frame.datalen = 0;
2007
2008 if (codec_ms != engine->cur_payload_map->codec_ms) {
2009 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2009, (const char*)(session)
, SWITCH_LOG_WARNING,
2010 "Asynchronous PTIME not supported, changing our end from %d to %d\n",
2011 (int) engine->cur_payload_map->codec_ms,
2012 (int) codec_ms
2013 );
2014
2015 switch_channel_set_variable_printf(session->channel, "rtp_h_X-Broken-PTIME", "Adv=%d;Sent=%d",
2016 (int) engine->cur_payload_map->codec_ms, (int) codec_ms);
2017
2018 engine->cur_payload_map->codec_ms = codec_ms;
2019
2020 /* mark to re-set codec */
2021 engine->reset_codec = 2;
2022 }
2023 }
2024 }
2025
2026 } else {
2027 engine->mismatch_count = 0;
2028 }
2029
2030 engine->last_ts = engine->read_frame.timestamp;
2031 engine->last_seq = engine->read_frame.seq;
2032
2033
2034 } else {
2035 engine->mismatch_count = 0;
2036 engine->last_ts = 0;
2037 engine->last_seq = 0;
2038 }
2039 }
2040
2041 /* autofix payload type */
2042
2043 if (!engine->reset_codec &&
2044 engine->codec_negotiated &&
2045 (!smh->mparams->cng_pt || engine->read_frame.payload != smh->mparams->cng_pt) &&
2046 (!smh->mparams->recv_te || engine->read_frame.payload != smh->mparams->recv_te) &&
2047 (!smh->mparams->te || engine->read_frame.payload != smh->mparams->te) &&
2048 engine->read_frame.payload != engine->cur_payload_map->recv_pt &&
2049 engine->read_frame.payload != engine->cur_payload_map->agreed_pt &&
2050 engine->read_frame.payload != engine->cur_payload_map->pt) {
2051
2052 payload_map_t *pmap;
2053
2054
2055 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2055, (const char*)(session)
, SWITCH_LOG_DEBUG,
2056 "alternate payload received (received %d, expecting %d)\n",
2057 (int) engine->read_frame.payload, (int) engine->cur_payload_map->agreed_pt);
2058
2059
2060 /* search for payload type */
2061 switch_mutex_lock(smh->sdp_mutex);
2062 for (pmap = engine->payload_map; pmap; pmap = pmap->next) {
2063 if (engine->read_frame.payload == pmap->recv_pt && pmap->negotiated) {
2064 engine->cur_payload_map = pmap;
2065 engine->cur_payload_map->current = 1;
2066 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2066, (const char*)(session)
, SWITCH_LOG_WARNING,
2067 "Changing current codec to %s (payload type %d).\n",
2068 pmap->iananame, pmap->pt);
2069
2070 /* mark to re-set codec */
2071 engine->reset_codec = 1;
2072 break;
2073 }
2074 }
2075 switch_mutex_unlock(smh->sdp_mutex);
2076
2077 if (!engine->reset_codec) {
2078 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2078, (const char*)(session)
, SWITCH_LOG_WARNING,
2079 "Could not change to payload type %d, ignoring...\n",
2080 (int) engine->read_frame.payload);
2081 }
2082 }
2083
2084 skip:
2085
2086 if ((bytes = engine->read_impl.encoded_bytes_per_packet)) {
2087 frames = (engine->read_frame.datalen / bytes);
2088 }
2089 engine->read_frame.samples = (int) (frames * engine->read_impl.samples_per_packet);
2090
2091 if (engine->read_frame.datalen == 0) {
2092 continue;
2093 }
2094 }
2095 break;
2096 }
2097 }
2098
2099 if (engine->read_frame.datalen == 0) {
2100 *frame = NULL((void*)0);
2101 }
2102
2103 *frame = &engine->read_frame;
2104
2105 status = SWITCH_STATUS_SUCCESS;
2106
2107 end:
2108
2109 if (engine->read_mutex[type]) {
2110 switch_mutex_unlock(engine->read_mutex[type]);
2111 }
2112
2113 return status;
2114}
2115
2116//?
2117SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_media_write_frame(switch_core_session_t *session,
2118 switch_frame_t *frame, switch_io_flag_t flags, int stream_id, switch_media_type_t type)
2119{
2120 switch_status_t status = SWITCH_STATUS_SUCCESS;
2121 int bytes = 0, samples = 0, frames = 0;
2122 switch_rtp_engine_t *engine;
2123 switch_media_handle_t *smh;
2124
2125 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 2125, __PRETTY_FUNCTION__))
;
2126
2127 if (!(smh = session->media_handle)) {
2128 return SWITCH_STATUS_FALSE;
2129 }
2130
2131 if (!smh->media_flags[SCMF_RUNNING]) {
2132 return SWITCH_STATUS_FALSE;
2133 }
2134
2135 engine = &smh->engines[type];
2136
2137 while (!(engine->read_codec.implementation && switch_rtp_ready(engine->rtp_session))) {
2138 if (switch_channel_ready(session->channel)switch_channel_test_ready(session->channel, SWITCH_TRUE, SWITCH_FALSE
)
) {
2139 switch_yield(10000)switch_sleep(10000);;
2140 } else {
2141 return SWITCH_STATUS_GENERR;
2142 }
2143 }
2144
2145 if (!engine->read_codec.implementation || !switch_core_codec_ready(&engine->read_codec)) {
2146 return SWITCH_STATUS_GENERR;
2147 }
2148
2149
2150 if (!engine->read_codec.implementation || !switch_core_codec_ready(&engine->read_codec)) {
2151 return SWITCH_STATUS_FALSE;
2152 }
2153
2154 if (!switch_test_flag(frame, SFF_CNG)((frame)->flags & SFF_CNG) && !switch_test_flag(frame, SFF_PROXY_PACKET)((frame)->flags & SFF_PROXY_PACKET)) {
2155 if (engine->read_impl.encoded_bytes_per_packet) {
2156 bytes = engine->read_impl.encoded_bytes_per_packet;
2157 frames = ((int) frame->datalen / bytes);
2158 } else
2159 frames = 1;
2160
2161 samples = frames * engine->read_impl.samples_per_packet;
2162 }
2163
2164 engine->timestamp_send += samples;
2165
2166 if (switch_rtp_write_frame(engine->rtp_session, frame) < 0) {
2167 status = SWITCH_STATUS_FALSE;
2168 }
2169
2170
2171 return status;
2172}
2173
2174
2175//?
2176SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_copy_t38_options(switch_t38_options_t *t38_options, switch_core_session_t *session)
2177{
2178 switch_channel_t *channel = switch_core_session_get_channel(session);
2179 switch_t38_options_t *local_t38_options = switch_channel_get_private(channel, "t38_options");
2180
2181 switch_assert(t38_options)((t38_options) ? (void) (0) : __assert_fail ("t38_options", "src/switch_core_media.c"
, 2181, __PRETTY_FUNCTION__))
;
2182
2183 if (!local_t38_options) {
2184 local_t38_options = switch_core_session_alloc(session, sizeof(switch_t38_options_t))switch_core_perform_session_alloc(session, sizeof(switch_t38_options_t
), "src/switch_core_media.c", (const char *)__func__, 2184)
;
2185 }
2186
2187 local_t38_options->T38MaxBitRate = t38_options->T38MaxBitRate;
2188 local_t38_options->T38FaxFillBitRemoval = t38_options->T38FaxFillBitRemoval;
2189 local_t38_options->T38FaxTranscodingMMR = t38_options->T38FaxTranscodingMMR;
2190 local_t38_options->T38FaxTranscodingJBIG = t38_options->T38FaxTranscodingJBIG;
2191 local_t38_options->T38FaxRateManagement = switch_core_session_strdup(session, t38_options->T38FaxRateManagement)switch_core_perform_session_strdup(session, t38_options->T38FaxRateManagement
, "src/switch_core_media.c", (const char *)__func__, 2191)
;
2192 local_t38_options->T38FaxMaxBuffer = t38_options->T38FaxMaxBuffer;
2193 local_t38_options->T38FaxMaxDatagram = t38_options->T38FaxMaxDatagram;
2194 local_t38_options->T38FaxUdpEC = switch_core_session_strdup(session, t38_options->T38FaxUdpEC)switch_core_perform_session_strdup(session, t38_options->T38FaxUdpEC
, "src/switch_core_media.c", (const char *)__func__, 2194)
;
2195 local_t38_options->T38VendorInfo = switch_core_session_strdup(session, t38_options->T38VendorInfo)switch_core_perform_session_strdup(session, t38_options->T38VendorInfo
, "src/switch_core_media.c", (const char *)__func__, 2195)
;
2196 local_t38_options->remote_ip = switch_core_session_strdup(session, t38_options->remote_ip)switch_core_perform_session_strdup(session, t38_options->remote_ip
, "src/switch_core_media.c", (const char *)__func__, 2196)
;
2197 local_t38_options->remote_port = t38_options->remote_port;
2198
2199
2200 switch_channel_set_private(channel, "t38_options", local_t38_options);
2201
2202}
2203
2204//?
2205SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_media_get_offered_pt(switch_core_session_t *session, const switch_codec_implementation_t *mimp, switch_payload_t *pt)
2206{
2207 int i = 0;
2208 switch_media_handle_t *smh;
2209
2210 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 2210, __PRETTY_FUNCTION__))
;
2211
2212 if (!(smh = session->media_handle) || !mimp) {
2213 return SWITCH_STATUS_FALSE;
2214 }
2215
2216
2217 for (i = 0; i < smh->mparams->num_codecs; i++) {
2218 const switch_codec_implementation_t *imp = smh->codecs[i];
2219
2220 if (!strcasecmp(imp->iananame, mimp->iananame) && imp->actual_samples_per_second == mimp->actual_samples_per_second) {
2221 *pt = smh->ianacodes[i];
2222
2223 return SWITCH_STATUS_SUCCESS;
2224 }
2225 }
2226
2227 return SWITCH_STATUS_FALSE;
2228}
2229
2230
2231
2232//?
2233SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_media_set_video_codec(switch_core_session_t *session, int force)
2234{
2235 switch_media_handle_t *smh;
2236 switch_rtp_engine_t *v_engine;
2237
2238 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 2238, __PRETTY_FUNCTION__))
;
2239
2240 if (!(smh = session->media_handle)) {
2241 return SWITCH_STATUS_FALSE;
2242 }
2243 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
2244
2245
2246 if (!v_engine->codec_negotiated) {
2247 return SWITCH_STATUS_FALSE;
2248 }
2249
2250 if (v_engine->read_codec.implementation && switch_core_codec_ready(&v_engine->read_codec)) {
2251 if (!force) {
2252 return SWITCH_STATUS_SUCCESS;
2253 }
2254 if (strcasecmp(v_engine->read_codec.implementation->iananame, v_engine->cur_payload_map->rm_encoding) ||
2255 v_engine->read_codec.implementation->samples_per_second != v_engine->cur_payload_map->rm_rate) {
2256
2257 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2257, (const char*)(session)
, SWITCH_LOG_DEBUG, "Changing Codec from %s to %s\n",
2258 v_engine->read_codec.implementation->iananame, v_engine->cur_payload_map->rm_encoding);
2259 switch_core_codec_destroy(&v_engine->read_codec);
2260 switch_core_codec_destroy(&v_engine->write_codec);
2261 } else {
2262 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2262, (const char*)(session)
, SWITCH_LOG_DEBUG, "Already using %s\n",
2263 v_engine->read_codec.implementation->iananame);
2264 return SWITCH_STATUS_SUCCESS;
2265 }
2266 }
2267
2268
2269
2270 if (switch_core_codec_init(&v_engine->read_codec,switch_core_codec_init_with_bitrate(&v_engine->read_codec
, v_engine->cur_payload_map->rm_encoding, v_engine->
cur_payload_map->rm_fmtp, v_engine->cur_payload_map->
rm_rate, 0, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
2271 v_engine->cur_payload_map->rm_encoding,switch_core_codec_init_with_bitrate(&v_engine->read_codec
, v_engine->cur_payload_map->rm_encoding, v_engine->
cur_payload_map->rm_fmtp, v_engine->cur_payload_map->
rm_rate, 0, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
2272 v_engine->cur_payload_map->rm_fmtp,switch_core_codec_init_with_bitrate(&v_engine->read_codec
, v_engine->cur_payload_map->rm_encoding, v_engine->
cur_payload_map->rm_fmtp, v_engine->cur_payload_map->
rm_rate, 0, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
2273 v_engine->cur_payload_map->rm_rate,switch_core_codec_init_with_bitrate(&v_engine->read_codec
, v_engine->cur_payload_map->rm_encoding, v_engine->
cur_payload_map->rm_fmtp, v_engine->cur_payload_map->
rm_rate, 0, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
2274 0,switch_core_codec_init_with_bitrate(&v_engine->read_codec
, v_engine->cur_payload_map->rm_encoding, v_engine->
cur_payload_map->rm_fmtp, v_engine->cur_payload_map->
rm_rate, 0, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
2275 1,switch_core_codec_init_with_bitrate(&v_engine->read_codec
, v_engine->cur_payload_map->rm_encoding, v_engine->
cur_payload_map->rm_fmtp, v_engine->cur_payload_map->
rm_rate, 0, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
2276 SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,switch_core_codec_init_with_bitrate(&v_engine->read_codec
, v_engine->cur_payload_map->rm_encoding, v_engine->
cur_payload_map->rm_fmtp, v_engine->cur_payload_map->
rm_rate, 0, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
2277 NULL, switch_core_session_get_pool(session))switch_core_codec_init_with_bitrate(&v_engine->read_codec
, v_engine->cur_payload_map->rm_encoding, v_engine->
cur_payload_map->rm_fmtp, v_engine->cur_payload_map->
rm_rate, 0, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
!= SWITCH_STATUS_SUCCESS) {
2278 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2278, (const char*)(session)
, SWITCH_LOG_ERROR, "Can't load codec?\n");
2279 return SWITCH_STATUS_FALSE;
2280 } else {
2281 if (switch_core_codec_init(&v_engine->write_codec,switch_core_codec_init_with_bitrate(&v_engine->write_codec
, v_engine->cur_payload_map->rm_encoding, v_engine->
cur_payload_map->rm_fmtp, v_engine->cur_payload_map->
rm_rate, 0, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
2282 v_engine->cur_payload_map->rm_encoding,switch_core_codec_init_with_bitrate(&v_engine->write_codec
, v_engine->cur_payload_map->rm_encoding, v_engine->
cur_payload_map->rm_fmtp, v_engine->cur_payload_map->
rm_rate, 0, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
2283 v_engine->cur_payload_map->rm_fmtp,switch_core_codec_init_with_bitrate(&v_engine->write_codec
, v_engine->cur_payload_map->rm_encoding, v_engine->
cur_payload_map->rm_fmtp, v_engine->cur_payload_map->
rm_rate, 0, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
2284 v_engine->cur_payload_map->rm_rate,switch_core_codec_init_with_bitrate(&v_engine->write_codec
, v_engine->cur_payload_map->rm_encoding, v_engine->
cur_payload_map->rm_fmtp, v_engine->cur_payload_map->
rm_rate, 0, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
2285 0,switch_core_codec_init_with_bitrate(&v_engine->write_codec
, v_engine->cur_payload_map->rm_encoding, v_engine->
cur_payload_map->rm_fmtp, v_engine->cur_payload_map->
rm_rate, 0, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
2286 1,switch_core_codec_init_with_bitrate(&v_engine->write_codec
, v_engine->cur_payload_map->rm_encoding, v_engine->
cur_payload_map->rm_fmtp, v_engine->cur_payload_map->
rm_rate, 0, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
2287 SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,switch_core_codec_init_with_bitrate(&v_engine->write_codec
, v_engine->cur_payload_map->rm_encoding, v_engine->
cur_payload_map->rm_fmtp, v_engine->cur_payload_map->
rm_rate, 0, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
2288 NULL, switch_core_session_get_pool(session))switch_core_codec_init_with_bitrate(&v_engine->write_codec
, v_engine->cur_payload_map->rm_encoding, v_engine->
cur_payload_map->rm_fmtp, v_engine->cur_payload_map->
rm_rate, 0, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
!= SWITCH_STATUS_SUCCESS) {
2289 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2289, (const char*)(session)
, SWITCH_LOG_ERROR, "Can't load codec?\n");
2290 return SWITCH_STATUS_FALSE;
2291 } else {
2292 v_engine->read_frame.rate = v_engine->cur_payload_map->rm_rate;
2293 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2293, (const char*)(session)
, SWITCH_LOG_DEBUG, "Set VIDEO Codec %s %s/%ld %d ms\n",
2294 switch_channel_get_name(session->channel), v_engine->cur_payload_map->rm_encoding,
2295 v_engine->cur_payload_map->rm_rate, v_engine->cur_payload_map->codec_ms);
2296 v_engine->read_frame.codec = &v_engine->read_codec;
2297
2298 v_engine->write_codec.fmtp_out = switch_core_session_strdup(session, v_engine->write_codec.fmtp_out)switch_core_perform_session_strdup(session, v_engine->write_codec
.fmtp_out, "src/switch_core_media.c", (const char *)__func__,
2298)
;
2299
2300 v_engine->write_codec.agreed_pt = v_engine->cur_payload_map->agreed_pt;
2301 v_engine->read_codec.agreed_pt = v_engine->cur_payload_map->agreed_pt;
2302 switch_core_session_set_video_read_codec(session, &v_engine->read_codec);
2303 switch_core_session_set_video_write_codec(session, &v_engine->write_codec);
2304
2305
2306 switch_channel_set_variable_printf(session->channel, "rtp_last_video_codec_string", "%s@%dh",
2307 v_engine->cur_payload_map->rm_encoding, v_engine->cur_payload_map->rm_rate);
2308
2309
2310 if (switch_rtp_ready(v_engine->rtp_session)) {
2311 switch_core_session_message_t msg = { 0 };
2312
2313 msg.from = __FILE__"src/switch_core_media.c";
2314 msg.message_id = SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ;
2315
2316 switch_rtp_set_default_payload(v_engine->rtp_session, v_engine->cur_payload_map->agreed_pt);
2317
2318 //XX
2319
2320 switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg
, "src/switch_core_media.c", (const char *)__func__, 2320)
;
2321
2322
2323 }
2324
2325 switch_channel_set_variable(session->channel, "rtp_use_video_codec_name", v_engine->cur_payload_map->rm_encoding)switch_channel_set_variable_var_check(session->channel, "rtp_use_video_codec_name"
, v_engine->cur_payload_map->rm_encoding, SWITCH_TRUE)
;
2326 switch_channel_set_variable(session->channel, "rtp_use_video_codec_fmtp", v_engine->cur_payload_map->rm_fmtp)switch_channel_set_variable_var_check(session->channel, "rtp_use_video_codec_fmtp"
, v_engine->cur_payload_map->rm_fmtp, SWITCH_TRUE)
;
2327 switch_channel_set_variable_printf(session->channel, "rtp_use_video_codec_rate", "%d", v_engine->cur_payload_map->rm_rate);
2328 switch_channel_set_variable_printf(session->channel, "rtp_use_video_codec_ptime", "%d", 0);
2329
2330 }
2331 }
2332 return SWITCH_STATUS_SUCCESS;
2333}
2334
2335
2336//?
2337SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_media_set_codec(switch_core_session_t *session, int force, uint32_t codec_flags)
2338{
2339 switch_status_t status = SWITCH_STATUS_SUCCESS;
2340 int resetting = 0;
2341 switch_media_handle_t *smh;
2342 switch_rtp_engine_t *a_engine;
2343
2344 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 2344, __PRETTY_FUNCTION__))
;
2345
2346 if (!(smh = session->media_handle)) {
2347 return SWITCH_STATUS_FALSE;
2348 }
2349 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
2350
2351 if (!a_engine->cur_payload_map->iananame) {
2352 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2352, (const char*)(session)
, SWITCH_LOG_DEBUG, "No audio codec available\n");
2353 switch_goto_status(SWITCH_STATUS_FALSE, end)status = SWITCH_STATUS_FALSE; goto end;
2354 }
2355
2356 if (switch_core_codec_ready(&a_engine->read_codec)) {
2357 if (!force) {
2358 switch_goto_status(SWITCH_STATUS_SUCCESS, end)status = SWITCH_STATUS_SUCCESS; goto end;
2359 }
2360 if (strcasecmp(a_engine->read_impl.iananame, a_engine->cur_payload_map->iananame) ||
2361 (uint32_t) a_engine->read_impl.microseconds_per_packet / 1000 != a_engine->cur_payload_map->codec_ms ||
2362 a_engine->read_impl.samples_per_second != a_engine->cur_payload_map->rm_rate ) {
2363
2364 if (session->read_resampler) {
2365 switch_mutex_lock(session->resample_mutex);
2366 switch_resample_destroy(&session->read_resampler);
2367 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2367, (const char*)(session)
, SWITCH_LOG_NOTICE, "Deactivating read resampler\n");
2368 switch_mutex_unlock(session->resample_mutex);
2369 }
2370
2371 if (session->write_resampler) {
2372 switch_mutex_lock(session->resample_mutex);
2373 switch_resample_destroy(&session->write_resampler);
2374 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2374, (const char*)(session)
, SWITCH_LOG_NOTICE, "Deactivating write resampler\n");
2375 switch_mutex_unlock(session->resample_mutex);
2376 }
2377
2378 switch_core_session_reset(session, 0, 0);
2379 switch_channel_audio_sync(session->channel)switch_channel_perform_audio_sync(session->channel, "src/switch_core_media.c"
, (const char *)__func__, 2379)
;
2380
2381 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2381, (const char*)(session)
, SWITCH_LOG_DEBUG,
2382 "Changing Codec from %s@%dms@%dhz to %s@%dms@%luhz\n",
2383 a_engine->read_impl.iananame,
2384 a_engine->read_impl.microseconds_per_packet / 1000,
2385 a_engine->read_impl.samples_per_second,
2386
2387 a_engine->cur_payload_map->iananame,
2388 a_engine->cur_payload_map->codec_ms,
2389 a_engine->cur_payload_map->rm_rate);
2390
2391 switch_yield(a_engine->read_impl.microseconds_per_packet)switch_sleep(a_engine->read_impl.microseconds_per_packet);;
2392 switch_core_session_lock_codec_write(session);
2393 switch_core_session_lock_codec_read(session);
2394 resetting = 1;
2395 switch_yield(a_engine->read_impl.microseconds_per_packet)switch_sleep(a_engine->read_impl.microseconds_per_packet);;
2396 switch_core_codec_destroy(&a_engine->read_codec);
2397 switch_core_codec_destroy(&a_engine->write_codec);
2398 switch_channel_audio_sync(session->channel)switch_channel_perform_audio_sync(session->channel, "src/switch_core_media.c"
, (const char *)__func__, 2398)
;
2399 } else {
2400 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2400, (const char*)(session)
, SWITCH_LOG_DEBUG, "Already using %s\n", a_engine->read_impl.iananame);
2401 switch_goto_status(SWITCH_STATUS_SUCCESS, end)status = SWITCH_STATUS_SUCCESS; goto end;
2402 }
2403 }
2404
2405 if (switch_core_codec_init_with_bitrate(&a_engine->read_codec,
2406 a_engine->cur_payload_map->iananame,
2407 a_engine->cur_payload_map->rm_fmtp,
2408 a_engine->cur_payload_map->rm_rate,
2409 a_engine->cur_payload_map->codec_ms,
2410 a_engine->cur_payload_map->channels,
2411 a_engine->cur_payload_map->bitrate,
2412 SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE | codec_flags,
2413 NULL((void*)0), switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
2414 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2414, (const char*)(session)
, SWITCH_LOG_ERROR, "Can't load codec?\n");
2415 switch_channel_hangup(session->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)switch_channel_perform_hangup(session->channel, "src/switch_core_media.c"
, (const char *)__func__, 2415, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION
)
;
2416 switch_goto_status(SWITCH_STATUS_FALSE, end)status = SWITCH_STATUS_FALSE; goto end;
2417 }
2418
2419 a_engine->read_codec.session = session;
2420
2421
2422 if (switch_core_codec_init_with_bitrate(&a_engine->write_codec,
2423 a_engine->cur_payload_map->iananame,
2424 a_engine->cur_payload_map->rm_fmtp,
2425 a_engine->cur_payload_map->rm_rate,
2426 a_engine->cur_payload_map->codec_ms,
2427 a_engine->cur_payload_map->channels,
2428 a_engine->cur_payload_map->bitrate,
2429 SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE | codec_flags,
2430 NULL((void*)0), switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
2431 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2431, (const char*)(session)
, SWITCH_LOG_ERROR, "Can't load codec?\n");
2432 switch_channel_hangup(session->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)switch_channel_perform_hangup(session->channel, "src/switch_core_media.c"
, (const char *)__func__, 2432, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION
)
;
2433 switch_goto_status(SWITCH_STATUS_FALSE, end)status = SWITCH_STATUS_FALSE; goto end;
2434 }
2435
2436 a_engine->write_codec.session = session;
2437
2438 switch_channel_set_variable(session->channel, "rtp_use_codec_name", a_engine->cur_payload_map->iananame)switch_channel_set_variable_var_check(session->channel, "rtp_use_codec_name"
, a_engine->cur_payload_map->iananame, SWITCH_TRUE)
;
2439 switch_channel_set_variable(session->channel, "rtp_use_codec_fmtp", a_engine->cur_payload_map->rm_fmtp)switch_channel_set_variable_var_check(session->channel, "rtp_use_codec_fmtp"
, a_engine->cur_payload_map->rm_fmtp, SWITCH_TRUE)
;
2440 switch_channel_set_variable_printf(session->channel, "rtp_use_codec_rate", "%d", a_engine->cur_payload_map->rm_rate);
2441 switch_channel_set_variable_printf(session->channel, "rtp_use_codec_ptime", "%d", a_engine->cur_payload_map->codec_ms);
2442 switch_channel_set_variable_printf(session->channel, "rtp_use_codec_channels", "%d", a_engine->cur_payload_map->channels);
2443 switch_channel_set_variable_printf(session->channel, "rtp_last_audio_codec_string", "%s@%dh@%di@%dc",
2444 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);
2445
2446 switch_assert(a_engine->read_codec.implementation)((a_engine->read_codec.implementation) ? (void) (0) : __assert_fail
("a_engine->read_codec.implementation", "src/switch_core_media.c"
, 2446, __PRETTY_FUNCTION__))
;
2447 switch_assert(a_engine->write_codec.implementation)((a_engine->write_codec.implementation) ? (void) (0) : __assert_fail
("a_engine->write_codec.implementation", "src/switch_core_media.c"
, 2447, __PRETTY_FUNCTION__))
;
2448
2449 a_engine->read_impl = *a_engine->read_codec.implementation;
2450 a_engine->write_impl = *a_engine->write_codec.implementation;
2451
2452 switch_core_session_set_read_impl(session, a_engine->read_codec.implementation);
2453 switch_core_session_set_write_impl(session, a_engine->write_codec.implementation);
2454
2455 if (switch_rtp_ready(a_engine->rtp_session)) {
2456 switch_assert(a_engine->read_codec.implementation)((a_engine->read_codec.implementation) ? (void) (0) : __assert_fail
("a_engine->read_codec.implementation", "src/switch_core_media.c"
, 2456, __PRETTY_FUNCTION__))
;
2457
2458 if (switch_rtp_change_interval(a_engine->rtp_session,
2459 a_engine->read_impl.microseconds_per_packet,
2460 a_engine->read_impl.samples_per_packet) != SWITCH_STATUS_SUCCESS) {
2461 switch_channel_hangup(session->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(session->channel, "src/switch_core_media.c"
, (const char *)__func__, 2461, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER
)
;
2462 switch_goto_status(SWITCH_STATUS_FALSE, end)status = SWITCH_STATUS_FALSE; goto end;
2463 }
2464 }
2465
2466 a_engine->read_frame.rate = a_engine->cur_payload_map->rm_rate;
2467
2468 if (!switch_core_codec_ready(&a_engine->read_codec)) {
2469 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2469, (const char*)(session)
, SWITCH_LOG_ERROR, "Can't load codec?\n");
2470 switch_goto_status(SWITCH_STATUS_FALSE, end)status = SWITCH_STATUS_FALSE; goto end;
2471 }
2472
2473 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2473, (const char*)(session)
, SWITCH_LOG_DEBUG, "Set Codec %s %s/%ld %d ms %d samples %d bits %d channels\n",
2474 switch_channel_get_name(session->channel), a_engine->cur_payload_map->iananame, a_engine->cur_payload_map->rm_rate,
2475 a_engine->cur_payload_map->codec_ms,
2476 a_engine->read_impl.samples_per_packet, a_engine->read_impl.bits_per_second, a_engine->read_impl.number_of_channels);
2477 a_engine->read_frame.codec = &a_engine->read_codec;
2478 a_engine->read_frame.channels = a_engine->read_impl.number_of_channels;
2479 a_engine->write_codec.agreed_pt = a_engine->cur_payload_map->agreed_pt;
2480 a_engine->read_codec.agreed_pt = a_engine->cur_payload_map->agreed_pt;
2481
2482 if (force != 2) {
2483 switch_core_session_set_real_read_codec(session, &a_engine->read_codec);
2484 switch_core_session_set_write_codec(session, &a_engine->write_codec);
2485 }
2486
2487 a_engine->cur_payload_map->fmtp_out = switch_core_session_strdup(session, a_engine->write_codec.fmtp_out)switch_core_perform_session_strdup(session, a_engine->write_codec
.fmtp_out, "src/switch_core_media.c", (const char *)__func__,
2487)
;
2488
2489 if (switch_rtp_ready(a_engine->rtp_session)) {
2490 switch_rtp_set_default_payload(a_engine->rtp_session, a_engine->cur_payload_map->pt);
2491 }
2492
2493 end:
2494
2495 if (resetting) {
2496 switch_core_session_unlock_codec_write(session);
2497 switch_core_session_unlock_codec_read(session);
2498 }
2499
2500 return status;
2501}
2502static void clear_ice(switch_core_session_t *session, switch_media_type_t type)
2503{
2504 switch_media_handle_t *smh;
2505 switch_rtp_engine_t *engine;
2506
2507 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 2507, __PRETTY_FUNCTION__))
;
2508
2509 if (!(smh = session->media_handle)) {
2510 return;
2511 }
2512
2513 engine = &smh->engines[type];
2514
2515 engine->ice_in.chosen[0] = 0;
2516 engine->ice_in.chosen[1] = 0;
2517 engine->ice_in.cand_idx = 0;
2518 memset(&engine->ice_in, 0, sizeof(engine->ice_in));
2519 engine->remote_rtcp_port = 0;
2520
2521 if (engine->rtp_session) {
2522 switch_rtp_reset(engine->rtp_session);
2523 }
2524
2525}
2526
2527//?
2528SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_clear_ice(switch_core_session_t *session)
2529{
2530 clear_ice(session, SWITCH_MEDIA_TYPE_AUDIO);
2531 clear_ice(session, SWITCH_MEDIA_TYPE_VIDEO);
2532
2533}
2534
2535SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_pause(switch_core_session_t *session)
2536{
2537 switch_rtp_engine_t *a_engine, *v_engine;
2538 switch_media_handle_t *smh;
2539
2540 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 2540, __PRETTY_FUNCTION__))
;
2541
2542 if (!(smh = session->media_handle)) {
2543 return;
2544 }
2545
2546 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
2547 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
2548
2549 if (a_engine->rtp_session) {
2550 switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PAUSE);
2551 }
2552
2553 if (v_engine->rtp_session) {
2554 switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_PAUSE);
2555 }
2556}
2557
2558SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_resume(switch_core_session_t *session)
2559{
2560 switch_rtp_engine_t *a_engine, *v_engine;
2561 switch_media_handle_t *smh;
2562
2563 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 2563, __PRETTY_FUNCTION__))
;
2564
2565 if (!(smh = session->media_handle)) {
2566 return;
2567 }
2568
2569 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
2570 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
2571
2572 if (a_engine->rtp_session) {
2573 switch_rtp_clear_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PAUSE);
2574 }
2575
2576 if (v_engine->rtp_session) {
2577 switch_rtp_clear_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_PAUSE);
2578 }
2579}
2580
2581
2582//?
2583SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_media_add_ice_acl(switch_core_session_t *session, switch_media_type_t type, const char *acl_name)
2584{
2585 switch_media_handle_t *smh;
2586 switch_rtp_engine_t *engine;
2587
2588 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 2588, __PRETTY_FUNCTION__))
;
2589
2590 if (!(smh = session->media_handle)) {
2591 return SWITCH_STATUS_FALSE;
2592 }
2593
2594 engine = &smh->engines[type];
2595
2596 if (engine->cand_acl_count < SWITCH_MAX_CAND_ACL25) {
2597 engine->cand_acl[engine->cand_acl_count++] = switch_core_session_strdup(session, acl_name)switch_core_perform_session_strdup(session, acl_name, "src/switch_core_media.c"
, (const char *)__func__, 2597)
;
2598 return SWITCH_STATUS_SUCCESS;
2599 }
2600
2601 return SWITCH_STATUS_FALSE;
2602}
2603
2604//?
2605SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_check_video_codecs(switch_core_session_t *session)
2606{
2607 switch_media_handle_t *smh;
2608
2609 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 2609, __PRETTY_FUNCTION__))
;
2610
2611 if (!(smh = session->media_handle)) {
2612 return;
2613 }
2614
2615 if (smh->mparams->num_codecs && !switch_channel_test_flag(session->channel, CF_VIDEO_POSSIBLE)) {
2616 int i;
2617 smh->video_count = 0;
2618 for (i = 0; i < smh->mparams->num_codecs; i++) {
2619
2620 if (smh->codecs[i]->codec_type == SWITCH_CODEC_TYPE_VIDEO) {
2621 if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_INBOUND &&
2622 switch_channel_test_flag(session->channel, CF_NOVIDEO)) {
2623 continue;
2624 }
2625 smh->video_count++;
2626 }
2627 }
2628 if (smh->video_count) {
2629 switch_channel_set_flag(session->channel, CF_VIDEO_POSSIBLE)switch_channel_set_flag_value(session->channel, CF_VIDEO_POSSIBLE
, 1)
;
2630 }
2631 }
2632}
2633
2634//?
2635static void generate_local_fingerprint(switch_media_handle_t *smh, switch_media_type_t type)
2636{
2637 switch_rtp_engine_t *engine = &smh->engines[type];
2638
2639 if (!engine->local_dtls_fingerprint.len) {
2640 if (engine->remote_dtls_fingerprint.type) {
2641 engine->local_dtls_fingerprint.type = engine->remote_dtls_fingerprint.type;
2642 } else {
2643 engine->local_dtls_fingerprint.type = "sha-256";
2644 }
2645 switch_core_cert_gen_fingerprint(DTLS_SRTP_FNAME"dtls-srtp", &engine->local_dtls_fingerprint);
2646 }
2647}
2648
2649//?
2650static int dtls_ok(switch_core_session_t *session)
2651{
2652 return switch_channel_test_flag(session->channel, CF_DTLS_OK);
2653}
2654
2655#ifdef _MSC_VER
2656/* remove this if the break is removed from the following for loop which causes unreachable code loop */
2657/* for (i = 0; i < engine->cand_acl_count; i++) { */
2658#pragma warning(push)
2659#pragma warning(disable:4702)
2660#endif
2661
2662//?
2663SWITCH_DECLARE(switch_call_direction_t)__attribute__((visibility("default"))) switch_call_direction_t switch_ice_direction(switch_core_session_t *session)
2664{
2665 switch_call_direction_t r = switch_channel_direction(session->channel);
2666
2667 if (switch_channel_test_flag(session->channel, CF_3PCC)) {
2668 r = (r == SWITCH_CALL_DIRECTION_INBOUND) ? SWITCH_CALL_DIRECTION_OUTBOUND : SWITCH_CALL_DIRECTION_INBOUND;
2669 }
2670
2671 if ((switch_channel_test_flag(session->channel, CF_REINVITE) || switch_channel_test_flag(session->channel, CF_RECOVERING))
2672 && switch_channel_test_flag(session->channel, CF_WEBRTC)) {
2673 r = SWITCH_CALL_DIRECTION_OUTBOUND;
2674 }
2675
2676 return r;
2677}
2678
2679//?
2680static void check_ice(switch_media_handle_t *smh, switch_media_type_t type, sdp_session_t *sdp, sdp_media_t *m)
2681{
2682 switch_rtp_engine_t *engine = &smh->engines[type];
2683 sdp_attribute_t *attr;
2684 int i = 0, got_rtcp_mux = 0;
2685 const char *val;
2686
2687 if (engine->ice_in.chosen[0] && engine->ice_in.chosen[1] && !switch_channel_test_flag(smh->session->channel, CF_REINVITE)) {
2688 return;
2689 }
2690
2691 engine->ice_in.chosen[0] = 0;
2692 engine->ice_in.chosen[1] = 0;
2693 engine->ice_in.cand_idx = 0;
2694
2695 if (m) {
2696 attr = m->m_attributes;
2697 } else {
2698 attr = sdp->sdp_attributes;
2699 }
2700
2701 for (; attr; attr = attr->a_next) {
2702 char *data;
2703 char *fields[15];
2704 int argc = 0, j = 0;
2705 int cid = 0;
2706
2707 if (zstr(attr->a_name)_zstr(attr->a_name)) {
2708 continue;
2709 }
2710
2711 if (!strcasecmp(attr->a_name, "ice-ufrag")) {
2712 engine->ice_in.ufrag = switch_core_session_strdup(smh->session, attr->a_value)switch_core_perform_session_strdup(smh->session, attr->
a_value, "src/switch_core_media.c", (const char *)__func__, 2712
)
;
2713 } else if (!strcasecmp(attr->a_name, "ice-pwd")) {
2714 engine->ice_in.pwd = switch_core_session_strdup(smh->session, attr->a_value)switch_core_perform_session_strdup(smh->session, attr->
a_value, "src/switch_core_media.c", (const char *)__func__, 2714
)
;
2715 } else if (!strcasecmp(attr->a_name, "ice-options")) {
2716 engine->ice_in.options = switch_core_session_strdup(smh->session, attr->a_value)switch_core_perform_session_strdup(smh->session, attr->
a_value, "src/switch_core_media.c", (const char *)__func__, 2716
)
;
2717
2718 } else if (switch_rtp_has_dtls() && dtls_ok(smh->session) && !strcasecmp(attr->a_name, "fingerprint") && !zstr(attr->a_value)_zstr(attr->a_value)) {
2719 char *p;
2720
2721 engine->remote_dtls_fingerprint.type = switch_core_session_strdup(smh->session, attr->a_value)switch_core_perform_session_strdup(smh->session, attr->
a_value, "src/switch_core_media.c", (const char *)__func__, 2721
)
;
2722
2723 if ((p = strchr(engine->remote_dtls_fingerprint.type, ' ')(__extension__ (__builtin_constant_p (' ') && !__builtin_constant_p
(engine->remote_dtls_fingerprint.type) && (' ') ==
'\0' ? (char *) __rawmemchr (engine->remote_dtls_fingerprint
.type, ' ') : __builtin_strchr (engine->remote_dtls_fingerprint
.type, ' ')))
)) {
2724 *p++ = '\0';
2725 switch_set_string(engine->local_dtls_fingerprint.str, p)switch_copy_string(engine->local_dtls_fingerprint.str, p, sizeof
(engine->local_dtls_fingerprint.str))
;
2726 }
2727
2728 //if (strcasecmp(engine->remote_dtls_fingerprint.type, "sha-256")) {
2729 // switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_WARNING, "Unsupported fingerprint type.\n");
2730 //engine->local_dtls_fingerprint.type = NULL;
2731 //engine->remote_dtls_fingerprint.type = NULL;
2732 //}
2733
2734
2735 generate_local_fingerprint(smh, type);
2736 switch_channel_set_flag(smh->session->channel, CF_DTLS)switch_channel_set_flag_value(smh->session->channel, CF_DTLS
, 1)
;
2737
2738 } else if (!engine->remote_ssrc && !strcasecmp(attr->a_name, "ssrc") && attr->a_value) {
2739 engine->remote_ssrc = (uint32_t) atol(attr->a_value);
2740
2741 if (engine->rtp_session && engine->remote_ssrc) {
2742 switch_rtp_set_remote_ssrc(engine->rtp_session, engine->remote_ssrc);
2743 }
2744
2745
2746#ifdef RTCP_MUX
2747 } else if (!strcasecmp(attr->a_name, "rtcp-mux")) {
2748 engine->rtcp_mux = SWITCH_TRUE;
2749 engine->remote_rtcp_port = engine->cur_payload_map->remote_sdp_port;
2750 got_rtcp_mux++;
2751#endif
2752 } else if (!strcasecmp(attr->a_name, "candidate")) {
2753 switch_channel_set_flag(smh->session->channel, CF_ICE)switch_channel_set_flag_value(smh->session->channel, CF_ICE
, 1)
;
2754
2755 if (!engine->cand_acl_count) {
2756 engine->cand_acl[engine->cand_acl_count++] = "wan.auto";
2757 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2757, (const char*)(smh->session)
, SWITCH_LOG_WARNING, "NO candidate ACL defined, Defaulting to wan.auto\n");
2758 }
2759
2760
2761 if (!switch_stristr(" udp ", attr->a_value)) {
2762 continue;
2763 }
2764
2765 data = switch_core_session_strdup(smh->session, attr->a_value)switch_core_perform_session_strdup(smh->session, attr->
a_value, "src/switch_core_media.c", (const char *)__func__, 2765
)
;
2766
2767 argc = switch_split(data, ' ', fields)switch_separate_string(data, ' ', fields, (sizeof(fields) / sizeof
(fields[0])))
;
2768
2769 if (argc < 5 || engine->ice_in.cand_idx >= MAX_CAND50 - 1) {
2770 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2770, (const char*)(smh->session)
, SWITCH_LOG_WARNING, "Invalid data\n");
2771 continue;
2772 }
2773
2774 cid = atoi(fields[1]) - 1;
2775
2776
2777 for (i = 0; i < argc; i++) {
2778 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2778, (const char*)(smh->session)
, SWITCH_LOG_DEBUG1, "CAND %d [%s]\n", i, fields[i]);
2779 }
2780
2781 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2781, (const char*)(smh->session)
, SWITCH_LOG_DEBUG,
2782 "Checking Candidate cid: %d proto: %s type: %s addr: %s:%s\n", cid+1, fields[2], fields[7], fields[4], fields[5]);
2783
2784
2785 engine->ice_in.cand_idx++;
2786
2787 for (i = 0; i < engine->cand_acl_count; i++) {
2788 if (!engine->ice_in.chosen[cid] && switch_check_network_list_ip(fields[4], engine->cand_acl[i])switch_check_network_list_ip_token(fields[4], engine->cand_acl
[i], ((void*)0))
) {
2789 engine->ice_in.chosen[cid] = engine->ice_in.cand_idx;
2790 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2790, (const char*)(smh->session)
, SWITCH_LOG_NOTICE,
2791 "Choose %s Candidate cid: %d proto: %s type: %s addr: %s:%s\n",
2792 type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio",
2793 cid+1, fields[2], fields[7], fields[4], fields[5]);
2794 } else {
2795 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2795, (const char*)(smh->session)
, SWITCH_LOG_NOTICE,
2796 "Save %s Candidate cid: %d proto: %s type: %s addr: %s:%s\n",
2797 type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio",
2798 cid+1, fields[2], fields[7], fields[4], fields[5]);
2799 }
2800
2801 engine->ice_in.cands[engine->ice_in.cand_idx][cid].foundation = switch_core_session_strdup(smh->session, fields[0])switch_core_perform_session_strdup(smh->session, fields[0]
, "src/switch_core_media.c", (const char *)__func__, 2801)
;
2802 engine->ice_in.cands[engine->ice_in.cand_idx][cid].component_id = atoi(fields[1]);
2803 engine->ice_in.cands[engine->ice_in.cand_idx][cid].transport = switch_core_session_strdup(smh->session, fields[2])switch_core_perform_session_strdup(smh->session, fields[2]
, "src/switch_core_media.c", (const char *)__func__, 2803)
;
2804 engine->ice_in.cands[engine->ice_in.cand_idx][cid].priority = atol(fields[3]);
2805 engine->ice_in.cands[engine->ice_in.cand_idx][cid].con_addr = switch_core_session_strdup(smh->session, fields[4])switch_core_perform_session_strdup(smh->session, fields[4]
, "src/switch_core_media.c", (const char *)__func__, 2805)
;
2806 engine->ice_in.cands[engine->ice_in.cand_idx][cid].con_port = (switch_port_t)atoi(fields[5]);
2807
2808
2809 j = 6;
2810
2811 while(j < argc && fields[j+1]) {
2812 if (!strcasecmp(fields[j], "typ")) {
2813 engine->ice_in.cands[engine->ice_in.cand_idx][cid].cand_type = switch_core_session_strdup(smh->session, fields[j+1])switch_core_perform_session_strdup(smh->session, fields[j+
1], "src/switch_core_media.c", (const char *)__func__, 2813)
;
2814 } else if (!strcasecmp(fields[j], "raddr")) {
2815 engine->ice_in.cands[engine->ice_in.cand_idx][cid].raddr = switch_core_session_strdup(smh->session, fields[j+1])switch_core_perform_session_strdup(smh->session, fields[j+
1], "src/switch_core_media.c", (const char *)__func__, 2815)
;
2816 } else if (!strcasecmp(fields[j], "rport")) {
2817 engine->ice_in.cands[engine->ice_in.cand_idx][cid].rport = (switch_port_t)atoi(fields[j+1]);
2818 } else if (!strcasecmp(fields[j], "generation")) {
2819 engine->ice_in.cands[engine->ice_in.cand_idx][cid].generation = switch_core_session_strdup(smh->session, fields[j+1])switch_core_perform_session_strdup(smh->session, fields[j+
1], "src/switch_core_media.c", (const char *)__func__, 2819)
;
2820 }
2821
2822 j += 2;
2823 }
2824
2825
2826 if (engine->ice_in.chosen[cid]) {
2827 engine->ice_in.cands[engine->ice_in.chosen[cid]][cid].ready++;
2828 }
2829
2830 break;
2831 }
2832 }
2833
2834 }
2835
2836 /* still no candidates, so start searching for some based on sane deduction */
2837
2838 /* look for candidates on the same network */
2839 if (!engine->ice_in.chosen[0] || !engine->ice_in.chosen[1]) {
2840 for (i = 0; i <= engine->ice_in.cand_idx && (!engine->ice_in.chosen[0] || !engine->ice_in.chosen[1]); i++) {
2841 if (!engine->ice_in.chosen[0] && engine->ice_in.cands[i][0].component_id == 1 &&
2842 !engine->ice_in.cands[i][0].rport && switch_check_network_list_ip(engine->ice_in.cands[i][0].con_addr, "localnet.auto")switch_check_network_list_ip_token(engine->ice_in.cands[i]
[0].con_addr, "localnet.auto", ((void*)0))
) {
2843 engine->ice_in.chosen[0] = i;
2844 engine->ice_in.cands[engine->ice_in.chosen[0]][0].ready++;
2845 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2845, (const char*)(smh->session)
, SWITCH_LOG_NOTICE,
2846 "No %s RTP candidate found; defaulting to the first local one.\n", type2str(type)type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio");
2847 }
2848 if (!engine->ice_in.chosen[1] && engine->ice_in.cands[i][1].component_id == 2 &&
2849 !engine->ice_in.cands[i][1].rport && switch_check_network_list_ip(engine->ice_in.cands[i][1].con_addr, "localnet.auto")switch_check_network_list_ip_token(engine->ice_in.cands[i]
[1].con_addr, "localnet.auto", ((void*)0))
) {
2850 engine->ice_in.chosen[1] = i;
2851 engine->ice_in.cands[engine->ice_in.chosen[1]][1].ready++;
2852 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2852, (const char*)(smh->session)
,SWITCH_LOG_NOTICE,
2853 "No %s RTCP candidate found; defaulting to the first local one.\n", type2str(type)type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio");
2854 }
2855 }
2856 }
2857
2858 /* look for candidates with srflx */
2859 if (!engine->ice_in.chosen[0] || !engine->ice_in.chosen[1]) {
2860 for (i = 0; i <= engine->ice_in.cand_idx && (!engine->ice_in.chosen[0] || !engine->ice_in.chosen[1]); i++) {
2861 if (!engine->ice_in.chosen[0] && engine->ice_in.cands[i][0].component_id == 1 && engine->ice_in.cands[i][0].rport) {
2862 engine->ice_in.chosen[0] = i;
2863 engine->ice_in.cands[engine->ice_in.chosen[0]][0].ready++;
2864 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2864, (const char*)(smh->session)
, SWITCH_LOG_NOTICE,
2865 "No %s RTP candidate found; defaulting to the first srflx one.\n", type2str(type)type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio");
2866 }
2867 if (!engine->ice_in.chosen[1] && engine->ice_in.cands[i][1].component_id == 2 && engine->ice_in.cands[i][1].rport) {
2868 engine->ice_in.chosen[1] = i;
2869 engine->ice_in.cands[engine->ice_in.chosen[1]][1].ready++;
2870 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2870, (const char*)(smh->session)
,SWITCH_LOG_NOTICE,
2871 "No %s RTCP candidate found; defaulting to the first srflx one.\n", type2str(type)type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio");
2872 }
2873 }
2874 }
2875
2876 /* Got RTP but not RTCP, probably mux */
2877 if (engine->ice_in.chosen[0] && !engine->ice_in.chosen[1] && got_rtcp_mux) {
2878 engine->ice_in.chosen[1] = engine->ice_in.chosen[0];
2879
2880 memcpy(&engine->ice_in.cands[engine->ice_in.chosen[1]][1], &engine->ice_in.cands[engine->ice_in.chosen[0]][0],
2881 sizeof(engine->ice_in.cands[engine->ice_in.chosen[0]][0]));
2882 engine->ice_in.cands[engine->ice_in.chosen[1]][1].ready++;
2883
2884 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2884, (const char*)(smh->session)
, SWITCH_LOG_NOTICE,
2885 "No %s RTCP candidate found; defaulting to the same as RTP [%s:%d]\n", type2str(type)type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio",
2886 engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_addr, engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port);
2887 }
2888
2889 /* look for any candidates and hope for auto-adjust */
2890 if (!engine->ice_in.chosen[0] || !engine->ice_in.chosen[1]) {
2891 for (i = 0; i <= engine->ice_in.cand_idx && (!engine->ice_in.chosen[0] || !engine->ice_in.chosen[1]); i++) {
2892 if (!engine->ice_in.chosen[0] && engine->ice_in.cands[i][0].component_id == 1) {
2893 engine->ice_in.chosen[0] = i;
2894 engine->ice_in.cands[engine->ice_in.chosen[0]][0].ready++;
2895 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2895, (const char*)(smh->session)
, SWITCH_LOG_NOTICE,
2896 "No %s RTP candidate found; defaulting to the first one.\n", type2str(type)type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio");
2897 }
2898 if (!engine->ice_in.chosen[1] && engine->ice_in.cands[i][1].component_id == 2) {
2899 engine->ice_in.chosen[1] = i;
2900 engine->ice_in.cands[engine->ice_in.chosen[1]][1].ready++;
2901 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2901, (const char*)(smh->session)
, SWITCH_LOG_NOTICE,
2902 "No %s RTCP candidate found; defaulting to the first one.\n", type2str(type)type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio");
2903 }
2904 }
2905 }
2906
2907 for (i = 0; i < 2; i++) {
2908 if (engine->ice_in.cands[engine->ice_in.chosen[i]][i].ready) {
2909 if (zstr(engine->ice_in.ufrag)_zstr(engine->ice_in.ufrag) || zstr(engine->ice_in.pwd)_zstr(engine->ice_in.pwd)) {
2910 engine->ice_in.cands[engine->ice_in.chosen[i]][i].ready = 0;
2911 }
2912 }
2913 }
2914
2915
2916 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) {
2917 char tmp[80] = "";
2918 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)switch_core_perform_session_strdup(smh->session, (char *) engine
->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr, "src/switch_core_media.c"
, (const char *)__func__, 2918)
;
2919 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2919, (const char*)(smh->session)
, SWITCH_LOG_NOTICE,
2920 "setting remote %s ice addr to %s:%d based on candidate\n", type2str(type)type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio",
2921 engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr, engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port);
2922 engine->ice_in.cands[engine->ice_in.chosen[0]][0].ready++;
2923
2924 engine->remote_rtp_ice_port = (switch_port_t) engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port;
2925 engine->remote_rtp_ice_addr = switch_core_session_strdup(smh->session, engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr)switch_core_perform_session_strdup(smh->session, engine->
ice_in.cands[engine->ice_in.chosen[0]][0].con_addr, "src/switch_core_media.c"
, (const char *)__func__, 2925)
;
2926
2927 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)switch_core_perform_session_strdup(smh->session, (char *) engine
->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr, "src/switch_core_media.c"
, (const char *)__func__, 2927)
;
2928 engine->cur_payload_map->remote_sdp_port = (switch_port_t) engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port;
2929 if (engine->remote_rtcp_port) {
2930 engine->remote_rtcp_port = engine->cur_payload_map->remote_sdp_port;
2931 }
2932
2933 switch_snprintf(tmp, sizeof(tmp), "%d", engine->cur_payload_map->remote_sdp_port);
2934 switch_channel_set_variable(smh->session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, engine->cur_payload_map->remote_sdp_ip)switch_channel_set_variable_var_check(smh->session->channel
, "remote_media_ip", engine->cur_payload_map->remote_sdp_ip
, SWITCH_TRUE)
;
2935 switch_channel_set_variable(smh->session->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp)switch_channel_set_variable_var_check(smh->session->channel
, "remote_media_port", tmp, SWITCH_TRUE)
;
2936 }
2937
2938 if (engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port) {
2939 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2939, (const char*)(smh->session)
, SWITCH_LOG_NOTICE,
2940 "setting remote rtcp %s addr to %s:%d based on candidate\n", type2str(type)type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio",
2941 engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_addr, engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port);
2942 engine->remote_rtcp_ice_port = engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port;
2943 engine->remote_rtcp_ice_addr = switch_core_session_strdup(smh->session, engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_addr)switch_core_perform_session_strdup(smh->session, engine->
ice_in.cands[engine->ice_in.chosen[1]][1].con_addr, "src/switch_core_media.c"
, (const char *)__func__, 2943)
;
2944
2945 engine->remote_rtcp_port = engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port;
2946 }
2947
2948
2949 if (m && !got_rtcp_mux) {
2950 engine->rtcp_mux = -1;
2951 }
2952
2953 if (switch_channel_test_flag(smh->session->channel, CF_REINVITE)) {
2954
2955 if (switch_rtp_ready(engine->rtp_session) && engine->ice_in.cands[engine->ice_in.chosen[0]][0].ready) {
2956 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2956, (const char*)(smh->session)
, SWITCH_LOG_INFO, "RE-Activating %s ICE\n", type2str(type)type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio");
2957
2958 switch_rtp_activate_ice(engine->rtp_session,
2959 engine->ice_in.ufrag,
2960 engine->ice_out.ufrag,
2961 engine->ice_out.pwd,
2962 engine->ice_in.pwd,
2963 IPR_RTP,
2964#ifdef GOOGLE_ICE
2965 ICE_GOOGLE_JINGLE,
2966 NULL((void*)0)
2967#else
2968 switch_ice_direction(smh->session) ==
2969 SWITCH_CALL_DIRECTION_OUTBOUND ? ICE_VANILLA : (ICE_VANILLA | ICE_CONTROLLED),
2970 &engine->ice_in
2971#endif
2972 );
2973
2974
2975
2976 }
2977
2978
2979 if (engine->rtp_session && ((val = switch_channel_get_variable(smh->session->channel,switch_channel_get_variable_dup(smh->session->channel, type
== SWITCH_MEDIA_TYPE_VIDEO ? "rtcp_video_interval_msec" : "rtcp_audio_interval_msec"
, SWITCH_TRUE, -1)
2980 type == SWITCH_MEDIA_TYPE_VIDEO ?switch_channel_get_variable_dup(smh->session->channel, type
== SWITCH_MEDIA_TYPE_VIDEO ? "rtcp_video_interval_msec" : "rtcp_audio_interval_msec"
, SWITCH_TRUE, -1)
2981 "rtcp_video_interval_msec" : "rtcp_audio_interval_msec")switch_channel_get_variable_dup(smh->session->channel, type
== SWITCH_MEDIA_TYPE_VIDEO ? "rtcp_video_interval_msec" : "rtcp_audio_interval_msec"
, SWITCH_TRUE, -1)
)
2982 || (val = type == SWITCH_MEDIA_TYPE_VIDEO ?
2983 smh->mparams->rtcp_video_interval_msec : smh->mparams->rtcp_audio_interval_msec))) {
2984
2985 switch_port_t remote_rtcp_port = engine->remote_rtcp_port;
2986
2987 if (remote_rtcp_port) {
2988 if (!strcasecmp(val, "passthru")) {
2989 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2989, (const char*)(smh->session)
, SWITCH_LOG_INFO, "Activating %s RTCP PASSTHRU PORT %d\n",
2990 type2str(type)type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio", remote_rtcp_port);
2991 switch_rtp_activate_rtcp(engine->rtp_session, -1, remote_rtcp_port, engine->rtcp_mux > 0);
2992 } else {
2993 int interval = atoi(val);
2994 if (interval < 100 || interval > 500000) {
2995 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 2995, (const char*)(smh->session)
, SWITCH_LOG_ERROR,
2996 "Invalid rtcp interval spec [%d] must be between 100 and 500000\n", interval);
2997 interval = 10000;
2998 }
2999
3000 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3000, (const char*)(smh->session)
, SWITCH_LOG_INFO, "Activating %s RTCP PORT %d\n", type2str(type)type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio", remote_rtcp_port);
3001 switch_rtp_activate_rtcp(engine->rtp_session, interval, remote_rtcp_port, engine->rtcp_mux > 0);
3002 }
3003 }
3004 }
3005
3006 if (engine->rtp_session && engine->ice_in.cands[engine->ice_in.chosen[1]][1].ready) {
3007 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)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_addr
) && __builtin_constant_p (engine->ice_in.cands[engine
->ice_in.chosen[0]][0].con_addr) && (__s1_len = __builtin_strlen
(engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_addr
), __s2_len = __builtin_strlen (engine->ice_in.cands[engine
->ice_in.chosen[0]][0].con_addr), (!((size_t)(const void *
)((engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_addr
) + 1) - (size_t)(const void *)(engine->ice_in.cands[engine
->ice_in.chosen[1]][1].con_addr) == 1) || __s1_len >= 4
) && (!((size_t)(const void *)((engine->ice_in.cands
[engine->ice_in.chosen[0]][0].con_addr) + 1) - (size_t)(const
void *)(engine->ice_in.cands[engine->ice_in.chosen[0]]
[0].con_addr) == 1) || __s2_len >= 4)) ? __builtin_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
) : (__builtin_constant_p (engine->ice_in.cands[engine->
ice_in.chosen[1]][1].con_addr) && ((size_t)(const void
*)((engine->ice_in.cands[engine->ice_in.chosen[1]][1].
con_addr) + 1) - (size_t)(const void *)(engine->ice_in.cands
[engine->ice_in.chosen[1]][1].con_addr) == 1) && (
__s1_len = __builtin_strlen (engine->ice_in.cands[engine->
ice_in.chosen[1]][1].con_addr), __s1_len < 4) ? (__builtin_constant_p
(engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr
) && ((size_t)(const void *)((engine->ice_in.cands
[engine->ice_in.chosen[0]][0].con_addr) + 1) - (size_t)(const
void *)(engine->ice_in.cands[engine->ice_in.chosen[0]]
[0].con_addr) == 1) ? __builtin_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) : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (engine->ice_in.cands[engine->ice_in.chosen[0]
][0].con_addr); int __result = (((const unsigned char *) (const
char *) (engine->ice_in.cands[engine->ice_in.chosen[1]
][1].con_addr))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (engine->ice_in.cands[engine->ice_in.chosen[1]
][1].con_addr))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (engine->ice_in.cands[engine->ice_in.chosen[1]
][1].con_addr))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (engine->ice_in.cands[engine->ice_in.chosen[1]][1].
con_addr))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr
) && ((size_t)(const void *)((engine->ice_in.cands
[engine->ice_in.chosen[0]][0].con_addr) + 1) - (size_t)(const
void *)(engine->ice_in.cands[engine->ice_in.chosen[0]]
[0].con_addr) == 1) && (__s2_len = __builtin_strlen (
engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr
), __s2_len < 4) ? (__builtin_constant_p (engine->ice_in
.cands[engine->ice_in.chosen[1]][1].con_addr) && (
(size_t)(const void *)((engine->ice_in.cands[engine->ice_in
.chosen[1]][1].con_addr) + 1) - (size_t)(const void *)(engine
->ice_in.cands[engine->ice_in.chosen[1]][1].con_addr) ==
1) ? __builtin_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) : (- (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (engine->
ice_in.cands[engine->ice_in.chosen[1]][1].con_addr); int __result
= (((const unsigned char *) (const char *) (engine->ice_in
.cands[engine->ice_in.chosen[0]][0].con_addr))[0] - __s2[0
]); if (__s2_len > 0 && __result == 0) { __result =
(((const unsigned char *) (const char *) (engine->ice_in.
cands[engine->ice_in.chosen[0]][0].con_addr))[1] - __s2[1]
); if (__s2_len > 1 && __result == 0) { __result =
(((const unsigned char *) (const char *) (engine->ice_in.
cands[engine->ice_in.chosen[0]][0].con_addr))[2] - __s2[2]
); if (__s2_len > 2 && __result == 0) __result = (
((const unsigned char *) (const char *) (engine->ice_in.cands
[engine->ice_in.chosen[0]][0].con_addr))[3] - __s2[3]); } }
__result; })))) : __builtin_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)))); })
3008 && engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port == engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port) {
3009 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3009, (const char*)(smh->session)
, SWITCH_LOG_INFO, "Skipping %s RTCP ICE (Same as RTP)\n", type2str(type)type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio");
3010 } else {
3011 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3011, (const char*)(smh->session)
, SWITCH_LOG_INFO, "Activating %s RTCP ICE\n", type2str(type)type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio");
3012
3013 switch_rtp_activate_ice(engine->rtp_session,
3014 engine->ice_in.ufrag,
3015 engine->ice_out.ufrag,
3016 engine->ice_out.pwd,
3017 engine->ice_in.pwd,
3018 IPR_RTCP,
3019#ifdef GOOGLE_ICE
3020 ICE_GOOGLE_JINGLE,
3021 NULL((void*)0)
3022#else
3023 switch_ice_direction(smh->session) ==
3024 SWITCH_CALL_DIRECTION_OUTBOUND ? ICE_VANILLA : (ICE_VANILLA | ICE_CONTROLLED),
3025 &engine->ice_in
3026#endif
3027 );
3028 }
3029
3030 }
3031
3032 }
3033}
3034#ifdef _MSC_VER
3035#pragma warning(pop)
3036#endif
3037
3038SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_session_set_ice(switch_core_session_t *session)
3039{
3040 switch_media_handle_t *smh;
3041
3042 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 3042, __PRETTY_FUNCTION__))
;
3043
3044 if (!(smh = session->media_handle)) {
3045 return;
3046 }
3047
3048 switch_channel_set_flag(session->channel, CF_VERBOSE_SDP)switch_channel_set_flag_value(session->channel, CF_VERBOSE_SDP
, 1)
;
3049 switch_channel_set_flag(session->channel, CF_WEBRTC)switch_channel_set_flag_value(session->channel, CF_WEBRTC,
1)
;
3050 switch_channel_set_flag(session->channel, CF_ICE)switch_channel_set_flag_value(session->channel, CF_ICE, 1);
3051 smh->mparams->rtcp_audio_interval_msec = "10000";
3052 smh->mparams->rtcp_video_interval_msec = "10000";
3053
3054}
3055
3056#define MAX_MATCHES30 30
3057struct matches {
3058 const switch_codec_implementation_t *imp;
3059 sdp_rtpmap_t *map;
3060 int rate;
3061 int codec_idx;
3062};
3063
3064static void greedy_sort(switch_media_handle_t *smh, struct matches *matches, int m_idx, const switch_codec_implementation_t **codec_array, int total_codecs)
3065{
3066 int j = 0, f = 0, g;
3067 struct matches mtmp[MAX_MATCHES30] = { { 0 } };
3068 for(j = 0; j < m_idx; j++) {
3069 *&mtmp[j] = *&matches[j];
3070 }
3071 for (g = 0; g < smh->mparams->num_codecs && g < total_codecs; g++) {
3072 const switch_codec_implementation_t *imp = codec_array[g];
3073
3074 for(j = 0; j < m_idx; j++) {
3075 if (mtmp[j].imp == imp) {
3076 *&matches[f++] = *&mtmp[j];
3077 }
3078 }
3079 }
3080}
3081
3082static void clear_pmaps(switch_rtp_engine_t *engine)
3083{
3084 payload_map_t *pmap;
3085
3086 for (pmap = engine->payload_map; pmap && pmap->allocated; pmap = pmap->next) {
3087 pmap->negotiated = 0;
3088 pmap->current = 0;
3089 }
3090}
3091
3092//?
3093SWITCH_DECLARE(uint8_t)__attribute__((visibility("default"))) 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)
3094{
3095 uint8_t match = 0;
3096 switch_payload_t best_te = 0, te = 0, cng_pt = 0;
3097 sdp_media_t *m;
3098 sdp_attribute_t *attr;
3099 int ptime = 0, dptime = 0, maxptime = 0, dmaxptime = 0;
3100 int sendonly = 0, recvonly = 0;
3101 int greedy = 0, x = 0, skip = 0;
3102 switch_channel_t *channel = switch_core_session_get_channel(session);
3103 const char *val;
3104 const char *crypto = NULL((void*)0);
3105 int got_crypto = 0, got_video_crypto = 0, got_audio = 0, got_avp = 0, got_video_avp = 0, got_video_savp = 0, got_savp = 0, got_udptl = 0, got_webrtc = 0;
3106 int scrooge = 0;
3107 sdp_parser_t *parser = NULL((void*)0);
3108 sdp_session_t *sdp;
3109 int reneg = 1;
3110 const switch_codec_implementation_t **codec_array;
3111 int total_codecs;
3112 switch_rtp_engine_t *a_engine, *v_engine;
3113 switch_media_handle_t *smh;
3114 uint32_t near_rate = 0;
3115 const switch_codec_implementation_t *mimp = NULL((void*)0), *near_match = NULL((void*)0);
3116 sdp_rtpmap_t *mmap = NULL((void*)0), *near_map = NULL((void*)0);
3117 struct matches matches[MAX_MATCHES30] = { { 0 } };
3118 struct matches near_matches[MAX_MATCHES30] = { { 0 } };
3119 int codec_ms = 0;
3120 uint32_t remote_codec_rate = 0, fmtp_remote_codec_rate = 0;
3121 const char *tmp;
3122 int m_idx = 0;
3123 int nm_idx = 0;
3124
3125 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 3125, __PRETTY_FUNCTION__))
;
3126
3127 if (!(smh = session->media_handle)) {
3128 return 0;
3129 }
3130
3131 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
3132 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
3133
3134 codec_array = smh->codecs;
3135 total_codecs = smh->mparams->num_codecs;
3136
3137 if (!(parser = sdp_parse(NULL((void*)0), r_sdp, (int) strlen(r_sdp), 0))) {
3138 return 0;
3139 }
3140
3141 if (!(sdp = sdp_session(parser))) {
3142 sdp_parser_free(parser);
3143 return 0;
3144 }
3145
3146 if (dtls_ok(session) && (tmp = switch_channel_get_variable(smh->session->channel, "webrtc_enable_dtls")switch_channel_get_variable_dup(smh->session->channel, "webrtc_enable_dtls"
, SWITCH_TRUE, -1)
) && switch_false(tmp)) {
3147 switch_channel_clear_flag(smh->session->channel, CF_DTLS_OK);
3148 switch_channel_clear_flag(smh->session->channel, CF_DTLS);
3149 }
3150
3151 switch_core_session_parse_crypto_prefs(session);
3152
3153 clear_pmaps(a_engine);
3154 clear_pmaps(v_engine);
3155
3156 if (proceed) *proceed = 1;
3157
3158 greedy = !!switch_media_handle_test_media_flag(smh, SCMF_CODEC_GREEDY);
3159 scrooge = !!switch_media_handle_test_media_flag(smh, SCMF_CODEC_SCROOGE);
3160
3161 if ((val = switch_channel_get_variable(channel, "rtp_codec_negotiation")switch_channel_get_variable_dup(channel, "rtp_codec_negotiation"
, SWITCH_TRUE, -1)
)) {
3162 if (!strcasecmp(val, "generous")) {
3163 greedy = 0;
3164 scrooge = 0;
3165 } else if (!strcasecmp(val, "greedy")) {
3166 greedy = 1;
3167 scrooge = 0;
3168 } else if (!strcasecmp(val, "scrooge")) {
3169 scrooge = 1;
3170 greedy = 1;
3171 } else {
3172 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3172, (const char*)(session)
, SWITCH_LOG_DEBUG, "rtp_codec_negotiation ignored invalid value : '%s' \n", val );
3173 }
3174 }
3175
3176 if ((smh->origin = switch_core_session_strdup(session, (char *) sdp->sdp_origin->o_username)switch_core_perform_session_strdup(session, (char *) sdp->
sdp_origin->o_username, "src/switch_core_media.c", (const char
*)__func__, 3176)
)) {
3177
3178 if ((smh->mparams->auto_rtp_bugs & RTP_BUG_CISCO_SKIP_MARK_BIT_2833)) {
3179
3180 if (strstr(smh->origin, "CiscoSystemsSIP-GW-UserAgent")) {
3181 a_engine->rtp_bugs |= RTP_BUG_CISCO_SKIP_MARK_BIT_2833;
3182 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3182, (const char*)(session)
, SWITCH_LOG_DEBUG, "Activate Buggy RFC2833 Mode!\n");
3183 }
3184 }
3185
3186 if ((smh->mparams->auto_rtp_bugs & RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833)) {
3187 if (strstr(smh->origin, "Sonus_UAC")) {
3188 a_engine->rtp_bugs |= RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833;
3189 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3189, (const char*)(session)
, SWITCH_LOG_WARNING,
3190 "Hello,\nI see you have a Sonus!\n"
3191 "FYI, Sonus cannot follow the RFC on the proper way to send DTMF.\n"
3192 "Sadly, my creator had to spend several hours figuring this out so I thought you'd like to know that!\n"
3193 "Don't worry, DTMF will work but you may want to ask them to fix it......\n");
3194 }
3195 }
3196 }
3197
3198 if ((val = switch_channel_get_variable(session->channel, "rtp_liberal_dtmf")switch_channel_get_variable_dup(session->channel, "rtp_liberal_dtmf"
, SWITCH_TRUE, -1)
) && switch_true(val)) {
3199 switch_channel_set_flag(session->channel, CF_LIBERAL_DTMF)switch_channel_set_flag_value(session->channel, CF_LIBERAL_DTMF
, 1)
;
3200 }
3201
3202 if (switch_stristr("T38FaxFillBitRemoval:", r_sdp) || switch_stristr("T38FaxTranscodingMMR:", r_sdp) ||
3203 switch_stristr("T38FaxTranscodingJBIG:", r_sdp)) {
3204 switch_channel_set_variable(session->channel, "t38_broken_boolean", "true")switch_channel_set_variable_var_check(session->channel, "t38_broken_boolean"
, "true", SWITCH_TRUE)
;
3205 }
3206
3207 switch_core_media_find_zrtp_hash(session, sdp);
3208 switch_core_media_pass_zrtp_hash(session);
3209
3210 check_ice(smh, SWITCH_MEDIA_TYPE_AUDIO, sdp, NULL((void*)0));
3211 check_ice(smh, SWITCH_MEDIA_TYPE_VIDEO, sdp, NULL((void*)0));
3212
3213 if ((sdp->sdp_connection && sdp->sdp_connection->c_address && !strcmp(sdp->sdp_connection->c_address, "0.0.0.0")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(sdp->sdp_connection->c_address) && __builtin_constant_p
("0.0.0.0") && (__s1_len = __builtin_strlen (sdp->
sdp_connection->c_address), __s2_len = __builtin_strlen ("0.0.0.0"
), (!((size_t)(const void *)((sdp->sdp_connection->c_address
) + 1) - (size_t)(const void *)(sdp->sdp_connection->c_address
) == 1) || __s1_len >= 4) && (!((size_t)(const void
*)(("0.0.0.0") + 1) - (size_t)(const void *)("0.0.0.0") == 1
) || __s2_len >= 4)) ? __builtin_strcmp (sdp->sdp_connection
->c_address, "0.0.0.0") : (__builtin_constant_p (sdp->sdp_connection
->c_address) && ((size_t)(const void *)((sdp->sdp_connection
->c_address) + 1) - (size_t)(const void *)(sdp->sdp_connection
->c_address) == 1) && (__s1_len = __builtin_strlen
(sdp->sdp_connection->c_address), __s1_len < 4) ? (
__builtin_constant_p ("0.0.0.0") && ((size_t)(const void
*)(("0.0.0.0") + 1) - (size_t)(const void *)("0.0.0.0") == 1
) ? __builtin_strcmp (sdp->sdp_connection->c_address, "0.0.0.0"
) : (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) ("0.0.0.0"); int __result = (((const unsigned
char *) (const char *) (sdp->sdp_connection->c_address
))[0] - __s2[0]); if (__s1_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) (sdp->
sdp_connection->c_address))[1] - __s2[1]); if (__s1_len >
1 && __result == 0) { __result = (((const unsigned char
*) (const char *) (sdp->sdp_connection->c_address))[2]
- __s2[2]); if (__s1_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) (sdp->sdp_connection
->c_address))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("0.0.0.0") && ((size_t)(const void *)(("0.0.0.0") +
1) - (size_t)(const void *)("0.0.0.0") == 1) && (__s2_len
= __builtin_strlen ("0.0.0.0"), __s2_len < 4) ? (__builtin_constant_p
(sdp->sdp_connection->c_address) && ((size_t)(
const void *)((sdp->sdp_connection->c_address) + 1) - (
size_t)(const void *)(sdp->sdp_connection->c_address) ==
1) ? __builtin_strcmp (sdp->sdp_connection->c_address,
"0.0.0.0") : (- (__extension__ ({ const unsigned char *__s2 =
(const unsigned char *) (const char *) (sdp->sdp_connection
->c_address); int __result = (((const unsigned char *) (const
char *) ("0.0.0.0"))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("0.0.0.0"))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("0.0.0.0"))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) ("0.0.0.0"))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(sdp->sdp_connection->c_address, "0.0.0.0")))); })
)) {
3214 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3214, (const char*)(session)
, SWITCH_LOG_WARNING, "RFC2543 from March 1999 called; They want their 0.0.0.0 hold method back.....\n");
3215 sendonly = 2; /* global sendonly always wins */
3216 }
3217
3218 for (m = sdp->sdp_media; m; m = m->m_next) {
3219 sdp_connection_t *connection;
3220 switch_core_session_t *other_session;
3221
3222 if (!m->m_port) {
3223 continue;
3224 }
3225
3226 ptime = dptime;
3227 maxptime = dmaxptime;
3228
3229 if (m->m_proto == sdp_proto_extended_srtp) {
3230 got_webrtc++;
3231 switch_core_session_set_ice(session);
3232 }
3233
3234 if (m->m_proto_name && !strcasecmp(m->m_proto_name, "UDP/TLS/RTP/SAVPF")) {
3235 switch_channel_set_flag(session->channel, CF_WEBRTC_MOZ)switch_channel_set_flag_value(session->channel, CF_WEBRTC_MOZ
, 1)
;
3236 }
3237
3238 if (m->m_proto == sdp_proto_srtp || m->m_proto == sdp_proto_extended_srtp) {
3239 if (m->m_type == sdp_media_audio) {
3240 got_savp++;
3241 } else {
3242 got_video_savp++;
3243 }
3244 } else if (m->m_proto == sdp_proto_rtp) {
3245 if (m->m_type == sdp_media_audio) {
3246 got_avp++;
3247 } else {
3248 got_video_avp++;
3249 }
3250 } else if (m->m_proto == sdp_proto_udptl) {
3251 got_udptl++;
3252 }
3253
3254 if (got_udptl && m->m_type == sdp_media_image && m->m_port) {
3255 switch_t38_options_t *t38_options = switch_core_media_process_udptl(session, sdp, m);
3256
3257 if (switch_channel_test_app_flag_key("T38", session->channel, CF_APP_T38_NEGOTIATED)) {
3258 match = 1;
3259 goto done;
3260 }
3261
3262 if (switch_true(switch_channel_get_variable(channel, "refuse_t38")switch_channel_get_variable_dup(channel, "refuse_t38", SWITCH_TRUE
, -1)
)) {
3263 switch_channel_clear_app_flag_key("T38", session->channel, CF_APP_T38);
3264 match = 0;
3265 goto done;
3266 } else {
3267 const char *var = switch_channel_get_variable(channel, "t38_passthru")switch_channel_get_variable_dup(channel, "t38_passthru", SWITCH_TRUE
, -1)
;
3268 int pass = switch_channel_test_flag(smh->session->channel, CF_T38_PASSTHRU);
3269
3270
3271 if (switch_channel_test_app_flag_key("T38", session->channel, CF_APP_T38)) {
3272 if (proceed) *proceed = 0;
3273 }
3274
3275 if (var) {
3276 if (!(pass = switch_true(var))) {
3277 if (!strcasecmp(var, "once")) {
3278 pass = 2;
3279 }
3280 }
3281 }
3282
3283 if ((pass == 2 && switch_channel_test_flag(smh->session->channel, CF_T38_PASSTHRU))
3284 || !switch_channel_test_flag(session->channel, CF_REINVITE) ||
3285
3286 switch_channel_test_flag(session->channel, CF_PROXY_MODE) ||
3287 switch_channel_test_flag(session->channel, CF_PROXY_MEDIA) ||
3288 !switch_rtp_ready(a_engine->rtp_session)) {
3289 pass = 0;
3290 }
3291
3292 if (pass && switch_core_session_get_partner(session, &other_session)switch_core_session_perform_get_partner(session, &other_session
, "src/switch_core_media.c", (const char *)__func__, 3292)
== SWITCH_STATUS_SUCCESS) {
3293 switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
3294 switch_core_session_message_t *msg;
3295 char *remote_host = switch_rtp_get_remote_host(a_engine->rtp_session);
3296 switch_port_t remote_port = switch_rtp_get_remote_port(a_engine->rtp_session);
3297 char tmp[32] = "";
3298
3299
3300 if (!switch_channel_test_flag(other_channel, CF_ANSWERED)) {
3301 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3301, (const char*)(session)
,
3302 SWITCH_LOG_WARNING, "%s Error Passing T.38 to unanswered channel %s\n",
3303 switch_channel_get_name(session->channel), switch_channel_get_name(other_channel));
3304 switch_core_session_rwunlock(other_session);
3305
3306 pass = 0;
3307 match = 0;
3308 goto done;
3309 }
3310
3311
3312 if (switch_true(switch_channel_get_variable(session->channel, "t38_broken_boolean")switch_channel_get_variable_dup(session->channel, "t38_broken_boolean"
, SWITCH_TRUE, -1)
) &&
3313 switch_true(switch_channel_get_variable(session->channel, "t38_pass_broken_boolean")switch_channel_get_variable_dup(session->channel, "t38_pass_broken_boolean"
, SWITCH_TRUE, -1)
)) {
3314 switch_channel_set_variable(other_channel, "t38_broken_boolean", "true")switch_channel_set_variable_var_check(other_channel, "t38_broken_boolean"
, "true", SWITCH_TRUE)
;
3315 }
3316
3317 a_engine->cur_payload_map->remote_sdp_ip = switch_core_session_strdup(session, t38_options->remote_ip)switch_core_perform_session_strdup(session, t38_options->remote_ip
, "src/switch_core_media.c", (const char *)__func__, 3317)
;
3318 a_engine->cur_payload_map->remote_sdp_port = t38_options->remote_port;
3319
3320 if (remote_host && remote_port && !strcmp(remote_host, a_engine->cur_payload_map->remote_sdp_ip)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(remote_host) && __builtin_constant_p (a_engine->
cur_payload_map->remote_sdp_ip) && (__s1_len = __builtin_strlen
(remote_host), __s2_len = __builtin_strlen (a_engine->cur_payload_map
->remote_sdp_ip), (!((size_t)(const void *)((remote_host) +
1) - (size_t)(const void *)(remote_host) == 1) || __s1_len >=
4) && (!((size_t)(const void *)((a_engine->cur_payload_map
->remote_sdp_ip) + 1) - (size_t)(const void *)(a_engine->
cur_payload_map->remote_sdp_ip) == 1) || __s2_len >= 4)
) ? __builtin_strcmp (remote_host, a_engine->cur_payload_map
->remote_sdp_ip) : (__builtin_constant_p (remote_host) &&
((size_t)(const void *)((remote_host) + 1) - (size_t)(const void
*)(remote_host) == 1) && (__s1_len = __builtin_strlen
(remote_host), __s1_len < 4) ? (__builtin_constant_p (a_engine
->cur_payload_map->remote_sdp_ip) && ((size_t)(
const void *)((a_engine->cur_payload_map->remote_sdp_ip
) + 1) - (size_t)(const void *)(a_engine->cur_payload_map->
remote_sdp_ip) == 1) ? __builtin_strcmp (remote_host, a_engine
->cur_payload_map->remote_sdp_ip) : (__extension__ ({ const
unsigned char *__s2 = (const unsigned char *) (const char *)
(a_engine->cur_payload_map->remote_sdp_ip); int __result
= (((const unsigned char *) (const char *) (remote_host))[0]
- __s2[0]); if (__s1_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) (remote_host))[1]
- __s2[1]); if (__s1_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) (remote_host))[2]
- __s2[2]); if (__s1_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) (remote_host))[3]
- __s2[3]); } } __result; }))) : (__builtin_constant_p (a_engine
->cur_payload_map->remote_sdp_ip) && ((size_t)(
const void *)((a_engine->cur_payload_map->remote_sdp_ip
) + 1) - (size_t)(const void *)(a_engine->cur_payload_map->
remote_sdp_ip) == 1) && (__s2_len = __builtin_strlen (
a_engine->cur_payload_map->remote_sdp_ip), __s2_len <
4) ? (__builtin_constant_p (remote_host) && ((size_t
)(const void *)((remote_host) + 1) - (size_t)(const void *)(remote_host
) == 1) ? __builtin_strcmp (remote_host, a_engine->cur_payload_map
->remote_sdp_ip) : (- (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) (remote_host)
; int __result = (((const unsigned char *) (const char *) (a_engine
->cur_payload_map->remote_sdp_ip))[0] - __s2[0]); if (__s2_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (a_engine->cur_payload_map->remote_sdp_ip
))[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (a_engine
->cur_payload_map->remote_sdp_ip))[2] - __s2[2]); if (__s2_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) (a_engine->cur_payload_map->remote_sdp_ip
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (remote_host
, a_engine->cur_payload_map->remote_sdp_ip)))); })
&& remote_port == a_engine->cur_payload_map->remote_sdp_port) {
3321 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3321, (const char*)(session)
, SWITCH_LOG_DEBUG, "Audio params are unchanged for %s.\n",
3322 switch_channel_get_name(session->channel));
3323 } else {
3324 const char *err = NULL((void*)0);
3325
3326 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3326, (const char*)(session)
, SWITCH_LOG_DEBUG, "Audio params changed for %s from %s:%d to %s:%d\n",
3327 switch_channel_get_name(session->channel),
3328 remote_host, remote_port, a_engine->cur_payload_map->remote_sdp_ip, a_engine->cur_payload_map->remote_sdp_port);
3329
3330 switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->cur_payload_map->remote_sdp_port);
3331 switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, a_engine->cur_payload_map->remote_sdp_ip)switch_channel_set_variable_var_check(session->channel, "remote_media_ip"
, a_engine->cur_payload_map->remote_sdp_ip, SWITCH_TRUE
)
;
3332 switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp)switch_channel_set_variable_var_check(session->channel, "remote_media_port"
, tmp, SWITCH_TRUE)
;
3333
3334 if (switch_rtp_set_remote_address(a_engine->rtp_session, a_engine->cur_payload_map->remote_sdp_ip,
3335 a_engine->cur_payload_map->remote_sdp_port, 0, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
3336 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3336, (const char*)(session)
, SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", err);
3337 switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION)switch_channel_perform_hangup(channel, "src/switch_core_media.c"
, (const char *)__func__, 3337, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION
)
;
3338 }
3339
3340 }
3341
3342
3343
3344 switch_core_media_copy_t38_options(t38_options, other_session);
3345
3346 switch_channel_set_flag(smh->session->channel, CF_T38_PASSTHRU)switch_channel_set_flag_value(smh->session->channel, CF_T38_PASSTHRU
, 1)
;
3347 switch_channel_set_flag(other_session->channel, CF_T38_PASSTHRU)switch_channel_set_flag_value(other_session->channel, CF_T38_PASSTHRU
, 1)
;
3348
3349 msg = switch_core_session_alloc(other_session, sizeof(*msg))switch_core_perform_session_alloc(other_session, sizeof(*msg)
, "src/switch_core_media.c", (const char *)__func__, 3349)
;
3350 msg->message_id = SWITCH_MESSAGE_INDICATE_REQUEST_IMAGE_MEDIA;
3351 msg->from = __FILE__"src/switch_core_media.c";
3352 msg->string_arg = switch_core_session_strdup(other_session, r_sdp)switch_core_perform_session_strdup(other_session, r_sdp, "src/switch_core_media.c"
, (const char *)__func__, 3352)
;
3353 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3353, (const char*)(session)
, SWITCH_LOG_DEBUG, "Passing T38 req to other leg.\n%s\n", r_sdp);
3354 switch_core_session_queue_message(other_session, msg);
3355 switch_core_session_rwunlock(other_session);
3356 }
3357 }
3358
3359
3360 /* do nothing here, mod_fax will trigger a response (if it's listening =/) */
3361 match = 1;
3362 goto done;
3363 } else if (m->m_type == sdp_media_audio && m->m_port && !got_audio) {
3364 sdp_rtpmap_t *map;
3365 int ice = 0;
3366
3367 if (!sendonly && (m->m_mode == sdp_sendonly || m->m_mode == sdp_inactive)) {
3368 sendonly = 1;
3369 }
3370
3371 if (!sendonly && m->m_connections && m->m_connections->c_address && !strcmp(m->m_connections->c_address, "0.0.0.0")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(m->m_connections->c_address) && __builtin_constant_p
("0.0.0.0") && (__s1_len = __builtin_strlen (m->m_connections
->c_address), __s2_len = __builtin_strlen ("0.0.0.0"), (!(
(size_t)(const void *)((m->m_connections->c_address) + 1
) - (size_t)(const void *)(m->m_connections->c_address)
== 1) || __s1_len >= 4) && (!((size_t)(const void
*)(("0.0.0.0") + 1) - (size_t)(const void *)("0.0.0.0") == 1
) || __s2_len >= 4)) ? __builtin_strcmp (m->m_connections
->c_address, "0.0.0.0") : (__builtin_constant_p (m->m_connections
->c_address) && ((size_t)(const void *)((m->m_connections
->c_address) + 1) - (size_t)(const void *)(m->m_connections
->c_address) == 1) && (__s1_len = __builtin_strlen
(m->m_connections->c_address), __s1_len < 4) ? (__builtin_constant_p
("0.0.0.0") && ((size_t)(const void *)(("0.0.0.0") +
1) - (size_t)(const void *)("0.0.0.0") == 1) ? __builtin_strcmp
(m->m_connections->c_address, "0.0.0.0") : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) ("0.0.0.0"); int __result = (((const unsigned char *
) (const char *) (m->m_connections->c_address))[0] - __s2
[0]); if (__s1_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) (m->m_connections
->c_address))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (m->m_connections->c_address))[2] - __s2[2]); if
(__s1_len > 2 && __result == 0) __result = (((const
unsigned char *) (const char *) (m->m_connections->c_address
))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (
"0.0.0.0") && ((size_t)(const void *)(("0.0.0.0") + 1
) - (size_t)(const void *)("0.0.0.0") == 1) && (__s2_len
= __builtin_strlen ("0.0.0.0"), __s2_len < 4) ? (__builtin_constant_p
(m->m_connections->c_address) && ((size_t)(const
void *)((m->m_connections->c_address) + 1) - (size_t)(
const void *)(m->m_connections->c_address) == 1) ? __builtin_strcmp
(m->m_connections->c_address, "0.0.0.0") : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (m->m_connections->c_address); int __result = (
((const unsigned char *) (const char *) ("0.0.0.0"))[0] - __s2
[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("0.0.0.0"))[1] -
__s2[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("0.0.0.0"))[2] -
__s2[2]); if (__s2_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) ("0.0.0.0"))[3] -
__s2[3]); } } __result; })))) : __builtin_strcmp (m->m_connections
->c_address, "0.0.0.0")))); })
) {
3372 sendonly = 1;
3373 }
3374
3375 for (attr = sdp->sdp_attributes; attr; attr = attr->a_next) {
3376 if (zstr(attr->a_name)_zstr(attr->a_name)) {
3377 continue;
3378 }
3379
3380
3381 if (!strncasecmp(attr->a_name, "ice", 3)) {
3382 ice++;
3383 } else if (sendonly < 2 && !strcasecmp(attr->a_name, "sendonly")) {
3384 sendonly = 1;
3385 switch_channel_set_variable(session->channel, "media_audio_mode", "recvonly")switch_channel_set_variable_var_check(session->channel, "media_audio_mode"
, "recvonly", SWITCH_TRUE)
;
3386 } else if (sendonly < 2 && !strcasecmp(attr->a_name, "inactive")) {
3387 sendonly = 1;
3388 switch_channel_set_variable(session->channel, "media_audio_mode", "inactive")switch_channel_set_variable_var_check(session->channel, "media_audio_mode"
, "inactive", SWITCH_TRUE)
;
3389 } else if (!strcasecmp(attr->a_name, "recvonly")) {
3390 switch_channel_set_variable(session->channel, "media_audio_mode", "sendonly")switch_channel_set_variable_var_check(session->channel, "media_audio_mode"
, "sendonly", SWITCH_TRUE)
;
3391 recvonly = 1;
3392
3393 if (switch_rtp_ready(a_engine->rtp_session)) {
3394 switch_rtp_set_max_missed_packets(a_engine->rtp_session, 0);
3395 a_engine->max_missed_hold_packets = 0;
3396 a_engine->max_missed_packets = 0;
3397 } else {
3398 switch_channel_set_variable(session->channel, "rtp_timeout_sec", "0")switch_channel_set_variable_var_check(session->channel, "rtp_timeout_sec"
, "0", SWITCH_TRUE)
;
3399 switch_channel_set_variable(session->channel, "rtp_hold_timeout_sec", "0")switch_channel_set_variable_var_check(session->channel, "rtp_hold_timeout_sec"
, "0", SWITCH_TRUE)
;
3400 }
3401 } else if (sendonly < 2 && !strcasecmp(attr->a_name, "sendrecv")) {
3402 sendonly = 0;
3403 } else if (!strcasecmp(attr->a_name, "ptime")) {
3404 ptime = dptime = atoi(attr->a_value);
3405 } else if (!strcasecmp(attr->a_name, "maxptime")) {
3406 maxptime = dmaxptime = atoi(attr->a_value);
3407 }
3408 }
3409
3410 if (sendonly == 2 && ice) {
3411 sendonly = 0;
3412 }
3413
3414
3415 if (sendonly != 1 && recvonly != 1) {
3416 switch_channel_set_variable(session->channel, "media_audio_mode", NULL)switch_channel_set_variable_var_check(session->channel, "media_audio_mode"
, ((void*)0), SWITCH_TRUE)
;
3417 }
3418
3419 if (!(switch_media_handle_test_media_flag(smh, SCMF_DISABLE_HOLD)
3420 || ((val = switch_channel_get_variable(session->channel, "rtp_disable_hold")switch_channel_get_variable_dup(session->channel, "rtp_disable_hold"
, SWITCH_TRUE, -1)
)
3421 && switch_true(val)))
3422 && !smh->mparams->hold_laps) {
3423 smh->mparams->hold_laps++;
3424 if (switch_core_media_toggle_hold(session, sendonly)) {
3425 reneg = switch_media_handle_test_media_flag(smh, SCMF_RENEG_ON_HOLD);
3426 if ((val = switch_channel_get_variable(session->channel, "rtp_renegotiate_codec_on_hold")switch_channel_get_variable_dup(session->channel, "rtp_renegotiate_codec_on_hold"
, SWITCH_TRUE, -1)
)) {
3427 reneg = switch_true(val);
3428 }
3429 }
3430 }
3431
3432 if (reneg) {
3433 reneg = switch_media_handle_test_media_flag(smh, SCMF_RENEG_ON_REINVITE);
3434
3435 if ((val = switch_channel_get_variable(session->channel, "rtp_renegotiate_codec_on_reinvite")switch_channel_get_variable_dup(session->channel, "rtp_renegotiate_codec_on_reinvite"
, SWITCH_TRUE, -1)
)) {
3436 reneg = switch_true(val);
3437 }
3438 }
3439
3440 if (session->bugs) {
3441 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3441, (const char*)(session)
, SWITCH_LOG_DEBUG,
3442 "Session is connected to a media bug. "
3443 "Re-Negotiation implicitly disabled.\n");
3444 reneg = 0;
3445 }
3446
3447 if (switch_channel_test_flag(session->channel, CF_RECOVERING)) {
3448 reneg = 0;
3449 }
3450
3451 if (sdp_type == SDP_TYPE_RESPONSE && smh->num_negotiated_codecs) {
3452 /* response to re-invite or update, only negotiated codecs are valid */
3453 reneg = 0;
3454 }
3455
3456
3457 if (!reneg && smh->num_negotiated_codecs) {
3458 codec_array = smh->negotiated_codecs;
3459 total_codecs = smh->num_negotiated_codecs;
3460 } else if (reneg) {
3461 smh->mparams->num_codecs = 0;
3462 switch_core_media_prepare_codecs(session, SWITCH_FALSE);
3463 codec_array = smh->codecs;
3464 total_codecs = smh->mparams->num_codecs;
3465 }
3466
3467
3468 if (switch_rtp_has_dtls() && dtls_ok(session)) {
3469 for (attr = m->m_attributes; attr; attr = attr->a_next) {
3470
3471 if (!strcasecmp(attr->a_name, "fingerprint") && !zstr(attr->a_value)_zstr(attr->a_value)) {
3472 got_crypto = 1;
3473 }
3474 }
3475 }
3476
3477 for (attr = m->m_attributes; attr; attr = attr->a_next) {
3478
3479 if (!strcasecmp(attr->a_name, "rtcp") && attr->a_value) {
3480 switch_channel_set_variable(session->channel, "rtp_remote_audio_rtcp_port", attr->a_value)switch_channel_set_variable_var_check(session->channel, "rtp_remote_audio_rtcp_port"
, attr->a_value, SWITCH_TRUE)
;
3481 a_engine->remote_rtcp_port = (switch_port_t)atoi(attr->a_value);
3482 if (!smh->mparams->rtcp_audio_interval_msec) {
3483 smh->mparams->rtcp_audio_interval_msec = "5000";
3484 }
3485 } else if (!strcasecmp(attr->a_name, "ptime") && attr->a_value) {
3486 ptime = atoi(attr->a_value);
3487 } else if (!strcasecmp(attr->a_name, "maxptime") && attr->a_value) {
3488 maxptime = atoi(attr->a_value);
3489 } else if (got_crypto < 1 && !strcasecmp(attr->a_name, "crypto") && !zstr(attr->a_value)_zstr(attr->a_value)) {
3490 int crypto_tag;
3491
3492 if (!(smh->mparams->ndlb & SM_NDLB_ALLOW_CRYPTO_IN_AVP) &&
3493 !switch_true(switch_channel_get_variable(session->channel, "rtp_allow_crypto_in_avp")switch_channel_get_variable_dup(session->channel, "rtp_allow_crypto_in_avp"
, SWITCH_TRUE, -1)
)) {
3494 if (m->m_proto != sdp_proto_srtp && !got_webrtc) {
3495 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3495, (const char*)(session)
, SWITCH_LOG_ERROR, "a=crypto in RTP/AVP, refer to rfc3711\n");
3496 match = 0;
3497 goto done;
3498 }
3499 }
3500
3501 crypto = attr->a_value;
3502 crypto_tag = atoi(crypto);
3503 got_crypto = switch_core_session_check_incoming_crypto(session,
3504 "rtp_has_crypto", SWITCH_MEDIA_TYPE_AUDIO, crypto, crypto_tag, sdp_type);
3505
3506 }
3507 }
3508
3509 if (got_crypto == -1 && got_savp && !got_avp && !got_webrtc) {
3510 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3510, (const char*)(session)
, SWITCH_LOG_WARNING, "Declining invite with only SAVP because secure media is administratively disabled\n");
3511 match = 0;
3512 break;
3513 }
3514
3515 connection = sdp->sdp_connection;
3516 if (m->m_connections) {
3517 connection = m->m_connections;
3518 }
3519
3520 if (!connection) {
3521 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3521, (const char*)(session)
, SWITCH_LOG_ERROR, "Cannot find a c= line in the sdp at media or session level!\n");
3522 match = 0;
3523 break;
3524 }
3525
3526 x = 0;
3527
3528 for (map = m->m_rtpmaps; map; map = map->rm_next) {
3529 int32_t i;
3530 const char *rm_encoding;
3531 uint32_t map_bit_rate = 0;
3532 switch_codec_fmtp_t codec_fmtp = { 0 };
3533 int map_channels = map->rm_params ? atoi(map->rm_params) : 1;
3534
3535 if (!(rm_encoding = map->rm_encoding)) {
3536 rm_encoding = "";
3537 }
3538
3539
3540 if (!strcasecmp(rm_encoding, "telephone-event")) {
3541 if (!best_te || map->rm_rate == a_engine->cur_payload_map->rm_rate) {
3542 best_te = (switch_payload_t) map->rm_pt;
3543 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3543, (const char*)(session)
, SWITCH_LOG_DEBUG, "Set telephone-event payload to %u\n", best_te);
3544 }
3545 continue;
3546 }
3547
3548 if (!switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG) && !cng_pt && !strcasecmp(rm_encoding, "CN")) {
3549 cng_pt = (switch_payload_t) map->rm_pt;
3550 if (a_engine->rtp_session) {
3551 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3551, (const char*)(session)
, SWITCH_LOG_DEBUG, "Set comfort noise payload to %u\n", cng_pt);
3552 switch_rtp_set_cng_pt(a_engine->rtp_session, smh->mparams->cng_pt);
3553 }
3554 continue;
3555 }
3556
3557
3558 if (x++ < skip) {
3559 continue;
3560 }
3561
3562 if (match) {
3563 continue;
3564 }
3565
3566 codec_ms = ptime;
3567
3568 if (switch_channel_get_variable(session->channel, "rtp_h_X-Broken-PTIME")switch_channel_get_variable_dup(session->channel, "rtp_h_X-Broken-PTIME"
, SWITCH_TRUE, -1)
&& a_engine->read_impl.microseconds_per_packet) {
3569 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3569, (const char*)(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);
3570 codec_ms = a_engine->read_impl.microseconds_per_packet / 1000;
3571 }
3572
3573 if (maxptime && (!codec_ms || codec_ms > maxptime)) {
3574 codec_ms = maxptime;
3575 }
3576
3577 if (!codec_ms) {
3578 codec_ms = switch_default_ptime(rm_encoding, map->rm_pt);
3579 }
3580
3581 map_bit_rate = switch_known_bitrate((switch_payload_t)map->rm_pt);
3582
3583 if (!ptime && !strcasecmp(map->rm_encoding, "g723")) {
3584 codec_ms = 30;
3585 }
3586
3587 remote_codec_rate = map->rm_rate;
3588 fmtp_remote_codec_rate = 0;
3589 memset(&codec_fmtp, 0, sizeof(codec_fmtp));
3590
3591 if (zstr(map->rm_fmtp)_zstr(map->rm_fmtp)) {
3592 if (!strcasecmp(map->rm_encoding, "ilbc")) {
3593 codec_ms = 30;
3594 map_bit_rate = 13330;
3595 } else if (!strcasecmp(map->rm_encoding, "isac")) {
3596 codec_ms = 30;
3597 map_bit_rate = 32000;
3598 }
3599 } else {
3600 if ((switch_core_codec_parse_fmtp(map->rm_encoding, map->rm_fmtp, map->rm_rate, &codec_fmtp)) == SWITCH_STATUS_SUCCESS) {
3601 if (codec_fmtp.bits_per_second) {
3602 map_bit_rate = codec_fmtp.bits_per_second;
3603 }
3604 if (codec_fmtp.microseconds_per_packet) {
3605 codec_ms = (codec_fmtp.microseconds_per_packet / 1000);
3606 }
3607 if (codec_fmtp.actual_samples_per_second) {
3608 fmtp_remote_codec_rate = codec_fmtp.actual_samples_per_second;
3609 }
3610 if (codec_fmtp.stereo) {
3611 map_channels = 2;
3612 } else if (!strcasecmp(map->rm_encoding, "opus")) {
3613 map_channels = 1;
3614 }
3615 }
3616 }
3617
3618 for (i = 0; i < smh->mparams->num_codecs && i < total_codecs; i++) {
3619 const switch_codec_implementation_t *imp = codec_array[i];
3620 uint32_t bit_rate = imp->bits_per_second;
3621 uint32_t codec_rate = imp->samples_per_second;
3622
3623 if (imp->codec_type != SWITCH_CODEC_TYPE_AUDIO) {
3624 continue;
3625 }
3626
3627 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3627, (const char*)(session)
, SWITCH_LOG_DEBUG, "Audio Codec Compare [%s:%d:%u:%d:%u:%d]/[%s:%d:%u:%d:%u:%d]\n",
3628 rm_encoding, map->rm_pt, (int) remote_codec_rate, codec_ms, map_bit_rate, map_channels,
3629 imp->iananame, imp->ianacode, codec_rate, imp->microseconds_per_packet / 1000, bit_rate, imp->number_of_channels);
3630 if ((zstr(map->rm_encoding)_zstr(map->rm_encoding) || (smh->mparams->ndlb & SM_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) {
3631 match = (map->rm_pt == imp->ianacode) ? 1 : 0;
3632 } else {
3633 match = (!strcasecmp(rm_encoding, imp->iananame) &&
3634 ((map->rm_pt < 96 && imp->ianacode < 96) || (map->rm_pt > 95 && imp->ianacode > 95)) &&
3635 (remote_codec_rate == codec_rate || fmtp_remote_codec_rate == imp->actual_samples_per_second)) ? 1 : 0;
3636 if (fmtp_remote_codec_rate) {
3637 remote_codec_rate = fmtp_remote_codec_rate;
3638 }
3639 }
3640
3641 if (match && bit_rate && map_bit_rate && map_bit_rate != bit_rate && strcasecmp(map->rm_encoding, "ilbc") &&
3642 strcasecmp(map->rm_encoding, "isac")) {
3643 /* if a bit rate is specified and doesn't match, this is not a codec match, except for ILBC */
3644 match = 0;
3645 }
3646
3647 if (match && remote_codec_rate && codec_rate && remote_codec_rate != codec_rate && (!strcasecmp(map->rm_encoding, "pcma") ||
3648 !strcasecmp(map->rm_encoding, "pcmu"))) {
3649 /* if the sampling rate is specified and doesn't match, this is not a codec match for G.711 */
3650 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3650, (const char*)(session)
, SWITCH_LOG_DEBUG, "sampling rates have to match for G.711\n");
3651 match = 0;
3652 }
3653
3654 if (match) {
3655 if (scrooge) {
3656 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3656, (const char*)(session)
, SWITCH_LOG_DEBUG,
3657 "Bah HUMBUG! Sticking with %s@%uh@%ui\n",
3658 imp->iananame, imp->samples_per_second, imp->microseconds_per_packet / 1000);
3659 } else if ((ptime && codec_ms && codec_ms * 1000 != imp->microseconds_per_packet) || remote_codec_rate != codec_rate) {
3660 /* ptime does not match */
3661 match = 0;
3662
3663 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3663, (const char*)(session)
, SWITCH_LOG_DEBUG,
3664 "Audio Codec Compare [%s:%d:%u:%d:%u:%d] is saved as a near-match\n",
3665 imp->iananame, imp->ianacode, codec_rate, imp->microseconds_per_packet / 1000, bit_rate, imp->number_of_channels);
3666
3667 near_matches[nm_idx].codec_idx = i;
3668 near_matches[nm_idx].rate = remote_codec_rate;
3669 near_matches[nm_idx].imp = imp;
3670 near_matches[nm_idx].map = map;
3671 nm_idx++;
3672
3673 continue;
3674 }
3675
3676 matches[m_idx].codec_idx = i;
3677 matches[m_idx].rate = codec_rate;
3678 matches[m_idx].imp = imp;
3679 matches[m_idx].map = map;
3680 m_idx++;
3681
3682 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3682, (const char*)(session)
, SWITCH_LOG_DEBUG,
3683 "Audio Codec Compare [%s:%d:%u:%d:%u:%d] ++++ is saved as a match\n",
3684 imp->iananame, imp->ianacode, codec_rate, imp->microseconds_per_packet / 1000, bit_rate, imp->number_of_channels);
3685
3686 if (m_idx >= MAX_MATCHES30) {
3687 break;
3688 }
3689
3690 match = 0;
3691 }
3692 }
3693
3694 if (m_idx >= MAX_MATCHES30) {
3695 break;
3696 }
3697 }
3698
3699 if (smh->crypto_mode == CRYPTO_MODE_MANDATORY && got_crypto < 1) {
3700 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3700, (const char*)(session)
, SWITCH_LOG_WARNING, "Crypto not negotiated but required.\n");
3701 match = 0;
3702 m_idx = nm_idx = 0;
3703 }
3704
3705
3706 if (!m_idx && nm_idx) {
3707 int j;
3708
3709 for(j = 0; j < nm_idx; j++) {
3710 const switch_codec_implementation_t *search[1];
3711 char *prefs[1];
3712 char tmp[80];
3713 int num;
3714 const switch_codec_implementation_t *timp = NULL((void*)0);
3715
3716 near_rate = near_matches[j].rate;
3717 near_match = near_matches[j].imp;
3718 near_map = near_matches[j].map;
3719
3720 switch_snprintf(tmp, sizeof(tmp), "%s@%uh@%ui%dc", near_match->iananame, near_rate ? near_rate : near_match->samples_per_second,
3721 codec_ms, near_match->number_of_channels);
3722
3723 prefs[0] = tmp;
3724 num = switch_loadable_module_get_codecs_sorted(search, 1, prefs, 1);
3725
3726 if (num) {
3727 timp = search[0];
3728 } else {
3729 timp = near_match;
3730 }
3731
3732 if (!maxptime || timp->microseconds_per_packet / 1000 <= maxptime) {
3733 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3733, (const char*)(session)
, SWITCH_LOG_DEBUG, "Substituting codec %s@%ui@%uh@%dc\n",
3734 timp->iananame, timp->microseconds_per_packet / 1000, timp->actual_samples_per_second, timp->number_of_channels);
3735 match = 1;
3736
3737 matches[m_idx].codec_idx = near_matches[j].codec_idx;
3738 matches[m_idx].rate = near_rate;
3739 matches[m_idx].imp = timp;
3740 matches[m_idx].map = near_map;
3741 m_idx++;
3742
3743 break;
3744 }
3745 }
3746 }
3747
3748 if (m_idx) {
3749 int j;
3750
3751 if (greedy) { /* sort in favor of mine */
3752 greedy_sort(smh, matches, m_idx, codec_array, total_codecs);
3753 }
3754
3755 match = 1;
3756 a_engine->codec_negotiated = 1;
3757 smh->num_negotiated_codecs = 0;
3758
3759 for(j = 0; j < m_idx; j++) {
3760 payload_map_t *pmap = switch_core_media_add_payload_map(session,
3761 SWITCH_MEDIA_TYPE_AUDIO,
3762 matches[j].map->rm_encoding,
3763 matches[j].map->rm_fmtp,
3764 sdp_type,
3765 matches[j].map->rm_pt,
3766 matches[j].imp->samples_per_second,
3767 matches[j].imp->microseconds_per_packet / 1000,
3768 matches[j].imp->number_of_channels,
3769 SWITCH_TRUE);
3770
3771 mimp = matches[j].imp;
3772 mmap = matches[j].map;
3773
3774 if (j == 0) {
3775 a_engine->cur_payload_map = pmap;
3776 a_engine->cur_payload_map->current = 1;
3777 if (a_engine->rtp_session) {
3778 switch_rtp_set_default_payload(a_engine->rtp_session, pmap->pt);
3779 }
3780 }
3781
3782 pmap->rm_encoding = switch_core_session_strdup(session, (char *) mmap->rm_encoding)switch_core_perform_session_strdup(session, (char *) mmap->
rm_encoding, "src/switch_core_media.c", (const char *)__func__
, 3782)
;
3783 pmap->iananame = switch_core_session_strdup(session, (char *) mimp->iananame)switch_core_perform_session_strdup(session, (char *) mimp->
iananame, "src/switch_core_media.c", (const char *)__func__, 3783
)
;
3784 pmap->recv_pt = (switch_payload_t) mmap->rm_pt;
3785 pmap->rm_rate = mimp->samples_per_second;
3786 pmap->adv_rm_rate = mimp->samples_per_second;
3787 if (strcasecmp(mimp->iananame, "g722")) {
3788 pmap->rm_rate = mimp->actual_samples_per_second;
3789 }
3790 pmap->codec_ms = mimp->microseconds_per_packet / 1000;
3791 pmap->bitrate = mimp->bits_per_second;
3792 pmap->channels = mmap->rm_params ? atoi(mmap->rm_params) : 1;
3793
3794 if (!strcasecmp((char *) mmap->rm_encoding, "opus")) {
3795 if (pmap->channels == 1) {
3796 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3796, (const char*)(session)
, SWITCH_LOG_WARNING, "Invalid SDP for opus. Don't ask.. but it needs a /2\n");
3797 pmap->adv_channels = 1;
3798 } else {
3799 pmap->adv_channels = 2; /* IKR ???*/
3800 }
3801 if (!zstr((char *) mmap->rm_fmtp)_zstr((char *) mmap->rm_fmtp) && switch_stristr("stereo=1", (char *) mmap->rm_fmtp)) {
3802 pmap->channels = 2;
3803 } else {
3804 pmap->channels = 1;
3805 }
3806 } else {
3807 pmap->adv_channels = pmap->channels;
3808 }
3809
3810 pmap->remote_sdp_ip = switch_core_session_strdup(session, (char *) connection->c_address)switch_core_perform_session_strdup(session, (char *) connection
->c_address, "src/switch_core_media.c", (const char *)__func__
, 3810)
;
3811 pmap->remote_sdp_port = (switch_port_t) m->m_port;
3812 pmap->rm_fmtp = switch_core_session_strdup(session, (char *) mmap->rm_fmtp)switch_core_perform_session_strdup(session, (char *) mmap->
rm_fmtp, "src/switch_core_media.c", (const char *)__func__, 3812
)
;
3813
3814 pmap->agreed_pt = (switch_payload_t) mmap->rm_pt;
3815 smh->negotiated_codecs[smh->num_negotiated_codecs++] = mimp;
3816 pmap->recv_pt = (switch_payload_t)mmap->rm_pt;
3817
3818 }
3819 }
3820
3821 if (match) {
3822 char tmp[50];
3823 //const char *mirror = switch_channel_get_variable(session->channel, "rtp_mirror_remote_audio_codec_payload");
3824
3825
3826 switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->cur_payload_map->remote_sdp_port);
3827 switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, a_engine->cur_payload_map->remote_sdp_ip)switch_channel_set_variable_var_check(session->channel, "remote_media_ip"
, a_engine->cur_payload_map->remote_sdp_ip, SWITCH_TRUE
)
;
3828 switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp)switch_channel_set_variable_var_check(session->channel, "remote_media_port"
, tmp, SWITCH_TRUE)
;
3829
3830
3831 if (a_engine->cur_payload_map->pt == smh->mparams->te) {
3832 switch_payload_t pl = 0;
3833 payload_map_t *pmap;
3834
3835 switch_mutex_lock(smh->sdp_mutex);
3836 for (pmap = a_engine->cur_payload_map; pmap && pmap->allocated; pmap = pmap->next) {
3837 if (pmap->pt > pl) {
3838 pl = pmap->pt;
3839 }
3840 }
3841 switch_mutex_unlock(smh->sdp_mutex);
3842
3843 smh->mparams->te = (switch_payload_t) ++pl;
3844 }
3845
3846
3847
3848#if 0
3849 if (!switch_true(mirror) &&
3850 switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND &&
3851 (!switch_channel_test_flag(session->channel, CF_REINVITE) || switch_media_handle_test_media_flag(smh, SCMF_RENEG_ON_REINVITE))) {
3852 switch_core_media_get_offered_pt(session, matches[0].imp, &a_engine->cur_payload_map->recv_pt);
3853 }
3854#endif
3855
3856 switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->cur_payload_map->recv_pt);
3857 switch_channel_set_variable(session->channel, "rtp_audio_recv_pt", tmp)switch_channel_set_variable_var_check(session->channel, "rtp_audio_recv_pt"
, tmp, SWITCH_TRUE)
;
3858
3859 if (switch_core_codec_ready(&a_engine->read_codec) && strcasecmp(matches[0].imp->iananame, a_engine->read_codec.implementation->iananame)) {
3860 a_engine->reset_codec = 1;
3861 }
3862
3863 if (switch_core_media_set_codec(session, 0, smh->mparams->codec_flags) == SWITCH_STATUS_SUCCESS) {
3864 got_audio = 1;
3865 check_ice(smh, SWITCH_MEDIA_TYPE_AUDIO, sdp, m);
3866 } else {
3867 match = 0;
3868 }
3869 }
3870
3871 if (!best_te && (switch_media_handle_test_media_flag(smh, SCMF_LIBERAL_DTMF) ||
3872 switch_channel_test_flag(session->channel, CF_LIBERAL_DTMF))) {
3873 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3873, (const char*)(session)
, SWITCH_LOG_DEBUG,
3874 "No 2833 in SDP. Liberal DTMF mode adding %d as telephone-event.\n", smh->mparams->te);
3875 best_te = smh->mparams->te;
3876 }
3877
3878 if (best_te) {
3879 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
3880 te = smh->mparams->te = (switch_payload_t) best_te;
3881 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3881, (const char*)(session)
, SWITCH_LOG_DEBUG, "Set 2833 dtmf send payload to %u\n", best_te);
3882 switch_channel_set_variable(session->channel, "dtmf_type", "rfc2833")switch_channel_set_variable_var_check(session->channel, "dtmf_type"
, "rfc2833", SWITCH_TRUE)
;
3883 smh->mparams->dtmf_type = DTMF_2833;
3884 if (a_engine->rtp_session) {
3885 switch_rtp_set_telephony_event(a_engine->rtp_session, (switch_payload_t) best_te);
3886 switch_channel_set_variable_printf(session->channel, "rtp_2833_send_payload", "%d", best_te);
3887 }
3888 } else {
3889 te = smh->mparams->recv_te = smh->mparams->te = (switch_payload_t) best_te;
3890 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3890, (const char*)(session)
, SWITCH_LOG_DEBUG, "Set 2833 dtmf send/recv payload to %u\n", te);
3891 switch_channel_set_variable(session->channel, "dtmf_type", "rfc2833")switch_channel_set_variable_var_check(session->channel, "dtmf_type"
, "rfc2833", SWITCH_TRUE)
;
3892 smh->mparams->dtmf_type = DTMF_2833;
3893 if (a_engine->rtp_session) {
3894 switch_rtp_set_telephony_event(a_engine->rtp_session, te);
3895 switch_channel_set_variable_printf(session->channel, "rtp_2833_send_payload", "%d", te);
3896 switch_rtp_set_telephony_recv_event(a_engine->rtp_session, te);
3897 switch_channel_set_variable_printf(session->channel, "rtp_2833_recv_payload", "%d", te);
3898 }
3899 }
3900 } else {
3901 /* by default, use SIP INFO if 2833 is not in the SDP */
3902 if (!switch_false(switch_channel_get_variable(channel, "rtp_info_when_no_2833")switch_channel_get_variable_dup(channel, "rtp_info_when_no_2833"
, SWITCH_TRUE, -1)
)) {
3903 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3903, (const char*)(session)
, SWITCH_LOG_DEBUG, "No 2833 in SDP. Disable 2833 dtmf and switch to INFO\n");
3904 switch_channel_set_variable(session->channel, "dtmf_type", "info")switch_channel_set_variable_var_check(session->channel, "dtmf_type"
, "info", SWITCH_TRUE)
;
3905 smh->mparams->dtmf_type = DTMF_INFO;
3906 te = smh->mparams->recv_te = smh->mparams->te = 0;
Value stored to 'te' is never read
3907 } else {
3908 switch_channel_set_variable(session->channel, "dtmf_type", "none")switch_channel_set_variable_var_check(session->channel, "dtmf_type"
, "none", SWITCH_TRUE)
;
3909 smh->mparams->dtmf_type = DTMF_NONE;
3910 te = smh->mparams->recv_te = smh->mparams->te = 0;
3911 }
3912 }
3913
3914 } else if (m->m_type == sdp_media_video && m->m_port) {
3915 sdp_rtpmap_t *map;
3916 const char *rm_encoding;
3917 const switch_codec_implementation_t *mimp = NULL((void*)0);
3918 int vmatch = 0, i;
3919
3920 nm_idx = 0;
3921 m_idx = 0;
3922 memset(matches, 0, sizeof(matches[0]) * MAX_MATCHES30);
3923 memset(near_matches, 0, sizeof(near_matches[0]) * MAX_MATCHES30);
3924
3925 switch_channel_set_variable(session->channel, "video_possible", "true")switch_channel_set_variable_var_check(session->channel, "video_possible"
, "true", SWITCH_TRUE)
;
3926
3927 connection = sdp->sdp_connection;
3928 if (m->m_connections) {
3929 connection = m->m_connections;
3930 }
3931
3932 if (!connection) {
3933 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3933, (const char*)(session)
, SWITCH_LOG_ERROR, "Cannot find a c= line in the sdp at media or session level!\n");
3934 match = 0;
3935 break;
3936 }
3937
3938 for (map = m->m_rtpmaps; map; map = map->rm_next) {
3939
3940 if (switch_rtp_has_dtls() && dtls_ok(session)) {
3941 for (attr = m->m_attributes; attr; attr = attr->a_next) {
3942 if (!strcasecmp(attr->a_name, "fingerprint") && !zstr(attr->a_value)_zstr(attr->a_value)) {
3943 got_video_crypto = 1;
3944 }
3945 }
3946 }
3947
3948 for (attr = m->m_attributes; attr; attr = attr->a_next) {
3949 if (!strcasecmp(attr->a_name, "framerate") && attr->a_value) {
3950 //framerate = atoi(attr->a_value);
3951 } else if (!strcasecmp(attr->a_name, "rtcp-fb")) {
3952 if (!zstr(attr->a_value)_zstr(attr->a_value)) {
3953 if (switch_stristr("fir", attr->a_value)) {
3954 v_engine->fir++;
3955 }
3956
3957 //if (switch_stristr("pli", attr->a_value)) {
3958 // v_engine->pli++;
3959 //}
3960
3961 smh->mparams->rtcp_video_interval_msec = "10000";
3962 }
3963 } else if (!strcasecmp(attr->a_name, "rtcp") && attr->a_value && !strcmp(attr->a_value, "1")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(attr->a_value) && __builtin_constant_p ("1") &&
(__s1_len = __builtin_strlen (attr->a_value), __s2_len = __builtin_strlen
("1"), (!((size_t)(const void *)((attr->a_value) + 1) - (
size_t)(const void *)(attr->a_value) == 1) || __s1_len >=
4) && (!((size_t)(const void *)(("1") + 1) - (size_t
)(const void *)("1") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(attr->a_value, "1") : (__builtin_constant_p (attr->a_value
) && ((size_t)(const void *)((attr->a_value) + 1) -
(size_t)(const void *)(attr->a_value) == 1) && (__s1_len
= __builtin_strlen (attr->a_value), __s1_len < 4) ? (__builtin_constant_p
("1") && ((size_t)(const void *)(("1") + 1) - (size_t
)(const void *)("1") == 1) ? __builtin_strcmp (attr->a_value
, "1") : (__extension__ ({ const unsigned char *__s2 = (const
unsigned char *) (const char *) ("1"); int __result = (((const
unsigned char *) (const char *) (attr->a_value))[0] - __s2
[0]); if (__s1_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) (attr->a_value
))[1] - __s2[1]); if (__s1_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (attr
->a_value))[2] - __s2[2]); if (__s1_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) (attr
->a_value))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("1") && ((size_t)(const void *)(("1") + 1) - (size_t
)(const void *)("1") == 1) && (__s2_len = __builtin_strlen
("1"), __s2_len < 4) ? (__builtin_constant_p (attr->a_value
) && ((size_t)(const void *)((attr->a_value) + 1) -
(size_t)(const void *)(attr->a_value) == 1) ? __builtin_strcmp
(attr->a_value, "1") : (- (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (attr->
a_value); int __result = (((const unsigned char *) (const char
*) ("1"))[0] - __s2[0]); if (__s2_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
"1"))[1] - __s2[1]); if (__s2_len > 1 && __result ==
0) { __result = (((const unsigned char *) (const char *) ("1"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("1"))[
3] - __s2[3]); } } __result; })))) : __builtin_strcmp (attr->
a_value, "1")))); })
) {
3964 switch_channel_set_variable(session->channel, "rtp_remote_video_rtcp_port", attr->a_value)switch_channel_set_variable_var_check(session->channel, "rtp_remote_video_rtcp_port"
, attr->a_value, SWITCH_TRUE)
;
3965 v_engine->remote_rtcp_port = (switch_port_t)atoi(attr->a_value);
3966 if (!smh->mparams->rtcp_video_interval_msec) {
3967 smh->mparams->rtcp_video_interval_msec = "5000";
3968 }
3969 } else if (!got_video_crypto && !strcasecmp(attr->a_name, "crypto") && !zstr(attr->a_value)_zstr(attr->a_value)) {
3970 int crypto_tag;
3971
3972 if (!(smh->mparams->ndlb & SM_NDLB_ALLOW_CRYPTO_IN_AVP) &&
3973 !switch_true(switch_channel_get_variable(session->channel, "rtp_allow_crypto_in_avp")switch_channel_get_variable_dup(session->channel, "rtp_allow_crypto_in_avp"
, SWITCH_TRUE, -1)
)) {
3974 if (m->m_proto != sdp_proto_srtp && !got_webrtc) {
3975 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 3975, (const char*)(session)
, SWITCH_LOG_ERROR, "a=crypto in RTP/AVP, refer to rfc3711\n");
3976 match = 0;
3977 goto done;
3978 }
3979 }
3980
3981 crypto = attr->a_value;
3982 crypto_tag = atoi(crypto);
3983
3984 got_video_crypto = switch_core_session_check_incoming_crypto(session,
3985 "rtp_has_video_crypto",
3986 SWITCH_MEDIA_TYPE_VIDEO, crypto, crypto_tag, sdp_type);
3987
3988 }
3989 }
3990
3991 if (!(rm_encoding = map->rm_encoding)) {
3992 rm_encoding = "";
3993 }
3994
3995 for (i = 0; i < total_codecs; i++) {
3996 const switch_codec_implementation_t *imp = codec_array[i];
3997
3998 if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO) {
3999 continue;
4000 }
4001
4002 if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_INBOUND &&
4003 switch_channel_test_flag(session->channel, CF_NOVIDEO)) {
4004 continue;
4005 }
4006
4007 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 4007, (const char*)(session)
, SWITCH_LOG_DEBUG, "Video Codec Compare [%s:%d]/[%s:%d]\n",
4008 rm_encoding, map->rm_pt, imp->iananame, imp->ianacode);
4009 if ((zstr(map->rm_encoding)_zstr(map->rm_encoding) || (smh->mparams->ndlb & SM_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) {
4010 vmatch = (map->rm_pt == imp->ianacode) ? 1 : 0;
4011 } else {
4012 vmatch = strcasecmp(rm_encoding, imp->iananame) ? 0 : 1;
4013 }
4014
4015
4016 if (vmatch && (map->rm_rate == imp->samples_per_second)) {
4017 matches[m_idx].imp = imp;
4018 matches[m_idx].map = map;
4019
4020 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 4020, (const char*)(session)
, SWITCH_LOG_DEBUG, "Video Codec Compare [%s:%d] +++ is saved as a match\n",
4021 imp->iananame, imp->ianacode);
4022 m_idx++;
4023 }
4024
4025 vmatch = 0;
4026 }
4027 }
4028
4029 if (smh->crypto_mode == CRYPTO_MODE_MANDATORY && got_video_crypto < 1) {
4030 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 4030, (const char*)(session)
, SWITCH_LOG_WARNING, "Crypto not negotiated but required.\n");
4031 vmatch = 0;
4032 m_idx = 0;
4033 }
4034
4035 if (m_idx) {
4036 char tmp[50];
4037 //const char *mirror = switch_channel_get_variable(session->channel, "rtp_mirror_remote_video_codec_payload");
4038 int j = 0;
4039
4040 if (greedy) { /* sort in favor of mine */
4041 greedy_sort(smh, matches, m_idx, codec_array, total_codecs);
4042 }
4043
4044 vmatch = 1;
4045 v_engine->codec_negotiated = 1;
4046
4047 for(j = 0; j < m_idx; j++) {
4048 payload_map_t *pmap = switch_core_media_add_payload_map(session,
4049 SWITCH_MEDIA_TYPE_VIDEO,
4050 matches[j].map->rm_encoding,
4051 matches[j].map->rm_fmtp,
4052 sdp_type,
4053 matches[j].map->rm_pt,
4054 matches[j].imp->samples_per_second,
4055 matches[j].imp->microseconds_per_packet / 1000,
4056 matches[j].imp->number_of_channels,
4057 SWITCH_TRUE);
4058 if (j == 0) {
4059 v_engine->cur_payload_map = pmap;
4060 v_engine->cur_payload_map->current = 1;
4061 if (v_engine->rtp_session) {
4062 switch_rtp_set_default_payload(v_engine->rtp_session, pmap->pt);
4063 }
4064 }
4065
4066 mimp = matches[j].imp;
4067 map = matches[j].map;
4068
4069 pmap->rm_encoding = switch_core_session_strdup(session, (char *) map->rm_encoding)switch_core_perform_session_strdup(session, (char *) map->
rm_encoding, "src/switch_core_media.c", (const char *)__func__
, 4069)
;
4070 pmap->recv_pt = (switch_payload_t) map->rm_pt;
4071 pmap->rm_rate = map->rm_rate;
4072 pmap->codec_ms = mimp->microseconds_per_packet / 1000;
4073
4074
4075 pmap->remote_sdp_ip = switch_core_session_strdup(session, (char *) connection->c_address)switch_core_perform_session_strdup(session, (char *) connection
->c_address, "src/switch_core_media.c", (const char *)__func__
, 4075)
;
4076 pmap->remote_sdp_port = (switch_port_t) m->m_port;
4077
4078 pmap->rm_fmtp = switch_core_session_strdup(session, (char *) map->rm_fmtp)switch_core_perform_session_strdup(session, (char *) map->
rm_fmtp, "src/switch_core_media.c", (const char *)__func__, 4078
)
;
4079
4080 pmap->agreed_pt = (switch_payload_t) map->rm_pt;
4081
4082
4083#if 0
4084 if (j == 0 && (!switch_true(mirror) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND)) {
4085 switch_core_media_get_offered_pt(session, mimp, &pmap->recv_pt);
4086 }
4087#endif
4088 }
4089
4090
4091
4092 switch_snprintf(tmp, sizeof(tmp), "%d", v_engine->cur_payload_map->remote_sdp_port);
4093 switch_channel_set_variable(session->channel, SWITCH_REMOTE_VIDEO_IP_VARIABLE, v_engine->cur_payload_map->remote_sdp_ip)switch_channel_set_variable_var_check(session->channel, "remote_video_ip"
, v_engine->cur_payload_map->remote_sdp_ip, SWITCH_TRUE
)
;
4094 switch_channel_set_variable(session->channel, SWITCH_REMOTE_VIDEO_PORT_VARIABLE, tmp)switch_channel_set_variable_var_check(session->channel, "remote_video_port"
, tmp, SWITCH_TRUE)
;
4095 switch_channel_set_variable(session->channel, "rtp_video_fmtp", v_engine->cur_payload_map->rm_fmtp)switch_channel_set_variable_var_check(session->channel, "rtp_video_fmtp"
, v_engine->cur_payload_map->rm_fmtp, SWITCH_TRUE)
;
4096 switch_snprintf(tmp, sizeof(tmp), "%d", v_engine->cur_payload_map->agreed_pt);
4097 switch_channel_set_variable(session->channel, "rtp_video_pt", tmp)switch_channel_set_variable_var_check(session->channel, "rtp_video_pt"
, tmp, SWITCH_TRUE)
;
4098 switch_core_media_check_video_codecs(session);
4099 switch_snprintf(tmp, sizeof(tmp), "%d", v_engine->cur_payload_map->recv_pt);
4100 switch_channel_set_variable(session->channel, "rtp_video_recv_pt", tmp)switch_channel_set_variable_var_check(session->channel, "rtp_video_recv_pt"
, tmp, SWITCH_TRUE)
;
4101 if (!match && vmatch) match = 1;
4102
4103 if (switch_core_codec_ready(&v_engine->read_codec) && strcasecmp(matches[0].imp->iananame, v_engine->read_codec.implementation->iananame)) {
4104 v_engine->reset_codec = 1;
4105 }
4106
4107 if (switch_core_media_set_video_codec(session, 0) == SWITCH_STATUS_SUCCESS) {
4108 check_ice(smh, SWITCH_MEDIA_TYPE_VIDEO, sdp, m);
4109 }
4110 }
4111 }
4112 }
4113
4114 done:
4115
4116
4117
4118
4119
4120
4121 if (parser) {
4122 sdp_parser_free(parser);
4123 }
4124
4125 smh->mparams->cng_pt = cng_pt;
4126
4127 return match;
4128}
4129
4130//?
4131
4132SWITCH_DECLARE(int)__attribute__((visibility("default"))) int switch_core_media_toggle_hold(switch_core_session_t *session, int sendonly)
4133{
4134 int changed = 0;
4135 switch_rtp_engine_t *a_engine, *v_engine;
4136 switch_media_handle_t *smh;
4137 switch_core_session_t *b_session = NULL((void*)0);
4138 switch_channel_t *b_channel = NULL((void*)0);
4139
4140 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 4140, __PRETTY_FUNCTION__))
;
4141
4142 if (!(smh = session->media_handle)) {
4143 return 0;
4144 }
4145
4146 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
4147 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
4148
4149
4150 if (switch_core_session_get_partner(session, &b_session)switch_core_session_perform_get_partner(session, &b_session
, "src/switch_core_media.c", (const char *)__func__, 4150)
== SWITCH_STATUS_SUCCESS) {
4151 b_channel = switch_core_session_get_channel(b_session);
4152 }
4153
4154 if (sendonly && switch_channel_test_flag(session->channel, CF_ANSWERED)) {
4155 if (!switch_channel_test_flag(session->channel, CF_PROTO_HOLD)) {
4156 const char *stream;
4157 const char *msg = "hold";
4158 const char *info;
4159
4160 if ((switch_channel_test_flag(session->channel, CF_SLA_BARGE) || switch_channel_test_flag(session->channel, CF_SLA_BARGING)) &&
4161 (!b_channel || switch_channel_test_flag(b_channel, CF_EVENT_LOCK_PRI))) {
4162 switch_channel_mark_hold(session->channel, sendonly);
4163 switch_channel_set_flag(session->channel, CF_PROTO_HOLD)switch_channel_set_flag_value(session->channel, CF_PROTO_HOLD
, 1)
;
4164 changed = 0;
4165 goto end;
4166 }
4167
4168 info = switch_channel_get_variable(session->channel, "presence_call_info")switch_channel_get_variable_dup(session->channel, "presence_call_info"
, SWITCH_TRUE, -1)
;
4169
4170 if (info) {
4171 if (switch_stristr("private", info)) {
4172 msg = "hold-private";
4173 }
4174 }
4175
4176 if (a_engine->rtp_session) {
4177 switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PAUSE);
4178 }
4179
4180 if (v_engine->rtp_session) {
4181 switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_PAUSE);
4182 }
4183
4184 switch_channel_set_flag(session->channel, CF_PROTO_HOLD)switch_channel_set_flag_value(session->channel, CF_PROTO_HOLD
, 1)
;
4185 switch_channel_mark_hold(session->channel, SWITCH_TRUE);
4186 switch_channel_presence(session->channel, "unknown", msg, NULL)switch_channel_perform_presence(session->channel, "unknown"
, msg, ((void*)0), "src/switch_core_media.c", (const char *)__func__
, 4186)
;
4187 changed = 1;
4188
4189 if (a_engine->max_missed_hold_packets && a_engine->rtp_session) {
4190 switch_rtp_set_max_missed_packets(a_engine->rtp_session, a_engine->max_missed_hold_packets);
4191 }
4192
4193 if (!(stream = switch_channel_get_hold_music(session->channel))) {
4194 stream = "local_stream://moh";
4195 }
4196
4197
4198 if (stream && strcasecmp(stream, "silence") && (!b_channel || !switch_channel_test_flag(b_channel, CF_EVENT_LOCK_PRI))) {
4199 if (!strcasecmp(stream, "indicate_hold")) {
4200 switch_channel_set_flag(session->channel, CF_SUSPEND)switch_channel_set_flag_value(session->channel, CF_SUSPEND
, 1)
;
4201 switch_channel_set_flag(session->channel, CF_HOLD)switch_channel_set_flag_value(session->channel, CF_HOLD, 1
)
;
4202 switch_ivr_hold_uuid(switch_core_session_get_uuid(b_session), NULL((void*)0), 0);
4203 } else {
4204 switch_ivr_broadcast(switch_core_session_get_uuid(b_session), stream,
4205 SMF_ECHO_ALEG | SMF_LOOP | SMF_PRIORITY);
4206 switch_yield(250000)switch_sleep(250000);;
4207 }
4208 }
4209
4210 }
4211 } else {
4212 if (switch_channel_test_flag(session->channel, CF_HOLD_LOCK)) {
4213 switch_channel_set_flag(session->channel, CF_PROTO_HOLD)switch_channel_set_flag_value(session->channel, CF_PROTO_HOLD
, 1)
;
4214 switch_channel_mark_hold(session->channel, SWITCH_TRUE);
4215
4216 if (a_engine->rtp_session) {
4217 switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PAUSE);
4218 }
4219
4220 if (v_engine->rtp_session) {
4221 switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_PAUSE);
4222 }
4223
4224 changed = 1;
4225 }
4226
4227 switch_channel_clear_flag(session->channel, CF_HOLD_LOCK);
4228
4229 if (switch_channel_test_flag(session->channel, CF_PROTO_HOLD)) {
4230 const char *val;
4231 int media_on_hold_a = switch_true(switch_channel_get_variable_dup(session->channel, "bypass_media_resume_on_hold", SWITCH_FALSE, -1));
4232 int media_on_hold_b = 0;
4233 int bypass_after_hold_a = 0;
4234 int bypass_after_hold_b = 0;
4235
4236 if (media_on_hold_a) {
4237 bypass_after_hold_a = switch_true(switch_channel_get_variable_dup(session->channel, "bypass_media_after_hold", SWITCH_FALSE, -1));
4238 }
4239
4240 if (b_channel) {
4241 if ((media_on_hold_b = switch_true(switch_channel_get_variable_dup(b_channel, "bypass_media_resume_on_hold", SWITCH_FALSE, -1)))) {
4242 bypass_after_hold_b = switch_true(switch_channel_get_variable_dup(b_channel, "bypass_media_after_hold", SWITCH_FALSE, -1));
4243 }
4244 }
4245
4246 switch_yield(250000)switch_sleep(250000);;
4247
4248 if (b_channel && (switch_channel_test_flag(session->channel, CF_BYPASS_MEDIA_AFTER_HOLD) ||
4249 switch_channel_test_flag(b_channel, CF_BYPASS_MEDIA_AFTER_HOLD) || bypass_after_hold_a || bypass_after_hold_b)) {
4250 /* try to stay out from media stream */
4251 switch_ivr_nomedia(switch_core_session_get_uuid(session), SMF_REBRIDGE);
4252 }
4253
4254 if (a_engine->max_missed_packets && a_engine->rtp_session) {
4255 switch_rtp_reset_media_timer(a_engine->rtp_session);
4256 switch_rtp_set_max_missed_packets(a_engine->rtp_session, a_engine->max_missed_packets);
4257 }
4258
4259 if (b_channel) {
4260 if (switch_channel_test_flag(session->channel, CF_HOLD)) {
4261 switch_ivr_unhold(b_session);
4262 switch_channel_clear_flag(session->channel, CF_SUSPEND);
4263 switch_channel_clear_flag(session->channel, CF_HOLD);
4264 } else {
4265 switch_channel_stop_broadcast(b_channel)for(;;) {if (switch_channel_test_flag(b_channel, CF_BROADCAST
)) {switch_channel_set_flag_value(b_channel, CF_STOP_BROADCAST
, 1); switch_channel_set_flag_value(b_channel, CF_BREAK, 1); }
break;}
;
4266 switch_channel_wait_for_flag(b_channel, CF_BROADCAST, SWITCH_FALSE, 5000, NULL((void*)0));
4267 }
4268 }
4269
4270 if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) &&
4271 !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")switch_channel_get_variable_dup(session->channel, "disable_rtp_auto_adjust"
, SWITCH_TRUE, -1)
) && switch_true(val)) &&
4272 !switch_channel_test_flag(session->channel, CF_WEBRTC)) {
4273 /* Reactivate the NAT buster flag. */
4274
4275 if (a_engine->rtp_session) {
4276 switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_AUTOADJ);
4277 }
4278
4279 if (v_engine->rtp_session) {
4280 switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_AUTOADJ);
4281 }
4282 }
4283
4284 switch_channel_clear_flag(session->channel, CF_PROTO_HOLD);
4285 switch_channel_mark_hold(session->channel, SWITCH_FALSE);
4286 switch_channel_presence(session->channel, "unknown", "unhold", NULL)switch_channel_perform_presence(session->channel, "unknown"
, "unhold", ((void*)0), "src/switch_core_media.c", (const char
*)__func__, 4286)
;
4287
4288 if (a_engine->rtp_session) {
4289 switch_rtp_clear_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PAUSE);
4290 }
4291
4292 if (v_engine->rtp_session) {
4293 switch_rtp_clear_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_PAUSE);
4294 }
4295
4296 changed = 1;
4297 }
4298 }
4299
4300
4301 end:
4302
4303 if (b_session) {
4304 switch_core_session_rwunlock(b_session);
4305 }
4306
4307
4308 return changed;
4309}
4310
4311static void *SWITCH_THREAD_FUNC video_helper_thread(switch_thread_t *thread, void *obj)
4312{
4313 struct media_helper *mh = obj;
4314 switch_core_session_t *session = mh->session;
4315 switch_channel_t *channel = switch_core_session_get_channel(session);
4316 switch_status_t status;
4317 switch_frame_t *read_frame;
4318 switch_media_handle_t *smh;
4319
4320 if (!(smh = session->media_handle)) {
4321 return NULL((void*)0);
4322 }
4323
4324 switch_core_session_read_lock(session);
4325
4326 mh->up = 1;
4327 switch_mutex_lock(mh->cond_mutex);
4328
4329 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_media.c", (const char
*)__func__, 4329, ((void*)0)
, SWITCH_LOG_DEBUG, "%s Video thread started. Echo is %s\n",
4330 switch_channel_get_name(session->channel), switch_channel_test_flag(channel, CF_VIDEO_ECHO) ? "on" : "off");
4331 switch_core_session_refresh_video(session);
4332
4333 while (switch_channel_up_nosig(channel)(switch_channel_get_state(channel) < CS_HANGUP)) {
4334
4335 if (switch_channel_test_flag(channel, CF_VIDEO_PASSIVE)) {
4336 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_media.c", (const char
*)__func__, 4336, ((void*)0)
, SWITCH_LOG_DEBUG, "%s Video thread paused. Echo is %s\n",
4337 switch_channel_get_name(session->channel), switch_channel_test_flag(channel, CF_VIDEO_ECHO) ? "on" : "off");
4338 switch_thread_cond_wait(mh->cond, mh->cond_mutex);
4339 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_media.c", (const char
*)__func__, 4339, ((void*)0)
, SWITCH_LOG_DEBUG, "%s Video thread resumed Echo is %s\n",
4340 switch_channel_get_name(session->channel), switch_channel_test_flag(channel, CF_VIDEO_ECHO) ? "on" : "off");
4341 switch_core_session_refresh_video(session);
4342 }
4343
4344 if (switch_channel_test_flag(channel, CF_VIDEO_PASSIVE)) {
4345 continue;
4346 }
4347
4348 if (!switch_channel_media_up(session->channel)(switch_channel_test_flag(session->channel, CF_ANSWERED) ||
switch_channel_test_flag(session->channel, CF_EARLY_MEDIA
))
) {
4349 switch_yield(10000)switch_sleep(10000);;
4350 continue;
4351 }
4352
4353
4354 status = switch_core_session_read_video_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
4355
4356 if (!SWITCH_READ_ACCEPTABLE(status)(status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK
|| status == SWITCH_STATUS_INUSE)
) {
4357 switch_cond_next();
4358 continue;
4359 }
4360
4361
4362 if (switch_channel_test_flag(channel, CF_VIDEO_REFRESH_REQ)) {
4363 switch_core_session_refresh_video(session);
4364 switch_channel_clear_flag(channel, CF_VIDEO_REFRESH_REQ);
4365 }
4366
4367 if (switch_test_flag(read_frame, SFF_CNG)((read_frame)->flags & SFF_CNG)) {
4368 continue;
4369 }
4370
4371 if (switch_channel_test_flag(channel, CF_VIDEO_ECHO)) {
4372 switch_core_session_write_video_frame(session, read_frame, SWITCH_IO_FLAG_NONE, 0);
4373 }
4374
4375 }
4376
4377
4378 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_media.c", (const char
*)__func__, 4378, ((void*)0)
, SWITCH_LOG_DEBUG, "%s Video thread ended\n", switch_channel_get_name(session->channel));
4379
4380 switch_mutex_unlock(mh->cond_mutex);
4381 switch_core_session_rwunlock(session);
4382
4383 mh->up = 0;
4384 return NULL((void*)0);
4385}
4386
4387
4388static switch_status_t start_video_thread(switch_core_session_t *session)
4389{
4390 switch_threadattr_t *thd_attr = NULL((void*)0);
4391 switch_memory_pool_t *pool = switch_core_session_get_pool(session);
4392 switch_rtp_engine_t *v_engine = NULL((void*)0);
4393 switch_media_handle_t *smh;
4394
4395 if (!(smh = session->media_handle)) {
4396 return SWITCH_STATUS_FALSE;
4397 }
4398
4399 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
4400
4401 if (v_engine->media_thread) {
4402 return SWITCH_STATUS_FALSE;
4403 }
4404
4405 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 4405, (const char*)(session)
, SWITCH_LOG_NOTICE, "%s Starting Video thread\n", switch_core_session_get_name(session)switch_channel_get_name(switch_core_session_get_channel(session
))
);
4406
4407 if (v_engine->rtp_session) {
4408 switch_rtp_set_default_payload(v_engine->rtp_session, v_engine->cur_payload_map->agreed_pt);
4409 }
4410
4411 v_engine->mh.session = session;
4412 switch_threadattr_create(&thd_attr, pool);
4413 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024);
4414
4415 switch_thread_cond_create(&v_engine->mh.cond, pool);
4416 switch_mutex_init(&v_engine->mh.cond_mutex, SWITCH_MUTEX_NESTED0x1, pool);
4417 switch_mutex_init(&v_engine->read_mutex[SWITCH_MEDIA_TYPE_VIDEO], SWITCH_MUTEX_NESTED0x1, pool);
4418 switch_thread_create(&v_engine->media_thread, thd_attr, video_helper_thread, &v_engine->mh, switch_core_session_get_pool(session));
4419
4420 return SWITCH_STATUS_SUCCESS;
4421}
4422
4423SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_media_start_video_thread(switch_core_session_t *session)
4424{
4425 return start_video_thread(session);
4426}
4427
4428//?
4429#define RA_PTR_LEN512 512
4430SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_media_proxy_remote_addr(switch_core_session_t *session, const char *sdp_str)
4431{
4432 const char *err;
4433 char rip[RA_PTR_LEN512] = "";
4434 char rp[RA_PTR_LEN512] = "";
4435 char rvp[RA_PTR_LEN512] = "";
4436 char *p, *ip_ptr = NULL((void*)0), *port_ptr = NULL((void*)0), *vid_port_ptr = NULL((void*)0), *pe;
4437 int x;
4438 const char *val;
4439 switch_status_t status = SWITCH_STATUS_FALSE;
4440 switch_rtp_engine_t *a_engine, *v_engine;
4441 switch_media_handle_t *smh;
4442
4443 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 4443, __PRETTY_FUNCTION__))
;
4444
4445 if (!(smh = session->media_handle)) {
4446 return SWITCH_STATUS_FALSE;
4447 }
4448
4449 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
4450 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
4451
4452 if (zstr(sdp_str)_zstr(sdp_str)) {
4453 sdp_str = smh->mparams->remote_sdp_str;
4454 }
4455
4456 if (zstr(sdp_str)_zstr(sdp_str)) {
4457 goto end;
4458 }
4459
4460 if ((p = (char *) switch_stristr("c=IN IP4 ", sdp_str)) || (p = (char *) switch_stristr("c=IN IP6 ", sdp_str))) {
4461 ip_ptr = p + 9;
4462 }
4463
4464 if ((p = (char *) switch_stristr("m=audio ", sdp_str))) {
4465 port_ptr = p + 8;
4466 }
4467
4468 if ((p = (char *) switch_stristr("m=image ", sdp_str))) {
4469 char *tmp = p + 8;
4470
4471 if (tmp && atoi(tmp)) {
4472 port_ptr = tmp;
4473 }
4474 }
4475
4476 if ((p = (char *) switch_stristr("m=video ", sdp_str))) {
4477 vid_port_ptr = p + 8;
4478 }
4479
4480 if (!(ip_ptr && port_ptr)) {
4481 goto end;
4482 }
4483
4484 p = ip_ptr;
4485 pe = p + strlen(p);
4486 x = 0;
4487 while (x < sizeof(rip) - 1 && p && *p && ((*p >= '0' && *p <= '9') || *p == '.' || *p == ':' || (*p >= 'a' && *p <= 'f') || (*p >= 'A' && *p <= 'F'))) {
4488 rip[x++] = *p;
4489 p++;
4490 if (p >= pe) {
4491 goto end;
4492 }
4493 }
4494
4495 p = port_ptr;
4496 x = 0;
4497 while (x < sizeof(rp) - 1 && p && *p && (*p >= '0' && *p <= '9')) {
4498 rp[x++] = *p;
4499 p++;
4500 if (p >= pe) {
4501 goto end;
4502 }
4503 }
4504
4505 p = vid_port_ptr;
4506 x = 0;
4507 while (x < sizeof(rvp) - 1 && p && *p && (*p >= '0' && *p <= '9')) {
4508 rvp[x++] = *p;
4509 p++;
4510 if (p >= pe) {
4511 goto end;
4512 }
4513 }
4514
4515 if (!(*rip && *rp)) {
4516 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 4516, (const char*)(session)
, SWITCH_LOG_ERROR, "invalid SDP\n");
4517 goto end;
4518 }
4519
4520 a_engine->cur_payload_map->remote_sdp_ip = switch_core_session_strdup(session, rip)switch_core_perform_session_strdup(session, rip, "src/switch_core_media.c"
, (const char *)__func__, 4520)
;
4521 a_engine->cur_payload_map->remote_sdp_port = (switch_port_t) atoi(rp);
4522
4523 if (*rvp) {
4524 v_engine->cur_payload_map->remote_sdp_ip = switch_core_session_strdup(session, rip)switch_core_perform_session_strdup(session, rip, "src/switch_core_media.c"
, (const char *)__func__, 4524)
;
4525 v_engine->cur_payload_map->remote_sdp_port = (switch_port_t) atoi(rvp);
4526 switch_channel_set_flag(session->channel, CF_VIDEO_POSSIBLE)switch_channel_set_flag_value(session->channel, CF_VIDEO_POSSIBLE
, 1)
;
4527 switch_channel_set_flag(session->channel, CF_VIDEO)switch_channel_set_flag_value(session->channel, CF_VIDEO, 1
)
;
4528 }
4529
4530 if (v_engine->cur_payload_map->remote_sdp_ip && v_engine->cur_payload_map->remote_sdp_port) {
4531 if (!strcmp(v_engine->cur_payload_map->remote_sdp_ip, rip)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(v_engine->cur_payload_map->remote_sdp_ip) && __builtin_constant_p
(rip) && (__s1_len = __builtin_strlen (v_engine->
cur_payload_map->remote_sdp_ip), __s2_len = __builtin_strlen
(rip), (!((size_t)(const void *)((v_engine->cur_payload_map
->remote_sdp_ip) + 1) - (size_t)(const void *)(v_engine->
cur_payload_map->remote_sdp_ip) == 1) || __s1_len >= 4)
&& (!((size_t)(const void *)((rip) + 1) - (size_t)(const
void *)(rip) == 1) || __s2_len >= 4)) ? __builtin_strcmp (
v_engine->cur_payload_map->remote_sdp_ip, rip) : (__builtin_constant_p
(v_engine->cur_payload_map->remote_sdp_ip) && (
(size_t)(const void *)((v_engine->cur_payload_map->remote_sdp_ip
) + 1) - (size_t)(const void *)(v_engine->cur_payload_map->
remote_sdp_ip) == 1) && (__s1_len = __builtin_strlen (
v_engine->cur_payload_map->remote_sdp_ip), __s1_len <
4) ? (__builtin_constant_p (rip) && ((size_t)(const void
*)((rip) + 1) - (size_t)(const void *)(rip) == 1) ? __builtin_strcmp
(v_engine->cur_payload_map->remote_sdp_ip, rip) : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (rip); int __result = (((const unsigned char *) (const
char *) (v_engine->cur_payload_map->remote_sdp_ip))[0]
- __s2[0]); if (__s1_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) (v_engine->cur_payload_map
->remote_sdp_ip))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (v_engine->cur_payload_map->remote_sdp_ip))[2]
- __s2[2]); if (__s1_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) (v_engine->cur_payload_map
->remote_sdp_ip))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(rip) && ((size_t)(const void *)((rip) + 1) - (size_t
)(const void *)(rip) == 1) && (__s2_len = __builtin_strlen
(rip), __s2_len < 4) ? (__builtin_constant_p (v_engine->
cur_payload_map->remote_sdp_ip) && ((size_t)(const
void *)((v_engine->cur_payload_map->remote_sdp_ip) + 1
) - (size_t)(const void *)(v_engine->cur_payload_map->remote_sdp_ip
) == 1) ? __builtin_strcmp (v_engine->cur_payload_map->
remote_sdp_ip, rip) : (- (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) (v_engine->
cur_payload_map->remote_sdp_ip); int __result = (((const unsigned
char *) (const char *) (rip))[0] - __s2[0]); if (__s2_len >
0 && __result == 0) { __result = (((const unsigned char
*) (const char *) (rip))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (rip))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (rip))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(v_engine->cur_payload_map->remote_sdp_ip, rip)))); })
&& atoi(rvp) == v_engine->cur_payload_map->remote_sdp_port) {
4532 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 4532, (const char*)(session)
, SWITCH_LOG_DEBUG, "Remote video address:port [%s:%d] has not changed.\n",
4533 v_engine->cur_payload_map->remote_sdp_ip, v_engine->cur_payload_map->remote_sdp_port);
4534 } else {
4535 switch_channel_set_flag(session->channel, CF_VIDEO_POSSIBLE)switch_channel_set_flag_value(session->channel, CF_VIDEO_POSSIBLE
, 1)
;
4536 switch_channel_set_flag(session->channel, CF_VIDEO)switch_channel_set_flag_value(session->channel, CF_VIDEO, 1
)
;
4537 if (switch_rtp_ready(v_engine->rtp_session)) {
4538 const char *rport = NULL((void*)0);
4539 switch_port_t remote_rtcp_port = v_engine->remote_rtcp_port;
4540
4541 if (!remote_rtcp_port) {
4542 if ((rport = switch_channel_get_variable(session->channel, "rtp_remote_video_rtcp_port")switch_channel_get_variable_dup(session->channel, "rtp_remote_video_rtcp_port"
, SWITCH_TRUE, -1)
)) {
4543 remote_rtcp_port = (switch_port_t)atoi(rport);
4544 }
4545 }
4546
4547
4548 if (switch_rtp_set_remote_address(v_engine->rtp_session, v_engine->cur_payload_map->remote_sdp_ip,
4549 v_engine->cur_payload_map->remote_sdp_port, remote_rtcp_port, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
4550 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 4550, (const char*)(session)
, SWITCH_LOG_ERROR, "VIDEO RTP REPORTS ERROR: [%s]\n", err);
4551 } else {
4552 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 4552, (const char*)(session)
, SWITCH_LOG_DEBUG, "VIDEO RTP CHANGING DEST TO: [%s:%d]\n",
4553 v_engine->cur_payload_map->remote_sdp_ip, v_engine->cur_payload_map->remote_sdp_port);
4554 if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) && !switch_channel_test_flag(session->channel, CF_PROXY_MODE) &&
4555 !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")switch_channel_get_variable_dup(session->channel, "disable_rtp_auto_adjust"
, SWITCH_TRUE, -1)
) && switch_true(val)) &&
4556 !switch_channel_test_flag(session->channel, CF_WEBRTC)) {
4557 /* Reactivate the NAT buster flag. */
4558 switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_AUTOADJ);
4559 start_video_thread(session);
4560
4561 }
4562 if (switch_media_handle_test_media_flag(smh, SCMF_AUTOFIX_TIMING)) {
4563 v_engine->check_frames = 0;
4564 }
4565 }
4566 }
4567 }
4568 }
4569
4570 if (switch_rtp_ready(a_engine->rtp_session)) {
4571 char *remote_host = switch_rtp_get_remote_host(a_engine->rtp_session);
4572 switch_port_t remote_port = switch_rtp_get_remote_port(a_engine->rtp_session);
4573 const char *rport = NULL((void*)0);
4574 switch_port_t remote_rtcp_port = 0;
4575
4576 if (remote_host && remote_port && !strcmp(remote_host, a_engine->cur_payload_map->remote_sdp_ip)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(remote_host) && __builtin_constant_p (a_engine->
cur_payload_map->remote_sdp_ip) && (__s1_len = __builtin_strlen
(remote_host), __s2_len = __builtin_strlen (a_engine->cur_payload_map
->remote_sdp_ip), (!((size_t)(const void *)((remote_host) +
1) - (size_t)(const void *)(remote_host) == 1) || __s1_len >=
4) && (!((size_t)(const void *)((a_engine->cur_payload_map
->remote_sdp_ip) + 1) - (size_t)(const void *)(a_engine->
cur_payload_map->remote_sdp_ip) == 1) || __s2_len >= 4)
) ? __builtin_strcmp (remote_host, a_engine->cur_payload_map
->remote_sdp_ip) : (__builtin_constant_p (remote_host) &&
((size_t)(const void *)((remote_host) + 1) - (size_t)(const void
*)(remote_host) == 1) && (__s1_len = __builtin_strlen
(remote_host), __s1_len < 4) ? (__builtin_constant_p (a_engine
->cur_payload_map->remote_sdp_ip) && ((size_t)(
const void *)((a_engine->cur_payload_map->remote_sdp_ip
) + 1) - (size_t)(const void *)(a_engine->cur_payload_map->
remote_sdp_ip) == 1) ? __builtin_strcmp (remote_host, a_engine
->cur_payload_map->remote_sdp_ip) : (__extension__ ({ const
unsigned char *__s2 = (const unsigned char *) (const char *)
(a_engine->cur_payload_map->remote_sdp_ip); int __result
= (((const unsigned char *) (const char *) (remote_host))[0]
- __s2[0]); if (__s1_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) (remote_host))[1]
- __s2[1]); if (__s1_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) (remote_host))[2]
- __s2[2]); if (__s1_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) (remote_host))[3]
- __s2[3]); } } __result; }))) : (__builtin_constant_p (a_engine
->cur_payload_map->remote_sdp_ip) && ((size_t)(
const void *)((a_engine->cur_payload_map->remote_sdp_ip
) + 1) - (size_t)(const void *)(a_engine->cur_payload_map->
remote_sdp_ip) == 1) && (__s2_len = __builtin_strlen (
a_engine->cur_payload_map->remote_sdp_ip), __s2_len <
4) ? (__builtin_constant_p (remote_host) && ((size_t
)(const void *)((remote_host) + 1) - (size_t)(const void *)(remote_host
) == 1) ? __builtin_strcmp (remote_host, a_engine->cur_payload_map
->remote_sdp_ip) : (- (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) (remote_host)
; int __result = (((const unsigned char *) (const char *) (a_engine
->cur_payload_map->remote_sdp_ip))[0] - __s2[0]); if (__s2_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (a_engine->cur_payload_map->remote_sdp_ip
))[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (a_engine
->cur_payload_map->remote_sdp_ip))[2] - __s2[2]); if (__s2_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) (a_engine->cur_payload_map->remote_sdp_ip
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (remote_host
, a_engine->cur_payload_map->remote_sdp_ip)))); })
&& remote_port == a_engine->cur_payload_map->remote_sdp_port) {
4577 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 4577, (const char*)(session)
, SWITCH_LOG_DEBUG, "Remote address:port [%s:%d] has not changed.\n",
4578 a_engine->cur_payload_map->remote_sdp_ip, a_engine->cur_payload_map->remote_sdp_port);
4579 switch_goto_status(SWITCH_STATUS_BREAK, end)status = SWITCH_STATUS_BREAK; goto end;
4580 } else if (remote_host && ( (strcmp(remote_host, "0.0.0.0")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(remote_host) && __builtin_constant_p ("0.0.0.0") &&
(__s1_len = __builtin_strlen (remote_host), __s2_len = __builtin_strlen
("0.0.0.0"), (!((size_t)(const void *)((remote_host) + 1) - (
size_t)(const void *)(remote_host) == 1) || __s1_len >= 4)
&& (!((size_t)(const void *)(("0.0.0.0") + 1) - (size_t
)(const void *)("0.0.0.0") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(remote_host, "0.0.0.0") : (__builtin_constant_p (remote_host
) && ((size_t)(const void *)((remote_host) + 1) - (size_t
)(const void *)(remote_host) == 1) && (__s1_len = __builtin_strlen
(remote_host), __s1_len < 4) ? (__builtin_constant_p ("0.0.0.0"
) && ((size_t)(const void *)(("0.0.0.0") + 1) - (size_t
)(const void *)("0.0.0.0") == 1) ? __builtin_strcmp (remote_host
, "0.0.0.0") : (__extension__ ({ const unsigned char *__s2 = (
const unsigned char *) (const char *) ("0.0.0.0"); int __result
= (((const unsigned char *) (const char *) (remote_host))[0]
- __s2[0]); if (__s1_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) (remote_host))[1]
- __s2[1]); if (__s1_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) (remote_host))[2]
- __s2[2]); if (__s1_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) (remote_host))[3]
- __s2[3]); } } __result; }))) : (__builtin_constant_p ("0.0.0.0"
) && ((size_t)(const void *)(("0.0.0.0") + 1) - (size_t
)(const void *)("0.0.0.0") == 1) && (__s2_len = __builtin_strlen
("0.0.0.0"), __s2_len < 4) ? (__builtin_constant_p (remote_host
) && ((size_t)(const void *)((remote_host) + 1) - (size_t
)(const void *)(remote_host) == 1) ? __builtin_strcmp (remote_host
, "0.0.0.0") : (- (__extension__ ({ const unsigned char *__s2
= (const unsigned char *) (const char *) (remote_host); int __result
= (((const unsigned char *) (const char *) ("0.0.0.0"))[0] -
__s2[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("0.0.0.0"))[1] -
__s2[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("0.0.0.0"))[2] -
__s2[2]); if (__s2_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) ("0.0.0.0"))[3] -
__s2[3]); } } __result; })))) : __builtin_strcmp (remote_host
, "0.0.0.0")))); })
== 0) ||
4581 (strcmp(a_engine->cur_payload_map->remote_sdp_ip, "0.0.0.0")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(a_engine->cur_payload_map->remote_sdp_ip) && __builtin_constant_p
("0.0.0.0") && (__s1_len = __builtin_strlen (a_engine
->cur_payload_map->remote_sdp_ip), __s2_len = __builtin_strlen
("0.0.0.0"), (!((size_t)(const void *)((a_engine->cur_payload_map
->remote_sdp_ip) + 1) - (size_t)(const void *)(a_engine->
cur_payload_map->remote_sdp_ip) == 1) || __s1_len >= 4)
&& (!((size_t)(const void *)(("0.0.0.0") + 1) - (size_t
)(const void *)("0.0.0.0") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(a_engine->cur_payload_map->remote_sdp_ip, "0.0.0.0") :
(__builtin_constant_p (a_engine->cur_payload_map->remote_sdp_ip
) && ((size_t)(const void *)((a_engine->cur_payload_map
->remote_sdp_ip) + 1) - (size_t)(const void *)(a_engine->
cur_payload_map->remote_sdp_ip) == 1) && (__s1_len
= __builtin_strlen (a_engine->cur_payload_map->remote_sdp_ip
), __s1_len < 4) ? (__builtin_constant_p ("0.0.0.0") &&
((size_t)(const void *)(("0.0.0.0") + 1) - (size_t)(const void
*)("0.0.0.0") == 1) ? __builtin_strcmp (a_engine->cur_payload_map
->remote_sdp_ip, "0.0.0.0") : (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) ("0.0.0.0"
); int __result = (((const unsigned char *) (const char *) (a_engine
->cur_payload_map->remote_sdp_ip))[0] - __s2[0]); if (__s1_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (a_engine->cur_payload_map->remote_sdp_ip
))[1] - __s2[1]); if (__s1_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (a_engine
->cur_payload_map->remote_sdp_ip))[2] - __s2[2]); if (__s1_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) (a_engine->cur_payload_map->remote_sdp_ip
))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (
"0.0.0.0") && ((size_t)(const void *)(("0.0.0.0") + 1
) - (size_t)(const void *)("0.0.0.0") == 1) && (__s2_len
= __builtin_strlen ("0.0.0.0"), __s2_len < 4) ? (__builtin_constant_p
(a_engine->cur_payload_map->remote_sdp_ip) && (
(size_t)(const void *)((a_engine->cur_payload_map->remote_sdp_ip
) + 1) - (size_t)(const void *)(a_engine->cur_payload_map->
remote_sdp_ip) == 1) ? __builtin_strcmp (a_engine->cur_payload_map
->remote_sdp_ip, "0.0.0.0") : (- (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (a_engine
->cur_payload_map->remote_sdp_ip); int __result = (((const
unsigned char *) (const char *) ("0.0.0.0"))[0] - __s2[0]); if
(__s2_len > 0 && __result == 0) { __result = (((const
unsigned char *) (const char *) ("0.0.0.0"))[1] - __s2[1]); if
(__s2_len > 1 && __result == 0) { __result = (((const
unsigned char *) (const char *) ("0.0.0.0"))[2] - __s2[2]); if
(__s2_len > 2 && __result == 0) __result = (((const
unsigned char *) (const char *) ("0.0.0.0"))[3] - __s2[3]); }
} __result; })))) : __builtin_strcmp (a_engine->cur_payload_map
->remote_sdp_ip, "0.0.0.0")))); })
== 0))) {
4582
4583 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 4583, (const char*)(session)
, SWITCH_LOG_DEBUG,
4584 "Remote address changed from [%s] to [%s]. Ignoring...\n",
4585 a_engine->cur_payload_map->remote_sdp_ip, remote_host);
4586 switch_goto_status(SWITCH_STATUS_BREAK, end)status = SWITCH_STATUS_BREAK; goto end;
4587 }
4588
4589 if ((rport = switch_channel_get_variable(session->channel, "rtp_remote_audio_rtcp_port")switch_channel_get_variable_dup(session->channel, "rtp_remote_audio_rtcp_port"
, SWITCH_TRUE, -1)
)) {
4590 remote_rtcp_port = (switch_port_t)atoi(rport);
4591 }
4592
4593
4594 if (switch_rtp_set_remote_address(a_engine->rtp_session, a_engine->cur_payload_map->remote_sdp_ip,
4595 a_engine->cur_payload_map->remote_sdp_port, remote_rtcp_port, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
4596 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 4596, (const char*)(session)
, SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", err);
4597 status = SWITCH_STATUS_GENERR;
4598 } else {
4599 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 4599, (const char*)(session)
, SWITCH_LOG_DEBUG, "AUDIO RTP CHANGING DEST TO: [%s:%d]\n",
4600 a_engine->cur_payload_map->remote_sdp_ip, a_engine->cur_payload_map->remote_sdp_port);
4601 if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) &&
4602 !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")switch_channel_get_variable_dup(session->channel, "disable_rtp_auto_adjust"
, SWITCH_TRUE, -1)
) && switch_true(val)) &&
4603 !switch_channel_test_flag(session->channel, CF_WEBRTC)) {
4604 /* Reactivate the NAT buster flag. */
4605 switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_AUTOADJ);
4606 }
4607 if (switch_media_handle_test_media_flag(smh, SCMF_AUTOFIX_TIMING)) {
4608 a_engine->check_frames = 0;
4609 }
4610 status = SWITCH_STATUS_SUCCESS;
4611 }
4612 }
4613
4614 end:
4615
4616 return status;
4617}
4618
4619//?
4620SWITCH_DECLARE(int)__attribute__((visibility("default"))) int switch_core_media_check_nat(switch_media_handle_t *smh, const char *network_ip)
4621{
4622 switch_assert(network_ip)((network_ip) ? (void) (0) : __assert_fail ("network_ip", "src/switch_core_media.c"
, 4622, __PRETTY_FUNCTION__))
;
4623
4624 return (smh->mparams->extsipip &&
4625 !switch_check_network_list_ip(network_ip, "loopback.auto")switch_check_network_list_ip_token(network_ip, "loopback.auto"
, ((void*)0))
&&
4626 !switch_check_network_list_ip(network_ip, smh->mparams->local_network)switch_check_network_list_ip_token(network_ip, smh->mparams
->local_network, ((void*)0))
);
4627}
4628
4629//?
4630SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_media_ext_address_lookup(switch_core_session_t *session, char **ip, switch_port_t *port, const char *sourceip)
4631
4632{
4633 char *error = "";
4634 switch_status_t status = SWITCH_STATUS_FALSE;
4635 int x;
4636 switch_port_t myport = *port;
4637 switch_port_t stun_port = SWITCH_STUN_DEFAULT_PORT3478;
4638 char *stun_ip = NULL((void*)0);
4639 switch_media_handle_t *smh;
4640 switch_memory_pool_t *pool = switch_core_session_get_pool(session);
4641
4642 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 4642, __PRETTY_FUNCTION__))
;
4643
4644 if (!(smh = session->media_handle)) {
4645 return SWITCH_STATUS_FALSE;
4646 }
4647
4648 if (!sourceip) {
4649 return status;
4650 }
4651
4652 if (!strncasecmp(sourceip, "host:", 5)) {
4653 status = (*ip = switch_stun_host_lookup(sourceip + 5, pool)) ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
4654 } else if (!strncasecmp(sourceip, "stun:", 5)) {
4655 char *p;
4656
4657 stun_ip = strdup(sourceip + 5)(__extension__ (__builtin_constant_p (sourceip + 5) &&
((size_t)(const void *)((sourceip + 5) + 1) - (size_t)(const
void *)(sourceip + 5) == 1) ? (((const char *) (sourceip + 5
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen (sourceip + 5) + 1; char *__retval = (
char *) malloc (__len); if (__retval != ((void*)0)) __retval =
(char *) memcpy (__retval, sourceip + 5, __len); __retval; }
)) : __strdup (sourceip + 5)))
;
4658
4659 if ((p = strchr(stun_ip, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(stun_ip) && (':') == '\0' ? (char *) __rawmemchr (stun_ip
, ':') : __builtin_strchr (stun_ip, ':')))
)) {
4660 int iport;
4661 *p++ = '\0';
4662 iport = atoi(p);
4663 if (iport > 0 && iport < 0xFFFF) {
4664 stun_port = (switch_port_t) iport;
4665 }
4666 }
4667
4668 if (zstr(stun_ip)_zstr(stun_ip)) {
4669 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_media.c", (const char
*)__func__, 4669, ((void*)0)
, SWITCH_LOG_ERROR, "STUN Failed! NO STUN SERVER\n");
4670 goto out;
4671 }
4672
4673 for (x = 0; x < 5; x++) {
4674 if ((status = switch_stun_lookup(ip, port, stun_ip, stun_port, &error, pool)) != SWITCH_STATUS_SUCCESS) {
4675 switch_yield(100000)switch_sleep(100000);;
4676 } else {
4677 break;
4678 }
4679 }
4680 if (status != SWITCH_STATUS_SUCCESS) {
4681 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_media.c", (const char
*)__func__, 4681, ((void*)0)
, SWITCH_LOG_ERROR, "STUN Failed! %s:%d [%s]\n", stun_ip, stun_port, error);
4682 goto out;
4683 }
4684 if (!*ip) {
4685 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_media.c", (const char
*)__func__, 4685, ((void*)0)
, SWITCH_LOG_ERROR, "STUN Failed! No IP returned\n");
4686 goto out;
4687 }
4688 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_media.c", (const char
*)__func__, 4688, ((void*)0)
, SWITCH_LOG_DEBUG, "STUN Success [%s]:[%d]\n", *ip, *port);
4689 status = SWITCH_STATUS_SUCCESS;
4690
4691 if (myport == *port && !strcmp(*ip, smh->mparams->rtpip)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(*ip) && __builtin_constant_p (smh->mparams->rtpip
) && (__s1_len = __builtin_strlen (*ip), __s2_len = __builtin_strlen
(smh->mparams->rtpip), (!((size_t)(const void *)((*ip)
+ 1) - (size_t)(const void *)(*ip) == 1) || __s1_len >= 4
) && (!((size_t)(const void *)((smh->mparams->rtpip
) + 1) - (size_t)(const void *)(smh->mparams->rtpip) ==
1) || __s2_len >= 4)) ? __builtin_strcmp (*ip, smh->mparams
->rtpip) : (__builtin_constant_p (*ip) && ((size_t
)(const void *)((*ip) + 1) - (size_t)(const void *)(*ip) == 1
) && (__s1_len = __builtin_strlen (*ip), __s1_len <
4) ? (__builtin_constant_p (smh->mparams->rtpip) &&
((size_t)(const void *)((smh->mparams->rtpip) + 1) - (
size_t)(const void *)(smh->mparams->rtpip) == 1) ? __builtin_strcmp
(*ip, smh->mparams->rtpip) : (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (smh->
mparams->rtpip); int __result = (((const unsigned char *) (
const char *) (*ip))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (*ip))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (*ip))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (*ip))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(smh->mparams->rtpip) && ((size_t)(const void *
)((smh->mparams->rtpip) + 1) - (size_t)(const void *)(smh
->mparams->rtpip) == 1) && (__s2_len = __builtin_strlen
(smh->mparams->rtpip), __s2_len < 4) ? (__builtin_constant_p
(*ip) && ((size_t)(const void *)((*ip) + 1) - (size_t
)(const void *)(*ip) == 1) ? __builtin_strcmp (*ip, smh->mparams
->rtpip) : (- (__extension__ ({ const unsigned char *__s2 =
(const unsigned char *) (const char *) (*ip); int __result =
(((const unsigned char *) (const char *) (smh->mparams->
rtpip))[0] - __s2[0]); if (__s2_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
smh->mparams->rtpip))[1] - __s2[1]); if (__s2_len > 1
&& __result == 0) { __result = (((const unsigned char
*) (const char *) (smh->mparams->rtpip))[2] - __s2[2])
; if (__s2_len > 2 && __result == 0) __result = ((
(const unsigned char *) (const char *) (smh->mparams->rtpip
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (*ip
, smh->mparams->rtpip)))); })
) {
4692 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_media.c", (const char
*)__func__, 4692, ((void*)0)
, SWITCH_LOG_DEBUG, "STUN Not Required ip and port match. [%s]:[%d]\n", *ip, *port);
4693 } else {
4694 smh->mparams->stun_ip = switch_core_session_strdup(session, stun_ip)switch_core_perform_session_strdup(session, stun_ip, "src/switch_core_media.c"
, (const char *)__func__, 4694)
;
4695 smh->mparams->stun_port = stun_port;
4696 smh->mparams->stun_flags |= STUN_FLAG_SET;
4697 }
4698 } else {
4699 *ip = (char *) sourceip;
4700 status = SWITCH_STATUS_SUCCESS;
4701 }
4702
4703 out:
4704
4705 switch_safe_free(stun_ip)if (stun_ip) {free(stun_ip);stun_ip=((void*)0);};
4706
4707 return status;
4708}
4709
4710//?
4711SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_reset_autofix(switch_core_session_t *session, switch_media_type_t type)
4712{
4713 switch_rtp_engine_t *engine;
4714 switch_media_handle_t *smh;
4715
4716 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 4716, __PRETTY_FUNCTION__))
;
4717
4718 if (!(smh = session->media_handle)) {
4719 return;
4720 }
4721
4722 engine = &smh->engines[type];
4723
4724 engine->check_frames = 0;
4725 engine->last_ts = 0;
4726 engine->last_seq = 0;
4727}
4728
4729
4730
4731//?
4732SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_media_choose_port(switch_core_session_t *session, switch_media_type_t type, int force)
4733{
4734 char *lookup_rtpip; /* Pointer to externally looked up address */
4735 switch_port_t sdp_port; /* The external port to be sent in the SDP */
4736 const char *use_ip = NULL((void*)0); /* The external IP to be sent in the SDP */
4737 switch_rtp_engine_t *engine;
4738 switch_media_handle_t *smh;
4739 const char *tstr = switch_media_type2str(type);
4740 char vname[128] = "";
4741
4742 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 4742, __PRETTY_FUNCTION__))
;
4743
4744 if (!(smh = session->media_handle)) {
4745 return SWITCH_STATUS_FALSE;
4746 }
4747
4748 engine = &smh->engines[type];
4749
4750 lookup_rtpip = smh->mparams->rtpip;
4751
4752 /* Don't do anything if we're in proxy mode or if a (remote) port already has been found */
4753 if (!force) {
4754 if (switch_channel_test_flag(session->channel, CF_PROXY_MODE) ||
4755 switch_channel_test_flag(session->channel, CF_PROXY_MEDIA) || engine->adv_sdp_port) {
4756 return SWITCH_STATUS_SUCCESS;
4757 }
4758 }
4759
4760 /* Release the local sdp port */
4761 if (engine->local_sdp_port) {
4762 switch_rtp_release_port(smh->mparams->rtpip, engine->local_sdp_port);
4763 }
4764
4765 /* Request a local port from the core's allocator */
4766 if (!(engine->local_sdp_port = switch_rtp_request_port(smh->mparams->rtpip))) {
4767 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 4767, (const char*)(session)
, SWITCH_LOG_CRIT, "No %s RTP ports available!\n", tstr);
4768 return SWITCH_STATUS_FALSE;
4769 }
4770
4771 engine->local_sdp_ip = smh->mparams->rtpip;
4772
4773
4774 sdp_port = engine->local_sdp_port;
4775
4776 /* Check if NAT is detected */
4777 if (!zstr(smh->mparams->remote_ip)_zstr(smh->mparams->remote_ip) && switch_core_media_check_nat(smh, smh->mparams->remote_ip)) {
4778 /* Yes, map the port through switch_nat */
4779 switch_nat_add_mapping(engine->local_sdp_port, SWITCH_NAT_UDP, &sdp_port, SWITCH_FALSE);
4780
4781 switch_snprintf(vname, sizeof(vname), "rtp_adv_%s_ip", tstr);
4782
4783 /* Find an IP address to use */
4784 if (!(use_ip = switch_channel_get_variable(session->channel, vname)switch_channel_get_variable_dup(session->channel, vname, SWITCH_TRUE
, -1)
)
4785 && !zstr(smh->mparams->extrtpip)_zstr(smh->mparams->extrtpip)) {
4786 use_ip = smh->mparams->extrtpip;
4787 }
4788
4789 if (use_ip) {
4790 if (switch_core_media_ext_address_lookup(session, &lookup_rtpip, &sdp_port, use_ip) != SWITCH_STATUS_SUCCESS) {
4791 /* Address lookup was required and fail (external ip was "host:..." or "stun:...") */
4792 return SWITCH_STATUS_FALSE;
4793 } else {
4794 /* Address properly resolved, use it as external ip */
4795 use_ip = lookup_rtpip;
4796 }
4797 } else {
4798 /* No external ip found, use the profile's rtp ip */
4799 use_ip = smh->mparams->rtpip;
4800 }
4801 } else {
4802 /* No NAT traversal required, use the profile's rtp ip */
4803 use_ip = smh->mparams->rtpip;
4804 }
4805
4806 engine->adv_sdp_port = sdp_port;
4807 engine->adv_sdp_ip = smh->mparams->adv_sdp_audio_ip = smh->mparams->extrtpip = switch_core_session_strdup(session, use_ip)switch_core_perform_session_strdup(session, use_ip, "src/switch_core_media.c"
, (const char *)__func__, 4807)
;
4808
4809
4810 if (type == SWITCH_MEDIA_TYPE_AUDIO) {
4811 switch_channel_set_variable(session->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE, engine->local_sdp_ip)switch_channel_set_variable_var_check(session->channel, "local_media_ip"
, engine->local_sdp_ip, SWITCH_TRUE)
;
4812 switch_channel_set_variable_printf(session->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE"local_media_port", "%d", sdp_port);
4813 switch_channel_set_variable(session->channel, SWITCH_ADVERTISED_MEDIA_IP_VARIABLE, engine->adv_sdp_ip)switch_channel_set_variable_var_check(session->channel, "advertised_media_ip"
, engine->adv_sdp_ip, SWITCH_TRUE)
;
4814 } else {
4815 switch_channel_set_variable(session->channel, SWITCH_LOCAL_VIDEO_IP_VARIABLE, engine->adv_sdp_ip)switch_channel_set_variable_var_check(session->channel, "local_video_ip"
, engine->adv_sdp_ip, SWITCH_TRUE)
;
4816 switch_channel_set_variable_printf(session->channel, SWITCH_LOCAL_VIDEO_PORT_VARIABLE"local_video_port", "%d", sdp_port);
4817 }
4818
4819 return SWITCH_STATUS_SUCCESS;
4820}
4821
4822SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_media_choose_ports(switch_core_session_t *session, switch_bool_t audio, switch_bool_t video)
4823{
4824 switch_status_t status = SWITCH_STATUS_SUCCESS;
4825
4826 if (audio && (status = switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_AUDIO, 0)) == SWITCH_STATUS_SUCCESS) {
4827 if (video) {
4828 switch_core_media_check_video_codecs(session);
4829 if (switch_channel_test_flag(session->channel, CF_VIDEO_POSSIBLE)) {
4830 switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_VIDEO, 0);
4831 }
4832 }
4833 }
4834
4835 return status;
4836}
4837
4838
4839
4840//?
4841SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_deactivate_rtp(switch_core_session_t *session)
4842{
4843 switch_rtp_engine_t *a_engine, *v_engine;
4844 switch_media_handle_t *smh;
4845
4846 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 4846, __PRETTY_FUNCTION__))
;
4847
4848 if (!(smh = session->media_handle)) {
4849 return;
4850 }
4851
4852 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
4853 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
4854
4855 if (v_engine->media_thread) {
4856 switch_status_t st;
4857 switch_channel_clear_flag(session->channel, CF_VIDEO_PASSIVE);
4858
4859 v_engine->mh.up = 0;
4860 switch_thread_join(&st, v_engine->media_thread);
4861 v_engine->media_thread = NULL((void*)0);
4862 }
4863
4864 if (v_engine->rtp_session) {
4865 switch_rtp_destroy(&v_engine->rtp_session);
4866 } else if (v_engine->local_sdp_port) {
4867 switch_rtp_release_port(smh->mparams->rtpip, v_engine->local_sdp_port);
4868 }
4869
4870
4871 if (v_engine->local_sdp_port > 0 && !zstr(smh->mparams->remote_ip)_zstr(smh->mparams->remote_ip) &&
4872 switch_core_media_check_nat(smh, smh->mparams->remote_ip)) {
4873 switch_nat_del_mapping((switch_port_t) v_engine->local_sdp_port, SWITCH_NAT_UDP);
4874 switch_nat_del_mapping((switch_port_t) v_engine->local_sdp_port + 1, SWITCH_NAT_UDP);
4875 }
4876
4877
4878 if (a_engine->rtp_session) {
4879 switch_rtp_destroy(&a_engine->rtp_session);
4880 } else if (a_engine->local_sdp_port) {
4881 switch_rtp_release_port(smh->mparams->rtpip, a_engine->local_sdp_port);
4882 }
4883
4884 if (a_engine->local_sdp_port > 0 && !zstr(smh->mparams->remote_ip)_zstr(smh->mparams->remote_ip) &&
4885 switch_core_media_check_nat(smh, smh->mparams->remote_ip)) {
4886 switch_nat_del_mapping((switch_port_t) a_engine->local_sdp_port, SWITCH_NAT_UDP);
4887 switch_nat_del_mapping((switch_port_t) a_engine->local_sdp_port + 1, SWITCH_NAT_UDP);
4888 }
4889
4890}
4891
4892
4893//?
4894static void gen_ice(switch_core_session_t *session, switch_media_type_t type, const char *ip, switch_port_t port)
4895{
4896 switch_media_handle_t *smh;
4897 switch_rtp_engine_t *engine;
4898 char tmp[33] = "";
4899
4900 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 4900, __PRETTY_FUNCTION__))
;
4901
4902 if (!(smh = session->media_handle)) {
4903 return;
4904 }
4905
4906 engine = &smh->engines[type];
4907
4908#ifdef RTCP_MUX
4909 if (!engine->rtcp_mux) {// && type == SWITCH_MEDIA_TYPE_AUDIO) {
4910 engine->rtcp_mux = SWITCH_TRUE;
4911 }
4912#endif
4913
4914 if (!smh->msid) {
4915 switch_stun_random_string(tmp, 32, NULL((void*)0));
4916 tmp[32] = '\0';
4917 smh->msid = switch_core_session_strdup(session, tmp)switch_core_perform_session_strdup(session, tmp, "src/switch_core_media.c"
, (const char *)__func__, 4917)
;
4918 }
4919
4920 if (!smh->cname) {
4921 switch_stun_random_string(tmp, 16, NULL((void*)0));
4922 tmp[16] = '\0';
4923 smh->cname = switch_core_session_strdup(session, tmp)switch_core_perform_session_strdup(session, tmp, "src/switch_core_media.c"
, (const char *)__func__, 4923)
;
4924 }
4925
4926 if (!engine->ice_out.ufrag) {
4927 switch_stun_random_string(tmp, 16, NULL((void*)0));
4928 tmp[16] = '\0';
4929 engine->ice_out.ufrag = switch_core_session_strdup(session, tmp)switch_core_perform_session_strdup(session, tmp, "src/switch_core_media.c"
, (const char *)__func__, 4929)
;
4930 }
4931
4932 if (!engine->ice_out.pwd) {
4933 switch_stun_random_string(tmp, 24, NULL((void*)0));
4934 tmp[24] = '\0';
4935 engine->ice_out.pwd = switch_core_session_strdup(session, tmp)switch_core_perform_session_strdup(session, tmp, "src/switch_core_media.c"
, (const char *)__func__, 4935)
;
4936 }
4937
4938 if (!engine->ice_out.cands[0][0].foundation) {
4939 switch_stun_random_string(tmp, 10, "0123456789");
4940 tmp[10] = '\0';
4941 engine->ice_out.cands[0][0].foundation = switch_core_session_strdup(session, tmp)switch_core_perform_session_strdup(session, tmp, "src/switch_core_media.c"
, (const char *)__func__, 4941)
;
4942 }
4943
4944 engine->ice_out.cands[0][0].transport = "udp";
4945
4946 if (!engine->ice_out.cands[0][0].component_id) {
4947 engine->ice_out.cands[0][0].component_id = 1;
4948 engine->ice_out.cands[0][0].priority = (2^24)*126 + (2^8)*65535 + (2^0)*(256 - engine->ice_out.cands[0][0].component_id);
4949 }
4950
4951 if (!zstr(ip)_zstr(ip)) {
4952 engine->ice_out.cands[0][0].con_addr = switch_core_session_strdup(session, ip)switch_core_perform_session_strdup(session, ip, "src/switch_core_media.c"
, (const char *)__func__, 4952)
;
4953 }
4954
4955 if (port) {
4956 engine->ice_out.cands[0][0].con_port = port;
4957 }
4958
4959 engine->ice_out.cands[0][0].generation = "0";
4960 //add rport stuff later
4961
4962 engine->ice_out.cands[0][0].ready = 1;
4963
4964
4965}
4966
4967SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_session_wake_video_thread(switch_core_session_t *session)
4968{
4969 switch_media_handle_t *smh;
4970 switch_rtp_engine_t *v_engine;
4971
4972 if (!(smh = session->media_handle)) {
4973 return;
4974 }
4975
4976 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
4977
4978 if ((!smh->mparams->external_video_source) && (!v_engine->rtp_session)) {
4979 return;
4980 }
4981
4982 if (!v_engine->mh.cond_mutex) {
4983 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 4983, (const char*)(session)
, SWITCH_LOG_WARNING, "Channel %s has no cond?\n",
4984 switch_channel_get_name(session->channel));
4985 return;
4986 }
4987
4988 if (switch_mutex_trylock(v_engine->mh.cond_mutex) == SWITCH_STATUS_SUCCESS) {
4989 switch_thread_cond_broadcast(v_engine->mh.cond);
4990 switch_mutex_unlock(v_engine->mh.cond_mutex);
4991 }
4992}
4993
4994static void check_dtls_reinvite(switch_core_session_t *session, switch_rtp_engine_t *engine)
4995{
4996 if (switch_channel_test_flag(session->channel, CF_REINVITE)) {
4997
4998 if (!zstr(engine->local_dtls_fingerprint.str)_zstr(engine->local_dtls_fingerprint.str) && switch_rtp_has_dtls() && dtls_ok(session)) {
4999 dtls_type_t xtype, dtype = switch_ice_direction(session) == SWITCH_CALL_DIRECTION_INBOUND ? DTLS_TYPE_CLIENT : DTLS_TYPE_SERVER;
5000 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5000, (const char*)(session)
, SWITCH_LOG_INFO, "RE-SETTING %s DTLS\n", type2str(engine->type)engine->type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio");
5001
5002 xtype = DTLS_TYPE_RTP;
5003 if (engine->rtcp_mux > 0) xtype |= DTLS_TYPE_RTCP;
5004
5005 switch_rtp_add_dtls(engine->rtp_session, &engine->local_dtls_fingerprint, &engine->remote_dtls_fingerprint, dtype | xtype);
5006
5007 if (engine->rtcp_mux < 1) {
5008 xtype = DTLS_TYPE_RTCP;
5009 switch_rtp_add_dtls(engine->rtp_session, &engine->local_dtls_fingerprint, &engine->remote_dtls_fingerprint, dtype | xtype);
5010 }
5011
5012 }
5013 }
5014}
5015
5016//?
5017SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_media_activate_rtp(switch_core_session_t *session)
5018
5019{
5020 const char *err = NULL((void*)0);
5021 const char *val = NULL((void*)0);
5022 switch_rtp_flag_t flags[SWITCH_RTP_FLAG_INVALID] = {0};
5023 switch_status_t status = SWITCH_STATUS_SUCCESS;
5024 char tmp[50];
5025 char *timer_name = NULL((void*)0);
5026 const char *var;
5027 switch_rtp_engine_t *a_engine, *v_engine;
5028 switch_media_handle_t *smh;
5029
5030 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 5030, __PRETTY_FUNCTION__))
;
5031
5032 if (!(smh = session->media_handle)) {
5033 return SWITCH_STATUS_FALSE;
5034 }
5035
5036 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
5037 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
5038
5039
5040 if (switch_channel_down(session->channel)(switch_channel_check_signal(session->channel, SWITCH_TRUE
) || switch_channel_get_state(session->channel) >= CS_HANGUP
)
) {
5041 return SWITCH_STATUS_FALSE;
5042 }
5043
5044
5045 if (switch_rtp_ready(a_engine->rtp_session)) {
5046 switch_rtp_reset_media_timer(a_engine->rtp_session);
5047 }
5048
5049 if (a_engine->crypto_type != CRYPTO_INVALID) {
5050 switch_channel_set_flag(session->channel, CF_SECURE)switch_channel_set_flag_value(session->channel, CF_SECURE,
1)
;
5051 }
5052
5053 if (switch_channel_test_flag(session->channel, CF_PROXY_MODE)) {
5054 status = SWITCH_STATUS_SUCCESS;
5055 goto end;
5056 }
5057
5058 if (!switch_channel_test_flag(session->channel, CF_REINVITE)) {
5059 if (switch_rtp_ready(a_engine->rtp_session)) {
5060 if (switch_channel_test_flag(session->channel, CF_VIDEO_POSSIBLE) && !switch_rtp_ready(v_engine->rtp_session)) {
5061 goto video;
5062 }
5063
5064 status = SWITCH_STATUS_SUCCESS;
5065 goto end;
5066 }
5067 }
5068
5069 if ((status = switch_core_media_set_codec(session, 0, smh->mparams->codec_flags)) != SWITCH_STATUS_SUCCESS) {
5070 goto end;
5071 }
5072
5073 switch_core_media_set_video_codec(session, 0);
5074
5075
5076 memset(flags, 0, sizeof(flags));
5077 flags[SWITCH_RTP_FLAG_DATAWAIT]++;
5078
5079 if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) && !switch_channel_test_flag(session->channel, CF_WEBRTC) &&
5080 !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")switch_channel_get_variable_dup(session->channel, "disable_rtp_auto_adjust"
, SWITCH_TRUE, -1)
) && switch_true(val))) {
5081 flags[SWITCH_RTP_FLAG_AUTOADJ]++;
5082 }
5083
5084 if (switch_media_handle_test_media_flag(smh, SCMF_PASS_RFC2833)
5085 || ((val = switch_channel_get_variable(session->channel, "pass_rfc2833")switch_channel_get_variable_dup(session->channel, "pass_rfc2833"
, SWITCH_TRUE, -1)
) && switch_true(val))) {
5086 switch_channel_set_flag(session->channel, CF_PASS_RFC2833)switch_channel_set_flag_value(session->channel, CF_PASS_RFC2833
, 1)
;
5087 }
5088
5089
5090 if (switch_media_handle_test_media_flag(smh, SCMF_AUTOFLUSH)
5091 || ((val = switch_channel_get_variable(session->channel, "rtp_autoflush")switch_channel_get_variable_dup(session->channel, "rtp_autoflush"
, SWITCH_TRUE, -1)
) && switch_true(val))) {
5092 flags[SWITCH_RTP_FLAG_AUTOFLUSH]++;
5093 }
5094
5095 if (!(switch_media_handle_test_media_flag(smh, SCMF_REWRITE_TIMESTAMPS) ||
5096 ((val = switch_channel_get_variable(session->channel, "rtp_rewrite_timestamps")switch_channel_get_variable_dup(session->channel, "rtp_rewrite_timestamps"
, SWITCH_TRUE, -1)
) && switch_true(val)))) {
5097 flags[SWITCH_RTP_FLAG_RAW_WRITE]++;
5098 }
5099
5100 if (switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG)) {
5101 smh->mparams->cng_pt = 0;
5102 } else if (smh->mparams->cng_pt) {
5103 flags[SWITCH_RTP_FLAG_AUTO_CNG]++;
5104 }
5105
5106#if __BYTE_ORDER1234 == __LITTLE_ENDIAN1234
5107 if (!strcasecmp(a_engine->read_impl.iananame, "L16")) {
5108 flags[SWITCH_RTP_FLAG_BYTESWAP]++;
5109 }
5110#endif
5111
5112 if ((flags[SWITCH_RTP_FLAG_BYTESWAP]) && (val = switch_channel_get_variable(session->channel, "rtp_disable_byteswap")switch_channel_get_variable_dup(session->channel, "rtp_disable_byteswap"
, SWITCH_TRUE, -1)
) && switch_true(val)) {
5113 flags[SWITCH_RTP_FLAG_BYTESWAP] = 0;
5114 }
5115
5116 if (a_engine->rtp_session && switch_channel_test_flag(session->channel, CF_REINVITE)) {
5117 //const char *ip = switch_channel_get_variable(session->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE);
5118 //const char *port = switch_channel_get_variable(session->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE);
5119 char *remote_host = switch_rtp_get_remote_host(a_engine->rtp_session);
5120 switch_port_t remote_port = switch_rtp_get_remote_port(a_engine->rtp_session);
5121
5122 if (remote_host && remote_port && !strcmp(remote_host, a_engine->cur_payload_map->remote_sdp_ip)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(remote_host) && __builtin_constant_p (a_engine->
cur_payload_map->remote_sdp_ip) && (__s1_len = __builtin_strlen
(remote_host), __s2_len = __builtin_strlen (a_engine->cur_payload_map
->remote_sdp_ip), (!((size_t)(const void *)((remote_host) +
1) - (size_t)(const void *)(remote_host) == 1) || __s1_len >=
4) && (!((size_t)(const void *)((a_engine->cur_payload_map
->remote_sdp_ip) + 1) - (size_t)(const void *)(a_engine->
cur_payload_map->remote_sdp_ip) == 1) || __s2_len >= 4)
) ? __builtin_strcmp (remote_host, a_engine->cur_payload_map
->remote_sdp_ip) : (__builtin_constant_p (remote_host) &&
((size_t)(const void *)((remote_host) + 1) - (size_t)(const void
*)(remote_host) == 1) && (__s1_len = __builtin_strlen
(remote_host), __s1_len < 4) ? (__builtin_constant_p (a_engine
->cur_payload_map->remote_sdp_ip) && ((size_t)(
const void *)((a_engine->cur_payload_map->remote_sdp_ip
) + 1) - (size_t)(const void *)(a_engine->cur_payload_map->
remote_sdp_ip) == 1) ? __builtin_strcmp (remote_host, a_engine
->cur_payload_map->remote_sdp_ip) : (__extension__ ({ const
unsigned char *__s2 = (const unsigned char *) (const char *)
(a_engine->cur_payload_map->remote_sdp_ip); int __result
= (((const unsigned char *) (const char *) (remote_host))[0]
- __s2[0]); if (__s1_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) (remote_host))[1]
- __s2[1]); if (__s1_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) (remote_host))[2]
- __s2[2]); if (__s1_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) (remote_host))[3]
- __s2[3]); } } __result; }))) : (__builtin_constant_p (a_engine
->cur_payload_map->remote_sdp_ip) && ((size_t)(
const void *)((a_engine->cur_payload_map->remote_sdp_ip
) + 1) - (size_t)(const void *)(a_engine->cur_payload_map->
remote_sdp_ip) == 1) && (__s2_len = __builtin_strlen (
a_engine->cur_payload_map->remote_sdp_ip), __s2_len <
4) ? (__builtin_constant_p (remote_host) && ((size_t
)(const void *)((remote_host) + 1) - (size_t)(const void *)(remote_host
) == 1) ? __builtin_strcmp (remote_host, a_engine->cur_payload_map
->remote_sdp_ip) : (- (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) (remote_host)
; int __result = (((const unsigned char *) (const char *) (a_engine
->cur_payload_map->remote_sdp_ip))[0] - __s2[0]); if (__s2_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (a_engine->cur_payload_map->remote_sdp_ip
))[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (a_engine
->cur_payload_map->remote_sdp_ip))[2] - __s2[2]); if (__s2_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) (a_engine->cur_payload_map->remote_sdp_ip
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (remote_host
, a_engine->cur_payload_map->remote_sdp_ip)))); })
&&
5123 remote_port == a_engine->cur_payload_map->remote_sdp_port) {
5124 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5124, (const char*)(session)
, SWITCH_LOG_DEBUG, "Audio params are unchanged for %s.\n",
5125 switch_channel_get_name(session->channel));
5126 a_engine->cur_payload_map->negotiated = 1;
5127 //XX
5128 goto video;
5129 } else {
5130 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5130, (const char*)(session)
, SWITCH_LOG_DEBUG, "Audio params changed for %s from %s:%d to %s:%d\n",
5131 switch_channel_get_name(session->channel),
5132 remote_host, remote_port, a_engine->cur_payload_map->remote_sdp_ip, a_engine->cur_payload_map->remote_sdp_port);
5133
5134 switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->cur_payload_map->remote_sdp_port);
5135 switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, a_engine->cur_payload_map->remote_sdp_ip)switch_channel_set_variable_var_check(session->channel, "remote_media_ip"
, a_engine->cur_payload_map->remote_sdp_ip, SWITCH_TRUE
)
;
5136 switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp)switch_channel_set_variable_var_check(session->channel, "remote_media_port"
, tmp, SWITCH_TRUE)
;
5137 }
5138 }
5139
5140 if (!switch_channel_test_flag(session->channel, CF_PROXY_MEDIA)) {
5141 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5141, (const char*)(session)
, SWITCH_LOG_DEBUG, "AUDIO RTP [%s] %s port %d -> %s port %d codec: %u ms: %d\n",
5142 switch_channel_get_name(session->channel),
5143 a_engine->local_sdp_ip,
5144 a_engine->local_sdp_port,
5145 a_engine->cur_payload_map->remote_sdp_ip,
5146 a_engine->cur_payload_map->remote_sdp_port, a_engine->cur_payload_map->agreed_pt, a_engine->read_impl.microseconds_per_packet / 1000);
5147
5148 //XX
5149 }
5150
5151 switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->local_sdp_port);
5152 switch_channel_set_variable(session->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE, a_engine->local_sdp_ip)switch_channel_set_variable_var_check(session->channel, "local_media_ip"
, a_engine->local_sdp_ip, SWITCH_TRUE)
;
5153 switch_channel_set_variable(session->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE, tmp)switch_channel_set_variable_var_check(session->channel, "local_media_port"
, tmp, SWITCH_TRUE)
;
5154 switch_channel_set_variable(session->channel, SWITCH_ADVERTISED_MEDIA_IP_VARIABLE, a_engine->adv_sdp_ip)switch_channel_set_variable_var_check(session->channel, "advertised_media_ip"
, a_engine->adv_sdp_ip, SWITCH_TRUE)
;
5155
5156 if (a_engine->rtp_session && switch_channel_test_flag(session->channel, CF_REINVITE)) {
5157 const char *rport = NULL((void*)0);
5158 switch_port_t remote_rtcp_port = a_engine->remote_rtcp_port;
5159
5160 if (!remote_rtcp_port) {
5161 if ((rport = switch_channel_get_variable(session->channel, "rtp_remote_audio_rtcp_port")switch_channel_get_variable_dup(session->channel, "rtp_remote_audio_rtcp_port"
, SWITCH_TRUE, -1)
)) {
5162 remote_rtcp_port = (switch_port_t)atoi(rport);
5163 }
5164 }
5165
5166 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,
5167 remote_rtcp_port, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
5168 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5168, (const char*)(session)
, SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", err);
5169 } else {
5170 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5170, (const char*)(session)
, SWITCH_LOG_DEBUG, "AUDIO RTP CHANGING DEST TO: [%s:%d]\n",
5171 a_engine->cur_payload_map->remote_sdp_ip, a_engine->cur_payload_map->remote_sdp_port);
5172
5173 if (switch_channel_test_flag(session->channel, CF_PROTO_HOLD) && strcmp(a_engine->cur_payload_map->remote_sdp_ip, "0.0.0.0")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(a_engine->cur_payload_map->remote_sdp_ip) && __builtin_constant_p
("0.0.0.0") && (__s1_len = __builtin_strlen (a_engine
->cur_payload_map->remote_sdp_ip), __s2_len = __builtin_strlen
("0.0.0.0"), (!((size_t)(const void *)((a_engine->cur_payload_map
->remote_sdp_ip) + 1) - (size_t)(const void *)(a_engine->
cur_payload_map->remote_sdp_ip) == 1) || __s1_len >= 4)
&& (!((size_t)(const void *)(("0.0.0.0") + 1) - (size_t
)(const void *)("0.0.0.0") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(a_engine->cur_payload_map->remote_sdp_ip, "0.0.0.0") :
(__builtin_constant_p (a_engine->cur_payload_map->remote_sdp_ip
) && ((size_t)(const void *)((a_engine->cur_payload_map
->remote_sdp_ip) + 1) - (size_t)(const void *)(a_engine->
cur_payload_map->remote_sdp_ip) == 1) && (__s1_len
= __builtin_strlen (a_engine->cur_payload_map->remote_sdp_ip
), __s1_len < 4) ? (__builtin_constant_p ("0.0.0.0") &&
((size_t)(const void *)(("0.0.0.0") + 1) - (size_t)(const void
*)("0.0.0.0") == 1) ? __builtin_strcmp (a_engine->cur_payload_map
->remote_sdp_ip, "0.0.0.0") : (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) ("0.0.0.0"
); int __result = (((const unsigned char *) (const char *) (a_engine
->cur_payload_map->remote_sdp_ip))[0] - __s2[0]); if (__s1_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (a_engine->cur_payload_map->remote_sdp_ip
))[1] - __s2[1]); if (__s1_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (a_engine
->cur_payload_map->remote_sdp_ip))[2] - __s2[2]); if (__s1_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) (a_engine->cur_payload_map->remote_sdp_ip
))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (
"0.0.0.0") && ((size_t)(const void *)(("0.0.0.0") + 1
) - (size_t)(const void *)("0.0.0.0") == 1) && (__s2_len
= __builtin_strlen ("0.0.0.0"), __s2_len < 4) ? (__builtin_constant_p
(a_engine->cur_payload_map->remote_sdp_ip) && (
(size_t)(const void *)((a_engine->cur_payload_map->remote_sdp_ip
) + 1) - (size_t)(const void *)(a_engine->cur_payload_map->
remote_sdp_ip) == 1) ? __builtin_strcmp (a_engine->cur_payload_map
->remote_sdp_ip, "0.0.0.0") : (- (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (a_engine
->cur_payload_map->remote_sdp_ip); int __result = (((const
unsigned char *) (const char *) ("0.0.0.0"))[0] - __s2[0]); if
(__s2_len > 0 && __result == 0) { __result = (((const
unsigned char *) (const char *) ("0.0.0.0"))[1] - __s2[1]); if
(__s2_len > 1 && __result == 0) { __result = (((const
unsigned char *) (const char *) ("0.0.0.0"))[2] - __s2[2]); if
(__s2_len > 2 && __result == 0) __result = (((const
unsigned char *) (const char *) ("0.0.0.0"))[3] - __s2[3]); }
} __result; })))) : __builtin_strcmp (a_engine->cur_payload_map
->remote_sdp_ip, "0.0.0.0")))); })
) {
5174 switch_core_media_toggle_hold(session, 0);
5175 }
5176
5177
5178 if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) &&
5179 !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")switch_channel_get_variable_dup(session->channel, "disable_rtp_auto_adjust"
, SWITCH_TRUE, -1)
) && switch_true(val)) &&
5180 !switch_channel_test_flag(session->channel, CF_WEBRTC)) {
5181 /* Reactivate the NAT buster flag. */
5182 switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_AUTOADJ);
5183 }
5184 }
5185
5186 if (session && a_engine) {
5187 check_dtls_reinvite(session, a_engine);
5188 }
5189
5190 goto video;
5191 }
5192
5193 if (switch_channel_test_flag(session->channel, CF_PROXY_MEDIA)) {
5194 switch_core_media_proxy_remote_addr(session, NULL((void*)0));
5195
5196 memset(flags, 0, sizeof(flags));
5197 flags[SWITCH_RTP_FLAG_DATAWAIT]++;
5198 flags[SWITCH_RTP_FLAG_PROXY_MEDIA]++;
5199
5200 if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) && !switch_channel_test_flag(session->channel, CF_WEBRTC) &&
5201 !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")switch_channel_get_variable_dup(session->channel, "disable_rtp_auto_adjust"
, SWITCH_TRUE, -1)
) && switch_true(val))) {
5202 flags[SWITCH_RTP_FLAG_AUTOADJ]++;
5203 }
5204 timer_name = NULL((void*)0);
5205
5206 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5206, (const char*)(session)
, SWITCH_LOG_DEBUG,
5207 "PROXY AUDIO RTP [%s] %s:%d->%s:%d codec: %u ms: %d\n",
5208 switch_channel_get_name(session->channel),
5209 a_engine->cur_payload_map->remote_sdp_ip,
5210 a_engine->cur_payload_map->remote_sdp_port,
5211 a_engine->cur_payload_map->remote_sdp_ip,
5212 a_engine->cur_payload_map->remote_sdp_port, a_engine->cur_payload_map->agreed_pt, a_engine->read_impl.microseconds_per_packet / 1000);
5213
5214 if (switch_rtp_ready(a_engine->rtp_session)) {
5215 switch_rtp_set_default_payload(a_engine->rtp_session, a_engine->cur_payload_map->agreed_pt);
5216 }
5217
5218 } else {
5219 timer_name = smh->mparams->timer_name;
5220
5221 if ((var = switch_channel_get_variable(session->channel, "rtp_timer_name")switch_channel_get_variable_dup(session->channel, "rtp_timer_name"
, SWITCH_TRUE, -1)
)) {
5222 timer_name = (char *) var;
5223 }
5224 }
5225
5226 if (switch_channel_up(session->channel)(switch_channel_check_signal(session->channel, SWITCH_TRUE
) || switch_channel_get_state(session->channel) < CS_HANGUP
)
) {
5227 switch_channel_set_variable(session->channel, "rtp_use_timer_name", timer_name)switch_channel_set_variable_var_check(session->channel, "rtp_use_timer_name"
, timer_name, SWITCH_TRUE)
;
5228
5229 a_engine->rtp_session = switch_rtp_new(a_engine->local_sdp_ip,
5230 a_engine->local_sdp_port,
5231 a_engine->cur_payload_map->remote_sdp_ip,
5232 a_engine->cur_payload_map->remote_sdp_port,
5233 a_engine->cur_payload_map->agreed_pt,
5234 a_engine->read_impl.samples_per_packet,
5235 a_engine->cur_payload_map->codec_ms * 1000,
5236 flags, timer_name, &err, switch_core_session_get_pool(session));
5237
5238 if (switch_rtp_ready(a_engine->rtp_session)) {
5239 switch_rtp_set_payload_map(a_engine->rtp_session, &a_engine->payload_map);
5240 }
5241 }
5242
5243 if (switch_rtp_ready(a_engine->rtp_session)) {
5244 uint8_t vad_in = (smh->mparams->vflags & VAD_IN);
5245 uint8_t vad_out = (smh->mparams->vflags & VAD_OUT);
5246 uint8_t inb = switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_INBOUND;
5247 const char *ssrc;
5248
5249 switch_mutex_init(&a_engine->read_mutex[SWITCH_MEDIA_TYPE_AUDIO], SWITCH_MUTEX_NESTED0x1, switch_core_session_get_pool(session));
5250
5251 //switch_core_media_set_rtp_session(session, SWITCH_MEDIA_TYPE_AUDIO, a_engine->rtp_session);
5252
5253 if ((ssrc = switch_channel_get_variable(session->channel, "rtp_use_ssrc")switch_channel_get_variable_dup(session->channel, "rtp_use_ssrc"
, SWITCH_TRUE, -1)
)) {
5254 uint32_t ssrc_ul = (uint32_t) strtoul(ssrc, NULL((void*)0), 10);
5255 switch_rtp_set_ssrc(a_engine->rtp_session, ssrc_ul);
5256 a_engine->ssrc = ssrc_ul;
5257 } else {
5258 switch_rtp_set_ssrc(a_engine->rtp_session, a_engine->ssrc);
5259 }
5260
5261 if (a_engine->remote_ssrc) {
5262 switch_rtp_set_remote_ssrc(a_engine->rtp_session, a_engine->remote_ssrc);
5263 }
5264
5265 switch_channel_set_flag(session->channel, CF_FS_RTP)switch_channel_set_flag_value(session->channel, CF_FS_RTP,
1)
;
5266
5267 switch_channel_set_variable_printf(session->channel, "rtp_use_pt", "%d", a_engine->cur_payload_map->agreed_pt);
5268
5269 if ((val = switch_channel_get_variable(session->channel, "rtp_enable_vad_in")switch_channel_get_variable_dup(session->channel, "rtp_enable_vad_in"
, SWITCH_TRUE, -1)
) && switch_true(val)) {
5270 vad_in = 1;
5271 }
5272 if ((val = switch_channel_get_variable(session->channel, "rtp_enable_vad_out")switch_channel_get_variable_dup(session->channel, "rtp_enable_vad_out"
, SWITCH_TRUE, -1)
) && switch_true(val)) {
5273 vad_out = 1;
5274 }
5275
5276 if ((val = switch_channel_get_variable(session->channel, "rtp_disable_vad_in")switch_channel_get_variable_dup(session->channel, "rtp_disable_vad_in"
, SWITCH_TRUE, -1)
) && switch_true(val)) {
5277 vad_in = 0;
5278 }
5279 if ((val = switch_channel_get_variable(session->channel, "rtp_disable_vad_out")switch_channel_get_variable_dup(session->channel, "rtp_disable_vad_out"
, SWITCH_TRUE, -1)
) && switch_true(val)) {
5280 vad_out = 0;
5281 }
5282
5283
5284 a_engine->ssrc = switch_rtp_get_ssrc(a_engine->rtp_session);
5285 switch_channel_set_variable_printf(session->channel, "rtp_use_ssrc", "%u", a_engine->ssrc);
5286
5287
5288
5289 if (smh->mparams->auto_rtp_bugs & RTP_BUG_IGNORE_MARK_BIT) {
5290 a_engine->rtp_bugs |= RTP_BUG_IGNORE_MARK_BIT;
5291 }
5292
5293 if ((val = switch_channel_get_variable(session->channel, "rtp_manual_rtp_bugs")switch_channel_get_variable_dup(session->channel, "rtp_manual_rtp_bugs"
, SWITCH_TRUE, -1)
)) {
5294 switch_core_media_parse_rtp_bugs(&a_engine->rtp_bugs, val);
5295 }
5296
5297 if (switch_channel_test_flag(session->channel, CF_WEBRTC)) {
5298 smh->mparams->manual_rtp_bugs = RTP_BUG_SEND_LINEAR_TIMESTAMPS;
5299 }
5300
5301 switch_rtp_intentional_bugs(a_engine->rtp_session, a_engine->rtp_bugs | smh->mparams->manual_rtp_bugs);
5302
5303 if ((vad_in && inb) || (vad_out && !inb)) {
5304 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);
5305
5306 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5306, (const char*)(session)
, SWITCH_LOG_DEBUG, "AUDIO RTP Engage VAD for %s ( %s %s )\n",
5307 switch_channel_get_name(switch_core_session_get_channel(session)), vad_in ? "in" : "", vad_out ? "out" : "");
5308 }
5309
5310
5311 if (a_engine->ice_in.cands[a_engine->ice_in.chosen[0]][0].ready) {
5312
5313 gen_ice(session, SWITCH_MEDIA_TYPE_AUDIO, NULL((void*)0), 0);
5314
5315 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5315, (const char*)(session)
, SWITCH_LOG_INFO, "Activating Audio ICE\n");
5316
5317 switch_rtp_activate_ice(a_engine->rtp_session,
5318 a_engine->ice_in.ufrag,
5319 a_engine->ice_out.ufrag,
5320 a_engine->ice_out.pwd,
5321 a_engine->ice_in.pwd,
5322 IPR_RTP,
5323#ifdef GOOGLE_ICE
5324 ICE_GOOGLE_JINGLE,
5325 NULL((void*)0)
5326#else
5327 switch_ice_direction(session) ==
5328 SWITCH_CALL_DIRECTION_OUTBOUND ? ICE_VANILLA : (ICE_VANILLA | ICE_CONTROLLED),
5329 &a_engine->ice_in
5330#endif
5331 );
5332
5333
5334
5335 }
5336
5337
5338
5339 if ((val = switch_channel_get_variable(session->channel, "rtcp_audio_interval_msec")switch_channel_get_variable_dup(session->channel, "rtcp_audio_interval_msec"
, SWITCH_TRUE, -1)
) || (val = smh->mparams->rtcp_audio_interval_msec)) {
5340 const char *rport = switch_channel_get_variable(session->channel, "rtp_remote_audio_rtcp_port")switch_channel_get_variable_dup(session->channel, "rtp_remote_audio_rtcp_port"
, SWITCH_TRUE, -1)
;
5341 switch_port_t remote_rtcp_port = a_engine->remote_rtcp_port;
5342
5343 if (!remote_rtcp_port && rport) {
5344 remote_rtcp_port = (switch_port_t)atoi(rport);
5345 }
5346
5347 if (!strcasecmp(val, "passthru")) {
5348 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5348, (const char*)(session)
, SWITCH_LOG_INFO, "Activating RTCP PASSTHRU PORT %d\n", remote_rtcp_port);
5349 switch_rtp_activate_rtcp(a_engine->rtp_session, -1, remote_rtcp_port, a_engine->rtcp_mux > 0);
5350 } else {
5351 int interval = atoi(val);
5352 if (interval < 100 || interval > 500000) {
5353 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5353, (const char*)(session)
, SWITCH_LOG_ERROR,
5354 "Invalid rtcp interval spec [%d] must be between 100 and 500000\n", interval);
5355 interval = 10000;
5356 }
5357
5358 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5358, (const char*)(session)
, SWITCH_LOG_INFO, "Activating RTCP PORT %d\n", remote_rtcp_port);
5359 switch_rtp_activate_rtcp(a_engine->rtp_session, interval, remote_rtcp_port, a_engine->rtcp_mux > 0);
5360
5361 }
5362
5363 if (a_engine->ice_in.cands[a_engine->ice_in.chosen[1]][1].ready) {
5364 if (a_engine->rtcp_mux > 0 && !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)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(a_engine->ice_in.cands[a_engine->ice_in.chosen[1]][1]
.con_addr) && __builtin_constant_p (a_engine->ice_in
.cands[a_engine->ice_in.chosen[0]][0].con_addr) &&
(__s1_len = __builtin_strlen (a_engine->ice_in.cands[a_engine
->ice_in.chosen[1]][1].con_addr), __s2_len = __builtin_strlen
(a_engine->ice_in.cands[a_engine->ice_in.chosen[0]][0]
.con_addr), (!((size_t)(const void *)((a_engine->ice_in.cands
[a_engine->ice_in.chosen[1]][1].con_addr) + 1) - (size_t)(
const void *)(a_engine->ice_in.cands[a_engine->ice_in.chosen
[1]][1].con_addr) == 1) || __s1_len >= 4) && (!((size_t
)(const void *)((a_engine->ice_in.cands[a_engine->ice_in
.chosen[0]][0].con_addr) + 1) - (size_t)(const void *)(a_engine
->ice_in.cands[a_engine->ice_in.chosen[0]][0].con_addr)
== 1) || __s2_len >= 4)) ? __builtin_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)
: (__builtin_constant_p (a_engine->ice_in.cands[a_engine->
ice_in.chosen[1]][1].con_addr) && ((size_t)(const void
*)((a_engine->ice_in.cands[a_engine->ice_in.chosen[1]]
[1].con_addr) + 1) - (size_t)(const void *)(a_engine->ice_in
.cands[a_engine->ice_in.chosen[1]][1].con_addr) == 1) &&
(__s1_len = __builtin_strlen (a_engine->ice_in.cands[a_engine
->ice_in.chosen[1]][1].con_addr), __s1_len < 4) ? (__builtin_constant_p
(a_engine->ice_in.cands[a_engine->ice_in.chosen[0]][0]
.con_addr) && ((size_t)(const void *)((a_engine->ice_in
.cands[a_engine->ice_in.chosen[0]][0].con_addr) + 1) - (size_t
)(const void *)(a_engine->ice_in.cands[a_engine->ice_in
.chosen[0]][0].con_addr) == 1) ? __builtin_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)
: (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (a_engine->ice_in.cands[a_engine->
ice_in.chosen[0]][0].con_addr); int __result = (((const unsigned
char *) (const char *) (a_engine->ice_in.cands[a_engine->
ice_in.chosen[1]][1].con_addr))[0] - __s2[0]); if (__s1_len >
0 && __result == 0) { __result = (((const unsigned char
*) (const char *) (a_engine->ice_in.cands[a_engine->ice_in
.chosen[1]][1].con_addr))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (a_engine->ice_in.cands[a_engine->ice_in.chosen
[1]][1].con_addr))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (a_engine->ice_in.cands[a_engine->ice_in.chosen[1]]
[1].con_addr))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(a_engine->ice_in.cands[a_engine->ice_in.chosen[0]][0]
.con_addr) && ((size_t)(const void *)((a_engine->ice_in
.cands[a_engine->ice_in.chosen[0]][0].con_addr) + 1) - (size_t
)(const void *)(a_engine->ice_in.cands[a_engine->ice_in
.chosen[0]][0].con_addr) == 1) && (__s2_len = __builtin_strlen
(a_engine->ice_in.cands[a_engine->ice_in.chosen[0]][0]
.con_addr), __s2_len < 4) ? (__builtin_constant_p (a_engine
->ice_in.cands[a_engine->ice_in.chosen[1]][1].con_addr)
&& ((size_t)(const void *)((a_engine->ice_in.cands
[a_engine->ice_in.chosen[1]][1].con_addr) + 1) - (size_t)(
const void *)(a_engine->ice_in.cands[a_engine->ice_in.chosen
[1]][1].con_addr) == 1) ? __builtin_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) : (-
(__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (a_engine->ice_in.cands[a_engine->
ice_in.chosen[1]][1].con_addr); int __result = (((const unsigned
char *) (const char *) (a_engine->ice_in.cands[a_engine->
ice_in.chosen[0]][0].con_addr))[0] - __s2[0]); if (__s2_len >
0 && __result == 0) { __result = (((const unsigned char
*) (const char *) (a_engine->ice_in.cands[a_engine->ice_in
.chosen[0]][0].con_addr))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (a_engine->ice_in.cands[a_engine->ice_in.chosen
[0]][0].con_addr))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (a_engine->ice_in.cands[a_engine->ice_in.chosen[0]]
[0].con_addr))[3] - __s2[3]); } } __result; })))) : __builtin_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)))); })
5365 && 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) {
5366 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5366, (const char*)(session)
, SWITCH_LOG_INFO, "Skipping RTCP ICE (Same as RTP)\n");
5367 } else {
5368 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5368, (const char*)(session)
, SWITCH_LOG_INFO, "Activating RTCP ICE\n");
5369
5370 switch_rtp_activate_ice(a_engine->rtp_session,
5371 a_engine->ice_in.ufrag,
5372 a_engine->ice_out.ufrag,
5373 a_engine->ice_out.pwd,
5374 a_engine->ice_in.pwd,
5375 IPR_RTCP,
5376#ifdef GOOGLE_ICE
5377 ICE_GOOGLE_JINGLE,
5378 NULL((void*)0)
5379#else
5380 switch_ice_direction(session) ==
5381 SWITCH_CALL_DIRECTION_OUTBOUND ? ICE_VANILLA : (ICE_VANILLA | ICE_CONTROLLED),
5382 &a_engine->ice_in
5383#endif
5384 );
5385 }
5386
5387 }
5388 }
5389
5390 if (!zstr(a_engine->local_dtls_fingerprint.str)_zstr(a_engine->local_dtls_fingerprint.str) && switch_rtp_has_dtls() && dtls_ok(smh->session)) {
5391 dtls_type_t xtype, dtype = switch_channel_direction(smh->session->channel) == SWITCH_CALL_DIRECTION_INBOUND ? DTLS_TYPE_CLIENT : DTLS_TYPE_SERVER;
5392
5393 if (switch_channel_test_flag(smh->session->channel, CF_3PCC)) {
5394 dtype = (dtype == DTLS_TYPE_CLIENT) ? DTLS_TYPE_SERVER : DTLS_TYPE_CLIENT;
5395 }
5396
5397 xtype = DTLS_TYPE_RTP;
5398 if (a_engine->rtcp_mux > 0 && smh->mparams->rtcp_audio_interval_msec) xtype |= DTLS_TYPE_RTCP;
5399
5400 switch_rtp_add_dtls(a_engine->rtp_session, &a_engine->local_dtls_fingerprint, &a_engine->remote_dtls_fingerprint, dtype | xtype);
5401
5402 if (a_engine->rtcp_mux < 1 && smh->mparams->rtcp_audio_interval_msec) {
5403 xtype = DTLS_TYPE_RTCP;
5404 switch_rtp_add_dtls(a_engine->rtp_session, &a_engine->local_dtls_fingerprint, &a_engine->remote_dtls_fingerprint, dtype | xtype);
5405 }
5406
5407 }
5408
5409 check_jb(session, NULL((void*)0));
5410
5411 if ((val = switch_channel_get_variable(session->channel, "rtp_timeout_sec")switch_channel_get_variable_dup(session->channel, "rtp_timeout_sec"
, SWITCH_TRUE, -1)
)) {
5412 int v = atoi(val);
5413 if (v >= 0) {
5414 smh->mparams->rtp_timeout_sec = v;
5415 }
5416 }
5417
5418 if ((val = switch_channel_get_variable(session->channel, "rtp_hold_timeout_sec")switch_channel_get_variable_dup(session->channel, "rtp_hold_timeout_sec"
, SWITCH_TRUE, -1)
)) {
5419 int v = atoi(val);
5420 if (v >= 0) {
5421 smh->mparams->rtp_hold_timeout_sec = v;
5422 }
5423 }
5424
5425 if (smh->mparams->rtp_timeout_sec) {
5426 a_engine->max_missed_packets = (a_engine->read_impl.samples_per_second * smh->mparams->rtp_timeout_sec) / a_engine->read_impl.samples_per_packet;
5427
5428 switch_rtp_set_max_missed_packets(a_engine->rtp_session, a_engine->max_missed_packets);
5429 if (!smh->mparams->rtp_hold_timeout_sec) {
5430 smh->mparams->rtp_hold_timeout_sec = smh->mparams->rtp_timeout_sec * 10;
5431 }
5432 }
5433
5434 if (smh->mparams->rtp_hold_timeout_sec) {
5435 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;
5436 }
5437
5438 if (smh->mparams->te) {
5439 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5439, (const char*)(session)
, SWITCH_LOG_DEBUG, "Set 2833 dtmf send payload to %u\n", smh->mparams->te);
5440 switch_rtp_set_telephony_event(a_engine->rtp_session, smh->mparams->te);
5441 switch_channel_set_variable_printf(session->channel, "rtp_2833_send_payload", "%d", smh->mparams->te);
5442 }
5443
5444 if (smh->mparams->recv_te) {
5445 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5445, (const char*)(session)
, SWITCH_LOG_DEBUG, "Set 2833 dtmf receive payload to %u\n", smh->mparams->recv_te);
5446 switch_rtp_set_telephony_recv_event(a_engine->rtp_session, smh->mparams->recv_te);
5447 switch_channel_set_variable_printf(session->channel, "rtp_2833_recv_payload", "%d", smh->mparams->recv_te);
5448 }
5449
5450 //XX
5451
5452 if (switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG) ||
5453 ((val = switch_channel_get_variable(session->channel, "supress_cng")switch_channel_get_variable_dup(session->channel, "supress_cng"
, SWITCH_TRUE, -1)
) && switch_true(val)) ||
5454 ((val = switch_channel_get_variable(session->channel, "suppress_cng")switch_channel_get_variable_dup(session->channel, "suppress_cng"
, SWITCH_TRUE, -1)
) && switch_true(val))) {
5455 smh->mparams->cng_pt = 0;
5456 }
5457
5458 if (((val = switch_channel_get_variable(session->channel, "rtp_digit_delay")switch_channel_get_variable_dup(session->channel, "rtp_digit_delay"
, SWITCH_TRUE, -1)
))) {
5459 int delayi = atoi(val);
5460 if (delayi < 0) delayi = 0;
5461 smh->mparams->dtmf_delay = (uint32_t) delayi;
5462 }
5463
5464
5465 if (smh->mparams->dtmf_delay) {
5466 switch_rtp_set_interdigit_delay(a_engine->rtp_session, smh->mparams->dtmf_delay);
5467 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5467, (const char*)(session)
, SWITCH_LOG_DEBUG,
5468 "%s Set rtp dtmf delay to %u\n", switch_channel_get_name(session->channel), smh->mparams->dtmf_delay);
5469
5470 }
5471
5472 if (smh->mparams->cng_pt && !switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG)) {
5473 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5473, (const char*)(session)
, SWITCH_LOG_DEBUG, "Set comfort noise payload to %u\n", smh->mparams->cng_pt);
5474 switch_rtp_set_cng_pt(a_engine->rtp_session, smh->mparams->cng_pt);
5475 }
5476
5477 switch_core_session_apply_crypto(session, SWITCH_MEDIA_TYPE_AUDIO);
5478
5479 switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->cur_payload_map->remote_sdp_port);
5480 switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, a_engine->cur_payload_map->remote_sdp_ip)switch_channel_set_variable_var_check(session->channel, "remote_media_ip"
, a_engine->cur_payload_map->remote_sdp_ip, SWITCH_TRUE
)
;
5481 switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp)switch_channel_set_variable_var_check(session->channel, "remote_media_port"
, tmp, SWITCH_TRUE)
;
5482
5483
5484 if (switch_channel_test_flag(session->channel, CF_ZRTP_PASSTHRU)) {
5485 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5485, (const char*)(session)
, SWITCH_LOG_INFO, "Activating ZRTP PROXY MODE\n");
5486 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5486, (const char*)(session)
, SWITCH_LOG_DEBUG, "Disable NOTIMER_DURING_BRIDGE\n");
5487 switch_channel_clear_flag(session->channel, CF_NOTIMER_DURING_BRIDGE);
5488 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5488, (const char*)(session)
, SWITCH_LOG_DEBUG, "Activating audio UDPTL mode\n");
5489 switch_rtp_udptl_mode(a_engine->rtp_session);
5490 }
5491
5492
5493
5494
5495
5496
5497 video:
5498
5499 if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
5500 switch_core_media_check_video_codecs(session);
5501 }
5502
5503 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) {
5504 /******************************************************************************************/
5505 if (v_engine->rtp_session && switch_channel_test_flag(session->channel, CF_REINVITE)) {
5506 //const char *ip = switch_channel_get_variable(session->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE);
5507 //const char *port = switch_channel_get_variable(session->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE);
5508 char *remote_host = switch_rtp_get_remote_host(v_engine->rtp_session);
5509 switch_port_t remote_port = switch_rtp_get_remote_port(v_engine->rtp_session);
5510
5511
5512
5513 if (remote_host && remote_port && !strcmp(remote_host, v_engine->cur_payload_map->remote_sdp_ip)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(remote_host) && __builtin_constant_p (v_engine->
cur_payload_map->remote_sdp_ip) && (__s1_len = __builtin_strlen
(remote_host), __s2_len = __builtin_strlen (v_engine->cur_payload_map
->remote_sdp_ip), (!((size_t)(const void *)((remote_host) +
1) - (size_t)(const void *)(remote_host) == 1) || __s1_len >=
4) && (!((size_t)(const void *)((v_engine->cur_payload_map
->remote_sdp_ip) + 1) - (size_t)(const void *)(v_engine->
cur_payload_map->remote_sdp_ip) == 1) || __s2_len >= 4)
) ? __builtin_strcmp (remote_host, v_engine->cur_payload_map
->remote_sdp_ip) : (__builtin_constant_p (remote_host) &&
((size_t)(const void *)((remote_host) + 1) - (size_t)(const void
*)(remote_host) == 1) && (__s1_len = __builtin_strlen
(remote_host), __s1_len < 4) ? (__builtin_constant_p (v_engine
->cur_payload_map->remote_sdp_ip) && ((size_t)(
const void *)((v_engine->cur_payload_map->remote_sdp_ip
) + 1) - (size_t)(const void *)(v_engine->cur_payload_map->
remote_sdp_ip) == 1) ? __builtin_strcmp (remote_host, v_engine
->cur_payload_map->remote_sdp_ip) : (__extension__ ({ const
unsigned char *__s2 = (const unsigned char *) (const char *)
(v_engine->cur_payload_map->remote_sdp_ip); int __result
= (((const unsigned char *) (const char *) (remote_host))[0]
- __s2[0]); if (__s1_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) (remote_host))[1]
- __s2[1]); if (__s1_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) (remote_host))[2]
- __s2[2]); if (__s1_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) (remote_host))[3]
- __s2[3]); } } __result; }))) : (__builtin_constant_p (v_engine
->cur_payload_map->remote_sdp_ip) && ((size_t)(
const void *)((v_engine->cur_payload_map->remote_sdp_ip
) + 1) - (size_t)(const void *)(v_engine->cur_payload_map->
remote_sdp_ip) == 1) && (__s2_len = __builtin_strlen (
v_engine->cur_payload_map->remote_sdp_ip), __s2_len <
4) ? (__builtin_constant_p (remote_host) && ((size_t
)(const void *)((remote_host) + 1) - (size_t)(const void *)(remote_host
) == 1) ? __builtin_strcmp (remote_host, v_engine->cur_payload_map
->remote_sdp_ip) : (- (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) (remote_host)
; int __result = (((const unsigned char *) (const char *) (v_engine
->cur_payload_map->remote_sdp_ip))[0] - __s2[0]); if (__s2_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (v_engine->cur_payload_map->remote_sdp_ip
))[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (v_engine
->cur_payload_map->remote_sdp_ip))[2] - __s2[2]); if (__s2_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) (v_engine->cur_payload_map->remote_sdp_ip
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (remote_host
, v_engine->cur_payload_map->remote_sdp_ip)))); })
&& remote_port == v_engine->cur_payload_map->remote_sdp_port) {
5514 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5514, (const char*)(session)
, SWITCH_LOG_DEBUG, "Video params are unchanged for %s.\n",
5515 switch_channel_get_name(session->channel));
5516 v_engine->cur_payload_map->negotiated = 1;
5517 goto video_up;
5518 } else {
5519 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5519, (const char*)(session)
, SWITCH_LOG_DEBUG, "Video params changed for %s from %s:%d to %s:%d\n",
5520 switch_channel_get_name(session->channel),
5521 remote_host, remote_port, v_engine->cur_payload_map->remote_sdp_ip, v_engine->cur_payload_map->remote_sdp_port);
5522 }
5523 }
5524
5525 if (!switch_channel_test_flag(session->channel, CF_PROXY_MEDIA)) {
5526 if (switch_rtp_ready(v_engine->rtp_session)) {
5527 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5527, (const char*)(session)
, SWITCH_LOG_DEBUG,
5528 "VIDEO RTP [%s] %s port %d -> %s port %d codec: %u\n", switch_channel_get_name(session->channel),
5529 v_engine->local_sdp_ip, v_engine->local_sdp_port, v_engine->cur_payload_map->remote_sdp_ip,
5530 v_engine->cur_payload_map->remote_sdp_port, v_engine->cur_payload_map->agreed_pt);
5531
5532
5533 start_video_thread(session);
5534 switch_rtp_set_default_payload(v_engine->rtp_session, v_engine->cur_payload_map->agreed_pt);
5535 }
5536 }
5537
5538 switch_snprintf(tmp, sizeof(tmp), "%d", v_engine->local_sdp_port);
5539 switch_channel_set_variable(session->channel, SWITCH_LOCAL_VIDEO_IP_VARIABLE, a_engine->adv_sdp_ip)switch_channel_set_variable_var_check(session->channel, "local_video_ip"
, a_engine->adv_sdp_ip, SWITCH_TRUE)
;
5540 switch_channel_set_variable(session->channel, SWITCH_LOCAL_VIDEO_PORT_VARIABLE, tmp)switch_channel_set_variable_var_check(session->channel, "local_video_port"
, tmp, SWITCH_TRUE)
;
5541
5542
5543 if (v_engine->rtp_session && switch_channel_test_flag(session->channel, CF_REINVITE)) {
5544 const char *rport = NULL((void*)0);
5545 switch_port_t remote_rtcp_port = v_engine->remote_rtcp_port;
5546
5547 //switch_channel_clear_flag(session->channel, CF_REINVITE);
5548
5549 if (!remote_rtcp_port) {
5550 if ((rport = switch_channel_get_variable(session->channel, "rtp_remote_video_rtcp_port")switch_channel_get_variable_dup(session->channel, "rtp_remote_video_rtcp_port"
, SWITCH_TRUE, -1)
)) {
5551 remote_rtcp_port = (switch_port_t)atoi(rport);
5552 }
5553 }
5554
5555 if (switch_rtp_set_remote_address
5556 (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,
5557 &err) != SWITCH_STATUS_SUCCESS) {
5558 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5558, (const char*)(session)
, SWITCH_LOG_ERROR, "VIDEO RTP REPORTS ERROR: [%s]\n", err);
5559 } else {
5560 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5560, (const char*)(session)
, SWITCH_LOG_DEBUG, "VIDEO RTP CHANGING DEST TO: [%s:%d]\n",
5561 v_engine->cur_payload_map->remote_sdp_ip, v_engine->cur_payload_map->remote_sdp_port);
5562 if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) && !switch_channel_test_flag(session->channel, CF_WEBRTC) &&
5563 !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")switch_channel_get_variable_dup(session->channel, "disable_rtp_auto_adjust"
, SWITCH_TRUE, -1)
) && switch_true(val))) {
5564 /* Reactivate the NAT buster flag. */
5565 switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_AUTOADJ);
5566 start_video_thread(session);
5567 }
5568
5569 }
5570 goto video_up;
5571 }
5572
5573 if (switch_channel_test_flag(session->channel, CF_PROXY_MEDIA)) {
5574 switch_core_media_proxy_remote_addr(session, NULL((void*)0));
5575
5576 memset(flags, 0, sizeof(flags));
5577 flags[SWITCH_RTP_FLAG_PROXY_MEDIA]++;
5578 flags[SWITCH_RTP_FLAG_DATAWAIT]++;
5579
5580 if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) && !switch_channel_test_flag(session->channel, CF_WEBRTC) &&
5581 !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")switch_channel_get_variable_dup(session->channel, "disable_rtp_auto_adjust"
, SWITCH_TRUE, -1)
) && switch_true(val))) {
5582 flags[SWITCH_RTP_FLAG_AUTOADJ]++;
5583 }
5584 timer_name = NULL((void*)0);
5585
5586 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5586, (const char*)(session)
, SWITCH_LOG_DEBUG,
5587 "PROXY VIDEO RTP [%s] %s:%d->%s:%d codec: %u ms: %d\n",
5588 switch_channel_get_name(session->channel),
5589 a_engine->cur_payload_map->remote_sdp_ip,
5590 v_engine->local_sdp_port,
5591 v_engine->cur_payload_map->remote_sdp_ip,
5592 v_engine->cur_payload_map->remote_sdp_port, v_engine->cur_payload_map->agreed_pt, v_engine->read_impl.microseconds_per_packet / 1000);
5593
5594 if (switch_rtp_ready(v_engine->rtp_session)) {
5595 switch_rtp_set_default_payload(v_engine->rtp_session, v_engine->cur_payload_map->agreed_pt);
5596 }
5597 } else {
5598 timer_name = smh->mparams->timer_name;
5599
5600 if ((var = switch_channel_get_variable(session->channel, "rtp_timer_name")switch_channel_get_variable_dup(session->channel, "rtp_timer_name"
, SWITCH_TRUE, -1)
)) {
5601 timer_name = (char *) var;
5602 }
5603 }
5604
5605 /******************************************************************************************/
5606
5607 if (v_engine->rtp_session) {
5608 goto video_up;
5609 }
5610
5611
5612 if (!v_engine->local_sdp_port) {
5613 switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_VIDEO, 1);
5614 }
5615
5616 memset(flags, 0, sizeof(flags));
5617 flags[SWITCH_RTP_FLAG_DATAWAIT]++;
5618 flags[SWITCH_RTP_FLAG_RAW_WRITE]++;
5619
5620 if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) && !switch_channel_test_flag(session->channel, CF_PROXY_MODE) &&
5621 !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")switch_channel_get_variable_dup(session->channel, "disable_rtp_auto_adjust"
, SWITCH_TRUE, -1)
) && switch_true(val)) &&
5622 !switch_channel_test_flag(session->channel, CF_WEBRTC)) {
5623 flags[SWITCH_RTP_FLAG_AUTOADJ]++;
5624 }
5625
5626 if (switch_channel_test_flag(session->channel, CF_PROXY_MEDIA)) {
5627 flags[SWITCH_RTP_FLAG_PROXY_MEDIA]++;
5628 }
5629 switch_core_media_set_video_codec(session, 0);
5630
5631 flags[SWITCH_RTP_FLAG_USE_TIMER] = 0;
5632 flags[SWITCH_RTP_FLAG_NOBLOCK] = 0;
5633 flags[SWITCH_RTP_FLAG_VIDEO]++;
5634
5635 v_engine->rtp_session = switch_rtp_new(a_engine->local_sdp_ip,
5636 v_engine->local_sdp_port,
5637 v_engine->cur_payload_map->remote_sdp_ip,
5638 v_engine->cur_payload_map->remote_sdp_port,
5639 v_engine->cur_payload_map->agreed_pt,
5640 1, 90000, flags, NULL((void*)0), &err, switch_core_session_get_pool(session));
5641
5642
5643 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5643, (const char*)(session)
, SWITCH_LOG_DEBUG, "%sVIDEO RTP [%s] %s:%d->%s:%d codec: %u ms: %d [%s]\n",
5644 switch_channel_test_flag(session->channel, CF_PROXY_MEDIA) ? "PROXY " : "",
5645 switch_channel_get_name(session->channel),
5646 a_engine->cur_payload_map->remote_sdp_ip,
5647 v_engine->local_sdp_port,
5648 v_engine->cur_payload_map->remote_sdp_ip,
5649 v_engine->cur_payload_map->remote_sdp_port, v_engine->cur_payload_map->agreed_pt,
5650 0, switch_rtp_ready(v_engine->rtp_session) ? "SUCCESS" : err);
5651
5652
5653 if (switch_rtp_ready(v_engine->rtp_session)) {
5654 const char *ssrc;
5655
5656 if (v_engine->fir) {
5657 switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_FIR);
5658 }
5659
5660 if (v_engine->pli) {
5661 switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_PLI);
5662 }
5663
5664 switch_rtp_set_payload_map(v_engine->rtp_session, &v_engine->payload_map);
5665
5666 start_video_thread(session);
5667 switch_channel_set_flag(session->channel, CF_VIDEO)switch_channel_set_flag_value(session->channel, CF_VIDEO, 1
)
;
5668
5669 if ((ssrc = switch_channel_get_variable(session->channel, "rtp_use_video_ssrc")switch_channel_get_variable_dup(session->channel, "rtp_use_video_ssrc"
, SWITCH_TRUE, -1)
)) {
5670 uint32_t ssrc_ul = (uint32_t) strtoul(ssrc, NULL((void*)0), 10);
5671 switch_rtp_set_ssrc(v_engine->rtp_session, ssrc_ul);
5672 v_engine->ssrc = ssrc_ul;
5673 } else {
5674 switch_rtp_set_ssrc(v_engine->rtp_session, v_engine->ssrc);
5675 }
5676
5677 if (v_engine->remote_ssrc) {
5678 switch_rtp_set_remote_ssrc(v_engine->rtp_session, v_engine->remote_ssrc);
5679 }
5680
5681 if (v_engine->ice_in.cands[v_engine->ice_in.chosen[0]][0].ready) {
5682
5683 gen_ice(session, SWITCH_MEDIA_TYPE_VIDEO, NULL((void*)0), 0);
5684
5685 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5685, (const char*)(session)
, SWITCH_LOG_INFO, "Activating Video ICE\n");
5686
5687 switch_rtp_activate_ice(v_engine->rtp_session,
5688 v_engine->ice_in.ufrag,
5689 v_engine->ice_out.ufrag,
5690 v_engine->ice_out.pwd,
5691 v_engine->ice_in.pwd,
5692 IPR_RTP,
5693#ifdef GOOGLE_ICE
5694 ICE_GOOGLE_JINGLE,
5695 NULL((void*)0)
5696#else
5697 switch_ice_direction(session) ==
5698 SWITCH_CALL_DIRECTION_OUTBOUND ? ICE_VANILLA : (ICE_VANILLA | ICE_CONTROLLED),
5699 &v_engine->ice_in
5700#endif
5701 );
5702
5703
5704 }
5705
5706 if ((val = switch_channel_get_variable(session->channel, "rtcp_video_interval_msec")switch_channel_get_variable_dup(session->channel, "rtcp_video_interval_msec"
, SWITCH_TRUE, -1)
) || (val = smh->mparams->rtcp_video_interval_msec)) {
5707 const char *rport = switch_channel_get_variable(session->channel, "rtp_remote_video_rtcp_port")switch_channel_get_variable_dup(session->channel, "rtp_remote_video_rtcp_port"
, SWITCH_TRUE, -1)
;
5708 switch_port_t remote_port = v_engine->remote_rtcp_port;
5709
5710 if (rport) {
5711 remote_port = (switch_port_t)atoi(rport);
5712 }
5713 if (!strcasecmp(val, "passthru")) {
5714 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5714, (const char*)(session)
, SWITCH_LOG_INFO, "Activating VIDEO RTCP PASSTHRU PORT %d\n", remote_port);
5715 switch_rtp_activate_rtcp(v_engine->rtp_session, -1, remote_port, v_engine->rtcp_mux > 0);
5716 } else {
5717 int interval = atoi(val);
5718 if (interval < 100 || interval > 500000) {
5719 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5719, (const char*)(session)
, SWITCH_LOG_ERROR,
5720 "Invalid rtcp interval spec [%d] must be between 100 and 500000\n", interval);
5721 }
5722 interval = 10000;
5723 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5723, (const char*)(session)
, SWITCH_LOG_INFO, "Activating VIDEO RTCP PORT %d mux %d\n", remote_port, v_engine->rtcp_mux);
5724 switch_rtp_activate_rtcp(v_engine->rtp_session, interval, remote_port, v_engine->rtcp_mux > 0);
5725
5726 }
5727
5728
5729 if (v_engine->ice_in.cands[v_engine->ice_in.chosen[1]][1].ready) {
5730
5731 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)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(v_engine->ice_in.cands[v_engine->ice_in.chosen[1]][1]
.con_addr) && __builtin_constant_p (v_engine->ice_in
.cands[v_engine->ice_in.chosen[0]][0].con_addr) &&
(__s1_len = __builtin_strlen (v_engine->ice_in.cands[v_engine
->ice_in.chosen[1]][1].con_addr), __s2_len = __builtin_strlen
(v_engine->ice_in.cands[v_engine->ice_in.chosen[0]][0]
.con_addr), (!((size_t)(const void *)((v_engine->ice_in.cands
[v_engine->ice_in.chosen[1]][1].con_addr) + 1) - (size_t)(
const void *)(v_engine->ice_in.cands[v_engine->ice_in.chosen
[1]][1].con_addr) == 1) || __s1_len >= 4) && (!((size_t
)(const void *)((v_engine->ice_in.cands[v_engine->ice_in
.chosen[0]][0].con_addr) + 1) - (size_t)(const void *)(v_engine
->ice_in.cands[v_engine->ice_in.chosen[0]][0].con_addr)
== 1) || __s2_len >= 4)) ? __builtin_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)
: (__builtin_constant_p (v_engine->ice_in.cands[v_engine->
ice_in.chosen[1]][1].con_addr) && ((size_t)(const void
*)((v_engine->ice_in.cands[v_engine->ice_in.chosen[1]]
[1].con_addr) + 1) - (size_t)(const void *)(v_engine->ice_in
.cands[v_engine->ice_in.chosen[1]][1].con_addr) == 1) &&
(__s1_len = __builtin_strlen (v_engine->ice_in.cands[v_engine
->ice_in.chosen[1]][1].con_addr), __s1_len < 4) ? (__builtin_constant_p
(v_engine->ice_in.cands[v_engine->ice_in.chosen[0]][0]
.con_addr) && ((size_t)(const void *)((v_engine->ice_in
.cands[v_engine->ice_in.chosen[0]][0].con_addr) + 1) - (size_t
)(const void *)(v_engine->ice_in.cands[v_engine->ice_in
.chosen[0]][0].con_addr) == 1) ? __builtin_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)
: (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (v_engine->ice_in.cands[v_engine->
ice_in.chosen[0]][0].con_addr); int __result = (((const unsigned
char *) (const char *) (v_engine->ice_in.cands[v_engine->
ice_in.chosen[1]][1].con_addr))[0] - __s2[0]); if (__s1_len >
0 && __result == 0) { __result = (((const unsigned char
*) (const char *) (v_engine->ice_in.cands[v_engine->ice_in
.chosen[1]][1].con_addr))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (v_engine->ice_in.cands[v_engine->ice_in.chosen
[1]][1].con_addr))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (v_engine->ice_in.cands[v_engine->ice_in.chosen[1]]
[1].con_addr))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(v_engine->ice_in.cands[v_engine->ice_in.chosen[0]][0]
.con_addr) && ((size_t)(const void *)((v_engine->ice_in
.cands[v_engine->ice_in.chosen[0]][0].con_addr) + 1) - (size_t
)(const void *)(v_engine->ice_in.cands[v_engine->ice_in
.chosen[0]][0].con_addr) == 1) && (__s2_len = __builtin_strlen
(v_engine->ice_in.cands[v_engine->ice_in.chosen[0]][0]
.con_addr), __s2_len < 4) ? (__builtin_constant_p (v_engine
->ice_in.cands[v_engine->ice_in.chosen[1]][1].con_addr)
&& ((size_t)(const void *)((v_engine->ice_in.cands
[v_engine->ice_in.chosen[1]][1].con_addr) + 1) - (size_t)(
const void *)(v_engine->ice_in.cands[v_engine->ice_in.chosen
[1]][1].con_addr) == 1) ? __builtin_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) : (-
(__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (v_engine->ice_in.cands[v_engine->
ice_in.chosen[1]][1].con_addr); int __result = (((const unsigned
char *) (const char *) (v_engine->ice_in.cands[v_engine->
ice_in.chosen[0]][0].con_addr))[0] - __s2[0]); if (__s2_len >
0 && __result == 0) { __result = (((const unsigned char
*) (const char *) (v_engine->ice_in.cands[v_engine->ice_in
.chosen[0]][0].con_addr))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (v_engine->ice_in.cands[v_engine->ice_in.chosen
[0]][0].con_addr))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (v_engine->ice_in.cands[v_engine->ice_in.chosen[0]]
[0].con_addr))[3] - __s2[3]); } } __result; })))) : __builtin_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)))); })
5732 && 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) {
5733 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5733, (const char*)(session)
, SWITCH_LOG_INFO, "Skipping VIDEO RTCP ICE (Same as VIDEO RTP)\n");
5734 } else {
5735
5736 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5736, (const char*)(session)
, SWITCH_LOG_INFO, "Activating VIDEO RTCP ICE\n");
5737 switch_rtp_activate_ice(v_engine->rtp_session,
5738 v_engine->ice_in.ufrag,
5739 v_engine->ice_out.ufrag,
5740 v_engine->ice_out.pwd,
5741 v_engine->ice_in.pwd,
5742 IPR_RTCP,
5743#ifdef GOOGLE_ICE
5744 ICE_GOOGLE_JINGLE,
5745 NULL((void*)0)
5746#else
5747 switch_ice_direction(session) ==
5748 SWITCH_CALL_DIRECTION_OUTBOUND ? ICE_VANILLA : (ICE_VANILLA | ICE_CONTROLLED),
5749
5750 &v_engine->ice_in
5751#endif
5752 );
5753
5754
5755
5756 }
5757
5758 }
5759 }
5760
5761 if (!zstr(v_engine->local_dtls_fingerprint.str)_zstr(v_engine->local_dtls_fingerprint.str) && switch_rtp_has_dtls() && dtls_ok(smh->session)) {
5762 dtls_type_t xtype,
5763 dtype = switch_channel_direction(smh->session->channel) == SWITCH_CALL_DIRECTION_INBOUND ? DTLS_TYPE_CLIENT : DTLS_TYPE_SERVER;
5764 xtype = DTLS_TYPE_RTP;
5765 if (v_engine->rtcp_mux > 0 && smh->mparams->rtcp_video_interval_msec) xtype |= DTLS_TYPE_RTCP;
5766
5767 switch_rtp_add_dtls(v_engine->rtp_session, &v_engine->local_dtls_fingerprint, &v_engine->remote_dtls_fingerprint, dtype | xtype);
5768
5769 if (v_engine->rtcp_mux < 1 && smh->mparams->rtcp_video_interval_msec) {
5770 xtype = DTLS_TYPE_RTCP;
5771 switch_rtp_add_dtls(v_engine->rtp_session, &v_engine->local_dtls_fingerprint, &v_engine->remote_dtls_fingerprint, dtype | xtype);
5772 }
5773 }
5774
5775
5776 if ((val = switch_channel_get_variable(session->channel, "rtp_manual_video_rtp_bugs")switch_channel_get_variable_dup(session->channel, "rtp_manual_video_rtp_bugs"
, SWITCH_TRUE, -1)
)) {
5777 switch_core_media_parse_rtp_bugs(&v_engine->rtp_bugs, val);
5778 }
5779
5780 switch_rtp_intentional_bugs(v_engine->rtp_session, v_engine->rtp_bugs | smh->mparams->manual_video_rtp_bugs);
5781
5782
5783 //XX
5784
5785
5786 switch_channel_set_variable_printf(session->channel, "rtp_use_video_pt", "%d", v_engine->cur_payload_map->agreed_pt);
5787 v_engine->ssrc = switch_rtp_get_ssrc(v_engine->rtp_session);
5788 switch_channel_set_variable_printf(session->channel, "rtp_use_video_ssrc", "%u", v_engine->ssrc);
5789
5790 switch_core_session_apply_crypto(session, SWITCH_MEDIA_TYPE_VIDEO);
5791
5792
5793 if (switch_channel_test_flag(session->channel, CF_ZRTP_PASSTHRU)) {
5794 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5794, (const char*)(session)
, SWITCH_LOG_DEBUG, "Activating video UDPTL mode\n");
5795 switch_rtp_udptl_mode(v_engine->rtp_session);
5796 }
5797
5798 } else {
5799 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5799, (const char*)(session)
, SWITCH_LOG_ERROR, "VIDEO RTP REPORTS ERROR: [%s]\n", switch_str_nil(err)(err ? err : ""));
5800 switch_channel_hangup(session->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(session->channel, "src/switch_core_media.c"
, (const char *)__func__, 5800, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER
)
;
5801 goto end;
5802 }
5803 }
5804
5805 } else {
5806 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 5806, (const char*)(session)
, SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", switch_str_nil(err)(err ? err : ""));
5807 switch_channel_hangup(session->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(session->channel, "src/switch_core_media.c"
, (const char *)__func__, 5807, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER
)
;
5808 status = SWITCH_STATUS_FALSE;
5809 goto end;
5810 }
5811
5812 video_up:
5813
5814 if (session && v_engine) {
5815 check_dtls_reinvite(session, v_engine);
5816 }
5817
5818 status = SWITCH_STATUS_SUCCESS;
5819
5820 end:
5821
5822 switch_channel_clear_flag(session->channel, CF_REINVITE);
5823
5824 switch_core_recovery_track(session);
5825
5826
5827
5828 return status;
5829
5830}
5831
5832static const char *get_media_profile_name(switch_core_session_t *session, int secure)
5833{
5834 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 5834, __PRETTY_FUNCTION__))
;
5835
5836 if (switch_channel_test_flag(session->channel, CF_WEBRTC)) {
5837 if (switch_channel_test_flag(session->channel, CF_WEBRTC_MOZ)) {
5838 return "UDP/TLS/RTP/SAVPF";
5839 } else {
5840 return "RTP/SAVPF";
5841 }
5842 }
5843
5844 if (secure) {
5845 return "RTP/SAVP";
5846 }
5847
5848 return "RTP/AVP";
5849
5850}
5851
5852//?
5853static void generate_m(switch_core_session_t *session, char *buf, size_t buflen,
5854 switch_port_t port, const char *family, const char *ip,
5855 int cur_ptime, const char *append_audio, const char *sr, int use_cng, int cng_type, switch_event_t *map, int secure,
5856 switch_sdp_type_t sdp_type)
5857{
5858 int i = 0;
5859 int rate;
5860 int already_did[128] = { 0 };
5861 int ptime = 0, noptime = 0;
5862 const char *local_sdp_audio_zrtp_hash;
5863 switch_media_handle_t *smh;
5864 switch_rtp_engine_t *a_engine;
5865
5866 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 5866, __PRETTY_FUNCTION__))
;
5867
5868 if (!(smh = session->media_handle)) {
5869 return;
5870 }
5871
5872 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
5873
5874 //switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "m=audio %d RTP/%sAVP%s",
5875 //port, secure ? "S" : "", switch_channel_test_flag(session->channel, CF_WEBRTC) ? "F" : "");
5876
5877 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "m=audio %d %s", port,
5878 get_media_profile_name(session,
5879 (secure && switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) ||
5880 a_engine->crypto_type != CRYPTO_INVALID));
5881
5882
5883 for (i = 0; i < smh->mparams->num_codecs; i++) {
5884 const switch_codec_implementation_t *imp = smh->codecs[i];
5885 int this_ptime = (imp->microseconds_per_packet / 1000);
5886
5887 if (!strcasecmp(imp->iananame, "ilbc") || !strcasecmp(imp->iananame, "isac") ) {
5888 this_ptime = 20;
5889 }
5890
5891 if (imp->codec_type != SWITCH_CODEC_TYPE_AUDIO) {
5892 continue;
5893 }
5894
5895 if (!noptime) {
5896 if (!cur_ptime) {
5897 if (!ptime) {
5898 ptime = this_ptime;
5899 }
5900 } else {
5901 if (this_ptime != cur_ptime) {
5902 continue;
5903 }
5904 }
5905 }
5906
5907 if (smh->ianacodes[i] < 128) {
5908 if (already_did[smh->ianacodes[i]]) {
5909 continue;
5910 }
5911
5912 already_did[smh->ianacodes[i]] = 1;
5913 }
5914
5915
5916 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), " %d", smh->ianacodes[i]);
5917 }
5918
5919 if (smh->mparams->dtmf_type == DTMF_2833 && smh->mparams->te > 95) {
5920 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), " %d", smh->mparams->te);
5921 }
5922
5923 if (!switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG) && cng_type && use_cng) {
5924 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), " %d", cng_type);
5925 }
5926
5927 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "\n");
5928
5929
5930 memset(already_did, 0, sizeof(already_did));
5931
5932
5933 for (i = 0; i < smh->mparams->num_codecs; i++) {
5934 const switch_codec_implementation_t *imp = smh->codecs[i];
5935 char *fmtp = imp->fmtp;
5936 int this_ptime = imp->microseconds_per_packet / 1000;
5937
5938 if (imp->codec_type != SWITCH_CODEC_TYPE_AUDIO) {
5939 continue;
5940 }
5941
5942 if (!strcasecmp(imp->iananame, "ilbc") || !strcasecmp(imp->iananame, "isac")) {
5943 this_ptime = 20;
5944 }
5945
5946 if (!noptime) {
5947 if (!cur_ptime) {
5948 if (!ptime) {
5949 ptime = this_ptime;
5950 }
5951 } else {
5952 if (this_ptime != cur_ptime) {
5953 continue;
5954 }
5955 }
5956 }
5957
5958 if (smh->ianacodes[i] < 128) {
5959 if (already_did[smh->ianacodes[i]]) {
5960 continue;
5961 }
5962
5963 already_did[smh->ianacodes[i]] = 1;
5964 }
5965
5966 rate = imp->samples_per_second;
5967
5968 if (map) {
5969 char key[128] = "";
5970 char *check = NULL((void*)0);
5971 switch_snprintf(key, sizeof(key), "%s:%u", imp->iananame, imp->bits_per_second);
5972
5973 if ((check = switch_event_get_header(map, key)switch_event_get_header_idx(map, key, -1)) || (check = switch_event_get_header(map, imp->iananame)switch_event_get_header_idx(map, imp->iananame, -1))) {
5974 fmtp = check;
5975 }
5976 }
5977
5978 if (smh->fmtps[i]) {
5979 fmtp = smh->fmtps[i];
5980 }
5981
5982 if (smh->ianacodes[i] > 95 || switch_channel_test_flag(session->channel, CF_VERBOSE_SDP)) {
5983 int channels = get_channels(imp->iananame, imp->number_of_channels);
5984
5985 if (channels > 1) {
5986 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtpmap:%d %s/%d/%d\n", smh->ianacodes[i], imp->iananame, rate, channels);
5987
5988 } else {
5989 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtpmap:%d %s/%d\n", smh->ianacodes[i], imp->iananame, rate);
5990 }
5991 }
5992
5993 if (fmtp) {
5994 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=fmtp:%d %s\n", smh->ianacodes[i], fmtp);
5995 }
5996 }
5997
5998
5999 if ((smh->mparams->dtmf_type == DTMF_2833 || switch_media_handle_test_media_flag(smh, SCMF_LIBERAL_DTMF) ||
6000 switch_channel_test_flag(session->channel, CF_LIBERAL_DTMF)) && smh->mparams->te > 95) {
6001
6002 if (switch_channel_test_flag(session->channel, CF_WEBRTC)) {
6003 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtpmap:%d telephone-event/8000\n", smh->mparams->te);
6004 } else {
6005 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtpmap:%d telephone-event/8000\na=fmtp:%d 0-16\n", smh->mparams->te, smh->mparams->te);
6006 }
6007
6008 }
6009
6010 if (!zstr(a_engine->local_dtls_fingerprint.type)_zstr(a_engine->local_dtls_fingerprint.type) && secure) {
6011 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=fingerprint:%s %s\n", a_engine->local_dtls_fingerprint.type,
6012 a_engine->local_dtls_fingerprint.str);
6013 }
6014
6015 if (smh->mparams->rtcp_audio_interval_msec) {
6016 if (a_engine->rtcp_mux > 0) {
6017 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtcp-mux\n");
6018 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtcp:%d IN %s %s\n", port, family, ip);
6019 } else {
6020 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtcp:%d IN %s %s\n", port + 1, family, ip);
6021 }
6022 }
6023
6024 //switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u\n", a_engine->ssrc);
6025
6026 if (a_engine->ice_out.cands[0][0].ready) {
6027 char tmp1[11] = "";
6028 char tmp2[11] = "";
6029 uint32_t c1 = (2^24)*126 + (2^8)*65535 + (2^0)*(256 - 1);
6030 uint32_t c2 = (2^24)*126 + (2^8)*65535 + (2^0)*(256 - 2);
6031 //uint32_t c3 = (2^24)*126 + (2^8)*65534 + (2^0)*(256 - 1);
6032 //uint32_t c4 = (2^24)*126 + (2^8)*65534 + (2^0)*(256 - 2);
6033 ice_t *ice_out;
6034
6035 tmp1[10] = '\0';
6036 tmp2[10] = '\0';
6037 switch_stun_random_string(tmp1, 10, "0123456789");
6038 switch_stun_random_string(tmp2, 10, "0123456789");
6039
6040 gen_ice(session, SWITCH_MEDIA_TYPE_AUDIO, NULL((void*)0), 0);
6041
6042 ice_out = &a_engine->ice_out;
6043
6044 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=ssrc:%u cname:%s\n", a_engine->ssrc, smh->cname);
6045 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=ssrc:%u msid:%s a0\n", a_engine->ssrc, smh->msid);
6046 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=ssrc:%u mslabel:%s\n", a_engine->ssrc, smh->msid);
6047 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=ssrc:%u label:%sa0\n", a_engine->ssrc, smh->msid);
6048
6049
6050 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=ice-ufrag:%s\n", ice_out->ufrag);
6051 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=ice-pwd:%s\n", ice_out->pwd);
6052
6053
6054 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=candidate:%s 1 %s %u %s %d typ host generation 0\n",
6055 tmp1, ice_out->cands[0][0].transport, c1,
6056 ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port
6057 );
6058
6059 if (!zstr(a_engine->local_sdp_ip)_zstr(a_engine->local_sdp_ip) && !zstr(ice_out->cands[0][0].con_addr)_zstr(ice_out->cands[0][0].con_addr) &&
6060 strcmp(a_engine->local_sdp_ip, ice_out->cands[0][0].con_addr)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(a_engine->local_sdp_ip) && __builtin_constant_p (
ice_out->cands[0][0].con_addr) && (__s1_len = __builtin_strlen
(a_engine->local_sdp_ip), __s2_len = __builtin_strlen (ice_out
->cands[0][0].con_addr), (!((size_t)(const void *)((a_engine
->local_sdp_ip) + 1) - (size_t)(const void *)(a_engine->
local_sdp_ip) == 1) || __s1_len >= 4) && (!((size_t
)(const void *)((ice_out->cands[0][0].con_addr) + 1) - (size_t
)(const void *)(ice_out->cands[0][0].con_addr) == 1) || __s2_len
>= 4)) ? __builtin_strcmp (a_engine->local_sdp_ip, ice_out
->cands[0][0].con_addr) : (__builtin_constant_p (a_engine->
local_sdp_ip) && ((size_t)(const void *)((a_engine->
local_sdp_ip) + 1) - (size_t)(const void *)(a_engine->local_sdp_ip
) == 1) && (__s1_len = __builtin_strlen (a_engine->
local_sdp_ip), __s1_len < 4) ? (__builtin_constant_p (ice_out
->cands[0][0].con_addr) && ((size_t)(const void *)
((ice_out->cands[0][0].con_addr) + 1) - (size_t)(const void
*)(ice_out->cands[0][0].con_addr) == 1) ? __builtin_strcmp
(a_engine->local_sdp_ip, ice_out->cands[0][0].con_addr
) : (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (ice_out->cands[0][0].con_addr); int
__result = (((const unsigned char *) (const char *) (a_engine
->local_sdp_ip))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (a_engine->local_sdp_ip))[1] - __s2[1]); if (__s1_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (a_engine->local_sdp_ip))[2] - __s2
[2]); if (__s1_len > 2 && __result == 0) __result =
(((const unsigned char *) (const char *) (a_engine->local_sdp_ip
))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (
ice_out->cands[0][0].con_addr) && ((size_t)(const void
*)((ice_out->cands[0][0].con_addr) + 1) - (size_t)(const void
*)(ice_out->cands[0][0].con_addr) == 1) && (__s2_len
= __builtin_strlen (ice_out->cands[0][0].con_addr), __s2_len
< 4) ? (__builtin_constant_p (a_engine->local_sdp_ip) &&
((size_t)(const void *)((a_engine->local_sdp_ip) + 1) - (
size_t)(const void *)(a_engine->local_sdp_ip) == 1) ? __builtin_strcmp
(a_engine->local_sdp_ip, ice_out->cands[0][0].con_addr
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (a_engine->local_sdp_ip); int __result
= (((const unsigned char *) (const char *) (ice_out->cands
[0][0].con_addr))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (ice_out->cands[0][0].con_addr))[1] - __s2[1]); if
(__s2_len > 1 && __result == 0) { __result = (((const
unsigned char *) (const char *) (ice_out->cands[0][0].con_addr
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (ice_out
->cands[0][0].con_addr))[3] - __s2[3]); } } __result; })))
) : __builtin_strcmp (a_engine->local_sdp_ip, ice_out->
cands[0][0].con_addr)))); })
6061 && a_engine->local_sdp_port != ice_out->cands[0][0].con_port) {
6062
6063 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=candidate:%s 1 %s %u %s %d typ srflx raddr %s rport %d generation 0\n",
6064 tmp2, ice_out->cands[0][0].transport, c2,
6065 ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port,
6066 a_engine->local_sdp_ip, a_engine->local_sdp_port
6067 );
6068 }
6069
6070 if (a_engine->rtcp_mux < 1 || switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
6071
6072
6073 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ host generation 0\n",
6074 tmp1, ice_out->cands[0][0].transport, c1,
6075 ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port + (a_engine->rtcp_mux > 0 ? 0 : 1)
6076 );
6077
6078 if (!zstr(a_engine->local_sdp_ip)_zstr(a_engine->local_sdp_ip) && !zstr(ice_out->cands[0][1].con_addr)_zstr(ice_out->cands[0][1].con_addr) &&
6079 strcmp(a_engine->local_sdp_ip, ice_out->cands[0][1].con_addr)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(a_engine->local_sdp_ip) && __builtin_constant_p (
ice_out->cands[0][1].con_addr) && (__s1_len = __builtin_strlen
(a_engine->local_sdp_ip), __s2_len = __builtin_strlen (ice_out
->cands[0][1].con_addr), (!((size_t)(const void *)((a_engine
->local_sdp_ip) + 1) - (size_t)(const void *)(a_engine->
local_sdp_ip) == 1) || __s1_len >= 4) && (!((size_t
)(const void *)((ice_out->cands[0][1].con_addr) + 1) - (size_t
)(const void *)(ice_out->cands[0][1].con_addr) == 1) || __s2_len
>= 4)) ? __builtin_strcmp (a_engine->local_sdp_ip, ice_out
->cands[0][1].con_addr) : (__builtin_constant_p (a_engine->
local_sdp_ip) && ((size_t)(const void *)((a_engine->
local_sdp_ip) + 1) - (size_t)(const void *)(a_engine->local_sdp_ip
) == 1) && (__s1_len = __builtin_strlen (a_engine->
local_sdp_ip), __s1_len < 4) ? (__builtin_constant_p (ice_out
->cands[0][1].con_addr) && ((size_t)(const void *)
((ice_out->cands[0][1].con_addr) + 1) - (size_t)(const void
*)(ice_out->cands[0][1].con_addr) == 1) ? __builtin_strcmp
(a_engine->local_sdp_ip, ice_out->cands[0][1].con_addr
) : (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (ice_out->cands[0][1].con_addr); int
__result = (((const unsigned char *) (const char *) (a_engine
->local_sdp_ip))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (a_engine->local_sdp_ip))[1] - __s2[1]); if (__s1_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (a_engine->local_sdp_ip))[2] - __s2
[2]); if (__s1_len > 2 && __result == 0) __result =
(((const unsigned char *) (const char *) (a_engine->local_sdp_ip
))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (
ice_out->cands[0][1].con_addr) && ((size_t)(const void
*)((ice_out->cands[0][1].con_addr) + 1) - (size_t)(const void
*)(ice_out->cands[0][1].con_addr) == 1) && (__s2_len
= __builtin_strlen (ice_out->cands[0][1].con_addr), __s2_len
< 4) ? (__builtin_constant_p (a_engine->local_sdp_ip) &&
((size_t)(const void *)((a_engine->local_sdp_ip) + 1) - (
size_t)(const void *)(a_engine->local_sdp_ip) == 1) ? __builtin_strcmp
(a_engine->local_sdp_ip, ice_out->cands[0][1].con_addr
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (a_engine->local_sdp_ip); int __result
= (((const unsigned char *) (const char *) (ice_out->cands
[0][1].con_addr))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (ice_out->cands[0][1].con_addr))[1] - __s2[1]); if
(__s2_len > 1 && __result == 0) { __result = (((const
unsigned char *) (const char *) (ice_out->cands[0][1].con_addr
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (ice_out
->cands[0][1].con_addr))[3] - __s2[3]); } } __result; })))
) : __builtin_strcmp (a_engine->local_sdp_ip, ice_out->
cands[0][1].con_addr)))); })
6080 && a_engine->local_sdp_port != ice_out->cands[0][1].con_port) {
6081
6082 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ srflx raddr %s rport %d generation 0\n",
6083 tmp2, ice_out->cands[0][0].transport, c2,
6084 ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port + (a_engine->rtcp_mux > 0 ? 0 : 1),
6085 a_engine->local_sdp_ip, a_engine->local_sdp_port + (a_engine->rtcp_mux > 0 ? 0 : 1)
6086 );
6087 }
6088 }
6089
6090
6091
6092#ifdef GOOGLE_ICE
6093 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=ice-options:google-ice\n");
6094#endif
6095 }
6096
6097
6098 if (secure && !switch_channel_test_flag(session->channel, CF_DTLS)) {
6099 int i;
6100
6101 for (i = 0; smh->crypto_suite_order[i] != CRYPTO_INVALID; i++) {
6102 switch_rtp_crypto_key_type_t j = SUITES[smh->crypto_suite_order[i]].type;
6103
6104 if ((a_engine->crypto_type == j || a_engine->crypto_type == CRYPTO_INVALID) && !zstr(a_engine->ssec[j].local_crypto_key)_zstr(a_engine->ssec[j].local_crypto_key)) {
6105 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=crypto:%s\n", a_engine->ssec[j].local_crypto_key);
6106 }
6107 }
6108 //switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=encryption:optional\n");
6109 }
6110
6111 if (!cng_type) {
6112 //switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtpmap:%d CN/8000\n", cng_type);
6113 //} else {
6114 if (switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG)) {
6115 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=silenceSupp:off - - - -\n");
6116 }
6117 }
6118
6119 if (append_audio) {
6120 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "%s%s", append_audio, end_of(append_audio)*(*append_audio == '\0' ? append_audio : append_audio + strlen
(append_audio) - 1)
== '\n' ? "" : "\n");
6121 }
6122
6123 if (!cur_ptime) {
6124 cur_ptime = ptime;
6125 }
6126
6127 if (!noptime && cur_ptime) {
6128 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=ptime:%d\n", cur_ptime);
6129 }
6130
6131 local_sdp_audio_zrtp_hash = switch_core_media_get_zrtp_hash(session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_TRUE);
6132
6133 if (local_sdp_audio_zrtp_hash) {
6134 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 6134, (const char*)(session)
, SWITCH_LOG_DEBUG, "Adding audio a=zrtp-hash:%s\n", local_sdp_audio_zrtp_hash);
6135 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=zrtp-hash:%s\n", local_sdp_audio_zrtp_hash);
6136 }
6137
6138 if (!zstr(sr)_zstr(sr)) {
6139 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=%s\n", sr);
6140 }
6141}
6142
6143//?
6144SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_check_dtmf_type(switch_core_session_t *session)
6145{
6146 const char *val;
6147 switch_media_handle_t *smh;
6148
6149 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 6149, __PRETTY_FUNCTION__))
;
6150
6151 if (!(smh = session->media_handle)) {
6152 return;
6153 }
6154
6155 if ((val = switch_channel_get_variable(session->channel, "dtmf_type")switch_channel_get_variable_dup(session->channel, "dtmf_type"
, SWITCH_TRUE, -1)
)) {
6156 if (!strcasecmp(val, "rfc2833")) {
6157 smh->mparams->dtmf_type = DTMF_2833;
6158 } else if (!strcasecmp(val, "info")) {
6159 smh->mparams->dtmf_type = DTMF_INFO;
6160 } else if (!strcasecmp(val, "none")) {
6161 smh->mparams->dtmf_type = DTMF_NONE;
6162 }
6163 }
6164}
6165
6166//?
6167switch_status_t switch_core_media_sdp_map(const char *r_sdp, switch_event_t **fmtp, switch_event_t **pt)
6168{
6169 sdp_media_t *m;
6170 sdp_parser_t *parser = NULL((void*)0);
6171 sdp_session_t *sdp;
6172
6173 if (!(parser = sdp_parse(NULL((void*)0), r_sdp, (int) strlen(r_sdp), 0))) {
6174 return SWITCH_STATUS_FALSE;
6175 }
6176
6177 if (!(sdp = sdp_session(parser))) {
6178 sdp_parser_free(parser);
6179 return SWITCH_STATUS_FALSE;
6180 }
6181
6182 switch_event_create(&(*fmtp), SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("src/switch_core_media.c"
, (const char * )(const char *)__func__, 6182, &(*fmtp), SWITCH_EVENT_REQUEST_PARAMS
, ((void*)0))
;
6183 switch_event_create(&(*pt), SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("src/switch_core_media.c"
, (const char * )(const char *)__func__, 6183, &(*pt), SWITCH_EVENT_REQUEST_PARAMS
, ((void*)0))
;
6184
6185 for (m = sdp->sdp_media; m; m = m->m_next) {
6186 if (m->m_proto == sdp_proto_rtp) {
6187 sdp_rtpmap_t *map;
6188
6189 for (map = m->m_rtpmaps; map; map = map->rm_next) {
6190 if (map->rm_encoding) {
6191 char buf[25] = "";
6192 char key[128] = "";
6193 char *br = NULL((void*)0);
6194
6195 if (map->rm_fmtp) {
6196 if ((br = strstr(map->rm_fmtp, "bitrate="))) {
6197 br += 8;
6198 }
6199 }
6200
6201 switch_snprintf(buf, sizeof(buf), "%d", map->rm_pt);
6202
6203 if (br) {
6204 switch_snprintf(key, sizeof(key), "%s:%s", map->rm_encoding, br);
6205 } else {
6206 switch_snprintf(key, sizeof(key), "%s", map->rm_encoding);
6207 }
6208
6209 switch_event_add_header_string(*pt, SWITCH_STACK_BOTTOM, key, buf);
6210
6211 if (map->rm_fmtp) {
6212 switch_event_add_header_string(*fmtp, SWITCH_STACK_BOTTOM, key, map->rm_fmtp);
6213 }
6214 }
6215 }
6216 }
6217 }
6218
6219 sdp_parser_free(parser);
6220
6221 return SWITCH_STATUS_SUCCESS;
6222
6223}
6224
6225//?
6226SWITCH_DECLARE(void)__attribute__((visibility("default"))) voidswitch_core_media_set_local_sdp(switch_core_session_t *session, const char *sdp_str, switch_bool_t dup)
6227{
6228 switch_media_handle_t *smh;
6229
6230 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 6230, __PRETTY_FUNCTION__))
;
6231
6232 if (!(smh = session->media_handle)) {
6233 return;
6234 }
6235
6236 if (smh->sdp_mutex) switch_mutex_lock(smh->sdp_mutex);
6237 smh->mparams->local_sdp_str = dup ? switch_core_session_strdup(session, sdp_str)switch_core_perform_session_strdup(session, sdp_str, "src/switch_core_media.c"
, (const char *)__func__, 6237)
: (char *) sdp_str;
6238 switch_channel_set_variable(session->channel, "rtp_local_sdp_str", smh->mparams->local_sdp_str)switch_channel_set_variable_var_check(session->channel, "rtp_local_sdp_str"
, smh->mparams->local_sdp_str, SWITCH_TRUE)
;
6239 if (smh->sdp_mutex) switch_mutex_unlock(smh->sdp_mutex);
6240}
6241
6242
6243//?
6244#define SDPBUFLEN65536 65536
6245SWITCH_DECLARE(void)__attribute__((visibility("default"))) 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)
6246{
6247 char *buf;
6248 int ptime = 0;
6249 uint32_t rate = 0;
6250 uint32_t v_port;
6251 int use_cng = 1;
6252 const char *val;
6253 const char *family;
6254 const char *pass_fmtp = switch_channel_get_variable(session->channel, "rtp_video_fmtp")switch_channel_get_variable_dup(session->channel, "rtp_video_fmtp"
, SWITCH_TRUE, -1)
;
6255 const char *ov_fmtp = switch_channel_get_variable(session->channel, "rtp_force_video_fmtp")switch_channel_get_variable_dup(session->channel, "rtp_force_video_fmtp"
, SWITCH_TRUE, -1)
;
6256 const char *append_audio = switch_channel_get_variable(session->channel, "rtp_append_audio_sdp")switch_channel_get_variable_dup(session->channel, "rtp_append_audio_sdp"
, SWITCH_TRUE, -1)
;
6257 const char *append_video = switch_channel_get_variable(session->channel, "rtp_append_video_sdp")switch_channel_get_variable_dup(session->channel, "rtp_append_video_sdp"
, SWITCH_TRUE, -1)
;
6258 char srbuf[128] = "";
6259 const char *var_val;
6260 const char *username;
6261 const char *fmtp_out;
6262 const char *fmtp_out_var = switch_channel_get_variable(session->channel, "rtp_force_audio_fmtp")switch_channel_get_variable_dup(session->channel, "rtp_force_audio_fmtp"
, SWITCH_TRUE, -1)
;
6263 switch_event_t *map = NULL((void*)0), *ptmap = NULL((void*)0);
6264 //const char *b_sdp = NULL;
6265 //const char *local_audio_crypto_key = switch_core_session_local_crypto_key(session, SWITCH_MEDIA_TYPE_AUDIO);
6266 const char *local_sdp_audio_zrtp_hash = switch_core_media_get_zrtp_hash(session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_TRUE);
6267 const char *local_sdp_video_zrtp_hash = switch_core_media_get_zrtp_hash(session, SWITCH_MEDIA_TYPE_VIDEO, SWITCH_TRUE);
6268 const char *tmp;
6269 switch_rtp_engine_t *a_engine, *v_engine;
6270 switch_media_handle_t *smh;
6271 ice_t *ice_out;
6272 int vp8 = 0;
6273 int red = 0;
6274 payload_map_t *pmap;
6275 int is_outbound = switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND;
6276
6277 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 6277, __PRETTY_FUNCTION__))
;
6278
6279 if (!(smh = session->media_handle)) {
6280 return;
6281 }
6282
6283 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
6284 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
6285
6286 if (switch_true(switch_channel_get_variable(session->channel, "rtcp_mux")switch_channel_get_variable_dup(session->channel, "rtcp_mux"
, SWITCH_TRUE, -1)
)) {
6287 a_engine->rtcp_mux = 1;
6288 v_engine->rtcp_mux = 1;
6289 }
6290
6291 if (!smh->mparams->rtcp_audio_interval_msec) {
6292 smh->mparams->rtcp_audio_interval_msec = (char *)switch_channel_get_variable(session->channel, "rtcp_audio_interval_msec")switch_channel_get_variable_dup(session->channel, "rtcp_audio_interval_msec"
, SWITCH_TRUE, -1)
;
6293 }
6294
6295 if (!smh->mparams->rtcp_video_interval_msec) {
6296 smh->mparams->rtcp_video_interval_msec = (char *)switch_channel_get_variable(session->channel, "rtcp_video_interval_msec")switch_channel_get_variable_dup(session->channel, "rtcp_video_interval_msec"
, SWITCH_TRUE, -1)
;
6297 }
6298
6299 if (dtls_ok(session) && (tmp = switch_channel_get_variable(smh->session->channel, "webrtc_enable_dtls")switch_channel_get_variable_dup(smh->session->channel, "webrtc_enable_dtls"
, SWITCH_TRUE, -1)
) && switch_false(tmp)) {
6300 switch_channel_clear_flag(smh->session->channel, CF_DTLS_OK);
6301 switch_channel_clear_flag(smh->session->channel, CF_DTLS);
6302 }
6303
6304 if (is_outbound || switch_channel_test_flag(session->channel, CF_RECOVERING) ||
6305 switch_channel_test_flag(session->channel, CF_3PCC)) {
6306 if (!switch_channel_test_flag(session->channel, CF_WEBRTC) &&
6307 switch_true(switch_channel_get_variable(session->channel, "media_webrtc")switch_channel_get_variable_dup(session->channel, "media_webrtc"
, SWITCH_TRUE, -1)
)) {
6308 switch_channel_set_flag(session->channel, CF_WEBRTC)switch_channel_set_flag_value(session->channel, CF_WEBRTC,
1)
;
6309 switch_channel_set_flag(session->channel, CF_ICE)switch_channel_set_flag_value(session->channel, CF_ICE, 1);
6310 smh->mparams->rtcp_audio_interval_msec = "5000";
6311 smh->mparams->rtcp_video_interval_msec = "5000";
6312 }
6313
6314 if ( switch_rtp_has_dtls() && dtls_ok(session)) {
6315 if (switch_channel_test_flag(session->channel, CF_WEBRTC) ||
6316 switch_true(switch_channel_get_variable(smh->session->channel, "rtp_use_dtls")switch_channel_get_variable_dup(smh->session->channel, "rtp_use_dtls"
, SWITCH_TRUE, -1)
)) {
6317 switch_channel_set_flag(smh->session->channel, CF_DTLS)switch_channel_set_flag_value(smh->session->channel, CF_DTLS
, 1)
;
6318 switch_channel_set_flag(smh->session->channel, CF_SECURE)switch_channel_set_flag_value(smh->session->channel, CF_SECURE
, 1)
;
6319 generate_local_fingerprint(smh, SWITCH_MEDIA_TYPE_AUDIO);
6320 }
6321 }
6322 switch_core_session_parse_crypto_prefs(session);
6323 switch_core_session_check_outgoing_crypto(session);
6324 }
6325
6326 fmtp_out = a_engine->cur_payload_map->fmtp_out;
6327 username = smh->mparams->sdp_username;
6328
6329
6330 switch_zmalloc(buf, SDPBUFLEN)(void)((((buf = calloc(1, (65536)))) ? (void) (0) : __assert_fail
("(buf = calloc(1, (65536)))", "src/switch_core_media.c", 6330
, __PRETTY_FUNCTION__)),buf)
;
6331
6332 switch_core_media_check_dtmf_type(session);
6333
6334 if (switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG) ||
6335 ((val = switch_channel_get_variable(session->channel, "supress_cng")switch_channel_get_variable_dup(session->channel, "supress_cng"
, SWITCH_TRUE, -1)
) && switch_true(val)) ||
6336 ((val = switch_channel_get_variable(session->channel, "suppress_cng")switch_channel_get_variable_dup(session->channel, "suppress_cng"
, SWITCH_TRUE, -1)
) && switch_true(val))) {
6337 use_cng = 0;
6338 smh->mparams->cng_pt = 0;
6339 }
6340
6341
6342
6343
6344 if (!smh->payload_space) {
6345 int i;
6346
6347 /* it could be 98 but chrome reserves 98 and 99 for some internal stuff even though they should not.
6348 Everyone expects dtmf to be at 101 and Its not worth the trouble so we'll start at 102 */
6349 smh->payload_space = 102;
6350
6351 for (i = 0; i < smh->mparams->num_codecs; i++) {
6352 smh->ianacodes[i] = smh->codecs[i]->ianacode;
6353 }
6354
6355 if (sdp_type == SDP_TYPE_REQUEST) {
6356 switch_core_session_t *orig_session = NULL((void*)0);
6357
6358 switch_core_session_get_partner(session, &orig_session)switch_core_session_perform_get_partner(session, &orig_session
, "src/switch_core_media.c", (const char *)__func__, 6358)
;
6359
6360 for (i = 0; i < smh->mparams->num_codecs; i++) {
6361 const switch_codec_implementation_t *imp = smh->codecs[i];
6362 switch_payload_t orig_pt = 0;
6363 char *orig_fmtp = NULL((void*)0);
6364
6365 //smh->ianacodes[i] = imp->ianacode;
6366
6367 if (smh->ianacodes[i] > 64) {
6368 if (smh->mparams->dtmf_type == DTMF_2833 && smh->mparams->te > 95 && smh->mparams->te == smh->payload_space) {
6369 smh->payload_space++;
6370 }
6371 if (!switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG) &&
6372 smh->mparams->cng_pt && use_cng && smh->mparams->cng_pt == smh->payload_space) {
6373 smh->payload_space++;
6374 }
6375
6376 if (orig_session &&
6377 switch_core_session_get_payload_code(orig_session,
6378 imp->codec_type == SWITCH_CODEC_TYPE_AUDIO ? SWITCH_MEDIA_TYPE_AUDIO : SWITCH_MEDIA_TYPE_VIDEO,
6379 imp->iananame, imp->samples_per_second, &orig_pt, NULL((void*)0), &orig_fmtp) == SWITCH_STATUS_SUCCESS) {
6380 if (orig_pt == smh->mparams->te) {
6381 smh->mparams->te = (switch_payload_t)smh->payload_space++;
6382 }
6383
6384 smh->ianacodes[i] = orig_pt;
6385
6386 if (orig_fmtp) {
6387 smh->fmtps[i] = switch_core_session_strdup(session, orig_fmtp)switch_core_perform_session_strdup(session, orig_fmtp, "src/switch_core_media.c"
, (const char *)__func__, 6387)
;
6388 }
6389 } else {
6390 smh->ianacodes[i] = (switch_payload_t)smh->payload_space++;
6391 }
6392 }
6393
6394 switch_core_media_add_payload_map(session,
6395 imp->codec_type == SWITCH_CODEC_TYPE_AUDIO ? SWITCH_MEDIA_TYPE_AUDIO : SWITCH_MEDIA_TYPE_VIDEO,
6396 imp->iananame,
6397 NULL((void*)0),
6398 sdp_type,
6399 smh->ianacodes[i],
6400 imp->samples_per_second,
6401 imp->microseconds_per_packet / 1000,
6402 imp->number_of_channels,
6403 SWITCH_FALSE);
6404 }
6405
6406
6407 if (orig_session) {
6408 switch_core_session_rwunlock(orig_session);
6409 }
6410 }
6411 }
6412
6413 if (fmtp_out_var) {
6414 fmtp_out = fmtp_out_var;
6415 }
6416
6417 val = switch_channel_get_variable(session->channel, "verbose_sdp")switch_channel_get_variable_dup(session->channel, "verbose_sdp"
, SWITCH_TRUE, -1)
;
6418
6419 if (!val || switch_true(val)) {
6420 switch_channel_set_flag(session->channel, CF_VERBOSE_SDP)switch_channel_set_flag_value(session->channel, CF_VERBOSE_SDP
, 1)
;
6421 }
6422
6423 if (!force && !ip && zstr(sr)_zstr(sr)
6424 && (switch_channel_test_flag(session->channel, CF_PROXY_MODE) || switch_channel_test_flag(session->channel, CF_PROXY_MEDIA))) {
6425 switch_safe_free(buf)if (buf) {free(buf);buf=((void*)0);};
6426 return;
6427 }
6428
6429 if (!ip) {
6430 if (!(ip = a_engine->adv_sdp_ip)) {
6431 ip = a_engine->proxy_sdp_ip;
6432 }
6433 }
6434
6435 if (!ip) {
6436 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_media.c", (const char
*)__func__, 6436, ((void*)0)
, SWITCH_LOG_CRIT, "%s NO IP!\n", switch_channel_get_name(session->channel));
6437 switch_safe_free(buf)if (buf) {free(buf);buf=((void*)0);};
6438 return;
6439 }
6440
6441 if (!port) {
6442 if (!(port = a_engine->adv_sdp_port)) {
6443 port = a_engine->proxy_sdp_port;
6444 }
6445 }
6446
6447 if (!port) {
6448 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_media.c", (const char
*)__func__, 6448, ((void*)0)
, SWITCH_LOG_CRIT, "%s NO PORT!\n", switch_channel_get_name(session->channel));
6449 switch_safe_free(buf)if (buf) {free(buf);buf=((void*)0);};
6450 return;
6451 }
6452
6453 //if (!a_engine->cur_payload_map->rm_encoding && (b_sdp = switch_channel_get_variable(session->channel, SWITCH_B_SDP_VARIABLE))) {
6454 //switch_core_media_sdp_map(b_sdp, &map, &ptmap);
6455 //}
6456
6457 if (zstr(sr)_zstr(sr)) {
6458 if ((var_val = switch_channel_get_variable(session->channel, "media_audio_mode")switch_channel_get_variable_dup(session->channel, "media_audio_mode"
, SWITCH_TRUE, -1)
)) {
6459 sr = var_val;
6460 } else {
6461 sr = "sendrecv";
6462 }
6463 }
6464
6465 if (!smh->owner_id) {
6466 smh->owner_id = (uint32_t) switch_epoch_time_now(NULL((void*)0)) - port;
6467 }
6468
6469 if (!smh->session_id) {
6470 smh->session_id = smh->owner_id;
6471 }
6472
6473 if (switch_true(switch_channel_get_variable_dup(session->channel, "drop_dtmf", SWITCH_FALSE, -1))) {
6474 switch_channel_set_flag(session->channel, CF_DROP_DTMF)switch_channel_set_flag_value(session->channel, CF_DROP_DTMF
, 1)
;
6475 }
6476
6477 smh->session_id++;
6478
6479 if ((smh->mparams->ndlb & SM_NDLB_SENDRECV_IN_SESSION) ||
6480 ((var_val = switch_channel_get_variable(session->channel, "ndlb_sendrecv_in_session")switch_channel_get_variable_dup(session->channel, "ndlb_sendrecv_in_session"
, SWITCH_TRUE, -1)
) && switch_true(var_val))) {
6481 if (!zstr(sr)_zstr(sr)) {
6482 switch_snprintf(srbuf, sizeof(srbuf), "a=%s\n", sr);
6483 }
6484 sr = NULL((void*)0);
6485 }
6486
6487 family = strchr(ip, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(ip) && (':') == '\0' ? (char *) __rawmemchr (ip, ':'
) : __builtin_strchr (ip, ':')))
? "IP6" : "IP4";
6488 switch_snprintf(buf, SDPBUFLEN65536,
6489 "v=0\n"
6490 "o=%s %010u %010u IN %s %s\n"
6491 "s=%s\n"
6492 "c=IN %s %s\n"
6493 "t=0 0\n"
6494 "%s",
6495 username, smh->owner_id, smh->session_id, family, ip, username, family, ip, srbuf);
6496
6497
6498 if (switch_channel_test_flag(smh->session->channel, CF_ICE)) {
6499 gen_ice(session, SWITCH_MEDIA_TYPE_AUDIO, ip, port);
6500 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=msid-semantic: WMS %s\n", smh->msid);
6501 }
6502
6503
6504 if (a_engine->codec_negotiated) {
6505 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "m=audio %d %s", port,
6506 get_media_profile_name(session, !a_engine->no_crypto &&
6507 (switch_channel_test_flag(session->channel, CF_DTLS) || a_engine->crypto_type != CRYPTO_INVALID)));
6508
6509
6510 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), " %d", a_engine->cur_payload_map->pt);
6511
6512
6513 if (switch_media_handle_test_media_flag(smh, SCMF_MULTI_ANSWER_AUDIO)) {
6514 switch_mutex_lock(smh->sdp_mutex);
6515 for (pmap = a_engine->cur_payload_map; pmap && pmap->allocated; pmap = pmap->next) {
6516 if (pmap->pt != a_engine->cur_payload_map->pt) {
6517 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), " %d", pmap->pt);
6518 }
6519 }
6520 switch_mutex_unlock(smh->sdp_mutex);
6521 }
6522
6523 if ((smh->mparams->dtmf_type == DTMF_2833 || switch_media_handle_test_media_flag(smh, SCMF_LIBERAL_DTMF) ||
6524 switch_channel_test_flag(session->channel, CF_LIBERAL_DTMF)) && smh->mparams->te > 95) {
6525 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), " %d", smh->mparams->te);
6526 }
6527
6528 if (!switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG) && smh->mparams->cng_pt && use_cng) {
6529 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), " %d", smh->mparams->cng_pt);
6530 }
6531
6532 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "\n");
6533
6534
6535 rate = a_engine->cur_payload_map->adv_rm_rate;
6536
6537 if (!a_engine->cur_payload_map->adv_channels) {
6538 a_engine->cur_payload_map->adv_channels = get_channels(a_engine->cur_payload_map->rm_encoding, 1);
6539 }
6540
6541 if (a_engine->cur_payload_map->adv_channels > 1) {
6542 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=rtpmap:%d %s/%d/%d\n",
6543 a_engine->cur_payload_map->agreed_pt, a_engine->cur_payload_map->rm_encoding, rate, a_engine->cur_payload_map->adv_channels);
6544 } else {
6545 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=rtpmap:%d %s/%d\n",
6546 a_engine->cur_payload_map->agreed_pt, a_engine->cur_payload_map->rm_encoding, rate);
6547 }
6548
6549 if (fmtp_out) {
6550 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=fmtp:%d %s\n", a_engine->cur_payload_map->agreed_pt, fmtp_out);
6551 }
6552
6553 if (switch_media_handle_test_media_flag(smh, SCMF_MULTI_ANSWER_AUDIO)) {
6554 switch_mutex_lock(smh->sdp_mutex);
6555 for (pmap = a_engine->cur_payload_map; pmap && pmap->allocated; pmap = pmap->next) {
6556 if (pmap->pt != a_engine->cur_payload_map->pt) {
6557 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=rtpmap:%d %s/%ld\n",
6558 pmap->pt, pmap->iananame,
6559 pmap->rate);
6560 }
6561 }
6562 switch_mutex_unlock(smh->sdp_mutex);
6563 }
6564
6565
6566 if (a_engine->read_codec.implementation && !ptime) {
6567 ptime = a_engine->read_codec.implementation->microseconds_per_packet / 1000;
6568 }
6569
6570
6571 if ((smh->mparams->dtmf_type == DTMF_2833 || switch_media_handle_test_media_flag(smh, SCMF_LIBERAL_DTMF) ||
6572 switch_channel_test_flag(session->channel, CF_LIBERAL_DTMF))
6573 && smh->mparams->te > 95) {
6574 if (switch_channel_test_flag(session->channel, CF_WEBRTC)) {
6575 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=rtpmap:%d telephone-event/8000\n", smh->mparams->te);
6576 } else {
6577 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=rtpmap:%d telephone-event/8000\na=fmtp:%d 0-16\n", smh->mparams->te, smh->mparams->te);
6578 }
6579 }
6580
6581 if (switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG)) {
6582 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=silenceSupp:off - - - -\n");
6583 } else if (smh->mparams->cng_pt && use_cng) {
6584 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=rtpmap:%d CN/8000\n", smh->mparams->cng_pt);
6585
6586 if (!a_engine->codec_negotiated) {
6587 smh->mparams->cng_pt = 0;
6588 }
6589 }
6590
6591 if (append_audio) {
6592 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "%s%s", append_audio, end_of(append_audio)*(*append_audio == '\0' ? append_audio : append_audio + strlen
(append_audio) - 1)
== '\n' ? "" : "\n");
6593 }
6594
6595 if (ptime) {
6596 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=ptime:%d\n", ptime);
6597 }
6598
6599
6600 if (local_sdp_audio_zrtp_hash) {
6601 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 6601, (const char*)(session)
, SWITCH_LOG_DEBUG, "Adding audio a=zrtp-hash:%s\n",
6602 local_sdp_audio_zrtp_hash);
6603 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=zrtp-hash:%s\n",
6604 local_sdp_audio_zrtp_hash);
6605 }
6606
6607 if (!zstr(sr)_zstr(sr)) {
6608 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=%s\n", sr);
6609 }
6610
6611
6612 if (!zstr(a_engine->local_dtls_fingerprint.type)_zstr(a_engine->local_dtls_fingerprint.type)) {
6613 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=fingerprint:%s %s\n", a_engine->local_dtls_fingerprint.type,
6614 a_engine->local_dtls_fingerprint.str);
6615 }
6616
6617 if (smh->mparams->rtcp_audio_interval_msec) {
6618 if (a_engine->rtcp_mux > 0) {
6619 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=rtcp-mux\n");
6620 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=rtcp:%d IN %s %s\n", port, family, ip);
6621 } else {
6622 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=rtcp:%d IN %s %s\n", port + 1, family, ip);
6623 }
6624 }
6625
6626 //switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u\n", a_engine->ssrc);
6627
6628 if (a_engine->ice_out.cands[0][0].ready) {
6629 char tmp1[11] = "";
6630 char tmp2[11] = "";
6631 uint32_t c1 = (2^24)*126 + (2^8)*65535 + (2^0)*(256 - 1);
6632 uint32_t c2 = (2^24)*126 + (2^8)*65535 + (2^0)*(256 - 2);
6633 uint32_t c3 = (2^24)*126 + (2^8)*65534 + (2^0)*(256 - 1);
6634 uint32_t c4 = (2^24)*126 + (2^8)*65534 + (2^0)*(256 - 2);
6635
6636 tmp1[10] = '\0';
6637 tmp2[10] = '\0';
6638 switch_stun_random_string(tmp1, 10, "0123456789");
6639 switch_stun_random_string(tmp2, 10, "0123456789");
6640
6641 ice_out = &a_engine->ice_out;
6642
6643 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=ssrc:%u cname:%s\n", a_engine->ssrc, smh->cname);
6644 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=ssrc:%u msid:%s a0\n", a_engine->ssrc, smh->msid);
6645 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=ssrc:%u mslabel:%s\n", a_engine->ssrc, smh->msid);
6646 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=ssrc:%u label:%sa0\n", a_engine->ssrc, smh->msid);
6647
6648
6649
6650 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=ice-ufrag:%s\n", ice_out->ufrag);
6651 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=ice-pwd:%s\n", ice_out->pwd);
6652
6653
6654 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=candidate:%s 1 %s %u %s %d typ host generation 0\n",
6655 tmp1, ice_out->cands[0][0].transport, c1,
6656 ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port
6657 );
6658
6659 if (!zstr(a_engine->local_sdp_ip)_zstr(a_engine->local_sdp_ip) && !zstr(ice_out->cands[0][0].con_addr)_zstr(ice_out->cands[0][0].con_addr) &&
6660 strcmp(a_engine->local_sdp_ip, ice_out->cands[0][0].con_addr)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(a_engine->local_sdp_ip) && __builtin_constant_p (
ice_out->cands[0][0].con_addr) && (__s1_len = __builtin_strlen
(a_engine->local_sdp_ip), __s2_len = __builtin_strlen (ice_out
->cands[0][0].con_addr), (!((size_t)(const void *)((a_engine
->local_sdp_ip) + 1) - (size_t)(const void *)(a_engine->
local_sdp_ip) == 1) || __s1_len >= 4) && (!((size_t
)(const void *)((ice_out->cands[0][0].con_addr) + 1) - (size_t
)(const void *)(ice_out->cands[0][0].con_addr) == 1) || __s2_len
>= 4)) ? __builtin_strcmp (a_engine->local_sdp_ip, ice_out
->cands[0][0].con_addr) : (__builtin_constant_p (a_engine->
local_sdp_ip) && ((size_t)(const void *)((a_engine->
local_sdp_ip) + 1) - (size_t)(const void *)(a_engine->local_sdp_ip
) == 1) && (__s1_len = __builtin_strlen (a_engine->
local_sdp_ip), __s1_len < 4) ? (__builtin_constant_p (ice_out
->cands[0][0].con_addr) && ((size_t)(const void *)
((ice_out->cands[0][0].con_addr) + 1) - (size_t)(const void
*)(ice_out->cands[0][0].con_addr) == 1) ? __builtin_strcmp
(a_engine->local_sdp_ip, ice_out->cands[0][0].con_addr
) : (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (ice_out->cands[0][0].con_addr); int
__result = (((const unsigned char *) (const char *) (a_engine
->local_sdp_ip))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (a_engine->local_sdp_ip))[1] - __s2[1]); if (__s1_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (a_engine->local_sdp_ip))[2] - __s2
[2]); if (__s1_len > 2 && __result == 0) __result =
(((const unsigned char *) (const char *) (a_engine->local_sdp_ip
))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (
ice_out->cands[0][0].con_addr) && ((size_t)(const void
*)((ice_out->cands[0][0].con_addr) + 1) - (size_t)(const void
*)(ice_out->cands[0][0].con_addr) == 1) && (__s2_len
= __builtin_strlen (ice_out->cands[0][0].con_addr), __s2_len
< 4) ? (__builtin_constant_p (a_engine->local_sdp_ip) &&
((size_t)(const void *)((a_engine->local_sdp_ip) + 1) - (
size_t)(const void *)(a_engine->local_sdp_ip) == 1) ? __builtin_strcmp
(a_engine->local_sdp_ip, ice_out->cands[0][0].con_addr
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (a_engine->local_sdp_ip); int __result
= (((const unsigned char *) (const char *) (ice_out->cands
[0][0].con_addr))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (ice_out->cands[0][0].con_addr))[1] - __s2[1]); if
(__s2_len > 1 && __result == 0) { __result = (((const
unsigned char *) (const char *) (ice_out->cands[0][0].con_addr
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (ice_out
->cands[0][0].con_addr))[3] - __s2[3]); } } __result; })))
) : __builtin_strcmp (a_engine->local_sdp_ip, ice_out->
cands[0][0].con_addr)))); })
6661 && a_engine->local_sdp_port != ice_out->cands[0][0].con_port) {
6662
6663 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=candidate:%s 1 %s %u %s %d typ srflx raddr %s rport %d generation 0\n",
6664 tmp2, ice_out->cands[0][0].transport, c3,
6665 ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port,
6666 a_engine->local_sdp_ip, a_engine->local_sdp_port
6667 );
6668 }
6669
6670
6671 if (a_engine->rtcp_mux < 1 || is_outbound ||
6672 switch_channel_test_flag(session->channel, CF_RECOVERING)) {
6673
6674 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ host generation 0\n",
6675 tmp1, ice_out->cands[0][0].transport, c2,
6676 ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port + (a_engine->rtcp_mux > 0 ? 0 : 1)
6677 );
6678
6679
6680
6681 if (!zstr(a_engine->local_sdp_ip)_zstr(a_engine->local_sdp_ip) && !zstr(ice_out->cands[0][0].con_addr)_zstr(ice_out->cands[0][0].con_addr) &&
6682 strcmp(a_engine->local_sdp_ip, ice_out->cands[0][0].con_addr)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(a_engine->local_sdp_ip) && __builtin_constant_p (
ice_out->cands[0][0].con_addr) && (__s1_len = __builtin_strlen
(a_engine->local_sdp_ip), __s2_len = __builtin_strlen (ice_out
->cands[0][0].con_addr), (!((size_t)(const void *)((a_engine
->local_sdp_ip) + 1) - (size_t)(const void *)(a_engine->
local_sdp_ip) == 1) || __s1_len >= 4) && (!((size_t
)(const void *)((ice_out->cands[0][0].con_addr) + 1) - (size_t
)(const void *)(ice_out->cands[0][0].con_addr) == 1) || __s2_len
>= 4)) ? __builtin_strcmp (a_engine->local_sdp_ip, ice_out
->cands[0][0].con_addr) : (__builtin_constant_p (a_engine->
local_sdp_ip) && ((size_t)(const void *)((a_engine->
local_sdp_ip) + 1) - (size_t)(const void *)(a_engine->local_sdp_ip
) == 1) && (__s1_len = __builtin_strlen (a_engine->
local_sdp_ip), __s1_len < 4) ? (__builtin_constant_p (ice_out
->cands[0][0].con_addr) && ((size_t)(const void *)
((ice_out->cands[0][0].con_addr) + 1) - (size_t)(const void
*)(ice_out->cands[0][0].con_addr) == 1) ? __builtin_strcmp
(a_engine->local_sdp_ip, ice_out->cands[0][0].con_addr
) : (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (ice_out->cands[0][0].con_addr); int
__result = (((const unsigned char *) (const char *) (a_engine
->local_sdp_ip))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (a_engine->local_sdp_ip))[1] - __s2[1]); if (__s1_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (a_engine->local_sdp_ip))[2] - __s2
[2]); if (__s1_len > 2 && __result == 0) __result =
(((const unsigned char *) (const char *) (a_engine->local_sdp_ip
))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (
ice_out->cands[0][0].con_addr) && ((size_t)(const void
*)((ice_out->cands[0][0].con_addr) + 1) - (size_t)(const void
*)(ice_out->cands[0][0].con_addr) == 1) && (__s2_len
= __builtin_strlen (ice_out->cands[0][0].con_addr), __s2_len
< 4) ? (__builtin_constant_p (a_engine->local_sdp_ip) &&
((size_t)(const void *)((a_engine->local_sdp_ip) + 1) - (
size_t)(const void *)(a_engine->local_sdp_ip) == 1) ? __builtin_strcmp
(a_engine->local_sdp_ip, ice_out->cands[0][0].con_addr
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (a_engine->local_sdp_ip); int __result
= (((const unsigned char *) (const char *) (ice_out->cands
[0][0].con_addr))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (ice_out->cands[0][0].con_addr))[1] - __s2[1]); if
(__s2_len > 1 && __result == 0) { __result = (((const
unsigned char *) (const char *) (ice_out->cands[0][0].con_addr
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (ice_out
->cands[0][0].con_addr))[3] - __s2[3]); } } __result; })))
) : __builtin_strcmp (a_engine->local_sdp_ip, ice_out->
cands[0][0].con_addr)))); })
6683 && a_engine->local_sdp_port != ice_out->cands[0][0].con_port) {
6684
6685 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ srflx raddr %s rport %d generation 0\n",
6686 tmp2, ice_out->cands[0][0].transport, c4,
6687 ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port + (a_engine->rtcp_mux > 0 ? 0 : 1),
6688 a_engine->local_sdp_ip, a_engine->local_sdp_port + (a_engine->rtcp_mux > 0 ? 0 : 1)
6689 );
6690 }
6691 }
6692
6693
6694#ifdef GOOGLE_ICE
6695 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=ice-options:google-ice\n");
6696#endif
6697 }
6698
6699 if (a_engine->crypto_type != CRYPTO_INVALID && !switch_channel_test_flag(session->channel, CF_DTLS) &&
6700 !zstr(a_engine->ssec[a_engine->crypto_type].local_crypto_key)_zstr(a_engine->ssec[a_engine->crypto_type].local_crypto_key
)
&& switch_channel_test_flag(session->channel, CF_SECURE)) {
6701
6702 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=crypto:%s\n", a_engine->ssec[a_engine->crypto_type].local_crypto_key);
6703 //switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=encryption:optional\n");
6704 }
6705
6706 } else if (smh->mparams->num_codecs) {
6707 int i;
6708 int cur_ptime = 0, this_ptime = 0, cng_type = 0;
6709 const char *mult;
6710
6711 if (!switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG) && smh->mparams->cng_pt && use_cng) {
6712 cng_type = smh->mparams->cng_pt;
6713
6714 if (!a_engine->codec_negotiated) {
6715 smh->mparams->cng_pt = 0;
6716 }
6717 }
6718
6719 mult = switch_channel_get_variable(session->channel, "sdp_m_per_ptime")switch_channel_get_variable_dup(session->channel, "sdp_m_per_ptime"
, SWITCH_TRUE, -1)
;
6720
6721
6722 if (switch_channel_test_flag(session->channel, CF_WEBRTC) || (mult && switch_false(mult))) {
6723 char *bp = buf;
6724 int both = (switch_channel_test_flag(session->channel, CF_WEBRTC) || switch_channel_test_flag(session->channel, CF_DTLS)) ? 0 : 1;
6725
6726 if ((!a_engine->no_crypto && switch_channel_test_flag(session->channel, CF_SECURE)) ||
6727 switch_channel_test_flag(session->channel, CF_DTLS)) {
6728 generate_m(session, buf, SDPBUFLEN65536, port, family, ip, 0, append_audio, sr, use_cng, cng_type, map, 1, sdp_type);
6729 bp = (buf + strlen(buf));
6730
6731 if (smh->crypto_mode == CRYPTO_MODE_MANDATORY) {
6732 both = 0;
6733 }
6734
6735 }
6736
6737 if (both) {
6738 generate_m(session, bp, SDPBUFLEN65536 - strlen(buf), port, family, ip, 0, append_audio, sr, use_cng, cng_type, map, 0, sdp_type);
6739 }
6740
6741 } else {
6742
6743 for (i = 0; i < smh->mparams->num_codecs; i++) {
6744 const switch_codec_implementation_t *imp = smh->codecs[i];
6745
6746 if (imp->codec_type != SWITCH_CODEC_TYPE_AUDIO) {
6747 continue;
6748 }
6749
6750 this_ptime = imp->microseconds_per_packet / 1000;
6751
6752 if (!strcasecmp(imp->iananame, "ilbc") || !strcasecmp(imp->iananame, "isac")) {
6753 this_ptime = 20;
6754 }
6755
6756 if (cur_ptime != this_ptime) {
6757 char *bp = buf;
6758 int both = 1;
6759
6760 cur_ptime = this_ptime;
6761
6762 if ((!a_engine->no_crypto && switch_channel_test_flag(session->channel, CF_SECURE)) ||
6763 switch_channel_test_flag(session->channel, CF_DTLS)) {
6764 generate_m(session, bp, SDPBUFLEN65536 - strlen(buf), port, family, ip, cur_ptime, append_audio, sr, use_cng, cng_type, map, 1, sdp_type);
6765 bp = (buf + strlen(buf));
6766
6767 if (smh->crypto_mode == CRYPTO_MODE_MANDATORY) {
6768 both = 0;
6769 }
6770 }
6771
6772 if (switch_channel_test_flag(session->channel, CF_WEBRTC) || switch_channel_test_flag(session->channel, CF_DTLS)) {
6773 both = 0;
6774 }
6775
6776 if (both) {
6777 generate_m(session, bp, SDPBUFLEN65536 - strlen(buf), port, family, ip, cur_ptime, append_audio, sr, use_cng, cng_type, map, 0, sdp_type);
6778 }
6779 }
6780
6781 }
6782 }
6783
6784 }
6785
6786 if (switch_channel_test_flag(session->channel, CF_VIDEO_POSSIBLE)) {
6787 if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
6788 if (switch_channel_test_flag(smh->session->channel, CF_DTLS)) {
6789 v_engine->no_crypto = 1;
6790 }
6791 }
6792
6793
6794 if (!v_engine->local_sdp_port) {
6795 switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_VIDEO, 0);
6796 }
6797
6798 if (switch_channel_test_flag(session->channel, CF_WEBRTC)) {
6799 switch_media_handle_set_media_flag(smh, SCMF_MULTI_ANSWER_VIDEO);
6800 }
6801
6802 if ((v_port = v_engine->adv_sdp_port)) {
6803 int loops;
6804
6805 for (loops = 0; loops < 2; loops++) {
6806
6807 if (switch_channel_test_flag(smh->session->channel, CF_ICE)) {
6808 gen_ice(session, SWITCH_MEDIA_TYPE_VIDEO, ip, (switch_port_t)v_port);
6809 }
6810
6811
6812 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "m=video %d %s",
6813 v_port,
6814 get_media_profile_name(session,
6815 (loops == 0 && switch_channel_test_flag(session->channel, CF_SECURE)
6816 && switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) ||
6817 a_engine->crypto_type != CRYPTO_INVALID || switch_channel_test_flag(session->channel, CF_DTLS)));
6818
6819
6820
6821
6822 /*****************************/
6823 if (v_engine->codec_negotiated) {
6824 payload_map_t *pmap;
6825 switch_core_media_set_video_codec(session, 0);
6826 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), " %d", v_engine->cur_payload_map->agreed_pt);
6827
6828 if (switch_media_handle_test_media_flag(smh, SCMF_MULTI_ANSWER_VIDEO)) {
6829 switch_mutex_lock(smh->sdp_mutex);
6830 for (pmap = v_engine->cur_payload_map; pmap && pmap->allocated; pmap = pmap->next) {
6831 if (pmap->pt != v_engine->cur_payload_map->pt) {
6832 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), " %d", pmap->pt);
6833 }
6834 }
6835 switch_mutex_unlock(smh->sdp_mutex);
6836 }
6837
6838 } else if (smh->mparams->num_codecs) {
6839 int i;
6840 int already_did[128] = { 0 };
6841 for (i = 0; i < smh->mparams->num_codecs; i++) {
6842 const switch_codec_implementation_t *imp = smh->codecs[i];
6843
6844
6845 if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO) {
6846 continue;
6847 }
6848
6849 if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_INBOUND &&
6850 switch_channel_test_flag(session->channel, CF_NOVIDEO)) {
6851 continue;
6852 }
6853
6854 if (smh->ianacodes[i] < 128) {
6855 if (already_did[smh->ianacodes[i]]) {
6856 continue;
6857 }
6858 already_did[smh->ianacodes[i]] = 1;
6859 }
6860
6861 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), " %d", smh->ianacodes[i]);
6862
6863 if (!ptime) {
6864 ptime = imp->microseconds_per_packet / 1000;
6865 }
6866 }
6867 }
6868
6869 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "\n");
6870
6871
6872 if (v_engine->codec_negotiated) {
6873 const char *of;
6874 payload_map_t *pmap;
6875
6876 if (!strcasecmp(v_engine->cur_payload_map->rm_encoding, "VP8")) {
6877 vp8 = v_engine->cur_payload_map->pt;
6878 }
6879
6880 if (!strcasecmp(v_engine->cur_payload_map->rm_encoding, "red")) {
6881 red = v_engine->cur_payload_map->pt;
6882 }
6883
6884 rate = v_engine->cur_payload_map->rm_rate;
6885 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=rtpmap:%d %s/%ld\n",
6886 v_engine->cur_payload_map->pt, v_engine->cur_payload_map->rm_encoding,
6887 v_engine->cur_payload_map->rm_rate);
6888
6889
6890 if (switch_channel_test_flag(session->channel, CF_RECOVERING)) {
6891 pass_fmtp = v_engine->cur_payload_map->rm_fmtp;
6892 } else {
6893
6894 pass_fmtp = NULL((void*)0);
6895
6896 if (switch_channel_get_partner_uuid(session->channel)) {
6897 if ((of = switch_channel_get_variable_partner(session->channel, "rtp_video_fmtp"))) {
6898 pass_fmtp = of;
6899 }
6900 }
6901
6902 if (ov_fmtp) {
6903 pass_fmtp = ov_fmtp;
6904 } else { //if (switch_true(switch_channel_get_variable_dup(session->channel, "rtp_mirror_fmtp", SWITCH_FALSE, -1))) {
6905 // seems to break eyebeam at least...
6906 pass_fmtp = switch_channel_get_variable(session->channel, "rtp_video_fmtp")switch_channel_get_variable_dup(session->channel, "rtp_video_fmtp"
, SWITCH_TRUE, -1)
;
6907 }
6908 }
6909
6910 if (pass_fmtp) {
6911 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=fmtp:%d %s\n", v_engine->cur_payload_map->pt, pass_fmtp);
6912 }
6913
6914
6915 if (switch_media_handle_test_media_flag(smh, SCMF_MULTI_ANSWER_VIDEO)) {
6916 switch_mutex_lock(smh->sdp_mutex);
6917 for (pmap = v_engine->cur_payload_map; pmap && pmap->allocated; pmap = pmap->next) {
6918 if (pmap->pt != v_engine->cur_payload_map->pt && pmap->negotiated) {
6919 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=rtpmap:%d %s/%ld\n",
6920 pmap->pt, pmap->iananame, pmap->rate);
6921
6922 }
6923 }
6924 switch_mutex_unlock(smh->sdp_mutex);
6925 }
6926
6927
6928 if (append_video) {
6929 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "%s%s", append_video, end_of(append_video)*(*append_video == '\0' ? append_video : append_video + strlen
(append_video) - 1)
== '\n' ? "" : "\n");
6930 }
6931
6932 } else if (smh->mparams->num_codecs) {
6933 int i;
6934 int already_did[128] = { 0 };
6935
6936 for (i = 0; i < smh->mparams->num_codecs; i++) {
6937 const switch_codec_implementation_t *imp = smh->codecs[i];
6938 char *fmtp = NULL((void*)0);
6939 uint32_t ianacode = smh->ianacodes[i];
6940 int channels;
6941
6942 if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO) {
6943 continue;
6944 }
6945
6946 if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_INBOUND &&
6947 switch_channel_test_flag(session->channel, CF_NOVIDEO)) {
6948 continue;
6949 }
6950
6951 if (ianacode < 128) {
6952 if (already_did[ianacode]) {
6953 continue;
6954 }
6955 already_did[ianacode] = 1;
6956 }
6957
6958 if (!rate) {
6959 rate = imp->samples_per_second;
6960 }
6961
6962 channels = get_channels(imp->iananame, imp->number_of_channels);
6963
6964 if (!strcasecmp(imp->iananame, "VP8")) {
6965 vp8 = ianacode;
6966 }
6967
6968 if (!strcasecmp(imp->iananame, "red")) {
6969 red = ianacode;
6970 }
6971
6972 if (channels > 1) {
6973 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=rtpmap:%d %s/%d/%d\n", ianacode, imp->iananame,
6974 imp->samples_per_second, channels);
6975 } else {
6976 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=rtpmap:%d %s/%d\n", ianacode, imp->iananame,
6977 imp->samples_per_second);
6978 }
6979
6980 if (!zstr(ov_fmtp)_zstr(ov_fmtp)) {
6981 fmtp = (char *) ov_fmtp;
6982 } else {
6983
6984 if (map) {
6985 fmtp = switch_event_get_header(map, imp->iananame)switch_event_get_header_idx(map, imp->iananame, -1);
6986 }
6987
6988 if (smh->fmtps[i]) {
6989 fmtp = smh->fmtps[i];
6990 }
6991
6992 if (zstr(fmtp)_zstr(fmtp)) fmtp = imp->fmtp;
6993
6994 if (zstr(fmtp)_zstr(fmtp)) fmtp = (char *) pass_fmtp;
6995 }
6996
6997 if (!zstr(fmtp)_zstr(fmtp) && strcasecmp(fmtp, "_blank_")) {
6998 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=fmtp:%d %s\n", ianacode, fmtp);
6999 }
7000 }
7001
7002 }
7003
7004 if ((is_outbound || switch_channel_test_flag(session->channel, CF_RECOVERING))
7005 && switch_channel_test_flag(smh->session->channel, CF_DTLS)) {
7006 generate_local_fingerprint(smh, SWITCH_MEDIA_TYPE_VIDEO);
7007 }
7008
7009
7010 if (!zstr(v_engine->local_dtls_fingerprint.type)_zstr(v_engine->local_dtls_fingerprint.type)) {
7011 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=fingerprint:%s %s\n", v_engine->local_dtls_fingerprint.type,
7012 v_engine->local_dtls_fingerprint.str);
7013 }
7014
7015
7016 if (smh->mparams->rtcp_video_interval_msec) {
7017 if (v_engine->rtcp_mux > 0) {
7018 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=rtcp-mux\n");
7019 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=rtcp:%d IN %s %s\n", v_port, family, ip);
7020 } else {
7021 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=rtcp:%d IN %s %s\n", v_port + 1, family, ip);
7022 }
7023 }
7024
7025
7026 if (v_engine->fir || v_engine->pli) {
7027 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf),
7028 "a=rtcp-fb:* %s%s\n", v_engine->fir ? "fir " : "", v_engine->pli ? "pli" : "");
7029 }
7030
7031 //switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u\n", v_engine->ssrc);
7032
7033 if (v_engine->ice_out.cands[0][0].ready) {
7034 char tmp1[11] = "";
7035 char tmp2[11] = "";
7036 uint32_t c1 = (2^24)*126 + (2^8)*65535 + (2^0)*(256 - 1);
7037 uint32_t c2 = (2^24)*126 + (2^8)*65535 + (2^0)*(256 - 2);
7038 uint32_t c3 = (2^24)*126 + (2^8)*65534 + (2^0)*(256 - 1);
7039 uint32_t c4 = (2^24)*126 + (2^8)*65534 + (2^0)*(256 - 2);
7040 const char *vbw;
7041 int bw = 256;
7042
7043 tmp1[10] = '\0';
7044 tmp2[10] = '\0';
7045 switch_stun_random_string(tmp1, 10, "0123456789");
7046 switch_stun_random_string(tmp2, 10, "0123456789");
7047
7048 ice_out = &v_engine->ice_out;
7049
7050
7051 if ((vbw = switch_channel_get_variable(smh->session->channel, "rtp_video_max_bandwidth")switch_channel_get_variable_dup(smh->session->channel, "rtp_video_max_bandwidth"
, SWITCH_TRUE, -1)
)) {
7052 int v = atoi(vbw);
7053 bw = v;
7054 }
7055
7056 if (bw > 0) {
7057 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "b=AS:%d\n", bw);
7058 }
7059
7060 if (vp8 && switch_channel_test_flag(session->channel, CF_WEBRTC)) {
7061 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf),
7062 "a=rtcp-fb:%d ccm fir\n", vp8);
7063 }
7064
7065 if (red) {
7066 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf),
7067 "a=rtcp-fb:%d nack\n", vp8);
7068 }
7069
7070 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=ssrc:%u cname:%s\n", v_engine->ssrc, smh->cname);
7071 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=ssrc:%u msid:%s v0\n", v_engine->ssrc, smh->msid);
7072 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=ssrc:%u mslabel:%s\n", v_engine->ssrc, smh->msid);
7073 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=ssrc:%u label:%sv0\n", v_engine->ssrc, smh->msid);
7074
7075
7076
7077 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=ice-ufrag:%s\n", ice_out->ufrag);
7078 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=ice-pwd:%s\n", ice_out->pwd);
7079
7080
7081 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=candidate:%s 1 %s %u %s %d typ host generation 0\n",
7082 tmp1, ice_out->cands[0][0].transport, c1,
7083 ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port
7084 );
7085
7086 if (!zstr(v_engine->local_sdp_ip)_zstr(v_engine->local_sdp_ip) && !zstr(ice_out->cands[0][0].con_addr)_zstr(ice_out->cands[0][0].con_addr) &&
7087 strcmp(v_engine->local_sdp_ip, ice_out->cands[0][0].con_addr)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(v_engine->local_sdp_ip) && __builtin_constant_p (
ice_out->cands[0][0].con_addr) && (__s1_len = __builtin_strlen
(v_engine->local_sdp_ip), __s2_len = __builtin_strlen (ice_out
->cands[0][0].con_addr), (!((size_t)(const void *)((v_engine
->local_sdp_ip) + 1) - (size_t)(const void *)(v_engine->
local_sdp_ip) == 1) || __s1_len >= 4) && (!((size_t
)(const void *)((ice_out->cands[0][0].con_addr) + 1) - (size_t
)(const void *)(ice_out->cands[0][0].con_addr) == 1) || __s2_len
>= 4)) ? __builtin_strcmp (v_engine->local_sdp_ip, ice_out
->cands[0][0].con_addr) : (__builtin_constant_p (v_engine->
local_sdp_ip) && ((size_t)(const void *)((v_engine->
local_sdp_ip) + 1) - (size_t)(const void *)(v_engine->local_sdp_ip
) == 1) && (__s1_len = __builtin_strlen (v_engine->
local_sdp_ip), __s1_len < 4) ? (__builtin_constant_p (ice_out
->cands[0][0].con_addr) && ((size_t)(const void *)
((ice_out->cands[0][0].con_addr) + 1) - (size_t)(const void
*)(ice_out->cands[0][0].con_addr) == 1) ? __builtin_strcmp
(v_engine->local_sdp_ip, ice_out->cands[0][0].con_addr
) : (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (ice_out->cands[0][0].con_addr); int
__result = (((const unsigned char *) (const char *) (v_engine
->local_sdp_ip))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (v_engine->local_sdp_ip))[1] - __s2[1]); if (__s1_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (v_engine->local_sdp_ip))[2] - __s2
[2]); if (__s1_len > 2 && __result == 0) __result =
(((const unsigned char *) (const char *) (v_engine->local_sdp_ip
))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (
ice_out->cands[0][0].con_addr) && ((size_t)(const void
*)((ice_out->cands[0][0].con_addr) + 1) - (size_t)(const void
*)(ice_out->cands[0][0].con_addr) == 1) && (__s2_len
= __builtin_strlen (ice_out->cands[0][0].con_addr), __s2_len
< 4) ? (__builtin_constant_p (v_engine->local_sdp_ip) &&
((size_t)(const void *)((v_engine->local_sdp_ip) + 1) - (
size_t)(const void *)(v_engine->local_sdp_ip) == 1) ? __builtin_strcmp
(v_engine->local_sdp_ip, ice_out->cands[0][0].con_addr
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (v_engine->local_sdp_ip); int __result
= (((const unsigned char *) (const char *) (ice_out->cands
[0][0].con_addr))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (ice_out->cands[0][0].con_addr))[1] - __s2[1]); if
(__s2_len > 1 && __result == 0) { __result = (((const
unsigned char *) (const char *) (ice_out->cands[0][0].con_addr
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (ice_out
->cands[0][0].con_addr))[3] - __s2[3]); } } __result; })))
) : __builtin_strcmp (v_engine->local_sdp_ip, ice_out->
cands[0][0].con_addr)))); })
7088 && v_engine->local_sdp_port != ice_out->cands[0][0].con_port) {
7089
7090 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=candidate:%s 1 %s %u %s %d typ srflx raddr %s rport %d generation 0\n",
7091 tmp2, ice_out->cands[0][0].transport, c3,
7092 ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port,
7093 v_engine->local_sdp_ip, v_engine->local_sdp_port
7094 );
7095 }
7096
7097
7098 if (v_engine->rtcp_mux < 1 || is_outbound ||
7099 switch_channel_test_flag(session->channel, CF_RECOVERING)) {
7100
7101 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ host generation 0\n",
7102 tmp1, ice_out->cands[0][0].transport, c2,
7103 ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port + (v_engine->rtcp_mux > 0 ? 0 : 1)
7104 );
7105
7106
7107 if (!zstr(v_engine->local_sdp_ip)_zstr(v_engine->local_sdp_ip) && !zstr(ice_out->cands[0][1].con_addr)_zstr(ice_out->cands[0][1].con_addr) &&
7108 strcmp(v_engine->local_sdp_ip, ice_out->cands[0][1].con_addr)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(v_engine->local_sdp_ip) && __builtin_constant_p (
ice_out->cands[0][1].con_addr) && (__s1_len = __builtin_strlen
(v_engine->local_sdp_ip), __s2_len = __builtin_strlen (ice_out
->cands[0][1].con_addr), (!((size_t)(const void *)((v_engine
->local_sdp_ip) + 1) - (size_t)(const void *)(v_engine->
local_sdp_ip) == 1) || __s1_len >= 4) && (!((size_t
)(const void *)((ice_out->cands[0][1].con_addr) + 1) - (size_t
)(const void *)(ice_out->cands[0][1].con_addr) == 1) || __s2_len
>= 4)) ? __builtin_strcmp (v_engine->local_sdp_ip, ice_out
->cands[0][1].con_addr) : (__builtin_constant_p (v_engine->
local_sdp_ip) && ((size_t)(const void *)((v_engine->
local_sdp_ip) + 1) - (size_t)(const void *)(v_engine->local_sdp_ip
) == 1) && (__s1_len = __builtin_strlen (v_engine->
local_sdp_ip), __s1_len < 4) ? (__builtin_constant_p (ice_out
->cands[0][1].con_addr) && ((size_t)(const void *)
((ice_out->cands[0][1].con_addr) + 1) - (size_t)(const void
*)(ice_out->cands[0][1].con_addr) == 1) ? __builtin_strcmp
(v_engine->local_sdp_ip, ice_out->cands[0][1].con_addr
) : (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (ice_out->cands[0][1].con_addr); int
__result = (((const unsigned char *) (const char *) (v_engine
->local_sdp_ip))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (v_engine->local_sdp_ip))[1] - __s2[1]); if (__s1_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (v_engine->local_sdp_ip))[2] - __s2
[2]); if (__s1_len > 2 && __result == 0) __result =
(((const unsigned char *) (const char *) (v_engine->local_sdp_ip
))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (
ice_out->cands[0][1].con_addr) && ((size_t)(const void
*)((ice_out->cands[0][1].con_addr) + 1) - (size_t)(const void
*)(ice_out->cands[0][1].con_addr) == 1) && (__s2_len
= __builtin_strlen (ice_out->cands[0][1].con_addr), __s2_len
< 4) ? (__builtin_constant_p (v_engine->local_sdp_ip) &&
((size_t)(const void *)((v_engine->local_sdp_ip) + 1) - (
size_t)(const void *)(v_engine->local_sdp_ip) == 1) ? __builtin_strcmp
(v_engine->local_sdp_ip, ice_out->cands[0][1].con_addr
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (v_engine->local_sdp_ip); int __result
= (((const unsigned char *) (const char *) (ice_out->cands
[0][1].con_addr))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (ice_out->cands[0][1].con_addr))[1] - __s2[1]); if
(__s2_len > 1 && __result == 0) { __result = (((const
unsigned char *) (const char *) (ice_out->cands[0][1].con_addr
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (ice_out
->cands[0][1].con_addr))[3] - __s2[3]); } } __result; })))
) : __builtin_strcmp (v_engine->local_sdp_ip, ice_out->
cands[0][1].con_addr)))); })
7109 && v_engine->local_sdp_port != ice_out->cands[0][1].con_port) {
7110
7111 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ srflx generation 0\n",
7112 tmp2, ice_out->cands[0][0].transport, c4,
7113 ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port + (v_engine->rtcp_mux > 0 ? 0 : 1),
7114 v_engine->local_sdp_ip, v_engine->local_sdp_port + (v_engine->rtcp_mux > 0 ? 0 : 1)
7115 );
7116 }
7117 }
7118
7119
7120
7121#ifdef GOOGLE_ICE
7122 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=ice-options:google-ice\n");
7123#endif
7124 }
7125
7126
7127
7128 if (loops == 0 && switch_channel_test_flag(session->channel, CF_SECURE) && !switch_channel_test_flag(session->channel, CF_DTLS)) {
7129 int i;
7130
7131 for (i = 0; smh->crypto_suite_order[i] != CRYPTO_INVALID; i++) {
7132 switch_rtp_crypto_key_type_t j = SUITES[smh->crypto_suite_order[i]].type;
7133
7134 if ((a_engine->crypto_type == j || a_engine->crypto_type == CRYPTO_INVALID) && !zstr(a_engine->ssec[j].local_crypto_key)_zstr(a_engine->ssec[j].local_crypto_key)) {
7135 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=crypto:%s\n", v_engine->ssec[j].local_crypto_key);
7136 }
7137 }
7138 //switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=encryption:optional\n");
7139 }
7140
7141
7142 if (local_sdp_video_zrtp_hash) {
7143 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 7143, (const char*)(session)
, SWITCH_LOG_DEBUG, "Adding video a=zrtp-hash:%s\n", local_sdp_video_zrtp_hash);
7144 switch_snprintf(buf + strlen(buf), SDPBUFLEN65536 - strlen(buf), "a=zrtp-hash:%s\n", local_sdp_video_zrtp_hash);
7145 }
7146
7147
7148 if (switch_channel_test_flag(session->channel, CF_DTLS) ||
7149 !switch_channel_test_flag(session->channel, CF_SECURE) ||
7150 smh->crypto_mode == CRYPTO_MODE_MANDATORY || smh->crypto_mode == CRYPTO_MODE_FORBIDDEN) {
7151 break;
7152 }
7153 }
7154 }
7155
7156 }
7157
7158
7159 if (map) {
7160 switch_event_destroy(&map);
7161 }
7162
7163 if (ptmap) {
7164 switch_event_destroy(&ptmap);
7165 }
7166
7167 switch_core_media_set_local_sdp(session, buf, SWITCH_TRUE);
7168
7169 switch_safe_free(buf)if (buf) {free(buf);buf=((void*)0);};
7170}
7171
7172
7173
7174//?
7175SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_absorb_sdp(switch_core_session_t *session)
7176{
7177 const char *sdp_str;
7178 switch_rtp_engine_t *a_engine;
7179 switch_media_handle_t *smh;
7180
7181 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 7181, __PRETTY_FUNCTION__))
;
7182
7183 if (!(smh = session->media_handle)) {
7184 return;
7185 }
7186
7187 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
7188
7189 if ((sdp_str = switch_channel_get_variable(session->channel, SWITCH_B_SDP_VARIABLE)switch_channel_get_variable_dup(session->channel, "switch_m_sdp"
, SWITCH_TRUE, -1)
)) {
7190 sdp_parser_t *parser;
7191 sdp_session_t *sdp;
7192 sdp_media_t *m;
7193 sdp_connection_t *connection;
7194
7195 if ((parser = sdp_parse(NULL((void*)0), sdp_str, (int) strlen(sdp_str), 0))) {
7196 if ((sdp = sdp_session(parser))) {
7197 for (m = sdp->sdp_media; m; m = m->m_next) {
7198 if (m->m_type != sdp_media_audio || !m->m_port) {
7199 continue;
7200 }
7201
7202 connection = sdp->sdp_connection;
7203 if (m->m_connections) {
7204 connection = m->m_connections;
7205 }
7206
7207 if (connection) {
7208 a_engine->proxy_sdp_ip = switch_core_session_strdup(session, connection->c_address)switch_core_perform_session_strdup(session, connection->c_address
, "src/switch_core_media.c", (const char *)__func__, 7208)
;
7209 }
7210 a_engine->proxy_sdp_port = (switch_port_t) m->m_port;
7211 if (a_engine->proxy_sdp_ip && a_engine->proxy_sdp_port) {
7212 break;
7213 }
7214 }
7215 }
7216 sdp_parser_free(parser);
7217 }
7218 switch_core_media_set_local_sdp(session, sdp_str, SWITCH_TRUE);
7219 }
7220}
7221
7222
7223//?
7224SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_set_udptl_image_sdp(switch_core_session_t *session, switch_t38_options_t *t38_options, int insist)
7225{
7226 char buf[2048] = "";
7227 char max_buf[128] = "";
7228 char max_data[128] = "";
7229 const char *ip;
7230 uint32_t port;
7231 const char *family = "IP4";
7232 const char *username;
7233 const char *bit_removal_on = "a=T38FaxFillBitRemoval\n";
7234 const char *bit_removal_off = "";
7235
7236 const char *mmr_on = "a=T38FaxTranscodingMMR\n";
7237 const char *mmr_off = "";
7238
7239 const char *jbig_on = "a=T38FaxTranscodingJBIG\n";
7240 const char *jbig_off = "";
7241 const char *var;
7242 int broken_boolean;
7243 switch_media_handle_t *smh;
7244 switch_rtp_engine_t *a_engine;
7245
7246 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 7246, __PRETTY_FUNCTION__))
;
7247
7248 if (!(smh = session->media_handle)) {
7249 return;
7250 }
7251
7252 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
7253
7254
7255 switch_assert(t38_options)((t38_options) ? (void) (0) : __assert_fail ("t38_options", "src/switch_core_media.c"
, 7255, __PRETTY_FUNCTION__))
;
7256
7257 ip = t38_options->local_ip;
7258 port = t38_options->local_port;
7259 username = smh->mparams->sdp_username;
7260
7261 var = switch_channel_get_variable(session->channel, "t38_broken_boolean")switch_channel_get_variable_dup(session->channel, "t38_broken_boolean"
, SWITCH_TRUE, -1)
;
7262
7263 broken_boolean = switch_true(var);
7264
7265
7266 if (!ip) {
7267 if (!(ip = a_engine->adv_sdp_ip)) {
7268 ip = a_engine->proxy_sdp_ip;
7269 }
7270 }
7271
7272 if (!ip) {
7273 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_media.c", (const char
*)__func__, 7273, ((void*)0)
, SWITCH_LOG_CRIT, "%s NO IP!\n", switch_channel_get_name(session->channel));
7274 return;
7275 }
7276
7277 if (!port) {
7278 if (!(port = a_engine->adv_sdp_port)) {
7279 port = a_engine->proxy_sdp_port;
7280 }
7281 }
7282
7283 if (!port) {
7284 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_core_media.c", (const char
*)__func__, 7284, ((void*)0)
, SWITCH_LOG_CRIT, "%s NO PORT!\n", switch_channel_get_name(session->channel));
7285 return;
7286 }
7287
7288 if (!smh->owner_id) {
7289 smh->owner_id = (uint32_t) switch_epoch_time_now(NULL((void*)0)) - port;
7290 }
7291
7292 if (!smh->session_id) {
7293 smh->session_id = smh->owner_id;
7294 }
7295
7296 smh->session_id++;
7297
7298 family = strchr(ip, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(ip) && (':') == '\0' ? (char *) __rawmemchr (ip, ':'
) : __builtin_strchr (ip, ':')))
? "IP6" : "IP4";
7299
7300
7301 switch_snprintf(buf, sizeof(buf),
7302 "v=0\n"
7303 "o=%s %010u %010u IN %s %s\n"
7304 "s=%s\n" "c=IN %s %s\n" "t=0 0\n", username, smh->owner_id, smh->session_id, family, ip, username, family, ip);
7305
7306 if (t38_options->T38FaxMaxBuffer) {
7307 switch_snprintf(max_buf, sizeof(max_buf), "a=T38FaxMaxBuffer:%d\n", t38_options->T38FaxMaxBuffer);
7308 };
7309
7310 if (t38_options->T38FaxMaxDatagram) {
7311 switch_snprintf(max_data, sizeof(max_data), "a=T38FaxMaxDatagram:%d\n", t38_options->T38FaxMaxDatagram);
7312 };
7313
7314
7315
7316
7317 if (broken_boolean) {
7318 bit_removal_on = "a=T38FaxFillBitRemoval:1\n";
7319 bit_removal_off = "a=T38FaxFillBitRemoval:0\n";
7320
7321 mmr_on = "a=T38FaxTranscodingMMR:1\n";
7322 mmr_off = "a=T38FaxTranscodingMMR:0\n";
7323
7324 jbig_on = "a=T38FaxTranscodingJBIG:1\n";
7325 jbig_off = "a=T38FaxTranscodingJBIG:0\n";
7326
7327 }
7328
7329
7330 switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
7331 "m=image %d udptl t38\n"
7332 "a=T38FaxVersion:%d\n"
7333 "a=T38MaxBitRate:%d\n"
7334 "%s"
7335 "%s"
7336 "%s"
7337 "a=T38FaxRateManagement:%s\n"
7338 "%s"
7339 "%s"
7340 "a=T38FaxUdpEC:%s\n",
7341 //"a=T38VendorInfo:%s\n",
7342 port,
7343 t38_options->T38FaxVersion,
7344 t38_options->T38MaxBitRate,
7345 t38_options->T38FaxFillBitRemoval ? bit_removal_on : bit_removal_off,
7346 t38_options->T38FaxTranscodingMMR ? mmr_on : mmr_off,
7347 t38_options->T38FaxTranscodingJBIG ? jbig_on : jbig_off,
7348 t38_options->T38FaxRateManagement,
7349 max_buf,
7350 max_data,
7351 t38_options->T38FaxUdpEC
7352 //t38_options->T38VendorInfo ? t38_options->T38VendorInfo : "0 0 0"
7353 );
7354
7355
7356
7357 if (insist) {
7358 switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "m=audio 0 RTP/AVP 19\n");
7359 }
7360
7361 switch_core_media_set_local_sdp(session, buf, SWITCH_TRUE);
7362
7363
7364 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 7364, (const char*)(session)
, SWITCH_LOG_DEBUG, "%s image media sdp:\n%s\n",
7365 switch_channel_get_name(session->channel), smh->mparams->local_sdp_str);
7366
7367
7368}
7369
7370
7371
7372//?
7373SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_patch_sdp(switch_core_session_t *session)
7374{
7375 switch_size_t len;
7376 char *p, *q, *pe, *qe;
7377 int has_video = 0, has_audio = 0, has_ip = 0;
7378 char port_buf[25] = "";
7379 char vport_buf[25] = "";
7380 char *new_sdp;
7381 int bad = 0;
7382 switch_media_handle_t *smh;
7383 switch_rtp_engine_t *a_engine, *v_engine;
7384 payload_map_t *pmap;
7385
7386 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 7386, __PRETTY_FUNCTION__))
;
7387
7388 if (!(smh = session->media_handle)) {
7389 return;
7390 }
7391
7392 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
7393 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
7394
7395 if (zstr(smh->mparams->local_sdp_str)_zstr(smh->mparams->local_sdp_str)) {
7396 return;
7397 }
7398
7399 len = strlen(smh->mparams->local_sdp_str) * 2;
7400
7401 if (!(smh->mparams->ndlb & SM_NDLB_NEVER_PATCH_REINVITE)) {
7402 if (switch_channel_test_flag(session->channel, CF_ANSWERED) &&
7403 (switch_stristr("sendonly", smh->mparams->local_sdp_str) || switch_stristr("0.0.0.0", smh->mparams->local_sdp_str))) {
7404 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 7404, (const char*)(session)
, SWITCH_LOG_DEBUG, "Skip patch on hold SDP\n");
7405 return;
7406 }
7407 }
7408
7409 if (zstr(a_engine->local_sdp_ip)_zstr(a_engine->local_sdp_ip) || !a_engine->local_sdp_port) {// || switch_channel_test_flag(session->channel, CF_PROXY_MEDIA)) {
7410 if (switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_AUDIO, 1) != SWITCH_STATUS_SUCCESS) {
7411 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 7411, (const char*)(session)
, SWITCH_LOG_ERROR, "%s I/O Error\n",
7412 switch_channel_get_name(session->channel));
7413 return;
7414 }
7415
7416 clear_pmaps(a_engine);
7417
7418 pmap = switch_core_media_add_payload_map(session,
7419 SWITCH_MEDIA_TYPE_AUDIO,
7420 "PROXY",
7421 NULL((void*)0),
7422 SDP_TYPE_RESPONSE,
7423 0,
7424 8000,
7425 8000,
7426 1,
7427 SWITCH_TRUE);
7428
7429 a_engine->cur_payload_map = pmap;
7430
7431 }
7432
7433 new_sdp = switch_core_session_alloc(session, len)switch_core_perform_session_alloc(session, len, "src/switch_core_media.c"
, (const char *)__func__, 7433)
;
7434 switch_snprintf(port_buf, sizeof(port_buf), "%u", a_engine->local_sdp_port);
7435
7436
7437 p = smh->mparams->local_sdp_str;
7438 q = new_sdp;
7439 pe = p + strlen(p);
7440 qe = q + len - 1;
7441
7442
7443 while (p && *p) {
7444 if (p >= pe) {
7445 bad = 1;
7446 goto end;
7447 }
7448
7449 if (q >= qe) {
7450 bad = 2;
7451 goto end;
7452 }
7453
7454 if (a_engine->local_sdp_ip && !strncmp("c=IN IP", p, 7)(__extension__ (__builtin_constant_p (7) && ((__builtin_constant_p
("c=IN IP") && strlen ("c=IN IP") < ((size_t) (7)
)) || (__builtin_constant_p (p) && strlen (p) < ((
size_t) (7)))) ? __extension__ ({ size_t __s1_len, __s2_len; (
__builtin_constant_p ("c=IN IP") && __builtin_constant_p
(p) && (__s1_len = __builtin_strlen ("c=IN IP"), __s2_len
= __builtin_strlen (p), (!((size_t)(const void *)(("c=IN IP"
) + 1) - (size_t)(const void *)("c=IN IP") == 1) || __s1_len >=
4) && (!((size_t)(const void *)((p) + 1) - (size_t)(
const void *)(p) == 1) || __s2_len >= 4)) ? __builtin_strcmp
("c=IN IP", p) : (__builtin_constant_p ("c=IN IP") &&
((size_t)(const void *)(("c=IN IP") + 1) - (size_t)(const void
*)("c=IN IP") == 1) && (__s1_len = __builtin_strlen (
"c=IN IP"), __s1_len < 4) ? (__builtin_constant_p (p) &&
((size_t)(const void *)((p) + 1) - (size_t)(const void *)(p)
== 1) ? __builtin_strcmp ("c=IN IP", p) : (__extension__ ({ const
unsigned char *__s2 = (const unsigned char *) (const char *)
(p); int __result = (((const unsigned char *) (const char *)
("c=IN IP"))[0] - __s2[0]); if (__s1_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
"c=IN IP"))[1] - __s2[1]); if (__s1_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
"c=IN IP"))[2] - __s2[2]); if (__s1_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) ("c=IN IP"
))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (
p) && ((size_t)(const void *)((p) + 1) - (size_t)(const
void *)(p) == 1) && (__s2_len = __builtin_strlen (p)
, __s2_len < 4) ? (__builtin_constant_p ("c=IN IP") &&
((size_t)(const void *)(("c=IN IP") + 1) - (size_t)(const void
*)("c=IN IP") == 1) ? __builtin_strcmp ("c=IN IP", p) : (- (
__extension__ ({ const unsigned char *__s2 = (const unsigned char
*) (const char *) ("c=IN IP"); int __result = (((const unsigned
char *) (const char *) (p))[0] - __s2[0]); if (__s2_len >
0 && __result == 0) { __result = (((const unsigned char
*) (const char *) (p))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (p))[2] - __s2[2]); if (__s2_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) (p
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp ("c=IN IP"
, p)))); }) : strncmp ("c=IN IP", p, 7)))
) {
7455 strncpy(q, p, 7)__builtin_strncpy (q, p, 7);
7456 p += 7;
7457 q += 7;
7458 strncpy(q, strchr(a_engine->adv_sdp_ip, ':') ? "6 " : "4 ", 2)__builtin_strncpy (q, (__extension__ (__builtin_constant_p (':'
) && !__builtin_constant_p (a_engine->adv_sdp_ip) &&
(':') == '\0' ? (char *) __rawmemchr (a_engine->adv_sdp_ip
, ':') : __builtin_strchr (a_engine->adv_sdp_ip, ':'))) ? "6 "
: "4 ", 2)
;
7459 p +=2;
7460 q +=2;
7461 strncpy(q, a_engine->adv_sdp_ip, strlen(a_engine->adv_sdp_ip))__builtin_strncpy (q, a_engine->adv_sdp_ip, strlen(a_engine
->adv_sdp_ip))
;
7462 q += strlen(a_engine->adv_sdp_ip);
7463
7464 while (p && *p && ((*p >= '0' && *p <= '9') || *p == '.' || *p == ':' || (*p >= 'A' && *p <= 'F') || (*p >= 'a' && *p <= 'f'))) {
7465 if (p >= pe) {
7466 bad = 3;
7467 goto end;
7468 }
7469 p++;
7470 }
7471
7472 has_ip++;
7473
7474 } else if (!strncmp("o=", p, 2)(__extension__ (__builtin_constant_p (2) && ((__builtin_constant_p
("o=") && strlen ("o=") < ((size_t) (2))) || (__builtin_constant_p
(p) && strlen (p) < ((size_t) (2)))) ? __extension__
({ size_t __s1_len, __s2_len; (__builtin_constant_p ("o=") &&
__builtin_constant_p (p) && (__s1_len = __builtin_strlen
("o="), __s2_len = __builtin_strlen (p), (!((size_t)(const void
*)(("o=") + 1) - (size_t)(const void *)("o=") == 1) || __s1_len
>= 4) && (!((size_t)(const void *)((p) + 1) - (size_t
)(const void *)(p) == 1) || __s2_len >= 4)) ? __builtin_strcmp
("o=", p) : (__builtin_constant_p ("o=") && ((size_t
)(const void *)(("o=") + 1) - (size_t)(const void *)("o=") ==
1) && (__s1_len = __builtin_strlen ("o="), __s1_len <
4) ? (__builtin_constant_p (p) && ((size_t)(const void
*)((p) + 1) - (size_t)(const void *)(p) == 1) ? __builtin_strcmp
("o=", p) : (__extension__ ({ const unsigned char *__s2 = (const
unsigned char *) (const char *) (p); int __result = (((const
unsigned char *) (const char *) ("o="))[0] - __s2[0]); if (__s1_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) ("o="))[1] - __s2[1]); if (__s1_len >
1 && __result == 0) { __result = (((const unsigned char
*) (const char *) ("o="))[2] - __s2[2]); if (__s1_len > 2
&& __result == 0) __result = (((const unsigned char *
) (const char *) ("o="))[3] - __s2[3]); } } __result; }))) : (
__builtin_constant_p (p) && ((size_t)(const void *)((
p) + 1) - (size_t)(const void *)(p) == 1) && (__s2_len
= __builtin_strlen (p), __s2_len < 4) ? (__builtin_constant_p
("o=") && ((size_t)(const void *)(("o=") + 1) - (size_t
)(const void *)("o=") == 1) ? __builtin_strcmp ("o=", p) : (-
(__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) ("o="); int __result = (((const unsigned
char *) (const char *) (p))[0] - __s2[0]); if (__s2_len >
0 && __result == 0) { __result = (((const unsigned char
*) (const char *) (p))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (p))[2] - __s2[2]); if (__s2_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) (p
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp ("o="
, p)))); }) : strncmp ("o=", p, 2)))
) {
7475 char *oe = strchr(p, '\n')(__extension__ (__builtin_constant_p ('\n') && !__builtin_constant_p
(p) && ('\n') == '\0' ? (char *) __rawmemchr (p, '\n'
) : __builtin_strchr (p, '\n')))
;
7476 switch_size_t len;
7477
7478 if (oe) {
7479 const char *family = "IP4";
7480 char o_line[1024] = "";
7481
7482 if (oe >= pe) {
7483 bad = 5;
7484 goto end;
7485 }
7486
7487 len = (oe - p);
7488 p += len;
7489
7490
7491 family = strchr(smh->mparams->sipip, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(smh->mparams->sipip) && (':') == '\0' ? (char
*) __rawmemchr (smh->mparams->sipip, ':') : __builtin_strchr
(smh->mparams->sipip, ':')))
? "IP6" : "IP4";
7492
7493 if (!smh->owner_id) {
7494 smh->owner_id = (uint32_t) switch_epoch_time_now(NULL((void*)0)) * 31821U + 13849U;
7495 }
7496
7497 if (!smh->session_id) {
7498 smh->session_id = smh->owner_id;
7499 }
7500
7501 smh->session_id++;
7502
7503
7504 snprintf(o_line, sizeof(o_line), "o=%s %010u %010u IN %s %s\n",
7505 smh->mparams->sdp_username, smh->owner_id, smh->session_id, family, smh->mparams->sipip);
7506
7507 strncpy(q, o_line, strlen(o_line))__builtin_strncpy (q, o_line, strlen(o_line));
7508 q += strlen(o_line) - 1;
7509
7510 }
7511
7512 } else if (!strncmp("s=", p, 2)(__extension__ (__builtin_constant_p (2) && ((__builtin_constant_p
("s=") && strlen ("s=") < ((size_t) (2))) || (__builtin_constant_p
(p) && strlen (p) < ((size_t) (2)))) ? __extension__
({ size_t __s1_len, __s2_len; (__builtin_constant_p ("s=") &&
__builtin_constant_p (p) && (__s1_len = __builtin_strlen
("s="), __s2_len = __builtin_strlen (p), (!((size_t)(const void
*)(("s=") + 1) - (size_t)(const void *)("s=") == 1) || __s1_len
>= 4) && (!((size_t)(const void *)((p) + 1) - (size_t
)(const void *)(p) == 1) || __s2_len >= 4)) ? __builtin_strcmp
("s=", p) : (__builtin_constant_p ("s=") && ((size_t
)(const void *)(("s=") + 1) - (size_t)(const void *)("s=") ==
1) && (__s1_len = __builtin_strlen ("s="), __s1_len <
4) ? (__builtin_constant_p (p) && ((size_t)(const void
*)((p) + 1) - (size_t)(const void *)(p) == 1) ? __builtin_strcmp
("s=", p) : (__extension__ ({ const unsigned char *__s2 = (const
unsigned char *) (const char *) (p); int __result = (((const
unsigned char *) (const char *) ("s="))[0] - __s2[0]); if (__s1_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) ("s="))[1] - __s2[1]); if (__s1_len >
1 && __result == 0) { __result = (((const unsigned char
*) (const char *) ("s="))[2] - __s2[2]); if (__s1_len > 2
&& __result == 0) __result = (((const unsigned char *
) (const char *) ("s="))[3] - __s2[3]); } } __result; }))) : (
__builtin_constant_p (p) && ((size_t)(const void *)((
p) + 1) - (size_t)(const void *)(p) == 1) && (__s2_len
= __builtin_strlen (p), __s2_len < 4) ? (__builtin_constant_p
("s=") && ((size_t)(const void *)(("s=") + 1) - (size_t
)(const void *)("s=") == 1) ? __builtin_strcmp ("s=", p) : (-
(__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) ("s="); int __result = (((const unsigned
char *) (const char *) (p))[0] - __s2[0]); if (__s2_len >
0 && __result == 0) { __result = (((const unsigned char
*) (const char *) (p))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (p))[2] - __s2[2]); if (__s2_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) (p
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp ("s="
, p)))); }) : strncmp ("s=", p, 2)))
) {
7513 char *se = strchr(p, '\n')(__extension__ (__builtin_constant_p ('\n') && !__builtin_constant_p
(p) && ('\n') == '\0' ? (char *) __rawmemchr (p, '\n'
) : __builtin_strchr (p, '\n')))
;
7514 switch_size_t len;
7515
7516 if (se) {
7517 char s_line[1024] = "";
7518
7519 if (se >= pe) {
7520 bad = 5;
7521 goto end;
7522 }
7523
7524 len = (se - p);
7525 p += len;
7526
7527 snprintf(s_line, sizeof(s_line), "s=%s\n", smh->mparams->sdp_username);
7528
7529 strncpy(q, s_line, strlen(s_line))__builtin_strncpy (q, s_line, strlen(s_line));
7530 q += strlen(s_line) - 1;
7531
7532 }
7533
7534 } else if ((!strncmp("m=audio ", p, 8)(__extension__ (__builtin_constant_p (8) && ((__builtin_constant_p
("m=audio ") && strlen ("m=audio ") < ((size_t) (
8))) || (__builtin_constant_p (p) && strlen (p) < (
(size_t) (8)))) ? __extension__ ({ size_t __s1_len, __s2_len;
(__builtin_constant_p ("m=audio ") && __builtin_constant_p
(p) && (__s1_len = __builtin_strlen ("m=audio "), __s2_len
= __builtin_strlen (p), (!((size_t)(const void *)(("m=audio "
) + 1) - (size_t)(const void *)("m=audio ") == 1) || __s1_len
>= 4) && (!((size_t)(const void *)((p) + 1) - (size_t
)(const void *)(p) == 1) || __s2_len >= 4)) ? __builtin_strcmp
("m=audio ", p) : (__builtin_constant_p ("m=audio ") &&
((size_t)(const void *)(("m=audio ") + 1) - (size_t)(const void
*)("m=audio ") == 1) && (__s1_len = __builtin_strlen
("m=audio "), __s1_len < 4) ? (__builtin_constant_p (p) &&
((size_t)(const void *)((p) + 1) - (size_t)(const void *)(p)
== 1) ? __builtin_strcmp ("m=audio ", p) : (__extension__ ({
const unsigned char *__s2 = (const unsigned char *) (const char
*) (p); int __result = (((const unsigned char *) (const char
*) ("m=audio "))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("m=audio "))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("m=audio "))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) ("m=audio "))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(p) && ((size_t)(const void *)((p) + 1) - (size_t)(const
void *)(p) == 1) && (__s2_len = __builtin_strlen (p)
, __s2_len < 4) ? (__builtin_constant_p ("m=audio ") &&
((size_t)(const void *)(("m=audio ") + 1) - (size_t)(const void
*)("m=audio ") == 1) ? __builtin_strcmp ("m=audio ", p) : (-
(__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) ("m=audio "); int __result = (((const
unsigned char *) (const char *) (p))[0] - __s2[0]); if (__s2_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (p))[1] - __s2[1]); if (__s2_len >
1 && __result == 0) { __result = (((const unsigned char
*) (const char *) (p))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (p))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
("m=audio ", p)))); }) : strncmp ("m=audio ", p, 8)))
&& *(p + 8) != '0') || (!strncmp("m=image ", p, 8)(__extension__ (__builtin_constant_p (8) && ((__builtin_constant_p
("m=image ") && strlen ("m=image ") < ((size_t) (
8))) || (__builtin_constant_p (p) && strlen (p) < (
(size_t) (8)))) ? __extension__ ({ size_t __s1_len, __s2_len;
(__builtin_constant_p ("m=image ") && __builtin_constant_p
(p) && (__s1_len = __builtin_strlen ("m=image "), __s2_len
= __builtin_strlen (p), (!((size_t)(const void *)(("m=image "
) + 1) - (size_t)(const void *)("m=image ") == 1) || __s1_len
>= 4) && (!((size_t)(const void *)((p) + 1) - (size_t
)(const void *)(p) == 1) || __s2_len >= 4)) ? __builtin_strcmp
("m=image ", p) : (__builtin_constant_p ("m=image ") &&
((size_t)(const void *)(("m=image ") + 1) - (size_t)(const void
*)("m=image ") == 1) && (__s1_len = __builtin_strlen
("m=image "), __s1_len < 4) ? (__builtin_constant_p (p) &&
((size_t)(const void *)((p) + 1) - (size_t)(const void *)(p)
== 1) ? __builtin_strcmp ("m=image ", p) : (__extension__ ({
const unsigned char *__s2 = (const unsigned char *) (const char
*) (p); int __result = (((const unsigned char *) (const char
*) ("m=image "))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("m=image "))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("m=image "))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) ("m=image "))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(p) && ((size_t)(const void *)((p) + 1) - (size_t)(const
void *)(p) == 1) && (__s2_len = __builtin_strlen (p)
, __s2_len < 4) ? (__builtin_constant_p ("m=image ") &&
((size_t)(const void *)(("m=image ") + 1) - (size_t)(const void
*)("m=image ") == 1) ? __builtin_strcmp ("m=image ", p) : (-
(__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) ("m=image "); int __result = (((const
unsigned char *) (const char *) (p))[0] - __s2[0]); if (__s2_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (p))[1] - __s2[1]); if (__s2_len >
1 && __result == 0) { __result = (((const unsigned char
*) (const char *) (p))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (p))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
("m=image ", p)))); }) : strncmp ("m=image ", p, 8)))
&& *(p + 8) != '0')) {
7535 strncpy(q, p, 8)__builtin_strncpy (q, p, 8);
7536 p += 8;
7537
7538 if (p >= pe) {
7539 bad = 4;
7540 goto end;
7541 }
7542
7543
7544 q += 8;
7545
7546 if (q >= qe) {
7547 bad = 5;
7548 goto end;
7549 }
7550
7551
7552 strncpy(q, port_buf, strlen(port_buf))__builtin_strncpy (q, port_buf, strlen(port_buf));
7553 q += strlen(port_buf);
7554
7555 if (q >= qe) {
7556 bad = 6;
7557 goto end;
7558 }
7559
7560 while (p && *p && (*p >= '0' && *p <= '9')) {
7561 if (p >= pe) {
7562 bad = 7;
7563 goto end;
7564 }
7565 p++;
7566 }
7567
7568 has_audio++;
7569
7570 } else if (!strncmp("m=video ", p, 8)(__extension__ (__builtin_constant_p (8) && ((__builtin_constant_p
("m=video ") && strlen ("m=video ") < ((size_t) (
8))) || (__builtin_constant_p (p) && strlen (p) < (
(size_t) (8)))) ? __extension__ ({ size_t __s1_len, __s2_len;
(__builtin_constant_p ("m=video ") && __builtin_constant_p
(p) && (__s1_len = __builtin_strlen ("m=video "), __s2_len
= __builtin_strlen (p), (!((size_t)(const void *)(("m=video "
) + 1) - (size_t)(const void *)("m=video ") == 1) || __s1_len
>= 4) && (!((size_t)(const void *)((p) + 1) - (size_t
)(const void *)(p) == 1) || __s2_len >= 4)) ? __builtin_strcmp
("m=video ", p) : (__builtin_constant_p ("m=video ") &&
((size_t)(const void *)(("m=video ") + 1) - (size_t)(const void
*)("m=video ") == 1) && (__s1_len = __builtin_strlen
("m=video "), __s1_len < 4) ? (__builtin_constant_p (p) &&
((size_t)(const void *)((p) + 1) - (size_t)(const void *)(p)
== 1) ? __builtin_strcmp ("m=video ", p) : (__extension__ ({
const unsigned char *__s2 = (const unsigned char *) (const char
*) (p); int __result = (((const unsigned char *) (const char
*) ("m=video "))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("m=video "))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("m=video "))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) ("m=video "))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(p) && ((size_t)(const void *)((p) + 1) - (size_t)(const
void *)(p) == 1) && (__s2_len = __builtin_strlen (p)
, __s2_len < 4) ? (__builtin_constant_p ("m=video ") &&
((size_t)(const void *)(("m=video ") + 1) - (size_t)(const void
*)("m=video ") == 1) ? __builtin_strcmp ("m=video ", p) : (-
(__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) ("m=video "); int __result = (((const
unsigned char *) (const char *) (p))[0] - __s2[0]); if (__s2_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (p))[1] - __s2[1]); if (__s2_len >
1 && __result == 0) { __result = (((const unsigned char
*) (const char *) (p))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (p))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
("m=video ", p)))); }) : strncmp ("m=video ", p, 8)))
&& *(p + 8) != '0') {
7571 if (!has_video) {
7572 switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_VIDEO, 1);
7573 clear_pmaps(v_engine);
7574 pmap = switch_core_media_add_payload_map(session,
7575 SWITCH_MEDIA_TYPE_AUDIO,
7576 "PROXY-VID",
7577 NULL((void*)0),
7578 SDP_TYPE_RESPONSE,
7579 0,
7580 90000,
7581 90000,
7582 1,
7583 SWITCH_TRUE);
7584 v_engine->cur_payload_map = pmap;
7585
7586 switch_snprintf(vport_buf, sizeof(vport_buf), "%u", v_engine->adv_sdp_port);
7587 if (switch_channel_media_ready(session->channel)switch_channel_test_ready(session->channel, SWITCH_TRUE, SWITCH_TRUE
)
&& !switch_rtp_ready(v_engine->rtp_session)) {
7588 switch_channel_set_flag(session->channel, CF_VIDEO_POSSIBLE)switch_channel_set_flag_value(session->channel, CF_VIDEO_POSSIBLE
, 1)
;
7589 switch_channel_set_flag(session->channel, CF_REINVITE)switch_channel_set_flag_value(session->channel, CF_REINVITE
, 1)
;
7590 switch_core_media_activate_rtp(session);
7591 }
7592 }
7593
7594 strncpy(q, p, 8)__builtin_strncpy (q, p, 8);
7595 p += 8;
7596
7597 if (p >= pe) {
7598 bad = 8;
7599 goto end;
7600 }
7601
7602 q += 8;
7603
7604 if (q >= qe) {
7605 bad = 9;
7606 goto end;
7607 }
7608
7609 strncpy(q, vport_buf, strlen(vport_buf))__builtin_strncpy (q, vport_buf, strlen(vport_buf));
7610 q += strlen(vport_buf);
7611
7612 if (q >= qe) {
7613 bad = 10;
7614 goto end;
7615 }
7616
7617 while (p && *p && (*p >= '0' && *p <= '9')) {
7618
7619 if (p >= pe) {
7620 bad = 11;
7621 goto end;
7622 }
7623
7624 p++;
7625 }
7626
7627 has_video++;
7628 }
7629
7630 while (p && *p && *p != '\n') {
7631
7632 if (p >= pe) {
7633 bad = 12;
7634 goto end;
7635 }
7636
7637 if (q >= qe) {
7638 bad = 13;
7639 goto end;
7640 }
7641
7642 *q++ = *p++;
7643 }
7644
7645 if (p >= pe) {
7646 bad = 14;
7647 goto end;
7648 }
7649
7650 if (q >= qe) {
7651 bad = 15;
7652 goto end;
7653 }
7654
7655 *q++ = *p++;
7656
7657 }
7658
7659 end:
7660
7661 if (bad) {
7662 return;
7663 }
7664
7665
7666 if (switch_channel_down(session->channel)(switch_channel_check_signal(session->channel, SWITCH_TRUE
) || switch_channel_get_state(session->channel) >= CS_HANGUP
)
) {
7667 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 7667, (const char*)(session)
, SWITCH_LOG_DEBUG, "%s too late.\n", switch_channel_get_name(session->channel));
7668 return;
7669 }
7670
7671
7672 if (!has_ip && !has_audio) {
7673 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 7673, (const char*)(session)
, SWITCH_LOG_DEBUG, "%s SDP has no audio in it.\n%s\n",
7674 switch_channel_get_name(session->channel), smh->mparams->local_sdp_str);
7675 return;
7676 }
7677
7678
7679 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 7679, (const char*)(session)
, SWITCH_LOG_DEBUG, "%s Patched SDP\n---\n%s\n+++\n%s\n",
7680 switch_channel_get_name(session->channel), smh->mparams->local_sdp_str, new_sdp);
7681
7682 switch_core_media_set_local_sdp(session, new_sdp, SWITCH_FALSE);
7683
7684}
7685
7686//?
7687SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_start_udptl(switch_core_session_t *session, switch_t38_options_t *t38_options)
7688{
7689 switch_media_handle_t *smh;
7690 switch_rtp_engine_t *a_engine;
7691
7692 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 7692, __PRETTY_FUNCTION__))
;
7693
7694 if (!(smh = session->media_handle)) {
7695 return;
7696 }
7697
7698 if (switch_channel_down(session->channel)(switch_channel_check_signal(session->channel, SWITCH_TRUE
) || switch_channel_get_state(session->channel) >= CS_HANGUP
)
) {
7699 return;
7700 }
7701
7702 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
7703
7704
7705 if (switch_rtp_ready(a_engine->rtp_session)) {
7706 char *remote_host = switch_rtp_get_remote_host(a_engine->rtp_session);
7707 switch_port_t remote_port = switch_rtp_get_remote_port(a_engine->rtp_session);
7708 const char *err, *val;
7709
7710 switch_channel_clear_flag(session->channel, CF_NOTIMER_DURING_BRIDGE);
7711 switch_rtp_udptl_mode(a_engine->rtp_session);
7712
7713 if (!t38_options || !t38_options->remote_ip) {
7714 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 7714, (const char*)(session)
, SWITCH_LOG_DEBUG, "No remote address\n");
7715 return;
7716 }
7717
7718 if (remote_host && remote_port && remote_port == t38_options->remote_port && !strcmp(remote_host, t38_options->remote_ip)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(remote_host) && __builtin_constant_p (t38_options->
remote_ip) && (__s1_len = __builtin_strlen (remote_host
), __s2_len = __builtin_strlen (t38_options->remote_ip), (
!((size_t)(const void *)((remote_host) + 1) - (size_t)(const void
*)(remote_host) == 1) || __s1_len >= 4) && (!((size_t
)(const void *)((t38_options->remote_ip) + 1) - (size_t)(const
void *)(t38_options->remote_ip) == 1) || __s2_len >= 4
)) ? __builtin_strcmp (remote_host, t38_options->remote_ip
) : (__builtin_constant_p (remote_host) && ((size_t)(
const void *)((remote_host) + 1) - (size_t)(const void *)(remote_host
) == 1) && (__s1_len = __builtin_strlen (remote_host)
, __s1_len < 4) ? (__builtin_constant_p (t38_options->remote_ip
) && ((size_t)(const void *)((t38_options->remote_ip
) + 1) - (size_t)(const void *)(t38_options->remote_ip) ==
1) ? __builtin_strcmp (remote_host, t38_options->remote_ip
) : (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (t38_options->remote_ip); int __result
= (((const unsigned char *) (const char *) (remote_host))[0]
- __s2[0]); if (__s1_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) (remote_host))[1]
- __s2[1]); if (__s1_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) (remote_host))[2]
- __s2[2]); if (__s1_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) (remote_host))[3]
- __s2[3]); } } __result; }))) : (__builtin_constant_p (t38_options
->remote_ip) && ((size_t)(const void *)((t38_options
->remote_ip) + 1) - (size_t)(const void *)(t38_options->
remote_ip) == 1) && (__s2_len = __builtin_strlen (t38_options
->remote_ip), __s2_len < 4) ? (__builtin_constant_p (remote_host
) && ((size_t)(const void *)((remote_host) + 1) - (size_t
)(const void *)(remote_host) == 1) ? __builtin_strcmp (remote_host
, t38_options->remote_ip) : (- (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (remote_host
); int __result = (((const unsigned char *) (const char *) (t38_options
->remote_ip))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (t38_options->remote_ip))[1] - __s2[1]); if (__s2_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (t38_options->remote_ip))[2] - __s2
[2]); if (__s2_len > 2 && __result == 0) __result =
(((const unsigned char *) (const char *) (t38_options->remote_ip
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (remote_host
, t38_options->remote_ip)))); })
) {
7719 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 7719, (const char*)(session)
, SWITCH_LOG_DEBUG, "Remote address:port [%s:%d] has not changed.\n",
7720 t38_options->remote_ip, t38_options->remote_port);
7721 return;
7722 }
7723
7724 if (switch_rtp_set_remote_address(a_engine->rtp_session, t38_options->remote_ip,
7725 t38_options->remote_port, 0, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
7726 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 7726, (const char*)(session)
, SWITCH_LOG_ERROR, "IMAGE UDPTL REPORTS ERROR: [%s]\n", err);
7727 } else {
7728 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 7728, (const char*)(session)
, SWITCH_LOG_DEBUG, "IMAGE UDPTL CHANGING DEST TO: [%s:%d]\n",
7729 t38_options->remote_ip, t38_options->remote_port);
7730 if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) && !switch_channel_test_flag(session->channel, CF_WEBRTC) &&
7731 !((val = switch_channel_get_variable(session->channel, "disable_udptl_auto_adjust")switch_channel_get_variable_dup(session->channel, "disable_udptl_auto_adjust"
, SWITCH_TRUE, -1)
) && switch_true(val))) {
7732 /* Reactivate the NAT buster flag. */
7733 switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_AUTOADJ);
7734 }
7735 }
7736 }
7737}
7738
7739//?
7740SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_hard_mute(switch_core_session_t *session, switch_bool_t on)
7741{
7742 switch_core_session_message_t msg = { 0 };
7743
7744 msg.from = __FILE__"src/switch_core_media.c";
7745
7746 msg.message_id = SWITCH_MESSAGE_INDICATE_HARD_MUTE;
7747 msg.numeric_arg = on;
7748 switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg
, "src/switch_core_media.c", (const char *)__func__, 7748)
;
7749}
7750
7751
7752//?
7753SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_media_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg)
7754{
7755 switch_media_handle_t *smh;
7756 switch_rtp_engine_t *a_engine, *v_engine;
7757 switch_status_t status = SWITCH_STATUS_SUCCESS;
7758
7759 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 7759, __PRETTY_FUNCTION__))
;
7760
7761 if (!(smh = session->media_handle)) {
7762 return SWITCH_STATUS_FALSE;
7763 }
7764
7765 if (switch_channel_down(session->channel)(switch_channel_check_signal(session->channel, SWITCH_TRUE
) || switch_channel_get_state(session->channel) >= CS_HANGUP
)
) {
7766 return SWITCH_STATUS_FALSE;
7767 }
7768
7769 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
7770 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
7771
7772 switch (msg->message_id) {
7773
7774 case SWITCH_MESSAGE_RESAMPLE_EVENT:
7775 {
7776 if (switch_channel_test_flag(session->channel, CF_CONFERENCE)) {
7777 switch_channel_set_flag(session->channel, CF_CONFERENCE_RESET_MEDIA)switch_channel_set_flag_value(session->channel, CF_CONFERENCE_RESET_MEDIA
, 1)
;
7778 }
7779 }
7780 break;
7781
7782 case SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ:
7783 {
7784 if (v_engine->rtp_session) {
7785 switch_rtp_video_refresh(v_engine->rtp_session);
7786 }
7787 }
7788
7789 break;
7790
7791 case SWITCH_MESSAGE_INDICATE_PROXY_MEDIA:
7792 {
7793 if (switch_rtp_ready(a_engine->rtp_session)) {
7794 if (msg->numeric_arg) {
7795 switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA);
7796 } else {
7797 switch_rtp_clear_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA);
7798 }
7799 }
7800 }
7801 break;
7802
7803 case SWITCH_MESSAGE_INDICATE_JITTER_BUFFER:
7804 {
7805 if (switch_rtp_ready(a_engine->rtp_session)) {
7806 check_jb(session, msg->string_arg);
7807 }
7808 }
7809 break;
7810
7811 case SWITCH_MESSAGE_INDICATE_HARD_MUTE:
7812 {
7813 if (session->bugs) {
7814 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 7814, (const char*)(session)
, SWITCH_LOG_WARNING,
7815 "%s has a media bug, hard mute not allowed.\n", switch_channel_get_name(session->channel));
7816 } else if (a_engine->rtp_session) {
7817 if (msg->numeric_arg) {
7818 switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_MUTE);
7819 } else {
7820 switch_rtp_clear_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_MUTE);
7821 }
7822
7823 rtp_flush_read_buffer(a_engine->rtp_session, SWITCH_RTP_FLUSH_ONCE);
7824 }
7825 }
7826
7827 break;
7828
7829 case SWITCH_MESSAGE_INDICATE_DEBUG_MEDIA:
7830 {
7831 switch_rtp_t *rtp = a_engine->rtp_session;
7832 const char *direction = msg->string_array_arg[0];
7833
7834 if (direction && *direction == 'v') {
7835 direction++;
7836 rtp = v_engine->rtp_session;
7837 }
7838
7839 if (switch_rtp_ready(rtp) && !zstr(direction)_zstr(direction) && !zstr(msg->string_array_arg[1])_zstr(msg->string_array_arg[1])) {
7840 switch_rtp_flag_t flags[SWITCH_RTP_FLAG_INVALID] = {0};
7841 int both = !strcasecmp(direction, "both");
7842 int set = 0;
7843
7844 if (both || !strcasecmp(direction, "read")) {
7845 flags[SWITCH_RTP_FLAG_DEBUG_RTP_READ]++;
7846 set++;
7847 }
7848
7849 if (both || !strcasecmp(direction, "write")) {
7850 flags[SWITCH_RTP_FLAG_DEBUG_RTP_WRITE]++;
7851 set++;
7852 }
7853
7854 if (set) {
7855 if (switch_true(msg->string_array_arg[1])) {
7856 switch_rtp_set_flags(rtp, flags);
7857 } else {
7858 switch_rtp_clear_flags(rtp, flags);
7859 }
7860 } else {
7861 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 7861, (const char*)(session)
, SWITCH_LOG_ERROR, "Invalid Options\n");
7862 }
7863 }
7864 }
7865 goto end;
7866 case SWITCH_MESSAGE_INDICATE_TRANSCODING_NECESSARY:
7867 if (a_engine->rtp_session && switch_rtp_test_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PASS_RFC2833)) {
7868 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 7868, (const char*)(session)
, SWITCH_LOG_WARNING, "Pass 2833 mode may not work on a transcoded call.\n");
7869 }
7870 goto end;
7871
7872 case SWITCH_MESSAGE_INDICATE_BRIDGE:
7873 {
7874
7875 if (switch_rtp_ready(a_engine->rtp_session)) {
7876 const char *val;
7877 int ok = 0;
7878
7879 if (!(val = switch_channel_get_variable(session->channel, "rtp_jitter_buffer_during_bridge")switch_channel_get_variable_dup(session->channel, "rtp_jitter_buffer_during_bridge"
, SWITCH_TRUE, -1)
) || switch_false(val)) {
7880 if (switch_channel_test_flag(session->channel, CF_JITTERBUFFER) && switch_channel_test_cap_partner(session->channel, CC_FS_RTP)) {
7881 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 7881, (const char*)(session)
, SWITCH_LOG_DEBUG,
7882 "%s PAUSE Jitterbuffer\n", switch_channel_get_name(session->channel));
7883 switch_rtp_pause_jitter_buffer(a_engine->rtp_session, SWITCH_TRUE);
7884 switch_set_flag(smh, SMF_JB_PAUSED)(smh)->flags |= (SMF_JB_PAUSED);
7885 }
7886 }
7887
7888 if (switch_channel_test_flag(session->channel, CF_PASS_RFC2833) && switch_channel_test_flag_partner(session->channel, CF_FS_RTP)) {
7889 switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PASS_RFC2833);
7890 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 7890, (const char*)(session)
, SWITCH_LOG_DEBUG,
7891 "%s activate passthru 2833 mode.\n", switch_channel_get_name(session->channel));
7892 }
7893
7894
7895 if ((val = switch_channel_get_variable(session->channel, "rtp_notimer_during_bridge")switch_channel_get_variable_dup(session->channel, "rtp_notimer_during_bridge"
, SWITCH_TRUE, -1)
)) {
7896 ok = switch_true(val);
7897 } else {
7898 ok = switch_channel_test_flag(session->channel, CF_RTP_NOTIMER_DURING_BRIDGE);
7899 }
7900
7901 if (ok && !switch_rtp_test_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_USE_TIMER)) {
7902 ok = 0;
7903 }
7904
7905 if (ok) {
7906 switch_rtp_clear_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_USE_TIMER);
7907 //switch_rtp_clear_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_NOBLOCK);
7908 switch_channel_set_flag(session->channel, CF_NOTIMER_DURING_BRIDGE)switch_channel_set_flag_value(session->channel, CF_NOTIMER_DURING_BRIDGE
, 1)
;
7909 }
7910
7911 if (ok && switch_channel_test_flag(session->channel, CF_NOTIMER_DURING_BRIDGE)) {
7912 /* these are not compat */
7913 ok = 0;
7914 } else {
7915 if ((val = switch_channel_get_variable(session->channel, "rtp_autoflush_during_bridge")switch_channel_get_variable_dup(session->channel, "rtp_autoflush_during_bridge"
, SWITCH_TRUE, -1)
)) {
7916 ok = switch_true(val);
7917 } else {
7918 ok = smh->media_flags[SCMF_RTP_AUTOFLUSH_DURING_BRIDGE];
7919 }
7920 }
7921
7922 if (ok) {
7923 rtp_flush_read_buffer(a_engine->rtp_session, SWITCH_RTP_FLUSH_STICK);
7924 switch_channel_set_flag(session->channel, CF_AUTOFLUSH_DURING_BRIDGE)switch_channel_set_flag_value(session->channel, CF_AUTOFLUSH_DURING_BRIDGE
, 1)
;
7925 } else {
7926 rtp_flush_read_buffer(a_engine->rtp_session, SWITCH_RTP_FLUSH_ONCE);
7927 }
7928
7929 }
7930 }
7931 goto end;
7932 case SWITCH_MESSAGE_INDICATE_UNBRIDGE:
7933 if (switch_rtp_ready(a_engine->rtp_session)) {
7934
7935 if (switch_test_flag(smh, SMF_JB_PAUSED)((smh)->flags & SMF_JB_PAUSED)) {
7936 switch_clear_flag(smh, SMF_JB_PAUSED)(smh)->flags &= ~(SMF_JB_PAUSED);
7937 if (switch_channel_test_flag(session->channel, CF_JITTERBUFFER)) {
7938 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 7938, (const char*)(session)
, SWITCH_LOG_DEBUG,
7939 "%s RESUME Jitterbuffer\n", switch_channel_get_name(session->channel));
7940 switch_rtp_pause_jitter_buffer(a_engine->rtp_session, SWITCH_FALSE);
7941 }
7942 }
7943
7944
7945 if (switch_rtp_test_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PASS_RFC2833)) {
7946 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 7946, (const char*)(session)
, SWITCH_LOG_DEBUG, "%s deactivate passthru 2833 mode.\n",
7947 switch_channel_get_name(session->channel));
7948 switch_rtp_clear_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PASS_RFC2833);
7949 }
7950
7951 if (switch_channel_test_flag(session->channel, CF_NOTIMER_DURING_BRIDGE)) {
7952 if (!switch_rtp_test_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_UDPTL) &&
7953 !switch_rtp_test_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA)) {
7954 switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_USE_TIMER);
7955 //switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_NOBLOCK);
7956 }
7957 switch_channel_clear_flag(session->channel, CF_NOTIMER_DURING_BRIDGE);
7958 }
7959
7960 if (switch_channel_test_flag(session->channel, CF_AUTOFLUSH_DURING_BRIDGE)) {
7961 rtp_flush_read_buffer(a_engine->rtp_session, SWITCH_RTP_FLUSH_UNSTICK);
7962 switch_channel_clear_flag(session->channel, CF_AUTOFLUSH_DURING_BRIDGE);
7963 } else {
7964 rtp_flush_read_buffer(a_engine->rtp_session, SWITCH_RTP_FLUSH_ONCE);
7965 }
7966
7967 }
7968 goto end;
7969 case SWITCH_MESSAGE_INDICATE_AUDIO_SYNC:
7970 if (switch_rtp_ready(a_engine->rtp_session)) {
7971 rtp_flush_read_buffer(a_engine->rtp_session, SWITCH_RTP_FLUSH_ONCE);
7972 }
7973 goto end;
7974
7975 case SWITCH_MESSAGE_INDICATE_MEDIA:
7976 {
7977
7978 a_engine->codec_negotiated = 0;
7979 v_engine->codec_negotiated = 0;
7980
7981 if (session->track_duration) {
7982 switch_core_session_enable_heartbeat(session, session->track_duration);
7983 }
7984 }
7985 break;
7986 case SWITCH_MESSAGE_INDICATE_NOMEDIA:
7987 {
7988 const char *uuid;
7989 switch_core_session_t *other_session;
7990 switch_channel_t *other_channel;
7991 const char *ip = NULL((void*)0), *port = NULL((void*)0);
7992
7993 switch_channel_set_flag(session->channel, CF_PROXY_MODE)switch_channel_set_flag_value(session->channel, CF_PROXY_MODE
, 1)
;
7994
7995 switch_core_media_set_local_sdp(session, NULL((void*)0), SWITCH_FALSE);
7996
7997 if (switch_true(switch_channel_get_variable(session->channel, "bypass_keep_codec")switch_channel_get_variable_dup(session->channel, "bypass_keep_codec"
, SWITCH_TRUE, -1)
)) {
7998 switch_channel_set_variable(session->channel, "absolute_codec_string", switch_channel_get_variable(session->channel, "ep_codec_string"))switch_channel_set_variable_var_check(session->channel, "absolute_codec_string"
, switch_channel_get_variable_dup(session->channel, "ep_codec_string"
, SWITCH_TRUE, -1), SWITCH_TRUE)
;
7999 }
8000
8001
8002 if ((uuid = switch_channel_get_partner_uuid(session->channel))
8003 && (other_session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "src/switch_core_media.c"
, (const char *)__func__, 8003)
)) {
8004 other_channel = switch_core_session_get_channel(other_session);
8005 ip = switch_channel_get_variable(other_channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE)switch_channel_get_variable_dup(other_channel, "remote_media_ip"
, SWITCH_TRUE, -1)
;
8006 port = switch_channel_get_variable(other_channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE)switch_channel_get_variable_dup(other_channel, "remote_media_port"
, SWITCH_TRUE, -1)
;
8007 switch_core_session_rwunlock(other_session);
8008
8009 if (ip && port) {
8010 switch_core_media_prepare_codecs(session, 1);
8011 clear_pmaps(a_engine);
8012 clear_pmaps(v_engine);
8013 switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, ip, (switch_port_t)atoi(port), NULL((void*)0), 1);
8014 }
8015 }
8016
8017
8018 if (!smh->mparams->local_sdp_str) {
8019 switch_core_media_absorb_sdp(session);
8020 }
8021
8022 if (session->track_duration) {
8023 switch_core_session_enable_heartbeat(session, session->track_duration);
8024 }
8025
8026 }
8027 break;
8028
8029
8030 default:
8031 break;
8032 }
8033
8034
8035 if (smh->mutex) switch_mutex_lock(smh->mutex);
8036
8037
8038 if (switch_channel_down(session->channel)(switch_channel_check_signal(session->channel, SWITCH_TRUE
) || switch_channel_get_state(session->channel) >= CS_HANGUP
)
) {
8039 status = SWITCH_STATUS_FALSE;
8040 goto end_lock;
8041 }
8042
8043 switch (msg->message_id) {
8044 case SWITCH_MESSAGE_INDICATE_MEDIA_RENEG:
8045 {
8046 switch_core_session_t *nsession;
8047
8048 if (msg->string_arg) {
8049 switch_channel_set_variable(session->channel, "absolute_codec_string", NULL)switch_channel_set_variable_var_check(session->channel, "absolute_codec_string"
, ((void*)0), SWITCH_TRUE)
;
8050 if (*msg->string_arg == '=') {
8051 switch_channel_set_variable(session->channel, "codec_string", msg->string_arg)switch_channel_set_variable_var_check(session->channel, "codec_string"
, msg->string_arg, SWITCH_TRUE)
;
8052 } else {
8053 switch_channel_set_variable_printf(session->channel, "codec_string", "=%s%s%s,%s",
8054 v_engine->cur_payload_map->rm_encoding ? v_engine->cur_payload_map->rm_encoding : "",
8055 v_engine->cur_payload_map->rm_encoding ? "," : "",
8056 a_engine->cur_payload_map->rm_encoding, msg->string_arg);
8057 }
8058
8059
8060 a_engine->codec_negotiated = 0;
8061 v_engine->codec_negotiated = 0;
8062 smh->num_negotiated_codecs = 0;
8063 switch_channel_clear_flag(session->channel, CF_VIDEO_POSSIBLE);
8064 switch_core_media_prepare_codecs(session, SWITCH_TRUE);
8065 switch_core_media_check_video_codecs(session);
8066 switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL((void*)0), 0, NULL((void*)0), 1);
8067 }
8068
8069 switch_media_handle_set_media_flag(smh, SCMF_RENEG_ON_REINVITE);
8070
8071 if (msg->numeric_arg && switch_core_session_get_partner(session, &nsession)switch_core_session_perform_get_partner(session, &nsession
, "src/switch_core_media.c", (const char *)__func__, 8071)
== SWITCH_STATUS_SUCCESS) {
8072 msg->numeric_arg = 0;
8073 switch_core_session_receive_message(nsession, msg)switch_core_session_perform_receive_message(nsession, msg, "src/switch_core_media.c"
, (const char *)__func__, 8073)
;
8074 switch_core_session_rwunlock(nsession);
8075 }
8076
8077 }
8078 break;
8079
8080 case SWITCH_MESSAGE_INDICATE_AUDIO_DATA:
8081 {
8082 if (switch_rtp_ready(a_engine->rtp_session)) {
8083 if (msg->numeric_arg) {
8084 if (switch_channel_test_flag(session->channel, CF_JITTERBUFFER)) {
8085 switch_rtp_pause_jitter_buffer(a_engine->rtp_session, SWITCH_TRUE);
8086 switch_set_flag(smh, SMF_JB_PAUSED)(smh)->flags |= (SMF_JB_PAUSED);
8087 }
8088
8089 rtp_flush_read_buffer(a_engine->rtp_session, SWITCH_RTP_FLUSH_UNSTICK);
8090
8091 } else {
8092 if (switch_test_flag(smh, SMF_JB_PAUSED)((smh)->flags & SMF_JB_PAUSED)) {
8093 switch_clear_flag(smh, SMF_JB_PAUSED)(smh)->flags &= ~(SMF_JB_PAUSED);
8094 if (switch_channel_test_flag(session->channel, CF_JITTERBUFFER)) {
8095 switch_rtp_pause_jitter_buffer(a_engine->rtp_session, SWITCH_FALSE);
8096 }
8097 }
8098 }
8099 }
8100 }
8101 break;
8102
8103 case SWITCH_MESSAGE_INDICATE_UDPTL_MODE:
8104 {
8105 switch_t38_options_t *t38_options = switch_channel_get_private(session->channel, "t38_options");
8106
8107 if (t38_options) {
8108 switch_core_media_start_udptl(session, t38_options);
8109 }
8110
8111 }
8112
8113
8114 default:
8115 break;
8116 }
8117
8118
8119 end_lock:
8120
8121 if (smh->mutex) switch_mutex_unlock(smh->mutex);
8122
8123 end:
8124
8125 if (switch_channel_down(session->channel)(switch_channel_check_signal(session->channel, SWITCH_TRUE
) || switch_channel_get_state(session->channel) >= CS_HANGUP
)
) {
8126 status = SWITCH_STATUS_FALSE;
8127 }
8128
8129 return status;
8130
8131}
8132
8133//?
8134SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_break(switch_core_session_t *session, switch_media_type_t type)
8135{
8136 switch_media_handle_t *smh;
8137
8138 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 8138, __PRETTY_FUNCTION__))
;
8139
8140 if (!(smh = session->media_handle)) {
8141 return;
8142 }
8143
8144 if (switch_rtp_ready(smh->engines[type].rtp_session)) {
8145 switch_rtp_break(smh->engines[type].rtp_session);
8146 }
8147}
8148
8149//?
8150SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_kill_socket(switch_core_session_t *session, switch_media_type_t type)
8151{
8152 switch_media_handle_t *smh;
8153
8154 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 8154, __PRETTY_FUNCTION__))
;
8155
8156 if (!(smh = session->media_handle)) {
8157 return;
8158 }
8159
8160 if (switch_rtp_ready(smh->engines[type].rtp_session)) {
8161 switch_rtp_kill_socket(smh->engines[type].rtp_session);
8162 }
8163}
8164
8165//?
8166SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_media_queue_rfc2833(switch_core_session_t *session, switch_media_type_t type, const switch_dtmf_t *dtmf)
8167{
8168 switch_media_handle_t *smh;
8169
8170 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 8170, __PRETTY_FUNCTION__))
;
8171
8172 if (!(smh = session->media_handle)) {
8173 return SWITCH_STATUS_FALSE;
8174 }
8175
8176 if (switch_rtp_ready(smh->engines[type].rtp_session)) {
8177 return switch_rtp_queue_rfc2833(smh->engines[type].rtp_session, dtmf);
8178 }
8179
8180 return SWITCH_STATUS_FALSE;
8181}
8182
8183//?
8184SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_media_queue_rfc2833_in(switch_core_session_t *session, switch_media_type_t type, const switch_dtmf_t *dtmf)
8185{
8186 switch_media_handle_t *smh;
8187
8188 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 8188, __PRETTY_FUNCTION__))
;
8189
8190 if (!(smh = session->media_handle)) {
8191 return SWITCH_STATUS_FALSE;
8192 }
8193
8194 if (switch_rtp_ready(smh->engines[type].rtp_session)) {
8195 return switch_rtp_queue_rfc2833_in(smh->engines[type].rtp_session, dtmf);
8196 }
8197
8198 return SWITCH_STATUS_FALSE;
8199}
8200
8201//?
8202SWITCH_DECLARE(uint8_t)__attribute__((visibility("default"))) uint8_t switch_core_media_ready(switch_core_session_t *session, switch_media_type_t type)
8203{
8204 switch_media_handle_t *smh;
8205
8206 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 8206, __PRETTY_FUNCTION__))
;
8207
8208 if (!(smh = session->media_handle)) {
8209 return 0;
8210 }
8211
8212 return switch_rtp_ready(smh->engines[type].rtp_session);
8213}
8214
8215//?
8216SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_set_rtp_flag(switch_core_session_t *session, switch_media_type_t type, switch_rtp_flag_t flag)
8217{
8218 switch_media_handle_t *smh;
8219
8220 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 8220, __PRETTY_FUNCTION__))
;
8221
8222 if (!(smh = session->media_handle)) {
8223 return;
8224 }
8225
8226 if (switch_rtp_ready(smh->engines[type].rtp_session)) {
8227 switch_rtp_set_flag(smh->engines[type].rtp_session, flag);
8228 }
8229}
8230
8231//?
8232SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_clear_rtp_flag(switch_core_session_t *session, switch_media_type_t type, switch_rtp_flag_t flag)
8233{
8234 switch_media_handle_t *smh;
8235
8236 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 8236, __PRETTY_FUNCTION__))
;
8237
8238 if (!(smh = session->media_handle)) {
8239 return;
8240 }
8241
8242 if (switch_rtp_ready(smh->engines[type].rtp_session)) {
8243 switch_rtp_clear_flag(smh->engines[type].rtp_session, flag);
8244 }
8245}
8246
8247//?
8248SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_set_telephony_event(switch_core_session_t *session, switch_media_type_t type, switch_payload_t te)
8249{
8250 switch_media_handle_t *smh;
8251
8252 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 8252, __PRETTY_FUNCTION__))
;
8253
8254 if (!(smh = session->media_handle)) {
8255 return;
8256 }
8257
8258 if (switch_rtp_ready(smh->engines[type].rtp_session)) {
8259 switch_rtp_set_telephony_event(smh->engines[type].rtp_session, te);
8260 }
8261}
8262
8263//?
8264SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_set_telephony_recv_event(switch_core_session_t *session, switch_media_type_t type, switch_payload_t te)
8265{
8266 switch_media_handle_t *smh;
8267
8268 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 8268, __PRETTY_FUNCTION__))
;
8269
8270 if (!(smh = session->media_handle)) {
8271 return;
8272 }
8273
8274 if (switch_rtp_ready(smh->engines[type].rtp_session)) {
8275 switch_rtp_set_telephony_recv_event(smh->engines[type].rtp_session, te);
8276 }
8277}
8278
8279//?
8280SWITCH_DECLARE(switch_rtp_stats_t *)__attribute__((visibility("default"))) switch_rtp_stats_t * switch_core_media_get_stats(switch_core_session_t *session, switch_media_type_t type, switch_memory_pool_t *pool)
8281{
8282 switch_media_handle_t *smh;
8283
8284 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 8284, __PRETTY_FUNCTION__))
;
8285
8286 if (!(smh = session->media_handle)) {
8287 return NULL((void*)0);
8288 }
8289
8290 if (smh->engines[type].rtp_session) {
8291 return switch_rtp_get_stats(smh->engines[type].rtp_session, pool);
8292 }
8293
8294 return NULL((void*)0);
8295}
8296
8297//?
8298SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_media_udptl_mode(switch_core_session_t *session, switch_media_type_t type)
8299{
8300 switch_media_handle_t *smh;
8301
8302 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 8302, __PRETTY_FUNCTION__))
;
8303
8304 if (!(smh = session->media_handle)) {
8305 return SWITCH_STATUS_FALSE;
8306 }
8307
8308 if (switch_rtp_ready(smh->engines[type].rtp_session)) {
8309 return switch_rtp_udptl_mode(smh->engines[type].rtp_session);
8310 }
8311
8312 return SWITCH_STATUS_FALSE;
8313}
8314
8315//?
8316SWITCH_DECLARE(stfu_instance_t *)__attribute__((visibility("default"))) stfu_instance_t * switch_core_media_get_jb(switch_core_session_t *session, switch_media_type_t type)
8317{
8318 switch_media_handle_t *smh;
8319
8320 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 8320, __PRETTY_FUNCTION__))
;
8321
8322 if (!(smh = session->media_handle)) {
8323 return NULL((void*)0);
8324 }
8325
8326 if (switch_rtp_ready(smh->engines[type].rtp_session)) {
8327 return switch_rtp_get_jitter_buffer(smh->engines[type].rtp_session);
8328 }
8329
8330 return NULL((void*)0);
8331}
8332
8333
8334//?
8335SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_set_sdp_codec_string(switch_core_session_t *session, const char *r_sdp, switch_sdp_type_t sdp_type)
8336{
8337 sdp_parser_t *parser;
8338 sdp_session_t *sdp;
8339 switch_media_handle_t *smh;
8340
8341 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 8341, __PRETTY_FUNCTION__))
;
8342
8343 if (!(smh = session->media_handle)) {
8344 return;
8345 }
8346
8347
8348 if ((parser = sdp_parse(NULL((void*)0), r_sdp, (int) strlen(r_sdp), 0))) {
8349
8350 if ((sdp = sdp_session(parser))) {
8351 switch_core_media_set_r_sdp_codec_string(session, switch_core_media_get_codec_string(session), sdp, sdp_type);
8352 }
8353
8354 sdp_parser_free(parser);
8355 }
8356
8357}
8358
8359
8360static void add_audio_codec(sdp_rtpmap_t *map, int ptime, char *buf, switch_size_t buflen)
8361{
8362 int codec_ms = ptime;
8363 uint32_t map_bit_rate = 0, map_channels = 1;
8364 char ptstr[20] = "";
8365 char ratestr[20] = "";
8366 char bitstr[20] = "";
8367 switch_codec_fmtp_t codec_fmtp = { 0 };
8368
8369 if (!codec_ms) {
8370 codec_ms = switch_default_ptime(map->rm_encoding, map->rm_pt);
8371 }
8372
8373 map_channels = map->rm_params ? atoi(map->rm_params) : 1;
8374 map_bit_rate = switch_known_bitrate((switch_payload_t)map->rm_pt);
8375
8376 if (!ptime && !strcasecmp(map->rm_encoding, "g723")) {
8377 ptime = codec_ms = 30;
8378 }
8379
8380 if (zstr(map->rm_fmtp)_zstr(map->rm_fmtp)) {
8381 if (!strcasecmp(map->rm_encoding, "ilbc")) {
8382 ptime = codec_ms = 30;
8383 map_bit_rate = 13330;
8384 } else if (!strcasecmp(map->rm_encoding, "isac")) {
8385 ptime = codec_ms = 30;
8386 map_bit_rate = 32000;
8387 }
8388 } else {
8389 if ((switch_core_codec_parse_fmtp(map->rm_encoding, map->rm_fmtp, map->rm_rate, &codec_fmtp)) == SWITCH_STATUS_SUCCESS) {
8390 if (codec_fmtp.bits_per_second) {
8391 map_bit_rate = codec_fmtp.bits_per_second;
8392 }
8393 if (codec_fmtp.microseconds_per_packet) {
8394 codec_ms = (codec_fmtp.microseconds_per_packet / 1000);
8395 }
8396 }
8397 }
8398
8399 if (map->rm_rate) {
8400 switch_snprintf(ratestr, sizeof(ratestr), "@%uh", (unsigned int) map->rm_rate);
8401 }
8402
8403 if (codec_ms) {
8404 switch_snprintf(ptstr, sizeof(ptstr), "@%di", codec_ms);
8405 }
8406
8407 if (map_bit_rate) {
8408 switch_snprintf(bitstr, sizeof(bitstr), "@%db", map_bit_rate);
8409 }
8410
8411 if (map_channels > 1) {
8412 switch_snprintf(bitstr, sizeof(bitstr), "@%dc", map_channels);
8413 }
8414
8415 switch_snprintf(buf + strlen(buf), buflen - strlen(buf), ",%s%s%s%s", map->rm_encoding, ratestr, ptstr, bitstr);
8416
8417}
8418
8419
8420static 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)
8421{
8422 char buf[1024] = { 0 };
8423 sdp_media_t *m;
8424 sdp_attribute_t *attr;
8425 int ptime = 0, dptime = 0;
8426 sdp_connection_t *connection;
8427 sdp_rtpmap_t *map;
8428 short int match = 0;
8429 int i;
8430 int already_did[128] = { 0 };
8431 int num_codecs = 0;
8432 char *codec_order[SWITCH_MAX_CODECS50];
8433 const switch_codec_implementation_t *codecs[SWITCH_MAX_CODECS50] = { 0 };
8434 switch_channel_t *channel = switch_core_session_get_channel(session);
8435 int prefer_sdp = 0;
8436 const char *var;
8437 switch_media_handle_t *smh;
8438
8439 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 8439, __PRETTY_FUNCTION__))
;
8440
8441 if (!(smh = session->media_handle)) {
8442 return;
8443 }
8444
8445
8446 if ((var = switch_channel_get_variable(channel, "ep_codec_prefer_sdp")switch_channel_get_variable_dup(channel, "ep_codec_prefer_sdp"
, SWITCH_TRUE, -1)
) && switch_true(var)) {
8447 prefer_sdp = 1;
8448 }
8449
8450 if (!zstr(codec_string)_zstr(codec_string)) {
8451 char *tmp_codec_string;
8452 if ((tmp_codec_string = strdup(codec_string)(__extension__ (__builtin_constant_p (codec_string) &&
((size_t)(const void *)((codec_string) + 1) - (size_t)(const
void *)(codec_string) == 1) ? (((const char *) (codec_string
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen (codec_string) + 1; char *__retval = (
char *) malloc (__len); if (__retval != ((void*)0)) __retval =
(char *) memcpy (__retval, codec_string, __len); __retval; }
)) : __strdup (codec_string)))
)) {
8453 num_codecs = switch_separate_string(tmp_codec_string, ',', codec_order, SWITCH_MAX_CODECS50);
8454 num_codecs = switch_loadable_module_get_codecs_sorted(codecs, SWITCH_MAX_CODECS50, codec_order, num_codecs);
8455 switch_safe_free(tmp_codec_string)if (tmp_codec_string) {free(tmp_codec_string);tmp_codec_string
=((void*)0);}
;
8456 }
8457 } else {
8458 num_codecs = switch_loadable_module_get_codecs(codecs, SWITCH_MAX_CODECS50);
8459 }
8460
8461 if (!channel || !num_codecs) {
8462 return;
8463 }
8464
8465 for (attr = sdp->sdp_attributes; attr; attr = attr->a_next) {
8466 if (zstr(attr->a_name)_zstr(attr->a_name)) {
8467 continue;
8468 }
8469 if (!strcasecmp(attr->a_name, "ptime")) {
8470 dptime = atoi(attr->a_value);
8471 break;
8472 }
8473 }
8474
8475 switch_core_media_find_zrtp_hash(session, sdp);
8476 switch_core_media_pass_zrtp_hash(session);
8477
8478 for (m = sdp->sdp_media; m; m = m->m_next) {
8479 ptime = dptime;
8480
8481 if ((m->m_type == sdp_media_audio || m->m_type == sdp_media_video) && m->m_port) {
8482 for (map = m->m_rtpmaps; map; map = map->rm_next) {
8483 for (attr = m->m_attributes; attr; attr = attr->a_next) {
8484 if (zstr(attr->a_name)_zstr(attr->a_name)) {
8485 continue;
8486 }
8487 if (!strcasecmp(attr->a_name, "ptime") && attr->a_value) {
8488 ptime = atoi(attr->a_value);
8489 break;
8490 }
8491 }
8492 switch_core_media_add_payload_map(session,
8493 m->m_type == sdp_media_audio ? SWITCH_MEDIA_TYPE_AUDIO : SWITCH_MEDIA_TYPE_VIDEO,
8494 map->rm_encoding,
8495 map->rm_fmtp,
8496 sdp_type,
8497 map->rm_pt,
8498 map->rm_rate,
8499 ptime,
8500 map->rm_params ? atoi(map->rm_params) : 1,
8501 SWITCH_FALSE);
8502 }
8503 }
8504 }
8505
8506 for (m = sdp->sdp_media; m; m = m->m_next) {
8507 ptime = dptime;
8508
8509 if (m->m_type == sdp_media_image && m->m_port) {
8510 switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ",t38");
8511 } else if (m->m_type == sdp_media_audio && m->m_port) {
8512 for (attr = m->m_attributes; attr; attr = attr->a_next) {
8513 if (zstr(attr->a_name)_zstr(attr->a_name)) {
8514 continue;
8515 }
8516 if (!strcasecmp(attr->a_name, "ptime") && attr->a_value) {
8517 ptime = atoi(attr->a_value);
8518 break;
8519 }
8520 }
8521 connection = sdp->sdp_connection;
8522 if (m->m_connections) {
8523 connection = m->m_connections;
8524 }
8525
8526 if (!connection) {
8527 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 8527, (const char*)switch_channel_get_session(channel
)
, SWITCH_LOG_ERROR, "Cannot find a c= line in the sdp at media or session level!\n");
8528 break;
8529 }
8530
8531 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND || prefer_sdp) {
8532 for (map = m->m_rtpmaps; map; map = map->rm_next) {
8533 if (map->rm_pt > 127 || already_did[map->rm_pt]) {
8534 continue;
8535 }
8536
8537 for (i = 0; i < num_codecs; i++) {
8538 const switch_codec_implementation_t *imp = codecs[i];
8539
8540 if ((zstr(map->rm_encoding)_zstr(map->rm_encoding) || (smh->mparams->ndlb & SM_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) {
8541 match = (map->rm_pt == imp->ianacode) ? 1 : 0;
8542 } else {
8543 if (map->rm_encoding) {
8544 match = !strcasecmp(map->rm_encoding, imp->iananame) &&
8545 ((map->rm_pt < 96 && imp->ianacode < 96) || (map->rm_pt > 95 && imp->ianacode > 95));
8546 } else {
8547 match = 0;
8548 }
8549 }
8550
8551 if (match) {
8552 add_audio_codec(map, ptime, buf, sizeof(buf));
8553 break;
8554 }
8555
8556 }
8557 }
8558
8559 } else {
8560 for (i = 0; i < num_codecs; i++) {
8561 const switch_codec_implementation_t *imp = codecs[i];
8562 if (imp->codec_type != SWITCH_CODEC_TYPE_AUDIO || imp->ianacode > 127 || already_did[imp->ianacode]) {
8563 continue;
8564 }
8565 for (map = m->m_rtpmaps; map; map = map->rm_next) {
8566 if (map->rm_pt > 127 || already_did[map->rm_pt]) {
8567 continue;
8568 }
8569
8570 if ((zstr(map->rm_encoding)_zstr(map->rm_encoding) || (smh->mparams->ndlb & SM_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) {
8571 match = (map->rm_pt == imp->ianacode) ? 1 : 0;
8572 } else {
8573 if (map->rm_encoding) {
8574 match = !strcasecmp(map->rm_encoding, imp->iananame) &&
8575 ((map->rm_pt < 96 && imp->ianacode < 96) || (map->rm_pt > 95 && imp->ianacode > 95));
8576 } else {
8577 match = 0;
8578 }
8579 }
8580
8581 if (match) {
8582 add_audio_codec(map, ptime, buf, sizeof(buf));
8583 break;
8584 }
8585 }
8586 }
8587 }
8588
8589 } else if (m->m_type == sdp_media_video && m->m_port) {
8590 connection = sdp->sdp_connection;
8591 if (m->m_connections) {
8592 connection = m->m_connections;
8593 }
8594
8595 if (!connection) {
8596 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 8596, (const char*)switch_channel_get_session(channel
)
, SWITCH_LOG_ERROR, "Cannot find a c= line in the sdp at media or session level!\n");
8597 break;
8598 }
8599 for (i = 0; i < num_codecs; i++) {
8600 const switch_codec_implementation_t *imp = codecs[i];
8601 int channels;
8602
8603 if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO || imp->ianacode > 127 || already_did[imp->ianacode]) {
8604 continue;
8605 }
8606
8607 if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_INBOUND &&
8608 switch_channel_test_flag(session->channel, CF_NOVIDEO)) {
8609 continue;
8610 }
8611
8612 for (map = m->m_rtpmaps; map; map = map->rm_next) {
8613 if (map->rm_pt > 127 || already_did[map->rm_pt]) {
8614 continue;
8615 }
8616
8617 if ((zstr(map->rm_encoding)_zstr(map->rm_encoding) || (smh->mparams->ndlb & SM_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) {
8618 match = (map->rm_pt == imp->ianacode) ? 1 : 0;
8619 } else {
8620 if (map->rm_encoding) {
8621 match = !strcasecmp(map->rm_encoding, imp->iananame) &&
8622 ((map->rm_pt < 96 && imp->ianacode < 96) || (map->rm_pt > 95 && imp->ianacode > 95));
8623 } else {
8624 match = 0;
8625 }
8626 }
8627
8628 if (match) {
8629 channels = map->rm_params ? atoi(map->rm_params) : 1;
8630 if (ptime > 0) {
8631 switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ",%s@%uh@%di@%dc", imp->iananame, (unsigned int) map->rm_rate,
8632 ptime, channels);
8633 } else {
8634 switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ",%s@%uh@%dc", imp->iananame, (unsigned int) map->rm_rate, channels);
8635 }
8636 already_did[imp->ianacode] = 1;
8637 break;
8638 }
8639 }
8640 }
8641 }
8642 }
8643 if (buf[0] == ',') {
8644 switch_channel_set_variable(channel, "ep_codec_string", buf + 1)switch_channel_set_variable_var_check(channel, "ep_codec_string"
, buf + 1, SWITCH_TRUE)
;
8645 }
8646}
8647
8648//?
8649SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_core_media_codec_chosen(switch_core_session_t *session, switch_media_type_t type)
8650{
8651 switch_rtp_engine_t *engine;
8652 switch_media_handle_t *smh;
8653
8654 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 8654, __PRETTY_FUNCTION__))
;
8655
8656 if (!(smh = session->media_handle)) {
8657 return SWITCH_STATUS_FALSE;
8658 }
8659
8660 engine = &smh->engines[type];
8661
8662 if (engine->cur_payload_map->iananame) {
8663 return SWITCH_STATUS_SUCCESS;
8664 }
8665
8666 return SWITCH_STATUS_FALSE;
8667}
8668
8669
8670//?
8671SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_check_outgoing_proxy(switch_core_session_t *session, switch_core_session_t *o_session)
8672{
8673 switch_rtp_engine_t *a_engine, *v_engine;
8674 switch_media_handle_t *smh;
8675 const char *r_sdp = NULL((void*)0);
8676 payload_map_t *pmap;
8677
8678 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 8678, __PRETTY_FUNCTION__))
;
8679
8680 if (!switch_channel_test_flag(o_session->channel, CF_PROXY_MEDIA)) {
8681 return;
8682 }
8683
8684 if (!(smh = session->media_handle)) {
8685 return;
8686 }
8687
8688 r_sdp = switch_channel_get_variable(o_session->channel, SWITCH_R_SDP_VARIABLE)switch_channel_get_variable_dup(o_session->channel, "switch_r_sdp"
, SWITCH_TRUE, -1)
;
8689
8690 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
8691 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
8692
8693 switch_channel_set_flag(session->channel, CF_PROXY_MEDIA)switch_channel_set_flag_value(session->channel, CF_PROXY_MEDIA
, 1)
;
8694
8695 clear_pmaps(a_engine);
8696 clear_pmaps(v_engine);
8697
8698 pmap = switch_core_media_add_payload_map(session,
8699 SWITCH_MEDIA_TYPE_AUDIO,
8700 "PROXY",
8701 NULL((void*)0),
8702 SDP_TYPE_RESPONSE,
8703 0,
8704 8000,
8705 8000,
8706 1,
8707 SWITCH_TRUE);
8708
8709 a_engine->cur_payload_map = pmap;
8710
8711 if (switch_stristr("m=video", r_sdp)) {
8712 switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_VIDEO, 1);
8713 pmap = switch_core_media_add_payload_map(session,
8714 SWITCH_MEDIA_TYPE_AUDIO,
8715 "PROXY-VID",
8716 NULL((void*)0),
8717 SDP_TYPE_RESPONSE,
8718 0,
8719 90000,
8720 90000,
8721 1,
8722 SWITCH_TRUE);
8723
8724 v_engine->cur_payload_map = pmap;
8725
8726 switch_channel_set_flag(session->channel, CF_VIDEO)switch_channel_set_flag_value(session->channel, CF_VIDEO, 1
)
;
8727 switch_channel_set_flag(session->channel, CF_VIDEO_POSSIBLE)switch_channel_set_flag_value(session->channel, CF_VIDEO_POSSIBLE
, 1)
;
8728 }
8729}
8730
8731#ifdef _MSC_VER
8732/* remove this if the break is removed from the following for loop which causes unreachable code loop */
8733/* for (m = sdp->sdp_media; m; m = m->m_next) { */
8734#pragma warning(push)
8735#pragma warning(disable:4702)
8736#endif
8737
8738//?
8739SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_proxy_codec(switch_core_session_t *session, const char *r_sdp)
8740{
8741 sdp_media_t *m;
8742 sdp_parser_t *parser = NULL((void*)0);
8743 sdp_session_t *sdp;
8744 sdp_attribute_t *attr;
8745 int ptime = 0, dptime = 0;
8746 switch_rtp_engine_t *a_engine;
8747 switch_media_handle_t *smh;
8748
8749 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 8749, __PRETTY_FUNCTION__))
;
8750
8751 if (!(smh = session->media_handle)) {
8752 return;
8753 }
8754
8755 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
8756
8757 if (!(parser = sdp_parse(NULL((void*)0), r_sdp, (int) strlen(r_sdp), 0))) {
8758 return;
8759 }
8760
8761 if (!(sdp = sdp_session(parser))) {
8762 sdp_parser_free(parser);
8763 return;
8764 }
8765
8766
8767 for (attr = sdp->sdp_attributes; attr; attr = attr->a_next) {
8768 if (zstr(attr->a_name)_zstr(attr->a_name)) {
8769 continue;
8770 }
8771
8772 if (!strcasecmp(attr->a_name, "ptime")) {
8773 dptime = atoi(attr->a_value);
8774 }
8775 }
8776
8777
8778 for (m = sdp->sdp_media; m; m = m->m_next) {
8779
8780 ptime = dptime;
8781 //maxptime = dmaxptime;
8782
8783 if (m->m_proto == sdp_proto_rtp) {
8784 sdp_rtpmap_t *map;
8785 for (attr = m->m_attributes; attr; attr = attr->a_next) {
8786 if (!strcasecmp(attr->a_name, "ptime") && attr->a_value) {
8787 ptime = atoi(attr->a_value);
8788 } else if (!strcasecmp(attr->a_name, "maxptime") && attr->a_value) {
8789 //maxptime = atoi(attr->a_value);
8790 }
8791 }
8792
8793 for (map = m->m_rtpmaps; map; map = map->rm_next) {
8794 a_engine->cur_payload_map->iananame = switch_core_session_strdup(session, map->rm_encoding)switch_core_perform_session_strdup(session, map->rm_encoding
, "src/switch_core_media.c", (const char *)__func__, 8794)
;
8795 a_engine->cur_payload_map->rm_rate = map->rm_rate;
8796 a_engine->cur_payload_map->adv_rm_rate = map->rm_rate;
8797 a_engine->cur_payload_map->codec_ms = ptime;
8798 switch_core_media_set_codec(session, 0, smh->mparams->codec_flags);
8799 break;
8800 }
8801
8802 break;
8803 }
8804 }
8805
8806 sdp_parser_free(parser);
8807
8808}
8809#ifdef _MSC_VER
8810#pragma warning(pop)
8811#endif
8812
8813SWITCH_DECLARE (void)__attribute__((visibility("default"))) void switch_core_media_recover_session(switch_core_session_t *session)
8814{
8815 const char *ip;
8816 const char *port;
8817 const char *a_ip;
8818 const char *r_ip;
8819 const char *r_port;
8820 const char *tmp;
8821 switch_rtp_engine_t *a_engine, *v_engine;
8822 switch_media_handle_t *smh;
8823
8824 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_core_media.c"
, 8824, __PRETTY_FUNCTION__))
;
8825
8826 if (!(smh = session->media_handle)) {
8827 return;
8828 }
8829
8830 ip = switch_channel_get_variable(session->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE)switch_channel_get_variable_dup(session->channel, "local_media_ip"
, SWITCH_TRUE, -1)
;
8831 port = switch_channel_get_variable(session->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE)switch_channel_get_variable_dup(session->channel, "local_media_port"
, SWITCH_TRUE, -1)
;
8832
8833 if (switch_channel_test_flag(session->channel, CF_PROXY_MODE) || !(ip && port)) {
8834 return;
8835 } else {
8836 a_ip = switch_channel_get_variable(session->channel, SWITCH_ADVERTISED_MEDIA_IP_VARIABLE)switch_channel_get_variable_dup(session->channel, "advertised_media_ip"
, SWITCH_TRUE, -1)
;
8837 r_ip = switch_channel_get_variable(session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE)switch_channel_get_variable_dup(session->channel, "remote_media_ip"
, SWITCH_TRUE, -1)
;
8838 r_port = switch_channel_get_variable(session->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE)switch_channel_get_variable_dup(session->channel, "remote_media_port"
, SWITCH_TRUE, -1)
;
8839 }
8840
8841 a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
8842 v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
8843
8844 a_engine->cur_payload_map->iananame = a_engine->cur_payload_map->rm_encoding = (char *) switch_channel_get_variable(session->channel, "rtp_use_codec_name")switch_channel_get_variable_dup(session->channel, "rtp_use_codec_name"
, SWITCH_TRUE, -1)
;
8845 a_engine->cur_payload_map->rm_fmtp = (char *) switch_channel_get_variable(session->channel, "rtp_use_codec_fmtp")switch_channel_get_variable_dup(session->channel, "rtp_use_codec_fmtp"
, SWITCH_TRUE, -1)
;
8846
8847 if ((tmp = switch_channel_get_variable(session->channel, SWITCH_R_SDP_VARIABLE)switch_channel_get_variable_dup(session->channel, "switch_r_sdp"
, SWITCH_TRUE, -1)
)) {
8848 smh->mparams->remote_sdp_str = switch_core_session_strdup(session, tmp)switch_core_perform_session_strdup(session, tmp, "src/switch_core_media.c"
, (const char *)__func__, 8848)
;
8849 }
8850
8851 if ((tmp = switch_channel_get_variable(session->channel, "rtp_use_timer_name")switch_channel_get_variable_dup(session->channel, "rtp_use_timer_name"
, SWITCH_TRUE, -1)
)) {
8852 smh->mparams->timer_name = switch_core_session_strdup(session, tmp)switch_core_perform_session_strdup(session, tmp, "src/switch_core_media.c"
, (const char *)__func__, 8852)
;
8853 }
8854
8855 if ((tmp = switch_channel_get_variable(session->channel, "rtp_last_audio_codec_string")switch_channel_get_variable_dup(session->channel, "rtp_last_audio_codec_string"
, SWITCH_TRUE, -1)
)) {
8856 const char *vtmp = switch_channel_get_variable(session->channel, "rtp_last_video_codec_string")switch_channel_get_variable_dup(session->channel, "rtp_last_video_codec_string"
, SWITCH_TRUE, -1)
;
8857 switch_channel_set_variable_printf(session->channel, "rtp_use_codec_string", "%s%s%s", tmp, vtmp ? "," : "", vtmp ? vtmp : "");
8858 }
8859
8860 if ((tmp = switch_channel_get_variable(session->channel, "rtp_use_codec_string")switch_channel_get_variable_dup(session->channel, "rtp_use_codec_string"
, SWITCH_TRUE, -1)
)) {
8861 char *tmp_codec_string = switch_core_session_strdup(smh->session, tmp)switch_core_perform_session_strdup(smh->session, tmp, "src/switch_core_media.c"
, (const char *)__func__, 8861)
;
8862 smh->codec_order_last = switch_separate_string(tmp_codec_string, ',', smh->codec_order, SWITCH_MAX_CODECS50);
8863 smh->mparams->num_codecs = switch_loadable_module_get_codecs_sorted(smh->codecs, SWITCH_MAX_CODECS50, smh->codec_order, smh->codec_order_last);
8864 }
8865
8866 if ((tmp = switch_channel_get_variable(session->channel, "rtp_2833_send_payload")switch_channel_get_variable_dup(session->channel, "rtp_2833_send_payload"
, SWITCH_TRUE, -1)
)) {
8867 smh->mparams->te = (switch_payload_t)atoi(tmp);
8868 }
8869
8870 if ((tmp = switch_channel_get_variable(session->channel, "rtp_2833_recv_payload")switch_channel_get_variable_dup(session->channel, "rtp_2833_recv_payload"
, SWITCH_TRUE, -1)
)) {
8871 smh->mparams->recv_te = (switch_payload_t)atoi(tmp);
8872 }
8873
8874 if ((tmp = switch_channel_get_variable(session->channel, "rtp_use_codec_rate")switch_channel_get_variable_dup(session->channel, "rtp_use_codec_rate"
, SWITCH_TRUE, -1)
)) {
8875 a_engine->cur_payload_map->rm_rate = atoi(tmp);
8876 a_engine->cur_payload_map->adv_rm_rate = a_engine->cur_payload_map->rm_rate;
8877 }
8878
8879 if ((tmp = switch_channel_get_variable(session->channel, "rtp_use_codec_ptime")switch_channel_get_variable_dup(session->channel, "rtp_use_codec_ptime"
, SWITCH_TRUE, -1)
)) {
8880 a_engine->cur_payload_map->codec_ms = atoi(tmp);
8881 }
8882
8883 if ((tmp = switch_channel_get_variable(session->channel, "rtp_use_codec_channels")switch_channel_get_variable_dup(session->channel, "rtp_use_codec_channels"
, SWITCH_TRUE, -1)
)) {
8884 a_engine->cur_payload_map->channels = atoi(tmp);
8885 }
8886
8887 if ((tmp = switch_channel_get_variable(session->channel, "rtp_use_pt")switch_channel_get_variable_dup(session->channel, "rtp_use_pt"
, SWITCH_TRUE, -1)
)) {
8888 a_engine->cur_payload_map->pt = a_engine->cur_payload_map->agreed_pt = (switch_payload_t)(smh->payload_space = atoi(tmp));
8889 }
8890
8891 if ((tmp = switch_channel_get_variable(session->channel, "rtp_audio_recv_pt")switch_channel_get_variable_dup(session->channel, "rtp_audio_recv_pt"
, SWITCH_TRUE, -1)
)) {
8892 a_engine->cur_payload_map->recv_pt = (switch_payload_t)atoi(tmp);
8893 }
8894
8895 switch_core_media_set_codec(session, 0, smh->mparams->codec_flags);
8896
8897 a_engine->adv_sdp_ip = smh->mparams->extrtpip = (char *) ip;
8898 a_engine->adv_sdp_port = a_engine->local_sdp_port = (switch_port_t)atoi(port);
8899 a_engine->codec_negotiated = 1;
8900
8901 if (!zstr(ip)_zstr(ip)) {
8902 a_engine->local_sdp_ip = switch_core_session_strdup(session, ip)switch_core_perform_session_strdup(session, ip, "src/switch_core_media.c"
, (const char *)__func__, 8902)
;
8903 smh->mparams->rtpip = a_engine->local_sdp_ip;
8904 }
8905
8906 if (!zstr(a_ip)_zstr(a_ip)) {
8907 a_engine->adv_sdp_ip = switch_core_session_strdup(session, a_ip)switch_core_perform_session_strdup(session, a_ip, "src/switch_core_media.c"
, (const char *)__func__, 8907)
;
8908 }
8909
8910 if (r_ip && r_port) {
8911 a_engine->cur_payload_map->remote_sdp_ip = (char *) r_ip;
8912 a_engine->cur_payload_map->remote_sdp_port = (switch_port_t)atoi(r_port);
8913 }
8914
8915 if (switch_channel_test_flag(session->channel, CF_VIDEO)) {
8916 if ((tmp = switch_channel_get_variable(session->channel, "rtp_use_video_pt")switch_channel_get_variable_dup(session->channel, "rtp_use_video_pt"
, SWITCH_TRUE, -1)
)) {
8917 v_engine->cur_payload_map->pt = v_engine->cur_payload_map->agreed_pt = (switch_payload_t)atoi(tmp);
8918 }
8919
8920 if ((tmp = switch_channel_get_variable(session->channel, "rtp_video_recv_pt")switch_channel_get_variable_dup(session->channel, "rtp_video_recv_pt"
, SWITCH_TRUE, -1)
)) {
8921 v_engine->cur_payload_map->recv_pt = (switch_payload_t)atoi(tmp);
8922 }
8923
8924 v_engine->cur_payload_map->rm_encoding = (char *) switch_channel_get_variable(session->channel, "rtp_use_video_codec_name")switch_channel_get_variable_dup(session->channel, "rtp_use_video_codec_name"
, SWITCH_TRUE, -1)
;
8925 v_engine->cur_payload_map->rm_fmtp = (char *) switch_channel_get_variable(session->channel, "rtp_use_video_codec_fmtp")switch_channel_get_variable_dup(session->channel, "rtp_use_video_codec_fmtp"
, SWITCH_TRUE, -1)
;
8926
8927 ip = switch_channel_get_variable(session->channel, SWITCH_LOCAL_VIDEO_IP_VARIABLE)switch_channel_get_variable_dup(session->channel, "local_video_ip"
, SWITCH_TRUE, -1)
;
8928 port = switch_channel_get_variable(session->channel, SWITCH_LOCAL_VIDEO_PORT_VARIABLE)switch_channel_get_variable_dup(session->channel, "local_video_port"
, SWITCH_TRUE, -1)
;
8929 r_ip = switch_channel_get_variable(session->channel, SWITCH_REMOTE_VIDEO_IP_VARIABLE)switch_channel_get_variable_dup(session->channel, "remote_video_ip"
, SWITCH_TRUE, -1)
;
8930 r_port = switch_channel_get_variable(session->channel, SWITCH_REMOTE_VIDEO_PORT_VARIABLE)switch_channel_get_variable_dup(session->channel, "remote_video_port"
, SWITCH_TRUE, -1)
;
8931
8932 switch_channel_set_flag(session->channel, CF_VIDEO_POSSIBLE)switch_channel_set_flag_value(session->channel, CF_VIDEO_POSSIBLE
, 1)
;
8933
8934 if ((tmp = switch_channel_get_variable(session->channel, "rtp_use_video_codec_rate")switch_channel_get_variable_dup(session->channel, "rtp_use_video_codec_rate"
, SWITCH_TRUE, -1)
)) {
8935 v_engine->cur_payload_map->rm_rate = atoi(tmp);
8936 v_engine->cur_payload_map->adv_rm_rate = v_engine->cur_payload_map->rm_rate;
8937 }
8938
8939 if ((tmp = switch_channel_get_variable(session->channel, "rtp_use_video_codec_ptime")switch_channel_get_variable_dup(session->channel, "rtp_use_video_codec_ptime"
, SWITCH_TRUE, -1)
)) {
8940 v_engine->cur_payload_map->codec_ms = atoi(tmp);
8941 }
8942
8943 v_engine->adv_sdp_port = v_engine->local_sdp_port = (switch_port_t)atoi(port);
8944 v_engine->local_sdp_ip = smh->mparams->rtpip;
8945
8946 if (r_ip && r_port) {
8947 v_engine->cur_payload_map->remote_sdp_ip = (char *) r_ip;
8948 v_engine->cur_payload_map->remote_sdp_port = (switch_port_t)atoi(r_port);
8949 }
8950 }
8951
8952 switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL((void*)0), 0, NULL((void*)0), 1);
8953 switch_core_media_set_video_codec(session, 1);
8954
8955 if (switch_core_media_activate_rtp(session) != SWITCH_STATUS_SUCCESS) {
8956 return;
8957 }
8958
8959 switch_core_session_get_recovery_crypto_key(session, SWITCH_MEDIA_TYPE_AUDIO);
8960 switch_core_session_get_recovery_crypto_key(session, SWITCH_MEDIA_TYPE_VIDEO);
8961
8962
8963 if ((tmp = switch_channel_get_variable(session->channel, "rtp_last_audio_local_crypto_key")switch_channel_get_variable_dup(session->channel, "rtp_last_audio_local_crypto_key"
, SWITCH_TRUE, -1)
) && a_engine->ssec[a_engine->crypto_type].remote_crypto_key) {
8964 int idx = atoi(tmp);
8965
8966 a_engine->ssec[a_engine->crypto_type].local_crypto_key = switch_core_session_strdup(session, tmp)switch_core_perform_session_strdup(session, tmp, "src/switch_core_media.c"
, (const char *)__func__, 8966)
;
8967 switch_core_media_add_crypto(&a_engine->ssec[a_engine->crypto_type], a_engine->ssec[a_engine->crypto_type].local_crypto_key, SWITCH_RTP_CRYPTO_SEND);
8968 switch_core_media_add_crypto(&a_engine->ssec[a_engine->crypto_type], a_engine->ssec[a_engine->crypto_type].remote_crypto_key, SWITCH_RTP_CRYPTO_RECV);
8969 switch_channel_set_flag(smh->session->channel, CF_SECURE)switch_channel_set_flag_value(smh->session->channel, CF_SECURE
, 1)
;
8970
8971 switch_rtp_add_crypto_key(a_engine->rtp_session, SWITCH_RTP_CRYPTO_SEND, idx,
8972 a_engine->crypto_type,
8973 a_engine->ssec[a_engine->crypto_type].local_raw_key,
8974 SUITES[a_engine->crypto_type].keylen);
8975
8976 switch_rtp_add_crypto_key(a_engine->rtp_session, SWITCH_RTP_CRYPTO_RECV,
8977 a_engine->ssec[a_engine->crypto_type].crypto_tag,
8978 a_engine->crypto_type,
8979 a_engine->ssec[a_engine->crypto_type].remote_raw_key,
8980 SUITES[a_engine->crypto_type].keylen);
8981 }
8982
8983
8984 if (switch_core_media_ready(session, SWITCH_MEDIA_TYPE_AUDIO)) {
8985 switch_rtp_set_telephony_event(a_engine->rtp_session, smh->mparams->te);
8986 switch_rtp_set_telephony_recv_event(a_engine->rtp_session, smh->mparams->recv_te);
8987 }
8988
8989}
8990
8991
8992SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_init(void)
8993{
8994 switch_core_gen_certs(DTLS_SRTP_FNAME"dtls-srtp" ".pem");
8995}
8996
8997SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_media_deinit(void)
8998{
8999
9000}
9001
9002static int payload_number(const char *name)
9003{
9004 if (!strcasecmp(name, "pcmu")) {
9005 return 0;
9006 }
9007
9008 if (!strcasecmp(name, "pcma")) {
9009 return 8;
9010 }
9011
9012 if (!strcasecmp(name, "gsm")) {
9013 return 3;
9014 }
9015
9016 if (!strcasecmp(name, "g722")) {
9017 return 9;
9018 }
9019
9020 if (!strcasecmp(name, "g729")) {
9021 return 18;
9022 }
9023
9024 if (!strcasecmp(name, "dvi4")) {
9025 return 5;
9026 }
9027
9028 if (!strcasecmp(name, "h261")) {
9029 return 31;
9030 }
9031
9032 if (!strcasecmp(name, "h263")) {
9033 return 34;
9034 }
9035
9036 return -1;
9037}
9038
9039static int find_pt(const char *sdp, const char *name)
9040{
9041 const char *p;
9042
9043 if ((p = switch_stristr(name, sdp))) {
9044 if (p < end_of_p(sdp)(*sdp == '\0' ? sdp : sdp + strlen(sdp) - 1) && *(p+strlen(name)) == '/' && *(p-1) == ' ') {
9045 p -= 2;
9046
9047 while(*p > 47 && *p < 58) {
9048 p--;
9049 }
9050 p++;
9051
9052 if (p) {
9053 return atoi(p);
9054 }
9055 }
9056 }
9057
9058 return -1;
9059}
9060
9061
9062SWITCH_DECLARE(char *)__attribute__((visibility("default"))) char * switch_core_media_filter_sdp(const char *sdp_str, const char *cmd, const char *arg)
9063{
9064 char *new_sdp = NULL((void*)0);
9065 int pt = -1, te = -1;
9066 switch_size_t len;
9067 const char *i;
9068 char *o;
9069 int in_m = 0, m_tally = 0, slash = 0;
9070 int number = 0, skip = 0;
9071 int remove = !strcasecmp(cmd, "remove");
9072 int only = !strcasecmp(cmd, "only");
9073 char *end = end_of_p((char *)sdp_str)(*(char *)sdp_str == '\0' ? (char *)sdp_str : (char *)sdp_str
+ strlen((char *)sdp_str) - 1)
;
9074 int tst;
9075 end++;
9076
9077
9078 if (remove || only) {
9079 pt = payload_number(arg);
9080
9081 if (pt < 0) {
9082 pt = find_pt(sdp_str, arg);
9083 }
9084 } else {
9085 return NULL((void*)0);
9086 }
9087
9088 if (only) {
9089 te = find_pt(sdp_str, "telephone-event");
9090 }
9091
9092
9093 len = strlen(sdp_str) + 2;
9094 new_sdp = malloc(len);
9095 o = new_sdp;
9096 i = sdp_str;
9097
9098
9099 while(i && *i && i < end) {
9100
9101 if (*i == 'm' && *(i+1) == '=') {
9102 in_m = 1;
9103 m_tally++;
9104 }
9105
9106 if (in_m) {
9107 if (*i == '\r' || *i == '\n') {
9108 in_m = 0;
9109 slash = 0;
9110 } else {
9111 if (*i == '/') {
9112 slash++;
9113 while(*i != ' ' && i < end) {
9114 *o++ = *i++;
9115 }
9116
9117 *o++ = *i++;
9118 }
9119
9120 if (slash && switch_is_leading_number(i)) {
9121
9122
9123 number = atoi(i);
9124
9125 while(i < end && ((*i > 47 && *i < 58) || *i == ' ')) {
9126
9127 if (remove) {
9128 tst = (number != pt);
9129 } else {
9130 tst = (number == pt || number == te);
9131 }
9132
9133 if (tst) {
9134 *o++ = *i;
9135 }
9136 i++;
9137
9138 if (*i == ' ') {
9139 break;
9140 }
9141
9142 }
9143
9144 if (remove) {
9145 tst = (number == pt);
9146 } else {
9147 tst = (number != pt && number != te);
9148 }
9149
9150 if (tst) {
9151 skip++;
9152 }
9153 }
9154 }
9155 }
9156
9157 while (i < end && !strncasecmp(i, "a=rtpmap:", 9)) {
9158 const char *t = i + 9;
9159
9160 number = atoi(t);
9161
9162 if (remove) {
9163 tst = (number == pt);
9164 } else {
9165 tst = (number != pt && number != te);
9166 }
9167
9168 while(i < end && (*i != '\r' && *i != '\n')) {
9169 if (!tst) *o++ = *i;
9170 i++;
9171 }
9172
9173 while(i < end && (*i == '\r' || *i == '\n')) {
9174 if (!tst) *o++ = *i;
9175 i++;
9176 }
9177 }
9178
9179 while (i < end && !strncasecmp(i, "a=fmtp:", 7)) {
9180 const char *t = i + 7;
9181
9182 number = atoi(t);
9183
9184 if (remove) {
9185 tst = (number == pt);
9186 } else {
9187 tst = (number != pt && number != te);
9188 }
9189
9190 while(i < end && (*i != '\r' && *i != '\n')) {
9191 if (!tst) *o++ = *i;
9192 i++;
9193 }
9194
9195 while(i < end && (*i == '\r' || *i == '\n')) {
9196 if (!tst) *o++ = *i;
9197 i++;
9198 }
9199 }
9200
9201 if (!skip) {
9202 *o++ = *i;
9203 }
9204
9205 skip = 0;
9206
9207 i++;
9208 }
9209
9210 *o = '\0';
9211
9212 return new_sdp;
9213}
9214
9215SWITCH_DECLARE(char *)__attribute__((visibility("default"))) char * switch_core_media_process_sdp_filter(const char *sdp, const char *cmd_buf, switch_core_session_t *session)
9216{
9217 switch_channel_t *channel = switch_core_session_get_channel(session);
9218 char *cmd = switch_core_session_strdup(session, cmd_buf)switch_core_perform_session_strdup(session, cmd_buf, "src/switch_core_media.c"
, (const char *)__func__, 9218)
;
9219 int argc = 0;
9220 char *argv[50];
9221 int x = 0;
9222 char *patched_sdp = NULL((void*)0);
9223
9224 argc = switch_split(cmd, '|', argv)switch_separate_string(cmd, '|', argv, (sizeof(argv) / sizeof
(argv[0])))
;
9225
9226 for (x = 0; x < argc; x++) {
9227 char *command = argv[x];
9228 char *arg = strchr(command, '(')(__extension__ (__builtin_constant_p ('(') && !__builtin_constant_p
(command) && ('(') == '\0' ? (char *) __rawmemchr (command
, '(') : __builtin_strchr (command, '(')))
;
9229
9230 if (arg) {
9231 char *e = switch_find_end_paren(arg, '(', ')');
9232 *arg++ = '\0';
9233 if (e) *e = '\0';
9234 }
9235
9236 if (zstr(command)_zstr(command) || zstr(arg)_zstr(arg)) {
9237 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 9237, (const char*)switch_channel_get_session(channel
)
, SWITCH_LOG_WARNING, "%s SDP FILTER PARSE ERROR\n", switch_channel_get_name(channel));
9238 } else {
9239 char *tmp_sdp = NULL((void*)0);
9240
9241 if (patched_sdp) {
9242 tmp_sdp = switch_core_media_filter_sdp(patched_sdp, command, arg);
9243 } else {
9244 tmp_sdp = switch_core_media_filter_sdp(sdp, command, arg);
9245 }
9246
9247
9248 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel)SWITCH_CHANNEL_ID_SESSION, "src/switch_core_media.c", (const char
*)__func__, 9248, (const char*)switch_channel_get_session(channel
)
, SWITCH_LOG_DEBUG,
9249 "%s Filter command %s(%s)\nFROM:\n==========\n%s\nTO:\n==========\n%s\n\n",
9250 switch_channel_get_name(channel),
9251 command, arg, patched_sdp ? patched_sdp : sdp, tmp_sdp);
9252
9253
9254 if (tmp_sdp) {
9255 switch_safe_free(patched_sdp)if (patched_sdp) {free(patched_sdp);patched_sdp=((void*)0);};
9256 patched_sdp = tmp_sdp;
9257 }
9258 }
9259 }
9260
9261 return patched_sdp;
9262
9263}
9264
9265/* For Emacs:
9266 * Local Variables:
9267 * mode:c
9268 * indent-tabs-mode:t
9269 * tab-width:4
9270 * c-basic-offset:4
9271 * End:
9272 * For VIM:
9273 * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
9274 */
9275