[Freeswitch-svn] [commit] r3991 - freeswitch/trunk/src/mod/endpoints/mod_iax

Freeswitch SVN anthm at freeswitch.org
Thu Jan 18 20:26:22 EST 2007


Author: anthm
Date: Thu Jan 18 20:26:22 2007
New Revision: 3991

Modified:
   freeswitch/trunk/src/mod/endpoints/mod_iax/mod_iax.c

Log:
a few twiax to prevent a race condition

Modified: freeswitch/trunk/src/mod/endpoints/mod_iax/mod_iax.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_iax/mod_iax.c	(original)
+++ freeswitch/trunk/src/mod/endpoints/mod_iax/mod_iax.c	Thu Jan 18 20:26:22 2007
@@ -98,6 +98,9 @@
 	//switch_thread_cond_t *cond;
 };
 
+typedef struct private_object private_t;
+
+
 SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_dialplan, globals.dialplan)
 SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_codec_string, globals.codec_string)
 SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_codec_rates_string, globals.codec_rates_string)
@@ -210,7 +213,7 @@
 	IAX_QUERY = 2
 } iax_io_t;
 
-static switch_status_t iax_set_codec(struct private_object *tech_pvt, struct iax_session *iax_session,
+static switch_status_t iax_set_codec(private_t *tech_pvt, struct iax_session *iax_session,
 								   unsigned int *format, unsigned int *cababilities, unsigned short *samprate,
 								   iax_io_t io)
 {
@@ -444,6 +447,15 @@
 	}
 }
 
+static void tech_init(private_t *tech_pvt, switch_core_session_t *session)
+{
+	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);
+    tech_pvt->session = session;
+}
 
 /* 
 State methods they get called when the state changes to the specific state 
@@ -453,7 +465,7 @@
 static switch_status_t channel_on_init(switch_core_session_t *session)
 {
 	switch_channel_t *channel;
-	struct private_object *tech_pvt = NULL;
+	private_t *tech_pvt = NULL;
 
 	tech_pvt = switch_core_session_get_private(session);
 	assert(tech_pvt != NULL);
@@ -461,13 +473,12 @@
 	channel = switch_core_session_get_channel(session);
 	assert(channel != NULL);
 
-	tech_pvt->read_frame.data = tech_pvt->databuf;
-	tech_pvt->read_frame.buflen = sizeof(tech_pvt->databuf);
+
 	iax_set_private(tech_pvt->iax_session, tech_pvt);
 
 	switch_set_flag_locked(tech_pvt, TFLAG_IO);
 
-	switch_mutex_init(&tech_pvt->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
+
 	//switch_thread_cond_create(&tech_pvt->cond, switch_core_session_get_pool(session));    
 	//switch_mutex_lock(tech_pvt->mutex);
 
@@ -483,7 +494,7 @@
 static switch_status_t channel_on_ring(switch_core_session_t *session)
 {
 	switch_channel_t *channel = NULL;
-	struct private_object *tech_pvt = NULL;
+	private_t *tech_pvt = NULL;
 
 	channel = switch_core_session_get_channel(session);
 	assert(channel != NULL);
@@ -500,7 +511,7 @@
 {
 
 	switch_channel_t *channel = NULL;
-	struct private_object *tech_pvt = NULL;
+	private_t *tech_pvt = NULL;
 
 	channel = switch_core_session_get_channel(session);
 	assert(channel != NULL);
@@ -517,7 +528,7 @@
 static switch_status_t channel_on_hangup(switch_core_session_t *session)
 {
 	switch_channel_t *channel = NULL;
-	struct private_object *tech_pvt = NULL;
+	private_t *tech_pvt = NULL;
 
 	channel = switch_core_session_get_channel(session);
 	assert(channel != NULL);
@@ -559,7 +570,7 @@
 static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig)
 {
 	switch_channel_t *channel = NULL;
-	struct private_object *tech_pvt = NULL;
+	private_t *tech_pvt = NULL;
 
 	channel = switch_core_session_get_channel(session);
 	assert(channel != NULL);
@@ -600,7 +611,7 @@
 
 static switch_status_t channel_waitfor_read(switch_core_session_t *session, int ms, int stream_id)
 {
-	struct private_object *tech_pvt = NULL;
+	private_t *tech_pvt = NULL;
 
 	tech_pvt = switch_core_session_get_private(session);
 	assert(tech_pvt != NULL);
@@ -610,7 +621,7 @@
 
 static switch_status_t channel_waitfor_write(switch_core_session_t *session, int ms, int stream_id)
 {
-	struct private_object *tech_pvt = NULL;
+	private_t *tech_pvt = NULL;
 
 	tech_pvt = switch_core_session_get_private(session);
 	assert(tech_pvt != NULL);
@@ -621,7 +632,7 @@
 
 static switch_status_t channel_send_dtmf(switch_core_session_t *session, char *dtmf)
 {
-	struct private_object *tech_pvt = NULL;
+	private_t *tech_pvt = NULL;
 	char *digit;
 
 	tech_pvt = switch_core_session_get_private(session);
@@ -639,7 +650,7 @@
 										switch_io_flag_t flags, int stream_id)
 {
 	switch_channel_t *channel = NULL;
-	struct private_object *tech_pvt = NULL;
+	private_t *tech_pvt = NULL;
 	switch_time_t started = switch_time_now();
 	unsigned int elapsed;
 
@@ -649,16 +660,18 @@
 	tech_pvt = switch_core_session_get_private(session);
 	assert(tech_pvt != NULL);
     tech_pvt->read_frame.flags = SFF_NONE;
-    
+    *frame = NULL;
+
 	while (switch_test_flag(tech_pvt, TFLAG_IO)) {
+        
+        if (!switch_test_flag(tech_pvt, TFLAG_CODEC)) {
+            switch_yield(1000);
+            continue;
+        }
 		//switch_thread_cond_wait(tech_pvt->cond, tech_pvt->mutex);
 		if (switch_test_flag(tech_pvt, TFLAG_BREAK)) {
             switch_clear_flag(tech_pvt, TFLAG_BREAK);
-            tech_pvt->read_frame.datalen = 13;
-            memset(tech_pvt->read_frame.data, 0, 13);
-            tech_pvt->read_frame.flags = SFF_CNG; 
-            *frame = &tech_pvt->read_frame;
-            return SWITCH_STATUS_SUCCESS;
+            goto cng;
         }
 
 		if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
@@ -692,13 +705,21 @@
 
 
 	return SWITCH_STATUS_FALSE;
+
+ cng:
+    tech_pvt->read_frame.datalen = 13;
+    memset(tech_pvt->read_frame.data, 0, 13);
+    tech_pvt->read_frame.flags = SFF_CNG; 
+    *frame = &tech_pvt->read_frame;
+    return SWITCH_STATUS_SUCCESS;
+
 }
 
 static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout,
 										 switch_io_flag_t flags, int stream_id)
 {
 	switch_channel_t *channel = NULL;
-	struct private_object *tech_pvt = NULL;
+	private_t *tech_pvt = NULL;
 	//switch_frame_t *pframe;
 
 	channel = switch_core_session_get_channel(session);
@@ -725,7 +746,7 @@
 
 static switch_status_t channel_answer_channel(switch_core_session_t *session)
 {
-	struct private_object *tech_pvt;
+	private_t *tech_pvt;
 	switch_channel_t *channel = NULL;
 
 	channel = switch_core_session_get_channel(session);
@@ -785,20 +806,16 @@
 											  switch_core_session_t **new_session, switch_memory_pool_t *pool)
 {
 	if ((*new_session = switch_core_session_request(&channel_endpoint_interface, pool)) != 0) {
-		struct private_object *tech_pvt;
+		private_t *tech_pvt;
 		switch_channel_t *channel;
 		switch_caller_profile_t *caller_profile;
 		unsigned int req = 0, cap = 0;
 		unsigned short samprate = 0;
 
 		switch_core_session_add_stream(*new_session, NULL);
-		if ((tech_pvt =
-			 (struct private_object *) switch_core_session_alloc(*new_session, sizeof(struct private_object))) != 0) {
-			memset(tech_pvt, 0, sizeof(*tech_pvt));
-			switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(*new_session));
+		if ((tech_pvt = (private_t *) switch_core_session_alloc(*new_session, sizeof(private_t))) != 0) {
 			channel = switch_core_session_get_channel(*new_session);
-			switch_core_session_set_private(*new_session, tech_pvt);
-			tech_pvt->session = *new_session;
+            tech_init(tech_pvt, *new_session);
 		} else {
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n");
 			switch_core_session_destroy(new_session);
@@ -929,6 +946,19 @@
 	return SWITCH_STATUS_SUCCESS;
 }
 
+static switch_status_t tech_media(private_t *tech_pvt, struct iax_event *iaxevent)
+{
+    unsigned int cap = iax_session_get_capability(iaxevent->session);
+    unsigned int format = iaxevent->ies.format;
+	switch_status_t status = SWITCH_STATUS_SUCCESS;
+    
+    if (!switch_test_flag(tech_pvt, TFLAG_CODEC) && 
+        (status = iax_set_codec(tech_pvt, iaxevent->session, &format, &cap, &iaxevent->ies.samprate, IAX_SET)) != SWITCH_STATUS_SUCCESS) {
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec Error %u %u\n", iaxevent->ies.format, iaxevent->ies.capability);
+    }
+    
+    return status;
+}
 
 SWITCH_MOD_DECLARE(switch_status_t) switch_module_runtime(void)
 {
@@ -960,8 +990,6 @@
 	}
 
 	for (;;) {
-
-
 		if (running == -1) {
 			break;
 		}
@@ -981,8 +1009,13 @@
 			switch_yield(waitlen);
 			continue;
 		} else {
-			struct private_object *tech_pvt = iax_get_private(iaxevent->session);
+			private_t *tech_pvt = NULL;
+            switch_channel_t *channel = NULL;
 
+            if ((tech_pvt = iax_get_private(iaxevent->session))) {
+                channel = switch_core_session_get_channel(tech_pvt->session);
+            }
+            
 			if (globals.debug && iaxevent->etype != IAX_EVENT_VOICE) {
 				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Event %d [%s]!\n",
 								  iaxevent->etype, IAXNAMES[iaxevent->etype]);
@@ -1001,17 +1034,8 @@
 				break;
 			case IAX_EVENT_ACCEPT:
 				if (tech_pvt) {
-					unsigned int cap = iax_session_get_capability(iaxevent->session);
-					unsigned int format = iaxevent->ies.format;
-					
-					if (iax_set_codec(tech_pvt, iaxevent->session, &format, &cap, &iaxevent->ies.samprate, IAX_SET) !=
-						SWITCH_STATUS_SUCCESS) {
-						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "WTF? %u %u\n", iaxevent->ies.format,
-											  iaxevent->ies.capability);
-					}
+                    tech_media(tech_pvt, iaxevent);
 				}
-
-
 				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Call accepted.\n");
 				break;
 			case IAX_EVENT_RINGA:
@@ -1022,20 +1046,18 @@
 				break;
 			case IAX_EVENT_ANSWER:
 				// the other side answered our call
-				if (tech_pvt) {
-					switch_channel_t *channel;
-					if ((channel = switch_core_session_get_channel(tech_pvt->session)) != 0) {
-						if (switch_channel_test_flag(channel, CF_ANSWERED)) {
-							switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "WTF Mutiple Answer %s?\n",
-											  switch_channel_get_name(channel));
-						} else {
-							switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Answer %s\n",
-												  switch_channel_get_name(channel));
-							switch_channel_answer(channel);
-						}
-					}
-				}
+				if (channel) {
+                    tech_media(tech_pvt, iaxevent);
 
+                    if (switch_channel_test_flag(channel, CF_ANSWERED)) {
+                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "WTF Mutiple Answer %s?\n", switch_channel_get_name(channel));
+						
+                    } else {
+                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Answer %s\n", switch_channel_get_name(channel));
+                        switch_channel_mark_answered(channel);
+                    }
+					
+				}
 				break;
 			case IAX_EVENT_CONNECT:
 				// incoming call detected
@@ -1051,18 +1073,13 @@
 					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "New Inbound Channel %s!\n",
 										  iaxevent->ies.calling_name);
 					if ((session = switch_core_session_request(&channel_endpoint_interface, NULL)) != 0) {
-						struct private_object *tech_pvt;
+						private_t *tech_pvt;
 						switch_channel_t *channel;
 
 						switch_core_session_add_stream(session, NULL);
-						if ((tech_pvt =
-							 (struct private_object *) switch_core_session_alloc(session,
-																				 sizeof(struct private_object))) != 0) {
-							memset(tech_pvt, 0, sizeof(*tech_pvt));
-							switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
+						if ((tech_pvt = (private_t *) switch_core_session_alloc(session, sizeof(private_t))) != 0) {
 							channel = switch_core_session_get_channel(session);
-							switch_core_session_set_private(session, tech_pvt);
-							tech_pvt->session = session;
+                            tech_init(tech_pvt, session);
 						} else {
 							switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n");
 							switch_core_session_destroy(&session);
@@ -1111,24 +1128,18 @@
 				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Rejected call.\n");
 			case IAX_EVENT_BUSY:
 			case IAX_EVENT_HANGUP:
-				if (tech_pvt) {
-					switch_channel_t *channel;
-					
+				if (channel) {
 					switch_mutex_lock(tech_pvt->flag_mutex);
 					switch_clear_flag(tech_pvt, TFLAG_IO);
 					switch_clear_flag(tech_pvt, TFLAG_VOICE);
 					switch_mutex_unlock(tech_pvt->flag_mutex);
 
-					if ((channel = switch_core_session_get_channel(tech_pvt->session)) != 0) {
-						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Hangup %s\n", switch_channel_get_name(channel));
-						switch_set_flag_locked(tech_pvt, TFLAG_HANGUP);
-						switch_channel_hangup(channel, iaxevent->etype == IAX_EVENT_HANGUP ? SWITCH_CAUSE_NORMAL_CLEARING : SWITCH_CAUSE_FACILITY_REJECTED);
-						//switch_thread_cond_signal(tech_pvt->cond);
-						iaxevent->session = NULL;
-					} else {
-						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No Session? %s\n",
-											  switch_test_flag(tech_pvt, TFLAG_VOICE) ? "yes" : "no");
-					}
+
+                    switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Hangup %s\n", switch_channel_get_name(channel));
+                    switch_set_flag_locked(tech_pvt, TFLAG_HANGUP);
+                    switch_channel_hangup(channel, iaxevent->etype == IAX_EVENT_HANGUP ? SWITCH_CAUSE_NORMAL_CLEARING : SWITCH_CAUSE_FACILITY_REJECTED);
+                    //switch_thread_cond_signal(tech_pvt->cond);
+                    iaxevent->session = NULL;
 				}
 				break;
 			case IAX_EVENT_CNG:
@@ -1137,9 +1148,7 @@
 				break;
 			case IAX_EVENT_VOICE:
 				if (tech_pvt && (tech_pvt->read_frame.datalen = iaxevent->datalen) != 0) {
-					switch_channel_t *channel;
-					if (((channel = switch_core_session_get_channel(tech_pvt->session)) != 0)
-						&& switch_channel_get_state(channel) <= CS_HANGUP) {
+					if (channel && switch_channel_get_state(channel) <= CS_HANGUP) {
 						int bytes, frames;
 						
 						if (!switch_test_flag(tech_pvt, TFLAG_CODEC)) {
@@ -1154,7 +1163,6 @@
 							frames = 1;
 						}
 
-
 						tech_pvt->read_frame.samples = frames * tech_pvt->read_codec.implementation->samples_per_frame;
 						memcpy(tech_pvt->read_frame.data, iaxevent->data, iaxevent->datalen);
 						/* wake up the i/o thread */
@@ -1168,16 +1176,13 @@
 				//session[0] = iaxevent->session;
 				break;
 			case IAX_EVENT_DTMF:
-				if (tech_pvt) {
-					switch_channel_t *channel;
-					if ((channel = switch_core_session_get_channel(tech_pvt->session)) != 0) {
-						char str[2] = { (char)iaxevent->subclass };
-						if (globals.debug) {
-							switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s DTMF %s\n", str,
-												  switch_channel_get_name(channel));
-						}
-						switch_channel_queue_dtmf(channel, str);
-					}
+				if (channel) {
+                    char str[2] = { (char)iaxevent->subclass };
+                    if (globals.debug) {
+                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s DTMF %s\n", str,
+                                          switch_channel_get_name(channel));
+                    }
+                    switch_channel_queue_dtmf(channel, str);
 				}
 
 				break;



More information about the Freeswitch-svn mailing list