2010-06-01 10:23:04 -05:00
|
|
|
|
/*
|
|
|
|
|
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_managed
|
|
|
|
|
* Copyright (C) 2008, Michael Giagnocavo <mgg@giagnocavo.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_managed
|
|
|
|
|
*
|
|
|
|
|
* The Initial Developer of the Original Code is
|
|
|
|
|
* Michael Giagnocavo <mgg@giagnocavo.net>
|
|
|
|
|
* Portions created by the Initial Developer are Copyright (C)
|
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
|
|
|
|
*
|
|
|
|
|
* Contributor(s):
|
|
|
|
|
*
|
|
|
|
|
* Michael Giagnocavo <mgg@giagnocavo.net>
|
|
|
|
|
*
|
|
|
|
|
* 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
|
|
|
|
|
{
|
2011-07-09 17:02:33 -05:00
|
|
|
|
public class SwitchEventWrap : switch_event, IDisposable
|
|
|
|
|
{
|
|
|
|
|
private bool disposed;
|
|
|
|
|
private SWIGTYPE_p_p_switch_event p_p_switch_event;
|
|
|
|
|
private IntPtr native_ptr_ptr;
|
|
|
|
|
|
|
|
|
|
internal SwitchEventWrap(IntPtr ptrPtr) : base((IntPtr)Marshal.PtrToStructure(ptrPtr, typeof(IntPtr)), false)
|
|
|
|
|
{
|
|
|
|
|
native_ptr_ptr = ptrPtr;
|
|
|
|
|
p_p_switch_event = new SWIGTYPE_p_p_switch_event(ptrPtr, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~SwitchEventWrap()
|
|
|
|
|
{
|
|
|
|
|
dispose();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void Dispose()
|
|
|
|
|
{
|
|
|
|
|
dispose();
|
|
|
|
|
GC.SuppressFinalize(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal void dispose()
|
|
|
|
|
{
|
|
|
|
|
if (disposed) return;
|
|
|
|
|
disposed = true;
|
|
|
|
|
freeswitch.switch_event_destroy(p_p_switch_event);
|
|
|
|
|
Marshal.FreeCoTaskMem(native_ptr_ptr);
|
|
|
|
|
}
|
|
|
|
|
}
|
2010-06-01 10:23:04 -05:00
|
|
|
|
|
|
|
|
|
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);
|
2011-07-09 17:02:33 -05:00
|
|
|
|
SwitchEventWrap dupe_evt = new SwitchEventWrap(clone_ptr_ptr);
|
2010-06-01 10:23:04 -05:00
|
|
|
|
return dupe_evt;
|
|
|
|
|
}
|
|
|
|
|
public static IDisposable Bind(string id, switch_event_types_t event_types, string subclass_name, Action<EventBindingArgs> 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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|