]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add loopback_bowout_on_execute var to make 1 legged loopback calls bow out of the...
authorAnthony Minessale <anthm@freeswitch.org>
Thu, 13 May 2010 23:49:32 +0000 (18:49 -0500)
committerAnthony Minessale <anthm@freeswitch.org>
Thu, 13 May 2010 23:49:32 +0000 (18:49 -0500)
src/mod/endpoints/mod_loopback/mod_loopback.c

index 9e11c5b474cc02d96b6e3672fdb5fd6311c9f970..11e180b0765051d404c3f936e43378e6e1000763 100644 (file)
@@ -759,6 +759,59 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s
        return SWITCH_STATUS_SUCCESS;
 }
 
+
+static switch_status_t loopback_bowout_on_execute_state_handler(switch_core_session_t *session)
+{
+       switch_channel_t *channel = switch_core_session_get_channel(session);
+       switch_channel_state_t state = switch_channel_get_state(channel);
+       private_t *tech_pvt = NULL;
+
+
+       if (state == CS_EXECUTE) {
+               const char *uuid;
+               switch_core_session_t *other_session = NULL;
+               switch_channel_t *b_channel = NULL;
+
+               tech_pvt = switch_core_session_get_private(session);
+
+               switch_core_session_read_lock(tech_pvt->other_session);
+               b_channel = switch_core_session_get_channel(tech_pvt->other_session);
+
+               uuid = switch_channel_get_variable(b_channel, SWITCH_SIGNAL_BOND_VARIABLE);
+
+               if (uuid && (other_session = switch_core_session_locate(uuid))) {
+                       switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
+                       switch_caller_profile_t *cp, *clone;
+                       
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->other_session), SWITCH_LOG_INFO, "Replacing loopback channel: %s with real channel: %s\n",
+                                                         switch_channel_get_name(b_channel), switch_channel_get_name(other_channel));
+                       
+                       if ((cp = switch_channel_get_caller_profile(channel))) {
+                               clone = switch_caller_profile_clone(other_session, cp);
+                               clone->originator_caller_profile = NULL;
+                               clone->originatee_caller_profile = NULL;
+                               switch_channel_set_caller_profile(other_channel, clone);
+                       }
+
+                       switch_channel_caller_extension_masquerade(channel, other_channel, 0);
+                       switch_channel_set_state(other_channel, CS_RESET);
+                       switch_channel_wait_for_state(other_channel, other_channel, CS_RESET);
+                       switch_channel_set_variable(channel, "process_cdr", "false");
+                       switch_channel_set_variable(b_channel, "process_cdr", "false");
+                       switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
+                       switch_channel_hangup(b_channel, SWITCH_CAUSE_NORMAL_CLEARING);
+                       switch_channel_set_state(other_channel, CS_EXECUTE);
+                       switch_core_session_rwunlock(other_session);
+               }
+
+               switch_core_session_rwunlock(tech_pvt->other_session);
+
+               switch_core_event_hook_remove_state_change(session, loopback_bowout_on_execute_state_handler);
+               
+       }
+       return SWITCH_STATUS_SUCCESS;
+}
+
 static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
                                                                                                        switch_caller_profile_t *outbound_profile,
                                                                                                        switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
@@ -851,6 +904,10 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
                        return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
                }
 
+               if (switch_true(switch_event_get_header(var_event, "loopback_bowout_on_execute"))) {
+                       switch_core_event_hook_add_state_change(*new_session, loopback_bowout_on_execute_state_handler);
+               }
+
                switch_channel_set_state(channel, CS_INIT);
 
                return SWITCH_CAUSE_SUCCESS;