[Freeswitch-svn] [commit] r8791 - in freeswitch/trunk/src/mod/languages: mod_mono mod_mono_managed

Freeswitch SVN michaelgg at freeswitch.org
Mon Jun 9 23:09:15 EDT 2008


Author: michaelgg
Date: Mon Jun  9 23:09:14 2008
New Revision: 8791

Modified:
   freeswitch/trunk/src/mod/languages/mod_mono/freeswitch_wrap.cxx
   freeswitch/trunk/src/mod/languages/mod_mono/mod_mono.cpp
   freeswitch/trunk/src/mod/languages/mod_mono_managed/AppFunction.cs
   freeswitch/trunk/src/mod/languages/mod_mono_managed/Demo.cs
   freeswitch/trunk/src/mod/languages/mod_mono_managed/Loader.cs
   freeswitch/trunk/src/mod/languages/mod_mono_managed/MonoSession.cs

Log:
Move input and hangup delegates to reside on MonoSession instead of bound to app.


Modified: freeswitch/trunk/src/mod/languages/mod_mono/freeswitch_wrap.cxx
==============================================================================
--- freeswitch/trunk/src/mod/languages/mod_mono/freeswitch_wrap.cxx	(original)
+++ freeswitch/trunk/src/mod/languages/mod_mono/freeswitch_wrap.cxx	Mon Jun  9 23:09:14 2008
@@ -24139,7 +24139,7 @@
 }
 
 
-SWIGEXPORT int SWIGSTDCALL CSharp_CoreSession_speak(void * jarg1, char * jarg2) {
+SWIGEXPORT int SWIGSTDCALL CSharp_CoreSession_Speak(void * jarg1, char * jarg2) {
   int jresult ;
   CoreSession *arg1 = (CoreSession *) 0 ;
   char *arg2 = (char *) 0 ;
@@ -24153,7 +24153,7 @@
 }
 
 
-SWIGEXPORT void SWIGSTDCALL CSharp_CoreSession_set_tts_parms(void * jarg1, char * jarg2, char * jarg3) {
+SWIGEXPORT void SWIGSTDCALL CSharp_CoreSession_SetTtsParameters(void * jarg1, char * jarg2, char * jarg3) {
   CoreSession *arg1 = (CoreSession *) 0 ;
   char *arg2 = (char *) 0 ;
   char *arg3 = (char *) 0 ;
@@ -24305,7 +24305,7 @@
 }
 
 
-SWIGEXPORT int SWIGSTDCALL CSharp_CoreSession_setAutoHangup(void * jarg1, unsigned int jarg2) {
+SWIGEXPORT int SWIGSTDCALL CSharp_CoreSession_SetAutoHangup(void * jarg1, unsigned int jarg2) {
   int jresult ;
   CoreSession *arg1 = (CoreSession *) 0 ;
   bool arg2 ;

Modified: freeswitch/trunk/src/mod/languages/mod_mono/mod_mono.cpp
==============================================================================
--- freeswitch/trunk/src/mod/languages/mod_mono/mod_mono.cpp	(original)
+++ freeswitch/trunk/src/mod/languages/mod_mono/mod_mono.cpp	Mon Jun  9 23:09:14 2008
@@ -33,7 +33,10 @@
  */  
 	
 #include <switch.h>
-	

SWITCH_BEGIN_EXTERN_C 
 
+	
+
+SWITCH_BEGIN_EXTERN_C 
+ 
 #include "freeswitch_mono.h"
 #include <glib.h>
 #include <mono/jit/jit.h>
@@ -47,272 +50,489 @@
 #define EXPORT __declspec(dllexport)
 #elif
 #define EXPORT 
-#endif	/* 
 */
+#endif	/* 
+ */
 	
 #define MOD_MONO_MANAGED_DLL "mod_mono_managed.dll"
-	
mod_mono_globals globals = {
-0};
-
-

SWITCH_MODULE_LOAD_FUNCTION(mod_mono_load);
-
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mono_shutdown);
-
SWITCH_MODULE_DEFINITION(mod_mono, mod_mono_load, mod_mono_shutdown, NULL);
-

SWITCH_STANDARD_API(monorun_api_function);	/* ExecuteBackground */
-
SWITCH_STANDARD_API(mono_api_function);	/* Execute */
-
SWITCH_STANDARD_APP(mono_app_function);	/* Run */
-


+	
+mod_mono_globals globals = {
+0};
+
+
+
+SWITCH_MODULE_LOAD_FUNCTION(mod_mono_load);
+
+SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mono_shutdown);
+
+SWITCH_MODULE_DEFINITION(mod_mono, mod_mono_load, mod_mono_shutdown, NULL);
+
+
+SWITCH_STANDARD_API(monorun_api_function);	/* ExecuteBackground */
+
+SWITCH_STANDARD_API(mono_api_function);	/* Execute */
+
+SWITCH_STANDARD_APP(mono_app_function);	/* Run */
+
+
 // Sets up delegates (and anything else needed) on the MonoSession object
 // Called via internalcall
-	SWITCH_MOD_DECLARE(void) InitMonoSession(MonoSession * session, MonoObject * dtmfDelegate, MonoObject * hangupDelegate) 
-{
-	
switch_assert(session);
-	
if (!session)
-		return;
-	
session->setDTMFCallback(NULL, "");
-	
session->setHangupHook(NULL);
-	
session->dtmfDelegateHandle = mono_gchandle_new(dtmfDelegate, FALSE);
-	
session->hangupDelegateHandle = mono_gchandle_new(hangupDelegate, FALSE);
-
}
-

switch_status_t setMonoDirs() 
-{
+SWITCH_MOD_DECLARE(void) InitMonoSession(MonoSession * session, MonoObject * dtmfDelegate, MonoObject * hangupDelegate) 
+{
+	switch_assert(session);
+	if (!session) {
+		return;
+	}
+	session->setDTMFCallback(NULL, "");
+	session->setHangupHook(NULL);
+	session->dtmfDelegateHandle = mono_gchandle_new(dtmfDelegate, FALSE);
+	session->hangupDelegateHandle = mono_gchandle_new(hangupDelegate, FALSE);
+}
+
+
+switch_status_t setMonoDirs() 
+{
 	
 #ifdef WIN32	
 		/* Win32 Mono installs can't figure out their own path
 		   // Guys in #mono say we should just deploy all the libs we need
 		   // I think it's much nicer to let the user deal with installing Mono
 		   // and we'll just look for it in program files. */ 
-		HANDLE hFind;
-	
WIN32_FIND_DATA findData;
-	
char progFilesPath[MAX_PATH];
-	
char findPath[MAX_PATH];
-	
SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL, SHGFP_TYPE_CURRENT, progFilesPath);
-	
switch_snprintf(findPath, MAX_PATH, "%s\\Mono-*", progFilesPath);
-	
hFind = FindFirstFile(findPath, &findData);
-	
if (hFind == INVALID_HANDLE_VALUE) {
-		
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error looking for Mono in Program Files.\n");
-		
return SWITCH_STATUS_FALSE;
-	
}
-	
while ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY) {
-		
if (FindNextFile(hFind, &findData) == 0) {
-			
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find Mono directory in Program Files.\n");
-			
FindClose(hFind);
-			
return SWITCH_STATUS_FALSE;
-		
}
-	
}
+		HANDLE hFind;
+	
+WIN32_FIND_DATA findData;
+	
+char progFilesPath[MAX_PATH];
+	
+char findPath[MAX_PATH];
+	
+SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL, SHGFP_TYPE_CURRENT, progFilesPath);
+	
+switch_snprintf(findPath, MAX_PATH, "%s\\Mono-*", progFilesPath);
+	
+hFind = FindFirstFile(findPath, &findData);
+	
+if (hFind == INVALID_HANDLE_VALUE) {
+		
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error looking for Mono in Program Files.\n");
+		
+return SWITCH_STATUS_FALSE;
+	
+}
+	
+while ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY) {
+		
+if (FindNextFile(hFind, &findData) == 0) {
+			
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find Mono directory in Program Files.\n");
+			
+FindClose(hFind);
+			
+return SWITCH_STATUS_FALSE;
+		
+}
+	
+}
 	
 		/* Got it */ 
-	{
-		
char libPath[MAX_PATH];
-		
char etcPath[MAX_PATH];
-		
switch_snprintf(libPath, MAX_PATH, "%s\\%s\\lib", progFilesPath, findData.cFileName);
-		
switch_snprintf(etcPath, MAX_PATH, "%s\\%s\\etc", progFilesPath, findData.cFileName);
-		
FindClose(hFind);
-		
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Using Mono paths '%s' and '%s'.\n", libPath, etcPath);
-		
mono_set_dirs(libPath, etcPath);
-		
return SWITCH_STATUS_SUCCESS;
-	
}
+	{
+		
+char libPath[MAX_PATH];
+		
+char etcPath[MAX_PATH];
+		
+switch_snprintf(libPath, MAX_PATH, "%s\\%s\\lib", progFilesPath, findData.cFileName);
+		
+switch_snprintf(etcPath, MAX_PATH, "%s\\%s\\etc", progFilesPath, findData.cFileName);
+		
+FindClose(hFind);
+		
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Using Mono paths '%s' and '%s'.\n", libPath, etcPath);
+		
+mono_set_dirs(libPath, etcPath);
+		
+return SWITCH_STATUS_SUCCESS;
+	
+}
 	
 #elif
 		// On other platforms, it should just work if it hasn't been relocated
-		mono_set_dirs(NULL, NULL);
-	
return SWITCH_STATUS_SUCCESS;
+		mono_set_dirs(NULL, NULL);
+	
+return SWITCH_STATUS_SUCCESS;
 	
-#endif	/* 
 */
-}
-

switch_status_t loadModMonoManaged() 
-{
+#endif	/* 
+ */
+}
+
+
+switch_status_t loadModMonoManaged() 
+{
 	
 		/* Find and load mod_mono_managed.exe */ 
-	char filename[256];
-	
switch_snprintf(filename, 256, "%s%s%s", SWITCH_GLOBAL_dirs.mod_dir, SWITCH_PATH_SEPARATOR, MOD_MONO_MANAGED_DLL);
-	
globals.domain = mono_jit_init(filename);
-	

if (!globals.domain) {
-		
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mono_jit_init failed.\n");
-		
return SWITCH_STATUS_FALSE;
-	
}
-	

+	char filename[256];
+	
+switch_snprintf(filename, 256, "%s%s%s", SWITCH_GLOBAL_dirs.mod_dir, SWITCH_PATH_SEPARATOR, MOD_MONO_MANAGED_DLL);
+	
+globals.domain = mono_jit_init(filename);
+	
+
+if (!globals.domain) {
+		
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mono_jit_init failed.\n");
+		
+return SWITCH_STATUS_FALSE;
+	
+}
+	
+
 		/* Open the assembly */ 
-		globals.mod_mono_asm = mono_domain_assembly_open(globals.domain, filename);
-	
if (!globals.mod_mono_asm) {
-		
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mono_domain_assembly_open failed.\n");
-		
return SWITCH_STATUS_FALSE;
-	
}
-	
return SWITCH_STATUS_SUCCESS;
-
}
-
-

MonoMethod * getMethod(const char *name, MonoClass * klass) 
-{
-	
MonoMethodDesc * desc;
-	
MonoMethod * method;
-	
desc = mono_method_desc_new(name, TRUE);
-	
method = mono_method_desc_search_in_class(desc, klass);
-	
if (!method) {
-		
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find %s method.\n", name);
-		
return NULL;
-	
}
-	
return method;
-
}
-

switch_status_t findLoader() 
-{
+		globals.mod_mono_asm = mono_domain_assembly_open(globals.domain, filename);
+	
+if (!globals.mod_mono_asm) {
+		
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mono_domain_assembly_open failed.\n");
+		
+return SWITCH_STATUS_FALSE;
+	
+}
+	
+return SWITCH_STATUS_SUCCESS;
+
+}
+
+
+
+MonoMethod * getMethod(const char *name, MonoClass * klass) 
+{
+	
+MonoMethodDesc * desc;
+	
+MonoMethod * method;
+	
+desc = mono_method_desc_new(name, TRUE);
+	
+method = mono_method_desc_search_in_class(desc, klass);
+	
+if (!method) {
+		
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find %s method.\n", name);
+		
+return NULL;
+	
+}
+	
+return method;
+
+}
+
+
+switch_status_t findLoader() 
+{
 	
 		/* Find loader class and methods */ 
-		MonoImage * img;
-	
MonoClass * loaderClass;
-	
img = mono_assembly_get_image(globals.mod_mono_asm);
-	
loaderClass = mono_class_from_name(img, "FreeSWITCH", "Loader");
-	
if (!loaderClass) {
-		
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find FreeSWITCH.Loader class.\n");
-		
return SWITCH_STATUS_FALSE;
-	
}
-	

globals.loadMethod = getMethod("FreeSWITCH.Loader:Load()", loaderClass);
-	
if (!globals.loadMethod)
-		return SWITCH_STATUS_FALSE;
-	

globals.unloadMethod = getMethod("FreeSWITCH.Loader:Unload()", loaderClass);
-	
if (!globals.unloadMethod)
-		return SWITCH_STATUS_FALSE;
-	

globals.runMethod = getMethod("FreeSWITCH.Loader:Run(string,intptr)", loaderClass);
-	
if (!globals.runMethod)
-		return SWITCH_STATUS_FALSE;
-	

globals.executeMethod = getMethod("FreeSWITCH.Loader:Execute(string,intptr,intptr)", loaderClass);
-	
if (!globals.executeMethod)
-		return SWITCH_STATUS_FALSE;
-	

globals.executeBackgroundMethod = getMethod("FreeSWITCH.Loader:ExecuteBackground(string)", loaderClass);
-	
if (!globals.executeBackgroundMethod)
-		return SWITCH_STATUS_FALSE;
-	

switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Found all loader functions.\n");
-	
return SWITCH_STATUS_SUCCESS;
-
}
-
-

SWITCH_MODULE_LOAD_FUNCTION(mod_mono_load) 
-{
+		MonoImage * img;
+	
+MonoClass * loaderClass;
+	
+img = mono_assembly_get_image(globals.mod_mono_asm);
+	
+loaderClass = mono_class_from_name(img, "FreeSWITCH", "Loader");
+	
+if (!loaderClass) {
+		
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find FreeSWITCH.Loader class.\n");
+		
+return SWITCH_STATUS_FALSE;
+	
+}
+	
+
+globals.loadMethod = getMethod("FreeSWITCH.Loader:Load()", loaderClass);
+	
+if (!globals.loadMethod)
+		return SWITCH_STATUS_FALSE;
+	
+
+globals.unloadMethod = getMethod("FreeSWITCH.Loader:Unload()", loaderClass);
+	
+if (!globals.unloadMethod)
+		return SWITCH_STATUS_FALSE;
+	
+
+globals.runMethod = getMethod("FreeSWITCH.Loader:Run(string,intptr)", loaderClass);
+	
+if (!globals.runMethod)
+		return SWITCH_STATUS_FALSE;
+	
+
+globals.executeMethod = getMethod("FreeSWITCH.Loader:Execute(string,intptr,intptr)", loaderClass);
+	
+if (!globals.executeMethod)
+		return SWITCH_STATUS_FALSE;
+	
+
+globals.executeBackgroundMethod = getMethod("FreeSWITCH.Loader:ExecuteBackground(string)", loaderClass);
+	
+if (!globals.executeBackgroundMethod)
+		return SWITCH_STATUS_FALSE;
+	
+
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Found all loader functions.\n");
+	
+return SWITCH_STATUS_SUCCESS;
+
+}
+
+
+
+SWITCH_MODULE_LOAD_FUNCTION(mod_mono_load) 
+{
 	
 		/* connect my internal structure to the blank pointer passed to me */ 
-		*module_interface = switch_loadable_module_create_module_interface(pool, modname);
-	
globals.pool = pool;
-	

if (setMonoDirs() != SWITCH_STATUS_SUCCESS) {
-		
return SWITCH_STATUS_FALSE;
-	
}
-	
if (loadModMonoManaged() != SWITCH_STATUS_SUCCESS) {
-		
return SWITCH_STATUS_FALSE;
-	
}
-	
if (findLoader() != SWITCH_STATUS_SUCCESS) {
-		
return SWITCH_STATUS_FALSE;
-	
}
-	

+		*module_interface = switch_loadable_module_create_module_interface(pool, modname);
+	
+globals.pool = pool;
+	
+
+if (setMonoDirs() != SWITCH_STATUS_SUCCESS) {
+		
+return SWITCH_STATUS_FALSE;
+	
+}
+	
+if (loadModMonoManaged() != SWITCH_STATUS_SUCCESS) {
+		
+return SWITCH_STATUS_FALSE;
+	
+}
+	
+if (findLoader() != SWITCH_STATUS_SUCCESS) {
+		
+return SWITCH_STATUS_FALSE;
+	
+}
+	
+
 		/* Not sure if this is necesary on the loading thread */ 
-		mono_thread_attach(globals.domain);
-	
mono_add_internal_call("FreeSWITCH.Native.MonoSession::InitMonoSession", InitMonoSession);
-	

+		mono_thread_attach(globals.domain);
+	
+mono_add_internal_call("FreeSWITCH.Native.MonoSession::InitMonoSession", InitMonoSession);
+	
+
 		/* Run loader */ 
-		MonoObject * objResult;
-	
MonoObject * exception = NULL;
-	
objResult = mono_runtime_invoke(globals.loadMethod, NULL, NULL, &exception);
-	
if (exception) {
-		
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Load threw an exception.\n");
-		
mono_print_unhandled_exception(exception);
-		
return SWITCH_STATUS_FALSE;
-	
}
-	
if (*(int *) mono_object_unbox(objResult)) {
-		
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Load completed successfully.\n");
-	
} else {
-		
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Load did not return true.\n");
-		
return SWITCH_STATUS_FALSE;
-	
}
-	


+		MonoObject * objResult;
+	
+MonoObject * exception = NULL;
+	
+objResult = mono_runtime_invoke(globals.loadMethod, NULL, NULL, &exception);
+	
+if (exception) {
+		
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Load threw an exception.\n");
+		
+mono_print_unhandled_exception(exception);
+		
+return SWITCH_STATUS_FALSE;
+	
+}
+	
+if (*(int *) mono_object_unbox(objResult)) {
+		
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Load completed successfully.\n");
+	
+} else {
+		
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Load did not return true.\n");
+		
+return SWITCH_STATUS_FALSE;
+	
+}
+	
+
+
 		/* We're good to register */ 
-	switch_api_interface_t *api_interface;
-	
switch_application_interface_t *app_interface;
-	

SWITCH_ADD_API(api_interface, "monorun", "Run a module (ExecuteBackground)", monorun_api_function, "<module> [<args>]");
-	
SWITCH_ADD_API(api_interface, "mono", "Run a module as an API function (Execute)", mono_api_function, "<module> [<args>]");
-	
SWITCH_ADD_APP(app_interface, "mono", "Run Mono IVR", "Run a Mono IVR on a channel", mono_app_function, "<modulename> [<args>]", SAF_NONE);
-	

return SWITCH_STATUS_SUCCESS;
-
}
-
-

SWITCH_STANDARD_API(monorun_api_function) 
-{
+	switch_api_interface_t *api_interface;
+	
+switch_application_interface_t *app_interface;
+	
+
+SWITCH_ADD_API(api_interface, "monorun", "Run a module (ExecuteBackground)", monorun_api_function, "<module> [<args>]");
+	
+SWITCH_ADD_API(api_interface, "mono", "Run a module as an API function (Execute)", mono_api_function, "<module> [<args>]");
+	
+SWITCH_ADD_APP(app_interface, "mono", "Run Mono IVR", "Run a Mono IVR on a channel", mono_app_function, "<modulename> [<args>]", SAF_NONE);
+	
+
+return SWITCH_STATUS_SUCCESS;
+
+}
+
+
+
+SWITCH_STANDARD_API(monorun_api_function) 
+{
 	
 		// TODO: Should we be detaching after all this?
-		mono_thread_attach(globals.domain);
-	
if (switch_strlen_zero(cmd)) {
-		
stream->write_function(stream, "-ERR no args specified!\n");
-		
return SWITCH_STATUS_SUCCESS;
-	
}
-	

+		mono_thread_attach(globals.domain);
+	
+if (switch_strlen_zero(cmd)) {
+		
+stream->write_function(stream, "-ERR no args specified!\n");
+		
+return SWITCH_STATUS_SUCCESS;
+	
+}
+	
+
 		// ExecuteBackground(string command)
-	void *args[1];
-	
args[0] = mono_string_new(globals.domain, cmd);
-	
MonoObject * exception = NULL;
-	
MonoObject * objResult = mono_runtime_invoke(globals.executeBackgroundMethod, NULL, args, &exception);
-	
if (exception) {
-		
stream->write_function(stream, "-ERR FreeSWITCH.Loader.ExecuteBackground threw an exception.\n");
-		
mono_print_unhandled_exception(exception);
-		
return SWITCH_STATUS_SUCCESS;
-	
}
-	
if (*(int *) mono_object_unbox(objResult)) {
-		
stream->write_function(stream, "+OK\n");
-	
} else {
-		
stream->write_function(stream, "-ERR ExecuteBackground returned false (unknown module?).\n");
-	
}
-	
return SWITCH_STATUS_SUCCESS;
-
}
-
-

SWITCH_STANDARD_API(mono_api_function) 
-{
-	
mono_thread_attach(globals.domain);
-	
if (switch_strlen_zero(cmd)) {
-		
stream->write_function(stream, "-ERR no args specified!\n");
-		
return SWITCH_STATUS_SUCCESS;
-	
}
-	

+	void *args[1];
+	
+args[0] = mono_string_new(globals.domain, cmd);
+	
+MonoObject * exception = NULL;
+	
+MonoObject * objResult = mono_runtime_invoke(globals.executeBackgroundMethod, NULL, args, &exception);
+	
+if (exception) {
+		
+stream->write_function(stream, "-ERR FreeSWITCH.Loader.ExecuteBackground threw an exception.\n");
+		
+mono_print_unhandled_exception(exception);
+		
+return SWITCH_STATUS_SUCCESS;
+	
+}
+	
+if (*(int *) mono_object_unbox(objResult)) {
+		
+stream->write_function(stream, "+OK\n");
+	
+} else {
+		
+stream->write_function(stream, "-ERR ExecuteBackground returned false (unknown module?).\n");
+	
+}
+	
+return SWITCH_STATUS_SUCCESS;
+
+}
+
+
+
+SWITCH_STANDARD_API(mono_api_function) 
+{
+	
+mono_thread_attach(globals.domain);
+	
+if (switch_strlen_zero(cmd)) {
+		
+stream->write_function(stream, "-ERR no args specified!\n");
+		
+return SWITCH_STATUS_SUCCESS;
+	
+}
+	
+
 		// Method is: Execute(string command, IntPtr streamPtr, IntPtr eventPtr)
-	void *args[3];
-	
args[0] = mono_string_new(globals.domain, cmd);
-	
args[1] = &stream;			// Address of the arguments
-	args[2] = &(stream->param_event);
-	

MonoObject * exception = NULL;
-	
MonoObject * objResult = mono_runtime_invoke(globals.executeMethod, NULL, args, &exception);
-	
if (exception) {
-		
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Exception trying to execute mono %s.\n", cmd);
-		
mono_print_unhandled_exception(exception);
-	
}
-	
if (!(*(int *) mono_object_unbox(objResult))) {
-		
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Execute failed for %s (unknown module?).\n", cmd);
-	
}
-	
return SWITCH_STATUS_SUCCESS;
-
}
-
-

SWITCH_STANDARD_APP(mono_app_function) 
-{
-	
mono_thread_attach(globals.domain);
-	
if (switch_strlen_zero(data)) {
-		
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No args specified!\n");
-	
}
-	

+	void *args[3];
+	
+args[0] = mono_string_new(globals.domain, cmd);
+	
+args[1] = &stream;			// Address of the arguments
+	args[2] = &(stream->param_event);
+	
+
+MonoObject * exception = NULL;
+	
+MonoObject * objResult = mono_runtime_invoke(globals.executeMethod, NULL, args, &exception);
+	
+if (exception) {
+		
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Exception trying to execute mono %s.\n", cmd);
+		
+mono_print_unhandled_exception(exception);
+	
+}
+	
+if (!(*(int *) mono_object_unbox(objResult))) {
+		
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Execute failed for %s (unknown module?).\n", cmd);
+	
+}
+	
+return SWITCH_STATUS_SUCCESS;
+
+}
+
+
+
+SWITCH_STANDARD_APP(mono_app_function) 
+{
+	
+mono_thread_attach(globals.domain);
+	
+if (switch_strlen_zero(data)) {
+		
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No args specified!\n");
+	
+}
+	
+
 		// bool Run(string command, IntPtr sessionHandle)
-	void *args[2];
-	
args[0] = mono_string_new(globals.domain, data);
-	
args[1] = &session;
-	

MonoObject * exception = NULL;
-	
MonoObject * objResult = mono_runtime_invoke(globals.runMethod, NULL, args, &exception);
-	
if (exception) {
-		
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Exception trying to execute application mono %s.\n", data);
-		
mono_print_unhandled_exception(exception);
-	
}
-	
if (!(*(int *) mono_object_unbox(objResult))) {
-		
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Application run failed for %s (unknown module?).\n", data);
-	
}
-
} 

SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mono_shutdown) 
-{
-	
mono_thread_attach(globals.domain);
-	
MonoObject * ex;
-	
mono_runtime_invoke(globals.unloadMethod, NULL, NULL, &ex);
-	
if (ex) {
-		
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Exception occurred in Loader::Unload.\n");
-		
mono_print_unhandled_exception(ex);
-	
}
-	
mono_runtime_set_shutting_down();
-	
mono_runtime_cleanup(globals.domain);
-	
mono_runtime_quit();
-	
return SWITCH_STATUS_SUCCESS;
-
}
-
-

SWITCH_END_EXTERN_C
+	void *args[2];
+	
+args[0] = mono_string_new(globals.domain, data);
+	
+args[1] = &session;
+	
+
+MonoObject * exception = NULL;
+	
+MonoObject * objResult = mono_runtime_invoke(globals.runMethod, NULL, args, &exception);
+	
+if (exception) {
+		
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Exception trying to execute application mono %s.\n", data);
+		
+mono_print_unhandled_exception(exception);
+	
+}
+	
+if (!(*(int *) mono_object_unbox(objResult))) {
+		
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Application run failed for %s (unknown module?).\n", data);
+	
+}
+
+} 
+
+SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mono_shutdown) 
+{
+	
+mono_thread_attach(globals.domain);
+	
+MonoObject * ex;
+	
+mono_runtime_invoke(globals.unloadMethod, NULL, NULL, &ex);
+	
+if (ex) {
+		
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Exception occurred in Loader::Unload.\n");
+		
+mono_print_unhandled_exception(ex);
+	
+}
+	
+mono_runtime_set_shutting_down();
+	
+mono_runtime_cleanup(globals.domain);
+	
+mono_runtime_quit();
+	
+return SWITCH_STATUS_SUCCESS;
+
+}
+
+
+
+SWITCH_END_EXTERN_C

Modified: freeswitch/trunk/src/mod/languages/mod_mono_managed/AppFunction.cs
==============================================================================
--- freeswitch/trunk/src/mod/languages/mod_mono_managed/AppFunction.cs	(original)
+++ freeswitch/trunk/src/mod/languages/mod_mono_managed/AppFunction.cs	Mon Jun  9 23:09:14 2008
@@ -43,60 +43,6 @@
 
         protected static void Unload() { }
 
-        void hangupCallback()
-        {
-            Log.WriteLine(LogLevel.Debug, "AppFunction is in hangupCallback.");
-            try {
-               abortRun();
-                var f = HangupFunction;
-                if (f != null) f();
-            }
-            catch (Exception ex) {
-                Log.WriteLine(LogLevel.Warning, "Exception in hangupCallback: {0}", ex.ToString());
-                throw;
-            }
-        }
-
-        protected Action HangupFunction { get; set; }
-
-        protected Func<Char, TimeSpan, string> DtmfReceivedFunction { get; set; }
-
-        protected Func<Native.Event, string> EventReceivedFunction { get; set; }
-
-        string inputCallback(IntPtr input, Native.switch_input_type_t inputType)
-        {
-            switch (inputType) {
-                case FreeSWITCH.Native.switch_input_type_t.SWITCH_INPUT_TYPE_DTMF:
-                    using (var dtmf = new Native.switch_dtmf_t(input, false)) {
-                        return dtmfCallback(dtmf);
-                    }
-                case FreeSWITCH.Native.switch_input_type_t.SWITCH_INPUT_TYPE_EVENT:
-                    using (var swevt = new Native.switch_event(input, false)) {
-                        return eventCallback(swevt);
-                    }
-                default: 
-                    return "";
-            }
-        }
-
-        string dtmfCallback(Native.switch_dtmf_t dtmf)
-        {
-            var f = DtmfReceivedFunction;
-            return f == null ?
-                "-ERR No DtmfReceivedFunction set." :
-                f(((char)(byte)dtmf.digit), TimeSpan.FromMilliseconds(dtmf.duration));
-        }
-
-        string eventCallback(Native.switch_event swevt)
-        {
-            using (var evt = new FreeSWITCH.Native.Event(swevt, 0)) {
-                var f = EventReceivedFunction;
-                return f == null ?
-                    "-ERR No EventReceivedFunction set." :
-                    f(evt);
-            }
-        }
-
         protected Native.MonoSession Session { get; private set; }
 
         protected string Arguments { get; private set; }
@@ -115,7 +61,7 @@
         bool abortable = false;
         readonly object abortLock = new object();
         Thread runThread;
-        void abortRun()
+        internal void AbortRun()
         {
             if (!AbortOnHangup) return;
             if (runThread == Thread.CurrentThread) {
@@ -136,7 +82,7 @@
         {
             this.Session = session;
             this.Arguments = args;
-            Session.SetDelegates(this.inputCallback, this.hangupCallback);
+            Session.AppToAbort = this;
             try { this.Uuid = new Guid(Session.GetUuid()); }
             catch { }
             try {

Modified: freeswitch/trunk/src/mod/languages/mod_mono_managed/Demo.cs
==============================================================================
--- freeswitch/trunk/src/mod/languages/mod_mono_managed/Demo.cs	(original)
+++ freeswitch/trunk/src/mod/languages/mod_mono_managed/Demo.cs	Mon Jun  9 23:09:14 2008
@@ -53,13 +53,12 @@
 
         protected override void Run()
         {
-            HangupFunction = hangupHook;
             Session.Answer();
-            this.DtmfReceivedFunction = (d, t) => {
+            Session.DtmfReceivedFunction = (d, t) => {
                 Log.WriteLine(LogLevel.Info, "Received {0} for {1}.", d, t);
                 return "";
             };
-            Log.WriteLine(LogLevel.Info, "Inside AppDemo.Run (args '{0}'); HookState is {1}.", Arguments, Session.HookState);
+            Log.WriteLine(LogLevel.Info, "Inside AppDemo.Run (args '{0}'); HookState is {1}. Now will collect digits.", Arguments, Session.HookState);
             Session.CollectDigits(5000); // Hanging up here will cause an abort and the next line won't be written
             Log.WriteLine(LogLevel.Info, "AppDemo is finishing its run and will now hang up.");
             Session.Hangup("USER_BUSY");

Modified: freeswitch/trunk/src/mod/languages/mod_mono_managed/Loader.cs
==============================================================================
--- freeswitch/trunk/src/mod/languages/mod_mono_managed/Loader.cs	(original)
+++ freeswitch/trunk/src/mod/languages/mod_mono_managed/Loader.cs	Mon Jun  9 23:09:14 2008
@@ -227,6 +227,7 @@
             if (fType == null) return false;
 
             using (var session = new Native.MonoSession(new Native.SWIGTYPE_p_switch_core_session(sessionHandle, false))) {
+                session.Initialize();
                 session.SetAutoHangup(false);
                 try {
                     var f = (AppFunction)Activator.CreateInstance(fType);

Modified: freeswitch/trunk/src/mod/languages/mod_mono_managed/MonoSession.cs
==============================================================================
--- freeswitch/trunk/src/mod/languages/mod_mono_managed/MonoSession.cs	(original)
+++ freeswitch/trunk/src/mod/languages/mod_mono_managed/MonoSession.cs	Mon Jun  9 23:09:14 2008
@@ -35,7 +35,7 @@
 
 namespace FreeSWITCH.Native
 {
-    //switch_status_t MonoSession::run_dtmf_callback(void *input, switch_input_type_t itype)
+    // switch_status_t MonoSession::run_dtmf_callback(void *input, switch_input_type_t itype)
     // But, process_callback_result is used to turn a string into a switch_status_t
     using DtmfCallback = Func<IntPtr, Native.switch_input_type_t, string>;
     public partial class MonoSession
@@ -44,9 +44,68 @@
         [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
         static extern void InitMonoSession(IntPtr sessionPtr, DtmfCallback dtmfDelegate, Action hangupDelegate);
 
-        internal void SetDelegates(DtmfCallback dtmfCallback, Action hangupHook)
+        /// <summary>Initializes the native MonoSession. Must be called after Originate.</summary>
+        public void Initialize()
         {
-            InitMonoSession(MonoSession.getCPtr(this).Handle, dtmfCallback, hangupHook);
+            InitMonoSession(MonoSession.getCPtr(this).Handle, inputCallback, hangupCallback);
+        }
+
+        /// <summary>Function to execute when this session hangs up.</summary>
+        public Action HangupFunction { get; set; }
+
+        /// <summary>Sets the application that should have it's run thread aborted (if enabled) when this session is hungup.</summary>
+        internal AppFunction AppToAbort { get; set; }
+
+        void hangupCallback()
+        {
+            Log.WriteLine(LogLevel.Debug, "AppFunction is in hangupCallback.");
+            try {
+                if (AppToAbort != null) AppToAbort.AbortRun();
+                var f = HangupFunction;
+                if (f != null) f();
+            }
+            catch (Exception ex) {
+                Log.WriteLine(LogLevel.Warning, "Exception in hangupCallback: {0}", ex.ToString());
+                throw;
+            }
+        }
+
+        public Func<Char, TimeSpan, string> DtmfReceivedFunction { get; set; }
+
+        public Func<Native.Event, string> EventReceivedFunction { get; set; }
+
+        string inputCallback(IntPtr input, Native.switch_input_type_t inputType)
+        {
+            switch (inputType) {
+                case FreeSWITCH.Native.switch_input_type_t.SWITCH_INPUT_TYPE_DTMF:
+                    using (var dtmf = new Native.switch_dtmf_t(input, false)) {
+                        return dtmfCallback(dtmf);
+                    }
+                case FreeSWITCH.Native.switch_input_type_t.SWITCH_INPUT_TYPE_EVENT:
+                    using (var swevt = new Native.switch_event(input, false)) {
+                        return eventCallback(swevt);
+                    }
+                default:
+                    return "";
+            }
+        }
+
+        string dtmfCallback(Native.switch_dtmf_t dtmf)
+        {
+            var f = DtmfReceivedFunction;
+            return f == null ?
+                "-ERR No DtmfReceivedFunction set." :
+                f(((char)(byte)dtmf.digit), TimeSpan.FromMilliseconds(dtmf.duration));
+        }
+
+        string eventCallback(Native.switch_event swevt)
+        {
+            using (var evt = new FreeSWITCH.Native.Event(swevt, 0)) {
+                var f = EventReceivedFunction;
+                return f == null ?
+                    "-ERR No EventReceivedFunction set." :
+                    f(evt);
+            }
         }
 
     }



More information about the Freeswitch-svn mailing list