[commit] r6573 - in freeswitch/trunk: conf/dialplan conf/noload_configs src src/include src/mod/applications/mod_dptools src/mod/applications/mod_limit
Author: anthm Date: Fri Dec 7 19:14:21 2007 New Revision: 6573 Removed: freeswitch/trunk/conf/noload_configs/ Modified: freeswitch/trunk/conf/dialplan/default.xml freeswitch/trunk/src/include/switch_channel.h freeswitch/trunk/src/include/switch_ivr.h freeswitch/trunk/src/include/switch_types.h freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c freeswitch/trunk/src/mod/applications/mod_limit/mod_limit.c freeswitch/trunk/src/switch_channel.c freeswitch/trunk/src/switch_core_state_machine.c freeswitch/trunk/src/switch_ivr_async.c freeswitch/trunk/src/switch_ivr_bridge.c Log: almost ready for b3 Modified: freeswitch/trunk/conf/dialplan/default.xml ============================================================================== --- freeswitch/trunk/conf/dialplan/default.xml (original) +++ freeswitch/trunk/conf/dialplan/default.xml Fri Dec 7 19:14:21 2007 @@ -1,4 +1,26 @@ <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"> <condition field="${network_addr}" condition="^$"> <action application="set" data="use_profile=${cond(${is_lan_addr($${local_ip_v4})} == yes ? nat : default)}"/> @@ -12,9 +34,56 @@ </condition> <condition> <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> + </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 NOT the called party dial the extension @@ -32,6 +101,8 @@ <anti-action application="set" data="call_timeout=30000"/> <anti-action application="set" data="hangup_after_bridge=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="voicemail" data="default $${domain} ${dialed_ext}"/> </condition> @@ -120,7 +191,6 @@ </condition> </extension> - <!-- this is a "catchall" extension that will match anything that's Modified: freeswitch/trunk/src/include/switch_channel.h ============================================================================== --- freeswitch/trunk/src/include/switch_channel.h (original) +++ freeswitch/trunk/src/include/switch_channel.h Fri Dec 7 19:14:21 2007 @@ -64,6 +64,7 @@ \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_running_state(switch_channel_t *channel); /*! \brief Determine if a channel is ready for io @@ -72,10 +73,15 @@ */ 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, 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 \param channel channel to set state of Modified: freeswitch/trunk/src/include/switch_ivr.h ============================================================================== --- freeswitch/trunk/src/include/switch_ivr.h (original) +++ freeswitch/trunk/src/include/switch_ivr.h Fri Dec 7 19:14:21 2007 @@ -718,6 +718,8 @@ 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_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 Modified: freeswitch/trunk/src/include/switch_types.h ============================================================================== --- freeswitch/trunk/src/include/switch_types.h (original) +++ freeswitch/trunk/src/include/switch_types.h Fri Dec 7 19:14:21 2007 @@ -1025,7 +1025,8 @@ SWITCH_CAUSE_ATTENDED_TRANSFER = 601, SWITCH_CAUSE_ALLOTTED_TIMEOUT = 602, SWITCH_CAUSE_USER_CHALLENGE = 603, - SWITCH_CAUSE_MEDIA_TIMEOUT = 604 + SWITCH_CAUSE_MEDIA_TIMEOUT = 604, + SWITCH_CAUSE_PICKED_OFF = 605 } switch_call_cause_t; typedef enum { Modified: freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c ============================================================================== --- freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c (original) +++ freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c Fri Dec 7 19:14:21 2007 @@ -86,7 +86,11 @@ } } - +#define INTERCEPT_SYNTAX "<uuid>" +SWITCH_STANDARD_APP(intercept_function) +{ + switch_ivr_intercept_session(session, data); +} #define eavesdrop_SYNTAX "<uuid>" @@ -1560,6 +1564,7 @@ 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, "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, "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); Modified: freeswitch/trunk/src/mod/applications/mod_limit/mod_limit.c ============================================================================== --- freeswitch/trunk/src/mod/applications/mod_limit/mod_limit.c (original) +++ freeswitch/trunk/src/mod/applications/mod_limit/mod_limit.c Fri Dec 7 19:14:21 2007 @@ -657,7 +657,7 @@ 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, "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 */ return SWITCH_STATUS_SUCCESS; Modified: freeswitch/trunk/src/switch_channel.c ============================================================================== --- freeswitch/trunk/src/switch_channel.c (original) +++ freeswitch/trunk/src/switch_channel.c Fri Dec 7 19:14:21 2007 @@ -98,6 +98,7 @@ {"ALLOTTED_TIMEOUT", SWITCH_CAUSE_ALLOTTED_TIMEOUT}, {"USER_CHALLENGE", SWITCH_CAUSE_USER_CHALLENGE}, {"MEDIA_TIMEOUT", SWITCH_CAUSE_MEDIA_TIMEOUT}, + {"PICKED_OFF", SWITCH_CAUSE_PICKED_OFF}, {NULL, 0} }; @@ -109,6 +110,7 @@ switch_mutex_t *profile_mutex; switch_core_session_t *session; switch_channel_state_t state; + switch_channel_state_t running_state; uint32_t flags; uint32_t state_flags; switch_caller_profile_t *caller_profile; @@ -469,6 +471,22 @@ 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) { assert(channel != NULL); @@ -502,6 +520,18 @@ 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) { uint8_t ret = 0; @@ -549,6 +579,38 @@ 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, const char *file, const char *func, int line, switch_channel_state_t state) { @@ -726,22 +788,6 @@ if (state == CS_HANGUP && !channel->hangup_cause) { 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) { switch_core_session_signal_state_change(channel->session); Modified: freeswitch/trunk/src/switch_core_state_machine.c ============================================================================== --- freeswitch/trunk/src/switch_core_state_machine.c (original) +++ freeswitch/trunk/src/switch_core_state_machine.c Fri Dec 7 19:14:21 2007 @@ -390,6 +390,7 @@ int index = 0; int proceed = 1; + switch_channel_set_running_state(session->channel); switch (state) { case CS_NEW: /* Just created, Waiting for first instructions */ Modified: freeswitch/trunk/src/switch_ivr_async.c ============================================================================== --- freeswitch/trunk/src/switch_ivr_async.c (original) +++ freeswitch/trunk/src/switch_ivr_async.c Fri Dec 7 19:14:21 2007 @@ -449,7 +449,7 @@ 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) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot attach bug\n"); goto end; Modified: freeswitch/trunk/src/switch_ivr_bridge.c ============================================================================== --- freeswitch/trunk/src/switch_ivr_bridge.c (original) +++ freeswitch/trunk/src/switch_ivr_bridge.c Fri Dec 7 19:14:21 2007 @@ -262,7 +262,7 @@ channel = switch_core_session_get_channel(session); 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 */ switch_channel_set_state(channel, CS_HOLD); @@ -276,7 +276,7 @@ channel = switch_core_session_get_channel(session); 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 */ return SWITCH_STATUS_FALSE; @@ -300,7 +300,7 @@ channel = switch_core_session_get_channel(session); 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); @@ -320,36 +320,32 @@ channel = switch_core_session_get_channel(session); 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); + if (!switch_channel_test_flag(channel, CF_ORIGINATOR)) { - switch_channel_set_flag(channel, CF_TAGGED); - return SWITCH_STATUS_FALSE; + return SWITCH_STATUS_SUCCESS; } if ((other_uuid = switch_channel_get_variable(channel, SWITCH_UUID_BRIDGE)) && (other_session = switch_core_session_locate(other_uuid))) { 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; 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_state(other_channel, CS_TRANSMIT); - for(;;) { - if (mystate >= CS_HANGUP || state >= CS_HANGUP || switch_channel_test_flag(other_channel, CF_TAGGED)) { - break; - } - 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_RESET); + + if (switch_channel_get_state(other_channel) == CS_RESET) { + switch_channel_set_state(other_channel, CS_TRANSMIT); } + + switch_channel_wait_for_state(channel, other_channel, CS_TRANSMIT); + switch_channel_clear_flag(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(other_session); @@ -368,19 +364,6 @@ 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" */ if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_EXECUTE) == SWITCH_STATUS_SUCCESS) { switch_channel_event_set_data(channel, event); @@ -704,6 +687,7 @@ switch_core_session_t *originator_session, *originatee_session; switch_channel_t *originator_channel, *originatee_channel; 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 ((originatee_session = switch_core_session_locate(originatee_uuid))) { @@ -720,6 +704,7 @@ switch_channel_clear_state_handler(originator_channel, NULL); switch_channel_clear_state_handler(originatee_channel, NULL); 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(originatee_channel, &uuid_bridge_state_handlers); switch_channel_set_variable(originator_channel, SWITCH_UUID_BRIDGE, switch_core_session_get_uuid(originatee_session)); @@ -732,6 +717,24 @@ 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)); + + 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(originatee_channel, CF_BREAK); @@ -759,3 +762,42 @@ 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); +}
participants (1)
-
Freeswitch SVN