]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
skypiax: completely new audio threads, let's see how it works on windoz
authorGiovanni Maruzzelli <gmaruzz@gmail.com>
Sat, 20 Feb 2010 12:32:10 +0000 (12:32 +0000)
committerGiovanni Maruzzelli <gmaruzz@gmail.com>
Sat, 20 Feb 2010 12:32:10 +0000 (12:32 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@16708 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/mod/endpoints/mod_skypiax/mod_skypiax.c
src/mod/endpoints/mod_skypiax/skypiax.h
src/mod/endpoints/mod_skypiax/skypiax_protocol.c

index 393e2ef359235fdf242de01edccbe9a175233d33..0776e01c6fd046b6cb756003bba8bde73b02e952 100644 (file)
@@ -258,6 +258,7 @@ switch_status_t skypiax_tech_init(private_t * tech_pvt, switch_core_session_t *s
                return SWITCH_STATUS_FALSE;
        }
 
+#if 0
        if (switch_core_timer_init(&tech_pvt->timer_read, "soft", 20, tech_pvt->read_codec.implementation->samples_per_packet, skypiax_module_pool) !=
                SWITCH_STATUS_SUCCESS) {
                ERRORA("setup timer failed\n", SKYPIAX_P_LOG);
@@ -267,7 +268,7 @@ switch_status_t skypiax_tech_init(private_t * tech_pvt, switch_core_session_t *s
        switch_core_timer_sync(&tech_pvt->timer_read);
 
 #ifdef TIMER_WRITE
-       if (switch_core_timer_init(&tech_pvt->timer_write, "soft", 20, tech_pvt->write_codec.implementation->samples_per_packet, skypiax_module_pool) !=
+       if (switch_core_timer_init(&tech_pvt->timer_write, "soft", 10, tech_pvt->write_codec.implementation->samples_per_packet, skypiax_module_pool) !=
                SWITCH_STATUS_SUCCESS) {
                ERRORA("setup timer failed\n", SKYPIAX_P_LOG);
                return SWITCH_STATUS_FALSE;
@@ -275,6 +276,7 @@ switch_status_t skypiax_tech_init(private_t * tech_pvt, switch_core_session_t *s
 
        switch_core_timer_sync(&tech_pvt->timer_write);
 #endif // TIMER_WRITE
+#endif
 
     dtmf_rx_init(&tech_pvt->dtmf_state, NULL, NULL);
     dtmf_rx_parms(&tech_pvt->dtmf_state, 0, 10, 10, -99);
@@ -512,6 +514,7 @@ 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];
+       switch_status_t status;
 
 
        channel = switch_core_session_get_channel(session);
@@ -532,6 +535,8 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
        switch_clear_flag(tech_pvt, TFLAG_VOICE);
        //switch_set_flag(tech_pvt, TFLAG_HANGUP);
 
+       tech_pvt->interface_state = SKYPIAX_STATE_HANGUP_REQUESTED;
+
        if (strlen(tech_pvt->skype_call_id)) {
                //switch_thread_cond_signal(tech_pvt->cond);
                DEBUGA_SKYPE("hanging up skype call: %s\n", SKYPIAX_P_LOG, tech_pvt->skype_call_id);
@@ -540,6 +545,17 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
        }
        //memset(tech_pvt->session_uuid_str, '\0', sizeof(tech_pvt->session_uuid_str));
        //*tech_pvt->session_uuid_str = '\0';
+
+                       if (tech_pvt->tcp_cli_thread) {
+                               switch_thread_join(&status, tech_pvt->tcp_cli_thread);
+                       }
+                       if(status!=SWITCH_STATUS_SUCCESS)
+       ERRORA("%s cli_join HANGUP\n", SKYPIAX_P_LOG, tech_pvt->name);
+                       if (tech_pvt->tcp_srv_thread) {
+                               switch_thread_join(&status, tech_pvt->tcp_srv_thread);
+                       }
+                       if(status!=SWITCH_STATUS_SUCCESS)
+       ERRORA("%s srv_join HANGUP\n", SKYPIAX_P_LOG, tech_pvt->name);
        DEBUGA_SKYPE("%s CHANNEL HANGUP\n", SKYPIAX_P_LOG, tech_pvt->name);
        switch_mutex_lock(globals.mutex);
        globals.calls--;
@@ -675,6 +691,8 @@ static switch_status_t channel_send_dtmf(switch_core_session_t *session, const s
        return SWITCH_STATUS_SUCCESS;
 }
 
+#ifdef OLDTCP
+#if 0
 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;
@@ -855,7 +873,205 @@ memset(tech_pvt->audiobuf_cli, 255, sizeof(tech_pvt->audiobuf_cli));
 
        return SWITCH_STATUS_SUCCESS;
 }
+#endif //0
+#else
+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;
+       char digit_str[256];
+       short *frame_16_khz;
+       short frame_8_khz[160]; 
+       int i;
+       int a;
+size_t bytes_read;
+
+
+       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("channel not ready \n", SKYPIAX_P_LOG);
+               //TODO: kill the bastard
+               return SWITCH_STATUS_FALSE;
+       }
+
+
+
+       if (!tech_pvt->read_buffer) {
+               int32_t len = 640 * 8;
+
+               switch_buffer_create(skypiax_module_pool, &tech_pvt->read_buffer, len);
+               switch_assert(tech_pvt->read_buffer);
+       }
+
+
+       tech_pvt->begin_to_read=1;
+
+
+
+       tech_pvt->read_frame.flags = SFF_NONE;
+       *frame = NULL;
+
+       switch_core_timer_next(&tech_pvt->timer_read);
+
+
+       switch_mutex_lock(tech_pvt->mutex_audio_srv);
+       if ((bytes_read = switch_buffer_read(tech_pvt->read_buffer, tech_pvt->read_frame.data, SAMPLES_PER_FRAME * sizeof(short)))) {
+               tech_pvt->read_frame.datalen = bytes_read;
+       }
+       switch_mutex_unlock(tech_pvt->mutex_audio_srv);
+
+
+       if (!bytes_read) {
+               ERRORA("skypiax_audio_read Silence\n", SKYPIAX_P_LOG);
+               memset(tech_pvt->read_frame.data, 255, SAMPLES_PER_FRAME * sizeof(short));
+               tech_pvt->read_frame.datalen = SAMPLES_PER_FRAME * sizeof(short);
+
+       }
+
+       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("CHANNEL READ FRAME goto CNG\n", SKYPIAX_P_LOG);
+                       goto cng;
+               }
+
+               if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
+                       DEBUGA_SKYPE("CHANNEL READ FRAME not IO\n", SKYPIAX_P_LOG);
+                       return SWITCH_STATUS_FALSE;
+               }
+
+               if (switch_test_flag(tech_pvt, TFLAG_IO) && switch_test_flag(tech_pvt, TFLAG_VOICE)) {
+                       switch_clear_flag(tech_pvt, TFLAG_VOICE);
+                       if (!tech_pvt->read_frame.datalen) {
+                               DEBUGA_SKYPE("CHANNEL READ CONTINUE\n", SKYPIAX_P_LOG);
+                               continue;
+                       }
+                       *frame = &tech_pvt->read_frame;
+
+
+                       if (switch_true(switch_channel_get_variable(channel, "skype_get_inband_dtmf"))) {
+
+                               frame_16_khz = tech_pvt->read_frame.data;
+
+                               a = 0;
+                               for (i = 0; i < tech_pvt->read_frame.datalen / sizeof(short); i++) {
+                                       frame_8_khz[a] = frame_16_khz[i];
+                                       i++;
+                                       a++;
+                               }
+                               //DEBUGA_SKYPE("a=%d i=%d\n", SKYPIAX_P_LOG, a, i);
+
+                               memset(digit_str, 0, sizeof(digit_str));
+                               //dtmf_rx(&tech_pvt->dtmf_state, (int16_t *) tech_pvt->read_frame.data,tech_pvt->read_frame.datalen/sizeof(short) );
+                               dtmf_rx(&tech_pvt->dtmf_state, (int16_t *) frame_8_khz, 160);
+                               dtmf_rx_get(&tech_pvt->dtmf_state, digit_str, sizeof(digit_str));
+
+
+                               if (digit_str[0]) {
+                                       switch_time_t new_dtmf_timestamp = switch_time_now();
+                                       if ((new_dtmf_timestamp - tech_pvt->old_dtmf_timestamp) > 350000) {     //FIXME: make it configurable
+                                               char *p = digit_str;
+                                               switch_channel_t *channel = switch_core_session_get_channel(session);
+
+                                               while (p && *p) {
+                                                       switch_dtmf_t dtmf;
+                                                       dtmf.digit = *p;
+                                                       dtmf.duration = SWITCH_DEFAULT_DTMF_DURATION;
+                                                       switch_channel_queue_dtmf(channel, &dtmf);
+                                                       p++;
+                                               }
+                                               NOTICA("DTMF DETECTED: [%s] new_dtmf_timestamp: %u, delta_t: %u\n", SKYPIAX_P_LOG, digit_str, (unsigned int) new_dtmf_timestamp,
+                                                               (unsigned int) (new_dtmf_timestamp - tech_pvt->old_dtmf_timestamp));
+                                               tech_pvt->old_dtmf_timestamp = new_dtmf_timestamp;
+                                       }
+                               }
+                       }
+
+
+
+
+
+#if SWITCH_BYTE_ORDER == __BIG_ENDIAN
+                       if (switch_test_flag(tech_pvt, TFLAG_LINEAR)) {
+                               switch_swap_linear((*frame)->data, (int) (*frame)->datalen / 2);
+                       }
+#endif
+                       return SWITCH_STATUS_SUCCESS;
+               }
+
+               DEBUGA_SKYPE("CHANNEL READ no TFLAG_IO\n", SKYPIAX_P_LOG);
+               return SWITCH_STATUS_FALSE;
+
+       }
+
+       DEBUGA_SKYPE("CHANNEL READ FALSE\n", SKYPIAX_P_LOG);
+       return SWITCH_STATUS_FALSE;
+
+cng:
+       data = (switch_byte_t *) tech_pvt->read_frame.data;
+       data[0] = 65;
+       data[1] = 0;
+       tech_pvt->read_frame.datalen = 2;
+       tech_pvt->read_frame.flags = SFF_CNG;
+       *frame = &tech_pvt->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;
+
+       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("channel not ready \n", 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->data, (int) frame->datalen / 2);
+       }
+#endif
+
+       if (!tech_pvt->write_buffer) {
+               int32_t len = 320 * 8;
+
+               switch_buffer_create(skypiax_module_pool, &tech_pvt->write_buffer, len);
+               switch_assert(tech_pvt->write_buffer);
+       }
+
+
+
+       sent = frame->datalen;
+
+       switch_mutex_lock(tech_pvt->mutex_audio_cli);
+       switch_buffer_write(tech_pvt->write_buffer, frame->data, frame->datalen);
+       switch_mutex_unlock(tech_pvt->mutex_audio_cli);
+
+       tech_pvt->begin_to_write=1;
+       if (sent != frame->datalen && sent != -1) {
+               DEBUGA_SKYPE("CLI PIPE write %d\n", SKYPIAX_P_LOG, sent);
+       }
+
+       return SWITCH_STATUS_SUCCESS;
+}
 
+#endif //OLDTCP
 static switch_status_t channel_answer_channel(switch_core_session_t *session)
 {
        private_t *tech_pvt;
@@ -1127,7 +1343,7 @@ static void *SWITCH_THREAD_FUNC skypiax_signaling_thread_func(switch_thread_t *
                if (!(running && tech_pvt->running))
                        break;
                res = skypiax_signaling_read(tech_pvt);
-               if (res == CALLFLOW_INCOMING_HANGUP) {
+               if (res == CALLFLOW_INCOMING_HANGUP || tech_pvt->skype_callflow == CALLFLOW_INCOMING_HANGUP) {
                        switch_core_session_t *session = NULL;
                        switch_channel_t *channel = NULL;
                        //private_t *tech_pvt = NULL;
@@ -1840,7 +2056,26 @@ int start_audio_threads(private_t * tech_pvt)
 
 tech_pvt->begin_to_write=0;
 tech_pvt->begin_to_read=0;
+#if 1
+       if (switch_core_timer_init(&tech_pvt->timer_read, "soft", 20, 320, skypiax_module_pool) !=
+               SWITCH_STATUS_SUCCESS) {
+               ERRORA("setup timer failed\n", SKYPIAX_P_LOG);
+               return SWITCH_STATUS_FALSE;
+       }
 
+       switch_core_timer_sync(&tech_pvt->timer_read);
+
+#ifdef TIMER_WRITE
+       if (switch_core_timer_init(&tech_pvt->timer_write, "soft", 10, 320, skypiax_module_pool) !=
+               SWITCH_STATUS_SUCCESS) {
+               ERRORA("setup timer failed\n", SKYPIAX_P_LOG);
+               return SWITCH_STATUS_FALSE;
+       }
+
+       switch_core_timer_sync(&tech_pvt->timer_write);
+#endif // TIMER_WRITE
+
+#endif
        switch_threadattr_create(&thd_attr, skypiax_module_pool);
        switch_threadattr_detach_set(thd_attr, 0);
        switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
index f367a2fab2c91b4072e6ccdcaffbb4febd8d9138..3ceffa67abb3efaf7d2c29f5e8a1dc115130e12f 100644 (file)
@@ -288,6 +288,9 @@ int begin_to_write;
 int begin_to_read;
                  dtmf_rx_state_t dtmf_state;
         switch_time_t old_dtmf_timestamp;
+               switch_buffer_t *write_buffer;
+               switch_buffer_t *read_buffer;
+
 
 };
 
index 693240f84aa4ffa5c26c7c72cdd8ba48b7806418..61f378cda68678c75ff82a7776a3698aff9a00ad 100644 (file)
@@ -728,6 +728,8 @@ int skypiax_signaling_read(private_t * tech_pvt)
        return 0;
 }
 
+#ifdef OLDTCP
+#if 0
 void *skypiax_do_tcp_srv_thread_func(void *obj)
 {
        private_t *tech_pvt = obj;
@@ -1278,7 +1280,369 @@ int skypiax_audio_read(private_t * tech_pvt)
        }
        return 1;
 }
+#endif//0
+#else
+
+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];
+       int sockbufsize = 0;
+       unsigned int size = sizeof(int);
+
+       s = skypiax_socket_create_and_bind(tech_pvt, &tech_pvt->tcp_srv_port);
+       if (s < 0) {
+               ERRORA("skypiax_socket_create_and_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 (tech_pvt->interface_state != SKYPIAX_STATE_DOWN
+                       && (tech_pvt->skype_callflow == CALLFLOW_STATUS_INPROGRESS
+                               || tech_pvt->skype_callflow == CALLFLOW_STATUS_EARLYMEDIA
+                               || tech_pvt->skype_callflow == CALLFLOW_STATUS_REMOTEHOLD || tech_pvt->skype_callflow == SKYPIAX_STATE_UP)) {
+
+               unsigned int fdselectgio;
+               int rtgio;
+               fd_set fsgio;
+               struct timeval togio;
+
+               if (!(running && tech_pvt->running))
+                       break;
+               FD_ZERO(&fsgio);
+               togio.tv_usec = 20000;  //20msec
+               togio.tv_sec = 0;
+               fdselectgio = s;
+               FD_SET(fdselectgio, &fsgio);
+
+               rtgio = select(fdselectgio + 1, &fsgio, NULL, NULL, &togio);
+
+               if (rtgio) {
+
+                       /****************************/
+
+                       while (s > 0 && (fd = accept(s, (struct sockaddr *) &remote_addr, &sin_size)) > 0) {
+                               DEBUGA_SKYPE("ACCEPTED here I send you %d\n", SKYPIAX_P_LOG, tech_pvt->tcp_srv_port);
+
+                               sockbufsize = 0;
+                               size = sizeof(int);
+                               getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *) &sockbufsize, &size);
+                               DEBUGA_SKYPE("3 SO_RCVBUF is %d, size is %d\n", SKYPIAX_P_LOG, sockbufsize, size);
+                               sockbufsize = 0;
+                               size = sizeof(int);
+                               getsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *) &sockbufsize, &size);
+                               DEBUGA_SKYPE("3 SO_SNDBUF is %d, size is %d\n", SKYPIAX_P_LOG, sockbufsize, size);
+
+
+                               if (!(running && tech_pvt->running))
+                                       break;
+                               while (tech_pvt->interface_state != SKYPIAX_STATE_DOWN
+                                               && (tech_pvt->skype_callflow == CALLFLOW_STATUS_INPROGRESS
+                                                       || tech_pvt->skype_callflow == CALLFLOW_STATUS_EARLYMEDIA
+                                                       || tech_pvt->skype_callflow == CALLFLOW_STATUS_REMOTEHOLD || tech_pvt->skype_callflow == SKYPIAX_STATE_UP)) {
+
+                                       unsigned int fdselect;
+                                       int rt;
+                                       fd_set fs;
+                                       struct timeval to;
+
+                                       if (!(running && tech_pvt->running))
+                                               break;
+                                       fdselect = fd;
+                                       FD_ZERO(&fs);
+                                       FD_SET(fdselect, &fs);
+                                       to.tv_usec = 60000;     //60 msec
+                                       to.tv_sec = 0;
+
+                                       if(tech_pvt->begin_to_read==0){
+                                               skypiax_sleep(1000);
+                                               continue;
+                                       }
+                                       rt = select(fdselect + 1, &fs, NULL, NULL, &to);
+                                       if (rt > 0) {
+
+                                               if (tech_pvt->skype_callflow != CALLFLOW_STATUS_REMOTEHOLD) {
+                                                       len = recv(fd, (char *) srv_in, 640, 0);
+                                               } else {
+                                                       continue;
+                                               }
+
+                                               if (len == -1) {
+                                                       ERRORA("len=%d, error: %s\n", SKYPIAX_P_LOG, len,  strerror(errno));
+                                                       break;
+                                               }
+                                               if (len > 0) {
+                                                       switch_mutex_lock(tech_pvt->mutex_audio_srv);
+                                                       switch_buffer_write(tech_pvt->read_buffer, srv_in, len);
+                                                       switch_mutex_unlock(tech_pvt->mutex_audio_srv);
+                                               } else if (len == 0) {
+                                                       ERRORA("CLOSING, len=%d, expected 640\n", SKYPIAX_P_LOG, len);
+                                                       break;
+                                               } else {
+                                                       WARNINGA("len=%d, expected 640\n", SKYPIAX_P_LOG, len);
+                                               }
+
+                                       } else if(rt==0){
+                                               continue;
+                                       } else {
+                                               ERRORA("SRV rt=%d\n", SKYPIAX_P_LOG, rt);
+                                               break;
+                                       }
+
+                               }
+
+                               DEBUGA_SKYPE("Skype incoming audio GONE\n", SKYPIAX_P_LOG);
+                               tech_pvt->skype_callflow = CALLFLOW_INCOMING_HANGUP;
+                               skypiax_sleep(20000);
+                               skypiax_close_socket(fd);
+                               break;
+                       }
+                       break;
+               }
+       }
+
+       DEBUGA_SKYPE("incoming audio (read) server (I am it) EXITING\n", SKYPIAX_P_LOG);
+       skypiax_close_socket(s);
+       s = -1;
+       tech_pvt->tcp_srv_thread = NULL;
+       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 */
+       int sockbufsize = 0;
+       unsigned int size = sizeof(int);
+
+       s = skypiax_socket_create_and_bind(tech_pvt, &tech_pvt->tcp_cli_port);
+       if (s < 0) {
+               ERRORA("skypiax_socket_create_and_bind error!\n", SKYPIAX_P_LOG);
+               return NULL;
+       }
+
+
+
+       DEBUGA_SKYPE("started tcp_cli_thread thread.\n", SKYPIAX_P_LOG);
+
+       listen(s, 6);
+
+       sin_size = sizeof(remote_addr);
+
+       /****************************/
+       while (tech_pvt->interface_state != SKYPIAX_STATE_DOWN
+                       && (tech_pvt->skype_callflow == CALLFLOW_STATUS_INPROGRESS
+                               || tech_pvt->skype_callflow == CALLFLOW_STATUS_EARLYMEDIA
+                               || tech_pvt->skype_callflow == CALLFLOW_STATUS_REMOTEHOLD || tech_pvt->skype_callflow == SKYPIAX_STATE_UP)) {
+
+               unsigned int fdselectgio;
+               int rtgio;
+               fd_set fsgio;
+               struct timeval togio;
+
+               if (!(running && tech_pvt->running))
+                       break;
+               FD_ZERO(&fsgio);
+               togio.tv_usec = 20000;  //20msec
+               togio.tv_sec = 0;
+               fdselectgio = s;
+               FD_SET(fdselectgio, &fsgio);
+
+               rtgio = select(fdselectgio + 1, &fsgio, NULL, NULL, &togio);
+
+               if (rtgio) {
+
+                       /****************************/
+
+                       while (s > 0 && (fd = accept(s, (struct sockaddr *) &remote_addr, &sin_size)) > 0) {
+                               DEBUGA_SKYPE("ACCEPTED here you send me %d\n", SKYPIAX_P_LOG, tech_pvt->tcp_cli_port);
+
+                               sockbufsize = 0;
+                               size = sizeof(int);
+                               getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *) &sockbufsize, &size);
+                               DEBUGA_SKYPE("4 SO_RCVBUF is %d, size is %d\n", SKYPIAX_P_LOG, sockbufsize, size);
+                               sockbufsize = 0;
+                               size = sizeof(int);
+                               getsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *) &sockbufsize, &size);
+                               DEBUGA_SKYPE("4 SO_SNDBUF is %d, size is %d\n", SKYPIAX_P_LOG, sockbufsize, size);
+
+
+
+                               if (!(running && tech_pvt->running))
+                                       break;
+                               while (tech_pvt->interface_state != SKYPIAX_STATE_DOWN
+                                               && (tech_pvt->skype_callflow == CALLFLOW_STATUS_INPROGRESS
+                                                       || tech_pvt->skype_callflow == CALLFLOW_STATUS_EARLYMEDIA
+                                                       || tech_pvt->skype_callflow == CALLFLOW_STATUS_REMOTEHOLD || tech_pvt->skype_callflow == SKYPIAX_STATE_UP)) {
+                                       unsigned int fdselect;
+                                       int rt;
+                                       fd_set fs;
+                                       struct timeval to;
+                                       size_t bytes_to_write;
+                                       int waitin;
+                                       int waited_max;
+
+                                       if (!(running && tech_pvt->running))
+                                               break;
+                                       FD_ZERO(&fs);
+                                       to.tv_usec = 1000;      //1msec
+                                       to.tv_sec = 0;
+
+                                       fdselect = fd;
+                                       FD_SET(fdselect, &fs);
+
+
+                                       if(tech_pvt->begin_to_write==0){
+                                               skypiax_sleep(1000);
+                                               continue;
+                                       }
+
+                                       //rt = select(fdselect + 1, NULL, &fs, NULL, &to);
+                                       //if(rt==-1)
+                                               //break;
+                                       rt=1;
+
+                                       if (rt > 0) {
+
+                                                       //DEBUGA_SKYPE("before!\n", SKYPIAX_P_LOG);
+                                               if (tech_pvt->timer_write.timer_interface && tech_pvt->timer_write.timer_interface->timer_next && tech_pvt->interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) {
+                                                       switch_core_timer_next(&tech_pvt->timer_write);
+                                               }
+                                                       //DEBUGA_SKYPE("after!\n", SKYPIAX_P_LOG);
+                                               bytes_to_write=0;
+                                               waitin=0;
+                                               waited_max=1;
+
+                                               if(tech_pvt->skype_callflow == CALLFLOW_INCOMING_HANGUP){
+                                                       break;
+                                               }
+                                               if(!switch_buffer_inuse(tech_pvt->write_buffer)){
+                                                       memset(cli_out, 255, sizeof(cli_out));
+                                                       bytes_to_write = 320;
+                                                       DEBUGA_SKYPE("Silence!\n", SKYPIAX_P_LOG);
+                                               }else {
+                                                       switch_mutex_lock(tech_pvt->mutex_audio_cli);
+                                                       bytes_to_write = switch_buffer_read(tech_pvt->write_buffer, cli_out, 320);
+                                                       switch_mutex_unlock(tech_pvt->mutex_audio_cli);
+                                               }
+
+                                               /* send the 16khz frame to the Skype client waiting for incoming audio to be sent to the remote party */
+                                               if (tech_pvt->skype_callflow != CALLFLOW_STATUS_REMOTEHOLD) {
+                                                       len = send(fd, cli_out, bytes_to_write, 0);
+                                                       if (len == -1) {
+                                                               ERRORA("len=%d, error: %s\n", SKYPIAX_P_LOG, len,  strerror(errno));
+                                                               break;
+                                                       }
+                                                       if (len != bytes_to_write) {
+                                                               WARNINGA("len=%d\n", SKYPIAX_P_LOG, len);
+                                                       }
+                                               }
+                                       } else if(rt==0){
+                                               continue;
+                                       } else {
+                                               ERRORA("CLI rt=%d\n", SKYPIAX_P_LOG, rt);
+                                               break;
+                                       }
+
+                               }
+                               DEBUGA_SKYPE("Skype outbound audio GONE\n", SKYPIAX_P_LOG);
+                               tech_pvt->skype_callflow = CALLFLOW_INCOMING_HANGUP;
+                               skypiax_sleep(20000);
+                               skypiax_close_socket(fd);
+                               break;
+                       }
+                       break;
+               }
+       }
+
+       DEBUGA_SKYPE("outbound audio server (I am it) EXITING\n", SKYPIAX_P_LOG);
+       skypiax_close_socket(s);
+       s = -1;
+       tech_pvt->tcp_cli_thread = NULL;
+       return NULL;
+}
+
+int skypiax_audio_read(private_t * tech_pvt)
+{
+       unsigned int samples;
+       int waitin;
+       int max_waitin=30;
+
+       waitin=0;
+       while (tech_pvt->flag_audio_srv == 0) {
+#ifdef WIN32
+               skypiax_sleep(1000);            //0.1 millisec
+#else
+               skypiax_sleep(1000);    //1 millisec
+#endif //WIN32
+               waitin++;
+
+               if(waitin == max_waitin){
+                       DEBUGA_SKYPE("read is now at max_waitin: %d\n", SKYPIAX_P_LOG, waitin);
+                       break;
+               }
+               //WARNINGA("read now is 0\n", SKYPIAX_P_LOG);
+       }
+       if(waitin > 22){
+               DEBUGA_SKYPE("read is now %d\n", SKYPIAX_P_LOG, waitin);
+       }
+       //samples = skypiax_pipe_read(tech_pvt->audiopipe_srv[0], tech_pvt->read_frame.data, SAMPLES_PER_FRAME * sizeof(short));
+                       switch_mutex_lock(tech_pvt->mutex_audio_srv);
+       memcpy(tech_pvt->read_frame.data, tech_pvt->audiobuf_srv, SAMPLES_PER_FRAME * sizeof(short));
+       tech_pvt->flag_audio_srv = 0;
+                       switch_mutex_unlock(tech_pvt->mutex_audio_srv);
+
+       samples = 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, (int) (SAMPLES_PER_FRAME * sizeof(short)));
+               return 0;
+       } else {
+               /* A real frame */
+               tech_pvt->read_frame.datalen = samples;
+       }
+       return 1;
+}
+
+
 
+#endif //OLDTCP
 int skypiax_senddigit(private_t * tech_pvt, char digit)
 {
        char msg_to_skype[1024];