/* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * Copyright (C) 2006, James Martelletti * * 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 * Portions created by the Initial Developer are Copyright (C) * the Initial Developer. All Rights Reserved. * * Contributor(s): * * James Martelletti * * * 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 { /// /// Base class for all Freeswitch.NET modules /// /// /// public class Example : Module /// { /// public Example() /// { /// AddApiInterface(new ExampleApi()); /// AddApplicationInterface(new ExampleApplication()); /// /// Register(); /// } /// } /// 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; /// /// Module constructor /// public Module() { Console.WriteLine("*** Creating new module object"); load = new ModuleLoad(Load); } /// /// Implementation of ModuleLoad Delegate /// /// /// /// 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; } /// /// AddApiInterface /// /// 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); } /// /// AddApplicationInterface /// /// 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); } /// /// Register /// 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; } } } }