<!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][16632] </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=16632">16632</a></dd>
<dt>Author</dt> <dd>gmaruzz</dd>
<dt>Date</dt> <dd>2010-02-13 05:10:30 -0600 (Sat, 13 Feb 2010)</dd>
</dl>

<h3>Log Message</h3>
<pre>skypiax: nothing to see here</pre>

<h3>Added Paths</h3>
<ul>
<li>freeswitch/trunk/src/mod/endpoints/mod_skypiax/103/</li>
<li><a href="#freeswitchtrunksrcmodendpointsmod_skypiax103dummyc">freeswitch/trunk/src/mod/endpoints/mod_skypiax/103/dummy.c</a></li>
<li><a href="#freeswitchtrunksrcmodendpointsmod_skypiax103mod_skypiaxc">freeswitch/trunk/src/mod/endpoints/mod_skypiax/103/mod_skypiax.c</a></li>
<li><a href="#freeswitchtrunksrcmodendpointsmod_skypiax103skypiaxh">freeswitch/trunk/src/mod/endpoints/mod_skypiax/103/skypiax.h</a></li>
<li><a href="#freeswitchtrunksrcmodendpointsmod_skypiax103skypiax_protocolc">freeswitch/trunk/src/mod/endpoints/mod_skypiax/103/skypiax_protocol.c</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="freeswitchtrunksrcmodendpointsmod_skypiax103dummyc"></a>
<div class="addfile"><h4>Added: freeswitch/trunk/src/mod/endpoints/mod_skypiax/103/dummy.c (0 => 16632)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/src/mod/endpoints/mod_skypiax/103/dummy.c                                (rev 0)
+++ freeswitch/trunk/src/mod/endpoints/mod_skypiax/103/dummy.c        2010-02-13 11:10:30 UTC (rev 16632)
</span><span class="lines">@@ -0,0 +1,964 @@
</span><ins>+/*
+ *  Dummy soundcard
+ *  Copyright (c) by Jaroslav Kysela &lt;perex@perex.cz&gt;
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#include &lt;sound/driver.h&gt;                //giova
+#include &lt;linux/init.h&gt;
+#include &lt;linux/err.h&gt;
+#include &lt;linux/platform_device.h&gt;
+#include &lt;linux/jiffies.h&gt;
+#include &lt;linux/slab.h&gt;
+#include &lt;linux/time.h&gt;
+#include &lt;linux/wait.h&gt;
+#include &lt;linux/moduleparam.h&gt;
+#include &lt;sound/core.h&gt;
+#include &lt;sound/control.h&gt;
+#include &lt;sound/tlv.h&gt;
+#include &lt;sound/pcm.h&gt;
+#include &lt;sound/rawmidi.h&gt;
+#include &lt;sound/initval.h&gt;
+
+
+MODULE_AUTHOR(&quot;Jaroslav Kysela &lt;perex@perex.cz&gt;&quot;);
+MODULE_DESCRIPTION(&quot;Dummy soundcard (/dev/null)&quot;);
+MODULE_LICENSE(&quot;GPL&quot;);
+MODULE_SUPPORTED_DEVICE(&quot;{{ALSA,Dummy soundcard}}&quot;);
+
+#define GIOVAMULTI                1
+#define MAX_PCM_DEVICES                4
+#define MAX_PCM_SUBSTREAMS        128
+#define MAX_MIDI_DEVICES        2
+
+#if 0                                                        /* emu10k1 emulation */
+#define MAX_BUFFER_SIZE                (128 * 1024)
+static int emu10k1_playback_constraints(struct snd_pcm_runtime *runtime)
+{
+        int err;
+        err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+        if (err &lt; 0)
+                return err;
+        err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 256, UINT_MAX);
+        if (err &lt; 0)
+                return err;
+        return 0;
+}
+
+#define add_playback_constraints emu10k1_playback_constraints
+#endif
+
+#if 0                                                        /* RME9652 emulation */
+#define MAX_BUFFER_SIZE                (26 * 64 * 1024)
+#define USE_FORMATS                SNDRV_PCM_FMTBIT_S32_LE
+#define USE_CHANNELS_MIN        26
+#define USE_CHANNELS_MAX        26
+#define USE_PERIODS_MIN                2
+#define USE_PERIODS_MAX                2
+#endif
+
+#if 0                                                        /* ICE1712 emulation */
+#define MAX_BUFFER_SIZE                (256 * 1024)
+#define USE_FORMATS                SNDRV_PCM_FMTBIT_S32_LE
+#define USE_CHANNELS_MIN        10
+#define USE_CHANNELS_MAX        10
+#define USE_PERIODS_MIN                1
+#define USE_PERIODS_MAX                1024
+#endif
+
+#if 0                                                        /* UDA1341 emulation */
+#define MAX_BUFFER_SIZE                (16380)
+#define USE_FORMATS                SNDRV_PCM_FMTBIT_S16_LE
+#define USE_CHANNELS_MIN        2
+#define USE_CHANNELS_MAX        2
+#define USE_PERIODS_MIN                2
+#define USE_PERIODS_MAX                255
+#endif
+
+#if 0                                                        /* simple AC97 bridge (intel8x0) with 48kHz AC97 only codec */
+#define USE_FORMATS                SNDRV_PCM_FMTBIT_S16_LE
+#define USE_CHANNELS_MIN        2
+#define USE_CHANNELS_MAX        2
+#define USE_RATE                SNDRV_PCM_RATE_48000
+#define USE_RATE_MIN                48000
+#define USE_RATE_MAX                48000
+#endif
+
+#if 0                                                        /* CA0106 */
+#define USE_FORMATS                SNDRV_PCM_FMTBIT_S16_LE
+#define USE_CHANNELS_MIN        2
+#define USE_CHANNELS_MAX        2
+#define USE_RATE                (SNDRV_PCM_RATE_48000|SNDRV_PCM_RATE_96000|SNDRV_PCM_RATE_192000)
+#define USE_RATE_MIN                48000
+#define USE_RATE_MAX                192000
+#define MAX_BUFFER_SIZE                ((65536-64)*8)
+#define MAX_PERIOD_SIZE                (65536-64)
+#define USE_PERIODS_MIN                2
+#define USE_PERIODS_MAX                8
+#endif
+
+
+/* defaults */
+#ifndef MAX_BUFFER_SIZE
+//#define MAX_BUFFER_SIZE                (64*1024)
+#define MAX_BUFFER_SIZE                (256*1024)
+#endif
+#ifndef MAX_PERIOD_SIZE
+#define MAX_PERIOD_SIZE                MAX_BUFFER_SIZE
+#endif
+#ifndef USE_FORMATS
+//#define USE_FORMATS                 (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE)
+#define USE_FORMATS                 SNDRV_PCM_FMTBIT_S16_LE
+#endif
+#ifndef USE_RATE
+//#define USE_RATE                SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000
+#define USE_RATE                SNDRV_PCM_RATE_8000
+//#define USE_RATE_MIN                5500
+#define USE_RATE_MIN                8000
+//#define USE_RATE_MAX                48000
+#define USE_RATE_MAX                8000
+#endif
+#ifndef USE_CHANNELS_MIN
+#define USE_CHANNELS_MIN         1
+#endif
+#ifndef USE_CHANNELS_MAX
+#define USE_CHANNELS_MAX         2
+#endif
+#ifndef USE_PERIODS_MIN
+#define USE_PERIODS_MIN         1
+#endif
+#ifndef USE_PERIODS_MAX
+#define USE_PERIODS_MAX         1024
+#endif
+#ifndef add_playback_constraints
+#define add_playback_constraints(x) 0
+#endif
+#ifndef add_capture_constraints
+#define add_capture_constraints(x) 0
+#endif
+
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;        /* Index 0-MAX */
+static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;        /* ID for this card */
+static int enable[SNDRV_CARDS] = { 1,[1 ... (SNDRV_CARDS - 1)] = 0 };
+static int pcm_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1 };
+static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 128 };
+
+//static int midi_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
+
+module_param_array(index, int, NULL, 0444);
+MODULE_PARM_DESC(index, &quot;Index value for dummy soundcard.&quot;);
+module_param_array(id, charp, NULL, 0444);
+MODULE_PARM_DESC(id, &quot;ID string for dummy soundcard.&quot;);
+module_param_array(enable, bool, NULL, 0444);
+MODULE_PARM_DESC(enable, &quot;Enable this dummy soundcard.&quot;);
+module_param_array(pcm_devs, int, NULL, 0444);
+MODULE_PARM_DESC(pcm_devs, &quot;PCM devices # (0-4) for dummy driver.&quot;);
+module_param_array(pcm_substreams, int, NULL, 0444);
+MODULE_PARM_DESC(pcm_substreams, &quot;PCM substreams # (1-64) for dummy driver.&quot;);
+//module_param_array(midi_devs, int, NULL, 0444);
+//MODULE_PARM_DESC(midi_devs, &quot;MIDI devices # (0-2) for dummy driver.&quot;);
+
+static struct platform_device *devices[SNDRV_CARDS];
+static struct timer_list giovatimer;        //giova
+static int giovastarted = 0;
+static int giovaindex = 0;
+static spinlock_t giovalock;
+struct giovadpcm {
+        struct snd_pcm_substream *substream;
+        struct snd_dummy_pcm *dpcm;
+        int started;
+};
+static struct giovadpcm giovadpcms[MAX_PCM_SUBSTREAMS];
+
+#define MIXER_ADDR_MASTER        0
+#define MIXER_ADDR_LINE                1
+#define MIXER_ADDR_MIC                2
+#define MIXER_ADDR_SYNTH        3
+#define MIXER_ADDR_CD                4
+#define MIXER_ADDR_LAST                4
+
+static void snd_card_dummy_pcm_timer_function(unsigned long data);
+struct snd_dummy {
+        struct snd_card *card;
+        struct snd_pcm *pcm;
+        spinlock_t mixer_lock;
+        int mixer_volume[MIXER_ADDR_LAST + 1][2];
+        int capture_source[MIXER_ADDR_LAST + 1][2];
+};
+
+struct snd_dummy_pcm {
+        struct snd_dummy *dummy;
+        spinlock_t lock;
+        struct timer_list timer;
+        unsigned int pcm_buffer_size;
+        unsigned int pcm_period_size;
+        unsigned int pcm_bps;                /* bytes per second */
+        unsigned int pcm_hz;                /* HZ */
+        unsigned int pcm_irq_pos;        /* IRQ position */
+        unsigned int pcm_buf_pos;        /* position in buffer */
+        struct snd_pcm_substream *substream;
+};
+
+
+static inline void snd_card_dummy_pcm_timer_start(struct snd_dummy_pcm *dpcm)
+{
+        int i;
+        int found = 0;
+
+
+//printk(&quot;giova: 1 timer_start %d %p\n&quot;, __LINE__, dpcm);
+        for (i = 0; i &lt; giovaindex + 1; i++) {
+                if (i &gt; MAX_PCM_SUBSTREAMS || giovaindex &gt; MAX_PCM_SUBSTREAMS) {
+                        printk(&quot;giova, %s:%d, i=%d, giovaindex=%d dpcm=%p\n&quot;, __FILE__, __LINE__, i, giovaindex, dpcm);
+                }
+
+                if (giovadpcms[i].dpcm == dpcm) {
+                        giovadpcms[i].started = 1;
+                        found = 1;
+                }
+        }
+        if (!found) {
+                printk(&quot;skypiax: start, NOT found?\n&quot;);
+        }
+
+//printk(&quot;giova: 2 timer_start %d %p\n&quot;, __LINE__, dpcm);
+}
+
+static inline void snd_card_dummy_pcm_timer_stop(struct snd_dummy_pcm *dpcm)
+{
+        //del_timer(&amp;dpcm-&gt;timer);
+        int i;
+        int found = 0;
+
+//printk(&quot;giova: 1 timer_stop %d %p\n&quot;, __LINE__, dpcm);
+        for (i = 0; i &lt; giovaindex + 1; i++) {
+
+                if (i &gt; MAX_PCM_SUBSTREAMS || giovaindex &gt; MAX_PCM_SUBSTREAMS) {
+                        printk(&quot;giova, %s:%d, i=%d, giovaindex=%d dpcm=%p\n&quot;, __FILE__, __LINE__, i, giovaindex, dpcm);
+                }
+                if (giovadpcms[i].dpcm == dpcm) {
+                        giovadpcms[i].started = 0;
+                        found = 1;
+                }
+        }
+        if (!found) {
+                //printk(&quot;skypiax: stop, NOT found?\n&quot;);
+        } else {
+                //printk(&quot;skypiax: stop, YES found!\n&quot;); 
+        }
+
+
+
+//printk(&quot;giova: 2 timer_stop %d %p\n&quot;, __LINE__, dpcm);
+}
+
+static int snd_card_dummy_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+        struct snd_pcm_runtime *runtime = substream-&gt;runtime;
+        struct snd_dummy_pcm *dpcm = runtime-&gt;private_data;
+        int err = 0;
+
+        //spin_lock(&amp;dpcm-&gt;lock, flags);
+        spin_lock_bh(&amp;giovalock);
+        switch (cmd) {
+        case SNDRV_PCM_TRIGGER_START:
+        case SNDRV_PCM_TRIGGER_RESUME:
+//printk(&quot;giova: trigger timer_start %d %p\n&quot;, __LINE__, dpcm);
+                snd_card_dummy_pcm_timer_start(dpcm);
+                break;
+        case SNDRV_PCM_TRIGGER_STOP:
+        case SNDRV_PCM_TRIGGER_SUSPEND:
+//printk(&quot;giova: trigger timer_stop %d %p\n&quot;, __LINE__, dpcm);
+                snd_card_dummy_pcm_timer_stop(dpcm);
+                break;
+        default:
+                err = -EINVAL;
+                break;
+        }
+        //spin_unlock(&amp;dpcm-&gt;lock, flags);
+        spin_unlock_bh(&amp;giovalock);
+        return 0;
+}
+
+static int snd_card_dummy_pcm_prepare(struct snd_pcm_substream *substream)
+{
+        struct snd_pcm_runtime *runtime = substream-&gt;runtime;
+        struct snd_dummy_pcm *dpcm = runtime-&gt;private_data;
+        int bps;
+
+        bps = snd_pcm_format_width(runtime-&gt;format) * runtime-&gt;rate * runtime-&gt;channels / 8;
+
+        if (bps &lt;= 0)
+                return -EINVAL;
+
+        dpcm-&gt;pcm_bps = bps;
+        dpcm-&gt;pcm_hz = HZ;
+        dpcm-&gt;pcm_buffer_size = snd_pcm_lib_buffer_bytes(substream);
+        dpcm-&gt;pcm_period_size = snd_pcm_lib_period_bytes(substream);
+        dpcm-&gt;pcm_irq_pos = 0;
+        dpcm-&gt;pcm_buf_pos = 0;
+        snd_pcm_format_set_silence(runtime-&gt;format, runtime-&gt;dma_area, bytes_to_samples(runtime, runtime-&gt;dma_bytes));
+
+//printk(&quot;giova: prepare %d %p\n&quot;, __LINE__, dpcm);
+        return 0;
+}
+
+static void snd_card_dummy_pcm_timer_function(unsigned long data)
+{
+        //struct snd_dummy_pcm *dpcm = (struct snd_dummy_pcm *)data;
+        struct snd_dummy_pcm *dpcm = NULL;
+        //unsigned long flags;
+        int i;
+
+
+        giovatimer.expires = (HZ/100 * (GIOVAMULTI)) + jiffies;
+        add_timer(&amp;giovatimer);
+
+        for (i = 0; i &lt; giovaindex + 1; i++) {
+
+                if (i &gt; MAX_PCM_SUBSTREAMS || giovaindex &gt; MAX_PCM_SUBSTREAMS) {
+                        printk(&quot;giova, %s:%d, i=%d, giovaindex=%d dpcm=%p\n&quot;, __FILE__, __LINE__, i, giovaindex, dpcm);
+                }
+//printk(&quot;giova: timer_func %d i=%d\n&quot;, __LINE__, i);
+
+                if (giovadpcms[i].started != 1)
+                        continue;
+                dpcm = giovadpcms[i].dpcm;
+                if (dpcm == NULL) {
+                        printk(&quot;giova: timer_func %d %d NULL: continue\n&quot;, __LINE__, i);
+                        continue;
+                }
+                //spin_lock_bh(&amp;dpcm-&gt;lock);
+                //if (in_irq())
+                        //printk(&quot;giova: timer_func %d %d we are in HARDWARE IRQ\n&quot;, __LINE__, i);
+                //if(in_softirq())
+                //printk(&quot;giova: timer_func %d %d we are in SOFT IRQ\n&quot;, __LINE__, i);
+//printk(&quot;giova: timer_func %d %d\n&quot;, __LINE__, i);
+                //spin_lock_irqsave(&amp;dpcm-&gt;lock, flags);
+                spin_lock_bh(&amp;dpcm-&gt;lock);
+//CICOPET printk(&quot;%d %s, dpcm=%p, dpcm-&gt;pcm_irq_pos=%u\t\t dpcm-&gt;pcm_bps=%u\t\t dpcm-&gt;pcm_buf_pos=%u\n&quot;, __LINE__, __FILE__, dpcm, dpcm-&gt;pcm_irq_pos, dpcm-&gt;pcm_bps,  dpcm-&gt;pcm_buf_pos);
+                //dpcm-&gt;pcm_irq_pos += dpcm-&gt;pcm_bps * ((HZ / 100) * GIOVAMULTI);
+                //dpcm-&gt;pcm_irq_pos += (dpcm-&gt;pcm_bps * ((HZ / 100) * GIOVAMULTI));
+                dpcm-&gt;pcm_irq_pos += (dpcm-&gt;pcm_bps * ( (HZ / 100) * GIOVAMULTI));
+//CICOPET printk(&quot;%d %s, dpcm=%p, dpcm-&gt;pcm_irq_pos=%u\t\t dpcm-&gt;pcm_bps=%u\t\t dpcm-&gt;pcm_buf_pos=%u\n&quot;, __LINE__, __FILE__, dpcm, dpcm-&gt;pcm_irq_pos, dpcm-&gt;pcm_bps,  dpcm-&gt;pcm_buf_pos);
+                //dpcm-&gt;pcm_buf_pos += (dpcm-&gt;pcm_bps * ((HZ / 100) * GIOVAMULTI));
+                dpcm-&gt;pcm_buf_pos += (dpcm-&gt;pcm_bps * ( (HZ / 100) * GIOVAMULTI));
+//CICOPET printk(&quot;%d %s, dpcm=%p, dpcm-&gt;pcm_irq_pos=%u\t\t dpcm-&gt;pcm_bps=%u\t\t dpcm-&gt;pcm_buf_pos=%u\n&quot;, __LINE__, __FILE__, dpcm, dpcm-&gt;pcm_irq_pos, dpcm-&gt;pcm_bps,  dpcm-&gt;pcm_buf_pos);
+                //dpcm-&gt;pcm_buf_pos %= (dpcm-&gt;pcm_buffer_size * dpcm-&gt;pcm_hz * GIOVAMULTI);
+                dpcm-&gt;pcm_buf_pos %= (dpcm-&gt;pcm_buffer_size * dpcm-&gt;pcm_hz );
+//BUONI printk(&quot;%d %s, dpcm=%p, dpcm-&gt;pcm_irq_pos=%u\t\t dpcm-&gt;pcm_bps=%u\t\t dpcm-&gt;pcm_buf_pos=%u (dpcm-&gt;pcm_period_size * dpcm-&gt;pcm_hz)=%u\n&quot;, __LINE__, __FILE__, dpcm, dpcm-&gt;pcm_irq_pos, dpcm-&gt;pcm_bps,  dpcm-&gt;pcm_buf_pos, (dpcm-&gt;pcm_period_size * dpcm-&gt;pcm_hz));
+                if (dpcm-&gt;pcm_irq_pos &gt;= (dpcm-&gt;pcm_period_size * dpcm-&gt;pcm_hz)) {
+//CICOPET printk(&quot;%d %s, dpcm=%p, dpcm-&gt;pcm_irq_pos=%u\t\t dpcm-&gt;pcm_bps=%u\t\t dpcm-&gt;pcm_buf_pos=%u\n&quot;, __LINE__, __FILE__, dpcm, dpcm-&gt;pcm_irq_pos, dpcm-&gt;pcm_bps,  dpcm-&gt;pcm_buf_pos);
+                        dpcm-&gt;pcm_irq_pos %= (dpcm-&gt;pcm_period_size * dpcm-&gt;pcm_hz);
+//BUONI printk(&quot;%d %s, dpcm=%p, dpcm-&gt;pcm_irq_pos=%u\t\t dpcm-&gt;pcm_bps=%u\t\t dpcm-&gt;pcm_buf_pos=%u PASSATO!\n&quot;, __LINE__, __FILE__, dpcm, dpcm-&gt;pcm_irq_pos, dpcm-&gt;pcm_bps,  dpcm-&gt;pcm_buf_pos);
+                        //spin_unlock_irqrestore(&amp;dpcm-&gt;lock, flags);
+                        spin_unlock_bh(&amp;dpcm-&gt;lock);
+                        snd_pcm_period_elapsed(dpcm-&gt;substream);
+                } else {
+                        //spin_unlock_irqrestore(&amp;dpcm-&gt;lock, flags);
+                        spin_unlock_bh(&amp;dpcm-&gt;lock);
+                }
+        }
+}
+
+static snd_pcm_uframes_t snd_card_dummy_pcm_pointer(struct snd_pcm_substream *substream)
+{
+        struct snd_pcm_runtime *runtime = substream-&gt;runtime;
+        struct snd_dummy_pcm *dpcm = runtime-&gt;private_data;
+
+snd_pcm_uframes_t ciapa=0;
+
+                spin_lock_bh(&amp;dpcm-&gt;lock);
+//ciapa = (dpcm-&gt;pcm_buf_pos / dpcm-&gt;pcm_hz) / (dpcm-&gt;pcm_bps/8000);
+//ciapa = bytes_to_frames(runtime, (dpcm-&gt;pcm_buf_pos / (dpcm-&gt;pcm_hz ))) / GIOVAMULTI;
+//printk(&quot;%d %s, dpcm=%p, dpcm-&gt;pcm_irq_pos=%u\t\t dpcm-&gt;pcm_bps=%u\t\t dpcm-&gt;pcm_buf_pos=%u, ciapa=%u\n&quot;, __LINE__, __FILE__, dpcm, dpcm-&gt;pcm_irq_pos, dpcm-&gt;pcm_bps,  dpcm-&gt;pcm_buf_pos, ciapa);
+ciapa = bytes_to_frames(runtime, (dpcm-&gt;pcm_buf_pos / (dpcm-&gt;pcm_hz )));
+
+                spin_unlock_bh(&amp;dpcm-&gt;lock);
+//printk(&quot;%d %s, dpcm=%p, dpcm-&gt;pcm_irq_pos=%u\t\t dpcm-&gt;pcm_bps=%u\t\t dpcm-&gt;pcm_buf_pos=%u, ciapa=%u\n&quot;, __LINE__, __FILE__, dpcm, dpcm-&gt;pcm_irq_pos, dpcm-&gt;pcm_bps,  dpcm-&gt;pcm_buf_pos, (unsigned int)ciapa);
+return ciapa;
+        //return bytes_to_frames(runtime, (dpcm-&gt;pcm_buf_pos / (dpcm-&gt;pcm_hz )) / GIOVAMULTI);
+        //return (dpcm-&gt;pcm_buf_pos / dpcm-&gt;pcm_hz) / (dpcm-&gt;pcm_bps/8000);
+}
+
+static struct snd_pcm_hardware snd_card_dummy_playback = {
+        .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID),
+        .formats = USE_FORMATS,
+        .rates = USE_RATE,
+        .rate_min = USE_RATE_MIN,
+        .rate_max = USE_RATE_MAX,
+        .channels_min = USE_CHANNELS_MIN,
+        .channels_max = USE_CHANNELS_MAX,
+        .buffer_bytes_max = MAX_BUFFER_SIZE,
+        .period_bytes_min = 64,
+        .period_bytes_max = MAX_PERIOD_SIZE,
+        .periods_min = USE_PERIODS_MIN,
+        .periods_max = USE_PERIODS_MAX,
+        .fifo_size = 0,
+};
+
+static struct snd_pcm_hardware snd_card_dummy_capture = {
+        .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID),
+        .formats = USE_FORMATS,
+        .rates = USE_RATE,
+        .rate_min = USE_RATE_MIN,
+        .rate_max = USE_RATE_MAX,
+        .channels_min = USE_CHANNELS_MIN,
+        .channels_max = USE_CHANNELS_MAX,
+        .buffer_bytes_max = MAX_BUFFER_SIZE,
+        .period_bytes_min = 64,
+        .period_bytes_max = MAX_PERIOD_SIZE,
+        .periods_min = USE_PERIODS_MIN,
+        .periods_max = USE_PERIODS_MAX,
+        .fifo_size = 0,
+};
+
+static void snd_card_dummy_runtime_free(struct snd_pcm_runtime *runtime)
+{
+        int i;
+//int found=0;
+
+//printk(&quot;snd_card_dummy_runtime_free giova 1 giovaindex=%d dpcm=%p runtime=%p\n&quot;, giovaindex, runtime-&gt;private_data, runtime);
+        spin_lock_bh(&amp;giovalock);
+
+        for (i = 0; i &lt; giovaindex; i++) {
+
+                if (i &gt; MAX_PCM_SUBSTREAMS || giovaindex &gt; MAX_PCM_SUBSTREAMS) {
+                        printk(&quot;giova, %s:%d, i=%d, giovaindex=%d \n&quot;, __FILE__, __LINE__, i, giovaindex);
+                }
+                //if((giovadpcms[i].substream == substream)  &amp;&amp; (giovadpcms[i].dpcm == dpcm)){
+                if ((giovadpcms[i].dpcm == runtime-&gt;private_data)) {
+                        //printk(&quot;giova, %s:%d, i=%d, giovaindex=%d %p==%p YES I AM!!!!\n&quot;, __FILE__, __LINE__, i, giovaindex, giovadpcms[i].dpcm , runtime-&gt;private_data);
+                        //giovadpcms[i].dpcm = NULL;
+                        //giovadpcms[i].substream = NULL;
+                        giovadpcms[i].started = 0;
+                        //break;
+                } else {
+                        //printk(&quot;giova, %s:%d, i=%d, giovaindex=%d %p!=%p NOT ME\n&quot;, __FILE__, __LINE__, i, giovaindex, giovadpcms[i].dpcm , runtime-&gt;private_data);
+                }
+        }
+
+        spin_unlock_bh(&amp;giovalock);
+        kfree(runtime-&gt;private_data);
+}
+
+static int snd_card_dummy_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params)
+{
+        return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
+}
+
+static int snd_card_dummy_hw_free(struct snd_pcm_substream *substream)
+{
+        return snd_pcm_lib_free_pages(substream);
+}
+
+static struct snd_dummy_pcm *new_pcm_stream(struct snd_pcm_substream *substream)
+{
+        struct snd_dummy_pcm *dpcm;
+        int i;
+        int found = 0;
+
+        //printk(&quot;giova, %s:%d, i=%d, giovaindex=%d %p==%p YES I AM!!!!\n&quot;, __FILE__, __LINE__, i, giovaindex, giovadpcms[i].dpcm , runtime-&gt;private_data);
+        //printk(&quot;giova, %s:%d, giovaindex=%d\n&quot;, __FILE__, __LINE__, giovaindex);
+        dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
+        //printk(&quot;giova, %s:%d, giovaindex=%d\n&quot;, __FILE__, __LINE__, giovaindex);
+        if (!dpcm) {
+                //spin_unlock_bh(&amp;giovalock);
+                printk(&quot;giova, %s:%d, giovaindex=%d NO MEMORY!!!!\n&quot;, __FILE__, __LINE__, giovaindex);
+                return dpcm;
+        }
+        //printk(&quot;giova, %s:%d, giovaindex=%d dpcm=%p\n&quot;, __FILE__, __LINE__, giovaindex, dpcm);
+        init_timer(&amp;dpcm-&gt;timer);
+        //dpcm-&gt;timer.data = (unsigned long) dpcm;
+        //dpcm-&gt;timer.function = snd_card_dummy_pcm_timer_function;
+        spin_lock_init(&amp;dpcm-&gt;lock);
+        dpcm-&gt;substream = substream;
+
+        spin_lock_bh(&amp;giovalock);
+        //printk(&quot;giova 1 giovaindex=%d dpcm=%p substream=%p sizeof=%lu\n&quot;, giovaindex, dpcm, substream, sizeof(*dpcm));
+        for (i = 0; i &lt; giovaindex; i++) {
+
+                if (i &gt; MAX_PCM_SUBSTREAMS || giovaindex &gt; MAX_PCM_SUBSTREAMS) {
+                        printk(&quot;giova, %s:%d, i=%d, giovaindex=%d dpcm=%p\n&quot;, __FILE__, __LINE__, i, giovaindex, dpcm);
+                }
+                //if((giovadpcms[i].substream == substream)  &amp;&amp; (giovadpcms[i].dpcm == dpcm))
+                if ((giovadpcms[i].substream == substream)) {
+                        found = 1;
+                        break;
+                }
+
+        }
+
+        if (!found) {
+
+                giovadpcms[giovaindex].substream = substream;
+                giovaindex++;
+                //printk(&quot;giova 2 giovaindex=%d dpcm=%p substream=%p\n&quot;, giovaindex, dpcm, substream);
+        }
+
+
+
+        found = 0;
+        for (i = 0; i &lt; giovaindex; i++) {
+
+                if (i &gt; MAX_PCM_SUBSTREAMS || giovaindex &gt; MAX_PCM_SUBSTREAMS) {
+                        printk(&quot;giova, %s:%d, i=%d, giovaindex=%d dpcm=%p\n&quot;, __FILE__, __LINE__, i, giovaindex, dpcm);
+                }
+                if (giovadpcms[i].substream == substream) {
+                        giovadpcms[i].dpcm = dpcm;
+                        giovadpcms[i].started = 0;
+                        found = 1;
+                        //printk(&quot;giova 3 giovaindex=%d dpcm=%p substream=%p\n&quot;, giovaindex, dpcm, substream);
+                        break;
+                }
+
+        }
+
+        spin_unlock_bh(&amp;giovalock);
+        if (!found) {
+                printk(&quot;skypiax giovaindex=%d NOT found????\n&quot;, giovaindex);
+        }
+        //printk(&quot;giova, %s:%d, giovaindex=%d\n&quot;, __FILE__, __LINE__, giovaindex);
+        return dpcm;
+}
+
+static int snd_card_dummy_playback_open(struct snd_pcm_substream *substream)
+{
+        struct snd_pcm_runtime *runtime = substream-&gt;runtime;
+        struct snd_dummy_pcm *dpcm;
+        int err;
+
+        if ((dpcm = new_pcm_stream(substream)) == NULL)
+                return -ENOMEM;
+        //printk(&quot;giova, %s:%d, giovaindex=%d dpcm=%p\n&quot;, __FILE__, __LINE__, giovaindex, dpcm);
+        runtime-&gt;private_data = dpcm;
+        /* makes the infrastructure responsible for freeing dpcm */
+        runtime-&gt;private_free = snd_card_dummy_runtime_free;
+        runtime-&gt;hw = snd_card_dummy_playback;
+        if (substream-&gt;pcm-&gt;device &amp; 1) {
+                runtime-&gt;hw.info &amp;= ~SNDRV_PCM_INFO_INTERLEAVED;
+                runtime-&gt;hw.info |= SNDRV_PCM_INFO_NONINTERLEAVED;
+        }
+        if (substream-&gt;pcm-&gt;device &amp; 2)
+                runtime-&gt;hw.info &amp;= ~(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID);
+        err = add_playback_constraints(runtime);
+        if (err &lt; 0)
+                return err;
+
+        return 0;
+}
+
+static int snd_card_dummy_capture_open(struct snd_pcm_substream *substream)
+{
+        struct snd_pcm_runtime *runtime = substream-&gt;runtime;
+        struct snd_dummy_pcm *dpcm;
+        int err;
+
+        if ((dpcm = new_pcm_stream(substream)) == NULL)
+                return -ENOMEM;
+        //printk(&quot;giova, %s:%d, giovaindex=%d dpcm=%p\n&quot;, __FILE__, __LINE__, giovaindex, dpcm);
+        runtime-&gt;private_data = dpcm;
+        /* makes the infrastructure responsible for freeing dpcm */
+        runtime-&gt;private_free = snd_card_dummy_runtime_free;
+        runtime-&gt;hw = snd_card_dummy_capture;
+        if (substream-&gt;pcm-&gt;device == 1) {
+                runtime-&gt;hw.info &amp;= ~SNDRV_PCM_INFO_INTERLEAVED;
+                runtime-&gt;hw.info |= SNDRV_PCM_INFO_NONINTERLEAVED;
+        }
+        if (substream-&gt;pcm-&gt;device &amp; 2)
+                runtime-&gt;hw.info &amp;= ~(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID);
+        err = add_capture_constraints(runtime);
+        if (err &lt; 0)
+                return err;
+
+        return 0;
+}
+
+static int snd_card_dummy_playback_close(struct snd_pcm_substream *substream)
+{
+//printk(&quot;play giova 1 giovaindex=%d dpcm=%p substream=%p\n&quot;, giovaindex, substream-&gt;private_data, substream);
+        snd_card_dummy_pcm_timer_stop(substream-&gt;private_data);
+        return 0;
+}
+
+static int snd_card_dummy_capture_close(struct snd_pcm_substream *substream)
+{
+//printk(&quot;capt giova 2 giovaindex=%d dpcm=%p substream=%p\n&quot;, giovaindex, substream-&gt;private_data, substream);
+        snd_card_dummy_pcm_timer_stop(substream-&gt;private_data);
+        return 0;
+}
+
+static struct snd_pcm_ops snd_card_dummy_playback_ops = {
+        .open = snd_card_dummy_playback_open,
+        .close = snd_card_dummy_playback_close,
+        .ioctl = snd_pcm_lib_ioctl,
+        .hw_params = snd_card_dummy_hw_params,
+        .hw_free = snd_card_dummy_hw_free,
+        .prepare = snd_card_dummy_pcm_prepare,
+        .trigger = snd_card_dummy_pcm_trigger,
+        .pointer = snd_card_dummy_pcm_pointer,
+};
+
+static struct snd_pcm_ops snd_card_dummy_capture_ops = {
+        .open = snd_card_dummy_capture_open,
+        .close = snd_card_dummy_capture_close,
+        .ioctl = snd_pcm_lib_ioctl,
+        .hw_params = snd_card_dummy_hw_params,
+        .hw_free = snd_card_dummy_hw_free,
+        .prepare = snd_card_dummy_pcm_prepare,
+        .trigger = snd_card_dummy_pcm_trigger,
+        .pointer = snd_card_dummy_pcm_pointer,
+};
+
+static int __devinit snd_card_dummy_pcm(struct snd_dummy *dummy, int device, int substreams)
+{
+        struct snd_pcm *pcm;
+        int err;
+
+        err = snd_pcm_new(dummy-&gt;card, &quot;Dummy PCM&quot;, device, substreams, substreams, &amp;pcm);
+        if (err &lt; 0)
+                return err;
+        dummy-&gt;pcm = pcm;
+        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &amp;snd_card_dummy_playback_ops);
+        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &amp;snd_card_dummy_capture_ops);
+        pcm-&gt;private_data = dummy;
+        pcm-&gt;info_flags = 0;
+        strcpy(pcm-&gt;name, &quot;Dummy PCM&quot;);
+        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, snd_dma_continuous_data(GFP_KERNEL), 128 * 1024, 1024 * 1024);
+
+        return 0;
+}
+
+#define DUMMY_VOLUME(xname, xindex, addr) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+  .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
+  .name = xname, .index = xindex, \
+  .info = snd_dummy_volume_info, \
+  .get = snd_dummy_volume_get, .put = snd_dummy_volume_put, \
+  .private_value = addr, \
+  .tlv = { .p = db_scale_dummy } }
+
+static int snd_dummy_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+{
+        uinfo-&gt;type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+        uinfo-&gt;count = 2;
+        uinfo-&gt;value.integer.min = -50;
+        uinfo-&gt;value.integer.max = 100;
+        return 0;
+}
+
+static int snd_dummy_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+        struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
+        int addr = kcontrol-&gt;private_value;
+        //unsigned long flags;
+
+        if (in_irq())
+                printk(&quot;giova: line %d we are in HARDWARE IRQ\n&quot;, __LINE__);
+//printk(&quot;giova: volume get %d %d\n&quot;, __LINE__, addr);
+        //spin_lock_irq(&amp;dummy-&gt;mixer_lock);
+        //spin_lock_irqsave(&amp;dummy-&gt;mixer_lock, flags);
+        spin_lock_bh(&amp;dummy-&gt;mixer_lock);
+        ucontrol-&gt;value.integer.value[0] = dummy-&gt;mixer_volume[addr][0];
+        ucontrol-&gt;value.integer.value[1] = dummy-&gt;mixer_volume[addr][1];
+        //spin_unlock_irqrestore(&amp;dummy-&gt;mixer_lock, flags);
+        spin_unlock_bh(&amp;dummy-&gt;mixer_lock);
+        return 0;
+}
+
+static int snd_dummy_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+        struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
+        int change, addr = kcontrol-&gt;private_value;
+        int left, right;
+        //unsigned long flags;
+
+        if (in_irq())
+                printk(&quot;giova: line %d we are in HARDWARE IRQ\n&quot;, __LINE__);
+        left = ucontrol-&gt;value.integer.value[0];
+        if (left &lt; -50)
+                left = -50;
+        if (left &gt; 100)
+                left = 100;
+        right = ucontrol-&gt;value.integer.value[1];
+        if (right &lt; -50)
+                right = -50;
+        if (right &gt; 100)
+                right = 100;
+//printk(&quot;giova: volume put %d %d\n&quot;, __LINE__, addr);
+        //spin_lock_irq(&amp;dummy-&gt;mixer_lock);
+        //spin_lock_irqsave(&amp;dummy-&gt;mixer_lock, flags);
+        spin_lock_bh(&amp;dummy-&gt;mixer_lock);
+        change = dummy-&gt;mixer_volume[addr][0] != left || dummy-&gt;mixer_volume[addr][1] != right;
+        dummy-&gt;mixer_volume[addr][0] = left;
+        dummy-&gt;mixer_volume[addr][1] = right;
+        //spin_unlock_irq(&amp;dummy-&gt;mixer_lock);
+        //spin_unlock_irqrestore(&amp;dummy-&gt;mixer_lock, flags);
+        spin_unlock_bh(&amp;dummy-&gt;mixer_lock);
+        return change;
+}
+
+static const DECLARE_TLV_DB_SCALE(db_scale_dummy, -4500, 30, 0);
+
+#define DUMMY_CAPSRC(xname, xindex, addr) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
+  .info = snd_dummy_capsrc_info, \
+  .get = snd_dummy_capsrc_get, .put = snd_dummy_capsrc_put, \
+  .private_value = addr }
+
+#define snd_dummy_capsrc_info        snd_ctl_boolean_stereo_info
+
+static int snd_dummy_capsrc_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+        struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
+        int addr = kcontrol-&gt;private_value;
+        //unsigned long flags;
+
+        if (in_irq())
+                printk(&quot;giova: line %d we are in HARDWARE IRQ\n&quot;, __LINE__);
+        //spin_lock_irq(&amp;dummy-&gt;mixer_lock);
+        //spin_lock_irqsave(&amp;dummy-&gt;mixer_lock, flags);
+        spin_lock_bh(&amp;dummy-&gt;mixer_lock);
+        ucontrol-&gt;value.integer.value[0] = dummy-&gt;capture_source[addr][0];
+        ucontrol-&gt;value.integer.value[1] = dummy-&gt;capture_source[addr][1];
+        //spin_unlock_irq(&amp;dummy-&gt;mixer_lock);
+        //spin_unlock_irqrestore(&amp;dummy-&gt;mixer_lock, flags);
+        spin_unlock_bh(&amp;dummy-&gt;mixer_lock);
+//printk(&quot;giova: capsrc_get %d %d\n&quot;, __LINE__, addr);
+        return 0;
+}
+
+static int snd_dummy_capsrc_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+        struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
+        int change, addr = kcontrol-&gt;private_value;
+        int left, right;
+        //unsigned long flags;
+
+        if (in_irq())
+                printk(&quot;giova: line %d we are in HARDWARE IRQ\n&quot;, __LINE__);
+        left = ucontrol-&gt;value.integer.value[0] &amp; 1;
+        right = ucontrol-&gt;value.integer.value[1] &amp; 1;
+        //spin_lock_irq(&amp;dummy-&gt;mixer_lock);
+        //spin_lock_irqsave(&amp;dummy-&gt;mixer_lock, flags);
+        spin_lock_bh(&amp;dummy-&gt;mixer_lock);
+        change = dummy-&gt;capture_source[addr][0] != left &amp;&amp; dummy-&gt;capture_source[addr][1] != right;
+        dummy-&gt;capture_source[addr][0] = left;
+        dummy-&gt;capture_source[addr][1] = right;
+        //spin_unlock_irq(&amp;dummy-&gt;mixer_lock);
+        //spin_unlock_irqrestore(&amp;dummy-&gt;mixer_lock, flags);
+        spin_unlock_bh(&amp;dummy-&gt;mixer_lock);
+//printk(&quot;giova: capsrc_put %d %d\n&quot;, __LINE__, addr);
+        return change;
+}
+
+static struct snd_kcontrol_new snd_dummy_controls[] = {
+        DUMMY_VOLUME(&quot;Master Volume&quot;, 0, MIXER_ADDR_MASTER),
+        DUMMY_CAPSRC(&quot;Master Capture Switch&quot;, 0, MIXER_ADDR_MASTER),
+        DUMMY_VOLUME(&quot;Synth Volume&quot;, 0, MIXER_ADDR_SYNTH),
+        DUMMY_CAPSRC(&quot;Synth Capture Switch&quot;, 0, MIXER_ADDR_SYNTH),
+        DUMMY_VOLUME(&quot;Line Volume&quot;, 0, MIXER_ADDR_LINE),
+        DUMMY_CAPSRC(&quot;Line Capture Switch&quot;, 0, MIXER_ADDR_LINE),
+        DUMMY_VOLUME(&quot;Mic Volume&quot;, 0, MIXER_ADDR_MIC),
+        DUMMY_CAPSRC(&quot;Mic Capture Switch&quot;, 0, MIXER_ADDR_MIC),
+        DUMMY_VOLUME(&quot;CD Volume&quot;, 0, MIXER_ADDR_CD),
+        DUMMY_CAPSRC(&quot;CD Capture Switch&quot;, 0, MIXER_ADDR_CD)
+};
+
+static int __devinit snd_card_dummy_new_mixer(struct snd_dummy *dummy)
+{
+        struct snd_card *card = dummy-&gt;card;
+        unsigned int idx;
+        int err;
+
+        //giova if (snd_BUG_ON(!dummy))
+        //giova return -EINVAL;
+        spin_lock_init(&amp;dummy-&gt;mixer_lock);
+        strcpy(card-&gt;mixername, &quot;Dummy Mixer&quot;);
+//printk(&quot;giova: new_mixer %d\n&quot;, __LINE__);
+        return 0;                                        //giova no mixer
+
+        for (idx = 0; idx &lt; ARRAY_SIZE(snd_dummy_controls); idx++) {
+                err = snd_ctl_add(card, snd_ctl_new1(&amp;snd_dummy_controls[idx], dummy));
+                if (err &lt; 0)
+                        return err;
+        }
+        return 0;
+}
+
+static int __devinit snd_dummy_probe(struct platform_device *devptr)
+{
+        struct snd_card *card;
+        struct snd_dummy *dummy;
+        int idx, err;
+        int dev = devptr-&gt;id;
+
+        card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(struct snd_dummy));
+        if (card == NULL)
+                return -ENOMEM;
+
+        //giova err = snd_card_create(index[dev], id[dev], THIS_MODULE,
+        //giova sizeof(struct snd_dummy), &amp;card);
+        //giova if (err &lt; 0)
+        //giova return err;
+        dummy = card-&gt;private_data;
+        dummy-&gt;card = card;
+        for (idx = 0; idx &lt; MAX_PCM_DEVICES &amp;&amp; idx &lt; pcm_devs[dev]; idx++) {
+                if (pcm_substreams[dev] &lt; 1)
+                        pcm_substreams[dev] = 1;
+                if (pcm_substreams[dev] &gt; MAX_PCM_SUBSTREAMS)
+                        pcm_substreams[dev] = MAX_PCM_SUBSTREAMS;
+                err = snd_card_dummy_pcm(dummy, idx, pcm_substreams[dev]);
+                if (err &lt; 0)
+                        goto __nodev;
+        }
+        err = snd_card_dummy_new_mixer(dummy);
+        if (err &lt; 0)
+                goto __nodev;
+        strcpy(card-&gt;driver, &quot;Dummy&quot;);
+        strcpy(card-&gt;shortname, &quot;Dummy&quot;);
+        sprintf(card-&gt;longname, &quot;Dummy %i&quot;, dev + 1);
+
+        snd_card_set_dev(card, &amp;devptr-&gt;dev);
+
+        err = snd_card_register(card);
+        if (err == 0) {
+                platform_set_drvdata(devptr, card);
+                return 0;
+        }
+  __nodev:
+        snd_card_free(card);
+        return err;
+}
+
+static int __devexit snd_dummy_remove(struct platform_device *devptr)
+{
+
+        del_timer(&amp;giovatimer);
+        snd_card_free(platform_get_drvdata(devptr));
+        platform_set_drvdata(devptr, NULL);
+        return 0;
+}
+
+#ifdef CONFIG_PM
+static int snd_dummy_suspend(struct platform_device *pdev, pm_message_t state)
+{
+        struct snd_card *card = platform_get_drvdata(pdev);
+        struct snd_dummy *dummy = card-&gt;private_data;
+
+        snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+        snd_pcm_suspend_all(dummy-&gt;pcm);
+        return 0;
+}
+
+static int snd_dummy_resume(struct platform_device *pdev)
+{
+        struct snd_card *card = platform_get_drvdata(pdev);
+
+        snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+        return 0;
+}
+#endif
+
+#define SND_DUMMY_DRIVER        &quot;snd_dummy&quot;
+
+static struct platform_driver snd_dummy_driver = {
+        .probe = snd_dummy_probe,
+        .remove = __devexit_p(snd_dummy_remove),
+#ifdef CONFIG_PM
+        .suspend = snd_dummy_suspend,
+        .resume = snd_dummy_resume,
+#endif
+        .driver = {
+                           .name = SND_DUMMY_DRIVER},
+};
+
+static void snd_dummy_unregister_all(void)
+{
+        int i;
+
+        for (i = 0; i &lt; ARRAY_SIZE(devices); ++i)
+                platform_device_unregister(devices[i]);
+        platform_driver_unregister(&amp;snd_dummy_driver);
+}
+
+static int __init alsa_card_dummy_init(void)
+{
+        int i, cards, err;
+
+        err = platform_driver_register(&amp;snd_dummy_driver);
+        if (err &lt; 0)
+                return err;
+
+        if (!giovastarted) {
+                giovastarted = 1;
+                spin_lock_init(&amp;giovalock);
+
+                spin_lock_bh(&amp;giovalock);
+                for (i = 0; i &lt; MAX_PCM_SUBSTREAMS; i++) {
+
+                        if (i &gt; MAX_PCM_SUBSTREAMS || giovaindex &gt; MAX_PCM_SUBSTREAMS) {
+                                printk(&quot;giova, %s:%d, i=%d, giovaindex=%d \n&quot;, __FILE__, __LINE__, i, giovaindex);
+                        }
+                        giovadpcms[i].substream = NULL;
+                        giovadpcms[i].dpcm = NULL;
+                        giovadpcms[i].started = 0;
+                }
+                init_timer(&amp;giovatimer);
+                //giovatimer.data = (unsigned long) dpcm;
+                giovatimer.data = (unsigned long) &amp;giovadpcms;
+                giovatimer.function = snd_card_dummy_pcm_timer_function;
+                giovatimer.expires = ((HZ / 1000) *GIOVAMULTI)+ jiffies;
+                add_timer(&amp;giovatimer);
+                printk(&quot;003 snd-dummy skypiax driver, %s:%d working on a machine with %dHZ kernel\n&quot;, __FILE__, __LINE__, HZ);
+                spin_unlock_bh(&amp;giovalock);
+        }
+
+
+        cards = 0;
+        for (i = 0; i &lt; SNDRV_CARDS; i++) {
+                struct platform_device *device;
+                if (!enable[i])
+                        continue;
+                device = platform_device_register_simple(SND_DUMMY_DRIVER, i, NULL, 0);
+                if (IS_ERR(device))
+                        continue;
+                if (!platform_get_drvdata(device)) {
+                        platform_device_unregister(device);
+                        continue;
+                }
+                devices[i] = device;
+                cards++;
+        }
+        if (!cards) {
+#ifdef MODULE
+                printk(KERN_ERR &quot;Dummy soundcard not found or device busy\n&quot;);
+#endif
+                snd_dummy_unregister_all();
+                return -ENODEV;
+        }
+        return 0;
+}
+
+static void __exit alsa_card_dummy_exit(void)
+{
+        del_timer(&amp;giovatimer);
+        snd_dummy_unregister_all();
+}
+
+module_init(alsa_card_dummy_init)
+        module_exit(alsa_card_dummy_exit)
</ins></span></pre></div>
<a id="freeswitchtrunksrcmodendpointsmod_skypiax103mod_skypiaxc"></a>
<div class="addfile"><h4>Added: freeswitch/trunk/src/mod/endpoints/mod_skypiax/103/mod_skypiax.c (0 => 16632)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/src/mod/endpoints/mod_skypiax/103/mod_skypiax.c                                (rev 0)
+++ freeswitch/trunk/src/mod/endpoints/mod_skypiax/103/mod_skypiax.c        2010-02-13 11:10:30 UTC (rev 16632)
</span><span class="lines">@@ -0,0 +1,2579 @@
</span><ins>+/*
+ * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ * Copyright (C) 2005/2006, Anthony Minessale II &lt;anthmct@yahoo.com&gt;
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the &quot;License&quot;); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an &quot;AS IS&quot; basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ *
+ * The Initial Developer of the Original Code is
+ * Anthony Minessale II &lt;anthmct@yahoo.com&gt;
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * This module (mod_skypiax) has been contributed by:
+ *
+ * Giovanni Maruzzelli (gmaruzz@gmail.com)
+ *
+ *
+ * Further Contributors:
+ *
+ *
+ *
+ * mod_skypiax.c -- Skype compatible Endpoint Module
+ *
+ */
+
+#include &quot;skypiax.h&quot;
+#define MDL_CHAT_PROTO &quot;skype&quot;
+#define TIMERS_ON
+#ifdef TIMERS_ON
+#undef TIMER_WRITE
+#else
+#undef TIMER_WRITE
+#endif
+
+#ifdef WIN32
+/***************/
+// from http://www.openasthra.com/c-tidbits/gettimeofday-function-for-windows/
+
+#include &lt;time.h&gt;
+
+#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
+#define DELTA_EPOCH_IN_MICROSECS  11644473600000000Ui64
+#else /*  */
+#define DELTA_EPOCH_IN_MICROSECS  11644473600000000ULL
+#endif /*  */
+struct sk_timezone {
+        int tz_minuteswest;                        /* minutes W of Greenwich */
+        int tz_dsttime;                                /* type of dst correction */
+};
+int gettimeofday(struct timeval *tv, struct sk_timezone *tz)
+{
+        FILETIME ft;
+        unsigned __int64 tmpres = 0;
+        static int tzflag;
+        if (NULL != tv) {
+                GetSystemTimeAsFileTime(&amp;ft);
+                tmpres |= ft.dwHighDateTime;
+                tmpres &lt;&lt;= 32;
+                tmpres |= ft.dwLowDateTime;
+
+                /*converting file time to unix epoch */
+                tmpres /= 10;                        /*convert into microseconds */
+                tmpres -= DELTA_EPOCH_IN_MICROSECS;
+                tv-&gt;tv_sec = (long) (tmpres / 1000000UL);
+                tv-&gt;tv_usec = (long) (tmpres % 1000000UL);
+        }
+        if (NULL != tz) {
+                if (!tzflag) {
+                        _tzset();
+                        tzflag++;
+                }
+                tz-&gt;tz_minuteswest = _timezone / 60;
+                tz-&gt;tz_dsttime = _daylight;
+        }
+        return 0;
+}
+
+/***************/
+#endif /* WIN32 */
+SWITCH_MODULE_LOAD_FUNCTION(mod_skypiax_load);
+SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_skypiax_shutdown);
+SWITCH_MODULE_DEFINITION(mod_skypiax, mod_skypiax_load, mod_skypiax_shutdown, NULL);
+SWITCH_STANDARD_API(sk_function);
+/* BEGIN: Changes here */
+#define SK_SYNTAX &quot;list [full] || console || skype_API_msg || remove &lt; skypeusername | #interface_name | #interface_id &gt; || reload&quot;
+/* END: Changes heres */
+SWITCH_STANDARD_API(skypiax_function);
+#define SKYPIAX_SYNTAX &quot;interface_name skype_API_msg&quot;
+
+SWITCH_STANDARD_API(skypiax_chat_function);
+#define SKYPIAX_CHAT_SYNTAX &quot;interface_name remote_skypename TEXT&quot;
+/* BEGIN: Changes here */
+#define FULL_RELOAD 0
+#define SOFT_RELOAD 1
+/* END: Changes heres */
+
+char *interface_status[] = {        /* should match SKYPIAX_STATE_xxx in skypiax.h */
+        &quot;IDLE&quot;,
+        &quot;DOWN&quot;,
+        &quot;RING&quot;,
+        &quot;DIALING&quot;,
+        &quot;BUSY&quot;,
+        &quot;UP&quot;,
+        &quot;RINGING&quot;,
+        &quot;PRERING&quot;,
+        &quot;DOUBLE&quot;,
+        &quot;SELECTD&quot;,
+        &quot;HANG_RQ&quot;,
+        &quot;PREANSW&quot;
+};
+char *skype_callflow[] = {                /* should match CALLFLOW_XXX in skypiax.h */
+        &quot;CALL_IDLE&quot;,
+        &quot;CALL_DOWN&quot;,
+        &quot;INCOMING_RNG&quot;,
+        &quot;CALL_DIALING&quot;,
+        &quot;CALL_LINEBUSY&quot;,
+        &quot;CALL_ACTIVE&quot;,
+        &quot;INCOMING_HNG&quot;,
+        &quot;CALL_RLEASD&quot;,
+        &quot;CALL_NOCARR&quot;,
+        &quot;CALL_INFLUX&quot;,
+        &quot;CALL_INCOMING&quot;,
+        &quot;CALL_FAILED&quot;,
+        &quot;CALL_NOSRVC&quot;,
+        &quot;CALL_OUTRESTR&quot;,
+        &quot;CALL_SECFAIL&quot;,
+        &quot;CALL_NOANSWER&quot;,
+        &quot;STATUS_FNSHED&quot;,
+        &quot;STATUS_CANCLED&quot;,
+        &quot;STATUS_FAILED&quot;,
+        &quot;STATUS_REFUSED&quot;,
+        &quot;STATUS_RINGING&quot;,
+        &quot;STATUS_INPROGRS&quot;,
+        &quot;STATUS_UNPLACD&quot;,
+        &quot;STATUS_ROUTING&quot;,
+        &quot;STATUS_EARLYMD&quot;,
+        &quot;INCOMING_CLID&quot;,
+        &quot;STATUS_RMTEHOLD&quot;
+};
+
+
+static struct {
+        int debug;
+        char *ip;
+        int port;
+        char *dialplan;
+        char *destination;
+        char *context;
+        char *codec_string;
+        char *codec_order[SWITCH_MAX_CODECS];
+        int codec_order_last;
+        char *codec_rates_string;
+        char *codec_rates[SWITCH_MAX_CODECS];
+        int codec_rates_last;
+        unsigned int flags;
+        int fd;
+        int calls;
+        int real_interfaces;
+        int next_interface;
+        char hold_music[256];
+        private_t SKYPIAX_INTERFACES[SKYPIAX_MAX_INTERFACES];
+        switch_mutex_t *mutex;
+        private_t *sk_console;
+} globals;
+
+switch_endpoint_interface_t *skypiax_endpoint_interface;
+switch_memory_pool_t *skypiax_module_pool = NULL;
+int running = 0;
+
+SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_dialplan, globals.dialplan);
+SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_context, globals.context);
+SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_destination, globals.destination);
+SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_codec_string, globals.codec_string);
+SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_codec_rates_string, globals.codec_rates_string);
+
+/* BEGIN: Changes here */
+static switch_status_t interface_exists(char *the_interface);
+static switch_status_t remove_interface(char *the_interface);
+/* END: Changes here */
+
+static switch_status_t channel_on_init(switch_core_session_t *session);
+static switch_status_t channel_on_hangup(switch_core_session_t *session);
+static switch_status_t channel_on_destroy(switch_core_session_t *session);
+static switch_status_t channel_on_routing(switch_core_session_t *session);
+static switch_status_t channel_on_exchange_media(switch_core_session_t *session);
+static switch_status_t channel_on_consume_media(switch_core_session_t *session);
+static switch_status_t channel_on_soft_execute(switch_core_session_t *session);
+static switch_call_cause_t channel_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,
+                                                                                                        switch_call_cause_t *cancel_cause);
+static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id);
+static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
+static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig);
+static switch_status_t skypiax_tech_init(private_t * tech_pvt, switch_core_session_t *session);
+
+static switch_status_t skypiax_codec(private_t * tech_pvt, int sample_rate, int codec_ms)
+{
+        switch_core_session_t *session = NULL;
+
+        if (switch_core_codec_init
+                (&amp;tech_pvt-&gt;read_codec, &quot;L16&quot;, NULL, sample_rate, codec_ms, 1,
+                 SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, NULL) != SWITCH_STATUS_SUCCESS) {
+                ERRORA(&quot;Can't load codec?\n&quot;, SKYPIAX_P_LOG);
+                return SWITCH_STATUS_FALSE;
+        }
+
+        if (switch_core_codec_init
+                (&amp;tech_pvt-&gt;write_codec, &quot;L16&quot;, NULL, sample_rate, codec_ms, 1,
+                 SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, NULL) != SWITCH_STATUS_SUCCESS) {
+                ERRORA(&quot;Can't load codec?\n&quot;, SKYPIAX_P_LOG);
+                switch_core_codec_destroy(&amp;tech_pvt-&gt;read_codec);
+                return SWITCH_STATUS_FALSE;
+        }
+
+        tech_pvt-&gt;read_frame.rate = sample_rate;
+        tech_pvt-&gt;read_frame.codec = &amp;tech_pvt-&gt;read_codec;
+
+        session = switch_core_session_locate(tech_pvt-&gt;session_uuid_str);
+
+        if (session) {
+                switch_core_session_set_read_codec(session, &amp;tech_pvt-&gt;read_codec);
+                switch_core_session_set_write_codec(session, &amp;tech_pvt-&gt;write_codec);
+                switch_core_session_rwunlock(session);
+        } else {
+                ERRORA(&quot;no session\n&quot;, SKYPIAX_P_LOG);
+                return SWITCH_STATUS_FALSE;
+        }
+
+        return SWITCH_STATUS_SUCCESS;
+
+}
+
+switch_status_t skypiax_tech_init(private_t * tech_pvt, switch_core_session_t *session)
+{
+
+        switch_assert(tech_pvt != NULL);
+        switch_assert(session != NULL);
+        tech_pvt-&gt;read_frame.data = tech_pvt-&gt;databuf;
+        tech_pvt-&gt;read_frame.buflen = sizeof(tech_pvt-&gt;databuf);
+        switch_mutex_init(&amp;tech_pvt-&gt;mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
+        switch_mutex_init(&amp;tech_pvt-&gt;flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
+        switch_core_session_set_private(session, tech_pvt);
+        switch_copy_string(tech_pvt-&gt;session_uuid_str, switch_core_session_get_uuid(session), sizeof(tech_pvt-&gt;session_uuid_str));
+        if (!strlen(tech_pvt-&gt;session_uuid_str)) {
+                ERRORA(&quot;no tech_pvt-&gt;session_uuid_str\n&quot;, SKYPIAX_P_LOG);
+                return SWITCH_STATUS_FALSE;
+        }
+        if (skypiax_codec(tech_pvt, SAMPLERATE_SKYPIAX, 20) != SWITCH_STATUS_SUCCESS) {
+                ERRORA(&quot;skypiax_codec FAILED\n&quot;, SKYPIAX_P_LOG);
+                return SWITCH_STATUS_FALSE;
+        }
+
+#ifdef TIMERS_ON
+        if (switch_core_timer_init(&amp;tech_pvt-&gt;timer_read, &quot;soft&quot;, 20, tech_pvt-&gt;read_codec.implementation-&gt;samples_per_packet, skypiax_module_pool) !=
+                SWITCH_STATUS_SUCCESS) {
+                ERRORA(&quot;setup timer failed\n&quot;, SKYPIAX_P_LOG);
+                return SWITCH_STATUS_FALSE;
+        }
+
+        switch_core_timer_sync(&amp;tech_pvt-&gt;timer_read);
+#endif// TIMERS_ON
+
+#ifdef TIMER_WRITE
+        if (switch_core_timer_init(&amp;tech_pvt-&gt;timer_write, &quot;soft&quot;, 20, tech_pvt-&gt;write_codec.implementation-&gt;samples_per_packet, skypiax_module_pool) !=
+                SWITCH_STATUS_SUCCESS) {
+                ERRORA(&quot;setup timer failed\n&quot;, SKYPIAX_P_LOG);
+                return SWITCH_STATUS_FALSE;
+        }
+
+        switch_core_timer_sync(&amp;tech_pvt-&gt;timer_write);
+#endif // TIMER_WRITE
+
+        DEBUGA_SKYPE(&quot;skypiax_tech_init SUCCESS\n&quot;, SKYPIAX_P_LOG);
+        return SWITCH_STATUS_SUCCESS;
+}
+
+/* BEGIN: Changes here */
+static switch_status_t interface_exists(char *the_interface)
+{
+        int i;
+        int interface_id;
+
+        if (*the_interface == '#') {        /* look by interface id or interface name */
+                the_interface++;
+                switch_assert(the_interface);
+                interface_id = atoi(the_interface);
+
+                /* take a number as interface id */
+                if (interface_id &gt; 0 || (interface_id == 0 &amp;&amp; strcmp(the_interface, &quot;0&quot;) == 0)) {
+                        if (strlen(globals.SKYPIAX_INTERFACES[interface_id].name)) {
+                                return SWITCH_STATUS_SUCCESS;
+                        }
+                } else {
+                        /* interface name */
+                        for (interface_id = 0; interface_id &lt; SKYPIAX_MAX_INTERFACES; interface_id++) {
+                                if (strcmp(globals.SKYPIAX_INTERFACES[interface_id].name, the_interface) == 0) {
+                                        return SWITCH_STATUS_SUCCESS;
+                                        break;
+                                }
+                        }
+                }
+        } else {                                        /* look by skype_user */
+
+
+                for (i = 0; i &lt; SKYPIAX_MAX_INTERFACES; i++) {
+                        if (strlen(globals.SKYPIAX_INTERFACES[i].skype_user)) {
+                                if (strcmp(globals.SKYPIAX_INTERFACES[i].skype_user, the_interface) == 0) {
+                                        return SWITCH_STATUS_SUCCESS;
+                                }
+                        }
+                }
+        }
+        return SWITCH_STATUS_FALSE;
+}
+
+static switch_status_t remove_interface(char *the_interface)
+{
+        int x = 10;
+        unsigned int howmany = 8;
+        int interface_id = -1;
+        private_t *tech_pvt = NULL;
+        switch_status_t status;
+
+        //running = 0;
+
+
+        if (*the_interface == '#') {        /* remove by interface id or interface name */
+                the_interface++;
+                switch_assert(the_interface);
+                interface_id = atoi(the_interface);
+
+                if (interface_id &gt; 0 || (interface_id == 0 &amp;&amp; strcmp(the_interface, &quot;0&quot;) == 0)) {
+                        /* take a number as interface id */
+                        tech_pvt = &amp;globals.SKYPIAX_INTERFACES[interface_id];
+                } else {
+
+                        for (interface_id = 0; interface_id &lt; SKYPIAX_MAX_INTERFACES; interface_id++) {
+                                if (strcmp(globals.SKYPIAX_INTERFACES[interface_id].name, the_interface) == 0) {
+                                        tech_pvt = &amp;globals.SKYPIAX_INTERFACES[interface_id];
+                                        break;
+                                }
+                        }
+                }
+        } else {                                        /* remove by skype_user */
+                for (interface_id = 0; interface_id &lt; SKYPIAX_MAX_INTERFACES; interface_id++) {
+                        if (strcmp(globals.SKYPIAX_INTERFACES[interface_id].skype_user, the_interface) == 0) {
+                                tech_pvt = &amp;globals.SKYPIAX_INTERFACES[interface_id];
+                                break;
+                        }
+                }
+        }
+
+        if (!tech_pvt) {
+                DEBUGA_SKYPE(&quot;interface '%s' does not exist\n&quot;, SKYPIAX_P_LOG, the_interface);
+                goto end;
+        }
+
+        if (strlen(globals.SKYPIAX_INTERFACES[interface_id].session_uuid_str)) {
+                DEBUGA_SKYPE(&quot;interface '%s' is busy\n&quot;, SKYPIAX_P_LOG, the_interface);
+                goto end;
+        }
+
+        globals.SKYPIAX_INTERFACES[interface_id].running = 0;
+
+        if (globals.SKYPIAX_INTERFACES[interface_id].skypiax_signaling_thread) {
+#ifdef WIN32
+                switch_file_write(tech_pvt-&gt;SkypiaxHandles.fdesc[1], &quot;sciutati&quot;, &amp;howmany);        // let's the controldev_thread die
+#else /* WIN32 */
+                howmany = write(tech_pvt-&gt;SkypiaxHandles.fdesc[1], &quot;sciutati&quot;, howmany);
+#endif /* WIN32 */
+        }
+
+        if (globals.SKYPIAX_INTERFACES[interface_id].skypiax_api_thread) {
+#ifdef WIN32
+                if (SendMessage(tech_pvt-&gt;SkypiaxHandles.win32_hInit_MainWindowHandle, WM_DESTROY, 0, 0) == FALSE) {        // let's the skypiax_api_thread_func die
+                        DEBUGA_SKYPE(&quot;got FALSE here, thread probably was already dead. GetLastError returned: %d\n&quot;, SKYPIAX_P_LOG, GetLastError());
+                        globals.SKYPIAX_INTERFACES[interface_id].skypiax_api_thread = NULL;
+                }
+#else
+                if (tech_pvt-&gt;running &amp;&amp; tech_pvt-&gt;SkypiaxHandles.disp) {
+                        XEvent e;
+                        Atom atom1 = XInternAtom(tech_pvt-&gt;SkypiaxHandles.disp, &quot;SKYPECONTROLAPI_MESSAGE_BEGIN&quot;, False);
+                        memset(&amp;e, 0, sizeof(e));
+                        e.xclient.type = ClientMessage;
+                        e.xclient.message_type = atom1;        /*  leading message */
+                        e.xclient.display = tech_pvt-&gt;SkypiaxHandles.disp;
+                        e.xclient.window = tech_pvt-&gt;SkypiaxHandles.skype_win;
+                        e.xclient.format = 8;
+
+                        XSendEvent(tech_pvt-&gt;SkypiaxHandles.disp, tech_pvt-&gt;SkypiaxHandles.win, False, 0, &amp;e);
+                        XSync(tech_pvt-&gt;SkypiaxHandles.disp, False);
+                }
+#endif
+        }
+
+        while (x) {
+                x--;
+                switch_yield(50000);
+        }
+
+        if (globals.SKYPIAX_INTERFACES[interface_id].skypiax_signaling_thread) {
+                switch_thread_join(&amp;status, globals.SKYPIAX_INTERFACES[interface_id].skypiax_signaling_thread);
+        }
+
+        if (globals.SKYPIAX_INTERFACES[interface_id].skypiax_api_thread) {
+                switch_thread_join(&amp;status, globals.SKYPIAX_INTERFACES[interface_id].skypiax_api_thread);
+        }
+
+        switch_mutex_lock(globals.mutex);
+        if (globals.sk_console == &amp;globals.SKYPIAX_INTERFACES[interface_id]) {
+                DEBUGA_SKYPE(&quot;interface '%s' no more console\n&quot;, SKYPIAX_P_LOG, the_interface);
+                globals.sk_console = NULL;
+        } else {
+                DEBUGA_SKYPE(&quot;interface '%s' STILL console\n&quot;, SKYPIAX_P_LOG, the_interface);
+        }
+        memset(&amp;globals.SKYPIAX_INTERFACES[interface_id], '\0', sizeof(private_t));
+        globals.real_interfaces--;
+        switch_mutex_unlock(globals.mutex);
+
+        DEBUGA_SKYPE(&quot;interface '%s' deleted successfully\n&quot;, SKYPIAX_P_LOG, the_interface);
+        globals.SKYPIAX_INTERFACES[interface_id].running = 1;
+  end:
+        //running = 1;
+        return SWITCH_STATUS_SUCCESS;
+}
+
+/* END: Changes here */
+
+/* 
+   State methods they get called when the state changes to the specific state 
+   returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next
+   so if you fully implement the state you can return SWITCH_STATUS_FALSE to skip it.
+*/
+static switch_status_t channel_on_init(switch_core_session_t *session)
+{
+        switch_channel_t *channel;
+        private_t *tech_pvt = NULL;
+
+        tech_pvt = switch_core_session_get_private(session);
+        switch_assert(tech_pvt != NULL);
+
+        channel = switch_core_session_get_channel(session);
+        switch_assert(channel != NULL);
+        //ERRORA(&quot;%s CHANNEL INIT\n&quot;, SKYPIAX_P_LOG, tech_pvt-&gt;name);
+        switch_set_flag(tech_pvt, TFLAG_IO);
+
+        /* Move channel's state machine to ROUTING. This means the call is trying
+           to get from the initial start where the call because, to the point
+           where a destination has been identified. If the channel is simply
+           left in the initial state, nothing will happen. */
+        switch_channel_set_state(channel, CS_ROUTING);
+        switch_mutex_lock(globals.mutex);
+        globals.calls++;
+
+        switch_mutex_unlock(globals.mutex);
+        DEBUGA_SKYPE(&quot;%s CHANNEL INIT %s\n&quot;, SKYPIAX_P_LOG, tech_pvt-&gt;name, switch_core_session_get_uuid(session));
+
+        return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t channel_on_destroy(switch_core_session_t *session)
+{
+        private_t *tech_pvt = NULL;
+
+        tech_pvt = switch_core_session_get_private(session);
+
+
+        if (tech_pvt) {
+                DEBUGA_SKYPE(&quot;%s CHANNEL DESTROY %s\n&quot;, SKYPIAX_P_LOG, tech_pvt-&gt;name, switch_core_session_get_uuid(session));
+
+                if (switch_core_codec_ready(&amp;tech_pvt-&gt;read_codec)) {
+                        switch_core_codec_destroy(&amp;tech_pvt-&gt;read_codec);
+                }
+
+                if (switch_core_codec_ready(&amp;tech_pvt-&gt;write_codec)) {
+                        switch_core_codec_destroy(&amp;tech_pvt-&gt;write_codec);
+                }
+
+#ifdef TIMERS_ON
+                switch_core_timer_destroy(&amp;tech_pvt-&gt;timer_read);
+#endif// TIMERS_ON
+#ifdef TIMER_WRITE
+
+                switch_core_timer_destroy(&amp;tech_pvt-&gt;timer_write);
+#endif // TIMER_WRITE
+
+
+                *tech_pvt-&gt;session_uuid_str = '\0';
+                tech_pvt-&gt;interface_state = SKYPIAX_STATE_IDLE;
+                if (tech_pvt-&gt;skype_callflow == CALLFLOW_STATUS_FINISHED) {
+                        tech_pvt-&gt;skype_callflow = CALLFLOW_CALL_IDLE;
+                }
+                switch_core_session_set_private(session, NULL);
+        } else {
+                DEBUGA_SKYPE(&quot;!!!!!!NO tech_pvt!!!! CHANNEL DESTROY %s\n&quot;, SKYPIAX_P_LOG, switch_core_session_get_uuid(session));
+        }
+
+        return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t channel_on_hangup(switch_core_session_t *session)
+{
+        switch_channel_t *channel = NULL;
+        private_t *tech_pvt = NULL;
+        char msg_to_skype[256];
+
+
+        channel = switch_core_session_get_channel(session);
+        switch_assert(channel != NULL);
+
+        tech_pvt = switch_core_session_get_private(session);
+        switch_assert(tech_pvt != NULL);
+
+        if (!switch_channel_test_flag(channel, CF_ANSWERED)) {
+                if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
+                        tech_pvt-&gt;ob_failed_calls++;
+                } else {
+                        tech_pvt-&gt;ib_failed_calls++;
+                }
+        }
+
+        switch_clear_flag(tech_pvt, TFLAG_IO);
+        switch_clear_flag(tech_pvt, TFLAG_VOICE);
+        //switch_set_flag(tech_pvt, TFLAG_HANGUP);
+
+        if (strlen(tech_pvt-&gt;skype_call_id)) {
+                //switch_thread_cond_signal(tech_pvt-&gt;cond);
+                DEBUGA_SKYPE(&quot;hanging up skype call: %s\n&quot;, SKYPIAX_P_LOG, tech_pvt-&gt;skype_call_id);
+                sprintf(msg_to_skype, &quot;ALTER CALL %s HANGUP&quot;, tech_pvt-&gt;skype_call_id);
+                skypiax_signaling_write(tech_pvt, msg_to_skype);
+        }
+        //memset(tech_pvt-&gt;session_uuid_str, '\0', sizeof(tech_pvt-&gt;session_uuid_str));
+        //*tech_pvt-&gt;session_uuid_str = '\0';
+        DEBUGA_SKYPE(&quot;%s CHANNEL HANGUP\n&quot;, SKYPIAX_P_LOG, tech_pvt-&gt;name);
+        switch_mutex_lock(globals.mutex);
+        globals.calls--;
+        if (globals.calls &lt; 0) {
+                globals.calls = 0;
+        }
+
+        tech_pvt-&gt;interface_state = SKYPIAX_STATE_IDLE;
+        if (tech_pvt-&gt;skype_callflow == CALLFLOW_STATUS_FINISHED) {
+                tech_pvt-&gt;skype_callflow = CALLFLOW_CALL_IDLE;
+        }
+        switch_mutex_unlock(globals.mutex);
+
+        return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t channel_on_routing(switch_core_session_t *session)
+{
+        switch_channel_t *channel = NULL;
+        private_t *tech_pvt = NULL;
+
+        channel = switch_core_session_get_channel(session);
+        switch_assert(channel != NULL);
+
+        tech_pvt = switch_core_session_get_private(session);
+        switch_assert(tech_pvt != NULL);
+
+        DEBUGA_SKYPE(&quot;%s CHANNEL ROUTING\n&quot;, SKYPIAX_P_LOG, tech_pvt-&gt;name);
+
+        return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t channel_on_execute(switch_core_session_t *session)
+{
+
+        switch_channel_t *channel = NULL;
+        private_t *tech_pvt = NULL;
+
+        channel = switch_core_session_get_channel(session);
+        switch_assert(channel != NULL);
+
+        tech_pvt = switch_core_session_get_private(session);
+        switch_assert(tech_pvt != NULL);
+
+        DEBUGA_SKYPE(&quot;%s CHANNEL EXECUTE\n&quot;, SKYPIAX_P_LOG, tech_pvt-&gt;name);
+
+        return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig)
+{
+        switch_channel_t *channel = NULL;
+        private_t *tech_pvt = NULL;
+
+        channel = switch_core_session_get_channel(session);
+        switch_assert(channel != NULL);
+
+        tech_pvt = switch_core_session_get_private(session);
+        switch_assert(tech_pvt != NULL);
+
+        DEBUGA_SKYPE(&quot;%s CHANNEL KILL_CHANNEL\n&quot;, SKYPIAX_P_LOG, tech_pvt-&gt;name);
+        switch (sig) {
+        case SWITCH_SIG_KILL:
+                DEBUGA_SKYPE(&quot;%s CHANNEL got SWITCH_SIG_KILL\n&quot;, SKYPIAX_P_LOG, switch_channel_get_name(channel));
+                switch_mutex_lock(tech_pvt-&gt;flag_mutex);
+                switch_clear_flag(tech_pvt, TFLAG_IO);
+                switch_clear_flag(tech_pvt, TFLAG_VOICE);
+                switch_set_flag(tech_pvt, TFLAG_HANGUP);
+                if (tech_pvt-&gt;skype_callflow == CALLFLOW_STATUS_REMOTEHOLD) {
+                        ERRORA(&quot;FYI %s CHANNEL in CALLFLOW_STATUS_REMOTEHOLD got SWITCH_SIG_KILL\n&quot;, SKYPIAX_P_LOG, switch_channel_get_name(channel));
+                        channel_on_hangup(session);
+                }
+                if (switch_channel_get_state(channel) == CS_NEW) {
+                        ERRORA(&quot;FYI %s CHANNEL in CS_NEW state got SWITCH_SIG_KILL\n&quot;, SKYPIAX_P_LOG, switch_channel_get_name(channel));
+                        channel_on_hangup(session);
+                }
+                if (switch_channel_get_state(channel) != CS_NEW &amp;&amp; switch_channel_get_state(channel) &lt; CS_EXECUTE) {
+                        ERRORA(&quot;FYI %s CHANNEL in %d state got SWITCH_SIG_KILL\n&quot;, SKYPIAX_P_LOG, switch_channel_get_name(channel), switch_channel_get_state(channel));
+                        channel_on_hangup(session);
+                }
+                switch_mutex_unlock(tech_pvt-&gt;flag_mutex);
+                break;
+        case SWITCH_SIG_BREAK:
+                DEBUGA_SKYPE(&quot;%s CHANNEL got SWITCH_SIG_BREAK\n&quot;, SKYPIAX_P_LOG, switch_channel_get_name(channel));
+                //switch_set_flag(tech_pvt, TFLAG_BREAK);
+                switch_mutex_lock(tech_pvt-&gt;flag_mutex);
+                switch_set_flag(tech_pvt, TFLAG_BREAK);
+                switch_mutex_unlock(tech_pvt-&gt;flag_mutex);
+                break;
+        default:
+                break;
+        }
+
+        return SWITCH_STATUS_SUCCESS;
+}
+static switch_status_t channel_on_consume_media(switch_core_session_t *session)
+{
+        private_t *tech_pvt = NULL;
+
+        tech_pvt = switch_core_session_get_private(session);
+
+        DEBUGA_SKYPE(&quot;%s CHANNEL CONSUME_MEDIA\n&quot;, SKYPIAX_P_LOG, tech_pvt-&gt;name);
+        return SWITCH_STATUS_SUCCESS;
+}
+
+
+static switch_status_t channel_on_exchange_media(switch_core_session_t *session)
+{
+        private_t *tech_pvt = NULL;
+        tech_pvt = switch_core_session_get_private(session);
+        DEBUGA_SKYPE(&quot;%s CHANNEL EXCHANGE_MEDIA\n&quot;, SKYPIAX_P_LOG, tech_pvt-&gt;name);
+        return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t channel_on_soft_execute(switch_core_session_t *session)
+{
+        private_t *tech_pvt = NULL;
+        tech_pvt = switch_core_session_get_private(session);
+        DEBUGA_SKYPE(&quot;%s CHANNEL SOFT_EXECUTE\n&quot;, SKYPIAX_P_LOG, tech_pvt-&gt;name);
+        return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t channel_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf)
+{
+        private_t *tech_pvt = switch_core_session_get_private(session);
+        switch_assert(tech_pvt != NULL);
+
+        DEBUGA_SKYPE(&quot;%s CHANNEL SEND_DTMF\n&quot;, SKYPIAX_P_LOG, tech_pvt-&gt;name);
+        DEBUGA_SKYPE(&quot;DTMF: %c\n&quot;, SKYPIAX_P_LOG, dtmf-&gt;digit);
+
+        skypiax_senddigit(tech_pvt, dtmf-&gt;digit);
+
+        return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
+{
+        switch_channel_t *channel = NULL;
+        private_t *tech_pvt = NULL;
+        switch_byte_t *data;
+//unsigned int len;
+
+        channel = switch_core_session_get_channel(session);
+        switch_assert(channel != NULL);
+
+        tech_pvt = switch_core_session_get_private(session);
+        switch_assert(tech_pvt != NULL);
+
+        if (!switch_channel_ready(channel) || !switch_test_flag(tech_pvt, TFLAG_IO)) {
+                ERRORA(&quot;channel not ready \n&quot;, SKYPIAX_P_LOG);
+                //TODO: kill the bastard
+                return SWITCH_STATUS_FALSE;
+        }
+
+        tech_pvt-&gt;read_frame.flags = SFF_NONE;
+        *frame = NULL;
+
+        //switch_core_timer_next(&amp;tech_pvt-&gt;timer_read);
+
+                                                if (tech_pvt-&gt;skype_callflow != CALLFLOW_STATUS_REMOTEHOLD) {
+                                                        tech_pvt-&gt;read_frame.datalen = recv(tech_pvt-&gt;readfd, (char *) tech_pvt-&gt;read_frame.data, 320, 0);        //seems that Skype only sends 320 bytes at time
+                                                } else {
+                                                        tech_pvt-&gt;read_frame.datalen = 0;
+                                                }
+
+        //if (!skypiax_audio_read(tech_pvt)) {
+        if (!tech_pvt-&gt;read_frame.datalen) {
+
+                ERRORA(&quot;skypiax_audio_read ERROR\n&quot;, SKYPIAX_P_LOG);
+
+        } else {
+                switch_set_flag(tech_pvt, TFLAG_VOICE);
+        }
+
+        while (switch_test_flag(tech_pvt, TFLAG_IO)) {
+                if (switch_test_flag(tech_pvt, TFLAG_BREAK)) {
+                        switch_clear_flag(tech_pvt, TFLAG_BREAK);
+                        DEBUGA_SKYPE(&quot;CHANNEL READ FRAME goto CNG\n&quot;, SKYPIAX_P_LOG);
+                        goto cng;
+                }
+
+                if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
+                        DEBUGA_SKYPE(&quot;CHANNEL READ FRAME not IO\n&quot;, SKYPIAX_P_LOG);
+                        return SWITCH_STATUS_FALSE;
+                }
+
+                if (switch_test_flag(tech_pvt, TFLAG_IO) &amp;&amp; switch_test_flag(tech_pvt, TFLAG_VOICE)) {
+                        switch_clear_flag(tech_pvt, TFLAG_VOICE);
+                        if (!tech_pvt-&gt;read_frame.datalen) {
+                                DEBUGA_SKYPE(&quot;CHANNEL READ CONTINUE\n&quot;, SKYPIAX_P_LOG);
+                                continue;
+                        }
+#ifdef TIMERS_ON
+                        switch_core_timer_check(&amp;tech_pvt-&gt;timer_read, SWITCH_TRUE);
+#endif// TIMERS_ON
+                        *frame = &amp;tech_pvt-&gt;read_frame;
+#if SWITCH_BYTE_ORDER == __BIG_ENDIAN
+                        if (switch_test_flag(tech_pvt, TFLAG_LINEAR)) {
+                                switch_swap_linear((*frame)-&gt;data, (int) (*frame)-&gt;datalen / 2);
+                        }
+#endif
+                        return SWITCH_STATUS_SUCCESS;
+                }
+
+                DEBUGA_SKYPE(&quot;CHANNEL READ no TFLAG_IO\n&quot;, SKYPIAX_P_LOG);
+                return SWITCH_STATUS_FALSE;
+
+        }
+
+        DEBUGA_SKYPE(&quot;CHANNEL READ FALSE\n&quot;, SKYPIAX_P_LOG);
+        return SWITCH_STATUS_FALSE;
+
+  cng:
+        data = (switch_byte_t *) tech_pvt-&gt;read_frame.data;
+        data[0] = 65;
+        data[1] = 0;
+        tech_pvt-&gt;read_frame.datalen = 2;
+        tech_pvt-&gt;read_frame.flags = SFF_CNG;
+        *frame = &amp;tech_pvt-&gt;read_frame;
+        return SWITCH_STATUS_SUCCESS;
+
+}
+
+static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
+{
+        switch_channel_t *channel = NULL;
+        private_t *tech_pvt = NULL;
+        unsigned int sent=0;
+
+        channel = switch_core_session_get_channel(session);
+        switch_assert(channel != NULL);
+
+        tech_pvt = switch_core_session_get_private(session);
+        switch_assert(tech_pvt != NULL);
+
+        if (!switch_channel_ready(channel) || !switch_test_flag(tech_pvt, TFLAG_IO)) {
+                ERRORA(&quot;channel not ready \n&quot;, SKYPIAX_P_LOG);
+                //TODO: kill the bastard
+                return SWITCH_STATUS_FALSE;
+        }
+#if SWITCH_BYTE_ORDER == __BIG_ENDIAN
+        if (switch_test_flag(tech_pvt, TFLAG_LINEAR)) {
+                switch_swap_linear(frame-&gt;data, (int) frame-&gt;datalen / 2);
+        }
+#endif
+
+#if 0
+        sent = frame-&gt;datalen;
+#ifdef WIN32
+        //switch_file_write(tech_pvt-&gt;audiopipe_cli[1], frame-&gt;data, &amp;sent);
+#else /* WIN32 */
+        //sent = write(tech_pvt-&gt;audiopipe_cli[1], frame-&gt;data, sent);
+#endif /* WIN32 */
+        //if (tech_pvt-&gt;flag_audio_cli == 0) {
+#ifdef TIMER_WRITE
+                switch_core_timer_next(&amp;tech_pvt-&gt;timer_write);
+#endif // TIMER_WRITE
+
+        //while (tech_pvt-&gt;flag_audio_cli == 1) {
+                //switch_sleep(1000);                //10 millisec
+                                                //WARNINGA(&quot;write now is 1\n&quot;, SKYPIAX_P_LOG);
+        //}
+        switch_mutex_lock(tech_pvt-&gt;flag_audio_cli_mutex);
+                memcpy(tech_pvt-&gt;audiobuf_cli, frame-&gt;data, frame-&gt;datalen);
+                tech_pvt-&gt;flag_audio_cli = 1;
+        switch_mutex_unlock(tech_pvt-&gt;flag_audio_cli_mutex);
+        //}
+        //NOTICA(&quot;write \n&quot;, SKYPIAX_P_LOG);
+#endif //0
+
+#ifdef TIMER_WRITE
+/* NONBLOCKING ? */
+                //switch_core_timer_next(&amp;tech_pvt-&gt;timer_write);
+                //switch_core_timer_check(&amp;tech_pvt-&gt;timer_write, SWITCH_TRUE);
+#endif // TIMER_WRITE
+        /* send the 16khz frame to the Skype client waiting for incoming audio to be sent to the remote party */
+                                                                if (tech_pvt-&gt;skype_callflow != CALLFLOW_STATUS_REMOTEHOLD) {
+                                                                        sent = send(tech_pvt-&gt;writefd, (char *) frame-&gt;data, frame-&gt;datalen, 0);
+                                                                        if (sent == -1) {
+                                                                                ERRORA(&quot;EXIT? sent=%d\n&quot;, SKYPIAX_P_LOG, sent);
+                                                                        } else if (sent != frame-&gt;datalen) {
+                                                                                ERRORA(&quot;sent=%d\n&quot;, SKYPIAX_P_LOG, sent);
+                                                                        }
+                                                                }
+
+
+#ifdef TIMER_WRITE
+/* BLOCKING ? */
+                switch_core_timer_check(&amp;tech_pvt-&gt;timer_write, SWITCH_TRUE);
+#endif // TIMER_WRITE
+        if (sent != frame-&gt;datalen &amp;&amp; sent != -1) {
+                DEBUGA_SKYPE(&quot;CLI PIPE write %d\n&quot;, SKYPIAX_P_LOG, sent);
+        }
+
+        return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t channel_answer_channel(switch_core_session_t *session)
+{
+        private_t *tech_pvt;
+        switch_channel_t *channel = NULL;
+
+        channel = switch_core_session_get_channel(session);
+        switch_assert(channel != NULL);
+
+        tech_pvt = switch_core_session_get_private(session);
+        switch_assert(tech_pvt != NULL);
+
+        DEBUGA_SKYPE(&quot;ANSWERED! \n&quot;, SKYPIAX_P_LOG);
+
+        return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t channel_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg)
+{
+        switch_channel_t *channel;
+        private_t *tech_pvt;
+        //int i;
+
+        channel = switch_core_session_get_channel(session);
+        switch_assert(channel != NULL);
+
+        tech_pvt = (private_t *) switch_core_session_get_private(session);
+        switch_assert(tech_pvt != NULL);
+
+        switch (msg-&gt;message_id) {
+        case SWITCH_MESSAGE_INDICATE_ANSWER:
+                {
+                        DEBUGA_SKYPE(&quot;MSG_ID=%d, TO BE ANSWERED!\n&quot;, SKYPIAX_P_LOG, msg-&gt;message_id);
+
+#ifdef TIMERS_ON
+                        switch_core_timer_sync(&amp;tech_pvt-&gt;timer_read);
+#endif// TIMERS_ON
+#ifdef TIMER_WRITE
+                        switch_core_timer_sync(&amp;tech_pvt-&gt;timer_write);
+#endif // TIMER_WRITE
+                        channel_answer_channel(session);
+                }
+                break;
+        case SWITCH_MESSAGE_INDICATE_AUDIO_SYNC:
+
+                DEBUGA_SKYPE(&quot;%s CHANNEL got SWITCH_MESSAGE_INDICATE_AUDIO_SYNC\n&quot;, SKYPIAX_P_LOG, switch_channel_get_name(channel));
+
+#ifdef TIMERS_ON
+                switch_core_timer_sync(&amp;tech_pvt-&gt;timer_read);
+#endif// TIMERS_ON
+#ifdef TIMER_WRITE
+                switch_core_timer_sync(&amp;tech_pvt-&gt;timer_write);
+#endif // TIMER_WRITE
+                break;
+        default:
+                {
+
+#ifdef TIMERS_ON
+                        switch_core_timer_sync(&amp;tech_pvt-&gt;timer_read);
+#endif// TIMERS_ON
+#ifdef TIMER_WRITE
+
+                        switch_core_timer_sync(&amp;tech_pvt-&gt;timer_write);
+#endif // TIMER_WRITE
+
+                        DEBUGA_SKYPE(&quot;MSG_ID=%d\n&quot;, SKYPIAX_P_LOG, msg-&gt;message_id);
+                }
+                break;
+        }
+
+        return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t channel_receive_event(switch_core_session_t *session, switch_event_t *event)
+{
+        struct private_object *tech_pvt = switch_core_session_get_private(session);
+        char *body = switch_event_get_body(event);
+        switch_assert(tech_pvt != NULL);
+
+        if (!body) {
+                body = &quot;&quot;;
+        }
+
+        WARNINGA(&quot;event: |||%s|||\n&quot;, SKYPIAX_P_LOG, body);
+
+        return SWITCH_STATUS_SUCCESS;
+}
+
+switch_state_handler_table_t skypiax_state_handlers = {
+        /*.on_init */ channel_on_init,
+        /*.on_routing */ channel_on_routing,
+        /*.on_execute */ channel_on_execute,
+        /*.on_hangup */ channel_on_hangup,
+        /*.on_exchange_media */ channel_on_exchange_media,
+        /*.on_soft_execute */ channel_on_soft_execute,
+        /*.on_consume_media */ channel_on_consume_media,
+        /*.on_hibernate */ NULL,
+        /*.on_reset */ NULL,
+        /*.on_park */ NULL,
+        /*.on_reporting */ NULL,
+        /*.on_destroy */ channel_on_destroy
+};
+
+switch_io_routines_t skypiax_io_routines = {
+        /*.outgoing_channel */ channel_outgoing_channel,
+        /*.read_frame */ channel_read_frame,
+        /*.write_frame */ channel_write_frame,
+        /*.kill_channel */ channel_kill_channel,
+        /*.send_dtmf */ channel_send_dtmf,
+        /*.receive_message */ channel_receive_message,
+        /*.receive_event */ channel_receive_event
+};
+
+static switch_call_cause_t channel_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,
+                                                                                                        switch_call_cause_t *cancel_cause)
+{
+        private_t *tech_pvt = NULL;
+        if ((*new_session = switch_core_session_request(skypiax_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, pool)) != 0) {
+                switch_channel_t *channel = NULL;
+                switch_caller_profile_t *caller_profile;
+                char *rdest;
+                int found = 0;
+                char interface_name[256];
+
+                DEBUGA_SKYPE(&quot;1 SESSION_REQUEST %s\n&quot;, SKYPIAX_P_LOG, switch_core_session_get_uuid(*new_session));
+                switch_core_session_add_stream(*new_session, NULL);
+
+
+                if (!zstr(outbound_profile-&gt;destination_number)) {
+                        int i;
+                        char *slash;
+
+                        switch_copy_string(interface_name, outbound_profile-&gt;destination_number, 255);
+                        slash = strrchr(interface_name, '/');
+                        *slash = '\0';
+
+                        switch_mutex_lock(globals.mutex);
+                        if (strncmp(&quot;ANY&quot;, interface_name, strlen(interface_name)) == 0 || strncmp(&quot;RR&quot;, interface_name, strlen(interface_name)) == 0) {
+                                /* we've been asked for the &quot;ANY&quot; interface, let's find the first idle interface */
+                                //DEBUGA_SKYPE(&quot;Finding one available skype interface\n&quot;, SKYPIAX_P_LOG);
+                                //tech_pvt = find_available_skypiax_interface(NULL);
+                                //if (tech_pvt)
+                                //found = 1;
+                                //} else if (strncmp(&quot;RR&quot;, interface_name, strlen(interface_name)) == 0) {
+                                /* Find the first idle interface using Round Robin */
+                                DEBUGA_SKYPE(&quot;Finding one available skype interface RR\n&quot;, SKYPIAX_P_LOG);
+                                tech_pvt = find_available_skypiax_interface_rr(NULL);
+                                if (tech_pvt)
+                                        found = 1;
+                        }
+
+                        for (i = 0; !found &amp;&amp; i &lt; SKYPIAX_MAX_INTERFACES; i++) {
+                                /* we've been asked for a normal interface name, or we have not found idle interfaces to serve as the &quot;ANY&quot; interface */
+                                if (strlen(globals.SKYPIAX_INTERFACES[i].name)
+                                        &amp;&amp; (strncmp(globals.SKYPIAX_INTERFACES[i].name, interface_name, strlen(interface_name)) == 0)) {
+                                        if (strlen(globals.SKYPIAX_INTERFACES[i].session_uuid_str)) {
+                                                DEBUGA_SKYPE
+                                                        (&quot;globals.SKYPIAX_INTERFACES[%d].name=|||%s||| session_uuid_str=|||%s||| is BUSY\n&quot;,
+                                                         SKYPIAX_P_LOG, i, globals.SKYPIAX_INTERFACES[i].name, globals.SKYPIAX_INTERFACES[i].session_uuid_str);
+                                                DEBUGA_SKYPE(&quot;1 SESSION_DESTROY %s\n&quot;, SKYPIAX_P_LOG, switch_core_session_get_uuid(*new_session));
+                                                switch_core_session_destroy(new_session);
+                                                switch_mutex_unlock(globals.mutex);
+                                                return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
+                                        }
+
+                                        DEBUGA_SKYPE(&quot;globals.SKYPIAX_INTERFACES[%d].name=|||%s|||?\n&quot;, SKYPIAX_P_LOG, i, globals.SKYPIAX_INTERFACES[i].name);
+                                        tech_pvt = &amp;globals.SKYPIAX_INTERFACES[i];
+                                        found = 1;
+                                        break;
+                                }
+
+                        }
+
+                } else {
+                        ERRORA(&quot;Doh! no destination number?\n&quot;, SKYPIAX_P_LOG);
+                        switch_core_session_destroy(new_session);
+                        return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
+                }
+
+                if (!found) {
+                        DEBUGA_SKYPE(&quot;Doh! no available interface for |||%s|||?\n&quot;, SKYPIAX_P_LOG, interface_name);
+                        DEBUGA_SKYPE(&quot;2 SESSION_DESTROY %s\n&quot;, SKYPIAX_P_LOG, switch_core_session_get_uuid(*new_session));
+                        switch_core_session_destroy(new_session);
+                        switch_mutex_unlock(globals.mutex);
+                        //return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
+                        return SWITCH_CAUSE_NORMAL_CIRCUIT_CONGESTION;
+                }
+
+                channel = switch_core_session_get_channel(*new_session);
+                if (!channel) {
+                        ERRORA(&quot;Doh! no channel?\n&quot;, SKYPIAX_P_LOG);
+                        switch_core_session_destroy(new_session);
+                        switch_mutex_unlock(globals.mutex);
+                        return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
+                }
+                if (skypiax_tech_init(tech_pvt, *new_session) != SWITCH_STATUS_SUCCESS) {
+                        ERRORA(&quot;Doh! no tech_init?\n&quot;, SKYPIAX_P_LOG);
+                        switch_core_session_destroy(new_session);
+                        switch_mutex_unlock(globals.mutex);
+                        return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
+                }
+
+
+                if (outbound_profile) {
+                        char name[128];
+
+                        if (strncmp(&quot;ANY&quot;, outbound_profile-&gt;destination_number, 3) == 0) {
+                                snprintf(name, sizeof(name), &quot;skypiax/ANY/%s%s&quot;, tech_pvt-&gt;name, outbound_profile-&gt;destination_number + 3);
+                        } else if (strncmp(&quot;RR&quot;, outbound_profile-&gt;destination_number, 2) == 0) {
+                                snprintf(name, sizeof(name), &quot;skypiax/RR/%s%s&quot;, tech_pvt-&gt;name, outbound_profile-&gt;destination_number + 2);
+                        } else {
+                                snprintf(name, sizeof(name), &quot;skypiax/%s&quot;, outbound_profile-&gt;destination_number);
+                        }
+
+                        //snprintf(name, sizeof(name), &quot;skypiax/%s&quot;, outbound_profile-&gt;destination_number);
+                        //snprintf(name, sizeof(name), &quot;skypiax/%s&quot;, tech_pvt-&gt;name);
+                        switch_channel_set_name(channel, name);
+                        caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
+                        switch_channel_set_caller_profile(channel, caller_profile);
+                        tech_pvt-&gt;caller_profile = caller_profile;
+                } else {
+                        ERRORA(&quot;Doh! no caller profile\n&quot;, SKYPIAX_P_LOG);
+                        switch_core_session_destroy(new_session);
+                        switch_mutex_unlock(globals.mutex);
+                        return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
+                }
+
+                tech_pvt-&gt;ob_calls++;
+
+                rdest = strchr(caller_profile-&gt;destination_number, '/');
+                *rdest++ = '\0';
+
+                //skypiax_call(tech_pvt, rdest, 30);
+
+                switch_copy_string(tech_pvt-&gt;session_uuid_str, switch_core_session_get_uuid(*new_session), sizeof(tech_pvt-&gt;session_uuid_str));
+                caller_profile = tech_pvt-&gt;caller_profile;
+                caller_profile-&gt;destination_number = rdest;
+
+                switch_channel_set_flag(channel, CF_OUTBOUND);
+                switch_set_flag(tech_pvt, TFLAG_OUTBOUND);
+                switch_channel_set_state(channel, CS_INIT);
+                skypiax_call(tech_pvt, rdest, 30);
+                switch_mutex_unlock(globals.mutex);
+                return SWITCH_CAUSE_SUCCESS;
+        }
+
+        ERRORA(&quot;Doh! no new_session\n&quot;, SKYPIAX_P_LOG);
+        return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
+}
+
+/*!
+ * \brief This thread runs during a call, and monitor the interface for signaling, like hangup, caller id, etc most of signaling is handled inside the skypiax_signaling_read function
+ *
+ */
+static void *SWITCH_THREAD_FUNC skypiax_signaling_thread_func(switch_thread_t * thread, void *obj)
+{
+        private_t *tech_pvt = obj;
+        int res;
+        int forever = 1;
+
+        if (!tech_pvt)
+                return NULL;
+
+        DEBUGA_SKYPE(&quot;In skypiax_signaling_thread_func: started, p=%p\n&quot;, SKYPIAX_P_LOG, (void *) tech_pvt);
+
+        while (forever) {
+                if (!(running &amp;&amp; tech_pvt-&gt;running))
+                        break;
+                res = skypiax_signaling_read(tech_pvt);
+                if (res == CALLFLOW_INCOMING_HANGUP) {
+                        switch_core_session_t *session = NULL;
+                        switch_channel_t *channel = NULL;
+                        //private_t *tech_pvt = NULL;
+                        DEBUGA_SKYPE(&quot;skype call ended\n&quot;, SKYPIAX_P_LOG);
+
+                        if (tech_pvt) {
+                                session = switch_core_session_locate(tech_pvt-&gt;session_uuid_str);
+                                if (session) {
+                                        channel = switch_core_session_get_channel(session);
+                                        if (channel) {
+                                                switch_channel_state_t state = switch_channel_get_state(channel);
+                                                if (state &lt; CS_EXECUTE) {
+                                                        switch_sleep(10000);        //10 msec, let the state evolve from CS_NEW
+                                                }
+                                                switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
+                                        } else {
+                                                ERRORA(&quot;no channel?\n&quot;, SKYPIAX_P_LOG);
+                                        }
+                                        switch_core_session_rwunlock(session);
+                                } else {
+                                        DEBUGA_SKYPE(&quot;no session\n&quot;, SKYPIAX_P_LOG);
+                                }
+                                switch_mutex_lock(globals.mutex);
+                                tech_pvt-&gt;interface_state = SKYPIAX_STATE_DOWN;
+                                *tech_pvt-&gt;session_uuid_str = '\0';
+                                *tech_pvt-&gt;skype_call_id = '\0';
+                                switch_mutex_unlock(globals.mutex);
+
+                                //ERRORA(&quot;LET'S WAIT\n&quot;, SKYPIAX_P_LOG);
+                                switch_sleep(300000);        //0.3 sec
+                                //ERRORA(&quot;WAIT'S OVER\n&quot;, SKYPIAX_P_LOG);
+                                //tech_pvt-&gt;skype_callflow = CALLFLOW_STATUS_FINISHED;
+                                //switch_sleep(30000);    //0.03 sec
+                                switch_mutex_lock(globals.mutex);
+                                tech_pvt-&gt;skype_callflow = CALLFLOW_CALL_IDLE;
+                                tech_pvt-&gt;interface_state = SKYPIAX_STATE_IDLE;
+                                switch_mutex_unlock(globals.mutex);
+                        } else {
+                                ERRORA(&quot;no tech_pvt?\n&quot;, SKYPIAX_P_LOG);
+                        }
+                }
+        }
+        return NULL;
+}
+
+/* BEGIN: Changes heres */
+static switch_status_t load_config(int reload_type)
+/* END: Changes heres */
+{
+        char *cf = &quot;skypiax.conf&quot;;
+        switch_xml_t cfg, xml, global_settings, param, interfaces, myinterface;
+        private_t *tech_pvt = NULL;
+
+        switch_mutex_init(&amp;globals.mutex, SWITCH_MUTEX_NESTED, skypiax_module_pool);
+        if (!(xml = switch_xml_open_cfg(cf, &amp;cfg, NULL))) {
+                ERRORA(&quot;open of %s failed\n&quot;, SKYPIAX_P_LOG, cf);
+                running = 0;
+                switch_xml_free(xml);
+                return SWITCH_STATUS_TERM;
+        }
+
+        switch_mutex_lock(globals.mutex);
+        if ((global_settings = switch_xml_child(cfg, &quot;global_settings&quot;))) {
+                for (param = switch_xml_child(global_settings, &quot;param&quot;); param; param = param-&gt;next) {
+                        char *var = (char *) switch_xml_attr_soft(param, &quot;name&quot;);
+                        char *val = (char *) switch_xml_attr_soft(param, &quot;value&quot;);
+
+                        if (!strcasecmp(var, &quot;debug&quot;)) {
+                                DEBUGA_SKYPE(&quot;globals.debug=%d\n&quot;, SKYPIAX_P_LOG, globals.debug);
+                                globals.debug = atoi(val);
+                                DEBUGA_SKYPE(&quot;globals.debug=%d\n&quot;, SKYPIAX_P_LOG, globals.debug);
+                        } else if (!strcasecmp(var, &quot;hold-music&quot;)) {
+                                switch_set_string(globals.hold_music, val);
+                                DEBUGA_SKYPE(&quot;globals.hold_music=%s\n&quot;, SKYPIAX_P_LOG, globals.hold_music);
+                        } else if (!strcmp(var, &quot;port&quot;)) {
+                                globals.port = atoi(val);
+                                DEBUGA_SKYPE(&quot;globals.port=%d\n&quot;, SKYPIAX_P_LOG, globals.port);
+                        } else if (!strcmp(var, &quot;codec-master&quot;)) {
+                                if (!strcasecmp(val, &quot;us&quot;)) {
+                                        switch_set_flag(&amp;globals, GFLAG_MY_CODEC_PREFS);
+                                }
+                                DEBUGA_SKYPE(&quot;codec-master globals.debug=%d\n&quot;, SKYPIAX_P_LOG, globals.debug);
+                        } else if (!strcmp(var, &quot;dialplan&quot;)) {
+                                set_global_dialplan(val);
+                                DEBUGA_SKYPE(&quot;globals.dialplan=%s\n&quot;, SKYPIAX_P_LOG, globals.dialplan);
+                        } else if (!strcmp(var, &quot;destination&quot;)) {
+                                set_global_destination(val);
+                                DEBUGA_SKYPE(&quot;globals.destination=%s\n&quot;, SKYPIAX_P_LOG, globals.destination);
+                        } else if (!strcmp(var, &quot;context&quot;)) {
+                                set_global_context(val);
+                                DEBUGA_SKYPE(&quot;globals.context=%s\n&quot;, SKYPIAX_P_LOG, globals.context);
+                        } else if (!strcmp(var, &quot;codec-prefs&quot;)) {
+                                set_global_codec_string(val);
+                                DEBUGA_SKYPE(&quot;globals.codec_string=%s\n&quot;, SKYPIAX_P_LOG, globals.codec_string);
+                                globals.codec_order_last = switch_separate_string(globals.codec_string, ',', globals.codec_order, SWITCH_MAX_CODECS);
+                        } else if (!strcmp(var, &quot;codec-rates&quot;)) {
+                                set_global_codec_rates_string(val);
+                                DEBUGA_SKYPE(&quot;globals.codec_rates_string=%s\n&quot;, SKYPIAX_P_LOG, globals.codec_rates_string);
+                                globals.codec_rates_last = switch_separate_string(globals.codec_rates_string, ',', globals.codec_rates, SWITCH_MAX_CODECS);
+                        }
+
+                }
+        }
+
+        if ((interfaces = switch_xml_child(cfg, &quot;per_interface_settings&quot;))) {
+                int i = 0;
+
+                for (myinterface = switch_xml_child(interfaces, &quot;interface&quot;); myinterface; myinterface = myinterface-&gt;next) {
+                        char *id = (char *) switch_xml_attr(myinterface, &quot;id&quot;);
+                        char *name = (char *) switch_xml_attr(myinterface, &quot;name&quot;);
+                        char *context = &quot;default&quot;;
+                        char *dialplan = &quot;XML&quot;;
+                        char *destination = &quot;5000&quot;;
+                        char *tonegroup = NULL;
+                        char *digit_timeout = NULL;
+                        char *max_digits = NULL;
+                        char *hotline = NULL;
+                        char *dial_regex = NULL;
+                        char *hold_music = NULL;
+                        char *fail_dial_regex = NULL;
+                        char *enable_callerid = &quot;true&quot;;
+                        char *X11_display = NULL;
+                        char *tcp_cli_port = NULL;
+                        char *tcp_srv_port = NULL;
+                        char *skype_user = NULL;
+                        char *report_incoming_chatmessages = &quot;true&quot;;
+
+                        uint32_t interface_id = 0, to = 0, max = 0;
+
+                        tech_pvt = NULL;
+
+                        for (param = switch_xml_child(myinterface, &quot;param&quot;); param; param = param-&gt;next) {
+                                char *var = (char *) switch_xml_attr_soft(param, &quot;name&quot;);
+                                char *val = (char *) switch_xml_attr_soft(param, &quot;value&quot;);
+
+                                if (!strcasecmp(var, &quot;tonegroup&quot;)) {
+                                        tonegroup = val;
+                                } else if (!strcasecmp(var, &quot;digit_timeout&quot;) || !strcasecmp(var, &quot;digit-timeout&quot;)) {
+                                        digit_timeout = val;
+                                } else if (!strcasecmp(var, &quot;context&quot;)) {
+                                        context = val;
+                                } else if (!strcasecmp(var, &quot;dialplan&quot;)) {
+                                        dialplan = val;
+                                } else if (!strcasecmp(var, &quot;destination&quot;)) {
+                                        destination = val;
+                                } else if (!strcasecmp(var, &quot;dial-regex&quot;)) {
+                                        dial_regex = val;
+                                } else if (!strcasecmp(var, &quot;enable-callerid&quot;)) {
+                                        enable_callerid = val;
+                                } else if (!strcasecmp(var, &quot;fail-dial-regex&quot;)) {
+                                        fail_dial_regex = val;
+                                } else if (!strcasecmp(var, &quot;hold-music&quot;)) {
+                                        hold_music = val;
+                                } else if (!strcasecmp(var, &quot;skype_user&quot;)) {
+                                        skype_user = val;
+                                } else if (!strcasecmp(var, &quot;report_incoming_chatmessages&quot;)) {
+                                        report_incoming_chatmessages = val;
+                                } else if (!strcasecmp(var, &quot;tcp_cli_port&quot;)) {
+                                        tcp_cli_port = val;
+                                } else if (!strcasecmp(var, &quot;tcp_srv_port&quot;)) {
+                                        tcp_srv_port = val;
+                                } else if (!strcasecmp(var, &quot;X11-display&quot;) || !strcasecmp(var, &quot;X11_display&quot;)) {
+                                        X11_display = val;
+                                } else if (!strcasecmp(var, &quot;max_digits&quot;) || !strcasecmp(var, &quot;max-digits&quot;)) {
+                                        max_digits = val;
+                                } else if (!strcasecmp(var, &quot;hotline&quot;)) {
+                                        hotline = val;
+                                }
+
+                        }
+                        if (!skype_user) {
+                                ERRORA(&quot;interface missing REQUIRED param 'skype_user'\n&quot;, SKYPIAX_P_LOG);
+                                continue;
+                        }
+
+                        /* BEGIN: Changes here */
+                        if (reload_type == SOFT_RELOAD) {
+                                char the_interface[256];
+                                sprintf(the_interface, &quot;#%s&quot;, name);
+
+                                if (interface_exists(the_interface) == SWITCH_STATUS_SUCCESS) {
+                                        continue;
+                                }
+                        }
+                        /* END: Changes here */
+
+                        if (!X11_display) {
+                                ERRORA(&quot;interface missing REQUIRED param 'X11_display'\n&quot;, SKYPIAX_P_LOG);
+                                continue;
+                        }
+                        if (!tcp_cli_port) {
+                                ERRORA(&quot;interface missing REQUIRED param 'tcp_cli_port'\n&quot;, SKYPIAX_P_LOG);
+                                continue;
+                        }
+
+                        if (!tcp_srv_port) {
+                                ERRORA(&quot;interface missing REQUIRED param 'tcp_srv_port'\n&quot;, SKYPIAX_P_LOG);
+                                continue;
+                        }
+                        if (!id) {
+                                ERRORA(&quot;interface missing REQUIRED param 'id'\n&quot;, SKYPIAX_P_LOG);
+                                continue;
+                        }
+                        if (switch_is_number(id)) {
+                                interface_id = atoi(id);
+                                DEBUGA_SKYPE(&quot;interface_id=%d\n&quot;, SKYPIAX_P_LOG, interface_id);
+                        } else {
+                                ERRORA(&quot;interface param 'id' MUST be a number, now id='%s'\n&quot;, SKYPIAX_P_LOG, id);
+                                continue;
+                        }
+
+                        if (!name) {
+                                WARNINGA(&quot;interface missing param 'name', not nice, but works\n&quot;, SKYPIAX_P_LOG);
+                        }
+
+                        if (!tonegroup) {
+                                tonegroup = &quot;us&quot;;
+                        }
+
+                        if (digit_timeout) {
+                                to = atoi(digit_timeout);
+                        }
+
+                        if (max_digits) {
+                                max = atoi(max_digits);
+                        }
+
+                        if (name) {
+                                DEBUGA_SKYPE(&quot;name=%s\n&quot;, SKYPIAX_P_LOG, name);
+                        }
+#ifndef WIN32
+                        if (!XInitThreads()) {
+                                ERRORA(&quot;Not initialized XInitThreads!\n&quot;, SKYPIAX_P_LOG);
+                        } else {
+                                DEBUGA_SKYPE(&quot;Initialized XInitThreads!\n&quot;, SKYPIAX_P_LOG);
+                        }
+                        switch_sleep(1000);
+#endif /* WIN32 */
+
+                        if (interface_id &amp;&amp; interface_id &lt; SKYPIAX_MAX_INTERFACES) {
+                                private_t newconf;
+                                switch_threadattr_t *skypiax_api_thread_attr = NULL;
+                                switch_threadattr_t *skypiax_signaling_thread_attr = NULL;
+
+                                memset(&amp;newconf, '\0', sizeof(newconf));
+                                globals.SKYPIAX_INTERFACES[interface_id] = newconf;
+                                globals.SKYPIAX_INTERFACES[interface_id].running = 1;
+
+
+                                tech_pvt = &amp;globals.SKYPIAX_INTERFACES[interface_id];
+
+                                switch_set_string(globals.SKYPIAX_INTERFACES[interface_id].interface_id, id);
+                                if (name) {
+                                        switch_set_string(globals.SKYPIAX_INTERFACES[interface_id].name, name);
+                                } else {
+                                        switch_set_string(globals.SKYPIAX_INTERFACES[interface_id].name, &quot;N/A&quot;);
+                                }
+                                DEBUGA_SKYPE(&quot;CONFIGURING interface_id=%d\n&quot;, SKYPIAX_P_LOG, interface_id);
+#ifdef WIN32
+                                globals.SKYPIAX_INTERFACES[interface_id].tcp_cli_port = (unsigned short) atoi(tcp_cli_port);
+                                globals.SKYPIAX_INTERFACES[interface_id].tcp_srv_port = (unsigned short) atoi(tcp_srv_port);
+#else /* WIN32 */
+                                globals.SKYPIAX_INTERFACES[interface_id].tcp_cli_port = atoi(tcp_cli_port);
+                                globals.SKYPIAX_INTERFACES[interface_id].tcp_srv_port = atoi(tcp_srv_port);
+#endif /* WIN32 */
+                                switch_set_string(globals.SKYPIAX_INTERFACES[interface_id].X11_display, X11_display);
+                                switch_set_string(globals.SKYPIAX_INTERFACES[interface_id].skype_user, skype_user);
+                                switch_set_string(globals.SKYPIAX_INTERFACES[interface_id].context, context);
+                                switch_set_string(globals.SKYPIAX_INTERFACES[interface_id].dialplan, dialplan);
+                                switch_set_string(globals.SKYPIAX_INTERFACES[interface_id].destination, destination);
+                                switch_set_string(globals.SKYPIAX_INTERFACES[interface_id].context, context);
+
+                                if (!strcmp(report_incoming_chatmessages, &quot;true&quot;) || !strcmp(report_incoming_chatmessages, &quot;1&quot;)) {
+                                        globals.SKYPIAX_INTERFACES[interface_id].report_incoming_chatmessages = 1;
+                                } else {
+                                        globals.SKYPIAX_INTERFACES[interface_id].report_incoming_chatmessages = 0;        //redundant, just in case
+
+                                }
+
+                                DEBUGA_SKYPE
+                                        (&quot;interface_id=%d globals.SKYPIAX_INTERFACES[interface_id].X11_display=%s\n&quot;,
+                                         SKYPIAX_P_LOG, interface_id, globals.SKYPIAX_INTERFACES[interface_id].X11_display);
+                                DEBUGA_SKYPE
+                                        (&quot;interface_id=%d globals.SKYPIAX_INTERFACES[interface_id].skype_user=%s\n&quot;,
+                                         SKYPIAX_P_LOG, interface_id, globals.SKYPIAX_INTERFACES[interface_id].skype_user);
+                                DEBUGA_SKYPE
+                                        (&quot;interface_id=%d globals.SKYPIAX_INTERFACES[interface_id].tcp_cli_port=%d\n&quot;,
+                                         SKYPIAX_P_LOG, interface_id, globals.SKYPIAX_INTERFACES[interface_id].tcp_cli_port);
+                                DEBUGA_SKYPE
+                                        (&quot;interface_id=%d globals.SKYPIAX_INTERFACES[interface_id].tcp_srv_port=%d\n&quot;,
+                                         SKYPIAX_P_LOG, interface_id, globals.SKYPIAX_INTERFACES[interface_id].tcp_srv_port);
+                                DEBUGA_SKYPE(&quot;interface_id=%d globals.SKYPIAX_INTERFACES[interface_id].name=%s\n&quot;,
+                                                         SKYPIAX_P_LOG, interface_id, globals.SKYPIAX_INTERFACES[interface_id].name);
+                                DEBUGA_SKYPE
+                                        (&quot;interface_id=%d globals.SKYPIAX_INTERFACES[interface_id].context=%s\n&quot;,
+                                         SKYPIAX_P_LOG, interface_id, globals.SKYPIAX_INTERFACES[interface_id].context);
+                                DEBUGA_SKYPE
+                                        (&quot;interface_id=%d globals.SKYPIAX_INTERFACES[interface_id].dialplan=%s\n&quot;,
+                                         SKYPIAX_P_LOG, interface_id, globals.SKYPIAX_INTERFACES[interface_id].dialplan);
+                                DEBUGA_SKYPE
+                                        (&quot;interface_id=%d globals.SKYPIAX_INTERFACES[interface_id].destination=%s\n&quot;,
+                                         SKYPIAX_P_LOG, interface_id, globals.SKYPIAX_INTERFACES[interface_id].destination);
+                                DEBUGA_SKYPE
+                                        (&quot;interface_id=%d globals.SKYPIAX_INTERFACES[interface_id].context=%s\n&quot;,
+                                         SKYPIAX_P_LOG, interface_id, globals.SKYPIAX_INTERFACES[interface_id].context);
+
+                                DEBUGA_SKYPE
+                                        (&quot;interface_id=%d globals.SKYPIAX_INTERFACES[interface_id].report_incoming_chatmessages=%d\n&quot;,
+                                         SKYPIAX_P_LOG, interface_id, globals.SKYPIAX_INTERFACES[interface_id].report_incoming_chatmessages);
+
+                                WARNINGA(&quot;STARTING interface_id=%d\n&quot;, SKYPIAX_P_LOG, interface_id);
+
+                                switch_threadattr_create(&amp;skypiax_api_thread_attr, skypiax_module_pool);
+                                switch_threadattr_detach_set(skypiax_api_thread_attr, 1);
+                                switch_threadattr_stacksize_set(skypiax_api_thread_attr, SWITCH_THREAD_STACKSIZE);
+                                switch_thread_create(&amp;globals.SKYPIAX_INTERFACES[interface_id].skypiax_api_thread,
+                                                                         skypiax_api_thread_attr, skypiax_do_skypeapi_thread, &amp;globals.SKYPIAX_INTERFACES[interface_id], skypiax_module_pool);
+
+                                switch_sleep(100000);
+
+                                switch_threadattr_create(&amp;skypiax_signaling_thread_attr, skypiax_module_pool);
+                                switch_threadattr_detach_set(skypiax_signaling_thread_attr, 1);
+                                switch_threadattr_stacksize_set(skypiax_signaling_thread_attr, SWITCH_THREAD_STACKSIZE);
+                                switch_thread_create(&amp;globals.SKYPIAX_INTERFACES[interface_id].
+                                                                         skypiax_signaling_thread, skypiax_signaling_thread_attr,
+                                                                         skypiax_signaling_thread_func, &amp;globals.SKYPIAX_INTERFACES[interface_id], skypiax_module_pool);
+
+                                switch_sleep(100000);
+
+                                skypiax_audio_init(&amp;globals.SKYPIAX_INTERFACES[interface_id]);
+
+        switch_mutex_init(&amp;globals.SKYPIAX_INTERFACES[interface_id].flag_audio_srv_mutex, SWITCH_MUTEX_NESTED, skypiax_module_pool);
+        switch_mutex_init(&amp;globals.SKYPIAX_INTERFACES[interface_id].flag_audio_cli_mutex, SWITCH_MUTEX_NESTED, skypiax_module_pool);
+                                NOTICA
+                                        (&quot;WAITING roughly 10 seconds to find a running Skype client and connect to its SKYPE API for interface_id=%d\n&quot;,
+                                         SKYPIAX_P_LOG, interface_id);
+                                i = 0;
+                                while (globals.SKYPIAX_INTERFACES[interface_id].SkypiaxHandles.api_connected == 0 &amp;&amp; running &amp;&amp; i &lt; 200) {        // 10 seconds! thanks Jeff Lenk
+                                        switch_sleep(50000);
+                                        i++;
+                                }
+                                if (globals.SKYPIAX_INTERFACES[interface_id].SkypiaxHandles.api_connected) {
+                                        NOTICA
+                                                (&quot;Found a running Skype client, connected to its SKYPE API for interface_id=%d, waiting 60 seconds for CURRENTUSERHANDLE==%s\n&quot;,
+                                                 SKYPIAX_P_LOG, interface_id, globals.SKYPIAX_INTERFACES[interface_id].skype_user);
+                                } else {
+                                        ERRORA
+                                                (&quot;Failed to connect to a SKYPE API for interface_id=%d, no SKYPE client running, please (re)start Skype client. Skypiax exiting\n&quot;,
+                                                 SKYPIAX_P_LOG, interface_id);
+                                        running = 0;
+                                        switch_mutex_unlock(globals.mutex);
+                                        switch_xml_free(xml);
+                                        return SWITCH_STATUS_FALSE;
+                                }
+
+                                i = 0;
+                                while (globals.SKYPIAX_INTERFACES[interface_id].SkypiaxHandles.currentuserhandle == 0 &amp;&amp; running &amp;&amp; i &lt; 1200) {        // 60 seconds! thanks Jeff Lenk
+                                        switch_sleep(50000);
+                                        i++;
+                                }
+                                if (globals.SKYPIAX_INTERFACES[interface_id].SkypiaxHandles.currentuserhandle) {
+                                        WARNINGA
+                                                (&quot;Interface_id=%d is now STARTED, the Skype client to which we are connected gave us the correct CURRENTUSERHANDLE (%s)\n&quot;,
+                                                 SKYPIAX_P_LOG, interface_id, globals.SKYPIAX_INTERFACES[interface_id].skype_user);
+
+
+                                        skypiax_signaling_write(&amp;globals.SKYPIAX_INTERFACES[interface_id], &quot;PROTOCOL 7&quot;);
+                                        switch_sleep(10000);
+                                        skypiax_signaling_write(&amp;globals.SKYPIAX_INTERFACES[interface_id], &quot;SET AUTOAWAY OFF&quot;);
+                                } else {
+                                        ERRORA
+                                                (&quot;The Skype client to which we are connected FAILED to gave us CURRENTUSERHANDLE=%s, interface_id=%d FAILED to start. No Skype client logged in as '%s' has been found. Please (re)launch a Skype client logged in as '%s'. Skypiax exiting now\n&quot;,
+                                                 SKYPIAX_P_LOG, globals.SKYPIAX_INTERFACES[interface_id].skype_user,
+                                                 interface_id, globals.SKYPIAX_INTERFACES[interface_id].skype_user, globals.SKYPIAX_INTERFACES[interface_id].skype_user);
+                                        running = 0;
+                                        switch_mutex_unlock(globals.mutex);
+                                        switch_xml_free(xml);
+                                        return SWITCH_STATUS_FALSE;
+                                }
+
+                        } else {
+                                ERRORA(&quot;interface id %d is higher than SKYPIAX_MAX_INTERFACES (%d)\n&quot;, SKYPIAX_P_LOG, interface_id, SKYPIAX_MAX_INTERFACES);
+                                continue;
+                        }
+
+                }
+
+                for (i = 0; i &lt; SKYPIAX_MAX_INTERFACES; i++) {
+                        if (strlen(globals.SKYPIAX_INTERFACES[i].name)) {
+                                /* How many real intterfaces */
+                                globals.real_interfaces = i + 1;
+
+                                tech_pvt = &amp;globals.SKYPIAX_INTERFACES[i];
+
+                                DEBUGA_SKYPE(&quot;i=%d globals.SKYPIAX_INTERFACES[%d].interface_id=%s\n&quot;, SKYPIAX_P_LOG, i, i, globals.SKYPIAX_INTERFACES[i].interface_id);
+                                DEBUGA_SKYPE(&quot;i=%d globals.SKYPIAX_INTERFACES[%d].X11_display=%s\n&quot;, SKYPIAX_P_LOG, i, i, globals.SKYPIAX_INTERFACES[i].X11_display);
+                                DEBUGA_SKYPE(&quot;i=%d globals.SKYPIAX_INTERFACES[%d].name=%s\n&quot;, SKYPIAX_P_LOG, i, i, globals.SKYPIAX_INTERFACES[i].name);
+                                DEBUGA_SKYPE(&quot;i=%d globals.SKYPIAX_INTERFACES[%d].context=%s\n&quot;, SKYPIAX_P_LOG, i, i, globals.SKYPIAX_INTERFACES[i].context);
+                                DEBUGA_SKYPE(&quot;i=%d globals.SKYPIAX_INTERFACES[%d].dialplan=%s\n&quot;, SKYPIAX_P_LOG, i, i, globals.SKYPIAX_INTERFACES[i].dialplan);
+                                DEBUGA_SKYPE(&quot;i=%d globals.SKYPIAX_INTERFACES[%d].destination=%s\n&quot;, SKYPIAX_P_LOG, i, i, globals.SKYPIAX_INTERFACES[i].destination);
+                                DEBUGA_SKYPE(&quot;i=%d globals.SKYPIAX_INTERFACES[%d].context=%s\n&quot;, SKYPIAX_P_LOG, i, i, globals.SKYPIAX_INTERFACES[i].context);
+                                DEBUGA_SKYPE(&quot;i=%d globals.SKYPIAX_INTERFACES[%d].report_incoming_chatmessages=%d\n&quot;, SKYPIAX_P_LOG, i, i,
+                                                         globals.SKYPIAX_INTERFACES[i].report_incoming_chatmessages);
+                        }
+                }
+        }
+
+        switch_mutex_unlock(globals.mutex);
+        switch_xml_free(xml);
+
+        return SWITCH_STATUS_SUCCESS;
+}
+static switch_status_t chat_send(const char *proto, const char *from, const char *to, const char *subject, const char *body, const char *type,
+                                                                 const char *hint)
+{
+        //char *user, *host, *f_user = NULL, *ffrom = NULL, *f_host = NULL, *f_resource = NULL;
+        char *user = NULL, *host, *f_user = NULL, *f_host = NULL, *f_resource = NULL;
+        //mdl_profile_t *profile = NULL;
+        private_t *tech_pvt = NULL;
+        int i = 0, found = 0, tried = 0;
+        char skype_msg[1024];
+
+        switch_assert(proto != NULL);
+
+        DEBUGA_SKYPE(&quot;chat_send(proto=%s, from=%s, to=%s, subject=%s, body=%s, type=%s, hint=%s)\n&quot;, SKYPIAX_P_LOG, proto, from, to, subject, body, type,
+                                 hint ? hint : &quot;NULL&quot;);
+
+        if (!to || !strlen(to)) {
+                ERRORA(&quot;Missing To: header.\n&quot;, SKYPIAX_P_LOG);
+                return SWITCH_STATUS_SUCCESS;
+        }
+
+        if ((!from &amp;&amp; !hint) || (!strlen(from) &amp;&amp; !strlen(hint))) {
+                ERRORA(&quot;Missing From: AND Hint: headers.\n&quot;, SKYPIAX_P_LOG);
+                return SWITCH_STATUS_SUCCESS;
+        }
+
+        if (from &amp;&amp; (f_user = strdup(from))) {
+                if ((f_host = strchr(f_user, '@'))) {
+                        *f_host++ = '\0';
+                        if ((f_resource = strchr(f_host, '/'))) {
+                                *f_resource++ = '\0';
+                        }
+                }
+        }
+
+        if (to &amp;&amp; (user = strdup(to))) {
+                if ((host = strchr(user, '@'))) {
+                        *host++ = '\0';
+                }
+                //if (!strcmp(proto, MDL_CHAT_PROTO)) {
+
+                DEBUGA_SKYPE(&quot;chat_send(proto=%s, from=%s, to=%s, subject=%s, body=%s, type=%s, hint=%s)\n&quot;, SKYPIAX_P_LOG, proto, from, to, subject, body, type,
+                                         hint ? hint : &quot;NULL&quot;);
+                if (hint &amp;&amp; strlen(hint)) {
+                        //in hint we receive the interface name to use
+                        for (i = 0; !found &amp;&amp; i &lt; SKYPIAX_MAX_INTERFACES; i++) {
+                                if (strlen(globals.SKYPIAX_INTERFACES[i].name)
+                                        &amp;&amp; (strncmp(globals.SKYPIAX_INTERFACES[i].name, hint, strlen(hint)) == 0)) {
+                                        tech_pvt = &amp;globals.SKYPIAX_INTERFACES[i];
+                                        DEBUGA_SKYPE(&quot;Using interface: globals.SKYPIAX_INTERFACES[%d].name=|||%s|||\n&quot;, SKYPIAX_P_LOG, i, globals.SKYPIAX_INTERFACES[i].name);
+                                        found = 1;
+                                        break;
+                                }
+                        }
+                } else {
+                        //we have no a predefined interface name to use (hint is NULL), so let's choose an interface from the username (from)
+                        for (i = 0; !found &amp;&amp; i &lt; SKYPIAX_MAX_INTERFACES; i++) {
+                                if (strlen(globals.SKYPIAX_INTERFACES[i].name)
+                                        &amp;&amp; (strncmp(globals.SKYPIAX_INTERFACES[i].skype_user, from, strlen(from)) == 0)) {
+                                        tech_pvt = &amp;globals.SKYPIAX_INTERFACES[i];
+                                        DEBUGA_SKYPE(&quot;Using interface: globals.SKYPIAX_INTERFACES[%d].name=|||%s|||\n&quot;, SKYPIAX_P_LOG, i, globals.SKYPIAX_INTERFACES[i].name);
+                                        found = 1;
+                                        break;
+                                }
+                        }
+                }
+                if (!found) {
+                        ERRORA(&quot;ERROR: A Skypiax interface with name='%s' or one with skypeuser='%s' was not found\n&quot;, SKYPIAX_P_LOG, hint ? hint : &quot;NULL&quot;,
+                                   from ? from : &quot;NULL&quot;);
+                        goto end;
+                } else {
+
+                        snprintf(skype_msg, sizeof(skype_msg), &quot;CHAT CREATE %s&quot;, to);
+                        skypiax_signaling_write(tech_pvt, skype_msg);
+                        switch_sleep(1000);
+                }
+                //} else {
+                //FIXME don't know how to do here, let's hope this is correct
+                //char *p;
+                //ffrom = switch_mprintf(&quot;%s+%s&quot;, proto, from);
+                //from = ffrom;
+                //if ((p = strchr(from, '/'))) {
+                //*p = '\0';
+                //}
+                //NOTICA(&quot;chat_send(proto=%s, from=%s, to=%s, subject=%s, body=%s, type=%s, hint=%s)\n&quot;, SKYPIAX_P_LOG, proto, from, to, subject, body, type, hint?hint:&quot;NULL&quot;);
+                //switch_core_chat_send(proto, proto, from, to, subject, body, type, hint);
+                //return SWITCH_STATUS_SUCCESS;
+                //}
+
+                found = 0;
+
+                while (!found) {
+                        for (i = 0; i &lt; MAX_CHATS; i++) {
+                                if (!strcmp(tech_pvt-&gt;chats[i].dialog_partner, to)) {
+                                        snprintf(skype_msg, sizeof(skype_msg), &quot;CHATMESSAGE %s %s&quot;, tech_pvt-&gt;chats[i].chatname, body);
+                                        skypiax_signaling_write(tech_pvt, skype_msg);
+                                        found = 1;
+                                        break;
+                                }
+                        }
+                        if (found) {
+                                break;
+                        }
+                        if (tried &gt; 1000) {
+                                ERRORA(&quot;No chat with dialog_partner='%s' was found\n&quot;, SKYPIAX_P_LOG, to);
+                                break;
+                        }
+                        switch_sleep(1000);
+                }
+
+        }
+  end:
+        switch_safe_free(user);
+        switch_safe_free(f_user);
+        return SWITCH_STATUS_SUCCESS;
+}
+
+
+SWITCH_MODULE_LOAD_FUNCTION(mod_skypiax_load)
+{
+        switch_api_interface_t *commands_api_interface;
+        switch_chat_interface_t *chat_interface;
+
+        skypiax_module_pool = pool;
+        memset(&amp;globals, '\0', sizeof(globals));
+
+        running = 1;
+
+        if (load_config(FULL_RELOAD) != SWITCH_STATUS_SUCCESS) {
+                running = 0;
+                return SWITCH_STATUS_FALSE;
+        }
+
+        if (switch_event_reserve_subclass(MY_EVENT_INCOMING_CHATMESSAGE) != SWITCH_STATUS_SUCCESS) {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;Couldn't register subclass!\n&quot;);
+                return SWITCH_STATUS_GENERR;
+        }
+
+        *module_interface = switch_loadable_module_create_module_interface(pool, modname);
+        skypiax_endpoint_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE);
+        skypiax_endpoint_interface-&gt;interface_name = &quot;skypiax&quot;;
+        skypiax_endpoint_interface-&gt;io_routines = &amp;skypiax_io_routines;
+        skypiax_endpoint_interface-&gt;state_handler = &amp;skypiax_state_handlers;
+
+        if (running) {
+
+                SWITCH_ADD_API(commands_api_interface, &quot;sk&quot;, &quot;Skypiax console commands&quot;, sk_function, SK_SYNTAX);
+                SWITCH_ADD_API(commands_api_interface, &quot;skypiax&quot;, &quot;Skypiax interface commands&quot;, skypiax_function, SKYPIAX_SYNTAX);
+                SWITCH_ADD_API(commands_api_interface, &quot;skypiax_chat&quot;, &quot;Skypiax_chat interface remote_skypename TEXT&quot;, skypiax_chat_function, SKYPIAX_CHAT_SYNTAX);
+                SWITCH_ADD_CHAT(chat_interface, MDL_CHAT_PROTO, chat_send);
+
+
+                /* indicate that the module should continue to be loaded */
+                return SWITCH_STATUS_SUCCESS;
+        } else
+                return SWITCH_STATUS_FALSE;
+}
+
+SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_skypiax_shutdown)
+{
+        int x;
+        private_t *tech_pvt = NULL;
+        switch_status_t status;
+        unsigned int howmany = 8;
+        int interface_id;
+
+        running = 0;
+
+        for (interface_id = 0; interface_id &lt; SKYPIAX_MAX_INTERFACES; interface_id++) {
+                tech_pvt = &amp;globals.SKYPIAX_INTERFACES[interface_id];
+
+                if (strlen(globals.SKYPIAX_INTERFACES[interface_id].name)) {
+                        if (globals.SKYPIAX_INTERFACES[interface_id].skypiax_signaling_thread) {
+#ifdef WIN32
+                                switch_file_write(tech_pvt-&gt;SkypiaxHandles.fdesc[1], &quot;sciutati&quot;, &amp;howmany);        // let's the controldev_thread die
+#else /* WIN32 */
+                                howmany = write(tech_pvt-&gt;SkypiaxHandles.fdesc[1], &quot;sciutati&quot;, howmany);
+#endif /* WIN32 */
+                        }
+
+                        if (globals.SKYPIAX_INTERFACES[interface_id].skypiax_api_thread) {
+#ifdef WIN32
+                                if (SendMessage(tech_pvt-&gt;SkypiaxHandles.win32_hInit_MainWindowHandle, WM_DESTROY, 0, 0) == FALSE) {        // let's the skypiax_api_thread_func die
+                                        DEBUGA_SKYPE(&quot;got FALSE here, thread probably was already dead. GetLastError returned: %d\n&quot;, SKYPIAX_P_LOG, GetLastError());
+                                        globals.SKYPIAX_INTERFACES[interface_id].skypiax_api_thread = NULL;
+                                }
+#else
+                                if (tech_pvt-&gt;SkypiaxHandles.disp) {
+                                        XEvent e;
+                                        Atom atom1 = XInternAtom(tech_pvt-&gt;SkypiaxHandles.disp, &quot;SKYPECONTROLAPI_MESSAGE_BEGIN&quot;,
+                                                                                         False);
+                                        memset(&amp;e, 0, sizeof(e));
+                                        e.xclient.type = ClientMessage;
+                                        e.xclient.message_type = atom1;        /*  leading message */
+                                        e.xclient.display = tech_pvt-&gt;SkypiaxHandles.disp;
+                                        e.xclient.window = tech_pvt-&gt;SkypiaxHandles.skype_win;
+                                        e.xclient.format = 8;
+
+                                        XSendEvent(tech_pvt-&gt;SkypiaxHandles.disp, tech_pvt-&gt;SkypiaxHandles.win, False, 0, &amp;e);
+                                        XSync(tech_pvt-&gt;SkypiaxHandles.disp, False);
+                                }
+#endif
+                        }
+                        x = 10;
+                        while (x) {                        //FIXME 0.5 seconds?
+                                x--;
+                                switch_yield(50000);
+                        }
+                        if (globals.SKYPIAX_INTERFACES[interface_id].skypiax_signaling_thread) {
+                                switch_thread_join(&amp;status, globals.SKYPIAX_INTERFACES[interface_id].skypiax_signaling_thread);
+                        }
+                        if (globals.SKYPIAX_INTERFACES[interface_id].skypiax_api_thread) {
+                                switch_thread_join(&amp;status, globals.SKYPIAX_INTERFACES[interface_id].skypiax_api_thread);
+                        }
+#ifndef WIN32
+                        WARNINGA(&quot;SHUTDOWN interface_id=%d\n&quot;, SKYPIAX_P_LOG, interface_id);
+                        shutdown(tech_pvt-&gt;audiopipe_cli[0], 2);
+                        close(tech_pvt-&gt;audiopipe_cli[0]);
+                        shutdown(tech_pvt-&gt;audiopipe_cli[1], 2);
+                        close(tech_pvt-&gt;audiopipe_cli[1]);
+                        shutdown(tech_pvt-&gt;audiopipe_srv[0], 2);
+                        close(tech_pvt-&gt;audiopipe_srv[0]);
+                        shutdown(tech_pvt-&gt;audiopipe_srv[1], 2);
+                        close(tech_pvt-&gt;audiopipe_srv[1]);
+                        shutdown(tech_pvt-&gt;SkypiaxHandles.fdesc[0], 2);
+                        close(tech_pvt-&gt;SkypiaxHandles.fdesc[0]);
+                        shutdown(tech_pvt-&gt;SkypiaxHandles.fdesc[1], 2);
+                        close(tech_pvt-&gt;SkypiaxHandles.fdesc[1]);
+#endif /* WIN32 */
+                }
+
+        }
+        switch_event_free_subclass(MY_EVENT_INCOMING_CHATMESSAGE);
+
+        switch_safe_free(globals.dialplan);
+        switch_safe_free(globals.context);
+        switch_safe_free(globals.destination);
+        switch_safe_free(globals.codec_string);
+        switch_safe_free(globals.codec_rates_string);
+
+        return SWITCH_STATUS_SUCCESS;
+}
+
+void *SWITCH_THREAD_FUNC skypiax_do_tcp_srv_thread(switch_thread_t * thread, void *obj)
+{
+        return skypiax_do_tcp_srv_thread_func(obj);
+}
+
+void *SWITCH_THREAD_FUNC skypiax_do_tcp_cli_thread(switch_thread_t * thread, void *obj)
+{
+        return skypiax_do_tcp_cli_thread_func(obj);
+}
+
+void *SWITCH_THREAD_FUNC skypiax_do_skypeapi_thread(switch_thread_t * thread, void *obj)
+{
+        return skypiax_do_skypeapi_thread_func(obj);
+}
+
+int dtmf_received(private_t * tech_pvt, char *value)
+{
+        switch_core_session_t *session = NULL;
+        switch_channel_t *channel = NULL;
+
+        session = switch_core_session_locate(tech_pvt-&gt;session_uuid_str);
+        channel = switch_core_session_get_channel(session);
+
+        if (channel) {
+
+                //if (!switch_channel_test_flag(channel, CF_BRIDGED)) {
+
+                        switch_dtmf_t dtmf = { (char) value[0], switch_core_default_dtmf_duration(0) };
+                        DEBUGA_SKYPE(&quot;received DTMF %c on channel %s\n&quot;, SKYPIAX_P_LOG, dtmf.digit, switch_channel_get_name(channel));
+                        switch_mutex_lock(tech_pvt-&gt;flag_mutex);
+                        //FIXME: why sometimes DTMFs from here do not seems to be get by FS?
+                        switch_channel_queue_dtmf(channel, &amp;dtmf);
+                        switch_set_flag(tech_pvt, TFLAG_DTMF);
+                        switch_mutex_unlock(tech_pvt-&gt;flag_mutex);
+                //} else {
+                        //NOTICA
+                                //(&quot;received a DTMF on channel %s, but we're BRIDGED, so let's NOT relay it out of band\n&quot;, SKYPIAX_P_LOG, switch_channel_get_name(channel));
+                //}
+        } else {
+                WARNINGA(&quot;received %c DTMF, but no channel?\n&quot;, SKYPIAX_P_LOG, value[0]);
+        }
+        switch_core_session_rwunlock(session);
+
+        return 0;
+}
+
+int start_audio_threads(private_t * tech_pvt)
+{
+        switch_threadattr_t *thd_attr = NULL;
+
+        switch_threadattr_create(&amp;thd_attr, skypiax_module_pool);
+        switch_threadattr_detach_set(thd_attr, 1);
+        switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
+        if (switch_thread_create(&amp;tech_pvt-&gt;tcp_srv_thread, thd_attr, skypiax_do_tcp_srv_thread, tech_pvt, skypiax_module_pool) == SWITCH_STATUS_SUCCESS) {
+                DEBUGA_SKYPE(&quot;started tcp_srv_thread thread.\n&quot;, SKYPIAX_P_LOG);
+        } else {
+                ERRORA(&quot;failed to start tcp_srv_thread thread.\n&quot;, SKYPIAX_P_LOG);
+                return -1;
+        }
+
+        switch_threadattr_create(&amp;thd_attr, skypiax_module_pool);
+        switch_threadattr_detach_set(thd_attr, 1);
+        switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
+        if (switch_thread_create(&amp;tech_pvt-&gt;tcp_cli_thread, thd_attr, skypiax_do_tcp_cli_thread, tech_pvt, skypiax_module_pool) == SWITCH_STATUS_SUCCESS) {
+                DEBUGA_SKYPE(&quot;started tcp_cli_thread thread.\n&quot;, SKYPIAX_P_LOG);
+        } else {
+                ERRORA(&quot;failed to start tcp_cli_thread thread.\n&quot;, SKYPIAX_P_LOG);
+                return -1;
+        }
+        switch_sleep(100000);
+
+        if (tech_pvt-&gt;tcp_cli_thread == NULL || tech_pvt-&gt;tcp_srv_thread == NULL) {
+                ERRORA(&quot;tcp_cli_thread or tcp_srv_thread exited\n&quot;, SKYPIAX_P_LOG);
+                return -1;
+        }
+
+        return 0;
+}
+
+int new_inbound_channel(private_t * tech_pvt)
+{
+        switch_core_session_t *session = NULL;
+        switch_channel_t *channel = NULL;
+
+        if ((session = switch_core_session_request(skypiax_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, NULL)) != 0) {
+                DEBUGA_SKYPE(&quot;2 SESSION_REQUEST %s\n&quot;, SKYPIAX_P_LOG, switch_core_session_get_uuid(session));
+                switch_core_session_add_stream(session, NULL);
+                channel = switch_core_session_get_channel(session);
+                if (!channel) {
+                        ERRORA(&quot;Doh! no channel?\n&quot;, SKYPIAX_P_LOG);
+                        switch_core_session_destroy(&amp;session);
+                        return 0;
+                }
+                if (skypiax_tech_init(tech_pvt, session) != SWITCH_STATUS_SUCCESS) {
+                        ERRORA(&quot;Doh! no tech_init?\n&quot;, SKYPIAX_P_LOG);
+                        switch_core_session_destroy(&amp;session);
+                        return 0;
+                }
+
+                if ((tech_pvt-&gt;caller_profile =
+                         switch_caller_profile_new(switch_core_session_get_pool(session), &quot;skypiax&quot;,
+                                                                           tech_pvt-&gt;dialplan, tech_pvt-&gt;callid_name,
+                                                                           tech_pvt-&gt;callid_number, NULL, NULL, NULL, NULL, &quot;mod_skypiax&quot;, tech_pvt-&gt;context, tech_pvt-&gt;destination)) != 0) {
+                        char name[128];
+                        //switch_snprintf(name, sizeof(name), &quot;skypiax/%s/%s&quot;, tech_pvt-&gt;name, tech_pvt-&gt;caller_profile-&gt;destination_number);
+                        switch_snprintf(name, sizeof(name), &quot;skypiax/%s&quot;, tech_pvt-&gt;name);
+                        switch_channel_set_name(channel, name);
+                        switch_channel_set_caller_profile(channel, tech_pvt-&gt;caller_profile);
+                }
+                switch_channel_set_state(channel, CS_INIT);
+                if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) {
+                        ERRORA(&quot;Error spawning thread\n&quot;, SKYPIAX_P_LOG);
+                        switch_core_session_destroy(&amp;session);
+                        return 0;
+                }
+        }
+        if (channel) {
+                switch_channel_mark_answered(channel);
+        }
+
+        DEBUGA_SKYPE(&quot;new_inbound_channel\n&quot;, SKYPIAX_P_LOG);
+
+        return 0;
+}
+
+int remote_party_is_ringing(private_t * tech_pvt)
+{
+        switch_core_session_t *session = NULL;
+        switch_channel_t *channel = NULL;
+
+        if (!zstr(tech_pvt-&gt;session_uuid_str)) {
+                session = switch_core_session_locate(tech_pvt-&gt;session_uuid_str);
+        } else {
+                ERRORA(&quot;No session???\n&quot;, SKYPIAX_P_LOG);
+                goto done;
+        }
+        if (session) {
+                channel = switch_core_session_get_channel(session);
+        } else {
+                ERRORA(&quot;No session???\n&quot;, SKYPIAX_P_LOG);
+                goto done;
+        }
+        if (channel) {
+                switch_channel_mark_ring_ready(channel);
+                DEBUGA_SKYPE(&quot;skype_call: REMOTE PARTY RINGING\n&quot;, SKYPIAX_P_LOG);
+        } else {
+                ERRORA(&quot;No channel???\n&quot;, SKYPIAX_P_LOG);
+        }
+
+        switch_core_session_rwunlock(session);
+
+  done:
+        return 0;
+}
+
+int remote_party_is_early_media(private_t * tech_pvt)
+{
+        switch_core_session_t *session = NULL;
+        switch_channel_t *channel = NULL;
+
+        if (!zstr(tech_pvt-&gt;session_uuid_str)) {
+                session = switch_core_session_locate(tech_pvt-&gt;session_uuid_str);
+        } else {
+                ERRORA(&quot;No session???\n\n\n&quot;, SKYPIAX_P_LOG);
+                //TODO: kill the bastard
+                goto done;
+        }
+        if (session) {
+                channel = switch_core_session_get_channel(session);
+                switch_core_session_add_stream(session, NULL);
+        } else {
+                ERRORA(&quot;No session???\n&quot;, SKYPIAX_P_LOG);
+                //TODO: kill the bastard
+                goto done;
+        }
+        if (channel) {
+                switch_channel_mark_pre_answered(channel);
+                DEBUGA_SKYPE(&quot;skype_call: REMOTE PARTY EARLY MEDIA\n&quot;, SKYPIAX_P_LOG);
+        } else {
+                ERRORA(&quot;No channel???\n&quot;, SKYPIAX_P_LOG);
+                //TODO: kill the bastard
+        }
+
+        switch_core_session_rwunlock(session);
+
+  done:
+        return 0;
+}
+
+int outbound_channel_answered(private_t * tech_pvt)
+{
+        switch_core_session_t *session = NULL;
+        switch_channel_t *channel = NULL;
+
+        if (!zstr(tech_pvt-&gt;session_uuid_str)) {
+                session = switch_core_session_locate(tech_pvt-&gt;session_uuid_str);
+        } else {
+                ERRORA(&quot;No session???\n&quot;, SKYPIAX_P_LOG);
+                goto done;
+        }
+        if (session) {
+                channel = switch_core_session_get_channel(session);
+        } else {
+                ERRORA(&quot;No channel???\n&quot;, SKYPIAX_P_LOG);
+                goto done;
+        }
+        if (channel) {
+                switch_channel_mark_answered(channel);
+                //DEBUGA_SKYPE(&quot;skype_call: %s, answered\n&quot;, SKYPIAX_P_LOG, id);
+        } else {
+                ERRORA(&quot;No channel???\n&quot;, SKYPIAX_P_LOG);
+        }
+
+        switch_core_session_rwunlock(session);
+
+  done:
+        DEBUGA_SKYPE(&quot;outbound_channel_answered!\n&quot;, SKYPIAX_P_LOG);
+
+        return 0;
+}
+
+private_t *find_available_skypiax_interface_rr(private_t * tech_pvt_calling)
+{
+        private_t *tech_pvt = NULL;
+        int i;
+        //int num_interfaces = SKYPIAX_MAX_INTERFACES; 
+        //int num_interfaces = globals.real_interfaces;
+
+        switch_mutex_lock(globals.mutex);
+
+        /* Fact is the real interface start from 1 */
+        //XXX no, is just a convention, but you can have it start from 0. I do not, for aestetic reasons :-)  
+        //if (globals.next_interface == 0) globals.next_interface = 1;
+
+        for (i = 0; i &lt; SKYPIAX_MAX_INTERFACES; i++) {
+                int interface_id;
+
+                interface_id = globals.next_interface;
+                //interface_id = interface_id &lt; SKYPIAX_MAX_INTERFACES ? interface_id : interface_id - SKYPIAX_MAX_INTERFACES + 1;
+                globals.next_interface = interface_id + 1 &lt; SKYPIAX_MAX_INTERFACES ? interface_id + 1 : 0;
+
+                if (strlen(globals.SKYPIAX_INTERFACES[interface_id].name)) {
+                        int skype_state = 0;
+
+                        tech_pvt = &amp;globals.SKYPIAX_INTERFACES[interface_id];
+                        skype_state = tech_pvt-&gt;interface_state;
+                        //DEBUGA_SKYPE(&quot;skype interface: %d, name: %s, state: %d\n&quot;, SKYPIAX_P_LOG, interface_id, globals.SKYPIAX_INTERFACES[interface_id].name, skype_state);
+                        if ((tech_pvt_calling ? strcmp(tech_pvt-&gt;skype_user, tech_pvt_calling-&gt;skype_user) : 1)
+                                &amp;&amp; (SKYPIAX_STATE_DOWN == skype_state || 0 == skype_state) &amp;&amp; (tech_pvt-&gt;skype_callflow == CALLFLOW_STATUS_FINISHED
+                                                                                                                                                           || 0 == tech_pvt-&gt;skype_callflow)) {
+                                DEBUGA_SKYPE(&quot;returning as available skype interface name: %s, state: %d callflow: %d\n&quot;, SKYPIAX_P_LOG, tech_pvt-&gt;name, skype_state,
+                                                         tech_pvt-&gt;skype_callflow);
+                                /*set to Dialing state to avoid other thread fint it, don't know if it is safe */
+                                //XXX no, it's not safe 
+                                if (tech_pvt_calling == NULL) {
+                                        tech_pvt-&gt;interface_state = SKYPIAX_STATE_SELECTED;
+                                }
+
+                                switch_mutex_unlock(globals.mutex);
+                                return tech_pvt;
+                        }
+                }                                                // else {
+                //DEBUGA_SKYPE(&quot;Skype interface: %d blank!! A hole here means we cannot hunt the last interface.\n&quot;, SKYPIAX_P_LOG, interface_id);
+                //}
+        }
+
+        switch_mutex_unlock(globals.mutex);
+        return NULL;
+}
+
+SWITCH_STANDARD_API(sk_function)
+{
+        char *mycmd = NULL, *argv[10] = { 0 };
+        int argc = 0;
+
+        if (globals.sk_console)
+                stream-&gt;write_function(stream, &quot;sk console is: |||%s|||\n&quot;, globals.sk_console-&gt;name);
+        else
+                stream-&gt;write_function(stream, &quot;sk console is NOT yet assigned\n&quot;);
+
+        if (!zstr(cmd) &amp;&amp; (mycmd = strdup(cmd))) {
+                argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+        }
+
+        if (!argc || !argv[0]) {
+                stream-&gt;write_function(stream, &quot;%s&quot;, SK_SYNTAX);
+                goto end;
+        }
+
+        if (!strcasecmp(argv[0], &quot;list&quot;)) {
+                int i;
+                int ib = 0;
+                int ib_failed = 0;
+                int ob = 0;
+                int ob_failed = 0;
+                char next_flag_char = ' ';
+
+                stream-&gt;write_function(stream, &quot;F ID\t    Name    \tIB (F/T)    OB (F/T)\tState\tCallFlw\t\tUUID\n&quot;);
+                stream-&gt;write_function(stream, &quot;= ====\t  ========  \t=======     =======\t======\t============\t======\n&quot;);
+
+                for (i = 0; i &lt; SKYPIAX_MAX_INTERFACES; i++) {
+                        next_flag_char = i == globals.next_interface ? '*' : ' ';
+                        ib += globals.SKYPIAX_INTERFACES[i].ib_calls;
+                        ib_failed += globals.SKYPIAX_INTERFACES[i].ib_failed_calls;
+                        ob += globals.SKYPIAX_INTERFACES[i].ob_calls;
+                        ob_failed += globals.SKYPIAX_INTERFACES[i].ob_failed_calls;
+
+                        if (strlen(globals.SKYPIAX_INTERFACES[i].name)) {
+                                stream-&gt;write_function(stream,
+                                                                           &quot;%c %d\t[%s]\t%3u/%u\t%6u/%u\t%s\t%s\t%s\n&quot;,
+                                                                           next_flag_char,
+                                                                           i, globals.SKYPIAX_INTERFACES[i].name,
+                                                                           globals.SKYPIAX_INTERFACES[i].ib_failed_calls,
+                                                                           globals.SKYPIAX_INTERFACES[i].ib_calls,
+                                                                           globals.SKYPIAX_INTERFACES[i].ob_failed_calls,
+                                                                           globals.SKYPIAX_INTERFACES[i].ob_calls,
+                                                                           interface_status[globals.SKYPIAX_INTERFACES[i].interface_state],
+                                                                           skype_callflow[globals.SKYPIAX_INTERFACES[i].skype_callflow], globals.SKYPIAX_INTERFACES[i].session_uuid_str);
+                        } else if (argc &gt; 1 &amp;&amp; !strcasecmp(argv[1], &quot;full&quot;)) {
+                                stream-&gt;write_function(stream, &quot;%c\t%d\n&quot;, next_flag_char, i);
+                        }
+
+                }
+                stream-&gt;write_function(stream, &quot;\nTotal Interfaces: %d  IB Calls(Failed/Total): %ld/%ld  OB Calls(Failed/Total): %ld/%ld\n&quot;,
+                                                           globals.real_interfaces &gt; 0 ? globals.real_interfaces - 1 : 0, ib_failed, ib, ob_failed, ob);
+
+        } else if (!strcasecmp(argv[0], &quot;console&quot;)) {
+                int i;
+                int found = 0;
+
+                if (argc == 2) {
+                        for (i = 0; !found &amp;&amp; i &lt; SKYPIAX_MAX_INTERFACES; i++) {
+                                /* we've been asked for a normal interface name, or we have not found idle interfaces to serve as the &quot;ANY&quot; interface */
+                                if (strlen(globals.SKYPIAX_INTERFACES[i].name)
+                                        &amp;&amp; (strncmp(globals.SKYPIAX_INTERFACES[i].name, argv[1], strlen(argv[1])) == 0)) {
+                                        globals.sk_console = &amp;globals.SKYPIAX_INTERFACES[i];
+                                        stream-&gt;write_function(stream,
+                                                                                   &quot;sk console is now: globals.SKYPIAX_INTERFACES[%d].name=|||%s|||\n&quot;, i, globals.SKYPIAX_INTERFACES[i].name);
+                                        stream-&gt;write_function(stream, &quot;sk console is: |||%s|||\n&quot;, globals.sk_console-&gt;name);
+                                        found = 1;
+                                        break;
+                                }
+
+                        }
+                        if (!found)
+                                stream-&gt;write_function(stream, &quot;ERROR: A Skypiax interface with name='%s' was not found\n&quot;, argv[1]);
+                } else {
+
+                        stream-&gt;write_function(stream, &quot;-ERR Usage: sk console interface_name\n&quot;);
+                        goto end;
+                }
+
+        } else if (!strcasecmp(argv[0], &quot;ciapalino&quot;)) {
+
+/* BEGIN: Changes heres */
+        } else if (!strcasecmp(argv[0], &quot;reload&quot;)) {
+                if (load_config(SOFT_RELOAD) != SWITCH_STATUS_SUCCESS) {
+                        stream-&gt;write_function(stream, &quot;sk reload failed\n&quot;);
+                } else {
+                        stream-&gt;write_function(stream, &quot;sk reload success\n&quot;);
+                }
+        } else if (!strcasecmp(argv[0], &quot;remove&quot;)) {
+                if (argc == 2) {
+                        if (remove_interface(argv[1]) == SWITCH_STATUS_SUCCESS) {
+                                if (interface_exists(argv[1]) == SWITCH_STATUS_SUCCESS) {
+                                        stream-&gt;write_function(stream, &quot;sk remove '%s' failed\n&quot;, argv[1]);
+                                } else {
+                                        stream-&gt;write_function(stream, &quot;sk remove '%s' success\n&quot;, argv[1]);
+                                }
+                        }
+                } else {
+                        stream-&gt;write_function(stream, &quot;-ERR Usage: sk remove interface_name\n&quot;);
+                        goto end;
+                }
+/* END: Changes heres */
+
+        } else {
+                if (globals.sk_console)
+                        skypiax_signaling_write(globals.sk_console, (char *) cmd);
+                else
+                        stream-&gt;write_function(stream, &quot;sk console is NOT yet assigned\n&quot;);
+        }
+  end:
+        switch_safe_free(mycmd);
+
+        return SWITCH_STATUS_SUCCESS;
+}
+
+SWITCH_STANDARD_API(skypiax_function)
+{
+        char *mycmd = NULL, *argv[10] = { 0 };
+        int argc = 0;
+        private_t *tech_pvt = NULL;
+
+        if (!zstr(cmd) &amp;&amp; (mycmd = strdup(cmd))) {
+                argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+        }
+
+        if (!argc) {
+                stream-&gt;write_function(stream, &quot;ERROR, usage: %s&quot;, SKYPIAX_SYNTAX);
+                goto end;
+        }
+
+        if (argc &lt; 2) {
+                stream-&gt;write_function(stream, &quot;ERROR, usage: %s&quot;, SKYPIAX_SYNTAX);
+                goto end;
+        }
+
+        if (argv[0]) {
+                int i;
+                int found = 0;
+
+                for (i = 0; !found &amp;&amp; i &lt; SKYPIAX_MAX_INTERFACES; i++) {
+                        /* we've been asked for a normal interface name, or we have not found idle interfaces to serve as the &quot;ANY&quot; interface */
+                        if (strlen(globals.SKYPIAX_INTERFACES[i].name)
+                                &amp;&amp; (strncmp(globals.SKYPIAX_INTERFACES[i].name, argv[0], strlen(argv[0])) == 0)) {
+                                tech_pvt = &amp;globals.SKYPIAX_INTERFACES[i];
+                                stream-&gt;write_function(stream, &quot;Using interface: globals.SKYPIAX_INTERFACES[%d].name=|||%s|||\n&quot;, i, globals.SKYPIAX_INTERFACES[i].name);
+                                found = 1;
+                                break;
+                        }
+
+                }
+                if (!found) {
+                        stream-&gt;write_function(stream, &quot;ERROR: A Skypiax interface with name='%s' was not found\n&quot;, argv[0]);
+                        switch_safe_free(mycmd);
+
+                        return SWITCH_STATUS_SUCCESS;
+                } else {
+                        skypiax_signaling_write(tech_pvt, (char *) &amp;cmd[strlen(argv[0]) + 1]);
+                }
+        } else {
+                stream-&gt;write_function(stream, &quot;ERROR, usage: %s&quot;, SKYPIAX_SYNTAX);
+        }
+  end:
+        switch_safe_free(mycmd);
+
+        return SWITCH_STATUS_SUCCESS;
+}
+
+int skypiax_answer(private_t * tech_pvt, char *id, char *value)
+{
+        char msg_to_skype[1024];
+        int i;
+        int found = 0;
+        private_t *giovatech;
+        struct timeval timenow;
+
+        switch_mutex_lock(globals.mutex);
+
+        gettimeofday(&amp;timenow, NULL);
+        for (i = 0; !found &amp;&amp; i &lt; SKYPIAX_MAX_INTERFACES; i++) {
+                if (strlen(globals.SKYPIAX_INTERFACES[i].name)) {
+
+                        giovatech = &amp;globals.SKYPIAX_INTERFACES[i];
+                        //NOTICA(&quot;interface=%d, name=%s, giovatech-&gt;skype_call_id=%s, giovatech-&gt;interface_state=%d, giovatech-&gt;skype_user=%s, tech_pvt-&gt;skype_user=%s, giovatech-&gt;callid_number=%s, value=%s, delta=%ld  500000\n&quot;, SKYPIAX_P_LOG, i, giovatech-&gt;name, giovatech-&gt;skype_call_id, giovatech-&gt;interface_state, giovatech-&gt;skype_user, tech_pvt-&gt;skype_user, giovatech-&gt;callid_number, value, (((timenow.tv_sec - giovatech-&gt;answer_time.tv_sec) * 1000000) + (timenow.tv_usec - giovatech-&gt;answer_time.tv_usec)) );
+                        if (strlen(giovatech-&gt;skype_call_id) &amp;&amp; (giovatech-&gt;interface_state != SKYPIAX_STATE_DOWN) &amp;&amp; (!strcmp(giovatech-&gt;skype_user, tech_pvt-&gt;skype_user)) &amp;&amp; (!strcmp(giovatech-&gt;callid_number, value)) &amp;&amp; ((((timenow.tv_sec - giovatech-&gt;answer_time.tv_sec) * 1000000) + (timenow.tv_usec - giovatech-&gt;answer_time.tv_usec)) &lt; 1000000)) {        //XXX 1.5sec - can have a max of 1 call coming from the same skypename to the same skypename each 1.5 seconds
+                                found = 1;
+                                DEBUGA_SKYPE
+                                        (&quot;FOUND  (name=%s, giovatech-&gt;interface_state=%d != SKYPIAX_STATE_DOWN) &amp;&amp; (giovatech-&gt;skype_user=%s == tech_pvt-&gt;skype_user=%s) &amp;&amp; (giovatech-&gt;callid_number=%s == value=%s)\n&quot;,
+                                         SKYPIAX_P_LOG, giovatech-&gt;name, giovatech-&gt;interface_state,
+                                         giovatech-&gt;skype_user, tech_pvt-&gt;skype_user, giovatech-&gt;callid_number, value)
+                                        if (tech_pvt-&gt;interface_state == SKYPIAX_STATE_PRERING) {
+                                        tech_pvt-&gt;interface_state = SKYPIAX_STATE_DOWN;
+                                } else if (tech_pvt-&gt;interface_state != 0 &amp;&amp; tech_pvt-&gt;interface_state != SKYPIAX_STATE_DOWN) {
+                                        WARNINGA(&quot;Why an interface_state %d HERE?\n&quot;, SKYPIAX_P_LOG, tech_pvt-&gt;interface_state);
+                                        tech_pvt-&gt;interface_state = SKYPIAX_STATE_DOWN;
+                                }
+
+                                break;
+                        }
+                }
+        }
+
+        if (found) {
+                //tech_pvt-&gt;callid_number[0]='\0';
+                //sprintf(msg_to_skype, &quot;ALTER CALL %s END HANGUP&quot;, id);
+                //skypiax_signaling_write(tech_pvt, msg_to_skype);
+                switch_mutex_unlock(globals.mutex);
+                return 0;
+        }
+        DEBUGA_SKYPE(&quot;NOT FOUND\n&quot;, SKYPIAX_P_LOG);
+
+        if (tech_pvt &amp;&amp; tech_pvt-&gt;skype_call_id &amp;&amp; !strlen(tech_pvt-&gt;skype_call_id)) {
+                /* we are not inside an active call */
+
+                tech_pvt-&gt;ib_calls++;
+
+                sprintf(msg_to_skype, &quot;GET CALL %s PARTNER_DISPNAME&quot;, id);
+                skypiax_signaling_write(tech_pvt, msg_to_skype);
+                switch_sleep(10000);
+                tech_pvt-&gt;interface_state = SKYPIAX_STATE_PREANSWER;
+                sprintf(msg_to_skype, &quot;ALTER CALL %s ANSWER&quot;, id);
+                skypiax_signaling_write(tech_pvt, msg_to_skype);
+                DEBUGA_SKYPE(&quot;We answered a Skype RING on skype_call %s\n&quot;, SKYPIAX_P_LOG, id);
+                //FIXME write a timestamp here
+                gettimeofday(&amp;tech_pvt-&gt;answer_time, NULL);
+                switch_copy_string(tech_pvt-&gt;skype_call_id, id, sizeof(tech_pvt-&gt;skype_call_id) - 1);
+
+                switch_copy_string(tech_pvt-&gt;callid_number, value, sizeof(tech_pvt-&gt;callid_number) - 1);
+
+                DEBUGA_SKYPE
+                        (&quot;NEW!  name: %s, state: %d, value=%s, tech_pvt-&gt;callid_number=%s, tech_pvt-&gt;skype_user=%s\n&quot;,
+                         SKYPIAX_P_LOG, tech_pvt-&gt;name, tech_pvt-&gt;interface_state, value, tech_pvt-&gt;callid_number, tech_pvt-&gt;skype_user);
+        } else if (!tech_pvt || !tech_pvt-&gt;skype_call_id) {
+                ERRORA(&quot;No Call ID?\n&quot;, SKYPIAX_P_LOG);
+        } else {
+                DEBUGA_SKYPE(&quot;We're in a call now (%s), let's refuse this one (%s)\n&quot;, SKYPIAX_P_LOG, tech_pvt-&gt;skype_call_id, id);
+                sprintf(msg_to_skype, &quot;ALTER CALL %s END HANGUP&quot;, id);
+                skypiax_signaling_write(tech_pvt, msg_to_skype);
+        }
+
+        switch_mutex_unlock(globals.mutex);
+        return 0;
+}
+int skypiax_transfer(private_t * tech_pvt, char *id, char *value)
+{
+        char msg_to_skype[1024];
+        int i;
+        int found = 0;
+        private_t *giovatech;
+        struct timeval timenow;
+
+        switch_mutex_lock(globals.mutex);
+
+        gettimeofday(&amp;timenow, NULL);
+        for (i = 0; !found &amp;&amp; i &lt; SKYPIAX_MAX_INTERFACES; i++) {
+                if (strlen(globals.SKYPIAX_INTERFACES[i].name)) {
+
+                        giovatech = &amp;globals.SKYPIAX_INTERFACES[i];
+                        //NOTICA(&quot;skype interface: %d, name: %s, state: %d, value=%s, giovatech-&gt;callid_number=%s, giovatech-&gt;skype_user=%s\n&quot;, SKYPIAX_P_LOG, i, giovatech-&gt;name, giovatech-&gt;interface_state, value, giovatech-&gt;callid_number, giovatech-&gt;skype_user);
+                        //FIXME check a timestamp here
+                        if (strlen(giovatech-&gt;skype_call_id) &amp;&amp; (giovatech-&gt;interface_state != SKYPIAX_STATE_DOWN) &amp;&amp; (!strcmp(giovatech-&gt;skype_user, tech_pvt-&gt;skype_user)) &amp;&amp; (!strcmp(giovatech-&gt;callid_number, value)) &amp;&amp; ((((timenow.tv_sec - giovatech-&gt;answer_time.tv_sec) * 1000000) + (timenow.tv_usec - giovatech-&gt;answer_time.tv_usec)) &lt; 500000)) {        //0.5sec
+                                found = 1;
+                                DEBUGA_SKYPE
+                                        (&quot;FOUND  (name=%s, giovatech-&gt;interface_state=%d != SKYPIAX_STATE_DOWN) &amp;&amp; (giovatech-&gt;skype_user=%s == tech_pvt-&gt;skype_user=%s) &amp;&amp; (giovatech-&gt;callid_number=%s == value=%s)\n&quot;,
+                                         SKYPIAX_P_LOG, giovatech-&gt;name, giovatech-&gt;interface_state,
+                                         giovatech-&gt;skype_user, tech_pvt-&gt;skype_user, giovatech-&gt;callid_number, value)
+                                        break;
+                        }
+                }
+        }
+
+        if (found) {
+                //tech_pvt-&gt;callid_number[0]='\0';
+                //sprintf(msg_to_skype, &quot;ALTER CALL %s END HANGUP&quot;, id);
+                //skypiax_signaling_write(tech_pvt, msg_to_skype);
+                switch_mutex_unlock(globals.mutex);
+                return 0;
+        }
+        DEBUGA_SKYPE(&quot;NOT FOUND\n&quot;, SKYPIAX_P_LOG);
+
+        if (!tech_pvt || !tech_pvt-&gt;skype_call_id || !strlen(tech_pvt-&gt;skype_call_id)) {
+                /* we are not inside an active call */
+                DEBUGA_SKYPE(&quot;We're NO MORE in a call now %s\n&quot;, SKYPIAX_P_LOG, (tech_pvt &amp;&amp; tech_pvt-&gt;skype_call_id) ? tech_pvt-&gt;skype_call_id : &quot;&quot;);
+                switch_mutex_unlock(globals.mutex);
+
+        } else {
+
+                /* we're owned, we're in a call, let's try to transfer */
+                /************************** TODO
+                  Checking here if it is possible to transfer this call to Test2
+                  -&gt; GET CALL 288 CAN_TRANSFER Test2
+                  &lt;- CALL 288 CAN_TRANSFER test2 TRUE
+                 **********************************/
+
+                private_t *available_skypiax_interface = NULL;
+
+                gettimeofday(&amp;timenow, NULL);
+                for (i = 0; !found &amp;&amp; i &lt; SKYPIAX_MAX_INTERFACES; i++) {
+                        if (strlen(globals.SKYPIAX_INTERFACES[i].name)) {
+
+                                giovatech = &amp;globals.SKYPIAX_INTERFACES[i];
+                                //NOTICA(&quot;skype interface: %d, name: %s, state: %d, value=%s, giovatech-&gt;callid_number=%s, giovatech-&gt;skype_user=%s\n&quot;, SKYPIAX_P_LOG, i, giovatech-&gt;name, giovatech-&gt;interface_state, value, giovatech-&gt;callid_number, giovatech-&gt;skype_user);
+                                //FIXME check a timestamp here
+                                if (strlen(giovatech-&gt;skype_transfer_call_id) &amp;&amp; (giovatech-&gt;interface_state != SKYPIAX_STATE_DOWN) &amp;&amp; (!strcmp(giovatech-&gt;skype_user, tech_pvt-&gt;skype_user)) &amp;&amp; (!strcmp(giovatech-&gt;transfer_callid_number, value)) &amp;&amp; ((((timenow.tv_sec - giovatech-&gt;transfer_time.tv_sec) * 1000000) + (timenow.tv_usec - giovatech-&gt;transfer_time.tv_usec)) &lt; 1000000)) {        //1.0 sec
+                                        found = 1;
+                                        DEBUGA_SKYPE
+                                                (&quot;FOUND  (name=%s, giovatech-&gt;interface_state=%d != SKYPIAX_STATE_DOWN) &amp;&amp; (giovatech-&gt;skype_user=%s == tech_pvt-&gt;skype_user=%s) &amp;&amp; (giovatech-&gt;transfer_callid_number=%s == value=%s)\n&quot;,
+                                                 SKYPIAX_P_LOG, giovatech-&gt;name, giovatech-&gt;interface_state,
+                                                 giovatech-&gt;skype_user, tech_pvt-&gt;skype_user, giovatech-&gt;transfer_callid_number, value)
+                                                break;
+                                }
+                        }
+                }
+
+                if (found) {
+                        //tech_pvt-&gt;callid_number[0]='\0';
+                        //sprintf(msg_to_skype, &quot;ALTER CALL %s END HANGUP&quot;, id);
+                        //skypiax_signaling_write(tech_pvt, msg_to_skype);
+                        switch_mutex_unlock(globals.mutex);
+                        return 0;
+                }
+                DEBUGA_SKYPE(&quot;NOT FOUND\n&quot;, SKYPIAX_P_LOG);
+
+                available_skypiax_interface = find_available_skypiax_interface_rr(tech_pvt);
+                if (available_skypiax_interface) {
+                        /* there is a skypiax interface idle, let's transfer the call to it */
+
+                        //FIXME write a timestamp here
+                        gettimeofday(&amp;tech_pvt-&gt;transfer_time, NULL);
+                        switch_copy_string(tech_pvt-&gt;skype_transfer_call_id, id, sizeof(tech_pvt-&gt;skype_transfer_call_id) - 1);
+
+                        switch_copy_string(tech_pvt-&gt;transfer_callid_number, value, sizeof(tech_pvt-&gt;transfer_callid_number) - 1);
+
+                        DEBUGA_SKYPE
+                                (&quot;Let's transfer the skype_call %s to %s interface (with skype_user: %s), because we are already in a skypiax call(%s)\n&quot;,
+                                 SKYPIAX_P_LOG, tech_pvt-&gt;skype_call_id, available_skypiax_interface-&gt;name, available_skypiax_interface-&gt;skype_user, id);
+
+                        //FIXME why this? the inbound call will come, eventually, on that other interface
+                        //available_skypiax_interface-&gt;ib_calls++;
+
+                        sprintf(msg_to_skype, &quot;ALTER CALL %s TRANSFER %s&quot;, id, available_skypiax_interface-&gt;skype_user);
+                        skypiax_signaling_write(tech_pvt, msg_to_skype);
+                        if (tech_pvt-&gt;interface_state == SKYPIAX_STATE_SELECTED) {
+                                tech_pvt-&gt;interface_state = SKYPIAX_STATE_IDLE;        //we marked it SKYPIAX_STATE_SELECTED just in case it has to make an outbound call
+                        }
+                } else {
+                        /* no skypiax interfaces idle, do nothing */
+                        DEBUGA_SKYPE
+                                (&quot;Not answering the skype_call %s, because we are already in a skypiax call(%s) and not transferring, because no other skypiax interfaces are available\n&quot;,
+                                 SKYPIAX_P_LOG, id, tech_pvt-&gt;skype_call_id);
+                        sprintf(msg_to_skype, &quot;ALTER CALL %s END HANGUP&quot;, id);
+                        skypiax_signaling_write(tech_pvt, msg_to_skype);
+                }
+                switch_sleep(10000);
+                DEBUGA_SKYPE
+                        (&quot;We have NOT answered a Skype RING from skype_call %s, because we are already in a skypiax call (%s)\n&quot;,
+                         SKYPIAX_P_LOG, id, tech_pvt-&gt;skype_call_id);
+
+                switch_mutex_unlock(globals.mutex);
+        }
+        return 0;
+}
+
+int incoming_chatmessage(private_t * tech_pvt, int which)
+{
+        switch_event_t *event;
+        switch_core_session_t *session = NULL;
+        int event_sent_to_esl = 0;
+
+        DEBUGA_SKYPE(&quot;received CHATMESSAGE on interface %s\n&quot;, SKYPIAX_P_LOG, tech_pvt-&gt;name);
+
+        if (!tech_pvt-&gt;report_incoming_chatmessages) {
+                DEBUGA_SKYPE(&quot;I will not generate an Event, report_incoming_chatmessages is %d\n&quot;, SKYPIAX_P_LOG, tech_pvt-&gt;report_incoming_chatmessages);
+                return 0;
+        }
+
+        if (!zstr(tech_pvt-&gt;session_uuid_str)) {
+                session = switch_core_session_locate(tech_pvt-&gt;session_uuid_str);
+        }
+        if (switch_event_create(&amp;event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) {
+                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;proto&quot;, MDL_CHAT_PROTO);
+                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;login&quot;, tech_pvt-&gt;name);
+                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;hint&quot;, tech_pvt-&gt;chatmessages[which].from_dispname);
+                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;from&quot;, tech_pvt-&gt;chatmessages[which].from_handle);
+                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;subject&quot;, &quot;SIMPLE MESSAGE&quot;);
+                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;chatname&quot;, tech_pvt-&gt;chatmessages[which].chatname);
+                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;id&quot;, tech_pvt-&gt;chatmessages[which].id);
+                switch_event_add_body(event, &quot;%s&quot;, tech_pvt-&gt;chatmessages[which].body);
+                if (session) {
+                        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;during-call&quot;, &quot;true&quot;);
+                        if (switch_core_session_queue_event(session, &amp;event) != SWITCH_STATUS_SUCCESS) {
+                                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;delivery-failure&quot;, &quot;true&quot;);
+                                switch_event_fire(&amp;event);
+                        }
+                } else {                                //no session
+                        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;during-call&quot;, &quot;false&quot;);
+                        switch_event_fire(&amp;event);
+                        event_sent_to_esl = 1;
+                }
+
+        } else {
+                ERRORA(&quot;cannot create event on interface %s. WHY?????\n&quot;, SKYPIAX_P_LOG, tech_pvt-&gt;name);
+        }
+
+        if (!event_sent_to_esl) {
+
+                if (switch_event_create(&amp;event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) {
+                        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;proto&quot;, MDL_CHAT_PROTO);
+                        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;login&quot;, tech_pvt-&gt;name);
+                        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;hint&quot;, tech_pvt-&gt;chatmessages[which].from_dispname);
+                        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;from&quot;, tech_pvt-&gt;chatmessages[which].from_handle);
+                        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;subject&quot;, &quot;SIMPLE MESSAGE&quot;);
+                        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;chatname&quot;, tech_pvt-&gt;chatmessages[which].chatname);
+                        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;id&quot;, tech_pvt-&gt;chatmessages[which].id);
+                        switch_event_add_body(event, &quot;%s&quot;, tech_pvt-&gt;chatmessages[which].body);
+                        if (session) {
+                                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;during-call&quot;, &quot;true&quot;);
+                        } else {                        //no session
+                                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, &quot;during-call&quot;, &quot;false&quot;);
+                        }
+                        switch_event_fire(&amp;event);
+                } else {
+                        ERRORA(&quot;cannot create event on interface %s. WHY?????\n&quot;, SKYPIAX_P_LOG, tech_pvt-&gt;name);
+                }
+        }
+
+        if (session) {
+                switch_core_session_rwunlock(session);
+        }
+        memset(&amp;tech_pvt-&gt;chatmessages[which], '\0', sizeof(&amp;tech_pvt-&gt;chatmessages[which]));
+        return 0;
+}
+
+
+SWITCH_STANDARD_API(skypiax_chat_function)
+{
+        char *mycmd = NULL, *argv[10] = { 0 };
+        int argc = 0;
+        private_t *tech_pvt = NULL;
+        //int tried =0;
+        int i;
+        int found = 0;
+        //char skype_msg[1024];
+
+        if (!zstr(cmd) &amp;&amp; (mycmd = strdup(cmd))) {
+                argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+        }
+
+        if (!argc) {
+                stream-&gt;write_function(stream, &quot;ERROR, usage: %s&quot;, SKYPIAX_CHAT_SYNTAX);
+                goto end;
+        }
+
+        if (argc &lt; 3) {
+                stream-&gt;write_function(stream, &quot;ERROR, usage: %s&quot;, SKYPIAX_CHAT_SYNTAX);
+                goto end;
+        }
+
+        if (argv[0]) {
+                for (i = 0; !found &amp;&amp; i &lt; SKYPIAX_MAX_INTERFACES; i++) {
+                        /* we've been asked for a normal interface name, or we have not found idle interfaces to serve as the &quot;ANY&quot; interface */
+                        if (strlen(globals.SKYPIAX_INTERFACES[i].name)
+                                &amp;&amp; (strncmp(globals.SKYPIAX_INTERFACES[i].name, argv[0], strlen(argv[0])) == 0)) {
+                                tech_pvt = &amp;globals.SKYPIAX_INTERFACES[i];
+                                stream-&gt;write_function(stream, &quot;Using interface: globals.SKYPIAX_INTERFACES[%d].name=|||%s|||\n&quot;, i, globals.SKYPIAX_INTERFACES[i].name);
+                                found = 1;
+                                break;
+                        }
+
+                }
+                if (!found) {
+                        stream-&gt;write_function(stream, &quot;ERROR: A Skypiax interface with name='%s' was not found\n&quot;, argv[0]);
+                        goto end;
+                } else {
+
+                        //chat_send(const char *proto, const char *from, const char *to, const char *subject, const char *body, const char *type, const char *hint);
+                        //chat_send(p*roto, const char *from, const char *to, const char *subject, const char *body, const char *type, const char *hint);
+                        //chat_send(MDL_CHAT_PROTO, tech_pvt-&gt;skype_user, argv[1], &quot;SIMPLE MESSAGE&quot;, switch_str_nil((char *) &amp;cmd[strlen(argv[0]) + 1 + strlen(argv[1]) + 1]), NULL, hint);
+
+                        NOTICA(&quot;chat_send(proto=%s, from=%s, to=%s, subject=%s, body=%s, type=NULL, hint=%s)\n&quot;, SKYPIAX_P_LOG, MDL_CHAT_PROTO, tech_pvt-&gt;skype_user,
+                                   argv[1], &quot;SIMPLE MESSAGE&quot;, switch_str_nil((char *) &amp;cmd[strlen(argv[0]) + 1 + strlen(argv[1]) + 1]), tech_pvt-&gt;name);
+
+                        chat_send(MDL_CHAT_PROTO, tech_pvt-&gt;skype_user, argv[1], &quot;SIMPLE MESSAGE&quot;,
+                                          switch_str_nil((char *) &amp;cmd[strlen(argv[0]) + 1 + strlen(argv[1]) + 1]), NULL, tech_pvt-&gt;name);
+
+                        //NOTICA(&quot;TEXT is: %s\n&quot;, SKYPIAX_P_LOG, (char *) &amp;cmd[strlen(argv[0]) + 1 + strlen(argv[1]) + 1] );
+                        //snprintf(skype_msg, sizeof(skype_msg), &quot;CHAT CREATE %s&quot;, argv[1]);
+                        //skypiax_signaling_write(tech_pvt, skype_msg);
+                        //switch_sleep(100);
+                }
+        } else {
+                stream-&gt;write_function(stream, &quot;ERROR, usage: %s&quot;, SKYPIAX_CHAT_SYNTAX);
+                goto end;
+        }
+
+#ifdef NOTDEF
+
+        found = 0;
+
+        while (!found) {
+                for (i = 0; i &lt; MAX_CHATS; i++) {
+                        if (!strcmp(tech_pvt-&gt;chats[i].dialog_partner, argv[1])) {
+                                snprintf(skype_msg, sizeof(skype_msg), &quot;CHATMESSAGE %s %s&quot;, tech_pvt-&gt;chats[i].chatname,
+                                                 (char *) &amp;cmd[strlen(argv[0]) + 1 + strlen(argv[1]) + 1]);
+                                skypiax_signaling_write(tech_pvt, skype_msg);
+                                found = 1;
+                                break;
+                        }
+                }
+                if (found) {
+                        break;
+                }
+                if (tried &gt; 1000) {
+                        stream-&gt;write_function(stream, &quot;ERROR: no chat with dialog_partner='%s' was found\n&quot;, argv[1]);
+                        break;
+                }
+                switch_sleep(1000);
+        }
+#endif //NOTDEF
+
+  end:
+        switch_safe_free(mycmd);
+
+        return SWITCH_STATUS_SUCCESS;
+}
+
+
+
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
+ */
</ins></span></pre></div>
<a id="freeswitchtrunksrcmodendpointsmod_skypiax103skypiaxh"></a>
<div class="addfile"><h4>Added: freeswitch/trunk/src/mod/endpoints/mod_skypiax/103/skypiax.h (0 => 16632)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/src/mod/endpoints/mod_skypiax/103/skypiax.h                                (rev 0)
+++ freeswitch/trunk/src/mod/endpoints/mod_skypiax/103/skypiax.h        2010-02-13 11:10:30 UTC (rev 16632)
</span><span class="lines">@@ -0,0 +1,332 @@
</span><ins>+/*
+ * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ * Copyright (C) 2005/2006, Anthony Minessale II &lt;anthmct@yahoo.com&gt;
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the &quot;License&quot;); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an &quot;AS IS&quot; basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ *
+ * The Initial Developer of the Original Code is
+ * Anthony Minessale II &lt;anthmct@yahoo.com&gt;
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * This module (mod_skypiax) has been contributed by:
+ *
+ * Giovanni Maruzzelli (gmaruzz@gmail.com)
+ *
+ *
+ * Further Contributors:
+ *
+ *
+ *
+ * mod_skypiax.c -- Skype compatible Endpoint Module
+ *
+ */
+
+#include &lt;switch.h&gt;
+#include &lt;switch_version.h&gt;
+
+#ifndef WIN32
+#include &lt;sys/time.h&gt;
+#include &lt;X11/Xlib.h&gt;
+#include &lt;X11/Xlibint.h&gt;
+#include &lt;X11/Xatom.h&gt;
+#endif //WIN32
+
+#ifdef _MSC_VER
+//Windows macro  for FD_SET includes a warning C4127: conditional expression is constant
+#pragma warning(push)
+#pragma warning(disable:4127)
+#endif
+
+#define MY_EVENT_INCOMING_CHATMESSAGE &quot;skypiax::incoming_chatmessage&quot;
+
+#define SAMPLERATE_SKYPIAX 16000
+#define SAMPLES_PER_FRAME SAMPLERATE_SKYPIAX/50
+
+#ifndef SKYPIAX_SVN_VERSION
+#define SKYPIAX_SVN_VERSION SWITCH_VERSION_REVISION
+#endif /* SKYPIAX_SVN_VERSION */
+
+typedef enum {
+        TFLAG_IO = (1 &lt;&lt; 0),
+        TFLAG_INBOUND = (1 &lt;&lt; 1),
+        TFLAG_OUTBOUND = (1 &lt;&lt; 2),
+        TFLAG_DTMF = (1 &lt;&lt; 3),
+        TFLAG_VOICE = (1 &lt;&lt; 4),
+        TFLAG_HANGUP = (1 &lt;&lt; 5),
+        TFLAG_LINEAR = (1 &lt;&lt; 6),
+        TFLAG_CODEC = (1 &lt;&lt; 7),
+        TFLAG_BREAK = (1 &lt;&lt; 8)
+} TFLAGS;
+
+typedef enum {
+        GFLAG_MY_CODEC_PREFS = (1 &lt;&lt; 0)
+} GFLAGS;
+
+#define DEBUGA_SKYPE(...)  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,                 &quot;rev &quot;SKYPIAX_SVN_VERSION &quot;[%p|%-7lx][DEBUG_SKYPE  %-5d][%-10s][%2d,%2d,%2d] &quot; __VA_ARGS__ );
+#define DEBUGA_CALL(...)  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,                 &quot;rev &quot;SKYPIAX_SVN_VERSION &quot;[%p|%-7lx][DEBUG_CALL  %-5d][%-10s][%2d,%2d,%2d] &quot; __VA_ARGS__ );
+#define DEBUGA_PBX(...)  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,                 &quot;rev &quot;SKYPIAX_SVN_VERSION &quot;[%p|%-7lx][DEBUG_PBX  %-5d][%-10s][%2d,%2d,%2d] &quot; __VA_ARGS__ );
+#define ERRORA(...)  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,                 &quot;rev &quot;SKYPIAX_SVN_VERSION &quot;[%p|%-7lx][ERRORA  %-5d][%-10s][%2d,%2d,%2d] &quot; __VA_ARGS__ );
+#define WARNINGA(...)  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,                 &quot;rev &quot;SKYPIAX_SVN_VERSION &quot;[%p|%-7lx][WARNINGA  %-5d][%-10s][%2d,%2d,%2d] &quot; __VA_ARGS__ );
+#define NOTICA(...)  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE,                 &quot;rev &quot;SKYPIAX_SVN_VERSION &quot;[%p|%-7lx][NOTICA  %-5d][%-10s][%2d,%2d,%2d] &quot; __VA_ARGS__ );
+
+#define SKYPIAX_P_LOG NULL, (unsigned long)55, __LINE__, tech_pvt ? tech_pvt-&gt;name ? tech_pvt-&gt;name : &quot;none&quot; : &quot;none&quot;, -1, tech_pvt ? tech_pvt-&gt;interface_state : -1, tech_pvt ? tech_pvt-&gt;skype_callflow : -1
+
+/*********************************/
+#define SKYPIAX_CAUSE_NORMAL                1
+/*********************************/
+#define SKYPIAX_FRAME_DTMF                        1
+/*********************************/
+#define SKYPIAX_CONTROL_RINGING                1
+#define SKYPIAX_CONTROL_ANSWER                2
+
+/*********************************/
+#define                SKYPIAX_STATE_IDLE                                        0
+#define                SKYPIAX_STATE_DOWN                                        1
+#define                SKYPIAX_STATE_RING                                        2
+#define                SKYPIAX_STATE_DIALING                                3
+#define                SKYPIAX_STATE_BUSY                                        4
+#define                SKYPIAX_STATE_UP                                        5
+#define                SKYPIAX_STATE_RINGING                                6
+#define                SKYPIAX_STATE_PRERING                                7
+#define                SKYPIAX_STATE_ERROR_DOUBLE_CALL                8
+#define                SKYPIAX_STATE_SELECTED                                9
+#define         SKYPIAX_STATE_HANGUP_REQUESTED                10
+#define                SKYPIAX_STATE_PREANSWER                                11
+/*********************************/
+/* call flow from the device */
+#define         CALLFLOW_CALL_IDLE                                        0
+#define         CALLFLOW_CALL_DOWN                                        1
+#define         CALLFLOW_INCOMING_RING                                2
+#define         CALLFLOW_CALL_DIALING                                3
+#define         CALLFLOW_CALL_LINEBUSY                                4
+#define         CALLFLOW_CALL_ACTIVE                                5
+#define         CALLFLOW_INCOMING_HANGUP                        6
+#define         CALLFLOW_CALL_RELEASED                                7
+#define         CALLFLOW_CALL_NOCARRIER                                8
+#define         CALLFLOW_CALL_INFLUX                                9
+#define         CALLFLOW_CALL_INCOMING                                10
+#define         CALLFLOW_CALL_FAILED                                11
+#define         CALLFLOW_CALL_NOSERVICE                                12
+#define         CALLFLOW_CALL_OUTGOINGRESTRICTED        13
+#define         CALLFLOW_CALL_SECURITYFAIL                        14
+#define         CALLFLOW_CALL_NOANSWER                                15
+#define         CALLFLOW_STATUS_FINISHED                        16
+#define         CALLFLOW_STATUS_CANCELLED                        17
+#define         CALLFLOW_STATUS_FAILED                                18
+#define         CALLFLOW_STATUS_REFUSED                                19
+#define         CALLFLOW_STATUS_RINGING                                20
+#define         CALLFLOW_STATUS_INPROGRESS                        21
+#define         CALLFLOW_STATUS_UNPLACED                        22
+#define         CALLFLOW_STATUS_ROUTING                                23
+#define         CALLFLOW_STATUS_EARLYMEDIA                        24
+#define         CALLFLOW_INCOMING_CALLID                        25
+#define         CALLFLOW_STATUS_REMOTEHOLD                        26
+
+/*********************************/
+
+#define SKYPIAX_MAX_INTERFACES 64
+
+#ifndef WIN32
+struct SkypiaxHandles {
+        Window skype_win;
+        Display *disp;
+        Window win;
+        int currentuserhandle;
+        int api_connected;
+        int fdesc[2];
+};
+#else //WIN32
+
+struct SkypiaxHandles {
+        HWND win32_hInit_MainWindowHandle;
+        HWND win32_hGlobal_SkypeAPIWindowHandle;
+        HINSTANCE win32_hInit_ProcessHandle;
+        char win32_acInit_WindowClassName[128];
+        UINT win32_uiGlobal_MsgID_SkypeControlAPIAttach;
+        UINT win32_uiGlobal_MsgID_SkypeControlAPIDiscover;
+        int currentuserhandle;
+        int api_connected;
+        switch_file_t *fdesc[2];
+};
+#endif //WIN32
+
+#define MAX_CHATS 10
+
+struct chat {
+        char chatname[256];
+        char dialog_partner[256];
+};
+typedef struct chat chat_t;
+
+#define MAX_CHATMESSAGES 10
+
+struct chatmessage {
+        char id[256];
+        char type[256];
+        char chatname[256];
+        char from_handle[256];
+        char from_dispname[256];
+        char body[512];
+};
+typedef struct chatmessage chatmessage_t;
+struct private_object {
+        unsigned int flags;
+        switch_codec_t read_codec;
+        switch_codec_t write_codec;
+        switch_frame_t read_frame;
+        unsigned char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
+        char session_uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
+        switch_caller_profile_t *caller_profile;
+        switch_mutex_t *mutex;
+        switch_mutex_t *flag_mutex;
+        switch_mutex_t *flag_audio_cli_mutex;
+        switch_mutex_t *flag_audio_srv_mutex;
+
+        char interface_id[80];
+        char name[80];
+        char dialplan[80];
+        char context[80];
+        char dial_regex[256];
+        char fail_dial_regex[256];
+        char hold_music[256];
+        char type[256];
+        char X11_display[256];
+#ifdef WIN32
+        unsigned short tcp_cli_port;
+        unsigned short tcp_srv_port;
+#else
+        int tcp_cli_port;
+        int tcp_srv_port;
+#endif
+        struct SkypiaxHandles SkypiaxHandles;
+
+        int interface_state;                /*!&lt; \brief 'state' of the interface (channel) */
+        char language[80];                        /*!&lt; \brief default Asterisk dialplan language for this interface */
+        char exten[80];                                /*!&lt; \brief default Asterisk dialplan extension for this interface */
+        int skypiax_sound_rate;                /*!&lt; \brief rate of the sound device, in Hz, eg: 8000 */
+        char callid_name[50];
+        char callid_number[50];
+        double playback_boost;
+        double capture_boost;
+        int stripmsd;
+        char skype_call_id[512];
+        int skype_call_ongoing;
+        char skype_friends[4096];
+        char skype_fullname[512];
+        char skype_displayname[512];
+        int skype_callflow;                        /*!&lt; \brief 'callflow' of the skype interface (as opposed to phone interface) */
+        int skype;                                        /*!&lt; \brief config flag, bool, Skype support on this interface (0 if false, -1 if true) */
+        int control_to_send;
+#ifdef WIN32
+        switch_file_t *audiopipe_srv[2];
+        switch_file_t *audiopipe_cli[2];
+        switch_file_t *skypiax_sound_capt_fd;        /*!&lt; \brief file descriptor for sound capture dev */
+#else                                                        /* WIN32 */
+        int audiopipe_srv[2];
+        int audiopipe_cli[2];
+        int skypiax_sound_capt_fd;        /*!&lt; \brief file descriptor for sound capture dev */
+#endif                                                        /* WIN32 */
+        switch_thread_t *tcp_srv_thread;
+        switch_thread_t *tcp_cli_thread;
+        switch_thread_t *skypiax_signaling_thread;
+        switch_thread_t *skypiax_api_thread;
+        short audiobuf[SAMPLES_PER_FRAME];
+        int audiobuf_is_loaded;
+        short audiobuf_cli[SAMPLES_PER_FRAME];
+        switch_mutex_t *mutex_audio_cli;
+        int flag_audio_cli;
+        short audiobuf_srv[SAMPLES_PER_FRAME];
+        switch_mutex_t *mutex_audio_srv;
+        int flag_audio_srv;
+
+        //int phonebook_listing;
+        //int phonebook_querying;
+        //int phonebook_listing_received_calls;
+
+        //int phonebook_first_entry;
+        //int phonebook_last_entry;
+        //int phonebook_number_lenght;
+        //int phonebook_text_lenght;
+        FILE *phonebook_writing_fp;
+        int skypiax_dir_entry_extension_prefix;
+        char skype_user[256];
+        char skype_password[256];
+        char destination[256];
+        struct timeval answer_time;
+
+        struct timeval transfer_time;
+        char transfer_callid_number[50];
+        char skype_transfer_call_id[512];
+        int running;
+        uint32_t ib_calls;
+        uint32_t ob_calls;
+        uint32_t ib_failed_calls;
+        uint32_t ob_failed_calls;
+
+        chatmessage_t chatmessages[MAX_CHATMESSAGES];
+        chat_t chats[MAX_CHATS];
+        uint32_t report_incoming_chatmessages;
+        switch_timer_t timer_read;
+        switch_timer_t timer_write;
+unsigned int writefd;
+unsigned int readfd;
+};
+
+typedef struct private_object private_t;
+
+void *SWITCH_THREAD_FUNC skypiax_api_thread_func(switch_thread_t * thread, void *obj);
+int skypiax_audio_read(private_t * tech_pvt);
+int skypiax_audio_init(private_t * tech_pvt);
+int skypiax_signaling_write(private_t * tech_pvt, char *msg_to_skype);
+int skypiax_signaling_read(private_t * tech_pvt);
+
+int skypiax_call(private_t * tech_pvt, char *idest, int timeout);
+int skypiax_senddigit(private_t * tech_pvt, char digit);
+
+void *skypiax_do_tcp_srv_thread_func(void *obj);
+void *SWITCH_THREAD_FUNC skypiax_do_tcp_srv_thread(switch_thread_t * thread, void *obj);
+
+void *skypiax_do_tcp_cli_thread_func(void *obj);
+void *SWITCH_THREAD_FUNC skypiax_do_tcp_cli_thread(switch_thread_t * thread, void *obj);
+
+void *skypiax_do_skypeapi_thread_func(void *obj);
+void *SWITCH_THREAD_FUNC skypiax_do_skypeapi_thread(switch_thread_t * thread, void *obj);
+int dtmf_received(private_t * tech_pvt, char *value);
+int start_audio_threads(private_t * tech_pvt);
+int new_inbound_channel(private_t * tech_pvt);
+int outbound_channel_answered(private_t * tech_pvt);
+int skypiax_signaling_write(private_t * tech_pvt, char *msg_to_skype);
+#if defined(WIN32) &amp;&amp; !defined(__CYGWIN__)
+int skypiax_pipe_read(switch_file_t * pipe, short *buf, int howmany);
+int skypiax_pipe_write(switch_file_t * pipe, short *buf, int howmany);
+/* Visual C do not have strsep ? */
+char *strsep(char **stringp, const char *delim);
+#else
+int skypiax_pipe_read(int pipe, short *buf, int howmany);
+int skypiax_pipe_write(int pipe, short *buf, int howmany);
+#endif /* WIN32 */
+int skypiax_close_socket(unsigned int fd);
+private_t *find_available_skypiax_interface_rr(private_t * tech_pvt_calling);
+int remote_party_is_ringing(private_t * tech_pvt);
+int remote_party_is_early_media(private_t * tech_pvt);
+int skypiax_answer(private_t * tech_pvt, char *id, char *value);
+int skypiax_transfer(private_t * tech_pvt, char *id, char *value);
+#ifndef WIN32
+int skypiax_socket_create_and_bind(private_t * tech_pvt, int *which_port);
+#else
+int skypiax_socket_create_and_bind(private_t * tech_pvt, unsigned short *which_port);
+#endif //WIN32
+int incoming_chatmessage(private_t * tech_pvt, int which);
</ins></span></pre></div>
<a id="freeswitchtrunksrcmodendpointsmod_skypiax103skypiax_protocolc"></a>
<div class="addfile"><h4>Added: freeswitch/trunk/src/mod/endpoints/mod_skypiax/103/skypiax_protocol.c (0 => 16632)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/trunk/src/mod/endpoints/mod_skypiax/103/skypiax_protocol.c                                (rev 0)
+++ freeswitch/trunk/src/mod/endpoints/mod_skypiax/103/skypiax_protocol.c        2010-02-13 11:10:30 UTC (rev 16632)
</span><span class="lines">@@ -0,0 +1,1926 @@
</span><ins>+#include &quot;skypiax.h&quot;
+
+#ifdef ASTERISK
+#define skypiax_sleep usleep
+#define skypiax_strncpy strncpy
+#define tech_pvt p
+extern int skypiax_debug;
+extern char *skypiax_console_active;
+#else /* FREESWITCH */
+#define skypiax_sleep switch_sleep
+#define skypiax_strncpy switch_copy_string
+extern switch_memory_pool_t *skypiax_module_pool;
+extern switch_endpoint_interface_t *skypiax_endpoint_interface;
+#endif /* ASTERISK */
+int samplerate_skypiax = SAMPLERATE_SKYPIAX;
+
+extern int running;
+
+/*************************************/
+/* suspicious globals FIXME */
+#ifdef WIN32
+DWORD win32_dwThreadId;
+#else
+XErrorHandler old_handler = 0;
+int xerror = 0;
+#endif /* WIN32 */
+/*************************************/
+#ifndef WIN32
+int skypiax_socket_create_and_bind(private_t * tech_pvt, int *which_port)
+#else
+int skypiax_socket_create_and_bind(private_t * tech_pvt, unsigned short *which_port)
+#endif                                                        //WIN32
+{
+        int s = -1;
+        struct sockaddr_in my_addr;
+#ifndef WIN32
+        int start_port = 6001;
+#else
+        unsigned short start_port = 6001;
+#endif //WIN32
+        int sockbufsize = 0;
+        unsigned int size = sizeof(int);
+
+
+        memset(&amp;my_addr, 0, sizeof(my_addr));
+        my_addr.sin_family = AF_INET;
+        my_addr.sin_addr.s_addr = htonl(0x7f000001);        /* use the localhost */
+
+        if ((s = socket(AF_INET, SOCK_STREAM, 0)) &lt; 0) {
+                ERRORA(&quot;socket Error\n&quot;, SKYPIAX_P_LOG);
+                return -1;
+        }
+
+        if (*which_port != 0)
+                start_port = *which_port;
+
+        my_addr.sin_port = htons(start_port);
+/* NONBLOCKING ? */
+        fcntl(s, F_SETFL, O_NONBLOCK);
+
+        *which_port = start_port;
+        while (bind(s, (struct sockaddr *) &amp;my_addr, sizeof(struct sockaddr)) &lt; 0) {
+                DEBUGA_SKYPE(&quot;*which_port=%d, tech_pvt-&gt;tcp_cli_port=%d, tech_pvt-&gt;tcp_srv_port=%d\n&quot;, SKYPIAX_P_LOG, *which_port, tech_pvt-&gt;tcp_cli_port,
+                                         tech_pvt-&gt;tcp_srv_port);
+                DEBUGA_SKYPE(&quot;bind errno=%d, error: %s\n&quot;, SKYPIAX_P_LOG, errno, strerror(errno));
+                start_port++;
+                my_addr.sin_port = htons(start_port);
+                *which_port = start_port;
+                DEBUGA_SKYPE(&quot;*which_port=%d, tech_pvt-&gt;tcp_cli_port=%d, tech_pvt-&gt;tcp_srv_port=%d\n&quot;, SKYPIAX_P_LOG, *which_port, tech_pvt-&gt;tcp_cli_port,
+                                         tech_pvt-&gt;tcp_srv_port);
+
+                if (start_port &gt; 65000) {
+                        ERRORA(&quot;NO MORE PORTS! *which_port=%d, tech_pvt-&gt;tcp_cli_port=%d, tech_pvt-&gt;tcp_srv_port=%d\n&quot;, SKYPIAX_P_LOG, *which_port,
+                                   tech_pvt-&gt;tcp_cli_port, tech_pvt-&gt;tcp_srv_port);
+                        return -1;
+                }
+        }
+
+        DEBUGA_SKYPE(&quot;SUCCESS! *which_port=%d, tech_pvt-&gt;tcp_cli_port=%d, tech_pvt-&gt;tcp_srv_port=%d\n&quot;, SKYPIAX_P_LOG, *which_port, tech_pvt-&gt;tcp_cli_port,
+                                 tech_pvt-&gt;tcp_srv_port);
+
+        sockbufsize = 0;
+        size = sizeof(int);
+        getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *) &amp;sockbufsize, &amp;size);
+        DEBUGA_SKYPE(&quot;1 SO_RCVBUF is %d, size is %d\n&quot;, SKYPIAX_P_LOG, sockbufsize, size);
+        sockbufsize = 0;
+        size = sizeof(int);
+        getsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *) &amp;sockbufsize, &amp;size);
+        DEBUGA_SKYPE(&quot;1 SO_SNDBUF is %d, size is %d\n&quot;, SKYPIAX_P_LOG, sockbufsize, size);
+
+
+
+/* for virtual machines, eg: Linux domU-12-31-39-02-68-28 2.6.18-xenU-ec2-v1.0 #2 SMP Tue Feb 19 10:51:53 EST 2008 i686 athlon i386 GNU/Linux
+ * use:
+ * sockbufsize=SAMPLES_PER_FRAME * 8;
+ */
+#ifdef WIN32
+        sockbufsize = SAMPLES_PER_FRAME * 8 * 3;
+#else
+        sockbufsize = SAMPLES_PER_FRAME * 8 * 3;
+#endif //WIN32
+        size = sizeof(int);
+        setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *) &amp;sockbufsize, size);
+
+        sockbufsize = 0;
+        size = sizeof(int);
+        getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *) &amp;sockbufsize, &amp;size);
+        DEBUGA_SKYPE(&quot;2 SO_RCVBUF is %d, size is %d\n&quot;, SKYPIAX_P_LOG, sockbufsize, size);
+
+/* for virtual machines, eg: Linux domU-12-31-39-02-68-28 2.6.18-xenU-ec2-v1.0 #2 SMP Tue Feb 19 10:51:53 EST 2008 i686 athlon i386 GNU/Linux
+ * use:
+ * sockbufsize=SAMPLES_PER_FRAME * 8;
+ */
+#ifdef WIN32
+        sockbufsize = SAMPLES_PER_FRAME * 8 * 3;
+#else
+        sockbufsize = SAMPLES_PER_FRAME * 8 * 3;
+#endif //WIN32
+        size = sizeof(int);
+        setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *) &amp;sockbufsize, size);
+
+
+        sockbufsize = 0;
+        size = sizeof(int);
+        getsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *) &amp;sockbufsize, &amp;size);
+        DEBUGA_SKYPE(&quot;2 SO_SNDBUF is %d, size is %d\n&quot;, SKYPIAX_P_LOG, sockbufsize, size);
+
+
+
+        return s;
+}
+
+int skypiax_signaling_read(private_t * tech_pvt)
+{
+        char read_from_pipe[4096];
+        char message[4096];
+        char message_2[4096];
+        char *buf, obj[512] = &quot;&quot;, id[512] = &quot;&quot;, prop[512] = &quot;&quot;, value[512] = &quot;&quot;, *where;
+        char **stringp = NULL;
+        int a;
+        unsigned int howmany;
+        unsigned int i;
+
+        memset(read_from_pipe, 0, 4096);
+        memset(message, 0, 4096);
+        memset(message_2, 0, 4096);
+
+        howmany = skypiax_pipe_read(tech_pvt-&gt;SkypiaxHandles.fdesc[0], (short *) read_from_pipe, sizeof(read_from_pipe));
+
+        a = 0;
+        for (i = 0; i &lt; howmany; i++) {
+                message[a] = read_from_pipe[i];
+                a++;
+
+                if (read_from_pipe[i] == '\0') {
+
+                        //if (!strstr(message, &quot;DURATION&quot;)) {
+                        DEBUGA_SKYPE(&quot;READING: |||%s||| \n&quot;, SKYPIAX_P_LOG, message);
+                        //}
+
+                        if (!strcasecmp(message, &quot;ERROR 68&quot;)) {
+                                DEBUGA_SKYPE
+                                        (&quot;If I don't connect immediately, please give the Skype client authorization to be connected by Skypiax (and to not ask you again)\n&quot;,
+                                         SKYPIAX_P_LOG);
+                                skypiax_sleep(1000000);
+                                skypiax_signaling_write(tech_pvt, &quot;PROTOCOL 7&quot;);
+                                skypiax_sleep(10000);
+                                return 0;
+                        }
+                        if (!strncasecmp(message, &quot;ERROR 92 CALL&quot;, 12)) {
+                                ERRORA(&quot;Skype got ERROR: |||%s|||, the (skypeout) number we called was not recognized as valid\n&quot;, SKYPIAX_P_LOG, message);
+                                tech_pvt-&gt;skype_callflow = CALLFLOW_STATUS_FINISHED;
+                                DEBUGA_SKYPE(&quot;skype_call now is DOWN\n&quot;, SKYPIAX_P_LOG);
+                                tech_pvt-&gt;skype_call_id[0] = '\0';
+
+                                if (tech_pvt-&gt;interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) {
+                                        tech_pvt-&gt;interface_state = SKYPIAX_STATE_DOWN;
+                                        return CALLFLOW_INCOMING_HANGUP;
+                                } else {
+                                        tech_pvt-&gt;interface_state = SKYPIAX_STATE_DOWN;
+                                }
+                        }
+
+                        if (!strncasecmp(message, &quot;ERROR&quot;, 4)) {
+                                if (!strncasecmp(message, &quot;ERROR 96 CALL&quot;, 12)) {
+                                        DEBUGA_SKYPE
+                                                (&quot;Skype got ERROR: |||%s|||, we are trying to use this interface to make or receive a call, but another call is half-active on this interface. Let's the previous one to continue.\n&quot;,
+                                                 SKYPIAX_P_LOG, message);
+                                } else if (!strncasecmp(message, &quot;ERROR 99 CALL&quot;, 12)) {
+                                        ERRORA(&quot;Skype got ERROR: |||%s|||, another call is active on this interface\n\n\n&quot;, SKYPIAX_P_LOG, message);
+                                        tech_pvt-&gt;interface_state = SKYPIAX_STATE_ERROR_DOUBLE_CALL;
+                                } else if (!strncasecmp(message, &quot;ERROR 592 ALTER CALL&quot;, 19)) {
+                                        ERRORA(&quot;Skype got ERROR about TRANSFERRING, no problem: |||%s|||\n&quot;, SKYPIAX_P_LOG, message);
+                                } else if (!strncasecmp(message, &quot;ERROR 559 CALL&quot;, 13)) {
+                                        DEBUGA_SKYPE(&quot;Skype got ERROR about a failed action (probably TRYING to HANGUP A CALL), no problem: |||%s|||\n&quot;, SKYPIAX_P_LOG,
+                                                                 message);
+                                } else {
+                                        ERRORA(&quot;Skype got ERROR: |||%s|||\n&quot;, SKYPIAX_P_LOG, message);
+                                        tech_pvt-&gt;skype_callflow = CALLFLOW_STATUS_FINISHED;
+                                        ERRORA(&quot;skype_call now is DOWN\n&quot;, SKYPIAX_P_LOG);
+                                        tech_pvt-&gt;skype_call_id[0] = '\0';
+
+                                        if (tech_pvt-&gt;interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) {
+                                                tech_pvt-&gt;interface_state = SKYPIAX_STATE_DOWN;
+                                                return CALLFLOW_INCOMING_HANGUP;
+                                        } else {
+                                                tech_pvt-&gt;interface_state = SKYPIAX_STATE_DOWN;
+                                        }
+                                }
+                        }
+
+
+
+
+                        skypiax_strncpy(message_2, message, sizeof(message) - 1);
+                        buf = message;
+                        stringp = &amp;buf;
+                        where = strsep(stringp, &quot; &quot;);
+                        if (!where) {
+                                WARNINGA(&quot;Skype MSG without spaces: %s\n&quot;, SKYPIAX_P_LOG, message);
+                        }
+
+
+
+
+
+
+
+
+                        if (!strcasecmp(message, &quot;CURRENTUSERHANDLE&quot;)) {
+                                skypiax_strncpy(obj, where, sizeof(obj) - 1);
+                                where = strsep(stringp, &quot; &quot;);
+                                skypiax_strncpy(id, where, sizeof(id) - 1);
+                                if (!strcasecmp(id, tech_pvt-&gt;skype_user)) {
+                                        tech_pvt-&gt;SkypiaxHandles.currentuserhandle = 1;
+                                        DEBUGA_SKYPE
+                                                (&quot;Skype MSG: message: %s, currentuserhandle: %s, cuh: %s, skype_user: %s!\n&quot;,
+                                                 SKYPIAX_P_LOG, message, obj, id, tech_pvt-&gt;skype_user);
+                                }
+                        }
+                        if (!strcasecmp(message, &quot;USER&quot;)) {
+                                skypiax_strncpy(obj, where, sizeof(obj) - 1);
+                                where = strsep(stringp, &quot; &quot;);
+                                skypiax_strncpy(id, where, sizeof(id) - 1);
+                                where = strsep(stringp, &quot; &quot;);
+                                skypiax_strncpy(prop, where, sizeof(prop) - 1);
+                                if (!strcasecmp(prop, &quot;RECEIVEDAUTHREQUEST&quot;)) {
+                                        char msg_to_skype[256];
+                                        DEBUGA_SKYPE(&quot;Skype MSG: message: %s, obj: %s, id: %s, prop: %s!\n&quot;, SKYPIAX_P_LOG, message, obj, id, prop);
+                                        //TODO: allow authorization based on config param
+                                        sprintf(msg_to_skype, &quot;SET USER %s ISAUTHORIZED TRUE&quot;, id);
+                                        skypiax_signaling_write(tech_pvt, msg_to_skype);
+                                }
+                        }
+                        if (!strcasecmp(message, &quot;MESSAGE&quot;)) {
+                                skypiax_strncpy(obj, where, sizeof(obj) - 1);
+                                where = strsep(stringp, &quot; &quot;);
+                                skypiax_strncpy(id, where, sizeof(id) - 1);
+                                where = strsep(stringp, &quot; &quot;);
+                                skypiax_strncpy(prop, where, sizeof(prop) - 1);
+                                if (!strcasecmp(prop, &quot;STATUS&quot;)) {
+                                        where = strsep(stringp, &quot; &quot;);
+                                        skypiax_strncpy(value, where, sizeof(value) - 1);
+                                        if (!strcasecmp(value, &quot;RECEIVED&quot;)) {
+                                                char msg_to_skype[256];
+                                                DEBUGA_SKYPE(&quot;Skype MSG: message: %s, obj: %s, id: %s, prop: %s value: %s!\n&quot;, SKYPIAX_P_LOG, message, obj, id, prop, value);
+                                                //TODO: authomatically flag messages as read based on config param
+                                                sprintf(msg_to_skype, &quot;SET MESSAGE %s SEEN&quot;, id);
+                                                skypiax_signaling_write(tech_pvt, msg_to_skype);
+                                        }
+                                } else if (!strcasecmp(prop, &quot;BODY&quot;)) {
+                                        char msg_to_skype[256];
+                                        DEBUGA_SKYPE(&quot;Skype MSG: message: %s, obj: %s, id: %s, prop: %s!\n&quot;, SKYPIAX_P_LOG, message, obj, id, prop);
+                                        //TODO: authomatically flag messages as read based on config param
+                                        sprintf(msg_to_skype, &quot;SET MESSAGE %s SEEN&quot;, id);
+                                        skypiax_signaling_write(tech_pvt, msg_to_skype);
+                                }
+                        }
+                        if (!strcasecmp(message, &quot;CHAT&quot;)) {
+                                char msg_to_skype[256];
+                                int i;
+                                int found;
+
+                                skypiax_strncpy(obj, where, sizeof(obj) - 1);
+                                where = strsep(stringp, &quot; &quot;);
+                                skypiax_strncpy(id, where, sizeof(id) - 1);
+                                where = strsep(stringp, &quot; &quot;);
+                                skypiax_strncpy(prop, where, sizeof(prop) - 1);
+                                skypiax_strncpy(value, *stringp, sizeof(value) - 1);
+
+                                if (!strcasecmp(prop, &quot;STATUS&quot;) &amp;&amp; !strcasecmp(value, &quot;DIALOG&quot;)) {
+                                        DEBUGA_SKYPE(&quot;CHAT %s is DIALOG\n&quot;, SKYPIAX_P_LOG, id);
+                                        sprintf(msg_to_skype, &quot;GET CHAT %s DIALOG_PARTNER&quot;, id);
+                                        skypiax_signaling_write(tech_pvt, msg_to_skype);
+                                }
+
+                                if (!strcasecmp(prop, &quot;DIALOG_PARTNER&quot;)) {
+                                        DEBUGA_SKYPE(&quot;CHAT %s has DIALOG_PARTNER %s\n&quot;, SKYPIAX_P_LOG, id, value);
+                                        found = 0;
+                                        for (i = 0; i &lt; MAX_CHATS; i++) {
+                                                if (strlen(tech_pvt-&gt;chats[i].chatname) == 0 || !strcmp(tech_pvt-&gt;chats[i].chatname, id)) {
+                                                        strncpy(tech_pvt-&gt;chats[i].chatname, id, sizeof(tech_pvt-&gt;chats[i].chatname));
+                                                        strncpy(tech_pvt-&gt;chats[i].dialog_partner, value, sizeof(tech_pvt-&gt;chats[i].dialog_partner));
+                                                        found = 1;
+                                                        break;
+                                                }
+                                        }
+                                        if (!found) {
+                                                DEBUGA_SKYPE(&quot;why we do not have a chats slot free? we have more than %d chats in parallel?\n&quot;, SKYPIAX_P_LOG, MAX_CHATS);
+                                        }
+
+                                        DEBUGA_SKYPE(&quot;CHAT %s is in position %d in the chats array, chatname=%s, dialog_partner=%s\n&quot;, SKYPIAX_P_LOG, id, i,
+                                                                 tech_pvt-&gt;chats[i].chatname, tech_pvt-&gt;chats[i].dialog_partner);
+                                }
+
+                        }
+
+
+                        if (!strcasecmp(message, &quot;CHATMESSAGE&quot;)) {
+                                char msg_to_skype[256];
+                                int i;
+                                int found;
+
+                                skypiax_strncpy(obj, where, sizeof(obj) - 1);
+                                where = strsep(stringp, &quot; &quot;);
+                                skypiax_strncpy(id, where, sizeof(id) - 1);
+                                where = strsep(stringp, &quot; &quot;);
+                                skypiax_strncpy(prop, where, sizeof(prop) - 1);
+                                skypiax_strncpy(value, *stringp, sizeof(value) - 1);
+
+                                if (!strcasecmp(prop, &quot;STATUS&quot;) &amp;&amp; !strcasecmp(value, &quot;RECEIVED&quot;)) {
+                                        DEBUGA_SKYPE(&quot;RECEIVED CHATMESSAGE %s, let's see which type it is\n&quot;, SKYPIAX_P_LOG, id);
+                                        sprintf(msg_to_skype, &quot;GET CHATMESSAGE %s TYPE&quot;, id);
+                                        skypiax_signaling_write(tech_pvt, msg_to_skype);
+                                }
+
+                                if (!strcasecmp(prop, &quot;TYPE&quot;) &amp;&amp; !strcasecmp(value, &quot;SAID&quot;)) {
+                                        DEBUGA_SKYPE(&quot;CHATMESSAGE %s is of type SAID, let's get the other infos\n&quot;, SKYPIAX_P_LOG, id);
+                                        found = 0;
+                                        for (i = 0; i &lt; MAX_CHATMESSAGES; i++) {
+                                                if (strlen(tech_pvt-&gt;chatmessages[i].id) == 0) {
+                                                        strncpy(tech_pvt-&gt;chatmessages[i].id, id, sizeof(tech_pvt-&gt;chatmessages[i].id));
+                                                        strncpy(tech_pvt-&gt;chatmessages[i].type, value, sizeof(tech_pvt-&gt;chatmessages[i].type));
+                                                        found = 1;
+                                                        break;
+                                                }
+                                        }
+                                        if (!found) {
+                                                DEBUGA_SKYPE(&quot;why we do not have a chatmessages slot free? we have more than %d chatmessages in parallel?\n&quot;, SKYPIAX_P_LOG,
+                                                                         MAX_CHATMESSAGES);
+                                        } else {
+                                                DEBUGA_SKYPE(&quot;CHATMESSAGE %s is in position %d in the chatmessages array, type=%s, id=%s\n&quot;, SKYPIAX_P_LOG, id, i,
+                                                                         tech_pvt-&gt;chatmessages[i].type, tech_pvt-&gt;chatmessages[i].id);
+                                                sprintf(msg_to_skype, &quot;GET CHATMESSAGE %s CHATNAME&quot;, id);
+                                                skypiax_signaling_write(tech_pvt, msg_to_skype);
+                                                skypiax_sleep(1000);
+                                                sprintf(msg_to_skype, &quot;GET CHATMESSAGE %s FROM_HANDLE&quot;, id);
+                                                skypiax_signaling_write(tech_pvt, msg_to_skype);
+                                                skypiax_sleep(1000);
+                                                sprintf(msg_to_skype, &quot;GET CHATMESSAGE %s FROM_DISPNAME&quot;, id);
+                                                skypiax_signaling_write(tech_pvt, msg_to_skype);
+                                                skypiax_sleep(1000);
+                                                sprintf(msg_to_skype, &quot;GET CHATMESSAGE %s BODY&quot;, id);
+                                                skypiax_signaling_write(tech_pvt, msg_to_skype);
+                                        }
+                                }
+
+                                if (!strcasecmp(prop, &quot;CHATNAME&quot;)) {
+                                        DEBUGA_SKYPE(&quot;CHATMESSAGE %s belongs to the CHAT %s\n&quot;, SKYPIAX_P_LOG, id, value);
+                                        found = 0;
+                                        for (i = 0; i &lt; MAX_CHATMESSAGES; i++) {
+                                                if (!strcmp(tech_pvt-&gt;chatmessages[i].id, id)) {
+                                                        strncpy(tech_pvt-&gt;chatmessages[i].chatname, value, sizeof(tech_pvt-&gt;chatmessages[i].chatname));
+                                                        found = 1;
+                                                        break;
+                                                }
+                                        }
+                                        if (!found) {
+                                                DEBUGA_SKYPE(&quot;why chatmessage %s was not found in the chatmessages array??\n&quot;, SKYPIAX_P_LOG, id);
+                                        }
+                                }
+                                if (!strcasecmp(prop, &quot;FROM_HANDLE&quot;)) {
+                                        DEBUGA_SKYPE(&quot;CHATMESSAGE %s was sent by FROM_HANDLE %s\n&quot;, SKYPIAX_P_LOG, id, value);
+                                        found = 0;
+                                        for (i = 0; i &lt; MAX_CHATMESSAGES; i++) {
+                                                if (!strcmp(tech_pvt-&gt;chatmessages[i].id, id)) {
+                                                        strncpy(tech_pvt-&gt;chatmessages[i].from_handle, value, sizeof(tech_pvt-&gt;chatmessages[i].from_handle));
+                                                        found = 1;
+                                                        break;
+                                                }
+                                        }
+                                        if (!found) {
+                                                DEBUGA_SKYPE(&quot;why chatmessage %s was not found in the chatmessages array??\n&quot;, SKYPIAX_P_LOG, id);
+                                        }
+
+                                }
+                                if (!strcasecmp(prop, &quot;FROM_DISPNAME&quot;)) {
+                                        DEBUGA_SKYPE(&quot;CHATMESSAGE %s was sent by FROM_DISPNAME %s\n&quot;, SKYPIAX_P_LOG, id, value);
+                                        found = 0;
+                                        for (i = 0; i &lt; MAX_CHATMESSAGES; i++) {
+                                                if (!strcmp(tech_pvt-&gt;chatmessages[i].id, id)) {
+                                                        strncpy(tech_pvt-&gt;chatmessages[i].from_dispname, value, sizeof(tech_pvt-&gt;chatmessages[i].from_dispname));
+                                                        found = 1;
+                                                        break;
+                                                }
+                                        }
+                                        if (!found) {
+                                                DEBUGA_SKYPE(&quot;why chatmessage %s was not found in the chatmessages array??\n&quot;, SKYPIAX_P_LOG, id);
+                                        }
+
+                                }
+                                if (!strcasecmp(prop, &quot;BODY&quot;)) {
+                                        DEBUGA_SKYPE(&quot;CHATMESSAGE %s has BODY %s\n&quot;, SKYPIAX_P_LOG, id, value);
+                                        found = 0;
+                                        for (i = 0; i &lt; MAX_CHATMESSAGES; i++) {
+                                                if (!strcmp(tech_pvt-&gt;chatmessages[i].id, id)) {
+                                                        strncpy(tech_pvt-&gt;chatmessages[i].body, value, sizeof(tech_pvt-&gt;chatmessages[i].body));
+                                                        found = 1;
+                                                        break;
+                                                }
+                                        }
+                                        if (!found) {
+                                                DEBUGA_SKYPE(&quot;why chatmessage %s was not found in the chatmessages array??\n&quot;, SKYPIAX_P_LOG, id);
+                                        } else {
+                                                DEBUGA_SKYPE
+                                                        (&quot;CHATMESSAGE %s is in position %d in the chatmessages array, type=%s, id=%s, chatname=%s, from_handle=%s, from_dispname=%s, body=%s\n&quot;,
+                                                         SKYPIAX_P_LOG, id, i, tech_pvt-&gt;chatmessages[i].type, tech_pvt-&gt;chatmessages[i].id, tech_pvt-&gt;chatmessages[i].chatname,
+                                                         tech_pvt-&gt;chatmessages[i].from_handle, tech_pvt-&gt;chatmessages[i].from_dispname, tech_pvt-&gt;chatmessages[i].body);
+                                                if (strcmp(tech_pvt-&gt;chatmessages[i].from_handle, tech_pvt-&gt;skype_user)) {        //if the message was not sent by myself
+                                                        incoming_chatmessage(tech_pvt, i);
+                                                }
+                                        }
+
+                                }
+
+                        }
+
+
+                        if (!strcasecmp(message, &quot;CALL&quot;)) {
+                                skypiax_strncpy(obj, where, sizeof(obj) - 1);
+                                where = strsep(stringp, &quot; &quot;);
+                                skypiax_strncpy(id, where, sizeof(id) - 1);
+                                where = strsep(stringp, &quot; &quot;);
+                                skypiax_strncpy(prop, where, sizeof(prop) - 1);
+                                where = strsep(stringp, &quot; &quot;);
+                                skypiax_strncpy(value, where, sizeof(value) - 1);
+                                where = strsep(stringp, &quot; &quot;);
+
+                                //DEBUGA_SKYPE
+                                //(&quot;Skype MSG: message: %s, obj: %s, id: %s, prop: %s, value: %s,where: %s!\n&quot;,
+                                //SKYPIAX_P_LOG, message, obj, id, prop, value, where ? where : &quot;NULL&quot;);
+
+                                if (!strcasecmp(prop, &quot;PARTNER_HANDLE&quot;)) {
+                                        if (tech_pvt-&gt;interface_state != SKYPIAX_STATE_SELECTED &amp;&amp; (!strlen(tech_pvt-&gt;skype_call_id) || !strlen(tech_pvt-&gt;session_uuid_str))) {
+                                                /* we are NOT inside an active call */
+                                                DEBUGA_SKYPE(&quot;Call %s TRY ANSWER\n&quot;, SKYPIAX_P_LOG, id);
+                                                skypiax_answer(tech_pvt, id, value);
+                                        } else {
+                                                /* we are inside an active call */
+                                                if (!strcasecmp(tech_pvt-&gt;skype_call_id, id)) {
+                                                        /* this is the call in which we are calling out */
+                                                        DEBUGA_SKYPE(&quot;Call %s DO NOTHING\n&quot;, SKYPIAX_P_LOG, id);
+                                                } else {
+                                                        skypiax_sleep(400000);        //0.4 seconds
+                                                        DEBUGA_SKYPE(&quot;Call %s TRY TRANSFER\n&quot;, SKYPIAX_P_LOG, id);
+                                                        skypiax_transfer(tech_pvt, id, value);
+                                                }
+                                        }
+                                }
+                                if (!strcasecmp(prop, &quot;PARTNER_DISPNAME&quot;)) {
+                                        snprintf(tech_pvt-&gt;callid_name, sizeof(tech_pvt-&gt;callid_name) - 1, &quot;%s%s%s&quot;, value, where ? &quot; &quot; : &quot;&quot;, where ? where : &quot;&quot;);
+                                        //DEBUGA_SKYPE
+                                        //(&quot;the skype_call %s caller PARTNER_DISPNAME (tech_pvt-&gt;callid_name) is: %s\n&quot;,
+                                        //SKYPIAX_P_LOG, id, tech_pvt-&gt;callid_name);
+                                }
+                                if (!strcasecmp(prop, &quot;CONF_ID&quot;) &amp;&amp; !strcasecmp(value, &quot;0&quot;)) {
+                                        //DEBUGA_SKYPE(&quot;the skype_call %s is NOT a conference call\n&quot;, SKYPIAX_P_LOG, id);
+                                        //if (tech_pvt-&gt;interface_state == SKYPIAX_STATE_DOWN)
+                                        //tech_pvt-&gt;interface_state = SKYPIAX_STATE_PRERING;
+                                }
+                                if (!strcasecmp(prop, &quot;CONF_ID&quot;) &amp;&amp; strcasecmp(value, &quot;0&quot;)) {
+                                        DEBUGA_SKYPE(&quot;the skype_call %s is a conference call\n&quot;, SKYPIAX_P_LOG, id);
+                                        //if (tech_pvt-&gt;interface_state == SKYPIAX_STATE_DOWN)
+                                        //tech_pvt-&gt;interface_state = SKYPIAX_STATE_PRERING;
+                                }
+                                if (!strcasecmp(prop, &quot;DTMF&quot;)) {
+                                        DEBUGA_SKYPE(&quot;Call %s received a DTMF: %s\n&quot;, SKYPIAX_P_LOG, id, value);
+                                        dtmf_received(tech_pvt, value);
+                                }
+                                if (!strcasecmp(prop, &quot;FAILUREREASON&quot;)) {
+                                        DEBUGA_SKYPE(&quot;Skype FAILED on skype_call %s. Let's wait for the FAILED message.\n&quot;, SKYPIAX_P_LOG, id);
+                                }
+                                if (!strcasecmp(prop, &quot;DURATION&quot;) &amp;&amp; (!strcasecmp(value, &quot;1&quot;))) {
+                                        if (strcasecmp(id, tech_pvt-&gt;skype_call_id)) {
+                                                skypiax_strncpy(tech_pvt-&gt;skype_call_id, id, sizeof(tech_pvt-&gt;skype_call_id) - 1);
+                                                DEBUGA_SKYPE(&quot;We called a Skype contact and he answered us on skype_call: %s.\n&quot;, SKYPIAX_P_LOG, id);
+                                        }
+                                }
+
+                                if (!strcasecmp(prop, &quot;DURATION&quot;) &amp;&amp; (tech_pvt-&gt;interface_state == SKYPIAX_STATE_ERROR_DOUBLE_CALL)) {
+                                        char msg_to_skype[1024];
+                                        skypiax_strncpy(tech_pvt-&gt;skype_call_id, id, sizeof(tech_pvt-&gt;skype_call_id) - 1);
+                                        ERRORA(&quot;We are in a double call situation, trying to get out hanging up call id: %s.\n&quot;, SKYPIAX_P_LOG, id);
+                                        sprintf(msg_to_skype, &quot;ALTER CALL %s HANGUP&quot;, id);
+                                        skypiax_signaling_write(tech_pvt, msg_to_skype);
+                                        skypiax_sleep(10000);
+                                        //return CALLFLOW_INCOMING_HANGUP;
+                                }
+
+                                if (!strcasecmp(prop, &quot;STATUS&quot;)) {
+
+                                        if (!strcasecmp(value, &quot;RINGING&quot;)) {
+                                                char msg_to_skype[1024];
+                                                if ((tech_pvt-&gt;interface_state != SKYPIAX_STATE_SELECTED &amp;&amp; tech_pvt-&gt;interface_state != SKYPIAX_STATE_DIALING)
+                                                        &amp;&amp; (!strlen(tech_pvt-&gt;skype_call_id) || !strlen(tech_pvt-&gt;session_uuid_str))) {
+                                                        /* we are NOT inside an active call */
+
+                                                        DEBUGA_SKYPE(&quot;NO ACTIVE calls in this moment, skype_call %s is RINGING, to ask PARTNER_HANDLE\n&quot;, SKYPIAX_P_LOG, id);
+                                                        sprintf(msg_to_skype, &quot;GET CALL %s PARTNER_HANDLE&quot;, id);
+                                                        skypiax_signaling_write(tech_pvt, msg_to_skype);
+                                                        skypiax_sleep(10000);
+                                                } else {
+                                                        /* we are inside an active call */
+                                                        if (!strcasecmp(tech_pvt-&gt;skype_call_id, id)) {
+                                                                /* this is the call in which we are calling out */
+                                                                tech_pvt-&gt;skype_callflow = CALLFLOW_STATUS_RINGING;
+                                                                tech_pvt-&gt;interface_state = SKYPIAX_STATE_RINGING;
+                                                                skypiax_strncpy(tech_pvt-&gt;skype_call_id, id, sizeof(tech_pvt-&gt;skype_call_id) - 1);
+                                                                DEBUGA_SKYPE(&quot;Our remote party in skype_call %s is RINGING\n&quot;, SKYPIAX_P_LOG, id);
+                                                                remote_party_is_ringing(tech_pvt);
+                                                        } else {
+                                                                DEBUGA_SKYPE
+                                                                        (&quot;We are in another call, but skype_call %s is RINGING on us, let's ask PARTNER_HANDLE, so maybe we'll TRANSFER\n&quot;,
+                                                                         SKYPIAX_P_LOG, id);
+                                                                sprintf(msg_to_skype, &quot;GET CALL %s PARTNER_HANDLE&quot;, id);
+                                                                skypiax_signaling_write(tech_pvt, msg_to_skype);
+                                                                skypiax_sleep(10000);
+                                                        }
+                                                }
+                                        } else if (!strcasecmp(value, &quot;EARLYMEDIA&quot;)) {
+                                                char msg_to_skype[1024];
+                                                tech_pvt-&gt;skype_callflow = CALLFLOW_STATUS_EARLYMEDIA;
+                                                tech_pvt-&gt;interface_state = SKYPIAX_STATE_DIALING;
+                                                DEBUGA_SKYPE(&quot;Our remote party in skype_call %s is EARLYMEDIA\n&quot;, SKYPIAX_P_LOG, id);
+                                                if (tech_pvt-&gt;tcp_cli_thread == NULL) {
+                                                        DEBUGA_SKYPE(&quot;START start_audio_threads\n&quot;, SKYPIAX_P_LOG);
+                                                        if (start_audio_threads(tech_pvt)) {
+                                                                ERRORA(&quot;start_audio_threads FAILED\n&quot;, SKYPIAX_P_LOG);
+                                                                return CALLFLOW_INCOMING_HANGUP;
+                                                        }
+                                                }
+                                                skypiax_sleep(1000);
+                                                sprintf(msg_to_skype, &quot;ALTER CALL %s SET_INPUT PORT=\&quot;%d\&quot;&quot;, id, tech_pvt-&gt;tcp_cli_port);
+                                                skypiax_signaling_write(tech_pvt, msg_to_skype);
+                                                sprintf(msg_to_skype, &quot;#output ALTER CALL %s SET_OUTPUT PORT=\&quot;%d\&quot;&quot;, id, tech_pvt-&gt;tcp_srv_port);
+                                                skypiax_signaling_write(tech_pvt, msg_to_skype);
+
+                                                remote_party_is_early_media(tech_pvt);
+                                        } else if (!strcasecmp(value, &quot;MISSED&quot;)) {
+                                                DEBUGA_SKYPE(&quot;We missed skype_call %s\n&quot;, SKYPIAX_P_LOG, id);
+                                        } else if (!strcasecmp(value, &quot;FINISHED&quot;)) {
+                                                //DEBUGA_SKYPE(&quot;skype_call %s now is DOWN\n&quot;, SKYPIAX_P_LOG, id);
+                                                if (!strcasecmp(tech_pvt-&gt;skype_call_id, id)) {
+                                                        //tech_pvt-&gt;skype_callflow = CALLFLOW_STATUS_FINISHED;
+                                                        DEBUGA_SKYPE(&quot;skype_call %s is MY call, now I'm going DOWN\n&quot;, SKYPIAX_P_LOG, id);
+                                                        //tech_pvt-&gt;skype_call_id[0] = '\0';
+                                                        if (tech_pvt-&gt;interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) {
+                                                                //tech_pvt-&gt;interface_state = SKYPIAX_STATE_DOWN;
+                                                                return CALLFLOW_INCOMING_HANGUP;
+                                                        } else {
+                                                                tech_pvt-&gt;interface_state = SKYPIAX_STATE_DOWN;
+                                                        }
+                                                } else {
+                                                        DEBUGA_SKYPE(&quot;skype_call %s is NOT MY call, ignoring\n&quot;, SKYPIAX_P_LOG, id);
+                                                }
+
+                                        } else if (!strcasecmp(value, &quot;CANCELLED&quot;)) {
+                                                tech_pvt-&gt;skype_callflow = CALLFLOW_STATUS_CANCELLED;
+                                                DEBUGA_SKYPE(&quot;we tried to call Skype on skype_call %s and Skype has now CANCELLED\n&quot;, SKYPIAX_P_LOG, id);
+                                                tech_pvt-&gt;skype_call_id[0] = '\0';
+                                                if (tech_pvt-&gt;interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) {
+                                                        tech_pvt-&gt;interface_state = SKYPIAX_STATE_DOWN;
+                                                        return CALLFLOW_INCOMING_HANGUP;
+                                                } else {
+                                                        tech_pvt-&gt;interface_state = SKYPIAX_STATE_DOWN;
+                                                }
+                                        } else if (!strcasecmp(value, &quot;FAILED&quot;)) {
+                                                tech_pvt-&gt;skype_callflow = CALLFLOW_STATUS_FAILED;
+                                                DEBUGA_SKYPE(&quot;we tried to call Skype on skype_call %s and Skype has now FAILED\n&quot;, SKYPIAX_P_LOG, id);
+                                                tech_pvt-&gt;skype_call_id[0] = '\0';
+                                                skypiax_strncpy(tech_pvt-&gt;skype_call_id, id, sizeof(tech_pvt-&gt;skype_call_id) - 1);
+                                                tech_pvt-&gt;interface_state = SKYPIAX_STATE_DOWN;
+                                                return CALLFLOW_INCOMING_HANGUP;
+                                        } else if (!strcasecmp(value, &quot;REFUSED&quot;)) {
+                                                if (!strcasecmp(id, tech_pvt-&gt;skype_call_id)) {
+                                                        /* this is the id of the call we are in, probably we generated it */
+                                                        tech_pvt-&gt;skype_callflow = CALLFLOW_STATUS_REFUSED;
+                                                        DEBUGA_SKYPE(&quot;we tried to call Skype on skype_call %s and Skype has now REFUSED\n&quot;, SKYPIAX_P_LOG, id);
+                                                        skypiax_strncpy(tech_pvt-&gt;skype_call_id, id, sizeof(tech_pvt-&gt;skype_call_id) - 1);
+                                                        tech_pvt-&gt;interface_state = SKYPIAX_STATE_DOWN;
+                                                        tech_pvt-&gt;skype_call_id[0] = '\0';
+                                                        return CALLFLOW_INCOMING_HANGUP;
+                                                } else {
+                                                        /* we're here because were us that refused an incoming call */
+                                                        DEBUGA_SKYPE(&quot;we REFUSED skype_call %s\n&quot;, SKYPIAX_P_LOG, id);
+                                                }
+                                        } else if (!strcasecmp(value, &quot;TRANSFERRING&quot;)) {
+                                                DEBUGA_SKYPE(&quot;skype_call %s is transferring\n&quot;, SKYPIAX_P_LOG, id);
+                                        } else if (!strcasecmp(value, &quot;TRANSFERRED&quot;)) {
+                                                DEBUGA_SKYPE(&quot;skype_call %s has been transferred\n&quot;, SKYPIAX_P_LOG, id);
+                                        } else if (!strcasecmp(value, &quot;ROUTING&quot;)) {
+                                                tech_pvt-&gt;skype_callflow = CALLFLOW_STATUS_ROUTING;
+                                                tech_pvt-&gt;interface_state = SKYPIAX_STATE_DIALING;
+                                                skypiax_strncpy(tech_pvt-&gt;skype_call_id, id, sizeof(tech_pvt-&gt;skype_call_id) - 1);
+                                                DEBUGA_SKYPE(&quot;skype_call: %s is now ROUTING\n&quot;, SKYPIAX_P_LOG, id);
+                                        } else if (!strcasecmp(value, &quot;UNPLACED&quot;)) {
+                                                tech_pvt-&gt;skype_callflow = CALLFLOW_STATUS_UNPLACED;
+                                                tech_pvt-&gt;interface_state = SKYPIAX_STATE_DIALING;
+                                                skypiax_strncpy(tech_pvt-&gt;skype_call_id, id, sizeof(tech_pvt-&gt;skype_call_id) - 1);
+                                                DEBUGA_SKYPE(&quot;skype_call: %s is now UNPLACED\n&quot;, SKYPIAX_P_LOG, id);
+                                        } else if (!strcasecmp(value, &quot;INPROGRESS&quot;)) {
+                                                char msg_to_skype[1024];
+
+                                                if (!strlen(tech_pvt-&gt;session_uuid_str)) {
+                                                        DEBUGA_SKYPE(&quot;no tech_pvt-&gt;session_uuid_str\n&quot;, SKYPIAX_P_LOG);
+                                                }
+                                                if (tech_pvt-&gt;skype_callflow != CALLFLOW_STATUS_REMOTEHOLD) {
+                                                        if (!strlen(tech_pvt-&gt;session_uuid_str) || !strlen(tech_pvt-&gt;skype_call_id)
+                                                                || !strcasecmp(tech_pvt-&gt;skype_call_id, id)) {
+                                                                skypiax_strncpy(tech_pvt-&gt;skype_call_id, id, sizeof(tech_pvt-&gt;skype_call_id) - 1);
+                                                                DEBUGA_SKYPE(&quot;skype_call: %s is now active\n&quot;, SKYPIAX_P_LOG, id);
+
+                                                                if (tech_pvt-&gt;skype_callflow != CALLFLOW_STATUS_EARLYMEDIA) {
+                                                                        tech_pvt-&gt;skype_callflow = CALLFLOW_STATUS_INPROGRESS;
+                                                                        tech_pvt-&gt;interface_state = SKYPIAX_STATE_UP;
+
+                                                                        if (tech_pvt-&gt;tcp_cli_thread == NULL) {
+                                                                                DEBUGA_SKYPE(&quot;START start_audio_threads\n&quot;, SKYPIAX_P_LOG);
+                                                                                if (start_audio_threads(tech_pvt)) {
+                                                                                        ERRORA(&quot;start_audio_threads FAILED\n&quot;, SKYPIAX_P_LOG);
+                                                                                        return CALLFLOW_INCOMING_HANGUP;
+                                                                                }
+                                                                        }
+                                                                        skypiax_sleep(1000);        //FIXME
+                                                                        sprintf(msg_to_skype, &quot;ALTER CALL %s SET_INPUT PORT=\&quot;%d\&quot;&quot;, id, tech_pvt-&gt;tcp_cli_port);
+                                                                        skypiax_signaling_write(tech_pvt, msg_to_skype);
+                                                                        skypiax_sleep(1000);        //FIXME
+                                                                        sprintf(msg_to_skype, &quot;#output ALTER CALL %s SET_OUTPUT PORT=\&quot;%d\&quot;&quot;, id, tech_pvt-&gt;tcp_srv_port);
+                                                                        skypiax_signaling_write(tech_pvt, msg_to_skype);
+                                                                }
+                                                                tech_pvt-&gt;skype_callflow = CALLFLOW_STATUS_INPROGRESS;
+                                                                if (!strlen(tech_pvt-&gt;session_uuid_str)) {
+                                                                        DEBUGA_SKYPE(&quot;New Inbound Channel!\n\n\n\n&quot;, SKYPIAX_P_LOG);
+                                                                        new_inbound_channel(tech_pvt);
+                                                                } else {
+                                                                        tech_pvt-&gt;interface_state = SKYPIAX_STATE_UP;
+                                                                        DEBUGA_SKYPE(&quot;Outbound Channel Answered! session_uuid_str=%s\n&quot;, SKYPIAX_P_LOG, tech_pvt-&gt;session_uuid_str);
+                                                                        outbound_channel_answered(tech_pvt);
+                                                                }
+                                                        } else {
+                                                                DEBUGA_SKYPE(&quot;I'm on %s, skype_call %s is NOT MY call, ignoring\n&quot;, SKYPIAX_P_LOG, tech_pvt-&gt;skype_call_id, id);
+                                                        }
+                                                } else {
+                                                        tech_pvt-&gt;skype_callflow = CALLFLOW_STATUS_INPROGRESS;
+                                                        DEBUGA_SKYPE(&quot;Back from REMOTEHOLD!\n&quot;, SKYPIAX_P_LOG);
+                                                }
+
+                                        } else if (!strcasecmp(value, &quot;REMOTEHOLD&quot;)) {
+                                                tech_pvt-&gt;skype_callflow = CALLFLOW_STATUS_REMOTEHOLD;
+                                                DEBUGA_SKYPE(&quot;skype_call: %s is now REMOTEHOLD\n&quot;, SKYPIAX_P_LOG, id);
+
+                                        } else if (!strcasecmp(value, &quot;BUSY&quot;)) {
+                                                tech_pvt-&gt;skype_callflow = CALLFLOW_STATUS_FAILED;
+                                                DEBUGA_SKYPE
+                                                        (&quot;we tried to call Skype on skype_call %s and remote party (destination) was BUSY. Our outbound call has failed\n&quot;,
+                                                         SKYPIAX_P_LOG, id);
+                                                skypiax_strncpy(tech_pvt-&gt;skype_call_id, id, sizeof(tech_pvt-&gt;skype_call_id) - 1);
+                                                tech_pvt-&gt;interface_state = SKYPIAX_STATE_DOWN;
+                                                tech_pvt-&gt;skype_call_id[0] = '\0';
+                                                skypiax_sleep(1000);
+                                                return CALLFLOW_INCOMING_HANGUP;
+                                        } else if (!strcasecmp(value, &quot;WAITING_REDIAL_COMMAND&quot;)) {
+                                                tech_pvt-&gt;skype_callflow = CALLFLOW_STATUS_FAILED;
+                                                DEBUGA_SKYPE
+                                                        (&quot;we tried to call Skype on skype_call %s and remote party (destination) has rejected us (WAITING_REDIAL_COMMAND). Our outbound call has failed\n&quot;,
+                                                         SKYPIAX_P_LOG, id);
+                                                skypiax_strncpy(tech_pvt-&gt;skype_call_id, id, sizeof(tech_pvt-&gt;skype_call_id) - 1);
+                                                tech_pvt-&gt;interface_state = SKYPIAX_STATE_DOWN;
+                                                tech_pvt-&gt;skype_call_id[0] = '\0';
+                                                skypiax_sleep(1000);
+                                                return CALLFLOW_INCOMING_HANGUP;
+                                        } else {
+                                                WARNINGA(&quot;skype_call: %s, STATUS: %s is not recognized\n&quot;, SKYPIAX_P_LOG, id, value);
+                                        }
+                                }                                //STATUS
+                        }                                        //CALL
+                        /* the &quot;numbered&quot; messages that follows are used by the directory application, not yet ported */
+                        if (!strcasecmp(message, &quot;#333&quot;)) {
+                                /* DEBUGA_SKYPE(&quot;Skype MSG: message_2: %s, message2[11]: %s\n&quot;, SKYPIAX_P_LOG,
+                                 * message_2, &amp;message_2[11]); */
+                                memset(tech_pvt-&gt;skype_friends, 0, 4096);
+                                skypiax_strncpy(tech_pvt-&gt;skype_friends, &amp;message_2[11], 4095);
+                        }
+                        if (!strcasecmp(message, &quot;#222&quot;)) {
+                                /* DEBUGA_SKYPE(&quot;Skype MSG: message_2: %s, message2[10]: %s\n&quot;, SKYPIAX_P_LOG,
+                                 * message_2, &amp;message_2[10]); */
+                                memset(tech_pvt-&gt;skype_fullname, 0, 512);
+                                skypiax_strncpy(tech_pvt-&gt;skype_fullname, &amp;message_2[10], 511);
+                        }
+                        if (!strcasecmp(message, &quot;#765&quot;)) {
+                                /* DEBUGA_SKYPE(&quot;Skype MSG: message_2: %s, message2[10]: %s\n&quot;, SKYPIAX_P_LOG,
+                                 * message_2, &amp;message_2[10]); */
+                                memset(tech_pvt-&gt;skype_displayname, 0, 512);
+                                skypiax_strncpy(tech_pvt-&gt;skype_displayname, &amp;message_2[10], 511);
+                        }
+                        a = 0;
+                }                                                //message end
+        }                                                        //read_from_pipe
+        return 0;
+}
+
+void *skypiax_do_tcp_srv_thread_func(void *obj)
+{
+        private_t *tech_pvt = obj;
+        int s;
+        //unsigned int len;
+        //unsigned int i;
+        //unsigned int a;
+#if defined(WIN32) &amp;&amp; !defined(__CYGWIN__)
+        int sin_size;
+#else /* WIN32 */
+        unsigned int sin_size;
+#endif /* WIN32 */
+        unsigned int fd;
+        //short srv_in[SAMPLES_PER_FRAME];
+        //short srv_out[SAMPLES_PER_FRAME / 2];
+        //struct sockaddr_in my_addr;
+        struct sockaddr_in remote_addr;
+        //int exit = 0;
+        //unsigned int kill_cli_size;
+        //short kill_cli_buff[SAMPLES_PER_FRAME];
+        //short totalbuf[SAMPLES_PER_FRAME];
+        int sockbufsize = 0;
+        unsigned int size = sizeof(int);
+
+        s = skypiax_socket_create_and_bind(tech_pvt, &amp;tech_pvt-&gt;tcp_srv_port);
+        if (s &lt; 0) {
+                ERRORA(&quot;skypiax_socket_create_and_bind error!\n&quot;, SKYPIAX_P_LOG);
+                return NULL;
+        }
+        DEBUGA_SKYPE(&quot;started tcp_srv_thread thread.\n&quot;, SKYPIAX_P_LOG);
+
+        listen(s, 6);
+
+        sin_size = sizeof(remote_addr);
+
+  /****************************/
+        while (tech_pvt-&gt;interface_state != SKYPIAX_STATE_DOWN
+                   &amp;&amp; (tech_pvt-&gt;skype_callflow == CALLFLOW_STATUS_INPROGRESS
+                           || tech_pvt-&gt;skype_callflow == CALLFLOW_STATUS_EARLYMEDIA
+                           || tech_pvt-&gt;skype_callflow == CALLFLOW_STATUS_REMOTEHOLD || tech_pvt-&gt;skype_callflow == SKYPIAX_STATE_UP)) {
+
+                unsigned int fdselectgio;
+                int rtgio;
+                fd_set fsgio;
+                struct timeval togio;
+
+                if (!(running &amp;&amp; tech_pvt-&gt;running))
+                        break;
+                FD_ZERO(&amp;fsgio);
+                togio.tv_usec = 20000;        //20msec
+                togio.tv_sec = 0;
+                fdselectgio = s;
+                FD_SET(fdselectgio, &amp;fsgio);
+
+                rtgio = select(fdselectgio + 1, &amp;fsgio, NULL, NULL, &amp;togio);
+
+                if (rtgio) {
+
+  /****************************/
+
+                        while (s &gt; 0 &amp;&amp; (fd = accept(s, (struct sockaddr *) &amp;remote_addr, &amp;sin_size)) &gt; 0) {
+                                DEBUGA_SKYPE(&quot;ACCEPTED here I send you %d\n&quot;, SKYPIAX_P_LOG, tech_pvt-&gt;tcp_srv_port);
+
+                                sockbufsize = 0;
+                                size = sizeof(int);
+                                getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *) &amp;sockbufsize, &amp;size);
+                                DEBUGA_SKYPE(&quot;3 SO_RCVBUF is %d, size is %d\n&quot;, SKYPIAX_P_LOG, sockbufsize, size);
+                                sockbufsize = 0;
+                                size = sizeof(int);
+                                getsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *) &amp;sockbufsize, &amp;size);
+                                DEBUGA_SKYPE(&quot;3 SO_SNDBUF is %d, size is %d\n&quot;, SKYPIAX_P_LOG, sockbufsize, size);
+
+
+                                if (!(running &amp;&amp; tech_pvt-&gt;running))
+                                        break;
+                                while (tech_pvt-&gt;interface_state != SKYPIAX_STATE_DOWN
+                                           &amp;&amp; (tech_pvt-&gt;skype_callflow == CALLFLOW_STATUS_INPROGRESS
+                                                   || tech_pvt-&gt;skype_callflow == CALLFLOW_STATUS_EARLYMEDIA
+                                                   || tech_pvt-&gt;skype_callflow == CALLFLOW_STATUS_REMOTEHOLD || tech_pvt-&gt;skype_callflow == SKYPIAX_STATE_UP)) {
+
+                                        tech_pvt-&gt;readfd = fd;
+                                                //WARNINGA(&quot;read HERE\n&quot;, SKYPIAX_P_LOG);
+                                                skypiax_sleep(100000);
+
+
+#if 0
+
+                                        unsigned int fdselect;
+                                        int rt;
+                                        fd_set fs;
+                                        struct timeval to;
+
+                                        if (!(running &amp;&amp; tech_pvt-&gt;running))
+                                                break;
+                                        //exit = 1;
+
+                                        fdselect = fd;
+                                        FD_ZERO(&amp;fs);
+                                        FD_SET(fdselect, &amp;fs);
+                                        //to.tv_usec = 2000000;     //2000 msec
+                                        to.tv_usec = 60000;        //60 msec
+                                        to.tv_sec = 0;
+
+                                        rt = select(fdselect + 1, &amp;fs, NULL, NULL, &amp;to);
+                                        if (rt &gt; 0) {
+
+                                                if (tech_pvt-&gt;skype_callflow != CALLFLOW_STATUS_REMOTEHOLD) {
+                                                        len = recv(fd, (char *) srv_in, 320, 0);        //seems that Skype only sends 320 bytes at time
+                                                } else {
+                                                        len = 0;
+                                                }
+
+                                                if (len == 320) {
+                                                        unsigned int howmany;
+
+                                                        if (samplerate_skypiax == 8000) {
+                                                                /* we're downsampling from 16khz to 8khz, srv_out will contain each other sample from srv_in */
+                                                                a = 0;
+                                                                for (i = 0; i &lt; len / sizeof(short); i++) {
+                                                                        srv_out[a] = srv_in[i];
+                                                                        i++;
+                                                                        a++;
+                                                                }
+                                                        } else if (samplerate_skypiax == 16000) {
+                                                                /* we're NOT downsampling, srv_out will contain ALL samples from srv_in */
+                                                                for (i = 0; i &lt; len / sizeof(short); i++) {
+                                                                        srv_out[i] = srv_in[i];
+                                                                }
+                                                        } else {
+                                                                ERRORA(&quot;SAMPLERATE_SKYPIAX can only be 8000 or 16000\n&quot;, SKYPIAX_P_LOG);
+                                                        }
+                                                        /* if not yet done, let's store the half incoming frame */
+                                                        if (!tech_pvt-&gt;audiobuf_is_loaded) {
+                                                                for (i = 0; i &lt; SAMPLES_PER_FRAME / 2; i++) {
+                                                                        tech_pvt-&gt;audiobuf[i] = srv_out[i];
+                                                                }
+                                                                tech_pvt-&gt;audiobuf_is_loaded = 1;
+                                                        } else {
+                                                                /* we got a stored half frame, build a complete frame in totalbuf using the stored half frame and the current half frame */
+                                                                for (i = 0; i &lt; SAMPLES_PER_FRAME / 2; i++) {
+                                                                        totalbuf[i] = tech_pvt-&gt;audiobuf[i];
+                                                                }
+                                                                for (a = 0; a &lt; SAMPLES_PER_FRAME / 2; a++) {
+                                                                        totalbuf[i] = srv_out[a];
+                                                                        i++;
+                                                                }
+                                                                /* send the complete frame through the pipe to our code waiting for incoming audio */
+                                                                //howmany = skypiax_pipe_write(tech_pvt-&gt;audiopipe_srv[1], totalbuf, SAMPLES_PER_FRAME * sizeof(short));
+                                                                //FIXME while(tech_pvt-&gt;flag_audio_srv == 1){
+                                                                //FIXME switch_sleep(100); //1 millisec
+                                                                //NOTICA(&quot;read now is 1\n&quot;, SKYPIAX_P_LOG);
+                                                                //FIXME }
+                                                                //WARNINGA(&quot;read is now 0\n&quot;, SKYPIAX_P_LOG);
+
+
+                                                                howmany = SAMPLES_PER_FRAME * sizeof(short);
+                                                                //while (tech_pvt-&gt;flag_audio_srv == 1) {
+                                                                        //switch_sleep(1000);        //10 millisec
+                                                //WARNINGA(&quot;read now is 1\n&quot;, SKYPIAX_P_LOG);
+                                                                //}
+                                                                //if (tech_pvt-&gt;flag_audio_srv == 0) {
+        //switch_mutex_lock(tech_pvt-&gt;flag_audio_srv_mutex);
+                                                                        memcpy(tech_pvt-&gt;audiobuf_srv, totalbuf, SAMPLES_PER_FRAME * sizeof(short));
+                                                                        tech_pvt-&gt;flag_audio_srv = 1;
+        //switch_mutex_unlock(tech_pvt-&gt;flag_audio_srv_mutex);
+                                                                //}
+                                                                //NOTICA(&quot;read \n&quot;, SKYPIAX_P_LOG);
+                                                                if (howmany != SAMPLES_PER_FRAME * sizeof(short)) {
+                                                                        ERRORA(&quot;howmany is %d, but was expected to be %d\n&quot;, SKYPIAX_P_LOG,
+                                                                                   howmany, (int) (SAMPLES_PER_FRAME * sizeof(short)));
+                                                                }
+                                                                /* done with the stored half frame */
+                                                                tech_pvt-&gt;audiobuf_is_loaded = 0;
+                                                        }
+
+                                                } else if (len == 0) {
+                                                        skypiax_sleep(1000);
+                                                } else {
+                                                        DEBUGA_SKYPE(&quot;len=%d, expected 320\n&quot;, SKYPIAX_P_LOG, len);
+                                                }
+
+                                        } else {
+                                                if (rt)
+                                                        ERRORA(&quot;SRV rt=%d\n&quot;, SKYPIAX_P_LOG, rt);
+                                                skypiax_sleep(10000);
+                                        }
+
+#endif// 0
+                                }
+
+                                skypiax_sleep(2000);
+                                DEBUGA_SKYPE(&quot;Skype incoming audio GONE\n&quot;, SKYPIAX_P_LOG);
+                                skypiax_close_socket(fd);
+                                fd = -1;
+                                break;
+                        }
+                }
+        }
+
+        DEBUGA_SKYPE(&quot;incoming audio server (I am it) EXITING\n&quot;, SKYPIAX_P_LOG);
+        skypiax_close_socket(s);
+        s = -1;
+        return NULL;
+}
+
+void *skypiax_do_tcp_cli_thread_func(void *obj)
+{
+        private_t *tech_pvt = obj;
+        int s=0;
+        //struct sockaddr_in my_addr;
+        struct sockaddr_in remote_addr;
+#if 0
+        unsigned int got;
+        unsigned int len;
+        unsigned int i;
+        unsigned int a;
+        short cli_out[SAMPLES_PER_FRAME * 2];
+        short cli_in[SAMPLES_PER_FRAME];
+#endif// 0
+        unsigned int fd=0;
+#ifdef WIN32
+        int sin_size;
+#else
+        unsigned int sin_size;
+#endif /* WIN32 */
+        int sockbufsize = 0;
+        unsigned int size = sizeof(int);
+
+        s = skypiax_socket_create_and_bind(tech_pvt, &amp;tech_pvt-&gt;tcp_cli_port);
+        if (s &lt; 0) {
+                ERRORA(&quot;skypiax_socket_create_and_bind error!\n&quot;, SKYPIAX_P_LOG);
+                return NULL;
+        }
+
+
+
+        DEBUGA_SKYPE(&quot;started tcp_cli_thread thread.\n&quot;, SKYPIAX_P_LOG);
+
+        listen(s, 6);
+
+        sin_size = sizeof(remote_addr);
+
+  /****************************/
+        while (tech_pvt-&gt;interface_state != SKYPIAX_STATE_DOWN
+                   &amp;&amp; (tech_pvt-&gt;skype_callflow == CALLFLOW_STATUS_INPROGRESS
+                           || tech_pvt-&gt;skype_callflow == CALLFLOW_STATUS_EARLYMEDIA
+                           || tech_pvt-&gt;skype_callflow == CALLFLOW_STATUS_REMOTEHOLD || tech_pvt-&gt;skype_callflow == SKYPIAX_STATE_UP)) {
+
+                unsigned int fdselectgio;
+                int rtgio;
+                fd_set fsgio;
+                struct timeval togio;
+
+                if (!(running &amp;&amp; tech_pvt-&gt;running))
+                        break;
+                FD_ZERO(&amp;fsgio);
+                togio.tv_usec = 20000;        //20msec
+                togio.tv_sec = 0;
+                fdselectgio = s;
+                FD_SET(fdselectgio, &amp;fsgio);
+
+                rtgio = select(fdselectgio + 1, &amp;fsgio, NULL, NULL, &amp;togio);
+
+                if (rtgio) {
+
+  /****************************/
+
+                        while (s &gt; 0 &amp;&amp; (fd = accept(s, (struct sockaddr *) &amp;remote_addr, &amp;sin_size)) &gt; 0) {
+                                DEBUGA_SKYPE(&quot;ACCEPTED here you send me %d\n&quot;, SKYPIAX_P_LOG, tech_pvt-&gt;tcp_cli_port);
+
+                                sockbufsize = 0;
+                                size = sizeof(int);
+                                getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *) &amp;sockbufsize, &amp;size);
+                                DEBUGA_SKYPE(&quot;4 SO_RCVBUF is %d, size is %d\n&quot;, SKYPIAX_P_LOG, sockbufsize, size);
+                                sockbufsize = 0;
+                                size = sizeof(int);
+                                getsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *) &amp;sockbufsize, &amp;size);
+                                DEBUGA_SKYPE(&quot;4 SO_SNDBUF is %d, size is %d\n&quot;, SKYPIAX_P_LOG, sockbufsize, size);
+
+
+
+                                if (!(running &amp;&amp; tech_pvt-&gt;running))
+                                        break;
+
+
+
+
+                                while (tech_pvt-&gt;interface_state != SKYPIAX_STATE_DOWN
+                                           &amp;&amp; (tech_pvt-&gt;skype_callflow == CALLFLOW_STATUS_INPROGRESS
+                                                   || tech_pvt-&gt;skype_callflow == CALLFLOW_STATUS_EARLYMEDIA
+                                                   || tech_pvt-&gt;skype_callflow == CALLFLOW_STATUS_REMOTEHOLD || tech_pvt-&gt;skype_callflow == SKYPIAX_STATE_UP)) {
+                                        tech_pvt-&gt;writefd = fd;
+                                                //NOTICA(&quot;write HERE\n&quot;, SKYPIAX_P_LOG);
+                                                skypiax_sleep(100000);
+#if 0
+#ifdef NOVARS
+                                        unsigned int fdselect;
+                                        int rt;
+                                        fd_set fs;
+                                        struct timeval to;
+
+                                        if (!(running &amp;&amp; tech_pvt-&gt;running))
+                                                break;
+                                        FD_ZERO(&amp;fs);
+                                        to.tv_usec = 120000;        //120msec
+                                        to.tv_sec = 0;
+#if defined(WIN32) &amp;&amp; !defined(__CYGWIN__)
+/* on win32 we cannot select from the apr &quot;pipe&quot;, so we select on socket writability */
+                                        fdselect = fd;
+                                        FD_SET(fdselect, &amp;fs);
+
+                                        //rt = select(fdselect + 1, NULL, &amp;fs, NULL, &amp;to);
+#else
+/* on *unix and cygwin we select from the real pipe */
+                                        //XXX fdselect = tech_pvt-&gt;audiopipe_cli[0];
+                                        //XXX FD_SET(fdselect, &amp;fs);
+
+                                        //rt = select(fdselect + 1, &amp;fs, NULL, NULL, &amp;to);
+#endif
+                                        fdselect = fd;
+                                        FD_SET(fdselect, &amp;fs);
+
+#endif// NOVARS
+#if 0
+                                        rt = select(fdselect + 1, NULL, &amp;fs, NULL, NULL);
+                                        while (tech_pvt-&gt;flag_audio_cli == 0) {
+#ifdef WIN32
+                                                skypiax_sleep(100);        //0.1 millisec
+#else
+                                                skypiax_sleep(1000);        //10 millisec
+#endif //WIN32
+                                                NOTICA(&quot;write now is 0\n&quot;, SKYPIAX_P_LOG);
+                                        }
+                                        //ERRORA(&quot;write is now 1\n&quot;, SKYPIAX_P_LOG);
+
+                                        rt = 1;
+#endif //0
+                                        //rt = select(fdselect + 1, NULL, &amp;fs, NULL, NULL);
+
+#ifdef NOLOOP
+                                        if (rt &gt; 0) {
+                                                int counter;
+#if 0
+                                        while (tech_pvt-&gt;flag_audio_cli == 0) {
+#ifdef WIN32
+                                                skypiax_sleep(100);        //0.1 millisec
+#else
+                                                skypiax_sleep(10000);        //10 millisec
+#endif //WIN32
+                                                WARNINGA(&quot;write now is 0\n&quot;, SKYPIAX_P_LOG);
+                                        }
+#endif //0
+        
+                                                /* until we drained the pipe to empty */
+                                                for (counter = 0; counter &lt; 1; counter++) {
+                                                        /* read from the pipe the audio frame we are supposed to send out */
+                                                        //got = skypiax_pipe_read(tech_pvt-&gt;audiopipe_cli[0], cli_in, SAMPLES_PER_FRAME * sizeof(short));
+
+
+                                                        got = SAMPLES_PER_FRAME * sizeof(short);
+        switch_mutex_lock(tech_pvt-&gt;flag_audio_cli_mutex);
+                                                        memcpy(cli_in, tech_pvt-&gt;audiobuf_cli, SAMPLES_PER_FRAME * sizeof(short));
+
+
+
+
+                                                        if (got == -1)
+                                                                break;
+
+                                                        if (got != SAMPLES_PER_FRAME * sizeof(short)) {
+                                                                WARNINGA(&quot;got is %d, but was expected to be %d\n&quot;, SKYPIAX_P_LOG, got, (int) (SAMPLES_PER_FRAME * sizeof(short)));
+                                                        }
+
+                                                        if (got == SAMPLES_PER_FRAME * sizeof(short)) {
+                                                                if (samplerate_skypiax == 8000) {
+
+                                                                        /* we're upsampling from 8khz to 16khz, cli_out will contain two times each sample from cli_in */
+                                                                        a = 0;
+                                                                        for (i = 0; i &lt; got / sizeof(short); i++) {
+                                                                                cli_out[a] = cli_in[i];
+                                                                                a++;
+                                                                                cli_out[a] = cli_in[i];
+                                                                                a++;
+                                                                        }
+                                                                        got = got * 2;
+                                                                } else if (samplerate_skypiax == 16000) {
+                                                                        /* we're NOT upsampling, cli_out will contain just ALL samples from cli_in */
+                                                                        for (i = 0; i &lt; got / sizeof(short); i++) {
+                                                                                cli_out[i] = cli_in[i];
+                                                                        }
+                                                                } else {
+                                                                        ERRORA(&quot;SAMPLERATE_SKYPIAX can only be 8000 or 16000\n&quot;, SKYPIAX_P_LOG);
+                                                                }
+
+                                                                /* send the 16khz frame to the Skype client waiting for incoming audio to be sent to the remote party */
+                                                                if (tech_pvt-&gt;skype_callflow != CALLFLOW_STATUS_REMOTEHOLD) {
+                                                                        len = send(fd, (char *) cli_out, got, 0);
+                                                        tech_pvt-&gt;flag_audio_cli = 0;
+                                                                        //skypiax_sleep(5000);  //5 msec
+
+                                                                        if (len == -1) {
+                                                                                break;
+                                                                        } else if (len != got) {
+                                                                                ERRORA(&quot;len=%d\n&quot;, SKYPIAX_P_LOG, len);
+                                                                                skypiax_sleep(1000);
+                                                                                break;
+                                                                        }
+                                                                }
+
+        switch_mutex_unlock(tech_pvt-&gt;flag_audio_cli_mutex);
+                                                        } else {
+
+                                                                WARNINGA(&quot;got is %d, but was expected to be %d\n&quot;, SKYPIAX_P_LOG, got, (int) (SAMPLES_PER_FRAME * sizeof(short)));
+                                                        }
+                                                }
+                                        } else {
+                                                if (rt)
+                                                        ERRORA(&quot;CLI rt=%d\n&quot;, SKYPIAX_P_LOG, rt);
+                                                memset(cli_out, 0, sizeof(cli_out));
+                                                if (tech_pvt-&gt;skype_callflow != CALLFLOW_STATUS_REMOTEHOLD) {
+                                                        len = send(fd, (char *) cli_out, sizeof(cli_out), 0);
+                                                        len = send(fd, (char *) cli_out, sizeof(cli_out) / 2, 0);
+                                                        //WARNINGA(&quot;sent %d of zeros to keep the Skype client socket busy\n&quot;, SKYPIAX_P_LOG, sizeof(cli_out) + sizeof(cli_out)/2);
+                                                } else {
+                                                        /*
+                                                           XXX do nothing 
+                                                         */
+                                                        //WARNINGA(&quot;we don't send it\n&quot;, SKYPIAX_P_LOG);
+                                                }
+                                                skypiax_sleep(1000);
+                                        }
+
+#endif// NOLOOP
+#endif// 0
+                                }
+                                DEBUGA_SKYPE(&quot;Skype outbound audio GONE\n&quot;, SKYPIAX_P_LOG);
+                                skypiax_close_socket(fd);
+                                fd = -1;
+                                break;
+                        }
+                }
+        }
+
+        DEBUGA_SKYPE(&quot;outbound audio server (I am it) EXITING\n&quot;, SKYPIAX_P_LOG);
+        skypiax_close_socket(s);
+        s = -1;
+        return NULL;
+}
+
+int skypiax_audio_read(private_t * tech_pvt)
+{
+        unsigned int samples;
+
+#if 0
+        while (tech_pvt-&gt;flag_audio_srv == 0) {
+#ifdef WIN32
+                skypiax_sleep(100);                //0.1 millisec
+#else
+                skypiax_sleep(1000);        //10 millisec
+#endif //WIN32
+
+                WARNINGA(&quot;read now is 0\n&quot;, SKYPIAX_P_LOG);
+        }
+#endif //0
+        //ERRORA(&quot;read is now 1\n&quot;, SKYPIAX_P_LOG);
+        //samples = skypiax_pipe_read(tech_pvt-&gt;audiopipe_srv[0], tech_pvt-&gt;read_frame.data, SAMPLES_PER_FRAME * sizeof(short));
+        samples = SAMPLES_PER_FRAME * sizeof(short);
+        //switch_mutex_lock(tech_pvt-&gt;flag_audio_srv_mutex);
+        memcpy(tech_pvt-&gt;read_frame.data, tech_pvt-&gt;audiobuf_srv, SAMPLES_PER_FRAME * sizeof(short));
+        tech_pvt-&gt;flag_audio_srv = 0;
+        //switch_mutex_unlock(tech_pvt-&gt;flag_audio_srv_mutex);
+
+        if (samples != SAMPLES_PER_FRAME * sizeof(short)) {
+                if (samples)
+                        WARNINGA(&quot;read samples=%u expected=%u\n&quot;, SKYPIAX_P_LOG, samples, (int) (SAMPLES_PER_FRAME * sizeof(short)));
+                return 0;
+        } else {
+                /* A real frame */
+                tech_pvt-&gt;read_frame.datalen = samples;
+        }
+        return 1;
+}
+
+int skypiax_senddigit(private_t * tech_pvt, char digit)
+{
+        char msg_to_skype[1024];
+
+        DEBUGA_SKYPE(&quot;DIGIT received: %c\n&quot;, SKYPIAX_P_LOG, digit);
+        sprintf(msg_to_skype, &quot;SET CALL %s DTMF %c&quot;, tech_pvt-&gt;skype_call_id, digit);
+        skypiax_signaling_write(tech_pvt, msg_to_skype);
+
+        return 0;
+}
+
+int skypiax_call(private_t * tech_pvt, char *rdest, int timeout)
+{
+        char msg_to_skype[1024];
+
+        //skypiax_sleep(5000);
+        DEBUGA_SKYPE(&quot;Calling Skype, rdest is: %s\n&quot;, SKYPIAX_P_LOG, rdest);
+        //skypiax_signaling_write(tech_pvt, &quot;SET AGC OFF&quot;);
+        //skypiax_sleep(10000);
+        //skypiax_signaling_write(tech_pvt, &quot;SET AEC OFF&quot;);
+        //skypiax_sleep(10000);
+
+        sprintf(msg_to_skype, &quot;CALL %s&quot;, rdest);
+        if (skypiax_signaling_write(tech_pvt, msg_to_skype) &lt; 0) {
+                ERRORA(&quot;failed to communicate with Skype client, now exit\n&quot;, SKYPIAX_P_LOG);
+                return -1;
+        }
+        return 0;
+}
+
+/***************************/
+/* PLATFORM SPECIFIC */
+/***************************/
+#if defined(WIN32) &amp;&amp; !defined(__CYGWIN__)
+int skypiax_pipe_read(switch_file_t * pipe, short *buf, int howmany)
+{
+        switch_size_t quantity;
+
+        quantity = howmany;
+
+        switch_file_read(pipe, buf, &amp;quantity);
+
+        howmany = quantity;
+
+        return howmany;
+}
+
+int skypiax_pipe_write(switch_file_t * pipe, short *buf, int howmany)
+{
+        switch_size_t quantity;
+
+        quantity = howmany;
+
+        switch_file_write(pipe, buf, &amp;quantity);
+
+        howmany = quantity;
+
+        return howmany;
+}
+
+int skypiax_close_socket(unsigned int fd)
+{
+        int res;
+
+        res = closesocket(fd);
+
+        return res;
+}
+
+int skypiax_audio_init(private_t * tech_pvt)
+{
+        switch_status_t rv;
+        rv = switch_file_pipe_create(&amp;tech_pvt-&gt;audiopipe_srv[0], &amp;tech_pvt-&gt;audiopipe_srv[1], skypiax_module_pool);
+        rv = switch_file_pipe_create(&amp;tech_pvt-&gt;audiopipe_cli[0], &amp;tech_pvt-&gt;audiopipe_cli[1], skypiax_module_pool);
+        return 0;
+}
+#else /* WIN32 */
+int skypiax_pipe_read(int pipe, short *buf, int howmany)
+{
+        howmany = read(pipe, buf, howmany);
+        return howmany;
+}
+
+int skypiax_pipe_write(int pipe, short *buf, int howmany)
+{
+        if (buf) {
+                howmany = write(pipe, buf, howmany);
+                return howmany;
+        } else {
+                return 0;
+        }
+}
+
+int skypiax_close_socket(unsigned int fd)
+{
+        int res;
+
+        res = close(fd);
+
+        return res;
+}
+
+int skypiax_audio_init(private_t * tech_pvt)
+{
+        if (pipe(tech_pvt-&gt;audiopipe_srv)) {
+                fcntl(tech_pvt-&gt;audiopipe_srv[0], F_SETFL, O_NONBLOCK);
+                fcntl(tech_pvt-&gt;audiopipe_srv[1], F_SETFL, O_NONBLOCK);
+        }
+        if (pipe(tech_pvt-&gt;audiopipe_cli)) {
+                fcntl(tech_pvt-&gt;audiopipe_cli[0], F_SETFL, O_NONBLOCK);
+                fcntl(tech_pvt-&gt;audiopipe_cli[1], F_SETFL, O_NONBLOCK);
+        }
+
+/* this pipe is the audio fd for asterisk to poll on during a call. FS do not use it */
+        tech_pvt-&gt;skypiax_sound_capt_fd = tech_pvt-&gt;audiopipe_srv[0];
+
+        return 0;
+}
+#endif /* WIN32 */
+
+#ifdef WIN32
+
+enum {
+        SKYPECONTROLAPI_ATTACH_SUCCESS = 0,        /*  Client is successfully 
+                                                                                   attached and API window handle can be found
+                                                                                   in wParam parameter */
+        SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION = 1,        /*  Skype has acknowledged
+                                                                                                                   connection request and is waiting
+                                                                                                                   for confirmation from the user. */
+        /*  The client is not yet attached 
+         * and should wait for SKYPECONTROLAPI_ATTACH_SUCCESS message */
+        SKYPECONTROLAPI_ATTACH_REFUSED = 2,        /*  User has explicitly
+                                                                                   denied access to client */
+        SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE = 3,        /*  API is not available
+                                                                                                   at the moment.
+                                                                                                   For example, this happens when no user
+                                                                                                   is currently logged in. */
+        /*  Client should wait for 
+         * SKYPECONTROLAPI_ATTACH_API_AVAILABLE 
+         * broadcast before making any further */
+        /*  connection attempts. */
+        SKYPECONTROLAPI_ATTACH_API_AVAILABLE = 0x8001
+};
+
+/* Visual C do not have strsep? */
+char
+    *strsep(char **stringp, const char *delim)
+{
+        char *res;
+
+        if (!stringp || !*stringp || !**stringp)
+                return (char *) 0;
+
+        res = *stringp;
+        while (**stringp &amp;&amp; !strchr(delim, **stringp))
+                ++(*stringp);
+
+        if (**stringp) {
+                **stringp = '\0';
+                ++(*stringp);
+        }
+
+        return res;
+}
+
+int skypiax_signaling_write(private_t * tech_pvt, char *msg_to_skype)
+{
+        static char acInputRow[1024];
+        COPYDATASTRUCT oCopyData;
+
+        DEBUGA_SKYPE(&quot;SENDING: |||%s||||\n&quot;, SKYPIAX_P_LOG, msg_to_skype);
+
+        sprintf(acInputRow, &quot;%s&quot;, msg_to_skype);
+        DEBUGA_SKYPE(&quot;acInputRow: |||%s||||\n&quot;, SKYPIAX_P_LOG, acInputRow);
+        /*  send command to skype */
+        oCopyData.dwData = 0;
+        oCopyData.lpData = acInputRow;
+        oCopyData.cbData = strlen(acInputRow) + 1;
+        if (oCopyData.cbData != 1) {
+                if (SendMessage
+                        (tech_pvt-&gt;SkypiaxHandles.win32_hGlobal_SkypeAPIWindowHandle, WM_COPYDATA,
+                         (WPARAM) tech_pvt-&gt;SkypiaxHandles.win32_hInit_MainWindowHandle, (LPARAM) &amp; oCopyData) == FALSE) {
+                        ERRORA(&quot;Sending message failed - probably Skype crashed.\n\nPlease shutdown Skypiax, then launch Skypiax and try again.\n&quot;, SKYPIAX_P_LOG);
+                        return -1;
+                }
+        }
+
+        return 0;
+
+}
+
+LRESULT APIENTRY skypiax_present(HWND hWindow, UINT uiMessage, WPARAM uiParam, LPARAM ulParam)
+{
+        LRESULT lReturnCode;
+        int fIssueDefProc;
+        private_t *tech_pvt = NULL;
+
+        lReturnCode = 0;
+        fIssueDefProc = 0;
+        tech_pvt = (private_t *) GetWindowLong(hWindow, GWL_USERDATA);
+        if (!running)
+                return lReturnCode;
+        switch (uiMessage) {
+        case WM_CREATE:
+                tech_pvt = (private_t *) ((LPCREATESTRUCT) ulParam)-&gt;lpCreateParams;
+                SetWindowLong(hWindow, GWL_USERDATA, (LONG) tech_pvt);
+                DEBUGA_SKYPE(&quot;got CREATE\n&quot;, SKYPIAX_P_LOG);
+                break;
+        case WM_DESTROY:
+                DEBUGA_SKYPE(&quot;got DESTROY\n&quot;, SKYPIAX_P_LOG);
+                tech_pvt-&gt;SkypiaxHandles.win32_hInit_MainWindowHandle = NULL;
+                PostQuitMessage(0);
+                break;
+        case WM_COPYDATA:
+                if (tech_pvt-&gt;SkypiaxHandles.win32_hGlobal_SkypeAPIWindowHandle == (HWND) uiParam) {
+                        unsigned int howmany;
+                        char msg_from_skype[2048];
+
+                        PCOPYDATASTRUCT poCopyData = (PCOPYDATASTRUCT) ulParam;
+
+                        memset(msg_from_skype, '\0', sizeof(msg_from_skype));
+                        skypiax_strncpy(msg_from_skype, (const char *) poCopyData-&gt;lpData, sizeof(msg_from_skype) - 2);
+
+                        howmany = strlen(msg_from_skype) + 1;
+                        howmany = skypiax_pipe_write(tech_pvt-&gt;SkypiaxHandles.fdesc[1], (short *) msg_from_skype, howmany);
+                        //DEBUGA_SKYPE(&quot;From Skype API: %s\n&quot;, SKYPIAX_P_LOG, msg_from_skype);
+                        lReturnCode = 1;
+                }
+                break;
+        default:
+                if (tech_pvt &amp;&amp; tech_pvt-&gt;SkypiaxHandles.win32_uiGlobal_MsgID_SkypeControlAPIAttach) {
+                        if (uiMessage == tech_pvt-&gt;SkypiaxHandles.win32_uiGlobal_MsgID_SkypeControlAPIAttach) {
+                                switch (ulParam) {
+                                case SKYPECONTROLAPI_ATTACH_SUCCESS:
+                                        if (!tech_pvt-&gt;SkypiaxHandles.currentuserhandle) {
+                                                //DEBUGA_SKYPE(&quot;\n\n\tConnected to Skype API!\n&quot;, SKYPIAX_P_LOG);
+                                                tech_pvt-&gt;SkypiaxHandles.api_connected = 1;
+                                                tech_pvt-&gt;SkypiaxHandles.win32_hGlobal_SkypeAPIWindowHandle = (HWND) uiParam;
+                                                tech_pvt-&gt;SkypiaxHandles.win32_hGlobal_SkypeAPIWindowHandle = tech_pvt-&gt;SkypiaxHandles.win32_hGlobal_SkypeAPIWindowHandle;
+                                        }
+                                        break;
+                                case SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION:
+                                        //DEBUGA_SKYPE (&quot;\n\n\tIf I do not (almost) immediately connect to Skype API,\n\tplease give the Skype client authorization to be connected \n\tby Asterisk and to not ask you again.\n\n&quot;, SKYPIAX_P_LOG);
+                                        skypiax_sleep(5000);
+#if 0
+                                        if (!tech_pvt-&gt;SkypiaxHandles.currentuserhandle) {
+                                                SendMessage(HWND_BROADCAST,
+                                                                        tech_pvt-&gt;SkypiaxHandles.
+                                                                        win32_uiGlobal_MsgID_SkypeControlAPIDiscover, (WPARAM) tech_pvt-&gt;SkypiaxHandles.win32_hInit_MainWindowHandle, 0);
+                                        }
+#endif
+                                        break;
+                                case SKYPECONTROLAPI_ATTACH_REFUSED:
+                                        ERRORA(&quot;Skype client refused to be connected by Skypiax!\n&quot;, SKYPIAX_P_LOG);
+                                        break;
+                                case SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE:
+                                        ERRORA(&quot;Skype API not (yet?) available\n&quot;, SKYPIAX_P_LOG);
+                                        break;
+                                case SKYPECONTROLAPI_ATTACH_API_AVAILABLE:
+                                        DEBUGA_SKYPE(&quot;Skype API available\n&quot;, SKYPIAX_P_LOG);
+                                        skypiax_sleep(5000);
+#if 0
+                                        if (!tech_pvt-&gt;SkypiaxHandles.currentuserhandle) {
+                                                SendMessage(HWND_BROADCAST,
+                                                                        tech_pvt-&gt;SkypiaxHandles.
+                                                                        win32_uiGlobal_MsgID_SkypeControlAPIDiscover, (WPARAM) tech_pvt-&gt;SkypiaxHandles.win32_hInit_MainWindowHandle, 0);
+                                        }
+#endif
+                                        break;
+                                default:
+                                        WARNINGA(&quot;GOT AN UNKNOWN SKYPE WINDOWS MSG\n&quot;, SKYPIAX_P_LOG);
+                                }
+                                lReturnCode = 1;
+                                break;
+                        }
+                }
+                fIssueDefProc = 1;
+                break;
+        }
+        if (fIssueDefProc)
+                lReturnCode = DefWindowProc(hWindow, uiMessage, uiParam, ulParam);
+        return (lReturnCode);
+}
+
+int win32_Initialize_CreateWindowClass(private_t * tech_pvt)
+{
+        unsigned char *paucUUIDString;
+        RPC_STATUS lUUIDResult;
+        int fReturnStatus;
+        UUID oUUID;
+
+        fReturnStatus = 0;
+        lUUIDResult = UuidCreate(&amp;oUUID);
+        tech_pvt-&gt;SkypiaxHandles.win32_hInit_ProcessHandle = (HINSTANCE) OpenProcess(PROCESS_DUP_HANDLE, FALSE, GetCurrentProcessId());
+        if (tech_pvt-&gt;SkypiaxHandles.win32_hInit_ProcessHandle != NULL &amp;&amp; (lUUIDResult == RPC_S_OK || lUUIDResult == RPC_S_UUID_LOCAL_ONLY)) {
+                if (UuidToString(&amp;oUUID, &amp;paucUUIDString) == RPC_S_OK) {
+                        WNDCLASS oWindowClass;
+
+                        strcpy(tech_pvt-&gt;SkypiaxHandles.win32_acInit_WindowClassName, &quot;Skype-API-Skypiax-&quot;);
+                        strcat(tech_pvt-&gt;SkypiaxHandles.win32_acInit_WindowClassName, (char *) paucUUIDString);
+
+                        oWindowClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
+                        oWindowClass.lpfnWndProc = (WNDPROC) &amp; skypiax_present;
+                        oWindowClass.cbClsExtra = 0;
+                        oWindowClass.cbWndExtra = 0;
+                        oWindowClass.hInstance = tech_pvt-&gt;SkypiaxHandles.win32_hInit_ProcessHandle;
+                        oWindowClass.hIcon = NULL;
+                        oWindowClass.hCursor = NULL;
+                        oWindowClass.hbrBackground = NULL;
+                        oWindowClass.lpszMenuName = NULL;
+                        oWindowClass.lpszClassName = tech_pvt-&gt;SkypiaxHandles.win32_acInit_WindowClassName;
+
+                        if (RegisterClass(&amp;oWindowClass) != 0)
+                                fReturnStatus = 1;
+
+                        RpcStringFree(&amp;paucUUIDString);
+                }
+        }
+        if (fReturnStatus == 0)
+                CloseHandle(tech_pvt-&gt;SkypiaxHandles.win32_hInit_ProcessHandle);
+        tech_pvt-&gt;SkypiaxHandles.win32_hInit_ProcessHandle = NULL;
+        return (fReturnStatus);
+}
+
+void win32_DeInitialize_DestroyWindowClass(private_t * tech_pvt)
+{
+        UnregisterClass(tech_pvt-&gt;SkypiaxHandles.win32_acInit_WindowClassName, tech_pvt-&gt;SkypiaxHandles.win32_hInit_ProcessHandle);
+        CloseHandle(tech_pvt-&gt;SkypiaxHandles.win32_hInit_ProcessHandle);
+        tech_pvt-&gt;SkypiaxHandles.win32_hInit_ProcessHandle = NULL;
+}
+
+int win32_Initialize_CreateMainWindow(private_t * tech_pvt)
+{
+        tech_pvt-&gt;SkypiaxHandles.win32_hInit_MainWindowHandle =
+                CreateWindowEx(WS_EX_APPWINDOW | WS_EX_WINDOWEDGE,
+                                           tech_pvt-&gt;SkypiaxHandles.win32_acInit_WindowClassName, &quot;&quot;,
+                                           WS_BORDER | WS_SYSMENU | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT,
+                                           128, 128, NULL, 0, tech_pvt-&gt;SkypiaxHandles.win32_hInit_ProcessHandle, tech_pvt);
+        return (tech_pvt-&gt;SkypiaxHandles.win32_hInit_MainWindowHandle != NULL ? 1 : 0);
+}
+
+void win32_DeInitialize_DestroyMainWindow(private_t * tech_pvt)
+{
+        if (tech_pvt-&gt;SkypiaxHandles.win32_hInit_MainWindowHandle != NULL)
+                DestroyWindow(tech_pvt-&gt;SkypiaxHandles.win32_hInit_MainWindowHandle), tech_pvt-&gt;SkypiaxHandles.win32_hInit_MainWindowHandle = NULL;
+}
+
+void *skypiax_do_skypeapi_thread_func(void *obj)
+{
+        private_t *tech_pvt = obj;
+#if defined(WIN32) &amp;&amp; !defined(__CYGWIN__)
+        switch_status_t rv;
+
+        switch_file_pipe_create(&amp;tech_pvt-&gt;SkypiaxHandles.fdesc[0], &amp;tech_pvt-&gt;SkypiaxHandles.fdesc[1], skypiax_module_pool);
+        rv = switch_file_pipe_create(&amp;tech_pvt-&gt;SkypiaxHandles.fdesc[0], &amp;tech_pvt-&gt;SkypiaxHandles.fdesc[1], skypiax_module_pool);
+#else /* WIN32 */
+        if (pipe(tech_pvt-&gt;SkypiaxHandles.fdesc)) {
+                fcntl(tech_pvt-&gt;SkypiaxHandles.fdesc[0], F_SETFL, O_NONBLOCK);
+                fcntl(tech_pvt-&gt;SkypiaxHandles.fdesc[1], F_SETFL, O_NONBLOCK);
+        }
+#endif /* WIN32 */
+
+        tech_pvt-&gt;SkypiaxHandles.win32_uiGlobal_MsgID_SkypeControlAPIAttach = RegisterWindowMessage(&quot;SkypeControlAPIAttach&quot;);
+        tech_pvt-&gt;SkypiaxHandles.win32_uiGlobal_MsgID_SkypeControlAPIDiscover = RegisterWindowMessage(&quot;SkypeControlAPIDiscover&quot;);
+
+        skypiax_sleep(200000);                //0,2 sec
+
+        if (tech_pvt-&gt;SkypiaxHandles.win32_uiGlobal_MsgID_SkypeControlAPIAttach != 0
+                &amp;&amp; tech_pvt-&gt;SkypiaxHandles.win32_uiGlobal_MsgID_SkypeControlAPIDiscover != 0) {
+                if (win32_Initialize_CreateWindowClass(tech_pvt)) {
+                        if (win32_Initialize_CreateMainWindow(tech_pvt)) {
+                                if (SendMessage
+                                        (HWND_BROADCAST,
+                                         tech_pvt-&gt;SkypiaxHandles.win32_uiGlobal_MsgID_SkypeControlAPIDiscover,
+                                         (WPARAM) tech_pvt-&gt;SkypiaxHandles.win32_hInit_MainWindowHandle, 0) != 0) {
+                                        tech_pvt-&gt;SkypiaxHandles.win32_hInit_MainWindowHandle = tech_pvt-&gt;SkypiaxHandles.win32_hInit_MainWindowHandle;
+                                        while (running &amp;&amp; tech_pvt-&gt;running) {
+                                                MSG oMessage;
+                                                if (!(running &amp;&amp; tech_pvt-&gt;running))
+                                                        break;
+                                                while (GetMessage(&amp;oMessage, 0, 0, 0)) {
+                                                        TranslateMessage(&amp;oMessage);
+                                                        DispatchMessage(&amp;oMessage);
+                                                }
+                                        }
+                                }
+                                win32_DeInitialize_DestroyMainWindow(tech_pvt);
+                        }
+                        win32_DeInitialize_DestroyWindowClass(tech_pvt);
+                }
+        }
+
+        return NULL;
+}
+
+#else /* NOT WIN32 */
+int X11_errors_handler(Display * dpy, XErrorEvent * err)
+{
+        private_t *tech_pvt = NULL;
+        (void) dpy;
+
+        xerror = err-&gt;error_code;
+        ERRORA(&quot;Received error code %d from X Server\n\n&quot;, SKYPIAX_P_LOG, xerror);        ///FIXME why crash the entire skypiax? just crash the interface, instead
+        //running = 0;
+        return 0;                                        /*  ignore the error */
+}
+
+static void X11_errors_trap(void)
+{
+        xerror = 0;
+        old_handler = XSetErrorHandler(X11_errors_handler);
+}
+
+static int X11_errors_untrap(void)
+{
+        XSetErrorHandler(old_handler);
+        return (xerror != BadValue) &amp;&amp; (xerror != BadWindow);
+}
+
+int skypiax_send_message(private_t * tech_pvt, const char *message_P)
+{
+        struct SkypiaxHandles *SkypiaxHandles = &amp;tech_pvt-&gt;SkypiaxHandles;
+        Window w_P = SkypiaxHandles-&gt;skype_win;
+        Display *disp = SkypiaxHandles-&gt;disp;
+        Window handle_P = SkypiaxHandles-&gt;win;
+        int ok;
+        //private_t *tech_pvt = NULL;
+
+
+        Atom atom1 = XInternAtom(disp, &quot;SKYPECONTROLAPI_MESSAGE_BEGIN&quot;, False);
+        Atom atom2 = XInternAtom(disp, &quot;SKYPECONTROLAPI_MESSAGE&quot;, False);
+        unsigned int pos = 0;
+        unsigned int len = strlen(message_P);
+        XEvent e;
+
+        memset(&amp;e, 0, sizeof(e));
+        e.xclient.type = ClientMessage;
+        e.xclient.message_type = atom1;        /*  leading message */
+        e.xclient.display = disp;
+        e.xclient.window = handle_P;
+        e.xclient.format = 8;
+
+        X11_errors_trap();
+        //XLockDisplay(disp);
+        do {
+                unsigned int i;
+                for (i = 0; i &lt; 20 &amp;&amp; i + pos &lt;= len; ++i)
+                        e.xclient.data.b[i] = message_P[i + pos];
+                XSendEvent(disp, w_P, False, 0, &amp;e);
+
+                e.xclient.message_type = atom2;        /*  following messages */
+                pos += i;
+        } while (pos &lt;= len);
+
+        XSync(disp, False);
+        ok = X11_errors_untrap();
+
+        if (!ok) {
+                ERRORA(&quot;Sending message failed with status %d\n&quot;, SKYPIAX_P_LOG, xerror);
+                tech_pvt-&gt;running = 0;
+                return 0;
+        }
+        //XUnlockDisplay(disp);
+
+        return 1;
+}
+
+int skypiax_signaling_write(private_t * tech_pvt, char *msg_to_skype)
+{
+
+        DEBUGA_SKYPE(&quot;SENDING: |||%s||||\n&quot;, SKYPIAX_P_LOG, msg_to_skype);
+
+
+        if (!skypiax_send_message(tech_pvt, msg_to_skype)) {
+                ERRORA
+                        (&quot;Sending message failed - probably Skype crashed.\n\nPlease shutdown Skypiax, then restart Skype, then launch Skypiax and try again.\n&quot;,
+                         SKYPIAX_P_LOG);
+                return -1;
+        }
+
+        return 0;
+
+}
+
+int skypiax_present(struct SkypiaxHandles *SkypiaxHandles)
+{
+        Atom skype_inst = XInternAtom(SkypiaxHandles-&gt;disp, &quot;_SKYPE_INSTANCE&quot;, True);
+
+        Atom type_ret;
+        int format_ret;
+        unsigned long nitems_ret;
+        unsigned long bytes_after_ret;
+        unsigned char *prop;
+        int status;
+        private_t *tech_pvt = NULL;
+
+        X11_errors_trap();
+        //XLockDisplay(disp);
+        status =
+                XGetWindowProperty(SkypiaxHandles-&gt;disp, DefaultRootWindow(SkypiaxHandles-&gt;disp),
+                                                   skype_inst, 0, 1, False, XA_WINDOW, &amp;type_ret, &amp;format_ret, &amp;nitems_ret, &amp;bytes_after_ret, &amp;prop);
+        //XUnlockDisplay(disp);
+        X11_errors_untrap();
+
+        /*  sanity check */
+        if (status != Success || format_ret != 32 || nitems_ret != 1) {
+                SkypiaxHandles-&gt;skype_win = (Window) - 1;
+                DEBUGA_SKYPE(&quot;Skype instance not found\n&quot;, SKYPIAX_P_LOG);
+                running = 0;
+                SkypiaxHandles-&gt;api_connected = 0;
+                return 0;
+        }
+
+        SkypiaxHandles-&gt;skype_win = *(const unsigned long *) prop &amp; 0xffffffff;
+        DEBUGA_SKYPE(&quot;Skype instance found with id #%d\n&quot;, SKYPIAX_P_LOG, (unsigned int) SkypiaxHandles-&gt;skype_win);
+        SkypiaxHandles-&gt;api_connected = 1;
+        return 1;
+}
+
+void skypiax_clean_disp(void *data)
+{
+
+        int *dispptr;
+        int disp;
+        private_t *tech_pvt = NULL;
+
+        dispptr = data;
+        disp = *dispptr;
+
+        if (disp) {
+                DEBUGA_SKYPE(&quot;to be destroyed disp %d\n&quot;, SKYPIAX_P_LOG, disp);
+                close(disp);
+                DEBUGA_SKYPE(&quot;destroyed disp\n&quot;, SKYPIAX_P_LOG);
+        } else {
+                DEBUGA_SKYPE(&quot;NOT destroyed disp\n&quot;, SKYPIAX_P_LOG);
+        }
+        DEBUGA_SKYPE(&quot;OUT destroyed disp\n&quot;, SKYPIAX_P_LOG);
+        skypiax_sleep(1000);
+}
+
+void *skypiax_do_skypeapi_thread_func(void *obj)
+{
+
+        private_t *tech_pvt = obj;
+        struct SkypiaxHandles *SkypiaxHandles;
+        char buf[512];
+        Display *disp = NULL;
+        Window root = -1;
+        Window win = -1;
+        int xfd;
+
+        if (!strlen(tech_pvt-&gt;X11_display))
+                strcpy(tech_pvt-&gt;X11_display, getenv(&quot;DISPLAY&quot;));
+
+        if (!tech_pvt-&gt;tcp_srv_port)
+                tech_pvt-&gt;tcp_srv_port = 10160;
+
+        if (!tech_pvt-&gt;tcp_cli_port)
+                tech_pvt-&gt;tcp_cli_port = 10161;
+
+        if (pipe(tech_pvt-&gt;SkypiaxHandles.fdesc)) {
+                fcntl(tech_pvt-&gt;SkypiaxHandles.fdesc[0], F_SETFL, O_NONBLOCK);
+                fcntl(tech_pvt-&gt;SkypiaxHandles.fdesc[1], F_SETFL, O_NONBLOCK);
+        }
+        SkypiaxHandles = &amp;tech_pvt-&gt;SkypiaxHandles;
+        disp = XOpenDisplay(tech_pvt-&gt;X11_display);
+        if (!disp) {
+                ERRORA(&quot;Cannot open X Display '%s', exiting skype thread\n&quot;, SKYPIAX_P_LOG, tech_pvt-&gt;X11_display);
+                running = 0;
+                return NULL;
+        } else {
+                DEBUGA_SKYPE(&quot;X Display '%s' opened\n&quot;, SKYPIAX_P_LOG, tech_pvt-&gt;X11_display);
+        }
+
+        xfd = XConnectionNumber(disp);
+        fcntl(xfd, F_SETFD, FD_CLOEXEC);
+
+        SkypiaxHandles-&gt;disp = disp;
+
+        if (skypiax_present(SkypiaxHandles)) {
+                root = DefaultRootWindow(disp);
+                win = XCreateSimpleWindow(disp, root, 0, 0, 1, 1, 0, BlackPixel(disp, DefaultScreen(disp)), BlackPixel(disp, DefaultScreen(disp)));
+
+                SkypiaxHandles-&gt;win = win;
+
+                snprintf(buf, 512, &quot;NAME skypiax&quot;);
+
+                if (!skypiax_send_message(tech_pvt, buf)) {
+                        ERRORA(&quot;Sending message failed - probably Skype crashed. Please run/restart Skype manually and launch Skypiax again\n&quot;, SKYPIAX_P_LOG);
+                        running = 0;
+                        //if(disp)
+                        //XCloseDisplay(disp);
+                        return NULL;
+                }
+
+                snprintf(buf, 512, &quot;PROTOCOL 7&quot;);
+                if (!skypiax_send_message(tech_pvt, buf)) {
+                        ERRORA(&quot;Sending message failed - probably Skype crashed. Please run/restart Skype manually and launch Skypiax again\n&quot;, SKYPIAX_P_LOG);
+                        running = 0;
+                        //if(disp)
+                        //XCloseDisplay(disp);
+                        return NULL;
+                }
+
+                {
+                        /* perform an events loop */
+                        XEvent an_event;
+                        char buf[21];                /*  can't be longer */
+                        char buffer[17000];
+                        char continuebuffer[17000];
+                        char *b;
+                        int i;
+                        int continue_is_broken = 0;
+                        int there_were_continues = 0;
+                        Atom atom_begin = XInternAtom(disp, &quot;SKYPECONTROLAPI_MESSAGE_BEGIN&quot;, False);
+                        Atom atom_continue = XInternAtom(disp, &quot;SKYPECONTROLAPI_MESSAGE&quot;, False);
+
+                        memset(buffer, '\0', 17000);
+                        memset(continuebuffer, '\0', 17000);
+                        b = buffer;
+
+                        while (running &amp;&amp; tech_pvt-&gt;running) {
+                                XNextEvent(disp, &amp;an_event);
+                                if (!(running &amp;&amp; tech_pvt-&gt;running))
+                                        break;
+                                switch (an_event.type) {
+                                case ClientMessage:
+
+                                        if (an_event.xclient.format != 8) {
+                                                skypiax_sleep(1000);        //0.1 msec
+                                                break;
+                                        }
+
+                                        for (i = 0; i &lt; 20 &amp;&amp; an_event.xclient.data.b[i] != '\0'; ++i)
+                                                buf[i] = an_event.xclient.data.b[i];
+
+                                        buf[i] = '\0';
+
+                                        //DEBUGA_SKYPE (&quot;BUF=|||%s|||\n&quot;, SKYPIAX_P_LOG, buf);
+
+                                        if (an_event.xclient.message_type == atom_begin) {
+                                                //DEBUGA_SKYPE (&quot;BEGIN BUF=|||%s|||\n&quot;, SKYPIAX_P_LOG, buf);
+
+                                                if (strlen(buffer)) {
+                                                        unsigned int howmany;
+                                                        howmany = strlen(b) + 1;
+                                                        howmany = write(SkypiaxHandles-&gt;fdesc[1], b, howmany);
+                                                        WARNINGA
+                                                                (&quot;A begin atom while the previous message is not closed???? value of previous message (between vertical bars) is=|||%s|||, will be lost\n&quot;,
+                                                                 SKYPIAX_P_LOG, buffer);
+                                                        memset(buffer, '\0', 17000);
+                                                }
+                                                if (continue_is_broken) {
+                                                        continue_is_broken = 0;
+                                                        there_were_continues = 1;
+                                                }
+                                        }
+                                        if (an_event.xclient.message_type == atom_continue) {
+                                                //DEBUGA_SKYPE (&quot;CONTINUE BUF=|||%s|||\n&quot;, SKYPIAX_P_LOG, buf);
+
+                                                if (!strlen(buffer)) {
+                                                        DEBUGA_SKYPE
+                                                                (&quot;Got a 'continue' XAtom without a previous 'begin'. It's value (between vertical bars) is=|||%s|||, let's store it and hope next 'begin' will be the good one\n&quot;,
+                                                                 SKYPIAX_P_LOG, buf);
+                                                        strcat(continuebuffer, buf);
+                                                        continue_is_broken = 1;
+                                                        if (!strncmp(buf, &quot;ognised identity&quot;, 15)) {
+                                                                WARNINGA
+                                                                        (&quot;Got a 'continue' XAtom without a previous 'begin'. It's value (between vertical bars) is=|||%s|||. Let's introduce a 1 second delay.\n&quot;,
+                                                                         SKYPIAX_P_LOG, buf);
+                                                                skypiax_sleep(1000000);        //1 sec
+                                                        }
+                                                        skypiax_sleep(1000);        //0.1 msec
+                                                        break;
+                                                }
+                                        }
+                                        if (continue_is_broken) {
+                                                XFlush(disp);
+                                                skypiax_sleep(1000);        //0.1 msec
+                                                continue;
+                                        }
+                                        //DEBUGA_SKYPE (&quot;i=%d, buffer=|||%s|||\n&quot;, SKYPIAX_P_LOG, i, buffer);
+                                        strcat(buffer, buf);
+                                        //DEBUGA_SKYPE (&quot;i=%d, buffer=|||%s|||\n&quot;, SKYPIAX_P_LOG, i, buffer);
+                                        strcat(buffer, continuebuffer);
+                                        //DEBUGA_SKYPE (&quot;i=%d, buffer=|||%s|||\n&quot;, SKYPIAX_P_LOG, i, buffer);
+                                        memset(continuebuffer, '\0', 17000);
+
+                                        if (i &lt; 20 || there_were_continues) {        /* last fragment */
+                                                unsigned int howmany;
+
+                                                howmany = strlen(b) + 1;
+
+                                                howmany = write(SkypiaxHandles-&gt;fdesc[1], b, howmany);
+                                                //DEBUGA_SKYPE (&quot;RECEIVED=|||%s|||\n&quot;, SKYPIAX_P_LOG, buffer);
+                                                memset(buffer, '\0', 17000);
+                                                XFlush(disp);
+                                                there_were_continues = 0;
+                                        }
+
+                                        skypiax_sleep(1000);        //0.1 msec
+                                        break;
+                                default:
+                                        skypiax_sleep(1000);        //0.1 msec
+                                        break;
+                                }
+                        }
+                }
+        } else {
+                ERRORA(&quot;Skype is not running, maybe crashed. Please run/restart Skype and relaunch Skypiax\n&quot;, SKYPIAX_P_LOG);
+                running = 0;
+                //if(disp)
+                //XCloseDisplay(disp);
+                return NULL;
+        }
+        //running = 0;
+        //if(disp)
+        //XCloseDisplay(disp);
+        return NULL;
+
+}
+#endif // WIN32
</ins></span></pre>
</div>
</div>
<div id="footer">See you at ClueCon</div>

</body>
</html>