From c219a73c0634a4b93e021e984589da5dc8f3b2b4 Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Tue, 7 Sep 2010 17:44:43 -0400 Subject: [PATCH 01/25] 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; } From dc51ccbec18a223beccfc5f8cbde063e6950e0bd Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Tue, 7 Sep 2010 13:28:30 -0400 Subject: [PATCH 02/25] freetdm:ftmod_sangoma_isdn changes Minor fixes to glare testing, add check for INBAND TONES available in ALERT msgs Fix for handling T310 expiring Minor fixes to glare testing Fixed handling for Progress with cause Support for facility timeout --- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.c | 13 ++- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.h | 15 ++- .../ftmod_sangoma_isdn_cfg.c | 5 + .../ftmod_sangoma_isdn_stack_hndl.c | 69 +++++++++++-- .../ftmod_sangoma_isdn_stack_rcv.c | 99 +++++++++---------- .../ftmod_sangoma_isdn_support.c | 24 ++++- 6 files changed, 156 insertions(+), 69 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c index 9ffd7097a3..e962eceb28 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c @@ -189,7 +189,8 @@ ftdm_state_map_t sangoma_isdn_state_map = { ZSD_OUTBOUND, ZSM_UNACCEPTABLE, {FTDM_CHANNEL_STATE_DIALING, FTDM_END}, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_DOWN, FTDM_END} + {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS, + FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_DOWN, FTDM_END} }, { ZSD_OUTBOUND, @@ -558,6 +559,9 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan) /* We are hangup local call because there was a glare, we are waiting for a RELEASE on this call, before we can process the saved call */ ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Waiting for RELEASE on hungup glared call\n"); + } else if (sngisdn_test_flag(sngisdn_info, FLAG_SEND_DISC)) { + /* Remote side sent a PROGRESS message, but cause indicates disconnect or T310 expired*/ + sngisdn_snd_disconnect(ftdmchan); } else { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Hanging up call upon local request!\n"); @@ -568,16 +572,15 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan) if (ftdmchan->last_state == FTDM_CHANNEL_STATE_RING || ftdmchan->last_state == FTDM_CHANNEL_STATE_DIALING) { + sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT); + sngisdn_snd_release(ftdmchan, 0); + if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) { sng_isdn_set_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN); } - - sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT); - sngisdn_snd_release(ftdmchan, 0); } else { sngisdn_snd_disconnect(ftdmchan); } - } /* now go to the HANGUP complete state */ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h index 3f63fbc1d4..5f26828529 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h @@ -68,6 +68,7 @@ typedef enum { FLAG_GLARE = (1 << 6), FLAG_DELAYED_REL = (1 << 7), FLAG_SENT_PROCEED = (1 << 8), + FLAG_SEND_DISC = (1 << 9), } sngisdn_flag_t; @@ -127,6 +128,13 @@ typedef enum { SNGISDN_EVENT_RST_IND, } ftdm_sngisdn_event_id_t; +/* Only timers that can be cancelled are listed here */ +#define SNGISDN_NUM_TIMERS 1 +/* Increase NUM_TIMERS as number of ftdm_sngisdn_timer_t increases */ +typedef enum { + SNGISDN_TIMER_FACILITY = 0, +} ftdm_sngisdn_timer_t; + typedef struct sngisdn_glare_data { int16_t suId; uint32_t suInstId; @@ -148,6 +156,7 @@ typedef struct sngisdn_chan_data { uint8_t globalFlg; sngisdn_glare_data_t glare; + ftdm_timer_t *timers[SNGISDN_NUM_TIMERS]; } sngisdn_chan_data_t; /* Span specific data */ @@ -165,6 +174,7 @@ typedef struct sngisdn_span_data { uint8_t overlap_dial; uint8_t setup_arb; uint8_t facility; + int8_t facility_timeout; ftdm_sched_t *sched; ftdm_queue_t *event_queue; } sngisdn_span_data_t; @@ -223,8 +233,8 @@ typedef struct sngisdn_cc { ftdm_trunk_type_t trunktype; uint32_t last_suInstId; ftdm_mutex_t *mutex; - sngisdn_chan_data_t *active_spInstIds[MAX_INSTID]; - sngisdn_chan_data_t *active_suInstIds[MAX_INSTID]; + sngisdn_chan_data_t *active_spInstIds[MAX_INSTID+1]; + sngisdn_chan_data_t *active_suInstIds[MAX_INSTID+1]; }sngisdn_cc_t; /* Global sngisdn data */ @@ -349,6 +359,7 @@ void sngisdn_set_span_sig_status(ftdm_span_t *ftdmspan, ftdm_signaling_status_t void sngisdn_delayed_release(void* p_sngisdn_info); void sngisdn_delayed_connect(void* p_sngisdn_info); void sngisdn_delayed_disconnect(void* p_sngisdn_info); +void sngisdn_facility_timeout(void* p_sngisdn_info); /* Stack management functions */ ftdm_status_t sng_isdn_stack_cfg(ftdm_span_t *span); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c index ec44142303..96eaf051a2 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c @@ -249,6 +249,11 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_ ftdm_span_set_bearer_capability(val, &span->default_caller_data.bearer_capability); } else if (!strcasecmp(var, "outbound-bearer_layer1")) { ftdm_span_set_bearer_layer1(val, &span->default_caller_data.bearer_layer1); + } else if (!strcasecmp(var, "facility-timeout")) { + signal_data->facility_timeout = atoi(val); + if (signal_data->facility_timeout < 0) { + signal_data->facility_timeout = 0; + } } else { ftdm_log(FTDM_LOG_WARNING, "Ignoring unknown parameter %s\n", ftdm_parameters[paramindex].var); } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c index c3d97e5c5c..ff9a53b294 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c @@ -78,14 +78,13 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) } sngisdn_info->suInstId = get_unique_suInstId(suId); - sngisdn_info->spInstId = spInstId; + sngisdn_info->spInstId = spInstId; /* If this is a glared call that was previously saved, we moved all the info to the current call, so clear the glared saved data */ - if (sngisdn_info->glare.spInstId == spInstId) { clear_call_glare_data(sngisdn_info); - } + } ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex); g_sngisdn_data.ccs[suId].active_suInstIds[sngisdn_info->suInstId] = sngisdn_info; @@ -105,7 +104,8 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_TEMPORARY_FAILURE; ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL); break; - } + } + /* Fill in call information */ cpy_calling_num_from_stack(&ftdmchan->caller_data, &conEvnt->cgPtyNmb); cpy_called_num_from_stack(&ftdmchan->caller_data, &conEvnt->cdPtyNmb); @@ -142,6 +142,10 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) if (ret_val == 1) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Expecting Caller name in FACILITY\n"); ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_GET_CALLERID); + /* Launch timer in case we never get a FACILITY msg */ + if (signal_data->facility_timeout) { + ftdm_sched_timer(signal_data->sched, "facility_timeout", signal_data->facility_timeout, sngisdn_facility_timeout, (void*) sngisdn_info, &sngisdn_info->timers[SNGISDN_TIMER_FACILITY]); + } break; } else if (ret_val == 0) { strcpy(ftdmchan->caller_data.cid_name, retrieved_str); @@ -289,6 +293,8 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info; ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; + CnStEvnt *cnStEvnt = &sngisdn_event->event.cnStEvnt; ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n"); @@ -302,19 +308,49 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) suId, suInstId, spInstId, ces); switch(evntType) { + case MI_PROGRESS: + if (signal_data->switchtype == SNGISDN_SWITCH_NI2 && + cnStEvnt->causeDgn[0].eh.pres && cnStEvnt->causeDgn[0].causeVal.pres) { + + switch(cnStEvnt->causeDgn[0].causeVal.val) { + case 17: /* User Busy */ + case 18: /* No User responding */ + case 19: /* User alerting, no answer */ + case 21: /* Call rejected, the called party does not with to accept this call */ + case 27: /* Destination out of order */ + case 31: /* Normal, unspecified */ + case 34: /* Circuit/Channel congestion */ + case 41: /* Temporary failure */ + case 42: /* Switching equipment is experiencing a period of high traffic */ + case 47: /* Resource unavailable */ + case 58: /* Bearer Capability not available */ + case 63: /* Service or option not available */ + case 65: /* Bearer Cap not implemented, not supported */ + case 79: /* Service or option not implemented, unspecified */ + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Cause requires disconnect (cause:%d)\n", cnStEvnt->causeDgn[0].causeVal.val); + ftdmchan->caller_data.hangup_cause = cnStEvnt->causeDgn[0].causeVal.val; + + sngisdn_set_flag(sngisdn_info, FLAG_SEND_DISC); + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); + goto sngisdn_process_cnst_ind_end; + } + } + /* fall-through */ case MI_ALERTING: case MI_CALLPROC: - case MI_PROGRESS: + switch(ftdmchan->state) { - case FTDM_CHANNEL_STATE_DIALING: - if (evntType == MI_PROGRESS) { + case FTDM_CHANNEL_STATE_DIALING: + if (evntType == MI_PROGRESS || + (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL)) { ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); } else { ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS); } break; case FTDM_CHANNEL_STATE_PROGRESS: - if (evntType == MI_PROGRESS) { + if (evntType == MI_PROGRESS || + (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL)) { ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); } break; @@ -371,6 +407,7 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) break; } +sngisdn_process_cnst_ind_end: ISDN_FUNC_TRACE_EXIT(__FUNCTION__); return; } @@ -638,12 +675,14 @@ void sngisdn_process_flc_ind (sngisdn_event_data_t *sngisdn_event) void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event) { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); + int16_t suId = sngisdn_event->suId; uint32_t suInstId = sngisdn_event->suInstId; uint32_t spInstId = sngisdn_event->spInstId; sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info; ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; FacEvnt *facEvnt = &sngisdn_event->event.facEvnt; @@ -659,10 +698,16 @@ void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event) if (sng_isdn_retrieve_facility_caller_name(facility_str, facEvnt->facElmt.facStr.len, retrieved_str) != FTDM_SUCCESS) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Failed to retrieve Caller Name from Facility IE\n"); } + /* Cancel facility timeout */ + ftdm_sched_cancel_timer(signal_data->sched, &sngisdn_info->timers[SNGISDN_TIMER_FACILITY]); } ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING); break; + case FTDM_CHANNEL_STATE_RING: + /* We received the caller ID Name in FACILITY, but its too late, facility-timeout already occurred */ + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "FACILITY received, but we already proceeded with call\n"); + break; default: /* We do not support other FACILITY types for now, so do nothing */ break; @@ -794,6 +839,14 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event) break; case 3: switch (ftdmchan->state) { + case FTDM_CHANNEL_STATE_PROGRESS: + /* T310 timer has expired */ + ftdmchan->caller_data.hangup_cause = staEvnt->causeDgn[0].causeVal.val; + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "T310 Timer expired, hanging up call\n"); + sngisdn_set_flag(sngisdn_info, FLAG_SEND_DISC); + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); + + break; case FTDM_CHANNEL_STATE_UP: /* Remote side is still waiting for our CONNECT message */ if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c index 29cfb2330e..f921b1be8c 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c @@ -45,8 +45,8 @@ void sngisdn_rcv_con_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Co { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); uint8_t bchan_no = 0; - sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_chan_data_t *sngisdn_info = NULL; + sngisdn_event_data_t *sngisdn_event = NULL; ftdm_assert(g_sngisdn_data.ccs[suId].activation_done != 0, "Con Ind on unconfigured cc\n"); ftdm_assert(g_sngisdn_data.dchans[dChan].num_spans != 0, "Con Ind on unconfigured dchan\n"); @@ -96,7 +96,7 @@ void sngisdn_rcv_con_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Co ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex); memcpy(&sngisdn_event->event.conEvnt, conEvnt, sizeof(*conEvnt)); - + ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); ISDN_FUNC_TRACE_EXIT(__FUNCTION__); } @@ -104,8 +104,8 @@ void sngisdn_rcv_con_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Co void sngisdn_rcv_con_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, int16_t dChan, uint8_t ces) { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); - sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_chan_data_t *sngisdn_info = NULL; + sngisdn_event_data_t *sngisdn_event = NULL; ftdm_assert(g_sngisdn_data.ccs[suId].activation_done != 0, "Con Cfm on unconfigured cc\n"); ftdm_assert(g_sngisdn_data.dchans[dChan].num_spans != 0, "Con Cfm on unconfigured dchan\n"); @@ -118,6 +118,7 @@ void sngisdn_rcv_con_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, Cn if (!sngisdn_info->spInstId) { ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex); + sngisdn_info->spInstId = spInstId; g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info; ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex); @@ -146,8 +147,8 @@ void sngisdn_rcv_con_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, Cn void sngisdn_rcv_cnst_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, uint8_t evntType, int16_t dChan, uint8_t ces) { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); - sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_chan_data_t *sngisdn_info = NULL; + sngisdn_event_data_t *sngisdn_event = NULL; ftdm_assert(g_sngisdn_data.ccs[suId].activation_done != 0, "Cnst Ind on unconfigured cc\n"); ftdm_assert(g_sngisdn_data.dchans[dChan].num_spans != 0, "Cnst Ind on unconfigured dchan\n"); @@ -160,6 +161,7 @@ void sngisdn_rcv_cnst_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, C if (!sngisdn_info->spInstId) { ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex); + sngisdn_info->spInstId = spInstId; g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info; ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex); @@ -188,15 +190,15 @@ void sngisdn_rcv_cnst_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, C memcpy(&sngisdn_event->event.cnStEvnt, cnStEvnt, sizeof(*cnStEvnt)); - ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); + ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); ISDN_FUNC_TRACE_EXIT(__FUNCTION__); } void sngisdn_rcv_disc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, DiscEvnt *discEvnt) { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); - sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_chan_data_t *sngisdn_info = NULL; + sngisdn_event_data_t *sngisdn_event = NULL; ftdm_assert(spInstId != 0, "Received DISCONNECT with invalid id"); @@ -207,13 +209,6 @@ void sngisdn_rcv_disc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, D ftdm_assert(0, "Inconsistent call states\n"); return; } - - if (!sngisdn_info->spInstId) { - ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex); - sngisdn_info->spInstId = spInstId; - g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info; - ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex); - } ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received DISCONNECT (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); @@ -229,7 +224,7 @@ void sngisdn_rcv_disc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, D memcpy(&sngisdn_event->event.discEvnt, discEvnt, sizeof(*discEvnt)); - ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); + ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); ISDN_FUNC_TRACE_EXIT(__FUNCTION__); } @@ -237,8 +232,8 @@ void sngisdn_rcv_disc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, D void sngisdn_rcv_rel_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, RelEvnt *relEvnt) { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); - sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_chan_data_t *sngisdn_info = NULL; + sngisdn_event_data_t *sngisdn_event = NULL; if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { @@ -251,7 +246,7 @@ void sngisdn_rcv_rel_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Re ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received RELEASE/RELEASE COMPLETE (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_REL_IND; @@ -270,7 +265,7 @@ void sngisdn_rcv_dat_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, In { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_event_data_t *sngisdn_event = NULL; if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { @@ -283,7 +278,7 @@ void sngisdn_rcv_dat_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, In ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received DATA IND suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId); sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_DAT_IND; @@ -302,7 +297,7 @@ void sngisdn_rcv_sshl_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, S { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_event_data_t *sngisdn_event = NULL; if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { @@ -315,7 +310,7 @@ void sngisdn_rcv_sshl_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, S ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received SSHL IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_SSHL_IND; @@ -335,7 +330,7 @@ void sngisdn_rcv_sshl_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, S { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_event_data_t *sngisdn_event = NULL; if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { @@ -348,7 +343,7 @@ void sngisdn_rcv_sshl_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, S ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received SSHL CFM (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_SSHL_CFM; @@ -360,14 +355,14 @@ void sngisdn_rcv_sshl_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, S memcpy(&sngisdn_event->event.ssHlEvnt, ssHlEvnt, sizeof(*ssHlEvnt)); - ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); + ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); ISDN_FUNC_TRACE_EXIT(__FUNCTION__); } void sngisdn_rcv_rmrt_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action) { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_event_data_t *sngisdn_event = NULL; if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { @@ -380,7 +375,7 @@ void sngisdn_rcv_rmrt_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, R ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received RMRT IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_RMRT_IND; @@ -392,7 +387,7 @@ void sngisdn_rcv_rmrt_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, R memcpy(&sngisdn_event->event.rmRtEvnt, rmRtEvnt, sizeof(*rmRtEvnt)); - ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); + ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); ISDN_FUNC_TRACE_EXIT(__FUNCTION__); } @@ -400,7 +395,7 @@ void sngisdn_rcv_rmrt_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, R { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_event_data_t *sngisdn_event = NULL; if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { @@ -413,7 +408,7 @@ void sngisdn_rcv_rmrt_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, R ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received RESUME/RETRIEVE CFM (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_RMRT_CFM; @@ -425,7 +420,7 @@ void sngisdn_rcv_rmrt_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, R memcpy(&sngisdn_event->event.rmRtEvnt, rmRtEvnt, sizeof(*rmRtEvnt)); - ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); + ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); ISDN_FUNC_TRACE_EXIT(__FUNCTION__); } @@ -433,7 +428,7 @@ void sngisdn_rcv_flc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, St { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_event_data_t *sngisdn_event = NULL; if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { @@ -446,7 +441,7 @@ void sngisdn_rcv_flc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, St ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received FLOW CONTROL IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_FLC_IND; @@ -457,7 +452,7 @@ void sngisdn_rcv_flc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, St memcpy(&sngisdn_event->event.staEvnt, staEvnt, sizeof(*staEvnt)); - ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); + ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); ISDN_FUNC_TRACE_EXIT(__FUNCTION__); } @@ -466,7 +461,7 @@ void sngisdn_rcv_fac_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Fa { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_event_data_t *sngisdn_event = NULL; if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { @@ -478,7 +473,7 @@ void sngisdn_rcv_fac_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Fa ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received FACILITY IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_FAC_IND; @@ -499,7 +494,7 @@ void sngisdn_rcv_sta_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, St { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_event_data_t *sngisdn_event = NULL; if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { @@ -512,7 +507,7 @@ void sngisdn_rcv_sta_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, St ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received STATUS CONFIRM (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_STA_CFM; @@ -532,7 +527,7 @@ void sngisdn_rcv_srv_ind (int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces ISDN_FUNC_TRACE_ENTER(__FUNCTION__); unsigned i; sngisdn_span_data_t *signal_data; - sngisdn_event_data_t *sngisdn_event; + sngisdn_event_data_t *sngisdn_event = NULL; ftdm_log(FTDM_LOG_INFO, "Received SERVICE IND (dChan:%d ces:%u)\n", dChan, ces); @@ -540,7 +535,7 @@ void sngisdn_rcv_srv_ind (int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces for(i=1; i<=g_sngisdn_data.dchans[dChan].num_spans; i++) { signal_data = g_sngisdn_data.dchans[dChan].spans[i]; sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_SRV_IND; @@ -550,7 +545,7 @@ void sngisdn_rcv_srv_ind (int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces sngisdn_event->signal_data = signal_data; memcpy(&sngisdn_event->event.srvEvnt, srvEvnt, sizeof(*srvEvnt)); - ftdm_queue_enqueue((signal_data)->event_queue, sngisdn_event); + ftdm_queue_enqueue((signal_data)->event_queue, sngisdn_event); } ISDN_FUNC_TRACE_EXIT(__FUNCTION__); } @@ -560,8 +555,8 @@ void sngisdn_rcv_srv_cfm (int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); unsigned i; - sngisdn_span_data_t *signal_data; - sngisdn_event_data_t *sngisdn_event; + sngisdn_span_data_t *signal_data = NULL; + sngisdn_event_data_t *sngisdn_event = NULL; ftdm_log(FTDM_LOG_INFO, "Received SERVICE CFM (dChan:%d ces:%u)\n", dChan, ces); @@ -569,7 +564,7 @@ void sngisdn_rcv_srv_cfm (int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces for(i=1; i<=g_sngisdn_data.dchans[dChan].num_spans; i++) { signal_data = g_sngisdn_data.dchans[dChan].spans[i]; sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_SRV_CFM; @@ -588,8 +583,8 @@ void sngisdn_rcv_rst_ind (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); unsigned i; - sngisdn_span_data_t *signal_data; - sngisdn_event_data_t *sngisdn_event; + sngisdn_span_data_t *signal_data = NULL; + sngisdn_event_data_t *sngisdn_event = NULL; ftdm_log(FTDM_LOG_INFO, "Received RESTART IND (dChan:%d ces:%u type:%u)\n", dChan, ces, evntType); @@ -597,7 +592,7 @@ void sngisdn_rcv_rst_ind (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces for(i=1; i<=g_sngisdn_data.dchans[dChan].num_spans; i++) { signal_data = g_sngisdn_data.dchans[dChan].spans[i]; sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_RST_IND; @@ -618,7 +613,7 @@ void sngisdn_rcv_rst_cfm (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces ISDN_FUNC_TRACE_ENTER(__FUNCTION__); unsigned i; sngisdn_span_data_t *signal_data; - sngisdn_event_data_t *sngisdn_event; + sngisdn_event_data_t *sngisdn_event = NULL; ftdm_log(FTDM_LOG_INFO, "Received RESTART CFM (dChan:%d ces:%u type:%u)\n", dChan, ces, evntType); @@ -626,7 +621,7 @@ void sngisdn_rcv_rst_cfm (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces for(i=1; i<=g_sngisdn_data.dchans[dChan].num_spans; i++) { signal_data = g_sngisdn_data.dchans[dChan].spans[i]; sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_RST_CFM; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c index 29e7994c87..5e37e0c684 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c @@ -73,8 +73,10 @@ void __inline__ clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info) sngisdn_info->glare.suInstId, sngisdn_info->glare.spInstId, sngisdn_info->suInstId, sngisdn_info->spInstId); - ftdm_mutex_lock(g_sngisdn_data.ccs[sngisdn_info->glare.suId].mutex); - g_sngisdn_data.ccs[sngisdn_info->glare.suId].active_spInstIds[sngisdn_info->glare.spInstId]=NULL; + ftdm_mutex_lock(g_sngisdn_data.ccs[sngisdn_info->glare.suId].mutex); + if (sngisdn_info->glare.spInstId != sngisdn_info->spInstId) { + g_sngisdn_data.ccs[sngisdn_info->glare.suId].active_spInstIds[sngisdn_info->glare.spInstId]=NULL; + } g_sngisdn_data.ccs[sngisdn_info->glare.suId].active_suInstIds[sngisdn_info->glare.suInstId]=NULL; ftdm_mutex_unlock(g_sngisdn_data.ccs[sngisdn_info->glare.suId].mutex); @@ -427,6 +429,24 @@ void sngisdn_delayed_disconnect(void* p_sngisdn_info) return; } +void sngisdn_facility_timeout(void* p_sngisdn_info) +{ + sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info; + ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; + + ftdm_mutex_lock(ftdmchan->mutex); + if (ftdmchan->state == FTDM_CHANNEL_STATE_GET_CALLERID) { + ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Facility timeout reached proceeding with call (suId:%d suInstId:%u spInstId:%u)\n", + signal_data->cc_id, sngisdn_info->spInstId, sngisdn_info->suInstId); + + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING); + } + + ftdm_mutex_unlock(ftdmchan->mutex); + return; +} + ftdm_status_t sngisdn_check_free_ids(void) { unsigned i; From 42c307253bc88621254fc9bd92f6364ca088c5da Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Wed, 8 Sep 2010 20:34:57 -0400 Subject: [PATCH 03/25] freetdm: ss7 - beta support for ANSI, added support for tx of cgb, cgu --- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c | 336 +++++++++++++++--- .../ftmod_sangoma_ss7_handle.c | 8 +- .../ftmod_sangoma_ss7_main.h | 2 + .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c | 107 ++++++ .../ftmod_sangoma_ss7_support.c | 18 + .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c | 2 +- 6 files changed, 423 insertions(+), 50 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c index edb15604e5..c0ce84b2ed 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c @@ -48,8 +48,6 @@ static ftdm_status_t handle_print_usuage(ftdm_stream_handle_t *stream); static ftdm_status_t handle_set_function_trace(ftdm_stream_handle_t *stream, int on, int level); static ftdm_status_t handle_set_message_trace(ftdm_stream_handle_t *stream, int on, int level); -static ftdm_status_t handle_set_blocks(ftdm_stream_handle_t *stream, int span, int chan, int verbose); -static ftdm_status_t handle_set_unblks(ftdm_stream_handle_t *stream, int span, int chan, int verbose); static ftdm_status_t handle_set_inhibit(ftdm_stream_handle_t *stream, char *name); static ftdm_status_t handle_set_uninhibit(ftdm_stream_handle_t *stream, char *name); @@ -63,6 +61,13 @@ static ftdm_status_t handle_show_status(ftdm_stream_handle_t *stream, int span, static ftdm_status_t handle_tx_rsc(ftdm_stream_handle_t *stream, int span, int chan, int verbose); static ftdm_status_t handle_tx_grs(ftdm_stream_handle_t *stream, int span, int chan, int range, int verbose); +static ftdm_status_t handle_tx_blo(ftdm_stream_handle_t *stream, int span, int chan, int verbose); +static ftdm_status_t handle_tx_ubl(ftdm_stream_handle_t *stream, int span, int chan, int verbose); + +static ftdm_status_t handle_tx_cgb(ftdm_stream_handle_t *stream, int span, int chan, int range, int verbose); +static ftdm_status_t handle_tx_cgu(ftdm_stream_handle_t *stream, int span, int chan, int range, int verbose); + + static ftdm_status_t handle_status_link(ftdm_stream_handle_t *stream, char *name); static ftdm_status_t handle_status_linkset(ftdm_stream_handle_t *stream, char *name); @@ -282,20 +287,12 @@ ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const cha /**********************************************************************/ } /**************************************************************************/ - } else if (!strcasecmp(argv[c], "block")) { + } else if (!strcasecmp(argv[c], "inhibit")) { /**************************************************************************/ if (check_arg_count(argc, 2)) goto handle_cli_error_argc; c++; - if (!strcasecmp(argv[c], "span")) { - /**********************************************************************/ - if (check_arg_count(argc, 5)) goto handle_cli_error_argc; - - if (extract_span_chan(argv, c, &span, &chan)) goto handle_cli_error_span_chan; - - handle_set_blocks(stream, span, chan, verbose); - /**********************************************************************/ - } else if (!strcasecmp(argv[c], "link")) { + if (!strcasecmp(argv[c], "link")) { /**********************************************************************/ if (check_arg_count(argc, 3)) goto handle_cli_error_argc; c++; @@ -309,7 +306,26 @@ ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const cha /**********************************************************************/ } /**************************************************************************/ - } else if (!strcasecmp(argv[c], "unblock")) { + } else if (!strcasecmp(argv[c], "uninhibit")) { + /**************************************************************************/ + if (check_arg_count(argc, 2)) goto handle_cli_error_argc; + c++; + + if (!strcasecmp(argv[c], "link")) { + /**********************************************************************/ + if (check_arg_count(argc, 3)) goto handle_cli_error_argc; + c++; + + handle_set_uninhibit(stream, argv[c]); + /**********************************************************************/ + } else { + /**********************************************************************/ + stream->write_function(stream, "Unknown \"unblock\" command\n"); + goto handle_cli_error; + /**********************************************************************/ + } + /**************************************************************************/ + } else if (!strcasecmp(argv[c], "blo")) { /**************************************************************************/ if (check_arg_count(argc, 2)) goto handle_cli_error_argc; c++; @@ -320,18 +336,101 @@ ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const cha if (extract_span_chan(argv, c, &span, &chan)) goto handle_cli_error_span_chan; - handle_set_unblks(stream, span, chan, verbose); - /**********************************************************************/ - } else if (!strcasecmp(argv[c], "link")) { - /**********************************************************************/ - if (check_arg_count(argc, 3)) goto handle_cli_error_argc; - c++; - - handle_set_uninhibit(stream, argv[c]); + handle_tx_blo(stream, span, chan, verbose); /**********************************************************************/ } else { /**********************************************************************/ - stream->write_function(stream, "Unknown \"unblock\" command\n"); + stream->write_function(stream, "Unknown \"block\" command\n"); + goto handle_cli_error; + /**********************************************************************/ + } + /**************************************************************************/ + } else if (!strcasecmp(argv[c], "ubl")) { + /**************************************************************************/ + if (check_arg_count(argc, 2)) goto handle_cli_error_argc; + c++; + + if (!strcasecmp(argv[c], "span")) { + /**********************************************************************/ + if (check_arg_count(argc, 5)) goto handle_cli_error_argc; + + if (extract_span_chan(argv, c, &span, &chan)) goto handle_cli_error_span_chan; + + handle_tx_ubl(stream, span, chan, verbose); + /**********************************************************************/ + } else { + /**********************************************************************/ + stream->write_function(stream, "Unknown \"ubl\" command\n"); + goto handle_cli_error; + /**********************************************************************/ + } + /**************************************************************************/ + } else if (!strcasecmp(argv[c], "cgb")) { + /**************************************************************************/ + if (check_arg_count(argc, 2)) goto handle_cli_error_argc; + c++; + + if (!strcasecmp(argv[c], "span")) { + /**********************************************************************/ + if (check_arg_count(argc, 5)) goto handle_cli_error_argc; + + if (extract_span_chan(argv, c, &span, &chan)) goto handle_cli_error_span_chan; + c = c + 4; + + if (check_arg_count(argc, 7)) goto handle_cli_error_argc; + + if (!strcasecmp(argv[c], "range")) { + /******************************************************************/ + c++; + range = atoi(argv[c]); + /******************************************************************/ + } else { + /******************************************************************/ + stream->write_function(stream, "Unknown \"cgb range\" command\n"); + goto handle_cli_error; + /******************************************************************/ + } + + handle_tx_cgb(stream, span, chan, range, verbose); + /**********************************************************************/ + } else { + /**********************************************************************/ + stream->write_function(stream, "Unknown \"cgb\" command\n"); + goto handle_cli_error; + /**********************************************************************/ + } + /**************************************************************************/ + } else if (!strcasecmp(argv[c], "cgu")) { + /**************************************************************************/ + if (check_arg_count(argc, 2)) goto handle_cli_error_argc; + c++; + + if (!strcasecmp(argv[c], "span")) { + /**********************************************************************/ + if (check_arg_count(argc, 5)) goto handle_cli_error_argc; + + if (extract_span_chan(argv, c, &span, &chan)) goto handle_cli_error_span_chan; + c = c + 4; + + if (check_arg_count(argc, 7)) goto handle_cli_error_argc; + + if (!strcasecmp(argv[c], "range")) { + /******************************************************************/ + c++; + range = atoi(argv[c]); + /******************************************************************/ + } else { + /******************************************************************/ + stream->write_function(stream, "Unknown \"cgu range\" command\n"); + goto handle_cli_error; + /******************************************************************/ + } + + handle_tx_cgu(stream, span, chan, range, verbose); + /**********************************************************************/ + } else { + /**********************************************************************/ + stream->write_function(stream, "Unknown \"cgu\" command\n"); goto handle_cli_error; /**********************************************************************/ } @@ -433,10 +532,15 @@ static ftdm_status_t handle_print_usuage(ftdm_stream_handle_t *stream) stream->write_function(stream, "ftdm ss7 show inreset span X chan Y\n"); stream->write_function(stream, "\n"); stream->write_function(stream, "Ftmod_sangoma_ss7 circuit control:\n"); - stream->write_function(stream, "ftdm ss7 block span X chan Y\n"); - stream->write_function(stream, "ftdm ss7 unblk span X chan Y\n"); + stream->write_function(stream, "ftdm ss7 blo span X chan Y\n"); + stream->write_function(stream, "ftdm ss7 ubl span X chan Y\n"); stream->write_function(stream, "ftdm ss7 rsc span X chan Y\n"); stream->write_function(stream, "ftdm ss7 grs span X chan Y range Z\n"); + stream->write_function(stream, "\n"); + stream->write_function(stream, "Ftmod_sangoma_ss7 link control:\n"); + stream->write_function(stream, "ftdm ss7 inhibit link X\n"); + stream->write_function(stream, "ftdm ss7 uninhibit link X\n"); + stream->write_function(stream, "\n"); return FTDM_SUCCESS; @@ -899,7 +1003,7 @@ static ftdm_status_t handle_show_status(ftdm_stream_handle_t *stream, int span, return FTDM_SUCCESS; } /******************************************************************************/ -static ftdm_status_t handle_set_blocks(ftdm_stream_handle_t *stream, int span, int chan, int verbose) +static ftdm_status_t handle_tx_blo(ftdm_stream_handle_t *stream, int span, int chan, int verbose) { int x; sngss7_chan_data_t *ss7_info; @@ -960,7 +1064,7 @@ static ftdm_status_t handle_set_blocks(ftdm_stream_handle_t *stream, int span, i } /******************************************************************************/ -static ftdm_status_t handle_set_unblks(ftdm_stream_handle_t *stream, int span, int chan, int verbose) +static ftdm_status_t handle_tx_ubl(ftdm_stream_handle_t *stream, int span, int chan, int verbose) { int x; sngss7_chan_data_t *ss7_info; @@ -1154,17 +1258,17 @@ static ftdm_status_t handle_set_uninhibit(ftdm_stream_handle_t *stream, char *na /******************************************************************************/ static ftdm_status_t handle_tx_rsc(ftdm_stream_handle_t *stream, int span, int chan, int verbose) { - int x; - sngss7_chan_data_t *ss7_info; - ftdm_channel_t *ftdmchan; - int lspan; - int lchan; + int x; + sngss7_chan_data_t *sngss7_info; + ftdm_channel_t *ftdmchan; + int lspan; + int lchan; x=1; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { - ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; - ftdmchan = ss7_info->ftdmchan; + sngss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; + ftdmchan = sngss7_info->ftdmchan; /* if span == 0 then all spans should be printed */ if (span == 0) { @@ -1181,27 +1285,31 @@ static ftdm_status_t handle_tx_rsc(ftdm_stream_handle_t *stream, int span, int c } if ((ftdmchan->physical_span_id == lspan) && (ftdmchan->physical_chan_id == lchan)) { - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ 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", ss7_info->circuit->cic); - SS7_ASSERT; - } else { - /* throw the ckt block flag */ - sngss7_set_flag(ss7_info, FLAG_RESET_TX); + /* throw the reset flag */ + sngss7_set_flag(sngss7_info, FLAG_RESET_TX); - /* set the channel to suspended state */ + switch (ftdmchan->state) { + /**************************************************************************/ + case FTDM_CHANNEL_STATE_RESTART: + /* go to idle so that we can redo the restart state*/ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE); + break; + /**************************************************************************/ + default: + /* set the state of the channel to restart...the rest is done by the chan monitor */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); + break; + /**************************************************************************/ } - + /* unlock the channel again before we exit */ ftdm_mutex_unlock(ftdmchan->mutex); - } /* if ( span and chan) */ - } /* if ( cic != 0) */ + } /* if ( cic == voice) */ /* go the next circuit */ x++; @@ -1270,6 +1378,144 @@ static ftdm_status_t handle_tx_grs(ftdm_stream_handle_t *stream, int span, int c return FTDM_SUCCESS; } +/******************************************************************************/ +static ftdm_status_t handle_tx_cgb(ftdm_stream_handle_t *stream, int span, int chan, int range, int verbose) +{ + int x; + sngss7_chan_data_t *sngss7_info; + ftdm_channel_t *ftdmchan; + ftdm_channel_t *main_chan = NULL; + sngss7_span_data_t *sngss7_span; + int byte = 0; + int bit = 0; + + if (range > 31) { + stream->write_function(stream, "Invalid range value %d", range); + return FTDM_SUCCESS; + } + + x=1; + while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { + + /* extract the channel and span info for this circuit */ + sngss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; + ftdmchan = sngss7_info->ftdmchan; + sngss7_span = ftdmchan->span->mod_data; + + /* check if this circuit is part of the block */ + if ((ftdmchan->physical_span_id == span) && + ((ftdmchan->physical_chan_id >= chan) && (ftdmchan->physical_chan_id < (chan+range)))) { + + /* now that we have the right channel...put a lock on it so no-one else can use it */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* throw the grp maint. block flag */ + sngss7_set_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX); + + /* if this is the first channel in the range */ + if (ftdmchan->physical_chan_id == chan) { + /* attach the cgb information */ + main_chan = ftdmchan; + sngss7_span->tx_cgb.circuit = sngss7_info->circuit->id; + sngss7_span->tx_cgb.range = range-1; + sngss7_span->tx_cgb.type = 0; /* maintenace block */ + } /* if (ftdmchan->physical_chan_id == chan) */ + + /* update the status field */ + sngss7_span->tx_cgb.status[byte] = (sngss7_span->tx_cgb.status[byte] | (1 << bit)); + + /* update the bit and byte counter*/ + bit ++; + if (bit == 8) { + byte++; + bit = 0; + } + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + } /* if ( span and chan) */ + } /* if ( cic == voice) */ + /* go the next circuit */ + x++; + } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */ + + /* send the circuit group block */ + ft_to_sngss7_cgb(main_chan); + + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static ftdm_status_t handle_tx_cgu(ftdm_stream_handle_t *stream, int span, int chan, int range, int verbose) +{ + int x; + sngss7_chan_data_t *sngss7_info; + ftdm_channel_t *ftdmchan; + ftdm_channel_t *main_chan = NULL; + sngss7_span_data_t *sngss7_span; + int byte = 0; + int bit = 0; + + if (range > 31) { + stream->write_function(stream, "Invalid range value %d", range); + return FTDM_SUCCESS; + } + + x=1; + while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { + + /* extract the channel and span info for this circuit */ + sngss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; + ftdmchan = sngss7_info->ftdmchan; + sngss7_span = ftdmchan->span->mod_data; + + /* check if this circuit is part of the block */ + if ((ftdmchan->physical_span_id == span) && + ((ftdmchan->physical_chan_id >= chan) && (ftdmchan->physical_chan_id < (chan+range)))) { + + /* now that we have the right channel...put a lock on it so no-one else can use it */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* throw the grp maint. block flag */ + sngss7_clear_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX); + + /* if this is the first channel in the range */ + if (ftdmchan->physical_chan_id == chan) { + /* attach the cgb information */ + main_chan = ftdmchan; + sngss7_span->tx_cgu.circuit = sngss7_info->circuit->id; + sngss7_span->tx_cgu.range = range-1; + sngss7_span->tx_cgu.type = 0; /* maintenace block */ + } /* if (ftdmchan->physical_chan_id == chan) */ + + /* update the status field */ + sngss7_span->tx_cgu.status[byte] = (sngss7_span->tx_cgu.status[byte] | (1 << bit)); + + /* update the bit and byte counter*/ + bit ++; + if (bit == 8) { + byte++; + bit = 0; + } + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + } /* if ( span and chan) */ + } /* if ( cic == voice) */ + /* go the next circuit */ + x++; + } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */ + + /* send the circuit group block */ + ft_to_sngss7_cgu(main_chan); + + + return FTDM_SUCCESS; +} + /******************************************************************************/ static ftdm_status_t extract_span_chan(char *argv[10], int pos, int *span, int *chan) { 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 0c3dcffec0..0286563f29 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 @@ -915,12 +915,12 @@ 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"); - handle_cgb_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + /*handle_cgb_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);*/ break; /**************************************************************************/ case SIT_STA_CGURSP: /* mntc. oriented CGU response */ SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx mntc CGU\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + /*SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));*/ break; /**************************************************************************/ case SIT_STA_GRSREQ: /* circuit group reset request */ @@ -1020,7 +1020,7 @@ ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ /**************************************************************************/ case SIT_STA_LMCQMINFOREQ: /* when LM requests ckt grp query */ SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LM CQM\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); +// SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_CIRLOCGRS: /* group reset initiated locally by the software */ @@ -2073,7 +2073,7 @@ ftdm_status_t handle_cgb_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ SS7_ASSERT; }; -#if 1 +#if 0 SS7_ERROR("KONRAD -> circuit=%d, byte=%d, bit=%d, status[byte]=%d, math=%d\n", x, byte, 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 c9dbfb3ac8..bab1c8be6a 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 @@ -471,6 +471,8 @@ 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 ft_to_sngss7_cgb(ftdm_channel_t * ftdmchan); +void ft_to_sngss7_cgu(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); 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 079f5e3e22..46bd39f7fb 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 @@ -61,6 +61,9 @@ 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_cgb(ftdm_channel_t * ftdmchan); +void ft_to_sngss7_cgu(ftdm_channel_t * ftdmchan); + void ft_to_sngss7_cgba(ftdm_channel_t * ftdmchan); void ft_to_sngss7_cgua(ftdm_channel_t * ftdmchan); /******************************************************************************/ @@ -121,6 +124,10 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) (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)) { + /* include only if we're running ANSI */ + iam.fwdCallInd.transCallNInd.pres = PRSNT_NODEF; + iam.fwdCallInd.transCallNInd.val = 0x0; + iam.usrServInfoA.eh.pres = PRSNT_NODEF; iam.usrServInfoA.infoTranCap.pres = PRSNT_NODEF; @@ -633,6 +640,106 @@ void ft_to_sngss7_cgua(ftdm_channel_t * ftdmchan) SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } + +/******************************************************************************/ +void ft_to_sngss7_cgb(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; + SiStaEvnt cgb; + int x = 0; + + + memset (&cgb, 0x0, sizeof(cgb)); + + /* fill in the circuit group supervisory message */ + cgb.cgsmti.eh.pres = PRSNT_NODEF; + cgb.cgsmti.typeInd.pres = PRSNT_NODEF; + cgb.cgsmti.typeInd.val = sngss7_span->tx_cgb.type; + + /* fill in the range */ + cgb.rangStat.eh.pres = PRSNT_NODEF; + cgb.rangStat.range.pres = PRSNT_NODEF; + cgb.rangStat.range.val = sngss7_span->tx_cgb.range; + + /* fill in the status */ + cgb.rangStat.status.pres = PRSNT_NODEF; + cgb.rangStat.status.len = ((sngss7_span->tx_cgb.range + 1) >> 3) + (((sngss7_span->tx_cgb.range + 1) & 0x07) ? 1 : 0); + for(x = 0; x < cgb.rangStat.status.len; x++){ + cgb.rangStat.status.val[x] = sngss7_span->tx_cgb.status[x]; + } + + sng_cc_sta_request (1, + 0, + 0, + sngss7_span->tx_cgb.circuit, + 0, + SIT_STA_CGBREQ, + &cgb); + + SS7_INFO_CHAN(ftdmchan, "Tx CGB (%d:%d)\n", + sngss7_info->circuit->cic, + (sngss7_info->circuit->cic + sngss7_span->tx_cgb.range)); + + /* clean out the saved data */ + memset(&sngss7_span->tx_cgb, 0x0, sizeof(sngss7_group_data_t)); + + SS7_FUNC_TRACE_EXIT (__FUNCTION__); + return; +} + +/******************************************************************************/ +void ft_to_sngss7_cgu(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; + SiStaEvnt cgu; + int x = 0; + + + memset (&cgu, 0x0, sizeof(cgu)); + + /* fill in the circuit group supervisory message */ + cgu.cgsmti.eh.pres = PRSNT_NODEF; + cgu.cgsmti.typeInd.pres = PRSNT_NODEF; + cgu.cgsmti.typeInd.val = sngss7_span->tx_cgu.type; + + /* fill in the range */ + cgu.rangStat.eh.pres = PRSNT_NODEF; + cgu.rangStat.range.pres = PRSNT_NODEF; + cgu.rangStat.range.val = sngss7_span->tx_cgu.range; + + /* fill in the status */ + cgu.rangStat.status.pres = PRSNT_NODEF; + cgu.rangStat.status.len = ((sngss7_span->tx_cgu.range + 1) >> 3) + (((sngss7_span->tx_cgu.range + 1) & 0x07) ? 1 : 0); + for(x = 0; x < cgu.rangStat.status.len; x++){ + cgu.rangStat.status.val[x] = sngss7_span->tx_cgu.status[x]; + } + + sng_cc_sta_request (1, + 0, + 0, + sngss7_span->tx_cgu.circuit, + 0, + SIT_STA_CGUREQ, + &cgu); + + SS7_INFO_CHAN(ftdmchan, "Tx CGU (%d:%d)\n", + sngss7_info->circuit->cic, + (sngss7_info->circuit->cic + sngss7_span->tx_cgu.range)); + + /* clean out the saved data */ + memset(&sngss7_span->tx_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 4ec57fe049..161a70d3ed 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 @@ -458,6 +458,9 @@ ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan) sngss7_chan_data_t *sngss7_info = NULL; sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmspan->mod_data; int i; + int byte = 0; + int bit = 0; + ftdm_log(FTDM_LOG_DEBUG, "Found Rx GRS on span %d...checking circuits\n", ftdmspan->span_id); @@ -505,6 +508,21 @@ ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan) /* move the channel to the down state */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); + /* update the status map if the ckt is in blocked state */ + if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) || + (sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) || + (sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX)) || + (sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) { + + sngss7_span->rx_grs.status[byte] = (sngss7_span->rx_grs.status[byte] | (1 << bit)); + } /* if blocked */ + + /* update the bit and byte counter*/ + bit ++; + if (bit == 8) { + byte++; + bit = 0; + } } /* for ( i = circuit; i < (circuit + range + 1); i++) */ GRS_UNLOCK_ALL: 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 4ebf3b95fd..f6d04ed2e8 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 @@ -1472,7 +1472,7 @@ static int ftmod_ss7_fill_in_isap(sng_isap_t *sng_isap) if (sng_isap->tex != 0) { g_ftdm_sngss7_data.cfg.isap[i].tex = sng_isap->tex; } else { - g_ftdm_sngss7_data.cfg.isap[i].tex = 10; + g_ftdm_sngss7_data.cfg.isap[i].tex = 1000; } if (sng_isap->tcrm != 0) { g_ftdm_sngss7_data.cfg.isap[i].tcrm = sng_isap->tcrm; From e7fecd0ff9bf86fe0cbf8bfd7878cf40337d3be5 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Thu, 9 Sep 2010 17:22:10 -0400 Subject: [PATCH 04/25] freetdm: fix config to allow both sangoma pri and bri spans to be configured --- libs/freetdm/mod_freetdm/mod_freetdm.c | 229 +++++++++++++------------ 1 file changed, 120 insertions(+), 109 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index fb85b3515c..b911155334 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -2371,6 +2371,121 @@ static int add_profile_parameters(switch_xml_t cfg, const char *profname, ftdm_c return paramindex; } +static void parse_bri_pri_spans(switch_xml_t cfg, switch_xml_t spans) +{ + switch_xml_t myspan, param; + + for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) { + ftdm_status_t zstatus = FTDM_FAIL; + const char *context = "default"; + const char *dialplan = "XML"; + ftdm_conf_parameter_t spanparameters[30]; + char *id = (char *) switch_xml_attr(myspan, "id"); + char *name = (char *) switch_xml_attr(myspan, "name"); + char *configname = (char *) switch_xml_attr(myspan, "cfgprofile"); + ftdm_span_t *span = NULL; + uint32_t span_id = 0; + unsigned paramindex = 0; + + if (!name && !id) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sangoma isdn span missing required attribute 'id' or 'name', skipping ...\n"); + continue; + } + + if (name) { + zstatus = ftdm_span_find_by_name(name, &span); + } else { + if (switch_is_number(id)) { + span_id = atoi(id); + zstatus = ftdm_span_find(span_id, &span); + } + + if (zstatus != FTDM_SUCCESS) { + zstatus = ftdm_span_find_by_name(id, &span); + } + } + + if (zstatus != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_ERROR, "Error finding FreeTDM span id:%s name:%s\n", switch_str_nil(id), switch_str_nil(name)); + continue; + } + + if (!span_id) { + span_id = ftdm_span_get_id(span); + } + + memset(spanparameters, 0, sizeof(spanparameters)); + paramindex = 0; + + if (configname) { + paramindex = add_profile_parameters(cfg, configname, spanparameters, ftdm_array_len(spanparameters)); + if (paramindex) { + ftdm_log(FTDM_LOG_DEBUG, "Added %d parameters from profile %s for span %d\n", paramindex, configname, span_id); + } + } + + /* some defaults first */ + SPAN_CONFIG[span_id].limit_backend = "hash"; + SPAN_CONFIG[span_id].limit_reset_event = FTDM_LIMIT_RESET_ON_TIMEOUT; + + for (param = switch_xml_child(myspan, "param"); param; param = param->next) { + char *var = (char *) switch_xml_attr_soft(param, "name"); + char *val = (char *) switch_xml_attr_soft(param, "value"); + + if (ftdm_array_len(spanparameters) == paramindex) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Too many parameters for ss7 span, ignoring any parameter after %s\n", var); + break; + } + + if (!strcasecmp(var, "context")) { + context = val; + } else if (!strcasecmp(var, "dialplan")) { + dialplan = val; + } else if (!strcasecmp(var, "call_limit_backend")) { + SPAN_CONFIG[span_id].limit_backend = val; + ftdm_log(FTDM_LOG_DEBUG, "Using limit backend %s for span %d\n", SPAN_CONFIG[span_id].limit_backend, span_id); + } else if (!strcasecmp(var, "call_limit_rate")) { + int calls; + int seconds; + if (sscanf(val, "%d/%d", &calls, &seconds) != 2) { + ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter, format example: 3/1 for 3 calls per second\n", var); + } else { + if (calls < 1 || seconds < 1) { + ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter value, minimum call limit must be 1 per second\n", var); + } else { + SPAN_CONFIG[span_id].limit_calls = calls; + SPAN_CONFIG[span_id].limit_seconds = seconds; + } + } + } else if (!strcasecmp(var, "call_limit_reset_event")) { + if (!strcasecmp(val, "answer")) { + SPAN_CONFIG[span_id].limit_reset_event = FTDM_LIMIT_RESET_ON_ANSWER; + } else { + ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter value, only accepted event is 'answer'\n", var); + } + } else { + spanparameters[paramindex].var = var; + spanparameters[paramindex].val = val; + paramindex++; + } + } + + if (ftdm_configure_span_signaling(span, + "sangoma_isdn", + on_clear_channel_signal, + spanparameters) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_ERROR, "Error configuring Sangoma ISDN FreeTDM span %d\n", span_id); + continue; + } + SPAN_CONFIG[span_id].span = span; + switch_copy_string(SPAN_CONFIG[span_id].context, context, sizeof(SPAN_CONFIG[span_id].context)); + switch_copy_string(SPAN_CONFIG[span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span_id].dialplan)); + switch_copy_string(SPAN_CONFIG[span_id].type, "Sangoma (ISDN)", sizeof(SPAN_CONFIG[span_id].type)); + ftdm_log(FTDM_LOG_DEBUG, "Configured Sangoma ISDN FreeTDM span %d\n", span_id); + ftdm_span_start(span); + } +} + static switch_status_t load_config(void) { const char *cf = "freetdm.conf"; @@ -2410,116 +2525,12 @@ static switch_status_t load_config(void) } } - if ((spans = switch_xml_child(cfg, "sangoma_pri_spans")) || (spans = switch_xml_child(cfg, "sangoma_bri_spans"))) { - for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) { - ftdm_status_t zstatus = FTDM_FAIL; - const char *context = "default"; - const char *dialplan = "XML"; - ftdm_conf_parameter_t spanparameters[30]; - char *id = (char *) switch_xml_attr(myspan, "id"); - char *name = (char *) switch_xml_attr(myspan, "name"); - char *configname = (char *) switch_xml_attr(myspan, "cfgprofile"); - ftdm_span_t *span = NULL; - uint32_t span_id = 0; - unsigned paramindex = 0; + if ((spans = switch_xml_child(cfg, "sangoma_pri_spans"))) { + parse_bri_pri_spans(cfg, spans); + } - if (!name && !id) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sangoma isdn span missing required attribute 'id' or 'name', skipping ...\n"); - continue; - } - - if (name) { - zstatus = ftdm_span_find_by_name(name, &span); - } else { - if (switch_is_number(id)) { - span_id = atoi(id); - zstatus = ftdm_span_find(span_id, &span); - } - - if (zstatus != FTDM_SUCCESS) { - zstatus = ftdm_span_find_by_name(id, &span); - } - } - - if (zstatus != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Error finding FreeTDM span id:%s name:%s\n", switch_str_nil(id), switch_str_nil(name)); - continue; - } - - if (!span_id) { - span_id = ftdm_span_get_id(span); - } - - memset(spanparameters, 0, sizeof(spanparameters)); - paramindex = 0; - - if (configname) { - paramindex = add_profile_parameters(cfg, configname, spanparameters, ftdm_array_len(spanparameters)); - if (paramindex) { - ftdm_log(FTDM_LOG_DEBUG, "Added %d parameters from profile %s for span %d\n", paramindex, configname, span_id); - } - } - - /* some defaults first */ - SPAN_CONFIG[span_id].limit_backend = "hash"; - SPAN_CONFIG[span_id].limit_reset_event = FTDM_LIMIT_RESET_ON_TIMEOUT; - - for (param = switch_xml_child(myspan, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - - if (ftdm_array_len(spanparameters) == paramindex) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Too many parameters for ss7 span, ignoring any parameter after %s\n", var); - break; - } - - if (!strcasecmp(var, "context")) { - context = val; - } else if (!strcasecmp(var, "dialplan")) { - dialplan = val; - } else if (!strcasecmp(var, "call_limit_backend")) { - SPAN_CONFIG[span_id].limit_backend = val; - ftdm_log(FTDM_LOG_DEBUG, "Using limit backend %s for span %d\n", SPAN_CONFIG[span_id].limit_backend, span_id); - } else if (!strcasecmp(var, "call_limit_rate")) { - int calls; - int seconds; - if (sscanf(val, "%d/%d", &calls, &seconds) != 2) { - ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter, format example: 3/1 for 3 calls per second\n", var); - } else { - if (calls < 1 || seconds < 1) { - ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter value, minimum call limit must be 1 per second\n", var); - } else { - SPAN_CONFIG[span_id].limit_calls = calls; - SPAN_CONFIG[span_id].limit_seconds = seconds; - } - } - } else if (!strcasecmp(var, "call_limit_reset_event")) { - if (!strcasecmp(val, "answer")) { - SPAN_CONFIG[span_id].limit_reset_event = FTDM_LIMIT_RESET_ON_ANSWER; - } else { - ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter value, only accepted event is 'answer'\n", var); - } - } else { - spanparameters[paramindex].var = var; - spanparameters[paramindex].val = val; - paramindex++; - } - } - - if (ftdm_configure_span_signaling(span, - "sangoma_isdn", - on_clear_channel_signal, - spanparameters) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Error configuring Sangoma ISDN FreeTDM span %d\n", span_id); - continue; - } - SPAN_CONFIG[span_id].span = span; - switch_copy_string(SPAN_CONFIG[span_id].context, context, sizeof(SPAN_CONFIG[span_id].context)); - switch_copy_string(SPAN_CONFIG[span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span_id].dialplan)); - switch_copy_string(SPAN_CONFIG[span_id].type, "Sangoma (ISDN)", sizeof(SPAN_CONFIG[span_id].type)); - ftdm_log(FTDM_LOG_DEBUG, "Configured Sangoma ISDN FreeTDM span %d\n", span_id); - ftdm_span_start(span); - } + if ((spans = switch_xml_child(cfg, "sangoma_bri_spans"))) { + parse_bri_pri_spans(cfg, spans); } switch_core_hash_init(&globals.ss7_configs, module_pool); From c4324d5af4a5ca8fafe34879dbf7af04325f1143 Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Thu, 9 Sep 2010 17:31:27 -0400 Subject: [PATCH 05/25] freetdm: ss7 - bug fixes in configuration --- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c | 12 ++- .../ftmod_sangoma_ss7_main.h | 2 + .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c | 88 ++++++++----------- 3 files changed, 46 insertions(+), 56 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 44764295d4..93bd3154b3 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 @@ -213,7 +213,7 @@ int ft_to_sngss7_cfg_all(void) SS7_CRITICAL("MTP3 ROUTE %d configuration FAILED!\n", x); SS7_ASSERT } else { - SS7_INFO("MTP3 ROUTE %d configuration DONE!\n"); + SS7_INFO("MTP3 ROUTE %d configuration DONE!\n",x); } /* set the CONFIGURED flag */ @@ -229,7 +229,7 @@ int ft_to_sngss7_cfg_all(void) SS7_CRITICAL("MTP3 ROUTE 0 configuration FAILED!\n"); SS7_ASSERT } else { - SS7_INFO("MTP3 ROUTE %d configuration DONE!\n"); + SS7_INFO("MTP3 ROUTE 0 configuration DONE!\n"); } /* set the CONFIGURED flag */ @@ -925,7 +925,6 @@ int ftmod_ss7_mtp3_linkset_config(int id) { Pst pst; SnMngmt cfg; - U16 c; sng_link_set_t *k = &g_ftdm_sngss7_data.cfg.mtpLinkSet[id]; /* initalize the post structure */ @@ -953,10 +952,9 @@ int ftmod_ss7_mtp3_linkset_config(int id) cfg.t.cfg.s.snLnkSet.adjDpc = k->apc; /* adjacent DPC */ cfg.t.cfg.s.snLnkSet.nmbActLnkReqd = k->minActive; /* minimum number of active links */ cfg.t.cfg.s.snLnkSet.nmbCmbLnkSet = 1; /* number of combined link sets */ - for (c = 0; c < LSN_MAXCMBLNK; c++) { - cfg.t.cfg.s.snLnkSet.cmbLnkSet[c].cmbLnkSetId = c+1; - cfg.t.cfg.s.snLnkSet.cmbLnkSet[c].lnkSetPrior = 0; - } + cfg.t.cfg.s.snLnkSet.cmbLnkSet[0].cmbLnkSetId = k->cmbLinkSetId; + cfg.t.cfg.s.snLnkSet.cmbLnkSet[0].lnkSetPrior = 0; + return(sng_cfg_mtp3(&pst, &cfg)); } 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 bab1c8be6a..f76a56099f 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 @@ -162,6 +162,7 @@ typedef struct sng_link_set { uint32_t flags; uint32_t apc; uint32_t linkType; + uint32_t cmbLinkSetId; uint32_t minActive; uint32_t numLinks; uint32_t links[16]; @@ -176,6 +177,7 @@ typedef struct sng_route { uint32_t linkType; uint32_t switchType; uint32_t ssf; + uint32_t nwId; uint32_t isSTP; uint32_t t6; uint32_t t8; 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 f6d04ed2e8..66907e78ba 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 @@ -343,11 +343,11 @@ static int ftmod_ss7_parse_mtp_linkset(ftdm_conf_node_t *mtp_linkset) /**********************************************************************/ } else if (!strcasecmp(parm->var, "apc")) { mtpLinkSet.apc = atoi(parm->val); - SS7_DEBUG("\tFoundmtpLinkSet->apc = %d\n", mtpLinkSet.apc); + SS7_DEBUG("\tFound mtpLinkSet->apc = %d\n", mtpLinkSet.apc); /**********************************************************************/ } else if (!strcasecmp(parm->var, "minActive")) { mtpLinkSet.minActive = atoi(parm->val); - SS7_DEBUG("\tFoundmtpLinkSet->minActive = %d\n", mtpLinkSet.minActive); + SS7_DEBUG("\tFound mtpLinkSet->minActive = %d\n", mtpLinkSet.minActive); /**********************************************************************/ } else { SS7_ERROR("\tFound an invalid parameter \"%s\"!\n", parm->val); @@ -497,27 +497,27 @@ static int ftmod_ss7_parse_mtp_link(ftdm_conf_node_t *mtp_link, sng_mtp_link_t * if (!strcasecmp(parm->val, "itu92")) { mtpLink->mtp2.linkType = LSD_SW_ITU92; mtpLink->mtp3.linkType = LSN_SW_ITU; - SS7_DEBUG("\tFoundmtpLink->linkType = \"ITU92\"\n"); + SS7_DEBUG("\tFound mtpLink->linkType = \"ITU92\"\n"); } else if (!strcasecmp(parm->val, "itu88")) { mtpLink->mtp2.linkType = LSD_SW_ITU88; mtpLink->mtp3.linkType = LSN_SW_ITU; - SS7_DEBUG("\tFoundmtpLink->linkType = \"ITU88\"\n"); + SS7_DEBUG("\tFound mtpLink->linkType = \"ITU88\"\n"); } else if (!strcasecmp(parm->val, "ansi96")) { mtpLink->mtp2.linkType = LSD_SW_ANSI92; mtpLink->mtp3.linkType = LSN_SW_ANS96; - SS7_DEBUG("\tFoundmtpLink->linkType = \"ANSI96\"\n"); + SS7_DEBUG("\tFound mtpLink->linkType = \"ANSI96\"\n"); } else if (!strcasecmp(parm->val, "ansi92")) { mtpLink->mtp2.linkType = LSD_SW_ANSI92; mtpLink->mtp3.linkType = LSN_SW_ANS; - SS7_DEBUG("\tFoundmtpLink->linkType = \"ANSI92\"\n"); + SS7_DEBUG("\tFound mtpLink->linkType = \"ANSI92\"\n"); } else if (!strcasecmp(parm->val, "ansi88")) { mtpLink->mtp2.linkType = LSD_SW_ANSI88; mtpLink->mtp3.linkType = LSN_SW_ANS; - SS7_DEBUG("\tFoundmtpLink->linkType = \"ANSI88\"\n"); + SS7_DEBUG("\tFound mtpLink->linkType = \"ANSI88\"\n"); } else if (!strcasecmp(parm->val, "etsi")) { mtpLink->mtp2.linkType = LSD_SW_ITU92; mtpLink->mtp3.linkType = LSN_SW_ITU; - SS7_DEBUG("\tFoundmtpLink->linkType = \"ETSI\"\n"); + SS7_DEBUG("\tFound mtpLink->linkType = \"ETSI\"\n"); } else { SS7_ERROR("\tFound an invalid linktype of \"%s\"!\n", parm->val); return FTDM_FAIL; @@ -526,40 +526,40 @@ static int ftmod_ss7_parse_mtp_link(ftdm_conf_node_t *mtp_link, sng_mtp_link_t * } else if (!strcasecmp(parm->var, "switchType")) { if (!strcasecmp(parm->val, "itu97")) { mtpLink->mtp3.switchType = LSI_SW_ITU97; - SS7_DEBUG("\tFoundmtpLink->switchType = \"ITU97\"\n"); + SS7_DEBUG("\tFound mtpLink->switchType = \"ITU97\"\n"); } else if (!strcasecmp(parm->val, "itu88")) { mtpLink->mtp3.switchType = LSI_SW_ITU; - SS7_DEBUG("\tFoundmtpLink->switchType = \"ITU88\"\n"); + SS7_DEBUG("\tFound mtpLink->switchType = \"ITU88\"\n"); } else if (!strcasecmp(parm->val, "itu92")) { mtpLink->mtp3.switchType = LSI_SW_ITU; - SS7_DEBUG("\tFoundmtpLink->switchType = \"ITU92\"\n"); + SS7_DEBUG("\tFound mtpLink->switchType = \"ITU92\"\n"); } else if (!strcasecmp(parm->val, "itu00")) { mtpLink->mtp3.switchType = LSI_SW_ITU2000; - SS7_DEBUG("\tFoundmtpLink->switchType = \"ITU00\"\n"); + SS7_DEBUG("\tFound mtpLink->switchType = \"ITU00\"\n"); } else if (!strcasecmp(parm->val, "ETSIV2")) { mtpLink->mtp3.switchType = LSI_SW_ETSI; - SS7_DEBUG("\tFoundmtpLink->switchType = \"ETSIV2\"\n"); + SS7_DEBUG("\tFound mtpLink->switchType = \"ETSIV2\"\n"); } else if (!strcasecmp(parm->val, "ETSIV3")) { mtpLink->mtp3.switchType = LSI_SW_ETSIV3; - SS7_DEBUG("\tFoundmtpLink->switchType = \"ETSIV3\"\n"); + SS7_DEBUG("\tFound mtpLink->switchType = \"ETSIV3\"\n"); } else if (!strcasecmp(parm->val, "UK")) { mtpLink->mtp3.switchType = LSI_SW_UK; - SS7_DEBUG("\tFoundmtpLink->switchType = \"UK\"\n"); + SS7_DEBUG("\tFound mtpLink->switchType = \"UK\"\n"); } else if (!strcasecmp(parm->val, "RUSSIA")) { mtpLink->mtp3.switchType = LSI_SW_RUSSIA; - SS7_DEBUG("\tFoundmtpLink->switchType = \"RUSSIA\"\n"); + SS7_DEBUG("\tFound mtpLink->switchType = \"RUSSIA\"\n"); } else if (!strcasecmp(parm->val, "INDIA")) { mtpLink->mtp3.switchType = LSI_SW_INDIA; - SS7_DEBUG("\tFoundmtpLink->switchType = \"INDIA\"\n"); + SS7_DEBUG("\tFound mtpLink->switchType = \"INDIA\"\n"); } else if (!strcasecmp(parm->val, "ansi88")) { mtpLink->mtp3.switchType = LSI_SW_ANS88; - SS7_DEBUG("\tFoundmtpLink->switchType = \"ANSI88\"\n"); + SS7_DEBUG("\tFound mtpLink->switchType = \"ANSI88\"\n"); } else if (!strcasecmp(parm->val, "ansi92")) { mtpLink->mtp3.switchType = LSI_SW_ANS92; - SS7_DEBUG("\tFoundmtpLink->switchType = \"ANSI92\"\n"); + SS7_DEBUG("\tFound mtpLink->switchType = \"ANSI92\"\n"); } else if (!strcasecmp(parm->val, "ansi95")) { mtpLink->mtp3.switchType = LSI_SW_ANS95; - SS7_DEBUG("\tFoundmtpLink->switchType = \"ANSI95\"\n"); + SS7_DEBUG("\tFound mtpLink->switchType = \"ANSI95\"\n"); } else { SS7_ERROR("\tFound an invalid linktype of \"%s\"!\n", parm->val); return FTDM_FAIL; @@ -577,7 +577,7 @@ static int ftmod_ss7_parse_mtp_link(ftdm_conf_node_t *mtp_link, sng_mtp_link_t * /**********************************************************************/ } else if (!strcasecmp(parm->var, "slc")) { mtpLink->mtp3.slc = atoi(parm->val); - SS7_DEBUG("\tFoundmtpLink->slc = \"%d\"\n",mtpLink->mtp3.slc); + SS7_DEBUG("\tFound mtpLink->slc = \"%d\"\n",mtpLink->mtp3.slc); /**********************************************************************/ } else { SS7_ERROR("\tFound an invalid parameter \"%s\"!\n", parm->val); @@ -665,7 +665,7 @@ static int ftmod_ss7_parse_mtp_route(ftdm_conf_node_t *mtp_route) mtpRoute.linkType = g_ftdm_sngss7_data.cfg.mtpLink[id].mtp3.linkType; mtpRoute.switchType = g_ftdm_sngss7_data.cfg.mtpLink[id].mtp3.switchType; mtpRoute.ssf = g_ftdm_sngss7_data.cfg.mtpLink[id].mtp3.ssf; - mtpRoute.cmbLinkSetId = g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id; + mtpRoute.cmbLinkSetId = g_ftdm_sngss7_data.cfg.mtpLinkSet[x].cmbLinkSetId; break; } x++; @@ -781,36 +781,25 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface) /* check if the name matches */ if (!strcasecmp((char *)g_ftdm_sngss7_data.cfg.mtpRoute[x].name, parm->val)) { - /* now, harvest the required information from the global structure */ sng_isup.mtpRouteId = g_ftdm_sngss7_data.cfg.mtpRoute[x].id; sng_isup.dpc = g_ftdm_sngss7_data.cfg.mtpRoute[x].dpc; sng_isup.switchType = g_ftdm_sngss7_data.cfg.mtpRoute[x].switchType; sng_isap.switchType = g_ftdm_sngss7_data.cfg.mtpRoute[x].switchType; - /* find the nwID from the nsap */ - int y = 1; - while (g_ftdm_sngss7_data.cfg.nsap[y].id != 0) { - - if ((g_ftdm_sngss7_data.cfg.nsap[y].linkType == g_ftdm_sngss7_data.cfg.mtpRoute[x].linkType) && - (g_ftdm_sngss7_data.cfg.nsap[y].switchType == g_ftdm_sngss7_data.cfg.mtpRoute[x].switchType) && - (g_ftdm_sngss7_data.cfg.nsap[y].ssf == g_ftdm_sngss7_data.cfg.mtpRoute[x].ssf)) { - + /* find the NSAP corresponding to this switchType and SSF */ + int z = 1; + while (g_ftdm_sngss7_data.cfg.nsap[z].id != 0) { + if ((g_ftdm_sngss7_data.cfg.nsap[z].linkType == g_ftdm_sngss7_data.cfg.mtpRoute[x].linkType) && + (g_ftdm_sngss7_data.cfg.nsap[z].switchType == g_ftdm_sngss7_data.cfg.mtpRoute[x].switchType) && + (g_ftdm_sngss7_data.cfg.nsap[z].ssf == g_ftdm_sngss7_data.cfg.mtpRoute[x].ssf)) { + sng_isup.nwId = g_ftdm_sngss7_data.cfg.nsap[z].nwId; /* we have a match so break out of this loop */ break; } /* move on to the next one */ - y++; - } /* while (g_ftdm_sngss7_data.cfg.mtp3_isup[y].id != 0) */ - - /* check how we exited the last while loop */ - if (g_ftdm_sngss7_data.cfg.nsap[y].id == 0) { - SS7_ERROR("\tFailed to find the nwID for = \"%s\"!\n", parm->val); - return FTDM_FAIL; - } else { - sng_isup.nwId = g_ftdm_sngss7_data.cfg.nsap[y].nwId; + z++; } - break; } x++; @@ -867,8 +856,6 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface) ftmod_ss7_fill_in_isup_interface(&sng_isup); - g_ftdm_sngss7_data.cfg.isap[sng_isap.id].spId = sng_isup.id; - return FTDM_SUCCESS; } @@ -1074,6 +1061,7 @@ static int ftmod_ss7_fill_in_mtpLinkSet(sng_link_set_t *mtpLinkSet) g_ftdm_sngss7_data.cfg.mtpLinkSet[i].id = mtpLinkSet->id; g_ftdm_sngss7_data.cfg.mtpLinkSet[i].apc = mtpLinkSet->apc; g_ftdm_sngss7_data.cfg.mtpLinkSet[i].linkType = g_ftdm_sngss7_data.cfg.mtpLink[1].mtp3.linkType; /* KONRAD FIX ME */ + g_ftdm_sngss7_data.cfg.mtpLinkSet[i].cmbLinkSetId = mtpLinkSet->id; g_ftdm_sngss7_data.cfg.mtpLinkSet[i].minActive = mtpLinkSet->minActive; g_ftdm_sngss7_data.cfg.mtpLinkSet[i].numLinks = mtpLinkSet->numLinks; @@ -1092,8 +1080,7 @@ static int ftmod_ss7_fill_in_mtp3_route(sng_route_t *mtp3_route) /* go through all the existing routes and see if we find a match */ i = 1; while (g_ftdm_sngss7_data.cfg.mtpRoute[i].id != 0) { - if (g_ftdm_sngss7_data.cfg.mtpRoute[i].dpc == mtp3_route->dpc) { - + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpRoute[i].name, mtp3_route->name)) { /* we have a match so break out of this loop */ break; } @@ -1115,7 +1102,7 @@ static int ftmod_ss7_fill_in_mtp3_route(sng_route_t *mtp3_route) g_ftdm_sngss7_data.cfg.mtpRoute[i].dpc = mtp3_route->dpc; g_ftdm_sngss7_data.cfg.mtpRoute[i].linkType = mtp3_route->linkType; g_ftdm_sngss7_data.cfg.mtpRoute[i].switchType = mtp3_route->switchType; - g_ftdm_sngss7_data.cfg.mtpRoute[i].cmbLinkSetId = 1; /* mtp3_route->cmbLinkSetId;*/ + g_ftdm_sngss7_data.cfg.mtpRoute[i].cmbLinkSetId = mtp3_route->cmbLinkSetId; g_ftdm_sngss7_data.cfg.mtpRoute[i].isSTP = mtp3_route->isSTP; g_ftdm_sngss7_data.cfg.mtpRoute[i].ssf = mtp3_route->ssf; if (mtp3_route->t6 != 0) { @@ -1222,7 +1209,7 @@ static int ftmod_ss7_fill_in_isup_interface(sng_isup_inf_t *sng_isup) /* go through all the existing interfaces and see if we find a match */ i = 1; while (g_ftdm_sngss7_data.cfg.isupIntf[i].id != 0) { - if (g_ftdm_sngss7_data.cfg.isupIntf[i].nwId == sng_isup->nwId) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.isupIntf[i].name, sng_isup->name)) { /* we have a match so break out of this loop */ break; @@ -1395,7 +1382,8 @@ static int ftmod_ss7_fill_in_isap(sng_isap_t *sng_isap) } g_ftdm_sngss7_data.cfg.isap[i].id = sng_isap->id; - g_ftdm_sngss7_data.cfg.isap[i].suId = 1; /*KONRAD FIX ME */ + g_ftdm_sngss7_data.cfg.isap[i].suId = sng_isap->id; + g_ftdm_sngss7_data.cfg.isap[i].spId = sng_isap->id; g_ftdm_sngss7_data.cfg.isap[i].switchType = sng_isap->switchType; g_ftdm_sngss7_data.cfg.isap[i].ssf = sng_isap->ssf; @@ -1513,7 +1501,9 @@ static int ftmod_ss7_fill_in_self_route(int spc, int linkType, int switchType, i SS7_DEBUG("found existing mtp3 self route\n"); return FTDM_SUCCESS; } else { - SS7_ERROR("found new mtp3 self route but it does not much the route already configured\n"); + SS7_ERROR("found new mtp3 self route but it does not match the route already configured (dpc=%d:spc=%d)\n", + g_ftdm_sngss7_data.cfg.mtpRoute[0].dpc, + spc); return FTDM_FAIL; } From 53d00f6947129979b0515e1d3e6850c55a041715 Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Thu, 9 Sep 2010 18:19:49 -0400 Subject: [PATCH 06/25] freetdm: ss7 - bug fix --- .../src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c | 3 +++ 1 file changed, 3 insertions(+) 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 0286563f29..a76b82a99c 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 @@ -1715,6 +1715,7 @@ ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ /* loop over the cics starting from circuit until range+1 */ for (x = circuit; x < (circuit + range + 1); x++) { + if (g_ftdm_sngss7_data.cfg.isupCkt[x].type != VOICE) continue; /* 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); @@ -2057,6 +2058,7 @@ ftdm_status_t handle_cgb_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ /* loop over the cics starting from circuit until range+1 */ for (x = circuit; x < (circuit + range + 1); x++) { + if (g_ftdm_sngss7_data.cfg.isupCkt[x].type != VOICE) continue; /* 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); @@ -2191,6 +2193,7 @@ ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ /* loop over the cics starting from circuit until range+1 */ for (x = circuit; x < (circuit + range + 1); x++) { + if (g_ftdm_sngss7_data.cfg.isupCkt[x].type != VOICE) continue; /* 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); From 05eb47abf1e1f31d118bf7d3b87cd1d8248b44ac Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Thu, 9 Sep 2010 20:55:38 -0400 Subject: [PATCH 07/25] freetdm: ss7 - update to configuration --- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c | 9 ++- .../ftmod_sangoma_ss7_main.c | 2 + .../ftmod_sangoma_ss7_main.h | 5 +- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c | 67 +++++++++++-------- 4 files changed, 52 insertions(+), 31 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 93bd3154b3..9c9947dfa4 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 @@ -925,6 +925,7 @@ int ftmod_ss7_mtp3_linkset_config(int id) { Pst pst; SnMngmt cfg; + int c; sng_link_set_t *k = &g_ftdm_sngss7_data.cfg.mtpLinkSet[id]; /* initalize the post structure */ @@ -951,9 +952,11 @@ int ftmod_ss7_mtp3_linkset_config(int id) cfg.t.cfg.s.snLnkSet.lnkSetType = k->linkType; /* link type */ cfg.t.cfg.s.snLnkSet.adjDpc = k->apc; /* adjacent DPC */ cfg.t.cfg.s.snLnkSet.nmbActLnkReqd = k->minActive; /* minimum number of active links */ - cfg.t.cfg.s.snLnkSet.nmbCmbLnkSet = 1; /* number of combined link sets */ - cfg.t.cfg.s.snLnkSet.cmbLnkSet[0].cmbLnkSetId = k->cmbLinkSetId; - cfg.t.cfg.s.snLnkSet.cmbLnkSet[0].lnkSetPrior = 0; + cfg.t.cfg.s.snLnkSet.nmbCmbLnkSet = k->numLinks; /* number of combined link sets */ + for(c = 0; c < k->numLinks;c++) { + cfg.t.cfg.s.snLnkSet.cmbLnkSet[c].cmbLnkSetId = k->links[c]; + cfg.t.cfg.s.snLnkSet.cmbLnkSet[c].lnkSetPrior = 0; + } return(sng_cfg_mtp3(&pst, &cfg)); 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 9986b29b2c..a47656f70e 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 @@ -1390,6 +1390,8 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_ss7_init) sngss7_id = 0; + cmbLinkSetId = 1; + /* initalize the global gen_config flag */ g_ftdm_sngss7_data.gen_config = 0; 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 f76a56099f..555c0d97a0 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 @@ -162,7 +162,8 @@ typedef struct sng_link_set { uint32_t flags; uint32_t apc; uint32_t linkType; - uint32_t cmbLinkSetId; + uint32_t switchType; + uint32_t ssf; uint32_t minActive; uint32_t numLinks; uint32_t links[16]; @@ -174,6 +175,7 @@ typedef struct sng_route { uint32_t flags; uint32_t dpc; uint32_t cmbLinkSetId; + uint32_t linkSetId; uint32_t linkType; uint32_t switchType; uint32_t ssf; @@ -421,6 +423,7 @@ typedef enum { extern ftdm_sngss7_data_t g_ftdm_sngss7_data; extern uint32_t sngss7_id; extern ftdm_sched_t *sngss7_sched; +extern int cmbLinkSetId; /******************************************************************************/ /* PROTOTYPES *****************************************************************/ 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 66907e78ba..4c1832d812 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 @@ -46,6 +46,8 @@ typedef struct sng_timeslot int gap; int hole; }sng_timeslot_t; + +int cmbLinkSetId; /******************************************************************************/ /* PROTOTYPES *****************************************************************/ @@ -385,8 +387,6 @@ static int ftmod_ss7_parse_mtp_linkset(ftdm_conf_node_t *mtp_linkset) if (count < 1 || count > 15 ) { SS7_ERROR("Invalid number of mtp_links found (%d)\n", count); return FTDM_FAIL; - } else { - mtpLinkSet.numLinks = count; } /* now we need to see if this linkset exists already or not and grab an Id */ @@ -418,8 +418,7 @@ static int ftmod_ss7_parse_mtp_linkset(ftdm_conf_node_t *mtp_linkset) mtpLink[i].mtp3.apc = mtpLinkSet.apc; mtpLink[i].mtp3.linkSetId = mtpLinkSet.id; - /* fill in the mtplink structure */ - mtpLinkSet.links[count] = ftmod_ss7_fill_in_mtpLink(&mtpLink[i]); + ftmod_ss7_fill_in_mtpLink(&mtpLink[i]); /* increment the links counter */ count++; @@ -428,6 +427,10 @@ static int ftmod_ss7_parse_mtp_linkset(ftdm_conf_node_t *mtp_linkset) i++; } + mtpLinkSet.linkType = mtpLink[0].mtp3.linkType; + mtpLinkSet.switchType = mtpLink[0].mtp3.switchType; + mtpLinkSet.ssf = mtpLink[0].mtp3.ssf; + ftmod_ss7_fill_in_mtpLinkSet(&mtpLinkSet); return FTDM_SUCCESS; @@ -658,14 +661,17 @@ static int ftmod_ss7_parse_mtp_route(ftdm_conf_node_t *mtp_route) /* check if the name matches */ if (!strcasecmp((char *)g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name, parm->val)) { - /* grab the mtpLink id value first*/ - int id = g_ftdm_sngss7_data.cfg.mtpLinkSet[x].links[0]; - /* now, harvest the required infomormation from the global structure */ - mtpRoute.linkType = g_ftdm_sngss7_data.cfg.mtpLink[id].mtp3.linkType; - mtpRoute.switchType = g_ftdm_sngss7_data.cfg.mtpLink[id].mtp3.switchType; - mtpRoute.ssf = g_ftdm_sngss7_data.cfg.mtpLink[id].mtp3.ssf; - mtpRoute.cmbLinkSetId = g_ftdm_sngss7_data.cfg.mtpLinkSet[x].cmbLinkSetId; + mtpRoute.linkType = g_ftdm_sngss7_data.cfg.mtpLinkSet[x].linkType; + mtpRoute.switchType = g_ftdm_sngss7_data.cfg.mtpLinkSet[x].switchType; + mtpRoute.ssf = g_ftdm_sngss7_data.cfg.mtpLinkSet[x].ssf; + mtpRoute.linkSetId = g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id; + cmbLinkSetId++; + mtpRoute.cmbLinkSetId = cmbLinkSetId; + + /* update the linkset with the new cmbLinkSet value */ + g_ftdm_sngss7_data.cfg.mtpLinkSet[x].numLinks++; + g_ftdm_sngss7_data.cfg.mtpLinkSet[x].links[g_ftdm_sngss7_data.cfg.mtpLinkSet[x].numLinks-1] = mtpRoute.cmbLinkSetId; break; } x++; @@ -701,9 +707,11 @@ static int ftmod_ss7_parse_mtp_route(ftdm_conf_node_t *mtp_route) parm = parm + 1; } + ftmod_ss7_fill_in_nsap(&mtpRoute); + ftmod_ss7_fill_in_mtp3_route(&mtpRoute); - ftmod_ss7_fill_in_nsap(&mtpRoute); + return FTDM_SUCCESS; } @@ -747,7 +755,6 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface) int num_parms = isup_interface->n_parameters; int i; int linkSetId; - int linkId; memset(&sng_isup, 0x0, sizeof(sng_isup)); memset(&sng_isap, 0x0, sizeof(sng_isap)); @@ -844,10 +851,15 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface) } /* trickle down the SPC to all sub entities */ - linkSetId = g_ftdm_sngss7_data.cfg.mtpRoute[sng_isup.mtpRouteId].cmbLinkSetId; - for (i = 0; i < g_ftdm_sngss7_data.cfg.mtpLinkSet[linkSetId].numLinks; i ++) { - linkId = g_ftdm_sngss7_data.cfg.mtpLinkSet[linkSetId].links[i]; - g_ftdm_sngss7_data.cfg.mtpLink[linkId].mtp3.spc = g_ftdm_sngss7_data.cfg.spc; + linkSetId = g_ftdm_sngss7_data.cfg.mtpRoute[sng_isup.mtpRouteId].linkSetId; + + i = 1; + while (g_ftdm_sngss7_data.cfg.mtpLink[i].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.linkSetId == linkSetId) { + g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.spc = g_ftdm_sngss7_data.cfg.spc; + } + + i++; } ftmod_ss7_fill_in_isap(&sng_isap); @@ -1053,22 +1065,19 @@ static int ftmod_ss7_fill_in_mtpLink(sng_mtp_link_t *mtpLink) /******************************************************************************/ static int ftmod_ss7_fill_in_mtpLinkSet(sng_link_set_t *mtpLinkSet) { - int count; int i = mtpLinkSet->id; strcpy((char *)g_ftdm_sngss7_data.cfg.mtpLinkSet[i].name, (char *)mtpLinkSet->name); g_ftdm_sngss7_data.cfg.mtpLinkSet[i].id = mtpLinkSet->id; g_ftdm_sngss7_data.cfg.mtpLinkSet[i].apc = mtpLinkSet->apc; - g_ftdm_sngss7_data.cfg.mtpLinkSet[i].linkType = g_ftdm_sngss7_data.cfg.mtpLink[1].mtp3.linkType; /* KONRAD FIX ME */ - g_ftdm_sngss7_data.cfg.mtpLinkSet[i].cmbLinkSetId = mtpLinkSet->id; + g_ftdm_sngss7_data.cfg.mtpLinkSet[i].linkType = mtpLinkSet->linkType; + g_ftdm_sngss7_data.cfg.mtpLinkSet[i].switchType = mtpLinkSet->switchType; + g_ftdm_sngss7_data.cfg.mtpLinkSet[i].ssf = mtpLinkSet->ssf; + + /* these values are filled in as we find routes and start allocating cmbLinkSetIds */ g_ftdm_sngss7_data.cfg.mtpLinkSet[i].minActive = mtpLinkSet->minActive; - g_ftdm_sngss7_data.cfg.mtpLinkSet[i].numLinks = mtpLinkSet->numLinks; - - for (count = 0; count < mtpLinkSet->numLinks; count++) { - g_ftdm_sngss7_data.cfg.mtpLinkSet[i].links[count] = mtpLinkSet->links[count]; - } - + g_ftdm_sngss7_data.cfg.mtpLinkSet[i].numLinks = 0; return 0; } @@ -1104,6 +1113,8 @@ static int ftmod_ss7_fill_in_mtp3_route(sng_route_t *mtp3_route) g_ftdm_sngss7_data.cfg.mtpRoute[i].switchType = mtp3_route->switchType; g_ftdm_sngss7_data.cfg.mtpRoute[i].cmbLinkSetId = mtp3_route->cmbLinkSetId; g_ftdm_sngss7_data.cfg.mtpRoute[i].isSTP = mtp3_route->isSTP; + g_ftdm_sngss7_data.cfg.mtpRoute[i].nwId = mtp3_route->nwId; + g_ftdm_sngss7_data.cfg.mtpRoute[i].linkSetId = mtp3_route->linkSetId; g_ftdm_sngss7_data.cfg.mtpRoute[i].ssf = mtp3_route->ssf; if (mtp3_route->t6 != 0) { g_ftdm_sngss7_data.cfg.mtpRoute[i].t6 = mtp3_route->t6; @@ -1185,15 +1196,17 @@ static int ftmod_ss7_fill_in_nsap(sng_route_t *mtp3_route) if (g_ftdm_sngss7_data.cfg.nsap[i].id == 0) { g_ftdm_sngss7_data.cfg.nsap[i].id = i; + mtp3_route->nwId = i; SS7_DEBUG("found new mtp3_isup interface, id is = %d\n", g_ftdm_sngss7_data.cfg.nsap[i].id); } else { g_ftdm_sngss7_data.cfg.nsap[i].id = i; + mtp3_route->nwId = i; SS7_DEBUG("found existing mtp3_isup interface, id is = %d\n", g_ftdm_sngss7_data.cfg.nsap[i].id); } g_ftdm_sngss7_data.cfg.nsap[i].spId = g_ftdm_sngss7_data.cfg.nsap[i].id; g_ftdm_sngss7_data.cfg.nsap[i].suId = g_ftdm_sngss7_data.cfg.nsap[i].id; - g_ftdm_sngss7_data.cfg.nsap[i].nwId = g_ftdm_sngss7_data.cfg.nsap[i].id; + g_ftdm_sngss7_data.cfg.nsap[i].nwId = mtp3_route->nwId; g_ftdm_sngss7_data.cfg.nsap[i].linkType = mtp3_route->linkType; g_ftdm_sngss7_data.cfg.nsap[i].switchType = mtp3_route->switchType; g_ftdm_sngss7_data.cfg.nsap[i].ssf = mtp3_route->ssf; From 71f142744714968acf672da37a3308dc3d6ce284 Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Thu, 9 Sep 2010 21:22:18 -0400 Subject: [PATCH 08/25] freetdm: ss7 - bug fix in configuration --- .../freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 9c9947dfa4..21ab1d32d2 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 @@ -644,7 +644,7 @@ int ftmod_ss7_mtp2_dlsap_config(int id) cfg.t.cfg.s.sdDLSAP.memMac.region = S_REG; /* memory region and pool id for MAC */ cfg.t.cfg.s.sdDLSAP.memMac.pool = S_POOL; cfg.t.cfg.s.sdDLSAP.maxOutsFrms = MAX_SD_OUTSTANDING; /* maximum outstanding frames */ - cfg.t.cfg.s.sdDLSAP.errType = SD_ERR_NRM; + cfg.t.cfg.s.sdDLSAP.errType = k->mtp2.errorType; cfg.t.cfg.s.sdDLSAP.t1.enb = TRUE; /* timer 1 - Alignment Ready Timer */ cfg.t.cfg.s.sdDLSAP.t1.val = k->mtp2.t1; cfg.t.cfg.s.sdDLSAP.t2.enb = TRUE; /* timer 2 - Not Aligned Timer */ From 29843a6e4ad565c03bfc525c13eafdf4d0aa2c36 Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Thu, 9 Sep 2010 21:45:51 -0400 Subject: [PATCH 09/25] freetdm: ss7 -bug fix --- .../freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c | 1 + 1 file changed, 1 insertion(+) 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 a47656f70e..b5fe619446 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 @@ -1240,6 +1240,7 @@ static ftdm_status_t ftdm_sangoma_ss7_start(ftdm_span_t * span) for (x = 1; x < (span->chan_count + 1); x++) { /* extract the channel structure and sngss7 channel data */ ftdmchan = span->channels[x]; + if (ftdmchan->call_data == NULL) continue; sngss7_info = ftdmchan->call_data; sngss7_span = ftdmchan->span->mod_data; From 5680d93a2243cf06a41e2f79f257cb65d53fcfd6 Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Fri, 10 Sep 2010 11:35:43 -0400 Subject: [PATCH 10/25] freetdm: ss7 - increase mtp2 T7 default value, printing link name now for mtp2 Alarms --- .../ftmod_sangoma_ss7_logger.c | 132 +++++++++++++++--- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c | 2 +- 2 files changed, 117 insertions(+), 17 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c index b666f726a1..1179ed9035 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c @@ -109,6 +109,10 @@ void handle_sng_mtp1_alarm(Pst *pst, L1Mngmt *sta) /******************************************************************************/ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta) { + char buf[50]; + int x = 1; + + memset(buf, '\0', sizeof(buf)); switch (sta->t.usta.alarm.category) { /**************************************************************************/ @@ -126,23 +130,39 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta) case (LSD_EVENT_REMOTE_CONG_END): case (LSD_EVENT_RX_REMOTE_SIPO): + /* find the name for the sap in question */ + x = 1; + while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->t.usta.evntParm[0]) { + break; + } + x++; + } + + if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) { + sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]); + } else { + sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name); + } + + switch (sta->t.usta.alarm.cause) { /******************************************************************/ case (LCM_CAUSE_UNKNOWN): - ftdm_log(FTDM_LOG_ERROR,"[MTP2][SAPID:%d] %s\n", - sta->t.usta.evntParm[0], + ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s\n", + buf, DECODE_LSD_EVENT(sta->t.usta.alarm.event)); break; /******************************************************************/ case (LCM_CAUSE_MGMT_INITIATED): - ftdm_log(FTDM_LOG_ERROR,"[MTP2][SAPID:%d][MGMT] %s\n", - sta->t.usta.evntParm[0], + ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s[MGMT] %s\n", + buf, DECODE_LSD_EVENT(sta->t.usta.alarm.event)); break; /******************************************************************/ default: - ftdm_log(FTDM_LOG_ERROR,"[MTP2][SAPID:%d] %s (***unknown cause***)\n", - sta->t.usta.evntParm[0], + ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s (***unknown cause***)\n", + buf, DECODE_LSD_EVENT(sta->t.usta.alarm.event)); break; /******************************************************************/ @@ -150,23 +170,71 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta) break; /**********************************************************************/ case (LSD_EVENT_PROT_ERR): - ftdm_log(FTDM_LOG_ERROR,"[MTP2][SAPID:%d] %s : %s\n", - sta->t.usta.evntParm[0], + + /* find the name for the sap in question */ + x = 1; + while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->t.usta.evntParm[0]) { + break; + } + x++; + } + + if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) { + sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]); + } else { + sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name); + } + + ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : %s\n", + buf, DECODE_LSD_EVENT(sta->t.usta.alarm.event), DECODE_LSD_CAUSE(sta->t.usta.alarm.cause)); break; /**********************************************************************/ case (LSD_EVENT_ALIGN_LOST): - ftdm_log(FTDM_LOG_ERROR,"[MTP2][SAPID:%d] %s : %s\n", - sta->t.usta.evntParm[0], + + /* find the name for the sap in question */ + x = 1; + while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->t.usta.evntParm[0]) { + break; + } + x++; + } + + if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) { + sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]); + } else { + sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name); + } + + ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : %s\n", + buf, DECODE_LSD_EVENT(sta->t.usta.alarm.event), DECODE_DISC_REASON(sta->t.usta.evntParm[1])); break; /**********************************************************************/ case (LSD_EVENT_RTB_FULL): case (LSD_EVENT_RTB_FULL_OVER): - ftdm_log(FTDM_LOG_ERROR,"[MTP2][SAPID:%d] %s : RTB Queue Len(%d)|Oldest BSN(%d)|Tx Queue Len(%d)|Outstanding Frames(%d)\n", - sta->t.usta.evntParm[0], + + /* find the name for the sap in question */ + x = 1; + while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->t.usta.evntParm[0]) { + break; + } + x++; + } + + if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) { + sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]); + } else { + sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name); + } + + ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : RTB Queue Len(%d)|Oldest BSN(%d)|Tx Queue Len(%d)|Outstanding Frames(%d)\n", + buf, DECODE_LSD_EVENT(sta->t.usta.alarm.event), sta->t.usta.evntParm[1], sta->t.usta.evntParm[2], @@ -175,15 +243,47 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta) break; /**********************************************************************/ case (LSD_EVENT_NEG_ACK): - ftdm_log(FTDM_LOG_ERROR,"[MTP2][SAPID:%d] %s : RTB Queue Len(%d)\n", - sta->t.usta.evntParm[0], + + /* find the name for the sap in question */ + x = 1; + while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->t.usta.evntParm[0]) { + break; + } + x++; + } + + if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) { + sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]); + } else { + sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name); + } + + ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : RTB Queue Len(%d)\n", + buf, DECODE_LSD_EVENT(sta->t.usta.alarm.event), sta->t.usta.evntParm[1]); break; /**********************************************************************/ case (LSD_EVENT_DAT_CFM_SDT): - ftdm_log(FTDM_LOG_ERROR,"[MTP2][SAPID:%d] %s : %d\n", - sta->t.usta.evntParm[0], + + /* find the name for the sap in question */ + x = 1; + while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->t.usta.evntParm[0]) { + break; + } + x++; + } + + if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) { + sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]); + } else { + sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name); + } + + ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : %d\n", + buf, DECODE_LSD_EVENT(sta->t.usta.alarm.event), DECODE_DISC_REASON(sta->t.usta.evntParm[1])); break; 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 4c1832d812..cf0bf7caae 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 @@ -965,7 +965,7 @@ static int ftmod_ss7_fill_in_mtpLink(sng_mtp_link_t *mtpLink) if ( mtpLink->mtp2.t7 != 0 ) { g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t7 = mtpLink->mtp2.t7; }else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t7 = 20; + g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t7 = 40; } if (mtpLink->mtp3.t1 != 0) { From e6d6045ba611785e0e2126fdcfb2daf9c641e260 Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Fri, 10 Sep 2010 11:43:06 -0400 Subject: [PATCH 11/25] freetdm: ss7 - updated mtp3 alarms to print link name instead of sapid --- .../ftmod_sangoma_ss7_logger.c | 32 +++++++++++++++---- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c index 1179ed9035..17e32c77f2 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c @@ -351,15 +351,35 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta) /******************************************************************************/ void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta) { + char buf[50]; + int x = 1; + + memset(buf, '\0', sizeof(buf)); switch (sta->hdr.elmId.elmnt) { /**************************************************************************/ case (STDLSAP): + + /* find the name for the sap in question */ + x = 1; + while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->hdr.elmId.elmntInst1) { + break; + } + x++; + } + + if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) { + sprintf(buf, "[SAPID:%d]", sta->hdr.elmId.elmntInst1); + } else { + sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name); + } + switch (sta->t.usta.alarm.event) { /**********************************************************************/ case (LSN_EVENT_INV_OPC_OTHER_END): - ftdm_log(FTDM_LOG_ERROR,"[MTP3][SAPID:%d] %s : %s : OPC(0x%X%X%X%X)\n", - sta->hdr.elmId.elmntInst1, + ftdm_log(FTDM_LOG_ERROR,"[MTP3]%s %s : %s : OPC(0x%X%X%X%X)\n", + buf, DECODE_LSN_EVENT(sta->t.usta.alarm.event), DECODE_LSN_CAUSE(sta->t.usta.alarm.cause), sta->t.usta.evntParm[3], @@ -369,16 +389,16 @@ void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta) break; /**********************************************************************/ case (LSN_EVENT_INV_SLC_OTHER_END): - ftdm_log(FTDM_LOG_ERROR,"[MTP3][SAPID:%d] %s : %s : SLC(%d)\n", - sta->hdr.elmId.elmntInst1, + ftdm_log(FTDM_LOG_ERROR,"[MTP3]%s %s : %s : SLC(%d)\n", + buf, DECODE_LSN_EVENT(sta->t.usta.alarm.event), DECODE_LSN_CAUSE(sta->t.usta.alarm.cause), sta->t.usta.evntParm[0]); break; /**********************************************************************/ default: - ftdm_log(FTDM_LOG_ERROR,"[MTP3][SAPID:%d] %s(%d) : %s(%d)\n", - sta->hdr.elmId.elmntInst1, + ftdm_log(FTDM_LOG_ERROR,"[MTP3]%s %s(%d) : %s(%d)\n", + buf, DECODE_LSN_EVENT(sta->t.usta.alarm.event), sta->t.usta.alarm.event, DECODE_LSN_CAUSE(sta->t.usta.alarm.cause), From bc2638334bca11e79b24ad1e44df9af09acbd0f7 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 10 Sep 2010 14:01:52 -0400 Subject: [PATCH 12/25] freetdm: iterators refactoring add channel iterator --- libs/freetdm/mod_freetdm/mod_freetdm.c | 19 +-- libs/freetdm/src/ftdm_io.c | 116 ++++++++++++++++-- libs/freetdm/src/include/freetdm.h | 28 ++++- libs/freetdm/src/include/private/ftdm_core.h | 3 + libs/freetdm/src/include/private/ftdm_types.h | 17 +++ 5 files changed, 161 insertions(+), 22 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index b911155334..6b4fec6d87 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -1404,6 +1404,7 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session private_t *tech_pvt = NULL; switch_channel_t *channel = NULL; ftdm_iterator_t *iter = NULL; + ftdm_iterator_t *curr = NULL; const char *var_name = NULL; const char *var_value = NULL; uint32_t spanid, chanid; @@ -1516,12 +1517,13 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session } /* Add any channel variable to the dial plan */ iter = ftdm_channel_get_var_iterator(sigmsg->channel); - for ( ; iter; iter = ftdm_iterator_next(iter)) { - ftdm_channel_get_current_var(iter, &var_name, &var_value); + for (curr = iter ; curr; curr = ftdm_iterator_next(curr)) { + ftdm_channel_get_current_var(curr, &var_name, &var_value); snprintf(name, sizeof(name), FREETDM_VAR_PREFIX "%s", var_name); switch_channel_set_variable_printf(channel, name, "%s", var_value); } - + ftdm_iterator_free(iter); + switch_channel_set_state(channel, CS_INIT); if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error spawning thread\n"); @@ -2496,7 +2498,8 @@ static switch_status_t load_config(void) unsigned boosti = 0; unsigned int i = 0; ftdm_channel_t *fchan = NULL; - unsigned int chancount = 0; + ftdm_iterator_t *chaniter = NULL; + ftdm_iterator_t *curr = NULL; memset(boost_spans, 0, sizeof(boost_spans)); memset(&globals, 0, sizeof(globals)); @@ -2780,11 +2783,13 @@ static switch_status_t load_config(void) switch_set_string(SPAN_CONFIG[span_id].dialplan, dialplan); SPAN_CONFIG[span_id].analog_options = analog_options | globals.analog_options; - chancount = ftdm_span_get_chan_count(span); - for (i = 1; i <= chancount; i++) { - fchan = ftdm_span_get_channel(span, i); + chaniter = ftdm_span_get_chan_iterator(span); + curr = chaniter + for (curr = chaniter ; curr; curr = ftdm_iterator_next(curr)) { + fchan = ftdm_iterator_current(curr); ftdm_channel_set_private(fchan, &SPAN_CONFIG[span_id].pvts[i]); } + ftdm_iterator_free(chaniter); if (dial_regex) { switch_set_string(SPAN_CONFIG[span_id].dial_regex, dial_regex); diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index b275403c85..b83f1b7e88 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -3524,16 +3524,48 @@ done: return var; } -FT_DECLARE(ftdm_iterator_t *) ftdm_channel_get_var_iterator(const ftdm_channel_t *ftdmchan) +static ftdm_iterator_t *get_iterator(ftdm_iterator_type_t type, ftdm_iterator_t *iter) { - ftdm_hash_iterator_t *iter = NULL; + int allocated = 0; + if (iter) { + if (iter->type != type) { + ftdm_log(FTDM_LOG_ERROR, "Cannot switch iterator types\n"); + return NULL; + } + allocated = iter->allocated; + memset(iter, 0, sizeof(*iter)); + iter->type = type; + iter->allocated = allocated; + return iter; + } + iter = ftdm_calloc(1, sizeof(*iter)); + if (!iter) { + return NULL; + } + iter->type = type; + iter->allocated = 1; + return iter; +} + +FT_DECLARE(ftdm_iterator_t *) ftdm_channel_get_var_iterator(const ftdm_channel_t *ftdmchan, ftdm_iterator_t *iter) +{ + if (!(iter = get_iterator(FTDM_ITERATOR_VARS, iter))) { + return NULL; + } ftdm_channel_lock(ftdmchan); - - iter = ftdmchan->variable_hash == NULL ? NULL : hashtable_first(ftdmchan->variable_hash); - + iter->pvt.hashiter = ftdmchan->variable_hash == NULL ? NULL : hashtable_first(ftdmchan->variable_hash); ftdm_channel_unlock(ftdmchan); + return iter; +} +FT_DECLARE(ftdm_iterator_t *) ftdm_span_get_chan_iterator(const ftdm_span_t *span, ftdm_iterator_t *iter) +{ + if (!(iter = get_iterator(FTDM_ITERATOR_CHANS, iter))) { + return NULL; + } + iter->pvt.chaniter.index = 1; + iter->pvt.chaniter.span = span; return iter; } @@ -3545,11 +3577,9 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_get_current_var(ftdm_iterator_t *iter, co *var_name = NULL; *var_val = NULL; - if (!iter) { - return FTDM_FAIL; - } + ftdm_assert_return(iter && (iter->type == FTDM_ITERATOR_CHANS) && iter->pvt.hashiter, FTDM_FAIL, "Cannot get variable from invalid iterator!\n"); - hashtable_this(iter, &key, NULL, &val); + hashtable_this(iter->pvt.hashiter, &key, NULL, &val); *var_name = key; *var_val = val; @@ -3559,10 +3589,72 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_get_current_var(ftdm_iterator_t *iter, co FT_DECLARE(ftdm_iterator_t *) ftdm_iterator_next(ftdm_iterator_t *iter) { - if (!iter) { - return NULL; + ftdm_assert_return(iter && iter->type, NULL, "Invalid iterator\n"); + + switch (iter->type) { + case FTDM_ITERATOR_VARS: + if (!iter->pvt.hashiter) { + return NULL; + } + iter->pvt.hashiter = hashtable_next(iter->pvt.hashiter); + if (!iter->pvt.hashiter) { + return NULL; + } + return iter; + case FTDM_ITERATOR_CHANS: + if (iter->pvt.chaniter.index == iter->pvt.chaniter.span->chan_count) { + return NULL; + } + iter->pvt.chaniter.index++; + return iter; + default: + break; } - return hashtable_next(iter); + + ftdm_assert_return(0, NULL, "Unknown iterator type\n"); + return NULL; +} + +FT_DECLARE(void *) ftdm_iterator_current(ftdm_iterator_t *iter) +{ + const void *key = NULL; + void *val = NULL; + + ftdm_assert_return(iter && iter->type, NULL, "Invalid iterator\n"); + + switch (iter->type) { + case FTDM_ITERATOR_VARS: + hashtable_this(iter->pvt.hashiter, &key, NULL, &val); + /* I decided to return the key instead of the value since the value can be retrieved using the key */ + return (void *)key; + case FTDM_ITERATOR_CHANS: + ftdm_assert_return(iter->pvt.chaniter.index, NULL, "channel iterator index cannot be zero!\n"); + ftdm_assert_return(iter->pvt.chaniter.index > iter->pvt.chaniter.span->chan_count, NULL, "channel iterator index bigger than span chan count!\n"); + return iter->pvt.chaniter.span->channels[iter->pvt.chaniter.index]; + default: + break; + } + + ftdm_assert_return(0, NULL, "Unknown iterator type\n"); + return NULL; +} + +FT_DECLARE(ftdm_status_t) ftdm_iterator_free(ftdm_iterator_t *iter) +{ + /* it's valid to pass a NULL iterator, do not return failure */ + if (!iter) { + return FTDM_SUCCESS; + } + + if (!iter->allocated) { + memset(iter, 0, sizeof(*iter)); + return FTDM_SUCCESS; + } + + ftdm_assert_return(iter->type, FTDM_FAIL, "Cannot free invalid iterator\n"); + ftdm_safe_free(iter); + + return FTDM_SUCCESS; } static struct { diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index 0437e02e51..1f50a2ccaa 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -386,7 +386,7 @@ typedef struct ftdm_conf_parameter { } ftdm_conf_parameter_t; /*! \brief Opaque general purpose iterator */ -typedef void ftdm_iterator_t; +typedef struct ftdm_iterator ftdm_iterator_t; /*! \brief Channel commands that can be executed through ftdm_channel_command() */ typedef enum { @@ -1032,8 +1032,19 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_add_var(ftdm_channel_t *ftdmchan, const c FT_DECLARE(const char *) ftdm_channel_get_var(ftdm_channel_t *ftdmchan, const char *var_name); /*! \brief Get an iterator to iterate over the channel variables - * \note The iterator pointer returned is only valid while the channel is open and it'll be destroyed when the channel is closed. */ -FT_DECLARE(ftdm_iterator_t *) ftdm_channel_get_var_iterator(const ftdm_channel_t *ftdmchan); + * \param ftdmchan The channel structure containing the variables + * \param iter Optional iterator. You can reuse an old iterator (not previously freed) to avoid the extra allocation of a new iterator. + * \note The iterator pointer returned is only valid while the channel is open and it'll be destroyed when the channel is closed. + * This iterator is completely non-thread safe, if you are adding variables or removing variables while iterating + * results are unpredictable + */ +FT_DECLARE(ftdm_iterator_t *) ftdm_channel_get_var_iterator(const ftdm_channel_t *ftdmchan, ftdm_iterator_t *iter); + +/*! \brief Get iterator current value (depends on the iterator type) + * \note Channel iterators return a pointer to ftdm_channel_t + * Variable iterators return a pointer to the variable name (not the variable value) + */ +FT_DECLARE(void *) ftdm_iterator_current(ftdm_iterator_t *iter); /*! \brief Get variable name and value for the current iterator position */ FT_DECLARE(ftdm_status_t) ftdm_channel_get_current_var(ftdm_iterator_t *iter, const char **var_name, const char **var_val); @@ -1041,6 +1052,11 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_get_current_var(ftdm_iterator_t *iter, co /*! \brief Advance iterator */ FT_DECLARE(ftdm_iterator_t *) ftdm_iterator_next(ftdm_iterator_t *iter); +/*! \brief Free iterator + * \note You must free an iterator after using it unless you plan to reuse it + */ +FT_DECLARE(ftdm_status_t) ftdm_iterator_free(ftdm_iterator_t *iter); + /*! \brief Get the span pointer associated to the channel */ FT_DECLARE(ftdm_span_t *) ftdm_channel_get_span(const ftdm_channel_t *ftdmchan); @@ -1144,6 +1160,12 @@ FT_DECLARE(uint32_t) ftdm_span_get_id(const ftdm_span_t *span); /*! \brief Get the span name */ FT_DECLARE(const char *) ftdm_span_get_name(const ftdm_span_t *span); +/*! \brief Get iterator for the span channels + * \param span The span containing the channels + * \param iter Optional iterator. You can reuse an old iterator (not previously freed) to avoid the extra allocation of a new iterator. + */ +FT_DECLARE(ftdm_iterator_t *) ftdm_span_get_chan_iterator(const ftdm_span_t *span, ftdm_iterator_t *iter); + /*! * \brief Execute a text command. The text command output will be returned and must be free'd * diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h index 74bea8148c..d8947f6de4 100644 --- a/libs/freetdm/src/include/private/ftdm_core.h +++ b/libs/freetdm/src/include/private/ftdm_core.h @@ -619,6 +619,9 @@ FT_DECLARE(ftdm_status_t) ftdm_span_trigger_signals(const ftdm_span_t *span); #define ftdm_log_chan(fchan, level, format, ...) ftdm_log(level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__) #define ftdm_log_chan_msg(fchan, level, msg) ftdm_log(level, "[s%dc%d][%d:%d] " msg, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id) +#define ftdm_span_lock(span) ftdm_mutex_lock(span->mutex) +#define ftdm_span_unlock(span) ftdm_mutex_unlock(span->mutex) + FT_DECLARE_DATA extern const char *FTDM_LEVEL_NAMES[9]; static __inline__ void ftdm_abort(void) diff --git a/libs/freetdm/src/include/private/ftdm_types.h b/libs/freetdm/src/include/private/ftdm_types.h index d8e8b5c2e6..ba6956344d 100644 --- a/libs/freetdm/src/include/private/ftdm_types.h +++ b/libs/freetdm/src/include/private/ftdm_types.h @@ -366,6 +366,23 @@ typedef ftdm_status_t (*ftdm_span_start_t)(ftdm_span_t *span); typedef ftdm_status_t (*ftdm_span_stop_t)(ftdm_span_t *span); typedef ftdm_status_t (*ftdm_channel_sig_read_t)(ftdm_channel_t *ftdmchan, void *data, ftdm_size_t size); +typedef enum { + FTDM_ITERATOR_VARS = 1, + FTDM_ITERATOR_CHANS, +} ftdm_iterator_type_t; + +struct ftdm_iterator { + ftdm_iterator_type_t type; + unsigned int allocated:1; + union { + struct { + int32_t index; + const ftdm_span_t *span; + } chaniter; + ftdm_hash_iterator_t *hashiter; + } pvt; +}; + #ifdef __cplusplus } #endif From 507b73070b65e0d28c4ce4714bb6d64d4cbff7f4 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 10 Sep 2010 14:09:06 -0400 Subject: [PATCH 13/25] freetdm: fix iterator usage --- libs/freetdm/mod_freetdm/mod_freetdm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 6b4fec6d87..9d6188f8a0 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -1516,7 +1516,7 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session switch_channel_set_variable_printf(channel, "freetdm_custom_call_data", "%s", channel_caller_data->raw_data); } /* Add any channel variable to the dial plan */ - iter = ftdm_channel_get_var_iterator(sigmsg->channel); + iter = ftdm_channel_get_var_iterator(sigmsg->channel, NULL); for (curr = iter ; curr; curr = ftdm_iterator_next(curr)) { ftdm_channel_get_current_var(curr, &var_name, &var_value); snprintf(name, sizeof(name), FREETDM_VAR_PREFIX "%s", var_name); @@ -2783,9 +2783,9 @@ static switch_status_t load_config(void) switch_set_string(SPAN_CONFIG[span_id].dialplan, dialplan); SPAN_CONFIG[span_id].analog_options = analog_options | globals.analog_options; - chaniter = ftdm_span_get_chan_iterator(span); - curr = chaniter - for (curr = chaniter ; curr; curr = ftdm_iterator_next(curr)) { + chaniter = ftdm_span_get_chan_iterator(span, NULL); + curr = chaniter; + for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { fchan = ftdm_iterator_current(curr); ftdm_channel_set_private(fchan, &SPAN_CONFIG[span_id].pvts[i]); } From 8370f0c23319dc41410507754ac8571b1cac42c4 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 10 Sep 2010 14:46:51 -0400 Subject: [PATCH 14/25] freetdm: more iterator fixes --- libs/freetdm/mod_freetdm/mod_freetdm.c | 18 ++++++++++-------- libs/freetdm/src/ftdm_io.c | 8 ++++---- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 9d6188f8a0..c70e0f9a65 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -3597,6 +3597,8 @@ SWITCH_STANDARD_API(ft_function) { char *mycmd = NULL, *argv[10] = { 0 }; int argc = 0; + ftdm_iterator_t *chaniter = NULL; + ftdm_iterator_t *curr = NULL; if (!zstr(cmd) && (mycmd = strdup(cmd))) { argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); @@ -3642,11 +3644,11 @@ SWITCH_STANDARD_API(ft_function) dump_chan_xml(span, chan_id, stream); } } else { - uint32_t j; - uint32_t ccount = ftdm_span_get_chan_count(span); - for (j = 1; j <= ccount; j++) { - dump_chan_xml(span, j, stream); + chaniter = ftdm_span_get_chan_iterator(span, NULL); + for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { + dump_chan_xml(span, ftdm_channel_get_id(ftdm_iterator_current(curr)), stream); } + ftdm_iterator_free(chaniter); } } @@ -3662,12 +3664,12 @@ SWITCH_STANDARD_API(ft_function) dump_chan(span, chan_id, stream); } } else { - uint32_t j; - uint32_t ccount = ftdm_span_get_chan_count(span); stream->write_function(stream, "+OK\n"); - for (j = 1; j <= ccount; j++) { - dump_chan(span, j, stream); + chaniter = ftdm_span_get_chan_iterator(span, NULL); + for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { + dump_chan(span, ftdm_channel_get_id(ftdm_iterator_current(curr)), stream); } + ftdm_iterator_free(chaniter); } } diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index b83f1b7e88..c774e61901 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -3602,9 +3602,8 @@ FT_DECLARE(ftdm_iterator_t *) ftdm_iterator_next(ftdm_iterator_t *iter) } return iter; case FTDM_ITERATOR_CHANS: - if (iter->pvt.chaniter.index == iter->pvt.chaniter.span->chan_count) { - return NULL; - } + ftdm_assert_return(iter->pvt.chaniter.index, NULL, "channel iterator index cannot be zero!\n"); + ftdm_assert_return(iter->pvt.chaniter.index <= iter->pvt.chaniter.span->chan_count, NULL, "channel iterator index bigger than span chan count!\n"); iter->pvt.chaniter.index++; return iter; default: @@ -3629,7 +3628,7 @@ FT_DECLARE(void *) ftdm_iterator_current(ftdm_iterator_t *iter) return (void *)key; case FTDM_ITERATOR_CHANS: ftdm_assert_return(iter->pvt.chaniter.index, NULL, "channel iterator index cannot be zero!\n"); - ftdm_assert_return(iter->pvt.chaniter.index > iter->pvt.chaniter.span->chan_count, NULL, "channel iterator index bigger than span chan count!\n"); + ftdm_assert_return(iter->pvt.chaniter.index <= iter->pvt.chaniter.span->chan_count, NULL, "channel iterator index bigger than span chan count!\n"); return iter->pvt.chaniter.span->channels[iter->pvt.chaniter.index]; default: break; @@ -3652,6 +3651,7 @@ FT_DECLARE(ftdm_status_t) ftdm_iterator_free(ftdm_iterator_t *iter) } ftdm_assert_return(iter->type, FTDM_FAIL, "Cannot free invalid iterator\n"); + ftdm_log(FTDM_LOG_DEBUG, "Freeing iterator %p\n", iter); ftdm_safe_free(iter); return FTDM_SUCCESS; From 9fbe363a86217b1b8a99553dbf8933414ebf26ac Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Fri, 10 Sep 2010 15:34:13 -0400 Subject: [PATCH 15/25] freetdm: ss7 - switching back to sending RSC rather then GRS at start --- .../src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) 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 b5fe619446..70a1a05440 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 @@ -1249,7 +1249,7 @@ static ftdm_status_t ftdm_sangoma_ss7_start(ftdm_span_t * span) /* throw the pause flag */ sngss7_set_flag(sngss7_info, FLAG_INFID_PAUSED); - +#if 0 /* throw the grp reset flag */ sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX); if (x == 1) { @@ -1257,7 +1257,10 @@ static ftdm_status_t ftdm_sangoma_ss7_start(ftdm_span_t * span) sngss7_span->tx_grs.circuit = sngss7_info->circuit->id; sngss7_span->tx_grs.range = span->chan_count -1; } - +#else + /* throw the channel into reset */ + sngss7_set_flag(sngss7_info, FLAG_RESET_TX); +#endif /* throw the channel to suspend */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); From c9e780b9b68c298687748c23818002511381ee3c Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 10 Sep 2010 17:52:08 -0400 Subject: [PATCH 16/25] freetdm: remove iterator free log --- libs/freetdm/src/ftdm_io.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index c774e61901..47d6936c54 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -3603,7 +3603,9 @@ FT_DECLARE(ftdm_iterator_t *) ftdm_iterator_next(ftdm_iterator_t *iter) return iter; case FTDM_ITERATOR_CHANS: ftdm_assert_return(iter->pvt.chaniter.index, NULL, "channel iterator index cannot be zero!\n"); - ftdm_assert_return(iter->pvt.chaniter.index <= iter->pvt.chaniter.span->chan_count, NULL, "channel iterator index bigger than span chan count!\n"); + if (iter->pvt.chaniter.index == iter->pvt.chaniter.span->chan_count) { + return NULL; + } iter->pvt.chaniter.index++; return iter; default: @@ -3651,7 +3653,6 @@ FT_DECLARE(ftdm_status_t) ftdm_iterator_free(ftdm_iterator_t *iter) } ftdm_assert_return(iter->type, FTDM_FAIL, "Cannot free invalid iterator\n"); - ftdm_log(FTDM_LOG_DEBUG, "Freeing iterator %p\n", iter); ftdm_safe_free(iter); return FTDM_SUCCESS; From 7cb6b4b3e141772d1c3196560d7c268cabd2a24c Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 10 Sep 2010 18:12:12 -0400 Subject: [PATCH 17/25] freetdm: fix assertion --- libs/freetdm/src/ftdm_io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 47d6936c54..49b61eed69 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -3577,7 +3577,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_get_current_var(ftdm_iterator_t *iter, co *var_name = NULL; *var_val = NULL; - ftdm_assert_return(iter && (iter->type == FTDM_ITERATOR_CHANS) && iter->pvt.hashiter, FTDM_FAIL, "Cannot get variable from invalid iterator!\n"); + ftdm_assert_return(iter && (iter->type == FTDM_ITERATOR_VARS) && iter->pvt.hashiter, FTDM_FAIL, "Cannot get variable from invalid iterator!\n"); hashtable_this(iter->pvt.hashiter, &key, NULL, &val); From a1eb601b197fc0fb3eb724768c22f920ee7b471c Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Fri, 10 Sep 2010 19:17:06 -0400 Subject: [PATCH 18/25] freetdm: ss7 - update to logging --- .../ftmod_sangoma_ss7_logger.c | 54 ++++++++++++++++--- 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c index 17e32c77f2..03f0beb090 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c @@ -423,13 +423,53 @@ void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta) break; /**************************************************************************/ case (STROUT): - ftdm_log(FTDM_LOG_ERROR,"[MTP3][DPC:0x%d%d%d%d] %s : %s\n", - sta->t.usta.evntParm[0], - sta->t.usta.evntParm[1], - sta->t.usta.evntParm[2], - sta->t.usta.evntParm[3], - DECODE_LSN_EVENT(sta->t.usta.alarm.event), - DECODE_LSN_CAUSE(sta->t.usta.alarm.cause)); + switch (sta->t.usta.alarm.event) { + /**********************************************************************/ + case (LSN_EVENT_RX_TRANSFER_MSG): + switch (sta->t.usta.evntParm[5]) { + /******************************************************************/ + case (0x23): + ftdm_log(FTDM_LOG_INFO,"[MTP3] Rx SNM TFC\n"); + break; + /******************************************************************/ + case (0x34): + ftdm_log(FTDM_LOG_INFO,"[MTP3] Rx SNM TFR\n"); + break; + /******************************************************************/ + case (0x54): + ftdm_log(FTDM_LOG_INFO,"[MTP3] Rx SNM TFA\n"); + break; + /******************************************************************/ + case (0x14): + ftdm_log(FTDM_LOG_INFO,"[MTP3] Rx SNM TFP\n"); + break; + /******************************************************************/ + case (0x24): + ftdm_log(FTDM_LOG_INFO,"[MTP3] Rx SNM TFP (cluster)\n"); + break; + /******************************************************************/ + case (0x64): + ftdm_log(FTDM_LOG_INFO,"[MTP3] Rx SNM TFA (cluster)\n"); + break; + /******************************************************************/ + case (0x44): + ftdm_log(FTDM_LOG_INFO,"[MTP3] Rx SNM TFR (cluster)\n"); + break; + /******************************************************************/ + } /* switch (sta->t.usta.evntParm[5]) */ + break; + /**********************************************************************/ + default: + ftdm_log(FTDM_LOG_ERROR,"[MTP3][DPC:0x%d%d%d%d] %s : %s\n", + sta->t.usta.evntParm[0], + sta->t.usta.evntParm[1], + sta->t.usta.evntParm[2], + sta->t.usta.evntParm[3], + DECODE_LSN_EVENT(sta->t.usta.alarm.event), + DECODE_LSN_CAUSE(sta->t.usta.alarm.cause)); + break; + /**********************************************************************/ + } /* switch (sta->t.usta.alarm.event) */ break; /**************************************************************************/ default: From 5219ab8c6330a4e00eb4c1262906b39044d89496 Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Mon, 13 Sep 2010 20:38:00 -0400 Subject: [PATCH 19/25] freetdm: ss7 - fixed bug in cic status, added activate/deactivate functions for mtp2/3 --- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c | 435 +++++++++++++++--- .../ftmod_sangoma_ss7_cntrl.c | 253 ++++++++++ .../ftmod_sangoma_ss7_handle.c | 22 - .../ftmod_sangoma_ss7_main.c | 28 +- .../ftmod_sangoma_ss7_main.h | 9 + .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c | 46 +- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c | 2 +- .../ftmod_sangoma_ss7_support.c | 59 +++ .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c | 9 +- 9 files changed, 724 insertions(+), 139 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c index c0ce84b2ed..20e1f27c9b 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c @@ -67,6 +67,14 @@ static ftdm_status_t handle_tx_ubl(ftdm_stream_handle_t *stream, int span, int c static ftdm_status_t handle_tx_cgb(ftdm_stream_handle_t *stream, int span, int chan, int range, int verbose); static ftdm_status_t handle_tx_cgu(ftdm_stream_handle_t *stream, int span, int chan, int range, int verbose); +static ftdm_status_t handle_activate_link(ftdm_stream_handle_t *stream, char *name); +static ftdm_status_t handle_deactivate_link(ftdm_stream_handle_t *stream, char *name); + +static ftdm_status_t handle_activate_linkset(ftdm_stream_handle_t *stream, char *name); +static ftdm_status_t handle_deactivate_linkset(ftdm_stream_handle_t *stream, char *name); + +static ftdm_status_t handle_tx_lpo(ftdm_stream_handle_t *stream, char *name); +static ftdm_status_t handle_tx_lpr(ftdm_stream_handle_t *stream, char *name); static ftdm_status_t handle_status_link(ftdm_stream_handle_t *stream, char *name); static ftdm_status_t handle_status_linkset(ftdm_stream_handle_t *stream, char *name); @@ -488,7 +496,97 @@ ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const cha stream->write_function(stream, "Unknown \"grs\" command\n"); goto handle_cli_error; /**********************************************************************/ - } + } + /**************************************************************************/ + } else if (!strcasecmp(argv[c], "lpo")) { + /**************************************************************************/ + if (check_arg_count(argc, 2)) goto handle_cli_error_argc; + c++; + + if (!strcasecmp(argv[c], "link")) { + /**********************************************************************/ + if (check_arg_count(argc, 3)) goto handle_cli_error_argc; + c++; + + handle_tx_lpo(stream, argv[c]); + /**********************************************************************/ + } else { + /**********************************************************************/ + stream->write_function(stream, "Unknown \"lpo\" command\n"); + goto handle_cli_error; + /**********************************************************************/ + } + /**************************************************************************/ + } else if (!strcasecmp(argv[c], "lpr")) { + /**************************************************************************/ + if (check_arg_count(argc, 2)) goto handle_cli_error_argc; + c++; + + if (!strcasecmp(argv[c], "link")) { + /**********************************************************************/ + if (check_arg_count(argc, 3)) goto handle_cli_error_argc; + c++; + + handle_tx_lpr(stream, argv[c]); + /**********************************************************************/ + } else { + /**********************************************************************/ + stream->write_function(stream, "Unknown \"lpr\" command\n"); + goto handle_cli_error; + /**********************************************************************/ + } + /**************************************************************************/ + } else if (!strcasecmp(argv[c], "activate")) { + /**************************************************************************/ + if (check_arg_count(argc, 2)) goto handle_cli_error_argc; + c++; + + if (!strcasecmp(argv[c], "link")) { + /**********************************************************************/ + if (check_arg_count(argc, 3)) goto handle_cli_error_argc; + c++; + + handle_activate_link(stream, argv[c]); + /**********************************************************************/ + }else if (!strcasecmp(argv[c], "linkset")) { + /**********************************************************************/ + if (check_arg_count(argc, 3)) goto handle_cli_error_argc; + c++; + + handle_activate_linkset(stream, argv[c]); + /**********************************************************************/ + } else { + /**********************************************************************/ + stream->write_function(stream, "Unknown \"activate\" command\n"); + goto handle_cli_error; + /**********************************************************************/ + } + /**************************************************************************/ + } else if (!strcasecmp(argv[c], "deactivate")) { + /**************************************************************************/ + if (check_arg_count(argc, 2)) goto handle_cli_error_argc; + c++; + + if (!strcasecmp(argv[c], "link")) { + /**********************************************************************/ + if (check_arg_count(argc, 3)) goto handle_cli_error_argc; + c++; + + handle_deactivate_link(stream, argv[c]); + /**********************************************************************/ + }else if (!strcasecmp(argv[c], "linkset")) { + /**********************************************************************/ + if (check_arg_count(argc, 3)) goto handle_cli_error_argc; + c++; + + handle_deactivate_linkset(stream, argv[c]); + /**********************************************************************/ + } else { + /**********************************************************************/ + stream->write_function(stream, "Unknown \"deactivate\" command\n"); + goto handle_cli_error; + /**********************************************************************/ + } /**************************************************************************/ } else { /**************************************************************************/ @@ -536,11 +634,18 @@ static ftdm_status_t handle_print_usuage(ftdm_stream_handle_t *stream) stream->write_function(stream, "ftdm ss7 ubl span X chan Y\n"); stream->write_function(stream, "ftdm ss7 rsc span X chan Y\n"); stream->write_function(stream, "ftdm ss7 grs span X chan Y range Z\n"); + stream->write_function(stream, "ftdm ss7 cgb span X chan Y range Z\n"); + stream->write_function(stream, "ftdm ss7 cgu span X chan Y range Z\n"); stream->write_function(stream, "\n"); stream->write_function(stream, "Ftmod_sangoma_ss7 link control:\n"); stream->write_function(stream, "ftdm ss7 inhibit link X\n"); stream->write_function(stream, "ftdm ss7 uninhibit link X\n"); - + stream->write_function(stream, "ftdm ss7 activate link X\n"); + stream->write_function(stream, "ftdm ss7 deactivate link X\n"); + stream->write_function(stream, "ftdm ss7 activate linkset X\n"); + stream->write_function(stream, "ftdm ss7 deactivate linkset X\n"); + stream->write_function(stream, "ftdm ss7 lpo link X\n"); + stream->write_function(stream, "ftdm ss7 lpr link X\n"); stream->write_function(stream, "\n"); return FTDM_SUCCESS; @@ -915,87 +1020,100 @@ static ftdm_status_t handle_show_blocks(ftdm_stream_handle_t *stream, int span, /******************************************************************************/ static ftdm_status_t handle_show_status(ftdm_stream_handle_t *stream, int span, int chan, int verbose) { - int x; - sngss7_chan_data_t *ss7_info; - ftdm_channel_t *ftdmchan; - int lspan; - int lchan; - ftdm_signaling_status_t sigstatus = FTDM_SIG_STATE_DOWN; + int x; + sngss7_chan_data_t *ss7_info; + ftdm_channel_t *ftdmchan; + int lspan; + int lchan; + ftdm_signaling_status_t sigstatus = FTDM_SIG_STATE_DOWN; + sng_isup_ckt_t *ckt; x=1; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { - if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { - ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; - ftdmchan = ss7_info->ftdmchan; + /* extract the circuit to make it easier to work with */ + ckt = &g_ftdm_sngss7_data.cfg.isupCkt[x]; /* if span == 0 then all spans should be printed */ if (span == 0) { - lspan = ftdmchan->physical_span_id; + lspan = ckt->span; } else { lspan = span; } /* if chan == 0 then all chans should be printed */ if (chan == 0) { - lchan = ftdmchan->physical_chan_id; + lchan = ckt->chan; } else { lchan = chan; } - if ((ftdmchan->physical_span_id == lspan) && (ftdmchan->physical_chan_id == lchan)) { - /* grab the signaling_status */ - ftdm_channel_get_sig_status(ftdmchan, &sigstatus); + /* check if this circuit is one of the circuits we're interested in */ + if ((ckt->span == lspan) && (ckt->chan == lchan)) { + if (ckt->type == HOLE) { + stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|NOT USED\n", + ckt->span, + ckt->chan, + ckt->cic); + } else if (ckt->type == SIG) { + stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|SIGNALING LINK\n", + ckt->span, + ckt->chan, + ckt->cic); + } else { + ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; + ftdmchan = ss7_info->ftdmchan; - stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|sig_status=%s|state=%s|", - ftdmchan->physical_span_id, - ftdmchan->physical_chan_id, - ss7_info->circuit->cic, - ftdm_signaling_status2str(sigstatus), - ftdm_channel_state2str(ftdmchan->state)); - - if((sngss7_test_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX)) || (sngss7_test_flag(ss7_info, FLAG_GRP_MN_BLOCK_TX))) { - stream->write_function(stream, "l_mn=Y|"); - }else { - stream->write_function(stream, "l_mn=N|"); - } - - if((sngss7_test_flag(ss7_info, FLAG_CKT_MN_BLOCK_RX)) || (sngss7_test_flag(ss7_info, FLAG_GRP_MN_BLOCK_RX))) { - stream->write_function(stream, "r_mn=Y|"); - }else { - stream->write_function(stream, "r_mn=N|"); - } - - if(sngss7_test_flag(ss7_info, FLAG_GRP_HW_BLOCK_TX)) { - stream->write_function(stream, "l_hw=Y|"); - }else { - stream->write_function(stream, "l_hw=N|"); - } - - if(sngss7_test_flag(ss7_info, FLAG_GRP_HW_BLOCK_RX)) { - stream->write_function(stream, "r_hw=Y|"); - }else { - stream->write_function(stream, "r_hw=N|"); - } - - if(sngss7_test_flag(ss7_info, FLAG_CKT_LC_BLOCK_RX)) { - stream->write_function(stream, "l_mngmt=Y|"); - }else { - stream->write_function(stream, "l_mngmt=N|"); - } - - if(sngss7_test_flag(ss7_info, FLAG_CKT_UCIC_BLOCK)) { - stream->write_function(stream, "l_ucic=Y|"); - }else { - stream->write_function(stream, "l_ucic=N|"); - } - - stream->write_function(stream, "flags=0x%X",ss7_info->flags); - - stream->write_function(stream, "\n"); + /* grab the signaling_status */ + ftdm_channel_get_sig_status(ftdmchan, &sigstatus); + + stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|sig_status=%s|state=%s|", + ckt->span, + ckt->chan, + ckt->cic, + ftdm_signaling_status2str(sigstatus), + ftdm_channel_state2str(ftdmchan->state)); + + if((sngss7_test_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX)) || (sngss7_test_flag(ss7_info, FLAG_GRP_MN_BLOCK_TX))) { + stream->write_function(stream, "l_mn=Y|"); + }else { + stream->write_function(stream, "l_mn=N|"); + } + + if((sngss7_test_flag(ss7_info, FLAG_CKT_MN_BLOCK_RX)) || (sngss7_test_flag(ss7_info, FLAG_GRP_MN_BLOCK_RX))) { + stream->write_function(stream, "r_mn=Y|"); + }else { + stream->write_function(stream, "r_mn=N|"); + } + + if(sngss7_test_flag(ss7_info, FLAG_GRP_HW_BLOCK_TX)) { + stream->write_function(stream, "l_hw=Y|"); + }else { + stream->write_function(stream, "l_hw=N|"); + } + + if(sngss7_test_flag(ss7_info, FLAG_GRP_HW_BLOCK_RX)) { + stream->write_function(stream, "r_hw=Y|"); + }else { + stream->write_function(stream, "r_hw=N|"); + } + + if(sngss7_test_flag(ss7_info, FLAG_CKT_LC_BLOCK_RX)) { + stream->write_function(stream, "l_mngmt=Y|"); + }else { + stream->write_function(stream, "l_mngmt=N|"); + } + + if(sngss7_test_flag(ss7_info, FLAG_CKT_UCIC_BLOCK)) { + stream->write_function(stream, "l_ucic=Y|"); + }else { + stream->write_function(stream, "l_ucic=N|"); + } + + stream->write_function(stream, "flags=0x%X",ss7_info->flags); + + stream->write_function(stream, "\n"); + } /* if ( hole, sig, voice) */ } /* if ( span and chan) */ - - } /* if ( cic != 0) */ - /* go the next circuit */ x++; } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */ @@ -1516,6 +1634,193 @@ static ftdm_status_t handle_tx_cgu(ftdm_stream_handle_t *stream, int span, int c return FTDM_SUCCESS; } +/******************************************************************************/ +static ftdm_status_t handle_activate_link(ftdm_stream_handle_t *stream, char *name) +{ + int x = 0; + + /* find the link request by it's name */ + x = 1; + while(g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLink[x].name, name)) { + + /* send the uninhibit request */ + if (ftmod_ss7_activate_mtplink(x)) { + stream->write_function(stream, "Failed to activate link=%s\n", name); + return FTDM_FAIL; + } + + /* print the new status of the link */ + handle_status_link(stream, &name[0]); + goto success; + } + + /* move to the next link */ + x++; + } /* while (id != 0) */ + + stream->write_function(stream, "Could not find link=%s\n", name); + +success: + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static ftdm_status_t handle_deactivate_link(ftdm_stream_handle_t *stream, char *name) +{ + int x = 0; + + /* find the link request by it's name */ + x = 1; + while(g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLink[x].name, name)) { + + /* send the deactivate request */ + if (ftmod_ss7_deactivate2_mtplink(x)) { + stream->write_function(stream, "Failed to deactivate link=%s\n", name); + return FTDM_FAIL; + } + + /* print the new status of the link */ + handle_status_link(stream, &name[0]); + goto success; + } + + /* move to the next link */ + x++; + } /* while (id != 0) */ + + stream->write_function(stream, "Could not find link=%s\n", name); + +success: + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static ftdm_status_t handle_activate_linkset(ftdm_stream_handle_t *stream, char *name) +{ + int x = 0; + + /* find the linkset request by it's name */ + x = 1; + while(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name, name)) { + + /* send the activate request */ + if (ftmod_ss7_activate_mtplinkSet(x)) { + stream->write_function(stream, "Failed to activate linkset=%s\n", name); + return FTDM_FAIL; + } + + /* print the new status of the linkset */ + handle_status_linkset(stream, &name[0]); + goto success; + } + + /* move to the next linkset */ + x++; + } /* while (id != 0) */ + + stream->write_function(stream, "Could not find linkset=%s\n", name); + +success: + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static ftdm_status_t handle_deactivate_linkset(ftdm_stream_handle_t *stream, char *name) +{ + int x = 0; + + /* find the linkset request by it's name */ + x = 1; + while(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name, name)) { + + /* send the deactivate request */ + if (ftmod_ss7_deactivate2_mtplinkSet(x)) { + stream->write_function(stream, "Failed to deactivate linkset=%s\n", name); + return FTDM_FAIL; + } + + /* print the new status of the linkset */ + handle_status_linkset(stream, &name[0]); + goto success; + } + + /* move to the next linkset */ + x++; + } /* while (id != 0) */ + + stream->write_function(stream, "Could not find linkset=%s\n", name); + +success: + return FTDM_SUCCESS; +} + +/******************************************************************************/ + +static ftdm_status_t handle_tx_lpo(ftdm_stream_handle_t *stream, char *name) +{ + int x = 0; + + /* find the link request by it's name */ + x = 1; + while(g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLink[x].name, name)) { + + /* send the uninhibit request */ + if (ftmod_ss7_lpo_mtplink(x)) { + stream->write_function(stream, "Failed set LPO link=%s\n", name); + return FTDM_FAIL; + } + + /* print the new status of the link */ + handle_status_link(stream, &name[0]); + goto success; + } + + /* move to the next link */ + x++; + } /* while (id != 0) */ + + stream->write_function(stream, "Could not find link=%s\n", name); + +success: + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static ftdm_status_t handle_tx_lpr(ftdm_stream_handle_t *stream, char *name) +{ + int x = 0; + + /* find the link request by it's name */ + x = 1; + while(g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLink[x].name, name)) { + + /* send the uninhibit request */ + if (ftmod_ss7_lpr_mtplink(x)) { + stream->write_function(stream, "Failed set LPR link=%s\n", name); + return FTDM_FAIL; + } + + /* print the new status of the link */ + handle_status_link(stream, &name[0]); + goto success; + } + + /* move to the next link */ + x++; + } /* while (id != 0) */ + + stream->write_function(stream, "Could not find link=%s\n", name); + +success: + return FTDM_SUCCESS; +} + /******************************************************************************/ static ftdm_status_t extract_span_chan(char *argv[10], int pos, int *span, int *chan) { diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c index 52b3860375..0d76329d25 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c @@ -50,6 +50,17 @@ static int ftmod_ss7_enable_mtpLinkSet(int lnkSetId); int ftmod_ss7_inhibit_mtplink(uint32_t id); int ftmod_ss7_uninhibit_mtplink(uint32_t id); + +int ftmod_ss7_activate_mtplink(uint32_t id); +int ftmod_ss7_deactivate_mtplink(uint32_t id); +int ftmod_ss7_deactivate2_mtplink(uint32_t id); + +int ftmod_ss7_activate_mtplinkSet(uint32_t id); +int ftmod_ss7_deactivate_mtplinkSet(uint32_t id); +int ftmod_ss7_deactivate2_mtplinkSet(uint32_t id); + +int ftmod_ss7_lpo_mtplink(uint32_t id); +int ftmod_ss7_lpr_mtplink(uint32_t id); /******************************************************************************/ /* FUNCTIONS ******************************************************************/ @@ -271,6 +282,248 @@ int ftmod_ss7_uninhibit_mtplink(uint32_t id) return (sng_cntrl_mtp3(&pst, &cntrl)); } +/******************************************************************************/ +int ftmod_ss7_activate_mtplink(uint32_t id) +{ + SnMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSN; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(SnMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSN; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STDLSAP; + cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLink[id].id; + + cntrl.t.cntrl.action = AENA; /* Activate */ + cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ + + return (sng_cntrl_mtp3(&pst, &cntrl)); +} + +/******************************************************************************/ +int ftmod_ss7_deactivate_mtplink(uint32_t id) +{ + SnMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSN; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(SnMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSN; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STDLSAP; + cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLink[id].id; + + cntrl.t.cntrl.action = ADISIMM; /* Deactivate */ + cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ + + return (sng_cntrl_mtp3(&pst, &cntrl)); +} + +/******************************************************************************/ +int ftmod_ss7_deactivate2_mtplink(uint32_t id) +{ + SnMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSN; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(SnMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSN; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STDLSAP; + cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLink[id].id; + + cntrl.t.cntrl.action = ADISIMM_L2; /* Deactivate...layer 2 only */ + cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ + + return (sng_cntrl_mtp3(&pst, &cntrl)); +} + +/******************************************************************************/ +int ftmod_ss7_activate_mtplinkSet(uint32_t id) +{ + SnMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSN; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(SnMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSN; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STLNKSET; + cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLinkSet[id].id; + + cntrl.t.cntrl.action = AACTLNKSET; /* Activate */ + cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ + + return (sng_cntrl_mtp3(&pst, &cntrl)); +} + +/******************************************************************************/ +int ftmod_ss7_deactivate_mtplinkSet(uint32_t id) +{ + SnMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSN; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(SnMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSN; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STLNKSET; + cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLinkSet[id].id; + + cntrl.t.cntrl.action = ADEACTLNKSET; /* Activate */ + cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ + + return (sng_cntrl_mtp3(&pst, &cntrl)); +} + +/******************************************************************************/ +int ftmod_ss7_deactivate2_mtplinkSet(uint32_t id) +{ + SnMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSN; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(SnMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSN; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STLNKSET; + cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLinkSet[id].id; + + cntrl.t.cntrl.action = ADEACTLNKSET_L2; /* Activate */ + cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ + + return (sng_cntrl_mtp3(&pst, &cntrl)); +} + +/******************************************************************************/ +int ftmod_ss7_lpo_mtplink(uint32_t id) +{ + SnMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSN; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(SnMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSN; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STDLSAP; + cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLink[id].id; + + cntrl.t.cntrl.action = ACTION_LPO; /* Activate */ + cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ + + return (sng_cntrl_mtp3(&pst, &cntrl)); +} + +/******************************************************************************/ +int ftmod_ss7_lpr_mtplink(uint32_t id) +{ + SnMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSN; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(SnMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSN; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STDLSAP; + cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLink[id].id; + + cntrl.t.cntrl.action = ACTION_LPR; /* Activate */ + cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ + + return (sng_cntrl_mtp3(&pst, &cntrl)); +} + +/******************************************************************************/ + /******************************************************************************/ /* For Emacs: * Local Variables: 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 a76b82a99c..5064d48f17 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 @@ -1123,21 +1123,10 @@ ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circui /* lock the channel */ 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); - i++; - SS7_ASSERT; - }; - /* check if the circuit is fully started */ if (ftdm_test_flag(ftdmchan->span, FTDM_SPAN_IN_THREAD)) { /* set the pause flag on the channel */ sngss7_set_flag(sngss7_info, FLAG_INFID_PAUSED); - - /* set the statet o SUSPENDED to bring the sig status down */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); } /* unlock the channel again before we exit */ @@ -1185,14 +1174,6 @@ ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circu /* lock the channel */ 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); - i++; - SS7_ASSERT; - }; - /* only resume if we are paused */ if (sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) { /* set the resume flag on the channel */ @@ -1200,9 +1181,6 @@ ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circu /* clear the paused flag */ sngss7_clear_flag(sngss7_info, FLAG_INFID_PAUSED); - - /* set the statet to SUSPENDED to bring the sig status up */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); } /* unlock the channel again before we exit */ 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 70a1a05440..6fba4e9e0a 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 @@ -347,6 +347,9 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj) /* check if the rx_grs has cleared */ check_if_rx_grs_processed(ftdmspan); } /* if (sngss7_span->rx_grs.range > 0) */ + + /* check each channel on the span to see if there is an un-procressed SUS/RES flag */ + check_for_res_sus_flag(ftdmspan); } /* master while loop */ /* clear the IN_THREAD flag so that we know the thread is done */ @@ -947,31 +950,6 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) SS7_DEBUG_CHAN(ftdmchan,"Current flags: 0x%X\n", sngss7_info->flags); - /**********************************************************************/ - if (sngss7_test_flag (sngss7_info, FLAG_INFID_PAUSED)) { - SS7_DEBUG_CHAN(ftdmchan, "Processing PAUSE flag %s\n", ""); - - /* bring the channel signaling status to down */ - sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sigev.sigstatus = FTDM_SIG_STATE_DOWN; - ftdm_span_send_signal (ftdmchan->span, &sigev); - - /* check the last state and return to it to allow the call to finish */ - goto suspend_goto_last; - } - - if (sngss7_test_flag (sngss7_info, FLAG_INFID_RESUME)) { - SS7_DEBUG_CHAN(ftdmchan, "Processing RESUME flag %s\n", ""); - - /* the reset flag is set for the first channel in the span at handle_resume */ - - /* clear the resume flag */ - sngss7_clear_flag(sngss7_info, FLAG_INFID_RESUME); - - /* go to restart state */ - goto suspend_goto_last; - } - /**********************************************************************/ if (sngss7_test_flag (sngss7_info, FLAG_CKT_MN_BLOCK_RX)) { SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_BLOCK_RX flag %s\n", ""); 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 555c0d97a0..415a897181 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 @@ -454,6 +454,14 @@ int ftmod_ss7_cc_isap_config(int id); int ftmod_ss7_inhibit_mtplink(uint32_t id); int ftmod_ss7_uninhibit_mtplink(uint32_t id); +int ftmod_ss7_activate_mtplink(uint32_t id); +int ftmod_ss7_deactivate_mtplink(uint32_t id); +int ftmod_ss7_deactivate2_mtplink(uint32_t id); +int ftmod_ss7_activate_mtplinkSet(uint32_t id); +int ftmod_ss7_deactivate_mtplinkSet(uint32_t id); +int ftmod_ss7_deactivate2_mtplinkSet(uint32_t id); +int ftmod_ss7_lpo_mtplink(uint32_t id); +int ftmod_ss7_lpr_mtplink(uint32_t id); int ftmod_ss7_mtplink_sta(uint32_t id, SnMngmt *cfm); int ftmod_ss7_mtplinkSet_sta(uint32_t id, SnMngmt *cfm); @@ -539,6 +547,7 @@ 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); +ftdm_status_t check_for_res_sus_flag(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 46bd39f7fb..879fcd239f 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 @@ -204,29 +204,29 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan) memset (&acm, 0x0, sizeof (acm)); /* fill in the needed information for the ACM */ - acm.bckCallInd.eh.pres = PRSNT_NODEF; - acm.bckCallInd.chrgInd.pres = PRSNT_NODEF; - acm.bckCallInd.chrgInd.val = 0x00; - acm.bckCallInd.cadPtyStatInd.pres = PRSNT_NODEF; - acm.bckCallInd.cadPtyStatInd.val = 0x01; - acm.bckCallInd.cadPtyCatInd.pres = PRSNT_NODEF; - acm.bckCallInd.cadPtyCatInd.val = 0x00; - acm.bckCallInd.end2EndMethInd.pres = PRSNT_NODEF; - acm.bckCallInd.end2EndMethInd.val = 0x00; - acm.bckCallInd.intInd.pres = PRSNT_NODEF; - acm.bckCallInd.intInd.val = 0x00; - acm.bckCallInd.end2EndInfoInd.pres = PRSNT_NODEF; - acm.bckCallInd.end2EndInfoInd.val = 0x00; - acm.bckCallInd.isdnUsrPrtInd.pres = PRSNT_NODEF; - acm.bckCallInd.isdnUsrPrtInd.val = 0x0; - acm.bckCallInd.holdInd.pres = PRSNT_NODEF; - acm.bckCallInd.holdInd.val = 0x00; - acm.bckCallInd.isdnAccInd.pres = PRSNT_NODEF; - acm.bckCallInd.isdnAccInd.val = 0x0; - acm.bckCallInd.echoCtrlDevInd.pres = PRSNT_NODEF; - acm.bckCallInd.echoCtrlDevInd.val = 0x0; - acm.bckCallInd.sccpMethInd.pres = PRSNT_NODEF; - acm.bckCallInd.sccpMethInd.val = 0x00; + acm.bckCallInd.eh.pres = PRSNT_NODEF; + acm.bckCallInd.chrgInd.pres = PRSNT_NODEF; + acm.bckCallInd.chrgInd.val = 0x00; + acm.bckCallInd.cadPtyStatInd.pres = PRSNT_NODEF; + acm.bckCallInd.cadPtyStatInd.val = 0x01; + acm.bckCallInd.cadPtyCatInd.pres = PRSNT_NODEF; + acm.bckCallInd.cadPtyCatInd.val = 0x00; + acm.bckCallInd.end2EndMethInd.pres = PRSNT_NODEF; + acm.bckCallInd.end2EndMethInd.val = 0x00; + acm.bckCallInd.intInd.pres = PRSNT_NODEF; + acm.bckCallInd.intInd.val = 0x00; + acm.bckCallInd.end2EndInfoInd.pres = PRSNT_NODEF; + acm.bckCallInd.end2EndInfoInd.val = 0x00; + acm.bckCallInd.isdnUsrPrtInd.pres = PRSNT_NODEF; + acm.bckCallInd.isdnUsrPrtInd.val = 0x0; + acm.bckCallInd.holdInd.pres = PRSNT_NODEF; + acm.bckCallInd.holdInd.val = 0x00; + acm.bckCallInd.isdnAccInd.pres = PRSNT_NODEF; + acm.bckCallInd.isdnAccInd.val = 0x0; + acm.bckCallInd.echoCtrlDevInd.pres = PRSNT_NODEF; + acm.bckCallInd.echoCtrlDevInd.val = 0x1; /* ec device present */ + acm.bckCallInd.sccpMethInd.pres = PRSNT_NODEF; + acm.bckCallInd.sccpMethInd.val = 0x00; /* send the ACM request to LibSngSS7 */ sng_cc_con_status (1, diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c index 305e1a50f5..d238462046 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c @@ -68,7 +68,7 @@ int ftmod_ss7_mtplinkSet_sta(uint32_t id, SnMngmt *cfm) sta.hdr.elmId.elmnt = STLNKSET; sta.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLinkSet[id].id; - sta.hdr.elmId.elmntInst2 = 1; + sta.hdr.elmId.elmntInst2 = g_ftdm_sngss7_data.cfg.mtpLinkSet[id].links[0]; return(sng_sta_mtp3(&sta, cfm)); } 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 161a70d3ed..181b76970e 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 @@ -58,6 +58,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); +ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan); /******************************************************************************/ /* FUNCTIONS ******************************************************************/ @@ -540,6 +541,64 @@ GRS_UNLOCK_ALL: return FTDM_SUCCESS; } +/******************************************************************************/ +ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan) +{ + ftdm_channel_t *ftdmchan = NULL; + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_sigmsg_t sigev; + int x; + + for (x = 1; x < (ftdmspan->chan_count + 1); x++) { + + /* extract the channel structure and sngss7 channel data */ + ftdmchan = ftdmspan->channels[x]; + + /* if the call data is NULL move on */ + if (ftdmchan->call_data == NULL) continue; + + sngss7_info = ftdmchan->call_data; + + /* lock the channel */ + ftdm_mutex_lock(ftdmchan->mutex); + + memset (&sigev, 0, sizeof (sigev)); + + sigev.chan_id = ftdmchan->chan_id; + sigev.span_id = ftdmchan->span_id; + sigev.channel = ftdmchan; + + if ((sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) && + (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP))) { + + /* bring the sig status down */ + sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; + sigev.sigstatus = FTDM_SIG_STATE_DOWN; + ftdm_span_send_signal(ftdmchan->span, &sigev); + } + + if ((sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) && + !(ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP))) { + + /* bring the sig status back up */ + sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; + sigev.sigstatus = FTDM_SIG_STATE_UP; + ftdm_span_send_signal(ftdmchan->span, &sigev); + + sngss7_clear_flag(sngss7_info, FLAG_INFID_RESUME); + } + + /* unlock the channel */ + ftdm_mutex_unlock(ftdmchan->mutex); + + } /* for (x = 1; x < (span->chan_count + 1); x++) */ + + /* signal the core that sig events are queued for processing */ + ftdm_span_trigger_signals(ftdmspan); + + return FTDM_SUCCESS; +} + /******************************************************************************/ 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 cf0bf7caae..bd1be4b6a4 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 @@ -1600,11 +1600,10 @@ static int ftmod_ss7_fill_in_circuits(char *ch_map, int cicbase, int typeCntrl, g_ftdm_sngss7_data.cfg.isupCkt[x].chan = count; if (timeslot.siglink) { g_ftdm_sngss7_data.cfg.isupCkt[x].type = SIG; - } else if (timeslot.hole) { - g_ftdm_sngss7_data.cfg.isupCkt[x].type = HOLE; } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].type = VOICE; + g_ftdm_sngss7_data.cfg.isupCkt[x].type = HOLE; } + if (timeslot.channel) { g_ftdm_sngss7_data.cfg.isupCkt[x].cic = cicbase; cicbase++; @@ -1625,6 +1624,10 @@ static int ftmod_ss7_fill_in_circuits(char *ch_map, int cicbase, int typeCntrl, g_ftdm_sngss7_data.cfg.isupCkt[x].obj = ss7_info; } /* if (g_ftdm_sngss7_data.cfg.isupCkt[x].id == 0) */ + + /* increment the span channel count */ + count++; + } else { /* if ((timeslot.siglink) || (timeslot.gap)) */ /* find the ftdm the channel structure for this channel*/ i = 1; From 5812c5fd53322940c5627703d57dd3d1d22ed6e5 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Wed, 8 Sep 2010 19:41:34 -0400 Subject: [PATCH 20/25] freetdm: Used channel iterator. Removed assert when we cannot find a call on RelInd, it seems like Trillium as a bug where they sometimes send release twice Fixes to some memory leaks Fix for bug in q921 trace disable command Fix for not recognizing etsi switchtype Fix for sending RESTART when we are not supposed to in EUROISDN NETWORK mode Support for l1 stats Fix for deadlocks/segfaults on shutdown Added index per link_id, support for show_spans Added progress-ind when sending CONNECT message Fix for sending CONNECT ACK when configured as TE --- libs/freetdm/mod_freetdm/mod_freetdm.c | 3 +- libs/freetdm/src/ftdm_io.c | 21 ++- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.c | 97 ++++++++++---- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.h | 10 +- .../ftmod_sangoma_isdn_cfg.c | 8 +- .../ftmod_sangoma_isdn_cntrl.c | 19 ++- .../ftmod_sangoma_isdn_stack_cfg.c | 10 +- .../ftmod_sangoma_isdn_stack_cntrl.c | 102 +++++++++----- .../ftmod_sangoma_isdn_stack_hndl.c | 10 ++ .../ftmod_sangoma_isdn_stack_out.c | 10 +- .../ftmod_sangoma_isdn_stack_rcv.c | 124 ++++++++---------- .../ftmod_sangoma_isdn_support.c | 91 ++++++++++++- 12 files changed, 341 insertions(+), 164 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index c70e0f9a65..b4a40f0bad 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -2182,9 +2182,8 @@ static void ftdm_logger(const char *file, const char *func, int line, int level, if (switch_vasprintf(&data, fmt, ap) != -1) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, (char *)func, line, NULL, level, "%s", data); - free(data); } - + if (data) free(data); va_end(ap); } diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 49b61eed69..6991e9ab9b 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -463,6 +463,7 @@ static ftdm_status_t ftdm_span_destroy(ftdm_span_t *span) status = FTDM_FAIL; } ftdm_safe_free(span->type); + ftdm_safe_free(span->name); ftdm_safe_free(span->dtmf_hangup); } @@ -536,7 +537,7 @@ static void ftdm_span_add(ftdm_span_t *span) } else { globals.spans = span; } - hashtable_insert(globals.span_hash, (void *)span->name, span, HASHTABLE_FLAG_NONE); + hashtable_insert(globals.span_hash, (void *)span->name, span, HASHTABLE_FLAG_FREE_VALUE); ftdm_mutex_unlock(globals.span_mutex); } @@ -3550,12 +3551,20 @@ static ftdm_iterator_t *get_iterator(ftdm_iterator_type_t type, ftdm_iterator_t FT_DECLARE(ftdm_iterator_t *) ftdm_channel_get_var_iterator(const ftdm_channel_t *ftdmchan, ftdm_iterator_t *iter) { + ftdm_hash_iterator_t *hashiter = NULL; + ftdm_channel_lock(ftdmchan); + hashiter = ftdmchan->variable_hash == NULL ? NULL : hashtable_first(ftdmchan->variable_hash); + ftdm_channel_unlock(ftdmchan); + + + if (hashiter == NULL) { + return NULL; + } + if (!(iter = get_iterator(FTDM_ITERATOR_VARS, iter))) { return NULL; } - ftdm_channel_lock(ftdmchan); - iter->pvt.hashiter = ftdmchan->variable_hash == NULL ? NULL : hashtable_first(ftdmchan->variable_hash); - ftdm_channel_unlock(ftdmchan); + iter->pvt.hashiter = hashiter; return iter; } @@ -4837,11 +4846,13 @@ FT_DECLARE(ftdm_status_t) ftdm_global_destroy(void) ftdm_mutex_lock(globals.mutex); hashtable_destroy(globals.interface_hash); - hashtable_destroy(globals.module_hash); + hashtable_destroy(globals.module_hash); hashtable_destroy(globals.span_hash); + hashtable_destroy(globals.group_hash); ftdm_mutex_unlock(globals.mutex); ftdm_mutex_destroy(&globals.mutex); ftdm_mutex_destroy(&globals.span_mutex); + ftdm_mutex_destroy(&globals.group_mutex); memset(&globals, 0, sizeof(globals)); return FTDM_SUCCESS; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c index e962eceb28..08f340dc83 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c @@ -472,10 +472,7 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan) case FTDM_CHANNEL_STATE_RING: /* incoming call request */ { ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending incoming call from %s to %s to FTDM core\n", ftdmchan->caller_data.ani.digits, ftdmchan->caller_data.dnis.digits); - ftdm_channel_add_var(ftdmchan, "isdn_specific_var", "1"); - ftdm_channel_add_var(ftdmchan, "isdn_crap", "morecrap"); - ftdm_channel_add_var(ftdmchan, "isdn_stuff", "s"); - ftdm_channel_add_var(ftdmchan, "isdn_d", "asdsadasdasdsad"); + /* we have enough information to inform FTDM of the call*/ sigev.event_id = FTDM_SIGEVENT_START; ftdm_span_send_signal(ftdmchan->span, &sigev); @@ -694,7 +691,7 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(ftdm_sangoma_isdn_outgoing_call) return status; } -static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_get_sig_status) +static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_get_chan_sig_status) { if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) { *status = FTDM_SIG_STATE_UP; @@ -705,17 +702,34 @@ static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_get_sig_status) return FTDM_SUCCESS; } -static FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_set_sig_status) +static FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_set_chan_sig_status) { ftdm_log(FTDM_LOG_ERROR,"Cannot set channel status in this module\n"); return FTDM_NOTIMPL; } +static FIO_SPAN_GET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_get_span_sig_status) +{ + if (ftdm_test_flag(span->channels[1], FTDM_CHANNEL_SIG_UP)) { + *status = FTDM_SIG_STATE_UP; + } else { + *status = FTDM_SIG_STATE_DOWN; + } + + return FTDM_SUCCESS; +} + +static FIO_SPAN_SET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_set_span_sig_status) +{ + ftdm_log(FTDM_LOG_ERROR,"Cannot set span status in this module\n"); + return FTDM_NOTIMPL; +} + static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span) { ftdm_log(FTDM_LOG_INFO,"Starting span %s:%u.\n",span->name,span->span_id); - if (sng_isdn_stack_activate(span) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "Failed to activate span %s\n", span->name); + if (sng_isdn_stack_start(span) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_CRIT, "Failed to start span %s\n", span->name); return FTDM_FAIL; } /* clear the monitor thread stop flag */ @@ -734,7 +748,8 @@ static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span) static ftdm_status_t ftdm_sangoma_isdn_stop(ftdm_span_t *span) { - unsigned i; + ftdm_iterator_t *chaniter = NULL; + ftdm_iterator_t *curr = NULL; ftdm_log(FTDM_LOG_INFO, "Stopping span %s\n", span->name); /* throw the STOP_THREAD flag to signal monitor thread stop */ @@ -746,11 +761,19 @@ static ftdm_status_t ftdm_sangoma_isdn_stop(ftdm_span_t *span) ftdm_sleep(10); } - /* FIXME: deconfigure any links, attached to this span */ - /* TODO: Use Moy's channel Iterator when its implemented */ - for (i=1;i<=span->chan_count;i++) { - ftdm_safe_free(span->channels[i]->call_data); + if (sng_isdn_stack_stop(span) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_CRIT, "Failed to stop span %s\n", span->name); } + + chaniter = ftdm_span_get_chan_iterator(span, NULL); + for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { + ftdm_safe_free(((ftdm_channel_t*)ftdm_iterator_current(curr))->call_data); + ((ftdm_channel_t*)ftdm_iterator_current(curr))->call_data = NULL; + } + ftdm_iterator_free(chaniter); + + ftdm_sched_destroy(&((sngisdn_span_data_t*)span->signal_data)->sched); + ftdm_queue_destroy(&((sngisdn_span_data_t*)span->signal_data)->event_queue); ftdm_safe_free(span->signal_data); ftdm_log(FTDM_LOG_DEBUG, "Finished stopping span %s\n", span->name); @@ -760,6 +783,9 @@ static ftdm_status_t ftdm_sangoma_isdn_stop(ftdm_span_t *span) static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config) { + ftdm_iterator_t *chaniter = NULL; + ftdm_iterator_t *curr = NULL; + sngisdn_span_data_t *span_data; ftdm_log(FTDM_LOG_INFO, "Configuring ftmod_sangoma_isdn span = %s\n", span->name); @@ -767,13 +793,15 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config) span_data = ftdm_calloc(1, sizeof(sngisdn_span_data_t)); span_data->ftdm_span = span; span->signal_data = span_data; - - unsigned i; - for (i=1;i <= span->chan_count; i++) { + + chaniter = ftdm_span_get_chan_iterator(span, NULL); + for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { sngisdn_chan_data_t *chan_data = ftdm_calloc(1, sizeof(sngisdn_chan_data_t)); - chan_data->ftdmchan = span->channels[i]; - span->channels[i]->call_data = chan_data; + chan_data->ftdmchan = ((ftdm_channel_t*)ftdm_iterator_current(curr)); + ((ftdm_channel_t*)ftdm_iterator_current(curr))->call_data = chan_data; + } + ftdm_iterator_free(chaniter); if (ftmod_isdn_parse_cfg(ftdm_parameters, span) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_ERROR, "Failed to parse configuration\n"); @@ -792,8 +820,10 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config) span->outgoing_call = ftdm_sangoma_isdn_outgoing_call; span->channel_request = NULL; span->signal_cb = sig_cb; - span->get_channel_sig_status = ftdm_sangoma_isdn_get_sig_status; - span->set_channel_sig_status = ftdm_sangoma_isdn_set_sig_status; + span->get_channel_sig_status = ftdm_sangoma_isdn_get_chan_sig_status; + span->set_channel_sig_status = ftdm_sangoma_isdn_set_chan_sig_status; + span->get_span_sig_status = ftdm_sangoma_isdn_get_span_sig_status; + span->set_span_sig_status = ftdm_sangoma_isdn_set_span_sig_status; span->state_map = &sangoma_isdn_state_map; ftdm_set_flag(span, FTDM_SPAN_USE_CHAN_QUEUE); ftdm_set_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE); @@ -855,7 +885,7 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_isdn_init) for(i=1;i<=MAX_VARIANTS;i++) { ftdm_mutex_create(&g_sngisdn_data.ccs[i].mutex); } - + /* initalize sng_isdn library */ sng_isdn_init(&g_sngisdn_event_interface); return FTDM_SUCCESS; @@ -923,16 +953,35 @@ static FIO_API_FUNCTION(ftdm_sangoma_isdn_api) if (!strcasecmp(argv[0], "l1_stats")) { ftdm_span_t *span; if (argc < 2) { - ftdm_log(FTDM_LOG_ERROR, "Usage: ftdm sangoma_isdn l1_stats \n"); + stream->write_function(stream, "Usage: ftdm sangoma_isdn l1_stats \n"); status = FTDM_FAIL; goto done; } status = ftdm_span_find_by_name(argv[1], &span); if (FTDM_SUCCESS != status) { - stream->write_function(stream, "-ERR failed to find span by name %s\n", argv[2]); + stream->write_function(stream, "-ERR failed to find span with name %s\n", argv[1]); + /* Return SUCCESS because we do not want to print the general FTDM usage list */ + status = FTDM_SUCCESS; goto done; } - /* TODO: implement PHY stats */ + sngisdn_print_phy_stats(stream, span); + } + + if (!strcasecmp(argv[0], "show_spans")) { + ftdm_span_t *span = NULL; + if (argc == 2) { + status = ftdm_span_find_by_name(argv[1], &span); + if (FTDM_SUCCESS != status) { + stream->write_function(stream, "-ERR failed to find span with name %s\n", argv[1]); + /* Return SUCCESS because we do not want to print the general FTDM usage list */ + status = FTDM_SUCCESS; + goto done; + } + sngisdn_print_span(stream, span); + status = FTDM_SUCCESS; + goto done; + } + sngisdn_print_spans(stream); } if (!strcasecmp(argv[0], "check_ids")) { sngisdn_check_free_ids(); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h index 5f26828529..cd96a18fce 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h @@ -243,7 +243,8 @@ typedef struct ftdm_sngisdn_data { uint8_t num_cc; /* 1 ent per switchtype */ struct sngisdn_cc ccs[MAX_VARIANTS+1]; uint8_t num_dchan; - sngisdn_dchan_data_t dchans[MAX_L1_LINKS+1]; + sngisdn_dchan_data_t dchans[MAX_L1_LINKS+1]; + sngisdn_span_data_t *spans[MAX_L1_LINKS+1]; /* spans are indexed by link_id */ }ftdm_sngisdn_data_t; @@ -363,9 +364,12 @@ void sngisdn_facility_timeout(void* p_sngisdn_info); /* Stack management functions */ ftdm_status_t sng_isdn_stack_cfg(ftdm_span_t *span); -ftdm_status_t sng_isdn_stack_activate(ftdm_span_t *span); - +ftdm_status_t sng_isdn_stack_start(ftdm_span_t *span); +ftdm_status_t sng_isdn_stack_stop(ftdm_span_t *span); +void sngisdn_print_phy_stats(ftdm_stream_handle_t *stream, ftdm_span_t *span); +void sngisdn_print_spans(ftdm_stream_handle_t *stream); +void sngisdn_print_span(ftdm_stream_handle_t *stream, ftdm_span_t *span); #endif /* __FTMOD_SNG_ISDN_H__ */ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c index 96eaf051a2..361b389f96 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c @@ -62,7 +62,8 @@ ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span) } break; case FTDM_TRUNK_E1: - if (!strcasecmp(switch_name, "euroisdn") || strcasecmp(switch_name, "etsi")) { + if (!strcasecmp(switch_name, "euroisdn") || + !strcasecmp(switch_name, "etsi")) { signal_data->switchtype = SNGISDN_SWITCH_EUROISDN; } else if (!strcasecmp(switch_name, "qsig")) { signal_data->switchtype = SNGISDN_SWITCH_QSIG; @@ -116,6 +117,8 @@ ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span) signal_data->span_id = dchan_data->num_spans; dchan_data->spans[signal_data->span_id] = signal_data; + + g_sngisdn_data.spans[signal_data->link_id] = signal_data; ftdm_log(FTDM_LOG_DEBUG, "%s: cc_id:%d dchan_id:%d span_id:%d\n", span->name, signal_data->cc_id, signal_data->dchan_id, signal_data->span_id); @@ -163,6 +166,7 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_ signal_data->overlap_dial = SNGISDN_OPT_DEFAULT; signal_data->setup_arb = SNGISDN_OPT_DEFAULT; + signal_data->link_id = span->span_id; span->default_caller_data.bearer_capability = IN_ITC_SPEECH; /* Cannot set default bearer_layer1 yet, as we do not know the switchtype */ @@ -258,7 +262,7 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_ ftdm_log(FTDM_LOG_WARNING, "Ignoring unknown parameter %s\n", ftdm_parameters[paramindex].var); } } - signal_data->link_id = span->span_id; + if (signal_data->switchtype == SNGISDN_SWITCH_INVALID) { ftdm_log(FTDM_LOG_ERROR, "%s: switchtype not specified", span->name); return FTDM_FAIL; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cntrl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cntrl.c index 7aba6a66ce..5060cb6bba 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cntrl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cntrl.c @@ -35,7 +35,6 @@ #include "ftmod_sangoma_isdn.h" - void sngisdn_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status_t status); void sngisdn_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status_t status) @@ -53,23 +52,21 @@ void sngisdn_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status return; } +void sngisdn_set_span_sig_status(ftdm_span_t *span, ftdm_signaling_status_t status) +{ + ftdm_iterator_t *chaniter = NULL; + ftdm_iterator_t *curr = NULL; -void sngisdn_set_span_sig_status(ftdm_span_t *ftdmspan, ftdm_signaling_status_t status) -{ - unsigned i; - /* TODO: use channel iterator once it is implemented */ - - for (i=1;i<=ftdmspan->chan_count;i++) { - sngisdn_set_chan_sig_status(ftdmspan->channels[i], status); + chaniter = ftdm_span_get_chan_iterator(span, NULL); + for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { + sngisdn_set_chan_sig_status(((ftdm_channel_t*)ftdm_iterator_current(curr)), status); } + ftdm_iterator_free(chaniter); return; } - - - /* For Emacs: * Local Variables: * mode:c diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c index f84e018f1e..942c2e4531 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c @@ -656,8 +656,7 @@ ftdm_status_t sng_isdn_stack_cfg_q931_dlsap(ftdm_span_t *span) cfg.t.cfg.s.inDLSAP.ctldInt[1] = 1; } - cfg.t.cfg.s.inDLSAP.numRstInd = 255; - cfg.t.cfg.s.inDLSAP.ackOpt = TRUE; + cfg.t.cfg.s.inDLSAP.numRstInd = 255; cfg.t.cfg.s.inDLSAP.relOpt = TRUE; #ifdef ISDN_SRV cfg.t.cfg.s.inDLSAP.bcas = FALSE; @@ -666,16 +665,19 @@ ftdm_status_t sng_isdn_stack_cfg_q931_dlsap(ftdm_span_t *span) #endif /* ISDN_SRV */ if (signal_data->signalling == SNGISDN_SIGNALING_NET) { + cfg.t.cfg.s.inDLSAP.ackOpt = TRUE; cfg.t.cfg.s.inDLSAP.intType = NETWORK; cfg.t.cfg.s.inDLSAP.clrGlr = FALSE; /* in case of glare, do not clear local call */ cfg.t.cfg.s.inDLSAP.statEnqOpt = TRUE; - if (span->trunk_type == FTDM_TRUNK_BRI || - span->trunk_type == FTDM_TRUNK_BRI_PTMP) { + + if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN || + signal_data->switchtype == SNGISDN_SWITCH_INSNET) { cfg.t.cfg.s.inDLSAP.rstOpt = FALSE; } else { cfg.t.cfg.s.inDLSAP.rstOpt = TRUE; } } else { + cfg.t.cfg.s.inDLSAP.ackOpt = FALSE; cfg.t.cfg.s.inDLSAP.intType = USER; cfg.t.cfg.s.inDLSAP.clrGlr = TRUE; /* in case of glare, clear local call */ cfg.t.cfg.s.inDLSAP.statEnqOpt = FALSE; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cntrl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cntrl.c index f92eceda5e..cea8ac0173 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cntrl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cntrl.c @@ -38,8 +38,8 @@ void stack_resp_hdr_init(Header *hdr); ftdm_status_t sng_isdn_activate_phy(ftdm_span_t *span); -ftdm_status_t sng_isdn_activate_q921(ftdm_span_t *span); -ftdm_status_t sng_isdn_activate_q931(ftdm_span_t *span); +ftdm_status_t sng_isdn_deactivate_phy(ftdm_span_t *span); + ftdm_status_t sng_isdn_activate_cc(ftdm_span_t *span); ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt); @@ -52,14 +52,23 @@ extern ftdm_sngisdn_data_t g_sngisdn_data; ftdm_status_t sng_isdn_stack_stop(ftdm_span_t *span); -ftdm_status_t sng_isdn_stack_activate(ftdm_span_t *span) +ftdm_status_t sng_isdn_stack_start(ftdm_span_t *span) { sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; - if (sng_isdn_activate_q921(span) != FTDM_SUCCESS) { + + if (sng_isdn_cntrl_q921(span, ABND_ENA, NOTUSED) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_CRIT, "%s:Failed to activate stack q921\n", span->name); return FTDM_FAIL; } + + /* Try to find an alternative for this */ + /* LAPD will call LdUiDatBndCfm before it received a LdLiMacBndCfm from L1, + so we need to give some time before activating q931, as q931 will send a + LdUiDatConReq when activated, and this requires the Mac SAP to be already + bound first */ + ftdm_sleep(500); + ftdm_log(FTDM_LOG_DEBUG, "%s:Stack q921 activated\n", span->name); if (!g_sngisdn_data.ccs[signal_data->cc_id].activation_done) { g_sngisdn_data.ccs[signal_data->cc_id].activation_done = 1; @@ -70,7 +79,8 @@ ftdm_status_t sng_isdn_stack_activate(ftdm_span_t *span) ftdm_log(FTDM_LOG_DEBUG, "%s:Stack CC activated\n", span->name); } - if (sng_isdn_activate_q931(span) != FTDM_SUCCESS) { + + if (sng_isdn_cntrl_q931(span, ABND_ENA, SAELMNT) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_CRIT, "%s:Failed to activate stack q931\n", span->name); return FTDM_FAIL; } @@ -80,50 +90,72 @@ ftdm_status_t sng_isdn_stack_activate(ftdm_span_t *span) return FTDM_SUCCESS; } -ftdm_status_t sng_isdn_stack_stop(ftdm_span_t *span) +ftdm_status_t sng_isdn_stack_stop(ftdm_span_t *span) { + /* Stop L1 first, so we do not receive any more frames */ + if (sng_isdn_deactivate_phy(span) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_CRIT, "%s:Failed to deactivate stack phy\n", span->name); + return FTDM_FAIL; + } + if (sng_isdn_cntrl_q931(span, AUBND_DIS, SAELMNT) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_CRIT, "%s:Failed to deactivate stack q931\n", span->name); + return FTDM_FAIL; + } + + if (sng_isdn_cntrl_q921(span, AUBND_DIS, SAELMNT) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_CRIT, "%s:Failed to deactivate stack q921\n", span->name); + return FTDM_FAIL; + } + + ftdm_log(FTDM_LOG_INFO, "%s:Signalling stopped\n", span->name); return FTDM_SUCCESS; } ftdm_status_t sng_isdn_activate_phy(ftdm_span_t *span) +{ + + /* There is no need to start phy, as it will Q921 will send a activate request to phy when it starts */ + + return FTDM_SUCCESS; +} + +ftdm_status_t sng_isdn_deactivate_phy(ftdm_span_t *span) { L1Mngmt cntrl; - Pst pst; + Pst pst; - ftdm_log(FTDM_LOG_ERROR, "%s:PHY control not implemented\n", span->name); - return FTDM_SUCCESS; - /* TODO: phy cntrl not implemented yet */ + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; - sng_isdn_phy_cntrl(&pst, &cntrl); + /* initalize the post structure */ + stack_pst_init(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTL1; + + /* initalize the control structure */ + memset(&cntrl, 0, sizeof(cntrl)); + + /* initalize the control header */ + stack_hdr_init(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* configuration */ + cntrl.hdr.entId.ent = ENTL1; /* entity */ + cntrl.hdr.entId.inst = S_INST; /* instance */ + cntrl.hdr.elmId.elmnt = STTSAP; /* SAP Specific cntrl */ + + cntrl.t.cntrl.action = AUBND_DIS; + cntrl.t.cntrl.subAction = SAELMNT; + cntrl.t.cntrl.sapId = signal_data->link_id; + + if (sng_isdn_phy_cntrl(&pst, &cntrl)) { + return FTDM_FAIL; + } return FTDM_SUCCESS; } -ftdm_status_t sng_isdn_activate_q921(ftdm_span_t *span) -{ - ftdm_status_t status; - status = sng_isdn_cntrl_q921(span, ABND_ENA, NOTUSED); - - /* Try to find an alternative for this */ - /* LAPD will call LdUiDatBndCfm before it received a LdLiMacBndCfm from L1, - so we need to give some time before activating q931, as q931 will send a - LdUiDatConReq when activated, and this requires the Mac SAP to be already - bound first */ - - if (status == FTDM_SUCCESS) { - ftdm_sleep(500); - } - return status; -} - -ftdm_status_t sng_isdn_activate_q931(ftdm_span_t *span) -{ - /* TODO: remove this function later, just call sng_isdn_cntrl_q931 directly */ - return sng_isdn_cntrl_q931(span, ABND_ENA, SAELMNT); -} - ftdm_status_t sng_isdn_activate_cc(ftdm_span_t *span) { CcMngmt cntrl;; @@ -167,7 +199,7 @@ ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t tra ftdm_log(FTDM_LOG_INFO, "s%d Disabling q921 trace\n", signal_data->link_id); sngisdn_clear_trace_flag(signal_data, SNGISDN_TRACE_Q921); - if (sng_isdn_cntrl_q921(span, ADISIMM, SAELMNT) != FTDM_SUCCESS) { + if (sng_isdn_cntrl_q921(span, ADISIMM, SATRC) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_ERROR, "s%d Failed to disable q921 trace\n"); } } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c index ff9a53b294..e2e67eed19 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c @@ -106,6 +106,13 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) break; } +#if 0 + /* Export ftdmchan variables here if we need to */ + ftdm_channel_add_var(ftdmchan, "isdn_specific_var", "1"); + ftdm_channel_add_var(ftdmchan, "isdn_crap", "morecrap"); + ftdm_channel_add_var(ftdmchan, "isdn_stuff", "s"); + ftdm_channel_add_var(ftdmchan, "isdn_d", "asdsadasdasdsad"); +#endif /* Fill in call information */ cpy_calling_num_from_stack(&ftdmchan->caller_data, &conEvnt->cgPtyNmb); cpy_called_num_from_stack(&ftdmchan->caller_data, &conEvnt->cdPtyNmb); @@ -267,6 +274,9 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event) /* This is the only valid state we should get a CONNECT ACK on */ /* do nothing */ break; + case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: + /* We just hung up an incoming call right after we sent a CONNECT so ignore this message */ + break; default: ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing CONNECT/CONNECT ACK in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state)); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c index 6e8e0e81fd..80a85ceec8 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c @@ -409,7 +409,7 @@ void sngisdn_snd_connect(ftdm_channel_t *ftdmchan) sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) { + if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) { ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending CONNECT, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId); sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT); ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); @@ -450,6 +450,14 @@ void sngisdn_snd_connect(ftdm_channel_t *ftdmchan) cnStEvnt.chanId.chanNmbSlotMap.len = 1; cnStEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id; } + + cnStEvnt.progInd.eh.pres = PRSNT_NODEF; + cnStEvnt.progInd.location.pres = PRSNT_NODEF; + cnStEvnt.progInd.location.val = IN_LOC_USER; + cnStEvnt.progInd.codeStand0.pres = PRSNT_NODEF; + cnStEvnt.progInd.codeStand0.val = IN_CSTD_CCITT; + cnStEvnt.progInd.progDesc.pres = PRSNT_NODEF; + cnStEvnt.progInd.progDesc.val = IN_PD_NOTETEISDN; /* Not end-to-end ISDN */ ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending CONNECT (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); if (sng_isdn_con_response(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, signal_data->dchan_id, sngisdn_info->ces)) { diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c index f921b1be8c..791c6b7d8c 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c @@ -239,7 +239,8 @@ void sngisdn_rcv_rel_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Re !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId); - ftdm_assert(0, "Inconsistent call states\n"); + /* It seems that Trillium has a bug where they sometimes send release twice on a call, so do not crash on these for now */ + /* ftdm_assert(0, "Inconsistent call states\n"); */ return; } @@ -591,6 +592,7 @@ void sngisdn_rcv_rst_ind (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces /* Enqueue the event to each span within the dChan */ for(i=1; i<=g_sngisdn_data.dchans[dChan].num_spans; i++) { signal_data = g_sngisdn_data.dchans[dChan].spans[i]; + sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); @@ -640,30 +642,24 @@ void sngisdn_rcv_rst_cfm (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces void sngisdn_rcv_phy_ind(SuId suId, Reason reason) { - ISDN_FUNC_TRACE_ENTER(__FUNCTION__); if (reason != LL1_REASON_CON_REQ_FAIL) { ftdm_log(FTDM_LOG_INFO, "[SNGISDN PHY] D-chan %d : %s\n", suId, DECODE_LL1_REASON(reason)); } - ISDN_FUNC_TRACE_EXIT(__FUNCTION__); return; } void sngisdn_rcv_q921_ind(BdMngmt *status) -{ - ISDN_FUNC_TRACE_ENTER(__FUNCTION__); - - unsigned j,k; - ftdm_span_t *ftdmspan = NULL; - - for(j=1;j<=g_sngisdn_data.num_dchan;j++) { - for(k=1;k<=g_sngisdn_data.dchans[j].num_spans;k++) { - if (g_sngisdn_data.dchans[j].spans[k]->link_id == status->t.usta.lnkNmb) { - ftdmspan = (ftdm_span_t*)g_sngisdn_data.dchans[j].spans[k]->ftdm_span; - } - } +{ + ftdm_span_t *ftdmspan; + sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[status->t.usta.lnkNmb]; + if (!signal_data) { + ftdm_log(FTDM_LOG_INFO, "Received q921 status on unconfigured span (lnkNmb:%d)\n", status->t.usta.lnkNmb); + return; } - if (ftdmspan == NULL) { - ftdm_log(FTDM_LOG_WARNING, "Received q921 status on unconfigured span (lnkNmb:%d)\n", status->t.usta.lnkNmb); + ftdmspan = signal_data->ftdm_span; + + if (!ftdmspan) { + ftdm_log(FTDM_LOG_INFO, "Received q921 status on unconfigured span (lnkNmb:%d)\n", status->t.usta.lnkNmb); return; } @@ -694,69 +690,56 @@ void sngisdn_rcv_q921_ind(BdMngmt *status) } break; } - - ISDN_FUNC_TRACE_EXIT(__FUNCTION__) return; } void sngisdn_rcv_q931_ind(InMngmt *status) -{ - ISDN_FUNC_TRACE_ENTER(__FUNCTION__); - ftdm_span_t *ftdmspan = NULL; - +{ if (status->t.usta.alarm.cause == 287) { get_memory_info(); return; } - switch (status->t.usta.alarm.category) { - case (LCM_CATEGORY_INTERFACE): - ftdm_log(FTDM_LOG_WARNING, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n", - status->t.usta.suId, - DECODE_LCM_CATEGORY(status->t.usta.alarm.category), - DECODE_LCM_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event, - DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause); - - /* clean this up later */ - - switch (status->t.usta.alarm.event) { - case LCM_EVENT_UP: - case LCM_EVENT_DOWN: - { - unsigned j,k; - for(j=1;j<=g_sngisdn_data.num_dchan;j++) { - for(k=1;k<=g_sngisdn_data.dchans[j].num_spans;k++) { - if (g_sngisdn_data.dchans[j].spans[k]->link_id == status->t.usta.suId) { - ftdmspan = (ftdm_span_t*)g_sngisdn_data.dchans[j].spans[k]->ftdm_span; - } - } - } - - if (ftdmspan == NULL) { - ftdm_log(FTDM_LOG_CRIT, "Received q931 LCM EVENT on unconfigured span (suId:%u)\n", status->t.usta.suId); - return; - } - - if (status->t.usta.alarm.event == LCM_EVENT_UP) { - sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_UP); - sng_isdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_UP); - } else { - sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_DOWN); - sng_isdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_PWR_SAVING); - } - } - break; + switch (status->t.usta.alarm.event) { + case LCM_EVENT_UP: + case LCM_EVENT_DOWN: + { + ftdm_span_t *ftdmspan; + sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[status->t.usta.suId]; + if (!signal_data) { + ftdm_log(FTDM_LOG_INFO, "Received q921 status on unconfigured span (lnkNmb:%d)\n", status->t.usta.suId); + return; } - break; + ftdmspan = signal_data->ftdm_span; + + if (status->t.usta.alarm.event == LCM_EVENT_UP) { + ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n", + status->t.usta.suId, + DECODE_LCM_CATEGORY(status->t.usta.alarm.category), + DECODE_LCM_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event, + DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause); + + sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_UP); + sng_isdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_UP); + } else { + ftdm_log(FTDM_LOG_WARNING, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n", + status->t.usta.suId, + DECODE_LCM_CATEGORY(status->t.usta.alarm.category), + DECODE_LCM_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event, + DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause); + + sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_DOWN); + sng_isdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_PWR_SAVING); + } + } + break; default: - ftdm_log(FTDM_LOG_DEBUG, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n", - status->t.usta.suId, - DECODE_LCM_CATEGORY(status->t.usta.alarm.category), - DECODE_LCM_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event, - DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause); - break; + ftdm_log(FTDM_LOG_WARNING, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n", + status->t.usta.suId, + DECODE_LCM_CATEGORY(status->t.usta.alarm.category), + DECODE_LCM_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event, + DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause); } - - + ISDN_FUNC_TRACE_EXIT(__FUNCTION__); return; } @@ -902,12 +885,13 @@ void sngisdn_rcv_sng_log(uint8_t level, char *fmt,...) break; case SNG_LOGLEVEL_CRIT: ftdm_log(FTDM_LOG_CRIT, "sng_isdn->%s", data); - /*ftdm_assert(0, "Got an error from stack");*/ + /* ftdm_assert(0, "Got an error from stack"); */ break; default: ftdm_log(FTDM_LOG_INFO, "sng_isdn->%s", data); break; } + ftdm_safe_free(data); return; } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c index 5e37e0c684..db22fe5ce8 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c @@ -134,16 +134,22 @@ ftdm_status_t __inline__ get_ftdmchan_by_spInstId(uint8_t cc_id, uint32_t spInst return FTDM_SUCCESS; } -ftdm_status_t sng_isdn_set_avail_rate(ftdm_span_t *ftdmspan, sngisdn_avail_t avail) +ftdm_status_t sng_isdn_set_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail) { - unsigned i; - if (ftdmspan->trunk_type == FTDM_TRUNK_BRI || - ftdmspan->trunk_type == FTDM_TRUNK_BRI_PTMP) { + + if (span->trunk_type == FTDM_TRUNK_BRI || + span->trunk_type == FTDM_TRUNK_BRI_PTMP) { - for(i=1; i<=ftdmspan->chan_count; i++) { - ftdm_log_chan(ftdmspan->channels[i], FTDM_LOG_DEBUG, "Setting availability rate to:%d\n", avail); - ftdmspan->channels[i]->availability_rate = avail; + ftdm_iterator_t *chaniter = NULL; + ftdm_iterator_t *curr = NULL; + + + chaniter = ftdm_span_get_chan_iterator(span, NULL); + for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { + ftdm_log_chan(((ftdm_channel_t*)ftdm_iterator_current(curr)), FTDM_LOG_DEBUG, "Setting availability rate to:%d\n", avail); + ((ftdm_channel_t*)ftdm_iterator_current(curr))->availability_rate = avail; } + ftdm_iterator_free(chaniter); } return FTDM_SUCCESS; } @@ -554,6 +560,77 @@ ftdm_user_layer1_prot_t sngisdn_get_usrInfoLyr1Prot_from_user(uint8_t layer1_pro return FTDM_USER_LAYER1_PROT_ULAW; } +void sngisdn_print_phy_stats(ftdm_stream_handle_t *stream, ftdm_span_t *span) +{ + L1Mngmt sts; + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; + + memset(&sts, 0, sizeof(sts)); + sng_isdn_phy_stats(signal_data->link_id , &sts); + + stream->write_function(stream, "\n---------------------------------------------------------------------\n"); + stream->write_function(stream, " Span:%s", span->name); + stream->write_function(stream, "\n---------------------------------------------------------------------\n"); + stream->write_function(stream, " Performance Counters"); + stream->write_function(stream, "\n---------------------------------------------------------------------\n"); + stream->write_function(stream, "RX Packets:\t%u\tTX Packets:\t%u\tEvents:%u\n", sts.t.sts.rx_packets, sts.t.sts.tx_packets, sts.t.sts.rx_events); + stream->write_function(stream, "RX Bytes:\t%u\tTX Bytes:\t%u\n\n", sts.t.sts.rx_bytes, sts.t.sts.tx_bytes); + stream->write_function(stream, "TX Queue:\t%u/%u\tRX Queue:\t%u/%u\tEvents Queue:\t%u/%u\n", + sts.t.sts.num_frames_in_tx_queue,sts.t.sts.tx_queue_len, + sts.t.sts.num_frames_in_rx_queue, sts.t.sts.rx_queue_len, + sts.t.sts.rx_events_in_queue, sts.t.sts.event_queue_len); + + stream->write_function(stream, "\n---------------------------------------------------------------------\n"); + stream->write_function(stream, " Errors"); + stream->write_function(stream, "\n---------------------------------------------------------------------\n"); + stream->write_function(stream, "RX Errors:\t%u\tTX Errors:\t%u\n", sts.t.sts.rx_errors, sts.t.sts.tx_errors); + stream->write_function(stream, "RX Dropped:\t%u\tTX Dropped:\t%u\tEvents Dropped:\t%u\n", sts.t.sts.rx_dropped, sts.t.sts.tx_dropped,sts.t.sts.rx_events_dropped); + + + stream->write_function(stream, "\n---------------------------------------------------------------------\n"); + stream->write_function(stream, " RX Errors Details"); + stream->write_function(stream, "\n---------------------------------------------------------------------\n"); + stream->write_function(stream, "CRC:\t\t%u\tFrame:\t\t%u\tOverruns:\t%u\n", sts.t.sts.rx_crc_errors, sts.t.sts.rx_frame_errors, sts.t.sts.rx_over_errors); + stream->write_function(stream, "Fifo:\t\t%u\tAborts:\t\t%u\tMissed:\t\t%u\n", sts.t.sts.rx_fifo_errors, sts.t.sts.rx_hdlc_abort_counter, sts.t.sts.rx_missed_errors); + stream->write_function(stream, "Length:\t\t%u\n", sts.t.sts.rx_length_errors); + + stream->write_function(stream, "\n---------------------------------------------------------------------\n"); + stream->write_function(stream, " TX Errors Details"); + stream->write_function(stream, "\n---------------------------------------------------------------------\n"); + stream->write_function(stream, "Aborted:\t%u\tFifo:\t\t%u\tCarrier:\t%u\n", sts.t.sts.tx_aborted_errors, sts.t.sts.tx_fifo_errors, sts.t.sts.tx_carrier_errors); + return; +} + + +void sngisdn_print_span(ftdm_stream_handle_t *stream, ftdm_span_t *span) +{ + ftdm_signaling_status_t sigstatus; + ftdm_alarm_flag_t alarmbits; + ftdm_channel_t *fchan; + alarmbits = FTDM_ALARM_NONE; + fchan = ftdm_span_get_channel(span, 1); + if (fchan) { + ftdm_channel_get_alarms(fchan, &alarmbits); + } + + ftdm_span_get_sig_status(span, &sigstatus); + stream->write_function(stream, "span:%s physical:%s signalling:%s\n", + span->name, alarmbits ? "ALARMED" : "OK", + ftdm_signaling_status2str(sigstatus)); + return; +} + +void sngisdn_print_spans(ftdm_stream_handle_t *stream) +{ + int i; + for(i=1;i<=MAX_L1_LINKS;i++) { + if (g_sngisdn_data.spans[i]) { + sngisdn_print_span(stream, g_sngisdn_data.spans[i]->ftdm_span); + } + } + return; +} + /* For Emacs: * Local Variables: * mode:c From 0ee84ea57b9dc9609d20d72e2b92972bd56ee331 Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Tue, 14 Sep 2010 11:14:15 -0400 Subject: [PATCH 21/25] freetdm: ss7 - added support for NADI value in sip x-headers --- .../ftmod_sangoma_ss7_handle.c | 6 +++++- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c | 17 ++++++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) 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 5064d48f17..263b599ddc 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 @@ -82,6 +82,9 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ sngss7_chan_data_t *sngss7_info = NULL; ftdm_channel_t *ftdmchan = NULL; + char nadi[2]; + + memset(nadi, '\0', sizeof(nadi)); /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { @@ -212,7 +215,8 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ } /* add any special variables for the dialplan */ - /*ftdm_channel_add_var(ftdmchan, "ss7_stuff", "s");*/ + sprintf(nadi, "%d", siConEvnt->cgPtyNum.natAddrInd.val); + ftdm_channel_add_var(ftdmchan, "ss7_nadi", nadi); /* set the state of the channel to collecting...the rest is done by the chan monitor */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_COLLECT); 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 879fcd239f..311d87c7e2 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 @@ -73,8 +73,9 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) { SS7_FUNC_TRACE_ENTER (__FUNCTION__); - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;; - SiConEvnt iam; + sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;; + const char *nadi = NULL; + SiConEvnt iam; sngss7_info->suInstId = get_unique_id (); sngss7_info->spInstId = 0; @@ -179,7 +180,17 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) /* copy down the calling number information */ copy_cgPtyNum_to_sngss7 (&ftdmchan->caller_data, &iam.cgPtyNum); - + + /* check if the user would like a custom NADI value for the calling Pty Num */ + nadi = ftdm_channel_get_var(ftdmchan, "ss7_nadi"); + if ((nadi != NULL) && (nadi != "")) { + SS7_DEBUG_CHAN(ftdmchan,"Found user supplied NADI value \"%s\"\n", nadi); + iam.cgPtyNum.natAddrInd.val = atoi(nadi); + } else { + SS7_DEBUG_CHAN(ftdmchan,"No user supplied NADI value found, using \"3\" %s\n", " "); + iam.cgPtyNum.natAddrInd.val = 0x03; + } + sng_cc_con_request (sngss7_info->spId, sngss7_info->suInstId, sngss7_info->spInstId, From 134b78c1038c8968f10a0e7bed97e73f7fd85699 Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Wed, 15 Sep 2010 15:06:51 -0400 Subject: [PATCH 22/25] freetdm: ss7 - updates to outgoing IAM and ACM --- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c | 31 +-- .../ftmod_sangoma_ss7_support.c | 207 +++++++++--------- 2 files changed, 116 insertions(+), 122 deletions(-) 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 311d87c7e2..72da36fdcb 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 @@ -103,11 +103,11 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) iam.fwdCallInd.end2EndInfoInd.pres = PRSNT_NODEF; iam.fwdCallInd.end2EndInfoInd.val = E2EINF_NOINFO; iam.fwdCallInd.isdnUsrPrtInd.pres = PRSNT_NODEF; - iam.fwdCallInd.isdnUsrPrtInd.val = ISUP_USED; + iam.fwdCallInd.isdnUsrPrtInd.val = ISUP_NOTUSED; iam.fwdCallInd.isdnUsrPrtPrfInd.pres = PRSNT_NODEF; - iam.fwdCallInd.isdnUsrPrtPrfInd.val = PREF_REQAW; + iam.fwdCallInd.isdnUsrPrtPrfInd.val = PREF_PREFAW; iam.fwdCallInd.isdnAccInd.pres = PRSNT_NODEF; - iam.fwdCallInd.isdnAccInd.val = ISDNACC_ISDN; + iam.fwdCallInd.isdnAccInd.val = ISDNACC_NONISDN; iam.fwdCallInd.sccpMethInd.pres = PRSNT_NODEF; iam.fwdCallInd.sccpMethInd.val = SCCPMTH_NOIND; @@ -179,11 +179,12 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) copy_cdPtyNum_to_sngss7 (&ftdmchan->caller_data, &iam.cdPtyNum); /* copy down the calling number information */ + copy_cgPtyNum_to_sngss7 (&ftdmchan->caller_data, &iam.cgPtyNum); /* check if the user would like a custom NADI value for the calling Pty Num */ nadi = ftdm_channel_get_var(ftdmchan, "ss7_nadi"); - if ((nadi != NULL) && (nadi != "")) { + if ((nadi != NULL) && (*nadi)) { SS7_DEBUG_CHAN(ftdmchan,"Found user supplied NADI value \"%s\"\n", nadi); iam.cgPtyNum.natAddrInd.val = atoi(nadi); } else { @@ -198,7 +199,9 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) &iam, 0); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx IAM\n"); + SS7_INFO_CHAN(ftdmchan,"Tx IAM clg = \"%s\", cld = \"%s\"\n", + ftdmchan->caller_data.cid_num.digits, + ftdmchan->caller_data.dnis.digits); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; @@ -217,27 +220,27 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan) /* fill in the needed information for the ACM */ acm.bckCallInd.eh.pres = PRSNT_NODEF; acm.bckCallInd.chrgInd.pres = PRSNT_NODEF; - acm.bckCallInd.chrgInd.val = 0x00; + acm.bckCallInd.chrgInd.val = CHRG_CHRG; acm.bckCallInd.cadPtyStatInd.pres = PRSNT_NODEF; acm.bckCallInd.cadPtyStatInd.val = 0x01; acm.bckCallInd.cadPtyCatInd.pres = PRSNT_NODEF; - acm.bckCallInd.cadPtyCatInd.val = 0x00; + acm.bckCallInd.cadPtyCatInd.val = CADCAT_ORDSUBS; acm.bckCallInd.end2EndMethInd.pres = PRSNT_NODEF; - acm.bckCallInd.end2EndMethInd.val = 0x00; + acm.bckCallInd.end2EndMethInd.val = E2EMTH_NOMETH; acm.bckCallInd.intInd.pres = PRSNT_NODEF; - acm.bckCallInd.intInd.val = 0x00; + acm.bckCallInd.intInd.val = INTIND_NOINTW; acm.bckCallInd.end2EndInfoInd.pres = PRSNT_NODEF; - acm.bckCallInd.end2EndInfoInd.val = 0x00; + acm.bckCallInd.end2EndInfoInd.val = E2EINF_NOINFO; acm.bckCallInd.isdnUsrPrtInd.pres = PRSNT_NODEF; - acm.bckCallInd.isdnUsrPrtInd.val = 0x0; + acm.bckCallInd.isdnUsrPrtInd.val = ISUP_USED; acm.bckCallInd.holdInd.pres = PRSNT_NODEF; - acm.bckCallInd.holdInd.val = 0x00; + acm.bckCallInd.holdInd.val = HOLD_NOTREQD; acm.bckCallInd.isdnAccInd.pres = PRSNT_NODEF; - acm.bckCallInd.isdnAccInd.val = 0x0; + acm.bckCallInd.isdnAccInd.val = ISDNACC_NONISDN; acm.bckCallInd.echoCtrlDevInd.pres = PRSNT_NODEF; acm.bckCallInd.echoCtrlDevInd.val = 0x1; /* ec device present */ acm.bckCallInd.sccpMethInd.pres = PRSNT_NODEF; - acm.bckCallInd.sccpMethInd.val = 0x00; + acm.bckCallInd.sccpMethInd.val = SCCPMTH_NOIND; /* send the ACM request to LibSngSS7 */ sng_cc_con_status (1, 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 181b76970e..1e8e54a5ee 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 @@ -74,9 +74,10 @@ uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum) int k; int j; int flag; + int odd; char tmp[2]; - unsigned char lower; - unsigned char upper; + uint8_t lower; + uint8_t upper; /**************************************************************************/ cgPtyNum->eh.pres = PRSNT_NODEF; @@ -106,81 +107,73 @@ uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum) k = 0; j = 0; flag = 0; + odd = 0; + upper = 0x0; + lower = 0x0; while (1) { + /* grab a digit from the ftdm digits */ tmp[0] = ftdm->cid_num.digits[k]; + /* check if the digit is a number and that is not null */ + while (!(isdigit(tmp[0])) && (tmp[0] != '\0')) { + /* move on to the next value */ + k++; + tmp[0] = ftdm->cid_num.digits[k]; + } /* while(!(isdigit(tmp))) */ + + /* check if tmp is null or a digit */ if (tmp[0] != '\0') { - if (isdigit(tmp[0])) { - lower = atoi(&tmp[0]); + /* push it into the lower nibble */ + lower = atoi(&tmp[0]); + /* move to the next digit */ + k++; + /* grab a digit from the ftdm digits */ + tmp[0] = ftdm->cid_num.digits[k]; + + /* check if the digit is a number and that is not null */ + while (!(isdigit(tmp[0])) && (tmp[0] != '\0')) { k++; tmp[0] = ftdm->cid_num.digits[k]; - } else { - while (!(isdigit(tmp[0])) && (tmp[0] != '\0')) { - k++; - tmp[0] = ftdm->cid_num.digits[k]; - } /* while(!(isdigit(tmp))) */ + } /* while(!(isdigit(tmp))) */ - if (tmp[0] != '\0') { - lower = atoi(&tmp[0]); - k++; - tmp[0] = ftdm->cid_num.digits[k]; - } else { - flag = 1; - lower = 0xf; - } /* if (tmp != '\0') */ - } /* (isdigit(tmp)) */ - } else { - flag = 1; - lower = 0xf; - } /* if (tmp != '\0') */ - - tmp[0] = ftdm->cid_num.digits[k]; - - if (tmp[0] != '\0') { - if (isdigit(tmp[0])) { + /* check if tmp is null or a digit */ + if (tmp[0] != '\0') { + /* push the digit into the upper nibble */ upper = (atoi(&tmp[0])) << 4; } else { - while (!(isdigit(tmp[0])) && (tmp[0] != '\0')) { - k++; - tmp[0] = ftdm->cid_num.digits[k]; - } /* while(!(isdigit(tmp))) */ - - if (tmp[0] != '\0') { - upper = (atoi(&tmp[0])) << 4; - k++; - } else { - flag = 1; - upper = 0xf; - } /* if (tmp != '\0') */ - } /* if (isdigit(tmp)) */ - } else { - if (flag == 1) { + /* there is no upper ... fill in 0 */ upper = 0x0; - } else { + /* throw the odd flag */ + odd = 1; + /* throw the end flag */ flag = 1; - upper = 0xf; - } /* if (flag == 1) */ - } /* if (tmp != '\0') */ + } /* if (tmp != '\0') */ + } else { + /* keep the odd flag down */ + odd = 0; + /* throw the flag */ + flag = 1; + } + /* push the digits into the trillium structure */ cgPtyNum->addrSig.val[j] = upper | lower; + /* increment the trillium pointer */ j++; - if (flag) { - break; - } else { - k++; - } + /* if the flag is up we're through all the digits */ + if (flag) break; + + /* move to the next digit */ + k++; } /* while(1) */ cgPtyNum->addrSig.len = j; /**************************************************************************/ cgPtyNum->oddEven.pres = PRSNT_NODEF; - - cgPtyNum->oddEven.val = ((cgPtyNum->addrSig.val[j] >> 4) == 0x0 ) ? 0x01 : 0x00; - + cgPtyNum->oddEven.val = odd; /**************************************************************************/ return 0; } @@ -198,9 +191,10 @@ uint8_t copy_cdPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum) int k; int j; int flag; + int odd; char tmp[2]; - unsigned char lower; - unsigned char upper; + uint8_t lower; + uint8_t upper; /**************************************************************************/ cdPtyNum->eh.pres = PRSNT_NODEF; @@ -219,77 +213,74 @@ uint8_t copy_cdPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum) /* atoi will search through memory starting from the pointer it is given until * it finds the \0...since tmp is on the stack it will start going through the * possibly causing corruption. Hard code a \0 to prevent this - */ + */ /* dnis */ tmp[1] = '\0'; k = 0; j = 0; flag = 0; + odd = 0; + upper = 0x0; + lower = 0x0; while (1) { + /* grab a digit from the ftdm digits */ tmp[0] = ftdm->dnis.digits[k]; + /* check if the digit is a number and that is not null */ + while (!(isdigit(tmp[0])) && (tmp[0] != '\0')) { + /* move on to the next value */ + k++; + tmp[0] = ftdm->dnis.digits[k]; + } /* while(!(isdigit(tmp))) */ + + /* check if tmp is null or a digit */ if (tmp[0] != '\0') { - if (isdigit(tmp[0])) { - lower = atoi(&tmp[0]); + /* push it into the lower nibble */ + lower = atoi(&tmp[0]); + /* move to the next digit */ + k++; + /* grab a digit from the ftdm digits */ + tmp[0] = ftdm->dnis.digits[k]; + + /* check if the digit is a number and that is not null */ + while (!(isdigit(tmp[0])) && (tmp[0] != '\0')) { k++; tmp[0] = ftdm->dnis.digits[k]; - } else { - while (!(isdigit(tmp[0])) && (tmp[0] != '\0')) { - k++; - tmp[0] = ftdm->dnis.digits[k]; - } /* while(!(isdigit(tmp))) */ + } /* while(!(isdigit(tmp))) */ - if (tmp[0] != '\0') { - lower = atoi(&tmp[0]); - k++; - tmp[0] = ftdm->dnis.digits[k]; - } else { - flag = 1; - lower = 0xf; - } /* if (tmp != '\0') */ - } /* (isdigit(tmp)) */ - } else { - flag = 1; - lower = 0xf; - } /* if (tmp != '\0') */ - - tmp[0] = ftdm->dnis.digits[k]; - - if (tmp[0] != '\0') { - if (isdigit(tmp[0])) { + /* check if tmp is null or a digit */ + if (tmp[0] != '\0') { + /* push the digit into the upper nibble */ upper = (atoi(&tmp[0])) << 4; } else { - while (!(isdigit(tmp[0])) && (tmp[0] != '\0')) { - k++; - tmp[0] = ftdm->dnis.digits[k]; - } /* while(!(isdigit(tmp))) */ - - if (tmp[0] != '\0') { - upper = (atoi(&tmp[0])) << 4; - k++; - } else { - flag = 1; - upper = 0xf; - } /* if (tmp != '\0') */ - } /* if (isdigit(tmp)) */ - } else { - if (flag == 1) { - upper = 0x0; - } else { + /* there is no upper ... fill in ST */ + upper = 0xF; + /* throw the odd flag */ + odd = 1; + /* throw the end flag */ flag = 1; - upper = 0xf; - } /* if (flag == 1) */ - } /* if (tmp != '\0') */ + } /* if (tmp != '\0') */ + } else { + /* keep the odd flag down */ + odd = 1; + /* need to add the ST */ + lower = 0xF; + upper = 0x0; + /* throw the flag */ + flag = 1; + } + /* push the digits into the trillium structure */ cdPtyNum->addrSig.val[j] = upper | lower; + /* increment the trillium pointer */ j++; - if (flag) { - break; - } else { - k++; - } + /* if the flag is up we're through all the digits */ + if (flag) break; + + /* move to the next digit */ + k++; } /* while(1) */ cdPtyNum->addrSig.len = j; @@ -297,7 +288,7 @@ uint8_t copy_cdPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum) /**************************************************************************/ cdPtyNum->oddEven.pres = PRSNT_NODEF; - cdPtyNum->oddEven.val = ((cdPtyNum->addrSig.val[j] >> 4) == 0x0 ) ? 0x01 : 0x00; + cdPtyNum->oddEven.val = odd; /**************************************************************************/ return 0; From 401b23549ef108acc18e1d417ea74ad6d1665d05 Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Thu, 16 Sep 2010 11:55:26 -0400 Subject: [PATCH 23/25] freetdm: ss7 - updated outgoing IAM --- .../src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 72da36fdcb..34abd265a6 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 @@ -103,11 +103,11 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) iam.fwdCallInd.end2EndInfoInd.pres = PRSNT_NODEF; iam.fwdCallInd.end2EndInfoInd.val = E2EINF_NOINFO; iam.fwdCallInd.isdnUsrPrtInd.pres = PRSNT_NODEF; - iam.fwdCallInd.isdnUsrPrtInd.val = ISUP_NOTUSED; + iam.fwdCallInd.isdnUsrPrtInd.val = ISUP_USED; iam.fwdCallInd.isdnUsrPrtPrfInd.pres = PRSNT_NODEF; iam.fwdCallInd.isdnUsrPrtPrfInd.val = PREF_PREFAW; iam.fwdCallInd.isdnAccInd.pres = PRSNT_NODEF; - iam.fwdCallInd.isdnAccInd.val = ISDNACC_NONISDN; + iam.fwdCallInd.isdnAccInd.val = ISDNACC_ISDN; iam.fwdCallInd.sccpMethInd.pres = PRSNT_NODEF; iam.fwdCallInd.sccpMethInd.val = SCCPMTH_NOIND; From a045519f6b07186b9d4c524d2bdad827b189f02c Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Thu, 16 Sep 2010 16:50:36 -0400 Subject: [PATCH 24/25] freetdm: ss7 - fixed bug in dnis if ST character present --- .../src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c | 9 ++++++--- .../ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c | 6 ++++-- 2 files changed, 10 insertions(+), 5 deletions(-) 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 6fba4e9e0a..0d52dfada7 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 @@ -483,14 +483,17 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) i++; } - /* check if the end of pulsing character has arrived or the right number of digits */ - if (ftdmchan->caller_data.dnis.digits[i] == 0xF) { + /* check if the end of pulsing (ST) character has arrived or the right number of digits */ + if (ftdmchan->caller_data.dnis.digits[i-1] == 'F') { SS7_DEBUG_CHAN(ftdmchan, "Received the end of pulsing character %s\n", ""); + /* remove the ST */ + ftdmchan->caller_data.dnis.digits[i-1] = '\0'; + /*now go to the RING state */ ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RING); - } else if (i >= g_ftdm_sngss7_data.min_digits) { + } else if (i > g_ftdm_sngss7_data.min_digits) { SS7_DEBUG_CHAN(ftdmchan, "Received %d digits (min digits = %d)\n", i, g_ftdm_sngss7_data.min_digits); /*now go to the RING state */ 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 1e8e54a5ee..5086d11a71 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 @@ -306,9 +306,9 @@ uint8_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven) j = 0; for (i = 0; i < str.len; i++) { - sprintf(&ftdm[j], "%d", (str.val[i] & 0x0F)); + sprintf(&ftdm[j], "%X", (str.val[i] & 0x0F)); j++; - sprintf(&ftdm[j], "%d", ((str.val[i] & 0xF0) >> 4)); + sprintf(&ftdm[j], "%X", ((str.val[i] & 0xF0) >> 4)); j++; } @@ -318,6 +318,8 @@ uint8_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven) } else { ftdm[j] = '\0'; } + + } else { SS7_ERROR("Asked to copy tknStr that is not present!\n"); return 1; From 1c76ca4d72df8faf698edcea32b17f33f5009533 Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Fri, 17 Sep 2010 13:37:20 -0400 Subject: [PATCH 25/25] freetdm: ss7 - bug fix in pause/resume handling --- .../ftmod_sangoma_ss7_main.c | 36 +++++++++++++++++++ .../ftmod_sangoma_ss7_support.c | 21 +++++------ 2 files changed, 44 insertions(+), 13 deletions(-) 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 0d52dfada7..a4fee0f862 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 @@ -953,6 +953,42 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) SS7_DEBUG_CHAN(ftdmchan,"Current flags: 0x%X\n", sngss7_info->flags); + /**********************************************************************/ + if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) { + + /* clear the RESUME flag */ + sngss7_clear_flag(sngss7_info, FLAG_INFID_RESUME); + + /* if there are any resets present */ + if ((sngss7_test_flag (sngss7_info, FLAG_RESET_TX)) || + (sngss7_test_flag (sngss7_info, FLAG_RESET_RX)) || + (sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_TX)) || + (sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_RX))) { + + /* go back to the reset state */ + goto suspend_goto_restart; + } else { + + /* bring the sig status back up */ + sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; + sigev.sigstatus = FTDM_SIG_STATE_UP; + ftdm_span_send_signal(ftdmchan->span, &sigev); + } + + /* go back to the last state */ + goto suspend_goto_last; + } /* if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) */ + + if (sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) { + + /* bring the sig status down */ + sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; + sigev.sigstatus = FTDM_SIG_STATE_DOWN; + ftdm_span_send_signal(ftdmchan->span, &sigev); + + /* go back to the last state */ + goto suspend_goto_last; + } /* if (sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) { */ /**********************************************************************/ if (sngss7_test_flag (sngss7_info, FLAG_CKT_MN_BLOCK_RX)) { SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_BLOCK_RX flag %s\n", ""); 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 5086d11a71..694e9a4ed8 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 @@ -561,24 +561,19 @@ ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan) sigev.span_id = ftdmchan->span_id; sigev.channel = ftdmchan; + /* if we have the PAUSED flag and the sig status is still UP */ if ((sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) && (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP))) { - /* bring the sig status down */ - sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sigev.sigstatus = FTDM_SIG_STATE_DOWN; - ftdm_span_send_signal(ftdmchan->span, &sigev); + /* throw the channel into SUSPENDED to process the flag */ + /* after doing this once the sig status will be down */ + ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); } - if ((sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) && - !(ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP))) { - - /* bring the sig status back up */ - sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sigev.sigstatus = FTDM_SIG_STATE_UP; - ftdm_span_send_signal(ftdmchan->span, &sigev); - - sngss7_clear_flag(sngss7_info, FLAG_INFID_RESUME); + /* if the RESUME flag is up go to SUSPENDED to process the flag */ + /* after doing this the flag will be cleared */ + if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) { + ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); } /* unlock the channel */