almost ready for b3

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@6573 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2007-12-08 00:14:21 +00:00
parent 74e2d0e37f
commit 4bc03bb392
10 changed files with 226 additions and 53 deletions

View File

@ -1,4 +1,26 @@
<context name="default"> <context name="default">
<extension name="intercept">
<condition field="destination_number" expression="^886$">
<action application="answer"/>
<action application="intercept" data="${db(select/last_dial/global)}"/>
<action application="sleep" data="2000"/>
</condition>
</extension>
<extension name="intercept-ext">
<condition field="destination_number" expression="^886(\d+)$">
<action application="answer"/>
<action application="intercept" data="${db(select/last_dial_ext/$1)}"/>
<action application="sleep" data="2000"/>
</condition>
</extension>
<extension name="redial">
<condition field="destination_number" expression="^870$">
<action application="transfer" data="${db(select/last_dial/${caller_id_number})}"/>
</condition>
</extension>
<extension name="global" continue="true"> <extension name="global" continue="true">
<condition field="${network_addr}" condition="^$"> <condition field="${network_addr}" condition="^$">
<action application="set" data="use_profile=${cond(${is_lan_addr($${local_ip_v4})} == yes ? nat : default)}"/> <action application="set" data="use_profile=${cond(${is_lan_addr($${local_ip_v4})} == yes ? nat : default)}"/>
@ -12,9 +34,56 @@
</condition> </condition>
<condition> <condition>
<action application="info"/> <action application="info"/>
<action application="db" data="insert/spymap/${caller_id_number}/${uuid}"/>
<action application="db" data="insert/last_dial/${caller_id_number}/${destination_number}"/>
<action application="db" data="insert/last_dial/global/${uuid}"/>
</condition> </condition>
</extension> </extension>
<extension name="eavesdrop">
<condition field="destination_number" expression="^88(.*)$|^*0(.*)$">
<action application="answer"/>
<action application="eavesdrop" data="${db(select/spymap/$1)}"/>
</condition>
</extension>
<extension name="star-69">
<condition field="destination_number" expression="^\*69$|^869$">
<action application="transfer" data="${db(select/call_return/${caller_id_number})}"/>
</condition>
</extension>
<extension name="add-group">
<condition field="destination_number" expression="^81(\d{2})$">
<action application="answer"/>
<action application="group" data="insert:$1:${sofia_contact(${sip_from_user}@${domain})}"/>
<action application="gentones" data="%(1000, 0, 640)"/>
</condition>
</extension>
<extension name="del-group">
<condition field="destination_number" expression="^80(\d{2})$">
<action application="answer"/>
<action application="group" data="delete:$1:${sofia_contact(${sip_from_user}@${domain})}"/>
<action application="gentones" data="%(1000, 0, 320)"/>
</condition>
</extension>
<extension name="call-group-simo">
<condition field="destination_number" expression="^82(\d{2})$">
<action application="bridge" data="${group(call:$1)}"/>
</condition>
</extension>
<extension name="call-group-order">
<condition field="destination_number" expression="^83(\d{2})$">
<action application="set" data="call_timeout=10"/>
<action application="bridge" data="${group(call:$1:order)}"/>
</condition>
</extension>
<!-- <!--
if the calling party is the called party, go to their VM if the calling party is the called party, go to their VM
if the calling party is NOT the called party dial the extension if the calling party is NOT the called party dial the extension
@ -32,6 +101,8 @@
<anti-action application="set" data="call_timeout=30000"/> <anti-action application="set" data="call_timeout=30000"/>
<anti-action application="set" data="hangup_after_bridge=true"/> <anti-action application="set" data="hangup_after_bridge=true"/>
<anti-action application="set" data="continue_on_fail=true"/> <anti-action application="set" data="continue_on_fail=true"/>
<anti-action application="db" data="insert/call_return/${dialed_ext}/${caller_id_number}"/>
<anti-action application="db" data="insert/last_dial_ext/${dialed_ext}/${uuid}"/>
<anti-action application="bridge" data="sofia/$${domain}/${dialed_ext}"/> <anti-action application="bridge" data="sofia/$${domain}/${dialed_ext}"/>
<anti-action application="voicemail" data="default $${domain} ${dialed_ext}"/> <anti-action application="voicemail" data="default $${domain} ${dialed_ext}"/>
</condition> </condition>
@ -120,7 +191,6 @@
</condition> </condition>
</extension> </extension>
<!-- <!--
this is a "catchall" extension that will match anything that's this is a "catchall" extension that will match anything that's

View File

@ -64,6 +64,7 @@ typedef struct switch_channel_timetable switch_channel_timetable_t;
\return current state of channel \return current state of channel
*/ */
SWITCH_DECLARE(switch_channel_state_t) switch_channel_get_state(switch_channel_t *channel); SWITCH_DECLARE(switch_channel_state_t) switch_channel_get_state(switch_channel_t *channel);
SWITCH_DECLARE(switch_channel_state_t) switch_channel_get_running_state(switch_channel_t *channel);
/*! /*!
\brief Determine if a channel is ready for io \brief Determine if a channel is ready for io
@ -72,10 +73,15 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_get_state(switch_channel_t
*/ */
SWITCH_DECLARE(uint8_t) switch_channel_ready(switch_channel_t *channel); SWITCH_DECLARE(uint8_t) switch_channel_ready(switch_channel_t *channel);
SWITCH_DECLARE(void) switch_channel_wait_for_state(switch_channel_t *channel, switch_channel_t *other_channel, switch_channel_state_t want_state);
SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_channel_t *channel, SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_channel_t *channel,
const char *file, const char *func, int line, switch_channel_state_t state); const char *file, const char *func, int line, switch_channel_state_t state);
SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_running_state(switch_channel_t *channel,
const char *file, const char *func, int line);
#define switch_channel_set_running_state(channel) switch_channel_perform_set_running_state(channel, __FILE__, __SWITCH_FUNC__, __LINE__)
/*! /*!
\brief Set the current state of a channel \brief Set the current state of a channel
\param channel channel to set state of \param channel channel to set state of

View File

@ -718,6 +718,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_menu_stack_xml_init(switch_ivr_menu_x
SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro(switch_core_session_t *session, const char *macro_name, const char *data, const char *lang, SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro(switch_core_session_t *session, const char *macro_name, const char *data, const char *lang,
switch_input_args_t *args); switch_input_args_t *args);
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_END_EXTERN_C SWITCH_END_EXTERN_C

View File

@ -1025,7 +1025,8 @@ typedef enum {
SWITCH_CAUSE_ATTENDED_TRANSFER = 601, SWITCH_CAUSE_ATTENDED_TRANSFER = 601,
SWITCH_CAUSE_ALLOTTED_TIMEOUT = 602, SWITCH_CAUSE_ALLOTTED_TIMEOUT = 602,
SWITCH_CAUSE_USER_CHALLENGE = 603, SWITCH_CAUSE_USER_CHALLENGE = 603,
SWITCH_CAUSE_MEDIA_TIMEOUT = 604 SWITCH_CAUSE_MEDIA_TIMEOUT = 604,
SWITCH_CAUSE_PICKED_OFF = 605
} switch_call_cause_t; } switch_call_cause_t;
typedef enum { typedef enum {

View File

@ -86,7 +86,11 @@ SWITCH_STANDARD_APP(exe_function)
} }
} }
#define INTERCEPT_SYNTAX "<uuid>"
SWITCH_STANDARD_APP(intercept_function)
{
switch_ivr_intercept_session(session, data);
}
#define eavesdrop_SYNTAX "<uuid>" #define eavesdrop_SYNTAX "<uuid>"
@ -1560,6 +1564,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
SWITCH_ADD_APP(app_interface, "sched_broadcast", SCHED_BROADCAST_DESCR, SCHED_BROADCAST_DESCR, sched_broadcast_function, "[+]<time> <path> [aleg|bleg|both]", SAF_SUPPORT_NOMEDIA); SWITCH_ADD_APP(app_interface, "sched_broadcast", SCHED_BROADCAST_DESCR, SCHED_BROADCAST_DESCR, sched_broadcast_function, "[+]<time> <path> [aleg|bleg|both]", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "sched_transfer", SCHED_TRANSF_DESCR, SCHED_TRANSF_DESCR, sched_transfer_function, "[+]<time> <extension> <dialplan> <context>", SAF_SUPPORT_NOMEDIA); SWITCH_ADD_APP(app_interface, "sched_transfer", SCHED_TRANSF_DESCR, SCHED_TRANSF_DESCR, sched_transfer_function, "[+]<time> <extension> <dialplan> <context>", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "execute_extension", "Execute an extension", "Execute an extension", exe_function, EXE_SYNTAX, SAF_SUPPORT_NOMEDIA); SWITCH_ADD_APP(app_interface, "execute_extension", "Execute an extension", "Execute an extension", exe_function, EXE_SYNTAX, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "intercept", "intercept", "intercept", intercept_function, INTERCEPT_SYNTAX, SAF_NONE);
SWITCH_ADD_APP(app_interface, "eavesdrop", "eavesdrop on a uuid", "eavesdrop on a uuid", eavesdrop_function, eavesdrop_SYNTAX, SAF_NONE); SWITCH_ADD_APP(app_interface, "eavesdrop", "eavesdrop on a uuid", "eavesdrop on a uuid", eavesdrop_function, eavesdrop_SYNTAX, SAF_NONE);
SWITCH_ADD_APP(app_interface, "set_user", "Set a User", "Set a User", set_user_function, SET_USER_SYNTAX, SAF_SUPPORT_NOMEDIA); SWITCH_ADD_APP(app_interface, "set_user", "Set a User", "Set a User", set_user_function, SET_USER_SYNTAX, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "stop_dtmf", "stop inband dtmf", "Stop detecting inband dtmf.", stop_dtmf_session_function, "", SAF_NONE); SWITCH_ADD_APP(app_interface, "stop_dtmf", "stop inband dtmf", "Stop detecting inband dtmf.", stop_dtmf_session_function, "", SAF_NONE);

View File

@ -657,7 +657,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_limit_load)
SWITCH_ADD_APP(app_interface, "group", "Manage a group", GROUP_DESC, group_function, GROUP_USAGE, SAF_NONE); SWITCH_ADD_APP(app_interface, "group", "Manage a group", GROUP_DESC, group_function, GROUP_USAGE, SAF_NONE);
SWITCH_ADD_API(commands_api_interface, "db", "db get/set", db_api_function, "[get|set]/<realm>/<key>/<value>"); SWITCH_ADD_API(commands_api_interface, "db", "db get/set", db_api_function, "[get|set]/<realm>/<key>/<value>");
SWITCH_ADD_API(commands_api_interface, "group", "group [insert|delete|call]", group_api_function, "[insert|delete|call] <group name> <url>"); SWITCH_ADD_API(commands_api_interface, "group", "group [insert|delete|call]", group_api_function, "[insert|delete|call]:<group name>:<url>");
/* indicate that the module should continue to be loaded */ /* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;

View File

@ -98,6 +98,7 @@ static struct switch_cause_table CAUSE_CHART[] = {
{"ALLOTTED_TIMEOUT", SWITCH_CAUSE_ALLOTTED_TIMEOUT}, {"ALLOTTED_TIMEOUT", SWITCH_CAUSE_ALLOTTED_TIMEOUT},
{"USER_CHALLENGE", SWITCH_CAUSE_USER_CHALLENGE}, {"USER_CHALLENGE", SWITCH_CAUSE_USER_CHALLENGE},
{"MEDIA_TIMEOUT", SWITCH_CAUSE_MEDIA_TIMEOUT}, {"MEDIA_TIMEOUT", SWITCH_CAUSE_MEDIA_TIMEOUT},
{"PICKED_OFF", SWITCH_CAUSE_PICKED_OFF},
{NULL, 0} {NULL, 0}
}; };
@ -109,6 +110,7 @@ struct switch_channel {
switch_mutex_t *profile_mutex; switch_mutex_t *profile_mutex;
switch_core_session_t *session; switch_core_session_t *session;
switch_channel_state_t state; switch_channel_state_t state;
switch_channel_state_t running_state;
uint32_t flags; uint32_t flags;
uint32_t state_flags; uint32_t state_flags;
switch_caller_profile_t *caller_profile; switch_caller_profile_t *caller_profile;
@ -469,6 +471,22 @@ SWITCH_DECLARE(switch_bool_t) switch_channel_clear_flag_partner(switch_channel_t
return SWITCH_FALSE; return SWITCH_FALSE;
} }
SWITCH_DECLARE(void) switch_channel_wait_for_state(switch_channel_t *channel, switch_channel_t *other_channel, switch_channel_state_t want_state)
{
switch_channel_state_t state, mystate, ostate;
ostate = switch_channel_get_state(channel);
for(;;) {
state = switch_channel_get_running_state(other_channel);
mystate = switch_channel_get_running_state(channel);
if (mystate != ostate || state >= CS_HANGUP || state == want_state) {
break;
}
switch_yield(1000);
}
}
SWITCH_DECLARE(void) switch_channel_set_flag(switch_channel_t *channel, switch_channel_flag_t flags) SWITCH_DECLARE(void) switch_channel_set_flag(switch_channel_t *channel, switch_channel_flag_t flags)
{ {
assert(channel != NULL); assert(channel != NULL);
@ -502,6 +520,18 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_get_state(switch_channel_t
return state; return state;
} }
SWITCH_DECLARE(switch_channel_state_t) switch_channel_get_running_state(switch_channel_t *channel)
{
switch_channel_state_t state;
assert(channel != NULL);
switch_mutex_lock(channel->flag_mutex);
state = channel->running_state;
switch_mutex_unlock(channel->flag_mutex);
return state;
}
SWITCH_DECLARE(uint8_t) switch_channel_ready(switch_channel_t *channel) SWITCH_DECLARE(uint8_t) switch_channel_ready(switch_channel_t *channel)
{ {
uint8_t ret = 0; uint8_t ret = 0;
@ -549,6 +579,38 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_name_state(const char *nam
return CS_DONE; return CS_DONE;
} }
SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_running_state(switch_channel_t *channel,
const char *file, const char *func, int line)
{
switch_mutex_lock(channel->flag_mutex);
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_DEBUG, "%s Running State Change %s\n",
channel->name, state_names[channel->state]);
channel->running_state = channel->state;
if (channel->state < CS_HANGUP) {
switch_event_t *event;
if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_STATE) == SWITCH_STATUS_SUCCESS) {
if (channel->state == CS_RING) {
switch_channel_event_set_data(channel, event);
} else {
char state_num[25];
snprintf(state_num, sizeof(state_num), "%d", channel->state);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-State", "%s", (char *) switch_channel_state_name(channel->state));
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-State-Number", "%s", (char *) state_num);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Name", "%s", channel->name);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Unique-ID", "%s", switch_core_session_get_uuid(channel->session));
}
switch_event_fire(&event);
}
}
switch_mutex_unlock(channel->flag_mutex);
return SWITCH_STATUS_SUCCESS;
}
SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_channel_t *channel, SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_channel_t *channel,
const char *file, const char *func, int line, switch_channel_state_t state) const char *file, const char *func, int line, switch_channel_state_t state)
{ {
@ -726,22 +788,6 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_c
if (state == CS_HANGUP && !channel->hangup_cause) { if (state == CS_HANGUP && !channel->hangup_cause) {
channel->hangup_cause = SWITCH_CAUSE_NORMAL_CLEARING; channel->hangup_cause = SWITCH_CAUSE_NORMAL_CLEARING;
} }
if (state < CS_HANGUP) {
switch_event_t *event;
if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_STATE) == SWITCH_STATUS_SUCCESS) {
if (state == CS_RING) {
switch_channel_event_set_data(channel, event);
} else {
char state_num[25];
snprintf(state_num, sizeof(state_num), "%d", channel->state);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-State", "%s", (char *) switch_channel_state_name(channel->state));
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-State-Number", "%s", (char *) state_num);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Name", "%s", channel->name);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Unique-ID", "%s", switch_core_session_get_uuid(channel->session));
}
switch_event_fire(&event);
}
}
if (state < CS_DONE) { if (state < CS_DONE) {
switch_core_session_signal_state_change(channel->session); switch_core_session_signal_state_change(channel->session);

View File

@ -390,6 +390,7 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session)
int index = 0; int index = 0;
int proceed = 1; int proceed = 1;
switch_channel_set_running_state(session->channel);
switch (state) { switch (state) {
case CS_NEW: /* Just created, Waiting for first instructions */ case CS_NEW: /* Just created, Waiting for first instructions */

View File

@ -449,7 +449,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session
if (switch_core_media_bug_add(tsession, eavesdrop_callback, &ep, 0, if (switch_core_media_bug_add(tsession, eavesdrop_callback, &ep, 0,
SMBF_READ_STREAM | SMBF_WRITE_STREAM | SMBF_READ_REPLACE | SMBF_WRITE_REPLACE, SMBF_READ_STREAM | SMBF_WRITE_STREAM | SMBF_READ_REPLACE | SMBF_WRITE_REPLACE | SMBF_READ_PING,
&bug) != SWITCH_STATUS_SUCCESS) { &bug) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot attach bug\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot attach bug\n");
goto end; goto end;

View File

@ -262,7 +262,7 @@ static switch_status_t audio_bridge_on_ring(switch_core_session_t *session)
channel = switch_core_session_get_channel(session); channel = switch_core_session_get_channel(session);
assert(channel != NULL); assert(channel != NULL);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CUSTOM RING\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CUSTOM RING\n", switch_channel_get_name(channel));
/* put the channel in a passive state so we can loop audio to it */ /* put the channel in a passive state so we can loop audio to it */
switch_channel_set_state(channel, CS_HOLD); switch_channel_set_state(channel, CS_HOLD);
@ -276,7 +276,7 @@ static switch_status_t audio_bridge_on_hold(switch_core_session_t *session)
channel = switch_core_session_get_channel(session); channel = switch_core_session_get_channel(session);
assert(channel != NULL); assert(channel != NULL);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CUSTOM HOLD\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CUSTOM HOLD\n", switch_channel_get_name(channel));
/* put the channel in a passive state so we can loop audio to it */ /* put the channel in a passive state so we can loop audio to it */
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
@ -300,7 +300,7 @@ static switch_status_t uuid_bridge_on_reset(switch_core_session_t *session)
channel = switch_core_session_get_channel(session); channel = switch_core_session_get_channel(session);
assert(channel != NULL); assert(channel != NULL);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CUSTOM RESET\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CUSTOM RESET\n", switch_channel_get_name(channel));
switch_channel_clear_flag(channel, CF_TRANSFER); switch_channel_clear_flag(channel, CF_TRANSFER);
@ -320,36 +320,32 @@ static switch_status_t uuid_bridge_on_transmit(switch_core_session_t *session)
channel = switch_core_session_get_channel(session); channel = switch_core_session_get_channel(session);
assert(channel != NULL); assert(channel != NULL);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CUSTOM TRANSMIT\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CUSTOM TRANSMIT\n", switch_channel_get_name(channel));
switch_channel_clear_state_handler(channel, NULL); switch_channel_clear_state_handler(channel, NULL);
if (!switch_channel_test_flag(channel, CF_ORIGINATOR)) { if (!switch_channel_test_flag(channel, CF_ORIGINATOR)) {
switch_channel_set_flag(channel, CF_TAGGED); return SWITCH_STATUS_SUCCESS;
return SWITCH_STATUS_FALSE;
} }
if ((other_uuid = switch_channel_get_variable(channel, SWITCH_UUID_BRIDGE)) && if ((other_uuid = switch_channel_get_variable(channel, SWITCH_UUID_BRIDGE)) &&
(other_session = switch_core_session_locate(other_uuid))) { (other_session = switch_core_session_locate(other_uuid))) {
switch_channel_t *other_channel = switch_core_session_get_channel(other_session); switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
switch_channel_state_t state = switch_channel_get_state(other_channel);
switch_channel_state_t mystate = switch_channel_get_state(channel);
switch_event_t *event; switch_event_t *event;
uint8_t ready_a, ready_b; uint8_t ready_a, ready_b;
switch_caller_profile_t *profile, *new_profile;
switch_channel_set_variable(channel, SWITCH_UUID_BRIDGE, NULL); switch_channel_set_variable(channel, SWITCH_UUID_BRIDGE, NULL);
switch_channel_set_state(other_channel, CS_TRANSMIT);
for(;;) { switch_channel_wait_for_state(channel, other_channel, CS_RESET);
if (mystate >= CS_HANGUP || state >= CS_HANGUP || switch_channel_test_flag(other_channel, CF_TAGGED)) {
break; if (switch_channel_get_state(other_channel) == CS_RESET) {
} switch_channel_set_state(other_channel, CS_TRANSMIT);
switch_yield(1000);
state = switch_channel_get_state(other_channel);
mystate = switch_channel_get_state(channel);
} }
switch_channel_wait_for_state(channel, other_channel, CS_TRANSMIT);
switch_channel_clear_flag(channel, CF_TRANSFER); switch_channel_clear_flag(channel, CF_TRANSFER);
switch_channel_clear_flag(other_channel, CF_TRANSFER); switch_channel_clear_flag(other_channel, CF_TRANSFER);
switch_channel_clear_flag(other_channel, CF_TAGGED);
switch_core_session_reset(session); switch_core_session_reset(session);
switch_core_session_reset(other_session); switch_core_session_reset(other_session);
@ -368,19 +364,6 @@ static switch_status_t uuid_bridge_on_transmit(switch_core_session_t *session)
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
} }
/* add another profile to both sessions for CDR's sake */
if ((profile = switch_channel_get_caller_profile(channel))) {
new_profile = switch_caller_profile_clone(session, profile);
new_profile->destination_number = switch_core_session_strdup(session, switch_core_session_get_uuid(other_session));
switch_channel_set_caller_profile(channel, new_profile);
}
if ((profile = switch_channel_get_caller_profile(other_channel))) {
new_profile = switch_caller_profile_clone(other_session, profile);
new_profile->destination_number = switch_core_session_strdup(other_session, switch_core_session_get_uuid(session));
switch_channel_set_caller_profile(other_channel, new_profile);
}
/* fire events that will change the data table from "show channels" */ /* fire events that will change the data table from "show channels" */
if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_EXECUTE) == SWITCH_STATUS_SUCCESS) { if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_EXECUTE) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(channel, event); switch_channel_event_set_data(channel, event);
@ -704,6 +687,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uu
switch_core_session_t *originator_session, *originatee_session; switch_core_session_t *originator_session, *originatee_session;
switch_channel_t *originator_channel, *originatee_channel; switch_channel_t *originator_channel, *originatee_channel;
switch_status_t status = SWITCH_STATUS_FALSE; switch_status_t status = SWITCH_STATUS_FALSE;
switch_caller_profile_t *cp, *originator_cp, *originatee_cp;
if ((originator_session = switch_core_session_locate(originator_uuid))) { if ((originator_session = switch_core_session_locate(originator_uuid))) {
if ((originatee_session = switch_core_session_locate(originatee_uuid))) { if ((originatee_session = switch_core_session_locate(originatee_uuid))) {
@ -720,6 +704,7 @@ 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_flag(originator_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));
@ -732,6 +717,24 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uu
switch_channel_set_variable(originatee_channel, SWITCH_BRIDGE_UUID_VARIABLE, switch_core_session_get_uuid(originator_session)); switch_channel_set_variable(originatee_channel, SWITCH_BRIDGE_UUID_VARIABLE, switch_core_session_get_uuid(originator_session));
switch_channel_set_variable(originatee_channel, SWITCH_SIGNAL_BOND_VARIABLE, switch_core_session_get_uuid(originator_session)); switch_channel_set_variable(originatee_channel, SWITCH_SIGNAL_BOND_VARIABLE, switch_core_session_get_uuid(originator_session));
originator_cp = switch_channel_get_caller_profile(originator_channel);
originatee_cp = switch_channel_get_caller_profile(originatee_channel);
cp = switch_caller_profile_clone(originatee_session, originatee_cp);
cp->destination_number = switch_core_strdup(cp->pool, originator_cp->caller_id_number);
cp->caller_id_number = switch_core_strdup(cp->pool, originator_cp->caller_id_number);
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_originator_caller_profile(originatee_channel, switch_caller_profile_clone(originatee_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->caller_id_number = switch_core_strdup(cp->pool, originatee_cp->caller_id_number);
cp->caller_id_name = switch_core_strdup(cp->pool, originatee_cp->caller_id_name);
switch_channel_set_caller_profile(originator_channel, cp);
switch_channel_set_originatee_caller_profile(originator_channel, switch_caller_profile_clone(originator_session, originatee_cp));
switch_channel_set_flag(originator_channel, CF_BREAK); switch_channel_set_flag(originator_channel, CF_BREAK);
switch_channel_set_flag(originatee_channel, CF_BREAK); switch_channel_set_flag(originatee_channel, CF_BREAK);
@ -759,3 +762,42 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uu
return status; return status;
} }
SWITCH_DECLARE(void) switch_ivr_intercept_session(switch_core_session_t *session, const char *uuid)
{
switch_core_session_t *rsession, *bsession;
switch_channel_t *channel, *rchannel, *bchannel;
const char *buuid;
if (switch_strlen_zero(uuid) || !(rsession = switch_core_session_locate(uuid))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "no uuid %s\n", uuid);
return;
}
channel = switch_core_session_get_channel(session);
rchannel = switch_core_session_get_channel(rsession);
switch_channel_answer(channel);
buuid = switch_channel_get_variable(rchannel, SWITCH_SIGNAL_BOND_VARIABLE);
switch_channel_set_state_flag(rchannel, CF_TRANSFER);
switch_channel_set_state(rchannel, CS_RESET);
if (buuid) {
if ((bsession = switch_core_session_locate(buuid))) {
bchannel = switch_core_session_get_channel(bsession);
switch_channel_hangup(bchannel, SWITCH_CAUSE_PICKED_OFF);
switch_core_session_rwunlock(bsession);
}
}
if (!switch_channel_test_flag(rchannel, CF_ANSWERED)) {
switch_channel_answer(rchannel);
}
switch_core_session_rwunlock(rsession);
switch_ivr_uuid_bridge(switch_core_session_get_uuid(session), uuid);
}