From 48b0043ebd40fe3e48fad7ec7c99487e2e2a9421 Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Sat, 20 Feb 2010 12:32:10 +0000 Subject: [PATCH] skypiax: completely new audio threads, let's see how it works on windoz git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@16708 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/mod/endpoints/mod_skypiax/mod_skypiax.c | 239 +++++++++++- src/mod/endpoints/mod_skypiax/skypiax.h | 3 + .../endpoints/mod_skypiax/skypiax_protocol.c | 364 ++++++++++++++++++ 3 files changed, 604 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_skypiax/mod_skypiax.c b/src/mod/endpoints/mod_skypiax/mod_skypiax.c index 393e2ef359..0776e01c6f 100644 --- a/src/mod/endpoints/mod_skypiax/mod_skypiax.c +++ b/src/mod/endpoints/mod_skypiax/mod_skypiax.c @@ -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); diff --git a/src/mod/endpoints/mod_skypiax/skypiax.h b/src/mod/endpoints/mod_skypiax/skypiax.h index f367a2fab2..3ceffa67ab 100644 --- a/src/mod/endpoints/mod_skypiax/skypiax.h +++ b/src/mod/endpoints/mod_skypiax/skypiax.h @@ -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; + }; diff --git a/src/mod/endpoints/mod_skypiax/skypiax_protocol.c b/src/mod/endpoints/mod_skypiax/skypiax_protocol.c index 693240f84a..61f378cda6 100644 --- a/src/mod/endpoints/mod_skypiax/skypiax_protocol.c +++ b/src/mod/endpoints/mod_skypiax/skypiax_protocol.c @@ -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];