[Freeswitch-branches] [commit] r11719 - freeswitch/branches/gmaruzz/mod_skypiax

FreeSWITCH SVN gmaruzz at freeswitch.org
Mon Feb 9 11:25:19 PST 2009


Author: gmaruzz
Date: Mon Feb  9 13:25:18 2009
New Revision: 11719

Log:
skypiax: cleaning skypiax_protocol.c

Modified:
   freeswitch/branches/gmaruzz/mod_skypiax/mod_skypiax.c
   freeswitch/branches/gmaruzz/mod_skypiax/skypiax_protocol.c

Modified: freeswitch/branches/gmaruzz/mod_skypiax/mod_skypiax.c
==============================================================================
--- freeswitch/branches/gmaruzz/mod_skypiax/mod_skypiax.c	(original)
+++ freeswitch/branches/gmaruzz/mod_skypiax/mod_skypiax.c	Mon Feb  9 13:25:18 2009
@@ -1058,13 +1058,16 @@
               if (channel) {
                 switch_dtmf_t dtmf =
                   { (char) value[0], switch_core_default_dtmf_duration(0) };
-                DEBUGA_SKYPE("%c DTMF %s\n", SKYPIAX_P_LOG, dtmf.digit,
+                NOTICA("received DTMF %c on channel %s\n", SKYPIAX_P_LOG, dtmf.digit,
                              switch_channel_get_name(channel));
                 switch_mutex_lock(tech_pvt->flag_mutex);
+		//FIXME: why sometimes DTMFs from here do not seems to be get by FS?
                 switch_channel_queue_dtmf(channel, &dtmf);
                 switch_set_flag(tech_pvt, TFLAG_DTMF);
                 switch_mutex_unlock(tech_pvt->flag_mutex);
-              }
+              } else {
+                WARNINGA("received %c DTMF, but no channel?\n", SKYPIAX_P_LOG, value[0]);
+	      }
               switch_core_session_rwunlock(session);
 
 	return 0;

Modified: freeswitch/branches/gmaruzz/mod_skypiax/skypiax_protocol.c
==============================================================================
--- freeswitch/branches/gmaruzz/mod_skypiax/skypiax_protocol.c	(original)
+++ freeswitch/branches/gmaruzz/mod_skypiax/skypiax_protocol.c	Mon Feb  9 13:25:18 2009
@@ -23,309 +23,8 @@
 #endif /* WIN32 */
 /*************************************/
 
-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) && !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];
-
-  memset(&my_addr, 0, sizeof(my_addr));
-  my_addr.sin_family = AF_INET;
-  my_addr.sin_addr.s_addr = htonl(0x7f000001);  /* use the localhost */
-  my_addr.sin_port = htons(tech_pvt->tcp_srv_port);
-
-  if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
-    ERRORA("socket Error\n", SKYPIAX_P_LOG);
-    return NULL;
-  }
-
-  if (bind(s, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) < 0) {
-    ERRORA("bind Error\n", SKYPIAX_P_LOG);
-    return NULL;
-  }
-  DEBUGA_SKYPE("started tcp_srv_thread thread.\n", SKYPIAX_P_LOG);
-
-  listen(s, 6);
-
-  sin_size = sizeof(remote_addr);
-  while ((fd = accept(s, (struct sockaddr *) &remote_addr, &sin_size)) > 0) {
-    DEBUGA_SKYPE("ACCEPTED\n", SKYPIAX_P_LOG);
-    if (!running)
-      break;
-    while (tech_pvt->interface_state != SKYPIAX_STATE_DOWN
-           && (tech_pvt->skype_callflow == CALLFLOW_STATUS_INPROGRESS
-               || tech_pvt->skype_callflow == SKYPIAX_STATE_UP)) {
-
-      unsigned int fdselect;
-      int rt;
-      fd_set fs;
-      struct timeval to;
-
-      if (!running)
-        break;
-      exit = 1;
-
-      fdselect = fd;
-      FD_ZERO(&fs);
-      FD_SET(fdselect, &fs);
-      to.tv_usec = 2000000;     //2000 msec
-      to.tv_sec = 0;
-
-      rt = select(fdselect + 1, &fs, NULL, NULL, &to);
-      if (rt > 0) {
-
-        len = recv(fd, (char *) srv_in, 320, 0);    //seems that Skype only sends 320 bytes at time
-
-        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 < 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 < len / sizeof(short); i++) {
-              srv_out[i] = srv_in[i];
-            }
-          } else {
-            ERRORA("SAMPLERATE_SKYPIAX can only be 8000 or 16000\n", SKYPIAX_P_LOG);
-          }
-          /* if not yet done, let's store the half incoming frame */
-          if (!tech_pvt->audiobuf_is_loaded) {
-            for (i = 0; i < SAMPLES_PER_FRAME / 2; i++) {
-              tech_pvt->audiobuf[i] = srv_out[i];
-            }
-            tech_pvt->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 < SAMPLES_PER_FRAME / 2; i++) {
-              totalbuf[i] = tech_pvt->audiobuf[i];
-            }
-            for (a = 0; a < 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->audiopipe[1], totalbuf,
-                                 SAMPLES_PER_FRAME * sizeof(short));
-            if (howmany != SAMPLES_PER_FRAME * sizeof(short)) {
-              ERRORA("howmany is %d, but was expected to be %d\n", SKYPIAX_P_LOG, howmany,
-                     SAMPLES_PER_FRAME * sizeof(short));
-            }
-            /* done with the stored half frame */
-            tech_pvt->audiobuf_is_loaded = 0;
-          }
-
-        } else if (len == 0) {
-          DEBUGA_SKYPE("Skype incoming audio GONE\n", SKYPIAX_P_LOG);
-          skypiax_sleep(1000);
-        } else {
-          ERRORA("len=%d\n", SKYPIAX_P_LOG, len);
-          exit = 1;
-          break;
-        }
-
-      } else {
-        if (rt)
-          ERRORA("SRV rt=%d\n", SKYPIAX_P_LOG, rt);
-        skypiax_sleep(10000);
-      }
-
-    }
-
-    /* let's send some frame in the pipes, so both tcp_cli and tcp_srv will have an occasion to die */
-    kill_cli_size = SAMPLES_PER_FRAME * sizeof(short);
-    len = skypiax_pipe_write(tech_pvt->audiopipe[1], kill_cli_buff, kill_cli_size);
-    kill_cli_size = SAMPLES_PER_FRAME * sizeof(short);
-    len = skypiax_pipe_write(tech_pvt->audioskypepipe[1], kill_cli_buff, kill_cli_size);
-    tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
-    kill_cli_size = SAMPLES_PER_FRAME * sizeof(short);
-    len = skypiax_pipe_write(tech_pvt->audiopipe[1], kill_cli_buff, kill_cli_size);
-    kill_cli_size = SAMPLES_PER_FRAME * sizeof(short);
-    len = skypiax_pipe_write(tech_pvt->audioskypepipe[1], kill_cli_buff, kill_cli_size);
-
-    DEBUGA_SKYPE("Skype incoming audio GONE\n", SKYPIAX_P_LOG);
-    skypiax_close_socket(fd);
-    if (exit)
-      break;
-  }
-
-  DEBUGA_SKYPE("incoming audio server (I am it) GONE\n", SKYPIAX_P_LOG);
-  skypiax_close_socket(s);
-  return NULL;
-}
-
-void *skypiax_do_tcp_cli_thread_func(void *obj)
-{
-  private_t *tech_pvt = obj;
-  int s;
-  struct sockaddr_in my_addr;
-  struct sockaddr_in remote_addr;
-  unsigned int got;
-  unsigned int len;
-  unsigned int i;
-  unsigned int a;
-  unsigned int fd;
-  short cli_out[SAMPLES_PER_FRAME * 2];
-  short cli_in[SAMPLES_PER_FRAME];
-#ifdef WIN32
-  int sin_size;
-#else
-  unsigned int sin_size;
-#endif /* WIN32 */
-
-  memset(&my_addr, 0, sizeof(my_addr));
-  my_addr.sin_family = AF_INET;
-  my_addr.sin_addr.s_addr = htonl(0x7f000001);  /* use the localhost */
-  my_addr.sin_port = htons(tech_pvt->tcp_cli_port);
-
-  if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
-    ERRORA("socket Error\n", SKYPIAX_P_LOG);
-    return NULL;
-  }
-
-  if (bind(s, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) < 0) {
-    ERRORA("bind Error\n", SKYPIAX_P_LOG);
-    skypiax_close_socket(s);
-    return NULL;
-  }
-  DEBUGA_SKYPE("started tcp_cli_thread thread.\n", SKYPIAX_P_LOG);
-
-  listen(s, 6);
-
-  sin_size = sizeof(remote_addr);
-  while ((fd = accept(s, (struct sockaddr *) &remote_addr, &sin_size)) > 0) {
-    DEBUGA_SKYPE("ACCEPTED\n", SKYPIAX_P_LOG);
-    if (!running)
-      break;
-    while (tech_pvt->interface_state != SKYPIAX_STATE_DOWN
-           && (tech_pvt->skype_callflow == CALLFLOW_STATUS_INPROGRESS
-               || tech_pvt->skype_callflow == SKYPIAX_STATE_UP)) {
-      unsigned int fdselect;
-      int rt;
-      fd_set fs;
-      struct timeval to;
-
-      if (!running)
-        break;
-      fdselect = fd;
-      FD_ZERO(&fs);
-      FD_SET(fdselect, &fs);
-      to.tv_usec = 2000000;     //2000 msec
-      to.tv_sec = 0;
-
-      rt = select(fdselect + 1, NULL, &fs, NULL, &to);
-
-      if (rt > 0) {
-
-        /* read from the pipe the audio frame we are supposed to send out */
-        got =
-          skypiax_pipe_read(tech_pvt->audioskypepipe[0], cli_in,
-                            SAMPLES_PER_FRAME * sizeof(short));
-        if (got != SAMPLES_PER_FRAME * sizeof(short)) {
-          WARNINGA("got is %d, but was expected to be %d\n", SKYPIAX_P_LOG, got,
-                   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 < 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 < got / sizeof(short); i++) {
-              cli_out[i] = cli_in[i];
-            }
-          } else {
-            ERRORA("SAMPLERATE_SKYPIAX can only be 8000 or 16000\n", SKYPIAX_P_LOG);
-          }
-
-          /* send the 16khz frame to the Skype client waiting for incoming audio */
-          len = send(fd, (char *) cli_out, got, 0);
-
-          if (len == -1) {
-            break;
-          } else if (len != got) {
-            ERRORA("len=%d\n", SKYPIAX_P_LOG, len);
-            skypiax_sleep(1000);
-            break;
-          }
-
-        } else {
-
-          WARNINGA("got is %d, but was expected to be %d\n", SKYPIAX_P_LOG, got,
-                   SAMPLES_PER_FRAME * sizeof(short));
-        }
-      } else {
-        if (rt)
-          ERRORA("CLI rt=%d\n", SKYPIAX_P_LOG, rt);
-        skypiax_sleep(10000);
-      }
-
-    }
-    DEBUGA_SKYPE("Skype outbound audio GONE\n", SKYPIAX_P_LOG);
-    skypiax_close_socket(fd);
-    break;
-  }
-
-  DEBUGA_SKYPE("outbound audio server (I am it) GONE\n", SKYPIAX_P_LOG);
-  skypiax_close_socket(s);
-  return NULL;
-}
-
-int skypiax_skypeaudio_read(private_t * tech_pvt)
-{
-  unsigned int samples;
-
-  samples =
-    skypiax_pipe_read(tech_pvt->audiopipe[0], tech_pvt->read_frame.data,
-                      SAMPLES_PER_FRAME * sizeof(short));
-
-  if (samples != SAMPLES_PER_FRAME * sizeof(short)) {
-    if (samples)
-      WARNINGA("read samples=%u expected=%u\n", SKYPIAX_P_LOG, samples,
-               SAMPLES_PER_FRAME * sizeof(short));
-    return 0;
-  } else {
-    /* A real frame */
-    tech_pvt->read_frame.datalen = samples;
-  }
-  return 1;
-}
-
 int skypiax_skype_read(private_t * tech_pvt)
 {
-
   char read_from_pipe[4096];
   char message[4096];
   char message_2[4096];
@@ -361,9 +60,8 @@
         skypiax_sleep(10000);
         return 0;
       }
-
       if (!strncasecmp(message, "ERROR 92 CALL", 12)) {
-        ERRORA("Skype got ERROR: |||%s|||, the number we called was not recognized\n",
+        ERRORA("Skype got ERROR: |||%s|||, the (skypeout) number we called was not recognized as valid\n",
                SKYPIAX_P_LOG, message);
         tech_pvt->skype_callflow = CALLFLOW_STATUS_FINISHED;
         DEBUGA_SKYPE("skype_call now is DOWN\n", SKYPIAX_P_LOG);
@@ -376,9 +74,7 @@
           tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
         }
       }
-
       strncpy(message_2, message, sizeof(message) - 1);
-
       buf = message;
       stringp = &buf;
       where = strsep(stringp, " ");
@@ -386,7 +82,7 @@
         WARNINGA("Skype MSG without spaces: %s\n", SKYPIAX_P_LOG, message);
       }
       if (!strcasecmp(message, "ERROR")) {
-        ERRORA("Skype got ERROR: |||%s|||\n", SKYPIAX_P_LOG, message);
+        WARNINGA("Skype got ERROR: |||%s|||\n", SKYPIAX_P_LOG, message);
         tech_pvt->skype_callflow = CALLFLOW_STATUS_FINISHED;
         DEBUGA_SKYPE("skype_call now is DOWN\n", SKYPIAX_P_LOG);
         tech_pvt->skype_call_id[0] = '\0';
@@ -400,11 +96,8 @@
       }
       if (!strcasecmp(message, "CURRENTUSERHANDLE")) {
         strncpy(obj, where, sizeof(obj) - 1);
-
         where = strsep(stringp, " ");
-
         strncpy(id, where, sizeof(id) - 1);
-
         if (!strcasecmp(id, tech_pvt->skype_user)) {
           tech_pvt->SkypiaxHandles.api_connected = 1;
           DEBUGA_SKYPE
@@ -412,309 +105,557 @@
              SKYPIAX_P_LOG, message, obj, id, tech_pvt->skype_user);
         }
       }
-
       if (!strcasecmp(message, "USER")) {
         strncpy(obj, where, sizeof(obj) - 1);
-
         where = strsep(stringp, " ");
-
         strncpy(id, where, sizeof(id) - 1);
-
         where = strsep(stringp, " ");
+        strncpy(prop, where, sizeof(prop) - 1);
+        if (!strcasecmp(prop, "RECEIVEDAUTHREQUEST")) {
+          char msg_to_skype[256];
+          DEBUGA_SKYPE("Skype MSG: message: %s, obj: %s, id: %s, prop: %s!\n",
+                       SKYPIAX_P_LOG, message, obj, id, prop);
+          //TODO: allow authorization based on config param
+          sprintf(msg_to_skype, "SET USER %s ISAUTHORIZED TRUE", id);
+          skypiax_skype_write(tech_pvt, msg_to_skype);
+        }
+      }
+      if (!strcasecmp(message, "MESSAGE")) {
+        strncpy(obj, where, sizeof(obj) - 1);
+        where = strsep(stringp, " ");
+        strncpy(id, where, sizeof(id) - 1);
+        where = strsep(stringp, " ");
+        strncpy(prop, where, sizeof(prop) - 1);
+        if (!strcasecmp(prop, "STATUS")) {
+          where = strsep(stringp, " ");
+          strncpy(value, where, sizeof(value) - 1);
+          if (!strcasecmp(value, "RECEIVED")) {
+            char msg_to_skype[256];
+            DEBUGA_SKYPE("Skype MSG: message: %s, obj: %s, id: %s, prop: %s value: %s!\n",
+                         SKYPIAX_P_LOG, message, obj, id, prop, value);
+            //TODO: authomatically flag messages as read based on config param
+            sprintf(msg_to_skype, "SET MESSAGE %s SEEN", id);
+            skypiax_skype_write(tech_pvt, msg_to_skype);
+          }
+        } else if (!strcasecmp(prop, "BODY")) {
+          char msg_to_skype[256];
+          DEBUGA_SKYPE("Skype MSG: message: %s, obj: %s, id: %s, prop: %s!\n",
+                       SKYPIAX_P_LOG, message, obj, id, prop);
+            //TODO: authomatically flag messages as read based on config param
+          sprintf(msg_to_skype, "SET MESSAGE %s SEEN", id);
+          skypiax_skype_write(tech_pvt, msg_to_skype);
+        }
+      }
+      if (!strcasecmp(message, "CALL")) {
+        strncpy(obj, where, sizeof(obj) - 1);
+        where = strsep(stringp, " ");
+        strncpy(id, where, sizeof(id) - 1);
+        where = strsep(stringp, " ");
+        strncpy(prop, where, sizeof(prop) - 1);
+        where = strsep(stringp, " ");
+        strncpy(value, where, sizeof(value) - 1);
+        where = strsep(stringp, " ");
+
+        DEBUGA_SKYPE
+          ("Skype MSG: message: %s, obj: %s, id: %s, prop: %s, value: %s,where: %s!\n",
+           SKYPIAX_P_LOG, message, obj, id, prop, value, where ? where : "NULL");
+
+        if (!strcasecmp(prop, "PARTNER_HANDLE")) {
+          strncpy(tech_pvt->callid_number, value, sizeof(tech_pvt->callid_number) - 1);
+          DEBUGA_SKYPE
+            ("the skype_call %s caller PARTNER_HANDLE (tech_pvt->callid_number) is: %s\n",
+             SKYPIAX_P_LOG, id, tech_pvt->callid_number);
+          return CALLFLOW_INCOMING_RING;
+        }
+        if (!strcasecmp(prop, "PARTNER_DISPNAME")) {
+          snprintf(tech_pvt->callid_name, sizeof(tech_pvt->callid_name) - 1, "%s%s%s",
+                   value, where ? " " : "", where ? where : "");
+          DEBUGA_SKYPE
+            ("the skype_call %s caller PARTNER_DISPNAME (tech_pvt->callid_name) is: %s\n",
+             SKYPIAX_P_LOG, id, tech_pvt->callid_name);
+        }
+        if (!strcasecmp(prop, "CONF_ID") && !strcasecmp(value, "0")) {
+          DEBUGA_SKYPE("the skype_call %s is NOT a conference call\n", SKYPIAX_P_LOG, id);
+          if (tech_pvt->interface_state == SKYPIAX_STATE_DOWN)
+            tech_pvt->interface_state = SKYPIAX_STATE_PRERING;
+        }
+        if (!strcasecmp(prop, "CONF_ID") && strcasecmp(value, "0")) {
+          DEBUGA_SKYPE("the skype_call %s is a conference call\n", SKYPIAX_P_LOG, id);
+          if (tech_pvt->interface_state == SKYPIAX_STATE_DOWN)
+            tech_pvt->interface_state = SKYPIAX_STATE_PRERING;
+        }
+        if (!strcasecmp(prop, "DTMF")) {
+          NOTICA("Call %s received a DTMF: %s\n", SKYPIAX_P_LOG, id, value);
+          dtmf_received(tech_pvt, value);
+        }
+        if (!strcasecmp(prop, "FAILUREREASON")) {
+          DEBUGA_SKYPE
+            ("Skype FAILED on skype_call %s. Let's wait for the FAILED message.\n",
+             SKYPIAX_P_LOG, id);
+        }
+        if (!strcasecmp(prop, "DURATION") && (!strcasecmp(value, "1"))) {
+          if (strcasecmp(id, tech_pvt->skype_call_id)) {
+            strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
+            DEBUGA_SKYPE
+              ("We called a Skype contact and he answered us on skype_call: %s.\n",
+               SKYPIAX_P_LOG, id);
+          }
+        }
+        if (!strcasecmp(prop, "STATUS")) {
+
+          if (!strcasecmp(value, "RINGING")) {
+            char msg_to_skype[1024];
+            if (tech_pvt->interface_state != SKYPIAX_STATE_DIALING) {
+              /* we are not calling out */
+              if (!strlen(tech_pvt->skype_call_id)) { 
+                /* we are not inside an active call */
+                tech_pvt->skype_callflow = CALLFLOW_STATUS_RINGING;
+                tech_pvt->interface_state = SKYPIAX_STATE_RING;
+                /* no owner, no active call, let's answer */
+                skypiax_skype_write(tech_pvt, "SET AGC OFF");
+                skypiax_sleep(10000);
+                skypiax_skype_write(tech_pvt, "SET AEC OFF");
+                skypiax_sleep(10000);
+                sprintf(msg_to_skype, "GET CALL %s PARTNER_DISPNAME", id);
+                skypiax_skype_write(tech_pvt, msg_to_skype);
+                skypiax_sleep(10000);
+                sprintf(msg_to_skype, "GET CALL %s PARTNER_HANDLE", id);
+                skypiax_skype_write(tech_pvt, msg_to_skype);
+                skypiax_sleep(10000);
+                sprintf(msg_to_skype, "ALTER CALL %s ANSWER", id);
+                skypiax_skype_write(tech_pvt, msg_to_skype);
+                DEBUGA_SKYPE("We answered a Skype RING on skype_call %s\n", SKYPIAX_P_LOG,
+                             id);
+                strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
+              } else {
+                /* we're owned, we're in a call, let's refuse */
+                sprintf(msg_to_skype, "ALTER CALL %s END HANGUP", id);
+                skypiax_skype_write(tech_pvt, msg_to_skype);
+                skypiax_sleep(10000);
+                DEBUGA_SKYPE
+                  ("We have NOT answered a Skype RING on skype_call %s, because we are already in a skypiax call\n",
+                   SKYPIAX_P_LOG, id);
+              }
+            } else {
+              /* we are calling out */
+              tech_pvt->skype_callflow = CALLFLOW_STATUS_RINGING;
+              tech_pvt->interface_state = SKYPIAX_STATE_RINGING;
+              strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
+              DEBUGA_SKYPE("Our remote party in skype_call %s is RINGING\n",
+                           SKYPIAX_P_LOG, id);
+            }
+          } else if (!strcasecmp(value, "EARLYMEDIA")) {
+            tech_pvt->skype_callflow = CALLFLOW_STATUS_EARLYMEDIA;
+            tech_pvt->interface_state = SKYPIAX_STATE_DIALING;
+            DEBUGA_SKYPE("Our remote party in skype_call %s is EARLYMEDIA\n",
+                         SKYPIAX_P_LOG, id);
+          } else if (!strcasecmp(value, "MISSED")) {
+            DEBUGA_SKYPE("We missed skype_call %s\n", SKYPIAX_P_LOG, id);
+          } else if (!strcasecmp(value, "FINISHED")) {
+            DEBUGA_SKYPE("skype_call %s now is DOWN\n", SKYPIAX_P_LOG, id);
+            tech_pvt->skype_call_id[0] = '\0';
+            if (tech_pvt->interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) {
+              //tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
+              return CALLFLOW_INCOMING_HANGUP;
+            } else {
+              tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
+            }
+          } else if (!strcasecmp(value, "CANCELLED")) {
+            tech_pvt->skype_callflow = CALLFLOW_STATUS_CANCELLED;
+            DEBUGA_SKYPE
+              ("we tried to call Skype on skype_call %s and Skype has now CANCELLED\n",
+               SKYPIAX_P_LOG, id);
+            tech_pvt->skype_call_id[0] = '\0';
+            if (tech_pvt->interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) {
+              tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
+              return CALLFLOW_INCOMING_HANGUP;
+            } else {
+              tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
+            }
+          } else if (!strcasecmp(value, "FAILED")) {
+            tech_pvt->skype_callflow = CALLFLOW_STATUS_FAILED;
+            DEBUGA_SKYPE
+              ("we tried to call Skype on skype_call %s and Skype has now FAILED\n",
+               SKYPIAX_P_LOG, id);
+            tech_pvt->skype_call_id[0] = '\0';
+            strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
+            tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
+            return CALLFLOW_INCOMING_HANGUP;
+          } else if (!strcasecmp(value, "REFUSED")) {
+            if (!strcasecmp(id, tech_pvt->skype_call_id)) {
+              /* this is the id of the call we are in, probably we generated it */
+              tech_pvt->skype_callflow = CALLFLOW_STATUS_REFUSED;
+              DEBUGA_SKYPE
+                ("we tried to call Skype on skype_call %s and Skype has now REFUSED\n",
+                 SKYPIAX_P_LOG, id);
+              strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
+              tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
+              tech_pvt->skype_call_id[0] = '\0';
+              return CALLFLOW_INCOMING_HANGUP;
+            } else {
+              /* we're here because were us that refused an incoming call */
+              DEBUGA_SKYPE("we REFUSED skype_call %s\n", SKYPIAX_P_LOG, id);
+            }
+          } else if (!strcasecmp(value, "ROUTING")) {
+            tech_pvt->skype_callflow = CALLFLOW_STATUS_ROUTING;
+            tech_pvt->interface_state = SKYPIAX_STATE_DIALING;
+            strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
+            DEBUGA_SKYPE("skype_call: %s is now ROUTING\n", SKYPIAX_P_LOG, id);
+          } else if (!strcasecmp(value, "UNPLACED")) {
+            tech_pvt->skype_callflow = CALLFLOW_STATUS_UNPLACED;
+            tech_pvt->interface_state = SKYPIAX_STATE_DIALING;
+            strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
+            DEBUGA_SKYPE("skype_call: %s is now UNPLACED\n", SKYPIAX_P_LOG, id);
+          } else if (!strcasecmp(value, "INPROGRESS")) {
+            char msg_to_skype[1024];
+            tech_pvt->skype_callflow = CALLFLOW_STATUS_INPROGRESS;
+            strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
+            tech_pvt->interface_state = SKYPIAX_STATE_UP;
+            DEBUGA_SKYPE("skype_call: %s is now active\n", SKYPIAX_P_LOG, id);
+            sprintf(msg_to_skype, "ALTER CALL %s SET_INPUT PORT=\"%d\"", id,
+                    tech_pvt->tcp_cli_port);
+            skypiax_skype_write(tech_pvt, msg_to_skype);
+            start_audio_threads(tech_pvt);
+            sprintf(msg_to_skype, "ALTER CALL %s SET_OUTPUT PORT=\"%d\"", id,
+                    tech_pvt->tcp_srv_port);
+            skypiax_skype_write(tech_pvt, msg_to_skype);
+            tech_pvt->skype_callflow = SKYPIAX_STATE_UP;
+            if (!strlen(tech_pvt->session_uuid_str)) {
+              DEBUGA_SKYPE("New Inbound Channel!\n", SKYPIAX_P_LOG);
+              new_inbound_channel(tech_pvt);
+            } else {
+              DEBUGA_SKYPE("Outbound Channel Answered!\n", SKYPIAX_P_LOG);
+              outbound_channel_answered(tech_pvt);
+            }
+          } else {
+            WARNINGA("skype_call: %s, STATUS: %s is not recognized\n", SKYPIAX_P_LOG, id,
+                     value);
+          }
+        }                       //STATUS
+      }                         //CALL
+      /* the "numbered" messages that follows are used by the directory application, not yet ported */
+      if (!strcasecmp(message, "#333")) {
+        /* DEBUGA_SKYPE("Skype MSG: message_2: %s, message2[11]: %s\n", SKYPIAX_P_LOG,
+         * message_2, &message_2[11]); */
+        memset(tech_pvt->skype_friends, 0, 4096);
+        strncpy(tech_pvt->skype_friends, &message_2[11], 4095);
+      }
+      if (!strcasecmp(message, "#222")) {
+        /* DEBUGA_SKYPE("Skype MSG: message_2: %s, message2[10]: %s\n", SKYPIAX_P_LOG,
+         * message_2, &message_2[10]); */
+        memset(tech_pvt->skype_fullname, 0, 512);
+        strncpy(tech_pvt->skype_fullname, &message_2[10], 511);
+      }
+      if (!strcasecmp(message, "#765")) {
+        /* DEBUGA_SKYPE("Skype MSG: message_2: %s, message2[10]: %s\n", SKYPIAX_P_LOG,
+         * message_2, &message_2[10]); */
+        memset(tech_pvt->skype_displayname, 0, 512);
+        strncpy(tech_pvt->skype_displayname, &message_2[10], 511);
+      }
+      a = 0;
+    }                           //message end
+  }                             //read_from_pipe
+  return 0;
+}
 
-        strncpy(prop, where, sizeof(prop) - 1);
+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) && !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];
 
-        if (!strcasecmp(prop, "RECEIVEDAUTHREQUEST")) {
-          char msg_to_skype[256];
-          DEBUGA_SKYPE("Skype MSG: message: %s, obj: %s, id: %s, prop: %s!\n",
-                       SKYPIAX_P_LOG, message, obj, id, prop);
+  memset(&my_addr, 0, sizeof(my_addr));
+  my_addr.sin_family = AF_INET;
+  my_addr.sin_addr.s_addr = htonl(0x7f000001);  /* use the localhost */
+  my_addr.sin_port = htons(tech_pvt->tcp_srv_port);
 
-          //FIXME: TODO: allow authorization based on config param
-          sprintf(msg_to_skype, "SET USER %s ISAUTHORIZED TRUE", id);
-          skypiax_skype_write(tech_pvt, msg_to_skype);
-        }
-      }
+  if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+    ERRORA("socket Error\n", SKYPIAX_P_LOG);
+    return NULL;
+  }
 
-      if (!strcasecmp(message, "MESSAGE")) {
-        strncpy(obj, where, sizeof(obj) - 1);
+  if (bind(s, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) < 0) {
+    ERRORA("bind Error\n", SKYPIAX_P_LOG);
+    return NULL;
+  }
+  DEBUGA_SKYPE("started tcp_srv_thread thread.\n", SKYPIAX_P_LOG);
 
-        where = strsep(stringp, " ");
+  listen(s, 6);
 
-        strncpy(id, where, sizeof(id) - 1);
+  sin_size = sizeof(remote_addr);
+  while ((fd = accept(s, (struct sockaddr *) &remote_addr, &sin_size)) > 0) {
+    DEBUGA_SKYPE("ACCEPTED\n", SKYPIAX_P_LOG);
+    if (!running)
+      break;
+    while (tech_pvt->interface_state != SKYPIAX_STATE_DOWN
+           && (tech_pvt->skype_callflow == CALLFLOW_STATUS_INPROGRESS
+               || tech_pvt->skype_callflow == SKYPIAX_STATE_UP)) {
 
-        where = strsep(stringp, " ");
+      unsigned int fdselect;
+      int rt;
+      fd_set fs;
+      struct timeval to;
 
-        strncpy(prop, where, sizeof(prop) - 1);
+      if (!running)
+        break;
+      exit = 1;
 
-        if (!strcasecmp(prop, "STATUS")) {
+      fdselect = fd;
+      FD_ZERO(&fs);
+      FD_SET(fdselect, &fs);
+      to.tv_usec = 2000000;     //2000 msec
+      to.tv_sec = 0;
 
-          where = strsep(stringp, " ");
+      rt = select(fdselect + 1, &fs, NULL, NULL, &to);
+      if (rt > 0) {
 
-          strncpy(value, where, sizeof(value) - 1);
+        len = recv(fd, (char *) srv_in, 320, 0);    //seems that Skype only sends 320 bytes at time
 
-          if (!strcasecmp(value, "RECEIVED")) {
-            char msg_to_skype[256];
-            DEBUGA_SKYPE("Skype MSG: message: %s, obj: %s, id: %s, prop: %s value: %s!\n",
-                         SKYPIAX_P_LOG, message, obj, id, prop, value);
+        if (len == 320) {
+          unsigned int howmany;
 
-            //FIXME: TODO: allow authorization based on config param
-            sprintf(msg_to_skype, "SET MESSAGE %s SEEN", id);
-            skypiax_skype_write(tech_pvt, msg_to_skype);
+          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 < 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 < len / sizeof(short); i++) {
+              srv_out[i] = srv_in[i];
+            }
+          } else {
+            ERRORA("SAMPLERATE_SKYPIAX can only be 8000 or 16000\n", SKYPIAX_P_LOG);
+          }
+          /* if not yet done, let's store the half incoming frame */
+          if (!tech_pvt->audiobuf_is_loaded) {
+            for (i = 0; i < SAMPLES_PER_FRAME / 2; i++) {
+              tech_pvt->audiobuf[i] = srv_out[i];
+            }
+            tech_pvt->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 < SAMPLES_PER_FRAME / 2; i++) {
+              totalbuf[i] = tech_pvt->audiobuf[i];
+            }
+            for (a = 0; a < 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->audiopipe[1], totalbuf,
+                                 SAMPLES_PER_FRAME * sizeof(short));
+            if (howmany != SAMPLES_PER_FRAME * sizeof(short)) {
+              ERRORA("howmany is %d, but was expected to be %d\n", SKYPIAX_P_LOG, howmany,
+                     SAMPLES_PER_FRAME * sizeof(short));
+            }
+            /* done with the stored half frame */
+            tech_pvt->audiobuf_is_loaded = 0;
           }
-        } else if (!strcasecmp(prop, "BODY")) {
-          char msg_to_skype[256];
-
-          DEBUGA_SKYPE("Skype MSG: message: %s, obj: %s, id: %s, prop: %s!\n",
-                       SKYPIAX_P_LOG, message, obj, id, prop);
 
-          //FIXME: TODO: on config param ???
-          sprintf(msg_to_skype, "SET MESSAGE %s SEEN", id);
-          skypiax_skype_write(tech_pvt, msg_to_skype);
+        } else if (len == 0) {
+          DEBUGA_SKYPE("Skype incoming audio GONE\n", SKYPIAX_P_LOG);
+          skypiax_sleep(1000);
+        } else {
+          ERRORA("len=%d\n", SKYPIAX_P_LOG, len);
+          exit = 1;
+          break;
         }
 
+      } else {
+        if (rt)
+          ERRORA("SRV rt=%d\n", SKYPIAX_P_LOG, rt);
+        skypiax_sleep(10000);
       }
 
-      if (!strcasecmp(message, "CALL")) {
-
-        strncpy(obj, where, sizeof(obj) - 1);
-
-        where = strsep(stringp, " ");
-
-        strncpy(id, where, sizeof(id) - 1);
-
-        where = strsep(stringp, " ");
-
-        strncpy(prop, where, sizeof(prop) - 1);
-
-        where = strsep(stringp, " ");
-
-        strncpy(value, where, sizeof(value) - 1);
-
-        where = strsep(stringp, " ");
-
-        DEBUGA_SKYPE
-          ("Skype MSG: message: %s, obj: %s, id: %s, prop: %s, value: %s,where: %s!\n",
-           SKYPIAX_P_LOG, message, obj, id, prop, value, where ? where : "NULL");
-
-        if (!strcasecmp(prop, "PARTNER_HANDLE")) {
-          strncpy(tech_pvt->callid_number, value, sizeof(tech_pvt->callid_number) - 1);
-          DEBUGA_SKYPE
-            ("the skype_call %s caller PARTNER_HANDLE (tech_pvt->callid_number) is: %s\n",
-             SKYPIAX_P_LOG, id, tech_pvt->callid_number);
-          return CALLFLOW_INCOMING_RING;
-        }
-        if (!strcasecmp(prop, "PARTNER_DISPNAME")) {
-          snprintf(tech_pvt->callid_name, sizeof(tech_pvt->callid_name) - 1, "%s%s%s",
-                   value, where ? " " : "", where ? where : "");
-          DEBUGA_SKYPE
-            ("the skype_call %s caller PARTNER_DISPNAME (tech_pvt->callid_name) is: %s\n",
-             SKYPIAX_P_LOG, id, tech_pvt->callid_name);
-        }
-        if (!strcasecmp(prop, "CONF_ID") && !strcasecmp(value, "0")) {
-          DEBUGA_SKYPE("the skype_call %s is NOT a conference call\n", SKYPIAX_P_LOG, id);
-          if (tech_pvt->interface_state == SKYPIAX_STATE_DOWN)
-            tech_pvt->interface_state = SKYPIAX_STATE_PRERING;
-        }
-        if (!strcasecmp(prop, "CONF_ID") && strcasecmp(value, "0")) {
-          DEBUGA_SKYPE("the skype_call %s is a conference call\n", SKYPIAX_P_LOG, id);
-          if (tech_pvt->interface_state == SKYPIAX_STATE_DOWN)
-            tech_pvt->interface_state = SKYPIAX_STATE_PRERING;
-        }
+    }
 
-        if (!strcasecmp(prop, "DTMF")) {
+    /* let's send some frame in the pipes, so both tcp_cli and tcp_srv will have an occasion to die */
+    kill_cli_size = SAMPLES_PER_FRAME * sizeof(short);
+    len = skypiax_pipe_write(tech_pvt->audiopipe[1], kill_cli_buff, kill_cli_size);
+    kill_cli_size = SAMPLES_PER_FRAME * sizeof(short);
+    len = skypiax_pipe_write(tech_pvt->audioskypepipe[1], kill_cli_buff, kill_cli_size);
+    tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
+    kill_cli_size = SAMPLES_PER_FRAME * sizeof(short);
+    len = skypiax_pipe_write(tech_pvt->audiopipe[1], kill_cli_buff, kill_cli_size);
+    kill_cli_size = SAMPLES_PER_FRAME * sizeof(short);
+    len = skypiax_pipe_write(tech_pvt->audioskypepipe[1], kill_cli_buff, kill_cli_size);
 
-          DEBUGA_SKYPE("Call %s received a DTMF: %s\n", SKYPIAX_P_LOG, id, value);
+    DEBUGA_SKYPE("Skype incoming audio GONE\n", SKYPIAX_P_LOG);
+    skypiax_close_socket(fd);
+    if (exit)
+      break;
+  }
 
-          dtmf_received(tech_pvt, value);
-        }
+  DEBUGA_SKYPE("incoming audio server (I am it) GONE\n", SKYPIAX_P_LOG);
+  skypiax_close_socket(s);
+  return NULL;
+}
 
-        if (!strcasecmp(prop, "FAILUREREASON")) {
-          DEBUGA_SKYPE
-            ("Skype has FAILED on skype_call %s. Let's wait for the FAILED message.\n",
-             SKYPIAX_P_LOG, id);
-        }
-        if (!strcasecmp(prop, "DURATION") && (!strcasecmp(value, "1"))) {
-          if (strcasecmp(id, tech_pvt->skype_call_id)) {
-            strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
-            DEBUGA_SKYPE
-              ("We called a Skype contact and he answered us on skype_call: %s.\n",
-               SKYPIAX_P_LOG, id);
-          }
-        }
+void *skypiax_do_tcp_cli_thread_func(void *obj)
+{
+  private_t *tech_pvt = obj;
+  int s;
+  struct sockaddr_in my_addr;
+  struct sockaddr_in remote_addr;
+  unsigned int got;
+  unsigned int len;
+  unsigned int i;
+  unsigned int a;
+  unsigned int fd;
+  short cli_out[SAMPLES_PER_FRAME * 2];
+  short cli_in[SAMPLES_PER_FRAME];
+#ifdef WIN32
+  int sin_size;
+#else
+  unsigned int sin_size;
+#endif /* WIN32 */
 
-        if (!strcasecmp(prop, "STATUS")) {
+  memset(&my_addr, 0, sizeof(my_addr));
+  my_addr.sin_family = AF_INET;
+  my_addr.sin_addr.s_addr = htonl(0x7f000001);  /* use the localhost */
+  my_addr.sin_port = htons(tech_pvt->tcp_cli_port);
 
-          if (!strcasecmp(value, "RINGING")) {
-            char msg_to_skype[1024];
-            if (tech_pvt->interface_state != SKYPIAX_STATE_DIALING) {
-              /* we are not calling out */
+  if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+    ERRORA("socket Error\n", SKYPIAX_P_LOG);
+    return NULL;
+  }
 
-              if (!strlen(tech_pvt->skype_call_id)) {   //FIXME
-                /* we are not inside an active call */
-                tech_pvt->skype_callflow = CALLFLOW_STATUS_RINGING;
-                tech_pvt->interface_state = SKYPIAX_STATE_RING;
-                /* no owner, no active call, let's answer */
-                skypiax_skype_write(tech_pvt, "SET AGC OFF");
-                skypiax_sleep(10000);
-                skypiax_skype_write(tech_pvt, "SET AEC OFF");
-                skypiax_sleep(10000);
-                sprintf(msg_to_skype, "GET CALL %s PARTNER_DISPNAME", id);
-                skypiax_skype_write(tech_pvt, msg_to_skype);
-                skypiax_sleep(10000);
-                sprintf(msg_to_skype, "GET CALL %s PARTNER_HANDLE", id);
-                skypiax_skype_write(tech_pvt, msg_to_skype);
-                skypiax_sleep(10000);
-                sprintf(msg_to_skype, "ALTER CALL %s ANSWER", id);
-                skypiax_skype_write(tech_pvt, msg_to_skype);
-                DEBUGA_SKYPE("We answered a Skype RING on skype_call %s\n", SKYPIAX_P_LOG,
-                             id);
-                strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
-              } else {
-                /* we're owned, we're in a call, let's refuse */
-                sprintf(msg_to_skype, "ALTER CALL %s END HANGUP", id);
-                skypiax_skype_write(tech_pvt, msg_to_skype);
-                skypiax_sleep(10000);
-                DEBUGA_SKYPE
-                  ("We have NOT answered a Skype RING on skype_call %s, because we are already in a skypiax call\n",
-                   SKYPIAX_P_LOG, id);
+  if (bind(s, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) < 0) {
+    ERRORA("bind Error\n", SKYPIAX_P_LOG);
+    skypiax_close_socket(s);
+    return NULL;
+  }
+  DEBUGA_SKYPE("started tcp_cli_thread thread.\n", SKYPIAX_P_LOG);
 
-              }
-            } else {
-              /* we are calling out */
-              tech_pvt->skype_callflow = CALLFLOW_STATUS_RINGING;
-              tech_pvt->interface_state = SKYPIAX_STATE_RINGING;
-              //FIXME ast_queue_control(tech_pvt->owner, SKYPIAX_CONTROL_RINGING);
-              strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
-              DEBUGA_SKYPE("Our remote party in skype_call %s is RINGING\n",
-                           SKYPIAX_P_LOG, id);
-            }
-          } else if (!strcasecmp(value, "EARLYMEDIA")) {
-            tech_pvt->skype_callflow = CALLFLOW_STATUS_EARLYMEDIA;
-            tech_pvt->interface_state = SKYPIAX_STATE_DIALING;
-            //FIXME ast_queue_control(tech_pvt->owner, SKYPIAX_CONTROL_RINGING);
-            DEBUGA_SKYPE("Our remote party in skype_call %s is EARLYMEDIA\n",
-                         SKYPIAX_P_LOG, id);
-          } else if (!strcasecmp(value, "MISSED")) {
-            DEBUGA_SKYPE("We missed skype_call %s\n", SKYPIAX_P_LOG, id);
+  listen(s, 6);
 
-          } else if (!strcasecmp(value, "FINISHED")) {
-            //tech_pvt->skype_callflow = CALLFLOW_STATUS_FINISHED;
-            DEBUGA_SKYPE("skype_call %s now is DOWN\n", SKYPIAX_P_LOG, id);
-            tech_pvt->skype_call_id[0] = '\0';
+  sin_size = sizeof(remote_addr);
+  while ((fd = accept(s, (struct sockaddr *) &remote_addr, &sin_size)) > 0) {
+    DEBUGA_SKYPE("ACCEPTED\n", SKYPIAX_P_LOG);
+    if (!running)
+      break;
+    while (tech_pvt->interface_state != SKYPIAX_STATE_DOWN
+           && (tech_pvt->skype_callflow == CALLFLOW_STATUS_INPROGRESS
+               || tech_pvt->skype_callflow == SKYPIAX_STATE_UP)) {
+      unsigned int fdselect;
+      int rt;
+      fd_set fs;
+      struct timeval to;
 
-            if (tech_pvt->interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) {
-              //tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
-              return CALLFLOW_INCOMING_HANGUP;
-            } else {
-              tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
-            }
+      if (!running)
+        break;
+      fdselect = fd;
+      FD_ZERO(&fs);
+      FD_SET(fdselect, &fs);
+      to.tv_usec = 2000000;     //2000 msec
+      to.tv_sec = 0;
 
-          } else if (!strcasecmp(value, "CANCELLED")) {
-            tech_pvt->skype_callflow = CALLFLOW_STATUS_CANCELLED;
-            DEBUGA_SKYPE
-              ("we tried to call Skype on skype_call %s and Skype has now CANCELLED\n",
-               SKYPIAX_P_LOG, id);
-            tech_pvt->skype_call_id[0] = '\0';
+      rt = select(fdselect + 1, NULL, &fs, NULL, &to);
 
-            if (tech_pvt->interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) {
-              tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
-              return CALLFLOW_INCOMING_HANGUP;
-            } else {
-              tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
-            }
-          } else if (!strcasecmp(value, "FAILED")) {
-            tech_pvt->skype_callflow = CALLFLOW_STATUS_FAILED;
-            DEBUGA_SKYPE
-              ("we tried to call Skype on skype_call %s and Skype has now FAILED\n",
-               SKYPIAX_P_LOG, id);
-            tech_pvt->skype_call_id[0] = '\0';
-            strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
-            tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
-            return CALLFLOW_INCOMING_HANGUP;
-          } else if (!strcasecmp(value, "REFUSED")) {
-            if (!strcasecmp(id, tech_pvt->skype_call_id)) {
-              /* this is the id of the call we are in, probably we generated it */
-              tech_pvt->skype_callflow = CALLFLOW_STATUS_REFUSED;
-              DEBUGA_SKYPE
-                ("we tried to call Skype on skype_call %s and Skype has now REFUSED\n",
-                 SKYPIAX_P_LOG, id);
-              strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
-              tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
-              tech_pvt->skype_call_id[0] = '\0';
-              return CALLFLOW_INCOMING_HANGUP;
-            } else {
-              /* we're here because were us that refused an incoming call */
-              DEBUGA_SKYPE("we REFUSED skype_call %s\n", SKYPIAX_P_LOG, id);
+      if (rt > 0) {
 
-            }
-          } else if (!strcasecmp(value, "ROUTING")) {
-            tech_pvt->skype_callflow = CALLFLOW_STATUS_ROUTING;
-            tech_pvt->interface_state = SKYPIAX_STATE_DIALING;
-            strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
-            DEBUGA_SKYPE("skype_call: %s is now ROUTING\n", SKYPIAX_P_LOG, id);
-          } else if (!strcasecmp(value, "UNPLACED")) {
-            tech_pvt->skype_callflow = CALLFLOW_STATUS_UNPLACED;
-            tech_pvt->interface_state = SKYPIAX_STATE_DIALING;
-            strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
-            DEBUGA_SKYPE("skype_call: %s is now UNPLACED\n", SKYPIAX_P_LOG, id);
-          } else if (!strcasecmp(value, "INPROGRESS")) {
-            char msg_to_skype[1024];
-            tech_pvt->skype_callflow = CALLFLOW_STATUS_INPROGRESS;
-            strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
-            tech_pvt->interface_state = SKYPIAX_STATE_UP;
-            DEBUGA_SKYPE("skype_call: %s is now active\n", SKYPIAX_P_LOG, id);
-            sprintf(msg_to_skype, "ALTER CALL %s SET_INPUT PORT=\"%d\"", id,
-                    tech_pvt->tcp_cli_port);
-            skypiax_skype_write(tech_pvt, msg_to_skype);
-            start_audio_threads(tech_pvt);
-            sprintf(msg_to_skype, "ALTER CALL %s SET_OUTPUT PORT=\"%d\"", id,
-                    tech_pvt->tcp_srv_port);
-            skypiax_skype_write(tech_pvt, msg_to_skype);
+        /* read from the pipe the audio frame we are supposed to send out */
+        got =
+          skypiax_pipe_read(tech_pvt->audioskypepipe[0], cli_in,
+                            SAMPLES_PER_FRAME * sizeof(short));
+        if (got != SAMPLES_PER_FRAME * sizeof(short)) {
+          WARNINGA("got is %d, but was expected to be %d\n", SKYPIAX_P_LOG, got,
+                   SAMPLES_PER_FRAME * sizeof(short));
+        }
 
-            tech_pvt->skype_callflow = SKYPIAX_STATE_UP;
+        if (got == SAMPLES_PER_FRAME * sizeof(short)) {
+          if (SAMPLERATE_SKYPIAX == 8000) {
 
-            if (!strlen(tech_pvt->session_uuid_str)) {
-              DEBUGA_SKYPE("New Inbound Channel!\n", SKYPIAX_P_LOG);
-              new_inbound_channel(tech_pvt);
-            } else {
-              DEBUGA_SKYPE("Outbound Channel Answered!\n", SKYPIAX_P_LOG);
-              outbound_channel_answered(tech_pvt);
+            /* we're upsampling from 8khz to 16khz, cli_out will contain two times each sample from cli_in */
+            a = 0;
+            for (i = 0; i < 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 < got / sizeof(short); i++) {
+              cli_out[i] = cli_in[i];
             }
-
           } else {
-            WARNINGA("skype_call: %s, STATUS: %s is not recognized\n", SKYPIAX_P_LOG, id,
-                     value);
+            ERRORA("SAMPLERATE_SKYPIAX can only be 8000 or 16000\n", SKYPIAX_P_LOG);
+          }
 
+          /* send the 16khz frame to the Skype client waiting for incoming audio */
+          len = send(fd, (char *) cli_out, got, 0);
+
+          if (len == -1) {
+            break;
+          } else if (len != got) {
+            ERRORA("len=%d\n", SKYPIAX_P_LOG, len);
+            skypiax_sleep(1000);
+            break;
           }
-        }                       //STATUS
 
-      }                         //CALL
+        } else {
 
-      /* the "numbered" messages that follows are used by the directory application, not yet ported */
-      if (!strcasecmp(message, "#333")) {
-        /* DEBUGA_SKYPE("Skype MSG: message_2: %s, message2[11]: %s\n", SKYPIAX_P_LOG,
-         * message_2, &message_2[11]); */
-        memset(tech_pvt->skype_friends, 0, 4096);
-        strncpy(tech_pvt->skype_friends, &message_2[11], 4095);
-      }
-      if (!strcasecmp(message, "#222")) {
-        /* DEBUGA_SKYPE("Skype MSG: message_2: %s, message2[10]: %s\n", SKYPIAX_P_LOG,
-         * message_2, &message_2[10]); */
-        memset(tech_pvt->skype_fullname, 0, 512);
-        strncpy(tech_pvt->skype_fullname, &message_2[10], 511);
-      }
-      if (!strcasecmp(message, "#765")) {
-        /* DEBUGA_SKYPE("Skype MSG: message_2: %s, message2[10]: %s\n", SKYPIAX_P_LOG,
-         * message_2, &message_2[10]); */
-        memset(tech_pvt->skype_displayname, 0, 512);
-        strncpy(tech_pvt->skype_displayname, &message_2[10], 511);
+          WARNINGA("got is %d, but was expected to be %d\n", SKYPIAX_P_LOG, got,
+                   SAMPLES_PER_FRAME * sizeof(short));
+        }
+      } else {
+        if (rt)
+          ERRORA("CLI rt=%d\n", SKYPIAX_P_LOG, rt);
+        skypiax_sleep(10000);
       }
 
-      a = 0;
-    }                           //message end
-  }                             //read_from_pipe
+    }
+    DEBUGA_SKYPE("Skype outbound audio GONE\n", SKYPIAX_P_LOG);
+    skypiax_close_socket(fd);
+    break;
+  }
 
-  return 0;
+  DEBUGA_SKYPE("outbound audio server (I am it) GONE\n", SKYPIAX_P_LOG);
+  skypiax_close_socket(s);
+  return NULL;
+}
+
+int skypiax_skypeaudio_read(private_t * tech_pvt)
+{
+  unsigned int samples;
+
+  samples =
+    skypiax_pipe_read(tech_pvt->audiopipe[0], tech_pvt->read_frame.data,
+                      SAMPLES_PER_FRAME * sizeof(short));
+
+  if (samples != SAMPLES_PER_FRAME * sizeof(short)) {
+    if (samples)
+      WARNINGA("read samples=%u expected=%u\n", SKYPIAX_P_LOG, samples,
+               SAMPLES_PER_FRAME * sizeof(short));
+    return 0;
+  } else {
+    /* A real frame */
+    tech_pvt->read_frame.datalen = samples;
+  }
+  return 1;
 }
 
 int skypiax_skype_senddigit(private_t * tech_pvt, char digit)
@@ -722,9 +663,7 @@
   char msg_to_skype[1024];
 
   DEBUGA_SKYPE("DIGIT received: %c\n", SKYPIAX_P_LOG, digit);
-
   sprintf(msg_to_skype, "SET CALL %s DTMF %c", tech_pvt->skype_call_id, digit);
-
   skypiax_skype_write(tech_pvt, msg_to_skype);
 
   return 0;
@@ -743,7 +682,6 @@
 
   sprintf(msg_to_skype, "CALL %s", rdest);
   if (skypiax_skype_write(tech_pvt, msg_to_skype) < 0) {
-
     ERRORA("failed to communicate with Skype client, now exit\n", SKYPIAX_P_LOG);
     return -1;
   }



More information about the Freeswitch-branches mailing list