提交 cd2d67ac authored 作者: James's avatar James

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
上级 a796c684
......@@ -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) {
......
......@@ -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*/
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论