]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
freetdm: implemented Trillium stack message queueing
authorKonrad Hammel <konrad@sangoma.com>
Tue, 31 Aug 2010 21:33:42 +0000 (17:33 -0400)
committerDavid Yat Sin <dyatsin@sangoma.com>
Wed, 1 Sep 2010 19:02:56 +0000 (15:02 -0400)
libs/freetdm/Makefile.am
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c [new file with mode: 0644]
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h

index 6ccc473ce3fbbf700b41cea06dbc8e63fd1bfa4e..33a8b96936a7424ea1035efe4d88909dcb88b7ba 100644 (file)
@@ -268,18 +268,19 @@ ftmod_pritap_la_LIBADD  = $(MYLIB)
 endif
 
 if SNGSS7
-ftmod_sangoma_ss7_la_SOURCES =  $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c \
-                               $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c \
-                               $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c \
-                               $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c \
-                               $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c \
-                               $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c \
-                               $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_timers.c \
-                               $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c \
-                               $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c \
-                               $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c \
-                               $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sts.c \
-                               $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c
+ftmod_sangoma_ss7_la_SOURCES = $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c \
+                                                               $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c \
+                                                               $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c \
+                                                               $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c \
+                                                               $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c \
+                                                               $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c \
+                                                               $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c \
+                                                               $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_timers.c \
+                                                               $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c \
+                                                               $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c \
+                                                               $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c \
+                                                               $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sts.c \
+                                                               $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c
 ftmod_sangoma_ss7_la_CFLAGS  = $(AM_CFLAGS) $(MY_CFLAGS) -D_GNU_SOURCE
 ftmod_sangoma_ss7_la_LDFLAGS = -module  -avoid-version -lsng_ss7
 ftmod_sangoma_ss7_la_LIBADD  = $(MYLIB)
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c
new file mode 100644 (file)
index 0000000..d1f3a8b
--- /dev/null
@@ -0,0 +1,1930 @@
+/*
+ * 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:
+ */
+/******************************************************************************/
index 98554db6a42c52d3a72ae686221dabcc74dca314..34893cf5aaff3cd40eba285ef2ac5c6888ec5f33 100644 (file)
@@ -53,31 +53,6 @@ void sngss7_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint
 void sngss7_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt);
 void sngss7_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit);
 
-static ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
-static ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
-static ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
-
-static ftdm_status_t handle_cot_start(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
-static ftdm_status_t handle_cot_stop(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
-static ftdm_status_t handle_cot(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
-
-static ftdm_status_t handle_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
-static ftdm_status_t handle_local_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
-static ftdm_status_t handle_rsc_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
-
-static ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
-static ftdm_status_t handle_grs_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
-
-static ftdm_status_t handle_blo_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
-static ftdm_status_t handle_blo_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
-static ftdm_status_t handle_ubl_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
-static ftdm_status_t handle_ubl_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
-
-static ftdm_status_t handle_local_blk(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
-static ftdm_status_t handle_local_ubl(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
-
-static ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
-
 /******************************************************************************/
 
 /* FUNCTIONS ******************************************************************/
@@ -85,8 +60,9 @@ void sngss7_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCo
 {
        SS7_FUNC_TRACE_ENTER(__FUNCTION__);
 
-       sngss7_chan_data_t  *sngss7_info ;
-       ftdm_channel_t    *ftdmchan;
+       sngss7_chan_data_t      *sngss7_info = NULL;
+       ftdm_channel_t          *ftdmchan = NULL;
+       sngss7_event_data_t     *sngss7_event = NULL;
 
        /* get the ftdmchan and ss7_chan_data from the circuit */
        if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
@@ -95,119 +71,26 @@ void sngss7_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCo
                return;
        }
 
-       /* now that we have the right channel...put a lock on it so no-one else can use it */
-       ftdm_mutex_lock(ftdmchan->mutex);
-
-       /* check if there is a pending state change, give it a bit to clear */
-       if (check_for_state_change(ftdmchan)) {
-               SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic);
-               ftdm_mutex_unlock(ftdmchan->mutex);
+       /* initalize the sngss7_event */
+       sngss7_event = ftdm_malloc(sizeof(*sngss7_event));
+       if (sngss7_event == NULL) {
+               SS7_ERROR("Failed to allocate memory for sngss7_event!\n");
                SS7_FUNC_TRACE_EXIT(__FUNCTION__);
-               SS7_ASSERT;
-       };
-
-       SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx IAM\n");
-
-       /* check if the circuit has a remote block */
-       if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) ||
-               (sngss7_test_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX)) ||
-               (sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) {
-
-               /* as per Q.764, 2.8.2.3 xiv ... remove the block from this channel */
-               sngss7_clear_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX);
-               sngss7_clear_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX);
-               sngss7_clear_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX);
-
-               /* KONRAD FIX ME : check in case there is a ckt and grp block */
+               return;
        }
+       memset(sngss7_event, 0x0, sizeof(*sngss7_event));
 
-       /* check whether the ftdm channel is in a state to accept a call */
-       switch (ftdmchan->state) {
-       /**************************************************************************/
-       case (FTDM_CHANNEL_STATE_DOWN):  /* only state it is fully valid to get IAM */
-
-               /* fill in the 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;
 }
 
 /******************************************************************************/
@@ -215,8 +98,9 @@ void sngss7_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCo
 {
        SS7_FUNC_TRACE_ENTER(__FUNCTION__);
 
-       sngss7_chan_data_t  *sngss7_info ;
-       ftdm_channel_t    *ftdmchan;
+       sngss7_chan_data_t      *sngss7_info = NULL;
+       ftdm_channel_t          *ftdmchan = NULL;
+       sngss7_event_data_t     *sngss7_event = NULL;
 
        /* get the ftdmchan and ss7_chan_data from the circuit */
        if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
@@ -225,59 +109,26 @@ void sngss7_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCo
                return;
        }
 
-       /* now that we have the right channel...put a lock on it so no-one else can use it */
-       ftdm_mutex_lock(ftdmchan->mutex);
-
-       /* check if there is a pending state change, give it a bit to clear */
-       if (check_for_state_change(ftdmchan)) {
-               SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic);
-               ftdm_mutex_unlock(ftdmchan->mutex);
+       /* initalize the sngss7_event */
+       sngss7_event = ftdm_malloc(sizeof(*sngss7_event));
+       if (sngss7_event == NULL) {
+               SS7_ERROR("Failed to allocate memory for sngss7_event!\n");
                SS7_FUNC_TRACE_EXIT(__FUNCTION__);
-               SS7_ASSERT;
-       };
-
-
-       /* check whether the ftdm channel is in a state to accept a call */
-       switch (ftdmchan->state) {
-       /**************************************************************************/
-       case FTDM_CHANNEL_STATE_PROGRESS:
-       case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
-
-               SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx ANM\n");
-
-               /* go to UP */
-               ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP);
-
-               break;
-       /**************************************************************************/
-       case FTDM_CHANNEL_STATE_DIALING:
-
-               SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CON\n");
-
-               /* go to UP */
-               ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP);
-
-               break;          
-       /**************************************************************************/
-       default:        /* incorrect state...reset the CIC */
-
-               SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx ANM/CON\n");
-
-               /* throw the TX reset flag */
-               sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX);
-
-               /* go to RESTART */
-               ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
-
-               break;
-       /**************************************************************************/
+               return;
        }
+       memset(sngss7_event, 0x0, sizeof(*sngss7_event));
+
+       /* 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;
 }
 
 /******************************************************************************/
@@ -285,8 +136,9 @@ void sngss7_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCn
 {
        SS7_FUNC_TRACE_ENTER(__FUNCTION__);
 
-       sngss7_chan_data_t  *sngss7_info ;
-       ftdm_channel_t    *ftdmchan;
+       sngss7_chan_data_t      *sngss7_info = NULL;
+       ftdm_channel_t          *ftdmchan = NULL;
+       sngss7_event_data_t     *sngss7_event = NULL;
 
        /* get the ftdmchan and ss7_chan_data from the circuit */
        if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
@@ -295,159 +147,27 @@ void sngss7_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCn
                return;
        }
 
-       /* now that we have the right channel...put a lock on it so no-one else can use it */
-       ftdm_mutex_lock(ftdmchan->mutex);
-
-       /* check if there is a pending state change, give it a bit to clear */
-       if (check_for_state_change(ftdmchan)) {
-               SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic);
-               ftdm_mutex_unlock(ftdmchan->mutex);
+       /* initalize the sngss7_event */
+       sngss7_event = ftdm_malloc(sizeof(*sngss7_event));
+       if (sngss7_event == NULL) {
+               SS7_ERROR("Failed to allocate memory for sngss7_event!\n");
                SS7_FUNC_TRACE_EXIT(__FUNCTION__);
-               SS7_ASSERT;
+               return;
        }
+       memset(sngss7_event, 0x0, sizeof(*sngss7_event));
 
-       switch (evntType) {
-       /**************************************************************************/
-       case (ADDRCMPLT):
-               SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx ACM\n");
-               switch (ftdmchan->state) {
-               /**********************************************************************/
-               case FTDM_CHANNEL_STATE_DIALING:
-                       /* KONRAD: should we confirm the instance ids ? */
-
-                       /* 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;
 }
 
 /******************************************************************************/
@@ -455,8 +175,9 @@ void sngss7_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRe
 {
        SS7_FUNC_TRACE_ENTER(__FUNCTION__);
 
-       sngss7_chan_data_t  *sngss7_info ;
-       ftdm_channel_t    *ftdmchan;
+       sngss7_chan_data_t      *sngss7_info = NULL;
+       ftdm_channel_t          *ftdmchan = NULL;
+       sngss7_event_data_t     *sngss7_event = NULL;
 
        /* get the ftdmchan and ss7_chan_data from the circuit */
        if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
@@ -465,186 +186,36 @@ void sngss7_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRe
                return;
        }
 
-       /* now that we have the right channel...put a lock on it so no-one else can use it */
-       ftdm_mutex_lock(ftdmchan->mutex);
-
-       /* check if there is a pending state change, give it a bit to clear */
-       if (check_for_state_change(ftdmchan)) {
-               SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic);
-               ftdm_mutex_unlock(ftdmchan->mutex);
-               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)) {
@@ -653,101 +224,36 @@ void sngss7_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint
                return;
        }
 
-       /* now that we have the right channel...put a lock on it so no-one else can use it */
-       ftdm_mutex_lock(ftdmchan->mutex);
-
-       /* check if there is a pending state change, give it a bit to clear */
-       if (check_for_state_change(ftdmchan)) {
-               SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic);
-               ftdm_mutex_unlock(ftdmchan->mutex);
-               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)) {
@@ -756,1209 +262,185 @@ void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint
                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
 /******************************************************************************/
 
 /******************************************************************************/
index fc2c1a66b724771e953a0b6e960691ff5cb9794a..a9851bda3f6f7447ab155469169f61f9435ca749 100644 (file)
@@ -46,7 +46,8 @@ ftdm_sngss7_data_t g_ftdm_sngss7_data;
 
 /* PROTOTYPES *****************************************************************/
 static void *ftdm_sangoma_ss7_run (ftdm_thread_t * me, void *obj);
-static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan);
+static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan);
+static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_event);
 
 static ftdm_status_t ftdm_sangoma_ss7_stop (ftdm_span_t * span);
 static ftdm_status_t ftdm_sangoma_ss7_start (ftdm_span_t * span);
@@ -268,11 +269,12 @@ ftdm_state_map_t sangoma_ss7_state_map = {
 /* MONITIOR THREADS ***********************************************************/
 static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
 {
-       ftdm_interrupt_t        *ftdm_sangoma_ss7_int = NULL;
+       ftdm_interrupt_t        *ftdm_sangoma_ss7_int[2];
        ftdm_span_t             *ftdmspan = (ftdm_span_t *) obj;
        ftdm_channel_t          *ftdmchan = NULL;
        sngss7_chan_data_t  *sngss7_info = NULL;
-       sngss7_span_data_t      *sngss7_span = NULL;
+       sngss7_event_data_t     *sngss7_event = NULL;
+       sngss7_span_data_t      *sngss7_span = (sngss7_span_data_t *)ftdmspan->mod_data;
        int                             i;
 
        ftdm_log (FTDM_LOG_INFO, "ftmod_sangoma_ss7 monitor thread for span=%u started.\n", ftdmspan->span_id);
@@ -280,31 +282,53 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
        /* set IN_THREAD flag so that we know this thread is running */
        ftdm_set_flag (ftdmspan, FTDM_SPAN_IN_THREAD);
 
-       /* get an interrupt queue for this span */
-       if (ftdm_queue_get_interrupt (ftdmspan->pendingchans, &ftdm_sangoma_ss7_int) != FTDM_SUCCESS) {
-               SS7_CRITICAL ("Failed to get a ftdm_interrupt for span = %d!\n", ftdmspan->span_id);
+       /* get an interrupt queue for this span for channel state changes */
+       if (ftdm_queue_get_interrupt (ftdmspan->pendingchans, &ftdm_sangoma_ss7_int[0]) != FTDM_SUCCESS) {
+               SS7_CRITICAL ("Failed to get a ftdm_interrupt for span = %d for channel state changes!\n", ftdmspan->span_id);
+               goto ftdm_sangoma_ss7_run_exit;
+       }
+
+       /* get an interrupt queue for this span for Trillium events */
+       if (ftdm_queue_get_interrupt (sngss7_span->event_queue, &ftdm_sangoma_ss7_int[1]) != FTDM_SUCCESS) {
+               SS7_CRITICAL ("Failed to get a ftdm_interrupt for span = %d for Trillium event queue!\n", ftdmspan->span_id);
                goto ftdm_sangoma_ss7_run_exit;
        }
 
        while (ftdm_running () && !(ftdm_test_flag (ftdmspan, FTDM_SPAN_STOP_THREAD))) {
 
-               /* find out why we returned from the interrupt queue */ 
-               switch ((ftdm_interrupt_wait (ftdm_sangoma_ss7_int, 100))) {
+               /* check the channel state queue for an event*/ 
+               switch ((ftdm_interrupt_multiple_wait(ftdm_sangoma_ss7_int, 2, 100))) {
                /**********************************************************************/
-               case FTDM_SUCCESS:      /* there was a state change on the span */
-                                                       /* process all pending state changes */
+               case FTDM_SUCCESS:      /* process all pending state changes */
 
+                       /* clean out all pending channel state changes */
                        while ((ftdmchan = ftdm_queue_dequeue (ftdmspan->pendingchans))) {
                                /* double check that this channel has a state change pending */
                                if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
+                                       /*first lock the channel */
+                                       ftdm_mutex_lock(ftdmchan->mutex);
+
                                        ftdm_sangoma_ss7_process_state_change (ftdmchan);
+
+                                       /* unlock the channel */
+                                       ftdm_mutex_unlock (ftdmchan->mutex);                            
                                } else {
-                                       SS7_ERROR("ftdm_core reported state change, but state change flag not set on ft-span = %d, ft-chan = %d\n",
+                                       /* since we handle state changes again after handling the trillium queue
+                                        * this can occur since we'll clear the flag for the event but can't pop
+                                        * the channel out of pendingchans
+                                        */
+/*                                     SS7_ERROR("ftdm_core reported state change, but state change flag not set on ft-span = %d, ft-chan = %d\n",
                                                                ftdmchan->physical_span_id,
-                                                               ftdmchan->physical_chan_id);
+                                                               ftdmchan->physical_chan_id);*/
                                }
                        }/* while ((ftdmchan = ftdm_queue_dequeue(ftdmspan->pendingchans)))  */
 
+                       /* clean out all pending stack events */
+                       while ((sngss7_event = ftdm_queue_dequeue(sngss7_span->event_queue))) {
+                               ftdm_sangoma_ss7_process_stack_event(sngss7_event);
+                               ftdm_safe_free(sngss7_event);
+                       }/* while ((sngss7_event = ftdm_queue_dequeue(ftdmspan->signal_data->event_queue))) */
+
                        break;
                /**********************************************************************/
                case FTDM_TIMEOUT:
@@ -412,6 +436,81 @@ ftdm_sangoma_ss7_run_exit:
        return NULL;
 }
 
+/******************************************************************************/
+static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_event)
+{
+       sngss7_chan_data_t  *sngss7_info ;
+       ftdm_channel_t    *ftdmchan;
+
+       /* get the ftdmchan and ss7_chan_data from the circuit */
+       if (extract_chan_data(sngss7_event->circuit, &sngss7_info, &ftdmchan)) {
+               SS7_ERROR("Failed to extract channel data for circuit = %d!\n", sngss7_event->circuit);
+               return;
+       }
+
+       /* now that we have the right channel...put a lock on it so no-one else can use it */
+       ftdm_mutex_lock(ftdmchan->mutex);
+
+       /* figure out the type of event and send it to the right handler */
+       switch (sngss7_event->event_id) {
+       /**************************************************************************/
+       case (SNGSS7_CON_IND_EVENT):
+               handle_con_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit,  &sngss7_event->event.siConEvnt);
+               break;
+       /**************************************************************************/
+       case (SNGSS7_CON_CFM_EVENT):
+               handle_con_cfm(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit,  &sngss7_event->event.siConEvnt);
+               break;
+       /**************************************************************************/
+       case (SNGSS7_CON_STA_EVENT):
+               handle_con_sta(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit,  &sngss7_event->event.siCnStEvnt, sngss7_event->evntType);
+               break;
+       /**************************************************************************/
+       case (SNGSS7_REL_IND_EVENT):
+               handle_rel_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit,  &sngss7_event->event.siRelEvnt);
+               break;
+       /**************************************************************************/
+       case (SNGSS7_REL_CFM_EVENT):
+               handle_rel_cfm(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit,  &sngss7_event->event.siRelEvnt);
+               break;
+       /**************************************************************************/
+       case (SNGSS7_DAT_IND_EVENT):
+               handle_dat_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit,  &sngss7_event->event.siInfoEvnt);
+               break;
+       /**************************************************************************/
+       case (SNGSS7_FAC_IND_EVENT):
+               handle_fac_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->evntType,  &sngss7_event->event.siFacEvnt);
+               break;
+       /**************************************************************************/
+       case (SNGSS7_FAC_CFM_EVENT):
+               handle_fac_cfm(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->evntType,  &sngss7_event->event.siFacEvnt);
+               break;
+       /**************************************************************************/
+       case (SNGSS7_UMSG_IND_EVENT):
+               handle_umsg_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit);
+               break;
+       /**************************************************************************/
+       case (SNGSS7_STA_IND_EVENT):
+               handle_sta_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->globalFlg, sngss7_event->evntType,  &sngss7_event->event.siStaEvnt);
+               break;
+       /**************************************************************************/
+       default:
+               SS7_ERROR("Unknown Event Id!\n");
+               break;
+       /**************************************************************************/
+       } /* switch (sngss7_event->event_id) */
+
+       /* while there's a state change present on this channel process it */
+       while (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
+               ftdm_sangoma_ss7_process_state_change(ftdmchan);
+       }
+
+       /* unlock the channel */
+       ftdm_mutex_unlock(ftdmchan->mutex);
+
+       return;
+}
+
 /******************************************************************************/
 static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
 {
@@ -426,9 +525,6 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
        sigev.span_id = ftdmchan->span_id;
        sigev.channel = ftdmchan;
 
-       /*first lock the channel */
-       ftdm_mutex_lock (ftdmchan->mutex);
-
        SS7_DEBUG_CHAN(ftdmchan, "ftmod_sangoma_ss7 processing state %s\n", ftdm_channel_state2str (ftdmchan->state));
 
        /* clear the state change flag...since we might be setting a new state */
@@ -1052,9 +1148,6 @@ suspend_goto_restart:
        /**************************************************************************/
        }/*switch (ftdmchan->state) */
 
-       /*unlock */
-       ftdm_mutex_unlock (ftdmchan->mutex);
-
        return;
 }
 
@@ -1254,7 +1347,7 @@ static ftdm_status_t ftdm_sangoma_ss7_stop(ftdm_span_t * span)
 /* SIG_FUNCTIONS ***************************************************************/
 static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_ss7_span_config)
 {
-       sngss7_span_data_t *ss7_span_info;
+       sngss7_span_data_t      *ss7_span_info;
 
        ftdm_log (FTDM_LOG_INFO, "Configuring ftmod_sangoma_ss7 span = %s(%d)...\n",
                                                                span->name,
@@ -1264,29 +1357,20 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_ss7_span_config)
        ss7_span_info = ftdm_calloc (1, sizeof (sngss7_span_data_t));
 
        /* create a timer schedule */
-       if (ftdm_sched_create (&ss7_span_info->sched, "SngSS7_Schedule")) {
-               SS7_CRITICAL ("Unable to create timer schedule!\n");
+       if (ftdm_sched_create(&ss7_span_info->sched, "SngSS7_Schedule")) {
+               SS7_CRITICAL("Unable to create timer schedule!\n");
                return FTDM_FAIL;
        }
 
        /* start the free run thread for the schedule */
-       if (ftdm_sched_free_run (ss7_span_info->sched)) {
-               SS7_CRITICAL ("Unable to schedule free run!\n");
+       if (ftdm_sched_free_run(ss7_span_info->sched)) {
+               SS7_CRITICAL("Unable to schedule free run!\n");
                return FTDM_FAIL;
        }
 
-       /* attach the span info to the span */
-       span->mod_data = ss7_span_info;
-
-       /* parse the configuration and apply to the global config structure */
-       if (ftmod_ss7_parse_xml(ftdm_parameters, span)) {
-               ftdm_log (FTDM_LOG_CRIT, "Failed to parse configuration!\n");
-               return FTDM_FAIL;
-       }
-
-       /* configure libsngss7 */
-       if (ft_to_sngss7_cfg_all()) {
-               ftdm_log (FTDM_LOG_CRIT, "Failed to configure LibSngSS7!\n");
+       /* create an event queue for this span */
+       if ((ftdm_queue_create(&(ss7_span_info)->event_queue, SNGSS7_EVENT_QUEUE_SIZE)) != FTDM_SUCCESS) {
+               SS7_CRITICAL("Unable to create event queue!\n");
                return FTDM_FAIL;
        }
 
@@ -1302,9 +1386,22 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_ss7_span_config)
        span->get_channel_sig_status    = ftdm_sangoma_ss7_get_sig_status;
        span->set_channel_sig_status    = ftdm_sangoma_ss7_set_sig_status;
        span->state_map                                 = &sangoma_ss7_state_map;
+       span->mod_data                                  = ss7_span_info;
 
        ftdm_set_flag (span, FTDM_SPAN_USE_CHAN_QUEUE);
 
+       /* parse the configuration and apply to the global config structure */
+       if (ftmod_ss7_parse_xml(ftdm_parameters, span)) {
+               ftdm_log (FTDM_LOG_CRIT, "Failed to parse configuration!\n");
+               return FTDM_FAIL;
+       }
+
+       /* configure libsngss7 */
+       if (ft_to_sngss7_cfg_all()) {
+               ftdm_log (FTDM_LOG_CRIT, "Failed to configure LibSngSS7!\n");
+               return FTDM_FAIL;
+       }
+
        ftdm_log (FTDM_LOG_INFO, "Finished configuring ftmod_sangoma_ss7 span = %s(%d)...\n",
                                                                span->name,
                                                                span->span_id);
@@ -1336,7 +1433,7 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_ss7_init)
 
        /* message (IAM, ACM, ANM, etc) trace initizalation */
        g_ftdm_sngss7_data.message_trace = 1;
-       g_ftdm_sngss7_data.message_trace_level = 7;
+       g_ftdm_sngss7_data.message_trace_level = 6;
 
        /* setup the call backs needed by Sangoma_SS7 library */
        sng_event.cc.sng_con_ind = sngss7_con_ind;
index 6bfc38e588faa2cc8c63b7d1c9aca16ab8e2c895..3bf12ae3077b7ac21e728a455970e9ebeec02855 100644 (file)
 /******************************************************************************/
 
 /* DEFINES ********************************************************************/
-#define MAX_NAME_LEN           10
-#define MAX_PATH                       255
+#define MAX_NAME_LEN                   10
+#define MAX_PATH                               255
 
-#define MAX_CIC_LENGTH         5
-#define MAX_CIC_MAP_LENGTH     1000 
+#define MAX_CIC_LENGTH                 5
+#define MAX_CIC_MAP_LENGTH             1000 
 
+#define SNGSS7_EVENT_QUEUE_SIZE        100
+
+typedef enum {
+       SNGSS7_CON_IND_EVENT = 0,
+       SNGSS7_CON_CFM_EVENT,
+       SNGSS7_CON_STA_EVENT,
+       SNGSS7_REL_IND_EVENT,
+       SNGSS7_REL_CFM_EVENT,
+       SNGSS7_DAT_IND_EVENT,
+       SNGSS7_FAC_IND_EVENT,
+       SNGSS7_FAC_CFM_EVENT,
+       SNGSS7_UMSG_IND_EVENT,
+       SNGSS7_STA_IND_EVENT
+} sng_event_type_t;
 
 typedef enum {
        VOICE = 0,
@@ -334,8 +348,31 @@ typedef struct sngss7_chan_data {
 typedef struct sngss7_span_data {
        ftdm_sched_t                    *sched;
        sngss7_group_data_t             grs;
+       ftdm_queue_t                    *event_queue;
 }sngss7_span_data_t;
 
+typedef struct sngss7_event_data
+{
+       uint32_t                event_id;
+       uint32_t                spId;
+       uint32_t                suId;
+       uint32_t                spInstId;
+       uint32_t                suInstId;
+       uint32_t                circuit;
+       uint8_t                 globalFlg;
+       uint8_t                 evntType;
+       union
+       {
+               SiConEvnt       siConEvnt;
+               SiCnStEvnt      siCnStEvnt;
+               SiRelEvnt       siRelEvnt;
+               SiInfoEvnt      siInfoEvnt;
+               SiFacEvnt       siFacEvnt;
+               SiStaEvnt       siStaEvnt;
+       } event;
+} sngss7_event_data_t;
+
+
 
 
 typedef enum {
@@ -441,6 +478,36 @@ void sngss7_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint
 void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
 void sngss7_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit);
 
+ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt);
+ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCnStEvnt *siCnStEvnt, uint8_t evntType);
+ftdm_status_t handle_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt);
+ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt);
+ftdm_status_t handle_rel_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt);
+ftdm_status_t handle_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiInfoEvnt *siInfoEvnt);
+ftdm_status_t handle_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt);
+ftdm_status_t handle_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt);
+ftdm_status_t handle_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit);
+ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
+
+ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
+ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
+ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
+ftdm_status_t handle_cot_start(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
+ftdm_status_t handle_cot_stop(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
+ftdm_status_t handle_cot(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
+ftdm_status_t handle_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
+ftdm_status_t handle_local_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
+ftdm_status_t handle_rsc_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
+ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
+ftdm_status_t handle_grs_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
+ftdm_status_t handle_blo_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
+ftdm_status_t handle_blo_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
+ftdm_status_t handle_ubl_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
+ftdm_status_t handle_ubl_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
+ftdm_status_t handle_local_blk(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
+ftdm_status_t handle_local_ubl(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
+ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
+
 uint8_t copy_cgPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum);
 uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum);
 uint8_t copy_cdPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum);