skypiax: ubermegapatch, more stability, robustness, scalability. Memory leaks not yet investigated, we'll do next

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@14517 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Giovanni Maruzzelli 2009-08-14 17:12:09 +00:00
parent cbb2b89f0a
commit fd2bf49b7c
3 changed files with 318 additions and 96 deletions

View File

@ -148,6 +148,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id); static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id);
static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id); static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig); static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig);
static switch_status_t skypiax_tech_init(private_t * tech_pvt, switch_core_session_t *session);
static switch_status_t skypiax_codec(private_t * tech_pvt, int sample_rate, int codec_ms) static switch_status_t skypiax_codec(private_t * tech_pvt, int sample_rate, int codec_ms)
{ {
@ -173,30 +174,40 @@ static switch_status_t skypiax_codec(private_t * tech_pvt, int sample_rate, int
session = switch_core_session_locate(tech_pvt->session_uuid_str); session = switch_core_session_locate(tech_pvt->session_uuid_str);
switch_core_session_set_read_codec(session, &tech_pvt->read_codec); if(session){
switch_core_session_set_write_codec(session, &tech_pvt->write_codec); switch_core_session_set_read_codec(session, &tech_pvt->read_codec);
switch_core_session_set_write_codec(session, &tech_pvt->write_codec);
switch_core_session_rwunlock(session); switch_core_session_rwunlock(session);
} else {
ERRORA("no session\n", SKYPIAX_P_LOG);
return SWITCH_STATUS_FALSE;
}
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
void skypiax_tech_init(private_t * tech_pvt, switch_core_session_t *session) switch_status_t skypiax_tech_init(private_t * tech_pvt, switch_core_session_t *session)
{ {
switch_assert(tech_pvt != NULL);
switch_assert(session != NULL);
tech_pvt->read_frame.data = tech_pvt->databuf; tech_pvt->read_frame.data = tech_pvt->databuf;
tech_pvt->read_frame.buflen = sizeof(tech_pvt->databuf); tech_pvt->read_frame.buflen = sizeof(tech_pvt->databuf);
switch_mutex_init(&tech_pvt->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); switch_mutex_init(&tech_pvt->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
switch_core_session_set_private(session, tech_pvt); switch_core_session_set_private(session, tech_pvt);
switch_copy_string(tech_pvt->session_uuid_str, switch_core_session_get_uuid(session), sizeof(tech_pvt->session_uuid_str)); switch_copy_string(tech_pvt->session_uuid_str, switch_core_session_get_uuid(session), sizeof(tech_pvt->session_uuid_str));
if(!strlen(tech_pvt->session_uuid_str)){
ERRORA("no tech_pvt->session_uuid_str\n", SKYPIAX_P_LOG);
return SWITCH_STATUS_FALSE;
}
if (skypiax_codec(tech_pvt, SAMPLERATE_SKYPIAX, 20) != SWITCH_STATUS_SUCCESS) { if (skypiax_codec(tech_pvt, SAMPLERATE_SKYPIAX, 20) != SWITCH_STATUS_SUCCESS) {
ERRORA("skypiax_codec FAILED\n", SKYPIAX_P_LOG); ERRORA("skypiax_codec FAILED\n", SKYPIAX_P_LOG);
} else { return SWITCH_STATUS_FALSE;
DEBUGA_SKYPE("skypiax_codec SUCCESS\n", SKYPIAX_P_LOG);
} }
DEBUGA_SKYPE("skypiax_codec SUCCESS\n", SKYPIAX_P_LOG);
return SWITCH_STATUS_SUCCESS;
} }
/* BEGIN: Changes here */ /* BEGIN: Changes here */
@ -364,7 +375,8 @@ static switch_status_t channel_on_init(switch_core_session_t *session)
channel = switch_core_session_get_channel(session); channel = switch_core_session_get_channel(session);
switch_assert(channel != NULL); switch_assert(channel != NULL);
switch_set_flag_locked(tech_pvt, TFLAG_IO); DEBUGA_SKYPE("%s CHANNEL INIT\n", SKYPIAX_P_LOG, switch_channel_get_name(channel));
switch_set_flag(tech_pvt, TFLAG_IO);
/* Move channel's state machine to ROUTING. This means the call is trying /* Move channel's state machine to ROUTING. This means the call is trying
to get from the initial start where the call because, to the point to get from the initial start where the call because, to the point
@ -376,7 +388,6 @@ static switch_status_t channel_on_init(switch_core_session_t *session)
switch_mutex_unlock(globals.mutex); switch_mutex_unlock(globals.mutex);
DEBUGA_SKYPE("%s CHANNEL INIT\n", SKYPIAX_P_LOG, switch_channel_get_name(channel));
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
@ -394,6 +405,7 @@ static switch_status_t channel_on_destroy(switch_core_session_t *session)
if (switch_core_codec_ready(&tech_pvt->write_codec)) { if (switch_core_codec_ready(&tech_pvt->write_codec)) {
switch_core_codec_destroy(&tech_pvt->write_codec); switch_core_codec_destroy(&tech_pvt->write_codec);
} }
*tech_pvt->session_uuid_str = '\0';
switch_core_session_set_private(session, NULL); switch_core_session_set_private(session, NULL);
} }
@ -406,15 +418,16 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
private_t *tech_pvt = NULL; private_t *tech_pvt = NULL;
char msg_to_skype[256]; char msg_to_skype[256];
channel = switch_core_session_get_channel(session); channel = switch_core_session_get_channel(session);
switch_assert(channel != NULL); switch_assert(channel != NULL);
tech_pvt = switch_core_session_get_private(session); tech_pvt = switch_core_session_get_private(session);
switch_assert(tech_pvt != NULL); switch_assert(tech_pvt != NULL);
switch_clear_flag_locked(tech_pvt, TFLAG_IO); switch_clear_flag(tech_pvt, TFLAG_IO);
switch_clear_flag_locked(tech_pvt, TFLAG_VOICE); switch_clear_flag(tech_pvt, TFLAG_VOICE);
//switch_set_flag_locked(tech_pvt, TFLAG_HANGUP); //switch_set_flag(tech_pvt, TFLAG_HANGUP);
if (strlen(tech_pvt->skype_call_id)) { if (strlen(tech_pvt->skype_call_id)) {
//switch_thread_cond_signal(tech_pvt->cond); //switch_thread_cond_signal(tech_pvt->cond);
@ -423,7 +436,7 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
skypiax_signaling_write(tech_pvt, msg_to_skype); skypiax_signaling_write(tech_pvt, msg_to_skype);
} }
//memset(tech_pvt->session_uuid_str, '\0', sizeof(tech_pvt->session_uuid_str)); //memset(tech_pvt->session_uuid_str, '\0', sizeof(tech_pvt->session_uuid_str));
*tech_pvt->session_uuid_str = '\0'; //*tech_pvt->session_uuid_str = '\0';
DEBUGA_SKYPE("%s CHANNEL HANGUP\n", SKYPIAX_P_LOG, switch_channel_get_name(channel)); DEBUGA_SKYPE("%s CHANNEL HANGUP\n", SKYPIAX_P_LOG, switch_channel_get_name(channel));
switch_mutex_lock(globals.mutex); switch_mutex_lock(globals.mutex);
globals.calls--; globals.calls--;
@ -482,13 +495,18 @@ static switch_status_t channel_kill_channel(switch_core_session_t *session, int
switch (sig) { switch (sig) {
case SWITCH_SIG_KILL: case SWITCH_SIG_KILL:
DEBUGA_SKYPE("%s CHANNEL got SWITCH_SIG_KILL\n", SKYPIAX_P_LOG, switch_channel_get_name(channel)); DEBUGA_SKYPE("%s CHANNEL got SWITCH_SIG_KILL\n", SKYPIAX_P_LOG, switch_channel_get_name(channel));
switch_clear_flag_locked(tech_pvt, TFLAG_IO); //switch_mutex_lock(tech_pvt->flag_mutex);
switch_clear_flag_locked(tech_pvt, TFLAG_VOICE); switch_clear_flag(tech_pvt, TFLAG_IO);
switch_set_flag_locked(tech_pvt, TFLAG_HANGUP); switch_clear_flag(tech_pvt, TFLAG_VOICE);
switch_set_flag(tech_pvt, TFLAG_HANGUP);
//switch_mutex_unlock(tech_pvt->flag_mutex);
break; break;
case SWITCH_SIG_BREAK: case SWITCH_SIG_BREAK:
DEBUGA_SKYPE("%s CHANNEL got SWITCH_SIG_BREAK\n", SKYPIAX_P_LOG, switch_channel_get_name(channel)); DEBUGA_SKYPE("%s CHANNEL got SWITCH_SIG_BREAK\n", SKYPIAX_P_LOG, switch_channel_get_name(channel));
switch_set_flag_locked(tech_pvt, TFLAG_BREAK); //switch_set_flag(tech_pvt, TFLAG_BREAK);
//switch_mutex_lock(tech_pvt->flag_mutex);
switch_set_flag(tech_pvt, TFLAG_BREAK);
//switch_mutex_unlock(tech_pvt->flag_mutex);
break; break;
default: default:
break; break;
@ -536,7 +554,8 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
switch_assert(tech_pvt != NULL); switch_assert(tech_pvt != NULL);
if (!switch_channel_ready(channel) || !switch_test_flag(tech_pvt, TFLAG_IO)) { if (!switch_channel_ready(channel) || !switch_test_flag(tech_pvt, TFLAG_IO)) {
ERRORA("CIAPA \n", SKYPIAX_P_LOG); ERRORA("channel not ready \n", SKYPIAX_P_LOG);
//TODO: kill the bastard
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
} }
@ -548,7 +567,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
ERRORA("skypiax_audio_read ERROR\n", SKYPIAX_P_LOG); ERRORA("skypiax_audio_read ERROR\n", SKYPIAX_P_LOG);
} else { } else {
switch_set_flag_locked(tech_pvt, TFLAG_VOICE); switch_set_flag(tech_pvt, TFLAG_VOICE);
} }
while (switch_test_flag(tech_pvt, TFLAG_IO)) { while (switch_test_flag(tech_pvt, TFLAG_IO)) {
@ -564,7 +583,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
} }
if (switch_test_flag(tech_pvt, TFLAG_IO) && switch_test_flag(tech_pvt, TFLAG_VOICE)) { if (switch_test_flag(tech_pvt, TFLAG_IO) && switch_test_flag(tech_pvt, TFLAG_VOICE)) {
switch_clear_flag_locked(tech_pvt, TFLAG_VOICE); switch_clear_flag(tech_pvt, TFLAG_VOICE);
if (!tech_pvt->read_frame.datalen) { if (!tech_pvt->read_frame.datalen) {
DEBUGA_SKYPE("CHANNEL READ CONTINUE\n", SKYPIAX_P_LOG); DEBUGA_SKYPE("CHANNEL READ CONTINUE\n", SKYPIAX_P_LOG);
continue; continue;
@ -610,7 +629,8 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
switch_assert(tech_pvt != NULL); switch_assert(tech_pvt != NULL);
if (!switch_channel_ready(channel) || !switch_test_flag(tech_pvt, TFLAG_IO)) { if (!switch_channel_ready(channel) || !switch_test_flag(tech_pvt, TFLAG_IO)) {
ERRORA("CIAPA \n", SKYPIAX_P_LOG); ERRORA("channel not ready \n", SKYPIAX_P_LOG);
//TODO: kill the bastard
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
} }
#ifdef BIGENDIAN #ifdef BIGENDIAN
@ -721,9 +741,9 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
switch_caller_profile_t *outbound_profile, switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags) switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags)
{ {
if ((*new_session = switch_core_session_request(skypiax_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, pool)) != 0) {
private_t *tech_pvt = NULL; private_t *tech_pvt = NULL;
switch_channel_t *channel; if ((*new_session = switch_core_session_request(skypiax_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, pool)) != 0) {
switch_channel_t *channel = NULL;
switch_caller_profile_t *caller_profile; switch_caller_profile_t *caller_profile;
char *rdest; char *rdest;
int found = 0; int found = 0;
@ -741,16 +761,16 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
*slash = '\0'; *slash = '\0';
switch_mutex_lock(globals.mutex); switch_mutex_lock(globals.mutex);
if (strncmp("ANY", interface_name, strlen(interface_name)) == 0) { if (strncmp("ANY", interface_name, strlen(interface_name)) == 0 || strncmp("RR", interface_name, strlen(interface_name)) == 0) {
/* we've been asked for the "ANY" interface, let's find the first idle interface */ /* 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); //DEBUGA_SKYPE("Finding one available skype interface\n", SKYPIAX_P_LOG);
tech_pvt = find_available_skypiax_interface(NULL); //tech_pvt = find_available_skypiax_interface(NULL);
if (tech_pvt) //if (tech_pvt)
found = 1; //found = 1;
} else if (strncmp("RR", interface_name, strlen(interface_name)) == 0) { //} else if (strncmp("RR", interface_name, strlen(interface_name)) == 0) {
/* Find the first idle interface using Round Robin */ /* Find the first idle interface using Round Robin */
DEBUGA_SKYPE("Finding one available skype interface RR\n", SKYPIAX_P_LOG); DEBUGA_SKYPE("Finding one available skype interface RR\n", SKYPIAX_P_LOG);
tech_pvt = find_available_skypiax_interface_rr(); tech_pvt = find_available_skypiax_interface_rr(NULL);
if (tech_pvt) if (tech_pvt)
found = 1; found = 1;
} }
@ -765,7 +785,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
SKYPIAX_P_LOG, i, globals.SKYPIAX_INTERFACES[i].name, globals.SKYPIAX_INTERFACES[i].session_uuid_str); SKYPIAX_P_LOG, i, globals.SKYPIAX_INTERFACES[i].name, globals.SKYPIAX_INTERFACES[i].session_uuid_str);
switch_core_session_destroy(new_session); switch_core_session_destroy(new_session);
switch_mutex_unlock(globals.mutex); switch_mutex_unlock(globals.mutex);
return SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE; return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
} }
DEBUGA_SKYPE("globals.SKYPIAX_INTERFACES[%d].name=|||%s|||?\n", SKYPIAX_P_LOG, i, globals.SKYPIAX_INTERFACES[i].name); DEBUGA_SKYPE("globals.SKYPIAX_INTERFACES[%d].name=|||%s|||?\n", SKYPIAX_P_LOG, i, globals.SKYPIAX_INTERFACES[i].name);
@ -783,14 +803,26 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
} }
if (!found) { if (!found) {
ERRORA("Doh! no matching interface for |||%s|||?\n", SKYPIAX_P_LOG, interface_name); DEBUGA_SKYPE("Doh! no available interface for |||%s|||?\n", SKYPIAX_P_LOG, interface_name);
switch_core_session_destroy(new_session);
switch_mutex_unlock(globals.mutex);
//return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
return SWITCH_CAUSE_NORMAL_CIRCUIT_CONGESTION;
}
channel = switch_core_session_get_channel(*new_session);
if(!channel){
ERRORA("Doh! no channel?\n", SKYPIAX_P_LOG);
switch_core_session_destroy(new_session);
switch_mutex_unlock(globals.mutex);
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
}
if( skypiax_tech_init(tech_pvt, *new_session) != SWITCH_STATUS_SUCCESS){
ERRORA("Doh! no tech_init?\n", SKYPIAX_P_LOG);
switch_core_session_destroy(new_session); switch_core_session_destroy(new_session);
switch_mutex_unlock(globals.mutex); switch_mutex_unlock(globals.mutex);
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
} }
channel = switch_core_session_get_channel(*new_session);
skypiax_tech_init(tech_pvt, *new_session);
if (outbound_profile) { if (outbound_profile) {
@ -812,19 +844,21 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
rdest = strchr(caller_profile->destination_number, '/'); rdest = strchr(caller_profile->destination_number, '/');
*rdest++ = '\0'; *rdest++ = '\0';
skypiax_call(tech_pvt, rdest, 30); //skypiax_call(tech_pvt, rdest, 30);
switch_copy_string(tech_pvt->session_uuid_str, switch_core_session_get_uuid(*new_session), sizeof(tech_pvt->session_uuid_str)); switch_copy_string(tech_pvt->session_uuid_str, switch_core_session_get_uuid(*new_session), sizeof(tech_pvt->session_uuid_str));
caller_profile = tech_pvt->caller_profile; caller_profile = tech_pvt->caller_profile;
caller_profile->destination_number = rdest; caller_profile->destination_number = rdest;
switch_channel_set_flag(channel, CF_OUTBOUND); switch_channel_set_flag(channel, CF_OUTBOUND);
switch_set_flag_locked(tech_pvt, TFLAG_OUTBOUND); switch_set_flag(tech_pvt, TFLAG_OUTBOUND);
switch_channel_set_state(channel, CS_INIT); switch_channel_set_state(channel, CS_INIT);
skypiax_call(tech_pvt, rdest, 30);
switch_mutex_unlock(globals.mutex); switch_mutex_unlock(globals.mutex);
return SWITCH_CAUSE_SUCCESS; return SWITCH_CAUSE_SUCCESS;
} }
ERRORA("Doh! no new_session\n", SKYPIAX_P_LOG);
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
} }
@ -849,29 +883,35 @@ static void *SWITCH_THREAD_FUNC skypiax_signaling_thread_func(switch_thread_t *
res = skypiax_signaling_read(tech_pvt); res = skypiax_signaling_read(tech_pvt);
if (res == CALLFLOW_INCOMING_HANGUP) { if (res == CALLFLOW_INCOMING_HANGUP) {
switch_core_session_t *session = NULL; switch_core_session_t *session = NULL;
//private_t *tech_pvt = NULL;
switch_channel_t *channel = NULL; switch_channel_t *channel = NULL;
//private_t *tech_pvt = NULL;
DEBUGA_SKYPE("skype call ended\n", SKYPIAX_P_LOG); DEBUGA_SKYPE("skype call ended\n", SKYPIAX_P_LOG);
if (tech_pvt) { if (tech_pvt) {
session = switch_core_session_locate(tech_pvt->session_uuid_str); session = switch_core_session_locate(tech_pvt->session_uuid_str);
if (session) { if (session) {
channel = switch_core_session_get_channel(session); channel = switch_core_session_get_channel(session);
if (channel) { if (channel) {
switch_channel_state_t state = switch_channel_get_state(channel);
if(state < CS_EXECUTE){
usleep(10000);//10 msec, let the state evolve from CS_NEW
}
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
switch_core_session_rwunlock(session);
} else { } else {
ERRORA("no channel?\n", SKYPIAX_P_LOG); ERRORA("no channel?\n", SKYPIAX_P_LOG);
switch_core_session_rwunlock(session);
} }
switch_core_session_rwunlock(session);
} else { } else {
DEBUGA_SKYPE("no session\n", SKYPIAX_P_LOG); DEBUGA_SKYPE("no session\n", SKYPIAX_P_LOG);
} }
tech_pvt->interface_state = SKYPIAX_STATE_DOWN; tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
*tech_pvt->session_uuid_str = '\0'; *tech_pvt->session_uuid_str = '\0';
//memset(tech_pvt->session_uuid_str, '\0', sizeof(tech_pvt->session_uuid_str)); *tech_pvt->skype_call_id = '\0';
//ERRORA("LET'S WAIT\n", SKYPIAX_P_LOG);
usleep(300000); //0.3 sec
//ERRORA("WAIT'S OVER\n", SKYPIAX_P_LOG);
tech_pvt->skype_callflow = CALLFLOW_STATUS_FINISHED;
} else { } else {
ERRORA("no tech_pvt?\n", SKYPIAX_P_LOG); ERRORA("no tech_pvt?\n", SKYPIAX_P_LOG);
} }
@ -1389,16 +1429,29 @@ int start_audio_threads(private_t * tech_pvt)
switch_threadattr_create(&thd_attr, skypiax_module_pool); switch_threadattr_create(&thd_attr, skypiax_module_pool);
switch_threadattr_detach_set(thd_attr, 1); switch_threadattr_detach_set(thd_attr, 1);
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
switch_thread_create(&tech_pvt->tcp_srv_thread, thd_attr, skypiax_do_tcp_srv_thread, tech_pvt, skypiax_module_pool); if (switch_thread_create(&tech_pvt->tcp_srv_thread, thd_attr, skypiax_do_tcp_srv_thread, tech_pvt, skypiax_module_pool) == SWITCH_STATUS_SUCCESS) {
DEBUGA_SKYPE("started tcp_srv_thread thread.\n", SKYPIAX_P_LOG); DEBUGA_SKYPE("started tcp_srv_thread thread.\n", SKYPIAX_P_LOG);
} else {
ERRORA("failed to start tcp_srv_thread thread.\n", SKYPIAX_P_LOG);
return -1;
}
switch_threadattr_create(&thd_attr, skypiax_module_pool); switch_threadattr_create(&thd_attr, skypiax_module_pool);
switch_threadattr_detach_set(thd_attr, 1); switch_threadattr_detach_set(thd_attr, 1);
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
switch_thread_create(&tech_pvt->tcp_cli_thread, thd_attr, skypiax_do_tcp_cli_thread, tech_pvt, skypiax_module_pool); if(switch_thread_create(&tech_pvt->tcp_cli_thread, thd_attr, skypiax_do_tcp_cli_thread, tech_pvt, skypiax_module_pool) == SWITCH_STATUS_SUCCESS) {
DEBUGA_SKYPE("started tcp_cli_thread thread.\n", SKYPIAX_P_LOG); DEBUGA_SKYPE("started tcp_cli_thread thread.\n", SKYPIAX_P_LOG);
}else{
ERRORA("failed to start tcp_cli_thread thread.\n", SKYPIAX_P_LOG);
return -1;
}
switch_sleep(100000); switch_sleep(100000);
if(tech_pvt->tcp_cli_thread == NULL || tech_pvt->tcp_srv_thread == NULL) {
ERRORA("tcp_cli_thread or tcp_srv_thread exited\n", SKYPIAX_P_LOG);
return -1;
}
return 0; return 0;
} }
@ -1410,7 +1463,16 @@ int new_inbound_channel(private_t * tech_pvt)
if ((session = switch_core_session_request(skypiax_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, NULL)) != 0) { if ((session = switch_core_session_request(skypiax_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, NULL)) != 0) {
switch_core_session_add_stream(session, NULL); switch_core_session_add_stream(session, NULL);
channel = switch_core_session_get_channel(session); channel = switch_core_session_get_channel(session);
skypiax_tech_init(tech_pvt, session); if(!channel){
ERRORA("Doh! no channel?\n", SKYPIAX_P_LOG);
switch_core_session_destroy(&session);
return 0;
}
if( skypiax_tech_init(tech_pvt, session) != SWITCH_STATUS_SUCCESS){
ERRORA("Doh! no tech_init?\n", SKYPIAX_P_LOG);
switch_core_session_destroy(&session);
return 0;
}
if ((tech_pvt->caller_profile = if ((tech_pvt->caller_profile =
switch_caller_profile_new(switch_core_session_get_pool(session), "skypiax", switch_caller_profile_new(switch_core_session_get_pool(session), "skypiax",
@ -1426,11 +1488,14 @@ int new_inbound_channel(private_t * tech_pvt)
if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) { if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) {
ERRORA("Error spawning thread\n", SKYPIAX_P_LOG); ERRORA("Error spawning thread\n", SKYPIAX_P_LOG);
switch_core_session_destroy(&session); switch_core_session_destroy(&session);
return 0;
} }
} }
switch_channel_mark_answered(channel); if(channel){
switch_channel_mark_answered(channel);
}
DEBUGA_SKYPE("Here\n", SKYPIAX_P_LOG); DEBUGA_SKYPE("new_inbound_channel\n", SKYPIAX_P_LOG);
return 0; return 0;
} }
@ -1457,7 +1522,6 @@ int remote_party_is_ringing(private_t * tech_pvt)
DEBUGA_SKYPE("skype_call: REMOTE PARTY RINGING\n", SKYPIAX_P_LOG); DEBUGA_SKYPE("skype_call: REMOTE PARTY RINGING\n", SKYPIAX_P_LOG);
} else { } else {
ERRORA("No channel???\n", SKYPIAX_P_LOG); ERRORA("No channel???\n", SKYPIAX_P_LOG);
goto done;
} }
switch_core_session_rwunlock(session); switch_core_session_rwunlock(session);
@ -1474,7 +1538,8 @@ int remote_party_is_early_media(private_t * tech_pvt)
if (!switch_strlen_zero(tech_pvt->session_uuid_str)) { if (!switch_strlen_zero(tech_pvt->session_uuid_str)) {
session = switch_core_session_locate(tech_pvt->session_uuid_str); session = switch_core_session_locate(tech_pvt->session_uuid_str);
} else { } else {
ERRORA("No session???\n", SKYPIAX_P_LOG); ERRORA("No session???\n\n\n", SKYPIAX_P_LOG);
//TODO: kill the bastard
goto done; goto done;
} }
if (session) { if (session) {
@ -1482,6 +1547,7 @@ int remote_party_is_early_media(private_t * tech_pvt)
switch_core_session_add_stream(session, NULL); switch_core_session_add_stream(session, NULL);
} else { } else {
ERRORA("No session???\n", SKYPIAX_P_LOG); ERRORA("No session???\n", SKYPIAX_P_LOG);
//TODO: kill the bastard
goto done; goto done;
} }
if (channel) { if (channel) {
@ -1489,7 +1555,7 @@ int remote_party_is_early_media(private_t * tech_pvt)
DEBUGA_SKYPE("skype_call: REMOTE PARTY EARLY MEDIA\n", SKYPIAX_P_LOG); DEBUGA_SKYPE("skype_call: REMOTE PARTY EARLY MEDIA\n", SKYPIAX_P_LOG);
} else { } else {
ERRORA("No channel???\n", SKYPIAX_P_LOG); ERRORA("No channel???\n", SKYPIAX_P_LOG);
goto done; //TODO: kill the bastard
} }
switch_core_session_rwunlock(session); switch_core_session_rwunlock(session);
@ -1512,7 +1578,7 @@ int outbound_channel_answered(private_t * tech_pvt)
if (session) { if (session) {
channel = switch_core_session_get_channel(session); channel = switch_core_session_get_channel(session);
} else { } else {
ERRORA("No session???\n", SKYPIAX_P_LOG); ERRORA("No channel???\n", SKYPIAX_P_LOG);
goto done; goto done;
} }
if (channel) { if (channel) {
@ -1520,17 +1586,17 @@ int outbound_channel_answered(private_t * tech_pvt)
//DEBUGA_SKYPE("skype_call: %s, answered\n", SKYPIAX_P_LOG, id); //DEBUGA_SKYPE("skype_call: %s, answered\n", SKYPIAX_P_LOG, id);
} else { } else {
ERRORA("No channel???\n", SKYPIAX_P_LOG); ERRORA("No channel???\n", SKYPIAX_P_LOG);
goto done;
} }
switch_core_session_rwunlock(session); switch_core_session_rwunlock(session);
done: done:
DEBUGA_SKYPE("HERE!\n", SKYPIAX_P_LOG); DEBUGA_SKYPE("outbound_channel_answered!\n", SKYPIAX_P_LOG);
return 0; return 0;
} }
#if 0
private_t *find_available_skypiax_interface(private_t * tech_pvt) private_t *find_available_skypiax_interface(private_t * tech_pvt)
{ {
private_t *tech_pvt2 = NULL; private_t *tech_pvt2 = NULL;
@ -1559,8 +1625,9 @@ private_t *find_available_skypiax_interface(private_t * tech_pvt)
else else
return NULL; return NULL;
} }
#endif
private_t *find_available_skypiax_interface_rr(void) private_t *find_available_skypiax_interface_rr(private_t * tech_pvt_calling)
{ {
private_t *tech_pvt = NULL; private_t *tech_pvt = NULL;
int i; int i;
@ -1585,12 +1652,14 @@ private_t *find_available_skypiax_interface_rr(void)
tech_pvt = &globals.SKYPIAX_INTERFACES[interface_id]; tech_pvt = &globals.SKYPIAX_INTERFACES[interface_id];
skype_state = tech_pvt->interface_state; skype_state = tech_pvt->interface_state;
DEBUGA_SKYPE("skype interface: %d, name: %s, state: %d\n", SKYPIAX_P_LOG, interface_id, //DEBUGA_SKYPE("skype interface: %d, name: %s, state: %d\n", SKYPIAX_P_LOG, interface_id, globals.SKYPIAX_INTERFACES[interface_id].name, skype_state);
globals.SKYPIAX_INTERFACES[interface_id].name, skype_state); if ((tech_pvt_calling ? strcmp(tech_pvt->skype_user, tech_pvt_calling->skype_user) : 1) && (SKYPIAX_STATE_DOWN == skype_state || 0 == skype_state) && (tech_pvt->skype_callflow ==CALLFLOW_STATUS_FINISHED || 0 == tech_pvt->skype_callflow )) {
if (SKYPIAX_STATE_DOWN == skype_state || 0 == skype_state) { DEBUGA_SKYPE("returning as available skype interface name: %s, state: %d callflow: %d\n", SKYPIAX_P_LOG, tech_pvt->name, skype_state, tech_pvt->skype_callflow);
/*set to Dialing state to avoid other thread fint it, don't know if it is safe */ /*set to Dialing state to avoid other thread fint it, don't know if it is safe */
//XXX no, it's not safe //XXX no, it's not safe
//tech_pvt->interface_state = SKYPIAX_STATE_DIALING ; if(tech_pvt_calling == NULL){
tech_pvt->interface_state = SKYPIAX_STATE_SELECTED ;
}
switch_mutex_unlock(globals.mutex); switch_mutex_unlock(globals.mutex);
return tech_pvt; return tech_pvt;
@ -1796,6 +1865,8 @@ int skypiax_answer(private_t * tech_pvt, char *id, char *value)
if (found) { if (found) {
//tech_pvt->callid_number[0]='\0'; //tech_pvt->callid_number[0]='\0';
//sprintf(msg_to_skype, "ALTER CALL %s END HANGUP", id);
//skypiax_signaling_write(tech_pvt, msg_to_skype);
switch_mutex_unlock(globals.mutex); switch_mutex_unlock(globals.mutex);
return 0; return 0;
} }
@ -1822,7 +1893,9 @@ int skypiax_answer(private_t * tech_pvt, char *id, char *value)
} else if (!tech_pvt || !tech_pvt->skype_call_id) { } else if (!tech_pvt || !tech_pvt->skype_call_id) {
ERRORA("No Call ID?\n", SKYPIAX_P_LOG); ERRORA("No Call ID?\n", SKYPIAX_P_LOG);
} else { } else {
ERRORA("We're in a call now %s\n", SKYPIAX_P_LOG, tech_pvt->skype_call_id); DEBUGA_SKYPE("We're in a call now (%s), let's refuse this one (%s)\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);
} }
switch_mutex_unlock(globals.mutex); switch_mutex_unlock(globals.mutex);
@ -1858,6 +1931,8 @@ int skypiax_transfer(private_t * tech_pvt, char *id, char *value)
if (found) { if (found) {
//tech_pvt->callid_number[0]='\0'; //tech_pvt->callid_number[0]='\0';
//sprintf(msg_to_skype, "ALTER CALL %s END HANGUP", id);
//skypiax_signaling_write(tech_pvt, msg_to_skype);
switch_mutex_unlock(globals.mutex); switch_mutex_unlock(globals.mutex);
return 0; return 0;
} }
@ -1899,12 +1974,14 @@ int skypiax_transfer(private_t * tech_pvt, char *id, char *value)
if (found) { if (found) {
//tech_pvt->callid_number[0]='\0'; //tech_pvt->callid_number[0]='\0';
//sprintf(msg_to_skype, "ALTER CALL %s END HANGUP", id);
//skypiax_signaling_write(tech_pvt, msg_to_skype);
switch_mutex_unlock(globals.mutex); switch_mutex_unlock(globals.mutex);
return 0; return 0;
} }
DEBUGA_SKYPE("NOT FOUND\n", SKYPIAX_P_LOG); DEBUGA_SKYPE("NOT FOUND\n", SKYPIAX_P_LOG);
available_skypiax_interface = find_available_skypiax_interface(tech_pvt); available_skypiax_interface = find_available_skypiax_interface_rr(tech_pvt);
if (available_skypiax_interface) { if (available_skypiax_interface) {
/* there is a skypiax interface idle, let's transfer the call to it */ /* there is a skypiax interface idle, let's transfer the call to it */
@ -1922,14 +1999,15 @@ int skypiax_transfer(private_t * tech_pvt, char *id, char *value)
} else { } else {
/* no skypiax interfaces idle, do nothing */ /* no skypiax interfaces idle, do nothing */
DEBUGA_SKYPE 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", ("Not answering the skype_call %s, because we are already in a skypiax call(%s) and not transferring, because no other skypiax interfaces are available\n",
SKYPIAX_P_LOG, tech_pvt->skype_call_id, id); SKYPIAX_P_LOG, id, tech_pvt->skype_call_id);
//sprintf(msg_to_skype, "ALTER CALL %s END HANGUP", id); sprintf(msg_to_skype, "ALTER CALL %s END HANGUP", id);
skypiax_signaling_write(tech_pvt, msg_to_skype);
} }
switch_sleep(10000); switch_sleep(10000);
DEBUGA_SKYPE DEBUGA_SKYPE
("We (%s) have NOT answered a Skype RING on skype_call %s, because we are already in a skypiax call\n", ("We have NOT answered a Skype RING from skype_call %s, because we are already in a skypiax call (%s)\n",
SKYPIAX_P_LOG, tech_pvt->skype_call_id, id); SKYPIAX_P_LOG, id, tech_pvt->skype_call_id);
switch_mutex_unlock(globals.mutex); switch_mutex_unlock(globals.mutex);
} }

View File

@ -98,6 +98,8 @@ typedef enum {
#define SKYPIAX_STATE_UP 5 #define SKYPIAX_STATE_UP 5
#define SKYPIAX_STATE_RINGING 6 #define SKYPIAX_STATE_RINGING 6
#define SKYPIAX_STATE_PRERING 7 #define SKYPIAX_STATE_PRERING 7
#define SKYPIAX_STATE_ERROR_DOUBLE_CALL 8
#define SKYPIAX_STATE_SELECTED 9
/*********************************/ /*********************************/
/* call flow from the device */ /* call flow from the device */
#define CALLFLOW_CALL_IDLE SKYPIAX_STATE_DOWN #define CALLFLOW_CALL_IDLE SKYPIAX_STATE_DOWN
@ -244,7 +246,6 @@ struct private_object {
typedef struct private_object private_t; typedef struct private_object private_t;
void *SWITCH_THREAD_FUNC skypiax_api_thread_func(switch_thread_t * thread, void *obj); void *SWITCH_THREAD_FUNC skypiax_api_thread_func(switch_thread_t * thread, void *obj);
void skypiax_tech_init(private_t * tech_pvt, switch_core_session_t *session);
int skypiax_audio_read(private_t * tech_pvt); int skypiax_audio_read(private_t * tech_pvt);
int skypiax_audio_init(private_t * tech_pvt); int skypiax_audio_init(private_t * tech_pvt);
int skypiax_signaling_write(private_t * tech_pvt, char *msg_to_skype); int skypiax_signaling_write(private_t * tech_pvt, char *msg_to_skype);
@ -277,8 +278,9 @@ int skypiax_pipe_write(int pipe, short *buf, int howmany);
#endif /* WIN32 */ #endif /* WIN32 */
int skypiax_close_socket(unsigned int fd); int skypiax_close_socket(unsigned int fd);
private_t *find_available_skypiax_interface(private_t * tech_pvt); private_t *find_available_skypiax_interface(private_t * tech_pvt);
private_t *find_available_skypiax_interface_rr(void); private_t *find_available_skypiax_interface_rr(private_t * tech_pvt_calling);
int remote_party_is_ringing(private_t * tech_pvt); int remote_party_is_ringing(private_t * tech_pvt);
int remote_party_is_early_media(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_answer(private_t * tech_pvt, char *id, char *value);
int skypiax_transfer(private_t * tech_pvt, char *id, char *value); int skypiax_transfer(private_t * tech_pvt, char *id, char *value);
int skypiax_socket_create_and_bind(private_t * tech_pvt, int * which_port);

View File

@ -25,6 +25,47 @@ XErrorHandler old_handler = 0;
int xerror = 0; int xerror = 0;
#endif /* WIN32 */ #endif /* WIN32 */
/*************************************/ /*************************************/
int skypiax_socket_create_and_bind(private_t * tech_pvt, int * which_port)
{
int s=-1;
struct sockaddr_in my_addr;
int start_port = 6001;
memset(&my_addr, 0, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_addr.s_addr = htonl(0x7f000001); /* use the localhost */
if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
ERRORA("socket Error\n", SKYPIAX_P_LOG);
return -1;
}
if(*which_port != 0)
start_port = *which_port;
my_addr.sin_port = htons(start_port);
//tech_pvt->tcp_cli_port = start_port;
*which_port = start_port;
while (bind(s, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) < 0) {
DEBUGA_SKYPE("*which_port=%d, tech_pvt->tcp_cli_port=%d, tech_pvt->tcp_srv_port=%d\n", SKYPIAX_P_LOG, *which_port, tech_pvt->tcp_cli_port, tech_pvt->tcp_srv_port);
DEBUGA_SKYPE("EADDRINUSE=%d, bind errno=%d, error: %s\n", SKYPIAX_P_LOG, EADDRINUSE, errno, strerror(errno));
start_port++;
my_addr.sin_port = htons(start_port);
*which_port = start_port;
DEBUGA_SKYPE("*which_port=%d, tech_pvt->tcp_cli_port=%d, tech_pvt->tcp_srv_port=%d\n", SKYPIAX_P_LOG, *which_port, tech_pvt->tcp_cli_port, tech_pvt->tcp_srv_port);
if(start_port > 65000){
ERRORA("NO MORE PORTS! *which_port=%d, tech_pvt->tcp_cli_port=%d, tech_pvt->tcp_srv_port=%d\n", SKYPIAX_P_LOG, *which_port, tech_pvt->tcp_cli_port, tech_pvt->tcp_srv_port);
return -1;
}
//usleep(100);
}
DEBUGA_SKYPE("SUCCESS! *which_port=%d, tech_pvt->tcp_cli_port=%d, tech_pvt->tcp_srv_port=%d\n", SKYPIAX_P_LOG, *which_port, tech_pvt->tcp_cli_port, tech_pvt->tcp_srv_port);
return s;
}
int skypiax_signaling_read(private_t * tech_pvt) int skypiax_signaling_read(private_t * tech_pvt)
{ {
char read_from_pipe[4096]; char read_from_pipe[4096];
@ -49,9 +90,9 @@ int skypiax_signaling_read(private_t * tech_pvt)
if (read_from_pipe[i] == '\0') { if (read_from_pipe[i] == '\0') {
if (!strstr(message, "DURATION")) { //if (!strstr(message, "DURATION")) {
DEBUGA_SKYPE("READING: |||%s||| \n", SKYPIAX_P_LOG, message); DEBUGA_SKYPE("READING: |||%s||| \n", SKYPIAX_P_LOG, message);
} //}
if (!strcasecmp(message, "ERROR 68")) { if (!strcasecmp(message, "ERROR 68")) {
DEBUGA_SKYPE DEBUGA_SKYPE
@ -75,20 +116,48 @@ int skypiax_signaling_read(private_t * tech_pvt)
tech_pvt->interface_state = SKYPIAX_STATE_DOWN; tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
} }
} }
skypiax_strncpy(message_2, message, sizeof(message) - 1); /*
buf = message; if (!strncasecmp(message, "ERROR 96 CALL", 12) ) {
stringp = &buf; ERRORA("Skype got ERROR: |||%s|||, we are trying to use this interface to make or receive a call, but another call is half-active on this interface. We abort this attenpt and leave the previous one to continue.\n", SKYPIAX_P_LOG, message);
where = strsep(stringp, " "); tech_pvt->skype_callflow = CALLFLOW_STATUS_FINISHED;
if (!where) { DEBUGA_SKYPE("skype_call now is DOWN\n", SKYPIAX_P_LOG);
WARNINGA("Skype MSG without spaces: %s\n", SKYPIAX_P_LOG, message); tech_pvt->skype_call_id[0] = '\0';
}
if (!strcasecmp(message, "ERROR")) { if (tech_pvt->interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) {
if (!strncasecmp(message, "ERROR 592 ALTER CALL", 19)) { tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
ERRORA("Skype got ERROR about TRANSFERRING, no problem: |||%s|||\n", SKYPIAX_P_LOG, message); return CALLFLOW_INCOMING_HANGUP;
} else { } else {
DEBUGA_SKYPE("Skype got ERROR: |||%s|||\n", SKYPIAX_P_LOG, message); tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
}
}
*/
/*
if (!strncasecmp(message, "ERROR 99 CALL", 12) ) {
//TODO: let's kill the call
ERRORA("Skype got ERROR: |||%s|||, another call is active on this interface\n\n\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';
tech_pvt->interface_state = SKYPIAX_STATE_ERROR_DOUBLE_CALL;
}
*/
if (!strncasecmp(message, "ERROR", 4)) {
if (!strncasecmp(message, "ERROR 96 CALL", 12) ) {
DEBUGA_SKYPE("Skype got ERROR: |||%s|||, we are trying to use this interface to make or receive a call, but another call is half-active on this interface. Let's the previous one to continue.\n", SKYPIAX_P_LOG, message);
} else if (!strncasecmp(message, "ERROR 99 CALL", 12) ) {
ERRORA("Skype got ERROR: |||%s|||, another call is active on this interface\n\n\n", SKYPIAX_P_LOG, message);
tech_pvt->interface_state = SKYPIAX_STATE_ERROR_DOUBLE_CALL;
} else if (!strncasecmp(message, "ERROR 592 ALTER CALL", 19)) {
ERRORA("Skype got ERROR about TRANSFERRING, no problem: |||%s|||\n", SKYPIAX_P_LOG, message);
} else if (!strncasecmp(message, "ERROR 559 CALL", 13)) {
DEBUGA_SKYPE("Skype got ERROR about a failed action (probably TRYING to HANGUP A CALL), no problem: |||%s|||\n", SKYPIAX_P_LOG, message);
} else {
ERRORA("Skype got ERROR: |||%s|||\n", SKYPIAX_P_LOG, message);
tech_pvt->skype_callflow = CALLFLOW_STATUS_FINISHED; tech_pvt->skype_callflow = CALLFLOW_STATUS_FINISHED;
DEBUGA_SKYPE("skype_call now is DOWN\n", SKYPIAX_P_LOG); ERRORA("skype_call now is DOWN\n", SKYPIAX_P_LOG);
tech_pvt->skype_call_id[0] = '\0'; tech_pvt->skype_call_id[0] = '\0';
if (tech_pvt->interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) { if (tech_pvt->interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) {
@ -99,6 +168,25 @@ int skypiax_signaling_read(private_t * tech_pvt)
} }
} }
} }
skypiax_strncpy(message_2, message, sizeof(message) - 1);
buf = message;
stringp = &buf;
where = strsep(stringp, " ");
if (!where) {
WARNINGA("Skype MSG without spaces: %s\n", SKYPIAX_P_LOG, message);
}
if (!strcasecmp(message, "CURRENTUSERHANDLE")) { if (!strcasecmp(message, "CURRENTUSERHANDLE")) {
skypiax_strncpy(obj, where, sizeof(obj) - 1); skypiax_strncpy(obj, where, sizeof(obj) - 1);
where = strsep(stringp, " "); where = strsep(stringp, " ");
@ -163,7 +251,8 @@ int skypiax_signaling_read(private_t * tech_pvt)
//SKYPIAX_P_LOG, message, obj, id, prop, value, where ? where : "NULL"); //SKYPIAX_P_LOG, message, obj, id, prop, value, where ? where : "NULL");
if (!strcasecmp(prop, "PARTNER_HANDLE")) { if (!strcasecmp(prop, "PARTNER_HANDLE")) {
if (!strlen(tech_pvt->skype_call_id)) { if (!strlen(tech_pvt->skype_call_id) || !strlen(tech_pvt->session_uuid_str)) {
//if (!strlen(tech_pvt->skype_call_id)) {
/* we are NOT inside an active call */ /* we are NOT inside an active call */
DEBUGA_SKYPE("Call %s TRY ANSWER\n", SKYPIAX_P_LOG, id); DEBUGA_SKYPE("Call %s TRY ANSWER\n", SKYPIAX_P_LOG, id);
skypiax_answer(tech_pvt, id, value); skypiax_answer(tech_pvt, id, value);
@ -171,7 +260,7 @@ int skypiax_signaling_read(private_t * tech_pvt)
/* we are inside an active call */ /* we are inside an active call */
if (!strcasecmp(tech_pvt->skype_call_id, id)) { if (!strcasecmp(tech_pvt->skype_call_id, id)) {
/* this is the call in which we are calling out */ /* this is the call in which we are calling out */
DEBUGA_SKYPE("Call %s NOTHING\n", SKYPIAX_P_LOG, id); DEBUGA_SKYPE("Call %s DO NOTHING\n", SKYPIAX_P_LOG, id);
} else { } else {
skypiax_sleep(400000); //0.4 seconds skypiax_sleep(400000); //0.4 seconds
DEBUGA_SKYPE("Call %s TRY TRANSFER\n", SKYPIAX_P_LOG, id); DEBUGA_SKYPE("Call %s TRY TRANSFER\n", SKYPIAX_P_LOG, id);
@ -208,12 +297,25 @@ int skypiax_signaling_read(private_t * tech_pvt)
DEBUGA_SKYPE("We called a Skype contact and he answered us on skype_call: %s.\n", SKYPIAX_P_LOG, id); DEBUGA_SKYPE("We called a Skype contact and he answered us on skype_call: %s.\n", SKYPIAX_P_LOG, id);
} }
} }
if (!strcasecmp(prop, "DURATION") && (tech_pvt->interface_state == SKYPIAX_STATE_ERROR_DOUBLE_CALL)) {
char msg_to_skype[1024];
skypiax_strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
ERRORA("We are in a double call situation, trying to get out hanging up call id: %s.\n", SKYPIAX_P_LOG, id);
sprintf(msg_to_skype, "ALTER CALL %s HANGUP", id);
skypiax_signaling_write(tech_pvt, msg_to_skype);
skypiax_sleep(10000);
//return CALLFLOW_INCOMING_HANGUP;
}
if (!strcasecmp(prop, "STATUS")) { if (!strcasecmp(prop, "STATUS")) {
if (!strcasecmp(value, "RINGING")) { if (!strcasecmp(value, "RINGING")) {
char msg_to_skype[1024]; char msg_to_skype[1024];
if (!strlen(tech_pvt->skype_call_id)) { if ( (tech_pvt->interface_state != SKYPIAX_STATE_SELECTED && tech_pvt->interface_state != SKYPIAX_STATE_DIALING ) && (!strlen(tech_pvt->skype_call_id) || !strlen(tech_pvt->session_uuid_str)) ) {
/* we are NOT inside an active call */ /* we are NOT inside an active call */
DEBUGA_SKYPE("NO ACTIVE calls in this moment, skype_call %s is RINGING, to ask PARTNER_HANDLE\n", SKYPIAX_P_LOG, id);
sprintf(msg_to_skype, "GET CALL %s PARTNER_HANDLE", id); sprintf(msg_to_skype, "GET CALL %s PARTNER_HANDLE", id);
skypiax_signaling_write(tech_pvt, msg_to_skype); skypiax_signaling_write(tech_pvt, msg_to_skype);
skypiax_sleep(10000); skypiax_sleep(10000);
@ -227,6 +329,7 @@ int skypiax_signaling_read(private_t * tech_pvt)
DEBUGA_SKYPE("Our remote party in skype_call %s is RINGING\n", SKYPIAX_P_LOG, id); DEBUGA_SKYPE("Our remote party in skype_call %s is RINGING\n", SKYPIAX_P_LOG, id);
remote_party_is_ringing(tech_pvt); remote_party_is_ringing(tech_pvt);
} else { } else {
DEBUGA_SKYPE("We are in another call, but skype_call %s is RINGING on us, let's ask PARTNER_HANDLE, so maybe we'll TRANSFER\n", SKYPIAX_P_LOG, id);
sprintf(msg_to_skype, "GET CALL %s PARTNER_HANDLE", id); sprintf(msg_to_skype, "GET CALL %s PARTNER_HANDLE", id);
skypiax_signaling_write(tech_pvt, msg_to_skype); skypiax_signaling_write(tech_pvt, msg_to_skype);
skypiax_sleep(10000); skypiax_sleep(10000);
@ -237,7 +340,10 @@ int skypiax_signaling_read(private_t * tech_pvt)
tech_pvt->skype_callflow = CALLFLOW_STATUS_EARLYMEDIA; tech_pvt->skype_callflow = CALLFLOW_STATUS_EARLYMEDIA;
tech_pvt->interface_state = SKYPIAX_STATE_DIALING; tech_pvt->interface_state = SKYPIAX_STATE_DIALING;
DEBUGA_SKYPE("Our remote party in skype_call %s is EARLYMEDIA\n", SKYPIAX_P_LOG, id); DEBUGA_SKYPE("Our remote party in skype_call %s is EARLYMEDIA\n", SKYPIAX_P_LOG, id);
start_audio_threads(tech_pvt); if (start_audio_threads(tech_pvt)){
ERRORA("start_audio_threads FAILED\n", SKYPIAX_P_LOG);
return CALLFLOW_INCOMING_HANGUP;
}
skypiax_sleep(1000); skypiax_sleep(1000);
sprintf(msg_to_skype, "ALTER CALL %s SET_INPUT PORT=\"%d\"", id, tech_pvt->tcp_cli_port); 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_signaling_write(tech_pvt, msg_to_skype);
@ -251,9 +357,9 @@ int skypiax_signaling_read(private_t * tech_pvt)
//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 //usleep(150000);//150msec, let's give the TCP sockets time to timeout
if (!strcasecmp(tech_pvt->skype_call_id, id)) { if (!strcasecmp(tech_pvt->skype_call_id, id)) {
tech_pvt->skype_callflow = CALLFLOW_STATUS_FINISHED; //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); 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'; //tech_pvt->skype_call_id[0] = '\0';
if (tech_pvt->interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) { if (tech_pvt->interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) {
//tech_pvt->interface_state = SKYPIAX_STATE_DOWN; //tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
return CALLFLOW_INCOMING_HANGUP; return CALLFLOW_INCOMING_HANGUP;
@ -311,6 +417,9 @@ int skypiax_signaling_read(private_t * tech_pvt)
} else if (!strcasecmp(value, "INPROGRESS")) { } else if (!strcasecmp(value, "INPROGRESS")) {
char msg_to_skype[1024]; char msg_to_skype[1024];
if (!strlen(tech_pvt->session_uuid_str)) {
DEBUGA_SKYPE("no tech_pvt->session_uuid_str\n", SKYPIAX_P_LOG);
}
if (tech_pvt->skype_callflow != CALLFLOW_STATUS_REMOTEHOLD) { if (tech_pvt->skype_callflow != CALLFLOW_STATUS_REMOTEHOLD) {
if (!strlen(tech_pvt->session_uuid_str) || !strlen(tech_pvt->skype_call_id) if (!strlen(tech_pvt->session_uuid_str) || !strlen(tech_pvt->skype_call_id)
|| !strcasecmp(tech_pvt->skype_call_id, id)) { || !strcasecmp(tech_pvt->skype_call_id, id)) {
@ -320,7 +429,11 @@ int skypiax_signaling_read(private_t * tech_pvt)
if (tech_pvt->skype_callflow != CALLFLOW_STATUS_EARLYMEDIA) { if (tech_pvt->skype_callflow != CALLFLOW_STATUS_EARLYMEDIA) {
tech_pvt->skype_callflow = CALLFLOW_STATUS_INPROGRESS; tech_pvt->skype_callflow = CALLFLOW_STATUS_INPROGRESS;
tech_pvt->interface_state = SKYPIAX_STATE_UP; tech_pvt->interface_state = SKYPIAX_STATE_UP;
start_audio_threads(tech_pvt);
if (start_audio_threads(tech_pvt)){
ERRORA("start_audio_threads FAILED\n", SKYPIAX_P_LOG);
return CALLFLOW_INCOMING_HANGUP;
}
skypiax_sleep(1000); //FIXME skypiax_sleep(1000); //FIXME
sprintf(msg_to_skype, "ALTER CALL %s SET_INPUT PORT=\"%d\"", id, tech_pvt->tcp_cli_port); 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_signaling_write(tech_pvt, msg_to_skype);
@ -330,7 +443,7 @@ int skypiax_signaling_read(private_t * tech_pvt)
} }
tech_pvt->skype_callflow = SKYPIAX_STATE_UP; tech_pvt->skype_callflow = SKYPIAX_STATE_UP;
if (!strlen(tech_pvt->session_uuid_str)) { if (!strlen(tech_pvt->session_uuid_str)) {
DEBUGA_SKYPE("New Inbound Channel!\n", SKYPIAX_P_LOG); DEBUGA_SKYPE("New Inbound Channel!\n\n\n\n", SKYPIAX_P_LOG);
new_inbound_channel(tech_pvt); new_inbound_channel(tech_pvt);
} else { } else {
DEBUGA_SKYPE("Outbound Channel Answered!\n", SKYPIAX_P_LOG); DEBUGA_SKYPE("Outbound Channel Answered!\n", SKYPIAX_P_LOG);
@ -413,13 +526,14 @@ void *skypiax_do_tcp_srv_thread_func(void *obj)
unsigned int fd; unsigned int fd;
short srv_in[SAMPLES_PER_FRAME]; short srv_in[SAMPLES_PER_FRAME];
short srv_out[SAMPLES_PER_FRAME / 2]; short srv_out[SAMPLES_PER_FRAME / 2];
struct sockaddr_in my_addr; //struct sockaddr_in my_addr;
struct sockaddr_in remote_addr; struct sockaddr_in remote_addr;
//int exit = 0; //int exit = 0;
unsigned int kill_cli_size; unsigned int kill_cli_size;
short kill_cli_buff[SAMPLES_PER_FRAME]; short kill_cli_buff[SAMPLES_PER_FRAME];
short totalbuf[SAMPLES_PER_FRAME]; short totalbuf[SAMPLES_PER_FRAME];
#ifdef NOTDEF
memset(&my_addr, 0, sizeof(my_addr)); memset(&my_addr, 0, sizeof(my_addr));
my_addr.sin_family = AF_INET; my_addr.sin_family = AF_INET;
my_addr.sin_addr.s_addr = htonl(0x7f000001); /* use the localhost */ my_addr.sin_addr.s_addr = htonl(0x7f000001); /* use the localhost */
@ -427,11 +541,21 @@ void *skypiax_do_tcp_srv_thread_func(void *obj)
if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
ERRORA("socket Error\n", SKYPIAX_P_LOG); ERRORA("socket Error\n", SKYPIAX_P_LOG);
tech_pvt->tcp_srv_thread = NULL;
return NULL; return NULL;
} }
if (bind(s, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) < 0) { if (bind(s, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) < 0) {
ERRORA("bind Error\n", SKYPIAX_P_LOG); ERRORA("bind error: %s\n", SKYPIAX_P_LOG, strerror(errno));
tech_pvt->tcp_srv_thread = NULL;
return NULL;
}
#endif //NOTDEF
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; return NULL;
} }
DEBUGA_SKYPE("started tcp_srv_thread thread.\n", SKYPIAX_P_LOG); DEBUGA_SKYPE("started tcp_srv_thread thread.\n", SKYPIAX_P_LOG);
@ -546,7 +670,7 @@ void *skypiax_do_tcp_srv_thread_func(void *obj)
} else if (len == 0) { } else if (len == 0) {
skypiax_sleep(1000); skypiax_sleep(1000);
} else { } else {
ERRORA("len=%d, expected 320\n", SKYPIAX_P_LOG, len); DEBUGA_SKYPE("len=%d, expected 320\n", SKYPIAX_P_LOG, len);
} }
} else { } else {
@ -578,6 +702,7 @@ void *skypiax_do_tcp_srv_thread_func(void *obj)
DEBUGA_SKYPE("incoming audio server (I am it) EXITING\n", SKYPIAX_P_LOG); DEBUGA_SKYPE("incoming audio server (I am it) EXITING\n", SKYPIAX_P_LOG);
skypiax_close_socket(s); skypiax_close_socket(s);
tech_pvt->tcp_srv_thread = NULL;
return NULL; return NULL;
} }
@ -585,7 +710,7 @@ void *skypiax_do_tcp_cli_thread_func(void *obj)
{ {
private_t *tech_pvt = obj; private_t *tech_pvt = obj;
int s; int s;
struct sockaddr_in my_addr; //struct sockaddr_in my_addr;
struct sockaddr_in remote_addr; struct sockaddr_in remote_addr;
unsigned int got; unsigned int got;
unsigned int len; unsigned int len;
@ -600,6 +725,7 @@ void *skypiax_do_tcp_cli_thread_func(void *obj)
unsigned int sin_size; unsigned int sin_size;
#endif /* WIN32 */ #endif /* WIN32 */
#ifdef NOTDEF
memset(&my_addr, 0, sizeof(my_addr)); memset(&my_addr, 0, sizeof(my_addr));
my_addr.sin_family = AF_INET; my_addr.sin_family = AF_INET;
my_addr.sin_addr.s_addr = htonl(0x7f000001); /* use the localhost */ my_addr.sin_addr.s_addr = htonl(0x7f000001); /* use the localhost */
@ -607,14 +733,29 @@ void *skypiax_do_tcp_cli_thread_func(void *obj)
if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
ERRORA("socket Error\n", SKYPIAX_P_LOG); ERRORA("socket Error\n", SKYPIAX_P_LOG);
tech_pvt->tcp_cli_thread = NULL;
return NULL; return NULL;
} }
if (bind(s, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) < 0) { if (bind(s, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) < 0) {
ERRORA("bind Error\n", SKYPIAX_P_LOG); //ERRORA("bind Error\n", SKYPIAX_P_LOG);
ERRORA("bind error: %s\n", SKYPIAX_P_LOG, strerror(errno));
skypiax_close_socket(s); skypiax_close_socket(s);
tech_pvt->tcp_cli_thread = NULL;
return NULL; return NULL;
} }
#endif // NOTDEF
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); DEBUGA_SKYPE("started tcp_cli_thread thread.\n", SKYPIAX_P_LOG);
listen(s, 6); listen(s, 6);
@ -764,6 +905,7 @@ void *skypiax_do_tcp_cli_thread_func(void *obj)
DEBUGA_SKYPE("outbound audio server (I am it) EXITING\n", SKYPIAX_P_LOG); DEBUGA_SKYPE("outbound audio server (I am it) EXITING\n", SKYPIAX_P_LOG);
skypiax_close_socket(s); skypiax_close_socket(s);
tech_pvt->tcp_cli_thread = NULL;
return NULL; return NULL;
} }