From 78fbece8865c2bbd5129401a0b452878536d46f8 Mon Sep 17 00:00:00 2001
From: David Yat Sin <dyatsin@sangoma.com>
Date: Fri, 23 Apr 2010 17:34:57 -0400
Subject: [PATCH] Added signalling state handle for boost modules

---
 libs/freetdm/mod_freetdm/mod_freetdm.c         | 18 ++++++++++++++++++
 libs/freetdm/src/ftdm_io.c                     |  8 +++++---
 .../ftmod_sangoma_boost/ftmod_sangoma_boost.c  | 17 +++++++++--------
 libs/freetdm/src/include/ftdm_types.h          |  1 +
 4 files changed, 33 insertions(+), 11 deletions(-)

diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c
index fc3f1c4ca9..269908ba27 100644
--- a/libs/freetdm/mod_freetdm/mod_freetdm.c
+++ b/libs/freetdm/mod_freetdm/mod_freetdm.c
@@ -1950,6 +1950,16 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal)
 					sigmsg->channel->span_id, sigmsg->channel->chan_id, (uuid) ? uuid : "N/A");
 			}
 		}
+		break;
+	case FTDM_SIGEVENT_SIGSTATUS_CHANGED:
+		{
+			if (*((ftdm_signaling_status_t*)(sigmsg->raw_data)) == FTDM_SIG_STATE_UP) {
+				ftdm_set_flag(sigmsg->channel, FTDM_CHANNEL_SIG_UP);
+			} else {
+				ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_SIG_UP);
+			}
+		}
+		break;
 	default:
 		{
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled msg type %d for channel %d:%d\n",
@@ -2992,6 +3002,8 @@ void dump_chan(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stre
 						   "chan_id: %u\n"
 						   "physical_span_id: %u\n"
 						   "physical_chan_id: %u\n"
+						   "physical_state: %s\n"
+						   "signaling_state: %s\n"
 						   "type: %s\n"
 						   "state: %s\n"
 						   "last_state: %s\n"
@@ -3009,6 +3021,8 @@ void dump_chan(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stre
 						   span->channels[chan_id]->chan_id,
 						   span->channels[chan_id]->physical_span_id,
 						   span->channels[chan_id]->physical_chan_id,
+					  	 (span->channels[chan_id]->alarm_flags) ? "DOWN" : "UP",
+					     ftdm_test_flag(span->channels[chan_id], FTDM_CHANNEL_SIG_UP) ? "UP" : "DOWN",
 						   ftdm_chan_type2str(span->channels[chan_id]->type),
 						   ftdm_channel_state2str(span->channels[chan_id]->state),
 						   ftdm_channel_state2str(span->channels[chan_id]->last_state),
@@ -3037,6 +3051,8 @@ void dump_chan_xml(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *
 						   "  <chan-id>%u</chan-id>>\n"
 						   "  <physical-span-id>%u</physical-span-id>\n"
 						   "  <physical-chan-id>%u</physical-chan-id>\n"
+						   "  <physical-state>%s</physical-state>\n"
+						   "  <signaling-state>%s</signaling-state>\n"
 						   "  <type>%s</type>\n"
 						   "  <state>%s</state>\n"
 						   "  <last-state>%s</last-state>\n"
@@ -3055,6 +3071,8 @@ void dump_chan_xml(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *
 						   span->channels[chan_id]->chan_id,
 						   span->channels[chan_id]->physical_span_id,
 						   span->channels[chan_id]->physical_chan_id,
+						   (span->channels[chan_id]->alarm_flags) ? "DOWN" : "UP",
+					     ftdm_test_flag(span->channels[chan_id], FTDM_CHANNEL_SIG_UP) ? "UP" : "DOWN",
 						   ftdm_chan_type2str(span->channels[chan_id]->type),
 						   ftdm_channel_state2str(span->channels[chan_id]->state),
 						   ftdm_channel_state2str(span->channels[chan_id]->last_state),
diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c
index f00e7988e3..86fbd88da4 100644
--- a/libs/freetdm/src/ftdm_io.c
+++ b/libs/freetdm/src/ftdm_io.c
@@ -1279,9 +1279,10 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_group(uint32_t group_id, ftdm_dir
 		if (!(check = group->channels[i])) {
 			status = FTDM_FAIL;
 			break;
-		}
+		} 
 
-		if (ftdm_test_flag(check, FTDM_CHANNEL_READY) && 
+		if (ftdm_test_flag(check, FTDM_CHANNEL_READY) &&
+			ftdm_test_flag(check, FTDM_CHANNEL_SIG_UP) &&
 			!ftdm_test_flag(check, FTDM_CHANNEL_INUSE) && 
 			!ftdm_test_flag(check, FTDM_CHANNEL_SUSPENDED) && 
 			!ftdm_test_flag(check, FTDM_CHANNEL_IN_ALARM) &&
@@ -1401,7 +1402,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_span(uint32_t span_id, ftdm_direc
 			break;
 		}
 			
-		if (ftdm_test_flag(check, FTDM_CHANNEL_READY) && 
+		if (ftdm_test_flag(check, FTDM_CHANNEL_READY) &&
+			ftdm_test_flag(check, FTDM_CHANNEL_SIG_UP) &&
 			!ftdm_test_flag(check, FTDM_CHANNEL_INUSE) && 
 			!ftdm_test_flag(check, FTDM_CHANNEL_SUSPENDED) && 
 			!ftdm_test_flag(check, FTDM_CHANNEL_IN_ALARM) && 
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c
index a45c5189d3..ef641deb51 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c
@@ -2119,6 +2119,7 @@ static FIO_SIG_UNLOAD_FUNCTION(ftdm_sangoma_boost_destroy)
 static ftdm_status_t ftdm_sangoma_boost_start(ftdm_span_t *span)
 {
 	int err;
+
 	ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data;
 	ftdm_set_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_RUNNING);
 	err=ftdm_thread_create_detached(ftdm_sangoma_boost_run, span);
@@ -2137,23 +2138,23 @@ static ftdm_status_t ftdm_sangoma_boost_start(ftdm_span_t *span)
 
 static ftdm_status_t ftdm_sangoma_boost_stop(ftdm_span_t *span)
 {
+	int cnt = 10;
 	ftdm_status_t status = FTDM_SUCCESS;
 	ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data;
 	if (sangoma_boost_data->sigmod) {
+
+		/* FIXME: we should make sure the span thread is stopped (use pthread_kill or freetdm thread kill function) */
 		/* I think stopping the span before destroying the queue makes sense
 		   otherwise may be boost events would still arrive when the queue is already destroyed! */
 		status = sangoma_boost_data->sigmod->stop_span(span);
 
 		ftdm_queue_enqueue(sangoma_boost_data->boost_queue, NULL);
-	}
-
-	while (ftdm_test_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_RUNNING)) {
-		ftdm_log(FTDM_LOG_DEBUG, "Waiting for boost thread\n");
-		ftdm_sleep(100);
-	}
-
-	if (sangoma_boost_data->sigmod) {
+		while(ftdm_test_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_RUNNING) && cnt-- > 0) {
+			ftdm_log(FTDM_LOG_DEBUG, "Waiting for boost thread\n");
+			ftdm_sleep(500);
+		}
 		ftdm_queue_destroy(&sangoma_boost_data->boost_queue);
+		return status;
 	}
 	return status;
 }
diff --git a/libs/freetdm/src/include/ftdm_types.h b/libs/freetdm/src/include/ftdm_types.h
index bf7720efd1..90562104db 100644
--- a/libs/freetdm/src/include/ftdm_types.h
+++ b/libs/freetdm/src/include/ftdm_types.h
@@ -415,6 +415,7 @@ typedef enum {
 	FTDM_CHANNEL_USE_RX_GAIN = (1 << 25),
 	FTDM_CHANNEL_USE_TX_GAIN = (1 << 26),
 	FTDM_CHANNEL_IN_ALARM = (1 << 27),
+	FTDM_CHANNEL_SIG_UP = (1 << 28),
 } ftdm_channel_flag_t;
 #if defined(__cplusplus) && defined(WIN32) 
     // fix C2676