From c219a73c0634a4b93e021e984589da5dc8f3b2b4 Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Tue, 7 Sep 2010 17:44:43 -0400 Subject: [PATCH] freetdm: ss7- added support for incoming group blocks, started adding support for ansi --- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c | 67 +++-- .../ftmod_sangoma_ss7_handle.c | 271 +++++++++++++++++- .../ftmod_sangoma_ss7_main.c | 70 +---- .../ftmod_sangoma_ss7_main.h | 36 ++- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c | 180 ++++++++++-- .../ftmod_sangoma_ss7_support.c | 73 +++++ .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c | 14 + 7 files changed, 588 insertions(+), 123 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c index c8c8bc3dd1..44764295d4 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c @@ -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; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c index f0cfa0237a..0c3dcffec0 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c @@ -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: diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c index 66efe1ab12..9986b29b2c 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c @@ -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 */ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h index 050f59e00e..c9dbfb3ac8 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h @@ -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 *********************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c index 4fac251c17..079f5e3e22 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c @@ -42,24 +42,27 @@ /******************************************************************************/ /* 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: diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c index 97957f3c82..4ec57fe049 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c @@ -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: diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c index aa639d1c3a..4ebf3b95fd 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c @@ -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; }