]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
Move input and hangup delegates to reside on MonoSession instead of bound to app.
authorMichael Giagnocavo <mgg@giagnocavo.net>
Tue, 10 Jun 2008 03:09:14 +0000 (03:09 +0000)
committerMichael Giagnocavo <mgg@giagnocavo.net>
Tue, 10 Jun 2008 03:09:14 +0000 (03:09 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@8791 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/mod/languages/mod_mono/freeswitch_wrap.cxx
src/mod/languages/mod_mono/mod_mono.cpp
src/mod/languages/mod_mono_managed/AppFunction.cs
src/mod/languages/mod_mono_managed/Demo.cs
src/mod/languages/mod_mono_managed/Loader.cs
src/mod/languages/mod_mono_managed/MonoSession.cs

index 6aa5e7defda53e1f1d7df77f3d8ad6cb57290491..8fc247ca6634f5d6487d2bbfa4b5b78aaabfc551 100644 (file)
@@ -24139,7 +24139,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_CoreSession_Originate(void * jarg1, void * jar
 }\r
 \r
 \r
-SWIGEXPORT int SWIGSTDCALL CSharp_CoreSession_speak(void * jarg1, char * jarg2) {\r
+SWIGEXPORT int SWIGSTDCALL CSharp_CoreSession_Speak(void * jarg1, char * jarg2) {\r
   int jresult ;\r
   CoreSession *arg1 = (CoreSession *) 0 ;\r
   char *arg2 = (char *) 0 ;\r
@@ -24153,7 +24153,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_CoreSession_speak(void * jarg1, char * jarg2)
 }\r
 \r
 \r
-SWIGEXPORT void SWIGSTDCALL CSharp_CoreSession_set_tts_parms(void * jarg1, char * jarg2, char * jarg3) {\r
+SWIGEXPORT void SWIGSTDCALL CSharp_CoreSession_SetTtsParameters(void * jarg1, char * jarg2, char * jarg3) {\r
   CoreSession *arg1 = (CoreSession *) 0 ;\r
   char *arg2 = (char *) 0 ;\r
   char *arg3 = (char *) 0 ;\r
@@ -24305,7 +24305,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_CoreSession_flushDigits(void * jarg1) {
 }\r
 \r
 \r
-SWIGEXPORT int SWIGSTDCALL CSharp_CoreSession_setAutoHangup(void * jarg1, unsigned int jarg2) {\r
+SWIGEXPORT int SWIGSTDCALL CSharp_CoreSession_SetAutoHangup(void * jarg1, unsigned int jarg2) {\r
   int jresult ;\r
   CoreSession *arg1 = (CoreSession *) 0 ;\r
   bool arg2 ;\r
index 92f1ea02b6d70cfa66b6d5592acf2c5a28d5493e..2c3447c7b08bb7722b6067f7b652789e91a5c22e 100644 (file)
  */  \r
        \r
 #include <switch.h>\r
-       \r\rSWITCH_BEGIN_EXTERN_C \r \r
+       \r
+\r
+SWITCH_BEGIN_EXTERN_C \r
\r
 #include "freeswitch_mono.h"\r
 #include <glib.h>\r
 #include <mono/jit/jit.h>\r
 #define EXPORT __declspec(dllexport)\r
 #elif\r
 #define EXPORT \r
-#endif /* \r */
+#endif /* \r
+ */\r
        \r
 #define MOD_MONO_MANAGED_DLL "mod_mono_managed.dll"\r
-       \rmod_mono_globals globals = {
-0};
-
-\r\rSWITCH_MODULE_LOAD_FUNCTION(mod_mono_load);
-\rSWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mono_shutdown);
-\rSWITCH_MODULE_DEFINITION(mod_mono, mod_mono_load, mod_mono_shutdown, NULL);
-\r\rSWITCH_STANDARD_API(monorun_api_function);   /* ExecuteBackground */
-\rSWITCH_STANDARD_API(mono_api_function);       /* Execute */
-\rSWITCH_STANDARD_APP(mono_app_function);       /* Run */
-\r\r\r
+       \r
+mod_mono_globals globals = {\r
+0};\r
+\r
+\r
+\r
+SWITCH_MODULE_LOAD_FUNCTION(mod_mono_load);\r
+\r
+SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mono_shutdown);\r
+\r
+SWITCH_MODULE_DEFINITION(mod_mono, mod_mono_load, mod_mono_shutdown, NULL);\r
+\r
+\r
+SWITCH_STANDARD_API(monorun_api_function);     /* ExecuteBackground */\r
+\r
+SWITCH_STANDARD_API(mono_api_function);        /* Execute */\r
+\r
+SWITCH_STANDARD_APP(mono_app_function);        /* Run */\r
+\r
+\r
 // Sets up delegates (and anything else needed) on the MonoSession object\r
 // Called via internalcall\r
-       SWITCH_MOD_DECLARE(void) InitMonoSession(MonoSession * session, MonoObject * dtmfDelegate, MonoObject * hangupDelegate) \r
-{
-       \rswitch_assert(session);
-       \rif (!session)
-               return;
-       \rsession->setDTMFCallback(NULL, "");
-       \rsession->setHangupHook(NULL);
-       \rsession->dtmfDelegateHandle = mono_gchandle_new(dtmfDelegate, FALSE);
-       \rsession->hangupDelegateHandle = mono_gchandle_new(hangupDelegate, FALSE);
-\r}
-\r\rswitch_status_t setMonoDirs() \r
-{
+SWITCH_MOD_DECLARE(void) InitMonoSession(MonoSession * session, MonoObject * dtmfDelegate, MonoObject * hangupDelegate) \r
+{\r
+       switch_assert(session);\r
+       if (!session) {\r
+               return;\r
+       }\r
+       session->setDTMFCallback(NULL, "");\r
+       session->setHangupHook(NULL);\r
+       session->dtmfDelegateHandle = mono_gchandle_new(dtmfDelegate, FALSE);\r
+       session->hangupDelegateHandle = mono_gchandle_new(hangupDelegate, FALSE);\r
+}\r
+\r
+\r
+switch_status_t setMonoDirs() \r
+{\r
        \r
 #ifdef WIN32   \r
                /* Win32 Mono installs can't figure out their own path\r
                   // Guys in #mono say we should just deploy all the libs we need\r
                   // I think it's much nicer to let the user deal with installing Mono\r
                   // and we'll just look for it in program files. */ \r
-               HANDLE hFind;
-       \rWIN32_FIND_DATA findData;
-       \rchar progFilesPath[MAX_PATH];
-       \rchar findPath[MAX_PATH];
-       \rSHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL, SHGFP_TYPE_CURRENT, progFilesPath);
-       \rswitch_snprintf(findPath, MAX_PATH, "%s\\Mono-*", progFilesPath);
-       \rhFind = FindFirstFile(findPath, &findData);
-       \rif (hFind == INVALID_HANDLE_VALUE) {
-               \rswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error looking for Mono in Program Files.\n");
-               \rreturn SWITCH_STATUS_FALSE;
-       \r}
-       \rwhile ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY) {
-               \rif (FindNextFile(hFind, &findData) == 0) {
-                       \rswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find Mono directory in Program Files.\n");
-                       \rFindClose(hFind);
-                       \rreturn SWITCH_STATUS_FALSE;
-               \r}
-       \r}
+               HANDLE hFind;\r
+       \r
+WIN32_FIND_DATA findData;\r
+       \r
+char progFilesPath[MAX_PATH];\r
+       \r
+char findPath[MAX_PATH];\r
+       \r
+SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL, SHGFP_TYPE_CURRENT, progFilesPath);\r
+       \r
+switch_snprintf(findPath, MAX_PATH, "%s\\Mono-*", progFilesPath);\r
+       \r
+hFind = FindFirstFile(findPath, &findData);\r
+       \r
+if (hFind == INVALID_HANDLE_VALUE) {\r
+               \r
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error looking for Mono in Program Files.\n");\r
+               \r
+return SWITCH_STATUS_FALSE;\r
+       \r
+}\r
+       \r
+while ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY) {\r
+               \r
+if (FindNextFile(hFind, &findData) == 0) {\r
+                       \r
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find Mono directory in Program Files.\n");\r
+                       \r
+FindClose(hFind);\r
+                       \r
+return SWITCH_STATUS_FALSE;\r
+               \r
+}\r
+       \r
+}\r
        \r
                /* Got it */ \r
-       {
-               \rchar libPath[MAX_PATH];
-               \rchar etcPath[MAX_PATH];
-               \rswitch_snprintf(libPath, MAX_PATH, "%s\\%s\\lib", progFilesPath, findData.cFileName);
-               \rswitch_snprintf(etcPath, MAX_PATH, "%s\\%s\\etc", progFilesPath, findData.cFileName);
-               \rFindClose(hFind);
-               \rswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Using Mono paths '%s' and '%s'.\n", libPath, etcPath);
-               \rmono_set_dirs(libPath, etcPath);
-               \rreturn SWITCH_STATUS_SUCCESS;
-       \r}
+       {\r
+               \r
+char libPath[MAX_PATH];\r
+               \r
+char etcPath[MAX_PATH];\r
+               \r
+switch_snprintf(libPath, MAX_PATH, "%s\\%s\\lib", progFilesPath, findData.cFileName);\r
+               \r
+switch_snprintf(etcPath, MAX_PATH, "%s\\%s\\etc", progFilesPath, findData.cFileName);\r
+               \r
+FindClose(hFind);\r
+               \r
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Using Mono paths '%s' and '%s'.\n", libPath, etcPath);\r
+               \r
+mono_set_dirs(libPath, etcPath);\r
+               \r
+return SWITCH_STATUS_SUCCESS;\r
+       \r
+}\r
        \r
 #elif\r
                // On other platforms, it should just work if it hasn't been relocated\r
-               mono_set_dirs(NULL, NULL);
-       \rreturn SWITCH_STATUS_SUCCESS;
+               mono_set_dirs(NULL, NULL);\r
+       \r
+return SWITCH_STATUS_SUCCESS;\r
        \r
-#endif /* \r */
-}
-\r\rswitch_status_t loadModMonoManaged() \r
-{
+#endif /* \r
+ */\r
+}\r
+\r
+\r
+switch_status_t loadModMonoManaged() \r
+{\r
        \r
                /* Find and load mod_mono_managed.exe */ \r
-       char filename[256];
-       \rswitch_snprintf(filename, 256, "%s%s%s", SWITCH_GLOBAL_dirs.mod_dir, SWITCH_PATH_SEPARATOR, MOD_MONO_MANAGED_DLL);
-       \rglobals.domain = mono_jit_init(filename);
-       \r\rif (!globals.domain) {
-               \rswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mono_jit_init failed.\n");
-               \rreturn SWITCH_STATUS_FALSE;
-       \r}
-       \r\r
+       char filename[256];\r
+       \r
+switch_snprintf(filename, 256, "%s%s%s", SWITCH_GLOBAL_dirs.mod_dir, SWITCH_PATH_SEPARATOR, MOD_MONO_MANAGED_DLL);\r
+       \r
+globals.domain = mono_jit_init(filename);\r
+       \r
+\r
+if (!globals.domain) {\r
+               \r
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mono_jit_init failed.\n");\r
+               \r
+return SWITCH_STATUS_FALSE;\r
+       \r
+}\r
+       \r
+\r
                /* Open the assembly */ \r
-               globals.mod_mono_asm = mono_domain_assembly_open(globals.domain, filename);
-       \rif (!globals.mod_mono_asm) {
-               \rswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mono_domain_assembly_open failed.\n");
-               \rreturn SWITCH_STATUS_FALSE;
-       \r}
-       \rreturn SWITCH_STATUS_SUCCESS;
-\r}
-
-\r\rMonoMethod * getMethod(const char *name, MonoClass * klass) \r
-{
-       \rMonoMethodDesc * desc;
-       \rMonoMethod * method;
-       \rdesc = mono_method_desc_new(name, TRUE);
-       \rmethod = mono_method_desc_search_in_class(desc, klass);
-       \rif (!method) {
-               \rswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find %s method.\n", name);
-               \rreturn NULL;
-       \r}
-       \rreturn method;
-\r}
-\r\rswitch_status_t findLoader() \r
-{
+               globals.mod_mono_asm = mono_domain_assembly_open(globals.domain, filename);\r
+       \r
+if (!globals.mod_mono_asm) {\r
+               \r
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mono_domain_assembly_open failed.\n");\r
+               \r
+return SWITCH_STATUS_FALSE;\r
+       \r
+}\r
+       \r
+return SWITCH_STATUS_SUCCESS;\r
+\r
+}\r
+\r
+\r
+\r
+MonoMethod * getMethod(const char *name, MonoClass * klass) \r
+{\r
+       \r
+MonoMethodDesc * desc;\r
+       \r
+MonoMethod * method;\r
+       \r
+desc = mono_method_desc_new(name, TRUE);\r
+       \r
+method = mono_method_desc_search_in_class(desc, klass);\r
+       \r
+if (!method) {\r
+               \r
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find %s method.\n", name);\r
+               \r
+return NULL;\r
+       \r
+}\r
+       \r
+return method;\r
+\r
+}\r
+\r
+\r
+switch_status_t findLoader() \r
+{\r
        \r
                /* Find loader class and methods */ \r
-               MonoImage * img;
-       \rMonoClass * loaderClass;
-       \rimg = mono_assembly_get_image(globals.mod_mono_asm);
-       \rloaderClass = mono_class_from_name(img, "FreeSWITCH", "Loader");
-       \rif (!loaderClass) {
-               \rswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find FreeSWITCH.Loader class.\n");
-               \rreturn SWITCH_STATUS_FALSE;
-       \r}
-       \r\rglobals.loadMethod = getMethod("FreeSWITCH.Loader:Load()", loaderClass);
-       \rif (!globals.loadMethod)
-               return SWITCH_STATUS_FALSE;
-       \r\rglobals.unloadMethod = getMethod("FreeSWITCH.Loader:Unload()", loaderClass);
-       \rif (!globals.unloadMethod)
-               return SWITCH_STATUS_FALSE;
-       \r\rglobals.runMethod = getMethod("FreeSWITCH.Loader:Run(string,intptr)", loaderClass);
-       \rif (!globals.runMethod)
-               return SWITCH_STATUS_FALSE;
-       \r\rglobals.executeMethod = getMethod("FreeSWITCH.Loader:Execute(string,intptr,intptr)", loaderClass);
-       \rif (!globals.executeMethod)
-               return SWITCH_STATUS_FALSE;
-       \r\rglobals.executeBackgroundMethod = getMethod("FreeSWITCH.Loader:ExecuteBackground(string)", loaderClass);
-       \rif (!globals.executeBackgroundMethod)
-               return SWITCH_STATUS_FALSE;
-       \r\rswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Found all loader functions.\n");
-       \rreturn SWITCH_STATUS_SUCCESS;
-\r}
-
-\r\rSWITCH_MODULE_LOAD_FUNCTION(mod_mono_load) \r
-{
+               MonoImage * img;\r
+       \r
+MonoClass * loaderClass;\r
+       \r
+img = mono_assembly_get_image(globals.mod_mono_asm);\r
+       \r
+loaderClass = mono_class_from_name(img, "FreeSWITCH", "Loader");\r
+       \r
+if (!loaderClass) {\r
+               \r
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find FreeSWITCH.Loader class.\n");\r
+               \r
+return SWITCH_STATUS_FALSE;\r
+       \r
+}\r
+       \r
+\r
+globals.loadMethod = getMethod("FreeSWITCH.Loader:Load()", loaderClass);\r
+       \r
+if (!globals.loadMethod)\r
+               return SWITCH_STATUS_FALSE;\r
+       \r
+\r
+globals.unloadMethod = getMethod("FreeSWITCH.Loader:Unload()", loaderClass);\r
+       \r
+if (!globals.unloadMethod)\r
+               return SWITCH_STATUS_FALSE;\r
+       \r
+\r
+globals.runMethod = getMethod("FreeSWITCH.Loader:Run(string,intptr)", loaderClass);\r
+       \r
+if (!globals.runMethod)\r
+               return SWITCH_STATUS_FALSE;\r
+       \r
+\r
+globals.executeMethod = getMethod("FreeSWITCH.Loader:Execute(string,intptr,intptr)", loaderClass);\r
+       \r
+if (!globals.executeMethod)\r
+               return SWITCH_STATUS_FALSE;\r
+       \r
+\r
+globals.executeBackgroundMethod = getMethod("FreeSWITCH.Loader:ExecuteBackground(string)", loaderClass);\r
+       \r
+if (!globals.executeBackgroundMethod)\r
+               return SWITCH_STATUS_FALSE;\r
+       \r
+\r
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Found all loader functions.\n");\r
+       \r
+return SWITCH_STATUS_SUCCESS;\r
+\r
+}\r
+\r
+\r
+\r
+SWITCH_MODULE_LOAD_FUNCTION(mod_mono_load) \r
+{\r
        \r
                /* connect my internal structure to the blank pointer passed to me */ \r
-               *module_interface = switch_loadable_module_create_module_interface(pool, modname);
-       \rglobals.pool = pool;
-       \r\rif (setMonoDirs() != SWITCH_STATUS_SUCCESS) {
-               \rreturn SWITCH_STATUS_FALSE;
-       \r}
-       \rif (loadModMonoManaged() != SWITCH_STATUS_SUCCESS) {
-               \rreturn SWITCH_STATUS_FALSE;
-       \r}
-       \rif (findLoader() != SWITCH_STATUS_SUCCESS) {
-               \rreturn SWITCH_STATUS_FALSE;
-       \r}
-       \r\r
+               *module_interface = switch_loadable_module_create_module_interface(pool, modname);\r
+       \r
+globals.pool = pool;\r
+       \r
+\r
+if (setMonoDirs() != SWITCH_STATUS_SUCCESS) {\r
+               \r
+return SWITCH_STATUS_FALSE;\r
+       \r
+}\r
+       \r
+if (loadModMonoManaged() != SWITCH_STATUS_SUCCESS) {\r
+               \r
+return SWITCH_STATUS_FALSE;\r
+       \r
+}\r
+       \r
+if (findLoader() != SWITCH_STATUS_SUCCESS) {\r
+               \r
+return SWITCH_STATUS_FALSE;\r
+       \r
+}\r
+       \r
+\r
                /* Not sure if this is necesary on the loading thread */ \r
-               mono_thread_attach(globals.domain);
-       \rmono_add_internal_call("FreeSWITCH.Native.MonoSession::InitMonoSession", InitMonoSession);
-       \r\r
+               mono_thread_attach(globals.domain);\r
+       \r
+mono_add_internal_call("FreeSWITCH.Native.MonoSession::InitMonoSession", InitMonoSession);\r
+       \r
+\r
                /* Run loader */ \r
-               MonoObject * objResult;
-       \rMonoObject * exception = NULL;
-       \robjResult = mono_runtime_invoke(globals.loadMethod, NULL, NULL, &exception);
-       \rif (exception) {
-               \rswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Load threw an exception.\n");
-               \rmono_print_unhandled_exception(exception);
-               \rreturn SWITCH_STATUS_FALSE;
-       \r}
-       \rif (*(int *) mono_object_unbox(objResult)) {
-               \rswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Load completed successfully.\n");
-       \r} else {
-               \rswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Load did not return true.\n");
-               \rreturn SWITCH_STATUS_FALSE;
-       \r}
-       \r\r\r
+               MonoObject * objResult;\r
+       \r
+MonoObject * exception = NULL;\r
+       \r
+objResult = mono_runtime_invoke(globals.loadMethod, NULL, NULL, &exception);\r
+       \r
+if (exception) {\r
+               \r
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Load threw an exception.\n");\r
+               \r
+mono_print_unhandled_exception(exception);\r
+               \r
+return SWITCH_STATUS_FALSE;\r
+       \r
+}\r
+       \r
+if (*(int *) mono_object_unbox(objResult)) {\r
+               \r
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Load completed successfully.\n");\r
+       \r
+} else {\r
+               \r
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Load did not return true.\n");\r
+               \r
+return SWITCH_STATUS_FALSE;\r
+       \r
+}\r
+       \r
+\r
+\r
                /* We're good to register */ \r
-       switch_api_interface_t *api_interface;
-       \rswitch_application_interface_t *app_interface;
-       \r\rSWITCH_ADD_API(api_interface, "monorun", "Run a module (ExecuteBackground)", monorun_api_function, "<module> [<args>]");
-       \rSWITCH_ADD_API(api_interface, "mono", "Run a module as an API function (Execute)", mono_api_function, "<module> [<args>]");
-       \rSWITCH_ADD_APP(app_interface, "mono", "Run Mono IVR", "Run a Mono IVR on a channel", mono_app_function, "<modulename> [<args>]", SAF_NONE);
-       \r\rreturn SWITCH_STATUS_SUCCESS;
-\r}
-
-\r\rSWITCH_STANDARD_API(monorun_api_function) \r
-{
+       switch_api_interface_t *api_interface;\r
+       \r
+switch_application_interface_t *app_interface;\r
+       \r
+\r
+SWITCH_ADD_API(api_interface, "monorun", "Run a module (ExecuteBackground)", monorun_api_function, "<module> [<args>]");\r
+       \r
+SWITCH_ADD_API(api_interface, "mono", "Run a module as an API function (Execute)", mono_api_function, "<module> [<args>]");\r
+       \r
+SWITCH_ADD_APP(app_interface, "mono", "Run Mono IVR", "Run a Mono IVR on a channel", mono_app_function, "<modulename> [<args>]", SAF_NONE);\r
+       \r
+\r
+return SWITCH_STATUS_SUCCESS;\r
+\r
+}\r
+\r
+\r
+\r
+SWITCH_STANDARD_API(monorun_api_function) \r
+{\r
        \r
                // TODO: Should we be detaching after all this?\r
-               mono_thread_attach(globals.domain);
-       \rif (switch_strlen_zero(cmd)) {
-               \rstream->write_function(stream, "-ERR no args specified!\n");
-               \rreturn SWITCH_STATUS_SUCCESS;
-       \r}
-       \r\r
+               mono_thread_attach(globals.domain);\r
+       \r
+if (switch_strlen_zero(cmd)) {\r
+               \r
+stream->write_function(stream, "-ERR no args specified!\n");\r
+               \r
+return SWITCH_STATUS_SUCCESS;\r
+       \r
+}\r
+       \r
+\r
                // ExecuteBackground(string command)\r
-       void *args[1];
-       \rargs[0] = mono_string_new(globals.domain, cmd);
-       \rMonoObject * exception = NULL;
-       \rMonoObject * objResult = mono_runtime_invoke(globals.executeBackgroundMethod, NULL, args, &exception);
-       \rif (exception) {
-               \rstream->write_function(stream, "-ERR FreeSWITCH.Loader.ExecuteBackground threw an exception.\n");
-               \rmono_print_unhandled_exception(exception);
-               \rreturn SWITCH_STATUS_SUCCESS;
-       \r}
-       \rif (*(int *) mono_object_unbox(objResult)) {
-               \rstream->write_function(stream, "+OK\n");
-       \r} else {
-               \rstream->write_function(stream, "-ERR ExecuteBackground returned false (unknown module?).\n");
-       \r}
-       \rreturn SWITCH_STATUS_SUCCESS;
-\r}
-
-\r\rSWITCH_STANDARD_API(mono_api_function) \r
-{
-       \rmono_thread_attach(globals.domain);
-       \rif (switch_strlen_zero(cmd)) {
-               \rstream->write_function(stream, "-ERR no args specified!\n");
-               \rreturn SWITCH_STATUS_SUCCESS;
-       \r}
-       \r\r
+       void *args[1];\r
+       \r
+args[0] = mono_string_new(globals.domain, cmd);\r
+       \r
+MonoObject * exception = NULL;\r
+       \r
+MonoObject * objResult = mono_runtime_invoke(globals.executeBackgroundMethod, NULL, args, &exception);\r
+       \r
+if (exception) {\r
+               \r
+stream->write_function(stream, "-ERR FreeSWITCH.Loader.ExecuteBackground threw an exception.\n");\r
+               \r
+mono_print_unhandled_exception(exception);\r
+               \r
+return SWITCH_STATUS_SUCCESS;\r
+       \r
+}\r
+       \r
+if (*(int *) mono_object_unbox(objResult)) {\r
+               \r
+stream->write_function(stream, "+OK\n");\r
+       \r
+} else {\r
+               \r
+stream->write_function(stream, "-ERR ExecuteBackground returned false (unknown module?).\n");\r
+       \r
+}\r
+       \r
+return SWITCH_STATUS_SUCCESS;\r
+\r
+}\r
+\r
+\r
+\r
+SWITCH_STANDARD_API(mono_api_function) \r
+{\r
+       \r
+mono_thread_attach(globals.domain);\r
+       \r
+if (switch_strlen_zero(cmd)) {\r
+               \r
+stream->write_function(stream, "-ERR no args specified!\n");\r
+               \r
+return SWITCH_STATUS_SUCCESS;\r
+       \r
+}\r
+       \r
+\r
                // Method is: Execute(string command, IntPtr streamPtr, IntPtr eventPtr)\r
-       void *args[3];
-       \rargs[0] = mono_string_new(globals.domain, cmd);
-       \rargs[1] = &stream;                     // Address of the arguments\r
-       args[2] = &(stream->param_event);
-       \r\rMonoObject * exception = NULL;
-       \rMonoObject * objResult = mono_runtime_invoke(globals.executeMethod, NULL, args, &exception);
-       \rif (exception) {
-               \rswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Exception trying to execute mono %s.\n", cmd);
-               \rmono_print_unhandled_exception(exception);
-       \r}
-       \rif (!(*(int *) mono_object_unbox(objResult))) {
-               \rswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Execute failed for %s (unknown module?).\n", cmd);
-       \r}
-       \rreturn SWITCH_STATUS_SUCCESS;
-\r}
-
-\r\rSWITCH_STANDARD_APP(mono_app_function) \r
-{
-       \rmono_thread_attach(globals.domain);
-       \rif (switch_strlen_zero(data)) {
-               \rswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No args specified!\n");
-       \r}
-       \r\r
+       void *args[3];\r
+       \r
+args[0] = mono_string_new(globals.domain, cmd);\r
+       \r
+args[1] = &stream;                     // Address of the arguments\r
+       args[2] = &(stream->param_event);\r
+       \r
+\r
+MonoObject * exception = NULL;\r
+       \r
+MonoObject * objResult = mono_runtime_invoke(globals.executeMethod, NULL, args, &exception);\r
+       \r
+if (exception) {\r
+               \r
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Exception trying to execute mono %s.\n", cmd);\r
+               \r
+mono_print_unhandled_exception(exception);\r
+       \r
+}\r
+       \r
+if (!(*(int *) mono_object_unbox(objResult))) {\r
+               \r
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Execute failed for %s (unknown module?).\n", cmd);\r
+       \r
+}\r
+       \r
+return SWITCH_STATUS_SUCCESS;\r
+\r
+}\r
+\r
+\r
+\r
+SWITCH_STANDARD_APP(mono_app_function) \r
+{\r
+       \r
+mono_thread_attach(globals.domain);\r
+       \r
+if (switch_strlen_zero(data)) {\r
+               \r
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No args specified!\n");\r
+       \r
+}\r
+       \r
+\r
                // bool Run(string command, IntPtr sessionHandle)\r
-       void *args[2];
-       \rargs[0] = mono_string_new(globals.domain, data);
-       \rargs[1] = &session;
-       \r\rMonoObject * exception = NULL;
-       \rMonoObject * objResult = mono_runtime_invoke(globals.runMethod, NULL, args, &exception);
-       \rif (exception) {
-               \rswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Exception trying to execute application mono %s.\n", data);
-               \rmono_print_unhandled_exception(exception);
-       \r}
-       \rif (!(*(int *) mono_object_unbox(objResult))) {
-               \rswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Application run failed for %s (unknown module?).\n", data);
-       \r}
-\r\r\rSWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mono_shutdown) \r
-{
-       \rmono_thread_attach(globals.domain);
-       \rMonoObject * ex;
-       \rmono_runtime_invoke(globals.unloadMethod, NULL, NULL, &ex);
-       \rif (ex) {
-               \rswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Exception occurred in Loader::Unload.\n");
-               \rmono_print_unhandled_exception(ex);
-       \r}
-       \rmono_runtime_set_shutting_down();
-       \rmono_runtime_cleanup(globals.domain);
-       \rmono_runtime_quit();
-       \rreturn SWITCH_STATUS_SUCCESS;
-\r}
-
-\r\rSWITCH_END_EXTERN_C
+       void *args[2];\r
+       \r
+args[0] = mono_string_new(globals.domain, data);\r
+       \r
+args[1] = &session;\r
+       \r
+\r
+MonoObject * exception = NULL;\r
+       \r
+MonoObject * objResult = mono_runtime_invoke(globals.runMethod, NULL, args, &exception);\r
+       \r
+if (exception) {\r
+               \r
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Exception trying to execute application mono %s.\n", data);\r
+               \r
+mono_print_unhandled_exception(exception);\r
+       \r
+}\r
+       \r
+if (!(*(int *) mono_object_unbox(objResult))) {\r
+               \r
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Application run failed for %s (unknown module?).\n", data);\r
+       \r
+}\r
+\r
+} \r
+\r
+SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mono_shutdown) \r
+{\r
+       \r
+mono_thread_attach(globals.domain);\r
+       \r
+MonoObject * ex;\r
+       \r
+mono_runtime_invoke(globals.unloadMethod, NULL, NULL, &ex);\r
+       \r
+if (ex) {\r
+               \r
+switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Exception occurred in Loader::Unload.\n");\r
+               \r
+mono_print_unhandled_exception(ex);\r
+       \r
+}\r
+       \r
+mono_runtime_set_shutting_down();\r
+       \r
+mono_runtime_cleanup(globals.domain);\r
+       \r
+mono_runtime_quit();\r
+       \r
+return SWITCH_STATUS_SUCCESS;\r
+\r
+}\r
+\r
+\r
+\r
+SWITCH_END_EXTERN_C\r
index f6e204844671d15ed345726280662fef4bfa795b..160c68e6503026f80f901fc6309dfc79ae774076 100644 (file)
@@ -43,60 +43,6 @@ namespace FreeSWITCH
 \r
         protected static void Unload() { }\r
 \r
-        void hangupCallback()\r
-        {\r
-            Log.WriteLine(LogLevel.Debug, "AppFunction is in hangupCallback.");\r
-            try {\r
-               abortRun();\r
-                var f = HangupFunction;\r
-                if (f != null) f();\r
-            }\r
-            catch (Exception ex) {\r
-                Log.WriteLine(LogLevel.Warning, "Exception in hangupCallback: {0}", ex.ToString());\r
-                throw;\r
-            }\r
-        }\r
-\r
-        protected Action HangupFunction { get; set; }\r
-\r
-        protected Func<Char, TimeSpan, string> DtmfReceivedFunction { get; set; }\r
-\r
-        protected Func<Native.Event, string> EventReceivedFunction { get; set; }\r
-\r
-        string inputCallback(IntPtr input, Native.switch_input_type_t inputType)\r
-        {\r
-            switch (inputType) {\r
-                case FreeSWITCH.Native.switch_input_type_t.SWITCH_INPUT_TYPE_DTMF:\r
-                    using (var dtmf = new Native.switch_dtmf_t(input, false)) {\r
-                        return dtmfCallback(dtmf);\r
-                    }\r
-                case FreeSWITCH.Native.switch_input_type_t.SWITCH_INPUT_TYPE_EVENT:\r
-                    using (var swevt = new Native.switch_event(input, false)) {\r
-                        return eventCallback(swevt);\r
-                    }\r
-                default: \r
-                    return "";\r
-            }\r
-        }\r
-\r
-        string dtmfCallback(Native.switch_dtmf_t dtmf)\r
-        {\r
-            var f = DtmfReceivedFunction;\r
-            return f == null ?\r
-                "-ERR No DtmfReceivedFunction set." :\r
-                f(((char)(byte)dtmf.digit), TimeSpan.FromMilliseconds(dtmf.duration));\r
-        }\r
-\r
-        string eventCallback(Native.switch_event swevt)\r
-        {\r
-            using (var evt = new FreeSWITCH.Native.Event(swevt, 0)) {\r
-                var f = EventReceivedFunction;\r
-                return f == null ?\r
-                    "-ERR No EventReceivedFunction set." :\r
-                    f(evt);\r
-            }\r
-        }\r
-\r
         protected Native.MonoSession Session { get; private set; }\r
 \r
         protected string Arguments { get; private set; }\r
@@ -115,7 +61,7 @@ namespace FreeSWITCH
         bool abortable = false;\r
         readonly object abortLock = new object();\r
         Thread runThread;\r
-        void abortRun()\r
+        internal void AbortRun()\r
         {\r
             if (!AbortOnHangup) return;\r
             if (runThread == Thread.CurrentThread) {\r
@@ -136,7 +82,7 @@ namespace FreeSWITCH
         {\r
             this.Session = session;\r
             this.Arguments = args;\r
-            Session.SetDelegates(this.inputCallback, this.hangupCallback);\r
+            Session.AppToAbort = this;\r
             try { this.Uuid = new Guid(Session.GetUuid()); }\r
             catch { }\r
             try {\r
index b63b1ca6506d24350dca29454f7d215499f933f6..d7a77d9d362675b768f727642492ab234252883f 100644 (file)
@@ -53,13 +53,12 @@ namespace FreeSWITCH.Demo
 \r
         protected override void Run()\r
         {\r
-            HangupFunction = hangupHook;\r
             Session.Answer();\r
-            this.DtmfReceivedFunction = (d, t) => {\r
+            Session.DtmfReceivedFunction = (d, t) => {\r
                 Log.WriteLine(LogLevel.Info, "Received {0} for {1}.", d, t);\r
                 return "";\r
             };\r
-            Log.WriteLine(LogLevel.Info, "Inside AppDemo.Run (args '{0}'); HookState is {1}.", Arguments, Session.HookState);\r
+            Log.WriteLine(LogLevel.Info, "Inside AppDemo.Run (args '{0}'); HookState is {1}. Now will collect digits.", Arguments, Session.HookState);\r
             Session.CollectDigits(5000); // Hanging up here will cause an abort and the next line won't be written\r
             Log.WriteLine(LogLevel.Info, "AppDemo is finishing its run and will now hang up.");\r
             Session.Hangup("USER_BUSY");\r
index 4d7c0bc377b83d64a56852027b13da1a17cf82c0..ce5f515ee8b562dc9bd7c5a23de52843c5db00db 100644 (file)
@@ -227,6 +227,7 @@ namespace FreeSWITCH
             if (fType == null) return false;\r
 \r
             using (var session = new Native.MonoSession(new Native.SWIGTYPE_p_switch_core_session(sessionHandle, false))) {\r
+                session.Initialize();\r
                 session.SetAutoHangup(false);\r
                 try {\r
                     var f = (AppFunction)Activator.CreateInstance(fType);\r
index 24c48b52220377c9b3a6a432d7c05fa88c59699c..8902928707103afd684d0660d71f1a6f4e8ad5d7 100644 (file)
@@ -35,7 +35,7 @@ using System.Text;
 \r
 namespace FreeSWITCH.Native\r
 {\r
-    //switch_status_t MonoSession::run_dtmf_callback(void *input, switch_input_type_t itype)\r
+    // switch_status_t MonoSession::run_dtmf_callback(void *input, switch_input_type_t itype)\r
     // But, process_callback_result is used to turn a string into a switch_status_t\r
     using DtmfCallback = Func<IntPtr, Native.switch_input_type_t, string>;\r
     public partial class MonoSession\r
@@ -44,9 +44,68 @@ namespace FreeSWITCH.Native
         [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]\r
         static extern void InitMonoSession(IntPtr sessionPtr, DtmfCallback dtmfDelegate, Action hangupDelegate);\r
 \r
-        internal void SetDelegates(DtmfCallback dtmfCallback, Action hangupHook)\r
+        /// <summary>Initializes the native MonoSession. Must be called after Originate.</summary>\r
+        public void Initialize()\r
         {\r
-            InitMonoSession(MonoSession.getCPtr(this).Handle, dtmfCallback, hangupHook);\r
+            InitMonoSession(MonoSession.getCPtr(this).Handle, inputCallback, hangupCallback);\r
+        }\r
+\r
+        /// <summary>Function to execute when this session hangs up.</summary>\r
+        public Action HangupFunction { get; set; }\r
+\r
+        /// <summary>Sets the application that should have it's run thread aborted (if enabled) when this session is hungup.</summary>\r
+        internal AppFunction AppToAbort { get; set; }\r
+\r
+        void hangupCallback()\r
+        {\r
+            Log.WriteLine(LogLevel.Debug, "AppFunction is in hangupCallback.");\r
+            try {\r
+                if (AppToAbort != null) AppToAbort.AbortRun();\r
+                var f = HangupFunction;\r
+                if (f != null) f();\r
+            }\r
+            catch (Exception ex) {\r
+                Log.WriteLine(LogLevel.Warning, "Exception in hangupCallback: {0}", ex.ToString());\r
+                throw;\r
+            }\r
+        }\r
+\r
+        public Func<Char, TimeSpan, string> DtmfReceivedFunction { get; set; }\r
+\r
+        public Func<Native.Event, string> EventReceivedFunction { get; set; }\r
+\r
+        string inputCallback(IntPtr input, Native.switch_input_type_t inputType)\r
+        {\r
+            switch (inputType) {\r
+                case FreeSWITCH.Native.switch_input_type_t.SWITCH_INPUT_TYPE_DTMF:\r
+                    using (var dtmf = new Native.switch_dtmf_t(input, false)) {\r
+                        return dtmfCallback(dtmf);\r
+                    }\r
+                case FreeSWITCH.Native.switch_input_type_t.SWITCH_INPUT_TYPE_EVENT:\r
+                    using (var swevt = new Native.switch_event(input, false)) {\r
+                        return eventCallback(swevt);\r
+                    }\r
+                default:\r
+                    return "";\r
+            }\r
+        }\r
+\r
+        string dtmfCallback(Native.switch_dtmf_t dtmf)\r
+        {\r
+            var f = DtmfReceivedFunction;\r
+            return f == null ?\r
+                "-ERR No DtmfReceivedFunction set." :\r
+                f(((char)(byte)dtmf.digit), TimeSpan.FromMilliseconds(dtmf.duration));\r
+        }\r
+\r
+        string eventCallback(Native.switch_event swevt)\r
+        {\r
+            using (var evt = new FreeSWITCH.Native.Event(swevt, 0)) {\r
+                var f = EventReceivedFunction;\r
+                return f == null ?\r
+                    "-ERR No EventReceivedFunction set." :\r
+                    f(evt);\r
+            }\r
         }\r
 \r
     }\r