<!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][16050] </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=16050">16050</a></dd>
<dt>Author</dt> <dd>szentesik</dd>
<dt>Date</dt> <dd>2009-12-23 18:51:46 -0600 (Wed, 23 Dec 2009)</dd>
</dl>

<h3>Log Message</h3>
<pre>CSTA interface added</pre>

<h3>Added Paths</h3>
<ul>
<li>freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/</li>
<li><a href="#freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketDownloadCSTAInsidevcproj">freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/Download CSTAInside.vcproj</a></li>
<li>freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/</li>
<li><a href="#freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketFreeSWITCHFreeSWITCHcpp">freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/FreeSWITCH.cpp</a></li>
<li><a href="#freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketFreeSWITCHFreeSWITCHh">freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/FreeSWITCH.h</a></li>
<li><a href="#freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketFreeSWITCHFreeSWITCHPlatformcpp">freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/FreeSWITCHPlatform.cpp</a></li>
<li><a href="#freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketFreeSWITCHFreeSWITCHPlatformh">freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/FreeSWITCHPlatform.h</a></li>
<li><a href="#freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketFreeSWITCHFreeSWITCHSocketcpp">freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/FreeSWITCHSocket.cpp</a></li>
<li><a href="#freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketFreeSWITCHFreeSWITCHSocketh">freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/FreeSWITCHSocket.h</a></li>
<li><a href="#freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketFreeSWITCHFreeSWITCH_CSTArc">freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/FreeSWITCH_CSTA.rc</a></li>
<li><a href="#freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketFreeSWITCHREADME">freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/README</a></li>
<li><a href="#freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketFreeSWITCHconfigcpp">freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/config.cpp</a></li>
<li><a href="#freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketFreeSWITCHconfigh">freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/config.h</a></li>
<li><a href="#freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketFreeSWITCHmod_csta_socketcpp">freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/mod_csta_socket.cpp</a></li>
<li><a href="#freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketFreeSWITCHmod_csta_socketdef">freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/mod_csta_socket.def</a></li>
<li><a href="#freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketFreeSWITCHmod_csta_socketvcproj">freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/mod_csta_socket.vcproj</a></li>
<li><a href="#freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketFreeSWITCHresourceh">freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/resource.h</a></li>
<li><a href="#freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketmod_csta_socketsln">freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/mod_csta_socket.sln</a></li>
<li><a href="#freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketutilvbs">freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/util.vbs</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li>freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/CSTAInsideCore/</li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketDownloadCSTAInsidevcproj"></a>
<div class="addfile"><h4>Added: freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/Download CSTAInside.vcproj (0 => 16050)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/Download CSTAInside.vcproj                                (rev 0)
+++ freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/Download CSTAInside.vcproj        2009-12-24 00:51:46 UTC (rev 16050)
</span><span class="lines">@@ -0,0 +1,100 @@
</span><ins>+&lt;?xml version=&quot;1.0&quot; encoding=&quot;Windows-1252&quot;?&gt;
+&lt;VisualStudioProject
+        ProjectType=&quot;Visual C++&quot;
+        Version=&quot;9,00&quot;
+        Name=&quot;Download CSTAInside&quot;
+        ProjectGUID=&quot;{4F92B672-DADB-4047-8D6A-4BB3796733FD}&quot;
+        RootNamespace=&quot;Download CSTAInside&quot;
+        Keyword=&quot;Win32Proj&quot;
+        TargetFrameworkVersion=&quot;131072&quot;
+        &gt;
+        &lt;Platforms&gt;
+                &lt;Platform
+                        Name=&quot;Win32&quot;
+                /&gt;
+        &lt;/Platforms&gt;
+        &lt;ToolFiles&gt;
+        &lt;/ToolFiles&gt;
+        &lt;Configurations&gt;
+                &lt;Configuration
+                        Name=&quot;Debug|Win32&quot;
+                        OutputDirectory=&quot;$(ConfigurationName)&quot;
+                        IntermediateDirectory=&quot;$(ConfigurationName)&quot;
+                        ConfigurationType=&quot;10&quot;
+                        CharacterSet=&quot;2&quot;
+                        BuildLogFile=&quot;$(IntDir)\BuildLog $(ProjectName).htm&quot;
+                        &gt;
+                        &lt;Tool
+                                Name=&quot;VCPreBuildEventTool&quot;
+                                Description=&quot;Downloading CSTAInside&quot;
+                                CommandLine=&quot;if not exist &amp;quot;$(ProjectDir)CSTAInsideCore&amp;quot; cscript /nologo &amp;quot;$(ProjectDir)util.vbs&amp;quot; GetUnzip http://freefr.dl.sourceforge.net/project/cstainside/cstainside/v0.2.0/cstainside_v0.2.0.92.zip &amp;quot;$(ProjectDir).&amp;quot;&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCCustomBuildTool&quot;
+                                CommandLine=&quot;&quot;
+                                Outputs=&quot;&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCMIDLTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCPostBuildEventTool&quot;
+                                CommandLine=&quot;if exist cstainside_v0.2.0.92 ren cstainside_v0.2.0.92 CSTAInsideCore&quot;
+                        /&gt;
+                &lt;/Configuration&gt;
+                &lt;Configuration
+                        Name=&quot;Release|Win32&quot;
+                        OutputDirectory=&quot;$(ConfigurationName)&quot;
+                        IntermediateDirectory=&quot;$(ConfigurationName)&quot;
+                        ConfigurationType=&quot;10&quot;
+                        CharacterSet=&quot;2&quot;
+                        BuildLogFile=&quot;$(IntDir)\BuildLog $(ProjectName).htm&quot;
+                        &gt;
+                        &lt;Tool
+                                Name=&quot;VCPreBuildEventTool&quot;
+                                Description=&quot;Downloading CSTAInside&quot;
+                                CommandLine=&quot;if not exist &amp;quot;$(ProjectDir)CSTAInsideCore&amp;quot; cscript /nologo &amp;quot;$(ProjectDir)util.vbs&amp;quot; GetUnzip http://freefr.dl.sourceforge.net/project/cstainside/cstainside/v0.2.0/cstainside_v0.2.0.92.zip &amp;quot;$(ProjectDir).&amp;quot;&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCCustomBuildTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCMIDLTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCPostBuildEventTool&quot;
+                                CommandLine=&quot;if exist cstainside_v0.2.0.92 ren cstainside_v0.2.0.92 CSTAInsideCore&quot;
+                        /&gt;
+                &lt;/Configuration&gt;
+        &lt;/Configurations&gt;
+        &lt;References&gt;
+        &lt;/References&gt;
+        &lt;Files&gt;
+                &lt;File
+                        RelativePath=&quot;.\cleancount&quot;
+                        &gt;
+                        &lt;FileConfiguration
+                                Name=&quot;Debug|Win32&quot;
+                                &gt;
+                                &lt;Tool
+                                        Name=&quot;VCCustomBuildTool&quot;
+                                        Description=&quot;Downloading CSTAInsideCore.&quot;
+                                        CommandLine=&quot;if not exist &amp;quot;$(ProjectDir)CSTAInsideCore&amp;quot; cscript /nologo &amp;quot;$(ProjectDir)util.vbs&amp;quot; GetUnzip http://freefr.dl.sourceforge.net/project/cstainside/cstainside/v0.2.0/cstainside_v0.2.0.92.zip &amp;quot;$(ProjectDir).&amp;quot;&amp;#x0D;&amp;#x0A;&quot;
+                                        Outputs=&quot;$(ProjectDir).&quot;
+                                /&gt;
+                        &lt;/FileConfiguration&gt;
+                        &lt;FileConfiguration
+                                Name=&quot;Release|Win32&quot;
+                                &gt;
+                                &lt;Tool
+                                        Name=&quot;VCCustomBuildTool&quot;
+                                        Description=&quot;Downloading CSTAInsideCore.&quot;
+                                        CommandLine=&quot;if not exist &amp;quot;$(ProjectDir)CSTAInsideCore&amp;quot; cscript /nologo &amp;quot;$(ProjectDir)util.vbs&amp;quot; GetUnzip http://freefr.dl.sourceforge.net/project/cstainside/cstainside/v0.2.0/cstainside_v0.2.0.92.zip &amp;quot;$(ProjectDir).&amp;quot;&amp;#x0D;&amp;#x0A;&quot;
+                                        Outputs=&quot;$(ProjectDir).&quot;
+                                /&gt;
+                        &lt;/FileConfiguration&gt;
+                &lt;/File&gt;
+        &lt;/Files&gt;
+        &lt;Globals&gt;
+        &lt;/Globals&gt;
+&lt;/VisualStudioProject&gt;
</ins></span></pre></div>
<a id="freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketFreeSWITCHFreeSWITCHcpp"></a>
<div class="addfile"><h4>Added: freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/FreeSWITCH.cpp (0 => 16050)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/FreeSWITCH.cpp                                (rev 0)
+++ freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/FreeSWITCH.cpp        2009-12-24 00:51:46 UTC (rev 16050)
</span><span class="lines">@@ -0,0 +1,1737 @@
</span><ins>+/* 
+ * CSTA interface for FreeSWICH 
+ * Copyright (C) 2009, Szentesi Krisztian &lt;sz.krisz@freemail.hu&gt;
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the &quot;License&quot;); 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 &quot;AS IS&quot; 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 CSTA interface for FreeSWICH   
+ * 
+ * The Initial Developer of the Original Code is
+ * Szentesi Krisztian &lt;sz.krisz@freemail.hu&gt;
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * 
+ * Szentesi Krisztian &lt;sz.krisz@freemail.hu&gt;
+ *
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the &quot;GPL&quot;), or
+ * the GNU Lesser General Public License Version 2.1 or later (the &quot;LGPL&quot;),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ */
+#include &lt;switch.h&gt;
+#include &lt;direct.h&gt;
+#include &quot;FreeSWITCH.h&quot;
+
+#include &quot;MonitorStartRequest.h&quot;
+#include &quot;UniversalErrorResponse.h&quot;
+#include &quot;MonitorStartResponse.h&quot;
+#include &quot;MakeCallRequest.h&quot;
+#include &quot;MakeCallResponse.h&quot;
+#include &quot;AnswerCallRequest.h&quot;
+#include &quot;AnswerCallResponse.h&quot;
+#include &quot;SingleStepTransferCallRequest.h&quot;
+#include &quot;SingleStepTransferCallResponse.h&quot;
+#include &quot;DeflectCallRequest.h&quot;
+#include &quot;DeflectCallResponse.h&quot;
+#include &quot;PlayMessageRequest.h&quot;
+#include &quot;PlayMessageResponse.h&quot;
+#include &quot;RecordMessageRequest.h&quot;
+#include &quot;RecordMessageResponse.h&quot;
+#include &quot;StopRequest.h&quot;
+#include &quot;StopResponse.h&quot;
+#include &quot;ServiceInitiatedEvent.h&quot;
+#include &quot;OriginatedEvent.h&quot;
+#include &quot;DeliveredEvent.h&quot;
+#include &quot;EstablishedEvent.h&quot;
+#include &quot;ConnectionClearedEvent.h&quot;
+#include &quot;QueuedEvent.h&quot;
+#include &quot;DtmfDetectedEvent.h&quot;
+#include &quot;PlayEvent.h&quot;
+#include &quot;RecordEvent.h&quot;
+#include &quot;StopEvent.h&quot;
+#include &quot;ClearConnectionRequest.h&quot;
+#include &quot;ClearConnectionResponse.h&quot;
+#include &quot;SnapshotDeviceRequest.h&quot;
+#include &quot;SnapshotDeviceResponse.h&quot;
+#include &quot;SnapshotCallRequest.h&quot;
+#include &quot;SnapshotCallResponse.h&quot;
+
+#include &lt;string&gt;
+using namespace std;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// class FreeSwitchDevice
+
+/*static*/ std::string FreeSwitchDevice::Channel2Device(const char* channel)
+{
+        string strDevice;
+        if(strncmp(channel, &quot;sofia/internal/&quot;, 15)==0)
+        {
+                if(strncmp(channel+15, &quot;sip:&quot;, 4)==0)
+                        strDevice=channel+19;
+                else
+                        strDevice=channel+15;
+        }
+        std::string::size_type i=strDevice.find(&quot;@&quot;);
+        if(i!=strDevice.npos)
+        {
+                strDevice.erase(i);
+        }        
+        
+        return strDevice;
+}
+
+/*static*/ char * FreeSwitchDevice::Type2Prefix(FreeSwitchDeviceType type)
+{
+        switch(type)
+        {
+        case type_network_interface: return &quot;01&quot;;
+        case type_queue: return &quot;02&quot;;
+        default: return &quot;&quot;;
+        };
+}
+
+/*static*/ FreeSwitchDeviceType FreeSwitchDevice::Device2Type(DeviceID device)
+{
+        if(device.GetTypeOfNumber()==typeOfNumberDialable)
+                return type_internal_subscriber;
+
+        if(device.GetCallNr().size()&lt;2)
+                return type_unknown;
+
+        for(int i=type_network_interface;Type2Prefix((FreeSwitchDeviceType)i)[0]!=0;i++)
+        {
+                if(strncmp(Type2Prefix((FreeSwitchDeviceType)i),device.GetCallNr().c_str(),2)==0)
+                {
+                        return (FreeSwitchDeviceType)i;
+                }
+        }
+
+        return type_unknown;
+}
+
+
+FreeSwitchDevice::FreeSwitchDevice(const char* pcDevice, FreeSwitchDeviceType deviceType/*=type_internal_subscriber*/) : m_strDevice(pcDevice), m_deviceType(deviceType), m_bIsMakeCallOriginator(false)
+{
+        
+}
+
+FreeSwitchConnection* FreeSwitchDevice::FindConnection(const char* uuid)
+{
+        for(MapCall2Connection::iterator it=connections.begin();it!=connections.end();it++)        
+        {
+                if(it-&gt;first-&gt;strUUID==uuid)                        
+                        return it-&gt;second;
+        }
+        return NULL;
+}
+
+FreeSwitchConnection* FreeSwitchDevice::FindConnection(FreeSwitchCall* pCall)
+{
+        MapCall2Connection::iterator it=connections.find(pCall);
+        if(it==connections.end())
+                return NULL;
+        else
+                return it-&gt;second;
+}
+
+FreeSwitchConnection* FreeSwitchDevice::AddConnection(const char* uuid, const char * channel, FreeSwitchCall* pCall, eDirection direction)
+{
+        FreeSwitchConnection* pConnection=new FreeSwitchConnection();                
+        pConnection-&gt;pCall=pCall;
+        pConnection-&gt;strUUID=uuid;
+        pConnection-&gt;state=STATE_INITIATED;        
+        pConnection-&gt;direction=direction;
+        pConnection-&gt;strChannel=channel;
+        pCall-&gt;devices[GetDeviceID()]=this;
+        connections[pCall]=pConnection;
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSwitchDevice::AddConnection: connection %s - %s added.\n&quot;,this-&gt;m_strDevice.c_str(),pCall-&gt;strUUID.c_str());
+        
+        return pConnection;
+}
+
+void FreeSwitchDevice::DeleteConnection(FreeSwitchCall* pCall)
+{        
+        MapCall2Connection::iterator it=connections.find(pCall);
+        if(it==connections.end())
+                return;
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSwitchDevice::DeleteConnection: connection %s - %s deleted.\n&quot;,this-&gt;m_strDevice.c_str(),pCall-&gt;strUUID.c_str());
+
+        delete it-&gt;second;
+        connections.erase(it);
+
+        pCall-&gt;devices.erase(this-&gt;GetDeviceID());
+}
+
+
+bool FreeSwitchDevice::IsMonitoredWithID(string crossRefID)
+{
+        return m_MonitoringSessions.find(crossRefID)==m_MonitoringSessions.end()?false:true;
+}
+
+bool FreeSwitchDevice::AddMonitor(CISession* session, string crossRefID)
+{
+        if(IsMonitoredWithID(crossRefID))
+                return false;        //XRefID already used
+        
+        m_MonitoringSessions[crossRefID]=session;
+        return true;
+}
+
+bool FreeSwitchDevice::RemoveMonitor(CISession* session)
+{
+        bool found=false;
+        for(MapStr2Session::iterator it=m_MonitoringSessions.begin();it!=m_MonitoringSessions.end();it++)
+                if(it-&gt;second==session)
+                {
+                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSwitchDevice::RemoveMonitor: removing session 0x%08X from device %s\n&quot;,session, m_strDevice.c_str());
+                        it=m_MonitoringSessions.erase(it);
+                        found=true;
+                        if(it==m_MonitoringSessions.end())
+                                break;
+                }
+        return found;
+}
+
+bool FreeSwitchDevice::RemoveMonitor(CISession* session, string crossRefID)
+{
+        MapStr2Session::iterator it=m_MonitoringSessions.find(crossRefID);
+        
+        if(it==m_MonitoringSessions.end())
+                return false;        //XRefID not found
+
+        if(it-&gt;second!=session)
+        {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSwitchDevice::RemoveMonitor: XRefID %s mapped to device %sbut from session 0x%08X instead of 0x%08X, removal denied.\n&quot;,crossRefID.c_str(), m_strDevice.c_str(), it-&gt;second, session);
+        }
+        m_MonitoringSessions.erase(it);
+        return true;
+}
+
+void FreeSwitchDevice::SendEvent(CSTAEvent* pEvent)
+{
+        for(MapStr2Session::iterator it=m_MonitoringSessions.begin();it!=m_MonitoringSessions.end();it++)
+        {
+                pEvent-&gt;SetCrossRefID(it-&gt;first);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSwitchDevice::SendEvent: device %s, session %X, sending event: \n%s\n&quot;,GetDeviceID().c_str(),it-&gt;second,pEvent-&gt;GetReadable().c_str());
+                it-&gt;second-&gt;SendMsg(pEvent);        
+        }
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// class FreeSwitchCall
+
+FreeSwitchDevice* FreeSwitchCall::GetDevice(std::string strDeviceID)
+{        
+        MapStr2Device::iterator it=devices.find(strDeviceID);
+        if(it!=devices.end())
+                return it-&gt;second;
+        else 
+                return NULL;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// class FreeSwitch
+
+FreeSWITCH::FreeSWITCH(switch_memory_pool_t *pool) : m_pool(pool), m_nLastXRefID(0)
+{
+        switch_mutex_init(&amp;m_mutex, SWITCH_MUTEX_NESTED, m_pool);
+}
+
+
+FreeSWITCH::~FreeSWITCH()
+{
+        for(MapStr2Device::iterator it=m_DeviceMap.begin();it!=m_DeviceMap.end();it++)
+        {
+                delete it-&gt;second;
+        }
+        m_DeviceMap.clear();
+        switch_mutex_destroy(m_mutex);
+}
+
+string FreeSWITCH::GetNextXRefID()
+{
+        ++m_nLastXRefID;
+        if(m_nLastXRefID&gt;100000)
+                m_nLastXRefID=1;
+        char temp[8];        
+        itoa(m_nLastXRefID,temp,10);
+        return string(temp);
+}
+
+
+FreeSwitchDevice * FreeSWITCH::PrepareDevice(const char * pcDevice, FreeSwitchDeviceType type/*=type_internal_subscriber*/)
+{
+        string strFullDevName=FreeSwitchDevice::Type2Prefix(type);
+        strFullDevName+=pcDevice;
+        
+        MapStr2Device::iterator it=m_DeviceMap.find(strFullDevName);
+        FreeSwitchDevice* pDevice=NULL;
+        if(it==m_DeviceMap.end())
+        {
+                pDevice=new FreeSwitchDevice(strFullDevName.c_str(),type);
+                m_DeviceMap[strFullDevName]=pDevice;
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::PrepareDevice: device %s type %d added.&quot;, pcDevice, type);
+        }
+        else
+        {
+                pDevice=it-&gt;second;
+                if(pDevice-&gt;GetDeviceType()!=type)
+                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::PrepareDevice: device %s found but type is different!&quot;,pcDevice);
+
+        }
+
+        return pDevice;
+}
+
+FreeSwitchCall* FreeSWITCH::GetCall(const char * pcUUID)
+{
+        if(!pcUUID)
+                return NULL;
+        MapStr2Call::iterator it=m_CallMap.find(pcUUID);
+        if(it==m_CallMap.end())
+                return NULL;
+        else return it-&gt;second;        //TODO: might chech the secondary UUID
+}
+
+bool FreeSWITCH::IsXRefIDUsed(string crossRefID)
+{
+        switch_mutex_lock(m_mutex);
+        
+        for(MapStr2Device::iterator it=m_DeviceMap.begin();it!=m_DeviceMap.end();it++)
+        {
+                if(it-&gt;second-&gt;IsMonitoredWithID(crossRefID))
+                {
+                        switch_mutex_unlock(m_mutex);
+                        return true;
+                }
+        }
+
+        switch_mutex_unlock(m_mutex);        
+        return false;
+}
+
+bool FreeSWITCH::FindCallerCalled(const char* uuid, string* pstrCaller, string* pstrCalled)
+{
+        switch_core_session_t * session=NULL;
+        for(int i=0;i&lt;3;i++)
+        {
+                session=switch_core_session_locate(uuid);
+                if(session)
+                        break;
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, &quot;FreeSWITCH::FindCallerCalled: Session %s not available, waiting.\n&quot;,uuid);
+                switch_yield(100000);
+        }
+
+        if(!session)
+        {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::FindCallerCalled: Session %s no longer exists.\n&quot;,uuid);
+                return false;
+        }
+        switch_channel_t* channel=switch_core_session_get_channel(session);
+        switch_caller_profile_t * caller=switch_channel_get_caller_profile(channel);
+        
+        if(pstrCaller)
+                *pstrCaller=caller-&gt;caller_id_number;
+
+        if(pstrCalled)
+        {
+                if(strncmp(caller-&gt;destination_number, &quot;sip:&quot;, 4)==0)
+                        *pstrCalled=caller-&gt;destination_number+4;
+                else
+                        *pstrCalled=caller-&gt;destination_number;
+
+                std::string::size_type i=(*pstrCalled).find(&quot;@&quot;);
+                if(i!=(*pstrCalled).npos)
+                {
+                        (*pstrCalled).erase(i);
+                }        
+        }
+
+        switch_core_session_rwunlock(session);
+        return true;
+}
+
+bool FreeSWITCH::PrepareCallData(const char* uuid, const char* uuid2, const char* channel, FreeSwitchDevice** ppDevice, FreeSwitchCall** ppCall, FreeSwitchConnection** ppConnection, bool bCreateCall, FreeSwitchDevice** ppQueue, FreeSwitchDevice** ppInboundNID, FreeSwitchDevice** ppOutboundNID, string* pstrCaller, string* pstrCalled)
+{
+        if(!ppDevice || !ppCall)
+        {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::PrepareCallData: mandatory parameter is null.\n&quot;);
+                return false;
+        }
+        
+        //Finding call:
+        if( !(*ppCall=GetCall(uuid)) &amp;&amp; !(uuid2 &amp;&amp; (*ppCall=GetCall(uuid2))) )
+        {
+                if(!bCreateCall)
+                {
+                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, &quot;FreeSWITCH::PrepareCallData: call %s [or %s] not found.\n&quot;,uuid, uuid2?uuid2:&quot;NULL&quot;);
+                        return false;
+                }
+                        
+                *ppCall=new FreeSwitchCall();
+                (*ppCall)-&gt;strUUID=uuid;
+                m_CallMap[(*ppCall)-&gt;strUUID]=*ppCall;
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::PrepareCallData: call %s created.\n&quot;,(*ppCall)-&gt;strUUID.c_str());
+        }        
+
+        //Finding the subscriber:
+        if(strncmp(channel,&quot;sofia/external&quot;,14)==0)
+        {
+                //Network interface - finding later
+                *ppDevice=NULL;
+        }
+        else
+        {
+                //Internal subscriber
+                string device=FreeSwitchDevice::Channel2Device(channel);
+                if(!device.size())
+                {                        
+                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::PrepareCallData: Channel %s not recognized.\n&quot;,channel);
+                        return false;
+                }
+                *ppDevice=PrepareDevice(device.c_str());        
+                if(!(*ppDevice))
+                {
+                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::PrepareCallData: Device %s not recognized.\n&quot;,device.c_str());
+                        return false;
+                }        
+        }
+        if(!*ppDevice || ppQueue || ppInboundNID || ppOutboundNID)
+        {
+
+                //Collecting special devices from the call &amp; finding network subscriber:
+                for(MapStr2Device::iterator it=(*ppCall)-&gt;devices.begin();it!=(*ppCall)-&gt;devices.end();it++)
+                {
+                        if(ppQueue &amp;&amp; it-&gt;second-&gt;GetDeviceType()==type_queue)
+                        {
+                                *ppQueue=it-&gt;second;                        
+                        }
+                        else
+                        if(it-&gt;second-&gt;GetDeviceType()==type_network_interface)
+                        {
+                                FreeSwitchConnection* pTempConn=it-&gt;second-&gt;FindConnection(*ppCall);
+                                if(!pTempConn)
+                                {
+                                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, &quot;FreeSWITCH::PrepareCallData: trunk %s is mapped to call %s without connection????\n&quot;,it-&gt;second-&gt;GetDeviceID().c_str(),(*ppCall)-&gt;strUUID.c_str());
+                                        continue;
+                                }
+                                if(ppInboundNID &amp;&amp; pTempConn-&gt;direction==direction_incoming)
+                                        *ppInboundNID=it-&gt;second;
+                                else
+                                if(ppOutboundNID &amp;&amp; pTempConn-&gt;direction==direction_outgoing)
+                                        *ppOutboundNID=it-&gt;second;
+
+                                if( (!*ppDevice) &amp;&amp; (pTempConn-&gt;strChannel==channel) )
+                                        *ppDevice=it-&gt;second;        
+                                
+                                if( (!*ppDevice) &amp;&amp; (pTempConn-&gt;strChannel.size()==0) &amp;&amp; (pTempConn-&gt;direction==direction_outgoing) )
+                                {
+                                        //External outbound call: the device was created before the FS channel, updating the data.                                 
+                                        *ppDevice=it-&gt;second;
+                                        pTempConn-&gt;strUUID=uuid;
+                                        pTempConn-&gt;strChannel=channel;
+                                }
+                        }
+                }
+        }
+
+        if(!*ppDevice)
+        {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::PrepareCallData: Device for channel %s not recognized.\n&quot;,channel);
+                return false;
+        }
+
+        //Finding connection:
+        if(ppConnection)
+                *ppConnection=(*ppDevice)-&gt;FindConnection(*ppCall);
+        
+        
+        //Finding caller &amp; called
+        if(pstrCaller || pstrCalled)
+        {                
+                FindCallerCalled(uuid, pstrCaller, pstrCalled);                
+        }
+
+        return true;
+}
+
+
+
+void FreeSWITCH::OnChannelCreate(switch_event_t *event)
+{                
+        const char* channel=switch_event_get_header(event, &quot;Channel-Name&quot;);
+        if(!channel || strstr(channel,&quot;sofia/external&quot;))        //External inbound calls are handled in OnCallNetworkIncoming
+                return;
+        
+        string device=FreeSwitchDevice::Channel2Device(channel);
+        if(!device.size())
+        {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::OnChannelCreate: Channel %s not recognized.\n&quot;,channel);
+                return;
+        }
+        switch_mutex_lock(m_mutex);
+        FreeSwitchDevice* pDevice=PrepareDevice(device.c_str());
+        if(!pDevice)        
+                return;
+        const char* direction=switch_event_get_header(event, &quot;Call-Direction&quot;);
+        const char* uuid=switch_event_get_header(event, &quot;Unique-ID&quot;);
+        if(                !direction || !uuid 
+                || (strcmp(direction, &quot;inbound&quot;) &amp;&amp; !pDevice-&gt;IsMakeCallOriginator()) )        //direction= &quot;inbound&quot; means outgoing call, direction is wrong from some reason
+        {
+                switch_mutex_unlock(m_mutex);
+                return;
+        }
+
+        if(GetCall(uuid))
+        {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::OnChannelCreate: Call %s already exists.\n&quot;,uuid);
+                switch_mutex_unlock(m_mutex);
+                return;
+        }
+
+        FreeSwitchCall* pCall=new FreeSwitchCall();
+        pCall-&gt;strUUID=uuid;
+        m_CallMap[pCall-&gt;strUUID]=pCall;
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::OnChannelCreate: call %s created.\n&quot;,pCall-&gt;strUUID.c_str());
+
+        pDevice-&gt;AddConnection(uuid, switch_event_get_header(event, &quot;Channel-Name&quot;), pCall,direction_outgoing);
+        if(pDevice-&gt;IsMonitored())
+        {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::OnChannelCreate: ServiceInitiated device: %s, call: %s.\n&quot;,pDevice-&gt;GetDeviceID().c_str(),uuid);
+                ServiceInitiatedEvent si(ConnectionID(pDevice-&gt;GetDeviceID(),pCall-&gt;strUUID));
+                if(pDevice-&gt;IsMakeCallOriginator())
+                        si.SetEventCause(CAUSE_MAKE_CALL);
+                pDevice-&gt;SendEvent(&amp;si);
+        }
+        switch_mutex_unlock(m_mutex);
+}
+
+
+void FreeSWITCH::OnProgress(switch_event_t *event)
+{
+        const char* channel=switch_event_get_header(event, &quot;Channel-Name&quot;);
+        const char* uuid=switch_event_get_header(event, &quot;Unique-ID&quot;);
+        const char* uuid2=switch_event_get_header(event, &quot;Other-Leg-Unique-ID&quot;);
+        if(!channel || !uuid)                                
+                return;        
+        
+        FreeSwitchCall* pCall;        
+        FreeSwitchDevice* pDevice=NULL, *pInboundNIDDevice=NULL, *pOutboundNIDDevice=NULL;
+        string caller, called;
+        FreeSwitchConnection* pConnection=NULL;
+        
+        switch_mutex_lock(m_mutex);
+        if(!PrepareCallData(uuid, uuid2, channel, &amp;pDevice, &amp;pCall, &amp;pConnection, true, NULL, &amp;pInboundNIDDevice, &amp;pOutboundNIDDevice, &amp;caller, &amp;called))
+        {
+                switch_mutex_unlock(m_mutex);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::OnProgress: PrepareCallData failed.\n&quot;);
+                return;
+        }
+        
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::OnProgress: %s device: %s, call: %s [%s].\n&quot;,event-&gt;event_id==SWITCH_EVENT_CHANNEL_PROGRESS?&quot;CHANNEL_PROGRESS&quot;:&quot;CHANNEL_PROGRESS_MEDIA&quot;,pDevice-&gt;GetDeviceID().c_str(), uuid, uuid2?uuid2:&quot;NULL&quot;);
+                
+        if(!pConnection)
+        {
+                pConnection=pDevice-&gt;AddConnection(uuid,channel,pCall,direction_incoming);
+                pConnection-&gt;state=STATE_ALERTING;
+        }
+        else
+                pConnection-&gt;state=STATE_CONNECTED;
+                        
+        DeviceID alertingDevice(called);
+
+        OriginatedEvent oe(ConnectionID(caller,pCall-&gt;strUUID), caller, called);        
+        oe.SetLocalConnectionInfo(STATE_CONNECTED);
+        DeliveredEvent de(ConnectionID(alertingDevice,pCall-&gt;strUUID), alertingDevice, caller, called);
+        de.SetLocalConnectionInfo(pConnection-&gt;state);
+
+        if(pInboundNIDDevice)
+        {
+                oe.SetNetworkCalledDevice(called);
+                oe.SetNetworkCallingDevice(caller);
+                oe.SetAssociatedCallingDevice(DeviceID(typeOfNumberDevice,pInboundNIDDevice-&gt;GetDeviceID()));
+
+                de.SetNetworkCalledDevice(called);
+                de.SetNetworkCallingDevice(caller);
+                de.SetAssociatedCallingDevice(DeviceID(typeOfNumberDevice,pInboundNIDDevice-&gt;GetDeviceID()));
+        }
+        if(pOutboundNIDDevice)
+        {
+                de.SetAssociatedCalledDevice(DeviceID(typeOfNumberDevice,pOutboundNIDDevice-&gt;GetDeviceID()));
+                de.SetConnection(ConnectionID(DeviceID(typeOfNumberDevice,pOutboundNIDDevice-&gt;GetDeviceID()),pCall-&gt;strUUID));
+        }
+                
+        if(pDevice-&gt;IsMonitored())
+        {
+                if(pConnection-&gt;state==STATE_CONNECTED)
+                        pDevice-&gt;SendEvent(&amp;oe);
+                pDevice-&gt;SendEvent(&amp;de);                
+        }
+
+        switch_mutex_unlock(m_mutex);
+}
+
+
+void FreeSWITCH::OnChannelAnswer(switch_event_t *event)
+{
+        const char* channel=switch_event_get_header(event, &quot;Channel-Name&quot;);
+        const char* uuid=switch_event_get_header(event, &quot;Unique-ID&quot;);
+        const char* uuid2=switch_event_get_header(event, &quot;Other-Leg-Unique-ID&quot;);
+        if(!channel || !uuid)                                
+                return;        
+        
+        FreeSwitchCall* pCall;        
+        FreeSwitchDevice* pDevice=NULL, *pQueueDevice=NULL, *pInboundNIDDevice=NULL, *pOutboundNIDDevice=NULL;
+        string caller, called;
+        FreeSwitchConnection* pConnection=NULL;
+        
+        switch_mutex_lock(m_mutex);
+        if(!PrepareCallData(uuid, uuid2, channel, &amp;pDevice, &amp;pCall, &amp;pConnection, true, &amp;pQueueDevice, &amp;pInboundNIDDevice, &amp;pOutboundNIDDevice, &amp;caller, &amp;called))
+        {
+                switch_mutex_unlock(m_mutex);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::OnChannelAnswer: PrepareCallData failed.\n&quot;);
+                return;
+        }
+        
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::OnChannelAnswer: CHANNEL_ANSWER device: %s, call: %s [%s].\n&quot;,pDevice-&gt;GetDeviceID().c_str(), uuid, uuid2?uuid2:&quot;NULL&quot;);
+                
+        if(!pConnection)
+        {
+                pConnection=pDevice-&gt;AddConnection(uuid,channel,pCall,direction_incoming);
+        }
+
+        pConnection-&gt;state=STATE_CONNECTED;
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::OnChannelAnswer: Established device: %s, call: %s.\n&quot;,pDevice-&gt;GetDeviceID().c_str(),pCall-&gt;strUUID.c_str());
+                
+        DeviceID answeringDevice;
+        if(pQueueDevice)
+        {
+                answeringDevice.SetCallNr(pQueueDevice-&gt;GetDeviceID().c_str());
+                answeringDevice.SetTypeOfNumber(typeOfNumberDevice);
+        }
+        else
+        {
+                answeringDevice.SetCallNr(called);
+        }
+        EstablishedEvent ee(ConnectionID(answeringDevice,pCall-&gt;strUUID), answeringDevice, caller, called);
+
+        if(pInboundNIDDevice)
+        {
+                ee.SetNetworkCalledDevice(called);
+                ee.SetNetworkCallingDevice(caller);
+                ee.SetAssociatedCallingDevice(DeviceID(typeOfNumberDevice,pInboundNIDDevice-&gt;GetDeviceID()));
+        }
+        if(pOutboundNIDDevice)
+        {
+                ee.SetAssociatedCalledDevice(DeviceID(typeOfNumberDevice,pOutboundNIDDevice-&gt;GetDeviceID()));
+                ee.SetEstablishedConnection(ConnectionID(DeviceID(typeOfNumberDevice,pOutboundNIDDevice-&gt;GetDeviceID()),pCall-&gt;strUUID));
+        }
+                
+        if(pDevice-&gt;IsMonitored())
+                pDevice-&gt;SendEvent(&amp;ee);        
+                
+        if(pQueueDevice &amp;&amp; pQueueDevice-&gt;IsMonitored())
+                pQueueDevice-&gt;SendEvent(&amp;ee);        
+
+        switch_mutex_unlock(m_mutex);
+}
+
+void FreeSWITCH::OnChannelHangup(switch_event_t *event)
+{
+        char* channel=switch_event_get_header(event, &quot;Channel-Name&quot;);
+        const char* uuid=switch_event_get_header(event, &quot;Unique-ID&quot;);
+        const char* uuid2=switch_event_get_header(event, &quot;Other-Leg-Unique-ID&quot;);
+        const char* cause=switch_event_get_header(event, &quot;Hangup-Cause&quot;);
+        if(!channel || !uuid)                                
+                return;        
+
+        FreeSwitchCall* pCall=NULL;        
+        FreeSwitchDevice* pDevice=NULL, *pQueueDevice=NULL;        
+
+        switch_mutex_lock(m_mutex);
+        if(!PrepareCallData(uuid, uuid2, channel, &amp;pDevice, &amp;pCall, NULL, false, NULL, NULL, NULL, NULL, NULL))
+        {
+                switch_mutex_unlock(m_mutex);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::OnChannelHangup: PrepareCallData failed.\n&quot;);
+                return;
+        }        
+        
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::OnChannelHangup: CHANNEL_HANGUP device: %s, call: %s [%s], cause: %s.\n&quot;,pDevice-&gt;GetDeviceID().c_str(),uuid, uuid2?uuid2:&quot;NULL&quot;, cause?cause:&quot;NULL&quot;);
+
+        ConnectionClearedEvent cc(ConnectionID(pDevice-&gt;GetDeviceID(),pCall-&gt;strUUID));
+
+        //Setting cause
+        if(!cause || !strcmp(cause,&quot;NORMAL_CLEARING&quot;) )
+                cc.SetEventCause(CAUSE_NORMAL_CLEARING);
+        else
+        if(!strcmp(cause,&quot;NO_ROUTE_DESTINATION&quot;))
+                cc.SetEventCause(CAUSE_DEST_NOT_OBTAINABLE);
+        else
+        if(!strcmp(cause,&quot;USER_BUSY&quot;))
+                cc.SetEventCause(CAUSE_BUSY);
+        if(!strcmp(cause,&quot;ORIGINATOR_CANCEL&quot;))
+                cc.SetEventCause(CAUSE_CALL_NOT_ANSWERED);
+
+        int devices_in_call=pCall-&gt;devices.size();        
+        //Sending event to all devices in the call
+        FreeSwitchConnection* pConnection=NULL;
+        for(MapStr2Device::iterator it=pCall-&gt;devices.begin();it!=pCall-&gt;devices.end();it++)
+        {                
+                pConnection=it-&gt;second-&gt;FindConnection(pCall-&gt;strUUID.c_str());
+                if(!pConnection)
+                {
+                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::OnChannelHangup: Device %s could not have connection to %s.&quot;,it-&gt;second-&gt;GetDeviceID().c_str(),pCall-&gt;strUUID.c_str());
+                        continue;
+                }
+                
+                if(it-&gt;second-&gt;GetDeviceType()==type_queue)
+                {
+                        pConnection-&gt;state=STATE_NULL;        
+                        pQueueDevice=it-&gt;second;
+                }
+                else
+                if(it-&gt;second==pDevice)                        
+                        pConnection-&gt;state=STATE_NULL;        //The terminated device
+                else
+                if(devices_in_call&lt;=2)
+                        pConnection-&gt;state=STATE_FAIL;        //If only one device remain, it will be in failed state
+                                                                                        //If more than one devices remain (conference), they will have the original state.        
+                
+                if(it-&gt;second-&gt;IsMonitored())
+                {                        
+                        cc.SetLocalConnectionInfo(pConnection-&gt;state);
+                        it-&gt;second-&gt;SendEvent(&amp;cc);                        
+                }        
+        }
+        pDevice-&gt;DeleteConnection(pCall);
+        if(pQueueDevice)
+        {
+                if(pQueueDevice-&gt;IsMonitored())
+                {
+                        ConnectionClearedEvent cc2(ConnectionID(DeviceID(typeOfNumberDevice,pQueueDevice-&gt;GetDeviceID()),pCall-&gt;strUUID));
+                        cc2.SetLocalConnectionInfo(STATE_NULL);
+                        cc2.SetEventCause(cc.GetEventCause());
+                        pQueueDevice-&gt;SendEvent(&amp;cc2);
+                }
+                pQueueDevice-&gt;DeleteConnection(pCall);
+        }
+
+        if(pCall-&gt;devices.size()==0)
+        {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::OnChannelHangup: call %s deleted.\n&quot;,pCall-&gt;strUUID.c_str());
+                m_CallMap.erase(pCall-&gt;strUUID);
+                delete pCall;
+        }        
+        switch_mutex_unlock(m_mutex);
+}
+
+void FreeSWITCH::OnDtmf(switch_event_t *event)
+{
+        char* channel=switch_event_get_header(event, &quot;Channel-Name&quot;);
+        const char* uuid=switch_event_get_header(event, &quot;Unique-ID&quot;);        
+        const char* uuid2=switch_event_get_header(event, &quot;Other-Leg-Unique-ID&quot;);
+        if(!channel || !uuid)                                
+                return;        
+
+        FreeSwitchCall* pCall=NULL;        
+        FreeSwitchDevice* pDevice=NULL, *pQueueDevice=NULL;        
+        
+        switch_mutex_lock(m_mutex);
+        
+        if(!PrepareCallData(uuid, uuid2, channel, &amp;pDevice, &amp;pCall, NULL, false, &amp;pQueueDevice, NULL, NULL, NULL, NULL))
+        {
+                switch_mutex_unlock(m_mutex);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::OnDtmf: PrepareCallData failed.\n&quot;);
+                return;
+        }        
+
+        const char* digit=switch_event_get_header(event, &quot;DTMF-Digit&quot;);
+        if(!digit)        
+        {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::OnDtmf: DTMF-Digit not found in event.&quot;);
+                switch_mutex_unlock(m_mutex);
+                return;
+        }
+
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::OnDtmf: DTMF device: %s, call: %s \n&quot;,pDevice-&gt;GetDeviceID().c_str(),pCall-&gt;strUUID.c_str());
+        
+        DeviceID dev(pDevice-&gt;GetDeviceType()==type_internal_subscriber?typeOfNumberDialable:typeOfNumberDevice,pDevice-&gt;GetDeviceID());
+        DtmfDetectedEvent dd(ConnectionID(dev,pCall-&gt;strUUID),digit[0]);
+
+        if(pDevice-&gt;IsMonitored())
+                pDevice-&gt;SendEvent(&amp;dd);
+        
+        if(pQueueDevice &amp;&amp; pQueueDevice-&gt;IsMonitored())        
+                pQueueDevice-&gt;SendEvent(&amp;dd);
+
+        switch_mutex_unlock(m_mutex);
+
+}
+
+void FreeSWITCH::OnPlayback(switch_event_t *event)
+{
+        char* channel=switch_event_get_header(event, &quot;Channel-Name&quot;);
+        const char* uuid=switch_event_get_header(event, &quot;Unique-ID&quot;);        
+        const char* uuid2=switch_event_get_header(event, &quot;Other-Leg-Unique-ID&quot;);
+        if(!channel || !uuid)                                
+                return;        
+
+        FreeSwitchCall* pCall=NULL;        
+        FreeSwitchDevice* pDevice=NULL;        
+        
+        switch_mutex_lock(m_mutex);
+        
+        if(!PrepareCallData(uuid, uuid2, channel, &amp;pDevice, &amp;pCall, NULL, false, NULL, NULL, NULL, NULL, NULL))
+        {
+                switch_mutex_unlock(m_mutex);
+                if(event-&gt;event_id!=SWITCH_EVENT_CHANNEL_EXECUTE_COMPLETE)        //Could be normal if call terminates during playback.
+                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::OnPlayback: PrepareCallData failed.\n&quot;);
+                return;
+        }        
+
+        const char* file=switch_event_get_header(event, &quot;Application-Data&quot;);
+        if(!file)
+        {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::OnPlayback: Filename not found in event.\n&quot;);
+                switch_mutex_unlock(m_mutex);
+                return;
+        }
+        
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::OnPlayback: device: %s, call: %s \n&quot;,pDevice-&gt;GetDeviceID().c_str(),pCall-&gt;strUUID.c_str());
+        
+        DeviceID dev(pDevice-&gt;GetDeviceType()==type_internal_subscriber?typeOfNumberDialable:typeOfNumberDevice,pDevice-&gt;GetDeviceID());
+        
+        CSTAEvent* pEvent=NULL;
+        if(event-&gt;event_id==SWITCH_EVENT_CHANNEL_EXECUTE_COMPLETE)
+        {
+                pEvent=new StopEvent(ConnectionID(dev,pCall-&gt;strUUID),file);
+                char* result=switch_event_get_header(event, &quot;Application-Response&quot;);
+                if(result)
+                {
+                        if(        strcmp(result, &quot;FILE PLAYED&quot;)==0)
+                                pEvent-&gt;SetEventCause(CAUSE_END_OF_MESSAGE_DETECTED);
+                        else
+                        if(strcmp(result, &quot;FILE NOT FOUND&quot;)==0)
+                                pEvent-&gt;SetEventCause(CAUSE_RESOURCES_NOT_AVAILABLE);
+                        else
+                        if(strcmp(result, &quot;PLAYBACK ERROR&quot;)==0)
+                                pEvent-&gt;SetEventCause(CAUSE_BLOCKED);
+                }                
+        }
+        else
+        {
+                pEvent=new PlayEvent(ConnectionID(dev,pCall-&gt;strUUID),file);
+        }
+
+        for(MapStr2Device::iterator it=pCall-&gt;devices.begin();it!=pCall-&gt;devices.end();it++)
+        {
+                if(it-&gt;second-&gt;IsMonitored())                
+                        it-&gt;second-&gt;SendEvent(pEvent);                
+        }
+
+        delete pEvent;
+
+        switch_mutex_unlock(m_mutex);
+}
+
+void FreeSWITCH::OnRecord(switch_event_t *event)
+{
+        char* channel=switch_event_get_header(event, &quot;Channel-Name&quot;);
+        const char* uuid=switch_event_get_header(event, &quot;Unique-ID&quot;);        
+        const char* uuid2=switch_event_get_header(event, &quot;Other-Leg-Unique-ID&quot;);
+        if(!channel || !uuid)                                
+                return;        
+
+        FreeSwitchCall* pCall=NULL;        
+        FreeSwitchDevice* pDevice=NULL;        
+        
+        switch_mutex_lock(m_mutex);
+        
+        if(!PrepareCallData(uuid, uuid2, channel, &amp;pDevice, &amp;pCall, NULL, false, NULL, NULL, NULL, NULL, NULL))
+        {
+                switch_mutex_unlock(m_mutex);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::OnRecord: PrepareCallData failed.\n&quot;);
+                return;
+        }        
+        
+        char* p=switch_event_get_header(event, &quot;Application-Data&quot;);
+        if(!p)
+        {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::OnRecord: Filename not found in event.\n&quot;);
+                switch_mutex_unlock(m_mutex);
+                return;
+        }
+
+        char file[MAX_PATH];
+        strcpy(file,p);        
+        p=strstr(file,&quot;.wav &quot;);
+        if(p)
+                p[4]=0;        //cutting length parameter
+        
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::OnRecord: device: %s, call: %s \n&quot;,pDevice-&gt;GetDeviceID().c_str(),pCall-&gt;strUUID.c_str());
+        
+        DeviceID dev(pDevice-&gt;GetDeviceType()==type_internal_subscriber?typeOfNumberDialable:typeOfNumberDevice,pDevice-&gt;GetDeviceID());
+        
+        CSTAEvent* pEvent=NULL;
+        if(event-&gt;event_id==SWITCH_EVENT_CHANNEL_EXECUTE_COMPLETE)
+        {
+                pEvent=new StopEvent(ConnectionID(dev,pCall-&gt;strUUID),file);
+                pEvent-&gt;SetEventCause(CAUSE_MESSAGE_DURATION_EXCEEDED);                
+        }
+        else
+        {
+                pEvent=new RecordEvent(ConnectionID(dev,pCall-&gt;strUUID),file);
+        }
+
+        for(MapStr2Device::iterator it=pCall-&gt;devices.begin();it!=pCall-&gt;devices.end();it++)
+        {
+                if(it-&gt;second-&gt;IsMonitored())                
+                        it-&gt;second-&gt;SendEvent(pEvent);                
+        }
+
+        delete pEvent;
+
+        switch_mutex_unlock(m_mutex);
+}
+
+
+void FreeSWITCH::OnCallQueued(const char* queue, switch_core_session_t *session)
+{
+        const char* uuid=switch_core_session_get_uuid(session);
+        switch_channel_t* channel=switch_core_session_get_channel(session);
+        switch_caller_profile_t * caller=switch_channel_get_caller_profile(channel);        
+
+        switch_mutex_lock(m_mutex);
+        
+        FreeSwitchDevice* pDevice=PrepareDevice(queue,type_queue);
+        if(!pDevice)        
+                return;
+
+        FreeSwitchCall* pCall=GetCall(uuid);
+        if(!pCall)
+        {
+                pCall=new FreeSwitchCall();
+                pCall-&gt;strUUID=uuid;
+                m_CallMap[pCall-&gt;strUUID]=pCall;
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::OnCallQueued: call %s created.\n&quot;,pCall-&gt;strUUID.c_str());
+        }
+        
+        FreeSwitchConnection* pConnection=pDevice-&gt;AddConnection(uuid, switch_channel_get_name(channel),pCall, direction_incoming);
+        pConnection-&gt;state=STATE_QUEUED;
+        QueuedEvent qe(ConnectionID(DeviceID(typeOfNumberDevice,pDevice-&gt;GetDeviceID()),uuid),DeviceID(typeOfNumberDevice,pDevice-&gt;GetDeviceID()),caller-&gt;caller_id_number, caller-&gt;destination_number);
+        
+        if(strstr(caller-&gt;chan_name,&quot;sofia/external&quot;))
+        {                
+                qe.SetNetworkCallingDevice(caller-&gt;caller_id_number);
+                qe.SetNetworkCalledDevice(caller-&gt;destination_number);
+                for(MapStr2Device::iterator it=pCall-&gt;devices.begin();it!=pCall-&gt;devices.end();it++)                
+                        if(it-&gt;second-&gt;GetDeviceType()==type_network_interface)
+                        {
+                                qe.SetAssociatedCallingDevice(DeviceID(typeOfNumberDevice,it-&gt;second-&gt;GetDeviceID()));
+                                break;
+                        }
+                
+        }        
+        qe.SetNumberQueued(pDevice-&gt;GetConnectionCount());
+        for(MapStr2Device::iterator it=pCall-&gt;devices.begin();it!=pCall-&gt;devices.end();it++)
+        {
+                //Sending queued event for the queue and the caller.
+                if(it-&gt;second-&gt;IsMonitored())                
+                        it-&gt;second-&gt;SendEvent(&amp;qe);
+        }
+
+
+        switch_mutex_unlock(m_mutex);
+}
+
+void FreeSWITCH::OnCallNetworkIncoming(const char* trunk, switch_core_session_t *session)
+{
+        const char* uuid=switch_core_session_get_uuid(session);
+        switch_channel_t* channel=switch_core_session_get_channel(session);        
+        //switch_caller_profile_t * caller=switch_channel_get_caller_profile(channel);
+
+        switch_mutex_lock(m_mutex);
+        
+        FreeSwitchDevice* pDevice=PrepareDevice(trunk,type_network_interface);
+        if(!pDevice)        
+                return;
+
+        FreeSwitchCall* pCall=GetCall(uuid);
+        if(!pCall)
+        {
+                pCall=new FreeSwitchCall();
+                pCall-&gt;strUUID=uuid;
+                m_CallMap[pCall-&gt;strUUID]=pCall;
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::OnCallNetworkIncoming: call %s created.\n&quot;,pCall-&gt;strUUID.c_str());
+        }
+        
+        FreeSwitchConnection* pConnection=pDevice-&gt;AddConnection(uuid, switch_channel_get_name(channel), pCall, direction_incoming);
+        pConnection-&gt;strChannel=switch_channel_get_name(channel);        
+        if(pDevice-&gt;IsMonitored())
+        {
+                ServiceInitiatedEvent si(ConnectionID(DeviceID(typeOfNumberDevice,pDevice-&gt;GetDeviceID()),uuid));
+                //TODO: add networkCallingDevice, networkCalledDevice, associatedCallingDevice fields
+                pDevice-&gt;SendEvent(&amp;si);
+        }
+        switch_mutex_unlock(m_mutex);
+}
+
+void FreeSWITCH::OnCallNetworkOutgoing(const char* trunk, switch_core_session_t *session)
+{
+        const char* uuid=switch_core_session_get_uuid(session);
+        //switch_channel_t* channel=switch_core_session_get_channel(session);        
+        //switch_caller_profile_t * caller=switch_channel_get_caller_profile(channel);
+
+        switch_mutex_lock(m_mutex);
+        
+        FreeSwitchDevice* pDevice=PrepareDevice(trunk,type_network_interface);
+        if(!pDevice)        
+                return;
+
+        FreeSwitchCall* pCall=GetCall(uuid);
+        if(!pCall)
+        {
+                pCall=new FreeSwitchCall();
+                pCall-&gt;strUUID=uuid;
+                m_CallMap[pCall-&gt;strUUID]=pCall;
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::OnCallNetworkOutgoing: call %s created.\n&quot;,pCall-&gt;strUUID.c_str());
+        }
+        
+        //outgoing uuid and channel name is not yet known.
+        pDevice-&gt;AddConnection(&quot;&quot;, &quot;&quot;, pCall, direction_outgoing);
+        
+        if(pDevice-&gt;IsMonitored())
+        {
+                //TODO: Network Reached
+        }
+        switch_mutex_unlock(m_mutex);
+}
+
+
+
+void FreeSWITCH::OnSessionFinished(CISession* sender)
+{
+        switch_mutex_lock(m_mutex);
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::OnSessionFinished: removing session 0x%08X\n&quot;,sender);
+        
+        try
+        {
+                for(MapStr2Device::iterator it=m_DeviceMap.begin();it!=m_DeviceMap.end();it++)
+                {
+                        it-&gt;second-&gt;RemoveMonitor(sender);
+                }
+        }
+        catch(...)
+        {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::OnSessionFinished: Exception.&quot;);
+        }
+
+        switch_mutex_unlock(m_mutex);        
+}
+
+void FreeSWITCH::MonitorStart(CISession* sender, MonitorStartRequest* pRequest)
+{        
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::MonitorStart: Request with InvokeID: %d\n:%s\n&quot;,pRequest-&gt;GetInvokeID(), pRequest-&gt;GetReadable().c_str());
+        
+        if(!pRequest-&gt;GetMonitorObject().GetCallNr().size())
+        {
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation, invalidMonitorObject);
+                sender-&gt;SendMsg(&amp;err);
+                return;
+        }
+        
+        
+        FreeSwitchDeviceType type=FreeSwitchDevice::Device2Type(pRequest-&gt;GetMonitorObject());
+        if(type==type_unknown)
+        {
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation, invalidMonitorObject);
+                sender-&gt;SendMsg(&amp;err);
+                return;
+        }
+
+        switch_mutex_lock(m_mutex);
+        FreeSwitchDevice* pDevice=PrepareDevice(pRequest-&gt;GetMonitorObject().GetCallNr().c_str()+(type==type_internal_subscriber?0:2), type);
+        
+        string crossRefID=pDevice-&gt;GetDeviceID().c_str();
+        for(crossRefID=pDevice-&gt;GetDeviceID();IsXRefIDUsed(crossRefID);crossRefID=GetNextXRefID());
+        
+        if(pDevice-&gt;AddMonitor(sender, crossRefID))
+        {
+                MonitorStartResponse resp(pRequest-&gt;GetInvokeID(),crossRefID);
+                sender-&gt;SendMsg(&amp;resp);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::MonitorStart: Response sent with InvokeID: %d\n:%s\n&quot;,resp.GetInvokeID(), resp.GetReadable().c_str());
+        }
+        else
+        {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::MonitorStart: AddMonitor failed.&quot;);
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation, invalidMonitorObject);
+                sender-&gt;SendMsg(&amp;err);
+        }
+        switch_mutex_unlock(m_mutex);
+}
+
+
+void FreeSWITCH::SnapshotDevice(CISession* sender, SnapshotDeviceRequest* pRequest)
+{
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::SnapshotDevice: Request with InvokeID: %d\n:%s\n&quot;,pRequest-&gt;GetInvokeID(), pRequest-&gt;GetReadable().c_str());
+        
+        FreeSwitchDeviceType type=FreeSwitchDevice::Device2Type(pRequest-&gt;GetSnapshotObject());
+        if(type==type_unknown)
+        {
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation, invalidDeviceID);
+                sender-&gt;SendMsg(&amp;err);
+                return;
+        }
+
+        switch_mutex_lock(m_mutex);
+        FreeSwitchDevice* pDevice=PrepareDevice(pRequest-&gt;GetSnapshotObject().GetCallNr().c_str()+(type==type_internal_subscriber?0:2), type);
+        
+        SnapshotDeviceResponse resp(pRequest-&gt;GetInvokeID());
+        
+        for(MapCall2Connection::iterator it=pDevice-&gt;connections.begin();it!=pDevice-&gt;connections.end();it++)        
+        {
+                SnapshotDeviceData data(ConnectionID(pRequest-&gt;GetSnapshotObject(),it-&gt;second-&gt;pCall-&gt;strUUID),it-&gt;second-&gt;state);
+                resp.AddSnapshotData(data);
+        }
+
+        sender-&gt;SendMsg(&amp;resp);
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::SnapshotDevice: Response sent with InvokeID: %d\n:%s\n&quot;,resp.GetInvokeID(), resp.GetReadable().c_str());
+
+        switch_mutex_unlock(m_mutex);
+}
+
+void FreeSWITCH::SnapshotCall(CISession* sender, SnapshotCallRequest* pRequest)
+{
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::SnapshotCall: Request with InvokeID: %d\n:%s\n&quot;,pRequest-&gt;GetInvokeID(), pRequest-&gt;GetReadable().c_str());
+
+        switch_mutex_lock(m_mutex);        
+        FreeSwitchCall* pCall=GetCall(pRequest-&gt;GetSnapshotObject().GetCallID().c_str());        
+        if(!pCall)
+                
+        {
+                switch_mutex_unlock(m_mutex);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::SnapshotCall: CallID %s not found.&quot;,pRequest-&gt;GetSnapshotObject().GetCallID().c_str());
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,invalidCallID);
+                sender-&gt;SendMsg(&amp;err);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::SnapshotCall: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                return;
+        }
+
+        SnapshotCallResponse resp(pRequest-&gt;GetInvokeID());
+        
+        for(MapStr2Device::iterator it=pCall-&gt;devices.begin();it!=pCall-&gt;devices.end();it++)
+        {
+                FreeSwitchConnection* pConn=it-&gt;second-&gt;FindConnection(pCall); 
+                SnapshotCallData data(it-&gt;second-&gt;GetDeviceID(),pConn?pConn-&gt;state:STATE_NULL);                
+                resp.AddSnapshotData(data);
+        }
+        string caller, called;
+        FindCallerCalled(pCall-&gt;strUUID.c_str(), &amp;caller, &amp;called);
+        resp.SetCallingDevice(caller);
+        resp.SetCalledDevice(called);
+
+        sender-&gt;SendMsg(&amp;resp);
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::SnapshotDevice: Response sent with InvokeID: %d\n:%s\n&quot;,resp.GetInvokeID(), resp.GetReadable().c_str());
+
+        switch_mutex_unlock(m_mutex);
+
+}
+
+
+void FreeSWITCH::MakeCall(CISession* sender, MakeCallRequest* pRequest)
+{
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::MakeCall: Request with InvokeID: %d\n:%s\n&quot;,pRequest-&gt;GetInvokeID(), pRequest-&gt;GetReadable().c_str());
+
+        switch_channel_t *caller_channel;
+        switch_core_session_t *caller_session = NULL;
+        char aleg[400], exten[400];
+        uint32_t timeout = 60;
+        switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING;
+        FreeSwitchDevice* pDevice=NULL;
+                
+        if(pRequest-&gt;GetCallingDevice().GetTypeOfNumber()==typeOfNumberDialable)
+        {
+                sprintf(aleg,&quot;%ssofia/internal/%s%s%s&quot;,pRequest-&gt;GetAutoOriginate()==ORIGINATE_DO_NOT_PROMPT?&quot;{sip_auto_answer=true}&quot;:&quot;&quot;,pRequest-&gt;GetCallingDevice().GetCallNr().c_str(),&quot;%&quot;,switch_core_get_variable(&quot;domain&quot;));
+                pDevice=PrepareDevice(pRequest-&gt;GetCallingDevice().GetCallNr().c_str());
+                pDevice-&gt;SetMakeCallOriginator(true);
+        }
+        else
+        {
+                sprintf(aleg,&quot;loopback/%s&quot;,pRequest-&gt;GetCallingDevice().GetCallNr().c_str()+2);
+        }
+        sprintf(exten,&quot;%s&quot;,pRequest-&gt;GetCalledDirectoryNumber().GetCallNr().c_str());
+                
+        if (switch_ivr_originate(NULL, &amp;caller_session, &amp;cause, aleg, timeout, NULL, &quot;CSTA&quot;, pRequest-&gt;GetCallingDevice().GetCallNr().c_str(), NULL, NULL, SOF_NONE) != SWITCH_STATUS_SUCCESS        || !caller_session) 
+        {                
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;-ERR Cannot Create Outgoing Channel! [%s] cause: %s\n&quot;, aleg, switch_channel_cause2str(cause));
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,genericError); //TODO: refine error code
+                sender-&gt;SendMsg(&amp;err);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::MakeCall: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                if(pDevice)
+                        pDevice-&gt;SetMakeCallOriginator(false);
+                return;
+        }
+
+        caller_channel = switch_core_session_get_channel(caller_session);
+        switch_channel_clear_state_handler(caller_channel, NULL);
+        
+        switch_ivr_session_transfer(caller_session, exten, &quot;XML&quot;, &quot;default&quot;);        
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;+OK Created Session: %s\n&quot;, switch_core_session_get_uuid(caller_session));
+        
+        MakeCallResponse resp(pRequest-&gt;GetInvokeID(),ConnectionID(pRequest-&gt;GetCallingDevice(),switch_core_session_get_uuid(caller_session)));
+        sender-&gt;SendMsg(&amp;resp);
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::MakeCall: Response sent with InvokeID: %d\n:%s\n&quot;,resp.GetInvokeID(), resp.GetReadable().c_str());
+        if(pDevice)
+                pDevice-&gt;SetMakeCallOriginator(false);
+        
+        switch_core_session_rwunlock(caller_session);        
+        
+}
+
+
+void FreeSWITCH::AnswerCall(CISession* sender, AnswerCallRequest* pRequest)
+{
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::AnswerCall: Request with InvokeID: %d\n:%s\n&quot;,pRequest-&gt;GetInvokeID(), pRequest-&gt;GetReadable().c_str());
+
+        switch_mutex_lock(m_mutex);
+
+        FreeSwitchCall* pCall=GetCall(pRequest-&gt;GetCallToBeAnswered().GetCallID().c_str());        
+        if(!pCall)
+                
+        {
+                switch_mutex_unlock(m_mutex);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::AnswerCall: CallID %s not found.&quot;,pRequest-&gt;GetCallToBeAnswered().GetCallID().c_str());
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,invalidCallID); 
+                sender-&gt;SendMsg(&amp;err);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::AnswerCall: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                return;
+        }
+
+        FreeSwitchDevice * pDevice=pCall-&gt;GetDevice(pRequest-&gt;GetCallToBeAnswered().GetDeviceID()-&gt;GetCallNr());        
+        if(!pDevice)
+        {
+                switch_mutex_unlock(m_mutex);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::AnswerCall: Device %s not found.&quot;,pRequest-&gt;GetCallToBeAnswered().GetDeviceID()-&gt;GetCallNr().c_str());
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,invalidDeviceID); 
+                sender-&gt;SendMsg(&amp;err);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::AnswerCall: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                return;
+        }
+        FreeSwitchConnection* pConnection=pDevice-&gt;FindConnection(pCall);
+        if(!pConnection)
+        {
+                switch_mutex_unlock(m_mutex);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::AnswerCall: Connection %s/%s not found.&quot;,pRequest-&gt;GetCallToBeAnswered().GetDeviceID()-&gt;GetCallNr().c_str(),pRequest-&gt;GetCallToBeAnswered().GetCallID().c_str());
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,invalidDeviceID); 
+                sender-&gt;SendMsg(&amp;err);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::AnswerCall: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                return;
+        }
+        switch_core_session_t* session=switch_core_session_locate(pConnection-&gt;strUUID.c_str());
+
+        if(!session)
+        {
+                switch_mutex_unlock(m_mutex);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::AnswerCall: No session for CallID %s found.&quot;,pRequest-&gt;GetCallToBeAnswered().GetCallID().c_str());
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,invalidCallID); 
+                sender-&gt;SendMsg(&amp;err);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::AnswerCall: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                return;
+        }
+        switch_channel_t * channel=switch_core_session_get_channel(session);
+        switch_channel_clear_flag(channel, CF_PROXY_MEDIA);
+        switch_channel_clear_flag(channel, CF_PROXY_MODE);
+        if(switch_channel_answer(channel)==SWITCH_STATUS_SUCCESS)
+        {
+                AnswerCallResponse resp(pRequest-&gt;GetInvokeID());
+                sender-&gt;SendMsg(&amp;resp);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::AnswerCall: Response sent with InvokeID: %d\n:%s\n&quot;,resp.GetInvokeID(), resp.GetReadable().c_str());
+        }
+        else
+        {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::AnswerCall: switch_channel_answer failed.&quot;);
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,genericError); 
+                sender-&gt;SendMsg(&amp;err);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::AnswerCall: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+
+        }
+        switch_core_session_rwunlock(session);
+        
+        switch_mutex_unlock(m_mutex);
+}
+
+void FreeSWITCH::PlayMessage(CISession* sender, PlayMessageRequest* pRequest)
+{
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::PlayMessage: Request with InvokeID: %d\n:%s\n&quot;,pRequest-&gt;GetInvokeID(), pRequest-&gt;GetReadable().c_str());
+
+        switch_mutex_lock(m_mutex);
+
+        FreeSwitchCall* pCall=GetCall(pRequest-&gt;GetOverConnection().GetCallID().c_str());        
+        if(!pCall)
+                
+        {
+                switch_mutex_unlock(m_mutex);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::PlayMessage: CallID %s not found.&quot;,pRequest-&gt;GetOverConnection().GetCallID().c_str());
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,invalidCallID); 
+                sender-&gt;SendMsg(&amp;err);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::PlayMessage: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                return;
+        }
+
+        FreeSwitchDevice * pDevice=pCall-&gt;GetDevice(pRequest-&gt;GetOverConnection().GetDeviceID()-&gt;GetCallNr());        
+        if(!pDevice)
+        {
+                switch_mutex_unlock(m_mutex);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::PlayMessage: Device %s not found.&quot;,pRequest-&gt;GetOverConnection().GetDeviceID()-&gt;GetCallNr().c_str());
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,invalidDeviceID); 
+                sender-&gt;SendMsg(&amp;err);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::PlayMessage: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                return;
+        }
+        FreeSwitchConnection* pConnection=pDevice-&gt;FindConnection(pCall);
+        if(!pConnection)
+        {
+                switch_mutex_unlock(m_mutex);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::PlayMessage: Connection %s/%s not found.&quot;,pRequest-&gt;GetOverConnection().GetDeviceID()-&gt;GetCallNr().c_str(),pRequest-&gt;GetOverConnection().GetCallID().c_str());
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,invalidDeviceID); 
+                sender-&gt;SendMsg(&amp;err);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::PlayMessage: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                return;
+        }
+        
+        if(switch_ivr_broadcast(pConnection-&gt;strUUID.c_str(), pRequest-&gt;GetMessageToBePlayed().c_str(), SMF_ECHO_ALEG)==SWITCH_STATUS_SUCCESS)
+        {
+                PlayMessageResponse resp(pRequest-&gt;GetInvokeID());
+                sender-&gt;SendMsg(&amp;resp);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::PlayMessage: Response sent with InvokeID: %d\n:%s\n&quot;,resp.GetInvokeID(), resp.GetReadable().c_str());
+        }
+        else
+        {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::PlayMessage: switch_ivr_broadcast failed.&quot;);
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,genericError); 
+                sender-&gt;SendMsg(&amp;err);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::PlayMessage: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+        }
+
+        switch_mutex_unlock(m_mutex);
+}
+
+void FreeSWITCH::RecordMessage(CISession* sender, RecordMessageRequest* pRequest)
+{
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::RecordMessage: Request with InvokeID: %d\n:%s\n&quot;,pRequest-&gt;GetInvokeID(), pRequest-&gt;GetReadable().c_str());
+        
+        switch_mutex_lock(m_mutex);
+
+        FreeSwitchCall* pCall=GetCall(pRequest-&gt;GetCallToBeRecorded().GetCallID().c_str());        
+        if(!pCall)                
+        {
+                switch_mutex_unlock(m_mutex);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::RecordMessage: CallID %s not found.&quot;,pRequest-&gt;GetCallToBeRecorded().GetCallID().c_str());
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,invalidCallID); 
+                sender-&gt;SendMsg(&amp;err);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::RecordMessage: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                return;
+        }
+
+        FreeSwitchDevice * pDevice=pCall-&gt;GetDevice(pRequest-&gt;GetCallToBeRecorded().GetDeviceID()-&gt;GetCallNr());        
+        if(!pDevice)
+        {
+                switch_mutex_unlock(m_mutex);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::RecordMessage: Device %s not found.&quot;,pRequest-&gt;GetCallToBeRecorded().GetDeviceID()-&gt;GetCallNr().c_str());
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,invalidDeviceID); 
+                sender-&gt;SendMsg(&amp;err);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::RecordMessage: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                return;
+        }
+        FreeSwitchConnection* pConnection=pDevice-&gt;FindConnection(pCall);
+        if(!pConnection)
+        {
+                switch_mutex_unlock(m_mutex);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::RecordMessage: Connection %s/%s not found.&quot;,pRequest-&gt;GetCallToBeRecorded().GetDeviceID()-&gt;GetCallNr().c_str(),pRequest-&gt;GetCallToBeRecorded().GetCallID().c_str());
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,invalidDeviceID); 
+                sender-&gt;SendMsg(&amp;err);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::RecordMessage: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                return;
+        }
+
+        switch_core_session_t *session=switch_core_session_locate(pConnection-&gt;strUUID.c_str());
+        if(!session)
+        {
+                switch_mutex_unlock(m_mutex);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::RecordMessage: Session %s not found.&quot;,pConnection-&gt;strUUID.c_str());
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,invalidCallID); 
+                sender-&gt;SendMsg(&amp;err);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::RecordMessage: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                return;
+        }
+        
+
+        if ((switch_channel_test_flag(switch_core_session_get_channel(session), CF_EVENT_PARSE))) 
+        {
+                switch_mutex_unlock(m_mutex);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::RecordMessage: Record or broadcast already in progress.&quot;);
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,genericError); 
+                sender-&gt;SendMsg(&amp;err);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::RecordMessage: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                return;
+        }
+
+        char filename[MAX_PATH];
+        sprintf(filename,&quot;%s-%X.wav&quot;,pRequest-&gt;GetCallToBeRecorded().GetCallID().c_str(),clock());
+        char arg[MAX_PATH+20];
+        
+        if(pRequest-&gt;GetMaxDuration()&gt;1000)
+        {
+                sprintf(arg, &quot;%s %d&quot;,filename,pRequest-&gt;GetMaxDuration()/1000);
+        }
+        else
+        {
+                strcpy(arg,filename);
+        }
+        
+    char path[MAX_PATH];          
+        strcat(path,switch_channel_get_variable(switch_core_session_get_channel(session), &quot;sound_prefix&quot;));
+        strcat(path,SWITCH_PATH_SEPARATOR);
+        strcat(path,filename);
+        
+        switch_event_t *event;
+        if (switch_event_create(&amp;event, SWITCH_EVENT_COMMAND) == SWITCH_STATUS_SUCCESS) 
+        {                
+                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;call-command&quot;, &quot;execute&quot;);
+                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;execute-app-name&quot;, &quot;record&quot;);
+                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;execute-app-arg&quot;, arg);                        
+                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;event-lock&quot;, &quot;true&quot;);
+                switch_core_session_queue_private_event(session, &amp;event);                
+
+                RecordMessageResponse resp(pRequest-&gt;GetInvokeID(),path);
+                sender-&gt;SendMsg(&amp;resp);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::RecordMessage: Response sent with InvokeID: %d\n:%s\n&quot;,resp.GetInvokeID(), resp.GetReadable().c_str());
+        }
+        else
+        {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::RecordMessage: switch_event_create failed.&quot;);
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,genericError); 
+                sender-&gt;SendMsg(&amp;err);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::RecordMessage: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+        }
+        switch_core_session_rwunlock(session);
+        switch_mutex_unlock(m_mutex);
+}
+
+void FreeSWITCH::StopMessage(CISession* sender, StopRequest* pRequest)
+{
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::StopMessage: Request with InvokeID: %d\n:%s\n&quot;,pRequest-&gt;GetInvokeID(), pRequest-&gt;GetReadable().c_str());
+        
+        switch_mutex_lock(m_mutex);
+
+        FreeSwitchCall* pCall=GetCall(pRequest-&gt;GetConnection().GetCallID().c_str());        
+        if(!pCall)                
+        {
+                switch_mutex_unlock(m_mutex);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::StopMessage: CallID %s not found.&quot;,pRequest-&gt;GetConnection().GetCallID().c_str());
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,invalidCallID); 
+                sender-&gt;SendMsg(&amp;err);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::StopMessage: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                return;
+        }
+
+        FreeSwitchDevice * pDevice=pCall-&gt;GetDevice(pRequest-&gt;GetConnection().GetDeviceID()-&gt;GetCallNr());        
+        if(!pDevice)
+        {
+                switch_mutex_unlock(m_mutex);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::StopMessage: Device %s not found.&quot;,pRequest-&gt;GetConnection().GetDeviceID()-&gt;GetCallNr().c_str());
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,invalidDeviceID); 
+                sender-&gt;SendMsg(&amp;err);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::StopMessage: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                return;
+        }
+        FreeSwitchConnection* pConnection=pDevice-&gt;FindConnection(pCall);
+        if(!pConnection)
+        {
+                switch_mutex_unlock(m_mutex);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::StopMessage: Connection %s/%s not found.&quot;,pRequest-&gt;GetConnection().GetDeviceID()-&gt;GetCallNr().c_str(),pRequest-&gt;GetConnection().GetCallID().c_str());
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,invalidDeviceID); 
+                sender-&gt;SendMsg(&amp;err);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::StopMessage: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                return;
+        }
+
+        switch_core_session_t *session=switch_core_session_locate(pConnection-&gt;strUUID.c_str());
+        if(!session)
+        {
+                switch_mutex_unlock(m_mutex);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::StopMessage: Session %s not found.&quot;,pConnection-&gt;strUUID.c_str());
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,invalidCallID); 
+                sender-&gt;SendMsg(&amp;err);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::StopMessage: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                return;
+        }        
+
+        if (!switch_channel_test_flag(switch_core_session_get_channel(session), CF_EVENT_PARSE)) 
+        {
+                switch_mutex_unlock(m_mutex);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::RecordMessage:No record or broadcast running.&quot;);
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,genericError); 
+                sender-&gt;SendMsg(&amp;err);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::RecordMessage: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                return;
+        }        
+        
+        switch_ivr_stop_record_session(session, pRequest-&gt;GetMessageToBeStopped().size()?pRequest-&gt;GetMessageToBeStopped().c_str():&quot;all&quot;);
+        switch_channel_stop_broadcast(switch_core_session_get_channel(session));
+
+        StopResponse resp(pRequest-&gt;GetInvokeID());
+        sender-&gt;SendMsg(&amp;resp);
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::StopMessage: Response sent with InvokeID: %d\n:%s\n&quot;,resp.GetInvokeID(), resp.GetReadable().c_str());        
+        
+        switch_core_session_rwunlock(session);
+        switch_mutex_unlock(m_mutex);
+}
+
+
+void FreeSWITCH::SingleStepTransferCall(CISession* sender,SingleStepTransferCallRequest* pRequest)
+{
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::SingleStepTransferCall: Request with InvokeID: %d\n:%s\n&quot;,pRequest-&gt;GetInvokeID(), pRequest-&gt;GetReadable().c_str());
+
+        switch_mutex_lock(m_mutex);
+
+        FreeSwitchCall* pCall=GetCall(pRequest-&gt;GetActiveCall().GetCallID().c_str());        
+        if(!pCall)                
+        {
+                switch_mutex_unlock(m_mutex);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::SingleStepTransferCall: CallID %s not found.&quot;,pRequest-&gt;GetActiveCall().GetCallID().c_str());
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,invalidCallID); 
+                sender-&gt;SendMsg(&amp;err);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::SingleStepTransferCall: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                return;
+        }
+
+        //Retrieving the device that initiates the transfer
+        FreeSwitchDevice * pTransferringDevice=pCall-&gt;GetDevice(pRequest-&gt;GetActiveCall().GetDeviceID()-&gt;GetCallNr());        
+        if(!pTransferringDevice)
+        {
+                switch_mutex_unlock(m_mutex);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::SingleStepTransferCall: Device %s not found.&quot;,pRequest-&gt;GetActiveCall().GetDeviceID()-&gt;GetCallNr().c_str());
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,invalidDeviceID); 
+                sender-&gt;SendMsg(&amp;err);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::SingleStepTransferCall: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                return;
+        }
+
+        for(MapStr2Device::iterator it=pCall-&gt;devices.begin();it!=pCall-&gt;devices.end();it++)
+        {
+                if(it-&gt;second!=pTransferringDevice)        
+                {
+                        FreeSwitchConnection* pConnectionToTransfer=it-&gt;second-&gt;FindConnection(pCall);
+                        if(!pConnectionToTransfer)
+                        {
+                                switch_mutex_unlock(m_mutex);
+                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::SingleStepTransferCall: Connection %s/%s not found.&quot;,it-&gt;second-&gt;GetDeviceID().c_str(),pRequest-&gt;GetActiveCall().GetCallID().c_str());
+                                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,invalidDeviceID); 
+                                sender-&gt;SendMsg(&amp;err);
+                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::SingleStepTransferCall: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                                return;
+                        }
+
+                        switch_core_session_t* sessionToTransfer=switch_core_session_locate(pConnectionToTransfer-&gt;strUUID.c_str());
+                        if(!sessionToTransfer)
+                        {
+                                switch_mutex_unlock(m_mutex);
+                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::SingleStepTransferCall: Session %s not found.&quot;,pConnectionToTransfer-&gt;strUUID.c_str());
+                                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,invalidDeviceID); 
+                                sender-&gt;SendMsg(&amp;err);
+                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::SingleStepTransferCall: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                                return;
+                        }
+
+                        if(switch_ivr_session_transfer(sessionToTransfer,pRequest-&gt;GetTransferredTo().GetCallNr().c_str(),NULL,NULL)==SWITCH_STATUS_SUCCESS)
+                        {
+                                SingleStepTransferCallResponse resp(pRequest-&gt;GetInvokeID(),ConnectionID(pRequest-&gt;GetTransferredTo(),pCall-&gt;strUUID));
+                                sender-&gt;SendMsg(&amp;resp);
+                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::SingleStepTransferCall: Response sent with InvokeID: %d\n:%s\n&quot;,resp.GetInvokeID(), resp.GetReadable().c_str());
+                        }
+                        else
+                        {
+                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::SingleStepTransferCall: switch_ivr_session_transfer failed.&quot;);
+                                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,genericError); 
+                                sender-&gt;SendMsg(&amp;err);
+                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::SingleStepTransferCall: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                        }
+                        switch_core_session_rwunlock(sessionToTransfer);
+                }
+        }
+
+        //TODO: send transferred event
+        pTransferringDevice-&gt;DeleteConnection(pCall);
+        
+        switch_mutex_unlock(m_mutex);
+}
+
+void FreeSWITCH::DeflectCall(CISession* sender,DeflectCallRequest* pRequest)
+{
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::DeflectCall: Request with InvokeID: %d\n:%s\n&quot;,pRequest-&gt;GetInvokeID(), pRequest-&gt;GetReadable().c_str());
+
+        switch_mutex_lock(m_mutex);
+
+        FreeSwitchCall* pCall=GetCall(pRequest-&gt;GetCallToBeDiverted().GetCallID().c_str());        
+        if(!pCall)                
+        {
+                switch_mutex_unlock(m_mutex);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::DeflectCall: CallID %s not found.&quot;,pRequest-&gt;GetCallToBeDiverted().GetCallID().c_str());
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,invalidCallID); 
+                sender-&gt;SendMsg(&amp;err);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::DeflectCall: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                return;
+        }
+
+        //Retrieving the device that initiates the transfer
+        FreeSwitchDevice * pTransferringDevice=pCall-&gt;GetDevice(pRequest-&gt;GetCallToBeDiverted().GetDeviceID()-&gt;GetCallNr());        
+        if(!pTransferringDevice)
+        {
+                switch_mutex_unlock(m_mutex);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::DeflectCall: Device %s not found.&quot;,pRequest-&gt;GetCallToBeDiverted().GetDeviceID()-&gt;GetCallNr().c_str());
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,invalidDeviceID); 
+                sender-&gt;SendMsg(&amp;err);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::DeflectCall: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                return;
+        }
+
+        for(MapStr2Device::iterator it=pCall-&gt;devices.begin();it!=pCall-&gt;devices.end();it++)
+        {
+                if(it-&gt;second!=pTransferringDevice)        
+                {
+                        FreeSwitchConnection* pConnectionToTransfer=it-&gt;second-&gt;FindConnection(pCall);
+                        if(!pConnectionToTransfer)
+                        {
+                                switch_mutex_unlock(m_mutex);
+                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::DeflectCall: Connection %s/%s not found.&quot;,it-&gt;second-&gt;GetDeviceID().c_str(),pRequest-&gt;GetCallToBeDiverted().GetCallID().c_str());
+                                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,invalidDeviceID); 
+                                sender-&gt;SendMsg(&amp;err);
+                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::DeflectCall: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                                return;
+                        }
+
+                        switch_core_session_t* sessionToTransfer=switch_core_session_locate(pConnectionToTransfer-&gt;strUUID.c_str());
+                        if(!sessionToTransfer)
+                        {
+                                switch_mutex_unlock(m_mutex);
+                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::DeflectCall: Session %s not found.&quot;,pConnectionToTransfer-&gt;strUUID.c_str());
+                                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,invalidDeviceID); 
+                                sender-&gt;SendMsg(&amp;err);
+                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::DeflectCall: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                                return;
+                        }
+
+                        if(switch_ivr_session_transfer(sessionToTransfer,pRequest-&gt;GetNewDestination().GetCallNr().c_str(),NULL,NULL)==SWITCH_STATUS_SUCCESS)
+                        {
+                                DeflectCallResponse resp(pRequest-&gt;GetInvokeID());
+                                sender-&gt;SendMsg(&amp;resp);
+                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::DeflectCall: Response sent with InvokeID: %d\n:%s\n&quot;,resp.GetInvokeID(), resp.GetReadable().c_str());
+                        }
+                        else
+                        {
+                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::DeflectCall: switch_ivr_session_transfer failed.&quot;);
+                                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,genericError); 
+                                sender-&gt;SendMsg(&amp;err);
+                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::DeflectCall: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                        }
+                        switch_core_session_rwunlock(sessionToTransfer);
+                }
+        }
+
+        //TODO: send transferred event
+        pTransferringDevice-&gt;DeleteConnection(pCall);
+        
+        switch_mutex_unlock(m_mutex);
+}
+
+void FreeSWITCH::ClearConnection(CISession* sender, ClearConnectionRequest* pRequest)
+{
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::ClearConnection: Request with InvokeID: %d\n:%s\n&quot;,pRequest-&gt;GetInvokeID(), pRequest-&gt;GetReadable().c_str());
+
+        switch_mutex_lock(m_mutex);
+
+        FreeSwitchCall* pCall=GetCall(pRequest-&gt;GetConnectionToBeCleared().GetCallID().c_str());        
+        if(!pCall)                
+        {
+                switch_mutex_unlock(m_mutex);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::ClearConnection: CallID %s not found.&quot;,pRequest-&gt;GetConnectionToBeCleared().GetCallID().c_str());
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,invalidCallID); 
+                sender-&gt;SendMsg(&amp;err);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::ClearConnection: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                return;
+        }
+
+        //Retrieving the device that initiates the transfer
+        FreeSwitchDevice * pDevice=pCall-&gt;GetDevice(pRequest-&gt;GetConnectionToBeCleared().GetDeviceID()-&gt;GetCallNr());        
+        if(!pDevice)
+        {
+                switch_mutex_unlock(m_mutex);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::ClearConnection: Device %s not found.&quot;,pRequest-&gt;GetConnectionToBeCleared().GetDeviceID()-&gt;GetCallNr().c_str());
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,invalidDeviceID); 
+                sender-&gt;SendMsg(&amp;err);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::ClearConnection: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                return;
+        }
+
+        FreeSwitchConnection* pConnection=pDevice-&gt;FindConnection(pCall);
+        if(!pConnection)
+        {
+                switch_mutex_unlock(m_mutex);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::ClearConnection: Connection %s/%s not found.&quot;,pDevice-&gt;GetDeviceID().c_str(),pRequest-&gt;GetConnectionToBeCleared().GetCallID().c_str());
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,invalidDeviceID); 
+                sender-&gt;SendMsg(&amp;err);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::ClearConnection: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                return;
+        }
+
+        switch_core_session_t* session=switch_core_session_locate(pConnection-&gt;strUUID.c_str());
+        if(!session)
+        {
+                switch_mutex_unlock(m_mutex);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::ClearConnection: Session %s not found.&quot;,pConnection-&gt;strUUID.c_str());
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,invalidDeviceID); 
+                sender-&gt;SendMsg(&amp;err);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::ClearConnection: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+                return;
+        }
+
+        switch_channel_t *channel = switch_core_session_get_channel(session);        
+
+        if(switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING)==CS_HANGUP)
+        {
+                ClearConnectionResponse resp(pRequest-&gt;GetInvokeID());
+                sender-&gt;SendMsg(&amp;resp);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::ClearConnection: Response sent with InvokeID: %d\n:%s\n&quot;,resp.GetInvokeID(), resp.GetReadable().c_str());
+        }
+        else
+        {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;FreeSWITCH::ClearConnection: switch_ivr_session_transfer failed.&quot;);
+                UniversalErrorResponse err(pRequest-&gt;GetInvokeID(),error_type_operation,genericError); 
+                sender-&gt;SendMsg(&amp;err);
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;FreeSWITCH::ClearConnection: Response sent with InvokeID: %d\n:%s\n&quot;,err.GetInvokeID(), err.GetReadable().c_str());
+        }
+        switch_core_session_rwunlock(session);
+        switch_mutex_unlock(m_mutex);
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketFreeSWITCHFreeSWITCHh"></a>
<div class="addfile"><h4>Added: freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/FreeSWITCH.h (0 => 16050)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/FreeSWITCH.h                                (rev 0)
+++ freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/FreeSWITCH.h        2009-12-24 00:51:46 UTC (rev 16050)
</span><span class="lines">@@ -0,0 +1,248 @@
</span><ins>+/* 
+ * CSTA interface for FreeSWICH 
+ * Copyright (C) 2009, Szentesi Krisztian &lt;sz.krisz@freemail.hu&gt;
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the &quot;License&quot;); 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 &quot;AS IS&quot; 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 CSTA interface for FreeSWICH   
+ *
+ * The Initial Developer of the Original Code is
+ * Szentesi Krisztian &lt;sz.krisz@freemail.hu&gt;
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * 
+ * Szentesi Krisztian &lt;sz.krisz@freemail.hu&gt;
+ *
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the &quot;GPL&quot;), or
+ * the GNU Lesser General Public License Version 2.1 or later (the &quot;LGPL&quot;),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ */
+
+#ifndef CI_FREE_SWITCH_H
+#define CI_FREE_SWITCH_H
+
+#include &quot;CICTIHandler.h&quot;
+#include &quot;CISession.h&quot;
+#include &quot;CSTAEvent.h&quot;
+#include &lt;map&gt;
+#include &lt;list&gt;
+#include &lt;string&gt;
+
+
+using namespace std;
+
+
+
+class FreeSwitchCall;
+
+enum eDirection
+{
+        direction_incoming,        //!&lt; attached device is the called (on internal subscriber) or call is incoming (on network interface)
+        direction_outgoing, //!&lt; attached device is the caller (on internal subscriber) or call is outgoing (on network interface)
+};
+
+class FreeSwitchConnection
+{
+public:
+        FreeSwitchCall* pCall;
+        string strUUID;                                        //&lt;! Unique ID of the connection (could be different from the call's unique ID)
+        eLocalConnectionState state;        //!&lt; Local connection state
+        eDirection        direction;                        //!&lt; direction of the call        
+        string strChannel;                                //!&lt; channel name
+};
+
+typedef map&lt;FreeSwitchCall*,FreeSwitchConnection*&gt; MapCall2Connection;
+typedef map&lt;string, CISession*&gt; MapStr2Session;
+
+enum FreeSwitchDeviceType
+{
+        type_internal_subscriber=0,
+        type_network_interface,
+        type_queue,
+        type_unknown,
+};
+
+class FreeSwitchDevice
+{
+protected:
+        string m_strDevice;        
+        MapStr2Session m_MonitoringSessions;                                //!&lt; Sessions monitoring this device
+
+        FreeSwitchDeviceType m_deviceType;
+
+        bool m_bIsMakeCallOriginator;                                        
+public:
+        static std::string Channel2Device(const char* channel);        
+        
+        static char * Type2Prefix(FreeSwitchDeviceType type);
+        
+        //! finds out FreeSWITCH device type of CSTA DeviceID object
+        /*!
+                CSTA devices with type &quot;dialingNumber&quot; will mapped to internal subscribers (Note, that in some cases, 
+                the implementation will ignore the type field in CSTA devices and interprets the CallNr as a dial string, 
+                e.g in MakeCall request the device type is checked for callingDevice but not for calledDirectoryNumber).
+
+                CSTA devices with type &quot;deviceNumber&quot; are used to represent non subscriber type entities. 
+                For FreeSWITCH implementation, the number string begins with 2 byte long device 
+                type identifier and a device identifier. The device identifier must only contain numeric characters
+
+                Current device type prefixes:
+                &quot;02&quot; - Queue
+
+                \sa queue_function
+        */
+        static FreeSwitchDeviceType Device2Type(DeviceID device);
+public:
+        MapCall2Connection connections;        //!&lt; Active connections of this device
+
+        FreeSwitchDevice(const char* pcDevice, FreeSwitchDeviceType deviceType=type_internal_subscriber);
+
+        string&amp; GetDeviceID() {return m_strDevice;}
+
+        bool IsMonitoredWithID(string crossRefID);
+        
+        bool AddMonitor(CISession* session, string crossRefID);
+
+        bool RemoveMonitor(CISession* session);
+
+        bool RemoveMonitor(CISession* session, string crossRefID);
+
+        bool IsMonitored() {return m_MonitoringSessions.size()&gt;0?true:false;}
+
+        FreeSwitchConnection* FindConnection(const char* uuid);
+
+        FreeSwitchConnection* FindConnection(FreeSwitchCall* pCall);
+
+        FreeSwitchConnection* AddConnection(const char* uuid, const char * channel, FreeSwitchCall* pCall, eDirection direction);
+
+        void DeleteConnection(FreeSwitchCall* pCall);
+
+        //! Sends CSTA event to all sessions monitoring the device
+        void SendEvent(CSTAEvent* pEvent);
+
+        FreeSwitchDeviceType GetDeviceType() {return m_deviceType;}
+
+        int GetConnectionCount() {return connections.size();}
+
+        bool IsMakeCallOriginator() {return m_bIsMakeCallOriginator;}
+
+        void SetMakeCallOriginator (bool bMakeCallOriginator) {m_bIsMakeCallOriginator=bMakeCallOriginator;}
+};
+
+typedef map&lt;string,FreeSwitchDevice*&gt; MapStr2Device;
+typedef map&lt;string,FreeSwitchCall*&gt; MapStr2Call;
+
+class FreeSwitchCall
+{
+public:
+        string strUUID;                                        //!&lt; Unique ID (used for CSTA CallID) - the FreeSWITCH unique ID of the first connection in the call.
+        MapStr2Device devices;        
+
+        FreeSwitchDevice* GetDevice(std::string strDeviceID);
+};
+
+
+
+
+//! CSTA Inside CICTIHandler interface realization for FreeSWITCH.
+/*!
+Provides FreeSWITCH specific telephony methods to used by CSTA Inside.
+*/
+class FreeSWITCH : public CICTIHandler
+{
+protected:
+         MapStr2Device m_DeviceMap;                        //!&lt; Stores the known devices. Map key is the device id (usually the dialing number)
+         MapStr2Call m_CallMap;                                //!&lt; Stores the active calls. Map key is the call ID (1st FreeSWITCH UUID)
+         switch_mutex_t *m_mutex;                        //!&lt; To protect the device and call map
+         switch_memory_pool_t * m_pool;
+
+         int m_nLastXRefID;
+
+         bool FindCallerCalled(const char* uuid, string* pstrCaller, string* pstrCalled);
+
+         bool PrepareCallData(const char* uuid, const char* uuid2, const char* channel, FreeSwitchDevice** ppDevice, FreeSwitchCall** ppCall, FreeSwitchConnection** ppConnection, bool bCreateCall, FreeSwitchDevice** ppQueue, FreeSwitchDevice** ppInboundNID, FreeSwitchDevice** ppOutboundNID, string* pstrCaller, string* pstrCalled);
+
+public:
+        FreeSWITCH(switch_memory_pool_t *pool);
+
+        virtual ~FreeSWITCH();
+
+        FreeSwitchDevice * PrepareDevice(const char * pcDevice, FreeSwitchDeviceType type=type_internal_subscriber);
+
+        FreeSwitchCall* GetCall(const char * pcUUID);
+
+        bool IsXRefIDUsed(string crossRefID);        //!&lt; Returns true if given XRefID already used in the current CTI handler
+
+        string GetNextXRefID();        //!&lt; Returns the next available monitor cross reference ID        
+
+//Switch event handlers:
+        void OnChannelCreate(switch_event_t *event);        //!&lt; Handling CHANNEL_CREATE FreeSwitch event
+
+        void OnChannelHangup(switch_event_t *event);        //!&lt; Handling CHANNEL_HANGUP FreeSwitch event
+
+        void OnChannelAnswer(switch_event_t *event);        //!&lt; Handling CHANNEL_ANSWER FreeSwitch event
+
+        void OnProgress(switch_event_t *event);                        //!&lt; Handling CHANNEL_PROGRESS_MEDIA and CHANNEL_PROGRESS events
+
+        void OnDtmf(switch_event_t *event);                                //!&lt; Handling DTMF FreeSWITCH event
+        
+        void OnCallQueued(const char* queue, switch_core_session_t *session);                //!&lt; Handling incoming call on queue
+
+        void OnCallNetworkIncoming(const char* trunk, switch_core_session_t *session);                //!&lt; Handling incoming call on a gateway
+
+        void OnCallNetworkOutgoing(const char* trunk, switch_core_session_t *session);                //!&lt; Handling outgoing call on a gateway
+
+        void OnPlayback(switch_event_t *event);                        //!&lt; Handling playback application start or stop
+
+        void OnRecord(switch_event_t *event);                        //!&lt; Handling record application start or stop
+
+//Session event handlers:
+
+        void OnSessionFinished(CISession* sender);                //!&lt; Called if given session is disconnected
+
+        void MonitorStart(CISession* sender, MonitorStartRequest* pRequest);        //!&lt; called if a Monitor Start request should be processed
+
+        void SnapshotDevice(CISession* sender, SnapshotDeviceRequest* pRequest);        //!&lt; Called if Snapshot Device request is received
+
+        void SnapshotCall(CISession* sender, SnapshotCallRequest* pRequest);        //!&lt; Called if Snapshot Call request is received
+
+        
+        void MakeCall(CISession* sender, MakeCallRequest* pRequest);                //!&lt; Called if Make Call request is received
+
+        void AnswerCall(CISession* sender, AnswerCallRequest* pRequest);        //!&lt; Called if Answer Call request is received
+
+        void PlayMessage(CISession* sender, PlayMessageRequest* pRequest);        //!&lt; Called if Play Message request is received
+
+        void RecordMessage(CISession* sender, RecordMessageRequest* pRequest);        //!&lt; Called if Record Message request is received
+
+        void StopMessage(CISession* sender, StopRequest* pRequest);                                //!&lt; Called if Stop request is received
+
+        void SingleStepTransferCall(CISession* sender,SingleStepTransferCallRequest* pRequest);        //!&lt; Called if Single Step Transfer Call Message request is received
+
+        void ClearConnection(CISession* sender,ClearConnectionRequest* pRequest);
+
+        void DeflectCall(CISession* sender,DeflectCallRequest* pRequest);        //!&lt; Called if Deflect Call Message request is received
+};
+
+#endif        //CI_FREE_SWITCH_H
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketFreeSWITCHFreeSWITCHPlatformcpp"></a>
<div class="addfile"><h4>Added: freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/FreeSWITCHPlatform.cpp (0 => 16050)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/FreeSWITCHPlatform.cpp                                (rev 0)
+++ freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/FreeSWITCHPlatform.cpp        2009-12-24 00:51:46 UTC (rev 16050)
</span><span class="lines">@@ -0,0 +1,72 @@
</span><ins>+/* 
+ * CSTA interface for FreeSWICH 
+ * Copyright (C) 2009, Szentesi Krisztian &lt;sz.krisz@freemail.hu&gt;
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the &quot;License&quot;); 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 &quot;AS IS&quot; 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 CSTA interface for FreeSWICH   
+ *
+ * The Initial Developer of the Original Code is
+ * Szentesi Krisztian &lt;sz.krisz@freemail.hu&gt;
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * 
+ * Szentesi Krisztian &lt;sz.krisz@freemail.hu&gt;
+ *
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the &quot;GPL&quot;), or
+ * the GNU Lesser General Public License Version 2.1 or later (the &quot;LGPL&quot;),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ */
+
+#include &quot;FreeSWITCHPlatform.h&quot;
+#include &quot;switch.h&quot;
+
+
+FreeSWITCHPlatform::FreeSWITCHPlatform(void)
+{
+}
+
+FreeSWITCHPlatform::~FreeSWITCHPlatform(void)
+{
+}
+
+void FreeSWITCHPlatform::Trace(ci_trace_level loglevel, const char *fmt, ...)
+{
+        switch_log_level_t fsloglevel=SWITCH_LOG_ALERT;
+        switch (loglevel)
+        {
+        case CI_LLV_FATAL: fsloglevel=SWITCH_LOG_ALERT;break;
+        case CI_LLV_ERROR: fsloglevel=SWITCH_LOG_ERROR;break;
+        case CI_LLV_WARN: fsloglevel=SWITCH_LOG_WARNING;break;
+        case CI_LLV_INFO: fsloglevel=SWITCH_LOG_NOTICE;break;
+        case CI_LLV_DEBUG: fsloglevel=SWITCH_LOG_DEBUG;break;
+        }
+        
+        va_list ap;
+        va_start(ap, fmt);
+        
+
+        switch_log_vprintf(SWITCH_CHANNEL_LOG, fsloglevel, fmt, ap);        
+        va_end(ap);
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketFreeSWITCHFreeSWITCHPlatformh"></a>
<div class="addfile"><h4>Added: freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/FreeSWITCHPlatform.h (0 => 16050)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/FreeSWITCHPlatform.h                                (rev 0)
+++ freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/FreeSWITCHPlatform.h        2009-12-24 00:51:46 UTC (rev 16050)
</span><span class="lines">@@ -0,0 +1,62 @@
</span><ins>+/* 
+ * CSTA interface for FreeSWICH 
+ * Copyright (C) 2009, Szentesi Krisztian &lt;sz.krisz@freemail.hu&gt;
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the &quot;License&quot;); 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 &quot;AS IS&quot; 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 CSTA interface for FreeSWICH   
+ *
+ * The Initial Developer of the Original Code is
+ * Szentesi Krisztian &lt;sz.krisz@freemail.hu&gt;
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * 
+ * Szentesi Krisztian &lt;sz.krisz@freemail.hu&gt;
+ *
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the &quot;GPL&quot;), or
+ * the GNU Lesser General Public License Version 2.1 or later (the &quot;LGPL&quot;),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ */
+
+
+#ifndef CI_FREE_SWITCH_PLATFORM_H
+#define CI_FREE_SWITCH_PLATFORM_H
+
+#include &quot;CIPlatform.h&quot;
+
+//! CSTA Inside CIPlatform interface realization for FreeSWITCH.
+/*!
+Provides FreeSWITCH platform specific OS/XML/... methods required by by CSTA Inside.
+*/
+class FreeSWITCHPlatform : public CIPlatform
+{
+public:
+        FreeSWITCHPlatform();
+
+        virtual ~FreeSWITCHPlatform();
+
+        virtual void Trace(ci_trace_level loglevel, const char *fmt, ...);
+};
+
+#endif        //CI_FREE_SWITCH_PLATFORM_H
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketFreeSWITCHFreeSWITCHSocketcpp"></a>
<div class="addfile"><h4>Added: freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/FreeSWITCHSocket.cpp (0 => 16050)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/FreeSWITCHSocket.cpp                                (rev 0)
+++ freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/FreeSWITCHSocket.cpp        2009-12-24 00:51:46 UTC (rev 16050)
</span><span class="lines">@@ -0,0 +1,98 @@
</span><ins>+/* 
+ * CSTA interface for FreeSWICH 
+ * Copyright (C) 2009, Szentesi Krisztian &lt;sz.krisz@freemail.hu&gt;
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the &quot;License&quot;); 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 &quot;AS IS&quot; 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 CSTA interface for FreeSWICH   
+ *
+ * The Initial Developer of the Original Code is
+ * Szentesi Krisztian &lt;sz.krisz@freemail.hu&gt;
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * 
+ * Szentesi Krisztian &lt;sz.krisz@freemail.hu&gt;
+ *
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the &quot;GPL&quot;), or
+ * the GNU Lesser General Public License Version 2.1 or later (the &quot;LGPL&quot;),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ */
+
+
+#include &quot;FreeSwitchSocket.h&quot;
+#include &lt;apr_errno.h&gt;
+
+FreeSWITCHSocket::FreeSWITCHSocket(switch_socket_t* pSocket, switch_memory_pool_t *pool) : m_pSocket(pSocket), m_pool(pool)
+{
+        switch_mutex_init(&amp;m_mutex, SWITCH_MUTEX_NESTED, m_pool);
+        switch_socket_opt_set(m_pSocket, SWITCH_SO_TCP_NODELAY, TRUE);
+        switch_socket_opt_set(m_pSocket, SWITCH_SO_NONBLOCK, FALSE);
+
+        char remote_ip[50];
+        switch_sockaddr_t *sa;
+
+        switch_socket_addr_get(&amp;sa, SWITCH_TRUE, m_pSocket);
+        switch_get_addr(remote_ip, sizeof(remote_ip), sa);
+        switch_port_t remote_port = switch_sockaddr_get_port(sa);
+
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, &quot;Connection Open from %s:%d\n&quot;, remote_ip, remote_port);
+}
+
+FreeSWITCHSocket::~FreeSWITCHSocket()
+{
+        switch_mutex_destroy(m_mutex);
+}
+
+int FreeSWITCHSocket::Receive(unsigned char *buf, size_t *len) 
+{
+        switch_status_t status=switch_socket_recv(m_pSocket, (char*)buf, len);
+        if(status)
+        {
+                char errbuf[4096];
+                switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_NOTICE,&quot;Receive: socket terminated: %d (%s)&quot;,status, apr_strerror(status,errbuf,sizeof(errbuf)));
+        }
+        else
+                switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_NOTICE,&quot;%d bytes received:\n%s&quot;,*len, buf);
+        return status;
+}        
+
+int FreeSWITCHSocket::Send(const unsigned char *buf, size_t *len) 
+{
+        switch_mutex_lock(m_mutex);
+        switch_status_t status=switch_socket_send(m_pSocket, (const char*)buf, len);
+        if(status)
+        {
+                char errbuf[4096];
+                switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_NOTICE,&quot;Send: socket terminated: %d (%s)&quot;,status, apr_strerror(status,errbuf,sizeof(errbuf)));
+        }
+        switch_mutex_unlock(m_mutex);
+        return status;
+}
+
+int FreeSWITCHSocket::Close()
+{
+        switch_socket_shutdown(m_pSocket, SWITCH_SHUTDOWN_READWRITE);
+        switch_socket_close(m_pSocket);        
+        return 0;
+}
</ins></span></pre></div>
<a id="freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketFreeSWITCHFreeSWITCHSocketh"></a>
<div class="addfile"><h4>Added: freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/FreeSWITCHSocket.h (0 => 16050)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/FreeSWITCHSocket.h                                (rev 0)
+++ freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/FreeSWITCHSocket.h        2009-12-24 00:51:46 UTC (rev 16050)
</span><span class="lines">@@ -0,0 +1,71 @@
</span><ins>+/* 
+ * CSTA interface for FreeSWICH 
+ * Copyright (C) 2009, Szentesi Krisztian &lt;sz.krisz@freemail.hu&gt;
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the &quot;License&quot;); 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 &quot;AS IS&quot; 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 CSTA interface for FreeSWICH   
+ *
+ * The Initial Developer of the Original Code is
+ * Szentesi Krisztian &lt;sz.krisz@freemail.hu&gt;
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * 
+ * Szentesi Krisztian &lt;sz.krisz@freemail.hu&gt;
+ *
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the &quot;GPL&quot;), or
+ * the GNU Lesser General Public License Version 2.1 or later (the &quot;LGPL&quot;),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ */
+
+
+#ifndef CI_FREE_SWITCH_SOCKET_H
+#define CI_FREE_SWITCH_SOCKET_H
+
+#include &quot;CISocket.h&quot;
+#include &quot;switch.h&quot;
+
+//! CSTA Inside CISocket interface realization for FreeSWITCH.
+/*!
+Provides FreeSWITCH platform specific socket manipulation methods required by CSTA Inside.
+*/
+class FreeSWITCHSocket : public CISocket
+{
+protected:
+        switch_socket_t* m_pSocket;
+        switch_mutex_t *m_mutex;
+        switch_memory_pool_t* m_pool;
+public:
+        FreeSWITCHSocket(switch_socket_t* pSocket, switch_memory_pool_t *pool);
+
+        virtual ~FreeSWITCHSocket();
+
+        virtual int Receive(unsigned char *buf, size_t *len);        
+
+        virtual int Send(const unsigned char *buf, size_t *len);
+
+        virtual int Close();
+};
+
+#endif        //CI_FREE_SWITCH_SOCKET_H
</ins></span></pre></div>
<a id="freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketFreeSWITCHFreeSWITCH_CSTArc"></a>
<div class="addfile"><h4>Added: freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/FreeSWITCH_CSTA.rc (0 => 16050)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/FreeSWITCH_CSTA.rc                                (rev 0)
+++ freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/FreeSWITCH_CSTA.rc        2009-12-24 00:51:46 UTC (rev 16050)
</span><span class="lines">@@ -0,0 +1,115 @@
</span><ins>+// Microsoft Visual C++ generated resource script.
+//
+#include &quot;resource.h&quot;
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include &quot;afxres.h&quot;
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Hungarian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_HUN)
+#ifdef _WIN32
+LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT
+#pragma code_page(1250)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE 
+BEGIN
+    &quot;resource.h\0&quot;
+END
+
+2 TEXTINCLUDE 
+BEGIN
+    &quot;#include &quot;&quot;afxres.h&quot;&quot;\r\n&quot;
+    &quot;\0&quot;
+END
+
+3 TEXTINCLUDE 
+BEGIN
+    &quot;\r\n&quot;
+    &quot;\0&quot;
+END
+
+#endif    // APSTUDIO_INVOKED
+
+#endif    // Hungarian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 0,2,0,92
+ PRODUCTVERSION 1,0,0,1
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK &quot;StringFileInfo&quot;
+    BEGIN
+        BLOCK &quot;040e04b0&quot;
+        BEGIN
+            VALUE &quot;Comments&quot;, &quot;http://cstainside.sourceforge.net/&quot;
+            VALUE &quot;FileDescription&quot;, &quot;CSTA interface for FreeSWITCH&quot;
+            VALUE &quot;FileVersion&quot;, &quot;0, 2, 0, 92&quot;
+            VALUE &quot;InternalName&quot;, &quot;mod_csta_socket&quot;
+            VALUE &quot;LegalCopyright&quot;, &quot;Copyright (C) 2009, Szentesi Krisztian &lt;sz.krisz@freemail.hu&gt;&quot;
+            VALUE &quot;LegalTrademarks&quot;, &quot;Licensed under MPL 1.1&quot;
+            VALUE &quot;OriginalFilename&quot;, &quot;mod_csta_socket.dll&quot;
+            VALUE &quot;ProductName&quot;, &quot;CSTA Inside&quot;
+            VALUE &quot;ProductVersion&quot;, &quot;1, 0, 0, 1&quot;
+        END
+    END
+    BLOCK &quot;VarFileInfo&quot;
+    BEGIN
+        VALUE &quot;Translation&quot;, 0x40e, 1200
+    END
+END
+
+#endif    // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+
</ins></span></pre></div>
<a id="freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketFreeSWITCHREADME"></a>
<div class="addfile"><h4>Added: freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/README (0 => 16050)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/README                                (rev 0)
+++ freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/README        2009-12-24 00:51:46 UTC (rev 16050)
</span><span class="lines">@@ -0,0 +1,192 @@
</span><ins>+                              mod_csta_socket - CSTA interface for FreeSWITCH
+                            
+    
+1. Capabilities
+   
+As a communication &amp; encoding interface CSTA XML over TCP without SOAP is supported yet (ECMA-323 Annex J-2).
+Module is based on CSTA Inside library.
+
+Supported device types:
+
+1.1. internal subscribers
+- internal subscribers are mapped to CSTA &quot;dialingNumber&quot; type of devices. The dialing sequence is the 
+phone number without any leading characters
+
+1.2 queues
+Queues are able to enqueue multiple calls. To configure a CSTA queue, add the csta_trigger_queue application 
+to a dialplan entry:
+
+&lt;action application=&quot;csta_trigger_queue&quot; data=&quot;9500&quot;/&gt;
+
+Data is the name of the queue. In CSTA events and requeust, the queue will be referenced as a device with type 
+of &quot;deviceNumber&quot;. The callNr will be concatenated with a type ID of &quot;02&quot; and the queue name (029500 on the above example).
+Queue name should be numeric to comply with CSTA standard.
+
+1.3 network interfaces
+Network interfaces or trunks representing devices via calls can leave or enter the CSTA subdomain.
+To configure CSTA NIDs, add the csta_trigger_trunk_inbound and csta_trigger_trunk_outbound application
+to the corresponding dialplan entry (if a call is directed to a gateway or external call directed into FreeSWITCH):
+
+outgoing example:
+
+&lt;extension name=&quot;outbound_example&quot;&gt;
+        &lt;condition field=&quot;destination_number&quot; expression=&quot;^20(.*)$&quot;&gt;
+                &lt;action application=&quot;csta_trigger_trunk_outbound&quot; data=&quot;20&quot;/&gt;                
+                &lt;action application=&quot;bridge&quot; data=&quot;sofia/gateway/example_gw/$1&quot;/&gt;
+        &lt;/condition&gt;
+&lt;/extension&gt; 
+
+incoming example:
+
+&lt;extension name=&quot;inbound_example&quot;&gt;
+        &lt;condition field=&quot;destination_number&quot; expression=&quot;^193190$&quot;&gt;       
+                 &lt;action application=&quot;csta_trigger_trunk_inbound&quot; data=&quot;20&quot;/&gt;
+                 &lt;action application=&quot;set&quot; data=&quot;domain_name=$${domain}&quot;/&gt;      
+                 &lt;action application=&quot;transfer&quot; data=&quot;9500 XML default&quot;/&gt;
+        &lt;/condition&gt;
+ &lt;/extension&gt;  

+Data is the name of the queue. In CSTA events and requeust, the NID will be referenced as a device with type 
+of &quot;deviceNumber&quot;. The callNr will be concatenated with a type ID of &quot;01&quot; and the NID name (0120 on the above example).
+NID name should be numeric to comply with CSTA standard. 
+
+The following CSTA messages are implemented:
+
+requests and responses:
+- Monitor Start
+  Starts monitoring of a device. 
+  Supported types: internal subscriber, queue, NID
+
+- Make Call
+  Originates a call to an extension
+  Supported types: callingDevice: internal subscriber 
+                   calledDirectoryNumber: any extension, used as dialing string
+  Do Not Prompt (auto originate) option works only with devices supporting sip_auto_answer flag
+  
+- Answer Call
+  Answers a ringing call
+  Supported Types: queue
+  
+- Single Step Transfer Call
+  Transfers a connection to another endpoint without hold &amp; consultation
+  Supported types: activeCall: internal subscriber, queue.
+                   transferredTo: any extension, used as dialing string.
+  
+- Play Message
+  Plays a wavefile for a connected connection. Wavefile path relative to &quot;/sounds/en/us/callie&quot; is to specify in 
+  messageToBePlayed parameter. If positive response is returned, check Stop event for result of the service.
+  Supported types: internal subscriber, queue
+  
+- Record Message
+  Records a connection to a wavefile. Filename is generated by the service and returned (with full path) in the response.
+  Supported types: internal subscriber, queue
+  
+- Stop
+  Stops playing or recording of a wavefile. 
+  Supported types: internal subscriber, queue
+  
+- Clear Connection
+  Clears an active connection. 
+  Supported types: internal subscriber, queue, NID
+  
+- Snapshot Device
+  Returns the active connections of a device. 
+  Supported types: internal subscriber, queue, NID
+  
+- Snapshot Call
+  Returns the devices participating in an active call. 
+  Supported types: internal subscriber, queue, NID
+
+- Deflect Call
+  Transfers a connection to another endpoint 
+  Supported types: callToBeDiverted: internal subscriber, queue.
+                   newDestination: any extension, used as dialing string.
+
+events:
+- Service Initiated
+  Generated if an outbound channel is created from a device
+  Supported types: internal subscriber, network interface
+  
+- Originated
+  Generated from the caller if call is delivered
+  Supported types: internal subscriber
+  
+- Delivered
+  Generated if call is delivered to called party
+  Supported types: internal subscriber
+
+- Established
+  Generated if channel is answered
+  Supported types: internal subscriber, queue, network interface
+
+- Connection Cleared
+  Generated if a device leaves a call
+  Supported types: internal subscriber, queue, network interface
+
+- Queued
+  Generated if a call enters a queue
+  Supported types: internal subscriber, queue,  network interface
+  
+- DTMF Detected
+  Generated if a DTMF tone is detected on a connected connection
+  Supported types: internal subscriber, queue (if a device connected to a queue generates a tone), network interface
+  Note: On queues FreeSWITCH only detects DTMF if acoustic conection is on. 
+  Workaround: add &lt;action application=&quot;playback&quot; data=&quot;silence_stream://1800000&quot;/&gt; after queue is answered to queue dialplan.
+  
+- Play
+  Generated if playback application is started.
+  The &quot;message&quot; field contains the soundfile relative path.
+
+- Record
+  Generated if record application is started.
+  The &quot;message&quot; field contains the soundfile relative path.
+
+- Stop     
+  Generated if playback or record application is stopped.
+  The &quot;message&quot; field contains the soundfile relative path. The &quot;cause&quot; field is set to &quot;endOfMessageDetected&quot; if 
+  file played successfully or stop service is invoked, &quot;resourcesNotAvailable&quot; if file not found, and &quot;blocked&quot; if playback failed from any other reason.
+  For recording &quot;messageDurationExceeded&quot; cause is used if record stopped after recording length reached maxDuration or stop service is invoked.
+  If recording stopped because of hangup, no Stop event will be generated, only Connection Cleared. 
+  
+                            
+2. Building from source
+
+For Win32 platform Visual Studio 2008 project file is included. Use only Release configuration. 
+
+Requirements:
+- CSTA Inside Core - Multi-purpose C++ CSTA-XML library 
+  download from: http://cstainside.sourceforge.net/
+  place to: &lt;root&gt;\CSTAInsideCore (project file expects ..\CSTAInsideCore directory)
+- FreeSWITCH
+  download from: http://wiki.freeswitch.org/wiki/Installation_Guide#Download_Source_Tarball
+  place to: &lt;root&gt;\3rdparty\freeswitch-snapshot
+
+Both must be build before building mod_csta_socket
+
+3. Usage
+
+mod_csta_socket.dll is placed to &lt;root&gt;\3rdparty\freeswitch-snapshot\Release\mod directory. To load use load 
+FreeSWITCH command or set automatic load in modules.conf.xml
+
+4. Configuration
+
+module reads configuration data from csta_socket.conf.xml file under &lt;freeswitch&gt;\conf\autoload_configs directory.
+
+Example:
+&lt;configuration name=&quot;csta_socket.conf&quot; description=&quot;CSTA Interface&quot;&gt;
+  &lt;settings&gt;        
+    &lt;param name=&quot;listen-ip&quot; value=&quot;127.0.0.1&quot;/&gt;
+    &lt;param name=&quot;xml-listen-port&quot; value=&quot;3000&quot;/&gt;
+    &lt;param name=&quot;apply-inbound-acl&quot; value=&quot;csta&quot;/&gt;
+  &lt;/settings&gt;
+&lt;/configuration&gt;
+
+listen-ip:          the IP address of interface to listen on. 0.0.0.0 specifies to listen on all interfaces.
+                    default: 127.0.0.1
+xml-listen-port:    the listening port for CSTA-XML over TCPinterface.
+                    default: 3000
+apply-inbound-acl:  the name of ACL entry configured in acl.conf to filter inbound connections.
+                    default: empty (no ACL applied)
+
+
+Copyright (C) 2009, Szentesi Krisztian &lt;sz.krisz@freemail.hu&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketFreeSWITCHconfigcpp"></a>
<div class="addfile"><h4>Added: freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/config.cpp (0 => 16050)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/config.cpp                                (rev 0)
+++ freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/config.cpp        2009-12-24 00:51:46 UTC (rev 16050)
</span><span class="lines">@@ -0,0 +1,88 @@
</span><ins>+/* 
+ * CSTA interface for FreeSWICH 
+ * Copyright (C) 2009, Szentesi Krisztian &lt;sz.krisz@freemail.hu&gt;
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the &quot;License&quot;); 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 &quot;AS IS&quot; 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 CSTA interface for FreeSWICH   
+ *
+ * The Initial Developer of the Original Code is
+ * Szentesi Krisztian &lt;sz.krisz@freemail.hu&gt;
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * 
+ * Szentesi Krisztian &lt;sz.krisz@freemail.hu&gt;
+ *
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the &quot;GPL&quot;), or
+ * the GNU Lesser General Public License Version 2.1 or later (the &quot;LGPL&quot;),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ */
+
+#include &lt;switch.h&gt;
+#include &quot;config.h&quot;
+
+
+/*static*/ Config Config::_instance;
+
+Config::Config()
+{
+        strcpy(listen_address,&quot;127.0.0.1&quot;);
+        xml_port=3000;
+        acl_name[0]=0;
+}
+
+bool Config::ReadConfig()
+{
+        
+        char *cf = &quot;csta_socket.conf&quot;;
+        switch_xml_t cfg, xml, settings, param;
+
+        if (!(xml = switch_xml_open_cfg(cf, &amp;cfg, NULL))) {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, &quot;Open of %s failed, using defaults.\n&quot;, cf);
+        } else {
+                if ((settings = switch_xml_child(cfg, &quot;settings&quot;))) {
+                        for (param = switch_xml_child(settings, &quot;param&quot;); param; param = param-&gt;next) {
+                                char *var = (char *) switch_xml_attr_soft(param, &quot;name&quot;);
+                                char *val = (char *) switch_xml_attr_soft(param, &quot;value&quot;);
+
+                                if (!strcmp(var, &quot;listen-ip&quot;))
+                                {
+                                        strncpy(listen_address,val,sizeof(listen_address));        
+                                        listen_address[sizeof(listen_address)-1]=0;
+                                }
+                                else if (!strcmp(var, &quot;xml-listen-port&quot;))
+                                        xml_port=(switch_port_t)atoi(val);
+                                else if (!strcasecmp(var, &quot;apply-inbound-acl&quot;)) 
+                                {
+                                        strncpy(acl_name,val,sizeof(acl_name));        
+                                        acl_name[sizeof(acl_name)-1]=0;
+                                }
+                        }
+                }
+                switch_xml_free(xml);
+        }
+        
+        return true;
+
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketFreeSWITCHconfigh"></a>
<div class="addfile"><h4>Added: freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/config.h (0 => 16050)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/config.h                                (rev 0)
+++ freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/config.h        2009-12-24 00:51:46 UTC (rev 16050)
</span><span class="lines">@@ -0,0 +1,73 @@
</span><ins>+/* 
+ * CSTA interface for FreeSWICH 
+ * Copyright (C) 2009, Szentesi Krisztian &lt;sz.krisz@freemail.hu&gt;
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the &quot;License&quot;); 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 &quot;AS IS&quot; 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 CSTA interface for FreeSWICH   
+ *
+ * The Initial Developer of the Original Code is
+ * Szentesi Krisztian &lt;sz.krisz@freemail.hu&gt;
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * 
+ * Szentesi Krisztian &lt;sz.krisz@freemail.hu&gt;
+ *
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the &quot;GPL&quot;), or
+ * the GNU Lesser General Public License Version 2.1 or later (the &quot;LGPL&quot;),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ */
+
+#ifndef CI_FS_CONFIG_H
+#define CI_FS_CONFIG_H
+
+
+//! Stores module configuration and processes module configuration file.
+class Config
+{
+protected:
+        static Config _instance;
+public:
+        static Config* Instance() {return &amp;_instance;}
+protected:
+        char listen_address[50];
+        switch_port_t xml_port;
+        char acl_name[50];
+protected:
+        Config();
+public:
+        bool ReadConfig();
+
+        const char* GetListenAddress() {return listen_address;}
+
+        const switch_port_t GetXmlPort() {return xml_port;}
+
+        bool IsACLEnabled() {return acl_name[0]==0?false:true;}
+
+        const char* GetACLName() {return acl_name;}
+};
+
+
+
+#endif //CI_FS_CONFIG_H
</ins></span></pre></div>
<a id="freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketFreeSWITCHmod_csta_socketcpp"></a>
<div class="addfile"><h4>Added: freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/mod_csta_socket.cpp (0 => 16050)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/mod_csta_socket.cpp                                (rev 0)
+++ freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/mod_csta_socket.cpp        2009-12-24 00:51:46 UTC (rev 16050)
</span><span class="lines">@@ -0,0 +1,476 @@
</span><ins>+/* 
+ * CSTA interface for FreeSWICH 
+ * Copyright (C) 2009, Szentesi Krisztian &lt;sz.krisz@freemail.hu&gt;
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the &quot;License&quot;); 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 &quot;AS IS&quot; 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 CSTA interface for FreeSWICH   
+ *
+ * The Initial Developer of the Original Code is
+ * Szentesi Krisztian &lt;sz.krisz@freemail.hu&gt;
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * 
+ * Szentesi Krisztian &lt;sz.krisz@freemail.hu&gt;
+ *
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the &quot;GPL&quot;), or
+ * the GNU Lesser General Public License Version 2.1 or later (the &quot;LGPL&quot;),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ */
+
+/*! \file mod_csta_socket.cpp
+\brief PBX module interface implementation for FreeSWITCH.
+
+Provides interface functions to allow integrate the module to FreeSWITCH 
+*/
+
+
+#include &lt;switch.h&gt;
+
+#include &quot;FreeSwitch.h&quot;
+#include &quot;FreeSwitchPlatform.h&quot;
+#include &quot;FreeSwitchSocket.h&quot;
+#include &quot;XMLSession.h&quot;
+#include &quot;config.h&quot;
+#include &quot;UniversalErrorResponse.h&quot;
+
+SWITCH_MODULE_LOAD_FUNCTION(mod_csta_socket_load);
+SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_csta_socket_shutdown);
+SWITCH_MODULE_RUNTIME_FUNCTION(mod_csta_socket_runtime);
+SWITCH_MODULE_DEFINITION(mod_csta_socket, mod_csta_socket_load, mod_csta_socket_shutdown, mod_csta_socket_runtime);
+
+static volatile bool bRunning=true;
+
+FreeSWITCH* fs=NULL;
+FreeSWITCHPlatform* platform=NULL;
+
+
+struct THREAD_INFO
+{
+        switch_memory_pool_t *pool;
+        switch_socket_t* socket;
+};
+
+
+switch_socket_t* listen_socket=NULL;
+switch_event_node_t *node=NULL;
+
+
+//! Called if a call hits a queue
+/*!
+        Called if call enters into a queue. Queues should be defined in dialplan 
+        default section with csta_trigger_queue application triggered.
+        \param session The FreeSWITCH session
+        \param data        The queue name set in dialplan (data parameter of csta_trigger_queue application)
+        
+        Example configuration:        
+
+   &lt;extension name=&quot;example_queue&quot;&gt;
+      &lt;condition field=&quot;destination_number&quot; expression=&quot;^9500$&quot;&gt;  
+          &lt;action application=&quot;ring_ready&quot;/&gt;
+          &lt;action application=&quot;csta_trigger_queue&quot; data=&quot;9500&quot;/&gt;
+          &lt;action application=&quot;sleep&quot; data=&quot;600000&quot;/&gt;
+      &lt;/condition&gt;      
+   &lt;/extension&gt; 
+
+   Note that queue name must only contain numeric characters to fit CSTA standard
+*/
+SWITCH_STANDARD_APP(queue_function)
+{
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, &quot;Queue triggered, queue: %s, call:%s!\n&quot;, data, switch_core_session_get_uuid(session));
+        fs-&gt;OnCallQueued(data, session); 
+}
+
+
+//! Called if a call enters FreeSWITCH from outside
+/*!
+        Called if a call enters FreeSWITCH from outside. Incoming CSTA Network interfaces should be defined in dialplan 
+        public section with csta_trigger_trunk_inbound application triggered.
+        \param session The FreeSWITCH session
+        \param data        The NID name set in dialplan (data parameter of csta_trigger_trunk_inbound application)
+        
+        Example configuration:        
+   
+          &lt;extension name=&quot;inbound_example&quot;&gt;
+                &lt;condition field=&quot;destination_number&quot; expression=&quot;^193190$&quot;&gt;       
+                  &lt;action application=&quot;csta_trigger_trunk_inbound&quot; data=&quot;20&quot;/&gt;
+                  &lt;action application=&quot;set&quot; data=&quot;domain_name=$${domain}&quot;/&gt;      
+                  &lt;action application=&quot;transfer&quot; data=&quot;9500 XML default&quot;/&gt;
+                &lt;/condition&gt;
+          &lt;/extension&gt;  
+
+   Note that NID name must only contain numeric characters to fit CSTA standard
+*/
+SWITCH_STANDARD_APP(trunk_inbound_function)
+{
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, &quot;Inbound call on trunk %s, call:%s!\n&quot;, data, switch_core_session_get_uuid(session));
+        fs-&gt;OnCallNetworkIncoming(data, session);
+}
+
+//! Called if a call leaves FreeSWITCH via a gateway
+/*!
+        Called if a call leaves FreeSWITCH via a gateway. Outgoing CSTA Network interfaces should be defined in dialplan 
+        default section with csta_trigger_trunk_outbound application triggered.
+        \param session The FreeSWITCH session
+        \param data        The NID name set in dialplan (data parameter of csta_trigger_trunk_outbound application)
+        
+        Example configuration:        
+   
+          &lt;extension name=&quot;outbound_example&quot;&gt;
+                &lt;condition field=&quot;destination_number&quot; expression=&quot;^20(.*)$&quot;&gt;
+                        &lt;action application=&quot;csta_trigger_trunk_outbound&quot; data=&quot;20&quot;/&gt;
+                        &lt;action application=&quot;set&quot; data=&quot;effective_caller_id_number=193190&quot;/&gt;
+                        &lt;action application=&quot;bridge&quot; data=&quot;sofia/gateway/example_gw/$1&quot;/&gt;
+                &lt;/condition&gt;
+          &lt;/extension&gt; 
+
+   Note that NID name must only contain numeric characters to fit CSTA standard
+*/
+SWITCH_STANDARD_APP(trunk_outbound_function)
+{
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, &quot;Outbound call on trunk %s, call:%s!\n&quot;, data, switch_core_session_get_uuid(session));
+        fs-&gt;OnCallNetworkOutgoing(data, session);
+}
+
+static void event_handler(switch_event_t *event)
+{
+        
+        switch(event-&gt;event_id)
+        {
+        case SWITCH_EVENT_CUSTOM:
+                break;
+        case SWITCH_EVENT_CLONE:
+                break;
+        case SWITCH_EVENT_CHANNEL_CREATE:
+                fs-&gt;OnChannelCreate(event);
+                break;
+        case SWITCH_EVENT_CHANNEL_DESTROY:
+                break;
+        case SWITCH_EVENT_CHANNEL_STATE:
+                break;
+        case SWITCH_EVENT_CHANNEL_ANSWER:
+                fs-&gt;OnChannelAnswer(event);
+                break;
+        case SWITCH_EVENT_CHANNEL_HANGUP:
+                fs-&gt;OnChannelHangup(event);
+                break;
+        case SWITCH_EVENT_CHANNEL_EXECUTE:                
+        case SWITCH_EVENT_CHANNEL_EXECUTE_COMPLETE:
+                {
+                        const char* app=switch_event_get_header(event, &quot;Application&quot;);
+                        if(app) 
+                        {
+                                if(strcmp(app,&quot;playback&quot;)==0)
+                                        fs-&gt;OnPlayback(event);
+                                else
+                                if(strcmp(app,&quot;record&quot;)==0)
+                                        fs-&gt;OnRecord(event);
+                        }
+                }
+                break;
+        case SWITCH_EVENT_CHANNEL_BRIDGE:
+                break;
+        case SWITCH_EVENT_CHANNEL_UNBRIDGE:
+                break;
+        case SWITCH_EVENT_CHANNEL_PROGRESS:                
+        case SWITCH_EVENT_CHANNEL_PROGRESS_MEDIA:
+                fs-&gt;OnProgress(event);
+                break;
+        case SWITCH_EVENT_CHANNEL_OUTGOING:
+                break;
+        case SWITCH_EVENT_CHANNEL_PARK:
+                break;
+        case SWITCH_EVENT_CHANNEL_UNPARK:
+                break;
+        case SWITCH_EVENT_CHANNEL_APPLICATION:
+                break;
+        case SWITCH_EVENT_CHANNEL_ORIGINATE:
+                break;
+        case SWITCH_EVENT_CHANNEL_UUID:
+                break;
+        case SWITCH_EVENT_API:
+                break;
+        case SWITCH_EVENT_LOG:
+                break;
+        case SWITCH_EVENT_INBOUND_CHAN:
+                break;
+        case SWITCH_EVENT_OUTBOUND_CHAN:
+                break;
+        case SWITCH_EVENT_STARTUP:
+                break;
+        case SWITCH_EVENT_SHUTDOWN:
+                break;
+        case SWITCH_EVENT_PUBLISH:
+                break;
+        case SWITCH_EVENT_UNPUBLISH:
+                break;
+        case SWITCH_EVENT_TALK:
+                break;
+        case SWITCH_EVENT_NOTALK:
+                break;
+        case SWITCH_EVENT_SESSION_CRASH:
+                break;
+        case SWITCH_EVENT_MODULE_LOAD:
+                break;
+        case SWITCH_EVENT_MODULE_UNLOAD:
+                break;
+        case SWITCH_EVENT_DTMF:
+                fs-&gt;OnDtmf(event);
+                break;
+        case SWITCH_EVENT_MESSAGE:
+                break;
+        case SWITCH_EVENT_PRESENCE_IN:
+                break;
+        case SWITCH_EVENT_NOTIFY_IN:
+                break;
+        case SWITCH_EVENT_PRESENCE_OUT:
+                break;
+        case SWITCH_EVENT_PRESENCE_PROBE:
+                break;
+        case SWITCH_EVENT_MESSAGE_WAITING:
+                break;
+        case SWITCH_EVENT_MESSAGE_QUERY:
+                break;
+        case SWITCH_EVENT_ROSTER:
+                break;
+        case SWITCH_EVENT_CODEC:
+                break;
+        case SWITCH_EVENT_BACKGROUND_JOB:
+                break;
+        case SWITCH_EVENT_DETECTED_SPEECH:
+                break;
+        case SWITCH_EVENT_DETECTED_TONE:
+                break;
+        case SWITCH_EVENT_PRIVATE_COMMAND:
+                break;
+        case SWITCH_EVENT_HEARTBEAT:
+                break;
+        case SWITCH_EVENT_TRAP:
+                break;
+        case SWITCH_EVENT_ADD_SCHEDULE:
+                break;
+        case SWITCH_EVENT_DEL_SCHEDULE:
+                break;
+        case SWITCH_EVENT_EXE_SCHEDULE:
+                break;
+        case SWITCH_EVENT_RE_SCHEDULE:
+                break;
+        case SWITCH_EVENT_RELOADXML:
+                break;
+        case SWITCH_EVENT_NOTIFY:
+                break;
+        case SWITCH_EVENT_SEND_MESSAGE:
+                break;
+        case SWITCH_EVENT_RECV_MESSAGE:
+                break;
+        case SWITCH_EVENT_REQUEST_PARAMS:
+                break;
+        case SWITCH_EVENT_CHANNEL_DATA:
+                break;
+        case SWITCH_EVENT_GENERAL:
+                break;
+        case SWITCH_EVENT_COMMAND:
+                break;
+        case SWITCH_EVENT_SESSION_HEARTBEAT:
+                break;
+        case SWITCH_EVENT_CLIENT_DISCONNECTED:
+                break;
+        case SWITCH_EVENT_SERVER_DISCONNECTED:
+                break;
+        case SWITCH_EVENT_SEND_INFO:
+                break;
+        case SWITCH_EVENT_RECV_INFO:
+                break;
+        }
+        
+}
+
+
+static void *SWITCH_THREAD_FUNC listener_run(switch_thread_t *thread, void *obj)
+{
+        THREAD_INFO* thread_info=(THREAD_INFO*)obj;
+        
+        FreeSWITCHSocket socket(thread_info-&gt;socket,thread_info-&gt;pool );
+        XMLSession csta_session(platform, &amp;socket, fs);
+        
+        char remote_ip[50];
+        switch_sockaddr_t *sa;
+        switch_socket_addr_get(&amp;sa, SWITCH_TRUE, thread_info-&gt;socket);
+        switch_get_addr(remote_ip, sizeof(remote_ip), sa);        
+        if(                (Config::Instance()-&gt;IsACLEnabled())
+                &amp;&amp;        (!switch_check_network_list_ip(remote_ip, Config::Instance()-&gt;GetACLName())) )
+        {                
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, &quot;IP %s Rejected by acl \&quot;%s\&quot;\n&quot;, remote_ip, Config::Instance()-&gt;GetACLName());                
+                UniversalErrorResponse err(0,error_type_security,genericError);
+                csta_session.SendMsg(&amp;err);
+                socket.Close();                
+        }
+        else
+                csta_session.Run();
+
+        delete thread_info;
+        return NULL;
+}
+
+
+SWITCH_MODULE_LOAD_FUNCTION(mod_csta_socket_load)
+{        
+        *module_interface = switch_loadable_module_create_module_interface(pool, modname);
+        switch_application_interface_t *app_interface;
+        
+        fs=new FreeSWITCH(pool);
+        platform=new FreeSWITCHPlatform();
+
+        bRunning=true;
+        Config::Instance()-&gt;ReadConfig();
+
+        SWITCH_ADD_APP(app_interface, &quot;csta_trigger_queue&quot;, &quot;Notifies about call entered a CSTA queue&quot;, &quot;Notifies CSTA module about a call entered a CSAT queue.&quot;, queue_function, &quot;&quot;, SAF_SUPPORT_NOMEDIA);
+        SWITCH_ADD_APP(app_interface, &quot;csta_trigger_trunk_inbound&quot;, &quot;Notifies about call entering FreeSWITCH from outside&quot;, &quot;Notifies CSTA module about about call entering FreeSWITCH from outside.&quot;, trunk_inbound_function, &quot;&quot;, SAF_SUPPORT_NOMEDIA);
+        SWITCH_ADD_APP(app_interface, &quot;csta_trigger_trunk_outbound&quot;, &quot;Notifies about call leaving FreeSWITCH&quot;, &quot;Notifies CSTA module about call leaving FreeSWITCH.&quot;, trunk_outbound_function, &quot;&quot;, SAF_SUPPORT_NOMEDIA);
+
+        //TODO: filter events
+        if (switch_event_bind_removable(modname, SWITCH_EVENT_ALL, SWITCH_EVENT_SUBCLASS_ANY, event_handler, NULL, &amp;node) != SWITCH_STATUS_SUCCESS) 
+        {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;Couldn't bind to events!\n&quot;);
+                return SWITCH_STATUS_GENERR;
+        }
+
+        return SWITCH_STATUS_SUCCESS;
+}
+
+SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_csta_socket_shutdown)
+{
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, &quot;Shutting down..\n&quot;);
+        bRunning=false;
+        if(listen_socket)
+        {
+                switch_socket_shutdown(listen_socket, SWITCH_SHUTDOWN_READWRITE);
+                switch_socket_close(listen_socket);
+                listen_socket=NULL;
+        }
+
+        switch_event_unbind(&amp;node);
+
+        delete fs;
+        delete platform;
+        fs=NULL;
+        platform=NULL;
+        
+        return SWITCH_STATUS_SUCCESS;
+}
+
+
+
+SWITCH_MODULE_RUNTIME_FUNCTION(mod_csta_socket_runtime)
+{
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;Starting..\n&quot;);
+
+        switch_status_t rv;
+        
+        switch_sockaddr_t *sa;
+        switch_memory_pool_t *pool = NULL, *listener_pool = NULL;
+        switch_socket_t *inbound_socket = NULL;        
+
+        if (switch_core_new_memory_pool(&amp;pool) != SWITCH_STATUS_SUCCESS) 
+        {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;switch_core_new_memory_pool failed.\n&quot;);
+                return SWITCH_STATUS_TERM;
+        }
+
+        rv = switch_sockaddr_info_get(&amp;sa, Config::Instance()-&gt;GetListenAddress(), SWITCH_INET, Config::Instance()-&gt;GetXmlPort(), 0, pool);
+        if(rv)
+        {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;switch_sockaddr_info_get failed.\n&quot;);
+                return SWITCH_STATUS_TERM;
+        }
+        rv = switch_socket_create(&amp;listen_socket, switch_sockaddr_get_family(sa), SOCK_STREAM, SWITCH_PROTO_TCP, pool);
+        if(rv)
+        {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;switch_socket_create failed.\n&quot;);
+                return SWITCH_STATUS_TERM;
+        }
+
+        rv = switch_socket_opt_set(listen_socket, SWITCH_SO_REUSEADDR, 1);
+        if (rv)
+        {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;switch_socket_opt_set failed.\n&quot;);
+                return SWITCH_STATUS_TERM;
+        }
+        rv = switch_socket_bind(listen_socket, sa);
+        if (rv)
+        {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;switch_socket_bind failed.\n&quot;);
+                return SWITCH_STATUS_TERM;
+        }
+        rv = switch_socket_listen(listen_socket, 5);
+        if (rv)
+        {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;switch_socket_listen failed.\n&quot;);
+                return SWITCH_STATUS_TERM;
+        }
+                        
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, &quot;CSTA-XML socket up listening on %s:%u\n&quot;, Config::Instance()-&gt;GetListenAddress(),Config::Instance()-&gt;GetXmlPort());
+
+        while(bRunning)
+        {
+                if (switch_core_new_memory_pool(&amp;listener_pool) != SWITCH_STATUS_SUCCESS) 
+                {
+                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;OH OH no pool\n&quot;);
+                        return SWITCH_STATUS_TERM;
+                }
+                
+                if ((rv = switch_socket_accept(&amp;inbound_socket, listen_socket, listener_pool))) {
+                        if (!bRunning) {
+                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, &quot;Shutting Down\n&quot;);
+                        } else {
+                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;Socket Error\n&quot;);
+                        }
+                        break;
+                }
+                
+
+                switch_thread_t *thread;
+                switch_threadattr_t *thd_attr = NULL;
+                THREAD_INFO * thread_info=new THREAD_INFO;
+                thread_info-&gt;socket=inbound_socket;
+                thread_info-&gt;pool=listener_pool;
+
+                switch_threadattr_create(&amp;thd_attr, listener_pool);
+                switch_threadattr_detach_set(thd_attr, 1);
+                switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
+                switch_thread_create(&amp;thread, thd_attr, listener_run, thread_info, listener_pool);                
+
+        }
+
+        if(listen_socket)
+        {
+                switch_socket_shutdown(listen_socket, SWITCH_SHUTDOWN_READWRITE);
+                //switch_socket_close(listen_socket);
+                listen_socket=NULL;
+        }
+
+        return SWITCH_STATUS_TERM;
+}
+
+
</ins></span></pre></div>
<a id="freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketFreeSWITCHmod_csta_socketdef"></a>
<div class="addfile"><h4>Added: freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/mod_csta_socket.def (0 => 16050)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/mod_csta_socket.def                                (rev 0)
+++ freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/mod_csta_socket.def        2009-12-24 00:51:46 UTC (rev 16050)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+EXPORTS
+   mod_csta_socket_module_interface
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketFreeSWITCHmod_csta_socketvcproj"></a>
<div class="addfile"><h4>Added: freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/mod_csta_socket.vcproj (0 => 16050)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/mod_csta_socket.vcproj                                (rev 0)
+++ freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/mod_csta_socket.vcproj        2009-12-24 00:51:46 UTC (rev 16050)
</span><span class="lines">@@ -0,0 +1,353 @@
</span><ins>+&lt;?xml version=&quot;1.0&quot; encoding=&quot;Windows-1252&quot;?&gt;
+&lt;VisualStudioProject
+        ProjectType=&quot;Visual C++&quot;
+        Version=&quot;9,00&quot;
+        Name=&quot;FreeSWITCH_CSTA&quot;
+        ProjectGUID=&quot;{05515420-16DE-4E63-B373-85BE859A5142}&quot;
+        RootNamespace=&quot;mod_csta_socket&quot;
+        Keyword=&quot;Win32Proj&quot;
+        TargetFrameworkVersion=&quot;131072&quot;
+        &gt;
+        &lt;Platforms&gt;
+                &lt;Platform
+                        Name=&quot;Win32&quot;
+                /&gt;
+                &lt;Platform
+                        Name=&quot;x64&quot;
+                /&gt;
+        &lt;/Platforms&gt;
+        &lt;ToolFiles&gt;
+        &lt;/ToolFiles&gt;
+        &lt;Configurations&gt;
+                &lt;Configuration
+                        Name=&quot;Debug|Win32&quot;
+                        OutputDirectory=&quot;$(SolutionDir)$(ConfigurationName)&quot;
+                        IntermediateDirectory=&quot;$(ConfigurationName)&quot;
+                        ConfigurationType=&quot;2&quot;
+                        InheritedPropertySheets=&quot;..\..\..\..\..\w32\module_Debug.vsprops&quot;
+                        CharacterSet=&quot;2&quot;
+                        &gt;
+                        &lt;Tool
+                                Name=&quot;VCPreBuildEventTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCCustomBuildTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCXMLDataGeneratorTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCWebServiceProxyGeneratorTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCMIDLTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCCLCompilerTool&quot;
+                                AdditionalIncludeDirectories=&quot;&amp;quot;..\..\..\..\..\src\include&amp;quot;;&amp;quot;..\..\..\..\..\libs\include&amp;quot;;..\CSTAInsideCore\include\csta;..\CSTAInsideCore\include&quot;
+                                UsePrecompiledHeader=&quot;0&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCManagedResourceCompilerTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCResourceCompilerTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCPreLinkEventTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCLinkerTool&quot;
+                                AdditionalDependencies=&quot;freeswitchcore.lib libapr-1.lib CSTAInsideCore.lib&quot;
+                                OutputFile=&quot;..\..\..\..\..\$(ConfigurationName)/mod/mod_csta_socket.dll&quot;
+                                AdditionalLibraryDirectories=&quot;&amp;quot;..\..\..\..\..\w32\library\$(ConfigurationName)\&amp;quot;;&amp;quot;..\..\..\..\..\libs\win32\apr\$(ConfigurationName)\&amp;quot;;..\CSTAInsideCore\lib\VC90&quot;
+                                RandomizedBaseAddress=&quot;1&quot;
+                                DataExecutionPrevention=&quot;0&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCALinkTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCManifestTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCXDCMakeTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCBscMakeTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCFxCopTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCAppVerifierTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCPostBuildEventTool&quot;
+                        /&gt;
+                &lt;/Configuration&gt;
+                &lt;Configuration
+                        Name=&quot;Debug|x64&quot;
+                        ConfigurationType=&quot;2&quot;
+                        InheritedPropertySheets=&quot;..\..\..\..\..\w32\module_Debug.vsprops&quot;
+                        CharacterSet=&quot;2&quot;
+                        &gt;
+                        &lt;Tool
+                                Name=&quot;VCPreBuildEventTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCCustomBuildTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCXMLDataGeneratorTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCWebServiceProxyGeneratorTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCMIDLTool&quot;
+                                TargetEnvironment=&quot;3&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCCLCompilerTool&quot;
+                                UsePrecompiledHeader=&quot;0&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCManagedResourceCompilerTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCResourceCompilerTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCPreLinkEventTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCLinkerTool&quot;
+                                OutputFile=&quot;$(SolutionDir)$(PlatformName)\$(ConfigurationName)/mod/$(ProjectName).dll&quot;
+                                RandomizedBaseAddress=&quot;1&quot;
+                                DataExecutionPrevention=&quot;0&quot;
+                                TargetMachine=&quot;17&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCALinkTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCManifestTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCXDCMakeTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCBscMakeTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCFxCopTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCAppVerifierTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCPostBuildEventTool&quot;
+                        /&gt;
+                &lt;/Configuration&gt;
+                &lt;Configuration
+                        Name=&quot;Release|Win32&quot;
+                        OutputDirectory=&quot;$(SolutionDir)$(ConfigurationName)&quot;
+                        IntermediateDirectory=&quot;$(ConfigurationName)&quot;
+                        ConfigurationType=&quot;2&quot;
+                        InheritedPropertySheets=&quot;..\..\..\..\..\w32\module_Release.vsprops&quot;
+                        CharacterSet=&quot;2&quot;
+                        &gt;
+                        &lt;Tool
+                                Name=&quot;VCPreBuildEventTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCCustomBuildTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCXMLDataGeneratorTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCWebServiceProxyGeneratorTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCMIDLTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCCLCompilerTool&quot;
+                                Optimization=&quot;0&quot;
+                                AdditionalIncludeDirectories=&quot;&amp;quot;..\..\..\..\..\src\include&amp;quot;;&amp;quot;..\..\..\..\..\libs\include&amp;quot;;..\CSTAInsideCore\include\csta;..\CSTAInsideCore\include&quot;
+                                UsePrecompiledHeader=&quot;0&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCManagedResourceCompilerTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCResourceCompilerTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCPreLinkEventTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCLinkerTool&quot;
+                                AdditionalDependencies=&quot;freeswitchcore.lib libapr-1.lib CSTAInsideCore.lib&quot;
+                                OutputFile=&quot;..\..\..\..\..\$(ConfigurationName)/mod/mod_csta_socket.dll&quot;
+                                AdditionalLibraryDirectories=&quot;&amp;quot;..\..\..\..\..\w32\library\$(ConfigurationName)\&amp;quot;;&amp;quot;..\..\..\..\..\libs\win32\apr\$(ConfigurationName)\&amp;quot;;..\CSTAInsideCore\lib\VC90&quot;
+                                ModuleDefinitionFile=&quot;$(InputName).def&quot;
+                                RandomizedBaseAddress=&quot;1&quot;
+                                DataExecutionPrevention=&quot;0&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCALinkTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCManifestTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCXDCMakeTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCBscMakeTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCFxCopTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCAppVerifierTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCPostBuildEventTool&quot;
+                        /&gt;
+                &lt;/Configuration&gt;
+                &lt;Configuration
+                        Name=&quot;Release|x64&quot;
+                        ConfigurationType=&quot;2&quot;
+                        InheritedPropertySheets=&quot;..\..\..\..\..\w32\module_Release.vsprops&quot;
+                        CharacterSet=&quot;2&quot;
+                        &gt;
+                        &lt;Tool
+                                Name=&quot;VCPreBuildEventTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCCustomBuildTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCXMLDataGeneratorTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCWebServiceProxyGeneratorTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCMIDLTool&quot;
+                                TargetEnvironment=&quot;3&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCCLCompilerTool&quot;
+                                UsePrecompiledHeader=&quot;0&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCManagedResourceCompilerTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCResourceCompilerTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCPreLinkEventTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCLinkerTool&quot;
+                                OutputFile=&quot;$(SolutionDir)$(PlatformName)\$(ConfigurationName)/mod/$(ProjectName).dll&quot;
+                                RandomizedBaseAddress=&quot;1&quot;
+                                DataExecutionPrevention=&quot;0&quot;
+                                TargetMachine=&quot;17&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCALinkTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCManifestTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCXDCMakeTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCBscMakeTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCFxCopTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCAppVerifierTool&quot;
+                        /&gt;
+                        &lt;Tool
+                                Name=&quot;VCPostBuildEventTool&quot;
+                        /&gt;
+                &lt;/Configuration&gt;
+        &lt;/Configurations&gt;
+        &lt;References&gt;
+        &lt;/References&gt;
+        &lt;Files&gt;
+                &lt;Filter
+                        Name=&quot;Header Files&quot;
+                        &gt;
+                        &lt;File
+                                RelativePath=&quot;.\config.h&quot;
+                                &gt;
+                        &lt;/File&gt;
+                        &lt;File
+                                RelativePath=&quot;.\FreeSWITCH.h&quot;
+                                &gt;
+                        &lt;/File&gt;
+                        &lt;File
+                                RelativePath=&quot;.\FreeSWITCHPlatform.h&quot;
+                                &gt;
+                        &lt;/File&gt;
+                        &lt;File
+                                RelativePath=&quot;.\FreeSWITCHSocket.h&quot;
+                                &gt;
+                        &lt;/File&gt;
+                &lt;/Filter&gt;
+                &lt;Filter
+                        Name=&quot;Source Files&quot;
+                        &gt;
+                        &lt;File
+                                RelativePath=&quot;.\config.cpp&quot;
+                                &gt;
+                        &lt;/File&gt;
+                        &lt;File
+                                RelativePath=&quot;.\FreeSWITCH.cpp&quot;
+                                &gt;
+                        &lt;/File&gt;
+                        &lt;File
+                                RelativePath=&quot;.\FreeSWITCHPlatform.cpp&quot;
+                                &gt;
+                        &lt;/File&gt;
+                        &lt;File
+                                RelativePath=&quot;.\FreeSWITCHSocket.cpp&quot;
+                                &gt;
+                        &lt;/File&gt;
+                &lt;/Filter&gt;
+                &lt;File
+                        RelativePath=&quot;.\FreeSWITCH_CSTA.rc&quot;
+                        &gt;
+                &lt;/File&gt;
+                &lt;File
+                        RelativePath=&quot;.\mod_csta_socket.cpp&quot;
+                        &gt;
+                &lt;/File&gt;
+                &lt;File
+                        RelativePath=&quot;.\mod_csta_socket.def&quot;
+                        &gt;
+                &lt;/File&gt;
+                &lt;File
+                        RelativePath=&quot;.\README&quot;
+                        &gt;
+                &lt;/File&gt;
+                &lt;File
+                        RelativePath=&quot;.\resource.h&quot;
+                        &gt;
+                &lt;/File&gt;
+        &lt;/Files&gt;
+        &lt;Globals&gt;
+        &lt;/Globals&gt;
+&lt;/VisualStudioProject&gt;
</ins></span></pre></div>
<a id="freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketFreeSWITCHresourceh"></a>
<div class="addfile"><h4>Added: freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/resource.h (0 => 16050)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/resource.h                                (rev 0)
+++ freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/FreeSWITCH/resource.h        2009-12-24 00:51:46 UTC (rev 16050)
</span><span class="lines">@@ -0,0 +1,14 @@
</span><ins>+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by FreeSWITCH_CSTA.rc
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        101
+#define _APS_NEXT_COMMAND_VALUE         40001
+#define _APS_NEXT_CONTROL_VALUE         1001
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif
</ins></span></pre></div>
<a id="freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketmod_csta_socketsln"></a>
<div class="addfile"><h4>Added: freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/mod_csta_socket.sln (0 => 16050)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/mod_csta_socket.sln                                (rev 0)
+++ freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/mod_csta_socket.sln        2009-12-24 00:51:46 UTC (rev 16050)
</span><span class="lines">@@ -0,0 +1,37 @@
</span><ins>+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project(&quot;{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}&quot;) = &quot;FreeSWITCH_CSTA&quot;, &quot;FreeSWITCH\mod_csta_socket.vcproj&quot;, &quot;{05515420-16DE-4E63-B373-85BE859A5142}&quot;
+        ProjectSection(ProjectDependencies) = postProject
+                {4F92B672-DADB-4047-8D6A-4BB3796733FD} = {4F92B672-DADB-4047-8D6A-4BB3796733FD}
+        EndProjectSection
+EndProject
+Project(&quot;{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}&quot;) = &quot;Download CSTAInside&quot;, &quot;Download CSTAInside.vcproj&quot;, &quot;{4F92B672-DADB-4047-8D6A-4BB3796733FD}&quot;
+EndProject
+Global
+        GlobalSection(SolutionConfigurationPlatforms) = preSolution
+                Debug|Win32 = Debug|Win32
+                Debug|x64 = Debug|x64
+                Release|Win32 = Release|Win32
+                Release|x64 = Release|x64
+        EndGlobalSection
+        GlobalSection(ProjectConfigurationPlatforms) = postSolution
+                {05515420-16DE-4E63-B373-85BE859A5142}.Debug|Win32.ActiveCfg = Debug|Win32
+                {05515420-16DE-4E63-B373-85BE859A5142}.Debug|Win32.Build.0 = Debug|Win32
+                {05515420-16DE-4E63-B373-85BE859A5142}.Debug|x64.ActiveCfg = Debug|x64
+                {05515420-16DE-4E63-B373-85BE859A5142}.Debug|x64.Build.0 = Debug|x64
+                {05515420-16DE-4E63-B373-85BE859A5142}.Release|Win32.ActiveCfg = Release|Win32
+                {05515420-16DE-4E63-B373-85BE859A5142}.Release|Win32.Build.0 = Release|Win32
+                {05515420-16DE-4E63-B373-85BE859A5142}.Release|x64.ActiveCfg = Release|x64
+                {05515420-16DE-4E63-B373-85BE859A5142}.Release|x64.Build.0 = Release|x64
+                {4F92B672-DADB-4047-8D6A-4BB3796733FD}.Debug|Win32.ActiveCfg = Debug|Win32
+                {4F92B672-DADB-4047-8D6A-4BB3796733FD}.Debug|Win32.Build.0 = Debug|Win32
+                {4F92B672-DADB-4047-8D6A-4BB3796733FD}.Debug|x64.ActiveCfg = Debug|Win32
+                {4F92B672-DADB-4047-8D6A-4BB3796733FD}.Release|Win32.ActiveCfg = Release|Win32
+                {4F92B672-DADB-4047-8D6A-4BB3796733FD}.Release|Win32.Build.0 = Release|Win32
+                {4F92B672-DADB-4047-8D6A-4BB3796733FD}.Release|x64.ActiveCfg = Release|Win32
+        EndGlobalSection
+        GlobalSection(SolutionProperties) = preSolution
+                HideSolutionNode = FALSE
+        EndGlobalSection
+EndGlobal
</ins></span></pre></div>
<a id="freeswitchtrunkcontribmodevent_handlersmod_csta_socketmod_csta_socketutilvbs"></a>
<div class="addfile"><h4>Added: freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/util.vbs (0 => 16050)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/util.vbs                                (rev 0)
+++ freeswitch/trunk/contrib/mod/event_handlers/mod_csta_socket/mod_csta_socket/util.vbs        2009-12-24 00:51:46 UTC (rev 16050)
</span><span class="lines">@@ -0,0 +1,329 @@
</span><ins>+'
+' Contributor(s):
+' Michael Jerris &lt;mike@jerris.com&gt;
+' David A. Horner http://dave.thehorners.com
+'----------------------------------------------
+
+'On Error Resume Next
+' **************
+' Initialization
+' **************
+
+Set WshShell = CreateObject(&quot;WScript.Shell&quot;)
+Set FSO = CreateObject(&quot;Scripting.FileSystemObject&quot;)
+Set WshSysEnv = WshShell.Environment(&quot;SYSTEM&quot;)
+Set xml = CreateObject(&quot;Microsoft.XMLHTTP&quot;)
+Dim UseWgetEXE
+
+On Error Resume Next
+Set oStream = CreateObject(&quot;Adodb.Stream&quot;)
+On Error Goto 0
+
+If Not IsObject(oStream)  Then
+        wscript.echo(&quot;Failed to create Adodb.Stream, using alternative download method.&quot;)
+        UseWgetEXE=true
+Else
+        UseWgetEXE=false
+End If
+Randomize
+Set objArgs = WScript.Arguments
+quote=Chr(34)
+ScriptDir=Left(WScript.ScriptFullName,Len(WScript.ScriptFullName)-Len(WScript.ScriptName))
+UtilsDir=Showpath(ScriptDir)
+ToolsBase=&quot;http://files.freeswitch.org/downloads/win32/&quot;
+
+If UseWgetEXE Then
+        GetWgetEXE UtilsDir
+End If
+
+GetCompressionTools UtilsDir
+
+
+If objArgs.Count &gt;=3 Then
+        Select Case objArgs(0)
+                Case &quot;Get&quot;                
+                        Wget objArgs(1), Showpath(objArgs(2))
+                Case &quot;GetUnzip&quot;                
+                        WgetUnCompress objArgs(1), Showpath(objArgs(2))
+                Case &quot;Version&quot;                                        
+                        'CreateVersion(tmpFolder, VersionDir, includebase, includedest)
+                        CreateVersion Showpath(objArgs(1)), Showpath(objArgs(2)), objArgs(3), objArgs(4)
+        End Select
+End If
+
+
+' *******************
+' Utility Subroutines
+' *******************
+
+
+Sub WgetUnCompress(URL, DestFolder)
+        If Right(DestFolder, 1) &lt;&gt; &quot;\&quot; Then DestFolder = DestFolder &amp; &quot;\&quot; End If
+        StartPos = InstrRev(URL, &quot;/&quot;, -1, 1) 
+        strlength = Len(URL)
+        filename=Right(URL,strlength-StartPos)
+        NameEnd = InstrRev(filename, &quot;.&quot;,-1, 1)
+        filestrlength = Len(filename)
+        filebase = Left(filename,NameEnd)
+        fileext = Right(filename, Len(filename) - NameEnd)
+        Wget URL, DestFolder
+        If fileext = &quot;zip&quot; Then
+                UnCompress Destfolder &amp; filename, DestFolder &amp; filebase
+        Else
+                UnCompress Destfolder &amp; filename, DestFolder        
+        End If
+End Sub
+
+Sub GetCompressionTools(DestFolder)
+        Dim oExec
+        If Right(DestFolder, 1) &lt;&gt; &quot;\&quot; Then DestFolder = DestFolder &amp; &quot;\&quot; End If
+        If Not FSO.FileExists(DestFolder &amp; &quot;7za.exe&quot;) Then 
+                If Not FSO.FileExists(DestFolder &amp; &quot;7za.tag&quot;) Then 
+                        Set MyFile = fso.CreateTextFile(DestFolder &amp; &quot;7za.tag&quot;, True)
+                        MyFile.WriteLine(&quot;This file marks a pending download for 7za.exe so we don't download it twice at the same time&quot;)
+                        MyFile.Close
+                                
+                                Wget ToolsBase &amp; &quot;7za.exe&quot;, DestFolder
+                        
+                        FSO.DeleteFile DestFolder &amp; &quot;7za.tag&quot; ,true 
+                Else
+                        WScript.Sleep(5000)
+                End If        
+        End If        
+End Sub
+
+Sub GetWgetEXE(DestFolder)
+        Dim oExec
+        If Right(DestFolder, 1) &lt;&gt; &quot;\&quot; Then DestFolder = DestFolder &amp; &quot;\&quot; End If
+        If Not FSO.FileExists(DestFolder &amp; &quot;wget.exe&quot;) Then 
+                Slow_Wget ToolsBase &amp; &quot;wget.exe&quot;, DestFolder
+        End If        
+End Sub
+
+Sub UnCompress(Archive, DestFolder)
+        batname = &quot;tmp&quot; &amp; CStr(Int(10000*Rnd)) &amp; &quot;.bat&quot;
+        wscript.echo(&quot;Extracting: &quot; &amp; Archive)
+        Set MyFile = fso.CreateTextFile(UtilsDir &amp; batname, True)
+        MyFile.WriteLine(&quot;@&quot; &amp; quote &amp; UtilsDir &amp; &quot;7za.exe&quot; &amp; quote &amp; &quot; x &quot; &amp; quote &amp; Archive &amp; quote &amp; &quot; -y -o&quot; &amp; quote &amp; DestFolder &amp; quote )
+        MyFile.Close
+        Set oExec = WshShell.Exec(UtilsDir &amp; batname)
+        Do
+                WScript.Echo OExec.StdOut.ReadLine()
+        Loop While Not OExec.StdOut.atEndOfStream
+        If FSO.FileExists(Left(Archive, Len(Archive)-3))Then  
+                Set MyFile = fso.CreateTextFile(UtilsDir &amp; batname, True)
+                MyFile.WriteLine(&quot;@&quot; &amp; quote &amp; UtilsDir &amp; &quot;7za.exe&quot; &amp; quote &amp; &quot; x &quot; &amp; quote &amp; Left(Archive, Len(Archive)-3) &amp; quote &amp; &quot; -y -o&quot; &amp; quote &amp; DestFolder &amp; quote )
+                MyFile.Close
+                Set oExec = WshShell.Exec(UtilsDir &amp; batname)
+                Do
+                        WScript.Echo OExec.StdOut.ReadLine()
+                Loop While Not OExec.StdOut.atEndOfStream
+                WScript.Sleep(500)
+                FSO.DeleteFile Left(Archive, Len(Archive)-3) ,true 
+        End If
+        If FSO.FileExists(Left(Archive, Len(Archive)-3) &amp; &quot;tar&quot;)Then  
+                Set MyFile = fso.CreateTextFile(UtilsDir &amp; batname, True)
+                MyFile.WriteLine(&quot;@&quot; &amp; quote &amp; UtilsDir &amp; &quot;7za.exe&quot; &amp; quote &amp; &quot; x &quot; &amp; quote &amp; Left(Archive, Len(Archive)-3) &amp; &quot;tar&quot; &amp; quote &amp; &quot; -y -o&quot; &amp; quote &amp; DestFolder &amp; quote )
+                MyFile.Close
+                Set oExec = WshShell.Exec(UtilsDir &amp; batname)
+                Do
+                        WScript.Echo OExec.StdOut.ReadLine()
+                Loop While Not OExec.StdOut.atEndOfStream
+                WScript.Sleep(500)
+                FSO.DeleteFile Left(Archive, Len(Archive)-3) &amp; &quot;tar&quot;,true 
+        End If
+        
+        WScript.Sleep(500)
+        If FSO.FileExists(UtilsDir &amp; batname)Then  
+                FSO.DeleteFile UtilsDir &amp; batname, True
+        End If
+End Sub
+
+Sub Wget(URL, DestFolder)
+        StartPos = InstrRev(URL, &quot;/&quot;, -1, 1)   
+        strlength = Len(URL)
+        filename=Right(URL,strlength-StartPos)
+        If Right(DestFolder, 1) &lt;&gt; &quot;\&quot; Then DestFolder = DestFolder &amp; &quot;\&quot; End If
+
+        Wscript.echo(&quot;Downloading: &quot; &amp; URL)
+        
+If UseWgetEXE Then
+        batname = &quot;tmp&quot; &amp; CStr(Int(10000*Rnd)) &amp; &quot;.bat&quot;
+        Set MyFile = fso.CreateTextFile(UtilsDir &amp; batname, True)
+        MyFile.WriteLine(&quot;@cd &quot; &amp; quote &amp; DestFolder &amp; quote)
+        MyFile.WriteLine(&quot;@&quot; &amp; quote &amp; UtilsDir &amp; &quot;wget.exe&quot; &amp; quote &amp; &quot; &quot; &amp; URL)
+        MyFile.Close
+        Set oExec = WshShell.Exec(UtilsDir &amp; batname)
+        Do
+                WScript.Echo OExec.StdOut.ReadLine()
+        Loop While Not OExec.StdOut.atEndOfStream
+
+Else
+        xml.Open &quot;GET&quot;, URL, False
+        xml.Send
+        
+        Const adTypeBinary = 1
+        Const adSaveCreateOverWrite = 2
+        Const adSaveCreateNotExist = 1 
+
+        oStream.type = adTypeBinary
+        oStream.open
+        oStream.write xml.responseBody
+        oStream.savetofile DestFolder &amp; filename, adSaveCreateOverWrite
+        oStream.close
+End If
+
+End Sub
+
+Sub Slow_Wget(URL, DestFolder)
+        StartPos = InstrRev(URL, &quot;/&quot;, -1, 1)   
+        strlength = Len(URL)
+        filename=Right(URL,strlength-StartPos)
+        If Right(DestFolder, 1) &lt;&gt; &quot;\&quot; Then DestFolder = DestFolder &amp; &quot;\&quot; End If
+
+        Wscript.echo(&quot;Downloading: &quot; &amp; URL)
+        xml.Open &quot;GET&quot;, URL, False
+        xml.Send
+        
+        const ForReading = 1 , ForWriting = 2 , ForAppending = 8 
+Set MyFile = fso.OpenTextFile(DestFolder &amp; filename ,ForWriting, True)
+For i = 1 to lenb(xml.responseBody)
+ MyFile.write Chr(Ascb(midb(xml.responseBody,i,1)))
+Next
+MyFile.Close()
+
+End Sub
+
+Function Showpath(folderspec)
+        Set f = FSO.GetFolder(folderspec)
+        showpath = f.path &amp; &quot;\&quot;
+End Function
+
+
+Function FindVersionStringInConfigure(strConfigFile, strVersionString)
+
+Set objRegEx = CreateObject(&quot;VBScript.RegExp&quot;)
+objRegEx.Pattern = &quot;[^#]AC_SUBST\(&quot; &amp; strVersionString &amp; &quot;.*\[([^\[]*)\]&quot;

+Set objFSO = CreateObject(&quot;Scripting.FileSystemObject&quot;)
+Set objFile = objFSO.OpenTextFile(strConfigFile, 1)
+strSearchString = objFile.ReadAll
+objFile.Close
+
+Set colMatches = objRegEx.Execute(strSearchString)  
+
+strResult = &quot;&quot;
+If colMatches.Count &gt; 0 Then
+   For Each strMatch in colMatches   
+        strResult = objRegEx.Replace(strMatch.Value, &quot;$1&quot;)
+    Next
+End If
+
+        FindVersionStringInConfigure = strResult
+
+End Function
+
+Sub FindReplaceInFile(FileName, sFind, sReplace)
+        Const OpenAsASCII = 0  ' Opens the file as ASCII (TristateFalse) 
+        Const OpenAsUnicode = -1  ' Opens the file as Unicode (TristateTrue) 
+        Const OpenAsDefault = -2  ' Opens the file using the system default 
+        
+        Const OverwriteIfExist = -1 
+        Const FailIfNotExist   =  0 
+        Const ForReading       =  1 
+        
+        Set fOrgFile = FSO.OpenTextFile(FileName, ForReading, FailIfNotExist, OpenAsASCII)
+        sText = fOrgFile.ReadAll
+        fOrgFile.Close
+        sText = Replace(sText, sFind, sReplace)
+        Set fNewFile = FSO.CreateTextFile(FileName, OverwriteIfExist, OpenAsASCII)
+        fNewFile.WriteLine sText
+        fNewFile.Close
+End Sub
+
+Sub CreateVersion(tmpFolder, VersionDir, includebase, includedest)
+        Dim oExec
+        
+        strVerMajor = FindVersionStringInConfigure(VersionDir &amp; &quot;configure.in&quot;, &quot;SWITCH_VERSION_MAJOR&quot;)
+        strVerMinor = FindVersionStringInConfigure(VersionDir &amp; &quot;configure.in&quot;, &quot;SWITCH_VERSION_MINOR&quot;)
+        strVerMicro = FindVersionStringInConfigure(VersionDir &amp; &quot;configure.in&quot;, &quot;SWITCH_VERSION_MICRO&quot;)
+        strVerRev   = FindVersionStringInConfigure(VersionDir &amp; &quot;configure.in&quot;, &quot;SWITCH_VERSION_REVISION&quot;)
+        
+        If Right(tmpFolder, 1) &lt;&gt; &quot;\&quot; Then tmpFolder = tmpFolder &amp; &quot;\&quot; End If
+        If Not FSO.FileExists(tmpFolder &amp; &quot;fs_svnversion.exe&quot;) Then 
+                Wget ToolsBase &amp; &quot;fs_svnversion.exe&quot;, tmpFolder
+        End If        
+
+        If Not FSO.FileExists(tmpFolder &amp; &quot;libdb44.dll&quot;) Then 
+                Wget ToolsBase &amp; &quot;libdb44.dll&quot;, tmpFolder
+        End If        
+        If Not FSO.FileExists(tmpFolder &amp; &quot;libsvn_diff-1.dll&quot;) Then 
+                Wget ToolsBase &amp; &quot;libsvn_diff-1.dll&quot;, tmpFolder
+        End If        
+        If Not FSO.FileExists(tmpFolder &amp; &quot;libsvn_subr-1.dll&quot;) Then 
+                Wget ToolsBase &amp; &quot;libsvn_subr-1.dll&quot;, tmpFolder
+        End If        
+        If Not FSO.FileExists(tmpFolder &amp; &quot;libsvn_wc-1.dll&quot;) Then 
+                Wget ToolsBase &amp; &quot;libsvn_wc-1.dll&quot;, tmpFolder
+        End If        
+        If Not FSO.FileExists(tmpFolder &amp; &quot;intl3_svn.dll&quot;) Then 
+                Wget ToolsBase &amp; &quot;intl3_svn.dll&quot;, tmpFolder
+        End If        
+        If Not FSO.FileExists(tmpFolder &amp; &quot;libapr-1.dll&quot;) Then 
+                Wget ToolsBase &amp; &quot;libapr-1.dll&quot;, tmpFolder
+        End If        
+        If Not FSO.FileExists(tmpFolder &amp; &quot;libaprutil-1.dll&quot;) Then 
+                Wget ToolsBase &amp; &quot;libaprutil-1.dll&quot;, tmpFolder
+        End If        
+        If Not FSO.FileExists(tmpFolder &amp; &quot;libapriconv-1.dll&quot;) Then 
+                Wget ToolsBase &amp; &quot;libapriconv-1.dll&quot;, tmpFolder
+        End If        
+        If Not FSO.FileExists(tmpFolder &amp; &quot;libsvn_delta-1.dll&quot;) Then 
+                Wget ToolsBase &amp; &quot;libsvn_delta-1.dll&quot;, tmpFolder
+        End If        
+
+        Dim sLastFile
+        Const OverwriteIfExist = -1
+        Const ForReading       =  1
+
+        if strVerRev = &quot;&quot; Then
+            VersionCmd=&quot;fs_svnversion &quot; &amp; quote &amp; VersionDir &amp; &quot;.&quot; &amp; quote &amp;  &quot; -n&quot;
+            Set MyFile = fso.CreateTextFile(tmpFolder &amp; &quot;tmpVersion.Bat&quot;, True)
+            MyFile.WriteLine(&quot;@&quot; &amp; &quot;cd &quot; &amp; quote &amp; tmpFolder &amp; quote )
+            MyFile.WriteLine(&quot;@&quot; &amp; VersionCmd)
+            MyFile.Close
+            Set oExec = WshShell.Exec(&quot;cmd /C &quot; &amp; quote &amp; tmpFolder &amp; &quot;tmpVersion.Bat&quot; &amp; quote)
+            Do
+                    strFromProc = OExec.StdOut.ReadLine()
+                    VERSION=strFromProc
+            Loop While Not OExec.StdOut.atEndOfStream
+            sLastVersion = &quot;&quot;
+            Set sLastFile = FSO.OpenTextFile(tmpFolder &amp; &quot;lastversion&quot;, ForReading, true, OpenAsASCII)
+            If Not sLastFile.atEndOfStream Then
+                    sLastVersion = sLastFile.ReadLine()
+            End If
+            sLastFile.Close
+    End If
+        
+        if strVerRev &lt;&gt; &quot;&quot; Then
+            VERSION = strVerRev
+        End If
+
+        If VERSION = &quot;&quot; Then
+                VERSION = &quot;UNKNOWN&quot;
+        End If
+
+        If VERSION &lt;&gt; sLastVersion Then
+                Set MyFile = fso.CreateTextFile(tmpFolder &amp; &quot;lastversion&quot;, True)
+                MyFile.WriteLine(VERSION)
+                MyFile.Close
+        
+                FSO.CopyFile includebase, includedest, true
+                FindReplaceInFile includedest, &quot;@SWITCH_VERSION_REVISION@&quot;, VERSION
+                FindReplaceInFile includedest, &quot;@SWITCH_VERSION_MAJOR@&quot;, strVerMajor
+                FindReplaceInFile includedest, &quot;@SWITCH_VERSION_MINOR@&quot;, strVerMinor
+                FindReplaceInFile includedest, &quot;@SWITCH_VERSION_MICRO@&quot;, strVerMicro
+
+        End If
+        
+End Sub
</ins></span></pre>
</div>
</div>
<div id="footer">See you at ClueCon</div>

</body>
</html>