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)) ||
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);
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);
+
+ /* 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 */
- ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
+ /* 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);
/* 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 */
/* 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) {
/**************************************************************************/
/* 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);
}
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;
/**************************************************************************/
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))) {
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:
ftdmchan->physical_span_id,
ftdmchan->physical_chan_id);
- goto outgoing_fail;
+ goto outgoing_break;
break;
/**************************************************************************/
} /* switch (ftdmchan->state) (original call) */
}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;
#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) */