Bug Summary

File:src/switch_ivr_bridge.c
Location:line 83, column 7
Description:Access to field 'flags' results in a dereference of a null pointer (loaded from variable 'read_frame')

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_ivr_bridge.c -- IVR Library
29 *
30 */
31
32#include <switch.h>
33#define DEFAULT_LEAD_FRAMES10 10
34
35static const switch_state_handler_table_t audio_bridge_peer_state_handlers;
36static void cleanup_proxy_mode_a(switch_core_session_t *session);
37static void cleanup_proxy_mode_b(switch_core_session_t *session);
38
39/* Bridge Related Stuff*/
40/*********************************************************************************/
41
42#ifdef SWITCH_VIDEO_IN_THREADS
43struct vid_helper {
44 switch_core_session_t *session_a;
45 switch_core_session_t *session_b;
46 int up;
47};
48
49static void *SWITCH_THREAD_FUNC video_bridge_thread(switch_thread_t *thread, void *obj)
50{
51 struct vid_helper *vh = obj;
52 switch_channel_t *channel = switch_core_session_get_channel(vh->session_a);
53 switch_channel_t *b_channel = switch_core_session_get_channel(vh->session_b);
54 switch_status_t status;
55 switch_frame_t *read_frame = 0;
1
'read_frame' initialized to a null pointer value
56 const char *source = switch_channel_get_variable(channel, "source")switch_channel_get_variable_dup(channel, "source", SWITCH_TRUE
, -1)
;
57 const char *b_source = switch_channel_get_variable(b_channel, "source")switch_channel_get_variable_dup(b_channel, "source", SWITCH_TRUE
, -1)
;
58
59 vh->up = 1;
60
61 switch_core_session_read_lock(vh->session_a);
62 switch_core_session_read_lock(vh->session_b);
63
64 if (!switch_stristr("loopback", source) && !switch_stristr("loopback", b_source)) {
65 switch_channel_set_flag(channel, CF_VIDEO_PASSIVE)switch_channel_set_flag_value(channel, CF_VIDEO_PASSIVE, 1);
66 //switch_channel_set_flag(b_channel, CF_VIDEO_PASSIVE);
67 }
68
69 switch_core_session_refresh_video(vh->session_a);
70 switch_core_session_refresh_video(vh->session_b);
71
72 while (switch_channel_up_nosig(channel)(switch_channel_get_state(channel) < CS_HANGUP) && switch_channel_up_nosig(b_channel)(switch_channel_get_state(b_channel) < CS_HANGUP) && vh->up == 1) {
2
Loop condition is true. Entering loop body
73
74 if (switch_channel_media_up(channel)(switch_channel_test_flag(channel, CF_ANSWERED) || switch_channel_test_flag
(channel, CF_EARLY_MEDIA))
) {
3
Taking false branch
75 status = switch_core_session_read_video_frame(vh->session_a, &read_frame, SWITCH_IO_FLAG_NONE, 0);
76
77 if (!SWITCH_READ_ACCEPTABLE(status)(status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK
|| status == SWITCH_STATUS_INUSE)
) {
78 switch_cond_next();
79 continue;
80 }
81 }
82
83 if (switch_test_flag(read_frame, SFF_CNG)((read_frame)->flags & SFF_CNG)) {
4
Within the expansion of the macro 'switch_test_flag':
a
Access to field 'flags' results in a dereference of a null pointer (loaded from variable 'read_frame')
84 continue;
85 }
86
87 if (switch_channel_media_up(b_channel)(switch_channel_test_flag(b_channel, CF_ANSWERED) || switch_channel_test_flag
(b_channel, CF_EARLY_MEDIA))
) {
88 if (switch_core_session_write_video_frame(vh->session_b, read_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
89 switch_cond_next();
90 continue;
91 }
92 }
93
94 }
95
96 switch_channel_clear_flag(channel, CF_VIDEO_PASSIVE);
97 //switch_channel_clear_flag(b_channel, CF_VIDEO_PASSIVE);
98
99 switch_core_session_kill_channel(vh->session_b, SWITCH_SIG_BREAK)switch_core_session_perform_kill_channel(vh->session_b, "src/switch_ivr_bridge.c"
, (const char *)__func__, 99, SWITCH_SIG_BREAK)
;
100 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(vh->session_a)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_bridge.c", (const char
*)__func__, 100, (const char*)(vh->session_a)
, SWITCH_LOG_DEBUG, "%s video thread ended.\n", switch_channel_get_name(channel));
101
102 switch_core_session_refresh_video(vh->session_a);
103 switch_core_session_refresh_video(vh->session_b);
104
105 switch_core_session_rwunlock(vh->session_a);
106 switch_core_session_rwunlock(vh->session_b);
107
108 vh->up = 0;
109 return NULL((void*)0);
110}
111
112static switch_thread_t *launch_video(struct vid_helper *vh)
113{
114 switch_thread_t *thread;
115 switch_threadattr_t *thd_attr = NULL((void*)0);
116
117 switch_threadattr_create(&thd_attr, switch_core_session_get_pool(vh->session_a));
118 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024);
119 switch_thread_create(&thread, thd_attr, video_bridge_thread, vh, switch_core_session_get_pool(vh->session_a));
120 return thread;
121}
122#endif
123
124
125static void send_display(switch_core_session_t *session, switch_core_session_t *peer_session)
126{
127
128 switch_core_session_message_t *msg;
129 switch_caller_profile_t *caller_profile, *peer_caller_profile;
130 switch_channel_t *caller_channel, *peer_channel;
131 const char *name, *number, *p;
132
133 caller_channel = switch_core_session_get_channel(session);
134 peer_channel = switch_core_session_get_channel(peer_session);
135
136 caller_profile = switch_channel_get_caller_profile(caller_channel);
137 peer_caller_profile = switch_channel_get_caller_profile(peer_channel);
138
139 if (switch_channel_test_flag(caller_channel, CF_BRIDGE_ORIGINATOR)) {
140 if (!zstr(peer_caller_profile->caller_id_name)_zstr(peer_caller_profile->caller_id_name)) {
141 name = peer_caller_profile->caller_id_name;
142 } else {
143 name = caller_profile->caller_id_name;
144 }
145
146 if (!zstr(peer_caller_profile->caller_id_number)_zstr(peer_caller_profile->caller_id_number)) {
147 number = peer_caller_profile->caller_id_number;
148 } else {
149 number = caller_profile->caller_id_number;
150 }
151
152 if (zstr(number)_zstr(number)) {
153 number = "UNKNOWN";
154 }
155 } else {
156 name = caller_profile->callee_id_name;
157 number = caller_profile->callee_id_number;
158
159 if (zstr(number)_zstr(number)) {
160 number = caller_profile->destination_number;
161 }
162 }
163
164
165 if (zstr(name)_zstr(name)) {
166 name = number;
167 }
168
169 if ((p = strrchr(number, '/'))) {
170 number = p + 1;
171 }
172 if ((p = strrchr(name, '/'))) {
173 name = p + 1;
174 }
175
176 msg = switch_core_session_alloc(peer_session, sizeof(*msg))switch_core_perform_session_alloc(peer_session, sizeof(*msg),
"src/switch_ivr_bridge.c", (const char *)__func__, 176)
;
177 MESSAGE_STAMP_FFL(msg)msg->_file = "src/switch_ivr_bridge.c"; msg->_func = (const
char *)__func__; msg->_line = 177
;
178 msg->message_id = SWITCH_MESSAGE_INDICATE_DISPLAY;
179 msg->string_array_arg[0] = switch_core_session_strdup(peer_session, name)switch_core_perform_session_strdup(peer_session, name, "src/switch_ivr_bridge.c"
, (const char *)__func__, 179)
;
180 msg->string_array_arg[1] = switch_core_session_strdup(peer_session, number)switch_core_perform_session_strdup(peer_session, number, "src/switch_ivr_bridge.c"
, (const char *)__func__, 180)
;
181 msg->from = __FILE__"src/switch_ivr_bridge.c";
182 switch_core_session_queue_message(peer_session, msg);
183
184}
185
186
187SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_ivr_bridge_display(switch_core_session_t *session, switch_core_session_t *peer_session)
188{
189
190 send_display(session, peer_session);
191 send_display(peer_session, session);
192
193}
194
195struct switch_ivr_bridge_data {
196 switch_core_session_t *session;
197 char b_uuid[SWITCH_UUID_FORMATTED_LENGTH256 + 1];
198 int stream_id;
199 switch_input_callback_function_t input_callback;
200 void *session_data;
201 int clean_exit;
202 int done;
203 struct switch_ivr_bridge_data *other_leg_data;
204};
205typedef struct switch_ivr_bridge_data switch_ivr_bridge_data_t;
206
207static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
208{
209 switch_ivr_bridge_data_t *data = obj;
210 int stream_id = 0, pre_b = 0, ans_a = 0, ans_b = 0, originator = 0;
211 switch_input_callback_function_t input_callback;
212 switch_core_session_message_t msg = { 0 };
213 void *user_data;
214 switch_channel_t *chan_a, *chan_b;
215 switch_frame_t *read_frame;
216 switch_core_session_t *session_a, *session_b;
217 uint32_t read_frame_count = 0;
218 const char *app_name = NULL((void*)0), *app_arg = NULL((void*)0);
219 int inner_bridge = 0, exec_check = 0;
220 switch_codec_t silence_codec = { 0 };
221 switch_frame_t silence_frame = { 0 };
222 int16_t silence_data[SWITCH_RECOMMENDED_BUFFER_SIZE8192 / 2] = { 0 };
223 const char *silence_var;
224 int silence_val = 0, bypass_media_after_bridge = 0;
225 const char *bridge_answer_timeout = NULL((void*)0);
226 int bridge_filter_dtmf, answer_timeout, sent_update = 0;
227 time_t answer_limit = 0;
228 const char *exec_app = NULL((void*)0);
229 const char *exec_data = NULL((void*)0);
230
231#ifdef SWITCH_VIDEO_IN_THREADS
232 switch_thread_t *vid_thread = NULL((void*)0);
233 struct vid_helper vh = { 0 };
234 uint32_t vid_launch = 0;
235#endif
236 data->clean_exit = 0;
237
238 session_a = data->session;
239 if (!(session_b = switch_core_session_locate(data->b_uuid)switch_core_session_perform_locate(data->b_uuid, "src/switch_ivr_bridge.c"
, (const char *)__func__, 239)
)) {
240 return NULL((void*)0);
241 }
242
243 input_callback = data->input_callback;
244 user_data = data->session_data;
245 stream_id = data->stream_id;
246
247 chan_a = switch_core_session_get_channel(session_a);
248 chan_b = switch_core_session_get_channel(session_b);
249
250
251 if ((exec_app = switch_channel_get_variable(chan_a, "bridge_pre_execute_app")switch_channel_get_variable_dup(chan_a, "bridge_pre_execute_app"
, SWITCH_TRUE, -1)
)) {
252 exec_data = switch_channel_get_variable(chan_a, "bridge_pre_execute_data")switch_channel_get_variable_dup(chan_a, "bridge_pre_execute_data"
, SWITCH_TRUE, -1)
;
253 }
254
255 bypass_media_after_bridge = switch_channel_test_flag(chan_a, CF_BYPASS_MEDIA_AFTER_BRIDGE);
256 switch_channel_clear_flag(chan_a, CF_BYPASS_MEDIA_AFTER_BRIDGE);
257
258 ans_a = switch_channel_test_flag(chan_a, CF_ANSWERED);
259
260 if ((originator = switch_channel_test_flag(chan_a, CF_BRIDGE_ORIGINATOR))) {
261 pre_b = switch_channel_test_flag(chan_a, CF_EARLY_MEDIA);
262 ans_b = switch_channel_test_flag(chan_b, CF_ANSWERED);
263 }
264
265 inner_bridge = switch_channel_test_flag(chan_a, CF_INNER_BRIDGE);
266
267 if (!switch_channel_test_flag(chan_a, CF_ANSWERED) && (bridge_answer_timeout = switch_channel_get_variable(chan_a, "bridge_answer_timeout")switch_channel_get_variable_dup(chan_a, "bridge_answer_timeout"
, SWITCH_TRUE, -1)
)) {
268 if ((answer_timeout = atoi(bridge_answer_timeout)) < 0) {
269 answer_timeout = 0;
270 } else {
271 answer_limit = switch_epoch_time_now(NULL((void*)0)) + answer_timeout;
272 }
273 }
274
275 switch_channel_clear_flag(chan_a, CF_INTERCEPT);
276 switch_channel_clear_flag(chan_a, CF_INTERCEPTED);
277
278 switch_channel_set_flag(chan_a, CF_BRIDGED)switch_channel_set_flag_value(chan_a, CF_BRIDGED, 1);
279
280 switch_channel_wait_for_flag(chan_b, CF_BRIDGED, SWITCH_TRUE, 10000, chan_a);
281
282 if (!switch_channel_test_flag(chan_b, CF_BRIDGED)) {
283 if (!(switch_channel_test_flag(chan_b, CF_TRANSFER) || switch_channel_test_flag(chan_b, CF_REDIRECT)
284 || switch_channel_get_state(chan_b) == CS_RESET)) {
285 switch_channel_hangup(chan_b, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(chan_b, "src/switch_ivr_bridge.c"
, (const char *)__func__, 285, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER
)
;
286 }
287 goto end_of_bridge_loop;
288 }
289
290 if (bypass_media_after_bridge) {
291 const char *source_a = switch_channel_get_variable(chan_a, "source")switch_channel_get_variable_dup(chan_a, "source", SWITCH_TRUE
, -1)
;
292 const char *source_b = switch_channel_get_variable(chan_b, "source")switch_channel_get_variable_dup(chan_b, "source", SWITCH_TRUE
, -1)
;
293
294 if (!source_a) source_a = "";
295 if (!source_b) source_b = "";
296
297 if (switch_stristr("loopback", source_a) || switch_stristr("loopback", source_b)) {
298 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_bridge.c", (const char
*)__func__, 298, (const char*)(session_a)
, SWITCH_LOG_WARNING, "Cannot bypass media while bridged to a loopback address.\n");
299 bypass_media_after_bridge = 0;
300 }
301 }
302
303 if ((silence_var = switch_channel_get_variable(chan_a, "bridge_generate_comfort_noise")switch_channel_get_variable_dup(chan_a, "bridge_generate_comfort_noise"
, SWITCH_TRUE, -1)
)) {
304 switch_codec_implementation_t read_impl = { 0 };
305 switch_core_session_get_read_impl(session_a, &read_impl);
306
307 if (!switch_channel_media_up(chan_a)(switch_channel_test_flag(chan_a, CF_ANSWERED) || switch_channel_test_flag
(chan_a, CF_EARLY_MEDIA))
) {
308 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_bridge.c", (const char
*)__func__, 308, (const char*)(session_a)
, SWITCH_LOG_ERROR, "Channel has no media!\n");
309 goto end_of_bridge_loop;
310 }
311
312 if (switch_true(silence_var)) {
313 silence_val = 1400;
314 } else {
315 if ((silence_val = atoi(silence_var)) < -1) {
316 silence_val = 0;
317 }
318 }
319
320 if (silence_val) {
321 if (switch_core_codec_init(&silence_codec,switch_core_codec_init_with_bitrate(&silence_codec, "L16"
, ((void*)0), read_impl.actual_samples_per_second, read_impl.
microseconds_per_packet / 1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE
| SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session_a))
322 "L16",switch_core_codec_init_with_bitrate(&silence_codec, "L16"
, ((void*)0), read_impl.actual_samples_per_second, read_impl.
microseconds_per_packet / 1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE
| SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session_a))
323 NULL,switch_core_codec_init_with_bitrate(&silence_codec, "L16"
, ((void*)0), read_impl.actual_samples_per_second, read_impl.
microseconds_per_packet / 1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE
| SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session_a))
324 read_impl.actual_samples_per_second,switch_core_codec_init_with_bitrate(&silence_codec, "L16"
, ((void*)0), read_impl.actual_samples_per_second, read_impl.
microseconds_per_packet / 1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE
| SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session_a))
325 read_impl.microseconds_per_packet / 1000,switch_core_codec_init_with_bitrate(&silence_codec, "L16"
, ((void*)0), read_impl.actual_samples_per_second, read_impl.
microseconds_per_packet / 1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE
| SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session_a))
326 1,switch_core_codec_init_with_bitrate(&silence_codec, "L16"
, ((void*)0), read_impl.actual_samples_per_second, read_impl.
microseconds_per_packet / 1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE
| SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session_a))
327 SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,switch_core_codec_init_with_bitrate(&silence_codec, "L16"
, ((void*)0), read_impl.actual_samples_per_second, read_impl.
microseconds_per_packet / 1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE
| SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session_a))
328 NULL, switch_core_session_get_pool(session_a))switch_core_codec_init_with_bitrate(&silence_codec, "L16"
, ((void*)0), read_impl.actual_samples_per_second, read_impl.
microseconds_per_packet / 1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE
| SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session_a))
!= SWITCH_STATUS_SUCCESS) {
329
330 silence_val = 0;
331 } else {
332 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_bridge.c", (const char
*)__func__, 332, (const char*)(session_a)
, SWITCH_LOG_DEBUG, "Setup generated silence from %s to %s at %d\n", switch_channel_get_name(chan_a),
333 switch_channel_get_name(chan_b), silence_val);
334 silence_frame.codec = &silence_codec;
335 silence_frame.data = silence_data;
336 silence_frame.buflen = sizeof(silence_data);
337 silence_frame.datalen = read_impl.decoded_bytes_per_packet;
338 silence_frame.samples = silence_frame.datalen / sizeof(int16_t);
339 }
340 }
341 }
342
343 bridge_filter_dtmf = switch_true(switch_channel_get_variable(chan_a, "bridge_filter_dtmf")switch_channel_get_variable_dup(chan_a, "bridge_filter_dtmf",
SWITCH_TRUE, -1)
);
344
345 for (;;) {
346 switch_channel_state_t b_state;
347 switch_status_t status;
348 switch_event_t *event;
349
350 if (switch_channel_test_flag(chan_a, CF_TRANSFER)) {
351 data->clean_exit = 1;
352 }
353
354 if (data->clean_exit || switch_channel_test_flag(chan_b, CF_TRANSFER)) {
355 switch_channel_clear_flag(chan_a, CF_HOLD);
356 switch_channel_clear_flag(chan_a, CF_SUSPEND);
357 goto end_of_bridge_loop;
358 }
359
360 if (!switch_channel_test_flag(chan_b, CF_BRIDGED)) {
361 goto end_of_bridge_loop;
362 }
363
364 if (!switch_channel_ready(chan_a)switch_channel_test_ready(chan_a, SWITCH_TRUE, SWITCH_FALSE)) {
365 if (switch_channel_up(chan_a)(switch_channel_check_signal(chan_a, SWITCH_TRUE) || switch_channel_get_state
(chan_a) < CS_HANGUP)
) {
366 data->clean_exit = 1;
367 }
368 goto end_of_bridge_loop;
369 }
370
371 if ((b_state = switch_channel_down_nosig(chan_b)(switch_channel_get_state(chan_b) >= CS_HANGUP))) {
372 goto end_of_bridge_loop;
373 }
374
375 if (switch_channel_test_flag(chan_a, CF_HOLD_ON_BRIDGE)) {
376 switch_core_session_message_t hmsg = { 0 };
377 switch_channel_clear_flag(chan_a, CF_HOLD_ON_BRIDGE);
378 hmsg.message_id = SWITCH_MESSAGE_INDICATE_HOLD;
379 hmsg.from = __FILE__"src/switch_ivr_bridge.c";
380 hmsg.numeric_arg = 1;
381 switch_core_session_receive_message(session_a, &hmsg)switch_core_session_perform_receive_message(session_a, &hmsg
, "src/switch_ivr_bridge.c", (const char *)__func__, 381)
;
382 }
383
384 if (read_frame_count > DEFAULT_LEAD_FRAMES10 && switch_channel_media_ack(chan_a)(!switch_channel_test_cap(chan_a, CC_MEDIA_ACK) || switch_channel_test_flag
(chan_a, CF_MEDIA_ACK))
&& switch_core_session_private_event_count(session_a)) {
385 switch_channel_set_flag(chan_b, CF_SUSPEND)switch_channel_set_flag_value(chan_b, CF_SUSPEND, 1);
386 msg.numeric_arg = 42;
387 msg.string_arg = data->b_uuid;
388 msg.message_id = SWITCH_MESSAGE_INDICATE_UNBRIDGE;
389 msg.from = __FILE__"src/switch_ivr_bridge.c";
390 switch_core_session_receive_message(session_a, &msg)switch_core_session_perform_receive_message(session_a, &msg
, "src/switch_ivr_bridge.c", (const char *)__func__, 390)
;
391 switch_ivr_parse_next_event(session_a);
392 msg.message_id = SWITCH_MESSAGE_INDICATE_BRIDGE;
393 switch_core_session_receive_message(session_a, &msg)switch_core_session_perform_receive_message(session_a, &msg
, "src/switch_ivr_bridge.c", (const char *)__func__, 393)
;
394 switch_channel_clear_flag(chan_b, CF_SUSPEND);
395 switch_core_session_kill_channel(session_b, SWITCH_SIG_BREAK)switch_core_session_perform_kill_channel(session_b, "src/switch_ivr_bridge.c"
, (const char *)__func__, 395, SWITCH_SIG_BREAK)
;
396 }
397
398 switch_ivr_parse_all_messages(session_a);
399
400 if (!inner_bridge && (switch_channel_test_flag(chan_a, CF_SUSPEND) || switch_channel_test_flag(chan_b, CF_SUSPEND))) {
401 status = switch_core_session_read_frame(session_a, &read_frame, SWITCH_IO_FLAG_NONE, stream_id);
402
403 if (!SWITCH_READ_ACCEPTABLE(status)(status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK
|| status == SWITCH_STATUS_INUSE)
) {
404 goto end_of_bridge_loop;
405 }
406 continue;
407 }
408#ifdef SWITCH_VIDEO_IN_THREADS
409 if (switch_channel_test_flag(chan_a, CF_VIDEO) && switch_channel_test_flag(chan_b, CF_VIDEO) && !vid_launch) {
410 vid_launch++;
411 vh.session_a = session_a;
412 vh.session_b = session_b;
413 vid_thread = launch_video(&vh);
414 }
415#endif
416
417 if (read_frame_count >= DEFAULT_LEAD_FRAMES10 && switch_channel_media_ack(chan_a)(!switch_channel_test_cap(chan_a, CC_MEDIA_ACK) || switch_channel_test_flag
(chan_a, CF_MEDIA_ACK))
) {
418
419 if (!exec_check) {
420 switch_channel_execute_on(chan_a, SWITCH_CHANNEL_EXECUTE_ON_PRE_BRIDGE_VARIABLE"execute_on_pre_bridge");
421
422 if (!inner_bridge) {
423 switch_channel_api_on(chan_a, SWITCH_API_BRIDGE_START_VARIABLE"api_before_bridge");
424 }
425 exec_check = 1;
426 }
427
428 if (exec_app) {
429 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_bridge.c", (const char
*)__func__, 429, (const char*)(session_a)
, SWITCH_LOG_DEBUG, "%s Bridge execute app %s(%s)\n",
430 switch_channel_get_name(chan_a), exec_app, exec_data);
431
432 switch_core_session_execute_application_async(session_a, exec_app, exec_data);
433 exec_app = exec_data = NULL((void*)0);
434 }
435
436 if ((bypass_media_after_bridge || switch_channel_test_flag(chan_b, CF_BYPASS_MEDIA_AFTER_BRIDGE)) && switch_channel_test_flag(chan_a, CF_ANSWERED)
437 && switch_channel_test_flag(chan_b, CF_ANSWERED)) {
438 switch_ivr_nomedia(switch_core_session_get_uuid(session_a), SMF_REBRIDGE);
439 bypass_media_after_bridge = 0;
440 switch_channel_clear_flag(chan_b, CF_BYPASS_MEDIA_AFTER_BRIDGE);
441 goto end_of_bridge_loop;
442 }
443 }
444
445 /* if 1 channel has DTMF pass it to the other */
446 while (switch_channel_has_dtmf(chan_a)) {
447 switch_dtmf_t dtmf = { 0, 0 };
448 if (switch_channel_dequeue_dtmf(chan_a, &dtmf) == SWITCH_STATUS_SUCCESS) {
449 int send_dtmf = 1;
450
451 if (input_callback) {
452 switch_status_t cb_status = input_callback(session_a, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, user_data, 0);
453
454 if (cb_status == SWITCH_STATUS_IGNORE) {
455 send_dtmf = 0;
456 } else if (cb_status != SWITCH_STATUS_SUCCESS) {
457 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_bridge.c", (const char
*)__func__, 457, (const char*)(session_a)
, SWITCH_LOG_DEBUG, "%s ended call via DTMF\n", switch_channel_get_name(chan_a));
458 switch_core_session_kill_channel(session_b, SWITCH_SIG_BREAK)switch_core_session_perform_kill_channel(session_b, "src/switch_ivr_bridge.c"
, (const char *)__func__, 458, SWITCH_SIG_BREAK)
;
459 goto end_of_bridge_loop;
460 }
461 }
462
463 if (bridge_filter_dtmf) {
464 send_dtmf = 0;
465 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_bridge.c", (const char
*)__func__, 465, (const char*)(session_a)
, SWITCH_LOG_DEBUG, "Dropping filtered DTMF received on %s\n", switch_channel_get_name(chan_a));
466 }
467
468 if (send_dtmf) {
469 switch_core_session_send_dtmf(session_b, &dtmf);
470 switch_core_session_kill_channel(session_b, SWITCH_SIG_BREAK)switch_core_session_perform_kill_channel(session_b, "src/switch_ivr_bridge.c"
, (const char *)__func__, 470, SWITCH_SIG_BREAK)
;
471 }
472 }
473 }
474
475 if (switch_core_session_dequeue_event(session_a, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
476 if (input_callback) {
477 status = input_callback(session_a, event, SWITCH_INPUT_TYPE_EVENT, user_data, 0);
478 }
479
480 if ((event->event_id != SWITCH_EVENT_COMMAND && event->event_id != SWITCH_EVENT_MESSAGE)
481 || switch_core_session_receive_event(session_b, &event) != SWITCH_STATUS_SUCCESS) {
482 switch_event_destroy(&event);
483 }
484
485 }
486
487 if (!switch_channel_test_flag(chan_a, CF_ANSWERED) && answer_limit && switch_epoch_time_now(NULL((void*)0)) > answer_limit) {
488 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_bridge.c", (const char
*)__func__, 488, (const char*)(session_a)
, SWITCH_LOG_DEBUG, "Answer timeout hit on %s.\n", switch_channel_get_name(chan_a));
489 switch_channel_hangup(chan_a, SWITCH_CAUSE_ALLOTTED_TIMEOUT)switch_channel_perform_hangup(chan_a, "src/switch_ivr_bridge.c"
, (const char *)__func__, 489, SWITCH_CAUSE_ALLOTTED_TIMEOUT)
;
490 }
491
492 if (!switch_channel_test_flag(chan_a, CF_ANSWERED)) {
493 if (originator) {
494 if (!ans_b && switch_channel_test_flag(chan_b, CF_ANSWERED)) {
495 switch_channel_pass_callee_id(chan_b, chan_a);
496 if (switch_channel_answer(chan_a)switch_channel_perform_answer(chan_a, "src/switch_ivr_bridge.c"
, (const char *)__func__, 496)
!= SWITCH_STATUS_SUCCESS) {
497 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_bridge.c", (const char
*)__func__, 497, (const char*)(session_a)
, SWITCH_LOG_DEBUG, "%s Media Establishment Failed.\n", switch_channel_get_name(chan_a));
498 goto end_of_bridge_loop;
499 }
500 ans_a = 1;
501 } else if (!pre_b && switch_channel_test_flag(chan_b, CF_EARLY_MEDIA)) {
502 if (switch_channel_pre_answer(chan_a)switch_channel_perform_pre_answer(chan_a, "src/switch_ivr_bridge.c"
, (const char *)__func__, 502)
!= SWITCH_STATUS_SUCCESS) {
503 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_bridge.c", (const char
*)__func__, 503, (const char*)(session_a)
, SWITCH_LOG_DEBUG, "%s Media Establishment Failed.\n", switch_channel_get_name(chan_a));
504 goto end_of_bridge_loop;
505 }
506 pre_b = 1;
507 }
508 if (!pre_b) {
509 switch_yield(10000)switch_sleep(10000);;
510 continue;
511 }
512 } else {
513 ans_a = switch_channel_test_flag(chan_b, CF_ANSWERED);
514 }
515 }
516
517 if (ans_a != ans_b) {
518 switch_channel_t *un = ans_a ? chan_b : chan_a;
519 switch_channel_t *a = un == chan_b ? chan_a : chan_b;
520
521 if (switch_channel_direction(un) == SWITCH_CALL_DIRECTION_INBOUND) {
522 if (switch_channel_direction(a) == SWITCH_CALL_DIRECTION_OUTBOUND || (un == chan_a && !originator)) {
523 switch_channel_pass_callee_id(a, un);
524 }
525
526 if (switch_channel_answer(un)switch_channel_perform_answer(un, "src/switch_ivr_bridge.c", (
const char *)__func__, 526)
!= SWITCH_STATUS_SUCCESS) {
527 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_bridge.c", (const char
*)__func__, 527, (const char*)(session_a)
, SWITCH_LOG_DEBUG, "%s Media Establishment Failed.\n", switch_channel_get_name(un));
528 goto end_of_bridge_loop;
529 }
530
531 if (ans_a) {
532 ans_b = 1;
533 } else {
534 ans_a = 1;
535 }
536 }
537 }
538
539 if (originator && !ans_b) ans_b = switch_channel_test_flag(chan_b, CF_ANSWERED);
540
541 if (originator && !sent_update && ans_a && ans_b && switch_channel_media_ack(chan_a)(!switch_channel_test_cap(chan_a, CC_MEDIA_ACK) || switch_channel_test_flag
(chan_a, CF_MEDIA_ACK))
&& switch_channel_media_ack(chan_b)(!switch_channel_test_cap(chan_b, CC_MEDIA_ACK) || switch_channel_test_flag
(chan_b, CF_MEDIA_ACK))
) {
542 switch_ivr_bridge_display(session_a, session_b);
543 sent_update = 1;
544 }
545#ifndef SWITCH_VIDEO_IN_THREADS
546 if (switch_channel_test_flag(chan_a, CF_VIDEO) && switch_channel_test_flag(chan_b, CF_VIDEO)) {
547 /* read video from 1 channel and write it to the other */
548 status = switch_core_session_read_video_frame(session_a, &read_frame, SWITCH_IO_FLAG_NONE, 0);
549
550 if (!SWITCH_READ_ACCEPTABLE(status)(status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK
|| status == SWITCH_STATUS_INUSE)
) {
551 goto end_of_bridge_loop;
552 }
553
554 switch_core_session_write_video_frame(session_b, read_frame, SWITCH_IO_FLAG_NONE, 0);
555 }
556#endif
557
558 /* read audio from 1 channel and write it to the other */
559 status = switch_core_session_read_frame(session_a, &read_frame, SWITCH_IO_FLAG_NONE, stream_id);
560
561 if (SWITCH_READ_ACCEPTABLE(status)(status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK
|| status == SWITCH_STATUS_INUSE)
) {
562 read_frame_count++;
563 if (switch_test_flag(read_frame, SFF_CNG)((read_frame)->flags & SFF_CNG)) {
564 if (silence_val) {
565 switch_generate_sln_silence((int16_t *) silence_frame.data, silence_frame.samples,
566 read_frame->codec->implementation->number_of_channels, silence_val);
567 read_frame = &silence_frame;
568 } else if (!switch_channel_test_flag(chan_b, CF_ACCEPT_CNG)) {
569 continue;
570 }
571 }
572
573 if (switch_channel_test_flag(chan_a, CF_BRIDGE_NOWRITE)) {
574 continue;
575 }
576
577 if (status != SWITCH_STATUS_BREAK && !switch_channel_test_flag(chan_a, CF_HOLD)) {
578 if (switch_core_session_write_frame(session_b, read_frame, SWITCH_IO_FLAG_NONE, stream_id) != SWITCH_STATUS_SUCCESS) {
579 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_bridge.c", (const char
*)__func__, 579, (const char*)(session_a)
, SWITCH_LOG_DEBUG,
580 "%s ending bridge by request from write function\n", switch_channel_get_name(chan_b));
581 goto end_of_bridge_loop;
582 }
583 }
584 } else {
585 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_bridge.c", (const char
*)__func__, 585, (const char*)(session_a)
, SWITCH_LOG_DEBUG, "%s ending bridge by request from read function\n", switch_channel_get_name(chan_a));
586 goto end_of_bridge_loop;
587 }
588 }
589
590 end_of_bridge_loop:
591
592#ifdef SWITCH_VIDEO_IN_THREADS
593 if (vid_thread) {
594 vh.up = -1;
595 switch_channel_set_flag(chan_a, CF_NOT_READY)switch_channel_set_flag_value(chan_a, CF_NOT_READY, 1);
596 //switch_channel_set_flag(chan_b, CF_NOT_READY);
597 switch_core_session_kill_channel(session_a, SWITCH_SIG_BREAK)switch_core_session_perform_kill_channel(session_a, "src/switch_ivr_bridge.c"
, (const char *)__func__, 597, SWITCH_SIG_BREAK)
;
598 switch_core_session_kill_channel(session_b, SWITCH_SIG_BREAK)switch_core_session_perform_kill_channel(session_b, "src/switch_ivr_bridge.c"
, (const char *)__func__, 598, SWITCH_SIG_BREAK)
;
599 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_bridge.c", (const char
*)__func__, 599, (const char*)(session_a)
, SWITCH_LOG_DEBUG, "Ending video thread.\n");
600 }
601#endif
602
603
604 if (silence_val) {
605 switch_core_codec_destroy(&silence_codec);
606 }
607
608 switch_channel_execute_on(chan_a, SWITCH_CHANNEL_EXECUTE_ON_POST_BRIDGE_VARIABLE"execute_on_post_bridge");
609
610 if (!inner_bridge) {
611 switch_channel_api_on(chan_a, SWITCH_API_BRIDGE_END_VARIABLE"api_after_bridge");
612 }
613
614 if (!inner_bridge && switch_channel_up_nosig(chan_a)(switch_channel_get_state(chan_a) < CS_HANGUP)) {
615 if ((app_name = switch_channel_get_variable(chan_a, SWITCH_EXEC_AFTER_BRIDGE_APP_VARIABLE)switch_channel_get_variable_dup(chan_a, "exec_after_bridge_app"
, SWITCH_TRUE, -1)
)) {
616 switch_caller_extension_t *extension = NULL((void*)0);
617 if ((extension = switch_caller_extension_new(session_a, app_name, app_name)) == 0) {
618 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_bridge.c", (const char
*)__func__, 618, (const char*)(session_a)
, SWITCH_LOG_CRIT, "memory error!\n");
619 goto end;
620 }
621 app_arg = switch_channel_get_variable(chan_a, SWITCH_EXEC_AFTER_BRIDGE_ARG_VARIABLE)switch_channel_get_variable_dup(chan_a, "exec_after_bridge_arg"
, SWITCH_TRUE, -1)
;
622
623 switch_caller_extension_add_application(session_a, extension, (char *) app_name, app_arg);
624 switch_channel_set_caller_extension(chan_a, extension);
625
626 if (switch_channel_get_state(chan_a) == CS_EXECUTE) {
627 switch_channel_set_flag(chan_a, CF_RESET)switch_channel_set_flag_value(chan_a, CF_RESET, 1);
628 } else {
629 switch_channel_set_state(chan_a, CS_EXECUTE)switch_channel_perform_set_state(chan_a, "src/switch_ivr_bridge.c"
, (const char *)__func__, 629, CS_EXECUTE)
;
630 }
631 }
632 }
633
634 end:
635
636#ifdef SWITCH_VIDEO_IN_THREADS
637 if (vid_thread) {
638 switch_status_t st;
639
640 if (vh.up == 1) {
641 vh.up = -1;
642 }
643
644 switch_channel_set_flag(chan_a, CF_VIDEO_BREAK)switch_channel_set_flag_value(chan_a, CF_VIDEO_BREAK, 1);
645 switch_channel_set_flag(chan_b, CF_VIDEO_BREAK)switch_channel_set_flag_value(chan_b, CF_VIDEO_BREAK, 1);
646 switch_core_session_kill_channel(session_a, SWITCH_SIG_BREAK)switch_core_session_perform_kill_channel(session_a, "src/switch_ivr_bridge.c"
, (const char *)__func__, 646, SWITCH_SIG_BREAK)
;
647 switch_core_session_kill_channel(session_b, SWITCH_SIG_BREAK)switch_core_session_perform_kill_channel(session_b, "src/switch_ivr_bridge.c"
, (const char *)__func__, 647, SWITCH_SIG_BREAK)
;
648
649 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_bridge.c", (const char
*)__func__, 649, (const char*)(session_a)
, SWITCH_LOG_DEBUG, "Ending video thread.\n");
650 switch_thread_join(&st, vid_thread);
651 switch_channel_clear_flag(chan_a, CF_NOT_READY);
652 switch_channel_clear_flag(chan_b, CF_NOT_READY);
653 }
654#endif
655
656
657
658 switch_core_session_reset(session_a, SWITCH_TRUE, SWITCH_TRUE);
659 switch_channel_set_variable(chan_a, SWITCH_BRIDGE_VARIABLE, NULL)switch_channel_set_variable_var_check(chan_a, "bridge_to", ((
void*)0), SWITCH_TRUE)
;
660 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_bridge.c", (const char
*)__func__, 660, (const char*)(session_a)
, SWITCH_LOG_DEBUG, "BRIDGE THREAD DONE [%s]\n", switch_channel_get_name(chan_a));
661 switch_channel_clear_flag(chan_a, CF_BRIDGED);
662
663 if (switch_channel_test_flag(chan_a, CF_LEG_HOLDING) || switch_channel_test_flag(chan_a, CF_HANGUP_HELD)) {
664 if (switch_channel_ready(chan_b)switch_channel_test_ready(chan_b, SWITCH_TRUE, SWITCH_FALSE) && switch_channel_get_state(chan_b) != CS_PARK && !data->other_leg_data->clean_exit) {
665 const char *ext = switch_channel_get_variable(chan_a, "hold_hangup_xfer_exten")switch_channel_get_variable_dup(chan_a, "hold_hangup_xfer_exten"
, SWITCH_TRUE, -1)
;
666
667 switch_channel_stop_broadcast(chan_b)for(;;) {if (switch_channel_test_flag(chan_b, CF_BROADCAST)) {
switch_channel_set_flag_value(chan_b, CF_STOP_BROADCAST, 1); switch_channel_set_flag_value
(chan_b, CF_BREAK, 1); } break;}
;
668
669 if (zstr(ext)_zstr(ext)) {
670 switch_call_cause_t cause = switch_channel_get_cause(chan_b);
671 if (cause == SWITCH_CAUSE_NONE) {
672 cause = SWITCH_CAUSE_NORMAL_CLEARING;
673 }
674 switch_channel_hangup(chan_b, cause)switch_channel_perform_hangup(chan_b, "src/switch_ivr_bridge.c"
, (const char *)__func__, 674, cause)
;
675 } else {
676 switch_channel_set_variable(chan_b, SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE, ext)switch_channel_set_variable_var_check(chan_b, "transfer_after_bridge"
, ext, SWITCH_TRUE)
;
677 }
678 }
679
680 if (switch_channel_test_flag(chan_a, CF_LEG_HOLDING)) {
681 switch_channel_mark_hold(chan_a, SWITCH_FALSE);
682 }
683 }
684
685 if (switch_channel_test_flag(chan_a, CF_INTERCEPTED)) {
686 switch_channel_set_flag(chan_b, CF_INTERCEPT)switch_channel_set_flag_value(chan_b, CF_INTERCEPT, 1);
687 }
688
689
690 switch_core_session_kill_channel(session_b, SWITCH_SIG_BREAK)switch_core_session_perform_kill_channel(session_b, "src/switch_ivr_bridge.c"
, (const char *)__func__, 690, SWITCH_SIG_BREAK)
;
691 data->done = 1;
692 switch_core_session_rwunlock(session_b);
693 return NULL((void*)0);
694}
695
696static void transfer_after_bridge(switch_core_session_t *session, const char *where)
697{
698 int argc;
699 char *argv[4] = { 0 };
700 char *mydata;
701
702 switch_channel_set_variable(switch_core_session_get_channel(session), SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE, NULL)switch_channel_set_variable_var_check(switch_core_session_get_channel
(session), "transfer_after_bridge", ((void*)0), SWITCH_TRUE)
;
703
704 if (!zstr(where)_zstr(where) && (mydata = switch_core_session_strdup(session, where)switch_core_perform_session_strdup(session, where, "src/switch_ivr_bridge.c"
, (const char *)__func__, 704)
)) {
705 if ((argc = switch_separate_string(mydata, ':', argv, (sizeof(argv) / sizeof(argv[0])))) >= 1) {
706 switch_ivr_session_transfer(session, argv[0], argv[1], argv[2]);
707 } else {
708 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_bridge.c", (const char
*)__func__, 708, (const char*)(session)
, SWITCH_LOG_ERROR, "No extension specified.\n");
709 }
710 }
711}
712
713static switch_status_t audio_bridge_on_exchange_media(switch_core_session_t *session)
714{
715 switch_channel_t *channel = switch_core_session_get_channel(session);
716 switch_ivr_bridge_data_t *bd = switch_channel_get_private(channel, "_bridge_");
717 switch_channel_state_t state;
718 const char *var;
719
720 if (bd) {
721 switch_channel_set_private(channel, "_bridge_", NULL((void*)0));
722 if (bd->session == session && *bd->b_uuid) {
723 audio_bridge_thread(NULL((void*)0), (void *) bd);
724 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
725 } else {
726 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 726, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER
)
;
727 }
728 } else {
729 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 729, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER
)
;
730 }
731 switch_channel_clear_state_handler(channel, &audio_bridge_peer_state_handlers);
732
733 state = switch_channel_get_state(channel);
734
735 if (state < CS_HANGUP && switch_true(switch_channel_get_variable(channel, SWITCH_PARK_AFTER_BRIDGE_VARIABLE)switch_channel_get_variable_dup(channel, "park_after_bridge",
SWITCH_TRUE, -1)
)) {
736 switch_ivr_park_session(session);
737 } else if (state < CS_HANGUP && (var = switch_channel_get_variable(channel, SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE)switch_channel_get_variable_dup(channel, "transfer_after_bridge"
, SWITCH_TRUE, -1)
)) {
738 transfer_after_bridge(session, var);
739 } else {
740 if (!switch_channel_test_flag(channel, CF_TRANSFER) && !switch_channel_test_flag(channel, CF_REDIRECT) &&
741 !switch_channel_test_flag(channel, CF_XFER_ZOMBIE) && bd && !bd->clean_exit
742 && state != CS_PARK && state != CS_ROUTING && state == CS_EXCHANGE_MEDIA && !switch_channel_test_flag(channel, CF_INNER_BRIDGE)) {
743 if (switch_channel_test_flag(channel, CF_INTERCEPTED)) {
744 switch_channel_clear_flag(channel, CF_INTERCEPT);
745 switch_channel_clear_flag(channel, CF_INTERCEPTED);
746 return SWITCH_STATUS_FALSE;
747 } else {
748 if (switch_channel_test_flag(channel, CF_INTERCEPT)) {
749 switch_channel_hangup(channel, SWITCH_CAUSE_PICKED_OFF)switch_channel_perform_hangup(channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 749, SWITCH_CAUSE_PICKED_OFF)
;
750 } else {
751 if (!switch_channel_test_flag(channel, CF_ANSWERED)) {
752 switch_channel_hangup(channel, SWITCH_CAUSE_ORIGINATOR_CANCEL)switch_channel_perform_hangup(channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 752, SWITCH_CAUSE_ORIGINATOR_CANCEL
)
;
753 } else {
754 switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING)switch_channel_perform_hangup(channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 754, SWITCH_CAUSE_NORMAL_CLEARING)
;
755 }
756 }
757 }
758 }
759 }
760
761 if (switch_channel_get_state(channel) == CS_EXCHANGE_MEDIA) {
762 switch_channel_set_variable(channel, "park_timeout", "3")switch_channel_set_variable_var_check(channel, "park_timeout"
, "3", SWITCH_TRUE)
;
763 switch_channel_set_state(channel, CS_PARK)switch_channel_perform_set_state(channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 763, CS_PARK)
;
764 }
765
766 return SWITCH_STATUS_FALSE;
767}
768
769static switch_status_t audio_bridge_on_routing(switch_core_session_t *session)
770{
771 switch_channel_t *channel = switch_core_session_get_channel(session);
772
773 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_bridge.c", (const char
*)__func__, 773, (const char*)(session)
, SWITCH_LOG_DEBUG, "%s CUSTOM ROUTING\n", switch_channel_get_name(channel));
774
775 /* put the channel in a passive state so we can loop audio to it */
776 switch_channel_set_state(channel, CS_CONSUME_MEDIA)switch_channel_perform_set_state(channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 776, CS_CONSUME_MEDIA)
;
777 return SWITCH_STATUS_FALSE;
778}
779
780static switch_status_t audio_bridge_on_consume_media(switch_core_session_t *session)
781{
782 switch_channel_t *channel = switch_core_session_get_channel(session);
783
784 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_bridge.c", (const char
*)__func__, 784, (const char*)(session)
, SWITCH_LOG_DEBUG, "%s CUSTOM HOLD\n", switch_channel_get_name(channel));
785
786 /* put the channel in a passive state so we can loop audio to it */
787 return SWITCH_STATUS_FALSE;
788}
789
790static const switch_state_handler_table_t audio_bridge_peer_state_handlers = {
791 /*.on_init */ NULL((void*)0),
792 /*.on_routing */ audio_bridge_on_routing,
793 /*.on_execute */ NULL((void*)0),
794 /*.on_hangup */ NULL((void*)0),
795 /*.on_exchange_media */ audio_bridge_on_exchange_media,
796 /*.on_soft_execute */ NULL((void*)0),
797 /*.on_consume_media */ audio_bridge_on_consume_media,
798};
799
800static switch_status_t uuid_bridge_on_reset(switch_core_session_t *session);
801static switch_status_t uuid_bridge_on_hibernate(switch_core_session_t *session);
802static switch_status_t uuid_bridge_on_soft_execute(switch_core_session_t *session);
803
804static const switch_state_handler_table_t uuid_bridge_state_handlers = {
805 /*.on_init */ NULL((void*)0),
806 /*.on_routing */ NULL((void*)0),
807 /*.on_execute */ NULL((void*)0),
808 /*.on_hangup */ NULL((void*)0),
809 /*.on_exchange_media */ NULL((void*)0),
810 /*.on_soft_execute */ uuid_bridge_on_soft_execute,
811 /*.on_consume_media */ uuid_bridge_on_hibernate,
812 /*.on_hibernate */ uuid_bridge_on_hibernate,
813 /*.on_reset */ uuid_bridge_on_reset
814};
815
816static switch_status_t uuid_bridge_on_reset(switch_core_session_t *session)
817{
818 switch_channel_t *channel = switch_core_session_get_channel(session);
819
820 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_bridge.c", (const char
*)__func__, 820, (const char*)(session)
, SWITCH_LOG_DEBUG, "%s CUSTOM RESET\n", switch_channel_get_name(channel));
821
822 switch_channel_clear_flag(channel, CF_ORIGINATING);
823
824 cleanup_proxy_mode_b(session);
825
826 if (switch_channel_test_flag(channel, CF_UUID_BRIDGE_ORIGINATOR)) {
827 switch_channel_set_state(channel, CS_SOFT_EXECUTE)switch_channel_perform_set_state(channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 827, CS_SOFT_EXECUTE)
;
828 }
829
830 return SWITCH_STATUS_SUCCESS;
831}
832
833static switch_status_t uuid_bridge_on_hibernate(switch_core_session_t *session)
834{
835 switch_channel_set_state(switch_core_session_get_channel(session), CS_RESET)switch_channel_perform_set_state(switch_core_session_get_channel
(session), "src/switch_ivr_bridge.c", (const char *)__func__,
835, CS_RESET)
;
836 return SWITCH_STATUS_FALSE;
837}
838
839static switch_status_t uuid_bridge_on_soft_execute(switch_core_session_t *session)
840{
841 switch_channel_t *channel = switch_core_session_get_channel(session);
842 switch_core_session_t *other_session = NULL((void*)0);
843 const char *other_uuid = NULL((void*)0);
844
845 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_bridge.c", (const char
*)__func__, 845, (const char*)(session)
, SWITCH_LOG_DEBUG, "%s CUSTOM SOFT_EXECUTE\n", switch_channel_get_name(channel));
846 switch_channel_clear_state_handler(channel, &uuid_bridge_state_handlers);
847
848 if (!switch_channel_test_flag(channel, CF_UUID_BRIDGE_ORIGINATOR)) {
849 return SWITCH_STATUS_SUCCESS;
850 }
851
852 if ((other_uuid = switch_channel_get_variable(channel, SWITCH_UUID_BRIDGE)switch_channel_get_variable_dup(channel, "uuid_bridge", SWITCH_TRUE
, -1)
) && (other_session = switch_core_session_locate(other_uuid)switch_core_session_perform_locate(other_uuid, "src/switch_ivr_bridge.c"
, (const char *)__func__, 852)
)) {
853 switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
854 switch_event_t *event;
855 int ready_a, ready_b;
856 switch_channel_state_t state, running_state;
857 int max = 1000, loops = max;
858
859 switch_channel_set_variable(channel, SWITCH_UUID_BRIDGE, NULL)switch_channel_set_variable_var_check(channel, "uuid_bridge",
((void*)0), SWITCH_TRUE)
;
860
861 for (;;) {
862 state = switch_channel_get_state(other_channel);
863 running_state = switch_channel_get_running_state(other_channel);
864
865 if (switch_channel_down_nosig(other_channel)(switch_channel_get_state(other_channel) >= CS_HANGUP) || switch_channel_down(channel)(switch_channel_check_signal(channel, SWITCH_TRUE) || switch_channel_get_state
(channel) >= CS_HANGUP)
) {
866 break;
867 }
868
869 if (state < CS_HANGUP && state == running_state) {
870
871 if (--loops < 1) {
872 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 872, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER
)
;
873 switch_channel_hangup(other_channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(other_channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 873, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER
)
;
874 }
875
876 if (running_state == CS_RESET) {
877 switch_channel_set_state(other_channel, CS_SOFT_EXECUTE)switch_channel_perform_set_state(other_channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 877, CS_SOFT_EXECUTE)
;
878 }
879
880 if (running_state == CS_SOFT_EXECUTE) {
881
882 if (switch_channel_test_flag(other_channel, CF_UUID_BRIDGE_ORIGINATOR)) {
883 goto done;
884 } else {
885 break;
886 }
887 }
888
889 } else {
890 loops = max;
891 }
892
893 switch_yield(20000)switch_sleep(20000);;
894 }
895
896 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
897
898 if (switch_ivr_wait_for_answer(session, other_session) != SWITCH_STATUS_SUCCESS) {
899 if (switch_true(switch_channel_get_variable(channel, "uuid_bridge_continue_on_cancel")switch_channel_get_variable_dup(channel, "uuid_bridge_continue_on_cancel"
, SWITCH_TRUE, -1)
)) {
900 switch_channel_set_state(channel, CS_EXECUTE)switch_channel_perform_set_state(channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 900, CS_EXECUTE)
;
901 } else if (switch_true(switch_channel_get_variable(channel, "uuid_bridge_park_on_cancel")switch_channel_get_variable_dup(channel, "uuid_bridge_park_on_cancel"
, SWITCH_TRUE, -1)
)) {
902 switch_ivr_park_session(session);
903 } else if (!switch_channel_test_flag(channel, CF_TRANSFER)) {
904 switch_channel_hangup(channel, SWITCH_CAUSE_ORIGINATOR_CANCEL)switch_channel_perform_hangup(channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 904, SWITCH_CAUSE_ORIGINATOR_CANCEL
)
;
905 }
906 goto done;
907 }
908
909 ready_a = switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE);
910 ready_b = switch_channel_ready(other_channel)switch_channel_test_ready(other_channel, SWITCH_TRUE, SWITCH_FALSE
)
;
911
912 if (!ready_a || !ready_b) {
913 if (!ready_a) {
914 switch_channel_hangup(other_channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(other_channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 914, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER
)
;
915 }
916
917 if (!ready_b) {
918 const char *cid = switch_channel_get_variable(other_channel, "rdnis")switch_channel_get_variable_dup(other_channel, "rdnis", SWITCH_TRUE
, -1)
;
919 if (ready_a && cid) {
920 switch_ivr_session_transfer(session, cid, NULL((void*)0), NULL((void*)0));
921 } else {
922 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 922, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER
)
;
923 }
924 }
925 goto done;
926 }
927
928 /* fire events that will change the data table from "show channels" */
929 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_EXECUTE)switch_event_create_subclass_detailed("src/switch_ivr_bridge.c"
, (const char * )(const char *)__func__, 929, &event, SWITCH_EVENT_CHANNEL_EXECUTE
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
930 switch_channel_event_set_data(channel, event);
931 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application", "uuid_bridge");
932 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-Data", switch_core_session_get_uuid(other_session));
933 switch_event_fire(&event)switch_event_fire_detailed("src/switch_ivr_bridge.c", (const char
* )(const char *)__func__, 933, &event, ((void*)0))
;
934 }
935
936 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_EXECUTE)switch_event_create_subclass_detailed("src/switch_ivr_bridge.c"
, (const char * )(const char *)__func__, 936, &event, SWITCH_EVENT_CHANNEL_EXECUTE
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
937 switch_channel_event_set_data(other_channel, event);
938 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application", "uuid_bridge");
939 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-Data", switch_core_session_get_uuid(session));
940 switch_event_fire(&event)switch_event_fire_detailed("src/switch_ivr_bridge.c", (const char
* )(const char *)__func__, 940, &event, ((void*)0))
;
941 }
942
943 switch_ivr_multi_threaded_bridge(session, other_session, NULL((void*)0), NULL((void*)0), NULL((void*)0));
944
945 state = switch_channel_get_state(channel);
946 if (!switch_channel_test_flag(channel, CF_TRANSFER) &&
947 !switch_channel_test_flag(channel, CF_REDIRECT) && state < CS_HANGUP && state != CS_ROUTING && state != CS_PARK) {
948 switch_channel_set_state(channel, CS_EXECUTE)switch_channel_perform_set_state(channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 948, CS_EXECUTE)
;
949 }
950 } else {
951 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 951, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER
)
;
952 }
953
954 done:
955
956 if (other_session) {
957 switch_core_session_rwunlock(other_session);
958 other_session = NULL((void*)0);
959 }
960
961 switch_channel_clear_flag(channel, CF_UUID_BRIDGE_ORIGINATOR);
962
963 return SWITCH_STATUS_FALSE;
964}
965
966static switch_status_t sb_on_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf, switch_dtmf_direction_t direction)
967{
968 switch_channel_t *channel = NULL((void*)0);
969 char *key;
970
971 channel = switch_core_session_get_channel(session);
972 switch_assert(channel != NULL)((channel != ((void*)0)) ? (void) (0) : __assert_fail ("channel != ((void*)0)"
, "src/switch_ivr_bridge.c", 972, __PRETTY_FUNCTION__))
;
973
974 if ((key = (char *) switch_channel_get_private(channel, "__bridge_term_key")) && dtmf->digit == *key) {
975 const char *uuid;
976 switch_core_session_t *other_session;
977
978 if (switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) {
979 switch_channel_set_state(channel, CS_EXECUTE)switch_channel_perform_set_state(channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 979, CS_EXECUTE)
;
980 } else {
981 if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE)switch_channel_get_variable_dup(channel, "signal_bridge_to", SWITCH_TRUE
, -1)
) && (other_session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "src/switch_ivr_bridge.c"
, (const char *)__func__, 981)
)) {
982 switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
983 switch_channel_set_state(other_channel, CS_EXECUTE)switch_channel_perform_set_state(other_channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 983, CS_EXECUTE)
;
984 switch_core_session_rwunlock(other_session);
985 } else {
986 return SWITCH_STATUS_SUCCESS;
987 }
988 }
989
990 return SWITCH_STATUS_FALSE;
991 }
992
993 return SWITCH_STATUS_SUCCESS;
994}
995
996static switch_status_t hanguphook(switch_core_session_t *session)
997{
998 switch_core_session_message_t *msg = NULL((void*)0);
999 switch_channel_t *channel = NULL((void*)0);
1000 switch_event_t *event;
1001
1002 channel = switch_core_session_get_channel(session);
1003
1004 if (switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) {
1005 switch_channel_clear_flag_recursive(channel, CF_BRIDGE_ORIGINATOR);
1006 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_UNBRIDGE)switch_event_create_subclass_detailed("src/switch_ivr_bridge.c"
, (const char * )(const char *)__func__, 1006, &event, SWITCH_EVENT_CHANNEL_UNBRIDGE
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1007 switch_channel_event_set_data(channel, event);
1008 switch_event_fire(&event)switch_event_fire_detailed("src/switch_ivr_bridge.c", (const char
* )(const char *)__func__, 1008, &event, ((void*)0))
;
1009 }
1010 }
1011
1012
1013 msg = switch_core_session_alloc(session, sizeof(*msg))switch_core_perform_session_alloc(session, sizeof(*msg), "src/switch_ivr_bridge.c"
, (const char *)__func__, 1013)
;
1014 MESSAGE_STAMP_FFL(msg)msg->_file = "src/switch_ivr_bridge.c"; msg->_func = (const
char *)__func__; msg->_line = 1014
;
1015 msg->message_id = SWITCH_MESSAGE_INDICATE_UNBRIDGE;
1016 msg->from = __FILE__"src/switch_ivr_bridge.c";
1017 msg->string_arg = switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE)switch_channel_get_variable_dup(channel, "signal_bridge_to", SWITCH_TRUE
, -1)
;
1018 switch_core_session_queue_message(session, msg);
1019
1020 switch_core_event_hook_remove_state_change(session, hanguphook);
1021
1022 return SWITCH_STATUS_SUCCESS;
1023
1024}
1025
1026static switch_status_t signal_bridge_on_hibernate(switch_core_session_t *session)
1027{
1028 switch_channel_t *channel = NULL((void*)0);
1029 const char *key;
1030 switch_core_session_message_t msg = { 0 };
1031 switch_event_t *event = NULL((void*)0);
1032 switch_ivr_dmachine_t *dmachine[2] = { 0 };
1033
1034 channel = switch_core_session_get_channel(session);
1035 switch_assert(channel != NULL)((channel != ((void*)0)) ? (void) (0) : __assert_fail ("channel != ((void*)0)"
, "src/switch_ivr_bridge.c", 1035, __PRETTY_FUNCTION__))
;
1036
1037 msg.message_id = SWITCH_MESSAGE_INDICATE_BRIDGE;
1038 msg.from = __FILE__"src/switch_ivr_bridge.c";
1039 msg.string_arg = switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE)switch_channel_get_variable_dup(channel, "signal_bridge_to", SWITCH_TRUE
, -1)
;
1040
1041 switch_core_event_hook_add_state_change(session, hanguphook);
1042
1043 switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg
, "src/switch_ivr_bridge.c", (const char *)__func__, 1043)
;
1044
1045 if ((key = switch_channel_get_variable(channel, "bridge_terminate_key")switch_channel_get_variable_dup(channel, "bridge_terminate_key"
, SWITCH_TRUE, -1)
)) {
1046 switch_channel_set_private(channel, "__bridge_term_key", switch_core_session_strdup(session, key)switch_core_perform_session_strdup(session, key, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1046)
);
1047 switch_core_event_hook_add_recv_dtmf(session, sb_on_dtmf);
1048 }
1049
1050 switch_channel_set_variable(channel, SWITCH_BRIDGE_VARIABLE, switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE))switch_channel_set_variable_var_check(channel, "bridge_to", switch_channel_get_variable_dup
(channel, "signal_bridge_to", SWITCH_TRUE, -1), SWITCH_TRUE)
;
1051 switch_channel_set_variable(channel, SWITCH_LAST_BRIDGE_VARIABLE, switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE))switch_channel_set_variable_var_check(channel, "last_bridge_to"
, switch_channel_get_variable_dup(channel, "signal_bridge_to"
, SWITCH_TRUE, -1), SWITCH_TRUE)
;
1052
1053 switch_channel_set_bridge_time(channel);
1054
1055
1056 if (switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) {
1057 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_BRIDGE)switch_event_create_subclass_detailed("src/switch_ivr_bridge.c"
, (const char * )(const char *)__func__, 1057, &event, SWITCH_EVENT_CHANNEL_BRIDGE
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1058 switch_core_session_t *other_session;
1059
1060 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-A-Unique-ID", switch_core_session_get_uuid(session));
1061 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", msg.string_arg);
1062 switch_channel_event_set_data(channel, event);
1063 if ((other_session = switch_core_session_locate(msg.string_arg)switch_core_session_perform_locate(msg.string_arg, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1063)
)) {
1064 switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
1065
1066 switch_channel_set_bridge_time(other_channel);
1067
1068 switch_event_add_presence_data_cols(other_channel, event, "Bridge-B-PD-");
1069 switch_core_session_rwunlock(other_session);
1070 }
1071 switch_event_fire(&event)switch_event_fire_detailed("src/switch_ivr_bridge.c", (const char
* )(const char *)__func__, 1071, &event, ((void*)0))
;
1072 }
1073 }
1074
1075 if ((dmachine[0] = switch_core_session_get_dmachine(session, DIGIT_TARGET_SELF)) ||
1076 (dmachine[1] = switch_core_session_get_dmachine(session, DIGIT_TARGET_PEER))) {
1077 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_bridge.c", (const char
*)__func__, 1077, (const char*)(session)
, SWITCH_LOG_DEBUG,
1078 "%s not hibernating due to active digit parser, semi-hibernation engaged.\n", switch_channel_get_name(channel));
1079
1080 while(switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE) && switch_channel_get_state(channel) == CS_HIBERNATE) {
1081 if (!switch_channel_test_flag(channel, CF_BROADCAST)) {
1082 if (dmachine[0]) {
1083 switch_ivr_dmachine_ping(dmachine[0], NULL((void*)0));
1084 }
1085 if (dmachine[1]) {
1086 switch_ivr_dmachine_ping(dmachine[1], NULL((void*)0));
1087 }
1088 }
1089 switch_yield(20000)switch_sleep(20000);;
1090 switch_ivr_parse_all_messages(session);
1091 }
1092 }
1093
1094
1095 return SWITCH_STATUS_SUCCESS;
1096}
1097
1098static switch_status_t signal_bridge_on_hangup(switch_core_session_t *session)
1099{
1100 const char *uuid;
1101 switch_channel_t *channel = switch_core_session_get_channel(session);
1102 switch_core_session_t *other_session;
1103 switch_event_t *event;
1104
1105 if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE)switch_channel_get_variable_dup(channel, "signal_bridge_to", SWITCH_TRUE
, -1)
)) {
1106 switch_channel_set_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE, NULL)switch_channel_set_variable_var_check(channel, "signal_bridge_to"
, ((void*)0), SWITCH_TRUE)
;
1107 }
1108
1109 if (switch_channel_get_private(channel, "__bridge_term_key")) {
1110 switch_core_event_hook_remove_recv_dtmf(session, sb_on_dtmf);
1111 switch_channel_set_private(channel, "__bridge_term_key", NULL((void*)0));
1112 }
1113
1114 switch_channel_set_variable(channel, SWITCH_BRIDGE_VARIABLE, NULL)switch_channel_set_variable_var_check(channel, "bridge_to", (
(void*)0), SWITCH_TRUE)
;
1115
1116 if (uuid && (other_session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1116)
)) {
1117 switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
1118 const char *sbv = switch_channel_get_variable(other_channel, SWITCH_SIGNAL_BRIDGE_VARIABLE)switch_channel_get_variable_dup(other_channel, "signal_bridge_to"
, SWITCH_TRUE, -1)
;
1119 const char *var;
1120
1121 if (!zstr(sbv)_zstr(sbv) && !strcmp(sbv, switch_core_session_get_uuid(session))__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(sbv) && __builtin_constant_p (switch_core_session_get_uuid
(session)) && (__s1_len = __builtin_strlen (sbv), __s2_len
= __builtin_strlen (switch_core_session_get_uuid(session)), (
!((size_t)(const void *)((sbv) + 1) - (size_t)(const void *)(
sbv) == 1) || __s1_len >= 4) && (!((size_t)(const void
*)((switch_core_session_get_uuid(session)) + 1) - (size_t)(const
void *)(switch_core_session_get_uuid(session)) == 1) || __s2_len
>= 4)) ? __builtin_strcmp (sbv, switch_core_session_get_uuid
(session)) : (__builtin_constant_p (sbv) && ((size_t)
(const void *)((sbv) + 1) - (size_t)(const void *)(sbv) == 1)
&& (__s1_len = __builtin_strlen (sbv), __s1_len <
4) ? (__builtin_constant_p (switch_core_session_get_uuid(session
)) && ((size_t)(const void *)((switch_core_session_get_uuid
(session)) + 1) - (size_t)(const void *)(switch_core_session_get_uuid
(session)) == 1) ? __builtin_strcmp (sbv, switch_core_session_get_uuid
(session)) : (__extension__ ({ const unsigned char *__s2 = (const
unsigned char *) (const char *) (switch_core_session_get_uuid
(session)); int __result = (((const unsigned char *) (const char
*) (sbv))[0] - __s2[0]); if (__s1_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
sbv))[1] - __s2[1]); if (__s1_len > 1 && __result ==
0) { __result = (((const unsigned char *) (const char *) (sbv
))[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (sbv))[
3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (switch_core_session_get_uuid
(session)) && ((size_t)(const void *)((switch_core_session_get_uuid
(session)) + 1) - (size_t)(const void *)(switch_core_session_get_uuid
(session)) == 1) && (__s2_len = __builtin_strlen (switch_core_session_get_uuid
(session)), __s2_len < 4) ? (__builtin_constant_p (sbv) &&
((size_t)(const void *)((sbv) + 1) - (size_t)(const void *)(
sbv) == 1) ? __builtin_strcmp (sbv, switch_core_session_get_uuid
(session)) : (- (__extension__ ({ const unsigned char *__s2 =
(const unsigned char *) (const char *) (sbv); int __result =
(((const unsigned char *) (const char *) (switch_core_session_get_uuid
(session)))[0] - __s2[0]); if (__s2_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
switch_core_session_get_uuid(session)))[1] - __s2[1]); if (__s2_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (switch_core_session_get_uuid(session
)))[2] - __s2[2]); if (__s2_len > 2 && __result ==
0) __result = (((const unsigned char *) (const char *) (switch_core_session_get_uuid
(session)))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(sbv, switch_core_session_get_uuid(session))))); })
) {
1122 int hup = 1;
1123
1124 switch_channel_set_variable(other_channel, SWITCH_SIGNAL_BRIDGE_VARIABLE, NULL)switch_channel_set_variable_var_check(other_channel, "signal_bridge_to"
, ((void*)0), SWITCH_TRUE)
;
1125 switch_channel_set_variable(other_channel, SWITCH_BRIDGE_VARIABLE, NULL)switch_channel_set_variable_var_check(other_channel, "bridge_to"
, ((void*)0), SWITCH_TRUE)
;
1126 switch_channel_set_variable(other_channel, "call_uuid", switch_core_session_get_uuid(other_session))switch_channel_set_variable_var_check(other_channel, "call_uuid"
, switch_core_session_get_uuid(other_session), SWITCH_TRUE)
;
1127
1128 if (switch_channel_up_nosig(other_channel)(switch_channel_get_state(other_channel) < CS_HANGUP)) {
1129 if (switch_true(switch_channel_get_variable(other_channel, SWITCH_PARK_AFTER_BRIDGE_VARIABLE)switch_channel_get_variable_dup(other_channel, "park_after_bridge"
, SWITCH_TRUE, -1)
)) {
1130 switch_ivr_park_session(other_session);
1131 hup = 0;
1132 } else if ((var = switch_channel_get_variable(other_channel, SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE)switch_channel_get_variable_dup(other_channel, "transfer_after_bridge"
, SWITCH_TRUE, -1)
)) {
1133 transfer_after_bridge(other_session, var);
1134 hup = 0;
1135 }
1136
1137 if (hup) {
1138 if (switch_channel_test_flag(other_channel, CF_BRIDGE_ORIGINATOR)) {
1139 if (switch_channel_test_flag(channel, CF_ANSWERED) &&
1140 switch_true(switch_channel_get_variable(other_channel, SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE)switch_channel_get_variable_dup(other_channel, "hangup_after_bridge"
, SWITCH_TRUE, -1)
)) {
1141
1142 if (switch_channel_test_flag(channel, CF_INTERCEPTED)) {
1143 switch_channel_set_flag(other_channel, CF_INTERCEPT)switch_channel_set_flag_value(other_channel, CF_INTERCEPT, 1);
1144 }
1145 switch_channel_hangup(other_channel, switch_channel_get_cause(channel))switch_channel_perform_hangup(other_channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1145, switch_channel_get_cause(channel
))
;
1146 } else {
1147 if (!switch_channel_test_flag(channel, CF_ANSWERED)) {
1148 switch_channel_handle_cause(other_channel, switch_channel_get_cause(channel));
1149 }
1150 switch_channel_set_state(other_channel, CS_EXECUTE)switch_channel_perform_set_state(other_channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1150, CS_EXECUTE)
;
1151 }
1152 } else {
1153 switch_channel_hangup(other_channel, switch_channel_get_cause(channel))switch_channel_perform_hangup(other_channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1153, switch_channel_get_cause(channel
))
;
1154 }
1155 }
1156 }
1157 }
1158
1159 if (switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) {
1160 switch_channel_clear_flag_recursive(channel, CF_BRIDGE_ORIGINATOR);
1161 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_UNBRIDGE)switch_event_create_subclass_detailed("src/switch_ivr_bridge.c"
, (const char * )(const char *)__func__, 1161, &event, SWITCH_EVENT_CHANNEL_UNBRIDGE
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1162 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-A-Unique-ID", switch_core_session_get_uuid(session));
1163 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", uuid);
1164 switch_event_add_presence_data_cols(other_channel, event, "Bridge-B-PD-");
1165 switch_channel_event_set_data(channel, event);
1166 switch_event_fire(&event)switch_event_fire_detailed("src/switch_ivr_bridge.c", (const char
* )(const char *)__func__, 1166, &event, ((void*)0))
;
1167 }
1168 }
1169
1170 switch_core_session_rwunlock(other_session);
1171 } else {
1172 if (switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) {
1173 switch_channel_clear_flag_recursive(channel, CF_BRIDGE_ORIGINATOR);
1174 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_UNBRIDGE)switch_event_create_subclass_detailed("src/switch_ivr_bridge.c"
, (const char * )(const char *)__func__, 1174, &event, SWITCH_EVENT_CHANNEL_UNBRIDGE
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1175 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-A-Unique-ID", switch_core_session_get_uuid(session));
1176 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", uuid);
1177 switch_channel_event_set_data(channel, event);
1178 switch_event_fire(&event)switch_event_fire_detailed("src/switch_ivr_bridge.c", (const char
* )(const char *)__func__, 1178, &event, ((void*)0))
;
1179 }
1180 }
1181 }
1182
1183 return SWITCH_STATUS_SUCCESS;
1184}
1185
1186static const switch_state_handler_table_t signal_bridge_state_handlers = {
1187 /*.on_init */ NULL((void*)0),
1188 /*.on_routing */ NULL((void*)0),
1189 /*.on_execute */ NULL((void*)0),
1190 /*.on_hangup */ signal_bridge_on_hangup,
1191 /*.on_exchange_media */ NULL((void*)0),
1192 /*.on_soft_execute */ NULL((void*)0),
1193 /*.on_consume_media */ NULL((void*)0),
1194 /*.on_hibernate */ signal_bridge_on_hibernate
1195};
1196
1197static void check_bridge_export(switch_channel_t *channel, switch_channel_t *peer_channel)
1198{
1199 switch_caller_profile_t *originator_cp, *originatee_cp;
1200
1201 originator_cp = switch_channel_get_caller_profile(channel);
1202 originatee_cp = switch_channel_get_caller_profile(peer_channel);
1203
1204 originator_cp->callee_id_name = switch_core_strdup(originator_cp->pool, originatee_cp->callee_id_name)switch_core_perform_strdup(originator_cp->pool, originatee_cp
->callee_id_name, "src/switch_ivr_bridge.c", (const char *
)__func__, 1204)
;
1205 originator_cp->callee_id_number = switch_core_strdup(originator_cp->pool, originatee_cp->callee_id_number)switch_core_perform_strdup(originator_cp->pool, originatee_cp
->callee_id_number, "src/switch_ivr_bridge.c", (const char
*)__func__, 1205)
;
1206
1207
1208 switch_channel_process_export(peer_channel, channel, NULL((void*)0), SWITCH_BRIDGE_EXPORT_VARS_VARIABLE"bridge_export_vars");
1209 switch_channel_process_export(channel, peer_channel, NULL((void*)0), SWITCH_BRIDGE_EXPORT_VARS_VARIABLE"bridge_export_vars");
1210}
1211
1212SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_signal_bridge(switch_core_session_t *session, switch_core_session_t *peer_session)
1213{
1214 switch_channel_t *caller_channel = switch_core_session_get_channel(session);
1215 switch_channel_t *peer_channel = switch_core_session_get_channel(peer_session);
1216 switch_event_t *event;
1217
1218 if (switch_channel_down_nosig(peer_channel)(switch_channel_get_state(peer_channel) >= CS_HANGUP)) {
1219 switch_channel_hangup(caller_channel, switch_channel_get_cause(peer_channel))switch_channel_perform_hangup(caller_channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1219, switch_channel_get_cause(peer_channel
))
;
1220 return SWITCH_STATUS_FALSE;
1221 }
1222
1223 if (!switch_channel_up_nosig(caller_channel)(switch_channel_get_state(caller_channel) < CS_HANGUP)) {
1224 switch_channel_hangup(peer_channel, SWITCH_CAUSE_ORIGINATOR_CANCEL)switch_channel_perform_hangup(peer_channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1224, SWITCH_CAUSE_ORIGINATOR_CANCEL
)
;
1225 return SWITCH_STATUS_FALSE;
1226 }
1227
1228 check_bridge_export(caller_channel, peer_channel);
1229
1230 switch_channel_set_flag_recursive(caller_channel, CF_SIGNAL_BRIDGE_TTL);
1231 switch_channel_set_flag_recursive(peer_channel, CF_SIGNAL_BRIDGE_TTL);
1232
1233 switch_channel_set_variable(caller_channel, SWITCH_SIGNAL_BRIDGE_VARIABLE, switch_core_session_get_uuid(peer_session))switch_channel_set_variable_var_check(caller_channel, "signal_bridge_to"
, switch_core_session_get_uuid(peer_session), SWITCH_TRUE)
;
1234 switch_channel_set_variable(peer_channel, SWITCH_SIGNAL_BRIDGE_VARIABLE, switch_core_session_get_uuid(session))switch_channel_set_variable_var_check(peer_channel, "signal_bridge_to"
, switch_core_session_get_uuid(session), SWITCH_TRUE)
;
1235 switch_channel_set_variable(peer_channel, "call_uuid", switch_core_session_get_uuid(session))switch_channel_set_variable_var_check(peer_channel, "call_uuid"
, switch_core_session_get_uuid(session), SWITCH_TRUE)
;
1236
1237 switch_channel_set_flag_recursive(caller_channel, CF_BRIDGE_ORIGINATOR);
1238 switch_channel_clear_flag(peer_channel, CF_BRIDGE_ORIGINATOR);
1239
1240 switch_channel_clear_state_handler(caller_channel, NULL((void*)0));
1241 switch_channel_clear_state_handler(peer_channel, NULL((void*)0));
1242
1243 switch_channel_add_state_handler(caller_channel, &signal_bridge_state_handlers);
1244 switch_channel_add_state_handler(peer_channel, &signal_bridge_state_handlers);
1245
1246 switch_channel_set_variable(caller_channel, "signal_bridge", "true")switch_channel_set_variable_var_check(caller_channel, "signal_bridge"
, "true", SWITCH_TRUE)
;
1247 switch_channel_set_variable(peer_channel, "signal_bridge", "true")switch_channel_set_variable_var_check(peer_channel, "signal_bridge"
, "true", SWITCH_TRUE)
;
1248
1249 /* fire events that will change the data table from "show channels" */
1250 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_EXECUTE)switch_event_create_subclass_detailed("src/switch_ivr_bridge.c"
, (const char * )(const char *)__func__, 1250, &event, SWITCH_EVENT_CHANNEL_EXECUTE
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1251 switch_channel_event_set_data(caller_channel, event);
1252 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application", "signal_bridge");
1253 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-Data", switch_core_session_get_uuid(peer_session));
1254 switch_event_fire(&event)switch_event_fire_detailed("src/switch_ivr_bridge.c", (const char
* )(const char *)__func__, 1254, &event, ((void*)0))
;
1255 }
1256
1257 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_EXECUTE)switch_event_create_subclass_detailed("src/switch_ivr_bridge.c"
, (const char * )(const char *)__func__, 1257, &event, SWITCH_EVENT_CHANNEL_EXECUTE
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1258 switch_channel_event_set_data(peer_channel, event);
1259 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application", "signal_bridge");
1260 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-Data", switch_core_session_get_uuid(session));
1261 switch_event_fire(&event)switch_event_fire_detailed("src/switch_ivr_bridge.c", (const char
* )(const char *)__func__, 1261, &event, ((void*)0))
;
1262 }
1263
1264 switch_channel_set_state_flag(caller_channel, CF_RESET);
1265 switch_channel_set_state_flag(peer_channel, CF_RESET);
1266
1267 switch_channel_set_state(caller_channel, CS_HIBERNATE)switch_channel_perform_set_state(caller_channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1267, CS_HIBERNATE)
;
1268 switch_channel_set_state(peer_channel, CS_HIBERNATE)switch_channel_perform_set_state(peer_channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1268, CS_HIBERNATE)
;
1269
1270#if 0
1271 if (switch_channel_test_flag(caller_channel, CF_BRIDGED)) {
1272 switch_channel_set_flag(caller_channel, CF_TRANSFER)switch_channel_set_flag_value(caller_channel, CF_TRANSFER, 1);
1273 switch_channel_set_flag(peer_channel, CF_TRANSFER)switch_channel_set_flag_value(peer_channel, CF_TRANSFER, 1);
1274 }
1275#endif
1276
1277 switch_ivr_bridge_display(session, peer_session);
1278
1279 return SWITCH_STATUS_SUCCESS;
1280}
1281
1282static void abort_call(switch_channel_t *caller_channel, switch_channel_t *peer_channel)
1283{
1284 switch_call_cause_t cause = switch_channel_get_cause(caller_channel);
1285
1286 if (!cause) {
1287 cause = SWITCH_CAUSE_ORIGINATOR_CANCEL;
1288 }
1289
1290 switch_channel_hangup(peer_channel, cause)switch_channel_perform_hangup(peer_channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1290, cause)
;
1291}
1292
1293SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_multi_threaded_bridge(switch_core_session_t *session,
1294 switch_core_session_t *peer_session,
1295 switch_input_callback_function_t input_callback, void *session_data,
1296 void *peer_session_data)
1297{
1298 switch_ivr_bridge_data_t *a_leg = switch_core_session_alloc(session, sizeof(*a_leg))switch_core_perform_session_alloc(session, sizeof(*a_leg), "src/switch_ivr_bridge.c"
, (const char *)__func__, 1298)
;
1299 switch_ivr_bridge_data_t *b_leg = switch_core_session_alloc(peer_session, sizeof(*b_leg))switch_core_perform_session_alloc(peer_session, sizeof(*b_leg
), "src/switch_ivr_bridge.c", (const char *)__func__, 1299)
;
1300 switch_channel_t *caller_channel = switch_core_session_get_channel(session);
1301 switch_channel_t *peer_channel = switch_core_session_get_channel(peer_session);
1302 int stream_id = 0;
1303 switch_status_t status = SWITCH_STATUS_SUCCESS;
1304 switch_channel_state_t state;
1305 switch_event_t *event;
1306 int br = 0;
1307 int inner_bridge = switch_channel_test_flag(caller_channel, CF_INNER_BRIDGE);
1308 const char *var;
1309 switch_call_cause_t cause;
1310 switch_core_session_message_t msg = { 0 };
1311
1312 if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE)) {
1313 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_bridge.c", (const char
*)__func__, 1313, (const char*)(session)
, SWITCH_LOG_DEBUG, "Call has no media... Redirecting to signal bridge.\n");
1314 return switch_ivr_signal_bridge(session, peer_session);
1315 }
1316
1317 check_bridge_export(caller_channel, peer_channel);
1318
1319 switch_channel_set_flag_recursive(caller_channel, CF_MEDIA_BRIDGE_TTL);
1320 switch_channel_set_flag_recursive(peer_channel, CF_MEDIA_BRIDGE_TTL);
1321
1322 switch_channel_set_flag_recursive(caller_channel, CF_BRIDGE_ORIGINATOR);
1323 switch_channel_clear_flag(peer_channel, CF_BRIDGE_ORIGINATOR);
1324
1325 switch_channel_audio_sync(caller_channel)switch_channel_perform_audio_sync(caller_channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1325)
;
1326 switch_channel_audio_sync(peer_channel)switch_channel_perform_audio_sync(peer_channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1326)
;
1327
1328 b_leg->session = peer_session;
1329 switch_copy_string(b_leg->b_uuid, switch_core_session_get_uuid(session), sizeof(b_leg->b_uuid));
1330 b_leg->stream_id = stream_id;
1331 b_leg->input_callback = input_callback;
1332 b_leg->session_data = peer_session_data;
1333 b_leg->clean_exit = 0;
1334 b_leg->other_leg_data = a_leg;
1335
1336 a_leg->session = session;
1337 switch_copy_string(a_leg->b_uuid, switch_core_session_get_uuid(peer_session), sizeof(a_leg->b_uuid));
1338 a_leg->stream_id = stream_id;
1339 a_leg->input_callback = input_callback;
1340 a_leg->session_data = session_data;
1341 a_leg->clean_exit = 0;
1342 a_leg->other_leg_data = b_leg;
1343
1344 switch_channel_add_state_handler(peer_channel, &audio_bridge_peer_state_handlers);
1345
1346 if (switch_channel_test_flag(peer_channel, CF_ANSWERED) && !switch_channel_test_flag(caller_channel, CF_ANSWERED)) {
1347 switch_channel_pass_callee_id(peer_channel, caller_channel);
1348 switch_channel_answer(caller_channel)switch_channel_perform_answer(caller_channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1348)
;
1349 }
1350
1351 if (switch_channel_test_flag(peer_channel, CF_ANSWERED) || switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA) ||
1352 switch_channel_test_flag(peer_channel, CF_RING_READY)) {
1353 const char *app, *data;
1354
1355 if (!switch_channel_ready(caller_channel)switch_channel_test_ready(caller_channel, SWITCH_TRUE, SWITCH_FALSE
)
) {
1356 abort_call(caller_channel, peer_channel);
1357 goto done;
1358 }
1359
1360 switch_channel_set_state(peer_channel, CS_CONSUME_MEDIA)switch_channel_perform_set_state(peer_channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1360, CS_CONSUME_MEDIA)
;
1361
1362 switch_channel_set_variable(peer_channel, "call_uuid", switch_core_session_get_uuid(session))switch_channel_set_variable_var_check(peer_channel, "call_uuid"
, switch_core_session_get_uuid(session), SWITCH_TRUE)
;
1363
1364 switch_channel_set_bridge_time(caller_channel);
1365 switch_channel_set_bridge_time(peer_channel);
1366
1367 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_BRIDGE)switch_event_create_subclass_detailed("src/switch_ivr_bridge.c"
, (const char * )(const char *)__func__, 1367, &event, SWITCH_EVENT_CHANNEL_BRIDGE
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1368 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-A-Unique-ID", switch_core_session_get_uuid(session));
1369 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", switch_core_session_get_uuid(peer_session));
1370 switch_channel_event_set_data(caller_channel, event);
1371 switch_event_add_presence_data_cols(peer_channel, event, "Bridge-B-PD-");
1372 switch_event_fire(&event)switch_event_fire_detailed("src/switch_ivr_bridge.c", (const char
* )(const char *)__func__, 1372, &event, ((void*)0))
;
1373 br = 1;
1374 }
1375
1376 if (switch_core_session_read_lock(peer_session) == SWITCH_STATUS_SUCCESS) {
1377 switch_channel_set_variable(caller_channel, SWITCH_BRIDGE_VARIABLE, switch_core_session_get_uuid(peer_session))switch_channel_set_variable_var_check(caller_channel, "bridge_to"
, switch_core_session_get_uuid(peer_session), SWITCH_TRUE)
;
1378 switch_channel_set_variable(peer_channel, SWITCH_BRIDGE_VARIABLE, switch_core_session_get_uuid(session))switch_channel_set_variable_var_check(peer_channel, "bridge_to"
, switch_core_session_get_uuid(session), SWITCH_TRUE)
;
1379 switch_channel_set_variable(caller_channel, SWITCH_LAST_BRIDGE_VARIABLE, switch_core_session_get_uuid(peer_session))switch_channel_set_variable_var_check(caller_channel, "last_bridge_to"
, switch_core_session_get_uuid(peer_session), SWITCH_TRUE)
;
1380 switch_channel_set_variable(peer_channel, SWITCH_LAST_BRIDGE_VARIABLE, switch_core_session_get_uuid(session))switch_channel_set_variable_var_check(peer_channel, "last_bridge_to"
, switch_core_session_get_uuid(session), SWITCH_TRUE)
;
1381
1382 if (!switch_channel_ready(caller_channel)switch_channel_test_ready(caller_channel, SWITCH_TRUE, SWITCH_FALSE
)
) {
1383 abort_call(caller_channel, peer_channel);
1384 switch_core_session_rwunlock(peer_session);
1385 goto done;
1386 }
1387
1388 if (!switch_channel_media_ready(caller_channel)switch_channel_test_ready(caller_channel, SWITCH_TRUE, SWITCH_TRUE
)
||
1389 (!switch_channel_test_flag(peer_channel, CF_ANSWERED) && !switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA))) {
1390 if ((status = switch_ivr_wait_for_answer(session, peer_session)) != SWITCH_STATUS_SUCCESS || !switch_channel_ready(caller_channel)switch_channel_test_ready(caller_channel, SWITCH_TRUE, SWITCH_FALSE
)
) {
1391 switch_channel_state_t w_state = switch_channel_get_state(caller_channel);
1392 switch_channel_hangup(peer_channel, SWITCH_CAUSE_ALLOTTED_TIMEOUT)switch_channel_perform_hangup(peer_channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1392, SWITCH_CAUSE_ALLOTTED_TIMEOUT
)
;
1393 if (w_state < CS_HANGUP && w_state != CS_ROUTING && w_state != CS_PARK &&
1394 !switch_channel_test_flag(caller_channel, CF_REDIRECT) && !switch_channel_test_flag(caller_channel, CF_TRANSFER) &&
1395 w_state != CS_EXECUTE) {
1396 const char *ext = switch_channel_get_variable(peer_channel, "original_destination_number")switch_channel_get_variable_dup(peer_channel, "original_destination_number"
, SWITCH_TRUE, -1)
;
1397 if (!ext) {
1398 ext = switch_channel_get_variable(peer_channel, "destination_number")switch_channel_get_variable_dup(peer_channel, "destination_number"
, SWITCH_TRUE, -1)
;
1399 }
1400
1401 if (ext) {
1402 switch_ivr_session_transfer(session, ext, NULL((void*)0), NULL((void*)0));
1403 } else {
1404 switch_channel_hangup(caller_channel, SWITCH_CAUSE_ALLOTTED_TIMEOUT)switch_channel_perform_hangup(caller_channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1404, SWITCH_CAUSE_ALLOTTED_TIMEOUT
)
;
1405 }
1406 }
1407 abort_call(caller_channel, peer_channel);
1408 switch_core_session_rwunlock(peer_session);
1409 goto done;
1410 }
1411 }
1412
1413 if (switch_channel_test_flag(peer_channel, CF_ANSWERED) && !switch_channel_test_flag(caller_channel, CF_ANSWERED)) {
1414 switch_channel_answer(caller_channel)switch_channel_perform_answer(caller_channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1414)
;
1415 }
1416
1417 switch_channel_wait_for_flag(peer_channel, CF_BROADCAST, SWITCH_FALSE, 10000, caller_channel);
1418 switch_ivr_parse_all_events(peer_session);
1419 switch_ivr_parse_all_events(session);
1420
1421 msg.message_id = SWITCH_MESSAGE_INDICATE_BRIDGE;
1422 msg.from = __FILE__"src/switch_ivr_bridge.c";
1423 msg.string_arg = switch_core_session_strdup(peer_session, switch_core_session_get_uuid(session))switch_core_perform_session_strdup(peer_session, switch_core_session_get_uuid
(session), "src/switch_ivr_bridge.c", (const char *)__func__,
1423)
;
1424
1425 if (switch_core_session_receive_message(peer_session, &msg)switch_core_session_perform_receive_message(peer_session, &
msg, "src/switch_ivr_bridge.c", (const char *)__func__, 1425)
!= SWITCH_STATUS_SUCCESS) {
1426 status = SWITCH_STATUS_FALSE;
1427 abort_call(caller_channel, peer_channel);
1428 switch_core_session_rwunlock(peer_session);
1429 goto done;
1430 }
1431
1432 msg.string_arg = switch_core_session_strdup(session, switch_core_session_get_uuid(peer_session))switch_core_perform_session_strdup(session, switch_core_session_get_uuid
(peer_session), "src/switch_ivr_bridge.c", (const char *)__func__
, 1432)
;
1433 if (switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg
, "src/switch_ivr_bridge.c", (const char *)__func__, 1433)
!= SWITCH_STATUS_SUCCESS) {
1434 status = SWITCH_STATUS_FALSE;
1435 abort_call(caller_channel, peer_channel);
1436 switch_core_session_rwunlock(peer_session);
1437 goto done;
1438 }
1439
1440 switch_channel_set_variable(caller_channel, SWITCH_BRIDGE_CHANNEL_VARIABLE, switch_channel_get_name(peer_channel))switch_channel_set_variable_var_check(caller_channel, "bridge_channel"
, switch_channel_get_name(peer_channel), SWITCH_TRUE)
;
1441 switch_channel_set_variable(caller_channel, SWITCH_BRIDGE_UUID_VARIABLE, switch_core_session_get_uuid(peer_session))switch_channel_set_variable_var_check(caller_channel, "bridge_uuid"
, switch_core_session_get_uuid(peer_session), SWITCH_TRUE)
;
1442 switch_channel_set_variable(caller_channel, SWITCH_SIGNAL_BOND_VARIABLE, switch_core_session_get_uuid(peer_session))switch_channel_set_variable_var_check(caller_channel, "signal_bond"
, switch_core_session_get_uuid(peer_session), SWITCH_TRUE)
;
1443 switch_channel_set_variable(peer_channel, SWITCH_BRIDGE_CHANNEL_VARIABLE, switch_channel_get_name(caller_channel))switch_channel_set_variable_var_check(peer_channel, "bridge_channel"
, switch_channel_get_name(caller_channel), SWITCH_TRUE)
;
1444 switch_channel_set_variable(peer_channel, SWITCH_BRIDGE_UUID_VARIABLE, switch_core_session_get_uuid(session))switch_channel_set_variable_var_check(peer_channel, "bridge_uuid"
, switch_core_session_get_uuid(session), SWITCH_TRUE)
;
1445 switch_channel_set_variable(peer_channel, SWITCH_SIGNAL_BOND_VARIABLE, switch_core_session_get_uuid(session))switch_channel_set_variable_var_check(peer_channel, "signal_bond"
, switch_core_session_get_uuid(session), SWITCH_TRUE)
;
1446
1447 if ((app = switch_channel_get_variable(caller_channel, "bridge_pre_execute_aleg_app")switch_channel_get_variable_dup(caller_channel, "bridge_pre_execute_aleg_app"
, SWITCH_TRUE, -1)
)) {
1448 switch_channel_set_variable(caller_channel, "bridge_pre_execute_app", app)switch_channel_set_variable_var_check(caller_channel, "bridge_pre_execute_app"
, app, SWITCH_TRUE)
;
1449
1450 if ((data = switch_channel_get_variable(caller_channel, "bridge_pre_execute_aleg_data")switch_channel_get_variable_dup(caller_channel, "bridge_pre_execute_aleg_data"
, SWITCH_TRUE, -1)
)) {
1451 switch_channel_set_variable(caller_channel, "bridge_pre_execute_data", data)switch_channel_set_variable_var_check(caller_channel, "bridge_pre_execute_data"
, data, SWITCH_TRUE)
;
1452 }
1453 }
1454
1455 if ((app = switch_channel_get_variable(caller_channel, "bridge_pre_execute_bleg_app")switch_channel_get_variable_dup(caller_channel, "bridge_pre_execute_bleg_app"
, SWITCH_TRUE, -1)
)) {
1456 switch_channel_set_variable(peer_channel, "bridge_pre_execute_app", app)switch_channel_set_variable_var_check(peer_channel, "bridge_pre_execute_app"
, app, SWITCH_TRUE)
;
1457
1458 if ((data = switch_channel_get_variable(caller_channel, "bridge_pre_execute_bleg_data")switch_channel_get_variable_dup(caller_channel, "bridge_pre_execute_bleg_data"
, SWITCH_TRUE, -1)
)) {
1459 switch_channel_set_variable(peer_channel, "bridge_pre_execute_data", data)switch_channel_set_variable_var_check(peer_channel, "bridge_pre_execute_data"
, data, SWITCH_TRUE)
;
1460 }
1461
1462 }
1463
1464 switch_channel_set_private(peer_channel, "_bridge_", b_leg);
1465 switch_channel_set_state(peer_channel, CS_EXCHANGE_MEDIA)switch_channel_perform_set_state(peer_channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1465, CS_EXCHANGE_MEDIA)
;
1466
1467 audio_bridge_thread(NULL((void*)0), (void *) a_leg);
1468
1469 switch_channel_clear_flag_recursive(caller_channel, CF_BRIDGE_ORIGINATOR);
1470
1471 switch_channel_stop_broadcast(peer_channel)for(;;) {if (switch_channel_test_flag(peer_channel, CF_BROADCAST
)) {switch_channel_set_flag_value(peer_channel, CF_STOP_BROADCAST
, 1); switch_channel_set_flag_value(peer_channel, CF_BREAK, 1
); } break;}
;
1472
1473
1474 while (switch_channel_get_state(peer_channel) == CS_EXCHANGE_MEDIA) {
1475 switch_ivr_parse_all_messages(session);
1476 switch_cond_next();
1477 }
1478
1479 if (inner_bridge) {
1480 if (switch_channel_ready(caller_channel)switch_channel_test_ready(caller_channel, SWITCH_TRUE, SWITCH_FALSE
)
) {
1481 switch_channel_set_flag(caller_channel, CF_BRIDGED)switch_channel_set_flag_value(caller_channel, CF_BRIDGED, 1);
1482 }
1483
1484 if (switch_channel_ready(peer_channel)switch_channel_test_ready(peer_channel, SWITCH_TRUE, SWITCH_FALSE
)
) {
1485 switch_channel_set_flag(peer_channel, CF_BRIDGED)switch_channel_set_flag_value(peer_channel, CF_BRIDGED, 1);
1486 }
1487 }
1488
1489 if ((cause = switch_channel_get_cause(caller_channel))) {
1490 switch_channel_set_variable(peer_channel, SWITCH_BRIDGE_HANGUP_CAUSE_VARIABLE, switch_channel_cause2str(cause))switch_channel_set_variable_var_check(peer_channel, "bridge_hangup_cause"
, switch_channel_cause2str(cause), SWITCH_TRUE)
;
1491 }
1492
1493 if ((cause = switch_channel_get_cause(peer_channel))) {
1494 switch_channel_set_variable(caller_channel, SWITCH_BRIDGE_HANGUP_CAUSE_VARIABLE, switch_channel_cause2str(cause))switch_channel_set_variable_var_check(caller_channel, "bridge_hangup_cause"
, switch_channel_cause2str(cause), SWITCH_TRUE)
;
1495 }
1496
1497 if (switch_channel_down_nosig(peer_channel)(switch_channel_get_state(peer_channel) >= CS_HANGUP)) {
1498 switch_bool_t copy_xml_cdr = switch_true(switch_channel_get_variable(peer_channel, SWITCH_COPY_XML_CDR_VARIABLE)switch_channel_get_variable_dup(peer_channel, "copy_xml_cdr",
SWITCH_TRUE, -1)
);
1499 switch_bool_t copy_json_cdr = switch_true(switch_channel_get_variable(peer_channel, SWITCH_COPY_JSON_CDR_VARIABLE)switch_channel_get_variable_dup(peer_channel, "copy_json_cdr"
, SWITCH_TRUE, -1)
);
1500
1501 if (copy_xml_cdr || copy_json_cdr) {
1502 char *cdr_text = NULL((void*)0);
1503
1504 switch_channel_wait_for_state(peer_channel, caller_channel, CS_DESTROY);
1505
1506 if (copy_xml_cdr) {
1507 switch_xml_t cdr = NULL((void*)0);
1508
1509 if (switch_ivr_generate_xml_cdr(peer_session, &cdr) == SWITCH_STATUS_SUCCESS) {
1510 cdr_text = switch_xml_toxml(cdr, SWITCH_FALSE);
1511 switch_xml_free(cdr);
1512 }
1513 }
1514 if (copy_json_cdr) {
1515 cJSON *cdr = NULL((void*)0);
1516
1517 if (switch_ivr_generate_json_cdr(peer_session, &cdr, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) {
1518 cdr_text = cJSON_PrintUnformatted(cdr);
1519 cJSON_Delete(cdr);
1520 }
1521 }
1522
1523 if (cdr_text) {
1524 switch_channel_set_variable(caller_channel, "b_leg_cdr", cdr_text)switch_channel_set_variable_var_check(caller_channel, "b_leg_cdr"
, cdr_text, SWITCH_TRUE)
;
1525 switch_channel_set_variable_name_printf(caller_channel, cdr_text, "b_leg_cdr_%s", switch_core_session_get_uuid(peer_session));
1526 switch_safe_free(cdr_text)if (cdr_text) {free(cdr_text);cdr_text=((void*)0);};
1527 }
1528 }
1529
1530 }
1531
1532 switch_core_session_rwunlock(peer_session);
1533
1534 } else {
1535 status = SWITCH_STATUS_FALSE;
1536 }
1537 } else {
1538 status = SWITCH_STATUS_FALSE;
1539 }
1540
1541 if (status != SWITCH_STATUS_SUCCESS) {
1542 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_bridge.c", (const char
*)__func__, 1542, (const char*)(session)
, SWITCH_LOG_WARNING, "Bridge Failed %s->%s\n",
1543 switch_channel_get_name(caller_channel), switch_channel_get_name(peer_channel)
1544 );
1545 switch_channel_hangup(peer_channel, SWITCH_CAUSE_NO_ANSWER)switch_channel_perform_hangup(peer_channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1545, SWITCH_CAUSE_NO_ANSWER)
;
1546 }
1547
1548 done:
1549
1550 switch_channel_set_variable(peer_channel, "call_uuid", switch_core_session_get_uuid(peer_session))switch_channel_set_variable_var_check(peer_channel, "call_uuid"
, switch_core_session_get_uuid(peer_session), SWITCH_TRUE)
;
1551
1552 if (br && switch_event_create(&event, SWITCH_EVENT_CHANNEL_UNBRIDGE)switch_event_create_subclass_detailed("src/switch_ivr_bridge.c"
, (const char * )(const char *)__func__, 1552, &event, SWITCH_EVENT_CHANNEL_UNBRIDGE
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1553 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-A-Unique-ID", switch_core_session_get_uuid(session));
1554 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", switch_core_session_get_uuid(peer_session));
1555 switch_channel_event_set_data(caller_channel, event);
1556 switch_event_add_presence_data_cols(peer_channel, event, "Bridge-B-PD-");
1557 switch_event_fire(&event)switch_event_fire_detailed("src/switch_ivr_bridge.c", (const char
* )(const char *)__func__, 1557, &event, ((void*)0))
;
1558 }
1559
1560 msg.message_id = SWITCH_MESSAGE_INDICATE_UNBRIDGE;
1561 msg.from = __FILE__"src/switch_ivr_bridge.c";
1562 msg.string_arg = switch_core_session_strdup(peer_session, switch_core_session_get_uuid(session))switch_core_perform_session_strdup(peer_session, switch_core_session_get_uuid
(session), "src/switch_ivr_bridge.c", (const char *)__func__,
1562)
;
1563 switch_core_session_receive_message(peer_session, &msg)switch_core_session_perform_receive_message(peer_session, &
msg, "src/switch_ivr_bridge.c", (const char *)__func__, 1563)
;
1564
1565 msg.string_arg = switch_core_session_strdup(session, switch_core_session_get_uuid(peer_session))switch_core_perform_session_strdup(session, switch_core_session_get_uuid
(peer_session), "src/switch_ivr_bridge.c", (const char *)__func__
, 1565)
;
1566 switch_core_session_receive_message(session, &msg)switch_core_session_perform_receive_message(session, &msg
, "src/switch_ivr_bridge.c", (const char *)__func__, 1566)
;
1567
1568 state = switch_channel_get_state(caller_channel);
1569
1570 if (!switch_channel_test_flag(caller_channel, CF_TRANSFER) && !switch_channel_test_flag(caller_channel, CF_REDIRECT) &&
1571 !switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE) && !a_leg->clean_exit && !inner_bridge) {
1572 switch_call_cause_t cause = switch_channel_get_cause(peer_channel);
1573 const char *hup = switch_channel_get_variable(caller_channel, SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE)switch_channel_get_variable_dup(caller_channel, "hangup_after_bridge"
, SWITCH_TRUE, -1)
;
1574 int explicit = 0;
1575
1576 if (cause == SWITCH_CAUSE_NONE) {
1577 cause = SWITCH_CAUSE_NORMAL_CLEARING;
1578 }
1579
1580 if (hup) {
1581 explicit = !strcasecmp(hup, "explicit");
1582 }
1583
1584 if (cause && !switch_channel_test_flag(peer_channel, CF_ANSWERED)) {
1585 switch_channel_handle_cause(caller_channel, cause);
1586 }
1587
1588 if (explicit) {
1589 if (switch_channel_test_flag(peer_channel, CF_INTERCEPTED)) {
1590 switch_channel_set_flag(peer_channel, CF_INTERCEPT)switch_channel_set_flag_value(peer_channel, CF_INTERCEPT, 1);
1591 }
1592 switch_channel_hangup(caller_channel, cause)switch_channel_perform_hangup(caller_channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1592, cause)
;
1593 }
1594
1595 if ((state != CS_EXECUTE && state != CS_SOFT_EXECUTE && state != CS_PARK && state != CS_ROUTING) ||
1596 (switch_channel_test_flag(peer_channel, CF_ANSWERED) && state < CS_HANGUP)) {
1597
1598 if (!switch_channel_test_flag(caller_channel, CF_TRANSFER)) {
1599 if (switch_true(switch_channel_get_variable(caller_channel, SWITCH_PARK_AFTER_BRIDGE_VARIABLE)switch_channel_get_variable_dup(caller_channel, "park_after_bridge"
, SWITCH_TRUE, -1)
)) {
1600 switch_ivr_park_session(session);
1601 } else if ((var = switch_channel_get_variable(caller_channel, SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE)switch_channel_get_variable_dup(caller_channel, "transfer_after_bridge"
, SWITCH_TRUE, -1)
)) {
1602 transfer_after_bridge(session, var);
1603 } else {
1604 if ((switch_channel_test_flag(peer_channel, CF_ANSWERED) && switch_true(hup))) {
1605 if (switch_channel_test_flag(peer_channel, CF_INTERCEPTED)) {
1606 switch_channel_set_flag(peer_channel, CF_INTERCEPT)switch_channel_set_flag_value(peer_channel, CF_INTERCEPT, 1);
1607 }
1608 switch_channel_hangup(caller_channel, cause)switch_channel_perform_hangup(caller_channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1608, cause)
;
1609 }
1610 }
1611 }
1612 }
1613 }
1614
1615 if (switch_channel_test_flag(caller_channel, CF_REDIRECT)) {
1616 if (switch_channel_test_flag(caller_channel, CF_RESET)) {
1617 switch_channel_clear_flag(caller_channel, CF_RESET);
1618 } else {
1619 state = switch_channel_get_state(caller_channel);
1620 if (!(state == CS_RESET || state == CS_PARK || state == CS_ROUTING)) {
1621 switch_channel_set_state(caller_channel, CS_RESET)switch_channel_perform_set_state(caller_channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1621, CS_RESET)
;
1622 }
1623 }
1624 }
1625
1626 return status;
1627}
1628
1629static void cleanup_proxy_mode_b(switch_core_session_t *session)
1630{
1631 switch_channel_t *channel = switch_core_session_get_channel(session);
1632
1633
1634 if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
1635 switch_ivr_media(switch_core_session_get_uuid(session), SMF_NONE);
1636 }
1637}
1638
1639
1640static void cleanup_proxy_mode_a(switch_core_session_t *session)
1641{
1642 switch_core_session_t *sbsession;
1643 switch_channel_t *channel = switch_core_session_get_channel(session);
1644 int done = 0;
1645
1646 if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
1647 if (switch_core_session_get_partner(session, &sbsession)switch_core_session_perform_get_partner(session, &sbsession
, "src/switch_ivr_bridge.c", (const char *)__func__, 1647)
== SWITCH_STATUS_SUCCESS) {
1648 switch_channel_t *sbchannel = switch_core_session_get_channel(sbsession);
1649
1650 if (switch_channel_test_flag(sbchannel, CF_PROXY_MODE)) {
1651 /* Clear this now, otherwise will cause the one we're interested in to hang up too...*/
1652 switch_channel_set_variable(sbchannel, SWITCH_SIGNAL_BRIDGE_VARIABLE, NULL)switch_channel_set_variable_var_check(sbchannel, "signal_bridge_to"
, ((void*)0), SWITCH_TRUE)
;
1653 switch_channel_hangup(sbchannel, SWITCH_CAUSE_ATTENDED_TRANSFER)switch_channel_perform_hangup(sbchannel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1653, SWITCH_CAUSE_ATTENDED_TRANSFER
)
;
1654 } else {
1655 done = 1;
1656 }
1657 switch_core_session_rwunlock(sbsession);
1658 }
1659 }
1660
1661 if (done) return;
1662
1663 switch_channel_set_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE, NULL)switch_channel_set_variable_var_check(channel, "signal_bridge_to"
, ((void*)0), SWITCH_TRUE)
;
1664 switch_channel_set_variable(channel, SWITCH_BRIDGE_VARIABLE, NULL)switch_channel_set_variable_var_check(channel, "bridge_to", (
(void*)0), SWITCH_TRUE)
;
1665 switch_channel_set_variable(channel, SWITCH_BRIDGE_UUID_VARIABLE, NULL)switch_channel_set_variable_var_check(channel, "bridge_uuid",
((void*)0), SWITCH_TRUE)
;
1666
1667}
1668
1669
1670SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_uuid_bridge(const char *originator_uuid, const char *originatee_uuid)
1671{
1672 switch_core_session_t *originator_session, *originatee_session, *swap_session;
1673 switch_channel_t *originator_channel, *originatee_channel, *swap_channel;
1674 switch_status_t status = SWITCH_STATUS_FALSE;
1675 switch_caller_profile_t *originator_cp, *originatee_cp;
1676 switch_channel_state_t state;
1677
1678 if ((originator_session = switch_core_session_locate(originator_uuid)switch_core_session_perform_locate(originator_uuid, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1678)
)) {
1679 if ((originatee_session = switch_core_session_locate(originatee_uuid)switch_core_session_perform_locate(originatee_uuid, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1679)
)) {
1680 originator_channel = switch_core_session_get_channel(originator_session);
1681 originatee_channel = switch_core_session_get_channel(originatee_session);
1682
1683
1684 if (switch_channel_test_flag(originator_channel, CF_LEG_HOLDING)) {
1685 switch_channel_set_flag(originator_channel, CF_HOLD_ON_BRIDGE)switch_channel_set_flag_value(originator_channel, CF_HOLD_ON_BRIDGE
, 1)
;
1686 }
1687
1688 if (switch_channel_test_flag(originatee_channel, CF_LEG_HOLDING)) {
1689 switch_channel_set_flag(originatee_channel, CF_HOLD_ON_BRIDGE)switch_channel_set_flag_value(originatee_channel, CF_HOLD_ON_BRIDGE
, 1)
;
1690 }
1691
1692
1693 if (switch_channel_direction(originator_channel) == SWITCH_CALL_DIRECTION_OUTBOUND && !switch_channel_test_flag(originator_channel, CF_DIALPLAN)) {
1694 if (!switch_channel_test_flag(originator_channel, CF_RECOVERING_BRIDGE)) {
1695 switch_channel_flip_cid(originator_channel);
1696 }
1697 switch_channel_set_flag(originator_channel, CF_DIALPLAN)switch_channel_set_flag_value(originator_channel, CF_DIALPLAN
, 1)
;
1698 }
1699
1700 if (switch_channel_down_nosig(originator_channel)(switch_channel_get_state(originator_channel) >= CS_HANGUP
)
) {
1701 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originator_session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_bridge.c", (const char
*)__func__, 1701, (const char*)(originator_session)
, SWITCH_LOG_DEBUG, "%s is hungup refusing to bridge.\n", switch_channel_get_name(originatee_channel));
1702 switch_core_session_rwunlock(originator_session);
1703 switch_core_session_rwunlock(originatee_session);
1704 return SWITCH_STATUS_FALSE;
1705 }
1706
1707 if (!switch_channel_media_up(originator_channel)(switch_channel_test_flag(originator_channel, CF_ANSWERED) ||
switch_channel_test_flag(originator_channel, CF_EARLY_MEDIA)
)
) {
1708 if (switch_channel_media_up(originatee_channel)(switch_channel_test_flag(originatee_channel, CF_ANSWERED) ||
switch_channel_test_flag(originatee_channel, CF_EARLY_MEDIA)
)
) {
1709 swap_session = originator_session;
1710 originator_session = originatee_session;
1711 originatee_session = swap_session;
1712
1713 swap_channel = originator_channel;
1714 originator_channel = originatee_channel;
1715 originatee_channel = swap_channel;
1716 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originatee_session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_bridge.c", (const char
*)__func__, 1716, (const char*)(originatee_session)
, SWITCH_LOG_WARNING, "reversing order of channels so this will work!\n");
1717 } else {
1718 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originator_session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_bridge.c", (const char
*)__func__, 1718, (const char*)(originator_session)
, SWITCH_LOG_CRIT, "Neither channel is answered, cannot bridge them.\n");
1719 switch_core_session_rwunlock(originator_session);
1720 switch_core_session_rwunlock(originatee_session);
1721 return SWITCH_STATUS_FALSE;
1722 }
1723 }
1724
1725 if (switch_channel_direction(originatee_channel) == SWITCH_CALL_DIRECTION_OUTBOUND && switch_channel_test_flag(originatee_channel, CF_DIALPLAN)) {
1726 switch_channel_clear_flag(originatee_channel, CF_DIALPLAN);
1727 }
1728
1729 cleanup_proxy_mode_a(originator_session);
1730 cleanup_proxy_mode_a(originatee_session);
1731
1732 /* override transmit state for originator_channel to bridge to originatee_channel
1733 * install pointer to originatee_session into originator_channel
1734 * set CF_TRANSFER on both channels and change state to CS_SOFT_EXECUTE to
1735 * interrupt anything they are already doing.
1736 * originatee_session will fall asleep and originator_session will bridge to it
1737 */
1738
1739 switch_channel_set_flag(originator_channel, CF_REDIRECT)switch_channel_set_flag_value(originator_channel, CF_REDIRECT
, 1)
;
1740 switch_channel_set_flag(originatee_channel, CF_REDIRECT)switch_channel_set_flag_value(originatee_channel, CF_REDIRECT
, 1)
;
1741
1742
1743 switch_channel_set_variable(originator_channel, SWITCH_UUID_BRIDGE, switch_core_session_get_uuid(originatee_session))switch_channel_set_variable_var_check(originator_channel, "uuid_bridge"
, switch_core_session_get_uuid(originatee_session), SWITCH_TRUE
)
;
1744 switch_channel_set_variable(originator_channel, SWITCH_BRIDGE_CHANNEL_VARIABLE, switch_channel_get_name(originatee_channel))switch_channel_set_variable_var_check(originator_channel, "bridge_channel"
, switch_channel_get_name(originatee_channel), SWITCH_TRUE)
;
1745 switch_channel_set_variable(originator_channel, SWITCH_BRIDGE_UUID_VARIABLE, switch_core_session_get_uuid(originatee_session))switch_channel_set_variable_var_check(originator_channel, "bridge_uuid"
, switch_core_session_get_uuid(originatee_session), SWITCH_TRUE
)
;
1746 switch_channel_set_variable(originator_channel, SWITCH_SIGNAL_BOND_VARIABLE, switch_core_session_get_uuid(originatee_session))switch_channel_set_variable_var_check(originator_channel, "signal_bond"
, switch_core_session_get_uuid(originatee_session), SWITCH_TRUE
)
;
1747 switch_channel_set_variable(originatee_channel, SWITCH_BRIDGE_CHANNEL_VARIABLE, switch_channel_get_name(originator_channel))switch_channel_set_variable_var_check(originatee_channel, "bridge_channel"
, switch_channel_get_name(originator_channel), SWITCH_TRUE)
;
1748 switch_channel_set_variable(originatee_channel, SWITCH_BRIDGE_UUID_VARIABLE, switch_core_session_get_uuid(originator_session))switch_channel_set_variable_var_check(originatee_channel, "bridge_uuid"
, switch_core_session_get_uuid(originator_session), SWITCH_TRUE
)
;
1749 switch_channel_set_variable(originatee_channel, SWITCH_SIGNAL_BOND_VARIABLE, switch_core_session_get_uuid(originator_session))switch_channel_set_variable_var_check(originatee_channel, "signal_bond"
, switch_core_session_get_uuid(originator_session), SWITCH_TRUE
)
;
1750
1751
1752 originator_cp = switch_channel_get_caller_profile(originator_channel);
1753 originatee_cp = switch_channel_get_caller_profile(originatee_channel);
1754
1755
1756
1757 if (switch_channel_outbound_display(originator_channel)((switch_channel_direction(originator_channel) == SWITCH_CALL_DIRECTION_INBOUND
&& switch_channel_test_flag(originator_channel, CF_BLEG
)) || (switch_channel_direction(originator_channel) == SWITCH_CALL_DIRECTION_OUTBOUND
&& !switch_channel_test_flag(originator_channel, CF_DIALPLAN
)))
) {
1758 switch_channel_invert_cid(originator_channel);
1759
1760 if (switch_channel_direction(originator_channel) == SWITCH_CALL_DIRECTION_INBOUND) {
1761 switch_channel_clear_flag(originatee_channel, CF_BLEG);
1762 }
1763 }
1764
1765 if (switch_channel_inbound_display(originatee_channel)((switch_channel_direction(originatee_channel) == SWITCH_CALL_DIRECTION_INBOUND
&& !switch_channel_test_flag(originatee_channel, CF_BLEG
)) || (switch_channel_direction(originatee_channel) == SWITCH_CALL_DIRECTION_OUTBOUND
&& switch_channel_test_flag(originatee_channel, CF_DIALPLAN
)))
) {
1766 switch_channel_invert_cid(originatee_channel);
1767
1768 if (switch_channel_direction(originatee_channel) == SWITCH_CALL_DIRECTION_INBOUND) {
1769 switch_channel_set_flag(originatee_channel, CF_BLEG)switch_channel_set_flag_value(originatee_channel, CF_BLEG, 1);
1770 }
1771
1772 }
1773
1774
1775 switch_channel_set_variable(originatee_channel, "original_destination_number", originatee_cp->destination_number)switch_channel_set_variable_var_check(originatee_channel, "original_destination_number"
, originatee_cp->destination_number, SWITCH_TRUE)
;
1776 switch_channel_set_variable(originatee_channel, "original_caller_id_name", originatee_cp->caller_id_name)switch_channel_set_variable_var_check(originatee_channel, "original_caller_id_name"
, originatee_cp->caller_id_name, SWITCH_TRUE)
;
1777 switch_channel_set_variable(originatee_channel, "original_caller_id_number", originatee_cp->caller_id_number)switch_channel_set_variable_var_check(originatee_channel, "original_caller_id_number"
, originatee_cp->caller_id_number, SWITCH_TRUE)
;
1778
1779 switch_channel_set_variable(originator_channel, "original_destination_number", originator_cp->destination_number)switch_channel_set_variable_var_check(originator_channel, "original_destination_number"
, originator_cp->destination_number, SWITCH_TRUE)
;
1780 switch_channel_set_variable(originator_channel, "original_caller_id_name", originator_cp->caller_id_name)switch_channel_set_variable_var_check(originator_channel, "original_caller_id_name"
, originator_cp->caller_id_name, SWITCH_TRUE)
;
1781 switch_channel_set_variable(originator_channel, "original_caller_id_number", originator_cp->caller_id_number)switch_channel_set_variable_var_check(originator_channel, "original_caller_id_number"
, originator_cp->caller_id_number, SWITCH_TRUE)
;
1782
1783 switch_channel_step_caller_profile(originatee_channel);
1784 switch_channel_step_caller_profile(originator_channel);
1785
1786 originator_cp = switch_channel_get_caller_profile(originator_channel);
1787 originatee_cp = switch_channel_get_caller_profile(originatee_channel);
1788
1789
1790#ifdef DEEP_DEBUG_CID
1791 {
1792 switch_event_t *event;
1793
1794 if (switch_event_create_plain(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) {
1795 //switch_channel_event_set_basic_data(originator_channel, event);
1796 switch_caller_profile_event_set_data(originator_cp, "ORIGINATOR", event);
1797 switch_caller_profile_event_set_data(originatee_cp, "ORIGINATEE", event);
1798 DUMP_EVENT(event){char *event_str;switch_event_serialize(event, &event_str
, SWITCH_FALSE);switch_log_printf(SWITCH_CHANNEL_ID_LOG, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1798, ((void*)0), SWITCH_LOG_CRIT, "DUMP\n%s\n"
, event_str);free(event_str);}
;
1799 switch_event_destroy(&event);
1800 }
1801 }
1802#endif
1803
1804 switch_channel_set_originator_caller_profile(originatee_channel, switch_caller_profile_clone(originatee_session, originator_cp));
1805 switch_channel_set_originatee_caller_profile(originator_channel, switch_caller_profile_clone(originator_session, originatee_cp));
1806
1807 originator_cp->callee_id_name = switch_core_strdup(originator_cp->pool, originatee_cp->callee_id_name)switch_core_perform_strdup(originator_cp->pool, originatee_cp
->callee_id_name, "src/switch_ivr_bridge.c", (const char *
)__func__, 1807)
;
1808 originator_cp->callee_id_number = switch_core_strdup(originator_cp->pool, originatee_cp->callee_id_number)switch_core_perform_strdup(originator_cp->pool, originatee_cp
->callee_id_number, "src/switch_ivr_bridge.c", (const char
*)__func__, 1808)
;
1809
1810 originatee_cp->caller_id_name = switch_core_strdup(originatee_cp->pool, originator_cp->caller_id_name)switch_core_perform_strdup(originatee_cp->pool, originator_cp
->caller_id_name, "src/switch_ivr_bridge.c", (const char *
)__func__, 1810)
;
1811 originatee_cp->caller_id_number = switch_core_strdup(originatee_cp->pool, originator_cp->caller_id_number)switch_core_perform_strdup(originatee_cp->pool, originator_cp
->caller_id_number, "src/switch_ivr_bridge.c", (const char
*)__func__, 1811)
;
1812
1813#ifdef DEEP_DEBUG_CID
1814 {
1815 switch_event_t *event;
1816
1817 if (switch_event_create_plain(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) {
1818 //switch_channel_event_set_basic_data(originator_channel, event);
1819 switch_caller_profile_event_set_data(originator_cp, "POST-ORIGINATOR", event);
1820 switch_caller_profile_event_set_data(originatee_cp, "POST-ORIGINATEE", event);
1821 DUMP_EVENT(event){char *event_str;switch_event_serialize(event, &event_str
, SWITCH_FALSE);switch_log_printf(SWITCH_CHANNEL_ID_LOG, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1821, ((void*)0), SWITCH_LOG_CRIT, "DUMP\n%s\n"
, event_str);free(event_str);}
;
1822 switch_event_destroy(&event);
1823 }
1824 }
1825#endif
1826
1827 switch_channel_stop_broadcast(originator_channel)for(;;) {if (switch_channel_test_flag(originator_channel, CF_BROADCAST
)) {switch_channel_set_flag_value(originator_channel, CF_STOP_BROADCAST
, 1); switch_channel_set_flag_value(originator_channel, CF_BREAK
, 1); } break;}
;
1828 switch_channel_stop_broadcast(originatee_channel)for(;;) {if (switch_channel_test_flag(originatee_channel, CF_BROADCAST
)) {switch_channel_set_flag_value(originatee_channel, CF_STOP_BROADCAST
, 1); switch_channel_set_flag_value(originatee_channel, CF_BREAK
, 1); } break;}
;
1829
1830 switch_channel_set_flag(originator_channel, CF_TRANSFER)switch_channel_set_flag_value(originator_channel, CF_TRANSFER
, 1)
;
1831 switch_channel_set_flag(originatee_channel, CF_TRANSFER)switch_channel_set_flag_value(originatee_channel, CF_TRANSFER
, 1)
;
1832
1833
1834 switch_channel_clear_flag(originator_channel, CF_ORIGINATING);
1835 switch_channel_clear_flag(originatee_channel, CF_ORIGINATING);
1836
1837
1838 originator_cp->transfer_source = switch_core_sprintf(originator_cp->pool,
1839 "%ld:%s:uuid_br:%s", (long)switch_epoch_time_now(NULL((void*)0)), originator_cp->uuid_str,
1840 switch_core_session_get_uuid(originatee_session));
1841 switch_channel_add_variable_var_check(originator_channel, SWITCH_TRANSFER_HISTORY_VARIABLE"transfer_history",
1842 originator_cp->transfer_source, SWITCH_FALSE, SWITCH_STACK_PUSH);
1843 switch_channel_set_variable(originator_channel, SWITCH_TRANSFER_SOURCE_VARIABLE, originator_cp->transfer_source)switch_channel_set_variable_var_check(originator_channel, "transfer_source"
, originator_cp->transfer_source, SWITCH_TRUE)
;
1844
1845
1846 originatee_cp->transfer_source = switch_core_sprintf(originatee_cp->pool,
1847 "%ld:%s:uuid_br:%s", (long)switch_epoch_time_now(NULL((void*)0)), originatee_cp->uuid_str,
1848 switch_core_session_get_uuid(originator_session));
1849 switch_channel_add_variable_var_check(originatee_channel, SWITCH_TRANSFER_HISTORY_VARIABLE"transfer_history",
1850 originatee_cp->transfer_source, SWITCH_FALSE, SWITCH_STACK_PUSH);
1851 switch_channel_set_variable(originatee_channel, SWITCH_TRANSFER_SOURCE_VARIABLE, originatee_cp->transfer_source)switch_channel_set_variable_var_check(originatee_channel, "transfer_source"
, originatee_cp->transfer_source, SWITCH_TRUE)
;
1852
1853 /* change the states and let the chips fall where they may */
1854
1855 //switch_channel_set_variable(originator_channel, SWITCH_PARK_AFTER_BRIDGE_VARIABLE, NULL);
1856 //switch_channel_set_variable(originatee_channel, SWITCH_PARK_AFTER_BRIDGE_VARIABLE, NULL);
1857 switch_channel_clear_state_handler(originator_channel, NULL((void*)0));
1858 switch_channel_clear_state_handler(originatee_channel, NULL((void*)0));
1859
1860
1861
1862 switch_channel_clear_state_flag(originator_channel, CF_BRIDGE_ORIGINATOR);
1863 switch_channel_clear_state_flag(originatee_channel, CF_BRIDGE_ORIGINATOR);
1864
1865 switch_channel_clear_flag(originator_channel, CF_UUID_BRIDGE_ORIGINATOR);
1866 switch_channel_clear_flag(originatee_channel, CF_UUID_BRIDGE_ORIGINATOR);
1867 switch_channel_set_state_flag(originator_channel, CF_UUID_BRIDGE_ORIGINATOR);
1868
1869 switch_channel_add_state_handler(originator_channel, &uuid_bridge_state_handlers);
1870 switch_channel_add_state_handler(originatee_channel, &uuid_bridge_state_handlers);
1871
1872 state = switch_channel_get_state(originator_channel);
1873 switch_channel_set_state(originator_channel, state == CS_HIBERNATE ? CS_CONSUME_MEDIA : CS_HIBERNATE)switch_channel_perform_set_state(originator_channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1873, state == CS_HIBERNATE ? CS_CONSUME_MEDIA
: CS_HIBERNATE)
;
1874 state = switch_channel_get_state(originatee_channel);
1875 switch_channel_set_state(originatee_channel, state == CS_HIBERNATE ? CS_CONSUME_MEDIA : CS_HIBERNATE)switch_channel_perform_set_state(originatee_channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1875, state == CS_HIBERNATE ? CS_CONSUME_MEDIA
: CS_HIBERNATE)
;
1876
1877 status = SWITCH_STATUS_SUCCESS;
1878
1879 //switch_ivr_bridge_display(originator_session, originatee_session);
1880
1881 /* release the read locks we have on the channels */
1882 switch_core_session_rwunlock(originator_session);
1883 switch_core_session_rwunlock(originatee_session);
1884
1885 } else {
1886 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originator_session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_bridge.c", (const char
*)__func__, 1886, (const char*)(originator_session)
, SWITCH_LOG_DEBUG, "originatee uuid %s is not present\n", originatee_uuid);
1887 switch_core_session_rwunlock(originator_session);
1888 }
1889 } else {
1890 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originator_session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_bridge.c", (const char
*)__func__, 1890, (const char*)(originator_session)
, SWITCH_LOG_DEBUG, "originator uuid %s is not present\n", originator_uuid);
1891 }
1892
1893 return status;
1894}
1895
1896SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_find_bridged_uuid(const char *uuid, char *b_uuid, switch_size_t blen)
1897{
1898 switch_core_session_t *rsession;
1899 switch_status_t status = SWITCH_STATUS_FALSE;
1900
1901 switch_assert(uuid)((uuid) ? (void) (0) : __assert_fail ("uuid", "src/switch_ivr_bridge.c"
, 1901, __PRETTY_FUNCTION__))
;
1902
1903 if ((rsession = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1903)
)) {
1904 switch_channel_t *rchannel = switch_core_session_get_channel(rsession);
1905 const char *brto;
1906
1907 if ((brto = switch_channel_get_variable(rchannel, SWITCH_ORIGINATE_SIGNAL_BOND_VARIABLE)switch_channel_get_variable_dup(rchannel, "originate_signal_bond"
, SWITCH_TRUE, -1)
) ||
1908 (brto = switch_channel_get_partner_uuid(rchannel))) {
1909 switch_copy_string(b_uuid, brto, blen);
1910 status = SWITCH_STATUS_SUCCESS;
1911 }
1912 switch_core_session_rwunlock(rsession);
1913 }
1914
1915 return status;
1916
1917}
1918
1919SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_ivr_intercept_session(switch_core_session_t *session, const char *uuid, switch_bool_t bleg)
1920{
1921 switch_core_session_t *rsession, *bsession = NULL((void*)0);
1922 switch_channel_t *channel, *rchannel, *bchannel = NULL((void*)0);
1923 const char *buuid, *var;
1924 char brto[SWITCH_UUID_FORMATTED_LENGTH256 + 1] = "";
1925
1926 if (bleg) {
1927 if (switch_ivr_find_bridged_uuid(uuid, brto, sizeof(brto)) == SWITCH_STATUS_SUCCESS) {
1928 uuid = switch_core_session_strdup(session, brto)switch_core_perform_session_strdup(session, brto, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1928)
;
1929 } else {
1930 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_bridge.c", (const char
*)__func__, 1930, (const char*)(session)
, SWITCH_LOG_DEBUG, "no uuid bridged to %s\n", uuid);
1931 return;
1932 }
1933 }
1934
1935 if (zstr(uuid)_zstr(uuid) || !(rsession = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1935)
)) {
1936 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_bridge.c", (const char
*)__func__, 1936, (const char*)(session)
, SWITCH_LOG_DEBUG, "no uuid %s\n", uuid);
1937 return;
1938 }
1939
1940 channel = switch_core_session_get_channel(session);
1941 rchannel = switch_core_session_get_channel(rsession);
1942 buuid = switch_channel_get_partner_uuid(rchannel);
1943
1944 if ((var = switch_channel_get_variable(channel, "intercept_unbridged_only")switch_channel_get_variable_dup(channel, "intercept_unbridged_only"
, SWITCH_TRUE, -1)
) && switch_true(var)) {
1945 if ((switch_channel_test_flag(rchannel, CF_BRIDGED))) {
1946 switch_core_session_rwunlock(rsession);
1947 return;
1948 }
1949 }
1950
1951 if ((var = switch_channel_get_variable(channel, "intercept_unanswered_only")switch_channel_get_variable_dup(channel, "intercept_unanswered_only"
, SWITCH_TRUE, -1)
) && switch_true(var)) {
1952 if ((switch_channel_test_flag(rchannel, CF_ANSWERED))) {
1953 switch_core_session_rwunlock(rsession);
1954 return;
1955 }
1956 }
1957
1958 switch_channel_answer(channel)switch_channel_perform_answer(channel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1958)
;
1959
1960 if (!zstr(buuid)_zstr(buuid)) {
1961 if ((bsession = switch_core_session_locate(buuid)switch_core_session_perform_locate(buuid, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1961)
)) {
1962 bchannel = switch_core_session_get_channel(bsession);
1963 switch_channel_set_flag(bchannel, CF_INTERCEPT)switch_channel_set_flag_value(bchannel, CF_INTERCEPT, 1);
1964 }
1965 }
1966
1967 if (!switch_channel_test_flag(rchannel, CF_ANSWERED)) {
1968 switch_channel_answer(rchannel)switch_channel_perform_answer(rchannel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1968)
;
1969 }
1970
1971 switch_channel_mark_hold(rchannel, SWITCH_FALSE);
1972
1973 switch_channel_set_state_flag(rchannel, CF_TRANSFER);
1974 switch_channel_set_state(rchannel, CS_PARK)switch_channel_perform_set_state(rchannel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1974, CS_PARK)
;
1975
1976 if (bchannel) {
1977 switch_channel_set_state_flag(bchannel, CF_TRANSFER);
1978 switch_channel_set_state(bchannel, CS_PARK)switch_channel_perform_set_state(bchannel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1978, CS_PARK)
;
1979 }
1980
1981 switch_channel_set_flag(rchannel, CF_INTERCEPTED)switch_channel_set_flag_value(rchannel, CF_INTERCEPTED, 1);
1982 switch_ivr_uuid_bridge(switch_core_session_get_uuid(session), uuid);
1983 switch_core_session_rwunlock(rsession);
1984
1985 if (bsession) {
1986 switch_channel_hangup(bchannel, SWITCH_CAUSE_PICKED_OFF)switch_channel_perform_hangup(bchannel, "src/switch_ivr_bridge.c"
, (const char *)__func__, 1986, SWITCH_CAUSE_PICKED_OFF)
;
1987 switch_core_session_rwunlock(bsession);
1988 }
1989
1990
1991
1992}
1993
1994/* For Emacs:
1995 * Local Variables:
1996 * mode:c
1997 * indent-tabs-mode:t
1998 * tab-width:4
1999 * c-basic-offset:4
2000 * End:
2001 * For VIM:
2002 * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
2003 */