From 7b83dd4c968f9769c58b8ef89a83eb55a8218df3 Mon Sep 17 00:00:00 2001 From: James Zhang Date: Thu, 1 Dec 2011 03:16:59 -0500 Subject: [PATCH] Fixed the exception condition - trigger reset used to clear ckt_flags, this was wrong. if ctk_flags are blindly cleard a PAUSE might be cleared. changed the code to clear only TX RESET and try to reset again. Release Collision If we get out of sync with other side we must reset the circuit. This condition occoured at 1+3 test box Local Management Block Its possible for stack to send us a BLO indicating to us that we are local blocked. This case never worked and we would get stuck there forever. If we never manaully sent a LOCAL block, the BLO from the stack will be acked and then unblocked. This condition occoured at 1+3 test box --- libs/freetdm/src/ftdm_state.c | 1 + .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c | 2 +- .../ftmod_sangoma_ss7_handle.c | 19 +++---- .../ftmod_sangoma_ss7_main.c | 24 ++++++--- .../ftmod_sangoma_ss7_main.h | 11 ++++- .../ftmod_sangoma_ss7_support.c | 49 +++++++++++++++++++ libs/freetdm/src/include/private/ftdm_core.h | 1 + 7 files changed, 89 insertions(+), 18 deletions(-) diff --git a/libs/freetdm/src/ftdm_state.c b/libs/freetdm/src/ftdm_state.c index d3f99f6074..6572ab75a4 100644 --- a/libs/freetdm/src/ftdm_state.c +++ b/libs/freetdm/src/ftdm_state.c @@ -87,6 +87,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_complete_state(const char *file, const c ftdm_assert(!fchan->history[hindex].end_time, "End time should be zero!\n"); fchan->history[hindex].end_time = ftdm_current_time_in_ms(); + fchan->last_state_change_time = ftdm_current_time_in_ms(); fchan->state_status = FTDM_STATE_STATUS_COMPLETED; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c index 1b24b9f8da..2c8f5172b9 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c @@ -1634,7 +1634,7 @@ static ftdm_status_t handle_tx_rsc(ftdm_stream_handle_t *stream, int span, int c /* throw the reset flag */ sngss7_set_ckt_flag (sngss7_info, FLAG_LOCAL_REL); sngss7_clear_ckt_flag (sngss7_info, FLAG_REMOTE_REL); - sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX); + sngss7_tx_reset_restart(sngss7_info); switch (ftdmchan->state) { /**************************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c index e7cc9db573..295d127064 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c @@ -327,9 +327,8 @@ handle_glare: /* throw the TX reset flag */ if (!sngss7_tx_reset_status_pending(sngss7_info)) { - sngss7_info->ckt_flags=0; + sngss7_tx_reset_restart(sngss7_info); sngss7_set_ckt_flag (sngss7_info, FLAG_REMOTE_REL); - sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX); /* go to RESTART */ ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART); @@ -401,9 +400,8 @@ ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circ /* throw the TX reset flag */ if (!sngss7_tx_reset_status_pending(sngss7_info)) { - sngss7_info->ckt_flags=0; + sngss7_tx_reset_restart(sngss7_info); sngss7_set_ckt_flag (sngss7_info, FLAG_REMOTE_REL); - sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX); /* go to RESTART */ ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART); @@ -668,9 +666,8 @@ ftdm_status_t handle_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circ /* throw the TX reset flag */ if (!sngss7_tx_reset_status_pending(sngss7_info)) { - sngss7_info->ckt_flags=0; + sngss7_tx_reset_restart(sngss7_info); sngss7_set_ckt_flag (sngss7_info, FLAG_REMOTE_REL); - sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX); /* go to RESTART */ ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART); @@ -772,6 +769,10 @@ ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ /* send out the release complete */ ft_to_sngss7_rlc (ftdmchan); + } else { + SS7_DEBUG_CHAN(ftdmchan, "Collision of REL messages - resetting state.\n", " "); + ft_to_sngss7_rlc (ftdmchan); + goto rel_ind_reset; } break; /**************************************************************************/ @@ -794,11 +795,11 @@ ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ /**************************************************************************/ default: +rel_ind_reset: /* throw the TX reset flag */ if (!sngss7_tx_reset_status_pending(sngss7_info)) { - sngss7_info->ckt_flags=0; - sngss7_set_ckt_flag (sngss7_info, FLAG_REMOTE_REL); - sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX); + sngss7_set_ckt_flag (sngss7_info, FLAG_REMOTE_REL); + sngss7_tx_reset_restart(sngss7_info); /* go to RESTART */ ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c index 1b7af43bc8..4c6992e61f 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c @@ -1358,6 +1358,8 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) } if (sngss7_tx_block_status_clear(sngss7_info) && !skip_unblock) { + sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX_DN); + sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX); ft_to_sngss7_ubl(ftdmchan); } @@ -1434,6 +1436,8 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) if (sngss7_tx_block_status_clear(sngss7_info)) { /* send a ubl */ + sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX_DN); + sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX); ft_to_sngss7_ubl(ftdmchan); } @@ -1446,13 +1450,19 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_LC_BLOCK_RX flag %s\n", ""); /* send a BLA */ - /*ft_to_sngss7_bla(ftdmchan);*/ + ft_to_sngss7_bla(ftdmchan); /* throw the done flag */ sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX_DN); - - /* bring the sig status down */ - sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_DOWN); + + if (sngss7_tx_block_status_clear(sngss7_info)) { + sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX_DN); + sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX); + ft_to_sngss7_ubl(ftdmchan); + } else { + /* bring the sig status down */ + sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_DOWN); + } } @@ -1468,7 +1478,7 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_UNBLK_RX); /* send a uba */ - /*ft_to_sngss7_uba(ftdmchan);*/ + ft_to_sngss7_uba(ftdmchan); if (sngss7_channel_status_clear(sngss7_info)) { sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_UP); @@ -1530,14 +1540,14 @@ suspend_goto_last: if (ftdmchan->last_state == FTDM_CHANNEL_STATE_UP) { /* proceed to UP */ } else if (!sngss7_channel_status_clear(sngss7_info)) { - SS7_DEBUG_CHAN(ftdmchan,"Channel opted to stay in RESTART due to blocks!%s\n", ""); + SS7_DEBUG_CHAN(ftdmchan,"Channel opted to stay in RESTART due to reset/blocks!%s\n", ""); SS7_DEBUG_CHAN(ftdmchan,"Current flags: ckt=0x%X, blk=0x%X, circuit->flag=0x%X\n", sngss7_info->ckt_flags, sngss7_info->blk_flags, sngss7_info->circuit->flags ); goto suspend_goto_restart; } else { - SS7_DEBUG_CHAN(ftdmchan,"Channel signaling is up proceed to DOWN! [Last State=%i]\n", ftdmchan->last_state); + SS7_DEBUG_CHAN(ftdmchan,"Channel signaling is up proceed to DOWN! [Last State=%s]\n", ftdm_channel_state2str(ftdmchan->last_state)); SS7_DEBUG_CHAN(ftdmchan,"Current flags: ckt=0x%X, blk=0x%X, circuit->flag=0x%X\n", sngss7_info->ckt_flags, sngss7_info->blk_flags, sngss7_info->circuit->flags ); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h index 697da825cb..631dadf007 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h @@ -1071,7 +1071,16 @@ if (ftdmchan->state == new_state) { \ #define sngss7_tx_reset_status_pending(obj) (sngss7_test_ckt_flag(obj, (FLAG_RESET_TX)) || sngss7_test_ckt_flag(obj, (FLAG_GRP_RESET_TX))) -#define sngss7_channel_status_clear(obj) ((sngss7_block_status_clear(obj)) && (sngss7_reset_status_clear(obj))) +#define sngss7_channel_status_clear(obj) ((sngss7_block_status_clear(obj)) && \ + (sngss7_reset_status_clear(obj)) && \ + (!sngss7_test_ckt_flag((obj),FLAG_INFID_PAUSED))) + +#define sngss7_tx_reset_restart(obj) do { clear_tx_grs_flags((obj)); \ + clear_tx_grs_data((obj)); \ + clear_tx_rsc_flags((obj)); \ + sngss7_set_ckt_flag((obj), (FLAG_RESET_TX)); \ + } while (0); + #ifdef SMG_RELAY_DBG diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c index eb1eb12961..7696974807 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c @@ -2098,6 +2098,55 @@ void sngss7_set_sig_status(sngss7_chan_data_t *sngss7_info, ftdm_signaling_statu return; } +#if 0 +ftdm_status_t check_for_invalid_states(ftdm_channel_t *ftmchan) +{ + sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; + + if (!sngss7_info) { + SS7_WARN_CHAN(ftdmchan, "Found ftdmchan with no sig module data!%s\n", " "); + return FTDM_FAIL; + } + + if (sngss7_test_flag(sngss7_intf, SNGSS7_PAUSED)) { + return FTDM_SUCCESS; + } + + switch (ftdmchan->state) { + case UP: + case DOWN: + return FTDM_SUCCESS; + + default: + if ((ftdm_current_time_in_ms() - ftdmchan->last_state_change_time) > 30000) { + SS7_WARN_CHAN(ftdmchan, "Circuite in state=%s too long - resetting!%s\n", + ftdm_channel_state2str(ftdmchan->state)); + + ftdm_channel_lock(ftdmchan); + + if (sngss7_channel_status_clear(sngss7_info)) { + sngss7_tx_reset_restart(sngss7_info); + + if (ftdmchan->state == FTDM_CHANNEL_STATE_RESTART) { + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); + } else { + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART); + } + } else { + + } + + + + ftdm_channel_unlock(ftdmchan); + } + } + + return FTDM_SUCCESS; +} +#endif + + /******************************************************************************/ ftdm_status_t check_for_reconfig_flag(ftdm_span_t *ftdmspan) { diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h index 65ffad677c..f27be789e2 100644 --- a/libs/freetdm/src/include/private/ftdm_core.h +++ b/libs/freetdm/src/include/private/ftdm_core.h @@ -469,6 +469,7 @@ struct ftdm_channel { int32_t txdrops; int32_t rxdrops; ftdm_usrmsg_t *usrmsg; + ftdm_time_t last_state_change_time; }; struct ftdm_span {