freetdm: ss7 - work on glare handling

This commit is contained in:
Konrad Hammel 2010-09-01 16:52:37 -04:00
parent cd0cc2e4a3
commit 16d918d025
3 changed files with 117 additions and 37 deletions

View File

@ -99,7 +99,11 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
SS7_ASSERT;
};
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx IAM\n");
if (sngss7_info->glare.spInstId > 0) {
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx IAM (glare detected on circuit)\n");
} else {
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx IAM\n");
}
/* check if the circuit has a remote block */
if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) ||
@ -208,11 +212,36 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
break;
/**************************************************************************/
case (FTDM_CHANNEL_STATE_DIALING):
case (FTDM_CHANNEL_STATE_TERMINATING):
case (FTDM_CHANNEL_STATE_HANGUP):
case (FTDM_CHANNEL_STATE_HANGUP_COMPLETE):
SS7_INFO_CHAN(ftdmchan, "Got IAM on channel in %s state...glare!\n", ftdm_channel_state2str (ftdmchan->state));
/* save the info so that we can use it later on */
sngss7_info->glare.spInstId = spInstId;
sngss7_info->glare.circuit = circuit;
memcpy(&sngss7_info->glare.iam, siConEvnt, sizeof(*siConEvnt));
if (!(sngss7_test_flag(sngss7_info, FLAG_GLARE))) {
/* glare, throw the flag */
sngss7_set_flag(sngss7_info, FLAG_GLARE);
/* setup the hangup cause */
ftdmchan->caller_data.hangup_cause = 34; /* Circuit Congrestion */
/* this is a remote hangup request */
sngss7_set_flag(sngss7_info, FLAG_REMOTE_REL);
/* move the state of the channel to Terminating to end the call */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
}
break;
/**************************************************************************/
default: /* should not have gotten an IAM while in this state */
SS7_ERROR("Got IAM in an invalid state (%s) on span=%d, chan=%d!\n",
ftdm_channel_state2str(ftdmchan->state),
ftdmchan->physical_span_id,
ftdmchan->physical_chan_id);
SS7_ERROR_CHAN(ftdmchan, "Got IAM on channel in invalid state(%s)...reset!\n", ftdm_channel_state2str (ftdmchan->state));
/* move the state of the channel to RESTART to force a reset */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
@ -1028,10 +1057,26 @@ ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t ci
SS7_ASSERT;
};
/* glare, throw the flag, go to down state*/
sngss7_set_flag(sngss7_info, FLAG_GLARE);
if (sngss7_test_flag(sngss7_info, FLAG_GLARE)) {
/* the glare flag is already up so it was caught ... do nothing */
SS7_DEBUG_CHAN(ftdmchan, "Glare flag is already up...nothing to do!%s\n", " ");
} else {
SS7_DEBUG_CHAN(ftdmchan, "Glare flag is not up yet...indicating glare from reattempt!%s\n", " ");
/* glare, throw the flag */
sngss7_set_flag(sngss7_info, FLAG_GLARE);
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
/* clear any existing glare data from the channel */
memset(&sngss7_info->glare, 0x0, sizeof(sngss7_glare_data_t));
/* setup the hangup cause */
ftdmchan->caller_data.hangup_cause = 34; /* Circuit Congrestion */
/* this is a remote hangup request */
sngss7_set_flag(sngss7_info, FLAG_REMOTE_REL);
/* move the state of the channel to Terminating to end the call */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
}
/* unlock the channel again before we exit */
ftdm_mutex_unlock(ftdmchan->mutex);

View File

@ -303,24 +303,17 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
/* clean out all pending channel state changes */
while ((ftdmchan = ftdm_queue_dequeue (ftdmspan->pendingchans))) {
/* double check that this channel has a state change pending */
if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
/*first lock the channel */
ftdm_mutex_lock(ftdmchan->mutex);
/*first lock the channel */
ftdm_mutex_lock(ftdmchan->mutex);
/* process state changes for this channel until they are all done */
while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
ftdm_sangoma_ss7_process_state_change (ftdmchan);
/* unlock the channel */
ftdm_mutex_unlock (ftdmchan->mutex);
} else {
/* since we handle state changes again after handling the trillium queue
* this can occur since we'll clear the flag for the event but can't pop
* the channel out of pendingchans
*/
/* SS7_ERROR("ftdm_core reported state change, but state change flag not set on ft-span = %d, ft-chan = %d\n",
ftdmchan->physical_span_id,
ftdmchan->physical_chan_id);*/
}
/* unlock the channel */
ftdm_mutex_unlock (ftdmchan->mutex);
}/* while ((ftdmchan = ftdm_queue_dequeue(ftdmspan->pendingchans))) */
/* clean out all pending stack events */
@ -451,6 +444,11 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev
/* now that we have the right channel...put a lock on it so no-one else can use it */
ftdm_mutex_lock(ftdmchan->mutex);
/* while there's a state change present on this channel process it */
while (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
ftdm_sangoma_ss7_process_state_change(ftdmchan);
}
/* figure out the type of event and send it to the right handler */
switch (sngss7_event->event_id) {
/**************************************************************************/
@ -748,7 +746,11 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
/* go to RESTART State until RSCa is received */
ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RESTART);
} else {
if (!(sngss7_test_flag (sngss7_info, FLAG_RESET_RX))) {
/* if the hangup is from a rx RSC, rx GRS, or glare don't sent RLC */
if (!(sngss7_test_flag(sngss7_info, FLAG_RESET_RX)) &&
!(sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX)) &&
!(sngss7_test_flag(sngss7_info, FLAG_GLARE))) {
/* send out the release complete */
ft_to_sngss7_rlc (ftdmchan);
}
@ -879,7 +881,26 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
ftdm_channel_t *close_chan = ftdmchan;
/* close the channel */
ftdm_channel_close (&close_chan);
}
} /* if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_OPEN)) */
/* check if there is a glared call that needs to be processed */
if (sngss7_test_flag(sngss7_info, FLAG_GLARE)) {
/* clear the glare flag */
sngss7_clear_flag (sngss7_info, FLAG_GLARE);
/* check if we have an IAM stored...if we don't have one just exit */
if (sngss7_info->glare.circuit != 0) {
/* send the saved call back in to us */
handle_con_ind (0,
sngss7_info->glare.spInstId,
sngss7_info->glare.circuit,
&sngss7_info->glare.iam);
/* clear the glare info */
memset(&sngss7_info->glare, 0x0, sizeof(sngss7_glare_data_t));
} /* if (sngss7_info->glare.circuit != 0) */
} /* if (sngss7_test_flag(sngss7_info, FLAG_GLARE)) */
break;
/**************************************************************************/
@ -1167,11 +1188,13 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(ftdm_sangoma_ss7_outgoing_call)
SS7_ASSERT;
};
/* check if the channel sig state is UP */
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
SS7_ERROR_CHAN(ftdmchan, "Requested channel sig state is down, cancelling call!%s\n", " ");
goto outgoing_fail;
}
/* check if there is a remote block */
if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) ||
(sngss7_test_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX)) ||
(sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) {
@ -1181,15 +1204,19 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(ftdm_sangoma_ss7_outgoing_call)
goto outgoing_break;
}
/* check if there is a local block */
if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) ||
(sngss7_test_flag(sngss7_info, FLAG_GRP_HW_BLOCK_TX)) ||
(sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX))) {
/* KONRAD FIX ME : we should check if this is a TEST call and allow it */
/* the channel is blocked...can't send any calls here */
SS7_ERROR_CHAN(ftdmchan, "Requested channel is locally blocked, re-hunt channel!%s\n", " ");
goto outgoing_break;
}
/* check the state of the channel */
switch (ftdmchan->state){
/**************************************************************************/
case FTDM_CHANNEL_STATE_DOWN:
@ -1208,7 +1235,7 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(ftdm_sangoma_ss7_outgoing_call)
ftdmchan->physical_span_id,
ftdmchan->physical_chan_id);
goto outgoing_fail;
goto outgoing_break;
break;
/**************************************************************************/
} /* switch (ftdmchan->state) (original call) */

View File

@ -321,8 +321,7 @@ typedef struct sngss7_timer_data {
}sngss7_timer_data_t;
typedef struct sngss7_glare_data {
uint32_t suInstId;
uint32_t spInstId;
uint32_t spInstId;
uint32_t circuit;
SiConEvnt iam;
}sngss7_glare_data_t;
@ -612,31 +611,40 @@ ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const cha
#define SS7_MSG_TRACE(fchan, sngss7info ,msg) if (g_ftdm_sngss7_data.message_trace) { \
switch (g_ftdm_sngss7_data.message_trace_level) { \
case 0: \
ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "[CIC:%d]%s",sngss7info->circuit->cic, msg); \
ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "[CIC:%d][SPINSTID:%d][SUINSTID:%d]%s", \
sngss7info->circuit->cic,sngss7info->spInstId,sngss7info->suInstId, msg); \
break; \
case 1: \
ftdm_log_chan(fchan, FTDM_LOG_ALERT, "[CIC:%d]%s",sngss7info->circuit->cic, msg); \
ftdm_log_chan(fchan, FTDM_LOG_ALERT, "[CIC:%d][SPINSTID:%d][SUINSTID:%d]%s", \
sngss7info->circuit->cic,sngss7info->spInstId,sngss7info->suInstId, msg); \
break; \
case 2: \
ftdm_log_chan(fchan, FTDM_LOG_CRIT, "[CIC:%d]%s",sngss7info->circuit->cic, msg); \
ftdm_log_chan(fchan, FTDM_LOG_CRIT, "[CIC:%d][SPINSTID:%d][SUINSTID:%d]%s", \
sngss7info->circuit->cic,sngss7info->spInstId,sngss7info->suInstId, msg); \
break; \
case 3: \
ftdm_log_chan(fchan, FTDM_LOG_ERROR, "[CIC:%d]%s",sngss7info->circuit->cic, msg); \
ftdm_log_chan(fchan, FTDM_LOG_ERROR, "[CIC:%d][SPINSTID:%d][SUINSTID:%d]%s", \
sngss7info->circuit->cic,sngss7info->spInstId,sngss7info->suInstId, msg); \
break; \
case 4: \
ftdm_log_chan(fchan, FTDM_LOG_WARNING, "[CIC:%d]%s",sngss7info->circuit->cic, msg); \
ftdm_log_chan(fchan, FTDM_LOG_WARNING, "[CIC:%d][SPINSTID:%d][SUINSTID:%d]%s", \
sngss7info->circuit->cic,sngss7info->spInstId,sngss7info->suInstId, msg); \
break; \
case 5: \
ftdm_log_chan(fchan, FTDM_LOG_NOTICE, "[CIC:%d]%s",sngss7info->circuit->cic, msg); \
ftdm_log_chan(fchan, FTDM_LOG_NOTICE, "[CIC:%d][SPINSTID:%d][SUINSTID:%d]%s", \
sngss7info->circuit->cic,sngss7info->spInstId,sngss7info->suInstId, msg); \
break; \
case 6: \
ftdm_log_chan(fchan, FTDM_LOG_INFO, "[CIC:%d]%s",sngss7info->circuit->cic, msg); \
ftdm_log_chan(fchan, FTDM_LOG_INFO, "[CIC:%d][SPINSTID:%d][SUINSTID:%d]%s", \
sngss7info->circuit->cic,sngss7info->spInstId,sngss7info->suInstId, msg); \
break; \
case 7: \
ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "[CIC:%d]%s",sngss7info->circuit->cic, msg); \
ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "[CIC:%d][SPINSTID:%d][SUINSTID:%d]%s", \
sngss7info->circuit->cic,sngss7info->spInstId,sngss7info->suInstId, msg); \
break; \
default: \
ftdm_log_chan(fchan, FTDM_LOG_INFO, "[CIC:%d]%s",sngss7info->circuit->cic, msg); \
ftdm_log_chan(fchan, FTDM_LOG_INFO, "[CIC:%d][SPINSTID:%d][SUINSTID:%d]%s", \
sngss7info->circuit->cic,sngss7info->spInstId,sngss7info->suInstId, msg); \
break; \
} /* switch (g_ftdm_sngss7_data.message_trace_level) */ \
} /* if(g_ftdm_sngss7_data.message_trace) */