]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
freetdm: Fix SS7 ISUP T10 (Overlap digit timeout) - issue #1445
authorMoises Silva <moy@sangoma.com>
Wed, 28 Sep 2011 23:15:35 +0000 (19:15 -0400)
committerMoises Silva <moy@sangoma.com>
Wed, 28 Sep 2011 23:17:40 +0000 (19:17 -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
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_timers.c
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c

index 26356220ec0a2188df2c53dd675c60a54045936f..213c4c8d4dd8ad0b68ff61a164a8b637b4d3a6cf 100644 (file)
@@ -405,6 +405,8 @@ ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circ
                                append_tknStr_from_sngss7(siCnStEvnt->subNum.addrSig, 
                                                                                        ftdmchan->caller_data.dnis.digits, 
                                                                                        siCnStEvnt->subNum.oddEven);
+                               SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Rx SAM (digits = %s)\n", sngss7_info->circuit->cic,
+                                               ftdmchan->caller_data.dnis.digits);
                        } else {
                                SS7_INFO_CHAN(ftdmchan,"No Called party (DNIS) information in SAM!%s\n", " ");
                        }
index 9f2cbbac25d22ec37bd4a96733653074a86b783a..5341983e4667b1f766818d39ebe5d7af23785120 100644 (file)
@@ -592,6 +592,11 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
                        i++;
                }
 
+               /* kill t10 if active */
+               if (sngss7_info->t10.hb_timer_id) {
+                       ftdm_sched_cancel_timer (sngss7_info->t10.sched, sngss7_info->t10.hb_timer_id);
+               }
+
                /* check if the end of pulsing (ST) character has arrived or the right number of digits */
                if (ftdmchan->caller_data.dnis.digits[i-1] == 'F') {
                        SS7_DEBUG_CHAN(ftdmchan, "Received the end of pulsing character %s\n", "");
@@ -613,7 +618,7 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
                } else {
                        /* if we are coming from idle state then we have already been here once before */
                        if (ftdmchan->last_state != FTDM_CHANNEL_STATE_IDLE) {
-                               SS7_INFO_CHAN(ftdmchan,"Received %d out of %d so far: %s...starting T35\n",
+                               SS7_INFO_CHAN(ftdmchan, "Received %d out of %d so far: %s...starting T35\n",
                                                                                i,
                                                                                sngss7_info->circuit->min_digits,
                                                                                ftdmchan->caller_data.dnis.digits);
@@ -628,7 +633,7 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
                
                                        SS7_ERROR ("Unable to schedule timer, hanging up call!\n");
                
-                                       ftdmchan->caller_data.hangup_cause = 41;
+                                       ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_TEMPORARY_FAILURE;
                
                                        /* set the flag to indicate this hangup is started from the local side */
                                        sngss7_set_ckt_flag (sngss7_info, FLAG_LOCAL_REL);
@@ -636,9 +641,29 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
                                        /* end the call */
                                        state_flag = 0;
                                        ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
-                               } /* if (ftdm_sched_timer(sngss7_info->t35.sched, */
-                       } /* if (ftdmchan->last_state != FTDM_CHANNEL_STATE_IDLE) */
-               } /* checking ST/#digits */
+                               }
+                       }
+
+                       /* start ISUP t10 */
+                       if (ftdm_sched_timer (sngss7_info->t10.sched,
+                                                                       "t10",
+                                                                       sngss7_info->t10.beat,
+                                                                       sngss7_info->t10.callback,
+                                                                       &sngss7_info->t10,
+                                                                       &sngss7_info->t10.hb_timer_id)) {
+       
+                               SS7_ERROR ("Unable to schedule timer, hanging up call!\n");
+       
+                               ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_TEMPORARY_FAILURE;
+       
+                               /* set the flag to indicate this hangup is started from the local side */
+                               sngss7_set_ckt_flag (sngss7_info, FLAG_LOCAL_REL);
+       
+                               /* end the call */
+                               state_flag = 0;
+                               ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
+                       }
+               }
 
          break;
 
index 7a116ecbb461cf48e8890b61799ab05eaa8f5949..d58d2a53318f580b4c55ced860e1ff5430fd89ed 100644 (file)
@@ -288,7 +288,6 @@ typedef struct sng_isup_intf {
        uint32_t                ssf;
        uint32_t                isap;
        uint16_t                t4;
-       uint32_t                t10;
        uint32_t                t11;
        uint32_t                t18;
        uint32_t                t19;
@@ -344,6 +343,7 @@ typedef struct sng_isup_ckt {
        uint8_t                 transparent_iam;
        void                    *obj;
        uint16_t                t3;
+       uint32_t                t10;
        uint16_t                t12;
        uint16_t                t13;
        uint16_t                t14;
@@ -471,6 +471,7 @@ typedef struct sngss7_chan_data {
        void                                    *raw_data;              /* send on next sigevent */
        sngss7_glare_data_t             glare;
        sngss7_timer_data_t             t35;
+       sngss7_timer_data_t             t10;
        sngss7_group_data_t             rx_grs;
        sngss7_group_data_t             rx_gra;
        sngss7_group_data_t             tx_grs;
@@ -887,6 +888,7 @@ ftdm_status_t sngss7_add_raw_data(sngss7_chan_data_t *sngss7_info, uint8_t* data
 
 /* in ftmod_sangoma_ss7_timers.c */
 void handle_isup_t35(void *userdata);
+void handle_isup_t10(void *userdata);
 
 /******************************************************************************/
 
index 10afc65bc9455339e0e183fed4e3ad16e209e0a1..6138ea34b0a5f345a86d7b6a0e2427a771cd08ab 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2009, Konrad Hammel <konrad@sangoma.com>
+ * Copyright (c) 2009, Sangoma Technologies
+ * Konrad Hammel <konrad@sangoma.com>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Contributors: 
+ *
+ * Moises Silva <moy@sangoma.com>
+ *
  */
 
 /* INCLUDE ********************************************************************/
@@ -70,12 +76,39 @@ void handle_isup_t35(void *userdata)
     /* end the call */
     ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
 
+    /* kill t10 if active */
+    if (sngss7_info->t10.hb_timer_id) {
+        ftdm_sched_cancel_timer (sngss7_info->t10.sched, sngss7_info->t10.hb_timer_id);
+    }
+
     /*unlock*/
     ftdm_channel_unlock(ftdmchan);
 
     SS7_FUNC_TRACE_EXIT(__FUNCTION__);
     return;
 }
+
+
+void handle_isup_t10(void *userdata)
+{
+       SS7_FUNC_TRACE_ENTER(__FUNCTION__);
+
+       sngss7_timer_data_t *timer = userdata;
+       sngss7_chan_data_t  *sngss7_info = timer->sngss7_info;
+       ftdm_channel_t      *ftdmchan = sngss7_info->ftdmchan;
+
+       ftdm_channel_lock(ftdmchan);
+
+       SS7_DEBUG("[Call-Control] Timer 10 expired on CIC = %d\n", sngss7_info->circuit->cic);
+
+       /* send the call to the user */
+       ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
+
+       ftdm_channel_unlock(ftdmchan);
+
+       SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+}
 /******************************************************************************/
 /* For Emacs:
  * Local Variables:
index d7fc553e2ff4e7ee5be36aebbf6b2ff6bf2ff539..acb29ba385bf243ba2eb1fb0ba96d44ab45fcacf 100644 (file)
@@ -127,6 +127,7 @@ typedef struct sng_ccSpan
        uint8_t                 itx_auto_reply;
        uint8_t                 transparent_iam;
        uint32_t                t3;
+       uint32_t                t10;
        uint32_t                t12;
        uint32_t                t13;
        uint32_t                t14;
@@ -1570,11 +1571,6 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface)
                        sng_isap.t9 = atoi(parm->val);
                        SS7_DEBUG("Found isup t9 = %d\n",sng_isap.t9);
                /**********************************************************************/
-               } else if (!strcasecmp(parm->var, "isup.t10")) {
-               /**********************************************************************/
-                       sng_isup.t10 = atoi(parm->val);
-                       SS7_DEBUG("Found isup t10 = %d\n",sng_isup.t10);
-               /**********************************************************************/
                } else if (!strcasecmp(parm->var, "isup.t11")) {
                /**********************************************************************/
                        sng_isup.t11 = atoi(parm->val);
@@ -1965,6 +1961,10 @@ static int ftmod_ss7_parse_cc_span(ftdm_conf_node_t *cc_span)
                /**********************************************************************/
                        sng_ccSpan.t3 = atoi(parm->val);
                        SS7_DEBUG("Found isup t3 = %d\n", sng_ccSpan.t3);
+               } else if (!strcasecmp(parm->var, "isup.t10")) {
+               /**********************************************************************/
+                       sng_ccSpan.t10 = atoi(parm->val);
+                       SS7_DEBUG("Found isup t10 = %d\n", sng_ccSpan.t10);
                /**********************************************************************/
                } else if (!strcasecmp(parm->var, "isup.t12")) {
                /**********************************************************************/
@@ -2584,11 +2584,6 @@ static int ftmod_ss7_fill_in_isup_interface(sng_isup_inf_t *sng_isup)
        } else {
                g_ftdm_sngss7_data.cfg.isupIntf[i].t4           = 3000;
        }
-       if (sng_isup->t10 != 0) {
-               g_ftdm_sngss7_data.cfg.isupIntf[i].t10          = sng_isup->t10;
-       } else {
-               g_ftdm_sngss7_data.cfg.isupIntf[i].t10          = 50;
-       }
        if (sng_isup->t11 != 0) {
                g_ftdm_sngss7_data.cfg.isupIntf[i].t11          = sng_isup->t11;
        } else {
@@ -2935,6 +2930,11 @@ static int ftmod_ss7_fill_in_ccSpan(sng_ccSpan_t *ccSpan)
                } else {
                        g_ftdm_sngss7_data.cfg.isupCkt[x].t3                    = ccSpan->t3;
                }
+               if (ccSpan->t10 == 0) {
+                       g_ftdm_sngss7_data.cfg.isupCkt[x].t10           = 50;
+               } else {
+                       g_ftdm_sngss7_data.cfg.isupCkt[x].t10           = ccSpan->t10;
+               }
                if (ccSpan->t12 == 0) {
                        g_ftdm_sngss7_data.cfg.isupCkt[x].t12           = 300;
                } else {
@@ -3063,12 +3063,18 @@ static int ftmod_ss7_fill_in_circuits(sng_span_t *sngSpan)
                ftdmchan->call_data = ss7_info;
 
                /* prepare the timer structures */
-               ss7_info->t35.sched                     = ((sngss7_span_data_t *)(ftdmspan->signal_data))->sched;
+               ss7_info->t35.sched             = ((sngss7_span_data_t *)(ftdmspan->signal_data))->sched;
                ss7_info->t35.counter           = 1;
-               ss7_info->t35.beat                      = (isupCkt->t35) * 100; /* beat is in ms, t35 is in 100ms */
+               ss7_info->t35.beat              = (isupCkt->t35) * 100; /* beat is in ms, t35 is in 100ms */
                ss7_info->t35.callback          = handle_isup_t35;
                ss7_info->t35.sngss7_info       = ss7_info;
 
+               ss7_info->t10.sched             = ((sngss7_span_data_t *)(ftdmspan->signal_data))->sched;
+               ss7_info->t10.counter           = 1;
+               ss7_info->t10.beat              = (isupCkt->t10) * 100; /* beat is in ms, t10 is in 100ms */
+               ss7_info->t10.callback          = handle_isup_t10;
+               ss7_info->t10.sngss7_info       = ss7_info;
+
 
        /**************************************************************************/
        } /* for (i == 1; i < ftdmspan->chan_count; i++) */