From 70f5fc615326393ccff7cd92c30055d6a246f1c6 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 21 May 2007 18:25:36 +0000 Subject: [PATCH] checkin q931/q932/q921 code. git-svn-id: http://svn.openzap.org/svn/openzap/trunk@65 a93c3328-9c30-0410-af19-c9cd2b2d52af --- libs/openzap/src/isdn/EuroISDNStateNT.c | 46 + libs/openzap/src/isdn/EuroISDNStateTE.c | 57 + libs/openzap/src/isdn/Q921.c | 477 ++++ libs/openzap/src/isdn/Q931.c | 664 +++++ libs/openzap/src/isdn/Q931StateNT.c | 1259 ++++++++++ libs/openzap/src/isdn/Q931StateTE.c | 1315 ++++++++++ libs/openzap/src/isdn/Q931api.c | 614 +++++ libs/openzap/src/isdn/Q931ie.c | 2951 +++++++++++++++++++++++ libs/openzap/src/isdn/Q931mes.c | 1931 +++++++++++++++ libs/openzap/src/isdn/Q932mes.c | 311 +++ libs/openzap/src/isdn/include/Q921.h | 102 + libs/openzap/src/isdn/include/Q931.h | 2408 ++++++++++++++++++ libs/openzap/src/isdn/include/Q932.h | 191 ++ libs/openzap/src/isdn/include/mfifo.h | 83 + libs/openzap/src/isdn/mfifo.c | 296 +++ 15 files changed, 12705 insertions(+) create mode 100644 libs/openzap/src/isdn/EuroISDNStateNT.c create mode 100644 libs/openzap/src/isdn/EuroISDNStateTE.c create mode 100644 libs/openzap/src/isdn/Q921.c create mode 100644 libs/openzap/src/isdn/Q931.c create mode 100644 libs/openzap/src/isdn/Q931StateNT.c create mode 100644 libs/openzap/src/isdn/Q931StateTE.c create mode 100644 libs/openzap/src/isdn/Q931api.c create mode 100644 libs/openzap/src/isdn/Q931ie.c create mode 100644 libs/openzap/src/isdn/Q931mes.c create mode 100644 libs/openzap/src/isdn/Q932mes.c create mode 100644 libs/openzap/src/isdn/include/Q921.h create mode 100644 libs/openzap/src/isdn/include/Q931.h create mode 100644 libs/openzap/src/isdn/include/Q932.h create mode 100644 libs/openzap/src/isdn/include/mfifo.h create mode 100644 libs/openzap/src/isdn/mfifo.c diff --git a/libs/openzap/src/isdn/EuroISDNStateNT.c b/libs/openzap/src/isdn/EuroISDNStateNT.c new file mode 100644 index 0000000000..9c2fc45616 --- /dev/null +++ b/libs/openzap/src/isdn/EuroISDNStateNT.c @@ -0,0 +1,46 @@ +/***************************************************************************** + + FileName: EuroISDNStateNT.c + + Contents: EuroISDN State Engine for NT (Network Mode). + + The controlling state engine for Q.931 is the state engine + on the NT side. The state engine on the TE side is a slave + of this. The TE side maintain it's own states as described in + ITU-T Q931, but will in raise conditions be overridden by + the NT side. + + License/Copyright: + + Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. + email:janvb@caselaboratories.com + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the Case Labs, Ltd nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*****************************************************************************/ + +#include "Q931.h" + + diff --git a/libs/openzap/src/isdn/EuroISDNStateTE.c b/libs/openzap/src/isdn/EuroISDNStateTE.c new file mode 100644 index 0000000000..cf0631c92b --- /dev/null +++ b/libs/openzap/src/isdn/EuroISDNStateTE.c @@ -0,0 +1,57 @@ +/***************************************************************************** + + FileName: EuroISDNStateTE.c + + Contents: EuroISDN State Engine for TE (User Mode). + + The controlling state engine for Q.931 is the state engine + on the NT side. The state engine on the TE side is a slave + of this. The TE side maintain it's own states as described in + ITU-T Q931, but will in raise conditions be overridden by + the NT side. + + License/Copyright: + + Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. + email:janvb@caselaboratories.com + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the Case Labs, Ltd nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*****************************************************************************/ + +#include "Q931.h" + +/* + EuroISDN is a sub-set of Q.931. Q.931 is very generic as it embrase a lot, + while EuroISDN is more exact and make decitions on some of the + 'implementation options' in the original standard. EuroISDN will + however run smoothly under the generic space, so these functions are more + for show +*/ + +void EuroISDNCreateTE(L3UCHAR i) +{ + Q931CreateTE(i); +} diff --git a/libs/openzap/src/isdn/Q921.c b/libs/openzap/src/isdn/Q921.c new file mode 100644 index 0000000000..c6be948c19 --- /dev/null +++ b/libs/openzap/src/isdn/Q921.c @@ -0,0 +1,477 @@ +/***************************************************************************** + + FileName: q921.c + + Description: Contains the implementation of a Q.921 protocol on top of the + Comet Driver. + + Most of the work required to execute a Q.921 protocol is + taken care of by the Comet ship and it's driver. This layer + will simply configure and make use of these features to + complete a Q.921 implementation. + + Created: 27.dec.2000/JVB + + License/Copyright: + + Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. + email:janvb@caselaboratories.com + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the Case Labs, Ltd nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +*****************************************************************************/ +#include "q921.h" +#include +#include "mfifo.h" + +/***************************************************************************** + Global Tables & Variables. +*****************************************************************************/ +Q921Data Q921DevSpace[Q921MAXTRUNK]; +int Q921HeaderSpace={0}; + +int (*Q921Tx21Proc)(int dev, unsigned char *, int)={NULL}; +int (*Q921Tx23Proc)(int dev, unsigned char *, int)={NULL}; + +/***************************************************************************** + + Function: Q921Init + + Decription: Initialize the Q.921 stack so it is ready for use. This + function MUST be called as part of initializing the + application. + +*****************************************************************************/ +void Q921Init() +{ + int x; + for(x=0; x>2, (mes[0]>>1)&0x01,mes[1]>>1, mes[3]&0x01); + } + else + { + /* todo: whatever*/ + } + } + + /* check for RR */ + else if(mes[2] ==0x01) + { + /* todo: check if RR is responce to I */ + Q921SendRR(trunk, (mes[0]&0xfc)>>2, (mes[0]>>1)&0x01,mes[1]>>1, mes[2]&0x01); + } + + /* check for RNR */ + /* check for REJ */ + /* check for SABME */ + else if((mes[2] & 0xef) == 0x6f) + { + Q921ProcSABME(trunk, mes, rs); + Q921SendUA(trunk, (mes[0]&0xfc)>>2, (mes[0]>>1)&0x01,mes[1]>>1, (mes[2]&0x10)>>4); + } + + /* check for DM */ + /* check for UI */ + /* check for DISC */ + /* check for UA */ + /* check for FRMR */ + /* check for XID */ + + else + { + /* what the ? Issue an error */ +// Q921ErrorProc(trunk, Q921_UNKNOWNFRAME, mes, rs); + /* todo: REJ or FRMR */ + } + + MFIFOKillNext(Q921DevSpace[trunk].HDLCInQueue); + + return 1; + } + return 0; +} + diff --git a/libs/openzap/src/isdn/Q931.c b/libs/openzap/src/isdn/Q931.c new file mode 100644 index 0000000000..42b76ecdb3 --- /dev/null +++ b/libs/openzap/src/isdn/Q931.c @@ -0,0 +1,664 @@ +/***************************************************************************** + + FileName: Q931.c + + Contents: Implementation of Q.931 stack main interface functions. + See q931.h for description. + + License/Copyright: + + Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. + email:janvb@caselaboratories.com + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the Case Labs, Ltd nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*****************************************************************************/ + +#include "Q931.h" + +/***************************************************************************** + + Dialect function pointers tables. + + The following function pointer arrays define pack/unpack functions and + processing furnctions for the different Q.931 based dialects. + + The arrays are initialized with pointers to dummy functions and later + overrided with pointers to actual functions as new dialects are added. + + The initial Q.931 will as an example define 2 dielects as it treats User + and Network mode as separate ISDN dialects. + + The API messages Q931AddProc, Q931AddMes, Q931AddIE are used to initialize + these table entries during system inititialization of a stack. + +*****************************************************************************/ +L3INT (*Q931Proc [Q931MAXDLCT][Q931MAXMES]) (Q931_TrunkInfo *pTrunk, L3UCHAR *,L3INT); + +L3INT (*Q931Umes [Q931MAXDLCT][Q931MAXMES]) (Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT Size); +L3INT (*Q931Pmes [Q931MAXDLCT][Q931MAXMES]) (Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); + +L3INT (*Q931Uie [Q931MAXDLCT][Q931MAXIE]) (Q931_TrunkInfo *pTrunk, ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff); +L3INT (*Q931Pie [Q931MAXDLCT][Q931MAXIE]) (Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet); + +void (*Q931CreateDialectCB[Q931MAXDLCT]) (L3UCHAR iDialect)= +{ + NULL, + NULL +}; + +Q931State Q931st[Q931MAXSTATE]; + +/***************************************************************************** + + Core system tables and variables. + +*****************************************************************************/ + +L3INT Q931L4HeaderSpace={0}; /* header space to be ignoder/inserted */ + /* at head of each message. */ + +L3INT Q931L2HeaderSpace = {4}; /* Q921 header space, sapi, tei etc */ + +/***************************************************************************** + + Main interface callback functions. + +*****************************************************************************/ + +L3INT (*Q931Tx34Proc)(Q931_TrunkInfo *pTrunk, L3UCHAR *,L3INT); + /* callback for messages to be send to */ + /* layer 4. */ + +L3INT (*Q931Tx32Proc)(Q931_TrunkInfo *pTrunk,L3UCHAR *,L3INT); + /* callback ptr for messages to be send */ + /* to layer 2. */ + +void (*Q931ErrorProc)(Q931_TrunkInfo *pTrunk, L3INT,L3INT,L3INT); + /* callback for error messages. */ + +L3ULONG (*Q931GetTimeProc) ()=NULL; /* callback for func reading time in ms */ + +/***************************************************************************** + + Function: Q931SetL4HeaderSpace + + Description: Set the # of bytes to be inserted/ignored at the head of + each message. Q931 will issue a message with space for header + and the user will use this to fill in whatever header info + is required to support the architecture used. + +*****************************************************************************/ +void Q931SetL4HeaderSpace(L3INT space) +{ + Q931L4HeaderSpace = space; +} + +/***************************************************************************** + + Function: Q931SetL2HeaderSpace + + Description: Set the # of bytes to be inserted/ignored at the head of + each message. Q931 will issue a message with space for header + and the user will use this to fill in whatever header info + is required to support the architecture used. + +*****************************************************************************/ +void Q931SetL2HeaderSpace(L3INT space) +{ + Q931L2HeaderSpace = space; +} + +/***************************************************************************** + + Function: Q931 + + Description: Dummy function for message processing. + +*****************************************************************************/ +L3INT Q931ProcDummy(Q931_TrunkInfo *pTrunk, L3UCHAR * b,L3INT c) +{ + return Q931E_INTERNAL; +} + +/***************************************************************************** + + Function: Q931 + + Description: Dummy function for message processing + +*****************************************************************************/ +L3INT Q931UmesDummy(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT Size) +{ + return Q931E_UNKNOWN_MESSAGE; +} + +/***************************************************************************** + + Function: Q931 + + Description: Dummy function for message processing + +*****************************************************************************/ +L3INT Q931UieDummy(Q931_TrunkInfo *pTrunk,ie *pIE,L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) +{ + return Q931E_UNKNOWN_IE; +} + +/***************************************************************************** + + Function: Q931 + + Description: Dummy function for message processing + +*****************************************************************************/ +L3INT Q931PmesDummy(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + return Q931E_UNKNOWN_MESSAGE; +} + +/***************************************************************************** + + Function: Q931PieDummy + + Description: Dummy function for message processing + +*****************************************************************************/ +L3INT Q931PieDummy(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) +{ + return Q931E_UNKNOWN_IE; +} + +/***************************************************************************** + + Function: Q931TxDummy + + Description: Dummy function for message processing + +*****************************************************************************/ +L3INT Q931TxDummy(Q931_TrunkInfo *pTrunk, L3UCHAR * b, L3INT n) +{ + return Q931E_MISSING_CB; +} + +/***************************************************************************** + + Function: Q931ErrorDummy + + Description: Dummy function for error processing + +*****************************************************************************/ +void Q931ErrorDummy(Q931_TrunkInfo *pTrunk,L3INT a, L3INT b, L3INT c) +{ +} + +/***************************************************************************** + + Function: Q931Initialize + + Description: This function Initialize the stack. + + Will set up the trunk array, channel + arrays and initialize Q931 function arrays before it finally + set up EuroISDN processing with User as diealect 0 and + Network as dialect 1. + + Note: Initialization of other stacks should be inserted after + the initialization of EuroISDN. + +*****************************************************************************/ +void Q931Initialize() +{ + L3INT x,y; + + /* Secure the callbacks to default procs */ + Q931Tx34Proc = Q931TxDummy; + Q931Tx32Proc = Q931TxDummy; + Q931ErrorProc = Q931ErrorDummy; + + /* The user will only add the message handlers and IE handlers he need, */ + /* so we need to initialize every single entry to a default function */ + /* that will throw an appropriate error if they are ever called. */ + for(x=0;x< Q931MAXDLCT;x++) + { + for(y=0;y 0 : Warning + see q931errors.h for details. + +*****************************************************************************/ +L3INT Q931Rx23(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT Size) +{ + L3UCHAR *Mes = &buf[Q931L2HeaderSpace]; + L3INT RetCode = Q931E_NO_ERROR; + + Q931mes_Alerting * m = (Q931mes_Alerting*)Mes; + L3INT ISize; + L3INT IOff = 0; + + /* Protocol Discriminator */ + m->ProtDisc = Mes[IOff++]; + + /* CRV */ + m->CRV = Q931Uie_CRV(pTrunk, Mes,m->buf, &IOff, &ISize); + + /* Message Type */ + m->MesType = Mes[IOff++]; + + /* Call table proc to unpack codec message */ + RetCode = Q931Umes[pTrunk->Dialect][m->MesType](pTrunk, Mes, pTrunk->L3Buf,Q931L4HeaderSpace,Size- Q931L4HeaderSpace); + if(RetCode >= Q931E_NO_ERROR) + { + RetCode=Q931Proc[pTrunk->Dialect][m->MesType](pTrunk, pTrunk->L3Buf, 2); + } + + return RetCode; +} + +/***************************************************************************** + + Function: Q931Tx34 + + Description: Called from the stac to send a message to layer 4. + + Parameters: Mes[IN] Ptr to message buffer. + Size[IN] Message size in bytes. + + Return Value: Error Code. 0 = No Error, < 0 :error, > 0 : Warning + see q931errors.h for details. + +*****************************************************************************/ +L3INT Q931Tx34(Q931_TrunkInfo *pTrunk, L3UCHAR * Mes, L3INT Size) +{ + return Q931Tx34Proc(pTrunk, Mes, Size); +} + +/***************************************************************************** + + Function: Q931Rx43 + + Description: Receive message from Layer 4 (application). + + Parameters: pTrunk[IN] Trunk #. + buf[IN] Message Pointer. + Size[IN] Message size in bytes. + + Return Value: Error Code. 0 = No Error, < 0 :error, > 0 : Warning + see q931errors.h for details. + +*****************************************************************************/ +L3INT Q931Rx43(Q931_TrunkInfo *pTrunk,L3UCHAR * buf, L3INT Size) +{ + Q931mes_Header *ptr = (Q931mes_Header*)&buf[Q931L4HeaderSpace]; + L3INT RetCode = Q931E_NO_ERROR; + + RetCode=Q931Proc[pTrunk->Dialect][ptr->MesType](pTrunk,buf,4); + + return RetCode; +} + +/***************************************************************************** + + Function: Q931Tx32 + + Description: Called from the stack to send a message to L2. The input is + always a non-packed message so it will first make a proper + call to create a packed message before it transmits that + message to layer 2. + + Parameters: pTrunk[IN] Trunk # + buf[IN] Ptr to message buffer. + Size[IN] Message size in bytes. + + Return Value: Error Code. 0 = No Error, < 0 :error, > 0 : Warning + see q931errors.h for details. + +*****************************************************************************/ +L3INT Q931Tx32(Q931_TrunkInfo *pTrunk, L3UCHAR * Mes, L3INT Size) +{ + L3INT OSize; + Q931mes_Alerting *ptr = (Q931mes_Alerting*)Mes; + L3INT RetCode = Q931E_NO_ERROR; + L3INT iDialect = pTrunk->Dialect; + + /* Call pack function through table. */ + RetCode = Q931Pmes[iDialect][ptr->MesType](pTrunk,Mes,Size,&pTrunk->L2Buf[Q931L2HeaderSpace], &OSize); + if(RetCode >= Q931E_NO_ERROR) + { + RetCode = Q931Tx32Proc(pTrunk, pTrunk->L2Buf, Size); + } + + return RetCode; +} + + +/***************************************************************************** + + Function: Q931SetError + + Description: Called from the stack to indicate an error. + + Parameters: ErrID ID of ie or message causing error. + ErrPar1 Error parameter 1 + ErrPar2 Error parameter 2. + + +*****************************************************************************/ +void Q931SetError(Q931_TrunkInfo *pTrunk,L3INT ErrID, L3INT ErrPar1, L3INT ErrPar2) +{ + Q931ErrorProc(pTrunk,ErrID, ErrPar1, ErrPar2); +} + +void Q931SetTx34CB(L3INT (*Q931Tx34Par)(Q931_TrunkInfo *pTrunk,L3UCHAR * Mes, L3INT Size)) +{ + Q931Tx34Proc = Q931Tx34Par; +} + +void Q931SetTx32CB(L3INT (*Q931Tx32Par)(Q931_TrunkInfo *pTrunk,L3UCHAR * Mes, L3INT Size)) +{ + Q931Tx32Proc = Q931Tx32Par; +} + +void Q931SetErrorCB(L3INT (*Q931ErrorPar)(Q931_TrunkInfo *pTrunk,L3INT,L3INT,L3INT)) +{ + Q931ErrorProc = Q931ErrorPar; +} + +/***************************************************************************** + + Function: Q931CreateCRV + + Description: Create a CRV entry and return it's index. The function will + locate a free entry in the call tables allocate it and + allocate a unique CRV value attached to it. + + Parameters: pTrunk [IN] Trunk number + callindex [OUT] return call table index. + + Return Value: Error Code. 0 = No Error, < 0 :error, > 0 : Warning + see q931errors.h for details. + +*****************************************************************************/ +L3INT Q931CreateCRV(Q931_TrunkInfo *pTrunk, L3INT * callIndex) +{ + L3INT CRV = Q931GetUniqueCRV(pTrunk); + + return Q931AllocateCRV(pTrunk, CRV, callIndex); +} + +/***************************************************************************** + + Function: Q931AllocateCRV + + Description: Allocate a call table entry and assigns the given CRV value + to it. + + Parameters: pTrunk [IN] Trunk number + iCRV [IN] Call Reference Value. + callindex [OUT] return call table index. + + Return Value: Error Code. 0 = No Error, < 0 :error, > 0 : Warning + see q931errors.h for details. + +*****************************************************************************/ +L3INT Q931AllocateCRV(Q931_TrunkInfo *pTrunk, L3INT iCRV, L3INT * callIndex) +{ + L3INT x; + for(x=0; x < Q931MAXCALLPERTRUNK; x++) + { + if(!pTrunk->call[x].InUse) + { + pTrunk->call[x].CRV = iCRV; + pTrunk->call[x].BChan = 255; + pTrunk->call[x].State = 0; /* null state - idle */ + pTrunk->call[x].TimerID = 0; /* no timer running */ + pTrunk->call[x].Timer = 0; + pTrunk->call[x].InUse = 1; /* mark as used */ + *callIndex = x; + return Q931E_NO_ERROR; + } + } + return Q931E_TOMANYCALLS; +} + +/***************************************************************************** + + Function: Q931GetCallState + + Description: Look up CRV and return current call state. A non existing + CRV is the same as state zero (0). + + Parameters: pTrunk [IN] Trunk number. + iCRV [IN] CRV + + Return Value: Call State. + +*****************************************************************************/ +L3INT Q931GetCallState(Q931_TrunkInfo *pTrunk, L3INT iCRV) +{ + L3INT x; + for(x=0; x < Q931MAXCALLPERTRUNK; x++) + { + if(!pTrunk->call[x].InUse) + { + if(pTrunk->call[x].CRV == iCRV) + { + return pTrunk->call[x].State; + } + } + } + return 0; /* assume state zero for non existing CRV's */ +} + +/***************************************************************************** + + Function: Q931StartTimer + + Description: Start a timer. + + Parameters: pTrunk Trunk number + callindex call index. + iTimer timer id +*****************************************************************************/ +L3INT Q931StartTimer(Q931_TrunkInfo *pTrunk, L3INT callIndex, L3INT iTimerID) +{ + pTrunk->call[callIndex].Timer = Q931GetTime(); + pTrunk->call[callIndex].TimerID = iTimerID; + return 0; +} + +L3INT Q931StopTimer(Q931_TrunkInfo *pTrunk, L3INT callindex, L3INT iTimerID) +{ + if(pTrunk->call[callindex].TimerID == iTimerID) + pTrunk->call[callindex].TimerID = 0; + return 0; +} + +L3INT Q931SetState(Q931_TrunkInfo *pTrunk, L3INT callIndex, L3INT iState) +{ + pTrunk->call[callIndex].State = iState; + + return 0; +} + +L3ULONG Q931GetTime() +{ + L3ULONG tNow; + static L3ULONG tLast={0}; + if(Q931GetTimeProc != NULL) + { + tNow = Q931GetTimeProc(); + if(tNow < tLast) /* wrapped */ + { + // todo + } + tLast = tNow; + } + return tNow; +} + +void Q931SetGetTimeCB(L3ULONG (*callback)()) +{ + Q931GetTimeProc = callback; +} + +L3INT Q931FindCRV(Q931_TrunkInfo *pTrunk, L3INT crv, L3INT *callindex) +{ + L3INT x; + for(x=0; x < Q931MAXCALLPERTRUNK; x++) + { + if(!pTrunk->call[x].InUse) + { + if(pTrunk->call[x].CRV == crv) + { + *callindex = x; + return Q931E_NO_ERROR; + } + } + } + return Q931E_INVALID_CRV; +} + + +void Q931AddDialect(L3UCHAR i, void (*callback)(L3UCHAR iD )) +{ + if(i < Q931MAXDLCT) + { + Q931CreateDialectCB[i] = callback; + } +} + +/***************************************************************************** + Function: Q931AddStateEntry + + Description: Find an empty entry in the dialects state table and add this + entry. +*****************************************************************************/ +void Q931AddStateEntry(L3UCHAR iD, L3INT iState, L3INT iMes, L3UCHAR cDir) +{ + int x; + for(x=0; x < Q931MAXSTATE; x++) + { + if(Q931st[x].Message == 0) + { + Q931st[x].State = iState; + Q931st[x].Message = iMes; + Q931st[x].Direction = cDir; + // TODO Sort table and use bsearch + return; + } + } +} + +/***************************************************************************** + Function: Q931IsEventLegal + + Description: Check state table for matching criteria to indicate if this + Message is legal in this state or not. + + Note: Someone write a bsearch or invent something smart here + please - sequensial is ok for now. +*****************************************************************************/ +L3BOOL Q931IsEventLegal(L3UCHAR iD, L3INT iState, L3INT iMes, L3UCHAR cDir) +{ + int x; + // TODO Sort table and use bsearch + for(x=0; x < Q931MAXSTATE; x++) + { + if( Q931st[x].State == iState + && Q931st[x].Message == iMes + && Q931st[x].Direction == cDir) + { + return L3TRUE; + } + } + return L3FALSE; +} diff --git a/libs/openzap/src/isdn/Q931StateNT.c b/libs/openzap/src/isdn/Q931StateNT.c new file mode 100644 index 0000000000..21adcfa05b --- /dev/null +++ b/libs/openzap/src/isdn/Q931StateNT.c @@ -0,0 +1,1259 @@ +/***************************************************************************** + + FileName: q931StateNT.c + + Contents: Q.931 State Engine for NT (Network Mode). + + The controlling state engine for Q.931 is the state engine + on the NT side. The state engine on the TE side is a slave + of this. The TE side maintain it's own states as described in + ITU-T Q931, but will in raise conditions be overridden by + the NT side. + + License/Copyright: + + Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. + email:janvb@caselaboratories.com + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the Case Labs, Ltd nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*****************************************************************************/ + +#include "Q931.h" + +extern L3INT Q931L4HeaderSpace; + +/***************************************************************************** + Function: Q931CreateNT + + Description: Will create the Q931 NT as a Dialect in the stack. The first + bulk set up the message handlers, the second bulk the IE + encoders/coders, and the last bulk set up the state table. + + Parameters: i Dialect index +*****************************************************************************/ +void Q931CreateNT(L3UCHAR i) +{ + Q931SetMesProc(Q931mes_ALERTING, i,Q931ProcAlertingNT, Q931Umes_Alerting, Q931Pmes_Alerting); + Q931SetMesProc(Q931mes_CALL_PROCEEDING, i,Q931ProcCallProceedingNT, Q931Umes_CallProceeding, Q931Pmes_CallProceeding); + Q931SetMesProc(Q931mes_CONNECT, i,Q931ProcConnectNT, Q931Umes_Connect, Q931Pmes_Connect); + Q931SetMesProc(Q931mes_CONNECT_ACKNOWLEDGE, i,Q931ProcConnectAckNT, Q931Umes_ConnectAck, Q931Pmes_ConnectAck); + Q931SetMesProc(Q931mes_PROGRESS, i,Q931ProcProgressNT, Q931Umes_Progress, Q931Pmes_Progress); + Q931SetMesProc(Q931mes_SETUP, i,Q931ProcSetupNT, Q931Umes_Setup, Q931Pmes_Setup); + Q931SetMesProc(Q931mes_SETUP_ACKNOWLEDGE, i,Q931ProcSetupAckNT, Q931Umes_SetupAck, Q931Pmes_SetupAck); + Q931SetMesProc(Q931mes_RESUME, i,Q931ProcResumeNT, Q931Umes_Resume, Q931Pmes_Resume); + Q931SetMesProc(Q931mes_RESUME_ACKNOWLEDGE, i,Q931ProcResumeAckNT, Q931Umes_ResumeAck, Q931Pmes_ResumeAck); + Q931SetMesProc(Q931mes_RESUME_REJECT, i,Q931ProcResumeRejectNT, Q931Umes_ResumeReject, Q931Pmes_ResumeReject); + Q931SetMesProc(Q931mes_SUSPEND, i,Q931ProcSuspendNT, Q931Umes_Suspend, Q931Pmes_Suspend); + Q931SetMesProc(Q931mes_SUSPEND_ACKNOWLEDGE, i,Q931ProcSuspendAckNT, Q931Umes_SuspendAck, Q931Pmes_SuspendAck); + Q931SetMesProc(Q931mes_SUSPEND_REJECT, i,Q931ProcSuspendRejectNT, Q931Umes_SuspendReject, Q931Pmes_SuspendReject); + Q931SetMesProc(Q931mes_USER_INFORMATION, i,Q931ProcUserInformationNT, Q931Umes_UserInformation, Q931Pmes_UserInformation); + Q931SetMesProc(Q931mes_DISCONNECT, i,Q931ProcDisconnectNT, Q931Umes_Disconnect, Q931Pmes_Disconnect); + Q931SetMesProc(Q931mes_RELEASE, i,Q931ProcReleaseNT, Q931Umes_Release, Q931Pmes_Release); + Q931SetMesProc(Q931mes_RELEASE_COMPLETE, i,Q931ProcReleaseCompleteNT, Q931Umes_ReleaseComplete, Q931Pmes_ReleaseComplete); + Q931SetMesProc(Q931mes_RESTART, i,Q931ProcRestartNT, Q931Umes_Restart, Q931Pmes_Restart); + Q931SetMesProc(Q931mes_RESTART_ACKNOWLEDGE, i,Q931ProcRestartAckNT, Q931Umes_RestartAck, Q931Pmes_RestartAck); + Q931SetMesProc(Q931mes_CONGESTION_CONTROL, i,Q931ProcCongestionControlNT, Q931Umes_CongestionControl, Q931Pmes_CongestionControl); + Q931SetMesProc(Q931mes_INFORMATION, i,Q931ProcInformationNT, Q931Umes_Information, Q931Pmes_Information); + Q931SetMesProc(Q931mes_NOTIFY, i,Q931ProcNotifyNT, Q931Umes_Notify, Q931Pmes_Notify); + Q931SetMesProc(Q931mes_STATUS, i,Q931ProcStatusNT, Q931Umes_Status, Q931Pmes_Status); + Q931SetMesProc(Q931mes_STATUS_ENQUIRY, i,Q931ProcStatusEnquiryNT, Q931Umes_StatusEnquiry, Q931Pmes_StatusEnquiry); + Q931SetMesProc(Q931mes_SEGMENT, i,Q931ProcSegmentNT, Q931Umes_Segment, Q931Pmes_Segment); + + Q931SetMesProc(Q932mes_FACILITY, i,Q932ProcFacilityNT, Q932Umes_Facility, Q932Pmes_Facility); + Q931SetMesProc(Q932mes_HOLD, i,Q932ProcHoldNT, Q932Umes_Hold, Q932Pmes_Hold); + Q931SetMesProc(Q932mes_HOLD_ACKNOWLEDGE, i,Q932ProcHoldAckNT, Q932Umes_HoldAck, Q932Pmes_HoldAck); + Q931SetMesProc(Q932mes_HOLD_REJECT, i,Q932ProcHoldRejectNT, Q932Umes_HoldReject, Q932Pmes_HoldReject); + Q931SetMesProc(Q932mes_REGISTER, i,Q932ProcRegisterNT, Q932Umes_Register, Q932Pmes_Register); + Q931SetMesProc(Q932mes_RETRIEVE, i,Q932ProcRetrieveNT, Q932Umes_Retrieve, Q932Pmes_Retrieve); + Q931SetMesProc(Q932mes_RETRIEVE_ACKNOWLEDGE,i,Q932ProcRetrieveAckNT, Q932Umes_RetrieveAck, Q932Pmes_RetrieveAck); + Q931SetMesProc(Q932mes_RETRIEVE_REJECT, i,Q932ProcRetrieveRejectNT, Q932Umes_RetrieveReject, Q932Pmes_RetrieveReject); + + /* Set up the IE encoder/decoder handle table.*/ + Q931SetIEProc(Q931ie_SEGMENTED_MESSAGE, i,Q931Pie_Segment, Q931Uie_Segment); + Q931SetIEProc(Q931ie_BEARER_CAPABILITY, i,Q931Pie_BearerCap, Q931Uie_BearerCap); + Q931SetIEProc(Q931ie_CAUSE, i,Q931Pie_Cause, Q931Uie_Cause); + Q931SetIEProc(Q931ie_CALL_IDENTITY, i,Q931Pie_CallID, Q931Uie_CallID); + Q931SetIEProc(Q931ie_CALL_STATE, i,Q931Pie_CallState, Q931Uie_CallState); + Q931SetIEProc(Q931ie_CHANNEL_IDENTIFICATION, i,Q931Pie_ChanID, Q931Uie_ChanID); + Q931SetIEProc(Q931ie_PROGRESS_INDICATOR, i,Q931Pie_ProgInd, Q931Uie_ProgInd); + Q931SetIEProc(Q931ie_NETWORK_SPECIFIC_FACILITIES, i,Q931Pie_NetFac, Q931Uie_NetFac); + Q931SetIEProc(Q931ie_NOTIFICATION_INDICATOR, i,Q931Pie_NotifInd, Q931Uie_NotifInd); + Q931SetIEProc(Q931ie_DISPLAY, i,Q931Pie_Display, Q931Uie_Display); + Q931SetIEProc(Q931ie_DATETIME, i,Q931Pie_DateTime, Q931Uie_DateTime); + Q931SetIEProc(Q931ie_KEYPAD_FACILITY, i,Q931Pie_KeypadFac, Q931Uie_KeypadFac); + Q931SetIEProc(Q931ie_SIGNAL, i,Q931Pie_Signal, Q931Uie_Signal); + Q931SetIEProc(Q931ie_TRANSIT_DELAY_SELECTION_AND_IND, i,Q931Pie_TransNetSel, Q931Uie_TransNetSel); + Q931SetIEProc(Q931ie_CALLING_PARTY_NUMBER, i,Q931Pie_CallingNum, Q931Uie_CallingNum); + Q931SetIEProc(Q931ie_CALLING_PARTY_SUBADDRESS, i,Q931Pie_CallingSub, Q931Uie_CallingSub); + Q931SetIEProc(Q931ie_CALLED_PARTY_NUMBER, i,Q931Pie_CalledNum, Q931Uie_CalledNum); + Q931SetIEProc(Q931ie_CALLED_PARTY_SUBADDRESS, i,Q931Pie_CalledSub, Q931Uie_CalledSub); + Q931SetIEProc(Q931ie_TRANSIT_NETWORK_SELECTION, i,Q931Pie_TransNetSel, Q931Uie_TransNetSel); + Q931SetIEProc(Q931ie_RESTART_INDICATOR, i,Q931Pie_RestartInd, Q931Uie_RestartInd); + Q931SetIEProc(Q931ie_LOW_LAYER_COMPATIBILITY, i,Q931Pie_LLComp, Q931Uie_LLComp); + Q931SetIEProc(Q931ie_HIGH_LAYER_COMPATIBILITY, i,Q931Pie_HLComp, Q931Uie_HLComp); + Q931SetIEProc(Q931ie_USER_USER, i,Q931Pie_UserUser, Q931Uie_UserUser); + + /* The following define a state machine. The point is that the Message */ + /* procs can when search this to find out if the message/state */ + /* combination is legale. If not, the proc for unexpected message apply.*/ + + // TODO define state table here +} + +/***************************************************************************** + + Function: Q931ProcAlertingNT + +*****************************************************************************/ +L3INT Q931ProcAlertingNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* Reset 4 sec timer. */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcCallProceedingNT + +*****************************************************************************/ +L3INT Q931ProcCallProceedingNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcConnectNT + +*****************************************************************************/ +L3INT Q931ProcConnectNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcConnectAckNT + +*****************************************************************************/ +L3INT Q931ProcConnectAckNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcProgressNT + +*****************************************************************************/ +L3INT Q931ProcProgressNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcSetupNT + + Description: Process a SETUP message. + + *****************************************************************************/ +L3INT Q931ProcSetupNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT rc=0; + Q931mes_Setup *pMes = (Q931mes_Setup *)&buf[Q931L4HeaderSpace]; + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + + /* Reject SETUP on existing calls */ + if(Q931GetCallState(pTrunk, pMes->CRV) != Q931_U0) + { + Q931Disconnect(pTrunk, iFrom, pMes->CRV, 81); + return Q931E_UNEXPECTED_MESSAGE; + } + + /* outgoing call */ + if(iFrom == 4) + { + ret = Q931CreateCRV(pTrunk, &callIndex); + if(ret) + return ret; + pMes->CRV = pTrunk->call[callIndex].CRV; + + ret = Q931Tx32(pTrunk,buf,pMes->Size); + if(ret) + return ret; + + Q931StartTimer(pTrunk, callIndex, 303); + + Q931SetState(pTrunk, callIndex, Q931_U1); + } + /* incoming call */ + else + { + /* Locate free CRV entry and store info */ + ret = Q931AllocateCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + { + /* Not possible to allocate CRV entry, so must reject call */ + + Q931Disconnect(pTrunk, iFrom, pMes->CRV, 42); + + return ret; + } + + /* Send setup indication to user */ + ret = Q931Tx34(pTrunk,(L3UCHAR*)pMes,pMes->Size); + if(ret != Q931E_NO_ERROR) + return ret; + else + { + /* Must be full queue, meaning we can't process the call */ + /* so we must disconnect */ + Q931Disconnect(pTrunk, iFrom, pMes->CRV, 81); + return ret; + } + + /* Set state U6 */ + Q931SetState(pTrunk, callIndex, Q931_U6); + + Q931StartTimer(pTrunk, callIndex, 303); + } + + return rc; +} + +/***************************************************************************** + + Function: Q931ProcSetupAckNT + + Description: Used to acknowedge a SETUP. Usually the first initial + response recevide back used to buy some time. + + Note that ChanID (B Channel Assignment) might come here from + NT side. + +*****************************************************************************/ +L3INT Q931ProcSetupAckNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcResumeNT + +*****************************************************************************/ +L3INT Q931ProcResumeNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcResumeAckNT + +*****************************************************************************/ +L3INT Q931ProcResumeAckNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcResumeRejectNT + +*****************************************************************************/ +L3INT Q931ProcResumeRejectNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcSuspendNT + +*****************************************************************************/ +L3INT Q931ProcSuspendNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcSuspendAckNT + +*****************************************************************************/ +L3INT Q931ProcSuspendAckNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcSuspendRejectNT + +*****************************************************************************/ +L3INT Q931ProcSuspendRejectNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcInformationNT + +*****************************************************************************/ +L3INT Q931ProcUserInformationNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcDisconnectNT + +*****************************************************************************/ +L3INT Q931ProcDisconnectNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcReleaseNT + +*****************************************************************************/ +L3INT Q931ProcReleaseNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcReleaseCompleteNT + +*****************************************************************************/ +L3INT Q931ProcReleaseCompleteNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcRestartNT + +*****************************************************************************/ +L3INT Q931ProcRestartNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcRestartAckNT + +*****************************************************************************/ +L3INT Q931ProcRestartAckNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcCongestionControlNT + +*****************************************************************************/ +L3INT Q931ProcCongestionControlNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcInformationNT + +*****************************************************************************/ +L3INT Q931ProcInformationNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcNotifyNT + +*****************************************************************************/ +L3INT Q931ProcNotifyNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcStatusNT + +*****************************************************************************/ +L3INT Q931ProcStatusNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcStatusEnquiryNT + +*****************************************************************************/ +L3INT Q931ProcStatusEnquiryNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcSegmentNT + +*****************************************************************************/ +L3INT Q931ProcSegmentNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/****************************************************************************/ +/******************* Q.932 - Supplementary Services *************************/ +/****************************************************************************/ + +/***************************************************************************** + + Function: Q932ProcFacilityNT + +*****************************************************************************/ +L3INT Q932ProcFacilityNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q932ProcHoldNT + +*****************************************************************************/ +L3INT Q932ProcHoldNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q932ProcHoldAckNT + +*****************************************************************************/ +L3INT Q932ProcHoldAckNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q932ProcHoldRejectNT + +*****************************************************************************/ +L3INT Q932ProcHoldRejectNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q932ProcRegisterTE + +*****************************************************************************/ +L3INT Q932ProcRegisterNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q932ProcRetrieveNT + +*****************************************************************************/ +L3INT Q932ProcRetrieveNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcRetrieveAckNT + +*****************************************************************************/ +L3INT Q932ProcRetrieveAckNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcRetrieveRejectNT + +*****************************************************************************/ +L3INT Q932ProcRetrieveRejectNT(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + diff --git a/libs/openzap/src/isdn/Q931StateTE.c b/libs/openzap/src/isdn/Q931StateTE.c new file mode 100644 index 0000000000..f2a3507473 --- /dev/null +++ b/libs/openzap/src/isdn/Q931StateTE.c @@ -0,0 +1,1315 @@ +/***************************************************************************** + + FileName: q931StateTE.c + + Contents: Q.931 State Engine for TE (User Mode). + + The controlling state engine for Q.931 is the state engine + on the NT side. The state engine on the TE side is a slave + of this. The TE side maintain it's own states as described in + ITU-T Q931, but will in raise conditions be overridden by + the NT side. + + This reference implementation uses a process per message, + meaning that each message must check call states. This + is easier for dialect maintenance as each message proc + can be replaced individually. A new TE variant only + need to copy the Q931CreateTE and replace those procs or + need to override. + + License/Copyright: + + Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. + email:janvb@caselaboratories.com + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the Case Labs, Ltd nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*****************************************************************************/ + +#include "Q931.h" + +extern L3INT Q931L4HeaderSpace; + +/***************************************************************************** + Function: Q931CreateTE + + Description: Will create the Q931 TE as a Dialect in the stack. The first + bulk set up the message handlers, the second bulk the IE + encoders/coders, and the last bulk set up the state table. + + Parameters: i Dialect index +*****************************************************************************/ +void Q931CreateTE(L3UCHAR i) +{ + Q931SetMesProc(Q931mes_ALERTING, i,Q931ProcAlertingTE, Q931Umes_Alerting, Q931Pmes_Alerting); + Q931SetMesProc(Q931mes_CALL_PROCEEDING, i,Q931ProcCallProceedingTE, Q931Umes_CallProceeding, Q931Pmes_CallProceeding); + Q931SetMesProc(Q931mes_CONNECT, i,Q931ProcConnectTE, Q931Umes_Connect, Q931Pmes_Connect); + Q931SetMesProc(Q931mes_CONNECT_ACKNOWLEDGE, i,Q931ProcConnectAckTE, Q931Umes_ConnectAck, Q931Pmes_ConnectAck); + Q931SetMesProc(Q931mes_PROGRESS, i,Q931ProcProgressTE, Q931Umes_Progress, Q931Pmes_Progress); + Q931SetMesProc(Q931mes_SETUP, i,Q931ProcSetupTE, Q931Umes_Setup, Q931Pmes_Setup); + Q931SetMesProc(Q931mes_SETUP_ACKNOWLEDGE, i,Q931ProcSetupAckTE, Q931Umes_SetupAck, Q931Pmes_SetupAck); + Q931SetMesProc(Q931mes_RESUME, i,Q931ProcResumeTE, Q931Umes_Resume, Q931Pmes_Resume); + Q931SetMesProc(Q931mes_RESUME_ACKNOWLEDGE, i,Q931ProcResumeAckTE, Q931Umes_ResumeAck, Q931Pmes_ResumeAck); + Q931SetMesProc(Q931mes_RESUME_REJECT, i,Q931ProcResumeRejectTE, Q931Umes_ResumeReject, Q931Pmes_ResumeReject); + Q931SetMesProc(Q931mes_SUSPEND, i,Q931ProcSuspendTE, Q931Umes_Suspend, Q931Pmes_Suspend); + Q931SetMesProc(Q931mes_SUSPEND_ACKNOWLEDGE, i,Q931ProcSuspendAckTE, Q931Umes_SuspendAck, Q931Pmes_SuspendAck); + Q931SetMesProc(Q931mes_SUSPEND_REJECT, i,Q931ProcSuspendRejectTE, Q931Umes_SuspendReject, Q931Pmes_SuspendReject); + Q931SetMesProc(Q931mes_USER_INFORMATION, i,Q931ProcUserInformationTE, Q931Umes_UserInformation, Q931Pmes_UserInformation); + Q931SetMesProc(Q931mes_DISCONNECT, i,Q931ProcDisconnectTE, Q931Umes_Disconnect, Q931Pmes_Disconnect); + Q931SetMesProc(Q931mes_RELEASE, i,Q931ProcReleaseTE, Q931Umes_Release, Q931Pmes_Release); + Q931SetMesProc(Q931mes_RELEASE_COMPLETE, i,Q931ProcReleaseCompleteTE, Q931Umes_ReleaseComplete, Q931Pmes_ReleaseComplete); + Q931SetMesProc(Q931mes_RESTART, i,Q931ProcRestartTE, Q931Umes_Restart, Q931Pmes_Restart); + Q931SetMesProc(Q931mes_RESTART_ACKNOWLEDGE, i,Q931ProcRestartAckTE, Q931Umes_RestartAck, Q931Pmes_RestartAck); + Q931SetMesProc(Q931mes_CONGESTION_CONTROL, i,Q931ProcCongestionControlTE, Q931Umes_CongestionControl, Q931Pmes_CongestionControl); + Q931SetMesProc(Q931mes_INFORMATION, i,Q931ProcInformationTE, Q931Umes_Information, Q931Pmes_Information); + Q931SetMesProc(Q931mes_NOTIFY, i,Q931ProcNotifyTE, Q931Umes_Notify, Q931Pmes_Notify); + Q931SetMesProc(Q931mes_STATUS, i,Q931ProcStatusTE, Q931Umes_Status, Q931Pmes_Status); + Q931SetMesProc(Q931mes_STATUS_ENQUIRY, i,Q931ProcStatusEnquiryTE, Q931Umes_StatusEnquiry, Q931Pmes_StatusEnquiry); + Q931SetMesProc(Q931mes_SEGMENT, i,Q931ProcSegmentTE, Q931Umes_Segment, Q931Pmes_Segment); + + Q931SetMesProc(Q932mes_FACILITY, i,Q932ProcFacilityTE, Q932Umes_Facility, Q932Pmes_Facility); + Q931SetMesProc(Q932mes_HOLD, i,Q932ProcHoldTE, Q932Umes_Hold, Q932Pmes_Hold); + Q931SetMesProc(Q932mes_HOLD_ACKNOWLEDGE, i,Q932ProcHoldAckTE, Q932Umes_HoldAck, Q932Pmes_HoldAck); + Q931SetMesProc(Q932mes_HOLD_REJECT, i,Q932ProcHoldRejectTE, Q932Umes_HoldReject, Q932Pmes_HoldReject); + Q931SetMesProc(Q932mes_REGISTER, i,Q932ProcRegisterTE, Q932Umes_Register, Q932Pmes_Register); + Q931SetMesProc(Q932mes_RETRIEVE, i,Q932ProcRetrieveTE, Q932Umes_Retrieve, Q932Pmes_Retrieve); + Q931SetMesProc(Q932mes_RETRIEVE_ACKNOWLEDGE,i,Q932ProcRetrieveAckTE, Q932Umes_RetrieveAck, Q932Pmes_RetrieveAck); + Q931SetMesProc(Q932mes_RETRIEVE_REJECT, i,Q932ProcRetrieveRejectTE, Q932Umes_RetrieveReject, Q932Pmes_RetrieveReject); + + /* Set up the IE encoder/decoder handle table.*/ + Q931SetIEProc(Q931ie_SEGMENTED_MESSAGE, i,Q931Pie_Segment, Q931Uie_Segment); + Q931SetIEProc(Q931ie_BEARER_CAPABILITY, i,Q931Pie_BearerCap, Q931Uie_BearerCap); + Q931SetIEProc(Q931ie_CAUSE, i,Q931Pie_Cause, Q931Uie_Cause); + Q931SetIEProc(Q931ie_CALL_IDENTITY, i,Q931Pie_CallID, Q931Uie_CallID); + Q931SetIEProc(Q931ie_CALL_STATE, i,Q931Pie_CallState, Q931Uie_CallState); + Q931SetIEProc(Q931ie_CHANNEL_IDENTIFICATION, i,Q931Pie_ChanID, Q931Uie_ChanID); + Q931SetIEProc(Q931ie_PROGRESS_INDICATOR, i,Q931Pie_ProgInd, Q931Uie_ProgInd); + Q931SetIEProc(Q931ie_NETWORK_SPECIFIC_FACILITIES, i,Q931Pie_NetFac, Q931Uie_NetFac); + Q931SetIEProc(Q931ie_NOTIFICATION_INDICATOR, i,Q931Pie_NotifInd, Q931Uie_NotifInd); + Q931SetIEProc(Q931ie_DISPLAY, i,Q931Pie_Display, Q931Uie_Display); + Q931SetIEProc(Q931ie_DATETIME, i,Q931Pie_DateTime, Q931Uie_DateTime); + Q931SetIEProc(Q931ie_KEYPAD_FACILITY, i,Q931Pie_KeypadFac, Q931Uie_KeypadFac); + Q931SetIEProc(Q931ie_SIGNAL, i,Q931Pie_Signal, Q931Uie_Signal); + Q931SetIEProc(Q931ie_TRANSIT_DELAY_SELECTION_AND_IND, i,Q931Pie_TransNetSel, Q931Uie_TransNetSel); + Q931SetIEProc(Q931ie_CALLING_PARTY_NUMBER, i,Q931Pie_CallingNum, Q931Uie_CallingNum); + Q931SetIEProc(Q931ie_CALLING_PARTY_SUBADDRESS, i,Q931Pie_CallingSub, Q931Uie_CallingSub); + Q931SetIEProc(Q931ie_CALLED_PARTY_NUMBER, i,Q931Pie_CalledNum, Q931Uie_CalledNum); + Q931SetIEProc(Q931ie_CALLED_PARTY_SUBADDRESS, i,Q931Pie_CalledSub, Q931Uie_CalledSub); + Q931SetIEProc(Q931ie_TRANSIT_NETWORK_SELECTION, i,Q931Pie_TransNetSel, Q931Uie_TransNetSel); + Q931SetIEProc(Q931ie_RESTART_INDICATOR, i,Q931Pie_RestartInd, Q931Uie_RestartInd); + Q931SetIEProc(Q931ie_LOW_LAYER_COMPATIBILITY, i,Q931Pie_LLComp, Q931Uie_LLComp); + Q931SetIEProc(Q931ie_HIGH_LAYER_COMPATIBILITY, i,Q931Pie_HLComp, Q931Uie_HLComp); + Q931SetIEProc(Q931ie_USER_USER, i,Q931Pie_UserUser, Q931Uie_UserUser); + + /* The following define a state machine. The point is that the Message */ + /* procs can when search this to find out if the message/state */ + /* combination is legale. If not, the proc for unexpected message apply.*/ + + /* State 0 Idle */ + Q931AddStateEntry(i,Q931_U0, Q931mes_RESUME, 2); + Q931AddStateEntry(i,Q931_U0, Q931mes_SETUP, 4); + Q931AddStateEntry(i,Q931_U0, Q931mes_SETUP, 2); + Q931AddStateEntry(i,Q931_U0, Q931mes_STATUS, 4); + Q931AddStateEntry(i,Q931_U0, Q931mes_RELEASE, 4); + Q931AddStateEntry(i,Q931_U0, Q931mes_RELEASE_COMPLETE,4); + + /* State 1 Call Initiating */ + Q931AddStateEntry(i,Q931_U1, Q931mes_DISCONNECT, 2); + Q931AddStateEntry(i,Q931_U1, Q931mes_SETUP_ACKNOWLEDGE, 4); + Q931AddStateEntry(i,Q931_U1, Q931mes_RELEASE_COMPLETE,4); + Q931AddStateEntry(i,Q931_U1, Q931mes_CALL_PROCEEDING, 4); + Q931AddStateEntry(i,Q931_U1, Q931mes_ALERTING, 4); + Q931AddStateEntry(i,Q931_U1, Q931mes_CONNECT, 4); + + /* State 2 Overlap Sending */ + Q931AddStateEntry(i,Q931_U2, Q931mes_INFORMATION, 2); + Q931AddStateEntry(i,Q931_U2, Q931mes_CALL_PROCEEDING, 4); + Q931AddStateEntry(i,Q931_U2, Q931mes_ALERTING, 4); + Q931AddStateEntry(i,Q931_U2, Q931mes_PROGRESS, 4); + Q931AddStateEntry(i,Q931_U2, Q931mes_CONNECT, 4); + Q931AddStateEntry(i,Q931_U2, Q931mes_RELEASE, 2); + + /* State 3 Outgoing Call Proceeding */ + Q931AddStateEntry(i,Q931_U3, Q931mes_PROGRESS, 4); + Q931AddStateEntry(i,Q931_U3, Q931mes_ALERTING, 4); + Q931AddStateEntry(i,Q931_U3, Q931mes_CONNECT, 4); + Q931AddStateEntry(i,Q931_U3, Q931mes_RELEASE, 2); + + /* State 4 Call Delivered */ + Q931AddStateEntry(i,Q931_U4, Q931mes_CONNECT, 4); + + /* State 6 Call Precent */ + Q931AddStateEntry(i,Q931_U6, Q931mes_INFORMATION, 2); + Q931AddStateEntry(i,Q931_U6, Q931mes_ALERTING, 2); + Q931AddStateEntry(i,Q931_U6, Q931mes_CALL_PROCEEDING,2); + Q931AddStateEntry(i,Q931_U6, Q931mes_CONNECT, 2); + Q931AddStateEntry(i,Q931_U6, Q931mes_RELEASE_COMPLETE,2); + Q931AddStateEntry(i,Q931_U6, Q931mes_RELEASE, 4); + Q931AddStateEntry(i,Q931_U6, Q931mes_DISCONNECT, 4); + + /* State 7 Call Received */ + Q931AddStateEntry(i,Q931_U7, Q931mes_CONNECT, 2); + + /* State 8 Connect request */ + Q931AddStateEntry(i,Q931_U8, Q931mes_CONNECT_ACKNOWLEDGE, 4); + + /* State 9 Incoming Call Proceeding */ + Q931AddStateEntry(i,Q931_U9, Q931mes_CONNECT, 2); + Q931AddStateEntry(i,Q931_U9, Q931mes_ALERTING, 2); + Q931AddStateEntry(i,Q931_U9, Q931mes_PROGRESS, 2); + + /* State 10 Active */ + Q931AddStateEntry(i,Q931_U10, Q931mes_SUSPEND, 2); + Q931AddStateEntry(i,Q931_U10, Q931mes_NOTIFY, 4); + Q931AddStateEntry(i,Q931_U10, Q931mes_NOTIFY, 2); + + /* State 11 Disconnect Request */ + Q931AddStateEntry(i,Q931_U11, Q931mes_RELEASE, 4); + Q931AddStateEntry(i,Q931_U11, Q931mes_DISCONNECT, 4); + Q931AddStateEntry(i,Q931_U11, Q931mes_NOTIFY, 4); + + /* State 12 Disconnect Ind */ + Q931AddStateEntry(i,Q931_U12, Q931mes_RELEASE, 4); + Q931AddStateEntry(i,Q931_U12, Q931mes_RELEASE, 2); + + /* State 15 Suspend Request */ + Q931AddStateEntry(i,Q931_U15, Q931mes_SUSPEND_ACKNOWLEDGE, 4); + Q931AddStateEntry(i,Q931_U15, Q931mes_SUSPEND_REJECT, 4); + Q931AddStateEntry(i,Q931_U15, Q931mes_DISCONNECT, 4); + Q931AddStateEntry(i,Q931_U15, Q931mes_RELEASE, 4); + +/* TODO + Q931AddStateEntry(i,Q931_U17, + Q931AddStateEntry(i,Q931_U19, + Q931AddStateEntry(i,Q931_U25, +*/ +} + +/***************************************************************************** + + Function: Q931ProcAlertingTE + +*****************************************************************************/ +L3INT Q931ProcAlertingTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* Reset 4 sec timer. */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcCallProceedingTE + +*****************************************************************************/ +L3INT Q931ProcCallProceedingTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcConnectTE + +*****************************************************************************/ +L3INT Q931ProcConnectTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcConnectAckTE + +*****************************************************************************/ +L3INT Q931ProcConnectAckTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcProgressTE + +*****************************************************************************/ +L3INT Q931ProcProgressTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcSetupTE + +*****************************************************************************/ +L3INT Q931ProcSetupTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT rc=0; + Q931mes_Setup *pMes = (Q931mes_Setup *)&buf[Q931L4HeaderSpace]; + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + + /* Reject SETUP on existing calls */ + if(Q931GetCallState(pTrunk, pMes->CRV) != Q931_U0) + { + Q931Disconnect(pTrunk, iFrom, pMes->CRV, 81); + return Q931E_UNEXPECTED_MESSAGE; + } + + /* outgoing call */ + if(iFrom == 4) + { + ret = Q931CreateCRV(pTrunk, &callIndex); + if(ret) + return ret; + pMes->CRV = pTrunk->call[callIndex].CRV; + + ret = Q931Tx32(pTrunk,buf,pMes->Size); + if(ret) + return ret; + + Q931StartTimer(pTrunk, callIndex, 303); + + Q931SetState(pTrunk, callIndex, Q931_U1); + } + /* incoming call */ + else + { + /* Locate free CRV entry and store info */ + ret = Q931AllocateCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + { + /* Not possible to allocate CRV entry, so must reject call */ + + Q931Disconnect(pTrunk, iFrom, pMes->CRV, 42); + + return ret; + } + + /* Send setup indication to user */ + ret = Q931Tx34(pTrunk,(L3UCHAR*)pMes,pMes->Size); + if(ret != Q931E_NO_ERROR) + return ret; + else + { + /* Must be full queue, meaning we can't process the call */ + /* so we must disconnect */ + Q931Disconnect(pTrunk, iFrom, pMes->CRV, 81); + return ret; + } + + /* Set state U6 */ + Q931SetState(pTrunk, callIndex, Q931_U6); + + Q931StartTimer(pTrunk, callIndex, 303); + } + + return rc; +} + +/***************************************************************************** + + Function: Q931ProcSetupAckTE + + Description: Used to acknowedge a SETUP. Usually the first initial + response recevide back used to buy some time. L4 sending this + should only be passed on. L2 sending this means that we set + a new timer (and pass it to L4). + + Note that ChanID (B Channel Assignment) might come here from + NT side. + +*****************************************************************************/ +L3INT Q931ProcSetupAckTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + Q931StartTimer(pTrunk, callIndex, 303); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcResumeTE + +*****************************************************************************/ +L3INT Q931ProcResumeTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + Q931mes_Resume * pMes = (Q931mes_Resume *)&buf[Q931L4HeaderSpace]; +// L3INT chanIndex; + L3INT callIndex; + L3INT ret = Q931E_NO_ERROR; + + if(Q931GetCallState(pTrunk,pMes->CRV) == Q931_U0 && iFrom == 4) + { + /* Call reference selection */ + ret = Q931CreateCRV(pTrunk, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + pMes->CRV = pTrunk->call[callIndex].CRV; + + /* Send RESUME to network */ + ret=Q931Tx32(pTrunk,buf, pMes->Size); + if(ret != Q931E_NO_ERROR) + return ret; + + /* Start timer T318 */ + Q931StartTimer(pTrunk, callIndex, 318); + + /*set state U17 */ + Q931SetState(pTrunk, callIndex, Q931_U17); + } + else + { + return Q931E_ILLEGAL_MESSAGE; + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcResumeAckTE + +*****************************************************************************/ +L3INT Q931ProcResumeAckTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcResumeRejectTE + +*****************************************************************************/ +L3INT Q931ProcResumeRejectTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcSuspendTE + +*****************************************************************************/ +L3INT Q931ProcSuspendTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcSuspendAckTE + +*****************************************************************************/ +L3INT Q931ProcSuspendAckTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcSuspendRejectTE + +*****************************************************************************/ +L3INT Q931ProcSuspendRejectTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcInformationTE + +*****************************************************************************/ +L3INT Q931ProcUserInformationTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcDisconnectTE + +*****************************************************************************/ +L3INT Q931ProcDisconnectTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcReleaseTE + +*****************************************************************************/ +L3INT Q931ProcReleaseTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + Q931mes_Release *pMes = (Q931mes_Release *)&buf[Q931L4HeaderSpace]; + L3INT state = Q931GetCallState(pTrunk, pMes->CRV); + L3INT ret = Q931E_NO_ERROR; + if(state == Q931_U0 && iFrom == 2) + { + ret = Q931ReleaseComplete(pTrunk, iFrom); + } + else + { + ret = Q931ProcUnexpectedMessage(pTrunk, buf, iFrom); + } + + return ret; +} + +/***************************************************************************** + + Function: Q931ProcReleaseCompleteTE + +*****************************************************************************/ +L3INT Q931ProcReleaseCompleteTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + Q931mes_ReleaseComplete *pMes = (Q931mes_ReleaseComplete *)&buf[Q931L4HeaderSpace]; + L3INT state = Q931GetCallState(pTrunk, pMes->CRV); + L3INT ret = Q931E_NO_ERROR; + if(state == Q931_U0 && iFrom == 2) + { + /* no action */ + } + return 0; +} + +/***************************************************************************** + + Function: Q931ProcRestartTE + +*****************************************************************************/ +L3INT Q931ProcRestartTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcRestartAckTE + +*****************************************************************************/ +L3INT Q931ProcRestartAckTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcCongestionControlTE + +*****************************************************************************/ +L3INT Q931ProcCongestionControlTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcInformationTE + +*****************************************************************************/ +L3INT Q931ProcInformationTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcNotifyTE + +*****************************************************************************/ +L3INT Q931ProcNotifyTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcStatusTE + +*****************************************************************************/ +L3INT Q931ProcStatusTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcStatusEnquiryTE + +*****************************************************************************/ +L3INT Q931ProcStatusEnquiryTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcSegmentTE + +*****************************************************************************/ +L3INT Q931ProcSegmentTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/****************************************************************************/ +/******************* Q.932 - Supplementary Services *************************/ +/****************************************************************************/ + +/***************************************************************************** + + Function: Q932ProcRetrieveTE + +*****************************************************************************/ +L3INT Q932ProcFacilityTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q932ProcRetrieveTE + +*****************************************************************************/ +L3INT Q932ProcHoldTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q932ProcRetrieveTE + +*****************************************************************************/ +L3INT Q932ProcHoldAckTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q932ProcRetrieveTE + +*****************************************************************************/ +L3INT Q932ProcHoldRejectTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q932ProcRegisterTE + +*****************************************************************************/ +L3INT Q932ProcRegisterTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q932ProcRetrieveTE + +*****************************************************************************/ +L3INT Q932ProcRetrieveTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcRetrieveAckTE + +*****************************************************************************/ +L3INT Q932ProcRetrieveAckTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + +/***************************************************************************** + + Function: Q931ProcRetrieveRejectTE + +*****************************************************************************/ +L3INT Q932ProcRetrieveRejectTE(Q931_TrunkInfo *pTrunk, L3UCHAR * buf, L3INT iFrom) +{ + L3INT callIndex; + L3INT ret=Q931E_NO_ERROR; + Q931mes_Header *pMes = (Q931mes_Header *)&buf[Q931L4HeaderSpace]; + + /* Find the call using CRV */ + ret = Q931FindCRV(pTrunk, pMes->CRV, &callIndex); + if(ret != Q931E_NO_ERROR) + return ret; + + /* TODO chack against state table for illegal or unexpected message here*/ + + /* TODO - Set correct timer here */ + Q931StartTimer(pTrunk, callIndex, 303); + if(iFrom == 4) + { + /* TODO Add proc here*/ + ret = Q931Tx32(pTrunk,buf,pMes->Size); + } + else if (iFrom ==2) + { + /* TODO Add proc here*/ + ret = Q931Tx34(pTrunk,buf,pMes->Size); + } + return ret; +} + diff --git a/libs/openzap/src/isdn/Q931api.c b/libs/openzap/src/isdn/Q931api.c new file mode 100644 index 0000000000..079ae8301c --- /dev/null +++ b/libs/openzap/src/isdn/Q931api.c @@ -0,0 +1,614 @@ +/***************************************************************************** + + FileName: Q931api.c + + Contents: api (Application Programming Interface) functions. + See q931.h for description. + + License/Copyright: + + Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. + email:janvb@caselaboratories.com + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the Case Labs, Ltd nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*****************************************************************************/ + +#include "Q931.h" +#include "memory.h" + +/* +L3INT Q931CreateMesIndex(L3INT mc) +{ + if(mc < 0 || mc > 127 ) + return Q931E_INTERNAL; + + if(Q931MesCount >127) + return Q931E_INTERNAL; + + Q931MesIndex[mc] = Q931MesCount ++; + + return Q931E_NO_ERROR; +} +*/ +/* +L3INT Q931CreateIEIndex(L3INT iec) +{ + if(iec < 0 || iec > 127 ) + return Q931E_INTERNAL; + + if(Q931IECount > 127) + return Q931E_INTERNAL; + + Q931IEIndex[iec] = Q931IECount ++; + + return Q931E_NO_ERROR; +} +*/ + +void Q931Api_InitTrunk(Q931_TrunkInfo *pTrunk) +{ + int y; + pTrunk->LastCRV = 0; + pTrunk->Dialect = 0; + pTrunk->Enabled = 0; + pTrunk->TrunkType = Q931_TrType_E1; + pTrunk->NetUser = Q931_TE; + pTrunk->TrunkState = 0; + for(y=0; y < Q931MAXCHPERTRUNK; y++) + { + pTrunk->ch[y].Available = 1; + + /* Set up E1 scheme by default */ + if(y==0) + { + pTrunk->ch[y].ChanType = Q931_ChType_Sync; + } + else if(y==16) + { + pTrunk->ch[y].ChanType = Q931_ChType_D; + } + else + { + pTrunk->ch[y].ChanType = Q931_ChType_B; + } + } + + for(y=0; y < Q931MAXCALLPERTRUNK; y++) + { + pTrunk->call[y].InUse = 0; + + } +} + +void Q931SetMesProc(L3UCHAR mes, L3UCHAR dialect, + L3INT (*Q931ProcFunc)(Q931_TrunkInfo *pTrunk, L3UCHAR * b, L3INT iFrom), + L3INT (*Q931UmesFunc)(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT Size), + L3INT (*Q931PmesFunc)(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +) +{ + if(Q931ProcFunc != NULL) + Q931Proc[dialect][mes] = Q931ProcFunc; + if(Q931UmesFunc != NULL) + Q931Umes[dialect][mes] = Q931UmesFunc; + if(Q931PmesFunc != NULL) + Q931Pmes[dialect][mes] = Q931PmesFunc; +} + +void Q931SetIEProc(L3UCHAR iec, L3UCHAR dialect, + L3INT (*Q931PieProc)(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet), + L3INT (*Q931UieProc)(Q931_TrunkInfo *pTrunk, ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) +) +{ + if(Q931PieProc != NULL) + Q931Pie[dialect][iec] = Q931PieProc; + if(Q931UieProc != NULL) + Q931Uie[dialect][iec] = Q931UieProc; +} + +#define trampoline(x) {x * t = (x *)pm; s = &t->buf[0];} + +/***************************************************************************** + + Function: Q931GetIEBuf + + Description: Return a ptr to the buf used for IE in the message. + +*****************************************************************************/ +L3UCHAR * Q931GetIEBuf(L3UCHAR *pm) +{ + L3UCHAR * s=NULL; + Q931mes_Alerting * pMes= (Q931mes_Alerting *)pm; + switch(pMes->MesType) + { + case Q931mes_ALERTING : + trampoline(Q931mes_Alerting); + break; + + case Q931mes_CALL_PROCEEDING : + trampoline(Q931mes_CallProceeding); + break; + + case Q931mes_CONNECT : + trampoline(Q931mes_Connect); + break; + + case Q931mes_CONNECT_ACKNOWLEDGE : + trampoline(Q931mes_ConnectAck); + break; + + case Q931mes_PROGRESS : + trampoline(Q931mes_Progress); + break; + + case Q931mes_SETUP : + trampoline(Q931mes_Setup); + break; + + case Q931mes_SETUP_ACKNOWLEDGE : + trampoline(Q931mes_SetupAck); + break; + + case Q931mes_RESUME : + trampoline(Q931mes_Resume); + break; + + case Q931mes_RESUME_ACKNOWLEDGE : + trampoline(Q931mes_ResumeAck); + break; + + case Q931mes_RESUME_REJECT : + trampoline(Q931mes_ResumeReject); + break; + + case Q932mes_RETRIEVE : + trampoline(Q932mes_Retrieve); + break; + + case Q932mes_RETRIEVE_ACKNOWLEDGE : + trampoline(Q932mes_RetrieveAck); + break; + + case Q932mes_RETRIEVE_REJECT : + trampoline(Q932mes_RetrieveReject); + break; + + case Q931mes_SUSPEND : + trampoline(Q931mes_Suspend); + break; + + case Q931mes_SUSPEND_ACKNOWLEDGE : + trampoline(Q931mes_SuspendAck); + break; + + case Q931mes_SUSPEND_REJECT : + trampoline(Q931mes_SuspendReject); + break; + + case Q931mes_USER_INFORMATION : + trampoline(Q931mes_UserInformation); + break; + + case Q931mes_DISCONNECT : + trampoline(Q931mes_Disconnect); + break; + + case Q931mes_RELEASE : + trampoline(Q931mes_Release); + break; + + case Q931mes_RELEASE_COMPLETE : + trampoline(Q931mes_ReleaseComplete); + break; + + case Q931mes_RESTART : + trampoline(Q931mes_Restart); + break; + + case Q931mes_RESTART_ACKNOWLEDGE : + trampoline(Q931mes_RestartAck); + break; + + case Q931mes_CONGESTION_CONTROL : + trampoline(Q931mes_CongestionControl); + break; + +// case Q931mes_FACILITY : +// trampoline(Q931mes_Facility); +// break; + + case Q931mes_INFORMATION : + trampoline(Q931mes_Information); + break; + + case Q931mes_NOTIFY : + trampoline(Q931mes_Notify); + break; + +// case Q931mes_REGISTER : +// trampoline(Q931mes_Register); +// break; + + case Q931mes_STATUS : + trampoline(Q931mes_Status); + break; + + case Q931mes_STATUS_ENQUIRY : + trampoline(Q931mes_StatusEnquiry); + break; + + case Q931mes_SEGMENT : + trampoline(Q931mes_Segment); + break; + + default: + s = 0; + break; + } + + return s; +} + +L3INT Q931GetMesSize(L3UCHAR *pMes) +{ + + L3UCHAR *p = Q931GetIEBuf(pMes); + L3INT Size = (L3INT)(p - pMes); + return Size; +} + +/***************************************************************************** + + Function: q931AppendIE + + Description: Append IE to the message. + + Parameters: pm Ptr to message. + pi Ptr to information element + + Return Value ie setting + +*****************************************************************************/ + +ie Q931AppendIE( L3UCHAR *pm, L3UCHAR *pi) +{ + ie IE = 0; + Q931mes_Alerting * pMes= (Q931mes_Alerting *)pm; + Q931ie_BearerCap * pIE= (Q931ie_BearerCap *)pi; + L3INT iISize = pIE->Size; + + L3UCHAR *pBuf = Q931GetIEBuf(pm); + L3INT Off = pMes->Size - (pBuf - pm); + IE = Off | 0x8000; + + memcpy(&pm[pMes->Size], pi, iISize); + + pMes->Size += iISize; + + return IE; +} + +/***************************************************************************** +*****************************************************************************/ +L3INT Q931GetUniqueCRV(Q931_TrunkInfo *pTrunk) +{ + static L3INT crv={1}; + return crv++; +} + +L3INT Q931InitMesSetup(Q931mes_Setup *pMes) +{ + pMes->ProtDisc = 0x80; + pMes->CRV = 0; /* CRV to be allocated, might be receive*/ + pMes->MesType = Q931mes_SETUP; + + pMes->Size = Q931GetMesSize((L3UCHAR*)pMes); + + pMes->SendComplete =0; /* Sending Complete */ + pMes->RepeatInd =0; /* Repeat Indicator */ + pMes->BearerCap =0; /* Bearer Capability */ + pMes->ChanID =0; /* Channel ID */ + pMes->ProgInd =0; /* Progress Indicator */ + pMes->NetFac =0; /* Network-specific facilities */ + pMes->Display =0; /* Display */ + pMes->DateTime =0; /* Date/Time */ + pMes->KeypadFac =0; /* Keypad Facility */ + pMes->Signal =0; /* Signal */ + pMes->CallingNum =0; /* Calling party number */ + pMes->CallingSub =0; /* Calling party sub address */ + pMes->CalledNum =0; /* Called party number */ + pMes->CalledSub =0; /* Called party sub address */ + pMes->TransNetSel =0; /* Transit network selection */ + pMes->LLRepeatInd =0; /* Repeat Indicator 2 LLComp */ + pMes->LLComp =0; /* Low layer compatibility */ + pMes->HLComp =0; /* High layer compatibility */ + + return 0; +} + +L3INT Q931InitMesResume(Q931mes_Resume * pMes) +{ + pMes->ProtDisc = 0x80; + pMes->CRV = 0; /* CRV to be allocated, might be receive*/ + pMes->MesType = Q931mes_RESUME; + + pMes->Size = Q931GetMesSize((L3UCHAR*)pMes); + pMes->CallID = 0; /* Channel Identification */ + return 0; +} + +L3INT Q931InitIEBearerCap(Q931ie_BearerCap *pIE) +{ + pIE->IEId = Q931ie_BEARER_CAPABILITY; + pIE->Size = sizeof(Q931ie_BearerCap); + pIE->CodStand = 0; + pIE->ITC = 0; + pIE->TransMode = 0; + pIE->ITR = 0x10; + pIE->RateMul = 0; + + pIE->Layer1Ident = 0; + pIE->UIL1Prot = 0; /* User Information Layer 1 Protocol */ + pIE->SyncAsync = 0; /* Sync/Async */ + pIE->Negot = 0; + pIE->UserRate = 0; + pIE->InterRate = 0; /* Intermediate Rate */ + pIE->NIConTx = 0; + pIE->NIConRx = 0; + pIE->FlowCtlTx = 0; /* Flow control on Tx */ + pIE->FlowCtlRx = 0; /* Flow control on Rx */ + pIE->HDR = 0; + pIE->MultiFrame = 0; /* Multi frame support */ + pIE->Mode = 0; + pIE->LLInegot = 0; + pIE->Assignor = 0; /* Assignor/assignee */ + pIE->InBandNeg = 0; /* In-band/out-band negot. */ + pIE->NumStopBits = 0; /* Number of stop bits */ + pIE->NumDataBits = 0; /* Number of data bits. */ + pIE->Parity = 0; + pIE->DuplexMode = 0; + pIE->ModemType = 0; + pIE->Layer2Ident = 0; + pIE->UIL2Prot = 0; /* User Information Layer 2 Protocol */ + pIE->Layer3Ident = 0; + pIE->UIL3Prot = 0; /* User Information Layer 3 Protocol */ + pIE->AL3Info1 = 0; + pIE->AL3Info2 = 0; + + return 0; +} + +L3INT Q931InitIEChanID(Q931ie_ChanID *pIE) +{ + pIE->IEId = Q931ie_CHANNEL_IDENTIFICATION; + pIE->Size = sizeof(Q931ie_ChanID); + pIE->IntIDPresent = 0; /* Int. id. present */ + pIE->IntType = 0; /* Int. type */ + pIE->PrefExcl = 0; /* Pref./Excl. */ + pIE->DChanInd = 0; /* D-channel ind. */ + pIE->InfoChanSel = 0; /* Info. channel selection */ + pIE->InterfaceID = 0; /* Interface identifier */ + pIE->CodStand = 0; /* Code standard */ + pIE->NumMap = 0; /* Number/Map */ + pIE->ChanMapType = 0; /* Channel type/Map element type */ + pIE->ChanSlot = 0; /* Channel number/Slot map */ + + return 0; +} + +L3INT Q931InitIEProgInd(Q931ie_ProgInd * pIE) +{ + pIE->IEId = Q931ie_PROGRESS_INDICATOR; + pIE->Size = sizeof(Q931ie_ProgInd); + pIE->CodStand = 0; /* Coding standard */ + pIE->Location = 0; /* Location */ + pIE->ProgDesc = 0; /* Progress description */ + + return 0; +} + +L3INT Q931InitIENetFac(Q931ie_NetFac * pIE) +{ + pIE->IEId = Q931ie_NETWORK_SPECIFIC_FACILITIES; + pIE->Size = sizeof(Q931ie_NetFac); + pIE->LenNetID = 0; /* Length of network facilities id. */ + pIE->TypeNetID = 0; /* Type of network identification */ + pIE->NetIDPlan = 0; /* Network identification plan. */ + pIE->NetFac = 0; /* Network specific facility spec. */ + pIE->NetID[0] = 0; + return 0; +} + +L3INT Q931InitIEDisplay(Q931ie_Display * pIE) +{ + pIE->IEId = Q931ie_DISPLAY; + pIE->Size = sizeof(Q931ie_Display); + pIE->Display[0] = 0; + return 0; +} + +L3INT Q931InitIEDateTime(Q931ie_DateTime * pIE) +{ + pIE->IEId = Q931ie_DATETIME; + pIE->Size = sizeof(Q931ie_DateTime); + pIE->Year = 0; /* Year */ + pIE->Month = 0; /* Month */ + pIE->Day = 0; /* Day */ + pIE->Hour = 0; /* Hour */ + pIE->Minute = 0; /* Minute */ + pIE->Second = 0; /* Second */ + + return 0; +} + +L3INT Q931InitIEKeypadFac(Q931ie_KeypadFac * pIE) +{ + pIE->IEId = Q931ie_KEYPAD_FACILITY; + pIE->Size = sizeof(Q931ie_KeypadFac); + pIE->KeypadFac[0] = 0; + return 0; +} + +L3INT Q931InitIESignal(Q931ie_Signal * pIE) +{ + pIE->IEId = Q931ie_SIGNAL; + pIE->Size = sizeof(Q931ie_Signal); + pIE->Signal = 0; + return 0; +} + +L3INT Q931InitIECallingNum(Q931ie_CallingNum * pIE) +{ + pIE->IEId = Q931ie_CALLING_PARTY_NUMBER; + pIE->Size = sizeof(Q931ie_CallingNum); + pIE->TypNum = 0; /* Type of number */ + pIE->NumPlanID = 0; /* Numbering plan identification */ + pIE->PresInd = 0; /* Presentation indicator */ + pIE->ScreenInd = 0; /* Screening indicator */ + pIE->Digit[0] = 0; /* Number digits (IA5) */ + + return 0; +} + +L3INT Q931InitIECallingSub(Q931ie_CallingSub * pIE) +{ + pIE->IEId = Q931ie_CALLING_PARTY_SUBADDRESS; + pIE->Size = sizeof(Q931ie_CallingSub); + pIE->TypNum = 0; /* Type of subaddress */ + pIE->OddEvenInd = 0; /* Odd/Even indicator */ + pIE->Digit[0] = 0; /* Digits */ + + return 0; +} + +L3INT Q931InitIECalledNum(Q931ie_CalledNum * pIE) +{ + pIE->IEId = Q931ie_CALLED_PARTY_NUMBER; + pIE->Size = sizeof(Q931ie_CalledNum); + pIE->TypNum = 0; /* Type of Number */ + pIE->NumPlanID = 0; /* Numbering plan identification */ + pIE->Digit[0] = 0; /* Digit (IA5) */ + + return 0; +} + +L3INT Q931InitIECalledSub(Q931ie_CalledSub * pIE) +{ + pIE->IEId = Q931ie_CALLED_PARTY_SUBADDRESS; + pIE->Size = sizeof(Q931ie_CalledSub); + pIE->TypNum = 0; /* Type of subaddress */ + pIE->OddEvenInd = 0; /* Odd/Even indicator */ + pIE->Digit[0] = 0; /* Digits */ + + return 0; +} + +L3INT Q931InitIETransNetSel(Q931ie_TransNetSel * pIE) +{ + pIE->IEId = Q931ie_TRANSIT_NETWORK_SELECTION; + pIE->Size = sizeof(Q931ie_TransNetSel); + pIE->Type = 0; /* Type of network identifier */ + pIE->NetIDPlan = 0; /* Network idetification plan */ + pIE->NetID[0] = 0; /* Network identification(IA5) */ + + return 0; +} + +L3INT Q931InitIELLComp(Q931ie_LLComp * pIE) +{ + pIE->IEId = Q931ie_LOW_LAYER_COMPATIBILITY; + pIE->Size = sizeof(Q931ie_LLComp); + + pIE->CodStand = 0; /* Coding standard */ + pIE->ITransCap = 0; /* Information transfer capability */ + pIE->NegotInd = 0; /* Negot indic. */ + pIE->TransMode = 0; /* Transfer Mode */ + pIE->InfoRate = 0; /* Information transfer rate */ + pIE->RateMul = 0; /* Rate multiplier */ + pIE->Layer1Ident = 0; /* Layer 1 ident. */ + pIE->UIL1Prot = 0; /* User information layer 1 protocol */ + pIE->SyncAsync = 0; /* Synch/asynch */ + pIE->Negot = 0; /* Negot */ + pIE->UserRate = 0; /* User rate */ + pIE->InterRate = 0; /* Intermediate rate */ + pIE->NIConTx = 0; /* NIC on Tx */ + pIE->NIConRx = 0; /* NIC on Rx */ + pIE->FlowCtlTx = 0; /* Flow control on Tx */ + pIE->FlowCtlRx = 0; /* Flow control on Rx */ + pIE->HDR = 0; /* Hdr/no hdr */ + pIE->MultiFrame = 0; /* Multiframe */ + pIE->ModeL1 = 0; /* Mode L1 */ + pIE->NegotLLI = 0; /* Negot. LLI */ + pIE->Assignor = 0; /* Assignor/Assignor ee */ + pIE->InBandNeg = 0; /* In-band negot. */ + pIE->NumStopBits = 0; /* Number of stop bits */ + pIE->NumDataBits = 0; /* Number of data bits */ + pIE->Parity = 0; /* Parity */ + pIE->DuplexMode = 0; /* Duplex Mode */ + pIE->ModemType = 0; /* Modem type */ + pIE->Layer2Ident = 0; /* Layer 2 ident. */ + pIE->UIL2Prot = 0; /* User information layer 2 protocol */ + pIE->ModeL2 = 0; /* ModeL2 */ + pIE->Q933use = 0; /* Q.9333 use */ + pIE->UsrSpcL2Prot = 0; /* User specified layer 2 protocol info */ + pIE->WindowSize = 0; /* Window size (k) */ + pIE->Layer3Ident = 0; /* Layer 3 ident */ + pIE->OptL3Info = 0; /* Optional layer 3 protocol info. */ + pIE->ModeL3 = 0; /* Mode of operation */ +// pIE->ModeX25op = 0; /* Mode of operation X.25 */ + pIE->DefPackSize = 0; /* Default packet size */ + pIE->PackWinSize = 0; /* Packet window size */ + pIE->AddL3Info = 0; /* Additional Layer 3 protocol info */ + + return 0; +} + +L3INT Q931InitIEHLComp(Q931ie_HLComp * pIE) +{ + pIE->IEId = Q931ie_HIGH_LAYER_COMPATIBILITY; + pIE->Size = sizeof(Q931ie_HLComp); + + return 0; +} + +L3INT Q931ProcUnknownMessage(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom) +{ + return 0; +} + +L3INT Q931ProcUnexpectedMessage(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom) +{ + return 0; +} + +L3INT Q931Disconnect(Q931_TrunkInfo *pTrunk, L3INT iTo, L3INT iCRV, L3INT iCause) +{ + return 0; +} + +L3INT Q931ReleaseComplete(Q931_TrunkInfo *pTrunk, L3INT iTo) +{ + return 0; +} diff --git a/libs/openzap/src/isdn/Q931ie.c b/libs/openzap/src/isdn/Q931ie.c new file mode 100644 index 0000000000..d9cddbb16d --- /dev/null +++ b/libs/openzap/src/isdn/Q931ie.c @@ -0,0 +1,2951 @@ +/***************************************************************************** + + FileName: Q931ie.c + + Contents: Information Element Pack/Unpack functions. + + These functions will pack out a Q931 message from the bit + packed original format into structs that are easier to process + and pack the same structs back into bit fields when sending + messages out. + + The messages contains a short for each possible IE. The MSB + bit flags the precense of an IE, while the remaining bits + are the offset into a buffer to find the actual IE. + + Each IE are supported by 3 functions: + + Q931Pie_XXX Pack struct into Q.931 IE + Q931Uie_XXX Unpack Q.931 IE into struct + Q931InitIEXXX Initialize IE (see Q931api.c). + + Dialect Note: This file will only contain standard DSS1 IE. Other IE as + used in QSIG, NI2, Q.932 etc are located in separate files. + + See q931.h for description. + + License/Copyright: + + Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. + email:janvb@caselaboratories.com + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the Case Labs, Ltd nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*****************************************************************************/ + +#include "Q931.h" + +/***************************************************************************** + + Macro: Q931MoreIE + + Description: Local helper macro detecting if there is more IE space left + based on the 3 standard parameters Octet, Off and IESpace. + This can be used to test if the IE is completed to avoid + that the header of the next IE is interpreted as a part of + the current IE. + +*****************************************************************************/ +#define Q931MoreIE() (Octet+Off - 2 < IESize) + +#define Q931IESizeTest(x) {\ + if(Octet+Off-2 != IESize)\ + {\ + Q931SetError(pTrunk,x, Octet, Off);\ + return x;\ + }\ + } + +/***************************************************************************** + + Function: Q931ReadExt + + Description: Many of the octets in the standard have an MSB 'ext.1'. This + means that the octet usually is the latest octet, but that a + futhure standard may extend the octet. A stack must be able + to handle such extensions by skipping the extension octets. + + This function will increase the offset counter with 1 for + each octet with an MSB of zero. This will allow the stack to + skip extensions wihout knowing anything about them. + + Parameters: IBuf ptr to octet array. + Off Starting offset counter + + Return Value: New offset value. + +*****************************************************************************/ + +L3INT Q931ReadExt(L3UCHAR * IBuf, L3INT Off) +{ + L3INT c =0; + while((IBuf[c] & 0x80) == 0) + c++; + + return Off + c; +} + +/***************************************************************************** + + Function: Q931Uie_BearerCap + + Description: Unpack a bearer capability ie. + + Parameters: pIE[OUT] ptr to Information Element id. + IBuf[IN] ptr to a packed ie. + OBuf[OUT] ptr to buffer for Unpacked ie. + IOff[IN\OUT] Input buffer offset + OOff[IN\OUT] Output buffer offset + + Ibuf and OBuf points directly to buffers. The IOff and OOff + must be updated, but are otherwise not used in the ie unpack. + + Return Value: Error Message + +*****************************************************************************/ + +L3INT Q931Uie_BearerCap(Q931_TrunkInfo *pTrunk, ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) +{ + Q931ie_BearerCap * pie = (Q931ie_BearerCap*)OBuf; + L3INT Off = 0; + L3INT Octet = 0; + L3INT IESize; + *pIE=0; + + /* Octet 1 */ + pie->IEId = IBuf[Octet]; + Octet ++; + + /* Octet 2 */ + IESize = IBuf[Octet ++]; + + /* Octet 3 */ + pie->CodStand = ieGetOctet((IBuf[Octet] & 0x60) >> 5); + pie->ITC = ieGetOctet(IBuf[Octet] & 0x1f); + Off = Q931ReadExt(&IBuf[Octet], Off); + Octet++; + + /* Octet 4 */ + pie->TransMode = ieGetOctet((IBuf[Octet+Off] & 0x60) >> 5); + pie->ITR = ieGetOctet(IBuf[Octet+Off] & 0x1f); + Off = Q931ReadExt(&IBuf[Octet+Off], Off); + Octet++; + + /* Octet 4.1. Rate multiplier is only present if ITR = Multirate */ + if(pie->ITR == 0x18) + { + pie->RateMul = ieGetOctet(IBuf[Octet+Off] & 0x7f); + Off = Q931ReadExt(&IBuf[Octet+Off], Off); + Off ++; + } + + /* Octet 5 */ + if((IBuf[Octet+Off] & 0x60) == 0x20 && Q931MoreIE()) + { + pie->Layer1Ident = ieGetOctet((IBuf[Octet+Off] & 0x60) >> 5); + pie->UIL1Prot = ieGetOctet(IBuf[Octet+Off] & 0x1f); + Octet++; + + /* Octet 5a. The octet may be present if ITC is unrestrictd digital info*/ + /* and UIL1Prot is either V.110, I.460 and X.30 or V.120. It may also */ + /* be present if ITC = 3.1 kHz audio and UIL1Prot is G.711. */ + /* Bit 8 of Octet 5 = 0 indicates that 5a is present. */ + + if(IsQ931Ext(IBuf[Octet+Off-1])) + { + if(((pie->ITC == 0x08) && (pie->UIL1Prot == 0x01 || pie->UIL1Prot == 0x08)) + || ((pie->ITC == 0x10) && (pie->UIL1Prot == 0x02 || pie->UIL1Prot == 0x03))) + { + pie->SyncAsync = ieGetOctet((IBuf[Octet+Off] & 0x40) >> 6); + pie->Negot = ieGetOctet((IBuf[Octet+Off] & 0x20) >> 5); + pie->UserRate = ieGetOctet(IBuf[Octet+Off] & 0x1f); + Off ++; + } + else + { + /* We have detected bit 8 = 0, but no setting that require the */ + /* additional octets ??? */ + Q931SetError(pTrunk, Q931E_BEARERCAP, 5,Off); + return Q931E_BEARERCAP; + } + + /* Octet 5b. Two different structures used. */ + if(IsQ931Ext(IBuf[Octet+Off-1])) + { + if(pie->UIL1Prot == 0x01) /* ITU V.110, I.460 and X.30 */ + { + pie->InterRate = ieGetOctet((IBuf[Octet+Off] & 0x60) >> 5); + pie->NIConTx = ieGetOctet((IBuf[Octet+Off] & 0x10) >> 4); + pie->NIConRx = ieGetOctet((IBuf[Octet+Off] & 0x08) >> 3); + pie->FlowCtlTx = ieGetOctet((IBuf[Octet+Off] & 0x04) >> 2); + pie->FlowCtlRx = ieGetOctet((IBuf[Octet+Off] & 0x20) >> 1); + Off++; + } + else if(pie->UIL1Prot == 0x08) /* ITU V.120 */ + { + pie->HDR = ieGetOctet((IBuf[Octet+Off] & 0x40) >> 6); + pie->MultiFrame = ieGetOctet((IBuf[Octet+Off] & 0x20) >> 5); + pie->Mode = ieGetOctet((IBuf[Octet+Off] & 0x10) >> 4); + pie->LLInegot = ieGetOctet((IBuf[Octet+Off] & 0x08) >> 3); + pie->Assignor = ieGetOctet((IBuf[Octet+Off] & 0x04) >> 2); + pie->InBandNeg = ieGetOctet((IBuf[Octet+Off] & 0x02) >> 1); + Off++; + } + else + { + Q931SetError(pTrunk,Q931E_BEARERCAP, 5,Off); + return Q931E_BEARERCAP; + + } + + /* Octet 5c */ + if(IsQ931Ext(IBuf[Octet+Off-1])) + { + + pie->NumStopBits = ieGetOctet((IBuf[Octet+Off] & 0x60) >> 5); + pie->NumDataBits = ieGetOctet((IBuf[Octet+Off] & 0x18) >> 3); + pie->Parity = ieGetOctet(IBuf[Octet+Off] & 0x07); + Off++; + + /* Octet 5d */ + if(IsQ931Ext(IBuf[Octet+Off-1])) + { + + pie->DuplexMode = ieGetOctet((IBuf[Octet+Off] & 0x40) >> 6); + pie->ModemType = ieGetOctet(IBuf[Octet+Off] & 0x3f); + Off ++; + } + } + } + } + } + + /* Octet 6 */ + if((IBuf[Octet+Off] & 0x60) == 0x40 && Q931MoreIE()) + { + pie->Layer2Ident = ieGetOctet((IBuf[Octet+Off] & 0x60) >> 5); + pie->UIL2Prot = ieGetOctet(IBuf[Octet+Off] & 0x1f); + + Off = Q931ReadExt(&IBuf[Octet+Off], Off); + Octet ++; + } + + /* Octet 7 */ + if((IBuf[Octet+Off] & 0x60) == 0x60 && Q931MoreIE()) + { + pie->Layer3Ident = ieGetOctet((IBuf[Octet+Off] & 0x60) >> 5); + pie->UIL3Prot = ieGetOctet(IBuf[Octet+Off] & 0x1f); + Octet++; + + /* Octet 7a */ + if(IsQ931Ext(IBuf[Octet+Off-1])) + { + if(pie->UIL3Prot == 0x0c) + { + pie->AL3Info1 = ieGetOctet(IBuf[Octet+Off] & 0x0f); + Off++; + + /* Octet 7b */ + if(IsQ931Ext(IBuf[Octet+Off])) + { + pie->AL3Info2 = ieGetOctet(IBuf[Octet+Off] & 0x0f); + Off++; + } + } + else + { + Q931SetError(pTrunk,Q931E_BEARERCAP, 7, Off); + return Q931E_BEARERCAP; + + } + } + } + + Q931IESizeTest(Q931E_BEARERCAP); + + *IOff = (*IOff) + Octet + Off; + *OOff = (*OOff) + sizeof(Q931ie_BearerCap); + pie->Size = sizeof(Q931ie_BearerCap); + + Q931SetIE(*pIE, *OOff); + + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pie_BearerCap + + Description: Packing a Q.931 Bearer Capability element from a generic + struct into a packed octet structure in accordance with the + standard. + + Parameters: IBuf[IN] Ptr to struct. + OBuf[OUT] Ptr tp packed output buffer. + Octet[IN/OUT] Offset into OBuf. + + Return Value: Error code, 0 = OK + +*****************************************************************************/ + +L3INT Q931Pie_BearerCap(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) +{ + Q931ie_BearerCap * pIE = (Q931ie_BearerCap*)IBuf; + L3INT rc=0; + L3INT Beg=*Octet;/* remember current offset */ + L3INT li; + + OBuf[(*Octet)++] = Q931ie_BEARER_CAPABILITY ; + li=(*Octet)++; /* remember length position */ + + /* Octet 3 - Coding standard / Information transfer capability */ + OBuf[(*Octet)++] = 0x80 | (pIE->CodStand<<5) | (pIE->ITR & 0x1f); + + /* Octet 4 - Transfer mode / Information transfer rate */ + if(pIE->ITR == 0x18) + { + OBuf[(*Octet)++] = 0x80 | (pIE->TransMode<<5) | (pIE->ITR & 0x1f); + } + else + { + OBuf[(*Octet)++] = 0x00 | (pIE->TransMode<<5) | (pIE->ITR & 0x1f); + + /* Octet 4.1 - Rate Multiplier */ + OBuf[(*Octet)++] = 0x80 | pIE->RateMul; + } + + /* Octet 5 - Layer 1 Ident / User information layer 1 protocol*/ + if(pIE->Layer1Ident == 0x01) + { + if(((pIE->ITC == 0x08) && (pIE->UIL1Prot == 0x01 || pIE->UIL1Prot == 0x08)) + || ((pIE->ITC == 0x10) && (pIE->UIL1Prot == 0x02 || pIE->UIL1Prot == 0x03))) + { + OBuf[(*Octet)++] = 0x00 | (pIE->Layer1Ident<<5) | (pIE->UIL1Prot & 0x15); + + /* Octet 5a - SyncAsync/Negot/UserRate */ + OBuf[(*Octet)++] = 0x00 | (pIE->SyncAsync<<6) | (pIE->Negot<<5) | (pIE->UserRate&0x1f); + + /* Octet 5b - one of two types */ + if(pIE->UIL1Prot == 0x01) /* ITU V.110, I.460 and X.30 */ + { + /* Octet 5b - Intermed rate/ Nic on Tx/Nix on Rx/FlowCtlTx/FlowCtlRx */ + OBuf[(*Octet)++] = 0x00 + | (pIE->InterRate<<6) + | (pIE->NIConTx << 4) + | (pIE->NIConRx << 3) + | (pIE->FlowCtlTx << 2) + | (pIE->FlowCtlRx << 1); + } + else if(pIE->UIL1Prot == 0x08) /* ITU V.120 */ + { + /* Octet 5b - HDR/Multiframe/Mode/LLINegot/Assignor/Inbandneg*/ + OBuf[(*Octet)++] = 0x00 + | (pIE->InterRate << 6) + | (pIE->MultiFrame << 5) + | (pIE->Mode << 4) + | (pIE->LLInegot << 3) + | (pIE->Assignor << 2) + | (pIE->InBandNeg << 1); + } + + /* Octet 5c - NumStopBits/NumStartBits/Parity */ + OBuf[(*Octet)++] = 0x00 + | (pIE->NumStopBits << 5 ) + | (pIE->NumDataBits << 3 ) + | (pIE->Parity); + + /* Octet 5d - Duplex Mode/Modem Type */ + OBuf[(*Octet)++] = 0x80 | (pIE->DuplexMode<<6) | (pIE->ModemType); + } + else + { + OBuf[(*Octet)++] = 0x80 | (pIE->Layer1Ident<<5) | (pIE->UIL1Prot & 0x15); + } + } + + /* Octet 6 - Layer2Ident/User information layer 2 prtocol */ + if(pIE->Layer2Ident == 0x02) + { + OBuf[(*Octet)++] = 0x80 | (pIE->Layer2Ident<<5) | (pIE->UIL2Prot); + } + + /* Octet 7 - Layer 3 Ident/ User information layer 3 protocol */ + if(pIE->Layer3Ident == 0x03) + { + if(pIE->UIL3Prot == 0x0c) + { + OBuf[(*Octet)++] = 0x00 | (pIE->Layer3Ident<<5) | (pIE->UIL3Prot); + + /* Octet 7a - Additional information layer 3 msb */ + OBuf[(*Octet)++] = 0x00 | (pIE->AL3Info1); + + /* Octet 7b - Additional information layer 3 lsb */ + OBuf[(*Octet)++] = 0x80 | (pIE->AL3Info2); + } + else + { + OBuf[(*Octet)++] = 0x80 | (pIE->Layer3Ident<<5) | (pIE->UIL3Prot); + } + } + + OBuf[li] = (*Octet)-Beg; + return rc; +} + +/***************************************************************************** + + Function: Q931Uie_CallID + + Parameters: pIE[OUT] ptr to Information Element id. + IBuf[IN] ptr to a packed ie. + OBuf[OUT] ptr to buffer for Unpacked ie. + IOff[IN\OUT] Input buffer offset + OOff[IN\OUT] Output buffer offset + + + Ibuf and OBuf points directly to buffers. The IOff and OOff + must be updated, but are otherwise not used in the ie unpack. + + Return Value: Error Message + +*****************************************************************************/ +L3INT Q931Uie_CallID(Q931_TrunkInfo *pTrunk, ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) +{ + Q931ie_CallID * pie = (Q931ie_CallID*)OBuf; + L3INT Off = 0; + L3INT Octet = 0; + L3INT x=0; + L3INT IESize; + + *pIE=0; + + /* Octet 1 */ + pie->IEId = IBuf[Octet]; + Octet ++; + + /* Octet 2 */ + IESize = IBuf[Octet ++]; + + /* Octet 3 */ + do{ + pie->CallId[x] = IBuf[Octet+Off] & 0x7f; + Off++; + x++; + }while(IBuf[Octet+Off]&0x80 != 0 && x < 10); + + Q931IESizeTest(Q931E_CALLID); + + *IOff = (*IOff) + Octet + Off; + *OOff = (*OOff) + sizeof(Q931ie_CallID) + x -1; + pie->Size = sizeof(Q931ie_CallID) + x -1; + + Q931SetIE(*pIE, *OOff); + + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pie_CallID + + Parameters: IBuf[IN] Ptr to struct. + OBuf[OUT] Ptr tp packed output buffer. + Octet[IN/OUT] Offset into OBuf. + + Return Value: Error code, 0 = OK + +*****************************************************************************/ + +L3INT Q931Pie_CallID(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) +{ + Q931ie_CallID * pIE = (Q931ie_CallID*)IBuf; + L3INT rc=0; + L3INT Beg=*Octet;/* remember current offset */ + L3INT li; + L3INT sCI = pIE->Size - sizeof(Q931ie_CallID) + 1; + L3INT x; + + OBuf[(*Octet)++] = Q931ie_CALL_IDENTITY ; + li=(*Octet)++; /* remember length position */ + + for(x=0;x < sCI; x++) + { + OBuf[(*Octet)++] = pIE->CallId[x]; + } + + OBuf[(*Octet)-1] |= 0x80; /* set complete flag at last octet*/ + + OBuf[li] = (*Octet)-Beg; + return rc; +} + +/***************************************************************************** + + Function: Q931Uie_CallState + + Parameters: pIE[OUT] ptr to Information Element id. + IBuf[IN] ptr to a packed ie. + OBuf[OUT] ptr to buffer for Unpacked ie. + IOff[IN\OUT] Input buffer offset + OOff[IN\OUT] Output buffer offset + + Ibuf and OBuf points directly to buffers. The IOff and OOff + must be updated, but are otherwise not used in the ie unpack. + + Return Value: Error Message + +*****************************************************************************/ +L3INT Q931Uie_CallState(Q931_TrunkInfo *pTrunk, ie *pIE,L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) +{ + Q931ie_CallState * pie = (Q931ie_CallState*)OBuf; + L3INT Off = 0; + L3INT Octet = 0; + L3INT IESize; + + *pIE=0; + + /* Octet 1 */ + pie->IEId = IBuf[Octet]; + Octet ++; + + /* Octet 2 */ + IESize = IBuf[Octet ++]; + + + /* Octet 3 */ + pie->CodStand = (IBuf[Octet+Off] >> 6) & 0x03; + pie->CallState= IBuf[Octet+Off] & 0x3f; + + Octet++; + + Q931IESizeTest(Q931E_CALLSTATE); + + *IOff = (*IOff) + Octet + Off; + *OOff = (*OOff) + sizeof(Q931ie_CallState); + pie->Size = sizeof(Q931ie_CallState); + + Q931SetIE(*pIE, *OOff); + + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pie_CallState + + Parameters: IBuf[IN] Ptr to struct. + OBuf[OUT] Ptr tp packed output buffer. + Octet[IN/OUT] Offset into OBuf. + + Return Value: Error code, 0 = OK + +*****************************************************************************/ +L3INT Q931Pie_CallState(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) +{ + Q931ie_CallState * pIE = (Q931ie_CallState*)IBuf; + L3INT rc=0; + L3INT Beg=*Octet;/* remember current offset */ + L3INT li; + + OBuf[(*Octet)++] = Q931ie_CALL_STATE; + li=(*Octet)++; /* remember length position */ + + OBuf[(*Octet)++] = 0x80 | (pIE->CodStand<<6) | pIE->CallState; + + OBuf[li] = (*Octet)-Beg; + return rc; +} + +/***************************************************************************** + + Function: Q931Uie_CalledSub + + Parameters: pIE[OUT] ptr to Information Element id. + IBuf[IN] ptr to a packed ie. + OBuf[OUT] ptr to buffer for Unpacked ie. + IOff[IN\OUT] Input buffer offset + OOff[IN\OUT] Output buffer offset + + Ibuf and OBuf points directly to buffers. The IOff and OOff + must be updated, but are otherwise not used in the ie unpack. + + Return Value: Error Message + +*****************************************************************************/ +L3INT Q931Uie_CalledSub(Q931_TrunkInfo *pTrunk, ie *pIE,L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) +{ + Q931ie_CalledSub * pie = (Q931ie_CalledSub*)OBuf; + L3INT Off = 0; + L3INT Octet = 0; + L3INT x; + L3INT IESize; + + *pIE=0; + + /* Octet 1 */ + pie->IEId = IBuf[Octet]; + Octet ++; + + /* Octet 2 */ + IESize = IBuf[Octet ++]; + + /* Octet 3 */ + pie->TypNum = (IBuf[Octet+Off] >> 4) & 0x07; + pie->OddEvenInd = (IBuf[Octet+Off] >> 3) & 0x01; + Octet ++; + + /* Octet 4 */ + x=0; + do{ + pie->Digit[x] = IBuf[Octet+Off] & 0x7f; + Off++; + x++; + }while(IBuf[Octet+Off]&0x80 != 0 && x < 20); + + Q931IESizeTest(Q931E_CALLEDSUB); + + *IOff = (*IOff) + Octet + Off; + *OOff = (*OOff) + sizeof(Q931ie_CalledSub) + x - 1; + pie->Size = sizeof(Q931ie_CalledSub) + x - 1; + + Q931SetIE(*pIE, *OOff); + + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pie_CalledSub + + Parameters: IBuf[IN] Ptr to struct. + OBuf[OUT] Ptr tp packed output buffer. + Octet[IN/OUT] Offset into OBuf. + + Return Value: Error code, 0 = OK + +*****************************************************************************/ +L3INT Q931Pie_CalledSub(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) +{ + Q931ie_CalledSub * pIE = (Q931ie_CalledSub*)IBuf; + L3INT rc=0; + L3INT Beg=*Octet; + L3INT li; + L3INT sN = pIE->Size - sizeof(Q931ie_CalledSub) + 1; + L3INT x; + + /* Octet 1 */ + OBuf[(*Octet)++] = Q931ie_CALLED_PARTY_SUBADDRESS; + li=(*Octet)++; + + /* Octet 3 */ + OBuf[(*Octet)++] = 0x80 | (pIE->TypNum << 4) | (pIE->OddEvenInd << 3); + + /* Octet 4 */ + for(x=0;xDigit[x]; + } + + OBuf[(*Octet)-1] |= 0x80; /* Terminate bit */ + + OBuf[li] = (*Octet)-Beg; + return rc; +} + +/***************************************************************************** + + Function: Q931Uie_CalledNum + + Parameters: pIE[OUT] ptr to Information Element id. + IBuf[IN] ptr to a packed ie. + OBuf[OUT] ptr to buffer for Unpacked ie. + IOff[IN\OUT] Input buffer offset + OOff[IN\OUT] Output buffer offset + + Ibuf and OBuf points directly to buffers. The IOff and OOff + must be updated, but are otherwise not used in the ie unpack. + + Return Value: Error Message + +*****************************************************************************/ +L3INT Q931Uie_CalledNum(Q931_TrunkInfo *pTrunk, ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) +{ + Q931ie_CalledNum * pie = (Q931ie_CalledNum*)OBuf; + L3INT Off = 0; + L3INT Octet = 0; + L3INT x; + L3INT IESize; /* # digits in this case */ + + *pIE=0; + + /* Octet 1 */ + pie->IEId = IBuf[Octet]; + Octet ++; + + /* Octet 2 */ + IESize = IBuf[Octet ++]; + + /* Octet 3 */ + pie->TypNum = (IBuf[Octet+Off] >> 4) & 0x07; + pie->NumPlanID = IBuf[Octet+Off] & 0x0f; + Octet ++; + + /* Octet 4*/ + for (x = 0; x < IESize && x < 20; x++) + { + pie->Digit[x] = IBuf[Octet+Off] & 0x7f; + Off++; + } + + *IOff = (*IOff) + Octet + Off; + *OOff = (*OOff) + sizeof(Q931ie_CalledNum) + x - 1; + pie->Size = sizeof(Q931ie_CalledNum) + x - 1; + + Q931SetIE(*pIE, *OOff); + + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pie_CalledNum + + Parameters: IBuf[IN] Ptr to struct. + OBuf[OUT] Ptr tp packed output buffer. + Octet[IN/OUT] Offset into OBuf. + + Return Value: Error code, 0 = OK + +*****************************************************************************/ +L3INT Q931Pie_CalledNum(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) +{ + Q931ie_CalledSub * pIE = (Q931ie_CalledSub*)IBuf; + L3INT rc=0; + L3INT Beg=*Octet; + L3INT li; + L3INT sN = pIE->Size - sizeof(Q931ie_CalledSub) + 1; + L3INT x; + + /* Octet 1 */ + OBuf[(*Octet)++] = Q931ie_CALLED_PARTY_NUMBER; + li=(*Octet)++; + + /* Octet 3 */ + OBuf[(*Octet)++] = 0x80 | (pIE->TypNum << 4) | (pIE->OddEvenInd << 3); + + /* Octet 4 */ + for(x=0;xDigit[x]; + } + + OBuf[(*Octet)-1] |= 0x80; /* Terminate bit */ + + OBuf[li] = (*Octet)-Beg; + return rc; +} + +/***************************************************************************** + + Function: Q931Uie_CallingNum + + Parameters: pIE[OUT] ptr to Information Element id. + IBuf[IN] ptr to a packed ie. + OBuf[OUT] ptr to buffer for Unpacked ie. + IOff[IN\OUT] Input buffer offset + OOff[IN\OUT] Output buffer offset + + Ibuf and OBuf points directly to buffers. The IOff and OOff + must be updated, but are otherwise not used in the ie unpack. + + Return Value: Error Message + +*****************************************************************************/ +L3INT Q931Uie_CallingNum(Q931_TrunkInfo *pTrunk, ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) +{ + Q931ie_CallingNum * pie = (Q931ie_CallingNum*)OBuf; + L3INT Off = 0; + L3INT Octet = 0; + L3INT x; + L3INT IESize; + + *pIE=0; + + /* Octet 1 */ + pie->IEId = IBuf[Octet]; + Octet ++; + + /* Octet 2 */ + IESize = IBuf[Octet ++]; + + /* Octet 3 */ + pie->TypNum = (IBuf[Octet+Off] >> 4) & 0x07; + pie->NumPlanID = IBuf[Octet+Off] & 0x0f; + + /* Octet 3a */ + if(IBuf[Octet+Off] & 0x80 != 0) + { + Off++; + pie->PresInd = (IBuf[Octet+Off] >> 5) & 0x03; + pie->ScreenInd = IBuf[Octet+Off] & 0x03; + } + Octet++; + + /* Octet 4a*/ + x=0; + do{ + pie->Digit[x] = IBuf[Octet+Off] & 0x7f; + Off++; + x++; + }while(IBuf[Octet+Off]&0x80 != 0 && x < 20); + + Q931IESizeTest(Q931E_CALLINGNUM); + + *IOff = (*IOff) + Octet + Off; + *OOff = (*OOff) + sizeof(Q931ie_CallingNum) + x - 1; + pie->Size = sizeof(Q931ie_CallingNum) + x - 1; + + Q931SetIE(*pIE, *OOff); + + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pie_CallingNum + + Parameters: IBuf[IN] Ptr to struct. + OBuf[OUT] Ptr tp packed output buffer. + Octet[IN/OUT] Offset into OBuf. + + Return Value: Error code, 0 = OK + +*****************************************************************************/ +L3INT Q931Pie_CallingNum(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) +{ + Q931ie_CallingSub * pIE = (Q931ie_CallingSub*)IBuf; + L3INT rc=0; + L3INT Beg=*Octet; + L3INT li; + L3INT sN = pIE->Size - sizeof(Q931ie_CalledSub) + 1; + L3INT x; + + /* Octet 1 */ + OBuf[(*Octet)++] = Q931ie_CALLING_PARTY_SUBADDRESS; + li=(*Octet)++; + + /* Octet 3 */ + OBuf[(*Octet)++] = 0x80 | (pIE->TypNum << 4) | (pIE->OddEvenInd << 3); + + /* Octet 3a */ + /* + + Details about the use and how to detect if Octet 3a is used + are very weak. Temp left out. + + Octet 3 msb is set to 1 to indicate that this is not present + + */ + + /* Octet 4 */ + for(x=0;xDigit[x]; + } + + OBuf[(*Octet)-1] |= 0x80; /* Terminate bit */ + + OBuf[li] = (*Octet)-Beg; + return rc; +} + +/***************************************************************************** + + Function: Q931Uie_CallingSub + + Parameters: pIE[OUT] ptr to Information Element id. + IBuf[IN] ptr to a packed ie. + OBuf[OUT] ptr to buffer for Unpacked ie. + IOff[IN\OUT] Input buffer offset + OOff[IN\OUT] Output buffer offset + + Ibuf and OBuf points directly to buffers. The IOff and OOff + must be updated, but are otherwise not used in the ie unpack. + + Return Value: Error Message + +*****************************************************************************/ +L3INT Q931Uie_CallingSub(Q931_TrunkInfo *pTrunk, ie *pIE,L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) +{ + Q931ie_CallingSub * pie = (Q931ie_CallingSub*)OBuf; + L3INT Off = 0; + L3INT Octet = 0; + L3INT x; + L3INT IESize; + + *pIE=0; + + /* Octet 1 */ + pie->IEId = IBuf[Octet]; + Octet ++; + + /* Octet 2 */ + IESize = IBuf[Octet ++]; + + /* Octet 3 */ + pie->TypNum = (IBuf[Octet+Off] >> 4) & 0x07; + pie->OddEvenInd = (IBuf[Octet+Off] >> 3) & 0x01; + Octet ++; + + /* Octet 4*/ + x=0; + do{ + pie->Digit[x] = IBuf[Octet+Off] & 0x7f; + Off++; + x++; + }while(IBuf[Octet+Off]&0x80 != 0 && x < 20); + + Q931IESizeTest(Q931E_CALLINGSUB); + + *IOff = (*IOff) + Octet + Off; + *OOff = (*OOff) + sizeof(Q931ie_CallingSub) + x -1; + pie->Size = sizeof(Q931ie_CallingSub) + x -1; + + Q931SetIE(*pIE, *OOff); + + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pie_CallingSub + + Parameters: IBuf[IN] Ptr to struct. + OBuf[OUT] Ptr tp packed output buffer. + Octet[IN/OUT] Offset into OBuf. + + Return Value: Error code, 0 = OK + +*****************************************************************************/ +L3INT Q931Pie_CallingSub(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) +{ + Q931ie_CallingSub * pIE = (Q931ie_CallingSub*)IBuf; + L3INT rc=0; + L3INT Beg=*Octet; + L3INT li; + L3INT sN = pIE->Size - sizeof(Q931ie_CallingSub) + 1; + L3INT x; + + /* Octet 1 */ + OBuf[(*Octet)++] = Q931ie_CALLING_PARTY_SUBADDRESS; + li=(*Octet)++; + + /* Octet 3 */ + OBuf[(*Octet)++] = 0x80 | (pIE->TypNum << 4) | (pIE->OddEvenInd << 3); + + /* Octet 4 */ + for(x=0;xDigit[x]; + } + + OBuf[(*Octet)-1] |= 0x80; /* Terminate bit */ + + OBuf[li] = (*Octet)-Beg; + return rc; +} + +/***************************************************************************** + + Function: Q931Uie_Cause + + Parameters: pIE[OUT] ptr to Information Element id. + IBuf[IN] ptr to a packed ie. + OBuf[OUT] ptr to buffer for Unpacked ie. + IOff[IN\OUT] Input buffer offset + OOff[IN\OUT] Output buffer offset + + Ibuf and OBuf points directly to buffers. The IOff and OOff + must be updated, but are otherwise not used in the ie unpack. + + Return Value: Error Message + +*****************************************************************************/ +L3INT Q931Uie_Cause(Q931_TrunkInfo *pTrunk, ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) +{ + Q931ie_Cause * pie = (Q931ie_Cause*)OBuf; + L3INT Off = 0; + L3INT Octet = 0; + L3INT IESize; + + *pIE=0; + + pie->IEId = IBuf[Octet]; + Octet ++; + + /* Octet 2*/ + IESize = IBuf[Octet ++]; + + /* Octet 3*/ + pie->CodStand = (IBuf[Octet+Off]>>5) & 0x03; + pie->Location = IBuf[Octet+Off] & 0x0f; + + /* Octet 3a */ + if(IBuf[Octet+Off] & 0x80 != 0) + { + Off++; + pie->Recom = IBuf[Octet+Off] & 0x7f; + } + Octet++; + + /* Octet 4 */ + pie->Value = IBuf[Octet+Off] & 0x7f; + + Q931IESizeTest(Q931E_CAUSE); + + *IOff = (*IOff) + Octet + Off; + *OOff = (*OOff) + sizeof(Q931ie_Cause); + pie->Size = sizeof(Q931ie_Cause); + + Q931SetIE(*pIE, *OOff); + + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pie_Cause + + Parameters: IBuf[IN] Ptr to struct. + OBuf[OUT] Ptr tp packed output buffer. + Octet[IN/OUT] Offset into OBuf. + + Return Value: Error code, 0 = OK + +*****************************************************************************/ +L3INT Q931Pie_Cause(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) +{ + Q931ie_Cause * pIE = (Q931ie_Cause*)IBuf; + L3INT rc=0; + L3INT Beg=*Octet; + L3INT li; + + OBuf[(*Octet)++] = Q931ie_CAUSE; + li=(*Octet)++; + + /* Octet 3 */ + OBuf[(*Octet)++] = 0x80 | (pIE->CodStand<<5) | pIE->Location; + + /* Octet 3a - currently not supported in send */ + + /* Octet 4 */ + OBuf[(*Octet)++] = 0x80 | pIE->Value; + + /* Octet 5 - diagnostics not supported in send */ + + OBuf[li] = (*Octet)-Beg; + return rc; +} + +/***************************************************************************** + + Function: Q931Uie_CongLevel + + Parameters: pIE[OUT] ptr to Information Element id. + IBuf[IN] ptr to a packed ie. + OBuf[OUT] ptr to buffer for Unpacked ie. + IOff[IN\OUT] Input buffer offset + OOff[IN\OUT] Output buffer offset + + Ibuf and OBuf points directly to buffers. The IOff and OOff + must be updated, but are otherwise not used in the ie unpack. + + Return Value: Error Message + +*****************************************************************************/ +L3INT Q931Uie_CongLevel(Q931_TrunkInfo *pTrunk, ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) +{ + Q931ie_CongLevel *pie = (Q931ie_CongLevel*)OBuf; + L3INT Off = 0; + L3INT Octet = 0; + + *pIE=0; + + pie->IEId = IBuf[Octet] & 0xf0; + pie->CongLevel = IBuf[Octet] & 0x0f; + Octet ++; + + *IOff = (*IOff) + Octet + Off; + *OOff = (*OOff) + sizeof(Q931ie_CongLevel); + pie->Size = sizeof(Q931ie_CongLevel); + + Q931SetIE(*pIE, *OOff); + + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pie_CongLevel + + Parameters: IBuf[IN] Ptr to struct. + OBuf[OUT] Ptr tp packed output buffer. + Octet[IN/OUT] Offset into OBuf. + + Return Value: Error code, 0 = OK + +*****************************************************************************/ +L3INT Q931Pie_CongLevel(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) +{ + Q931ie_CongLevel * pIE = (Q931ie_CongLevel*)IBuf; + L3INT rc=0; + L3INT Beg=*Octet; + + OBuf[(*Octet)++] = Q931ie_CONGESTION_LEVEL | pIE->CongLevel; + + return rc; +} + +/***************************************************************************** + + Function: Q931Uie_ChanID + + Parameters: IBuf[IN] ptr to a packed ie. + OBuf[OUT] ptr to buffer for Unpacked ie. + IOff[IN\OUT] Input buffer offset + OOff[IN\OUT] Output buffer offset + + Ibuf and OBuf points directly to buffers. The IOff and OOff + must be updated, but are otherwise not used in the ie unpack. + + Return Value: Error code, 0 = OK + +*****************************************************************************/ +L3INT Q931Uie_ChanID(Q931_TrunkInfo *pTrunk, ie *pIE,L3UCHAR * IBuf, L3UCHAR *OBuf, L3INT *IOff, L3INT *OOff) +{ + Q931ie_ChanID * pie = (Q931ie_ChanID*)OBuf; + L3INT Off = 0; + L3INT Octet = 0; + L3INT IESize; + + *pIE=0; + + /* Octet 1 */ + pie->IEId = IBuf[Octet]; + Octet ++; + + /* Octet 2 */ + IESize = IBuf[Octet ++]; + + /* Octet 3 */ + pie->IntIDPresent = (IBuf[Octet] >> 6) & 0x01; + pie->IntType = (IBuf[Octet] >> 5) & 0x01; + pie->PrefExcl = (IBuf[Octet] >> 3) & 0x01; + pie->DChanInd = (IBuf[Octet] >> 2) & 0x01; + pie->InfoChanSel = IBuf[Octet] & 0x03; + + Off = Q931ReadExt(&IBuf[Octet+Off], Off); + Octet++; + + /* Octet 3.1 */ + + if(pie->IntIDPresent) + { + pie->InterfaceID = IBuf[Octet+Off] & 0x7f; + + /* Temp fix. Interface id can be extended using the extension bit */ + /* this will read the octets, but do nothing with them. this is done */ + /* because the usage of this field is a little unclear */ + /* 30.jan.2001/JVB */ + Off = Q931ReadExt(&IBuf[Octet+Off], Off); + Off++; + } + else + { + /* Octet 3.2 */ + if(pie->IntType == 1) /* PRI etc */ + { + pie->CodStand = (IBuf[Octet + Off] >> 5) & 0x03; + pie->NumMap = (IBuf[Octet + Off] >> 4) & 0x01; + pie->ChanMapType= IBuf[Octet + Off] & 0x0f; + + Off ++; + + + /* Octet 3.3 */ + /* Temp fix. Assume B channel. H channels not supported */ + pie->ChanSlot = IBuf[Octet+Off] & 0x7f; + Off = Q931ReadExt(&IBuf[Octet+Off], Off); + Off++; + } + } + + Q931IESizeTest(Q931E_CHANID); + + *IOff = (*IOff) + Octet + Off; + *OOff = (*OOff) + sizeof(Q931ie_BearerCap); + pie->Size = sizeof(Q931ie_BearerCap); + + Q931SetIE(*pIE, *OOff); + + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pie_ChanID + + Parameters: IBuf[IN] Ptr to struct. + OBuf[OUT] Ptr tp packed output buffer. + Octet[IN/OUT] Offset into OBuf. + + Return Value: Error code, 0 = OK + +*****************************************************************************/ +L3INT Q931Pie_ChanID(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) +{ + Q931ie_ChanID * pIE = (Q931ie_ChanID*)IBuf; + L3INT rc=Q931E_NO_ERROR; + L3INT Beg=*Octet;/* remember current offset */ + L3INT li; + + OBuf[(*Octet)++] = Q931ie_CHANNEL_IDENTIFICATION; + li=(*Octet)++; /* remember length position */ + + /* Octet 3 flags & BRI chan # */ + OBuf[(*Octet)++] = 0x80 + | (pIE->IntIDPresent << 6) + | (pIE->IntType<<5) + | (pIE->PrefExcl<<3) + | pIE->InfoChanSel; + + /* Octet 3.1 - Interface Identifier */ + if(pIE->IntIDPresent) + { + OBuf[(*Octet)++] = 0x80 | pIE->InterfaceID; + } + else + { + /* Octet 3.2 & 3.3 - PRI */ + if(pIE->IntType == 1) + { + OBuf[(*Octet)++] = 0x80 + | (pIE->CodStand << 5) + | (pIE->NumMap << 4) + | pIE->ChanMapType; + + /* Octet 3.2 Channel number/slot map */ + OBuf[(*Octet)++] = 0x80 | pIE->ChanSlot; + } + } + + OBuf[li] = (*Octet)-Beg; + return rc; +} + + +/***************************************************************************** + + Function: Q931Uie_CRV + + Description: Reading CRV. + + The CRV is currently returned in the return value that + Q921Rx23 will assign to the CRV field in the unpacked + message. CRV is basically 2 bytes etc, but the spec allows + the use of longer CRV values. + + Parameters: pIE[OUT] ptr to Information Element id. + IBuf[IN] ptr to a packed ie. + OBuf[OUT] ptr to buffer for Unpacked ie. + IOff[IN\OUT] Input buffer offset + OOff[IN\OUT] Output buffer offset + + Ibuf and OBuf points directly to buffers. The IOff and OOff + must be updated, but are otherwise not used in the ie unpack. + + Return Value: CRV + +*****************************************************************************/ +L3USHORT Q931Uie_CRV(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *IOff, L3INT *OOff) +{ + L3INT Octet = *IOff; + L3INT l = IBuf[Octet]; + L3USHORT CRV; + Octet++; /*Octet 2 is length indicator */ + + if(l == 1) /* One octet CRV */ + { + CRV = IBuf[Octet]; + Octet++; + } + else if(l==2) /* two octet CRV */ + { + CRV = IBuf[Octet] << 8; + CRV += IBuf[Octet+1]; + Octet += 2; + } + else + { + /* Long CRV is not used, so we skip this */ + Octet+=l; + } + + *IOff = Octet; + return CRV; +} + +/***************************************************************************** + + Function: Q931Uie_DateTime + + Parameters: pTrunk [IN] Ptr to trunk information. + pIE [OUT] ptr to Information Element id. + IBuf [IN] ptr to a packed ie. + OBuf [OUT] ptr to buffer for Unpacked ie. + IOff [IN\OUT] Input buffer offset + OOff [IN\OUT] Output buffer offset + + Ibuf and OBuf points directly to buffers. The IOff and OOff + must be updated, but are otherwise not used in the ie unpack. + + Return Value: Error Message + +*****************************************************************************/ +L3INT Q931Uie_DateTime(Q931_TrunkInfo *pTrunk, ie *pIE, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *IOff, L3INT *OOff) +{ + Q931ie_DateTime * pie = (Q931ie_DateTime*)OBuf; + L3INT Off = 0; + L3INT Octet = 0; + L3INT IESize=0; + + *pIE=0; + + pie->IEId = IBuf[Octet]; + IESize = IBuf[Octet ++]; + + /* Octet 2 */ + IESize = IBuf[Octet ++]; + + /* Octet 3 - Year */ + pie->Year = IBuf[Octet++]; + + /* Octet 4 - Month */ + pie->Month = IBuf[Octet++]; + + /* Octet 5 - Day */ + pie->Day = IBuf[Octet++]; + + /******************************************************************* + The remaining part of the IE are optioinal, but only the length + can now tell us wherever these fields are present or not + ********************************************************************/ + pie->Format=0; + + /* Octet 6 - Hour (optional)*/ + if(IESize >= 6) + { + pie->Format = 1; + pie->Hour = IBuf[Octet++]; + + /* Octet 7 - Minute (optional)*/ + if(IESize >= 7) + { + pie->Format = 2; + pie->Minute = IBuf[Octet++]; + + /* Octet 8 - Second (optional)*/ + if(IESize >= 8) + { + pie->Format = 3; + pie->Second = IBuf[Octet++]; + } + } + } + + Q931IESizeTest(Q931E_DATETIME); + + *IOff = (*IOff) + Octet + Off; + *OOff = (*OOff) + sizeof(Q931ie_DateTime); + pie->Size = sizeof(Q931ie_DateTime); + + Q931SetIE(*pIE, *OOff); + + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pie_DateTime + + Parameters: IBuf[IN] Ptr to struct. + OBuf[OUT] Ptr tp packed output buffer. + Octet[IN/OUT] Offset into OBuf. + + Return Value: Error code, 0 = OK + +*****************************************************************************/ +L3INT Q931Pie_DateTime(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) +{ + Q931ie_DateTime * pIE = (Q931ie_DateTime*)IBuf; + L3INT rc=0; + L3INT Beg=*Octet; + L3INT li; + + OBuf[(*Octet)++] = Q931ie_DATETIME; + li=(*Octet)++; + + OBuf[(*Octet)++] = pIE->Year; + OBuf[(*Octet)++] = pIE->Month; + OBuf[(*Octet)++] = pIE->Day; + if(pIE->Format >= 1) + { + OBuf[(*Octet)++] = pIE->Hour; + if(pIE->Format >= 2) + { + OBuf[(*Octet)++] = pIE->Minute; + if(pIE->Format >= 3) + { + OBuf[(*Octet)++] = pIE->Second; + } + } + } + + OBuf[li] = (*Octet)-Beg; + return rc; +} + +/***************************************************************************** + + Function: Q931Uie_Display + + Parameters: pIE[OUT] ptr to Information Element id. + IBuf[IN] ptr to a packed ie. + OBuf[OUT] ptr to buffer for Unpacked ie. + IOff[IN\OUT] Input buffer offset + OOff[IN\OUT] Output buffer offset + + Ibuf and OBuf points directly to buffers. The IOff and OOff + must be updated, but are otherwise not used in the ie unpack. + + Return Value: Error Message + +*****************************************************************************/ +L3INT Q931Uie_Display(Q931_TrunkInfo *pTrunk, ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) +{ + Q931ie_Display * pie = (Q931ie_Display*)OBuf; + L3INT Off = 0; + L3INT Octet = 0; + L3INT IESize; + L3INT x; + + *pIE=0; + + pie->IEId = IBuf[Octet]; + Octet ++; + + IESize = IBuf[Octet ++]; + + for(x=0; xDisplay[x] = IBuf[Octet+Off] & 0x7f; + Off++; + } + + Q931IESizeTest(Q931E_DISPLAY); + + *IOff = (*IOff) + Octet + Off; + *OOff = (*OOff) + sizeof(Q931ie_Display) + x - 1; + pie->Size = sizeof(Q931ie_Display) + x - 1; + + Q931SetIE(*pIE, *OOff); + + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pie_Display + + Parameters: IBuf[IN] Ptr to struct. + OBuf[OUT] Ptr tp packed output buffer. + Octet[IN/OUT] Offset into OBuf. + + Return Value: Error code, 0 = OK + +*****************************************************************************/ +L3INT Q931Pie_Display(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) +{ + Q931ie_Display * pIE = (Q931ie_Display*)IBuf; + L3INT rc=0; + L3INT Beg=*Octet; + L3INT li; + L3INT DSize; + L3INT x; + + OBuf[(*Octet)++] = Q931ie_DISPLAY; + li=(*Octet)++; + + DSize = pIE->Size - sizeof(Q931ie_Display) + 1; + + for(x=0; x< DSize; x++) + { + + OBuf[(*Octet)++] = pIE->Display[x]; + } + + OBuf[li] = (*Octet)-Beg; + return rc; +} + +/***************************************************************************** + + Function: Q931Uie_HLComp + + Parameters: pIE[OUT] ptr to Information Element id. + IBuf[IN] ptr to a packed ie. + OBuf[OUT] ptr to buffer for Unpacked ie. + IOff[IN\OUT] Input buffer offset + OOff[IN\OUT] Output buffer offset + + Ibuf and OBuf points directly to buffers. The IOff and OOff + must be updated, but are otherwise not used in the ie unpack. + + Return Value: Error Message + +*****************************************************************************/ +L3INT Q931Uie_HLComp(Q931_TrunkInfo *pTrunk, ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) +{ + Q931ie_HLComp * pie = (Q931ie_HLComp*)OBuf; + L3INT Off = 0; + L3INT Octet = 0; + L3INT IESize; + + *pIE=0; + + pie->IEId = IBuf[Octet]; + Octet ++; + + /* Octet */ + IESize = IBuf[Octet ++]; + + /* Octet 3*/ + pie->CodStand = (IBuf[Octet + Off] >>5) & 0x03; + pie->Interpret= (IBuf[Octet + Off] >>2) & 0x07; + pie->PresMeth = IBuf[Octet + Off] & 0x03; + + Octet++; + + /* Octet 4 */ + pie->HLCharID = IBuf[Octet+Off] & 0x7f; + + Octet++; + + /* Octet 4a*/ + if((IBuf[Octet + Off-1] & 0x80) == 0 && Q931MoreIE()) + { + if(pie->HLCharID == 0x5e || pie->HLCharID == 0x5f) + { + pie->EHLCharID = IBuf[Octet+Off] & 0x7f; + Off++; + } + else if( pie->HLCharID >= 0xc3 && pie->HLCharID <= 0xcf) + { + pie->EVideoTlfCharID = IBuf[Octet+Off] & 0x7f; + Off++; + } + else + { + // error Octet 4a indicated, but invalid value in Octet 4. + Q931SetError(pTrunk,Q931E_HLCOMP, 4, Off); + return Q931E_HLCOMP; + } + Off = Q931ReadExt(&IBuf[Octet+Off], Off); + } + + Q931IESizeTest(Q931E_HLCOMP); + + *IOff = (*IOff) + Octet + Off; + *OOff = (*OOff) + sizeof(Q931ie_HLComp); + pie->Size = sizeof(Q931ie_HLComp); + + Q931SetIE(*pIE, *OOff); + + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pie_HLComp + + Parameters: IBuf[IN] Ptr to struct. + OBuf[OUT] Ptr tp packed output buffer. + Octet[IN/OUT] Offset into OBuf. + + Return Value: Error code, 0 = OK + +*****************************************************************************/ +L3INT Q931Pie_HLComp(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) +{ + Q931ie_HLComp * pIE = (Q931ie_HLComp*)IBuf; + L3INT rc=0; + L3INT Beg=*Octet; + L3INT li; + + OBuf[(*Octet)++] = Q931ie_HIGH_LAYER_COMPATIBILITY; + li=(*Octet)++; + + /* Octet 3 */ + OBuf[(*Octet)++] = 0x80 | (pIE->CodStand << 5) | (pIE->Interpret << 2) | pIE->PresMeth; + + /* Octet 4 */ + OBuf[(*Octet)++] = pIE->HLCharID; + + /* Octet 4a */ + if(pIE->HLCharID == 0x5e || pIE->HLCharID == 0x5f) + { + OBuf[(*Octet)++] = 0x80 | pIE->EHLCharID; + } + else if( pIE->HLCharID >= 0xc3 && pIE->HLCharID <= 0xcf) + { + OBuf[(*Octet)++] = 0x80 | pIE->EVideoTlfCharID; + } + else + { + OBuf[(*Octet)-1] |= 0x80; + } + + OBuf[li] = (*Octet)-Beg; + return rc; +} + +/***************************************************************************** + + Function: Q931Uie_KeypadFac + + Parameters: pIE[OUT] ptr to Information Element id. + IBuf[IN] ptr to a packed ie. + OBuf[OUT] ptr to buffer for Unpacked ie. + IOff[IN\OUT] Input buffer offset + OOff[IN\OUT] Output buffer offset + + Ibuf and OBuf points directly to buffers. The IOff and OOff + must be updated, but are otherwise not used in the ie unpack. + + Return Value: Error Message + +*****************************************************************************/ +L3INT Q931Uie_KeypadFac(Q931_TrunkInfo *pTrunk, ie *pIE,L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) +{ + Q931ie_KeypadFac * pie = (Q931ie_KeypadFac*)OBuf; + L3INT Off = 0; + L3INT Octet = 0; + L3INT IESize; + L3INT x; + + *pIE=0; + + pie->IEId = IBuf[Octet]; + Octet ++; + + IESize = IBuf[Octet ++]; + + for(x=0; xKeypadFac[x] = IBuf[Octet+Off] & 0x7f; + Off++; + } + + Q931IESizeTest(Q931E_KEYPADFAC); + + *IOff = (*IOff) + Octet + Off; + *OOff = (*OOff) + sizeof(Q931ie_KeypadFac) + x - 1; + pie->Size = sizeof(Q931ie_KeypadFac) + x - 1; + + Q931SetIE(*pIE, *OOff); + + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pie_KeypadFac + + Parameters: IBuf[IN] Ptr to struct. + OBuf[OUT] Ptr tp packed output buffer. + Octet[IN/OUT] Offset into OBuf. + + Return Value: Error code, 0 = OK + +*****************************************************************************/ +L3INT Q931Pie_KeypadFac(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) +{ + Q931ie_KeypadFac * pIE = (Q931ie_KeypadFac*)IBuf; + L3INT rc=0; + L3INT Beg=*Octet; + L3INT li; + L3INT DSize; + L3INT x; + + OBuf[(*Octet)++] = Q931ie_KEYPAD_FACILITY; + li=(*Octet)++; + + DSize = pIE->Size - sizeof(Q931ie_KeypadFac) + 1; + + for(x=0; x< DSize; x++) + { + OBuf[(*Octet)++] = pIE->KeypadFac[x]; + } + + OBuf[li] = (*Octet)-Beg; + return rc; +} + +/***************************************************************************** + + Function: Q931Uie_LLComp + + Parameters: pIE[OUT] ptr to Information Element id. + IBuf[IN] ptr to a packed ie. + OBuf[OUT] ptr to buffer for Unpacked ie. + IOff[IN\OUT] Input buffer offset + OOff[IN\OUT] Output buffer offset + + Ibuf and OBuf points directly to buffers. The IOff and OOff + must be updated, but are otherwise not used in the ie unpack. + + Return Value: Error Message + +*****************************************************************************/ +L3INT Q931Uie_LLComp(Q931_TrunkInfo *pTrunk, ie *pIE,L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) +{ + Q931ie_LLComp * pie = (Q931ie_LLComp*)OBuf; + L3INT Off = 0; + L3INT Octet = 0; + L3INT IESize; + + *pIE=0; + + pie->IEId = IBuf[Octet]; + Octet ++; + + /* Octet 2 */ + IESize = IBuf[Octet ++]; + + /* Octet 3*/ + + pie->CodStand = (IBuf[Octet+Off] >> 5) & 0x03; + pie->ITransCap= IBuf[Octet+Off] & 0x1f; + + Octet++; + + /* Octet 3a*/ + if(IBuf[Octet+Off-1] & 0x80 != 0) + { + pie->NegotInd = (IBuf[Octet+Off] >> 6) & 0x01; + Off++; + } + + /* Octet 4 */ + pie->TransMode = (IBuf[Octet+Off] >> 5) & 0x03; + pie->InfoRate = IBuf[Octet+Off] & 0x1f; + + Octet++; + + /* Octet 4.1 */ + if(pie->InfoRate == 0x14 ) /* Mutirate */ + { + pie->RateMul = IBuf[Octet+Off] & 0x7f; + Off++; + } + + /* Octet 5 - Layer 1 Ident */ + if(IBuf[Octet+Off] & 0x60 == 0x20) /* Layer 1 Ident ? */ + { + pie->Layer1Ident = (IBuf[Octet+Off] >> 5) & 0x03; + pie->UIL1Prot = IBuf[Octet+Off] & 0x1f; + + Octet++; + + /* Octet 5a */ + if(IBuf[Octet+Off-1] & 0x80 != 0) + { + pie->SyncAsync = (IBuf[Octet+Off] >> 6) & 0x01; + pie->Negot = (IBuf[Octet+Off] >> 5) & 0x01; + pie->UserRate = IBuf[Octet+Off] & 0x1f; + Off++; + + /* Octet 5b - 2 options */ + if(IBuf[Octet+Off-1] & 0x80 != 0) + { + if(pie->UIL1Prot == 0x01) /* V.110, I.460 and X.30*/ + { + pie->InterRate = (IBuf[Octet+Off] >> 5) & 0x03; + pie->NIConTx = (IBuf[Octet+Off] >> 4) & 0x01; + pie->NIConRx = (IBuf[Octet+Off] >> 3) & 0x01; + pie->FlowCtlTx = (IBuf[Octet+Off] >> 2) & 0x01; + pie->FlowCtlRx = (IBuf[Octet+Off] >> 1) & 0x01; + Off++; + } + else if(pie->UIL1Prot == 0x80)/* V.120 */ + { + pie->HDR = (IBuf[Octet+Off] >> 6) & 0x01; + pie->MultiFrame = (IBuf[Octet+Off] >> 5) & 0x01; + pie->ModeL1 = (IBuf[Octet+Off] >> 4) & 0x01; + pie->NegotLLI = (IBuf[Octet+Off] >> 3) & 0x01; + pie->Assignor = (IBuf[Octet+Off] >> 2) & 0x01; + pie->InBandNeg = (IBuf[Octet+Off] >> 1) & 0x01; + Off++; + } + else if(pie->UIL1Prot == 0x07)/* non standard */ + { + Off = Q931ReadExt(&IBuf[Octet+Off], Off); + Off++; + } + else + { + Q931SetError(pTrunk,Q931E_LLCOMP, 5,2); + return Q931E_LLCOMP; + } + + /* Octet 5c */ + if(IBuf[Octet+Off-1] & 0x80 != 0) + { + pie->NumStopBits=(IBuf[Octet+Off] >> 5) & 0x03; + pie->NumDataBits=(IBuf[Octet+Off] >> 3) & 0x03; + pie->Parity =IBuf[Octet+Off] & 0x07; + Off++; + + /* Octet 5d */ + if(IBuf[Octet+Off-1] & 0x80 != 0) + { + pie->DuplexMode = (IBuf[Octet+Off] >> 6) & 0x01; + pie->ModemType = IBuf[Octet+Off] & 0x3f; + Off = Q931ReadExt(&IBuf[Octet+Off], Off); + Off++; + } + } + } + } + } + + /* Octet 6 - Layer 2 Ident */ + if(IBuf[Octet+Off] & 0x60 == 0x40) /* Layer 1 Ident ? */ + { + pie->Layer2Ident= (IBuf[Octet+Off] >>5) & 0x03; + pie->UIL2Prot = IBuf[Octet+Off] & 0x1f; + Octet++; + + /* Octet 6a */ + if(IBuf[Octet+Off-1] & 0x80 != 0) + { + if(pie->UIL2Prot == 0x10) /* 2nd 6a */ + { + pie->UsrSpcL2Prot = IBuf[Octet+Off] & 0x7f; + Off++; + } + else /* assume 1st 6a*/ + { + pie->ModeL2 = (IBuf[Octet+Off] >> 5) & 0x03; + pie->Q933use=IBuf[Octet+Off] & 0x03; + Off++; + } + /* Octet 6b*/ + if(IBuf[Octet+Off-1] & 0x80 != 0) + { + pie->WindowSize = IBuf[Octet+Off] & 0x7f; + Off++; + } + } + } + + /* Octet 7 - layer 3 Ident */ + if(IBuf[Octet+Off] & 0x60 == 0x60) /* Layer 3 Ident ? */ + { + pie->Layer3Ident= (IBuf[Octet+Off] >> 5) & 0x03; + pie->UIL3Prot = IBuf[Octet+Off] & 0x1f; + Octet++; + + /* Octet 7a */ + if(IBuf[Octet+Off-1] & 0x80 != 0) + { + + if(pie->UIL3Prot == 0x0b) + { + /* Octet 7a + 7b AddL3Info */ + pie->AddL3Info = ((IBuf[Octet+Off] << 4) &0xf0) + |(IBuf[Octet+Off+1] & 0x0f); + Off+=2; + } + else + { + if(pie->UIL3Prot == 0x1f) + { + pie->ModeL3 = (IBuf[Octet+Off] >> 5) & 0x03; + Off++; + } + else + { + pie->OptL3Info = IBuf[Octet+Off] & 0x7f; + Off++; + } + + /* Octet 7b*/ + if(IBuf[Octet+Off-1] & 0x80 != 0) + { + pie->DefPackSize = IBuf[Octet+Off] & 0x0f; + Off++; + + /* Octet 7c */ + if(IBuf[Octet+Off-1] & 0x80 != 0) + { + pie->PackWinSize= IBuf[Octet+Off] & 0x7f; + } + } + } + } + } + else + { + Q931SetError(pTrunk,Q931E_LLCOMP, 7,0); + return Q931E_LLCOMP; + } + + Q931IESizeTest(Q931E_LLCOMP); + + *IOff = (*IOff) + Octet + Off; + *OOff = (*OOff) + sizeof(Q931ie_LLComp); + pie->Size = sizeof(Q931ie_LLComp); + + Q931SetIE(*pIE, *OOff); + + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pie_LLComp + + Parameters: IBuf[IN] Ptr to struct. + OBuf[OUT] Ptr tp packed output buffer. + Octet[IN/OUT] Offset into OBuf. + + Return Value: Error code, 0 = OK + +*****************************************************************************/ +L3INT Q931Pie_LLComp(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) +{ + Q931ie_LLComp * pIE = (Q931ie_LLComp*)IBuf; + L3INT rc=0; + L3INT Beg=*Octet; + L3INT li; + + OBuf[(*Octet)++] = Q931ie_LOW_LAYER_COMPATIBILITY; + li=(*Octet)++; + + /* Octet 3*/ + OBuf[(*Octet)++] = (pIE->CodStand << 6) | pIE->ITransCap; + + /* Octet 3a*/ + OBuf[(*Octet)++] = 0x80 | (pIE->NegotInd << 6); + + /* Octet 4 */ + OBuf[(*Octet)++] = 0x80 | (pIE->TransMode << 5) | pIE->InfoRate; + + /* Octet 4.1*/ + if(pIE->InfoRate == 0x18) + { + OBuf[(*Octet)++] = 0x80 | pIE->RateMul; + } + + /* Octet 5*/ + if(pIE->Layer1Ident == 0x01) + { + OBuf[(*Octet)++] = (pIE->Layer1Ident << 5) | pIE->UIL1Prot; + + /* Octet 5a*/ + if((pIE->ITransCap == 0x08 && (pIE->UIL1Prot == 0x01 || pIE->UIL1Prot == 0x08)) + || (pIE->ITransCap == 0x10 && (pIE->UIL1Prot == 0x02 || pIE->UIL1Prot == 0x03))) + { + OBuf[(*Octet)++] = (pIE->SyncAsync<<6) | (pIE->Negot<<5) | pIE->UserRate; + + /* Octet 5b*/ + if(pIE->UIL1Prot == 0x01) + { + OBuf[(*Octet)++] = (pIE->InterRate << 5) + | (pIE->NIConTx << 4) + | (pIE->NIConTx << 3) + | (pIE->FlowCtlTx << 2) + | (pIE->FlowCtlRx << 1); + } + else if(pIE->UIL1Prot == 0x08) + { + OBuf[(*Octet)++] = (pIE->HDR << 6) + | (pIE->MultiFrame<< 5) + | (pIE->ModeL1 << 4) + | (pIE->NegotLLI << 3) + | (pIE->Assignor << 2) + | (pIE->InBandNeg << 1); + } + else + { + OBuf[(*Octet)-1] |= 0x80; + } + + /* How to detect wherever 5c and 5d is to present is not clear*/ + /* but they have been inculded as 'standard'*/ + /* Octet 5c*/ + if(pIE->UIL1Prot == 0x01 || pIE->UIL1Prot == 0x08) + { + OBuf[(*Octet)++] = (pIE->NumStopBits<<5) | (pIE->NumDataBits<<3) | pIE->Parity ; + + /* Octet 5d*/ + OBuf[(*Octet)++] = 0x80 | (pIE->DuplexMode<<6) | pIE->ModemType; + } + } + else + { + OBuf[(*Octet)-1] |= 0x80; + } + } + + /* Octet 6*/ + if(pIE->Layer2Ident == 0x02) + { + OBuf[(*Octet)++] = (pIE->Layer2Ident << 5) | pIE->UIL2Prot; + + /* Octet 6a*/ + if(pIE->UIL2Prot == 0x02 /* Q.921/I.441 */ + || pIE->UIL2Prot == 0x06 /* X.25 link layer */ + || pIE->UIL2Prot == 0x07 /* X.25 multilink */ + || pIE->UIL2Prot == 0x09 /* HDLC ARM */ + || pIE->UIL2Prot == 0x0a /* HDLC NRM */ + || pIE->UIL2Prot == 0x0b /* HDLC ABM */ + || pIE->UIL2Prot == 0x0d /* X.75 SLP */ + || pIE->UIL2Prot == 0x0e /* Q.922 */ + || pIE->UIL2Prot == 0x11)/* ISO/ECE 7776 DTE-DCE */ + { + OBuf[(*Octet)++] = (pIE->ModeL2 << 5) | pIE->Q933use; + + /* Octet 6b*/ + OBuf[(*Octet)++] = 0x80 | pIE->WindowSize; + } + else if(pIE->UIL2Prot == 0x10) /* User Specific */ + { + OBuf[(*Octet)++] = 0x80 | pIE->UsrSpcL2Prot; + } + else + { + OBuf[(*Octet)-1] |= 0x80; + } + } + + /* Octet 7*/ + if(pIE->Layer3Ident == 0x03) + { + OBuf[(*Octet)++] = (pIE->Layer3Ident<<5) | pIE->UIL3Prot; + + /* Octet 7a - 3 different ones */ + if(pIE->UIL3Prot == 0x10) + { + OBuf[(*Octet++)] = 0x80 | pIE->OptL3Info; + } + else if(pIE->UIL3Prot == 0x06 + || pIE->UIL3Prot == 0x07 + || pIE->UIL3Prot == 0x08) + { + OBuf[(*Octet)++] = pIE->ModeL3 << 5; + + /* Octet 7b note 7*/ + OBuf[(*Octet)++] = pIE->DefPackSize; + + /* Octet 7c note 7*/ + OBuf[(*Octet)++] = 0x80 | pIE->PackWinSize; + } + else if(pIE->UIL3Prot == 0x0b) + { + OBuf[(*Octet)++] = (pIE->AddL3Info >> 4) & 0x0f; + OBuf[(*Octet)++] = 0x80 | (pIE->AddL3Info & 0x0f); + } + else + { + OBuf[(*Octet)-1] |= 0x80; + } + } + else + { + Q931SetError(pTrunk,Q931E_LLCOMP, 7,0); + rc = Q931E_LLCOMP; + } + + OBuf[li] = (*Octet)-Beg; + return rc; +} + +/***************************************************************************** + + Function: Q931Uie_NetFac + + Parameters: pIE[OUT] ptr to Information Element id. + IBuf[IN] ptr to a packed ie. + OBuf[OUT] ptr to buffer for Unpacked ie. + IOff[IN\OUT] Input buffer offset + OOff[IN\OUT] Output buffer offset + + Ibuf and OBuf points directly to buffers. The IOff and OOff + must be updated, but are otherwise not used in the ie unpack. + + Return Value: Error Message + +*****************************************************************************/ +L3INT Q931Uie_NetFac(Q931_TrunkInfo *pTrunk, ie *pIE,L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) +{ + Q931ie_NetFac * pie = (Q931ie_NetFac*)OBuf; + L3INT Off = 0; + L3INT Octet = 0; + L3INT x=0; + L3INT IESize; + + *pIE=0; + + pie->IEId = IBuf[Octet]; + Octet ++; + + /* Octet 2 */ + IESize = IBuf[Octet ++]; + + pie->LenNetID = IBuf[Octet+Off]; /* full octet is used */ + Octet++; + + if(pie->LenNetID > 0) + { + /* Octet 3.1 */ + pie->TypeNetID = (IBuf[Octet+Off] >> 4) & 0x0f; + pie->NetIDPlan = IBuf[Octet+Off] & 0x0f; + Off = Q931ReadExt(&IBuf[Octet], Off); + Off++; + + /* Octet 3.2*/ + for(x=0; x < pie->LenNetID; x++) + { + pie->NetID[x] = IBuf[Octet+Off] & 0x7f; + Off++; + } + } + + /* Octet 4*/ + pie->NetFac = IBuf[Octet+Off]; /* Full Octet is used */ + Octet++; + + Q931IESizeTest(Q931E_NETFAC); + + *IOff = (*IOff) + Octet + Off; + *OOff = (*OOff) + sizeof(Q931ie_NetFac) + x - 1; + pie->Size = sizeof(Q931ie_NetFac) + x - 1; + + Q931SetIE(*pIE, *OOff); + + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pie_NetFac + + Parameters: IBuf[IN] Ptr to struct. + OBuf[OUT] Ptr tp packed output buffer. + Octet[IN/OUT] Offset into OBuf. + + Return Value: Error code, 0 = OK + +*****************************************************************************/ +L3INT Q931Pie_NetFac(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) +{ + Q931ie_NetFac * pIE = (Q931ie_NetFac*)IBuf; + L3INT rc=Q931E_NO_ERROR; + L3INT Beg=*Octet; + L3INT li; + L3INT x; + + OBuf[(*Octet)++] = Q931ie_NETWORK_SPECIFIC_FACILITIES; + li=(*Octet)++; + + /* Octet 3 */ + OBuf[(*Octet)++] = pIE->LenNetID; + + if(pIE->LenNetID > 0) + { + /* Octet 3.1 */ + OBuf[(*Octet)++] = 0x80 | (pIE->TypeNetID << 4) | pIE->NetIDPlan; + + /* Octet 3.2 */ + for(x=0; x LenNetID; x++) + { + OBuf[(*Octet)++] = pIE->NetID[x]; + } + } + + /* Octet 4*/ + OBuf[(*Octet)++] = pIE->NetFac; + + OBuf[li] = (*Octet)-Beg; + return rc; +} + +/***************************************************************************** + + Function: Q931Uie_NotifInd + + Parameters: pIE[OUT] ptr to Information Element id. + IBuf[IN] ptr to a packed ie. + OBuf[OUT] ptr to buffer for Unpacked ie. + IOff[IN\OUT] Input buffer offset + OOff[IN\OUT] Output buffer offset + + Ibuf and OBuf points directly to buffers. The IOff and OOff + must be updated, but are otherwise not used in the ie unpack. + + Return Value: Error Message + +*****************************************************************************/ +L3INT Q931Uie_NotifInd(Q931_TrunkInfo *pTrunk, ie *pIE,L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) +{ + Q931ie_NotifInd * pie = (Q931ie_NotifInd*)OBuf; + L3INT Off = 0; + L3INT Octet = 0; + L3INT IESize; + + *pIE=0; + + pie->IEId = IBuf[Octet]; + Octet ++; + + /* Octet 2*/ + IESize = IBuf[Octet ++]; + + /* Octet 3 */ + pie->Notification = IBuf[Octet+Off] & 0x7f; + + Off = Q931ReadExt(&IBuf[Octet], Off); + Octet++; + + Q931IESizeTest(Q931E_NOTIFIND); + + *IOff = (*IOff) + Octet + Off; + *OOff = (*OOff) + sizeof(Q931ie_NotifInd); + pie->Size = sizeof(Q931ie_NotifInd); + + Q931SetIE(*pIE, *OOff); + + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pie_NotifInd + + Parameters: IBuf[IN] Ptr to struct. + OBuf[OUT] Ptr tp packed output buffer. + Octet[IN/OUT] Offset into OBuf. + + Return Value: Error code, 0 = OK + +*****************************************************************************/ +L3INT Q931Pie_NotifInd(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) +{ + Q931ie_NotifInd * pIE = (Q931ie_NotifInd*)IBuf; + L3INT rc=Q931E_NO_ERROR; + L3INT Beg=*Octet; + L3INT li; + + OBuf[(*Octet)++] = Q931ie_NOTIFICATION_INDICATOR; + li=(*Octet)++; + + /* Octet 3*/ + OBuf[(*Octet)++] = pIE->Notification; + + OBuf[li] = (*Octet)-Beg; + return rc; +} + +/***************************************************************************** + + Function: Q931Uie_ProgInd + + Parameters: pIE[OUT] ptr to Information Element id. + IBuf[IN] ptr to a packed ie. + OBuf[OUT] ptr to buffer for Unpacked ie. + IOff[IN\OUT] Input buffer offset + OOff[IN\OUT] Output buffer offset + + Ibuf and OBuf points directly to buffers. The IOff and OOff + must be updated, but are otherwise not used in the ie unpack. + + Return Value: Error Message + +*****************************************************************************/ +L3INT Q931Uie_ProgInd(Q931_TrunkInfo *pTrunk, ie *pIE,L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) +{ + Q931ie_ProgInd * pie = (Q931ie_ProgInd*)OBuf; + L3INT Off = 0; + L3INT Octet = 0; + L3INT IESize; + + *pIE=0; + + pie->IEId = IBuf[Octet]; + Octet ++; + + /* Octet 2*/ + IESize = IBuf[Octet ++]; + + /* Octet 3*/ + pie->CodStand = (IBuf[Octet+Off] >> 5) & 0x03; + pie->Location = IBuf[Octet+Off] & 0x0f; + + Off = Q931ReadExt(&IBuf[Octet], Off); + Octet++; + + /* Octet 4*/ + pie->ProgDesc = IBuf[Octet+Off] & 0x7f; + Off = Q931ReadExt(&IBuf[Octet], Off); + Octet++; + + Q931IESizeTest(Q931E_PROGIND); + + *IOff = (*IOff) + Octet + Off; + *OOff = (*OOff) + sizeof(Q931ie_ProgInd); + pie->Size = sizeof(Q931ie_ProgInd); + + Q931SetIE(*pIE, *OOff); + + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pie_ProgInd + + Parameters: IBuf[IN] Ptr to struct. + OBuf[OUT] Ptr tp packed output buffer. + Octet[IN/OUT] Offset L3INTo OBuf. + + Return Value: Error code, 0 = OK + +*****************************************************************************/ +L3INT Q931Pie_ProgInd(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) +{ + Q931ie_ProgInd * pIE = (Q931ie_ProgInd*)IBuf; + L3INT rc=Q931E_NO_ERROR; + L3INT Beg=*Octet; + L3INT li; + + OBuf[(*Octet)++] = Q931ie_PROGRESS_INDICATOR; + li=(*Octet)++; + + /* Octet 3*/ + OBuf[(*Octet)++] = 0x80 | (pIE->CodStand << 5) | pIE->Location; + + /* Octet 4*/ + OBuf[(*Octet)++] = 0x80 | pIE->ProgDesc; + + OBuf[li] = (*Octet)-Beg; + return rc; +} + +/***************************************************************************** + + Function: Q931Uie_RepeatInd + + Parameters: pIE[OUT] ptr to Information Element id. + IBuf[IN] ptr to a packed ie. + OBuf[OUT] ptr to buffer for Unpacked ie. + IOff[IN\OUT] Input buffer offset + OOff[IN\OUT] Output buffer offset + + Ibuf and OBuf points directly to buffers. The IOff and OOff + must be updated, but are otherwise not used in the ie unpack. + + Return Value: Error Message + +*****************************************************************************/ +L3INT Q931Uie_RepeatInd(Q931_TrunkInfo *pTrunk, ie *pIE,L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) +{ + Q931ie_RepeatInd *pie = (Q931ie_RepeatInd*)OBuf; + L3INT Off = 0; + L3INT Octet = 0; + + *pIE=0; + + pie->IEId = IBuf[Octet] & 0xf0; + pie->RepeatInd = IBuf[Octet] & 0x0f; + Octet ++; + + *IOff = (*IOff) + Octet + Off; + *OOff = (*OOff) + sizeof(Q931ie_RepeatInd); + pie->Size = sizeof(Q931ie_RepeatInd); + + Q931SetIE(*pIE, *OOff); + + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pie_RepeatInd + + Parameters: IBuf[IN] Ptr to struct. + OBuf[OUT] Ptr tp packed output buffer. + Octet[IN/OUT] Offset into OBuf. + + Return Value: Error code, 0 = OK + +*****************************************************************************/ +L3INT Q931Pie_RepeatInd(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) +{ + Q931ie_RepeatInd * pIE = (Q931ie_RepeatInd*)IBuf; + L3INT rc=0; + L3INT Beg=*Octet; + + OBuf[(*Octet)++] = Q931ie_REPEAT_INDICATOR | pIE->RepeatInd; + + return rc; +} + +/***************************************************************************** + + Function: Q931Uie_RevChargeInd + + Parameters: pIE[OUT] ptr to Information Element id. + IBuf[IN] ptr to a packed ie. + OBuf[OUT] ptr to buffer for Unpacked ie. + IOff[IN\OUT] Input buffer offset + OOff[IN\OUT] Output buffer offset + + Ibuf and OBuf points directly to buffers. The IOff and OOff + must be updated, but are otherwise not used in the ie unpack. + + Return Value: Error Message + +*****************************************************************************/ +L3INT Q931Uie_RevChargeInd(Q931_TrunkInfo *pTrunk, ie *pIE,L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) +{ + ie iE; + Q931SetIE(iE, *OOff); + + return iE; +} + +/***************************************************************************** + + Function: Q931Pie_RevChargeInd + + Parameters: IBuf[IN] Ptr to struct. + OBuf[OUT] Ptr tp packed output buffer. + Octet[IN/OUT] Offset into OBuf. + + Return Value: Error code, 0 = OK + +*****************************************************************************/ +L3INT Q931Pie_RevChargeInd(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) +{ + L3BOOL RetCode = L3FALSE; + + NoWarning(OBuf); + NoWarning(IBuf); + + return RetCode; +} + +/***************************************************************************** + + Function: Q931Uie_RestartInd + + Parameters: pIE[OUT] ptr to Information Element id. + IBuf[IN] ptr to a packed ie. + OBuf[OUT] ptr to buffer for Unpacked ie. + IOff[IN\OUT] Input buffer offset + OOff[IN\OUT] Output buffer offset + + Ibuf and OBuf points directly to buffers. The IOff and OOff + must be updated, but are otherwise not used in the ie unpack. + + Return Value: Error Message + +*****************************************************************************/ +L3INT Q931Uie_RestartInd(Q931_TrunkInfo *pTrunk, ie *pIE,L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) +{ + Q931ie_RestartInd * pie = (Q931ie_RestartInd*)OBuf; + L3INT Off = 0; + L3INT Octet = 0; + L3INT IESize; + + *pIE=0; + + pie->IEId = IBuf[Octet]; + Octet ++; + + /* Octet 2*/ + IESize = IBuf[Octet ++]; + + /* Octet 3 */ + pie->Class = IBuf[Octet+Off] & 0x07; + + Off = Q931ReadExt(&IBuf[Octet], Off); + Octet++; + + Q931IESizeTest(Q931E_RESTARTIND); + + *IOff = (*IOff) + Octet + Off; + *OOff = (*OOff) + sizeof(Q931ie_RestartInd); + pie->Size = sizeof(Q931ie_RestartInd); + + Q931SetIE(*pIE, *OOff); + + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pie_RestartInd + + Parameters: IBuf[IN] Ptr to struct. + OBuf[OUT] Ptr tp packed output buffer. + Octet[IN/OUT] Offset into OBuf. + + Return Value: Error code, 0 = OK + +*****************************************************************************/ +L3INT Q931Pie_RestartInd(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) +{ + Q931ie_RestartInd * pIE = (Q931ie_RestartInd*)IBuf; + L3INT rc=Q931E_NO_ERROR; + L3INT Beg=*Octet; + L3INT li; + + OBuf[(*Octet)++] = Q931ie_RESTART_INDICATOR; + li=(*Octet)++; + + /* Octet 3*/ + OBuf[(*Octet)++] = 0x80 | pIE->Class ; + + OBuf[li] = (*Octet)-Beg; + return rc; +} + +/***************************************************************************** + + Function: Q931Uie_Segment + + Parameters: pIE[OUT] ptr to Information Element id. + IBuf[IN] ptr to a packed ie. + OBuf[OUT] ptr to buffer for Unpacked ie. + IOff[IN\OUT] Input buffer offset + OOff[IN\OUT] Output buffer offset + + Ibuf and OBuf points directly to buffers. The IOff and OOff + must be updated, but are otherwise not used in the ie unpack. + + Return Value: Error Message + +*****************************************************************************/ +L3INT Q931Uie_Segment(Q931_TrunkInfo *pTrunk, ie *pIE,L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) +{ + Q931ie_Segment * pie = (Q931ie_Segment*)OBuf; + L3INT Off = 0; + L3INT Octet = 0; + L3INT IESize; + + *pIE=0; + + pie->IEId = IBuf[Octet]; + Octet ++; + + /* Octet 2*/ + IESize = IBuf[Octet ++]; + + /* Octet 3 */ + pie->FSI = (IBuf[Octet+Off] & 0x80) >> 7; + pie->NumSegRem = IBuf[Octet+Off] & 0x7f; + Octet++; + + /* Octet 4 */ + pie->SegType = IBuf[Octet+Off] & 0x7f; + Octet++; + + Q931IESizeTest(Q931E_SEGMENT); + + *IOff = (*IOff) + Octet + Off; + *OOff = (*OOff) + sizeof(Q931ie_Segment); + pie->Size = sizeof(Q931ie_Segment); + + Q931SetIE(*pIE, *OOff); + + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pie_Segment + + Parameters: IBuf[IN] Ptr to struct. + OBuf[OUT] Ptr tp packed output buffer. + Octet[IN/OUT] Offset into OBuf. + + Return Value: Error code, 0 = OK + +*****************************************************************************/ +L3INT Q931Pie_Segment(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) +{ + Q931ie_Segment * pIE = (Q931ie_Segment*)IBuf; + L3INT rc=Q931E_NO_ERROR; + L3INT Beg=*Octet; + L3INT li; + + OBuf[(*Octet)++] = Q931ie_SEGMENTED_MESSAGE; + li=(*Octet)++; + + /* Octet 3*/ + OBuf[(*Octet)++] = (pIE->FSI<<7) | pIE->NumSegRem; + + /* Octet 4 */ + OBuf[(*Octet)++] = pIE->SegType; + + OBuf[li] = (*Octet)-Beg; + return rc; +} + +/***************************************************************************** + + Function: Q931Uie_SendComplete + + Parameters: pIE[OUT] ptr to Information Element id. + IBuf[IN] ptr to a packed ie. + OBuf[OUT] ptr to buffer for Unpacked ie. + IOff[IN\OUT] Input buffer offset + OOff[IN\OUT] Output buffer offset + + Ibuf and OBuf points directly to buffers. The IOff and OOff + must be updated, but are otherwise not used in the ie unpack. + + Return Value: Error Message + +*****************************************************************************/ +L3INT Q931Uie_SendComplete(Q931_TrunkInfo *pTrunk, ie *pIE,L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) +{ + Q931ie_SendComplete *pie = (Q931ie_SendComplete*)OBuf; + L3INT Off = 0; + L3INT Octet = 0; + + *pIE=0; + + Octet ++; + + *IOff = (*IOff) + Octet + Off; + *OOff = (*OOff) + sizeof(Q931ie_SendComplete); + pie->Size = sizeof(Q931ie_SendComplete); + + Q931SetIE(*pIE, *OOff); + + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pie_ProgInd + + Parameters: IBuf[IN] Ptr to struct. + OBuf[OUT] Ptr tp packed output buffer. + Octet[IN/OUT] Offset into OBuf. + + Return Value: Error code, 0 = OK + +*****************************************************************************/ +L3INT Q931Pie_SendComplete(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) +{ + Q931ie_SendComplete * pIE = (Q931ie_SendComplete*)IBuf; + L3INT rc=Q931E_NO_ERROR; + L3INT Beg=*Octet; +// L3INT li; + + OBuf[(*Octet)++] = 0x80 | (L3UCHAR)Q931ie_SENDING_COMPLETE; + + return rc; +} + +/***************************************************************************** + + Function: Q931Uie_Signal + + Parameters: pIE[OUT] ptr to Information Element id. + IBuf[IN] ptr to a packed ie. + OBuf[OUT] ptr to buffer for Unpacked ie. + IOff[IN\OUT] Input buffer offset + OOff[IN\OUT] Output buffer offset + + Ibuf and OBuf points directly to buffers. The IOff and OOff + must be updated, but are otherwise not used in the ie unpack. + + Return Value: Error Message + +*****************************************************************************/ +L3INT Q931Uie_Signal(Q931_TrunkInfo *pTrunk, ie *pIE,L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) +{ + Q931ie_Signal * pie = (Q931ie_Signal*)OBuf; + L3INT Off = 0; + L3INT Octet = 0; + L3INT IESize; + + *pIE=0; + + pie->IEId = IBuf[Octet]; + Octet ++; + + /* Octet 2*/ + IESize = IBuf[Octet ++]; + + /* Octet 3 */ + pie->Signal = IBuf[Octet+Off]; + Octet++; + + Q931IESizeTest(Q931E_SIGNAL); + + *IOff = (*IOff) + Octet + Off; + *OOff = (*OOff) + sizeof(Q931ie_Signal); + pie->Size = sizeof(Q931ie_Signal); + + Q931SetIE(*pIE, *OOff); + + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pie_Signal + + Parameters: IBuf[IN] Ptr to struct. + OBuf[OUT] Ptr tp packed output buffer. + Octet[IN/OUT] Offset into OBuf. + + Return Value: Error code, 0 = OK + +*****************************************************************************/ +L3INT Q931Pie_Signal(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) +{ + Q931ie_Signal * pIE = (Q931ie_Signal*)IBuf; + L3INT rc=Q931E_NO_ERROR; + L3INT Beg=*Octet; + L3INT li; + + OBuf[(*Octet)++] = Q931ie_SIGNAL; + li=(*Octet)++; + + /* Octet 3*/ + OBuf[(*Octet)++] = pIE->Signal; + + OBuf[li] = (*Octet)-Beg; + return rc; +} + +/***************************************************************************** + + Function: Q931Uie_TransNetSel + + Parameters: pIE[OUT] ptr to Information Element id. + IBuf[IN] ptr to a packed ie. + OBuf[OUT] ptr to buffer for Unpacked ie. + IOff[IN\OUT] Input buffer offset + OOff[IN\OUT] Output buffer offset + + Ibuf and OBuf points directly to buffers. The IOff and OOff + must be updated, but are otherwise not used in the ie unpack. + + Return Value: Error Message + +*****************************************************************************/ +L3INT Q931Uie_TransNetSel(Q931_TrunkInfo *pTrunk, ie *pIE,L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) +{ + Q931ie_TransNetSel * pie = (Q931ie_TransNetSel*)OBuf; + L3INT Off = 0; + L3INT Octet = 0; + L3INT x=0; + L3INT l; + + *pIE=0; + + pie->IEId = IBuf[Octet]; + Octet ++; + + /* Octet 2 */ + l = IBuf[Octet] - 3; + Octet++; + + /* Octet 3*/ + pie->Type = (IBuf[Octet+Off] >> 4) & 0x07; + + Off = Q931ReadExt(&IBuf[Octet], Off); + Octet++; + + for(x=0; x < l; x++) + { + pie->NetID[x] = IBuf[Octet+Off] & 0x7f; + Off++; + } + + *IOff = (*IOff) + Octet + Off; + *OOff = (*OOff) + sizeof(Q931ie_TransNetSel) + x - 1; + pie->Size = sizeof(Q931ie_TransNetSel) + x - 1; + + Q931SetIE(*pIE, *OOff); + + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pie_TransNetSel + + Parameters: IBuf[IN] Ptr to struct. + OBuf[OUT] Ptr tp packed output buffer. + Octet[IN/OUT] Offset into OBuf. + + Return Value: Error code, 0 = OK + +*****************************************************************************/ +L3INT Q931Pie_TransNetSel(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) +{ + Q931ie_TransNetSel * pIE = (Q931ie_TransNetSel*)IBuf; + L3INT rc=Q931E_NO_ERROR; + L3INT Beg=*Octet; + L3INT li; + L3INT x; + L3INT l; + + OBuf[(*Octet)++] = Q931ie_TRANSIT_NETWORK_SELECTION; + li=(*Octet)++; + + /* Octet 3 */ + OBuf[(*Octet)++] = 0x80 | (pIE->Type<<4) | pIE->NetIDPlan; + + /* Octet 4 */ + l = pIE->Size - sizeof(Q931ie_TransNetSel) + 1; + for(x=0;xNetID[x]; + } + + OBuf[li] = (*Octet)-Beg; + return rc; +} + +/***************************************************************************** + + Function: Q931Uie_UserUser + + Parameters: pIE[OUT] ptr to Information Element id. + IBuf[IN] ptr to a packed ie. + OBuf[OUT] ptr to buffer for Unpacked ie. + IOff[IN\OUT] Input buffer offset + OOff[IN\OUT] Output buffer offset + + Ibuf and OBuf points directly to buffers. The IOff and OOff + must be updated, but are otherwise not used in the ie unpack. + + Return Value: Error Message + +*****************************************************************************/ +L3INT Q931Uie_UserUser(Q931_TrunkInfo *pTrunk, ie *pIE,L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) +{ + Q931ie_UserUser * pie = (Q931ie_UserUser*)OBuf; + L3INT Off = 0; + L3INT Octet = 0; + L3INT x=0; + L3INT l; + + *pIE=0; + + pie->IEId = IBuf[Octet]; + Octet ++; + + /* Octet 2 */ + l = IBuf[Octet] - 3; + Octet++; + + /* Octet 3*/ + pie->ProtDisc = IBuf[Octet+Off]; + Octet++; + + for(x=0; x < l; x++) + { + pie->User[x] = IBuf[Octet+Off]; + Off++; + } + + *IOff = (*IOff) + Octet + Off; + *OOff = (*OOff) + sizeof(Q931ie_UserUser) + x - 1; + pie->Size = sizeof(Q931ie_UserUser) + x - 1; + + Q931SetIE(*pIE, *OOff); + + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pie_UserUser + + Parameters: IBuf[IN] Ptr to struct. + OBuf[OUT] Ptr tp packed output buffer. + Octet[IN/OUT] Offset into OBuf. + + Return Value: Error code, 0 = OK + +*****************************************************************************/ +L3INT Q931Pie_UserUser(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet) +{ + Q931ie_UserUser * pIE = (Q931ie_UserUser*)IBuf; + L3INT rc=Q931E_NO_ERROR; + L3INT Beg=*Octet; + L3INT li; + L3INT x; + L3INT l; + + OBuf[(*Octet)++] = Q931ie_USER_USER; + li=(*Octet)++; + + /* Octet 3 */ + OBuf[(*Octet)++] = pIE->ProtDisc; + + /* Octet 4 */ + l = pIE->Size - sizeof(Q931ie_UserUser) + 1; + for(x=0;xUser[x]; + } + + OBuf[li] = (*Octet)-Beg; + return rc; +} + diff --git a/libs/openzap/src/isdn/Q931mes.c b/libs/openzap/src/isdn/Q931mes.c new file mode 100644 index 0000000000..d2066d0358 --- /dev/null +++ b/libs/openzap/src/isdn/Q931mes.c @@ -0,0 +1,1931 @@ +/***************************************************************************** + + FileName: Q931mes.c + + Contents: Pack/Unpack functions. These functions will unpack a Q931 + message from the bit packed original format into structs + that contains variables sized by the user. It will also pack + the struct back into a Q.931 message as required. + + See q931.h for description. + + License/Copyright: + + Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. + email:janvb@caselaboratories.com + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the Case Labs, Ltd nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +*****************************************************************************/ + +#include "Q931.h" + +/***************************************************************************** + + Function: Q931Umes_Alerting + +*****************************************************************************/ + +L3INT Q931Umes_Alerting(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT Size) +{ + L3INT i = IOff; + L3INT ir=0; + L3INT OOff=0; + Q931mes_Alerting *mes = (Q931mes_Alerting*)OBuf; + L3INT rc=Q931E_NO_ERROR; + L3UCHAR mescode = (L3UCHAR)IBuf[IOff]; + while(IOff < Size) + { + switch(mescode) + { + case Q931ie_BEARER_CAPABILITY: + rc = Q931Uie[pTrunk->Dialect][mescode](pTrunk, &mes->BearerCap,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_CHANNEL_IDENTIFICATION: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->ChanID,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_PROGRESS_INDICATOR: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->ProgInd,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_DISPLAY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Display,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_SIGNAL: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Signal,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_HIGH_LAYER_COMPATIBILITY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->HLComp,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + default: + return Q931E_ILLEGAL_IE; + break; + } + } + mes->Size = sizeof(Q931mes_Alerting) - 1 + OOff; + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pmes_Alerting + +*****************************************************************************/ +L3INT Q931Pmes_Alerting(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3INT rc = Q931E_NO_ERROR; + Q931mes_Alerting *pMes = (Q931mes_Alerting *)IBuf; + L3INT Octet = 0; + + /* Q931 Message Header */ + + OBuf[Octet++] = pMes->ProtDisc; /* Protocol discriminator */ + OBuf[Octet++] = 2; /* length is 2 octets */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV>>8); /* msb */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV); /* lsb */ + OBuf[Octet++] = pMes->MesType; /* message header */ + + /* Bearer capability */ + if(Q931IsIEPresent(pMes->BearerCap)) + { + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->BearerCap,pMes->buf), OBuf, &Octet))!=0) + return rc; + } + + /* Channel Identification */ + if(Q931IsIEPresent(pMes->ChanID)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->ChanID,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Progress indicator */ + if(Q931IsIEPresent(pMes->ProgInd)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->ProgInd,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Display */ + if(Q931IsIEPresent(pMes->Display)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Signal */ + if(Q931IsIEPresent(pMes->Signal)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Signal,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* High Layer Compatibility */ + if(Q931IsIEPresent(pMes->HLComp)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->HLComp,pMes->buf), OBuf, &Octet))!=0) + return rc; + + return rc; +} + +/***************************************************************************** + + Function: Q931Umes_CallProceeding + +*****************************************************************************/ +L3INT Q931Umes_CallProceeding(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT Size) +{ + L3INT i = IOff; + L3INT ir=0; + L3INT OOff=0; + Q931mes_CallProceeding *mes = (Q931mes_CallProceeding*)OBuf; + L3INT rc=Q931E_NO_ERROR; + while(IOff < Size) + { + switch(IBuf[IOff]) + { + case Q931ie_BEARER_CAPABILITY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->BearerCap,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_CHANNEL_IDENTIFICATION: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->ChanID,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_PROGRESS_INDICATOR: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->ProgInd,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_DISPLAY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Display,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_HIGH_LAYER_COMPATIBILITY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->HLComp,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + default: + return Q931E_ILLEGAL_IE; + break; + } + } + mes->Size = sizeof(Q931mes_CallProceeding) - 1 + OOff; + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pmes_CallProceeding + +*****************************************************************************/ +L3INT Q931Pmes_CallProceeding(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3INT rc = Q931E_NO_ERROR; + Q931mes_CallProceeding *pMes = (Q931mes_CallProceeding *)IBuf; + L3INT Octet = 0; + + /* Q931 Message Header */ + + OBuf[Octet++] = pMes->ProtDisc; /* Protocol discriminator */ + OBuf[Octet++] = 2; /* length is 2 octets */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV>>8); /* msb */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV); /* lsb */ + OBuf[Octet++] = pMes->MesType; /* message header */ + + /* Bearer capability */ + if(Q931IsIEPresent(pMes->BearerCap)) + { + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->BearerCap,pMes->buf), OBuf, &Octet))!=0) + return rc; + } + + /* Channel Identification */ + if(Q931IsIEPresent(pMes->ChanID)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->ChanID,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Progress indicator */ + if(Q931IsIEPresent(pMes->ProgInd)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->ProgInd,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Display */ + if(Q931IsIEPresent(pMes->Display)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* High Layer Compatibility */ + if(Q931IsIEPresent(pMes->HLComp)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->HLComp,pMes->buf), OBuf, &Octet))!=0) + return rc; + + return rc; +} + +/***************************************************************************** + + Function: Q931Umes_CongestionControl + +*****************************************************************************/ +L3INT Q931Umes_CongestionControl(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O) +{ + L3BOOL RetCode = L3FALSE; + + NoWarning(OBuf); + NoWarning(IBuf); + + return RetCode; +} + + +/***************************************************************************** + + Function: Q931Pmes_CongestionControl + +*****************************************************************************/ +L3INT Q931Pmes_CongestionControl(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3BOOL RetCode = L3FALSE; + + NoWarning(OBuf); + NoWarning(IBuf); + + return RetCode; +} + +/***************************************************************************** + + Function: Q931Umes_Connect + +*****************************************************************************/ +L3INT Q931Umes_Connect(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT Size) +{ + L3INT i = IOff; + L3INT ir=0; + L3INT OOff=0; + Q931mes_Connect *mes = (Q931mes_Connect*)OBuf; + L3INT rc=Q931E_NO_ERROR; + while(IOff < Size) + { + switch(IBuf[IOff]) + { + case Q931ie_BEARER_CAPABILITY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->BearerCap,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_CHANNEL_IDENTIFICATION: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->ChanID,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_PROGRESS_INDICATOR: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->ProgInd,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_DISPLAY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Display,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_DATETIME: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->DateTime,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_SIGNAL: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Signal,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_LOW_LAYER_COMPATIBILITY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->LLComp,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_HIGH_LAYER_COMPATIBILITY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->HLComp,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + default: + return Q931E_ILLEGAL_IE; + break; + } + } + mes->Size = sizeof(Q931mes_Connect) - 1 + OOff; + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pmes_Connect + +*****************************************************************************/ +L3INT Q931Pmes_Connect(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3INT rc = Q931E_NO_ERROR; + Q931mes_Connect *pMes = (Q931mes_Connect *)IBuf; + L3INT Octet = 0; + + /* Q931 Message Header */ + + OBuf[Octet++] = pMes->ProtDisc; /* Protocol discriminator */ + OBuf[Octet++] = 2; /* length is 2 octets */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV>>8); /* msb */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV); /* lsb */ + OBuf[Octet++] = pMes->MesType; /* message header */ + + /* Bearer capability */ + if(Q931IsIEPresent(pMes->BearerCap)) + { + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->BearerCap,pMes->buf), OBuf, &Octet))!=0) + return rc; + } + + /* Channel Identification */ + if(Q931IsIEPresent(pMes->ChanID)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->ChanID,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Progress indicator */ + if(Q931IsIEPresent(pMes->ProgInd)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->ProgInd,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Display */ + if(Q931IsIEPresent(pMes->Display)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Date/Time */ + if(Q931IsIEPresent(pMes->DateTime)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->DateTime,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Signal */ + if(Q931IsIEPresent(pMes->Signal)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Signal,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Low Layer Compatibility */ + if(Q931IsIEPresent(pMes->LLComp)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->LLComp,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* High Layer Compatibility */ + if(Q931IsIEPresent(pMes->HLComp)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->HLComp,pMes->buf), OBuf, &Octet))!=0) + return rc; + + return rc; +} + +/***************************************************************************** + + Function: Q931Umes_ConnectAck + +*****************************************************************************/ +L3INT Q931Umes_ConnectAck(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT Size) +{ + L3INT i = IOff; + L3INT ir=0; + L3INT OOff=0; + Q931mes_ConnectAck *mes = (Q931mes_ConnectAck*)OBuf; + L3INT rc=Q931E_NO_ERROR; + while(IOff < Size) + { + switch(IBuf[IOff]) + { + case Q931ie_DISPLAY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Display,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + + case Q931ie_SIGNAL: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Signal,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + default: + return Q931E_ILLEGAL_IE; + break; + } + } + mes->Size = sizeof(Q931mes_ConnectAck) - 1 + OOff; + return Q931E_NO_ERROR; +} + + +/***************************************************************************** + + Function: Q931Pmes_ConnectAck + +*****************************************************************************/ +L3INT Q931Pmes_ConnectAck(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3INT rc = Q931E_NO_ERROR; + Q931mes_ConnectAck *pMes = (Q931mes_ConnectAck *)IBuf; + L3INT Octet = 0; + + /* Q931 Message Header */ + + OBuf[Octet++] = pMes->ProtDisc; /* Protocol discriminator */ + OBuf[Octet++] = 2; /* length is 2 octets */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV>>8); /* msb */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV); /* lsb */ + OBuf[Octet++] = pMes->MesType; /* message header */ + + /* Display */ + if(Q931IsIEPresent(pMes->Display)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Signal */ + if(Q931IsIEPresent(pMes->Signal)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Signal,pMes->buf), OBuf, &Octet))!=0) + return rc; + + return rc; +} + +/***************************************************************************** + + Function: Q931Umes_Disconnect + +*****************************************************************************/ +L3INT Q931Umes_Disconnect(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT Size) +{ + L3INT i = IOff; + L3INT ir=0; + L3INT OOff=0; + Q931mes_Disconnect *mes = (Q931mes_Disconnect*)OBuf; + L3INT rc=Q931E_NO_ERROR; + while(IOff < Size) + { + switch(IBuf[IOff]) + { + case Q931ie_CAUSE: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Cause,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_PROGRESS_INDICATOR: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->ProgInd,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_DISPLAY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Display,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_SIGNAL: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Signal,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + default: + return Q931E_ILLEGAL_IE; + break; + } + } + mes->Size = sizeof(Q931mes_Disconnect) - 1 + OOff; + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pmes_Disconnect + +*****************************************************************************/ +L3INT Q931Pmes_Disconnect(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3INT rc = Q931E_NO_ERROR; + Q931mes_Disconnect *pMes = (Q931mes_Disconnect *)IBuf; + L3INT Octet = 0; + + /* Q931 Message Header */ + + OBuf[Octet++] = pMes->ProtDisc; /* Protocol discriminator */ + OBuf[Octet++] = 2; /* length is 2 octets */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV>>8); /* msb */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV); /* lsb */ + OBuf[Octet++] = pMes->MesType; /* message header */ + + /* Cause */ + if(Q931IsIEPresent(pMes->Cause)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Cause,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Progress indicator */ + if(Q931IsIEPresent(pMes->ProgInd)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->ProgInd,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Display */ + if(Q931IsIEPresent(pMes->Display)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Signal */ + if(Q931IsIEPresent(pMes->Signal)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Signal,pMes->buf), OBuf, &Octet))!=0) + return rc; + + return rc; +} + +/***************************************************************************** + + Function: Q931Umes_Information + +*****************************************************************************/ +L3INT Q931Umes_Information(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT Size) +{ + L3INT i = IOff; + L3INT ir=0; + L3INT OOff=0; + Q931mes_Information *mes = (Q931mes_Information*)OBuf; + L3INT rc=Q931E_NO_ERROR; + while(IOff < Size) + { + switch(IBuf[IOff]) + { + case Q931ie_SENDING_COMPLETE: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->SendComplete,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + + case Q931ie_DISPLAY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Display,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + + case Q931ie_KEYPAD_FACILITY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->KeypadFac,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + + case Q931ie_CALLED_PARTY_NUMBER: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->CalledNum,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + + default: + return Q931E_ILLEGAL_IE; + break; + } + } + mes->Size = sizeof(Q931mes_Information) - 1 + OOff; + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pmes_Information + +*****************************************************************************/ +L3INT Q931Pmes_Information(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3INT rc = Q931E_NO_ERROR; + Q931mes_Information *pMes = (Q931mes_Information *)IBuf; + L3INT Octet = 0; + + /* Q931 Message Header */ + + OBuf[Octet++] = pMes->ProtDisc; /* Protocol discriminator */ + OBuf[Octet++] = 2; /* length is 2 octets */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV>>8); /* msb */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV); /* lsb */ + OBuf[Octet++] = pMes->MesType; /* message header */ + + /* Sending Complete */ + if(Q931IsIEPresent(pMes->SendComplete)) + OBuf[Octet++] = (L3UCHAR)(pMes->SendComplete & 0x00ff); + + /* Display */ + if(Q931IsIEPresent(pMes->Display)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Keypad Facility */ + if(Q931IsIEPresent(pMes->KeypadFac)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->KeypadFac,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Signal */ + if(Q931IsIEPresent(pMes->Signal)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Signal,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Called Party number */ + if(Q931IsIEPresent(pMes->CalledNum)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->CalledNum,pMes->buf), OBuf, &Octet))!=0) + return rc; + + return rc; +} + +/***************************************************************************** + + Function: Q931Umes_Notify + +*****************************************************************************/ +L3INT Q931Umes_Notify(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT Size) +{ + L3INT i = IOff; + L3INT ir=0; + L3INT OOff=0; + Q931mes_Notify *mes = (Q931mes_Notify*)OBuf; + L3INT rc=Q931E_NO_ERROR; + while(IOff < Size) + { + switch(IBuf[IOff]) + { + case Q931ie_BEARER_CAPABILITY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->BearerCap,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + + case Q931ie_NOTIFICATION_INDICATOR: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->NotifInd,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + + case Q931ie_DISPLAY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Display,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + } + } + mes->Size = sizeof(Q931mes_Notify) - 1 + OOff; + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pmes_Notify + +*****************************************************************************/ +L3INT Q931Pmes_Notify(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3INT rc = Q931E_NO_ERROR; + Q931mes_Notify *pMes = (Q931mes_Notify *)IBuf; + L3INT Octet = 0; + + /* Q931 Message Header */ + + OBuf[Octet++] = pMes->ProtDisc; /* Protocol discriminator */ + OBuf[Octet++] = 2; /* length is 2 octets */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV>>8); /* msb */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV); /* lsb */ + OBuf[Octet++] = pMes->MesType; /* message header */ + + /* Bearer capability */ + if(Q931IsIEPresent(pMes->BearerCap)) + { + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->BearerCap,pMes->buf), OBuf, &Octet))!=0) + return rc; + } + + /* Display */ + if(Q931IsIEPresent(pMes->Display)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet))!=0) + return rc; + + return rc; +} + +/***************************************************************************** + + Function: Q931Umes_Progress + +*****************************************************************************/ +L3INT Q931Umes_Progress(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT Size) +{ + L3INT i = IOff; + L3INT ir=0; + L3INT OOff=0; + Q931mes_Progress *mes = (Q931mes_Progress*)OBuf; + L3INT rc=Q931E_NO_ERROR; + while(IOff < Size) + { + switch(IBuf[IOff]) + { + case Q931ie_BEARER_CAPABILITY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->BearerCap,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_CAUSE: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Cause,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_PROGRESS_INDICATOR: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->ProgInd,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_DISPLAY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Display,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_HIGH_LAYER_COMPATIBILITY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->HLComp,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + default: + return Q931E_ILLEGAL_IE; + break; + } + } + mes->Size = sizeof(Q931mes_Progress) - 1 + OOff; + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pmes_Progress + +*****************************************************************************/ +L3INT Q931Pmes_Progress(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3INT rc = Q931E_NO_ERROR; + Q931mes_Progress *pMes = (Q931mes_Progress *)IBuf; + L3INT Octet = 0; + + /* Q931 Message Header */ + + OBuf[Octet++] = pMes->ProtDisc; /* Protocol discriminator */ + OBuf[Octet++] = 2; /* length is 2 octets */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV>>8); /* msb */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV); /* lsb */ + OBuf[Octet++] = pMes->MesType; /* message header */ + + /* Bearer capability */ + if(Q931IsIEPresent(pMes->BearerCap)) + { + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->BearerCap,pMes->buf), OBuf, &Octet))!=0) + return rc; + } + + /* Cause */ + if(Q931IsIEPresent(pMes->Cause)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Cause,pMes->buf), OBuf, &Octet))!=0) + return rc; + /* Progress indicator */ + if(Q931IsIEPresent(pMes->ProgInd)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->ProgInd,pMes->buf), OBuf, &Octet))!=0) + return rc; + /* Display */ + if(Q931IsIEPresent(pMes->Display)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet))!=0) + return rc; + /* High Layer Compatibility */ + if(Q931IsIEPresent(pMes->HLComp)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->HLComp,pMes->buf), OBuf, &Octet))!=0) + return rc; + + return rc; +} + +/***************************************************************************** + + Function: Q931Umes_Release + +*****************************************************************************/ +L3INT Q931Umes_Release(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT Size) +{ + L3INT i = IOff; + L3INT ir=0; + L3INT OOff=0; + Q931mes_Release *mes = (Q931mes_Release*)OBuf; + L3INT rc=Q931E_NO_ERROR; + while(IOff < Size) + { + switch(IBuf[IOff]) + { + case Q931ie_CAUSE: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Cause,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_DISPLAY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Display,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_SIGNAL: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Signal,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + default: + return Q931E_ILLEGAL_IE; + break; + } + } + mes->Size = sizeof(Q931mes_Release) - 1 + OOff; + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pmes_Release + +*****************************************************************************/ +L3INT Q931Pmes_Release(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3INT rc = Q931E_NO_ERROR; + Q931mes_Release *pMes = (Q931mes_Release *)IBuf; + L3INT Octet = 0; + + /* Q931 Message Header */ + + OBuf[Octet++] = pMes->ProtDisc; /* Protocol discriminator */ + OBuf[Octet++] = 2; /* length is 2 octets */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV>>8); /* msb */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV); /* lsb */ + OBuf[Octet++] = pMes->MesType; /* message header */ + + /* Cause */ + if(Q931IsIEPresent(pMes->Cause)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Cause,pMes->buf), OBuf, &Octet))!=0) + return rc; + /* Display */ + if(Q931IsIEPresent(pMes->Display)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet))!=0) + return rc; + /* Signal */ + if(Q931IsIEPresent(pMes->Signal)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Signal,pMes->buf), OBuf, &Octet))!=0) + return rc; + + return rc; +} + +/***************************************************************************** + + Function: Q931Umes_ReleaseComplete + +*****************************************************************************/ +L3INT Q931Umes_ReleaseComplete(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT Size) +{ + L3INT i = IOff; + L3INT ir=0; + L3INT OOff=0; + Q931mes_ReleaseComplete *mes = (Q931mes_ReleaseComplete*)OBuf; + L3INT rc=Q931E_NO_ERROR; + while(IOff < Size) + { + switch(IBuf[IOff]) + { + case Q931ie_CAUSE: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Cause,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_DISPLAY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Display,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_SIGNAL: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Signal,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + default: + return Q931E_ILLEGAL_IE; + break; + } + } + mes->Size = sizeof(Q931mes_ReleaseComplete) - 1 + OOff; + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pmes_ReleaseComplete + +*****************************************************************************/ +L3INT Q931Pmes_ReleaseComplete(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3INT rc = Q931E_NO_ERROR; + Q931mes_ReleaseComplete *pMes = (Q931mes_ReleaseComplete *)IBuf; + L3INT Octet = 0; + + /* Q931 Message Header */ + + OBuf[Octet++] = pMes->ProtDisc; /* Protocol discriminator */ + OBuf[Octet++] = 2; /* length is 2 octets */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV>>8); /* msb */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV); /* lsb */ + OBuf[Octet++] = pMes->MesType; /* message header */ + + /* Cause */ + if(Q931IsIEPresent(pMes->Cause)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Cause,pMes->buf), OBuf, &Octet))!=0) + return rc; + /* Display */ + if(Q931IsIEPresent(pMes->Display)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet))!=0) + return rc; + /* Signal */ + if(Q931IsIEPresent(pMes->Signal)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Signal,pMes->buf), OBuf, &Octet))!=0) + return rc; + + return rc; +} + +/***************************************************************************** + + Function: Q931Umes_Restart + +*****************************************************************************/ +L3INT Q931Umes_Restart(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O) +{ + L3BOOL RetCode = L3FALSE; + + NoWarning(OBuf); + NoWarning(IBuf); + + return RetCode; +} + +/***************************************************************************** + + Function: Q931Pmes_Restart + +*****************************************************************************/ +L3INT Q931Pmes_Restart(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3BOOL RetCode = L3FALSE; + + NoWarning(OBuf); + NoWarning(IBuf); + + return RetCode; +} + +/***************************************************************************** + + Function: Q931Umes_RestartAck + +*****************************************************************************/ +L3INT Q931Umes_RestartAck(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O) +{ + L3BOOL RetCode = L3FALSE; + + NoWarning(OBuf); + NoWarning(IBuf); + + return RetCode; +} + +/***************************************************************************** + + Function: Q931Pmes_RestartAck + +*****************************************************************************/ +L3INT Q931Pmes_RestartAck(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3BOOL RetCode = L3FALSE; + + NoWarning(OBuf); + NoWarning(IBuf); + + return RetCode; +} + +/***************************************************************************** + + Function: Q931Umes_Resume + +*****************************************************************************/ +L3INT Q931Umes_Resume(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT Size) +{ + L3INT i = IOff; + L3INT ir=0; + L3INT OOff=0; + Q931mes_Resume *mes = (Q931mes_Resume*)OBuf; + L3INT rc=Q931E_NO_ERROR; + while(IOff < Size) + { + switch(IBuf[IOff]) + { + case Q931ie_CALL_IDENTITY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->CallID,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + default: + return Q931E_ILLEGAL_IE; + break; + } + } + mes->Size = sizeof(Q931mes_Resume) - 1 + OOff; + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pmes_Resume + +*****************************************************************************/ +L3INT Q931Pmes_Resume(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3INT rc = Q931E_NO_ERROR; + Q931mes_Resume *pMes = (Q931mes_Resume *)IBuf; + L3INT Octet = 0; + + /* Q931 Message Header */ + + OBuf[Octet++] = pMes->ProtDisc; /* Protocol discriminator */ + OBuf[Octet++] = 2; /* length is 2 octets */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV>>8); /* msb */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV); /* lsb */ + OBuf[Octet++] = pMes->MesType; /* message header */ + + /* Call Identity */ + if(Q931IsIEPresent(pMes->CallID)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->CallID,pMes->buf), OBuf, &Octet))!=0) + return rc; + + return rc; +} + +/***************************************************************************** + + Function: Q931Umes_ResumeAck + +*****************************************************************************/ +L3INT Q931Umes_ResumeAck(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT Size) +{ + L3INT i = IOff; + L3INT ir=0; + L3INT OOff=0; + Q931mes_ResumeAck *mes = (Q931mes_ResumeAck*)OBuf; + L3INT rc=Q931E_NO_ERROR; + while(IOff < Size) + { + switch(IBuf[IOff]) + { + case Q931ie_CHANNEL_IDENTIFICATION: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->ChanID,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_DISPLAY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Display,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + default: + return Q931E_ILLEGAL_IE; + break; + } + } + mes->Size = sizeof(Q931mes_ResumeAck) - 1 + OOff; + return Q931E_NO_ERROR; +} + + +/***************************************************************************** + + Function: Q931Pmes_ResumeAck + +*****************************************************************************/ +L3INT Q931Pmes_ResumeAck(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3INT rc = Q931E_NO_ERROR; + Q931mes_ResumeAck *pMes = (Q931mes_ResumeAck *)IBuf; + L3INT Octet = 0; + + /* Q931 Message Header */ + + OBuf[Octet++] = pMes->ProtDisc; /* Protocol discriminator */ + OBuf[Octet++] = 2; /* length is 2 octets */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV>>8); /* msb */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV); /* lsb */ + OBuf[Octet++] = pMes->MesType; /* message header */ + + /* Channel Identification */ + if(Q931IsIEPresent(pMes->ChanID)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->ChanID,pMes->buf), OBuf, &Octet))!=0) + return rc; + /* Display */ + if(Q931IsIEPresent(pMes->Display)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet))!=0) + return rc; + + return rc; +} + +/***************************************************************************** + + Function: Q931Umes_ResumeReject + +*****************************************************************************/ +L3INT Q931Umes_ResumeReject(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT IOff, L3INT Size) +{ + L3INT i = IOff; + L3INT ir=0; + L3INT OOff=0; + Q931mes_ResumeReject *mes = (Q931mes_ResumeReject*)OBuf; + L3INT rc=Q931E_NO_ERROR; + while(IOff < Size) + { + switch(IBuf[IOff]) + { + case Q931ie_CAUSE: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Cause,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_DISPLAY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Display,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + default: + return Q931E_ILLEGAL_IE; + break; + } + } + mes->Size = sizeof(Q931mes_ResumeReject) - 1 + OOff; + return Q931E_NO_ERROR; +} + + +/***************************************************************************** + + Function: Q931Pmes_ResumeReject + +*****************************************************************************/ +L3INT Q931Pmes_ResumeReject(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3INT rc = Q931E_NO_ERROR; + Q931mes_ResumeReject *pMes = (Q931mes_ResumeReject *)IBuf; + L3INT Octet = 0; + + /* Q931 Message Header */ + OBuf[Octet++] = pMes->ProtDisc; /* Protocol discriminator */ + OBuf[Octet++] = 2; /* length is 2 octets */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV>>8); /* msb */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV); /* lsb */ + OBuf[Octet++] = pMes->MesType; /* message header */ + + /* Cause */ + if(Q931IsIEPresent(pMes->Cause)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Cause,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Display */ + if(Q931IsIEPresent(pMes->Display)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet))!=0) + return rc; + + return rc; +} + +L3INT Q931Umes_Segment(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT OOff) +{ + L3INT i = IOff; + + return IOff - i; +} + +L3INT Q931Pmes_Segment(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3BOOL RetCode = L3FALSE; + + return RetCode; +} + +/***************************************************************************** + + Function: Q931Umes_Setup + +*****************************************************************************/ +L3INT Q931Umes_Setup(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT Size) +{ + L3INT i = IOff; + L3INT ir=0; + L3INT OOff=0; + Q931mes_Setup *mes = (Q931mes_Setup*)OBuf; + L3INT rc=Q931E_NO_ERROR; + while(IOff < Size) + { + switch(IBuf[IOff]) + { + case Q931ie_SENDING_COMPLETE: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->SendComplete,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_REPEAT_INDICATOR: + if(ir==0) + { + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->RepeatInd,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + ir++; + } + else if(ir==1) + { + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->LLRepeatInd,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + ir++; + } + else + { + return Q931E_ILLEGAL_IE; + } + break; + case Q931ie_BEARER_CAPABILITY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->BearerCap,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_CHANNEL_IDENTIFICATION: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->ChanID,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_PROGRESS_INDICATOR: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->ProgInd,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_NETWORK_SPECIFIC_FACILITIES: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->NetFac,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_DISPLAY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Display,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_DATETIME: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->DateTime,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_KEYPAD_FACILITY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->KeypadFac,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_SIGNAL: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Signal,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_CALLING_PARTY_NUMBER: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->CallingNum,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_CALLING_PARTY_SUBADDRESS: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->CallingSub,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_CALLED_PARTY_NUMBER: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->CalledSub,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_CALLED_PARTY_SUBADDRESS: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->CalledSub,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_TRANSIT_NETWORK_SELECTION: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->TransNetSel,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_LOW_LAYER_COMPATIBILITY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->LLComp,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_HIGH_LAYER_COMPATIBILITY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->HLComp,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + default: + return Q931E_ILLEGAL_IE; + break; + } + } + mes->Size = sizeof(Q931mes_Setup) - 1 + OOff; + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pmes_Setup + + Decription: Pack a Q931mes_Setup into a real Q.931 message. The user will + set up a SETUP message and issue this to the stack where it + is processed by Q931ProcSetup that processes and validates + it before it actually sends it out. This function is called + to compute the real Q.931 message. + + Parameters: IBuf[IN] Ptr to un-packed struct + ISize[IN] Size of input buffer (unpacked message). + OBuf[OUT] Ptr to packed 'octet' wise message. + OSize[OUT] Size of packed message. + + Called By: Q931ProcSetup + +*****************************************************************************/ +L3INT Q931Pmes_Setup(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3INT rc = Q931E_NO_ERROR; + Q931mes_Setup *pMes = (Q931mes_Setup *)IBuf; + L3INT Octet = 0; + + /* Q931 Message Header */ + + OBuf[Octet++] = pMes->ProtDisc; /* Protocol discriminator */ + OBuf[Octet++] = 2; /* length is 2 octets */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV>>8); /* msb */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV); /* lsb */ + OBuf[Octet++] = pMes->MesType; /* message header */ + + /* Sending Complete */ + if(Q931IsIEPresent(pMes->SendComplete)) + OBuf[Octet++] = (L3UCHAR)(pMes->SendComplete & 0x00ff); + + /* Repeat Indicator */ + if(Q931IsIEPresent(pMes->RepeatInd)) + OBuf[Octet++] = (L3UCHAR)(pMes->RepeatInd & 0x00ff); + + /* Bearer capability */ + if(Q931IsIEPresent(pMes->BearerCap)) + { + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->BearerCap,pMes->buf), OBuf, &Octet))!=0) + return rc; + } + else + { + rc=Q931E_BEARERCAP; + } + + /* Channel Identification */ + if(Q931IsIEPresent(pMes->ChanID)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->ChanID,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Progress indicator */ + if(Q931IsIEPresent(pMes->ProgInd)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->ProgInd,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Network spesific facilities */ + if(Q931IsIEPresent(pMes->NetFac)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->NetFac,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Display */ + if(Q931IsIEPresent(pMes->Display)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Date/Time */ + if(Q931IsIEPresent(pMes->DateTime)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->DateTime,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Keypad Facility */ + if(Q931IsIEPresent(pMes->KeypadFac)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->KeypadFac,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Signal */ + if(Q931IsIEPresent(pMes->Signal)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Signal,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Calling Party Number */ + if(Q931IsIEPresent(pMes->CallingNum)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->CallingNum,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Calling Party Subaddress */ + if(Q931IsIEPresent(pMes->CallingSub)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->CallingSub,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Called Party number */ + if(Q931IsIEPresent(pMes->CalledNum)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->CalledNum,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Called party subaddress */ + if(Q931IsIEPresent(pMes->CalledSub)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->CalledSub,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Transit network selection */ + if(Q931IsIEPresent(pMes->TransNetSel)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->TransNetSel,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Repeat Indicator */ + if(Q931IsIEPresent(pMes->LLRepeatInd)) + ;//TODO + + /* Low Layer Compatibility */ + if(Q931IsIEPresent(pMes->LLComp)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->LLComp,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* High Layer Compatibility */ + if(Q931IsIEPresent(pMes->HLComp)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->HLComp,pMes->buf), OBuf, &Octet))!=0) + return rc; + + return rc; +} + +/***************************************************************************** + + Function: Q931Umes_SetupAck + +*****************************************************************************/ +L3INT Q931Umes_SetupAck(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT Size) +{ + L3INT i = IOff; + L3INT ir=0; + L3INT OOff=0; + Q931mes_SetupAck *mes = (Q931mes_SetupAck*)OBuf; + L3INT rc=Q931E_NO_ERROR; + while(IOff < Size) + { + switch(IBuf[IOff]) + { + case Q931ie_CHANNEL_IDENTIFICATION: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->ChanID,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_PROGRESS_INDICATOR: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->ProgInd,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_DISPLAY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Display,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_SIGNAL: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Signal,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + default: + return Q931E_ILLEGAL_IE; + break; + } + } + mes->Size = sizeof(Q931mes_SetupAck) - 1 + OOff; + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pmes_SetupAck + +*****************************************************************************/ +L3INT Q931Pmes_SetupAck(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3INT rc = Q931E_NO_ERROR; + Q931mes_SetupAck *pMes = (Q931mes_SetupAck *)IBuf; + L3INT Octet = 0; + + /* Q931 Message Header */ + + OBuf[Octet++] = pMes->ProtDisc; /* Protocol discriminator */ + OBuf[Octet++] = 2; /* length is 2 octets */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV>>8); /* msb */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV); /* lsb */ + OBuf[Octet++] = pMes->MesType; /* message header */ + + /* Channel Identification */ + if(Q931IsIEPresent(pMes->ChanID)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->ChanID,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Progress indicator */ + if(Q931IsIEPresent(pMes->ProgInd)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->ProgInd,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Display */ + if(Q931IsIEPresent(pMes->Display)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Signal */ + if(Q931IsIEPresent(pMes->Signal)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Signal,pMes->buf), OBuf, &Octet))!=0) + return rc; + + return rc; +} + +/***************************************************************************** + + Function: Q931Umes_Status + +*****************************************************************************/ +L3INT Q931Umes_Status(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT Size) +{ + L3INT i = IOff; + L3INT ir=0; + L3INT OOff=0; + Q931mes_Status *mes = (Q931mes_Status*)OBuf; + L3INT rc=Q931E_NO_ERROR; + while(IOff < Size) + { + switch(IBuf[IOff]) + { + case Q931ie_CAUSE: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Cause,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_CALL_STATE: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->CallState,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_DISPLAY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Display,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + default: + return Q931E_ILLEGAL_IE; + break; + } + } + mes->Size = sizeof(Q931mes_Status) - 1 + OOff; + return Q931E_NO_ERROR; +} + + +/***************************************************************************** + + Function: Q931Pmes_Status + +*****************************************************************************/ +L3INT Q931Pmes_Status(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3INT rc = Q931E_NO_ERROR; + Q931mes_Status *pMes = (Q931mes_Status *)IBuf; + L3INT Octet = 0; + + /* Q931 Message Header */ + + OBuf[Octet++] = pMes->ProtDisc; /* Protocol discriminator */ + OBuf[Octet++] = 2; /* length is 2 octets */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV>>8); /* msb */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV); /* lsb */ + OBuf[Octet++] = pMes->MesType; /* message header */ + + /* Cause */ + if(Q931IsIEPresent(pMes->Cause)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Cause,pMes->buf), OBuf, &Octet))!=0) + return rc; + /* Call State */ + if(Q931IsIEPresent(pMes->CallState)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->CallState,pMes->buf), OBuf, &Octet))!=0) + return rc; + /* Display */ + if(Q931IsIEPresent(pMes->Display)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet))!=0) + return rc; + + return rc; +} + +/***************************************************************************** + + Function: Q931Umes_StatusEnquiry + +*****************************************************************************/ +L3INT Q931Umes_StatusEnquiry(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT Size) +{ + L3INT i = IOff; + L3INT ir=0; + L3INT OOff=0; + Q931mes_StatusEnquiry *mes = (Q931mes_StatusEnquiry*)OBuf; + L3INT rc=Q931E_NO_ERROR; + while(IOff < Size) + { + switch(IBuf[IOff]) + { + case Q931ie_DISPLAY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Display,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + default: + return Q931E_ILLEGAL_IE; + break; + } + } + mes->Size = sizeof(Q931mes_StatusEnquiry) - 1 + OOff; + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pmes_StatusEnquiry + +*****************************************************************************/ +L3INT Q931Pmes_StatusEnquiry(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3INT rc = Q931E_NO_ERROR; + Q931mes_StatusEnquiry *pMes = (Q931mes_StatusEnquiry *)IBuf; + L3INT Octet = 0; + + /* Q931 Message Header */ + + OBuf[Octet++] = pMes->ProtDisc; /* Protocol discriminator */ + OBuf[Octet++] = 2; /* length is 2 octets */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV>>8); /* msb */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV); /* lsb */ + OBuf[Octet++] = pMes->MesType; /* message header */ + + /* Display */ + if(Q931IsIEPresent(pMes->Display)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet))!=0) + return rc; + + return rc; +} + +/***************************************************************************** + + Function: Q931Umes_Suspend + +*****************************************************************************/ +L3INT Q931Umes_Suspend(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT Size) +{ + L3INT i = IOff; + L3INT ir=0; + L3INT OOff=0; + Q931mes_Suspend *mes = (Q931mes_Suspend*)OBuf; + L3INT rc=Q931E_NO_ERROR; + while(IOff < Size) + { + switch(IBuf[IOff]) + { + case Q931ie_CALL_IDENTITY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->CallID,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + default: + return Q931E_ILLEGAL_IE; + break; + } + } + mes->Size = sizeof(Q931mes_Suspend) - 1 + OOff; + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pmes_Suspend + +*****************************************************************************/ +L3INT Q931Pmes_Suspend(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3INT rc = Q931E_NO_ERROR; + Q931mes_Suspend *pMes = (Q931mes_Suspend *)IBuf; + L3INT Octet = 0; + + /* Q931 Message Header */ + + OBuf[Octet++] = pMes->ProtDisc; /* Protocol discriminator */ + OBuf[Octet++] = 2; /* length is 2 octets */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV>>8); /* msb */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV); /* lsb */ + OBuf[Octet++] = pMes->MesType; /* message header */ + + /* Call Identity */ + if(Q931IsIEPresent(pMes->CallID)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->CallID,pMes->buf), OBuf, &Octet))!=0) + return rc; + + return rc; +} + +/***************************************************************************** + + Function: Q931Umes_SuspendAck + +*****************************************************************************/ +L3INT Q931Umes_SuspendAck(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT Size) +{ + L3INT i = IOff; + L3INT ir=0; + L3INT OOff=0; + Q931mes_SuspendAck *mes = (Q931mes_SuspendAck*)OBuf; + L3INT rc=Q931E_NO_ERROR; + while(IOff < Size) + + { + switch(IBuf[IOff]) + { + case Q931ie_DISPLAY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Display,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + default: + return Q931E_ILLEGAL_IE; + break; + } + } + mes->Size = sizeof(Q931mes_SuspendAck) - 1 + OOff; + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pmes_SuspendAck + +*****************************************************************************/ +L3INT Q931Pmes_SuspendAck(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3INT rc = Q931E_NO_ERROR; + Q931mes_SuspendAck *pMes = (Q931mes_SuspendAck *)IBuf; + L3INT Octet = 0; + + /* Q931 Message Header */ + + OBuf[Octet++] = pMes->ProtDisc; /* Protocol discriminator */ + OBuf[Octet++] = 2; /* length is 2 octets */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV>>8); /* msb */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV); /* lsb */ + OBuf[Octet++] = pMes->MesType; /* message header */ + + /* Display */ + if(Q931IsIEPresent(pMes->Display)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet))!=0) + return rc; + + return rc; +} + +/***************************************************************************** + + Function: Q931Umes_SuspendReject + +*****************************************************************************/ +L3INT Q931Umes_SuspendReject(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT Size) +{ + L3INT i = IOff; + L3INT ir=0; + L3INT OOff=0; + Q931mes_SuspendReject *mes = (Q931mes_SuspendReject*)OBuf; + L3INT rc=Q931E_NO_ERROR; + while(IOff < Size) + { + switch(IBuf[IOff]) + { + case Q931ie_CAUSE: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Cause,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + case Q931ie_DISPLAY: + rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, &mes->Display,&IBuf[IOff], &OBuf[OOff], &IOff, &OOff); + if(rc != Q931E_NO_ERROR) + return rc; + break; + default: + return Q931E_ILLEGAL_IE; + break; + } + } + mes->Size = sizeof(Q931mes_SuspendReject) - 1 + OOff; + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pmes_SuspendReject + +*****************************************************************************/ +L3INT Q931Pmes_SuspendReject(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3INT rc = Q931E_NO_ERROR; + Q931mes_SuspendReject *pMes = (Q931mes_SuspendReject *)IBuf; + L3INT Octet = 0; + + /* Q931 Message Header */ + + OBuf[Octet++] = pMes->ProtDisc; /* Protocol discriminator */ + OBuf[Octet++] = 2; /* length is 2 octets */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV>>8); /* msb */ + OBuf[Octet++] = (L3UCHAR)(pMes->CRV); /* lsb */ + OBuf[Octet++] = pMes->MesType; /* message header */ + + /* Cause */ + if(Q931IsIEPresent(pMes->Cause)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Cause,pMes->buf), OBuf, &Octet))!=0) + return rc; + + /* Display */ + if(Q931IsIEPresent(pMes->Display)) + if((rc=Q931Pie[pTrunk->Dialect][pMes->MesType](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet))!=0) + return rc; + + return rc; +} + +/***************************************************************************** + + Function: Q931Umes_UserInformation + +*****************************************************************************/ +L3INT Q931Umes_UserInformation(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O) +{ + L3BOOL RetCode = L3FALSE; + + NoWarning(OBuf); + NoWarning(IBuf); + + return RetCode; +} + +/***************************************************************************** + + Function: Q931Pmes_UserInformation + +*****************************************************************************/ +L3INT Q931Pmes_UserInformation(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3BOOL RetCode = L3FALSE; + + NoWarning(OBuf); + NoWarning(IBuf); + + return RetCode; +} + diff --git a/libs/openzap/src/isdn/Q932mes.c b/libs/openzap/src/isdn/Q932mes.c new file mode 100644 index 0000000000..0540fa80f0 --- /dev/null +++ b/libs/openzap/src/isdn/Q932mes.c @@ -0,0 +1,311 @@ +/***************************************************************************** + + FileName: Q932mes.c + + Contents: Q.932 Message Encoders/Decoders + + License/Copyright: + + Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. + email:janvb@caselaboratories.com + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the Case Labs, Ltd nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*****************************************************************************/ + +#include "Q931.h" + +/***************************************************************************** + + Function: Q932Umes_Facility + +*****************************************************************************/ + +L3INT Q932Umes_Facility(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT Size) +{ + L3INT i = IOff; + L3INT ir=0; + L3INT OOff=0; + L3INT rc=Q931E_NO_ERROR; + Q932mes_Facility *mes = (Q932mes_Facility*)IBuf; + + //TODO + + mes->Size = sizeof(Q932mes_Facility) - 1 + OOff; + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pmes_Facility + +*****************************************************************************/ +L3INT Q932Pmes_Facility(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3BOOL RetCode = L3FALSE; + + NoWarning(OBuf); + NoWarning(IBuf); + + return RetCode; +} + +/***************************************************************************** + + Function: Q932Umes_Hold + +*****************************************************************************/ + +L3INT Q932Umes_Hold(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT Size) +{ + L3INT i = IOff; + L3INT ir=0; + L3INT OOff=0; + Q932mes_Hold *mes = (Q932mes_Hold*)IBuf; + + //TODO + + mes->Size = sizeof(Q932mes_Hold) - 1 + OOff; + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pmes_Hold + +*****************************************************************************/ +L3INT Q932Pmes_Hold(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3BOOL RetCode = L3FALSE; + + NoWarning(OBuf); + NoWarning(IBuf); + + return RetCode; +} + +/***************************************************************************** + + Function: Q932Umes_HoldAck + +*****************************************************************************/ + +L3INT Q932Umes_HoldAck(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT Size) +{ + L3INT i = IOff; + L3INT ir=0; + L3INT OOff=0; + Q932mes_HoldAck *mes = (Q932mes_HoldAck*)IBuf; + + //TODO + + mes->Size = sizeof(Q932mes_HoldAck) - 1 + OOff; + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pmes_HoldAck + +*****************************************************************************/ +L3INT Q932Pmes_HoldAck(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3BOOL RetCode = L3FALSE; + + NoWarning(OBuf); + NoWarning(IBuf); + + return RetCode; +} + +/***************************************************************************** + + Function: Q932Umes_HoldReject + +*****************************************************************************/ + +L3INT Q932Umes_HoldReject(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT Size) +{ + L3INT i = IOff; + L3INT ir=0; + L3INT OOff=0; + Q932mes_HoldReject *mes = (Q932mes_HoldReject*)IBuf; + + //TODO + + mes->Size = sizeof(Q932mes_HoldReject) - 1 + OOff; + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pmes_HoldReject + +*****************************************************************************/ +L3INT Q932Pmes_HoldReject(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3BOOL RetCode = L3FALSE; + + NoWarning(OBuf); + NoWarning(IBuf); + + return RetCode; +} + +/***************************************************************************** + + Function: Q932Umes_Register + +*****************************************************************************/ + +L3INT Q932Umes_Register(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT Size) +{ + L3INT i = IOff; + L3INT ir=0; + L3INT OOff=0; + Q932mes_Register *mes = (Q932mes_Register*)IBuf; + + //TODO + + mes->Size = sizeof(Q932mes_Register) - 1 + OOff; + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pmes_Register + +*****************************************************************************/ +L3INT Q932Pmes_Register(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3BOOL RetCode = L3FALSE; + + NoWarning(OBuf); + NoWarning(IBuf); + + return RetCode; +} + +/***************************************************************************** + + Function: Q932Umes_Retrieve + +*****************************************************************************/ + +L3INT Q932Umes_Retrieve(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT Size) +{ + L3INT i = IOff; + L3INT ir=0; + L3INT OOff=0; + Q932mes_Retrieve *mes = (Q932mes_Retrieve*)IBuf; + + //TODO + + mes->Size = sizeof(Q932mes_Retrieve) - 1 + OOff; + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pmes_Retrieve + +*****************************************************************************/ +L3INT Q932Pmes_Retrieve(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3BOOL RetCode = L3FALSE; + + NoWarning(OBuf); + NoWarning(IBuf); + + return RetCode; +} + +/***************************************************************************** + + Function: Q932Umes_RetrieveAck + +*****************************************************************************/ + +L3INT Q932Umes_RetrieveAck(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT Size) +{ + L3INT i = IOff; + L3INT ir=0; + L3INT OOff=0; + Q932mes_RetrieveAck *mes = (Q932mes_RetrieveAck*)IBuf; + + //TODO + + mes->Size = sizeof(Q932mes_RetrieveAck) - 1 + OOff; + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pmes_RetrieveAck + +*****************************************************************************/ +L3INT Q932Pmes_RetrieveAck(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3BOOL RetCode = L3FALSE; + + NoWarning(OBuf); + NoWarning(IBuf); + + return RetCode; +} + +/***************************************************************************** + + Function: Q932Umes_RetrieveReject + +*****************************************************************************/ + +L3INT Q932Umes_RetrieveReject(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT Size) +{ + L3INT i = IOff; + L3INT ir=0; + L3INT OOff=0; + Q932mes_RetrieveReject *mes = (Q932mes_RetrieveReject*)IBuf; + + //TODO + + mes->Size = sizeof(Q932mes_RetrieveReject) - 1 + OOff; + return Q931E_NO_ERROR; +} + +/***************************************************************************** + + Function: Q931Pmes_RetrieveReject + +*****************************************************************************/ +L3INT Q932Pmes_RetrieveReject(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize) +{ + L3BOOL RetCode = L3FALSE; + + NoWarning(OBuf); + NoWarning(IBuf); + + return RetCode; +} diff --git a/libs/openzap/src/isdn/include/Q921.h b/libs/openzap/src/isdn/include/Q921.h new file mode 100644 index 0000000000..acb830383f --- /dev/null +++ b/libs/openzap/src/isdn/include/Q921.h @@ -0,0 +1,102 @@ +/***************************************************************************** + + FileName: q921.h + + Description: Contains headers of a Q.921 protocol on top of the Comet + Driver. + + Most of the work required to execute a Q.921 protocol is + taken care of by the Comet ship and it's driver. This layer + will simply configure and make use of these features to + complete a Q.921 implementation. + + Note: This header file is the only include file that should be + acessed by users of the Q.921 stack. + + Interface: The Q.921 stack contains 2 layers. + + - One interface layer. + - One driver layer. + + The interface layer contains the interface functions required + for a layer 3 stack to be able to send and receive messages. + + The driver layer will simply feed bytes into the ship as + required and queue messages received out from the ship. + + Q921TimeTick The Q.921 like any other blackbox + modules contains no thread by it's own + and must therefore be called regularly + by an external 'thread' to do maintenance + etc. + + Q921Rx32 Receive message from layer 3. Called by + the layer 3 stack to send a message. + + Q921Tx23 Send a message to layer 3. + + OnQ921Error Function called every if an error is + deteceted. + + OnQ921Log Function called if logging is active. + + + Maintenance/Configuration interface + + Created: 27.dec.2000/JVB + + License/Copyright: + + Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. + email:janvb@caselaboratories.com + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the Case Labs, Ltd nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +*****************************************************************************/ + +#ifndef _Q921 +#define _Q921 + +#define Q921MAXTRUNK 4 +#define Q921MAXHDLCSPACE 3000 + +typedef struct +{ + char HDLCInQueue[Q921MAXHDLCSPACE]; + unsigned char vs; + unsigned char vr; + int state; +}Q921Data; + +void Q921Init(); +void Q921SetHeaderSpace(int hspace); +void Q921SetTx21CB(int (*callback)(int dev, unsigned char *, int)); +void Q921SetTx23CB(int (*callback)(int dev, unsigned char *, int)); +int Q921QueueHDLCFrame(int trunk, char *b, int size); +int Q921Rx12(long trunk); + +#endif + diff --git a/libs/openzap/src/isdn/include/Q931.h b/libs/openzap/src/isdn/include/Q931.h new file mode 100644 index 0000000000..dd8261cff3 --- /dev/null +++ b/libs/openzap/src/isdn/include/Q931.h @@ -0,0 +1,2408 @@ +/****************************************************************************** + + FileName: Q931.h + + Contents: Header and definition for the ITU-T Q.931 stack. The + header contents the following parts: + + - Definition of codes + - Definition of information elements (Q931ie_). + - Definition of messages (Q931mes_). + - Definitian of variables (var_). + - Function prototypes. + + Description: The Q.931 stack provided here covers ITU-T Q.931 w/Q.932 + supplementary services for both PRI, BRI and variants. + The stack is generic and designed to deal with variants as + needed. + + The stack uses the following interface functions: + + - Q931Initialize Initialize the Q.931 stack. + - Q931Rx23 Receive a message from layer 2 + - Q931Tx32 Send a message to layer 2 + - Q931Rx43 Receive a message from layer 4 or above. + - Q931Tx34 Send a message to layer 4 or above. + - Q931TimeTick Periodical timer processing. + - Q931ErrorProc Callback for stack error message. + + The protocol is a module with no external dependencies and + can easely be ported to any operating system like Windows, + Linux, rtos and others. + + Related Files: Q931.h Q.931 Definitions + Q931.c Q.931 Interface Functions. + Q931api.c Low level L4 API functions. + + Q932.h Q.932 Suplementary Services + Q932mes.c Q.932 encoders/coders + + Q931mes.c Q.931 Message encoders/coders + Q931ie.c Q.931 IE encoders/coders + Q931StateTE.c Generic Q.931 TE State Engine + Q931StateNT.c Generic Q.931 NT State Engine + + Design Note 1: For each variant please add separate files starting with + the variant short-name as follows: + + .h Spesific headers needed. + mes.c Message encoders/decores. + ie.c IE encoders/decoders. + StateTE.c TE side state engine. + StateNT.c NT side state engine. + + Design Note 2: The stack is deliberatly made non-threading. Use 1 + thread per Trunk, but lock access from the timertick + and rx, tx functions. And make sure the callbacks only + dump messages to a queue, no time-consuming processing + inside stack processing. + + All stack processing is async 'fire and forget', meaning + that there are not, and should not be any time-consuming + processing within the stack-time. The best way to thread + a stack is to use one single thread that signal 5 queues. + + - Incoming L2 queue. + - Incoming L4 queue. + - Outgoing L2 queue. + - Outgoing L4 queue. + - Error/Trace queue. + + Design Note 3: DSP optimization. The L3 (Rx23) can be called directly + from a hdlc receiver without usage of queues for optimized + processing. But keep in mind that Q.931 calls Tx34 or Tx32 + as part of receiving a message from Layer 2. + + License/Copyright: + + Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. + email:janvb@caselaboratories.com + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the Case Labs, Ltd nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +******************************************************************************/ + +#ifndef _Q931_NL +#define _Q931_NL + +/* uncomment the #define below to add x.25 support to the Q.931 */ +//#define Q931_X25_SUPPORT + +#include "stdio.h" + +/***************************************************************************** + + Error Codes + +*****************************************************************************/ +#define Q931E_NO_ERROR 0 +#define Q931E_UNKNOWN_MESSAGE -3001 +#define Q931E_ILLEGAL_IE -3002 +#define Q931E_UNKNOWN_IE -3003 +#define Q931E_BEARERCAP -3004 +#define Q931E_HLCOMP -3005 +#define Q931E_LLCOMP -3006 +#define Q931E_INTERNAL -3007 +#define Q931E_MISSING_CB -3008 +#define Q931E_UNEXPECTED_MESSAGE -3009 +#define Q931E_ILLEGAL_MESSAGE -3010 +#define Q931E_TOMANYCALLS -3011 +#define Q931E_INVALID_CRV -3012 +#define Q931E_CALLID -3013 +#define Q931E_CALLSTATE -3014 +#define Q931E_CALLEDSUB -3015 +#define Q931E_CALLEDNUM -3016 +#define Q931E_CALLINGNUM -3017 +#define Q931E_CALLINGSUB -3018 +#define Q931E_CAUSE -3019 +#define Q931E_CHANID -3020 +#define Q931E_DATETIME -3021 +#define Q931E_DISPLAY -3022 +#define Q931E_KEYPADFAC -3023 +#define Q931E_NETFAC -3024 +#define Q931E_NOTIFIND -3025 +#define Q931E_PROGIND -3026 +#define Q931E_RESTARTIND -3027 +#define Q931E_SEGMENT -3028 +#define Q931E_SIGNAL -3029 + +/***************************************************************************** + + Some speed optimization can be achieved by changing all variables to the + word size of your processor. A 32 bit processor have to do a lot of extra + work to read a packed 8 bit integer. Changing all fields to 32 bit integer + will ressult in usage of some extra space, but speed up the stack. + + The stack have been designed to allow L3UCHAR etc. to be any size of 8 bit + or larger. + +*****************************************************************************/ + +#define L3UCHAR unsigned char /* Min 8 bit */ +#define L3USHORT unsigned short /* Min 16 bit unsigned */ +#define L3UINT unsigned int /* Min 16 bit unsigned */ +#define L3INT int /* Min 16 bit signed */ +#define L3ULONG unsigned long /* Min 32 bit */ +#define L3BOOL char /* Min 1 bit, valuse 0 & 1 only */ + +#define L3TRUE 1 +#define L3FALSE 0 + +/***************************************************************************** + + MAXTRUNKS sets how many physical trunks this system might have. This + number should be keept at a minimum since it will use global space. + + It is recommended that you leave MAXCHPERTRUNK as is + +*****************************************************************************/ + +#define Q931L4BUF 1000 /* size of message buffer */ + +#define Q931L2BUF 300 /* size of message buffer */ + +#define Q931MAXTRUNKS 1 /* Total number of trunks that will be */ + /* processed by this instance of the */ + /* stack */ + +#define Q931MAXCHPERTRUNK 32 /* Number of channels per trunk. The */ + /* stack uses a static set of 32 */ + /* channels regardless if it is E1, T1 */ + /* or BRI that actually is used. */ + +#define Q931MAXCALLPERTRUNK (Q931MAXCHPERTRUNK * 2) + /* Number of max active CRV per trunk. */ + /* Q.931 can have more calls than there */ + /* are channels. */ + +/***************************************************************************** + + The following defines control the dialect switch tables and should only be + changed when a new dialect needs to be inserted into the stack. + + This stack uses an array of functions to know which function to call as + it receives a SETUP message etc. A new dialect can when schoose to use + the proc etc for standard Q.931 or insert a modified proc. + + This technique has also been used to distinguish between user and network + mode to make the code as easy to read and maintainable as possible. + + A message and IE index have been used to save space. These indexes allowes + the message or IE code to be used directly and will give back a new index + into the table. + +*****************************************************************************/ + +/* WARNING! Initialize Q931CreateDialectCB[] will NULL when increasing the */ +/* Q931MAXDLCT value to avoid Q931Initialize from crashing if one entry is */ +/* not used. */ +#define Q931MAXDLCT 2 /* Max dialects included in this */ + /* compile. User and Network count as */ + /* one dialect each. */ + + +#define Q931MAXMES 255 /* Number of messages */ + +#define Q931MAXIE 255 /* Number of IE */ + +#define Q931MAXSTATE 100 /* Size of state tables */ + +/***************************************************************************** + + Call States for ITU-T Q.931 TE (User Mode) + +*****************************************************************************/ + +#define Q931_U0 0 +#define Q931_U1 1 +#define Q931_U2 2 +#define Q931_U3 3 +#define Q931_U4 4 +#define Q931_U6 6 +#define Q931_U7 7 +#define Q931_U8 8 +#define Q931_U9 9 +#define Q931_U10 10 +#define Q931_U11 11 +#define Q931_U12 12 +#define Q931_U15 15 +#define Q931_U17 17 +#define Q931_U19 19 +#define Q931_U25 25 + +/***************************************************************************** + + Call States for ITU-T Q.931 NT (Network Mode) + +*****************************************************************************/ +#define Q931_N0 (0x0100 | 0) +#define Q931_N1 (0x0100 | 1) +#define Q931_N2 (0x0100 | 2) +#define Q931_N3 (0x0100 | 3) +#define Q931_N4 (0x0100 | 4) +#define Q931_N6 (0x0100 | 6) +#define Q931_N7 (0x0100 | 7) +#define Q931_N8 (0x0100 | 8) +#define Q931_N9 (0x0100 | 9) +#define Q931_N10 (0x0100 | 11) +#define Q931_N11 (0x0100 | 11) +#define Q931_N12 (0x0100 | 12) +#define Q931_N15 (0x0100 | 15) +#define Q931_N17 (0x0100 | 17) +#define Q931_N19 (0x0100 | 19) +#define Q931_N22 (0x0100 | 22) +#define Q931_N25 (0x0100 | 25) + +/***************************************************************************** + + Q.931 Message codes + +*****************************************************************************/ + +#define Q931mes_ALERTING 0x01 /* 0000 0001 */ +#define Q931mes_CALL_PROCEEDING 0x02 /* 0000 0010 */ +#define Q931mes_CONNECT 0x07 /* 0000 0111 */ +#define Q931mes_CONNECT_ACKNOWLEDGE 0x0f /* 0000 1111 */ +#define Q931mes_PROGRESS 0x03 /* 0000 0011 */ +#define Q931mes_SETUP 0x05 /* 0000 0101 */ +#define Q931mes_SETUP_ACKNOWLEDGE 0x0d /* 0000 1101 */ +#define Q931mes_RESUME 0x26 /* 0010 0110 */ +#define Q931mes_RESUME_ACKNOWLEDGE 0x2e /* 0010 1110 */ +#define Q931mes_RESUME_REJECT 0x22 /* 0010 0010 */ +#define Q931mes_SUSPEND 0x25 /* 0010 0101 */ +#define Q931mes_SUSPEND_ACKNOWLEDGE 0x2d /* 0010 1101 */ +#define Q931mes_SUSPEND_REJECT 0x21 /* 0010 0001 */ +#define Q931mes_USER_INFORMATION 0x20 /* 0010 0000 */ +#define Q931mes_DISCONNECT 0x45 /* 0100 0101 */ +#define Q931mes_RELEASE 0x4d /* 0100 1101 */ +#define Q931mes_RELEASE_COMPLETE 0x5a /* 0101 1010 */ +#define Q931mes_RESTART 0x46 /* 0100 0110 */ +#define Q931mes_RESTART_ACKNOWLEDGE 0x4e /* 0100 1110 */ +#define Q931mes_CONGESTION_CONTROL 0x79 /* 0111 1001 */ +#define Q931mes_INFORMATION 0x7a /* 0111 1011 */ +#define Q931mes_NOTIFY 0x6e /* 0110 1110 */ +#define Q931mes_STATUS 0x7d /* 0111 1101 */ +#define Q931mes_STATUS_ENQUIRY 0x75 /* 0111 0101 */ +#define Q931mes_SEGMENT 0x60 /* 0110 0000 */ + + +/* Single octet information elements */ +#define Q931ie_SHIFT 0x90 /* 1001 ---- */ +#define Q931ie_MORE_DATA 0xa0 /* 1010 ---- */ +#define Q931ie_SENDING_COMPLETE 0xa1 /* 1010 0000 */ +#define Q931ie_CONGESTION_LEVEL 0xb0 /* 1011 ---- */ +#define Q931ie_REPEAT_INDICATOR 0xd0 /* 1101 ---- */ + +/* Variable Length Information Elements */ +#define Q931ie_SEGMENTED_MESSAGE 0x00 /* 0000 0000 */ +#define Q931ie_BEARER_CAPABILITY 0x04 /* 0000 0100 */ +#define Q931ie_CAUSE 0x08 /* 0000 1000 */ +#define Q931ie_CALL_IDENTITY 0x10 /* 0001 0000 */ +#define Q931ie_CALL_STATE 0x14 /* 0001 0100 */ +#define Q931ie_CHANNEL_IDENTIFICATION 0x18 /* 0001 1000 */ +#define Q931ie_PROGRESS_INDICATOR 0x1e /* 0001 1110 */ +#define Q931ie_NETWORK_SPECIFIC_FACILITIES 0x20 /* 0010 0000 */ +#define Q931ie_NOTIFICATION_INDICATOR 0x27 /* 0010 0111 */ +#define Q931ie_DISPLAY 0x28 /* 0010 1000 */ +#define Q931ie_DATETIME 0x29 /* 0010 1001 */ +#define Q931ie_KEYPAD_FACILITY 0x2c /* 0010 1100 */ +#define Q931ie_SIGNAL 0x34 /* 0011 0100 */ +#define Q931ie_SWITCHOOK 0x36 /* 0011 0110 */ +#define Q931ie_FEATURE_ACTIVATION 0x38 /* 0011 1000 */ +#define Q931ie_FEATURE_INDICATION 0x39 /* 0011 1001 */ +#define Q931ie_INFORMATION_RATE 0x40 /* 0100 0000 */ +#define Q931ie_END_TO_END_TRANSIT_DELAY 0x42 /* 0100 0010 */ +#define Q931ie_TRANSIT_DELAY_SELECTION_AND_IND 0x43 /* 0100 0011 */ +#define Q931ie_PACKED_LAYER_BIMARY_PARAMETERS 0x44 /* 0100 0100 */ +#define Q931ie_PACKED_LAYER_WINDOW_SIZE 0x45 /* 0100 0101 */ +#define Q931ie_PACKED_SIZE 0x46 /* 0100 0110 */ +#define Q931ie_CALLING_PARTY_NUMBER 0x6c /* 0110 1100 */ +#define Q931ie_CALLING_PARTY_SUBADDRESS 0x6d /* 0110 1101 */ +#define Q931ie_CALLED_PARTY_NUMBER 0x70 /* 0111 0000 */ +#define Q931ie_CALLED_PARTY_SUBADDRESS 0x71 /* 0111 0001 */ +#define Q931ie_REDIRECTING_NUMBER 0x74 /* 0111 0100 */ +#define Q931ie_TRANSIT_NETWORK_SELECTION 0x78 /* 0111 1000 */ +#define Q931ie_RESTART_INDICATOR 0x79 /* 0111 1001 */ +#define Q931ie_LOW_LAYER_COMPATIBILITY 0x7c /* 0111 1100 */ +#define Q931ie_HIGH_LAYER_COMPATIBILITY 0x7d /* 0111 1101 */ +#define Q931ie_USER_USER 0x7e /* 0111 1110 */ +#define Q931ie_ESCAPE_FOR_EX 0x7f /* 0111 1111 */ + +/***************************************************************************** + + Global defines. + +*****************************************************************************/ + +typedef L3USHORT ie; /* Special data type to hold a dynamic */ + /* or optional information element as */ + /* part of a message struct. MSB = 1 */ + /* indicate that the ie is present, the */ + /* last 15 bits is an offset ( or the */ + /* value for single octet ) to the */ + /* struct holding the ie. Offset = 0 */ + /* is buf[1] etc. */ + /* ie == 0xffff indicate error */ + +/***************************************************************************** + + Struct: Q931ie_BearerCap + + Description: Bearer Capability Information Element. + +*****************************************************************************/ + +typedef struct +{ + L3UCHAR IEId; /* 00000100 for Bearer Capability */ + + L3UCHAR Size; /* Length of Information Element */ + + L3UCHAR CodStand; /* Coding Standard. */ + /* 00 - ITU-T */ + /* 01 - ISO/IEC */ + /* 10 - National standard */ + /* 11 - Network side spesific */ + + L3UCHAR ITC; /* Information Transfer Capability */ + /* 00000 - Speech */ + /* 01000 - Unrestricted digital info */ + /* 01001 - Restricted digital info */ + /* 10000 - 3.1 kHz audio */ + /* 10001 - Unrestricted with tones */ + /* 11000 - Video */ + + L3UCHAR TransMode; /* Transfer Mode. */ + /* 00 - Circuit mode */ + /* 10 - Packet mode */ + + L3UCHAR ITR; /* Information Transfer Rate. */ + /* 00000 - Packed mode */ + /* 10000 - 64 kbit/s */ + /* 10001 - 2 x 64 kbit/s */ + /* 10011 - 384 kbit/s */ + /* 10101 - 1536 kbit/s */ + /* 10111 - 1920 kbit/s */ + /* 11000 - Multirat (64 kbit/s base) */ + + L3UCHAR RateMul; /* Rate Multiplier */ + + L3UCHAR Layer1Ident; /* Layer 1 Ident. */ + + L3UCHAR UIL1Prot; /* User Information Layer 1 Protocol */ + /* 00001 : ITU-T V.110, I.460 and X.30 */ + /* 00010 : G.711 my-law */ + /* 00011 : G.711 A-law */ + /* 00100 : G.721 */ + /* 00101 : H.221 and H.242 */ + /* 00110 : H.223 and H.245 */ + /* 00111 : Non ITU-T Standard */ + /* 01000 : ITU-T V.120 */ + /* 01001 : ITU-T X.31 HDLC flag stuff. */ + + L3UCHAR SyncAsync; /* Sync/Async */ + /* 0 : Syncronous data */ + /* 1 : Asyncronous data */ + + L3UCHAR Negot; /* Negotiation */ + /* 0 : In-band negotiation not possib. */ + /* 1 : In-band negotiation possible */ + + L3UCHAR UserRate; /* User rate */ + /* 00000 : I.460, V.110, X,30 */ + /* 00001 : 0.6 kbit/s x.1 */ + /* 00010 : 1.2 kbit/s */ + /* 00011 : 2.4 kbit/s */ + /* 00100 : 3.6 kbit/s */ + /* 00101 : 4.8 kbit/s */ + /* 00110 : 7.2 kbit/s */ + /* 00111 : 8 kbit/s I.460 */ + /* 01000 : 9.6 kbit/s */ + /* 01001 : 14.4 kbit/s */ + /* 01010 : 16 kbit/s */ + /* 01011 : 19.2 kbit/s */ + /* 01100 : 32 kbit/s */ + /* 01101 : 38.4 kbit/s */ + /* 01110 : 48 kbit/s */ + /* 01111 : 56 kbit/s */ + /* 10000 : 57.6 kbit/s */ + /* 10010 : 28.8 kbit/s */ + /* 10100 : 24 kbit/s */ + /* 10101 : 0.1345 kbit/s */ + /* 10110 : 0.100 kbit/s */ + /* 10111 : 0.075/1.2 kbit/s */ + /* 11000 : 1.2/0.075/kbit/s */ + /* 11001 : 0.050 kbit/s */ + /* 11010 : 0.075 kbit/s */ + /* 11011 : 0.110 kbit/s */ + /* 11100 : 0.150 kbit/s */ + /* 11101 : 0.200 kbit/s */ + /* 11110 : 0.300 kbit/s */ + /* 11111 : 12 kbit/s */ + + L3UCHAR InterRate; /* Intermediate Rate */ + /* 00 : Not used */ + /* 01 : 8 kbit/s */ + /* 10 : 16 kbit/s */ + /* 11 : 32 kbit/s */ + + L3UCHAR NIConTx; /* Network Indepentend Clock on transmit*/ + /* 0 : Not required to send data clc */ + /* 1 : Send data w/NIC clc */ + + L3UCHAR NIConRx; /* NIC on Rx */ + /* 0 : Cannot accept indep. clc */ + /* 1 : data with indep. clc accepted */ + + L3UCHAR FlowCtlTx; /* Flow control on Tx */ + /* 0 : Send Flow ctrl not required */ + /* 1 : Send flow ctrl required */ + + L3UCHAR FlowCtlRx; /* Flow control on Rx */ + /* 0 : cannot use receive flow ctrl */ + /* 1 : Receive flow ctrl accepted */ + L3UCHAR HDR; /* HDR/No HDR */ + L3UCHAR MultiFrame; /* Multi frame support */ + /* 0 : multiframe not supported */ + /* 1 : multiframe supported */ + + L3UCHAR Mode; /* Mode of operation */ + /* 0 : bit transparent mode of operat. */ + /* 1 : protocol sesitive mode of op. */ + + L3UCHAR LLInegot; /* Logical link id negotiation (oct. 5b)*/ + /* 0 : default LLI=256 only */ + /* 1 : Full protocol negotiation */ + + L3UCHAR Assignor; /* Assignor/assignee */ + /* 0 : Default Asignee */ + /* 1 : Assignor only */ + + L3UCHAR InBandNeg; /* In-band/out-band negot. */ + /* 0 : negot done w/ USER INFO mes */ + /* 1 : negot done in-band w/link zero */ + + L3UCHAR NumStopBits; /* Number of stop bits */ + /* 00 : Not used */ + /* 01 : 1 bit */ + /* 10 : 1.5 bits */ + /* 11 : 2 bits */ + + L3UCHAR NumDataBits; /* Number of data bits. */ + /* 00 : not used */ + /* 01 : 5 bits */ + /* 10 : 7 bits */ + /* 11 : 8 bits */ + + L3UCHAR Parity; /* Parity Information */ + /* 000 : Odd */ + /* 010 : Even */ + /* 011 : None */ + /* 100 : Forced to 0 */ + /* 101 : Forced to 1 */ + + L3UCHAR DuplexMode; /* Mode duplex */ + /* 0 : Half duplex */ + /* 1 : Full duplex */ + + L3UCHAR ModemType; /* Modem type, see Q.931 p 64 */ + + L3UCHAR Layer2Ident; /* Layer 2 Ident */ + + L3UCHAR UIL2Prot; /* User Information Layer 2 Protocol */ + /* 00010 : Q.921/I.441 */ + /* 00110 : X.25 */ + /* 01100 : LAN logical link */ + + L3UCHAR Layer3Ident; /* Layer 3 ident. */ + + L3UCHAR UIL3Prot; /* User Information Layer 3 Protocol */ + /* 00010 : Q.931 */ + /* 00110 : X.25 */ + /* 01011 : ISO/IEC TR 9577 */ + + L3UCHAR AL3Info1; /* additional layer 3 info 1 */ + + L3UCHAR AL3Info2; /* additional layer 3 info 2 */ +}Q931ie_BearerCap; + +/***************************************************************************** + + Struct: Q931ie_CallID + + +*****************************************************************************/ + +typedef struct +{ + L3UCHAR IEId; /* 00010000 */ + L3UCHAR Size; /* Length of Information Element */ + L3UCHAR CallId[1]; /* Call identity */ +}Q931ie_CallID; + +/***************************************************************************** + + Struct: Q931ie_CallState + + +*****************************************************************************/ + +typedef struct +{ + L3UCHAR IEId; /* 00010100 */ + L3UCHAR Size; /* Length of Information Element */ + L3UCHAR CodStand; /* Coding Standard */ + L3UCHAR CallState; /* Call State Value */ +}Q931ie_CallState; + +/***************************************************************************** + + Struct: Q931ie_Cause + + Description: Cause IE as described in Q.850 + +*****************************************************************************/ +typedef struct +{ + L3UCHAR IEId; /* 00010100 */ + L3UCHAR Size; /* Length of Information Element */ + L3UCHAR CodStand; /* Coding Standard */ + L3UCHAR Location; /* Location */ + L3UCHAR Recom; /* Recommendation */ + L3UCHAR Value; /* Cause Value */ + L3UCHAR Diag[1]; /* Optional Diagnostics Field */ +}Q931ie_Cause; + +/***************************************************************************** + + Struct: Q931ie_CalledNum + +*****************************************************************************/ +typedef struct +{ + L3UCHAR IEId; /* 01110000 */ + L3UCHAR Size; /* Length of Information Element */ + L3UCHAR TypNum; /* Type of Number */ + L3UCHAR NumPlanID; /* Numbering plan identification */ + L3UCHAR Digit[1]; /* Digit (IA5) */ +}Q931ie_CalledNum; + +/***************************************************************************** + + Struct: Q931ie_CalledSub + + Description: Called party subaddress + +*****************************************************************************/ + +typedef struct +{ + L3UCHAR IEId; /* 01110001 */ + L3UCHAR Size; /* Length of Information Element */ + L3UCHAR TypNum; /* Type of subaddress */ + L3UCHAR OddEvenInd; /* Odd/Even indicator */ + L3UCHAR Digit[1]; /* digits */ +}Q931ie_CalledSub; + +/***************************************************************************** + + Struct: Q931ie_CallingNum + + Description: Calling party number + +*****************************************************************************/ + +typedef struct +{ + L3UCHAR IEId; /* 01101100 */ + L3UCHAR Size; /* Length of Information Element */ + L3UCHAR TypNum; /* Type of number */ + L3UCHAR NumPlanID; /* Numbering plan identification */ + L3UCHAR PresInd; /* Presentation indicator */ + L3UCHAR ScreenInd; /* Screening indicator */ + L3UCHAR Digit[1]; /* Number digits (IA5) */ +}Q931ie_CallingNum; + +/***************************************************************************** + + Struct: Q931ie_CallingSub + + Description: Calling party subaddress + +*****************************************************************************/ + +typedef struct +{ + L3UCHAR IEId; /* 01101101 */ + L3UCHAR Size; /* Length of Information Element */ + L3UCHAR TypNum; /* Type of subaddress */ + L3UCHAR OddEvenInd; /* Odd/Even indicator */ + L3UCHAR Digit[1]; /* digits */ +}Q931ie_CallingSub; + +/***************************************************************************** + + Struct: Q931ie_ChanID + + Description: Channel identification + + Channel Identificationis one of the IE elements that differ + between BRI and PRI. IntType = 1 = BRI and ChanSlot is used + for channel number, while InfoChanSel is used for BRI. + + ChanID is one of the most important IE as it is passed + either though SETUP or CALL PROCEEDING to select the channel + to be used. + +*****************************************************************************/ + +typedef struct +{ + L3UCHAR IEId; /* 00011000 */ + L3UCHAR Size; /* Length of Information Element */ + L3UCHAR IntIDPresent; /* Int. id. present */ + L3UCHAR IntType; /* Interface Type */ + /* 0 : Basic Interface (BRI) */ + /* 1 : Other interfaces, PRI etc. */ + + L3UCHAR PrefExcl; /* Pref./Excl. */ + /* 0 : Indicated channel is preffered */ + /* 1 : Exclusive, no other accepted */ + + L3UCHAR DChanInd; /* D-channel ind. */ + /* 0 : chan is NOT D chan. */ + /* 1 : chan is D chan */ + + L3UCHAR InfoChanSel; /* Info. channel selection */ + /* 00 : No channel */ + /* 01 : B1 channel */ + /* 10 : B2 channel */ + /* 11 : Any channel */ + + L3UCHAR InterfaceID; /* Interface identifier */ + + L3UCHAR CodStand; /* Code standard */ + /* 00 : ITU-T standardization coding */ + /* 01 : ISO/IEC Standard */ + /* 10 : National Standard */ + /* 11 : Standard def. by network. */ + + L3UCHAR NumMap; /* Number/Map */ + /* 0 : chan is in following octet */ + /* 1 : chan is indicated by slot map */ + + L3UCHAR ChanMapType; /* Channel type/Map element type */ + /* 0011 : B Channel units */ + /* 0110 : H0 channel units */ + /* 1000 : H11 channel units */ + /* 1001 : H12 channel units */ + + L3UCHAR ChanSlot; /* Channel number */ +}Q931ie_ChanID; + +/***************************************************************************** + + Struct: Q931ie_DateTime + + Description: Date/time + +*****************************************************************************/ + +typedef struct +{ + L3UCHAR IEId; /* 00101001 */ + L3UCHAR Size; /* Length of Information Element */ + L3UCHAR Year; /* Year */ + L3UCHAR Month; /* Month */ + L3UCHAR Day; /* Day */ + L3UCHAR Hour; /* Hour */ + L3UCHAR Minute; /* Minute */ + L3UCHAR Second; /* Second */ + L3UCHAR Format; /* Indicate presense of Hour, Min & sec */ + /* 0 : Only Date */ + /* 1 : Hour present */ + /* 2 : Hour and Minute present */ + /* 3 : Hour, Minute and Second present */ +}Q931ie_DateTime; + +/***************************************************************************** + + Struct: Q931ie_Display + + Description: Display + +*****************************************************************************/ + +typedef struct +{ + L3UCHAR IEId; /* 00101000 */ + L3UCHAR Size; /* Length of Information Element */ + L3UCHAR Display[1]; /* Display information (IA5) */ +}Q931ie_Display; + +/***************************************************************************** + + Struct: Q931ie_HLComp + + Description: High layer compatibility + +*****************************************************************************/ + +typedef struct +{ + L3UCHAR IEId; /* 01111101 */ + L3UCHAR Size; /* Length of Information Element */ + L3UCHAR CodStand; /* Coding standard */ + L3UCHAR Interpret; /* Interpretation */ + L3UCHAR PresMeth; /* Presentation methor of prot. profile */ + L3UCHAR HLCharID; /* High layer characteristics id. */ + L3UCHAR EHLCharID; /* Extended high layer character. id. */ + L3UCHAR EVideoTlfCharID; /* Ext. videotelephony char. id. */ +}Q931ie_HLComp; + +/***************************************************************************** + + Struct: Q931ie_KeypadFac + + Description: Keypad facility + +*****************************************************************************/ + +typedef struct +{ + L3UCHAR IEId; /* 00101100 */ + L3UCHAR Size; /* Length of Information Element */ + L3UCHAR KeypadFac[1]; /* dynamic buffer */ +}Q931ie_KeypadFac; + +/***************************************************************************** + + Struct: Q931ie_LLComp + + Description: Low layer compatibility + +*****************************************************************************/ + +typedef struct +{ + L3UCHAR IEId; /* 01111100 */ + L3UCHAR Size; /* Length of Information Element */ + L3UCHAR CodStand; /* Coding standard */ + /* 00 - ITU-T */ + /* 01 - ISO/IEC */ + /* 10 - National standard */ + /* 11 - Network side spesific */ + + L3UCHAR ITransCap; /* Information transfer capability */ + /* 00000 - Speech */ + /* 01000 - Unrestricted digital info */ + /* 01001 - Restricted digital info */ + /* 10000 - 3.1 kHz audio */ + /* 10001 - Unrestricted with tones */ + /* 11000 - Video */ + + L3UCHAR NegotInd; /* Negot indic. */ + /* 0 : Out-band neg. not possib. */ + /* 1 : Out-band neg. possible */ + + L3UCHAR TransMode; /* Transfer Mode */ + /* 00 : Circuit Mode */ + /* 10 : Packed Mode */ + + L3UCHAR InfoRate; /* Information transfer rate */ + /* 00000 - Packed mode */ + /* 10000 - 64 kbit/s */ + /* 10001 - 2 x 64 kbit/s */ + /* 10011 - 384 kbit/s */ + /* 10101 - 1536 kbit/s */ + /* 10111 - 1920 kbit/s */ + /* 11000 - Multirat (64 kbit/s base) */ + + L3UCHAR RateMul; /* Rate multiplier */ + L3UCHAR Layer1Ident; /* Layer 1 ident. */ + L3UCHAR UIL1Prot; /* User information layer 1 protocol */ + /* 00001 : ITU-T V.110, I.460 and X.30 */ + /* 00010 : G.711 my-law */ + /* 00011 : G.711 A-law */ + /* 00100 : G.721 */ + /* 00101 : H.221 and H.242 */ + /* 00110 : H.223 and H.245 */ + /* 00111 : Non ITU-T Standard */ + /* 01000 : ITU-T V.120 */ + /* 01001 : ITU-T X.31 HDLC flag stuff. */ + + L3UCHAR SyncAsync; /* Synch/asynch */ + /* 0 : Syncronous data */ + /* 1 : Asyncronous data */ + + L3UCHAR Negot; /* Negot */ + /* 0 : In-band negotiation not possib. */ + /* 1 : In-band negotiation possible */ + + L3UCHAR UserRate; /* User rate */ + /* 00000 : I.460, V.110, X,30 */ + /* 00001 : 0.6 kbit/s x.1 */ + /* 00010 : 1.2 kbit/s */ + /* 00011 : 2.4 kbit/s */ + /* 00100 : 3.6 kbit/s */ + /* 00101 : 4.8 kbit/s */ + /* 00110 : 7.2 kbit/s */ + /* 00111 : 8 kbit/s I.460 */ + /* 01000 : 9.6 kbit/s */ + /* 01001 : 14.4 kbit/s */ + /* 01010 : 16 kbit/s */ + /* 01011 : 19.2 kbit/s */ + /* 01100 : 32 kbit/s */ + /* 01101 : 38.4 kbit/s */ + /* 01110 : 48 kbit/s */ + /* 01111 : 56 kbit/s */ + /* 10000 : 57.6 kbit/s */ + /* 10010 : 28.8 kbit/s */ + /* 10100 : 24 kbit/s */ + /* 10101 : 0.1345 kbit/s */ + /* 10110 : 0.100 kbit/s */ + /* 10111 : 0.075/1.2 kbit/s */ + /* 11000 : 1.2/0.075/kbit/s */ + /* 11001 : 0.050 kbit/s */ + /* 11010 : 0.075 kbit/s */ + /* 11011 : 0.110 kbit/s */ + /* 11100 : 0.150 kbit/s */ + /* 11101 : 0.200 kbit/s */ + /* 11110 : 0.300 kbit/s */ + /* 11111 : 12 kbit/s */ + + L3UCHAR InterRate; /* Intermediate rate */ + /* 00 : Not used */ + /* 01 : 8 kbit/s */ + /* 10 : 16 kbit/s */ + /* 11 : 32 kbit/s */ + + L3UCHAR NIConTx; /* Network Indepentend Clock on transmit*/ + /* 0 : Not required to send data clc */ + /* 1 : Send data w/NIC clc */ + + L3UCHAR NIConRx; /* NIC on Rx */ + /* 0 : Cannot accept indep. clc */ + /* 1 : data with indep. clc accepted */ + + L3UCHAR FlowCtlTx; /* Flow control on Tx */ + /* 0 : Send Flow ctrl not required */ + /* 1 : Send flow ctrl required */ + + L3UCHAR FlowCtlRx; /* Flow control on Rx */ + /* 0 : cannot use receive flow ctrl */ + /* 1 : Receive flow ctrl accepted */ + L3UCHAR HDR; /* HDR/No HDR */ + L3UCHAR MultiFrame; /* Multi frame support */ + /* 0 : multiframe not supported */ + /* 1 : multiframe supported */ + + L3UCHAR ModeL1; /* Mode L1 */ + /* 0 : bit transparent mode of operat. */ + /* 1 : protocol sesitive mode of op. */ + + L3UCHAR NegotLLI; /* Negot. LLI */ + /* 0 : default LLI=256 only */ + /* 1 : Full protocol negotiation */ + + L3UCHAR Assignor; /* Assignor/Assignor ee */ + /* 0 : Default Asignee */ + /* 1 : Assignor only */ + + L3UCHAR InBandNeg; /* In-band negot. */ + /* 0 : negot done w/ USER INFO mes */ + /* 1 : negot done in-band w/link zero */ + + L3UCHAR NumStopBits; /* Number of stop bits */ + /* 00 : Not used */ + /* 01 : 1 bit */ + /* 10 : 1.5 bits */ + /* 11 : 2 bits */ + + L3UCHAR NumDataBits; /* Number of data bits. */ + /* 00 : not used */ + /* 01 : 5 bits */ + /* 10 : 7 bits */ + /* 11 : 8 bits */ + + L3UCHAR Parity; /* Parity Information */ + /* 000 : Odd */ + /* 010 : Even */ + /* 011 : None */ + /* 100 : Forced to 0 */ + /* 101 : Forced to 1 */ + + L3UCHAR DuplexMode; /* Mode duplex */ + /* 0 : Half duplex */ + /* 1 : Full duplex */ + + L3UCHAR ModemType; /* Modem type, see Q.931 p 89 */ + + L3UCHAR Layer2Ident; /* Layer 2 ident. */ + + L3UCHAR UIL2Prot; /* User information layer 2 protocol */ + /* 00001 : Basic mode ISO 1745 */ + /* 00010 : Q.921/I.441 */ + /* 00110 : X.25 single link */ + /* 00111 : X.25 multilink */ + /* 01000 : Extended LAPB T.71 */ + /* 01001 : HDLC ARM */ + /* 01010 : HDLC NRM */ + /* 01011 : HDLC ABM */ + /* 01100 : LAN logical link */ + /* 01101 : X.75 SLP */ + /* 01110 : Q.922 */ + /* 01111 : Q.922 core aspect */ + /* 10000 : User specified */ + /* 10001 : ISO/IEC 7776 DTE-DCE */ + + L3UCHAR ModeL2; /* Mode */ + /* 01 : Normal Mode of operation */ + /* 10 : Extended mode of operation */ + + L3UCHAR Q933use; /* Q.9333 use */ + + L3UCHAR UsrSpcL2Prot; /* User specified layer 2 protocol info */ + + L3UCHAR WindowSize; /* Window size (k) */ + + L3UCHAR Layer3Ident; /* Layer 3 ident */ + + L3UCHAR UIL3Prot; /* User Information Layer 3 protocol */ + /* 00010 : Q.931 */ + /* 00110 : X.25 */ + /* 00111 : 8208 */ + /* 01000 : X.233 ... */ + /* 01001 : 6473 */ + /* 01010 : T.70 */ + /* 01011 : ISO/IEC TR 9577 */ + /* 10000 : User specified */ + L3UCHAR OptL3Info; /* Optional Leyer 3 info */ + + L3UCHAR ModeL3; /* Mode of operation */ + /* 01 : Normal packed seq. numbering */ + /* 10 : Extended packed seq. numbering */ + + L3UCHAR DefPackSize; /* Default packet size */ + + L3UCHAR PackWinSize; /* Packet window size */ + + L3UCHAR AddL3Info; /* Additional Layer 3 protocol info */ +}Q931ie_LLComp; + +/***************************************************************************** + + Struct: Q931ie_NetFac; + + Description: Network-specific facilities + +*****************************************************************************/ + +typedef struct +{ + L3UCHAR IEId; /* 00100000 */ + L3UCHAR Size; /* Length of Information Element */ + L3UCHAR LenNetID; /* Length of network facilities id. */ + L3UCHAR TypeNetID; /* Type of network identification */ + L3UCHAR NetIDPlan; /* Network identification plan. */ + L3UCHAR NetFac; /* Network specific facility spec. */ + L3UCHAR NetID[1]; /* Network id. (IA5) */ +}Q931ie_NetFac; + +/***************************************************************************** + + Struct: Q931ie_NotifInd; + + Description: Notification Indicator + +*****************************************************************************/ + +typedef struct +{ + L3UCHAR IEId; /* 00100000 */ + L3UCHAR Size; /* Length of Information Element */ + L3UCHAR Notification; /* Notification descriptor */ +}Q931ie_NotifInd; + +/***************************************************************************** + + Struct: Q931ie_ProgInd + + Description: Progress indicator + +*****************************************************************************/ + +typedef struct +{ + L3UCHAR IEId; /* 00011110 */ + L3UCHAR Size; /* Length of Information Element */ + L3UCHAR CodStand; /* Coding standard */ + L3UCHAR Location; /* Location */ + L3UCHAR ProgDesc; /* Progress description */ +}Q931ie_ProgInd; + +/***************************************************************************** + + Struct; Q931ie_Segment + + Description: Segmented message + +*****************************************************************************/ + +typedef struct +{ + L3UCHAR IEId; /* 00000000 */ + L3UCHAR Size; /* Length of Information Element */ + L3UCHAR FSI; /* First segment indicator */ + L3UCHAR NumSegRem; /* Number of segments remaining */ + L3UCHAR SegType; /* Segment message type */ +}Q931ie_Segment; + +typedef struct +{ + L3UCHAR IEId; /* 00000000 */ + L3UCHAR Size; /* Length of Information Element */ +}Q931ie_SendComplete; + +/***************************************************************************** + + Struct: Q931ie_Signal + + Description: Signal + +*****************************************************************************/ + +typedef struct +{ + L3UCHAR IEId; /* 00000000 */ + L3UCHAR Size; /* Length of Information Element */ + L3UCHAR Signal; /* Signal value */ + /* 00000000 Dial tone on */ + /* 00000001 Ring back tone on */ + /* 00000010 Intercept tone on */ + /* 00000011 Network congestion on */ + /* 00000100 Busy tone on */ + /* 00000101 Confirm tone on */ + /* 00000110 Answer tone on */ + /* 00000111 Call waiting tone */ + /* 00001000 Off-hook warning tone */ + /* 00001001 Pre-emption tone on */ + /* 00111111 Tones off */ + /* 01000000 Alerting on - pattern 0 */ + /* 01000001 Alerting on - pattern 1 */ + /* 01000010 Alerting on - pattern 2 */ + /* 01000011 Alerting on - pattern 3 */ + /* 01000100 Alerting on - pattern 4 */ + /* 01000101 Alerting on - pattern 5 */ + /* 01000110 Alerting on - pattern 6 */ + /* 01000111 Alerting on - pattern 7 */ + /* 01001111 Alerting off */ +}Q931ie_Signal; + +/***************************************************************************** + + Struct: Q931ie_TransDelSelInd + + description: Transit delay selection and indication + +*****************************************************************************/ +#ifdef Q931_X25_SUPPORT +typedef struct +{ + L3UCHAR IEId; /* 00000000 */ + L3UCHAR Size; /* Length of Information Element */ + L3ULONG TxDSIValue; /* Trans. delay sel. & ind. value */ +}Q931ie_TransDelSelInd; +#endif + +/***************************************************************************** + + Struct: Q931ie_TransNetSel + + Description: Transit network selection + +*****************************************************************************/ + +typedef struct +{ + L3UCHAR IEId; /* 01111000 */ + L3UCHAR Size; /* Length of Information Element */ + L3UCHAR Type; /* Type of network identifier */ + L3UCHAR NetIDPlan; /* Network idetification plan */ + L3UCHAR NetID[1]; /* Network identification(IA5) */ +}Q931ie_TransNetSel; + +/***************************************************************************** + + Struct: Q931ie_UserUser + + Description: User-user + +*****************************************************************************/ + +typedef struct +{ + L3UCHAR IEId; /* 01111110 */ + L3UCHAR Size; /* Length of Information Element */ + L3UCHAR ProtDisc; /* Protocol discriminator */ + L3UCHAR User[1]; /* User information */ +}Q931ie_UserUser; + +/***************************************************************************** + + Struct: Q931ie_ClosedUserGrp + + Description: Closed user group + +*****************************************************************************/ +#ifdef Q931_X25_SUPPORT +typedef struct +{ + L3UCHAR IEId; /* 01000111 */ + L3UCHAR Size; /* Length of Information Element */ + L3UCHAR CUGInd; /* CUG indication */ + L3UCHAR CUG[1]; /* CUG index code (IA5) */ +}Q931ie_ClosedUserGrp; +#endif + +/***************************************************************************** + + Struct: Q931ie_CongLevel + + Description: Congestion Level + +*****************************************************************************/ +typedef struct +{ + L3UCHAR IEId; /* 01000111 */ + L3UCHAR Size; /* Length of Information Element */ + L3UCHAR CongLevel; /* Conguestion Level */ +}Q931ie_CongLevel; + +/***************************************************************************** + + Struct: Q931ie_EndEndTxDelay + + Description: End to end transit delay + +*****************************************************************************/ +#ifdef Q931_X25_SUPPORT +typedef struct +{ + L3UCHAR IEId; /* 01000010 */ + L3UCHAR Size; /* Length of Information Element */ + L3ULONG CumTxDelay; /* Cumulative transit delay value */ + L3ULONG ReqTxDelay; /* Requested end to end transit delay */ + L3ULONG MaxTxDelay; /* Maximum transit delay */ +}Q931ie_EndEndTxDelay; +#endif + +/***************************************************************************** + + Struct: Q931ie_InfoRate + + Description: Information Rate + +*****************************************************************************/ +#ifdef Q931_X25_SUPPORT +typedef struct +{ + L3UCHAR IEId; /* 01100000 */ + L3UCHAR Size; /* Length of Information Element */ + L3UCHAR InInfoRate; /* Incoming information rate */ + L3UCHAR OutInfoRate; /* Outgoing information rate */ + L3UCHAR MinInInfoRate; /* Minimum incoming information rate */ + L3UCHAR MinOutInfoRate; /* Minimum outgoing information rate */ +}Q931ie_InfoRate; +#endif + +/***************************************************************************** + + Struct: Q931ie_PackParam + + Description: Packed layer binary parameters + +*****************************************************************************/ +#ifdef Q931_X25_SUPPORT +typedef struct +{ + L3UCHAR IEId; /* 01000100 */ + L3UCHAR Size; /* Length of Information Element */ + L3UCHAR FastSel; /* Fast selected */ + L3UCHAR ExpData; /* Exp. data */ + L3UCHAR DelConf; /* Delivery conf */ + L3UCHAR Modulus; /* Modulus */ +}Q931ie_PackParam; +#endif + +/***************************************************************************** + + Struct: Q931ie_PackWinSize + + Description: Packed window size + +*****************************************************************************/ +#ifdef Q931_X25_SUPPORT +typedef struct +{ + L3UCHAR IEId; /* 01000101 */ + L3UCHAR Size; /* Length of Information Element */ + L3UCHAR ForwardValue; /* Forward value */ + L3UCHAR BackwardValue; /* Backward value */ +}Q931ie_PackWinSize; +#endif + +/***************************************************************************** + + Struct: Q931ie_PackSize + + Description: Packet size + +*****************************************************************************/ +#ifdef Q931_X25_SUPPORT +typedef struct +{ + L3UCHAR IEId; /* 01000110 */ + L3UCHAR Size; /* Length of Information Element */ + L3UCHAR ForwardValue; /* Forward value */ + L3UCHAR BackwardValue; /* Backward value */ +}Q931ie_PackSize; +#endif + +/***************************************************************************** + + Struct: Q931ie_RedirNum + + Description: Redirecting number + +*****************************************************************************/ +#ifdef Q931_X25_SUPPORT +typedef struct +{ + L3UCHAR IEId; /* 01110100 */ + L3UCHAR Size; /* Length of Information Element */ + L3UCHAR TypeNum; /* Type of number */ + L3UCHAR NumPlanID; /* Number plan identification */ + L3UCHAR PresInd; /* Presentation indicator */ + L3UCHAR ScreenInd; /* Screening indicator */ + L3UCHAR Reason; /* Reason for redirection */ + L3UCHAR Digit[1]; /* Number digits (IA5) */ +}Q931ie_RedirNum; +#endif + +typedef struct +{ + L3UCHAR IEId; /* 01110100 */ + L3UCHAR Size; /* Length of Information Element */ + L3UCHAR RepeatInd; /* 0010 Prioritized list for selecting */ + /* one possible. */ +}Q931ie_RepeatInd; + +typedef struct +{ + L3UCHAR IEId; /* 01110100 */ + L3UCHAR Size; /* Length of Information Element */ + L3UCHAR Class; /* Class */ + /* 000 Indicate channels */ + /* 110 Single interface */ + /* 111 All interfaces */ +}Q931ie_RestartInd; + +/***************************************************************************** + + Struct: Q931mes_Header + + Description: Used to read the header & message code. + +*****************************************************************************/ +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ +}Q931mes_Header; + +/***************************************************************************** + + Struct: Q931mes_Generic + + Description: Generic header containing all IE's. This is not used, but is + provided in case a proprietary variant needs it. + +*****************************************************************************/ +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + + ie Shift; + ie MoreData; + ie SendComplete; + ie CongestionLevel; + ie RepeatInd; + + ie Segment; /* Segmented message */ + ie BearerCap; /* Bearer Capability */ + ie Cause; /* Cause */ + ie CallID; /* Call Identity */ + ie ChanID; /* Channel Identification */ + ie ProgInd; /* Progress Indicator */ + ie NetFac; /* Network Spesific Facilities */ + ie NotifInd; /* Notification Indicator */ + ie Display; /* Display */ + ie DateTime; /* Date/Time */ + ie KeypadFac; /* Keypad Facility */ + ie Signal; /* Signal */ + ie InfoRate; /* Information rate */ + ie EndEndTxDelay; /* End to End Transmit Delay */ + ie TransDelSelInd; /* Transmit Delay Sel. and Ind. */ + ie PackParam; /* Packed Layer Binary parameters */ + ie PackWinSize; /* Packet Layer Window Size */ + ie PackSize; /* Packed Size */ + ie ClosedUserGrp; /* Closed User Group */ + ie RevChargeInd; /* Reverse Charging Indicator */ + ie CalledNum; /* Called Party Number */ + ie CalledSub; /* Called Party subaddress */ + ie CallingNum; /* Calling Party Number */ + ie CallingSub; /* Calling Party Subaddress */ + ie RedirNum; /* Redirection Number */ + ie TransNetSel; /* Transmit Network Selection */ + ie RestartInd; /* Restart Indicator */ + ie LLComp; /* Low Layer Compatibility */ + ie HLComp; /* High Layer Compatibility */ + ie UserUser; /* User-user */ + ie Escape; /* Escape for extension */ + L3UCHAR buf[1]; /* Buffer for IE's */ + +}Q931mes_Generic; + +/***************************************************************************** + + Struct: Q931mes_Alerting + + Description: This message is send by the called party to indicate that + the phone is ringing. + + The message consist of an header that MUST be identical with + Q931mes_Header, a fixed number of IE flags w/offset, and + a dynamic buffer storing normalized IE's. + +*****************************************************************************/ +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + ie BearerCap; /* Bearer Capability */ + ie ChanID; /* Channel Identification */ + ie ProgInd; /* Progress Indicator */ + ie Display; /* Display */ + ie Signal; /* Signal */ + ie HLComp; /* High Layer Compatibility */ + L3UCHAR buf[1]; /* Dynamic buffer */ +}Q931mes_Alerting; + +/***************************************************************************** + + Struct: Q931mes_CallProceeding + +*****************************************************************************/ + +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + ie BearerCap; /* Bearer Capability */ + ie ChanID; /* Channel Identification */ + ie ProgInd; /* Progress Indicator */ + ie Display; /* Display */ + ie HLComp; /* High Layer Compatibility */ + L3UCHAR buf[1]; /* Dynamic buffer */ +}Q931mes_CallProceeding; + +/***************************************************************************** + + Struct: Q931mes_Connect + +*****************************************************************************/ + +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + ie BearerCap; /* Bearer Capability */ + ie ChanID; /* Channel Identification */ + ie ProgInd; /* Progress Indicator */ + ie Display; /* Display */ + ie DateTime; /* Date/Time */ + ie Signal; /* Signal */ + ie LLComp; /* Low Layer Compatibility */ + ie HLComp; /* High layer Compatibility */ + L3UCHAR buf[1]; /* Dynamic buffer */ +}Q931mes_Connect; + +/***************************************************************************** + + Struct: Q931mes_ConnectAck + +*****************************************************************************/ + +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + ie Display; /* Display */ + ie Signal; /* Signal */ + L3UCHAR buf[1]; /* Dynamic buffer */ +}Q931mes_ConnectAck; + +/***************************************************************************** + + Struct: Q931mes_Disconnect + +*****************************************************************************/ + +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + ie Cause; /* Cause */ + ie ProgInd; /* Progress Indicator */ + ie Display; /* Display */ + ie Signal; /* Signal */ +#ifdef Q931_X25_SUPPORT + ie UserUser; /* User - user. Packed Mode. */ +#endif + L3UCHAR buf[1]; /* Dynamic buffer */ +}Q931mes_Disconnect; + +/***************************************************************************** + + Struct: Q931mes_Information + +*****************************************************************************/ + +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + ie SendComplete; /* Sending Complete */ + ie Display; /* Display */ + ie KeypadFac; /* Keypad facility */ + ie Signal; /* Signal */ + ie CalledNum; /* Called party number */ +#ifdef Q931_X25_SUPPORT + ie Cause; /* Cause (packed only) */ +#endif + L3UCHAR buf[1]; /* Dynamic buffer */ +}Q931mes_Information; + +/***************************************************************************** + + Struct: Q931mes_Notify + +*****************************************************************************/ + +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + ie BearerCap; /* Bearer Capability */ + ie NotifInd; /* Notification Indicator */ + ie Display; /* Display */ + L3UCHAR buf[1]; /* Dynamic buffer */ +}Q931mes_Notify; + +/***************************************************************************** + + Struct: Q931mes_Progress + +*****************************************************************************/ + +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + ie BearerCap; /* Bearer Capability */ + ie Cause; /* Cause */ + ie ProgInd; /* Progress Indicator */ + ie Display; /* Display */ + ie HLComp; /* High Layer Compatibility */ + L3UCHAR buf[1]; /* Dynamic buffer */ +}Q931mes_Progress; + +/***************************************************************************** + + Struct: Q931mes_Release + +*****************************************************************************/ + +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + ie Cause; /* Cause */ + ie Display; /* Display */ + ie Signal; /* Signal */ +#ifdef Q931_X25_SUPPORT + ie UserUser; /* User-User packed mode */ +#endif + L3UCHAR buf[1]; /* Dynamic buffer */ +}Q931mes_Release; + +/***************************************************************************** + + Struct: Q931mes_ReleaseComplete + +*****************************************************************************/ + +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + ie Cause; /* Cause */ + ie Display; /* Display */ + ie Signal; /* Signal */ +#ifdef Q931_X25_SUPPORT + ie UserUser; /* User-User packed mode */ +#endif + L3UCHAR buf[1]; /* Dynamic buffer */ +}Q931mes_ReleaseComplete; + +/***************************************************************************** + + Struct: Q931mes_Resume + +*****************************************************************************/ +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + ie CallID; /* Call Identity */ + L3UCHAR buf[1]; +}Q931mes_Resume; + +/***************************************************************************** + + Struct: Q931mes_ResumeAck + +*****************************************************************************/ + +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + ie ChanID; /* Channel ID */ + ie Display; /* Display */ + L3UCHAR buf[1]; /* Dynamic buffer */ +}Q931mes_ResumeAck; + +/***************************************************************************** + + Struct: Q931mes_ResumeReject + +*****************************************************************************/ + +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + ie Cause; /* Cause */ + ie Display; /* Display */ + L3UCHAR buf[1]; /* Dynamic buffer */ +}Q931mes_ResumeReject; + +/***************************************************************************** + + Struct: Q931mes_Segment + +*****************************************************************************/ + +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + L3UCHAR buf[1]; /* Dynamic buffer */ +}Q931mes_Segment; + +/***************************************************************************** + + Struct: Q931mes_Setup + +*****************************************************************************/ + +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + ie SendComplete; /* Sending Complete */ + ie RepeatInd; /* Repeat Indicator */ + ie BearerCap; /* Bearer Capability */ + ie ChanID; /* Channel ID */ + ie ProgInd; /* Progress Indicator */ + ie NetFac; /* Network-specific facilities */ + /* Note: Up to 4 NetFac's may be */ + /* included. */ + ie Display; /* Display */ + ie DateTime; /* Date/Time */ + ie KeypadFac; /* Keypad Facility */ + ie Signal; /* Signal */ + ie CallingNum; /* Calling party number */ + ie CallingSub; /* Calling party sub address */ + ie CalledNum; /* Called party number */ + ie CalledSub; /* Called party sub address */ + ie TransNetSel; /* Transit network selection */ + ie LLRepeatInd; /* Repeat Indicator 2 LLComp */ + ie LLComp; /* Low layer compatibility */ + ie HLComp; /* High layer compatibility */ + +#ifdef Q931_X25_SUPPORT + /* Packed mode additions */ + ie IndoRate; /* Information Rate */ + ie EndEndDelay; /* End-end transit delay */ + ie TransDelayInd; /* TRansit delay selection and ind. */ + ie PackParam; /* Packed layer binary parameters */ + ie PackWinSize; /* Packed layer window size */ + ie PackSize; /* Packet Size */ + ie ClosedUserGrp; /* Closed User Group */ + ie RevChargInd; /* Reverse charhing indicator */ + ie RedirNum; /* Redirection number */ + ie UserUser; /* User-user. */ +#endif + L3UCHAR buf[1]; /* Dynamic buffer */ +}Q931mes_Setup; + +/***************************************************************************** + + Struct: Q931mes_SetupAck + +*****************************************************************************/ + +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + ie ChanID; /* Channel ID */ + ie ProgInd; /* Progress Indicator */ + ie Display; /* Display */ + ie Signal; /* Signal */ + L3UCHAR buf[1]; /* Dynamic buffer */ +}Q931mes_SetupAck; + +/***************************************************************************** + + Struct: Q931mes_Status + +*****************************************************************************/ + +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + ie Cause; /* Cause */ + ie CallState; /* Call State */ + ie Display; /* Display */ + L3UCHAR buf[1]; /* Dynamic buffer */ +}Q931mes_Status; + +/***************************************************************************** + + Struct: Q931mes_StatusEnquire + +*****************************************************************************/ + +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + ie Display; /* Display */ + L3UCHAR buf[1]; /* Dynamic buffer */ +}Q931mes_StatusEnquiry; + +/***************************************************************************** + + Struct: Q931mes_Suspend + +*****************************************************************************/ + +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + ie CallID; /* Call Identity */ + L3UCHAR buf[1]; /* Dynamic buffer */ +}Q931mes_Suspend; + +/***************************************************************************** + + Struct: Q931mes_SuspendAck + +*****************************************************************************/ + +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + ie Display; /* Display */ + L3UCHAR buf[1]; /* Dynamic buffer */ +}Q931mes_SuspendAck; + +/***************************************************************************** + + Struct: Q931mes_SuspendReject + +*****************************************************************************/ + +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + ie Cause; /* Cause */ + ie Display; /* Display */ + L3UCHAR buf[1]; /* Dynamic buffer */ +}Q931mes_SuspendReject; + +/***************************************************************************** + + Struct: Q931mes_CongestionControl + +*****************************************************************************/ + +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + ie CongLevel; /* Congestion level */ + ie Cause; /* Cause */ + ie Display; /* Display */ + L3UCHAR buf[1]; /* Dynamic buffer */ +}Q931mes_CongestionControl; + +/***************************************************************************** + + Struct: Q931mes_UserInformation + +*****************************************************************************/ + +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + ie MoreData; /* More data */ + ie UserUser; /* User-user */ + L3UCHAR buf[1]; /* Dynamic buffer */ +}Q931mes_UserInformation; + +/***************************************************************************** + + Struct: Q931mes_Restart + +*****************************************************************************/ + +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + ie ChanID; /* Channel identification */ + ie Display; /* Display */ + ie RestartInd; /* Restart indicator */ + L3UCHAR buf[1]; /* Dynamic buffer */ +}Q931mes_Restart; + +/***************************************************************************** + + Struct: Q931mes_RestartAck + +*****************************************************************************/ + +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + ie ChanID; /* Channel identification */ + ie Display; /* Display */ + ie RestartWin; /* Restart Window */ + ie RestartInd; /* Restart Indicator */ + L3UCHAR buf[1]; /* Dynamic buffer */ +}Q931mes_RestartAck; + +/***************************************************************************** + + Struct: Q931_TrunkInfo + + Description: TrunkInfo is the struct entry used to store Q.931 related + information and state for E1/T1/J1 trunks and assosiated + channels in the system. + + The user should store this information outside this stack + and need to feed the interface functions with a pointer to + the trunk Info entry. + +*****************************************************************************/ + +typedef struct +{ + enum _NetUser /* Network/User Mode. */ + { + Q931_TE=0, /* 0 : User Mode */ + Q931_NT=1 /* 1 : Network Mode */ + }NetUser; + + L3UCHAR Dialect; /* Q.931 Based dielact index. */ + + enum _TrunkType /* Trunk Line Type. */ + { + Q931_TrType_E1=0, /* 0 : E1 Trunk */ + Q931_TrType_T1=1, /* 1 : T1 Trunk */ + Q931_TrType_J1=2, /* 2 : J1 Trunk */ + Q931_TrType_BRI=3 /* 3 : BRI Trunk */ + }TrunkType; + + L3UCHAR Enabled; /* Enabled/Disabled */ + /* 0 = Disabled */ + /* 1 = Enabled */ + + enum _TrState /* Trunk State */ + { + Q931_TrState_NoAlignment=0, /* Trunk not aligned */ + Q931_TrState_Aligning=1, /* Aligning in progress */ + Q931_TrState_Aligned=2, /* Trunk Aligned */ + }TrunkState; + + L3INT LastCRV; /* Last used crv for the trunk. */ + + L3UCHAR L3Buf[Q931L4BUF]; /* message buffer for messages to be */ + /* send from Q.931 L4. */ + + L3UCHAR L2Buf[Q931L2BUF]; /* buffer for messages send to L2. */ + + /* The auto flags below switch on/off automatic Ack messages. SETUP ACK */ + /* as an example can be send by the stack in response to SETUP to buy */ + /* time in processing on L4. Setting this to true will cause the stack */ + /* to automatically send this. */ + + L3BOOL autoSetupAck; /* Indicate if the stack should send */ + /* SETUP ACK or not. 0=No, 1 = Yes. */ + + L3BOOL autoConnectAck; /* Indicate if the stack should send */ + /* CONNECT ACT or not. 0=No, 1=Yes. */ + + L3BOOL autoRestartAck; /* Indicate if the stack should send */ + /* RESTART ACK or not. 0=No, 1=Yes. */ + + /* channel array holding info per channel. Usually defined to 32 */ + /* channels to fit an E1 since T1/J1 and BRI will fit inside a E1. */ + struct _charray + { + enum _ChanType{ + Q931_ChType_NotUsed=0, /* Unused Channel */ + Q931_ChType_B=1, /* B Channel (Voice) */ + Q931_ChType_D=2, /* D Channel (Signalling) */ + Q931_ChType_Sync=3 /* Sync Channel */ + }ChanType; + + L3UCHAR Available; /* Channel Available Flag */ + /* 0 : Avaiabled */ + /* 1 : Used */ + + L3INT CRV; /* Associated CRV */ + + }ch[Q931MAXCHPERTRUNK]; + + /* Active Call information indentified by CRV. See Q931AllocateCRV for */ + /* initialization of call table. */ + struct _ccarray + { + L3UCHAR InUse; /* Indicate if entry is in use. */ + /* 0 = Not in Use */ + /* 1 = Active Call. */ + + L3UCHAR BChan; /* Associated B Channel. */ + /* 0 - 31 valid B chan */ + /* 255 = Not allocated */ + + L3INT CRV; /* Associated CRV. */ + + L3UINT State; /* Call State. */ + /* 0 is Idle, but other values are */ + /* defined per dialect. */ + /* Default usage is 1-99 for TE and */ + /* 101 - 199 for NT. */ + + L3ULONG Timer; /* Timer in ms. The TimeTick will check */ + /* if this has exceeded the timeout, and*/ + /* if so call the timers timeout proc. */ + + L3USHORT TimerID; /* Timer Identification/State */ + /* actual values defined by dialect */ + /* 0 : No timer running */ + /* ITU-T Q.931:301 - 322 Timer running */ + + }call[Q931MAXCALLPERTRUNK]; + +}Q931_TrunkInfo; + +/***************************************************************************** + + Struct: Q931State + + Description: Define a Q931 State, legal events and next state for each + event. Used to simplify the state engine logic. Each state + engine define it's own state table and the logic only need + to call a helper function to check if the message is legal + at this stage. + +*****************************************************************************/ +typedef struct +{ + L3INT State; + L3INT Message; + L3UCHAR Direction; +}Q931State; + +/***************************************************************************** + + Proc table external references. + + The proc tables are defined in Q931.c and initialized in Q931Initialize. + +*****************************************************************************/ +extern L3INT (*Q931Proc [Q931MAXDLCT][Q931MAXMES]) (Q931_TrunkInfo *pTrunk, L3UCHAR *,L3INT); + +extern L3INT (*Q931Umes [Q931MAXDLCT][Q931MAXMES]) (Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT Size); +extern L3INT (*Q931Pmes [Q931MAXDLCT][Q931MAXMES]) (Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); + +extern L3INT (*Q931Uie [Q931MAXDLCT][Q931MAXIE] ) (Q931_TrunkInfo *pTrunk,ie *pIE,L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff); +extern L3INT (*Q931Pie [Q931MAXDLCT][Q931MAXIE] ) (Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet); + +/***************************************************************************** + + Macro: GetIETotoSize + + Syntax: L3INT GetIETotSize(InfoElem ie); + + Description: Compute the total size in bytes of an info element including + size of 'header'. + +*****************************************************************************/ +#define Q931GetIETotSize(ie) (((ie.InfoID & 0x80) !=0) ? 1:ie.LenIE)+2) + +/***************************************************************************** + + Macro: IsIEPresent + + Syntax: BOOL IsIEPresent(ie InfoElement); + + Description: Return TRUE if the Information Element is included. + +*****************************************************************************/ +#define Q931IsIEPresent(x) ((x & 0x8000) != 0) + +/***************************************************************************** + + Macro: GetIEOffset and GetIEValue + + Syntax: L3INT GetIEOffset(ie InfoElement) + L3INT GetIEValue(ie InfoElement) + + Description: Returns the offset (or the value )to the Information Element. + + Note: GetIEValue assumes that the 15 lsb bit is the value of a + single octet information element. This macro can not be used + on a variable information element. + +*****************************************************************************/ +#define Q931GetIEOffset(x) (x & 0x7fff) +#define Q931GetIEValue(x) (x & 0x7fff) + +/***************************************************************************** + + Macro: Q931GetIEPtr + + Syntax: void * Q931GetIEPtr(ie InfoElement, L3UCHAR * Buf); + + Description: Compute a Ptr to the information element. + +*****************************************************************************/ +#define Q931GetIEPtr(ie,buf) (&buf[Q931GetIEOffset(ie)]) + +/***************************************************************************** + + Macro: SetIE + + Syntax: void SetIE(ie InfoElement, L3INT Offset); + + Description: Set an information element. + +*****************************************************************************/ +#define Q931SetIE(x,o) {x = (ie)(o) | 0x8000;} + +/***************************************************************************** + + Macro: IsQ931Ext + + Syntax BOOL IsQ931Ext(L3UCHAR c) + + Description: Return true Check if the msb (bit 8) is 0. This indicate + that the octet is extended. + +*****************************************************************************/ +#define IsQ931Ext(x) ((x&0x80)==0) + +/***************************************************************************** + + Macro: ieGetOctet + + Syntax: unsigned L3UCHAR ieGetOctet(L3INT e) + + Description: Macro to fetch one byte from an integer. Mostly used to + avoid warnings. + +*****************************************************************************/ +#define ieGetOctet(x) ((L3UCHAR)(x)) + +/***************************************************************************** + + Macro: NoWarning + + Syntax: void NoWarning(x) + + Description: Macro to suppress unreferenced formal parameter warnings + + Used during creation of the stack since the stack is + developed for Warning Level 4 and this creates a lot of + warning for the initial empty functions. + +*****************************************************************************/ +#define NoWarning(x) (x=x) + +/***************************************************************************** + + External references. See Q931.c for details. + +*****************************************************************************/ + +extern Q931_TrunkInfo Q931Trunk[Q931MAXTRUNKS]; + +#include "Q932.h" + +/***************************************************************************** + + Q.931 Information Element Pack/Unpack functions. Implemented in Q931ie.c + +*****************************************************************************/ + +L3INT Q931Pie_BearerCap(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet); +L3INT Q931Pie_ChanID(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet); +L3INT Q931Pie_ProgInd(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet); +L3INT Q931Pie_Display(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet); +L3INT Q931Pie_Signal(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet); +L3INT Q931Pie_HLComp(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet); +L3INT Q931Pie_Segment(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet); +L3INT Q931Pie_DateTime(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet); +L3INT Q931Pie_Cause(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet); +L3INT Q931Pie_SendComplete(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet); +L3INT Q931Pie_KeypadFac(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet); +L3INT Q931Pie_NotifInd(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet); +L3INT Q931Pie_CallID(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet); +L3INT Q931Pie_RepeatInd(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet); +L3INT Q931Pie_NetFac(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet); +L3INT Q931Pie_CallingNum(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet); +L3INT Q931Pie_CallingSub(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet); +L3INT Q931Pie_CalledNum(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet); +L3INT Q931Pie_CalledSub(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet); +L3INT Q931Pie_CalledNum(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet); +L3INT Q931Pie_TransNetSel(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet); +L3INT Q931Pie_LLComp(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet); +L3INT Q931Pie_CallState(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet); +L3INT Q931Pie_RestartInd(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet); +L3INT Q931Pie_UserUser(Q931_TrunkInfo *pTrunk,L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet); + +L3INT Q931Uie_BearerCap(Q931_TrunkInfo *pTrunk,ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff); +L3USHORT Q931Uie_CRV(Q931_TrunkInfo *pTrunk,L3UCHAR * IBuf, L3UCHAR *OBuf, L3INT *IOff, L3INT *OOff); +L3INT Q931Uie_ChanID(Q931_TrunkInfo *pTrunk,ie *pIE, L3UCHAR * IBuf, L3UCHAR *OBuf, L3INT *IOff, L3INT *OOff); +L3INT Q931Uie_ProgInd(Q931_TrunkInfo *pTrunk,ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff); +L3INT Q931Uie_Display(Q931_TrunkInfo *pTrunk,ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff); +L3INT Q931Uie_Signal(Q931_TrunkInfo *pTrunk,ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff); +L3INT Q931Uie_HLComp(Q931_TrunkInfo *pTrunk,ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff); +L3INT Q931Uie_Segment(Q931_TrunkInfo *pTrunk,ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff); +L3INT Q931Uie_DateTime(Q931_TrunkInfo *pTrunk,ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff); +L3INT Q931Uie_Cause(Q931_TrunkInfo *pTrunk,ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff); +L3INT Q931Uie_SendComplete(Q931_TrunkInfo *pTrunk,ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff); +L3INT Q931Uie_KeypadFac(Q931_TrunkInfo *pTrunk,ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff); +L3INT Q931Uie_NotifInd(Q931_TrunkInfo *pTrunk,ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff); +L3INT Q931Uie_CallID(Q931_TrunkInfo *pTrunk,ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff); +L3INT Q931Uie_RepeatInd(Q931_TrunkInfo *pTrunk,ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff); +L3INT Q931Uie_NetFac(Q931_TrunkInfo *pTrunk,ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff); +L3INT Q931Uie_CallingNum(Q931_TrunkInfo *pTrunk,ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff); +L3INT Q931Uie_CallingSub(Q931_TrunkInfo *pTrunk,ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff); +L3INT Q931Uie_CalledNum(Q931_TrunkInfo *pTrunk,ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff); +L3INT Q931Uie_CalledSub(Q931_TrunkInfo *pTrunk,ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff); +L3INT Q931Uie_TransNetSel(Q931_TrunkInfo *pTrunk,ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff); +L3INT Q931Uie_LLComp(Q931_TrunkInfo *pTrunk,ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff); +L3INT Q931Uie_CallState(Q931_TrunkInfo *pTrunk,ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff); +L3INT Q931Uie_RestartInd(Q931_TrunkInfo *pTrunk,ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff); +L3INT Q931Uie_UserUser(Q931_TrunkInfo *pTrunk,ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff); + +/***************************************************************************** + + Q.931 Message Pack/Unpack functions. Implemented in Q931mes.c + +*****************************************************************************/ +L3INT Q931Pmes_Alerting(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q931Pmes_CallProceeding(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q931Pmes_Connect(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q931Pmes_ConnectAck(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q931Pmes_Progress(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q931Pmes_Setup(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q931Pmes_SetupAck(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q931Pmes_Resume(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q931Pmes_ResumeAck(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q931Pmes_ResumeReject(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q931Pmes_Suspend(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q931Pmes_SuspendAck(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q931Pmes_SuspendReject(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q931Pmes_UserInformation(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q931Pmes_Disconnect(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q931Pmes_Release(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q931Pmes_ReleaseComplete(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q931Pmes_Restart(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q931Pmes_RestartAck(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q931Pmes_CongestionControl(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q931Pmes_Information(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q931Pmes_Notify(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q931Pmes_Segment(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q931Pmes_Status(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q931Pmes_StatusEnquiry(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); + +L3INT Q931Umes_Alerting(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); +L3INT Q931Umes_CallProceeding(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); +L3INT Q931Umes_Connect(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); +L3INT Q931Umes_ConnectAck(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); +L3INT Q931Umes_Progress(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); +L3INT Q931Umes_Setup(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); +L3INT Q931Umes_SetupAck(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); +L3INT Q931Umes_Resume(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); +L3INT Q931Umes_ResumeAck(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); +L3INT Q931Umes_ResumeReject(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); +L3INT Q931Umes_Suspend(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); +L3INT Q931Umes_SuspendAck(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); +L3INT Q931Umes_SuspendReject(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); +L3INT Q931Umes_UserInformation(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); +L3INT Q931Umes_Disconnect(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); +L3INT Q931Umes_Release(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); +L3INT Q931Umes_ReleaseComplete(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); +L3INT Q931Umes_Restart(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); +L3INT Q931Umes_RestartAck(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); +L3INT Q931Umes_CongestionControl(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); +L3INT Q931Umes_Information(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); +L3INT Q931Umes_Notify(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); +L3INT Q931Umes_Segment(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); +L3INT Q931Umes_Status(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); +L3INT Q931Umes_StatusEnquiry(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); + +/***************************************************************************** + + Q.931 Process Function Prototyping. Implemented in Q931StateTE.c + +*****************************************************************************/ +L3INT Q931ProcAlertingTE(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcCallProceedingTE(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcConnectTE(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcConnectAckTE(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcProgressTE(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcSetupTE(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcSetupAckTE(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcResumeTE(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcResumeAckTE(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcResumeRejectTE(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcSuspendTE(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcSuspendAckTE(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcSuspendRejectTE(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcUserInformationTE(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcDisconnectTE(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcReleaseTE(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcReleaseCompleteTE(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcRestartTE(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcRestartAckTE(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcCongestionControlTE(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcInformationTE(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcNotifyTE(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcStatusTE(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcStatusEnquiryTE(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcSegmentTE(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); + +L3INT Q931ProcAlertingNT(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcCallProceedingNT(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcConnectNT(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcConnectAckNT(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcProgressNT(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcSetupNT(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcSetupAckNT(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcResumeNT(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcResumeAckNT(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcResumeRejectNT(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcSuspendNT(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcSuspendAckNT(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcSuspendRejectNT(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcUserInformationNT(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcDisconnectNT(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcReleaseNT(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcReleaseCompleteNT(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcRestartNT(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcRestartAckNT(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcCongestionControlNT(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcInformationNT(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcNotifyNT(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcStatusNT(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcStatusEnquiryNT(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcSegmentNT(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); + +L3INT Q931ProcUnknownMessage(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); +L3INT Q931ProcUnexpectedMessage(Q931_TrunkInfo *pTrunk,L3UCHAR * b, L3INT iFrom); + +/***************************************************************************** + + Interface Function Prototypes. Implemented in Q931.c + +*****************************************************************************/ +void Q931TimeTick(L3ULONG ms); +L3INT Q931Rx23(Q931_TrunkInfo *pTrunk, L3UCHAR * Mes, L3INT Size); +L3INT Q931Tx32(Q931_TrunkInfo *pTrunk, L3UCHAR * Mes, L3INT Size); +L3INT Q931Rx43(Q931_TrunkInfo *pTrunk, L3UCHAR * Mes, L3INT Size); +L3INT Q931Tx34(Q931_TrunkInfo *pTrunk, L3UCHAR * Mes, L3INT Size); +void Q931SetError(Q931_TrunkInfo *pTrunk,L3INT ErrID, L3INT ErrPar1, L3INT ErrPar2); +void Q931SetTx34CB(L3INT (*Q931Tx34Par)(Q931_TrunkInfo *pTrunk,L3UCHAR * Mes, L3INT Size)); +void Q931SetTx32CB(L3INT (*Q931Tx32Par)(Q931_TrunkInfo *pTrunk,L3UCHAR * Mes, L3INT Size)); +void Q931SetErrorCB(L3INT (*Q931ErrorPar)(Q931_TrunkInfo *pTrunk,L3INT,L3INT,L3INT)); +void Q931CreateTE(L3UCHAR i); +void Q931CreateNT(L3UCHAR i); +void Q931SetMesCreateCB(L3INT (*callback)()); +void Q931SetDialectCreateCB(L3INT (*callback)(L3INT)); +void Q931SetHeaderSpace(L3INT space); +void Q931SetMesProc(L3UCHAR mes, L3UCHAR dialect, + L3INT (*Q931ProcFunc)(Q931_TrunkInfo *pTrunk, L3UCHAR * b, L3INT iFrom), + L3INT (*Q931UmesFunc)(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT IOff, L3INT Size), + L3INT (*Q931PmesFunc)(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize)); + +void Q931SetIEProc(L3UCHAR iec, L3UCHAR dialect, + L3INT (*Q931PieProc)(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet), + L3INT (*Q931UieProc)(Q931_TrunkInfo *pTrunk, ie *pIE, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)); + +void Q931Initialize(); +void Q931AddDialect(L3UCHAR iDialect, void (*Q931CreateDialectCB)(L3UCHAR iDialect)); +L3INT Q931InitMesSetup(Q931mes_Setup *p); + +L3INT Q931CreateCRV(Q931_TrunkInfo *pTrunk, L3INT * callIndex); +L3INT Q931AllocateCRV(Q931_TrunkInfo *pTrunk, L3INT iCRV, L3INT * callIndex); +L3INT Q931FindCRV(Q931_TrunkInfo *pTrunk, L3INT crv, L3INT *callindex); +L3INT Q931GetCallState(Q931_TrunkInfo *pTrunk, L3INT iCRV); +L3INT Q931StartTimer(Q931_TrunkInfo *pTrunk, L3INT callIndex, L3INT iTimer); +L3INT Q931StopTimer(Q931_TrunkInfo *pTrunk, L3INT callindex, L3INT iTimer); +L3INT Q931SetState(Q931_TrunkInfo *pTrunk, L3INT callIndex, L3INT iState); +L3ULONG Q931GetTime(); +void Q931AddStateEntry(L3UCHAR iD, L3INT iState, L3INT iMes, L3UCHAR cDir); +L3BOOL Q931IsEventLegal(L3UCHAR iD, L3INT iState, L3INT iMes, L3UCHAR cDir); + +/***************************************************************************** + + Q.931 Low Level API Function Prototyping. Implemented in Q931API.c + +*****************************************************************************/ +ie Q931AppendIE(L3UCHAR *pm, L3UCHAR *pi); +L3INT Q931GetUniqueCRV(Q931_TrunkInfo *pTrunk); + +L3INT Q931InitIEBearerCap(Q931ie_BearerCap *p); +L3INT Q931InitIEChanID(Q931ie_ChanID *p); +L3INT Q931InitIEProgInd(Q931ie_ProgInd *p); +L3INT Q931InitIENetFac(Q931ie_NetFac * pIE); +L3INT Q931InitIEDisplay(Q931ie_Display * pIE); +L3INT Q931InitIEDateTime(Q931ie_DateTime * pIE); +L3INT Q931InitIEKeypadFac(Q931ie_KeypadFac * pIE); +L3INT Q931InitIESignal(Q931ie_Signal * pIE); +L3INT Q931InitIECallingNum(Q931ie_CallingNum * pIE); +L3INT Q931InitIECallingSub(Q931ie_CallingSub * pIE); +L3INT Q931InitIECalledNum(Q931ie_CalledNum * pIE); +L3INT Q931InitIECalledSub(Q931ie_CalledSub * pIE); +L3INT Q931InitIETransNetSel(Q931ie_TransNetSel * pIE); +L3INT Q931InitIELLComp(Q931ie_LLComp * pIE); +L3INT Q931InitIEHLComp(Q931ie_HLComp * pIE); + +L3INT Q931Disconnect(Q931_TrunkInfo *pTrunk, L3INT iTo, L3INT iCRV, L3INT iCause); +L3INT Q931ReleaseComplete(Q931_TrunkInfo *pTrunk, L3INT iTo); + +#endif /* _Q931_NL */ diff --git a/libs/openzap/src/isdn/include/Q932.h b/libs/openzap/src/isdn/include/Q932.h new file mode 100644 index 0000000000..fa17e38ae7 --- /dev/null +++ b/libs/openzap/src/isdn/include/Q932.h @@ -0,0 +1,191 @@ +/***************************************************************************** + + FileName: Q932.h + + Contents: Header w/structs for Q932 Suplementary Services. + + NB: Do NOT include this header directly, include Q931.h + + License/Copyright: + + Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. + email:janvb@caselaboratories.com + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the Case Labs, Ltd nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*****************************************************************************/ + +/***************************************************************************** + Q.932 Additional Message codes +*****************************************************************************/ + +#define Q932mes_HOLD 0x24 /* 0010 0100 */ +#define Q932mes_HOLD_ACKNOWLEDGE 0x28 /* 0010 1000 */ +#define Q932mes_HOLD_REJECT 0x30 /* 0011 0000 */ +#define Q932mes_RETRIEVE 0x31 /* 0011 0001 */ +#define Q932mes_RETRIEVE_ACKNOWLEDGE 0x33 /* 0011 0011 */ +#define Q932mes_RETRIEVE_REJECT 0x37 /* 0011 0111 */ +#define Q932mes_FACILITY 0x62 /* 0110 0010 */ +#define Q932mes_REGISTER 0x64 /* 0110 0100 */ + +/***************************************************************************** + Q.932 Additional EI Codes +*****************************************************************************/ +#define Q932ie_FACILITY 0x1c /* 0001 1100 */ + +/***************************************************************************** + Struct: Q932ie_Facility +*****************************************************************************/ +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + L3UCHAR buf[1]; /* Dynamic buffer */ +}Q932mes_Facility; + +/***************************************************************************** + Struct: Q932ie_Hold +*****************************************************************************/ +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + L3UCHAR buf[1]; /* Dynamic buffer */ +}Q932mes_Hold; + +/***************************************************************************** + Struct: Q932ie_HoldAck +*****************************************************************************/ +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + L3UCHAR buf[1]; /* Dynamic buffer */ +}Q932mes_HoldAck; + +/***************************************************************************** + Struct: Q932ie_HoldReject +*****************************************************************************/ +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + L3UCHAR buf[1]; /* Dynamic buffer */ +}Q932mes_HoldReject; + +/***************************************************************************** + Struct: Q932ie_Register +*****************************************************************************/ +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + L3UCHAR buf[1]; /* Dynamic buffer */ +}Q932mes_Register; + +/***************************************************************************** + Struct: Q932ie_Retrieve +*****************************************************************************/ +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + L3UCHAR buf[1]; /* Dynamic buffer */ +}Q932mes_Retrieve; + +/***************************************************************************** + Struct: Q932ie_RetrieveAck +*****************************************************************************/ +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + L3UCHAR buf[1]; /* Dynamic buffer */ +}Q932mes_RetrieveAck; + +/***************************************************************************** + Struct: Q932ie_RetrieveReject +*****************************************************************************/ +typedef struct +{ + L3UINT Size; /* Size of message in bytes */ + L3UCHAR ProtDisc; /* Protocol Discriminator */ + L3UCHAR MesType; /* Message type */ + L3USHORT CRV; /* Call reference value */ + L3UCHAR buf[1]; /* Dynamic buffer */ +}Q932mes_RetrieveReject; + +/***************************************************************************** + Function Prototypes. +*****************************************************************************/ +L3INT Q932ProcFacilityTE(Q931_TrunkInfo *pTrunk, L3UCHAR * b, L3INT iFrom); +L3INT Q932ProcHoldTE(Q931_TrunkInfo *pTrunk, L3UCHAR * b, L3INT iFrom); +L3INT Q932ProcHoldAckTE(Q931_TrunkInfo *pTrunk, L3UCHAR * b, L3INT iFrom); +L3INT Q932ProcHoldRejectTE(Q931_TrunkInfo *pTrunk, L3UCHAR * b, L3INT iFrom); +L3INT Q932ProcRegisterTE(Q931_TrunkInfo *pTrunk, L3UCHAR * b, L3INT iFrom); +L3INT Q932ProcRetrieveTE(Q931_TrunkInfo *pTrunk, L3UCHAR * b, L3INT iFrom); +L3INT Q932ProcRetrieveAckTE(Q931_TrunkInfo *pTrunk, L3UCHAR * b, L3INT iFrom); +L3INT Q932ProcRetrieveRejectTE(Q931_TrunkInfo *pTrunk, L3UCHAR * b, L3INT iFrom); + +L3INT Q932ProcFacilityNT(Q931_TrunkInfo *pTrunk, L3UCHAR * b, L3INT iFrom); +L3INT Q932ProcHoldNT(Q931_TrunkInfo *pTrunk, L3UCHAR * b, L3INT iFrom); +L3INT Q932ProcHoldAckNT(Q931_TrunkInfo *pTrunk, L3UCHAR * b, L3INT iFrom); +L3INT Q932ProcHoldRejectNT(Q931_TrunkInfo *pTrunk, L3UCHAR * b, L3INT iFrom); +L3INT Q932ProcRegisterNT(Q931_TrunkInfo *pTrunk, L3UCHAR * b, L3INT iFrom); +L3INT Q932ProcRetrieveNT(Q931_TrunkInfo *pTrunk, L3UCHAR * b, L3INT iFrom); +L3INT Q932ProcRetrieveAckNT(Q931_TrunkInfo *pTrunk, L3UCHAR * b, L3INT iFrom); +L3INT Q932ProcRetrieveRejectNT(Q931_TrunkInfo *pTrunk, L3UCHAR * b, L3INT iFrom); + +L3INT Q932Pmes_Facility(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q932Pmes_Hold(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q932Pmes_HoldAck(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q932Pmes_HoldReject(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q932Pmes_Register(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q932Pmes_Retrieve(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q932Pmes_RetrieveAck(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); +L3INT Q932Pmes_RetrieveReject(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize); + +L3INT Q932Umes_Facility(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); +L3INT Q932Umes_Hold(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); +L3INT Q932Umes_HoldAck(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); +L3INT Q932Umes_HoldReject(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); +L3INT Q932Umes_Register(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); +L3INT Q932Umes_Retrieve(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); +L3INT Q932Umes_RetrieveAck(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); +L3INT Q932Umes_RetrieveReject(Q931_TrunkInfo *pTrunk, L3UCHAR *IBuf, L3UCHAR * OBuf, L3INT I, L3INT O); diff --git a/libs/openzap/src/isdn/include/mfifo.h b/libs/openzap/src/isdn/include/mfifo.h new file mode 100644 index 0000000000..21a053173e --- /dev/null +++ b/libs/openzap/src/isdn/include/mfifo.h @@ -0,0 +1,83 @@ +/***************************************************************************** + + Filename: mfifo.h + + Contents: header for MFIFO + + License/Copyright: + + Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. + email:janvb@caselaboratories.com + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the Case Labs, Ltd nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*****************************************************************************/ +#ifndef _MFIFO +#define _MFIFO + +/***************************************************************************** + + Struct: MINDEX + + Description: Message Index used to index a dynamic size Message FIFO. + +*****************************************************************************/ +typedef struct _mindex +{ + int offset; /* offset to message in buf */ + int size; /* size of message in bytes */ +}MINDEX; + +/***************************************************************************** + + Struct: MFIFO + + Description: Message FIFO. Provides a dynamic sized message based FIFO + queue. + +*****************************************************************************/ +typedef struct _mfifo +{ + int first; /* first out */ + int last; /* last in + 1 */ + int bsize; /* buffer size */ + char *buf; /* ptr to start of buffer */ + int ixsize; /* index size */ + MINDEX ix[1]; /* message index */ +}MFIFO; + +/***************************************************************************** + Function prototypes. +*****************************************************************************/ +int MFIFOCreate(char *buf, int size, int index); +void MFIFOClear(char * buf); +int MFIFOGetLBOffset(char *buf); +int MFIFOGetFBOffset(char *buf); +void MFIFOWriteIX(char *buf, char *mes, int size, int ix, int off); +int MFIFOWriteMes(char *buf, char *mes, int size); +char * MFIFOGetMesPtr(char *buf, int *size); +void MFIFOKillNext(char *buf); + +#endif diff --git a/libs/openzap/src/isdn/mfifo.c b/libs/openzap/src/isdn/mfifo.c new file mode 100644 index 0000000000..adf6bc9ebd --- /dev/null +++ b/libs/openzap/src/isdn/mfifo.c @@ -0,0 +1,296 @@ +/***************************************************************************** + + Filename: mfifo.c + + Description: mfifo is a message orriented fifo system with support of + both message and byte per byte retriaval of messages. + + The fifo has been designed with two usages in mind: + + - Queueing of frames for hdlc and feeding out byte per byte + with the possibility of re-sending of frames etc. + + - fifo for messages of dynamic size. + + The fifo is allocated on top of any buffer and creates an + index of message in the queue. The user can write/read + messages or write messages and read the message one byte + at the time. + + Interface: + MFIFOCreate Create/reset/initialize fifo. + MFIFOClear Clear FIFO. + MFIFOWriteMes Write message into fifo + * MFIFOReadMes Read message from fifo. + MFIFOGetMesPtr Get ptr to next message. + MFIFOKillNext Kill next message. + + * currently not implemented. + + Note: The message will always be saved continuously. If there is not + sufficient space at the end of the buffer, the fifo will skip + the last bytes and save the message at the top of the buffer. + + This is required to allow direct ptr access to messages + stored in the queue. + + License/Copyright: + + Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved. + email:janvb@caselaboratories.com + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the Case Labs, Ltd nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*****************************************************************************/ + +#include "mfifo.h" +#include +#include + +/***************************************************************************** + + Function: MFIFOCreate + + Description: Creates a fifo on top of an existing buffer. + + Parameters: buf ptr to buffer. + size size of buffer in bytes. + index size of index entries (max no messages). + + Return value: 0 if failure, 1 if ok. + +*****************************************************************************/ +int MFIFOCreate(char *buf, int size, int index) +{ + MFIFO * mf; + mf = (MFIFO*)buf; + + mf->first = mf->last = 0; + mf->ixsize = index; + mf->buf = &buf[sizeof(MFIFO) + (sizeof(MINDEX) * (index-1))]; + + if(mf->buf > & buf[size]) + return 0; + + mf->bsize = size - sizeof(MFIFO) - (sizeof(MINDEX) * (index-1)); + + return 1; +} + +/***************************************************************************** + + Function: MFIFOClear + + Description: Clear the FIFO + + Paremeters: buf ptr to fifo + + Return Value: none + +*****************************************************************************/ +void MFIFOClear(char * buf) +{ + MFIFO * mf; + mf = (MFIFO*)buf; + mf->first = mf->last = 0; +} + +/***************************************************************************** + + Function: MFIFOGetLBOffset + + Description: Helper function caclulating offset to the 'first out' byte. + + Paremeters: buf ptr to fifo + + Return Value: offset. + +*****************************************************************************/ +int MFIFOGetLBOffset(char *buf) +{ + MFIFO * mf; + mf = (MFIFO*)buf; + if(mf->last != mf->first) + return mf->ix[mf->last].offset; + + return 0; +} + +/***************************************************************************** + + Function: MFIFOGetFBOffset + + Description: Helper function calculating the offset to the 'first in' + byte in the buffer. This is the position the next byte + entering the fifo will occupy. + + Paremeters: buf ptr to fifo + + Return Value: offset + +*****************************************************************************/ +int MFIFOGetFBOffset(char *buf) +{ + int x; + MFIFO * mf; + mf = (MFIFO*)buf; + if(mf->last == mf->first) + return 0; + x=mf->first; + x--; + if(x<0) + x=mf->ixsize; + return mf->ix[x].offset + mf->ix[x].size; +} + +/***************************************************************************** + + Function: MFIFOWriteIX + + Description: Helper function writing a calculated entry. The function + will perform a memcpy to move the message and set the index + values as well as increase the 'first in' index. + + Paremeters: buf ptr to fifo + mes ptr to message + size size of message in bytes. + ix index to index entry. + off offset to position to receive the message + + Return Value: none + +*****************************************************************************/ +void MFIFOWriteIX(char *buf, char *mes, int size, int ix, int off) +{ + int x; + MFIFO * mf; + mf = (MFIFO*)buf; + memcpy(&mf->buf[off],mes,size); + mf->ix[ix].offset=off; + mf->ix[ix].size=size; + x = mf->first+1; + if(x > mf->ixsize) + x=0; + mf->first=x; +} + +/***************************************************************************** + + Function: MFIFOWriteMes + + Description: + + Paremeters: + + Return Value: + +*****************************************************************************/ +int MFIFOWriteMes(char *buf, char *mes, int size) +{ + int of,ol,x; + MFIFO * mf; + mf = (MFIFO*)buf; + + x = mf->first+1; + if(x > mf->ixsize) + x=0; + if(x == mf->last) + return 0; /* full queue */ + + of = MFIFOGetFBOffset(buf); + ol = MFIFOGetLBOffset(buf); + if(mf->last == mf->first) /* empty queue */ + { + mf->first = mf->last = 0; /* optimize */ + MFIFOWriteIX(buf, mes, size, mf->first, 0); + return 1; + } + else if(of > ol) + { + if(mf->bsize - of >= size) + { + MFIFOWriteIX(buf,mes,size,mf->first,of); + return 1; + } + else if(ol > size) + { + MFIFOWriteIX(buf,mes,size,mf->first,ol); + return 1; + } + } + else if(ol - of > size) + { + MFIFOWriteIX(buf,mes,size,mf->first,of); + return 1; + } + + return 0; +} + +/***************************************************************************** + + Function: MFIFOGetMesPtr + + Description: + + Paremeters: + + Return Value: + +*****************************************************************************/ +char * MFIFOGetMesPtr(char *buf, int *size) +{ + MFIFO * mf; + mf = (MFIFO*)buf; + if(mf->first==mf->last) + return NULL; + *size = mf->ix[mf->last].size; + return &mf->buf[mf->ix[mf->last].offset]; +} + +/***************************************************************************** + + Function: MFIFOKillNext + + Description: + + Paremeters: + + Return Value: + +*****************************************************************************/ +void MFIFOKillNext(char *buf) +{ + int x; + MFIFO * mf; + mf = (MFIFO*)buf; + if(mf->first!=mf->last) + { + x = mf->last+1; + if(x > mf->ixsize) + x=0; + mf->last=x; + } +}