Q931api.c

Go to the documentation of this file.
00001 /*****************************************************************************
00002 
00003   FileName:             Q931api.c
00004 
00005   Contents:             api (Application Programming Interface) functions.
00006                                 See     q931.h for description. 
00007 
00008   License/Copyright:
00009 
00010   Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved.
00011   email:janvb@caselaboratories.com  
00012 
00013   Redistribution and use in source and binary forms, with or without 
00014   modification, are permitted provided that the following conditions are 
00015   met:
00016 
00017     * Redistributions of source code must retain the above copyright notice, 
00018           this list of conditions and the following disclaimer.
00019     * Redistributions in binary form must reproduce the above copyright notice, 
00020           this list of conditions and the following disclaimer in the documentation 
00021           and/or other materials provided with the distribution.
00022     * Neither the name of the Case Labs, Ltd nor the names of its contributors 
00023           may be used to endorse or promote products derived from this software 
00024           without specific prior written permission.
00025 
00026   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
00027   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
00028   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
00029   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
00030   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
00031   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
00032   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00033   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
00034   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
00035   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
00036   POSSIBILITY OF SUCH DAMAGE.
00037 *****************************************************************************/
00038 #define Q931PRIVATE
00039 #include "Q931.h"
00040 #include "memory.h"
00041 
00042 extern L3INT Q931L4HeaderSpace;
00043 
00044 L3INT Q931InitTrunk(Q931_TrunkInfo_t *pTrunk,
00045                                                 Q931Dialect_t Dialect,
00046                                                 Q931NetUser_t NetUser,
00047                                                 Q931_TrunkType_t TrunkType,
00048                                                 Q931Tx34CB_t Q931Tx34CBProc,
00049                                                 Q931Tx32CB_t Q931Tx32CBProc,
00050                                                 Q931ErrorCB_t Q931ErrorCBProc,
00051                                                 void *PrivateData32,
00052                                                 void *PrivateData34)
00053 {
00054         int y, dchannel, maxchans, has_sync = 0;
00055 
00056         memset(pTrunk, 0, sizeof(Q931_TrunkInfo_t));
00057 
00058         switch(TrunkType) {
00059         case Q931_TrType_E1:
00060                 dchannel = 16;
00061                 maxchans = 31;
00062                 has_sync = 1;
00063                 break;
00064 
00065         case Q931_TrType_T1:
00066         case Q931_TrType_J1:
00067                 dchannel = 24;
00068                 maxchans = 24;
00069                 break;
00070 
00071         case Q931_TrType_BRI:
00072         case Q931_TrType_BRI_PTMP:
00073                 dchannel = 3;
00074                 maxchans = 3;
00075                 break;
00076 
00077         default:
00078                 return -1;
00079         }
00080 
00081         pTrunk->Q931Tx34CBProc  = Q931Tx34CBProc;
00082         pTrunk->Q931Tx32CBProc  = Q931Tx32CBProc;
00083         pTrunk->Q931ErrorCBProc = Q931ErrorCBProc;
00084         pTrunk->PrivateData32   = PrivateData32;
00085         pTrunk->PrivateData34   = PrivateData34;
00086 
00087         pTrunk->LastCRV        = 0;
00088         pTrunk->Enabled        = 0;
00089         pTrunk->TrunkState     = 0;
00090 #if 0
00091         pTrunk->autoRestartAck = 0;
00092 #endif
00093 
00094         /* Set dialect */
00095         pTrunk->Dialect = Q931DialectGet(Dialect, NetUser);
00096         if (!pTrunk->Dialect) {
00097                 return -1;
00098         }
00099         pTrunk->TrunkType = TrunkType;
00100         pTrunk->NetUser   = NetUser;
00101 
00102         /* Init channel list */
00103         for (y = 0; y < Q931MAXCHPERTRUNK; y++) {
00104                 pTrunk->ch[y].Available = 1;
00105 
00106                 if (has_sync && y == 0) {
00107                         pTrunk->ch[y].ChanType = Q931_ChType_Sync;
00108                 }
00109                 else if (y == dchannel) {
00110                         pTrunk->ch[y].ChanType = Q931_ChType_D;
00111                 }
00112                 else if(y > maxchans) {
00113                         pTrunk->ch[y].ChanType = Q931_ChType_NotUsed;
00114                 }
00115                 else {
00116                         pTrunk->ch[y].ChanType = Q931_ChType_B;
00117                 }
00118         }
00119 
00120         /* Init global call */
00121         pTrunk->call[0].Trunk = pTrunk;
00122         pTrunk->call[0].InUse = 1;
00123 
00124         return 0;
00125 }
00126 
00130 L3INT Q931Start(Q931_TrunkInfo_t *trunk)
00131 {
00132         L3UCHAR buf[Q931L4BUF];
00133         Q931mes_Generic *pMes = (Q931mes_Generic *)&buf[Q931L4HeaderSpace];
00134         Q931ie_RestartInd resind;
00135 
00136         Q931InitMesGeneric(pMes);
00137         pMes->MesType = Q931mes_RESTART;
00138         pMes->CRV     = 0;
00139 
00140         /* Restart Indicator */
00141         resind.IEId  = Q931ie_RESTART_INDICATOR;
00142         resind.Class = 0x06;    /* Restart this interfaces (?) */
00143         resind.Size  = sizeof(Q931ie_RestartInd);
00144 
00145         pMes->RestartInd = Q931AppendIE((L3UCHAR *)pMes, (L3UCHAR *)&resind);
00146 
00147         Q931Log(trunk, Q931_LOG_NOTICE, "RestartInd Offset: %d\n", pMes->RestartInd);
00148 
00149         return Q931Proc(trunk, buf, 4);
00150 }
00151 
00152 L3INT Q931GetMesSize(Q931mes_Generic *pMes)
00153 {
00154         return ((L3INT)(&pMes->buf[0] - (L3UCHAR *)pMes));
00155 }
00156 
00157 /*****************************************************************************
00158 
00159   Function:     q931AppendIE    
00160 
00161   Description:  Append IE to the message.
00162 
00163   Parameters:   pm      Ptr to message.
00164                 pi      Ptr to information element
00165 
00166   Return Value  ie setting
00167 
00168 *****************************************************************************/
00169 ie Q931AppendIE(L3UCHAR *pm, L3UCHAR *pi)
00170 {
00171         Q931mes_Generic *pMes = (Q931mes_Generic *)pm;
00172         L3INT iISize = ((Q931ie_BearerCap *)pi)->Size;
00173         L3INT Off    = pMes->Size - (&pMes->buf[0] - pm);
00174 
00175         memcpy(&pm[pMes->Size], pi, iISize);
00176         pMes->Size += iISize;
00177 
00178         return (ie)(Off | 0x8000);
00179 }
00180 
00181 /*****************************************************************************
00182 *****************************************************************************/
00183 
00184 L3INT Q931GetUniqueCRV(Q931_TrunkInfo_t *pTrunk)
00185 {
00186         L3INT max = (Q931_IS_BRI(pTrunk)) ? Q931_BRI_MAX_CRV : Q931_PRI_MAX_CRV;
00187         L3INT attempts = 50;
00188 
00189         do {
00190                 pTrunk->LastCRV++;
00191                 pTrunk->LastCRV = (pTrunk->LastCRV <= max) ? pTrunk->LastCRV : 1;
00192 
00193         } while(Q931GetCallByCRV(pTrunk, pTrunk->LastCRV) && --attempts > 0);
00194 
00195         return pTrunk->LastCRV;
00196 }
00197 
00198 L3INT Q931InitMesGeneric(Q931mes_Generic *pMes)
00199 {
00200         memset(pMes, 0, sizeof(*pMes));
00201         pMes->ProtDisc = 0x08;
00202         pMes->Size     = Q931GetMesSize(pMes);
00203 
00204         return 0;
00205 }
00206 
00207 L3INT Q931InitMesResume(Q931mes_Generic * pMes)
00208 {
00209         pMes->ProtDisc = 0x08;
00210         pMes->CRV      = 0;             /* CRV to be allocated, might be receive */
00211         pMes->MesType  = Q931mes_RESUME;
00212         pMes->Size     = Q931GetMesSize(pMes);
00213         pMes->CallID   = 0;             /* Chall Identification */
00214 
00215         return 0;
00216 }
00217 
00218 L3INT Q931InitMesRestartAck(Q931mes_Generic * pMes)
00219 {
00220         pMes->ProtDisc   = 0x08;
00221         pMes->CRV        = 0;           /* CRV to be allocated, might be receive */
00222         pMes->MesType    = Q931mes_RESTART_ACKNOWLEDGE;
00223         pMes->Size       = Q931GetMesSize(pMes);
00224         pMes->ChanID     = 0;           /* Channel Identification */
00225         pMes->Display    = 0;
00226         pMes->RestartInd = 0;
00227         pMes->RestartWin = 0;
00228 
00229         return 0;
00230 }
00231 
00232 L3INT Q931InitIEBearerCap(Q931ie_BearerCap *pIE)
00233 {
00234         pIE->IEId        = Q931ie_BEARER_CAPABILITY;
00235         pIE->Size        = sizeof(Q931ie_BearerCap);
00236         pIE->CodStand    = 0;
00237         pIE->ITC         = 0;
00238         pIE->TransMode   = 0;
00239         pIE->ITR         = 0x10;
00240         pIE->RateMul     = 0;
00241         pIE->Layer1Ident = 0;
00242         pIE->UIL1Prot    = 0;        /* User Information Layer 1 Protocol    */
00243         pIE->SyncAsync   = 0;        /* Sync/Async                           */
00244         pIE->Negot       = 0;                
00245         pIE->UserRate    = 0;
00246         pIE->InterRate   = 0;        /* Intermediate Rate                    */
00247         pIE->NIConTx     = 0;
00248         pIE->NIConRx     = 0;
00249         pIE->FlowCtlTx   = 0;        /* Flow control on Tx                   */
00250         pIE->FlowCtlRx   = 0;        /* Flow control on Rx                   */
00251         pIE->HDR         = 0;
00252         pIE->MultiFrame  = 0;        /* Multi frame support                  */
00253         pIE->Mode        = 0;
00254         pIE->LLInegot    = 0;
00255         pIE->Assignor    = 0;        /* Assignor/assignee                    */
00256         pIE->InBandNeg   = 0;        /* In-band/out-band negot.              */
00257         pIE->NumStopBits = 0;        /* Number of stop bits                  */
00258         pIE->NumDataBits = 0;        /* Number of data bits.                 */
00259         pIE->Parity      = 0;
00260         pIE->DuplexMode  = 0;
00261         pIE->ModemType   = 0;
00262         pIE->Layer2Ident = 0;
00263         pIE->UIL2Prot    = 0;        /* User Information Layer 2 Protocol    */
00264         pIE->Layer3Ident = 0;           
00265         pIE->UIL3Prot    = 0;        /* User Information Layer 3 Protocol    */
00266         pIE->AL3Info1    = 0;
00267         pIE->AL3Info2    = 0;
00268 
00269         return 0;
00270 }
00271 
00272 L3INT Q931InitIEChanID(Q931ie_ChanID *pIE)
00273 {
00274         pIE->IEId         = Q931ie_CHANNEL_IDENTIFICATION;
00275         pIE->Size         = sizeof(Q931ie_ChanID);
00276         pIE->IntIDPresent = 0;          /* Int. id. present                     */
00277         pIE->IntType      = 0;          /* Int. type                            */
00278         pIE->PrefExcl     = 0;          /* Pref./Excl.                          */
00279         pIE->DChanInd     = 0;          /* D-channel ind.                       */
00280         pIE->InfoChanSel  = 0;          /* Info. channel selection              */
00281         pIE->InterfaceID  = 0;          /* Interface identifier                 */
00282         pIE->CodStand     = 0;          /* Code standard                        */
00283         pIE->NumMap       = 0;          /* Number/Map                           */
00284         pIE->ChanMapType  = 0;          /* Channel type/Map element type        */
00285         pIE->ChanSlot     = 0;          /* Channel number/Slot map              */
00286 
00287         return 0;
00288 }
00289 
00290 L3INT Q931InitIEProgInd(Q931ie_ProgInd * pIE)
00291 {
00292         pIE->IEId     = Q931ie_PROGRESS_INDICATOR;
00293         pIE->Size     = sizeof(Q931ie_ProgInd);
00294         pIE->CodStand = 0;        /* Coding standard                      */
00295         pIE->Location = 0;        /* Location                             */
00296         pIE->ProgDesc = 0;        /* Progress description                 */
00297 
00298         return 0;
00299 }
00300 
00301 L3INT Q931InitIENetFac(Q931ie_NetFac * pIE)
00302 {
00303         pIE->IEId      = Q931ie_NETWORK_SPECIFIC_FACILITIES;
00304         pIE->Size      = sizeof(Q931ie_NetFac);
00305         pIE->LenNetID  = 0;        /* Length of network facilities id.     */
00306         pIE->TypeNetID = 0;        /* Type of network identification       */
00307         pIE->NetIDPlan = 0;        /* Network identification plan.         */
00308         pIE->NetFac    = 0;        /* Network specific facility spec.      */
00309         pIE->NetID[0]  = 0;
00310 
00311         return 0;
00312 }
00313 
00314 L3INT Q931InitIEDisplay(Q931ie_Display * pIE)
00315 {
00316         pIE->IEId       = Q931ie_DISPLAY;
00317         pIE->Size       = sizeof(Q931ie_Display);
00318         pIE->Display[0] = 0;
00319 
00320         return 0;
00321 }
00322 
00323 L3INT Q931InitIEDateTime(Q931ie_DateTime * pIE)
00324 {
00325         pIE->IEId   = Q931ie_DATETIME;
00326         pIE->Size   = sizeof(Q931ie_DateTime);
00327         pIE->Year   = 0;
00328         pIE->Month  = 0;
00329         pIE->Day    = 0;
00330         pIE->Hour   = 0;
00331         pIE->Minute = 0;
00332         pIE->Second = 0;
00333 
00334         return 0;
00335 }
00336 
00337 L3INT Q931InitIEKeypadFac(Q931ie_KeypadFac * pIE)
00338 {
00339         pIE->IEId         = Q931ie_KEYPAD_FACILITY;
00340         pIE->Size         = sizeof(Q931ie_KeypadFac);
00341         pIE->KeypadFac[0] = 0;
00342 
00343         return 0;
00344 }
00345 
00346 L3INT Q931InitIESignal(Q931ie_Signal * pIE)
00347 {
00348         pIE->IEId   = Q931ie_SIGNAL;
00349         pIE->Size   = sizeof(Q931ie_Signal);
00350         pIE->Signal = 0;
00351 
00352         return 0;
00353 }
00354 
00355 L3INT Q931InitIECallingNum(Q931ie_CallingNum * pIE)
00356 {
00357         pIE->IEId      = Q931ie_CALLING_PARTY_NUMBER;
00358         pIE->Size      = sizeof(Q931ie_CallingNum);
00359         pIE->TypNum    = 0;        /* Type of number                       */
00360         pIE->NumPlanID = 0;        /* Numbering plan identification        */
00361         pIE->PresInd   = 0;        /* Presentation indicator               */
00362         pIE->ScreenInd = 0;        /* Screening indicator                  */
00363         pIE->Digit[0]  = 0;        /* Number digits (IA5)                  */
00364 
00365         return 0;
00366 }
00367 
00368 L3INT Q931InitIECallingSub(Q931ie_CallingSub * pIE)
00369 {
00370         pIE->IEId       = Q931ie_CALLING_PARTY_SUBADDRESS;
00371         pIE->Size       = sizeof(Q931ie_CallingSub);
00372         pIE->TypNum     = 0;        /* Type of subaddress                   */
00373         pIE->OddEvenInd = 0;        /* Odd/Even indicator                   */
00374         pIE->Digit[0]   = 0;        /* Digits                               */
00375 
00376         return 0;
00377 }
00378 
00379 L3INT Q931InitIECalledNum(Q931ie_CalledNum * pIE)
00380 {
00381         pIE->IEId      = Q931ie_CALLED_PARTY_NUMBER;
00382         pIE->Size      = sizeof(Q931ie_CalledNum);
00383         pIE->TypNum    = 0;        /* Type of Number                       */
00384         pIE->NumPlanID = 0;        /* Numbering plan identification        */
00385         pIE->Digit[0]  = 0;        /* Digit (IA5)                          */
00386 
00387         return 0;
00388 }
00389 
00390 L3INT Q931InitIECalledSub(Q931ie_CalledSub * pIE)
00391 {
00392         pIE->IEId       = Q931ie_CALLED_PARTY_SUBADDRESS;
00393         pIE->Size       = sizeof(Q931ie_CalledSub);
00394         pIE->TypNum     = 0;        /* Type of subaddress                   */
00395         pIE->OddEvenInd = 0;        /* Odd/Even indicator                   */
00396         pIE->Digit[0]   = 0;        /* Digits                               */
00397 
00398         return 0;
00399 }
00400 
00401 L3INT Q931InitIETransNetSel(Q931ie_TransNetSel * pIE)
00402 {
00403         pIE->IEId      = Q931ie_TRANSIT_NETWORK_SELECTION;
00404         pIE->Size      = sizeof(Q931ie_TransNetSel);
00405         pIE->Type      = 0;        /* Type of network identifier           */
00406         pIE->NetIDPlan = 0;        /* Network idetification plan           */
00407         pIE->NetID[0]  = 0;        /* Network identification(IA5)          */
00408 
00409         return 0;
00410 }
00411 
00412 L3INT Q931InitIELLComp(Q931ie_LLComp * pIE)
00413 {
00414         pIE->IEId         = Q931ie_LOW_LAYER_COMPATIBILITY;
00415         pIE->Size         = sizeof(Q931ie_LLComp);
00416         pIE->CodStand     = 0;        /* Coding standard                      */
00417         pIE->ITransCap    = 0;        /* Information transfer capability      */
00418         pIE->NegotInd     = 0;        /* Negot indic.                         */
00419         pIE->TransMode    = 0;        /* Transfer Mode                        */
00420         pIE->InfoRate     = 0;        /* Information transfer rate            */
00421         pIE->RateMul      = 0;        /* Rate multiplier                      */
00422         pIE->Layer1Ident  = 0;        /* Layer 1 ident.                       */
00423         pIE->UIL1Prot     = 0;        /* User information layer 1 protocol    */
00424         pIE->SyncAsync    = 0;        /* Synch/asynch                         */
00425         pIE->Negot        = 0;        /* Negot                                */
00426         pIE->UserRate     = 0;        /* User rate                            */
00427         pIE->InterRate    = 0;        /* Intermediate rate                    */
00428         pIE->NIConTx      = 0;        /* NIC on Tx                            */
00429         pIE->NIConRx      = 0;        /* NIC on Rx                            */
00430         pIE->FlowCtlTx    = 0;        /* Flow control on Tx                   */
00431         pIE->FlowCtlRx    = 0;        /* Flow control on Rx                   */
00432         pIE->HDR          = 0;        /* Hdr/no hdr                           */
00433         pIE->MultiFrame   = 0;        /* Multiframe                           */
00434         pIE->ModeL1       = 0;          /* Mode L1                                                              */
00435         pIE->NegotLLI     = 0;        /* Negot. LLI                           */
00436         pIE->Assignor     = 0;        /* Assignor/Assignor ee                 */
00437         pIE->InBandNeg    = 0;        /* In-band negot.                       */
00438         pIE->NumStopBits  = 0;        /* Number of stop bits                  */
00439         pIE->NumDataBits  = 0;        /* Number of data bits                  */
00440         pIE->Parity       = 0;        /* Parity                               */
00441         pIE->DuplexMode   = 0;        /* Duplex Mode                          */
00442         pIE->ModemType    = 0;        /* Modem type                           */
00443         pIE->Layer2Ident  = 0;        /* Layer 2 ident.                       */
00444         pIE->UIL2Prot     = 0;        /* User information layer 2 protocol    */
00445         pIE->ModeL2       = 0;        /* ModeL2                               */
00446         pIE->Q933use      = 0;        /* Q.9333 use                           */
00447         pIE->UsrSpcL2Prot = 0;        /* User specified layer 2 protocol info */
00448         pIE->WindowSize   = 0;        /* Window size (k)                      */
00449         pIE->Layer3Ident  = 0;        /* Layer 3 ident                        */
00450         pIE->OptL3Info    = 0;        /* Optional layer 3 protocol info.      */
00451         pIE->ModeL3       = 0;        /* Mode of operation                    */
00452 #if 0
00453         pIE->ModeX25op    = 0;        /* Mode of operation X.25               */
00454 #endif
00455         pIE->DefPackSize  = 0;        /* Default packet size                  */
00456         pIE->PackWinSize  = 0;        /* Packet window size                   */
00457         pIE->AddL3Info    = 0;        /* Additional Layer 3 protocol info     */
00458 
00459         return 0;
00460 }
00461 
00462 L3INT Q931InitIEHLComp(Q931ie_HLComp * pIE)
00463 {
00464         pIE->IEId = Q931ie_HIGH_LAYER_COMPATIBILITY;
00465         pIE->Size = sizeof(Q931ie_HLComp);
00466 
00467         return 0;
00468 }
00469 
00470 L3INT Q931Disconnect(Q931_TrunkInfo_t *pTrunk, L3INT iTo, L3INT iCRV, L3INT iCause)
00471 {
00472         /* TODO:  Unhandled paramaters */
00473         (void)pTrunk;
00474         (void)iTo;
00475         (void)iCRV;
00476         (void)iCause;
00477 
00478         return 0;
00479 }
00480 
00481 L3INT Q931Release(Q931_TrunkInfo_t *pTrunk, L3UCHAR *buf, struct Q931_Call *call, L3UCHAR causeval)
00482 {
00483         Q931mes_Generic *gen = (Q931mes_Generic *)&buf[Q931L4HeaderSpace];
00484         Q931ie_Cause cause;
00485 
00486         Q931InitMesGeneric(gen);
00487         gen->MesType = Q931mes_RELEASE;
00488         gen->CRV     = Q931CallGetCRV(call);
00489         gen->CRVFlag = (Q931CallGetDirection(call) == Q931_DIRECTION_INBOUND) ? 1 : 0;
00490 
00491         if (causeval) {
00492                 /* Inititalize cause IE */
00493                 cause.IEId = Q931ie_CAUSE;
00494                 cause.Size = sizeof(Q931ie_Cause);
00495                 cause.CodStand = Q931_CODING_ITU;
00496                 cause.Location = 1;
00497                 cause.Recom    = 1;
00498                 cause.Value    = causeval;
00499                 *cause.Diag    = '\0';
00500 
00501                 gen->Cause = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &cause);
00502         }
00503 
00504         return Q931Tx32Data(pTrunk, 0, buf, gen->Size);
00505 }
00506 
00507 L3INT Q931ReleaseComplete(Q931_TrunkInfo_t *pTrunk, L3UCHAR *buf, struct Q931_Call *call, L3UCHAR causeval)
00508 {
00509         Q931mes_Generic *gen = (Q931mes_Generic *)&buf[Q931L4HeaderSpace];
00510         Q931ie_Cause cause;
00511 
00512         Q931InitMesGeneric(gen);
00513         gen->MesType = Q931mes_RELEASE_COMPLETE;
00514         gen->CRV     = Q931CallGetCRV(call);
00515         gen->CRVFlag = (Q931CallGetDirection(call) == Q931_DIRECTION_INBOUND) ? 1 : 0;
00516 
00517         if (causeval) {
00518                 /* Inititalize cause IE */
00519                 cause.IEId = Q931ie_CAUSE;
00520                 cause.Size = sizeof(Q931ie_Cause);
00521                 cause.CodStand = Q931_CODING_ITU;
00522                 cause.Location = 1;
00523                 cause.Recom    = 1;
00524                 cause.Value    = causeval;
00525                 *cause.Diag    = '\0';
00526 
00527                 gen->Cause = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &cause);
00528         }
00529 
00530         return Q931Tx32Data(pTrunk, 0, buf, gen->Size);
00531 }
00532 
00533 L3INT Q931StatusEnquiryResponse(Q931_TrunkInfo_t *pTrunk, L3UCHAR *buf, struct Q931_Call *call, L3UCHAR causeval)
00534 {
00535         Q931mes_Generic *gen = (Q931mes_Generic *)&buf[Q931L4HeaderSpace];
00536         Q931ie_CallState state;
00537         Q931ie_Cause cause;
00538 
00539         Q931InitMesGeneric(gen);
00540 
00541         gen->MesType = Q931mes_STATUS;
00542         gen->CRV     = Q931CallGetCRV(call);
00543         gen->CRVFlag = (Q931CallGetDirection(call) == Q931_DIRECTION_INBOUND) ? 1 : 0;
00544 
00545         /* Inititalize cause IE */
00546         cause.IEId = Q931ie_CAUSE;
00547         cause.Size = sizeof(Q931ie_Cause);
00548         cause.CodStand = Q931_CODING_ITU;
00549         cause.Location = 1;
00550         cause.Recom    = 1;
00551         cause.Value    = causeval;
00552         *cause.Diag    = '\0';
00553 
00554         gen->Cause = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &cause);
00555 
00556         /* Initialize callstate IE */
00557         state.IEId = Q931ie_CALL_STATE;
00558         state.Size = sizeof(Q931ie_CallState);
00559         state.CodStand  = Q931_CODING_ITU;
00560         state.CallState = (L3UCHAR)(Q931CallGetState(call) & 0xff);
00561 
00562         gen->CallState = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &state);
00563 
00564         return Q931Tx32Data(pTrunk, 0, buf, gen->Size);
00565 }
00566 
00576 L3INT Q931CallSendStatus(const struct Q931_Call *call, const L3UCHAR causeval)
00577 {
00578         L3UCHAR buf[Q931L4BUF];
00579         Q931mes_Generic *gen = (Q931mes_Generic *)&buf[Q931L4HeaderSpace];
00580         Q931_TrunkInfo_t *trunk;
00581         Q931ie_CallState state;
00582         Q931ie_Cause cause;
00583 
00584         trunk = Q931CallGetTrunk(call);
00585 
00586         Q931InitMesGeneric(gen);
00587 
00588         gen->MesType = Q931mes_STATUS;
00589         gen->CRVFlag = Q931CallIsOutgoing(call) ? 0 : 1;
00590 
00591         /* Inititalize cause IE */
00592         cause.IEId = Q931ie_CAUSE;
00593         cause.Size = sizeof(Q931ie_Cause);
00594         cause.CodStand = Q931_CODING_ITU;
00595         cause.Location = 1;
00596         cause.Recom    = 1;
00597         cause.Value    = causeval;
00598         *cause.Diag    = '\0';
00599 
00600         gen->Cause = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &cause);
00601 
00602         /* Initialize callstate IE */
00603         state.IEId = Q931ie_CALL_STATE;
00604         state.Size = sizeof(Q931ie_CallState);
00605         state.CodStand  = Q931_CODING_ITU;
00606         state.CallState = (L3UCHAR)(Q931CallGetState(call) & 0xff);
00607 
00608         gen->CallState = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &state);
00609 
00610         return Q931Tx32Data(trunk, 0, buf, gen->Size);
00611 }
00612 
00613 L3INT Q931AckRestart(Q931_TrunkInfo_t *pTrunk, L3UCHAR *buf)
00614 {
00615         Q931mes_Generic *pMes = (Q931mes_Generic *)&buf[Q931L4HeaderSpace];
00616         L3INT RetCode;
00617 
00618         pMes->MesType = Q931mes_RESTART_ACKNOWLEDGE;
00619         pMes->CRVFlag = !(pMes->CRVFlag);
00620 
00621         /* Restart Indicator */
00622         if (!pMes->RestartInd) {
00623                 Q931ie_RestartInd resind;
00624 
00625                 resind.IEId  = Q931ie_RESTART_INDICATOR;
00626                 resind.Class = 0x06;    /* Restart this interface (?) */
00627 
00628                 pMes->RestartInd = Q931AppendIE((L3UCHAR *)pMes, (L3UCHAR *)&resind);
00629         }
00630 
00631         RetCode = Q931Proc(pTrunk, buf, 4);
00632         return RetCode;
00633 }
00634 
00635 L3INT Q931AckSetup(Q931_TrunkInfo_t *pTrunk, L3UCHAR *buf)
00636 {
00637         Q931mes_Header *ptr = (Q931mes_Header*)&buf[Q931L4HeaderSpace];
00638         L3INT RetCode;
00639 
00640         ptr->MesType = Q931mes_SETUP_ACKNOWLEDGE;
00641 
00642         RetCode = Q931Proc(pTrunk, buf, 4);
00643 
00644         return RetCode;
00645 }
00646 
00647 L3INT Q931Send(struct Q931_Call *call, Q931mes_Generic *mes, L3INT bcast)
00648 {
00649         Q931_TrunkInfo_t *trunk;
00650         trunk = Q931CallGetTrunk(call);
00651 
00652         return Q931Tx32Data(trunk, bcast, (L3UCHAR *)mes, mes->Size);
00653 }
00654 
00655 L3INT Q931AckConnect(struct Q931_Call *call)
00656 {
00657         L3UCHAR buf[Q931L4BUF];
00658         Q931mes_Generic *gen = (Q931mes_Generic *)buf;
00659         Q931_TrunkInfo_t *trunk;
00660 
00661         trunk = Q931CallGetTrunk(call);
00662 
00663         Q931InitMesGeneric(gen);
00664         gen->MesType = Q931mes_CONNECT_ACKNOWLEDGE;
00665         gen->CRVFlag = Q931CallIsOutgoing(call) ? 0 : 1;
00666 
00667         return Q931Send(call, gen, 0);
00668 }
00669 
00670 L3INT Q931AckService(Q931_TrunkInfo_t *pTrunk, L3UCHAR *buf)
00671 {
00672         Q931mes_Header *ptr = (Q931mes_Header*)&buf[Q931L4HeaderSpace];
00673         L3INT RetCode;
00674 
00675         ptr->MesType = Q931mes_SERVICE_ACKNOWLEDGE;
00676         if (ptr->CRV) {
00677                 ptr->CRVFlag = !(ptr->CRVFlag);
00678         }
00679 
00680         RetCode = Q931Proc(pTrunk, buf, 4);
00681 
00682         return RetCode;
00683 }
00684 
00685 Q931_ENUM_NAMES(DIALECT_TYPE_NAMES, DIALECT_STRINGS)
00686 Q931_STR2ENUM(q931_str2Q931Dialect_type, q931_Q931Dialect_type2str, Q931Dialect_t, DIALECT_TYPE_NAMES, Q931_Dialect_Count)

Generated on Tue Apr 7 17:38:19 2009 for mod_ssh by  doxygen 1.5.4