freeswitch/src/dotnet/Module.cs

216 lines
9.0 KiB
C#

/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2006, James Martelletti <james@nerdc0re.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
*
* The Initial Developer of the Original Code is
* James Martelletti <james@nerdc0re.com>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* James Martelletti <james@nerdc0re.com>
*
*
* Module.cs --
*
*/
using System;
using System.Collections;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using FreeSwitch.Types;
using FreeSwitch.Modules;
using FreeSwitch.Marshaling.Types;
namespace FreeSwitch
{
/// <summary>
/// Base class for all Freeswitch.NET modules
/// </summary>
/// <example>
/// public class Example : Module
/// {
/// public Example()
/// {
/// AddApiInterface(new ExampleApi());
/// AddApplicationInterface(new ExampleApplication());
///
/// Register();
/// }
/// }
/// </example>
public class Module
{
private LoadableModuleInterfaceMarshal module_interface = new LoadableModuleInterfaceMarshal();
private LoadableModuleMarshal module = new LoadableModuleMarshal();
private ArrayList applicationInterfaces = new ArrayList();
private ArrayList apiInterfaces = new ArrayList();
private ModuleLoad load;
private string name;
private string filename = Assembly.GetCallingAssembly().GetName().Name;
/// <summary>
/// Module constructor
/// </summary>
public Module()
{
Console.WriteLine("*** Creating new module object");
load = new ModuleLoad(Load);
}
/// <summary>
/// Implementation of ModuleLoad Delegate
/// </summary>
/// <param name="module"></param>
/// <param name="name"></param>
/// <returns></returns>
public Status Load(ref IntPtr module, string name)
{
/* Allocate some unmanaged mem for the ModuleInterface */
module = Marshal.AllocHGlobal(Marshal.SizeOf(module_interface));
/* Set the module_name field of the LoadableModuleInterface */
module_interface.module_name = Marshal.StringToHGlobalAnsi(filename);
if (apiInterfaces.Count > 0)
{
/* Grab the first ApiInterface in our array and add a pointer to this in our ModuleInterface*/
Api apiIndex = (Api)apiInterfaces[0];
module_interface.api_interface = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(ApiInterfaceMarshal)));
Marshal.StructureToPtr(apiIndex.handle.Wrapper, module_interface.api_interface, true);
}
if (applicationInterfaces.Count > 0)
{
/* For each Application interface */
Application applicationIndex = (Application)applicationInterfaces[0];
module_interface.application_interface = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(ApplicationInterfaceMarshal)));
Marshal.StructureToPtr(applicationIndex.handle.Wrapper, module_interface.application_interface, true);
}
/* Finally, marshal the moduleinterface class and return */
Marshal.StructureToPtr(module_interface, module, true);
return Status.Success;
}
/// <summary>
/// AddApiInterface
/// </summary>
/// <param name="apiInterface"></param>
public void AddApiInterface(Api apiInterface)
{
/* Create a new ApiInterface type and allocate unmanaged mem */
ApiInterfaceMarshal apiInterfaceMarshal = new ApiInterfaceMarshal();
IntPtr apiInterfacePtr = Marshal.AllocHGlobal(Marshal.SizeOf(apiInterfaceMarshal));
/* Allocate umanaged mem to to interface fields so GC doesn't disturb them */
apiInterfaceMarshal.interface_name = Marshal.StringToHGlobalAnsi(apiInterface.Name);
apiInterfaceMarshal.desc = Marshal.StringToHGlobalAnsi(apiInterface.Description);
apiInterfaceMarshal.syntax = Marshal.StringToHGlobalAnsi(apiInterface.Syntax);
apiInterfaceMarshal.function = new ApiFunction(apiInterface.ApiFunction);
/* Set the handle of the managed object */
apiInterface.handle = new HandleRef(apiInterfaceMarshal, apiInterfacePtr);
Marshal.StructureToPtr(apiInterfaceMarshal, apiInterface.handle.Handle, true);
/* Check to see whether there is already an interface defined, if there is then
* we want to set the *next pointer of the last element before adding the new
* interface to the array
*/
if (apiInterfaces.Count > 0)
{
Api apiInterfaceElement = (Api)apiInterfaces[apiInterfaces.Count - 1];
ApiInterfaceMarshal apiInterfacePrev = (ApiInterfaceMarshal)apiInterfaceElement.handle.Wrapper;
apiInterfacePrev.next = apiInterface.handle.Handle;
}
/* Finally, add our new interface to the array */
apiInterfaces.Add(apiInterface);
}
/// <summary>
/// AddApplicationInterface
/// </summary>
/// <param name="applicationInterface"></param>
public void AddApplicationInterface(Application applicationInterface)
{
/* Create a new ApplicationInterface type and allocate unmanaged mem */
ApplicationInterfaceMarshal applicationInterfaceMarshal = new ApplicationInterfaceMarshal();
IntPtr applicationInterfacePtr = Marshal.AllocHGlobal(Marshal.SizeOf(applicationInterfaceMarshal));
/* Allocate umanaged mem to to interface fields so GC doesn't disturb them */
applicationInterfaceMarshal.interface_name = Marshal.StringToHGlobalAnsi(applicationInterface.Name);
applicationInterfaceMarshal.syntax = Marshal.StringToHGlobalAnsi(applicationInterface.Syntax);
applicationInterfaceMarshal.long_desc = Marshal.StringToHGlobalAnsi(applicationInterface.LongDescription);
applicationInterfaceMarshal.short_desc = Marshal.StringToHGlobalAnsi(applicationInterface.ShortDescription);
applicationInterfaceMarshal.application_function = new ApplicationFunction(applicationInterface.ApplicationFunction);
/* Set the handle of the managed object */
applicationInterface.handle = new HandleRef(applicationInterfaceMarshal, applicationInterfacePtr);
Marshal.StructureToPtr(applicationInterfaceMarshal, applicationInterface.handle.Handle, true);
/* Check to see whether there is already an interface defined, if there is then
* we want to set the *next pointer of the last element before adding the new
* interface to the array
*/
if (applicationInterfaces.Count > 0)
{
Application applicationInterfaceElement = (Application)applicationInterfaces[applicationInterfaces.Count - 1];
ApplicationInterfaceMarshal applicationInterfacePrev = (ApplicationInterfaceMarshal)applicationInterfaceElement.handle.Wrapper;
applicationInterfacePrev.next = applicationInterface.handle.Handle;
}
/* Finally, add our new interface to the array */
applicationInterfaces.Add(applicationInterface);
}
/// <summary>
/// Register
/// </summary>
public void Register()
{
module.module_load = new ModuleLoad(Load);
Switch.switch_loadable_module_build_dynamic(filename,
module.module_load,
module.module_runtime,
module.module_shutdown);
}
public string Name
{
set { name = value; }
get { return name; }
}
}
}