diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index a668f14376..de696cd743 100644 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -1578,31 +1578,40 @@ SWITCH_STANDARD_APP(att_xfer_function) switch_channel_clear_flag(peer_channel, CF_INNER_BRIDGE); switch_channel_clear_flag(channel, CF_INNER_BRIDGE); - if (switch_channel_down(peer_channel)) { + if (zstr(bond) && switch_channel_down(peer_channel)) { switch_core_session_rwunlock(peer_session); goto end; } if (bond) { char buf[128] = ""; - - if (!switch_channel_ready(channel)) { - switch_ivr_uuid_bridge(switch_core_session_get_uuid(peer_session), bond); - } else if ((b_session = switch_core_session_locate(bond))) { - switch_channel_t *b_channel = switch_core_session_get_channel(b_session); - switch_snprintf(buf, sizeof(buf), "%s %s", switch_core_session_get_uuid(peer_session), switch_core_session_get_uuid(session)); - switch_channel_set_variable(b_channel, "xfer_uuids", buf); - - switch_snprintf(buf, sizeof(buf), "%s %s", switch_core_session_get_uuid(peer_session), bond); - switch_channel_set_variable(channel, "xfer_uuids", buf); - - switch_core_event_hook_add_state_change(session, hanguphook); - switch_core_event_hook_add_state_change(b_session, hanguphook); - - switch_core_session_rwunlock(b_session); - } + int br = 0; switch_channel_set_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE, bond); + + if (!switch_channel_down(peer_channel)) { + if (!switch_channel_ready(channel)) { + switch_ivr_uuid_bridge(switch_core_session_get_uuid(peer_session), bond); + br++; + } else if ((b_session = switch_core_session_locate(bond))) { + switch_channel_t *b_channel = switch_core_session_get_channel(b_session); + switch_snprintf(buf, sizeof(buf), "%s %s", switch_core_session_get_uuid(peer_session), switch_core_session_get_uuid(session)); + switch_channel_set_variable(b_channel, "xfer_uuids", buf); + + switch_snprintf(buf, sizeof(buf), "%s %s", switch_core_session_get_uuid(peer_session), bond); + switch_channel_set_variable(channel, "xfer_uuids", buf); + + switch_core_event_hook_add_state_change(session, hanguphook); + switch_core_event_hook_add_state_change(b_session, hanguphook); + + switch_core_session_rwunlock(b_session); + } + } + + if (!br) { + switch_ivr_uuid_bridge(switch_core_session_get_uuid(session), bond); + } + } switch_core_session_rwunlock(peer_session); diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 2e900c8e9f..f51a1915dc 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -1472,11 +1472,16 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_get_app_flags(const char *ap if ((application_interface = switch_loadable_module_get_application_interface(app)) == 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Application %s\n", app); + goto end; } else if (application_interface->flags) { *flags = application_interface->flags; status = SWITCH_STATUS_SUCCESS; } + UNPROTECT_INTERFACE(application_interface); + + end: + return status; } @@ -1524,6 +1529,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_execute_application_get_flag switch_core_session_exec(session, application_interface, arg); done: + UNPROTECT_INTERFACE(application_interface); return status; diff --git a/src/switch_ivr.c b/src/switch_ivr.c index df33e9f5db..1cf1617d07 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -501,7 +501,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_parse_event(switch_core_session_t *se } if (cmd_hash == CMD_EXECUTE) { - switch_application_interface_t *application_interface; char *app_name = switch_event_get_header(event, "execute-app-name"); char *app_arg = switch_event_get_header(event, "execute-app-arg"); char *loop_h = switch_event_get_header(event, "loops"); @@ -513,61 +512,60 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_parse_event(switch_core_session_t *se } if (app_name) { - if ((application_interface = switch_loadable_module_get_application_interface(app_name))) { - if (application_interface->application_function) { - int x; - const char *b_uuid = NULL; - switch_core_session_t *b_session = NULL; + int x; + const char *b_uuid = NULL; + switch_core_session_t *b_session = NULL; - switch_channel_clear_flag(channel, CF_STOP_BROADCAST); - switch_channel_set_flag(channel, CF_BROADCAST); - if (hold_bleg && switch_true(hold_bleg)) { - if ((b_uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))) { - const char *stream; - b_uuid = switch_core_session_strdup(session, b_uuid); + switch_channel_clear_flag(channel, CF_STOP_BROADCAST); + switch_channel_set_flag(channel, CF_BROADCAST); + if (hold_bleg && switch_true(hold_bleg)) { + if ((b_uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))) { + const char *stream; + b_uuid = switch_core_session_strdup(session, b_uuid); - if (!(stream = switch_channel_get_variable_partner(channel, SWITCH_HOLD_MUSIC_VARIABLE))) { - stream = switch_channel_get_variable(channel, SWITCH_HOLD_MUSIC_VARIABLE); - } - - if (stream && switch_is_moh(stream)) { - if ((b_session = switch_core_session_locate(b_uuid))) { - switch_channel_t *b_channel = switch_core_session_get_channel(b_session); - switch_ivr_broadcast(b_uuid, stream, SMF_ECHO_ALEG | SMF_LOOP); - switch_channel_wait_for_flag(b_channel, CF_BROADCAST, SWITCH_TRUE, 5000, NULL); - switch_core_session_rwunlock(b_session); - } - } else { - b_uuid = NULL; - } - } - } - for (x = 0; x < loops || loops < 0; x++) { - switch_time_t b4, aftr; - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Command Execute %s(%s)\n", - switch_channel_get_name(channel), app_name, switch_str_nil(app_arg)); - b4 = switch_micro_time_now(); - switch_core_session_exec(session, application_interface, app_arg); - aftr = switch_micro_time_now(); - if (!switch_channel_ready(channel) || switch_channel_test_flag(channel, CF_STOP_BROADCAST) || aftr - b4 < 500000) { - break; - } + if (!(stream = switch_channel_get_variable_partner(channel, SWITCH_HOLD_MUSIC_VARIABLE))) { + stream = switch_channel_get_variable(channel, SWITCH_HOLD_MUSIC_VARIABLE); } - if (b_uuid) { + if (stream && switch_is_moh(stream)) { if ((b_session = switch_core_session_locate(b_uuid))) { switch_channel_t *b_channel = switch_core_session_get_channel(b_session); - switch_channel_stop_broadcast(b_channel); - switch_channel_wait_for_flag(b_channel, CF_BROADCAST, SWITCH_FALSE, 5000, NULL); + switch_ivr_broadcast(b_uuid, stream, SMF_ECHO_ALEG | SMF_LOOP); + switch_channel_wait_for_flag(b_channel, CF_BROADCAST, SWITCH_TRUE, 5000, NULL); switch_core_session_rwunlock(b_session); } + } else { + b_uuid = NULL; } - - switch_channel_clear_flag(channel, CF_BROADCAST); } - UNPROTECT_INTERFACE(application_interface); } + + for (x = 0; x < loops || loops < 0; x++) { + switch_time_t b4, aftr; + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Command Execute %s(%s)\n", + switch_channel_get_name(channel), app_name, switch_str_nil(app_arg)); + b4 = switch_micro_time_now(); + if (switch_core_session_execute_application(session, app_name, app_arg) != SWITCH_STATUS_SUCCESS) { + goto done; + } + + aftr = switch_micro_time_now(); + if (!switch_channel_ready(channel) || switch_channel_test_flag(channel, CF_STOP_BROADCAST) || aftr - b4 < 500000) { + break; + } + } + + if (b_uuid) { + if ((b_session = switch_core_session_locate(b_uuid))) { + switch_channel_t *b_channel = switch_core_session_get_channel(b_session); + switch_channel_stop_broadcast(b_channel); + switch_channel_wait_for_flag(b_channel, CF_BROADCAST, SWITCH_FALSE, 5000, NULL); + switch_core_session_rwunlock(b_session); + } + } + + switch_channel_clear_flag(channel, CF_BROADCAST); } } else if (cmd_hash == CMD_UNICAST) { char *local_ip = switch_event_get_header(event, "local-ip"); diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index 1967555092..6acd1fbe08 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -637,7 +637,8 @@ static switch_status_t audio_bridge_on_exchange_media(switch_core_session_t *ses } if (switch_channel_get_state(channel) == CS_EXCHANGE_MEDIA) { - switch_channel_set_state(channel, CS_RESET); + switch_channel_set_variable(channel, "park_timeout", "3"); + switch_channel_set_state(channel, CS_PARK); } return SWITCH_STATUS_FALSE;