FreeSWITCH API Documentation  1.7.0
switch_ivr_bridge.c
Go to the documentation of this file.
1 /*
2  * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3  * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
4  *
5  * Version: MPL 1.1
6  *
7  * The contents of this file are subject to the Mozilla Public License Version
8  * 1.1 (the "License"); you may not use this file except in compliance with
9  * the License. You may obtain a copy of the License at
10  * http://www.mozilla.org/MPL/
11  *
12  * Software distributed under the License is distributed on an "AS IS" basis,
13  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14  * for the specific language governing rights and limitations under the
15  * License.
16  *
17  * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
18  *
19  * The Initial Developer of the Original Code is
20  * Anthony Minessale II <anthm@freeswitch.org>
21  * Portions created by the Initial Developer are Copyright (C)
22  * the Initial Developer. All Rights Reserved.
23  *
24  * Contributor(s):
25  *
26  * Anthony Minessale II <anthm@freeswitch.org>
27  *
28  * switch_ivr_bridge.c -- IVR Library
29  *
30  */
31 
32 #include <switch.h>
33 #define DEFAULT_LEAD_FRAMES 10
34 
36 static void cleanup_proxy_mode_a(switch_core_session_t *session);
37 static void cleanup_proxy_mode_b(switch_core_session_t *session);
38 
39 /* Bridge Related Stuff*/
40 /*********************************************************************************/
41 
42 #ifdef SWITCH_VIDEO_IN_THREADS
43 struct vid_helper {
44  switch_core_session_t *session_a;
45  switch_core_session_t *session_b;
46  int up;
47 };
48 
49 static void video_bridge_thread(switch_core_session_t *session, 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;
56  int set_decoded_read = 0, refresh_timer = 0, playing_file = 0;
57  switch_frame_t fr = { 0 };
58  unsigned char *buf = NULL;
59  int send_blank = 0;
60  int refresh_cnt = 300;
61  int blank_cnt = 30;
62  switch_image_t *blank_img = NULL;
63 
64  vh->up = 1;
65 
66  switch_core_session_read_lock(vh->session_a);
67  switch_core_session_read_lock(vh->session_b);
68 
71 
72  refresh_timer = refresh_cnt;
73 
74  while (switch_channel_up_nosig(channel) && switch_channel_up_nosig(b_channel) && vh->up == 1) {
75  if (switch_channel_media_up(channel)) {
79 
81  refresh_timer = refresh_cnt;
82  }
83 
85  switch_assert(a_codec);
86  switch_assert(b_codec);
87 
90  if (set_decoded_read) {
92  set_decoded_read = 0;
93  refresh_timer = refresh_cnt;
94  }
95  }
96  } else {
97  if (a_codec->implementation->impl_id != b_codec->implementation->impl_id ||
100  set_decoded_read = 1;
101  refresh_timer = refresh_cnt;
102  }
103  }
104  }
105 
106  if (refresh_timer) {
107  if (refresh_timer > 0 && (refresh_timer % 100) == 0) {
110  switch_core_media_gen_key_frame(vh->session_a);
111  switch_core_media_gen_key_frame(vh->session_b);
112  }
113  refresh_timer--;
114  }
115 
116  if (send_blank) {
117  send_blank--;
118  fr.img = blank_img;
121  switch_yield(30000);
122  continue;
123  }
124 
126  switch_status_t wstatus;
127 
128  if (!buf) {
130  buf = switch_core_session_alloc(session, buflen);
131  fr.packet = buf;
132  fr.packetlen = buflen;
133  fr.data = buf + 12;
134  fr.buflen = buflen - 12;
135  }
136 
137  wstatus = switch_core_file_read_video(fh, &fr, SVR_FLUSH | SVR_BLOCK);
138 
139 
140  if (!blank_img && fr.img) {
141  switch_rgb_color_t bgcolor = { 0 };
142  blank_img = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, fr.img->d_w, fr.img->d_h, 1);
143  switch_color_set_rgb(&bgcolor, "#000000");
144  switch_img_fill(blank_img, 0, 0, blank_img->d_w, blank_img->d_h, &bgcolor);
145  }
146 
147  if (!playing_file) {
148  playing_file = 1;
150  send_blank = blank_cnt;
151  refresh_timer = refresh_cnt;
152  switch_channel_video_sync(channel);
153  switch_channel_video_sync(b_channel);
154  continue;
155  }
156 
157  if (wstatus == SWITCH_STATUS_SUCCESS) {
159  switch_img_free(&fr.img);
160  } else if (wstatus != SWITCH_STATUS_BREAK) {
162  }
163 
164  continue;
165  }
166 
167 
168  if (playing_file) {
169  playing_file = 0;
170  send_blank = blank_cnt;
171  refresh_timer = refresh_cnt;
172  switch_channel_video_sync(channel);
173  switch_channel_video_sync(b_channel);
174  }
175 
176  status = switch_core_session_read_video_frame(vh->session_a, &read_frame, SWITCH_IO_FLAG_NONE, 0);
177 
178  if (!SWITCH_READ_ACCEPTABLE(status)) {
180  continue;
181  }
182 
183 
184  if (switch_test_flag(read_frame, SFF_CNG)) {
186  continue;
187  }
188  }
189 
191  switch_channel_video_sync(channel);
193  continue;
194  }
195 
196 
197  if (switch_channel_media_up(b_channel)) {
200  continue;
201  }
202  }
203  }
204 
205  switch_img_free(&blank_img);
206 
207  if (set_decoded_read) {
209  }
210 
212  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(vh->session_a), SWITCH_LOG_DEBUG, "%s video thread ended.\n", switch_channel_get_name(channel));
213 
216 
217  switch_core_session_rwunlock(vh->session_a);
218  switch_core_session_rwunlock(vh->session_b);
219 
220  vh->up = 0;
221  return;
222 }
223 
224 static void launch_video(struct vid_helper *vh)
225 {
226  switch_core_media_start_video_function(vh->session_a, video_bridge_thread, vh);
227 }
228 #endif
229 
230 
231 static void send_display(switch_core_session_t *session, switch_core_session_t *peer_session)
232 {
233 
235  switch_caller_profile_t *caller_profile, *peer_caller_profile;
236  switch_channel_t *caller_channel, *peer_channel;
237  const char *name, *number, *p;
238 
239  caller_channel = switch_core_session_get_channel(session);
240  peer_channel = switch_core_session_get_channel(peer_session);
241 
242  caller_profile = switch_channel_get_caller_profile(caller_channel);
243  peer_caller_profile = switch_channel_get_caller_profile(peer_channel);
244 
245  if (switch_channel_test_flag(caller_channel, CF_BRIDGE_ORIGINATOR)) {
246  if (!zstr(peer_caller_profile->caller_id_name)) {
247  name = peer_caller_profile->caller_id_name;
248  } else {
249  name = caller_profile->caller_id_name;
250  }
251 
252  if (!zstr(peer_caller_profile->caller_id_number)) {
253  number = peer_caller_profile->caller_id_number;
254  } else {
255  number = caller_profile->caller_id_number;
256  }
257 
258  if (zstr(number)) {
259  number = "UNKNOWN";
260  }
261  } else {
262  name = caller_profile->callee_id_name;
263  number = caller_profile->callee_id_number;
264 
265  if (zstr(number)) {
266  number = caller_profile->destination_number;
267  }
268  }
269 
270 
271  if (zstr(name)) {
272  name = number;
273  }
274 
275  if ((p = strrchr(number, '/'))) {
276  number = p + 1;
277  }
278  if ((p = strrchr(name, '/'))) {
279  name = p + 1;
280  }
281 
282  msg = switch_core_session_alloc(peer_session, sizeof(*msg));
283  MESSAGE_STAMP_FFL(msg);
285  msg->string_array_arg[0] = switch_core_session_strdup(peer_session, name);
286  msg->string_array_arg[1] = switch_core_session_strdup(peer_session, number);
287  msg->from = __FILE__;
288  switch_core_session_queue_message(peer_session, msg);
289 
290 }
291 
292 
294 {
295 
296  send_display(session, peer_session);
297  send_display(peer_session, session);
298 
299 }
300 
308  int done;
310 };
312 
313 static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
314 {
315  switch_ivr_bridge_data_t *data = obj;
316  int stream_id = 0, pre_b = 0, ans_a = 0, ans_b = 0, originator = 0;
318  switch_core_session_message_t msg = { 0 };
319  void *user_data;
320  switch_channel_t *chan_a, *chan_b;
321  switch_frame_t *read_frame;
322  switch_core_session_t *session_a, *session_b;
323  uint32_t read_frame_count = 0;
324  const char *app_name = NULL, *app_arg = NULL;
325  int inner_bridge = 0, exec_check = 0;
326  switch_codec_t silence_codec = { 0 };
327  switch_frame_t silence_frame = { 0 };
328  int16_t silence_data[SWITCH_RECOMMENDED_BUFFER_SIZE / 2] = { 0 };
329  const char *silence_var;
330  int silence_val = 0, bypass_media_after_bridge = 0;
331  const char *bridge_answer_timeout = NULL;
332  int bridge_filter_dtmf, answer_timeout, sent_update = 0;
333  time_t answer_limit = 0;
334  const char *exec_app = NULL;
335  const char *exec_data = NULL;
336  switch_codec_implementation_t read_impl = { 0 };
337 
338 #ifdef SWITCH_VIDEO_IN_THREADS
339  struct vid_helper vh = { 0 };
340  uint32_t vid_launch = 0;
341 #endif
342  data->clean_exit = 0;
343 
344  session_a = data->session;
345  if (!(session_b = switch_core_session_locate(data->b_uuid))) {
346  return NULL;
347  }
348 
349  switch_core_session_get_read_impl(session_a, &read_impl);
350 
351 
352  input_callback = data->input_callback;
353  user_data = data->session_data;
354  stream_id = data->stream_id;
355 
356  chan_a = switch_core_session_get_channel(session_a);
357  chan_b = switch_core_session_get_channel(session_b);
358 
359  if ((exec_app = switch_channel_get_variable(chan_a, "bridge_pre_execute_app"))) {
360  exec_data = switch_channel_get_variable(chan_a, "bridge_pre_execute_data");
361  }
362 
363  bypass_media_after_bridge = switch_channel_test_flag(chan_a, CF_BYPASS_MEDIA_AFTER_BRIDGE);
365 
366  ans_a = switch_channel_test_flag(chan_a, CF_ANSWERED);
367 
368  if ((originator = switch_channel_test_flag(chan_a, CF_BRIDGE_ORIGINATOR))) {
369  pre_b = switch_channel_test_flag(chan_a, CF_EARLY_MEDIA);
370  ans_b = switch_channel_test_flag(chan_b, CF_ANSWERED);
371  }
372 
373  inner_bridge = switch_channel_test_flag(chan_a, CF_INNER_BRIDGE);
374 
375  if (!switch_channel_test_flag(chan_a, CF_ANSWERED) && (bridge_answer_timeout = switch_channel_get_variable(chan_a, "bridge_answer_timeout"))) {
376  if ((answer_timeout = atoi(bridge_answer_timeout)) < 0) {
377  answer_timeout = 0;
378  } else {
379  answer_limit = switch_epoch_time_now(NULL) + answer_timeout;
380  }
381  }
382 
385 
387 
388  switch_channel_wait_for_flag(chan_b, CF_BRIDGED, SWITCH_TRUE, 10000, chan_a);
389 
390  if (!switch_channel_test_flag(chan_b, CF_BRIDGED)) {
392  || switch_channel_get_state(chan_b) == CS_RESET)) {
394  }
395  goto end_of_bridge_loop;
396  }
397 
398  if (bypass_media_after_bridge) {
399  const char *source_a = switch_channel_get_variable(chan_a, "source");
400  const char *source_b = switch_channel_get_variable(chan_b, "source");
401 
402  if (!source_a) source_a = "";
403  if (!source_b) source_b = "";
404 
405  if (switch_stristr("loopback", source_a) || switch_stristr("loopback", source_b)) {
406  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_WARNING, "Cannot bypass media while bridged to a loopback address.\n");
407  bypass_media_after_bridge = 0;
408  }
409  }
410 
411  if ((silence_var = switch_channel_get_variable(chan_a, "bridge_generate_comfort_noise"))) {
412 
413  if (!switch_channel_media_up(chan_a)) {
414  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_ERROR, "Channel has no media!\n");
415  goto end_of_bridge_loop;
416  }
417 
418  if (switch_true(silence_var)) {
419  silence_val = 1400;
420  } else {
421  if ((silence_val = atoi(silence_var)) < -1) {
422  silence_val = 0;
423  }
424  }
425 
426  if (silence_val) {
427  if (switch_core_codec_init(&silence_codec,
428  "L16",
429  NULL,
430  NULL,
431  read_impl.actual_samples_per_second,
432  read_impl.microseconds_per_packet / 1000,
433  1,
436 
437  silence_val = 0;
438  } else {
439  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "Setup generated silence from %s to %s at %d\n", switch_channel_get_name(chan_a),
440  switch_channel_get_name(chan_b), silence_val);
441  silence_frame.codec = &silence_codec;
442  silence_frame.data = silence_data;
443  silence_frame.buflen = sizeof(silence_data);
444  silence_frame.datalen = read_impl.decoded_bytes_per_packet;
445  silence_frame.samples = silence_frame.datalen / sizeof(int16_t);
446  }
447  }
448  }
449 
450  bridge_filter_dtmf = switch_true(switch_channel_get_variable(chan_a, "bridge_filter_dtmf"));
451 
452  for (;;) {
453  switch_channel_state_t b_state;
454  switch_status_t status;
455  switch_event_t *event;
456 
457  if (switch_channel_test_flag(chan_a, CF_TRANSFER)) {
458  data->clean_exit = 1;
459  }
460 
461  if (data->clean_exit || switch_channel_test_flag(chan_b, CF_TRANSFER)) {
464  goto end_of_bridge_loop;
465  }
466 
467  if (!switch_channel_test_flag(chan_b, CF_BRIDGED)) {
468  goto end_of_bridge_loop;
469  }
470 
471  if (!switch_channel_ready(chan_a)) {
472  if (switch_channel_up(chan_a)) {
473  data->clean_exit = 1;
474  }
475  goto end_of_bridge_loop;
476  }
477 
478  if ((b_state = switch_channel_down_nosig(chan_b))) {
479  goto end_of_bridge_loop;
480  }
481 
483  switch_core_session_message_t hmsg = { 0 };
486  hmsg.from = __FILE__;
487  hmsg.numeric_arg = 1;
488  switch_core_session_receive_message(session_a, &hmsg);
489  }
490 
491  if (read_frame_count > DEFAULT_LEAD_FRAMES && switch_channel_media_ack(chan_a) && switch_core_session_private_event_count(session_a)) {
493  msg.numeric_arg = 42;
494  msg.string_arg = data->b_uuid;
496  msg.from = __FILE__;
497  switch_core_session_receive_message(session_a, &msg);
498  switch_ivr_parse_next_event(session_a);
500  switch_core_session_receive_message(session_a, &msg);
503  }
504 
506 
507  if (!inner_bridge && (switch_channel_test_flag(chan_a, CF_SUSPEND) || switch_channel_test_flag(chan_b, CF_SUSPEND))) {
508  status = switch_core_session_read_frame(session_a, &read_frame, SWITCH_IO_FLAG_NONE, stream_id);
509 
510  if (!SWITCH_READ_ACCEPTABLE(status)) {
511  goto end_of_bridge_loop;
512  }
513  continue;
514  }
515 #ifdef SWITCH_VIDEO_IN_THREADS
516  if (switch_channel_test_flag(chan_a, CF_VIDEO) && switch_channel_test_flag(chan_b, CF_VIDEO) && !vid_launch) {
517  vid_launch++;
518  vh.session_a = session_a;
519  vh.session_b = session_b;
522  launch_video(&vh);
523  } else {
524  if (switch_channel_test_flag(chan_a, CF_VIDEO)) {
526  }
527 
528  if (switch_channel_test_flag(chan_b, CF_VIDEO)) {
530  }
531  }
532 #endif
533 
534  if (read_frame_count >= DEFAULT_LEAD_FRAMES && switch_channel_media_ack(chan_a)) {
535 
536  if (!exec_check) {
538 
539  if (!inner_bridge) {
541  }
542  exec_check = 1;
543  }
544 
545  if (exec_app) {
546  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "%s Bridge execute app %s(%s)\n",
547  switch_channel_get_name(chan_a), exec_app, exec_data);
548 
549  switch_core_session_execute_application_async(session_a, exec_app, exec_data);
550  exec_app = exec_data = NULL;
551  }
552 
553  if ((bypass_media_after_bridge || switch_channel_test_flag(chan_b, CF_BYPASS_MEDIA_AFTER_BRIDGE)) && switch_channel_test_flag(chan_a, CF_ANSWERED)
556  bypass_media_after_bridge = 0;
558  goto end_of_bridge_loop;
559  }
560  }
561 
562  /* if 1 channel has DTMF pass it to the other */
563  while (switch_channel_has_dtmf(chan_a)) {
564  switch_dtmf_t dtmf = { 0, 0 };
565  if (switch_channel_dequeue_dtmf(chan_a, &dtmf) == SWITCH_STATUS_SUCCESS) {
566  int send_dtmf = 1;
567 
568  if (input_callback) {
569  switch_status_t cb_status = input_callback(session_a, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, user_data, 0);
570 
571  if (cb_status == SWITCH_STATUS_IGNORE) {
572  send_dtmf = 0;
573  } else if (cb_status != SWITCH_STATUS_SUCCESS) {
574  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "%s ended call via DTMF\n", switch_channel_get_name(chan_a));
576  goto end_of_bridge_loop;
577  }
578  }
579 
580  if (bridge_filter_dtmf) {
581  send_dtmf = 0;
582  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "Dropping filtered DTMF received on %s\n", switch_channel_get_name(chan_a));
583  }
584 
585  if (send_dtmf) {
586  switch_core_session_send_dtmf(session_b, &dtmf);
588  }
589  }
590  }
591 
593  if (input_callback) {
594  status = input_callback(session_a, event, SWITCH_INPUT_TYPE_EVENT, user_data, 0);
595  }
596 
597  if ((event->event_id != SWITCH_EVENT_COMMAND && event->event_id != SWITCH_EVENT_MESSAGE)
598  || switch_core_session_receive_event(session_b, &event) != SWITCH_STATUS_SUCCESS) {
599  switch_event_destroy(&event);
600  }
601 
602  }
603 
604  if (!switch_channel_test_flag(chan_a, CF_ANSWERED) && answer_limit && switch_epoch_time_now(NULL) > answer_limit) {
605  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "Answer timeout hit on %s.\n", switch_channel_get_name(chan_a));
606  if (switch_true(switch_channel_get_variable_dup(chan_a, "continue_on_answer_timeout", SWITCH_FALSE, -1))) {
607  data->clean_exit = 1;
608  goto end_of_bridge_loop;
609  } else {
611  }
612  }
613 
614  if (!switch_channel_test_flag(chan_a, CF_ANSWERED)) {
615  if (originator) {
616  if (!ans_b && switch_channel_test_flag(chan_b, CF_ANSWERED)) {
617  switch_channel_pass_callee_id(chan_b, chan_a);
619  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "%s Media Establishment Failed.\n", switch_channel_get_name(chan_a));
620  goto end_of_bridge_loop;
621  }
622  ans_a = 1;
623  } else if (!pre_b && switch_channel_test_flag(chan_b, CF_EARLY_MEDIA)) {
625  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "%s Media Establishment Failed.\n", switch_channel_get_name(chan_a));
626  goto end_of_bridge_loop;
627  }
628  pre_b = 1;
629  }
630  if (!pre_b) {
631  switch_yield(10000);
632  continue;
633  }
634  } else {
635  ans_a = switch_channel_test_flag(chan_b, CF_ANSWERED);
636  }
637  }
638 
639  if (ans_a != ans_b) {
640  switch_channel_t *un = ans_a ? chan_b : chan_a;
641  switch_channel_t *a = un == chan_b ? chan_a : chan_b;
642 
644  if (switch_channel_direction(a) == SWITCH_CALL_DIRECTION_OUTBOUND || (un == chan_a && !originator)) {
646  }
647 
649  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "%s Media Establishment Failed.\n", switch_channel_get_name(un));
650  goto end_of_bridge_loop;
651  }
652 
653  if (ans_a) {
654  ans_b = 1;
655  } else {
656  ans_a = 1;
657  }
658  }
659  }
660 
661  if (originator && !ans_b) ans_b = switch_channel_test_flag(chan_b, CF_ANSWERED);
662 
663  if (originator && !sent_update && ans_a && ans_b && switch_channel_media_ack(chan_a) && switch_channel_media_ack(chan_b)) {
664  switch_ivr_bridge_display(session_a, session_b);
665  sent_update = 1;
666  }
667 #ifndef SWITCH_VIDEO_IN_THREADS
669  /* read video from 1 channel and write it to the other */
670  status = switch_core_session_read_video_frame(session_a, &read_frame, SWITCH_IO_FLAG_NONE, 0);
671 
672  if (!SWITCH_READ_ACCEPTABLE(status)) {
673  goto end_of_bridge_loop;
674  }
675 
677  }
678 #endif
679 
680  /* read audio from 1 channel and write it to the other */
681  status = switch_core_session_read_frame(session_a, &read_frame, SWITCH_IO_FLAG_NONE, stream_id);
682 
683  if (SWITCH_READ_ACCEPTABLE(status)) {
684  read_frame_count++;
685  if (switch_test_flag(read_frame, SFF_CNG)) {
686  if (silence_val) {
687  switch_generate_sln_silence((int16_t *) silence_frame.data, silence_frame.samples,
688  read_impl.number_of_channels, silence_val);
689  read_frame = &silence_frame;
690  } else if (!switch_channel_test_flag(chan_b, CF_ACCEPT_CNG)) {
691  continue;
692  }
693  }
694 
696  continue;
697  }
698 
700  if (switch_core_session_write_frame(session_b, read_frame, SWITCH_IO_FLAG_NONE, stream_id) != SWITCH_STATUS_SUCCESS) {
702  "%s ending bridge by request from write function\n", switch_channel_get_name(chan_b));
703  goto end_of_bridge_loop;
704  }
705  }
706  } else {
707  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "%s ending bridge by request from read function\n", switch_channel_get_name(chan_a));
708  goto end_of_bridge_loop;
709  }
710  }
711 
712  end_of_bridge_loop:
713 
714 #ifdef SWITCH_VIDEO_IN_THREADS
715  if (vh.up > 0) {
716  vh.up = -1;
718  //switch_channel_set_flag(chan_b, CF_NOT_READY);
721  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "Ending video thread.\n");
722  }
723 #endif
724 
725 
726  if (silence_val) {
727  switch_core_codec_destroy(&silence_codec);
728  }
729 
731 
732  if (!inner_bridge) {
734  }
735 
736  if (!inner_bridge && switch_channel_up_nosig(chan_a)) {
738  switch_caller_extension_t *extension = NULL;
739  if ((extension = switch_caller_extension_new(session_a, app_name, app_name)) == 0) {
740  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_CRIT, "memory error!\n");
741  goto end;
742  }
744 
745  switch_caller_extension_add_application(session_a, extension, (char *) app_name, app_arg);
746  switch_channel_set_caller_extension(chan_a, extension);
747 
748  if (switch_channel_get_state(chan_a) == CS_EXECUTE) {
750  } else {
752  }
753  }
754  }
755 
756  end:
757 
758 #ifdef SWITCH_VIDEO_IN_THREADS
760  if (vh.up == 1) {
761  vh.up = -1;
762  }
763 
768 
769  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "Ending video thread.\n");
773  }
774 #endif
775 
776 
777 
780  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "BRIDGE THREAD DONE [%s]\n", switch_channel_get_name(chan_a));
782 
784  if (switch_channel_ready(chan_b) &&
786  const char *ext = switch_channel_get_variable(chan_a, "hold_hangup_xfer_exten");
787 
789 
790  if (zstr(ext)) {
792  if (cause == SWITCH_CAUSE_NONE) {
794  }
795  switch_channel_hangup(chan_b, cause);
796  } else {
798  }
799  }
800 
803  }
804  }
805 
808  }
809 
812 
814  data->done = 1;
817 
818  switch_core_session_rwunlock(session_b);
819  return NULL;
820 }
821 
822 static void transfer_after_bridge(switch_core_session_t *session, const char *where)
823 {
824  int argc;
825  char *argv[4] = { 0 };
826  char *mydata;
827 
829 
830  if (!zstr(where) && (mydata = switch_core_session_strdup(session, where))) {
831  if ((argc = switch_separate_string(mydata, ':', argv, (sizeof(argv) / sizeof(argv[0])))) >= 1) {
832  switch_ivr_session_transfer(session, argv[0], argv[1], argv[2]);
833  } else {
834  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No extension specified.\n");
835  }
836  }
837 }
838 
840 {
842  switch_ivr_bridge_data_t *bd = switch_channel_get_private(channel, "_bridge_");
844  const char *var;
845 
846  if (bd) {
847  switch_channel_set_private(channel, "_bridge_", NULL);
848  if (bd->session == session && *bd->b_uuid) {
849  audio_bridge_thread(NULL, (void *) bd);
851  } else {
853  }
854  } else {
856  }
857  switch_channel_clear_state_handler(channel, &audio_bridge_peer_state_handlers);
858 
859  state = switch_channel_get_state(channel);
860 
862  !switch_channel_test_flag(channel, CF_XFER_ZOMBIE) && bd && !bd->clean_exit && state != CS_PARK && state != CS_ROUTING &&
864 
866  switch_ivr_park_session(session);
867  return SWITCH_STATUS_FALSE;
868  } else if (state < CS_HANGUP && (var = switch_channel_get_variable(channel, SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE))) {
869  transfer_after_bridge(session, var);
870  return SWITCH_STATUS_FALSE;
871  }
872 
876  return SWITCH_STATUS_FALSE;
877  } else {
878  if (switch_channel_test_flag(channel, CF_INTERCEPT)) {
880  } else {
881  if (!switch_channel_test_flag(channel, CF_ANSWERED)) {
883  } else {
885  }
886  }
887  }
888  }
889 
891  switch_channel_set_variable(channel, "park_timeout", "3");
893  }
894 
895  return SWITCH_STATUS_FALSE;
896 }
897 
899 {
901 
902  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CUSTOM ROUTING\n", switch_channel_get_name(channel));
903 
904  /* put the channel in a passive state so we can loop audio to it */
906  return SWITCH_STATUS_FALSE;
907 }
908 
910 {
912 
914 
915  /* put the channel in a passive state so we can loop audio to it */
916  return SWITCH_STATUS_FALSE;
917 }
918 
919 static const switch_state_handler_table_t audio_bridge_peer_state_handlers = {
920  /*.on_init */ NULL,
921  /*.on_routing */ audio_bridge_on_routing,
922  /*.on_execute */ NULL,
923  /*.on_hangup */ NULL,
924  /*.on_exchange_media */ audio_bridge_on_exchange_media,
925  /*.on_soft_execute */ NULL,
926  /*.on_consume_media */ audio_bridge_on_consume_media,
927 };
928 
932 
934  /*.on_init */ NULL,
935  /*.on_routing */ NULL,
936  /*.on_execute */ NULL,
937  /*.on_hangup */ NULL,
938  /*.on_exchange_media */ NULL,
939  /*.on_soft_execute */ uuid_bridge_on_soft_execute,
940  /*.on_consume_media */ uuid_bridge_on_hibernate,
941  /*.on_hibernate */ uuid_bridge_on_hibernate,
942  /*.on_reset */ uuid_bridge_on_reset
943 };
944 
946 {
948 
950 
952 
953  cleanup_proxy_mode_b(session);
954 
957  }
958 
959  return SWITCH_STATUS_SUCCESS;
960 }
961 
963 {
965  return SWITCH_STATUS_FALSE;
966 }
967 
969 {
971  switch_core_session_t *other_session = NULL;
972  const char *other_uuid = NULL;
973 
974  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CUSTOM SOFT_EXECUTE\n", switch_channel_get_name(channel));
975  switch_channel_clear_state_handler(channel, &uuid_bridge_state_handlers);
976 
978  return SWITCH_STATUS_SUCCESS;
979  }
980 
981  if ((other_uuid = switch_channel_get_variable(channel, SWITCH_UUID_BRIDGE)) && (other_session = switch_core_session_locate(other_uuid))) {
982  switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
983  switch_event_t *event;
984  int ready_a, ready_b;
985  switch_channel_state_t state, running_state;
986  int max = 1000, loops = max;
987 
989 
990  for (;;) {
991  state = switch_channel_get_state(other_channel);
992  running_state = switch_channel_get_running_state(other_channel);
993 
994  if (switch_channel_down_nosig(other_channel) || switch_channel_down(channel)) {
995  break;
996  }
997 
998  if (state < CS_HANGUP && state == running_state) {
999 
1000  if (--loops < 1) {
1003  }
1004 
1005  if (running_state == CS_RESET) {
1006  switch_channel_set_state(other_channel, CS_SOFT_EXECUTE);
1007  }
1008 
1009  if (running_state == CS_SOFT_EXECUTE) {
1010 
1012  goto done;
1013  } else {
1014  break;
1015  }
1016  }
1017 
1018  } else {
1019  loops = max;
1020  }
1021 
1022  switch_yield(20000);
1023  }
1024 
1026 
1027  if (switch_ivr_wait_for_answer(session, other_session) != SWITCH_STATUS_SUCCESS) {
1028  if (switch_true(switch_channel_get_variable(channel, "uuid_bridge_continue_on_cancel"))) {
1030  } else if (switch_true(switch_channel_get_variable(channel, "uuid_bridge_park_on_cancel"))) {
1031  switch_ivr_park_session(session);
1032  } else if (!switch_channel_test_flag(channel, CF_TRANSFER)) {
1034  }
1035  goto done;
1036  }
1037 
1038  ready_a = switch_channel_ready(channel);
1039  ready_b = switch_channel_ready(other_channel);
1040 
1041  if (!ready_a || !ready_b) {
1042  if (!ready_a) {
1044  }
1045 
1046  if (!ready_b) {
1047  const char *cid = switch_channel_get_variable(other_channel, "rdnis");
1048  if (ready_a && cid) {
1049  switch_ivr_session_transfer(session, cid, NULL, NULL);
1050  } else {
1052  }
1053  }
1054  goto done;
1055  }
1056 
1057  /* fire events that will change the data table from "show channels" */
1059  switch_channel_event_set_data(channel, event);
1060  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application", "uuid_bridge");
1061  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-Data", switch_core_session_get_uuid(other_session));
1062  switch_event_fire(&event);
1063  }
1064 
1066  switch_channel_event_set_data(other_channel, event);
1067  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application", "uuid_bridge");
1069  switch_event_fire(&event);
1070  }
1071 
1072  switch_ivr_multi_threaded_bridge(session, other_session, NULL, NULL, NULL);
1073 
1074  state = switch_channel_get_state(channel);
1075  if (!switch_channel_test_flag(channel, CF_TRANSFER) &&
1076  !switch_channel_test_flag(channel, CF_REDIRECT) && state < CS_HANGUP && state != CS_ROUTING && state != CS_PARK) {
1078  }
1079  } else {
1081  }
1082 
1083  done:
1084 
1085  if (other_session) {
1086  switch_core_session_rwunlock(other_session);
1087  other_session = NULL;
1088  }
1089 
1091 
1092  return SWITCH_STATUS_FALSE;
1093 }
1094 
1096 {
1097  switch_channel_t *channel = NULL;
1098  char *key;
1099 
1100  channel = switch_core_session_get_channel(session);
1101  switch_assert(channel != NULL);
1102 
1103  if ((key = (char *) switch_channel_get_private(channel, "__bridge_term_key")) && dtmf->digit == *key) {
1104  const char *uuid;
1105  switch_core_session_t *other_session;
1106 
1109  } else {
1110  if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE)) && (other_session = switch_core_session_locate(uuid))) {
1111  switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
1112  switch_channel_set_state(other_channel, CS_EXECUTE);
1113  switch_core_session_rwunlock(other_session);
1114  } else {
1115  return SWITCH_STATUS_SUCCESS;
1116  }
1117  }
1118 
1119  return SWITCH_STATUS_FALSE;
1120  }
1121 
1122  return SWITCH_STATUS_SUCCESS;
1123 }
1124 
1126 {
1127  switch_core_session_message_t *msg = NULL;
1128  switch_channel_t *channel = NULL;
1129  switch_event_t *event;
1130 
1131  channel = switch_core_session_get_channel(session);
1132 
1136  switch_channel_event_set_data(channel, event);
1137  switch_event_fire(&event);
1138  }
1139  }
1140 
1141 
1142  msg = switch_core_session_alloc(session, sizeof(*msg));
1143  MESSAGE_STAMP_FFL(msg);
1145  msg->from = __FILE__;
1147  switch_core_session_queue_message(session, msg);
1148 
1149  switch_core_event_hook_remove_state_change(session, hanguphook);
1150 
1151  return SWITCH_STATUS_SUCCESS;
1152 
1153 }
1154 
1156 {
1157  switch_channel_t *channel = NULL;
1158  const char *key;
1159  switch_core_session_message_t msg = { 0 };
1160  switch_event_t *event = NULL;
1161  switch_ivr_dmachine_t *dmachine[2] = { 0 };
1162 
1163  channel = switch_core_session_get_channel(session);
1164  switch_assert(channel != NULL);
1165 
1167  msg.from = __FILE__;
1169 
1170  switch_core_event_hook_add_state_change(session, hanguphook);
1171 
1172  switch_core_session_receive_message(session, &msg);
1173 
1174  if ((key = switch_channel_get_variable(channel, "bridge_terminate_key"))) {
1175  switch_channel_set_private(channel, "__bridge_term_key", switch_core_session_strdup(session, key));
1176  switch_core_event_hook_add_recv_dtmf(session, sb_on_dtmf);
1177  }
1178 
1181 
1183 
1184 
1187  switch_core_session_t *other_session;
1188 
1190  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", msg.string_arg);
1191  switch_channel_event_set_data(channel, event);
1192  if ((other_session = switch_core_session_locate(msg.string_arg))) {
1193  switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
1194 
1195  switch_channel_set_bridge_time(other_channel);
1196 
1197  switch_event_add_presence_data_cols(other_channel, event, "Bridge-B-PD-");
1198  switch_core_session_rwunlock(other_session);
1199  }
1200  switch_event_fire(&event);
1201  }
1202  }
1203 
1204  if ((dmachine[0] = switch_core_session_get_dmachine(session, DIGIT_TARGET_SELF)) ||
1205  (dmachine[1] = switch_core_session_get_dmachine(session, DIGIT_TARGET_PEER))) {
1207  "%s not hibernating due to active digit parser, semi-hibernation engaged.\n", switch_channel_get_name(channel));
1208 
1209  while(switch_channel_ready(channel) && switch_channel_get_state(channel) == CS_HIBERNATE) {
1210  if (!switch_channel_test_flag(channel, CF_BROADCAST)) {
1211  if (dmachine[0]) {
1212  switch_ivr_dmachine_ping(dmachine[0], NULL);
1213  }
1214  if (dmachine[1]) {
1215  switch_ivr_dmachine_ping(dmachine[1], NULL);
1216  }
1217  }
1218  switch_yield(20000);
1220  }
1221  }
1222 
1223 
1224  return SWITCH_STATUS_SUCCESS;
1225 }
1226 
1228 {
1229  const char *uuid;
1231  switch_core_session_t *other_session;
1232  switch_event_t *event;
1233 
1236  }
1237 
1238  if (switch_channel_get_private(channel, "__bridge_term_key")) {
1239  switch_core_event_hook_remove_recv_dtmf(session, sb_on_dtmf);
1240  switch_channel_set_private(channel, "__bridge_term_key", NULL);
1241  }
1242 
1244 
1245  if (uuid && (other_session = switch_core_session_locate(uuid))) {
1246  switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
1247  const char *sbv = switch_channel_get_variable(other_channel, SWITCH_SIGNAL_BRIDGE_VARIABLE);
1248  const char *var;
1249 
1250  if (!zstr(sbv) && !strcmp(sbv, switch_core_session_get_uuid(session))) {
1251  int hup = 1;
1252 
1255  switch_channel_set_variable(other_channel, "call_uuid", switch_core_session_get_uuid(other_session));
1256 
1257  if (switch_channel_up_nosig(other_channel)) {
1259  switch_ivr_park_session(other_session);
1260  hup = 0;
1261  } else if ((var = switch_channel_get_variable(other_channel, SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE))) {
1262  transfer_after_bridge(other_session, var);
1263  hup = 0;
1264  }
1265 
1266  if (hup) {
1267  if (switch_channel_test_flag(other_channel, CF_BRIDGE_ORIGINATOR)) {
1268  if (switch_channel_test_flag(channel, CF_ANSWERED) &&
1270 
1271  if (switch_channel_test_flag(channel, CF_INTERCEPTED)) {
1272  switch_channel_set_flag(other_channel, CF_INTERCEPT);
1273  }
1274  switch_channel_hangup(other_channel, switch_channel_get_cause(channel));
1275  } else {
1276  if (!switch_channel_test_flag(channel, CF_ANSWERED)) {
1277  switch_channel_handle_cause(other_channel, switch_channel_get_cause(channel));
1278  }
1279  switch_channel_set_state(other_channel, CS_EXECUTE);
1280  }
1281  } else {
1282  switch_channel_hangup(other_channel, switch_channel_get_cause(channel));
1283  }
1284  }
1285  }
1286  }
1287 
1292  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", uuid);
1293  switch_event_add_presence_data_cols(other_channel, event, "Bridge-B-PD-");
1294  switch_channel_event_set_data(channel, event);
1295  switch_event_fire(&event);
1296  }
1297  }
1298 
1299  switch_core_session_rwunlock(other_session);
1300  } else {
1305  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", uuid);
1306  switch_channel_event_set_data(channel, event);
1307  switch_event_fire(&event);
1308  }
1309  }
1310  }
1311 
1312  return SWITCH_STATUS_SUCCESS;
1313 }
1314 
1316  /*.on_init */ NULL,
1317  /*.on_routing */ NULL,
1318  /*.on_execute */ NULL,
1319  /*.on_hangup */ signal_bridge_on_hangup,
1320  /*.on_exchange_media */ NULL,
1321  /*.on_soft_execute */ NULL,
1322  /*.on_consume_media */ NULL,
1323  /*.on_hibernate */ signal_bridge_on_hibernate
1324 };
1325 
1326 static void check_bridge_export(switch_channel_t *channel, switch_channel_t *peer_channel)
1327 {
1328  switch_caller_profile_t *originator_cp, *originatee_cp;
1329 
1330  originator_cp = switch_channel_get_caller_profile(channel);
1331  originatee_cp = switch_channel_get_caller_profile(peer_channel);
1332 
1333  originator_cp->callee_id_name = switch_core_strdup(originator_cp->pool, originatee_cp->callee_id_name);
1334  originator_cp->callee_id_number = switch_core_strdup(originator_cp->pool, originatee_cp->callee_id_number);
1335 
1336 
1339 }
1340 
1342 {
1343  switch_channel_t *caller_channel = switch_core_session_get_channel(session);
1344  switch_channel_t *peer_channel = switch_core_session_get_channel(peer_session);
1345  switch_event_t *event;
1346 
1347  if (switch_channel_down_nosig(peer_channel)) {
1348  switch_channel_hangup(caller_channel, switch_channel_get_cause(peer_channel));
1349  return SWITCH_STATUS_FALSE;
1350  }
1351 
1352  if (!switch_channel_up_nosig(caller_channel)) {
1354  return SWITCH_STATUS_FALSE;
1355  }
1356 
1357  check_bridge_export(caller_channel, peer_channel);
1358 
1361 
1364  switch_channel_set_variable(peer_channel, "call_uuid", switch_core_session_get_uuid(session));
1365 
1368 
1369  switch_channel_clear_state_handler(caller_channel, NULL);
1370  switch_channel_clear_state_handler(peer_channel, NULL);
1371 
1372  switch_channel_add_state_handler(caller_channel, &signal_bridge_state_handlers);
1373  switch_channel_add_state_handler(peer_channel, &signal_bridge_state_handlers);
1374 
1375  switch_channel_set_variable(caller_channel, "signal_bridge", "true");
1376  switch_channel_set_variable(peer_channel, "signal_bridge", "true");
1377 
1378  /* fire events that will change the data table from "show channels" */
1380  switch_channel_event_set_data(caller_channel, event);
1381  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application", "signal_bridge");
1382  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-Data", switch_core_session_get_uuid(peer_session));
1383  switch_event_fire(&event);
1384  }
1385 
1387  switch_channel_event_set_data(peer_channel, event);
1388  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application", "signal_bridge");
1390  switch_event_fire(&event);
1391  }
1392 
1393  switch_channel_set_state_flag(caller_channel, CF_RESET);
1394  switch_channel_set_state_flag(peer_channel, CF_RESET);
1395 
1396  switch_channel_set_state(caller_channel, CS_HIBERNATE);
1397  switch_channel_set_state(peer_channel, CS_HIBERNATE);
1398 
1399 #if 0
1400  if (switch_channel_test_flag(caller_channel, CF_BRIDGED)) {
1401  switch_channel_set_flag(caller_channel, CF_TRANSFER);
1402  switch_channel_set_flag(peer_channel, CF_TRANSFER);
1403  }
1404 #endif
1405 
1406  switch_ivr_bridge_display(session, peer_session);
1407 
1408  return SWITCH_STATUS_SUCCESS;
1409 }
1410 
1411 static void abort_call(switch_channel_t *caller_channel, switch_channel_t *peer_channel)
1412 {
1413  switch_call_cause_t cause = switch_channel_get_cause(caller_channel);
1414 
1415  if (!cause) {
1417  }
1418 
1419  switch_channel_hangup(peer_channel, cause);
1420 }
1421 
1423  switch_core_session_t *peer_session,
1424  switch_input_callback_function_t input_callback, void *session_data,
1425  void *peer_session_data)
1426 {
1427  switch_ivr_bridge_data_t *a_leg = switch_core_session_alloc(session, sizeof(*a_leg));
1428  switch_ivr_bridge_data_t *b_leg = switch_core_session_alloc(peer_session, sizeof(*b_leg));
1429  switch_channel_t *caller_channel = switch_core_session_get_channel(session);
1430  switch_channel_t *peer_channel = switch_core_session_get_channel(peer_session);
1431  int stream_id = 0;
1434  switch_event_t *event;
1435  int br = 0;
1436  int inner_bridge = switch_channel_test_flag(caller_channel, CF_INNER_BRIDGE);
1437  const char *var;
1438  switch_call_cause_t cause;
1439  switch_core_session_message_t msg = { 0 };
1440 
1441  if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE)) {
1442  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Call has no media... Redirecting to signal bridge.\n");
1443  return switch_ivr_signal_bridge(session, peer_session);
1444  }
1445 
1446  check_bridge_export(caller_channel, peer_channel);
1447 
1450 
1453 
1454  switch_channel_audio_sync(caller_channel);
1455  switch_channel_audio_sync(peer_channel);
1456 
1457  b_leg->session = peer_session;
1458  switch_copy_string(b_leg->b_uuid, switch_core_session_get_uuid(session), sizeof(b_leg->b_uuid));
1459  b_leg->stream_id = stream_id;
1460  b_leg->input_callback = input_callback;
1461  b_leg->session_data = peer_session_data;
1462  b_leg->clean_exit = 0;
1463  b_leg->other_leg_data = a_leg;
1464 
1465  a_leg->session = session;
1466  switch_copy_string(a_leg->b_uuid, switch_core_session_get_uuid(peer_session), sizeof(a_leg->b_uuid));
1467  a_leg->stream_id = stream_id;
1468  a_leg->input_callback = input_callback;
1469  a_leg->session_data = session_data;
1470  a_leg->clean_exit = 0;
1471  a_leg->other_leg_data = b_leg;
1472 
1473  switch_channel_add_state_handler(peer_channel, &audio_bridge_peer_state_handlers);
1474 
1475  if (switch_channel_test_flag(peer_channel, CF_ANSWERED) && !switch_channel_test_flag(caller_channel, CF_ANSWERED)) {
1476  switch_channel_pass_callee_id(peer_channel, caller_channel);
1477  switch_channel_answer(caller_channel);
1478  }
1479 
1480  if (switch_channel_test_flag(peer_channel, CF_ANSWERED) || switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA) ||
1481  switch_channel_test_flag(peer_channel, CF_RING_READY)) {
1482  const char *app, *data;
1483 
1484  if (!switch_channel_ready(caller_channel)) {
1485  abort_call(caller_channel, peer_channel);
1486  goto done;
1487  }
1488 
1490 
1491  switch_channel_set_variable(peer_channel, "call_uuid", switch_core_session_get_uuid(session));
1492 
1493  switch_channel_set_bridge_time(caller_channel);
1494  switch_channel_set_bridge_time(peer_channel);
1495 
1498  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", switch_core_session_get_uuid(peer_session));
1499  switch_channel_event_set_data(caller_channel, event);
1500  switch_event_add_presence_data_cols(peer_channel, event, "Bridge-B-PD-");
1501  switch_event_fire(&event);
1502  br = 1;
1503  }
1504 
1510 
1511  if (!switch_channel_ready(caller_channel)) {
1512  abort_call(caller_channel, peer_channel);
1513  switch_core_session_rwunlock(peer_session);
1514  goto done;
1515  }
1516 
1517  if (!switch_channel_media_ready(caller_channel) ||
1518  (!switch_channel_test_flag(peer_channel, CF_ANSWERED) && !switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA))) {
1519  if ((status = switch_ivr_wait_for_answer(session, peer_session)) != SWITCH_STATUS_SUCCESS || !switch_channel_ready(caller_channel)) {
1520  switch_channel_state_t w_state = switch_channel_get_state(caller_channel);
1522  if (w_state < CS_HANGUP && w_state != CS_ROUTING && w_state != CS_PARK &&
1523  !switch_channel_test_flag(caller_channel, CF_REDIRECT) && !switch_channel_test_flag(caller_channel, CF_TRANSFER) &&
1524  w_state != CS_EXECUTE) {
1525  const char *ext = switch_channel_get_variable(peer_channel, "original_destination_number");
1526  if (!ext) {
1527  ext = switch_channel_get_variable(peer_channel, "destination_number");
1528  }
1529 
1530  if (ext) {
1531  switch_ivr_session_transfer(session, ext, NULL, NULL);
1532  } else {
1534  }
1535  }
1536  abort_call(caller_channel, peer_channel);
1537  switch_core_session_rwunlock(peer_session);
1538  goto done;
1539  }
1540  }
1541 
1542  if (switch_channel_test_flag(peer_channel, CF_ANSWERED) && !switch_channel_test_flag(caller_channel, CF_ANSWERED)) {
1543  switch_channel_answer(caller_channel);
1544  }
1545 
1546  switch_channel_wait_for_flag(peer_channel, CF_BROADCAST, SWITCH_FALSE, 10000, caller_channel);
1547  switch_ivr_parse_all_events(peer_session);
1548  switch_ivr_parse_all_events(session);
1549 
1551  msg.from = __FILE__;
1553 
1554  if (switch_core_session_receive_message(peer_session, &msg) != SWITCH_STATUS_SUCCESS) {
1555  status = SWITCH_STATUS_FALSE;
1556  abort_call(caller_channel, peer_channel);
1557  switch_core_session_rwunlock(peer_session);
1558  goto done;
1559  }
1560 
1563  status = SWITCH_STATUS_FALSE;
1564  abort_call(caller_channel, peer_channel);
1565  switch_core_session_rwunlock(peer_session);
1566  goto done;
1567  }
1568 
1575 
1576  if ((app = switch_channel_get_variable(caller_channel, "bridge_pre_execute_aleg_app"))) {
1577  switch_channel_set_variable(caller_channel, "bridge_pre_execute_app", app);
1578 
1579  if ((data = switch_channel_get_variable(caller_channel, "bridge_pre_execute_aleg_data"))) {
1580  switch_channel_set_variable(caller_channel, "bridge_pre_execute_data", data);
1581  }
1582  }
1583 
1584  if ((app = switch_channel_get_variable(caller_channel, "bridge_pre_execute_bleg_app"))) {
1585  switch_channel_set_variable(peer_channel, "bridge_pre_execute_app", app);
1586 
1587  if ((data = switch_channel_get_variable(caller_channel, "bridge_pre_execute_bleg_data"))) {
1588  switch_channel_set_variable(peer_channel, "bridge_pre_execute_data", data);
1589  }
1590 
1591  }
1592 
1593  switch_channel_set_private(peer_channel, "_bridge_", b_leg);
1595 
1596  audio_bridge_thread(NULL, (void *) a_leg);
1597 
1599 
1600  switch_channel_stop_broadcast(peer_channel);
1601 
1602 
1603  while (switch_channel_get_state(peer_channel) == CS_EXCHANGE_MEDIA) {
1605  switch_cond_next();
1606  }
1607 
1608  if (inner_bridge) {
1609  if (switch_channel_ready(caller_channel)) {
1610  switch_channel_set_flag(caller_channel, CF_BRIDGED);
1611  }
1612 
1613  if (switch_channel_ready(peer_channel)) {
1614  switch_channel_set_flag(peer_channel, CF_BRIDGED);
1615  }
1616  }
1617 
1618  if ((cause = switch_channel_get_cause(caller_channel))) {
1620  }
1621 
1622  if ((cause = switch_channel_get_cause(peer_channel))) {
1624  }
1625 
1626  if (switch_channel_down_nosig(peer_channel)) {
1629 
1630  if (copy_xml_cdr || copy_json_cdr) {
1631  char *cdr_text = NULL;
1632 
1633  switch_channel_wait_for_state(peer_channel, caller_channel, CS_DESTROY);
1634 
1635  if (copy_xml_cdr) {
1636  switch_xml_t cdr = NULL;
1637 
1638  if (switch_ivr_generate_xml_cdr(peer_session, &cdr) == SWITCH_STATUS_SUCCESS) {
1639  cdr_text = switch_xml_toxml(cdr, SWITCH_FALSE);
1640  switch_xml_free(cdr);
1641  }
1642  }
1643  if (copy_json_cdr) {
1644  cJSON *cdr = NULL;
1645 
1646  if (switch_ivr_generate_json_cdr(peer_session, &cdr, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) {
1647  cdr_text = cJSON_PrintUnformatted(cdr);
1648  cJSON_Delete(cdr);
1649  }
1650  }
1651 
1652  if (cdr_text) {
1653  switch_channel_set_variable(caller_channel, "b_leg_cdr", cdr_text);
1654  switch_channel_set_variable_name_printf(caller_channel, cdr_text, "b_leg_cdr_%s", switch_core_session_get_uuid(peer_session));
1655  switch_safe_free(cdr_text);
1656  }
1657  }
1658 
1659  }
1660 
1661  switch_core_session_rwunlock(peer_session);
1662 
1663  } else {
1664  status = SWITCH_STATUS_FALSE;
1665  }
1666  } else {
1667  status = SWITCH_STATUS_FALSE;
1668  }
1669 
1670  if (status != SWITCH_STATUS_SUCCESS) {
1671  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Bridge Failed %s->%s\n",
1672  switch_channel_get_name(caller_channel), switch_channel_get_name(peer_channel)
1673  );
1675  }
1676 
1677  done:
1678 
1679  switch_channel_set_variable(peer_channel, "call_uuid", switch_core_session_get_uuid(peer_session));
1680 
1683  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", switch_core_session_get_uuid(peer_session));
1684  switch_channel_event_set_data(caller_channel, event);
1685  switch_event_add_presence_data_cols(peer_channel, event, "Bridge-B-PD-");
1686  switch_event_fire(&event);
1687  }
1688 
1690  msg.from = __FILE__;
1692  switch_core_session_receive_message(peer_session, &msg);
1693 
1695  switch_core_session_receive_message(session, &msg);
1696 
1697  state = switch_channel_get_state(caller_channel);
1698 
1699  if (!switch_channel_test_flag(caller_channel, CF_TRANSFER) && !switch_channel_test_flag(caller_channel, CF_REDIRECT) &&
1700  !switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE) && !a_leg->clean_exit && !inner_bridge) {
1701  switch_call_cause_t cause = switch_channel_get_cause(peer_channel);
1702  const char *hup = switch_channel_get_variable(caller_channel, SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE);
1703  int explicit = 0;
1704  int answered = 0;
1705  int early = 0;
1706 
1707  if (cause == SWITCH_CAUSE_NONE) {
1709  }
1710 
1711  if (hup) {
1712  explicit = !strcasecmp(hup, "explicit");
1713  }
1714 
1715  if (cause && !switch_channel_test_flag(peer_channel, CF_ANSWERED)) {
1716  switch_channel_handle_cause(caller_channel, cause);
1717  }
1718 
1719  if (explicit) {
1720  if (switch_channel_test_flag(peer_channel, CF_INTERCEPTED)) {
1721  switch_channel_set_flag(peer_channel, CF_INTERCEPT);
1722  }
1723  switch_channel_hangup(caller_channel, cause);
1724  }
1725 
1726  answered = switch_channel_test_flag(peer_channel, CF_ANSWERED);
1727  early = switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA);
1728 
1729  if ((state != CS_EXECUTE && state != CS_SOFT_EXECUTE && state != CS_PARK && state != CS_ROUTING) || ((answered || early) && state < CS_HANGUP)) {
1730 
1731  if (!switch_channel_test_flag(caller_channel, CF_TRANSFER)) {
1732 
1733  if ((answered && switch_true(switch_channel_get_variable(caller_channel, SWITCH_PARK_AFTER_BRIDGE_VARIABLE))) ||
1735  switch_ivr_park_session(session);
1736  } else if ((answered && (var = switch_channel_get_variable(caller_channel, SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE))) ||
1738  transfer_after_bridge(session, var);
1739  } else if (answered) {
1740  if (switch_true(hup)) {
1741  if (switch_channel_test_flag(peer_channel, CF_INTERCEPTED)) {
1742  switch_channel_set_flag(peer_channel, CF_INTERCEPT);
1743  }
1744  switch_channel_hangup(caller_channel, cause);
1745  }
1746  }
1747  }
1748  }
1749  }
1750 
1751  if (switch_channel_test_flag(caller_channel, CF_REDIRECT)) {
1752  if (switch_channel_test_flag(caller_channel, CF_RESET)) {
1753  switch_channel_clear_flag(caller_channel, CF_RESET);
1754  } else {
1755  state = switch_channel_get_state(caller_channel);
1756  if (!(state == CS_RESET || state == CS_PARK || state == CS_ROUTING)) {
1757  switch_channel_set_state(caller_channel, CS_RESET);
1758  }
1759  }
1760  }
1761 
1762  return status;
1763 }
1764 
1766 {
1768 
1769  if (switch_channel_test_flag(channel, CF_PROXY_MODE) &&
1772  }
1773 }
1774 
1775 
1777 {
1778  switch_core_session_t *sbsession;
1780  int done = 0;
1781 
1784  if (switch_core_session_get_partner(session, &sbsession) == SWITCH_STATUS_SUCCESS) {
1785  switch_channel_t *sbchannel = switch_core_session_get_channel(sbsession);
1786 
1787  if (switch_channel_test_flag(sbchannel, CF_PROXY_MODE)) {
1788  /* Clear this now, otherwise will cause the one we're interested in to hang up too...*/
1791  } else {
1792  done = 1;
1793  }
1794  switch_core_session_rwunlock(sbsession);
1795  }
1796  }
1797 
1798  if (done) return;
1799 
1803 
1804 }
1805 
1806 
1807 SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uuid, const char *originatee_uuid)
1808 {
1809  switch_core_session_t *originator_session, *originatee_session, *swap_session;
1810  switch_channel_t *originator_channel, *originatee_channel, *swap_channel;
1812  switch_caller_profile_t *originator_cp, *originatee_cp;
1814 
1815  if ((originator_session = switch_core_session_locate(originator_uuid))) {
1816  if ((originatee_session = switch_core_session_locate(originatee_uuid))) {
1817  originator_channel = switch_core_session_get_channel(originator_session);
1818  originatee_channel = switch_core_session_get_channel(originatee_session);
1819 
1820 
1821  if (switch_channel_test_flag(originator_channel, CF_LEG_HOLDING)) {
1822  switch_channel_set_flag(originator_channel, CF_HOLD_ON_BRIDGE);
1823  }
1824 
1825  if (switch_channel_test_flag(originatee_channel, CF_LEG_HOLDING)) {
1826  switch_channel_set_flag(originatee_channel, CF_HOLD_ON_BRIDGE);
1827  }
1828 
1829 
1830  if (switch_channel_direction(originator_channel) == SWITCH_CALL_DIRECTION_OUTBOUND && !switch_channel_test_flag(originator_channel, CF_DIALPLAN)) {
1831  if (!switch_channel_test_flag(originator_channel, CF_RECOVERING_BRIDGE)) {
1832  switch_channel_flip_cid(originator_channel);
1833  }
1834  switch_channel_set_flag(originator_channel, CF_DIALPLAN);
1835  }
1836 
1837  if (switch_channel_down_nosig(originator_channel)) {
1838  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originator_session), SWITCH_LOG_DEBUG, "%s is hungup refusing to bridge.\n", switch_channel_get_name(originatee_channel));
1839  switch_core_session_rwunlock(originator_session);
1840  switch_core_session_rwunlock(originatee_session);
1841  return SWITCH_STATUS_FALSE;
1842  }
1843 
1844  if (!switch_channel_media_up(originator_channel)) {
1845  if (switch_channel_media_up(originatee_channel)) {
1846  swap_session = originator_session;
1847  originator_session = originatee_session;
1848  originatee_session = swap_session;
1849 
1850  swap_channel = originator_channel;
1851  originator_channel = originatee_channel;
1852  originatee_channel = swap_channel;
1853  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originatee_session), SWITCH_LOG_WARNING, "reversing order of channels so this will work!\n");
1854  } else {
1855  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originator_session), SWITCH_LOG_CRIT, "Neither channel is answered, cannot bridge them.\n");
1856  switch_core_session_rwunlock(originator_session);
1857  switch_core_session_rwunlock(originatee_session);
1858  return SWITCH_STATUS_FALSE;
1859  }
1860  }
1861 
1862  if (switch_channel_direction(originatee_channel) == SWITCH_CALL_DIRECTION_OUTBOUND && switch_channel_test_flag(originatee_channel, CF_DIALPLAN)) {
1863  switch_channel_clear_flag(originatee_channel, CF_DIALPLAN);
1864  }
1865 
1866  cleanup_proxy_mode_a(originator_session);
1867  cleanup_proxy_mode_a(originatee_session);
1868 
1869  /* override transmit state for originator_channel to bridge to originatee_channel
1870  * install pointer to originatee_session into originator_channel
1871  * set CF_TRANSFER on both channels and change state to CS_SOFT_EXECUTE to
1872  * interrupt anything they are already doing.
1873  * originatee_session will fall asleep and originator_session will bridge to it
1874  */
1875 
1876  switch_channel_set_flag(originator_channel, CF_REDIRECT);
1877  switch_channel_set_flag(originatee_channel, CF_REDIRECT);
1878 
1879 
1880  switch_channel_set_variable(originator_channel, SWITCH_UUID_BRIDGE, switch_core_session_get_uuid(originatee_session));
1887 
1888 
1889  originator_cp = switch_channel_get_caller_profile(originator_channel);
1890  originatee_cp = switch_channel_get_caller_profile(originatee_channel);
1891 
1892 
1893 
1894  if (switch_channel_outbound_display(originator_channel)) {
1895  switch_channel_invert_cid(originator_channel);
1896 
1897  if (switch_channel_direction(originator_channel) == SWITCH_CALL_DIRECTION_INBOUND) {
1898  switch_channel_clear_flag(originatee_channel, CF_BLEG);
1899  }
1900  }
1901 
1902  if (switch_channel_inbound_display(originatee_channel)) {
1903  switch_channel_invert_cid(originatee_channel);
1904 
1905  if (switch_channel_direction(originatee_channel) == SWITCH_CALL_DIRECTION_INBOUND) {
1906  switch_channel_set_flag(originatee_channel, CF_BLEG);
1907  }
1908 
1909  }
1910 
1911 
1912  switch_channel_set_variable(originatee_channel, "original_destination_number", originatee_cp->destination_number);
1913  switch_channel_set_variable(originatee_channel, "original_caller_id_name", originatee_cp->caller_id_name);
1914  switch_channel_set_variable(originatee_channel, "original_caller_id_number", originatee_cp->caller_id_number);
1915 
1916  switch_channel_set_variable(originator_channel, "original_destination_number", originator_cp->destination_number);
1917  switch_channel_set_variable(originator_channel, "original_caller_id_name", originator_cp->caller_id_name);
1918  switch_channel_set_variable(originator_channel, "original_caller_id_number", originator_cp->caller_id_number);
1919 
1920  switch_channel_step_caller_profile(originatee_channel);
1921  switch_channel_step_caller_profile(originator_channel);
1922 
1923  originator_cp = switch_channel_get_caller_profile(originator_channel);
1924  originatee_cp = switch_channel_get_caller_profile(originatee_channel);
1925 
1926 
1927 #ifdef DEEP_DEBUG_CID
1928  {
1929  switch_event_t *event;
1930 
1932  //switch_channel_event_set_basic_data(originator_channel, event);
1933  switch_caller_profile_event_set_data(originator_cp, "ORIGINATOR", event);
1934  switch_caller_profile_event_set_data(originatee_cp, "ORIGINATEE", event);
1935  DUMP_EVENT(event);
1936  switch_event_destroy(&event);
1937  }
1938  }
1939 #endif
1940 
1941  switch_channel_set_originator_caller_profile(originatee_channel, switch_caller_profile_clone(originatee_session, originator_cp));
1942  switch_channel_set_originatee_caller_profile(originator_channel, switch_caller_profile_clone(originator_session, originatee_cp));
1943 
1944  originator_cp->callee_id_name = switch_core_strdup(originator_cp->pool, originatee_cp->callee_id_name);
1945  originator_cp->callee_id_number = switch_core_strdup(originator_cp->pool, originatee_cp->callee_id_number);
1946 
1947  originatee_cp->caller_id_name = switch_core_strdup(originatee_cp->pool, originator_cp->caller_id_name);
1948  originatee_cp->caller_id_number = switch_core_strdup(originatee_cp->pool, originator_cp->caller_id_number);
1949 
1950 #ifdef DEEP_DEBUG_CID
1951  {
1952  switch_event_t *event;
1953 
1955  //switch_channel_event_set_basic_data(originator_channel, event);
1956  switch_caller_profile_event_set_data(originator_cp, "POST-ORIGINATOR", event);
1957  switch_caller_profile_event_set_data(originatee_cp, "POST-ORIGINATEE", event);
1958  DUMP_EVENT(event);
1959  switch_event_destroy(&event);
1960  }
1961  }
1962 #endif
1963 
1964  switch_channel_stop_broadcast(originator_channel);
1965  switch_channel_stop_broadcast(originatee_channel);
1966 
1967  switch_channel_set_flag(originator_channel, CF_TRANSFER);
1968  switch_channel_set_flag(originatee_channel, CF_TRANSFER);
1969 
1970 
1971  switch_channel_clear_flag(originator_channel, CF_ORIGINATING);
1972  switch_channel_clear_flag(originatee_channel, CF_ORIGINATING);
1973 
1974 
1975  originator_cp->transfer_source = switch_core_sprintf(originator_cp->pool,
1976  "%ld:%s:uuid_br:%s", (long)switch_epoch_time_now(NULL), originator_cp->uuid_str,
1977  switch_core_session_get_uuid(originatee_session));
1981 
1982 
1983  originatee_cp->transfer_source = switch_core_sprintf(originatee_cp->pool,
1984  "%ld:%s:uuid_br:%s", (long)switch_epoch_time_now(NULL), originatee_cp->uuid_str,
1985  switch_core_session_get_uuid(originator_session));
1989 
1990  /* change the states and let the chips fall where they may */
1991 
1992  //switch_channel_set_variable(originator_channel, SWITCH_PARK_AFTER_BRIDGE_VARIABLE, NULL);
1993  //switch_channel_set_variable(originatee_channel, SWITCH_PARK_AFTER_BRIDGE_VARIABLE, NULL);
1994  switch_channel_clear_state_handler(originator_channel, NULL);
1995  switch_channel_clear_state_handler(originatee_channel, NULL);
1996 
1997 
1998 
2001 
2005 
2006  switch_channel_add_state_handler(originator_channel, &uuid_bridge_state_handlers);
2007  switch_channel_add_state_handler(originatee_channel, &uuid_bridge_state_handlers);
2008 
2009  state = switch_channel_get_state(originator_channel);
2010  switch_channel_set_state(originator_channel, state == CS_HIBERNATE ? CS_CONSUME_MEDIA : CS_HIBERNATE);
2011  state = switch_channel_get_state(originatee_channel);
2012  switch_channel_set_state(originatee_channel, state == CS_HIBERNATE ? CS_CONSUME_MEDIA : CS_HIBERNATE);
2013 
2014  status = SWITCH_STATUS_SUCCESS;
2015 
2016  //switch_ivr_bridge_display(originator_session, originatee_session);
2017 
2018  /* release the read locks we have on the channels */
2019  switch_core_session_rwunlock(originator_session);
2020  switch_core_session_rwunlock(originatee_session);
2021 
2022  } else {
2023  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originator_session), SWITCH_LOG_DEBUG, "originatee uuid %s is not present\n", originatee_uuid);
2024  switch_core_session_rwunlock(originator_session);
2025  }
2026  } else {
2027  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originator_session), SWITCH_LOG_DEBUG, "originator uuid %s is not present\n", originator_uuid);
2028  }
2029 
2030  return status;
2031 }
2032 
2034 {
2035  switch_core_session_t *rsession;
2037 
2038  switch_assert(uuid);
2039 
2040  if ((rsession = switch_core_session_locate(uuid))) {
2041  switch_channel_t *rchannel = switch_core_session_get_channel(rsession);
2042  const char *brto;
2043 
2045  (brto = switch_channel_get_partner_uuid(rchannel))) {
2046  switch_copy_string(b_uuid, brto, blen);
2047  status = SWITCH_STATUS_SUCCESS;
2048  }
2049  switch_core_session_rwunlock(rsession);
2050  }
2051 
2052  return status;
2053 
2054 }
2055 
2057 {
2058  switch_core_session_t *rsession, *bsession = NULL;
2059  switch_channel_t *channel, *rchannel, *bchannel = NULL;
2060  const char *buuid, *var;
2061  char brto[SWITCH_UUID_FORMATTED_LENGTH + 1] = "";
2062 
2063  if (bleg) {
2064  if (switch_ivr_find_bridged_uuid(uuid, brto, sizeof(brto)) == SWITCH_STATUS_SUCCESS) {
2065  uuid = switch_core_session_strdup(session, brto);
2066  } else {
2067  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "no uuid bridged to %s\n", uuid);
2068  return;
2069  }
2070  }
2071 
2072  if (zstr(uuid) || !(rsession = switch_core_session_locate(uuid))) {
2073  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "no uuid %s\n", uuid);
2074  return;
2075  }
2076 
2077  channel = switch_core_session_get_channel(session);
2078  rchannel = switch_core_session_get_channel(rsession);
2079  buuid = switch_channel_get_partner_uuid(rchannel);
2080 
2081  if ((var = switch_channel_get_variable(channel, "intercept_unbridged_only")) && switch_true(var)) {
2082  if ((switch_channel_test_flag(rchannel, CF_BRIDGED))) {
2083  switch_core_session_rwunlock(rsession);
2084  return;
2085  }
2086  }
2087 
2088  if ((var = switch_channel_get_variable(channel, "intercept_unanswered_only")) && switch_true(var)) {
2089  if ((switch_channel_test_flag(rchannel, CF_ANSWERED))) {
2090  switch_core_session_rwunlock(rsession);
2091  return;
2092  }
2093  }
2094 
2095  switch_channel_answer(channel);
2096 
2097  if (!zstr(buuid)) {
2098  if ((bsession = switch_core_session_locate(buuid))) {
2099  bchannel = switch_core_session_get_channel(bsession);
2101  }
2102  }
2103 
2104  if (!switch_channel_test_flag(rchannel, CF_ANSWERED)) {
2105  switch_channel_answer(rchannel);
2106  }
2107 
2109 
2111  switch_channel_set_state(rchannel, CS_PARK);
2112 
2113  if (bchannel) {
2114  switch_channel_set_variable(bchannel, "park_after_bridge", "true");
2115  }
2116 
2119  switch_core_session_rwunlock(rsession);
2120 
2121  if (bsession) {
2123  switch_core_session_rwunlock(bsession);
2124  }
2125 
2126 
2127 
2128 }
2129 
2130 /* For Emacs:
2131  * Local Variables:
2132  * mode:c
2133  * indent-tabs-mode:t
2134  * tab-width:4
2135  * c-basic-offset:4
2136  * End:
2137  * For VIM:
2138  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
2139  */
#define SWITCH_SIGNAL_BRIDGE_VARIABLE
Definition: switch_types.h:201
switch_channel_state_t switch_channel_get_state(switch_channel_t *channel)
Get the current state of a channel in the state engine.
#define switch_event_fire(event)
Fire an event filling in most of the arguements with obvious values.
Definition: switch_event.h:412
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it's state machine to end.
#define switch_core_media_gen_key_frame(_session)
void switch_xml_free(_In_opt_ switch_xml_t xml)
frees the memory allocated for an switch_xml structure
#define switch_channel_answer(channel)
Answer a channel (initiate/acknowledge a successful connection)
switch_status_t switch_channel_execute_on(switch_channel_t *channel, const char *variable_prefix)
switch_event_types_t event_id
Definition: switch_event.h:82
void switch_channel_set_flag_recursive(switch_channel_t *channel, switch_channel_flag_t flag)
#define SWITCH_CHANNEL_SESSION_LOG(x)
An Abstract Representation of a dialplan extension.
Image Descriptor.
Definition: switch_image.h:88
Call Specific Data.
Definition: switch_caller.h:73
char * switch_xml_toxml(_In_ switch_xml_t xml, _In_ switch_bool_t prn_header)
Converts an switch_xml structure back to xml in html format. Returns a string of html data that \ mus...
#define SWITCH_LAST_BRIDGE_VARIABLE
Definition: switch_types.h:200
switch_core_session_message_types_t message_id
Definition: switch_core.h:181
void switch_core_session_reset(_In_ switch_core_session_t *session, switch_bool_t flush_dtmf, switch_bool_t reset_read_codec)
Reset the buffers and resampler on a session.
switch_status_t switch_channel_set_variable_name_printf(switch_channel_t *channel, const char *val, const char *fmt,...)
#define SWITCH_COPY_XML_CDR_VARIABLE
Definition: switch_types.h:138
void switch_img_free(switch_image_t **img)
Close an image descriptor.
switch_core_session_t * session
#define SWITCH_PARK_AFTER_EARLY_BRIDGE_VARIABLE
Definition: switch_types.h:218
const char * switch_channel_get_partner_uuid(switch_channel_t *channel)
#define switch_channel_set_state(channel, state)
Set the current state of a channel.
switch_status_t switch_channel_set_private(switch_channel_t *channel, const char *key, const void *private_info)
Set private data on channel.
const char * switch_channel_cause2str(_In_ switch_call_cause_t cause)
return a cause string for a given cause
void switch_channel_clear_state_flag(switch_channel_t *channel, switch_channel_flag_t flag)
#define SWITCH_TRANSFER_SOURCE_VARIABLE
Definition: switch_types.h:143
#define SWITCH_API_BRIDGE_END_VARIABLE
Definition: switch_types.h:172
switch_status_t switch_ivr_wait_for_answer(switch_core_session_t *session, switch_core_session_t *peer_session)
static switch_status_t uuid_bridge_on_soft_execute(switch_core_session_t *session)
switch_status_t switch_core_file_read_video(switch_file_handle_t *fh, switch_frame_t *frame, switch_video_read_flag_t flags)
#define switch_channel_stop_broadcast(_channel)
void switch_channel_set_bridge_time(switch_channel_t *channel)
#define switch_channel_up(_channel)
#define SWITCH_RECOMMENDED_BUFFER_SIZE
Definition: switch_types.h:557
void switch_event_add_presence_data_cols(switch_channel_t *channel, switch_event_t *event, const char *prefix)
void switch_channel_event_set_data(_In_ switch_channel_t *channel, _In_ switch_event_t *event)
Add information about a given channel to an event object.
switch_codec_t * switch_core_session_get_video_read_codec(_In_ switch_core_session_t *session)
Retrieve the video_read codec from a given session.
switch_bool_t
Definition: switch_types.h:405
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:729
switch_status_t switch_core_session_read_video_frame(_In_ switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
Read a video frame from a session.
Representation of an event.
Definition: switch_event.h:80
struct switch_ivr_bridge_data * other_leg_data
static void send_display(switch_core_session_t *session, switch_core_session_t *peer_session)
#define switch_channel_ready(_channel)
static switch_status_t audio_bridge_on_consume_media(switch_core_session_t *session)
switch_status_t switch_core_session_read_lock(_In_ switch_core_session_t *session)
Acquire a read lock on the session.
#define SWITCH_RTP_MAX_BUF_LEN
Definition: switch_rtp.h:44
switch_status_t switch_core_media_set_video_file(switch_core_session_t *session, switch_file_handle_t *fh, switch_rw_t rw)
static const switch_state_handler_table_t uuid_bridge_state_handlers
switch_caller_profile_t * switch_caller_profile_clone(_In_ switch_core_session_t *session, _In_ switch_caller_profile_t *tocopy)
Clone an existing caller profile object.
void switch_generate_sln_silence(int16_t *data, uint32_t samples, uint32_t channels, uint32_t divisor)
Generate static noise.
switch_channel_state_t switch_channel_get_running_state(switch_channel_t *channel)
void switch_channel_flip_cid(switch_channel_t *channel)
#define switch_channel_media_ready(_channel)
#define switch_channel_outbound_display(_channel)
A representation of an XML tree.
Definition: switch_xml.h:76
switch_status_t switch_core_codec_destroy(switch_codec_t *codec)
Destroy an initalized codec handle.
const char * switch_channel_get_variable_dup(switch_channel_t *channel, const char *varname, switch_bool_t dup, int idx)
Retrieve a variable from a given channel.
const char * string_array_arg[MESSAGE_STRING_ARG_MAX]
Definition: switch_core.h:209
static void cleanup_proxy_mode_b(switch_core_session_t *session)
void switch_channel_set_state_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Set given flag(s) on a given channel to be applied on the next state change.
static switch_status_t sb_on_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf, switch_dtmf_direction_t direction)
switch_status_t switch_core_session_queue_message(_In_ switch_core_session_t *session, _In_ switch_core_session_message_t *message)
Queue a message on a session.
switch_status_t switch_ivr_parse_all_events(switch_core_session_t *session)
Parse all commands from an event.
Definition: switch_ivr.c:867
switch_status_t switch_ivr_media(const char *uuid, switch_media_flag_t flags)
Signal a session to request direct media access to it's remote end.
Definition: switch_ivr.c:1674
void switch_ivr_intercept_session(switch_core_session_t *session, const char *uuid, switch_bool_t bleg)
switch_status_t switch_core_session_execute_application_async(switch_core_session_t *session, const char *app, const char *arg)
static switch_thread_t * thread
Definition: switch_log.c:279
#define SWITCH_CHANNEL_EXECUTE_ON_PRE_BRIDGE_VARIABLE
Definition: switch_types.h:157
static int switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:450
uint32_t switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Test for presence of given flag on a given channel.
switch_status_t switch_core_session_read_frame(_In_ switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
Read a frame from a session.
switch_codec_t * codec
Definition: switch_frame.h:45
A message object designed to allow unlike technologies to exchange data.
Definition: switch_core.h:177
switch_image_t * switch_img_alloc(switch_image_t *img, switch_img_fmt_t fmt, unsigned int d_w, unsigned int d_h, unsigned int align)
Open a descriptor, allocating storage for the underlying image.
#define SWITCH_COPY_JSON_CDR_VARIABLE
Definition: switch_types.h:139
void switch_core_media_end_video_function(switch_core_session_t *session)
#define SWITCH_ORIGINATE_SIGNAL_BOND_VARIABLE
Definition: switch_types.h:203
#define zstr(x)
Definition: switch_utils.h:281
#define SWITCH_PARK_AFTER_BRIDGE_VARIABLE
Definition: switch_types.h:217
switch_status_t switch_ivr_session_transfer(_In_ switch_core_session_t *session, const char *extension, const char *dialplan, const char *context)
Transfer an existing session to another location.
unsigned int d_w
Definition: switch_image.h:99
switch_status_t switch_core_session_write_frame(_In_ switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
Write a frame to a session.
void switch_channel_invert_cid(switch_channel_t *channel)
switch_status_t switch_core_session_get_read_impl(switch_core_session_t *session, switch_codec_implementation_t *impp)
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
switch_status_t switch_ivr_parse_next_event(switch_core_session_t *session)
Definition: switch_ivr.c:755
#define SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE
Definition: switch_types.h:216
#define SWITCH_EXEC_AFTER_BRIDGE_APP_VARIABLE
Definition: switch_types.h:221
#define SWITCH_CHANNEL_EXECUTE_ON_POST_BRIDGE_VARIABLE
Definition: switch_types.h:158
void switch_channel_mark_hold(switch_channel_t *channel, switch_bool_t on)
void switch_channel_wait_for_state(switch_channel_t *channel, switch_channel_t *other_channel, switch_channel_state_t want_state)
void switch_caller_profile_event_set_data(_In_ switch_caller_profile_t *caller_profile, _In_opt_z_ const char *prefix, _In_ switch_event_t *event)
Add headers to an existing event in regards to a specific profile.
const switch_codec_implementation_t * implementation
uint32_t buflen
Definition: switch_frame.h:59
switch_byte_t switch_byte_t * buf
#define SWITCH_BRIDGE_EXPORT_VARS_VARIABLE
Definition: switch_types.h:195
#define switch_yield(ms)
Wait a desired number of microseconds and yield the CPU.
Definition: switch_utils.h:908
#define switch_channel_audio_sync(_c)
unsigned int switch_separate_string(_In_ char *buf, char delim, _Post_count_(return) char **array, unsigned int arraylen)
Separate a string into an array based on a character delimiter.
int switch_core_media_check_video_function(switch_core_session_t *session)
uint32_t datalen
Definition: switch_frame.h:57
static void exec_app(switch_core_session_t *session, char *app_str)
#define switch_channel_inbound_display(_channel)
uint32_t packetlen
Definition: switch_frame.h:51
switch_status_t switch_ivr_find_bridged_uuid(const char *uuid, char *b_uuid, switch_size_t blen)
switch_file_handle_t * switch_core_media_get_video_file(switch_core_session_t *session, switch_rw_t rw)
char b_uuid[SWITCH_UUID_FORMATTED_LENGTH+1]
const char * callee_id_number
Definition: switch_caller.h:89
void switch_channel_process_export(switch_channel_t *channel, switch_channel_t *peer_channel, switch_event_t *var_event, const char *export_varname)
switch_status_t(* switch_input_callback_function_t)(switch_core_session_t *session, void *input, switch_input_type_t input_type, void *buf, unsigned int buflen)
switch_status_t switch_channel_add_variable_var_check(switch_channel_t *channel, const char *varname, const char *value, switch_bool_t var_check, switch_stack_t stack)
switch_status_t switch_core_session_send_dtmf(_In_ switch_core_session_t *session, const switch_dtmf_t *dtmf)
Send DTMF to a session.
void switch_channel_clear_state_handler(switch_channel_t *channel, const switch_state_handler_table_t *state_handler)
clear a state handler table from a given channel
#define DUMP_EVENT(_e)
#define switch_channel_get_variable(_c, _v)
#define switch_channel_video_sync(_c)
switch_status_t switch_channel_dequeue_dtmf(_In_ switch_channel_t *channel, _In_ switch_dtmf_t *dtmf)
Retrieve DTMF digits from a given channel.
switch_status_t switch_event_add_header_string(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *data)
Add a string header to an event.
#define DEFAULT_LEAD_FRAMES
const char * caller_id_name
Definition: switch_caller.h:79
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
#define SWITCH_BRIDGE_HANGUP_CAUSE_VARIABLE
Definition: switch_types.h:127
switch_status_t switch_ivr_uuid_bridge(const char *originator_uuid, const char *originatee_uuid)
Bridge two existing sessions.
#define SWITCH_BRIDGE_UUID_VARIABLE
Definition: switch_types.h:182
#define switch_channel_down_nosig(_channel)
#define SWITCH_API_BRIDGE_START_VARIABLE
Definition: switch_types.h:173
void switch_channel_set_caller_extension(switch_channel_t *channel, switch_caller_extension_t *caller_extension)
Assign a caller extension to a given channel.
An abstraction of a data frame.
Definition: switch_frame.h:43
uintptr_t switch_size_t
#define SWITCH_TRANSFER_AFTER_EARLY_BRIDGE_VARIABLE
Definition: switch_types.h:220
void switch_caller_extension_add_application(_In_ switch_core_session_t *session, _In_ switch_caller_extension_t *caller_extension, _In_z_ const char *application_name, _In_z_ const char *extra_data)
Add an application (instruction) to the given extension.
void switch_channel_set_originator_caller_profile(switch_channel_t *channel, switch_caller_profile_t *caller_profile)
Set the given channel's originator caller profile.
static switch_status_t hanguphook(switch_core_session_t *session)
switch_codec_t * switch_core_session_get_video_write_codec(_In_ switch_core_session_t *session)
Retrieve the video_write codec from a given session.
switch_byte_t switch_byte_t uint32_t buflen
#define switch_core_codec_init(_codec, _codec_name, _modname, _fmtp, _rate, _ms, _channels, _flags, _codec_settings, _pool)
Initialize a codec handle.
Definition: switch_core.h:1602
void switch_cond_next(void)
Definition: switch_time.c:638
#define switch_core_session_get_partner(_session, _partner)
Definition: switch_core.h:1002
char * switch_copy_string(_Out_z_cap_(dst_size) char *dst, _In_z_ const char *src, _In_ switch_size_t dst_size)
void switch_color_set_rgb(switch_rgb_color_t *color, const char *color_str)
Set RGB color with a string.
#define SWITCH_BRIDGE_VARIABLE
Definition: switch_types.h:199
switch_call_cause_t
switch_dtmf_direction_t
Definition: switch_types.h:310
static switch_status_t switch_event_create_plain(switch_event_t **event, switch_event_types_t event_id)
Definition: switch_event.h:385
switch_caller_extension_t * switch_caller_extension_new(_In_ switch_core_session_t *session, _In_z_ const char *extension_name, _In_z_ const char *extension_number)
Create a new extension with desired parameters.
#define switch_core_session_receive_message(_session, _message)
Definition: switch_core.h:1217
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.
void switch_core_session_video_reset(switch_core_session_t *session)
char * switch_core_session_get_uuid(_In_ switch_core_session_t *session)
Retrieve the unique identifier from a session.
switch_input_callback_function_t input_callback
static switch_status_t uuid_bridge_on_reset(switch_core_session_t *session)
static switch_status_t audio_bridge_on_exchange_media(switch_core_session_t *session)
void switch_ivr_park_session(switch_core_session_t *session)
Definition: switch_ivr.c:3411
static switch_status_t signal_bridge_on_hibernate(switch_core_session_t *session)
switch_status_t switch_core_session_write_video_frame(_In_ switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
Write a video frame to a session.
switch_channel_state_t
Channel States (these are the defaults, CS_SOFT_EXECUTE, CS_EXCHANGE_MEDIA, and CS_CONSUME_MEDIA are ...
void * packet
Definition: switch_frame.h:49
switch_status_t switch_core_session_request_video_refresh(switch_core_session_t *session)
switch_status_t switch_ivr_3p_nomedia(const char *uuid, switch_media_flag_t flags)
Definition: switch_ivr.c:1774
#define switch_channel_down(_channel)
static switch_status_t signal_bridge_on_hangup(switch_core_session_t *session)
void switch_channel_step_caller_profile(switch_channel_t *channel)
switch_status_t switch_ivr_generate_json_cdr(switch_core_session_t *session, cJSON **json_cdr, switch_bool_t urlencode)
Generate an JSON CDR report.
Definition: switch_ivr.c:3177
switch_image_t * img
Definition: switch_frame.h:77
switch_status_t
Common return values.
#define MESSAGE_STAMP_FFL(_m)
Definition: switch_core.h:173
#define SWITCH_EXEC_AFTER_BRIDGE_ARG_VARIABLE
Definition: switch_types.h:222
void * switch_channel_get_private(switch_channel_t *channel, const char *key)
Retrieve private from a given channel.
static void check_bridge_export(switch_channel_t *channel, switch_channel_t *peer_channel)
switch_status_t switch_core_session_dequeue_event(_In_ switch_core_session_t *session, _Out_ switch_event_t **event, switch_bool_t force)
DE-Queue an event on a given session.
static void transfer_after_bridge(switch_core_session_t *session, const char *where)
#define SWITCH_SIGNAL_BOND_VARIABLE
Definition: switch_types.h:202
switch_status_t switch_core_session_receive_event(_In_ switch_core_session_t *session, _Inout_ switch_event_t **event)
Send an event to a session translating it to it's native message format.
void switch_channel_set_originatee_caller_profile(switch_channel_t *channel, switch_caller_profile_t *caller_profile)
Set the given channel's originatee caller profile.
switch_size_t switch_channel_has_dtmf(_In_ switch_channel_t *channel)
Test for presence of DTMF on a given channel.
void switch_img_fill(switch_image_t *img, int x, int y, int w, int h, switch_rgb_color_t *color)
Fill image with color.
struct apr_thread_t switch_thread_t
Definition: switch_apr.h:941
#define switch_core_session_locate(uuid_str)
Locate a session based on it's uuid.
Definition: switch_core.h:916
Main Library Header.
switch_ivr_dmachine_t * switch_core_session_get_dmachine(switch_core_session_t *session, switch_digit_action_target_t target)
#define switch_event_create(event, id)
Create a new event assuming it will not be custom event and therefore hiding the unused parameters...
Definition: switch_event.h:383
#define SWITCH_DECLARE(type)
uint32_t samples
Definition: switch_frame.h:61
uint32_t switch_core_session_private_event_count(_In_ switch_core_session_t *session)
Indicate the number of waiting private events on a session.
void switch_core_media_start_video_function(switch_core_session_t *session, switch_video_function_t video_function, void *user_data)
static void abort_call(switch_channel_t *caller_channel, switch_channel_t *peer_channel)
#define switch_channel_set_flag(_c, _f)
#define SWITCH_IMG_FMT_I420
Definition: switch_vpx.h:77
void switch_ivr_bridge_display(switch_core_session_t *session, switch_core_session_t *peer_session)
switch_call_direction_t switch_channel_direction(switch_channel_t *channel)
static void cleanup_proxy_mode_a(switch_core_session_t *session)
switch_status_t switch_ivr_dmachine_ping(switch_ivr_dmachine_t *dmachine, switch_ivr_dmachine_match_t **match_p)
#define SWITCH_TRANSFER_HISTORY_VARIABLE
Definition: switch_types.h:142
#define switch_channel_media_ack(_channel)
static const switch_state_handler_table_t audio_bridge_peer_state_handlers
time_t switch_epoch_time_now(time_t *t)
Get the current epoch time.
Definition: switch_time.c:321
const char * caller_id_number
Definition: switch_caller.h:81
int switch_channel_add_state_handler(switch_channel_t *channel, const switch_state_handler_table_t *state_handler)
add a state handler table to a given channel
#define switch_core_session_alloc(_session, _memory)
Allocate memory from a session's pool.
Definition: switch_core.h:694
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
static switch_status_t audio_bridge_on_routing(switch_core_session_t *session)
void switch_channel_clear_flag_recursive(switch_channel_t *channel, switch_channel_flag_t flag)
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
const char * switch_stristr(const char *instr, const char *str)
A table of settings and callbacks that define a paticular implementation of a codec.
#define switch_channel_up_nosig(_channel)
switch_status_t switch_ivr_multi_threaded_bridge(switch_core_session_t *session, switch_core_session_t *peer_session, switch_input_callback_function_t input_callback, void *session_data, void *peer_session_data)
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session's pool.
Definition: switch_core.h:717
void switch_event_destroy(switch_event_t **event)
Destroy an event.
unsigned int d_h
Definition: switch_image.h:100
switch_status_t switch_channel_wait_for_flag(switch_channel_t *channel, switch_channel_flag_t want_flag, switch_bool_t pres, uint32_t to, switch_channel_t *super_channel)
void switch_channel_clear_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Clear given flag(s) from a channel.
switch_status_t switch_ivr_signal_bridge(switch_core_session_t *session, switch_core_session_t *peer_session)
Bridge Signalling from one session to another.
char * switch_core_sprintf(_In_ switch_memory_pool_t *pool, _In_z_ _Printf_format_string_ const char *fmt,...)
printf-style style printing routine. The data is output to a string allocated from the pool ...
#define switch_assert(expr)
#define switch_channel_set_variable(_channel, _var, _val)
switch_status_t switch_ivr_generate_xml_cdr(switch_core_session_t *session, switch_xml_t *xml_cdr)
Generate an XML CDR report.
Definition: switch_ivr.c:2713
#define switch_channel_pre_answer(channel)
Indicate progress on a channel to attempt early media.
switch_caller_profile_t * switch_channel_get_caller_profile(switch_channel_t *channel)
Retrieve the given channel's caller profile.
#define switch_core_session_kill_channel(session, sig)
Send a signal to a channel.
Definition: switch_core.h:1352
switch_status_t switch_channel_api_on(switch_channel_t *channel, const char *variable_prefix)
#define SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE
Definition: switch_types.h:219
void cJSON_Delete(cJSON *c)
Definition: switch_json.c:93
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.
switch_status_t switch_channel_pass_callee_id(switch_channel_t *channel, switch_channel_t *other_channel)
#define SWITCH_READ_ACCEPTABLE(status)
Definition: switch_utils.h:995
#define switch_channel_media_up(_channel)
static const switch_state_handler_table_t signal_bridge_state_handlers
const char * callee_id_name
Definition: switch_caller.h:87
switch_memory_pool_t * switch_core_session_get_pool(_In_ switch_core_session_t *session)
Retrieve the memory pool from a session.
char * cJSON_PrintUnformatted(cJSON *item)
Definition: switch_json.c:285
#define SWITCH_UUID_FORMATTED_LENGTH
Definition: switch_apr.h:545
#define SWITCH_BRIDGE_CHANNEL_VARIABLE
Definition: switch_types.h:180
switch_call_cause_t switch_channel_get_cause(_In_ switch_channel_t *channel)
return the cause code for a given channel
#define SWITCH_UUID_BRIDGE
Definition: switch_types.h:227
static void * audio_bridge_thread(switch_thread_t *thread, void *obj)
switch_status_t switch_ivr_parse_all_messages(switch_core_session_t *session)
Definition: switch_ivr.c:801
switch_memory_pool_t * pool
static switch_status_t uuid_bridge_on_hibernate(switch_core_session_t *session)
void switch_channel_handle_cause(switch_channel_t *channel, switch_call_cause_t cause)