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)
--- /dev/null
+/*
+ * Copyright (c) 2009 Konrad Hammel <konrad@sangoma.com>
+ * 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:
+ */
+/******************************************************************************/
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 ******************************************************************/
{
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)) {
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 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) */
+ /* 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));
- 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;
}
/******************************************************************************/
{
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)) {
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));
+
+ /* 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));
- /* 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;
}
/******************************************************************************/
{
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)) {
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 ? */
-
- /* 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;
- /**************************************************************************/
- }
+ /* 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));
- /* 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;
}
/******************************************************************************/
{
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)) {
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);
- 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;
-}
-
-
-/******************************************************************************/
-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;
-
- /* 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);
+ /* 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));
- /* 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);
+ /* 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));
- 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);
+ /* 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)
+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;
-
- /* 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;
- }
-
- /* 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;
-}
-
-/******************************************************************************/
-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)) {
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);
- 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;
-}
-
-/******************************************************************************/
-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;
-
- /* 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);
+ /* 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));
- /* 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");
+ /* 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));
- /* 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)
+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;
-
- /* 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;
- }
-
- /* 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;
-}
-
-/* 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;
+ 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)) {
return;
}
- 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;
-}
-
-/******************************************************************************/
-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);
+ /* 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 FTDM_FAIL;
+ return;
}
+ memset(sngss7_event, 0x0, sizeof(*sngss7_event));
- /* 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 */
+ /* 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 again before we exit */
- 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 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)
+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 = NULL;
- ftdm_channel_t *ftdmchan = NULL;
+ 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)) {
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");
+ return;
}
- /* 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);
+ /* 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 FTDM_FAIL;
+ return;
}
+ memset(sngss7_event, 0x0, sizeof(*sngss7_event));
- /* now that we have the right channel...put a lock on it so no-one else can use it */
- ftdm_mutex_lock(ftdmchan->mutex);
+ /* 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));
- /* 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);
+ /* 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 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)
+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 = NULL;
- ftdm_channel_t *ftdmchan = NULL;
+ 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)) {
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;
- /**************************************************************************/
+ return;
}
- /* 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);
+ /* 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 FTDM_FAIL;
+ return;
}
+ memset(sngss7_event, 0x0, sizeof(*sngss7_event));
- /* 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);
+ /* 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));
- 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);
+ /* 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 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)
+void sngss7_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit)
{
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
- sngss7_chan_data_t *sngss7_info = NULL;
- ftdm_channel_t *ftdmchan = NULL;
+ 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)) {
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;
+ return;
}
- /* 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);
+ /* 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 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);
-
+ return;
}
+ memset(sngss7_event, 0x0, sizeof(*sngss7_event));
- 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__);
+ /* 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;
- 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;
- }
+ /* enqueue this event */
+ ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event);
- /* 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)
+/* GENERAL STATUS *************************************************************/
+void sngss7_sta_ind(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_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)) {
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");
+ return;
}
- /* 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);
+ /* 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 FTDM_FAIL;
+ return;
}
+ memset(sngss7_event, 0x0, sizeof(*sngss7_event));
- /* 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;
+ /* 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));
}
- /* 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);
+ /* 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 FTDM_SUCCESS;
}
-/******************************************************************************/
-#endif
/******************************************************************************/
/******************************************************************************/
/* 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);
/* 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);
/* 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:
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)
{
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 */
/**************************************************************************/
}/*switch (ftdmchan->state) */
- /*unlock */
- ftdm_mutex_unlock (ftdmchan->mutex);
-
return;
}
/* 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,
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;
}
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);
/* 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;
/******************************************************************************/
/* 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,
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 {
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);