From cd2d67ace17b036fcdc06e2a81a0dd0021c11c92 Mon Sep 17 00:00:00 2001 From: James Date: Fri, 13 Apr 2012 17:26:48 -0400 Subject: [PATCH] freetdm: fixed group block/unblock state dead lock when signal link is down and recovered later To re-produce this bug: 1. do CGB on one side 2. unplug signaling link cable 3. plug signaling link cable back 4. do CGU on the blocking side 5. cic state stay in RESTART for ever Fix this problem by sending cic to SUSPENDED state after receiving/sending CGU message --- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c | 36 +++++-------------- .../ftmod_sangoma_ss7_handle.c | 7 ++-- 2 files changed, 14 insertions(+), 29 deletions(-) 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 3f1a03f4d8..df872b260c 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 @@ -35,7 +35,7 @@ * */ -#if 0 +#if 0 #define SMG_RELAY_DBG #endif @@ -1332,7 +1332,7 @@ static ftdm_status_t handle_show_status(ftdm_stream_handle_t *stream, int span, } #ifdef SMG_RELAY_DBG - stream->write_function(stream," blk_flag=%x | ckt_flag=%x | chan_flag=%x", ss7_info->blk_flags, ss7_info->ckt_flags, ftdmchan->flags); + stream->write_function(stream," | blk_flag=%x | ckt_flag=%x", ss7_info->blk_flags, ss7_info->ckt_flags); #endif stream->write_function(stream, "\n"); } /* if ( hole, sig, voice) */ @@ -1374,36 +1374,26 @@ static ftdm_status_t handle_tx_blo(ftdm_stream_handle_t *stream, int span, int c } if ((ftdmchan->physical_span_id == lspan) && (ftdmchan->physical_chan_id == lchan)) { - /* now that we have the right channel...put a lock on it so no-one else can use it */ ftdm_mutex_lock(ftdmchan->mutex); /* check if there is a pending state change|give it a bit to clear */ if (check_for_state_change(ftdmchan)) { SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", ss7_info->circuit->cic); - /* check if we need to die */ ftdm_assert(0, "State change not completed\n"); - /* unlock the channel again before we exit */ ftdm_mutex_unlock(ftdmchan->mutex); - /* move to the next channel */ continue; } else { - /* throw the ckt block flag */ sngss7_set_ckt_blk_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX); - - /* set the channel to suspended state */ ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); } - - /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + } - } /* if ( span and chan) */ + } - } /* if ( cic != 0) */ - - /* go the next circuit */ x++; - } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */ + } handle_show_blocks(stream, span, chan, verbose); @@ -1440,33 +1430,22 @@ static ftdm_status_t handle_tx_ubl(ftdm_stream_handle_t *stream, int span, int c } if ((ftdmchan->physical_span_id == lspan) && (ftdmchan->physical_chan_id == lchan)) { - /* now that we have the right channel...put a lock on it so no-one else can use it */ ftdm_mutex_lock(ftdmchan->mutex); /* check if there is a pending state change|give it a bit to clear */ if (check_for_state_change(ftdmchan)) { SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", ss7_info->circuit->cic); - /* check if we need to die */ ftdm_assert(0, "State change not completed\n"); - /* unlock the channel again before we exit */ ftdm_mutex_unlock(ftdmchan->mutex); - /* move to the next channel */ continue; } else { - /* throw the ckt block flag */ sngss7_set_ckt_blk_flag(ss7_info, FLAG_CKT_MN_UNBLK_TX); - - /* clear the block flag */ sngss7_clear_ckt_blk_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX); - - /* check group blocking */ sngss7_clear_ckt_blk_flag(ss7_info, FLAG_GRP_MN_BLOCK_TX); - /* set the channel to suspended state */ ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); } - /* unlock the channel again before we exit */ ftdm_mutex_unlock(ftdmchan->mutex); } @@ -1812,6 +1791,8 @@ static ftdm_status_t handle_tx_cgb(ftdm_stream_handle_t *stream, int span, int c /* throw the grp maint. block flag */ sngss7_set_ckt_blk_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX); + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); + /* bring the sig status down */ sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_DOWN); @@ -1945,6 +1926,7 @@ static ftdm_status_t handle_tx_cgu(ftdm_stream_handle_t *stream, int span, int c /* bring the sig status up */ sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_UP); + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); /* if this is the first channel in the range */ if (!main_chan) { 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 04dff6ee5e..d0d6c32867 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 @@ -1181,11 +1181,12 @@ ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ break; /**************************************************************************/ case SIT_STA_CGBRSP: /* mntc. oriented CGB response */ - /*handle_cgb_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);*/ + SS7_INFO(" Rx CGBA \n"); break; /**************************************************************************/ case SIT_STA_CGURSP: /* mntc. oriented CGU response */ /*SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));*/ + SS7_INFO(" Rx CGUA \n"); break; /**************************************************************************/ case SIT_STA_GRSREQ: /* circuit group reset request */ @@ -2510,6 +2511,7 @@ ftdm_status_t handle_cgb_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ /* bring the sig status down */ sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_DOWN); + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); /* unlock the channel again before we exit */ ftdm_mutex_unlock(ftdmchan->mutex); @@ -2665,7 +2667,8 @@ ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ if (sngss7_channel_status_clear(sngss7_info)) { sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_UP); } - + + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); ftdm_mutex_unlock(ftdmchan->mutex); /* update the bit and byte counter*/