]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
freetdm: ss7- added support for incoming group blocks, started adding support for...
authorKonrad Hammel <konrad@sangoma.com>
Tue, 7 Sep 2010 21:44:43 +0000 (17:44 -0400)
committerKonrad Hammel <konrad@sangoma.com>
Tue, 7 Sep 2010 22:14:30 +0000 (18:14 -0400)
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c
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
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c

index c8c8bc3dd13d748021a4e3a764b59061699d320d..44764295d43eb5bab9f97ebc60e894f622cd37f1 100644 (file)
@@ -444,8 +444,8 @@ int ftmod_ss7_mtp3_gen_config(void)
        cfg.t.cfg.s.snGen.tmr.t21.enb   = TRUE;                         /* t21 - waiting to restart traffic routed through adjacent SP */
        cfg.t.cfg.s.snGen.tmr.t21.val   = 650;
 # if (SS7_ANS92 || SS7_ANS88 || SS7_ANS96 || defined(TDS_ROLL_UPGRADE_SUPPORT))
-       cfg.t.cfg.s.snGen.t26.enb               = TRUE;                         /* t26 - waiting to repeat traffic restart waiting message for ANSI */
-       cfg.t.cfg.s.snGen.t26.val               = 600;
+       cfg.t.cfg.s.snGen.tmr.t26.enb           = TRUE;                         /* t26 - waiting to repeat traffic restart waiting message for ANSI */
+       cfg.t.cfg.s.snGen.tmr.t26.val           = 600;
 # endif
 #endif
 
@@ -744,10 +744,6 @@ int ftmod_ss7_mtp3_dlsap_config(int id)
        cfg.t.cfg.s.snDLSAP.msgPrior            = 0;                                    /* management message priority */
        cfg.t.cfg.s.snDLSAP.lnkType                     = k->mtp3.linkType;             /* link type ANSI, ITU, BICI or CHINA */
        cfg.t.cfg.s.snDLSAP.upSwtch                     = k->mtp3.switchType;   /* user part switch type */
-# if (SS7_ANS92 || SS7_ANS88 || SS7_ANS96 || SS7_CHINA)
-       cfg.t.cfg.s.snDLSAP.l2Type                      = LSN_MTP2_56KBPS;              /* layer 2 type - 56kbps MTP2 link, 1.536Mbps MTP2 link or QSAAL link */
-       cfg.t.cfg.s.snDLSAP.isCLink                     = FALSE;                                /* identifies if the link is a C type link.Required to check if sls has to be rotated.*/
-# endif
        cfg.t.cfg.s.snDLSAP.maxSLTtry           = MAX_SLTM_RETRIES;             /* maximun times to retry SLTM */
        cfg.t.cfg.s.snDLSAP.p0QLen                      = 32;                                   /* size of the priority 0 Q */
        cfg.t.cfg.s.snDLSAP.p1QLen                      = 32;                                   /* size of the priority 1 Q */
@@ -775,17 +771,46 @@ int ftmod_ss7_mtp3_dlsap_config(int id)
        cfg.t.cfg.s.snDLSAP.selector            = 0;                                    /* lower layer selector */
        cfg.t.cfg.s.snDLSAP.mem.region          = S_REG;                                /* memory region id */
        cfg.t.cfg.s.snDLSAP.mem.pool            = S_POOL;                               /* memory pool id */
-#if( SS7_ANS92 || SS7_ANS88 || SS7_ANS96 || SS7_CHINA )
-       cfg.t.cfg.s.snDLSAP.dpcLen                      = DPC24;                                /* dpc length 24 bits */
-#else
-       cfg.t.cfg.s.snDLSAP.dpcLen                      = DPC14;                                /* dpc length 14 bits */
-#endif
        cfg.t.cfg.s.snDLSAP.spId                        = k->mtp3.mtp2Id                ;/* service provider id */
-#if (SS7_ITU88 || SS7_CHINA || SS7_TTC || SS7_NTT || SS7_BICI )
-       cfg.t.cfg.s.snDLSAP.flushContFlag       = FALSE;                                /* flush continue handling */
-#else
-       cfg.t.cfg.s.snDLSAP.flushContFlag       = TRUE;                                 /* flush continue handling */
-#endif
+
+       switch (k->mtp3.linkType) {
+       /**************************************************************************/
+       case (LSN_SW_ANS):
+       case (LSN_SW_ANS96):
+       case (LSN_SW_CHINA):
+               cfg.t.cfg.s.snDLSAP.dpcLen              = DPC24;                                /* dpc length 24 bits */
+               cfg.t.cfg.s.snDLSAP.l2Type              = LSN_MTP2_56KBPS;              /* layer 2 type - 56kbps MTP2 link, 1.536Mbps MTP2 link or QSAAL link */
+               cfg.t.cfg.s.snDLSAP.isCLink             = FALSE;                                /* identifies if the link is a C type link.Required to check if sls has to be rotated.*/
+               break;
+       /**************************************************************************/
+       case (LSN_SW_ITU):
+               cfg.t.cfg.s.snDLSAP.dpcLen              = DPC14;                                /* dpc length 14 bits */
+               break;
+       /**************************************************************************/
+       default:
+               cfg.t.cfg.s.snDLSAP.dpcLen              = DPC14;                                /* dpc length 14 bits */
+               break;
+       /**************************************************************************/
+       } /* switch (k->mtp3.linkType) */
+
+       switch (k->mtp3.linkType) {
+       /**************************************************************************/
+       case (LSN_SW_ANS):
+       case (LSN_SW_ANS96):
+               cfg.t.cfg.s.snDLSAP.flushContFlag       = TRUE;                 /* flush continue handling */
+               break;
+       /**************************************************************************/
+       case (LSN_SW_ITU):
+       case (LSN_SW_CHINA):
+               cfg.t.cfg.s.snDLSAP.flushContFlag       = FALSE;                        /* flush continue handling */
+               break;
+       /**************************************************************************/
+       default:
+               cfg.t.cfg.s.snDLSAP.flushContFlag       = FALSE;                        /* flush continue handling */
+               break;
+       /**************************************************************************/
+       } /* switch (k->mtp3.linkType) */
+
        cfg.t.cfg.s.snDLSAP.tmr.t1.enb          = TRUE;                                 /* t1 - delay to avoid missequencing on changeover */
        cfg.t.cfg.s.snDLSAP.tmr.t1.val          = k->mtp3.t1;
        cfg.t.cfg.s.snDLSAP.tmr.t2.enb          = TRUE;                                 /* t2 - waiting for changeover ack */
@@ -1209,12 +1234,12 @@ int ftmod_ss7_isup_ckt_config(int id)
        cfg.t.cfg.s.siCir.typeCntrl                     = k->typeCntrl;         /* type of control                                               */
        cfg.t.cfg.s.siCir.contReq                       = FALSE;                        /* continuity check required                            */
 #if (SI_218_COMP || SS7_ANS88 || SS7_ANS92 || SS7_ANS95 || SS7_BELL)
-       cfg.t.cfg.s.siCir.firstCic                      =;                                      /* First cic in the circuit group                 */
-       cfg.t.cfg.s.siCir.numCir                        =;                                      /* Number of circuits in the circuit group */
+       cfg.t.cfg.s.siCir.firstCic                      = 1;                                    /* First cic in the circuit group                 */
+       cfg.t.cfg.s.siCir.numCir                        = 24;                                   /* Number of circuits in the circuit group */
        cfg.t.cfg.s.siCir.nonSS7Con                     = TRUE;                         /* connecting to non SS7 network                        */
-       cfg.t.cfg.s.siCir.outTrkGrpN            =;                                      /* outgoing trunk group number (For EXM)        */
-       cfg.t.cfg.s.siCir.cvrTrkClli            =;                                      /* Trunk Group number (For CVR validation) */
-       cfg.t.cfg.s.siCir.clli                          =;                                      /* common language location identifier   */
+       cfg.t.cfg.s.siCir.outTrkGrpN.length     = 0;                                    /* outgoing trunk group number (For EXM)        */
+       cfg.t.cfg.s.siCir.cvrTrkClli.length     = 0;                                    /* Trunk Group number (For CVR validation) */
+       cfg.t.cfg.s.siCir.clli.length           = 0;                                    /* common language location identifier   */
 #endif
        cfg.t.cfg.s.siCir.cirTmr.t3.enb         = TRUE;                         /* t3 timer - overload received                 */
        cfg.t.cfg.s.siCir.cirTmr.t3.val         = k->t3;
index f0cfa0237acae4fdc41495bbd97d8dee86cd74c2..0c3dcffec07285aff68b0de769de358342f3cf48 100644 (file)
@@ -71,6 +71,8 @@ ftdm_status_t handle_ubl_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ
 ftdm_status_t handle_local_blk(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
 ftdm_status_t handle_local_ubl(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
 ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
+ftdm_status_t handle_cgb_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
+ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
 /******************************************************************************/
 
 /* FUNCTIONS ******************************************************************/
@@ -898,12 +900,12 @@ ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
        /**************************************************************************/
        case SIT_STA_CGBREQ:                    /* CGB request */
                SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CGB\n");
-               SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
+               handle_cgb_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
                break;
        /**************************************************************************/
        case SIT_STA_CGUREQ:                    /* CGU request */
                SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CGU\n");
-               SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
+               handle_cgu_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
                break;
        /**************************************************************************/
        case SIT_STA_CGQRYREQ:            /* circuit group query request */
@@ -913,7 +915,7 @@ ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
        /**************************************************************************/
        case SIT_STA_CGBRSP:                    /* mntc. oriented CGB response */
                SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx mntc CGB\n");
-               SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
+               handle_cgb_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
                break;
        /**************************************************************************/
        case SIT_STA_CGURSP:                    /* mntc. oriented CGU response */
@@ -1012,8 +1014,8 @@ ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
                break;
        /**************************************************************************/
        case SIT_STA_CGBINFOIND:                /* circuit grp blking ind , no resp req */
-               SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CGB no resp req\n");
-               SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
+               /*SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CGB no resp req\n");*/
+/*             handle_cgb_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);*/
                break;
        /**************************************************************************/
        case SIT_STA_LMCQMINFOREQ:        /* when LM requests ckt grp query */
@@ -1989,6 +1991,265 @@ ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit
        return FTDM_SUCCESS;
 }
 
+/******************************************************************************/
+ftdm_status_t handle_cgb_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
+{
+       SS7_FUNC_TRACE_ENTER(__FUNCTION__);
+
+       sngss7_chan_data_t      *sngss7_info = NULL;
+       sngss7_span_data_t      *sngss7_span = NULL;
+       ftdm_channel_t          *ftdmchan = NULL;
+       int                                     range;
+       uint8_t                         status[255];
+       int                                     blockType = 0;
+       int                                     byte = 0;
+       int                                     bit = 0;
+       int                             x;
+
+       memset(&status[0], '\0', sizeof(status));
+
+       /* 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;
+       }
+
+       /* grab the span info */
+       sngss7_span = ftdmchan->span->mod_data;
+
+       /* figure out what type of block needs to be applied */
+       if ((siStaEvnt->cgsmti.eh.pres == PRSNT_NODEF) && (siStaEvnt->cgsmti.typeInd.pres == PRSNT_NODEF)) {
+               blockType = siStaEvnt->cgsmti.typeInd.val;
+       } else {
+               SS7_ERROR("Received CGB with no circuit group supervision value on CIC = %d\n", sngss7_info->circuit->cic);
+               SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+               return FTDM_FAIL;
+       }       
+
+       /* pull out the range value */
+       if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.range.pres == PRSNT_NODEF)) {
+               range = siStaEvnt->rangStat.range.val;
+       } else {
+               SS7_ERROR("Received CGB with no range value on CIC = %d\n", sngss7_info->circuit->cic);
+               SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+               return FTDM_FAIL;
+       }
+
+       /* pull out the status field */
+       if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.status.pres == PRSNT_NODEF)) {
+               for (x = 0; x < siStaEvnt->rangStat.status.len; x++) {
+                       status[x] = siStaEvnt->rangStat.status.val[x];
+               }
+       } else {
+               SS7_ERROR("Received CGB with no status value on CIC = %d\n", sngss7_info->circuit->cic);
+               SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+               return FTDM_FAIL;
+       }
+
+       /* save the circuit, range and status */
+       sngss7_span->rx_cgb.circuit = circuit;
+       sngss7_span->rx_cgb.range = range;
+       sngss7_span->rx_cgb.type = blockType;
+       for (x = 0; x < siStaEvnt->rangStat.status.len; x++) {
+               sngss7_span->rx_cgb.status[x] = status[x];
+       }
+
+       /* loop over the cics starting from circuit until range+1 */
+       for (x = circuit; x < (circuit + range + 1); x++) {
+               /* grab the circuit in question */
+               if (extract_chan_data(x, &sngss7_info, &ftdmchan)) {
+                       SS7_ERROR("Failed to extract channel data for circuit = %d!\n", x);
+                       break;
+               }
+       
+               /* now that we have the right channel...put a lock on it so no-one else can use it */
+               ftdm_mutex_lock(ftdmchan->mutex);
+       
+               /* check if there is a pending state change, give it a bit to clear */
+               if (check_for_state_change(ftdmchan)) {
+                       SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic);
+                       ftdm_mutex_unlock(ftdmchan->mutex);
+                       SS7_ASSERT;
+               };
+
+#if 1
+               SS7_ERROR("KONRAD -> circuit=%d, byte=%d, bit=%d, status[byte]=%d, math=%d\n",
+                                       x,
+                                       byte,
+                                       bit,
+                                       status[byte],
+                                       (status[byte] & (1 << bit)));
+#endif
+               if (status[byte] & (1 << bit)) {
+                       switch (blockType) {
+                       /**********************************************************************/
+                       case 0: /* maintenance oriented */
+                               sngss7_set_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX);
+                               break;
+                       /**********************************************************************/
+                       case 1: /* hardware failure oriented */
+                               sngss7_set_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX);
+                               break;
+                       /**********************************************************************/
+                       case 2: /* reserved for national use */
+                               break;
+                       /**********************************************************************/
+                       default:
+                               break;
+                       /**********************************************************************/
+                       } /* switch (blockType) */
+               }
+
+               /* unlock the channel again before we exit */
+               ftdm_mutex_unlock(ftdmchan->mutex);
+
+               /* update the bit and byte counter*/
+               bit ++;
+               if (bit == 8) {
+                       byte++;
+                       bit = 0;
+               }
+
+       } /* for (x = circuit; x < (circuit + range + 1); x++) */
+
+       /* 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;
+       }
+
+       ft_to_sngss7_cgba(ftdmchan);
+
+       return FTDM_SUCCESS;
+}
+
+/******************************************************************************/
+ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
+{
+       SS7_FUNC_TRACE_ENTER(__FUNCTION__);
+
+       sngss7_chan_data_t      *sngss7_info = NULL;
+       sngss7_span_data_t      *sngss7_span = NULL;
+       ftdm_channel_t          *ftdmchan = NULL;
+       int                                     range;
+       uint8_t                         status[255];
+       int                                     blockType = 0;
+       int                                     byte = 0;
+       int                                     bit = 0;
+       int                             x;
+
+       memset(&status[0], '\0', sizeof(status));
+
+       /* 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;
+       }
+
+       /* grab the span info */
+       sngss7_span = ftdmchan->span->mod_data;
+
+       /* figure out what type of block needs to be applied */
+       if ((siStaEvnt->cgsmti.eh.pres == PRSNT_NODEF) && (siStaEvnt->cgsmti.typeInd.pres == PRSNT_NODEF)) {
+               blockType = siStaEvnt->cgsmti.typeInd.val;
+       } else {
+               SS7_ERROR("Received CGB with no circuit group supervision value on CIC = %d\n", sngss7_info->circuit->cic);
+               SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+               return FTDM_FAIL;
+       }       
+
+       /* pull out the range value */
+       if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.range.pres == PRSNT_NODEF)) {
+               range = siStaEvnt->rangStat.range.val;
+       } else {
+               SS7_ERROR("Received CGB with no range value on CIC = %d\n", sngss7_info->circuit->cic);
+               SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+               return FTDM_FAIL;
+       }
+
+       /* pull out the status field */
+       if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.status.pres == PRSNT_NODEF)) {
+               for (x = 0; x < siStaEvnt->rangStat.status.len; x++) {
+                       status[x] = siStaEvnt->rangStat.status.val[x];
+               }
+       } else {
+               SS7_ERROR("Received CGB with no status value on CIC = %d\n", sngss7_info->circuit->cic);
+               SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+               return FTDM_FAIL;
+       }
+
+       /* save the circuit, range and status */
+       sngss7_span->rx_cgu.circuit = circuit;
+       sngss7_span->rx_cgu.range = range;
+       sngss7_span->rx_cgu.type = blockType;
+       for (x = 0; x < siStaEvnt->rangStat.status.len; x++) {
+               sngss7_span->rx_cgu.status[x] = status[x];
+       }
+
+       /* loop over the cics starting from circuit until range+1 */
+       for (x = circuit; x < (circuit + range + 1); x++) {
+               /* grab the circuit in question */
+               if (extract_chan_data(x, &sngss7_info, &ftdmchan)) {
+                       SS7_ERROR("Failed to extract channel data for circuit = %d!\n", x);
+                       break;
+               }
+       
+               /* now that we have the right channel...put a lock on it so no-one else can use it */
+               ftdm_mutex_lock(ftdmchan->mutex);
+       
+               /* check if there is a pending state change, give it a bit to clear */
+               if (check_for_state_change(ftdmchan)) {
+                       SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic);
+                       ftdm_mutex_unlock(ftdmchan->mutex);
+                       SS7_ASSERT;
+               };
+
+               if (status[byte] & (1 << bit)) {
+                       switch (blockType) {
+                       /**********************************************************************/
+                       case 0: /* maintenance oriented */
+                               sngss7_clear_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX);
+                               break;
+                       /**********************************************************************/
+                       case 1: /* hardware failure oriented */
+                               sngss7_clear_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX);
+                               break;
+                       /**********************************************************************/
+                       case 2: /* reserved for national use */
+                               break;
+                       /**********************************************************************/
+                       default:
+                               break;
+                       /**********************************************************************/
+                       } /* switch (blockType) */
+               } /* */
+       
+               /* unlock the channel again before we exit */
+               ftdm_mutex_unlock(ftdmchan->mutex);
+
+               /* update the bit and byte counter*/
+               bit ++;
+               if (bit == 8) {
+                       byte++;
+                       bit = 0;
+               }
+
+       } /* for (x = circuit; x < (circuit + range + 1); x++) */
+
+       /* 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;
+       }
+
+       ft_to_sngss7_cgua(ftdmchan);
+
+       return FTDM_SUCCESS;
+}
 
 /******************************************************************************/
 /* For Emacs:
index 66efe1ab129ce0c8547d99e856a3212c5d86a8af..9986b29b2ca0a25d158b9d54c7e793d0d0bc4034 100644 (file)
@@ -272,10 +272,8 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
        ftdm_interrupt_t        *ftdm_sangoma_ss7_int[2];
        ftdm_span_t             *ftdmspan = (ftdm_span_t *) obj;
        ftdm_channel_t          *ftdmchan = NULL;
-       sngss7_chan_data_t  *sngss7_info = NULL;
        sngss7_event_data_t     *sngss7_event = NULL;
        sngss7_span_data_t      *sngss7_span = (sngss7_span_data_t *)ftdmspan->mod_data;
-       int                             i;
 
        ftdm_log (FTDM_LOG_INFO, "ftmod_sangoma_ss7 monitor thread for span=%u started.\n", ftdmspan->span_id);
 
@@ -344,73 +342,11 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
                /**********************************************************************/
                } /* switch ((ftdm_interrupt_wait(ftdm_sangoma_ss7_int, 100))) */
 
-               /* extract the span data structure */
-               sngss7_span = (sngss7_span_data_t *)ftdmspan->mod_data;
-
                /* check if there is a GRS being processed on the span */
                if (sngss7_span->rx_grs.range > 0) {
-                       ftdm_log(FTDM_LOG_DEBUG, "Found Rx GRS on span %d...checking circuits\n", ftdmspan->span_id);
-                       /*SS7_DEBUG("Found Rx GRS on span %d...checking circuits\n", ftdmspan->span_id);*/
-
-                       /* check all the circuits in the range to see if they are done resetting */
-                       for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
-
-                               /* extract the channel in question */
-                               if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
-                                       SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i);
-                                       SS7_ASSERT;
-                               }
-
-                               /* lock the channel */
-                               ftdm_mutex_lock(ftdmchan->mutex);
-
-                               /* check if there is a state change pending on the channel */
-                               if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
-                                       /* check the state to the GRP_RESET_RX_DN flag */
-                                       if (!sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) {
-                                               /* this channel is still resetting...do nothing */
-                                               goto GRS_UNLOCK_ALL;
-                                       } /* if (!sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) */
-                               } else {
-                                       /* state change pending */
-                                       goto GRS_UNLOCK_ALL;
-                               }
-                       } /* for ( i = circuit; i < (circuit + range + 1); i++) */
-
-                       SS7_DEBUG("All circuits out of reset for GRS: circuit=%d, range=%d\n",
-                                               sngss7_span->rx_grs.circuit,
-                                               sngss7_span->rx_grs.range);
-
-                       /* check all the circuits in the range to see if they are done resetting */
-                       for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
-
-                               /* extract the channel in question */
-                               if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
-                                       SS7_ERROR("Failed to extract channel data for circuit = %d!\n",i);
-                                       SS7_ASSERT;
-                               }
-
-                               /* throw the GRP reset flag complete flag */
-                               sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT);
-
-                               /* move the channel to the down state */
-                               ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
-
-                       } /* for ( i = circuit; i < (circuit + range + 1); i++) */
-
-GRS_UNLOCK_ALL:
-                       for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
-                               /* extract the channel in question */
-                               if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
-                                       SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i);
-                                       SS7_ASSERT;
-                               }
-
-                               /* unlock the channel */
-                               ftdm_mutex_unlock(ftdmchan->mutex);
-                       }
-
-               } /* if (ftdmspan->grs.range > 0) */
+                       /* check if the rx_grs has cleared */
+                       check_if_rx_grs_processed(ftdmspan);
+               } /* if (sngss7_span->rx_grs.range > 0) */
        } /* master while loop */
 
        /* clear the IN_THREAD flag so that we know the thread is done */
index 050f59e00ef41cc509c2251bb994bcd7f8413e5e..c9dbfb3ac85a9f170f36212a567ba516314205fd 100644 (file)
@@ -139,7 +139,6 @@ typedef struct sng_mtp_link {
                uint32_t        t23;
                uint32_t        t24;
                uint32_t        t25;
-               uint32_t        t26;
                uint32_t        t27;
                uint32_t        t28;
                uint32_t        t29;
@@ -188,6 +187,7 @@ typedef struct sng_route {
        uint32_t                t19;
        uint32_t                t21;
        uint32_t                t25;
+       uint32_t                t26;
 } sng_route_t;
 
 typedef struct sng_isup_intf {
@@ -329,6 +329,8 @@ typedef struct sngss7_glare_data {
 typedef struct sngss7_group_data {
        uint32_t                                circuit;
        uint32_t                                range;
+       uint8_t                                 status[255];
+       uint8_t                                 type;
 }sngss7_group_data_t;
 
 typedef struct sngss7_chan_data {
@@ -348,6 +350,10 @@ typedef struct sngss7_span_data {
        ftdm_sched_t                    *sched;
        sngss7_group_data_t             rx_grs;
        sngss7_group_data_t             tx_grs;
+       sngss7_group_data_t             rx_cgb;
+       sngss7_group_data_t             tx_cgb;
+       sngss7_group_data_t             rx_cgu;
+       sngss7_group_data_t             tx_cgu;
        ftdm_queue_t                    *event_queue;
 }sngss7_span_data_t;
 
@@ -376,8 +382,8 @@ typedef struct sngss7_event_data
 
 
 typedef enum {
-       FLAG_RESET_RX              = (1 << 0),
-       FLAG_RESET_TX              = (1 << 1),
+       FLAG_RESET_RX                   = (1 << 0),
+       FLAG_RESET_TX                   = (1 << 1),
        FLAG_RESET_SENT                 = (1 << 2),
        FLAG_RESET_TX_RSP               = (1 << 3),
        FLAG_GRP_RESET_RX               = (1 << 4),
@@ -387,27 +393,25 @@ typedef enum {
        FLAG_GRP_RESET_TX               = (1 << 8),
        FLAG_GRP_RESET_SENT             = (1 << 9),
        FLAG_GRP_RESET_TX_RSP   = (1 << 10),
-       FLAG_REMOTE_REL          = (1 << 11),
-       FLAG_LOCAL_REL            = (1 << 12),
-       FLAG_GLARE                        = (1 << 13),
-       FLAG_INFID_RESUME          = (1 << 14),
-       FLAG_INFID_PAUSED          = (1 << 15),
+       FLAG_REMOTE_REL                 = (1 << 11),
+       FLAG_LOCAL_REL                  = (1 << 12),
+       FLAG_GLARE                              = (1 << 13),
+       FLAG_INFID_RESUME               = (1 << 14),
+       FLAG_INFID_PAUSED               = (1 << 15),
        FLAG_CKT_UCIC_BLOCK             = (1 << 16),
        FLAG_CKT_UCIC_UNBLK             = (1 << 17),
        FLAG_CKT_LC_BLOCK_RX    = (1 << 18),
        FLAG_CKT_LC_UNBLK_RX    = (1 << 19),
        FLAG_CKT_MN_BLOCK_RX    = (1 << 20),
-       FLAG_CKT_MN_BLOCK_TX    = (1 << 21),
-       FLAG_CKT_MN_UNBLK_RX    = (1 << 22),
+       FLAG_CKT_MN_UNBLK_RX    = (1 << 21),
+       FLAG_CKT_MN_BLOCK_TX    = (1 << 22),
        FLAG_CKT_MN_UNBLK_TX    = (1 << 23),
        FLAG_GRP_HW_BLOCK_RX    = (1 << 24),
        FLAG_GRP_HW_BLOCK_TX    = (1 << 25),
        FLAG_GRP_MN_BLOCK_RX    = (1 << 26),
        FLAG_GRP_MN_BLOCK_TX    = (1 << 27),
-       FLAG_GRP_HW_UNBLK_RX    = (1 << 28),
-       FLAG_GRP_HW_UNBLK_TX    = (1 << 29),
-       FLAG_GRP_MN_UNBLK_RX    = (1 << 30),
-       FLAG_GRP_MN_UNBLK_TX    = (1 << 31)
+       FLAG_GRP_HW_UNBLK_TX    = (1 << 28),
+       FLAG_GRP_MN_UNBLK_TX    = (1 << 29)
 } flag_t;
 /******************************************************************************/
 
@@ -465,6 +469,8 @@ void ft_to_sngss7_uba(ftdm_channel_t *ftdmchan);
 void ft_to_sngss7_lpa(ftdm_channel_t *ftdmchan);
 void ft_to_sngss7_gra(ftdm_channel_t *ftdmchan);
 void ft_to_sngss7_grs(ftdm_channel_t *ftdmchan);
+void ft_to_sngss7_cgba(ftdm_channel_t * ftdmchan);
+void ft_to_sngss7_cgua(ftdm_channel_t * ftdmchan);
 
 void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
 void sngss7_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt);
@@ -524,6 +530,8 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa
 void handle_isup_t35(void *userdata);
 
 ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const char *data);
+
+ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan);
 /******************************************************************************/
 
 /* MACROS *********************************************************************/
index 4fac251c17d1b2f786457c3cab3f47e5162bdd90..079f5e3e22973b1621d1695cd488f137c616b0f7 100644 (file)
 /******************************************************************************/
 
 /* PROTOTYPES *****************************************************************/
-void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan);
-void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan);
-void ft_to_sngss7_anm (ftdm_channel_t * ftdmchan);
-void ft_to_sngss7_rel (ftdm_channel_t * ftdmchan);
-void ft_to_sngss7_rlc (ftdm_channel_t * ftdmchan);
+void ft_to_sngss7_iam(ftdm_channel_t * ftdmchan);
+void ft_to_sngss7_acm(ftdm_channel_t * ftdmchan);
+void ft_to_sngss7_anm(ftdm_channel_t * ftdmchan);
+void ft_to_sngss7_rel(ftdm_channel_t * ftdmchan);
+void ft_to_sngss7_rlc(ftdm_channel_t * ftdmchan);
 
-void ft_to_sngss7_rsc (ftdm_channel_t * ftdmchan);
-void ft_to_sngss7_rsca (ftdm_channel_t * ftdmchan);
+void ft_to_sngss7_rsc(ftdm_channel_t * ftdmchan);
+void ft_to_sngss7_rsca(ftdm_channel_t * ftdmchan);
 
-void ft_to_sngss7_blo (ftdm_channel_t * ftdmchan);
-void ft_to_sngss7_bla (ftdm_channel_t * ftdmchan);
-void ft_to_sngss7_ubl (ftdm_channel_t * ftdmchan);
-void ft_to_sngss7_uba (ftdm_channel_t * ftdmchan);
+void ft_to_sngss7_blo(ftdm_channel_t * ftdmchan);
+void ft_to_sngss7_bla(ftdm_channel_t * ftdmchan);
+void ft_to_sngss7_ubl(ftdm_channel_t * ftdmchan);
+void ft_to_sngss7_uba(ftdm_channel_t * ftdmchan);
 
-void ft_to_sngss7_lpa (ftdm_channel_t * ftdmchan);
+void ft_to_sngss7_lpa(ftdm_channel_t * ftdmchan);
 
-void ft_to_sngss7_gra (ftdm_channel_t * ftdmchan);
-void ft_to_sngss7_grs (ftdm_channel_t * ftdmchan);
+void ft_to_sngss7_gra(ftdm_channel_t * ftdmchan);
+void ft_to_sngss7_grs(ftdm_channel_t * ftdmchan);
+
+void ft_to_sngss7_cgba(ftdm_channel_t * ftdmchan);
+void ft_to_sngss7_cgua(ftdm_channel_t * ftdmchan);
 /******************************************************************************/
 
 /* FUNCTIONS ******************************************************************/
@@ -113,6 +116,56 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
        iam.txMedReq.eh.pres                            = PRSNT_NODEF;
        iam.txMedReq.trMedReq.pres                      = PRSNT_NODEF;
        iam.txMedReq.trMedReq.val                       = ftdmchan->caller_data.bearer_capability;
+
+       if ((g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].switchType == LSI_SW_ANS88) ||
+               (g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].switchType == LSI_SW_ANS92) ||
+               (g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].switchType == LSI_SW_ANS95)) {
+
+               iam.usrServInfoA.eh.pres                                = PRSNT_NODEF;
+
+               iam.usrServInfoA.infoTranCap.pres               = PRSNT_NODEF;
+               switch (ftdmchan->caller_data.bearer_capability) {
+               /**********************************************************************/
+               case (FTDM_BEARER_CAP_SPEECH):
+                       iam.usrServInfoA.infoTranCap.val        = 0x0;                  /* speech as per ATIS-1000113.3.2005 */
+                       break;
+               /**********************************************************************/
+               case (FTDM_BEARER_CAP_64K_UNRESTRICTED):
+                       iam.usrServInfoA.infoTranCap.val        = 0x8;                  /* unrestricted digital as per ATIS-1000113.3.2005 */
+                       break;
+               /**********************************************************************/
+               case (FTDM_BEARER_CAP_3_1KHZ_AUDIO):
+                       iam.usrServInfoA.infoTranCap.val        = 0x10;                 /* 3.1kHz audio as per ATIS-1000113.3.2005 */
+                       break;
+               /**********************************************************************/
+               default:
+                       SS7_ERROR_CHAN(ftdmchan, "Unknown Bearer capability falling back to speech%s\n", " ");
+                       iam.usrServInfoA.infoTranCap.val        = 0x0;                  /* speech as per ATIS-1000113.3.2005 */
+                       break;
+               /**********************************************************************/
+               } /* switch (ftdmchan->caller_data.bearer_capability) */
+
+               iam.usrServInfoA.cdeStand.pres                  = PRSNT_NODEF;
+               iam.usrServInfoA.cdeStand.val                   = 0x0;                          /* ITU-T standardized coding */
+               iam.usrServInfoA.tranMode.pres                  = PRSNT_NODEF;
+               iam.usrServInfoA.tranMode.val                   = 0x0;                          /* circuit mode */
+               iam.usrServInfoA.infoTranRate0.pres             = PRSNT_NODEF;
+               iam.usrServInfoA.infoTranRate0.val              = 0x10;                         /* 64kbps origination to destination */
+               iam.usrServInfoA.infoTranRate1.pres             = PRSNT_NODEF;
+               iam.usrServInfoA.infoTranRate1.val              = 0x10;                         /* 64kbps destination to origination */
+               iam.usrServInfoA.chanStruct.pres                = PRSNT_NODEF;
+               iam.usrServInfoA.chanStruct.val                 = 0x1;                          /* 8kHz integrity */
+               iam.usrServInfoA.config.pres                    = PRSNT_NODEF;
+               iam.usrServInfoA.config.val                             = 0x0;                          /* point to point configuration */
+               iam.usrServInfoA.establish.pres                 = PRSNT_NODEF;
+               iam.usrServInfoA.establish.val                  = 0x0;                          /* on demand */
+               iam.usrServInfoA.symmetry.pres                  = PRSNT_NODEF;
+               iam.usrServInfoA.symmetry.val                   = 0x0;                          /* bi-directional symmetric */
+               iam.usrServInfoA.usrInfLyr1Prot.pres    = PRSNT_NODEF;
+               iam.usrServInfoA.usrInfLyr1Prot.val             = 0x2;                          /* G.711 ulaw */
+               iam.usrServInfoA.rateMultiplier.pres    = PRSNT_NODEF;
+               iam.usrServInfoA.rateMultiplier.val             = 0x1;                          /* 1x rate multipler */
+       } /* if ANSI */
        
        /* copy down the called number information */
        copy_cdPtyNum_to_sngss7 (&ftdmchan->caller_data, &iam.cdPtyNum);
@@ -126,7 +179,7 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
                                                sngss7_info->circuit->id, 
                                                &iam, 
                                                0);
-       
+
        SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx IAM\n");
        
        SS7_FUNC_TRACE_EXIT (__FUNCTION__);
@@ -463,7 +516,7 @@ void ft_to_sngss7_grs (ftdm_channel_t * ftdmchan)
        
        SiStaEvnt grs;
        
-       memset (&grs, 0x0, sizeof (grs));
+       memset (&grs, 0x0, sizeof(grs));
        
        grs.rangStat.eh.pres    = PRSNT_NODEF;
        grs.rangStat.range.pres = PRSNT_NODEF;
@@ -485,6 +538,101 @@ void ft_to_sngss7_grs (ftdm_channel_t * ftdmchan)
 return;
 }
 
+/******************************************************************************/
+void ft_to_sngss7_cgba(ftdm_channel_t * ftdmchan)
+{      
+       SS7_FUNC_TRACE_ENTER (__FUNCTION__);
+       
+       sngss7_span_data_t      *sngss7_span = ftdmchan->span->mod_data;
+       sngss7_chan_data_t      *sngss7_info = ftdmchan->call_data;
+       int                                     x = 0;
+       
+       SiStaEvnt cgba;
+
+       memset (&cgba, 0x0, sizeof(cgba));
+
+       /* fill in the circuit group supervisory message */
+       cgba.cgsmti.eh.pres = PRSNT_NODEF;
+       cgba.cgsmti.typeInd.pres = PRSNT_NODEF;
+       cgba.cgsmti.typeInd.val = sngss7_span->rx_cgb.type;
+
+       cgba.rangStat.eh.pres = PRSNT_NODEF;
+       /* fill in the range */ 
+       cgba.rangStat.range.pres = PRSNT_NODEF;
+       cgba.rangStat.range.val = sngss7_span->rx_cgb.range;
+       /* fill in the status */
+       cgba.rangStat.status.pres = PRSNT_NODEF;
+       cgba.rangStat.status.len = ((sngss7_span->rx_cgb.range + 1) >> 3) + (((sngss7_span->rx_cgb.range + 1) & 0x07) ? 1 : 0);
+       for(x = 0; x < cgba.rangStat.status.len; x++){
+               cgba.rangStat.status.val[x] = sngss7_span->rx_cgb.status[x];
+       }
+
+       sng_cc_sta_request (1,
+                                               0,
+                                               0,
+                                               sngss7_span->rx_cgb.circuit,
+                                               0,
+                                               SIT_STA_CGBRSP,
+                                               &cgba);
+       
+       SS7_INFO_CHAN(ftdmchan, "Tx CGBA (%d:%d)\n",
+                                                       sngss7_info->circuit->cic,
+                                                       (sngss7_info->circuit->cic + sngss7_span->rx_cgb.range));
+
+       /* clean out the saved data */
+       memset(&sngss7_span->rx_cgb, 0x0, sizeof(sngss7_group_data_t));
+
+       SS7_FUNC_TRACE_EXIT (__FUNCTION__);
+       return;
+}
+
+/******************************************************************************/
+void ft_to_sngss7_cgua(ftdm_channel_t * ftdmchan)
+{      
+       SS7_FUNC_TRACE_ENTER (__FUNCTION__);
+       
+       sngss7_span_data_t      *sngss7_span = ftdmchan->span->mod_data;
+       sngss7_chan_data_t      *sngss7_info = ftdmchan->call_data;
+       int                                     x = 0;
+       
+       SiStaEvnt cgua;
+
+       memset (&cgua, 0x0, sizeof(cgua));
+
+       /* fill in the circuit group supervisory message */
+       cgua.cgsmti.eh.pres = PRSNT_NODEF;
+       cgua.cgsmti.typeInd.pres = PRSNT_NODEF;
+       cgua.cgsmti.typeInd.val = sngss7_span->rx_cgu.type;
+
+       cgua.rangStat.eh.pres = PRSNT_NODEF;
+       /* fill in the range */ 
+       cgua.rangStat.range.pres = PRSNT_NODEF;
+       cgua.rangStat.range.val = sngss7_span->rx_cgu.range;
+       /* fill in the status */
+       cgua.rangStat.status.pres = PRSNT_NODEF;
+       cgua.rangStat.status.len = ((sngss7_span->rx_cgu.range + 1) >> 3) + (((sngss7_span->rx_cgu.range + 1) & 0x07) ? 1 : 0);
+       for(x = 0; x < cgua.rangStat.status.len; x++){
+               cgua.rangStat.status.val[x] = sngss7_span->rx_cgu.status[x];
+       }
+
+       sng_cc_sta_request (1,
+                                               0,
+                                               0,
+                                               sngss7_span->rx_cgu.circuit,
+                                               0,
+                                               SIT_STA_CGURSP,
+                                               &cgua);
+       
+       SS7_INFO_CHAN(ftdmchan, "Tx CGUA (%d:%d)\n",
+                                                       sngss7_info->circuit->cic,
+                                                       (sngss7_info->circuit->cic + sngss7_span->rx_cgu.range));
+
+       /* clean out the saved data */
+       memset(&sngss7_span->rx_cgu, 0x0, sizeof(sngss7_group_data_t));
+
+       SS7_FUNC_TRACE_EXIT (__FUNCTION__);
+       return;
+}
 /******************************************************************************/
 /* For Emacs:
  * Local Variables:
index 97957f3c821740c34e61c4bf79366ac47323d711..4ec57fe049593d551649cd234fb1c9edf83514b4 100644 (file)
@@ -57,6 +57,7 @@ unsigned long get_unique_id(void);
 
 ftdm_status_t extract_chan_data(uint32_t circuit, sngss7_chan_data_t **sngss7_info, ftdm_channel_t **ftdmchan);
 
+ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan);
 /******************************************************************************/
 
 /* FUNCTIONS ******************************************************************/
@@ -451,6 +452,78 @@ unsigned long get_unique_id(void)
 }
 
 /******************************************************************************/
+ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan)
+{
+       ftdm_channel_t          *ftdmchan = NULL;
+       sngss7_chan_data_t  *sngss7_info = NULL;
+       sngss7_span_data_t      *sngss7_span = (sngss7_span_data_t *)ftdmspan->mod_data;
+       int                             i;
+
+       ftdm_log(FTDM_LOG_DEBUG, "Found Rx GRS on span %d...checking circuits\n", ftdmspan->span_id);
+
+       /* check all the circuits in the range to see if they are done resetting */
+       for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
+
+               /* extract the channel in question */
+               if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
+                       SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i);
+                       SS7_ASSERT;
+               }
+
+               /* lock the channel */
+               ftdm_mutex_lock(ftdmchan->mutex);
+
+               /* check if there is a state change pending on the channel */
+               if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
+                       /* check the state to the GRP_RESET_RX_DN flag */
+                       if (!sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) {
+                               /* this channel is still resetting...do nothing */
+                                       goto GRS_UNLOCK_ALL;
+                               } /* if (!sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) */
+                       } else {
+                               /* state change pending */
+                               goto GRS_UNLOCK_ALL;
+                       }
+               } /* for ( i = circuit; i < (circuit + range + 1); i++) */
+
+               SS7_DEBUG("All circuits out of reset for GRS: circuit=%d, range=%d\n",
+                                               sngss7_span->rx_grs.circuit,
+                                               sngss7_span->rx_grs.range);
+
+               /* check all the circuits in the range to see if they are done resetting */
+               for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
+
+                       /* extract the channel in question */
+                       if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
+                               SS7_ERROR("Failed to extract channel data for circuit = %d!\n",i);
+                               SS7_ASSERT;
+                       }
+
+                       /* throw the GRP reset flag complete flag */
+                       sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT);
+
+                       /* move the channel to the down state */
+                       ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
+
+               } /* for ( i = circuit; i < (circuit + range + 1); i++) */
+
+GRS_UNLOCK_ALL:
+               for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
+                       /* extract the channel in question */
+                       if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
+                               SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i);
+                               SS7_ASSERT;
+                       }
+
+                       /* unlock the channel */
+                       ftdm_mutex_unlock(ftdmchan->mutex);
+               }
+
+       return FTDM_SUCCESS;
+}
+
+/******************************************************************************/
+
 
 /******************************************************************************/
 /* For Emacs:
index aa639d1c3a35d76ac8b5a3991693368325af2ea6..4ebf3b95fd6cef67b2789ed16a5b568dc5775d33 100644 (file)
@@ -551,6 +551,15 @@ static int ftmod_ss7_parse_mtp_link(ftdm_conf_node_t *mtp_link, sng_mtp_link_t *
                        } else if (!strcasecmp(parm->val, "INDIA")) {
                                mtpLink->mtp3.switchType = LSI_SW_INDIA;
                                SS7_DEBUG("\tFoundmtpLink->switchType = \"INDIA\"\n");
+                       } else if (!strcasecmp(parm->val, "ansi88")) {
+                               mtpLink->mtp3.switchType = LSI_SW_ANS88;
+                               SS7_DEBUG("\tFoundmtpLink->switchType = \"ANSI88\"\n");
+                       } else if (!strcasecmp(parm->val, "ansi92")) {
+                               mtpLink->mtp3.switchType = LSI_SW_ANS92;
+                               SS7_DEBUG("\tFoundmtpLink->switchType = \"ANSI92\"\n");
+                       } else if (!strcasecmp(parm->val, "ansi95")) {
+                               mtpLink->mtp3.switchType = LSI_SW_ANS95;
+                               SS7_DEBUG("\tFoundmtpLink->switchType = \"ANSI95\"\n");
                        } else {
                                SS7_ERROR("\tFound an invalid linktype of \"%s\"!\n", parm->val);
                                return FTDM_FAIL;
@@ -1159,6 +1168,11 @@ static int ftmod_ss7_fill_in_mtp3_route(sng_route_t *mtp3_route)
        } else {
                g_ftdm_sngss7_data.cfg.mtpRoute[i].t25     = 100;
        }
+       if (mtp3_route->t26 != 0) {
+               g_ftdm_sngss7_data.cfg.mtpRoute[i].t26          = mtp3_route->t26;
+       } else {
+               g_ftdm_sngss7_data.cfg.mtpRoute[i].t26     = 100;
+       }
 
        return 0;
 }