root/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. handle_con_ind
  2. handle_con_sta
  3. handle_con_cfm
  4. handle_rel_ind
  5. handle_rel_cfm
  6. handle_dat_ind
  7. handle_fac_ind
  8. handle_fac_cfm
  9. handle_umsg_ind
  10. handle_susp_ind
  11. handle_resm_ind
  12. handle_sta_ind
  13. handle_reattempt
  14. handle_pause
  15. handle_resume
  16. handle_cot_start
  17. handle_cot_stop
  18. handle_cot
  19. handle_blo_req
  20. handle_blo_rsp
  21. handle_ubl_req
  22. handle_ubl_rsp
  23. handle_rsc_req
  24. handle_local_rsc_req
  25. handle_rsc_rsp
  26. handle_grs_req
  27. handle_grs_rsp
  28. handle_local_blk
  29. handle_local_ubl
  30. handle_ucic
  31. handle_cgb_req
  32. handle_cgu_req
  33. handle_olm_msg

   1 /*
   2  * Copyright (c) 2009 Konrad Hammel <konrad@sangoma.com>
   3  * All rights reserved.
   4  *
   5  * Redistribution and use in source and binary forms|with or without
   6  * modification|are permitted provided that the following conditions
   7  * are met:
   8  *
   9  * * Redistributions of source code must retain the above copyright
  10  * notice|this list of conditions and the following disclaimer.
  11  *
  12  * * Redistributions in binary form must reproduce the above copyright
  13  * notice|this list of conditions and the following disclaimer in the
  14  * documentation and/or other materials provided with the distribution.
  15  *
  16  * * Neither the name of the original author; nor the names of any contributors
  17  * may be used to endorse or promote products derived from this software
  18  * without specific prior written permission.
  19  *
  20  *
  21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES|INCLUDING|BUT NOT
  23  * LIMITED TO|THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  24  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
  25  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT|INDIRECT|INCIDENTAL|SPECIAL,
  26  * EXEMPLARY|OR CONSEQUENTIAL DAMAGES (INCLUDING|BUT NOT LIMITED TO,
  27  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE|DATA|OR
  28  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  29  * LIABILITY|WHETHER IN CONTRACT|STRICT LIABILITY|OR TORT (INCLUDING
  30  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  31  * SOFTWARE|EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32  */
  33 
  34 /* INCLUDE ********************************************************************/
  35 #include "ftmod_sangoma_ss7_main.h"
  36 /******************************************************************************/
  37 
  38 /* DEFINES ********************************************************************/
  39 /******************************************************************************/
  40 
  41 /* GLOBALS ********************************************************************/
  42 /******************************************************************************/
  43 
  44 /* PROTOTYPES *****************************************************************/
  45 ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt);
  46 ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCnStEvnt *siCnStEvnt, uint8_t evntType);
  47 ftdm_status_t handle_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt);
  48 ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt);
  49 ftdm_status_t handle_rel_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt);
  50 ftdm_status_t handle_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiInfoEvnt *siInfoEvnt);
  51 ftdm_status_t handle_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt);
  52 ftdm_status_t handle_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt);
  53 ftdm_status_t handle_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit);
  54 ftdm_status_t handle_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt);
  55 ftdm_status_t handle_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiResmEvnt *siResmEvnt);
  56 ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
  57 
  58 ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
  59 ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
  60 ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
  61 ftdm_status_t handle_cot_start(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
  62 ftdm_status_t handle_cot_stop(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
  63 ftdm_status_t handle_cot(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
  64 ftdm_status_t handle_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
  65 ftdm_status_t handle_local_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
  66 ftdm_status_t handle_rsc_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
  67 ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
  68 ftdm_status_t handle_grs_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
  69 ftdm_status_t handle_blo_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
  70 ftdm_status_t handle_blo_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
  71 ftdm_status_t handle_ubl_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
  72 ftdm_status_t handle_ubl_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
  73 ftdm_status_t handle_local_blk(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
  74 ftdm_status_t handle_local_ubl(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
  75 ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
  76 ftdm_status_t handle_cgb_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
  77 ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
  78 ftdm_status_t handle_olm_msg(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
  79 /******************************************************************************/
  80 
  81 /* FUNCTIONS ******************************************************************/
  82 ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt)
  83 {
  84         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
  85 
  86         sngss7_chan_data_t  *sngss7_info = NULL;
  87         ftdm_channel_t          *ftdmchan = NULL;
  88         char                            nadi[2];
  89 
  90         memset(nadi, '\0', sizeof(nadi));
  91 
  92         /* get the ftdmchan and ss7_chan_data from the circuit */
  93         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
  94                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
  95                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
  96                 return FTDM_FAIL;
  97         }
  98 
  99         /* lock the channel */
 100         ftdm_mutex_lock(ftdmchan->mutex);
 101 
 102         if (sngss7_test_flag(sngss7_info, FLAG_GLARE)) {
 103                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx IAM (glare)\n", sngss7_info->circuit->cic);
 104         } else {
 105                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx IAM\n", sngss7_info->circuit->cic);
 106         }
 107 
 108         /* check if the circuit has a remote block */
 109         if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) ||
 110                 (sngss7_test_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX)) ||
 111                 (sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) {
 112 
 113                 /* as per Q.764, 2.8.2.3 xiv ... remove the block from this channel */
 114                 sngss7_clear_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX);
 115                 sngss7_clear_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX);
 116                 sngss7_clear_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX);
 117 
 118                 /* KONRAD FIX ME : check in case there is a ckt and grp block */
 119         }
 120 
 121         /* check whether the ftdm channel is in a state to accept a call */
 122         switch (ftdmchan->state) {
 123         /**************************************************************************/
 124         case (FTDM_CHANNEL_STATE_DOWN):  /* only state it is valid to get IAM (except if there is glare */
 125 
 126                 /* check if there is any reason why we can't use this channel */
 127                 if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE)) {
 128                         /* channel is already requested for use by the ftdm core */
 129                         goto handle_glare;
 130                 } else if(ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
 131                         /* channel is not inuse but we can't open it...fail the call */
 132                         SS7_ERROR("Failed to open span: %d, chan: %d\n",
 133                                                 ftdmchan->physical_span_id,
 134                                                 ftdmchan->physical_chan_id);
 135 
 136                          /* set the flag to indicate this hangup is started from the local side */
 137                         sngss7_set_flag(sngss7_info, FLAG_LOCAL_REL);
 138 
 139                         ftdmchan->caller_data.hangup_cause = 41;
 140 
 141                         /* move the state to CANCEL */
 142                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
 143 
 144                 } else {
 145 
 146                         /* fill in the channels SS7 Stack information */
 147                         sngss7_info->suInstId = get_unique_id();
 148                         sngss7_info->spInstId = spInstId;
 149 
 150                         /* fill in calling party information */
 151                         if (siConEvnt->cgPtyNum.eh.pres) {
 152                                 if (siConEvnt->cgPtyNum.addrSig.pres) {
 153                                         /* fill in cid_num */
 154                                         copy_tknStr_from_sngss7(siConEvnt->cgPtyNum.addrSig,
 155                                                                                         ftdmchan->caller_data.cid_num.digits, 
 156                                                                                         siConEvnt->cgPtyNum.oddEven);
 157 
 158                                         /* fill in cid Name */
 159                                         ftdm_set_string(ftdmchan->caller_data.cid_name, ftdmchan->caller_data.cid_num.digits);
 160 
 161                                         /* fill in ANI */
 162                                         ftdm_set_string(ftdmchan->caller_data.ani.digits, ftdmchan->caller_data.cid_num.digits);
 163                                 }
 164 
 165                                 if (siConEvnt->cgPtyNum.scrnInd.pres) {
 166                                         /* fill in the screening indication value */
 167                                         ftdmchan->caller_data.screen = siConEvnt->cgPtyNum.scrnInd.val;
 168                                 }
 169 
 170                                 if (siConEvnt->cgPtyNum.presRest.pres) {
 171                                         /* fill in the presentation value */
 172                                         ftdmchan->caller_data.pres = siConEvnt->cgPtyNum.presRest.val;
 173                                 }       
 174                         } else {
 175                                 SS7_INFO_CHAN(ftdmchan,"No Calling party (ANI) information in IAM!%s\n", " ");
 176                         }
 177 
 178                         /* fill in called party infomation */
 179                         if (siConEvnt->cdPtyNum.eh.pres) {
 180                                 if (siConEvnt->cdPtyNum.addrSig.pres) {
 181                                         /* fill in the called number/dnis */
 182                                         copy_tknStr_from_sngss7(siConEvnt->cdPtyNum.addrSig, 
 183                                                                                         ftdmchan->caller_data.dnis.digits, 
 184                                                                                         siConEvnt->cdPtyNum.oddEven);
 185                                 }
 186                         } else {
 187                                 SS7_INFO_CHAN(ftdmchan,"No Called party (DNIS) information in IAM!%s\n", " ");
 188                         }
 189 
 190                         /* fill in rdnis information*/
 191                         if (siConEvnt->redirgNum.eh.pres) {
 192                                 if (siConEvnt->redirgNum.addrSig.pres) {
 193                                         /* fill in the rdnis digits */
 194                                         copy_tknStr_from_sngss7(siConEvnt->redirgNum.addrSig, 
 195                                                                                         ftdmchan->caller_data.rdnis.digits, 
 196                                                                                         siConEvnt->cgPtyNum.oddEven);
 197                                 }
 198                         }   else {
 199                                 SS7_DEBUG_CHAN(ftdmchan,"No RDNIS party information in IAM!%s\n", " ");
 200                         }
 201 
 202                         /* fill in the TMR/bearer capability */
 203                         if (siConEvnt->txMedReq.eh.pres) {
 204                                 if (siConEvnt->txMedReq.trMedReq.pres) {
 205                                         /* fill in the bearer type */
 206                                         ftdmchan->caller_data.bearer_capability = siConEvnt->txMedReq.trMedReq.val;
 207                                 }
 208                         } else {
 209                                 SS7_DEBUG_CHAN(ftdmchan,"No TMR/Bearer Cap information in IAM!%s\n", " ");
 210                         }
 211 
 212                         /* add any special variables for the dialplan */
 213                         sprintf(nadi, "%d", siConEvnt->cgPtyNum.natAddrInd.val);
 214                         ftdm_call_add_var(&ftdmchan->caller_data, "ss7_clg_nadi", nadi);
 215 
 216                         sprintf(nadi, "%d", siConEvnt->cdPtyNum.natAddrInd.val);
 217                         ftdm_call_add_var(&ftdmchan->caller_data, "ss7_cld_nadi", nadi);
 218 
 219 
 220                         /* check if a COT test is requested */
 221                         if ((siConEvnt->natConInd.eh.pres) && 
 222                                 (siConEvnt->natConInd.contChkInd.pres) &&
 223                                 (siConEvnt->natConInd.contChkInd.val)) {
 224 
 225                                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Found COT Request\n", sngss7_info->circuit->cic);
 226 
 227                                 /* tell the core to loop the channel */
 228                                 ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_LOOP, NULL);
 229 
 230                                 /* move to in loop state */
 231                                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IN_LOOP);
 232                         } else {
 233                                 /* set the state of the channel to collecting...the rest is done by the chan monitor */
 234                                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_COLLECT);
 235                         }
 236 
 237                 } /* if (channel is usable */
 238 
 239                 break;
 240         /**************************************************************************/
 241         case (FTDM_CHANNEL_STATE_DIALING):
 242         case (FTDM_CHANNEL_STATE_TERMINATING):
 243         case (FTDM_CHANNEL_STATE_HANGUP):
 244         case (FTDM_CHANNEL_STATE_HANGUP_COMPLETE):
 245 handle_glare:
 246                 /* the core already has plans for this channel...glare */
 247                 SS7_INFO_CHAN(ftdmchan, "Got IAM on channel that is already inuse (state=%s|inuse=%d)...glare!\n", 
 248                                                                 ftdm_channel_state2str (ftdmchan->state),
 249                                                                 ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE));
 250 
 251                 /* save the info so that we can use it later on */
 252                 sngss7_info->glare.spInstId = spInstId;
 253                 sngss7_info->glare.circuit = circuit;
 254                 memcpy(&sngss7_info->glare.iam, siConEvnt, sizeof(*siConEvnt));
 255 
 256                 if (!(sngss7_test_flag(sngss7_info, FLAG_GLARE))) {
 257                         /* glare, throw the flag */
 258                         sngss7_set_flag(sngss7_info, FLAG_GLARE);
 259                 
 260                         /* setup the hangup cause */
 261                         ftdmchan->caller_data.hangup_cause = 34;        /* Circuit Congrestion */
 262                 
 263                         /* this is a remote hangup request */
 264                         sngss7_set_flag(sngss7_info, FLAG_REMOTE_REL);
 265                 
 266                         /* move the state of the channel to Terminating to end the call */
 267                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
 268                 } /* if (!(sngss7_test_flag(sngss7_info, FLAG_GLARE))) */
 269                 break;
 270         /**************************************************************************/
 271         default:        /* should not have gotten an IAM while in this state */
 272                 SS7_ERROR_CHAN(ftdmchan, "Got IAM on channel in invalid state(%s)...reset!\n", ftdm_channel_state2str (ftdmchan->state));
 273 
 274                 /* reset the cic */
 275                 sngss7_set_flag(sngss7_info, FLAG_RESET_TX);
 276 
 277                 /* move the state of the channel to RESTART to force a reset */
 278                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
 279 
 280                 break;
 281         /**************************************************************************/
 282         } /* switch (ftdmchan->state) */
 283 
 284         /* unlock the channel */
 285         ftdm_mutex_unlock(ftdmchan->mutex);
 286 
 287         SS7_FUNC_TRACE_EXIT(__FUNCTION__);
 288         return FTDM_SUCCESS;
 289 }
 290 
 291 /******************************************************************************/
 292 ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCnStEvnt *siCnStEvnt, uint8_t evntType)
 293 {
 294         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
 295 
 296         sngss7_chan_data_t  *sngss7_info ;
 297         ftdm_channel_t    *ftdmchan;
 298 
 299         /* get the ftdmchan and ss7_chan_data from the circuit */
 300         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
 301                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
 302                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
 303                 return FTDM_FAIL;
 304         }
 305 
 306         /* lock the channel */
 307         ftdm_mutex_lock(ftdmchan->mutex);
 308 
 309         switch (evntType) {
 310         /**************************************************************************/
 311         case (ADDRCMPLT):
 312                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx ACM\n", sngss7_info->circuit->cic);
 313 
 314                 switch (ftdmchan->state) {
 315                 /**********************************************************************/
 316                 case FTDM_CHANNEL_STATE_DIALING:
 317                         /* KONRAD: should we confirm the instance ids ? */
 318 
 319                         /* need to grab the sp instance id */ 
 320                         sngss7_info->spInstId = spInstId;
 321 
 322                         if ((siCnStEvnt->optBckCalInd.eh.pres) && 
 323                                 (siCnStEvnt->optBckCalInd.inbndInfoInd.pres)) {
 324 
 325                                 if (siCnStEvnt->optBckCalInd.inbndInfoInd.val) {
 326                                         /* go to PROGRESS_MEDIA */
 327                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
 328                                 } else {
 329                                         /* go to PROGRESS */
 330                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
 331                                 } /* if (inband) */
 332                         } else {
 333                                 /* go to PROGRESS_MEDIA */
 334                                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
 335                         }
 336                         
 337                         break;
 338                 /**********************************************************************/
 339                 default:        /* incorrect state...reset the CIC */
 340                         SS7_ERROR_CHAN(ftdmchan, "RX ACM in invalid state :%s...resetting CIC\n", 
 341                                                                         ftdm_channel_state2str (ftdmchan->state));
 342 
 343                         /* reset the cic */
 344                         sngss7_set_flag(sngss7_info, FLAG_RESET_TX);
 345 
 346                         /* go to RESTART */
 347                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
 348                         break;
 349                 /**********************************************************************/
 350                 } /* switch (ftdmchan->state) */
 351 
 352                 break;
 353         /**************************************************************************/
 354         case (MODIFY):
 355                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx MODIFY\n", sngss7_info->circuit->cic);
 356                 break;
 357         /**************************************************************************/
 358         case (MODCMPLT):
 359                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx MODIFY-COMPLETE\n", sngss7_info->circuit->cic);
 360                 break;
 361         /**************************************************************************/
 362         case (MODREJ):
 363                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx MODIFY-REJECT\n", sngss7_info->circuit->cic);
 364                 break;
 365         /**************************************************************************/
 366         case (PROGRESS):
 367                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CPG\n", sngss7_info->circuit->cic);
 368                 break;
 369         /**************************************************************************/
 370         case (FRWDTRSFR):
 371                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx FOT\n", sngss7_info->circuit->cic);
 372                 break;
 373         /**************************************************************************/
 374         case (INFORMATION):
 375                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx INF\n", sngss7_info->circuit->cic);
 376                 break;
 377         /**************************************************************************/
 378         case (INFORMATREQ):
 379                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx INR\n", sngss7_info->circuit->cic);
 380                 break;
 381         /**************************************************************************/
 382         case (SUBSADDR):
 383                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx SAM\n", sngss7_info->circuit->cic);
 384 
 385                 /* check the channel state */
 386                 switch (ftdmchan->state) {
 387                 /**********************************************************************/
 388                 case (FTDM_CHANNEL_STATE_COLLECT):
 389                         
 390                         /* confirm that the event contains the subsquent number field */
 391                         if (siCnStEvnt->subNum.eh.pres && siCnStEvnt->subNum.addrSig.pres) {
 392                                 /* add the digits to the ftdm channel variable */
 393                                 append_tknStr_from_sngss7(siCnStEvnt->subNum.addrSig, 
 394                                                                                         ftdmchan->caller_data.dnis.digits, 
 395                                                                                         siCnStEvnt->subNum.oddEven);
 396                         } else {
 397                                 SS7_INFO_CHAN(ftdmchan,"No Called party (DNIS) information in SAM!%s\n", " ");
 398                         }
 399 
 400                         /* go to idle so that collect state is processed again */
 401                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE);
 402 
 403                         break;
 404                 /**********************************************************************/
 405                 default:
 406                         SS7_ERROR_CHAN(ftdmchan, "RX SAM in invalid state :%s...ignoring\n", 
 407                                                                                 ftdm_channel_state2str (ftdmchan->state));
 408                         break;
 409                 /**********************************************************************/
 410                 } /* switch (ftdmchan->state) */
 411 
 412                 break;
 413         /**************************************************************************/
 414         case (EXIT):
 415                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx EXIT\n", sngss7_info->circuit->cic);
 416                 break;
 417         /**************************************************************************/
 418         case (NETRESMGT):
 419                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx NRM\n", sngss7_info->circuit->cic);
 420                 break;
 421         /**************************************************************************/
 422         case (IDENTREQ):
 423                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx IDR\n", sngss7_info->circuit->cic);
 424                 break;
 425         /**************************************************************************/
 426         case (IDENTRSP):
 427                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx IRS\n", sngss7_info->circuit->cic);
 428                 break;
 429         /**************************************************************************/
 430         case (MALCLLPRNT):
 431                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx MALICIOUS CALL\n", sngss7_info->circuit->cic);
 432                 break;
 433         /**************************************************************************/
 434         case (CHARGE):
 435                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CRG\n", sngss7_info->circuit->cic);
 436                 break;
 437         /**************************************************************************/
 438         case (TRFFCHGE):
 439                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CRG-TARIFF\n", sngss7_info->circuit->cic);
 440                 break;
 441         /**************************************************************************/
 442         case (CHARGEACK):
 443                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CRG-ACK\n", sngss7_info->circuit->cic);
 444                 break;
 445         /**************************************************************************/
 446         case (CALLOFFMSG):
 447                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CALL-OFFER\n", sngss7_info->circuit->cic);
 448                 break;
 449         /**************************************************************************/
 450         case (LOOPPRVNT):
 451                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx LOP\n", sngss7_info->circuit->cic);
 452                 break;
 453         /**************************************************************************/
 454         case (TECT_TIMEOUT):
 455                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx ECT-Timeout\n", sngss7_info->circuit->cic);
 456                 break;
 457         /**************************************************************************/
 458         case (RINGSEND):
 459                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx RINGING-SEND\n", sngss7_info->circuit->cic);
 460                 break;
 461         /**************************************************************************/
 462         case (CALLCLEAR):
 463                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CALL-LINE Clear\n", sngss7_info->circuit->cic);
 464                 break;
 465         /**************************************************************************/
 466         case (PRERELEASE):
 467                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx PRI\n", sngss7_info->circuit->cic);
 468                 break;
 469         /**************************************************************************/
 470         case (APPTRANSPORT):
 471                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx APM\n", sngss7_info->circuit->cic);
 472                 break;
 473         /**************************************************************************/
 474         case (OPERATOR):
 475                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx OPERATOR\n", sngss7_info->circuit->cic);
 476                 break;
 477         /**************************************************************************/
 478         case (METPULSE):
 479                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx METERING-PULSE\n", sngss7_info->circuit->cic);
 480                 break;
 481         /**************************************************************************/
 482         case (CLGPTCLR):
 483                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CALLING_PARTY_CLEAR\n", sngss7_info->circuit->cic);
 484                 break;
 485         /**************************************************************************/
 486         case (SUBDIRNUM):
 487                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx SUB-DIR\n", sngss7_info->circuit->cic);
 488                 break;
 489         /**************************************************************************/
 490         default:
 491                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Unknown Msg\n", sngss7_info->circuit->cic);
 492                 break;
 493         /**************************************************************************/
 494         }
 495 
 496         /* unlock the channel */
 497         ftdm_mutex_unlock(ftdmchan->mutex);
 498 
 499         SS7_FUNC_TRACE_EXIT(__FUNCTION__);
 500         return FTDM_SUCCESS;
 501 }
 502 
 503 /******************************************************************************/
 504 ftdm_status_t handle_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt)
 505 {
 506         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
 507 
 508         sngss7_chan_data_t  *sngss7_info ;
 509         ftdm_channel_t    *ftdmchan;
 510 
 511         /* get the ftdmchan and ss7_chan_data from the circuit */
 512         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
 513                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
 514                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
 515                 return FTDM_FAIL;
 516         }
 517 
 518         /* lock the channel */
 519         ftdm_mutex_lock(ftdmchan->mutex);
 520 
 521         /* check whether the ftdm channel is in a state to accept a call */
 522         switch (ftdmchan->state) {
 523         /**************************************************************************/
 524         case FTDM_CHANNEL_STATE_PROGRESS:
 525         case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
 526 
 527                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx ANM\n", sngss7_info->circuit->cic);
 528 
 529                 /* go to UP */
 530                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP);
 531 
 532                 break;
 533         /**************************************************************************/
 534         case FTDM_CHANNEL_STATE_DIALING:
 535 
 536                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CON\n", sngss7_info->circuit->cic);
 537 
 538                 /* go to UP */
 539                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP);
 540 
 541                 break;          
 542         /**************************************************************************/
 543         default:        /* incorrect state...reset the CIC */
 544 
 545                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx ANM/CON\n", sngss7_info->circuit->cic);
 546 
 547                 /* throw the TX reset flag */
 548                 sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX);
 549 
 550                 /* go to RESTART */
 551                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
 552 
 553                 break;
 554         /**************************************************************************/
 555         }
 556 
 557         /* unlock the channel */
 558         ftdm_mutex_unlock(ftdmchan->mutex);
 559 
 560         SS7_FUNC_TRACE_EXIT(__FUNCTION__);
 561         return FTDM_SUCCESS;
 562 }
 563 
 564 /******************************************************************************/
 565 ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt)
 566 {
 567         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
 568 
 569         sngss7_chan_data_t  *sngss7_info ;
 570         ftdm_channel_t    *ftdmchan;
 571 
 572         /* get the ftdmchan and ss7_chan_data from the circuit */
 573         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
 574                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
 575                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
 576                 return FTDM_FAIL;
 577         }
 578 
 579         /* lock the channel */
 580         ftdm_mutex_lock(ftdmchan->mutex);
 581 
 582         SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx REL cause=%d\n",
 583                                                         sngss7_info->circuit->cic, 
 584                                                         siRelEvnt->causeDgn.causeVal.val);
 585 
 586         /* check whether the ftdm channel is in a state to release a call */
 587         switch (ftdmchan->state) {
 588         /**************************************************************************/
 589         case FTDM_CHANNEL_STATE_DIALING:
 590 
 591                 /* pass the release code up to FTDM */
 592                 if (siRelEvnt->causeDgn.causeVal.pres) {
 593                         ftdmchan->caller_data.hangup_cause = siRelEvnt->causeDgn.causeVal.val;
 594                 } else {
 595                         SS7_ERROR("REL does not have a cause code!\n");
 596                         ftdmchan->caller_data.hangup_cause = 0;
 597                 }
 598 
 599                 /* this is a remote hangup request */
 600                 sngss7_set_flag(sngss7_info, FLAG_REMOTE_REL);
 601 ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL);
 602                 /* move the state of the channel to CANCEL to end the call */
 603                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
 604 
 605                 break;
 606         /**************************************************************************/
 607         case FTDM_CHANNEL_STATE_RING:
 608         case FTDM_CHANNEL_STATE_PROGRESS:
 609         case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
 610         case FTDM_CHANNEL_STATE_UP:
 611 
 612                 /* pass the release code up to FTDM */
 613                 if (siRelEvnt->causeDgn.causeVal.pres) {
 614                         ftdmchan->caller_data.hangup_cause = siRelEvnt->causeDgn.causeVal.val;
 615                 } else {
 616                         SS7_ERROR("REL does not have a cause ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL);code!\n");
 617                         ftdmchan->caller_data.hangup_cause = 0;
 618                 }
 619 
 620                 /* this is a remote hangup request */
 621                 sngss7_set_flag(sngss7_info, FLAG_REMOTE_REL);
 622 
 623                 /* move the state of the channel to TERMINATING to end the call */
 624                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
 625 
 626                 break;
 627         /**************************************************************************/
 628         case FTDM_CHANNEL_STATE_IN_LOOP:
 629 
 630                 /* inform the core to unloop the channel*/
 631                 ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL);
 632 
 633                 /* since we need to acknowledge the hang up set the flag for remote release */
 634                 sngss7_set_flag(sngss7_info, FLAG_REMOTE_REL);
 635 
 636                 /* go to hangup complete to send the RLC */
 637                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
 638 
 639                 /* save the call info for the RLC */
 640                 sngss7_info->suInstId = get_unique_id();
 641                 sngss7_info->spInstId = spInstId;
 642 
 643                 break;
 644         /**************************************************************************/
 645         default:
 646 
 647                 /* throw the reset flag */
 648                 sngss7_set_flag(sngss7_info, FLAG_RESET_RX);
 649 
 650                 /* set the state to RESTART */
 651                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
 652                 break;
 653         /**************************************************************************/
 654         } /* switch (ftdmchan->state) */
 655 
 656 
 657         /* unlock the channel */
 658         ftdm_mutex_unlock(ftdmchan->mutex);
 659 
 660         SS7_FUNC_TRACE_EXIT(__FUNCTION__);
 661         return FTDM_SUCCESS;
 662 }
 663 
 664 /******************************************************************************/
 665 ftdm_status_t handle_rel_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt)
 666 {
 667         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
 668         
 669         sngss7_chan_data_t  *sngss7_info ;
 670         ftdm_channel_t    *ftdmchan;
 671 
 672         /* get the ftdmchan and ss7_chan_data from the circuit */
 673         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
 674                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
 675                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
 676                 return FTDM_FAIL;
 677         }
 678 
 679         /* lock the channel */
 680         ftdm_mutex_lock(ftdmchan->mutex);
 681 
 682         SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx RLC\n", sngss7_info->circuit->cic);
 683 
 684         /* check whether the ftdm channel is in a state to accept a call */
 685         switch (ftdmchan->state) {
 686         /**************************************************************************/
 687         case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
 688 
 689                 /* go to DOWN */
 690                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
 691 
 692                 break;
 693         /**************************************************************************/
 694         case FTDM_CHANNEL_STATE_DOWN:
 695                 /* do nothing, just drop the message */
 696                 break;
 697         /**************************************************************************/
 698         default:        
 699                 /* KONRAD: should just stop the call...but a reset is easier for now (since it does hangup the call) */
 700 
 701                 /* go to RESTART */
 702                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
 703 
 704                 break;
 705         /**************************************************************************/
 706         }
 707 
 708         /* unlock the channel */
 709         ftdm_mutex_unlock(ftdmchan->mutex);
 710 
 711         SS7_FUNC_TRACE_EXIT(__FUNCTION__);
 712         return FTDM_SUCCESS;
 713 }
 714 
 715 /******************************************************************************/
 716 ftdm_status_t handle_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiInfoEvnt *siInfoEvnt)
 717 {
 718         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
 719         
 720         sngss7_chan_data_t  *sngss7_info ;
 721         ftdm_channel_t    *ftdmchan;
 722 
 723         /* get the ftdmchan and ss7_chan_data from the circuit */
 724         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
 725                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
 726                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
 727                 return FTDM_FAIL;
 728         }
 729 
 730         /* lock the channel */
 731         ftdm_mutex_lock(ftdmchan->mutex);
 732 
 733         SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx DATA IND\n", sngss7_info->circuit->cic);
 734 
 735         /* unlock the channel */
 736         ftdm_mutex_unlock(ftdmchan->mutex);
 737 
 738         SS7_FUNC_TRACE_EXIT(__FUNCTION__);
 739         return FTDM_SUCCESS;
 740 }
 741 
 742 /******************************************************************************/
 743 ftdm_status_t handle_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt)
 744 {
 745         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
 746         
 747         sngss7_chan_data_t  *sngss7_info ;
 748         ftdm_channel_t    *ftdmchan;
 749 
 750         /* get the ftdmchan and ss7_chan_data from the circuit */
 751         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
 752                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
 753                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
 754                 return FTDM_FAIL;
 755         }
 756 
 757         /* lock the channel */
 758         ftdm_mutex_lock(ftdmchan->mutex);
 759 
 760         SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx FAC\n", sngss7_info->circuit->cic);
 761 
 762         /* unlock the channel */
 763         ftdm_mutex_unlock(ftdmchan->mutex);
 764 
 765         SS7_FUNC_TRACE_EXIT(__FUNCTION__);
 766         return FTDM_SUCCESS;
 767 }
 768 
 769 /******************************************************************************/
 770 ftdm_status_t handle_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt)
 771 {
 772         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
 773         
 774         sngss7_chan_data_t  *sngss7_info ;
 775         ftdm_channel_t    *ftdmchan;
 776 
 777         /* get the ftdmchan and ss7_chan_data from the circuit */
 778         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
 779                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
 780                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
 781                 return FTDM_FAIL;
 782         }
 783 
 784         /* lock the channel */
 785         ftdm_mutex_lock(ftdmchan->mutex);
 786 
 787         SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx FAC-CON\n", sngss7_info->circuit->cic);
 788 
 789         /* unlock the channel */
 790         ftdm_mutex_unlock(ftdmchan->mutex);
 791 
 792         SS7_FUNC_TRACE_EXIT(__FUNCTION__);
 793         return FTDM_SUCCESS;
 794 }
 795 
 796 /******************************************************************************/
 797 ftdm_status_t handle_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit)
 798 {
 799         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
 800         
 801         sngss7_chan_data_t  *sngss7_info ;
 802         ftdm_channel_t    *ftdmchan;
 803 
 804         /* get the ftdmchan and ss7_chan_data from the circuit */
 805         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
 806                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
 807                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
 808                 return FTDM_FAIL;
 809         }
 810 
 811         /* lock the channel */
 812         ftdm_mutex_lock(ftdmchan->mutex);
 813 
 814         SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx USER-USER msg\n", sngss7_info->circuit->cic);
 815 
 816         /* unlock the channel */
 817         ftdm_mutex_unlock(ftdmchan->mutex);
 818 
 819         SS7_FUNC_TRACE_EXIT(__FUNCTION__);
 820         return FTDM_SUCCESS;
 821 }
 822 
 823 /******************************************************************************/
 824 ftdm_status_t handle_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt)
 825 {
 826         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
 827         
 828         sngss7_chan_data_t  *sngss7_info ;
 829         ftdm_channel_t    *ftdmchan;
 830 
 831         /* get the ftdmchan and ss7_chan_data from the circuit */
 832         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
 833                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
 834                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
 835                 return FTDM_FAIL;
 836         }
 837 
 838         /* lock the channel */
 839         ftdm_mutex_lock(ftdmchan->mutex);
 840 
 841         SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Call-Suspend msg\n", sngss7_info->circuit->cic);
 842 
 843         /* unlock the channel */
 844         ftdm_mutex_unlock(ftdmchan->mutex);
 845 
 846         SS7_FUNC_TRACE_EXIT(__FUNCTION__);
 847         return FTDM_SUCCESS;
 848 }
 849 
 850 /******************************************************************************/
 851 ftdm_status_t handle_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiResmEvnt *siResmEvnt)
 852 {
 853         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
 854         
 855         sngss7_chan_data_t  *sngss7_info ;
 856         ftdm_channel_t    *ftdmchan;
 857 
 858         /* get the ftdmchan and ss7_chan_data from the circuit */
 859         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
 860                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
 861                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
 862                 return FTDM_FAIL;
 863         }
 864 
 865         /* lock the channel */
 866         ftdm_mutex_lock(ftdmchan->mutex);
 867 
 868         SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Call-Resume msg\n", sngss7_info->circuit->cic);
 869 
 870         /* unlock the channel */
 871         ftdm_mutex_unlock(ftdmchan->mutex);
 872 
 873         SS7_FUNC_TRACE_EXIT(__FUNCTION__);
 874         return FTDM_SUCCESS;
 875 }
 876 
 877 /******************************************************************************/
 878 ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
 879 {
 880         sngss7_chan_data_t  *sngss7_info ;
 881         ftdm_channel_t    *ftdmchan;
 882 
 883         /* get the ftdmchan and ss7_chan_data from the circuit */
 884         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
 885                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
 886                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
 887                 return FTDM_FAIL;
 888         }
 889 
 890         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
 891 
 892         switch (evntType) {
 893         /**************************************************************************/
 894         case SIT_STA_REATTEMPT:          /* reattempt indication */
 895                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Reattempt indication\n", sngss7_info->circuit->cic);
 896                 handle_reattempt(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
 897                 break;
 898         /**************************************************************************/
 899         case SIT_STA_ERRORIND:            /* error indication */
 900                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Error indication\n", sngss7_info->circuit->cic);
 901                 SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
 902                 break;
 903         /**************************************************************************/
 904         case SIT_STA_CONTCHK:              /* continuity check */
 905                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CCR start\n", sngss7_info->circuit->cic);
 906                 handle_cot_start(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
 907                 break;
 908         /**************************************************************************/
 909         case SIT_STA_CONTREP:              /* continuity report */
 910                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx COT report\n", sngss7_info->circuit->cic);
 911                 handle_cot(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
 912                 break;
 913         /**************************************************************************/
 914         case SIT_STA_STPCONTIN:          /* stop continuity */
 915                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CCR stop\n", sngss7_info->circuit->cic);
 916                 handle_cot_stop(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
 917                 break;
 918         /**************************************************************************/
 919         case SIT_STA_CGQRYRSP:            /* circuit grp query response from far end forwarded to upper layer by ISUP */
 920                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CQM\n", sngss7_info->circuit->cic);
 921                 SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
 922                 break;
 923         /**************************************************************************/
 924         case SIT_STA_CONFUSION:          /* confusion */
 925                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CFN\n", sngss7_info->circuit->cic);
 926                 SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
 927                 break;
 928         /**************************************************************************/
 929         case SIT_STA_LOOPBACKACK:          /* loop-back acknowledge */
 930                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx LPA\n", sngss7_info->circuit->cic);
 931                 SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
 932                 break;
 933         /**************************************************************************/
 934         case SIT_STA_CIRRSRVREQ:                /* circuit reservation request */
 935                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Ckt Resveration req\n", sngss7_info->circuit->cic);
 936                 SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
 937                 break;
 938         /**************************************************************************/
 939         case SIT_STA_CIRRSRVACK:                /* circuit reservation acknowledgement */
 940                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Ckt Res ack\n", sngss7_info->circuit->cic);
 941                 SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
 942                 break;
 943         /**************************************************************************/
 944         case SIT_STA_CIRBLOREQ:          /* circuit blocking request */
 945                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx BLO\n", sngss7_info->circuit->cic);
 946                 handle_blo_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
 947                 break;
 948         /**************************************************************************/
 949         case SIT_STA_CIRBLORSP:          /* circuit blocking response   */
 950                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx BLA\n", sngss7_info->circuit->cic);
 951                 handle_blo_rsp(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
 952                 break;
 953         /**************************************************************************/
 954         case SIT_STA_CIRUBLREQ:          /* circuit unblocking request */
 955                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx UBL\n", sngss7_info->circuit->cic);
 956                 handle_ubl_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
 957                 break;
 958         /**************************************************************************/
 959         case SIT_STA_CIRUBLRSP:          /* circuit unblocking response */
 960                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx UBA\n", sngss7_info->circuit->cic);
 961                 handle_ubl_rsp(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
 962                 break;
 963         /**************************************************************************/
 964         case SIT_STA_CIRRESREQ:          /* circuit reset request - RSC */
 965                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx RSC\n", sngss7_info->circuit->cic);
 966                 handle_rsc_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
 967                 break;
 968         /**************************************************************************/
 969         case SIT_STA_CIRLOCRES:          /* reset initiated locally by the software */
 970                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Local RSC\n", sngss7_info->circuit->cic);
 971                 handle_local_rsc_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
 972                 break;
 973         /**************************************************************************/
 974         case SIT_STA_CIRRESRSP:          /* circuit reset response */
 975                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx RSC-RLC\n", sngss7_info->circuit->cic);
 976                 handle_rsc_rsp(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
 977                 break;
 978         /**************************************************************************/
 979         case SIT_STA_CGBREQ:                    /* CGB request */
 980                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CGB\n", sngss7_info->circuit->cic);
 981                 handle_cgb_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
 982                 break;
 983         /**************************************************************************/
 984         case SIT_STA_CGUREQ:                    /* CGU request */
 985                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CGU\n", sngss7_info->circuit->cic);
 986                 handle_cgu_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
 987                 break;
 988         /**************************************************************************/
 989         case SIT_STA_CGQRYREQ:            /* circuit group query request */
 990                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CQM\n", sngss7_info->circuit->cic);
 991                 SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
 992                 break;
 993         /**************************************************************************/
 994         case SIT_STA_CGBRSP:                    /* mntc. oriented CGB response */
 995                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx mntc CGB\n", sngss7_info->circuit->cic);
 996                 /*handle_cgb_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);*/
 997                 break;
 998         /**************************************************************************/
 999         case SIT_STA_CGURSP:                    /* mntc. oriented CGU response */
1000                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx mntc CGU\n", sngss7_info->circuit->cic);
1001                 /*SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));*/
1002                 break;
1003         /**************************************************************************/
1004         case SIT_STA_GRSREQ:                    /* circuit group reset request */
1005                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx GRS\n", sngss7_info->circuit->cic);
1006                 handle_grs_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
1007                 break;
1008         /**************************************************************************/
1009         case SIT_STA_CIRUNEQPD:          /* circuit unequipped indication */
1010                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx UCIC\n", sngss7_info->circuit->cic);
1011                 handle_ucic(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
1012                 break;
1013         /**************************************************************************/
1014         case SIT_STA_GRSRSP:                    /* circuit group reset response */
1015                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx GRA\n", sngss7_info->circuit->cic);
1016                 handle_grs_rsp(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
1017                 break;
1018         /**************************************************************************/
1019         case SIT_STA_PAUSEIND:            /* pause indication */
1020                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx SUS\n", sngss7_info->circuit->cic);
1021                 handle_pause(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
1022                 break;
1023         /**************************************************************************/
1024         case SIT_STA_RESUMEIND:          /* resume indication */
1025                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx RES\n", sngss7_info->circuit->cic);
1026                 handle_resume(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
1027                 break;
1028         /**************************************************************************/
1029         case SIT_STA_USRPARTA:            /* user part available */
1030                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx UPA\n", sngss7_info->circuit->cic);
1031                 SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
1032                 break;
1033         /**************************************************************************/
1034         case SIT_STA_RMTUSRUNAV:                /* remote user not available */
1035                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Remote User not Available\n", sngss7_info->circuit->cic);
1036                 SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
1037                 break;
1038         /**************************************************************************/
1039         case SIT_STA_MTPCONG0:            /* congestion indication level 0 */
1040                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Congestion L0\n", sngss7_info->circuit->cic);
1041                 SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
1042                 break;
1043         /**************************************************************************/
1044         case SIT_STA_MTPCONG1:            /* congestion indication level 1 */
1045                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Congestion L1\n", sngss7_info->circuit->cic);
1046                 SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
1047                 break;
1048         /**************************************************************************/
1049         case SIT_STA_MTPCONG2:            /* congestion indication level 2 */
1050                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Congestion L2\n", sngss7_info->circuit->cic);
1051                 SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
1052                 break;
1053         /**************************************************************************/
1054         case SIT_STA_MTPCONG3:            /* congestion indication level 3 */
1055                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Congestion L3\n", sngss7_info->circuit->cic);
1056                 SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
1057                 break;
1058         /**************************************************************************/
1059         case SIT_STA_MTPSTPCONG:                /* stop congestion indication level 0 */
1060                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Stop Congestion\n", sngss7_info->circuit->cic);
1061                 SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
1062                 break; 
1063         /**************************************************************************/
1064         case SIT_STA_CIRLOCALBLOIND:    /* Mngmt local blocking */
1065                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Local BLO\n", sngss7_info->circuit->cic);
1066                 handle_local_blk(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
1067                 break;
1068         /**************************************************************************/
1069         case SIT_STA_CIRLOCALUBLIND:    /* Mngmt local unblocking */
1070                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Local UBL\n", sngss7_info->circuit->cic);
1071                 handle_local_ubl(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
1072                 break;
1073         /**************************************************************************/
1074         case SIT_STA_OVERLOAD:            /* Overload */
1075                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Overload\n", sngss7_info->circuit->cic);
1076                 handle_olm_msg(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
1077                 break;
1078         /**************************************************************************/
1079         case SIT_STA_LMCGBREQ:            /* when LM requests ckt grp blocking */
1080                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx LM CGB\n", sngss7_info->circuit->cic);
1081                 SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
1082                 break;
1083         /**************************************************************************/
1084         case SIT_STA_LMCGUREQ:            /* when LM requests ckt grp unblocking */
1085                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx LM CGU\n", sngss7_info->circuit->cic);
1086                 SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
1087                 break;
1088         /**************************************************************************/
1089         case SIT_STA_LMGRSREQ:            /* when LM requests ckt grp reset */
1090                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx LM RSC\n", sngss7_info->circuit->cic);
1091                 SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
1092                 break;
1093         /**************************************************************************/
1094         case SIT_STA_CGBINFOIND:                /* circuit grp blking ind , no resp req */
1095                 /*SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CGB no resp req\n", sngss7_info->circuit->cic);*/
1096 /*              handle_cgb_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);*/
1097                 break;
1098         /**************************************************************************/
1099         case SIT_STA_LMCQMINFOREQ:        /* when LM requests ckt grp query */
1100                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx LM CQM\n", sngss7_info->circuit->cic);
1101 //              SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
1102                 break;
1103         /**************************************************************************/
1104         case SIT_STA_CIRLOCGRS:          /* group reset initiated locally by the software */
1105                 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Local GRS\n", sngss7_info->circuit->cic);
1106                 SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
1107                 break;
1108         /**************************************************************************/
1109         default:
1110                 SS7_INFO("[SNG-CC] Received Unknown indication %d\n", evntType);
1111                 break;
1112         } /* switch (evntType) */
1113 
1114         SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1115         return FTDM_SUCCESS;
1116 
1117 }
1118 
1119 /******************************************************************************/
1120 ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
1121 {
1122         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
1123 
1124         sngss7_chan_data_t  *sngss7_info = NULL;
1125         ftdm_channel_t    *ftdmchan = NULL;
1126 
1127         /* get the ftdmchan and ss7_chan_data from the circuit */
1128         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
1129                 SS7_ERROR("Failed to extract channel data for ISUP circuit = %d!\n", circuit);
1130                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1131                 return FTDM_FAIL;
1132         }
1133 
1134         /* lock the channel */
1135         ftdm_mutex_lock(ftdmchan->mutex);
1136 
1137         if (sngss7_test_flag(sngss7_info, FLAG_GLARE)) {
1138                 /* the glare flag is already up so it was caught ... do nothing */
1139                 SS7_DEBUG_CHAN(ftdmchan, "Glare flag is already up...nothing to do!%s\n", " ");
1140         } else {
1141                 SS7_DEBUG_CHAN(ftdmchan, "Glare flag is not up yet...indicating glare from reattempt!%s\n", " ");
1142                 /* glare, throw the flag */
1143                 sngss7_set_flag(sngss7_info, FLAG_GLARE);
1144 
1145                 /* clear any existing glare data from the channel */
1146                 memset(&sngss7_info->glare, 0x0, sizeof(sngss7_glare_data_t));
1147 
1148                 /* setup the hangup cause */
1149                 ftdmchan->caller_data.hangup_cause = 34;        /* Circuit Congrestion */
1150 
1151                 /* this is a remote hangup request */
1152                 sngss7_set_flag(sngss7_info, FLAG_REMOTE_REL);
1153 
1154                 /* move the state of the channel to Terminating to end the call */
1155                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
1156         }
1157 
1158         /* unlock the channel again before we exit */
1159         ftdm_mutex_unlock(ftdmchan->mutex);
1160 
1161         SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1162         return FTDM_SUCCESS;
1163 }
1164 
1165 /******************************************************************************/
1166 ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
1167 {
1168         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
1169         
1170         sngss7_chan_data_t  *sngss7_info = NULL;
1171         ftdm_channel_t    *ftdmchan = NULL;
1172         int                              infId;
1173         int                              i;
1174         
1175         /* extract the affected infId from the circuit structure */
1176         infId = g_ftdm_sngss7_data.cfg.isupCkt[circuit].infId;
1177 
1178         /* set the interface to paused */
1179         sngss7_set_flag(&g_ftdm_sngss7_data.cfg.isupIntf[infId], SNGSS7_PAUSED);
1180         
1181         /* go through all the circuits now and find any other circuits on this infId */
1182         i = 1;
1183         while (g_ftdm_sngss7_data.cfg.isupCkt[i].id != 0) {
1184                 
1185                 /* check that the infId matches and that this is not a siglink */
1186                 if ((g_ftdm_sngss7_data.cfg.isupCkt[i].infId == infId) && 
1187                         (g_ftdm_sngss7_data.cfg.isupCkt[i].type == VOICE)) {
1188         
1189                         /* get the ftdmchan and ss7_chan_data from the circuit */
1190                         if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
1191                                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
1192                                 i++;
1193                                 continue;
1194                         }
1195         
1196                         /* lock the channel */
1197                         ftdm_mutex_lock(ftdmchan->mutex);
1198         
1199                         /* check if the circuit is fully started */
1200                         if (ftdm_test_flag(ftdmchan->span, FTDM_SPAN_IN_THREAD)) {
1201                                 SS7_DEBUG_CHAN(ftdmchan, "Rx PAUSE%s\n", "");
1202                                 /* set the pause flag on the channel */
1203                                 sngss7_set_flag(sngss7_info, FLAG_INFID_PAUSED);
1204                         }
1205         
1206                         /* unlock the channel again before we exit */
1207                         ftdm_mutex_unlock(ftdmchan->mutex);
1208         
1209                 } /* if (g_ftdm_sngss7_data.cfg.isupCkt[i].infId == infId) */
1210         
1211                 /* move to the next circuit */
1212                 i++;
1213         
1214         } /* while (g_ftdm_sngss7_data.cfg.isupCkt[i].id != 0) */
1215         
1216         SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1217         return FTDM_SUCCESS;
1218 }
1219 
1220 /******************************************************************************/
1221 ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
1222 {
1223         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
1224 
1225         sngss7_chan_data_t  *sngss7_info = NULL;
1226         ftdm_channel_t    *ftdmchan = NULL;
1227         int                              infId;
1228         int                              i;
1229 
1230         /* extract the affect infId from the circuit structure */
1231         infId = g_ftdm_sngss7_data.cfg.isupCkt[circuit].infId;
1232 
1233         /* set the interface to resumed */
1234         sngss7_clear_flag(&g_ftdm_sngss7_data.cfg.isupIntf[infId], SNGSS7_PAUSED);
1235 
1236         /* go through all the circuits now and find any other circuits on this infId */
1237         i = 1;
1238         while (g_ftdm_sngss7_data.cfg.isupCkt[i].id != 0) {
1239 
1240                 /* check that the infId matches and that this is not a siglink */
1241                 if ((g_ftdm_sngss7_data.cfg.isupCkt[i].infId == infId) && 
1242                         (g_ftdm_sngss7_data.cfg.isupCkt[i].type == VOICE)) {
1243 
1244                         /* get the ftdmchan and ss7_chan_data from the circuit */
1245                         if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
1246                                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
1247                                 i++;
1248                                 continue;
1249                         }
1250 
1251                         /* lock the channel */
1252                         ftdm_mutex_lock(ftdmchan->mutex);
1253 
1254                         /* only resume if we are paused */
1255                         if (sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) {
1256                                 SS7_DEBUG_CHAN(ftdmchan, "Rx RESUME%s\n", "");
1257 
1258                                 /* set the resume flag on the channel */
1259                                 sngss7_set_flag(sngss7_info, FLAG_INFID_RESUME);
1260 
1261                                 /* clear the paused flag */
1262                                 sngss7_clear_flag(sngss7_info, FLAG_INFID_PAUSED);
1263                         }
1264                         
1265                         /* unlock the channel again before we exit */
1266                         ftdm_mutex_unlock(ftdmchan->mutex);
1267 
1268                 } /* if (g_ftdm_sngss7_data.cfg.isupCkt[i].infId == infId) */
1269 
1270                 /* move to the next circuit */
1271                 i++;
1272 
1273         } /* while (g_ftdm_sngss7_data.cfg.isupCkt[i].id != 0) */
1274 
1275         SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1276         return FTDM_SUCCESS;
1277 }
1278 
1279 /******************************************************************************/
1280 ftdm_status_t handle_cot_start(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
1281 {
1282         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
1283 
1284         sngss7_chan_data_t  *sngss7_info = NULL;
1285         ftdm_channel_t    *ftdmchan = NULL;
1286 
1287         /* get the ftdmchan and ss7_chan_data from the circuit */
1288         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
1289                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
1290                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1291                 return FTDM_FAIL;
1292         }
1293 
1294         /* lock the channel */
1295         ftdm_mutex_lock(ftdmchan->mutex);
1296 
1297         /* open the channel if it is not open */
1298         if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) {
1299                 if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
1300                         SS7_ERROR("Failed to open CIC %d for CCR test!\n", sngss7_info->circuit->cic);
1301                         /* KONRAD FIX ME */
1302                         SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1303                         return FTDM_FAIL;
1304                 }
1305         }
1306 
1307         /* tell the core to loop the channel */
1308         ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_LOOP, NULL);
1309 
1310         /* switch to the IN_LOOP state */
1311         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IN_LOOP);
1312 
1313         /* unlock the channel again before we exit */
1314         ftdm_mutex_unlock(ftdmchan->mutex);
1315 
1316         SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1317         return FTDM_SUCCESS;
1318 }
1319 
1320 /******************************************************************************/
1321 ftdm_status_t handle_cot_stop(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
1322 {
1323         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
1324 
1325         sngss7_chan_data_t  *sngss7_info = NULL;
1326         ftdm_channel_t    *ftdmchan = NULL;
1327 
1328         /* get the ftdmchan and ss7_chan_data from the circuit */
1329         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
1330                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
1331                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1332                 return FTDM_FAIL;
1333         }
1334 
1335         /* lock the channel */
1336         ftdm_mutex_lock(ftdmchan->mutex);
1337 
1338         /* tell the core to stop looping the channel */
1339         ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL);
1340 
1341         /* exit out of the LOOP state to the last state */
1342         ftdm_set_state_locked(ftdmchan, ftdmchan->last_state);
1343 
1344         /* unlock the channel again before we exit */
1345         ftdm_mutex_unlock(ftdmchan->mutex);
1346 
1347         SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1348         return FTDM_SUCCESS;
1349 }
1350 
1351 /******************************************************************************/
1352 ftdm_status_t handle_cot(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
1353 {
1354         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
1355 
1356         sngss7_chan_data_t  *sngss7_info = NULL;
1357         ftdm_channel_t    *ftdmchan = NULL;
1358 
1359         /* get the ftdmchan and ss7_chan_data from the circuit */
1360         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
1361                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
1362                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1363                 return FTDM_FAIL;
1364         }
1365 
1366         /* lock the channel */
1367         ftdm_mutex_lock(ftdmchan->mutex);
1368 
1369         switch (ftdmchan->state) {
1370         /**************************************************************************/
1371         case (FTDM_CHANNEL_STATE_IN_LOOP):
1372                 /* tell the core to stop looping the channel */
1373                 ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL);
1374         
1375                 /* exit out of the LOOP state and go to collect */
1376                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_COLLECT);
1377                 
1378                 break;
1379         /**************************************************************************/
1380         default:
1381                 /* exit out of the LOOP state to the last state */
1382                 ftdm_set_state_locked(ftdmchan, ftdmchan->last_state);
1383 
1384                 break;
1385         /**************************************************************************/
1386         } /* switch (ftdmchan->state) */
1387 
1388         if ( (siStaEvnt->contInd.eh.pres > 0) && (siStaEvnt->contInd.contInd.pres > 0)) {
1389                 SS7_INFO("Continuity Test result for CIC = %d (span %d, chan %d) is: \"%s\"\n",
1390                                         g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic,
1391                                         g_ftdm_sngss7_data.cfg.isupCkt[circuit].span,
1392                                         g_ftdm_sngss7_data.cfg.isupCkt[circuit].chan,
1393                                         (siStaEvnt->contInd.contInd.val) ? "PASS" : "FAIL");
1394         } else {
1395                 SS7_ERROR("Recieved Continuity report containing no results!\n");
1396         }
1397 
1398         /* unlock the channel again before we exit */
1399         ftdm_mutex_unlock(ftdmchan->mutex);
1400 
1401         SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1402         return FTDM_SUCCESS;
1403 }
1404 
1405 /******************************************************************************/
1406 ftdm_status_t handle_blo_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
1407 {
1408         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
1409 
1410         sngss7_chan_data_t  *sngss7_info = NULL;
1411         ftdm_channel_t    *ftdmchan = NULL;
1412 
1413         /* get the ftdmchan and ss7_chan_data from the circuit */
1414         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
1415                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
1416                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1417                 return FTDM_FAIL;
1418         }
1419 
1420         /* lock the channel */
1421         ftdm_mutex_lock(ftdmchan->mutex);
1422 
1423         /* check if the circuit is already blocked or not */
1424         if (sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) {
1425                 SS7_WARN("Received BLO on circuit that is already blocked!\n");
1426         }
1427 
1428         /* throw the ckt block flag */
1429         sngss7_set_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX);
1430 
1431         /* set the channel to suspended state */
1432         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
1433 
1434         /* unlock the channel again before we exit */
1435         ftdm_mutex_unlock(ftdmchan->mutex);
1436 
1437         SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1438         return FTDM_SUCCESS;
1439 }
1440 
1441 /******************************************************************************/
1442 ftdm_status_t handle_blo_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
1443 {
1444         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
1445 
1446         sngss7_chan_data_t  *sngss7_info = NULL;
1447         ftdm_channel_t    *ftdmchan = NULL;
1448 
1449         /* get the ftdmchan and ss7_chan_data from the circuit */
1450         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
1451                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
1452                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1453                 return FTDM_FAIL;
1454         }
1455 
1456         /* lock the channel */
1457         ftdm_mutex_lock(ftdmchan->mutex);
1458 
1459         /* KONRAD FIX ME */
1460 
1461         /* unlock the channel again before we exit */
1462         ftdm_mutex_unlock(ftdmchan->mutex);
1463 
1464         SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1465         return FTDM_SUCCESS;
1466 }
1467 
1468 /******************************************************************************/
1469 ftdm_status_t handle_ubl_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
1470 {
1471         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
1472 
1473         sngss7_chan_data_t  *sngss7_info = NULL;
1474         ftdm_channel_t    *ftdmchan = NULL;
1475 
1476         /* get the ftdmchan and ss7_chan_data from the circuit */
1477         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
1478                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
1479                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1480                 return FTDM_FAIL;
1481         }
1482 
1483         /* lock the channel */
1484         ftdm_mutex_lock(ftdmchan->mutex);
1485 
1486         /* check if the channel is blocked */
1487         if (!(sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX))) {
1488                 SS7_WARN("Received UBL on circuit that is not blocked!\n");
1489         }
1490 
1491         /* throw the unblock flag */
1492         sngss7_set_flag(sngss7_info, FLAG_CKT_MN_UNBLK_RX);
1493 
1494         /* clear the block flag */
1495         sngss7_clear_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX);
1496 
1497         /* set the channel to suspended state */
1498         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
1499 
1500         /* unlock the channel again before we exit */
1501         ftdm_mutex_unlock(ftdmchan->mutex);
1502 
1503         SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1504         return FTDM_SUCCESS;
1505 }
1506 
1507 /******************************************************************************/
1508 ftdm_status_t handle_ubl_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
1509 {
1510         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
1511 
1512         sngss7_chan_data_t  *sngss7_info = NULL;
1513         ftdm_channel_t    *ftdmchan = NULL;
1514 
1515         /* get the ftdmchan and ss7_chan_data from the circuit */
1516         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
1517                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
1518                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1519                 return FTDM_FAIL;
1520         }
1521 
1522         /* lock the channel */
1523         ftdm_mutex_lock(ftdmchan->mutex);
1524 
1525         /* KONRAD FIX ME */
1526 
1527         /* unlock the channel again before we exit */
1528         ftdm_mutex_unlock(ftdmchan->mutex);
1529 
1530         SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1531         return FTDM_SUCCESS;
1532 }
1533 
1534 /******************************************************************************/
1535 ftdm_status_t handle_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
1536 {
1537         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
1538 
1539         sngss7_chan_data_t  *sngss7_info = NULL;
1540         ftdm_channel_t    *ftdmchan = NULL;
1541 
1542         /* get the ftdmchan and ss7_chan_data from the circuit */
1543         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
1544                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
1545                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1546                 return FTDM_FAIL;
1547         }
1548 
1549         /* lock the channel */
1550         ftdm_mutex_lock(ftdmchan->mutex);
1551 
1552         /* throw the reset flag */
1553         sngss7_set_flag(sngss7_info, FLAG_RESET_RX);
1554 
1555         switch (ftdmchan->state) {
1556         /**************************************************************************/
1557         case FTDM_CHANNEL_STATE_RESTART:
1558 
1559                 /* go to idle so that we can redo the restart state*/
1560                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE);
1561 
1562                 break;
1563         /**************************************************************************/
1564         default:
1565 
1566                 /* set the state of the channel to restart...the rest is done by the chan monitor */
1567                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
1568                 break;
1569         /**************************************************************************/
1570         }
1571 
1572         /* unlock the channel again before we exit */
1573         ftdm_mutex_unlock(ftdmchan->mutex);
1574 
1575         SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1576         return FTDM_SUCCESS;
1577 }
1578 
1579 /******************************************************************************/
1580 ftdm_status_t handle_local_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
1581 {
1582         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
1583 
1584         sngss7_chan_data_t  *sngss7_info = NULL;
1585         ftdm_channel_t    *ftdmchan = NULL;
1586 
1587         /* get the ftdmchan and ss7_chan_data from the circuit */
1588         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
1589                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
1590                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1591                 return FTDM_FAIL;
1592         }
1593 
1594         /* lock the channel */
1595         ftdm_mutex_lock(ftdmchan->mutex);
1596 
1597         /* throw the reset flag */
1598         sngss7_set_flag(sngss7_info, FLAG_RESET_RX);
1599 
1600         switch (ftdmchan->state) {
1601         /**************************************************************************/
1602         case FTDM_CHANNEL_STATE_RESTART:
1603 
1604                 /* go to idle so that we can redo the restart state*/
1605                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE);
1606 
1607                 break;
1608         /**************************************************************************/
1609         default:
1610 
1611                 /* set the state of the channel to restart...the rest is done by the chan monitor */
1612                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
1613                 break;
1614         /**************************************************************************/
1615         }
1616 
1617         /* unlock the channel again before we exit */
1618         ftdm_mutex_unlock(ftdmchan->mutex);
1619 
1620         SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1621         return FTDM_SUCCESS;
1622 }
1623 
1624 /******************************************************************************/
1625 ftdm_status_t handle_rsc_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
1626 {
1627         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
1628 
1629         sngss7_chan_data_t  *sngss7_info = NULL;
1630         ftdm_channel_t    *ftdmchan = NULL;
1631 
1632         /* get the ftdmchan and ss7_chan_data from the circuit */
1633         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
1634                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
1635                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1636                 return FTDM_FAIL;
1637         }
1638 
1639         /* lock the channel */
1640         ftdm_mutex_lock(ftdmchan->mutex);
1641 
1642         switch (ftdmchan->state) {
1643         /**********************************************************************/
1644         case FTDM_CHANNEL_STATE_RESTART:
1645                 
1646                 if ( sngss7_test_flag(sngss7_info, FLAG_RESET_TX) ) {
1647                         /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */
1648                         sngss7_set_flag(sngss7_info, FLAG_RESET_TX_RSP);
1649 
1650                         /* go to DOWN */
1651                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
1652                 } else {
1653                         SS7_ERROR("Received RSC-RLC but we're not waiting on a RSC-RLC on CIC #, dropping\n", sngss7_info->circuit->cic);
1654                 }
1655 
1656                 break;
1657         /**********************************************************************/
1658         case FTDM_CHANNEL_STATE_DOWN:
1659                 
1660                 /* do nothing, just drop the message */
1661                 SS7_DEBUG("Receveived RSC-RLC in down state, dropping\n");
1662                 
1663                 break;
1664         /**********************************************************************/
1665         case FTDM_CHANNEL_STATE_TERMINATING:
1666         case FTDM_CHANNEL_STATE_HANGUP:
1667         case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
1668                 
1669                 /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */
1670                 sngss7_set_flag(sngss7_info, FLAG_RESET_TX_RSP);
1671 
1672                 /* go to DOWN */
1673                 /*ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);*/
1674 
1675                 break;
1676         /**********************************************************************/
1677         default:
1678                 /* ITU Q764-2.9.5.1.c -> release the circuit */
1679                 if ((siStaEvnt != NULL) &&
1680                         (siStaEvnt->causeDgn.eh.pres ==PRSNT_NODEF) &&
1681                         (siStaEvnt->causeDgn.causeVal.pres == PRSNT_NODEF)) {
1682                         ftdmchan->caller_data.hangup_cause = siStaEvnt->causeDgn.causeVal.val;
1683                 } else {
1684                         ftdmchan->caller_data.hangup_cause = 98;        /* Message not compatiable with call state */
1685                 }
1686 
1687                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
1688                 break;
1689         /**********************************************************************/
1690         }
1691 
1692         /* unlock the channel again before we exit */
1693         ftdm_mutex_unlock(ftdmchan->mutex);
1694 
1695         SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1696         return FTDM_SUCCESS;
1697 }
1698 /******************************************************************************/
1699 ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
1700 {
1701         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
1702 
1703         sngss7_chan_data_t      *sngss7_info = NULL;
1704         ftdm_channel_t          *ftdmchan = NULL;
1705         sngss7_span_data_t      *sngss7_span = NULL; 
1706         int                                     range;
1707 
1708 
1709         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
1710                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
1711                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1712                 return FTDM_FAIL;
1713         }
1714 
1715         /* extract the range value from the event structure */
1716         if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.range.pres == PRSNT_NODEF)) {
1717                 range = siStaEvnt->rangStat.range.val;
1718         } else {
1719                 SS7_ERROR("Received GRS with no range value on CIC = %d\n", sngss7_info->circuit->cic);
1720                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1721                 return FTDM_FAIL;
1722         }
1723 
1724         /* fill in the span structure for this circuit */
1725         sngss7_span = ftdmchan->span->signal_data;
1726         sngss7_span->rx_grs.circuit = circuit; 
1727         sngss7_span->rx_grs.range = range;
1728 
1729         /* the reset will be started in the main thread by "check_if_rx_grs_started" */
1730 
1731         SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1732         return FTDM_SUCCESS;
1733 }
1734 
1735 /******************************************************************************/
1736 ftdm_status_t handle_grs_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
1737 {
1738         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
1739 
1740         sngss7_chan_data_t      *sngss7_info = NULL;
1741         ftdm_channel_t          *ftdmchan = NULL;
1742         sngss7_span_data_t      *sngss7_span = NULL; 
1743         int                                     range;
1744 
1745         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
1746                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
1747                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1748                 return FTDM_FAIL;
1749         }
1750 
1751         /* extract the range value from the event structure */
1752         if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.range.pres == PRSNT_NODEF)) {
1753                 range = siStaEvnt->rangStat.range.val;
1754         } else {
1755                 SS7_ERROR("Received GRA with no range value on CIC = %d\n", sngss7_info->circuit->cic);
1756                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1757                 return FTDM_FAIL;
1758         }
1759 
1760         /* fill in the span structure for this circuit */
1761         sngss7_span = ftdmchan->span->signal_data;
1762         sngss7_span->rx_gra.circuit = circuit; 
1763         sngss7_span->rx_gra.range = range;
1764 
1765         /* check if there is a cause value in the GRA */
1766         if ((siStaEvnt != NULL) &&
1767                 (siStaEvnt->causeDgn.eh.pres == PRSNT_NODEF) &&
1768                 (siStaEvnt->causeDgn.causeVal.pres == PRSNT_NODEF)) {
1769 
1770                 sngss7_span->rx_gra.cause = siStaEvnt->causeDgn.causeVal.val;
1771         }
1772 
1773         /* the reset will be started in the main thread by "check_if_rx_gra_started" */
1774         
1775         SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1776         return FTDM_SUCCESS;
1777 }
1778 
1779 /******************************************************************************/
1780 ftdm_status_t handle_local_blk(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
1781 {
1782         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
1783 
1784         sngss7_chan_data_t  *sngss7_info = NULL;
1785         ftdm_channel_t    *ftdmchan = NULL;
1786 
1787         /* get the ftdmchan and ss7_chan_data from the circuit */
1788         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
1789                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
1790                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1791                 return FTDM_FAIL;
1792         }
1793 
1794         /* lock the channel */
1795         ftdm_mutex_lock(ftdmchan->mutex);
1796 
1797         /* check if the circuit is already blocked or not */
1798         if (sngss7_test_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX)) {
1799                 SS7_WARN("Received local BLO on circuit that is already blocked!\n");
1800         }
1801 
1802         /* throw the ckt block flag */
1803         sngss7_set_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX);
1804 
1805         /* set the channel to suspended state */
1806         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
1807 
1808         /* unlock the channel again before we exit */
1809         ftdm_mutex_unlock(ftdmchan->mutex);
1810 
1811         SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1812         return FTDM_SUCCESS;
1813 }
1814 
1815 /******************************************************************************/
1816 ftdm_status_t handle_local_ubl(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
1817 {
1818         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
1819 
1820         sngss7_chan_data_t  *sngss7_info = NULL;
1821         ftdm_channel_t    *ftdmchan = NULL;
1822 
1823         /* get the ftdmchan and ss7_chan_data from the circuit */
1824         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
1825                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
1826                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1827                 return FTDM_FAIL;
1828         }
1829 
1830         /* lock the channel */
1831         ftdm_mutex_lock(ftdmchan->mutex);
1832 
1833         /* check if the circuit is already blocked or not */
1834         if (sngss7_test_flag(sngss7_info, FLAG_CKT_LC_UNBLK_RX)) {
1835                 SS7_WARN("Received local UBL on circuit that is already unblocked!\n");
1836         }
1837 
1838         /* throw the ckt block flag */
1839         sngss7_set_flag(sngss7_info, FLAG_CKT_LC_UNBLK_RX);
1840 
1841         /* set the channel to suspended state */
1842         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
1843 
1844         /* unlock the channel again before we exit */
1845         ftdm_mutex_unlock(ftdmchan->mutex);
1846 
1847         SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1848         return FTDM_SUCCESS;
1849 }
1850 
1851 /******************************************************************************/
1852 ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
1853 {
1854         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
1855 
1856         sngss7_chan_data_t      *sngss7_info = NULL;
1857         sngss7_span_data_t      *sngss7_span = NULL;
1858         ftdm_channel_t          *ftdmchan = NULL;
1859 
1860 
1861         /* get the ftdmchan and ss7_chan_data from the circuit */
1862         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
1863                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
1864                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1865                 return FTDM_FAIL;
1866         }
1867 
1868         /* check if we just sent a GRS request...*/
1869         sngss7_span = ftdmchan->span->signal_data;
1870         if (sngss7_span->tx_grs.circuit > 0) {
1871                 /* we need to put all circuits on this UCIC */
1872                 sngss7_span->ucic.circuit = sngss7_span->tx_grs.circuit;
1873                 sngss7_span->ucic.range = sngss7_span->tx_grs.range;
1874                 goto done;
1875         }
1876 
1877         /* lock the channel */
1878         ftdm_mutex_lock(ftdmchan->mutex);
1879 
1880         /* throw the ckt block flag */
1881         sngss7_set_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK);
1882 
1883         /* set the channel to suspended state */
1884         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
1885 
1886         /* unlock the channel again before we exit */
1887         ftdm_mutex_unlock(ftdmchan->mutex);
1888 done:
1889         SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1890         return FTDM_SUCCESS;
1891 }
1892 
1893 /******************************************************************************/
1894 ftdm_status_t handle_cgb_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
1895 {
1896         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
1897 
1898         sngss7_chan_data_t      *sngss7_info = NULL;
1899         sngss7_span_data_t      *sngss7_span = NULL;
1900         ftdm_channel_t          *ftdmchan = NULL;
1901         int                                     range;
1902         uint8_t                         status[255];
1903         int                                     blockType = 0;
1904         int                                     byte = 0;
1905         int                                     bit = 0;
1906         int                             x;
1907         ftdm_sigmsg_t           sigev;
1908 
1909         memset(&sigev, 0, sizeof (sigev));
1910         memset(&status[0], '\0', sizeof(status));
1911 
1912         /* get the ftdmchan and ss7_chan_data from the circuit */
1913         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
1914                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
1915                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1916                 return FTDM_FAIL;
1917         }
1918 
1919         /* grab the span info */
1920         sngss7_span = ftdmchan->span->signal_data;
1921 
1922         /* figure out what type of block needs to be applied */
1923         if ((siStaEvnt->cgsmti.eh.pres == PRSNT_NODEF) && (siStaEvnt->cgsmti.typeInd.pres == PRSNT_NODEF)) {
1924                 blockType = siStaEvnt->cgsmti.typeInd.val;
1925         } else {
1926                 SS7_ERROR("Received CGB with no circuit group supervision value on CIC = %d\n", sngss7_info->circuit->cic);
1927                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1928                 return FTDM_FAIL;
1929         }       
1930 
1931         /* pull out the range value */
1932         if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.range.pres == PRSNT_NODEF)) {
1933                 range = siStaEvnt->rangStat.range.val;
1934         } else {
1935                 SS7_ERROR("Received CGB with no range value on CIC = %d\n", sngss7_info->circuit->cic);
1936                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1937                 return FTDM_FAIL;
1938         }
1939 
1940         /* pull out the status field */
1941         if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.status.pres == PRSNT_NODEF)) {
1942                 for (x = 0; x < siStaEvnt->rangStat.status.len; x++) {
1943                         status[x] = siStaEvnt->rangStat.status.val[x];
1944                 }
1945         } else {
1946                 SS7_ERROR("Received CGB with no status value on CIC = %d\n", sngss7_info->circuit->cic);
1947                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
1948                 return FTDM_FAIL;
1949         }
1950 
1951         /* save the circuit, range and status */
1952         sngss7_span->rx_cgb.circuit = circuit;
1953         sngss7_span->rx_cgb.range = range;
1954         sngss7_span->rx_cgb.type = blockType;
1955         for (x = 0; x < siStaEvnt->rangStat.status.len; x++) {
1956                 sngss7_span->rx_cgb.status[x] = status[x];
1957         }
1958 
1959         /* loop over the cics starting from circuit until range+1 */
1960         for (x = circuit; x < (circuit + range + 1); x++) {
1961                 /* confirm this is a voice channel */
1962                 if (g_ftdm_sngss7_data.cfg.isupCkt[x].type != VOICE) continue;
1963 
1964                 /* grab the circuit in question */
1965                 if (extract_chan_data(x, &sngss7_info, &ftdmchan)) {
1966                         SS7_ERROR("Failed to extract channel data for circuit = %d!\n", x);
1967                         break;
1968                 }
1969         
1970                 /* lock the channel */
1971                 ftdm_mutex_lock(ftdmchan->mutex);
1972 
1973 #if 0
1974                 SS7_ERROR("KONRAD -> circuit=%d, byte=%d, bit=%d, status[byte]=%d, math=%d\n",
1975                                         x,
1976                                         byte,
1977                                         bit,
1978                                         status[byte],
1979                                         (status[byte] & (1 << bit)));
1980 #endif
1981                 if (status[byte] & (1 << bit)) {
1982                         switch (blockType) {
1983                         /**********************************************************************/
1984                         case 0: /* maintenance oriented */
1985                                 sngss7_set_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX);
1986                                 break;
1987                         /**********************************************************************/
1988                         case 1: /* hardware failure oriented */
1989                                 sngss7_set_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX);
1990                                 break;
1991                         /**********************************************************************/
1992                         case 2: /* reserved for national use */
1993                                 break;
1994                         /**********************************************************************/
1995                         default:
1996                                 break;
1997                         /**********************************************************************/
1998                         } /* switch (blockType) */
1999                 }
2000 
2001                 sigev.chan_id = ftdmchan->chan_id;
2002                 sigev.span_id = ftdmchan->span_id;
2003                 sigev.channel = ftdmchan;
2004 
2005                 /* bring the sig status down */
2006                 sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
2007                 sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_DOWN;
2008                 ftdm_span_send_signal(ftdmchan->span, &sigev);
2009 
2010                 /* unlock the channel again before we exit */
2011                 ftdm_mutex_unlock(ftdmchan->mutex);
2012 
2013                 /* update the bit and byte counter*/
2014                 bit ++;
2015                 if (bit == 8) {
2016                         byte++;
2017                         bit = 0;
2018                 }
2019 
2020         } /* for (x = circuit; x < (circuit + range + 1); x++) */
2021 
2022         /* get the ftdmchan and ss7_chan_data from the circuit */
2023         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
2024                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
2025                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
2026                 return FTDM_FAIL;
2027         }
2028 
2029         ft_to_sngss7_cgba(ftdmchan);
2030 
2031         return FTDM_SUCCESS;
2032 }
2033 
2034 /******************************************************************************/
2035 ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
2036 {
2037         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
2038 
2039         sngss7_chan_data_t      *sngss7_info = NULL;
2040         sngss7_span_data_t      *sngss7_span = NULL;
2041         ftdm_channel_t          *ftdmchan = NULL;
2042         int                                     range;
2043         uint8_t                         status[255];
2044         int                                     blockType = 0;
2045         int                                     byte = 0;
2046         int                                     bit = 0;
2047         int                             x;
2048         ftdm_sigmsg_t           sigev;
2049 
2050         memset(&sigev, 0, sizeof (sigev));
2051         memset(&status[0], '\0', sizeof(status));
2052 
2053         /* get the ftdmchan and ss7_chan_data from the circuit */
2054         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
2055                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
2056                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
2057                 return FTDM_FAIL;
2058         }
2059 
2060         /* grab the span info */
2061         sngss7_span = ftdmchan->span->signal_data;
2062 
2063         /* figure out what type of block needs to be applied */
2064         if ((siStaEvnt->cgsmti.eh.pres == PRSNT_NODEF) && (siStaEvnt->cgsmti.typeInd.pres == PRSNT_NODEF)) {
2065                 blockType = siStaEvnt->cgsmti.typeInd.val;
2066         } else {
2067                 SS7_ERROR("Received CGU with no circuit group supervision value on CIC = %d\n", sngss7_info->circuit->cic);
2068                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
2069                 return FTDM_FAIL;
2070         }       
2071 
2072         /* pull out the range value */
2073         if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.range.pres == PRSNT_NODEF)) {
2074                 range = siStaEvnt->rangStat.range.val;
2075         } else {
2076                 SS7_ERROR("Received CGU with no range value on CIC = %d\n", sngss7_info->circuit->cic);
2077                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
2078                 return FTDM_FAIL;
2079         }
2080 
2081         /* pull out the status field */
2082         if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.status.pres == PRSNT_NODEF)) {
2083                 for (x = 0; x < siStaEvnt->rangStat.status.len; x++) {
2084                         status[x] = siStaEvnt->rangStat.status.val[x];
2085                 }
2086         } else {
2087                 SS7_ERROR("Received CGU with no status value on CIC = %d\n", sngss7_info->circuit->cic);
2088                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
2089                 return FTDM_FAIL;
2090         }
2091 
2092         /* save the circuit, range and status */
2093         sngss7_span->rx_cgu.circuit = circuit;
2094         sngss7_span->rx_cgu.range = range;
2095         sngss7_span->rx_cgu.type = blockType;
2096         for (x = 0; x < siStaEvnt->rangStat.status.len; x++) {
2097                 sngss7_span->rx_cgu.status[x] = status[x];
2098         }
2099 
2100         /* loop over the cics starting from circuit until range+1 */
2101         for (x = circuit; x < (circuit + range + 1); x++) {
2102                 if (g_ftdm_sngss7_data.cfg.isupCkt[x].type != VOICE) continue;
2103                 /* grab the circuit in question */
2104                 if (extract_chan_data(x, &sngss7_info, &ftdmchan)) {
2105                         SS7_ERROR("Failed to extract channel data for circuit = %d!\n", x);
2106                         break;
2107                 }
2108         
2109                 /* lock the channel */
2110                 ftdm_mutex_lock(ftdmchan->mutex);
2111 
2112                 if (status[byte] & (1 << bit)) {
2113                         switch (blockType) {
2114                         /**********************************************************************/
2115                         case 0: /* maintenance oriented */
2116                                 sngss7_clear_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX);
2117                                 break;
2118                         /**********************************************************************/
2119                         case 1: /* hardware failure oriented */
2120                                 sngss7_clear_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX);
2121                                 break;
2122                         /**********************************************************************/
2123                         case 2: /* reserved for national use */
2124                                 break;
2125                         /**********************************************************************/
2126                         default:
2127                                 break;
2128                         /**********************************************************************/
2129                         } /* switch (blockType) */
2130                 } /* if (status[byte] & (1 << bit)) */
2131 
2132                 sigev.chan_id = ftdmchan->chan_id;
2133                 sigev.span_id = ftdmchan->span_id;
2134                 sigev.channel = ftdmchan;
2135 
2136                 /* bring the sig status down */
2137                 sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
2138                 sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_UP;
2139                 ftdm_span_send_signal(ftdmchan->span, &sigev);
2140         
2141                 /* unlock the channel again before we exit */
2142                 ftdm_mutex_unlock(ftdmchan->mutex);
2143 
2144                 /* update the bit and byte counter*/
2145                 bit ++;
2146                 if (bit == 8) {
2147                         byte++;
2148                         bit = 0;
2149                 }
2150 
2151         } /* for (x = circuit; x < (circuit + range + 1); x++) */
2152 
2153         /* get the ftdmchan and ss7_chan_data from the circuit */
2154         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
2155                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
2156                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
2157                 return FTDM_FAIL;
2158         }
2159 
2160         ft_to_sngss7_cgua(ftdmchan);
2161 
2162         return FTDM_SUCCESS;
2163 }
2164 
2165 /******************************************************************************/
2166 ftdm_status_t handle_olm_msg(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
2167 {
2168         SS7_FUNC_TRACE_ENTER(__FUNCTION__);
2169 
2170         sngss7_chan_data_t      *sngss7_info = NULL;
2171         ftdm_channel_t          *ftdmchan = NULL;
2172 
2173         /* get the ftdmchan and ss7_chan_data from the circuit */
2174         if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
2175                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
2176                 SS7_FUNC_TRACE_EXIT(__FUNCTION__);
2177                 return FTDM_FAIL;
2178         }
2179 
2180         /* handle overload */
2181         SS7_ERROR_CHAN(ftdmchan,"[CIC:%d]Rx Overload\n", sngss7_info->circuit->cic);
2182 
2183         sng_isup_reg_info_show();
2184 
2185         SS7_FUNC_TRACE_EXIT(__FUNCTION__);
2186         return FTDM_SUCCESS;
2187 }
2188 
2189 /******************************************************************************/
2190 /* For Emacs:
2191  * Local Variables:
2192  * mode:c
2193  * indent-tabs-mode:t
2194  * tab-width:4
2195  * c-basic-offset:4
2196  * End:
2197  * For VIM:
2198  * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
2199  */
2200 /******************************************************************************/

/* [<][>][^][v][top][bottom][index][help] */