root/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c

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

DEFINITIONS

This source file includes following definitions.
  1. ftdm_sangoma_ss7_run
  2. ftdm_sangoma_ss7_process_stack_event
  3. ftdm_sangoma_ss7_process_state_change
  4. FIO_CHANNEL_OUTGOING_CALL_FUNCTION
  5. FIO_CHANNEL_REQUEST_FUNCTION
  6. FIO_CHANNEL_GET_SIG_STATUS_FUNCTION
  7. FIO_CHANNEL_SET_SIG_STATUS_FUNCTION
  8. ftdm_sangoma_ss7_start
  9. ftdm_sangoma_ss7_stop
  10. FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION
  11. FIO_SIG_LOAD_FUNCTION
  12. FIO_SIG_UNLOAD_FUNCTION
  13. FIO_API_FUNCTION
  14. FIO_IO_LOAD_FUNCTION

   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 static sng_isup_event_interface_t sng_event;
  43 static ftdm_io_interface_t g_ftdm_sngss7_interface;
  44 ftdm_sngss7_data_t g_ftdm_sngss7_data;
  45 /******************************************************************************/
  46 
  47 /* PROTOTYPES *****************************************************************/
  48 static void *ftdm_sangoma_ss7_run (ftdm_thread_t * me, void *obj);
  49 static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_event);
  50 
  51 static ftdm_status_t ftdm_sangoma_ss7_stop (ftdm_span_t * span);
  52 static ftdm_status_t ftdm_sangoma_ss7_start (ftdm_span_t * span);
  53 /******************************************************************************/
  54 
  55 /* STATE MAP ******************************************************************/
  56 ftdm_state_map_t sangoma_ss7_state_map = {
  57   {
  58    {
  59         ZSD_INBOUND,
  60         ZSM_UNACCEPTABLE,
  61         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_END},
  62         {FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_DOWN,
  63          FTDM_CHANNEL_STATE_IN_LOOP, FTDM_CHANNEL_STATE_COLLECT,
  64          FTDM_CHANNEL_STATE_RING, FTDM_CHANNEL_STATE_PROGRESS,
  65          FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP,
  66          FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_TERMINATING,
  67          FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END}
  68         },
  69    {
  70         ZSD_INBOUND,
  71         ZSM_UNACCEPTABLE,
  72         {FTDM_CHANNEL_STATE_RESTART, FTDM_END},
  73         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_TERMINATING,
  74          FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_HANGUP_COMPLETE,
  75          FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_IDLE, FTDM_END}
  76         },
  77         {
  78         ZSD_INBOUND,
  79         ZSM_UNACCEPTABLE,
  80         {FTDM_CHANNEL_STATE_IDLE, FTDM_END},
  81         {FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_COLLECT, FTDM_END}
  82         },
  83    {
  84         ZSD_INBOUND,
  85         ZSM_UNACCEPTABLE,
  86         {FTDM_CHANNEL_STATE_DOWN, FTDM_END},
  87         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
  88          FTDM_CHANNEL_STATE_COLLECT, FTDM_CHANNEL_STATE_IN_LOOP, FTDM_END}
  89         },
  90    {
  91         ZSD_INBOUND,
  92         ZSM_UNACCEPTABLE,
  93         {FTDM_CHANNEL_STATE_IN_LOOP, FTDM_END},
  94         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
  95          FTDM_CHANNEL_STATE_COLLECT, FTDM_CHANNEL_STATE_DOWN,
  96          FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END}
  97         },
  98    {
  99         ZSD_INBOUND,
 100         ZSM_UNACCEPTABLE,
 101         {FTDM_CHANNEL_STATE_COLLECT, FTDM_END},
 102         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 103          FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_RING, 
 104          FTDM_CHANNEL_STATE_IDLE, FTDM_END}
 105         },
 106    {
 107         ZSD_INBOUND,
 108         ZSM_UNACCEPTABLE,
 109         {FTDM_CHANNEL_STATE_RING, FTDM_END},
 110         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 111          FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
 112          FTDM_CHANNEL_STATE_PROGRESS, FTDM_END}
 113         },
 114    {
 115         ZSD_INBOUND,
 116         ZSM_UNACCEPTABLE,
 117         {FTDM_CHANNEL_STATE_PROGRESS, FTDM_END},
 118         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 119          FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
 120          FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_END}
 121         },
 122    {
 123         ZSD_INBOUND,
 124         ZSM_UNACCEPTABLE,
 125         {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_END},
 126         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 127          FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
 128          FTDM_CHANNEL_STATE_UP, FTDM_END}
 129         },
 130    {
 131         ZSD_INBOUND,
 132         ZSM_UNACCEPTABLE,
 133         {FTDM_CHANNEL_STATE_UP, FTDM_END},
 134         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 135          FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_END}
 136         },
 137    {
 138         ZSD_INBOUND,
 139         ZSM_UNACCEPTABLE,
 140         {FTDM_CHANNEL_STATE_CANCEL, FTDM_END},
 141         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 142          FTDM_CHANNEL_STATE_HANGUP, FTDM_END}
 143         },
 144    {
 145         ZSD_INBOUND,
 146         ZSM_UNACCEPTABLE,
 147         {FTDM_CHANNEL_STATE_TERMINATING, FTDM_END},
 148         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 149          FTDM_CHANNEL_STATE_HANGUP, FTDM_END}
 150         },
 151    {
 152         ZSD_INBOUND,
 153         ZSM_UNACCEPTABLE,
 154         {FTDM_CHANNEL_STATE_HANGUP, FTDM_END},
 155         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 156          FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END}
 157         },
 158    {
 159         ZSD_INBOUND,
 160         ZSM_UNACCEPTABLE,
 161         {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END},
 162         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 163          FTDM_CHANNEL_STATE_DOWN, FTDM_END}
 164         },
 165         /**************************************************************************/
 166    {
 167         ZSD_OUTBOUND,
 168         ZSM_UNACCEPTABLE,
 169         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_END},
 170         {FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_DOWN,
 171          FTDM_CHANNEL_STATE_IN_LOOP, FTDM_CHANNEL_STATE_DIALING,
 172          FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA,
 173          FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_CANCEL,
 174          FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
 175          FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END}
 176         },
 177    {
 178         ZSD_OUTBOUND,
 179         ZSM_UNACCEPTABLE,
 180         {FTDM_CHANNEL_STATE_RESTART, FTDM_END},
 181         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_TERMINATING,
 182          FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_HANGUP_COMPLETE,
 183          FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_IDLE, FTDM_END}
 184         },
 185         {
 186         ZSD_OUTBOUND,
 187         ZSM_UNACCEPTABLE,
 188         {FTDM_CHANNEL_STATE_IDLE, FTDM_END},
 189         {FTDM_CHANNEL_STATE_RESTART, FTDM_END}
 190         },
 191    {
 192         ZSD_OUTBOUND,
 193         ZSM_UNACCEPTABLE,
 194         {FTDM_CHANNEL_STATE_DOWN, FTDM_END},
 195         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 196          FTDM_CHANNEL_STATE_DIALING, FTDM_CHANNEL_STATE_IN_LOOP, FTDM_END}
 197         },
 198    {
 199         ZSD_OUTBOUND,
 200         ZSM_UNACCEPTABLE,
 201         {FTDM_CHANNEL_STATE_IN_LOOP, FTDM_END},
 202         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 203          FTDM_CHANNEL_STATE_DIALING, FTDM_CHANNEL_STATE_DOWN, FTDM_END}
 204         },
 205    {
 206         ZSD_OUTBOUND,
 207         ZSM_UNACCEPTABLE,
 208         {FTDM_CHANNEL_STATE_DIALING, FTDM_END},
 209         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 210          FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_TERMINATING,
 211          FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS,
 212          FTDM_CHANNEL_STATE_PROGRESS_MEDIA ,FTDM_CHANNEL_STATE_UP, FTDM_END}
 213         },
 214    {
 215         ZSD_OUTBOUND,
 216         ZSM_UNACCEPTABLE,
 217         {FTDM_CHANNEL_STATE_PROGRESS, FTDM_END},
 218         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 219          FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
 220          FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_END}
 221         },
 222    {
 223         ZSD_OUTBOUND,
 224         ZSM_UNACCEPTABLE,
 225         {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_END},
 226         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 227          FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
 228          FTDM_CHANNEL_STATE_UP, FTDM_END}
 229         },
 230    {
 231         ZSD_OUTBOUND,
 232         ZSM_UNACCEPTABLE,
 233         {FTDM_CHANNEL_STATE_UP, FTDM_END},
 234         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 235          FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_END}
 236         },
 237    {
 238         ZSD_OUTBOUND,
 239         ZSM_UNACCEPTABLE,
 240         {FTDM_CHANNEL_STATE_CANCEL, FTDM_END},
 241         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 242          FTDM_CHANNEL_STATE_HANGUP, FTDM_END}
 243         },
 244    {
 245         ZSD_OUTBOUND,
 246         ZSM_UNACCEPTABLE,
 247         {FTDM_CHANNEL_STATE_TERMINATING, FTDM_END},
 248         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 249          FTDM_CHANNEL_STATE_HANGUP, FTDM_END}
 250         },
 251    {
 252         ZSD_OUTBOUND,
 253         ZSM_UNACCEPTABLE,
 254         {FTDM_CHANNEL_STATE_HANGUP, FTDM_END},
 255         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 256          FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END}
 257         },
 258    {
 259         ZSD_OUTBOUND,
 260         ZSM_UNACCEPTABLE,
 261         {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END},
 262         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 263          FTDM_CHANNEL_STATE_DOWN, FTDM_END}
 264         },
 265    }
 266 };
 267 
 268 /******************************************************************************/
 269 
 270 /* MONITIOR THREADS ***********************************************************/
 271 static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
 272 {
 273         ftdm_interrupt_t        *ftdm_sangoma_ss7_int[2];
 274         ftdm_span_t             *ftdmspan = (ftdm_span_t *) obj;
 275         ftdm_channel_t          *ftdmchan = NULL;
 276         sngss7_event_data_t     *sngss7_event = NULL;
 277         sngss7_span_data_t      *sngss7_span = (sngss7_span_data_t *)ftdmspan->signal_data;
 278 
 279         ftdm_log (FTDM_LOG_INFO, "ftmod_sangoma_ss7 monitor thread for span=%u started.\n", ftdmspan->span_id);
 280 
 281         /* set IN_THREAD flag so that we know this thread is running */
 282         ftdm_set_flag (ftdmspan, FTDM_SPAN_IN_THREAD);
 283 
 284         /* get an interrupt queue for this span for channel state changes */
 285         if (ftdm_queue_get_interrupt (ftdmspan->pendingchans, &ftdm_sangoma_ss7_int[0]) != FTDM_SUCCESS) {
 286                 SS7_CRITICAL ("Failed to get a ftdm_interrupt for span = %d for channel state changes!\n", ftdmspan->span_id);
 287                 goto ftdm_sangoma_ss7_run_exit;
 288         }
 289 
 290         /* get an interrupt queue for this span for Trillium events */
 291         if (ftdm_queue_get_interrupt (sngss7_span->event_queue, &ftdm_sangoma_ss7_int[1]) != FTDM_SUCCESS) {
 292                 SS7_CRITICAL ("Failed to get a ftdm_interrupt for span = %d for Trillium event queue!\n", ftdmspan->span_id);
 293                 goto ftdm_sangoma_ss7_run_exit;
 294         }
 295 
 296         while (ftdm_running () && !(ftdm_test_flag (ftdmspan, FTDM_SPAN_STOP_THREAD))) {
 297 
 298                 /* check the channel state queue for an event*/ 
 299                 switch ((ftdm_interrupt_multiple_wait(ftdm_sangoma_ss7_int, 2, 100))) {
 300                 /**********************************************************************/
 301                 case FTDM_SUCCESS:      /* process all pending state changes */
 302 
 303                         /* clean out all pending channel state changes */
 304                         while ((ftdmchan = ftdm_queue_dequeue (ftdmspan->pendingchans))) {
 305                                 
 306                                 /*first lock the channel */
 307                                 ftdm_mutex_lock(ftdmchan->mutex);
 308 
 309                                 /* process state changes for this channel until they are all done */
 310                                 ftdm_channel_advance_states(ftdmchan);
 311  
 312                                 /* unlock the channel */
 313                                 ftdm_mutex_unlock (ftdmchan->mutex);                            
 314                         }/* while ((ftdmchan = ftdm_queue_dequeue(ftdmspan->pendingchans)))  */
 315 
 316                         /* clean out all pending stack events */
 317                         while ((sngss7_event = ftdm_queue_dequeue(sngss7_span->event_queue))) {
 318                                 ftdm_sangoma_ss7_process_stack_event(sngss7_event);
 319                                 ftdm_safe_free(sngss7_event);
 320                         }/* while ((sngss7_event = ftdm_queue_dequeue(ftdmspan->signal_data->event_queue))) */
 321 
 322                         /* signal the core that sig events are queued for processing */
 323                         ftdm_span_trigger_signals(ftdmspan);
 324 
 325                         break;
 326                 /**********************************************************************/
 327                 case FTDM_TIMEOUT:
 328                         SS7_DEVEL_DEBUG ("ftdm_interrupt_wait timed-out on span = %d\n",ftdmspan->span_id);
 329 
 330                         break;
 331                 /**********************************************************************/
 332                 case FTDM_FAIL:
 333                         SS7_ERROR ("ftdm_interrupt_wait returned error!\non span = %d\n", ftdmspan->span_id);
 334 
 335                         break;
 336                 /**********************************************************************/
 337                 default:
 338                         SS7_ERROR("ftdm_interrupt_wait returned with unknown code on span = %d\n",ftdmspan->span_id);
 339 
 340                         break;
 341                 /**********************************************************************/
 342                 } /* switch ((ftdm_interrupt_wait(ftdm_sangoma_ss7_int, 100))) */
 343 
 344                 /* check if there is a GRA to proccess on the span */
 345                 if (sngss7_span->rx_gra.range > 0) {
 346                         check_if_rx_gra_started(ftdmspan);
 347                 } /* if (sngss7->span->rx_gra.range > 0) */
 348 
 349                 /* check if there is a GRS being processed on the span */
 350                 if (sngss7_span->rx_grs.range > 0) {
 351                         /* check if the rx_grs has started */
 352                         check_if_rx_grs_started(ftdmspan);
 353 
 354                         /* check if the rx_grs has cleared */
 355                         check_if_rx_grs_processed(ftdmspan);
 356                 } /* if (sngss7_span->rx_grs.range > 0) */
 357 
 358                 /* check if there is a UCIC to be processed on the span */
 359                 if (sngss7_span->ucic.range > 0) {
 360                         /* process the span wide UCIC */
 361                         process_span_ucic(ftdmspan);
 362                 } /* if (sngss7_span->ucic.range > 0) */
 363 
 364                 /* check each channel on the span to see if there is an un-procressed SUS/RES flag */
 365                 check_for_res_sus_flag(ftdmspan);
 366         } /* master while loop */
 367 
 368         /* clear the IN_THREAD flag so that we know the thread is done */
 369         ftdm_clear_flag (ftdmspan, FTDM_SPAN_IN_THREAD);
 370 
 371         ftdm_log (FTDM_LOG_INFO,"ftmod_sangoma_ss7 monitor thread for span=%u stopping.\n",ftdmspan->span_id);
 372 
 373         return NULL;
 374 
 375 ftdm_sangoma_ss7_run_exit:
 376 
 377         /* clear the IN_THREAD flag so that we know the thread is done */
 378         ftdm_clear_flag (ftdmspan, FTDM_SPAN_IN_THREAD);
 379 
 380         ftdm_log (FTDM_LOG_INFO,"ftmod_sangoma_ss7 monitor thread for span=%u stopping due to error.\n",ftdmspan->span_id);
 381 
 382         ftdm_sangoma_ss7_stop (ftdmspan);
 383 
 384         return NULL;
 385 }
 386 
 387 /******************************************************************************/
 388 static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_event)
 389 {
 390         sngss7_chan_data_t  *sngss7_info ;
 391         ftdm_channel_t    *ftdmchan;
 392 
 393         /* get the ftdmchan and ss7_chan_data from the circuit */
 394         if (extract_chan_data(sngss7_event->circuit, &sngss7_info, &ftdmchan)) {
 395                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", sngss7_event->circuit);
 396                 return;
 397         }
 398 
 399         /* now that we have the right channel...put a lock on it so no-one else can use it */
 400         ftdm_mutex_lock(ftdmchan->mutex);
 401 
 402         /* while there's a state change present on this channel process it */
 403         ftdm_channel_advance_states(ftdmchan);
 404 
 405         /* figure out the type of event and send it to the right handler */
 406         switch (sngss7_event->event_id) {
 407         /**************************************************************************/
 408         case (SNGSS7_CON_IND_EVENT):
 409                 handle_con_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit,  &sngss7_event->event.siConEvnt);
 410                 break;
 411         /**************************************************************************/
 412         case (SNGSS7_CON_CFM_EVENT):
 413                 handle_con_cfm(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit,  &sngss7_event->event.siConEvnt);
 414                 break;
 415         /**************************************************************************/
 416         case (SNGSS7_CON_STA_EVENT):
 417                 handle_con_sta(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit,  &sngss7_event->event.siCnStEvnt, sngss7_event->evntType);
 418                 break;
 419         /**************************************************************************/
 420         case (SNGSS7_REL_IND_EVENT):
 421                 handle_rel_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit,  &sngss7_event->event.siRelEvnt);
 422                 break;
 423         /**************************************************************************/
 424         case (SNGSS7_REL_CFM_EVENT):
 425                 handle_rel_cfm(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit,  &sngss7_event->event.siRelEvnt);
 426                 break;
 427         /**************************************************************************/
 428         case (SNGSS7_DAT_IND_EVENT):
 429                 handle_dat_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit,  &sngss7_event->event.siInfoEvnt);
 430                 break;
 431         /**************************************************************************/
 432         case (SNGSS7_FAC_IND_EVENT):
 433                 handle_fac_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->evntType,  &sngss7_event->event.siFacEvnt);
 434                 break;
 435         /**************************************************************************/
 436         case (SNGSS7_FAC_CFM_EVENT):
 437                 handle_fac_cfm(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->evntType,  &sngss7_event->event.siFacEvnt);
 438                 break;
 439         /**************************************************************************/
 440         case (SNGSS7_UMSG_IND_EVENT):
 441                 handle_umsg_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit);
 442                 break;
 443         /**************************************************************************/
 444         case (SNGSS7_STA_IND_EVENT):
 445                 handle_sta_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->globalFlg, sngss7_event->evntType,  &sngss7_event->event.siStaEvnt);
 446                 break;
 447         /**************************************************************************/
 448         case (SNGSS7_SUSP_IND_EVENT):
 449                 handle_susp_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit,  &sngss7_event->event.siSuspEvnt);
 450                 break;
 451         /**************************************************************************/
 452         case (SNGSS7_RESM_IND_EVENT):
 453                 handle_resm_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit,  &sngss7_event->event.siResmEvnt);
 454                 break;
 455         /**************************************************************************/
 456         case (SNGSS7_SSP_STA_CFM_EVENT):
 457                 break;
 458         /**************************************************************************/
 459         default:
 460                 SS7_ERROR("Unknown Event Id!\n");
 461                 break;
 462         /**************************************************************************/
 463         } /* switch (sngss7_event->event_id) */
 464 
 465         /* while there's a state change present on this channel process it */
 466         ftdm_channel_advance_states(ftdmchan);
 467 
 468         /* unlock the channel */
 469         ftdm_mutex_unlock(ftdmchan->mutex);
 470 
 471         return;
 472 }
 473 
 474 /******************************************************************************/
 475 ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
 476 {
 477         sngss7_chan_data_t      *sngss7_info = ftdmchan->call_data;
 478         sng_isup_inf_t          *isup_intf = NULL; 
 479         int                             i = 0;
 480         ftdm_sigmsg_t           sigev;
 481 
 482         memset (&sigev, 0, sizeof (sigev));
 483 
 484         sigev.chan_id = ftdmchan->chan_id;
 485         sigev.span_id = ftdmchan->span_id;
 486         sigev.channel = ftdmchan;
 487 
 488         SS7_DEBUG_CHAN(ftdmchan, "ftmod_sangoma_ss7 processing state %s\n", ftdm_channel_state2str (ftdmchan->state));
 489 
 490         /* clear the state change flag...since we might be setting a new state */
 491         ftdm_channel_complete_state(ftdmchan);
 492         
 493         /*check what state we are supposed to be in */
 494         switch (ftdmchan->state) {
 495         /**************************************************************************/
 496         case FTDM_CHANNEL_STATE_COLLECT:        /* IAM received but wating on digits */
 497 
 498                 isup_intf = &g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId];
 499 
 500                 if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) {
 501                         SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n");
 502                         break;
 503                 }
 504 
 505                 while (ftdmchan->caller_data.dnis.digits[i] != '\0'){
 506                         i++;
 507                 }
 508 
 509                 /* check if the end of pulsing (ST) character has arrived or the right number of digits */
 510                 if (ftdmchan->caller_data.dnis.digits[i-1] == 'F') {
 511                         SS7_DEBUG_CHAN(ftdmchan, "Received the end of pulsing character %s\n", "");
 512 
 513                         /* remove the ST */
 514                         ftdmchan->caller_data.dnis.digits[i-1] = '\0';
 515                         
 516                         /*now go to the RING state */
 517                         ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RING);
 518                         
 519                 } else if (i >= isup_intf->min_digits) {
 520                         SS7_DEBUG_CHAN(ftdmchan, "Received %d digits (min digits = %d)\n", i, isup_intf->min_digits);
 521 
 522                         /*now go to the RING state */
 523                         ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RING);
 524                         
 525                 } else {
 526                         /* if we are coming from idle state then we have already been here once before */
 527                         if (ftdmchan->last_state != FTDM_CHANNEL_STATE_IDLE) {
 528                                 SS7_INFO_CHAN(ftdmchan,"Received %d out of %d so far: %s...starting T35\n",
 529                                                                                 i,
 530                                                                                 isup_intf->min_digits,
 531                                                                                 ftdmchan->caller_data.dnis.digits);
 532                 
 533                                 /* start ISUP t35 */
 534                                 if (ftdm_sched_timer (sngss7_info->t35.sched,
 535                                                                                 "t35",
 536                                                                                 sngss7_info->t35.beat,
 537                                                                                 sngss7_info->t35.callback,
 538                                                                                 &sngss7_info->t35,
 539                                                                                 &sngss7_info->t35.hb_timer_id)) {
 540                 
 541                                         SS7_ERROR ("Unable to schedule timer, hanging up call!\n");
 542                 
 543                                         ftdmchan->caller_data.hangup_cause = 41;
 544                 
 545                                         /* set the flag to indicate this hangup is started from the local side */
 546                                         sngss7_set_flag (sngss7_info, FLAG_LOCAL_REL);
 547                 
 548                                         /* end the call */
 549                                         ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
 550                                 } /* if (ftdm_sched_timer(sngss7_info->t35.sched, */
 551                         } /* if (ftdmchan->last_state != FTDM_CHANNEL_STATE_IDLE) */
 552                 } /* checking ST/#digits */
 553 
 554           break;
 555 
 556         /**************************************************************************/
 557         case FTDM_CHANNEL_STATE_RING:   /*incoming call request */
 558 
 559                 if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) {
 560                         SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n");
 561                         break;
 562                 }
 563 
 564                 /* kill t35 if active */
 565                 if (sngss7_info->t35.hb_timer_id) {
 566                         ftdm_sched_cancel_timer (sngss7_info->t35.sched, sngss7_info->t35.hb_timer_id);
 567                 }
 568 
 569                 SS7_DEBUG_CHAN(ftdmchan, "Sending incoming call from %s to %s to FTDM core\n",
 570                                         ftdmchan->caller_data.ani.digits,
 571                                         ftdmchan->caller_data.dnis.digits);
 572 
 573 
 574                 /* we have enough information to inform FTDM of the call */
 575                 sigev.event_id = FTDM_SIGEVENT_START;
 576                 ftdm_span_send_signal (ftdmchan->span, &sigev);
 577 
 578                 break;
 579         /**************************************************************************/
 580         case FTDM_CHANNEL_STATE_DIALING:        /*outgoing call request */
 581 
 582                 if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) {
 583                         SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n");
 584                         break;
 585                 }
 586 
 587                 SS7_DEBUG_CHAN(ftdmchan, "Sending outgoing call from \"%s\" to \"%s\" to LibSngSS7\n",
 588                                            ftdmchan->caller_data.ani.digits,
 589                                            ftdmchan->caller_data.dnis.digits);
 590 
 591                 /*call sangoma_ss7_dial to make outgoing call */
 592                 ft_to_sngss7_iam(ftdmchan);
 593 
 594                 break;
 595         /**************************************************************************/
 596         case FTDM_CHANNEL_STATE_PROGRESS:
 597 
 598                 if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) {
 599                         SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n");
 600                         break;
 601                 }
 602 
 603                 /*check if the channel is inbound or outbound */
 604                 if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
 605                         /*OUTBOUND...so we were told by the line of this so noifiy the user */
 606                         sigev.event_id = FTDM_SIGEVENT_PROGRESS;
 607                         ftdm_span_send_signal (ftdmchan->span, &sigev);
 608 
 609                         /* move to progress media  */
 610                         ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
 611                 } else {
 612                         /* inbound call so we need to send out ACM */
 613                         ft_to_sngss7_acm(ftdmchan);
 614                 }
 615 
 616                 break;
 617         /**************************************************************************/
 618         case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
 619 
 620                 if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) {
 621                         SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n");
 622                         break;
 623                 }
 624 
 625                 if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
 626                         /* inform the user there is media avai */
 627                         sigev.event_id = FTDM_SIGEVENT_PROGRESS_MEDIA;
 628                         ftdm_span_send_signal (ftdmchan->span, &sigev);
 629                 }
 630                         
 631 
 632                 /* nothing to do at this time */
 633                 break;
 634         /**************************************************************************/
 635         case FTDM_CHANNEL_STATE_UP:     /*call is accpeted...both incoming and outgoing */
 636 
 637                 if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) {
 638                         SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n");
 639                         break;
 640                 }
 641 
 642                 /*check if the channel is inbound or outbound */
 643                 if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
 644                         /*OUTBOUND...so we were told by the line that the other side answered */
 645                         sigev.event_id = FTDM_SIGEVENT_UP;
 646                         ftdm_span_send_signal(ftdmchan->span, &sigev);
 647                 } else {
 648                         /*INBOUND...so FS told us it was going to answer...tell the stack */
 649                         ft_to_sngss7_anm(ftdmchan);
 650                 }
 651 
 652                 break;
 653         /**************************************************************************/
 654         case FTDM_CHANNEL_STATE_CANCEL:
 655 
 656                 if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) {
 657                         SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n");
 658                         break;
 659                 }
 660 
 661                 SS7_ERROR_CHAN(ftdmchan,"Hanging up call before informing user%s\n", " ");
 662 
 663                 /*now go to the HANGUP complete state */
 664                 ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
 665 
 666                 break;
 667         /**************************************************************************/
 668         case FTDM_CHANNEL_STATE_TERMINATING:    /*call is hung up remotely */
 669 
 670                 if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) {
 671                         SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n");
 672                         break;
 673                 }
 674 
 675                 /* set the flag to indicate this hangup is started from the remote side */
 676                 sngss7_set_flag (sngss7_info, FLAG_REMOTE_REL);
 677 
 678                 /*this state is set when the line is hanging up */
 679                 sigev.event_id = FTDM_SIGEVENT_STOP;
 680                 ftdm_span_send_signal (ftdmchan->span, &sigev);
 681 
 682                 break;
 683         /**************************************************************************/
 684         case FTDM_CHANNEL_STATE_HANGUP: /*call is hung up locally */
 685 
 686                 if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) {
 687                         SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n");
 688                         break;
 689                 }
 690 
 691                 /* check for remote hangup flag */
 692                 if (sngss7_test_flag (sngss7_info, FLAG_REMOTE_REL)) {
 693                         /* remote release ...do nothing here */
 694                         SS7_DEBUG_CHAN(ftdmchan,"Hanging up remotely requested call!%s\n", "");
 695                 } else if (sngss7_test_flag (sngss7_info, FLAG_GLARE)) {
 696                         /* release due to glare */
 697                         SS7_DEBUG_CHAN(ftdmchan,"Hanging up requested call do to glare%s\n", "");
 698                 } else  {
 699                         /* set the flag to indicate this hangup is started from the local side */
 700                         sngss7_set_flag (sngss7_info, FLAG_LOCAL_REL);
 701 
 702                         /*this state is set when FS is hanging up...so tell the stack */
 703                         ft_to_sngss7_rel (ftdmchan);
 704 
 705                         SS7_DEBUG_CHAN(ftdmchan,"Hanging up locally requested call!%s\n", "");
 706                 }
 707 
 708                 /*now go to the HANGUP complete state */
 709                 ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
 710 
 711                 break;
 712 
 713         /**************************************************************************/
 714         case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
 715 
 716                 if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) {
 717                         SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n");
 718                         break;
 719                 }
 720 
 721                 if (sngss7_test_flag (sngss7_info, FLAG_REMOTE_REL)) {
 722                         /* check if this hangup is from a tx RSC */
 723                         if (sngss7_test_flag (sngss7_info, FLAG_RESET_TX)) {
 724                                 /* go to RESTART State until RSCa is received */
 725                                 ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RESTART);
 726                         } else {
 727                                 /* if the hangup is from a rx RSC, rx GRS, or glare don't sent RLC */
 728                                 if (!(sngss7_test_flag(sngss7_info, FLAG_RESET_RX)) &&
 729                                         !(sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX)) &&
 730                                         !(sngss7_test_flag(sngss7_info, FLAG_GLARE))) {
 731 
 732                                         /* send out the release complete */
 733                                         ft_to_sngss7_rlc (ftdmchan);
 734                                 }
 735 
 736                                 /*now go to the DOWN state */
 737                                 ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_DOWN);
 738                         }
 739 
 740                         SS7_DEBUG_CHAN(ftdmchan,"Completing remotely requested hangup!%s\n", "");
 741                 } else if (sngss7_test_flag (sngss7_info, FLAG_LOCAL_REL)) {
 742 
 743                         /* if this hang up is do to a rx RESET we need to sit here till the RSP arrives */
 744                         if (sngss7_test_flag (sngss7_info, FLAG_RESET_TX_RSP)) {
 745                                 /* go to the down state as we have already received RSC-RLC */
 746                                 ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_DOWN);
 747                         }
 748 
 749                         /* if it's a local release the user sends us to down */
 750                         SS7_DEBUG_CHAN(ftdmchan,"Completing locally requested hangup!%s\n", "");
 751                 } else if (sngss7_test_flag (sngss7_info, FLAG_GLARE)) {
 752                         SS7_DEBUG_CHAN(ftdmchan,"Completing requested hangup due to glare!%s\n", "");
 753 
 754                         ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_DOWN);
 755                 } else {
 756                         SS7_DEBUG_CHAN(ftdmchan,"Completing requested hangup for unknown reason!%s\n", "");
 757                 }
 758 
 759                 break;
 760 
 761         /**************************************************************************/
 762         case FTDM_CHANNEL_STATE_DOWN:   /*the call is finished and removed */
 763 
 764                 if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) {
 765                         SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n");
 766                         break;
 767                 }
 768 
 769                 /* check if there is a reset response that needs to be sent */
 770                 if (sngss7_test_flag (sngss7_info, FLAG_RESET_RX)) {
 771                         /* send a RSC-RLC */
 772                         ft_to_sngss7_rsca (ftdmchan);
 773 
 774                         /* clear the reset flag  */
 775                         clear_rx_rsc_flags(sngss7_info);
 776                 } /* if (sngss7_test_flag (sngss7_info, FLAG_RESET_RX)) */
 777 
 778                 /* check if there was a GRS that needs a GRA */
 779                 if ((sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX)) &&
 780                         (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) &&
 781                         (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT))) {
 782 
 783                         /* check if this is the base circuit and send out the GRA
 784                          * we insure that this is the last circuit to have the state change queued
 785                          */
 786                         sngss7_span_data_t *span = ftdmchan->span->signal_data;
 787                         if (span->rx_grs.circuit == sngss7_info->circuit->id) {
 788                                 /* send out the GRA */
 789                                 ft_to_sngss7_gra(ftdmchan);
 790 
 791                                 /* clean out the spans GRS structure */
 792                                 clear_rx_grs_data(sngss7_info);
 793                         }
 794 
 795                         /* clear the grp reset flag */
 796                         clear_rx_grs_flags(sngss7_info);
 797                 }/*  if ( sngss7_test_flag ( sngss7_info, FLAG_GRP_RESET_RX ) ) */
 798 
 799                 /* check if we got the reset response */
 800                 if (sngss7_test_flag(sngss7_info, FLAG_RESET_TX_RSP)) {
 801                         /* clear the reset flag  */
 802                         clear_tx_rsc_flags(sngss7_info);
 803                 } /* if (sngss7_test_flag(sngss7_info, FLAG_RESET_TX_RSP)) */
 804 
 805                 if (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) {
 806                         /* clear the reset flag  */
 807                         clear_tx_grs_flags(sngss7_info);
 808                         
 809                         /* clean out the spans GRA structure */
 810                         clear_rx_gra_data(sngss7_info);
 811                 } /* if (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) */
 812 
 813                 /* check if we came from reset (aka we just processed a reset) */
 814                 if ((ftdmchan->last_state == FTDM_CHANNEL_STATE_RESTART) || 
 815                         (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED)) {
 816 
 817                         /* check if reset flags are up indicating there is more processing to do yet */
 818                         if (!(sngss7_test_flag (sngss7_info, FLAG_RESET_TX)) &&
 819                                 !(sngss7_test_flag (sngss7_info, FLAG_RESET_RX)) &&
 820                                 !(sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_TX)) &&
 821                                 !(sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_RX))) {
 822 
 823                                 /* now check if there is an active block */
 824                                 if (!(sngss7_test_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX)) &&
 825                                         !(sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) &&
 826                                         !(sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) &&
 827                                         !(sngss7_test_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX)) &&
 828                                         !(sngss7_test_flag(sngss7_info, FLAG_GRP_HW_BLOCK_TX)) &&
 829                                         !(sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX)) &&
 830                                         !(sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX))) {
 831                                 
 832                                         /* check if the sig status is down, and bring it up if it isn't */
 833                                         if (!ftdm_test_flag (ftdmchan, FTDM_CHANNEL_SIG_UP)) {
 834                                                 SS7_DEBUG_CHAN(ftdmchan,"All reset flags cleared %s\n", "");
 835                                                 /* all flags are down so we can bring up the sig status */
 836                                                 sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
 837                                                 sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_UP;
 838                                                 ftdm_span_send_signal (ftdmchan->span, &sigev);
 839                                         } /* if (!ftdm_test_flag (ftdmchan, FTDM_CHANNEL_SIG_UP)) */
 840                                 } /* if !blocked */
 841                         } else {
 842                                 SS7_DEBUG_CHAN(ftdmchan,"Reset flags present (0x%X)\n", sngss7_info->flags);
 843                         
 844                                 /* there is still another reset pending so go back to reset*/
 845                                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
 846                         }
 847                 } /* if ((ftdmchan->last_state == FTDM_CHANNEL_STATE_RESTART) */
 848 
 849                 /* check if t35 is active */
 850                 if (sngss7_info->t35.hb_timer_id) {
 851                         ftdm_sched_cancel_timer (sngss7_info->t35.sched, sngss7_info->t35.hb_timer_id);
 852                 }
 853 
 854                 /* clear all of the call specific data store in the channel structure */
 855                 sngss7_info->suInstId = 0;
 856                 sngss7_info->spInstId = 0;
 857                 sngss7_info->globalFlg = 0;
 858                 sngss7_info->spId = 0;
 859 
 860                 /* clear any call related flags */
 861                 sngss7_clear_flag (sngss7_info, FLAG_REMOTE_REL);
 862                 sngss7_clear_flag (sngss7_info, FLAG_LOCAL_REL);
 863 
 864 
 865                 if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_OPEN)) {
 866                         ftdm_channel_t *close_chan = ftdmchan;
 867                         /* close the channel */
 868                         ftdm_channel_close (&close_chan);
 869                 } /* if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_OPEN)) */
 870 
 871                 /* check if there is a glared call that needs to be processed */
 872                 if (sngss7_test_flag(sngss7_info, FLAG_GLARE)) {
 873                         
 874                         /* clear the glare flag */
 875                         sngss7_clear_flag (sngss7_info, FLAG_GLARE);
 876 
 877                         /* check if we have an IAM stored...if we don't have one just exit */
 878                         if (sngss7_info->glare.circuit != 0) {
 879                                 /* send the saved call back in to us */
 880                                 handle_con_ind (0, 
 881                                                                 sngss7_info->glare.spInstId, 
 882                                                                 sngss7_info->glare.circuit, 
 883                                                                 &sngss7_info->glare.iam);
 884 
 885                                 /* clear the glare info */
 886                                 memset(&sngss7_info->glare, 0x0, sizeof(sngss7_glare_data_t));
 887                         } /* if (sngss7_info->glare.circuit != 0) */
 888                 } /* if (sngss7_test_flag(sngss7_info, FLAG_GLARE)) */
 889 
 890                 break;
 891         /**************************************************************************/
 892         case FTDM_CHANNEL_STATE_RESTART:        /* CICs needs a Reset */
 893 
 894                 if (sngss7_test_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK)) {
 895                         if ((sngss7_test_flag(sngss7_info, FLAG_RESET_RX)) ||
 896                                 (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX))) {
 897 
 898                                 SS7_DEBUG_CHAN(ftdmchan,"Incoming Reset request on CIC in UCIC block, removing UCIC block%s\n", "");
 899 
 900                                 /* set the unblk flag */
 901                                 sngss7_set_flag(sngss7_info, FLAG_CKT_UCIC_UNBLK);
 902 
 903                                 /* clear the block flag */
 904                                 sngss7_clear_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK);
 905 
 906                                 /* process the flag */
 907                                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
 908 
 909                                 /* break out of the processing for now */
 910                                 break;
 911                         }
 912                 }
 913 
 914                 /* if we're not coming from HANGUP_COMPLETE we need to check for resets
 915                  * we can also check if we are in a PAUSED state (no point in sending message
 916                  */
 917                 if ((ftdmchan->last_state != FTDM_CHANNEL_STATE_HANGUP_COMPLETE) &&
 918                         (!sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED))) {
 919 
 920                         /* check if this is an outgoing RSC */
 921                         if ((sngss7_test_flag(sngss7_info, FLAG_RESET_TX)) &&
 922                                 !(sngss7_test_flag(sngss7_info, FLAG_RESET_SENT))) {
 923 
 924                                 /* send a reset request */
 925                                 ft_to_sngss7_rsc (ftdmchan);
 926                                 sngss7_set_flag(sngss7_info, FLAG_RESET_SENT);
 927 
 928                         } /* if (sngss7_test_flag(sngss7_info, FLAG_RESET_TX)) */
 929         
 930                         /* check if this is the first channel of a GRS (this flag is thrown when requesting reset) */
 931                         if ( (sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_TX)) &&
 932                                 !(sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_SENT)) &&
 933                                 (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_BASE))) {
 934 
 935                                         /* send out the grs */
 936                                         ft_to_sngss7_grs (ftdmchan);
 937                                         sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_SENT);
 938 
 939                         }/* if ( sngss7_test_flag ( sngss7_info, FLAG_GRP_RESET_TX ) ) */
 940                 } /* if ( last_state != HANGUP && !PAUSED */
 941         
 942                 /* if the sig_status is up...bring it down */
 943                 if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_SIG_UP)) {
 944                         sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
 945                         sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_DOWN;
 946                         ftdm_span_send_signal (ftdmchan->span, &sigev);
 947                 }
 948 
 949                 if (sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_RX)) {
 950                         /* set the grp reset done flag so we know we have finished this reset */
 951                         sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX_DN);
 952                 } /* if (sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_RX)) */
 953 
 954 
 955                 if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_INUSE)) {
 956                         /* bring the call down first...then process the rest of the reset */
 957                         switch (ftdmchan->last_state){
 958                         /******************************************************************/
 959                         case (FTDM_CHANNEL_STATE_TERMINATING):
 960                                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);     
 961                                 break;
 962                         /******************************************************************/
 963                         case (FTDM_CHANNEL_STATE_HANGUP):
 964                         case (FTDM_CHANNEL_STATE_HANGUP_COMPLETE):
 965                                 /* go back to the last state after taking care of the rest of the restart state */
 966                                 ftdm_set_state_locked (ftdmchan, ftdmchan->last_state);
 967                         break;
 968                         /******************************************************************/
 969                         case (FTDM_CHANNEL_STATE_IN_LOOP):
 970                                 /* we screwed up in a COT/CCR, remove the loop */
 971                                 ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL);
 972 
 973                                 /* go to down */
 974                                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
 975                                 break;
 976                         /******************************************************************/
 977                         default:
 978                                 /* KONRAD: find out what the cause code should be */
 979                                 ftdmchan->caller_data.hangup_cause = 41;
 980 
 981                                 /* change the state to terminatting, it will throw us back here
 982                                  * once the call is done
 983                                  */
 984                                 ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
 985                         break;
 986                         /******************************************************************/
 987                         } /* switch (ftdmchan->last_state) */
 988                 } else {
 989                         /* check if this an incoming RSC or we have a response already */
 990                         if (sngss7_test_flag (sngss7_info, FLAG_RESET_RX) ||
 991                                 sngss7_test_flag (sngss7_info, FLAG_RESET_TX_RSP) ||
 992                                 sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_TX_RSP) ||
 993                                 sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_RX_CMPLT)) {
 994         
 995                                 SS7_DEBUG_CHAN(ftdmchan, "Reset processed moving to DOWN (0x%X)\n", sngss7_info->flags);
 996         
 997                                 /* go to a down state to clear the channel and send the response */
 998                                 ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_DOWN);
 999                         } else {
1000                                 SS7_DEBUG_CHAN(ftdmchan, "Waiting on Reset Rsp/Grp Reset to move to DOWN (0x%X)\n", sngss7_info->flags);
1001                         }
1002                 }
1003 
1004                 break;
1005         /**************************************************************************/
1006         case FTDM_CHANNEL_STATE_SUSPENDED:      /* circuit has been blocked */
1007 
1008                   SS7_DEBUG_CHAN(ftdmchan,"Current flags: 0x%X\n", sngss7_info->flags);
1009 
1010                 /**********************************************************************/
1011                 if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) {
1012                         SS7_DEBUG_CHAN(ftdmchan, "Processing RESUME%s\n", "");
1013 
1014                         /* clear the RESUME flag */
1015                         sngss7_clear_flag(sngss7_info, FLAG_INFID_RESUME);
1016 
1017                         /* if there are any resets present */
1018                         if ((sngss7_test_flag (sngss7_info, FLAG_RESET_TX)) ||
1019                                 (sngss7_test_flag (sngss7_info, FLAG_RESET_RX)) ||
1020                                 (sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_TX)) ||
1021                                 (sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_RX))) {
1022 
1023                                 /* go back to the reset state */
1024                                 goto suspend_goto_restart;
1025                         } else {
1026 
1027                                 /* bring the sig status back up */
1028                                 sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
1029                                 sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_UP;
1030                                 ftdm_span_send_signal(ftdmchan->span, &sigev);
1031                         }
1032 
1033                         /* go back to the last state */
1034                         goto suspend_goto_last;
1035                 } /* if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) */
1036 
1037                 if (sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) {
1038                         SS7_DEBUG_CHAN(ftdmchan, "Processing PAUSE%s\n", "");
1039 
1040                         /* bring the sig status down */
1041                         sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
1042                         sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_DOWN;
1043                         ftdm_span_send_signal(ftdmchan->span, &sigev);
1044 
1045                         /* go back to the last state */
1046                         goto suspend_goto_last;
1047                 } /* if (sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) { */
1048                 /**********************************************************************/
1049                 if (sngss7_test_flag (sngss7_info, FLAG_CKT_MN_BLOCK_RX)) {
1050                         SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_BLOCK_RX flag %s\n", "");
1051 
1052                         /* bring the sig status down */
1053                         sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
1054                         sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_DOWN;
1055                         ftdm_span_send_signal(ftdmchan->span, &sigev); 
1056 
1057                         /* send a BLA */
1058                         ft_to_sngss7_bla (ftdmchan);
1059 
1060                         /* check the last state and return to it to allow the call to finish */
1061                         goto suspend_goto_last;
1062                 }
1063 
1064                 if (sngss7_test_flag (sngss7_info, FLAG_CKT_MN_UNBLK_RX)){
1065                         SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_UNBLK_RX flag %s\n", "");
1066 
1067                         /* clear the unblock flag */
1068                         sngss7_clear_flag (sngss7_info, FLAG_CKT_MN_UNBLK_RX);
1069 
1070                         /* bring the sig status up */
1071                         sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
1072                         sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_UP;
1073                         ftdm_span_send_signal(ftdmchan->span, &sigev); 
1074 
1075                         /* send a uba */
1076                         ft_to_sngss7_uba (ftdmchan);
1077 
1078                         /* check the last state and return to it to allow the call to finish */
1079                         goto suspend_goto_last;
1080                 }
1081 
1082                 /**********************************************************************/
1083                 if (sngss7_test_flag (sngss7_info, FLAG_CKT_MN_BLOCK_TX)) {
1084                         SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_BLOCK_TX flag %s\n", "");
1085 
1086                         /* bring the sig status down */
1087                         sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
1088                         sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_DOWN;
1089                         ftdm_span_send_signal(ftdmchan->span, &sigev); 
1090 
1091                         /* send a blo */
1092                         ft_to_sngss7_blo (ftdmchan);
1093 
1094                         /* check the last state and return to it to allow the call to finish */
1095                         goto suspend_goto_last;
1096                 }
1097 
1098                 if (sngss7_test_flag (sngss7_info, FLAG_CKT_MN_UNBLK_TX)){
1099                         SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_UNBLK_TX flag %s\n", "");
1100 
1101                         /* clear the unblock flag */
1102                         sngss7_clear_flag (sngss7_info, FLAG_CKT_MN_UNBLK_TX);
1103 
1104                         /* bring the sig status up */
1105                         sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
1106                         sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_UP;
1107                         ftdm_span_send_signal(ftdmchan->span, &sigev); 
1108 
1109                         /* send a ubl */
1110                         ft_to_sngss7_ubl (ftdmchan);
1111 
1112                         /* check the last state and return to it to allow the call to finish */
1113                         goto suspend_goto_last;
1114                 }
1115 
1116                 /**********************************************************************/
1117                 if (sngss7_test_flag (sngss7_info, FLAG_CKT_LC_BLOCK_RX)) {
1118                         SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_LC_BLOCK_RX flag %s\n", "");
1119 
1120                         /* send a BLA */
1121                         /*ft_to_sngss7_bla(ftdmchan);*/
1122 
1123                         /* check the last state and return to it to allow the call to finish */
1124                         goto suspend_goto_last;
1125                 }
1126 
1127                 if (sngss7_test_flag (sngss7_info, FLAG_CKT_LC_UNBLK_RX)) {
1128                         SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_LC_UNBLK_RX flag %s\n", "");
1129                         
1130                         /* clear the unblock flag */
1131                         sngss7_clear_flag (sngss7_info, FLAG_CKT_MN_UNBLK_RX);
1132 
1133                         /* send a uba */
1134                         /*ft_to_sngss7_uba(ftdmchan);*/
1135 
1136                         /* check the last state and return to it to allow the call to finish */
1137                         goto suspend_goto_last;
1138                 }
1139                 /**********************************************************************/
1140                 if (sngss7_test_flag (sngss7_info, FLAG_CKT_UCIC_BLOCK)) {
1141                         SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_UCIC_BLOCK flag %s\n", "");
1142 
1143                         /* bring the channel signaling status to down */
1144                         sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
1145                         sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_DOWN;
1146                         ftdm_span_send_signal (ftdmchan->span, &sigev);
1147 
1148                         /* remove any reset flags */
1149                         clear_rx_grs_flags(sngss7_info);
1150                         clear_rx_grs_data(sngss7_info);
1151                         clear_tx_grs_flags(sngss7_info);
1152                         clear_tx_grs_data(sngss7_info);
1153                         clear_rx_rsc_flags(sngss7_info);
1154                         clear_tx_rsc_flags(sngss7_info);
1155                         
1156                         /* bring the channel down */
1157                         goto suspend_goto_last;
1158                 }
1159 
1160                 if (sngss7_test_flag (sngss7_info, FLAG_CKT_UCIC_UNBLK)) {
1161                         SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_UCIC_UNBLK flag %s\n", "");;
1162 
1163                         /* remove the UCIC block flag */
1164                         sngss7_clear_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK);
1165 
1166                         /* remove the UCIC unblock flag */
1167                         sngss7_clear_flag(sngss7_info, FLAG_CKT_UCIC_UNBLK);
1168 
1169                         /* throw the channel into reset to sync states */
1170                         sngss7_set_flag(sngss7_info, FLAG_RESET_TX);
1171 
1172                         /* bring the channel into restart again */
1173                         goto suspend_goto_restart;
1174                 }
1175 
1176 suspend_goto_last:
1177                 ftdm_set_state_locked (ftdmchan, ftdmchan->last_state);
1178                 break;
1179 
1180 suspend_goto_restart:
1181                 ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RESTART);
1182                 break;
1183 
1184         /**************************************************************************/
1185         case FTDM_CHANNEL_STATE_IN_LOOP:        /* COT test */
1186 
1187                 isup_intf = &g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId];
1188 
1189                 if (sngss7_test_options(isup_intf, SNGSS7_LPA_FOR_COT)) {
1190                         /* send the lpa */
1191                         ft_to_sngss7_lpa (ftdmchan);
1192                 } 
1193 
1194                 break;
1195         /**************************************************************************/
1196         case FTDM_CHANNEL_STATE_IDLE:
1197                         ftdm_set_state_locked(ftdmchan, ftdmchan->last_state);
1198                 break;
1199         /**************************************************************************/
1200         default:
1201                 /* we don't handle any of the other states */
1202                 SS7_ERROR_CHAN(ftdmchan, "ftmod_sangoma_ss7 does not support %s state\n",  ftdm_channel_state2str (ftdmchan->state));
1203                 
1204                 break;
1205         /**************************************************************************/
1206         }/*switch (ftdmchan->state) */
1207 
1208         return FTDM_SUCCESS;
1209 }
1210 
1211 /******************************************************************************/
1212 static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(ftdm_sangoma_ss7_outgoing_call)
1213 {
1214         sngss7_chan_data_t  *sngss7_info = ftdmchan->call_data;
1215 
1216         /* lock the channel while we check whether it is availble */
1217         ftdm_mutex_lock (ftdmchan->mutex);
1218 
1219         /* check if there is a pending state change, give it a bit to clear */
1220         if (check_for_state_change(ftdmchan)) {
1221                 SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic);
1222                 /* check if we need to die */
1223                 SS7_ASSERT;
1224                 /* end the request */
1225                 goto outgoing_fail;
1226         };
1227 
1228         /* check if the channel sig state is UP */
1229         if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
1230                 SS7_ERROR_CHAN(ftdmchan, "Requested channel sig state is down, cancelling call!%s\n", " ");
1231                 goto outgoing_fail;
1232         }
1233 
1234         /* check if there is a remote block */
1235         if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) ||
1236                 (sngss7_test_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX)) ||
1237                 (sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) {
1238 
1239                 /* the channel is blocked...can't send any calls here */
1240                 SS7_ERROR_CHAN(ftdmchan, "Requested channel is remotely blocked, re-hunt channel!%s\n", " ");
1241                 goto outgoing_break;
1242         }
1243 
1244         /* check if there is a local block */
1245         if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) ||
1246                 (sngss7_test_flag(sngss7_info, FLAG_GRP_HW_BLOCK_TX)) ||
1247                 (sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX))) {
1248 
1249                 /* KONRAD FIX ME : we should check if this is a TEST call and allow it */
1250 
1251                 /* the channel is blocked...can't send any calls here */
1252                 SS7_ERROR_CHAN(ftdmchan, "Requested channel is locally blocked, re-hunt channel!%s\n", " ");
1253                 goto outgoing_break;
1254         }
1255 
1256         /* check the state of the channel */
1257         switch (ftdmchan->state){
1258         /**************************************************************************/
1259         case FTDM_CHANNEL_STATE_DOWN:
1260                 /* inform the monitor thread that we want to make a call */
1261                 ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_DIALING);
1262 
1263                 /* unlock the channel */
1264                 ftdm_mutex_unlock (ftdmchan->mutex);
1265                 
1266                 goto outgoing_successful;
1267                 break;
1268         /**************************************************************************/
1269         default:
1270                 /* the channel is already used...this can't be, end the request */
1271                 SS7_ERROR("Outgoing call requested channel in already in use...indicating glare on span=%d,chan=%d\n",
1272                                         ftdmchan->physical_span_id,
1273                                         ftdmchan->physical_chan_id);
1274 
1275                 goto outgoing_break;
1276                 break;
1277         /**************************************************************************/
1278         } /* switch (ftdmchan->state) (original call) */
1279 
1280 outgoing_fail:
1281         SS7_DEBUG_CHAN(ftdmchan, "Call Request failed%s\n", " ");
1282         /* unlock the channel */
1283         ftdm_mutex_unlock (ftdmchan->mutex);
1284         return FTDM_FAIL;
1285 
1286 outgoing_break:
1287         SS7_DEBUG_CHAN(ftdmchan, "Call Request re-hunt%s\n", " ");
1288         /* unlock the channel */
1289         ftdm_mutex_unlock (ftdmchan->mutex);
1290         return FTDM_BREAK;
1291 
1292 outgoing_successful:
1293         SS7_DEBUG_CHAN(ftdmchan, "Call Request successful%s\n", " ");
1294         /* unlock the channel */
1295         ftdm_mutex_unlock (ftdmchan->mutex);
1296         return FTDM_SUCCESS;
1297 }
1298 
1299 /******************************************************************************/
1300 #if 0
1301           static FIO_CHANNEL_REQUEST_FUNCTION (ftdm_sangoma_ss7_request_chan)
1302           {
1303         SS7_INFO ("KONRAD-> I got called %s\n", __FUNCTION__);
1304         return FTDM_SUCCESS;
1305           }
1306 
1307 #endif
1308 
1309 /******************************************************************************/
1310 
1311 /* FT-CORE SIG STATUS FUNCTIONS ********************************************** */
1312 static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(ftdm_sangoma_ss7_get_sig_status)
1313 {
1314         if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_SIG_UP)) {
1315                 *status = FTDM_SIG_STATE_UP;
1316         } else {
1317                 *status = FTDM_SIG_STATE_DOWN;
1318         }
1319 
1320         return FTDM_SUCCESS;
1321 }
1322 
1323 /******************************************************************************/
1324 static FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(ftdm_sangoma_ss7_set_sig_status)
1325 {
1326         SS7_ERROR ("Cannot set channel status in this module\n");
1327         return FTDM_NOTIMPL;
1328 }
1329 
1330 /* FT-CORE SIG FUNCTIONS ******************************************************/
1331 static ftdm_status_t ftdm_sangoma_ss7_start(ftdm_span_t * span)
1332 {
1333         ftdm_channel_t          *ftdmchan = NULL;
1334         sngss7_chan_data_t      *sngss7_info = NULL;
1335         sngss7_span_data_t      *sngss7_span = NULL;
1336         sng_isup_inf_t          *sngss7_intf = NULL;
1337         int                             x;
1338 
1339 
1340         SS7_INFO ("Starting span %s:%u.\n", span->name, span->span_id);
1341 
1342         /* throw the channels in pause */
1343         for (x = 1; x < (span->chan_count + 1); x++) {
1344                 /* extract the channel structure and sngss7 channel data */
1345                 ftdmchan = span->channels[x];
1346                 if (ftdmchan->call_data == NULL) continue;
1347                 sngss7_info = ftdmchan->call_data;
1348                 sngss7_span = ftdmchan->span->signal_data;
1349                 sngss7_intf = &g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId];
1350 
1351 
1352                 /* lock the channel */
1353                 ftdm_mutex_lock(ftdmchan->mutex);
1354 
1355                 /* check if the interface is paused or resumed */
1356                 if (sngss7_test_flag(sngss7_intf, SNGSS7_PAUSED)) {
1357                         /* throw the pause flag */
1358                         sngss7_clear_flag(sngss7_info, FLAG_INFID_RESUME);
1359                         sngss7_set_flag(sngss7_info, FLAG_INFID_PAUSED);
1360                 } else {
1361                         /* throw the pause flag */
1362                         sngss7_clear_flag(sngss7_info, FLAG_INFID_PAUSED);
1363                         sngss7_set_flag(sngss7_info, FLAG_INFID_RESUME);
1364                 }
1365 #if 0
1366                 /* throw the grp reset flag */
1367                 sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX);
1368                 if (x == 1) {
1369                         sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_BASE);
1370                         sngss7_span->tx_grs.circuit = sngss7_info->circuit->id;
1371                         sngss7_span->tx_grs.range = span->chan_count -1;
1372                 }
1373 #else
1374                 /* throw the channel into reset */
1375                 sngss7_set_flag(sngss7_info, FLAG_RESET_TX);
1376 #endif
1377                 /* throw the channel to suspend */
1378                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
1379 
1380                 /* unlock the channel */
1381                 ftdm_mutex_unlock(ftdmchan->mutex);
1382         }
1383 
1384         /* clear the monitor thread stop flag */
1385         ftdm_clear_flag (span, FTDM_SPAN_STOP_THREAD);
1386         ftdm_clear_flag (span, FTDM_SPAN_IN_THREAD);
1387 
1388         /* activate all the configured ss7 links */
1389         if (ft_to_sngss7_activate_all()) {
1390                 SS7_CRITICAL ("Failed to activate LibSngSS7!\n");
1391                 return FTDM_FAIL;
1392         }
1393 
1394         /*start the span monitor thread */
1395         if (ftdm_thread_create_detached (ftdm_sangoma_ss7_run, span) != FTDM_SUCCESS) {
1396                 SS7_CRITICAL ("Failed to start Span Monitor Thread!\n");
1397                 return FTDM_FAIL;
1398         }
1399 
1400         SS7_DEBUG ("Finished starting span %s:%u.\n", span->name, span->span_id);
1401 
1402         return FTDM_SUCCESS;
1403 }
1404 
1405 /******************************************************************************/
1406 static ftdm_status_t ftdm_sangoma_ss7_stop(ftdm_span_t * span)
1407 {
1408         /*this function is called by the FT-Core to stop this span */
1409 
1410         ftdm_log (FTDM_LOG_INFO, "Stopping span %s:%u.\n", span->name,span->span_id);
1411 
1412         /* throw the STOP_THREAD flag to signal monitor thread stop */
1413         ftdm_set_flag (span, FTDM_SPAN_STOP_THREAD);
1414 
1415         /* wait for the thread to stop */
1416         while (ftdm_test_flag (span, FTDM_SPAN_IN_THREAD)) {
1417                 ftdm_log (FTDM_LOG_DEBUG,"Waiting for monitor thread to end for %s:%u.\n",
1418                                                                         span->name,
1419                                                                         span->span_id);
1420                 ftdm_sleep (1);
1421         }
1422 
1423         /* KONRAD FIX ME - deconfigure any circuits, links, attached to this span */
1424 
1425         ftdm_log (FTDM_LOG_DEBUG, "Finished stopping span %s:%u.\n", span->name, span->span_id);
1426 
1427         return FTDM_SUCCESS;
1428 }
1429 
1430 /* SIG_FUNCTIONS ***************************************************************/
1431 static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_ss7_span_config)
1432 {
1433         sngss7_span_data_t      *ss7_span_info;
1434 
1435         ftdm_log (FTDM_LOG_INFO, "Configuring ftmod_sangoma_ss7 span = %s(%d)...\n",
1436                                                                 span->name,
1437                                                                 span->span_id);
1438 
1439         /* initalize the span's data structure */
1440         ss7_span_info = ftdm_calloc (1, sizeof (sngss7_span_data_t));
1441 
1442         /* create a timer schedule */
1443         if (ftdm_sched_create(&ss7_span_info->sched, "SngSS7_Schedule")) {
1444                 SS7_CRITICAL("Unable to create timer schedule!\n");
1445                 return FTDM_FAIL;
1446         }
1447 
1448         /* start the free run thread for the schedule */
1449         if (ftdm_sched_free_run(ss7_span_info->sched)) {
1450                 SS7_CRITICAL("Unable to schedule free run!\n");
1451                 return FTDM_FAIL;
1452         }
1453 
1454         /* create an event queue for this span */
1455         if ((ftdm_queue_create(&(ss7_span_info)->event_queue, SNGSS7_EVENT_QUEUE_SIZE)) != FTDM_SUCCESS) {
1456                 SS7_CRITICAL("Unable to create event queue!\n");
1457                 return FTDM_FAIL;
1458         }
1459 
1460         /*setup the span structure with the info so far */
1461         g_ftdm_sngss7_data.sig_cb               = sig_cb;
1462         span->start                                     = ftdm_sangoma_ss7_start;
1463         span->stop                                              = ftdm_sangoma_ss7_stop;
1464         span->signal_type                               = FTDM_SIGTYPE_SS7;
1465         span->signal_data                               = NULL;
1466         span->outgoing_call                     = ftdm_sangoma_ss7_outgoing_call;
1467         span->channel_request                   = NULL;
1468         span->signal_cb                                 = sig_cb;
1469         span->get_channel_sig_status    = ftdm_sangoma_ss7_get_sig_status;
1470         span->set_channel_sig_status    = ftdm_sangoma_ss7_set_sig_status;
1471         span->state_map                                 = &sangoma_ss7_state_map;
1472         span->state_processor = ftdm_sangoma_ss7_process_state_change;
1473         span->signal_data                                       = ss7_span_info;
1474 
1475         /* set the flag to indicate that this span uses channel state change queues */
1476         ftdm_set_flag (span, FTDM_SPAN_USE_CHAN_QUEUE);
1477         /* set the flag to indicate that this span uses sig event queues */
1478         ftdm_set_flag (span, FTDM_SPAN_USE_SIGNALS_QUEUE);
1479 
1480         /* parse the configuration and apply to the global config structure */
1481         if (ftmod_ss7_parse_xml(ftdm_parameters, span)) {
1482                 ftdm_log (FTDM_LOG_CRIT, "Failed to parse configuration!\n");
1483                 return FTDM_FAIL;
1484         }
1485 
1486         /* configure libsngss7 */
1487         if (ft_to_sngss7_cfg_all()) {
1488                 ftdm_log (FTDM_LOG_CRIT, "Failed to configure LibSngSS7!\n");
1489                 return FTDM_FAIL;
1490         }
1491 
1492         ftdm_log (FTDM_LOG_INFO, "Finished configuring ftmod_sangoma_ss7 span = %s(%d)...\n",
1493                                                                 span->name,
1494                                                                 span->span_id);
1495 
1496         return FTDM_SUCCESS;
1497 }
1498 
1499 /******************************************************************************/
1500 static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_ss7_init)
1501 {
1502         /*this function is called by the FT-core to load the signaling module */
1503         uint32_t major = 0;
1504         uint32_t minor = 0;
1505         uint32_t build = 0;
1506 
1507         ftdm_log (FTDM_LOG_INFO, "Loading ftmod_sangoma_ss7...\n");
1508 
1509         /* default the global structure */
1510         memset (&g_ftdm_sngss7_data, 0x0, sizeof (ftdm_sngss7_data_t));
1511 
1512         sngss7_id = 0;
1513 
1514         cmbLinkSetId = 0;
1515 
1516         /* initalize the global gen_config flag */
1517         g_ftdm_sngss7_data.gen_config = 0;
1518 
1519         /* function trace initizalation */
1520         g_ftdm_sngss7_data.function_trace = 1;
1521         g_ftdm_sngss7_data.function_trace_level = 7;
1522 
1523         /* message (IAM, ACM, ANM, etc) trace initizalation */
1524         g_ftdm_sngss7_data.message_trace = 1;
1525         g_ftdm_sngss7_data.message_trace_level = 6;
1526 
1527         /* setup the call backs needed by Sangoma_SS7 library */
1528         sng_event.cc.sng_con_ind = sngss7_con_ind;
1529         sng_event.cc.sng_con_cfm = sngss7_con_cfm;
1530         sng_event.cc.sng_con_sta = sngss7_con_sta;
1531         sng_event.cc.sng_rel_ind = sngss7_rel_ind;
1532         sng_event.cc.sng_rel_cfm = sngss7_rel_cfm;
1533         sng_event.cc.sng_dat_ind = sngss7_dat_ind;
1534         sng_event.cc.sng_fac_ind = sngss7_fac_ind;
1535         sng_event.cc.sng_fac_cfm = sngss7_fac_cfm;
1536         sng_event.cc.sng_sta_ind = sngss7_sta_ind;
1537         sng_event.cc.sng_umsg_ind = sngss7_umsg_ind;
1538         sng_event.cc.sng_susp_ind = sngss7_susp_ind;
1539         sng_event.cc.sng_resm_ind = sngss7_resm_ind;
1540         sng_event.cc.sng_ssp_sta_cfm = sngss7_ssp_sta_cfm;
1541 
1542         sng_event.sm.sng_log = handle_sng_log;
1543         sng_event.sm.sng_mtp1_alarm = handle_sng_mtp1_alarm;
1544         sng_event.sm.sng_mtp2_alarm = handle_sng_mtp2_alarm;
1545         sng_event.sm.sng_mtp3_alarm = handle_sng_mtp3_alarm;
1546         sng_event.sm.sng_isup_alarm = handle_sng_isup_alarm;
1547         sng_event.sm.sng_cc_alarm = handle_sng_cc_alarm;
1548 
1549         /* initalize sng_ss7 library */
1550         sng_isup_init (&sng_event);
1551 
1552         /* print the version of the library being used */
1553         sng_isup_version(&major, &minor, &build);
1554         SS7_INFO("Loaded LibSng-SS7 %d.%d.%d\n", major, minor, build);
1555 
1556         /* crash on assert fail */
1557         ftdm_global_set_crash_policy (FTDM_CRASH_ON_ASSERT);
1558 
1559         return FTDM_SUCCESS;
1560 }
1561 
1562 /******************************************************************************/
1563 static FIO_SIG_UNLOAD_FUNCTION(ftdm_sangoma_ss7_unload)
1564 {
1565         /*this function is called by the FT-core to unload the signaling module */
1566 
1567         ftdm_log (FTDM_LOG_INFO, "Starting ftmod_sangoma_ss7 unload...\n");
1568 
1569         sng_isup_free();
1570 
1571         ftdm_log (FTDM_LOG_INFO, "Finished ftmod_sangoma_ss7 unload!\n");
1572         return FTDM_SUCCESS;
1573 }
1574 
1575 /******************************************************************************/
1576 static FIO_API_FUNCTION(ftdm_sangoma_ss7_api)
1577 {
1578         /* handle this in it's own file....so much to do */
1579         return (ftdm_sngss7_handle_cli_cmd (stream, data));
1580 }
1581 
1582 /******************************************************************************/
1583 static FIO_IO_LOAD_FUNCTION(ftdm_sangoma_ss7_io_init)
1584 {
1585         assert (fio != NULL);
1586         memset (&g_ftdm_sngss7_interface, 0, sizeof (g_ftdm_sngss7_interface));
1587 
1588         g_ftdm_sngss7_interface.name = "ss7";
1589         g_ftdm_sngss7_interface.api = ftdm_sangoma_ss7_api;
1590 
1591         *fio = &g_ftdm_sngss7_interface;
1592 
1593         return FTDM_SUCCESS;
1594 }
1595 
1596 /******************************************************************************/
1597 
1598 
1599 /* START **********************************************************************/
1600 ftdm_module_t ftdm_module = {
1601         "sangoma_ss7",                                  /*char name[256];                                  */
1602         ftdm_sangoma_ss7_io_init,               /*fio_io_load_t                                  */
1603         NULL,                                                   /*fio_io_unload_t                                  */
1604         ftdm_sangoma_ss7_init,                  /*fio_sig_load_t                                        */
1605         NULL,                                                   /*fio_sig_configure_t                      */
1606         ftdm_sangoma_ss7_unload,                /*fio_sig_unload_t                                */
1607         ftdm_sangoma_ss7_span_config    /*fio_configure_span_signaling_t        */
1608 };
1609 /******************************************************************************/
1610 
1611 /******************************************************************************/
1612 /* For Emacs:
1613 * Local Variables:
1614 * mode:c
1615 * indent-tabs-mode:t
1616 * tab-width:4
1617 * c-basic-offset:4
1618 * End:
1619 * For VIM:
1620 * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
1621 */
1622 /******************************************************************************/

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