indent pass 2

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@8689 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale committed 2008-05-27 04:54:52 +00:00
1 parent 9bbcabbbdd
commit f930eaeec7
101 files changed
+31644 -31458

No files matched your search

+69 -75
View File
@@ -27,8 +27,8 @@
*
* freeswitch_mono.cpp -- Mono-specific CoreSession subclass
*
*/
*/
#include <switch.h>
#include <switch_cpp.h>
#include <glib.h>
@@ -38,77 +38,71 @@
#include <mono/metadata/threads.h>
#include <mono/metadata/metadata.h>
#include "freeswitch_mono.h"
␍MonoSession::MonoSession():CoreSession()
{
␍} ␍␍MonoSession::MonoSession(char *uuid):CoreSession(uuid)
{
␍} ␍␍MonoSession::MonoSession(switch_core_session_t *session):CoreSession(session)
{
␍} ␍␍MonoSession::~MonoSession()
{
␍mono_thread_attach(globals.domain);
␍if (dtmfDelegateHandle)
mono_gchandle_free(dtmfDelegateHandle);
␍if (hangupDelegateHandle)
mono_gchandle_free(hangupDelegateHandle);
␍}
␍␍bool MonoSession::begin_allow_threads()
{
␍return true;
␍}
␍␍bool MonoSession::end_allow_threads()
{
␍return true;
␍}
␍␍void MonoSession::check_hangup_hook()
{
␍mono_thread_attach(globals.domain);
␍if (!hangupDelegateHandle) {
␍return;
␍}
␍MonoObject * hangupDelegate = mono_gchandle_get_target(hangupDelegateHandle);
␍if (!hangupDelegate) {
␍switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "hangupDelegateHandle didn't get an object.");
␍return;
␍}
␍MonoObject * ex = NULL;
␍mono_runtime_delegate_invoke(hangupDelegate, NULL, &ex);
␍if (ex) {
␍switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "hangupDelegate threw an exception.");
␍}
␍}
␍␍switch_status_t MonoSession::run_dtmf_callback(void *input, switch_input_type_t itype)
{
␍mono_thread_attach(globals.domain);
␍if (!dtmfDelegateHandle) {
␍return SWITCH_STATUS_SUCCESS;
␍}
␍MonoObject * dtmfDelegate = mono_gchandle_get_target(dtmfDelegateHandle);
␍if (!dtmfDelegate) {
␍switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "dtmfDelegateHandle didn't get an object.");
␍return SWITCH_STATUS_SUCCESS;
␍}
␍void *args[2];
␍args[0] = &input;
␍args[1] = &itype;
␍MonoObject * ex = NULL;
␍MonoObject * res = mono_runtime_delegate_invoke(dtmfDelegate, args, &ex);
␍if (ex) {
␍switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "dtmfDelegate threw an exception.");
␍return SWITCH_STATUS_FALSE;
␍}
␍char *resPtr = mono_string_to_utf8((MonoString *) res);
␍switch_status_t status = process_callback_result(resPtr);
␍␍g_free(resPtr);
␍return status;
␍}
MonoSession::MonoSession() : CoreSession()
{
}
MonoSession::MonoSession(char *uuid) : CoreSession(uuid)
{
}
MonoSession::MonoSession(switch_core_session_t *session) : CoreSession(session)
{
}
MonoSession::~MonoSession()
{
mono_thread_attach(globals.domain);
if (dtmfDelegateHandle) mono_gchandle_free(dtmfDelegateHandle);
if (hangupDelegateHandle) mono_gchandle_free(hangupDelegateHandle);
}
bool MonoSession::begin_allow_threads()
{
return true;
}
bool MonoSession::end_allow_threads()
{
return true;
}
void MonoSession::check_hangup_hook()
{
mono_thread_attach(globals.domain);
if (!hangupDelegateHandle) {
return;
}
MonoObject *hangupDelegate = mono_gchandle_get_target(hangupDelegateHandle);
if (!hangupDelegate) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "hangupDelegateHandle didn't get an object.");
return;
}
MonoObject *ex = NULL;
mono_runtime_delegate_invoke(hangupDelegate, NULL, &ex);
if (ex) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "hangupDelegate threw an exception.");
}
}
switch_status_t MonoSession::run_dtmf_callback(void *input, switch_input_type_t itype)
{
mono_thread_attach(globals.domain);
if (!dtmfDelegateHandle) {
return SWITCH_STATUS_SUCCESS;
}
MonoObject *dtmfDelegate = mono_gchandle_get_target(dtmfDelegateHandle);
if (!dtmfDelegate) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "dtmfDelegateHandle didn't get an object.");
return SWITCH_STATUS_SUCCESS;
}
void *args[2];
args[0] = &input;
args[1] = &itype;
MonoObject *ex = NULL;
MonoObject *res = mono_runtime_delegate_invoke(dtmfDelegate, args, &ex);
if (ex) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "dtmfDelegate threw an exception.");
return SWITCH_STATUS_FALSE;
}
char *resPtr = mono_string_to_utf8((MonoString*)res);
switch_status_t status = process_callback_result(resPtr);
g_free(resPtr);
return status;
}
+264 -273
View File
@@ -30,13 +30,10 @@
* Most of mod_mono is implmented in the mod_mono_managed Loader class.
* The native code just handles getting the Mono runtime up and down
* and passing pointers into managed code.
*/
*/
#include <switch.h>
SWITCH_BEGIN_EXTERN_C
␍␍SWITCH_BEGIN_EXTERN_C ␍
#include "freeswitch_mono.h"
#include <glib.h>
#include <mono/jit/jit.h>
@@ -44,284 +41,278 @@ SWITCH_BEGIN_EXTERN_C
#include <mono/metadata/environment.h>
#include <mono/metadata/threads.h>
#include <mono/metadata/debug-helpers.h>
#ifdef WIN32
#include <shlobj.h>
#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;
}
}
/* 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;
}
/* 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;
␍}
␍}
/* 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;
␍}
#elif
// On other platforms, it should just work if it hasn't been relocated
mono_set_dirs(NULL, NULL);
return SWITCH_STATUS_SUCCESS;
#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;
}
/* 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()
{
/* 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;
// On other platforms, it should just work if it hasn't been relocated
mono_set_dirs(NULL, NULL);
␍return SWITCH_STATUS_SUCCESS;
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;
}
/* Not sure if this is necesary on the loading thread */
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;
}
/* 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);
#endif /* ␍ */
}
␍␍switch_status_t loadModMonoManaged()
{
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;
}
// 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;
}
/* 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;
␍}
␍
/* 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()
{
// 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);
/* 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)
{
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
/* 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;
␍}
␍
/* Not sure if this is necesary on the loading thread */
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;
␍}
␍␍
/* 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)
{
// 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;
␍}
␍
// 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;
␍}
␍
// 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");
␍}
␍
// 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