inital checkin of mod_dotnet (to be merged somewhat with mod_mono)

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@9629 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Michael Jerris 2008-09-23 21:28:48 +00:00
parent 65f04969a5
commit 3be36d902f
19 changed files with 51887 additions and 0 deletions

View File

@ -0,0 +1,139 @@
%module freeswitch
/** insert the following includes into generated code so it compiles */
%{
#include "switch.h"
#include "switch_cpp.h"
#include "freeswitch_mono.h"
%}
%typemap(csclassmodifiers) MonoSession "public partial class"
%typemap(csclassmodifiers) Event "public partial class"
%typemap(csclassmodifiers) Stream "public partial class"
// Allow bitwise compare on flag fields
%typemap(csclassmodifiers) session_flag_t "[System.Flags] public enum"
%typemap(csclassmodifiers) switch_application_flag_enum_t "[System.Flags] public enum"
%typemap(csclassmodifiers) switch_asr_flag_enum_t "[System.Flags] public enum"
%typemap(csclassmodifiers) switch_bind_flag_enum_t "[System.Flags] public enum"
%typemap(csclassmodifiers) switch_caller_profile_flag_enum_t "[System.Flags] public enum"
%typemap(csclassmodifiers) switch_channel_flag_enum_t "[System.Flags] public enum"
%typemap(csclassmodifiers) switch_codec_flag_enum_t "[System.Flags] public enum"
%typemap(csclassmodifiers) switch_core_flag_enum_t "[System.Flags] public enum"
%typemap(csclassmodifiers) switch_core_session_message_flag_enum_t "[System.Flags] public enum"
%typemap(csclassmodifiers) switch_directory_flag_enum_t "[System.Flags] public enum"
%typemap(csclassmodifiers) switch_eavesdrop_flag_enum_t "[System.Flags] public enum"
%typemap(csclassmodifiers) switch_file_flag_enum_t "[System.Flags] public enum"
%typemap(csclassmodifiers) switch_frame_flag_enum_t "[System.Flags] public enum"
%typemap(csclassmodifiers) switch_io_flag_enum_t "[System.Flags] public enum"
%typemap(csclassmodifiers) switch_media_bug_flag_enum_t "[System.Flags] public enum"
%typemap(csclassmodifiers) switch_media_flag_enum_t "[System.Flags] public enum"
%typemap(csclassmodifiers) switch_originate_flag_enum_t "[System.Flags] public enum"
%typemap(csclassmodifiers) switch_port_flag_enum_t "[System.Flags] public enum"
%typemap(csclassmodifiers) switch_rtp_flag_enum_t "[System.Flags] public enum"
%typemap(csclassmodifiers) switch_scheduler_flag_enum_t "[System.Flags] public enum"
%typemap(csclassmodifiers) switch_speech_flag_enum_t "[System.Flags] public enum"
%typemap(csclassmodifiers) switch_timer_flag_enum_t "[System.Flags] public enum"
%typemap(csclassmodifiers) switch_unicast_flag_enum_t "[System.Flags] public enum"
%typemap(csclassmodifiers) switch_vad_flag_enum_t "[System.Flags] public enum"
%typemap(csclassmodifiers) switch_xml_flag_t "[System.Flags] public enum"
%typemap(csclassmodifiers) switch_xml_section_enum_t "[System.Flags] public enum"
// Some things we dont want exposed to managed users directly, since
// we're gonna handle them with our own internalcall methods
%ignore dtmfDelegateHandle;
%ignore hangupDelegateHandle;
%ignore setHangupHook;
%ignore beginAllowThreads;
%ignore endAllowThreads;
%ignore process_callback_result;
%ignore run_dtmf_callback;
%ignore setDTMFCallback;
// Rename some things to make them more .NET-like
//%csmethodmodifiers CoreSession::hangup "internal";
%rename (Answer) CoreSession::answer;
%rename (Hangup) CoreSession::hangup;
%rename (Ready) CoreSession::ready;
%rename (Transfer) CoreSession::transfer;
%rename (Originate) CoreSession::originate;
%rename (SetVariable) CoreSession::setVariable;
%rename (GetVariable) CoreSession::getVariable;
%rename (SetPrivate) CoreSession::setPrivate;
%rename (GetPrivate) CoreSession::getPrivate;
%rename (Say) CoreSession::say;
%rename (SayPhrase) CoreSession::sayPhrase;
%rename (RecordFile) CoreSession::recordFile;
%rename (SetCallerData) CoreSession::setCallerData;
%rename (CollectDigits) CoreSession::collectDigits;
%rename (GetDigits) CoreSession::getDigits;
%rename (PlayAndGetDigits) CoreSession::playAndGetDigits;
%rename (StreamFile) CoreSession::streamFile;
%rename (Execute) CoreSession::execute;
%rename (GetUuid) CoreSession::get_uuid;
%rename (HookState) CoreSession::hook_state;
%rename (InternalSession) CoreSession::session;
%rename (Speak) CoreSession::speak;
%rename (SetTtsParameters) CoreSession::set_tts_parms;
%rename (SetAutoHangup) CoreSession::setAutoHangup;
%rename (Serialize) Event::serialize;
%rename (SetPriority) Event::setPriority;
%rename (GetHeader) Event::getHeader;
%rename (GetBody) Event::getBody;
%rename (GetEventType) Event::getType;
%rename (AddBody) Event::addBody;
%rename (AddHeader) Event::addHeader;
%rename (DeleteHeader) Event::delHeader;
%rename (Fire) Event::fire;
%rename (InternalEvent) Event::event;
%rename (Write) Stream::write;
%rename (GetData) Stream::getData;
%rename (Api) API;
%rename (Execute) API::execute;
%rename (ExecuteString) API::executeString;
%rename (IvrMenu) IVRMenu;
%rename (Execute) IVRMenu::execute;
%rename (ExecuteString) API::executeString;
// Causes C2564, todo
%ignore switch_ivr_menu_action_function_t;
// todo, other errors
%ignore switch_core_session_get_event_hooks;
%ignore switch_inet_pton;
%ignore switch_xml_idx;
// Real header includes now
%import switch_platform.i // This will give us all the macros we need to compile the other stuff
%include switch.h
%include switch_types.h
%include switch_core_db.h
%include switch_regex.h
%include switch_core.h
//%include switch_loadable_module.h // todo: Sort out some linking issues
%include switch_console.h // Has unsupported varargs functions
%include switch_utils.h
%include switch_caller.h
%include switch_frame.h
%include switch_module_interfaces.h
%include switch_channel.h
%include switch_buffer.h
%include switch_event.h // Varargs omitted
%include switch_resample.h
%include switch_ivr.h
%include switch_rtp.h
%include switch_log.h // switch_log_printf is omitted (varargs)
%include switch_xml.h
%include switch_core_event_hook.h
%include switch_scheduler.h
%include switch_config.h
%include switch_cpp.h
%include freeswitch_mono.h

View File

@ -0,0 +1,107 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_dotnet
* Copyright (C) 2008, Michael Giagnocavo <mgg@packetrino.com>
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_dotnet
*
* The Initial Developer of the Original Code is
* Michael Giagnocavo <mgg@packetrino.com>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Michael Giagnocavo <mgg@packetrino.com>
* Jeff Lenk <jlenk@frontiernet.net> - Modified class to support Dotnet
*
* freeswitch_mono.cpp -- Dotnet-specific CoreSession subclass
*
*/
#include <switch.h>
#include <switch_cpp.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()
{
// Do auto-hangup ourselves because CoreSession can't call check_hangup_hook
// after MonoSession destruction (cause at point it's pure virtual)
if (session) {
channel = switch_core_session_get_channel(session);
if (switch_test_flag(this, S_HUP) && !switch_channel_test_flag(channel, CF_TRANSFER)) {
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
setAutoHangup(0);
}
// Don't let any callbacks use this CoreSession anymore
switch_channel_set_private(channel, "CoreSession", NULL);
}
}
bool MonoSession::begin_allow_threads()
{
return true;
}
bool MonoSession::end_allow_threads()
{
return true;
}
void MonoSession::check_hangup_hook()
{
if (!hangupDelegateHandle) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "hangupDelegateHandle didn't get an object.");
return;
}
hangupDelegateHandle();
}
switch_status_t MonoSession::run_dtmf_callback(void *input, switch_input_type_t itype)
{
if (!dtmfDelegateHandle) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "dtmfDelegateHandle didn't get an object.");
return SWITCH_STATUS_FALSE;;
}
char* result = dtmfDelegateHandle(input, itype);
switch_status_t status = process_callback_result(result);
return status;
}

View File

@ -0,0 +1,81 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_dotnet
* Copyright (C) 2008, Michael Giagnocavo <mgg@packetrino.com>
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_dotnet
*
* The Initial Developer of the Original Code is
* Michael Giagnocavo <mgg@packetrino.com>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Michael Giagnocavo <mgg@packetrino.com>
* Jeff Lenk <jlenk@frontiernet.net> - Modified class to support Dotnet
*
* freeswitch_mono.h -- Header for MonoSession and globals
*
*/
#ifndef FREESWITCH_MONO_H
#define FREESWITCH_MONO_H
SWITCH_BEGIN_EXTERN_C
#include <switch.h>
#include <switch_cpp.h>
typedef char* (CALLBACK* inputtype)(void * input, switch_input_type_t type);
typedef void (CALLBACK* hanguptype)();
SWITCH_END_EXTERN_C
using namespace System;
using namespace System::Reflection;
using namespace System::Runtime::InteropServices;
delegate void HangupMethod();
public ref class FreeSwitchManaged
{
public:
static Assembly^ mod_dotnet_managed;
static MethodInfo^ loadMethod;
static MethodInfo^ unloadMethod;
static MethodInfo^ runMethod;
static MethodInfo^ executeMethod;
static MethodInfo^ executeBackgroundMethod;
};
class MonoSession : public CoreSession
{
public:
MonoSession();
MonoSession(char *uuid);
MonoSession(switch_core_session_t *session);
virtual ~MonoSession();
virtual bool begin_allow_threads();
virtual bool end_allow_threads();
virtual void check_hangup_hook();
virtual switch_status_t run_dtmf_callback(void *input, switch_input_type_t itype);
inputtype dtmfDelegateHandle; // GCHandle to the input delegate
hanguptype hangupDelegateHandle; // GCHandle to the hangup delegate
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,328 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_dotnet
* Copyright (C) 2008, Jeff Lenk <jlenk@frontiernet.net>
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_dotnet
*
* The Initial Developer of the Original Code is
* Jeff Lenk <jlenk@frontiernet.net>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Jeff Lenk <jlenk@frontiernet.net>
* Michael Giagnocavo <mgg@packetrino.com> - used mod_mono as a template and inspiration
*
* mod_dotnet.cpp -- FreeSWITCH mod_dotnet main class
*
* Most of mod_dotnet is implmented in the mod_dotnet_managed Loader class.
* The native code just handles getting the Dotnet runtime up and down
* and passing pointers into managed code.
*/
#include <switch.h>
#include <apr_pools.h>
#include <mscoree.h>
SWITCH_BEGIN_EXTERN_C
#include "freeswitch_mono.h"
#define MOD_DOTNET_MANAGED_DLL "mod_dotnet_managed.dll"
struct dotnet_conf_t {
switch_memory_pool_t *pool;
ICLRRuntimeHost *pCorRuntime;
HMODULE lock_module;
OSVERSIONINFO osver;
char *cor_version;
} globals;
SWITCH_MODULE_LOAD_FUNCTION(mod_dotnet_load);
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_dotnet_shutdown);
SWITCH_MODULE_DEFINITION(mod_dotnet, mod_dotnet_load, mod_dotnet_shutdown, NULL);
SWITCH_STANDARD_API(dotnetrun_api_function); /* ExecuteBackground */
SWITCH_STANDARD_API(dotnet_api_function); /* Execute */
SWITCH_STANDARD_APP(dotnet_app_function); /* Run */
// Sets up delegates (and anything else needed) on the MonoSession object
// Called from MonoSession.Initialize Managed -> this is Unmanaged code so all pointers are marshalled and prevented from GC
// Exported method.
SWITCH_MOD_DECLARE(void) InitDotnetSession(MonoSession * session, inputtype dtmfDelegate, hanguptype hangupDelegate)
{
switch_assert(session);
if (!session) {
return;
}
session->setDTMFCallback(NULL, "");
session->setHangupHook(NULL);
session->dtmfDelegateHandle = dtmfDelegate;
session->hangupDelegateHandle = hangupDelegate;
}
switch_status_t loadModDotnetManaged()
{
/* Find and load mod_dotnet_managed.dll */
char filename[256];
switch_snprintf(filename, 256, "%s%s%s", SWITCH_GLOBAL_dirs.mod_dir, SWITCH_PATH_SEPARATOR, MOD_DOTNET_MANAGED_DLL);
HRESULT hr;
wchar_t wCORVersion[256];
if (globals.cor_version) {
MultiByteToWideChar(CP_UTF8, 0, globals.cor_version, -1,
wCORVersion, sizeof(wCORVersion) / sizeof(wchar_t));
}
else {
DWORD bytes;
hr = GetCORVersion(wCORVersion, sizeof(wCORVersion)
/ sizeof(wchar_t) - 1, &bytes);
if (FAILED(hr)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
"mod_dotnet: GetCORVersion failed to return "
"the .NET CLR engine version.");
return SWITCH_STATUS_FALSE;
}
int len = WideCharToMultiByte(CP_UTF8, 0, wCORVersion, -1,
NULL, 0, NULL, NULL);
globals.cor_version = (char *)apr_palloc(globals.pool, len);
len = WideCharToMultiByte(CP_UTF8, 0, wCORVersion, -1,
globals.cor_version, len, NULL, NULL);
}
//verify that the clr is already loaded - because this dll is a clr enabled dll it will be loaded but lets get its info anyway
hr = CorBindToRuntimeEx(wCORVersion,
L"wks", // Or "svr"
STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN_HOST |
STARTUP_CONCURRENT_GC,
CLSID_CorRuntimeHost,
IID_ICorRuntimeHost,
(void **)&globals.pCorRuntime);
if (FAILED(hr)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
"mod_dotnet: Could not CorBindToRuntimeEx version "
"%s for the .NET CLR engine.", globals.cor_version);
return SWITCH_STATUS_FALSE;
}
if (hr != 1) { // a value of one here means that the specified clr is already loaded and good.
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
"mod_dotnet: Could not start the "
".NET CLR engine.");
return SWITCH_STATUS_FALSE;
}
wchar_t modpath[256];
mbstowcs(modpath, filename, 255);
try {
FreeSwitchManaged::mod_dotnet_managed = Assembly::LoadFrom(gcnew String(modpath));
}
catch (Exception^) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mono_domain_assembly_open failed.\n");
return SWITCH_STATUS_FALSE;
}
return SWITCH_STATUS_SUCCESS;
}
switch_status_t findLoader()
{
try{
FreeSwitchManaged::loadMethod = FreeSwitchManaged::mod_dotnet_managed->GetType("FreeSWITCH.Loader")->GetMethod("Load");
FreeSwitchManaged::unloadMethod = FreeSwitchManaged::mod_dotnet_managed->GetType("FreeSWITCH.Loader")->GetMethod("Unload");
FreeSwitchManaged::runMethod = FreeSwitchManaged::mod_dotnet_managed->GetType("FreeSWITCH.Loader")->GetMethod("Run");
FreeSwitchManaged::executeMethod = FreeSwitchManaged::mod_dotnet_managed->GetType("FreeSWITCH.Loader")->GetMethod("Execute");
FreeSwitchManaged::executeBackgroundMethod = FreeSwitchManaged::mod_dotnet_managed->GetType("FreeSWITCH.Loader")->GetMethod("ExecuteBackground");
}
catch(Exception^ ex) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find FreeSWITCH.Loader class %s.\n", ex->ToString());
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_dotnet_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 (loadModDotnetManaged() != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_FALSE;
}
if (findLoader() != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_FALSE;
}
Object ^objResult;
try {
objResult = FreeSwitchManaged::loadMethod->Invoke(nullptr, nullptr);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Load completed successfully.\n");
}
catch(Exception^ ex) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Load did not return true. %s\n", ex->ToString());
return SWITCH_STATUS_FALSE;
}
if (*reinterpret_cast<bool^>(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, "dotnetrun", "Run a module (ExecuteBackground)", dotnetrun_api_function, "<module> [<args>]");
SWITCH_ADD_API(api_interface, "dotnet", "Run a module as an API function (Execute)", dotnet_api_function, "<module> [<args>]");
SWITCH_ADD_APP(app_interface, "dotnet", "Run Mono App", "Run an App on a channel", dotnet_app_function, "<modulename> [<args>]", SAF_NONE);
return SWITCH_STATUS_SUCCESS;
}
SWITCH_STANDARD_API(dotnetrun_api_function)
{
if (switch_strlen_zero(cmd)) {
stream->write_function(stream, "-ERR no args specified!\n");
return SWITCH_STATUS_SUCCESS;
}
Object ^objResult;
try {
objResult = FreeSwitchManaged::executeBackgroundMethod->Invoke(nullptr, gcnew array<Object^>{gcnew String(cmd)});
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Load completed successfully.\n");
}
catch(Exception^) {
stream->write_function(stream, "-ERR FreeSWITCH.Loader.ExecuteBackground threw an exception.\n");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Load did not return true.\n");
return SWITCH_STATUS_FALSE;
}
if (*reinterpret_cast<bool^>(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(dotnet_api_function)
{
if (switch_strlen_zero(cmd)) {
stream->write_function(stream, "-ERR no args specified!\n");
return SWITCH_STATUS_SUCCESS;
}
Object ^objResult;
try {
objResult = FreeSwitchManaged::executeMethod->Invoke(nullptr, gcnew array<Object^>{gcnew String(cmd),gcnew IntPtr(stream), gcnew IntPtr(stream->param_event)});
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Execute completed successfully.\n");
}
catch(Exception ^ex) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Exception trying to execute mono %s %s.\n", cmd, ex->ToString());
return SWITCH_STATUS_FALSE;
}
if (!*reinterpret_cast<bool^>(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(dotnet_app_function)
{
if (switch_strlen_zero(data)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No args specified!\n");
}
Object ^objResult;
try {
objResult = FreeSwitchManaged::runMethod->Invoke(nullptr, gcnew array<Object^>{gcnew String(data),gcnew IntPtr(session)});
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "RunMethod completed successfully.\n");
}
catch(Exception ^ex) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Exception trying to execute application mono %s %s.\n", data, ex->ToString());
return;
}
if (!*reinterpret_cast<bool^>(objResult)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Application run failed for %s (unknown module?).\n", data);
}
}
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_dotnet_shutdown)
{
Object ^objResult;
try {
objResult = FreeSwitchManaged::unloadMethod->Invoke(nullptr, nullptr);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "UnloadMethod completed successfully.\n");
}
catch(Exception^) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Exception occurred in Loader::Unload.\n");
return SWITCH_STATUS_FALSE;;
}
return SWITCH_STATUS_SUCCESS;
}
SWITCH_END_EXTERN_C

View File

@ -0,0 +1,226 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="mod_dotnet"
ProjectGUID="{7B42BDA1-72C0-4378-A9B6-5C530F8CD61E}"
RootNamespace="mod_dotnet"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
InheritedPropertySheets="..\..\..\..\w32\module_debug.vsprops"
CharacterSet="2"
ManagedExtensions="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;C:\Program Files\Mono\lib\glib-2.0\include&quot;;&quot;C:\Program Files\Mono\include\glib-2.0&quot;;&quot;C:\Program Files\Mono\include\mono-1.0&quot;;..\..\..\..\libs\apr\include"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_MONO_EXPORTS"
MinimalRebuild="false"
BasicRuntimeChecks="0"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
DisableSpecificWarnings="4505"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="shlwapi.lib mscoree.lib"
LinkIncremental="2"
ModuleDefinitionFile=""
GenerateDebugInformation="true"
AssemblyDebug="1"
SubSystem="0"
DataExecutionPrevention="1"
TargetMachine="0"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
InheritedPropertySheets="..\..\..\..\w32\module_release.vsprops"
CharacterSet="1"
ManagedExtensions="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="..\..\..\..\libs\apr\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_MONO_EXPORTS"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
ModuleDefinitionFile=""
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\freeswitch_mono.cpp"
>
</File>
<File
RelativePath=".\freeswitch_wrap.cxx"
>
</File>
<File
RelativePath=".\mod_dotnet.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\freeswitch_mono.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
<File
RelativePath=".\freeswitch.i"
>
</File>
<File
RelativePath=".\switch_platform.i"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,336 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_dotnet
* Copyright (C) 2008, Michael Giagnocavo <mgg@packetrino.com>
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_dotnet
*
* The Initial Developer of the Original Code is
* Michael Giagnocavo <mgg@packetrino.com>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Michael Giagnocavo <mgg@packetrino.com>
*
* mod_mono.cpp -- FreeSWITCH mod_mono main class
*
* Most of mod_dotnet is implmented in the mod_dotnet_managed Loader class.
* The native code just handles getting the Dotnet runtime up and down
* and passing pointers into managed code.
*/
#include <switch.h>
#include <apr_pools.h>
#include <mscoree.h>
SWITCH_BEGIN_EXTERN_C
#ifdef WIN32
#include <shlobj.h>
#define EXPORT __declspec(dllexport)
#elif
#define EXPORT
#endif /*
*/
#include "freeswitch_mono.h"
#define MOD_DOTNET_MANAGED_DLL "mod_dotnet_managed.dll"
struct dotnet_conf_t {
switch_memory_pool_t *pool;
ICLRRuntimeHost *pCorRuntime;
HMODULE lock_module;
OSVERSIONINFO osver;
char *cor_version;
} globals;
SWITCH_MODULE_LOAD_FUNCTION(mod_dotnet_load);
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_dotnet_shutdown);
SWITCH_MODULE_DEFINITION(mod_dotnet, mod_dotnet_load, mod_dotnet_shutdown, NULL);
SWITCH_STANDARD_API(dotnetrun_api_function); /* ExecuteBackground */
SWITCH_STANDARD_API(dotnet_api_function); /* Execute */
SWITCH_STANDARD_APP(dotnet_app_function); /* Run */
// Sets up delegates (and anything else needed) on the MonoSession object
// Called from MonoSession.Initialize Managed -> this is Unmanaged code so all pointers are marshalled and prevented from GC
// Exported method.
SWITCH_MOD_DECLARE(void) InitDotnetSession(MonoSession * session, inputtype dtmfDelegate, hanguptype hangupDelegate)
{
switch_assert(session);
if (!session) {
return;
}
session->setDTMFCallback(NULL, "");
session->setHangupHook(NULL);
session->dtmfDelegateHandle = dtmfDelegate;
session->hangupDelegateHandle = hangupDelegate;
}
switch_status_t loadModMonoManaged()
{
/* Find and load mod_dotnet_managed.dll */
char filename[256];
switch_snprintf(filename, 256, "%s%s%s", SWITCH_GLOBAL_dirs.mod_dir, SWITCH_PATH_SEPARATOR, MOD_DOTNET_MANAGED_DLL);
HRESULT hr;
wchar_t wCORVersion[256];
if (globals.cor_version) {
MultiByteToWideChar(CP_UTF8, 0, globals.cor_version, -1,
wCORVersion, sizeof(wCORVersion) / sizeof(wchar_t));
}
else {
DWORD bytes;
hr = GetCORVersion(wCORVersion, sizeof(wCORVersion)
/ sizeof(wchar_t) - 1, &bytes);
if (FAILED(hr)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
"mod_dotnet: GetCORVersion failed to return "
"the .NET CLR engine version.");
return SWITCH_STATUS_FALSE;
}
int len = WideCharToMultiByte(CP_UTF8, 0, wCORVersion, -1,
NULL, 0, NULL, NULL);
globals.cor_version = (char *)apr_palloc(globals.pool, len);
len = WideCharToMultiByte(CP_UTF8, 0, wCORVersion, -1,
globals.cor_version, len, NULL, NULL);
}
hr = CorBindToRuntimeEx(wCORVersion,
L"wks", // Or "svr"
STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN_HOST |
STARTUP_CONCURRENT_GC,
CLSID_CorRuntimeHost,
IID_ICorRuntimeHost,
(void **)&globals.pCorRuntime);
if (FAILED(hr)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
"mod_dotnet: Could not CorBindToRuntimeEx version "
"%s for the .NET CLR engine.", globals.cor_version);
return SWITCH_STATUS_FALSE;
}
hr = globals.pCorRuntime->Start();
if (FAILED(hr)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
"mod_dotnet: Could not start the "
".NET CLR engine.");
return SWITCH_STATUS_FALSE;
}
wchar_t modpath[256];
mbstowcs(modpath, filename, 255);
try
{
FreeSwitchManaged::mod_dotnet_managed = Assembly::LoadFrom(gcnew String(modpath));
}
catch (Exception^) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mono_domain_assembly_open failed.\n");
return SWITCH_STATUS_FALSE;
}
return SWITCH_STATUS_SUCCESS;
}
switch_status_t findLoader()
{
try{
FreeSwitchManaged::loadMethod = FreeSwitchManaged::mod_dotnet_managed->GetType("FreeSWITCH.Loader")->GetMethod("Load");
FreeSwitchManaged::unloadMethod = FreeSwitchManaged::mod_dotnet_managed->GetType("FreeSWITCH.Loader")->GetMethod("Unload");
FreeSwitchManaged::runMethod = FreeSwitchManaged::mod_dotnet_managed->GetType("FreeSWITCH.Loader")->GetMethod("Run");
FreeSwitchManaged::executeMethod = FreeSwitchManaged::mod_dotnet_managed->GetType("FreeSWITCH.Loader")->GetMethod("Execute");
FreeSwitchManaged::executeBackgroundMethod = FreeSwitchManaged::mod_dotnet_managed->GetType("FreeSWITCH.Loader")->GetMethod("ExecuteBackground");
}
catch(Exception^ ex) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find FreeSWITCH.Loader class %s.\n", ex->ToString());
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_dotnet_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 (loadModMonoManaged() != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_FALSE;
}
if (findLoader() != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_FALSE;
}
Object ^objResult;
try{
objResult = FreeSwitchManaged::loadMethod->Invoke(nullptr, nullptr);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Load completed successfully.\n");
}
catch(Exception^ ex) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Load did not return true. %s\n", ex->ToString());
return SWITCH_STATUS_FALSE;
}
if (*reinterpret_cast<bool^>(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, "dotnetrun", "Run a module (ExecuteBackground)", dotnetrun_api_function, "<module> [<args>]");
SWITCH_ADD_API(api_interface, "dotnet", "Run a module as an API function (Execute)", dotnet_api_function, "<module> [<args>]");
SWITCH_ADD_APP(app_interface, "dotnet", "Run Mono IVR", "Run an App on a channel", dotnet_app_function, "<modulename> [<args>]", SAF_NONE);
return SWITCH_STATUS_SUCCESS;
}
SWITCH_STANDARD_API(dotnetrun_api_function)
{
if (switch_strlen_zero(cmd)) {
stream->write_function(stream, "-ERR no args specified!\n");
return SWITCH_STATUS_SUCCESS;
}
Object ^objResult;
try{
objResult = FreeSwitchManaged::executeBackgroundMethod->Invoke(nullptr, gcnew array<Object^>{gcnew String(cmd)});
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Load completed successfully.\n");
}
catch(Exception^) {
stream->write_function(stream, "-ERR FreeSWITCH.Loader.ExecuteBackground threw an exception.\n");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Load did not return true.\n");
return SWITCH_STATUS_FALSE;
}
if (*reinterpret_cast<bool^>(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(dotnet_api_function)
{
if (switch_strlen_zero(cmd)) {
stream->write_function(stream, "-ERR no args specified!\n");
return SWITCH_STATUS_SUCCESS;
}
Object ^objResult;
try{
objResult = FreeSwitchManaged::executeMethod->Invoke(nullptr, gcnew array<Object^>{gcnew String(cmd),gcnew IntPtr(stream), gcnew IntPtr(stream->param_event)});
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Execute completed successfully.\n");
}
catch(Exception ^ex) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Exception trying to execute mono %s %s.\n", cmd, ex->ToString());
return SWITCH_STATUS_FALSE;
}
if (!*reinterpret_cast<bool^>(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(dotnet_app_function)
{
if (switch_strlen_zero(data)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No args specified!\n");
}
Object ^objResult;
try{
objResult = FreeSwitchManaged::runMethod->Invoke(nullptr, gcnew array<Object^>{gcnew String(data),gcnew IntPtr(session)});
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "RunMethod completed successfully.\n");
}
catch(Exception ^ex) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Exception trying to execute application mono %s %s.\n", data, ex->ToString());
return;
}
if (!*reinterpret_cast<bool^>(objResult)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Application run failed for %s (unknown module?).\n", data);
}
}
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_dotnet_shutdown)
{
Object ^objResult;
try{
objResult = FreeSwitchManaged::unloadMethod->Invoke(nullptr, nullptr);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "UnloadMethod completed successfully.\n");
}
catch(Exception^) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Exception occurred in Loader::Unload.\n");
return SWITCH_STATUS_FALSE;;
}
return SWITCH_STATUS_SUCCESS;
}
SWITCH_END_EXTERN_C

View File

@ -0,0 +1,727 @@
; file generated by create-windef.pl
LIBRARY mono.dll
EXPORTS
MonoFixupCorEE
mono_add_internal_call
mono_alloc_special_static_data
mono_array_class_get
mono_array_clone
mono_array_element_size
mono_array_new
mono_array_new_full
mono_array_new_specific
mono_assemblies_cleanup
mono_assemblies_init
mono_assembly_close
mono_assembly_fill_assembly_name
mono_assembly_foreach
mono_assembly_get_assemblyref
mono_assembly_get_image
mono_assembly_get_main
mono_assembly_get_object
mono_assembly_getrootdir
mono_assembly_invoke_load_hook
mono_assembly_invoke_search_hook
mono_assembly_load
mono_assembly_load_from
mono_assembly_load_from_full
mono_assembly_load_full
mono_assembly_load_module
mono_assembly_load_reference
mono_assembly_load_references
mono_assembly_load_with_partial_name
mono_assembly_loaded
mono_assembly_loaded_full
mono_assembly_names_equal
mono_assembly_open
mono_assembly_open_full
mono_assembly_set_main
mono_assembly_setrootdir
mono_bitset_alloc_size
mono_bitset_clear
mono_bitset_clear_all
mono_bitset_clone
mono_bitset_copyto
mono_bitset_count
mono_bitset_equal
mono_bitset_find_first
mono_bitset_find_first_unset
mono_bitset_find_last
mono_bitset_find_start
mono_bitset_foreach
mono_bitset_free
mono_bitset_intersection
mono_bitset_intersection_2
mono_bitset_invert
mono_bitset_mem_new
mono_bitset_new
mono_bitset_set
mono_bitset_set_all
mono_bitset_size
mono_bitset_sub
mono_bitset_test
mono_bitset_test_bulk
mono_bitset_union
mono_bounded_array_class_get
mono_burg_emit
mono_burg_init
mono_burg_kids
mono_burg_label
mono_burg_rule
mono_check_corlib_version
mono_class_array_element_size
mono_class_data_size
mono_class_describe_statics
mono_class_enum_basetype
mono_class_from_generic_parameter
mono_class_from_mono_type
mono_class_from_name
mono_class_from_name_case
mono_class_from_typeref
mono_class_get
mono_class_get_byref_type
mono_class_get_element_class
mono_class_get_event_token
mono_class_get_events
mono_class_get_field
mono_class_get_field_from_name
mono_class_get_field_token
mono_class_get_fields
mono_class_get_flags
mono_class_get_full
mono_class_get_image
mono_class_get_interfaces
mono_class_get_method_from_name
mono_class_get_method_from_name_flags
mono_class_get_methods
mono_class_get_name
mono_class_get_namespace
mono_class_get_nested_types
mono_class_get_nesting_type
mono_class_get_parent
mono_class_get_properties
mono_class_get_property_from_name
mono_class_get_property_token
mono_class_get_rank
mono_class_get_type
mono_class_get_type_token
mono_class_inflate_generic_method
mono_class_inflate_generic_method_full
mono_class_inflate_generic_type
mono_class_init
mono_class_instance_size
mono_class_is_assignable_from
mono_class_is_enum
mono_class_is_subclass_of
mono_class_is_valuetype
mono_class_min_align
mono_class_name_from_token
mono_class_num_events
mono_class_num_fields
mono_class_num_methods
mono_class_num_properties
mono_class_value_size
mono_class_vtable
mono_cli_rva_image_map
mono_code_manager_commit
mono_code_manager_destroy
mono_code_manager_foreach
mono_code_manager_invalidate
mono_code_manager_new
mono_code_manager_new_dynamic
mono_code_manager_reserve
mono_compile_method
mono_config_for_assembly
mono_config_parse
mono_config_parse_memory
mono_config_string_for_assembly_file
mono_context_get
mono_context_init
mono_context_set
mono_counters_dump
mono_counters_enable
mono_counters_register
mono_custom_attrs_construct
mono_custom_attrs_free
mono_custom_attrs_from_assembly
mono_custom_attrs_from_class
mono_custom_attrs_from_event
mono_custom_attrs_from_field
mono_custom_attrs_from_index
mono_custom_attrs_from_method
mono_custom_attrs_from_param
mono_custom_attrs_from_property
mono_custom_attrs_get_attr
mono_custom_attrs_has_attr
mono_debug_add_method
mono_debug_cleanup
mono_debug_close_mono_symbol_file
mono_debug_find_method
mono_debug_free_source_location
mono_debug_init
mono_debug_lookup_method
mono_debug_lookup_source_location
mono_debug_open_mono_symbols
mono_debug_print_stack_frame
mono_debug_print_vars
mono_debug_symfile_lookup_location
mono_debug_symfile_lookup_method
mono_debug_using_mono_debugger
mono_debugger_breakpoint_callback
mono_debugger_check_runtime_version
mono_debugger_cleanup
mono_debugger_event
mono_debugger_handle_exception
mono_debugger_initialize
mono_debugger_insert_breakpoint
mono_debugger_insert_breakpoint_full
mono_debugger_lock
mono_debugger_method_has_breakpoint
mono_debugger_remove_breakpoint
mono_debugger_run_finally
mono_debugger_runtime_invoke
mono_debugger_throw_exception
mono_debugger_unhandled_exception
mono_debugger_unlock
mono_declsec_flags_from_assembly
mono_declsec_flags_from_class
mono_declsec_flags_from_method
mono_declsec_get_assembly_action
mono_declsec_get_class_action
mono_declsec_get_demands
mono_declsec_get_inheritdemands_class
mono_declsec_get_inheritdemands_method
mono_declsec_get_linkdemands
mono_declsec_get_method_action
mono_digest_get_public_token
mono_disasm_code
mono_disasm_code_one
mono_dllmap_insert
mono_domain_add_class_static_data
mono_domain_assembly_open
mono_domain_create
mono_domain_finalize
mono_domain_foreach
mono_domain_free
mono_domain_get
mono_domain_get_by_id
mono_domain_get_id
mono_domain_has_type_resolve
mono_domain_is_unloading
mono_domain_owns_vtable_slot
mono_domain_set
mono_domain_set_internal
mono_domain_try_type_resolve
mono_environment_exitcode_get
mono_environment_exitcode_set
mono_escape_uri_string
mono_event_get_add_method
mono_event_get_flags
mono_event_get_name
mono_event_get_object
mono_event_get_parent
mono_event_get_raise_method
mono_event_get_remove_method
mono_exception_from_name
mono_exception_from_name_domain
mono_exception_from_name_msg
mono_exception_from_name_two_strings
mono_exception_from_token
mono_field_from_token
mono_field_get_data
mono_field_get_flags
mono_field_get_name
mono_field_get_object
mono_field_get_parent
mono_field_get_type
mono_field_get_value
mono_field_get_value_object
mono_field_set_value
mono_field_static_get_value
mono_field_static_set_value
mono_file_map
mono_file_unmap
mono_free_method
mono_free_verify_list
mono_g_hash_table_destroy
mono_g_hash_table_foreach
mono_g_hash_table_foreach_remove
mono_g_hash_table_foreach_steal
mono_g_hash_table_insert
mono_g_hash_table_lookup
mono_g_hash_table_lookup_extended
mono_g_hash_table_new
mono_g_hash_table_new_full
mono_g_hash_table_new_type
mono_g_hash_table_remap
mono_g_hash_table_remove
mono_g_hash_table_replace
mono_g_hash_table_size
mono_g_hash_table_steal
mono_gc_collect
mono_gc_collection_count
mono_gc_enable_events
mono_gc_get_generation
mono_gc_get_heap_size
mono_gc_get_used_size
mono_gc_is_finalizer_thread
mono_gc_max_generation
mono_gc_out_of_memory
mono_gc_wbarrier_arrayref_copy
mono_gc_wbarrier_generic_store
mono_gc_wbarrier_object
mono_gc_wbarrier_set_arrayref
mono_gc_wbarrier_set_field
mono_gc_wbarrier_value_copy
mono_gchandle_free
mono_gchandle_get_target
mono_gchandle_new
mono_gchandle_new_weakref
mono_get_array_class
mono_get_boolean_class
mono_get_byte_class
mono_get_char_class
mono_get_config_dir
mono_get_corlib
mono_get_dbnull_object
mono_get_delegate_invoke
mono_get_double_class
mono_get_enum_class
mono_get_exception_appdomain_unloaded
mono_get_exception_argument
mono_get_exception_argument_null
mono_get_exception_argument_out_of_range
mono_get_exception_arithmetic
mono_get_exception_array_type_mismatch
mono_get_exception_bad_image_format
mono_get_exception_bad_image_format2
mono_get_exception_cannot_unload_appdomain
mono_get_exception_class
mono_get_exception_divide_by_zero
mono_get_exception_execution_engine
mono_get_exception_file_not_found
mono_get_exception_file_not_found2
mono_get_exception_index_out_of_range
mono_get_exception_invalid_cast
mono_get_exception_invalid_operation
mono_get_exception_io
mono_get_exception_missing_field
mono_get_exception_missing_method
mono_get_exception_not_implemented
mono_get_exception_not_supported
mono_get_exception_null_reference
mono_get_exception_overflow
mono_get_exception_reflection_type_load
mono_get_exception_security
mono_get_exception_serialization
mono_get_exception_stack_overflow
mono_get_exception_synchronization_lock
mono_get_exception_thread_abort
mono_get_exception_thread_interrupted
mono_get_exception_thread_state
mono_get_exception_type_initialization
mono_get_exception_type_load
mono_get_inflated_method
mono_get_int16_class
mono_get_int32_class
mono_get_int64_class
mono_get_intptr_class
mono_get_machine_config
mono_get_method
mono_get_method_constrained
mono_get_method_full
mono_get_object_class
mono_get_root_domain
mono_get_sbyte_class
mono_get_single_class
mono_get_special_static_data
mono_get_string_class
mono_get_thread_class
mono_get_uint16_class
mono_get_uint32_class
mono_get_uint64_class
mono_get_uintptr_class
mono_get_void_class
mono_guid_to_string
mono_image_add_to_name_cache
mono_image_addref
mono_image_close
mono_image_ensure_section
mono_image_ensure_section_idx
mono_image_get_assembly
mono_image_get_entry_point
mono_image_get_filename
mono_image_get_guid
mono_image_get_name
mono_image_get_public_key
mono_image_get_resource
mono_image_get_strong_name
mono_image_get_table_info
mono_image_get_table_rows
mono_image_has_authenticode_entry
mono_image_init
mono_image_init_name_cache
mono_image_is_dynamic
mono_image_load_file_for_image
mono_image_loaded
mono_image_loaded_by_guid
mono_image_loaded_by_guid_full
mono_image_loaded_full
mono_image_lookup_resource
mono_image_open
mono_image_open_from_data
mono_image_open_from_data_full
mono_image_open_full
mono_image_rva_map
mono_image_strerror
mono_image_strong_name_position
mono_image_verify_tables
mono_images_cleanup
mono_images_init
mono_init
mono_init_from_assembly
mono_init_version
mono_inst_name
mono_install_assembly_load_hook
mono_install_assembly_postload_refonly_search_hook
mono_install_assembly_postload_search_hook
mono_install_assembly_preload_hook
mono_install_assembly_refonly_preload_hook
mono_install_assembly_refonly_search_hook
mono_install_assembly_search_hook
mono_install_runtime_cleanup
mono_jit_cleanup
mono_jit_exec
mono_jit_info_get_code_size
mono_jit_info_get_code_start
mono_jit_info_get_method
mono_jit_info_table_find
mono_jit_init
mono_jit_init_version
mono_jit_thread_attach
mono_ldstr
mono_ldtoken
mono_load_remote_field
mono_load_remote_field_new
mono_locks_dump
mono_lookup_internal_call
mono_lookup_pinvoke_call
mono_main
mono_marshal_string_to_utf16
mono_mb_free
mono_md5_final
mono_md5_get_digest
mono_md5_get_digest_from_file
mono_md5_init
mono_md5_update
mono_mempool_alloc
mono_mempool_alloc0
mono_mempool_contains_addr
mono_mempool_destroy
mono_mempool_empty
mono_mempool_get_allocated
mono_mempool_invalidate
mono_mempool_new
mono_mempool_stats
mono_mempool_strdup
mono_metadata_blob_heap
mono_metadata_cleanup
mono_metadata_compute_size
mono_metadata_custom_attrs_from_index
mono_metadata_declsec_from_index
mono_metadata_decode_blob_size
mono_metadata_decode_row
mono_metadata_decode_row_col
mono_metadata_decode_signed_value
mono_metadata_decode_table_row
mono_metadata_decode_table_row_col
mono_metadata_decode_value
mono_metadata_encode_value
mono_metadata_events_from_typedef
mono_metadata_field_info
mono_metadata_free_array
mono_metadata_free_marshal_spec
mono_metadata_free_method_signature
mono_metadata_free_mh
mono_metadata_free_type
mono_metadata_generic_class_is_valuetype
mono_metadata_get_constant_index
mono_metadata_get_generic_param_row
mono_metadata_get_marshal_info
mono_metadata_get_param_attrs
mono_metadata_guid_heap
mono_metadata_implmap_from_method
mono_metadata_init
mono_metadata_interfaces_from_typedef
mono_metadata_load_generic_param_constraints
mono_metadata_load_generic_params
mono_metadata_locate
mono_metadata_locate_token
mono_metadata_methods_from_event
mono_metadata_methods_from_property
mono_metadata_nested_in_typedef
mono_metadata_nesting_typedef
mono_metadata_packing_from_typedef
mono_metadata_parse_array
mono_metadata_parse_custom_mod
mono_metadata_parse_field_type
mono_metadata_parse_marshal_spec
mono_metadata_parse_method_signature
mono_metadata_parse_method_signature_full
mono_metadata_parse_mh
mono_metadata_parse_mh_full
mono_metadata_parse_param
mono_metadata_parse_signature
mono_metadata_parse_type
mono_metadata_parse_type_full
mono_metadata_parse_typedef_or_ref
mono_metadata_properties_from_typedef
mono_metadata_signature_alloc
mono_metadata_signature_dup
mono_metadata_signature_equal
mono_metadata_string_heap
mono_metadata_token_from_dor
mono_metadata_translate_token_index
mono_metadata_type_equal
mono_metadata_type_hash
mono_metadata_typedef_from_field
mono_metadata_typedef_from_method
mono_metadata_user_string
mono_method_body_get_object
mono_method_desc_free
mono_method_desc_from_method
mono_method_desc_full_match
mono_method_desc_match
mono_method_desc_new
mono_method_desc_search_in_class
mono_method_desc_search_in_image
mono_method_full_name
mono_method_get_class
mono_method_get_flags
mono_method_get_header
mono_method_get_index
mono_method_get_last_managed
mono_method_get_marshal_info
mono_method_get_name
mono_method_get_object
mono_method_get_param_names
mono_method_get_param_token
mono_method_get_signature
mono_method_get_signature_full
mono_method_get_token
mono_method_has_marshal_info
mono_method_header_get_clauses
mono_method_header_get_code
mono_method_header_get_locals
mono_method_header_get_num_clauses
mono_method_signature
mono_method_verify
mono_mlist_alloc
mono_mlist_append
mono_mlist_get_data
mono_mlist_last
mono_mlist_length
mono_mlist_next
mono_mlist_prepend
mono_mlist_remove_item
mono_mlist_set_data
mono_module_file_get_object
mono_module_get_object
mono_monitor_enter
mono_monitor_exit
mono_monitor_try_enter
mono_mprotect
mono_object_castclass_mbyref
mono_object_clone
mono_object_describe
mono_object_describe_fields
mono_object_get_class
mono_object_get_domain
mono_object_get_size
mono_object_get_virtual_method
mono_object_hash
mono_object_is_alive
mono_object_isinst
mono_object_isinst_mbyref
mono_object_new
mono_object_new_alloc_specific
mono_object_new_fast
mono_object_new_from_token
mono_object_new_specific
mono_object_unbox
mono_opcode_name
mono_opcode_value
mono_pagesize
mono_param_get_objects
mono_parse_default_optimizations
mono_path_canonicalize
mono_path_resolve_symlinks
mono_pe_file_open
mono_pmip
mono_poll
mono_print_method_from_ip
mono_print_thread_dump
mono_print_unhandled_exception
mono_profiler_coverage_get
mono_profiler_get_events
mono_profiler_install
mono_profiler_install_allocation
mono_profiler_install_appdomain
mono_profiler_install_assembly
mono_profiler_install_class
mono_profiler_install_coverage_filter
mono_profiler_install_enter_leave
mono_profiler_install_gc
mono_profiler_install_jit_compile
mono_profiler_install_jit_end
mono_profiler_install_module
mono_profiler_install_statistical
mono_profiler_install_thread
mono_profiler_install_transition
mono_profiler_load
mono_profiler_set_events
mono_property_get_flags
mono_property_get_get_method
mono_property_get_name
mono_property_get_object
mono_property_get_parent
mono_property_get_set_method
mono_property_get_value
mono_property_set_value
mono_ptr_class_get
mono_raise_exception
mono_reflection_get_custom_attrs
mono_reflection_get_custom_attrs_blob
mono_reflection_get_custom_attrs_by_type
mono_reflection_get_custom_attrs_data
mono_reflection_get_custom_attrs_info
mono_reflection_get_token
mono_reflection_get_type
mono_reflection_parse_type
mono_reflection_type_from_name
mono_register_bundled_assemblies
mono_register_config_for_assembly
mono_register_machine_config
mono_remote_class
mono_runtime_class_init
mono_runtime_cleanup
mono_runtime_delegate_invoke
mono_runtime_exec_main
mono_runtime_exec_managed_code
mono_runtime_get_main_args
mono_runtime_init
mono_runtime_invoke
mono_runtime_invoke_array
mono_runtime_is_shutting_down
mono_runtime_object_init
mono_runtime_quit
mono_runtime_run_main
mono_runtime_set_shutting_down
mono_set_config_dir
mono_set_defaults
mono_set_dirs
mono_set_rootdir
mono_sha1_final
mono_sha1_get_digest
mono_sha1_get_digest_from_file
mono_sha1_init
mono_sha1_update
mono_signature_explicit_this
mono_signature_get_call_conv
mono_signature_get_desc
mono_signature_get_param_count
mono_signature_get_params
mono_signature_get_return_type
mono_signature_hash
mono_signature_is_instance
mono_signature_vararg_start
mono_signbit_double
mono_signbit_float
mono_stack_walk
mono_stack_walk_no_il
mono_store_remote_field
mono_store_remote_field_new
mono_string_equal
mono_string_from_utf16
mono_string_hash
mono_string_intern
mono_string_is_interned
mono_string_new
mono_string_new_len
mono_string_new_size
mono_string_new_utf16
mono_string_new_wrapper
mono_string_to_utf16
mono_string_to_utf8
mono_stringify_assembly_name
mono_table_info_get_rows
mono_thread_abort_all_other_threads
mono_thread_attach
mono_thread_cleanup
mono_thread_create
mono_thread_current
mono_thread_detach
mono_thread_exit
mono_thread_force_interruption_checkpoint
mono_thread_get_abort_signal
mono_thread_get_main
mono_thread_has_appdomain_ref
mono_thread_init
mono_thread_interruption_checkpoint
mono_thread_interruption_request_flag
mono_thread_interruption_requested
mono_thread_manage
mono_thread_new_init
mono_thread_pop_appdomain_ref
mono_thread_push_appdomain_ref
mono_thread_request_interruption
mono_thread_set_main
mono_thread_stop
mono_thread_suspend_all_other_threads
mono_threads_abort_appdomain_threads
mono_threads_clear_cached_culture
mono_threads_get_default_stacksize
mono_threads_install_cleanup
mono_threads_request_thread_dump
mono_threads_set_default_stacksize
mono_trace
mono_trace_cleanup
mono_trace_is_traced
mono_trace_pop
mono_trace_push
mono_trace_set_level
mono_trace_set_level_string
mono_trace_set_mask
mono_trace_set_mask_string
mono_tracev
mono_type_create_from_typespec
mono_type_full_name
mono_type_generic_inst_is_valuetype
mono_type_get_array_type
mono_type_get_class
mono_type_get_desc
mono_type_get_modifiers
mono_type_get_name
mono_type_get_object
mono_type_get_ptr_type
mono_type_get_signature
mono_type_get_type
mono_type_get_underlying_type
mono_type_is_byref
mono_type_size
mono_type_stack_size
mono_type_to_unmanaged
mono_unhandled_exception
mono_unicode_from_external
mono_unicode_to_external
mono_upgrade_remote_class_wrapper
mono_utf8_from_external
mono_valloc
mono_value_box
mono_value_copy
mono_value_copy_array
mono_value_describe_fields
mono_verify_corlib
mono_vfree
mono_vtable_get_static_field_data
mono_walk_stack

View File

@ -0,0 +1,45 @@
// MANUALLY GENERATED
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned long uint32_t;
typedef unsigned long long uint64_t;
typedef signed char int8_t;
typedef short int16_t;
typedef int int32_t;
typedef long long int64_t;
typedef unsigned long in_addr_t;
// TODO: C# chars are 2 bytes, C is one. The marshalling copies two bytes (Value+whatever) into the C# char
// causing corruption. We should figure this out. It's as simple as ((char)(byte)<thebyte>) whever
// we define char as byte.
// TODO: Possible? It'd be nice to do the whole char*->IntPtr->Marshal/Free thing here instead of swigStringFix
#define SWITCH_DECLARE(type) type
#define SWITCH_DECLARE_NONSTD(type) type
#define SWITCH_MOD_DECLARE(type) type
#define SWITCH_DECLARE_DATA
#define SWITCH_MOD_DECLARE_DATA
#define SWITCH_THREAD_FUNC
#define SWITCH_DECLARE_CONSTRUCTOR SWITCH_DECLARE_DATA
#define _In_
#define _In_z_
#define _In_opt_z_
#define _In_opt_
#define _Printf_format_string_
#define _Ret_opt_z_
#define _Ret_z_
#define _Out_opt_
#define _Out_
#define _Check_return_
#define _Inout_
#define _Inout_opt_
#define _In_bytecount_(x)
#define _Out_opt_bytecapcount_(x)
#define _Out_bytecapcount_(x)
#define _Ret_
#define _Post_z_
#define _Out_cap_(x)
#define _Out_z_cap_(x)
#define _Out_ptrdiff_cap_(x)
#define _Out_opt_ptrdiff_cap_(x)

View File

@ -0,0 +1,49 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_mono
* Copyright (C) 2008, Michael Giagnocavo <mgg@packetrino.com>
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_mono
*
* The Initial Developer of the Original Code is
* Michael Giagnocavo <mgg@packetrino.com>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Michael Giagnocavo <mgg@packetrino.com>
*
* AppFunction.cs -- Base class for API functions
*
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FreeSWITCH
{
public abstract class ApiFunction
{
protected static bool Load() { return true; }
protected static void Unload() { }
public abstract void ExecuteBackground(string args);
public abstract void Execute(FreeSWITCH.Native.Stream stream, FreeSWITCH.Native.Event evt, string args);
}
}

View File

@ -0,0 +1,108 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_mono
* Copyright (C) 2008, Michael Giagnocavo <mgg@packetrino.com>
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_mono
*
* The Initial Developer of the Original Code is
* Michael Giagnocavo <mgg@packetrino.com>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Michael Giagnocavo <mgg@packetrino.com>
*
* AppFunction.cs -- Base class for applications
*
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace FreeSWITCH
{
public abstract class AppFunction
{
protected static bool Load() { return true; }
protected static void Unload() { }
protected Native.MonoSession Session { get; private set; }
protected string Arguments { get; private set; }
public bool IsAvailable
{
get
{
if (this.Session == null) return false;
return this.Session.Ready();
}
}
/// <summary>Determines if the thread used for Run will have Abort called on it on hangup. Defaults to false.</summary>
protected virtual bool AbortOnHangup { get { return false; } }
bool abortable = false;
readonly object abortLock = new object();
Thread runThread;
internal void AbortRun()
{
if (!AbortOnHangup) return;
if (runThread == Thread.CurrentThread) {
Log.WriteLine(LogLevel.Warning, "Thread will not be aborted because Hangup was called from the Run thread.");
return;
}
lock (abortLock) {
if (abortable) {
Log.WriteLine(LogLevel.Critical, "Aborting run thread.");
runThread.Abort();
}
}
}
protected Guid Uuid { get; private set; }
internal void RunInternal(FreeSWITCH.Native.MonoSession session, string args)
{
this.Session = session;
this.Arguments = args;
Session.AppToAbort = this;
try { this.Uuid = new Guid(Session.GetUuid()); }
catch { }
try {
runThread = Thread.CurrentThread;
lock (abortLock) abortable = true;
Run();
}
catch (ThreadAbortException) {
Log.WriteLine(LogLevel.Critical, "Run thread aborted.");
Thread.ResetAbort();
}
finally {
lock (abortLock) { abortable = false; }
if (runThread.ThreadState == ThreadState.AbortRequested) {
try { Thread.ResetAbort(); }
catch { }
}
}
}
protected abstract void Run();
}
}

View File

@ -0,0 +1,105 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_mono
* Copyright (C) 2008, Michael Giagnocavo <mgg@packetrino.com>
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_mono
*
* The Initial Developer of the Original Code is
* Michael Giagnocavo <mgg@packetrino.com>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Michael Giagnocavo <mgg@packetrino.com>
*
* Demo.cs -- mod_mono demo classes
*
*/
#if DEBUG
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FreeSWITCH.Demo
{
public class AppDemo : AppFunction
{
new protected static bool Load()
{
Log.WriteLine(LogLevel.Info, "Inside AppDemo::Load.");
return true;
}
new protected static void Unload()
{
Log.WriteLine(LogLevel.Info, "Inside AppDemo::Unload.");
}
protected override void Run()
{
Session.Answer();
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}. 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");
}
void hangupHook()
{
Log.WriteLine(LogLevel.Debug, "AppDemo hanging up, UUID: {0}.", this.Uuid);
}
protected override bool AbortOnHangup { get { return true; } }
}
public class ApiDemo : ApiFunction
{
new protected static bool Load()
{
Log.WriteLine(LogLevel.Debug, "Inside ApiDemo::Load.");
return true;
}
new protected static void Unload()
{
Log.WriteLine(LogLevel.Debug, "Inside ApiDemo::Unload.");
}
public override void ExecuteBackground(string args)
{
Log.WriteLine(LogLevel.Debug, "ApiDemo on a background thread #({0}), with args '{1}'.",
System.Threading.Thread.CurrentThread.ManagedThreadId,
args);
}
public override void Execute(Native.Stream stream, Native.Event evt, string args)
{
stream.Write(string.Format("ApiDemo executed with args '{0}' and event type {1}.",
args, evt == null ? "<none>" : evt.GetEventType()));
}
}
}
#endif

View File

@ -0,0 +1,47 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_mono
* Copyright (C) 2008, Michael Giagnocavo <mgg@packetrino.com>
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_mono
*
* The Initial Developer of the Original Code is
* Michael Giagnocavo <mgg@packetrino.com>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Michael Giagnocavo <mgg@packetrino.com>
*
* Extensions.cs -- Helper extensions
*
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace System.Linq
{
internal static class EnumerableExtensions
{
public static void ForEach<T>(this IEnumerable<T> source, Action<T> f)
{
foreach (var item in source) {
f(item);
}
}
}
}

View File

@ -0,0 +1,260 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_mono
* Copyright (C) 2008, Michael Giagnocavo <mgg@packetrino.com>
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_mono
*
* The Initial Developer of the Original Code is
* Michael Giagnocavo <mgg@packetrino.com>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Michael Giagnocavo <mgg@packetrino.com>
* Jeff Lenk <jlenk@frontiernet.net> - Modified class to support Dotnet
*
* Loader.cs -- mod_mono managed loader
*
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Linq;
using System.Reflection;
namespace FreeSWITCH
{
internal static class Loader
{
// Stores a list of the loaded function types so we can instantiate them as needed
static readonly Dictionary<string, Type> functions = new Dictionary<string, Type>(StringComparer.InvariantCultureIgnoreCase);
// Only class name. Last in wins.
static readonly Dictionary<string, Type> shortFunctions = new Dictionary<string, Type>(StringComparer.InvariantCultureIgnoreCase);
#region Load/Unload
public static bool Load()
{
string managedDir = Path.Combine(Native.freeswitch.SWITCH_GLOBAL_dirs.mod_dir, "dotnet");
Log.WriteLine(LogLevel.Debug, "mod_mono_managed loader is starting with directory '{0}'.", managedDir);
if (!Directory.Exists(managedDir)) {
Log.WriteLine(LogLevel.Error, "Managed directory not found: {0}", managedDir);
return false;
}
// This is a simple one-time loader to get things in memory
// Some day we should allow reloading of modules or something
loadAssemblies(managedDir)
.SelectMany(a => a.GetExportedTypes())
.Where(t => !t.IsAbstract)
.Where(t => t.IsSubclassOf(typeof(AppFunction)) || t.IsSubclassOf(typeof(ApiFunction)))
.ToList()
.loadFunctions();
return true;
}
// Be rather lenient in finding the Load and Unload methods
static readonly BindingFlags methodBindingFlags =
BindingFlags.Static | // Required
BindingFlags.Public | BindingFlags.NonPublic | // Implementors might decide to make the load method private
BindingFlags.IgnoreCase | // Some case insensitive languages?
BindingFlags.FlattenHierarchy; // Allow inherited methods for hierarchies
static void loadFunctions(this List<Type> allTypes)
{
foreach (var t in allTypes) {
try {
if (functions.ContainsKey(t.FullName)) {
Log.WriteLine(LogLevel.Error, "Duplicate function {0}. Skipping.", t.FullName);
continue;
}
var loadMethod = t.GetMethod("Load", methodBindingFlags, null, Type.EmptyTypes, null);
var shouldLoad = Convert.ToBoolean(loadMethod.Invoke(null, null)); // We don't require the Load method to return a bool exactly
if (shouldLoad) {
Log.WriteLine(LogLevel.Notice, "Function {0} loaded.", t.FullName);
functions.Add(t.FullName, t);
shortFunctions[t.Name] = t;
}
else {
Log.WriteLine(LogLevel.Notice, "Function {0} requested not to be loaded.", t.FullName);
}
}
catch (Exception ex) {
logException("Load", t.FullName, ex);
}
}
}
static List<Assembly> loadAssemblies(string managedDir)
{
return Directory.GetFiles(managedDir, "*.dll", SearchOption.AllDirectories)
.Select(f => Path.Combine(managedDir, f))
.Select(f => {
try {
return System.Reflection.Assembly.LoadFile(f);
}
catch (Exception ex) {
Log.WriteLine(LogLevel.Notice, "Assembly.LoadFile failed; skipping {0} ({1})", f, ex.Message);
return null;
}
})
.Where(a => a != null)
.Concat(new[] { System.Reflection.Assembly.GetExecutingAssembly() }) // Add in our own to load Demo or built-in things if added
.ToList();
}
public static void Unload()
{
Log.WriteLine(LogLevel.Debug, "mod_mono_managed Loader is unloading.");
foreach (var t in functions.Values) {
try {
var unloadMethod = t.GetMethod("Unload", methodBindingFlags, null, Type.EmptyTypes, null);
unloadMethod.Invoke(null, null);
}
catch (Exception ex) {
logException("Unload", t.FullName, ex);
}
}
}
#endregion
#region Execution
static Type getFunctionType<TFunction>(string fullName)
{
Type t;
if (!functions.TryGetValue(fullName, out t) || !t.IsSubclassOf(typeof(TFunction))) {
if (!shortFunctions.TryGetValue(fullName, out t) || !t.IsSubclassOf(typeof(TFunction))) {
Log.WriteLine(LogLevel.Error, "Could not find function {0}.", fullName);
return null;
}
}
return t;
}
static readonly char[] spaceArray = new[] { ' ' };
/// <summary>Returns a string couple containing the module name and arguments</summary>
static string[] parseCommand(string command)
{
if (string.IsNullOrEmpty(command)) {
Log.WriteLine(LogLevel.Error, "No arguments supplied.");
return null;
}
var args = command.Split(spaceArray, 2, StringSplitOptions.RemoveEmptyEntries);
if (args.Length == 0 || string.IsNullOrEmpty(args[0]) || string.IsNullOrEmpty(args[0].Trim())) {
Log.WriteLine(LogLevel.Error, "Module name not supplied.");
return null;
}
if (args.Length == 1) {
return new[] { args[0], "" };
}
else {
return args;
}
}
public static bool ExecuteBackground(string command)
{
var parsed = parseCommand(command);
if (parsed == null) return false;
var fullName = parsed[0];
var args = parsed[1];
var fType = getFunctionType<ApiFunction>(fullName);
if (fType == null) return false;
new System.Threading.Thread(() => {
try {
var f = (ApiFunction)Activator.CreateInstance(fType);
f.ExecuteBackground(args);
Log.WriteLine(LogLevel.Debug, "ExecuteBackground in {0} completed.", fullName);
}
catch (Exception ex) {
logException("ExecuteBackground", fullName, ex);
}
}).Start();
return true;
}
public static bool Execute(string command, IntPtr streamHandle, IntPtr eventHandle)
{
System.Diagnostics.Debug.Assert(streamHandle != IntPtr.Zero, "streamHandle is null.");
var parsed = parseCommand(command);
if (parsed == null) return false;
var fullName = parsed[0];
var args = parsed[1];
var fType = getFunctionType<ApiFunction>(fullName);
if (fType == null) return false;
using (var stream = new Native.Stream(new Native.switch_stream_handle(streamHandle, false)))
using (var evt = eventHandle == IntPtr.Zero ? null : new Native.Event(new Native.switch_event(eventHandle, false), 0)) {
try {
var f = (ApiFunction)Activator.CreateInstance(fType);
f.Execute(stream, evt, args);
return true;
}
catch (Exception ex) {
logException("Execute", fullName, ex);
return false;
}
}
}
/// <summary>Runs an application function.</summary>
public static bool Run(string command, IntPtr sessionHandle)
{
Log.WriteLine(LogLevel.Debug, "mod_mono attempting to run application '{0}'.", command);
System.Diagnostics.Debug.Assert(sessionHandle != IntPtr.Zero, "sessionHandle is null.");
var parsed = parseCommand(command);
if (parsed == null) return false;
var fullName = parsed[0];
var args = parsed[1];
var fType = getFunctionType<AppFunction>(fullName);
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);
f.RunInternal(session, args);
return true;
}
catch (Exception ex) {
logException("Run", fullName, ex);
return false;
}
}
}
static void logException(string action, string moduleName, Exception ex)
{
Log.WriteLine(LogLevel.Error, "{0} exception in {1}: {2}", action, moduleName, ex.Message);
Log.WriteLine(LogLevel.Debug, "{0} exception: {1}", moduleName, ex.ToString());
}
#endregion
}
}

View File

@ -0,0 +1,96 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_mono
* Copyright (C) 2008, Michael Giagnocavo <mgg@packetrino.com>
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_mono
*
* The Initial Developer of the Original Code is
* Michael Giagnocavo <mgg@packetrino.com>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Michael Giagnocavo <mgg@packetrino.com>
*
* Log.cs -- Log wrappers
*
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FreeSWITCH
{
public static class Log
{
public static void Write(LogLevel level, string message)
{
Native.freeswitch.console_log(level.ToLogString(), message);
}
public static void Write(LogLevel level, string format, params object[] args)
{
Native.freeswitch.console_log(level.ToLogString(), string.Format(format, args));
}
public static void WriteLine(LogLevel level, string message)
{
Native.freeswitch.console_log(level.ToLogString(), message + Environment.NewLine);
}
public static void WriteLine(LogLevel level, string format, params object[] args)
{
Native.freeswitch.console_log(level.ToLogString(), string.Format(format, args) + Environment.NewLine);
}
static string ToLogString(this LogLevel level)
{
switch (level) {
case LogLevel.Alert: return "ALERT";
case LogLevel.Critical: return "CRIT";
case LogLevel.Debug: return "DEBUG";
case LogLevel.Error: return "ERR";
case LogLevel.Info: return "INFO";
case LogLevel.Notice: return "NOTICE";
case LogLevel.Warning: return "WARNING";
default:
System.Diagnostics.Debug.Fail("Invalid LogLevel: " + level.ToString() + " (" + (int)level+ ").");
return "INFO";
}
}
}
/*switch_log.c:
tatic const char *LEVELS[] = {
"CONSOLE",
"ALERT",
"CRIT",
"ERR",
"WARNING",
"NOTICE",
"INFO",
"DEBUG",
NULL
};*/
public enum LogLevel
{
Debug,
Info,
Error,
Critical,
Alert,
Warning,
Notice,
}
}

View File

@ -0,0 +1,130 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_mono
* Copyright (C) 2008, Michael Giagnocavo <mgg@packetrino.com>
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_mono
*
* The Initial Developer of the Original Code is
* Michael Giagnocavo <mgg@packetrino.com>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Michael Giagnocavo <mgg@packetrino.com>
* Jeff Lenk <jlenk@frontiernet.net> - Modified class to support Dotnet
*
* MonoSession.cs -- MonoSession additional functions
*
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace FreeSWITCH.Native
{
public partial class MonoSession
{
public delegate void hangupDelegate();
hangupDelegate hangupDel;
System.Runtime.InteropServices.GCHandle gcHangup;
IntPtr hangupFuncPtr;
public delegate string dtmfDelegate(IntPtr input, Native.switch_input_type_t inputType);
dtmfDelegate dtmfDel;
System.Runtime.InteropServices.GCHandle gcDtmf;
IntPtr dtmfFuncPtr;
[DllImport("mod_dotnet", EntryPoint = "InitDotnetSession")]
public static extern void InitDotnetSession(IntPtr sessionPtr, IntPtr dtmfDelegate, IntPtr hangupDelegate);
/// <summary>Initializes the native MonoSession. Must be called after Originate.</summary>
public void Initialize()
{
hangupDel = new hangupDelegate(hangupCallback);
//Calling the Alloc function to make sure the managed object is not garbage collected
gcHangup = GCHandle.Alloc(hangupDel);
hangupFuncPtr = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate(hangupDel);
dtmfDel = new dtmfDelegate(inputCallback);
//Calling the Alloc function to make sure the managed object is not garbage collected
gcDtmf = GCHandle.Alloc(dtmfDel);
dtmfFuncPtr = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate(dtmfDel);
InitDotnetSession(MonoSession.getCPtr(this).Handle, dtmfFuncPtr, hangupFuncPtr);
}
/// <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);
}
}
}
}

View File

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("mod_mono_managed")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("mod_mono_managed")]
[assembly: AssemblyCopyright("Copyright © 2008")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("b66ea632-ec95-4c9e-9cf7-7c0805a50526")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.21022</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{C95B7C7D-77F3-4DF7-9FB6-A44CBEF47B35}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>mod_dotnet_managed</RootNamespace>
<AssemblyName>mod_dotnet_managed</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<StartupObject>
</StartupObject>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\..\..\Debug\mod\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\..\..\Release\mod\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data.DataSetExtensions">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Compile Include="MonoSession.cs" />
<Compile Include="Loader.cs" />
<Compile Include="Extensions.cs" />
<Compile Include="Log.cs" />
</ItemGroup>
<ItemGroup>
<Compile Include="ApiFunction.cs" />
<Compile Include="AppFunction.cs" />
<Compile Include="Demo.cs" />
<Compile Include="swig.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

File diff suppressed because it is too large Load Diff