From e3b9db88947df3ae21ca1e20b24d84d230bb059a Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Tue, 31 Aug 2010 17:33:42 -0400 Subject: [PATCH] freetdm: implemented Trillium stack message queueing --- libs/freetdm/Makefile.am | 25 +- .../ftmod_sangoma_ss7_handle.c | 1930 +++++++++++++++++ .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c | 1906 ++-------------- .../ftmod_sangoma_ss7_main.c | 169 +- .../ftmod_sangoma_ss7_main.h | 75 +- 5 files changed, 2341 insertions(+), 1764 deletions(-) create mode 100644 libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c diff --git a/libs/freetdm/Makefile.am b/libs/freetdm/Makefile.am index 6ccc473ce3..33a8b96936 100644 --- a/libs/freetdm/Makefile.am +++ b/libs/freetdm/Makefile.am @@ -268,18 +268,19 @@ ftmod_pritap_la_LIBADD = $(MYLIB) endif if SNGSS7 -ftmod_sangoma_ss7_la_SOURCES = $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_timers.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sts.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c +ftmod_sangoma_ss7_la_SOURCES = $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c \ + $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c \ + $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c \ + $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c \ + $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c \ + $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c \ + $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c \ + $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_timers.c \ + $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c \ + $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c \ + $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c \ + $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sts.c \ + $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c ftmod_sangoma_ss7_la_CFLAGS = $(AM_CFLAGS) $(MY_CFLAGS) -D_GNU_SOURCE ftmod_sangoma_ss7_la_LDFLAGS = -module -avoid-version -lsng_ss7 ftmod_sangoma_ss7_la_LIBADD = $(MYLIB) 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 new file mode 100644 index 0000000000..d1f3a8b89c --- /dev/null +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c @@ -0,0 +1,1930 @@ +/* + * Copyright (c) 2009 Konrad Hammel + * All rights reserved. + * + * Redistribution and use in source and binary forms|with or without + * modification|are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice|this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice|this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of the original author; nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES|INCLUDING|BUT NOT + * LIMITED TO|THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT|INDIRECT|INCIDENTAL|SPECIAL, + * EXEMPLARY|OR CONSEQUENTIAL DAMAGES (INCLUDING|BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE|DATA|OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY|WHETHER IN CONTRACT|STRICT LIABILITY|OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE|EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* INCLUDE ********************************************************************/ +#include "ftmod_sangoma_ss7_main.h" +/******************************************************************************/ + +/* DEFINES ********************************************************************/ +/******************************************************************************/ + +/* GLOBALS ********************************************************************/ +/******************************************************************************/ + +/* PROTOTYPES *****************************************************************/ +/* PROTOTYPES *****************************************************************/ +ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt); +ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCnStEvnt *siCnStEvnt, uint8_t evntType); +ftdm_status_t handle_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt); +ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt); +ftdm_status_t handle_rel_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt); +ftdm_status_t handle_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiInfoEvnt *siInfoEvnt); +ftdm_status_t handle_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt); +ftdm_status_t handle_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt); +ftdm_status_t handle_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit); +ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); + +ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_cot_start(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_cot_stop(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_cot(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_local_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_rsc_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_grs_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_blo_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_blo_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_ubl_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_ubl_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +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); +/******************************************************************************/ + +/* FUNCTIONS ******************************************************************/ +ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info ; + ftdm_channel_t *ftdmchan; + + /* 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; + } + + /* 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_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx IAM\n"); + + /* check if the circuit has a remote block */ + if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) || + (sngss7_test_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX)) || + (sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) { + + /* as per Q.764, 2.8.2.3 xiv ... remove the block from this channel */ + sngss7_clear_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); + sngss7_clear_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX); + sngss7_clear_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX); + + /* KONRAD FIX ME : check in case there is a ckt and grp block */ + } + + /* check whether the ftdm channel is in a state to accept a call */ + switch (ftdmchan->state) { + /**************************************************************************/ + case (FTDM_CHANNEL_STATE_DOWN): /* only state it is fully valid to get IAM */ + + /* fill in the channels SS7 Stack information */ + sngss7_info->suInstId = get_unique_id(); + sngss7_info->spInstId = spInstId; + + /* try to open the ftdm channel */ + if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) { + SS7_ERROR("Failed to open span: %d, chan: %d\n", + ftdmchan->physical_span_id, + ftdmchan->physical_chan_id); + + /* set the flag to indicate this hangup is started from the local side */ + sngss7_set_flag(sngss7_info, FLAG_LOCAL_REL); + + ftdmchan->caller_data.hangup_cause = 41; + + /* move the state to CANCEL */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_CANCEL); + + } else { + + /* fill in cid/ani number */ + if (siConEvnt->cgPtyNum.addrSig.pres) { + copy_tknStr_from_sngss7(siConEvnt->cgPtyNum.addrSig, + ftdmchan->caller_data.cid_num.digits, + siConEvnt->cgPtyNum.oddEven); + + /* fill in cid Name */ + ftdm_set_string(ftdmchan->caller_data.cid_name, ftdmchan->caller_data.cid_num.digits); + + ftdm_set_string(ftdmchan->caller_data.ani.digits, ftdmchan->caller_data.cid_num.digits); + + } else { + SS7_INFO("No Calling party (ANI) information in IAM!\n"); + } + + /* fill in dnis */ + if (siConEvnt->cdPtyNum.addrSig.pres) { + copy_tknStr_from_sngss7(siConEvnt->cdPtyNum.addrSig, + ftdmchan->caller_data.dnis.digits, + siConEvnt->cdPtyNum.oddEven); + } else { + SS7_INFO("No Called party (DNIS) information in IAM!\n"); + } + + /* fill in rdnis */ + if (siConEvnt->redirgNum.addrSig.pres) { + copy_tknStr_from_sngss7(siConEvnt->redirgNum.addrSig, + ftdmchan->caller_data.rdnis.digits, + siConEvnt->cgPtyNum.oddEven); + } else { + SS7_INFO("No RDNIS party information in IAM!\n"); + } + + /* fill in screening/presentation */ + ftdmchan->caller_data.screen = siConEvnt->cgPtyNum.scrnInd.val; + ftdmchan->caller_data.pres = siConEvnt->cgPtyNum.presRest.val; + + /* set the state of the channel to collecting...the rest is done by the chan monitor */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_COLLECT); + + } /* if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) */ + + break; + /**************************************************************************/ + default: /* should not have gotten an IAM while in this state */ + SS7_ERROR("Got IAM in an invalid state (%s) on span=%d, chan=%d!\n", + ftdm_channel_state2str(ftdmchan->state), + ftdmchan->physical_span_id, + ftdmchan->physical_chan_id); + + /* move the state of the channel to RESTART to force a reset */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); + + break; + /**************************************************************************/ + } /* switch (ftdmchan->state) */ + + /* unlock the channel */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCnStEvnt *siCnStEvnt, uint8_t evntType) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info ; + ftdm_channel_t *ftdmchan; + + /* 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; + } + + /* 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_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + } + + switch (evntType) { + /**************************************************************************/ + case (ADDRCMPLT): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx ACM\n"); + switch (ftdmchan->state) { + /**********************************************************************/ + case FTDM_CHANNEL_STATE_DIALING: + /* KONRAD: should we confirm the instance ids ? */ + + /* need to grab the sp instance id */ + sngss7_info->spInstId = spInstId; + + /* go to PROGRESS */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS); + break; + /**********************************************************************/ + default: /* incorrect state...reset the CIC */ + /* go to RESTART */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS); + break; + /**********************************************************************/ + } /* switch (ftdmchan->state) */ + /**************************************************************************/ + case (MODIFY): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx MODIFY\n"); + break; + /**************************************************************************/ + case (MODCMPLT): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx MODIFY-COMPLETE\n"); + break; + /**************************************************************************/ + case (MODREJ): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx MODIFY-REJECT\n"); + break; + /**************************************************************************/ + case (PROGRESS): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CPG\n"); + break; + /**************************************************************************/ + case (FRWDTRSFR): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx FOT\n"); + break; + /**************************************************************************/ + case (INFORMATION): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx INF\n"); + break; + /**************************************************************************/ + case (INFORMATREQ): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx INR\n"); + break; + /**************************************************************************/ + case (SUBSADDR): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx SAM\n"); + break; + /**************************************************************************/ + case (EXIT): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx EXIT\n"); + break; + /**************************************************************************/ + case (NETRESMGT): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx NRM\n"); + break; + /**************************************************************************/ + case (IDENTREQ): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx IDR\n"); + break; + /**************************************************************************/ + case (IDENTRSP): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx IRS\n"); + break; + /**************************************************************************/ + case (MALCLLPRNT): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx MALICIOUS CALL\n"); + break; + /**************************************************************************/ + case (CHARGE): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CRG\n"); + break; + /**************************************************************************/ + case (TRFFCHGE): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CRG-TARIFF\n"); + break; + /**************************************************************************/ + case (CHARGEACK): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CRG-ACK\n"); + break; + /**************************************************************************/ + case (CALLOFFMSG): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CALL-OFFER\n"); + break; + /**************************************************************************/ + case (LOOPPRVNT): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LOP\n"); + break; + /**************************************************************************/ + case (TECT_TIMEOUT): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx ECT-Timeout\n"); + break; + /**************************************************************************/ + case (RINGSEND): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx RINGING-SEND\n"); + break; + /**************************************************************************/ + case (CALLCLEAR): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CALL-LINE Clear\n"); + break; + /**************************************************************************/ + case (PRERELEASE): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx PRI\n"); + break; + /**************************************************************************/ + case (APPTRANSPORT): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx APM\n"); + break; + /**************************************************************************/ + case (OPERATOR): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx OPERATOR\n"); + break; + /**************************************************************************/ + case (METPULSE): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx METERING-PULSE\n"); + break; + /**************************************************************************/ + case (CLGPTCLR): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CALLING_PARTY_CLEAR\n"); + break; + /**************************************************************************/ + case (SUBDIRNUM): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx SUB-DIR\n"); + break; + /**************************************************************************/ + default: + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Unknown Msg\n"); + break; + /**************************************************************************/ + } + + /* unlock the channel */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info ; + ftdm_channel_t *ftdmchan; + + /* 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; + } + + /* 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_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + + /* check whether the ftdm channel is in a state to accept a call */ + switch (ftdmchan->state) { + /**************************************************************************/ + case FTDM_CHANNEL_STATE_PROGRESS: + case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: + + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx ANM\n"); + + /* go to UP */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP); + + break; + /**************************************************************************/ + case FTDM_CHANNEL_STATE_DIALING: + + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CON\n"); + + /* go to UP */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP); + + break; + /**************************************************************************/ + default: /* incorrect state...reset the CIC */ + + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx ANM/CON\n"); + + /* throw the TX reset flag */ + sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX); + + /* go to RESTART */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); + + break; + /**************************************************************************/ + } + + /* unlock the channel */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info ; + ftdm_channel_t *ftdmchan; + + /* 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; + } + + /* 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_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx REL\n"); + + /* check whether the ftdm channel is in a state to release a call */ + switch (ftdmchan->state) { + /**************************************************************************/ + case FTDM_CHANNEL_STATE_DIALING: + + /* pass the release code up to FTDM */ + if (siRelEvnt->causeDgn.causeVal.pres) { + ftdmchan->caller_data.hangup_cause = siRelEvnt->causeDgn.causeVal.val; + } else { + SS7_ERROR("REL does not have a cause code!\n"); + ftdmchan->caller_data.hangup_cause = 0; + } + + /* this is a remote hangup request */ + sngss7_set_flag(sngss7_info, FLAG_REMOTE_REL); + + /* move the state of the channel to CANCEL to end the call */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); + + break; + /**************************************************************************/ + case FTDM_CHANNEL_STATE_RING: + case FTDM_CHANNEL_STATE_PROGRESS: + case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: + case FTDM_CHANNEL_STATE_UP: + + /* pass the release code up to FTDM */ + if (siRelEvnt->causeDgn.causeVal.pres) { + ftdmchan->caller_data.hangup_cause = siRelEvnt->causeDgn.causeVal.val; + } else { + SS7_ERROR("REL does not have a cause code!\n"); + ftdmchan->caller_data.hangup_cause = 0; + } + + /* this is a remote hangup request */ + sngss7_set_flag(sngss7_info, FLAG_REMOTE_REL); + + /* move the state of the channel to TERMINATING to end the call */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); + + break; + /**************************************************************************/ + default: + + /* fill in the channels SS7 Stack information */ + sngss7_info->suInstId = get_unique_id(); + sngss7_info->spInstId = spInstId; + + /* throw the reset flag */ + sngss7_set_flag(sngss7_info, FLAG_RESET_RX); + + /* set the state to RESTART */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); + break; + /**************************************************************************/ + } /* switch (ftdmchan->state) */ + + + /* unlock the channel */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_rel_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info ; + ftdm_channel_t *ftdmchan; + + /* 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; + } + + /* 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_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx RLC\n"); + + /* check whether the ftdm channel is in a state to accept a call */ + switch (ftdmchan->state) { + /**************************************************************************/ + case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: + + /* go to DOWN */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); + + break; + /**************************************************************************/ + case FTDM_CHANNEL_STATE_DOWN: + /* do nothing, just drop the message */ + break; + /**************************************************************************/ + default: + /* KONRAD: should just stop the call...but a reset is easier for now (since it does hangup the call) */ + + /* go to RESTART */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); + + break; + /**************************************************************************/ + } + + /* unlock the channel */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiInfoEvnt *siInfoEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info ; + ftdm_channel_t *ftdmchan; + + /* 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; + } + + /* 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_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx DATA IND\n"); + + /* unlock the channel */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info ; + ftdm_channel_t *ftdmchan; + + /* 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; + } + + /* 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_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx FAC\n"); + + /* unlock the channel */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info ; + ftdm_channel_t *ftdmchan; + + /* 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; + } + + /* 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_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx FAC-CON\n"); + + /* unlock the channel */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info ; + ftdm_channel_t *ftdmchan; + + /* 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; + } + + /* 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_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx USER-USER msg\n"); + + /* unlock the channel */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) +{ + sngss7_chan_data_t *sngss7_info ; + ftdm_channel_t *ftdmchan; + + /* 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; + } + + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + switch (evntType) { + /**************************************************************************/ + case SIT_STA_REATTEMPT: /* reattempt indication */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Reattempt indication\n"); + handle_reattempt(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_ERRORIND: /* error indication */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Error indication\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_CONTCHK: /* continuity check */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx COT start\n"); + handle_cot_start(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_CONTREP: /* continuity report */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx COT report\n"); + handle_cot(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_STPCONTIN: /* stop continuity */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx COT stop\n"); + handle_cot_stop(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_CGQRYRSP: /* circuit grp query response from far end forwarded to upper layer by ISUP */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CQM\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_CONFUSION: /* confusion */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CFN\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_LOOPBACKACK: /* loop-back acknowledge */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LPA\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_CIRRSRVREQ: /* circuit reservation request */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Ckt Resveration req\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_CIRRSRVACK: /* circuit reservation acknowledgement */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Ckt Res ack\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_CIRBLOREQ: /* circuit blocking request */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx BLO\n"); + handle_blo_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_CIRBLORSP: /* circuit blocking response */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx BLA\n"); + handle_blo_rsp(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_CIRUBLREQ: /* circuit unblocking request */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx UBL\n"); + handle_ubl_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_CIRUBLRSP: /* circuit unblocking response */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx UBA\n"); + handle_ubl_rsp(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_CIRRESREQ: /* circuit reset request - RSC */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx RSC\n"); + handle_rsc_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_CIRLOCRES: /* reset initiated locally by the software */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Local RSC\n"); + handle_local_rsc_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_CIRRESRSP: /* circuit reset response */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx RSC-RLC\n"); + handle_rsc_rsp(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + 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)); + 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)); + break; + /**************************************************************************/ + case SIT_STA_CGQRYREQ: /* circuit group query request */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CQM\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + 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)); + 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)); + break; + /**************************************************************************/ + case SIT_STA_GRSREQ: /* circuit group reset request */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx GRS\n"); + handle_grs_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_CIRUNEQPD: /* circuit unequipped indication */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx UCIC\n"); + handle_ucic(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_GRSRSP: /* circuit group reset response */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx GRA\n"); + handle_grs_rsp(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_PAUSEIND: /* pause indication */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx SUS\n"); + handle_pause(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_RESUMEIND: /* resume indication */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx RES\n"); + handle_resume(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_USRPARTA: /* user part available */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx UPA\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_RMTUSRUNAV: /* remote user not available */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Remote User not Available\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_MTPCONG0: /* congestion indication level 0 */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Congestion L0\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_MTPCONG1: /* congestion indication level 1 */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Congestion L1\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_MTPCONG2: /* congestion indication level 2 */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Congestion L2\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_MTPCONG3: /* congestion indication level 3 */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Congestion L3\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_MTPSTPCONG: /* stop congestion indication level 0 */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Stop Congestion\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_CIRLOCALBLOIND: /* Mngmt local blocking */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Local BLO\n"); + handle_local_blk(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_CIRLOCALUBLIND: /* Mngmt local unblocking */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Local UBL\n"); + handle_local_ubl(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_OVERLOAD: /* Overload */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Overload\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_LMCGBREQ: /* when LM requests ckt grp blocking */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LM CGB\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_LMCGUREQ: /* when LM requests ckt grp unblocking */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LM CGU\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_LMGRSREQ: /* when LM requests ckt grp reset */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LM RSC\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + 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)); + break; + /**************************************************************************/ + 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)); + break; + /**************************************************************************/ + case SIT_STA_CIRLOCGRS: /* group reset initiated locally by the software */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Local GRS\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + default: + SS7_INFO("[SNG-CC] Received Unknown indication %d\n", evntType); + break; + } /* switch (evntType) */ + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; + +} + +/******************************************************************************/ +ftdm_status_t handle_reattempt(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; + ftdm_channel_t *ftdmchan = NULL; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for ISUP circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* 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_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + /* glare, throw the flag, go to down state*/ + sngss7_set_flag(sngss7_info, FLAG_GLARE); + + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_CANCEL); + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_pause(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; + ftdm_channel_t *ftdmchan = NULL; + int infId; + int i; + + /* extract the affect infId from the circuit structure */ + infId = g_ftdm_sngss7_data.cfg.isupCkt[circuit].infId; + + /* go through all the circuits now and find any other circuits on this infId */ + i = 1; + while (g_ftdm_sngss7_data.cfg.isupCkt[i].id != 0) { + + /* check that the infId matches and that this is not a siglink */ + if ((g_ftdm_sngss7_data.cfg.isupCkt[i].infId == infId) && + (g_ftdm_sngss7_data.cfg.isupCkt[i].type == VOICE)) { + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(i, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + i++; + continue; + } + + /* 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 */ + ftdm_mutex_unlock(ftdmchan->mutex); + + } /* if (g_ftdm_sngss7_data.cfg.isupCkt[i].infId == infId) */ + + /* move to the next circuit */ + i++; + + } /* while (g_ftdm_sngss7_data.cfg.isupCkt[i].id != 0) */ + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_resume(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; + ftdm_channel_t *ftdmchan = NULL; + int infId; + int i; + + /* extract the affect infId from the circuit structure */ + infId = g_ftdm_sngss7_data.cfg.isupCkt[circuit].infId; + + /* go through all the circuits now and find any other circuits on this infId */ + i = 1; + while (g_ftdm_sngss7_data.cfg.isupCkt[i].id != 0) { + + /* check that the infId matches and that this is not a siglink */ + if ((g_ftdm_sngss7_data.cfg.isupCkt[i].infId == infId) && + (g_ftdm_sngss7_data.cfg.isupCkt[i].type == VOICE)) { + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(i, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + i++; + continue; + } + + /* 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 */ + sngss7_set_flag(sngss7_info, FLAG_INFID_RESUME); + + /* 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 */ + ftdm_mutex_unlock(ftdmchan->mutex); + + } /* if (g_ftdm_sngss7_data.cfg.isupCkt[i].infId == infId) */ + + /* move to the next circuit */ + i++; + + } /* while (g_ftdm_sngss7_data.cfg.isupCkt[i].id != 0) */ + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_cot_start(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; + ftdm_channel_t *ftdmchan = NULL; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* 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_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + /* open the channel if it is not open */ + if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) { + if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) { + SS7_ERROR("Failed to open CIC %d for COT test!\n", sngss7_info->circuit->cic); + /* KONRAD FIX ME */ + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + } + + /* tell the core to loop the channel */ + ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_LOOP, NULL); + + /* switch to the IN_LOOP state */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IN_LOOP); + + /* store the sngss7 ids */ + if (suInstId == 0) { + sngss7_info->suInstId = get_unique_id(); + } else { + sngss7_info->suInstId = suInstId; + } + sngss7_info->spInstId = spInstId; + sngss7_info->globalFlg = globalFlg; + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_cot_stop(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; + ftdm_channel_t *ftdmchan = NULL; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* 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_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + /* tell the core to stop looping the channel */ + ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL); + + /* exit out of the LOOP state to the last state */ + ftdm_set_state_locked(ftdmchan, ftdmchan->last_state); + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_cot(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + if ( (siStaEvnt->contInd.eh.pres > 0) && (siStaEvnt->contInd.contInd.pres > 0)) { + SS7_INFO("Continuity Test result for CIC = %d (span %d, chan %d) is: \"%s\"\n", + g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, + g_ftdm_sngss7_data.cfg.isupCkt[circuit].span, + g_ftdm_sngss7_data.cfg.isupCkt[circuit].chan, + (siStaEvnt->contInd.contInd.val) ? "PASS" : "FAIL"); + } else { + SS7_ERROR("Recieved Continuity report containing no results!\n"); + } + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ + + +/******************************************************************************/ +ftdm_status_t handle_blo_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* 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_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + /* check if the circuit is already blocked or not */ + if (sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) { + SS7_WARN("Received BLO on circuit that is already blocked!\n"); + } + + /* throw the ckt block flag */ + sngss7_set_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); + + /* set the channel to suspended state */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_blo_rsp(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; + ftdm_channel_t *ftdmchan = NULL; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* 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_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + /* KONRAD FIX ME */ + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_ubl_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; + ftdm_channel_t *ftdmchan = NULL; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* 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_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + /* check if the channel is blocked */ + if (!(sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX))) { + SS7_WARN("Received UBL on circuit that is not blocked!\n"); + } + + /* throw the unblock flag */ + sngss7_set_flag(sngss7_info, FLAG_CKT_MN_UNBLK_RX); + + /* clear the block flag */ + sngss7_clear_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); + + /* set the channel to suspended state */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_ubl_rsp(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; + ftdm_channel_t *ftdmchan = NULL; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* 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_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + /* KONRAD FIX ME */ + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_rsc_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; + ftdm_channel_t *ftdmchan = NULL; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* 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_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + /* throw the reset flag */ + sngss7_set_flag(sngss7_info, FLAG_RESET_RX); + + 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); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_local_rsc_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; + ftdm_channel_t *ftdmchan = NULL; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* 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_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + /* throw the reset flag */ + sngss7_set_flag(sngss7_info, FLAG_RESET_RX); + + 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); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_rsc_rsp(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; + ftdm_channel_t *ftdmchan = NULL; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* 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_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + switch (ftdmchan->state) { + /**********************************************************************/ + case FTDM_CHANNEL_STATE_RESTART: + + if ( sngss7_test_flag(sngss7_info, FLAG_RESET_TX) ) { + /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ + sngss7_set_flag(sngss7_info, FLAG_RESET_TX_RSP); + + /* go to DOWN */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); + } else { + SS7_ERROR("Received RSC-RLC but we're not waiting on a RSC-RLC on CIC #, dropping\n", sngss7_info->circuit->cic); + } + + break; + /**********************************************************************/ + case FTDM_CHANNEL_STATE_DOWN: + + /* do nothing, just drop the message */ + SS7_DEBUG("Receveived RSC-RLC in down state, dropping\n"); + + break; + /**********************************************************************/ + case FTDM_CHANNEL_STATE_TERMINATING: + case FTDM_CHANNEL_STATE_HANGUP: + case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: + + /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ + sngss7_set_flag(sngss7_info, FLAG_RESET_TX_RSP); + + /* go to DOWN */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); + + break; + /**********************************************************************/ + default: + /* ITU Q764-2.9.5.1.c -> release the circuit */ + if ((siStaEvnt != NULL) && + (siStaEvnt->causeDgn.eh.pres ==PRSNT_NODEF) && + (siStaEvnt->causeDgn.causeVal.pres == PRSNT_NODEF)) { + ftdmchan->caller_data.hangup_cause = siStaEvnt->causeDgn.causeVal.val; + } else { + ftdmchan->caller_data.hangup_cause = 98; /* Message not compatiable with call state */ + } + + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); + break; + /**********************************************************************/ + } + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} +/******************************************************************************/ +ftdm_status_t handle_grs_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; + ftdm_channel_t *ftdmchan = NULL; + sngss7_span_data_t *span = NULL; + int range; + int x; + + 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; + } + + /* extract the range value from the event structure */ + if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.range.pres == PRSNT_NODEF)) { + range = siStaEvnt->rangStat.range.val; + } else { + SS7_ERROR("Received GRS with no range value on CIC = %d\n", sngss7_info->circuit->cic); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* 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; + }; + + /* fill in the span structure for this circuit */ + span = ftdmchan->span->mod_data; + span->grs.circuit = circuit; + span->grs.range = range; + + SS7_DEBUG_CHAN(ftdmchan, "Rx GRS (%d:%d)\n", + g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, + (g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic + range)); + + /* flag the channel as having received a reset */ + sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX); + + 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); + + } + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_grs_rsp(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; + ftdm_channel_t *ftdmchan = NULL; + int range; + int x; + + /* extract the range value from the event structure */ + if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.range.pres == PRSNT_NODEF)) { + range = siStaEvnt->rangStat.range.val; + } else { + SS7_ERROR("Received GRA with no range value on CIC = %d\n", sngss7_info->circuit->cic); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* go through all the circuits in the range */ + 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", circuit); + 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; + }; + + SS7_DEBUG_CHAN(ftdmchan, "Rx GRA (%d:%d)\n", + g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, + (g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic + range)); + + switch (ftdmchan->state) { + /**********************************************************************/ + case FTDM_CHANNEL_STATE_RESTART: + + /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ + sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); + + /* go to DOWN */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); + + break; + /**********************************************************************/ + case FTDM_CHANNEL_STATE_DOWN: + + /* do nothing, just drop the message */ + SS7_DEBUG("Receveived GRA in down state, dropping\n"); + + break; + /**********************************************************************/ + case FTDM_CHANNEL_STATE_TERMINATING: + case FTDM_CHANNEL_STATE_HANGUP: + case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: + + /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ + sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); + + break; + /**********************************************************************/ + default: + /* ITU Q764-2.9.5.1.c -> release the circuit */ + if ((siStaEvnt != NULL) && + (siStaEvnt->causeDgn.eh.pres ==PRSNT_NODEF) && + (siStaEvnt->causeDgn.causeVal.pres == PRSNT_NODEF)) { + ftdmchan->caller_data.hangup_cause = siStaEvnt->causeDgn.causeVal.val; + } else { + ftdmchan->caller_data.hangup_cause = 98; /* Message not compatiable with call state */ + } + + /* go to terminating to hang up the call */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); + break; + /**********************************************************************/ + } + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + } /* for (( x = 0; x < (circuit + range); x++) */ + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_local_blk(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; + ftdm_channel_t *ftdmchan = NULL; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* 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_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + /* check if the circuit is already blocked or not */ + if (sngss7_test_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX)) { + SS7_WARN("Received local BLO on circuit that is already blocked!\n"); + } + + /* throw the ckt block flag */ + sngss7_set_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX); + + /* set the channel to suspended state */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_local_ubl(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; + ftdm_channel_t *ftdmchan = NULL; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* 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_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + /* check if the circuit is already blocked or not */ + if (sngss7_test_flag(sngss7_info, FLAG_CKT_LC_UNBLK_RX)) { + SS7_WARN("Received local UBL on circuit that is already unblocked!\n"); + } + + /* throw the ckt block flag */ + sngss7_set_flag(sngss7_info, FLAG_CKT_LC_UNBLK_RX); + + /* set the channel to suspended state */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_ucic(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; + ftdm_channel_t *ftdmchan = NULL; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* 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_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + /* throw the ckt block flag */ + sngss7_set_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK); + + /* set the channel to suspended state */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + + +/******************************************************************************/ +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4: + */ +/******************************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c index 98554db6a4..34893cf5aa 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c @@ -53,31 +53,6 @@ void sngss7_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint void sngss7_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt); void sngss7_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit); -static ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -static ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -static ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); - -static ftdm_status_t handle_cot_start(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -static ftdm_status_t handle_cot_stop(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -static ftdm_status_t handle_cot(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); - -static ftdm_status_t handle_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -static ftdm_status_t handle_local_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -static ftdm_status_t handle_rsc_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); - -static ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -static ftdm_status_t handle_grs_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); - -static ftdm_status_t handle_blo_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -static ftdm_status_t handle_blo_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -static ftdm_status_t handle_ubl_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -static ftdm_status_t handle_ubl_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); - -static ftdm_status_t handle_local_blk(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -static ftdm_status_t handle_local_ubl(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); - -static ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); - /******************************************************************************/ /* FUNCTIONS ******************************************************************/ @@ -85,8 +60,9 @@ void sngss7_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCo { SS7_FUNC_TRACE_ENTER(__FUNCTION__); - sngss7_chan_data_t *sngss7_info ; - ftdm_channel_t *ftdmchan; + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + sngss7_event_data_t *sngss7_event = NULL; /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { @@ -95,119 +71,26 @@ void sngss7_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCo return; } - /* 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); + /* initalize the sngss7_event */ + sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); + if (sngss7_event == NULL) { + SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx IAM\n"); - - /* check if the circuit has a remote block */ - if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) || - (sngss7_test_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX)) || - (sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) { - - /* as per Q.764, 2.8.2.3 xiv ... remove the block from this channel */ - sngss7_clear_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); - sngss7_clear_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX); - sngss7_clear_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX); - - /* KONRAD FIX ME : check in case there is a ckt and grp block */ + return; } + memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - /* check whether the ftdm channel is in a state to accept a call */ - switch (ftdmchan->state) { - /**************************************************************************/ - case (FTDM_CHANNEL_STATE_DOWN): /* only state it is fully valid to get IAM */ + /* fill in the sngss7_event struct */ + sngss7_event->spInstId = spInstId; + sngss7_event->suInstId = suInstId; + sngss7_event->circuit = circuit; + sngss7_event->event_id = SNGSS7_CON_IND_EVENT; + memcpy(&sngss7_event->event.siConEvnt, siConEvnt, sizeof(*siConEvnt)); - /* fill in the channels SS7 Stack information */ - sngss7_info->suInstId = get_unique_id(); - sngss7_info->spInstId = spInstId; - - /* try to open the ftdm channel */ - if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) { - SS7_ERROR("Failed to open span: %d, chan: %d\n", - ftdmchan->physical_span_id, - ftdmchan->physical_chan_id); - - /* set the flag to indicate this hangup is started from the local side */ - sngss7_set_flag(sngss7_info, FLAG_LOCAL_REL); - - ftdmchan->caller_data.hangup_cause = 41; - - /* move the state to CANCEL */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_CANCEL); - - } else { - - /* fill in cid/ani number */ - if (siConEvnt->cgPtyNum.addrSig.pres) { - copy_tknStr_from_sngss7(siConEvnt->cgPtyNum.addrSig, - ftdmchan->caller_data.cid_num.digits, - siConEvnt->cgPtyNum.oddEven); - - /* fill in cid Name */ - ftdm_set_string(ftdmchan->caller_data.cid_name, ftdmchan->caller_data.cid_num.digits); - - ftdm_set_string(ftdmchan->caller_data.ani.digits, ftdmchan->caller_data.cid_num.digits); - - } else { - SS7_INFO("No Calling party (ANI) information in IAM!\n"); - } - - /* fill in dnis */ - if (siConEvnt->cdPtyNum.addrSig.pres) { - copy_tknStr_from_sngss7(siConEvnt->cdPtyNum.addrSig, - ftdmchan->caller_data.dnis.digits, - siConEvnt->cdPtyNum.oddEven); - } else { - SS7_INFO("No Called party (DNIS) information in IAM!\n"); - } - - /* fill in rdnis */ - if (siConEvnt->redirgNum.addrSig.pres) { - copy_tknStr_from_sngss7(siConEvnt->redirgNum.addrSig, - ftdmchan->caller_data.rdnis.digits, - siConEvnt->cgPtyNum.oddEven); - } else { - SS7_INFO("No RDNIS party information in IAM!\n"); - } - - /* fill in screening/presentation */ - ftdmchan->caller_data.screen = siConEvnt->cgPtyNum.scrnInd.val; - ftdmchan->caller_data.pres = siConEvnt->cgPtyNum.presRest.val; - - /* set the state of the channel to collecting...the rest is done by the chan monitor */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_COLLECT); - - } /* if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) */ - - break; - /**************************************************************************/ - default: /* should not have gotten an IAM while in this state */ - SS7_ERROR("Got IAM in an invalid state (%s) on span=%d, chan=%d!\n", - ftdm_channel_state2str(ftdmchan->state), - ftdmchan->physical_span_id, - ftdmchan->physical_chan_id); - - /* move the state of the channel to RESTART to force a reset */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - - break; - /**************************************************************************/ - } /* switch (ftdmchan->state) */ - - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); + /* enqueue this event */ + ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return; } /******************************************************************************/ @@ -215,8 +98,9 @@ void sngss7_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCo { SS7_FUNC_TRACE_ENTER(__FUNCTION__); - sngss7_chan_data_t *sngss7_info ; - ftdm_channel_t *ftdmchan; + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + sngss7_event_data_t *sngss7_event = NULL; /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { @@ -225,59 +109,26 @@ void sngss7_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCo return; } - /* 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); + /* initalize the sngss7_event */ + sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); + if (sngss7_event == NULL) { + SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - - /* check whether the ftdm channel is in a state to accept a call */ - switch (ftdmchan->state) { - /**************************************************************************/ - case FTDM_CHANNEL_STATE_PROGRESS: - case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx ANM\n"); - - /* go to UP */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP); - - break; - /**************************************************************************/ - case FTDM_CHANNEL_STATE_DIALING: - - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CON\n"); - - /* go to UP */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP); - - break; - /**************************************************************************/ - default: /* incorrect state...reset the CIC */ - - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx ANM/CON\n"); - - /* throw the TX reset flag */ - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX); - - /* go to RESTART */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - - break; - /**************************************************************************/ + return; } + memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); + /* fill in the sngss7_event struct */ + sngss7_event->spInstId = spInstId; + sngss7_event->suInstId = suInstId; + sngss7_event->circuit = circuit; + sngss7_event->event_id = SNGSS7_CON_CFM_EVENT; + memcpy(&sngss7_event->event.siConEvnt, siConEvnt, sizeof(*siConEvnt)); + + /* enqueue this event */ + ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return; } /******************************************************************************/ @@ -285,8 +136,9 @@ void sngss7_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCn { SS7_FUNC_TRACE_ENTER(__FUNCTION__); - sngss7_chan_data_t *sngss7_info ; - ftdm_channel_t *ftdmchan; + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + sngss7_event_data_t *sngss7_event = NULL; /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { @@ -295,159 +147,27 @@ void sngss7_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCn return; } - /* 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); + /* initalize the sngss7_event */ + sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); + if (sngss7_event == NULL) { + SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; + return; } + memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - switch (evntType) { - /**************************************************************************/ - case (ADDRCMPLT): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx ACM\n"); - switch (ftdmchan->state) { - /**********************************************************************/ - case FTDM_CHANNEL_STATE_DIALING: - /* KONRAD: should we confirm the instance ids ? */ + /* fill in the sngss7_event struct */ + sngss7_event->spInstId = spInstId; + sngss7_event->suInstId = suInstId; + sngss7_event->circuit = circuit; + sngss7_event->evntType = evntType; + sngss7_event->event_id = SNGSS7_CON_STA_EVENT; + memcpy(&sngss7_event->event.siCnStEvnt, siCnStEvnt, sizeof(*siCnStEvnt)); - /* need to grab the sp instance id */ - sngss7_info->spInstId = spInstId; - - /* go to PROGRESS */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS); - break; - /**********************************************************************/ - default: /* incorrect state...reset the CIC */ - /* go to RESTART */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS); - break; - /**********************************************************************/ - } /* switch (ftdmchan->state) */ - /**************************************************************************/ - case (MODIFY): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx MODIFY\n"); - break; - /**************************************************************************/ - case (MODCMPLT): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx MODIFY-COMPLETE\n"); - break; - /**************************************************************************/ - case (MODREJ): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx MODIFY-REJECT\n"); - break; - /**************************************************************************/ - case (PROGRESS): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CPG\n"); - break; - /**************************************************************************/ - case (FRWDTRSFR): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx FOT\n"); - break; - /**************************************************************************/ - case (INFORMATION): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx INF\n"); - break; - /**************************************************************************/ - case (INFORMATREQ): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx INR\n"); - break; - /**************************************************************************/ - case (SUBSADDR): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx SAM\n"); - break; - /**************************************************************************/ - case (EXIT): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx EXIT\n"); - break; - /**************************************************************************/ - case (NETRESMGT): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx NRM\n"); - break; - /**************************************************************************/ - case (IDENTREQ): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx IDR\n"); - break; - /**************************************************************************/ - case (IDENTRSP): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx IRS\n"); - break; - /**************************************************************************/ - case (MALCLLPRNT): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx MALICIOUS CALL\n"); - break; - /**************************************************************************/ - case (CHARGE): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CRG\n"); - break; - /**************************************************************************/ - case (TRFFCHGE): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CRG-TARIFF\n"); - break; - /**************************************************************************/ - case (CHARGEACK): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CRG-ACK\n"); - break; - /**************************************************************************/ - case (CALLOFFMSG): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CALL-OFFER\n"); - break; - /**************************************************************************/ - case (LOOPPRVNT): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LOP\n"); - break; - /**************************************************************************/ - case (TECT_TIMEOUT): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx ECT-Timeout\n"); - break; - /**************************************************************************/ - case (RINGSEND): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx RINGING-SEND\n"); - break; - /**************************************************************************/ - case (CALLCLEAR): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CALL-LINE Clear\n"); - break; - /**************************************************************************/ - case (PRERELEASE): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx PRI\n"); - break; - /**************************************************************************/ - case (APPTRANSPORT): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx APM\n"); - break; - /**************************************************************************/ - case (OPERATOR): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx OPERATOR\n"); - break; - /**************************************************************************/ - case (METPULSE): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx METERING-PULSE\n"); - break; - /**************************************************************************/ - case (CLGPTCLR): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CALLING_PARTY_CLEAR\n"); - break; - /**************************************************************************/ - case (SUBDIRNUM): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx SUB-DIR\n"); - break; - /**************************************************************************/ - default: - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Unknown Msg\n"); - break; - /**************************************************************************/ - } - - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); + /* enqueue this event */ + ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return; } /******************************************************************************/ @@ -455,8 +175,9 @@ void sngss7_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRe { SS7_FUNC_TRACE_ENTER(__FUNCTION__); - sngss7_chan_data_t *sngss7_info ; - ftdm_channel_t *ftdmchan; + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + sngss7_event_data_t *sngss7_event = NULL; /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { @@ -465,92 +186,36 @@ void sngss7_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRe return; } - /* 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); + /* initalize the sngss7_event */ + sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); + if (sngss7_event == NULL) { + SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; + return; + } + memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx REL\n"); + /* fill in the sngss7_event struct */ + sngss7_event->spInstId = spInstId; + sngss7_event->suInstId = suInstId; + sngss7_event->circuit = circuit; + sngss7_event->event_id = SNGSS7_REL_IND_EVENT; + memcpy(&sngss7_event->event.siRelEvnt, siRelEvnt, sizeof(*siRelEvnt)); - /* check whether the ftdm channel is in a state to release a call */ - switch (ftdmchan->state) { - /**************************************************************************/ - case FTDM_CHANNEL_STATE_DIALING: - - /* pass the release code up to FTDM */ - if (siRelEvnt->causeDgn.causeVal.pres) { - ftdmchan->caller_data.hangup_cause = siRelEvnt->causeDgn.causeVal.val; - } else { - SS7_ERROR("REL does not have a cause code!\n"); - ftdmchan->caller_data.hangup_cause = 0; - } - - /* this is a remote hangup request */ - sngss7_set_flag(sngss7_info, FLAG_REMOTE_REL); - - /* move the state of the channel to CANCEL to end the call */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - - break; - /**************************************************************************/ - case FTDM_CHANNEL_STATE_RING: - case FTDM_CHANNEL_STATE_PROGRESS: - case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - case FTDM_CHANNEL_STATE_UP: - - /* pass the release code up to FTDM */ - if (siRelEvnt->causeDgn.causeVal.pres) { - ftdmchan->caller_data.hangup_cause = siRelEvnt->causeDgn.causeVal.val; - } else { - SS7_ERROR("REL does not have a cause code!\n"); - ftdmchan->caller_data.hangup_cause = 0; - } - - /* this is a remote hangup request */ - sngss7_set_flag(sngss7_info, FLAG_REMOTE_REL); - - /* move the state of the channel to TERMINATING to end the call */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - - break; - /**************************************************************************/ - default: - - /* fill in the channels SS7 Stack information */ - sngss7_info->suInstId = get_unique_id(); - sngss7_info->spInstId = spInstId; - - /* throw the reset flag */ - sngss7_set_flag(sngss7_info, FLAG_RESET_RX); - - /* set the state to RESTART */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - break; - /**************************************************************************/ - } /* switch (ftdmchan->state) */ - - - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); + /* enqueue this event */ + ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return; } - /******************************************************************************/ void sngss7_rel_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt) { SS7_FUNC_TRACE_ENTER(__FUNCTION__); - - sngss7_chan_data_t *sngss7_info ; - ftdm_channel_t *ftdmchan; + + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + sngss7_event_data_t *sngss7_event = NULL; /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { @@ -559,57 +224,36 @@ void sngss7_rel_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRe return; } - /* 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); + /* initalize the sngss7_event */ + sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); + if (sngss7_event == NULL) { + SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx RLC\n"); - - /* check whether the ftdm channel is in a state to accept a call */ - switch (ftdmchan->state) { - /**************************************************************************/ - case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: - - /* go to DOWN */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - - break; - /**************************************************************************/ - case FTDM_CHANNEL_STATE_DOWN: - /* do nothing, just drop the message */ - break; - /**************************************************************************/ - default: - /* KONRAD: should just stop the call...but a reset is easier for now (since it does hangup the call) */ - - /* go to RESTART */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - - break; - /**************************************************************************/ + return; } + memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); + /* fill in the sngss7_event struct */ + sngss7_event->spInstId = spInstId; + sngss7_event->suInstId = suInstId; + sngss7_event->circuit = circuit; + sngss7_event->event_id = SNGSS7_REL_CFM_EVENT; + memcpy(&sngss7_event->event.siRelEvnt, siRelEvnt, sizeof(*siRelEvnt)); + + /* enqueue this event */ + ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return; } /******************************************************************************/ void sngss7_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiInfoEvnt *siInfoEvnt) { SS7_FUNC_TRACE_ENTER(__FUNCTION__); - - sngss7_chan_data_t *sngss7_info ; - ftdm_channel_t *ftdmchan; + + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + sngss7_event_data_t *sngss7_event = NULL; /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { @@ -618,33 +262,36 @@ void sngss7_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiIn return; } - /* 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); + /* initalize the sngss7_event */ + sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); + if (sngss7_event == NULL) { + SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; + return; + } + memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx DATA IND\n"); + /* fill in the sngss7_event struct */ + sngss7_event->spInstId = spInstId; + sngss7_event->suInstId = suInstId; + sngss7_event->circuit = circuit; + sngss7_event->event_id = SNGSS7_DAT_IND_EVENT; + memcpy(&sngss7_event->event.siInfoEvnt, siInfoEvnt, sizeof(*siInfoEvnt)); - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); + /* enqueue this event */ + ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return; } /******************************************************************************/ void sngss7_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt) { SS7_FUNC_TRACE_ENTER(__FUNCTION__); - - sngss7_chan_data_t *sngss7_info ; - ftdm_channel_t *ftdmchan; + + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + sngss7_event_data_t *sngss7_event = NULL; /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { @@ -653,33 +300,37 @@ void sngss7_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint return; } - /* 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); + /* initalize the sngss7_event */ + sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); + if (sngss7_event == NULL) { + SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; + return; + } + memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx FAC\n"); + /* fill in the sngss7_event struct */ + sngss7_event->spInstId = spInstId; + sngss7_event->suInstId = suInstId; + sngss7_event->circuit = circuit; + sngss7_event->evntType = evntType; + sngss7_event->event_id = SNGSS7_FAC_IND_EVENT; + memcpy(&sngss7_event->event.siFacEvnt, siFacEvnt, sizeof(*siFacEvnt)); - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); + /* enqueue this event */ + ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return; } /******************************************************************************/ void sngss7_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt) { SS7_FUNC_TRACE_ENTER(__FUNCTION__); - - sngss7_chan_data_t *sngss7_info ; - ftdm_channel_t *ftdmchan; + + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + sngss7_event_data_t *sngss7_event = NULL; /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { @@ -688,33 +339,37 @@ void sngss7_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint return; } - /* 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); + /* initalize the sngss7_event */ + sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); + if (sngss7_event == NULL) { + SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; + return; + } + memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx FAC-CON\n"); + /* fill in the sngss7_event struct */ + sngss7_event->spInstId = spInstId; + sngss7_event->suInstId = suInstId; + sngss7_event->circuit = circuit; + sngss7_event->evntType = evntType; + sngss7_event->event_id = SNGSS7_FAC_CFM_EVENT; + memcpy(&sngss7_event->event.siFacEvnt, siFacEvnt, sizeof(*siFacEvnt)); - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); + /* enqueue this event */ + ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return; } /******************************************************************************/ void sngss7_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit) { SS7_FUNC_TRACE_ENTER(__FUNCTION__); - - sngss7_chan_data_t *sngss7_info ; - ftdm_channel_t *ftdmchan; + + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + sngss7_event_data_t *sngss7_event = NULL; /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { @@ -723,31 +378,35 @@ void sngss7_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit) return; } - /* 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); + /* initalize the sngss7_event */ + sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); + if (sngss7_event == NULL) { + SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; + return; + } + memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx USER-USER msg\n"); + /* fill in the sngss7_event struct */ + sngss7_event->spInstId = spInstId; + sngss7_event->suInstId = suInstId; + sngss7_event->circuit = circuit; + sngss7_event->event_id = SNGSS7_UMSG_IND_EVENT; - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); + /* enqueue this event */ + ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return; -} +} /* GENERAL STATUS *************************************************************/ void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) { - sngss7_chan_data_t *sngss7_info ; - ftdm_channel_t *ftdmchan; + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + sngss7_event_data_t *sngss7_event = NULL; /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { @@ -756,1209 +415,32 @@ void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint return; } - SS7_FUNC_TRACE_ENTER(__FUNCTION__); + /* initalize the sngss7_event */ + sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); + if (sngss7_event == NULL) { + SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return; + } + memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - switch (evntType) { - /**************************************************************************/ - case SIT_STA_REATTEMPT: /* reattempt indication */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Reattempt indication\n"); - handle_reattempt(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_ERRORIND: /* error indication */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Error indication\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_CONTCHK: /* continuity check */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx COT start\n"); - handle_cot_start(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CONTREP: /* continuity report */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx COT report\n"); - handle_cot(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_STPCONTIN: /* stop continuity */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx COT stop\n"); - handle_cot_stop(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CGQRYRSP: /* circuit grp query response from far end forwarded to upper layer by ISUP */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CQM\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_CONFUSION: /* confusion */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CFN\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_LOOPBACKACK: /* loop-back acknowledge */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LPA\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_CIRRSRVREQ: /* circuit reservation request */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Ckt Resveration req\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_CIRRSRVACK: /* circuit reservation acknowledgement */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Ckt Res ack\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_CIRBLOREQ: /* circuit blocking request */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx BLO\n"); - handle_blo_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CIRBLORSP: /* circuit blocking response */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx BLA\n"); - handle_blo_rsp(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CIRUBLREQ: /* circuit unblocking request */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx UBL\n"); - handle_ubl_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CIRUBLRSP: /* circuit unblocking response */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx UBA\n"); - handle_ubl_rsp(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CIRRESREQ: /* circuit reset request - RSC */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx RSC\n"); - handle_rsc_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CIRLOCRES: /* reset initiated locally by the software */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Local RSC\n"); - handle_local_rsc_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CIRRESRSP: /* circuit reset response */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx RSC-RLC\n"); - handle_rsc_rsp(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - 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)); - 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)); - break; - /**************************************************************************/ - case SIT_STA_CGQRYREQ: /* circuit group query request */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CQM\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - 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)); - 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)); - break; - /**************************************************************************/ - case SIT_STA_GRSREQ: /* circuit group reset request */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx GRS\n"); - handle_grs_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CIRUNEQPD: /* circuit unequipped indication */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx UCIC\n"); - handle_ucic(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_GRSRSP: /* circuit group reset response */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx GRA\n"); - handle_grs_rsp(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_PAUSEIND: /* pause indication */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx SUS\n"); - handle_pause(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_RESUMEIND: /* resume indication */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx RES\n"); - handle_resume(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_USRPARTA: /* user part available */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx UPA\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_RMTUSRUNAV: /* remote user not available */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Remote User not Available\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_MTPCONG0: /* congestion indication level 0 */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Congestion L0\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_MTPCONG1: /* congestion indication level 1 */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Congestion L1\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_MTPCONG2: /* congestion indication level 2 */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Congestion L2\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_MTPCONG3: /* congestion indication level 3 */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Congestion L3\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_MTPSTPCONG: /* stop congestion indication level 0 */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Stop Congestion\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_CIRLOCALBLOIND: /* Mngmt local blocking */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Local BLO\n"); - handle_local_blk(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CIRLOCALUBLIND: /* Mngmt local unblocking */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Local UBL\n"); - handle_local_ubl(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_OVERLOAD: /* Overload */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Overload\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_LMCGBREQ: /* when LM requests ckt grp blocking */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LM CGB\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_LMCGUREQ: /* when LM requests ckt grp unblocking */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LM CGU\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_LMGRSREQ: /* when LM requests ckt grp reset */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LM RSC\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - 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)); - break; - /**************************************************************************/ - 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)); - break; - /**************************************************************************/ - case SIT_STA_CIRLOCGRS: /* group reset initiated locally by the software */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Local GRS\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - default: - SS7_INFO("[SNG-CC] Received Unknown indication %d\n", evntType); - break; - } /* switch (evntType) */ + /* fill in the sngss7_event struct */ + sngss7_event->spInstId = spInstId; + sngss7_event->suInstId = suInstId; + sngss7_event->circuit = circuit; + sngss7_event->globalFlg = globalFlg; + sngss7_event->evntType = evntType; + sngss7_event->event_id = SNGSS7_STA_IND_EVENT; + if (siStaEvnt != NULL) { + memcpy(&sngss7_event->event.siStaEvnt, siStaEvnt, sizeof(*siStaEvnt)); + } + + /* enqueue this event */ + ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return; } -/******************************************************************************/ -static ftdm_status_t handle_reattempt(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; - ftdm_channel_t *ftdmchan = NULL; - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for ISUP circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* 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_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - /* glare, throw the flag, go to down state*/ - sngss7_set_flag(sngss7_info, FLAG_GLARE); - - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_CANCEL); - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_pause(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; - ftdm_channel_t *ftdmchan = NULL; - int infId; - int i; - - /* extract the affect infId from the circuit structure */ - infId = g_ftdm_sngss7_data.cfg.isupCkt[circuit].infId; - - /* go through all the circuits now and find any other circuits on this infId */ - i = 1; - while (g_ftdm_sngss7_data.cfg.isupCkt[i].id != 0) { - - /* check that the infId matches and that this is not a siglink */ - if ((g_ftdm_sngss7_data.cfg.isupCkt[i].infId == infId) && - (g_ftdm_sngss7_data.cfg.isupCkt[i].type == VOICE)) { - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(i, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - i++; - continue; - } - - /* 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 */ - ftdm_mutex_unlock(ftdmchan->mutex); - - } /* if (g_ftdm_sngss7_data.cfg.isupCkt[i].infId == infId) */ - - /* move to the next circuit */ - i++; - - } /* while (g_ftdm_sngss7_data.cfg.isupCkt[i].id != 0) */ - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_resume(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; - ftdm_channel_t *ftdmchan = NULL; - int infId; - int i; - - /* extract the affect infId from the circuit structure */ - infId = g_ftdm_sngss7_data.cfg.isupCkt[circuit].infId; - - /* go through all the circuits now and find any other circuits on this infId */ - i = 1; - while (g_ftdm_sngss7_data.cfg.isupCkt[i].id != 0) { - - /* check that the infId matches and that this is not a siglink */ - if ((g_ftdm_sngss7_data.cfg.isupCkt[i].infId == infId) && - (g_ftdm_sngss7_data.cfg.isupCkt[i].type == VOICE)) { - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(i, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - i++; - continue; - } - - /* 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 */ - sngss7_set_flag(sngss7_info, FLAG_INFID_RESUME); - - /* 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 */ - ftdm_mutex_unlock(ftdmchan->mutex); - - } /* if (g_ftdm_sngss7_data.cfg.isupCkt[i].infId == infId) */ - - /* move to the next circuit */ - i++; - - } /* while (g_ftdm_sngss7_data.cfg.isupCkt[i].id != 0) */ - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_cot_start(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; - ftdm_channel_t *ftdmchan = NULL; - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* 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_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - /* open the channel if it is not open */ - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) { - if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) { - SS7_ERROR("Failed to open CIC %d for COT test!\n", sngss7_info->circuit->cic); - /* KONRAD FIX ME */ - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - } - - /* tell the core to loop the channel */ - ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_LOOP, NULL); - - /* switch to the IN_LOOP state */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IN_LOOP); - - /* store the sngss7 ids */ - if (suInstId == 0) { - sngss7_info->suInstId = get_unique_id(); - } else { - sngss7_info->suInstId = suInstId; - } - sngss7_info->spInstId = spInstId; - sngss7_info->globalFlg = globalFlg; - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_cot_stop(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; - ftdm_channel_t *ftdmchan = NULL; - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* 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_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - /* tell the core to stop looping the channel */ - ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL); - - /* exit out of the LOOP state to the last state */ - ftdm_set_state_locked(ftdmchan, ftdmchan->last_state); - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_cot(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FUNCTION__); - - if ( (siStaEvnt->contInd.eh.pres > 0) && (siStaEvnt->contInd.contInd.pres > 0)) { - SS7_INFO("Continuity Test result for CIC = %d (span %d, chan %d) is: \"%s\"\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - g_ftdm_sngss7_data.cfg.isupCkt[circuit].span, - g_ftdm_sngss7_data.cfg.isupCkt[circuit].chan, - (siStaEvnt->contInd.contInd.val) ? "PASS" : "FAIL"); - } else { - SS7_ERROR("Recieved Continuity report containing no results!\n"); - } - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ - - -/******************************************************************************/ -static ftdm_status_t handle_blo_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; - ftdm_channel_t *ftdmchan = NULL; - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* 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_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - /* check if the circuit is already blocked or not */ - if (sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) { - SS7_WARN("Received BLO on circuit that is already blocked!\n"); - } - - /* throw the ckt block flag */ - sngss7_set_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); - - /* set the channel to suspended state */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_blo_rsp(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; - ftdm_channel_t *ftdmchan = NULL; - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* 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_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - /* KONRAD FIX ME */ - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_ubl_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; - ftdm_channel_t *ftdmchan = NULL; - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* 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_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - /* check if the channel is blocked */ - if (!(sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX))) { - SS7_WARN("Received UBL on circuit that is not blocked!\n"); - } - - /* throw the unblock flag */ - sngss7_set_flag(sngss7_info, FLAG_CKT_MN_UNBLK_RX); - - /* clear the block flag */ - sngss7_clear_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); - - /* set the channel to suspended state */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_ubl_rsp(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; - ftdm_channel_t *ftdmchan = NULL; - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* 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_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - /* KONRAD FIX ME */ - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_rsc_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; - ftdm_channel_t *ftdmchan = NULL; - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* 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_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - /* throw the reset flag */ - sngss7_set_flag(sngss7_info, FLAG_RESET_RX); - - 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); - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_local_rsc_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; - ftdm_channel_t *ftdmchan = NULL; - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* 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_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - /* throw the reset flag */ - sngss7_set_flag(sngss7_info, FLAG_RESET_RX); - - 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); - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_rsc_rsp(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; - ftdm_channel_t *ftdmchan = NULL; - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* 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_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - switch (ftdmchan->state) { - /**********************************************************************/ - case FTDM_CHANNEL_STATE_RESTART: - - if ( sngss7_test_flag(sngss7_info, FLAG_RESET_TX) ) { - /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ - sngss7_set_flag(sngss7_info, FLAG_RESET_TX_RSP); - - /* go to DOWN */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } else { - SS7_ERROR("Received RSC-RLC but we're not waiting on a RSC-RLC on CIC #, dropping\n", sngss7_info->circuit->cic); - } - - break; - /**********************************************************************/ - case FTDM_CHANNEL_STATE_DOWN: - - /* do nothing, just drop the message */ - SS7_DEBUG("Receveived RSC-RLC in down state, dropping\n"); - - break; - /**********************************************************************/ - case FTDM_CHANNEL_STATE_TERMINATING: - case FTDM_CHANNEL_STATE_HANGUP: - case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: - - /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ - sngss7_set_flag(sngss7_info, FLAG_RESET_TX_RSP); - - /* go to DOWN */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - - break; - /**********************************************************************/ - default: - /* ITU Q764-2.9.5.1.c -> release the circuit */ - if ((siStaEvnt != NULL) && - (siStaEvnt->causeDgn.eh.pres ==PRSNT_NODEF) && - (siStaEvnt->causeDgn.causeVal.pres == PRSNT_NODEF)) { - ftdmchan->caller_data.hangup_cause = siStaEvnt->causeDgn.causeVal.val; - } else { - ftdmchan->caller_data.hangup_cause = 98; /* Message not compatiable with call state */ - } - - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - break; - /**********************************************************************/ - } - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} -/******************************************************************************/ -static ftdm_status_t handle_grs_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; - ftdm_channel_t *ftdmchan = NULL; - sngss7_span_data_t *span = NULL; - int range; - int x; - - 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; - } - - /* extract the range value from the event structure */ - if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.range.pres == PRSNT_NODEF)) { - range = siStaEvnt->rangStat.range.val; - } else { - SS7_ERROR("Received GRS with no range value on CIC = %d\n", sngss7_info->circuit->cic); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* 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; - }; - - /* fill in the span structure for this circuit */ - span = ftdmchan->span->mod_data; - span->grs.circuit = circuit; - span->grs.range = range; - - SS7_DEBUG_CHAN(ftdmchan, "Rx GRS (%d:%d)\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - (g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic + range)); - - /* flag the channel as having received a reset */ - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX); - - 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); - - } - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_grs_rsp(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; - ftdm_channel_t *ftdmchan = NULL; - int range; - int x; - - /* extract the range value from the event structure */ - if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.range.pres == PRSNT_NODEF)) { - range = siStaEvnt->rangStat.range.val; - } else { - SS7_ERROR("Received GRA with no range value on CIC = %d\n", sngss7_info->circuit->cic); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* go through all the circuits in the range */ - 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", circuit); - 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; - }; - - SS7_DEBUG_CHAN(ftdmchan, "Rx GRA (%d:%d)\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - (g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic + range)); - - switch (ftdmchan->state) { - /**********************************************************************/ - case FTDM_CHANNEL_STATE_RESTART: - - /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); - - /* go to DOWN */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - - break; - /**********************************************************************/ - case FTDM_CHANNEL_STATE_DOWN: - - /* do nothing, just drop the message */ - SS7_DEBUG("Receveived GRA in down state, dropping\n"); - - break; - /**********************************************************************/ - case FTDM_CHANNEL_STATE_TERMINATING: - case FTDM_CHANNEL_STATE_HANGUP: - case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: - - /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); - - break; - /**********************************************************************/ - default: - /* ITU Q764-2.9.5.1.c -> release the circuit */ - if ((siStaEvnt != NULL) && - (siStaEvnt->causeDgn.eh.pres ==PRSNT_NODEF) && - (siStaEvnt->causeDgn.causeVal.pres == PRSNT_NODEF)) { - ftdmchan->caller_data.hangup_cause = siStaEvnt->causeDgn.causeVal.val; - } else { - ftdmchan->caller_data.hangup_cause = 98; /* Message not compatiable with call state */ - } - - /* go to terminating to hang up the call */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - break; - /**********************************************************************/ - } - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - } /* for (( x = 0; x < (circuit + range); x++) */ - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_local_blk(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; - ftdm_channel_t *ftdmchan = NULL; - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* 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_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - /* check if the circuit is already blocked or not */ - if (sngss7_test_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX)) { - SS7_WARN("Received local BLO on circuit that is already blocked!\n"); - } - - /* throw the ckt block flag */ - sngss7_set_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX); - - /* set the channel to suspended state */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_local_ubl(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; - ftdm_channel_t *ftdmchan = NULL; - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* 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_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - /* check if the circuit is already blocked or not */ - if (sngss7_test_flag(sngss7_info, FLAG_CKT_LC_UNBLK_RX)) { - SS7_WARN("Received local UBL on circuit that is already unblocked!\n"); - } - - /* throw the ckt block flag */ - sngss7_set_flag(sngss7_info, FLAG_CKT_LC_UNBLK_RX); - - /* set the channel to suspended state */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_ucic(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; - ftdm_channel_t *ftdmchan = NULL; - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* 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_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - /* throw the ckt block flag */ - sngss7_set_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK); - - /* set the channel to suspended state */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - - -/******************************************************************************/ -#if 0 -{ - SS7_FUNC_TRACE_ENTER(__FUNCTION__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* 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_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - }; - - /* fill in here */ - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -#endif /******************************************************************************/ /******************************************************************************/ 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 fc2c1a66b7..a9851bda3f 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 @@ -46,7 +46,8 @@ ftdm_sngss7_data_t g_ftdm_sngss7_data; /* PROTOTYPES *****************************************************************/ static void *ftdm_sangoma_ss7_run (ftdm_thread_t * me, void *obj); -static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan); +static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan); +static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_event); static ftdm_status_t ftdm_sangoma_ss7_stop (ftdm_span_t * span); static ftdm_status_t ftdm_sangoma_ss7_start (ftdm_span_t * span); @@ -268,11 +269,12 @@ ftdm_state_map_t sangoma_ss7_state_map = { /* MONITIOR THREADS ***********************************************************/ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj) { - ftdm_interrupt_t *ftdm_sangoma_ss7_int = NULL; + 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_span_data_t *sngss7_span = 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); @@ -280,31 +282,53 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj) /* set IN_THREAD flag so that we know this thread is running */ ftdm_set_flag (ftdmspan, FTDM_SPAN_IN_THREAD); - /* get an interrupt queue for this span */ - if (ftdm_queue_get_interrupt (ftdmspan->pendingchans, &ftdm_sangoma_ss7_int) != FTDM_SUCCESS) { - SS7_CRITICAL ("Failed to get a ftdm_interrupt for span = %d!\n", ftdmspan->span_id); + /* get an interrupt queue for this span for channel state changes */ + if (ftdm_queue_get_interrupt (ftdmspan->pendingchans, &ftdm_sangoma_ss7_int[0]) != FTDM_SUCCESS) { + SS7_CRITICAL ("Failed to get a ftdm_interrupt for span = %d for channel state changes!\n", ftdmspan->span_id); + goto ftdm_sangoma_ss7_run_exit; + } + + /* get an interrupt queue for this span for Trillium events */ + if (ftdm_queue_get_interrupt (sngss7_span->event_queue, &ftdm_sangoma_ss7_int[1]) != FTDM_SUCCESS) { + SS7_CRITICAL ("Failed to get a ftdm_interrupt for span = %d for Trillium event queue!\n", ftdmspan->span_id); goto ftdm_sangoma_ss7_run_exit; } while (ftdm_running () && !(ftdm_test_flag (ftdmspan, FTDM_SPAN_STOP_THREAD))) { - /* find out why we returned from the interrupt queue */ - switch ((ftdm_interrupt_wait (ftdm_sangoma_ss7_int, 100))) { + /* check the channel state queue for an event*/ + switch ((ftdm_interrupt_multiple_wait(ftdm_sangoma_ss7_int, 2, 100))) { /**********************************************************************/ - case FTDM_SUCCESS: /* there was a state change on the span */ - /* process all pending state changes */ + case FTDM_SUCCESS: /* process all pending state changes */ + /* clean out all pending channel state changes */ while ((ftdmchan = ftdm_queue_dequeue (ftdmspan->pendingchans))) { /* double check that this channel has a state change pending */ if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) { + /*first lock the channel */ + ftdm_mutex_lock(ftdmchan->mutex); + ftdm_sangoma_ss7_process_state_change (ftdmchan); + + /* unlock the channel */ + ftdm_mutex_unlock (ftdmchan->mutex); } else { - SS7_ERROR("ftdm_core reported state change, but state change flag not set on ft-span = %d, ft-chan = %d\n", + /* since we handle state changes again after handling the trillium queue + * this can occur since we'll clear the flag for the event but can't pop + * the channel out of pendingchans + */ +/* SS7_ERROR("ftdm_core reported state change, but state change flag not set on ft-span = %d, ft-chan = %d\n", ftdmchan->physical_span_id, - ftdmchan->physical_chan_id); + ftdmchan->physical_chan_id);*/ } }/* while ((ftdmchan = ftdm_queue_dequeue(ftdmspan->pendingchans))) */ + /* clean out all pending stack events */ + while ((sngss7_event = ftdm_queue_dequeue(sngss7_span->event_queue))) { + ftdm_sangoma_ss7_process_stack_event(sngss7_event); + ftdm_safe_free(sngss7_event); + }/* while ((sngss7_event = ftdm_queue_dequeue(ftdmspan->signal_data->event_queue))) */ + break; /**********************************************************************/ case FTDM_TIMEOUT: @@ -412,6 +436,81 @@ ftdm_sangoma_ss7_run_exit: return NULL; } +/******************************************************************************/ +static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_event) +{ + sngss7_chan_data_t *sngss7_info ; + ftdm_channel_t *ftdmchan; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(sngss7_event->circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", sngss7_event->circuit); + return; + } + + /* now that we have the right channel...put a lock on it so no-one else can use it */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* figure out the type of event and send it to the right handler */ + switch (sngss7_event->event_id) { + /**************************************************************************/ + case (SNGSS7_CON_IND_EVENT): + handle_con_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siConEvnt); + break; + /**************************************************************************/ + case (SNGSS7_CON_CFM_EVENT): + handle_con_cfm(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siConEvnt); + break; + /**************************************************************************/ + case (SNGSS7_CON_STA_EVENT): + handle_con_sta(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siCnStEvnt, sngss7_event->evntType); + break; + /**************************************************************************/ + case (SNGSS7_REL_IND_EVENT): + handle_rel_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siRelEvnt); + break; + /**************************************************************************/ + case (SNGSS7_REL_CFM_EVENT): + handle_rel_cfm(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siRelEvnt); + break; + /**************************************************************************/ + case (SNGSS7_DAT_IND_EVENT): + handle_dat_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siInfoEvnt); + break; + /**************************************************************************/ + case (SNGSS7_FAC_IND_EVENT): + handle_fac_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->evntType, &sngss7_event->event.siFacEvnt); + break; + /**************************************************************************/ + case (SNGSS7_FAC_CFM_EVENT): + handle_fac_cfm(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->evntType, &sngss7_event->event.siFacEvnt); + break; + /**************************************************************************/ + case (SNGSS7_UMSG_IND_EVENT): + handle_umsg_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit); + break; + /**************************************************************************/ + case (SNGSS7_STA_IND_EVENT): + handle_sta_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->globalFlg, sngss7_event->evntType, &sngss7_event->event.siStaEvnt); + break; + /**************************************************************************/ + default: + SS7_ERROR("Unknown Event Id!\n"); + break; + /**************************************************************************/ + } /* switch (sngss7_event->event_id) */ + + /* while there's a state change present on this channel process it */ + while (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) { + ftdm_sangoma_ss7_process_state_change(ftdmchan); + } + + /* unlock the channel */ + ftdm_mutex_unlock(ftdmchan->mutex); + + return; +} + /******************************************************************************/ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) { @@ -426,9 +525,6 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) sigev.span_id = ftdmchan->span_id; sigev.channel = ftdmchan; - /*first lock the channel */ - ftdm_mutex_lock (ftdmchan->mutex); - SS7_DEBUG_CHAN(ftdmchan, "ftmod_sangoma_ss7 processing state %s\n", ftdm_channel_state2str (ftdmchan->state)); /* clear the state change flag...since we might be setting a new state */ @@ -1052,9 +1148,6 @@ suspend_goto_restart: /**************************************************************************/ }/*switch (ftdmchan->state) */ - /*unlock */ - ftdm_mutex_unlock (ftdmchan->mutex); - return; } @@ -1254,7 +1347,7 @@ static ftdm_status_t ftdm_sangoma_ss7_stop(ftdm_span_t * span) /* SIG_FUNCTIONS ***************************************************************/ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_ss7_span_config) { - sngss7_span_data_t *ss7_span_info; + sngss7_span_data_t *ss7_span_info; ftdm_log (FTDM_LOG_INFO, "Configuring ftmod_sangoma_ss7 span = %s(%d)...\n", span->name, @@ -1264,29 +1357,20 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_ss7_span_config) ss7_span_info = ftdm_calloc (1, sizeof (sngss7_span_data_t)); /* create a timer schedule */ - if (ftdm_sched_create (&ss7_span_info->sched, "SngSS7_Schedule")) { - SS7_CRITICAL ("Unable to create timer schedule!\n"); + if (ftdm_sched_create(&ss7_span_info->sched, "SngSS7_Schedule")) { + SS7_CRITICAL("Unable to create timer schedule!\n"); return FTDM_FAIL; } /* start the free run thread for the schedule */ - if (ftdm_sched_free_run (ss7_span_info->sched)) { - SS7_CRITICAL ("Unable to schedule free run!\n"); + if (ftdm_sched_free_run(ss7_span_info->sched)) { + SS7_CRITICAL("Unable to schedule free run!\n"); return FTDM_FAIL; } - /* attach the span info to the span */ - span->mod_data = ss7_span_info; - - /* parse the configuration and apply to the global config structure */ - if (ftmod_ss7_parse_xml(ftdm_parameters, span)) { - ftdm_log (FTDM_LOG_CRIT, "Failed to parse configuration!\n"); - return FTDM_FAIL; - } - - /* configure libsngss7 */ - if (ft_to_sngss7_cfg_all()) { - ftdm_log (FTDM_LOG_CRIT, "Failed to configure LibSngSS7!\n"); + /* create an event queue for this span */ + if ((ftdm_queue_create(&(ss7_span_info)->event_queue, SNGSS7_EVENT_QUEUE_SIZE)) != FTDM_SUCCESS) { + SS7_CRITICAL("Unable to create event queue!\n"); return FTDM_FAIL; } @@ -1302,9 +1386,22 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_ss7_span_config) span->get_channel_sig_status = ftdm_sangoma_ss7_get_sig_status; span->set_channel_sig_status = ftdm_sangoma_ss7_set_sig_status; span->state_map = &sangoma_ss7_state_map; + span->mod_data = ss7_span_info; ftdm_set_flag (span, FTDM_SPAN_USE_CHAN_QUEUE); + /* parse the configuration and apply to the global config structure */ + if (ftmod_ss7_parse_xml(ftdm_parameters, span)) { + ftdm_log (FTDM_LOG_CRIT, "Failed to parse configuration!\n"); + return FTDM_FAIL; + } + + /* configure libsngss7 */ + if (ft_to_sngss7_cfg_all()) { + ftdm_log (FTDM_LOG_CRIT, "Failed to configure LibSngSS7!\n"); + return FTDM_FAIL; + } + ftdm_log (FTDM_LOG_INFO, "Finished configuring ftmod_sangoma_ss7 span = %s(%d)...\n", span->name, span->span_id); @@ -1336,7 +1433,7 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_ss7_init) /* message (IAM, ACM, ANM, etc) trace initizalation */ g_ftdm_sngss7_data.message_trace = 1; - g_ftdm_sngss7_data.message_trace_level = 7; + g_ftdm_sngss7_data.message_trace_level = 6; /* setup the call backs needed by Sangoma_SS7 library */ sng_event.cc.sng_con_ind = sngss7_con_ind; 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 6bfc38e588..3bf12ae307 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 @@ -50,12 +50,26 @@ /******************************************************************************/ /* DEFINES ********************************************************************/ -#define MAX_NAME_LEN 10 -#define MAX_PATH 255 +#define MAX_NAME_LEN 10 +#define MAX_PATH 255 -#define MAX_CIC_LENGTH 5 -#define MAX_CIC_MAP_LENGTH 1000 +#define MAX_CIC_LENGTH 5 +#define MAX_CIC_MAP_LENGTH 1000 +#define SNGSS7_EVENT_QUEUE_SIZE 100 + +typedef enum { + SNGSS7_CON_IND_EVENT = 0, + SNGSS7_CON_CFM_EVENT, + SNGSS7_CON_STA_EVENT, + SNGSS7_REL_IND_EVENT, + SNGSS7_REL_CFM_EVENT, + SNGSS7_DAT_IND_EVENT, + SNGSS7_FAC_IND_EVENT, + SNGSS7_FAC_CFM_EVENT, + SNGSS7_UMSG_IND_EVENT, + SNGSS7_STA_IND_EVENT +} sng_event_type_t; typedef enum { VOICE = 0, @@ -334,8 +348,31 @@ typedef struct sngss7_chan_data { typedef struct sngss7_span_data { ftdm_sched_t *sched; sngss7_group_data_t grs; + ftdm_queue_t *event_queue; }sngss7_span_data_t; +typedef struct sngss7_event_data +{ + uint32_t event_id; + uint32_t spId; + uint32_t suId; + uint32_t spInstId; + uint32_t suInstId; + uint32_t circuit; + uint8_t globalFlg; + uint8_t evntType; + union + { + SiConEvnt siConEvnt; + SiCnStEvnt siCnStEvnt; + SiRelEvnt siRelEvnt; + SiInfoEvnt siInfoEvnt; + SiFacEvnt siFacEvnt; + SiStaEvnt siStaEvnt; + } event; +} sngss7_event_data_t; + + typedef enum { @@ -441,6 +478,36 @@ void sngss7_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); void sngss7_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit); +ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt); +ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCnStEvnt *siCnStEvnt, uint8_t evntType); +ftdm_status_t handle_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt); +ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt); +ftdm_status_t handle_rel_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt); +ftdm_status_t handle_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiInfoEvnt *siInfoEvnt); +ftdm_status_t handle_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt); +ftdm_status_t handle_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt); +ftdm_status_t handle_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit); +ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); + +ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_cot_start(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_cot_stop(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_cot(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_local_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_rsc_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_grs_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_blo_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_blo_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_ubl_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_ubl_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +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); + uint8_t copy_cgPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum); uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum); uint8_t copy_cdPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum);