freetdm: ss7 - work on glare handling
This commit is contained in:
parent
cd0cc2e4a3
commit
16d918d025
|
@ -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);
|
||||
|
|
|
@ -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) */
|
||||
|
|
|
@ -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) */
|
||||
|
|
Loading…
Reference in New Issue