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  switch_ivr_bridge_data

Defines

#define DEFAULT_LEAD_FRAMES   10

Typedefs

typedef 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 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)
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.
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.
switch_status_t switch_ivr_find_bridged_uuid (const char *uuid, char *b_uuid, switch_size_t blen)
void 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 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


Define Documentation

#define DEFAULT_LEAD_FRAMES   10

Definition at line 33 of file switch_ivr_bridge.c.

Referenced by audio_bridge_thread().


Typedef Documentation

typedef struct switch_ivr_bridge_data switch_ivr_bridge_data_t

Definition at line 159 of file switch_ivr_bridge.c.


Function Documentation

static void abort_call ( switch_channel_t caller_channel,
switch_channel_t peer_channel 
) [static]

Definition at line 1181 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().

01182 {
01183         switch_call_cause_t cause = switch_channel_get_cause(caller_channel);
01184         
01185         if (!cause) {
01186                 cause = SWITCH_CAUSE_ORIGINATOR_CANCEL;
01187         }
01188         
01189         switch_channel_hangup(peer_channel, cause);
01190 }

static switch_status_t audio_bridge_on_consume_media ( switch_core_session_t session  )  [static]

Definition at line 702 of file switch_ivr_bridge.c.

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

00703 {
00704         switch_channel_t *channel = switch_core_session_get_channel(session);
00705 
00706         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CUSTOM HOLD\n", switch_channel_get_name(channel));
00707 
00708         /* put the channel in a passive state so we can loop audio to it */
00709         return SWITCH_STATUS_FALSE;
00710 }

static switch_status_t audio_bridge_on_exchange_media ( switch_core_session_t session  )  [static]

Definition at line 635 of file switch_ivr_bridge.c.

References audio_bridge_peer_state_handlers, 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_clear_flag(), switch_channel_clear_state_handler(), 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_TRANSFER_AFTER_BRIDGE_VARIABLE, switch_true(), SWITCH_TRUE, and transfer_after_bridge().

00636 {
00637         switch_channel_t *channel = switch_core_session_get_channel(session);
00638         switch_ivr_bridge_data_t *bd = switch_channel_get_private(channel, "_bridge_");
00639         switch_channel_state_t state;
00640         const char *var;
00641 
00642         if (bd) {
00643                 switch_channel_set_private(channel, "_bridge_", NULL);
00644                 if (bd->session == session && *bd->b_uuid) {
00645                         audio_bridge_thread(NULL, (void *) bd);
00646                         switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
00647                 } else {
00648                         switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
00649                 }
00650         } else {
00651                 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
00652         }
00653         switch_channel_clear_state_handler(channel, &audio_bridge_peer_state_handlers);
00654 
00655         state = switch_channel_get_state(channel);
00656 
00657         if (state < CS_HANGUP && switch_true(switch_channel_get_variable(channel, SWITCH_PARK_AFTER_BRIDGE_VARIABLE))) {
00658                 switch_ivr_park_session(session);
00659         } else if (state < CS_HANGUP && (var = switch_channel_get_variable(channel, SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE))) {
00660                 transfer_after_bridge(session, var);
00661         } else {
00662                 if (!switch_channel_test_flag(channel, CF_TRANSFER) && !switch_channel_test_flag(channel, CF_REDIRECT) &&
00663                         !switch_channel_test_flag(channel, CF_XFER_ZOMBIE) && bd && !bd->clean_exit
00664                         && state != CS_PARK && state != CS_ROUTING && state == CS_EXCHANGE_MEDIA && !switch_channel_test_flag(channel, CF_INNER_BRIDGE)) {
00665                         if (switch_channel_test_flag(channel, CF_INTERCEPTED)) {
00666                                 switch_channel_clear_flag(channel, CF_INTERCEPT);
00667                                 switch_channel_clear_flag(channel, CF_INTERCEPTED);
00668                                 return SWITCH_STATUS_FALSE;
00669                         } else {
00670                                 if (switch_channel_test_flag(channel, CF_INTERCEPT)) {
00671                                         switch_channel_hangup(channel, SWITCH_CAUSE_PICKED_OFF);
00672                                 } else {
00673                                         if (!switch_channel_test_flag(channel, CF_ANSWERED)) {
00674                                                 switch_channel_hangup(channel, SWITCH_CAUSE_ORIGINATOR_CANCEL);
00675                                         } else {
00676                                                 switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
00677                                         }
00678                                 }
00679                         }
00680                 }
00681         }
00682 
00683         if (switch_channel_get_state(channel) == CS_EXCHANGE_MEDIA) {
00684                 switch_channel_set_variable(channel, "park_timeout", "3");
00685                 switch_channel_set_state(channel, CS_PARK);
00686         }
00687 
00688         return SWITCH_STATUS_FALSE;
00689 }

static switch_status_t audio_bridge_on_routing ( switch_core_session_t session  )  [static]

Definition at line 691 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.

00692 {
00693         switch_channel_t *channel = switch_core_session_get_channel(session);
00694 
00695         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CUSTOM ROUTING\n", switch_channel_get_name(channel));
00696 
00697         /* put the channel in a passive state so we can loop audio to it */
00698         switch_channel_set_state(channel, CS_CONSUME_MEDIA);
00699         return SWITCH_STATUS_FALSE;
00700 }

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

Definition at line 161 of file switch_ivr_bridge.c.

References switch_codec_implementation::actual_samples_per_second, switch_ivr_bridge_data::b_uuid, switch_frame::buflen, CF_ACCEPT_CNG, CF_ANSWERED, CF_BRIDGE_NOWRITE, CF_BRIDGE_ORIGINATOR, CF_BRIDGED, CF_BYPASS_MEDIA_AFTER_BRIDGE, CF_EARLY_MEDIA, CF_HOLD, CF_INNER_BRIDGE, CF_INTERCEPT, CF_INTERCEPTED, CF_LEG_HOLDING, CF_NOT_READY, CF_REDIRECT, CF_RESET, CF_SUSPEND, CF_TRANSFER, CF_VIDEO, switch_ivr_bridge_data::clean_exit, switch_frame::codec, CS_EXECUTE, CS_RESET, switch_stream_handle::data, switch_frame::data, switch_frame::datalen, switch_codec_implementation::decoded_bytes_per_packet, DEFAULT_LEAD_FRAMES, switch_event::event_id, switch_core_session_message::from, switch_ivr_bridge_data::input_callback, switch_core_session_message::message_id, switch_codec_implementation::microseconds_per_packet, switch_core_session_message::numeric_arg, switch_frame::samples, switch_ivr_bridge_data::session, switch_ivr_bridge_data::session_data, SFF_CNG, SMF_REBRIDGE, switch_ivr_bridge_data::stream_id, switch_core_session_message::string_arg, SWITCH_API_BRIDGE_END_VARIABLE, switch_api_execute(), 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_clear_flag(), switch_channel_dequeue_dtmf(), switch_channel_direction(), switch_channel_down_nosig, switch_channel_get_cause(), switch_channel_get_name(), switch_channel_get_state(), switch_channel_get_variable, switch_channel_hangup, switch_channel_has_dtmf(), switch_channel_media_ack, switch_channel_media_ready, switch_channel_pass_callee_id(), switch_channel_pre_answer, switch_channel_ready, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_bridge_time(), 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_nosig, switch_channel_wait_for_flag(), SWITCH_CODEC_FLAG_DECODE, SWITCH_CODEC_FLAG_ENCODE, switch_core_codec_destroy(), switch_core_codec_init, 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_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_strdup, 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_bridge_display(), switch_ivr_nomedia(), switch_ivr_parse_all_messages(), switch_ivr_parse_next_event(), SWITCH_LOG_CRIT, SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_LOG_WARNING, SWITCH_MESSAGE_INDICATE_BRIDGE, SWITCH_MESSAGE_INDICATE_UNBRIDGE, SWITCH_READ_ACCEPTABLE, SWITCH_RECOMMENDED_BUFFER_SIZE, switch_safe_free, SWITCH_SIG_BREAK, SWITCH_STANDARD_STREAM, SWITCH_STATUS_BREAK, SWITCH_STATUS_IGNORE, SWITCH_STATUS_SUCCESS, switch_str_nil, switch_stristr(), switch_test_flag, switch_thread_join(), SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE, switch_true(), SWITCH_TRUE, switch_yield, and zstr.

Referenced by audio_bridge_on_exchange_media(), and switch_ivr_multi_threaded_bridge().

00162 {
00163         switch_ivr_bridge_data_t *data = obj;
00164         int stream_id = 0, pre_b = 0, ans_a = 0, ans_b = 0, originator = 0;
00165         switch_input_callback_function_t input_callback;
00166         switch_core_session_message_t msg = { 0 };
00167         void *user_data;
00168         switch_channel_t *chan_a, *chan_b;
00169         switch_frame_t *read_frame;
00170         switch_core_session_t *session_a, *session_b;
00171         uint32_t read_frame_count = 0;
00172         const char *app_name = NULL, *app_arg = NULL;
00173         const char *hook_var = NULL;
00174         int inner_bridge = 0;
00175         switch_codec_t silence_codec = { 0 };
00176         switch_frame_t silence_frame = { 0 };
00177         int16_t silence_data[SWITCH_RECOMMENDED_BUFFER_SIZE / 2] = { 0 };
00178         const char *silence_var;
00179         int silence_val = 0, bypass_media_after_bridge = 0;
00180         const char *bridge_answer_timeout = NULL;
00181         int answer_timeout, sent_update = 0;
00182         time_t answer_limit = 0;
00183         const char *exec_app = NULL;
00184         const char *exec_data = NULL;
00185 
00186 #ifdef SWITCH_VIDEO_IN_THREADS
00187         switch_thread_t *vid_thread = NULL;
00188         struct vid_helper vh = { 0 };
00189         uint32_t vid_launch = 0;
00190 #endif
00191         data->clean_exit = 0;
00192 
00193         session_a = data->session;
00194         if (!(session_b = switch_core_session_locate(data->b_uuid))) {
00195                 return NULL;
00196         }
00197 
00198         input_callback = data->input_callback;
00199         user_data = data->session_data;
00200         stream_id = data->stream_id;
00201 
00202         chan_a = switch_core_session_get_channel(session_a);
00203         chan_b = switch_core_session_get_channel(session_b);
00204         
00205         switch_channel_set_bridge_time(chan_a);
00206  
00207         if ((exec_app = switch_channel_get_variable(chan_a, "bridge_pre_execute_app"))) {
00208                 exec_data = switch_channel_get_variable(chan_a, "bridge_pre_execute_data");
00209         }
00210 
00211         bypass_media_after_bridge = switch_channel_test_flag(chan_a, CF_BYPASS_MEDIA_AFTER_BRIDGE);
00212         switch_channel_clear_flag(chan_a, CF_BYPASS_MEDIA_AFTER_BRIDGE);
00213 
00214         ans_a = switch_channel_test_flag(chan_a, CF_ANSWERED);
00215 
00216         if ((originator = switch_channel_test_flag(chan_a, CF_BRIDGE_ORIGINATOR))) {
00217                 pre_b = switch_channel_test_flag(chan_a, CF_EARLY_MEDIA);
00218                 ans_b = switch_channel_test_flag(chan_b, CF_ANSWERED);
00219         }
00220 
00221         inner_bridge = switch_channel_test_flag(chan_a, CF_INNER_BRIDGE);
00222         
00223         if (!switch_channel_test_flag(chan_a, CF_ANSWERED) && (bridge_answer_timeout = switch_channel_get_variable(chan_a, "bridge_answer_timeout"))) {
00224                 if ((answer_timeout = atoi(bridge_answer_timeout)) < 0) {
00225                         answer_timeout = 0;
00226                 } else {
00227                         answer_limit = switch_epoch_time_now(NULL) + answer_timeout;
00228                 }
00229         }
00230 
00231         switch_channel_clear_flag(chan_a, CF_INTERCEPT);
00232         switch_channel_clear_flag(chan_a, CF_INTERCEPTED);
00233 
00234         switch_channel_set_flag(chan_a, CF_BRIDGED);
00235 
00236         switch_channel_wait_for_flag(chan_b, CF_BRIDGED, SWITCH_TRUE, 10000, chan_a);
00237 
00238         if (!switch_channel_test_flag(chan_b, CF_BRIDGED)) {
00239                 if (!(switch_channel_test_flag(chan_b, CF_TRANSFER) || switch_channel_test_flag(chan_b, CF_REDIRECT)
00240                           || switch_channel_get_state(chan_b) == CS_RESET)) {
00241                         switch_channel_hangup(chan_b, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
00242                 }
00243                 goto end_of_bridge_loop;
00244         }
00245 
00246         if (bypass_media_after_bridge) {
00247                 if (switch_stristr("loopback", switch_channel_get_name(chan_a)) || switch_stristr("loopback", switch_channel_get_name(chan_b))) {
00248                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_WARNING, "Cannot bypass media while bridged to a loopback address.\n");
00249                         bypass_media_after_bridge = 0;
00250                 }
00251         }
00252 
00253         if ((silence_var = switch_channel_get_variable(chan_a, "bridge_generate_comfort_noise"))) {
00254                 switch_codec_implementation_t read_impl = { 0 };
00255                 switch_core_session_get_read_impl(session_a, &read_impl);
00256 
00257                 if (!switch_channel_media_ready(chan_a)) {
00258                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_ERROR, "Channel has no media!\n");
00259                         goto end_of_bridge_loop;
00260                 }
00261 
00262                 if (switch_true(silence_var)) {
00263                         silence_val = 1400;
00264                 } else {
00265                         if ((silence_val = atoi(silence_var)) < 0) {
00266                                 silence_val = 0;
00267                         }
00268                 }
00269 
00270                 if (silence_val) {
00271                         if (switch_core_codec_init(&silence_codec,
00272                                                                            "L16",
00273                                                                            NULL,
00274                                                                            read_impl.actual_samples_per_second,
00275                                                                            read_impl.microseconds_per_packet / 1000,
00276                                                                            1,
00277                                                                            SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
00278                                                                            NULL, switch_core_session_get_pool(session_a)) != SWITCH_STATUS_SUCCESS) {
00279 
00280                                 silence_val = 0;
00281                         } else {
00282                                 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),
00283                                                                   switch_channel_get_name(chan_b), silence_val);
00284                                 silence_frame.codec = &silence_codec;
00285                                 silence_frame.data = silence_data;
00286                                 silence_frame.buflen = sizeof(silence_data);
00287                                 silence_frame.datalen = read_impl.decoded_bytes_per_packet;
00288                                 silence_frame.samples = silence_frame.datalen / sizeof(int16_t);
00289                         }
00290                 }
00291         }
00292 
00293         for (;;) {
00294                 switch_channel_state_t b_state;
00295                 switch_status_t status;
00296                 switch_event_t *event;
00297 
00298                 if (switch_channel_test_flag(chan_a, CF_TRANSFER)) {
00299                         data->clean_exit = 1;
00300                 }
00301 
00302                 if (data->clean_exit || switch_channel_test_flag(chan_b, CF_TRANSFER)) {
00303                         switch_channel_clear_flag(chan_a, CF_HOLD);
00304                         switch_channel_clear_flag(chan_a, CF_SUSPEND);
00305                         goto end_of_bridge_loop;
00306                 }
00307 
00308                 if (!switch_channel_test_flag(chan_b, CF_BRIDGED)) {
00309                         goto end_of_bridge_loop;
00310                 }
00311 
00312                 if (!switch_channel_ready(chan_a)) {
00313                         goto end_of_bridge_loop;
00314                 }
00315 
00316                 if ((b_state = switch_channel_down_nosig(chan_b))) {
00317                         goto end_of_bridge_loop;
00318                 }
00319                 
00320                 if (read_frame_count > DEFAULT_LEAD_FRAMES && switch_channel_media_ack(chan_a) && switch_core_session_private_event_count(session_a)) {
00321                         switch_channel_set_flag(chan_b, CF_SUSPEND);
00322                         msg.numeric_arg = 42;
00323                         msg.string_arg = data->b_uuid;
00324                         msg.message_id = SWITCH_MESSAGE_INDICATE_UNBRIDGE;
00325                         msg.from = __FILE__;
00326                         switch_core_session_receive_message(session_a, &msg);
00327                         switch_ivr_parse_next_event(session_a);
00328                         msg.message_id = SWITCH_MESSAGE_INDICATE_BRIDGE;
00329                         switch_core_session_receive_message(session_a, &msg);
00330                         switch_channel_clear_flag(chan_b, CF_SUSPEND);
00331                         switch_core_session_kill_channel(session_b, SWITCH_SIG_BREAK);
00332                 }
00333 
00334                 switch_ivr_parse_all_messages(session_a);
00335 
00336                 if (!inner_bridge && (switch_channel_test_flag(chan_a, CF_SUSPEND) || switch_channel_test_flag(chan_b, CF_SUSPEND))) {
00337                         status = switch_core_session_read_frame(session_a, &read_frame, SWITCH_IO_FLAG_NONE, stream_id);
00338 
00339                         if (!SWITCH_READ_ACCEPTABLE(status)) {
00340                                 goto end_of_bridge_loop;
00341                         }
00342                         continue;
00343                 }
00344 #ifdef SWITCH_VIDEO_IN_THREADS
00345                 if (switch_channel_test_flag(chan_a, CF_VIDEO) && switch_channel_test_flag(chan_b, CF_VIDEO) && !vid_launch) {
00346                         vid_launch++;
00347                         vh.session_a = session_a;
00348                         vh.session_b = session_b;
00349                         vid_thread = launch_video(&vh);
00350                 }
00351 #endif
00352 
00353                 if (read_frame_count > DEFAULT_LEAD_FRAMES && switch_channel_media_ack(chan_a)) {
00354                         
00355                         if (exec_app) {
00356                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "%s Bridge execute app %s(%s)\n", 
00357                                                                   switch_channel_get_name(chan_a), exec_app, exec_data);
00358 
00359                                 switch_core_session_execute_application_async(session_a, exec_app, exec_data);
00360                                 exec_app = exec_data = NULL;
00361                         }
00362 
00363 
00364                         if ((bypass_media_after_bridge || switch_channel_test_flag(chan_b, CF_BYPASS_MEDIA_AFTER_BRIDGE)) && switch_channel_test_flag(chan_a, CF_ANSWERED)
00365                                 && switch_channel_test_flag(chan_b, CF_ANSWERED)) {
00366                                 switch_ivr_nomedia(switch_core_session_get_uuid(session_a), SMF_REBRIDGE);
00367                                 bypass_media_after_bridge = 0;
00368                                 switch_channel_clear_flag(chan_b, CF_BYPASS_MEDIA_AFTER_BRIDGE);
00369                                 goto end_of_bridge_loop;
00370                         }
00371                 }
00372 
00373                 /* if 1 channel has DTMF pass it to the other */
00374                 while (switch_channel_has_dtmf(chan_a)) {
00375                         switch_dtmf_t dtmf = { 0, 0 };
00376                         if (switch_channel_dequeue_dtmf(chan_a, &dtmf) == SWITCH_STATUS_SUCCESS) {
00377                                 int send_dtmf = 1;
00378 
00379                                 if (input_callback) {
00380                                         switch_status_t cb_status = input_callback(session_a, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, user_data, 0);
00381 
00382                                         if (cb_status == SWITCH_STATUS_IGNORE) {
00383                                                 send_dtmf = 0;
00384                                         } else if (cb_status != SWITCH_STATUS_SUCCESS) {
00385                                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "%s ended call via DTMF\n", switch_channel_get_name(chan_a));
00386                                                 switch_core_session_kill_channel(session_b, SWITCH_SIG_BREAK);
00387                                                 goto end_of_bridge_loop;
00388                                         }
00389                                 }
00390 
00391                                 if (send_dtmf) {
00392                                         switch_core_session_send_dtmf(session_b, &dtmf);
00393                                         switch_core_session_kill_channel(session_b, SWITCH_SIG_BREAK);
00394                                 }
00395                         }
00396                 }
00397 
00398                 if (switch_core_session_dequeue_event(session_a, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
00399                         if (input_callback) {
00400                                 status = input_callback(session_a, event, SWITCH_INPUT_TYPE_EVENT, user_data, 0);
00401                         }
00402 
00403                         if ((event->event_id != SWITCH_EVENT_COMMAND && event->event_id != SWITCH_EVENT_MESSAGE)
00404                                 || switch_core_session_receive_event(session_b, &event) != SWITCH_STATUS_SUCCESS) {
00405                                 switch_event_destroy(&event);
00406                         }
00407 
00408                 }
00409 
00410                 if (!ans_a && answer_limit && switch_epoch_time_now(NULL) > answer_limit) {
00411                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "Answer timeout hit on %s.\n", switch_channel_get_name(chan_a));
00412                         switch_channel_hangup(chan_a, SWITCH_CAUSE_ALLOTTED_TIMEOUT);
00413                 }
00414 
00415                 if (!ans_a) {
00416                         if (originator) {
00417                                 if (!ans_b && switch_channel_test_flag(chan_b, CF_ANSWERED)) {
00418                                         switch_channel_pass_callee_id(chan_b, chan_a);
00419                                         if (switch_channel_answer(chan_a) != SWITCH_STATUS_SUCCESS) {
00420                                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "%s Media Establishment Failed.\n", switch_channel_get_name(chan_a));
00421                                                 goto end_of_bridge_loop;
00422                                         }
00423                                         ans_a = 1;
00424                                 } else if (!pre_b && switch_channel_test_flag(chan_b, CF_EARLY_MEDIA)) {
00425                                         if (switch_channel_pre_answer(chan_a) != SWITCH_STATUS_SUCCESS) {
00426                                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "%s Media Establishment Failed.\n", switch_channel_get_name(chan_a));
00427                                                 goto end_of_bridge_loop;
00428                                         }
00429                                         pre_b = 1;
00430                                 }
00431                                 if (!pre_b) {
00432                                         switch_yield(10000);
00433                                         continue;
00434                                 }
00435                         } else {
00436                                 ans_a = switch_channel_test_flag(chan_b, CF_ANSWERED);
00437                         }
00438                 }
00439 
00440                 if (ans_a != ans_b) {
00441                         switch_channel_t *un = ans_a ? chan_b : chan_a;
00442                         switch_channel_t *a = un == chan_b ? chan_a : chan_b;
00443 
00444                         if (switch_channel_direction(un) == SWITCH_CALL_DIRECTION_INBOUND) {
00445                                 if (switch_channel_direction(a) == SWITCH_CALL_DIRECTION_OUTBOUND || (un == chan_a && !originator)) {
00446                                         switch_channel_pass_callee_id(a, un);
00447                                 }
00448 
00449                                 if (switch_channel_answer(un) != SWITCH_STATUS_SUCCESS) {
00450                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "%s Media Establishment Failed.\n", switch_channel_get_name(un));
00451                                         goto end_of_bridge_loop;
00452                                 }
00453 
00454                                 if (ans_a) {
00455                                         ans_b = 1;
00456                                 } else {
00457                                         ans_a = 1;
00458                                 }
00459                         }
00460                 }
00461 
00462                 if (originator && !ans_b) ans_b = switch_channel_test_flag(chan_b, CF_ANSWERED);
00463 
00464                 if (originator && !sent_update && ans_a && ans_b && switch_channel_media_ack(chan_a) && switch_channel_media_ack(chan_b)) {
00465                         switch_ivr_bridge_display(session_a, session_b);
00466                         sent_update = 1;
00467                 }
00468 #ifndef SWITCH_VIDEO_IN_THREADS
00469                 if (switch_channel_test_flag(chan_a, CF_VIDEO) && switch_channel_test_flag(chan_b, CF_VIDEO)) {
00470                         /* read video from 1 channel and write it to the other */
00471                         status = switch_core_session_read_video_frame(session_a, &read_frame, SWITCH_IO_FLAG_NONE, 0);
00472 
00473                         if (!SWITCH_READ_ACCEPTABLE(status)) {
00474                                 goto end_of_bridge_loop;
00475                         }
00476 
00477                         switch_core_session_write_video_frame(session_b, read_frame, SWITCH_IO_FLAG_NONE, 0);
00478                 }
00479 #endif
00480 
00481                 /* read audio from 1 channel and write it to the other */
00482                 status = switch_core_session_read_frame(session_a, &read_frame, SWITCH_IO_FLAG_NONE, stream_id);
00483 
00484                 if (SWITCH_READ_ACCEPTABLE(status)) {
00485                         read_frame_count++;
00486                         if (switch_test_flag(read_frame, SFF_CNG)) {
00487                                 if (silence_val) {
00488                                         switch_generate_sln_silence((int16_t *) silence_frame.data, silence_frame.samples, silence_val);
00489                                         read_frame = &silence_frame;
00490                                 } else if (!switch_channel_test_flag(chan_b, CF_ACCEPT_CNG)) {
00491                                         continue;
00492                                 }
00493                         }
00494 
00495                         if (switch_channel_test_flag(chan_a, CF_BRIDGE_NOWRITE)) {
00496                                 continue;
00497                         }
00498 
00499                         if (status != SWITCH_STATUS_BREAK && !switch_channel_test_flag(chan_a, CF_HOLD)) {
00500                                 if (switch_core_session_write_frame(session_b, read_frame, SWITCH_IO_FLAG_NONE, stream_id) != SWITCH_STATUS_SUCCESS) {
00501                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG,
00502                                                                           "%s ending bridge by request from write function\n", switch_channel_get_name(chan_b));
00503                                         goto end_of_bridge_loop;
00504                                 }
00505                         }
00506                 } else {
00507                         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));
00508                         goto end_of_bridge_loop;
00509                 }
00510         }
00511 
00512   end_of_bridge_loop:
00513 
00514 #ifdef SWITCH_VIDEO_IN_THREADS
00515         if (vid_thread) {
00516                 vh.up = -1;
00517                 switch_channel_set_flag(chan_a, CF_NOT_READY);
00518                 switch_channel_set_flag(chan_b, CF_NOT_READY);
00519                 switch_core_session_kill_channel(session_a, SWITCH_SIG_BREAK);
00520                 switch_core_session_kill_channel(session_b, SWITCH_SIG_BREAK);
00521                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "Ending video thread.\n");
00522         }
00523 #endif
00524 
00525 
00526         if (silence_val) {
00527                 switch_core_codec_destroy(&silence_codec);
00528         }
00529 
00530         if (!inner_bridge) {
00531                 hook_var = switch_channel_get_variable(chan_a, SWITCH_API_BRIDGE_END_VARIABLE);
00532         }
00533 
00534         if (!zstr(hook_var)) {
00535                 switch_stream_handle_t stream = { 0 };
00536                 char *cmd = switch_core_session_strdup(session_a, hook_var);
00537                 char *arg = NULL;
00538                 if ((arg = strchr(cmd, ' '))) {
00539                         *arg++ = '\0';
00540                 }
00541                 SWITCH_STANDARD_STREAM(stream);
00542                 switch_api_execute(cmd, arg, NULL, &stream);
00543                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "\nPost-Bridge Command %s(%s):\n%s\n", cmd, arg, switch_str_nil((char *) stream.data));
00544                 switch_safe_free(stream.data);
00545         }
00546 
00547         if (!inner_bridge && switch_channel_up_nosig(chan_a)) {
00548                 if ((app_name = switch_channel_get_variable(chan_a, SWITCH_EXEC_AFTER_BRIDGE_APP_VARIABLE))) {
00549                         switch_caller_extension_t *extension = NULL;
00550                         if ((extension = switch_caller_extension_new(session_a, app_name, app_name)) == 0) {
00551                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_CRIT, "memory error!\n");
00552                                 goto end;
00553                         }
00554                         app_arg = switch_channel_get_variable(chan_a, SWITCH_EXEC_AFTER_BRIDGE_ARG_VARIABLE);
00555 
00556                         switch_caller_extension_add_application(session_a, extension, (char *) app_name, app_arg);
00557                         switch_channel_set_caller_extension(chan_a, extension);
00558 
00559                         if (switch_channel_get_state(chan_a) == CS_EXECUTE) {
00560                                 switch_channel_set_flag(chan_a, CF_RESET);
00561                         } else {
00562                                 switch_channel_set_state(chan_a, CS_EXECUTE);
00563                         }
00564                 }
00565         }
00566 
00567   end:
00568 
00569 #ifdef SWITCH_VIDEO_IN_THREADS
00570         if (vid_thread) {
00571                 switch_status_t st;
00572 
00573                 if (vh.up) {
00574                         switch_core_session_kill_channel(session_a, SWITCH_SIG_BREAK);
00575                         switch_core_session_kill_channel(session_b, SWITCH_SIG_BREAK);
00576                 }
00577                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "Ending video thread.\n");
00578                 switch_thread_join(&st, vid_thread);
00579                 switch_channel_clear_flag(chan_a, CF_NOT_READY);
00580                 switch_channel_clear_flag(chan_b, CF_NOT_READY);
00581         }
00582 #endif
00583 
00584 
00585 
00586         switch_core_session_reset(session_a, SWITCH_TRUE, SWITCH_TRUE);
00587         switch_channel_set_variable(chan_a, SWITCH_BRIDGE_VARIABLE, NULL);
00588         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "BRIDGE THREAD DONE [%s]\n", switch_channel_get_name(chan_a));
00589         switch_channel_clear_flag(chan_a, CF_BRIDGED);
00590 
00591         if (switch_channel_test_flag(chan_a, CF_LEG_HOLDING) && switch_channel_ready(chan_b)) {
00592                 const char *ext = switch_channel_get_variable(chan_a, "hold_hangup_xfer_exten");
00593 
00594                 switch_channel_stop_broadcast(chan_b);
00595 
00596                 if (zstr(ext)) {
00597                         switch_call_cause_t cause = switch_channel_get_cause(chan_b);
00598                         if (cause == SWITCH_CAUSE_NONE) {
00599                                 cause = SWITCH_CAUSE_NORMAL_CLEARING;
00600                         }
00601                         switch_channel_hangup(chan_b, cause);
00602                 } else {
00603                         switch_channel_set_variable(chan_b, SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE, ext);
00604                 }
00605                 switch_channel_clear_flag(chan_a, CF_LEG_HOLDING);
00606         }
00607 
00608         if (switch_channel_test_flag(chan_a, CF_INTERCEPTED)) {
00609                 switch_channel_set_flag(chan_b, CF_INTERCEPT);
00610         }
00611 
00612 
00613         switch_core_session_kill_channel(session_b, SWITCH_SIG_BREAK);
00614         switch_core_session_rwunlock(session_b);
00615         return NULL;
00616 }

static void check_bridge_export ( switch_channel_t channel,
switch_channel_t peer_channel 
) [static]

Definition at line 1102 of file switch_ivr_bridge.c.

References SWITCH_BRIDGE_EXPORT_VARS_VARIABLE, and switch_channel_process_export().

Referenced by switch_ivr_multi_threaded_bridge(), and switch_ivr_signal_bridge().

01103 {
01104         switch_channel_process_export(peer_channel, channel, NULL, SWITCH_BRIDGE_EXPORT_VARS_VARIABLE);
01105         switch_channel_process_export(channel, peer_channel, NULL, SWITCH_BRIDGE_EXPORT_VARS_VARIABLE);
01106 }

static void cleanup_proxy_mode_a ( switch_core_session_t session  )  [static]

Definition at line 1513 of file switch_ivr_bridge.c.

References 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().

01514 {
01515         switch_core_session_t *sbsession;
01516         switch_channel_t *channel = switch_core_session_get_channel(session);
01517         int done = 0;
01518 
01519         if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
01520                 if (switch_core_session_get_partner(session, &sbsession) == SWITCH_STATUS_SUCCESS) {
01521                         switch_channel_t *sbchannel = switch_core_session_get_channel(sbsession);
01522 
01523                         if (switch_channel_test_flag(sbchannel, CF_PROXY_MODE)) {       
01524                                 /* Clear this now, otherwise will cause the one we're interested in to hang up too...*/
01525                                 switch_channel_set_variable(sbchannel, SWITCH_SIGNAL_BRIDGE_VARIABLE, NULL);
01526                                 switch_channel_hangup(sbchannel, SWITCH_CAUSE_ATTENDED_TRANSFER);
01527                         } else {
01528                                 done = 1;
01529                         }
01530                         switch_core_session_rwunlock(sbsession);
01531                 }
01532         }
01533 
01534         if (done) return;
01535         
01536         switch_channel_set_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE, NULL);
01537         switch_channel_set_variable(channel, SWITCH_BRIDGE_VARIABLE, NULL);
01538         switch_channel_set_variable(channel, SWITCH_BRIDGE_UUID_VARIABLE, NULL);
01539 
01540 }

static void cleanup_proxy_mode_b ( switch_core_session_t session  )  [static]

Definition at line 1502 of file switch_ivr_bridge.c.

References 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().

01503 {
01504         switch_channel_t *channel = switch_core_session_get_channel(session);
01505 
01506 
01507         if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
01508                 switch_ivr_media(switch_core_session_get_uuid(session), SMF_NONE);
01509         }
01510 }

static switch_status_t hanguphook ( switch_core_session_t session  )  [static]

Definition at line 914 of file switch_ivr_bridge.c.

References CF_BRIDGE_ORIGINATOR, switch_core_session_message::from, hanguphook(), switch_core_session_message::message_id, 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_get_channel(), switch_core_session_receive_message, SWITCH_EVENT_CHANNEL_UNBRIDGE, switch_event_create, switch_event_fire, SWITCH_MESSAGE_INDICATE_UNBRIDGE, SWITCH_SIGNAL_BRIDGE_VARIABLE, and SWITCH_STATUS_SUCCESS.

00915 {
00916         switch_core_session_message_t msg = { 0 };
00917         switch_channel_t *channel = NULL;
00918         switch_event_t *event;
00919 
00920         channel = switch_core_session_get_channel(session);
00921 
00922 
00923         msg.message_id = SWITCH_MESSAGE_INDICATE_UNBRIDGE;
00924         msg.from = __FILE__;
00925         msg.string_arg = switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE);
00926 
00927         
00928         if (switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) {
00929                 switch_channel_clear_flag_recursive(channel, CF_BRIDGE_ORIGINATOR);
00930                 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_UNBRIDGE) == SWITCH_STATUS_SUCCESS) {
00931                         switch_channel_event_set_data(channel, event);
00932                         switch_event_fire(&event);
00933                 }
00934         }
00935 
00936         
00937         switch_core_session_receive_message(session, &msg);
00938         switch_core_event_hook_remove_state_change(session, hanguphook);
00939 
00940         return SWITCH_STATUS_SUCCESS;
00941 
00942 }

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 884 of file switch_ivr_bridge.c.

References CF_BRIDGE_ORIGINATOR, CS_EXECUTE, switch_dtmf_t::digit, 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().

00885 {
00886         switch_channel_t *channel = NULL;
00887         char *key;
00888 
00889         channel = switch_core_session_get_channel(session);
00890         switch_assert(channel != NULL);
00891 
00892         if ((key = (char *) switch_channel_get_private(channel, "__bridge_term_key")) && dtmf->digit == *key) {
00893                 const char *uuid;
00894                 switch_core_session_t *other_session;
00895 
00896                 if (switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) {
00897                         switch_channel_set_state(channel, CS_EXECUTE);
00898                 } else {
00899                         if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE)) && (other_session = switch_core_session_locate(uuid))) {
00900                                 switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
00901                                 switch_channel_set_state(other_channel, CS_EXECUTE);
00902                                 switch_core_session_rwunlock(other_session);
00903                         } else {
00904                                 return SWITCH_STATUS_SUCCESS;
00905                         }
00906                 }
00907 
00908                 return SWITCH_STATUS_FALSE;
00909         }
00910 
00911         return SWITCH_STATUS_SUCCESS;
00912 }

static void send_display ( switch_core_session_t session,
switch_core_session_t peer_session 
) [static]

Definition at line 92 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_DIALPLAN, switch_caller_profile::destination_number, MESSAGE_STAMP_FFL, SWITCH_CALL_DIRECTION_OUTBOUND, switch_channel_direction(), 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().

00093 {
00094 
00095         switch_core_session_message_t *msg;
00096         switch_caller_profile_t *caller_profile;
00097         switch_channel_t *caller_channel;
00098         const char *name, *number, *p;
00099 
00100         caller_channel = switch_core_session_get_channel(session);
00101         caller_profile = switch_channel_get_caller_profile(caller_channel);
00102         
00103         if (switch_channel_direction(caller_channel) == SWITCH_CALL_DIRECTION_OUTBOUND && !switch_channel_test_flag(caller_channel, CF_DIALPLAN)) {
00104                 name = caller_profile->callee_id_name;
00105                 number = caller_profile->callee_id_number;
00106 
00107                 if (zstr(name)) {
00108                         name = caller_profile->destination_number;
00109                 }
00110                 if (zstr(number)) {
00111                         number = caller_profile->destination_number;
00112                 }
00113         } else {
00114                 name = caller_profile->caller_id_name;
00115                 number = caller_profile->caller_id_number;
00116 
00117                 if (zstr(name)) {
00118                         name = caller_profile->destination_number;
00119                 }
00120                 if (zstr(number)) {
00121                         number = caller_profile->destination_number;
00122                 }
00123         }
00124 
00125         if ((p = strrchr(number, '/'))) {
00126                 number = p + 1;
00127         }
00128         if ((p = strrchr(name, '/'))) {
00129                 name = p + 1;
00130         }
00131 
00132         msg = switch_core_session_alloc(peer_session, sizeof(*msg));
00133         MESSAGE_STAMP_FFL(msg);
00134         msg->message_id = SWITCH_MESSAGE_INDICATE_DISPLAY;
00135         msg->string_array_arg[0] = switch_core_session_strdup(peer_session, name);
00136         msg->string_array_arg[1] = switch_core_session_strdup(peer_session, number);
00137         msg->from = __FILE__;
00138         switch_core_session_queue_message(peer_session, msg);
00139 
00140 }

static switch_status_t signal_bridge_on_hangup ( switch_core_session_t session  )  [static]

Definition at line 1010 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_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.

01011 {
01012         const char *uuid;
01013         switch_channel_t *channel = switch_core_session_get_channel(session);
01014         switch_core_session_t *other_session;
01015         switch_event_t *event;
01016 
01017         if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE))) {
01018                 switch_channel_set_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE, NULL);
01019         }
01020 
01021         if (switch_channel_get_private(channel, "__bridge_term_key")) {
01022                 switch_core_event_hook_remove_recv_dtmf(session, sb_on_dtmf);
01023                 switch_channel_set_private(channel, "__bridge_term_key", NULL);
01024         }
01025 
01026         switch_channel_set_variable(channel, SWITCH_BRIDGE_VARIABLE, NULL);
01027 
01028         if (uuid && (other_session = switch_core_session_locate(uuid))) {
01029                 switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
01030                 const char *sbv = switch_channel_get_variable(other_channel, SWITCH_SIGNAL_BRIDGE_VARIABLE);
01031                 const char *var;
01032 
01033                 if (!zstr(sbv) && !strcmp(sbv, switch_core_session_get_uuid(session))) {
01034 
01035                         switch_channel_set_variable(other_channel, SWITCH_SIGNAL_BRIDGE_VARIABLE, NULL);
01036                         switch_channel_set_variable(other_channel, SWITCH_BRIDGE_VARIABLE, NULL);
01037                         switch_channel_set_variable(other_channel, "call_uuid", switch_core_session_get_uuid(other_session));
01038 
01039                         if (switch_channel_up_nosig(other_channel)) {
01040 
01041                                 if (switch_true(switch_channel_get_variable(other_channel, SWITCH_PARK_AFTER_BRIDGE_VARIABLE))) {
01042                                         switch_ivr_park_session(other_session);
01043                                 } else if ((var = switch_channel_get_variable(other_channel, SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE))) {
01044                                         transfer_after_bridge(other_session, var);
01045                                 }
01046 
01047                                 if (switch_channel_test_flag(other_channel, CF_BRIDGE_ORIGINATOR)) {
01048                                         if (switch_channel_test_flag(channel, CF_ANSWERED) &&
01049                                                 switch_true(switch_channel_get_variable(other_channel, SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE))) {
01050 
01051                                                 if (switch_channel_test_flag(channel, CF_INTERCEPTED)) {
01052                                                         switch_channel_set_flag(other_channel, CF_INTERCEPT);
01053                                                 }
01054                                                 switch_channel_hangup(other_channel, switch_channel_get_cause(channel));
01055                                         } else {
01056                                                 switch_channel_set_state(other_channel, CS_EXECUTE);
01057                                         }
01058                                 } else {
01059                                         switch_channel_hangup(other_channel, switch_channel_get_cause(channel));
01060                                 }
01061                         }
01062                 }
01063                 
01064                 if (switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) {
01065                         switch_channel_clear_flag_recursive(channel, CF_BRIDGE_ORIGINATOR);
01066                         if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_UNBRIDGE) == SWITCH_STATUS_SUCCESS) {
01067                                 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-A-Unique-ID", switch_core_session_get_uuid(session));
01068                                 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", uuid);
01069                                 switch_event_add_presence_data_cols(other_channel, event, "Bridge-B-PD-");
01070                                 switch_channel_event_set_data(channel, event);
01071                                 switch_event_fire(&event);
01072                         }
01073                 }
01074 
01075                 switch_core_session_rwunlock(other_session);
01076         } else {
01077                 if (switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) {
01078                         switch_channel_clear_flag_recursive(channel, CF_BRIDGE_ORIGINATOR);
01079                         if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_UNBRIDGE) == SWITCH_STATUS_SUCCESS) {
01080                                 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-A-Unique-ID", switch_core_session_get_uuid(session));
01081                                 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", uuid);
01082                                 switch_channel_event_set_data(channel, event);
01083                                 switch_event_fire(&event);
01084                         }
01085                 }
01086         }
01087 
01088         return SWITCH_STATUS_SUCCESS;
01089 }

static switch_status_t signal_bridge_on_hibernate ( switch_core_session_t session  )  [static]

Definition at line 944 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(), 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_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.

00945 {
00946         switch_channel_t *channel = NULL;
00947         const char *key;
00948         switch_core_session_message_t msg = { 0 };
00949         switch_event_t *event = NULL;
00950         switch_ivr_dmachine_t *dmachine[2] = { 0 };
00951 
00952         channel = switch_core_session_get_channel(session);
00953         switch_assert(channel != NULL);
00954 
00955         msg.message_id = SWITCH_MESSAGE_INDICATE_BRIDGE;
00956         msg.from = __FILE__;
00957         msg.string_arg = switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE);
00958 
00959         switch_core_event_hook_add_state_change(session, hanguphook);
00960 
00961         switch_core_session_receive_message(session, &msg);
00962 
00963         if ((key = switch_channel_get_variable(channel, "bridge_terminate_key"))) {
00964                 switch_channel_set_private(channel, "__bridge_term_key", switch_core_session_strdup(session, key));
00965                 switch_core_event_hook_add_recv_dtmf(session, sb_on_dtmf);
00966         }
00967 
00968         switch_channel_set_variable(channel, SWITCH_BRIDGE_VARIABLE, switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE));
00969         switch_channel_set_variable(channel, SWITCH_LAST_BRIDGE_VARIABLE, switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE));
00970 
00971         if (switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) {
00972                 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_BRIDGE) == SWITCH_STATUS_SUCCESS) {
00973                         switch_core_session_t *other_session;
00974 
00975                         switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-A-Unique-ID", switch_core_session_get_uuid(session));
00976                         switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", msg.string_arg);
00977                         switch_channel_event_set_data(channel, event);
00978                         if ((other_session = switch_core_session_locate(msg.string_arg))) {
00979                                 switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
00980                                 switch_event_add_presence_data_cols(other_channel, event, "Bridge-B-PD-");
00981                                 switch_core_session_rwunlock(other_session);
00982                         }
00983                         switch_event_fire(&event);
00984                 }
00985         }
00986 
00987         if ((dmachine[0] = switch_core_session_get_dmachine(session, DIGIT_TARGET_SELF)) || 
00988                 (dmachine[1] = switch_core_session_get_dmachine(session, DIGIT_TARGET_PEER))) {
00989                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, 
00990                                                   "%s not hibernating due to active digit parser, semi-hibernation engaged.\n", switch_channel_get_name(channel));
00991 
00992                 while(switch_channel_ready(channel) && switch_channel_get_state(channel) == CS_HIBERNATE) {
00993                         if (!switch_channel_test_flag(channel, CF_BROADCAST)) {
00994                                 if (dmachine[0]) {
00995                                         switch_ivr_dmachine_ping(dmachine[0], NULL);
00996                                 }
00997                                 if (dmachine[1]) {
00998                                         switch_ivr_dmachine_ping(dmachine[1], NULL);
00999                                 }
01000                         }
01001                         switch_yield(20000);
01002                         switch_ivr_parse_all_messages(session);
01003                 }
01004         }
01005         
01006 
01007         return SWITCH_STATUS_SUCCESS;
01008 }

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 1192 of file switch_ivr_bridge.c.

References abort_call(), audio_bridge_peer_state_handlers, audio_bridge_thread(), CF_ANSWERED, 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(), cJSON_Delete(), cJSON_PrintUnformatted(), 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_core_session_message::message_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_hangup, switch_channel_media_ready, switch_channel_pass_callee_id(), switch_channel_ready, SWITCH_CHANNEL_SESSION_LOG, 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_safe_free, SWITCH_SIGNAL_BOND_VARIABLE, SWITCH_STACK_BOTTOM, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE, SWITCH_TRUE, switch_true(), switch_xml_free(), switch_xml_toxml(), and transfer_after_bridge().

01196 {
01197         switch_ivr_bridge_data_t *a_leg = switch_core_session_alloc(session, sizeof(*a_leg));
01198         switch_ivr_bridge_data_t *b_leg = switch_core_session_alloc(peer_session, sizeof(*b_leg));
01199         switch_channel_t *caller_channel = switch_core_session_get_channel(session);
01200         switch_channel_t *peer_channel = switch_core_session_get_channel(peer_session);
01201         int stream_id = 0;
01202         switch_status_t status = SWITCH_STATUS_SUCCESS;
01203         switch_channel_state_t state;
01204         switch_event_t *event;
01205         int br = 0;
01206         int inner_bridge = switch_channel_test_flag(caller_channel, CF_INNER_BRIDGE);
01207         const char *var;
01208         switch_call_cause_t cause;
01209         switch_core_session_message_t msg = { 0 };
01210 
01211         if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE)) {
01212                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Call has no media... Redirecting to signal bridge.\n");
01213                 return switch_ivr_signal_bridge(session, peer_session);
01214         }
01215 
01216         check_bridge_export(caller_channel, peer_channel);
01217         
01218         switch_channel_set_flag_recursive(caller_channel, CF_MEDIA_BRIDGE_TTL);
01219         switch_channel_set_flag_recursive(peer_channel, CF_MEDIA_BRIDGE_TTL);
01220 
01221         switch_channel_set_flag_recursive(caller_channel, CF_BRIDGE_ORIGINATOR);
01222         switch_channel_clear_flag(peer_channel, CF_BRIDGE_ORIGINATOR);
01223 
01224         switch_channel_audio_sync(caller_channel);
01225         switch_channel_audio_sync(peer_channel);
01226 
01227         b_leg->session = peer_session;
01228         switch_copy_string(b_leg->b_uuid, switch_core_session_get_uuid(session), sizeof(b_leg->b_uuid));
01229         b_leg->stream_id = stream_id;
01230         b_leg->input_callback = input_callback;
01231         b_leg->session_data = peer_session_data;
01232         b_leg->clean_exit = 0;
01233 
01234         a_leg->session = session;
01235         switch_copy_string(a_leg->b_uuid, switch_core_session_get_uuid(peer_session), sizeof(a_leg->b_uuid));
01236         a_leg->stream_id = stream_id;
01237         a_leg->input_callback = input_callback;
01238         a_leg->session_data = session_data;
01239         a_leg->clean_exit = 0;
01240 
01241         switch_channel_add_state_handler(peer_channel, &audio_bridge_peer_state_handlers);
01242 
01243         if (switch_channel_test_flag(peer_channel, CF_ANSWERED) && !switch_channel_test_flag(caller_channel, CF_ANSWERED)) {
01244                 switch_channel_pass_callee_id(peer_channel, caller_channel);
01245                 switch_channel_answer(caller_channel);
01246         }
01247 
01248         if (switch_channel_test_flag(peer_channel, CF_ANSWERED) || switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA) ||
01249                 switch_channel_test_flag(peer_channel, CF_RING_READY)) {
01250                 const char *app, *data;
01251                 
01252                 if (!switch_channel_ready(caller_channel)) {
01253                         abort_call(caller_channel, peer_channel);
01254                         goto done;
01255                 }
01256 
01257                 switch_channel_set_state(peer_channel, CS_CONSUME_MEDIA);
01258 
01259                 switch_channel_set_variable(peer_channel, "call_uuid", switch_core_session_get_uuid(session));
01260                 
01261                 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_BRIDGE) == SWITCH_STATUS_SUCCESS) {
01262                         switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-A-Unique-ID", switch_core_session_get_uuid(session));
01263                         switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", switch_core_session_get_uuid(peer_session));
01264                         switch_channel_event_set_data(caller_channel, event);
01265                         switch_event_add_presence_data_cols(peer_channel, event, "Bridge-B-PD-");
01266                         switch_event_fire(&event);
01267                         br = 1;
01268                 }
01269 
01270                 if (switch_core_session_read_lock(peer_session) == SWITCH_STATUS_SUCCESS) {
01271                         switch_channel_set_variable(caller_channel, SWITCH_BRIDGE_VARIABLE, switch_core_session_get_uuid(peer_session));
01272                         switch_channel_set_variable(peer_channel, SWITCH_BRIDGE_VARIABLE, switch_core_session_get_uuid(session));
01273                         switch_channel_set_variable(caller_channel, SWITCH_LAST_BRIDGE_VARIABLE, switch_core_session_get_uuid(peer_session));
01274                         switch_channel_set_variable(peer_channel, SWITCH_LAST_BRIDGE_VARIABLE, switch_core_session_get_uuid(session));
01275 
01276                         if (!switch_channel_ready(caller_channel)) {
01277                                 abort_call(caller_channel, peer_channel);
01278                                 switch_core_session_rwunlock(peer_session);
01279                                 goto done;
01280                         }
01281 
01282                         if (!switch_channel_media_ready(caller_channel) ||
01283                                 (!switch_channel_test_flag(peer_channel, CF_ANSWERED) && !switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA))) {
01284                                 if ((status = switch_ivr_wait_for_answer(session, peer_session)) != SWITCH_STATUS_SUCCESS || !switch_channel_ready(caller_channel)) {
01285                                         switch_channel_state_t w_state = switch_channel_get_state(caller_channel);
01286                                         switch_channel_hangup(peer_channel, SWITCH_CAUSE_ALLOTTED_TIMEOUT);
01287                                         if (w_state < CS_HANGUP && w_state != CS_ROUTING && w_state != CS_PARK &&
01288                                                 !switch_channel_test_flag(caller_channel, CF_REDIRECT) && !switch_channel_test_flag(caller_channel, CF_TRANSFER) &&
01289                                                 w_state != CS_EXECUTE) {
01290                                                 const char *ext = switch_channel_get_variable(peer_channel, "original_destination_number");
01291                                                 if (!ext) {
01292                                                         ext = switch_channel_get_variable(peer_channel, "destination_number");
01293                                                 }
01294 
01295                                                 if (ext) {
01296                                                         switch_ivr_session_transfer(session, ext, NULL, NULL);
01297                                                 } else {
01298                                                         switch_channel_hangup(caller_channel, SWITCH_CAUSE_ALLOTTED_TIMEOUT);
01299                                                 }
01300                                         }
01301                                         abort_call(caller_channel, peer_channel);
01302                                         switch_core_session_rwunlock(peer_session);
01303                                         goto done;
01304                                 }
01305 
01306                                 if (switch_channel_test_flag(peer_channel, CF_ANSWERED) && !switch_channel_test_flag(caller_channel, CF_ANSWERED)) {
01307                                         switch_channel_answer(caller_channel);
01308                                 }
01309                         }
01310 
01311                         switch_channel_wait_for_flag(peer_channel, CF_BROADCAST, SWITCH_FALSE, 10000, caller_channel);
01312                         switch_ivr_parse_all_events(peer_session);
01313                         switch_ivr_parse_all_events(session);
01314 
01315                         msg.message_id = SWITCH_MESSAGE_INDICATE_BRIDGE;
01316                         msg.from = __FILE__;
01317                         msg.string_arg = switch_core_session_strdup(peer_session, switch_core_session_get_uuid(session));
01318 
01319                         if (switch_core_session_receive_message(peer_session, &msg) != SWITCH_STATUS_SUCCESS) {
01320                                 status = SWITCH_STATUS_FALSE;
01321                                 abort_call(caller_channel, peer_channel);
01322                                 switch_core_session_rwunlock(peer_session);
01323                                 goto done;
01324                         }
01325 
01326                         msg.string_arg = switch_core_session_strdup(session, switch_core_session_get_uuid(peer_session));
01327                         if (switch_core_session_receive_message(session, &msg) != SWITCH_STATUS_SUCCESS) {
01328                                 status = SWITCH_STATUS_FALSE;
01329                                 abort_call(caller_channel, peer_channel);
01330                                 switch_core_session_rwunlock(peer_session);
01331                                 goto done;
01332                         }
01333 
01334                         switch_channel_set_variable(caller_channel, SWITCH_BRIDGE_CHANNEL_VARIABLE, switch_channel_get_name(peer_channel));
01335                         switch_channel_set_variable(caller_channel, SWITCH_BRIDGE_UUID_VARIABLE, switch_core_session_get_uuid(peer_session));
01336                         switch_channel_set_variable(caller_channel, SWITCH_SIGNAL_BOND_VARIABLE, switch_core_session_get_uuid(peer_session));
01337                         switch_channel_set_variable(peer_channel, SWITCH_BRIDGE_CHANNEL_VARIABLE, switch_channel_get_name(caller_channel));
01338                         switch_channel_set_variable(peer_channel, SWITCH_BRIDGE_UUID_VARIABLE, switch_core_session_get_uuid(session));
01339                         switch_channel_set_variable(peer_channel, SWITCH_SIGNAL_BOND_VARIABLE, switch_core_session_get_uuid(session));
01340 
01341                         if ((app = switch_channel_get_variable(caller_channel, "bridge_pre_execute_aleg_app"))) {
01342                                 switch_channel_set_variable(caller_channel, "bridge_pre_execute_app", app);
01343                                 
01344                                 if ((data = switch_channel_get_variable(caller_channel, "bridge_pre_execute_aleg_data"))) {
01345                                         switch_channel_set_variable(caller_channel, "bridge_pre_execute_data", data);
01346                                 }
01347                         }
01348 
01349                         if ((app = switch_channel_get_variable(caller_channel, "bridge_pre_execute_bleg_app"))) {
01350                                 switch_channel_set_variable(peer_channel, "bridge_pre_execute_app", app);
01351 
01352                                 if ((data = switch_channel_get_variable(caller_channel, "bridge_pre_execute_bleg_data"))) {
01353                                         switch_channel_set_variable(peer_channel, "bridge_pre_execute_data", data);
01354                                 }
01355                                 
01356                         }
01357                         
01358                         switch_channel_set_private(peer_channel, "_bridge_", b_leg);
01359                         switch_channel_set_state(peer_channel, CS_EXCHANGE_MEDIA);
01360                         audio_bridge_thread(NULL, (void *) a_leg);
01361 
01362                         switch_channel_clear_flag_recursive(caller_channel, CF_BRIDGE_ORIGINATOR);
01363 
01364                         switch_channel_stop_broadcast(peer_channel);
01365 
01366 
01367                         while (switch_channel_get_state(peer_channel) == CS_EXCHANGE_MEDIA) {
01368                                 switch_ivr_parse_all_messages(session);
01369                                 switch_cond_next();
01370                         }
01371 
01372                         if (inner_bridge) {
01373                                 if (switch_channel_ready(caller_channel)) {
01374                                         switch_channel_set_flag(caller_channel, CF_BRIDGED);
01375                                 }
01376 
01377                                 if (switch_channel_ready(peer_channel)) {
01378                                         switch_channel_set_flag(peer_channel, CF_BRIDGED);
01379                                 }
01380                         }
01381 
01382                         if ((cause = switch_channel_get_cause(caller_channel))) {
01383                                 switch_channel_set_variable(peer_channel, SWITCH_BRIDGE_HANGUP_CAUSE_VARIABLE, switch_channel_cause2str(cause));
01384                         }
01385 
01386                         if ((cause = switch_channel_get_cause(peer_channel))) {
01387                                 switch_channel_set_variable(caller_channel, SWITCH_BRIDGE_HANGUP_CAUSE_VARIABLE, switch_channel_cause2str(cause));
01388                         }
01389                         
01390                         if (switch_channel_down_nosig(peer_channel)) {
01391                                 switch_bool_t copy_xml_cdr = switch_true(switch_channel_get_variable(peer_channel, SWITCH_COPY_XML_CDR_VARIABLE));
01392                                 switch_bool_t copy_json_cdr = switch_true(switch_channel_get_variable(peer_channel, SWITCH_COPY_JSON_CDR_VARIABLE));
01393 
01394                                 if (copy_xml_cdr || copy_json_cdr) {
01395                                         char *cdr_text = NULL;                                  
01396 
01397                                         switch_channel_wait_for_state(peer_channel, caller_channel, CS_DESTROY);
01398 
01399                                         if (copy_xml_cdr) {
01400                                                 switch_xml_t cdr = NULL;
01401 
01402                                                 if (switch_ivr_generate_xml_cdr(peer_session, &cdr) == SWITCH_STATUS_SUCCESS) {
01403                                                         cdr_text = switch_xml_toxml(cdr, SWITCH_FALSE);
01404                                                         switch_xml_free(cdr);
01405                                                 }
01406                                         }
01407                                         if (copy_json_cdr) {
01408                                                 cJSON *cdr = NULL;
01409 
01410                                                 if (switch_ivr_generate_json_cdr(peer_session, &cdr, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) {
01411                                                         cdr_text = cJSON_PrintUnformatted(cdr);
01412                                                         cJSON_Delete(cdr);
01413                                                 }
01414                                         }
01415 
01416                                         if (cdr_text) {
01417                                                 switch_channel_set_variable(caller_channel, "b_leg_cdr", cdr_text);
01418                                                 switch_channel_set_variable_name_printf(caller_channel, cdr_text, "b_leg_cdr_%s", switch_core_session_get_uuid(peer_session));
01419                                                 switch_safe_free(cdr_text);
01420                                         }
01421                                 }
01422                                         
01423                         }
01424                         
01425                         switch_core_session_rwunlock(peer_session);
01426 
01427                 } else {
01428                         status = SWITCH_STATUS_FALSE;
01429                 }
01430         } else {
01431                 status = SWITCH_STATUS_FALSE;
01432         }
01433 
01434         if (status != SWITCH_STATUS_SUCCESS) {
01435                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Bridge Failed %s->%s\n",
01436                                                   switch_channel_get_name(caller_channel), switch_channel_get_name(peer_channel)
01437                         );
01438                 switch_channel_hangup(peer_channel, SWITCH_CAUSE_NO_ANSWER);
01439         }
01440 
01441   done:
01442 
01443         switch_channel_set_variable(peer_channel, "call_uuid", switch_core_session_get_uuid(peer_session));
01444 
01445         if (br && switch_event_create(&event, SWITCH_EVENT_CHANNEL_UNBRIDGE) == SWITCH_STATUS_SUCCESS) {
01446                 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-A-Unique-ID", switch_core_session_get_uuid(session));
01447                 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-B-Unique-ID", switch_core_session_get_uuid(peer_session));
01448                 switch_channel_event_set_data(caller_channel, event);
01449                 switch_event_add_presence_data_cols(peer_channel, event, "Bridge-B-PD-");
01450                 switch_event_fire(&event);
01451         }
01452 
01453         msg.message_id = SWITCH_MESSAGE_INDICATE_UNBRIDGE;
01454         msg.from = __FILE__;
01455         msg.string_arg = switch_core_session_strdup(peer_session, switch_core_session_get_uuid(session));
01456         switch_core_session_receive_message(peer_session, &msg);
01457 
01458         msg.string_arg = switch_core_session_strdup(session, switch_core_session_get_uuid(peer_session));
01459         switch_core_session_receive_message(session, &msg);
01460 
01461         state = switch_channel_get_state(caller_channel);
01462 
01463 
01464         if (!switch_channel_test_flag(caller_channel, CF_TRANSFER) && !switch_channel_test_flag(caller_channel, CF_REDIRECT) &&
01465                 !switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE) && !a_leg->clean_exit && !inner_bridge) {
01466                 if ((state != CS_EXECUTE && state != CS_SOFT_EXECUTE && state != CS_PARK && state != CS_ROUTING) ||
01467                         (switch_channel_test_flag(peer_channel, CF_ANSWERED) && state < CS_HANGUP)) {
01468 
01469                         if (switch_true(switch_channel_get_variable(caller_channel, SWITCH_PARK_AFTER_BRIDGE_VARIABLE))) {
01470                                 switch_ivr_park_session(session);
01471                         } else if ((var = switch_channel_get_variable(caller_channel, SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE))) {
01472                                 transfer_after_bridge(session, var);
01473                         } else if (switch_channel_test_flag(peer_channel, CF_ANSWERED) &&
01474                                            switch_true(switch_channel_get_variable(caller_channel, SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE))) {
01475                                 switch_call_cause_t cause = switch_channel_get_cause(peer_channel);
01476                                 if (cause == SWITCH_CAUSE_NONE) {
01477                                         cause = SWITCH_CAUSE_NORMAL_CLEARING;
01478                                 }
01479 
01480                                 if (switch_channel_test_flag(peer_channel, CF_INTERCEPTED)) {
01481                                         switch_channel_set_flag(peer_channel, CF_INTERCEPT);
01482                                 }
01483                                 switch_channel_hangup(caller_channel, cause);
01484                         }
01485                 }
01486         }
01487 
01488         if (switch_channel_test_flag(caller_channel, CF_REDIRECT)) {
01489                 if (switch_channel_test_flag(caller_channel, CF_RESET)) {
01490                         switch_channel_clear_flag(caller_channel, CF_RESET);
01491                 } else {
01492                         state = switch_channel_get_state(caller_channel);
01493                         if (!(state == CS_RESET || state == CS_PARK || state == CS_ROUTING)) {
01494                                 switch_channel_set_state(caller_channel, CS_RESET);
01495                         }
01496                 }
01497         }
01498 
01499         return status;
01500 }

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

Definition at line 618 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(), and switch_ivr_multi_threaded_bridge().

00619 {
00620         int argc;
00621         char *argv[4] = { 0 };
00622         char *mydata;
00623 
00624         switch_channel_set_variable(switch_core_session_get_channel(session), SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE, NULL);
00625 
00626         if (!zstr(where) && (mydata = switch_core_session_strdup(session, where))) {
00627                 if ((argc = switch_separate_string(mydata, ':', argv, (sizeof(argv) / sizeof(argv[0])))) >= 1) {
00628                         switch_ivr_session_transfer(session, argv[0], argv[1], argv[2]);
00629                 } else {
00630                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No extension specified.\n");
00631                 }
00632         }
00633 }

static switch_status_t uuid_bridge_on_hibernate ( switch_core_session_t session  )  [static]

Definition at line 755 of file switch_ivr_bridge.c.

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

static switch_status_t uuid_bridge_on_reset ( switch_core_session_t session  )  [static]

Definition at line 738 of file switch_ivr_bridge.c.

References CF_BRIDGE_ORIGINATOR, CF_ORIGINATING, 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.

00739 {
00740         switch_channel_t *channel = switch_core_session_get_channel(session);
00741 
00742         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CUSTOM RESET\n", switch_channel_get_name(channel));
00743 
00744         switch_channel_clear_flag(channel, CF_ORIGINATING);
00745 
00746         cleanup_proxy_mode_b(session);
00747 
00748         if (switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) {
00749                 switch_channel_set_state(channel, CS_SOFT_EXECUTE);
00750         }
00751 
00752         return SWITCH_STATUS_SUCCESS;
00753 }

static switch_status_t uuid_bridge_on_soft_execute ( switch_core_session_t session  )  [static]

Definition at line 761 of file switch_ivr_bridge.c.

References CF_BRIDGE_ORIGINATOR, CF_REDIRECT, CF_TRANSFER, 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_recursive(), 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_session_transfer(), switch_ivr_wait_for_answer(), SWITCH_LOG_DEBUG, switch_log_printf(), SWITCH_STACK_BOTTOM, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_true(), SWITCH_TRUE, SWITCH_UUID_BRIDGE, switch_yield, and uuid_bridge_state_handlers.

00762 {
00763         switch_channel_t *channel = switch_core_session_get_channel(session);
00764         switch_core_session_t *other_session;
00765         const char *other_uuid = NULL;
00766 
00767         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CUSTOM SOFT_EXECUTE\n", switch_channel_get_name(channel));
00768         switch_channel_clear_state_handler(channel, &uuid_bridge_state_handlers);
00769 
00770         if (!switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) {
00771                 return SWITCH_STATUS_SUCCESS;
00772         }
00773 
00774         if ((other_uuid = switch_channel_get_variable(channel, SWITCH_UUID_BRIDGE)) && (other_session = switch_core_session_locate(other_uuid))) {
00775                 switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
00776                 switch_event_t *event;
00777                 int ready_a, ready_b;
00778                 switch_channel_state_t state, running_state;
00779                 int max = 1000, loops = max;
00780 
00781                 switch_channel_set_variable(channel, SWITCH_UUID_BRIDGE, NULL);
00782                 
00783                 for (;;) {
00784                         state = switch_channel_get_state(other_channel);
00785                         running_state = switch_channel_get_running_state(other_channel);
00786 
00787                         if (switch_channel_down_nosig(other_channel) || switch_channel_down(channel)) {
00788                                 break;
00789                         }
00790 
00791                         if (state < CS_HANGUP && state == running_state) {
00792                                 
00793                                 if (--loops < 1) {
00794                                         switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
00795                                         switch_channel_hangup(other_channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
00796                                 }
00797 
00798                                 if (running_state == CS_RESET) {
00799                                         switch_channel_set_state(other_channel, CS_SOFT_EXECUTE);
00800                                 }
00801 
00802                                 if (running_state == CS_SOFT_EXECUTE) {
00803 
00804                                         if (switch_channel_test_flag(other_channel, CF_BRIDGE_ORIGINATOR)) {
00805                                                 goto done;
00806                                         } else {
00807                                                 break;
00808                                         }
00809                                 }
00810 
00811                         } else {
00812                                 loops = max;
00813                         }
00814                         
00815                         switch_yield(20000);
00816                 }
00817 
00818                 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
00819 
00820                 if (switch_ivr_wait_for_answer(session, other_session) != SWITCH_STATUS_SUCCESS) {
00821                         switch_core_session_rwunlock(other_session);
00822                         if (switch_true(switch_channel_get_variable(channel, "uuid_bridge_continue_on_cancel"))) {
00823                                 switch_channel_set_state(channel, CS_EXECUTE);
00824                         } else if (!switch_channel_test_flag(channel, CF_TRANSFER)) {
00825                                 switch_channel_hangup(channel, SWITCH_CAUSE_ORIGINATOR_CANCEL);
00826                         }
00827                         goto done;
00828                 }
00829 
00830                 ready_a = switch_channel_ready(channel);
00831                 ready_b = switch_channel_ready(other_channel);
00832 
00833                 if (!ready_a || !ready_b) {
00834                         if (!ready_a) {
00835                                 switch_channel_hangup(other_channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
00836                         }
00837 
00838                         if (!ready_b) {
00839                                 const char *cid = switch_channel_get_variable(other_channel, "rdnis");
00840                                 if (ready_a && cid) {
00841                                         switch_ivr_session_transfer(session, cid, NULL, NULL);
00842                                 } else {
00843                                         switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
00844                                 }
00845                         }
00846                         switch_core_session_rwunlock(other_session);
00847                         goto done;
00848                 }
00849 
00850                 /* fire events that will change the data table from "show channels" */
00851                 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_EXECUTE) == SWITCH_STATUS_SUCCESS) {
00852                         switch_channel_event_set_data(channel, event);
00853                         switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application", "uuid_bridge");
00854                         switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-Data", switch_core_session_get_uuid(other_session));
00855                         switch_event_fire(&event);
00856                 }
00857 
00858                 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_EXECUTE) == SWITCH_STATUS_SUCCESS) {
00859                         switch_channel_event_set_data(other_channel, event);
00860                         switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application", "uuid_bridge");
00861                         switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-Data", switch_core_session_get_uuid(session));
00862                         switch_event_fire(&event);
00863                 }
00864 
00865                 switch_ivr_multi_threaded_bridge(session, other_session, NULL, NULL, NULL);
00866 
00867                 state = switch_channel_get_state(channel);
00868                 if (!switch_channel_test_flag(channel, CF_TRANSFER) &&
00869                         !switch_channel_test_flag(channel, CF_REDIRECT) && state < CS_HANGUP && state != CS_ROUTING && state != CS_PARK) {
00870                         switch_channel_set_state(channel, CS_EXECUTE);
00871                 }
00872                 switch_core_session_rwunlock(other_session);
00873         } else {
00874                 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
00875         }
00876 
00877  done:
00878 
00879         switch_channel_clear_flag_recursive(channel, CF_BRIDGE_ORIGINATOR);
00880 
00881         return SWITCH_STATUS_FALSE;
00882 }


Variable Documentation

const switch_state_handler_table_t audio_bridge_peer_state_handlers [static]

Initial value:

Definition at line 712 of file switch_ivr_bridge.c.

const switch_state_handler_table_t audio_bridge_peer_state_handlers [static]

Definition at line 35 of file switch_ivr_bridge.c.

Referenced by audio_bridge_on_exchange_media(), and switch_ivr_multi_threaded_bridge().

const switch_state_handler_table_t signal_bridge_state_handlers [static]

Initial value:

 {
         NULL,
         NULL,
         NULL,
         signal_bridge_on_hangup,
         NULL,
         NULL,
         NULL,
         signal_bridge_on_hibernate
}

Definition at line 1091 of file switch_ivr_bridge.c.

Referenced by switch_ivr_signal_bridge().

const switch_state_handler_table_t uuid_bridge_state_handlers [static]

Initial value:

 {
         NULL,
         NULL,
         NULL,
         NULL,
         NULL,
         uuid_bridge_on_soft_execute,
         uuid_bridge_on_hibernate,
         uuid_bridge_on_hibernate,
         uuid_bridge_on_reset
}

Definition at line 726 of file switch_ivr_bridge.c.

Referenced by switch_ivr_uuid_bridge(), and uuid_bridge_on_soft_execute().


Generated on Sun May 20 04:00:11 2012 for FreeSWITCH API Documentation by  doxygen 1.4.7