root/src/isdn/Q931ie.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. Q931ReadExt
  2. Q931Uie_BearerCap
  3. Q931Pie_BearerCap
  4. Q931Uie_CallID
  5. Q931Pie_CallID
  6. Q931Uie_CallState
  7. Q931Pie_CallState
  8. Q931Uie_CalledSub
  9. Q931Pie_CalledSub
  10. Q931Uie_CalledNum
  11. Q931Pie_CalledNum
  12. Q931Uie_CallingNum
  13. Q931Pie_CallingNum
  14. Q931Uie_CallingSub
  15. Q931Pie_CallingSub
  16. Q931Uie_Cause
  17. Q931Pie_Cause
  18. Q931Uie_CongLevel
  19. Q931Pie_CongLevel
  20. Q931Uie_ChanID
  21. Q931Pie_ChanID
  22. Q931Uie_CRV
  23. Q931Uie_DateTime
  24. Q931Pie_DateTime
  25. Q931Uie_Display
  26. Q931Pie_Display
  27. Q931Uie_HLComp
  28. Q931Pie_HLComp
  29. Q931Uie_KeypadFac
  30. Q931Pie_KeypadFac
  31. Q931Uie_LLComp
  32. Q931Pie_LLComp
  33. Q931Uie_NetFac
  34. Q931Pie_NetFac
  35. Q931Uie_NotifInd
  36. Q931Pie_NotifInd
  37. Q931Uie_ProgInd
  38. Q931Pie_ProgInd
  39. Q931Uie_RepeatInd
  40. Q931Pie_RepeatInd
  41. Q931Uie_RevChargeInd
  42. Q931Pie_RevChargeInd
  43. Q931Uie_RestartInd
  44. Q931Pie_RestartInd
  45. Q931Uie_Segment
  46. Q931Pie_Segment
  47. Q931Uie_SendComplete
  48. Q931Pie_SendComplete
  49. Q931Uie_Signal
  50. Q931Pie_Signal
  51. Q931Uie_TransNetSel
  52. Q931Pie_TransNetSel
  53. Q931Uie_UserUser
  54. Q931Pie_UserUser
  55. Q931Uie_GenericDigits
  56. Q931Pie_GenericDigits
  57. Q931Uie_ChangeStatus
  58. Q931Pie_ChangeStatus
  59. Q931Uie_Generic
  60. Q931Pie_Generic

   1 /*****************************************************************************
   2 
   3   FileName:      Q931ie.c
   4 
   5   Contents:      Information Element Pack/Unpack functions. 
   6   
   7                 These functions will pack out a Q931 message from the bit 
   8                 packed original format into structs that are easier to process 
   9                 and pack the same structs back into bit fields when sending
  10                 messages out.
  11 
  12                 The messages contains a short for each possible IE. The MSB 
  13                 bit flags the precense of an IE, while the remaining bits 
  14                 are the offset into a buffer to find the actual IE.
  15 
  16                 Each IE are supported by 3 functions:
  17 
  18                 Q931Pie_XXX      Pack struct into Q.931 IE
  19                 Q931Uie_XXX      Unpack Q.931 IE into struct
  20                 Q931InitIEXXX   Initialize IE (see Q931api.c).
  21 
  22   Dialect Note: This file will only contain standard DSS1 IE. Other IE as 
  23                 used in QSIG, NI2, Q.932 etc are located in separate files.
  24 
  25                 See     q931.h for description. 
  26 
  27   License/Copyright:
  28 
  29   Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved.
  30   email:janvb@caselaboratories.com  
  31 
  32   Redistribution and use in source and binary forms, with or without 
  33   modification, are permitted provided that the following conditions are 
  34   met:
  35 
  36         * Redistributions of source code must retain the above copyright notice, 
  37           this list of conditions and the following disclaimer.
  38         * Redistributions in binary form must reproduce the above copyright notice, 
  39           this list of conditions and the following disclaimer in the documentation 
  40           and/or other materials provided with the distribution.
  41         * Neither the name of the Case Labs, Ltd nor the names of its contributors 
  42           may be used to endorse or promote products derived from this software 
  43           without specific prior written permission.
  44 
  45   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
  46   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
  47   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
  48   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
  49   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
  50   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
  51   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
  52   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
  53   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
  54   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
  55   POSSIBILITY OF SUCH DAMAGE.
  56 *****************************************************************************/
  57 
  58 #include "Q931.h"
  59 
  60 #ifdef _MSC_VER
  61 #ifndef __inline__
  62 #define __inline__ __inline
  63 #endif
  64 #if (_MSC_VER >= 1400)                  /* VC8+ */
  65 #ifndef _CRT_SECURE_NO_DEPRECATE
  66 #define _CRT_SECURE_NO_DEPRECATE
  67 #endif
  68 #ifndef _CRT_NONSTDC_NO_DEPRECATE
  69 #define _CRT_NONSTDC_NO_DEPRECATE
  70 #endif
  71 #endif
  72 #ifndef strcasecmp
  73 #define strcasecmp(s1, s2) _stricmp(s1, s2)
  74 #endif
  75 #ifndef strncasecmp
  76 #define strncasecmp(s1, s2, n) _strnicmp(s1, s2, n)
  77 #endif
  78 #ifndef snprintf
  79 #define snprintf _snprintf
  80 #endif
  81 #endif
  82 
  83 /*****************************************************************************
  84 
  85   Macro:                Q931MoreIE
  86 
  87   Description:  Local helper macro detecting if there is more IE space left
  88                 based on the 3 standard parameters Octet, Off and IESpace.
  89                 This can be used to test if the IE is completed to avoid
  90                 that the header of the next IE is interpreted as a part of
  91                 the current IE.
  92 
  93 *****************************************************************************/
  94 #define Q931MoreIE() (Octet + Off - 2 < IESize)
  95 
  96 #define Q931IESizeTest(x) {\
  97         if (Octet + Off - 2 != IESize) {\
  98                 Q931SetError(pTrunk, x, Octet, Off);\
  99                 return x;\
 100         }\
 101 }
 102 
 103 /*****************************************************************************
 104 
 105   Function:      Q931ReadExt
 106 
 107   Description:  Many of the octets in the standard have an MSB 'ext.1'. This
 108                                 means that the octet usually is the latest octet, but that a
 109                                 futhure standard may extend the octet. A stack must be able 
 110                                 to handle such extensions by skipping the extension octets.
 111 
 112                                 This function will increase the offset counter with 1 for 
 113                                 each octet with an MSB of zero. This will allow the stack to
 114                                 skip extensions wihout knowing anything about them.
 115 
 116   Parameters:   IBuf    ptr to octet array.
 117                                 Off      Starting offset counter
 118 
 119   Return Value: New offset value.
 120 
 121 *****************************************************************************/
 122 
 123 L3INT Q931ReadExt(L3UCHAR * IBuf, L3INT Off)
 124 {
 125         L3INT c = 0;
 126         while ((IBuf[c] & 0x80) == 0) {
 127                 c++;
 128         }
 129         return Off + c;
 130 }
 131 
 132 /*****************************************************************************
 133 
 134   Function:      Q931Uie_BearerCap
 135 
 136   Description:  Unpack a bearer capability ie.
 137 
 138   Parameters:   pIE[OUT]        ptr to Information Element id.
 139                 IBuf[IN]        ptr to a packed ie.
 140                 OBuf[OUT]       ptr to buffer for Unpacked ie.
 141                 IOff[IN\OUT]    Input buffer offset
 142                 OOff[IN\OUT]    Output buffer offset
 143 
 144                 Ibuf and OBuf points directly to buffers. The IOff and OOff
 145                 must be updated, but are otherwise not used in the ie unpack.
 146 
 147   Return Value: Error Message
 148 
 149 *****************************************************************************/
 150 
 151 L3INT Q931Uie_BearerCap(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) 
 152 {
 153         Q931ie_BearerCap *pie = (Q931ie_BearerCap*)OBuf;
 154         ie *pIE = &pMsg->BearerCap;
 155         L3INT Off = 0;
 156         L3INT Octet = 0;
 157         L3INT IESize;
 158         *pIE = 0;
 159 
 160         /* Octet 1 */
 161         pie->IEId = IBuf[Octet++];
 162 
 163         /* Octet 2 */
 164         IESize = IBuf[Octet++]; 
 165 
 166         /* Octet 3 */
 167         pie->CodStand = ieGetOctet((IBuf[Octet] & 0x60) >> 5);
 168         pie->ITC      = ieGetOctet(IBuf[Octet] & 0x1f);
 169         Off           = Q931ReadExt(&IBuf[Octet], Off);
 170         Octet++;
 171 
 172         /* Octet 4 */
 173         pie->TransMode = ieGetOctet((IBuf[Octet + Off] & 0x60) >> 5);
 174         pie->ITR       = ieGetOctet(IBuf[Octet + Off] & 0x1f);
 175         Off            = Q931ReadExt(&IBuf[Octet + Off], Off);
 176         Octet++;
 177 
 178         /* Octet 4.1. Rate multiplier is only present if ITR = Multirate                */
 179         if (pie->ITR == 0x18) {
 180                 pie->RateMul = ieGetOctet(IBuf[Octet + Off] & 0x7f);
 181                 Off = Q931ReadExt(&IBuf[Octet + Off], Off);
 182                 Off ++;
 183         }
 184 
 185         /* Octet 5 */
 186         if ((IBuf[Octet + Off] & 0x60) == 0x20 && Q931MoreIE()) {
 187                 pie->Layer1Ident = ieGetOctet((IBuf[Octet + Off] & 0x60) >> 5);
 188                 pie->UIL1Prot    = ieGetOctet(IBuf[Octet + Off] & 0x1f);
 189                 Octet++;
 190 
 191                 /* Octet 5a. The octet may be present if ITC is unrestrictd digital info
 192                  * and UIL1Prot is either V.110, I.460 and X.30 or V.120. It may also
 193                  * be present if ITC = 3.1 kHz audio and UIL1Prot is G.711.
 194                  * Bit 8 of Octet 5 = 0 indicates that 5a is present.
 195                  */
 196 
 197                 if (IsQ931Ext(IBuf[Octet + Off - 1])) {
 198                         if (((pie->ITC == 0x08) && (pie->UIL1Prot == 0x01 || pie->UIL1Prot == 0x08))
 199                         || ((pie->ITC == 0x10) && (pie->UIL1Prot == 0x02 || pie->UIL1Prot == 0x03))) {
 200                                 pie->SyncAsync = ieGetOctet((IBuf[Octet + Off] & 0x40) >> 6);
 201                                 pie->Negot     = ieGetOctet((IBuf[Octet + Off] & 0x20) >> 5);
 202                                 pie->UserRate  = ieGetOctet(IBuf[Octet + Off] & 0x1f);
 203                                 Off ++;
 204                         }
 205                         else {
 206                                 /* We have detected bit 8 = 0, but no setting that require the  */
 207                                 /* additional octets ??? */
 208                                 Q931SetError(pTrunk, Q931E_BEARERCAP, 5,Off);
 209                                 return Q931E_BEARERCAP;
 210                         }
 211 
 212                         /* Octet 5b. Two different structures used. */
 213                         if (IsQ931Ext(IBuf[Octet + Off - 1])) {
 214                                 if (pie->UIL1Prot == 0x01) { /* ITU V.110, I.460 and X.30 */
 215                                         pie->InterRate = ieGetOctet((IBuf[Octet + Off] & 0x60) >> 5);
 216                                         pie->NIConTx   = ieGetOctet((IBuf[Octet + Off] & 0x10) >> 4);
 217                                         pie->NIConRx   = ieGetOctet((IBuf[Octet + Off] & 0x08) >> 3);
 218                                         pie->FlowCtlTx = ieGetOctet((IBuf[Octet + Off] & 0x04) >> 2);
 219                                         pie->FlowCtlRx = ieGetOctet((IBuf[Octet + Off] & 0x20) >> 1);
 220                                         Off++;
 221                                 }
 222                                 else if (pie->UIL1Prot == 0x08) { /* ITU V.120 */
 223                                         pie->HDR        = ieGetOctet((IBuf[Octet + Off] & 0x40) >> 6);
 224                                         pie->MultiFrame = ieGetOctet((IBuf[Octet + Off] & 0x20) >> 5);
 225                                         pie->Mode       = ieGetOctet((IBuf[Octet + Off] & 0x10) >> 4);
 226                                         pie->LLInegot   = ieGetOctet((IBuf[Octet + Off] & 0x08) >> 3);
 227                                         pie->Assignor   = ieGetOctet((IBuf[Octet + Off] & 0x04) >> 2);
 228                                         pie->InBandNeg  = ieGetOctet((IBuf[Octet + Off] & 0x02) >> 1);
 229                                         Off++;
 230                                 }
 231                                 else {
 232                                         Q931SetError(pTrunk,Q931E_BEARERCAP, 5,Off);
 233                                         return Q931E_BEARERCAP;
 234                                 }
 235 
 236                                 /* Octet 5c */
 237                                 if (IsQ931Ext(IBuf[Octet + Off - 1])) {
 238                                         pie->NumStopBits = ieGetOctet((IBuf[Octet + Off] & 0x60) >> 5);
 239                                         pie->NumDataBits = ieGetOctet((IBuf[Octet + Off] & 0x18) >> 3);
 240                                         pie->Parity      = ieGetOctet(IBuf[Octet + Off] & 0x07);
 241                                         Off++;
 242 
 243                                         /* Octet 5d */
 244                                         if (IsQ931Ext(IBuf[Octet + Off - 1])) {
 245                                                 pie->DuplexMode = ieGetOctet((IBuf[Octet + Off] & 0x40) >> 6);
 246                                                 pie->ModemType  = ieGetOctet(IBuf[Octet + Off] & 0x3f);
 247                                                 Off ++;
 248                                         }
 249                                 }
 250                         }
 251                 }
 252         }
 253 
 254         /* Octet 6 */
 255         if ((IBuf[Octet + Off] & 0x60) == 0x40 && Q931MoreIE()) {
 256                 pie->Layer2Ident = ieGetOctet((IBuf[Octet + Off] & 0x60) >> 5);
 257                 pie->UIL2Prot    = ieGetOctet(IBuf[Octet + Off] & 0x1f);
 258 
 259                 Off = Q931ReadExt(&IBuf[Octet + Off], Off);
 260                 Octet ++;
 261         }
 262 
 263         /* Octet 7 */
 264         if ((IBuf[Octet + Off] & 0x60) == 0x60 && Q931MoreIE()) {
 265                 pie->Layer3Ident = ieGetOctet((IBuf[Octet + Off] & 0x60) >> 5);
 266                 pie->UIL3Prot    = ieGetOctet(IBuf[Octet + Off] & 0x1f);
 267                 Octet++;
 268 
 269                 /* Octet 7a */
 270                 if (IsQ931Ext(IBuf[Octet + Off - 1])) {
 271                         if (pie->UIL3Prot == 0x0c) {
 272                                 pie->AL3Info1 = ieGetOctet(IBuf[Octet + Off] & 0x0f);
 273                                 Off++;
 274 
 275                                 /* Octet 7b */
 276                                 if (IsQ931Ext(IBuf[Octet + Off])) {
 277                                         pie->AL3Info2 = ieGetOctet(IBuf[Octet + Off] & 0x0f);
 278                                         Off++;
 279                                 }
 280                         }
 281                         else {
 282                                 Q931SetError(pTrunk,Q931E_BEARERCAP, 7, Off);
 283                                 return Q931E_BEARERCAP;
 284 
 285                         }
 286                 }
 287         }
 288 
 289         Q931IESizeTest(Q931E_BEARERCAP);
 290         Q931SetIE(*pIE, *OOff);
 291 
 292         *IOff = (*IOff) + Octet + Off;
 293         *OOff = (*OOff) + sizeof(Q931ie_BearerCap);
 294         pie->Size = sizeof(Q931ie_BearerCap);
 295 
 296         return Q931E_NO_ERROR;
 297 }
 298 
 299 /*****************************************************************************
 300 
 301   Function:      Q931Pie_BearerCap
 302 
 303   Description:  Packing a Q.931 Bearer Capability element from a generic 
 304                                 struct into a packed octet structure in accordance with the
 305                                 standard.
 306 
 307   Parameters:   IBuf[IN]                Ptr to struct.
 308                                 OBuf[OUT]               Ptr tp packed output buffer.
 309                                 Octet[IN/OUT]   Offset into OBuf.
 310 
 311   Return Value: Error code, 0 = OK
 312 
 313 *****************************************************************************/
 314 
 315 L3INT Q931Pie_BearerCap(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
 316 {
 317         Q931ie_BearerCap *pIE = (Q931ie_BearerCap*)IBuf;
 318         L3INT rc = 0;
 319         L3INT Beg = *Octet; /* remember current offset */
 320         L3INT li;
 321 
 322         Q931Log(pTrunk, Q931_LOG_DEBUG, "Encoding Bearer Capability IE\n");
 323 
 324         OBuf[(*Octet)++] = Q931ie_BEARER_CAPABILITY ;
 325         li = (*Octet)++; /* remember length position */
 326 
 327         /* Octet 3 - Coding standard / Information transfer capability */
 328         OBuf[(*Octet)++] = 0x80 | ((pIE->CodStand << 5) & 0x60) | (pIE->ITC & 0x1f);
 329 
 330         /* Octet 4 - Transfer mode / Information transfer rate */
 331         OBuf[(*Octet)++] = 0x80 | ((pIE->TransMode << 5) & 0x60) | (pIE->ITR & 0x1f);
 332 
 333         if (pIE->ITR == 0x18) {
 334                 /* Octet 4.1 - Rate Multiplier */
 335                 OBuf[(*Octet)++] = 0x80 | (pIE->RateMul & 0x7f);
 336         }
 337 
 338         /* Octet 5 - Layer 1 Ident / User information layer 1 protocol */
 339         if (pIE->Layer1Ident == 0x01) {
 340                 if (((pIE->ITC == 0x08) && (pIE->UIL1Prot == 0x01 || pIE->UIL1Prot == 0x08)) ||
 341                    ((pIE->ITC == 0x10) && (pIE->UIL1Prot == 0x02 || pIE->UIL1Prot == 0x03))) {
 342                         OBuf[(*Octet)++] = 0x00 | ((pIE->Layer1Ident << 5) & 0x60) | (pIE->UIL1Prot & 0x15);
 343                         
 344                         /* Octet 5a - SyncAsync/Negot/UserRate */
 345                         OBuf[(*Octet)++] = 0x00 | ((pIE->SyncAsync << 6) & 0x40) | ((pIE->Negot << 5) & 0x20) | (pIE->UserRate & 0x1f);
 346 
 347                         /* Octet 5b - one of two types */
 348                         if (pIE->UIL1Prot == 0x01) { /* ITU V.110, I.460 and X.30       */
 349                                 /* Octet 5b - Intermed rate/ Nic on Tx/Nix on Rx/FlowCtlTx/FlowCtlRx */
 350                                 OBuf[(*Octet)++] = 0x00 
 351                                                 | ((pIE->InterRate << 6) & 0x60)
 352                                                 | ((pIE->NIConTx   << 4) & 0x10)
 353                                                 | ((pIE->NIConRx   << 3) & 0x08)
 354                                                 | ((pIE->FlowCtlTx << 2) & 0x04)
 355                                                 | ((pIE->FlowCtlRx << 1) & 0x02);
 356                         }
 357                         else if (pIE->UIL1Prot == 0x08) { /* ITU V.120 */
 358                                 /* Octet 5b - HDR/Multiframe/Mode/LLINegot/Assignor/Inbandneg*/
 359                                 OBuf[(*Octet)++] = 0x00
 360                                                 | ((pIE->InterRate  << 6) & 0x60)
 361                                                 | ((pIE->MultiFrame << 5) & 0x20)
 362                                                 | ((pIE->Mode       << 4) & 0x10)
 363                                                 | ((pIE->LLInegot   << 3) & 0x08)
 364                                                 | ((pIE->Assignor   << 2) & 0x04)
 365                                                 | ((pIE->InBandNeg  << 1) & 0x02);
 366                         }
 367 
 368                         /* Octet 5c - NumStopBits/NumStartBits/Parity                                   */
 369                         OBuf[(*Octet)++] = 0x00
 370                                         | ((pIE->NumStopBits << 5) & 0x60)
 371                                         | ((pIE->NumDataBits << 3) & 0x18)
 372                                         | (pIE->Parity & 0x07);
 373 
 374                         /* Octet 5d - Duplex Mode/Modem Type */
 375                         OBuf[(*Octet)++] = 0x80 | ((pIE->DuplexMode << 6) & 0x40) | (pIE->ModemType & 0x3f);
 376                 }
 377                 else {
 378                         OBuf[(*Octet)++] = 0x80 | ((pIE->Layer1Ident << 5) & 0x60) | (pIE->UIL1Prot & 0x1f);
 379                 }
 380         }
 381 
 382         /* Octet 6 - Layer2Ident/User information layer 2 prtocol */
 383         if (pIE->Layer2Ident == 0x02) {
 384                 OBuf[(*Octet)++] = 0x80 | ((pIE->Layer2Ident << 5) & 0x60) | (pIE->UIL2Prot & 0x1f);
 385         }
 386 
 387         /* Octet 7 - Layer 3 Ident/ User information layer 3 protocol */
 388         if (pIE->Layer3Ident == 0x03) {
 389                 if (pIE->UIL3Prot == 0x0c) {
 390                         OBuf[(*Octet)++] = 0x00 | ((pIE->Layer3Ident << 5) & 0x60) | (pIE->UIL3Prot & 0x1f);
 391 
 392                         /* Octet 7a - Additional information layer 3 msb */
 393                         OBuf[(*Octet)++] = 0x00 | (pIE->AL3Info1 & 0x0f);
 394 
 395                         /* Octet 7b - Additional information layer 3 lsb */
 396                         OBuf[(*Octet)++] = 0x80 | (pIE->AL3Info2 & 0x0f);
 397                 }
 398                 else {
 399                         OBuf[(*Octet)++] = 0x80 | ((pIE->Layer3Ident << 5) & 0x60) | (pIE->UIL3Prot & 0x1f);
 400                 }
 401         }
 402 
 403         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
 404         return rc;
 405 }
 406 
 407 /*****************************************************************************
 408 
 409   Function:      Q931Uie_CallID
 410 
 411   Parameters:   pIE[OUT]                ptr to Information Element id.
 412                                 IBuf[IN]                ptr to a packed ie.
 413                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
 414                                 IOff[IN\OUT]    Input buffer offset
 415                                 OOff[IN\OUT]    Output buffer offset
 416 
 417 
 418                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
 419                                 must be updated, but are otherwise not used in the ie unpack.
 420 
 421   Return Value: Error Message
 422 
 423 *****************************************************************************/
 424 L3INT Q931Uie_CallID(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
 425 {
 426         Q931ie_CallID *pie = (Q931ie_CallID*)OBuf;
 427         ie *pIE = &pMsg->CallID;
 428         L3INT Off = 0;
 429         L3INT Octet = 0;
 430         L3INT x = 0;
 431         L3INT IESize;
 432 
 433         *pIE = 0;
 434 
 435         /* Octet 1 */
 436         pie->IEId = IBuf[Octet++];
 437 
 438         /* Octet 2 */
 439         IESize = IBuf[Octet++]; 
 440 
 441         /* Octet 3 */
 442         do {
 443                 pie->CallId[x] = IBuf[Octet + Off] & 0x7f;
 444                 Off++;
 445                 x++;
 446         } while (Q931MoreIE());
 447 
 448         Q931IESizeTest(Q931E_CALLID);
 449         Q931SetIE(*pIE, *OOff);
 450 
 451         *IOff = (*IOff) + Octet + Off;
 452         *OOff = (*OOff) + sizeof(Q931ie_CallID) + x - 1;
 453         pie->Size = (L3UCHAR)(sizeof(Q931ie_CallID) + x - 1);
 454 
 455         return Q931E_NO_ERROR;
 456 }
 457 
 458 /*****************************************************************************
 459 
 460   Function:      Q931Pie_CallID
 461 
 462   Parameters:   IBuf[IN]                Ptr to struct.
 463                                 OBuf[OUT]               Ptr tp packed output buffer.
 464                                 Octet[IN/OUT]   Offset into OBuf.
 465 
 466   Return Value: Error code, 0 = OK
 467 
 468 *****************************************************************************/
 469 
 470 L3INT Q931Pie_CallID(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
 471 {
 472         Q931ie_CallID *pIE = (Q931ie_CallID*)IBuf;
 473         L3INT rc = 0;
 474         L3INT Beg = *Octet;/* remember current offset */
 475         L3INT li;
 476         L3INT sCI = pIE->Size - sizeof(Q931ie_CallID) + 1;
 477         L3INT x;
 478 
 479         OBuf[(*Octet)++] = Q931ie_CALL_IDENTITY ;
 480         li = (*Octet)++; /* remember length position */
 481 
 482         for (x = 0; x < sCI; x++) {
 483                 OBuf[(*Octet)++] = pIE->CallId[x];
 484         }
 485 
 486         OBuf[(*Octet) - 1] |= 0x80; /* set complete flag at last octet*/
 487 
 488         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
 489         return rc;
 490 }
 491 
 492 /*****************************************************************************
 493 
 494   Function:      Q931Uie_CallState
 495 
 496   Parameters:   pIE[OUT]                ptr to Information Element id.
 497                                 IBuf[IN]                ptr to a packed ie.
 498                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
 499                                 IOff[IN\OUT]    Input buffer offset
 500                                 OOff[IN\OUT]    Output buffer offset
 501 
 502                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
 503                                 must be updated, but are otherwise not used in the ie unpack.
 504 
 505   Return Value: Error Message
 506 
 507 *****************************************************************************/
 508 L3INT Q931Uie_CallState(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
 509 {
 510         Q931ie_CallState *pie = (Q931ie_CallState*)OBuf;
 511         ie *pIE = &pMsg->CallState;
 512         L3INT Off = 0;
 513         L3INT Octet = 0;
 514         L3INT IESize;
 515 
 516         *pIE = 0;
 517 
 518         /* Octet 1 */
 519         pie->IEId = IBuf[Octet++];
 520 
 521         /* Octet 2 */
 522         IESize = IBuf[Octet++];
 523 
 524         /* Octet 3 */
 525         pie->CodStand  = (IBuf[Octet + Off] >> 6) & 0x03;
 526         pie->CallState =  IBuf[Octet + Off] & 0x3f;
 527         Octet++;
 528 
 529         Q931IESizeTest(Q931E_CALLSTATE);
 530         Q931SetIE(*pIE, *OOff);
 531 
 532         *IOff = (*IOff) + Octet + Off;
 533         *OOff = (*OOff) + sizeof(Q931ie_CallState);
 534         pie->Size = sizeof(Q931ie_CallState);
 535 
 536         return Q931E_NO_ERROR;
 537 }
 538 
 539 /*****************************************************************************
 540 
 541   Function:      Q931Pie_CallState
 542 
 543   Parameters:   IBuf[IN]                Ptr to struct.
 544                                 OBuf[OUT]               Ptr tp packed output buffer.
 545                                 Octet[IN/OUT]   Offset into OBuf.
 546 
 547   Return Value: Error code, 0 = OK
 548 
 549 *****************************************************************************/
 550 L3INT Q931Pie_CallState(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
 551 {
 552         Q931ie_CallState *pIE = (Q931ie_CallState*)IBuf;
 553         L3INT rc = 0;
 554         L3INT Beg = *Octet; /* remember current offset */
 555         L3INT li;
 556 
 557         OBuf[(*Octet)++] = Q931ie_CALL_STATE;
 558         li = (*Octet)++; /* remember length position */
 559 
 560         OBuf[(*Octet)++] = (pIE->CodStand << 6) | (pIE->CallState & 0x3f);
 561 
 562         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
 563         return rc;
 564 }
 565 
 566 /*****************************************************************************
 567 
 568   Function:      Q931Uie_CalledSub
 569 
 570   Parameters:   pIE[OUT]                ptr to Information Element id.
 571                                 IBuf[IN]                ptr to a packed ie.
 572                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
 573                                 IOff[IN\OUT]    Input buffer offset
 574                                 OOff[IN\OUT]    Output buffer offset
 575 
 576                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
 577                                 must be updated, but are otherwise not used in the ie unpack.
 578 
 579   Return Value: Error Message
 580 
 581 *****************************************************************************/
 582 L3INT Q931Uie_CalledSub(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
 583 {
 584         Q931ie_CalledSub *pie = (Q931ie_CalledSub*)OBuf;
 585         ie *pIE = &pMsg->CalledSub;
 586         L3INT Off = 0;
 587         L3INT Octet = 0;
 588         L3INT x;
 589         L3INT IESize;
 590 
 591         *pIE = 0;
 592 
 593         /* Octet 1 */
 594         pie->IEId = IBuf[Octet++];
 595 
 596         /* Octet 2 */
 597         IESize = IBuf[Octet++]; 
 598 
 599         /* Octet 3 */
 600         pie->TypNum     = (IBuf[Octet + Off] >> 4) & 0x07;
 601         pie->OddEvenInd = (IBuf[Octet + Off] >> 3) & 0x01;
 602         Octet++;
 603         
 604         /* Octet 4 */
 605         x = 0;
 606         do {
 607                 pie->Digit[x] = IBuf[Octet + Off] & 0x7f;
 608                 Off++;
 609                 x++;
 610         } while (Q931MoreIE() && x < 20);
 611 
 612         Q931IESizeTest(Q931E_CALLEDSUB);
 613         Q931SetIE(*pIE, *OOff);
 614 
 615         *IOff = (*IOff) + Octet + Off;
 616         *OOff = (*OOff) + sizeof(Q931ie_CalledSub) + x - 1;
 617         pie->Size = (L3UCHAR)(sizeof(Q931ie_CalledSub) + x - 1);
 618 
 619         return Q931E_NO_ERROR;
 620 }
 621 
 622 /*****************************************************************************
 623 
 624   Function:      Q931Pie_CalledSub
 625 
 626   Parameters:   IBuf[IN]                Ptr to struct.
 627                                 OBuf[OUT]               Ptr tp packed output buffer.
 628                                 Octet[IN/OUT]   Offset into OBuf.
 629 
 630   Return Value: Error code, 0 = OK
 631 
 632 *****************************************************************************/
 633 L3INT Q931Pie_CalledSub(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
 634 {
 635         Q931ie_CalledSub *pIE = (Q931ie_CalledSub*)IBuf;
 636         L3INT rc = 0;
 637         L3INT Beg = *Octet;
 638         L3INT li;
 639         L3INT sN = pIE->Size - sizeof(Q931ie_CalledSub) + 1;
 640         L3INT x;
 641 
 642         /* Octet 1 */
 643         OBuf[(*Octet)++] = Q931ie_CALLED_PARTY_SUBADDRESS;
 644         li = (*Octet)++;
 645 
 646         /* Octet 3 */
 647         OBuf[(*Octet)++] = 0x80 | (pIE->TypNum << 4) | (pIE->OddEvenInd << 3);
 648         
 649         /* Octet 4 */
 650         for (x = 0; x<sN; x++) {
 651                 OBuf[(*Octet)++] = pIE->Digit[x];
 652         }
 653 
 654         OBuf[(*Octet) - 1] |= 0x80; /* Terminate bit */
 655 
 656         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
 657         return rc;
 658 }
 659 
 660 /*****************************************************************************
 661 
 662   Function:      Q931Uie_CalledNum
 663 
 664   Parameters:   pIE[OUT]                ptr to Information Element id.
 665                                 IBuf[IN]                ptr to a packed ie.
 666                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
 667                                 IOff[IN\OUT]    Input buffer offset
 668                                 OOff[IN\OUT]    Output buffer offset
 669 
 670                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
 671                                 must be updated, but are otherwise not used in the ie unpack.
 672 
 673   Return Value: Error Message
 674 
 675 *****************************************************************************/
 676 L3INT Q931Uie_CalledNum(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
 677 {
 678         Q931ie_CalledNum *pie = (Q931ie_CalledNum*)OBuf;
 679         ie *pIE = &pMsg->CalledNum;
 680         L3INT Off = 0;
 681         L3INT Octet = 0;
 682         L3INT x;
 683         L3INT IESize; /* # digits in this case */
 684 
 685         *pIE = 0;
 686 
 687         /* Octet 1 */
 688         pie->IEId = IBuf[Octet++];
 689 
 690         /* Octet 2 */
 691         IESize = IBuf[Octet++]; 
 692 
 693         /* Octet 3 */
 694         pie->TypNum    = (IBuf[Octet + Off] >> 4) & 0x07;
 695         pie->NumPlanID =  IBuf[Octet + Off] & 0x0f;
 696         Octet++;
 697 
 698         /* Octet 4*/
 699         x = 0;
 700         do {
 701                 pie->Digit[x] = IBuf[Octet + Off] & 0x7f;
 702                 Off++;
 703                 x++;
 704         } while ((IBuf[Octet + Off]&0x80) == 0 && Q931MoreIE());
 705 
 706         pie->Digit[x] = '\0';
 707 
 708         Q931SetIE(*pIE, *OOff);
 709 
 710         *IOff = (*IOff) + Octet + Off;
 711         *OOff = (*OOff) + sizeof(Q931ie_CalledNum) + x;
 712         pie->Size = (L3UCHAR)(sizeof(Q931ie_CalledNum) + x);
 713 
 714         return Q931E_NO_ERROR;
 715 }
 716 
 717 /*****************************************************************************
 718 
 719   Function:      Q931Pie_CalledNum
 720 
 721   Parameters:   IBuf[IN]                Ptr to struct.
 722                                 OBuf[OUT]               Ptr tp packed output buffer.
 723                                 Octet[IN/OUT]   Offset into OBuf.
 724 
 725   Return Value: Error code, 0 = OK
 726 
 727 *****************************************************************************/
 728 L3INT Q931Pie_CalledNum(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
 729 {
 730         Q931ie_CalledNum *pIE = (Q931ie_CalledNum*)IBuf;
 731         L3INT rc = 0;
 732         L3INT Beg = *Octet;
 733         L3INT li;
 734         L3INT sN = pIE->Size - sizeof(Q931ie_CalledNum);
 735         L3INT x;
 736 
 737         /* Octet 1 */
 738         OBuf[(*Octet)++] = Q931ie_CALLED_PARTY_NUMBER;
 739         
 740         /* Octet 2 */
 741         li = (*Octet)++;
 742 
 743         /* Octet 3 */
 744         OBuf[(*Octet)++] = 0x80 | (pIE->TypNum << 4) | (pIE->NumPlanID);
 745         
 746         /* Octet 4 */
 747         for (x = 0; x<sN; x++) {
 748                 OBuf[(*Octet)++] = pIE->Digit[x];
 749         }
 750 
 751         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
 752         return rc;
 753 }
 754 
 755 /*****************************************************************************
 756 
 757   Function:      Q931Uie_CallingNum
 758 
 759   Parameters:   pIE[OUT]                ptr to Information Element id.
 760                                 IBuf[IN]                ptr to a packed ie.
 761                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
 762                                 IOff[IN\OUT]    Input buffer offset
 763                                 OOff[IN\OUT]    Output buffer offset
 764 
 765                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
 766                                 must be updated, but are otherwise not used in the ie unpack.
 767 
 768   Return Value: Error Message
 769 
 770 *****************************************************************************/
 771 L3INT Q931Uie_CallingNum(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
 772 {
 773         Q931ie_CallingNum *pie = (Q931ie_CallingNum*)OBuf;
 774         ie *pIE = &pMsg->CallingNum;
 775         L3INT Off = 0;
 776         L3INT Octet = 0;
 777         L3INT x;
 778         L3INT IESize;
 779 
 780         *pIE = 0;
 781 
 782         /* Octet 1 */
 783         pie->IEId = IBuf[Octet++];
 784 
 785         /* Octet 2 */
 786         IESize = IBuf[Octet++]; 
 787 
 788         /* Octet 3 */
 789         pie->TypNum    = (IBuf[Octet + Off] >> 4) & 0x07;
 790         pie->NumPlanID =  IBuf[Octet + Off] & 0x0f;
 791 
 792         /* Octet 3a */
 793         if ((IBuf[Octet + Off] & 0x80) == 0) {
 794                 Off++;
 795                 pie->PresInd   = (IBuf[Octet + Off] >> 5) & 0x03;
 796                 pie->ScreenInd =  IBuf[Octet + Off] & 0x03;
 797         }
 798         Octet++;
 799 
 800         /* Octet 4 */
 801         x = 0;
 802         while (Q931MoreIE()) {
 803                 pie->Digit[x++] = IBuf[Octet + Off] & 0x7f;
 804 
 805                 if ((IBuf[Octet + Off] & 0x80) != 0) {
 806                         break;
 807                 }
 808                 Off++;
 809         }
 810         pie->Digit[x] = '\0';
 811 
 812         Q931IESizeTest(Q931E_CALLINGNUM);
 813         Q931SetIE(*pIE, *OOff);
 814 
 815         *IOff = (*IOff) + Octet + Off;
 816         *OOff = (*OOff) + sizeof(Q931ie_CallingNum) + x;
 817         pie->Size = (L3UCHAR)(sizeof(Q931ie_CallingNum) + x);
 818 
 819         return Q931E_NO_ERROR;
 820 }
 821 
 822 /*****************************************************************************
 823 
 824   Function:      Q931Pie_CallingNum
 825 
 826   Parameters:   IBuf[IN]                Ptr to struct.
 827                                 OBuf[OUT]               Ptr tp packed output buffer.
 828                                 Octet[IN/OUT]   Offset into OBuf.
 829 
 830   Return Value: Error code, 0 = OK
 831 
 832 *****************************************************************************/
 833 L3INT Q931Pie_CallingNum(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
 834 {
 835         Q931ie_CallingNum *pIE = (Q931ie_CallingNum*)IBuf;
 836         L3INT rc = 0;
 837         L3INT Beg = *Octet;
 838         L3INT li;
 839         L3INT sN = pIE->Size - sizeof(Q931ie_CallingNum);
 840         L3INT x;
 841 
 842         /* Octet 1 */
 843         OBuf[(*Octet)++] = Q931ie_CALLING_PARTY_NUMBER;
 844         
 845         /* Octet 2 */
 846         li = (*Octet)++;
 847 
 848         /* Octet 3 */
 849         OBuf[(*Octet)++] = 0x00 | (pIE->TypNum << 4) | (pIE->NumPlanID);
 850         
 851         /* Octet 4 */
 852         OBuf[(*Octet)++] = 0x80;
 853 
 854         /* Octet 5 */
 855         for (x = 0; x<sN; x++) {
 856                 OBuf[(*Octet)++] = pIE->Digit[x];
 857         }
 858 
 859         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
 860         return rc;
 861 }
 862 
 863 /*****************************************************************************
 864 
 865   Function:      Q931Uie_CallingSub
 866 
 867   Parameters:   pIE[OUT]                ptr to Information Element id.
 868                                 IBuf[IN]                ptr to a packed ie.
 869                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
 870                                 IOff[IN\OUT]    Input buffer offset
 871                                 OOff[IN\OUT]    Output buffer offset
 872 
 873                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
 874                                 must be updated, but are otherwise not used in the ie unpack.
 875 
 876   Return Value: Error Message
 877 
 878 *****************************************************************************/
 879 L3INT Q931Uie_CallingSub(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
 880 {
 881         Q931ie_CallingSub *pie = (Q931ie_CallingSub*)OBuf;
 882         ie *pIE = &pMsg->CallingSub;
 883         L3INT Off = 0;
 884         L3INT Octet = 0;
 885         L3INT x;
 886         L3INT IESize;
 887 
 888         *pIE = 0;
 889 
 890         /* Octet 1 */
 891         pie->IEId = IBuf[Octet++];
 892 
 893         /* Octet 2 */
 894         IESize = IBuf[Octet++]; 
 895 
 896         /* Octet 3 */
 897         pie->TypNum     = (IBuf[Octet + Off] >> 4) & 0x07;
 898         pie->OddEvenInd = (IBuf[Octet + Off] >> 3) & 0x01;
 899         Octet++;
 900         
 901         /* Octet 4*/
 902         x = 0;
 903         do {
 904                 pie->Digit[x] = IBuf[Octet + Off] & 0x7f;
 905                 Off++;
 906                 x++;
 907         } while (Q931MoreIE() && x < 20);
 908 
 909         Q931IESizeTest(Q931E_CALLINGSUB);
 910         Q931SetIE(*pIE, *OOff);
 911 
 912         *IOff = (*IOff) + Octet + Off;
 913         *OOff = (*OOff) + sizeof(Q931ie_CallingSub) + x -1;
 914         pie->Size = (L3UCHAR)(sizeof(Q931ie_CallingSub) + x -1);
 915 
 916         return Q931E_NO_ERROR;
 917 }
 918 
 919 /*****************************************************************************
 920 
 921   Function:      Q931Pie_CallingSub
 922 
 923   Parameters:   IBuf[IN]                Ptr to struct.
 924                                 OBuf[OUT]               Ptr tp packed output buffer.
 925                                 Octet[IN/OUT]   Offset into OBuf.
 926 
 927   Return Value: Error code, 0 = OK
 928 
 929 *****************************************************************************/
 930 L3INT Q931Pie_CallingSub(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
 931 {
 932         Q931ie_CallingSub *pIE = (Q931ie_CallingSub*)IBuf;
 933         L3INT rc = 0;
 934         L3INT Beg = *Octet;
 935         L3INT li;
 936         L3INT sN = pIE->Size - sizeof(Q931ie_CallingSub) + 1;
 937         L3INT x;
 938 
 939         /* Octet 1 */
 940         OBuf[(*Octet)++] = Q931ie_CALLING_PARTY_SUBADDRESS;
 941         li = (*Octet)++;
 942 
 943         /* Octet 3 */
 944         OBuf[(*Octet)++] = 0x80 | (pIE->TypNum << 4) | (pIE->OddEvenInd << 3);
 945         
 946         /* Octet 4 */
 947         for (x = 0; x<sN; x++) {
 948                 OBuf[(*Octet)++] = pIE->Digit[x];
 949         }
 950 
 951         OBuf[(*Octet) - 1] |= 0x80; /* Terminate bit */
 952 
 953         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
 954         return rc;
 955 }
 956 
 957 /*****************************************************************************
 958 
 959   Function:             Q931Uie_Cause
 960   
 961   Parameters:   pIE[OUT]                ptr to Information Element id.
 962                                 IBuf[IN]                ptr to a packed ie.
 963                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
 964                                 IOff[IN\OUT]    Input buffer offset
 965                                 OOff[IN\OUT]    Output buffer offset
 966 
 967                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
 968                                 must be updated, but are otherwise not used in the ie unpack.
 969 
 970   Return Value: Error Message
 971 
 972 *****************************************************************************/
 973 L3INT Q931Uie_Cause(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) 
 974 {
 975         Q931ie_Cause *pie = (Q931ie_Cause*)OBuf;
 976         ie *pIE = &pMsg->Cause;
 977         L3INT Off = 0;
 978         L3INT Octet = 0;
 979         L3INT IESize;
 980 
 981         *pIE = 0;
 982 
 983         pie->IEId = IBuf[Octet++];
 984 
 985         /* Octet 2*/
 986         IESize = IBuf[Octet++]; 
 987 
 988         /* Octet 3*/
 989         pie->CodStand = (IBuf[Octet + Off]>>5) & 0x03;
 990         pie->Location =  IBuf[Octet + Off] & 0x0f;
 991 
 992         /* Octet 3a */
 993         if ((IBuf[Octet + Off] & 0x80) == 0) {
 994                 Off++;
 995                 pie->Recom = IBuf[Octet + Off] & 0x7f;
 996         }
 997         Octet++;
 998 
 999         /* Octet 4 */
1000         pie->Value = IBuf[Octet + Off] & 0x7f;
1001         Octet++;
1002 
1003         /* Consume optional Diagnostic bytes */
1004         while (Q931MoreIE()) {
1005                 Off++;
1006         };
1007 
1008         Q931IESizeTest(Q931E_CAUSE);
1009         Q931SetIE(*pIE, *OOff);
1010 
1011         *IOff = (*IOff) + Octet + Off;
1012         *OOff = (*OOff) + sizeof(Q931ie_Cause);
1013         pie->Size = sizeof(Q931ie_Cause);
1014 
1015         return Q931E_NO_ERROR;
1016 }
1017 
1018 /*****************************************************************************
1019 
1020   Function:             Q931Pie_Cause
1021 
1022   Parameters:   IBuf[IN]                Ptr to struct.
1023                                 OBuf[OUT]               Ptr tp packed output buffer.
1024                                 Octet[IN/OUT]   Offset into OBuf.
1025 
1026   Return Value: Error code, 0 = OK
1027 
1028 *****************************************************************************/
1029 L3INT Q931Pie_Cause(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
1030 {
1031         Q931ie_Cause *pIE = (Q931ie_Cause*)IBuf;
1032         L3INT rc = 0;
1033         L3INT Beg = *Octet;
1034         L3INT li;
1035 
1036         OBuf[(*Octet)++] = Q931ie_CAUSE;
1037         li = (*Octet)++;
1038 
1039         /* Octet 3 */
1040         OBuf[(*Octet)++] = 0x80 | (pIE->CodStand<<5) | pIE->Location;
1041 
1042         /* Octet 3a - currently not supported in send */
1043 
1044         /* Octet 4 */
1045         OBuf[(*Octet)++] = 0x80 | pIE->Value;
1046 
1047         /* Octet 5 - diagnostics not supported in send */
1048 
1049         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
1050         return rc;
1051 }
1052 
1053 /*****************************************************************************
1054 
1055   Function:      Q931Uie_CongLevel
1056   
1057   Parameters:   pIE[OUT]                ptr to Information Element id.
1058                                 IBuf[IN]                ptr to a packed ie.
1059                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
1060                                 IOff[IN\OUT]    Input buffer offset
1061                                 OOff[IN\OUT]    Output buffer offset
1062 
1063                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
1064                                 must be updated, but are otherwise not used in the ie unpack.
1065 
1066   Return Value: Error Message
1067 
1068 *****************************************************************************/
1069 L3INT Q931Uie_CongLevel(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) 
1070 {
1071         Q931ie_CongLevel *pie = (Q931ie_CongLevel*)OBuf;
1072         ie *pIE = &pMsg->CongestionLevel;
1073         L3INT Off = 0;
1074         L3INT Octet = 0;
1075 
1076         *pIE = 0;
1077 
1078         pie->IEId      = IBuf[Octet] & 0xf0;
1079         pie->CongLevel = IBuf[Octet] & 0x0f;
1080         Octet ++;
1081 
1082         Q931SetIE(*pIE, *OOff);
1083 
1084         *IOff = (*IOff) + Octet + Off;
1085         *OOff = (*OOff) + sizeof(Q931ie_CongLevel);
1086         pie->Size = sizeof(Q931ie_CongLevel);
1087 
1088         return Q931E_NO_ERROR;
1089 }
1090 
1091 /*****************************************************************************
1092 
1093   Function:      Q931Pie_CongLevel
1094 
1095   Parameters:   IBuf[IN]                Ptr to struct.
1096                                 OBuf[OUT]               Ptr tp packed output buffer.
1097                                 Octet[IN/OUT]   Offset into OBuf.
1098 
1099   Return Value: Error code, 0 = OK
1100 
1101 *****************************************************************************/
1102 L3INT Q931Pie_CongLevel(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
1103 {
1104         Q931ie_CongLevel *pIE = (Q931ie_CongLevel*)IBuf;
1105         L3INT rc = 0;
1106         /* L3INT Beg = *Octet; */
1107 
1108         OBuf[(*Octet)++] = Q931ie_CONGESTION_LEVEL | pIE->CongLevel;
1109 
1110         return rc;
1111 }
1112 
1113 /*****************************************************************************
1114 
1115   Function:      Q931Uie_ChanID
1116 
1117   Parameters:   IBuf[IN]                ptr to a packed ie.
1118                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
1119                                 IOff[IN\OUT]    Input buffer offset
1120                                 OOff[IN\OUT]    Output buffer offset
1121 
1122                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
1123                                 must be updated, but are otherwise not used in the ie unpack.
1124 
1125   Return Value: Error code, 0 = OK
1126 
1127 *****************************************************************************/
1128 L3INT Q931Uie_ChanID(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR *OBuf, L3INT *IOff, L3INT *OOff)
1129 {
1130         Q931ie_ChanID *pie = (Q931ie_ChanID*)OBuf;
1131         ie *pIE = &pMsg->ChanID;
1132         L3INT Off = 0;
1133         L3INT Octet = 0;
1134         L3INT IESize;
1135 //18 04 e1 80 83 01
1136         *pIE = 0;
1137 
1138         Q931Log(pTrunk, Q931_LOG_DEBUG, "Decoding ChanID IE\n");
1139 
1140         /* Octet 1 */
1141         pie->IEId = IBuf[Octet++];
1142 
1143         /* Octet 2 */
1144         IESize    = IBuf[Octet++]; 
1145 
1146         /* Octet 3 */
1147         pie->IntIDPresent = (IBuf[Octet] >> 6) & 0x01;
1148         pie->IntType      = (IBuf[Octet] >> 5) & 0x01;
1149         pie->PrefExcl     = (IBuf[Octet] >> 3) & 0x01;
1150         pie->DChanInd     = (IBuf[Octet] >> 2) & 0x01;
1151         pie->InfoChanSel  =  IBuf[Octet] & 0x03;
1152 
1153         Off = Q931ReadExt(&IBuf[Octet++], Off);
1154 
1155         /* Octet 3.1 */
1156         if (pie->IntIDPresent) {
1157                 pie->InterfaceID = IBuf[Octet + Off] & 0x7f;
1158 
1159                 /* Temp fix. Interface id can be extended using the extension bit */
1160                 /* this will read the octets, but do nothing with them. this is done */
1161                 /* because the usage of this field is a little unclear */
1162                 /* 30.jan.2001/JVB */
1163                 Off = Q931ReadExt(&IBuf[Octet + Off], Off);
1164                 Off++;
1165         }
1166 
1167         if ((Octet + Off - 2) != IESize) {
1168                 /* Octet 3.2 */
1169                 if (pie->IntType == 1) {        /* PRI etc */
1170                         pie->CodStand    = (IBuf[Octet + Off] >> 5) & 0x03;
1171                         pie->NumMap      = (IBuf[Octet + Off] >> 4) & 0x01;
1172                         pie->ChanMapType =  IBuf[Octet + Off] & 0x0f;
1173                         Off++;
1174 
1175                         /* Octet 3.3 */
1176                         /* Temp fix. Assume B channel. H channels not supported */
1177                         pie->ChanSlot = IBuf[Octet + Off] & 0x7f;
1178 
1179                         /* Some dialects don't follow the extension coding properly for this, but this should be safe for all */
1180                         if ((Octet + Off - 1) != IESize) {
1181                                 Off = Q931ReadExt(&IBuf[Octet + Off], Off);
1182                         }
1183                         Off++;
1184                 }
1185         }
1186 
1187         Q931IESizeTest(Q931E_CHANID);
1188         Q931SetIE(*pIE, *OOff);
1189 
1190         *IOff = (*IOff) + Octet + Off;
1191         *OOff = (*OOff) + sizeof(Q931ie_ChanID);
1192         pie->Size = sizeof(Q931ie_ChanID);
1193 
1194         if (pTrunk->loglevel == Q931_LOG_DEBUG) {
1195                 const char *iface;
1196                 char tmp[100] = "";
1197 
1198                 if (!pie->IntType) {
1199                         switch (pie->InfoChanSel) {
1200                         case 0x0:
1201                                 iface = "None";
1202                                 break;
1203                         case 0x1:
1204                                 iface = "B1";
1205                                 break;
1206                         case 0x2:
1207                                 iface = "B2";
1208                                 break;
1209                         default:
1210                                 iface = "Any Channel";
1211                         }
1212 
1213                         snprintf(tmp, sizeof(tmp)-1, "InfoChanSel: %d (%s)", pie->InfoChanSel, iface);
1214                 }
1215 
1216                 Q931Log(pTrunk, Q931_LOG_DEBUG,
1217                         "\n-------------------------- Q.931 Channel ID ------------------------\n"
1218                         "    Pref/Excl: %s, Interface Type: %s\n"
1219                         "    %s\n"
1220                         "--------------------------------------------------------------------\n\n",
1221                         ((pie->PrefExcl) ? "Preferred" : "Exclusive"),
1222                         ((pie->IntType) ? "PRI/Other" : "BRI"),
1223                         tmp);
1224         }
1225         return Q931E_NO_ERROR;
1226 }
1227 
1228 /*****************************************************************************
1229 
1230   Function:      Q931Pie_ChanID
1231 
1232   Parameters:   IBuf[IN]                Ptr to struct.
1233                                 OBuf[OUT]               Ptr tp packed output buffer.
1234                                 Octet[IN/OUT]   Offset into OBuf.
1235 
1236   Return Value: Error code, 0 = OK
1237 
1238 *****************************************************************************/
1239 L3INT Q931Pie_ChanID(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
1240 {
1241         Q931ie_ChanID *pIE = (Q931ie_ChanID*)IBuf;
1242         L3INT rc = Q931E_NO_ERROR;
1243         L3INT Beg = *Octet;     /* remember current offset */
1244         L3INT li;
1245 
1246         OBuf[(*Octet)++] = Q931ie_CHANNEL_IDENTIFICATION;
1247         li = (*Octet)++; /* remember length position */
1248 
1249         /* Octet 3 flags & BRI chan # */
1250         OBuf[(*Octet)++] = 0x80 
1251                         | ((pIE->IntIDPresent << 6) & 0x40)
1252                         | ((pIE->IntType << 5) & 0x20)
1253                         | ((pIE->PrefExcl << 3) & 0x08)
1254                         |  (pIE->InfoChanSel & 0x03);
1255 
1256         /* Octet 3.1 - Interface Identifier */
1257         if (pIE->IntIDPresent) {
1258                 OBuf[(*Octet)++] = 0x80 | (pIE->InterfaceID & 0x7f);
1259         }
1260 
1261         /* Octet 3.2 & 3.3 - PRI */
1262         if (pIE->IntType) {
1263                 OBuf[(*Octet)++]  = 0x80
1264                         | ((pIE->CodStand << 5) & 0x60)
1265                         | ((pIE->NumMap << 4) & 0x10)
1266                         |  (pIE->ChanMapType & 0x0f);           /* TODO: support all possible channel map types */
1267 
1268                 /* Octet 3.3 Channel number */
1269                 switch (pIE->ChanMapType) {
1270                 case 0x6:       /* Slot map: H0 Channel Units */        /* unsupported, Octets 3.3.1 - 3.3.3 */
1271                         return Q931E_CHANID;
1272 
1273                 case 0x8:       /* Slot map: H11 Channel Units */
1274                 case 0x9:       /* Slot map: H12 Channel Units */
1275                 default:        /* Channel number */
1276                         OBuf[(*Octet)++] = 0x80 | (pIE->ChanSlot & 0x7f);
1277                         break;
1278                 }
1279         }
1280 
1281         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
1282         return rc;
1283 }
1284 
1285 
1286 /*****************************************************************************
1287 
1288   Function:      Q931Uie_CRV
1289 
1290   Description:  Reading CRV. 
1291 
1292                                 The CRV is currently returned in the return value that 
1293                                 Q921Rx23 will assign to the CRV field in the unpacked
1294                                 message. CRV is basically 2 bytes etc, but the spec allows
1295                                 the use of longer CRV values.
1296   
1297   Parameters:   pIE[OUT]                ptr to Information Element id.
1298                                 IBuf[IN]                ptr to a packed ie.
1299                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
1300                                 IOff[IN\OUT]    Input buffer offset
1301                                 OOff[IN\OUT]    Output buffer offset
1302 
1303                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
1304                                 must be updated, but are otherwise not used in the ie unpack.
1305 
1306   Return Value: CRV
1307 
1308 *****************************************************************************/
1309 L3USHORT Q931Uie_CRV(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *IOff, L3INT *OOff)
1310 {
1311         L3USHORT CRV = 0;
1312         L3INT Octet = *IOff;
1313         L3INT l = IBuf[Octet++]; 
1314 
1315         if (l == 1) {   /* One octet CRV */
1316                 CRV = IBuf[Octet++] & 0x7F;
1317         }
1318         else if (l == 2) {      /* two octet CRV */
1319                 CRV  = (IBuf[Octet++] & 0x7f) << 8;
1320                 CRV |=  IBuf[Octet++];
1321         }
1322         else {
1323                 /* Long CRV is not used, so we skip this */
1324                 /* TODO: is it right to set to 0 here? */
1325                 CRV = 0;
1326                 Octet += l;
1327         }
1328 
1329         *IOff = Octet;
1330         return CRV;
1331 }
1332 
1333 /*****************************************************************************
1334 
1335   Function:      Q931Uie_DateTime
1336 
1337   Parameters:   pTrunk          [IN]            Ptr to trunk information.
1338                                 pIE                     [OUT]       ptr to Information Element id.
1339                                 IBuf            [IN]            ptr to a packed ie.
1340                                 OBuf            [OUT]      ptr to buffer for Unpacked ie.
1341                                 IOff            [IN\OUT]        Input buffer offset
1342                                 OOff            [IN\OUT]        Output buffer offset
1343 
1344                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
1345                                 must be updated, but are otherwise not used in the ie unpack.
1346 
1347   Return Value: Error Message
1348 
1349 *****************************************************************************/
1350 L3INT Q931Uie_DateTime(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *IOff, L3INT *OOff)
1351 {
1352         Q931ie_DateTime * pie = (Q931ie_DateTime*)OBuf;
1353         ie *pIE = &pMsg->DateTime;
1354         L3INT Off = 0;
1355         L3INT Octet = 0;
1356         L3INT IESize = 0;
1357 
1358         *pIE = 0;
1359 
1360         pie->IEId = IBuf[Octet++];
1361         
1362         /* Octet 2 */
1363         IESize = IBuf[Octet++]; 
1364 
1365         /* Octet 3 - Year */
1366         pie->Year = IBuf[Octet++];
1367 
1368         /* Octet 4 - Month */
1369         pie->Month = IBuf[Octet++];
1370 
1371         /* Octet 5 - Day */
1372         pie->Day = IBuf[Octet++];
1373 
1374         /*******************************************************************
1375                 The remaining part of the IE are optioinal, but only the length 
1376                 can now tell us wherever these fields are present or not
1377                 (always remember: IESize does not include ID and Size octet)
1378         ********************************************************************/
1379         pie->Format = 0;
1380 
1381         /* Octet 6 - Hour (optional)*/
1382         if (IESize >= 4) {
1383                 pie->Format = 1;
1384                 pie->Hour = IBuf[Octet++];
1385 
1386                 /* Octet 7 - Minute (optional)*/
1387                 if (IESize >= 5) {
1388                         pie->Format = 2;
1389                         pie->Minute = IBuf[Octet++];
1390 
1391                         /* Octet 8 - Second (optional)*/
1392                         if (IESize >= 6) {
1393                                 pie->Format = 3;
1394                                 pie->Second = IBuf[Octet++];
1395                         }
1396                 }
1397         }
1398 
1399         Q931IESizeTest(Q931E_DATETIME);
1400         Q931SetIE(*pIE, *OOff);
1401 
1402         *IOff = (*IOff) + Octet + Off;
1403         *OOff = (*OOff) + sizeof(Q931ie_DateTime);
1404         pie->Size = sizeof(Q931ie_DateTime);
1405 
1406         return Q931E_NO_ERROR;
1407 }
1408 
1409 /*****************************************************************************
1410 
1411   Function:      Q931Pie_DateTime
1412 
1413   Parameters:   IBuf[IN]                Ptr to struct.
1414                                 OBuf[OUT]               Ptr tp packed output buffer.
1415                                 Octet[IN/OUT]   Offset into OBuf.
1416 
1417   Return Value: Error code, 0 = OK
1418 
1419 *****************************************************************************/
1420 L3INT Q931Pie_DateTime(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
1421 {
1422         Q931ie_DateTime *pIE = (Q931ie_DateTime*)IBuf;
1423         L3INT rc = 0;
1424         L3INT Beg = *Octet;
1425         L3INT li;
1426 
1427         OBuf[(*Octet)++] = Q931ie_DATETIME;
1428         li = (*Octet)++;
1429 
1430         OBuf[(*Octet)++] = pIE->Year;
1431         OBuf[(*Octet)++] = pIE->Month;
1432         OBuf[(*Octet)++] = pIE->Day;
1433         if (pIE->Format >= 1) {
1434                 OBuf[(*Octet)++] = pIE->Hour;
1435 
1436                 if (pIE->Format >= 2) {
1437                         OBuf[(*Octet)++] = pIE->Minute;
1438 
1439                         if (pIE->Format >= 3) {
1440                                 OBuf[(*Octet)++] = pIE->Second;
1441                         }
1442                 }
1443         }
1444 
1445         OBuf[li] = (L3UCHAR)((*Octet)-Beg) - 2;
1446         return rc;
1447 }
1448 
1449 /*****************************************************************************
1450 
1451   Function:      Q931Uie_Display
1452 
1453   Parameters:   pIE[OUT]                ptr to Information Element id.
1454                                 IBuf[IN]                ptr to a packed ie.
1455                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
1456                                 IOff[IN\OUT]    Input buffer offset
1457                                 OOff[IN\OUT]    Output buffer offset
1458 
1459                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
1460                                 must be updated, but are otherwise not used in the ie unpack.
1461 
1462   Return Value: Error Message
1463 
1464 *****************************************************************************/
1465 L3INT Q931Uie_Display(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
1466 {
1467         Q931ie_Display *pie = (Q931ie_Display*)OBuf;
1468         ie *pIE = &pMsg->Display;
1469         L3INT Off = 0;
1470         L3INT Octet = 0;
1471         L3INT IESize;
1472         L3INT x;
1473 
1474         *pIE = 0;
1475 
1476         pie->IEId = IBuf[Octet++];
1477         IESize    = IBuf[Octet++]; 
1478 
1479         for (x = 0; x<IESize; x++) {
1480                 pie->Display[x] = IBuf[Octet + Off] & 0x7f;
1481                 Off++;
1482         }
1483 
1484         Q931IESizeTest(Q931E_DISPLAY);
1485         Q931SetIE(*pIE, *OOff);
1486 
1487         *IOff = (*IOff) + Octet + Off;
1488         *OOff = (*OOff) + sizeof(Q931ie_Display) + x - 1;
1489         pie->Size = (L3UCHAR)(sizeof(Q931ie_Display) + x - 1);
1490 
1491         return Q931E_NO_ERROR;
1492 }
1493 
1494 /*****************************************************************************
1495 
1496   Function:      Q931Pie_Display
1497 
1498   Parameters:   IBuf[IN]                Ptr to struct.
1499                                 OBuf[OUT]               Ptr tp packed output buffer.
1500                                 Octet[IN/OUT]   Offset into OBuf.
1501 
1502   Return Value: Error code, 0 = OK
1503 
1504 *****************************************************************************/
1505 L3INT Q931Pie_Display(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
1506 {
1507         Q931ie_Display *pIE = (Q931ie_Display*)IBuf;
1508         L3INT rc = 0;
1509         L3INT Beg = *Octet;
1510         L3INT li;
1511         L3INT DSize;
1512         L3INT x;
1513 
1514         OBuf[(*Octet)++] = Q931ie_DISPLAY;
1515         li = (*Octet)++;
1516 
1517         DSize = pIE->Size - sizeof(Q931ie_Display);
1518 
1519         for (x = 0; x< DSize; x++) {
1520                 
1521                 OBuf[(*Octet)++] = pIE->Display[x];
1522         }
1523 
1524         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
1525         return rc;
1526 }
1527 
1528 /*****************************************************************************
1529 
1530   Function:      Q931Uie_HLComp
1531 
1532   Parameters:   pIE[OUT]                ptr to Information Element id.
1533                                 IBuf[IN]                ptr to a packed ie.
1534                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
1535                                 IOff[IN\OUT]    Input buffer offset
1536                                 OOff[IN\OUT]    Output buffer offset
1537 
1538                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
1539                                 must be updated, but are otherwise not used in the ie unpack.
1540 
1541   Return Value: Error Message
1542 
1543 *****************************************************************************/
1544 L3INT Q931Uie_HLComp(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) 
1545 {
1546         Q931ie_HLComp * pie = (Q931ie_HLComp*)OBuf;
1547         ie *pIE = &pMsg->HLComp;
1548         L3INT Off = 0;
1549         L3INT Octet = 0;
1550         L3INT IESize;
1551 
1552         *pIE = 0;
1553 
1554         pie->IEId = IBuf[Octet++];
1555 
1556         /* Octet */
1557         IESize = IBuf[Octet++]; 
1558 
1559         /* Octet 3*/
1560         pie->CodStand  = (IBuf[Octet + Off] >>5) & 0x03;
1561         pie->Interpret = (IBuf[Octet + Off] >>2) & 0x07;
1562         pie->PresMeth  =  IBuf[Octet + Off] & 0x03;
1563         Octet++;
1564 
1565         /* Octet 4 */
1566         pie->HLCharID = IBuf[Octet + Off] & 0x7f;
1567         Octet++;
1568         
1569         /* Octet 4a*/
1570         if ((IBuf[Octet + Off - 1] & 0x80) == 0 && Q931MoreIE()) {
1571                 if (pie->HLCharID == 0x5e || pie->HLCharID == 0x5f) {
1572                         pie->EHLCharID = IBuf[Octet + Off] & 0x7f;
1573                         Off++;
1574                 }
1575                 else if ( pie->HLCharID >= 0xc3 && pie->HLCharID <= 0xcf) {
1576                         pie->EVideoTlfCharID = IBuf[Octet + Off] & 0x7f;
1577                         Off++;
1578                 }
1579                 else {
1580                         /* error Octet 4a indicated, but invalid value in Octet 4. */
1581                         Q931SetError(pTrunk,Q931E_HLCOMP, 4, Off);
1582                         return Q931E_HLCOMP;
1583                 }
1584                 Off = Q931ReadExt(&IBuf[Octet + Off], Off);
1585         }
1586 
1587         Q931IESizeTest(Q931E_HLCOMP);
1588         Q931SetIE(*pIE, *OOff);
1589 
1590         *IOff = (*IOff) + Octet + Off;
1591         *OOff = (*OOff) + sizeof(Q931ie_HLComp);
1592         pie->Size = sizeof(Q931ie_HLComp);
1593 
1594         return Q931E_NO_ERROR;
1595 }
1596 
1597 /*****************************************************************************
1598 
1599   Function:      Q931Pie_HLComp
1600 
1601   Parameters:   IBuf[IN]                Ptr to struct.
1602                                 OBuf[OUT]               Ptr tp packed output buffer.
1603                                 Octet[IN/OUT]   Offset into OBuf.
1604 
1605   Return Value: Error code, 0 = OK
1606 
1607 *****************************************************************************/
1608 L3INT Q931Pie_HLComp(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
1609 {
1610         Q931ie_HLComp *pIE = (Q931ie_HLComp*)IBuf;
1611         L3INT rc = 0;
1612         L3INT Beg = *Octet;
1613         L3INT li;
1614 
1615         OBuf[(*Octet)++] = Q931ie_HIGH_LAYER_COMPATIBILITY;
1616         li = (*Octet)++;
1617 
1618         /* Octet 3 */
1619         OBuf[(*Octet)++] = 0x80 | ((pIE->CodStand << 5) & 0x60) | ((pIE->Interpret << 2) & 0x1c) | (pIE->PresMeth & 0x03);
1620 
1621         /* Octet 4 */
1622         OBuf[(*Octet)++] = pIE->HLCharID;
1623 
1624         /* Octet 4a */
1625         if (pIE->HLCharID == 0x5e || pIE->HLCharID == 0x5f) {
1626                 OBuf[(*Octet)++] = 0x80 | (pIE->EHLCharID & 0x7f);
1627         }
1628         else if ( pIE->HLCharID >= 0xc3 && pIE->HLCharID <= 0xcf) {
1629                 OBuf[(*Octet)++] = 0x80 | (pIE->EVideoTlfCharID & 0x7f);
1630         }
1631         else {
1632                 OBuf[(*Octet) - 1] |= 0x80;
1633         }
1634 
1635         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
1636         return rc;
1637 }
1638 
1639 /*****************************************************************************
1640 
1641   Function:      Q931Uie_KeypadFac
1642 
1643   Parameters:   pIE[OUT]                ptr to Information Element id.
1644                                 IBuf[IN]                ptr to a packed ie.
1645                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
1646                                 IOff[IN\OUT]    Input buffer offset
1647                                 OOff[IN\OUT]    Output buffer offset
1648 
1649                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
1650                                 must be updated, but are otherwise not used in the ie unpack.
1651 
1652   Return Value: Error Message
1653 
1654 *****************************************************************************/
1655 L3INT Q931Uie_KeypadFac(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
1656 {
1657         Q931ie_KeypadFac *pie = (Q931ie_KeypadFac*)OBuf;
1658         ie *pIE = &pMsg->KeypadFac;
1659         L3INT Off = 0;
1660         L3INT Octet = 0;
1661         L3INT IESize;
1662         L3INT x;
1663 
1664         *pIE = 0;
1665 
1666         pie->IEId = IBuf[Octet++];
1667         IESize = IBuf[Octet++]; 
1668 
1669         for (x = 0; x<IESize; x++) {
1670                 pie->KeypadFac[x] = IBuf[Octet + Off] & 0x7f;
1671                 Off++;
1672         }
1673 
1674         Q931IESizeTest(Q931E_KEYPADFAC);
1675         Q931SetIE(*pIE, *OOff);
1676 
1677         *IOff = (*IOff) + Octet + Off;
1678         *OOff = (*OOff) + sizeof(Q931ie_KeypadFac) + x - 1;
1679         pie->Size = (L3UCHAR)(sizeof(Q931ie_KeypadFac) + x - 1);
1680 
1681         return Q931E_NO_ERROR;
1682 }
1683 
1684 /*****************************************************************************
1685 
1686   Function:      Q931Pie_KeypadFac
1687 
1688   Parameters:   IBuf[IN]                Ptr to struct.
1689                                 OBuf[OUT]               Ptr tp packed output buffer.
1690                                 Octet[IN/OUT]   Offset into OBuf.
1691 
1692   Return Value: Error code, 0 = OK
1693 
1694 *****************************************************************************/
1695 L3INT Q931Pie_KeypadFac(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
1696 {
1697         Q931ie_KeypadFac *pIE = (Q931ie_KeypadFac*)IBuf;
1698         L3INT rc = 0;
1699         L3INT Beg = *Octet;
1700         L3INT li;
1701         L3INT DSize;
1702         L3INT x;
1703 
1704         OBuf[(*Octet)++] = Q931ie_KEYPAD_FACILITY;
1705         li = (*Octet)++;
1706 
1707         DSize = pIE->Size - sizeof(Q931ie_KeypadFac) + 1;
1708 
1709         for (x = 0; x< DSize; x++) {
1710                 OBuf[(*Octet)++] = pIE->KeypadFac[x];
1711         }
1712 
1713         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
1714         return rc;
1715 }
1716 
1717 /*****************************************************************************
1718 
1719   Function:      Q931Uie_LLComp
1720 
1721   Parameters:   pIE[OUT]                ptr to Information Element id.
1722                                 IBuf[IN]                ptr to a packed ie.
1723                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
1724                                 IOff[IN\OUT]    Input buffer offset
1725                                 OOff[IN\OUT]    Output buffer offset
1726 
1727                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
1728                                 must be updated, but are otherwise not used in the ie unpack.
1729 
1730   Return Value: Error Message
1731 
1732 *****************************************************************************/
1733 L3INT Q931Uie_LLComp(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
1734 {
1735         Q931ie_LLComp *pie = (Q931ie_LLComp*)OBuf;
1736         ie *pIE = &pMsg->LLComp;
1737         L3INT Off = 0;
1738         L3INT Octet = 0;
1739         L3INT IESize;
1740 
1741         *pIE = 0;
1742 
1743         pie->IEId = IBuf[Octet++];
1744 
1745         /* Octet 2 */
1746         IESize = IBuf[Octet++]; 
1747 
1748         /* Octet 3 */
1749         pie->CodStand  = (IBuf[Octet + Off] >> 5) & 0x03;
1750         pie->ITransCap =  IBuf[Octet + Off] & 0x1f;
1751         Octet++;
1752 
1753         /* Octet 3a*/
1754         if (IsQ931Ext(IBuf[Octet + Off - 1])) {
1755                 pie->NegotInd = (IBuf[Octet + Off] >> 6) & 0x01;
1756                 Off++;
1757         }
1758 
1759         /* Octet 4 */
1760         pie->TransMode = (IBuf[Octet + Off] >> 5) & 0x03;
1761         pie->InfoRate  =  IBuf[Octet + Off] & 0x1f;
1762 
1763         Octet++;
1764 
1765         /* Octet 4.1 */
1766         if (pie->InfoRate == 0x14) { /* Mutirate */
1767                 pie->RateMul = IBuf[Octet + Off] & 0x7f;
1768                 Off++;
1769         }
1770 
1771         /* Octet 5 - Layer 1 Ident */
1772         if ((IBuf[Octet + Off] & 0x60) == 0x20) { /* Layer 1 Ident ? */
1773                 pie->Layer1Ident = (IBuf[Octet + Off] >> 5) & 0x03;
1774                 pie->UIL1Prot    =  IBuf[Octet + Off] & 0x1f;
1775                 Octet++;
1776 
1777                 /* Octet 5a */
1778                 if (IsQ931Ext(IBuf[Octet + Off - 1])) {
1779                         pie->SyncAsync = (IBuf[Octet + Off] >> 6) & 0x01;
1780                         pie->Negot     = (IBuf[Octet + Off] >> 5) & 0x01;
1781                         pie->UserRate  =  IBuf[Octet + Off] & 0x1f;
1782                         Off++;
1783 
1784                         /* Octet 5b - 2 options */
1785                         if (IsQ931Ext(IBuf[Octet + Off - 1])) {
1786                                 if (pie->UIL1Prot == 0x01) { /* V.110, I.460 and X.30*/
1787                                         pie->InterRate = (IBuf[Octet + Off] >> 5) & 0x03;
1788                                         pie->NIConTx   = (IBuf[Octet + Off] >> 4) & 0x01;
1789                                         pie->NIConRx   = (IBuf[Octet + Off] >> 3) & 0x01;
1790                                         pie->FlowCtlTx = (IBuf[Octet + Off] >> 2) & 0x01;
1791                                         pie->FlowCtlRx = (IBuf[Octet + Off] >> 1) & 0x01;
1792                                         Off++;
1793                                 }
1794                                 else if (pie->UIL1Prot == 0x80) { /* V.120 */
1795                                         pie->HDR        = (IBuf[Octet + Off] >> 6) & 0x01;
1796                                         pie->MultiFrame = (IBuf[Octet + Off] >> 5) & 0x01;
1797                                         pie->ModeL1     = (IBuf[Octet + Off] >> 4) & 0x01;
1798                                         pie->NegotLLI   = (IBuf[Octet + Off] >> 3) & 0x01;
1799                                         pie->Assignor   = (IBuf[Octet + Off] >> 2) & 0x01;
1800                                         pie->InBandNeg  = (IBuf[Octet + Off] >> 1) & 0x01;
1801                                         Off++;
1802                                 }
1803                                 else if (pie->UIL1Prot == 0x07) { /* non standard */
1804                                         Off = Q931ReadExt(&IBuf[Octet + Off], Off);
1805                                         Off++;
1806                                 }
1807                                 else {
1808                                         Q931SetError(pTrunk,Q931E_LLCOMP, 5,2);
1809                                         return Q931E_LLCOMP;
1810                                 }
1811 
1812                                 /* Octet 5c */
1813                                 if (IsQ931Ext(IBuf[Octet + Off - 1])) {
1814                                         pie->NumStopBits = (IBuf[Octet + Off] >> 5) & 0x03;
1815                                         pie->NumDataBits = (IBuf[Octet + Off] >> 3) & 0x03;
1816                                         pie->Parity      =  IBuf[Octet + Off] & 0x07;
1817                                         Off++;
1818 
1819                                         /* Octet 5d */
1820                                         if (IsQ931Ext(IBuf[Octet + Off - 1])) {
1821                                                 pie->DuplexMode = (IBuf[Octet + Off] >> 6) & 0x01;
1822                                                 pie->ModemType  =  IBuf[Octet + Off] & 0x3f;
1823                                                 Off = Q931ReadExt(&IBuf[Octet + Off], Off);
1824                                                 Off++;
1825                                         }
1826                                 }
1827                         }
1828                 }
1829         }
1830 
1831         /* Octet 6 - Layer 2 Ident */
1832         if ((IBuf[Octet + Off] & 0x60) == 0x40) { /* Layer 1 Ident ? */
1833                 pie->Layer2Ident = (IBuf[Octet + Off] >>5) & 0x03;
1834                 pie->UIL2Prot    =  IBuf[Octet + Off] & 0x1f;
1835                 Octet++;
1836 
1837                 /* Octet 6a */
1838                 if (IsQ931Ext(IBuf[Octet + Off - 1])) {
1839                         if (pie->UIL2Prot == 0x10) { /* 2nd 6a */
1840                                 pie->UsrSpcL2Prot = IBuf[Octet + Off] & 0x7f;
1841                                 Off++;
1842                         }
1843                         else { /* assume 1st 6a */
1844                                 pie->ModeL2  = (IBuf[Octet + Off] >> 5) & 0x03;
1845                                 pie->Q933use =  IBuf[Octet + Off] & 0x03;
1846                                 Off++;
1847                         }
1848                         /* Octet 6b */
1849                         if (IsQ931Ext(IBuf[Octet + Off - 1])) {
1850                                 pie->WindowSize = IBuf[Octet + Off] & 0x7f;
1851                                 Off++;
1852                         }
1853                 }
1854         }
1855 
1856         /* Octet 7 - layer 3 Ident */
1857         if ((IBuf[Octet + Off] & 0x60) == 0x60) { /* Layer 3 Ident ? */
1858                 pie->Layer3Ident = (IBuf[Octet + Off] >> 5) & 0x03;
1859                 pie->UIL3Prot    =  IBuf[Octet + Off] & 0x1f;
1860                 Octet++;
1861 
1862                 /* Octet 7a */
1863                 if (IsQ931Ext(IBuf[Octet + Off - 1])) {
1864                         if (pie->UIL3Prot == 0x0b) {
1865                                 /* Octet 7a + 7b AddL3Info */
1866                                 pie->AddL3Info = ((IBuf[Octet + Off] << 4) & 0xf0)
1867                                                                 | (IBuf[Octet + Off + 1] & 0x0f);
1868                                 Off += 2;
1869                         }
1870                         else {
1871                                 if (pie->UIL3Prot == 0x1f) {
1872                                         pie->ModeL3 = (IBuf[Octet + Off] >> 5) & 0x03;
1873                                         Off++;
1874                                 }
1875                                 else {
1876                                         pie->OptL3Info = IBuf[Octet + Off] & 0x7f;
1877                                         Off++;
1878                                 }
1879 
1880                                 /* Octet 7b*/
1881                                 if (IsQ931Ext(IBuf[Octet + Off - 1])) {
1882                                         pie->DefPackSize = IBuf[Octet + Off] & 0x0f;
1883                                         Off++;
1884 
1885                                         /* Octet 7c */
1886                                         if (IsQ931Ext(IBuf[Octet + Off - 1])) {
1887                                                 pie->PackWinSize= IBuf[Octet + Off] & 0x7f;
1888                                         }
1889                                 }
1890                         }
1891                 }
1892         }
1893 
1894         Q931IESizeTest(Q931E_LLCOMP);
1895         Q931SetIE(*pIE, *OOff);
1896 
1897         *IOff = (*IOff) + Octet + Off;
1898         *OOff = (*OOff) + sizeof(Q931ie_LLComp);
1899         pie->Size = sizeof(Q931ie_LLComp);
1900 
1901         return Q931E_NO_ERROR;
1902 }
1903 
1904 /*****************************************************************************
1905 
1906   Function:      Q931Pie_LLComp
1907 
1908   Parameters:   IBuf[IN]                Ptr to struct.
1909                                 OBuf[OUT]               Ptr tp packed output buffer.
1910                                 Octet[IN/OUT]   Offset into OBuf.
1911 
1912   Return Value: Error code, 0 = OK
1913 
1914 *****************************************************************************/
1915 L3INT Q931Pie_LLComp(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
1916 {
1917         Q931ie_LLComp *pIE = (Q931ie_LLComp*)IBuf;
1918         L3INT rc = 0;
1919         L3INT Beg = *Octet;
1920         L3INT li;
1921 
1922         OBuf[(*Octet)++] = Q931ie_LOW_LAYER_COMPATIBILITY;
1923         li = (*Octet)++;
1924 
1925         /* Octet 3 */
1926         OBuf[(*Octet)++] = (pIE->CodStand << 6) | pIE->ITransCap;
1927 
1928         /* Octet 3a */
1929         OBuf[(*Octet)++] = 0x80 | (pIE->NegotInd << 6);
1930 
1931         /* Octet 4 */
1932         OBuf[(*Octet)++] = 0x80 | (pIE->TransMode << 5) | pIE->InfoRate;
1933 
1934         /* Octet 4.1 */
1935         if (pIE->InfoRate == 0x18) {
1936                 OBuf[(*Octet)++] = 0x80 | pIE->RateMul;
1937         }
1938 
1939         /* Octet 5 */
1940         if (pIE->Layer1Ident == 0x01) {
1941                 OBuf[(*Octet)++] = (pIE->Layer1Ident << 5) | pIE->UIL1Prot;
1942                 
1943                 /* Octet 5a */
1944                 if ((pIE->ITransCap == 0x08 && (pIE->UIL1Prot == 0x01 || pIE->UIL1Prot == 0x08))
1945                         || (pIE->ITransCap == 0x10 && (pIE->UIL1Prot == 0x02 || pIE->UIL1Prot == 0x03))) {
1946                         OBuf[(*Octet)++] = (pIE->SyncAsync<<6) | (pIE->Negot<<5) | pIE->UserRate;
1947                         
1948                         /* Octet 5b*/
1949                         if (pIE->UIL1Prot == 0x01) {
1950                                 OBuf[(*Octet)++] =  (pIE->InterRate << 5)
1951                                                         | (pIE->NIConTx << 4)
1952                                                         | (pIE->NIConTx << 3)
1953                                                         | (pIE->FlowCtlTx << 2)
1954                                                         | (pIE->FlowCtlRx << 1);
1955                         }
1956                         else if (pIE->UIL1Prot == 0x08) {
1957                                 OBuf[(*Octet)++] =  (pIE->HDR << 6)
1958                                                         | (pIE->MultiFrame << 5)
1959                                                         | (pIE->ModeL1 << 4)
1960                                                         | (pIE->NegotLLI << 3)
1961                                                         | (pIE->Assignor << 2)
1962                                                         | (pIE->InBandNeg << 1);
1963                         }
1964                         else {
1965                                 OBuf[(*Octet) - 1] |= 0x80;
1966                         }
1967 
1968                         /* How to detect wherever 5c and 5d is to present is not clear
1969                          * but they have been inculded as 'standard'
1970                          * Octet 5c
1971                          */
1972                         if (pIE->UIL1Prot == 0x01 || pIE->UIL1Prot == 0x08) {
1973                                 OBuf[(*Octet)++] = (pIE->NumStopBits << 5) | (pIE->NumDataBits << 3) | pIE->Parity ;
1974 
1975                                 /* Octet 5d */
1976                                 OBuf[(*Octet)++] = 0x80 | (pIE->DuplexMode << 6) | pIE->ModemType;
1977                         }
1978                 }
1979                 else {
1980                         OBuf[(*Octet) - 1] |= 0x80;
1981                 }
1982         }
1983 
1984         /* Octet 6 */
1985         if (pIE->Layer2Ident == 0x02) {
1986                 OBuf[(*Octet)++] = (pIE->Layer2Ident << 5) | pIE->UIL2Prot;
1987 
1988                 /* Octet 6a*/
1989                 if (pIE->UIL2Prot == 0x02 /* Q.921/I.441 */
1990                 || pIE->UIL2Prot == 0x06 /* X.25 link layer */
1991                 || pIE->UIL2Prot == 0x07 /* X.25 multilink */
1992                 || pIE->UIL2Prot == 0x09 /* HDLC ARM */
1993                 || pIE->UIL2Prot == 0x0a /* HDLC NRM */
1994                 || pIE->UIL2Prot == 0x0b /* HDLC ABM */
1995                 || pIE->UIL2Prot == 0x0d /* X.75 SLP */
1996                 || pIE->UIL2Prot == 0x0e /* Q.922 */
1997                 || pIE->UIL2Prot == 0x11) { /* ISO/ECE 7776 DTE-DCE */
1998                         OBuf[(*Octet)++] = (pIE->ModeL2 << 5) | pIE->Q933use;
1999 
2000                         /* Octet 6b */
2001                         OBuf[(*Octet)++] = 0x80 | pIE->WindowSize;
2002                 }
2003                 else if (pIE->UIL2Prot == 0x10) { /* User Specific */
2004                         OBuf[(*Octet)++] = 0x80 | pIE->UsrSpcL2Prot;
2005                 }
2006                 else {
2007                         OBuf[(*Octet) - 1] |= 0x80;
2008                 }
2009         }
2010 
2011         /* Octet 7 */
2012         if (pIE->Layer3Ident == 0x03) {
2013                 OBuf[(*Octet)++] = (pIE->Layer3Ident << 5) | pIE->UIL3Prot;
2014 
2015                 /* Octet 7a - 3 different ones */
2016                 if (pIE->UIL3Prot == 0x10) {
2017                         OBuf[(*Octet++)] = 0x80 | pIE->OptL3Info;
2018                 }
2019                 else if (pIE->UIL3Prot == 0x06
2020                         ||  pIE->UIL3Prot == 0x07
2021                         ||  pIE->UIL3Prot == 0x08) {
2022                         OBuf[(*Octet)++] = pIE->ModeL3 << 5;
2023 
2024                         /* Octet 7b note 7 */
2025                         OBuf[(*Octet)++] = pIE->DefPackSize;
2026 
2027                         /* Octet 7c note 7 */
2028                         OBuf[(*Octet)++] = 0x80 | pIE->PackWinSize;
2029                 }
2030                 else if (pIE->UIL3Prot == 0x0b) {
2031                         OBuf[(*Octet)++] = (pIE->AddL3Info >> 4) & 0x0f;
2032                         OBuf[(*Octet)++] = 0x80 | (pIE->AddL3Info & 0x0f);
2033                 }
2034                 else {
2035                         OBuf[(*Octet) - 1] |= 0x80;
2036                 }
2037         }
2038         else {
2039                 Q931SetError(pTrunk,Q931E_LLCOMP, 7,0);
2040                 rc = Q931E_LLCOMP;
2041         }
2042 
2043         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
2044         return rc;
2045 }
2046 
2047 /*****************************************************************************
2048 
2049   Function:      Q931Uie_NetFac
2050 
2051   Parameters:   pIE[OUT]                ptr to Information Element id.
2052                                 IBuf[IN]                ptr to a packed ie.
2053                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
2054                                 IOff[IN\OUT]    Input buffer offset
2055                                 OOff[IN\OUT]    Output buffer offset
2056 
2057                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
2058                                 must be updated, but are otherwise not used in the ie unpack.
2059 
2060   Return Value: Error Message
2061 
2062 *****************************************************************************/
2063 L3INT Q931Uie_NetFac(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
2064 {
2065         Q931ie_NetFac *pie = (Q931ie_NetFac*)OBuf;
2066         ie *pIE = &pMsg->NetFac;
2067         L3INT Off = 0;
2068         L3INT Octet = 0;
2069         L3INT x = 0;
2070         L3INT IESize;
2071 
2072         *pIE = 0;
2073 
2074         pie->IEId = IBuf[Octet++];
2075 
2076         /* Octet 2 */
2077         IESize = IBuf[Octet++]; 
2078 
2079         pie->LenNetID = IBuf[Octet + Off]; /* full octet is used */
2080         Octet++;
2081 
2082         if (pie->LenNetID > 0) {
2083                 /* Octet 3.1 */
2084                 pie->TypeNetID = (IBuf[Octet + Off] >> 4) & 0x0f;
2085                 pie->NetIDPlan =  IBuf[Octet + Off] & 0x0f;
2086                 Off = Q931ReadExt(&IBuf[Octet], Off);
2087                 Off++;
2088 
2089                 /* Octet 3.2*/
2090                 for (x = 0; x < pie->LenNetID; x++) {
2091                         pie->NetID[x] = IBuf[Octet + Off] & 0x7f;
2092                         Off++;
2093                 }
2094         }
2095 
2096         /* Octet 4*/
2097         pie->NetFac = IBuf[Octet + Off]; /* Full Octet is used */
2098         Octet++;
2099 
2100         Q931IESizeTest(Q931E_NETFAC);
2101         Q931SetIE(*pIE, *OOff);
2102 
2103         *IOff = (*IOff) + Octet + Off;
2104         *OOff = (*OOff) + sizeof(Q931ie_NetFac) + x - 1;
2105         pie->Size = (L3UCHAR)(sizeof(Q931ie_NetFac) + x - 1);
2106 
2107         return Q931E_NO_ERROR;
2108 }
2109 
2110 /*****************************************************************************
2111 
2112   Function:      Q931Pie_NetFac
2113 
2114   Parameters:   IBuf[IN]                Ptr to struct.
2115                                 OBuf[OUT]               Ptr tp packed output buffer.
2116                                 Octet[IN/OUT]   Offset into OBuf.
2117 
2118   Return Value: Error code, 0 = OK
2119 
2120 *****************************************************************************/
2121 L3INT Q931Pie_NetFac(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
2122 {
2123         Q931ie_NetFac *pIE = (Q931ie_NetFac*)IBuf;
2124         L3INT rc = Q931E_NO_ERROR;
2125         L3INT Beg = *Octet;
2126         L3INT li;
2127         L3INT x;
2128 
2129         OBuf[(*Octet)++] = Q931ie_NETWORK_SPECIFIC_FACILITIES;
2130         li = (*Octet)++;
2131 
2132         /* Octet 3 */
2133         OBuf[(*Octet)++] = pIE->LenNetID;
2134 
2135         if (pIE->LenNetID > 0) {
2136                 /* Octet 3.1 */
2137                 OBuf[(*Octet)++] = 0x80 | (pIE->TypeNetID << 4) | pIE->NetIDPlan;
2138 
2139                 /* Octet 3.2 */
2140                 for (x = 0; x <pIE->LenNetID; x++) {
2141                         OBuf[(*Octet)++] = pIE->NetID[x];
2142                 }
2143         }
2144 
2145         /* Octet 4 */
2146         OBuf[(*Octet)++] = pIE->NetFac;
2147 
2148         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
2149         return rc;
2150 }
2151 
2152 /*****************************************************************************
2153 
2154   Function:             Q931Uie_NotifInd
2155 
2156   Parameters:   pIE[OUT]                ptr to Information Element id.
2157                                 IBuf[IN]                ptr to a packed ie.
2158                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
2159                                 IOff[IN\OUT]    Input buffer offset
2160                                 OOff[IN\OUT]    Output buffer offset
2161 
2162                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
2163                                 must be updated, but are otherwise not used in the ie unpack.
2164 
2165   Return Value: Error Message
2166 
2167 *****************************************************************************/
2168 L3INT Q931Uie_NotifInd(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
2169 {
2170         Q931ie_NotifInd *pie = (Q931ie_NotifInd*)OBuf;
2171         ie *pIE = &pMsg->NotifInd;
2172         L3INT Off = 0;
2173         L3INT Octet = 0;
2174         L3INT IESize;
2175 
2176         *pIE = 0;
2177 
2178         pie->IEId = IBuf[Octet++];
2179 
2180         /* Octet 2*/
2181         IESize = IBuf[Octet++]; 
2182 
2183         /* Octet 3 */
2184         pie->Notification = IBuf[Octet + Off] & 0x7f;
2185 
2186         Off = Q931ReadExt(&IBuf[Octet], Off);
2187         Octet++;
2188 
2189         Q931IESizeTest(Q931E_NOTIFIND);
2190         Q931SetIE(*pIE, *OOff);
2191 
2192         *IOff = (*IOff) + Octet + Off;
2193         *OOff = (*OOff) + sizeof(Q931ie_NotifInd);
2194         pie->Size = sizeof(Q931ie_NotifInd);
2195 
2196         return Q931E_NO_ERROR;
2197 }
2198 
2199 /*****************************************************************************
2200 
2201   Function:      Q931Pie_NotifInd
2202 
2203   Parameters:   IBuf[IN]                Ptr to struct.
2204                                 OBuf[OUT]               Ptr tp packed output buffer.
2205                                 Octet[IN/OUT]   Offset into OBuf.
2206 
2207   Return Value: Error code, 0 = OK
2208 
2209 *****************************************************************************/
2210 L3INT Q931Pie_NotifInd(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
2211 {
2212         Q931ie_NotifInd *pIE = (Q931ie_NotifInd*)IBuf;
2213         L3INT rc = Q931E_NO_ERROR;
2214         L3INT Beg = *Octet;
2215         L3INT li;
2216 
2217         OBuf[(*Octet)++] = Q931ie_NOTIFICATION_INDICATOR;
2218         li = (*Octet)++;
2219 
2220         /* Octet 3 */
2221         OBuf[(*Octet)++] = pIE->Notification;
2222 
2223         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
2224         return rc;
2225 }
2226 
2227 /*****************************************************************************
2228 
2229   Function:      Q931Uie_ProgInd
2230 
2231   Parameters:   pIE[OUT]                ptr to Information Element id.
2232                                 IBuf[IN]                ptr to a packed ie.
2233                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
2234                                 IOff[IN\OUT]    Input buffer offset
2235                                 OOff[IN\OUT]    Output buffer offset
2236 
2237                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
2238                                 must be updated, but are otherwise not used in the ie unpack.
2239 
2240   Return Value: Error Message
2241 
2242 *****************************************************************************/
2243 L3INT Q931Uie_ProgInd(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
2244 {
2245         Q931ie_ProgInd *pie = (Q931ie_ProgInd*)OBuf;
2246         ie *pIE = &pMsg->ProgInd;
2247         L3INT Off = 0;
2248         L3INT Octet = 0;
2249         L3INT IESize;
2250 
2251         *pIE = 0;
2252 
2253         pie->IEId = IBuf[Octet++];
2254 
2255         /* Octet 2 */
2256         IESize = IBuf[Octet++]; 
2257 
2258         /* Octet 3 */
2259         pie->CodStand = (IBuf[Octet + Off] >> 5) & 0x03;
2260         pie->Location =  IBuf[Octet + Off] & 0x0f;
2261 
2262         Off = Q931ReadExt(&IBuf[Octet], Off);
2263         Octet++;
2264 
2265         /* Octet 4 */
2266         pie->ProgDesc = IBuf[Octet + Off] & 0x7f;
2267         Off = Q931ReadExt(&IBuf[Octet], Off);
2268         Octet++;
2269 
2270         Q931IESizeTest(Q931E_PROGIND);
2271         Q931SetIE(*pIE, *OOff);
2272 
2273         *IOff = (*IOff) + Octet + Off;
2274         *OOff = (*OOff) + sizeof(Q931ie_ProgInd);
2275         pie->Size = sizeof(Q931ie_ProgInd);
2276 
2277         return Q931E_NO_ERROR;
2278 }
2279 
2280 /*****************************************************************************
2281 
2282   Function:      Q931Pie_ProgInd
2283 
2284   Parameters:   IBuf[IN]                Ptr to struct.
2285                                 OBuf[OUT]          Ptr tp packed output buffer.
2286                                 Octet[IN/OUT]   Offset L3INTo OBuf.
2287 
2288   Return Value: Error code, 0 = OK
2289 
2290 *****************************************************************************/
2291 L3INT Q931Pie_ProgInd(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
2292 {
2293         Q931ie_ProgInd *pIE = (Q931ie_ProgInd*)IBuf;
2294         L3INT rc = Q931E_NO_ERROR;
2295         L3INT Beg = *Octet;
2296         L3INT li;
2297 
2298         OBuf[(*Octet)++] = Q931ie_PROGRESS_INDICATOR;
2299         li = (*Octet)++;
2300 
2301         /* Octet 3 */
2302         OBuf[(*Octet)++] = 0x80 | (pIE->CodStand << 5) | pIE->Location;
2303 
2304         /* Octet 4 */
2305         OBuf[(*Octet)++] = 0x80 | pIE->ProgDesc;
2306 
2307         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
2308         return rc;
2309 }
2310 
2311 /*****************************************************************************
2312 
2313   Function:      Q931Uie_RepeatInd
2314 
2315   Parameters:   pIE[OUT]                ptr to Information Element id.
2316                                 IBuf[IN]                ptr to a packed ie.
2317                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
2318                                 IOff[IN\OUT]    Input buffer offset
2319                                 OOff[IN\OUT]    Output buffer offset
2320 
2321                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
2322                                 must be updated, but are otherwise not used in the ie unpack.
2323 
2324   Return Value: Error Message
2325 
2326 *****************************************************************************/
2327 L3INT Q931Uie_RepeatInd(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
2328 {
2329         Q931ie_RepeatInd *pie = (Q931ie_RepeatInd*)OBuf;
2330         ie *pIE = &pMsg->RepeatInd;
2331         L3INT Off = 0;
2332         L3INT Octet = 0;
2333 
2334         *pIE = 0;
2335 
2336         pie->IEId      = IBuf[Octet] & 0xf0;
2337         pie->RepeatInd = IBuf[Octet] & 0x0f;
2338         Octet ++;
2339 
2340         Q931SetIE(*pIE, *OOff);
2341 
2342         *IOff = (*IOff) + Octet + Off;
2343         *OOff = (*OOff) + sizeof(Q931ie_RepeatInd);
2344         pie->Size = sizeof(Q931ie_RepeatInd);
2345 
2346         return Q931E_NO_ERROR;
2347 }
2348 
2349 /*****************************************************************************
2350 
2351   Function:      Q931Pie_RepeatInd
2352 
2353   Parameters:   IBuf[IN]                Ptr to struct.
2354                                 OBuf[OUT]               Ptr tp packed output buffer.
2355                                 Octet[IN/OUT]   Offset into OBuf.
2356 
2357   Return Value: Error code, 0 = OK
2358 
2359 *****************************************************************************/
2360 L3INT Q931Pie_RepeatInd(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
2361 {
2362         Q931ie_RepeatInd *pIE = (Q931ie_RepeatInd*)IBuf;
2363         L3INT rc = 0;
2364         /* L3INT Beg = *Octet; */
2365 
2366         OBuf[(*Octet)++] = Q931ie_REPEAT_INDICATOR | pIE->RepeatInd;
2367 
2368         return rc;
2369 }
2370 
2371 /*****************************************************************************
2372 
2373   Function:      Q931Uie_RevChargeInd
2374 
2375   Parameters:   pIE[OUT]                ptr to Information Element id.
2376                                 IBuf[IN]                ptr to a packed ie.
2377                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
2378                                 IOff[IN\OUT]    Input buffer offset
2379                                 OOff[IN\OUT]    Output buffer offset
2380 
2381                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
2382                                 must be updated, but are otherwise not used in the ie unpack.
2383 
2384   Return Value: Error Message
2385 
2386 *****************************************************************************/
2387 L3INT Q931Uie_RevChargeInd(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
2388 {
2389         ie iE;
2390         /* ie *pIE = &pMsg->RevChargeInd; */
2391         Q931SetIE(iE, *OOff);
2392 
2393         return iE;
2394 }
2395 
2396 /*****************************************************************************
2397 
2398   Function:      Q931Pie_RevChargeInd
2399 
2400   Parameters:   IBuf[IN]                Ptr to struct.
2401                                 OBuf[OUT]               Ptr tp packed output buffer.
2402                                 Octet[IN/OUT]   Offset into OBuf.
2403 
2404   Return Value: Error code, 0 = OK
2405 
2406 *****************************************************************************/
2407 L3INT Q931Pie_RevChargeInd(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
2408 {
2409         L3BOOL RetCode = L3FALSE;
2410 
2411         NoWarning(OBuf);
2412         NoWarning(IBuf);
2413 
2414         return RetCode;
2415 }
2416 
2417 /*****************************************************************************
2418 
2419   Function:      Q931Uie_RestartInd
2420 
2421   Parameters:   pIE[OUT]                ptr to Information Element id.
2422                                 IBuf[IN]                ptr to a packed ie.
2423                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
2424                                 IOff[IN\OUT]    Input buffer offset
2425                                 OOff[IN\OUT]    Output buffer offset
2426 
2427                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
2428                                 must be updated, but are otherwise not used in the ie unpack.
2429 
2430   Return Value: Error Message
2431 
2432 *****************************************************************************/
2433 L3INT Q931Uie_RestartInd(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
2434 {
2435         Q931ie_RestartInd *pie = (Q931ie_RestartInd*)OBuf;
2436         ie *pIE = &pMsg->RestartInd;
2437         L3INT Off = 0;
2438         L3INT Octet = 0;
2439         L3INT IESize;
2440 
2441         *pIE = 0;
2442 
2443         pie->IEId = IBuf[Octet++];
2444 
2445         /* Octet 2 */
2446         IESize = IBuf[Octet++]; 
2447 
2448         /* Octet 3 */
2449         pie->Class = IBuf[Octet + Off] & 0x07;
2450         pie->Spare = IBuf[Octet + Off] & 0x78;
2451 
2452         Off = Q931ReadExt(&IBuf[Octet], Off);
2453         Octet++;
2454 
2455         Q931IESizeTest(Q931E_RESTARTIND);
2456         Q931SetIE(*pIE, *OOff);
2457 
2458         *IOff = (*IOff) + Octet + Off;
2459         *OOff = (*OOff) + sizeof(Q931ie_RestartInd);
2460         pie->Size = sizeof(Q931ie_RestartInd);
2461 
2462 
2463         return Q931E_NO_ERROR;
2464 }
2465 
2466 /*****************************************************************************
2467 
2468   Function:      Q931Pie_RestartInd
2469 
2470   Parameters:   IBuf[IN]                Ptr to struct.
2471                                 OBuf[OUT]               Ptr tp packed output buffer.
2472                                 Octet[IN/OUT]   Offset into OBuf.
2473 
2474   Return Value: Error code, 0 = OK
2475 
2476 *****************************************************************************/
2477 L3INT Q931Pie_RestartInd(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
2478 {
2479         Q931ie_RestartInd *pIE = (Q931ie_RestartInd*)IBuf;
2480         L3INT rc = Q931E_NO_ERROR;
2481         L3INT Beg = *Octet;
2482         L3INT li;
2483 
2484         OBuf[(*Octet)++] = Q931ie_RESTART_INDICATOR;
2485         li = (*Octet)++;
2486 
2487         /* Octet 3*/
2488         OBuf[(*Octet)++] = 0x80 | pIE->Class ;
2489 
2490         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
2491         return rc;
2492 }
2493 
2494 /*****************************************************************************
2495 
2496   Function:      Q931Uie_Segment
2497 
2498   Parameters:   pIE[OUT]                ptr to Information Element id.
2499                                 IBuf[IN]                ptr to a packed ie.
2500                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
2501                                 IOff[IN\OUT]    Input buffer offset
2502                                 OOff[IN\OUT]    Output buffer offset
2503 
2504                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
2505                                 must be updated, but are otherwise not used in the ie unpack.
2506 
2507   Return Value: Error Message
2508 
2509 *****************************************************************************/
2510 L3INT Q931Uie_Segment(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
2511 {
2512         Q931ie_Segment *pie = (Q931ie_Segment*)OBuf;
2513         ie *pIE = &pMsg->Segment;
2514         L3INT Off = 0;
2515         L3INT Octet = 0;
2516         L3INT IESize;
2517 
2518         *pIE = 0;
2519 
2520         pie->IEId = IBuf[Octet++];
2521         Octet++;
2522 
2523         /* Octet 2*/
2524         IESize = IBuf[Octet++]; 
2525 
2526         /* Octet 3 */
2527         pie->FSI       = (IBuf[Octet + Off] & 0x80) >> 7;
2528         pie->NumSegRem =  IBuf[Octet + Off] & 0x7f;
2529         Octet++;
2530 
2531         /* Octet 4 */
2532         pie->SegType = IBuf[Octet + Off] & 0x7f;
2533         Octet++;
2534         
2535         Q931IESizeTest(Q931E_SEGMENT);
2536         Q931SetIE(*pIE, *OOff);
2537 
2538         *IOff = (*IOff) + Octet + Off;
2539         *OOff = (*OOff) + sizeof(Q931ie_Segment);
2540         pie->Size = sizeof(Q931ie_Segment);
2541 
2542         return Q931E_NO_ERROR;
2543 }
2544 
2545 /*****************************************************************************
2546 
2547   Function:      Q931Pie_Segment
2548 
2549   Parameters:   IBuf[IN]                Ptr to struct.
2550                                 OBuf[OUT]               Ptr tp packed output buffer.
2551                                 Octet[IN/OUT]   Offset into OBuf.
2552 
2553   Return Value: Error code, 0 = OK
2554 
2555 *****************************************************************************/
2556 L3INT Q931Pie_Segment(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
2557 {
2558         Q931ie_Segment *pIE = (Q931ie_Segment*)IBuf;
2559         L3INT rc = Q931E_NO_ERROR;
2560         L3INT Beg = *Octet;
2561         L3INT li;
2562 
2563         OBuf[(*Octet)++] = Q931ie_SEGMENTED_MESSAGE;
2564         li = (*Octet)++;
2565 
2566         /* Octet 3 */
2567         OBuf[(*Octet)++] = (pIE->FSI << 7) | pIE->NumSegRem;
2568 
2569         /* Octet 4 */
2570         OBuf[(*Octet)++] = pIE->SegType;
2571 
2572         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
2573         return rc;
2574 }
2575 
2576 /*****************************************************************************
2577 
2578   Function:             Q931Uie_SendComplete
2579 
2580   Parameters:   pIE[OUT]                ptr to Information Element id.
2581                                 IBuf[IN]                ptr to a packed ie.
2582                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
2583                                 IOff[IN\OUT]    Input buffer offset
2584                                 OOff[IN\OUT]    Output buffer offset
2585 
2586                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
2587                                 must be updated, but are otherwise not used in the ie unpack.
2588 
2589   Return Value: Error Message
2590 
2591 *****************************************************************************/
2592 L3INT Q931Uie_SendComplete(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
2593 {
2594         Q931ie_SendComplete *pie = (Q931ie_SendComplete*)OBuf;
2595         ie *pIE = &pMsg->SendComplete;
2596         L3INT Off = 0;
2597         L3INT Octet = 0;
2598 
2599         *pIE = 0;
2600         Octet++;
2601 
2602         Q931SetIE(*pIE, *OOff);
2603 
2604         *IOff = (*IOff) + Octet + Off;
2605         *OOff = (*OOff) + sizeof(Q931ie_SendComplete);
2606         pie->Size = sizeof(Q931ie_SendComplete);
2607 
2608         return Q931E_NO_ERROR;
2609 }
2610 
2611 /*****************************************************************************
2612 
2613   Function:      Q931Pie_ProgInd
2614 
2615   Parameters:   IBuf[IN]                Ptr to struct.
2616                                 OBuf[OUT]          Ptr tp packed output buffer.
2617                                 Octet[IN/OUT]   Offset into OBuf.
2618 
2619   Return Value: Error code, 0 = OK
2620 
2621 *****************************************************************************/
2622 L3INT Q931Pie_SendComplete(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
2623 {
2624         /* Q931ie_SendComplete * pIE = (Q931ie_SendComplete*)IBuf; */
2625         L3INT rc = Q931E_NO_ERROR;
2626         /* L3INT Beg = *Octet; */
2627 
2628         OBuf[(*Octet)++] = 0x80 | (L3UCHAR)Q931ie_SENDING_COMPLETE;
2629 
2630         return rc;
2631 }
2632 
2633 /*****************************************************************************
2634 
2635   Function:      Q931Uie_Signal
2636 
2637   Parameters:   pIE[OUT]                ptr to Information Element id.
2638                                 IBuf[IN]                ptr to a packed ie.
2639                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
2640                                 IOff[IN\OUT]    Input buffer offset
2641                                 OOff[IN\OUT]    Output buffer offset
2642 
2643                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
2644                                 must be updated, but are otherwise not used in the ie unpack.
2645 
2646   Return Value: Error Message
2647 
2648 *****************************************************************************/
2649 L3INT Q931Uie_Signal(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
2650 {
2651         Q931ie_Signal *pie = (Q931ie_Signal*)OBuf;
2652         ie *pIE = &pMsg->Signal;
2653         L3INT Off = 0;
2654         L3INT Octet = 0;
2655         L3INT IESize;
2656 
2657         *pIE = 0;
2658 
2659         pie->IEId = IBuf[Octet++];
2660 
2661         /* Octet 2 */
2662         IESize = IBuf[Octet++]; 
2663 
2664         /* Octet 3 */
2665         pie->Signal = IBuf[Octet + Off];
2666         Octet++;
2667 
2668         Q931IESizeTest(Q931E_SIGNAL);
2669         Q931SetIE(*pIE, *OOff);
2670 
2671         *IOff = (*IOff) + Octet + Off;
2672         *OOff = (*OOff) + sizeof(Q931ie_Signal);
2673         pie->Size = sizeof(Q931ie_Signal);
2674 
2675         return Q931E_NO_ERROR;
2676 }
2677 
2678 /*****************************************************************************
2679 
2680   Function:      Q931Pie_Signal
2681 
2682   Parameters:   IBuf[IN]                Ptr to struct.
2683                                 OBuf[OUT]               Ptr tp packed output buffer.
2684                                 Octet[IN/OUT]   Offset into OBuf.
2685 
2686   Return Value: Error code, 0 = OK
2687 
2688 *****************************************************************************/
2689 L3INT Q931Pie_Signal(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
2690 {
2691         Q931ie_Signal *pIE = (Q931ie_Signal*)IBuf;
2692         L3INT rc = Q931E_NO_ERROR;
2693         L3INT Beg = *Octet;
2694         L3INT li;
2695 
2696         OBuf[(*Octet)++] = Q931ie_SIGNAL;
2697         li = (*Octet)++;
2698 
2699         /* Octet 3 */
2700         OBuf[(*Octet)++] = pIE->Signal;
2701 
2702         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
2703         return rc;
2704 }
2705 
2706 /*****************************************************************************
2707 
2708   Function:      Q931Uie_TransNetSel
2709 
2710   Parameters:   pIE[OUT]                ptr to Information Element id.
2711                                 IBuf[IN]                ptr to a packed ie.
2712                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
2713                                 IOff[IN\OUT]    Input buffer offset
2714                                 OOff[IN\OUT]    Output buffer offset
2715 
2716                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
2717                                 must be updated, but are otherwise not used in the ie unpack.
2718 
2719   Return Value: Error Message
2720 
2721 *****************************************************************************/
2722 L3INT Q931Uie_TransNetSel(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
2723 {
2724         Q931ie_TransNetSel *pie = (Q931ie_TransNetSel*)OBuf;
2725         ie *pIE = &pMsg->TransNetSel;
2726         L3INT Off = 0;
2727         L3INT Octet = 0;
2728         L3INT x = 0;
2729         L3INT l;
2730 
2731         *pIE = 0;
2732 
2733         pie->IEId = IBuf[Octet++];
2734 
2735         /* Octet 2 */
2736         l = IBuf[Octet++] - 3; 
2737 
2738         /* Octet 3 */
2739         pie->Type = (IBuf[Octet + Off] >> 4) & 0x07;
2740 
2741         Off = Q931ReadExt(&IBuf[Octet], Off);
2742         Octet++;
2743 
2744         for (x = 0; x < l; x++) {
2745                 pie->NetID[x] = IBuf[Octet + Off] & 0x7f;
2746                 Off++;
2747         }
2748 
2749         Q931SetIE(*pIE, *OOff);
2750 
2751         *IOff = (*IOff) + Octet + Off;
2752         *OOff = (*OOff) + sizeof(Q931ie_TransNetSel) + x - 1;
2753         pie->Size = (L3UCHAR)(sizeof(Q931ie_TransNetSel) + x - 1);
2754 
2755         return Q931E_NO_ERROR;
2756 }
2757 
2758 /*****************************************************************************
2759 
2760   Function:      Q931Pie_TransNetSel
2761 
2762   Parameters:   IBuf[IN]                Ptr to struct.
2763                                 OBuf[OUT]               Ptr tp packed output buffer.
2764                                 Octet[IN/OUT]   Offset into OBuf.
2765 
2766   Return Value: Error code, 0 = OK
2767 
2768 *****************************************************************************/
2769 L3INT Q931Pie_TransNetSel(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
2770 {
2771         Q931ie_TransNetSel *pIE = (Q931ie_TransNetSel*)IBuf;
2772         L3INT rc = Q931E_NO_ERROR;
2773         L3INT Beg = *Octet;
2774         L3INT li;
2775         L3INT x;
2776         L3INT l;
2777 
2778         OBuf[(*Octet)++] = Q931ie_TRANSIT_NETWORK_SELECTION;
2779         li = (*Octet)++;
2780 
2781         /* Octet 3 */
2782         OBuf[(*Octet)++] = 0x80 | (pIE->Type << 4) | pIE->NetIDPlan;
2783 
2784         /* Octet 4 */
2785         l = pIE->Size - sizeof(Q931ie_TransNetSel) + 1;
2786         for (x = 0; x < l; x++) {
2787                 OBuf[(*Octet)++] = pIE->NetID[x];
2788         }
2789 
2790         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
2791         return rc;
2792 }
2793 
2794 /*****************************************************************************
2795 
2796   Function:      Q931Uie_UserUser
2797 
2798   Parameters:   pIE[OUT]                ptr to Information Element id.
2799                                 IBuf[IN]                ptr to a packed ie.
2800                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
2801                                 IOff[IN\OUT]    Input buffer offset
2802                                 OOff[IN\OUT]    Output buffer offset
2803 
2804                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
2805                                 must be updated, but are otherwise not used in the ie unpack.
2806 
2807   Return Value: Error Message
2808 
2809 *****************************************************************************/
2810 L3INT Q931Uie_UserUser(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
2811 {
2812         Q931ie_UserUser *pie = (Q931ie_UserUser*)OBuf;
2813         ie *pIE = &pMsg->UserUser;
2814         L3INT Off = 0;
2815         L3INT Octet = 0;
2816         L3INT l;
2817 
2818         *pIE = 0;
2819 
2820         pie->IEId = IBuf[Octet++];
2821 
2822         /* Octet 2 */
2823         l = IBuf[Octet++] - 1;
2824 
2825         /* Octet 3 */
2826         pie->ProtDisc = IBuf[Octet++];
2827 
2828         for (Off = 0; Off < l; Off++) {
2829                 pie->User[Off] = IBuf[Octet + Off];
2830         }
2831 
2832         Q931SetIE(*pIE, *OOff);
2833 
2834         *IOff = (*IOff) + Octet + Off;
2835         *OOff = (*OOff) + sizeof(Q931ie_UserUser) + Off - 1;
2836         pie->Size = (L3UCHAR)(sizeof(Q931ie_UserUser) + Off - 1);
2837 
2838         return Q931E_NO_ERROR;
2839 }
2840 
2841 /*****************************************************************************
2842 
2843   Function:      Q931Pie_UserUser
2844 
2845   Parameters:   IBuf[IN]                Ptr to struct.
2846                                 OBuf[OUT]               Ptr tp packed output buffer.
2847                                 Octet[IN/OUT]   Offset into OBuf.
2848 
2849   Return Value: Error code, 0 = OK
2850 
2851 *****************************************************************************/
2852 L3INT Q931Pie_UserUser(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
2853 {
2854         Q931ie_UserUser *pIE = (Q931ie_UserUser*)IBuf;
2855         L3INT rc = Q931E_NO_ERROR;
2856         L3INT Beg = *Octet;
2857         L3INT li;
2858         L3INT x;
2859         L3INT l;
2860 
2861         OBuf[(*Octet)++] = Q931ie_USER_USER;
2862         li = (*Octet)++;
2863 
2864         /* Octet 3 */
2865         OBuf[(*Octet)++] = pIE->ProtDisc;
2866 
2867         /* Octet 4 */
2868         l = pIE->Size - sizeof(Q931ie_UserUser) + 1;
2869         for (x = 0; x < l; x++) {
2870                 OBuf[(*Octet)++] = pIE->User[x];
2871         }
2872 
2873         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
2874         return rc;
2875 }
2876 
2877 /*****************************************************************************
2878 
2879   Function:      Q931Uie_GenericDigits
2880 
2881   Parameters:   pIE[OUT]                ptr to Information Element id.
2882                                 IBuf[IN]                ptr to a packed ie.
2883                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
2884                                 IOff[IN\OUT]    Input buffer offset
2885                                 OOff[IN\OUT]    Output buffer offset
2886 
2887 
2888                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
2889                                 must be updated, but are otherwise not used in the ie unpack.
2890 
2891   Return Value: Error Message
2892 
2893 *****************************************************************************/
2894 L3INT Q931Uie_GenericDigits(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
2895 {
2896         Q931ie_GenericDigits *pie = (Q931ie_GenericDigits*)OBuf;
2897         ie *pIE = &pMsg->GenericDigits;
2898         L3INT Off = 0;
2899         L3INT Octet = 0;
2900         L3INT x;
2901         L3INT IESize;
2902 
2903         *pIE = 0;
2904 
2905         /* Octet 1 */
2906         pie->IEId = IBuf[Octet++];
2907 
2908         /* Octet 2 */
2909         IESize = IBuf[Octet++]; 
2910 
2911         /* Octet 3 */
2912         pie->Type     = (IBuf[Octet]) & 0x1F;
2913         pie->Encoding = (IBuf[Octet] >> 5) & 0x07;
2914         Octet++;
2915         
2916         /* Octet 4*/
2917         if (pie->Encoding == 0) { /* BCD Even */
2918                 x = 0;
2919                 do {
2920                         pie->Digit[x++] =  IBuf[Octet + Off] & 0x0f;
2921                         pie->Digit[x++] = (IBuf[Octet + Off] >> 4) & 0x0f;
2922                         Off++;
2923                 } while (Q931MoreIE());
2924         } else if (pie->Encoding == 1) { /* BCD Odd */
2925                 x = 0;
2926                 do {
2927                         pie->Digit[x++] = IBuf[Octet + Off] & 0x0f;
2928                         if (Q931MoreIE()) {
2929                                 pie->Digit[x] = (IBuf[Octet + Off] >> 4) & 0x0f;
2930                         }
2931                         x++;
2932                         Off++;
2933                 } while (Q931MoreIE());
2934         } else if (pie->Encoding == 2) { /* IA5 */
2935                 x = 0;
2936                 do {
2937                         pie->Digit[x++] = IBuf[Octet + Off] & 0x7f;
2938                         Off++;
2939                 } while (Q931MoreIE());
2940         } else {
2941                 /* Binary encoding type unkown */
2942                 Q931SetError(pTrunk, Q931E_GENERIC_DIGITS, Octet, Off);
2943                 return Q931E_GENERIC_DIGITS;
2944         }
2945 
2946         Q931IESizeTest(Q931E_GENERIC_DIGITS);
2947         Q931SetIE(*pIE, *OOff);
2948 
2949         *IOff = (*IOff) + Octet + Off;
2950         *OOff = (*OOff) + sizeof(Q931ie_CallingSub) + x - 1;
2951         pie->Size = (L3UCHAR)(sizeof(Q931ie_CallingSub) + x - 1);
2952 
2953         return Q931E_NO_ERROR;
2954 }
2955 
2956 /*****************************************************************************
2957 
2958   Function:      Q931Pie_GenericDigits
2959 
2960   Parameters:   IBuf[IN]                Ptr to struct.
2961                                 OBuf[OUT]               Ptr tp packed output buffer.
2962                                 Octet[IN/OUT]   Offset into OBuf.
2963 
2964   Return Value: Error code, 0 = OK
2965 
2966 *****************************************************************************/
2967 
2968 L3INT Q931Pie_GenericDigits(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
2969 {
2970         OBuf[(*Octet)++] = (Q931ie_GENERIC_DIGITS & 0xFF);
2971         OBuf[(*Octet)++] = 0;
2972 
2973         return Q931E_NO_ERROR;
2974 }
2975 
2976 /*****************************************************************************
2977 
2978   Function:      Q931Uie_ChangeStatus
2979 
2980   Parameters:   pIE[OUT]                ptr to Information Element id.
2981                                 IBuf[IN]                ptr to a packed ie.
2982                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
2983                                 IOff[IN\OUT]    Input buffer offset
2984                                 OOff[IN\OUT]    Output buffer offset
2985 
2986                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
2987                                 must be updated, but are otherwise not used in the ie unpack.
2988 
2989   Return Value: Error Message
2990 
2991 *****************************************************************************/
2992 L3INT Q931Uie_ChangeStatus(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
2993 {
2994         Q931ie_ChangeStatus *pie = (Q931ie_ChangeStatus*)OBuf;
2995         ie *pIE = &pMsg->ChangeStatus;
2996         L3INT Off = 0;
2997         L3INT Octet = 0;
2998         L3INT IESize;
2999 
3000         *pIE = 0;
3001 
3002         pie->IEId = IBuf[Octet++];
3003 
3004         /* Octet 2 */
3005         IESize = IBuf[Octet++]; 
3006 
3007         /* Octet 3 */
3008         pie->Preference = (IBuf[Octet + Off] >> 6) & 0x01;
3009         pie->Spare      =  IBuf[Octet + Off] & 0x38;
3010         pie->NewStatus  =  IBuf[Octet + Off] & 0x07;
3011         Octet++;
3012 
3013         Q931SetIE(*pIE, *OOff);
3014 
3015         *IOff = (*IOff) + Octet + Off;
3016         *OOff = (*OOff) + sizeof(Q931ie_ChangeStatus);
3017         pie->Size = sizeof(Q931ie_ChangeStatus);
3018 
3019         return Q931E_NO_ERROR;
3020 }
3021 
3022 /*****************************************************************************
3023 
3024   Function:      Q931Pie_ChangeStatus
3025 
3026   Parameters:   IBuf[IN]                Ptr to struct.
3027                                 OBuf[OUT]               Ptr tp packed output buffer.
3028                                 Octet[IN/OUT]   Offset into OBuf.
3029 
3030   Return Value: Error code, 0 = OK
3031 
3032 *****************************************************************************/
3033 L3INT Q931Pie_ChangeStatus(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
3034 {
3035         Q931ie_ChangeStatus *pIE = (Q931ie_ChangeStatus*)IBuf;
3036         L3INT rc = Q931E_NO_ERROR;
3037         L3INT Beg = *Octet;
3038         L3INT li;
3039 
3040         OBuf[(*Octet)++] = Q931ie_CHANGE_STATUS;
3041         li = (*Octet)++;
3042 
3043         /* Octet 3 */
3044         OBuf[(*Octet)++] = 0x80 | pIE->NewStatus | ((pIE->Preference & 0x01) << 6);
3045 
3046         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
3047         return rc;
3048 }
3049 
3050 
3051 
3052 L3INT Q931Uie_Generic(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *IOff, L3INT *OOff)
3053 {
3054         L3INT Octet = 0;
3055         L3UCHAR id = 0;
3056 
3057         /* id */
3058         id = IBuf[Octet++];
3059 
3060         /* Length */
3061         Octet += IBuf[Octet];
3062         Octet++;
3063 
3064         Q931Log(pTrunk, Q931_LOG_DEBUG, "Discarding IE %#hhx with length %d\n", id, Octet - 2);
3065 
3066         *IOff += Octet;
3067         return Q931E_NO_ERROR;
3068 }
3069 
3070 L3INT Q931Pie_Generic(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
3071 {
3072         /* do nothing */
3073         return Q931E_NO_ERROR;
3074 }

/* [<][>][^][v][top][bottom][index][help] */