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_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 */
|
/* check if the circuit has a remote block */
|
||||||
if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) ||
|
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;
|
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 */
|
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",
|
SS7_ERROR_CHAN(ftdmchan, "Got IAM on channel in invalid state(%s)...reset!\n", ftdm_channel_state2str (ftdmchan->state));
|
||||||
ftdm_channel_state2str(ftdmchan->state),
|
|
||||||
ftdmchan->physical_span_id,
|
|
||||||
ftdmchan->physical_chan_id);
|
|
||||||
|
|
||||||
/* move the state of the channel to RESTART to force a reset */
|
/* move the state of the channel to RESTART to force a reset */
|
||||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
|
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;
|
SS7_ASSERT;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* glare, throw the flag, go to down state*/
|
if (sngss7_test_flag(sngss7_info, FLAG_GLARE)) {
|
||||||
sngss7_set_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 */
|
/* unlock the channel again before we exit */
|
||||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
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 */
|
/* clean out all pending channel state changes */
|
||||||
while ((ftdmchan = ftdm_queue_dequeue (ftdmspan->pendingchans))) {
|
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);
|
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))) */
|
}/* while ((ftdmchan = ftdm_queue_dequeue(ftdmspan->pendingchans))) */
|
||||||
|
|
||||||
/* clean out all pending stack events */
|
/* 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 */
|
/* now that we have the right channel...put a lock on it so no-one else can use it */
|
||||||
ftdm_mutex_lock(ftdmchan->mutex);
|
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 */
|
/* figure out the type of event and send it to the right handler */
|
||||||
switch (sngss7_event->event_id) {
|
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 */
|
/* go to RESTART State until RSCa is received */
|
||||||
ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RESTART);
|
ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RESTART);
|
||||||
} else {
|
} 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 */
|
/* send out the release complete */
|
||||||
ft_to_sngss7_rlc (ftdmchan);
|
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;
|
ftdm_channel_t *close_chan = ftdmchan;
|
||||||
/* close the channel */
|
/* close the channel */
|
||||||
ftdm_channel_close (&close_chan);
|
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;
|
break;
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
|
@ -1167,11 +1188,13 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(ftdm_sangoma_ss7_outgoing_call)
|
||||||
SS7_ASSERT;
|
SS7_ASSERT;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* check if the channel sig state is UP */
|
||||||
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
|
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
|
||||||
SS7_ERROR_CHAN(ftdmchan, "Requested channel sig state is down, cancelling call!%s\n", " ");
|
SS7_ERROR_CHAN(ftdmchan, "Requested channel sig state is down, cancelling call!%s\n", " ");
|
||||||
goto outgoing_fail;
|
goto outgoing_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check if there is a remote block */
|
||||||
if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) ||
|
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_HW_BLOCK_RX)) ||
|
||||||
(sngss7_test_flag(sngss7_info, FLAG_GRP_MN_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;
|
goto outgoing_break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check if there is a local block */
|
||||||
if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) ||
|
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_HW_BLOCK_TX)) ||
|
||||||
(sngss7_test_flag(sngss7_info, FLAG_GRP_MN_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 */
|
/* the channel is blocked...can't send any calls here */
|
||||||
SS7_ERROR_CHAN(ftdmchan, "Requested channel is locally blocked, re-hunt channel!%s\n", " ");
|
SS7_ERROR_CHAN(ftdmchan, "Requested channel is locally blocked, re-hunt channel!%s\n", " ");
|
||||||
goto outgoing_break;
|
goto outgoing_break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check the state of the channel */
|
||||||
switch (ftdmchan->state){
|
switch (ftdmchan->state){
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
case FTDM_CHANNEL_STATE_DOWN:
|
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_span_id,
|
||||||
ftdmchan->physical_chan_id);
|
ftdmchan->physical_chan_id);
|
||||||
|
|
||||||
goto outgoing_fail;
|
goto outgoing_break;
|
||||||
break;
|
break;
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
} /* switch (ftdmchan->state) (original call) */
|
} /* switch (ftdmchan->state) (original call) */
|
||||||
|
|
|
@ -321,7 +321,6 @@ typedef struct sngss7_timer_data {
|
||||||
}sngss7_timer_data_t;
|
}sngss7_timer_data_t;
|
||||||
|
|
||||||
typedef struct sngss7_glare_data {
|
typedef struct sngss7_glare_data {
|
||||||
uint32_t suInstId;
|
|
||||||
uint32_t spInstId;
|
uint32_t spInstId;
|
||||||
uint32_t circuit;
|
uint32_t circuit;
|
||||||
SiConEvnt iam;
|
SiConEvnt iam;
|
||||||
|
@ -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) { \
|
#define SS7_MSG_TRACE(fchan, sngss7info ,msg) if (g_ftdm_sngss7_data.message_trace) { \
|
||||||
switch (g_ftdm_sngss7_data.message_trace_level) { \
|
switch (g_ftdm_sngss7_data.message_trace_level) { \
|
||||||
case 0: \
|
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; \
|
break; \
|
||||||
case 1: \
|
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; \
|
break; \
|
||||||
case 2: \
|
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; \
|
break; \
|
||||||
case 3: \
|
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; \
|
break; \
|
||||||
case 4: \
|
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; \
|
break; \
|
||||||
case 5: \
|
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; \
|
break; \
|
||||||
case 6: \
|
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; \
|
break; \
|
||||||
case 7: \
|
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; \
|
break; \
|
||||||
default: \
|
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; \
|
break; \
|
||||||
} /* switch (g_ftdm_sngss7_data.message_trace_level) */ \
|
} /* switch (g_ftdm_sngss7_data.message_trace_level) */ \
|
||||||
} /* if(g_ftdm_sngss7_data.message_trace) */
|
} /* if(g_ftdm_sngss7_data.message_trace) */
|
||||||
|
|
Loading…
Reference in New Issue