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

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