root/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c

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

DEFINITIONS

This source file includes following definitions.
  1. copy_cgPtyNum_from_sngss7
  2. copy_cgPtyNum_to_sngss7
  3. copy_cdPtyNum_from_sngss7
  4. copy_cdPtyNum_to_sngss7
  5. copy_tknStr_from_sngss7
  6. check_for_state_change
  7. check_cics_in_range
  8. extract_chan_data
  9. check_for_reset
  10. get_unique_id
  11. check_if_rx_grs_started
  12. check_if_rx_grs_processed
  13. check_if_rx_gra_started
  14. check_for_res_sus_flag
  15. clear_rx_grs_flags
  16. clear_tx_grs_flags
  17. clear_rx_rsc_flags
  18. clear_tx_rsc_flags

   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 uint32_t sngss7_id;
  43 /******************************************************************************/
  44 
  45 /* PROTOTYPES *****************************************************************/
  46 uint8_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
  47 uint8_t copy_cgPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum);
  48 uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum);
  49 uint8_t copy_cdPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum);
  50 uint8_t copy_cdPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum);
  51 
  52 int check_for_state_change(ftdm_channel_t *ftdmchan);
  53 int check_cics_in_range(sngss7_chan_data_t *sngss7_info);
  54 int check_for_reset(sngss7_chan_data_t *sngss7_info);
  55 
  56 unsigned long get_unique_id(void);
  57 
  58 ftdm_status_t extract_chan_data(uint32_t circuit, sngss7_chan_data_t **sngss7_info, ftdm_channel_t **ftdmchan);
  59 
  60 ftdm_status_t check_if_rx_grs_started(ftdm_span_t *ftdmspan);
  61 ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan);
  62 ftdm_status_t check_if_rx_gra_started(ftdm_span_t *ftdmspan);
  63 ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan);
  64 
  65 ftdm_status_t clear_rx_grs_flags(sngss7_chan_data_t *sngss7_info);
  66 ftdm_status_t clear_tx_grs_flags(sngss7_chan_data_t *sngss7_info);
  67 ftdm_status_t clear_rx_rsc_flags(sngss7_chan_data_t *sngss7_info);
  68 ftdm_status_t clear_tx_rsc_flags(sngss7_chan_data_t *sngss7_info);
  69 /******************************************************************************/
  70 
  71 /* FUNCTIONS ******************************************************************/
  72 uint8_t copy_cgPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum)
  73 {
  74 
  75         return 0;
  76 }
  77 
  78 /******************************************************************************/
  79 uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum)
  80 {
  81         int k;
  82         int j;
  83         int flag;
  84         int odd;
  85         char tmp[2];
  86         uint8_t lower;
  87         uint8_t upper;
  88 
  89         /**************************************************************************/
  90         cgPtyNum->eh.pres                  = PRSNT_NODEF;
  91         /**************************************************************************/
  92         cgPtyNum->natAddrInd.pres   = PRSNT_NODEF;
  93         cgPtyNum->natAddrInd.val        = 0x03;
  94         /**************************************************************************/
  95         cgPtyNum->scrnInd.pres    = PRSNT_NODEF;
  96         cgPtyNum->scrnInd.val      = ftdm->screen;
  97         /**************************************************************************/
  98         cgPtyNum->presRest.pres  = PRSNT_NODEF;
  99         cgPtyNum->presRest.val    = ftdm->pres;
 100         /**************************************************************************/
 101         cgPtyNum->numPlan.pres    = PRSNT_NODEF;
 102         cgPtyNum->numPlan.val      = 0x01;
 103         /**************************************************************************/
 104         cgPtyNum->niInd.pres            = PRSNT_NODEF;
 105         cgPtyNum->niInd.val              = 0x00;
 106         /**************************************************************************/
 107         cgPtyNum->addrSig.pres    = PRSNT_NODEF;
 108 
 109         /* atoi will search through memory starting from the pointer it is given until
 110          * it finds the \0...since tmp is on the stack it will start going through the
 111          * possibly causing corruption.  Hard code a \0 to prevent this
 112          */
 113         tmp[1] = '\0';
 114         k = 0;
 115         j = 0;
 116         flag = 0;
 117         odd = 0;
 118         upper = 0x0;
 119         lower = 0x0;
 120 
 121         while (1) {
 122                 /* grab a digit from the ftdm digits */
 123                 tmp[0] = ftdm->cid_num.digits[k];
 124 
 125                 /* check if the digit is a number and that is not null */
 126                 while (!(isdigit(tmp[0])) && (tmp[0] != '\0')) {
 127                         /* move on to the next value */
 128                         k++;
 129                         tmp[0] = ftdm->cid_num.digits[k];
 130                 } /* while(!(isdigit(tmp))) */
 131 
 132                 /* check if tmp is null or a digit */
 133                 if (tmp[0] != '\0') {
 134                         /* push it into the lower nibble */
 135                         lower = atoi(&tmp[0]);
 136                         /* move to the next digit */
 137                         k++;
 138                         /* grab a digit from the ftdm digits */
 139                         tmp[0] = ftdm->cid_num.digits[k];
 140 
 141                         /* check if the digit is a number and that is not null */
 142                         while (!(isdigit(tmp[0])) && (tmp[0] != '\0')) {
 143                                 k++;
 144                                 tmp[0] = ftdm->cid_num.digits[k];
 145                         } /* while(!(isdigit(tmp))) */
 146 
 147                         /* check if tmp is null or a digit */
 148                         if (tmp[0] != '\0') {
 149                                 /* push the digit into the upper nibble */
 150                                 upper = (atoi(&tmp[0])) << 4;
 151                         } else {
 152                                 /* there is no upper ... fill in 0 */
 153                                 upper = 0x0;
 154                                 /* throw the odd flag */
 155                                 odd = 1;
 156                                 /* throw the end flag */
 157                                 flag = 1;
 158                         } /* if (tmp != '\0') */
 159                 } else {
 160                         /* keep the odd flag down */
 161                         odd = 0;
 162                         /* throw the flag */
 163                         flag = 1;
 164                 }
 165 
 166                 /* push the digits into the trillium structure */
 167                 cgPtyNum->addrSig.val[j] = upper | lower;
 168 
 169                 /* increment the trillium pointer */
 170                 j++;
 171 
 172                 /* if the flag is up we're through all the digits */
 173                 if (flag) break;
 174 
 175                 /* move to the next digit */
 176                 k++;
 177         } /* while(1) */
 178 
 179         cgPtyNum->addrSig.len = j;
 180 
 181         /**************************************************************************/
 182         cgPtyNum->oddEven.pres    = PRSNT_NODEF;
 183         cgPtyNum->oddEven.val      = odd;
 184         /**************************************************************************/
 185         return 0;
 186 }
 187 
 188 /******************************************************************************/
 189 uint8_t copy_cdPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum)
 190 {
 191 
 192         return 0;
 193 }
 194 
 195 /******************************************************************************/
 196 uint8_t copy_cdPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum)
 197 {
 198         int k;
 199         int j;
 200         int flag;
 201         int odd;
 202         char tmp[2];
 203         uint8_t lower;
 204         uint8_t upper;
 205 
 206         /**************************************************************************/
 207         cdPtyNum->eh.pres                  = PRSNT_NODEF;
 208         /**************************************************************************/
 209         cdPtyNum->natAddrInd.pres   = PRSNT_NODEF;
 210         cdPtyNum->natAddrInd.val        = 0x03;
 211         /**************************************************************************/
 212         cdPtyNum->numPlan.pres    = PRSNT_NODEF;
 213         cdPtyNum->numPlan.val      = 0x01;
 214         /**************************************************************************/
 215         cdPtyNum->innInd.pres      = PRSNT_NODEF;
 216         cdPtyNum->innInd.val            = 0x01;
 217         /**************************************************************************/
 218         cdPtyNum->addrSig.pres    = PRSNT_NODEF;
 219 
 220         /* atoi will search through memory starting from the pointer it is given until
 221          * it finds the \0...since tmp is on the stack it will start going through the
 222          * possibly causing corruption.  Hard code a \0 to prevent this
 223          */ /* dnis */
 224         tmp[1] = '\0';
 225         k = 0;
 226         j = 0;
 227         flag = 0;
 228         odd = 0;
 229         upper = 0x0;
 230         lower = 0x0;
 231 
 232         while (1) {
 233                 /* grab a digit from the ftdm digits */
 234                 tmp[0] = ftdm->dnis.digits[k];
 235 
 236                 /* check if the digit is a number and that is not null */
 237                 while (!(isdigit(tmp[0])) && (tmp[0] != '\0')) {
 238                         /* move on to the next value */
 239                         k++;
 240                         tmp[0] = ftdm->dnis.digits[k];
 241                 } /* while(!(isdigit(tmp))) */
 242 
 243                 /* check if tmp is null or a digit */
 244                 if (tmp[0] != '\0') {
 245                         /* push it into the lower nibble */
 246                         lower = atoi(&tmp[0]);
 247                         /* move to the next digit */
 248                         k++;
 249                         /* grab a digit from the ftdm digits */
 250                         tmp[0] = ftdm->dnis.digits[k];
 251 
 252                         /* check if the digit is a number and that is not null */
 253                         while (!(isdigit(tmp[0])) && (tmp[0] != '\0')) {
 254                                 k++;
 255                                 tmp[0] = ftdm->dnis.digits[k];
 256                         } /* while(!(isdigit(tmp))) */
 257 
 258                         /* check if tmp is null or a digit */
 259                         if (tmp[0] != '\0') {
 260                                 /* push the digit into the upper nibble */
 261                                 upper = (atoi(&tmp[0])) << 4;
 262                         } else {
 263                                 /* there is no upper ... fill in ST */
 264                                 upper = 0xF;
 265                                 /* throw the odd flag */
 266                                 odd = 1;
 267                                 /* throw the end flag */
 268                                 flag = 1;
 269                         } /* if (tmp != '\0') */
 270                 } else {
 271                         /* keep the odd flag down */
 272                         odd = 1;
 273                         /* need to add the ST */
 274                         lower = 0xF;
 275                         upper = 0x0;
 276                         /* throw the flag */
 277                         flag = 1;
 278                 }
 279 
 280                 /* push the digits into the trillium structure */
 281                 cdPtyNum->addrSig.val[j] = upper | lower;
 282 
 283                 /* increment the trillium pointer */
 284                 j++;
 285 
 286                 /* if the flag is up we're through all the digits */
 287                 if (flag) break;
 288 
 289                 /* move to the next digit */
 290                 k++;
 291         } /* while(1) */
 292 
 293         cdPtyNum->addrSig.len = j;
 294 
 295         /**************************************************************************/
 296         cdPtyNum->oddEven.pres    = PRSNT_NODEF;
 297 
 298         cdPtyNum->oddEven.val      = odd;
 299 
 300         /**************************************************************************/
 301         return 0;
 302 }
 303 
 304 /******************************************************************************/
 305 uint8_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven)
 306 {
 307         uint8_t i;
 308         uint8_t j;
 309 
 310         /* check if the token string is present */
 311 
 312         if (str.pres == 1) {
 313                 j = 0;
 314 
 315                 for (i = 0; i < str.len; i++) {
 316                         sprintf(&ftdm[j], "%X", (str.val[i] & 0x0F));
 317                         j++;
 318                         sprintf(&ftdm[j], "%X", ((str.val[i] & 0xF0) >> 4));
 319                         j++;
 320                 }
 321 
 322                 /* if the odd flag is up the last digit is a fake "0" */
 323                 if ((oddEven.pres == 1) && (oddEven.val == 1)) {
 324                         ftdm[j-1] = '\0';
 325                 } else {
 326                         ftdm[j] = '\0';
 327                 }
 328 
 329                 
 330         } else {
 331                 SS7_ERROR("Asked to copy tknStr that is not present!\n");
 332                 return 1;
 333         }
 334 
 335         return 0;
 336 }
 337 
 338 /******************************************************************************/
 339 int check_for_state_change(ftdm_channel_t *ftdmchan)
 340 {
 341 
 342         /* check to see if there are any pending state changes on the channel and give them a sec to happen*/
 343         ftdm_wait_for_flag_cleared(ftdmchan, FTDM_CHANNEL_STATE_CHANGE, 500);
 344 
 345         /* check the flag to confirm it is clear now */
 346 
 347         if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
 348                 /* the flag is still up...so we have a problem */
 349                 SS7_DEBUG_CHAN(ftdmchan, "FTDM_CHANNEL_STATE_CHANGE flag set for over 500ms, channel state = %s\n",
 350                                                                         ftdm_channel_state2str (ftdmchan->state));
 351 
 352                 return 1;
 353         }
 354 
 355         return 0;
 356 }
 357 
 358 /******************************************************************************/
 359 int check_cics_in_range(sngss7_chan_data_t *sngss7_info)
 360 {
 361 
 362 
 363 #if 0
 364         ftdm_channel_t          *tmp_ftdmchan;
 365         sngss7_chan_data_t  *tmp_sngss7_info;
 366         int                             i = 0;
 367         
 368         /* check all the circuits in the range to see if we are the last ckt to reset */
 369         for ( i = sngss7_info->grs.circuit; i < ( sngss7_info->grs.range + 1 ); i++ ) {
 370                 if ( g_ftdm_sngss7_data.cfg.isupCircuit[i].siglink == 0 ) {
 371                 
 372                         /* get the ftdmchan and ss7_chan_data from the circuit */
 373                         if (extract_chan_data(g_ftdm_sngss7_data.cfg.isupCircuit[i].id, &tmp_sngss7_info, &tmp_ftdmchan)) {
 374                                 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", g_ftdm_sngss7_data.cfg.isupCircuit[i].id);
 375                                 return 0;
 376                         }
 377 
 378                         /* check if the channel still has the reset flag done is up */
 379                         if (!sngss7_test_flag(tmp_sngss7_info, FLAG_GRP_RESET_RX_DN)) {
 380                                 SS7_DEBUG_CHAN(tmp_ftdmchan, "[CIC:%d] Still processing reset...\n", tmp_sngss7_info->circuit->cic);
 381                                 return 0;
 382                         }
 383                 } /* if not siglink */
 384         } /* for */
 385 
 386         SS7_DEBUG("All circuits out of reset: circuit=%d, range=%d\n",
 387                                 sngss7_info->grs.circuit,
 388                                 sngss7_info->grs.range);
 389         return 1;
 390 
 391 #endif
 392 
 393         return 0;
 394 
 395 }
 396 
 397 /******************************************************************************/
 398 ftdm_status_t extract_chan_data(uint32_t circuit, sngss7_chan_data_t **sngss7_info, ftdm_channel_t **ftdmchan)
 399 {
 400         /*SS7_FUNC_TRACE_ENTER(__FUNCTION__);*/
 401 
 402         if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].obj == NULL) {
 403                 SS7_ERROR("sngss7_info is Null for circuit #%d\n", circuit);
 404                 return FTDM_FAIL;
 405         }
 406 
 407         ftdm_assert_return(g_ftdm_sngss7_data.cfg.isupCkt[circuit].obj, FTDM_FAIL, "received message on signalling link or non-configured cic\n");
 408 
 409         *sngss7_info = g_ftdm_sngss7_data.cfg.isupCkt[circuit].obj;
 410 
 411         ftdm_assert_return((*sngss7_info)->ftdmchan, FTDM_FAIL, "received message on signalling link or non-configured cic\n");
 412         *ftdmchan = (*sngss7_info)->ftdmchan;
 413 
 414         /*SS7_FUNC_TRACE_EXIT(__FUNCTION__);*/
 415         return FTDM_SUCCESS;
 416 }
 417 
 418 /******************************************************************************/
 419 int check_for_reset(sngss7_chan_data_t *sngss7_info)
 420 {
 421 
 422         if (sngss7_test_flag(sngss7_info,FLAG_RESET_RX)) {
 423                 return 1;
 424         }
 425         
 426         if (sngss7_test_flag(sngss7_info,FLAG_RESET_TX)) {
 427                 return 1;
 428         }
 429         
 430         if (sngss7_test_flag(sngss7_info,FLAG_GRP_RESET_RX)) {
 431                 return 1;
 432         }
 433         
 434         if (sngss7_test_flag(sngss7_info,FLAG_GRP_RESET_TX)) {
 435                 return 1;
 436         }
 437 
 438         return 0;
 439         
 440 }
 441 
 442 /******************************************************************************/
 443 unsigned long get_unique_id(void)
 444 {
 445 
 446         if (sngss7_id < 420000000) {
 447                 sngss7_id++;
 448         } else {
 449                 sngss7_id = 1;
 450         }
 451 
 452         return(sngss7_id);
 453 }
 454 
 455 /******************************************************************************/
 456 ftdm_status_t check_if_rx_grs_started(ftdm_span_t *ftdmspan)
 457 {
 458         ftdm_channel_t          *ftdmchan = NULL;
 459         sngss7_chan_data_t  *sngss7_info = NULL;
 460         sngss7_span_data_t      *sngss7_span = (sngss7_span_data_t *)ftdmspan->mod_data;
 461         int                             i;
 462 
 463         for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
 464 
 465                 /* extract the channel in question */
 466                 if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
 467                         SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i);
 468                         continue;
 469                 }
 470 
 471                 /* check if the GRP_RESET_RX flag is already up */
 472                 if (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX)) {
 473                         /* we have already processed this channel...move along */
 474                         continue;
 475                 }
 476 
 477                 /* lock the channel */
 478                 ftdm_mutex_lock(ftdmchan->mutex);
 479 
 480                 /* clear up any pending state changes */
 481                 while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
 482                         ftdm_sangoma_ss7_process_state_change (ftdmchan);
 483                 }
 484 
 485                 SS7_INFO_CHAN(ftdmchan, "Rx GRS (%d:%d)\n", 
 486                                 g_ftdm_sngss7_data.cfg.isupCkt[sngss7_span->rx_grs.circuit].cic, 
 487                                 (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_span->rx_grs.circuit].cic + sngss7_span->rx_grs.range));
 488 
 489                 /* flag the channel as having received a reset */
 490                 sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX);
 491 
 492                 switch (ftdmchan->state) {
 493                 /**************************************************************************/
 494                 case FTDM_CHANNEL_STATE_RESTART:
 495 
 496                         /* go to idle so that we can redo the restart state*/
 497                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE);
 498 
 499                         break;
 500                 /**************************************************************************/
 501                 default:
 502 
 503                         /* set the state of the channel to restart...the rest is done by the chan monitor */
 504                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
 505                         break;
 506                 /**************************************************************************/
 507                 } /* switch (ftdmchan->state) */
 508 
 509                 /* unlock the channel again before we exit */
 510                 ftdm_mutex_unlock(ftdmchan->mutex);
 511 
 512         } /* for (chans in GRS */
 513 
 514         return FTDM_SUCCESS;
 515 }
 516 
 517 /******************************************************************************/
 518 ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan)
 519 {
 520         ftdm_channel_t          *ftdmchan = NULL;
 521         sngss7_chan_data_t  *sngss7_info = NULL;
 522         sngss7_span_data_t      *sngss7_span = (sngss7_span_data_t *)ftdmspan->mod_data;
 523         int                             i;
 524         int                                     byte = 0;
 525         int                                     bit = 0;
 526 
 527 
 528         ftdm_log(FTDM_LOG_DEBUG, "Found Rx GRS on span %d...checking circuits\n", ftdmspan->span_id);
 529 
 530         /* check all the circuits in the range to see if they are done resetting */
 531         for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
 532 
 533                 /* extract the channel in question */
 534                 if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
 535                         SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i);
 536                         continue;
 537                 }
 538 
 539                 /* lock the channel */
 540                 ftdm_mutex_lock(ftdmchan->mutex);
 541 
 542                 /* check if there is a state change pending on the channel */
 543                 if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
 544                         /* check the state to the GRP_RESET_RX_DN flag */
 545                         if (!sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) {
 546                                 /* this channel is still resetting...do nothing */
 547                                         goto GRS_UNLOCK_ALL;
 548                         } /* if (!sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) */
 549                 } else {
 550                         /* state change pending */
 551                         goto GRS_UNLOCK_ALL;
 552                 }
 553         } /* for ( i = circuit; i < (circuit + range + 1); i++) */
 554 
 555         SS7_DEBUG("All circuits out of reset for GRS: circuit=%d, range=%d\n",
 556                                         sngss7_span->rx_grs.circuit,
 557                                         sngss7_span->rx_grs.range);
 558 
 559         /* check all the circuits in the range to see if they are done resetting */
 560         for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
 561 
 562                 /* extract the channel in question */
 563                 if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
 564                         SS7_ERROR("Failed to extract channel data for circuit = %d!\n",i);
 565                         /* check if we need to die */
 566                         SS7_ASSERT;
 567                         /* move along */
 568                         continue;
 569                 }
 570 
 571                 /* throw the GRP reset flag complete flag */
 572                 sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT);
 573 
 574                 /* move the channel to the down state */
 575                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
 576 
 577                 /* update the status map if the ckt is in blocked state */
 578                 if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) ||
 579                         (sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) ||
 580                         (sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX)) ||
 581                         (sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) {
 582                 
 583                         sngss7_span->rx_grs.status[byte] = (sngss7_span->rx_grs.status[byte] | (1 << bit));
 584                 } /* if blocked */
 585                 
 586                 /* update the bit and byte counter*/
 587                 bit ++;
 588                 if (bit == 8) {
 589                         byte++;
 590                         bit = 0;
 591                 }
 592         } /* for ( i = circuit; i < (circuit + range + 1); i++) */
 593 
 594 GRS_UNLOCK_ALL:
 595         for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
 596                 /* extract the channel in question */
 597                 if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
 598                         SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i);
 599                         continue;
 600                 }
 601 
 602                 /* unlock the channel */
 603                 ftdm_mutex_unlock(ftdmchan->mutex);
 604         }
 605 
 606         return FTDM_SUCCESS;
 607 }
 608 
 609 /******************************************************************************/
 610 ftdm_status_t check_if_rx_gra_started(ftdm_span_t *ftdmspan)
 611 {
 612         ftdm_channel_t          *ftdmchan = NULL;
 613         sngss7_chan_data_t  *sngss7_info = NULL;
 614         sngss7_span_data_t      *sngss7_span = (sngss7_span_data_t *)ftdmspan->mod_data;
 615         int                             i;
 616 
 617         for ( i = sngss7_span->rx_gra.circuit; i < (sngss7_span->rx_gra.circuit + sngss7_span->rx_gra.range + 1); i++) {
 618 
 619                 /* extract the channel in question */
 620                 if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
 621                         SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i);
 622                         continue;
 623                 }
 624 
 625                 /* check if the channel is already procoessing the GRA */
 626                 if (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) {
 627                         /* move along */
 628                         continue;
 629                 }
 630 
 631                 /* lock the channel */
 632                 ftdm_mutex_lock(ftdmchan->mutex);
 633 
 634                 /* clear up any pending state changes */
 635                 while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
 636                         ftdm_sangoma_ss7_process_state_change (ftdmchan);
 637                 }
 638 
 639                 SS7_INFO_CHAN(ftdmchan, "Rx GRA (%d:%d)\n", 
 640                                 g_ftdm_sngss7_data.cfg.isupCkt[sngss7_span->rx_gra.circuit].cic, 
 641                                 (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_span->rx_gra.circuit].cic + sngss7_span->rx_gra.range));
 642 
 643                 switch (ftdmchan->state) {
 644                 /**********************************************************************/
 645                 case FTDM_CHANNEL_STATE_RESTART:
 646                         
 647                         /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */
 648                         sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP);
 649 
 650                         /* go to DOWN */
 651                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
 652 
 653                         break;
 654                 /**********************************************************************/
 655                 case FTDM_CHANNEL_STATE_DOWN:
 656 
 657                         /* do nothing, just drop the message */
 658                         SS7_DEBUG("Receveived GRA in down state, dropping\n");
 659 
 660                         break;
 661                 /**********************************************************************/
 662                 case FTDM_CHANNEL_STATE_TERMINATING:
 663                 case FTDM_CHANNEL_STATE_HANGUP:
 664                 case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
 665                         
 666                         /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */
 667                         sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP);
 668 
 669                         break;
 670                 /**********************************************************************/
 671                 default:
 672                         /* ITU Q764-2.9.5.1.c -> release the circuit */
 673                         if (sngss7_span->rx_gra.cause != 0) {
 674                                 ftdmchan->caller_data.hangup_cause = sngss7_span->rx_gra.cause;
 675                         } else {
 676                                 ftdmchan->caller_data.hangup_cause = 98;        /* Message not compatiable with call state */
 677                         }
 678 
 679                         /* go to terminating to hang up the call */
 680                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
 681                         break;
 682                 /**********************************************************************/
 683                 }
 684 
 685                 /* unlock the channel again before we exit */
 686                 ftdm_mutex_unlock(ftdmchan->mutex);
 687 
 688         } /* for ( circuits in request */
 689 
 690 
 691         return FTDM_SUCCESS;
 692 }
 693 
 694 /******************************************************************************/
 695 ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan)
 696 {
 697         ftdm_channel_t          *ftdmchan = NULL;
 698         sngss7_chan_data_t      *sngss7_info = NULL;
 699         ftdm_sigmsg_t           sigev;
 700         int                             x;
 701 
 702         for (x = 1; x < (ftdmspan->chan_count + 1); x++) {
 703 
 704                 /* extract the channel structure and sngss7 channel data */
 705                 ftdmchan = ftdmspan->channels[x];
 706                 
 707                 /* if the call data is NULL move on */
 708                 if (ftdmchan->call_data == NULL) continue;
 709 
 710                 sngss7_info = ftdmchan->call_data;
 711 
 712                 /* lock the channel */
 713                 ftdm_mutex_lock(ftdmchan->mutex);
 714 
 715                 memset (&sigev, 0, sizeof (sigev));
 716 
 717                 sigev.chan_id = ftdmchan->chan_id;
 718                 sigev.span_id = ftdmchan->span_id;
 719                 sigev.channel = ftdmchan;
 720 
 721                 /* if we have the PAUSED flag and the sig status is still UP */
 722                 if ((sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) &&
 723                         (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP))) {
 724 
 725                         /* clear up any pending state changes */
 726                         while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
 727                                 ftdm_sangoma_ss7_process_state_change (ftdmchan);
 728                         }
 729                         
 730                         /* throw the channel into SUSPENDED to process the flag */
 731                         /* after doing this once the sig status will be down */
 732                         ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
 733                 }
 734 
 735                 /* if the RESUME flag is up go to SUSPENDED to process the flag */
 736                 /* after doing this the flag will be cleared */
 737                 if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) {
 738 
 739                         /* clear up any pending state changes */
 740                         while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
 741                                 ftdm_sangoma_ss7_process_state_change (ftdmchan);
 742                         }
 743 
 744                         /* got SUSPENDED state to clear the flag */
 745                         ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
 746                 }
 747 
 748                 /* unlock the channel */
 749                 ftdm_mutex_unlock(ftdmchan->mutex);
 750 
 751         } /* for (x = 1; x < (span->chan_count + 1); x++) */
 752 
 753         /* signal the core that sig events are queued for processing */
 754         ftdm_span_trigger_signals(ftdmspan);
 755 
 756         return FTDM_SUCCESS;
 757 }
 758 
 759 /******************************************************************************/
 760 ftdm_status_t clear_rx_grs_flags(sngss7_chan_data_t *sngss7_info)
 761 {
 762         /* clear all the flags related to an incoming GRS */
 763         sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_RX);
 764         sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_RX_DN);
 765         sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT);
 766 
 767         return FTDM_SUCCESS;
 768 }
 769 
 770 /******************************************************************************/
 771 ftdm_status_t clear_tx_grs_flags(sngss7_chan_data_t *sngss7_info)
 772 {
 773         /* clear all the flags related to an outgoing GRS */
 774         sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_BASE);
 775         sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_TX);
 776         sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_SENT);
 777         sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP);
 778 
 779         return FTDM_SUCCESS;
 780 }
 781 
 782 /******************************************************************************/
 783 ftdm_status_t clear_rx_rsc_flags(sngss7_chan_data_t *sngss7_info)
 784 {
 785         /* clear all the flags related to an incoming RSC */
 786         sngss7_clear_flag(sngss7_info, FLAG_RESET_RX);
 787 
 788         return FTDM_SUCCESS;
 789 }
 790 
 791 /******************************************************************************/
 792 ftdm_status_t clear_tx_rsc_flags(sngss7_chan_data_t *sngss7_info)
 793 {
 794         /* clear all the flags related to an outgoing RSC */
 795         sngss7_clear_flag(sngss7_info, FLAG_RESET_TX);
 796         sngss7_clear_flag(sngss7_info, FLAG_RESET_SENT);
 797         sngss7_clear_flag(sngss7_info, FLAG_RESET_TX_RSP);
 798 
 799         return FTDM_SUCCESS;
 800 }
 801 
 802 /******************************************************************************/
 803 
 804 /******************************************************************************/
 805 /* For Emacs:
 806  * Local Variables:
 807  * mode:c
 808  * indent-tabs-mode:t
 809  * tab-width:4
 810  * c-basic-offset:4
 811  * End:
 812  * For VIM:
 813  * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
 814  */
 815 /******************************************************************************/

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