00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #define Q931PRIVATE
00040
00041 #include "Q921.h"
00042 #include "Q931.h"
00043
00044 #if defined(HAVE_DIALECT_5ESS)
00045 #include "5ESS.h"
00046 #endif
00047
00048 #if defined(HAVE_DIALECT_DSS1)
00049 #include "DSS1.h"
00050 #endif
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 L3INT Q931L4HeaderSpace = {0};
00077
00078
00079 L3INT Q931L2HeaderSpace = {4};
00080
00081
00082
00083
00084
00085
00086
00087 L3ULONG (*Q931GetTimeProc) (void) = NULL;
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 void Q931SetL4HeaderSpace(L3INT space)
00100 {
00101 Q931L4HeaderSpace = space;
00102 }
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 void Q931SetL2HeaderSpace(L3INT space)
00115 {
00116 Q931L2HeaderSpace = space;
00117 }
00118
00119
00120
00121
00122
00123
00124
00125
00126 L3INT Q931ProcDummy(Q931_TrunkInfo_t *pTrunk, L3UCHAR * b,L3INT c)
00127 {
00128 return Q931E_INTERNAL;
00129 }
00130
00131
00132
00133
00134
00135
00136
00137
00138 L3INT Q931UmesDummy(Q931_TrunkInfo_t *pTrunk,L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT IOff, L3INT Size)
00139 {
00140 return Q931E_UNKNOWN_MESSAGE;
00141 }
00142
00143
00144
00145
00146
00147
00148
00149
00150 L3INT Q931UieDummy(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
00151 {
00152 return Q931E_UNKNOWN_IE;
00153 }
00154
00155
00156
00157
00158
00159
00160
00161
00162 L3INT Q931PmesDummy(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize)
00163 {
00164 return Q931E_UNKNOWN_MESSAGE;
00165 }
00166
00167
00168
00169
00170
00171
00172
00173
00174 L3INT Q931PieDummy(Q931_TrunkInfo_t *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
00175 {
00176 return Q931E_UNKNOWN_IE;
00177 }
00178
00179
00180
00181
00182
00183
00184
00185
00186 L3INT Q931TxDummy(Q931_TrunkInfo_t *pTrunk, L3UCHAR * b, L3INT n)
00187 {
00188 return Q931E_MISSING_CB;
00189 }
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00210 void Q931Initialize(void)
00211 {
00212
00213
00214
00215 Q931DialectRegistryInit();
00216
00217
00218 Q931DialectRegister(Q931_Dialect_Q931, Q931_TE, Q931CreateTE);
00219 Q931DialectRegister(Q931_Dialect_Q931, Q931_NT, Q931CreateNT);
00220
00221
00222 Q931DialectRegister(Q931_Dialect_DSS1, Q931_TE, DSS1CreateTE);
00223 Q931DialectRegister(Q931_Dialect_DSS1, Q931_NT, DSS1CreateNT);
00224
00225 #if 0
00226
00227 Q931DialectRegister(Q931_Dialect_5ESS, Q931_TE, ATT5ESSCreateTE);
00228 Q931DialectRegister(Q931_Dialect_5ESS, Q931_NT, ATT5ESSCreateNT);
00229 #endif
00230 }
00231
00237 void Q931TimerTick(Q931_TrunkInfo_t *pTrunk)
00238 {
00239 struct Q931_Call *call = NULL;
00240 L3ULONG now = 0;
00241 L3INT x;
00242
00243
00244
00245
00246
00247
00248 now = Q931GetTime();
00249
00250 for (x = 0; x < Q931MAXCALLPERTRUNK; x++) {
00251 call = &pTrunk->call[x];
00252
00253 if (!call->InUse || !call->Timer || !call->TimerID)
00254 continue;
00255
00256 if (call->Timer <= now) {
00257 int id = call->TimerID;
00258
00259
00260 Q931CallStopTimer(call, id);
00261
00262
00263 Q931CallIncrementTimerExpireCount(call);
00264
00265
00266 Q931Timeout(pTrunk, call, id);
00267
00268
00269
00270
00271
00272 if (!Q931CallIsGlobal(call)) {
00273 if ((Q931CallGetState(call) & 0xff) == Q931_U0) {
00274
00275 struct Q931_CallEvent event;
00276
00277 event.id = Q931_EVENT_RELEASE_CRV;
00278 event.type = Q931_EVENT_TYPE_CRV;
00279 event.error = 0;
00280
00281 Q931CallSendEvent(call, &event);
00282
00283 Q931Log(pTrunk, Q931_LOG_DEBUG, "Garbage-collecting call %d\n", Q931CallGetCRV(call));
00284
00285
00286 Q931CallRelease(call);
00287 }
00288 }
00289 }
00290 }
00291 }
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314 L3INT Q931Rx23(Q931_TrunkInfo_t *pTrunk, L3INT ind, L3UCHAR tei, L3UCHAR * buf, L3INT Size)
00315 {
00316 L3UCHAR *Mes = NULL;
00317 L3INT RetCode = Q931E_NO_ERROR;
00318 Q931mes_Generic *m = (Q931mes_Generic *) pTrunk->L3Buf;
00319 struct Q931_Call *call = NULL;
00320 L3INT ISize;
00321 L3INT IOff = 0;
00322 L3INT L2HSize = Q931L2HeaderSpace;
00323
00324 switch (ind) {
00325 case Q921_DL_UNIT_DATA:
00326 L2HSize = 3;
00327
00328 case Q921_DL_DATA:
00329
00330 memset(pTrunk->L3Buf, 0, sizeof(pTrunk->L3Buf));
00331
00332
00333 Mes = &buf[L2HSize];
00334
00335
00336 m->ProtDisc = Mes[IOff++];
00337
00338
00339 m->CRVFlag = (Mes[IOff + 1] >> 7) & 0x01;
00340 m->CRV = Q931Uie_CRV(pTrunk, Mes, m->buf, &IOff, &ISize);
00341
00342
00343 m->MesType = Mes[IOff++];
00344
00345
00346 m->Tei = tei;
00347
00348
00349
00350
00351
00352
00353 if (tei && m->CRV) {
00354
00355 call = Q931GetCallByCRV(pTrunk, m->CRV);
00356 if (call && !call->Tei) {
00357 call->Tei = tei;
00358 }
00359 }
00360
00361
00362 if (m->CRV) {
00363
00364 call = Q931GetCallByCRV(pTrunk, m->CRV);
00365 if (!call) {
00366
00367 if(m->MesType == Q931mes_SETUP) {
00368
00369 call = Q931CallNewIncoming(pTrunk, m->CRV);
00370 } else {
00371
00372
00373 return Q931E_INVALID_CRV;
00374 }
00375
00376
00377 if (!call) {
00378
00379 Q931Disconnect(pTrunk, MSGF_FROM_L2, m->CRV, 42);
00380 return Q931E_INTERNAL;
00381 }
00382 }
00383
00384
00385 Q931Log(pTrunk, Q931_LOG_DEBUG, "Call is in state %d [%s]\n", Q931CallGetState(call), Q931CallGetStateName(call));
00386 } else {
00387
00388 call = Q931GetGlobalCall(pTrunk);
00389
00390 Q931Log(pTrunk, Q931_LOG_DEBUG, "Using global call for message\n");
00391 }
00392
00393
00394 Q931Log(pTrunk, Q931_LOG_DEBUG, "Received message from Q.921 (ind %d, tei %d, size %d)\nMesType: %d, CRVFlag %d (%s), CRV %d (Dialect: %s)\n", ind, m->Tei, Size,
00395 m->MesType, m->CRVFlag, m->CRVFlag ? "Terminator" : "Originator", m->CRV, Q931DialectGetName(pTrunk->Dialect));
00396
00397 RetCode = Q931Umes(pTrunk, m->MesType, Mes, (Q931mes_Generic *)pTrunk->L3Buf, IOff, Size - L2HSize);
00398 if (RetCode >= Q931E_NO_ERROR) {
00399 RetCode = Q931Proc(pTrunk, pTrunk->L3Buf, 2);
00400 Q931Log(pTrunk, Q931_LOG_DEBUG, "Q931Proc[%s][%d]() returned %d\n", Q931DialectGetName(pTrunk->Dialect), m->MesType, RetCode);
00401 } else {
00402 Q931Log(pTrunk, Q931_LOG_DEBUG, "Q931Umes[%s][%d]() returned %d\n", Q931DialectGetName(pTrunk->Dialect), m->MesType, RetCode);
00403 }
00404
00405
00406 if (RetCode < Q931E_NO_ERROR) {
00407
00408
00409
00410 switch (RetCode) {
00411 case Q931E_MANDATORY_IE_MISSING:
00412
00413 RetCode = Q931StatusEnquiryResponse(pTrunk, buf, call, Q850_CAUSE_MANDATORY_IE_MISSING);
00414 break;
00415
00416 case Q931E_ILLEGAL_IE:
00417
00418 RetCode = Q931StatusEnquiryResponse(pTrunk, buf, call, Q850_CAUSE_IE_NONEXIST);
00419 break;
00420
00421 case Q931E_UNKNOWN_IE:
00422
00423 RetCode = Q931StatusEnquiryResponse(pTrunk, buf, call, Q850_CAUSE_INVALID_IE_CONTENTS);
00424 break;
00425
00426 case Q931E_UNEXPECTED_MESSAGE:
00427 case Q931E_UNRECOGNIZED_MESSAGE:
00428
00429 if ((Q931CallGetState(call) & 0xff) == Q931_U0)
00430 goto out;
00431
00432
00433 if (m->MesType == Q931mes_RELEASE || m->MesType == Q931mes_RELEASE_COMPLETE)
00434 goto out;
00435
00436 if (Q931TrunkGetStatusEnquiry(pTrunk)) {
00437
00438 Q931InitMesGeneric(m);
00439 m->CRV = Q931CallGetCRV(call);
00440 m->CRVFlag = Q931CallIsOutgoing(call) ? 0 : 1;
00441 m->MesType = Q931mes_STATUS_ENQUIRY;
00442
00443
00444 RetCode = Q931Tx32Data(pTrunk, 0, buf, m->Size);
00445 } else {
00446
00447 RetCode = Q931StatusEnquiryResponse(pTrunk, buf, call,
00448 (RetCode == Q931E_UNEXPECTED_MESSAGE) ? Q850_CAUSE_WRONG_MESSAGE : Q850_CAUSE_MESSAGE_TYPE_NONEXIST);
00449 }
00450 break;
00451
00452 default:
00453 break;
00454 }
00455 }
00456 break;
00457
00458 default:
00459 break;
00460 }
00461
00462 out:
00463 if (call) {
00464
00465 Q931CallSendQueuedEvents(call);
00466
00467
00468
00469
00470
00471
00472
00473
00474 if (!Q931CallIsGlobal(call)) {
00475 if ((Q931CallGetState(call) & 0xff) == Q931_U0) {
00476
00477 struct Q931_CallEvent event;
00478
00479 event.id = Q931_EVENT_RELEASE_CRV;
00480 event.type = Q931_EVENT_TYPE_CRV;
00481 event.error = 0;
00482
00483 Q931CallSendEvent(call, &event);
00484
00485 Q931Log(pTrunk, Q931_LOG_DEBUG, "Garbage-collecting call %d\n", Q931CallGetCRV(call));
00486
00487
00488 Q931CallRelease(call);
00489 }
00490 }
00491 }
00492 return RetCode;
00493 }
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508 L3INT Q931Tx34(Q931_TrunkInfo_t *pTrunk, L3UCHAR * Mes, L3INT Size)
00509 {
00510 Q931Log(pTrunk, Q931_LOG_DEBUG, "Sending message to Layer4 (size: %d)\n", Size);
00511
00512 if (pTrunk->Q931Tx34CBProc) {
00513 return pTrunk->Q931Tx34CBProc(pTrunk->PrivateData34, Mes, Size);
00514 }
00515 return Q931E_MISSING_CB;
00516 }
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532 L3INT Q931Rx43(Q931_TrunkInfo_t *pTrunk,L3UCHAR * buf, L3INT Size)
00533 {
00534 Q931mes_Header *ptr = (Q931mes_Header*)&buf[Q931L4HeaderSpace];
00535 L3INT RetCode = Q931E_NO_ERROR;
00536 struct Q931_Call *call = NULL;
00537
00538 Q931Log(pTrunk, Q931_LOG_DEBUG, "Receiving message from Layer4 (size: %d, type: %d [0x%x], CRV: %d, CRVFlag: %d)\n", Size, ptr->MesType, ptr->MesType, ptr->CRV, ptr->CRVFlag);
00539
00540
00541
00542
00543
00544
00545 if (ptr->CRV) {
00546
00547 call = Q931GetCallByCRV(pTrunk, ptr->CRV);
00548 if(!call)
00549 return Q931E_INVALID_CRV;
00550
00551
00552 ptr->CRVFlag = Q931CallIsOutgoing(call) ? 0 : 1;
00553 } else {
00554
00555 call = Q931GetGlobalCall(pTrunk);
00556 }
00557
00558
00559 if (!Q931DialectGetMesProc(pTrunk->Dialect, ptr->MesType)) {
00560 RetCode = Q931E_UNRECOGNIZED_MESSAGE;
00561
00562 Q931Log(pTrunk, Q931_LOG_WARNING, "Unrecognized message from Layer 4 (size: %d, type: %d)\n", Size, ptr->MesType);
00563
00564
00565 if (Q931TrunkIsSetFlag(pTrunk, Q931_TFLAG_IGNORE_UNKNOWN_MSG)) {
00566 RetCode = Q931E_NO_ERROR;
00567 }
00568 goto out;
00569 }
00570
00571
00572 if (!Q931DialectIsEventLegal(pTrunk->Dialect, Q931CallGetState(call), ptr->MesType, 4)) {
00573 RetCode = Q931E_UNEXPECTED_MESSAGE;
00574
00575 Q931Log(pTrunk, Q931_LOG_ERROR, "Unexpected message (invalid in current state) from Layer 4 (size: %d, type: %d [0x%x])\n", Size, ptr->MesType, ptr->MesType);
00576 goto out;
00577 }
00578
00579 Q931Log(pTrunk, Q931_LOG_NOTICE, "Handling message from Layer4 in %s call state: %d\n", Q931CallIsGlobal(call) ? "global" : "", Q931CallGetState(call));
00580
00581 RetCode = Q931Proc(pTrunk, buf, 4);
00582
00583 out:
00584 if (call) {
00585
00586
00587
00588
00589
00590
00591
00592 if (!Q931CallIsGlobal(call)) {
00593 if ((Q931CallGetState(call) & 0xff) == Q931_U0) {
00594
00595 struct Q931_CallEvent event;
00596
00597 event.id = Q931_EVENT_RELEASE_CRV;
00598 event.type = Q931_EVENT_TYPE_CRV;
00599 event.error = 0;
00600
00601 Q931CallSendEvent(call, &event);
00602
00603 Q931Log(pTrunk, Q931_LOG_DEBUG, "Garbage-collecting call %d\n", Q931CallGetCRV(call));
00604
00605
00606 Q931CallRelease(call);
00607 }
00608 }
00609 }
00610
00611 Q931Log(pTrunk, Q931_LOG_DEBUG, "Q931Rx43 return code: %d\n", RetCode);
00612 return RetCode;
00613 }
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632 L3INT Q931Tx32Data(Q931_TrunkInfo_t *pTrunk, L3UCHAR bcast, L3UCHAR * Mes, L3INT Size)
00633 {
00634 Q931mes_Generic *ptr = (Q931mes_Generic*)Mes;
00635 L3INT RetCode = Q931E_NO_ERROR;
00636 L3INT Offset = bcast ? (Q931L2HeaderSpace - 1) : Q931L2HeaderSpace;
00637 L3INT OSize;
00638 L3UCHAR tei = 0;
00639
00640 Q931Log(pTrunk, Q931_LOG_DEBUG, "Sending message to Q.921 (size: %d)\n", Size);
00641
00642 memset(pTrunk->L2Buf, 0, sizeof(pTrunk->L2Buf));
00643
00644 if (ptr->CRV) {
00645 struct Q931_Call *call;
00646
00647
00648 call = Q931GetCallByCRV(pTrunk, ptr->CRV);
00649 if(!call)
00650 return Q931E_INVALID_CRV;
00651
00652 tei = call->Tei;
00653
00654
00655 ptr->CRVFlag = Q931CallIsOutgoing(call) ? 0 : 1;
00656 }
00657
00658
00659 RetCode = Q931Pmes(pTrunk, ptr->MesType, (Q931mes_Generic *)Mes, Size, &pTrunk->L2Buf[Offset], &OSize);
00660 if (RetCode >= Q931E_NO_ERROR) {
00661
00662 if (pTrunk->Q931Tx32CBProc) {
00663 RetCode = pTrunk->Q931Tx32CBProc(pTrunk->PrivateData32, bcast ? Q921_DL_UNIT_DATA : Q921_DL_DATA, tei, pTrunk->L2Buf, OSize + Offset);
00664 if (RetCode > 0) {
00665
00666 RetCode = Q931E_NO_ERROR;
00667 }
00668 } else {
00669 RetCode = Q931E_MISSING_CB;
00670 }
00671 }
00672
00673 return RetCode;
00674 }
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689 void Q931SetError(Q931_TrunkInfo_t *pTrunk,L3INT ErrID, L3INT ErrPar1, L3INT ErrPar2)
00690 {
00691 if (pTrunk->Q931ErrorCBProc) {
00692 pTrunk->Q931ErrorCBProc(pTrunk->PrivateData34, ErrID, ErrPar1, ErrPar2);
00693 }
00694 }
00695
00696
00697 L3INT Q931ReleaseCRV(Q931_TrunkInfo_t *pTrunk, L3INT CRV)
00698 {
00699 struct Q931_Call *call;
00700
00701 call = Q931GetCallByCRV(pTrunk, CRV);
00702 if (!call)
00703 return Q931E_INVALID_CRV;
00704
00705 call->InUse = 0;
00706 return Q931E_NO_ERROR;
00707 }
00708
00709 L3ULONG Q931GetTime()
00710 {
00711 L3ULONG tNow = 0;
00712 static L3ULONG tLast = 0;
00713
00714 if (Q931GetTimeProc != NULL) {
00715 tNow = Q931GetTimeProc();
00716 if (tNow < tLast) {
00717
00718 }
00719 tLast = tNow;
00720 }
00721 return tNow;
00722 }
00723
00724 void Q931SetGetTimeCB(L3ULONG (*callback)(void))
00725 {
00726 Q931GetTimeProc = callback;
00727 }
00728
00729
00730
00731
00732
00733
00734
00735
00736 void Q931AddStateEntry(L3UCHAR iD, L3INT iState, L3INT iMes, L3UCHAR flags)
00737 {
00738 return;
00739 }
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750 L3BOOL Q931IsEventLegal(L3UCHAR iD, L3INT iState, L3INT iMes, L3UCHAR dirflags)
00751 {
00752 return L3FALSE;
00753 }
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764 static const char *q931_error_names[] = {
00765 "Q931E_NO_ERROR",
00766
00767 "Q931E_UNKNOWN_MESSAGE",
00768 "Q931E_ILLEGAL_IE",
00769 "Q931E_UNKNOWN_IE",
00770 "Q931E_BEARERCAP",
00771 "Q931E_HLCOMP",
00772 "Q931E_LLCOMP",
00773 "Q931E_INTERNAL",
00774 "Q931E_MISSING_CB",
00775 "Q931E_UNEXPECTED_MESSAGE",
00776 "Q931E_ILLEGAL_MESSAGE",
00777 "Q931E_TOMANYCALLS",
00778 "Q931E_INVALID_CRV",
00779 "Q931E_CALLID",
00780 "Q931E_CALLSTATE",
00781 "Q931E_CALLEDSUB",
00782 "Q931E_CALLEDNUM",
00783 "Q931E_CALLINGNUM",
00784 "Q931E_CALLINGSUB",
00785 "Q931E_CAUSE",
00786 "Q931E_CHANID",
00787 "Q931E_DATETIME",
00788 "Q931E_DISPLAY",
00789 "Q931E_KEYPADFAC",
00790 "Q931E_NETFAC",
00791 "Q931E_NOTIFIND",
00792 "Q931E_PROGIND",
00793 "Q931E_RESTARTIND",
00794 "Q931E_SEGMENT",
00795 "Q931E_SIGNAL",
00796 "Q931E_GENERIC_DIGITS",
00797
00798 "Q931E_MANDATORY_IE_MISSING",
00799 "Q931E_UNRECOGNIZED_MESSAGE",
00800 };
00801
00802 #define Q931_MAX_ERROR 32
00803
00804 const char *q931_error_to_name(q931_error_t error)
00805 {
00806 int index = 0;
00807 if ((int)error < 0) {
00808 index = (((int)error * -1) -3000);
00809 }
00810 if (index < 0 || index > Q931_MAX_ERROR) {
00811 return "";
00812 }
00813 return q931_error_names[index];
00814 }
00815
00816
00817
00818 #include <stdarg.h>
00819
00820 L3INT Q931Log(Q931_TrunkInfo_t *trunk, Q931LogLevel_t level, const char *fmt, ...)
00821 {
00822 char buf[Q931_LOGBUFSIZE];
00823 L3INT len;
00824 va_list ap;
00825
00826 if (!trunk->Q931LogCBProc)
00827 return 0;
00828
00829 if (trunk->loglevel < level)
00830 return 0;
00831
00832 va_start(ap, fmt);
00833
00834 len = vsnprintf(buf, sizeof(buf)-1, fmt, ap);
00835 if (len <= 0) {
00836
00837 return -1;
00838 }
00839 if (len >= sizeof(buf))
00840 len = sizeof(buf) - 1;
00841
00842 buf[len] = '\0';
00843
00844 va_end(ap);
00845
00846 return trunk->Q931LogCBProc(trunk->PrivateDataLog, level, buf, len);
00847 }
00848
00853 void Q931SetLogCB(Q931_TrunkInfo_t *trunk, Q931LogCB_t func, void *priv)
00854 {
00855 trunk->Q931LogCBProc = func;
00856 trunk->PrivateDataLog = priv;
00857 }
00858
00863 void Q931SetLogLevel(Q931_TrunkInfo_t *trunk, Q931LogLevel_t level)
00864 {
00865 if(!trunk) {
00866 return;
00867 }
00868
00869 if (level < Q931_LOG_NONE) {
00870 level = Q931_LOG_NONE;
00871 } else if (level > Q931_LOG_DEBUG) {
00872 level = Q931_LOG_DEBUG;
00873 }
00874 trunk->loglevel = level;
00875 }
00876
00883 L3INT Q931TimeoutDummy(Q931_TrunkInfo_t *pTrunk, struct Q931_Call *call)
00884 {
00885 Q931Log(pTrunk, Q931_LOG_DEBUG, "Timer %d of call %d timed out\n", call->TimerID, call->CRV);
00886
00887 return 0;
00888 }
00889
00890
00891
00892
00893
00894
00895 #include <assert.h>
00896
00897 void Q931TrunkSetFlag(Q931_TrunkInfo_t *trunk, L3INT flag)
00898 {
00899 trunk->flags |= flag;
00900 }
00901
00902 void Q931TrunkClearFlag(Q931_TrunkInfo_t *trunk, L3INT flag)
00903 {
00904 trunk->flags &= ~flag;
00905 }
00906
00907 void Q931TrunkClearAllFlags(Q931_TrunkInfo_t *trunk)
00908 {
00909 trunk->flags = 0;
00910 }
00911
00912 L3BOOL Q931TrunkIsSetFlag(const Q931_TrunkInfo_t *trunk, const L3INT flag)
00913 {
00914 return ((trunk->flags & flag) != 0);
00915 }
00916
00917
00918 #define Q931_TRUNK_FLAG_SET_FUNC(_name, _flag) \
00919 void _name(Q931_TrunkInfo_t *trunk, L3BOOL enable) { \
00920 assert(trunk); \
00921 if (enable) { \
00922 Q931TrunkSetFlag(trunk, _flag); \
00923 } else { \
00924 Q931TrunkClearFlag(trunk, _flag); \
00925 } \
00926 }
00927
00928 #define Q931_TRUNK_FLAG_GET_FUNC(_name, _flag) \
00929 L3BOOL _name(Q931_TrunkInfo_t *trunk) { \
00930 assert(trunk); \
00931 return Q931TrunkIsSetFlag(trunk, _flag); \
00932 }
00933
00934 Q931_TRUNK_FLAG_SET_FUNC(Q931TrunkSetAutoSetupAck, Q931_TFLAG_AUTO_SETUP_ACK);
00935 Q931_TRUNK_FLAG_SET_FUNC(Q931TrunkSetAutoServiceAck, Q931_TFLAG_AUTO_SERVICE_ACK);
00936 Q931_TRUNK_FLAG_SET_FUNC(Q931TrunkSetAutoConnectAck, Q931_TFLAG_AUTO_CONNECT_ACK);
00937 Q931_TRUNK_FLAG_SET_FUNC(Q931TrunkSetAutoRestartAck, Q931_TFLAG_AUTO_RESTART_ACK);
00938 Q931_TRUNK_FLAG_SET_FUNC(Q931TrunkSetStatusEnquiry, Q931_TFLAG_STATUS_ENQUIRY);
00939 Q931_TRUNK_FLAG_SET_FUNC(Q931TrunkSetIgnoreUnknownMsg, Q931_TFLAG_IGNORE_UNKNOWN_MSG);
00940 Q931_TRUNK_FLAG_SET_FUNC(Q931TrunkSetIgnoreUnknownIEs, Q931_TFLAG_IGNORE_UNKNOWN_IE);
00941 Q931_TRUNK_FLAG_SET_FUNC(Q931TrunkSetIgnoreIllegalIEs, Q931_TFLAG_IGNORE_ILLEGAL_IE);
00942
00943 Q931_TRUNK_FLAG_GET_FUNC(Q931TrunkGetAutoSetupAck, Q931_TFLAG_AUTO_SETUP_ACK);
00944 Q931_TRUNK_FLAG_GET_FUNC(Q931TrunkGetAutoServiceAck, Q931_TFLAG_AUTO_SERVICE_ACK);
00945 Q931_TRUNK_FLAG_GET_FUNC(Q931TrunkGetAutoConnectAck, Q931_TFLAG_AUTO_CONNECT_ACK);
00946 Q931_TRUNK_FLAG_GET_FUNC(Q931TrunkGetAutoRestartAck, Q931_TFLAG_AUTO_RESTART_ACK);
00947 Q931_TRUNK_FLAG_GET_FUNC(Q931TrunkGetStatusEnquiry, Q931_TFLAG_STATUS_ENQUIRY);
00948 Q931_TRUNK_FLAG_GET_FUNC(Q931TrunkGetIgnoreUnknownMsg, Q931_TFLAG_IGNORE_UNKNOWN_MSG);
00949 Q931_TRUNK_FLAG_GET_FUNC(Q931TrunkGetIgnoreUnknownIEs, Q931_TFLAG_IGNORE_UNKNOWN_IE);
00950 Q931_TRUNK_FLAG_GET_FUNC(Q931TrunkGetIgnoreIllegalIEs, Q931_TFLAG_IGNORE_ILLEGAL_IE);
00951
00960 void Q931TrunkSetRelaxedMode(Q931_TrunkInfo_t *trunk, L3BOOL enable)
00961 {
00962 int flags = (Q931_TFLAG_IGNORE_UNKNOWN_MSG | Q931_TFLAG_IGNORE_UNKNOWN_IE | Q931_TFLAG_IGNORE_ILLEGAL_IE);
00963 assert(trunk);
00964
00965 if (enable) {
00966 Q931TrunkSetFlag(trunk, flags);
00967 } else {
00968 Q931TrunkClearFlag(trunk, flags);
00969 }
00970 }
00971
00972
00973
00974
00975
00976 L3INT Q931Proc(Q931_TrunkInfo_t *pTrunk, L3UCHAR *buf, L3INT iFrom)
00977 {
00978 Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace];
00979 q931proc_func_t *func = Q931DialectGetMesProc(pTrunk->Dialect, pMes->MesType);
00980
00981 if (func) {
00982 return func(pTrunk, buf, iFrom);
00983 }
00984
00985
00986 if (Q931TrunkIsSetFlag(pTrunk, Q931_TFLAG_IGNORE_UNKNOWN_MSG)) {
00987 return Q931E_NO_ERROR;
00988 }
00989
00990 func = Q931DialectGetUnknownMesProc(pTrunk->Dialect);
00991 if (func) {
00992 return func(pTrunk, buf, iFrom);
00993 }
00994 return Q931E_INTERNAL;
00995 }
00996
00997 L3INT Q931ProcInvalid(Q931_TrunkInfo_t *pTrunk, L3UCHAR *buf, L3INT iFrom)
00998 {
00999 q931proc_func_t *func = Q931DialectGetInvalidMesProc(pTrunk->Dialect);
01000
01001 if (func) {
01002 return func(pTrunk, buf, iFrom);
01003 }
01004 return Q931E_INTERNAL;
01005 }
01006
01007 L3INT Q931Umes(Q931_TrunkInfo_t *pTrunk, L3UCHAR id, L3UCHAR *IBuf, Q931mes_Generic *OBuf, L3INT IOff, L3INT Size)
01008 {
01009 q931umes_func_t *func = Q931DialectGetUmesProc(pTrunk->Dialect, id);
01010
01011 if (func) {
01012 return func(pTrunk, IBuf, OBuf, IOff, Size);
01013 }
01014
01015
01016 if (Q931TrunkIsSetFlag(pTrunk, Q931_TFLAG_IGNORE_UNKNOWN_MSG)) {
01017 return Q931E_NO_ERROR;
01018 }
01019
01020 return Q931E_INTERNAL;
01021 }
01022
01023 L3INT Q931Pmes(Q931_TrunkInfo_t *pTrunk, L3UCHAR id, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize)
01024 {
01025 q931pmes_func_t *func = Q931DialectGetPmesProc(pTrunk->Dialect, id);
01026
01027 if (func) {
01028 return func(pTrunk, IBuf, ISize, OBuf, OSize);
01029 }
01030 return Q931E_INTERNAL;
01031 }
01032
01033 L3INT Q931Uie(Q931_TrunkInfo_t *pTrunk, L3UCHAR id, Q931mes_Generic *pMes, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *IOff, L3INT *OOff)
01034 {
01035 q931uie_func_t *func = Q931DialectGetUieProc(pTrunk->Dialect, id);
01036
01037 if (func) {
01038 return func(pTrunk, pMes, IBuf, OBuf, IOff, OOff);
01039 }
01040 return Q931E_INTERNAL;
01041 }
01042
01043 L3INT Q931Pie(Q931_TrunkInfo_t *pTrunk, L3UCHAR id, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
01044 {
01045 q931pie_func_t *func = Q931DialectGetPieProc(pTrunk->Dialect, id);
01046
01047 if (func) {
01048 return func(pTrunk, IBuf, OBuf, Octet);
01049 }
01050 return Q931E_INTERNAL;
01051 }
01052
01053 L3BOOL Q931UieIsNull(Q931_TrunkInfo_t *pTrunk, L3UCHAR id)
01054 {
01055 return (!Q931DialectGetUieProc(pTrunk->Dialect, id));
01056 }
01057
01058 L3BOOL Q931PieIsNull(Q931_TrunkInfo_t *pTrunk, L3UCHAR id)
01059 {
01060 return (!Q931DialectGetPieProc(pTrunk->Dialect, id));
01061 }
01062
01063 L3INT Q931Timeout(Q931_TrunkInfo_t *pTrunk, struct Q931_Call *call, L3UCHAR timer)
01064 {
01065 q931timeout_func_t *func = Q931DialectGetTimerProc(pTrunk->Dialect, timer);
01066
01067 if (func) {
01068 return func(pTrunk, call);
01069 }
01070 return Q931E_INTERNAL;
01071 }
01072
01073
01074
01075
01076
01077 L3INT Q931ProcUnknownMessage(Q931_TrunkInfo_t *pTrunk, L3UCHAR *buf, L3INT iFrom)
01078 {
01079 Q931mes_Header *mes = (Q931mes_Header *)&buf[Q931L4HeaderSpace];
01080
01081 Q931Log(pTrunk, Q931_LOG_NOTICE, "Unknown message %#hx received\n", mes->MesType);
01082
01083 return Q931E_NO_ERROR;
01084 }
01085
01086 L3INT Q931ProcUnexpectedMessage(Q931_TrunkInfo_t *pTrunk, L3UCHAR *buf, L3INT iFrom)
01087 {
01088 Q931mes_Header *mes = (Q931mes_Header *)&buf[Q931L4HeaderSpace];
01089
01090 Q931Log(pTrunk, Q931_LOG_NOTICE, "Unexpected/Invalid message %#hx received\n", mes->MesType);
01091
01092 return Q931E_NO_ERROR;
01093 }
01094