RTS API Documentation  1.10.11
Data Structures | Macros | Typedefs | Functions | Variables
switch_ivr_bridge.c File Reference
#include <switch.h>
+ Include dependency graph for switch_ivr_bridge.c:

Go to the source code of this file.

Data Structures

struct  vid_helper
 
struct  switch_ivr_bridge_data
 

Macros

#define DEFAULT_LEAD_FRAMES   10
 

Typedefs

typedef struct switch_ivr_bridge_data switch_ivr_bridge_data_t
 

Functions

static void cleanup_proxy_mode_a (switch_core_session_t *session)
 
static void cleanup_proxy_mode_b (switch_core_session_t *session)
 
static void text_bridge_thread (switch_core_session_t *session, void *obj)
 
static void send_display (switch_core_session_t *session, switch_core_session_t *peer_session)
 
void switch_ivr_bridge_display (switch_core_session_t *session, switch_core_session_t *peer_session)
 
static void * audio_bridge_thread (switch_thread_t *thread, void *obj)
 
static void transfer_after_bridge (switch_core_session_t *session, const char *where)
 
static switch_status_t audio_bridge_on_exchange_media (switch_core_session_t *session)
 
static switch_status_t audio_bridge_on_routing (switch_core_session_t *session)
 
static switch_status_t audio_bridge_on_consume_media (switch_core_session_t *session)
 
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_multi_threaded_bridge on a-leg and b-leg. More...
 
static switch_status_t uuid_bridge_on_reset (switch_core_session_t *session)
 
static switch_status_t uuid_bridge_on_hibernate (switch_core_session_t *session)
 
static switch_status_t uuid_bridge_on_soft_execute (switch_core_session_t *session)
 
static switch_status_t sb_on_dtmf (switch_core_session_t *session, const switch_dtmf_t *dtmf, switch_dtmf_direction_t direction)
 
static switch_status_t hanguphook (switch_core_session_t *session)
 
static switch_status_t signal_bridge_on_hibernate (switch_core_session_t *session)
 
static switch_status_t signal_bridge_on_hangup (switch_core_session_t *session)
 
static void check_bridge_export (switch_channel_t *channel, switch_channel_t *peer_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. More...
 
static void abort_call (switch_channel_t *caller_channel, switch_channel_t *peer_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)
 
switch_status_t switch_ivr_uuid_bridge (const char *originator_uuid, const char *originatee_uuid)
 Bridge two existing sessions. More...
 
switch_status_t switch_ivr_find_bridged_uuid (const char *uuid, char *b_uuid, switch_size_t blen)
 
switch_status_t switch_ivr_intercept_session (switch_core_session_t *session, const char *uuid, switch_bool_t bleg)
 

Variables

static const switch_state_handler_table_t audio_bridge_peer_state_handlers
 
static const switch_state_handler_table_t uuid_bridge_state_handlers
 
static const switch_state_handler_table_t signal_bridge_state_handlers
 

Macro Definition Documentation

◆ DEFAULT_LEAD_FRAMES

#define DEFAULT_LEAD_FRAMES   10

Definition at line 33 of file switch_ivr_bridge.c.

Referenced by audio_bridge_thread().

Typedef Documentation

◆ switch_ivr_bridge_data_t

Definition at line 354 of file switch_ivr_bridge.c.

Function Documentation

◆ abort_call()

static void abort_call ( switch_channel_t caller_channel,
switch_channel_t peer_channel 
)
static

Definition at line 1602 of file switch_ivr_bridge.c.

References SWITCH_CAUSE_ORIGINATOR_CANCEL, switch_channel_get_cause(), and switch_channel_hangup.

Referenced by switch_ivr_multi_threaded_bridge().

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 }
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it&#39;s state machine to end.
switch_call_cause_t
switch_call_cause_t switch_channel_get_cause(_In_ switch_channel_t *channel)
return the cause code for a given channel

◆ audio_bridge_on_consume_media()

static switch_status_t audio_bridge_on_consume_media ( switch_core_session_t session)
static

Definition at line 1052 of file switch_ivr_bridge.c.

References audio_bridge_on_exchange_media(), audio_bridge_on_routing(), switch_channel_get_name(), SWITCH_CHANNEL_SESSION_LOG, switch_core_session_get_channel(), SWITCH_LOG_DEBUG, switch_log_printf(), and SWITCH_STATUS_FALSE.

1053 {
1055 
1057 
1058  /* put the channel in a passive state so we can loop audio to it */
1059  return SWITCH_STATUS_FALSE;
1060 }
#define SWITCH_CHANNEL_SESSION_LOG(x)
_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.
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.
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.

◆ audio_bridge_on_exchange_media()

static switch_status_t audio_bridge_on_exchange_media ( switch_core_session_t session)
static

Definition at line 969 of file switch_ivr_bridge.c.

References audio_bridge_thread(), switch_ivr_bridge_data::b_uuid, CF_ANSWERED, CF_INNER_BRIDGE, CF_INTERCEPT, CF_INTERCEPTED, CF_REDIRECT, CF_TRANSFER, CF_XFER_ZOMBIE, switch_ivr_bridge_data::clean_exit, CS_EXCHANGE_MEDIA, CS_HANGUP, CS_PARK, CS_ROUTING, switch_ivr_bridge_data::session, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, SWITCH_CAUSE_NORMAL_CLEARING, SWITCH_CAUSE_ORIGINATOR_CANCEL, SWITCH_CAUSE_PICKED_OFF, switch_channel_api_on(), switch_channel_clear_flag(), switch_channel_clear_state_handler(), switch_channel_execute_on(), switch_channel_get_private(), switch_channel_get_state(), switch_channel_get_variable, switch_channel_hangup, switch_channel_set_private(), switch_channel_set_state, switch_channel_set_variable, switch_channel_test_flag(), switch_core_session_get_channel(), switch_core_session_reset(), switch_ivr_park_session(), SWITCH_PARK_AFTER_BRIDGE_VARIABLE, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE, SWITCH_TRUE, switch_true(), and transfer_after_bridge().

Referenced by audio_bridge_on_consume_media(), and switch_ivr_bridge_bleg().

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  }
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 }
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_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it&#39;s state machine to end.
switch_status_t switch_channel_execute_on(switch_channel_t *channel, const char *variable_prefix)
static switch_bool_t switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:519
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_core_session_t * session
#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.
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.
#define SWITCH_PARK_AFTER_BRIDGE_VARIABLE
Definition: switch_types.h:220
_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.
char b_uuid[SWITCH_UUID_FORMATTED_LENGTH+1]
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 switch_channel_get_variable(_c, _v)
void switch_ivr_park_session(switch_core_session_t *session)
Definition: switch_ivr.c:3571
switch_channel_state_t
Channel States (these are the defaults, CS_SOFT_EXECUTE, CS_EXCHANGE_MEDIA, and CS_CONSUME_MEDIA are ...
void * switch_channel_get_private(switch_channel_t *channel, const char *key)
Retrieve private from a given channel.
static void transfer_after_bridge(switch_core_session_t *session, const char *where)
static const switch_state_handler_table_t audio_bridge_peer_state_handlers
void switch_channel_clear_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Clear given flag(s) from a channel.
#define switch_channel_set_variable(_channel, _var, _val)
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
static void * audio_bridge_thread(switch_thread_t *thread, void *obj)

◆ audio_bridge_on_routing()

static switch_status_t audio_bridge_on_routing ( switch_core_session_t session)
static

Definition at line 1041 of file switch_ivr_bridge.c.

References CS_CONSUME_MEDIA, switch_channel_get_name(), SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_state, switch_core_session_get_channel(), SWITCH_LOG_DEBUG, switch_log_printf(), and SWITCH_STATUS_FALSE.

Referenced by audio_bridge_on_consume_media().

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 }
#define SWITCH_CHANNEL_SESSION_LOG(x)
#define switch_channel_set_state(channel, state)
Set the current state of a channel.
_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.
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.
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.

◆ audio_bridge_thread()

static void* audio_bridge_thread ( switch_thread_t thread,
void *  obj 
)
static

Definition at line 356 of file switch_ivr_bridge.c.

References switch_codec_implementation::actual_samples_per_second, switch_ivr_bridge_data::b_uuid, switch_frame::buflen, CF_3P_NOMEDIA_REQUESTED, CF_ACCEPT_CNG, CF_ANSWERED, CF_AUDIO, CF_AUDIO_PAUSE_READ, CF_AUDIO_PAUSE_WRITE, CF_BRIDGE_NOWRITE, CF_BRIDGE_ORIGINATOR, CF_BRIDGED, CF_BYPASS_MEDIA_AFTER_BRIDGE, CF_EARLY_MEDIA, CF_HANGUP_HELD, CF_HAS_TEXT, CF_HOLD, CF_HOLD_ON_BRIDGE, CF_INNER_BRIDGE, CF_INTERCEPT, CF_INTERCEPTED, CF_LEG_HOLDING, CF_NOT_READY, CF_REDIRECT, CF_RESET, CF_SUSPEND, CF_TRANSFER, CF_VIDEO, CF_VIDEO_BLANK, CF_VIDEO_BREAK, CF_VIDEO_PAUSE_READ, CF_VIDEO_READY, switch_ivr_bridge_data::clean_exit, switch_frame::codec, CS_EXECUTE, CS_PARK, CS_RESET, switch_frame::data, switch_frame::datalen, switch_codec_implementation::decoded_bytes_per_packet, DEFAULT_LEAD_FRAMES, switch_ivr_bridge_data::done, switch_event::event_id, exec_app(), switch_core_session_message::from, switch_ivr_bridge_data::input_callback, switch_core_session_message::message_id, switch_codec_implementation::microseconds_per_packet, switch_codec_implementation::number_of_channels, switch_core_session_message::numeric_arg, switch_ivr_bridge_data::other_leg_data, switch_frame::samples, switch_ivr_bridge_data::session, vid_helper::session_a, vid_helper::session_b, switch_ivr_bridge_data::session_data, SFF_CNG, SMF_ECHO_ALEG, SMF_ECHO_BLEG, SMF_REBRIDGE, switch_ivr_bridge_data::stream_id, switch_core_session_message::string_arg, SWITCH_API_BRIDGE_END_VARIABLE, SWITCH_API_BRIDGE_START_VARIABLE, SWITCH_BRIDGE_VARIABLE, SWITCH_CALL_DIRECTION_INBOUND, SWITCH_CALL_DIRECTION_OUTBOUND, switch_caller_extension_add_application(), switch_caller_extension_new(), SWITCH_CAUSE_ALLOTTED_TIMEOUT, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, SWITCH_CAUSE_NONE, SWITCH_CAUSE_NORMAL_CLEARING, switch_channel_answer, switch_channel_api_on(), switch_channel_clear_flag(), switch_channel_dequeue_dtmf(), switch_channel_direction(), switch_channel_down_nosig, switch_channel_execute_on(), SWITCH_CHANNEL_EXECUTE_ON_POST_BRIDGE_VARIABLE, SWITCH_CHANNEL_EXECUTE_ON_PRE_BRIDGE_VARIABLE, switch_channel_get_cause(), switch_channel_get_name(), switch_channel_get_state(), switch_channel_get_variable, switch_channel_get_variable_dup(), switch_channel_hangup, switch_channel_has_dtmf(), switch_channel_mark_hold(), switch_channel_media_ack, switch_channel_media_up, switch_channel_pass_callee_id(), switch_channel_pre_answer, switch_channel_ready, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_caller_extension(), switch_channel_set_flag, switch_channel_set_state, switch_channel_set_variable, switch_channel_stop_broadcast, switch_channel_test_flag(), switch_channel_up, switch_channel_up_nosig, switch_channel_wait_for_flag(), SWITCH_CODEC_FLAG_DECODE, SWITCH_CODEC_FLAG_ENCODE, switch_core_codec_destroy(), switch_core_codec_init, switch_core_media_check_engine_function(), switch_core_media_end_engine_function(), switch_core_media_start_engine_function(), switch_core_session_dequeue_event(), switch_core_session_execute_application_async(), switch_core_session_get_channel(), switch_core_session_get_pool(), switch_core_session_get_read_impl(), switch_core_session_get_uuid(), switch_core_session_kill_channel, switch_core_session_locate, switch_core_session_passthru(), switch_core_session_private_event_count(), switch_core_session_read_frame(), switch_core_session_read_video_frame(), switch_core_session_receive_event(), switch_core_session_receive_message, switch_core_session_reset(), switch_core_session_rwunlock(), switch_core_session_send_dtmf(), switch_core_session_transcoding(), switch_core_session_video_reset(), switch_core_session_write_frame(), switch_core_session_write_video_frame(), switch_epoch_time_now(), SWITCH_EVENT_COMMAND, switch_event_destroy(), SWITCH_EVENT_MESSAGE, SWITCH_EXEC_AFTER_BRIDGE_APP_VARIABLE, SWITCH_EXEC_AFTER_BRIDGE_ARG_VARIABLE, SWITCH_FALSE, switch_generate_sln_silence(), SWITCH_INPUT_TYPE_DTMF, SWITCH_INPUT_TYPE_EVENT, SWITCH_IO_FLAG_NONE, switch_ivr_3p_nomedia(), switch_ivr_bridge_display(), switch_ivr_broadcast(), switch_ivr_nomedia(), switch_ivr_parse_all_messages(), switch_ivr_parse_next_event(), switch_ivr_sleep(), SWITCH_LOG_CRIT, SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_LOG_WARNING, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_MEDIA_TYPE_TEXT, SWITCH_MEDIA_TYPE_VIDEO, SWITCH_MESSAGE_INDICATE_BRIDGE, SWITCH_MESSAGE_INDICATE_HOLD, SWITCH_MESSAGE_INDICATE_UNBRIDGE, SWITCH_READ_ACCEPTABLE, SWITCH_RECOMMENDED_BUFFER_SIZE, SWITCH_SIG_BREAK, SWITCH_STATUS_BREAK, SWITCH_STATUS_IGNORE, SWITCH_STATUS_SUCCESS, switch_stristr(), switch_test_flag, SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE, SWITCH_TRUE, switch_true(), switch_yield, text_bridge_thread(), vid_helper::up, and zstr.

Referenced by audio_bridge_on_exchange_media(), and switch_ivr_multi_threaded_bridge().

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;
360  switch_input_callback_function_t input_callback;
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;
365  switch_core_session_t *session_a, *session_b;
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 }
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_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it&#39;s state machine to end.
#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
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.
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.
void switch_core_session_passthru(switch_core_session_t *session, switch_media_type_t type, switch_bool_t on)
switch_core_session_t * session
#define switch_channel_set_state(channel, state)
Set the current state of a channel.
#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_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)
#define switch_channel_up(_channel)
#define SWITCH_RECOMMENDED_BUFFER_SIZE
Definition: switch_types.h:590
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
#define switch_channel_ready(_channel)
void switch_generate_sln_silence(int16_t *data, uint32_t samples, uint32_t channels, uint32_t divisor)
Generate static noise.
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.
switch_status_t switch_core_session_execute_application_async(switch_core_session_t *session, const char *app, const char *arg)
#define SWITCH_CHANNEL_EXECUTE_ON_PRE_BRIDGE_VARIABLE
Definition: switch_types.h:159
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 zstr(x)
Definition: switch_utils.h:314
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.
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_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)
uint32_t buflen
Definition: switch_frame.h:70
#define switch_yield(ms)
Wait a desired number of microseconds and yield the CPU.
Definition: switch_utils.h:998
uint32_t datalen
Definition: switch_frame.h:68
static void exec_app(switch_core_session_t *session, char *app_str)
char b_uuid[SWITCH_UUID_FORMATTED_LENGTH+1]
switch_status_t switch_core_session_send_dtmf(_In_ switch_core_session_t *session, const switch_dtmf_t *dtmf)
Send DTMF to a session.
#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.
#define DEFAULT_LEAD_FRAMES
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_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
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.
#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
#define SWITCH_BRIDGE_VARIABLE
Definition: switch_types.h:200
switch_call_cause_t
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
switch_bool_t switch_core_session_transcoding(switch_core_session_t *session_a, switch_core_session_t *session_b, switch_media_type_t type)
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_status_t switch_ivr_3p_nomedia(const char *uuid, switch_media_flag_t flags)
Definition: switch_ivr.c:1881
switch_status_t
Common return values.
#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)
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.
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.
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
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.
#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)
#define switch_channel_media_ack(_channel)
time_t switch_epoch_time_now(time_t *t)
Get the current epoch time.
Definition: switch_time.c:322
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:693
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)
void switch_event_destroy(switch_event_t **event)
Destroy an event.
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.
#define switch_channel_set_variable(_channel, _var, _val)
#define switch_channel_pre_answer(channel)
Indicate progress on a channel to attempt early media.
#define switch_core_session_kill_channel(session, sig)
Send a signal to a channel.
Definition: switch_core.h:1393
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
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)
switch_memory_pool_t * switch_core_session_get_pool(_In_ switch_core_session_t *session)
Retrieve the memory pool from a session.
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
static void text_bridge_thread(switch_core_session_t *session, void *obj)
switch_status_t switch_ivr_parse_all_messages(switch_core_session_t *session)
Definition: switch_ivr.c:847

◆ check_bridge_export()

static void check_bridge_export ( switch_channel_t channel,
switch_channel_t peer_channel 
)
static

Definition at line 1517 of file switch_ivr_bridge.c.

References switch_caller_profile::callee_id_name, switch_caller_profile::callee_id_number, switch_caller_profile::pool, SWITCH_BRIDGE_EXPORT_VARS_VARIABLE, switch_channel_get_caller_profile(), switch_channel_process_export(), and switch_core_strdup.

Referenced by switch_ivr_multi_threaded_bridge(), and switch_ivr_signal_bridge().

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 }
Call Specific Data.
Definition: switch_caller.h:73
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:733
#define SWITCH_BRIDGE_EXPORT_VARS_VARIABLE
Definition: switch_types.h:196
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_caller_profile_t * switch_channel_get_caller_profile(switch_channel_t *channel)
Retrieve the given channel&#39;s caller profile.
const char * callee_id_name
Definition: switch_caller.h:87
switch_memory_pool_t * pool

◆ cleanup_proxy_mode_a()

static void cleanup_proxy_mode_a ( switch_core_session_t session)
static

Definition at line 1974 of file switch_ivr_bridge.c.

References CF_3P_MEDIA_REQUESTED, CF_3P_NOMEDIA_REQUESTED, CF_PROXY_MODE, SWITCH_BRIDGE_UUID_VARIABLE, SWITCH_BRIDGE_VARIABLE, SWITCH_CAUSE_ATTENDED_TRANSFER, switch_channel_hangup, switch_channel_set_variable, switch_channel_test_flag(), switch_core_session_get_channel(), switch_core_session_get_partner, switch_core_session_rwunlock(), SWITCH_SIGNAL_BRIDGE_VARIABLE, and SWITCH_STATUS_SUCCESS.

Referenced by switch_ivr_uuid_bridge().

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 }
#define SWITCH_SIGNAL_BRIDGE_VARIABLE
Definition: switch_types.h:202
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it&#39;s state machine to end.
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.
_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.
#define SWITCH_BRIDGE_UUID_VARIABLE
Definition: switch_types.h:184
#define switch_core_session_get_partner(_session, _partner)
Definition: switch_core.h:1028
#define SWITCH_BRIDGE_VARIABLE
Definition: switch_types.h:200
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.
#define switch_channel_set_variable(_channel, _var, _val)

◆ cleanup_proxy_mode_b()

static void cleanup_proxy_mode_b ( switch_core_session_t session)
static

Definition at line 1963 of file switch_ivr_bridge.c.

References CF_3P_MEDIA_REQUESTED, CF_MEDIA_TRANS, CF_PROXY_MODE, SMF_NONE, switch_channel_test_flag(), switch_core_session_get_channel(), switch_core_session_get_uuid(), and switch_ivr_media().

Referenced by uuid_bridge_on_reset().

1964 {
1966 
1967  if (switch_channel_test_flag(channel, CF_PROXY_MODE) &&
1970  }
1971 }
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
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.
_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.
char * switch_core_session_get_uuid(_In_ switch_core_session_t *session)
Retrieve the unique identifier from a session.

◆ hanguphook()

static switch_status_t hanguphook ( switch_core_session_t session)
static

Definition at line 1316 of file switch_ivr_bridge.c.

References CF_BRIDGE_ORIGINATOR, switch_core_session_message::from, switch_core_session_message::message_id, MESSAGE_STAMP_FFL, switch_core_session_message::string_arg, switch_channel_clear_flag_recursive(), switch_channel_event_set_data(), switch_channel_get_variable, switch_channel_test_flag(), switch_core_session_alloc, switch_core_session_get_channel(), switch_core_session_queue_message(), SWITCH_EVENT_CHANNEL_UNBRIDGE, switch_event_create, switch_event_fire, SWITCH_MESSAGE_INDICATE_UNBRIDGE, SWITCH_SIGNAL_BRIDGE_VARIABLE, and SWITCH_STATUS_SUCCESS.

Referenced by signal_bridge_on_hibernate().

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 }
#define SWITCH_SIGNAL_BRIDGE_VARIABLE
Definition: switch_types.h:202
#define switch_event_fire(event)
Fire an event filling in most of the arguements with obvious values.
Definition: switch_event.h:413
switch_core_session_message_types_t message_id
Definition: switch_core.h:183
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.
Representation of an event.
Definition: switch_event.h:80
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.
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.
A message object designed to allow unlike technologies to exchange data.
Definition: switch_core.h:179
_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.
#define switch_channel_get_variable(_c, _v)
static switch_status_t hanguphook(switch_core_session_t *session)
#define MESSAGE_STAMP_FFL(_m)
Definition: switch_core.h:175
#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_core_session_alloc(_session, _memory)
Allocate memory from a session&#39;s pool.
Definition: switch_core.h:696
void switch_channel_clear_flag_recursive(switch_channel_t *channel, switch_channel_flag_t flag)

◆ sb_on_dtmf()

static switch_status_t sb_on_dtmf ( switch_core_session_t session,
const switch_dtmf_t dtmf,
switch_dtmf_direction_t  direction 
)
static

Definition at line 1286 of file switch_ivr_bridge.c.

References CF_BRIDGE_ORIGINATOR, CS_EXECUTE, switch_dtmf_t::digit, key, switch_assert, switch_channel_get_private(), switch_channel_get_variable, switch_channel_set_state, switch_channel_test_flag(), switch_core_session_get_channel(), switch_core_session_locate, switch_core_session_rwunlock(), SWITCH_SIGNAL_BRIDGE_VARIABLE, SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

Referenced by signal_bridge_on_hangup(), and signal_bridge_on_hibernate().

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 }
#define SWITCH_SIGNAL_BRIDGE_VARIABLE
Definition: switch_types.h:202
#define switch_channel_set_state(channel, state)
Set the current state of a channel.
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.
_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.
#define switch_channel_get_variable(_c, _v)
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.
void * switch_channel_get_private(switch_channel_t *channel, const char *key)
Retrieve private from a given channel.
#define switch_core_session_locate(uuid_str)
Locate a session based on it&#39;s uuid.
Definition: switch_core.h:932
char * key
Definition: switch_msrp.c:64
#define switch_assert(expr)

◆ send_display()

static void send_display ( switch_core_session_t session,
switch_core_session_t peer_session 
)
static

Definition at line 274 of file switch_ivr_bridge.c.

References switch_caller_profile::callee_id_name, switch_caller_profile::callee_id_number, switch_caller_profile::caller_id_name, switch_caller_profile::caller_id_number, CF_BRIDGE_ORIGINATOR, switch_caller_profile::destination_number, switch_core_session_message::from, switch_core_session_message::message_id, MESSAGE_STAMP_FFL, name, number, switch_core_session_message::string_array_arg, switch_channel_get_caller_profile(), switch_channel_test_flag(), switch_core_session_alloc, switch_core_session_get_channel(), switch_core_session_queue_message(), switch_core_session_strdup, SWITCH_MESSAGE_INDICATE_DISPLAY, and zstr.

Referenced by switch_ivr_bridge_display().

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 }
Call Specific Data.
Definition: switch_caller.h:73
switch_core_session_message_types_t message_id
Definition: switch_core.h:183
const char *const const double number
Definition: switch_cJSON.h:254
const char * string_array_arg[MESSAGE_STRING_ARG_MAX]
Definition: switch_core.h:211
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.
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.
A message object designed to allow unlike technologies to exchange data.
Definition: switch_core.h:179
#define zstr(x)
Definition: switch_utils.h:314
_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.
const char * callee_id_number
Definition: switch_caller.h:89
const char * caller_id_name
Definition: switch_caller.h:79
#define MESSAGE_STAMP_FFL(_m)
Definition: switch_core.h:175
const char * caller_id_number
Definition: switch_caller.h:81
#define switch_core_session_alloc(_session, _memory)
Allocate memory from a session&#39;s pool.
Definition: switch_core.h:696
const char *const name
Definition: switch_cJSON.h:250
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session&#39;s pool.
Definition: switch_core.h:719
switch_caller_profile_t * switch_channel_get_caller_profile(switch_channel_t *channel)
Retrieve the given channel&#39;s caller profile.
const char * callee_id_name
Definition: switch_caller.h:87

◆ signal_bridge_on_hangup()

static switch_status_t signal_bridge_on_hangup ( switch_core_session_t session)
static

Definition at line 1418 of file switch_ivr_bridge.c.

References CF_ANSWERED, CF_BRIDGE_ORIGINATOR, CF_INTERCEPT, CF_INTERCEPTED, CS_EXECUTE, sb_on_dtmf(), SWITCH_BRIDGE_VARIABLE, switch_channel_clear_flag_recursive(), switch_channel_event_set_data(), switch_channel_get_cause(), switch_channel_get_private(), switch_channel_get_variable, switch_channel_handle_cause(), switch_channel_hangup, switch_channel_set_flag, switch_channel_set_private(), switch_channel_set_state, switch_channel_set_variable, switch_channel_test_flag(), switch_channel_up_nosig, switch_core_session_get_channel(), switch_core_session_get_uuid(), switch_core_session_locate, switch_core_session_rwunlock(), switch_event_add_header_string(), switch_event_add_presence_data_cols(), SWITCH_EVENT_CHANNEL_UNBRIDGE, switch_event_create, switch_event_fire, SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE, switch_ivr_park_session(), SWITCH_PARK_AFTER_BRIDGE_VARIABLE, SWITCH_SIGNAL_BRIDGE_VARIABLE, SWITCH_STACK_BOTTOM, SWITCH_STATUS_SUCCESS, SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE, switch_true(), transfer_after_bridge(), and zstr.

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 }
#define SWITCH_SIGNAL_BRIDGE_VARIABLE
Definition: switch_types.h:202
#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.
static switch_bool_t switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:519
#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.
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.
Representation of an event.
Definition: switch_event.h:80
static switch_status_t sb_on_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf, switch_dtmf_direction_t direction)
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.
#define zstr(x)
Definition: switch_utils.h:314
#define SWITCH_PARK_AFTER_BRIDGE_VARIABLE
Definition: switch_types.h:220
_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.
#define SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE
Definition: switch_types.h:219
#define switch_channel_get_variable(_c, _v)
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_BRIDGE_VARIABLE
Definition: switch_types.h:200
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.
char * switch_core_session_get_uuid(_In_ switch_core_session_t *session)
Retrieve the unique identifier from a session.
void switch_ivr_park_session(switch_core_session_t *session)
Definition: switch_ivr.c:3571
void * switch_channel_get_private(switch_channel_t *channel, const char *key)
Retrieve private from a given channel.
static void transfer_after_bridge(switch_core_session_t *session, const char *where)
#define switch_core_session_locate(uuid_str)
Locate a session based on it&#39;s uuid.
Definition: switch_core.h:932
#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_channel_set_flag(_c, _f)
void switch_channel_clear_flag_recursive(switch_channel_t *channel, switch_channel_flag_t flag)
#define switch_channel_up_nosig(_channel)
#define switch_channel_set_variable(_channel, _var, _val)
#define SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE
Definition: switch_types.h:222
switch_call_cause_t switch_channel_get_cause(_In_ switch_channel_t *channel)
return the cause code for a given channel
void switch_channel_handle_cause(switch_channel_t *channel, switch_call_cause_t cause)

◆ signal_bridge_on_hibernate()

static switch_status_t signal_bridge_on_hibernate ( switch_core_session_t session)
static

Definition at line 1346 of file switch_ivr_bridge.c.

References CF_BRIDGE_ORIGINATOR, CF_BROADCAST, CS_HIBERNATE, DIGIT_TARGET_PEER, DIGIT_TARGET_SELF, switch_core_session_message::from, hanguphook(), key, switch_core_session_message::message_id, sb_on_dtmf(), switch_core_session_message::string_arg, switch_assert, SWITCH_BRIDGE_VARIABLE, switch_channel_event_set_data(), switch_channel_get_name(), switch_channel_get_state(), switch_channel_get_variable, switch_channel_ready, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_bridge_time(), switch_channel_set_private(), switch_channel_set_variable, switch_channel_test_flag(), switch_core_session_get_channel(), switch_core_session_get_dmachine(), switch_core_session_get_uuid(), switch_core_session_locate, switch_core_session_receive_message, switch_core_session_rwunlock(), switch_core_session_strdup, switch_event_add_header_string(), switch_event_add_presence_data_cols(), SWITCH_EVENT_CHANNEL_BRIDGE, switch_event_create, switch_event_fire, switch_ivr_dmachine_ping(), switch_ivr_parse_all_messages(), SWITCH_LAST_BRIDGE_VARIABLE, SWITCH_LOG_DEBUG, switch_log_printf(), SWITCH_MESSAGE_INDICATE_BRIDGE, SWITCH_SIGNAL_BRIDGE_VARIABLE, SWITCH_STACK_BOTTOM, SWITCH_STATUS_SUCCESS, and switch_yield.

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 }
#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_SESSION_LOG(x)
#define SWITCH_LAST_BRIDGE_VARIABLE
Definition: switch_types.h:201
switch_core_session_message_types_t message_id
Definition: switch_core.h:183
switch_status_t switch_channel_set_private(switch_channel_t *channel, const char *key, const void *private_info)
Set private data on channel.
void switch_channel_set_bridge_time(switch_channel_t *channel)
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.
Representation of an event.
Definition: switch_event.h:80
#define switch_channel_ready(_channel)
static switch_status_t sb_on_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf, switch_dtmf_direction_t direction)
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.
A message object designed to allow unlike technologies to exchange data.
Definition: switch_core.h:179
_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.
#define switch_yield(ms)
Wait a desired number of microseconds and yield the CPU.
Definition: switch_utils.h:998
#define switch_channel_get_variable(_c, _v)
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.
static switch_status_t hanguphook(switch_core_session_t *session)
#define SWITCH_BRIDGE_VARIABLE
Definition: switch_types.h:200
#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.
char * switch_core_session_get_uuid(_In_ switch_core_session_t *session)
Retrieve the unique identifier from a session.
#define switch_core_session_locate(uuid_str)
Locate a session based on it&#39;s uuid.
Definition: switch_core.h:932
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
switch_status_t switch_ivr_dmachine_ping(switch_ivr_dmachine_t *dmachine, switch_ivr_dmachine_match_t **match_p)
char * key
Definition: switch_msrp.c:64
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.
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session&#39;s pool.
Definition: switch_core.h:719
#define switch_assert(expr)
#define switch_channel_set_variable(_channel, _var, _val)
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.
switch_status_t switch_ivr_parse_all_messages(switch_core_session_t *session)
Definition: switch_ivr.c:847

◆ switch_ivr_multi_threaded_bridge()

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 
)

Definition at line 1613 of file switch_ivr_bridge.c.

References abort_call(), audio_bridge_thread(), switch_ivr_bridge_data::b_uuid, CF_ANSWERED, CF_ARRANGED_BRIDGE, CF_BRIDGE_ORIGINATOR, CF_BRIDGED, CF_BROADCAST, CF_EARLY_MEDIA, CF_INNER_BRIDGE, CF_INTERCEPT, CF_INTERCEPTED, CF_MEDIA_BRIDGE_TTL, CF_PROXY_MODE, CF_REDIRECT, CF_RESET, CF_RING_READY, CF_TRANSFER, CF_XFER_ZOMBIE, check_bridge_export(), switch_ivr_bridge_data::clean_exit, CS_CONSUME_MEDIA, CS_DESTROY, CS_EXCHANGE_MEDIA, CS_EXECUTE, CS_HANGUP, CS_PARK, CS_RESET, CS_ROUTING, CS_SOFT_EXECUTE, switch_core_session_message::from, switch_ivr_bridge_data::input_callback, switch_core_session_message::message_id, switch_ivr_bridge_data::other_leg_data, switch_ivr_bridge_data::session, switch_ivr_bridge_data::session_data, switch_ivr_bridge_data::stream_id, switch_core_session_message::string_arg, SWITCH_BRIDGE_CHANNEL_VARIABLE, SWITCH_BRIDGE_HANGUP_CAUSE_VARIABLE, SWITCH_BRIDGE_UUID_VARIABLE, SWITCH_BRIDGE_VARIABLE, SWITCH_CAUSE_ALLOTTED_TIMEOUT, SWITCH_CAUSE_NO_ANSWER, SWITCH_CAUSE_NONE, SWITCH_CAUSE_NORMAL_CLEARING, switch_channel_add_state_handler(), switch_channel_answer, switch_channel_audio_sync, switch_channel_cause2str(), switch_channel_clear_flag(), switch_channel_clear_flag_recursive(), switch_channel_down_nosig, switch_channel_event_set_data(), switch_channel_get_cause(), switch_channel_get_name(), switch_channel_get_state(), switch_channel_get_variable, switch_channel_handle_cause(), switch_channel_hangup, switch_channel_media_ready, switch_channel_pass_callee_id(), switch_channel_ready, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_bridge_time(), switch_channel_set_flag, switch_channel_set_flag_recursive(), switch_channel_set_private(), switch_channel_set_state, switch_channel_set_variable, switch_channel_set_variable_name_printf(), switch_channel_stop_broadcast, switch_channel_test_flag(), switch_channel_wait_for_flag(), switch_channel_wait_for_state(), switch_cond_next(), SWITCH_COPY_JSON_CDR_VARIABLE, switch_copy_string(), SWITCH_COPY_XML_CDR_VARIABLE, switch_core_session_alloc, switch_core_session_get_channel(), switch_core_session_get_uuid(), switch_core_session_read_lock(), switch_core_session_receive_message, switch_core_session_rwunlock(), switch_core_session_strdup, switch_event_add_header_string(), switch_event_add_presence_data_cols(), SWITCH_EVENT_CHANNEL_BRIDGE, SWITCH_EVENT_CHANNEL_UNBRIDGE, switch_event_create, switch_event_fire, SWITCH_FALSE, SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE, switch_ivr_generate_json_cdr(), switch_ivr_generate_xml_cdr(), switch_ivr_park_session(), switch_ivr_parse_all_events(), switch_ivr_parse_all_messages(), switch_ivr_session_transfer(), switch_ivr_signal_bridge(), switch_ivr_wait_for_answer(), SWITCH_LAST_BRIDGE_VARIABLE, SWITCH_LOG_DEBUG, switch_log_printf(), SWITCH_LOG_WARNING, SWITCH_MESSAGE_INDICATE_BRIDGE, SWITCH_MESSAGE_INDICATE_UNBRIDGE, SWITCH_PARK_AFTER_BRIDGE_VARIABLE, SWITCH_PARK_AFTER_EARLY_BRIDGE_VARIABLE, switch_safe_free, SWITCH_SIGNAL_BOND_VARIABLE, SWITCH_STACK_BOTTOM, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE, SWITCH_TRANSFER_AFTER_EARLY_BRIDGE_VARIABLE, SWITCH_TRUE, switch_true(), switch_xml_free(), switch_xml_toxml, and transfer_after_bridge().

Referenced by uuid_bridge_on_soft_execute().

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 
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 }
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)
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)
#define SWITCH_LAST_BRIDGE_VARIABLE
Definition: switch_types.h:201
switch_core_session_message_types_t message_id
Definition: switch_core.h:183
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:140
switch_core_session_t * session
#define SWITCH_PARK_AFTER_EARLY_BRIDGE_VARIABLE
Definition: switch_types.h:221
#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
switch_status_t switch_ivr_wait_for_answer(switch_core_session_t *session, switch_core_session_t *peer_session)
#define switch_channel_stop_broadcast(_channel)
void switch_channel_set_bridge_time(switch_channel_t *channel)
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
Representation of an event.
Definition: switch_event.h:80
struct switch_ivr_bridge_data * other_leg_data
#define switch_channel_ready(_channel)
switch_status_t switch_core_session_read_lock(_In_ switch_core_session_t *session)
Acquire a read lock on the session.
#define switch_channel_media_ready(_channel)
A representation of an XML tree.
Definition: switch_xml.h:79
switch_status_t switch_ivr_parse_all_events(switch_core_session_t *session)
Parse all commands from an event.
Definition: switch_ivr.c:913
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.
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_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.
_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.
#define SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE
Definition: switch_types.h:219
void switch_channel_wait_for_state(switch_channel_t *channel, switch_channel_t *other_channel, switch_channel_state_t want_state)
#define switch_channel_audio_sync(_c)
char b_uuid[SWITCH_UUID_FORMATTED_LENGTH+1]
#define switch_channel_get_variable(_c, _v)
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_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
#define SWITCH_BRIDGE_UUID_VARIABLE
Definition: switch_types.h:184
#define switch_channel_down_nosig(_channel)
#define SWITCH_TRANSFER_AFTER_EARLY_BRIDGE_VARIABLE
Definition: switch_types.h:223
void switch_cond_next(void)
Definition: switch_time.c:658
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
#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.
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
void switch_ivr_park_session(switch_core_session_t *session)
Definition: switch_ivr.c:3571
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_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.
static void check_bridge_export(switch_channel_t *channel, switch_channel_t *peer_channel)
static void transfer_after_bridge(switch_core_session_t *session, const char *where)
#define SWITCH_SIGNAL_BOND_VARIABLE
Definition: switch_types.h:203
#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
static void abort_call(switch_channel_t *caller_channel, switch_channel_t *peer_channel)
#define switch_channel_set_flag(_c, _f)
static const switch_state_handler_table_t audio_bridge_peer_state_handlers
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&#39;s pool.
Definition: switch_core.h:696
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.
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session&#39;s pool.
Definition: switch_core.h:719
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.
#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_TRANSFER_AFTER_BRIDGE_VARIABLE
Definition: switch_types.h:222
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_BRIDGE_CHANNEL_VARIABLE
Definition: switch_types.h:182
switch_call_cause_t switch_channel_get_cause(_In_ switch_channel_t *channel)
return the cause code for a given channel
#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 * 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
void switch_channel_handle_cause(switch_channel_t *channel, switch_call_cause_t cause)

◆ text_bridge_thread()

static void text_bridge_thread ( switch_core_session_t session,
void *  obj 
)
static

Definition at line 49 of file switch_ivr_bridge.c.

References CF_LEG_HOLDING, CF_PROXY_MEDIA, CF_TEXT_IDLE, CF_TEXT_LINE_BASED, CF_VIDEO_DECODED_READ, CF_VIDEO_READ_FILE_ATTACHED, CF_VIDEO_REFRESH_REQ, switch_frame::data, switch_frame::datalen, switch_codec_implementation::impl_id, vid_helper::session_a, vid_helper::session_b, SFF_CNG, SFF_TEXT_LINE_BREAK, switch_assert, switch_buffer_create_dynamic(), switch_buffer_destroy(), switch_buffer_inuse(), switch_buffer_read(), switch_buffer_write(), SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, switch_channel_clear_flag(), switch_channel_clear_flag_recursive(), switch_channel_get_name(), switch_channel_hangup, switch_channel_media_up, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_flag_recursive(), switch_channel_test_flag(), switch_channel_up_nosig, switch_cond_next(), switch_core_media_start_engine_function(), switch_core_session_get_channel(), switch_core_session_get_video_read_impl(), switch_core_session_get_video_write_impl(), switch_core_session_kill_channel, switch_core_session_passthru(), switch_core_session_read_lock(), switch_core_session_read_text_frame(), switch_core_session_read_video_frame(), switch_core_session_request_video_refresh, switch_core_session_rwunlock(), switch_core_session_transcoding(), switch_core_session_write_text_frame(), switch_core_session_write_video_frame(), SWITCH_FALSE, SWITCH_IO_FLAG_NONE, SWITCH_LOG_DEBUG, switch_log_printf(), SWITCH_MEDIA_TYPE_VIDEO, SWITCH_READ_ACCEPTABLE, switch_safe_free, SWITCH_SIG_BREAK, SWITCH_STATUS_SUCCESS, switch_test_flag, SWITCH_TRUE, switch_zmalloc, and vid_helper::up.

Referenced by audio_bridge_thread().

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 }
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it&#39;s state machine to end.
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...
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.
switch_core_session_t * session_a
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_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.
_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.
uint32_t datalen
Definition: switch_frame.h:68
#define switch_zmalloc(ptr, len)
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:885
An abstraction of a data frame.
Definition: switch_frame.h:54
uintptr_t switch_size_t
switch_status_t
Common return values.
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:693
#define switch_channel_up_nosig(_channel)
#define switch_assert(expr)
switch_size_t switch_buffer_inuse(_In_ switch_buffer_t *buffer)
Get the in use amount of a switch_buffer_t.
void switch_buffer_destroy(switch_buffer_t **buffer)
Destroy the buffer.
#define SWITCH_READ_ACCEPTABLE(status)
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_core_session_t * session_b

◆ transfer_after_bridge()

static void transfer_after_bridge ( switch_core_session_t session,
const char *  where 
)
static

Definition at line 953 of file switch_ivr_bridge.c.

References SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_variable, switch_core_session_get_channel(), switch_core_session_strdup, switch_ivr_session_transfer(), SWITCH_LOG_ERROR, switch_log_printf(), switch_separate_string(), SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE, and zstr.

Referenced by audio_bridge_on_exchange_media(), signal_bridge_on_hangup(), switch_ivr_multi_threaded_bridge(), and uuid_bridge_on_soft_execute().

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 }
#define SWITCH_CHANNEL_SESSION_LOG(x)
#define zstr(x)
Definition: switch_utils.h:314
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.
_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.
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.
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.
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session&#39;s pool.
Definition: switch_core.h:719
#define switch_channel_set_variable(_channel, _var, _val)
#define SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE
Definition: switch_types.h:222

◆ uuid_bridge_on_hibernate()

static switch_status_t uuid_bridge_on_hibernate ( switch_core_session_t session)
static

Definition at line 1140 of file switch_ivr_bridge.c.

References CS_RESET, switch_channel_set_state, switch_core_session_get_channel(), and SWITCH_STATUS_FALSE.

Referenced by switch_ivr_bridge_bleg().

1141 {
1143  return SWITCH_STATUS_FALSE;
1144 }
#define switch_channel_set_state(channel, state)
Set the current state of a channel.
_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.

◆ uuid_bridge_on_reset()

static switch_status_t uuid_bridge_on_reset ( switch_core_session_t session)
static

Definition at line 1123 of file switch_ivr_bridge.c.

References CF_ORIGINATING, CF_UUID_BRIDGE_ORIGINATOR, cleanup_proxy_mode_b(), CS_SOFT_EXECUTE, switch_channel_clear_flag(), switch_channel_get_name(), SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_state, switch_channel_test_flag(), switch_core_session_get_channel(), SWITCH_LOG_DEBUG, switch_log_printf(), and SWITCH_STATUS_SUCCESS.

Referenced by switch_ivr_bridge_bleg().

1124 {
1126 
1128 
1130 
1131  cleanup_proxy_mode_b(session);
1132 
1135  }
1136 
1137  return SWITCH_STATUS_SUCCESS;
1138 }
#define SWITCH_CHANNEL_SESSION_LOG(x)
#define switch_channel_set_state(channel, state)
Set the current state of a channel.
static void cleanup_proxy_mode_b(switch_core_session_t *session)
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.
_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.
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.
void switch_channel_clear_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Clear given flag(s) from a channel.
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.

◆ uuid_bridge_on_soft_execute()

static switch_status_t uuid_bridge_on_soft_execute ( switch_core_session_t session)
static

Definition at line 1146 of file switch_ivr_bridge.c.

References CF_REDIRECT, CF_TRANSFER, CF_UUID_BRIDGE_ORIGINATOR, CS_EXECUTE, CS_HANGUP, CS_PARK, CS_RESET, CS_ROUTING, CS_SOFT_EXECUTE, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, SWITCH_CAUSE_ORIGINATOR_CANCEL, switch_channel_clear_flag(), switch_channel_clear_state_handler(), switch_channel_down, switch_channel_down_nosig, switch_channel_event_set_data(), switch_channel_get_name(), switch_channel_get_running_state(), switch_channel_get_state(), switch_channel_get_variable, switch_channel_hangup, switch_channel_ready, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_state, switch_channel_set_variable, switch_channel_test_flag(), switch_core_session_get_channel(), switch_core_session_get_uuid(), switch_core_session_locate, switch_core_session_reset(), switch_core_session_rwunlock(), switch_event_add_header_string(), SWITCH_EVENT_CHANNEL_EXECUTE, switch_event_create, switch_event_fire, switch_ivr_multi_threaded_bridge(), switch_ivr_park_session(), switch_ivr_session_transfer(), switch_ivr_wait_for_answer(), SWITCH_LOG_DEBUG, switch_log_printf(), SWITCH_PARK_AFTER_BRIDGE_VARIABLE, SWITCH_STACK_BOTTOM, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE, SWITCH_TRUE, switch_true(), SWITCH_UUID_BRIDGE, switch_yield, and transfer_after_bridge().

Referenced by switch_ivr_bridge_bleg().

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));
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 }
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.
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)
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.
#define switch_channel_set_state(channel, state)
Set the current state of a channel.
switch_status_t switch_ivr_wait_for_answer(switch_core_session_t *session, switch_core_session_t *peer_session)
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.
Representation of an event.
Definition: switch_event.h:80
#define switch_channel_ready(_channel)
static const switch_state_handler_table_t uuid_bridge_state_handlers
switch_channel_state_t switch_channel_get_running_state(switch_channel_t *channel)
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.
#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.
_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.
#define switch_yield(ms)
Wait a desired number of microseconds and yield the CPU.
Definition: switch_utils.h:998
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 switch_channel_get_variable(_c, _v)
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_channel_down_nosig(_channel)
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.
char * switch_core_session_get_uuid(_In_ switch_core_session_t *session)
Retrieve the unique identifier from a session.
void switch_ivr_park_session(switch_core_session_t *session)
Definition: switch_ivr.c:3571
switch_channel_state_t
Channel States (these are the defaults, CS_SOFT_EXECUTE, CS_EXCHANGE_MEDIA, and CS_CONSUME_MEDIA are ...
#define switch_channel_down(_channel)
static void transfer_after_bridge(switch_core_session_t *session, const char *where)
#define switch_core_session_locate(uuid_str)
Locate a session based on it&#39;s uuid.
Definition: switch_core.h:932
#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
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.
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)
void switch_channel_clear_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Clear given flag(s) from a channel.
#define switch_channel_set_variable(_channel, _var, _val)
#define SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE
Definition: switch_types.h:222
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.
#define SWITCH_UUID_BRIDGE
Definition: switch_types.h:234

Variable Documentation

◆ audio_bridge_peer_state_handlers

static const switch_state_handler_table_t audio_bridge_peer_state_handlers
static
Initial value:
= {
NULL,
NULL,
NULL,
NULL,
}
static switch_status_t audio_bridge_on_consume_media(switch_core_session_t *session)
static switch_status_t audio_bridge_on_exchange_media(switch_core_session_t *session)
static switch_status_t audio_bridge_on_routing(switch_core_session_t *session)

Definition at line 35 of file switch_ivr_bridge.c.

◆ signal_bridge_state_handlers

const switch_state_handler_table_t signal_bridge_state_handlers
static
Initial value:
= {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
}
static switch_status_t signal_bridge_on_hibernate(switch_core_session_t *session)
static switch_status_t signal_bridge_on_hangup(switch_core_session_t *session)

Definition at line 1506 of file switch_ivr_bridge.c.

◆ uuid_bridge_state_handlers

const switch_state_handler_table_t uuid_bridge_state_handlers
static
Initial value:
= {
NULL,
NULL,
NULL,
NULL,
NULL,
}
static switch_status_t uuid_bridge_on_soft_execute(switch_core_session_t *session)
static switch_status_t uuid_bridge_on_reset(switch_core_session_t *session)
static switch_status_t uuid_bridge_on_hibernate(switch_core_session_t *session)

Definition at line 1111 of file switch_ivr_bridge.c.