]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
execute hangup state asap
authorAnthony Minessale <anthony.minessale@gmail.com>
Mon, 14 Sep 2009 20:10:58 +0000 (20:10 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Mon, 14 Sep 2009 20:10:58 +0000 (20:10 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@14852 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/include/private/switch_core_pvt.h
src/include/switch_core.h
src/include/switch_cpp.h
src/mod/languages/mod_managed/freeswitch_wrap.cxx
src/mod/languages/mod_managed/managed/swig.cs
src/switch_channel.c
src/switch_core_session.c
src/switch_core_state_machine.c
src/switch_cpp.cpp

index e3519bc10e5a9b7fa05803ed2f5e9bd560972964..b6d3a60d6d0bfd222274f087f2de32ec603fa776 100644 (file)
 typedef enum {
        SSF_NONE = 0,
        SSF_DESTROYED = (1 << 0),
-       SSF_WARN_TRANSCODE = (1 << 1)
+       SSF_WARN_TRANSCODE = (1 << 1),
+       SSF_HANGUP = (1 << 2)
 } switch_session_flag_t;
 
 
 struct switch_core_session {
        switch_memory_pool_t *pool;
        switch_thread_t *thread;
+       switch_thread_id_t thread_id;
        switch_endpoint_interface_t *endpoint_interface;
        switch_size_t id;
        switch_session_flag_t flags;
index a08eb6676cd1f92dc120be4e786d809a0a066641..2fc783e742bfdab1195e633375d37ce985b6df8c 100644 (file)
@@ -591,6 +591,7 @@ SWITCH_DECLARE(void) switch_core_session_perform_destroy(_Inout_ switch_core_ses
 
 SWITCH_DECLARE(void) switch_core_session_destroy_state(switch_core_session_t *session);
 SWITCH_DECLARE(void) switch_core_session_reporting_state(switch_core_session_t *session);
+SWITCH_DECLARE(void) switch_core_session_hangup_state(switch_core_session_t *session);
 
 /*! 
   \brief Provide the total number of sessions
index b59c2165c86ddd54ed17a7a4f23362e15881b78d..a143b0616bc401ce6e5bbc61b441a35336f521af 100644 (file)
@@ -260,7 +260,7 @@ SWITCH_DECLARE(void) consoleCleanLog(char *msg);
         * \return an int status code indicating success or failure
         *
         */
-                SWITCH_DECLARE(int) originate(CoreSession * a_leg_session, char *dest, int timeout = 60);
+                SWITCH_DECLARE(int) originate(CoreSession * a_leg_session, char *dest, int timeout = 60, switch_state_handler_table_t *handlers = NULL);
 
 
                 SWITCH_DECLARE(virtual void) destroy(void);
index 6f460be9cef3311b494274f8116f98d799e415aa..96ce47777dfbab6ddc10841c14c0b5cf3f9dd91f 100644 (file)
@@ -6048,6 +6048,14 @@ SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_session_reporting_state(void * ja
 }
 
 
+SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_session_hangup_state(void * jarg1) {
+  switch_core_session_t *arg1 = (switch_core_session_t *) 0 ;
+  
+  arg1 = (switch_core_session_t *)jarg1; 
+  switch_core_session_hangup_state(arg1);
+}
+
+
 SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_core_session_count() {
   unsigned long jresult ;
   uint32_t result;
@@ -28592,19 +28600,21 @@ SWIGEXPORT void SWIGSTDCALL CSharp_CoreSession_SetCallerData(void * jarg1, char
 }
 
 
-SWIGEXPORT int SWIGSTDCALL CSharp_CoreSession_Originate(void * jarg1, void * jarg2, char * jarg3, int jarg4) {
+SWIGEXPORT int SWIGSTDCALL CSharp_CoreSession_Originate(void * jarg1, void * jarg2, char * jarg3, int jarg4, void * jarg5) {
   int jresult ;
   CoreSession *arg1 = (CoreSession *) 0 ;
   CoreSession *arg2 = (CoreSession *) 0 ;
   char *arg3 = (char *) 0 ;
   int arg4 = (int) 60 ;
+  switch_state_handler_table_t *arg5 = (switch_state_handler_table_t *) NULL ;
   int result;
   
   arg1 = (CoreSession *)jarg1; 
   arg2 = (CoreSession *)jarg2; 
   arg3 = (char *)jarg3; 
   arg4 = (int)jarg4; 
-  result = (int)(arg1)->originate(arg2,arg3,arg4);
+  arg5 = (switch_state_handler_table_t *)jarg5; 
+  result = (int)(arg1)->originate(arg2,arg3,arg4,arg5);
   jresult = result; 
   return jresult;
 }
index 4a4cdcbbd4ab8bbdcbf3e8949e76e412bfbe5a2a..c521a5f6308822006975bd24d7d3f70cdc61c29f 100644 (file)
@@ -244,8 +244,8 @@ public class CoreSession : IDisposable {
     freeswitchPINVOKE.CoreSession_SetCallerData(swigCPtr, var, val);
   }
 
-  public int Originate(CoreSession a_leg_session, string dest, int timeout) {
-    int ret = freeswitchPINVOKE.CoreSession_Originate(swigCPtr, CoreSession.getCPtr(a_leg_session), dest, timeout);
+  public int Originate(CoreSession a_leg_session, string dest, int timeout, switch_state_handler_table handlers) {
+    int ret = freeswitchPINVOKE.CoreSession_Originate(swigCPtr, CoreSession.getCPtr(a_leg_session), dest, timeout, switch_state_handler_table.getCPtr(handlers));
     return ret;
   }
 
@@ -1142,6 +1142,10 @@ public class freeswitch {
     freeswitchPINVOKE.switch_core_session_reporting_state(SWIGTYPE_p_switch_core_session.getCPtr(session));
   }
 
+  public static void switch_core_session_hangup_state(SWIGTYPE_p_switch_core_session session) {
+    freeswitchPINVOKE.switch_core_session_hangup_state(SWIGTYPE_p_switch_core_session.getCPtr(session));
+  }
+
   public static uint switch_core_session_count() {
     uint ret = freeswitchPINVOKE.switch_core_session_count();
     return ret;
@@ -6008,6 +6012,9 @@ class freeswitchPINVOKE {
   [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_reporting_state")]
   public static extern void switch_core_session_reporting_state(HandleRef jarg1);
 
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_hangup_state")]
+  public static extern void switch_core_session_hangup_state(HandleRef jarg1);
+
   [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_count")]
   public static extern uint switch_core_session_count();
 
@@ -11289,7 +11296,7 @@ class freeswitchPINVOKE {
   public static extern void CoreSession_SetCallerData(HandleRef jarg1, string jarg2, string jarg3);
 
   [DllImport("mod_managed", EntryPoint="CSharp_CoreSession_Originate")]
-  public static extern int CoreSession_Originate(HandleRef jarg1, HandleRef jarg2, string jarg3, int jarg4);
+  public static extern int CoreSession_Originate(HandleRef jarg1, HandleRef jarg2, string jarg3, int jarg4, HandleRef jarg5);
 
   [DllImport("mod_managed", EntryPoint="CSharp_CoreSession_destroy")]
   public static extern void CoreSession_destroy(HandleRef jarg1);
index 6b75ef6cea8dd555793274df35827e971cb346b1..1b0ee19aa3060f01ca2afce0c3a11c31bd518997 100644 (file)
@@ -1714,6 +1714,7 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_hangup(switch_chan
 
                switch_core_session_kill_channel(channel->session, SWITCH_SIG_KILL);
                switch_core_session_signal_state_change(channel->session);
+               switch_core_session_hangup_state(channel->session);
        }
 
        return channel->state;
index c714581204b684c00b1f1e0cdd7d1d52c7b13409..1544e884cf19d6968acbc08a41869ab27f4356ef 100644 (file)
@@ -1062,7 +1062,8 @@ static void *SWITCH_THREAD_FUNC switch_core_session_thread(switch_thread_t *thre
        const char *val;
 
        session->thread = thread;
-       
+       session->thread_id = switch_thread_self();
+
        switch_core_session_run(session);
        switch_core_media_bug_remove_all(session);
        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Session %" SWITCH_SIZE_T_FMT " (%s) Locked, Waiting on external entities\n",
@@ -1207,6 +1208,7 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_uuid(switch_
 
        session = switch_core_alloc(usepool, sizeof(*session));
        session->pool = usepool;
+       session->thread_id = switch_thread_self();
 
        switch_core_memory_pool_set_data(session->pool, "__session", session);
        
index 9fdf8a7f549ab3c5f233c85dd4051a23120ed5eb..00ba89e308c43b9f4df6e78e636772a728be3fb7 100644 (file)
@@ -413,69 +413,7 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session)
                                goto done;
                        case CS_HANGUP: /* Deactivate and end the thread */
                                {
-                                       const char *hook_var;
-                                       switch_core_session_t *use_session = NULL;
-                                       switch_call_cause_t cause = switch_channel_get_cause(session->channel);
-                                       switch_call_cause_t cause_q850 = switch_channel_get_cause_q850(session->channel);
-                                       switch_event_t *event;
-               
-                                       switch_channel_set_hangup_time(session->channel);
-
-                                       switch_core_media_bug_remove_all(session);
-                               
-                                       switch_channel_stop_broadcast(session->channel);
-                                       
-                                       switch_channel_set_variable(session->channel, "hangup_cause", switch_channel_cause2str(cause));
-                                       switch_channel_set_variable_printf(session->channel, "hangup_cause_q850", "%d", cause_q850);
-                                       switch_channel_presence(session->channel, "unknown", switch_channel_cause2str(cause), NULL);
-                                       
-                                       switch_channel_set_timestamps(session->channel);
-                                       
-                                       STATE_MACRO(hangup, "HANGUP");
-
-                                       hook_var = switch_channel_get_variable(session->channel, SWITCH_API_HANGUP_HOOK_VARIABLE);
-                                       if (switch_true(switch_channel_get_variable(session->channel, SWITCH_SESSION_IN_HANGUP_HOOK_VARIABLE))) {
-                                               use_session = session;
-                                       }
-
-                                       if (!switch_strlen_zero(hook_var)) {
-                                               switch_stream_handle_t stream = { 0 };
-                                               char *cmd = switch_core_session_strdup(session, hook_var);
-                                               char *arg = NULL;
-                                               char *expanded = NULL;
-                                               
-                                               if ((arg = strchr(cmd, ':')) && *(arg+1) == ':') {
-                                                       *arg++ = '\0';
-                                                       *arg++ = '\0';
-                                               } else {
-                                                       if ((arg = strchr(cmd, ' '))) {
-                                                               *arg++ = '\0';
-                                                       }
-                                               }
-
-                                               SWITCH_STANDARD_STREAM(stream);
-                                               
-                                               switch_channel_get_variables(session->channel, &stream.param_event);
-                                               switch_channel_event_set_data(session->channel, stream.param_event);
-                                               expanded = switch_channel_expand_variables(session->channel, arg);
-
-                                               switch_api_execute(cmd, expanded, use_session, &stream);
-                                               
-                                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Hangup Command %s(%s):\n%s\n", cmd, switch_str_nil(expanded),
-                                                                                 switch_str_nil((char *) stream.data));
-
-                                               if (expanded != arg) {
-                                                       switch_safe_free(expanded);
-                                               }
-                                               switch_safe_free(stream.data);
-                                       }
-
-                                       if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_HANGUP_COMPLETE) == SWITCH_STATUS_SUCCESS) {
-                                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Hangup-Cause", switch_channel_cause2str(cause));
-                                               switch_channel_event_set_data(session->channel, event);
-                                               switch_event_fire(&event);
-                                       }
-                               
+                                       switch_core_session_hangup_state(session);                              
                                        switch_channel_set_state(session->channel, CS_REPORTING);
                                }
 
@@ -557,6 +495,8 @@ SWITCH_DECLARE(void) switch_core_session_destroy_state(switch_core_session_t *se
 
        switch_assert(session != NULL);
        switch_channel_set_running_state(session->channel, CS_DESTROY);
+       switch_channel_clear_flag(session->channel, CF_TRANSFER);
+       switch_channel_clear_flag(session->channel, CF_REDIRECT);
 
        session->thread_running = 1;
        endpoint_interface = session->endpoint_interface;
@@ -571,6 +511,101 @@ SWITCH_DECLARE(void) switch_core_session_destroy_state(switch_core_session_t *se
 }
 
 
+SWITCH_DECLARE(void) switch_core_session_hangup_state(switch_core_session_t *session)
+{
+       const char *hook_var;
+       switch_core_session_t *use_session = NULL;
+       switch_call_cause_t cause = switch_channel_get_cause(session->channel);
+       switch_call_cause_t cause_q850 = switch_channel_get_cause_q850(session->channel);
+       switch_event_t *event;
+       int proceed = 1;
+       int global_proceed = 1;
+       int do_extra_handlers = 1;
+       int silly = 0;
+       int index = 0;
+       switch_channel_state_t state = switch_channel_get_state(session->channel), midstate = state;
+       const switch_endpoint_interface_t *endpoint_interface;
+       const switch_state_handler_table_t *driver_state_handler = NULL;
+       const switch_state_handler_table_t *application_state_handler = NULL;
+
+
+       if (switch_thread_self() != session->thread_id) {
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "thread mismatch skipping state handler.\n");
+               return;
+       }
+
+       if (switch_test_flag(session, SSF_HANGUP)) {
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "handler already called, skipping state handler.\n");
+               return;
+       }
+
+       endpoint_interface = session->endpoint_interface;
+       switch_assert(endpoint_interface != NULL);
+
+       driver_state_handler = endpoint_interface->state_handler;
+       switch_assert(driver_state_handler != NULL);
+
+       switch_channel_set_hangup_time(session->channel);
+
+       switch_core_media_bug_remove_all(session);
+                               
+       switch_channel_stop_broadcast(session->channel);
+                                       
+       switch_channel_set_variable(session->channel, "hangup_cause", switch_channel_cause2str(cause));
+       switch_channel_set_variable_printf(session->channel, "hangup_cause_q850", "%d", cause_q850);
+       switch_channel_presence(session->channel, "unknown", switch_channel_cause2str(cause), NULL);
+                                       
+       switch_channel_set_timestamps(session->channel);
+                                       
+       STATE_MACRO(hangup, "HANGUP");
+
+       hook_var = switch_channel_get_variable(session->channel, SWITCH_API_HANGUP_HOOK_VARIABLE);
+       if (switch_true(switch_channel_get_variable(session->channel, SWITCH_SESSION_IN_HANGUP_HOOK_VARIABLE))) {
+               use_session = session;
+       }
+
+       if (!switch_strlen_zero(hook_var)) {
+               switch_stream_handle_t stream = { 0 };
+               char *cmd = switch_core_session_strdup(session, hook_var);
+               char *arg = NULL;
+               char *expanded = NULL;
+                                               
+               if ((arg = strchr(cmd, ':')) && *(arg+1) == ':') {
+                       *arg++ = '\0';
+                       *arg++ = '\0';
+               } else {
+                       if ((arg = strchr(cmd, ' '))) {
+                               *arg++ = '\0';
+                       }
+               }
+
+               SWITCH_STANDARD_STREAM(stream);
+                                               
+               switch_channel_get_variables(session->channel, &stream.param_event);
+               switch_channel_event_set_data(session->channel, stream.param_event);
+               expanded = switch_channel_expand_variables(session->channel, arg);
+
+               switch_api_execute(cmd, expanded, use_session, &stream);
+                                               
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Hangup Command %s(%s):\n%s\n", cmd, switch_str_nil(expanded),
+                                                 switch_str_nil((char *) stream.data));
+
+               if (expanded != arg) {
+                       switch_safe_free(expanded);
+               }
+               switch_safe_free(stream.data);
+       }
+
+       if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_HANGUP_COMPLETE) == SWITCH_STATUS_SUCCESS) {
+               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Hangup-Cause", switch_channel_cause2str(cause));
+               switch_channel_event_set_data(session->channel, event);
+               switch_event_fire(&event);
+       }
+
+       switch_set_flag(session, SSF_HANGUP);
+       
+}
+
 SWITCH_DECLARE(void) switch_core_session_reporting_state(switch_core_session_t *session)
 {
        switch_channel_state_t state = switch_channel_get_state(session->channel), midstate = state;
index 3f4fc4d18aa2d75cdf0d8db48af1201ad7bb85a4..b6c2f6812885e249e78ff6acf3002fc7d8cbb6a2 100644 (file)
@@ -932,7 +932,7 @@ SWITCH_DECLARE(void) CoreSession::destroy(void)
        
 }
 
-SWITCH_DECLARE(int) CoreSession::originate(CoreSession *a_leg_session, char *dest, int timeout)
+SWITCH_DECLARE(int) CoreSession::originate(CoreSession *a_leg_session, char *dest, int timeout, switch_state_handler_table_t *handlers)
 {
 
        switch_core_session_t *aleg_core_session = NULL;
@@ -957,7 +957,7 @@ SWITCH_DECLARE(int) CoreSession::originate(CoreSession *a_leg_session, char *des
                                                         &cause, 
                                                         dest, 
                                                         timeout,
-                                                        NULL
+                                                        handlers
                                                         NULL, 
                                                         NULL, 
                                                         &caller_profile,