提交 69120105 authored 作者: Anthony Minessale's avatar Anthony Minessale

support crazy transfer crap

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@7083 d0543943-73ff-0310-b7d9-9358b9ac24b2
上级 cb03f74e
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
<!--<param name="dtmf-type" value="info"/>--> <!--<param name="dtmf-type" value="info"/>-->
<param name="record-template" value="$${base_dir}/recordings/${caller_id_number}.${strftime(%Y-%m-%d-%H-%M-%S)}.wav"/> <param name="record-template" value="$${base_dir}/recordings/${caller_id_number}.${strftime(%Y-%m-%d-%H-%M-%S)}.wav"/>
<!--enable to use presense and mwi --> <!--enable to use presense and mwi -->
<param name="manage-presence" value="true"/> <param name="manage-presence" value="false"/>
<!-- This setting is for AAL2 bitpacking on G726 --> <!-- This setting is for AAL2 bitpacking on G726 -->
<!-- <param name="bitpacking" value="aal2"/> --> <!-- <param name="bitpacking" value="aal2"/> -->
<!--max number of open dialogs in proceeding --> <!--max number of open dialogs in proceeding -->
......
...@@ -727,6 +727,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro(switch_core_session_t *s ...@@ -727,6 +727,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro(switch_core_session_t *s
SWITCH_DECLARE(void) switch_ivr_delay_echo(switch_core_session_t *session, uint32_t delay_ms); SWITCH_DECLARE(void) switch_ivr_delay_echo(switch_core_session_t *session, uint32_t delay_ms);
SWITCH_DECLARE(void) switch_ivr_intercept_session(switch_core_session_t *session, const char *uuid); SWITCH_DECLARE(void) switch_ivr_intercept_session(switch_core_session_t *session, const char *uuid);
SWITCH_DECLARE(void) switch_ivr_park_session(switch_core_session_t *session); SWITCH_DECLARE(void) switch_ivr_park_session(switch_core_session_t *session);
SWITCH_DECLARE(switch_status_t) switch_ivr_wait_for_answer(switch_core_session_t *session, switch_core_session_t *peer_session);
/** @} */ /** @} */
......
...@@ -628,6 +628,7 @@ CF_UNICAST = (1 << 21) - Channel has a unicast connection ...@@ -628,6 +628,7 @@ CF_UNICAST = (1 << 21) - Channel has a unicast connection
CF_VIDEO = (1 << 22) - Channel has video CF_VIDEO = (1 << 22) - Channel has video
CF_EVENT_LOCK = (1 << 23) - Don't parse events CF_EVENT_LOCK = (1 << 23) - Don't parse events
CF_RESET = (1 << 24) - Tell extension parser to reset CF_RESET = (1 << 24) - Tell extension parser to reset
CF_ORIGINATING = (1 << 25) - Channel is originating
</pre> </pre>
*/ */
...@@ -656,7 +657,8 @@ typedef enum { ...@@ -656,7 +657,8 @@ typedef enum {
CF_UNICAST = (1 << 21), CF_UNICAST = (1 << 21),
CF_VIDEO = (1 << 22), CF_VIDEO = (1 << 22),
CF_EVENT_LOCK = (1 << 23), CF_EVENT_LOCK = (1 << 23),
CF_RESET = (1 << 24) CF_RESET = (1 << 24),
CF_ORIGINATING = (1 << 25)
} switch_channel_flag_t; } switch_channel_flag_t;
......
...@@ -1685,6 +1685,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session ...@@ -1685,6 +1685,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session
switch_channel_set_variable(nchannel, "sip_destination_url", tech_pvt->dest); switch_channel_set_variable(nchannel, "sip_destination_url", tech_pvt->dest);
caller_profile = switch_caller_profile_clone(nsession, outbound_profile); caller_profile = switch_caller_profile_clone(nsession, outbound_profile);
caller_profile->destination_number = switch_core_strdup(caller_profile->pool, dest);
switch_channel_set_caller_profile(nchannel, caller_profile); switch_channel_set_caller_profile(nchannel, caller_profile);
switch_channel_set_flag(nchannel, CF_OUTBOUND); switch_channel_set_flag(nchannel, CF_OUTBOUND);
switch_set_flag_locked(tech_pvt, TFLAG_OUTBOUND); switch_set_flag_locked(tech_pvt, TFLAG_OUTBOUND);
......
...@@ -132,7 +132,7 @@ static void switch_core_standard_on_execute(switch_core_session_t *session) ...@@ -132,7 +132,7 @@ static void switch_core_standard_on_execute(switch_core_session_t *session)
char *expanded = NULL; char *expanded = NULL;
int nomedia = 0; int nomedia = 0;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Execute %s(%s)\n", switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Execute %s(%s)\n", switch_channel_get_name(session->channel),
extension->current_application->application_name, switch_str_nil(extension->current_application->application_data)); extension->current_application->application_name, switch_str_nil(extension->current_application->application_data));
if ((application_interface = switch_loadable_module_get_application_interface(extension->current_application->application_name)) == 0) { if ((application_interface = switch_loadable_module_get_application_interface(extension->current_application->application_name)) == 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Application %s\n", extension->current_application->application_name); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Application %s\n", extension->current_application->application_name);
...@@ -156,8 +156,9 @@ static void switch_core_standard_on_execute(switch_core_session_t *session) ...@@ -156,8 +156,9 @@ static void switch_core_standard_on_execute(switch_core_session_t *session)
if ((expanded = if ((expanded =
switch_channel_expand_variables(session->channel, switch_channel_expand_variables(session->channel,
extension->current_application->application_data)) != extension->current_application->application_data) { extension->current_application->application_data)) != extension->current_application->application_data) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Expanded String %s(%s)\n", extension->current_application->application_name, switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Expanded String %s(%s)\n", switch_channel_get_name(session->channel),
expanded); extension->current_application->application_name, expanded);
} }
if (switch_channel_get_variable(session->channel, "presence_id")) { if (switch_channel_get_variable(session->channel, "presence_id")) {
......
...@@ -852,6 +852,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_session_transfer(switch_core_session_ ...@@ -852,6 +852,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_session_transfer(switch_core_session_
channel = switch_core_session_get_channel(session); channel = switch_core_session_get_channel(session);
switch_assert(channel != NULL); switch_assert(channel != NULL);
switch_channel_clear_flag(channel, CF_ORIGINATING);
/* clear all state handlers */ /* clear all state handlers */
switch_channel_clear_state_handler(channel, NULL); switch_channel_clear_state_handler(channel, NULL);
......
...@@ -596,7 +596,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses ...@@ -596,7 +596,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses
switch_channel_answer(caller_channel); switch_channel_answer(caller_channel);
} }
if (switch_channel_test_flag(peer_channel, CF_ANSWERED) || switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA)) { if (switch_channel_test_flag(peer_channel, CF_ANSWERED) || switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA) ||
switch_channel_test_flag(peer_channel, CF_RING_READY)) {
switch_event_t *event; switch_event_t *event;
switch_core_session_message_t msg = { 0 }; switch_core_session_message_t msg = { 0 };
const switch_application_interface_t *application_interface; const switch_application_interface_t *application_interface;
...@@ -627,7 +628,29 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses ...@@ -627,7 +628,29 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses
} }
} }
if (!(switch_channel_test_flag(peer_channel, CF_ANSWERED) || switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA))) {
if ((status = switch_ivr_wait_for_answer(session, peer_session)) != SWITCH_STATUS_SUCCESS) {
switch_channel_state_t w_state = switch_channel_get_state(caller_channel);
switch_channel_hangup(peer_channel, SWITCH_CAUSE_ALLOTTED_TIMEOUT);
if (w_state < CS_HANGUP && w_state != CS_RING && w_state != CS_PARK && !switch_channel_test_flag(caller_channel, CF_TRANSFER) &&
w_state != CS_EXECUTE) {
const char *ext = switch_channel_get_variable(peer_channel, "original_destination_number");
if (!ext) {
ext = switch_channel_get_variable(peer_channel, "destination_number");
}
if (ext) {
switch_ivr_session_transfer(session, ext, NULL, NULL);
} else {
switch_channel_hangup(caller_channel, SWITCH_CAUSE_ALLOTTED_TIMEOUT);
}
}
switch_core_session_rwunlock(peer_session);
goto done;
}
}
msg.message_id = SWITCH_MESSAGE_INDICATE_BRIDGE; msg.message_id = SWITCH_MESSAGE_INDICATE_BRIDGE;
msg.from = __FILE__; msg.from = __FILE__;
msg.string_arg = switch_core_session_strdup(peer_session, switch_core_session_get_uuid(session)); msg.string_arg = switch_core_session_strdup(peer_session, switch_core_session_get_uuid(session));
...@@ -707,8 +730,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses ...@@ -707,8 +730,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses
SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uuid, const char *originatee_uuid) SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uuid, const char *originatee_uuid)
{ {
switch_core_session_t *originator_session, *originatee_session; switch_core_session_t *originator_session, *originatee_session, *swap_session;
switch_channel_t *originator_channel, *originatee_channel; switch_channel_t *originator_channel, *originatee_channel, *swap_channel;
switch_status_t status = SWITCH_STATUS_FALSE; switch_status_t status = SWITCH_STATUS_FALSE;
switch_caller_profile_t *cp, *originator_cp, *originatee_cp; switch_caller_profile_t *cp, *originator_cp, *originatee_cp;
...@@ -717,6 +740,23 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uu ...@@ -717,6 +740,23 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uu
originator_channel = switch_core_session_get_channel(originator_session); originator_channel = switch_core_session_get_channel(originator_session);
originatee_channel = switch_core_session_get_channel(originatee_session); originatee_channel = switch_core_session_get_channel(originatee_session);
if (!switch_channel_test_flag(originator_channel, CF_ANSWERED)) {
if (switch_channel_test_flag(originatee_channel, CF_ANSWERED)) {
swap_session = originator_session;
originator_session = originatee_session;
originatee_session = swap_session;
swap_channel = originator_channel;
originator_channel = originatee_channel;
originatee_channel = swap_channel;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "reversing order of channels so this will work!\n");
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Neither channel is answered, cannot bridge them.\n");
return SWITCH_STATUS_FALSE;
}
}
/* override transmit state for originator_channel to bridge to originatee_channel /* override transmit state for originator_channel to bridge to originatee_channel
* install pointer to originatee_session into originator_channel * install pointer to originatee_session into originator_channel
* set CF_TRANSFER on both channels and change state to CS_TRANSMIT to * set CF_TRANSFER on both channels and change state to CS_TRANSMIT to
...@@ -726,12 +766,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uu ...@@ -726,12 +766,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uu
switch_channel_clear_state_handler(originator_channel, NULL); switch_channel_clear_state_handler(originator_channel, NULL);
switch_channel_clear_state_handler(originatee_channel, NULL); switch_channel_clear_state_handler(originatee_channel, NULL);
switch_channel_set_flag(originator_channel, CF_ORIGINATOR); switch_channel_set_state_flag(originator_channel, CF_ORIGINATOR);
switch_channel_clear_flag(originatee_channel, CF_ORIGINATOR); switch_channel_clear_flag(originatee_channel, CF_ORIGINATOR);
switch_channel_add_state_handler(originator_channel, &uuid_bridge_state_handlers); switch_channel_add_state_handler(originator_channel, &uuid_bridge_state_handlers);
switch_channel_add_state_handler(originatee_channel, &uuid_bridge_state_handlers); switch_channel_add_state_handler(originatee_channel, &uuid_bridge_state_handlers);
switch_channel_set_variable(originator_channel, SWITCH_UUID_BRIDGE, switch_core_session_get_uuid(originatee_session)); switch_channel_set_variable(originator_channel, SWITCH_UUID_BRIDGE, switch_core_session_get_uuid(originatee_session));
switch_channel_set_variable(originator_channel, SWITCH_BRIDGE_CHANNEL_VARIABLE, switch_channel_get_name(originatee_channel)); switch_channel_set_variable(originator_channel, SWITCH_BRIDGE_CHANNEL_VARIABLE, switch_channel_get_name(originatee_channel));
switch_channel_set_variable(originator_channel, SWITCH_BRIDGE_UUID_VARIABLE, switch_core_session_get_uuid(originatee_session)); switch_channel_set_variable(originator_channel, SWITCH_BRIDGE_UUID_VARIABLE, switch_core_session_get_uuid(originatee_session));
...@@ -743,6 +784,16 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uu ...@@ -743,6 +784,16 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uu
originator_cp = switch_channel_get_caller_profile(originator_channel); originator_cp = switch_channel_get_caller_profile(originator_channel);
originatee_cp = switch_channel_get_caller_profile(originatee_channel); originatee_cp = switch_channel_get_caller_profile(originatee_channel);
switch_channel_set_variable(originatee_channel, "original_destination_number", originatee_cp->destination_number);
switch_channel_set_variable(originatee_channel, "original_caller_id_name", originatee_cp->caller_id_name);
switch_channel_set_variable(originatee_channel, "original_caller_id_number", originatee_cp->caller_id_number);
switch_channel_set_variable(originator_channel, "original_destination_number", originator_cp->destination_number);
switch_channel_set_variable(originator_channel, "original_caller_id_name", originator_cp->caller_id_name);
switch_channel_set_variable(originator_channel, "original_caller_id_number", originator_cp->caller_id_number);
cp = switch_caller_profile_clone(originatee_session, originatee_cp); cp = switch_caller_profile_clone(originatee_session, originatee_cp);
cp->destination_number = switch_core_strdup(cp->pool, originator_cp->caller_id_number); cp->destination_number = switch_core_strdup(cp->pool, originator_cp->caller_id_number);
...@@ -750,7 +801,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uu ...@@ -750,7 +801,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uu
cp->caller_id_name = switch_core_strdup(cp->pool, originator_cp->caller_id_name); cp->caller_id_name = switch_core_strdup(cp->pool, originator_cp->caller_id_name);
switch_channel_set_caller_profile(originatee_channel, cp); switch_channel_set_caller_profile(originatee_channel, cp);
switch_channel_set_originator_caller_profile(originatee_channel, switch_caller_profile_clone(originatee_session, originator_cp)); switch_channel_set_originator_caller_profile(originatee_channel, switch_caller_profile_clone(originatee_session, originator_cp));
cp = switch_caller_profile_clone(originator_session, originator_cp); cp = switch_caller_profile_clone(originator_session, originator_cp);
cp->destination_number = switch_core_strdup(cp->pool, originatee_cp->caller_id_number); cp->destination_number = switch_core_strdup(cp->pool, originatee_cp->caller_id_number);
cp->caller_id_number = switch_core_strdup(cp->pool, originatee_cp->caller_id_number); cp->caller_id_number = switch_core_strdup(cp->pool, originatee_cp->caller_id_number);
...@@ -763,6 +814,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uu ...@@ -763,6 +814,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uu
switch_channel_set_flag(originator_channel, CF_TRANSFER); switch_channel_set_flag(originator_channel, CF_TRANSFER);
switch_channel_set_flag(originatee_channel, CF_TRANSFER); switch_channel_set_flag(originatee_channel, CF_TRANSFER);
switch_channel_clear_flag(originator_channel, CF_ORIGINATING);
switch_channel_clear_flag(originatee_channel, CF_ORIGINATING);
/* change the states and let the chips fall where they may */ /* change the states and let the chips fall where they may */
switch_channel_set_state(originator_channel, CS_RESET); switch_channel_set_state(originator_channel, CS_RESET);
......
差异被折叠。
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论