diff --git a/src/mod/endpoints/mod_skypiax/mod_skypiax.c b/src/mod/endpoints/mod_skypiax/mod_skypiax.c index 1b61ffbe4c..0c0af6d3e2 100644 --- a/src/mod/endpoints/mod_skypiax/mod_skypiax.c +++ b/src/mod/endpoints/mod_skypiax/mod_skypiax.c @@ -185,7 +185,7 @@ static switch_status_t channel_on_init(switch_core_session_t * session) static switch_status_t channel_on_destroy(switch_core_session_t * session) { - //switch_channel_t *channel = NULL; + //switch_channel_t *channel = NULL; private_t *tech_pvt = NULL; //channel = switch_core_session_get_channel(session); @@ -194,19 +194,18 @@ static switch_status_t channel_on_destroy(switch_core_session_t * session) tech_pvt = switch_core_session_get_private(session); if (tech_pvt) { - if (switch_core_codec_ready(&tech_pvt->read_codec)) { - switch_core_codec_destroy(&tech_pvt->read_codec); - } - - if (switch_core_codec_ready(&tech_pvt->write_codec)) { - switch_core_codec_destroy(&tech_pvt->write_codec); - } + if (switch_core_codec_ready(&tech_pvt->read_codec)) { + switch_core_codec_destroy(&tech_pvt->read_codec); + } + + if (switch_core_codec_ready(&tech_pvt->write_codec)) { + switch_core_codec_destroy(&tech_pvt->write_codec); + } } return SWITCH_STATUS_SUCCESS; } - static switch_status_t channel_on_hangup(switch_core_session_t * session) { switch_channel_t *channel = NULL; @@ -230,7 +229,6 @@ static switch_status_t channel_on_hangup(switch_core_session_t * session) skypiax_signaling_write(tech_pvt, msg_to_skype); } - memset(tech_pvt->session_uuid_str, '\0', sizeof(tech_pvt->session_uuid_str)); DEBUGA_SKYPE("%s CHANNEL HANGUP\n", SKYPIAX_P_LOG, switch_channel_get_name(channel)); switch_mutex_lock(globals.mutex); @@ -509,12 +507,12 @@ switch_state_handler_table_t skypiax_state_handlers = { /*.on_hangup */ channel_on_hangup, /*.on_exchange_media */ channel_on_exchange_media, /*.on_soft_execute */ channel_on_soft_execute, - /*.on_consume_media*/ NULL, - /*.on_hibernate*/ NULL, - /*.on_reset*/ NULL, - /*.on_park*/ NULL, - /*.on_reporting*/ NULL, - /*.on_destroy*/ channel_on_destroy + /*.on_consume_media */ NULL, + /*.on_hibernate */ NULL, + /*.on_reset */ NULL, + /*.on_park */ NULL, + /*.on_reporting */ NULL, + /*.on_destroy */ channel_on_destroy }; switch_io_routines_t skypiax_io_routines = { @@ -561,7 +559,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t * sess if (strncmp("ANY", interface_name, strlen(interface_name)) == 0) { /* we've been asked for the "ANY" interface, let's find the first idle interface */ DEBUGA_SKYPE("Finding one available skype interface\n", SKYPIAX_P_LOG); - tech_pvt = find_available_skypiax_interface(); + tech_pvt = find_available_skypiax_interface(NULL); if (tech_pvt) found = 1; } @@ -1002,6 +1000,9 @@ static switch_status_t load_config(void) ("Interface_id=%d is now STARTED, the Skype client to which we are connected gave us the correct CURRENTUSERHANDLE (%s)\n", SKYPIAX_P_LOG, interface_id, globals.SKYPIAX_INTERFACES[interface_id].skype_user); + + skypiax_signaling_write(&globals.SKYPIAX_INTERFACES[interface_id], + "SET AUTOAWAY OFF"); } else { ERRORA ("The Skype client to which we are connected FAILED to gave us CURRENTUSERHANDLE=%s, interface_id=%d FAILED to start. No Skype client logged in as '%s' has been found. Please (re)launch a Skype client logged in as '%s'. Skypiax exiting now\n", @@ -1175,19 +1176,21 @@ int dtmf_received(private_t * tech_pvt, char *value) if (channel) { - if (! switch_channel_test_flag(channel, CF_BRIDGED)) { + if (!switch_channel_test_flag(channel, CF_BRIDGED)) { - switch_dtmf_t dtmf = { (char) value[0], switch_core_default_dtmf_duration(0) }; - DEBUGA_SKYPE("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 { - DEBUGA_SKYPE("received a DTMF on channel %s, but we're BRIDGED, so let's NOT relay it out of band\n", SKYPIAX_P_LOG, switch_channel_get_name(channel)); - } + switch_dtmf_t dtmf = { (char) value[0], switch_core_default_dtmf_duration(0) }; + DEBUGA_SKYPE("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 { + DEBUGA_SKYPE + ("received a DTMF on channel %s, but we're BRIDGED, so let's NOT relay it out of band\n", + SKYPIAX_P_LOG, switch_channel_get_name(channel)); + } } else { WARNINGA("received %c DTMF, but no channel?\n", SKYPIAX_P_LOG, value[0]); } @@ -1351,29 +1354,32 @@ done: return 0; } -private_t *find_available_skypiax_interface(void) +private_t *find_available_skypiax_interface(private_t * tech_pvt) { - private_t *tech_pvt = NULL; + private_t *tech_pvt2 = NULL; int found = 0; int i; + switch_mutex_lock(globals.mutex); + for (i = 0; !found && i < SKYPIAX_MAX_INTERFACES; i++) { if (strlen(globals.SKYPIAX_INTERFACES[i].name)) { int skype_state = 0; - tech_pvt = &globals.SKYPIAX_INTERFACES[i]; - skype_state = tech_pvt->interface_state; + tech_pvt2 = &globals.SKYPIAX_INTERFACES[i]; + skype_state = tech_pvt2->interface_state; DEBUGA_SKYPE("skype interface: %d, name: %s, state: %d\n", SKYPIAX_P_LOG, i, globals.SKYPIAX_INTERFACES[i].name, skype_state); - if (SKYPIAX_STATE_DOWN == skype_state || 0 == skype_state) { + if ((tech_pvt ? strcmp(tech_pvt2->skype_user, tech_pvt->skype_user) : 1) && (SKYPIAX_STATE_DOWN == skype_state || SKYPIAX_STATE_RING == skype_state || 0 == skype_state)) { //(if we got tech_pvt NOT NULL) if user is NOT the same, and iface is idle found = 1; break; } } } + switch_mutex_unlock(globals.mutex); if (found) - return tech_pvt; + return tech_pvt2; else return NULL; } @@ -1514,6 +1520,182 @@ end: return SWITCH_STATUS_SUCCESS; } +int skypiax_answer(private_t * tech_pvt, char *id, char *value) +{ + char msg_to_skype[1024]; + int i; + int found = 0; + private_t *giovatech; + struct timeval timenow; + + switch_mutex_lock(globals.mutex); + + gettimeofday(&timenow, NULL); + for (i = 0; !found && i < SKYPIAX_MAX_INTERFACES; i++) { + if (strlen(globals.SKYPIAX_INTERFACES[i].name)) { + + giovatech = &globals.SKYPIAX_INTERFACES[i]; + //NOTICA("skype interface: %d, name: %s, state: %d, value=%s, giovatech->callid_number=%s, giovatech->skype_user=%s\n", SKYPIAX_P_LOG, i, giovatech->name, giovatech->interface_state, value, giovatech->callid_number, giovatech->skype_user); + //FIXME check a timestamp here + if (strlen(giovatech->skype_call_id) && (giovatech->interface_state != SKYPIAX_STATE_DOWN) && (!strcmp(giovatech->skype_user, tech_pvt->skype_user)) && (!strcmp(giovatech->callid_number, value)) && ((((timenow.tv_sec - giovatech->answer_time.tv_sec) * 1000000) + (timenow.tv_usec - giovatech->answer_time.tv_usec)) < 500000)) { //0.5sec + found = 1; + DEBUGA_SKYPE + ("FOUND (name=%s, giovatech->interface_state=%d != SKYPIAX_STATE_DOWN) && (giovatech->skype_user=%s == tech_pvt->skype_user=%s) && (giovatech->callid_number=%s == value=%s)\n", + SKYPIAX_P_LOG, giovatech->name, giovatech->interface_state, + giovatech->skype_user, tech_pvt->skype_user, giovatech->callid_number, value) + break; + } + } + } + + if (found) { + //tech_pvt->callid_number[0]='\0'; + switch_mutex_unlock(globals.mutex); + return 0; + } + DEBUGA_SKYPE("NOT FOUND\n", SKYPIAX_P_LOG); + + if (!strlen(tech_pvt->skype_call_id)) { + /* we are not inside an active call */ + + sprintf(msg_to_skype, "GET CALL %s PARTNER_DISPNAME", id); + skypiax_signaling_write(tech_pvt, msg_to_skype); + switch_sleep(10000); + sprintf(msg_to_skype, "ALTER CALL %s ANSWER", id); + skypiax_signaling_write(tech_pvt, msg_to_skype); + DEBUGA_SKYPE("We answered a Skype RING on skype_call %s\n", SKYPIAX_P_LOG, id); + //FIXME write a timestamp here + gettimeofday(&tech_pvt->answer_time, NULL); + switch_copy_string(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1); + + switch_copy_string(tech_pvt->callid_number, value, + sizeof(tech_pvt->callid_number) - 1); + + DEBUGA_SKYPE + ("NEW! name: %s, state: %d, value=%s, tech_pvt->callid_number=%s, tech_pvt->skype_user=%s\n", + SKYPIAX_P_LOG, tech_pvt->name, tech_pvt->interface_state, value, + tech_pvt->callid_number, tech_pvt->skype_user); + switch_mutex_unlock(globals.mutex); + } else { + + ERRORA("We're in a call now %s\n", SKYPIAX_P_LOG, tech_pvt->skype_call_id); + switch_mutex_unlock(globals.mutex); + } + return 0; +} +int skypiax_transfer(private_t * tech_pvt, char *id, char *value) +{ + char msg_to_skype[1024]; + int i; + int found = 0; + private_t *giovatech; + struct timeval timenow; + + switch_mutex_lock(globals.mutex); + + gettimeofday(&timenow, NULL); + for (i = 0; !found && i < SKYPIAX_MAX_INTERFACES; i++) { + if (strlen(globals.SKYPIAX_INTERFACES[i].name)) { + + giovatech = &globals.SKYPIAX_INTERFACES[i]; + //NOTICA("skype interface: %d, name: %s, state: %d, value=%s, giovatech->callid_number=%s, giovatech->skype_user=%s\n", SKYPIAX_P_LOG, i, giovatech->name, giovatech->interface_state, value, giovatech->callid_number, giovatech->skype_user); + //FIXME check a timestamp here + if (strlen(giovatech->skype_call_id) && (giovatech->interface_state != SKYPIAX_STATE_DOWN) && (!strcmp(giovatech->skype_user, tech_pvt->skype_user)) && (!strcmp(giovatech->callid_number, value)) && ((((timenow.tv_sec - giovatech->answer_time.tv_sec) * 1000000) + (timenow.tv_usec - giovatech->answer_time.tv_usec)) < 500000)) { //0.5sec + found = 1; + DEBUGA_SKYPE + ("FOUND (name=%s, giovatech->interface_state=%d != SKYPIAX_STATE_DOWN) && (giovatech->skype_user=%s == tech_pvt->skype_user=%s) && (giovatech->callid_number=%s == value=%s)\n", + SKYPIAX_P_LOG, giovatech->name, giovatech->interface_state, + giovatech->skype_user, tech_pvt->skype_user, giovatech->callid_number, value) + break; + } + } + } + + if (found) { + //tech_pvt->callid_number[0]='\0'; + switch_mutex_unlock(globals.mutex); + return 0; + } + DEBUGA_SKYPE("NOT FOUND\n", SKYPIAX_P_LOG); + + if (!strlen(tech_pvt->skype_call_id)) { + /* we are not inside an active call */ + ERRORA("We're NO MORE in a call now %s\n", SKYPIAX_P_LOG, tech_pvt->skype_call_id); + switch_mutex_unlock(globals.mutex); + + } else { + + /* we're owned, we're in a call, let's try to transfer */ + /************************** TODO + Checking here if it is possible to transfer this call to Test2 + -> GET CALL 288 CAN_TRANSFER Test2 + <- CALL 288 CAN_TRANSFER test2 TRUE + **********************************/ + + private_t *available_skypiax_interface = NULL; + + gettimeofday(&timenow, NULL); + for (i = 0; !found && i < SKYPIAX_MAX_INTERFACES; i++) { + if (strlen(globals.SKYPIAX_INTERFACES[i].name)) { + + giovatech = &globals.SKYPIAX_INTERFACES[i]; + //NOTICA("skype interface: %d, name: %s, state: %d, value=%s, giovatech->callid_number=%s, giovatech->skype_user=%s\n", SKYPIAX_P_LOG, i, giovatech->name, giovatech->interface_state, value, giovatech->callid_number, giovatech->skype_user); + //FIXME check a timestamp here + if (strlen(giovatech->skype_transfer_call_id) && (giovatech->interface_state != SKYPIAX_STATE_DOWN) && (!strcmp(giovatech->skype_user, tech_pvt->skype_user)) && (!strcmp(giovatech->transfer_callid_number, value)) && ((((timenow.tv_sec - giovatech->transfer_time.tv_sec) * 1000000) + (timenow.tv_usec - giovatech->transfer_time.tv_usec)) < 1000000)) { //1.0 sec + found = 1; + DEBUGA_SKYPE + ("FOUND (name=%s, giovatech->interface_state=%d != SKYPIAX_STATE_DOWN) && (giovatech->skype_user=%s == tech_pvt->skype_user=%s) && (giovatech->transfer_callid_number=%s == value=%s)\n", + SKYPIAX_P_LOG, giovatech->name, giovatech->interface_state, + giovatech->skype_user, tech_pvt->skype_user, + giovatech->transfer_callid_number, value) + break; + } + } + } + + if (found) { + //tech_pvt->callid_number[0]='\0'; + switch_mutex_unlock(globals.mutex); + return 0; + } + DEBUGA_SKYPE("NOT FOUND\n", SKYPIAX_P_LOG); + + available_skypiax_interface = find_available_skypiax_interface(tech_pvt); + if (available_skypiax_interface) { + /* there is a skypiax interface idle, let's transfer the call to it */ + + //FIXME write a timestamp here + gettimeofday(&tech_pvt->transfer_time, NULL); + switch_copy_string(tech_pvt->skype_transfer_call_id, id, + sizeof(tech_pvt->skype_transfer_call_id) - 1); + + switch_copy_string(tech_pvt->transfer_callid_number, value, + sizeof(tech_pvt->transfer_callid_number) - 1); + + DEBUGA_SKYPE + ("Let's transfer the skype_call %s to %s interface (with skype_user: %s), because we are already in a skypiax call(%s)\n", + SKYPIAX_P_LOG, tech_pvt->skype_call_id, available_skypiax_interface->name, + available_skypiax_interface->skype_user, id); + sprintf(msg_to_skype, "ALTER CALL %s TRANSFER %s", id, + available_skypiax_interface->skype_user); + skypiax_signaling_write(tech_pvt, msg_to_skype); + } else { + /* no skypiax interfaces idle, do nothing */ + DEBUGA_SKYPE + ("Not answering the skype_call %s, because we are already in a skypiax call(%s) and no other skypiax interfaces are available OR another interface is answering this call\n", + SKYPIAX_P_LOG, tech_pvt->skype_call_id, id); + //sprintf(msg_to_skype, "ALTER CALL %s END HANGUP", id); + } + switch_sleep(10000); + DEBUGA_SKYPE + ("We (%s) have NOT answered a Skype RING on skype_call %s, because we are already in a skypiax call\n", + SKYPIAX_P_LOG, tech_pvt->skype_call_id, id); + + switch_mutex_unlock(globals.mutex); + } + return 0; +} + /* For Emacs: * Local Variables: * mode:c diff --git a/src/mod/endpoints/mod_skypiax/skypiax.h b/src/mod/endpoints/mod_skypiax/skypiax.h index 03482c6644..c1f5003165 100644 --- a/src/mod/endpoints/mod_skypiax/skypiax.h +++ b/src/mod/endpoints/mod_skypiax/skypiax.h @@ -36,6 +36,7 @@ #include #include +#include #ifndef WIN32 #include @@ -232,7 +233,11 @@ struct private_object { char skype_user[256]; char skype_password[256]; char destination[256]; + struct timeval answer_time; + struct timeval transfer_time; + char transfer_callid_number[50]; + char skype_transfer_call_id[512]; }; typedef struct private_object private_t; @@ -270,6 +275,8 @@ int skypiax_pipe_read(int pipe, short *buf, int howmany); int skypiax_pipe_write(int pipe, short *buf, int howmany); #endif /* WIN32 */ int skypiax_close_socket(unsigned int fd); -private_t *find_available_skypiax_interface(void); +private_t *find_available_skypiax_interface(private_t * tech_pvt); int remote_party_is_ringing(private_t * tech_pvt); int remote_party_is_early_media(private_t * tech_pvt); +int skypiax_answer(private_t * tech_pvt, char *id, char *value); +int skypiax_transfer(private_t * tech_pvt, char *id, char *value); diff --git a/src/mod/endpoints/mod_skypiax/skypiax_protocol.c b/src/mod/endpoints/mod_skypiax/skypiax_protocol.c index dca420f0ae..e16c798f6f 100644 --- a/src/mod/endpoints/mod_skypiax/skypiax_protocol.c +++ b/src/mod/endpoints/mod_skypiax/skypiax_protocol.c @@ -25,7 +25,6 @@ XErrorHandler old_handler = 0; int xerror = 0; #endif /* WIN32 */ /*************************************/ - int skypiax_signaling_read(private_t * tech_pvt) { char read_from_pipe[4096]; @@ -52,7 +51,9 @@ int skypiax_signaling_read(private_t * tech_pvt) if (read_from_pipe[i] == '\0') { - DEBUGA_SKYPE("READING: |||%s||| \n", SKYPIAX_P_LOG, message); + if (!strstr(message, "DURATION")) { + DEBUGA_SKYPE("READING: |||%s||| \n", SKYPIAX_P_LOG, message); + } if (!strcasecmp(message, "ERROR 68")) { DEBUGA_SKYPE @@ -86,16 +87,21 @@ int skypiax_signaling_read(private_t * tech_pvt) WARNINGA("Skype MSG without spaces: %s\n", SKYPIAX_P_LOG, message); } if (!strcasecmp(message, "ERROR")) { - DEBUGA_SKYPE("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'; - - if (tech_pvt->interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) { - tech_pvt->interface_state = SKYPIAX_STATE_DOWN; - return CALLFLOW_INCOMING_HANGUP; + if (!strncasecmp(message, "ERROR 592 ALTER CALL", 19)) { + ERRORA("Skype got ERROR about TRANSFERRING, no problem: |||%s|||\n", + SKYPIAX_P_LOG, message); } else { - tech_pvt->interface_state = SKYPIAX_STATE_DOWN; + DEBUGA_SKYPE("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'; + + 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 (!strcasecmp(message, "CURRENTUSERHANDLE")) { @@ -160,27 +166,36 @@ int skypiax_signaling_read(private_t * tech_pvt) skypiax_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"); + //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")) { - skypiax_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 (!strlen(tech_pvt->skype_call_id)) { + /* we are NOT inside an active call */ + DEBUGA_SKYPE("Call %s TRY ANSWER\n", SKYPIAX_P_LOG, id); + skypiax_answer(tech_pvt, id, value); + } else { + /* we are inside an active call */ + if (!strcasecmp(tech_pvt->skype_call_id, id)) { + /* this is the call in which we are calling out */ + DEBUGA_SKYPE("Call %s NOTHING\n", SKYPIAX_P_LOG, id); + } else { + usleep(400000); //0.4 seconds + DEBUGA_SKYPE("Call %s TRY TRANSFER\n", SKYPIAX_P_LOG, id); + skypiax_transfer(tech_pvt, id, value); + } + } } 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); + //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); + //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; } @@ -211,71 +226,27 @@ int skypiax_signaling_read(private_t * tech_pvt) 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 */ + if (!strlen(tech_pvt->skype_call_id)) { + /* we are NOT inside an active call */ + sprintf(msg_to_skype, "GET CALL %s PARTNER_HANDLE", id); + skypiax_signaling_write(tech_pvt, msg_to_skype); + skypiax_sleep(10000); + } else { + /* we are inside an active call */ + if (!strcasecmp(tech_pvt->skype_call_id, id)) { + /* this is the call in which we are calling out */ tech_pvt->skype_callflow = CALLFLOW_STATUS_RINGING; - tech_pvt->interface_state = SKYPIAX_STATE_RING; - /* no owner, no active call, let's answer */ - skypiax_signaling_write(tech_pvt, "SET AGC OFF"); - skypiax_sleep(10000); - skypiax_signaling_write(tech_pvt, "SET AEC OFF"); - skypiax_sleep(10000); - sprintf(msg_to_skype, "GET CALL %s PARTNER_DISPNAME", id); - skypiax_signaling_write(tech_pvt, msg_to_skype); - skypiax_sleep(10000); + tech_pvt->interface_state = SKYPIAX_STATE_RINGING; + skypiax_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); + remote_party_is_ringing(tech_pvt); + } else { sprintf(msg_to_skype, "GET CALL %s PARTNER_HANDLE", id); skypiax_signaling_write(tech_pvt, msg_to_skype); skypiax_sleep(10000); - sprintf(msg_to_skype, "ALTER CALL %s ANSWER", id); - skypiax_signaling_write(tech_pvt, msg_to_skype); - DEBUGA_SKYPE("We answered a Skype RING on skype_call %s\n", SKYPIAX_P_LOG, - id); - skypiax_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 try to transfer */ - /************************** TODO - Checking here if it is possible to transfer this call to Test2 - -> GET CALL 288 CAN_TRANSFER Test2 - <- CALL 288 CAN_TRANSFER test2 TRUE - **********************************/ - - private_t *available_skypiax_interface; - - available_skypiax_interface = find_available_skypiax_interface(); - if (available_skypiax_interface) { - /* there is a skypiax interface idle, let's transfer the call to it */ - DEBUGA_SKYPE - ("Let's transfer the skype_call %s to %s interface (with skype_user: %s), because we are already in a skypiax call(%s)\n", - SKYPIAX_P_LOG, tech_pvt->skype_call_id, - available_skypiax_interface->name, - available_skypiax_interface->skype_user, id); - sprintf(msg_to_skype, "ALTER CALL %s TRANSFER %s", id, - available_skypiax_interface->skype_user); - } else { - /* no skypiax interfaces idle, let's refuse the call */ - DEBUGA_SKYPE - ("Let's refuse the skype_call %s, because we are already in a skypiax call(%s) and no other skypiax interfaces are available\n", - SKYPIAX_P_LOG, tech_pvt->skype_call_id, id); - sprintf(msg_to_skype, "ALTER CALL %s END HANGUP", id); - } - skypiax_signaling_write(tech_pvt, msg_to_skype); - skypiax_sleep(10000); - DEBUGA_SKYPE - ("We (%s) have NOT answered a Skype RING on skype_call %s, because we are already in a skypiax call\n", - SKYPIAX_P_LOG, tech_pvt->skype_call_id, id); } - } else { - /* we are calling out */ - tech_pvt->skype_callflow = CALLFLOW_STATUS_RINGING; - tech_pvt->interface_state = SKYPIAX_STATE_RINGING; - skypiax_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); - remote_party_is_ringing(tech_pvt); } } else if (!strcasecmp(value, "EARLYMEDIA")) { char msg_to_skype[1024]; @@ -296,8 +267,10 @@ int skypiax_signaling_read(private_t * tech_pvt) } 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); + //DEBUGA_SKYPE("skype_call %s now is DOWN\n", SKYPIAX_P_LOG, id); + //usleep(150000);//150msec, let's give the TCP sockets time to timeout if (!strcasecmp(tech_pvt->skype_call_id, id)) { + tech_pvt->skype_callflow = CALLFLOW_STATUS_FINISHED; DEBUGA_SKYPE("skype_call %s is MY call, now I'm going DOWN\n", SKYPIAX_P_LOG, id); tech_pvt->skype_call_id[0] = '\0'; @@ -365,50 +338,50 @@ int skypiax_signaling_read(private_t * tech_pvt) skypiax_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]; + } else if (!strcasecmp(value, "INPROGRESS")) { + char msg_to_skype[1024]; - if (tech_pvt->skype_callflow != CALLFLOW_STATUS_REMOTEHOLD) { - if (!strlen(tech_pvt->session_uuid_str) || !strlen(tech_pvt->skype_call_id) - || !strcasecmp(tech_pvt->skype_call_id, id)) { - skypiax_strncpy(tech_pvt->skype_call_id, id, - sizeof(tech_pvt->skype_call_id) - 1); - DEBUGA_SKYPE("skype_call: %s is now active\n", SKYPIAX_P_LOG, id); + if (tech_pvt->skype_callflow != CALLFLOW_STATUS_REMOTEHOLD) { + if (!strlen(tech_pvt->session_uuid_str) || !strlen(tech_pvt->skype_call_id) + || !strcasecmp(tech_pvt->skype_call_id, id)) { + skypiax_strncpy(tech_pvt->skype_call_id, id, + sizeof(tech_pvt->skype_call_id) - 1); + DEBUGA_SKYPE("skype_call: %s is now active\n", SKYPIAX_P_LOG, id); - if (tech_pvt->skype_callflow != CALLFLOW_STATUS_EARLYMEDIA) { - tech_pvt->skype_callflow = CALLFLOW_STATUS_INPROGRESS; - tech_pvt->interface_state = SKYPIAX_STATE_UP; - start_audio_threads(tech_pvt); - skypiax_sleep(1000); //FIXME - sprintf(msg_to_skype, "ALTER CALL %s SET_INPUT PORT=\"%d\"", id, - tech_pvt->tcp_cli_port); - skypiax_signaling_write(tech_pvt, msg_to_skype); - skypiax_sleep(1000); //FIXME - sprintf(msg_to_skype, "#output ALTER CALL %s SET_OUTPUT PORT=\"%d\"", id, - tech_pvt->tcp_srv_port); - skypiax_signaling_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 { - DEBUGA_SKYPE("I'm on %s, skype_call %s is NOT MY call, ignoring\n", - SKYPIAX_P_LOG, tech_pvt->skype_call_id, id); - } - } else { - tech_pvt->skype_callflow = CALLFLOW_STATUS_INPROGRESS; - WARNINGA("Back from REMOTEHOLD!\n", SKYPIAX_P_LOG); - } + if (tech_pvt->skype_callflow != CALLFLOW_STATUS_EARLYMEDIA) { + tech_pvt->skype_callflow = CALLFLOW_STATUS_INPROGRESS; + tech_pvt->interface_state = SKYPIAX_STATE_UP; + start_audio_threads(tech_pvt); + skypiax_sleep(1000); //FIXME + sprintf(msg_to_skype, "ALTER CALL %s SET_INPUT PORT=\"%d\"", id, + tech_pvt->tcp_cli_port); + skypiax_signaling_write(tech_pvt, msg_to_skype); + skypiax_sleep(1000); //FIXME + sprintf(msg_to_skype, "#output ALTER CALL %s SET_OUTPUT PORT=\"%d\"", + id, tech_pvt->tcp_srv_port); + skypiax_signaling_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 { + DEBUGA_SKYPE("I'm on %s, skype_call %s is NOT MY call, ignoring\n", + SKYPIAX_P_LOG, tech_pvt->skype_call_id, id); + } + } else { + tech_pvt->skype_callflow = CALLFLOW_STATUS_INPROGRESS; + WARNINGA("Back from REMOTEHOLD!\n", SKYPIAX_P_LOG); + } - } else if (!strcasecmp(value, "REMOTEHOLD")) { - tech_pvt->skype_callflow = CALLFLOW_STATUS_REMOTEHOLD; - WARNINGA("skype_call: %s is now REMOTEHOLD\n", SKYPIAX_P_LOG, id); - } else { + } else if (!strcasecmp(value, "REMOTEHOLD")) { + tech_pvt->skype_callflow = CALLFLOW_STATUS_REMOTEHOLD; + WARNINGA("skype_call: %s is now REMOTEHOLD\n", SKYPIAX_P_LOG, id); + } else { WARNINGA("skype_call: %s, STATUS: %s is not recognized\n", SKYPIAX_P_LOG, id, value); } @@ -456,7 +429,7 @@ void *skypiax_do_tcp_srv_thread_func(void *obj) short srv_out[SAMPLES_PER_FRAME / 2]; struct sockaddr_in my_addr; struct sockaddr_in remote_addr; - int exit = 0; + //int exit = 0; unsigned int kill_cli_size; short kill_cli_buff[SAMPLES_PER_FRAME]; short totalbuf[SAMPLES_PER_FRAME]; @@ -480,115 +453,148 @@ void *skypiax_do_tcp_srv_thread_func(void *obj) listen(s, 6); sin_size = sizeof(remote_addr); - while ((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); + + /****************************/ + 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) 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)) { + FD_ZERO(&fsgio); + togio.tv_usec = 20000; //20msec + togio.tv_sec = 0; + fdselectgio = s; + FD_SET(fdselectgio, &fsgio); - unsigned int fdselect; - int rt; - fd_set fs; - struct timeval to; + rtgio = select(fdselectgio + 1, &fsgio, NULL, NULL, &togio); - if (!running) + if (rtgio) { + + /****************************/ + + while ((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); + if (!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) + break; + //exit = 1; + + fdselect = fd; + FD_ZERO(&fs); + FD_SET(fdselect, &fs); + //to.tv_usec = 2000000; //2000 msec + to.tv_usec = 60000; //60 msec + to.tv_sec = 0; + + 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, 320, 0); //seems that Skype only sends 320 bytes at time + } else { + len = 0; + } + + if (len == 320) { + unsigned int howmany; + + if (samplerate_skypiax == 8000) { + /* we're downsampling from 16khz to 8khz, srv_out will contain each other sample from srv_in */ + a = 0; + for (i = 0; i < 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, (int) (SAMPLES_PER_FRAME * sizeof(short))); + } + /* done with the stored half frame */ + tech_pvt->audiobuf_is_loaded = 0; + } + + } else if (len == 0) { + skypiax_sleep(1000); + } else { + ERRORA("len=%d, expected 320\n", SKYPIAX_P_LOG, len); + } + + } 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; - 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) { - - if (tech_pvt->skype_callflow != CALLFLOW_STATUS_REMOTEHOLD) { - len = recv(fd, (char *) srv_in, 320, 0); //seems that Skype only sends 320 bytes at time - } else { - len = 0; - } - - if (len == 320) { - unsigned int howmany; - - if (samplerate_skypiax == 8000) { - /* we're downsampling from 16khz to 8khz, srv_out will contain each other sample from srv_in */ - a = 0; - for (i = 0; i < 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, - (int) (SAMPLES_PER_FRAME * sizeof(short))); - } - /* done with the stored half frame */ - tech_pvt->audiobuf_is_loaded = 0; - } - - } else if (len == 0) { - skypiax_sleep(1000); - } else { - ERRORA("len=%d, expected 320\n", SKYPIAX_P_LOG, len); - } - - } 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) EXITING\n", SKYPIAX_P_LOG); @@ -635,110 +641,140 @@ void *skypiax_do_tcp_cli_thread_func(void *obj) listen(s, 6); sin_size = sizeof(remote_addr); - while ((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); + + /****************************/ + 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) 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; + FD_ZERO(&fsgio); + togio.tv_usec = 20000; //20msec + togio.tv_sec = 0; + fdselectgio = s; + FD_SET(fdselectgio, &fsgio); - if (!running) - break; - FD_ZERO(&fs); - to.tv_usec = 60000; //60msec - to.tv_sec = 0; + rtgio = select(fdselectgio + 1, &fsgio, NULL, NULL, &togio); + + if (rtgio) { + + /****************************/ + + while ((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); + if (!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) + break; + FD_ZERO(&fs); + to.tv_usec = 60000; //60msec + to.tv_sec = 0; #if defined(WIN32) && !defined(__CYGWIN__) /* on win32 we cannot select from the apr "pipe", so we select on socket writability */ - fdselect = fd; - FD_SET(fdselect, &fs); + fdselect = fd; + FD_SET(fdselect, &fs); - rt = select(fdselect + 1, NULL, &fs, NULL, &to); + rt = select(fdselect + 1, NULL, &fs, NULL, &to); #else /* on *unix and cygwin we select from the real pipe */ - fdselect = tech_pvt->audioskypepipe[0]; - FD_SET(fdselect, &fs); + fdselect = tech_pvt->audioskypepipe[0]; + FD_SET(fdselect, &fs); - rt = select(fdselect + 1, &fs, NULL, NULL, &to); + rt = select(fdselect + 1, &fs, NULL, NULL, &to); #endif - 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, - (int) (SAMPLES_PER_FRAME * sizeof(short))); - } - - if (got == SAMPLES_PER_FRAME * sizeof(short)) { - if (samplerate_skypiax == 8000) { - - /* we're upsampling from 8khz to 16khz, cli_out will contain two times each sample from cli_in */ - a = 0; - for (i = 0; i < got / sizeof(short); i++) { - cli_out[a] = cli_in[i]; - a++; - cli_out[a] = cli_in[i]; - a++; + 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, + (int) (SAMPLES_PER_FRAME * sizeof(short))); } - 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]; + + 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 to be sent to the remote party */ + if (tech_pvt->skype_callflow != CALLFLOW_STATUS_REMOTEHOLD) { + len = send(fd, (char *) cli_out, got, 0); + skypiax_sleep(5000); //5 msec + + 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, + (int) (SAMPLES_PER_FRAME * sizeof(short))); } } else { - ERRORA("SAMPLERATE_SKYPIAX can only be 8000 or 16000\n", SKYPIAX_P_LOG); + if (rt) + ERRORA("CLI rt=%d\n", SKYPIAX_P_LOG, rt); + memset(cli_out, 0, sizeof(cli_out)); + if (tech_pvt->skype_callflow != CALLFLOW_STATUS_REMOTEHOLD) { + len = send(fd, (char *) cli_out, sizeof(cli_out), 0); + len = send(fd, (char *) cli_out, sizeof(cli_out) / 2, 0); + //WARNINGA("sent %d of zeros to keep the Skype client socket busy\n", SKYPIAX_P_LOG, sizeof(cli_out) + sizeof(cli_out)/2); + } else { + /* + XXX do nothing + */ + //WARNINGA("we don't send it\n", SKYPIAX_P_LOG); + } + skypiax_sleep(1000); } - /* 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, (char *) cli_out, got, 0); - skypiax_sleep(5000); //5 msec - - 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, - (int) (SAMPLES_PER_FRAME * sizeof(short))); } - } else { - if (rt) - ERRORA("CLI rt=%d\n", SKYPIAX_P_LOG, rt); - memset(cli_out, 0, sizeof(cli_out)); - if (tech_pvt->skype_callflow != CALLFLOW_STATUS_REMOTEHOLD) { - len = send(fd, (char *) cli_out, sizeof(cli_out), 0); - len = send(fd, (char *) cli_out, sizeof(cli_out) / 2, 0); - //WARNINGA("sent %d of zeros to keep the Skype client socket busy\n", SKYPIAX_P_LOG, sizeof(cli_out) + sizeof(cli_out)/2); - } else { - /* - XXX do nothing - */ - //WARNINGA("we don't send it\n", SKYPIAX_P_LOG); - } - skypiax_sleep(1000); + DEBUGA_SKYPE("Skype outbound audio GONE\n", SKYPIAX_P_LOG); + skypiax_close_socket(fd); + break; } - } - DEBUGA_SKYPE("Skype outbound audio GONE\n", SKYPIAX_P_LOG); - skypiax_close_socket(fd); - break; } DEBUGA_SKYPE("outbound audio server (I am it) EXITING\n", SKYPIAX_P_LOG); @@ -783,10 +819,10 @@ int skypiax_call(private_t * tech_pvt, char *rdest, int timeout) skypiax_sleep(5000); DEBUGA_SKYPE("Calling Skype, rdest is: %s\n", SKYPIAX_P_LOG, rdest); - skypiax_signaling_write(tech_pvt, "SET AGC OFF"); - skypiax_sleep(10000); - skypiax_signaling_write(tech_pvt, "SET AEC OFF"); - skypiax_sleep(10000); + //skypiax_signaling_write(tech_pvt, "SET AGC OFF"); + //skypiax_sleep(10000); + //skypiax_signaling_write(tech_pvt, "SET AEC OFF"); + //skypiax_sleep(10000); sprintf(msg_to_skype, "CALL %s", rdest); if (skypiax_signaling_write(tech_pvt, msg_to_skype) < 0) { @@ -1022,8 +1058,8 @@ LRESULT APIENTRY skypiax_present(HWND hWindow, UINT uiMessage, WPARAM uiParam, #if 0 if (!tech_pvt->SkypiaxHandles.currentuserhandle) { SendMessage(HWND_BROADCAST, - tech_pvt-> - SkypiaxHandles.win32_uiGlobal_MsgID_SkypeControlAPIDiscover, + tech_pvt->SkypiaxHandles. + win32_uiGlobal_MsgID_SkypeControlAPIDiscover, (WPARAM) tech_pvt->SkypiaxHandles.win32_hInit_MainWindowHandle, 0); } @@ -1041,8 +1077,8 @@ LRESULT APIENTRY skypiax_present(HWND hWindow, UINT uiMessage, WPARAM uiParam, #if 0 if (!tech_pvt->SkypiaxHandles.currentuserhandle) { SendMessage(HWND_BROADCAST, - tech_pvt-> - SkypiaxHandles.win32_uiGlobal_MsgID_SkypeControlAPIDiscover, + tech_pvt->SkypiaxHandles. + win32_uiGlobal_MsgID_SkypeControlAPIDiscover, (WPARAM) tech_pvt->SkypiaxHandles.win32_hInit_MainWindowHandle, 0); } @@ -1155,7 +1191,7 @@ void *skypiax_do_skypeapi_thread_func(void *obj) tech_pvt->SkypiaxHandles.win32_uiGlobal_MsgID_SkypeControlAPIDiscover = RegisterWindowMessage("SkypeControlAPIDiscover"); - skypiax_sleep(200000); //0,2 sec + skypiax_sleep(200000); //0,2 sec if (tech_pvt->SkypiaxHandles.win32_uiGlobal_MsgID_SkypeControlAPIAttach != 0 && tech_pvt->SkypiaxHandles.win32_uiGlobal_MsgID_SkypeControlAPIDiscover != 0) { @@ -1410,7 +1446,7 @@ void *skypiax_do_skypeapi_thread_func(void *obj) char buffer[17000]; char *b; int i; - int continue_is_broken=0; + int continue_is_broken = 0; Atom atom_begin = XInternAtom(disp, "SKYPECONTROLAPI_MESSAGE_BEGIN", False); Atom atom_continue = XInternAtom(disp, "SKYPECONTROLAPI_MESSAGE", False); @@ -1431,43 +1467,47 @@ void *skypiax_do_skypeapi_thread_func(void *obj) buf[i] = '\0'; - DEBUGA_SKYPE ("BUF=|||%s|||\n", SKYPIAX_P_LOG, buf); + //DEBUGA_SKYPE ("BUF=|||%s|||\n", SKYPIAX_P_LOG, buf); - if(an_event.xclient.message_type == atom_begin){ + if (an_event.xclient.message_type == atom_begin) { - if(strlen(buffer)){ - unsigned int howmany; - howmany = strlen(b) + 1; - howmany = write(SkypiaxHandles->fdesc[1], b, howmany); - DEBUGA_SKYPE ("RECEIVED2=|||%s|||\n", SKYPIAX_P_LOG, buffer); - memset(buffer, '\0', 17000); - } - } - if(an_event.xclient.message_type == atom_continue){ + if (strlen(buffer)) { + unsigned int howmany; + howmany = strlen(b) + 1; + howmany = write(SkypiaxHandles->fdesc[1], b, howmany); + DEBUGA_SKYPE("RECEIVED2=|||%s|||\n", SKYPIAX_P_LOG, buffer); + memset(buffer, '\0', 17000); + } + } + if (an_event.xclient.message_type == atom_continue) { + + if (!strlen(buffer)) { + DEBUGA_SKYPE + ("Got a 'continue' XAtom without a previous 'begin'. It's value (between vertical bars) is=|||%s|||\n", + SKYPIAX_P_LOG, buf); + continue_is_broken = 1; + if (!strncmp(buf, "ognised identity", 15)) { + WARNINGA + ("Got a 'continue' XAtom without a previous 'begin'. It's value (between vertical bars) is=|||%s|||. Let's introduce a 1 second delay.\n", + SKYPIAX_P_LOG, buf); + skypiax_sleep(1000000); //1 sec + } + break; + } + } - if(!strlen(buffer)){ - DEBUGA_SKYPE("Got a 'continue' XAtom without a previous 'begin'. It's value (between vertical bars) is=|||%s|||\n", SKYPIAX_P_LOG, buf); - continue_is_broken=1; - if(!strncmp(buf, "ognised identity", 15)) { - WARNINGA("Got a 'continue' XAtom without a previous 'begin'. It's value (between vertical bars) is=|||%s|||. Let's introduce a 1 second delay.\n", SKYPIAX_P_LOG, buf); - skypiax_sleep(1000000); //1 sec - } - break; - } - } - strcat(buffer, buf); - if (i < 20 || continue_is_broken) { /* last fragment */ + if (i < 20 || continue_is_broken) { /* last fragment */ unsigned int howmany; howmany = strlen(b) + 1; howmany = write(SkypiaxHandles->fdesc[1], b, howmany); - DEBUGA_SKYPE ("RECEIVED=|||%s|||\n", SKYPIAX_P_LOG, buffer); + //DEBUGA_SKYPE ("RECEIVED=|||%s|||\n", SKYPIAX_P_LOG, buffer); memset(buffer, '\0', 17000); XFlush(disp); - continue_is_broken=0; + continue_is_broken = 0; } break;