This source file includes following definitions.
- Q931SetL4HeaderSpace
- Q931SetL2HeaderSpace
- Q931ProcDummy
- Q931UmesDummy
- Q931UieDummy
- Q931PmesDummy
- Q931PieDummy
- Q931TxDummy
- Q931ErrorDummy
- Q931Initialize
- Q931TimerTick
- Q931Rx23
- Q931Tx34
- Q931Rx43
- Q931Tx32Data
- Q931SetError
- Q931SetDefaultErrorCB
- Q931CreateCRV
- Q931ReleaseCRV
- Q931AllocateCRV
- Q931GetCallState
- Q931StartTimer
- Q931StopTimer
- Q931SetState
- Q931GetTime
- Q931SetGetTimeCB
- Q931FindCRV
- Q931AddDialect
- Q931AddStateEntry
- Q931IsEventLegal
- q931_error_to_name
- Q931Log
- Q931SetLogCB
- Q931SetLogLevel
- Q931TimeoutDummy
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
36
37
38
39 #include "Q921.h"
40 #include "Q931.h"
41 #include "national.h"
42 #include "DMS.h"
43 #include "5ESS.h"
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 q931proc_func_t *Q931Proc[Q931MAXDLCT][Q931MAXMES];
64
65 q931umes_func_t *Q931Umes[Q931MAXDLCT][Q931MAXMES];
66 q931pmes_func_t *Q931Pmes[Q931MAXDLCT][Q931MAXMES];
67
68 q931uie_func_t *Q931Uie[Q931MAXDLCT][Q931MAXIE];
69 q931pie_func_t *Q931Pie[Q931MAXDLCT][Q931MAXIE];
70
71 q931timeout_func_t *Q931Timeout[Q931MAXDLCT][Q931MAXTIMER];
72 q931timer_t Q931Timer[Q931MAXDLCT][Q931MAXTIMER];
73
74 void (*Q931CreateDialectCB[Q931MAXDLCT])(L3UCHAR iDialect) = { NULL, NULL };
75
76 Q931State Q931st[Q931MAXSTATE];
77
78
79
80
81
82
83
84 L3INT Q931L4HeaderSpace = {0};
85
86
87 L3INT Q931L2HeaderSpace = {4};
88
89
90
91
92
93
94
95 Q931ErrorCB_t Q931ErrorProc;
96 L3ULONG (*Q931GetTimeProc) (void) = NULL;
97
98
99
100
101
102
103
104
105
106
107
108 void Q931SetL4HeaderSpace(L3INT space)
109 {
110 Q931L4HeaderSpace = space;
111 }
112
113
114
115
116
117
118
119
120
121
122
123 void Q931SetL2HeaderSpace(L3INT space)
124 {
125 Q931L2HeaderSpace = space;
126 }
127
128
129
130
131
132
133
134
135 L3INT Q931ProcDummy(Q931_TrunkInfo_t *pTrunk, L3UCHAR * b,L3INT c)
136 {
137 return Q931E_INTERNAL;
138 }
139
140
141
142
143
144
145
146
147 L3INT Q931UmesDummy(Q931_TrunkInfo_t *pTrunk,L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT IOff, L3INT Size)
148 {
149 return Q931E_UNKNOWN_MESSAGE;
150 }
151
152
153
154
155
156
157
158
159 L3INT Q931UieDummy(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
160 {
161 return Q931E_UNKNOWN_IE;
162 }
163
164
165
166
167
168
169
170
171 L3INT Q931PmesDummy(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize)
172 {
173 return Q931E_UNKNOWN_MESSAGE;
174 }
175
176
177
178
179
180
181
182
183 L3INT Q931PieDummy(Q931_TrunkInfo_t *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
184 {
185 return Q931E_UNKNOWN_IE;
186 }
187
188
189
190
191
192
193
194
195 L3INT Q931TxDummy(Q931_TrunkInfo_t *pTrunk, L3UCHAR * b, L3INT n)
196 {
197 return Q931E_MISSING_CB;
198 }
199
200
201
202
203
204
205
206
207 L3INT Q931ErrorDummy(void *priv, L3INT a, L3INT b, L3INT c)
208 {
209 return 0;
210 }
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227 void Q931Initialize()
228 {
229 L3INT x,y;
230
231
232 Q931ErrorProc = Q931ErrorDummy;
233
234
235
236
237
238 for (x = 0; x < Q931MAXDLCT; x++) {
239 for (y = 0; y < Q931MAXMES; y++) {
240 Q931Proc[x][y] = Q931ProcDummy;
241 Q931Umes[x][y] = Q931UmesDummy;
242 Q931Pmes[x][y] = Q931PmesDummy;
243 }
244 for (y = 0; y < Q931MAXIE; y++) {
245 Q931Pie[x][y] = Q931PieDummy;
246 Q931Uie[x][y] = Q931UieDummy;
247 }
248 for (y = 0; y < Q931MAXTIMER; y++) {
249 Q931Timeout[x][y] = Q931TimeoutDummy;
250 Q931Timer[x][y] = 0;
251 }
252 }
253
254 if (Q931CreateDialectCB[Q931_Dialect_Q931 + Q931_TE] == NULL)
255 Q931AddDialect(Q931_Dialect_Q931 + Q931_TE, Q931CreateTE);
256
257 if (Q931CreateDialectCB[Q931_Dialect_Q931 + Q931_NT] == NULL)
258 Q931AddDialect(Q931_Dialect_Q931 + Q931_NT, Q931CreateNT);
259
260 if (Q931CreateDialectCB[Q931_Dialect_National + Q931_TE] == NULL)
261 Q931AddDialect(Q931_Dialect_National + Q931_TE, nationalCreateTE);
262
263 if (Q931CreateDialectCB[Q931_Dialect_National + Q931_NT] == NULL)
264 Q931AddDialect(Q931_Dialect_National + Q931_NT, nationalCreateNT);
265
266 if (Q931CreateDialectCB[Q931_Dialect_DMS + Q931_TE] == NULL)
267 Q931AddDialect(Q931_Dialect_DMS + Q931_TE, DMSCreateTE);
268
269 if (Q931CreateDialectCB[Q931_Dialect_DMS + Q931_NT] == NULL)
270 Q931AddDialect(Q931_Dialect_DMS + Q931_NT, DMSCreateNT);
271
272 if (Q931CreateDialectCB[Q931_Dialect_5ESS + Q931_TE] == NULL)
273 Q931AddDialect(Q931_Dialect_5ESS + Q931_TE, ATT5ESSCreateTE);
274
275 if (Q931CreateDialectCB[Q931_Dialect_5ESS + Q931_NT] == NULL)
276 Q931AddDialect(Q931_Dialect_5ESS + Q931_NT, ATT5ESSCreateNT);
277
278
279 for (x = 0; x < Q931MAXDLCT; x++) {
280 if (Q931CreateDialectCB[x] != NULL) {
281 Q931CreateDialectCB[x]((L3UCHAR)x);
282 }
283 }
284 }
285
286
287
288
289
290
291 void Q931TimerTick(Q931_TrunkInfo_t *pTrunk)
292 {
293 struct Q931_Call *call = NULL;
294 L3ULONG now = 0;
295 L3INT x;
296
297
298
299
300
301
302 now = Q931GetTime();
303
304 for (x = 0; x < Q931MAXCALLPERTRUNK; x++) {
305 call = &pTrunk->call[x];
306
307 if (!call->InUse || !call->Timer || !call->TimerID)
308 continue;
309
310 if (call->Timer <= now) {
311
312 Q931StopTimer(pTrunk, x, call->TimerID);
313
314
315 Q931Timeout[pTrunk->Dialect][call->TimerID](pTrunk, x);
316 }
317 }
318 }
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341 L3INT Q931Rx23(Q931_TrunkInfo_t *pTrunk, L3INT ind, L3UCHAR tei, L3UCHAR * buf, L3INT Size)
342 {
343 L3UCHAR *Mes = NULL;
344 L3INT RetCode = Q931E_NO_ERROR;
345 Q931mes_Generic *m = (Q931mes_Generic *) pTrunk->L3Buf;
346 L3INT ISize;
347 L3INT IOff = 0;
348 L3INT L2HSize = Q931L2HeaderSpace;
349
350 switch (ind) {
351 case Q921_DL_UNIT_DATA:
352 L2HSize = 3;
353
354 case Q921_DL_DATA:
355
356 memset(pTrunk->L3Buf, 0, sizeof(pTrunk->L3Buf));
357
358
359 Mes = &buf[L2HSize];
360
361
362 m->ProtDisc = Mes[IOff++];
363
364
365 m->CRVFlag = (Mes[IOff + 1] >> 7) & 0x01;
366 m->CRV = Q931Uie_CRV(pTrunk, Mes, m->buf, &IOff, &ISize);
367
368
369 m->MesType = Mes[IOff++];
370
371
372 m->Tei = tei;
373
374
375
376
377
378 if (tei) {
379 L3INT callIndex = 0;
380
381
382 RetCode = Q931FindCRV(pTrunk, m->CRV, &callIndex);
383 if (RetCode == Q931E_NO_ERROR && !pTrunk->call[callIndex].Tei) {
384 pTrunk->call[callIndex].Tei = tei;
385 }
386 }
387
388 Q931Log(pTrunk, Q931_LOG_DEBUG, "Received message from Q.921 (ind %d, tei %d, size %d)\nMesType: %d, CRVFlag %d (%s), CRV %d (Dialect: %d)\n", ind, m->Tei, Size,
389 m->MesType, m->CRVFlag, m->CRVFlag ? "Terminator" : "Originator", m->CRV, pTrunk->Dialect);
390
391 RetCode = Q931Umes[pTrunk->Dialect][m->MesType](pTrunk, Mes, (Q931mes_Generic *)pTrunk->L3Buf, IOff, Size - L2HSize);
392 if (RetCode >= Q931E_NO_ERROR) {
393 RetCode = Q931Proc[pTrunk->Dialect][m->MesType](pTrunk, pTrunk->L3Buf, 2);
394 }
395 break;
396
397 default:
398 break;
399 }
400
401 return RetCode;
402 }
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417 L3INT Q931Tx34(Q931_TrunkInfo_t *pTrunk, L3UCHAR * Mes, L3INT Size)
418 {
419 Q931Log(pTrunk, Q931_LOG_DEBUG, "Sending message to Layer4 (size: %d)\n", Size);
420
421 if (pTrunk->Q931Tx34CBProc) {
422 return pTrunk->Q931Tx34CBProc(pTrunk->PrivateData34, Mes, Size);
423 }
424 return Q931E_MISSING_CB;
425 }
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441 L3INT Q931Rx43(Q931_TrunkInfo_t *pTrunk,L3UCHAR * buf, L3INT Size)
442 {
443 Q931mes_Header *ptr = (Q931mes_Header*)&buf[Q931L4HeaderSpace];
444 L3INT RetCode = Q931E_NO_ERROR;
445
446 Q931Log(pTrunk, Q931_LOG_DEBUG, "Receiving message from Layer4 (size: %d, type: %d)\n", Size, ptr->MesType);
447
448 RetCode = Q931Proc[pTrunk->Dialect][ptr->MesType](pTrunk, buf, 4);
449
450 Q931Log(pTrunk, Q931_LOG_DEBUG, "Q931Rx43 return code: %d\n", RetCode);
451
452 return RetCode;
453 }
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472 L3INT Q931Tx32Data(Q931_TrunkInfo_t *pTrunk, L3UCHAR bcast, L3UCHAR * Mes, L3INT Size)
473 {
474 Q931mes_Generic *ptr = (Q931mes_Generic*)Mes;
475 L3INT RetCode = Q931E_NO_ERROR;
476 L3INT iDialect = pTrunk->Dialect;
477 L3INT Offset = bcast ? (Q931L2HeaderSpace - 1) : Q931L2HeaderSpace;
478 L3INT OSize;
479
480 Q931Log(pTrunk, Q931_LOG_DEBUG, "Sending message to Q.921 (size: %d)\n", Size);
481
482 memset(pTrunk->L2Buf, 0, sizeof(pTrunk->L2Buf));
483
484
485 RetCode = Q931Pmes[iDialect][ptr->MesType](pTrunk, (Q931mes_Generic *)Mes, Size, &pTrunk->L2Buf[Offset], &OSize);
486 if (RetCode >= Q931E_NO_ERROR) {
487 L3INT callIndex;
488 L3UCHAR tei = 0;
489
490 if (ptr->CRV) {
491
492 RetCode = Q931FindCRV(pTrunk, ptr->CRV, &callIndex);
493 if (RetCode != Q931E_NO_ERROR)
494 return RetCode;
495
496 tei = pTrunk->call[callIndex].Tei;
497 }
498
499 if (pTrunk->Q931Tx32CBProc) {
500 RetCode = pTrunk->Q931Tx32CBProc(pTrunk->PrivateData32, bcast ? Q921_DL_UNIT_DATA : Q921_DL_DATA, tei, pTrunk->L2Buf, OSize + Offset);
501 } else {
502 RetCode = Q931E_MISSING_CB;
503 }
504 }
505
506 return RetCode;
507 }
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522 void Q931SetError(Q931_TrunkInfo_t *pTrunk,L3INT ErrID, L3INT ErrPar1, L3INT ErrPar2)
523 {
524 if (pTrunk->Q931ErrorCBProc) {
525 pTrunk->Q931ErrorCBProc(pTrunk->PrivateData34, ErrID, ErrPar1, ErrPar2);
526 } else {
527 Q931ErrorProc(pTrunk->PrivateData34, ErrID, ErrPar1, ErrPar2);
528 }
529 }
530
531 void Q931SetDefaultErrorCB(Q931ErrorCB_t Q931ErrorPar)
532 {
533 Q931ErrorProc = Q931ErrorPar;
534 }
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550 L3INT Q931CreateCRV(Q931_TrunkInfo_t *pTrunk, L3INT * callIndex)
551 {
552 L3INT CRV = Q931GetUniqueCRV(pTrunk);
553
554 return Q931AllocateCRV(pTrunk, CRV, callIndex);
555 }
556
557
558 L3INT Q931ReleaseCRV(Q931_TrunkInfo_t *pTrunk, L3INT CRV)
559 {
560 int callIndex;
561
562 if ((Q931FindCRV(pTrunk, CRV, &callIndex)) == Q931E_NO_ERROR) {
563 pTrunk->call[callIndex].InUse = 0;
564 return Q931E_NO_ERROR;
565 }
566
567 return Q931E_INVALID_CRV;
568 }
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585 L3INT Q931AllocateCRV(Q931_TrunkInfo_t *pTrunk, L3INT iCRV, L3INT * callIndex)
586 {
587 L3INT x;
588 for (x = 0; x < Q931MAXCALLPERTRUNK; x++) {
589 if (!pTrunk->call[x].InUse) {
590 pTrunk->call[x].CRV = iCRV;
591 pTrunk->call[x].BChan = 255;
592 pTrunk->call[x].State = 0;
593 pTrunk->call[x].TimerID = 0;
594 pTrunk->call[x].Timer = 0;
595 pTrunk->call[x].InUse = 1;
596 *callIndex = x;
597 return Q931E_NO_ERROR;
598 }
599 }
600 return Q931E_TOMANYCALLS;
601 }
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616 L3INT Q931GetCallState(Q931_TrunkInfo_t *pTrunk, L3INT iCRV)
617 {
618 L3INT x;
619 for (x = 0; x < Q931MAXCALLPERTRUNK; x++) {
620 if (pTrunk->call[x].InUse) {
621 if (pTrunk->call[x].CRV == iCRV) {
622 return pTrunk->call[x].State;
623 }
624 }
625 }
626 return 0;
627 }
628
629
630
631
632
633
634
635
636
637 L3INT Q931StartTimer(Q931_TrunkInfo_t *pTrunk, L3INT callIndex, L3USHORT iTimerID)
638 {
639 #if 0
640 L3ULONG duration = Q931Timer[pTrunk->Dialect][iTimerID];
641
642 if (duration) {
643 pTrunk->call[callIndex].Timer = Q931GetTime() + duration;
644 pTrunk->call[callIndex].TimerID = iTimerID;
645 }
646 #endif
647 return 0;
648 }
649
650
651
652
653
654
655
656
657
658 L3INT Q931StopTimer(Q931_TrunkInfo_t *pTrunk, L3INT callindex, L3USHORT iTimerID)
659 {
660 if (pTrunk->call[callindex].TimerID == iTimerID)
661 pTrunk->call[callindex].TimerID = 0;
662
663 return 0;
664 }
665
666 L3INT Q931SetState(Q931_TrunkInfo_t *pTrunk, L3INT callIndex, L3INT iState)
667 {
668 pTrunk->call[callIndex].State = iState;
669
670 return 0;
671 }
672
673 L3ULONG Q931GetTime()
674 {
675 L3ULONG tNow = 0;
676 static L3ULONG tLast = 0;
677
678 if (Q931GetTimeProc != NULL) {
679 tNow = Q931GetTimeProc();
680 if (tNow < tLast) {
681
682 }
683 tLast = tNow;
684 }
685 return tNow;
686 }
687
688 void Q931SetGetTimeCB(L3ULONG (*callback)(void))
689 {
690 Q931GetTimeProc = callback;
691 }
692
693 L3INT Q931FindCRV(Q931_TrunkInfo_t *pTrunk, L3INT crv, L3INT *callindex)
694 {
695 L3INT x;
696 for (x = 0; x < Q931MAXCALLPERTRUNK; x++) {
697 if (pTrunk->call[x].InUse) {
698 if (pTrunk->call[x].CRV == crv) {
699 *callindex = x;
700 return Q931E_NO_ERROR;
701 }
702 }
703 }
704 return Q931E_INVALID_CRV;
705 }
706
707
708 void Q931AddDialect(L3UCHAR i, void (*callback)(L3UCHAR iD ))
709 {
710 if (i < Q931MAXDLCT) {
711 Q931CreateDialectCB[i] = callback;
712 }
713 }
714
715
716
717
718
719
720
721 void Q931AddStateEntry(L3UCHAR iD, L3INT iState, L3INT iMes, L3UCHAR cDir)
722 {
723 int x;
724 for (x = 0; x < Q931MAXSTATE; x++) {
725 if (Q931st[x].Message == 0) {
726 Q931st[x].State = iState;
727 Q931st[x].Message = iMes;
728 Q931st[x].Direction = cDir;
729
730 return;
731 }
732 }
733 }
734
735
736
737
738
739
740
741
742
743
744 L3BOOL Q931IsEventLegal(L3UCHAR iD, L3INT iState, L3INT iMes, L3UCHAR cDir)
745 {
746 int x;
747
748 for (x = 0; x < Q931MAXSTATE; x++) {
749 if (Q931st[x].State == iState && Q931st[x].Message == iMes &&
750 Q931st[x].Direction == cDir) {
751 return L3TRUE;
752 }
753 }
754 return L3FALSE;
755 }
756
757
758
759
760
761
762
763
764
765
766 static const char *q931_error_names[] = {
767 "Q931E_NO_ERROR",
768
769 "Q931E_UNKNOWN_MESSAGE",
770 "Q931E_ILLEGAL_IE",
771 "Q931E_UNKNOWN_IE",
772 "Q931E_BEARERCAP",
773 "Q931E_HLCOMP",
774 "Q931E_LLCOMP",
775 "Q931E_INTERNAL",
776 "Q931E_MISSING_CB",
777 "Q931E_UNEXPECTED_MESSAGE",
778 "Q931E_ILLEGAL_MESSAGE",
779 "Q931E_TOMANYCALLS",
780 "Q931E_INVALID_CRV",
781 "Q931E_CALLID",
782 "Q931E_CALLSTATE",
783 "Q931E_CALLEDSUB",
784 "Q931E_CALLEDNUM",
785 "Q931E_CALLINGNUM",
786 "Q931E_CALLINGSUB",
787 "Q931E_CAUSE",
788 "Q931E_CHANID",
789 "Q931E_DATETIME",
790 "Q931E_DISPLAY",
791 "Q931E_KEYPADFAC",
792 "Q931E_NETFAC",
793 "Q931E_NOTIFIND",
794 "Q931E_PROGIND",
795 "Q931E_RESTARTIND",
796 "Q931E_SEGMENT",
797 "Q931E_SIGNAL",
798 "Q931E_GENERIC_DIGITS"
799
800 };
801
802 #define Q931_MAX_ERROR 30
803
804 const char *q931_error_to_name(q931_error_t error)
805 {
806 int index = 0;
807 if ((int)error < 0) {
808 index = (((int)error * -1) -3000);
809 }
810 if (index < 0 || index > Q931_MAX_ERROR) {
811 return "";
812 }
813 return q931_error_names[index];
814 }
815
816
817
818 #include <stdarg.h>
819
820 L3INT Q931Log(Q931_TrunkInfo_t *trunk, Q931LogLevel_t level, const char *fmt, ...)
821 {
822 char buf[Q931_LOGBUFSIZE];
823 L3INT len;
824 va_list ap;
825
826 if (!trunk->Q931LogCBProc)
827 return 0;
828
829 if (trunk->loglevel < level)
830 return 0;
831
832 va_start(ap, fmt);
833
834 len = vsnprintf(buf, sizeof(buf)-1, fmt, ap);
835 if (len <= 0) {
836
837 return -1;
838 }
839 if (len >= sizeof(buf))
840 len = sizeof(buf) - 1;
841
842 buf[len] = '\0';
843
844 va_end(ap);
845
846 return trunk->Q931LogCBProc(trunk->PrivateDataLog, level, buf, len);
847 }
848
849
850
851
852
853 void Q931SetLogCB(Q931_TrunkInfo_t *trunk, Q931LogCB_t func, void *priv)
854 {
855 trunk->Q931LogCBProc = func;
856 trunk->PrivateDataLog = priv;
857 }
858
859
860
861
862
863 void Q931SetLogLevel(Q931_TrunkInfo_t *trunk, Q931LogLevel_t level)
864 {
865 if(!trunk)
866 return;
867
868 if (level < Q931_LOG_NONE) {
869 level = Q931_LOG_NONE;
870 } else if (level > Q931_LOG_DEBUG) {
871 level = Q931_LOG_DEBUG;
872 }
873
874 trunk->loglevel = level;
875 }
876
877
878
879
880
881
882
883 L3INT Q931TimeoutDummy(Q931_TrunkInfo_t *pTrunk, L3INT callIndex)
884 {
885 Q931Log(pTrunk, Q931_LOG_DEBUG, "Timer %d of call %d (CRV: %d) timed out\n", pTrunk->call[callIndex].TimerID, callIndex, pTrunk->call[callIndex].CRV);
886
887 return 0;
888 }