#include <switch.h>Include dependency graph for switch_ivr_bridge.c:
Go to the source code of this file.
| #define DEFAULT_LEAD_FRAMES 10 |
| typedef struct switch_ivr_bridge_data switch_ivr_bridge_data_t |
Definition at line 159 of file switch_ivr_bridge.c.
| 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.
00756 { 00757 switch_channel_set_state(switch_core_session_get_channel(session), CS_RESET); 00758 return SWITCH_STATUS_FALSE; 00759 }
| 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 }
const switch_state_handler_table_t audio_bridge_peer_state_handlers [static] |
Initial value:
{
NULL,
audio_bridge_on_routing,
NULL,
NULL,
audio_bridge_on_exchange_media,
NULL,
audio_bridge_on_consume_media,
}
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().
1.4.7