<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[Freeswitch-trunk][16623] </title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<div id="header">FreeSWITCH Subversion</div>
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://fisheye.freeswitch.org/changelog/FreeSWITCH?cs=16623">16623</a></dd>
<dt>Author</dt> <dd>joshrivers</dd>
<dt>Date</dt> <dd>2010-02-12 13:21:11 -0600 (Fri, 12 Feb 2010)</dd>
</dl>

<h3>Log Message</h3>
<pre></pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#freeswitchbranchesjoshriversmod_managed_update_branchsrcmodlanguagesmod_managedfreeswitchi">freeswitch/branches/joshrivers/mod_managed_update_branch/src/mod/languages/mod_managed/freeswitch.i</a></li>
<li><a href="#freeswitchbranchesjoshriversmod_managed_update_branchsrcmodlanguagesmod_managedmanagedChannelVariablescs">freeswitch/branches/joshrivers/mod_managed_update_branch/src/mod/languages/mod_managed/managed/ChannelVariables.cs</a></li>
<li><a href="#freeswitchbranchesjoshriversmod_managed_update_branchsrcmodlanguagesmod_managedmanagedManagedSessioncs">freeswitch/branches/joshrivers/mod_managed_update_branch/src/mod/languages/mod_managed/managed/ManagedSession.cs</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="freeswitchbranchesjoshriversmod_managed_update_branchsrcmodlanguagesmod_managedfreeswitchi"></a>
<div class="modfile"><h4>Modified: freeswitch/branches/joshrivers/mod_managed_update_branch/src/mod/languages/mod_managed/freeswitch.i (16622 => 16623)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/branches/joshrivers/mod_managed_update_branch/src/mod/languages/mod_managed/freeswitch.i        2010-02-12 18:19:24 UTC (rev 16622)
+++ freeswitch/branches/joshrivers/mod_managed_update_branch/src/mod/languages/mod_managed/freeswitch.i        2010-02-12 19:21:11 UTC (rev 16623)
</span><span class="lines">@@ -76,6 +76,7 @@
</span><span class="cx"> %typemap(csclassmodifiers) ManagedSession &quot;public partial class&quot;
</span><span class="cx"> %typemap(csclassmodifiers) Event &quot;public partial class&quot;
</span><span class="cx"> %typemap(csclassmodifiers) Stream &quot;public partial class&quot;
</span><ins>+%typemap(csclassmodifiers) API &quot;public partial class&quot;
</ins><span class="cx"> %newobject EventConsumer::pop;
</span><span class="cx"> %newobject Session;
</span><span class="cx"> %newobject CoreSession;
</span><span class="lines">@@ -148,6 +149,34 @@
</span><span class="cx"> %rename (Speak) CoreSession::speak;
</span><span class="cx"> %rename (SetTtsParameters) CoreSession::set_tts_parms;
</span><span class="cx"> %rename (SetAutoHangup) CoreSession::setAutoHangup;
</span><ins>+%rename (Flags) CoreSession::flags;
+%rename (Channel) CoreSession::channel;
+%rename (Allocated) CoreSession::allocated;
+%rename (CallbackState) CoreSession::cb_state;
+%rename (UuidString) CoreSession::uuid;
+%rename (TextToSpeechEngine) CoreSession::tts_name;
+%rename (TextToSpeechVoice) CoreSession::voice_name;
+%rename (PreAnswer) CoreSession::preAnswer;
+%rename (HangupState) CoreSession::hangupState;
+%rename (HangupCause) CoreSession::hangupCause;
+%rename (GetState) CoreSession::getState;
+%rename (Destroy) CoreSession::destroy;
+%rename (Read) CoreSession::read;
+%rename (Sleep) CoreSession::sleep;
+%rename (FlushEvents) CoreSession::flushEvents;
+%rename (FlushDigits) CoreSession::flushDigits;
+%rename (Answered) CoreSession::answered;
+%rename (MediaReady) CoreSession::mediaReady;
+%rename (WaitForAnswer) CoreSession::waitForAnswer;
+%rename (SendEvent) CoreSession::sendEvent;
+%rename (QueuePrivateEvent) CoreSession::queuePrivateEvent;
+%rename (SetEventData) CoreSession::setEventData;
+%rename (GetXmlCdr) CoreSession::getXMLCDR;
+%rename (BeginAllowThreads) CoreSession::begin_allow_threads;
+%rename (EndAllowThreads) CoreSession::end_allow_threads;
+%rename (GetCallbackArguments) CoreSession::get_cb_args;
+%rename (CheckHangupHook) CoreSession::check_hangup_hook;
+%rename (CallCause) CoreSession::cause;
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> %rename (Serialize) Event::serialize;
</span></span></pre></div>
<a id="freeswitchbranchesjoshriversmod_managed_update_branchsrcmodlanguagesmod_managedmanagedChannelVariablescs"></a>
<div class="modfile"><h4>Modified: freeswitch/branches/joshrivers/mod_managed_update_branch/src/mod/languages/mod_managed/managed/ChannelVariables.cs (16622 => 16623)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/branches/joshrivers/mod_managed_update_branch/src/mod/languages/mod_managed/managed/ChannelVariables.cs        2010-02-12 18:19:24 UTC (rev 16622)
+++ freeswitch/branches/joshrivers/mod_managed_update_branch/src/mod/languages/mod_managed/managed/ChannelVariables.cs        2010-02-12 19:21:11 UTC (rev 16623)
</span><span class="lines">@@ -66,7 +66,7 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         ChannelVariables _variables; // Set on ManagedSession init
</span><del>-        public ChannelVariables Variables {
</del><ins>+        public IChannelVariables Variables {
</ins><span class="cx">             get {
</span><span class="cx">                 if (_variables == null) {
</span><span class="cx">                     _variables = new ChannelVariables(this);
</span><span class="lines">@@ -75,8 +75,49 @@
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        public interface IChannelVariables
+        {
+            IDictionary&lt;string, string&gt; GetAllVariables();
+            bool BypassMedia { get; set; }
+            DateTime CreatedTime { get; }
+            DateTime? AnsweredTime { get; }
+            DateTime? HangupTime { get; }
+            DateTime? ProgressTime { get; }
+            DateTime? ProgressMediaTime { get; }
+            DateTime? TransferTime { get; }
+            string SofiaProfileName { get; }
+            string SipCallID { get; }
+            string SipReceivedIP { get; }
+            short? SipReceivedPort { get; }
+            string SipViaProtocolString { get; }
+            string SipFromUser { get; }
+            string SipFromUriString { get; }
+            string SipFromHost { get; }
+            string SipReqUser { get; }
+            string SipReqUriString { get; }
+            string SipReqHost { get; }
+            string SipToUser { get; }
+            string SipToUriString { get; }
+            string SipToHost { get; }
+            string SipContactUser { get; }
+            string SipContactUriString { get; }
+            string SipContactHost { get; }
+            short? SipContactPort { get; }
+            string SipDestinationUrlString { get; }
+            int? SipTermStatus { get; }
+            int? SipTermCause { get; }
+            string SwitchRSdp { get; }
+            string SwitchMSdp { get; }
+            string SipHangupPhrase { get; }
+            string ProtoSpecificHangupCause { get; }
+            string HangupCauseString { get; }
+            int? HangupCauseQ850 { get; }
+            string OriginateDispositionString { get; }
+            Native.switch_call_direction_t CallDirection { get; }
+        }
</ins><span class="cx">         /// &lt;summary&gt;Strongly typed access to common variables&lt;/summary&gt;
</span><del>-        public class ChannelVariables {
</del><ins>+        public class ChannelVariables : IChannelVariables
+        {
</ins><span class="cx">             readonly ManagedSession sess;
</span><span class="cx">             internal ChannelVariables(ManagedSession session) {
</span><span class="cx">                 this.sess = session;
</span><span class="lines">@@ -84,12 +125,12 @@
</span><span class="cx"> 
</span><span class="cx">             public IDictionary&lt;string, string&gt; GetAllVariables() {
</span><span class="cx">                 var dic = new Dictionary&lt;string, string&gt;(StringComparer.OrdinalIgnoreCase);
</span><del>-                var evt = Native.freeswitch.switch_channel_variable_first(sess.channel);
</del><ins>+                var evt = Native.freeswitch.switch_channel_variable_first(sess.Channel);
</ins><span class="cx">                 while(evt != null) {
</span><span class="cx">                     dic.Add(evt.name, evt.value);
</span><span class="cx">                     evt = evt.next;
</span><span class="cx">                 }
</span><del>-                Native.freeswitch.switch_channel_variable_last(sess.channel);
</del><ins>+                Native.freeswitch.switch_channel_variable_last(sess.Channel);
</ins><span class="cx">                 return dic;
</span><span class="cx">             }
</span><span class="cx"> 
</span></span></pre></div>
<a id="freeswitchbranchesjoshriversmod_managed_update_branchsrcmodlanguagesmod_managedmanagedManagedSessioncs"></a>
<div class="modfile"><h4>Modified: freeswitch/branches/joshrivers/mod_managed_update_branch/src/mod/languages/mod_managed/managed/ManagedSession.cs (16622 => 16623)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/branches/joshrivers/mod_managed_update_branch/src/mod/languages/mod_managed/managed/ManagedSession.cs        2010-02-12 18:19:24 UTC (rev 16622)
+++ freeswitch/branches/joshrivers/mod_managed_update_branch/src/mod/languages/mod_managed/managed/ManagedSession.cs        2010-02-12 19:21:11 UTC (rev 16623)
</span><span class="lines">@@ -45,10 +45,72 @@
</span><span class="cx"> 
</span><span class="cx">     // This callback is used for originate
</span><span class="cx">     [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
</span><del>-    public delegate switch_status_t switch_state_handler_t_delegate(IntPtr sessionPtr); 
</del><ins>+    public delegate switch_status_t switch_state_handler_t_delegate(IntPtr sessionPtr);
</ins><span class="cx"> 
</span><del>-    public partial class ManagedSession
</del><ins>+    public interface IManagedSession : IDisposable
</ins><span class="cx">     {
</span><ins>+        int Answer();
+        bool Answered();
+        int Allocated { get; set; }
+        bool BeginAllowThreads();
+        input_callback_state_t CallbackState { get; set; }
+        switch_call_cause_t CallCause { get; set; }
+        SWIGTYPE_p_switch_channel Channel { get; set; }
+        void CheckHangupHook();
+        int CollectDigits(int abs_timeout);
+        int CollectDigits(int digit_timeout, int abs_timeout);
+        Func&lt;Char, TimeSpan, string&gt; DtmfReceivedFunction { get; set; }
+        void Destroy();
+        bool EndAllowThreads();
+        Func&lt;Native.Event, string&gt; EventReceivedFunction { get; set; }
+        void Execute(string app, string data);
+        uint Flags { get; set; }
+        int FlushEvents();
+        int FlushDigits();
+        switch_input_args_t GetCallbackArguments();
+        string GetState();
+        string GetUuid();
+        string GetDigits(int maxdigits, string terminators, int timeout);
+        string GetDigits(int maxdigits, string terminators, int timeout, int interdigit);
+        SWIGTYPE_p_void GetPrivate(string var);
+        string GetVariable(string var);
+        string GetXmlCdr();
+        void Hangup(string cause);
+        string HangupCause();
+        Action HangupFunction { get; set; }
+        void HangupState();
+        switch_channel_state_t HookState { get; set; }
+        SWIGTYPE_p_switch_core_session InternalSession { get; set; }
+        bool IsAvailable { get; }
+        bool MediaReady();
+        bool Originate(CoreSession aLegSession, string destination, TimeSpan timeout);
+        string PlayAndGetDigits(int min_digits, int max_digits, int max_tries, int timeout, string terminators, string audio_files, string bad_input_audio_files, string digits_regex, string var_name);
+        int PreAnswer();
+        void QueuePrivateEvent(IEvent sendME);
+        string Read(int min_digits, int max_digits, string prompt_audio_file, int timeout, string valid_terminators);
+        bool Ready();
+        int RecordFile(string file_name, int time_limit, int silence_threshold, int silence_hits);
+        int SetAutoHangup(bool val);
+        void SetPrivate(string var, SWIGTYPE_p_void val);
+        void SetVariable(string var, string val);
+        void Say(string tosay, string module_name, string say_type, string say_method);
+        void SayPhrase(string phrase_name, string phrase_data, string phrase_lang);
+        void SetTtsParameters(string tts_name, string voice_name);
+        int Speak(string text);
+        int StreamFile(string file, int starting_sample_count);
+        int Sleep(int ms, int sync);
+        void SendEvent(Event sendME);
+        void SetEventData(Event e);
+        int Transfer(string extension, string dialplan, string context);
+        string TextToSpeechEngine { get; set; }
+        string TextToSpeechVoice { get; set; }
+        Guid Uuid { get; }
+        string UuidString { get; set; }
+        ManagedSession.IChannelVariables Variables { get; }
+        void WaitForAnswer(CoreSession calling_session);
+    }
+    public partial class ManagedSession : IManagedSession
+    {
</ins><span class="cx">         // SWITCH_DECLARE(void) InitManagedSession(ManagedSession *session, MonoObject *dtmfDelegate, MonoObject *hangupDelegate)
</span><span class="cx">         [DllImport(&quot;mod_managed.dll&quot;, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
</span><span class="cx">         static extern void InitManagedSession(IntPtr sessionPtr, DtmfCallback dtmfDelegate, CdeclAction hangupDelegate);
</span><span class="lines">@@ -56,7 +118,8 @@
</span><span class="cx">         /// &lt;summary&gt;Initializes the native ManagedSession. Called after Originate completes successfully .&lt;/summary&gt;
</span><span class="cx">         internal void Initialize()
</span><span class="cx">         {
</span><del>-            if (allocated == 0) {
</del><ins>+            if (Allocated == 0)
+            {
</ins><span class="cx">                 throw new InvalidOperationException(&quot;Cannot initialize a ManagedSession until it is allocated (originated successfully).&quot;);
</span><span class="cx">             }
</span><span class="cx">             // P/Invoke generated function pointers stick around until the delegate is collected
</span><span class="lines">@@ -77,11 +140,13 @@
</span><span class="cx">         void hangupCallback()
</span><span class="cx">         {
</span><span class="cx">             Log.WriteLine(LogLevel.Debug, &quot;AppFunction is in hangupCallback.&quot;);
</span><del>-            try {
</del><ins>+            try
+            {
</ins><span class="cx">                 var f = HangupFunction;
</span><span class="cx">                 if (f != null) f();
</span><span class="cx">             }
</span><del>-            catch (Exception ex) {
</del><ins>+            catch (Exception ex)
+            {
</ins><span class="cx">                 Log.WriteLine(LogLevel.Warning, &quot;Exception in hangupCallback: {0}&quot;, ex.ToString());
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="lines">@@ -92,43 +157,54 @@
</span><span class="cx"> 
</span><span class="cx">         string inputCallback(IntPtr input, Native.switch_input_type_t inputType)
</span><span class="cx">         {
</span><del>-            try {
-                switch (inputType) {
</del><ins>+            try
+            {
+                switch (inputType)
+                {
</ins><span class="cx">                     case FreeSWITCH.Native.switch_input_type_t.SWITCH_INPUT_TYPE_DTMF:
</span><del>-                        using (var dtmf = new Native.switch_dtmf_t(input, false)) {
</del><ins>+                        using (var dtmf = new Native.switch_dtmf_t(input, false))
+                        {
</ins><span class="cx">                             return dtmfCallback(dtmf);
</span><span class="cx">                         }
</span><span class="cx">                     case FreeSWITCH.Native.switch_input_type_t.SWITCH_INPUT_TYPE_EVENT:
</span><del>-                        using (var swevt = new Native.switch_event(input, false)) {
</del><ins>+                        using (var swevt = new Native.switch_event(input, false))
+                        {
</ins><span class="cx">                             return eventCallback(swevt);
</span><span class="cx">                         }
</span><span class="cx">                     default:
</span><span class="cx">                         return &quot;&quot;;
</span><span class="cx">                 }
</span><del>-            } catch (Exception ex) {
</del><ins>+            }
+            catch (Exception ex)
+            {
</ins><span class="cx">                 Log.WriteLine(LogLevel.Error, &quot;InputCallback threw exception: &quot; + ex.ToString());
</span><span class="cx">                 return &quot;-ERR InputCallback Exception: &quot; + ex.Message;
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        string dtmfCallback(Native.switch_dtmf_t dtmf) {
</del><ins>+        string dtmfCallback(Native.switch_dtmf_t dtmf)
+        {
</ins><span class="cx">             var f = DtmfReceivedFunction;
</span><del>-            return f == null ? &quot;&quot; 
</del><ins>+            return f == null ? &quot;&quot;
</ins><span class="cx">                 : f(((char)(byte)dtmf.digit), TimeSpan.FromMilliseconds(dtmf.duration));
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        string eventCallback(Native.switch_event swevt) {
-            using (var evt = new FreeSWITCH.Native.Event(swevt, 0)) {
</del><ins>+        string eventCallback(Native.switch_event swevt)
+        {
+            using (var evt = new FreeSWITCH.Native.Event(swevt, 0))
+            {
</ins><span class="cx">                 var f = EventReceivedFunction;
</span><del>-                return f == null ? &quot;&quot; 
</del><ins>+                return f == null ? &quot;&quot;
</ins><span class="cx">                     : f(evt);
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         [Obsolete(&quot;Use static Originate method.&quot;, false)]
</span><del>-        public bool Originate(CoreSession aLegSession, string destination, TimeSpan timeout) {
</del><ins>+        public bool Originate(CoreSession aLegSession, string destination, TimeSpan timeout)
+        {
</ins><span class="cx">             var res = 0 == this.originate(aLegSession, destination, (int)timeout.TotalMilliseconds, null);
</span><del>-            if (res) {
</del><ins>+            if (res)
+            {
</ins><span class="cx">                 this.Initialize();
</span><span class="cx">             }
</span><span class="cx">             return res;
</span><span class="lines">@@ -139,18 +215,22 @@
</span><span class="cx">         // The delegate needs to be stored so it doesn't get GC'd, so we can't just return GetFunctionPointerForDelegate right away.
</span><span class="cx"> 
</span><span class="cx">         /// &lt;summary&gt;Wraps a nice handler into a delegate suitable for reverse P/Invoke. This only currently works well for hangup/reporting handlers.&lt;/summary&gt;
</span><del>-        public static switch_state_handler_t_delegate CreateStateHandlerDelegate(Action&lt;ManagedSession&gt; handler) {
</del><ins>+        public static switch_state_handler_t_delegate CreateStateHandlerDelegate(Action&lt;ManagedSession&gt; handler)
+        {
</ins><span class="cx">             // We create a ManagedSession on top of the session so callbacks can use it &quot;nicely&quot;
</span><span class="cx">             // Then we sort of dispose it.
</span><del>-            switch_state_handler_t_delegate del = ptr =&gt; {
-                using (var sess = new ManagedSession(new SWIGTYPE_p_switch_core_session(ptr, false))) {
</del><ins>+            switch_state_handler_t_delegate del = ptr =&gt;
+            {
+                using (var sess = new ManagedSession(new SWIGTYPE_p_switch_core_session(ptr, false)))
+                {
</ins><span class="cx">                     handler(sess);
</span><span class="cx">                     return switch_status_t.SWITCH_STATUS_SUCCESS;
</span><span class="cx">                 }
</span><span class="cx">             };
</span><span class="cx">             return del;
</span><span class="cx">         }
</span><del>-        public static SWIGTYPE_p_f_p_switch_core_session__switch_status_t WrapStateHandlerDelegate(switch_state_handler_t_delegate del) {
</del><ins>+        public static SWIGTYPE_p_f_p_switch_core_session__switch_status_t WrapStateHandlerDelegate(switch_state_handler_t_delegate del)
+        {
</ins><span class="cx">             return new SWIGTYPE_p_f_p_switch_core_session__switch_status_t(Marshal.GetFunctionPointerForDelegate(del), false);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -162,15 +242,18 @@
</span><span class="cx">         switch_state_handler_table originate_table;
</span><span class="cx">         GCHandle originate_keepalive_handle; // Make sure the B Leg is not collected and disposed until we run ondestroy
</span><span class="cx"> 
</span><del>-        switch_status_t originate_ondestroy_method(IntPtr channelPtr) {
</del><ins>+        switch_status_t originate_ondestroy_method(IntPtr channelPtr)
+        {
</ins><span class="cx">             // CS_DESTROY lets the bleg be collected
</span><span class="cx">             // and frees originate_table memory
</span><span class="cx">             // Note that this (bleg ManagedSession) is invalid 
</span><span class="cx">             // to touch right now - the unmanaged memory has already been free'd
</span><del>-            if (this.originate_keepalive_handle.IsAllocated) {
</del><ins>+            if (this.originate_keepalive_handle.IsAllocated)
+            {
</ins><span class="cx">                 this.originate_keepalive_handle.Free(); // GC can now collect this bleg
</span><span class="cx">             }
</span><del>-            if (this.originate_table != null) {
</del><ins>+            if (this.originate_table != null)
+            {
</ins><span class="cx">                 this.originate_table.Dispose();
</span><span class="cx">                 this.originate_table = null;
</span><span class="cx">             }
</span><span class="lines">@@ -181,12 +264,15 @@
</span><span class="cx">         /// Performs originate. Returns ManagedSession on success, null on failure.
</span><span class="cx">         /// onHangup is called as a state handler, after the channel is truly hungup (CS_REPORTING).
</span><span class="cx">         /// &lt;/summary&gt;
</span><del>-        public static ManagedSession OriginateHandleHangup(CoreSession aLegSession, string destination, TimeSpan timeout, Action&lt;ManagedSession&gt; onHangup) {
</del><ins>+        public static ManagedSession OriginateHandleHangup(CoreSession aLegSession, string destination, TimeSpan timeout, Action&lt;ManagedSession&gt; onHangup)
+        {
</ins><span class="cx">             var bleg = new ManagedSession();
</span><span class="cx"> 
</span><span class="cx">             bleg.originate_ondestroy_delegate = bleg.originate_ondestroy_method;
</span><del>-            bleg.originate_onhangup_delegate = CreateStateHandlerDelegate(sess_b =&gt; {
-                if (onHangup != null) {
</del><ins>+            bleg.originate_onhangup_delegate = CreateStateHandlerDelegate(sess_b =&gt;
+            {
+                if (onHangup != null)
+                {
</ins><span class="cx">                     onHangup(sess_b);
</span><span class="cx">                 }
</span><span class="cx">             });
</span><span class="lines">@@ -196,35 +282,199 @@
</span><span class="cx">             bleg.originate_table.flags = (int)switch_state_handler_flag_t.SSH_FLAG_STICKY;
</span><span class="cx">             var res = 0 == bleg.originate(aLegSession, destination, (int)timeout.TotalSeconds, bleg.originate_table);
</span><span class="cx">             bleg.originate_keepalive_handle = GCHandle.Alloc(bleg, GCHandleType.Normal); // Prevent GC from eating the bleg
</span><del>-            if (res) {
</del><ins>+            if (res)
+            {
</ins><span class="cx">                 bleg.Initialize();
</span><span class="cx">                 return bleg;
</span><del>-            } else {
</del><ins>+            }
+            else
+            {
</ins><span class="cx">                 // Dispose to free the lock
</span><span class="cx">                 // The bleg lives on with its unmanaged memory freed 
</span><span class="cx">                 // Until CS_DESTROY gets called
</span><del>-                bleg.Dispose(); 
</del><ins>+                bleg.Dispose();
</ins><span class="cx">                 return null;
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         // Convenience
</span><del>-        public bool IsAvailable {
</del><ins>+        public bool IsAvailable
+        {
</ins><span class="cx">             get { return this.Ready(); }
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        public Guid Uuid {
-            get {
-                if (allocated == 0) throw new InvalidOperationException(&quot;Session has not been initialized.&quot;);
</del><ins>+        public Guid Uuid
+        {
+            get
+            {
+                if (Allocated == 0) throw new InvalidOperationException(&quot;Session has not been initialized.&quot;);
</ins><span class="cx">                 return new Guid(this.GetUuid());
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        public switch_call_cause_t CallCause {
-            get {
-                if (allocated == 0) throw new InvalidOperationException(&quot;Session has not been initialized.&quot;);
-                return freeswitch.switch_channel_get_cause(this.channel);
</del><ins>+        public switch_call_cause_t CallCause
+        {
+            get
+            {
+                if (Allocated == 0) throw new InvalidOperationException(&quot;Session has not been initialized.&quot;);
+                return freeswitch.switch_channel_get_cause(this.Channel);
</ins><span class="cx">             }
</span><ins>+            set
+            {
+                if (Allocated == 0) throw new InvalidOperationException(&quot;Session has not been initialized.&quot;);
+                base.CallCause = value;
+            }
</ins><span class="cx">         }
</span><ins>+
+        public void QueuePrivateEvent(IEvent sendME)
+        {
+            Event sendEE = sendME as Event;
+            if (sendEE == null) { return; }
+            base.QueuePrivateEvent(sendEE);
+        }
</ins><span class="cx">     }
</span><ins>+
+    public interface IEvent : IDisposable
+    {
+        switch_event InternalEvent { get; set; }
+        string serialized_string { get; set; }
+        int mine { get; set; }
+        string Serialize(string format);
+        bool SetPriority(switch_priority_t priority);
+        string GetHeader(string header_name);
+        string GetBody();
+        string GetEventType();
+        bool AddBody(string value);
+        bool AddHeader(string header_name, string value);
+        bool DeleteHeader(string header_name);
+        bool Fire();
+        IEnumerable&lt;string&gt; HeaderNames();
+    }
+    public partial class Event : IEvent
+    {
+        public IEnumerable&lt;string&gt; HeaderNames()
+        {
+            switch_event_header header = this.InternalEvent.headers;
+            while (header != null)
+            {
+                yield return header.name;
+                header = header.next;
+            }
+        }
+
+        public class EventClassStrings
+        {
+            public static readonly string SWITCH_EVENT_CUSTOM = &quot;CUSTOM&quot;;
+            public static readonly string SWITCH_EVENT_CLONE = &quot;CLONE&quot;;
+            public static readonly string SWITCH_EVENT_CHANNEL_CREATE = &quot;CHANNEL_CREATE&quot;;
+            public static readonly string SWITCH_EVENT_CHANNEL_DESTROY = &quot;CHANNEL_DESTROY&quot;;
+            public static readonly string SWITCH_EVENT_CHANNEL_STATE = &quot;CHANNEL_STATE&quot;;
+            public static readonly string SWITCH_EVENT_CHANNEL_ANSWER = &quot;CHANNEL_ANSWER&quot;;
+            public static readonly string SWITCH_EVENT_CHANNEL_HANGUP = &quot;CHANNEL_HANGUP&quot;;
+            public static readonly string SWITCH_EVENT_CHANNEL_HANGUP_COMPLETE = &quot;CHANNEL_HANGUP_COMPLETE&quot;;
+            public static readonly string SWITCH_EVENT_CHANNEL_EXECUTE = &quot;CHANNEL_EXECUTE&quot;;
+            public static readonly string SWITCH_EVENT_CHANNEL_EXECUTE_COMPLETE = &quot;CHANNEL_EXECUTE_COMPLETE&quot;;
+            public static readonly string SWITCH_EVENT_CHANNEL_BRIDGE = &quot;CHANNEL_BRIDGE&quot;;
+            public static readonly string SWITCH_EVENT_CHANNEL_UNBRIDGE = &quot;CHANNEL_UNBRIDGE&quot;;
+            public static readonly string SWITCH_EVENT_CHANNEL_PROGRESS = &quot;CHANNEL_PROGRESS&quot;;
+            public static readonly string SWITCH_EVENT_CHANNEL_PROGRESS_MEDIA = &quot;CHANNEL_PROGRESS_MEDIA&quot;;
+            public static readonly string SWITCH_EVENT_CHANNEL_OUTGOING = &quot;CHANNEL_OUTGOING&quot;;
+            public static readonly string SWITCH_EVENT_CHANNEL_PARK = &quot;CHANNEL_PARK&quot;;
+            public static readonly string SWITCH_EVENT_CHANNEL_UNPARK = &quot;CHANNEL_UNPARK&quot;;
+            public static readonly string SWITCH_EVENT_CHANNEL_APPLICATION = &quot;CHANNEL_APPLICATION&quot;;
+            public static readonly string SWITCH_EVENT_CHANNEL_ORIGINATE = &quot;CHANNEL_ORIGINATE&quot;;
+            public static readonly string SWITCH_EVENT_CHANNEL_UUID = &quot;CHANNEL_UUID&quot;;
+            public static readonly string SWITCH_EVENT_API = &quot;API&quot;;
+            public static readonly string SWITCH_EVENT_LOG = &quot;LOG&quot;;
+            public static readonly string SWITCH_EVENT_INBOUND_CHAN = &quot;INBOUND_CHAN&quot;;
+            public static readonly string SWITCH_EVENT_OUTBOUND_CHAN = &quot;OUTBOUND_CHAN&quot;;
+            public static readonly string SWITCH_EVENT_STARTUP = &quot;STARTUP&quot;;
+            public static readonly string SWITCH_EVENT_SHUTDOWN = &quot;SHUTDOWN&quot;;
+            public static readonly string SWITCH_EVENT_PUBLISH = &quot;PUBLISH&quot;;
+            public static readonly string SWITCH_EVENT_UNPUBLISH = &quot;UNPUBLISH&quot;;
+            public static readonly string SWITCH_EVENT_TALK = &quot;TALK&quot;;
+            public static readonly string SWITCH_EVENT_NOTALK = &quot;NOTALK&quot;;
+            public static readonly string SWITCH_EVENT_SESSION_CRASH = &quot;SESSION_CRASH&quot;;
+            public static readonly string SWITCH_EVENT_MODULE_LOAD = &quot;MODULE_LOAD&quot;;
+            public static readonly string SWITCH_EVENT_MODULE_UNLOAD = &quot;MODULE_UNLOAD&quot;;
+            public static readonly string SWITCH_EVENT_DTMF = &quot;DTMF&quot;;
+            public static readonly string SWITCH_EVENT_MESSAGE = &quot;MESSAGE&quot;;
+            public static readonly string SWITCH_EVENT_PRESENCE_IN = &quot;PRESENCE_IN&quot;;
+            public static readonly string SWITCH_EVENT_NOTIFY_IN = &quot;NOTIFY_IN&quot;;
+            public static readonly string SWITCH_EVENT_PRESENCE_OUT = &quot;PRESENCE_OUT&quot;;
+            public static readonly string SWITCH_EVENT_PRESENCE_PROBE = &quot;PRESENCE_PROBE&quot;;
+            public static readonly string SWITCH_EVENT_MESSAGE_WAITING = &quot;MESSAGE_WAITING&quot;;
+            public static readonly string SWITCH_EVENT_MESSAGE_QUERY = &quot;MESSAGE_QUERY&quot;;
+            public static readonly string SWITCH_EVENT_ROSTER = &quot;ROSTER&quot;;
+            public static readonly string SWITCH_EVENT_CODEC = &quot;CODEC&quot;;
+            public static readonly string SWITCH_EVENT_BACKGROUND_JOB = &quot;BACKGROUND_JOB&quot;;
+            public static readonly string SWITCH_EVENT_DETECTED_SPEECH = &quot;DETECTED_SPEECH&quot;;
+            public static readonly string SWITCH_EVENT_DETECTED_TONE = &quot;DETECTED_TONE&quot;;
+            public static readonly string SWITCH_EVENT_PRIVATE_COMMAND = &quot;PRIVATE_COMMAND&quot;;
+            public static readonly string SWITCH_EVENT_HEARTBEAT = &quot;HEARTBEAT&quot;;
+            public static readonly string SWITCH_EVENT_TRAP = &quot;TRAP&quot;;
+            public static readonly string SWITCH_EVENT_ADD_SCHEDULE = &quot;ADD_SCHEDULE&quot;;
+            public static readonly string SWITCH_EVENT_DEL_SCHEDULE = &quot;DEL_SCHEDULE&quot;;
+            public static readonly string SWITCH_EVENT_EXE_SCHEDULE = &quot;EXE_SCHEDULE&quot;;
+            public static readonly string SWITCH_EVENT_RE_SCHEDULE = &quot;RE_SCHEDULE&quot;;
+            public static readonly string SWITCH_EVENT_RELOADXML = &quot;RELOADXML&quot;;
+            public static readonly string SWITCH_EVENT_NOTIFY = &quot;NOTIFY&quot;;
+            public static readonly string SWITCH_EVENT_SEND_MESSAGE = &quot;SEND_MESSAGE&quot;;
+            public static readonly string SWITCH_EVENT_RECV_MESSAGE = &quot;RECV_MESSAGE&quot;;
+            public static readonly string SWITCH_EVENT_REQUEST_PARAMS = &quot;REQUEST_PARAMS&quot;;
+            public static readonly string SWITCH_EVENT_CHANNEL_DATA = &quot;CHANNEL_DATA&quot;;
+            public static readonly string SWITCH_EVENT_GENERAL = &quot;GENERAL&quot;;
+            public static readonly string SWITCH_EVENT_COMMAND = &quot;COMMAND&quot;;
+            public static readonly string SWITCH_EVENT_SESSION_HEARTBEAT = &quot;SESSION_HEARTBEAT&quot;;
+            public static readonly string SWITCH_EVENT_CLIENT_DISCONNECTED = &quot;CLIENT_DISCONNECTED&quot;;
+            public static readonly string SWITCH_EVENT_SERVER_DISCONNECTED = &quot;SERVER_DISCONNECTED&quot;;
+            public static readonly string SWITCH_EVENT_SEND_INFO = &quot;SEND_INFO&quot;;
+            public static readonly string SWITCH_EVENT_RECV_INFO = &quot;RECV_INFO&quot;;
+            public static readonly string SWITCH_EVENT_CALL_SECURE = &quot;CALL_SECURE&quot;;
+            public static readonly string SWITCH_EVENT_NAT = &quot;NAT&quot;;
+            public static readonly string SWITCH_EVENT_RECORD_START = &quot;RECORD_START&quot;;
+            public static readonly string SWITCH_EVENT_RECORD_STOP = &quot;RECORD_STOP&quot;;
+            public static readonly string SWITCH_EVENT_CALL_UPDATE = &quot;CALL_UPDATE&quot;;
+            public static readonly string SWITCH_EVENT_ALL = &quot;ALL&quot;;
+        }
+    }
+
+    public interface IManagedEventConsumer
+    {
+        IEvent Pop(bool block);
+    }
+    public class ManagedEventConsumer : IDisposable, IManagedEventConsumer
+    {
+        private EventConsumer _eventConsumer;
+        public ManagedEventConsumer(string eventClass, string EventSubclass)
+        {
+            this._eventConsumer = new EventConsumer(eventClass, EventSubclass);
+        }
+
+        public IEvent Pop(bool block)
+        {
+            if (block)
+            {
+                return this._eventConsumer.pop(1);
+            }
+            else
+            {
+                return this._eventConsumer.pop(0);
+            }
+        }
+
+        public void Dispose()
+        {
+            this._eventConsumer.Dispose();
+        }
+    }
+
+
+    public interface IApi : IDisposable
+    {
+        string Execute(string command, string data);
+        string ExecuteString(string command);
+        string getTime();
+    }
+    public partial class Api : IApi { }
</ins><span class="cx"> }
</span></span></pre>
</div>
</div>
<div id="footer">See you at ClueCon</div>

</body>
</html>