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 <stdlib.h>
+#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<Q921MAXTRUNK;x++)
+    {
+        MFIFOCreate(Q921DevSpace[x].HDLCInQueue, Q921MAXHDLCSPACE, 10);
+        Q921DevSpace[x].vr=0;
+        Q921DevSpace[x].vs=0;
+        Q921DevSpace[x].state=0;;
+    }
+}
+
+void Q921SetHeaderSpace(int hspace)
+{
+    Q921HeaderSpace=hspace;
+}
+
+void Q921SetTx21CB(int (*callback)(int dev, unsigned char *, int))
+{
+    Q921Tx21Proc = callback;
+}
+
+void Q921SetTx23CB(int (*callback)(int dev, unsigned char *, int))
+{
+    Q921Tx23Proc = callback;
+}
+
+/*****************************************************************************
+
+  Function:     Q921QueueHDLCFrame
+
+  Description:  Called to receive and queue an incoming HDLC frame. Will
+                queue this in Q921HDLCInQueue. The called must either call
+                Q921Rx12 directly afterwards or signal Q921Rx12 to be called
+                later. Q921Rx12 will read from the same queue and process
+                the frame.
+
+                This function assumes that the message contains header 
+                space. This is removed for internal Q921 processing, but 
+                must be keept for I frames.
+
+  Parameters:   trunk   trunk #
+                b       ptr to frame;
+                size    size of frame in bytes
+
+*****************************************************************************/
+int Q921QueueHDLCFrame(int trunk, char *b, int size)
+{
+    return MFIFOWriteMes(Q921DevSpace[trunk].HDLCInQueue, b, size);
+}
+
+/*****************************************************************************
+
+  Function:     Q921SendI
+
+  Description:  Compose and Send I Frame to layer. Will receive an I frame
+                with space for L2 header and fill out that header before
+                it call Q921Tx21Proc.
+
+  Parameters:   trunk       trunk #
+                Sapi        Sapi
+                cr          C/R field.
+                Tei         Tei.
+                pf          P fiels octet 5
+                mes         ptr to I frame message.
+                size        size of message in bytes.
+
+  Return Value: 0 if failed, 1 if Send.
+
+*****************************************************************************/
+int Q921SendI(int trunk, unsigned char Sapi, char cr, unsigned char Tei, char pf, char *mes, int size)
+{
+    mes[Q921HeaderSpace+0] = (Sapi&0xfc) | ((cr<<1)&0x02);
+    mes[Q921HeaderSpace+1] = (Tei<<1) | 0x01;
+    mes[Q921HeaderSpace+2] = Q921DevSpace[trunk].vs<<1;
+    mes[Q921HeaderSpace+3] = (Q921DevSpace[trunk].vr<<1) | (pf & 0x01);
+    Q921DevSpace[trunk].vs++;
+
+    return Q921Tx21Proc(trunk, mes, size);
+}
+
+/*****************************************************************************
+
+  Function:     Q921SendRR
+
+  Description:  Compose and send Receive Ready.
+
+  Parameters:   trunk       trunk #
+                Sapi        Sapi
+                cr          C/R field.
+                Tei         Tei.
+                pf          P/F fiels octet 5
+
+  Return Value: 0 if failed, 1 if Send.
+
+*****************************************************************************/
+
+int Q921SendRR(int trunk, int Sapi, int cr, int Tei, int pf)
+{
+    char mes[400];
+
+    mes[Q921HeaderSpace+0] = (Sapi&0xfc) | ((cr<<1)&0x02);
+    mes[Q921HeaderSpace+1] = (Tei<<1) | 0x01;
+    mes[Q921HeaderSpace+2] = 0x01;
+    mes[Q921HeaderSpace+3] = (Q921DevSpace[trunk].vr<<1) | (pf & 0x01);
+
+    return Q921Tx21Proc(trunk, mes, Q921HeaderSpace+4);
+}
+
+/*****************************************************************************
+
+  Function:     Q921SendRNR
+
+  Description:  Compose and send Receive Nor Ready
+
+  Parameters:   trunk       trunk #
+                Sapi        Sapi
+                cr          C/R field.
+                Tei         Tei.
+                pf          P/F fiels octet 5
+
+  Return Value: 0 if failed, 1 if Send.
+
+*****************************************************************************/
+int Q921SendRNR(int trunk, int Sapi, int cr, int Tei, int pf)
+{
+    char mes[400];
+
+    mes[Q921HeaderSpace+0] = (Sapi&0xfc) | ((cr<<1)&0x02);
+    mes[Q921HeaderSpace+1] = (Tei<<1) | 0x01;
+    mes[Q921HeaderSpace+2] = 0x05;
+    mes[Q921HeaderSpace+3] = (Q921DevSpace[trunk].vr<<1) | (pf & 0x01);
+
+    return Q921Tx21Proc(trunk, mes, Q921HeaderSpace+4);
+}
+
+/*****************************************************************************
+
+  Function:     Q921SendREJ
+
+  Description:  Compose and Send Reject.
+
+  Parameters:   trunk       trunk #
+                Sapi        Sapi
+                cr          C/R field.
+                Tei         Tei.
+                pf          P/F fiels octet 5
+
+  Return Value: 0 if failed, 1 if Send.
+
+*****************************************************************************/
+int Q921SendREJ(int trunk, int Sapi, int cr, int Tei, int pf)
+{
+    char mes[400];
+
+    mes[Q921HeaderSpace+0] = (Sapi&0xfc) | ((cr<<1)&0x02);
+    mes[Q921HeaderSpace+1] = (Tei<<1) | 0x01;
+    mes[Q921HeaderSpace+2] = 0x09;
+    mes[Q921HeaderSpace+3] = (Q921DevSpace[trunk].vr<<1) | (pf & 0x01);
+
+    return Q921Tx21Proc(trunk, mes, Q921HeaderSpace+4);
+}
+
+/*****************************************************************************
+
+  Function:     Q921SendSABME
+
+  Description:  Compose and send SABME
+
+  Parameters:   trunk       trunk #
+                Sapi        Sapi
+                cr          C/R field.
+                Tei         Tei.
+                pf          P fiels octet 4
+
+  Return Value: 0 if failed, 1 if Send.
+
+*****************************************************************************/
+int Q921SendSABME(int trunk, int Sapi, int cr, int Tei, int pf)
+{
+    char mes[400];
+
+    mes[Q921HeaderSpace+0] = (Sapi&0xfc) | ((cr<<1)&0x02);
+    mes[Q921HeaderSpace+1] = (Tei<<1) | 0x01;
+    mes[Q921HeaderSpace+2] = 0x6f | ((pf<<4)&0x10);
+
+    return Q921Tx21Proc(trunk, mes, Q921HeaderSpace+3);
+}
+
+/*****************************************************************************
+
+  Function:     Q921SendDM
+
+  Description:  Comose and Send DM (Disconnected Mode)
+
+  Parameters:   trunk       trunk #
+                Sapi        Sapi
+                cr          C/R field.
+                Tei         Tei.
+                pf          F fiels octet 4
+
+  Return Value: 0 if failed, 1 if Send.
+
+*****************************************************************************/
+int Q921SendDM(int trunk, int Sapi, int cr, int Tei, int pf)
+{
+    char mes[400];
+
+    mes[Q921HeaderSpace+0] = (Sapi&0xfc) | ((cr<<1)&0x02);
+    mes[Q921HeaderSpace+1] = (Tei<<1) | 0x01;
+    mes[Q921HeaderSpace+2] = 0x0f | ((pf<<4)&0x10);
+
+    return Q921Tx21Proc(trunk, mes, Q921HeaderSpace+3);
+}
+
+/*****************************************************************************
+
+  Function:     Q921
+
+  Description:
+
+  Parameters:   trunk       trunk #
+                Sapi        Sapi
+                cr          C/R field.
+                Tei         Tei.
+                pf          P fiels octet 4
+
+  Return Value: 0 if failed, 1 if Send.
+
+*****************************************************************************/
+//int Q921SendUI(...)
+//{
+//}
+
+/*****************************************************************************
+
+  Function:     Q921SendDISC
+
+  Description:  Compose and Send Disconnect
+
+  Parameters:   trunk       trunk #
+                Sapi        Sapi
+                cr          C/R field.
+                Tei         Tei.
+                pf          P fiels octet 4
+
+  Return Value: 0 if failed, 1 if Send.
+
+*****************************************************************************/
+int Q921SendDISC(int trunk, int Sapi, int cr, int Tei, int pf)
+{
+    char mes[400];
+
+    mes[Q921HeaderSpace+0] = (Sapi&0xfc) | ((cr<<1)&0x02);
+    mes[Q921HeaderSpace+1] = (Tei<<1) | 0x01;
+    mes[Q921HeaderSpace+2] = 0x43 | ((pf<<4)&0x10);
+
+    return Q921Tx21Proc(trunk, mes, Q921HeaderSpace+3);
+}
+
+/*****************************************************************************
+
+  Function:     Q921SendUA
+
+  Description:  Compose and Send UA
+
+  Parameters:   trunk       trunk #
+                Sapi        Sapi
+                cr          C/R field.
+                Tei         Tei.
+                pf          F fiels octet 4
+
+  Return Value: 0 if failed, 1 if Send.
+
+*****************************************************************************/
+int Q921SendUA(int trunk, int Sapi, int cr, int Tei, int pf)
+{
+    char mes[400];
+
+    mes[Q921HeaderSpace+0] = (Sapi&0xfc) | ((cr<<1)&0x02);
+    mes[Q921HeaderSpace+1] = (Tei<<1) | 0x01;
+    mes[Q921HeaderSpace+2] = 0x63 | ((pf<<4)&0x10);
+
+    return Q921Tx21Proc(trunk, mes, Q921HeaderSpace+3);
+}
+
+/*****************************************************************************
+
+  Function:     Q921
+
+  Description:
+
+  Parameters:   trunk       trunk #
+                Sapi        Sapi
+                cr          C/R field.
+                Tei         Tei.
+                pf          P fiels octet 5
+
+  Return Value: 0 if failed, 1 if Send.
+
+*****************************************************************************/
+//int Q921SendFRMR(...)
+//{
+//}
+
+/*****************************************************************************
+
+  Function:     Q921
+
+  Description:
+
+  Parameters:   trunk       trunk #
+                Sapi        Sapi
+                cr          C/R field.
+                Tei         Tei.
+                pf          P fiels octet 5
+
+  Return Value: 0 if failed, 1 if Send.
+
+*****************************************************************************/
+//int Q921SendXID(...)
+//{
+//}
+
+int Q921ProcSABME(int trunk, char *mes, int size)
+{
+    Q921DevSpace[trunk].vr=0;
+    Q921DevSpace[trunk].vs=0;
+
+    return 1;
+}
+
+/*****************************************************************************
+
+  Function:     Q921Rx12
+
+  Description:  Called to process a message frame from layer 1. Will 
+                identify the message and call the proper 'processor' for
+                layer 2 messages and forward I frames to the layer 3 entity.
+
+                Q921Rx12 will check the input fifo for a message, and if a 
+                message exist process one message before it exits. The caller
+                must either call Q921Rx12 polling or keep track on # 
+                messages in the queue.
+
+  Parameters:   trunk       trunk #.
+
+  Return Value: # messages processed (always 1 or 0).
+
+*****************************************************************************/
+int Q921Rx12(long trunk)
+{
+    char *mes;
+    int rs,size;     /* receive size & Q921 frame size*/
+    char *smes = MFIFOGetMesPtr(Q921DevSpace[trunk].HDLCInQueue, &size);
+    if(smes != NULL)
+    {
+        rs = size - Q921HeaderSpace;
+        mes = &smes[Q921HeaderSpace];
+        /* check for I frame */
+        if((mes[2] & 0x01) == 0)
+        {
+            if(Q921Tx23Proc(trunk, smes, size-2)) /* -2 to clip away CRC */
+            {
+                Q921DevSpace[trunk].vr++;
+                Q921SendRR(trunk, (mes[0]&0xfc)>>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<Q931MAXMES;y++)
+        {
+            Q931Proc[x][y] = Q931ProcDummy;
+            Q931Umes[x][y] = Q931UmesDummy;
+            Q931Pmes[x][y] = Q931PmesDummy;
+        }
+        for(y=0;y<Q931MAXIE;y++)
+        {
+            Q931Pie[x][y] = Q931PieDummy;
+            Q931Uie[x][y] = Q931UieDummy;
+        }
+    }
+
+	if(Q931CreateDialectCB[0] == NULL)
+		Q931AddDialect(0, Q931CreateTE);
+
+	if(Q931CreateDialectCB[1] == NULL)
+		Q931AddDialect(1, Q931CreateNT);
+
+	/* The last step we do is to call the callbacks to create the dialects  */
+	for(x=0; x< Q931MAXDLCT; x++)
+	{
+		if(Q931CreateDialectCB[x] != NULL)
+		{
+			Q931CreateDialectCB[x]((L3UCHAR)x);
+		}
+	}
+}
+
+/*****************************************************************************
+
+  Function:     Q931TimeTick
+
+  Description:  Called periodically from an external source to allow the 
+                stack to process and maintain it's own timers.
+
+  Parameters:   ms[IN]        Milliseconds since last call.
+
+  Return Value: none
+
+*****************************************************************************/
+void Q931TimeTick(L3ULONG ms)
+{
+    ms=ms; // avoid warning for now.
+
+	// TODO: Loop through all active calls, check timers and call timour procs
+	// if timers are expired.
+	// Implement an function array so each dialect can deal with their own
+	// timeouts.
+}
+
+/*****************************************************************************
+
+  Function:     Q931Rx23
+
+  Description:  Receive message from layer 2 (LAPD). Receiving a message 
+                is always done in 2 steps. First the message must be 
+                interpreted and translated to a static struct. Secondly
+                the message is processed and responded to.
+
+				The Q.931 message contains a static header that is 
+				interpreated in his function. The rest is interpreted
+				in a sub function according to mestype.
+
+  Parameters:   pTrunk	[IN]	Ptr to trunk info.
+				buf		[IN]	Ptr to buffer containing message.
+				Size	[IN]	Size of message.
+
+  Return Value: Error Code. 0 = No Error, < 0 :error, > 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;x<sN;x++)
+    {
+        OBuf[(*Octet)++] = pIE->Digit[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;x<sN;x++)
+    {
+        OBuf[(*Octet)++] = pIE->Digit[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;x<sN;x++)
+    {
+        OBuf[(*Octet)++] = pIE->Digit[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;x<sN;x++)
+    {
+        OBuf[(*Octet)++] = pIE->Digit[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; x<IESize; x++)
+    {
+        pie->Display[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; x<IESize; x++)
+    {
+        pie->KeypadFac[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 <pIE->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;x<l;x++)
+    {
+        OBuf[(*Octet)++] = pIE->NetID[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;x<l;x++)
+    {
+        OBuf[(*Octet)++] = pIE->User[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.
+
+
+                <TODO> 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:
+
+					<variant>.h			Spesific headers needed.
+					<variant>mes.c		Message encoders/decores.
+					<variant>ie.c		IE encoders/decoders.
+					<variant>StateTE.c	TE side state engine.
+					<variant>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 <memory.h>
+#include <stdlib.h>
+
+/*****************************************************************************
+
+  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;
+    }
+}