From a5f07a80666ff74f4378555b73f074b21ccc65ed Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Tue, 1 Jun 2010 10:23:04 -0500 Subject: [PATCH] MODLANG-165 Added wrapper for switch_event_bind for .net --- .../mod_managed/managed/EventBinding.cs | 119 ++++++++++++++++++ .../managed/FreeSWITCH.Managed.csproj | 1 + 2 files changed, 120 insertions(+) create mode 100644 src/mod/languages/mod_managed/managed/EventBinding.cs diff --git a/src/mod/languages/mod_managed/managed/EventBinding.cs b/src/mod/languages/mod_managed/managed/EventBinding.cs new file mode 100644 index 0000000000..f8de8891d6 --- /dev/null +++ b/src/mod/languages/mod_managed/managed/EventBinding.cs @@ -0,0 +1,119 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_managed + * Copyright (C) 2008, Michael Giagnocavo + * + * 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_managed + * + * The Initial Developer of the Original Code is + * Michael Giagnocavo + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Michael Giagnocavo + * + * EventBinding.cs - Helpers for switch_event_bind function + * + */ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Runtime.InteropServices; +using System.Reflection; +using FreeSWITCH.Native; + +namespace FreeSWITCH +{ + + public class EventBinding : IDisposable + { + + public class EventBindingArgs : EventArgs + { + public switch_event EventObj { get; set; } + } + + //typedef void (*switch_event_callback_t) (switch_event_t *); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate void switch_event_callback_delegate(IntPtr event_data); + + readonly switch_event_callback_delegate del; // Prevent GC + readonly SWIGTYPE_p_f_p_switch_event__void function; + + private EventBinding(SWIGTYPE_p_f_p_switch_event__void function, switch_event_callback_delegate origDelegate) + { + this.function = function; + this.del = origDelegate; + } + bool disposed; + public void Dispose() + { + dispose(); + GC.SuppressFinalize(this); + } + void dispose() + { + if (disposed) return; + // HACK: FS crashes if we unbind after shutdown is pretty complete. This is still a race condition. + if (freeswitch.switch_core_ready() == switch_bool_t.SWITCH_FALSE) return; + freeswitch.switch_event_unbind_callback(this.function); + disposed = true; + } + ~EventBinding() + { + dispose(); + } + public static switch_event SwitchEventDupe(switch_event evt) + { + IntPtr clone_ptr_ptr = Marshal.AllocCoTaskMem(IntPtr.Size); + freeswitch.switch_event_dup(new SWIGTYPE_p_p_switch_event(clone_ptr_ptr, false), evt); + IntPtr event_ptr = (IntPtr)Marshal.PtrToStructure(clone_ptr_ptr, typeof(IntPtr)); + switch_event dupe_evt = new switch_event(event_ptr, false); + Marshal.FreeCoTaskMem(clone_ptr_ptr); + return dupe_evt; + } + public static IDisposable Bind(string id, switch_event_types_t event_types, string subclass_name, Action f, bool dupe) + { + switch_event_callback_delegate boundFunc; + if (dupe) + { + boundFunc = (eventObj) => + { + var args = new EventBindingArgs { EventObj = SwitchEventDupe(new switch_event(eventObj,false)) }; + f(args); + }; + } + else + { + boundFunc = (eventObj) => + { + var args = new EventBindingArgs { EventObj = new switch_event(eventObj, false) }; + f(args); + }; + } + var fp = Marshal.GetFunctionPointerForDelegate(boundFunc); + var swigFp = new SWIGTYPE_p_f_p_switch_event__void(fp, false); + var res = freeswitch.switch_event_bind(id, event_types, subclass_name, swigFp, null); + if (res != switch_status_t.SWITCH_STATUS_SUCCESS) + { + throw new InvalidOperationException("Call to switch_event_bind failed, result: " + res + "."); + } + return new EventBinding(swigFp, boundFunc); + } + } +} \ No newline at end of file diff --git a/src/mod/languages/mod_managed/managed/FreeSWITCH.Managed.csproj b/src/mod/languages/mod_managed/managed/FreeSWITCH.Managed.csproj index c9947dd82c..cffb967a54 100644 --- a/src/mod/languages/mod_managed/managed/FreeSWITCH.Managed.csproj +++ b/src/mod/languages/mod_managed/managed/FreeSWITCH.Managed.csproj @@ -49,6 +49,7 @@ +