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 void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan);
  50 static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_event);
  51 
  52 static ftdm_status_t ftdm_sangoma_ss7_stop (ftdm_span_t * span);
  53 static ftdm_status_t ftdm_sangoma_ss7_start (ftdm_span_t * span);
  54 /******************************************************************************/
  55 
  56 /* STATE MAP ******************************************************************/
  57 ftdm_state_map_t sangoma_ss7_state_map = {
  58   {
  59    {
  60         ZSD_INBOUND,
  61         ZSM_UNACCEPTABLE,
  62         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_END},
  63         {FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_DOWN,
  64          FTDM_CHANNEL_STATE_IN_LOOP, FTDM_CHANNEL_STATE_COLLECT,
  65          FTDM_CHANNEL_STATE_RING, FTDM_CHANNEL_STATE_PROGRESS,
  66          FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP,
  67          FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_TERMINATING,
  68          FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END}
  69         },
  70    {
  71         ZSD_INBOUND,
  72         ZSM_UNACCEPTABLE,
  73         {FTDM_CHANNEL_STATE_RESTART, FTDM_END},
  74         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_TERMINATING,
  75          FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_HANGUP_COMPLETE,
  76          FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_IDLE, FTDM_END}
  77         },
  78         {
  79         ZSD_INBOUND,
  80         ZSM_UNACCEPTABLE,
  81         {FTDM_CHANNEL_STATE_IDLE, FTDM_END},
  82         {FTDM_CHANNEL_STATE_RESTART, FTDM_END}
  83         },
  84    {
  85         ZSD_INBOUND,
  86         ZSM_UNACCEPTABLE,
  87         {FTDM_CHANNEL_STATE_DOWN, FTDM_END},
  88         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
  89          FTDM_CHANNEL_STATE_COLLECT, FTDM_CHANNEL_STATE_IN_LOOP, FTDM_END}
  90         },
  91    {
  92         ZSD_INBOUND,
  93         ZSM_UNACCEPTABLE,
  94         {FTDM_CHANNEL_STATE_IN_LOOP, FTDM_END},
  95         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
  96          FTDM_CHANNEL_STATE_COLLECT, FTDM_CHANNEL_STATE_DOWN, 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, FTDM_END}
 104         },
 105    {
 106         ZSD_INBOUND,
 107         ZSM_UNACCEPTABLE,
 108         {FTDM_CHANNEL_STATE_RING, FTDM_END},
 109         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 110          FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
 111          FTDM_CHANNEL_STATE_PROGRESS, FTDM_END}
 112         },
 113    {
 114         ZSD_INBOUND,
 115         ZSM_UNACCEPTABLE,
 116         {FTDM_CHANNEL_STATE_PROGRESS, FTDM_END},
 117         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 118          FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
 119          FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_END}
 120         },
 121    {
 122         ZSD_INBOUND,
 123         ZSM_UNACCEPTABLE,
 124         {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_END},
 125         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 126          FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
 127          FTDM_CHANNEL_STATE_UP, FTDM_END}
 128         },
 129    {
 130         ZSD_INBOUND,
 131         ZSM_UNACCEPTABLE,
 132         {FTDM_CHANNEL_STATE_UP, FTDM_END},
 133         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 134          FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_END}
 135         },
 136    {
 137         ZSD_INBOUND,
 138         ZSM_UNACCEPTABLE,
 139         {FTDM_CHANNEL_STATE_CANCEL, FTDM_END},
 140         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 141          FTDM_CHANNEL_STATE_HANGUP, FTDM_END}
 142         },
 143    {
 144         ZSD_INBOUND,
 145         ZSM_UNACCEPTABLE,
 146         {FTDM_CHANNEL_STATE_TERMINATING, FTDM_END},
 147         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 148          FTDM_CHANNEL_STATE_HANGUP, FTDM_END}
 149         },
 150    {
 151         ZSD_INBOUND,
 152         ZSM_UNACCEPTABLE,
 153         {FTDM_CHANNEL_STATE_HANGUP, FTDM_END},
 154         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 155          FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END}
 156         },
 157    {
 158         ZSD_INBOUND,
 159         ZSM_UNACCEPTABLE,
 160         {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END},
 161         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 162          FTDM_CHANNEL_STATE_DOWN, FTDM_END}
 163         },
 164         /**************************************************************************/
 165    {
 166         ZSD_OUTBOUND,
 167         ZSM_UNACCEPTABLE,
 168         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_END},
 169         {FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_DOWN,
 170          FTDM_CHANNEL_STATE_IN_LOOP, FTDM_CHANNEL_STATE_DIALING,
 171          FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA,
 172          FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_CANCEL,
 173          FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
 174          FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END}
 175         },
 176    {
 177         ZSD_OUTBOUND,
 178         ZSM_UNACCEPTABLE,
 179         {FTDM_CHANNEL_STATE_RESTART, FTDM_END},
 180         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_TERMINATING,
 181          FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_HANGUP_COMPLETE,
 182          FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_IDLE, FTDM_END}
 183         },
 184         {
 185         ZSD_OUTBOUND,
 186         ZSM_UNACCEPTABLE,
 187         {FTDM_CHANNEL_STATE_IDLE, FTDM_END},
 188         {FTDM_CHANNEL_STATE_RESTART, FTDM_END}
 189         },
 190    {
 191         ZSD_OUTBOUND,
 192         ZSM_UNACCEPTABLE,
 193         {FTDM_CHANNEL_STATE_DOWN, FTDM_END},
 194         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 195          FTDM_CHANNEL_STATE_DIALING, FTDM_CHANNEL_STATE_IN_LOOP, FTDM_END}
 196         },
 197    {
 198         ZSD_OUTBOUND,
 199         ZSM_UNACCEPTABLE,
 200         {FTDM_CHANNEL_STATE_IN_LOOP, FTDM_END},
 201         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 202          FTDM_CHANNEL_STATE_DIALING, FTDM_CHANNEL_STATE_DOWN, FTDM_END}
 203         },
 204    {
 205         ZSD_OUTBOUND,
 206         ZSM_UNACCEPTABLE,
 207         {FTDM_CHANNEL_STATE_DIALING, FTDM_END},
 208         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 209          FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_TERMINATING,
 210          FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS,
 211          FTDM_CHANNEL_STATE_PROGRESS_MEDIA ,FTDM_CHANNEL_STATE_UP, FTDM_END}
 212         },
 213    {
 214         ZSD_OUTBOUND,
 215         ZSM_UNACCEPTABLE,
 216         {FTDM_CHANNEL_STATE_PROGRESS, FTDM_END},
 217         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 218          FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
 219          FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_END}
 220         },
 221    {
 222         ZSD_OUTBOUND,
 223         ZSM_UNACCEPTABLE,
 224         {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_END},
 225         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 226          FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
 227          FTDM_CHANNEL_STATE_UP, FTDM_END}
 228         },
 229    {
 230         ZSD_OUTBOUND,
 231         ZSM_UNACCEPTABLE,
 232         {FTDM_CHANNEL_STATE_UP, FTDM_END},
 233         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 234          FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_END}
 235         },
 236    {
 237         ZSD_OUTBOUND,
 238         ZSM_UNACCEPTABLE,
 239         {FTDM_CHANNEL_STATE_CANCEL, FTDM_END},
 240         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 241          FTDM_CHANNEL_STATE_HANGUP, FTDM_END}
 242         },
 243    {
 244         ZSD_OUTBOUND,
 245         ZSM_UNACCEPTABLE,
 246         {FTDM_CHANNEL_STATE_TERMINATING, FTDM_END},
 247         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 248          FTDM_CHANNEL_STATE_HANGUP, FTDM_END}
 249         },
 250    {
 251         ZSD_OUTBOUND,
 252         ZSM_UNACCEPTABLE,
 253         {FTDM_CHANNEL_STATE_HANGUP, FTDM_END},
 254         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 255          FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END}
 256         },
 257    {
 258         ZSD_OUTBOUND,
 259         ZSM_UNACCEPTABLE,
 260         {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END},
 261         {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
 262          FTDM_CHANNEL_STATE_DOWN, FTDM_END}
 263         },
 264    }
 265 };
 266 
 267 /******************************************************************************/
 268 
 269 /* MONITIOR THREADS ***********************************************************/
 270 static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
 271 {
 272         ftdm_interrupt_t        *ftdm_sangoma_ss7_int[2];
 273         ftdm_span_t             *ftdmspan = (ftdm_span_t *) obj;
 274         ftdm_channel_t          *ftdmchan = NULL;
 275         sngss7_event_data_t     *sngss7_event = NULL;
 276         sngss7_span_data_t      *sngss7_span = (sngss7_span_data_t *)ftdmspan->mod_data;
 277 
 278         ftdm_log (FTDM_LOG_INFO, "ftmod_sangoma_ss7 monitor thread for span=%u started.\n", ftdmspan->span_id);
 279 
 280         /* set IN_THREAD flag so that we know this thread is running */
 281         ftdm_set_flag (ftdmspan, FTDM_SPAN_IN_THREAD);
 282 
 283         /* get an interrupt queue for this span for channel state changes */
 284         if (ftdm_queue_get_interrupt (ftdmspan->pendingchans, &ftdm_sangoma_ss7_int[0]) != FTDM_SUCCESS) {
 285                 SS7_CRITICAL ("Failed to get a ftdm_interrupt for span = %d for channel state changes!\n", ftdmspan->span_id);
 286                 goto ftdm_sangoma_ss7_run_exit;
 287         }
 288 
 289         /* get an interrupt queue for this span for Trillium events */
 290         if (ftdm_queue_get_interrupt (sngss7_span->event_queue, &ftdm_sangoma_ss7_int[1]) != FTDM_SUCCESS) {
 291                 SS7_CRITICAL ("Failed to get a ftdm_interrupt for span = %d for Trillium event queue!\n", ftdmspan->span_id);
 292                 goto ftdm_sangoma_ss7_run_exit;
 293         }
 294 
 295         while (ftdm_running () && !(ftdm_test_flag (ftdmspan, FTDM_SPAN_STOP_THREAD))) {
 296 
 297                 /* check the channel state queue for an event*/ 
 298                 switch ((ftdm_interrupt_multiple_wait(ftdm_sangoma_ss7_int, 2, 100))) {
 299                 /**********************************************************************/
 300                 case FTDM_SUCCESS:      /* process all pending state changes */
 301 
 302                         /* clean out all pending channel state changes */
 303                         while ((ftdmchan = ftdm_queue_dequeue (ftdmspan->pendingchans))) {
 304                                 
 305                                 /*first lock the channel */
 306                                 ftdm_mutex_lock(ftdmchan->mutex);
 307 
 308                                 /* process state changes for this channel until they are all done */
 309                                 while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
 310                                         ftdm_sangoma_ss7_process_state_change (ftdmchan);
 311                                 }
 312  
 313                                 /* unlock the channel */
 314                                 ftdm_mutex_unlock (ftdmchan->mutex);                            
 315                         }/* while ((ftdmchan = ftdm_queue_dequeue(ftdmspan->pendingchans)))  */
 316 
 317                         /* clean out all pending stack events */
 318                         while ((sngss7_event = ftdm_queue_dequeue(sngss7_span->event_queue))) {
 319                                 ftdm_sangoma_ss7_process_stack_event(sngss7_event);
 320                                 ftdm_safe_free(sngss7_event);
 321                         }/* while ((sngss7_event = ftdm_queue_dequeue(ftdmspan->signal_data->event_queue))) */
 322 
 323                         /* signal the core that sig events are queued for processing */
 324                         ftdm_span_trigger_signals(ftdmspan);
 325 
 326                         break;
 327                 /**********************************************************************/
 328                 case FTDM_TIMEOUT:
 329                         SS7_DEVEL_DEBUG ("ftdm_interrupt_wait timed-out on span = %d\n",ftdmspan->span_id);
 330 
 331                         break;
 332                 /**********************************************************************/
 333                 case FTDM_FAIL:
 334                         SS7_ERROR ("ftdm_interrupt_wait returned error!\non span = %d\n", ftdmspan->span_id);
 335 
 336                         break;
 337                 /**********************************************************************/
 338                 default:
 339                         SS7_ERROR("ftdm_interrupt_wait returned with unknown code on span = %d\n",ftdmspan->span_id);
 340 
 341                         break;
 342                 /**********************************************************************/
 343                 } /* switch ((ftdm_interrupt_wait(ftdm_sangoma_ss7_int, 100))) */
 344 
 345                 /* check if there is a GRA to proccess on the span */
 346                 if (sngss7_span->rx_gra.range > 0) {
 347                         check_if_rx_gra_started(ftdmspan);
 348                 } /* if (sngss7->span->rx_gra.range > 0) */
 349 
 350                 /* check if there is a GRS being processed on the span */
 351                 if (sngss7_span->rx_grs.range > 0) {
 352                         /* check if the rx_grs has started */
 353                         check_if_rx_grs_started(ftdmspan);
 354 
 355                         /* check if the rx_grs has cleared */
 356                         check_if_rx_grs_processed(ftdmspan);
 357                 } /* if (sngss7_span->rx_grs.range > 0) */
 358 
 359                 /* check if there is a UCIC to be processed on the span */
 360                 if (sngss7_span->ucic.range > 0) {
 361                         /* process the span wide UCIC */
 362                         process_span_ucic(ftdmspan);
 363                 } /* if (sngss7_span->ucic.range > 0) */
 364 
 365                 /* check each channel on the span to see if there is an un-procressed SUS/RES flag */
 366                 check_for_res_sus_flag(ftdmspan);
 367         } /* master while loop */
 368 
 369         /* clear the IN_THREAD flag so that we know the thread is done */
 370         ftdm_clear_flag (ftdmspan, FTDM_SPAN_IN_THREAD);
 371 
 372         ftdm_log (FTDM_LOG_INFO,"ftmod_sangoma_ss7 monitor thread for span=%u stopping.\n",ftdmspan->span_id);
 373 
 374         return NULL;
 375 
 376 ftdm_sangoma_ss7_run_exit:
 377 
 378         /* clear the IN_THREAD flag so that we know the thread is done */
 379         ftdm_clear_flag (ftdmspan, FTDM_SPAN_IN_THREAD);
 380 
 381         ftdm_log (FTDM_LOG_INFO,"ftmod_sangoma_ss7 monitor thread for span=%u stopping due to error.\n",ftdmspan->span_id);
 382 
 383         ftdm_sangoma_ss7_stop (ftdmspan);
 384 
 385         return NULL;
 386 }
 387 
 388 /******************************************************************************/
 389 static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_event)
 390 {
 391         sngss7_chan_data_t  *sngss7_info ;
 392         ftdm_channel_t    *ftdmchan;
 393 
 394         /* get the ftdmchan and ss7_chan_data from the circuit */
 395         if (extract_chan_data(sngss7_event->circuit, &sngss7_info, &ftdmchan)) {
 396                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", sngss7_event->circuit);
 397                 return;
 398         }
 399 
 400         /* now that we have the right channel...put a lock on it so no-one else can use it */
 401         ftdm_mutex_lock(ftdmchan->mutex);
 402 
 403         /* while there's a state change present on this channel process it */
 404         while (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
 405                 ftdm_sangoma_ss7_process_state_change(ftdmchan);
 406         }
 407 
 408         /* figure out the type of event and send it to the right handler */
 409         switch (sngss7_event->event_id) {
 410         /**************************************************************************/
 411         case (SNGSS7_CON_IND_EVENT):
 412                 handle_con_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit,  &sngss7_event->event.siConEvnt);
 413                 break;
 414         /**************************************************************************/
 415         case (SNGSS7_CON_CFM_EVENT):
 416                 handle_con_cfm(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit,  &sngss7_event->event.siConEvnt);
 417                 break;
 418         /**************************************************************************/
 419         case (SNGSS7_CON_STA_EVENT):
 420                 handle_con_sta(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit,  &sngss7_event->event.siCnStEvnt, sngss7_event->evntType);
 421                 break;
 422         /**************************************************************************/
 423         case (SNGSS7_REL_IND_EVENT):
 424                 handle_rel_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit,  &sngss7_event->event.siRelEvnt);
 425                 break;
 426         /**************************************************************************/
 427         case (SNGSS7_REL_CFM_EVENT):
 428                 handle_rel_cfm(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit,  &sngss7_event->event.siRelEvnt);
 429                 break;
 430         /**************************************************************************/
 431         case (SNGSS7_DAT_IND_EVENT):
 432                 handle_dat_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit,  &sngss7_event->event.siInfoEvnt);
 433                 break;
 434         /**************************************************************************/
 435         case (SNGSS7_FAC_IND_EVENT):
 436                 handle_fac_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->evntType,  &sngss7_event->event.siFacEvnt);
 437                 break;
 438         /**************************************************************************/
 439         case (SNGSS7_FAC_CFM_EVENT):
 440                 handle_fac_cfm(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->evntType,  &sngss7_event->event.siFacEvnt);
 441                 break;
 442         /**************************************************************************/
 443         case (SNGSS7_UMSG_IND_EVENT):
 444                 handle_umsg_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit);
 445                 break;
 446         /**************************************************************************/
 447         case (SNGSS7_STA_IND_EVENT):
 448                 handle_sta_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->globalFlg, sngss7_event->evntType,  &sngss7_event->event.siStaEvnt);
 449                 break;
 450         /**************************************************************************/
 451         case (SNGSS7_SUSP_IND_EVENT):
 452                 handle_susp_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit,  &sngss7_event->event.siSuspEvnt);
 453                 break;
 454         /**************************************************************************/
 455         case (SNGSS7_RESM_IND_EVENT):
 456                 handle_resm_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit,  &sngss7_event->event.siResmEvnt);
 457                 break;
 458         /**************************************************************************/
 459         case (SNGSS7_SSP_STA_CFM_EVENT):
 460                 break;
 461         /**************************************************************************/
 462         default:
 463                 SS7_ERROR("Unknown Event Id!\n");
 464                 break;
 465         /**************************************************************************/
 466         } /* switch (sngss7_event->event_id) */
 467 
 468         /* while there's a state change present on this channel process it */
 469         while (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
 470                 ftdm_sangoma_ss7_process_state_change(ftdmchan);
 471         }
 472 
 473         /* unlock the channel */
 474         ftdm_mutex_unlock(ftdmchan->mutex);
 475 
 476         return;
 477 }
 478 
 479 /******************************************************************************/
 480 void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
 481 {
 482         sngss7_chan_data_t      *sngss7_info = ftdmchan->call_data;
 483         sng_isup_inf_t          *isup_intf = NULL; 
 484         int                             i = 0;
 485         ftdm_sigmsg_t           sigev;
 486 
 487         memset (&sigev, 0, sizeof (sigev));
 488 
 489         sigev.chan_id = ftdmchan->chan_id;
 490         sigev.span_id = ftdmchan->span_id;
 491         sigev.channel = ftdmchan;
 492 
 493         SS7_DEBUG_CHAN(ftdmchan, "ftmod_sangoma_ss7 processing state %s\n", ftdm_channel_state2str (ftdmchan->state));
 494 
 495         /* clear the state change flag...since we might be setting a new state */
 496         ftdm_clear_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE);
 497         
 498         /*check what state we are supposed to be in */
 499         switch (ftdmchan->state) {
 500         /**************************************************************************/
 501         case FTDM_CHANNEL_STATE_COLLECT:        /* IAM received but wating on digits */
 502 
 503                 if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) {
 504                         SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n");
 505                         break;
 506                 }
 507 
 508                 while (ftdmchan->caller_data.dnis.digits[i] != '\0'){
 509                         i++;
 510                 }
 511 
 512                 /* check if the end of pulsing (ST) character has arrived or the right number of digits */
 513                 if (ftdmchan->caller_data.dnis.digits[i-1] == 'F') {
 514                         SS7_DEBUG_CHAN(ftdmchan, "Received the end of pulsing character %s\n", "");
 515 
 516                         /* remove the ST */
 517                         ftdmchan->caller_data.dnis.digits[i-1] = '\0';
 518                         
 519                         /*now go to the RING state */
 520                         ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RING);
 521                         
 522                 } else if (i >= g_ftdm_sngss7_data.min_digits) {
 523                         SS7_DEBUG_CHAN(ftdmchan, "Received %d digits (min digits = %d)\n", i, g_ftdm_sngss7_data.min_digits);
 524 
 525                         /*now go to the RING state */
 526                         ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RING);
 527                         
 528                 } else {
 529                         SS7_INFO_CHAN(ftdmchan,"Received %d out of %d so far: %s...starting T35\n",
 530                                                 i,
 531                                                 g_ftdm_sngss7_data.min_digits,
 532                                                 ftdmchan->caller_data.dnis.digits);
 533 
 534                         /* start ISUP t35 */
 535                         if (ftdm_sched_timer (sngss7_info->t35.sched,
 536                                                                         "t35",
 537                                                                         sngss7_info->t35.beat,
 538                                                                         sngss7_info->t35.callback,
 539                                                                         &sngss7_info->t35,
 540                                                                         &sngss7_info->t35.hb_timer_id)) {
 541 
 542                                 SS7_ERROR ("Unable to schedule timer, hanging up call!\n");
 543 
 544                                 ftdmchan->caller_data.hangup_cause = 41;
 545 
 546                                 /* set the flag to indicate this hangup is started from the local side */
 547                                 sngss7_set_flag (sngss7_info, FLAG_LOCAL_REL);
 548 
 549                                 /* end the call */
 550                                 ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
 551                         } /* if (ftdm_sched_timer(sngss7_info->t35.sched, */
 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->mod_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.sigstatus = 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.sigstatus = 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                         default:
 970                                 /* KONRAD: find out what the cause code should be */
 971                                 ftdmchan->caller_data.hangup_cause = 41;
 972 
 973                                 /* change the state to terminatting, it will throw us back here
 974                                  * once the call is done
 975                                  */
 976                                 ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
 977                         break;
 978                         /******************************************************************/
 979                         } /* switch (ftdmchan->last_state) */
 980                 } else {
 981                         /* check if this an incoming RSC or we have a response already */
 982                         if (sngss7_test_flag (sngss7_info, FLAG_RESET_RX) ||
 983                                 sngss7_test_flag (sngss7_info, FLAG_RESET_TX_RSP) ||
 984                                 sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_TX_RSP) ||
 985                                 sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_RX_CMPLT)) {
 986         
 987                                 SS7_DEBUG_CHAN(ftdmchan, "Reset processed moving to DOWN (0x%X)\n", sngss7_info->flags);
 988         
 989                                 /* go to a down state to clear the channel and send the response */
 990                                 ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_DOWN);
 991                         } else {
 992                                 SS7_DEBUG_CHAN(ftdmchan, "Waiting on Reset Rsp/Grp Reset to move to DOWN (0x%X)\n", sngss7_info->flags);
 993                         }
 994                 }
 995 
 996                 break;
 997         /**************************************************************************/
 998         case FTDM_CHANNEL_STATE_SUSPENDED:      /* circuit has been blocked */
 999 
1000                   SS7_DEBUG_CHAN(ftdmchan,"Current flags: 0x%X\n", sngss7_info->flags);
1001 
1002                 /**********************************************************************/
1003                 if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) {
1004                         SS7_DEBUG_CHAN(ftdmchan, "Processing RESUME%s\n", "");
1005 
1006                         /* clear the RESUME flag */
1007                         sngss7_clear_flag(sngss7_info, FLAG_INFID_RESUME);
1008 
1009                         /* if there are any resets present */
1010                         if ((sngss7_test_flag (sngss7_info, FLAG_RESET_TX)) ||
1011                                 (sngss7_test_flag (sngss7_info, FLAG_RESET_RX)) ||
1012                                 (sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_TX)) ||
1013                                 (sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_RX))) {
1014 
1015                                 /* go back to the reset state */
1016                                 goto suspend_goto_restart;
1017                         } else {
1018 
1019                                 /* bring the sig status back up */
1020                                 sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
1021                                 sigev.sigstatus = FTDM_SIG_STATE_UP;
1022                                 ftdm_span_send_signal(ftdmchan->span, &sigev);
1023                         }
1024 
1025                         /* go back to the last state */
1026                         goto suspend_goto_last;
1027                 } /* if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) */
1028 
1029                 if (sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) {
1030                         SS7_DEBUG_CHAN(ftdmchan, "Processing PAUSE%s\n", "");
1031 
1032                         /* bring the sig status down */
1033                         sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
1034                         sigev.sigstatus = FTDM_SIG_STATE_DOWN;
1035                         ftdm_span_send_signal(ftdmchan->span, &sigev);
1036 
1037                         /* go back to the last state */
1038                         goto suspend_goto_last;
1039                 } /* if (sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) { */
1040                 /**********************************************************************/
1041                 if (sngss7_test_flag (sngss7_info, FLAG_CKT_MN_BLOCK_RX)) {
1042                         SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_BLOCK_RX flag %s\n", "");
1043 
1044                         /* bring the sig status down */
1045                         sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
1046                         sigev.sigstatus = FTDM_SIG_STATE_DOWN;
1047                         ftdm_span_send_signal(ftdmchan->span, &sigev); 
1048 
1049                         /* send a BLA */
1050                         ft_to_sngss7_bla (ftdmchan);
1051 
1052                         /* check the last state and return to it to allow the call to finish */
1053                         goto suspend_goto_last;
1054                 }
1055 
1056                 if (sngss7_test_flag (sngss7_info, FLAG_CKT_MN_UNBLK_RX)){
1057                         SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_UNBLK_RX flag %s\n", "");
1058 
1059                         /* clear the unblock flag */
1060                         sngss7_clear_flag (sngss7_info, FLAG_CKT_MN_UNBLK_RX);
1061 
1062                         /* bring the sig status up */
1063                         sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
1064                         sigev.sigstatus = FTDM_SIG_STATE_UP;
1065                         ftdm_span_send_signal(ftdmchan->span, &sigev); 
1066 
1067                         /* send a uba */
1068                         ft_to_sngss7_uba (ftdmchan);
1069 
1070                         /* check the last state and return to it to allow the call to finish */
1071                         goto suspend_goto_last;
1072                 }
1073 
1074                 /**********************************************************************/
1075                 if (sngss7_test_flag (sngss7_info, FLAG_CKT_MN_BLOCK_TX)) {
1076                         SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_BLOCK_TX flag %s\n", "");
1077 
1078                         /* bring the sig status down */
1079                         sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
1080                         sigev.sigstatus = FTDM_SIG_STATE_DOWN;
1081                         ftdm_span_send_signal(ftdmchan->span, &sigev); 
1082 
1083                         /* send a blo */
1084                         ft_to_sngss7_blo (ftdmchan);
1085 
1086                         /* check the last state and return to it to allow the call to finish */
1087                         goto suspend_goto_last;
1088                 }
1089 
1090                 if (sngss7_test_flag (sngss7_info, FLAG_CKT_MN_UNBLK_TX)){
1091                         SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_UNBLK_TX flag %s\n", "");
1092 
1093                         /* clear the unblock flag */
1094                         sngss7_clear_flag (sngss7_info, FLAG_CKT_MN_UNBLK_TX);
1095 
1096                         /* bring the sig status up */
1097                         sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
1098                         sigev.sigstatus = FTDM_SIG_STATE_UP;
1099                         ftdm_span_send_signal(ftdmchan->span, &sigev); 
1100 
1101                         /* send a ubl */
1102                         ft_to_sngss7_ubl (ftdmchan);
1103 
1104                         /* check the last state and return to it to allow the call to finish */
1105                         goto suspend_goto_last;
1106                 }
1107 
1108                 /**********************************************************************/
1109                 if (sngss7_test_flag (sngss7_info, FLAG_CKT_LC_BLOCK_RX)) {
1110                         SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_LC_BLOCK_RX flag %s\n", "");
1111 
1112                         /* send a BLA */
1113                         /*ft_to_sngss7_bla(ftdmchan);*/
1114 
1115                         /* check the last state and return to it to allow the call to finish */
1116                         goto suspend_goto_last;
1117                 }
1118 
1119                 if (sngss7_test_flag (sngss7_info, FLAG_CKT_LC_UNBLK_RX)) {
1120                         SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_LC_UNBLK_RX flag %s\n", "");
1121                         
1122                         /* clear the unblock flag */
1123                         sngss7_clear_flag (sngss7_info, FLAG_CKT_MN_UNBLK_RX);
1124 
1125                         /* send a uba */
1126                         /*ft_to_sngss7_uba(ftdmchan);*/
1127 
1128                         /* check the last state and return to it to allow the call to finish */
1129                         goto suspend_goto_last;
1130                 }
1131                 /**********************************************************************/
1132                 if (sngss7_test_flag (sngss7_info, FLAG_CKT_UCIC_BLOCK)) {
1133                         SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_UCIC_BLOCK flag %s\n", "");
1134 
1135                         /* bring the channel signaling status to down */
1136                         sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
1137                         sigev.sigstatus = FTDM_SIG_STATE_DOWN;
1138                         ftdm_span_send_signal (ftdmchan->span, &sigev);
1139 
1140                         /* remove any reset flags */
1141                         clear_rx_grs_flags(sngss7_info);
1142                         clear_rx_grs_data(sngss7_info);
1143                         clear_tx_grs_flags(sngss7_info);
1144                         clear_tx_grs_data(sngss7_info);
1145                         clear_rx_rsc_flags(sngss7_info);
1146                         clear_tx_rsc_flags(sngss7_info);
1147                         
1148                         /* bring the channel down */
1149                         goto suspend_goto_last;
1150                 }
1151 
1152                 if (sngss7_test_flag (sngss7_info, FLAG_CKT_UCIC_UNBLK)) {
1153                         SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_UCIC_UNBLK flag %s\n", "");;
1154 
1155                         /* remove the UCIC block flag */
1156                         sngss7_clear_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK);
1157 
1158                         /* remove the UCIC unblock flag */
1159                         sngss7_clear_flag(sngss7_info, FLAG_CKT_UCIC_UNBLK);
1160 
1161                         /* throw the channel into reset to sync states */
1162                         sngss7_set_flag(sngss7_info, FLAG_RESET_TX);
1163 
1164                         /* bring the channel into restart again */
1165                         goto suspend_goto_restart;
1166                 }
1167 
1168 suspend_goto_last:
1169                 ftdm_set_state_locked (ftdmchan, ftdmchan->last_state);
1170                 break;
1171 
1172 suspend_goto_restart:
1173                 ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RESTART);
1174                 break;
1175 
1176         /**************************************************************************/
1177         case FTDM_CHANNEL_STATE_IN_LOOP:        /* COT test */
1178 
1179                 isup_intf = &g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId];
1180 
1181                 if (sngss7_test_options(isup_intf, SNGSS7_LPA_FOR_COT)) {
1182                         /* send the lpa */
1183                         ft_to_sngss7_lpa (ftdmchan);
1184                 } 
1185 
1186                 break;
1187         /**************************************************************************/
1188         case FTDM_CHANNEL_STATE_IDLE:
1189                         ftdm_set_state_locked(ftdmchan, ftdmchan->last_state);
1190                 break;
1191         /**************************************************************************/
1192         default:
1193                 /* we don't handle any of the other states */
1194                 SS7_ERROR_CHAN(ftdmchan, "ftmod_sangoma_ss7 does not support %s state\n",  ftdm_channel_state2str (ftdmchan->state));
1195                 
1196                 break;
1197         /**************************************************************************/
1198         }/*switch (ftdmchan->state) */
1199 
1200         return;
1201 }
1202 
1203 /******************************************************************************/
1204 static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(ftdm_sangoma_ss7_outgoing_call)
1205 {
1206         sngss7_chan_data_t  *sngss7_info = ftdmchan->call_data;
1207 
1208         /* lock the channel while we check whether it is availble */
1209         ftdm_mutex_lock (ftdmchan->mutex);
1210 
1211         /* check if there is a pending state change, give it a bit to clear */
1212         if (check_for_state_change(ftdmchan)) {
1213                 SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic);
1214                 /* check if we need to die */
1215                 SS7_ASSERT;
1216                 /* end the request */
1217                 goto outgoing_fail;
1218         };
1219 
1220         /* check if the channel sig state is UP */
1221         if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
1222                 SS7_ERROR_CHAN(ftdmchan, "Requested channel sig state is down, cancelling call!%s\n", " ");
1223                 goto outgoing_fail;
1224         }
1225 
1226         /* check if there is a remote block */
1227         if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) ||
1228                 (sngss7_test_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX)) ||
1229                 (sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) {
1230 
1231                 /* the channel is blocked...can't send any calls here */
1232                 SS7_ERROR_CHAN(ftdmchan, "Requested channel is remotely blocked, re-hunt channel!%s\n", " ");
1233                 goto outgoing_break;
1234         }
1235 
1236         /* check if there is a local block */
1237         if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) ||
1238                 (sngss7_test_flag(sngss7_info, FLAG_GRP_HW_BLOCK_TX)) ||
1239                 (sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX))) {
1240 
1241                 /* KONRAD FIX ME : we should check if this is a TEST call and allow it */
1242 
1243                 /* the channel is blocked...can't send any calls here */
1244                 SS7_ERROR_CHAN(ftdmchan, "Requested channel is locally blocked, re-hunt channel!%s\n", " ");
1245                 goto outgoing_break;
1246         }
1247 
1248         /* check the state of the channel */
1249         switch (ftdmchan->state){
1250         /**************************************************************************/
1251         case FTDM_CHANNEL_STATE_DOWN:
1252                 /* inform the monitor thread that we want to make a call */
1253                 ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_DIALING);
1254 
1255                 /* unlock the channel */
1256                 ftdm_mutex_unlock (ftdmchan->mutex);
1257                 
1258                 goto outgoing_successful;
1259                 break;
1260         /**************************************************************************/
1261         default:
1262                 /* the channel is already used...this can't be, end the request */
1263                 SS7_ERROR("Outgoing call requested channel in already in use...indicating glare on span=%d,chan=%d\n",
1264                                         ftdmchan->physical_span_id,
1265                                         ftdmchan->physical_chan_id);
1266 
1267                 goto outgoing_break;
1268                 break;
1269         /**************************************************************************/
1270         } /* switch (ftdmchan->state) (original call) */
1271 
1272 outgoing_fail:
1273         SS7_DEBUG_CHAN(ftdmchan, "Call Request failed%s\n", " ");
1274         /* unlock the channel */
1275         ftdm_mutex_unlock (ftdmchan->mutex);
1276         return FTDM_FAIL;
1277 
1278 outgoing_break:
1279         SS7_DEBUG_CHAN(ftdmchan, "Call Request re-hunt%s\n", " ");
1280         /* unlock the channel */
1281         ftdm_mutex_unlock (ftdmchan->mutex);
1282         return FTDM_BREAK;
1283 
1284 outgoing_successful:
1285         SS7_DEBUG_CHAN(ftdmchan, "Call Request successful%s\n", " ");
1286         /* unlock the channel */
1287         ftdm_mutex_unlock (ftdmchan->mutex);
1288         return FTDM_SUCCESS;
1289 }
1290 
1291 /******************************************************************************/
1292 #if 0
1293           static FIO_CHANNEL_REQUEST_FUNCTION (ftdm_sangoma_ss7_request_chan)
1294           {
1295         SS7_INFO ("KONRAD-> I got called %s\n", __FUNCTION__);
1296         return FTDM_SUCCESS;
1297           }
1298 
1299 #endif
1300 
1301 /******************************************************************************/
1302 
1303 /* FT-CORE SIG STATUS FUNCTIONS ********************************************** */
1304 static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(ftdm_sangoma_ss7_get_sig_status)
1305 {
1306         if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_SIG_UP)) {
1307                 *status = FTDM_SIG_STATE_UP;
1308         } else {
1309                 *status = FTDM_SIG_STATE_DOWN;
1310         }
1311 
1312         return FTDM_SUCCESS;
1313 }
1314 
1315 /******************************************************************************/
1316 static FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(ftdm_sangoma_ss7_set_sig_status)
1317 {
1318         SS7_ERROR ("Cannot set channel status in this module\n");
1319         return FTDM_NOTIMPL;
1320 }
1321 
1322 /* FT-CORE SIG FUNCTIONS ******************************************************/
1323 static ftdm_status_t ftdm_sangoma_ss7_start(ftdm_span_t * span)
1324 {
1325         ftdm_channel_t          *ftdmchan = NULL;
1326         sngss7_chan_data_t      *sngss7_info = NULL;
1327         sngss7_span_data_t      *sngss7_span = NULL;
1328         sng_isup_inf_t          *sngss7_intf = NULL;
1329         int                             x;
1330 
1331 
1332         SS7_INFO ("Starting span %s:%u.\n", span->name, span->span_id);
1333 
1334         /* throw the channels in pause */
1335         for (x = 1; x < (span->chan_count + 1); x++) {
1336                 /* extract the channel structure and sngss7 channel data */
1337                 ftdmchan = span->channels[x];
1338                 if (ftdmchan->call_data == NULL) continue;
1339                 sngss7_info = ftdmchan->call_data;
1340                 sngss7_span = ftdmchan->span->mod_data;
1341                 sngss7_intf = &g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId];
1342 
1343 
1344                 /* lock the channel */
1345                 ftdm_mutex_lock(ftdmchan->mutex);
1346 
1347                 /* check if the interface is paused or resumed */
1348                 if (sngss7_test_flag(sngss7_intf, SNGSS7_PAUSED)) {
1349                         /* throw the pause flag */
1350                         sngss7_clear_flag(sngss7_info, FLAG_INFID_RESUME);
1351                         sngss7_set_flag(sngss7_info, FLAG_INFID_PAUSED);
1352                 } else {
1353                         /* throw the pause flag */
1354                         sngss7_clear_flag(sngss7_info, FLAG_INFID_PAUSED);
1355                         sngss7_set_flag(sngss7_info, FLAG_INFID_RESUME);
1356                 }
1357 #if 0
1358                 /* throw the grp reset flag */
1359                 sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX);
1360                 if (x == 1) {
1361                         sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_BASE);
1362                         sngss7_span->tx_grs.circuit = sngss7_info->circuit->id;
1363                         sngss7_span->tx_grs.range = span->chan_count -1;
1364                 }
1365 #else
1366                 /* throw the channel into reset */
1367                 sngss7_set_flag(sngss7_info, FLAG_RESET_TX);
1368 #endif
1369                 /* throw the channel to suspend */
1370                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
1371 
1372                 /* unlock the channel */
1373                 ftdm_mutex_unlock(ftdmchan->mutex);
1374         }
1375 
1376         /* clear the monitor thread stop flag */
1377         ftdm_clear_flag (span, FTDM_SPAN_STOP_THREAD);
1378         ftdm_clear_flag (span, FTDM_SPAN_IN_THREAD);
1379 
1380         /* activate all the configured ss7 links */
1381         if (ft_to_sngss7_activate_all()) {
1382                 SS7_CRITICAL ("Failed to activate LibSngSS7!\n");
1383                 return FTDM_FAIL;
1384         }
1385 
1386         /*start the span monitor thread */
1387         if (ftdm_thread_create_detached (ftdm_sangoma_ss7_run, span) != FTDM_SUCCESS) {
1388                 SS7_CRITICAL ("Failed to start Span Monitor Thread!\n");
1389                 return FTDM_FAIL;
1390         }
1391 
1392         SS7_DEBUG ("Finished starting span %s:%u.\n", span->name, span->span_id);
1393 
1394         return FTDM_SUCCESS;
1395 }
1396 
1397 /******************************************************************************/
1398 static ftdm_status_t ftdm_sangoma_ss7_stop(ftdm_span_t * span)
1399 {
1400         /*this function is called by the FT-Core to stop this span */
1401 
1402         ftdm_log (FTDM_LOG_INFO, "Stopping span %s:%u.\n", span->name,span->span_id);
1403 
1404         /* throw the STOP_THREAD flag to signal monitor thread stop */
1405         ftdm_set_flag (span, FTDM_SPAN_STOP_THREAD);
1406 
1407         /* wait for the thread to stop */
1408         while (ftdm_test_flag (span, FTDM_SPAN_IN_THREAD)) {
1409                 ftdm_log (FTDM_LOG_DEBUG,"Waiting for monitor thread to end for %s:%u.\n",
1410                                                                         span->name,
1411                                                                         span->span_id);
1412                 ftdm_sleep (1);
1413         }
1414 
1415         /* KONRAD FIX ME - deconfigure any circuits, links, attached to this span */
1416 
1417         ftdm_log (FTDM_LOG_DEBUG, "Finished stopping span %s:%u.\n", span->name, span->span_id);
1418 
1419         return FTDM_SUCCESS;
1420 }
1421 
1422 /* SIG_FUNCTIONS ***************************************************************/
1423 static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_ss7_span_config)
1424 {
1425         sngss7_span_data_t      *ss7_span_info;
1426 
1427         ftdm_log (FTDM_LOG_INFO, "Configuring ftmod_sangoma_ss7 span = %s(%d)...\n",
1428                                                                 span->name,
1429                                                                 span->span_id);
1430 
1431         /* initalize the span's data structure */
1432         ss7_span_info = ftdm_calloc (1, sizeof (sngss7_span_data_t));
1433 
1434         /* create a timer schedule */
1435         if (ftdm_sched_create(&ss7_span_info->sched, "SngSS7_Schedule")) {
1436                 SS7_CRITICAL("Unable to create timer schedule!\n");
1437                 return FTDM_FAIL;
1438         }
1439 
1440         /* start the free run thread for the schedule */
1441         if (ftdm_sched_free_run(ss7_span_info->sched)) {
1442                 SS7_CRITICAL("Unable to schedule free run!\n");
1443                 return FTDM_FAIL;
1444         }
1445 
1446         /* create an event queue for this span */
1447         if ((ftdm_queue_create(&(ss7_span_info)->event_queue, SNGSS7_EVENT_QUEUE_SIZE)) != FTDM_SUCCESS) {
1448                 SS7_CRITICAL("Unable to create event queue!\n");
1449                 return FTDM_FAIL;
1450         }
1451 
1452         /*setup the span structure with the info so far */
1453         g_ftdm_sngss7_data.sig_cb               = sig_cb;
1454         span->start                                     = ftdm_sangoma_ss7_start;
1455         span->stop                                              = ftdm_sangoma_ss7_stop;
1456         span->signal_type                               = FTDM_SIGTYPE_SS7;
1457         span->signal_data                               = NULL;
1458         span->outgoing_call                     = ftdm_sangoma_ss7_outgoing_call;
1459         span->channel_request                   = NULL;
1460         span->signal_cb                                 = sig_cb;
1461         span->get_channel_sig_status    = ftdm_sangoma_ss7_get_sig_status;
1462         span->set_channel_sig_status    = ftdm_sangoma_ss7_set_sig_status;
1463         span->state_map                                 = &sangoma_ss7_state_map;
1464         span->mod_data                                  = ss7_span_info;
1465 
1466         /* set the flag to indicate that this span uses channel state change queues */
1467         ftdm_set_flag (span, FTDM_SPAN_USE_CHAN_QUEUE);
1468         /* set the flag to indicate that this span uses sig event queues */
1469         ftdm_set_flag (span, FTDM_SPAN_USE_SIGNALS_QUEUE);
1470 
1471         /* parse the configuration and apply to the global config structure */
1472         if (ftmod_ss7_parse_xml(ftdm_parameters, span)) {
1473                 ftdm_log (FTDM_LOG_CRIT, "Failed to parse configuration!\n");
1474                 return FTDM_FAIL;
1475         }
1476 
1477         /* configure libsngss7 */
1478         if (ft_to_sngss7_cfg_all()) {
1479                 ftdm_log (FTDM_LOG_CRIT, "Failed to configure LibSngSS7!\n");
1480                 return FTDM_FAIL;
1481         }
1482 
1483         ftdm_log (FTDM_LOG_INFO, "Finished configuring ftmod_sangoma_ss7 span = %s(%d)...\n",
1484                                                                 span->name,
1485                                                                 span->span_id);
1486 
1487         return FTDM_SUCCESS;
1488 }
1489 
1490 /******************************************************************************/
1491 static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_ss7_init)
1492 {
1493         /*this function is called by the FT-core to load the signaling module */
1494         uint32_t major = 0;
1495         uint32_t minor = 0;
1496         uint32_t build = 0;
1497 
1498         ftdm_log (FTDM_LOG_INFO, "Loading ftmod_sangoma_ss7...\n");
1499 
1500         /* default the global structure */
1501         memset (&g_ftdm_sngss7_data, 0x0, sizeof (ftdm_sngss7_data_t));
1502 
1503         sngss7_id = 0;
1504 
1505         cmbLinkSetId = 0;
1506 
1507         /* initalize the global gen_config flag */
1508         g_ftdm_sngss7_data.gen_config = 0;
1509 
1510         /* min. number of digitis to wait for */
1511         g_ftdm_sngss7_data.min_digits = 7;
1512 
1513         /* function trace initizalation */
1514         g_ftdm_sngss7_data.function_trace = 1;
1515         g_ftdm_sngss7_data.function_trace_level = 7;
1516 
1517         /* message (IAM, ACM, ANM, etc) trace initizalation */
1518         g_ftdm_sngss7_data.message_trace = 1;
1519         g_ftdm_sngss7_data.message_trace_level = 6;
1520 
1521         /* setup the call backs needed by Sangoma_SS7 library */
1522         sng_event.cc.sng_con_ind = sngss7_con_ind;
1523         sng_event.cc.sng_con_cfm = sngss7_con_cfm;
1524         sng_event.cc.sng_con_sta = sngss7_con_sta;
1525         sng_event.cc.sng_rel_ind = sngss7_rel_ind;
1526         sng_event.cc.sng_rel_cfm = sngss7_rel_cfm;
1527         sng_event.cc.sng_dat_ind = sngss7_dat_ind;
1528         sng_event.cc.sng_fac_ind = sngss7_fac_ind;
1529         sng_event.cc.sng_fac_cfm = sngss7_fac_cfm;
1530         sng_event.cc.sng_sta_ind = sngss7_sta_ind;
1531         sng_event.cc.sng_umsg_ind = sngss7_umsg_ind;
1532         sng_event.cc.sng_susp_ind = sngss7_susp_ind;
1533         sng_event.cc.sng_resm_ind = sngss7_resm_ind;
1534         sng_event.cc.sng_ssp_sta_cfm = sngss7_ssp_sta_cfm;
1535 
1536         sng_event.sm.sng_log = handle_sng_log;
1537         sng_event.sm.sng_mtp1_alarm = handle_sng_mtp1_alarm;
1538         sng_event.sm.sng_mtp2_alarm = handle_sng_mtp2_alarm;
1539         sng_event.sm.sng_mtp3_alarm = handle_sng_mtp3_alarm;
1540         sng_event.sm.sng_isup_alarm = handle_sng_isup_alarm;
1541         sng_event.sm.sng_cc_alarm = handle_sng_cc_alarm;
1542 
1543         /* initalize sng_ss7 library */
1544         sng_isup_init (&sng_event);
1545 
1546         /* print the version of the library being used */
1547         sng_isup_version(&major, &minor, &build);
1548         SS7_INFO("Loaded LibSng-SS7 %d.%d.%d\n", major, minor, build);
1549 
1550         /* crash on assert fail */
1551         ftdm_global_set_crash_policy (FTDM_CRASH_ON_ASSERT);
1552 
1553         return FTDM_SUCCESS;
1554 }
1555 
1556 /******************************************************************************/
1557 static FIO_SIG_UNLOAD_FUNCTION(ftdm_sangoma_ss7_unload)
1558 {
1559         /*this function is called by the FT-core to unload the signaling module */
1560 
1561         ftdm_log (FTDM_LOG_INFO, "Starting ftmod_sangoma_ss7 unload...\n");
1562 
1563         sng_isup_free();
1564 
1565         ftdm_log (FTDM_LOG_INFO, "Finished ftmod_sangoma_ss7 unload!\n");
1566         return FTDM_SUCCESS;
1567 }
1568 
1569 /******************************************************************************/
1570 static FIO_API_FUNCTION(ftdm_sangoma_ss7_api)
1571 {
1572         /* handle this in it's own file....so much to do */
1573         return (ftdm_sngss7_handle_cli_cmd (stream, data));
1574 }
1575 
1576 /******************************************************************************/
1577 static FIO_IO_LOAD_FUNCTION(ftdm_sangoma_ss7_io_init)
1578 {
1579         assert (fio != NULL);
1580         memset (&g_ftdm_sngss7_interface, 0, sizeof (g_ftdm_sngss7_interface));
1581 
1582         g_ftdm_sngss7_interface.name = "ss7";
1583         g_ftdm_sngss7_interface.api = ftdm_sangoma_ss7_api;
1584 
1585         *fio = &g_ftdm_sngss7_interface;
1586 
1587         return FTDM_SUCCESS;
1588 }
1589 
1590 /******************************************************************************/
1591 
1592 
1593 /* START **********************************************************************/
1594 ftdm_module_t ftdm_module = {
1595         "sangoma_ss7",                                  /*char name[256];                                  */
1596         ftdm_sangoma_ss7_io_init,               /*fio_io_load_t                                  */
1597         NULL,                                                   /*fio_io_unload_t                                  */
1598         ftdm_sangoma_ss7_init,                  /*fio_sig_load_t                                        */
1599         NULL,                                                   /*fio_sig_configure_t                      */
1600         ftdm_sangoma_ss7_unload,                /*fio_sig_unload_t                                */
1601         ftdm_sangoma_ss7_span_config    /*fio_configure_span_signaling_t        */
1602 };
1603 /******************************************************************************/
1604 
1605 /******************************************************************************/
1606 /* For Emacs:
1607 * Local Variables:
1608 * mode:c
1609 * indent-tabs-mode:t
1610 * tab-width:4
1611 * c-basic-offset:4
1612 * End:
1613 * For VIM:
1614 * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
1615 */
1616 /******************************************************************************/

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