diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c
index 38197bb2f0..d8f98f1c61 100755
--- a/libs/freetdm/mod_freetdm/mod_freetdm.c
+++ b/libs/freetdm/mod_freetdm/mod_freetdm.c
@@ -2167,6 +2167,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal)
 		}
 		break;
 	case FTDM_SIGEVENT_PROGRESS:
+	case FTDM_SIGEVENT_RINGING:
 		{
 			if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
 				channel = switch_core_session_get_channel(session);
@@ -3922,6 +3923,28 @@ SWITCH_STANDARD_API(ft_function)
 			}
 		}
 		stream->write_function(stream, "+OK gains set to Rx %f and Tx %f\n", rxgain, txgain);
+	} else if (!strcasecmp(argv[0], "restart")) {
+		uint32_t chan_id = 0;
+		ftdm_channel_t *chan;
+		ftdm_span_t *span = NULL;
+		if (argc < 3) {
+			stream->write_function(stream, "-ERR Usage: ftdm restart <span_id> <chan_id>\n");
+			goto end;
+		}
+		ftdm_span_find_by_name(argv[1], &span);
+		if (!span) {
+			stream->write_function(stream, "-ERR invalid span\n");
+			goto end;
+		}
+		
+		chan_id = atoi(argv[2]);
+		chan = ftdm_span_get_channel(span, chan_id);
+		if (!chan) {
+			stream->write_function(stream, "-ERR Could not find chan\n");
+			goto end;
+		}
+		stream->write_function(stream, "Resetting channel %s:%s\n", argv[2], argv[3]);
+		ftdm_channel_reset(chan);
 	} else {
 
 		char *rply = ftdm_api_execute(cmd);
diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c
index fca3adc9ad..6166c551f7 100644
--- a/libs/freetdm/src/ftdm_io.c
+++ b/libs/freetdm/src/ftdm_io.c
@@ -65,6 +65,8 @@ ftdm_time_t time_current_throttle_log = 0;
 static ftdm_iterator_t *get_iterator(ftdm_iterator_type_t type, ftdm_iterator_t *iter);
 static ftdm_status_t ftdm_call_set_call_id(ftdm_caller_data_t *caller_data);
 static ftdm_status_t ftdm_call_clear_call_id(ftdm_caller_data_t *caller_data);
+static ftdm_status_t ftdm_channel_clear_vars(ftdm_channel_t *ftdmchan);
+static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan);
 
 static int time_is_init = 0;
 
@@ -1874,45 +1876,6 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_span(uint32_t span_id, ftdm_direc
 	return status;
 }
 
-static ftdm_status_t ftdm_channel_reset(ftdm_channel_t *ftdmchan)
-{
-	ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_OPEN);
-	ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT);
-	ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_SUPRESS_DTMF);
-	ftdm_channel_done(ftdmchan);
-	ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_HOLD);
-
-	memset(ftdmchan->tokens, 0, sizeof(ftdmchan->tokens));
-	ftdmchan->token_count = 0;
-
-	ftdm_channel_flush_dtmf(ftdmchan);
-
-	if (ftdmchan->gen_dtmf_buffer) {
-		ftdm_buffer_zero(ftdmchan->gen_dtmf_buffer);
-	}
-
-	if (ftdmchan->digit_buffer) {
-		ftdm_buffer_zero(ftdmchan->digit_buffer);
-	}
-
-	if (!ftdmchan->dtmf_on) {
-		ftdmchan->dtmf_on = FTDM_DEFAULT_DTMF_ON;
-	}
-
-	if (!ftdmchan->dtmf_off) {
-		ftdmchan->dtmf_off = FTDM_DEFAULT_DTMF_OFF;
-	}
-
-	memset(ftdmchan->dtmf_hangup_buf, '\0', ftdmchan->span->dtmf_hangup_len);
-
-	if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE)) {
-		ftdmchan->effective_codec = ftdmchan->native_codec;
-		ftdmchan->packet_len = ftdmchan->native_interval * (ftdmchan->effective_codec == FTDM_CODEC_SLIN ? 16 : 8);
-		ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE);
-	}
-
-	return FTDM_SUCCESS;
-}
 
 FT_DECLARE(ftdm_status_t) ftdm_channel_init(ftdm_channel_t *ftdmchan)
 {
@@ -2416,14 +2379,16 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch
 			ftdm_set_flag(ftdmchan, FTDM_CHANNEL_PROGRESS);
 			ftdm_set_flag(ftdmchan, FTDM_CHANNEL_MEDIA);
 		} else {
-			if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS) {
-				ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS, 1);
-			}
+			if (!ftdm_test_flag(ftdmchan->span, FTDM_SPAN_USE_SKIP_STATES)) {
+				if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS) {
+					ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS, 1);
+				}
 
-			/* set state unlocks the channel so we need to re-confirm that the channel hasn't gone to hell */
-			if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) {
-				ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring answer because the call has moved to TERMINATING while we're moving to PROGRESS\n");
-				goto done;
+				/* set state unlocks the channel so we need to re-confirm that the channel hasn't gone to hell */
+				if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) {
+					ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring answer because the call has moved to TERMINATING while we're moving to PROGRESS\n");
+					goto done;
+				}
 			}
 
 			ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, 1);
@@ -2462,6 +2427,16 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_send_msg(const char *file, const ch
 	return status;
 }
 
+FT_DECLARE(ftdm_status_t) _ftdm_channel_reset(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan)
+{
+	ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "null channel");
+
+	ftdm_channel_lock(ftdmchan);
+	ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_RESET, 1);
+	ftdm_channel_unlock(ftdmchan);
+	return FTDM_SUCCESS;
+}
+
 FT_DECLARE(ftdm_status_t) _ftdm_channel_call_place(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan)
 {
 	ftdm_status_t status = FTDM_FAIL;
@@ -2545,12 +2520,13 @@ FT_DECLARE(ftdm_status_t) ftdm_span_get_sig_status(ftdm_span_t *span, ftdm_signa
 	}
 }
 
-static ftdm_status_t ftdm_channel_clear_vars(ftdm_channel_t *ftdmchan);
-FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan)
+static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan)
 {
 	ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "Null channel can't be done!\n");
-
 	ftdm_mutex_lock(ftdmchan->mutex);
+	ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_OPEN);
+	ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT);
+	ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_SUPRESS_DTMF);
 	ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_INUSE);
 	ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND);
 	ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_WINK);
@@ -2591,17 +2567,47 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan)
 		sigmsg.event_id = FTDM_SIGEVENT_RELEASED;
 		ftdm_span_send_signal(ftdmchan->span, &sigmsg);
 		ftdm_call_clear_call_id(&ftdmchan->caller_data);
-	}	
-
-	if (ftdmchan->txdrops || ftdmchan->rxdrops) {
-		ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "channel dropped data: txdrops = %d, rxdrops = %d\n", 
-				ftdmchan->txdrops, ftdmchan->rxdrops);
 	}
 
-	ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "channel done\n");
+	if (ftdmchan->txdrops || ftdmchan->rxdrops) {
+		ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "channel dropped data: txdrops = %d, rxdrops = %d\n",
+				ftdmchan->txdrops, ftdmchan->rxdrops);
+	}
+	
 	memset(&ftdmchan->caller_data, 0, sizeof(ftdmchan->caller_data));
-	ftdm_mutex_unlock(ftdmchan->mutex);
 
+	ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_HOLD);
+
+	memset(ftdmchan->tokens, 0, sizeof(ftdmchan->tokens));
+	ftdmchan->token_count = 0;
+
+	ftdm_channel_flush_dtmf(ftdmchan);
+
+	if (ftdmchan->gen_dtmf_buffer) {
+		ftdm_buffer_zero(ftdmchan->gen_dtmf_buffer);
+	}
+
+	if (ftdmchan->digit_buffer) {
+		ftdm_buffer_zero(ftdmchan->digit_buffer);
+	}
+
+	if (!ftdmchan->dtmf_on) {
+		ftdmchan->dtmf_on = FTDM_DEFAULT_DTMF_ON;
+	}
+
+	if (!ftdmchan->dtmf_off) {
+		ftdmchan->dtmf_off = FTDM_DEFAULT_DTMF_OFF;
+	}
+
+	memset(ftdmchan->dtmf_hangup_buf, '\0', ftdmchan->span->dtmf_hangup_len);
+
+	if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE)) {
+		ftdmchan->effective_codec = ftdmchan->native_codec;
+		ftdmchan->packet_len = ftdmchan->native_interval * (ftdmchan->effective_codec == FTDM_CODEC_SLIN ? 16 : 8);
+		ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE);
+	}
+	ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "channel done\n");
+	ftdm_mutex_unlock(ftdmchan->mutex);
 	return FTDM_SUCCESS;
 }
 
@@ -2631,8 +2637,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_close(ftdm_channel_t **ftdmchan)
 		if (ftdm_test_flag(check, FTDM_CHANNEL_OPEN)) {
 			status = check->fio->close(check);
 			if (status == FTDM_SUCCESS) {
-				ftdm_clear_flag(check, FTDM_CHANNEL_INUSE);
-				ftdm_channel_reset(check);
+				ftdm_channel_done(check);
 				*ftdmchan = NULL;
 			}
 		} else {
diff --git a/libs/freetdm/src/ftdm_m3ua.c b/libs/freetdm/src/ftdm_m3ua.c
index 1a6fe362e7..8d3e00213a 100644
--- a/libs/freetdm/src/ftdm_m3ua.c
+++ b/libs/freetdm/src/ftdm_m3ua.c
@@ -156,7 +156,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
 				release_request_id((m3ua_request_id_t)ftdmchan->extra_id);
 				ftdmchan->extra_id = 0;
 			}
-			ftdm_channel_done(ftdmchan);			
+			ftdm_channel_close(&ftdmchan);			
 		}
 		break;
 	case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
diff --git a/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c b/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c
index 6a8a4eb379..5b4ce7196a 100644
--- a/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c
+++ b/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c
@@ -1325,7 +1325,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
 				}
 				Q931ReleaseCRV(&isdn_data->q931, gen->CRV);
 			}
-			ftdm_channel_done(ftdmchan);
+			ftdm_channel_close(&ftdmchan);
 		}
 		break;
 	case FTDM_CHANNEL_STATE_PROGRESS:
diff --git a/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c b/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c
index 220a96515b..27fbe2139f 100644
--- a/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c
+++ b/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c
@@ -280,12 +280,12 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
 
 	switch (ftdmchan->state) {
 	case FTDM_CHANNEL_STATE_DOWN:
-		{
-			ftdm_channel_done(ftdmchan);			
+		{			
 			ftdmchan->call_data = NULL;
+			ftdm_channel_close(&ftdmchan);
 
-			ftdm_channel_done(peerchan);
 			peerchan->call_data = NULL;
+			ftdm_channel_close(&peerchan);
 		}
 		break;
 
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 50a01cc0ec..f59b3b8c4f 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
@@ -839,7 +839,7 @@ static void handle_call_released(ftdm_span_t *span, sangomabc_connection_t *mcon
 	if ((ftdmchan = find_ftdmchan(span, event, 1))) {
 		ftdm_log(FTDM_LOG_DEBUG, "Releasing completely chan s%dc%d\n", BOOST_EVENT_SPAN(mcon->sigmod, event), 
 				BOOST_EVENT_CHAN(mcon->sigmod, event));
-		ftdm_channel_done(ftdmchan);
+		ftdm_channel_close(&ftdmchan);
 	} else {
 		ftdm_log(FTDM_LOG_CRIT, "Odd, We could not find chan: s%dc%d to release the call completely!!\n", 
 				BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event));
@@ -1105,8 +1105,9 @@ static void handle_call_loop_start(ftdm_span_t *span, sangomabc_connection_t *mc
 
 	ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_IN_LOOP, res);
 	if (res != FTDM_SUCCESS) {
+		ftdm_channel_t *toclose = ftdmchan;
 		ftdm_log(FTDM_LOG_CRIT, "yay, could not set the state of the channel to IN_LOOP, loop will fail\n");
-		ftdm_channel_done(ftdmchan);
+		ftdm_channel_close(&toclose);
 		return;
 	}
 	ftdm_log(FTDM_LOG_DEBUG, "%d:%d starting loop\n", ftdmchan->span_id, ftdmchan->chan_id);
@@ -1426,11 +1427,12 @@ static __inline__ ftdm_status_t state_advance(ftdm_channel_t *ftdmchan)
 			ftdmchan->sflags = 0;
 			memset(ftdmchan->call_data, 0, sizeof(sangoma_boost_call_t));
 			if (sangoma_boost_data->sigmod && call_stopped_ack_sent) {
-				/* we dont want to call ftdm_channel_done just yet until call released is received */
+				/* we dont want to call ftdm_channel_close just yet until call released is received */
 				ftdm_log(FTDM_LOG_DEBUG, "Waiting for call release confirmation before declaring chan %d:%d as available \n", 
 						ftdmchan->span_id, ftdmchan->chan_id);
 			} else {
-				ftdm_channel_done(ftdmchan);
+				ftdm_channel_t *toclose = ftdmchan;
+				ftdm_channel_close(&toclose);
 			}
 		}
 		break;
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c
index e20d3ae7e0..48ddddce6b 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c
@@ -65,7 +65,13 @@ ftdm_state_map_t sangoma_isdn_state_map = {
 		ZSD_INBOUND,
 		ZSM_UNACCEPTABLE,
 		{FTDM_ANY_STATE, FTDM_END},
-		{FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_SUSPENDED, FTDM_END}
+		{FTDM_CHANNEL_STATE_RESET, FTDM_CHANNEL_STATE_RESTART, FTDM_END}
+	},
+	{
+		ZSD_INBOUND,
+		ZSM_UNACCEPTABLE,
+		{FTDM_CHANNEL_STATE_RESET, FTDM_END},
+		{FTDM_CHANNEL_STATE_DOWN, FTDM_END}
 	},
 	{
 		ZSD_INBOUND,
@@ -170,7 +176,13 @@ ftdm_state_map_t sangoma_isdn_state_map = {
 		ZSD_OUTBOUND,
 		ZSM_UNACCEPTABLE,
 		{FTDM_ANY_STATE, FTDM_END},
-		{FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}
+		{FTDM_CHANNEL_STATE_RESET, FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}
+	},
+	{
+		ZSD_OUTBOUND,
+		ZSM_UNACCEPTABLE,
+		{FTDM_CHANNEL_STATE_RESET, FTDM_END},
+		{FTDM_CHANNEL_STATE_DOWN, FTDM_END}
 	},
 	{
 		ZSD_OUTBOUND,
@@ -203,7 +215,7 @@ ftdm_state_map_t sangoma_isdn_state_map = {
 		ZSM_UNACCEPTABLE,
 		{FTDM_CHANNEL_STATE_DIALING, FTDM_END},
 		{FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
-		 FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP,
+		 FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP,
 		 FTDM_CHANNEL_STATE_DOWN, FTDM_END}
 	},
 	{
@@ -211,14 +223,20 @@ ftdm_state_map_t sangoma_isdn_state_map = {
 		ZSM_UNACCEPTABLE,
 		{FTDM_CHANNEL_STATE_PROCEED, FTDM_END},
 		{FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
-		 FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END},
-		},
+		 FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END},
+	},
 	{
 		ZSD_OUTBOUND,
 		ZSM_UNACCEPTABLE,
 		{FTDM_CHANNEL_STATE_PROGRESS, FTDM_END},
 		{FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END},
 	},
+	{
+		ZSD_OUTBOUND,
+		ZSM_UNACCEPTABLE,
+		{FTDM_CHANNEL_STATE_RINGING, FTDM_END},
+		{FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END},
+	},
 	{
 		ZSD_OUTBOUND,
 		ZSM_UNACCEPTABLE,
@@ -680,8 +698,17 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
 		break;
 	case FTDM_CHANNEL_STATE_RINGING:
 		{
-			ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN};
-			sngisdn_snd_alert(ftdmchan, prog_ind);
+			if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
+				/* OUTBOUND...so we were told by the line of this so notify the user */
+				sigev.event_id = FTDM_SIGEVENT_RINGING;
+				ftdm_span_send_signal(ftdmchan->span, &sigev);
+				if (sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY)) {
+					ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
+				}
+			} else {
+				ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN};
+				sngisdn_snd_alert(ftdmchan, prog_ind);
+			}
 		}
 		break;
 	case FTDM_CHANNEL_STATE_PROGRESS:
@@ -692,12 +719,9 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
 				sigev.event_id = FTDM_SIGEVENT_PROGRESS;
 				ftdm_span_send_signal(ftdmchan->span, &sigev);
 			} else {
-				/* If we already sent a PROCEED before, do not send a PROGRESS as there is nothing to indicate to the remote switch */
-				if (ftdmchan->last_state != FTDM_CHANNEL_STATE_PROCEED) {
-					/* Send a progress message, indicating: Call is not end-to-end ISDN, further call progress may be available */
-					ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN};
-					sngisdn_snd_progress(ftdmchan, prog_ind);
-				}
+				/* Send a progress message, indicating: Call is not end-to-end ISDN, further call progress may be available */
+				ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN};
+				sngisdn_snd_progress(ftdmchan, prog_ind);				
 			}
 		}
 		break;
@@ -780,7 +804,7 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
 					sngisdn_snd_release(ftdmchan, 0);
 
 					if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
-						sngisdn_set_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN);
+						sngisdn_set_span_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN);
 					}
 				} else {
 					sngisdn_snd_disconnect(ftdmchan);
@@ -838,6 +862,11 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
 			/* IMPLEMENT ME */
 		}
 		break;
+	case FTDM_CHANNEL_STATE_RESET:
+		{
+			sngisdn_snd_restart(ftdmchan);
+		}
+		break;
 	default:
 		{
 			ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "unsupported sngisdn_rcvd state %s\n", ftdm_channel_state2str(ftdmchan->state));
@@ -862,10 +891,6 @@ static FIO_CHANNEL_SEND_MSG_FUNCTION(ftdm_sangoma_isdn_send_msg)
 	ftdm_status_t status = FTDM_FAIL;
 
 	switch (sigmsg->event_id) {
-		case FTDM_SIGEVENT_RESTART:
-			/* TODO: Send a channel restart here */
-			/* Implement me */
-			break;
 		case FTDM_SIGEVENT_FACILITY:
 			sngisdn_snd_fac_req(ftdmchan);
 			break;
@@ -1072,7 +1097,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config)
 	if (span->trunk_type == FTDM_TRUNK_BRI_PTMP ||
 		span->trunk_type == FTDM_TRUNK_BRI) {
 		
-		sngisdn_set_avail_rate(span, SNGISDN_AVAIL_PWR_SAVING);
+		sngisdn_set_span_avail_rate(span, SNGISDN_AVAIL_PWR_SAVING);
 	}
 
 	/* Initialize scheduling context */
@@ -1167,6 +1192,7 @@ static FIO_API_FUNCTION(ftdm_sangoma_isdn_api)
 		goto done;
 	}
 
+	/* TODO: Move functions to table + function pointers */
 	if (!strcasecmp(argv[0], "trace")) {
 		char *trace_opt;
 		
@@ -1210,7 +1236,7 @@ static FIO_API_FUNCTION(ftdm_sangoma_isdn_api)
 		}
 		sngisdn_print_phy_stats(stream, span);
 	}
-
+	
 	if (!strcasecmp(argv[0], "show_spans")) {
 		ftdm_span_t *span = NULL;
 		if (argc == 2) {
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h
index f15eff9200..0c6c1c6eef 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h
@@ -101,9 +101,11 @@ typedef enum {
 	FLAG_GLARE              = (1 << 6),
 	FLAG_DELAYED_REL        = (1 << 7),
 	FLAG_SENT_PROCEED       = (1 << 8),
-	FLAG_SEND_DISC  		= (1 << 9),
+	FLAG_SEND_DISC  		= (1 << 9),	
 	/* Used for BRI only, flag is set after we request line CONNECTED */
-	FLAG_ACTIVATING			= (1 << 10), 
+	FLAG_ACTIVATING			= (1 << 10),
+	/* Used when we receive an ALERT msg + inband tones ready */
+	FLAG_MEDIA_READY		= (1 << 11),
 } sngisdn_flag_t;
 
 
@@ -352,8 +354,11 @@ void clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info);
 ftdm_status_t get_ftdmchan_by_suInstId(int16_t cc_id, uint32_t suInstId, sngisdn_chan_data_t **sngisdn_data);
 ftdm_status_t get_ftdmchan_by_spInstId(int16_t cc_id, uint32_t spInstId, sngisdn_chan_data_t **sngisdn_data);
 
+ftdm_status_t sngisdn_set_span_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail);
+ftdm_status_t sngisdn_set_chan_avail_rate(ftdm_channel_t *chan, sngisdn_avail_t avail);
+void sngisdn_set_span_sig_status(ftdm_span_t *ftdmspan, ftdm_signaling_status_t status);
+void sngisdn_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status_t status);
 
-ftdm_status_t sngisdn_set_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail);
 ftdm_status_t sngisdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt);
 
 
@@ -374,6 +379,7 @@ void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan);
 void sngisdn_snd_fac_req(ftdm_channel_t *ftdmchan);
 void sngisdn_snd_info_req(ftdm_channel_t *ftdmchan);
 void sngisdn_snd_status_enq(ftdm_channel_t *ftdmchan);
+void sngisdn_snd_restart(ftdm_channel_t *ftdmchan);
 void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len);
 void sngisdn_snd_event(ftdm_channel_t *dchan, ftdm_oob_event_t event);
 
@@ -453,6 +459,9 @@ ftdm_status_t set_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb);
 ftdm_status_t set_calling_name(ftdm_channel_t *ftdmchan, ConEvnt *conEvnt);
 ftdm_status_t set_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad);
 ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_sngisdn_progind_t prog_ind);
+ftdm_status_t set_bear_cap_ie(ftdm_channel_t *ftdmchan, BearCap *bearCap);
+ftdm_status_t set_chan_id_ie(ftdm_channel_t *ftdmchan, ChanId *chanId);
+ftdm_status_t set_restart_ind_ie(ftdm_channel_t *ftdmchan, RstInd *rstInd);
 ftdm_status_t set_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr);
 ftdm_status_t set_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, uint8_t *data_len);
 
@@ -482,7 +491,6 @@ static __inline__ void sngisdn_set_flag(sngisdn_chan_data_t *sngisdn_info, sngis
 
 
 void handle_sng_log(uint8_t level, char *fmt,...);
-void sngisdn_set_span_sig_status(ftdm_span_t *ftdmspan, ftdm_signaling_status_t status);
 void sngisdn_delayed_setup(void* p_sngisdn_info);
 void sngisdn_delayed_release(void* p_sngisdn_info);
 void sngisdn_delayed_connect(void* p_sngisdn_info);
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c
index fb65d20cab..7e9e360c6d 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c
@@ -33,7 +33,8 @@
  */
 
 #include "ftmod_sangoma_isdn.h"
-ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn);
+static ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn);
+static void sngisdn_process_restart_confirm(ftdm_channel_t *ftdmchan);
 
 /* Remote side transmit a SETUP */
 void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
@@ -232,6 +233,9 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
 				ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
 			}
 			break;
+		case FTDM_CHANNEL_STATE_RESET:
+				ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
+			break;
 		default:
 			ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing SETUP in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
 			break;
@@ -274,6 +278,7 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
 	if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
 		switch(ftdmchan->state) {
 			case FTDM_CHANNEL_STATE_PROCEED:
+			case FTDM_CHANNEL_STATE_RINGING:
 			case FTDM_CHANNEL_STATE_PROGRESS:
 			case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
 			case FTDM_CHANNEL_STATE_DIALING:
@@ -285,6 +290,9 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
 			case FTDM_CHANNEL_STATE_HANGUP:
 				/* Race condition, we just hung up the call - ignore this message */
 				break;
+			case FTDM_CHANNEL_STATE_RESET:
+				ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
+				break;				
 			default:
 				ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing CONNECT/CONNECT ACK in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
 
@@ -301,6 +309,9 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
 			case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
 				/* Race condition, We just hung up an incoming call right after we sent a CONNECT - ignore this message */
 				break;
+			case FTDM_CHANNEL_STATE_RESET:
+				ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
+				break;
 			default:
 				ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing CONNECT/CONNECT ACK in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
 				
@@ -354,27 +365,47 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
 				ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
 				goto sngisdn_process_cnst_ind_end;
 			}
-			
+
 			switch(ftdmchan->state) {
 				case FTDM_CHANNEL_STATE_DIALING:
 				case FTDM_CHANNEL_STATE_PROCEED:
-					if (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL) {
-						ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
-					} else 	if (evntType == MI_CALLPROC) {
-						ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROCEED);
-					} else {
-						ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
-					}
-					break;
 				case FTDM_CHANNEL_STATE_PROGRESS:
+				case FTDM_CHANNEL_STATE_RINGING:
 					if (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL) {
-						ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
+						sngisdn_set_flag(sngisdn_info, FLAG_MEDIA_READY);
+					}
+					switch (evntType) {
+						case MI_CALLPROC:
+							if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALING) {
+								ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROCEED);
+							}
+							break;
+						case MI_ALERTING:
+							if (ftdmchan->state == FTDM_CHANNEL_STATE_PROCEED) {
+								ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RINGING);
+							}
+							break;
+						case MI_PROGRESS:
+							if (sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY)) {
+								
+								ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
+							} else if (ftdmchan->state != FTDM_CHANNEL_STATE_PROGRESS) {
+																
+								ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
+							}
+							break;
+						default:
+							/* We should never reach this section !*/
+							ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle this event %d\n", evntType);
 					}
 					break;
 				case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
 					/* We are already in progress media, we can't go to any higher state except up */
 					/* Do nothing */
 					break;
+				case FTDM_CHANNEL_STATE_RESET:
+					ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
+					break;
 				default:
 					ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing ALERT/PROCEED/PROGRESS in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
 
@@ -414,6 +445,9 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
 					case FTDM_CHANNEL_STATE_UP:
 						ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Receiving more digits %s, but we already proceeded with call\n", cnStEvnt->cdPtyNmb.nmbDigits.val);
 						break;
+					case FTDM_CHANNEL_STATE_RESET:
+						ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
+						break;
 					default:
 						ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "\n", suId, suInstId, spInstId);
 						break;
@@ -477,6 +511,9 @@ void sngisdn_process_disc_ind (sngisdn_event_data_t *sngisdn_event)
 			/* This is a race condition. We just sent a DISCONNECT, on this channel */
 			/* Do nothing */
 			break;
+		case FTDM_CHANNEL_STATE_RESET:
+			ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
+			break;
 		default:
 			ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received DISCONNECT in an invalid state (%s)\n",
 						  ftdm_channel_state2str(ftdmchan->state));
@@ -531,7 +568,7 @@ void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event)
 		case FTDM_CHANNEL_STATE_DIALING:
 			/* Remote side rejected our SETUP message on outbound call */
 			if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
-				sngisdn_set_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN);
+				sngisdn_set_span_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN);
 			}
 			/* fall-through */
 		case FTDM_CHANNEL_STATE_PROCEED:
@@ -581,6 +618,9 @@ void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event)
 				/* set abort flag so that we do not transmit another release complete on this channel once FS core is done */
 			}
 			break;
+		case FTDM_CHANNEL_STATE_RESET:
+			ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
+			break;
 		default:
 			ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received RELEASE in an invalid state (%s)\n",
 							ftdm_channel_state2str(ftdmchan->state));
@@ -1050,18 +1090,91 @@ void sngisdn_process_srv_cfm (sngisdn_event_data_t *sngisdn_event)
 	return;
 }
 
+static void sngisdn_process_restart_confirm(ftdm_channel_t *ftdmchan)
+{
+	switch (ftdmchan->state) {
+		case FTDM_CHANNEL_STATE_RESET:
+			ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
+			break;
+		case FTDM_CHANNEL_STATE_DOWN:
+			/* Do nothing */
+			break;
+		default:
+			ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received RESTART CFM in an invalid state (%s)\n",
+						  ftdm_channel_state2str(ftdmchan->state));
+	}
+
+	return;
+}
+
+
 void sngisdn_process_rst_cfm (sngisdn_event_data_t *sngisdn_event)
 {
 	int16_t suId = sngisdn_event->suId;
 	int16_t dChan = sngisdn_event->dChan;
 	uint8_t ces = sngisdn_event->ces;
 	uint8_t evntType = sngisdn_event->evntType;
-
-	ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
-
-	/* Function does not require any info from ssHlEvnt struct for now */
-	/*Rst *rstEvnt = &sngisdn_event->event.rstEvnt;*/
+	uint8_t chan_no = 0;
+	Rst *rstEvnt = &sngisdn_event->event.rstEvnt;
 	
+	sngisdn_span_data_t	*signal_data = g_sngisdn_data.dchans[dChan].spans[1];
+	if (!signal_data) {
+		ftdm_log(FTDM_LOG_CRIT, "Received RESTART on unconfigured span (suId:%d)\n", suId);
+		return;
+	}
+	
+	if (!rstEvnt->rstInd.eh.pres || !rstEvnt->rstInd.rstClass.pres) {
+		ftdm_log(FTDM_LOG_DEBUG, "Receved RESTART, but Restart Indicator IE not present\n");
+		return;
+	}
+		
+	switch(rstEvnt->rstInd.rstClass.val) {
+		case IN_CL_INDCHAN: /* Indicated b-channel */
+			if (rstEvnt->chanId.eh.pres) {
+				if (rstEvnt->chanId.intType.val == IN_IT_BASIC) {
+					if (rstEvnt->chanId.infoChanSel.pres == PRSNT_NODEF) {
+						chan_no = rstEvnt->chanId.infoChanSel.val;
+					}
+				} else if (rstEvnt->chanId.intType.val == IN_IT_OTHER) {
+					if (rstEvnt->chanId.chanNmbSlotMap.pres == PRSNT_NODEF) {
+						chan_no = rstEvnt->chanId.chanNmbSlotMap.val[0];
+					}
+				}
+			}
+			if (!chan_no) {
+				ftdm_log(FTDM_LOG_CRIT, "Failed to determine channel from RESTART\n");
+				return;
+			}
+			break;
+		case IN_CL_SNGINT: /* Single interface */
+		case IN_CL_ALLINT: /* All interfaces */
+			/* In case restart class indicates all interfaces, we will duplicate
+			this event on each span associated to this d-channel in sngisdn_rcv_rst_cfm,
+			so treat it as a single interface anyway */
+			break;
+		default:
+			ftdm_log(FTDM_LOG_CRIT, "Invalid restart indicator class:%d\n", rstEvnt->rstInd.rstClass.val);
+			return;
+	}
+
+	if (chan_no) { /* For a single channel */
+		if (chan_no > ftdm_span_get_chan_count(signal_data->ftdm_span)) {
+			ftdm_log(FTDM_LOG_CRIT, "Received RESTART on invalid channel:%d\n", chan_no);
+		} else {
+			ftdm_channel_t *ftdmchan = ftdm_span_get_channel(signal_data->ftdm_span, chan_no);
+			sngisdn_process_restart_confirm(ftdmchan);
+		}
+	} else { /* for all channels */
+		ftdm_iterator_t *chaniter = NULL;
+		ftdm_iterator_t *curr = NULL;
+
+		chaniter = ftdm_span_get_chan_iterator(signal_data->ftdm_span, NULL);
+		for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
+			sngisdn_process_restart_confirm((ftdm_channel_t*)ftdm_iterator_current(curr));
+		}
+		ftdm_iterator_free(chaniter);
+	}
+
 	ftdm_log(FTDM_LOG_DEBUG, "Processing RESTART CFM (suId:%u dChan:%d ces:%d type:%d)\n", suId, dChan, ces, evntType);
 	ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
 	return;
@@ -1090,7 +1203,7 @@ void sngisdn_process_rst_ind (sngisdn_event_data_t *sngisdn_event)
 	return;
 }
 
-ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn)
+static ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn)
 {
 	sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
 	
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c
index 297c59c3b7..bb04f887ab 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c
@@ -51,72 +51,6 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan)
 	ftdm_mutex_unlock(g_sngisdn_data.ccs[signal_data->cc_id].mutex);
 
 	memset(&conEvnt, 0, sizeof(conEvnt));
-
-	conEvnt.bearCap[0].eh.pres = PRSNT_NODEF;
-	conEvnt.bearCap[0].infoTranCap.pres = PRSNT_NODEF;
-	conEvnt.bearCap[0].infoTranCap.val = sngisdn_get_infoTranCap_from_user(ftdmchan->caller_data.bearer_capability);
-
-	conEvnt.bearCap[0].codeStand0.pres = PRSNT_NODEF;
-	conEvnt.bearCap[0].codeStand0.val = IN_CSTD_CCITT;
-	conEvnt.bearCap[0].infoTranRate0.pres = PRSNT_NODEF;
-	conEvnt.bearCap[0].infoTranRate0.val = IN_ITR_64KBIT;
-	conEvnt.bearCap[0].tranMode.pres = PRSNT_NODEF;
-	conEvnt.bearCap[0].tranMode.val = IN_TM_CIRCUIT;
-
-	conEvnt.chanId.eh.pres = PRSNT_NODEF;
-	conEvnt.chanId.prefExc.pres = PRSNT_NODEF;
-	conEvnt.chanId.prefExc.val = IN_PE_EXCLSVE;
-	conEvnt.chanId.dChanInd.pres = PRSNT_NODEF;
-	conEvnt.chanId.dChanInd.val = IN_DSI_NOTDCHAN;
-	conEvnt.chanId.intIdentPres.pres = PRSNT_NODEF;
-	conEvnt.chanId.intIdentPres.val = IN_IIP_IMPLICIT;
-	conEvnt.chanId.intIdent.pres = NOTPRSNT;
-
-	if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI ||
-		ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
-		/* Trillium stack rejests lyr1Ident on BRI, but Netbricks always sends it.
-		Check with Trillium if this ever causes calls to fail in the field */
-
-		/* BRI only params */
-		conEvnt.chanId.intType.pres = PRSNT_NODEF;
-		conEvnt.chanId.intType.val = IN_IT_BASIC;
-		conEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
-		conEvnt.chanId.infoChanSel.val = ftdmchan->physical_chan_id;
-	} else {
-		/* PRI only params */
-		conEvnt.bearCap[0].usrInfoLyr1Prot.pres = PRSNT_NODEF;
-		conEvnt.bearCap[0].usrInfoLyr1Prot.val = sngisdn_get_usrInfoLyr1Prot_from_user(ftdmchan->caller_data.bearer_layer1);
-		
-		if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN &&
-			conEvnt.bearCap[0].usrInfoLyr1Prot.val == IN_UIL1_G711ULAW) {
-			
-			/* We are bridging a call from T1 */
-			conEvnt.bearCap[0].usrInfoLyr1Prot.val = IN_UIL1_G711ALAW;
-			
-		} else if (conEvnt.bearCap[0].usrInfoLyr1Prot.val == IN_UIL1_G711ALAW) {
-			
-			/* We are bridging a call from E1 */
-			conEvnt.bearCap[0].usrInfoLyr1Prot.val = IN_UIL1_G711ULAW;
-		}
-		
-		conEvnt.bearCap[0].lyr1Ident.pres = PRSNT_NODEF;
-		conEvnt.bearCap[0].lyr1Ident.val = IN_L1_IDENT;
-
-		conEvnt.chanId.intType.pres = PRSNT_NODEF;
-		conEvnt.chanId.intType.val = IN_IT_OTHER;
-		conEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
-		conEvnt.chanId.infoChanSel.val = IN_ICS_B1CHAN;
-		conEvnt.chanId.chanMapType.pres = PRSNT_NODEF;
-		conEvnt.chanId.chanMapType.val = IN_CMT_BCHAN;
-		conEvnt.chanId.nmbMap.pres = PRSNT_NODEF;
-		conEvnt.chanId.nmbMap.val = IN_NM_CHNNMB;
-		conEvnt.chanId.codeStand1.pres = PRSNT_NODEF;
-		conEvnt.chanId.codeStand1.val = IN_CSTD_CCITT;
-		conEvnt.chanId.chanNmbSlotMap.pres = PRSNT_NODEF;
-		conEvnt.chanId.chanNmbSlotMap.len = 1;
-		conEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
-	}
-
 	if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN) {
 		conEvnt.sndCmplt.eh.pres = PRSNT_NODEF;
 	}
@@ -126,6 +60,8 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan)
 	}
 	ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Outgoing call: Called No:[%s] Calling No:[%s]\n", ftdmchan->caller_data.dnis.digits, ftdmchan->caller_data.cid_num.digits);
 
+	set_chan_id_ie(ftdmchan, &conEvnt.chanId);
+	set_bear_cap_ie(ftdmchan, &conEvnt.bearCap[0]);
 	set_called_num(ftdmchan, &conEvnt.cdPtyNmb);
 	set_calling_num(ftdmchan, &conEvnt.cgPtyNmb);
 	set_calling_num2(ftdmchan, &conEvnt.cgPtyNmb2);
@@ -161,38 +97,7 @@ void sngisdn_snd_setup_ack(ftdm_channel_t *ftdmchan)
 	
 	memset(&cnStEvnt, 0, sizeof(cnStEvnt));	
 
-	cnStEvnt.chanId.eh.pres = PRSNT_NODEF;
-	cnStEvnt.chanId.prefExc.pres = PRSNT_NODEF;
-	cnStEvnt.chanId.prefExc.val = IN_PE_EXCLSVE;
-	cnStEvnt.chanId.dChanInd.pres = PRSNT_NODEF;
-	cnStEvnt.chanId.dChanInd.val = IN_DSI_NOTDCHAN;
-	cnStEvnt.chanId.intIdentPres.pres = PRSNT_NODEF;
-	cnStEvnt.chanId.intIdentPres.val = IN_IIP_IMPLICIT;
 
-	
-	if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI ||
-		ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
-
-		/* BRI only params */
-		cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
-		cnStEvnt.chanId.intType.val = IN_IT_BASIC;
-		cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
-		cnStEvnt.chanId.infoChanSel.val = ftdmchan->physical_chan_id;
-	} else {
-		cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
-		cnStEvnt.chanId.intType.val = IN_IT_OTHER;
-		cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
-		cnStEvnt.chanId.infoChanSel.val = IN_ICS_B1CHAN;
-		cnStEvnt.chanId.chanMapType.pres = PRSNT_NODEF;
-		cnStEvnt.chanId.chanMapType.val = IN_CMT_BCHAN;
-		cnStEvnt.chanId.nmbMap.pres = PRSNT_NODEF;
-		cnStEvnt.chanId.nmbMap.val = IN_NM_CHNNMB;
-		cnStEvnt.chanId.codeStand1.pres = PRSNT_NODEF;
-		cnStEvnt.chanId.codeStand1.val = IN_CSTD_CCITT;
-		cnStEvnt.chanId.chanNmbSlotMap.pres = PRSNT_NODEF;
-		cnStEvnt.chanId.chanNmbSlotMap.len = 1;
-		cnStEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
-	}
 
 	ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending SETUP ACK (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
 
@@ -221,38 +126,7 @@ void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan)
 	
 	memset(&cnStEvnt, 0, sizeof(cnStEvnt));
 	
-	cnStEvnt.chanId.eh.pres = PRSNT_NODEF;
-	cnStEvnt.chanId.prefExc.pres = PRSNT_NODEF;
-	cnStEvnt.chanId.prefExc.val = IN_PE_EXCLSVE;
-	cnStEvnt.chanId.dChanInd.pres = PRSNT_NODEF;
-	cnStEvnt.chanId.dChanInd.val = IN_DSI_NOTDCHAN;
-	cnStEvnt.chanId.intIdentPres.pres = PRSNT_NODEF;
-	cnStEvnt.chanId.intIdentPres.val = IN_IIP_IMPLICIT;
-	
-	if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI ||
-		ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
-
-		/* BRI only params */
-		cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
-		cnStEvnt.chanId.intType.val = IN_IT_BASIC;
-		cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
-		cnStEvnt.chanId.infoChanSel.val = ftdmchan->physical_chan_id;
-	} else {
-		cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
-		cnStEvnt.chanId.intType.val = IN_IT_OTHER;
-		cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
-		cnStEvnt.chanId.infoChanSel.val = IN_ICS_B1CHAN;
-		cnStEvnt.chanId.chanMapType.pres = PRSNT_NODEF;
-		cnStEvnt.chanId.chanMapType.val = IN_CMT_BCHAN;
-		cnStEvnt.chanId.nmbMap.pres = PRSNT_NODEF;
-		cnStEvnt.chanId.nmbMap.val = IN_NM_CHNNMB;
-		cnStEvnt.chanId.codeStand1.pres = PRSNT_NODEF;
-		cnStEvnt.chanId.codeStand1.val = IN_CSTD_CCITT;
-		cnStEvnt.chanId.chanNmbSlotMap.pres = PRSNT_NODEF;
-		cnStEvnt.chanId.chanNmbSlotMap.len = 1;
-		cnStEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
-	}
-
+	set_chan_id_ie(ftdmchan, &cnStEvnt.chanId);
 
 	ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending CONNECT COMPL (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
 
@@ -277,41 +151,11 @@ void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_i
 	}
 	
 	memset(&cnStEvnt, 0, sizeof(cnStEvnt));
-	
-	cnStEvnt.chanId.eh.pres = PRSNT_NODEF;
-	cnStEvnt.chanId.prefExc.pres = PRSNT_NODEF;
-	cnStEvnt.chanId.prefExc.val = IN_PE_EXCLSVE;
-	cnStEvnt.chanId.dChanInd.pres = PRSNT_NODEF;
-	cnStEvnt.chanId.dChanInd.val = IN_DSI_NOTDCHAN;
-	cnStEvnt.chanId.intIdentPres.pres = PRSNT_NODEF;
-	cnStEvnt.chanId.intIdentPres.val = IN_IIP_IMPLICIT;
-	
-	if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI ||
-		ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
-
-		/* BRI only params */
-		cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
-		cnStEvnt.chanId.intType.val = IN_IT_BASIC;
-		cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
-		cnStEvnt.chanId.infoChanSel.val = ftdmchan->physical_chan_id;
-	} else {
-		cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
-		cnStEvnt.chanId.intType.val = IN_IT_OTHER;
-		cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
-		cnStEvnt.chanId.infoChanSel.val = IN_ICS_B1CHAN;
-		cnStEvnt.chanId.chanMapType.pres = PRSNT_NODEF;
-		cnStEvnt.chanId.chanMapType.val = IN_CMT_BCHAN;
-		cnStEvnt.chanId.nmbMap.pres = PRSNT_NODEF;
-		cnStEvnt.chanId.nmbMap.val = IN_NM_CHNNMB;
-		cnStEvnt.chanId.codeStand1.pres = PRSNT_NODEF;
-		cnStEvnt.chanId.codeStand1.val = IN_CSTD_CCITT;
-		cnStEvnt.chanId.chanNmbSlotMap.pres = PRSNT_NODEF;
-		cnStEvnt.chanId.chanNmbSlotMap.len = 1;
-		cnStEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
-	}
 
+	set_chan_id_ie(ftdmchan, &cnStEvnt.chanId);
 	set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind);
 	set_facility_ie(ftdmchan, &cnStEvnt.facilityStr);
+	
 	ftdm_call_clear_data(&ftdmchan->caller_data);
 
 	ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending PROCEED (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
@@ -397,39 +241,8 @@ void sngisdn_snd_connect(ftdm_channel_t *ftdmchan)
 	}
 	
 	memset(&cnStEvnt, 0, sizeof(cnStEvnt));
-
-	cnStEvnt.chanId.eh.pres = PRSNT_NODEF;
-	cnStEvnt.chanId.prefExc.pres = PRSNT_NODEF;
-	cnStEvnt.chanId.prefExc.val = IN_PE_EXCLSVE;
-	cnStEvnt.chanId.dChanInd.pres = PRSNT_NODEF;
-	cnStEvnt.chanId.dChanInd.val = IN_DSI_NOTDCHAN;
-	cnStEvnt.chanId.intIdentPres.pres = PRSNT_NODEF;
-	cnStEvnt.chanId.intIdentPres.val = IN_IIP_IMPLICIT;
 	
-	if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI ||
-		ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
-
-		/* BRI only params */
-		cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
-		cnStEvnt.chanId.intType.val = IN_IT_BASIC;
-		cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
-		cnStEvnt.chanId.infoChanSel.val = ftdmchan->physical_chan_id;
-	} else {
-		cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
-		cnStEvnt.chanId.intType.val = IN_IT_OTHER;
-		cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
-		cnStEvnt.chanId.infoChanSel.val = IN_ICS_B1CHAN;
-		cnStEvnt.chanId.chanMapType.pres = PRSNT_NODEF;
-		cnStEvnt.chanId.chanMapType.val = IN_CMT_BCHAN;
-		cnStEvnt.chanId.nmbMap.pres = PRSNT_NODEF;
-		cnStEvnt.chanId.nmbMap.val = IN_NM_CHNNMB;
-		cnStEvnt.chanId.codeStand1.pres = PRSNT_NODEF;
-		cnStEvnt.chanId.codeStand1.val = IN_CSTD_CCITT;
-		cnStEvnt.chanId.chanNmbSlotMap.pres = PRSNT_NODEF;
-		cnStEvnt.chanId.chanNmbSlotMap.len = 1;
-		cnStEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
-	}
-
+	set_chan_id_ie(ftdmchan, &cnStEvnt.chanId);
 	set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind);
 	set_facility_ie(ftdmchan, &cnStEvnt.facilityStr);
 	ftdm_call_clear_data(&ftdmchan->caller_data);
@@ -563,6 +376,7 @@ void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan)
 	}
 	return;
 }
+
 void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare)
 {
 	RelEvnt relEvnt;
@@ -618,6 +432,24 @@ void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare)
 	return;
 }
 
+void sngisdn_snd_restart(ftdm_channel_t *ftdmchan)
+{
+	Rst rstEvnt;
+	sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
+
+	memset(&rstEvnt, 0, sizeof(rstEvnt));
+
+	set_chan_id_ie(ftdmchan, &rstEvnt.chanId);
+	set_restart_ind_ie(ftdmchan, &rstEvnt.rstInd);
+	
+	ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending RESTART (suId:%d dchan:%d ces:%d)\n", signal_data->cc_id, signal_data->dchan_id, CES_MNGMNT);
+
+	if (sng_isdn_restart_request(signal_data->cc_id, &rstEvnt, signal_data->dchan_id, CES_MNGMNT, IN_SND_RST)) {
+		ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused RESTART request\n");
+	}
+	return;
+}
+
 
 /* We received an incoming frame on the d-channel, send data to the stack */
 void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len)
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c
index af180d1f7c..4b04fb065e 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c
@@ -630,8 +630,9 @@ void sngisdn_rcv_rst_cfm (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces
 
 	ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
 
+
 	ftdm_log(FTDM_LOG_INFO, "Received RESTART CFM (dChan:%d ces:%u type:%u)\n", dChan, ces, evntType);
-	
+
 	/* Enqueue the event to each span within the dChan */
 	for(i=1; i<=g_sngisdn_data.dchans[dChan].num_spans; i++) {
 		signal_data = g_sngisdn_data.dchans[dChan].spans[i];
@@ -725,14 +726,25 @@ void sngisdn_rcv_q931_ind(InMngmt *status)
 			ftdmspan = signal_data->ftdm_span;
 			
 			if (status->t.usta.alarm.event == LCM_EVENT_UP) {
+				uint32_t chan_no = status->t.usta.evntParm[2];
 				ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n",
 						 status->t.usta.suId,
 								DECODE_LCM_CATEGORY(status->t.usta.alarm.category),
 								DECODE_LCM_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event,
 								DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause);
-				
-				sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_UP);
-				sngisdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_UP);
+
+				if (chan_no) {
+					ftdm_channel_t *ftdmchan = ftdm_span_get_channel(ftdmspan, chan_no);
+					if (ftdmchan) {
+						sngisdn_set_chan_sig_status(ftdmchan, FTDM_SIG_STATE_UP);
+						sngisdn_set_chan_avail_rate(ftdmchan, SNGISDN_AVAIL_UP);
+					} else {
+						ftdm_log(FTDM_LOG_CRIT, "stack alarm event on invalid channel :%d\n", chan_no);
+					}
+				} else {
+					sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_UP);
+					sngisdn_set_span_avail_rate(ftdmspan, SNGISDN_AVAIL_UP);
+				}
 			} else {
 				ftdm_log(FTDM_LOG_WARNING, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n",
 						 		status->t.usta.suId,
@@ -741,7 +753,7 @@ void sngisdn_rcv_q931_ind(InMngmt *status)
 								DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause);
 				
 				sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_DOWN);
-				sngisdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_PWR_SAVING);
+				sngisdn_set_span_avail_rate(ftdmspan, SNGISDN_AVAIL_PWR_SAVING);
 			}
 		}
 		break;
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c
index 76d11d6d34..28768a1f09 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c
@@ -136,19 +136,25 @@ ftdm_status_t get_ftdmchan_by_spInstId(int16_t cc_id, uint32_t spInstId, sngisdn
 	return FTDM_SUCCESS;
 }
 
-ftdm_status_t sngisdn_set_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail)
+ftdm_status_t sngisdn_set_chan_avail_rate(ftdm_channel_t *chan, sngisdn_avail_t avail)
 {
-	if (span->trunk_type == FTDM_TRUNK_BRI ||
-		span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
+	if (FTDM_SPAN_IS_BRI(chan->span)) {
+		ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Setting availability rate to:%d\n", avail);
+		chan->availability_rate = avail;
+	}
+	return FTDM_SUCCESS;
+}
 
+ftdm_status_t sngisdn_set_span_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail)
+{
+	if (FTDM_SPAN_IS_BRI(span)) {
 		ftdm_iterator_t *chaniter = NULL;
 		ftdm_iterator_t *curr = NULL;
 
-
 		chaniter = ftdm_span_get_chan_iterator(span, NULL);
 		for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
 			ftdm_log_chan(((ftdm_channel_t*)ftdm_iterator_current(curr)), FTDM_LOG_DEBUG, "Setting availability rate to:%d\n", avail);
-			((ftdm_channel_t*)ftdm_iterator_current(curr))->availability_rate = avail;
+			sngisdn_set_chan_avail_rate(((ftdm_channel_t*)ftdm_iterator_current(curr)), avail);
 		}
 		ftdm_iterator_free(chaniter);
 	}
@@ -676,7 +682,6 @@ ftdm_status_t set_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad)
 	return FTDM_SUCCESS;
 }
 
-
 ftdm_status_t set_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr)
 {
 	ftdm_status_t status;
@@ -789,6 +794,93 @@ ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_s
 	return FTDM_SUCCESS;
 }
 
+ftdm_status_t set_chan_id_ie(ftdm_channel_t *ftdmchan, ChanId *chanId)
+{
+	if (!ftdmchan) {
+		return FTDM_SUCCESS;
+	}
+	chanId->eh.pres = PRSNT_NODEF;
+	chanId->prefExc.pres = PRSNT_NODEF;
+	chanId->prefExc.val = IN_PE_EXCLSVE;
+	chanId->dChanInd.pres = PRSNT_NODEF;
+	chanId->dChanInd.val = IN_DSI_NOTDCHAN;
+	chanId->intIdentPres.pres = PRSNT_NODEF;
+	chanId->intIdentPres.val = IN_IIP_IMPLICIT;
+
+	if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI ||
+		   ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
+
+		/* BRI only params */
+		chanId->intType.pres = PRSNT_NODEF;
+		chanId->intType.val = IN_IT_BASIC;
+		chanId->infoChanSel.pres = PRSNT_NODEF;
+		chanId->infoChanSel.val = ftdmchan->physical_chan_id;
+	} else {
+		chanId->intType.pres = PRSNT_NODEF;
+		chanId->intType.val = IN_IT_OTHER;
+		chanId->infoChanSel.pres = PRSNT_NODEF;
+		chanId->infoChanSel.val = IN_ICS_B1CHAN;
+		chanId->chanMapType.pres = PRSNT_NODEF;
+		chanId->chanMapType.val = IN_CMT_BCHAN;
+		chanId->nmbMap.pres = PRSNT_NODEF;
+		chanId->nmbMap.val = IN_NM_CHNNMB;
+		chanId->codeStand1.pres = PRSNT_NODEF;
+		chanId->codeStand1.val = IN_CSTD_CCITT;
+		chanId->chanNmbSlotMap.pres = PRSNT_NODEF;
+		chanId->chanNmbSlotMap.len = 1;
+		chanId->chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
+	}
+	return FTDM_SUCCESS;
+}
+
+ftdm_status_t set_bear_cap_ie(ftdm_channel_t *ftdmchan, BearCap *bearCap)
+{
+	sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
+	
+	bearCap->eh.pres = PRSNT_NODEF;
+	bearCap->infoTranCap.pres = PRSNT_NODEF;
+	bearCap->infoTranCap.val = sngisdn_get_infoTranCap_from_user(ftdmchan->caller_data.bearer_capability);
+
+	bearCap->codeStand0.pres = PRSNT_NODEF;
+	bearCap->codeStand0.val = IN_CSTD_CCITT;
+	bearCap->infoTranRate0.pres = PRSNT_NODEF;
+	bearCap->infoTranRate0.val = IN_ITR_64KBIT;
+	bearCap->tranMode.pres = PRSNT_NODEF;
+	bearCap->tranMode.val = IN_TM_CIRCUIT;
+
+	if (!FTDM_SPAN_IS_BRI(ftdmchan->span)) {
+		/* Trillium stack rejests lyr1Ident on BRI, but Netbricks always sends it.
+		Check with Trillium if this ever causes calls to fail in the field */
+
+		/* PRI only params */
+		bearCap->usrInfoLyr1Prot.pres = PRSNT_NODEF;
+		bearCap->usrInfoLyr1Prot.val = sngisdn_get_usrInfoLyr1Prot_from_user(ftdmchan->caller_data.bearer_layer1);
+
+		if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN &&
+			bearCap->usrInfoLyr1Prot.val == IN_UIL1_G711ULAW) {
+
+			/* We are bridging a call from T1 */
+			bearCap->usrInfoLyr1Prot.val = IN_UIL1_G711ALAW;
+
+		} else if (bearCap->usrInfoLyr1Prot.val == IN_UIL1_G711ALAW) {
+
+			/* We are bridging a call from E1 */
+			bearCap->usrInfoLyr1Prot.val = IN_UIL1_G711ULAW;
+		}
+
+		bearCap->lyr1Ident.pres = PRSNT_NODEF;
+		bearCap->lyr1Ident.val = IN_L1_IDENT;
+	}
+	return FTDM_SUCCESS;
+}
+
+ftdm_status_t set_restart_ind_ie(ftdm_channel_t *ftdmchan, RstInd *rstInd)
+{
+	rstInd->eh.pres = PRSNT_NODEF;
+	rstInd->rstClass.pres = PRSNT_NODEF;
+	rstInd->rstClass.val = IN_CL_INDCHAN;
+	return FTDM_SUCCESS;
+}
 
 void sngisdn_t3_timeout(void* p_sngisdn_info)
 {
diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h
index cc32d66bdd..f8f69abc71 100644
--- a/libs/freetdm/src/include/freetdm.h
+++ b/libs/freetdm/src/include/freetdm.h
@@ -314,7 +314,8 @@ typedef enum {
 	FTDM_SIGEVENT_RELEASED, /*!< Channel is completely released and available */
 	FTDM_SIGEVENT_UP, /*!< Outgoing call has been answered */
 	FTDM_SIGEVENT_FLASH, /*!< Flash event  (typically on-hook/off-hook for analog devices) */
- 	FTDM_SIGEVENT_PROCEED, /*!< Outgoing call got a response */
+	FTDM_SIGEVENT_PROCEED, /*!< Outgoing call got a response */
+	FTDM_SIGEVENT_RINGING, /*!< Remote side is in ringing state */
 	FTDM_SIGEVENT_PROGRESS, /*!< Outgoing call is making progress */
 	FTDM_SIGEVENT_PROGRESS_MEDIA, /*!< Outgoing call is making progress and there is media available */
 	FTDM_SIGEVENT_ALARM_TRAP, /*!< Hardware alarm ON */
@@ -327,7 +328,7 @@ typedef enum {
 	FTDM_SIGEVENT_FACILITY, /* !< In call facility event */
 	FTDM_SIGEVENT_INVALID
 } ftdm_signal_event_t;
-#define SIGNAL_STRINGS "START", "STOP", "RELEASED", "UP", "FLASH", "PROCEED", "PROGRESS", \
+#define SIGNAL_STRINGS "START", "STOP", "RELEASED", "UP", "FLASH", "PROCEED", "RINGING", "PROGRESS", \
 		"PROGRESS_MEDIA", "ALARM_TRAP", "ALARM_CLEAR", \
 		"COLLECTED_DIGIT", "ADD_CALL", "RESTART", "SIGSTATUS_CHANGED", "COLLISION", "MSG", "INVALID"
 
@@ -702,6 +703,14 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_hangup(const char *file, const char
 /*! \brief Hangup the call with cause recording the source code point where it was called (see ftdm_channel_call_hangup_with_cause for an easy to use macro) */
 FT_DECLARE(ftdm_status_t) _ftdm_channel_call_hangup_with_cause(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_call_cause_t);
 
+/*! \brief Reset the channel */
+#define ftdm_channel_reset(ftdmchan) _ftdm_channel_reset(__FILE__, __FUNCTION__, __LINE__, (ftdmchan))
+
+/*! \brief Reset the channel (see _ftdm_channel_reset for an easy to use macro) 
+ *  \note if there was a call on this channel, call will be cleared without any notifications to the user
+ */
+FT_DECLARE(ftdm_status_t) _ftdm_channel_reset(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan);
+
 /*! \brief Put a call on hold (if supported by the signaling stack) */
 #define ftdm_channel_call_hold(ftdmchan) _ftdm_channel_call_hold(__FILE__, __FUNCTION__, __LINE__, (ftdmchan))
 
@@ -741,6 +750,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_set_sig_status(ftdm_span_t *span, ftdm_signa
 /*! \brief Get span signaling status (ie: whether protocol layer is up or down) */
 FT_DECLARE(ftdm_status_t) ftdm_span_get_sig_status(ftdm_span_t *span, ftdm_signaling_status_t *status);
 
+
 /*! 
  * \brief Set user private data in the channel
  *
diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h
index deabafd537..9222da3a42 100644
--- a/libs/freetdm/src/include/private/ftdm_core.h
+++ b/libs/freetdm/src/include/private/ftdm_core.h
@@ -599,7 +599,6 @@ FT_DECLARE(void) ftdm_channel_rotate_tokens(ftdm_channel_t *ftdmchan);
 FT_DECLARE(int) ftdm_load_module(const char *name);
 FT_DECLARE(int) ftdm_load_module_assume(const char *name);
 FT_DECLARE(int) ftdm_vasprintf(char **ret, const char *fmt, va_list ap);
-FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan);
 
 FT_DECLARE(ftdm_status_t) ftdm_span_close_all(void);
 FT_DECLARE(ftdm_status_t) ftdm_channel_open_chan(ftdm_channel_t *ftdmchan);
diff --git a/libs/freetdm/src/include/private/ftdm_types.h b/libs/freetdm/src/include/private/ftdm_types.h
index 313044abc4..f03c060e5a 100644
--- a/libs/freetdm/src/include/private/ftdm_types.h
+++ b/libs/freetdm/src/include/private/ftdm_types.h
@@ -228,12 +228,13 @@ typedef enum {
 	FTDM_CHANNEL_STATE_HANGUP,
 	FTDM_CHANNEL_STATE_HANGUP_COMPLETE,
 	FTDM_CHANNEL_STATE_IN_LOOP,
+	FTDM_CHANNEL_STATE_RESET,
 	FTDM_CHANNEL_STATE_INVALID
 } ftdm_channel_state_t;
 #define CHANNEL_STATE_STRINGS "DOWN", "HOLD", "SUSPENDED", "DIALTONE", "COLLECT", \
 		"RING", "RINGING", "BUSY", "ATTN", "GENRING", "DIALING", "GET_CALLERID", "CALLWAITING", \
 		"RESTART", "PROCEED", "PROGRESS", "PROGRESS_MEDIA", "UP", "IDLE", "TERMINATING", "CANCEL", \
-		"HANGUP", "HANGUP_COMPLETE", "IN_LOOP", "INVALID"
+		"HANGUP", "HANGUP_COMPLETE", "IN_LOOP", "RESET", "INVALID"
 FTDM_STR2ENUM_P(ftdm_str2ftdm_channel_state, ftdm_channel_state2str, ftdm_channel_state_t)
 
 typedef enum {