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

1.3.9.1