Revision
14517
Author
gmaruzz
Date
2009-08-14 12:12:09 -0500 (Fri, 14 Aug 2009)

Log Message

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

Modified Paths

Diff

Modified: freeswitch/trunk/src/mod/endpoints/mod_skypiax/mod_skypiax.c (14516 => 14517)


--- freeswitch/trunk/src/mod/endpoints/mod_skypiax/mod_skypiax.c	2009-08-14 13:27:27 UTC (rev 14516)
+++ freeswitch/trunk/src/mod/endpoints/mod_skypiax/mod_skypiax.c	2009-08-14 17:12:09 UTC (rev 14517)
@@ -148,6 +148,7 @@
 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_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)
 {
@@ -173,30 +174,40 @@
 
 	session = switch_core_session_locate(tech_pvt->session_uuid_str);
 
-	switch_core_session_set_read_codec(session, &tech_pvt->read_codec);
-	switch_core_session_set_write_codec(session, &tech_pvt->write_codec);
+	if(session){
+		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);
+	} else {
+		ERRORA("no session\n", SKYPIAX_P_LOG);
+		return SWITCH_STATUS_FALSE;
+	}
 
-	switch_core_session_rwunlock(session);
-
 	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.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->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
 	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));
+	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) {
 		ERRORA("skypiax_codec FAILED\n", SKYPIAX_P_LOG);
-	} else {
-		DEBUGA_SKYPE("skypiax_codec SUCCESS\n", SKYPIAX_P_LOG);
+		return SWITCH_STATUS_FALSE;
 	}
-
+	DEBUGA_SKYPE("skypiax_codec SUCCESS\n", SKYPIAX_P_LOG);
+	return SWITCH_STATUS_SUCCESS;
 }
 
 /* BEGIN: Changes here */
@@ -364,7 +375,8 @@
 
 	channel = switch_core_session_get_channel(session);
 	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
 	   to get from the initial start where the call because, to the point
@@ -376,7 +388,6 @@
 
 	switch_mutex_unlock(globals.mutex);
 
-	DEBUGA_SKYPE("%s CHANNEL INIT\n", SKYPIAX_P_LOG, switch_channel_get_name(channel));
 	return SWITCH_STATUS_SUCCESS;
 }
 
@@ -394,6 +405,7 @@
 		if (switch_core_codec_ready(&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);
 	}
 
@@ -406,15 +418,16 @@
 	private_t *tech_pvt = NULL;
 	char msg_to_skype[256];
 
+
 	channel = switch_core_session_get_channel(session);
 	switch_assert(channel != NULL);
 
 	tech_pvt = switch_core_session_get_private(session);
 	switch_assert(tech_pvt != NULL);
 
-	switch_clear_flag_locked(tech_pvt, TFLAG_IO);
-	switch_clear_flag_locked(tech_pvt, TFLAG_VOICE);
-	//switch_set_flag_locked(tech_pvt, TFLAG_HANGUP);
+	switch_clear_flag(tech_pvt, TFLAG_IO);
+	switch_clear_flag(tech_pvt, TFLAG_VOICE);
+	//switch_set_flag(tech_pvt, TFLAG_HANGUP);
 
 	if (strlen(tech_pvt->skype_call_id)) {
 		//switch_thread_cond_signal(tech_pvt->cond);
@@ -423,7 +436,7 @@
 		skypiax_signaling_write(tech_pvt, msg_to_skype);
 	}
 	//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));
 	switch_mutex_lock(globals.mutex);
 	globals.calls--;
@@ -482,13 +495,18 @@
 	switch (sig) {
 	case SWITCH_SIG_KILL:
 		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_clear_flag_locked(tech_pvt, TFLAG_VOICE);
-		switch_set_flag_locked(tech_pvt, TFLAG_HANGUP);
+		//switch_mutex_lock(tech_pvt->flag_mutex);
+		switch_clear_flag(tech_pvt, TFLAG_IO);
+		switch_clear_flag(tech_pvt, TFLAG_VOICE);
+		switch_set_flag(tech_pvt, TFLAG_HANGUP);
+		//switch_mutex_unlock(tech_pvt->flag_mutex);
 		break;
 	case SWITCH_SIG_BREAK:
 		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;
 	default:
 		break;
@@ -536,7 +554,8 @@
 	switch_assert(tech_pvt != NULL);
 
 	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;
 	}
 
@@ -548,7 +567,7 @@
 		ERRORA("skypiax_audio_read ERROR\n", SKYPIAX_P_LOG);
 
 	} else {
-		switch_set_flag_locked(tech_pvt, TFLAG_VOICE);
+		switch_set_flag(tech_pvt, TFLAG_VOICE);
 	}
 
 	while (switch_test_flag(tech_pvt, TFLAG_IO)) {
@@ -564,7 +583,7 @@
 		}
 
 		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) {
 				DEBUGA_SKYPE("CHANNEL READ CONTINUE\n", SKYPIAX_P_LOG);
 				continue;
@@ -610,7 +629,8 @@
 	switch_assert(tech_pvt != NULL);
 
 	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;
 	}
 #ifdef BIGENDIAN
@@ -721,9 +741,9 @@
 													switch_caller_profile_t *outbound_profile,
 													switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags)
 {
+		private_t *tech_pvt = NULL;
 	if ((*new_session = switch_core_session_request(skypiax_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, pool)) != 0) {
-		private_t *tech_pvt = NULL;
-		switch_channel_t *channel;
+		switch_channel_t *channel = NULL;
 		switch_caller_profile_t *caller_profile;
 		char *rdest;
 		int found = 0;
@@ -741,16 +761,16 @@
 			*slash = '\0';
 
 			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 */
-				DEBUGA_SKYPE("Finding one available skype interface\n", SKYPIAX_P_LOG);
-				tech_pvt = find_available_skypiax_interface(NULL);
-				if (tech_pvt)
-					found = 1;
-			} else if (strncmp("RR", interface_name, strlen(interface_name)) == 0) {
+				//DEBUGA_SKYPE("Finding one available skype interface\n", SKYPIAX_P_LOG);
+				//tech_pvt = find_available_skypiax_interface(NULL);
+				//if (tech_pvt)
+					//found = 1;
+			//} else if (strncmp("RR", interface_name, strlen(interface_name)) == 0) {
 				/* Find the first idle interface using Round Robin */
 				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)
 					found = 1;
 			}
@@ -765,7 +785,7 @@
 							 SKYPIAX_P_LOG, i, globals.SKYPIAX_INTERFACES[i].name, globals.SKYPIAX_INTERFACES[i].session_uuid_str);
 						switch_core_session_destroy(new_session);
 						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);
@@ -783,14 +803,26 @@
 		}
 
 		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_DESTINATION_OUT_OF_ORDER;
+			return SWITCH_CAUSE_NORMAL_CIRCUIT_CONGESTION;
 		}
 
 		channel = switch_core_session_get_channel(*new_session);
-		skypiax_tech_init(tech_pvt, *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_mutex_unlock(globals.mutex);
+			return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
+		}
 
 
 		if (outbound_profile) {
@@ -812,19 +844,21 @@
 		rdest = strchr(caller_profile->destination_number, '/');
 		*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));
 		caller_profile = tech_pvt->caller_profile;
 		caller_profile->destination_number = rdest;
 
 		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);
+		skypiax_call(tech_pvt, rdest, 30);
 		switch_mutex_unlock(globals.mutex);
 		return SWITCH_CAUSE_SUCCESS;
 	}
 
+	ERRORA("Doh! no new_session\n", SKYPIAX_P_LOG);
 	return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
 }
 
@@ -849,29 +883,35 @@
 		res = skypiax_signaling_read(tech_pvt);
 		if (res == CALLFLOW_INCOMING_HANGUP) {
 			switch_core_session_t *session = NULL;
+			switch_channel_t *channel = NULL;
 			//private_t *tech_pvt = NULL;
-			switch_channel_t *channel = NULL;
-
 			DEBUGA_SKYPE("skype call ended\n", SKYPIAX_P_LOG);
 
 			if (tech_pvt) {
 				session = switch_core_session_locate(tech_pvt->session_uuid_str);
-
 				if (session) {
 					channel = switch_core_session_get_channel(session);
 					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_core_session_rwunlock(session);
 					} else {
 						ERRORA("no channel?\n", SKYPIAX_P_LOG);
+					}
 						switch_core_session_rwunlock(session);
-					}
 				} else {
 					DEBUGA_SKYPE("no session\n", SKYPIAX_P_LOG);
 				}
 				tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
 				*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 {
 				ERRORA("no tech_pvt?\n", SKYPIAX_P_LOG);
 			}
@@ -1389,16 +1429,29 @@
 	switch_threadattr_create(&thd_attr, skypiax_module_pool);
 	switch_threadattr_detach_set(thd_attr, 1);
 	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);
+	} 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_detach_set(thd_attr, 1);
 	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);
+	}else{
+	ERRORA("failed to start tcp_cli_thread thread.\n", SKYPIAX_P_LOG);
+	return -1;
+	}
 	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;
 }
 
@@ -1410,7 +1463,16 @@
 	if ((session = switch_core_session_request(skypiax_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, NULL)) != 0) {
 		switch_core_session_add_stream(session, NULL);
 		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 =
 			 switch_caller_profile_new(switch_core_session_get_pool(session), "skypiax",
@@ -1426,11 +1488,14 @@
 		if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) {
 			ERRORA("Error spawning thread\n", SKYPIAX_P_LOG);
 			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;
 }
@@ -1457,7 +1522,6 @@
 		DEBUGA_SKYPE("skype_call: REMOTE PARTY RINGING\n", SKYPIAX_P_LOG);
 	} else {
 		ERRORA("No channel???\n", SKYPIAX_P_LOG);
-		goto done;
 	}
 
 	switch_core_session_rwunlock(session);
@@ -1474,7 +1538,8 @@
 	if (!switch_strlen_zero(tech_pvt->session_uuid_str)) {
 		session = switch_core_session_locate(tech_pvt->session_uuid_str);
 	} else {
-		ERRORA("No session???\n", SKYPIAX_P_LOG);
+		ERRORA("No session???\n\n\n", SKYPIAX_P_LOG);
+		//TODO: kill the bastard
 		goto done;
 	}
 	if (session) {
@@ -1482,6 +1547,7 @@
 		switch_core_session_add_stream(session, NULL);
 	} else {
 		ERRORA("No session???\n", SKYPIAX_P_LOG);
+		//TODO: kill the bastard
 		goto done;
 	}
 	if (channel) {
@@ -1489,7 +1555,7 @@
 		DEBUGA_SKYPE("skype_call: REMOTE PARTY EARLY MEDIA\n", SKYPIAX_P_LOG);
 	} else {
 		ERRORA("No channel???\n", SKYPIAX_P_LOG);
-		goto done;
+		//TODO: kill the bastard
 	}
 
 	switch_core_session_rwunlock(session);
@@ -1512,7 +1578,7 @@
 	if (session) {
 		channel = switch_core_session_get_channel(session);
 	} else {
-		ERRORA("No session???\n", SKYPIAX_P_LOG);
+		ERRORA("No channel???\n", SKYPIAX_P_LOG);
 		goto done;
 	}
 	if (channel) {
@@ -1520,17 +1586,17 @@
 		//DEBUGA_SKYPE("skype_call: %s, answered\n", SKYPIAX_P_LOG, id);
 	} else {
 		ERRORA("No channel???\n", SKYPIAX_P_LOG);
-		goto done;
 	}
 
 	switch_core_session_rwunlock(session);
 
   done:
-	DEBUGA_SKYPE("HERE!\n", SKYPIAX_P_LOG);
+	DEBUGA_SKYPE("outbound_channel_answered!\n", SKYPIAX_P_LOG);
 
 	return 0;
 }
 
+#if 0
 private_t *find_available_skypiax_interface(private_t * tech_pvt)
 {
 	private_t *tech_pvt2 = NULL;
@@ -1559,8 +1625,9 @@
 	else
 		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;
 	int i;
@@ -1585,12 +1652,14 @@
 
 			tech_pvt = &globals.SKYPIAX_INTERFACES[interface_id];
 			skype_state = tech_pvt->interface_state;
-			DEBUGA_SKYPE("skype interface: %d, name: %s, state: %d\n", SKYPIAX_P_LOG, interface_id,
-						 globals.SKYPIAX_INTERFACES[interface_id].name, skype_state);
-			if (SKYPIAX_STATE_DOWN == skype_state || 0 == skype_state) {
+			//DEBUGA_SKYPE("skype interface: %d, name: %s, state: %d\n", SKYPIAX_P_LOG, interface_id, 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 )) {
+				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 */
 				//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);
 				return tech_pvt;
@@ -1796,6 +1865,8 @@
 
 	if (found) {
 		//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);
 		return 0;
 	}
@@ -1822,7 +1893,9 @@
 	} else if (!tech_pvt || !tech_pvt->skype_call_id) {
 		ERRORA("No Call ID?\n", SKYPIAX_P_LOG);
 	} 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);
@@ -1858,6 +1931,8 @@
 
 	if (found) {
 		//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);
 		return 0;
 	}
@@ -1899,12 +1974,14 @@
 
 		if (found) {
 			//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);
 			return 0;
 		}
 		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) {
 			/* there is a skypiax interface idle, let's transfer the call to it */
 
@@ -1922,14 +1999,15 @@
 		} 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);
+				("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, id, tech_pvt->skype_call_id);
+			sprintf(msg_to_skype, "ALTER CALL %s END HANGUP", id);
+					skypiax_signaling_write(tech_pvt, msg_to_skype);
 		}
 		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);
+			("We have NOT answered a Skype RING from skype_call %s, because we are already in a skypiax call (%s)\n",
+			 SKYPIAX_P_LOG, id, tech_pvt->skype_call_id);
 
 		switch_mutex_unlock(globals.mutex);
 	}

Modified: freeswitch/trunk/src/mod/endpoints/mod_skypiax/skypiax.h (14516 => 14517)


--- freeswitch/trunk/src/mod/endpoints/mod_skypiax/skypiax.h	2009-08-14 13:27:27 UTC (rev 14516)
+++ freeswitch/trunk/src/mod/endpoints/mod_skypiax/skypiax.h	2009-08-14 17:12:09 UTC (rev 14517)
@@ -98,6 +98,8 @@
 #define		SKYPIAX_STATE_UP		5
 #define		SKYPIAX_STATE_RINGING	6
 #define		SKYPIAX_STATE_PRERING	7
+#define		SKYPIAX_STATE_ERROR_DOUBLE_CALL	8
+#define		SKYPIAX_STATE_SELECTED	9
 /*********************************/
 /* call flow from the device */
 #define 	CALLFLOW_CALL_IDLE  SKYPIAX_STATE_DOWN
@@ -244,7 +246,6 @@
 typedef struct private_object private_t;
 
 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_init(private_t * tech_pvt);
 int skypiax_signaling_write(private_t * tech_pvt, char *msg_to_skype);
@@ -277,8 +278,9 @@
 #endif /* WIN32 */
 int skypiax_close_socket(unsigned int fd);
 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_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);
+int skypiax_socket_create_and_bind(private_t * tech_pvt, int * which_port);

Modified: freeswitch/trunk/src/mod/endpoints/mod_skypiax/skypiax_protocol.c (14516 => 14517)


--- freeswitch/trunk/src/mod/endpoints/mod_skypiax/skypiax_protocol.c	2009-08-14 13:27:27 UTC (rev 14516)
+++ freeswitch/trunk/src/mod/endpoints/mod_skypiax/skypiax_protocol.c	2009-08-14 17:12:09 UTC (rev 14517)
@@ -25,6 +25,47 @@
 int xerror = 0;
 #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)
 {
 	char read_from_pipe[4096];
@@ -49,9 +90,9 @@
 
 		if (read_from_pipe[i] == '\0') {
 
-			if (!strstr(message, "DURATION")) {
+			//if (!strstr(message, "DURATION")) {
 				DEBUGA_SKYPE("READING: |||%s||| \n", SKYPIAX_P_LOG, message);
-			}
+			//}
 
 			if (!strcasecmp(message, "ERROR 68")) {
 				DEBUGA_SKYPE
@@ -75,20 +116,48 @@
 					tech_pvt->interface_state = SKYPIAX_STATE_DOWN;
 				}
 			}
-			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 (!strncasecmp(message, "ERROR 96 CALL", 12) ) {
+				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);
+				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, "ERROR")) {
-				if (!strncasecmp(message, "ERROR 592 ALTER CALL", 19)) {
+				*/
+			/*
+			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 {
-					DEBUGA_SKYPE("Skype got ERROR: |||%s|||\n", SKYPIAX_P_LOG, message);
+					ERRORA("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);
+					ERRORA("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) {
@@ -99,6 +168,25 @@
 					}
 				}
 			}
+
+
+
+
+			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")) {
 				skypiax_strncpy(obj, where, sizeof(obj) - 1);
 				where = strsep(stringp, " ");
@@ -163,7 +251,8 @@
 				//SKYPIAX_P_LOG, message, obj, id, prop, value, where ? where : "NULL");
 
 				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 */
 						DEBUGA_SKYPE("Call %s TRY ANSWER\n", SKYPIAX_P_LOG, id);
 						skypiax_answer(tech_pvt, id, value);
@@ -171,7 +260,7 @@
 						/* 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);
+							DEBUGA_SKYPE("Call %s DO NOTHING\n", SKYPIAX_P_LOG, id);
 						} else {
 							skypiax_sleep(400000);	//0.4 seconds
 							DEBUGA_SKYPE("Call %s TRY TRANSFER\n", SKYPIAX_P_LOG, id);
@@ -208,12 +297,25 @@
 						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(value, "RINGING")) {
 						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 */
+
+								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);
 							skypiax_signaling_write(tech_pvt, msg_to_skype);
 							skypiax_sleep(10000);
@@ -227,6 +329,7 @@
 								DEBUGA_SKYPE("Our remote party in skype_call %s is RINGING\n", SKYPIAX_P_LOG, id);
 								remote_party_is_ringing(tech_pvt);
 							} 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);
 								skypiax_signaling_write(tech_pvt, msg_to_skype);
 								skypiax_sleep(10000);
@@ -237,7 +340,10 @@
 						tech_pvt->skype_callflow = CALLFLOW_STATUS_EARLYMEDIA;
 						tech_pvt->interface_state = SKYPIAX_STATE_DIALING;
 						DEBUGA_SKYPE("Our remote party in skype_call %s is EARLYMEDIA\n", SKYPIAX_P_LOG, id);
-						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);
 						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);
@@ -251,9 +357,9 @@
 						//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;
+							//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';
+							//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;
@@ -311,6 +417,9 @@
 					} else if (!strcasecmp(value, "INPROGRESS")) {
 						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 (!strlen(tech_pvt->session_uuid_str) || !strlen(tech_pvt->skype_call_id)
 								|| !strcasecmp(tech_pvt->skype_call_id, id)) {
@@ -320,7 +429,11 @@
 								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);
+
+						if (start_audio_threads(tech_pvt)){
+							ERRORA("start_audio_threads FAILED\n", SKYPIAX_P_LOG);
+							return CALLFLOW_INCOMING_HANGUP;
+						}
 									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);
@@ -330,7 +443,7 @@
 								}
 								tech_pvt->skype_callflow = SKYPIAX_STATE_UP;
 								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);
 								} else {
 									DEBUGA_SKYPE("Outbound Channel Answered!\n", SKYPIAX_P_LOG);
@@ -413,13 +526,14 @@
 	unsigned int fd;
 	short srv_in[SAMPLES_PER_FRAME];
 	short srv_out[SAMPLES_PER_FRAME / 2];
-	struct sockaddr_in my_addr;
+	//struct sockaddr_in my_addr;
 	struct sockaddr_in remote_addr;
 	//int exit = 0;
 	unsigned int kill_cli_size;
 	short kill_cli_buff[SAMPLES_PER_FRAME];
 	short totalbuf[SAMPLES_PER_FRAME];
 
+#ifdef  NOTDEF
 	memset(&my_addr, 0, sizeof(my_addr));
 	my_addr.sin_family = AF_INET;
 	my_addr.sin_addr.s_addr = htonl(0x7f000001);	/* use the localhost */
@@ -427,13 +541,23 @@
 
 	if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
 		ERRORA("socket Error\n", SKYPIAX_P_LOG);
+		tech_pvt->tcp_srv_thread = NULL;
 		return NULL;
 	}
 
 	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;
+	}
 	DEBUGA_SKYPE("started tcp_srv_thread thread.\n", SKYPIAX_P_LOG);
 
 	listen(s, 6);
@@ -546,7 +670,7 @@
 						} else if (len == 0) {
 							skypiax_sleep(1000);
 						} else {
-							ERRORA("len=%d, expected 320\n", SKYPIAX_P_LOG, len);
+							DEBUGA_SKYPE("len=%d, expected 320\n", SKYPIAX_P_LOG, len);
 						}
 
 					} else {
@@ -578,6 +702,7 @@
 
 	DEBUGA_SKYPE("incoming audio server (I am it) EXITING\n", SKYPIAX_P_LOG);
 	skypiax_close_socket(s);
+	tech_pvt->tcp_srv_thread = NULL;
 	return NULL;
 }
 
@@ -585,7 +710,7 @@
 {
 	private_t *tech_pvt = obj;
 	int s;
-	struct sockaddr_in my_addr;
+	//struct sockaddr_in my_addr;
 	struct sockaddr_in remote_addr;
 	unsigned int got;
 	unsigned int len;
@@ -600,6 +725,7 @@
 	unsigned int sin_size;
 #endif /* WIN32 */
 
+#ifdef NOTDEF
 	memset(&my_addr, 0, sizeof(my_addr));
 	my_addr.sin_family = AF_INET;
 	my_addr.sin_addr.s_addr = htonl(0x7f000001);	/* use the localhost */
@@ -607,14 +733,29 @@
 
 	if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
 		ERRORA("socket Error\n", SKYPIAX_P_LOG);
+		tech_pvt->tcp_cli_thread = NULL;
 		return NULL;
 	}
 
 	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);
+		tech_pvt->tcp_cli_thread = 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);
 
 	listen(s, 6);
@@ -764,6 +905,7 @@
 
 	DEBUGA_SKYPE("outbound audio server (I am it) EXITING\n", SKYPIAX_P_LOG);
 	skypiax_close_socket(s);
+	tech_pvt->tcp_cli_thread = NULL;
 	return NULL;
 }