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
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;
/* 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) {
/**************************************************************************/
/* 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);
/* 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);
/* 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);
/* 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;
/**************************************************************************/
/**************************************************************************/
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);
}
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);
}
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);
}
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);
+ }
}
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);
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 );
#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
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)
{
int32_t txdrops;
int32_t rxdrops;
ftdm_usrmsg_t *usrmsg;
+ ftdm_time_t last_state_change_time;
};
struct ftdm_span {