Main Page | Modules | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

switch_ivr_bridge.c File Reference


Data Structures

struct  switch_ivr_bridge_data

Typedefs

typedef switch_ivr_bridge_data switch_ivr_bridge_data_t

Functions

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


Typedef Documentation

typedef struct switch_ivr_bridge_data switch_ivr_bridge_data_t
 


Function Documentation

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
 

00651 {
00652         switch_ivr_bridge_data_t *a_leg = switch_core_session_alloc(session, sizeof(*a_leg));
00653         switch_ivr_bridge_data_t *b_leg = switch_core_session_alloc(peer_session, sizeof(*b_leg));
00654         switch_channel_t *caller_channel = switch_core_session_get_channel(session);
00655         switch_channel_t *peer_channel = switch_core_session_get_channel(peer_session);
00656         int stream_id = 0;
00657         switch_status_t status = SWITCH_STATUS_SUCCESS;
00658         switch_channel_state_t state;
00659         switch_event_t *event;
00660         int br = 0;
00661         int inner_bridge = switch_channel_test_flag(caller_channel, CF_INNER_BRIDGE);
00662         
00663         switch_channel_set_flag(caller_channel, CF_ORIGINATOR);
00664         switch_channel_clear_flag(caller_channel, CF_TRANSFER);
00665         switch_channel_clear_flag(peer_channel, CF_TRANSFER);
00666 
00667         b_leg->session = peer_session;
00668         switch_copy_string(b_leg->b_uuid, switch_core_session_get_uuid(session), sizeof(b_leg->b_uuid));
00669         b_leg->stream_id = stream_id;
00670         b_leg->input_callback = input_callback;
00671         b_leg->session_data = peer_session_data;
00672 
00673         a_leg->session = session;
00674         switch_copy_string(a_leg->b_uuid, switch_core_session_get_uuid(peer_session), sizeof(a_leg->b_uuid));
00675         a_leg->stream_id = stream_id;
00676         a_leg->input_callback = input_callback;
00677         a_leg->session_data = session_data;
00678 
00679         switch_channel_add_state_handler(peer_channel, &audio_bridge_peer_state_handlers);
00680 
00681         if (switch_channel_test_flag(peer_channel, CF_ANSWERED) && !switch_channel_test_flag(caller_channel, CF_ANSWERED)) {
00682                 switch_channel_answer(caller_channel);
00683         }
00684 
00685         if (switch_channel_test_flag(peer_channel, CF_ANSWERED) || switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA) ||
00686                 switch_channel_test_flag(peer_channel, CF_RING_READY)) {
00687                 switch_core_session_message_t msg = { 0 };
00688                 const switch_application_interface_t *application_interface;
00689                 const char *app, *data;
00690 
00691                 switch_channel_set_state(peer_channel, CS_CONSUME_MEDIA);
00692 
00693                 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_BRIDGE) == SWITCH_STATUS_SUCCESS) {
00694                         switch_channel_event_set_data(caller_channel, event);
00695                         switch_event_fire(&event);
00696                         br = 1;
00697                 }
00698                 
00699                 if (switch_core_session_read_lock(peer_session) == SWITCH_STATUS_SUCCESS) {
00700                         switch_channel_set_variable(caller_channel, SWITCH_BRIDGE_VARIABLE, switch_core_session_get_uuid(peer_session));
00701                         switch_channel_set_variable(peer_channel, SWITCH_BRIDGE_VARIABLE, switch_core_session_get_uuid(session));
00702 
00703                         if (!(switch_channel_test_flag(peer_channel, CF_ANSWERED) || switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA))) {
00704                                 if ((status = switch_ivr_wait_for_answer(session, peer_session)) != SWITCH_STATUS_SUCCESS) {
00705                                         switch_channel_state_t w_state = switch_channel_get_state(caller_channel);
00706                                         switch_channel_hangup(peer_channel, SWITCH_CAUSE_ALLOTTED_TIMEOUT);
00707                                         if (w_state < CS_HANGUP && w_state != CS_ROUTING && w_state != CS_PARK && !switch_channel_test_flag(caller_channel, CF_TRANSFER) &&
00708                                                 w_state != CS_EXECUTE) {
00709                                                 const char *ext = switch_channel_get_variable(peer_channel, "original_destination_number");
00710                                                 if (!ext) {
00711                                                         ext = switch_channel_get_variable(peer_channel, "destination_number");
00712                                                 }
00713 
00714                                                 if (ext) {
00715                                                         switch_ivr_session_transfer(session, ext, NULL, NULL);
00716                                                 } else {
00717                                                         switch_channel_hangup(caller_channel, SWITCH_CAUSE_ALLOTTED_TIMEOUT);
00718                                                 }
00719                                         }
00720                                         switch_core_session_rwunlock(peer_session);
00721                                         goto done;
00722                                 }
00723                                 if (switch_channel_test_flag(peer_channel, CF_ANSWERED) && !switch_channel_test_flag(caller_channel, CF_ANSWERED)) {
00724                                         switch_channel_answer(caller_channel);
00725                                 }
00726                         }
00727 
00728                         msg.message_id = SWITCH_MESSAGE_INDICATE_BRIDGE;
00729                         msg.from = __FILE__;
00730                         msg.string_arg = switch_core_session_strdup(peer_session, switch_core_session_get_uuid(session));
00731 
00732                         if (switch_core_session_receive_message(peer_session, &msg) != SWITCH_STATUS_SUCCESS) {
00733                                 status = SWITCH_STATUS_FALSE;
00734                                 switch_core_session_rwunlock(peer_session);
00735                                 goto done;
00736                         }
00737 
00738                         msg.string_arg = switch_core_session_strdup(session, switch_core_session_get_uuid(peer_session));
00739                         if (switch_core_session_receive_message(session, &msg) != SWITCH_STATUS_SUCCESS) {
00740                                 status = SWITCH_STATUS_FALSE;
00741                                 switch_core_session_rwunlock(peer_session);
00742                                 goto done;
00743                         }
00744 
00745                         switch_channel_set_variable(caller_channel, SWITCH_BRIDGE_CHANNEL_VARIABLE, switch_channel_get_name(peer_channel));
00746                         switch_channel_set_variable(caller_channel, SWITCH_BRIDGE_UUID_VARIABLE, switch_core_session_get_uuid(peer_session));
00747                         switch_channel_set_variable(caller_channel, SWITCH_SIGNAL_BOND_VARIABLE, switch_core_session_get_uuid(peer_session));
00748                         switch_channel_set_variable(peer_channel, SWITCH_BRIDGE_CHANNEL_VARIABLE, switch_channel_get_name(caller_channel));
00749                         switch_channel_set_variable(peer_channel, SWITCH_BRIDGE_UUID_VARIABLE, switch_core_session_get_uuid(session));
00750                         switch_channel_set_variable(peer_channel, SWITCH_SIGNAL_BOND_VARIABLE, switch_core_session_get_uuid(session));
00751                         
00752                         if ((app = switch_channel_get_variable(caller_channel, "bridge_pre_execute_aleg_app"))) {
00753                                 data = switch_channel_get_variable(caller_channel, "bridge_pre_execute_aleg_data");
00754                                 if ((application_interface = switch_loadable_module_get_application_interface(app))) {
00755                                         switch_core_session_exec(session, application_interface, data);
00756                                 }
00757                         }
00758                         
00759                         if ((app = switch_channel_get_variable(caller_channel, "bridge_pre_execute_bleg_app"))) {
00760                                 data = switch_channel_get_variable(caller_channel, "bridge_pre_execute_bleg_data");
00761                                 if ((application_interface = switch_loadable_module_get_application_interface(app))) {
00762                                         switch_core_session_exec(peer_session, application_interface, data);
00763                                 }
00764                         }
00765 
00766                         switch_channel_set_private(peer_channel, "_bridge_", b_leg);
00767                         switch_channel_set_state(peer_channel, CS_EXCHANGE_MEDIA);
00768                         audio_bridge_thread(NULL, (void *) a_leg);
00769 
00770                         switch_channel_clear_flag(caller_channel, CF_ORIGINATOR);
00771                         
00772                         if (!switch_channel_test_flag(peer_channel, CF_TRANSFER) && switch_channel_get_state(peer_channel) == CS_EXCHANGE_MEDIA) {
00773                                 switch_channel_set_state(peer_channel, CS_RESET);
00774                         }
00775 
00776                         while (switch_channel_get_state(peer_channel) == CS_EXCHANGE_MEDIA) {
00777                                 switch_yield(1000);
00778                         }
00779 
00780                         switch_core_session_rwunlock(peer_session);
00781 
00782                 } else {
00783                         status = SWITCH_STATUS_FALSE;
00784                 }
00785         } else {
00786                 status = SWITCH_STATUS_FALSE;
00787         }
00788 
00789         if (status != SWITCH_STATUS_SUCCESS) {
00790                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Bridge Failed %s->%s\n",
00791                                                   switch_channel_get_name(caller_channel), switch_channel_get_name(peer_channel)
00792                         );
00793                 switch_channel_hangup(peer_channel, SWITCH_CAUSE_NO_ANSWER);
00794         }
00795 
00796   done:
00797 
00798         if (br && switch_event_create(&event, SWITCH_EVENT_CHANNEL_UNBRIDGE) == SWITCH_STATUS_SUCCESS) {
00799                 switch_channel_event_set_data(caller_channel, event);
00800                 switch_event_fire(&event);
00801         }
00802 
00803         state = switch_channel_get_state(caller_channel);
00804         
00805         if (!switch_channel_test_flag(caller_channel, CF_TRANSFER) && !inner_bridge) {
00806                 if ((state != CS_EXECUTE && state != CS_PARK && state != CS_ROUTING) || 
00807                         (switch_channel_test_flag(peer_channel, CF_ANSWERED) && state < CS_HANGUP && 
00808                          switch_true(switch_channel_get_variable(caller_channel, SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE)))) {
00809                         switch_channel_hangup(caller_channel, switch_channel_get_cause(peer_channel));
00810                 }
00811         }
00812 
00813         return status;
00814 }

Here is the call graph for this function:


Generated on Mon May 26 22:06:52 2008 for FreeSWITCH by  doxygen 1.3.9.1