This source file includes following definitions.
- copy_cgPtyNum_from_sngss7
- copy_cgPtyNum_to_sngss7
- copy_cdPtyNum_from_sngss7
- copy_cdPtyNum_to_sngss7
- copy_tknStr_from_sngss7
- append_tknStr_from_sngss7
- check_for_state_change
- check_cics_in_range
- extract_chan_data
- check_for_reset
- get_unique_id
- check_if_rx_grs_started
- check_if_rx_grs_processed
- check_if_rx_gra_started
- check_for_res_sus_flag
- process_span_ucic
- clear_rx_grs_flags
- clear_rx_grs_data
- clear_rx_gra_data
- clear_tx_grs_flags
- clear_tx_grs_data
- clear_rx_rsc_flags
- clear_tx_rsc_flags
- encode_subAddrIE_nsap
- encode_subAddrIE_nat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 #include "ftmod_sangoma_ss7_main.h"
36
37
38
39
40
41
42 uint32_t sngss7_id;
43
44
45
46 uint8_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
47 uint8_t append_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
48 uint8_t copy_cgPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum);
49 uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum);
50 uint8_t copy_cdPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum);
51 uint8_t copy_cdPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum);
52
53 int check_for_state_change(ftdm_channel_t *ftdmchan);
54 int check_cics_in_range(sngss7_chan_data_t *sngss7_info);
55 int check_for_reset(sngss7_chan_data_t *sngss7_info);
56
57 unsigned long get_unique_id(void);
58
59 ftdm_status_t extract_chan_data(uint32_t circuit, sngss7_chan_data_t **sngss7_info, ftdm_channel_t **ftdmchan);
60
61 ftdm_status_t check_if_rx_grs_started(ftdm_span_t *ftdmspan);
62 ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan);
63 ftdm_status_t check_if_rx_gra_started(ftdm_span_t *ftdmspan);
64 ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan);
65
66 ftdm_status_t process_span_ucic(ftdm_span_t *ftdmspan);
67
68 ftdm_status_t clear_rx_grs_flags(sngss7_chan_data_t *sngss7_info);
69 ftdm_status_t clear_tx_grs_flags(sngss7_chan_data_t *sngss7_info);
70 ftdm_status_t clear_rx_rsc_flags(sngss7_chan_data_t *sngss7_info);
71 ftdm_status_t clear_tx_rsc_flags(sngss7_chan_data_t *sngss7_info);
72 ftdm_status_t clear_rx_grs_data(sngss7_chan_data_t *sngss7_info);
73 ftdm_status_t clear_rx_gra_data(sngss7_chan_data_t *sngss7_info);
74 ftdm_status_t clear_tx_grs_data(sngss7_chan_data_t *sngss7_info);
75
76 ftdm_status_t encode_subAddrIE_nsap(const char *subAddr, char *subAddrIE, int type);
77 ftdm_status_t encode_subAddrIE_nat(const char *subAddr, char *subAddrIE, int type);
78
79
80
81 uint8_t copy_cgPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum)
82 {
83
84 return 0;
85 }
86
87
88 uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum)
89 {
90 int k;
91 int j;
92 int flag;
93 int odd;
94 char tmp[2];
95 uint8_t lower;
96 uint8_t upper;
97
98
99 cgPtyNum->eh.pres = PRSNT_NODEF;
100
101 cgPtyNum->natAddrInd.pres = PRSNT_NODEF;
102 cgPtyNum->natAddrInd.val = 0x03;
103
104 cgPtyNum->scrnInd.pres = PRSNT_NODEF;
105 cgPtyNum->scrnInd.val = ftdm->screen;
106
107 cgPtyNum->presRest.pres = PRSNT_NODEF;
108 cgPtyNum->presRest.val = ftdm->pres;
109
110 cgPtyNum->numPlan.pres = PRSNT_NODEF;
111 cgPtyNum->numPlan.val = 0x01;
112
113 cgPtyNum->niInd.pres = PRSNT_NODEF;
114 cgPtyNum->niInd.val = 0x00;
115
116 cgPtyNum->addrSig.pres = PRSNT_NODEF;
117
118
119
120
121
122 tmp[1] = '\0';
123 k = 0;
124 j = 0;
125 flag = 0;
126 odd = 0;
127 upper = 0x0;
128 lower = 0x0;
129
130 while (1) {
131
132 tmp[0] = ftdm->cid_num.digits[k];
133
134
135 while (!(isxdigit(tmp[0])) && (tmp[0] != '\0')) {
136 SS7_INFO("Dropping invalid digit: %c\n", tmp[0]);
137
138 k++;
139 tmp[0] = ftdm->cid_num.digits[k];
140 }
141
142
143 if (tmp[0] != '\0') {
144
145 lower = strtol(&tmp[0], (char **)NULL, 16);
146
147 k++;
148
149 tmp[0] = ftdm->cid_num.digits[k];
150
151
152 while (!(isxdigit(tmp[0])) && (tmp[0] != '\0')) {
153 SS7_INFO("Dropping invalid digit: %c\n", tmp[0]);
154 k++;
155 tmp[0] = ftdm->cid_num.digits[k];
156 }
157
158
159 if (tmp[0] != '\0') {
160
161 upper = (strtol(&tmp[0], (char **)NULL, 16)) << 4;
162 } else {
163
164 upper = 0x0;
165
166 odd = 1;
167
168 flag = 1;
169 }
170 } else {
171
172 odd = 0;
173
174 break;
175 }
176
177
178 cgPtyNum->addrSig.val[j] = upper | lower;
179
180
181 j++;
182
183
184 if (flag) break;
185
186
187 k++;
188 }
189
190 cgPtyNum->addrSig.len = j;
191
192
193 cgPtyNum->oddEven.pres = PRSNT_NODEF;
194 cgPtyNum->oddEven.val = odd;
195
196 return 0;
197 }
198
199
200 uint8_t copy_cdPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum)
201 {
202
203 return 0;
204 }
205
206
207 uint8_t copy_cdPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum)
208 {
209 int k;
210 int j;
211 int flag;
212 int odd;
213 char tmp[2];
214 uint8_t lower;
215 uint8_t upper;
216
217
218 cdPtyNum->eh.pres = PRSNT_NODEF;
219
220 cdPtyNum->natAddrInd.pres = PRSNT_NODEF;
221 cdPtyNum->natAddrInd.val = 0x03;
222
223 cdPtyNum->numPlan.pres = PRSNT_NODEF;
224 cdPtyNum->numPlan.val = 0x01;
225
226 cdPtyNum->innInd.pres = PRSNT_NODEF;
227 cdPtyNum->innInd.val = 0x01;
228
229 cdPtyNum->addrSig.pres = PRSNT_NODEF;
230
231
232
233
234
235 tmp[1] = '\0';
236 k = 0;
237 j = 0;
238 flag = 0;
239 odd = 0;
240 upper = 0x0;
241 lower = 0x0;
242
243 while (1) {
244
245 tmp[0] = ftdm->dnis.digits[k];
246
247
248 while (!(isxdigit(tmp[0])) && (tmp[0] != '\0')) {
249 SS7_INFO("Dropping invalid digit: %c\n", tmp[0]);
250
251 k++;
252 tmp[0] = ftdm->dnis.digits[k];
253 }
254
255
256 if (tmp[0] != '\0') {
257
258 lower = strtol(&tmp[0], (char **)NULL, 16);
259
260 k++;
261
262 tmp[0] = ftdm->dnis.digits[k];
263
264
265 while (!(isxdigit(tmp[0])) && (tmp[0] != '\0')) {
266 SS7_INFO("Dropping invalid digit: %c\n", tmp[0]);
267 k++;
268 tmp[0] = ftdm->dnis.digits[k];
269 }
270
271
272 if (tmp[0] != '\0') {
273
274 upper = (strtol(&tmp[0], (char **)NULL, 16)) << 4;
275 } else {
276
277 upper = 0xF0;
278
279 odd = 0;
280
281 flag = 1;
282 }
283 } else {
284
285 odd = 1;
286
287 lower = 0xF;
288 upper = 0x0;
289
290 flag = 1;
291 }
292
293
294 cdPtyNum->addrSig.val[j] = upper | lower;
295
296
297 j++;
298
299
300 if (flag) break;
301
302
303 k++;
304 }
305
306 cdPtyNum->addrSig.len = j;
307
308
309 cdPtyNum->oddEven.pres = PRSNT_NODEF;
310
311 cdPtyNum->oddEven.val = odd;
312
313
314 return 0;
315 }
316
317
318 uint8_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven)
319 {
320 uint8_t i;
321 uint8_t j;
322
323
324
325 if (str.pres == 1) {
326 j = 0;
327
328 for (i = 0; i < str.len; i++) {
329 sprintf(&ftdm[j], "%X", (str.val[i] & 0x0F));
330 j++;
331 sprintf(&ftdm[j], "%X", ((str.val[i] & 0xF0) >> 4));
332 j++;
333 }
334
335
336 if ((oddEven.pres == 1) && (oddEven.val == 1)) {
337 ftdm[j-1] = '\0';
338 } else {
339 ftdm[j] = '\0';
340 }
341
342
343 } else {
344 SS7_ERROR("Asked to copy tknStr that is not present!\n");
345 return 1;
346 }
347
348 return 0;
349 }
350
351
352 uint8_t append_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven)
353 {
354 int i = 0;
355 int j = 0;
356
357
358 if (str.pres == 1) {
359
360 j = strlen(ftdm);
361
362
363 if ( j > 25 ) {
364 SS7_ERROR("string length exceeds maxium value...aborting append!\n");
365 return 1;
366 }
367
368
369 for (i = 0; i < str.len; i++) {
370
371 sprintf(&ftdm[j], "%X", (str.val[i] & 0x0F));
372
373 j++;
374
375 sprintf(&ftdm[j], "%X", ((str.val[i] & 0xF0) >> 4));
376
377 j++;
378 }
379
380
381 if ((oddEven.pres == 1) && (oddEven.val == 1)) {
382 ftdm[j-1] = '\0';
383 } else {
384 ftdm[j] = '\0';
385 }
386 } else {
387 SS7_ERROR("Asked to copy tknStr that is not present!\n");
388 return 1;
389 }
390
391 return 0;
392 }
393
394
395 int check_for_state_change(ftdm_channel_t *ftdmchan)
396 {
397
398
399 ftdm_wait_for_flag_cleared(ftdmchan, FTDM_CHANNEL_STATE_CHANGE, 500);
400
401
402
403 if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
404
405 SS7_DEBUG_CHAN(ftdmchan, "FTDM_CHANNEL_STATE_CHANGE flag set for over 500ms, channel state = %s\n",
406 ftdm_channel_state2str (ftdmchan->state));
407
408 return 1;
409 }
410
411 return 0;
412 }
413
414
415 int check_cics_in_range(sngss7_chan_data_t *sngss7_info)
416 {
417
418
419 #if 0
420 ftdm_channel_t *tmp_ftdmchan;
421 sngss7_chan_data_t *tmp_sngss7_info;
422 int i = 0;
423
424
425 for ( i = sngss7_info->grs.circuit; i < ( sngss7_info->grs.range + 1 ); i++ ) {
426 if ( g_ftdm_sngss7_data.cfg.isupCircuit[i].siglink == 0 ) {
427
428
429 if (extract_chan_data(g_ftdm_sngss7_data.cfg.isupCircuit[i].id, &tmp_sngss7_info, &tmp_ftdmchan)) {
430 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", g_ftdm_sngss7_data.cfg.isupCircuit[i].id);
431 return 0;
432 }
433
434
435 if (!sngss7_test_flag(tmp_sngss7_info, FLAG_GRP_RESET_RX_DN)) {
436 SS7_DEBUG_CHAN(tmp_ftdmchan, "[CIC:%d] Still processing reset...\n", tmp_sngss7_info->circuit->cic);
437 return 0;
438 }
439 }
440 }
441
442 SS7_DEBUG("All circuits out of reset: circuit=%d, range=%d\n",
443 sngss7_info->grs.circuit,
444 sngss7_info->grs.range);
445 return 1;
446
447 #endif
448
449 return 0;
450
451 }
452
453
454 ftdm_status_t extract_chan_data(uint32_t circuit, sngss7_chan_data_t **sngss7_info, ftdm_channel_t **ftdmchan)
455 {
456
457
458 if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].obj == NULL) {
459 SS7_ERROR("sngss7_info is Null for circuit #%d\n", circuit);
460 return FTDM_FAIL;
461 }
462
463 ftdm_assert_return(g_ftdm_sngss7_data.cfg.isupCkt[circuit].obj, FTDM_FAIL, "received message on signalling link or non-configured cic\n");
464
465 *sngss7_info = g_ftdm_sngss7_data.cfg.isupCkt[circuit].obj;
466
467 ftdm_assert_return((*sngss7_info)->ftdmchan, FTDM_FAIL, "received message on signalling link or non-configured cic\n");
468 *ftdmchan = (*sngss7_info)->ftdmchan;
469
470
471 return FTDM_SUCCESS;
472 }
473
474
475 int check_for_reset(sngss7_chan_data_t *sngss7_info)
476 {
477
478 if (sngss7_test_flag(sngss7_info,FLAG_RESET_RX)) {
479 return 1;
480 }
481
482 if (sngss7_test_flag(sngss7_info,FLAG_RESET_TX)) {
483 return 1;
484 }
485
486 if (sngss7_test_flag(sngss7_info,FLAG_GRP_RESET_RX)) {
487 return 1;
488 }
489
490 if (sngss7_test_flag(sngss7_info,FLAG_GRP_RESET_TX)) {
491 return 1;
492 }
493
494 return 0;
495
496 }
497
498
499 unsigned long get_unique_id(void)
500 {
501
502 if (sngss7_id < 420000000) {
503 sngss7_id++;
504 } else {
505 sngss7_id = 1;
506 }
507
508 return(sngss7_id);
509 }
510
511
512 ftdm_status_t check_if_rx_grs_started(ftdm_span_t *ftdmspan)
513 {
514 ftdm_channel_t *ftdmchan = NULL;
515 sngss7_chan_data_t *sngss7_info = NULL;
516 sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmspan->signal_data;
517 int i;
518
519 for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
520
521
522 if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
523 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i);
524 continue;
525 }
526
527
528 if (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX)) {
529
530 continue;
531 }
532
533
534 ftdm_mutex_lock(ftdmchan->mutex);
535
536
537 while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
538 ftdm_sangoma_ss7_process_state_change (ftdmchan);
539 }
540
541 SS7_INFO_CHAN(ftdmchan, "Rx GRS (%d:%d)\n",
542 g_ftdm_sngss7_data.cfg.isupCkt[sngss7_span->rx_grs.circuit].cic,
543 (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_span->rx_grs.circuit].cic + sngss7_span->rx_grs.range));
544
545
546 sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX);
547
548 switch (ftdmchan->state) {
549
550 case FTDM_CHANNEL_STATE_RESTART:
551
552
553 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE);
554
555 break;
556
557 default:
558
559
560 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
561 break;
562
563 }
564
565
566 ftdm_mutex_unlock(ftdmchan->mutex);
567
568 }
569
570 return FTDM_SUCCESS;
571 }
572
573
574 ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan)
575 {
576 ftdm_channel_t *ftdmchan = NULL;
577 sngss7_chan_data_t *sngss7_info = NULL;
578 sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmspan->signal_data;
579 int i;
580 int byte = 0;
581 int bit = 0;
582
583
584 ftdm_log(FTDM_LOG_DEBUG, "Found Rx GRS on span %s...checking circuits\n", ftdmspan->name);
585
586
587 for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
588
589
590 if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
591 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i);
592 continue;
593 }
594
595
596 ftdm_mutex_lock(ftdmchan->mutex);
597
598
599 if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
600
601 if (!sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) {
602
603 goto GRS_UNLOCK_ALL;
604 }
605 } else {
606
607 goto GRS_UNLOCK_ALL;
608 }
609 }
610
611 SS7_DEBUG("All circuits out of reset for GRS: circuit=%d, range=%d\n",
612 sngss7_span->rx_grs.circuit,
613 sngss7_span->rx_grs.range);
614
615
616 for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
617
618
619 if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
620 SS7_ERROR("Failed to extract channel data for circuit = %d!\n",i);
621
622 SS7_ASSERT;
623
624 continue;
625 }
626
627
628 sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT);
629
630
631 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
632
633
634 if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) ||
635 (sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) ||
636 (sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX)) ||
637 (sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) {
638
639 sngss7_span->rx_grs.status[byte] = (sngss7_span->rx_grs.status[byte] | (1 << bit));
640 }
641
642
643 bit ++;
644 if (bit == 8) {
645 byte++;
646 bit = 0;
647 }
648 }
649
650 GRS_UNLOCK_ALL:
651 for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
652
653 if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
654 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i);
655 continue;
656 }
657
658
659 ftdm_mutex_unlock(ftdmchan->mutex);
660 }
661
662 return FTDM_SUCCESS;
663 }
664
665
666 ftdm_status_t check_if_rx_gra_started(ftdm_span_t *ftdmspan)
667 {
668 ftdm_channel_t *ftdmchan = NULL;
669 sngss7_chan_data_t *sngss7_info = NULL;
670 sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmspan->signal_data;
671 int i;
672
673 for (i = sngss7_span->rx_gra.circuit; i < (sngss7_span->rx_gra.circuit + sngss7_span->rx_gra.range + 1); i++) {
674
675
676 if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
677 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i);
678 continue;
679 }
680
681
682 if (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) {
683
684 continue;
685 }
686
687
688 ftdm_mutex_lock(ftdmchan->mutex);
689
690
691 while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
692 ftdm_sangoma_ss7_process_state_change (ftdmchan);
693 }
694
695 SS7_INFO_CHAN(ftdmchan, "Rx GRA (%d:%d)\n",
696 g_ftdm_sngss7_data.cfg.isupCkt[sngss7_span->rx_gra.circuit].cic,
697 (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_span->rx_gra.circuit].cic + sngss7_span->rx_gra.range));
698
699 switch (ftdmchan->state) {
700
701 case FTDM_CHANNEL_STATE_RESTART:
702
703
704 sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP);
705
706
707 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
708
709 break;
710
711 case FTDM_CHANNEL_STATE_DOWN:
712
713
714 SS7_DEBUG("Receveived GRA in down state, dropping\n");
715
716 break;
717
718 case FTDM_CHANNEL_STATE_TERMINATING:
719 case FTDM_CHANNEL_STATE_HANGUP:
720 case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
721
722
723 sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP);
724
725 break;
726
727 default:
728
729 if (sngss7_span->rx_gra.cause != 0) {
730 ftdmchan->caller_data.hangup_cause = sngss7_span->rx_gra.cause;
731 } else {
732 ftdmchan->caller_data.hangup_cause = 98;
733 }
734
735
736 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
737 break;
738
739 }
740
741
742 ftdm_mutex_unlock(ftdmchan->mutex);
743
744 }
745
746
747 return FTDM_SUCCESS;
748 }
749
750
751 ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan)
752 {
753 ftdm_channel_t *ftdmchan = NULL;
754 sngss7_chan_data_t *sngss7_info = NULL;
755 ftdm_sigmsg_t sigev;
756 int x;
757
758 for (x = 1; x < (ftdmspan->chan_count + 1); x++) {
759
760
761 ftdmchan = ftdmspan->channels[x];
762
763
764 if (ftdmchan->call_data == NULL) continue;
765
766 sngss7_info = ftdmchan->call_data;
767
768
769 ftdm_mutex_lock(ftdmchan->mutex);
770
771 memset (&sigev, 0, sizeof (sigev));
772
773 sigev.chan_id = ftdmchan->chan_id;
774 sigev.span_id = ftdmchan->span_id;
775 sigev.channel = ftdmchan;
776
777
778 if ((sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) &&
779 (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP))) {
780
781
782 while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
783 ftdm_sangoma_ss7_process_state_change (ftdmchan);
784 }
785
786
787
788 ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
789 }
790
791
792
793 if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) {
794
795
796 while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
797 ftdm_sangoma_ss7_process_state_change (ftdmchan);
798 }
799
800
801 ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
802 }
803
804
805 ftdm_mutex_unlock(ftdmchan->mutex);
806
807 }
808
809
810 ftdm_span_trigger_signals(ftdmspan);
811
812 return FTDM_SUCCESS;
813 }
814
815
816 ftdm_status_t process_span_ucic(ftdm_span_t *ftdmspan)
817 {
818 ftdm_channel_t *ftdmchan = NULL;
819 sngss7_chan_data_t *sngss7_info = NULL;
820 sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmspan->signal_data;
821 int i;
822
823 for (i = sngss7_span->ucic.circuit; i < (sngss7_span->ucic.circuit + sngss7_span->ucic.range + 1); i++) {
824
825
826 if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
827 SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i);
828 continue;
829 }
830
831
832 ftdm_mutex_lock(ftdmchan->mutex);
833
834 SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx UCIC\n", sngss7_info->circuit->cic);
835
836
837 while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
838 ftdm_sangoma_ss7_process_state_change (ftdmchan);
839 }
840
841
842 sngss7_set_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK);
843
844
845 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
846
847
848 ftdm_mutex_unlock(ftdmchan->mutex);
849 }
850
851
852 memset(&sngss7_span->ucic, 0x0, sizeof(sngss7_group_data_t));
853
854 return FTDM_SUCCESS;
855 }
856
857
858 ftdm_status_t clear_rx_grs_flags(sngss7_chan_data_t *sngss7_info)
859 {
860
861 sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_RX);
862 sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_RX_DN);
863 sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT);
864
865 return FTDM_SUCCESS;
866 }
867
868
869 ftdm_status_t clear_rx_grs_data(sngss7_chan_data_t *sngss7_info)
870 {
871 ftdm_channel_t *ftdmchan = sngss7_info->ftdmchan;
872 sngss7_span_data_t *sngss7_span = ftdmchan->span->signal_data;
873
874
875 memset(&sngss7_span->rx_grs, 0x0, sizeof(sngss7_group_data_t));
876
877 return FTDM_SUCCESS;
878 }
879
880
881 ftdm_status_t clear_rx_gra_data(sngss7_chan_data_t *sngss7_info)
882 {
883 ftdm_channel_t *ftdmchan = sngss7_info->ftdmchan;
884 sngss7_span_data_t *sngss7_span = ftdmchan->span->signal_data;
885
886
887 memset(&sngss7_span->rx_gra, 0x0, sizeof(sngss7_group_data_t));
888
889 return FTDM_SUCCESS;
890 }
891
892 ftdm_status_t clear_tx_grs_flags(sngss7_chan_data_t *sngss7_info)
893 {
894
895 sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_BASE);
896 sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_TX);
897 sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_SENT);
898 sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP);
899
900 return FTDM_SUCCESS;
901 }
902
903
904 ftdm_status_t clear_tx_grs_data(sngss7_chan_data_t *sngss7_info)
905 {
906 ftdm_channel_t *ftdmchan = sngss7_info->ftdmchan;
907 sngss7_span_data_t *sngss7_span = ftdmchan->span->signal_data;
908
909
910 memset(&sngss7_span->tx_grs, 0x0, sizeof(sngss7_group_data_t));
911
912 return FTDM_SUCCESS;
913 }
914
915
916
917
918 ftdm_status_t clear_rx_rsc_flags(sngss7_chan_data_t *sngss7_info)
919 {
920
921 sngss7_clear_flag(sngss7_info, FLAG_RESET_RX);
922
923 return FTDM_SUCCESS;
924 }
925
926
927 ftdm_status_t clear_tx_rsc_flags(sngss7_chan_data_t *sngss7_info)
928 {
929
930 sngss7_clear_flag(sngss7_info, FLAG_RESET_TX);
931 sngss7_clear_flag(sngss7_info, FLAG_RESET_SENT);
932 sngss7_clear_flag(sngss7_info, FLAG_RESET_TX_RSP);
933
934 return FTDM_SUCCESS;
935 }
936
937
938 ftdm_status_t encode_subAddrIE_nsap(const char *subAddr, char *subAddrIE, int type)
939 {
940
941
942
943
944
945
946
947
948
949 int x = 0;
950 int p = 0;
951 int len = 0;
952 char tmp[2];
953
954
955 tmp[1]='\0';
956
957
958 p = 0;
959 switch(type) {
960
961 case SNG_CALLED:
962 subAddrIE[p] = 0x71;
963 break;
964
965 case SNG_CALLING:
966 subAddrIE[p] = 0x6d;
967 break;
968
969 default:
970 SS7_ERROR("Sub-Address type is invalid: %d\n", type);
971 return FTDM_FAIL;
972 break;
973
974 }
975
976
977 p = 2;
978 subAddrIE[p] = 0x80;
979
980
981 p = 3;
982
983
984 while (subAddr[x] != '\0') {
985
986
987 tmp[0] = subAddr[x];
988
989
990 if (!isdigit(tmp[0])) {
991 SS7_INFO("Dropping invalid digit: %c\n", tmp[0]);
992
993 x++;
994
995
996 continue;
997 }
998
999
1000 subAddrIE[p] = atoi(&tmp[0]);
1001 subAddrIE[p] |= 0x3 << 4;
1002
1003
1004 len++;
1005
1006
1007 p++;
1008
1009
1010 x++;
1011
1012 }
1013
1014
1015 p = 1;
1016 subAddrIE[p] = len + 1;
1017
1018
1019 return FTDM_SUCCESS;
1020 }
1021
1022
1023 ftdm_status_t encode_subAddrIE_nat(const char *subAddr, char *subAddrIE, int type)
1024 {
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034 int x = 0;
1035 int p = 0;
1036 int len = 0;
1037 char tmp[2];
1038 int flag = 0;
1039 int odd = 0;
1040 uint8_t lower = 0x0;
1041 uint8_t upper = 0x0;
1042
1043
1044 tmp[1]='\0';
1045
1046
1047 p = 0;
1048 switch(type) {
1049
1050 case SNG_CALLED:
1051 subAddrIE[p] = 0x71;
1052 break;
1053
1054 case SNG_CALLING:
1055 subAddrIE[p] = 0x6d;
1056 break;
1057
1058 default:
1059 SS7_ERROR("Sub-Address type is invalid: %d\n", type);
1060 return FTDM_FAIL;
1061 break;
1062
1063 }
1064
1065
1066 p = 3;
1067
1068
1069 while (1) {
1070
1071
1072 tmp[0] = subAddr[x];
1073
1074
1075 while ((!isxdigit(tmp[0])) && (tmp[0] != '\0')) {
1076 SS7_INFO("Dropping invalid digit: %c\n", tmp[0]);
1077
1078 x++;
1079 tmp[0] = subAddr[x];
1080 }
1081
1082
1083 if (tmp[0] != '\0') {
1084
1085 lower = strtol(&tmp[0], (char **)NULL, 16);
1086
1087 x++;
1088
1089 tmp[0] = subAddr[x];
1090
1091
1092 while (!(isxdigit(tmp[0])) && (tmp[0] != '\0')) {
1093 SS7_INFO("Dropping invalid digit: %c\n", tmp[0]);
1094 x++;
1095 tmp[0] = subAddr[x];
1096 }
1097
1098
1099 if (tmp[0] != '\0') {
1100
1101 upper = (strtol(&tmp[0], (char **)NULL, 16)) << 4;
1102 } else {
1103
1104 upper = 0x00;
1105
1106 odd = 1;
1107
1108 flag = 1;
1109 }
1110 } else {
1111
1112 odd = 0;
1113
1114
1115 flag = 1;
1116
1117
1118 break;
1119 }
1120
1121
1122 subAddrIE[p] = upper | lower;
1123
1124
1125 len++;
1126
1127
1128 if (flag) break;
1129
1130
1131 p++;
1132
1133
1134 x++;
1135
1136 }
1137
1138
1139 p = 1;
1140 subAddrIE[p] = len + 1;
1141
1142
1143 p = 2;
1144 subAddrIE[p] = 0xa0 | (odd << 3);
1145
1146
1147 return FTDM_SUCCESS;
1148 }
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161