<!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][15223] </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=15223">15223</a></dd>
<dt>Author</dt> <dd>bottleman</dd>
<dt>Date</dt> <dd>2009-10-23 20:48:45 -0500 (Fri, 23 Oct 2009)</dd>
</dl>

<h3>Log Message</h3>
<pre>initial commit</pre>

<h3>Added Paths</h3>
<ul>
<li><a href="#freeswitchtrunksrcmodendpointsmod_h323Makefile">freeswitch/trunk/src/mod/endpoints/mod_h323/Makefile</a></li>
<li><a href="#freeswitchtrunksrcmodendpointsmod_h323bugs">freeswitch/trunk/src/mod/endpoints/mod_h323/bugs</a></li>
<li><a href="#freeswitchtrunksrcmodendpointsmod_h323changestxt">freeswitch/trunk/src/mod/endpoints/mod_h323/changes.txt</a></li>
<li><a href="#freeswitchtrunksrcmodendpointsmod_h323h323confxml">freeswitch/trunk/src/mod/endpoints/mod_h323/h323.conf.xml</a></li>
<li><a href="#freeswitchtrunksrcmodendpointsmod_h323mod_h323cpp">freeswitch/trunk/src/mod/endpoints/mod_h323/mod_h323.cpp</a></li>
<li><a href="#freeswitchtrunksrcmodendpointsmod_h323mod_h323h">freeswitch/trunk/src/mod/endpoints/mod_h323/mod_h323.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="freeswitchtrunksrcmodendpointsmod_h323Makefile"></a>
<div class="addfile"><h4>Added: freeswitch/trunk/src/mod/endpoints/mod_h323/Makefile (0 => 15223)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/src/mod/endpoints/mod_h323/Makefile                                (rev 0)
+++ freeswitch/trunk/src/mod/endpoints/mod_h323/Makefile        2009-10-24 01:48:45 UTC (rev 15223)
</span><span class="lines">@@ -0,0 +1,5 @@
</span><ins>+BASE=../../../..
+LOCAL_CFLAGS+=-g -I/usr/include/ptlib -I/usr/local/src/h323plus/include  -I. -DPTRACING=1 -D_REENTRANT -fno-exceptions
+LOCAL_LDFLAGS= -L/usr/local/src/h323plus/lib -lh323_linux_x86_ -lpt -lrt 
+
+include $(BASE)/build/modmake.rules
</ins></span></pre></div>
<a id="freeswitchtrunksrcmodendpointsmod_h323bugs"></a>
<div class="addfile"><h4>Added: freeswitch/trunk/src/mod/endpoints/mod_h323/bugs (0 => 15223)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/src/mod/endpoints/mod_h323/bugs                                (rev 0)
+++ freeswitch/trunk/src/mod/endpoints/mod_h323/bugs        2009-10-24 01:48:45 UTC (rev 15223)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+faststart and codecs v CallProceeding due to h323plus, grep &quot;Very Frustrating - S.H.&quot; in h323plus 
+source and uncomment commented lines.
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="freeswitchtrunksrcmodendpointsmod_h323changestxt"></a>
<div class="addfile"><h4>Added: freeswitch/trunk/src/mod/endpoints/mod_h323/changes.txt (0 => 15223)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/src/mod/endpoints/mod_h323/changes.txt                                (rev 0)
+++ freeswitch/trunk/src/mod/endpoints/mod_h323/changes.txt        2009-10-24 01:48:45 UTC (rev 15223)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+
+fix misstype in codec conversion.
+fix rtp issue causes choppy sound.
+fix progress ind handling on outbound calls.
+fix crash on log line, btw not understand why.
+implement dtmf transfer.
+fix codec name conversion a bit.
+fix crash on inbound fast start connection.
+
+initial release.
</ins></span></pre></div>
<a id="freeswitchtrunksrcmodendpointsmod_h323h323confxml"></a>
<div class="addfile"><h4>Added: freeswitch/trunk/src/mod/endpoints/mod_h323/h323.conf.xml (0 => 15223)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/src/mod/endpoints/mod_h323/h323.conf.xml                                (rev 0)
+++ freeswitch/trunk/src/mod/endpoints/mod_h323/h323.conf.xml        2009-10-24 01:48:45 UTC (rev 15223)
</span><span class="lines">@@ -0,0 +1,18 @@
</span><ins>+&lt;configuration name=&quot;h323.conf&quot; description=&quot;H323 Endpoints&quot;&gt;
+  &lt;settings&gt;
+    &lt;param name=&quot;trace-level&quot; value=&quot;10&quot;/&gt;
+    &lt;param name=&quot;context&quot; value=&quot;default&quot;/&gt;
+    &lt;param name=&quot;dialplan&quot; value=&quot;XML&quot;/&gt;
+    &lt;param name=&quot;codec-prefs&quot; value=&quot;PCMA,GSM,G729,G726&quot;/&gt;
+    &lt;param name=&quot;gk-address&quot; value=&quot;&quot;/&gt;    &lt;!-- empty to disable, &quot;*&quot; to search LAN --&gt;
+    &lt;param name=&quot;gk-identifer&quot; value=&quot;&quot;/&gt;  &lt;!-- optional name of gk --&gt;
+    &lt;param name=&quot;gk-interface&quot; value=&quot;&quot;/&gt;  &lt;!-- optional listener interface name --&gt;
+  &lt;/settings&gt;
+  &lt;listeners&gt;
+    &lt;listener name=&quot;default&quot;&gt;
+      &lt;param name=&quot;h323-ip&quot; value=&quot;$${local_ip_v4}&quot;/&gt;
+      &lt;param name=&quot;h323-port&quot; value=&quot;1720&quot;/&gt;
+    &lt;/listener&gt;
+  &lt;/listeners&gt;
+&lt;/configuration&gt;
+
</ins></span></pre></div>
<a id="freeswitchtrunksrcmodendpointsmod_h323mod_h323cpp"></a>
<div class="addfile"><h4>Added: freeswitch/trunk/src/mod/endpoints/mod_h323/mod_h323.cpp (0 => 15223)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/src/mod/endpoints/mod_h323/mod_h323.cpp                                (rev 0)
+++ freeswitch/trunk/src/mod/endpoints/mod_h323/mod_h323.cpp        2009-10-24 01:48:45 UTC (rev 15223)
</span><span class="lines">@@ -0,0 +1,1485 @@
</span><ins>+
+
+#include &quot;mod_h323.h&quot;
+
+SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_codec_string, mod_h323_globals.codec_string);
+SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_context, mod_h323_globals.context);
+SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_dialplan, mod_h323_globals.dialplan);
+
+
+SWITCH_MODULE_LOAD_FUNCTION(mod_h323_load);
+SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_h323_shutdown);
+SWITCH_MODULE_DEFINITION(mod_h323, mod_h323_load, mod_h323_shutdown, NULL);
+
+#define CF_NEED_FLUSH (1 &lt;&lt; 1)
+struct mod_h323_globals mod_h323_globals = { 0 };
+
+static switch_call_cause_t create_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
+                                                   switch_caller_profile_t *outbound_profile, switch_core_session_t **new_session,
+                                                   switch_memory_pool_t **pool, switch_originate_flag_t flags);
+
+static const char modulename[] = &quot;h323&quot;;
+static const char* h323_formats[] = {
+    &quot;G.711-ALaw-64k&quot;, &quot;PCMA&quot;,
+    &quot;G.711-uLaw-64k&quot;, &quot;PCMU&quot;,
+    &quot;GSM-06.10&quot;, &quot;GSM&quot;,
+    &quot;MS-GSM&quot;, &quot;msgsm&quot;,
+    &quot;SpeexNarrow&quot;, &quot;speex&quot;,
+    &quot;LPC-10&quot;, &quot;lpc10&quot;,
+    &quot;iLBC-15k2&quot;, &quot;ilbc20&quot;,
+    &quot;iLBC-13k3&quot;, &quot;ilbc30&quot;,
+    &quot;G.723&quot;, &quot;G723&quot;,
+    &quot;G.726&quot;, &quot;G726&quot;,
+    &quot;G.728&quot;, &quot;G728&quot;,
+    &quot;G.729B&quot;, &quot;G729b&quot;,
+    &quot;G.729&quot;, &quot;G729&quot;,
+    &quot;PCM-16&quot;, &quot;slin&quot;,
+    &quot;G.729A&quot;, &quot;G729a&quot;,
+    &quot;G.729A/B&quot;, &quot;G729ab&quot;,
+    &quot;G.723.1&quot;, &quot;G723.1&quot;,
+    &quot;G.723.1(5.3k)&quot;, &quot;G723.1-5k3&quot;,
+    &quot;G.723.1A(5.3k)&quot;, &quot;G723.1a-5k3&quot;,
+    &quot;G.723.1A(6.3k)&quot;, &quot;G723.1a-6k3&quot;,
+    &quot;G.723.1A(6.3k)-Cisco&quot;, &quot;g723.1a-6k3-cisco&quot;,
+    &quot;G.726-16k&quot;, &quot;G726-16&quot;,
+    &quot;G.726-24k&quot;, &quot;G726-24&quot;,
+    &quot;G.726-32k&quot;, &quot;G726-32&quot;,
+    &quot;G.726-40k&quot;, &quot;G726-40&quot;,
+    &quot;iLBC&quot;, &quot;ilbc&quot;,
+    &quot;SpeexNarrow-18.2k&quot;, &quot;speex-18k2&quot;,
+    &quot;SpeexNarrow-15k&quot;, &quot;speex-15k&quot;,
+    &quot;SpeexNarrow-11k&quot;, &quot;speex-11k&quot;,
+    &quot;SpeexNarrow-8k&quot;, &quot;speex-8k&quot;,
+    &quot;SpeexNarrow-5.95k&quot;, &quot;speex-5k95&quot;,
+    0
+};
+
+static switch_status_t on_hangup(switch_core_session_t *session);
+static switch_status_t on_destroy(switch_core_session_t *session);
+
+
+static switch_io_routines_t h323fs_io_routines = {
+    /*.outgoing_channel */ create_outgoing_channel,
+    /*.read_frame */ FSH323Connection::read_audio_frame,
+    /*.write_frame */ FSH323Connection::write_audio_frame,
+    /*.kill_channel */ FSH323Connection::kill_channel,
+    /*.send_dtmf */ FSH323Connection::send_dtmf,
+    /*.receive_message */ FSH323Connection::receive_message,
+    /*.receive_event */ FSH323Connection::receive_event,
+    /*.state_change */ FSH323Connection::state_change,
+    /*.read_video_frame */ FSH323Connection::read_video_frame,
+    /*.write_video_frame */ FSH323Connection::write_video_frame
+};
+
+static switch_state_handler_table_t h323fs_event_handlers = {
+    /*.on_init */ FSH323Connection::on_init,
+    /*.on_routing */ FSH323Connection::on_routing,
+    /*.on_execute */ FSH323Connection::on_execute,
+    /*.on_hangup */ on_hangup,
+    /*.on_exchange_media */ FSH323Connection::on_exchange_media,
+    /*.on_soft_execute */ FSH323Connection::on_soft_execute,
+    /*.on_consume_media*/ NULL,
+    /*.on_hibernate*/ NULL,
+    /*.on_reset*/ NULL,
+    /*.on_park*/ NULL,
+    /*.on_reporting*/ NULL,
+    /*.on_destroy*/ on_destroy
+};
+
+
+static FSProcess *opal_process = NULL;
+SWITCH_MODULE_LOAD_FUNCTION(mod_h323_load){
+    switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, &quot;Starting loading mod_h323\n&quot;);
+

+    *module_interface = switch_loadable_module_create_module_interface(pool, modname);
+                        
+    if (!*module_interface) {
+        return SWITCH_STATUS_MEMERR;
+    }
+
+    h323_process = new FSProcess();
+    if (h323_process == NULL) {
+        return SWITCH_STATUS_MEMERR;
+    }
+
+    if (h323_process-&gt;Initialise(*module_interface)) {
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, &quot;Opal manager initialized and running\n&quot;);
+        //unloading causes a seg in linux
+        return SWITCH_STATUS_NOUNLOAD;
+        //return SWITCH_STATUS_SUCCESS;
+    }
+
+    delete h323_process;
+    h323_process = NULL;
+    return SWITCH_STATUS_FALSE;
+}
+
+SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_h323_shutdown){
+    
+    switch_safe_free(mod_h323_globals.context);
+    switch_safe_free(mod_h323_globals.dialplan);
+    switch_safe_free(mod_h323_globals.codec_string);
+    delete h323_process;
+    h323_process = NULL;
+    return SWITCH_STATUS_SUCCESS;
+}
+
+
+
+#if PTRACING
+
+class FSTrace : public ostream {
+ public:
+ FSTrace()
+     : ostream(&amp;buffer)
+        {
+        }
+
+ private:
+ class Buffer : public streambuf {
+        char buffer[250];
+
+    public:
+        Buffer()
+            {
+                setg(buffer, buffer, &amp;buffer[sizeof(buffer)-2]);
+                setp(buffer, &amp;buffer[sizeof(buffer)-2]);
+            }
+
+        virtual int sync()
+        {
+            return overflow(EOF);
+        }
+
+        virtual int underflow()
+        {
+            return EOF;
+        }
+
+        virtual int overflow(int c)
+        {
+            const char *fmt = &quot;%s&quot;;
+            char *func = NULL;
+
+            int bufSize = pptr() - pbase();
+
+            if (c != EOF) {
+                *pptr() = (char)c;
+                bufSize++;
+            }
+            
+            if (bufSize != 0) {
+                char *bufPtr = pbase();
+                char *bufEndPtr = NULL;
+                setp(bufPtr, epptr());
+                bufPtr[bufSize] = '\0';
+                int line = 0;
+                char *p;
+                
+                char *file = NULL;
+                switch_log_level_t level;
+
+                
+                switch (strtoul(bufPtr, &amp;file, 10)) {
+                case 1 :
+                    level = SWITCH_LOG_INFO;
+                    break;
+                default :
+                    level = SWITCH_LOG_DEBUG;
+                    break;
+                }
+
+                if (file) {
+                    while (isspace(*file)) file++;
+                    
+                    if (file &amp;&amp; (bufPtr = strchr(file, '(')) &amp;&amp; (bufEndPtr = strchr(bufPtr, ')'))) {
+                        char *e;
+
+                        for(p = bufPtr; p &amp;&amp; *p; p++) {
+                            if (*p == '\t') {
+                                *p = ' ';
+                            }
+                        }
+
+                        *bufPtr++ = '\0';
+                        line = atoi(bufPtr);
+                        while (bufEndPtr &amp;&amp; isspace(*(++bufEndPtr)));
+                        bufPtr = bufEndPtr;
+                        if (bufPtr &amp;&amp; (e = strchr(bufPtr, ' ')) || (e = strchr(bufPtr, '\t'))) {
+                            func = bufPtr;
+                            bufPtr = e;
+                            *bufPtr++ = '\0';
+                        }
+                    }
+                }
+                
+                switch_text_channel_t tchannel = SWITCH_CHANNEL_ID_LOG;
+
+                if (!bufPtr) {
+                    bufPtr = pbase();
+                    level = SWITCH_LOG_DEBUG;
+                }
+
+                if (bufPtr) {
+                    if (end_of(bufPtr) != '\n') {
+                        fmt = &quot;%s\n&quot;;
+                    }
+                    if (!(file &amp;&amp; func &amp;&amp; line)) tchannel = SWITCH_CHANNEL_ID_LOG_CLEAN;
+
+                    switch_log_printf(tchannel, file, func, line, NULL, level, fmt, bufPtr);
+                }
+                
+            }
+
+            return 0;
+        }
+    } buffer;
+};
+
+#endif
+
+PString GetH245CodecName(const H245_AudioCapability &amp;cap){
+        switch (cap.GetTag()) {
+        case H245_AudioCapability::e_g711Alaw64k:
+        case H245_AudioCapability::e_g711Alaw56k:
+                return &quot;PCMA&quot;;
+        case H245_AudioCapability::e_g711Ulaw64k:
+        case H245_AudioCapability::e_g711Ulaw56k:
+                return &quot;PCMU&quot;;
+        case H245_AudioCapability::e_g722_64k:
+        case H245_AudioCapability::e_g722_56k:
+        case H245_AudioCapability::e_g722_48k:
+                return &quot;G722&quot;;
+        case H245_AudioCapability::e_g728:
+                return &quot;G728&quot;;
+        case H245_AudioCapability::e_g729:
+        case H245_AudioCapability::e_g729AnnexA:
+        case H245_AudioCapability::e_g729wAnnexB:
+        case H245_AudioCapability::e_g729AnnexAwAnnexB:
+                return &quot;G729&quot;;
+        case H245_AudioCapability::e_g7231:
+        case H245_AudioCapability::e_g7231AnnexCCapability:
+                return &quot;G723&quot;;
+        case H245_AudioCapability::e_gsmFullRate:
+        case H245_AudioCapability::e_gsmHalfRate:
+        case H245_AudioCapability::e_gsmEnhancedFullRate:
+                return &quot;GSM&quot;;
+        }
+        return &quot;Unknown&quot;;
+}
+
+FSProcess::FSProcess()
+  : PLibraryProcess(&quot;Test&quot;, &quot;mod_h323&quot;, 1, 0, AlphaCode, 1)
+  , m_h323endpoint(NULL){
+}
+
+
+FSProcess::~FSProcess(){
+  delete m_h323endpoint;
+}
+
+
+bool FSProcess::Initialise(switch_loadable_module_interface_t *iface){
+        PTRACE(4, &quot;mod_h323\t======&gt;FSProcess::Initialise &quot; &lt;&lt; *this);
+        
+  m_h323endpoint = new FSH323EndPoint();
+  return m_h323endpoint != NULL &amp;&amp; m_h323endpoint-&gt;Initialise(iface);
+}
+
+bool FSH323EndPoint::Initialise(switch_loadable_module_interface_t *iface){
+        PTRACE(4, &quot;mod_h323\t======&gt;FSManager::Initialise &quot; &lt;&lt; *this);
+    ReadConfig(false);
+
+    PTrace::SetLevel(mod_h323_globals.trace_level);        //just for fun and eyecandy ;)
+    PTrace::SetOptions(PTrace::TraceLevel);
+    PTrace::SetStream(new FSTrace);
+
+    m_freeswitch = (switch_endpoint_interface_t *) switch_loadable_module_create_interface(iface, SWITCH_ENDPOINT_INTERFACE);
+    m_freeswitch-&gt;interface_name = modulename;
+    m_freeswitch-&gt;io_routines = &amp;h323fs_io_routines;
+    m_freeswitch-&gt;state_handler = &amp;h323fs_event_handlers;
+                        
+        PString codec = ((const char *)mod_h323_globals.codec_string);
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;Config capabilliti %s \n&quot;,(const char *)codec);
+        if (!codec.IsEmpty()) {                
+                const char** f = h323_formats;
+                for (; *f; f += 2) {                        
+                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;Find capabilliti %s to %s\n&quot;,f[1],(const char *)codec);
+                        if (codec.Find(f[1]) != P_MAX_INDEX) {
+                                PString tmp = f[0];
+                                tmp += &quot;*{sw}&quot;;
+                                PINDEX init = GetCapabilities().GetSize();
+                                AddAllCapabilities(0, 0, tmp);
+                                PINDEX num = GetCapabilities().GetSize() - init;
+                                if (!num) {
+                                        // failed to add so pretend we support it in hardware
+                                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;H323 failed to add capability '%s' \n&quot;,(const char *)tmp);
+                                        tmp = f[0];
+                                        tmp += &quot;*{hw}&quot;;
+                                        AddAllCapabilities(0, 0, tmp);
+                                        num = GetCapabilities().GetSize() - init;
+                                }
+                                if (num)                                        
+                                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;H.323 added %d capabilities '%s' \n&quot;,num,(const char *)tmp);
+                                else
+                                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;H323 failed to add capability '%s' \n&quot;,(const char *)tmp);
+                                        
+                        }                
+                }
+        }
+
+
+                
+    AddAllUserInputCapabilities(0,1);
+         PTRACE(1, &quot;OpenPhone\tCapability Table:\n&quot; &lt;&lt; setprecision(4) &lt;&lt; capabilities);
+    if (m_listeners.empty()) {
+        StartListener(&quot;&quot;);
+    } else {
+        for (std::list &lt; FSListener &gt;::iterator it = m_listeners.begin(); it != m_listeners.end(); ++it) {
+            if (!StartListener(it-&gt;listenAddress)) {
+                PTRACE(3, &quot;mod_h323\tCannot start listener for &quot; &lt;&lt; it-&gt;name);
+            }
+        }
+    }
+
+/*
+    OpalMediaFormatList allCodecs = OpalMediaFormat::GetAllRegisteredMediaFormats();
+    for (OpalMediaFormatList::iterator it = allCodecs.begin(); it != allCodecs.end(); ++it) {
+      if (it-&gt;GetMediaType() == OpalMediaType::Audio()) {
+        it-&gt;SetOptionInteger(OpalAudioFormat::RxFramesPerPacketOption(), 1);
+        it-&gt;SetOptionInteger(OpalAudioFormat::TxFramesPerPacketOption(), 1);
+      }
+    }
+*/
+
+    if (!m_gkAddress.IsEmpty()) {
+      if (UseGatekeeper(m_gkAddress, m_gkIdentifer, m_gkInterface))
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, &quot;Started gatekeeper: %s\n&quot;,
+                          (const char *)GetGatekeeper()-&gt;GetName());
+      else
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
+                          &quot;Could not start gatekeeper: addr=\&quot;%s\&quot;, id=\&quot;%s\&quot;, if=\&quot;%s\&quot;\n&quot;,
+                          (const char *)m_gkAddress,
+                          (const char *)m_gkIdentifer,
+                          (const char *)m_gkInterface);
+    }
+
+    return TRUE;
+}
+
+switch_status_t FSH323EndPoint::ReadConfig(int reload){
+        PTRACE(4, &quot;mod_h323\t======&gt;FSH323EndPoint::ReadConfig &quot; &lt;&lt; *this);
+    const char *cf = &quot;h323.conf&quot;;
+    switch_status_t status = SWITCH_STATUS_SUCCESS;
+
+        switch_memory_pool_t *pool = NULL;
+    if ((status = switch_core_new_memory_pool(&amp;pool)) != SWITCH_STATUS_SUCCESS) {
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, &quot;Memory Error!\n&quot;);
+        return status;
+    }
+
+    set_global_context(&quot;default&quot;);
+    set_global_dialplan(&quot;XML&quot;);
+
+    switch_event_t *params = NULL;
+    switch_event_create(&amp;params, SWITCH_EVENT_REQUEST_PARAMS);
+    switch_assert(params);
+    switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, &quot;profile&quot;, switch_str_nil(&quot;&quot;));
+    switch_xml_t cfg;
+    switch_xml_t xml = switch_xml_open_cfg(cf, &amp;cfg, params);
+    if (xml == NULL) {
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;open of %s failed\n&quot;, cf);
+        return SWITCH_STATUS_FALSE;
+    }
+
+    switch_xml_t xmlSettings = switch_xml_child(cfg, &quot;settings&quot;);
+    if (xmlSettings) {
+        for (switch_xml_t xmlParam = switch_xml_child(xmlSettings, &quot;param&quot;); xmlParam != NULL; xmlParam = xmlParam-&gt;next) {
+            const char *var = switch_xml_attr_soft(xmlParam, &quot;name&quot;);
+            const char *val = switch_xml_attr_soft(xmlParam, &quot;value&quot;);
+
+            if (!strcasecmp(var, &quot;trace-level&quot;)) {
+                int level = atoi(val);
+                if (level &gt; 0) {
+                    mod_h323_globals.trace_level = level;
+                }
+            } else if (!strcasecmp(var, &quot;context&quot;)) {
+                set_global_context(val);
+            } else if (!strcasecmp(var, &quot;dialplan&quot;)) {
+                set_global_dialplan(val);
+            } else if (!strcasecmp(var, &quot;codec-prefs&quot;)) {
+                set_global_codec_string(val);
+            } else if (!strcasecmp(var, &quot;jitter-size&quot;)) {
+                char * next;
+                unsigned minJitter = strtoul(val, &amp;next, 10);
+                if (minJitter &gt;= 10) {
+                    unsigned maxJitter = minJitter;
+                    if (*next == ',')
+                      maxJitter = atoi(next+1);
+                    SetAudioJitterDelay(minJitter, maxJitter); // In milliseconds
+                } else{
+                                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;Set zero Jitter buffer\n&quot;);
+                                        SetAudioJitterDelay(0, 0);
+                                }
+            } else if (!strcasecmp(var, &quot;gk-address&quot;)) {
+                m_gkAddress = val;
+            } else if (!strcasecmp(var, &quot;gk-identifer&quot;)) {
+                m_gkIdentifer = val;
+            } else if (!strcasecmp(var, &quot;gk-interface&quot;)) {
+                m_gkInterface = val;
+            } else if (!strcasecmp(var, &quot;gk-prefix&quot;)) {
+                                m_gkPrefixes.AppendString(val);
+                        }
+        }
+    }
+
+    switch_xml_t xmlListeners = switch_xml_child(cfg, &quot;listeners&quot;);
+    if (xmlListeners != NULL) {
+        for (switch_xml_t xmlListener = switch_xml_child(xmlListeners, &quot;listener&quot;); xmlListener != NULL; xmlListener = xmlListener-&gt;next) {
+
+            m_listeners.push_back(FSListener());
+            FSListener &amp; listener = m_listeners.back();
+
+            listener.name = switch_xml_attr_soft(xmlListener, &quot;name&quot;);
+            if (listener.name.IsEmpty())
+                listener.name = &quot;unnamed&quot;;
+
+            PIPSocket::Address ip;
+            WORD port = 1720;
+
+            for (switch_xml_t xmlParam = switch_xml_child(xmlListener, &quot;param&quot;); xmlParam != NULL; xmlParam = xmlParam-&gt;next) {
+                const char *var = switch_xml_attr_soft(xmlParam, &quot;name&quot;);
+                const char *val = switch_xml_attr_soft(xmlParam, &quot;value&quot;);
+                //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;Var - '%s' and Val - '%s' \n&quot;, var, val);
+                if (!strcasecmp(var, &quot;h323-ip&quot;))
+                    ip = val;
+                else if (!strcasecmp(var, &quot;h323-port&quot;))
+                    port = (WORD) atoi(val);
+            }
+
+            listener.listenAddress = new H323ListenerTCP(*this,ip,port);
+            switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;Created Listener '%s'\n&quot;, (const char *) listener.name);
+        }
+    }
+
+    switch_event_destroy(&amp;params);
+
+    if (xml)
+        switch_xml_free(xml);
+
+    return status;
+}
+
+FSH323EndPoint::FSH323EndPoint(){
+        PTRACE(4, &quot;mod_h323\t======&gt;FSH323EndPoint::FSH323EndPoint &quot; &lt;&lt; *this);
+        terminalType = e_GatewayOnly;
+}        
+
+H323Connection  *FSH323EndPoint::CreateConnection(
+        unsigned callReference,
+        void* userData,
+        H323Transport* transport,
+        H323SignalPDU* setupPDU){
+        PTRACE(4, &quot;mod_h323\t======&gt;FSH323EndPoint::CreateConnection callReference = &quot;&lt;&lt; callReference &lt;&lt;&quot; userDate = &quot;&lt;&lt;userData&lt;&lt;&quot; [&quot; &lt;&lt; *this&lt;&lt;&quot;]&quot;);
+
+        if ((switch_caller_profile_t *)userData){
+                PTRACE(4, &quot;mod_h323\t------&gt; SWITCH_CALL_DIRECTION_OUTBOUND&quot;);
+        } else{
+                PTRACE(4, &quot;mod_h323\t------&gt; SWITCH_CALL_DIRECTION_INBOUND&quot;);
+        }
+        
+    switch_core_session_t *fsSession = switch_core_session_request(GetSwitchInterface(), 
+                                       (switch_caller_profile_t *)userData ? SWITCH_CALL_DIRECTION_OUTBOUND : SWITCH_CALL_DIRECTION_INBOUND, NULL);
+    if (fsSession == NULL)
+        return NULL;
+        
+        PTRACE(4, &quot;mod_h323\t------&gt; fsSession = &quot;&lt;&lt;fsSession);
+    switch_channel_t *fsChannel = switch_core_session_get_channel(fsSession);
+
+        if (fsChannel == NULL) {
+        switch_core_session_destroy(&amp;fsSession);
+        return NULL;
+        }
+        
+  return new FSH323Connection(*this,transport,callReference,(switch_caller_profile_t *)userData, fsSession, fsChannel);
+  
+}
+
+bool FSH323EndPoint::OnSetGatewayPrefixes(PStringList &amp; prefixes) const{
+        PTRACE(4, &quot;mod_h323\t======&gt;FSH323EndPoint::OnSetGatewayPrefixes &quot; &lt;&lt; *this);
+        if(m_gkPrefixes.GetSize() &gt; 0) {
+                PTRACE(4, &quot;mod_h323\tOnSetGatewayPrefixes &quot; &lt;&lt; m_gkPrefixes);
+                prefixes = m_gkPrefixes;
+                return true;
+        }
+        return false;
+}
+
+FSH323Connection::FSH323Connection(FSH323EndPoint&amp; endpoint, H323Transport* transport, unsigned callReference,  switch_caller_profile_t *outbound_profile, switch_core_session_t *fsSession, switch_channel_t *fsChannel)
+        : H323Connection(endpoint,callReference)
+        , m_endpoint(&amp;endpoint)
+        , m_fsSession(fsSession)
+    , m_fsChannel(fsChannel)
+        , m_callOnPreAnswer(false)
+        , m_startRTP(false){
+        PTRACE(4, &quot;mod_h323\t======&gt;FSH323Connection::FSH323Connection &quot; &lt;&lt; *this);
+
+    h323_private_t *tech_pvt = (h323_private_t *) switch_core_session_alloc(m_fsSession, sizeof(*tech_pvt));
+    tech_pvt-&gt;me = this;
+    switch_core_session_set_private(m_fsSession, tech_pvt);
+        
+        switch_mutex_init(&amp;tech_pvt-&gt;flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(m_fsSession));
+        switch_mutex_init(&amp;tech_pvt-&gt;h323_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(m_fsSession));
+        
+    if (outbound_profile != NULL) {
+        SetLocalPartyName(outbound_profile-&gt;caller_id_number);
+        SetDisplayName(outbound_profile-&gt;caller_id_name);
+
+        switch_caller_profile_t *caller_profile = switch_caller_profile_clone(m_fsSession, outbound_profile);
+        switch_channel_set_caller_profile(m_fsChannel, caller_profile);
+
+        PString name = &quot;h323/&quot;;
+        name += outbound_profile-&gt;destination_number;
+        switch_channel_set_name(m_fsChannel, name);
+
+        switch_channel_set_flag(m_fsChannel, CF_OUTBOUND);
+        switch_channel_set_state(m_fsChannel, CS_INIT);
+    }
+        
+        m_RTPlocalPort = switch_rtp_request_port((const char *)m_RTPlocalIP.AsString());
+}        
+
+FSH323Connection::~FSH323Connection(){
+    PTRACE(4, &quot;mod_h323\t======&gt;FSH323Connection::~FSH323Connection  [&quot;&lt;&lt;*this&lt;&lt;&quot;]&quot;);
+        h323_private_t *tech_pvt = (h323_private_t *) switch_core_session_get_private(m_fsSession);
+    tech_pvt-&gt;me = NULL;
+}        
+
+void FSH323Connection::OnSetLocalCapabilities(){
+        PTRACE(4, &quot;mod_h323\t======&gt;FSH323Connection::OnSetLocalCapabilities() [&quot; &lt;&lt; *this&lt;&lt;&quot;]&quot;);
+        H323Connection::OnSetLocalCapabilities();
+        SetLocalCapabilities();
+}
+
+bool FSH323Connection::SetLocalCapabilities(){
+        PTRACE(4, &quot;mod_h323\t======&gt;FSH323Connection::SetLocalCapabilities() Size local capability = &quot;&lt;&lt;localCapabilities.GetSize()&lt;&lt;&quot; [&quot; &lt;&lt; *this&lt;&lt;&quot;]&quot;);
+    if (!mod_h323_globals.codec_string)
+                return false;
+    
+    bool nocodecs = true;
+    bool changed = false;
+    for (int i = 0; i &lt; localCapabilities.GetSize(); i++) {
+                const char* format = 0;
+                PString fname;
+                decodeCapability(localCapabilities[i],&amp;format,0,&amp;fname);
+                if (format) {
+                        PString m_globalcodec = ((const char *)mod_h323_globals.codec_string);
+                        if (m_globalcodec.Find(format) &lt; 0) {
+                                PTRACE(1, &quot;mod_h323\tRemoving capability '&quot;&lt;&lt;fname&lt;&lt;&quot;' (&quot;&lt;&lt;format&lt;&lt;&quot;) not in remote '&quot;&lt;&lt;m_globalcodec&lt;&lt;&quot;'&quot;);
+                                changed = true;
+                                for (PINDEX idx = 0; idx &lt; fastStartChannels.GetSize(); idx++) {
+                                        if (fastStartChannels[idx].GetCapability() == localCapabilities[i]) {
+                                                PTRACE(1, &quot;mod_h323\tRemoving fast start channel &quot;&lt;&lt;fastStartChannels[idx].GetDirection()&lt;&lt;&quot; '&quot;&lt;&lt;fname&lt;&lt;&quot;' (&quot;&lt;&lt;format&lt;&lt;&quot;)&quot;);
+                                                fastStartChannels.RemoveAt(idx--);
+                                        }                
+                                }
+                                localCapabilities.Remove(fname);
+                                i--;
+                        } else        nocodecs = false;
+                }
+    }
+    if (nocodecs) {
+                PTRACE(3, &quot;mod_h323\tNo codecs remaining for H323 connection [&quot;&lt;&lt;*this&lt;&lt;&quot;]&quot;);
+                changed = false;
+                ClearCall(EndedByCapabilityExchange);                
+    }
+    return changed;
+}
+
+bool FSH323Connection::decodeCapability(const H323Capability&amp; capability, const char** dataFormat, int* payload, PString* capabName){
+        PTRACE(4, &quot;mod_h323\t======&gt;FSH323Connection::decodeCapability&quot;);
+    PString fname((const char *)capability.GetFormatName());
+  
+    if (fname.Find(&quot;{sw}&quot;) == (fname.GetLength() - 4))
+                fname = fname.Mid(0,fname.GetLength()-4);
+    if (fname.Find(&quot;{hw}&quot;) == (fname.GetLength() - 4))
+                fname = fname.Mid(0,fname.GetLength()-4);
+                
+    OpalMediaFormat oformat(fname, false);
+    int pload = oformat.GetPayloadType();
+    const char *format = 0;
+    const char** f = h323_formats;
+    for (; *f; f += 2) {
+                if (fname.Find(*f) == 0) {
+                        format = f[1];
+                        break;
+                }
+    }
+    
+        PTRACE(1, &quot;mod_h323\tcapability '&quot;&lt;&lt; fname &lt;&lt; &quot;' format '&quot;&lt;&lt;format&lt;&lt;&quot;' payload &quot;&lt;&lt;pload);
+    if (format) {
+                if (capabName)
+                        *capabName = fname;
+                if (dataFormat)
+                        *dataFormat = format;
+                if (payload)
+                        *payload = pload;
+                return true;
+    }
+    return false;
+}
+
+H323Connection::AnswerCallResponse FSH323Connection::OnAnswerCall(const PString &amp;caller,
+    const H323SignalPDU &amp;setupPDU, H323SignalPDU &amp;connectPDU){
+        PTRACE(4, &quot;mod_h323\t======&gt;FSH323Connection::OnAnswerCall caller = &quot;&lt;&lt; caller&lt;&lt;&quot; [&quot; &lt;&lt; *this&lt;&lt;&quot;]&quot;);
+        
+        if (m_fsSession == NULL) {
+        PTRACE(1, &quot;mod_h323\tSession request failed.&quot;);
+        return H323Connection::AnswerCallDenied;
+    }
+
+    switch_core_session_add_stream(m_fsSession, NULL);
+
+    switch_channel_t *channel = switch_core_session_get_channel(m_fsSession);
+    if (channel == NULL) {
+        PTRACE(1, &quot;mod_h323\tSession does not have a channel&quot;);
+        return H323Connection::AnswerCallDenied;
+    }
+
+        const Q931&amp; q931 = setupPDU.GetQ931();
+        const H225_Setup_UUIE&amp; setup = setupPDU.m_h323_uu_pdu.m_h323_message_body;
+    const H225_ArrayOf_AliasAddress&amp; address = setup.m_destinationAddress;
+    for (int i = 0; i&lt;address.GetSize(); i++)
+                PTRACE(2, &quot;mod_h323\t address index = &quot;&lt;&lt;i&lt;&lt;&quot; value = &quot;&lt;&lt;(const char *)H323GetAliasAddressString(address[i]));
+        PString called;
+    if (address.GetSize() &gt; 0)
+                called = (const char *)H323GetAliasAddressString(address[0]);
+    if (!called.IsEmpty())
+                PTRACE(2, &quot;mod_h323\t Called number or alias = &quot;&lt;&lt;called);
+    else {
+                PString callnam;
+                if (q931.GetCalledPartyNumber(callnam)) {
+                        called=(const char *)callnam;                        
+                        PTRACE(2, &quot;mod_h323\t Called-Party-Number = &quot;&lt;&lt;called);
+                }
+    }
+       
+        
+    switch_caller_profile_t *caller_profile = switch_caller_profile_new(switch_core_session_get_pool(m_fsSession),
+                                                                        NULL,
+                                                                        /** username */
+                                                                        mod_h323_globals.dialplan,
+                                                                        /** dial plan */
+                                                                        GetRemotePartyName(),
+                                                                        /** caller_id_name */
+                                                                        GetRemotePartyNumber(),
+                                                                        /** caller_id_number */
+                                                                        NULL,
+                                                                        /** network addr */
+                                                                        NULL,
+                                                                        /** ANI */
+                                                                        NULL,
+                                                                        /** ANI II */
+                                                                        NULL,
+                                                                        /** RDNIS */
+                                                                        modulename,
+                                                                        /** source */
+                                                                        mod_h323_globals.context,
+                                                                        /** set context  */
+                                                                        called
+                                                                        /** destination_number */
+                                                                        );
+    if (caller_profile == NULL) {
+        PTRACE(1, &quot;mod_h323\tCould not create caller profile&quot;);
+        return H323Connection::AnswerCallDenied;
+    }
+
+    PTRACE(4, &quot;mod_h323\tCreated switch caller profile:\n&quot;
+           &quot;  username       = &quot; &lt;&lt; caller_profile-&gt;username &lt;&lt; &quot;\n&quot;
+           &quot;  dialplan       = &quot; &lt;&lt; caller_profile-&gt;dialplan &lt;&lt; &quot;\n&quot;
+           &quot;  caller_id_name     = &quot; &lt;&lt; caller_profile-&gt;caller_id_name &lt;&lt; &quot;\n&quot;
+           &quot;  caller_id_number   = &quot; &lt;&lt; caller_profile-&gt;caller_id_number &lt;&lt; &quot;\n&quot;
+           &quot;  network_addr   = &quot; &lt;&lt; caller_profile-&gt;network_addr &lt;&lt; &quot;\n&quot;
+           &quot;  source         = &quot; &lt;&lt; caller_profile-&gt;source &lt;&lt; &quot;\n&quot;
+           &quot;  context        = &quot; &lt;&lt; caller_profile-&gt;context &lt;&lt; &quot;\n&quot; 
+                   &quot;  destination_number= &quot; &lt;&lt; caller_profile-&gt;destination_number);
+    switch_channel_set_caller_profile(channel, caller_profile);
+
+    char name[256] = &quot;h323/&quot;;
+    switch_copy_string(name + 5, caller_profile-&gt;destination_number, sizeof(name)-5);
+    switch_channel_set_name(channel, name);
+    switch_channel_set_state(channel, CS_INIT);
+
+    if (switch_core_session_thread_launch(m_fsSession) != SWITCH_STATUS_SUCCESS) {
+        PTRACE(1, &quot;mod_h323\tCould not launch session thread&quot;);
+        return H323Connection::AnswerCallDenied;
+    }
+
+        return H323Connection::AnswerCallDeferred;
+}
+
+H323Channel* FSH323Connection::CreateRealTimeLogicalChannel(const H323Capability&amp; capability,H323Channel::Directions dir,unsigned sessionID,const H245_H2250LogicalChannelParameters* param, RTP_QOS * rtpqos){
+        PTRACE(4, &quot;mod_h323\t======&gt;FSH323Connection::CreateRealTimeLogicalChannel &quot; &lt;&lt; *this);
+        
+        H323TransportAddress m_h323transportadd = GetSignallingChannel()-&gt;GetLocalAddress();
+        m_h323transportadd.GetIpAddress(m_RTPlocalIP);
+//        return H323Connection::CreateRealTimeLogicalChannel(capability,dir,sessionID,param);
+        return new FSH323_ExternalRTPChannel(*this, capability, dir, sessionID,m_RTPlocalIP,m_RTPlocalPort);
+}
+
+PBoolean FSH323Connection::OnStartLogicalChannel(H323Channel &amp; channel){
+    PTRACE(4, &quot;mod_h323\t======&gt;FSH323Connection::OnStartLogicalChannel chennel = &quot;&lt;&lt;&amp;channel&lt;&lt;&quot;, &quot;&lt;&lt;*this);
+    
+//    return  H323Connection::OnStartLogicalChannel(channel);
+        return true;
+}
+
+PBoolean FSH323Connection::OnCreateLogicalChannel(const H323Capability&amp; capability, H323Channel::Directions dir, unsigned&amp; errorCode){
+    PTRACE(4, &quot;mod_h323\t======&gt;FSH323Connection::OnCreateLogicalChannel ('&quot;&lt;&lt; (const char *)capability.GetFormatName()&lt;&lt;&quot;',&quot;&lt;&lt;dir&lt;&lt;&quot;) &quot;&lt;&lt;*this);
+    
+        return H323Connection::OnCreateLogicalChannel(capability,dir,errorCode);
+}
+
+void FSH323Connection::OnReceivedReleaseComplete(const H323SignalPDU &amp; pdu){
+        PTRACE(4, &quot;mod_h323\t======&gt;FSH323Connection::OnReceivedReleaseComplete cause = &quot;&lt;&lt;pdu.GetQ931().GetCause()&lt;&lt;&quot; value = &quot;&lt;&lt;(switch_call_cause_t)pdu.GetQ931().GetCause());
+        h323_private_t *tech_pvt = (h323_private_t *) switch_core_session_get_private(m_fsSession);
+//        tech_pvt-&gt;me = NULL;
+        
+        switch_channel_hangup(switch_core_session_get_channel(m_fsSession),(switch_call_cause_t)pdu.GetQ931().GetCause()); 
+//        on_hangup(GetCallReference(), (const char *)GetCallToken(), pdu.GetQ931().GetCause());
+        return H323Connection::OnReceivedReleaseComplete(pdu);
+}
+
+bool FSH323Connection::OnReceivedProgress(const H323SignalPDU &amp;pdu)
+{
+        PTRACE(4, &quot;mod_h323\t======&gt;FSH323Connection::OnReceivedProgress&quot;);
+        m_txAudioOpened.Wait();
+        switch_channel_mark_pre_answered(m_fsChannel);
+        return true;
+}
+
+
+bool FSH323Connection::OnSendReleaseComplete(H323SignalPDU &amp; pdu)
+{
+        PTRACE(4, &quot;mod_h323\t======&gt;FSH323Connection::OnSendReleaseComplete cause = &quot;&lt;&lt;pdu.GetQ931().GetCause()&lt;&lt;&quot; value = &quot;&lt;&lt;(switch_call_cause_t)pdu.GetQ931().GetCause());
+        
+        switch_channel_hangup(m_fsChannel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);                        
+        return H323Connection::OnSendReleaseComplete(pdu);
+}
+
+PBoolean FSH323Connection::OpenLogicalChannel(const H323Capability&amp; capability, unsigned sessionID, H323Channel::Directions dir){
+        PTRACE(4, &quot;mod_h323\t======&gt;FSH323Connection::OpenLogicalChannel ('&quot;&lt;&lt; (const char *)capability.GetFormatName()&lt;&lt;&quot;', &quot;&lt;&lt; sessionID&lt;&lt;&quot;, &quot;&lt;&lt;dir &lt;&lt;&quot;) &quot;&lt;&lt;*this);
+    
+    return H323Connection::OpenLogicalChannel(capability,sessionID,dir);
+}
+
+
+bool FSH323Connection::OnReceivedCapabilitySet(const H323Capabilities &amp; remoteCaps,
+                                                        const H245_MultiplexCapability * muxCap,
+                                                        H245_TerminalCapabilitySetReject &amp; reject){
+        
+        PTRACE(4, &quot;mod_h323\t======&gt;FSH323Connection::OnReceivedCapabilitySet [&quot;&lt;&lt;*this&lt;&lt;&quot;]&quot;);
+        if (!H323Connection::OnReceivedCapabilitySet(remoteCaps, muxCap, reject)) {
+                return false;
+        }
+        PTRACE(4, &quot;mod_h323\t======&gt;END H323Connection::OnReceivedCapabilitySet [&quot;&lt;&lt;*this&lt;&lt;&quot;]&quot;);
+        
+        for (int i = 0; i &lt; remoteCapabilities.GetSize(); ++i) {
+                PTRACE(4, &quot;mod_h323\t----&gt; Capabilities = &quot;&lt;&lt;remoteCapabilities[i]);
+        }
+        
+        H323Capability * cap = remoteCapabilities.FindCapability(H323Capability::e_Audio);
+        if (cap == NULL) {
+                PTRACE(4, &quot;mod_h323\t----&gt; Capabilities is NULL &quot;);
+                return false;
+        }
+        PTRACE(4, &quot;mod_h323\t----&gt; Capabilities not NULL &quot;);
+        return true;                                                
+}
+
+
+bool FSH323Connection::OnAlerting(const H323SignalPDU &amp;alertingPDU, const PString &amp;user){
+
+        PTRACE(4, &quot;mod_h323\t======&gt;PFSH323Connection::OnAlerting user = &quot;&lt;&lt;(const char *)user&lt;&lt;&quot; [&quot;&lt;&lt;*this&lt;&lt;&quot;]&quot;);
+        
+        return (switch_channel_mark_ring_ready(m_fsChannel) == SWITCH_STATUS_SUCCESS);
+         ;
+}
+
+void FSH323Connection::OnEstablished(){
+
+        PTRACE(4, &quot;mod_h323\t======&gt;PFSH323Connection::OnEstablished [&quot;&lt;&lt;*this&lt;&lt;&quot;]&quot;);
+        
+        switch_channel_mark_answered(m_fsChannel);
+}
+
+
+
+void FSH323Connection::setRemoteAddress(const char* remoteIP, WORD remotePort){
+        PTRACE(4, &quot;mod_h323\t======&gt;PFSH323Connection::setRemoteAddress remoteIP =&quot;&lt;&lt;remoteIP&lt;&lt;&quot;, remotePort = &quot;&lt;&lt;remotePort&lt;&lt;&quot; &quot;&lt;&lt;*this);
+    if (!m_remotePort) {
+        PTRACE(4, &quot;mod_h323\tGot remote RTP address &quot;&lt;&lt;remoteIP&lt;&lt;&quot;:&quot;&lt;&lt;remotePort&lt;&lt;&quot; &quot;&lt;&lt;*this);
+        m_remotePort = remotePort;
+        m_remoteAddr = remoteIP;
+    }
+}
+
+switch_status_t FSH323Connection::on_execute(){
+        PTRACE(4, &quot;mod_h323\t======&gt;FSH323Connection::on_execute &quot; &lt;&lt; *this);
+    
+    return SWITCH_STATUS_SUCCESS;
+}
+
+switch_status_t FSH323Connection::on_routing(){
+        PTRACE(4, &quot;mod_h323\t======&gt;FSH323Connection::on_routing &quot; &lt;&lt; *this);
+   
+    return SWITCH_STATUS_SUCCESS;
+}
+
+switch_status_t FSH323Connection::kill_channel(int sig){
+        PTRACE(4, &quot;mod_h323\t======&gt;FSH323Connection::kill_channel &quot; &lt;&lt; *this);
+    PTRACE(3, &quot;mod_h323\tKill &quot; &lt;&lt; sig &lt;&lt; &quot; on connection &quot; &lt;&lt; *this);
+        h323_private_t *tech_pvt = (h323_private_t *) switch_core_session_get_private(m_fsSession);
+        
+        if (!tech_pvt) {
+                return SWITCH_STATUS_FALSE;
+        }
+        
+    switch (sig) {
+    case SWITCH_SIG_BREAK:
+                if (switch_rtp_ready(tech_pvt-&gt;rtp_session)) {
+                        switch_rtp_break(tech_pvt-&gt;rtp_session);
+                }
+        break;
+    case SWITCH_SIG_KILL:
+    default:
+                m_rxAudioOpened.Signal();
+        m_txAudioOpened.Signal();
+                if (switch_rtp_ready(tech_pvt-&gt;rtp_session)) {
+                        switch_rtp_kill_socket(tech_pvt-&gt;rtp_session);
+                }
+        break;
+    }
+
+    return SWITCH_STATUS_SUCCESS;
+}
+
+switch_status_t FSH323Connection::send_dtmf(const switch_dtmf_t *dtmf){
+        PTRACE(4, &quot;mod_h323\t======&gt;FSH323Connection::send_dtmf &quot; &lt;&lt; *this);
+    SendUserInputTone(dtmf-&gt;digit, dtmf-&gt;duration);
+    return SWITCH_STATUS_SUCCESS;
+}
+
+void FSH323Connection::SendUserInputTone(char tone, unsigned duration, unsigned logicalChannel, unsigned rtpTimestamp)
+{
+        PTRACE(4, &quot;mod_h323\t======&gt;FSH323Connection::SendUserInputTone [&quot; &lt;&lt; *this&lt;&lt;&quot;]&quot;);
+        H323Connection::SendUserInputTone(tone, duration);
+}
+
+void FSH323Connection::OnUserInputTone(char tone, unsigned duration, unsigned logicalChannel, unsigned rtpTimestamp)
+{
+        PTRACE(4, &quot;mod_h323\t======&gt;FSH323Connection::OnUserInputTone [&quot; &lt;&lt; *this&lt;&lt;&quot;]&quot;);
+        switch_dtmf_t dtmf = { tone, duration };
+    switch_channel_queue_dtmf(m_fsChannel, &amp;dtmf);
+        H323Connection::OnUserInputTone( tone,  duration, logicalChannel, rtpTimestamp);
+}
+
+void FSH323Connection::OnUserInputString(const PString &amp;value)
+{
+        PTRACE(4, &quot;mod_h323\t======&gt;FSH323Connection::OnUserInputString [&quot; &lt;&lt; *this&lt;&lt;&quot;]&quot;);
+        switch_dtmf_t dtmf = { value[0], 0 };
+    switch_channel_queue_dtmf(m_fsChannel, &amp;dtmf);
+        H323Connection::OnUserInputString(value);
+}
+
+
+switch_status_t FSH323Connection::receive_message(switch_core_session_message_t *msg){
+        PTRACE(4, &quot;mod_h323\t======&gt;FSH323Connection::receive_message MSG=&quot; &lt;&lt; msg-&gt;message_id);
+        
+        
+    switch_channel_t *channel = switch_core_session_get_channel(m_fsSession);
+
+
+
+    switch (msg-&gt;message_id) {
+    case SWITCH_MESSAGE_INDICATE_BRIDGE:
+    case SWITCH_MESSAGE_INDICATE_UNBRIDGE:
+    case SWITCH_MESSAGE_INDICATE_AUDIO_SYNC:
+        switch_channel_set_private_flag(channel, CF_NEED_FLUSH);
+        break;
+    default:
+        break;
+    }
+
+    switch (msg-&gt;message_id) {
+                case SWITCH_MESSAGE_INDICATE_RINGING:{
+//                         AnsweringCall(AnswerCallAlertWithMedia);
+                         AnsweringCall(AnswerCallPending);
+                        break;
+                }
+                case SWITCH_MESSAGE_INDICATE_DEFLECT:{
+        /*      PSafePtr&lt;OpalConnection&gt; other = GetOtherPartyConnection();
+                        if (other != NULL)
+                          other-&gt;TransferConnection(msg-&gt;string_arg);
+                        break;
+        */                
+                }
+                case SWITCH_MESSAGE_INDICATE_PROGRESS:{
+                        m_callOnPreAnswer = true;                
+                        AnsweringCall(AnswerCallPending);
+                        AnsweringCall(AnswerCallDeferredWithMedia);
+                        m_txAudioOpened.Wait();
+                        if (!switch_channel_test_flag(m_fsChannel, CF_EARLY_MEDIA)) {
+                                switch_channel_mark_pre_answered(m_fsChannel);
+                        }
+                        break;
+                }
+                case SWITCH_MESSAGE_INDICATE_ANSWER:{
+                        if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
+                                return SWITCH_STATUS_FALSE;
+                        }
+                        AnsweringCall(H323Connection::AnswerCallNow);
+                        PTRACE(4, &quot;mod_h323\tMedia started on connection &quot; &lt;&lt; *this);
+
+                        m_rxAudioOpened.Wait();
+            m_txAudioOpened.Wait();
+
+                        if (!switch_channel_test_flag(m_fsChannel, CF_EARLY_MEDIA)) {
+                                PTRACE(4, &quot;mod_h323\t--------------------&gt;switch_channel_mark_answered(m_fsChannel) &quot; &lt;&lt; *this);
+                                switch_channel_mark_answered(m_fsChannel);
+                        }
+                        break;
+                }
+                default:{
+                        PTRACE(3, &quot;mod_h323\tReceived message &quot; &lt;&lt; msg-&gt;message_id &lt;&lt; &quot; on connection &quot; &lt;&lt; *this);
+                }        
+    }
+    return SWITCH_STATUS_SUCCESS;
+}
+
+switch_status_t FSH323Connection::receive_event(switch_event_t *event){
+        PTRACE(4, &quot;mod_h323\t======&gt;FSH323Connection::receive_event &quot; &lt;&lt; *this);
+    PTRACE(3, &quot;mod_h323\tReceived event &quot; &lt;&lt; event-&gt;event_id &lt;&lt; &quot; on connection &quot; &lt;&lt; *this);
+    return SWITCH_STATUS_SUCCESS;
+}
+
+switch_status_t FSH323Connection::state_change(){
+        PTRACE(4, &quot;mod_h323\t======&gt;FSH323Connection::state_change &quot; &lt;&lt; *this);
+    PTRACE(3, &quot;mod_h323\tState changed on connection &quot; &lt;&lt; *this);
+    return SWITCH_STATUS_SUCCESS;
+}
+
+switch_status_t FSH323Connection::on_init(){
+        PTRACE(4, &quot;mod_h323\t======&gt;FSH323Connection::on_init &quot; &lt;&lt; *this);
+    switch_channel_t *channel = switch_core_session_get_channel(m_fsSession);
+    if (channel == NULL) {
+        return SWITCH_STATUS_FALSE;
+    }
+
+    PTRACE(3, &quot;mod_h323\tStarted routing for connection &quot; &lt;&lt; *this);
+    switch_channel_set_state(channel, CS_ROUTING);
+    return SWITCH_STATUS_SUCCESS;
+}
+
+switch_status_t FSH323Connection::on_exchange_media(){
+        PTRACE(4, &quot;mod_h323\t======&gt;FSH323Connection::on_exchange_media &quot; &lt;&lt; *this);
+    
+    return SWITCH_STATUS_SUCCESS;
+}
+
+switch_status_t FSH323Connection::on_soft_execute(){
+    PTRACE(4, &quot;mod_h323\t======&gt;FSH323Connection::on_soft_execute &quot; &lt;&lt; *this);
+        
+    return SWITCH_STATUS_SUCCESS;
+}
+
+switch_status_t FSH323Connection::read_audio_frame(switch_frame_t **frame, switch_io_flag_t flags, int stream_id){
+        PTRACE(4, &quot;mod_h323\t======&gt;FSH323Connection::read_audio_frame &quot; &lt;&lt; *this);
+        h323_private_t *tech_pvt = (h323_private_t *) switch_core_session_get_private(m_fsSession);
+        tech_pvt-&gt;read_frame.flags = 0;
+/*        
+        if (switch_channel_test_private_flag(m_fsChannel, CF_NEED_FLUSH)) {
+        switch_channel_clear_private_flag(m_fsChannel, CF_NEED_FLUSH);
+    } else {            
+        switch_core_timer_next(&amp;tech_pvt-&gt;read_timer);
+    }
+*/
+        switch_set_flag_locked(tech_pvt, TFLAG_READING);
+        
+    if (!switch_channel_ready(m_fsChannel)) {
+                PTRACE(4, &quot;mod_h323\t---------&gt; RETURN&quot;);
+                switch_clear_flag_locked(tech_pvt, TFLAG_READING);
+        return SWITCH_STATUS_FALSE;
+    }
+
+    if (!switch_core_codec_ready(&amp;tech_pvt-&gt;read_codec )) {
+                PTRACE(4, &quot;mod_h323\t---------&gt; RETURN&quot;);
+                switch_clear_flag_locked(tech_pvt, TFLAG_READING);
+        return SWITCH_STATUS_FALSE;
+    }
+
+    //switch_core_timer_step(&amp;m_switchTimer);
+
+        
+        switch_status_t status = switch_rtp_zerocopy_read_frame(tech_pvt-&gt;rtp_session, &amp;tech_pvt-&gt;read_frame, flags);
+        if (status != SWITCH_STATUS_SUCCESS &amp;&amp; status != SWITCH_STATUS_BREAK) {
+                        PTRACE(4, &quot;mod_h323\t---------&gt; RETURN&quot;);
+                        switch_clear_flag_locked(tech_pvt, TFLAG_READING);
+                        return SWITCH_STATUS_FALSE;
+        }
+        PTRACE(4, &quot;mod_h323\t---------&gt;\n source = &quot;&lt;&lt;tech_pvt-&gt;read_frame.source&lt;&lt; &quot;\n packetlen = &quot;&lt;&lt;tech_pvt-&gt;read_frame.packetlen&lt;&lt;&quot;\n datalen = &quot;&lt;&lt;tech_pvt-&gt;read_frame.datalen&lt;&lt;&quot;\n samples = &quot;&lt;&lt;tech_pvt-&gt;read_frame.samples&lt;&lt;&quot;\n rate = &quot;&lt;&lt;tech_pvt-&gt;read_frame.rate&lt;&lt;&quot;\n payload = &quot;&lt;&lt;(int)tech_pvt-&gt;read_frame.payload&lt;&lt;&quot;\n timestamp = &quot;&lt;&lt;tech_pvt-&gt;read_frame.timestamp&lt;&lt;&quot;\n seq = &quot;&lt;&lt;tech_pvt-&gt;read_frame.seq&lt;&lt;&quot;\n ssrc = &quot;&lt;&lt;tech_pvt-&gt;read_frame.ssrc);
+    if (tech_pvt-&gt;read_frame.flags &amp; SFF_CNG) {
+        tech_pvt-&gt;read_frame.buflen = sizeof(m_buf);
+        tech_pvt-&gt;read_frame.data = m_buf;
+        tech_pvt-&gt;read_frame.packet = NULL;
+        tech_pvt-&gt;read_frame.packetlen = 0;
+        tech_pvt-&gt;read_frame.timestamp = 0;
+        tech_pvt-&gt;read_frame.m = SWITCH_FALSE;
+        tech_pvt-&gt;read_frame.seq = 0;
+        tech_pvt-&gt;read_frame.ssrc = 0;
+        tech_pvt-&gt;read_frame.codec = &amp;tech_pvt-&gt;read_codec ;
+    } else {
+        tech_pvt-&gt;read_frame.codec = &amp;tech_pvt-&gt;read_codec ;
+    }
+        switch_clear_flag_locked(tech_pvt, TFLAG_READING);
+    *frame = &amp;tech_pvt-&gt;read_frame;
+
+    return SWITCH_STATUS_SUCCESS;
+        
+
+}
+
+switch_status_t FSH323Connection::write_audio_frame(switch_frame_t *frame, switch_io_flag_t flags, int stream_id){
+        PTRACE(4, &quot;mod_h323\t======&gt;FSH323Connection::write_audio_frame &quot; &lt;&lt; *this);
+        
+        switch_status_t status = SWITCH_STATUS_SUCCESS;
+        h323_private_t *tech_pvt = (h323_private_t *) switch_core_session_get_private(m_fsSession);
+        switch_assert(tech_pvt != NULL);
+        
+        if (!switch_channel_ready(m_fsChannel)) {
+                PTRACE(4, &quot;mod_h323\t---------&gt; RETURN&quot;);
+        return SWITCH_STATUS_FALSE;
+    }        
+        
+        while (!(tech_pvt-&gt;read_codec.implementation &amp;&amp; switch_rtp_ready(tech_pvt-&gt;rtp_session))) {
+                if (switch_channel_ready(m_fsChannel)) {
+                        switch_yield(10000);
+                } else {
+                        PTRACE(4, &quot;mod_h323\t---------&gt; RETURN&quot;);
+                        return SWITCH_STATUS_GENERR;
+                }
+        }
+        
+        if (!switch_core_codec_ready(&amp;tech_pvt-&gt;read_codec) || !tech_pvt-&gt;read_codec.implementation) {
+                PTRACE(4, &quot;mod_h323\t---------&gt; RETURN&quot;);
+                return SWITCH_STATUS_GENERR;
+        }
+
+        if ((frame-&gt;flags &amp; SFF_CNG)) {
+                PTRACE(4, &quot;mod_h323\t---------&gt; RETURN&quot;);
+        return SWITCH_STATUS_SUCCESS;
+    }
+        switch_set_flag_locked(tech_pvt, TFLAG_WRITING);
+        
+        if (switch_rtp_write_frame(tech_pvt-&gt;rtp_session, frame)&lt; 0) {
+                status = SWITCH_STATUS_GENERR;
+        }
+        
+        switch_clear_flag_locked(tech_pvt, TFLAG_WRITING);
+        PTRACE(4, &quot;mod_h323\t---------&gt; RETURN&quot;);        
+        return status;
+}
+
+switch_status_t FSH323Connection::read_video_frame(switch_frame_t **frame, switch_io_flag_t flag, int stream_id){
+        PTRACE(4, &quot;mod_h323\t======&gt;FSH323Connection::read_video_frame &quot; &lt;&lt; *this);

+}
+
+switch_status_t FSH323Connection::write_video_frame(switch_frame_t *frame, switch_io_flag_t flag, int stream_id){
+        PTRACE(4, &quot;mod_h323\t======&gt;FSH323Connection::write_video_frame &quot; &lt;&lt; *this);
+//    return write_frame(OpalMediaType::Video(), frame, flag);
+}
+
+///////////////////////////////////////////////////////////////////////
+
+FSH323_ExternalRTPChannel::FSH323_ExternalRTPChannel( 
+    FSH323Connection&amp; connection,
+    const H323Capability&amp; capability,
+    Directions direction, 
+    unsigned sessionID,
+        const PIPSocket::Address&amp; ip, 
+        WORD dataPort)
+    : H323_ExternalRTPChannel(connection, capability, direction, sessionID,ip,dataPort)
+        , m_conn(&amp;connection)
+        , m_fsSession(connection.GetSession())
+        , m_capability(&amp;capability)
+        , m_RTPlocalPort(dataPort){ 
+        h323_private_t *tech_pvt = (h323_private_t *) switch_core_session_get_private(m_fsSession);
+        
+    m_RTPlocalIP = (const char *)ip.AsString();
+        SetExternalAddress(H323TransportAddress(ip, dataPort), H323TransportAddress(ip, dataPort+1));
+    PTRACE(4, &quot;mod_h323\t======&gt;FSH323_ExternalRTPChannel::FSH323_ExternalRTPChannel &quot;&lt;&lt; GetDirection()&lt;&lt; &quot; addr=&quot;&lt;&lt; m_RTPlocalIP &lt;&lt;&quot;:&quot;&lt;&lt; m_RTPlocalPort&lt;&lt;&quot; [&quot;&lt;&lt;*this&lt;&lt;&quot;]&quot;);        
+        
+        memset(&amp;m_readFrame, 0, sizeof(m_readFrame));
+    m_readFrame.codec = m_switchCodec;
+    m_readFrame.flags = SFF_RAW_RTP;
+        
+        m_fsChannel = switch_core_session_get_channel(m_fsSession);
+    //SetExternalAddress(H323TransportAddress(localIpAddress, m_RTPlocalPort), H323TransportAddress(localIpAddress, m_RTPlocalPort+1));
+        PTRACE(4, &quot;mod_h323\t-------&gt;capability.GetPayloadType() return = &quot;&lt;&lt;capability.GetPayloadType());
+        PTRACE(4, &quot;mod_h323\t-------&gt;capability.GetFormatName() return = &quot;&lt;&lt;capability.GetFormatName());
+        
+        PString fname((const char *)capability.GetFormatName());
+  
+    if (fname.Find(&quot;{sw}&quot;) == (fname.GetLength() - 4))
+                fname = fname.Mid(0,fname.GetLength()-4);
+    if (fname.Find(&quot;{hw}&quot;) == (fname.GetLength() - 4))
+                fname = fname.Mid(0,fname.GetLength()-4);
+        
+        OpalMediaFormat format(fname, FALSE);
+        m_format = &amp;format;
+        payloadCode = format.GetPayloadType();
+        PTRACE(4, &quot;mod_h323\t-------&gt;payloadCode = &quot;&lt;&lt;(int)payloadCode);
+}
+
+
+FSH323_ExternalRTPChannel::~FSH323_ExternalRTPChannel(){
+    PTRACE(4, &quot;mod_h323\t======&gt;FSH323_ExternalRTPChannel::~FSH323_ExternalRTPChannel  &quot;&lt;&lt; GetDirection()&lt;&lt;&quot; &quot;&lt;&lt;*this);
+        h323_private_t *tech_pvt = (h323_private_t *) switch_core_session_get_private(m_fsSession);
+        if (IsRunning()){
+                PTRACE(4, &quot;mod_h323\t-------------&gt;Running&quot;);
+                if (switch_rtp_ready(tech_pvt-&gt;rtp_session)) {
+                        switch_rtp_kill_socket(tech_pvt-&gt;rtp_session);
+                }
+        }
+}
+
+PBoolean FSH323_ExternalRTPChannel::Start(){
+    PTRACE(4, &quot;mod_h323\t======&gt;FSH323_ExternalRTPChannel::Start() &quot;&lt;&lt;*this);
+        const char *err = NULL;
+        switch_rtp_flag_t flags;
+        char * timer_name = NULL;
+        const char *var;
+    h323_private_t *tech_pvt = (h323_private_t *) switch_core_session_get_private(m_fsSession);
+        if (!(m_conn &amp;&amp; H323_ExternalRTPChannel::Start()))
+                return FALSE;
+        
+        
+        bool isAudio;
+    if (m_capability-&gt;GetMainType() == H323Capability::e_Audio) {
+        isAudio = true;
+                PTRACE(4, &quot;mod_h323\t-------------------------&gt;H323Capability::e_Audio&quot;);
+    } else if (m_capability-&gt;GetMainType() == H323Capability::e_Video) {
+        isAudio = false;
+                PTRACE(4, &quot;mod_h323\t-------------------------&gt;H323Capability::e_Video&quot;);
+    }
+        
+        H323Codec *codec = GetCodec();
+        
+        
+        PTRACE(4, &quot;mod_h323\t-------------------&gt;GetFrameSize() return = &quot;&lt;&lt;m_format-&gt;GetFrameSize());
+        PTRACE(4, &quot;mod_h323\t-------------------&gt;GetFrameTime() return = &quot;&lt;&lt;m_format-&gt;GetFrameTime());
+        PTRACE(4, &quot;mod_h323\t-------------------&gt;payloadCode = &quot;&lt;&lt;(int)payloadCode);
+        PTRACE(4, &quot;mod_h323\t-------------------&gt;m_capability-&gt;GetTxFramesInPacket() return =  &quot;&lt;&lt;m_capability-&gt;GetTxFramesInPacket());
+        PTRACE(4, &quot;mod_h323\t-------------------&gt;m_capability-&gt;GetFormatName() return =  &quot;&lt;&lt;m_capability-&gt;GetFormatName());
+        
+        PTRACE(4, &quot;mod_h323\t-------------------&gt;GetH245CodecName() return =  &quot;&lt;&lt;GetH245CodecName(m_capability-&gt;GetSubType()));
+        
+        
+        
+        
+        
+        if (GetDirection() == IsReceiver){
+                m_switchCodec = isAudio ? &amp;tech_pvt-&gt;read_codec : &amp;tech_pvt-&gt;vid_read_codec;
+        m_switchTimer = isAudio ? &amp;tech_pvt-&gt;read_timer : &amp;tech_pvt-&gt;vid_read_timer;
+        }else{
+                m_switchCodec = isAudio ? &amp;tech_pvt-&gt;write_codec : &amp;tech_pvt-&gt;vid_write_codec;
+        }
+        
+        if (m_conn-&gt;m_callOnPreAnswer &amp;&amp; !(GetDirection() == IsReceiver)){
+                m_switchCodec = isAudio ? &amp;tech_pvt-&gt;read_codec : &amp;tech_pvt-&gt;vid_read_codec;
+        m_switchTimer = isAudio ? &amp;tech_pvt-&gt;read_timer : &amp;tech_pvt-&gt;vid_read_timer;
+        }
+        
+        
+        
+        if (switch_core_codec_init(m_switchCodec, GetH245CodecName(m_capability-&gt;GetSubType()), NULL, // FMTP
+                               8000, m_capability-&gt;GetTxFramesInPacket(), 1,  // Channels
+                               SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,   // Settings
+                               switch_core_session_get_pool(m_fsSession)) != SWITCH_STATUS_SUCCESS) {
+        
+        if (switch_core_codec_init(m_switchCodec, GetH245CodecName(m_capability-&gt;GetSubType()), NULL, // FMTP
+                                   8000, 0, 1,  // Channels
+                                   SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,   // Settings
+                                   switch_core_session_get_pool(m_fsSession)) != SWITCH_STATUS_SUCCESS) {
+            PTRACE(1, &quot;mod_h323\t&quot; &lt;&lt; switch_channel_get_name(m_fsChannel)&lt;&lt; &quot; Cannot initialise &quot; &lt;&lt; ((GetDirection() == IsReceiver)? &quot; read&quot; : &quot; write&quot;) &lt;&lt; ' '
+                   &lt;&lt; m_capability-&gt;GetMainType() &lt;&lt; &quot; codec &quot; &lt;&lt; m_capability &lt;&lt; &quot; for connection &quot; &lt;&lt; *this);
+            switch_channel_hangup(m_fsChannel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
+            return false;
+        }
+        PTRACE(2, &quot;mod_h323\t&quot; &lt;&lt; switch_channel_get_name(m_fsChannel)&lt;&lt; &quot; Unsupported ptime of &quot; &lt;&lt; m_capability-&gt;GetTxFramesInPacket() &lt;&lt; &quot; on &quot; &lt;&lt; ((GetDirection() == IsReceiver)? &quot; read&quot; : &quot; write&quot;) &lt;&lt; ' '
+               &lt;&lt; m_capability-&gt;GetMainType() &lt;&lt; &quot; codec &quot; &lt;&lt; m_capability &lt;&lt; &quot; for connection &quot; &lt;&lt; *this);
+    }
+
+    PTRACE(1, &quot;mod_h323\t&quot; &lt;&lt; switch_channel_get_name(m_fsChannel)&lt;&lt; &quot; initialise &quot; &lt;&lt; 
+           switch_channel_get_name(m_fsChannel) &lt;&lt; ((GetDirection() == IsReceiver)? &quot; read&quot; : &quot; write&quot;) &lt;&lt; ' '
+           &lt;&lt; m_capability-&gt;GetMainType() &lt;&lt; &quot; codec &quot; &lt;&lt; m_capability &lt;&lt; &quot; for connection &quot; &lt;&lt; *this);
+        
+         if (GetDirection() == IsReceiver) {
+        m_readFrame.rate = tech_pvt-&gt;read_codec.implementation-&gt;actual_samples_per_second;
+
+        if (isAudio) {
+            switch_core_session_set_read_codec(m_fsSession, m_switchCodec);
+            if (switch_core_timer_init(m_switchTimer,
+                                       &quot;soft&quot;,
+                                       m_switchCodec-&gt;implementation-&gt;microseconds_per_packet / 1000,
+                                       m_switchCodec-&gt;implementation-&gt;samples_per_packet,
+                                       switch_core_session_get_pool(m_fsSession)) != SWITCH_STATUS_SUCCESS) {
+                switch_core_codec_destroy(m_switchCodec);
+                m_switchCodec = NULL;
+                return false;
+            }
+        } else {
+            switch_core_session_set_video_read_codec(m_fsSession, m_switchCodec);
+            switch_channel_set_flag(m_fsChannel, CF_VIDEO);
+        }
+    } else {
+        if (isAudio) {
+            switch_core_session_set_write_codec(m_fsSession, m_switchCodec);
+        } else {
+            switch_core_session_set_video_write_codec(m_fsSession, m_switchCodec);
+            switch_channel_set_flag(m_fsChannel, CF_VIDEO);
+        }
+    }
+
+        if (m_conn-&gt;m_callOnPreAnswer &amp;&amp; !(GetDirection() == IsReceiver)){
+                m_readFrame.rate = tech_pvt-&gt;read_codec.implementation-&gt;actual_samples_per_second;
+
+        if (isAudio) {
+            switch_core_session_set_read_codec(m_fsSession, m_switchCodec);
+            if (switch_core_timer_init(m_switchTimer,
+                                       &quot;soft&quot;,
+                                       m_switchCodec-&gt;implementation-&gt;microseconds_per_packet / 1000,
+                                       m_switchCodec-&gt;implementation-&gt;samples_per_packet,
+                                       switch_core_session_get_pool(m_fsSession)) != SWITCH_STATUS_SUCCESS) {
+                switch_core_codec_destroy(m_switchCodec);
+                m_switchCodec = NULL;
+                return false;
+            }
+                        switch_channel_set_variable(m_fsChannel,&quot;timer_name&quot;,&quot;soft&quot;);
+                }        
+        }
+        
+    PTRACE(3, &quot;mod_h323\tSet &quot; &lt;&lt; ((GetDirection() == IsReceiver)? &quot; read&quot; : &quot; write&quot;) &lt;&lt; ' '
+           &lt;&lt; m_capability-&gt;GetMainType() &lt;&lt; &quot; codec to &lt;&lt; &quot; &lt;&lt; m_capability &lt;&lt; &quot; for connection &quot; &lt;&lt; *this);
+
+        switch_mutex_lock(tech_pvt-&gt;h323_mutex);
+        
+        PIPSocket::Address remoteIpAddress;
+    GetRemoteAddress(remoteIpAddress,m_RTPremotePort);        
+        m_RTPremoteIP = (const char *)remoteIpAddress.AsString();
+        PTRACE(4, &quot;mod_h323\t-------------------&gt;tech_pvt-&gt;rtp_session = &quot;&lt;&lt;tech_pvt-&gt;rtp_session);
+        PTRACE(4, &quot;mod_h323\t-------------------&gt;samples_per_packet = &quot;&lt;&lt;m_switchCodec-&gt;implementation-&gt;samples_per_packet);
+        PTRACE(4, &quot;mod_h323\t-------------------&gt;actual_samples_per_second = &quot;&lt;&lt;m_switchCodec-&gt;implementation-&gt;actual_samples_per_second);
+        
+        if (!m_conn-&gt;m_startRTP) {                        
+                flags = (switch_rtp_flag_t) (SWITCH_RTP_FLAG_DATAWAIT|SWITCH_RTP_FLAG_AUTO_CNG|SWITCH_RTP_FLAG_RAW_WRITE|SWITCH_RTP_FLAG_AUTOADJ);                
+                if ((var = switch_channel_get_variable(m_fsChannel, &quot;timer_name&quot;))) {
+                        timer_name = (char *) var;
+                }
+                tech_pvt-&gt;rtp_session = switch_rtp_new((const char *)m_RTPlocalIP,
+                                                                                           m_RTPlocalPort,
+                                                                                           (const char *)m_RTPremoteIP,
+                                                                                           m_RTPremotePort,
+                                                                                           (switch_payload_t)payloadCode,
+                                                                                           m_switchCodec-&gt;implementation-&gt;samples_per_packet,        
+                                                                                           m_capability-&gt;GetTxFramesInPacket() * 1000,
+                                                                                           (switch_rtp_flag_t) flags, timer_name, &amp;err,
+                                                                                           switch_core_session_get_pool(m_fsSession));
+                PTRACE(4, &quot;mod_h323\t-------------------------&gt;tech_pvt-&gt;rtp_session = &quot;&lt;&lt;tech_pvt-&gt;rtp_session);
+                m_conn-&gt;m_startRTP = true;
+                if (switch_rtp_ready(tech_pvt-&gt;rtp_session)) {
+                        PTRACE(4, &quot;mod_h323\t+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++&quot;);                
+                        switch_channel_set_flag(m_fsChannel, CF_FS_RTP);
+                        
+                }else{
+                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;AUDIO RTP REPORTS ERROR: [%s]\n&quot;, switch_str_nil(err));
+                        switch_channel_hangup(m_fsChannel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);                        
+                        switch_mutex_unlock(tech_pvt-&gt;h323_mutex);
+                        return SWITCH_STATUS_FALSE;
+                }
+        }
+        if (GetDirection() == IsReceiver) m_conn-&gt;m_rxAudioOpened.Signal();
+        else m_conn-&gt;m_txAudioOpened.Signal();
+    PTRACE(4, &quot;mod_h323\t-------------&gt;External RTP address &quot;&lt;&lt;m_RTPremoteIP&lt;&lt;&quot;:&quot;&lt;&lt;m_RTPremotePort);
+        switch_mutex_unlock(tech_pvt-&gt;h323_mutex);
+        
+        return true;
+}
+
+
+PBoolean FSH323_ExternalRTPChannel::OnReceivedPDU(
+                                const H245_H2250LogicalChannelParameters&amp; param,
+                                unsigned&amp; errorCode){
+    PTRACE(4, &quot;mod_h323\t======&gt;FSH323_ExternalRTPChannel::OnReceivedPDU [&quot;&lt;&lt;*this&lt;&lt;&quot;]&quot;);
+    if (!H323_ExternalRTPChannel::OnReceivedPDU(param,errorCode))
+                return true;
+//    if (!m_conn || m_conn-&gt;hasRemoteAddress())
+//                return true;
+    PIPSocket::Address remoteIpAddress;
+    WORD remotePort;
+    GetRemoteAddress(remoteIpAddress,remotePort);
+    PTRACE(4, &quot;mod_h323\tRemote RTP address &quot;&lt;&lt;(const char *)remoteIpAddress.AsString()&lt;&lt;&quot;:&quot;&lt;&lt;remotePort);
+    m_conn-&gt;setRemoteAddress((const char *)remoteIpAddress.AsString(), remotePort);
+    return true;
+}
+
+PBoolean FSH323_ExternalRTPChannel::OnSendingPDU(H245_H2250LogicalChannelParameters&amp; param){
+   PTRACE(4, &quot;mod_h323\t======&gt;FSH323_ExternalRTPChannel::OnSendingPDU [&quot;&lt;&lt;*this&lt;&lt;&quot;]&quot;);
+    return H323_ExternalRTPChannel::OnSendingPDU(param);
+}
+
+PBoolean FSH323_ExternalRTPChannel::OnReceivedAckPDU(const H245_H2250LogicalChannelAckParameters&amp; param){
+    PTRACE(4, &quot;mod_h323\t======&gt;FSH323_ExternalRTPChannel::OnReceivedAckPDU [&quot;&lt;&lt;*this&lt;&lt;&quot;]&quot;);
+    return H323_ExternalRTPChannel::OnReceivedAckPDU(param);
+}
+
+void FSH323_ExternalRTPChannel::OnSendOpenAck(H245_H2250LogicalChannelAckParameters&amp; param){
+    PTRACE(4, &quot;mod_h323\t======&gt;FSH323_ExternalRTPChannel::OnSendOpenAck [&quot;&lt;&lt;*this&lt;&lt;&quot;]&quot;);
+    H323_ExternalRTPChannel::OnSendOpenAck(param);
+}
+
+
+FSH323Connection * FSH323EndPoint::FSMakeCall(const PString &amp; dest, void *userData){
+        PTRACE(4, &quot;mod_h323\t======&gt;FSH323EndPoint::FSMakeCall DST NUMBER = &quot;&lt;&lt;dest&lt;&lt;&quot; [&quot;&lt;&lt;*this&lt;&lt;&quot;]&quot;);
+        
+        FSH323Connection * connection;
+        PString token;
+        H323Transport *transport = NULL;
+        
+    if (listeners.GetSize() &gt; 0) {
+                        H323TransportAddress taddr = listeners[0].GetTransportAddress();
+                        PIPSocket::Address addr;
+                        WORD port;
+                        if (taddr.GetIpAndPort(addr, port)) {                                
+                                if (addr) {
+                                        PTRACE(4, &quot;mod_h323\t----&gt; Using &quot;&lt;&lt;addr&lt;&lt;&quot; for outbound call&quot;);
+                                        transport = new H323TransportTCP(*this, addr,false);
+                                        if (!transport)                                                
+                                                PTRACE(4, &quot;mod_h323\t----&gt; Unable to create transport for outgoing call&quot;);
+                                }
+                        } else
+                                PTRACE(4, &quot;mod_h323\t----&gt; Unable to get address and port&quot;);
+        }
+        
+/*        
+    if (!(connection = (FSH323Connection *)H323EndPoint::MakeCallLocked(dest, token, userData, transport))) {
+        return NULL;
+    }
+*/        
+
+    if (!(connection = (FSH323Connection *)H323EndPoint::MakeCall(dest, token, userData))) {
+        return NULL;
+    }
+
+/*
+        unsigned int *callReference;
+        
+        *callReference = connection-&gt;GetCallReference();
+        PTRACE(2, &quot;mod_h323\t======&gt;\n\tCreate outgoing cennel\n\tCall token = &quot;&lt;&lt;(const char *)token&lt;&lt;&quot;\n\tCall reference = &quot;&lt;&lt;*callReference);
+*/
+        return connection;
+}
+
+
+static switch_call_cause_t create_outgoing_channel(switch_core_session_t *session,
+                                                   switch_event_t *var_event,
+                                                   switch_caller_profile_t *outbound_profile,
+                                                   switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags){
+        PTRACE(4, &quot;mod_h323\t======&gt;create_outgoing_channel DST NUMBER = &quot;&lt;&lt;outbound_profile-&gt;destination_number);
+        
+        FSH323Connection * connection;
+    if (h323_process == NULL) {
+        return SWITCH_CAUSE_CRASH;
+    }
+        FSH323EndPoint &amp; ep = h323_process-&gt;GetH323EndPoint();
+        if (!(connection = ep.FSMakeCall(outbound_profile-&gt;destination_number,outbound_profile))){
+                return SWITCH_CAUSE_PROTOCOL_ERROR;
+        }
+/*    PSafePtr &lt; OpalCall &gt; call = manager.FindCallWithLock(token);
+
+    if (call == NULL) {
+        return SWITCH_CAUSE_PROTOCOL_ERROR;
+    }
+
+    PSafePtr &lt; FSConnection &gt; connection = call-&gt;GetConnectionAs &lt; FSConnection &gt; (0);
+
+    if (connection == NULL) {
+        return SWITCH_CAUSE_PROTOCOL_ERROR;
+    }
+*/
+    *new_session = connection-&gt;GetSession();
+        PTRACE(4, &quot;mod_h323\t---------&gt;GetSession() return = &quot;&lt;&lt;connection-&gt;GetSession());
+    return SWITCH_CAUSE_SUCCESS;
+}
+
+
+static switch_status_t on_destroy(switch_core_session_t *session){
+        PTRACE(4, &quot;mod_h323\t======&gt;on_destroy &quot;);
+
+    h323_private_t *tech_pvt = (h323_private_t *) switch_core_session_get_private(session);
+    
+    if (tech_pvt) {
+    if (tech_pvt-&gt;read_codec.implementation) {
+        switch_core_codec_destroy(&amp;tech_pvt-&gt;read_codec);
+    }
+
+    if (tech_pvt-&gt;write_codec.implementation) {
+        switch_core_codec_destroy(&amp;tech_pvt-&gt;write_codec);
+    }
+
+    if (tech_pvt-&gt;vid_read_codec.implementation) {
+        switch_core_codec_destroy(&amp;tech_pvt-&gt;vid_read_codec);
+    }
+
+    if (tech_pvt-&gt;vid_write_codec.implementation) {
+        switch_core_codec_destroy(&amp;tech_pvt-&gt;vid_write_codec);
+    }
+
+    if (tech_pvt-&gt;read_timer.timer_interface) {
+        switch_core_timer_destroy(&amp;tech_pvt-&gt;read_timer);
+    }
+
+    if (tech_pvt-&gt;vid_read_timer.timer_interface) {
+        switch_core_timer_destroy(&amp;tech_pvt-&gt;vid_read_timer);
+    }
+    }
+
+    return SWITCH_STATUS_SUCCESS;
+}
+
+
+static switch_status_t on_hangup(switch_core_session_t *session){
+        PTRACE(4, &quot;mod_h323\t======&gt;switch_status_t on_hangup &quot;);
+
+    switch_channel_t *channel = switch_core_session_get_channel(session);
+    h323_private_t *tech_pvt = (h323_private_t *) switch_core_session_get_private(session);
+    if (tech_pvt-&gt;me) {
+                PTRACE(4, &quot;mod_h323\t-----&gt;&quot;);
+        Q931::CauseValues cause = (Q931::CauseValues)switch_channel_get_cause_q850(channel);
+        tech_pvt-&gt;me-&gt;SetQ931Cause(cause);
+        tech_pvt-&gt;me-&gt;ClearCallSynchronous(NULL, H323TranslateToCallEndReason(cause, UINT_MAX));
+        tech_pvt-&gt;me = NULL;
+    }
+
+    return SWITCH_STATUS_SUCCESS;
+}
+
+
+
+
+
+
+
+
</ins></span></pre></div>
<a id="freeswitchtrunksrcmodendpointsmod_h323mod_h323h"></a>
<div class="addfile"><h4>Added: freeswitch/trunk/src/mod/endpoints/mod_h323/mod_h323.h (0 => 15223)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/src/mod/endpoints/mod_h323/mod_h323.h                                (rev 0)
+++ freeswitch/trunk/src/mod/endpoints/mod_h323/mod_h323.h        2009-10-24 01:48:45 UTC (rev 15223)
</span><span class="lines">@@ -0,0 +1,431 @@
</span><ins>+
+
+#if defined(__GNUC__) &amp;&amp; defined(HAVE_VISIBILITY)
+#pragma GCC visibility push(default)
+#endif
+
+#include &lt;ptlib.h&gt;
+#include &lt;h323.h&gt;
+#include &lt;h323neg.h&gt;
+#include &lt;h323pdu.h&gt;
+#include &lt;h323caps.h&gt;
+#include &lt;ptclib/delaychan.h&gt;
+
+#include &lt;list&gt;
+
+
+#if defined(__GNUC__) &amp;&amp; defined(HAVE_VISIBILITY)
+#pragma GCC visibility pop
+#endif
+
+#undef strcasecmp
+#undef strncasecmp
+
+#define HAVE_APR
+#include &lt;switch.h&gt;
+#include &lt;switch_version.h&gt;
+#define MODNAME &quot;mod_h323&quot;
+
+
+typedef enum {
+        TFLAG_IO = (1 &lt;&lt; 0),
+        TFLAG_INBOUND = (1 &lt;&lt; 1),
+        TFLAG_OUTBOUND = (1 &lt;&lt; 2),
+        TFLAG_READING = (1 &lt;&lt; 3),
+        TFLAG_WRITING = (1 &lt;&lt; 4),
+        TFLAG_BYE = (1 &lt;&lt; 5),
+        TFLAG_VOICE = (1 &lt;&lt; 6),
+        TFLAG_RTP_READY = (1 &lt;&lt; 7),
+        TFLAG_CODEC_READY = (1 &lt;&lt; 8),
+        TFLAG_TRANSPORT = (1 &lt;&lt; 9),
+        TFLAG_ANSWER = (1 &lt;&lt; 10),
+        TFLAG_VAD_IN = (1 &lt;&lt; 11),
+        TFLAG_VAD_OUT = (1 &lt;&lt; 12),
+        TFLAG_VAD = (1 &lt;&lt; 13),
+        TFLAG_DO_CAND = (1 &lt;&lt; 14),
+        TFLAG_DO_DESC = (1 &lt;&lt; 15),
+        TFLAG_LANADDR = (1 &lt;&lt; 16),
+        TFLAG_AUTO = (1 &lt;&lt; 17),
+        TFLAG_DTMF = (1 &lt;&lt; 18),
+        TFLAG_TIMER = (1 &lt;&lt; 19),
+        TFLAG_TERM = (1 &lt;&lt; 20),
+        TFLAG_TRANSPORT_ACCEPT = (1 &lt;&lt; 21),
+        TFLAG_READY = (1 &lt;&lt; 22),
+} TFLAGS;
+
+struct mod_h323_globals {
+    int trace_level;
+    char *codec_string;
+    char *context;
+    char *dialplan;
+};
+
+extern struct mod_h323_globals mod_h323_globals;
+
+class FSH323Connection;
+class FSH323_ExternalRTPChannel;
+
+typedef struct {
+        unsigned int flags;
+    switch_timer_t read_timer;
+    switch_codec_t read_codec;
+    switch_codec_t write_codec;
+        switch_frame_t read_frame;
+        
+    switch_timer_t vid_read_timer;
+    switch_codec_t vid_read_codec;
+    switch_codec_t vid_write_codec;
+        switch_rtp_t *rtp_session;
+        switch_mutex_t *flag_mutex;
+        switch_mutex_t *h323_mutex;
+        
+    FSH323Connection *me;
+} h323_private_t;
+
+#define DECLARE_CALLBACK0(name)                           \
+    static switch_status_t name(switch_core_session_t *session) {       \
+        h323_private_t *tech_pvt = (h323_private_t *) switch_core_session_get_private(session); \
+        return tech_pvt &amp;&amp; tech_pvt-&gt;me != NULL ? tech_pvt-&gt;me-&gt;name() : SWITCH_STATUS_FALSE; } \
+switch_status_t name()
+
+#define DECLARE_CALLBACK1(name, type1, name1)                           \
+    static switch_status_t name(switch_core_session_t *session, type1 name1) { \
+        h323_private_t *tech_pvt = (h323_private_t *) switch_core_session_get_private(session); \
+        return tech_pvt &amp;&amp; tech_pvt-&gt;me != NULL ? tech_pvt-&gt;me-&gt;name(name1) : SWITCH_STATUS_FALSE; } \
+switch_status_t name(type1 name1)
+
+#define DECLARE_CALLBACK3(name, type1, name1, type2, name2, type3, name3) \
+    static switch_status_t name(switch_core_session_t *session, type1 name1, type2 name2, type3 name3) { \
+        h323_private_t *tech_pvt = (h323_private_t *) switch_core_session_get_private(session); \
+        return tech_pvt &amp;&amp; tech_pvt-&gt;me != NULL ? tech_pvt-&gt;me-&gt;name(name1, name2, name3) : SWITCH_STATUS_FALSE; } \
+switch_status_t name(type1 name1, type2 name2, type3 name3)
+
+class FSH323EndPoint;
+class FSProcess : public PLibraryProcess {
+    PCLASSINFO(FSProcess, PLibraryProcess);
+
+ public:
+    FSProcess();
+    ~FSProcess();
+
+    bool Initialise(switch_loadable_module_interface_t *iface);
+
+    FSH323EndPoint &amp; GetH323EndPoint() const { return *m_h323endpoint; }
+
+  protected:
+    FSH323EndPoint * m_h323endpoint;
+};
+
+struct FSListener {
+    FSListener() {
+    }
+
+    PString name;
+    H323ListenerTCP *listenAddress;
+    PString localUserName;
+    PString gatekeeper;
+};
+
+class FSH323EndPoint:public H323EndPoint {
+
+    PCLASSINFO(FSH323EndPoint, H323EndPoint);
+        public:
+                FSH323EndPoint();
+                
+                
+         /**Create a connection that uses the specified call.
+      */
+        virtual H323Connection* CreateConnection(
+                unsigned callReference, 
+                void* userData,
+                H323Transport* transport, 
+                H323SignalPDU* setupPDU
+        );
+        virtual bool OnSetGatewayPrefixes(PStringList &amp; prefixes) const;
+        
+        bool Initialise(switch_loadable_module_interface_t *iface);
+        
+    switch_status_t ReadConfig(int reload);
+        
+        switch_endpoint_interface_t *GetSwitchInterface() const {
+        return m_freeswitch;
+    }
+        FSH323Connection * FSMakeCall(const PString &amp; dest,void *userData);
+        list &lt;FSListener&gt; m_listeners;
+        
+        protected:
+                PStringList m_gkPrefixes;
+                switch_endpoint_interface_t *m_freeswitch;
+                PString m_gkAddress;
+                PString m_gkIdentifer;
+                PString m_gkInterface;
+                
+};
+
+class FSH323Connection:public H323Connection {
+    PCLASSINFO(FSH323Connection, H323Connection)
+
+  public:
+        FSH323Connection(FSH323EndPoint&amp; endpoint, 
+                                        H323Transport* transport, 
+                                        unsigned callReference, 
+                                        switch_caller_profile_t *outbound_profile,
+                                        switch_core_session_t *fsSession,
+                                        switch_channel_t *fsChannel);
+
+        ~FSH323Connection();                                
+
+        virtual H323Channel* CreateRealTimeLogicalChannel(
+                const H323Capability&amp; capability, 
+                H323Channel::Directions dir,
+                unsigned sessionID,
+                const H245_H2250LogicalChannelParameters* param,
+                RTP_QOS * rtpqos = NULL
+        );
+        virtual PBoolean OnStartLogicalChannel(H323Channel&amp; channel);
+        virtual PBoolean OnCreateLogicalChannel(const H323Capability&amp; capability, H323Channel::Directions dir, unsigned&amp; errorCode);
+        virtual void OnReceivedReleaseComplete(const H323SignalPDU &amp; pdu);
+        virtual        bool OnReceivedProgress(const H323SignalPDU &amp;);
+        virtual bool OnSendReleaseComplete(H323SignalPDU &amp; pdu);
+        virtual PBoolean OpenLogicalChannel(const H323Capability&amp; capability, unsigned sessionID, H323Channel::Directions dir);
+    void setRemoteAddress(const char* remoteIP, WORD remotePort);
+        virtual void OnSetLocalCapabilities();
+        virtual bool OnAlerting(const H323SignalPDU &amp;alertingPDU, const PString &amp;user);
+        virtual void OnEstablished();
+        bool SetLocalCapabilities();
+        static bool decodeCapability(const H323Capability&amp; capability, const char** dataFormat, int* payload = 0, PString* capabName = 0);
+        virtual H323Connection::AnswerCallResponse OnAnswerCall(const PString&amp; caller,
+                                                const H323SignalPDU&amp; signalPDU, H323SignalPDU&amp; connectPDU);
+        virtual bool OnReceivedCapabilitySet(const H323Capabilities &amp; remoteCaps,
+                                                                const H245_MultiplexCapability * muxCap,
+                                                                H245_TerminalCapabilitySetReject &amp; reject);
+        switch_core_session_t *GetSession() const {
+        return m_fsSession;
+    }
+        virtual void SendUserInputTone(char tone, unsigned duration = 0, unsigned logicalChannel = 0, unsigned rtpTimestamp = 0);
+        virtual void OnUserInputTone(char, unsigned, unsigned, unsigned);
+        virtual void OnUserInputString(const PString &amp;value);
+        DECLARE_CALLBACK0(on_init);
+    DECLARE_CALLBACK0(on_routing);
+    DECLARE_CALLBACK0(on_execute);
+
+    DECLARE_CALLBACK0(on_exchange_media);
+    DECLARE_CALLBACK0(on_soft_execute);
+
+    DECLARE_CALLBACK1(kill_channel, int, sig);
+    DECLARE_CALLBACK1(send_dtmf, const switch_dtmf_t *, dtmf);
+    DECLARE_CALLBACK1(receive_message, switch_core_session_message_t *, msg);
+    DECLARE_CALLBACK1(receive_event, switch_event_t *, event);
+    DECLARE_CALLBACK0(state_change);
+
+        DECLARE_CALLBACK3(read_audio_frame, switch_frame_t **, frame, switch_io_flag_t, flags, int, stream_id);
+    DECLARE_CALLBACK3(write_audio_frame, switch_frame_t *, frame, switch_io_flag_t, flags, int, stream_id);
+    DECLARE_CALLBACK3(read_video_frame, switch_frame_t **, frame, switch_io_flag_t, flag, int, stream_id);
+    DECLARE_CALLBACK3(write_video_frame, switch_frame_t *, frame, switch_io_flag_t, flag, int, stream_id);
+        
+        bool m_callOnPreAnswer;
+        bool m_startRTP;
+        PSyncPoint m_rxAudioOpened;
+    PSyncPoint m_txAudioOpened;
+  protected:
+        FSH323EndPoint * m_endpoint;
+        PString m_remoteAddr;
+    int m_remotePort;
+        switch_core_session_t *m_fsSession;
+    switch_channel_t *m_fsChannel;
+        PIPSocket::Address m_RTPlocalIP;
+        WORD m_RTPlocalPort;
+        unsigned char m_buf[SWITCH_RECOMMENDED_BUFFER_SIZE];
+};
+
+class FSH323_ExternalRTPChannel : public H323_ExternalRTPChannel{
+    PCLASSINFO(FSH323_ExternalRTPChannel, H323_ExternalRTPChannel);
+public:
+    /* Create a new channel. */
+    FSH323_ExternalRTPChannel(
+                FSH323Connection&amp; connection,
+                const H323Capability&amp; capability,
+                Directions direction,
+                unsigned sessionID,
+                const PIPSocket::Address&amp; ip, 
+                WORD dataPort
+        );
+    /* Destructor */
+    ~FSH323_ExternalRTPChannel();
+
+    virtual PBoolean Start();
+    virtual PBoolean OnReceivedAckPDU(const H245_H2250LogicalChannelAckParameters&amp; param);
+    virtual PBoolean OnSendingPDU(H245_H2250LogicalChannelParameters&amp; param);
+    virtual PBoolean OnReceivedPDU(const H245_H2250LogicalChannelParameters&amp; param,unsigned&amp; errorCode);
+    virtual void OnSendOpenAck(H245_H2250LogicalChannelAckParameters&amp; param);
+        
+
+private:
+    FSH323Connection* m_conn;
+        const H323Capability* m_capability;
+        switch_core_session_t *m_fsSession;
+        switch_channel_t *m_fsChannel;
+        switch_codec_t *m_switchCodec;
+        OpalMediaFormat *m_format;
+        switch_frame_t m_readFrame;
+        switch_timer_t *m_switchTimer;
+        PString m_RTPremoteIP;
+        WORD m_RTPremotePort;
+        PString m_RTPlocalIP;
+        WORD m_RTPlocalPort;
+        BYTE payloadCode;
+        
+};
+
+class BaseG7231Capab : public H323AudioCapability
+{
+    PCLASSINFO(BaseG7231Capab, H323AudioCapability);
+public:
+    BaseG7231Capab(const char* fname, bool annexA = true)
+        : H323AudioCapability(7,4), m_name(fname), m_aa(annexA)
+        { }
+        
+    virtual PObject* Clone() const{ 
+                return new BaseG7231Capab(*this); 
+        }
+        
+    virtual unsigned GetSubType() const{
+                return H245_AudioCapability::e_g7231; 
+        }
+        
+    virtual PString GetFormatName() const{
+                return m_name; 
+        }
+        
+    virtual H323Codec* CreateCodec(H323Codec::Direction direction) const{
+                return 0; 
+        }
+        
+    virtual Comparison Compare(const PObject&amp; obj) const{
+            Comparison res = H323AudioCapability::Compare(obj);
+            if (res != EqualTo)
+                        return res;
+            bool aa = static_cast&lt;const BaseG7231Capab&amp;&gt;(obj).m_aa;
+            if (aa &amp;&amp; !m_aa)
+                        return LessThan;
+            if (m_aa &amp;&amp; !aa)
+                        return GreaterThan;
+            return EqualTo;
+        }
+        
+    virtual bool OnSendingPDU(H245_AudioCapability&amp; pdu, unsigned packetSize) const        {
+            pdu.SetTag(GetSubType());
+            H245_AudioCapability_g7231&amp; g7231 = pdu;
+            g7231.m_maxAl_sduAudioFrames = packetSize;
+            g7231.m_silenceSuppression = m_aa;
+            return true;
+        }
+        
+    virtual bool OnReceivedPDU(const H245_AudioCapability&amp; pdu, unsigned&amp; packetSize){
+            if (pdu.GetTag() != H245_AudioCapability::e_g7231)
+                        return false;
+            const H245_AudioCapability_g7231&amp; g7231 = pdu;
+            packetSize = g7231.m_maxAl_sduAudioFrames;
+            m_aa = (g7231.m_silenceSuppression != 0);
+            return true;
+        }
+
+protected:
+    const char* m_name;
+    bool m_aa;
+};
+
+class BaseG729Capab : public H323AudioCapability
+{
+    PCLASSINFO(BaseG729Capab, H323AudioCapability);
+public:
+    BaseG729Capab(const char* fname, unsigned type = H245_AudioCapability::e_g729)
+        : H323AudioCapability(24,6), m_name(fname), m_type(type)
+        { }
+    virtual PObject* Clone() const
+        // default copy constructor - take care!
+        { return new BaseG729Capab(*this); }
+    virtual unsigned GetSubType() const
+        { return m_type; }
+    virtual PString GetFormatName() const
+        { return m_name; }
+    virtual H323Codec* CreateCodec(H323Codec::Direction direction) const
+        { return 0; }
+protected:
+    const char* m_name;
+    unsigned m_type;
+};
+
+class BaseGSM0610Cap : public H323AudioCapability
+{
+        PCLASSINFO(BaseGSM0610Cap, H323AudioCapability);
+
+public:
+        
+        BaseGSM0610Cap(const char* fname, unsigned type = H245_AudioCapability::e_gsmFullRate)
+        : H323AudioCapability(24,2), m_name(fname), m_type(type),m_comfortNoise(0),m_scrambled(0)
+        { }
+        
+        virtual PObject * Clone() const{
+                return new BaseGSM0610Cap(*this);
+        }
+
+        virtual H323Codec* CreateCodec(H323Codec::Direction direction) const{
+                return 0;
+        }
+
+        virtual unsigned GetSubType() const{
+                return H245_AudioCapability::e_gsmFullRate;
+        }
+
+        virtual PString GetFormatName() const{
+                return m_name;
+        }
+
+        virtual bool OnSendingPDU(H245_AudioCapability &amp; pdu, unsigned packetSize) const{
+                pdu.SetTag(H245_AudioCapability::e_gsmFullRate);
+                H245_GSMAudioCapability &amp; gsm = pdu;
+                gsm.m_audioUnitSize = packetSize * 33;
+                gsm.m_comfortNoise = m_comfortNoise;
+                gsm.m_scrambled = m_scrambled;
+                return true;
+        }
+        
+        virtual bool OnReceivedPDU(const H245_AudioCapability &amp; pdu, unsigned &amp; packetSize){
+                PTRACE(2, &quot;mod_h323\t==============&gt;BaseGSM0610Cap::OnReceivedPDU&quot;);
+                if (pdu.GetTag() != H245_AudioCapability::e_gsmFullRate)
+                        return false;
+                const H245_GSMAudioCapability &amp; gsm = pdu;
+                packetSize = (gsm.m_audioUnitSize + 32) / 33;
+                m_comfortNoise = gsm.m_comfortNoise;
+                m_scrambled = gsm.m_scrambled;
+                return true;
+        }
+
+protected:
+        const char* m_name;
+        int m_comfortNoise;
+        int m_scrambled;
+        unsigned m_type;
+};
+
+
+#define DEFINE_H323_CAPAB(cls,base,param,name) \
+class cls : public base { \
+  public: \
+    cls() : base(name,param) { } \
+}; \
+H323_REGISTER_CAPABILITY(cls,name) \
+
+
+DEFINE_H323_CAPAB(FS_G7231_5,BaseG7231Capab,false,OPAL_G7231_5k3&quot;{sw}&quot;)
+DEFINE_H323_CAPAB(FS_G7231_6,BaseG7231Capab,false,OPAL_G7231_6k3&quot;{sw}&quot;)
+DEFINE_H323_CAPAB(FS_G7231A_5,BaseG7231Capab,true,OPAL_G7231A_5k3&quot;{sw}&quot;)
+DEFINE_H323_CAPAB(FS_G7231A_6,BaseG7231Capab,true,OPAL_G7231A_6k3&quot;{sw}&quot;)
+DEFINE_H323_CAPAB(FS_G729,BaseG729Capab,H245_AudioCapability::e_g729,OPAL_G729&quot;{sw}&quot;)
+DEFINE_H323_CAPAB(FS_G729A,BaseG729Capab,H245_AudioCapability::e_g729AnnexA,OPAL_G729A&quot;{sw}&quot;)
+DEFINE_H323_CAPAB(FS_G729B,BaseG729Capab,H245_AudioCapability::e_g729wAnnexB,OPAL_G729B&quot;{sw}&quot;)
+DEFINE_H323_CAPAB(FS_G729AB,BaseG729Capab,H245_AudioCapability::e_g729AnnexAwAnnexB,OPAL_G729AB&quot;{sw}&quot;)
+DEFINE_H323_CAPAB(FS_GSM,BaseGSM0610Cap,H245_AudioCapability::e_gsmFullRate,OPAL_GSM0610&quot;{sw}&quot;)
+
+static FSProcess *h323_process = NULL;
</ins></span></pre>
</div>
</div>
<div id="footer">See you at ClueCon</div>

</body>
</html>