]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
Fixed the exception condition - trigger reset
authorJames Zhang <jzhang@sangoma.com>
Thu, 1 Dec 2011 08:16:59 +0000 (03:16 -0500)
committerJames Zhang <jzhang@sangoma.com>
Thu, 1 Dec 2011 08:16:59 +0000 (03:16 -0500)
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
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c
libs/freetdm/src/include/private/ftdm_core.h

index d3f99f6074bef9363db46b4a96828dd2d7dc8bb1..6572ab75a483d2030a81d050b49dc152c571c47f 100644 (file)
@@ -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;
 
index 1b24b9f8da6bbdd73ab71869086865e15dec7f47..2c8f5172b9795c18dd153ad16d8c8b270b49b1c8 100644 (file)
@@ -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) {
                                /**************************************************************************/
index e7cc9db5738a3b98b3fd25b57b77f19fac35c5b4..295d1270644da3c325ade8cf3c816bceefb9957d 100644 (file)
@@ -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);
index 1b7af43bc8bb8502b75d5265430ccbb38d22c8a0..4c6992e61fbf74c9146e880dc8cc979c788e49a4 100644 (file)
@@ -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 );
index 697da825cbf1918c041e096771ca57d7d9cbc0fb..631dadf007182902a3568f76b3a94a143d211782 100644 (file)
@@ -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
index eb1eb129610b55b44086ec731939ca71793d27ae..7696974807485fb40cee132279ccc351a70d665a 100644 (file)
@@ -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)
 {
index 65ffad677ce5e5136decf6d899aaed1e4451931c..f27be789e2c36661d919d071da3c3443d19e1207 100644 (file)
@@ -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 {