root/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c

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

DEFINITIONS

This source file includes following definitions.
  1. sngisdn_process_con_ind
  2. sngisdn_process_con_cfm
  3. sngisdn_process_cnst_ind
  4. sngisdn_process_disc_ind
  5. sngisdn_process_rel_ind
  6. sngisdn_process_dat_ind
  7. sngisdn_process_sshl_ind
  8. sngisdn_process_sshl_cfm
  9. sngisdn_process_rmrt_ind
  10. sngisdn_process_rmrt_cfm
  11. sngisdn_process_flc_ind
  12. sngisdn_process_fac_ind
  13. sngisdn_process_sta_cfm
  14. sngisdn_process_srv_ind
  15. sngisdn_process_srv_cfm
  16. sngisdn_process_restart_confirm
  17. sngisdn_process_rst_cfm
  18. sngisdn_process_rst_ind
  19. sngisdn_cause_val_requires_disconnect

   1 /*
   2  * Copyright (c) 2010, Sangoma Technologies
   3  * David Yat Sin <dyatsin@sangoma.com>
   4  * All rights reserved.
   5  *
   6  * Redistribution and use in source and binary forms, with or without
   7  * modification, are permitted provided that the following conditions
   8  * are met:
   9  *
  10  * * Redistributions of source code must retain the above copyright
  11  * notice, this list of conditions and the following disclaimer.
  12  *
  13  * * Redistributions in binary form must reproduce the above copyright
  14  * notice, this list of conditions and the following disclaimer in the
  15  * documentation and/or other materials provided with the distribution.
  16  *
  17  * * Neither the name of the original author; nor the names of any contributors
  18  * may be used to endorse or promote products derived from this software
  19  * without specific prior written permission.
  20  *
  21  *
  22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  25  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
  26  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  27  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  28  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  29  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  30  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  31  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  32  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33  */
  34 
  35 #include "ftmod_sangoma_isdn.h"
  36 static ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn);
  37 static void sngisdn_process_restart_confirm(ftdm_channel_t *ftdmchan);
  38 
  39 /* Remote side transmit a SETUP */
  40 void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
  41 {
  42         unsigned i;
  43         int16_t suId = sngisdn_event->suId;
  44         uint32_t suInstId = sngisdn_event->suInstId;
  45         uint32_t spInstId = sngisdn_event->spInstId;
  46         int16_t dChan = sngisdn_event->dChan;
  47         uint8_t ces = sngisdn_event->ces;
  48         sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;        
  49         ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
  50         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
  51         ConEvnt *conEvnt = &sngisdn_event->event.conEvnt;
  52 
  53         ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
  54 
  55         ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n");
  56         
  57         ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
  58                 
  59         switch (ftdmchan->state) {
  60                 case FTDM_CHANNEL_STATE_DOWN: /* Proper state to receive a SETUP */
  61                         if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE) ||
  62                                 ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
  63 
  64                                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Received SETUP but channel is in USE, saving call for later processing\n");
  65                                 /* the flag the channel as having a collision */
  66                                 sngisdn_set_flag(sngisdn_info, FLAG_GLARE);
  67 
  68                                 /* save the SETUP for processing once the channel has gone to DOWN */
  69                                 memcpy(&sngisdn_info->glare.setup, conEvnt, sizeof(*conEvnt));
  70                                 sngisdn_info->glare.suId = suId;
  71                                 sngisdn_info->glare.suInstId = suInstId; /* Do not generate a suInstId now, we will generate when glared call gets extracted */
  72                                 sngisdn_info->glare.spInstId = spInstId;
  73                                 sngisdn_info->glare.dChan = dChan;
  74                                 sngisdn_info->glare.ces = ces;                          
  75                                 break;
  76                         }
  77                         
  78                         sngisdn_info->suInstId = get_unique_suInstId(suId);
  79                         sngisdn_info->spInstId = spInstId;
  80 
  81                         if (conEvnt->cdPtyNmb.eh.pres && signal_data->num_local_numbers) {
  82                                 uint8_t local_number_matched = 0;
  83                                 for (i = 0 ; i < signal_data->num_local_numbers ; i++) {
  84                                         if (!strcmp(signal_data->local_numbers[i], (char*)conEvnt->cdPtyNmb.nmbDigits.val)) {
  85                                                 local_number_matched++;
  86                                                 break;
  87                                         }
  88                                 }
  89                                 if (!local_number_matched) {
  90                                         ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received SETUP, but local-number %s does not match - ignoring\n", conEvnt->cdPtyNmb.nmbDigits.val);
  91                                         /* Special case to tell the stack to clear all internal resources about this call. We will no receive any event for this call after sending disconnect request */
  92                                         ftdmchan->caller_data.hangup_cause = IN_CCNORTTODEST;
  93                                         ftdm_sched_timer(signal_data->sched, "delayed_disconnect", 1, sngisdn_delayed_disconnect, (void*) sngisdn_info, NULL);
  94                                         return;
  95                                 }
  96                         }
  97 
  98                         /* If this is a glared call that was previously saved, we moved
  99                         all the info to the current call, so clear the glared saved data */
 100                         if (sngisdn_info->glare.spInstId == spInstId) {
 101                                 clear_call_glare_data(sngisdn_info);
 102                         }
 103 
 104                         
 105                         if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
 106                                 if (signal_data->signalling == SNGISDN_SIGNALING_NET) {
 107                                         sngisdn_info->ces = ces;
 108                                 }
 109                         }
 110 
 111                         ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex);
 112                         g_sngisdn_data.ccs[suId].active_suInstIds[sngisdn_info->suInstId] = sngisdn_info;
 113                         ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex);
 114 
 115                         ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND);
 116 
 117                         /* try to open the channel */
 118                         if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
 119                                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Failed to open channel");
 120                                 sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_REL);
 121                                 ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_TEMPORARY_FAILURE;
 122                                 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
 123                                 break;
 124                         }
 125 
 126                         /* Fill in call information */
 127 #ifdef NETBORDER_CALL_REF
 128                         get_callref(ftdmchan, &conEvnt->callRef);
 129 #endif
 130                         get_calling_num(ftdmchan, &conEvnt->cgPtyNmb);
 131                         get_calling_num2(ftdmchan, &conEvnt->cgPtyNmb2);
 132                         get_called_num(ftdmchan, &conEvnt->cdPtyNmb);
 133                         get_redir_num(ftdmchan, &conEvnt->redirNmb);
 134                         get_calling_subaddr(ftdmchan, &conEvnt->cgPtySad);
 135                         get_prog_ind_ie(ftdmchan, &conEvnt->progInd);
 136                         get_facility_ie(ftdmchan, &conEvnt->facilityStr);                       
 137                         
 138                         if (get_calling_name_from_display(ftdmchan, &conEvnt->display) != FTDM_SUCCESS) {
 139                                 get_calling_name_from_usr_usr(ftdmchan, &conEvnt->usrUsr);
 140                         }
 141 
 142                         ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Incoming call: Called No:[%s] Calling No:[%s]\n", ftdmchan->caller_data.dnis.digits, ftdmchan->caller_data.cid_num.digits);
 143 
 144                         if (conEvnt->bearCap[0].eh.pres) {
 145                                 ftdmchan->caller_data.bearer_layer1 = sngisdn_get_usrInfoLyr1Prot_from_stack(conEvnt->bearCap[0].usrInfoLyr1Prot.val);
 146                                 ftdmchan->caller_data.bearer_capability = sngisdn_get_infoTranCap_from_stack(conEvnt->bearCap[0].infoTranCap.val);
 147                         }
 148                         
 149                         if (conEvnt->shift11.eh.pres && conEvnt->ni2OctStr.eh.pres) {
 150                                 if (conEvnt->ni2OctStr.str.len == 4 && conEvnt->ni2OctStr.str.val[0] == 0x37) {
 151                                         uint8_t encoding = (conEvnt->ni2OctStr.str.val[2] >> 5);
 152                                         if (encoding == 0 || encoding == 1) {
 153                                                 /* BCD even or BCD odd */
 154                                                 uint8_t value = (conEvnt->ni2OctStr.str.val[3] & 0x0F)*10 + ((conEvnt->ni2OctStr.str.val[3] >> 4) & 0x0F);
 155                                                 snprintf(ftdmchan->caller_data.aniII, 5, "%.2d", value);
 156                                         } else if (encoding == 2) {
 157                                                 /* IA 5 */
 158                                                 snprintf(ftdmchan->caller_data.aniII, 5, "%c", conEvnt->ni2OctStr.str.val[3]);
 159                                         }
 160                                 }
 161                         }
 162 
 163                         /* this should be in get_facility_ie function, fix this later */
 164                         if (signal_data->facility == SNGISDN_OPT_TRUE && conEvnt->facilityStr.eh.pres) {
 165                                 /* Verify whether the Caller Name will come in a subsequent FACILITY message */
 166                                 uint16_t ret_val;
 167                                 char retrieved_str[255];
 168 
 169                                 ret_val = sng_isdn_retrieve_facility_caller_name(conEvnt->facilityStr.facilityStr.val, conEvnt->facilityStr.facilityStr.len, retrieved_str);
 170                                         /*
 171                                                 return values for "sng_isdn_retrieve_facility_information_following":
 172                                 If there will be no information following, or fails to decode IE, returns -1
 173                                 If there will be no information following, but current FACILITY IE contains a caller name, returns 0
 174                                 If there will be information following, returns 1
 175                                                                                 */
 176 
 177                                 if (ret_val == 1) {
 178                                         ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Expecting Caller name in FACILITY\n");
 179                                         ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_GET_CALLERID);
 180                                         /* Launch timer in case we never get a FACILITY msg */
 181                                         if (signal_data->facility_timeout) {
 182                                                 ftdm_sched_timer(signal_data->sched, "facility_timeout", signal_data->facility_timeout,
 183                                                                                  sngisdn_facility_timeout, (void*) sngisdn_info, &sngisdn_info->timers[SNGISDN_TIMER_FACILITY]);
 184                                         }
 185                                         break;
 186                                 } else if (ret_val == 0) {
 187                                         strcpy(ftdmchan->caller_data.cid_name, retrieved_str);
 188                                 }
 189                         }
 190                         
 191                         if (signal_data->overlap_dial == SNGISDN_OPT_TRUE && !conEvnt->sndCmplt.eh.pres) {
 192                                 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_COLLECT);
 193                         } else {
 194                                 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
 195                         }
 196                         break;
 197                 case FTDM_CHANNEL_STATE_TERMINATING:
 198                         ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Processing SETUP in TERMINATING state, saving SETUP info for later processing\n");
 199                         ftdm_assert(!sngisdn_test_flag(sngisdn_info, FLAG_GLARE), "Trying to save GLARE info, but we already had a glare\n");
 200                         
 201                         sngisdn_set_flag(sngisdn_info, FLAG_GLARE);
 202 
 203                         /* save the SETUP for processing once the channel has gone to DOWN */
 204                         memcpy(&sngisdn_info->glare.setup, conEvnt, sizeof(*conEvnt));
 205                         sngisdn_info->glare.suId = suId;
 206                         sngisdn_info->glare.suInstId = suInstId; /* Do not generate a suInstId now, we will generate when glared call gets extracted */
 207                         sngisdn_info->glare.spInstId = spInstId;
 208                         sngisdn_info->glare.dChan = dChan;
 209                         sngisdn_info->glare.ces = ces;
 210                         
 211                         break;
 212                 case FTDM_CHANNEL_STATE_DIALING:        /* glare */
 213                         if (signal_data->signalling == SNGISDN_SIGNALING_NET) {
 214                                 /* Save inbound call info so we can send a RELEASE when this channel goes to a different state */
 215                                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Processing SETUP in DIALING state, rejecting inbound call\n");
 216                                 sngisdn_set_flag(sngisdn_info, FLAG_DELAYED_REL);
 217 
 218                                 sngisdn_info->glare.suId = suId;
 219                                 sngisdn_info->glare.suInstId = get_unique_suInstId(suId);
 220                                 sngisdn_info->glare.spInstId = spInstId;
 221 
 222                                 sngisdn_info->glare.dChan = dChan;
 223                                 sngisdn_info->glare.ces = ces;
 224                                 ftdmchan->caller_data.hangup_cause = 0x2C; /* Channel requested not available */
 225                                 ftdm_sched_timer(signal_data->sched, "delayed_release", 1, sngisdn_delayed_release, (void*) sngisdn_info, NULL);
 226                         } else {
 227                                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Processing SETUP in DIALING state, saving SETUP info for later processing\n");
 228                                 
 229                                 /* the flag the channel as having a collision */
 230                                 ftdm_assert(!sngisdn_test_flag(sngisdn_info, FLAG_GLARE), "Trying to save GLARE info, but we already had a glare");
 231                                 sngisdn_set_flag(sngisdn_info, FLAG_GLARE);
 232 
 233                                 /* save the SETUP for processing once the channel has gone to DOWN */
 234                                 memcpy(&sngisdn_info->glare.setup, conEvnt, sizeof(*conEvnt));
 235                                 sngisdn_info->glare.suId = suId;
 236                                 sngisdn_info->glare.suInstId = suInstId; /* Do not generate a suInstId now, we will generate when glared call gets extracted */
 237                                 sngisdn_info->glare.spInstId = spInstId;
 238                                 sngisdn_info->glare.dChan = dChan;
 239                                 sngisdn_info->glare.ces = ces;
 240 
 241                                 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
 242                         }
 243                         break;
 244                 case FTDM_CHANNEL_STATE_RESET:
 245                                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
 246                         break;
 247                 default:
 248                         ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing SETUP in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
 249                         break;
 250         }
 251         ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
 252         return;
 253 }
 254 
 255 /* Remote side transmit a CONNECT or CONNECT ACK */
 256 void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
 257 {
 258         int16_t suId = sngisdn_event->suId;
 259         uint32_t suInstId = sngisdn_event->suInstId;
 260         uint32_t spInstId = sngisdn_event->spInstId;
 261         uint8_t ces = sngisdn_event->ces;
 262         sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
 263         ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
 264         CnStEvnt *cnStEvnt = &sngisdn_event->event.cnStEvnt;
 265 
 266         ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
 267                                 
 268         ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n");
 269         
 270         ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing CONNECT/CONNECT ACK (suId:%u suInstId:%u spInstId:%u ces:%d)\n", suId, suInstId, spInstId, ces);
 271 
 272         if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP &&
 273                 ((sngisdn_span_data_t*)ftdmchan->span->signal_data)->signalling == SNGISDN_SIGNALING_NET) {
 274 
 275                 if(sngisdn_info->ces == CES_MNGMNT) {
 276                         /* We assign the call to the first TE */
 277                         sngisdn_info->ces = ces;
 278                 } else {
 279                         /* We already assigned this call, do nothing */
 280                         ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Call already assigned, ignoring connect\n");
 281                         ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
 282                         return;
 283                 }
 284         }
 285 
 286         if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
 287                 switch(ftdmchan->state) {
 288                         case FTDM_CHANNEL_STATE_PROCEED:
 289                         case FTDM_CHANNEL_STATE_RINGING:
 290                         case FTDM_CHANNEL_STATE_PROGRESS:
 291                         case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
 292                         case FTDM_CHANNEL_STATE_DIALING:
 293 #ifdef NETBORDER_CALL_REF
 294                                 get_callref(ftdmchan, &cnStEvnt->callRef);
 295 #endif
 296                                 get_prog_ind_ie(ftdmchan, &cnStEvnt->progInd);
 297                                 get_facility_ie(ftdmchan, &cnStEvnt->facilityStr);
 298                                 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP);
 299                                 break;
 300                         case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
 301                         case FTDM_CHANNEL_STATE_HANGUP:
 302                                 /* Race condition, we just hung up the call - ignore this message */
 303                                 break;
 304                         case FTDM_CHANNEL_STATE_RESET:
 305                                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
 306                                 break;                          
 307                         default:
 308                                 ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing CONNECT/CONNECT ACK in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
 309 
 310                                 /* Start the disconnect procedure */
 311                                 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
 312                                 break;
 313                 }
 314         } else {
 315                 switch(ftdmchan->state) {
 316                         case FTDM_CHANNEL_STATE_UP:
 317                                 /* This is the only valid state we should get a CONNECT ACK on */
 318                                 /* do nothing */
 319                                 break;
 320                         case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
 321                                 /* Race condition, We just hung up an incoming call right after we sent a CONNECT - ignore this message */
 322                                 break;
 323                         case FTDM_CHANNEL_STATE_RESET:
 324                                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
 325                                 break;
 326                         default:
 327                                 ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing CONNECT/CONNECT ACK in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
 328                                 
 329                                 /* Start the disconnect procedure */
 330                                 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
 331                                 break;
 332                 }
 333         }
 334 
 335         ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
 336         return;
 337 }
 338 
 339 void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
 340 {
 341         int16_t suId = sngisdn_event->suId;
 342         uint32_t suInstId = sngisdn_event->suInstId;
 343         uint32_t spInstId = sngisdn_event->spInstId;
 344         uint8_t ces = sngisdn_event->ces;
 345         uint8_t evntType = sngisdn_event->evntType;
 346         
 347         sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
 348         ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
 349         
 350         CnStEvnt *cnStEvnt = &sngisdn_event->event.cnStEvnt;
 351 
 352         ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
 353 
 354         ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n");
 355 
 356         ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing %s (suId:%u suInstId:%u spInstId:%u ces:%d)\n",
 357                                                                                                         (evntType == MI_ALERTING)?"ALERT":
 358                                                                                                         (evntType == MI_CALLPROC)?"PROCEED":
 359                                                                                                         (evntType == MI_PROGRESS)?"PROGRESS":
 360                                                                                                         (evntType == MI_SETUPACK)?"SETUP ACK":
 361                                                                                                                         (evntType == MI_INFO)?"INFO":"UNKNOWN",
 362                                                                                                                         suId, suInstId, spInstId, ces);
 363         
 364         switch(evntType) {
 365                 case MI_CALLPROC:                       
 366                 case MI_PROGRESS:
 367                 case MI_ALERTING:
 368 #ifdef NETBORDER_CALL_REF
 369                         get_callref(ftdmchan, &cnStEvnt->callRef);
 370 #endif
 371                         get_prog_ind_ie(ftdmchan, &cnStEvnt->progInd);
 372                         get_facility_ie(ftdmchan, &cnStEvnt->facilityStr);
 373 
 374                         if (sngisdn_cause_val_requires_disconnect(ftdmchan, &cnStEvnt->causeDgn[0]) == FTDM_SUCCESS) {
 375                                 ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Cause requires disconnect (cause:%d)\n", cnStEvnt->causeDgn[0].causeVal.val);
 376                                 ftdmchan->caller_data.hangup_cause = cnStEvnt->causeDgn[0].causeVal.val;
 377                                                 
 378                                 sngisdn_set_flag(sngisdn_info, FLAG_SEND_DISC);
 379                                 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
 380                                 goto sngisdn_process_cnst_ind_end;
 381                         }
 382 
 383                         switch(ftdmchan->state) {
 384                                 case FTDM_CHANNEL_STATE_DIALING:
 385                                 case FTDM_CHANNEL_STATE_PROCEED:
 386                                 case FTDM_CHANNEL_STATE_PROGRESS:
 387                                 case FTDM_CHANNEL_STATE_RINGING:
 388                                         if (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL) {
 389                                                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Early media available\n");
 390                                                 sngisdn_set_flag(sngisdn_info, FLAG_MEDIA_READY);
 391                                         } else {
 392                                                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Early media not available\n");
 393                                         }
 394                                         switch (evntType) {
 395                                                 case MI_CALLPROC:
 396                                                         if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALING) {
 397                                                                 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROCEED);
 398                                                         }
 399                                                         break;
 400                                                 case MI_ALERTING:
 401                                                         if (ftdmchan->state == FTDM_CHANNEL_STATE_PROCEED) {
 402                                                                 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RINGING);
 403                                                         }
 404                                                         break;
 405                                                 case MI_PROGRESS:
 406                                                         if (sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY)) {
 407                                                                 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
 408                                                         } else if (ftdmchan->state != FTDM_CHANNEL_STATE_PROGRESS) {
 409                                                                 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
 410                                                         }
 411                                                         break;
 412                                                 default:
 413                                                         /* We should never reach this section !*/
 414                                                         ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle this event %d\n", evntType);
 415                                         }
 416                                         break;
 417                                 case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
 418                                         /* We are already in progress media, we can't go to any higher state except up */
 419                                         /* Do nothing */
 420                                         break;
 421                                 case FTDM_CHANNEL_STATE_RESET:
 422                                         ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
 423                                         break;
 424                                 default:
 425                                         ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing ALERT/PROCEED/PROGRESS in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
 426 
 427                                         /* Start the disconnect procedure */
 428                                         ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
 429                                         break;
 430                         }
 431                         break;
 432                 case MI_SETUPACK:
 433                         ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Processing SETUP_ACK, but overlap sending not implemented (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
 434                         break;
 435                 case MI_INFO:
 436                         ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing INFO (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
 437 
 438                         if (cnStEvnt->cdPtyNmb.eh.pres) {
 439                                 switch(ftdmchan->state) {
 440                                         case FTDM_CHANNEL_STATE_COLLECT:
 441                                         {
 442                                                 ftdm_size_t min_digits = ((sngisdn_span_data_t*)ftdmchan->span->signal_data)->min_digits;
 443                                                 ftdm_size_t num_digits;
 444 
 445                                                 get_called_num(ftdmchan, &cnStEvnt->cdPtyNmb);
 446                                                 num_digits = strlen(ftdmchan->caller_data.dnis.digits);
 447 
 448                                                 if (cnStEvnt->sndCmplt.eh.pres || num_digits >= min_digits) {
 449                                                         ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
 450                                                 } else {
 451                                                         ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "received %d of %d digits\n", num_digits, min_digits);
 452                                                 }
 453                                         }
 454                                         break;
 455                                         case FTDM_CHANNEL_STATE_RING:
 456                                         case FTDM_CHANNEL_STATE_RINGING:
 457                                         case FTDM_CHANNEL_STATE_PROCEED:
 458                                         case FTDM_CHANNEL_STATE_PROGRESS:
 459                                         case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
 460                                         case FTDM_CHANNEL_STATE_UP:
 461                                                 ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Receiving more digits %s, but we already proceeded with call\n", cnStEvnt->cdPtyNmb.nmbDigits.val);
 462                                                 break;
 463                                         case FTDM_CHANNEL_STATE_RESET:
 464                                                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
 465                                                 break;
 466                                         default:
 467                                                 ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "\n", suId, suInstId, spInstId);
 468                                                 break;
 469                                 }
 470                         }
 471 
 472                         break;
 473                 default:
 474                         ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Unhandled STATUS event\n");
 475                         break;
 476         }
 477 
 478 sngisdn_process_cnst_ind_end:
 479         ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
 480         return;
 481 }
 482 
 483 void sngisdn_process_disc_ind (sngisdn_event_data_t *sngisdn_event)
 484 {
 485         int16_t suId = sngisdn_event->suId;
 486         uint32_t suInstId = sngisdn_event->suInstId;
 487         uint32_t spInstId = sngisdn_event->spInstId;
 488         sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
 489         ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
 490         
 491         DiscEvnt *discEvnt = &sngisdn_event->event.discEvnt;
 492 
 493         ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
 494 
 495         ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing DISCONNECT (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
 496 
 497         ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n");
 498         switch (ftdmchan->state) {              
 499                 case FTDM_CHANNEL_STATE_RING:
 500                 case FTDM_CHANNEL_STATE_RINGING:
 501                 case FTDM_CHANNEL_STATE_DIALING:
 502                 case FTDM_CHANNEL_STATE_PROCEED:
 503                 case FTDM_CHANNEL_STATE_PROGRESS:
 504                 case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
 505                 case FTDM_CHANNEL_STATE_UP:
 506                         get_facility_ie(ftdmchan, &discEvnt->facilityStr);
 507 
 508                         if (discEvnt->causeDgn[0].eh.pres && discEvnt->causeDgn[0].causeVal.pres) {
 509                                 ftdmchan->caller_data.hangup_cause = discEvnt->causeDgn[0].causeVal.val;
 510                         } else {
 511                                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "DISCONNECT did not have a cause code\n");
 512                                 ftdmchan->caller_data.hangup_cause = 0;
 513                         }
 514                         sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_REL);
 515                         ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
 516                         break;
 517                 case FTDM_CHANNEL_STATE_COLLECT:
 518                 case FTDM_CHANNEL_STATE_GET_CALLERID:
 519                         ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
 520                         break;
 521                 case FTDM_CHANNEL_STATE_DOWN:
 522                         /* somehow we are in down, nothing we can do locally */
 523                         ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Received DISCONNECT but we are in DOWN state\n");
 524                         break;
 525                 case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
 526                         /* This is a race condition. We just sent a DISCONNECT, on this channel */
 527                         /* Do nothing */
 528                         break;
 529                 case FTDM_CHANNEL_STATE_RESET:
 530                         ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
 531                         break;
 532                 default:
 533                         ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received DISCONNECT in an invalid state (%s)\n",
 534                                                   ftdm_channel_state2str(ftdmchan->state));
 535                         /* start reset procedure */
 536 
 537                         /* Start the release procedure */
 538                         ftdm_set_flag(sngisdn_info, FLAG_REMOTE_REL);
 539                         ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
 540                         break;
 541         }
 542 
 543         ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
 544         return;
 545 }
 546 
 547 void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event)
 548 {
 549         int16_t suId = sngisdn_event->suId;
 550         uint32_t suInstId = sngisdn_event->suInstId;
 551         uint32_t spInstId = sngisdn_event->spInstId;
 552         sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;        
 553         ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
 554         
 555         RelEvnt *relEvnt = &sngisdn_event->event.relEvnt;
 556 
 557         ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
 558 
 559         ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing RELEASE/RELEASE COMPLETE (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
 560         
 561         ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n");
 562         
 563         if ((suInstId && (sngisdn_info->glare.suInstId == suInstId)) ||
 564                 (spInstId && (sngisdn_info->glare.spInstId == spInstId))) {
 565 
 566                 /* This hangup is for a glared saved call */
 567                 ftdm_clear_flag(sngisdn_info, FLAG_DELAYED_REL);
 568                 clear_call_glare_data(sngisdn_info);
 569 
 570                 ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
 571                 return;
 572         }
 573 
 574         /* check whether the ftdm channel is in a state to accept a call */
 575         switch (ftdmchan->state) {
 576                 case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
 577                         /* go to DOWN */
 578                         ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
 579                         break;
 580                 case FTDM_CHANNEL_STATE_DOWN:
 581                         /* do nothing, just drop the message */
 582                         break;
 583                 case FTDM_CHANNEL_STATE_DIALING:
 584                         /* Remote side rejected our SETUP message on outbound call */
 585                         if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
 586                                 sngisdn_set_span_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN);
 587                         }
 588                         /* fall-through */
 589                 case FTDM_CHANNEL_STATE_PROCEED:
 590                 case FTDM_CHANNEL_STATE_PROGRESS:
 591                 case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
 592                 case FTDM_CHANNEL_STATE_UP:
 593                 case FTDM_CHANNEL_STATE_RING:
 594                 case FTDM_CHANNEL_STATE_RINGING:
 595                         /* If we previously had a glare on this channel,
 596                         this RELEASE could be for the previous call.  Confirm whether call_data has
 597                         not changed while we were waiting for ftdmchan->mutex by comparing suInstId's */
 598                         if (((sngisdn_chan_data_t*)ftdmchan->call_data)->suInstId == suInstId ||
 599                                                                         ((sngisdn_chan_data_t*)ftdmchan->call_data)->spInstId == spInstId) {
 600 
 601                                 get_facility_ie(ftdmchan, &relEvnt->facilityStr);
 602                                 
 603                                 if (relEvnt->causeDgn[0].eh.pres && relEvnt->causeDgn[0].causeVal.pres) {
 604                                         ftdmchan->caller_data.hangup_cause = relEvnt->causeDgn[0].causeVal.val;
 605                                         ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "cause:%d\n", ftdmchan->caller_data.hangup_cause);
 606                                 } else {
 607                                         ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "RELEASE COMPLETE did not have a cause code\n");
 608                                         ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_REQUESTED_CHAN_UNAVAIL;
 609                                 }
 610 
 611                                 sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_ABORT);
 612                                 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
 613 
 614                         } else {
 615                                 ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "RELEASE was for previous call (suInstId:%u spInstId:%u)\n", suInstId, spInstId);
 616                         }
 617                         break;
 618                 case FTDM_CHANNEL_STATE_COLLECT:
 619                 case FTDM_CHANNEL_STATE_GET_CALLERID:
 620                         ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
 621                         break;
 622                 case FTDM_CHANNEL_STATE_TERMINATING:
 623                         if (sngisdn_test_flag(sngisdn_info, FLAG_GLARE) &&
 624                                                                 sngisdn_info->glare.suInstId != suInstId) {
 625                                 /* This release if for the outbound call that we already started clearing */
 626 
 627                                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Received RELEASE for local glared call\n");
 628                                 sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_ABORT);
 629                         } else {
 630                                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Received release before we could clear local call\n");
 631                                 /* FS core took too long to respond to the SIG STOP event */
 632                                 sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_ABORT);
 633                                 /* set abort flag so that we do not transmit another release complete on this channel once FS core is done */
 634                         }
 635                         break;
 636                 case FTDM_CHANNEL_STATE_RESET:
 637                         ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
 638                         break;
 639                 default:
 640                         ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received RELEASE in an invalid state (%s)\n",
 641                                                         ftdm_channel_state2str(ftdmchan->state));
 642 
 643                         break;
 644         }
 645 
 646 
 647         ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
 648         return;
 649 }
 650 
 651 void sngisdn_process_dat_ind (sngisdn_event_data_t *sngisdn_event)
 652 {
 653         int16_t suId = sngisdn_event->suId;
 654         uint32_t suInstId = sngisdn_event->suInstId;
 655         uint32_t spInstId = sngisdn_event->spInstId;
 656 
 657         sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
 658         ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
 659 
 660         ISDN_FUNC_TRACE_ENTER(__FUNCTION__);    
 661 
 662         /* Function does not require any info from infoEvnt struct for now */
 663         /* InfoEvnt *infoEvnt = &sngisdn_event->event.infoEvnt; */
 664         
 665         ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing DATA IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
 666         ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
 667         return;
 668 }
 669 
 670 void sngisdn_process_sshl_ind (sngisdn_event_data_t *sngisdn_event)
 671 {
 672         int16_t suId = sngisdn_event->suId;
 673         uint32_t suInstId = sngisdn_event->suInstId;
 674         uint32_t spInstId = sngisdn_event->spInstId;
 675 
 676         sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
 677         ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
 678 
 679         ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
 680 
 681         /* Function does not require any info from ssHlEvnt struct for now */
 682         /* SsHlEvnt *ssHlEvnt = &sngisdn_event->event.ssHlEvnt; */
 683         
 684         ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing SSHL IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
 685         ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
 686         return;
 687 }
 688 
 689 void sngisdn_process_sshl_cfm (sngisdn_event_data_t *sngisdn_event)
 690 {
 691         int16_t suId = sngisdn_event->suId;
 692         uint32_t suInstId = sngisdn_event->suInstId;
 693         uint32_t spInstId = sngisdn_event->spInstId;
 694 
 695         sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
 696         ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
 697 
 698         ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
 699         
 700         /* Function does not require any info from ssHlEvnt struct for now */
 701         /* SsHlEvnt *ssHlEvnt = &sngisdn_event->event.ssHlEvnt; */
 702 
 703         ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing SSHL CFM (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
 704         ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
 705         return;
 706 }
 707 
 708 void sngisdn_process_rmrt_ind (sngisdn_event_data_t *sngisdn_event)
 709 {
 710         int16_t suId = sngisdn_event->suId;
 711         uint32_t suInstId = sngisdn_event->suInstId;
 712         uint32_t spInstId = sngisdn_event->spInstId;
 713 
 714         sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
 715         ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
 716 
 717         ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
 718 
 719         /* Function does not require any info from ssHlEvnt struct for now */
 720         /* RmRtEvnt *rmRtEvnt = &sngisdn_event->event.rmRtEvnt; */
 721 
 722         ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing RESUME/RETRIEVE IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
 723         ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
 724         return;
 725 }
 726 
 727 void sngisdn_process_rmrt_cfm (sngisdn_event_data_t *sngisdn_event)
 728 {
 729         int16_t suId = sngisdn_event->suId;
 730         uint32_t suInstId = sngisdn_event->suInstId;
 731         uint32_t spInstId = sngisdn_event->spInstId;
 732 
 733         sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
 734         ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
 735         
 736         ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
 737 
 738         /* Function does not require any info from ssHlEvnt struct for now */
 739         /* RmRtEvnt *rmRtEvnt = &sngisdn_event->event.rmRtEvnt; */
 740         
 741         ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing RESUME/RETRIEVE CFM (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
 742         ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
 743         return;
 744 }
 745 
 746 void sngisdn_process_flc_ind (sngisdn_event_data_t *sngisdn_event)
 747 {
 748         int16_t suId = sngisdn_event->suId;
 749         uint32_t suInstId = sngisdn_event->suInstId;
 750         uint32_t spInstId = sngisdn_event->spInstId;
 751 
 752         sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
 753         ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
 754 
 755         ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
 756 
 757         /* Function does not require any info from ssHlEvnt struct for now */
 758         /* StaEvnt *staEvnt = &sngisdn_event->event.staEvnt; */
 759 
 760         ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing FLOW CONTROL IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
 761         ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
 762         return;
 763 }
 764 
 765 void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event)
 766 {
 767         int16_t suId = sngisdn_event->suId;
 768         uint32_t suInstId = sngisdn_event->suInstId;
 769         uint32_t spInstId = sngisdn_event->spInstId;
 770 
 771         sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
 772         ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
 773         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
 774 
 775         FacEvnt *facEvnt = &sngisdn_event->event.facEvnt;
 776 
 777         ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
 778 
 779         ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing FACILITY IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
 780 
 781         switch (ftdmchan->state) {
 782                 case FTDM_CHANNEL_STATE_GET_CALLERID:
 783                         /* Update the caller ID Name */
 784 
 785                         if (facEvnt->facElmt.facStr.pres) {
 786                                 char retrieved_str[255];
 787 
 788                                 /* return values for "sng_isdn_retrieve_facility_information_following":
 789                                 If there will be no information following, or fails to decode IE, returns -1
 790                                 If there will be no information following, but current FACILITY IE contains a caller name, returns 0
 791                                 If there will be information following, returns 1
 792                                 */
 793 
 794                                 if (sng_isdn_retrieve_facility_caller_name(&facEvnt->facElmt.facStr.val[2], facEvnt->facElmt.facStr.len, retrieved_str) == 0) {
 795                                         strcpy(ftdmchan->caller_data.cid_name, retrieved_str);
 796                                 } else {
 797                                         ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Failed to retrieve Caller Name from Facility IE\n");
 798                                 }
 799                                 if (signal_data->facility_timeout) {
 800                                         /* Cancel facility timeout */
 801                                         ftdm_sched_cancel_timer(signal_data->sched, sngisdn_info->timers[SNGISDN_TIMER_FACILITY]);
 802                                 }
 803                         }
 804 
 805                         ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
 806                         break;
 807                 case FTDM_CHANNEL_STATE_RING:
 808                         /* We received the caller ID Name in FACILITY, but its too late, facility-timeout already occurred */
 809                         ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "FACILITY received, but we already proceeded with call\n");
 810                         break;
 811                 case FTDM_CHANNEL_STATE_UP:
 812                         {
 813                                 ftdm_sigmsg_t sigev;
 814                                 if (facEvnt->facElmt.facStr.pres) {
 815                                         get_facility_ie_str(ftdmchan, &facEvnt->facElmt.facStr.val[2], facEvnt->facElmt.facStr.len-2);
 816                                 }
 817                                 memset(&sigev, 0, sizeof(sigev));
 818                                 sigev.chan_id = ftdmchan->chan_id;
 819                                 sigev.span_id = ftdmchan->span_id;
 820                                 sigev.channel = ftdmchan;
 821                                 
 822                                 sigev.event_id = FTDM_SIGEVENT_FACILITY;
 823                                 ftdm_span_send_signal(ftdmchan->span, &sigev);
 824                         }
 825                         break;
 826                 default:
 827                         /* We do not support other FACILITY types for now, so do nothing */
 828                         break;
 829         }
 830         ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
 831         return;
 832 }
 833 
 834 void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event)
 835 {
 836         int16_t suId = sngisdn_event->suId;
 837         uint32_t suInstId = sngisdn_event->suInstId;
 838         uint32_t spInstId = sngisdn_event->spInstId;
 839         sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
 840         ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
 841         
 842         StaEvnt *staEvnt = &sngisdn_event->event.staEvnt;
 843         
 844         uint8_t call_state = 0;
 845 
 846         ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
 847         
 848         if (staEvnt->callSte.eh.pres && staEvnt->callSte.callGlblSte.pres) {
 849                 call_state = staEvnt->callSte.callGlblSte.val;
 850         }
 851 
 852         ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing STATUS CONFIRM (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
 853 
 854         ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n");
 855 
 856         if (staEvnt->causeDgn[0].eh.pres && staEvnt->causeDgn[0].causeVal.pres) {
 857                 if (staEvnt->callSte.eh.pres && staEvnt->callSte.callGlblSte.pres) {
 858                         call_state = staEvnt->callSte.callGlblSte.val;
 859                 } else {
 860                         ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Received STATUS without call state\n");
 861                         ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
 862                         return;
 863                 }
 864                 switch (staEvnt->causeDgn[0].causeVal.val) {
 865                         case FTDM_CAUSE_RESPONSE_TO_STATUS_ENQUIRY:
 866                                 ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Status Check OK:%d", call_state);
 867                                 ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
 868                                 return;
 869                         case FTDM_CAUSE_WRONG_CALL_STATE:
 870                                 ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Message incompatible with call state (call_state:%d channel-state:%s cause:%d) (suId:%u suInstId:%u spInstId:%u)\n", call_state, ftdm_channel_state2str(ftdmchan->state), staEvnt->causeDgn[0].causeVal.val, suId, suInstId, spInstId);
 871                                 break;
 872                         case FTDM_CAUSE_RECOVERY_ON_TIMER_EXPIRE:
 873                                 ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Recovery on timer expire (call_state:%d channel-state:%s cause:%d) (suId:%u suInstId:%u spInstId:%u)\n", call_state, ftdm_channel_state2str(ftdmchan->state), staEvnt->causeDgn[0].causeVal.val, suId, suInstId, spInstId);
 874                                 break;
 875                         default:
 876                                 ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "STATUS CONFIRM (call_state:%d channel-state:%s cause:%d) (suId:%u suInstId:%u spInstId:%u)\n", call_state, ftdm_channel_state2str(ftdmchan->state), staEvnt->causeDgn[0].causeVal.val, suId, suInstId, spInstId);
 877                                 break;
 878                 }
 879 
 880                 /* Section 4.3.30 from INT Interface - Service Definition */
 881                 ftdmchan->caller_data.hangup_cause = staEvnt->causeDgn[0].causeVal.val;
 882                 
 883                 switch(call_state) {
 884                         /* Sere ITU-T Q931 for definition of call states */
 885                         case 0: /* Remote switch thinks there are no calls on this channel */
 886                                 switch (ftdmchan->state) {
 887                                         case FTDM_CHANNEL_STATE_COLLECT:
 888                                         case FTDM_CHANNEL_STATE_DIALING:
 889                                         case FTDM_CHANNEL_STATE_UP:
 890                                                 sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_ABORT);
 891                                                 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
 892                                                 break;
 893                                         case FTDM_CHANNEL_STATE_TERMINATING:
 894                                                 /* We are in the process of clearing local states,
 895                                                 just make sure we will not send any messages to remote switch */
 896                                                 sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_ABORT);
 897                                                 break;
 898                                         case FTDM_CHANNEL_STATE_HANGUP:
 899                                                 /* This cannot happen, state_advance always sets
 900                                                 ftdmchan to STATE_HANGUP_COMPLETE when in STATE_HANGUP
 901                                                 and we called check_for_state_change earlier so something is very wrong here!!! */
 902                                                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "How can we we in FTDM_CHANNEL_STATE_HANGUP after checking for state change?\n");
 903                                                 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
 904                                                 break;
 905                                         case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
 906                                                 /* We were waiting for remote switch to send RELEASE COMPLETE
 907                                                 but this will not happen, so just clear local state */
 908                                                 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
 909                                                 break;
 910                                         case FTDM_CHANNEL_STATE_DOWN:
 911                                                 /* If our local state is down as well, then there is nothing to do */
 912                                                 break;
 913                                         default:
 914                                                 ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state));
 915                                                 break;
 916                                 }
 917                                 break;
 918                         case 1:
 919                                 switch (ftdmchan->state) {
 920                                         case FTDM_CHANNEL_STATE_UP:
 921                                                 /* Remote side is still waiting for our CONNECT message */
 922                                                 if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
 923                                                         ftdm_sched_timer(((sngisdn_span_data_t*)ftdmchan->span->signal_data)->sched, "delayed_connect", 1, sngisdn_delayed_connect, (void*) sngisdn_info, NULL);
 924                                                         break;
 925                                                 }
 926                                                 /* Fall-through */
 927                                         default:
 928                                                 ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state));
 929                                                 break;
 930                                 }
 931                                 break;
 932                                 case 2: /* overlap sending/receiving */
 933                                         switch (ftdmchan->state) {
 934                                                 case FTDM_CHANNEL_STATE_COLLECT:
 935                                                         /* T302 Timeout reached */
 936                                                         /* Send the call to user, and see if they accept it */
 937                                                         ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "T302 Timer expired, proceeding with call\n");
 938                                                         ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
 939                                                         break;
 940                                                 case FTDM_CHANNEL_STATE_PROCEED:
 941                                                 case FTDM_CHANNEL_STATE_PROGRESS:
 942                                                 case FTDM_CHANNEL_STATE_RINGING:
 943                                                 case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
 944                                                         ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Remote switch expecting OVERLAP receive, but we are already PROCEEDING\n");
 945                                                         sngisdn_snd_disconnect(ftdmchan);
 946                                                         break;
 947                                                 case FTDM_CHANNEL_STATE_DOWN:
 948                                                 case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
 949                                                         /* We hung up locally, but remote switch doesn't know send disconnect again*/
 950                                                         sngisdn_snd_disconnect(ftdmchan);
 951                                                         break;
 952                                                 default:
 953                                                         ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state));
 954                                                         break;
 955                                         }
 956                                         break;
 957                         case 3:
 958                                 switch (ftdmchan->state) {
 959                                         case FTDM_CHANNEL_STATE_PROCEED:
 960                                         case FTDM_CHANNEL_STATE_PROGRESS:
 961                                         case FTDM_CHANNEL_STATE_RINGING:
 962                                                 /* T310 timer has expired */
 963                                                 ftdmchan->caller_data.hangup_cause = staEvnt->causeDgn[0].causeVal.val;
 964                                                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "T310 Timer expired, hanging up call\n");
 965                                                 sngisdn_set_flag(sngisdn_info, FLAG_SEND_DISC);
 966                                                 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
 967 
 968                                                 break;
 969                                         case FTDM_CHANNEL_STATE_UP:
 970                                                 /* Remote side is still waiting for our CONNECT message */
 971                                                 if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
 972                                                         ftdm_sched_timer(((sngisdn_span_data_t*)ftdmchan->span->signal_data)->sched, "delayed_connect", 1, sngisdn_delayed_connect, (void*) sngisdn_info, NULL);
 973                                                         break;
 974                                                 }
 975                                                 /* Fall-through */
 976                                         default:
 977                                                 ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state));
 978                                                 break;
 979                                 }
 980                                 break;
 981                         case 8: /* Remote switch is in "Connect Request state" */
 982                                 switch (ftdmchan->state) {
 983                                         case FTDM_CHANNEL_STATE_UP:
 984                                                 /* This is ok. We sent a Connect, and we are waiting for a connect ack */
 985                                                 /* Do nothing */
 986                                                 break;
 987                                         case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
 988                                                 /* We hung up locally, but remote switch doesn't know send disconnect again*/
 989                                                 sngisdn_snd_disconnect(ftdmchan);
 990                                                 break;
 991                                         default:
 992                                                 ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state));
 993                                                 break;
 994                                 }
 995                                 break;
 996                         case 9: /* Remote switch is in "Incoming call proceeding" state */
 997                                 switch (ftdmchan->state) {
 998                                         case FTDM_CHANNEL_STATE_RINGING:
 999                                         case FTDM_CHANNEL_STATE_PROGRESS:
1000                                         case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
1001                                         case FTDM_CHANNEL_STATE_GET_CALLERID:
1002                                                 /* Do nothing */
1003                                                 break;
1004                                         case FTDM_CHANNEL_STATE_UP:
1005                                                 /* Remote switch missed our CONNECT message, re-send */
1006                                                 ftdm_sched_timer(((sngisdn_span_data_t*)ftdmchan->span->signal_data)->sched, "delayed_connect", 1, sngisdn_delayed_connect, (void*) sngisdn_info, NULL);
1007                                                 break;
1008                                         default:
1009                                                 ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state));
1010                                                 break;
1011                                 }
1012                                 break;
1013                         case 10: /* Remote switch is in active state */
1014                                 switch (ftdmchan->state) {
1015                                         case FTDM_CHANNEL_STATE_UP:
1016                                                 /* This is ok, they are in active state and we are in active state */
1017                                                 /* Do nothing */
1018                                                 break;
1019                                         case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
1020                                                 /* We sent a disconnect message, but remote side missed it ? */
1021                                                 ftdm_sched_timer(((sngisdn_span_data_t*)ftdmchan->span->signal_data)->sched, "delayed_disconnect", 1, sngisdn_delayed_disconnect, (void*) sngisdn_info, NULL);
1022                                                 break;
1023                                         default:
1024                                                 ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state));
1025                                                 break;
1026                                 }
1027                                 break;
1028                         case 12: /* We received a disconnect indication */
1029                                 switch (ftdmchan->state) {
1030                                         case FTDM_CHANNEL_STATE_TERMINATING:
1031                                                 /* We are already waiting for user app to handle the disconnect, do nothing */
1032                                                 break;
1033                                         default:
1034                                                 ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state));
1035                                                 break;
1036                                 }
1037                                 break;
1038                         case 22:
1039                                 switch (ftdmchan->state) {
1040                                         case FTDM_CHANNEL_STATE_UP:
1041                                                 /* Stack is in the process of clearing the call*/
1042                                                 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
1043                                                 break;
1044                                         case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
1045                                                 /* Do nothing as we will get a RELEASE COMPLETE */
1046                                                 break;
1047                                         default:
1048                                                 ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state));
1049                                                 //ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
1050                                                 break;
1051                                 }
1052                                 break;
1053                         case 25: /* Overlap receiving */
1054                                 switch (ftdmchan->state) {
1055                                         case FTDM_CHANNEL_STATE_COLLECT:
1056                                                 /* do nothing */
1057                                                 break;
1058                                         default:
1059                                                 ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state));
1060                                                 //ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
1061                                                 break;
1062                                 }
1063                                 break;
1064                         default:
1065                                 ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state));
1066                                                 //ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
1067                                 break;
1068                 }
1069         }
1070 
1071         ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
1072         return;
1073 }
1074 
1075 
1076 void sngisdn_process_srv_ind (sngisdn_event_data_t *sngisdn_event)
1077 {
1078         int16_t suId = sngisdn_event->suId;
1079         int16_t dChan = sngisdn_event->dChan;
1080         uint8_t ces = sngisdn_event->ces;
1081 
1082         ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
1083 
1084         /* Function does not require any info from ssHlEvnt struct for now */
1085         /*Srv *srvEvnt = &sngisdn_event->event.srvEvnt;*/
1086         
1087         ftdm_log(FTDM_LOG_DEBUG, "Processing SERVICE IND (suId:%u dChan:%d ces:%d)\n", suId, dChan, ces);
1088         ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
1089         return;
1090 }
1091 
1092 void sngisdn_process_srv_cfm (sngisdn_event_data_t *sngisdn_event)
1093 {
1094         int16_t suId = sngisdn_event->suId;
1095         int16_t dChan = sngisdn_event->dChan;
1096         uint8_t ces = sngisdn_event->ces;
1097 
1098         ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
1099 
1100         /* Function does not require any info from ssHlEvnt struct for now */
1101         /*Srv *srvEvnt = &sngisdn_event->event.srvEvnt;*/
1102         
1103         ftdm_log(FTDM_LOG_DEBUG, "Processing SERVICE CFM (suId:%u dChan:%d ces:%d)\n", suId, dChan, ces);
1104         ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
1105         return;
1106 }
1107 
1108 static void sngisdn_process_restart_confirm(ftdm_channel_t *ftdmchan)
1109 {
1110         switch (ftdmchan->state) {
1111                 case FTDM_CHANNEL_STATE_RESET:
1112                         ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
1113                         break;
1114                 case FTDM_CHANNEL_STATE_DOWN:
1115                         /* Do nothing */
1116                         break;
1117                 default:
1118                         ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received RESTART CFM in an invalid state (%s)\n",
1119                                                   ftdm_channel_state2str(ftdmchan->state));
1120         }
1121 
1122         return;
1123 }
1124 
1125 
1126 void sngisdn_process_rst_cfm (sngisdn_event_data_t *sngisdn_event)
1127 {
1128         int16_t suId = sngisdn_event->suId;
1129         int16_t dChan = sngisdn_event->dChan;
1130         uint8_t ces = sngisdn_event->ces;
1131         uint8_t evntType = sngisdn_event->evntType;
1132         uint8_t chan_no = 0;
1133         Rst *rstEvnt = &sngisdn_event->event.rstEvnt;
1134         
1135         sngisdn_span_data_t     *signal_data = g_sngisdn_data.dchans[dChan].spans[1];
1136         if (!signal_data) {
1137                 ftdm_log(FTDM_LOG_CRIT, "Received RESTART on unconfigured span (suId:%d)\n", suId);
1138                 return;
1139         }
1140         
1141         if (!rstEvnt->rstInd.eh.pres || !rstEvnt->rstInd.rstClass.pres) {
1142                 ftdm_log(FTDM_LOG_DEBUG, "Receved RESTART, but Restart Indicator IE not present\n");
1143                 return;
1144         }
1145                 
1146         switch(rstEvnt->rstInd.rstClass.val) {
1147                 case IN_CL_INDCHAN: /* Indicated b-channel */
1148                         if (rstEvnt->chanId.eh.pres) {
1149                                 if (rstEvnt->chanId.intType.val == IN_IT_BASIC) {
1150                                         if (rstEvnt->chanId.infoChanSel.pres == PRSNT_NODEF) {
1151                                                 chan_no = rstEvnt->chanId.infoChanSel.val;
1152                                         }
1153                                 } else if (rstEvnt->chanId.intType.val == IN_IT_OTHER) {
1154                                         if (rstEvnt->chanId.chanNmbSlotMap.pres == PRSNT_NODEF) {
1155                                                 chan_no = rstEvnt->chanId.chanNmbSlotMap.val[0];
1156                                         }
1157                                 }
1158                         }
1159                         if (!chan_no) {
1160                                 ftdm_log(FTDM_LOG_CRIT, "Failed to determine channel from RESTART\n");
1161                                 return;
1162                         }
1163                         break;
1164                 case IN_CL_SNGINT: /* Single interface */
1165                 case IN_CL_ALLINT: /* All interfaces */
1166                         /* In case restart class indicates all interfaces, we will duplicate
1167                         this event on each span associated to this d-channel in sngisdn_rcv_rst_cfm,
1168                         so treat it as a single interface anyway */
1169                         break;
1170                 default:
1171                         ftdm_log(FTDM_LOG_CRIT, "Invalid restart indicator class:%d\n", rstEvnt->rstInd.rstClass.val);
1172                         return;
1173         }
1174 
1175         if (chan_no) { /* For a single channel */
1176                 if (chan_no > ftdm_span_get_chan_count(signal_data->ftdm_span)) {
1177                         ftdm_log(FTDM_LOG_CRIT, "Received RESTART on invalid channel:%d\n", chan_no);
1178                 } else {
1179                         ftdm_channel_t *ftdmchan = ftdm_span_get_channel(signal_data->ftdm_span, chan_no);
1180                         sngisdn_process_restart_confirm(ftdmchan);
1181                 }
1182         } else { /* for all channels */
1183                 ftdm_iterator_t *chaniter = NULL;
1184                 ftdm_iterator_t *curr = NULL;
1185 
1186                 chaniter = ftdm_span_get_chan_iterator(signal_data->ftdm_span, NULL);
1187                 for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
1188                         sngisdn_process_restart_confirm((ftdm_channel_t*)ftdm_iterator_current(curr));
1189                 }
1190                 ftdm_iterator_free(chaniter);
1191         }
1192 
1193         ftdm_log(FTDM_LOG_DEBUG, "Processing RESTART CFM (suId:%u dChan:%d ces:%d type:%d)\n", suId, dChan, ces, evntType);
1194         ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
1195         return;
1196 }
1197 
1198 
1199 void sngisdn_process_rst_ind (sngisdn_event_data_t *sngisdn_event)
1200 {
1201         int16_t suId = sngisdn_event->suId;
1202         int16_t dChan = sngisdn_event->dChan;
1203         uint8_t ces = sngisdn_event->ces;
1204         uint8_t evntType = sngisdn_event->evntType;
1205 
1206         ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
1207 
1208         /* Function does not require any info from ssHlEvnt struct for now */
1209         /*Rst *rstEvnt = &sngisdn_event->event.rstEvnt;*/
1210                 
1211         ftdm_log(FTDM_LOG_DEBUG, "Processing RESTART CFM (suId:%u dChan:%d ces:%d %s)\n", suId, dChan, ces,
1212                                                                                                         (evntType == IN_LNK_DWN)?"LNK_DOWN":
1213                                                                                                         (evntType == IN_LNK_UP)?"LNK_UP":
1214                                                                                                         (evntType == IN_INDCHAN)?"b-channel":
1215                                                                                                         (evntType == IN_LNK_DWN_DM_RLS)?"NFAS service procedures":
1216                                                                                                         (evntType == IN_SWCHD_BU_DCHAN)?"NFAS switchover to backup":"Unknown");
1217         ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
1218         return;
1219 }
1220 
1221 static ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn)
1222 {
1223         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
1224         
1225         if (signal_data->ignore_cause_value == SNGISDN_OPT_TRUE) {
1226                 return FTDM_FAIL;
1227         }
1228 
1229         /* By default, we only evaluate cause value on 5ESS switches */
1230         if (signal_data->ignore_cause_value == SNGISDN_OPT_DEFAULT &&
1231                 signal_data->switchtype != SNGISDN_SWITCH_5ESS) {
1232 
1233                 return FTDM_FAIL;
1234         }
1235 
1236         /* ignore_cause_value = SNGISDN_OPT_FALSE or switchtype == 5ESS */
1237         switch(causeDgn->causeVal.val) {
1238                 case 17:        /* User Busy */
1239                 case 18:        /* No User responding */
1240                 case 19:        /* User alerting, no answer */
1241                 case 21:        /* Call rejected, the called party does not with to accept this call */
1242                 case 27:        /* Destination out of order */
1243                 case 31:        /* Normal, unspecified */
1244                 case 34:        /* Circuit/Channel congestion */
1245                 case 41:        /* Temporary failure */
1246                 case 42:        /* Switching equipment is experiencing a period of high traffic */
1247                 case 47:        /* Resource unavailable */
1248                 case 58:        /* Bearer Capability not available */
1249                 case 63:        /* Service or option not available */
1250                 case 65:        /* Bearer Cap not implemented, not supported */
1251                 case 79:        /* Service or option not implemented, unspecified */
1252                         return FTDM_SUCCESS;
1253         }
1254         return FTDM_FAIL;
1255 }

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