]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
freetdm: ss7 - work on glare handling
authorKonrad Hammel <konrad@sangoma.com>
Wed, 1 Sep 2010 20:52:37 +0000 (16:52 -0400)
committerKonrad Hammel <konrad@sangoma.com>
Thu, 2 Sep 2010 21:48:14 +0000 (17:48 -0400)
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h

index a0bf95b09c9c8838df000d42909e2b5a9cf82782..a9735c9b62dcf6c80fb8953b46754c4ff97c17b4 100644 (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);
+
+               /* 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);
index a9851bda3f6f7447ab155469169f61f9435ca749..da90d34b48843f8ea60e74c2e0c3140fef00e18f 100644 (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) */
index 3bf12ae3077b7ac21e728a455970e9ebeec02855..45cf4957b6ff7aad8038f4d5d50f1af8d4e1f0da 100644 (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) */