Diff
Modified: freeswitch/trunk/src/include/private/switch_core_pvt.h (14851 => 14852)
--- freeswitch/trunk/src/include/private/switch_core_pvt.h 2009-09-14 19:43:15 UTC (rev 14851)
+++ freeswitch/trunk/src/include/private/switch_core_pvt.h 2009-09-14 20:10:58 UTC (rev 14852)
@@ -87,13 +87,15 @@
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;
Modified: freeswitch/trunk/src/include/switch_core.h (14851 => 14852)
--- freeswitch/trunk/src/include/switch_core.h 2009-09-14 19:43:15 UTC (rev 14851)
+++ freeswitch/trunk/src/include/switch_core.h 2009-09-14 20:10:58 UTC (rev 14852)
@@ -591,6 +591,7 @@
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
Modified: freeswitch/trunk/src/include/switch_cpp.h (14851 => 14852)
--- freeswitch/trunk/src/include/switch_cpp.h 2009-09-14 19:43:15 UTC (rev 14851)
+++ freeswitch/trunk/src/include/switch_cpp.h 2009-09-14 20:10:58 UTC (rev 14852)
@@ -260,7 +260,7 @@
* \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);
Modified: freeswitch/trunk/src/mod/languages/mod_managed/freeswitch_wrap.cxx (14851 => 14852)
--- freeswitch/trunk/src/mod/languages/mod_managed/freeswitch_wrap.cxx 2009-09-14 19:43:15 UTC (rev 14851)
+++ freeswitch/trunk/src/mod/languages/mod_managed/freeswitch_wrap.cxx 2009-09-14 20:10:58 UTC (rev 14852)
@@ -6048,6 +6048,14 @@
}
+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 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;
}
Modified: freeswitch/trunk/src/mod/languages/mod_managed/managed/swig.cs (14851 => 14852)
--- freeswitch/trunk/src/mod/languages/mod_managed/managed/swig.cs 2009-09-14 19:43:15 UTC (rev 14851)
+++ freeswitch/trunk/src/mod/languages/mod_managed/managed/swig.cs 2009-09-14 20:10:58 UTC (rev 14852)
@@ -244,8 +244,8 @@
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 @@
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 @@
[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 @@
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);
Modified: freeswitch/trunk/src/switch_channel.c (14851 => 14852)
--- freeswitch/trunk/src/switch_channel.c 2009-09-14 19:43:15 UTC (rev 14851)
+++ freeswitch/trunk/src/switch_channel.c 2009-09-14 20:10:58 UTC (rev 14852)
@@ -1714,6 +1714,7 @@
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;
Modified: freeswitch/trunk/src/switch_core_session.c (14851 => 14852)
--- freeswitch/trunk/src/switch_core_session.c 2009-09-14 19:43:15 UTC (rev 14851)
+++ freeswitch/trunk/src/switch_core_session.c 2009-09-14 20:10:58 UTC (rev 14852)
@@ -1062,7 +1062,8 @@
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 @@
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);
Modified: freeswitch/trunk/src/switch_core_state_machine.c (14851 => 14852)
--- freeswitch/trunk/src/switch_core_state_machine.c 2009-09-14 19:43:15 UTC (rev 14851)
+++ freeswitch/trunk/src/switch_core_state_machine.c 2009-09-14 20:10:58 UTC (rev 14852)
@@ -413,69 +413,7 @@
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_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_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;
Modified: freeswitch/trunk/src/switch_cpp.cpp (14851 => 14852)
--- freeswitch/trunk/src/switch_cpp.cpp 2009-09-14 19:43:15 UTC (rev 14851)
+++ freeswitch/trunk/src/switch_cpp.cpp 2009-09-14 20:10:58 UTC (rev 14852)
@@ -932,7 +932,7 @@
}
-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,9 +957,9 @@
&cause,
dest,
timeout,
+ handlers,
NULL,
NULL,
- NULL,
&caller_profile,
NULL,
SOF_NONE) != SWITCH_STATUS_SUCCESS) {