RTS API Documentation  1.10.11
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 struct vid_helper {
45  int up;
46 };
47 
48 
49 static void text_bridge_thread(switch_core_session_t *session, void *obj)
50 {
51  struct vid_helper *vh = obj;
52  switch_status_t status;
53  switch_frame_t *read_frame = 0;
56  switch_buffer_t *text_buffer = NULL;
57  switch_size_t text_framesize = 1024, inuse = 0;
58  unsigned char *text_framedata = NULL;
59  switch_frame_t frame = { 0 };
60 
61  switch_buffer_create_dynamic(&text_buffer, 512, 1024, 0);
62  switch_zmalloc(text_framedata, 1024);
63  text_framesize = 1024;
64 
65  vh->up = 1;
66 
67  while (switch_channel_up_nosig(channel) && switch_channel_up_nosig(b_channel) && vh->up == 1) {
69 
70  if (!SWITCH_READ_ACCEPTABLE(status)) {
72  continue;
73  }
74 
76  if (read_frame->data && read_frame->datalen && !switch_test_flag(read_frame, SFF_CNG)) {
77  switch_buffer_write(text_buffer, read_frame->data, read_frame->datalen);
78  }
79 
80  inuse = switch_buffer_inuse(text_buffer);
81 
82  if (inuse && (switch_channel_test_flag(channel, CF_TEXT_IDLE) || switch_test_flag(read_frame, SFF_TEXT_LINE_BREAK))) {
83  int bytes;
84 
85  if (inuse + 4 > text_framesize) {
86  void *tmp = malloc(inuse + 1024);
87 
88  switch_assert(tmp);
89  memcpy(tmp, text_framedata, text_framesize);
90 
91  text_framesize = inuse + 1024;
92 
93  free(text_framedata);
94  text_framedata = tmp;
95  }
96 
97  bytes = switch_buffer_read(text_buffer, text_framedata, inuse);
98 
99  /* need to strip the unicode line feed because Blink ignores the message, need to see if that is a thing with other msrp clients */
100  if (switch_test_flag(read_frame, SFF_TEXT_LINE_BREAK)) {
101  int x;
102 
103  for (x = 0; x < bytes - 2; x++) {
104  if (text_framedata[x] == 0xe2 && text_framedata[x+1] == 0x80 && text_framedata[x+2] == 0xa8) {
105  text_framedata[x] = '\0';
106  bytes = strlen((char *)text_framedata);
107  break;
108  }
109  }
110  }
111 
112  if (!bytes) continue;
113 
114  *(text_framedata + bytes) = '\r';
115  *(text_framedata + bytes + 1) = '\n';
116  *(text_framedata + bytes + 2) = '\0';
117 
118  frame.data = text_framedata;
119  frame.datalen = strlen((char *)frame.data);
120  read_frame = &frame;
121 
122  } else {
123  continue;
124  }
125 
126  }
127 
128  if (!switch_test_flag(read_frame, SFF_CNG)) {
129  switch_status_t tstatus = switch_core_session_write_text_frame(vh->session_b, read_frame, 0, 0);
130 
131  if (tstatus != SWITCH_STATUS_SUCCESS) {
133  }
134  }
136  }
137 
138  vh->up = 0;
139 
140  switch_buffer_destroy(&text_buffer);
141  switch_safe_free(text_framedata);
142 }
143 
144 
145 #ifdef SWITCH_VIDEO_IN_THREADS
146 
147 static void video_bridge_thread(switch_core_session_t *session, void *obj)
148 {
149  struct vid_helper *vh = obj;
152  switch_status_t status;
153  switch_frame_t *read_frame = 0;
154  int set_decoded_read = 0, refresh_timer = 0;
155  int refresh_cnt = 300;
156  int pass_val = 0, last_pass_val = 0;
157 
158  vh->up = 1;
159 
161  vh->up = 0;
162  return;
163  }
164 
166  vh->up = 0;
168  return;
169  }
170 
173 
174  refresh_timer = refresh_cnt;
175 
176  while (switch_channel_up_nosig(channel) && switch_channel_up_nosig(b_channel) && vh->up == 1) {
177  if (switch_channel_media_up(channel)) {
179  pass_val = 1;
180  } else {
181  pass_val = 2;
182  }
183 
184  if (pass_val != last_pass_val) {
186  last_pass_val = pass_val;
187  }
188 
191  refresh_timer = refresh_cnt;
192  }
193 
194  if (!switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
195  switch_codec_implementation_t session_a_codec_implementation;
196  switch_codec_implementation_t session_b_codec_implementation;
197 
198  switch_core_session_get_video_read_impl(vh->session_a, &session_a_codec_implementation);
199  switch_core_session_get_video_write_impl(vh->session_b, &session_b_codec_implementation);
200 
202  if (session_a_codec_implementation.impl_id == session_b_codec_implementation.impl_id && !switch_channel_test_flag(b_channel, CF_VIDEO_DECODED_READ)) {
203  if (set_decoded_read) {
205  set_decoded_read = 0;
206  refresh_timer = refresh_cnt;
207  }
208  }
209  } else {
210  if (session_a_codec_implementation.impl_id != session_b_codec_implementation.impl_id ||
213  set_decoded_read = 1;
214  refresh_timer = refresh_cnt;
215  }
216  }
217  }
218 
219  if (refresh_timer) {
220  if (refresh_timer > 0 && (refresh_timer % 100) == 0) {
222  }
223  refresh_timer--;
224  }
225 
227 
228  if (!SWITCH_READ_ACCEPTABLE(status)) {
230  continue;
231  }
232  }
233 
234 
235  if (read_frame && (switch_test_flag(read_frame, SFF_CNG) ||
237  continue;
238  }
239 
240  if (read_frame && switch_channel_media_up(b_channel)) {
243  continue;
244  }
245  }
246  }
247 
248  if (set_decoded_read) {
250  }
251 
254 
257 
259 
262 
263  vh->up = 0;
264  return;
265 }
266 
267 static void launch_video(struct vid_helper *vh)
268 {
270 }
271 #endif
272 
273 
274 static void send_display(switch_core_session_t *session, switch_core_session_t *peer_session)
275 {
276 
278  switch_caller_profile_t *caller_profile, *peer_caller_profile;
279  switch_channel_t *caller_channel, *peer_channel;
280  const char *name, *number, *p;
281 
282  caller_channel = switch_core_session_get_channel(session);
283  peer_channel = switch_core_session_get_channel(peer_session);
284 
285  caller_profile = switch_channel_get_caller_profile(caller_channel);
286  peer_caller_profile = switch_channel_get_caller_profile(peer_channel);
287 
288  if (switch_channel_test_flag(caller_channel, CF_BRIDGE_ORIGINATOR)) {
289  if (!zstr(peer_caller_profile->caller_id_name)) {
290  name = peer_caller_profile->caller_id_name;
291  } else {
292  name = caller_profile->caller_id_name;
293  }
294 
295  if (!zstr(peer_caller_profile->caller_id_number)) {
296  number = peer_caller_profile->caller_id_number;
297  } else {
298  number = caller_profile->caller_id_number;
299  }
300 
301  if (zstr(number)) {
302  number = "UNKNOWN";
303  }
304  } else {
305  name = caller_profile->callee_id_name;
306  number = caller_profile->callee_id_number;
307 
308  if (zstr(number)) {
309  number = caller_profile->destination_number;
310  }
311  }
312 
313 
314  if (zstr(name)) {
315  name = number;
316  }
317 
318  if ((p = strrchr(number, '/'))) {
319  number = p + 1;
320  }
321  if ((p = strrchr(name, '/'))) {
322  name = p + 1;
323  }
324 
325  msg = switch_core_session_alloc(peer_session, sizeof(*msg));
326  MESSAGE_STAMP_FFL(msg);
328  msg->string_array_arg[0] = switch_core_session_strdup(peer_session, name);
329  msg->string_array_arg[1] = switch_core_session_strdup(peer_session, number);
330  msg->from = __FILE__;
331  switch_core_session_queue_message(peer_session, msg);
332 
333 }
334 
335 
337 {
338 
339  send_display(session, peer_session);
340  send_display(peer_session, session);
341 
342 }
343 
351  int done;
353 };
355 
356 static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
357 {
358  switch_ivr_bridge_data_t *data = obj;
359  int stream_id = 0, pre_b = 0, ans_a = 0, ans_b = 0, originator = 0;
361  switch_core_session_message_t msg = { 0 };
362  void *user_data;
363  switch_channel_t *chan_a, *chan_b;
364  switch_frame_t *read_frame;
366  uint32_t read_frame_count = 0;
367  const char *app_name = NULL, *app_arg = NULL;
368  int inner_bridge = 0, exec_check = 0;
369  switch_codec_t silence_codec = { 0 };
370  switch_frame_t silence_frame = { 0 };
371  int16_t silence_data[SWITCH_RECOMMENDED_BUFFER_SIZE / 2] = { 0 };
372  const char *silence_var;
373  int silence_val = 0, bypass_media_after_bridge = 0;
374  const char *bridge_answer_timeout = NULL;
375  int bridge_filter_dtmf, answer_timeout, sent_update = 0;
376  time_t answer_limit = 0;
377  const char *exec_app = NULL;
378  const char *exec_data = NULL;
379  switch_codec_implementation_t read_impl = { 0 };
380  uint32_t txt_launch = 0;
381  struct vid_helper th = { 0 };
382  const char *banner_file = NULL;
383  int played_banner = 0, banner_counter = 0;
384  int pass_val = 0, last_pass_val = 0;
385 
386 #ifdef SWITCH_VIDEO_IN_THREADS
387  struct vid_helper vh = { 0 };
388  uint32_t vid_launch = 0;
389 #endif
390  data->clean_exit = 0;
391 
392  session_a = data->session;
393  if (!(session_b = switch_core_session_locate(data->b_uuid))) {
394  return NULL;
395  }
396 
397  switch_core_session_get_read_impl(session_a, &read_impl);
398 
399  input_callback = data->input_callback;
400  user_data = data->session_data;
401  stream_id = data->stream_id;
402 
403  chan_a = switch_core_session_get_channel(session_a);
404  chan_b = switch_core_session_get_channel(session_b);
405 
406  if ((exec_app = switch_channel_get_variable(chan_a, "bridge_pre_execute_app"))) {
407  exec_data = switch_channel_get_variable(chan_a, "bridge_pre_execute_data");
408  }
409 
410  bypass_media_after_bridge = switch_channel_test_flag(chan_a, CF_BYPASS_MEDIA_AFTER_BRIDGE);
412 
413  ans_a = switch_channel_test_flag(chan_a, CF_ANSWERED);
414 
415  if ((originator = switch_channel_test_flag(chan_a, CF_BRIDGE_ORIGINATOR))) {
416  pre_b = switch_channel_test_flag(chan_a, CF_EARLY_MEDIA);
417  ans_b = switch_channel_test_flag(chan_b, CF_ANSWERED);
418  }
419 
420  inner_bridge = switch_channel_test_flag(chan_a, CF_INNER_BRIDGE);
421 
422  if (!switch_channel_test_flag(chan_a, CF_ANSWERED) && (bridge_answer_timeout = switch_channel_get_variable(chan_a, "bridge_answer_timeout"))) {
423  if ((answer_timeout = atoi(bridge_answer_timeout)) >= 0) {
424  answer_limit = switch_epoch_time_now(NULL) + answer_timeout;
425  }
426  }
427 
430 
432 
433  switch_channel_wait_for_flag(chan_b, CF_BRIDGED, SWITCH_TRUE, 10000, chan_a);
434 
435  if (!switch_channel_test_flag(chan_b, CF_BRIDGED)) {
437  || switch_channel_get_state(chan_b) == CS_RESET)) {
439  }
440  goto end_of_bridge_loop;
441  }
442 
443 
444  if (switch_channel_test_flag(chan_a, CF_BRIDGE_ORIGINATOR) && (banner_file = switch_channel_get_variable(chan_a, "video_pre_call_banner"))) {
451  }
452 
453 
454  if (bypass_media_after_bridge) {
455  const char *source_a = switch_channel_get_variable(chan_a, "source");
456  const char *source_b = switch_channel_get_variable(chan_b, "source");
457 
458  if (!source_a) source_a = "";
459  if (!source_b) source_b = "";
460 
461  if (switch_stristr("loopback", source_a) || switch_stristr("loopback", source_b)) {
462  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_WARNING, "Cannot bypass media while bridged to a loopback address.\n");
463  bypass_media_after_bridge = 0;
464  }
465  }
466 
467  if ((silence_var = switch_channel_get_variable(chan_a, "bridge_generate_comfort_noise"))) {
468 
469  if (!switch_channel_media_up(chan_a)) {
470  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_ERROR, "Channel has no media!\n");
471  goto end_of_bridge_loop;
472  }
473 
474  if (switch_true(silence_var)) {
475  silence_val = 1400;
476  } else {
477  if ((silence_val = atoi(silence_var)) < -1) {
478  silence_val = 0;
479  }
480  }
481 
482  if (silence_val) {
483  if (switch_core_codec_init(&silence_codec,
484  "L16",
485  NULL,
486  NULL,
487  read_impl.actual_samples_per_second,
488  read_impl.microseconds_per_packet / 1000,
489  1,
492 
493  silence_val = 0;
494  } else {
495  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),
496  switch_channel_get_name(chan_b), silence_val);
497  silence_frame.codec = &silence_codec;
498  silence_frame.data = silence_data;
499  silence_frame.buflen = sizeof(silence_data);
500  silence_frame.datalen = read_impl.decoded_bytes_per_packet;
501  silence_frame.samples = silence_frame.datalen / sizeof(int16_t);
502  }
503  }
504  }
505 
506  bridge_filter_dtmf = switch_true(switch_channel_get_variable(chan_a, "bridge_filter_dtmf"));
507 
508 
509  for (;;) {
510  switch_status_t status;
511  switch_event_t *event;
512 
513  if (switch_core_session_transcoding(session_a, session_b, SWITCH_MEDIA_TYPE_AUDIO)) {
514  pass_val = 1;
515  } else {
516  pass_val = 2;
517  }
518 
519  if (pass_val != last_pass_val) {
521  last_pass_val = pass_val;
522  }
523 
524  if (switch_channel_test_flag(chan_a, CF_TRANSFER)) {
525  data->clean_exit = 1;
526  }
527 
528  if (data->clean_exit || switch_channel_test_flag(chan_b, CF_TRANSFER)) {
531  goto end_of_bridge_loop;
532  }
533 
534  if (!switch_channel_test_flag(chan_b, CF_BRIDGED)) {
535  goto end_of_bridge_loop;
536  }
537 
538  if (!switch_channel_ready(chan_a)) {
539  if (switch_channel_up(chan_a)) {
540  data->clean_exit = 1;
541  }
542  goto end_of_bridge_loop;
543  }
544 
545  if (switch_channel_down_nosig(chan_b)) {
546  goto end_of_bridge_loop;
547  }
548 
550  switch_core_session_message_t hmsg = { 0 };
553  hmsg.from = __FILE__;
554  hmsg.numeric_arg = 1;
555  switch_core_session_receive_message(session_a, &hmsg);
556  }
557 
558  if (read_frame_count > DEFAULT_LEAD_FRAMES && switch_channel_media_ack(chan_a) && switch_core_session_private_event_count(session_a)) {
560  msg.numeric_arg = 42;
561  msg.string_arg = data->b_uuid;
563  msg.from = __FILE__;
564  switch_core_session_receive_message(session_a, &msg);
565  switch_ivr_parse_next_event(session_a);
567  switch_core_session_receive_message(session_a, &msg);
570  }
571 
573 
574  if (!inner_bridge && (switch_channel_test_flag(chan_a, CF_SUSPEND) || switch_channel_test_flag(chan_b, CF_SUSPEND))) {
575  status = switch_core_session_read_frame(session_a, &read_frame, SWITCH_IO_FLAG_NONE, stream_id);
576 
577  if (!SWITCH_READ_ACCEPTABLE(status)) {
578  goto end_of_bridge_loop;
579  }
580  continue;
581  }
582 
583  if (switch_channel_test_flag(chan_a, CF_HAS_TEXT) && switch_channel_test_flag(chan_b, CF_HAS_TEXT) && !txt_launch) {
584  txt_launch++;
585 
586  th.session_a = session_a;
587  th.session_b = session_b;
589 
590  }
591 
592 #ifdef SWITCH_VIDEO_IN_THREADS
593  if (switch_channel_test_flag(chan_a, CF_VIDEO) && switch_channel_test_flag(chan_b, CF_VIDEO) && !vid_launch) {
594  vid_launch++;
595  vh.session_a = session_a;
596  vh.session_b = session_b;
599  launch_video(&vh);
600  } else {
601  if (switch_channel_test_flag(chan_a, CF_VIDEO)) {
603  }
604 
605  if (switch_channel_test_flag(chan_b, CF_VIDEO)) {
607  }
608  }
609 #endif
610 
611  if (read_frame_count >= DEFAULT_LEAD_FRAMES && switch_channel_media_ack(chan_a)) {
612  if (!played_banner && switch_channel_test_flag(chan_a, CF_VIDEO) && switch_channel_test_flag(chan_b, CF_VIDEO) &&
614  ++banner_counter > 100 &&
616  switch_channel_test_flag(chan_a, CF_BRIDGE_ORIGINATOR) && banner_file) {
617  const char *b_banner_file = switch_channel_get_variable(chan_b, "video_pre_call_banner");
618 
619  if (!b_banner_file) {
620  b_banner_file = switch_channel_get_variable(chan_a, "video_pre_call_banner_bleg");
621  }
622 
623 
626 
627  if (b_banner_file) {
630  } else {
632  }
633 
634  played_banner = 1;
635 
640  }
641 
642 
643 
644  if (!exec_check) {
646 
647  if (!inner_bridge) {
649  }
650  exec_check = 1;
651  }
652 
653  if (exec_app) {
654  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "%s Bridge execute app %s(%s)\n",
655  switch_channel_get_name(chan_a), exec_app, exec_data);
656 
657  switch_core_session_execute_application_async(session_a, exec_app, exec_data);
658  exec_app = exec_data = NULL;
659  }
660 
661  if ((bypass_media_after_bridge || switch_channel_test_flag(chan_b, CF_BYPASS_MEDIA_AFTER_BRIDGE)) && switch_channel_test_flag(chan_a, CF_ANSWERED)
663 
664  if (switch_true(switch_channel_get_variable_dup(chan_a, "bypass_media_after_bridge_oldschool", SWITCH_FALSE, -1))) {
666  } else {
668  }
670  goto end_of_bridge_loop;
671  }
672  }
673 
674  /* if 1 channel has DTMF pass it to the other */
675  while (switch_channel_has_dtmf(chan_a)) {
676  switch_dtmf_t dtmf = { 0, 0 };
677  if (switch_channel_dequeue_dtmf(chan_a, &dtmf) == SWITCH_STATUS_SUCCESS) {
678  int send_dtmf = 1;
679 
680  if (input_callback) {
681  switch_status_t cb_status = input_callback(session_a, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, user_data, 0);
682 
683  if (cb_status == SWITCH_STATUS_IGNORE) {
684  send_dtmf = 0;
685  } else if (cb_status != SWITCH_STATUS_SUCCESS) {
686  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "%s ended call via DTMF\n", switch_channel_get_name(chan_a));
688  goto end_of_bridge_loop;
689  }
690  }
691 
692  if (bridge_filter_dtmf) {
693  send_dtmf = 0;
694  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));
695  }
696 
697  if (send_dtmf) {
698  switch_core_session_send_dtmf(session_b, &dtmf);
700  }
701  }
702  }
703 
705  if (input_callback) {
706  input_callback(session_a, event, SWITCH_INPUT_TYPE_EVENT, user_data, 0);
707  }
708 
709  if ((event->event_id != SWITCH_EVENT_COMMAND && event->event_id != SWITCH_EVENT_MESSAGE)
710  || switch_core_session_receive_event(session_b, &event) != SWITCH_STATUS_SUCCESS) {
711  switch_event_destroy(&event);
712  }
713 
714  }
715 
716  if (!switch_channel_test_flag(chan_a, CF_ANSWERED) && answer_limit && switch_epoch_time_now(NULL) > answer_limit) {
717  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "Answer timeout hit on %s.\n", switch_channel_get_name(chan_a));
718  if (switch_true(switch_channel_get_variable_dup(chan_a, "continue_on_answer_timeout", SWITCH_FALSE, -1))) {
719  data->clean_exit = 1;
720  goto end_of_bridge_loop;
721  } else {
723  }
724  }
725 
726  if (!switch_channel_test_flag(chan_a, CF_ANSWERED)) {
727  if (originator) {
728  if (!ans_b && switch_channel_test_flag(chan_b, CF_ANSWERED)) {
729  switch_channel_pass_callee_id(chan_b, chan_a);
731  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "%s Media Establishment Failed.\n", switch_channel_get_name(chan_a));
732  goto end_of_bridge_loop;
733  }
734  ans_a = 1;
735  } else if (!pre_b && switch_channel_test_flag(chan_b, CF_EARLY_MEDIA)) {
737  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "%s Media Establishment Failed.\n", switch_channel_get_name(chan_a));
738  goto end_of_bridge_loop;
739  }
740  pre_b = 1;
741  }
742  if (!pre_b) {
743  switch_yield(10000);
744  continue;
745  }
746  } else {
747  ans_a = switch_channel_test_flag(chan_b, CF_ANSWERED);
748  }
749  }
750 
751  if (ans_a != ans_b) {
752  switch_channel_t *un = ans_a ? chan_b : chan_a;
753  switch_channel_t *a = un == chan_b ? chan_a : chan_b;
754 
756  if (switch_channel_direction(a) == SWITCH_CALL_DIRECTION_OUTBOUND || (un == chan_a && !originator)) {
758  }
759 
761  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "%s Media Establishment Failed.\n", switch_channel_get_name(un));
762  goto end_of_bridge_loop;
763  }
764 
765  if (ans_a) {
766  ans_b = 1;
767  } else {
768  ans_a = 1;
769  }
770  }
771  }
772 
773  if (originator && !ans_b) ans_b = switch_channel_test_flag(chan_b, CF_ANSWERED);
774 
775  if (originator && !sent_update && ans_a && ans_b && switch_channel_media_ack(chan_a) && switch_channel_media_ack(chan_b)) {
776  switch_ivr_bridge_display(session_a, session_b);
777  sent_update = 1;
778  }
779 #ifndef SWITCH_VIDEO_IN_THREADS
781  /* read video from 1 channel and write it to the other */
782  status = switch_core_session_read_video_frame(session_a, &read_frame, SWITCH_IO_FLAG_NONE, 0);
783 
784  if (!SWITCH_READ_ACCEPTABLE(status)) {
785  goto end_of_bridge_loop;
786  }
787 
789  }
790 #endif
791 
792  if (!switch_channel_test_flag(chan_a, CF_AUDIO)) {
793  switch_ivr_sleep(session_a, 5000, SWITCH_FALSE, NULL);
794  continue;
795  }
796 
797 
798  /* read audio from 1 channel and write it to the other */
799  status = switch_core_session_read_frame(session_a, &read_frame, SWITCH_IO_FLAG_NONE, stream_id);
800 
801  if (SWITCH_READ_ACCEPTABLE(status)) {
802  read_frame_count++;
803  if (switch_test_flag(read_frame, SFF_CNG)) {
804  if (silence_val) {
805  switch_generate_sln_silence((int16_t *) silence_frame.data, silence_frame.samples,
806  read_impl.number_of_channels, silence_val);
807  read_frame = &silence_frame;
808  } else if (!switch_channel_test_flag(chan_b, CF_ACCEPT_CNG)) {
809  continue;
810  }
811  }
812 
814  continue;
815  }
816 
818  if (switch_core_session_write_frame(session_b, read_frame, SWITCH_IO_FLAG_NONE, stream_id) != SWITCH_STATUS_SUCCESS) {
820  "%s ending bridge by request from write function\n", switch_channel_get_name(chan_b));
821  goto end_of_bridge_loop;
822  }
823  }
824  } else {
825  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));
826  goto end_of_bridge_loop;
827  }
828  }
829 
830  end_of_bridge_loop:
831 
833 
834 
835 #ifdef SWITCH_VIDEO_IN_THREADS
836  if (vh.up > 0) {
837  vh.up = -1;
839  //switch_channel_set_flag(chan_b, CF_NOT_READY);
842  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "Ending video thread.\n");
843  }
844 #endif
845 
846 
847  if (silence_val) {
848  switch_core_codec_destroy(&silence_codec);
849  }
850 
852 
853  if (!inner_bridge) {
855  }
856 
857  if (!inner_bridge && switch_channel_up_nosig(chan_a) && !switch_channel_test_flag(chan_a, CF_REDIRECT)) {
859  switch_caller_extension_t *extension = NULL;
860  if ((extension = switch_caller_extension_new(session_a, app_name, app_name)) == 0) {
861  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_CRIT, "memory error!\n");
862  goto end;
863  }
865 
866  switch_caller_extension_add_application(session_a, extension, (char *) app_name, app_arg);
867  switch_channel_set_caller_extension(chan_a, extension);
868 
869  if (switch_channel_get_state(chan_a) == CS_EXECUTE) {
871  } else {
873  }
874  }
875  }
876 
877  end:
878 
879 
881  if (th.up == 1) {
882  th.up = -1;
883  }
884 
885  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "Ending text thread.\n");
887  }
888 
889 #ifdef SWITCH_VIDEO_IN_THREADS
891  if (vh.up == 1) {
892  vh.up = -1;
893  }
894 
899 
900  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "Ending video thread.\n");
904  }
905 #endif
906 
907 
908 
911  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "BRIDGE THREAD DONE [%s]\n", switch_channel_get_name(chan_a));
913 
915  if (switch_channel_ready(chan_b) &&
917  const char *ext = switch_channel_get_variable(chan_a, "hold_hangup_xfer_exten");
918 
920 
921  if (zstr(ext)) {
923  if (cause == SWITCH_CAUSE_NONE) {
925  }
926  switch_channel_hangup(chan_b, cause);
927  } else {
929  }
930  }
931 
934  }
935  }
936 
939  }
940 
943 
945  data->done = 1;
948 
949  switch_core_session_rwunlock(session_b);
950  return NULL;
951 }
952 
953 static void transfer_after_bridge(switch_core_session_t *session, const char *where)
954 {
955  char *argv[4] = { 0 };
956  char *mydata;
957 
959 
960  if (!zstr(where) && (mydata = switch_core_session_strdup(session, where))) {
961  if (switch_separate_string(mydata, ':', argv, (sizeof(argv) / sizeof(argv[0]))) >= 1) {
962  switch_ivr_session_transfer(session, argv[0], argv[1], argv[2]);
963  } else {
964  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No extension specified.\n");
965  }
966  }
967 }
968 
970 {
972  switch_ivr_bridge_data_t *bd = switch_channel_get_private(channel, "_bridge_");
974  const char *var;
975 
976  if (bd) {
977  switch_channel_set_private(channel, "_bridge_", NULL);
978  if (bd->session == session && *bd->b_uuid) {
979  audio_bridge_thread(NULL, (void *) bd);
981  } else {
983  }
984  } else {
986  }
987  switch_channel_clear_state_handler(channel, &audio_bridge_peer_state_handlers);
988 
989  state = switch_channel_get_state(channel);
990 
992  !switch_channel_test_flag(channel, CF_XFER_ZOMBIE) && bd && !bd->clean_exit && state != CS_PARK && state != CS_ROUTING &&
994 
996  switch_ivr_park_session(session);
997  return SWITCH_STATUS_FALSE;
998  } else if (state < CS_HANGUP && (var = switch_channel_get_variable(channel, SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE))) {
999  transfer_after_bridge(session, var);
1000  return SWITCH_STATUS_FALSE;
1001  }
1002 
1003  if (switch_channel_test_flag(channel, CF_INTERCEPTED)) {
1006  return SWITCH_STATUS_FALSE;
1007  } else {
1008  if (switch_channel_test_flag(channel, CF_INTERCEPT)) {
1010  } else {
1011  if (!switch_channel_test_flag(channel, CF_ANSWERED)) {
1012  int x = 0;
1013 
1014  if (switch_channel_execute_on(channel, "execute_on_orphaned_bleg") == SWITCH_STATUS_SUCCESS) {
1015  x++;
1016  }
1017 
1018  if (switch_channel_api_on(channel, "api_on_orphaned_bleg") == SWITCH_STATUS_SUCCESS) {
1019  x++;
1020  }
1021 
1022  if (!x) {
1024  }
1025 
1026  } else {
1028  }
1029  }
1030  }
1031  }
1032 
1033  if (switch_channel_get_state(channel) == CS_EXCHANGE_MEDIA) {
1034  switch_channel_set_variable(channel, "park_timeout", "3");
1036  }
1037 
1038  return SWITCH_STATUS_FALSE;
1039 }
1040 
1042 {
1044 
1045  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CUSTOM ROUTING\n", switch_channel_get_name(channel));
1046 
1047  /* put the channel in a passive state so we can loop audio to it */
1049  return SWITCH_STATUS_FALSE;
1050 }
1051 
1053 {
1055 
1057 
1058  /* put the channel in a passive state so we can loop audio to it */
1059  return SWITCH_STATUS_FALSE;
1060 }
1061 
1062 static const switch_state_handler_table_t audio_bridge_peer_state_handlers = {
1063  /*.on_init */ NULL,
1064  /*.on_routing */ audio_bridge_on_routing,
1065  /*.on_execute */ NULL,
1066  /*.on_hangup */ NULL,
1067  /*.on_exchange_media */ audio_bridge_on_exchange_media,
1068  /*.on_soft_execute */ NULL,
1069  /*.on_consume_media */ audio_bridge_on_consume_media,
1070 };
1071 
1072 
1074 {
1075  switch_channel_t *channel;
1076  switch_channel_t *peer_channel = NULL;
1078 
1079  switch_assert(session);
1080  channel = switch_core_session_get_channel(session);
1081 
1083 
1084  if (peer_session) {
1085  peer_channel = switch_core_session_get_channel(peer_session);
1086  }
1087 
1088  status = switch_channel_wait_for_flag(channel, CF_ARRANGED_BRIDGE, SWITCH_FALSE, max_wait_ms, peer_channel);
1089 
1090  if (status == SWITCH_STATUS_FALSE) return status;
1091 
1094  return SWITCH_STATUS_FALSE;
1095  } else {
1097  if (!switch_channel_test_flag(channel, CF_TRANSFER)) {
1099  }
1100  }
1101 
1102  return SWITCH_STATUS_SUCCESS;
1103 }
1104 
1105 
1106 
1110 
1112  /*.on_init */ NULL,
1113  /*.on_routing */ NULL,
1114  /*.on_execute */ NULL,
1115  /*.on_hangup */ NULL,
1116  /*.on_exchange_media */ NULL,
1117  /*.on_soft_execute */ uuid_bridge_on_soft_execute,
1118  /*.on_consume_media */ uuid_bridge_on_hibernate,
1119  /*.on_hibernate */ uuid_bridge_on_hibernate,
1120  /*.on_reset */ uuid_bridge_on_reset
1121 };
1122 
1124 {
1126 
1128 
1130 
1131  cleanup_proxy_mode_b(session);
1132 
1135  }
1136 
1137  return SWITCH_STATUS_SUCCESS;
1138 }
1139 
1141 {
1143  return SWITCH_STATUS_FALSE;
1144 }
1145 
1147 {
1149  switch_core_session_t *other_session = NULL;
1150  const char *other_uuid = NULL;
1151 
1152  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CUSTOM SOFT_EXECUTE\n", switch_channel_get_name(channel));
1153  switch_channel_clear_state_handler(channel, &uuid_bridge_state_handlers);
1154 
1156  return SWITCH_STATUS_SUCCESS;
1157  }
1158 
1159  if ((other_uuid = switch_channel_get_variable(channel, SWITCH_UUID_BRIDGE)) && (other_session = switch_core_session_locate(other_uuid))) {
1160  switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
1161  switch_event_t *event;
1162  int ready_a, ready_b;
1163  switch_channel_state_t state, running_state;
1164  int max = 1000, loops = max;
1165 
1167 
1168  for (;;) {
1169  state = switch_channel_get_state(other_channel);
1170  running_state = switch_channel_get_running_state(other_channel);
1171 
1172  if (switch_channel_down_nosig(other_channel) || switch_channel_down(channel)) {
1173  break;
1174  }
1175 
1176  if (state < CS_HANGUP && state == running_state) {
1177 
1178  if (--loops < 1) {
1181  }
1182 
1183  if (running_state == CS_RESET) {
1184  switch_channel_set_state(other_channel, CS_SOFT_EXECUTE);
1185  }
1186 
1187  if (running_state == CS_SOFT_EXECUTE) {
1188 
1190  goto done;
1191  } else {
1192  break;
1193  }
1194  }
1195 
1196  } else {
1197  loops = max;
1198  }
1199 
1200  switch_yield(20000);
1201  }
1202 
1204 
1205  if (switch_ivr_wait_for_answer(session, other_session) != SWITCH_STATUS_SUCCESS) {
1206  if (switch_true(switch_channel_get_variable(channel, "uuid_bridge_continue_on_cancel"))) {
1208  } else if (switch_true(switch_channel_get_variable(channel, "uuid_bridge_park_on_cancel"))) {
1209  switch_ivr_park_session(session);
1210  } else if (!switch_channel_test_flag(channel, CF_TRANSFER)) {
1212  }
1213  goto done;
1214  }
1215 
1216  ready_a = switch_channel_ready(channel);
1217  ready_b = switch_channel_ready(other_channel);
1218 
1219  if (!ready_a || !ready_b) {
1220  if (!ready_a) {
1222  }
1223 
1224  if (!ready_b) {
1225  const char *cid = switch_channel_get_variable(other_channel, "rdnis");
1226  if (ready_a && cid) {
1227  switch_ivr_session_transfer(session, cid, NULL, NULL);
1228  } else {
1230  }
1231  }
1232  goto done;
1233  }
1234 
1235  /* fire events that will change the data table from "show channels" */
1237  switch_channel_event_set_data(channel, event);
1238  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application", "uuid_bridge");
1239  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-Data", switch_core_session_get_uuid(other_session));
1240  switch_event_fire(&event);
1241  }
1242 
1244  switch_channel_event_set_data(other_channel, event);
1245  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application", "uuid_bridge");
1247  switch_event_fire(&event);
1248  }
1249 
1250  switch_ivr_multi_threaded_bridge(session, other_session, NULL, NULL, NULL);
1251 
1252  state = switch_channel_get_state(channel);
1253  if (!switch_channel_test_flag(channel, CF_TRANSFER) &&
1254  !switch_channel_test_flag(channel, CF_REDIRECT) && state < CS_HANGUP && state != CS_ROUTING && state != CS_PARK) {
1256  }
1257  } else {
1258  int hup = 1;
1259  const char *var;
1260 
1262  switch_ivr_park_session(session);
1263  hup = 0;
1265  transfer_after_bridge(session, var);
1266  hup = 0;
1267  }
1268 
1269  if (hup) {
1271  }
1272  }
1273 
1274  done:
1275 
1276  if (other_session) {
1277  switch_core_session_rwunlock(other_session);
1278  other_session = NULL;
1279  }
1280 
1282 
1283  return SWITCH_STATUS_FALSE;
1284 }
1285 
1287 {
1288  switch_channel_t *channel = NULL;
1289  char *key;
1290 
1291  channel = switch_core_session_get_channel(session);
1292  switch_assert(channel != NULL);
1293 
1294  if ((key = (char *) switch_channel_get_private(channel, "__bridge_term_key")) && dtmf->digit == *key) {
1295  const char *uuid;
1296  switch_core_session_t *other_session;
1297 
1300  } else {
1301  if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE)) && (other_session = switch_core_session_locate(uuid))) {
1302  switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
1303  switch_channel_set_state(other_channel, CS_EXECUTE);
1304  switch_core_session_rwunlock(other_session);
1305  } else {
1306  return SWITCH_STATUS_SUCCESS;
1307  }
1308  }
1309 
1310  return SWITCH_STATUS_FALSE;
1311  }
1312 
1313  return SWITCH_STATUS_SUCCESS;
1314 }
1315 
1317 {
1318  switch_core_session_message_t *msg = NULL;
1319  switch_channel_t *channel = NULL;
1320  switch_event_t *event;
1321 
1322  channel = switch_core_session_get_channel(session);
1323 
1327  switch_channel_event_set_data(channel, event);
1328  switch_event_fire(&event);
1329  }
1330  }
1331 
1332 
1333  msg = switch_core_session_alloc(session, sizeof(*msg));
1334  MESSAGE_STAMP_FFL(msg);
1336  msg->from = __FILE__;
1338  switch_core_session_queue_message(session, msg);
1339 
1340  switch_core_event_hook_remove_state_change(session, hanguphook);
1341 
1342  return SWITCH_STATUS_SUCCESS;
1343 
1344 }
1345 
1347 {
1348  switch_channel_t *channel = NULL;
1349  const char *key;
1350  switch_core_session_message_t msg = { 0 };
1351  switch_event_t *event = NULL;
1352  switch_ivr_dmachine_t *dmachine[2] = { 0 };
1353 
1354  channel = switch_core_session_get_channel(session);
1355  switch_assert(channel != NULL);
1356 
1358  msg.from = __FILE__;
1360 
1361  switch_core_event_hook_add_state_change(session, hanguphook);
1362 
1363  switch_core_session_receive_message(session, &msg);
1364 
1365  if ((key = switch_channel_get_variable(channel, "bridge_terminate_key"))) {
1366  switch_channel_set_private(channel, "__bridge_term_key", switch_core_session_strdup(session, key));
1367  switch_core_event_hook_add_recv_dtmf(session, sb_on_dtmf);
1368  }
1369 
1372 
1374 
1375 
1378  switch_core_session_t *other_session;
1379 
1381  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", msg.string_arg);
1382  switch_channel_event_set_data(channel, event);
1383  if ((other_session = switch_core_session_locate(msg.string_arg))) {
1384  switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
1385 
1386  switch_channel_set_bridge_time(other_channel);
1387 
1388  switch_event_add_presence_data_cols(other_channel, event, "Bridge-B-PD-");
1389  switch_core_session_rwunlock(other_session);
1390  }
1391  switch_event_fire(&event);
1392  }
1393  }
1394 
1395  if ((dmachine[0] = switch_core_session_get_dmachine(session, DIGIT_TARGET_SELF)) ||
1396  (dmachine[1] = switch_core_session_get_dmachine(session, DIGIT_TARGET_PEER))) {
1398  "%s not hibernating due to active digit parser, semi-hibernation engaged.\n", switch_channel_get_name(channel));
1399 
1400  while(switch_channel_ready(channel) && switch_channel_get_state(channel) == CS_HIBERNATE) {
1401  if (!switch_channel_test_flag(channel, CF_BROADCAST)) {
1402  if (dmachine[0]) {
1403  switch_ivr_dmachine_ping(dmachine[0], NULL);
1404  }
1405  if (dmachine[1]) {
1406  switch_ivr_dmachine_ping(dmachine[1], NULL);
1407  }
1408  }
1409  switch_yield(20000);
1411  }
1412  }
1413 
1414 
1415  return SWITCH_STATUS_SUCCESS;
1416 }
1417 
1419 {
1420  const char *uuid;
1422  switch_core_session_t *other_session;
1423  switch_event_t *event;
1424 
1427  }
1428 
1429  if (switch_channel_get_private(channel, "__bridge_term_key")) {
1430  switch_core_event_hook_remove_recv_dtmf(session, sb_on_dtmf);
1431  switch_channel_set_private(channel, "__bridge_term_key", NULL);
1432  }
1433 
1435 
1436  if (uuid && (other_session = switch_core_session_locate(uuid))) {
1437  switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
1438  const char *sbv = switch_channel_get_variable(other_channel, SWITCH_SIGNAL_BRIDGE_VARIABLE);
1439  const char *var;
1440 
1441  if (!zstr(sbv) && !strcmp(sbv, switch_core_session_get_uuid(session))) {
1442  int hup = 1;
1443 
1446  switch_channel_set_variable(other_channel, "call_uuid", switch_core_session_get_uuid(other_session));
1447 
1448  if (switch_channel_up_nosig(other_channel)) {
1450  switch_ivr_park_session(other_session);
1451  hup = 0;
1452  } else if ((var = switch_channel_get_variable(other_channel, SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE))) {
1453  transfer_after_bridge(other_session, var);
1454  hup = 0;
1455  }
1456 
1457  if (hup) {
1458  if (switch_channel_test_flag(other_channel, CF_BRIDGE_ORIGINATOR)) {
1459  if (switch_channel_test_flag(channel, CF_ANSWERED) &&
1461 
1462  if (switch_channel_test_flag(channel, CF_INTERCEPTED)) {
1463  switch_channel_set_flag(other_channel, CF_INTERCEPT);
1464  }
1465  switch_channel_hangup(other_channel, switch_channel_get_cause(channel));
1466  } else {
1467  if (!switch_channel_test_flag(channel, CF_ANSWERED)) {
1468  switch_channel_handle_cause(other_channel, switch_channel_get_cause(channel));
1469  }
1470  switch_channel_set_state(other_channel, CS_EXECUTE);
1471  }
1472  } else {
1473  switch_channel_hangup(other_channel, switch_channel_get_cause(channel));
1474  }
1475  }
1476  }
1477  }
1478 
1483  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", uuid);
1484  switch_event_add_presence_data_cols(other_channel, event, "Bridge-B-PD-");
1485  switch_channel_event_set_data(channel, event);
1486  switch_event_fire(&event);
1487  }
1488  }
1489 
1490  switch_core_session_rwunlock(other_session);
1491  } else {
1496  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", uuid);
1497  switch_channel_event_set_data(channel, event);
1498  switch_event_fire(&event);
1499  }
1500  }
1501  }
1502 
1503  return SWITCH_STATUS_SUCCESS;
1504 }
1505 
1507  /*.on_init */ NULL,
1508  /*.on_routing */ NULL,
1509  /*.on_execute */ NULL,
1510  /*.on_hangup */ signal_bridge_on_hangup,
1511  /*.on_exchange_media */ NULL,
1512  /*.on_soft_execute */ NULL,
1513  /*.on_consume_media */ NULL,
1514  /*.on_hibernate */ signal_bridge_on_hibernate
1515 };
1516 
1517 static void check_bridge_export(switch_channel_t *channel, switch_channel_t *peer_channel)
1518 {
1519  switch_caller_profile_t *originator_cp, *originatee_cp;
1520 
1521  originator_cp = switch_channel_get_caller_profile(channel);
1522  originatee_cp = switch_channel_get_caller_profile(peer_channel);
1523 
1524  originator_cp->callee_id_name = switch_core_strdup(originator_cp->pool, originatee_cp->callee_id_name);
1525  originator_cp->callee_id_number = switch_core_strdup(originator_cp->pool, originatee_cp->callee_id_number);
1526 
1527 
1530 }
1531 
1533 {
1534  switch_channel_t *caller_channel = switch_core_session_get_channel(session);
1535  switch_channel_t *peer_channel = switch_core_session_get_channel(peer_session);
1536  switch_event_t *event;
1537 
1538  if (switch_channel_down_nosig(peer_channel)) {
1539  switch_channel_hangup(caller_channel, switch_channel_get_cause(peer_channel));
1540  return SWITCH_STATUS_FALSE;
1541  }
1542 
1543  if (!switch_channel_up_nosig(caller_channel)) {
1545  return SWITCH_STATUS_FALSE;
1546  }
1547 
1548  check_bridge_export(caller_channel, peer_channel);
1549 
1552 
1555  switch_channel_set_variable(peer_channel, "call_uuid", switch_core_session_get_uuid(session));
1556 
1559 
1560  switch_channel_clear_state_handler(caller_channel, NULL);
1561  switch_channel_clear_state_handler(peer_channel, NULL);
1562 
1563  switch_channel_add_state_handler(caller_channel, &signal_bridge_state_handlers);
1564  switch_channel_add_state_handler(peer_channel, &signal_bridge_state_handlers);
1565 
1566  switch_channel_set_variable(caller_channel, "signal_bridge", "true");
1567  switch_channel_set_variable(peer_channel, "signal_bridge", "true");
1568 
1569  /* fire events that will change the data table from "show channels" */
1571  switch_channel_event_set_data(caller_channel, event);
1572  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application", "signal_bridge");
1573  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-Data", switch_core_session_get_uuid(peer_session));
1574  switch_event_fire(&event);
1575  }
1576 
1578  switch_channel_event_set_data(peer_channel, event);
1579  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application", "signal_bridge");
1581  switch_event_fire(&event);
1582  }
1583 
1584  switch_channel_set_state_flag(caller_channel, CF_RESET);
1585  switch_channel_set_state_flag(peer_channel, CF_RESET);
1586 
1587  switch_channel_set_state(caller_channel, CS_HIBERNATE);
1588  switch_channel_set_state(peer_channel, CS_HIBERNATE);
1589 
1590 #if 0
1591  if (switch_channel_test_flag(caller_channel, CF_BRIDGED)) {
1592  switch_channel_set_flag(caller_channel, CF_TRANSFER);
1593  switch_channel_set_flag(peer_channel, CF_TRANSFER);
1594  }
1595 #endif
1596 
1597  switch_ivr_bridge_display(session, peer_session);
1598 
1599  return SWITCH_STATUS_SUCCESS;
1600 }
1601 
1602 static void abort_call(switch_channel_t *caller_channel, switch_channel_t *peer_channel)
1603 {
1604  switch_call_cause_t cause = switch_channel_get_cause(caller_channel);
1605 
1606  if (!cause) {
1608  }
1609 
1610  switch_channel_hangup(peer_channel, cause);
1611 }
1612 
1614  switch_core_session_t *peer_session,
1615  switch_input_callback_function_t input_callback, void *session_data,
1616  void *peer_session_data)
1617 {
1618  switch_ivr_bridge_data_t *a_leg = switch_core_session_alloc(session, sizeof(*a_leg));
1619  switch_ivr_bridge_data_t *b_leg = switch_core_session_alloc(peer_session, sizeof(*b_leg));
1620  switch_channel_t *caller_channel = switch_core_session_get_channel(session);
1621  switch_channel_t *peer_channel = switch_core_session_get_channel(peer_session);
1622  int stream_id = 0;
1625  switch_event_t *event;
1626  int br = 0;
1627  int inner_bridge = switch_channel_test_flag(caller_channel, CF_INNER_BRIDGE);
1628  const char *var;
1629  switch_call_cause_t cause;
1630  switch_core_session_message_t msg = { 0 };
1631 
1632  if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE)) {
1633  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Call has no media... Redirecting to signal bridge.\n");
1634  return switch_ivr_signal_bridge(session, peer_session);
1635  }
1636 
1637  check_bridge_export(caller_channel, peer_channel);
1638 
1641 
1644 
1645  switch_channel_audio_sync(caller_channel);
1646  switch_channel_audio_sync(peer_channel);
1647 
1648  b_leg->session = peer_session;
1649  switch_copy_string(b_leg->b_uuid, switch_core_session_get_uuid(session), sizeof(b_leg->b_uuid));
1650  b_leg->stream_id = stream_id;
1651  b_leg->input_callback = input_callback;
1652  b_leg->session_data = peer_session_data;
1653  b_leg->clean_exit = 0;
1654  b_leg->other_leg_data = a_leg;
1655 
1656  a_leg->session = session;
1657  switch_copy_string(a_leg->b_uuid, switch_core_session_get_uuid(peer_session), sizeof(a_leg->b_uuid));
1658  a_leg->stream_id = stream_id;
1659  a_leg->input_callback = input_callback;
1660  a_leg->session_data = session_data;
1661  a_leg->clean_exit = 0;
1662  a_leg->other_leg_data = b_leg;
1663 
1664  switch_channel_add_state_handler(peer_channel, &audio_bridge_peer_state_handlers);
1665 
1666  if (switch_channel_test_flag(peer_channel, CF_ANSWERED) && !switch_channel_test_flag(caller_channel, CF_ANSWERED)) {
1667  switch_channel_pass_callee_id(peer_channel, caller_channel);
1668  switch_channel_answer(caller_channel);
1669  }
1670 
1671  if (switch_channel_test_flag(peer_channel, CF_ANSWERED) || switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA) ||
1672  switch_channel_test_flag(peer_channel, CF_RING_READY)) {
1673  const char *app, *data;
1674 
1675  if (!switch_channel_ready(caller_channel)) {
1676  abort_call(caller_channel, peer_channel);
1677  goto done;
1678  }
1679 
1680  if (!switch_channel_test_flag(peer_channel, CF_ARRANGED_BRIDGE)) {
1682  }
1683 
1684  switch_channel_set_variable(peer_channel, "call_uuid", switch_core_session_get_uuid(session));
1685 
1686  switch_channel_set_bridge_time(caller_channel);
1687  switch_channel_set_bridge_time(peer_channel);
1688 
1691  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", switch_core_session_get_uuid(peer_session));
1692  switch_channel_event_set_data(caller_channel, event);
1693  switch_event_add_presence_data_cols(peer_channel, event, "Bridge-B-PD-");
1694  switch_event_fire(&event);
1695  br = 1;
1696  }
1697 
1703 
1704  if (!switch_channel_ready(caller_channel)) {
1705  abort_call(caller_channel, peer_channel);
1706  switch_core_session_rwunlock(peer_session);
1707  goto done;
1708  }
1709 
1710  if (!switch_channel_media_ready(caller_channel) ||
1711  (!switch_channel_test_flag(peer_channel, CF_ANSWERED) && !switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA))) {
1712  if ((status = switch_ivr_wait_for_answer(session, peer_session)) != SWITCH_STATUS_SUCCESS || !switch_channel_ready(caller_channel)) {
1713  switch_channel_state_t w_state = switch_channel_get_state(caller_channel);
1715  if (w_state < CS_HANGUP && w_state != CS_ROUTING && w_state != CS_PARK &&
1716  !switch_channel_test_flag(caller_channel, CF_REDIRECT) && !switch_channel_test_flag(caller_channel, CF_TRANSFER) &&
1717  w_state != CS_EXECUTE) {
1718  const char *ext = switch_channel_get_variable(peer_channel, "original_destination_number");
1719  if (!ext) {
1720  ext = switch_channel_get_variable(peer_channel, "destination_number");
1721  }
1722 
1723  if (ext) {
1724  switch_ivr_session_transfer(session, ext, NULL, NULL);
1725  } else {
1727  }
1728  }
1729  abort_call(caller_channel, peer_channel);
1730  switch_core_session_rwunlock(peer_session);
1731  goto done;
1732  }
1733  }
1734 
1735  if (switch_channel_test_flag(peer_channel, CF_ANSWERED) && !switch_channel_test_flag(caller_channel, CF_ANSWERED)) {
1736  switch_channel_answer(caller_channel);
1737  }
1738 
1739  switch_channel_wait_for_flag(peer_channel, CF_BROADCAST, SWITCH_FALSE, 10000, caller_channel);
1740  switch_ivr_parse_all_events(peer_session);
1741  switch_ivr_parse_all_events(session);
1742 
1744  msg.from = __FILE__;
1746 
1747  if (switch_core_session_receive_message(peer_session, &msg) != SWITCH_STATUS_SUCCESS) {
1748  status = SWITCH_STATUS_FALSE;
1749  abort_call(caller_channel, peer_channel);
1750  switch_core_session_rwunlock(peer_session);
1751  goto done;
1752  }
1753 
1756  status = SWITCH_STATUS_FALSE;
1757  abort_call(caller_channel, peer_channel);
1758  switch_core_session_rwunlock(peer_session);
1759  goto done;
1760  }
1761 
1768 
1769  if ((app = switch_channel_get_variable(caller_channel, "bridge_pre_execute_aleg_app"))) {
1770  switch_channel_set_variable(caller_channel, "bridge_pre_execute_app", app);
1771 
1772  if ((data = switch_channel_get_variable(caller_channel, "bridge_pre_execute_aleg_data"))) {
1773  switch_channel_set_variable(caller_channel, "bridge_pre_execute_data", data);
1774  }
1775  }
1776 
1777  if ((app = switch_channel_get_variable(caller_channel, "bridge_pre_execute_bleg_app"))) {
1778  switch_channel_set_variable(peer_channel, "bridge_pre_execute_app", app);
1779 
1780  if ((data = switch_channel_get_variable(caller_channel, "bridge_pre_execute_bleg_data"))) {
1781  switch_channel_set_variable(peer_channel, "bridge_pre_execute_data", data);
1782  }
1783 
1784  }
1785 
1786  switch_channel_set_private(peer_channel, "_bridge_", b_leg);
1787 
1788  if (switch_channel_test_flag(peer_channel, CF_ARRANGED_BRIDGE)) {
1790  } else {
1792  }
1793 
1794  audio_bridge_thread(NULL, (void *) a_leg);
1795 
1797 
1798  switch_channel_stop_broadcast(peer_channel);
1799 
1800 
1801  while (switch_channel_get_state(peer_channel) == CS_EXCHANGE_MEDIA) {
1803  switch_cond_next();
1804  }
1805 
1806  if (inner_bridge) {
1807  if (switch_channel_ready(caller_channel)) {
1808  switch_channel_set_flag(caller_channel, CF_BRIDGED);
1809  }
1810 
1811  if (switch_channel_ready(peer_channel)) {
1812  switch_channel_set_flag(peer_channel, CF_BRIDGED);
1813  }
1814  }
1815 
1816  if ((cause = switch_channel_get_cause(caller_channel))) {
1818  }
1819 
1820  if ((cause = switch_channel_get_cause(peer_channel))) {
1822  }
1823 
1824  if (switch_channel_down_nosig(peer_channel)) {
1827 
1828  if (copy_xml_cdr || copy_json_cdr) {
1829  char *cdr_text = NULL;
1830 
1831  switch_channel_wait_for_state(peer_channel, caller_channel, CS_DESTROY);
1832 
1833  if (copy_xml_cdr) {
1834  switch_xml_t cdr = NULL;
1835 
1836  if (switch_ivr_generate_xml_cdr(peer_session, &cdr) == SWITCH_STATUS_SUCCESS) {
1837  cdr_text = switch_xml_toxml(cdr, SWITCH_FALSE);
1838  switch_xml_free(cdr);
1839  }
1840  }
1841  if (copy_json_cdr) {
1842  cJSON *cdr = NULL;
1843 
1844  if (switch_ivr_generate_json_cdr(peer_session, &cdr, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) {
1845  cdr_text = cJSON_PrintUnformatted(cdr);
1846  cJSON_Delete(cdr);
1847  }
1848  }
1849 
1850  if (cdr_text) {
1851  switch_channel_set_variable(caller_channel, "b_leg_cdr", cdr_text);
1852  switch_channel_set_variable_name_printf(caller_channel, cdr_text, "b_leg_cdr_%s", switch_core_session_get_uuid(peer_session));
1853  switch_safe_free(cdr_text);
1854  }
1855  }
1856 
1857  }
1858 
1859  switch_core_session_rwunlock(peer_session);
1860 
1861  } else {
1862  status = SWITCH_STATUS_FALSE;
1863  }
1864  } else {
1865  status = SWITCH_STATUS_FALSE;
1866  }
1867 
1868  if (status != SWITCH_STATUS_SUCCESS) {
1869  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Bridge Failed %s->%s\n",
1870  switch_channel_get_name(caller_channel), switch_channel_get_name(peer_channel)
1871  );
1873  }
1874 
1875  done:
1876 
1877  switch_channel_set_variable(peer_channel, "call_uuid", switch_core_session_get_uuid(peer_session));
1878 
1881  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", switch_core_session_get_uuid(peer_session));
1882  switch_channel_event_set_data(caller_channel, event);
1883  switch_event_add_presence_data_cols(peer_channel, event, "Bridge-B-PD-");
1884  switch_event_fire(&event);
1885  }
1886 
1888  msg.from = __FILE__;
1890  switch_core_session_receive_message(peer_session, &msg);
1891 
1893  switch_core_session_receive_message(session, &msg);
1894 
1895  state = switch_channel_get_state(caller_channel);
1896 
1897  if (!switch_channel_test_flag(caller_channel, CF_TRANSFER) && !switch_channel_test_flag(caller_channel, CF_REDIRECT) &&
1898  !switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE) && !a_leg->clean_exit && !inner_bridge) {
1899  switch_call_cause_t cause = switch_channel_get_cause(peer_channel);
1900  const char *hup = switch_channel_get_variable(caller_channel, SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE);
1901  int explicit = 0;
1902  int answered = 0;
1903  int early = 0;
1904 
1905  if (cause == SWITCH_CAUSE_NONE) {
1907  }
1908 
1909  if (hup) {
1910  explicit = !strcasecmp(hup, "explicit");
1911  }
1912 
1913  if (!switch_channel_test_flag(peer_channel, CF_ANSWERED)) {
1914  switch_channel_handle_cause(caller_channel, cause);
1915  }
1916 
1917  if (explicit) {
1918  if (switch_channel_test_flag(peer_channel, CF_INTERCEPTED)) {
1919  switch_channel_set_flag(peer_channel, CF_INTERCEPT);
1920  }
1921  switch_channel_hangup(caller_channel, cause);
1922  }
1923 
1924  answered = switch_channel_test_flag(peer_channel, CF_ANSWERED);
1925  early = switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA);
1926 
1927  if ((state != CS_EXECUTE && state != CS_SOFT_EXECUTE && state != CS_PARK && state != CS_ROUTING) || ((answered || early) && state < CS_HANGUP)) {
1928 
1929  if (!switch_channel_test_flag(caller_channel, CF_TRANSFER)) {
1930 
1931  if ((answered && switch_true(switch_channel_get_variable(caller_channel, SWITCH_PARK_AFTER_BRIDGE_VARIABLE))) ||
1933  switch_ivr_park_session(session);
1934  } else if ((answered && (var = switch_channel_get_variable(caller_channel, SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE))) ||
1936  transfer_after_bridge(session, var);
1937  } else if (answered) {
1938  if (switch_true(hup)) {
1939  if (switch_channel_test_flag(peer_channel, CF_INTERCEPTED)) {
1940  switch_channel_set_flag(peer_channel, CF_INTERCEPT);
1941  }
1942  switch_channel_hangup(caller_channel, cause);
1943  }
1944  }
1945  }
1946  }
1947  }
1948 
1949  if (switch_channel_test_flag(caller_channel, CF_REDIRECT)) {
1950  if (switch_channel_test_flag(caller_channel, CF_RESET)) {
1951  switch_channel_clear_flag(caller_channel, CF_RESET);
1952  } else {
1953  state = switch_channel_get_state(caller_channel);
1954  if (!(state == CS_RESET || state == CS_PARK || state == CS_ROUTING || state == CS_EXECUTE)) {
1955  switch_channel_set_state(caller_channel, CS_RESET);
1956  }
1957  }
1958  }
1959 
1960  return status;
1961 }
1962 
1964 {
1966 
1967  if (switch_channel_test_flag(channel, CF_PROXY_MODE) &&
1970  }
1971 }
1972 
1973 
1975 {
1976  switch_core_session_t *sbsession;
1978  int done = 0;
1979 
1982  if (switch_core_session_get_partner(session, &sbsession) == SWITCH_STATUS_SUCCESS) {
1983  switch_channel_t *sbchannel = switch_core_session_get_channel(sbsession);
1984 
1985  if (switch_channel_test_flag(sbchannel, CF_PROXY_MODE)) {
1986  /* Clear this now, otherwise will cause the one we're interested in to hang up too...*/
1989  } else {
1990  done = 1;
1991  }
1992  switch_core_session_rwunlock(sbsession);
1993  }
1994  }
1995 
1996  if (done) return;
1997 
2001 
2002 }
2003 
2004 
2005 SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uuid, const char *originatee_uuid)
2006 {
2007  switch_core_session_t *originator_session, *originatee_session, *swap_session;
2008  switch_channel_t *originator_channel, *originatee_channel, *swap_channel;
2010  switch_caller_profile_t *originator_cp, *originatee_cp;
2012 
2013  if ((originator_session = switch_core_session_locate(originator_uuid))) {
2014  if ((originatee_session = switch_core_session_locate(originatee_uuid))) {
2015  originator_channel = switch_core_session_get_channel(originator_session);
2016  originatee_channel = switch_core_session_get_channel(originatee_session);
2017 
2018  switch_ivr_check_hold(originator_session);
2019  switch_ivr_check_hold(originatee_session);
2020 
2021 
2022  if (switch_channel_test_flag(originator_channel, CF_LEG_HOLDING)) {
2023  switch_channel_set_flag(originator_channel, CF_HOLD_ON_BRIDGE);
2024  }
2025 
2026  if (switch_channel_test_flag(originatee_channel, CF_LEG_HOLDING)) {
2027  switch_channel_set_flag(originatee_channel, CF_HOLD_ON_BRIDGE);
2028  }
2029 
2030 
2031  if (switch_channel_direction(originator_channel) == SWITCH_CALL_DIRECTION_OUTBOUND && !switch_channel_test_flag(originator_channel, CF_DIALPLAN)) {
2032  if (!switch_channel_test_flag(originator_channel, CF_RECOVERING_BRIDGE)) {
2033  switch_channel_flip_cid(originator_channel);
2034  }
2035  switch_channel_set_flag(originator_channel, CF_DIALPLAN);
2036  }
2037 
2038  if (switch_channel_down_nosig(originator_channel)) {
2039  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));
2040  switch_core_session_rwunlock(originator_session);
2041  switch_core_session_rwunlock(originatee_session);
2042  return SWITCH_STATUS_FALSE;
2043  }
2044 
2045  if (!switch_channel_media_up(originator_channel)) {
2046  if (switch_channel_media_up(originatee_channel)) {
2047  swap_session = originator_session;
2048  originator_session = originatee_session;
2049  originatee_session = swap_session;
2050 
2051  swap_channel = originator_channel;
2052  originator_channel = originatee_channel;
2053  originatee_channel = swap_channel;
2054  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originatee_session), SWITCH_LOG_WARNING, "reversing order of channels so this will work!\n");
2055  } else {
2056  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originator_session), SWITCH_LOG_CRIT, "Neither channel is answered, cannot bridge them.\n");
2057  switch_core_session_rwunlock(originator_session);
2058  switch_core_session_rwunlock(originatee_session);
2059  return SWITCH_STATUS_FALSE;
2060  }
2061  }
2062 
2063  if (switch_channel_direction(originatee_channel) == SWITCH_CALL_DIRECTION_OUTBOUND && switch_channel_test_flag(originatee_channel, CF_DIALPLAN)) {
2064  switch_channel_clear_flag(originatee_channel, CF_DIALPLAN);
2065  }
2066 
2067  cleanup_proxy_mode_a(originator_session);
2068  cleanup_proxy_mode_a(originatee_session);
2069 
2070  /* override transmit state for originator_channel to bridge to originatee_channel
2071  * install pointer to originatee_session into originator_channel
2072  * set CF_TRANSFER on both channels and change state to CS_SOFT_EXECUTE to
2073  * interrupt anything they are already doing.
2074  * originatee_session will fall asleep and originator_session will bridge to it
2075  */
2076 
2077  switch_channel_set_flag(originator_channel, CF_REDIRECT);
2078  switch_channel_set_flag(originatee_channel, CF_REDIRECT);
2079 
2080 
2081  switch_channel_set_variable(originator_channel, SWITCH_UUID_BRIDGE, switch_core_session_get_uuid(originatee_session));
2088 
2089 
2090  originator_cp = switch_channel_get_caller_profile(originator_channel);
2091  originatee_cp = switch_channel_get_caller_profile(originatee_channel);
2092 
2093 
2094 
2095  if (switch_channel_outbound_display(originator_channel)) {
2096  switch_channel_invert_cid(originator_channel);
2097 
2098  if (switch_channel_direction(originator_channel) == SWITCH_CALL_DIRECTION_INBOUND) {
2099  switch_channel_clear_flag(originatee_channel, CF_BLEG);
2100  }
2101  }
2102 
2103  if (switch_channel_inbound_display(originatee_channel)) {
2104  switch_channel_invert_cid(originatee_channel);
2105 
2106  if (switch_channel_direction(originatee_channel) == SWITCH_CALL_DIRECTION_INBOUND) {
2107  switch_channel_set_flag(originatee_channel, CF_BLEG);
2108  }
2109 
2110  }
2111 
2112 
2113  switch_channel_set_variable(originatee_channel, "original_destination_number", originatee_cp->destination_number);
2114  switch_channel_set_variable(originatee_channel, "original_caller_id_name", originatee_cp->caller_id_name);
2115  switch_channel_set_variable(originatee_channel, "original_caller_id_number", originatee_cp->caller_id_number);
2116 
2117  switch_channel_set_variable(originator_channel, "original_destination_number", originator_cp->destination_number);
2118  switch_channel_set_variable(originator_channel, "original_caller_id_name", originator_cp->caller_id_name);
2119  switch_channel_set_variable(originator_channel, "original_caller_id_number", originator_cp->caller_id_number);
2120 
2121  switch_channel_step_caller_profile(originatee_channel);
2122  switch_channel_step_caller_profile(originator_channel);
2123 
2124  originator_cp = switch_channel_get_caller_profile(originator_channel);
2125  originatee_cp = switch_channel_get_caller_profile(originatee_channel);
2126 
2127 
2128 #ifdef DEEP_DEBUG_CID
2129  {
2130  switch_event_t *event;
2131 
2133  //switch_channel_event_set_basic_data(originator_channel, event);
2134  switch_caller_profile_event_set_data(originator_cp, "ORIGINATOR", event);
2135  switch_caller_profile_event_set_data(originatee_cp, "ORIGINATEE", event);
2136  DUMP_EVENT(event);
2137  switch_event_destroy(&event);
2138  }
2139  }
2140 #endif
2141 
2142  switch_channel_set_originator_caller_profile(originatee_channel, switch_caller_profile_clone(originatee_session, originator_cp));
2143  switch_channel_set_originatee_caller_profile(originator_channel, switch_caller_profile_clone(originator_session, originatee_cp));
2144 
2145  originator_cp->callee_id_name = switch_core_strdup(originator_cp->pool, originatee_cp->callee_id_name);
2146  originator_cp->callee_id_number = switch_core_strdup(originator_cp->pool, originatee_cp->callee_id_number);
2147 
2148  originatee_cp->caller_id_name = switch_core_strdup(originatee_cp->pool, originator_cp->caller_id_name);
2149  originatee_cp->caller_id_number = switch_core_strdup(originatee_cp->pool, originator_cp->caller_id_number);
2150 
2151 #ifdef DEEP_DEBUG_CID
2152  {
2153  switch_event_t *event;
2154 
2156  //switch_channel_event_set_basic_data(originator_channel, event);
2157  switch_caller_profile_event_set_data(originator_cp, "POST-ORIGINATOR", event);
2158  switch_caller_profile_event_set_data(originatee_cp, "POST-ORIGINATEE", event);
2159  DUMP_EVENT(event);
2160  switch_event_destroy(&event);
2161  }
2162  }
2163 #endif
2164 
2165  switch_channel_stop_broadcast(originator_channel);
2166  switch_channel_stop_broadcast(originatee_channel);
2167 
2168  switch_channel_set_flag(originator_channel, CF_TRANSFER);
2169  switch_channel_set_flag(originatee_channel, CF_TRANSFER);
2170 
2171 
2172  switch_channel_clear_flag(originator_channel, CF_ORIGINATING);
2173  switch_channel_clear_flag(originatee_channel, CF_ORIGINATING);
2174 
2175 
2176  originator_cp->transfer_source = switch_core_sprintf(originator_cp->pool,
2177  "%ld:%s:uuid_br:%s", (long)switch_epoch_time_now(NULL), originator_cp->uuid_str,
2178  switch_core_session_get_uuid(originatee_session));
2182 
2183 
2184  originatee_cp->transfer_source = switch_core_sprintf(originatee_cp->pool,
2185  "%ld:%s:uuid_br:%s", (long)switch_epoch_time_now(NULL), originatee_cp->uuid_str,
2186  switch_core_session_get_uuid(originator_session));
2190 
2191  /* change the states and let the chips fall where they may */
2192 
2193  //switch_channel_set_variable(originator_channel, SWITCH_PARK_AFTER_BRIDGE_VARIABLE, NULL);
2194  //switch_channel_set_variable(originatee_channel, SWITCH_PARK_AFTER_BRIDGE_VARIABLE, NULL);
2195  switch_channel_clear_state_handler(originator_channel, NULL);
2196  switch_channel_clear_state_handler(originatee_channel, NULL);
2197 
2198 
2199 
2202 
2206 
2207  switch_channel_add_state_handler(originator_channel, &uuid_bridge_state_handlers);
2208  switch_channel_add_state_handler(originatee_channel, &uuid_bridge_state_handlers);
2209 
2210  state = switch_channel_get_state(originator_channel);
2211  switch_channel_set_state(originator_channel, state == CS_HIBERNATE ? CS_CONSUME_MEDIA : CS_HIBERNATE);
2212  state = switch_channel_get_state(originatee_channel);
2213  switch_channel_set_state(originatee_channel, state == CS_HIBERNATE ? CS_CONSUME_MEDIA : CS_HIBERNATE);
2214 
2215  status = SWITCH_STATUS_SUCCESS;
2216 
2217  //switch_ivr_bridge_display(originator_session, originatee_session);
2218 
2219  /* release the read locks we have on the channels */
2220  switch_core_session_rwunlock(originator_session);
2221  switch_core_session_rwunlock(originatee_session);
2222 
2223  } else {
2224  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originator_session), SWITCH_LOG_DEBUG, "originatee uuid %s is not present\n", originatee_uuid);
2225  switch_core_session_rwunlock(originator_session);
2226  }
2227  } else {
2228  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originator_session), SWITCH_LOG_DEBUG, "originator uuid %s is not present\n", originator_uuid);
2229  }
2230 
2231  return status;
2232 }
2233 
2235 {
2236  switch_core_session_t *rsession;
2238 
2239  switch_assert(uuid);
2240 
2241  if ((rsession = switch_core_session_locate(uuid))) {
2242  switch_channel_t *rchannel = switch_core_session_get_channel(rsession);
2243  const char *brto;
2244 
2246  (brto = switch_channel_get_partner_uuid(rchannel))) {
2247  switch_copy_string(b_uuid, brto, blen);
2248  status = SWITCH_STATUS_SUCCESS;
2249  }
2250  switch_core_session_rwunlock(rsession);
2251  }
2252 
2253  return status;
2254 
2255 }
2256 
2258 {
2259  switch_core_session_t *rsession, *bsession = NULL;
2260  switch_channel_t *channel, *rchannel, *bchannel = NULL;
2261  const char *buuid, *var;
2262  char brto[SWITCH_UUID_FORMATTED_LENGTH + 1] = "";
2264 
2265  if (bleg) {
2266  if (switch_ivr_find_bridged_uuid(uuid, brto, sizeof(brto)) == SWITCH_STATUS_SUCCESS) {
2267  uuid = switch_core_session_strdup(session, brto);
2268  } else {
2269  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "no uuid bridged to %s\n", uuid);
2270  return status;
2271  }
2272  }
2273 
2274  if (zstr(uuid) || !(rsession = switch_core_session_locate(uuid))) {
2275  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "no uuid %s\n", uuid);
2276  return status;
2277  }
2278 
2279  channel = switch_core_session_get_channel(session);
2280  rchannel = switch_core_session_get_channel(rsession);
2281  buuid = switch_channel_get_partner_uuid(rchannel);
2282 
2283  if (zstr(buuid) || !strcasecmp(buuid, switch_core_session_get_uuid(session))) {
2284  buuid = NULL;
2285  }
2286 
2287  if ((var = switch_channel_get_variable(channel, "intercept_unbridged_only")) && switch_true(var)) {
2288  if ((switch_channel_test_flag(rchannel, CF_BRIDGED))) {
2289  switch_core_session_rwunlock(rsession);
2290  return status;
2291  }
2292  }
2293 
2294  if ((var = switch_channel_get_variable(channel, "intercept_unanswered_only")) && switch_true(var)) {
2295  if ((switch_channel_test_flag(rchannel, CF_ANSWERED))) {
2296  switch_core_session_rwunlock(rsession);
2297  return status;
2298  }
2299  }
2300 
2301  switch_channel_answer(channel);
2302 
2303  if (!zstr(buuid)) {
2304  if ((bsession = switch_core_session_locate(buuid))) {
2305  bchannel = switch_core_session_get_channel(bsession);
2307  }
2308  }
2309 
2310  if (!switch_channel_test_flag(rchannel, CF_ANSWERED)) {
2311  switch_channel_answer(rchannel);
2312  }
2313 
2315 
2317  switch_channel_set_state(rchannel, CS_PARK);
2318 
2319  if (bchannel) {
2320  switch_channel_set_variable(bchannel, "park_after_bridge", "true");
2321  }
2322 
2323  if ((var = switch_channel_get_variable(channel, "intercept_pre_bond")) && switch_true(var)) {
2326  }
2327 
2329  status = switch_ivr_uuid_bridge(switch_core_session_get_uuid(session), uuid);
2330  switch_core_session_rwunlock(rsession);
2331 
2332  if (bsession) {
2334  switch_core_session_rwunlock(bsession);
2335  }
2336 
2337  return status;
2338 
2339 }
2340 
2341 /* For Emacs:
2342  * Local Variables:
2343  * mode:c
2344  * indent-tabs-mode:t
2345  * tab-width:4
2346  * c-basic-offset:4
2347  * End:
2348  * For VIM:
2349  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
2350  */
#define SWITCH_SIGNAL_BRIDGE_VARIABLE
Definition: switch_types.h:202
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:413
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it&#39;s state machine to end.
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)
static switch_bool_t switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:519
#define SWITCH_CHANNEL_SESSION_LOG(x)
An Abstract Representation of a dialplan extension.
Call Specific Data.
Definition: switch_caller.h:73
#define SWITCH_LAST_BRIDGE_VARIABLE
Definition: switch_types.h:201
switch_core_session_message_types_t message_id
Definition: switch_core.h:183
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_size_t switch_buffer_read(_In_ switch_buffer_t *buffer, _In_ void *data, _In_ switch_size_t datalen)
Read data from a switch_buffer_t up to the ammount of datalen if it is available. Remove read data fr...
void switch_core_session_passthru(switch_core_session_t *session, switch_media_type_t type, switch_bool_t on)
switch_status_t switch_channel_set_variable_name_printf(switch_channel_t *channel, const char *val, const char *fmt,...)
const char *const const double number
Definition: switch_cJSON.h:254
#define SWITCH_COPY_XML_CDR_VARIABLE
Definition: switch_types.h:140
switch_core_session_t * session
#define SWITCH_PARK_AFTER_EARLY_BRIDGE_VARIABLE
Definition: switch_types.h:221
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)
switch_status_t switch_buffer_create_dynamic(_Out_ switch_buffer_t **buffer, _In_ switch_size_t blocksize, _In_ switch_size_t start_len, _In_ switch_size_t max_len)
Allocate a new dynamic switch_buffer.
#define SWITCH_TRANSFER_SOURCE_VARIABLE
Definition: switch_types.h:145
#define SWITCH_API_BRIDGE_END_VARIABLE
Definition: switch_types.h:174
switch_status_t switch_ivr_sleep(switch_core_session_t *session, uint32_t ms, switch_bool_t sync, switch_input_args_t *args)
Wait for time to pass for a specified number of milliseconds.
Definition: switch_ivr.c:127
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_ivr_nomedia(const char *uuid, switch_media_flag_t flags)
Signal a session to request indirect media allowing it to exchange media directly with another device...
Definition: switch_ivr.c:1987
#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:590
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_bool_t
Definition: switch_types.h:437
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:733
switch_core_session_t * session_a
switch_status_t switch_ivr_broadcast(const char *uuid, const char *path, switch_media_flag_t flags)
Signal the session to broadcast audio.
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.
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:79
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:211
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_core_session_write_text_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
switch_status_t switch_ivr_intercept_session(switch_core_session_t *session, const char *uuid, switch_bool_t bleg)
switch_status_t switch_ivr_parse_all_events(switch_core_session_t *session)
Parse all commands from an event.
Definition: switch_ivr.c:913
switch_status_t switch_ivr_media(const char *uuid, switch_media_flag_t flags)
Signal a session to request direct media access to it&#39;s remote end.
Definition: switch_ivr.c:1773
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:486
#define SWITCH_CHANNEL_EXECUTE_ON_PRE_BRIDGE_VARIABLE
Definition: switch_types.h:159
switch_size_t switch_buffer_write(_In_ switch_buffer_t *buffer, _In_bytecount_(datalen) const void *data, _In_ switch_size_t datalen)
Write data into a switch_buffer_t up to the length of datalen.
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:56
A message object designed to allow unlike technologies to exchange data.
Definition: switch_core.h:179
#define SWITCH_COPY_JSON_CDR_VARIABLE
Definition: switch_types.h:141
#define SWITCH_ORIGINATE_SIGNAL_BOND_VARIABLE
Definition: switch_types.h:204
switch_status_t switch_core_session_get_video_write_impl(switch_core_session_t *session, switch_codec_implementation_t *impp)
#define zstr(x)
Definition: switch_utils.h:314
#define SWITCH_PARK_AFTER_BRIDGE_VARIABLE
Definition: switch_types.h:220
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.
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:796
#define SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE
Definition: switch_types.h:219
#define SWITCH_EXEC_AFTER_BRIDGE_APP_VARIABLE
Definition: switch_types.h:224
#define SWITCH_CHANNEL_EXECUTE_ON_POST_BRIDGE_VARIABLE
Definition: switch_types.h:160
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.
uint32_t buflen
Definition: switch_frame.h:70
#define SWITCH_BRIDGE_EXPORT_VARS_VARIABLE
Definition: switch_types.h:196
#define switch_yield(ms)
Wait a desired number of microseconds and yield the CPU.
Definition: switch_utils.h:998
#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.
static void exec_app(switch_core_session_t *session, char *app_str)
uint32_t datalen
Definition: switch_frame.h:68
#define switch_channel_inbound_display(_channel)
switch_status_t switch_ivr_find_bridged_uuid(const char *uuid, char *b_uuid, switch_size_t blen)
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_channel_add_variable_var_check(switch_channel_t *channel, const char *varname, const char *value, switch_bool_t var_check, switch_stack_t stack)
#define switch_core_session_request_video_refresh(_s)
Definition: switch_core.h:2881
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)
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 switch_zmalloc(ptr, len)
switch_status_t switch_ivr_bridge_bleg(switch_core_session_t *session, switch_core_session_t *peer_session, uint32_t max_wait_ms)
Bridge leaving b-leg in the control of another thread. Call from b-leg first then call switch_ivr_mul...
#define DEFAULT_LEAD_FRAMES
const char * caller_id_name
Definition: switch_caller.h:79
#define switch_channel_set_variable_partner(_channel, _var, _val)
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:885
#define SWITCH_BRIDGE_HANGUP_CAUSE_VARIABLE
Definition: switch_types.h:129
switch_status_t switch_ivr_uuid_bridge(const char *originator_uuid, const char *originatee_uuid)
Bridge two existing sessions.
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)
#define SWITCH_BRIDGE_UUID_VARIABLE
Definition: switch_types.h:184
#define switch_channel_down_nosig(_channel)
#define SWITCH_API_BRIDGE_START_VARIABLE
Definition: switch_types.h:175
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:54
uintptr_t switch_size_t
#define SWITCH_TRANSFER_AFTER_EARLY_BRIDGE_VARIABLE
Definition: switch_types.h:223
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&#39;s originator caller profile.
static switch_status_t hanguphook(switch_core_session_t *session)
#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:1693
void switch_cond_next(void)
Definition: switch_time.c:658
#define switch_core_session_get_partner(_session, _partner)
Definition: switch_core.h:1028
char * switch_copy_string(_Out_z_cap_(dst_size) char *dst, _In_z_ const char *src, _In_ switch_size_t dst_size)
#define SWITCH_BRIDGE_VARIABLE
Definition: switch_types.h:200
switch_call_cause_t
switch_dtmf_direction_t
Definition: switch_types.h:320
static switch_status_t switch_event_create_plain(switch_event_t **event, switch_event_types_t event_id)
Definition: switch_event.h:386
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.
int switch_core_media_check_engine_function(switch_core_session_t *session, switch_media_type_t type)
#define switch_core_session_receive_message(_session, _message)
Definition: switch_core.h:1247
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:3571
switch_bool_t switch_core_session_transcoding(switch_core_session_t *session_a, switch_core_session_t *session_b, switch_media_type_t type)
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 ...
switch_status_t switch_ivr_3p_nomedia(const char *uuid, switch_media_flag_t flags)
Definition: switch_ivr.c:1881
#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:3335
switch_status_t
Common return values.
#define MESSAGE_STAMP_FFL(_m)
Definition: switch_core.h:175
#define SWITCH_EXEC_AFTER_BRIDGE_ARG_VARIABLE
Definition: switch_types.h:225
void switch_core_media_end_engine_function(switch_core_session_t *session, switch_media_type_t type)
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:203
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&#39;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&#39;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.
#define switch_core_session_locate(uuid_str)
Locate a session based on it&#39;s uuid.
Definition: switch_core.h:932
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:384
#define SWITCH_DECLARE(type)
uint32_t samples
Definition: switch_frame.h:72
uint32_t switch_core_session_private_event_count(_In_ switch_core_session_t *session)
Indicate the number of waiting private events on a session.
static void abort_call(switch_channel_t *caller_channel, switch_channel_t *peer_channel)
#define switch_channel_set_flag(_c, _f)
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)
void switch_core_media_start_engine_function(switch_core_session_t *session, switch_media_type_t type, switch_engine_function_t engine_function, void *user_data)
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:144
#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:322
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
char * key
Definition: switch_msrp.c:64
#define switch_core_session_alloc(_session, _memory)
Allocate memory from a session&#39;s pool.
Definition: switch_core.h:696
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:693
static switch_status_t audio_bridge_on_routing(switch_core_session_t *session)
void switch_ivr_check_hold(switch_core_session_t *session)
Definition: switch_ivr.c:2143
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.
const char *const name
Definition: switch_cJSON.h:250
#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&#39;s pool.
Definition: switch_core.h:719
void switch_event_destroy(switch_event_t **event)
Destroy an event.
switch_status_t switch_core_session_get_video_read_impl(switch_core_session_t *session, switch_codec_implementation_t *impp)
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)
struct fspr_thread_t switch_thread_t
Definition: switch_apr.h:941
#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:2862
#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&#39;s caller profile.
#define switch_core_session_kill_channel(session, sig)
Send a signal to a channel.
Definition: switch_core.h:1393
switch_size_t switch_buffer_inuse(_In_ switch_buffer_t *buffer)
Get the in use amount of a switch_buffer_t.
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:222
void switch_buffer_destroy(switch_buffer_t **buffer)
Destroy the buffer.
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)
#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_status_t switch_core_session_read_text_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
switch_memory_pool_t * switch_core_session_get_pool(_In_ switch_core_session_t *session)
Retrieve the memory pool from a session.
#define SWITCH_UUID_FORMATTED_LENGTH
Definition: switch_apr.h:545
#define SWITCH_BRIDGE_CHANNEL_VARIABLE
Definition: switch_types.h:182
switch_core_session_t * session_b
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:234
#define switch_xml_toxml(xml, prn_header)
Converts an switch_xml structure back to xml in html format. Returns a string of html data that \ mus...
Definition: switch_xml.h:224
static void text_bridge_thread(switch_core_session_t *session, void *obj)
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:847
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)