Project "FreeSWITCH Source" received a push.

branch: master updated

       via: 7c99cd9da80ad23cab7e83de31019b2fb2b721db (commit)
       via: 6fc0bb088654437771b89e42c90f6196d14acad6 (commit)
       via: 6734fe711bbc69dc999f237a1865a3013a1d762b (commit)
       via: a020724030c651aed8e427511b8dc79c4ae7a661 (commit)
      from: 57613192ccbf2a735d4afacfd63956aba5735457 (commit)


= COMMIT LOG ===========================================================
committer: Michael S Collins
comments: 
Merge branch 'master' of git://git.freeswitch.org/freeswitch
committer: Moises Silva
comments: 
Merge remote branch 'fsorig/master'
committer: Moises Silva
comments: 
freetdm: General fixes for alarm handling and added MFCR2 suspend support          - Clean up ftdm_channel_set_sig_status locking and sanity checks          - Set FTDM_CHANNEL_SUSPENDED when delivering FTDM_SIGEVENT_SIGSTATUS changed to SUSPENDED          - Clear FTDM_CHANNEL_SUSPENDED when delivering FTDM_SIGEVENT_SIGSTATUS changed to UP          - Update ftmod_r2 to honor local suspend requests when returning from alarm state

diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c
index 6cd2a22..6bfa375 100644
--- a/libs/freetdm/src/ftdm_io.c
+++ b/libs/freetdm/src/ftdm_io.c
@@ -2529,26 +2529,34 @@ done:
 	return status;
 }
 
-FT_DECLARE(ftdm_status_t) ftdm_channel_set_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status_t sigstatus)
+FT_DECLARE(ftdm_status_t) ftdm_channel_set_sig_status(ftdm_channel_t *fchan, ftdm_signaling_status_t sigstatus)
 {
-	ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "Null channel\n");
-	ftdm_assert_return(ftdmchan->span != NULL, FTDM_FAIL, "Null span\n");
+	ftdm_status_t res;
 
-	if (sigstatus == FTDM_SIG_STATE_DOWN) {
-		ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "The user is not allowed to set the signaling status to DOWN, valid states are UP or SUSPENDED\n");
-		return FTDM_FAIL;
+	ftdm_assert_return(fchan != NULL, FTDM_FAIL, "Null channel\n");
+	ftdm_assert_return(fchan->span != NULL, FTDM_FAIL, "Null span\n");
+	ftdm_assert_return(fchan->span->set_channel_sig_status != NULL, FTDM_ENOSYS, "Not implemented\n");
+
+	ftdm_channel_lock(fchan);
+
+	if (ftdm_test_flag(fchan, FTDM_CHANNEL_IN_ALARM)) {
+		ftdm_log_chan_msg(fchan, FTDM_LOG_WARNING, "You can not set the signaling status of an alarmed channel\n");
+		res = FTDM_EINVAL;
+		goto done;
 	}
 
-	if (ftdmchan->span->set_channel_sig_status) {
-		ftdm_status_t res;
-		ftdm_channel_lock(ftdmchan);
-		res = ftdmchan->span->set_channel_sig_status(ftdmchan, sigstatus);
-		ftdm_channel_unlock(ftdmchan);
-		return res;
-	} else {
-		ftdm_log(FTDM_LOG_ERROR, "set_channel_sig_status method not implemented!\n");
-		return FTDM_FAIL;
+	if (sigstatus == FTDM_SIG_STATE_DOWN) {
+		ftdm_log_chan_msg(fchan, FTDM_LOG_WARNING, "You can not set the signaling status to DOWN, valid states are UP or SUSPENDED\n");
+		res = FTDM_EINVAL;
+		goto done;
 	}
+
+	res = fchan->span->set_channel_sig_status(fchan, sigstatus);
+done:
+
+	ftdm_channel_unlock(fchan);
+
+	return res;
 }
 
 FT_DECLARE(ftdm_status_t) ftdm_channel_get_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status_t *sigstatus)
@@ -5505,8 +5513,14 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
 		{
 			if (sigmsg->ev_data.sigstatus.status == FTDM_SIG_STATE_UP) {
 				ftdm_set_flag(sigmsg->channel, FTDM_CHANNEL_SIG_UP);
+				ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_SUSPENDED);
 			} else {
 				ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_SIG_UP);
+				if (sigmsg->ev_data.sigstatus.status == FTDM_SIG_STATE_SUSPENDED) {
+					ftdm_set_flag(sigmsg->channel, FTDM_CHANNEL_SUSPENDED);
+				} else {
+					ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_SUSPENDED);
+				}
 			}
 		}
 		break;
diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c
index 2c9c42d..4344177 100644
--- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c
+++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c
@@ -70,6 +70,7 @@ typedef struct ftdm_r2_call_t {
 	int answer_pending:1;
 	int disconnect_rcvd:1;
 	int protocol_error:1;
+	int localsuspend_on_alarm:1;
 	ftdm_size_t dnis_index;
 	ftdm_size_t ani_index;
 	char logname[255];
@@ -499,8 +500,16 @@ static ftdm_status_t ftdm_r2_stop(ftdm_span_t *span)
 
 static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(ftdm_r2_get_channel_sig_status)
 {
+	openr2_chan_t *r2chan = R2CALL(ftdmchan)->r2chan;
+	openr2_cas_signal_t rxcas, txcas;
+
+	/* get the current rx and tx cas bits */
+	openr2_chan_get_cas(r2chan, &rxcas, &txcas);
+
 	if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
 		*status = FTDM_SIG_STATE_UP;
+	} else if (rxcas ==  OR2_CAS_BLOCK || txcas == OR2_CAS_BLOCK) {
+		*status = FTDM_SIG_STATE_SUSPENDED;
 	} else {
 		*status = FTDM_SIG_STATE_DOWN;
 	}
@@ -561,6 +570,11 @@ static FIO_SPAN_GET_SIG_STATUS_FUNCTION(ftdm_r2_get_span_sig_status)
 	for (citer = chaniter; citer; citer = ftdm_iterator_next(citer)) {
 		ftdm_channel_t *fchan = ftdm_iterator_current(citer);
 		ftdm_channel_lock(fchan);
+		if (ftdm_test_flag(fchan, FTDM_CHANNEL_IN_ALARM)) {
+			*status = FTDM_SIG_STATE_DOWN;
+			ftdm_channel_unlock(fchan);
+			break;
+		}
 		if (ftdm_test_flag(fchan, FTDM_CHANNEL_SIG_UP)) {
 			*status = FTDM_SIG_STATE_UP;
 			ftdm_channel_unlock(fchan);
@@ -825,8 +839,11 @@ static void ftdm_r2_on_hardware_alarm(openr2_chan_t *r2chan, int alarm)
 	ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Alarm notification %d when in state %s (sigstatus = %d)\n", 
 			alarm, ftdm_channel_state2str(fchan->state), ftdm_test_flag(fchan, FTDM_CHANNEL_SIG_UP) ? 1 : 0);
 
-	if (alarm && ftdm_test_flag(fchan, FTDM_CHANNEL_SIG_UP)) {
-		ftdm_r2_set_chan_sig_status(fchan, FTDM_SIG_STATE_DOWN);
+	if (alarm) {
+		R2CALL(fchan)->localsuspend_on_alarm = ftdm_test_flag(fchan, FTDM_CHANNEL_SUSPENDED) ? 1 : 0;
+		if (ftdm_test_flag(fchan, FTDM_CHANNEL_SIG_UP) || ftdm_test_flag(fchan, FTDM_CHANNEL_SUSPENDED)) {
+			ftdm_r2_set_chan_sig_status(fchan, FTDM_SIG_STATE_DOWN);
+		}
 	}
 }
 
@@ -881,18 +898,31 @@ static void ftdm_r2_on_line_blocked(openr2_chan_t *r2chan)
 {
 	ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan);
 	ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Far end blocked in state %s\n", ftdm_channel_state2str(ftdmchan->state));
-	if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
+	if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)
+	    || !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SUSPENDED)) {
 		ftdm_r2_set_chan_sig_status(ftdmchan, FTDM_SIG_STATE_SUSPENDED);
 	}
 }
 
 static void ftdm_r2_on_line_idle(openr2_chan_t *r2chan)
 {
+	openr2_cas_signal_t rxcas, txcas;
 	ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan);
+	
+	/* get the current rx and tx cas bits */
+	openr2_chan_get_cas(r2chan, &rxcas, &txcas);
 	ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Far end unblocked in state %s\n", ftdm_channel_state2str(ftdmchan->state));
-	if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
+	if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP) 
+	     && txcas == OR2_CAS_IDLE) {
+		/* if txcas is not idle, it means we're still blocked as far as the user is concerned, do not send SIGEVENT UP,
+		 * it will be done when the user set the line to IDLE (if the remote is still also IDLE) */
 		ftdm_r2_set_chan_sig_status(ftdmchan, FTDM_SIG_STATE_UP);
+	} else if (txcas == OR2_CAS_BLOCK && R2CALL(ftdmchan)->localsuspend_on_alarm) {
+		/* the user requested to block, we do not notify about state up until the user set the bits to IDLE, however
+		 * if we're just getting back from alarmed condition, we notify about suspended again */
+		ftdm_r2_set_chan_sig_status(ftdmchan, FTDM_SIG_STATE_SUSPENDED);
 	}
+	R2CALL(ftdmchan)->localsuspend_on_alarm = 0;
 }
 
 static void ftdm_r2_write_log(openr2_log_level_t level, const char *file, const char *function, int line, const char *message)
@@ -2018,9 +2048,6 @@ static void __inline__ block_channel(ftdm_channel_t *fchan, ftdm_stream_handle_t
 	if (fchan->state != FTDM_CHANNEL_STATE_DOWN) {
 		stream->write_function(stream, "cannot block channel %d:%d because has a call in progress\n", 
 				fchan->span_id, fchan->chan_id);
-	} else if (ftdm_test_flag(fchan, FTDM_CHANNEL_SUSPENDED)) {
-		stream->write_function(stream, "cannot block channel %d:%d because is already blocked\n", 
-				fchan->span_id, fchan->chan_id);
 	} else {
 		if (!openr2_chan_set_blocked(r2chan)) {
 			ftdm_set_flag(fchan, FTDM_CHANNEL_SUSPENDED);
@@ -2038,17 +2065,12 @@ static void __inline__ unblock_channel(ftdm_channel_t *fchan, ftdm_stream_handle
 {
 	openr2_chan_t *r2chan = R2CALL(fchan)->r2chan;
 	ftdm_mutex_lock(fchan->mutex);
-	if (ftdm_test_flag(fchan, FTDM_CHANNEL_SUSPENDED)) {
-		if (!openr2_chan_set_idle(r2chan)) {
-			ftdm_clear_flag(fchan, FTDM_CHANNEL_SUSPENDED);
-			stream->write_function(stream, "unblocked channel %d:%d\n", 
-					fchan->span_id, fchan->chan_id);
-		} else {
-			stream->write_function(stream, "failed to unblock channel %d:%d\n", 
-					fchan->span_id, fchan->chan_id);
-		}
+	if (!openr2_chan_set_idle(r2chan)) {
+		ftdm_clear_flag(fchan, FTDM_CHANNEL_SUSPENDED);
+		stream->write_function(stream, "unblocked channel %d:%d\n", 
+				fchan->span_id, fchan->chan_id);
 	} else {
-		stream->write_function(stream, "cannot unblock channel %d:%d because is not blocked\n", 
+		stream->write_function(stream, "failed to unblock channel %d:%d\n", 
 				fchan->span_id, fchan->chan_id);
 	}
 	ftdm_mutex_unlock(fchan->mutex);
diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c
index c73f0c7..1f2ad84 100644
--- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c
+++ b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c
@@ -1257,6 +1257,7 @@ static __inline__ ftdm_status_t wanpipe_channel_process_event(ftdm_channel_t *fc
 	switch(tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_type) {
 	case WP_API_EVENT_LINK_STATUS:
 		{
+#if 0
 			switch(tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_link_status) {
 			case WP_TDMAPI_EVENT_LINK_STATUS_CONNECTED:
 				*event_id = FTDM_OOB_ALARM_CLEAR;
@@ -1265,6 +1266,11 @@ static __inline__ ftdm_status_t wanpipe_channel_process_event(ftdm_channel_t *fc
 				*event_id = FTDM_OOB_ALARM_TRAP;
 				break;
 			};
+#else
+			/* The WP_API_EVENT_ALARM event should be used to clear alarms */
+			ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Ignoring wanpipe link status event\n", ftdm_oob_event2str(*event_id));
+			*event_id = FTDM_OOB_NOOP;
+#endif
 		}
 		break;
 
@@ -1353,8 +1359,13 @@ static __inline__ ftdm_status_t wanpipe_channel_process_event(ftdm_channel_t *fc
 		break;
 	case WP_API_EVENT_ALARM:
 		{
-			ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Got wanpipe alarms %d\n", tdm_api->wp_tdm_cmd.event.wp_api_event_alarm);
-			*event_id = FTDM_OOB_ALARM_TRAP;
+			if (tdm_api->wp_tdm_cmd.event.wp_api_event_alarm) {
+				ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Got Wanpipe alarms %d\n", tdm_api->wp_tdm_cmd.event.wp_api_event_alarm);
+				*event_id = FTDM_OOB_ALARM_TRAP;
+			} else {
+				ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "Wanpipe alarms cleared\n");
+				*event_id = FTDM_OOB_ALARM_CLEAR;
+			}
 		}
 		break;
 	case WP_API_EVENT_POLARITY_REVERSE:
committer: Moises Silva
comments: 
freetdm: add deprecate warning to get last error stuff that nobody sets anyways

diff --git a/libs/freetdm/TODO b/libs/freetdm/TODO
index 45b134b..6b8ef8f 100644
--- a/libs/freetdm/TODO
+++ b/libs/freetdm/TODO
@@ -5,5 +5,9 @@
   then ftdm_event_t would be renamed to ftdm_oob_event_t and the enum_id renamed to type, then ftdm_span_next_event()
   will only return OOB events
 
-- query span hw status (connected/disconnected) on startup 
+- Deprecate last_error members. 
+  It requires a lot of discipline to set the last_error string for every failure.
+  It does not add much value to the user either, most of the errors are criptic and
+  cannot be shown to end users, we already provide extensive logging for problem
+  troubleshooting.
 
diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h
index 0b9c619..2666a26 100644
--- a/libs/freetdm/src/include/freetdm.h
+++ b/libs/freetdm/src/include/freetdm.h
@@ -1064,6 +1064,9 @@ FT_DECLARE(ftdm_codec_t) ftdm_channel_get_codec(const ftdm_channel_t *ftdmchan);
 /*! 
  * \brief Get the last error string for the channel
  *
+ * \deprecated This API will disappear in the future and not every 
+ *             FreeTDM API set the last error value
+ *
  * \param ftdmchan The channel to get the error from
  *
  * \retval The error string (not thread-safe, the string is per channel, not per thread)
@@ -1136,6 +1139,9 @@ FT_DECLARE(ftdm_status_t) ftdm_span_find(uint32_t id, ftdm_span_t **span);
 /*! 
  * \brief Get the last error string for the given span
  *
+ * \deprecated This API will disappear in the future and not every 
+ *             FreeTDM API set the last error value
+ *
  * \param span The span to get the last error from
  *
  * \retval character string for the last error
========================================================================

Summary of changes:
 libs/freetdm/TODO                                  |    6 ++-
 libs/freetdm/src/ftdm_io.c                         |   44 ++++++++++-----
 libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c         |   56 ++++++++++++++------
 .../src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c        |   15 +++++-
 libs/freetdm/src/include/freetdm.h                 |    6 ++
 5 files changed, 92 insertions(+), 35 deletions(-)

this email was generated because of /git/your-repo.git/hooks/post-receive by the file /git-core/contrib/hooks/post-receive-email
For more info, see http://blog.chomperstomp.com/?p=630 --
FreeSWITCH Source