]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
freetdm: ss7, bug fix in obci_bita handling
authorKonrad Hammel <konrad@sangoma.com>
Mon, 25 Oct 2010 20:55:03 +0000 (16:55 -0400)
committerKonrad Hammel <konrad@sangoma.com>
Wed, 27 Oct 2010 22:00:25 +0000 (18:00 -0400)
freetdm: ss7, added support for SAM
freetdm: ss7, updated support for COT in IAM

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_out.c
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c

index 807b3b62c786f2906727462b95541340f89de302..c4922654eb26de7f57c4641a4ff2a33f7c435d27 100644 (file)
@@ -216,8 +216,20 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
                        sprintf(nadi, "%d", siConEvnt->cdPtyNum.natAddrInd.val);
                        ftdm_channel_add_var(ftdmchan, "ss7_cld_nadi", nadi);
 
-                       /* set the state of the channel to collecting...the rest is done by the chan monitor */
-                       ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_COLLECT);
+
+                       /* check if a COT test is requested */
+                       if ((siConEvnt->natConInd.eh.pres) && (siConEvnt->natConInd.contChkInd.pres)) {
+                               SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Found COT Request\n", sngss7_info->circuit->cic);
+
+                               /* tell the core to loop the channel */
+                               ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_LOOP, NULL);
+
+                               /* move to in loop state */
+                               ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IN_LOOP);
+                       } else {
+                               /* set the state of the channel to collecting...the rest is done by the chan monitor */
+                               ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_COLLECT);
+                       }
 
                } /* if (channel is usable */
 
@@ -256,6 +268,9 @@ handle_glare:
        default:        /* should not have gotten an IAM while in this state */
                SS7_ERROR_CHAN(ftdmchan, "Got IAM on channel in invalid state(%s)...reset!\n", ftdm_channel_state2str (ftdmchan->state));
 
+               /* reset the cic */
+               sngss7_set_flag(sngss7_info, FLAG_RESET_TX);
+
                /* move the state of the channel to RESTART to force a reset */
                ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
 
@@ -292,6 +307,7 @@ ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circ
        /**************************************************************************/
        case (ADDRCMPLT):
                SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx ACM\n", sngss7_info->circuit->cic);
+
                switch (ftdmchan->state) {
                /**********************************************************************/
                case FTDM_CHANNEL_STATE_DIALING:
@@ -315,14 +331,22 @@ ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circ
                                ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
                        }
                        
-               break;
+                       break;
                /**********************************************************************/
                default:        /* incorrect state...reset the CIC */
+                       SS7_ERROR_CHAN(ftdmchan, "RX ACM in invalid state :%s...resetting CIC\n", 
+                                                                       ftdm_channel_state2str (ftdmchan->state));
+
+                       /* reset the cic */
+                       sngss7_set_flag(sngss7_info, FLAG_RESET_TX);
+
                        /* go to RESTART */
-                       ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
-               break;
+                       ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
+                       break;
                /**********************************************************************/
                } /* switch (ftdmchan->state) */
+
+               break;
        /**************************************************************************/
        case (MODIFY):
                SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx MODIFY\n", sngss7_info->circuit->cic);
@@ -354,6 +378,34 @@ ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circ
        /**************************************************************************/
        case (SUBSADDR):
                SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx SAM\n", sngss7_info->circuit->cic);
+
+               /* check the channel state */
+               switch (ftdmchan->state) {
+               /**********************************************************************/
+               case (FTDM_CHANNEL_STATE_COLLECT):
+                       
+                       /* confirm that the event contains the subsquent number field */
+                       if (siCnStEvnt->subNum.eh.pres && siCnStEvnt->subNum.addrSig.pres) {
+                               /* add the digits to the ftdm channel variable */
+                               append_tknStr_from_sngss7(siCnStEvnt->subNum.addrSig, 
+                                                                                       ftdmchan->caller_data.dnis.digits, 
+                                                                                       siCnStEvnt->subNum.oddEven);
+                       } else {
+                               SS7_INFO_CHAN(ftdmchan,"No Called party (DNIS) information in SAM!%s\n", " ");
+                       }
+
+                       /* go to idle so that collect state is processed again */
+                       ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE);
+
+                       break;
+               /**********************************************************************/
+               default:
+                       SS7_ERROR_CHAN(ftdmchan, "RX SAM in invalid state :%s...ignoring\n", 
+                                                                               ftdm_channel_state2str (ftdmchan->state));
+                       break;
+               /**********************************************************************/
+               } /* switch (ftdmchan->state) */
+
                break;
        /**************************************************************************/
        case (EXIT):
@@ -830,7 +882,7 @@ ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
                break;
        /**************************************************************************/
        case SIT_STA_CONTCHK:              /* continuity check */
-               SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx COT start\n", sngss7_info->circuit->cic);
+               SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CCR start\n", sngss7_info->circuit->cic);
                handle_cot_start(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
                break;
        /**************************************************************************/
@@ -840,7 +892,7 @@ ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
                break;
        /**************************************************************************/
        case SIT_STA_STPCONTIN:          /* stop continuity */
-               SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx COT stop\n", sngss7_info->circuit->cic);
+               SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CCR stop\n", sngss7_info->circuit->cic);
                handle_cot_stop(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
                break;
        /**************************************************************************/
@@ -1225,7 +1277,7 @@ ftdm_status_t handle_cot_start(uint32_t suInstId, uint32_t spInstId, uint32_t ci
        /* open the channel if it is not open */
        if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) {
                if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
-                       SS7_ERROR("Failed to open CIC %d for COT test!\n", sngss7_info->circuit->cic);
+                       SS7_ERROR("Failed to open CIC %d for CCR test!\n", sngss7_info->circuit->cic);
                        /* KONRAD FIX ME */
                        SS7_FUNC_TRACE_EXIT(__FUNCTION__);
                        return FTDM_FAIL;
@@ -1290,6 +1342,38 @@ ftdm_status_t handle_cot(uint32_t suInstId, uint32_t spInstId, uint32_t circuit,
 {
        SS7_FUNC_TRACE_ENTER(__FUNCTION__);
 
+       sngss7_chan_data_t  *sngss7_info = NULL;
+       ftdm_channel_t    *ftdmchan = NULL;
+
+       /* get the ftdmchan and ss7_chan_data from the circuit */
+       if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
+               SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
+               SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+               return FTDM_FAIL;
+       }
+
+       /* lock the channel */
+       ftdm_mutex_lock(ftdmchan->mutex);
+
+       switch (ftdmchan->state) {
+       /**************************************************************************/
+       case (FTDM_CHANNEL_STATE_IN_LOOP):
+               /* tell the core to stop looping the channel */
+               ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL);
+       
+               /* exit out of the LOOP state and go to collect */
+               ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_COLLECT);
+               
+               break;
+       /**************************************************************************/
+       default:
+               /* exit out of the LOOP state to the last state */
+               ftdm_set_state_locked(ftdmchan, ftdmchan->last_state);
+
+               break;
+       /**************************************************************************/
+       } /* switch (ftdmchan->state) */
+
        if ( (siStaEvnt->contInd.eh.pres > 0) && (siStaEvnt->contInd.contInd.pres > 0)) {
                SS7_INFO("Continuity Test result for CIC = %d (span %d, chan %d) is: \"%s\"\n",
                                        g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic,
@@ -1300,13 +1384,13 @@ ftdm_status_t handle_cot(uint32_t suInstId, uint32_t spInstId, uint32_t circuit,
                SS7_ERROR("Recieved Continuity report containing no results!\n");
        }
 
+       /* unlock the channel again before we exit */
+       ftdm_mutex_unlock(ftdmchan->mutex);
+
        SS7_FUNC_TRACE_EXIT(__FUNCTION__);
        return FTDM_SUCCESS;
 }
 
-/******************************************************************************/
-
-
 /******************************************************************************/
 ftdm_status_t handle_blo_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
 {
index 587242d94e285b72e84972a017927324618fcb2b..ebb4efa311bac1a3d413220aefd61f05ad18d993 100644 (file)
@@ -79,7 +79,7 @@ ftdm_state_map_t sangoma_ss7_state_map = {
        ZSD_INBOUND,
        ZSM_UNACCEPTABLE,
        {FTDM_CHANNEL_STATE_IDLE, FTDM_END},
-       {FTDM_CHANNEL_STATE_RESTART, FTDM_END}
+       {FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_COLLECT, FTDM_END}
        },
    {
        ZSD_INBOUND,
@@ -100,7 +100,8 @@ ftdm_state_map_t sangoma_ss7_state_map = {
        ZSM_UNACCEPTABLE,
        {FTDM_CHANNEL_STATE_COLLECT, FTDM_END},
        {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
-        FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_RING, FTDM_END}
+        FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_RING, 
+        FTDM_CHANNEL_STATE_IDLE, FTDM_END}
        },
    {
        ZSD_INBOUND,
@@ -526,29 +527,32 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
                        ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RING);
                        
                } else {
-                       SS7_INFO_CHAN(ftdmchan,"Received %d out of %d so far: %s...starting T35\n",
-                                               i,
-                                               g_ftdm_sngss7_data.min_digits,
-                                               ftdmchan->caller_data.dnis.digits);
-
-                       /* start ISUP t35 */
-                       if (ftdm_sched_timer (sngss7_info->t35.sched,
-                                                                       "t35",
-                                                                       sngss7_info->t35.beat,
-                                                                       sngss7_info->t35.callback,
-                                                                       &sngss7_info->t35,
-                                                                       &sngss7_info->t35.hb_timer_id)) {
-
-                               SS7_ERROR ("Unable to schedule timer, hanging up call!\n");
-
-                               ftdmchan->caller_data.hangup_cause = 41;
-
-                               /* set the flag to indicate this hangup is started from the local side */
-                               sngss7_set_flag (sngss7_info, FLAG_LOCAL_REL);
-
-                               /* end the call */
-                               ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
-                       } /* if (ftdm_sched_timer(sngss7_info->t35.sched, */
+                       /* 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",
+                                                                               i,
+                                                                               g_ftdm_sngss7_data.min_digits,
+                                                                               ftdmchan->caller_data.dnis.digits);
+               
+                               /* start ISUP t35 */
+                               if (ftdm_sched_timer (sngss7_info->t35.sched,
+                                                                               "t35",
+                                                                               sngss7_info->t35.beat,
+                                                                               sngss7_info->t35.callback,
+                                                                               &sngss7_info->t35,
+                                                                               &sngss7_info->t35.hb_timer_id)) {
+               
+                                       SS7_ERROR ("Unable to schedule timer, hanging up call!\n");
+               
+                                       ftdmchan->caller_data.hangup_cause = 41;
+               
+                                       /* set the flag to indicate this hangup is started from the local side */
+                                       sngss7_set_flag (sngss7_info, FLAG_LOCAL_REL);
+               
+                                       /* end the call */
+                                       ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
+                               } /* if (ftdm_sched_timer(sngss7_info->t35.sched, */
+                       } /* if (ftdmchan->last_state != FTDM_CHANNEL_STATE_IDLE) */
                } /* checking ST/#digits */
 
          break;
index 27833cb2a210c5c3e8b33d8668fde069fc2ec31a..378b50e0ade9de28c552b9cce09586f450e28b15 100644 (file)
@@ -581,6 +581,8 @@ uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum);
 uint8_t copy_cdPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum);
 uint8_t copy_cdPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum);
 uint8_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
+uint8_t append_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
+
 int check_for_state_change(ftdm_channel_t *ftdmchan);
 int check_cics_in_range(sngss7_chan_data_t *sngss7_info);
 int check_for_reset(sngss7_chan_data_t *sngss7_info);
index 8cbe6d94988f54aa6a689463ce14a974afa92767..f2e34e6c2cffc3abb663a3c18d1aa6c71f124727 100644 (file)
@@ -341,9 +341,10 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan)
 
        /* fill in any optional parameters */
        if (sngss7_test_options(isup_intf, SNGSS7_ACM_OBCI_BITA)) {
+               SS7_DEBUG_CHAN(ftdmchan, "Found ACM_OBCI_BITA flag:0x%X\n", isup_intf->options);
                acm.optBckCalInd.eh.pres                                = PRSNT_NODEF;
                acm.optBckCalInd.inbndInfoInd.pres              = PRSNT_NODEF;
-               acm.optBckCalInd.inbndInfoInd.val               = sngss7_test_options(isup_intf, SNGSS7_ACM_OBCI_BITA);
+               acm.optBckCalInd.inbndInfoInd.val               = 0x1;
                acm.optBckCalInd.caFwdMayOcc.pres               = PRSNT_DEF;
                acm.optBckCalInd.simpleSegmInd.pres             = PRSNT_DEF;
                acm.optBckCalInd.mlppUserInd.pres               = PRSNT_DEF;
index 718663950af817288a6abf8063709f143db46f9a..4d514caf8653711588b9d2c310e7751a84eeee1d 100644 (file)
@@ -44,6 +44,7 @@ uint32_t sngss7_id;
 
 /* PROTOTYPES *****************************************************************/
 uint8_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
+uint8_t append_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
 uint8_t copy_cgPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum);
 uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum);
 uint8_t copy_cdPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum);
@@ -343,6 +344,49 @@ uint8_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven)
        return 0;
 }
 
+/******************************************************************************/
+uint8_t append_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven)
+{
+       int i = 0;
+       int j = 0;
+
+       /* check if the token string is present */
+       if (str.pres == 1) {
+               /* find the length of the digits so far */
+               j = strlen(ftdm);
+
+               /* confirm that we found an acceptable length */
+               if ( j > 25 ) {
+                       SS7_ERROR("string length exceeds maxium value...aborting append!\n");
+                       return 1;
+               } /* if ( j > 25 ) */
+
+               /* copy in digits */
+               for (i = 0; i < str.len; i++) {
+                       /* convert 4 bit integer to char and copy into lower nibblet*/
+                       sprintf(&ftdm[j], "%X", (str.val[i] & 0x0F));
+                       /* move along */
+                       j++;
+                       /* convert 4 bit integer to char and copy into upper nibblet */
+                       sprintf(&ftdm[j], "%X", ((str.val[i] & 0xF0) >> 4));
+                       /* move along */
+                       j++;
+               } /* for (i = 0; i < str.len; i++) */
+
+               /* if the odd flag is up the last digit is a fake "0" */
+               if ((oddEven.pres == 1) && (oddEven.val == 1)) {
+                       ftdm[j-1] = '\0';
+               } else {
+                       ftdm[j] = '\0';
+               } /* if ((oddEven.pres == 1) && (oddEven.val == 1)) */
+       } else {
+               SS7_ERROR("Asked to copy tknStr that is not present!\n");
+               return 1;
+       } /* if (str.pres == 1) */
+
+       return 0;
+}
+
 /******************************************************************************/
 int check_for_state_change(ftdm_channel_t *ftdmchan)
 {