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
This commit is contained in:
James 2012-04-13 17:26:48 -04:00
parent a796c6849c
commit cd2d67ace1
2 changed files with 14 additions and 29 deletions

View File

@ -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) {

View File

@ -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*/