Q931ie.c

Go to the documentation of this file.
00001 /*****************************************************************************
00002 
00003   FileName:      Q931ie.c
00004 
00005   Contents:      Information Element Pack/Unpack functions. 
00006   
00007                 These functions will pack out a Q931 message from the bit 
00008                 packed original format into structs that are easier to process 
00009                 and pack the same structs back into bit fields when sending
00010                 messages out.
00011 
00012                 The messages contains a short for each possible IE. The MSB 
00013                 bit flags the precense of an IE, while the remaining bits 
00014                 are the offset into a buffer to find the actual IE.
00015 
00016                 Each IE are supported by 3 functions:
00017 
00018                 Q931Pie_XXX      Pack struct into Q.931 IE
00019                 Q931Uie_XXX      Unpack Q.931 IE into struct
00020                 Q931InitIEXXX   Initialize IE (see Q931api.c).
00021 
00022   Dialect Note: This file will only contain standard DSS1 IE. Other IE as 
00023                 used in QSIG, NI2, Q.932 etc are located in separate files.
00024 
00025                 See     q931.h for description. 
00026 
00027   License/Copyright:
00028 
00029   Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved.
00030   email:janvb@caselaboratories.com  
00031 
00032   Redistribution and use in source and binary forms, with or without 
00033   modification, are permitted provided that the following conditions are 
00034   met:
00035 
00036         * Redistributions of source code must retain the above copyright notice, 
00037           this list of conditions and the following disclaimer.
00038         * Redistributions in binary form must reproduce the above copyright notice, 
00039           this list of conditions and the following disclaimer in the documentation 
00040           and/or other materials provided with the distribution.
00041         * Neither the name of the Case Labs, Ltd nor the names of its contributors 
00042           may be used to endorse or promote products derived from this software 
00043           without specific prior written permission.
00044 
00045   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
00046   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
00047   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
00048   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
00049   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
00050   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
00051   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00052   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
00053   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
00054   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
00055   POSSIBILITY OF SUCH DAMAGE.
00056 *****************************************************************************/
00057 #define Q931PRIVATE
00058 
00059 #include "Q931.h"
00060 
00061 #ifdef _MSC_VER
00062 #ifndef __inline__
00063 #define __inline__ __inline
00064 #endif
00065 #if (_MSC_VER >= 1400)                  /* VC8+ */
00066 #ifndef _CRT_SECURE_NO_DEPRECATE
00067 #define _CRT_SECURE_NO_DEPRECATE
00068 #endif
00069 #ifndef _CRT_NONSTDC_NO_DEPRECATE
00070 #define _CRT_NONSTDC_NO_DEPRECATE
00071 #endif
00072 #endif
00073 #ifndef strcasecmp
00074 #define strcasecmp(s1, s2) _stricmp(s1, s2)
00075 #endif
00076 #ifndef strncasecmp
00077 #define strncasecmp(s1, s2, n) _strnicmp(s1, s2, n)
00078 #endif
00079 #ifndef snprintf
00080 #define snprintf _snprintf
00081 #endif
00082 #endif
00083 
00084 /*****************************************************************************
00085 
00086   Macro:                Q931MoreIE
00087 
00088   Description:  Local helper macro detecting if there is more IE space left
00089                 based on the 3 standard parameters Octet, Off and IESpace.
00090                 This can be used to test if the IE is completed to avoid
00091                 that the header of the next IE is interpreted as a part of
00092                 the current IE.
00093 
00094 *****************************************************************************/
00095 #define Q931MoreIE() (Octet + Off - 2 < IESize)
00096 
00097 #define Q931IESizeTest(x) {\
00098         if (Octet + Off - 2 != IESize) {\
00099                 Q931SetError(pTrunk, x, Octet, Off);\
00100                 return x;\
00101         }\
00102 }
00103 
00104 /*****************************************************************************
00105 
00106   Function:      Q931ReadExt
00107 
00108   Description:  Many of the octets in the standard have an MSB 'ext.1'. This
00109                                 means that the octet usually is the latest octet, but that a
00110                                 futhure standard may extend the octet. A stack must be able 
00111                                 to handle such extensions by skipping the extension octets.
00112 
00113                                 This function will increase the offset counter with 1 for 
00114                                 each octet with an MSB of zero. This will allow the stack to
00115                                 skip extensions wihout knowing anything about them.
00116 
00117   Parameters:   IBuf    ptr to octet array.
00118                                 Off      Starting offset counter
00119 
00120   Return Value: New offset value.
00121 
00122 *****************************************************************************/
00123 
00124 L3INT Q931ReadExt(L3UCHAR * IBuf, L3INT Off)
00125 {
00126         L3INT c = 0;
00127         while ((IBuf[c] & 0x80) == 0) {
00128                 c++;
00129         }
00130         return Off + c;
00131 }
00132 
00133 /*****************************************************************************
00134 
00135   Function:      Q931Uie_BearerCap
00136 
00137   Description:  Unpack a bearer capability ie.
00138 
00139   Parameters:   pIE[OUT]        ptr to Information Element id.
00140                 IBuf[IN]        ptr to a packed ie.
00141                 OBuf[OUT]       ptr to buffer for Unpacked ie.
00142                 IOff[IN\OUT]    Input buffer offset
00143                 OOff[IN\OUT]    Output buffer offset
00144 
00145                 Ibuf and OBuf points directly to buffers. The IOff and OOff
00146                 must be updated, but are otherwise not used in the ie unpack.
00147 
00148   Return Value: Error Message
00149 
00150 *****************************************************************************/
00151 
00152 L3INT Q931Uie_BearerCap(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) 
00153 {
00154         Q931ie_BearerCap *pie = (Q931ie_BearerCap*)OBuf;
00155         ie *pIE = &pMsg->BearerCap;
00156         L3INT Off = 0;
00157         L3INT Octet = 0;
00158         L3INT IESize;
00159         *pIE = 0;
00160 
00161         /* Octet 1 */
00162         pie->IEId = IBuf[Octet++];
00163 
00164         /* Octet 2 */
00165         IESize = IBuf[Octet++]; 
00166 
00167         /* Octet 3 */
00168         pie->CodStand = ieGetOctet((IBuf[Octet] & 0x60) >> 5);
00169         pie->ITC      = ieGetOctet(IBuf[Octet] & 0x1f);
00170         Off           = Q931ReadExt(&IBuf[Octet], Off);
00171         Octet++;
00172 
00173         /* Octet 4 */
00174         pie->TransMode = ieGetOctet((IBuf[Octet + Off] & 0x60) >> 5);
00175         pie->ITR       = ieGetOctet(IBuf[Octet + Off] & 0x1f);
00176         Off            = Q931ReadExt(&IBuf[Octet + Off], Off);
00177         Octet++;
00178 
00179         /* Octet 4.1. Rate multiplier is only present if ITR = Multirate                */
00180         if (pie->ITR == 0x18) {
00181                 pie->RateMul = ieGetOctet(IBuf[Octet + Off] & 0x7f);
00182                 Off = Q931ReadExt(&IBuf[Octet + Off], Off);
00183                 Off ++;
00184         }
00185 
00186         /* Octet 5 */
00187         if ((IBuf[Octet + Off] & 0x60) == 0x20 && Q931MoreIE()) {
00188                 pie->Layer1Ident = ieGetOctet((IBuf[Octet + Off] & 0x60) >> 5);
00189                 pie->UIL1Prot    = ieGetOctet(IBuf[Octet + Off] & 0x1f);
00190                 Octet++;
00191 
00192                 /* Octet 5a. The octet may be present if ITC is unrestrictd digital info
00193                  * and UIL1Prot is either V.110, I.460 and X.30 or V.120. It may also
00194                  * be present if ITC = 3.1 kHz audio and UIL1Prot is G.711.
00195                  * Bit 8 of Octet 5 = 0 indicates that 5a is present.
00196                  */
00197 
00198                 if (IsQ931Ext(IBuf[Octet + Off - 1])) {
00199                         if (((pie->ITC == 0x08) && (pie->UIL1Prot == 0x01 || pie->UIL1Prot == 0x08))
00200                         || ((pie->ITC == 0x10) && (pie->UIL1Prot == 0x02 || pie->UIL1Prot == 0x03))) {
00201                                 pie->SyncAsync = ieGetOctet((IBuf[Octet + Off] & 0x40) >> 6);
00202                                 pie->Negot     = ieGetOctet((IBuf[Octet + Off] & 0x20) >> 5);
00203                                 pie->UserRate  = ieGetOctet(IBuf[Octet + Off] & 0x1f);
00204                                 Off ++;
00205                         }
00206                         else {
00207                                 /* We have detected bit 8 = 0, but no setting that require the  */
00208                                 /* additional octets ??? */
00209                                 Q931SetError(pTrunk, Q931E_BEARERCAP, 5,Off);
00210                                 return Q931E_BEARERCAP;
00211                         }
00212 
00213                         /* Octet 5b. Two different structures used. */
00214                         if (IsQ931Ext(IBuf[Octet + Off - 1])) {
00215                                 if (pie->UIL1Prot == 0x01) { /* ITU V.110, I.460 and X.30 */
00216                                         pie->InterRate = ieGetOctet((IBuf[Octet + Off] & 0x60) >> 5);
00217                                         pie->NIConTx   = ieGetOctet((IBuf[Octet + Off] & 0x10) >> 4);
00218                                         pie->NIConRx   = ieGetOctet((IBuf[Octet + Off] & 0x08) >> 3);
00219                                         pie->FlowCtlTx = ieGetOctet((IBuf[Octet + Off] & 0x04) >> 2);
00220                                         pie->FlowCtlRx = ieGetOctet((IBuf[Octet + Off] & 0x20) >> 1);
00221                                         Off++;
00222                                 }
00223                                 else if (pie->UIL1Prot == 0x08) { /* ITU V.120 */
00224                                         pie->HDR        = ieGetOctet((IBuf[Octet + Off] & 0x40) >> 6);
00225                                         pie->MultiFrame = ieGetOctet((IBuf[Octet + Off] & 0x20) >> 5);
00226                                         pie->Mode       = ieGetOctet((IBuf[Octet + Off] & 0x10) >> 4);
00227                                         pie->LLInegot   = ieGetOctet((IBuf[Octet + Off] & 0x08) >> 3);
00228                                         pie->Assignor   = ieGetOctet((IBuf[Octet + Off] & 0x04) >> 2);
00229                                         pie->InBandNeg  = ieGetOctet((IBuf[Octet + Off] & 0x02) >> 1);
00230                                         Off++;
00231                                 }
00232                                 else {
00233                                         Q931SetError(pTrunk,Q931E_BEARERCAP, 5,Off);
00234                                         return Q931E_BEARERCAP;
00235                                 }
00236 
00237                                 /* Octet 5c */
00238                                 if (IsQ931Ext(IBuf[Octet + Off - 1])) {
00239                                         pie->NumStopBits = ieGetOctet((IBuf[Octet + Off] & 0x60) >> 5);
00240                                         pie->NumDataBits = ieGetOctet((IBuf[Octet + Off] & 0x18) >> 3);
00241                                         pie->Parity      = ieGetOctet(IBuf[Octet + Off] & 0x07);
00242                                         Off++;
00243 
00244                                         /* Octet 5d */
00245                                         if (IsQ931Ext(IBuf[Octet + Off - 1])) {
00246                                                 pie->DuplexMode = ieGetOctet((IBuf[Octet + Off] & 0x40) >> 6);
00247                                                 pie->ModemType  = ieGetOctet(IBuf[Octet + Off] & 0x3f);
00248                                                 Off ++;
00249                                         }
00250                                 }
00251                         }
00252                 }
00253         }
00254 
00255         /* Octet 6 */
00256         if ((IBuf[Octet + Off] & 0x60) == 0x40 && Q931MoreIE()) {
00257                 pie->Layer2Ident = ieGetOctet((IBuf[Octet + Off] & 0x60) >> 5);
00258                 pie->UIL2Prot    = ieGetOctet(IBuf[Octet + Off] & 0x1f);
00259 
00260                 Off = Q931ReadExt(&IBuf[Octet + Off], Off);
00261                 Octet ++;
00262         }
00263 
00264         /* Octet 7 */
00265         if ((IBuf[Octet + Off] & 0x60) == 0x60 && Q931MoreIE()) {
00266                 pie->Layer3Ident = ieGetOctet((IBuf[Octet + Off] & 0x60) >> 5);
00267                 pie->UIL3Prot    = ieGetOctet(IBuf[Octet + Off] & 0x1f);
00268                 Octet++;
00269 
00270                 /* Octet 7a */
00271                 if (IsQ931Ext(IBuf[Octet + Off - 1])) {
00272                         if (pie->UIL3Prot == 0x0c) {
00273                                 pie->AL3Info1 = ieGetOctet(IBuf[Octet + Off] & 0x0f);
00274                                 Off++;
00275 
00276                                 /* Octet 7b */
00277                                 if (IsQ931Ext(IBuf[Octet + Off])) {
00278                                         pie->AL3Info2 = ieGetOctet(IBuf[Octet + Off] & 0x0f);
00279                                         Off++;
00280                                 }
00281                         }
00282                         else {
00283                                 Q931SetError(pTrunk,Q931E_BEARERCAP, 7, Off);
00284                                 return Q931E_BEARERCAP;
00285 
00286                         }
00287                 }
00288         }
00289 
00290         Q931IESizeTest(Q931E_BEARERCAP);
00291         Q931SetIE(*pIE, *OOff);
00292 
00293         *IOff = (*IOff) + Octet + Off;
00294         *OOff = (*OOff) + sizeof(Q931ie_BearerCap);
00295         pie->Size = sizeof(Q931ie_BearerCap);
00296 
00297         return Q931E_NO_ERROR;
00298 }
00299 
00300 /*****************************************************************************
00301 
00302   Function:      Q931Pie_BearerCap
00303 
00304   Description:  Packing a Q.931 Bearer Capability element from a generic 
00305                                 struct into a packed octet structure in accordance with the
00306                                 standard.
00307 
00308   Parameters:   IBuf[IN]                Ptr to struct.
00309                                 OBuf[OUT]               Ptr tp packed output buffer.
00310                                 Octet[IN/OUT]   Offset into OBuf.
00311 
00312   Return Value: Error code, 0 = OK
00313 
00314 *****************************************************************************/
00315 
00316 L3INT Q931Pie_BearerCap(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
00317 {
00318         Q931ie_BearerCap *pIE = (Q931ie_BearerCap*)IBuf;
00319         L3INT rc = 0;
00320         L3INT Beg = *Octet; /* remember current offset */
00321         L3INT li;
00322 
00323         Q931Log(pTrunk, Q931_LOG_DEBUG, "Encoding Bearer Capability IE\n");
00324 
00325         OBuf[(*Octet)++] = Q931ie_BEARER_CAPABILITY ;
00326         li = (*Octet)++; /* remember length position */
00327 
00328         /* Octet 3 - Coding standard / Information transfer capability */
00329         OBuf[(*Octet)++] = 0x80 | ((pIE->CodStand << 5) & 0x60) | (pIE->ITC & 0x1f);
00330 
00331         /* Octet 4 - Transfer mode / Information transfer rate */
00332         OBuf[(*Octet)++] = 0x80 | ((pIE->TransMode << 5) & 0x60) | (pIE->ITR & 0x1f);
00333 
00334         if (pIE->ITR == 0x18) {
00335                 /* Octet 4.1 - Rate Multiplier */
00336                 OBuf[(*Octet)++] = 0x80 | (pIE->RateMul & 0x7f);
00337         }
00338 
00339         /* Octet 5 - Layer 1 Ident / User information layer 1 protocol */
00340         if (pIE->Layer1Ident == 0x01) {
00341                 if (((pIE->ITC == 0x08) && (pIE->UIL1Prot == 0x01 || pIE->UIL1Prot == 0x08)) ||
00342                    ((pIE->ITC == 0x10) && (pIE->UIL1Prot == 0x02 || pIE->UIL1Prot == 0x03))) {
00343                         OBuf[(*Octet)++] = 0x00 | ((pIE->Layer1Ident << 5) & 0x60) | (pIE->UIL1Prot & 0x15);
00344                         
00345                         /* Octet 5a - SyncAsync/Negot/UserRate */
00346                         OBuf[(*Octet)++] = 0x00 | ((pIE->SyncAsync << 6) & 0x40) | ((pIE->Negot << 5) & 0x20) | (pIE->UserRate & 0x1f);
00347 
00348                         /* Octet 5b - one of two types */
00349                         if (pIE->UIL1Prot == 0x01) { /* ITU V.110, I.460 and X.30       */
00350                                 /* Octet 5b - Intermed rate/ Nic on Tx/Nix on Rx/FlowCtlTx/FlowCtlRx */
00351                                 OBuf[(*Octet)++] = 0x00 
00352                                                 | ((pIE->InterRate << 6) & 0x60)
00353                                                 | ((pIE->NIConTx   << 4) & 0x10)
00354                                                 | ((pIE->NIConRx   << 3) & 0x08)
00355                                                 | ((pIE->FlowCtlTx << 2) & 0x04)
00356                                                 | ((pIE->FlowCtlRx << 1) & 0x02);
00357                         }
00358                         else if (pIE->UIL1Prot == 0x08) { /* ITU V.120 */
00359                                 /* Octet 5b - HDR/Multiframe/Mode/LLINegot/Assignor/Inbandneg*/
00360                                 OBuf[(*Octet)++] = 0x00
00361                                                 | ((pIE->InterRate  << 6) & 0x60)
00362                                                 | ((pIE->MultiFrame << 5) & 0x20)
00363                                                 | ((pIE->Mode       << 4) & 0x10)
00364                                                 | ((pIE->LLInegot   << 3) & 0x08)
00365                                                 | ((pIE->Assignor   << 2) & 0x04)
00366                                                 | ((pIE->InBandNeg  << 1) & 0x02);
00367                         }
00368 
00369                         /* Octet 5c - NumStopBits/NumStartBits/Parity                                   */
00370                         OBuf[(*Octet)++] = 0x00
00371                                         | ((pIE->NumStopBits << 5) & 0x60)
00372                                         | ((pIE->NumDataBits << 3) & 0x18)
00373                                         | (pIE->Parity & 0x07);
00374 
00375                         /* Octet 5d - Duplex Mode/Modem Type */
00376                         OBuf[(*Octet)++] = 0x80 | ((pIE->DuplexMode << 6) & 0x40) | (pIE->ModemType & 0x3f);
00377                 }
00378                 else {
00379                         OBuf[(*Octet)++] = 0x80 | ((pIE->Layer1Ident << 5) & 0x60) | (pIE->UIL1Prot & 0x1f);
00380                 }
00381         }
00382 
00383         /* Octet 6 - Layer2Ident/User information layer 2 prtocol */
00384         if (pIE->Layer2Ident == 0x02) {
00385                 OBuf[(*Octet)++] = 0x80 | ((pIE->Layer2Ident << 5) & 0x60) | (pIE->UIL2Prot & 0x1f);
00386         }
00387 
00388         /* Octet 7 - Layer 3 Ident/ User information layer 3 protocol */
00389         if (pIE->Layer3Ident == 0x03) {
00390                 if (pIE->UIL3Prot == 0x0c) {
00391                         OBuf[(*Octet)++] = 0x00 | ((pIE->Layer3Ident << 5) & 0x60) | (pIE->UIL3Prot & 0x1f);
00392 
00393                         /* Octet 7a - Additional information layer 3 msb */
00394                         OBuf[(*Octet)++] = 0x00 | (pIE->AL3Info1 & 0x0f);
00395 
00396                         /* Octet 7b - Additional information layer 3 lsb */
00397                         OBuf[(*Octet)++] = 0x80 | (pIE->AL3Info2 & 0x0f);
00398                 }
00399                 else {
00400                         OBuf[(*Octet)++] = 0x80 | ((pIE->Layer3Ident << 5) & 0x60) | (pIE->UIL3Prot & 0x1f);
00401                 }
00402         }
00403 
00404         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
00405         return rc;
00406 }
00407 
00408 /*****************************************************************************
00409 
00410   Function:      Q931Uie_CallID
00411 
00412   Parameters:   pIE[OUT]                ptr to Information Element id.
00413                                 IBuf[IN]                ptr to a packed ie.
00414                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
00415                                 IOff[IN\OUT]    Input buffer offset
00416                                 OOff[IN\OUT]    Output buffer offset
00417 
00418 
00419                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
00420                                 must be updated, but are otherwise not used in the ie unpack.
00421 
00422   Return Value: Error Message
00423 
00424 *****************************************************************************/
00425 L3INT Q931Uie_CallID(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
00426 {
00427         Q931ie_CallID *pie = (Q931ie_CallID*)OBuf;
00428         ie *pIE = &pMsg->CallID;
00429         L3INT Off = 0;
00430         L3INT Octet = 0;
00431         L3INT x = 0;
00432         L3INT IESize;
00433 
00434         *pIE = 0;
00435 
00436         /* Octet 1 */
00437         pie->IEId = IBuf[Octet++];
00438 
00439         /* Octet 2 */
00440         IESize = IBuf[Octet++]; 
00441 
00442         /* Octet 3 */
00443         do {
00444                 pie->CallId[x] = IBuf[Octet + Off] & 0x7f;
00445                 Off++;
00446                 x++;
00447         } while (Q931MoreIE());
00448 
00449         Q931IESizeTest(Q931E_CALLID);
00450         Q931SetIE(*pIE, *OOff);
00451 
00452         *IOff = (*IOff) + Octet + Off;
00453         *OOff = (*OOff) + sizeof(Q931ie_CallID) + x - 1;
00454         pie->Size = (L3UCHAR)(sizeof(Q931ie_CallID) + x - 1);
00455 
00456         return Q931E_NO_ERROR;
00457 }
00458 
00459 /*****************************************************************************
00460 
00461   Function:      Q931Pie_CallID
00462 
00463   Parameters:   IBuf[IN]                Ptr to struct.
00464                                 OBuf[OUT]               Ptr tp packed output buffer.
00465                                 Octet[IN/OUT]   Offset into OBuf.
00466 
00467   Return Value: Error code, 0 = OK
00468 
00469 *****************************************************************************/
00470 
00471 L3INT Q931Pie_CallID(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
00472 {
00473         Q931ie_CallID *pIE = (Q931ie_CallID*)IBuf;
00474         L3INT rc = 0;
00475         L3INT Beg = *Octet;/* remember current offset */
00476         L3INT li;
00477         L3INT sCI = pIE->Size - sizeof(Q931ie_CallID) + 1;
00478         L3INT x;
00479 
00480         OBuf[(*Octet)++] = Q931ie_CALL_IDENTITY ;
00481         li = (*Octet)++; /* remember length position */
00482 
00483         for (x = 0; x < sCI; x++) {
00484                 OBuf[(*Octet)++] = pIE->CallId[x];
00485         }
00486 
00487         OBuf[(*Octet) - 1] |= 0x80; /* set complete flag at last octet*/
00488 
00489         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
00490         return rc;
00491 }
00492 
00493 /*****************************************************************************
00494 
00495   Function:      Q931Uie_CallState
00496 
00497   Parameters:   pIE[OUT]                ptr to Information Element id.
00498                                 IBuf[IN]                ptr to a packed ie.
00499                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
00500                                 IOff[IN\OUT]    Input buffer offset
00501                                 OOff[IN\OUT]    Output buffer offset
00502 
00503                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
00504                                 must be updated, but are otherwise not used in the ie unpack.
00505 
00506   Return Value: Error Message
00507 
00508 *****************************************************************************/
00509 L3INT Q931Uie_CallState(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
00510 {
00511         Q931ie_CallState *pie = (Q931ie_CallState*)OBuf;
00512         ie *pIE = &pMsg->CallState;
00513         L3INT Off = 0;
00514         L3INT Octet = 0;
00515         L3INT IESize;
00516 
00517         *pIE = 0;
00518 
00519         /* Octet 1 */
00520         pie->IEId = IBuf[Octet++];
00521 
00522         /* Octet 2 */
00523         IESize = IBuf[Octet++]; 
00524 
00525         /* Octet 3 */
00526         pie->CodStand  = (IBuf[Octet + Off] >> 6) & 0x03;
00527         pie->CallState =  IBuf[Octet + Off] & 0x3f;
00528         Octet++;
00529 
00530         Q931IESizeTest(Q931E_CALLSTATE);
00531         Q931SetIE(*pIE, *OOff);
00532 
00533         *IOff = (*IOff) + Octet + Off;
00534         *OOff = (*OOff) + sizeof(Q931ie_CallState);
00535         pie->Size = sizeof(Q931ie_CallState);
00536 
00537         return Q931E_NO_ERROR;
00538 }
00539 
00540 /*****************************************************************************
00541 
00542   Function:      Q931Pie_CallState
00543 
00544   Parameters:   IBuf[IN]                Ptr to struct.
00545                                 OBuf[OUT]               Ptr tp packed output buffer.
00546                                 Octet[IN/OUT]   Offset into OBuf.
00547 
00548   Return Value: Error code, 0 = OK
00549 
00550 *****************************************************************************/
00551 L3INT Q931Pie_CallState(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
00552 {
00553         Q931ie_CallState *pIE = (Q931ie_CallState*)IBuf;
00554         L3INT rc = 0;
00555         L3INT Beg = *Octet; /* remember current offset */
00556         L3INT li;
00557 
00558         OBuf[(*Octet)++] = Q931ie_CALL_STATE;
00559         li = (*Octet)++; /* remember length position */
00560 
00561         OBuf[(*Octet)++] = ((pIE->CodStand & 0x03) << 6) | (pIE->CallState & 0x3f);
00562 
00563         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
00564         return rc;
00565 }
00566 
00567 /*****************************************************************************
00568 
00569   Function:      Q931Uie_CalledSub
00570 
00571   Parameters:   pIE[OUT]                ptr to Information Element id.
00572                                 IBuf[IN]                ptr to a packed ie.
00573                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
00574                                 IOff[IN\OUT]    Input buffer offset
00575                                 OOff[IN\OUT]    Output buffer offset
00576 
00577                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
00578                                 must be updated, but are otherwise not used in the ie unpack.
00579 
00580   Return Value: Error Message
00581 
00582 *****************************************************************************/
00583 L3INT Q931Uie_CalledSub(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
00584 {
00585         Q931ie_CalledSub *pie = (Q931ie_CalledSub*)OBuf;
00586         ie *pIE = &pMsg->CalledSub;
00587         L3INT Off = 0;
00588         L3INT Octet = 0;
00589         L3INT x;
00590         L3INT IESize;
00591 
00592         *pIE = 0;
00593 
00594         /* Octet 1 */
00595         pie->IEId = IBuf[Octet++];
00596 
00597         /* Octet 2 */
00598         IESize = IBuf[Octet++]; 
00599 
00600         /* Octet 3 */
00601         pie->TypNum     = (IBuf[Octet + Off] >> 4) & 0x07;
00602         pie->OddEvenInd = (IBuf[Octet + Off] >> 3) & 0x01;
00603         Octet++;
00604         
00605         /* Octet 4 */
00606         x = 0;
00607         do {
00608                 pie->Digit[x] = IBuf[Octet + Off] & 0x7f;
00609                 Off++;
00610                 x++;
00611         } while (Q931MoreIE() && x < 20);
00612 
00613         Q931IESizeTest(Q931E_CALLEDSUB);
00614         Q931SetIE(*pIE, *OOff);
00615 
00616         *IOff = (*IOff) + Octet + Off;
00617         *OOff = (*OOff) + sizeof(Q931ie_CalledSub) + x - 1;
00618         pie->Size = (L3UCHAR)(sizeof(Q931ie_CalledSub) + x - 1);
00619 
00620         return Q931E_NO_ERROR;
00621 }
00622 
00623 /*****************************************************************************
00624 
00625   Function:      Q931Pie_CalledSub
00626 
00627   Parameters:   IBuf[IN]                Ptr to struct.
00628                                 OBuf[OUT]               Ptr tp packed output buffer.
00629                                 Octet[IN/OUT]   Offset into OBuf.
00630 
00631   Return Value: Error code, 0 = OK
00632 
00633 *****************************************************************************/
00634 L3INT Q931Pie_CalledSub(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
00635 {
00636         Q931ie_CalledSub *pIE = (Q931ie_CalledSub*)IBuf;
00637         L3INT rc = 0;
00638         L3INT Beg = *Octet;
00639         L3INT li;
00640         L3INT sN = pIE->Size - sizeof(Q931ie_CalledSub) + 1;
00641         L3INT x;
00642 
00643         /* Octet 1 */
00644         OBuf[(*Octet)++] = Q931ie_CALLED_PARTY_SUBADDRESS;
00645         li = (*Octet)++;
00646 
00647         /* Octet 3 */
00648         OBuf[(*Octet)++] = 0x80 | (pIE->TypNum << 4) | (pIE->OddEvenInd << 3);
00649         
00650         /* Octet 4 */
00651         for (x = 0; x<sN; x++) {
00652                 OBuf[(*Octet)++] = pIE->Digit[x];
00653         }
00654 
00655         OBuf[(*Octet) - 1] |= 0x80; /* Terminate bit */
00656 
00657         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
00658         return rc;
00659 }
00660 
00661 /*****************************************************************************
00662 
00663   Function:      Q931Uie_CalledNum
00664 
00665   Parameters:   pIE[OUT]                ptr to Information Element id.
00666                                 IBuf[IN]                ptr to a packed ie.
00667                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
00668                                 IOff[IN\OUT]    Input buffer offset
00669                                 OOff[IN\OUT]    Output buffer offset
00670 
00671                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
00672                                 must be updated, but are otherwise not used in the ie unpack.
00673 
00674   Return Value: Error Message
00675 
00676 *****************************************************************************/
00677 L3INT Q931Uie_CalledNum(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
00678 {
00679         Q931ie_CalledNum *pie = (Q931ie_CalledNum*)OBuf;
00680         ie *pIE = &pMsg->CalledNum;
00681         L3INT Off = 0;
00682         L3INT Octet = 0;
00683         L3INT x;
00684         L3INT IESize; /* # digits in this case */
00685 
00686         *pIE = 0;
00687 
00688         /* Octet 1 */
00689         pie->IEId = IBuf[Octet++];
00690 
00691         /* Octet 2 */
00692         IESize = IBuf[Octet++]; 
00693 
00694         /* Octet 3 */
00695         pie->TypNum    = (IBuf[Octet + Off] >> 4) & 0x07;
00696         pie->NumPlanID =  IBuf[Octet + Off] & 0x0f;
00697         Octet++;
00698 
00699         /* Octet 4*/
00700         x = 0;
00701         do {
00702                 pie->Digit[x] = IBuf[Octet + Off] & 0x7f;
00703                 Off++;
00704                 x++;
00705         } while ((IBuf[Octet + Off]&0x80) == 0 && Q931MoreIE());
00706 
00707         pie->Digit[x] = '\0';
00708 
00709         Q931SetIE(*pIE, *OOff);
00710 
00711         *IOff = (*IOff) + Octet + Off;
00712         *OOff = (*OOff) + sizeof(Q931ie_CalledNum) + x;
00713         pie->Size = (L3UCHAR)(sizeof(Q931ie_CalledNum) + x);
00714 
00715         return Q931E_NO_ERROR;
00716 }
00717 
00718 /*****************************************************************************
00719 
00720   Function:      Q931Pie_CalledNum
00721 
00722   Parameters:   IBuf[IN]                Ptr to struct.
00723                                 OBuf[OUT]               Ptr tp packed output buffer.
00724                                 Octet[IN/OUT]   Offset into OBuf.
00725 
00726   Return Value: Error code, 0 = OK
00727 
00728 *****************************************************************************/
00729 L3INT Q931Pie_CalledNum(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
00730 {
00731         Q931ie_CalledNum *pIE = (Q931ie_CalledNum*)IBuf;
00732         L3INT rc = 0;
00733         L3INT Beg = *Octet;
00734         L3INT li;
00735         L3INT sN = pIE->Size - sizeof(Q931ie_CalledNum);
00736         L3INT x;
00737 
00738         /* Octet 1 */
00739         OBuf[(*Octet)++] = Q931ie_CALLED_PARTY_NUMBER;
00740         
00741         /* Octet 2 */
00742         li = (*Octet)++;
00743 
00744         /* Octet 3 */
00745         OBuf[(*Octet)++] = 0x80 | (pIE->TypNum << 4) | (pIE->NumPlanID);
00746         
00747         /* Octet 4 */
00748         for (x = 0; x<sN; x++) {
00749                 OBuf[(*Octet)++] = pIE->Digit[x];
00750         }
00751 
00752         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
00753         return rc;
00754 }
00755 
00756 /*****************************************************************************
00757 
00758   Function:      Q931Uie_CallingNum
00759 
00760   Parameters:   pIE[OUT]                ptr to Information Element id.
00761                                 IBuf[IN]                ptr to a packed ie.
00762                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
00763                                 IOff[IN\OUT]    Input buffer offset
00764                                 OOff[IN\OUT]    Output buffer offset
00765 
00766                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
00767                                 must be updated, but are otherwise not used in the ie unpack.
00768 
00769   Return Value: Error Message
00770 
00771 *****************************************************************************/
00772 L3INT Q931Uie_CallingNum(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
00773 {
00774         Q931ie_CallingNum *pie = (Q931ie_CallingNum*)OBuf;
00775         ie *pIE = &pMsg->CallingNum;
00776         L3INT Off = 0;
00777         L3INT Octet = 0;
00778         L3INT x;
00779         L3INT IESize;
00780 
00781         *pIE = 0;
00782 
00783         /* Octet 1 */
00784         pie->IEId = IBuf[Octet++];
00785 
00786         /* Octet 2 */
00787         IESize = IBuf[Octet++]; 
00788 
00789         /* Octet 3 */
00790         pie->TypNum    = (IBuf[Octet + Off] >> 4) & 0x07;
00791         pie->NumPlanID =  IBuf[Octet + Off] & 0x0f;
00792 
00793         /* Octet 3a */
00794         if ((IBuf[Octet + Off] & 0x80) == 0) {
00795                 Off++;
00796                 pie->PresInd   = (IBuf[Octet + Off] >> 5) & 0x03;
00797                 pie->ScreenInd =  IBuf[Octet + Off] & 0x03;
00798         }
00799         Octet++;
00800 
00801         /* Octet 4 */
00802         x = 0;
00803         while (Q931MoreIE()) {
00804                 pie->Digit[x++] = IBuf[Octet + Off] & 0x7f;
00805 
00806                 if ((IBuf[Octet + Off] & 0x80) != 0) {
00807                         break;
00808                 }
00809                 Off++;
00810         }
00811         pie->Digit[x] = '\0';
00812 
00813         Q931IESizeTest(Q931E_CALLINGNUM);
00814         Q931SetIE(*pIE, *OOff);
00815 
00816         *IOff = (*IOff) + Octet + Off;
00817         *OOff = (*OOff) + sizeof(Q931ie_CallingNum) + x;
00818         pie->Size = (L3UCHAR)(sizeof(Q931ie_CallingNum) + x);
00819 
00820         return Q931E_NO_ERROR;
00821 }
00822 
00823 /*****************************************************************************
00824 
00825   Function:      Q931Pie_CallingNum
00826 
00827   Parameters:   IBuf[IN]                Ptr to struct.
00828                                 OBuf[OUT]               Ptr tp packed output buffer.
00829                                 Octet[IN/OUT]   Offset into OBuf.
00830 
00831   Return Value: Error code, 0 = OK
00832 
00833 *****************************************************************************/
00834 L3INT Q931Pie_CallingNum(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
00835 {
00836         Q931ie_CallingNum *pIE = (Q931ie_CallingNum*)IBuf;
00837         L3INT rc = 0;
00838         L3INT Beg = *Octet;
00839         L3INT li;
00840         L3INT sN = pIE->Size - sizeof(Q931ie_CallingNum);
00841         L3INT x;
00842 
00843         /* Octet 1 */
00844         OBuf[(*Octet)++] = Q931ie_CALLING_PARTY_NUMBER;
00845         
00846         /* Octet 2 */
00847         li = (*Octet)++;
00848 
00849         /* Octet 3 */
00850         OBuf[(*Octet)++] = 0x00 | (pIE->TypNum << 4) | (pIE->NumPlanID);
00851         
00852         /* Octet 4 */
00853         OBuf[(*Octet)++] = 0x80;
00854 
00855         /* Octet 5 */
00856         for (x = 0; x<sN; x++) {
00857                 OBuf[(*Octet)++] = pIE->Digit[x];
00858         }
00859 
00860         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
00861         return rc;
00862 }
00863 
00864 /*****************************************************************************
00865 
00866   Function:      Q931Uie_CallingSub
00867 
00868   Parameters:   pIE[OUT]                ptr to Information Element id.
00869                                 IBuf[IN]                ptr to a packed ie.
00870                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
00871                                 IOff[IN\OUT]    Input buffer offset
00872                                 OOff[IN\OUT]    Output buffer offset
00873 
00874                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
00875                                 must be updated, but are otherwise not used in the ie unpack.
00876 
00877   Return Value: Error Message
00878 
00879 *****************************************************************************/
00880 L3INT Q931Uie_CallingSub(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
00881 {
00882         Q931ie_CallingSub *pie = (Q931ie_CallingSub*)OBuf;
00883         ie *pIE = &pMsg->CallingSub;
00884         L3INT Off = 0;
00885         L3INT Octet = 0;
00886         L3INT x;
00887         L3INT IESize;
00888 
00889         *pIE = 0;
00890 
00891         /* Octet 1 */
00892         pie->IEId = IBuf[Octet++];
00893 
00894         /* Octet 2 */
00895         IESize = IBuf[Octet++]; 
00896 
00897         /* Octet 3 */
00898         pie->TypNum     = (IBuf[Octet + Off] >> 4) & 0x07;
00899         pie->OddEvenInd = (IBuf[Octet + Off] >> 3) & 0x01;
00900         Octet++;
00901         
00902         /* Octet 4*/
00903         x = 0;
00904         do {
00905                 pie->Digit[x] = IBuf[Octet + Off] & 0x7f;
00906                 Off++;
00907                 x++;
00908         } while (Q931MoreIE() && x < 20);
00909 
00910         Q931IESizeTest(Q931E_CALLINGSUB);
00911         Q931SetIE(*pIE, *OOff);
00912 
00913         *IOff = (*IOff) + Octet + Off;
00914         *OOff = (*OOff) + sizeof(Q931ie_CallingSub) + x -1;
00915         pie->Size = (L3UCHAR)(sizeof(Q931ie_CallingSub) + x -1);
00916 
00917         return Q931E_NO_ERROR;
00918 }
00919 
00920 /*****************************************************************************
00921 
00922   Function:      Q931Pie_CallingSub
00923 
00924   Parameters:   IBuf[IN]                Ptr to struct.
00925                                 OBuf[OUT]               Ptr tp packed output buffer.
00926                                 Octet[IN/OUT]   Offset into OBuf.
00927 
00928   Return Value: Error code, 0 = OK
00929 
00930 *****************************************************************************/
00931 L3INT Q931Pie_CallingSub(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
00932 {
00933         Q931ie_CallingSub *pIE = (Q931ie_CallingSub*)IBuf;
00934         L3INT rc = 0;
00935         L3INT Beg = *Octet;
00936         L3INT li;
00937         L3INT sN = pIE->Size - sizeof(Q931ie_CallingSub) + 1;
00938         L3INT x;
00939 
00940         /* Octet 1 */
00941         OBuf[(*Octet)++] = Q931ie_CALLING_PARTY_SUBADDRESS;
00942         li = (*Octet)++;
00943 
00944         /* Octet 3 */
00945         OBuf[(*Octet)++] = 0x80 | (pIE->TypNum << 4) | (pIE->OddEvenInd << 3);
00946         
00947         /* Octet 4 */
00948         for (x = 0; x<sN; x++) {
00949                 OBuf[(*Octet)++] = pIE->Digit[x];
00950         }
00951 
00952         OBuf[(*Octet) - 1] |= 0x80; /* Terminate bit */
00953 
00954         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
00955         return rc;
00956 }
00957 
00958 /*****************************************************************************
00959 
00960   Function:             Q931Uie_Cause
00961   
00962   Parameters:   pIE[OUT]                ptr to Information Element id.
00963                                 IBuf[IN]                ptr to a packed ie.
00964                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
00965                                 IOff[IN\OUT]    Input buffer offset
00966                                 OOff[IN\OUT]    Output buffer offset
00967 
00968                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
00969                                 must be updated, but are otherwise not used in the ie unpack.
00970 
00971   Return Value: Error Message
00972 
00973 *****************************************************************************/
00974 L3INT Q931Uie_Cause(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) 
00975 {
00976         Q931ie_Cause *pie = (Q931ie_Cause*)OBuf;
00977         ie *pIE = &pMsg->Cause;
00978         L3INT Off = 0;
00979         L3INT Octet = 0;
00980         L3INT IESize;
00981 
00982         *pIE = 0;
00983 
00984         pie->IEId = IBuf[Octet++];
00985 
00986         /* Octet 2*/
00987         IESize = IBuf[Octet++]; 
00988 
00989         /* Octet 3*/
00990         pie->CodStand = (IBuf[Octet + Off]>>5) & 0x03;
00991         pie->Location =  IBuf[Octet + Off] & 0x0f;
00992 
00993         /* Octet 3a */
00994         if ((IBuf[Octet + Off] & 0x80) == 0) {
00995                 Off++;
00996                 pie->Recom = IBuf[Octet + Off] & 0x7f;
00997         }
00998         Octet++;
00999 
01000         /* Octet 4 */
01001         pie->Value = IBuf[Octet + Off] & 0x7f;
01002         Octet++;
01003 
01004         /* Consume optional Diagnostic bytes */
01005         while (Q931MoreIE()) {
01006                 Off++;
01007         };
01008 
01009         Q931IESizeTest(Q931E_CAUSE);
01010         Q931SetIE(*pIE, *OOff);
01011 
01012         *IOff = (*IOff) + Octet + Off;
01013         *OOff = (*OOff) + sizeof(Q931ie_Cause);
01014         pie->Size = sizeof(Q931ie_Cause);
01015 
01016         return Q931E_NO_ERROR;
01017 }
01018 
01019 /*****************************************************************************
01020 
01021   Function:             Q931Pie_Cause
01022 
01023   Parameters:   IBuf[IN]                Ptr to struct.
01024                                 OBuf[OUT]               Ptr tp packed output buffer.
01025                                 Octet[IN/OUT]   Offset into OBuf.
01026 
01027   Return Value: Error code, 0 = OK
01028 
01029 *****************************************************************************/
01030 L3INT Q931Pie_Cause(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
01031 {
01032         Q931ie_Cause *pIE = (Q931ie_Cause*)IBuf;
01033         L3INT rc = 0;
01034         L3INT Beg = *Octet;
01035         L3INT li;
01036 
01037         OBuf[(*Octet)++] = Q931ie_CAUSE;
01038         li = (*Octet)++;
01039 
01040         /* Octet 3 */
01041         OBuf[(*Octet)++] = 0x80 | (pIE->CodStand<<5) | pIE->Location;
01042 
01043         /* Octet 3a - currently not supported in send */
01044 
01045         /* Octet 4 */
01046         OBuf[(*Octet)++] = 0x80 | pIE->Value;
01047 
01048         /* Octet 5 - diagnostics not supported in send */
01049 
01050         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
01051         return rc;
01052 }
01053 
01054 /*****************************************************************************
01055 
01056   Function:      Q931Uie_CongLevel
01057   
01058   Parameters:   pIE[OUT]                ptr to Information Element id.
01059                                 IBuf[IN]                ptr to a packed ie.
01060                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
01061                                 IOff[IN\OUT]    Input buffer offset
01062                                 OOff[IN\OUT]    Output buffer offset
01063 
01064                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
01065                                 must be updated, but are otherwise not used in the ie unpack.
01066 
01067   Return Value: Error Message
01068 
01069 *****************************************************************************/
01070 L3INT Q931Uie_CongLevel(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) 
01071 {
01072         Q931ie_CongLevel *pie = (Q931ie_CongLevel*)OBuf;
01073         ie *pIE = &pMsg->CongestionLevel;
01074         L3INT Off = 0;
01075         L3INT Octet = 0;
01076 
01077         *pIE = 0;
01078 
01079         pie->IEId      = IBuf[Octet] & 0xf0;
01080         pie->CongLevel = IBuf[Octet] & 0x0f;
01081         Octet ++;
01082 
01083         Q931SetIE(*pIE, *OOff);
01084 
01085         *IOff = (*IOff) + Octet + Off;
01086         *OOff = (*OOff) + sizeof(Q931ie_CongLevel);
01087         pie->Size = sizeof(Q931ie_CongLevel);
01088 
01089         return Q931E_NO_ERROR;
01090 }
01091 
01092 /*****************************************************************************
01093 
01094   Function:      Q931Pie_CongLevel
01095 
01096   Parameters:   IBuf[IN]                Ptr to struct.
01097                                 OBuf[OUT]               Ptr tp packed output buffer.
01098                                 Octet[IN/OUT]   Offset into OBuf.
01099 
01100   Return Value: Error code, 0 = OK
01101 
01102 *****************************************************************************/
01103 L3INT Q931Pie_CongLevel(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
01104 {
01105         Q931ie_CongLevel *pIE = (Q931ie_CongLevel*)IBuf;
01106         L3INT rc = 0;
01107         /* L3INT Beg = *Octet; */
01108 
01109         OBuf[(*Octet)++] = Q931ie_CONGESTION_LEVEL | pIE->CongLevel;
01110 
01111         return rc;
01112 }
01113 
01114 /*****************************************************************************
01115 
01116   Function:      Q931Uie_ChanID
01117 
01118   Parameters:   IBuf[IN]                ptr to a packed ie.
01119                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
01120                                 IOff[IN\OUT]    Input buffer offset
01121                                 OOff[IN\OUT]    Output buffer offset
01122 
01123                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
01124                                 must be updated, but are otherwise not used in the ie unpack.
01125 
01126   Return Value: Error code, 0 = OK
01127 
01128 *****************************************************************************/
01129 L3INT Q931Uie_ChanID(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR *OBuf, L3INT *IOff, L3INT *OOff)
01130 {
01131         Q931ie_ChanID *pie = (Q931ie_ChanID*)OBuf;
01132         ie *pIE = &pMsg->ChanID;
01133         L3INT Off = 0;
01134         L3INT Octet = 0;
01135         L3INT IESize;
01136 //18 04 e1 80 83 01
01137         *pIE = 0;
01138 
01139         Q931Log(pTrunk, Q931_LOG_DEBUG, "Decoding ChanID IE\n");
01140 
01141         /* Octet 1 */
01142         pie->IEId = IBuf[Octet++];
01143 
01144         /* Octet 2 */
01145         IESize    = IBuf[Octet++]; 
01146 
01147         /* Octet 3 */
01148         pie->IntIDPresent = (IBuf[Octet] >> 6) & 0x01;
01149         pie->IntType      = (IBuf[Octet] >> 5) & 0x01;
01150         pie->PrefExcl     = (IBuf[Octet] >> 3) & 0x01;
01151         pie->DChanInd     = (IBuf[Octet] >> 2) & 0x01;
01152         pie->InfoChanSel  =  IBuf[Octet] & 0x03;
01153 
01154         Off = Q931ReadExt(&IBuf[Octet++], Off);
01155 
01156         /* Octet 3.1 */
01157         if (pie->IntIDPresent) {
01158                 pie->InterfaceID = IBuf[Octet + Off] & 0x7f;
01159 
01160                 /* Temp fix. Interface id can be extended using the extension bit */
01161                 /* this will read the octets, but do nothing with them. this is done */
01162                 /* because the usage of this field is a little unclear */
01163                 /* 30.jan.2001/JVB */
01164                 Off = Q931ReadExt(&IBuf[Octet + Off], Off);
01165                 Off++;
01166         }
01167 
01168         if ((Octet + Off - 2) != IESize) {
01169                 /* Octet 3.2 */
01170                 if (pie->IntType == 1) {        /* PRI etc */
01171                         pie->CodStand    = (IBuf[Octet + Off] >> 5) & 0x03;
01172                         pie->NumMap      = (IBuf[Octet + Off] >> 4) & 0x01;
01173                         pie->ChanMapType =  IBuf[Octet + Off] & 0x0f;
01174                         Off++;
01175 
01176                         /* Octet 3.3 */
01177                         /* Temp fix. Assume B channel. H channels not supported */
01178                         pie->ChanSlot = IBuf[Octet + Off] & 0x7f;
01179 
01180                         /* Some dialects don't follow the extension coding properly for this, but this should be safe for all */
01181                         if ((Octet + Off - 1) != IESize) {
01182                                 Off = Q931ReadExt(&IBuf[Octet + Off], Off);
01183                         }
01184                         Off++;
01185                 }
01186         }
01187 
01188         Q931IESizeTest(Q931E_CHANID);
01189         Q931SetIE(*pIE, *OOff);
01190 
01191         *IOff = (*IOff) + Octet + Off;
01192         *OOff = (*OOff) + sizeof(Q931ie_ChanID);
01193         pie->Size = sizeof(Q931ie_ChanID);
01194 
01195         if (pTrunk->loglevel == Q931_LOG_DEBUG) {
01196                 const char *iface;
01197                 char tmp[100] = "";
01198 
01199                 if (!pie->IntType) {
01200                         switch (pie->InfoChanSel) {
01201                         case 0x0:
01202                                 iface = "None";
01203                                 break;
01204                         case 0x1:
01205                                 iface = "B1";
01206                                 break;
01207                         case 0x2:
01208                                 iface = "B2";
01209                                 break;
01210                         default:
01211                                 iface = "Any Channel";
01212                         }
01213 
01214                         snprintf(tmp, sizeof(tmp)-1, "InfoChanSel: %d (%s)", pie->InfoChanSel, iface);
01215                 }
01216 
01217                 Q931Log(pTrunk, Q931_LOG_DEBUG,
01218                         "\n-------------------------- Q.931 Channel ID ------------------------\n"
01219                         "    Pref/Excl: %s, Interface Type: %s\n"
01220                         "    %s\n"
01221                         "--------------------------------------------------------------------\n\n",
01222                         ((pie->PrefExcl) ? "Preferred" : "Exclusive"),
01223                         ((pie->IntType) ? "PRI/Other" : "BRI"),
01224                         tmp);
01225         }
01226         return Q931E_NO_ERROR;
01227 }
01228 
01229 /*****************************************************************************
01230 
01231   Function:      Q931Pie_ChanID
01232 
01233   Parameters:   IBuf[IN]                Ptr to struct.
01234                                 OBuf[OUT]               Ptr tp packed output buffer.
01235                                 Octet[IN/OUT]   Offset into OBuf.
01236 
01237   Return Value: Error code, 0 = OK
01238 
01239 *****************************************************************************/
01240 L3INT Q931Pie_ChanID(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
01241 {
01242         Q931ie_ChanID *pIE = (Q931ie_ChanID*)IBuf;
01243         L3INT rc = Q931E_NO_ERROR;
01244         L3INT Beg = *Octet;     /* remember current offset */
01245         L3INT li;
01246 
01247         OBuf[(*Octet)++] = Q931ie_CHANNEL_IDENTIFICATION;
01248         li = (*Octet)++; /* remember length position */
01249 
01250         /* Octet 3 flags & BRI chan # */
01251         OBuf[(*Octet)++] = 0x80 
01252                         | ((pIE->IntIDPresent << 6) & 0x40)
01253                         | ((pIE->IntType << 5) & 0x20)
01254                         | ((pIE->PrefExcl << 3) & 0x08)
01255                         |  (pIE->InfoChanSel & 0x03);
01256 
01257         /* Octet 3.1 - Interface Identifier */
01258         if (pIE->IntIDPresent) {
01259                 OBuf[(*Octet)++] = 0x80 | (pIE->InterfaceID & 0x7f);
01260         }
01261 
01262         /* Octet 3.2 & 3.3 - PRI */
01263         if (pIE->IntType) {
01264                 OBuf[(*Octet)++]  = 0x80
01265                         | ((pIE->CodStand << 5) & 0x60)
01266                         | ((pIE->NumMap << 4) & 0x10)
01267                         |  (pIE->ChanMapType & 0x0f);           /* TODO: support all possible channel map types */
01268 
01269                 /* Octet 3.3 Channel number */
01270                 switch (pIE->ChanMapType) {
01271                 case 0x6:       /* Slot map: H0 Channel Units */        /* unsupported, Octets 3.3.1 - 3.3.3 */
01272                         return Q931E_CHANID;
01273 
01274                 case 0x8:       /* Slot map: H11 Channel Units */
01275                 case 0x9:       /* Slot map: H12 Channel Units */
01276                 default:        /* Channel number */
01277                         OBuf[(*Octet)++] = 0x80 | (pIE->ChanSlot & 0x7f);
01278                         break;
01279                 }
01280         }
01281 
01282         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
01283         return rc;
01284 }
01285 
01286 
01287 /*****************************************************************************
01288 
01289   Function:      Q931Uie_CRV
01290 
01291   Description:  Reading CRV. 
01292 
01293                                 The CRV is currently returned in the return value that 
01294                                 Q921Rx23 will assign to the CRV field in the unpacked
01295                                 message. CRV is basically 2 bytes etc, but the spec allows
01296                                 the use of longer CRV values.
01297   
01298   Parameters:   pIE[OUT]                ptr to Information Element id.
01299                                 IBuf[IN]                ptr to a packed ie.
01300                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
01301                                 IOff[IN\OUT]    Input buffer offset
01302                                 OOff[IN\OUT]    Output buffer offset
01303 
01304                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
01305                                 must be updated, but are otherwise not used in the ie unpack.
01306 
01307   Return Value: CRV
01308 
01309 *****************************************************************************/
01310 L3USHORT Q931Uie_CRV(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *IOff, L3INT *OOff)
01311 {
01312         L3USHORT CRV = 0;
01313         L3INT Octet = *IOff;
01314         L3INT l = IBuf[Octet++]; 
01315 
01316         if (l == 1) {   /* One octet CRV */
01317                 CRV = IBuf[Octet++] & 0x7F;
01318         }
01319         else if (l == 2) {      /* two octet CRV */
01320                 CRV  = (IBuf[Octet++] & 0x7f) << 8;
01321                 CRV |=  IBuf[Octet++];
01322         }
01323         else {
01324                 /* Long CRV is not used, so we skip this */
01325                 /* TODO: is it right to set to 0 here? */
01326                 CRV = 0;
01327                 Octet += l;
01328         }
01329 
01330         *IOff = Octet;
01331         return CRV;
01332 }
01333 
01334 /*****************************************************************************
01335 
01336   Function:      Q931Uie_DateTime
01337 
01338   Parameters:   pTrunk          [IN]            Ptr to trunk information.
01339                                 pIE                     [OUT]       ptr to Information Element id.
01340                                 IBuf            [IN]            ptr to a packed ie.
01341                                 OBuf            [OUT]      ptr to buffer for Unpacked ie.
01342                                 IOff            [IN\OUT]        Input buffer offset
01343                                 OOff            [IN\OUT]        Output buffer offset
01344 
01345                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
01346                                 must be updated, but are otherwise not used in the ie unpack.
01347 
01348   Return Value: Error Message
01349 
01350 *****************************************************************************/
01351 L3INT Q931Uie_DateTime(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *IOff, L3INT *OOff)
01352 {
01353         Q931ie_DateTime * pie = (Q931ie_DateTime*)OBuf;
01354         ie *pIE = &pMsg->DateTime;
01355         L3INT Off = 0;
01356         L3INT Octet = 0;
01357         L3INT IESize = 0;
01358 
01359         *pIE = 0;
01360 
01361         pie->IEId = IBuf[Octet++];
01362         
01363         /* Octet 2 */
01364         IESize = IBuf[Octet++]; 
01365 
01366         /* Octet 3 - Year */
01367         pie->Year = IBuf[Octet++];
01368 
01369         /* Octet 4 - Month */
01370         pie->Month = IBuf[Octet++];
01371 
01372         /* Octet 5 - Day */
01373         pie->Day = IBuf[Octet++];
01374 
01375         /*******************************************************************
01376                 The remaining part of the IE are optioinal, but only the length 
01377                 can now tell us wherever these fields are present or not
01378                 (always remember: IESize does not include ID and Size octet)
01379         ********************************************************************/
01380         pie->Format = 0;
01381 
01382         /* Octet 6 - Hour (optional)*/
01383         if (IESize >= 4) {
01384                 pie->Format = 1;
01385                 pie->Hour = IBuf[Octet++];
01386 
01387                 /* Octet 7 - Minute (optional)*/
01388                 if (IESize >= 5) {
01389                         pie->Format = 2;
01390                         pie->Minute = IBuf[Octet++];
01391 
01392                         /* Octet 8 - Second (optional)*/
01393                         if (IESize >= 6) {
01394                                 pie->Format = 3;
01395                                 pie->Second = IBuf[Octet++];
01396                         }
01397                 }
01398         }
01399 
01400         Q931IESizeTest(Q931E_DATETIME);
01401         Q931SetIE(*pIE, *OOff);
01402 
01403         *IOff = (*IOff) + Octet + Off;
01404         *OOff = (*OOff) + sizeof(Q931ie_DateTime);
01405         pie->Size = sizeof(Q931ie_DateTime);
01406 
01407         return Q931E_NO_ERROR;
01408 }
01409 
01410 /*****************************************************************************
01411 
01412   Function:      Q931Pie_DateTime
01413 
01414   Parameters:   IBuf[IN]                Ptr to struct.
01415                                 OBuf[OUT]               Ptr tp packed output buffer.
01416                                 Octet[IN/OUT]   Offset into OBuf.
01417 
01418   Return Value: Error code, 0 = OK
01419 
01420 *****************************************************************************/
01421 L3INT Q931Pie_DateTime(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
01422 {
01423         Q931ie_DateTime *pIE = (Q931ie_DateTime*)IBuf;
01424         L3INT rc = 0;
01425         L3INT Beg = *Octet;
01426         L3INT li;
01427 
01428         OBuf[(*Octet)++] = Q931ie_DATETIME;
01429         li = (*Octet)++;
01430 
01431         OBuf[(*Octet)++] = pIE->Year;
01432         OBuf[(*Octet)++] = pIE->Month;
01433         OBuf[(*Octet)++] = pIE->Day;
01434         if (pIE->Format >= 1) {
01435                 OBuf[(*Octet)++] = pIE->Hour;
01436 
01437                 if (pIE->Format >= 2) {
01438                         OBuf[(*Octet)++] = pIE->Minute;
01439 
01440                         if (pIE->Format >= 3) {
01441                                 OBuf[(*Octet)++] = pIE->Second;
01442                         }
01443                 }
01444         }
01445 
01446         OBuf[li] = (L3UCHAR)((*Octet)-Beg) - 2;
01447         return rc;
01448 }
01449 
01450 /*****************************************************************************
01451 
01452   Function:      Q931Uie_Display
01453 
01454   Parameters:   pIE[OUT]                ptr to Information Element id.
01455                                 IBuf[IN]                ptr to a packed ie.
01456                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
01457                                 IOff[IN\OUT]    Input buffer offset
01458                                 OOff[IN\OUT]    Output buffer offset
01459 
01460                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
01461                                 must be updated, but are otherwise not used in the ie unpack.
01462 
01463   Return Value: Error Message
01464 
01465 *****************************************************************************/
01466 L3INT Q931Uie_Display(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
01467 {
01468         Q931ie_Display *pie = (Q931ie_Display*)OBuf;
01469         ie *pIE = &pMsg->Display;
01470         L3INT Off = 0;
01471         L3INT Octet = 0;
01472         L3INT IESize;
01473         L3INT x;
01474 
01475         *pIE = 0;
01476 
01477         pie->IEId = IBuf[Octet++];
01478         IESize    = IBuf[Octet++]; 
01479 
01480         for (x = 0; x<IESize; x++) {
01481                 pie->Display[x] = IBuf[Octet + Off] & 0x7f;
01482                 Off++;
01483         }
01484 
01485         Q931IESizeTest(Q931E_DISPLAY);
01486         Q931SetIE(*pIE, *OOff);
01487 
01488         *IOff = (*IOff) + Octet + Off;
01489         *OOff = (*OOff) + sizeof(Q931ie_Display) + x - 1;
01490         pie->Size = (L3UCHAR)(sizeof(Q931ie_Display) + x - 1);
01491 
01492         return Q931E_NO_ERROR;
01493 }
01494 
01495 /*****************************************************************************
01496 
01497   Function:      Q931Pie_Display
01498 
01499   Parameters:   IBuf[IN]                Ptr to struct.
01500                                 OBuf[OUT]               Ptr tp packed output buffer.
01501                                 Octet[IN/OUT]   Offset into OBuf.
01502 
01503   Return Value: Error code, 0 = OK
01504 
01505 *****************************************************************************/
01506 L3INT Q931Pie_Display(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
01507 {
01508         Q931ie_Display *pIE = (Q931ie_Display*)IBuf;
01509         L3INT rc = 0;
01510         L3INT Beg = *Octet;
01511         L3INT li;
01512         L3INT DSize;
01513         L3INT x;
01514 
01515         OBuf[(*Octet)++] = Q931ie_DISPLAY;
01516         li = (*Octet)++;
01517 
01518         DSize = pIE->Size - sizeof(Q931ie_Display);
01519 
01520         for (x = 0; x< DSize; x++) {
01521                 
01522                 OBuf[(*Octet)++] = pIE->Display[x];
01523         }
01524 
01525         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
01526         return rc;
01527 }
01528 
01529 /*****************************************************************************
01530 
01531   Function:      Q931Uie_HLComp
01532 
01533   Parameters:   pIE[OUT]                ptr to Information Element id.
01534                                 IBuf[IN]                ptr to a packed ie.
01535                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
01536                                 IOff[IN\OUT]    Input buffer offset
01537                                 OOff[IN\OUT]    Output buffer offset
01538 
01539                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
01540                                 must be updated, but are otherwise not used in the ie unpack.
01541 
01542   Return Value: Error Message
01543 
01544 *****************************************************************************/
01545 L3INT Q931Uie_HLComp(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff) 
01546 {
01547         Q931ie_HLComp * pie = (Q931ie_HLComp*)OBuf;
01548         ie *pIE = &pMsg->HLComp;
01549         L3INT Off = 0;
01550         L3INT Octet = 0;
01551         L3INT IESize;
01552 
01553         *pIE = 0;
01554 
01555         pie->IEId = IBuf[Octet++];
01556 
01557         /* Octet */
01558         IESize = IBuf[Octet++]; 
01559 
01560         /* Octet 3*/
01561         pie->CodStand  = (IBuf[Octet + Off] >>5) & 0x03;
01562         pie->Interpret = (IBuf[Octet + Off] >>2) & 0x07;
01563         pie->PresMeth  =  IBuf[Octet + Off] & 0x03;
01564         Octet++;
01565 
01566         /* Octet 4 */
01567         pie->HLCharID = IBuf[Octet + Off] & 0x7f;
01568         Octet++;
01569         
01570         /* Octet 4a*/
01571         if ((IBuf[Octet + Off - 1] & 0x80) == 0 && Q931MoreIE()) {
01572                 if (pie->HLCharID == 0x5e || pie->HLCharID == 0x5f) {
01573                         pie->EHLCharID = IBuf[Octet + Off] & 0x7f;
01574                         Off++;
01575                 }
01576                 else if ( pie->HLCharID >= 0xc3 && pie->HLCharID <= 0xcf) {
01577                         pie->EVideoTlfCharID = IBuf[Octet + Off] & 0x7f;
01578                         Off++;
01579                 }
01580                 else {
01581                         /* error Octet 4a indicated, but invalid value in Octet 4. */
01582                         Q931SetError(pTrunk,Q931E_HLCOMP, 4, Off);
01583                         return Q931E_HLCOMP;
01584                 }
01585                 Off = Q931ReadExt(&IBuf[Octet + Off], Off);
01586         }
01587 
01588         Q931IESizeTest(Q931E_HLCOMP);
01589         Q931SetIE(*pIE, *OOff);
01590 
01591         *IOff = (*IOff) + Octet + Off;
01592         *OOff = (*OOff) + sizeof(Q931ie_HLComp);
01593         pie->Size = sizeof(Q931ie_HLComp);
01594 
01595         return Q931E_NO_ERROR;
01596 }
01597 
01598 /*****************************************************************************
01599 
01600   Function:      Q931Pie_HLComp
01601 
01602   Parameters:   IBuf[IN]                Ptr to struct.
01603                                 OBuf[OUT]               Ptr tp packed output buffer.
01604                                 Octet[IN/OUT]   Offset into OBuf.
01605 
01606   Return Value: Error code, 0 = OK
01607 
01608 *****************************************************************************/
01609 L3INT Q931Pie_HLComp(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
01610 {
01611         Q931ie_HLComp *pIE = (Q931ie_HLComp*)IBuf;
01612         L3INT rc = 0;
01613         L3INT Beg = *Octet;
01614         L3INT li;
01615 
01616         OBuf[(*Octet)++] = Q931ie_HIGH_LAYER_COMPATIBILITY;
01617         li = (*Octet)++;
01618 
01619         /* Octet 3 */
01620         OBuf[(*Octet)++] = 0x80 | ((pIE->CodStand << 5) & 0x60) | ((pIE->Interpret << 2) & 0x1c) | (pIE->PresMeth & 0x03);
01621 
01622         /* Octet 4 */
01623         OBuf[(*Octet)++] = pIE->HLCharID;
01624 
01625         /* Octet 4a */
01626         if (pIE->HLCharID == 0x5e || pIE->HLCharID == 0x5f) {
01627                 OBuf[(*Octet)++] = 0x80 | (pIE->EHLCharID & 0x7f);
01628         }
01629         else if ( pIE->HLCharID >= 0xc3 && pIE->HLCharID <= 0xcf) {
01630                 OBuf[(*Octet)++] = 0x80 | (pIE->EVideoTlfCharID & 0x7f);
01631         }
01632         else {
01633                 OBuf[(*Octet) - 1] |= 0x80;
01634         }
01635 
01636         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
01637         return rc;
01638 }
01639 
01640 /*****************************************************************************
01641 
01642   Function:      Q931Uie_KeypadFac
01643 
01644   Parameters:   pIE[OUT]                ptr to Information Element id.
01645                                 IBuf[IN]                ptr to a packed ie.
01646                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
01647                                 IOff[IN\OUT]    Input buffer offset
01648                                 OOff[IN\OUT]    Output buffer offset
01649 
01650                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
01651                                 must be updated, but are otherwise not used in the ie unpack.
01652 
01653   Return Value: Error Message
01654 
01655 *****************************************************************************/
01656 L3INT Q931Uie_KeypadFac(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
01657 {
01658         Q931ie_KeypadFac *pie = (Q931ie_KeypadFac*)OBuf;
01659         ie *pIE = &pMsg->KeypadFac;
01660         L3INT Off = 0;
01661         L3INT Octet = 0;
01662         L3INT IESize;
01663         L3INT x;
01664 
01665         *pIE = 0;
01666 
01667         pie->IEId = IBuf[Octet++];
01668         IESize = IBuf[Octet++]; 
01669 
01670         for (x = 0; x<IESize; x++) {
01671                 pie->KeypadFac[x] = IBuf[Octet + Off] & 0x7f;
01672                 Off++;
01673         }
01674 
01675         Q931IESizeTest(Q931E_KEYPADFAC);
01676         Q931SetIE(*pIE, *OOff);
01677 
01678         *IOff = (*IOff) + Octet + Off;
01679         *OOff = (*OOff) + sizeof(Q931ie_KeypadFac) + x - 1;
01680         pie->Size = (L3UCHAR)(sizeof(Q931ie_KeypadFac) + x - 1);
01681 
01682         return Q931E_NO_ERROR;
01683 }
01684 
01685 /*****************************************************************************
01686 
01687   Function:      Q931Pie_KeypadFac
01688 
01689   Parameters:   IBuf[IN]                Ptr to struct.
01690                                 OBuf[OUT]               Ptr tp packed output buffer.
01691                                 Octet[IN/OUT]   Offset into OBuf.
01692 
01693   Return Value: Error code, 0 = OK
01694 
01695 *****************************************************************************/
01696 L3INT Q931Pie_KeypadFac(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
01697 {
01698         Q931ie_KeypadFac *pIE = (Q931ie_KeypadFac*)IBuf;
01699         L3INT rc = 0;
01700         L3INT Beg = *Octet;
01701         L3INT li;
01702         L3INT DSize;
01703         L3INT x;
01704 
01705         OBuf[(*Octet)++] = Q931ie_KEYPAD_FACILITY;
01706         li = (*Octet)++;
01707 
01708         DSize = pIE->Size - sizeof(Q931ie_KeypadFac) + 1;
01709 
01710         for (x = 0; x< DSize; x++) {
01711                 OBuf[(*Octet)++] = pIE->KeypadFac[x];
01712         }
01713 
01714         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
01715         return rc;
01716 }
01717 
01718 /*****************************************************************************
01719 
01720   Function:      Q931Uie_LLComp
01721 
01722   Parameters:   pIE[OUT]                ptr to Information Element id.
01723                                 IBuf[IN]                ptr to a packed ie.
01724                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
01725                                 IOff[IN\OUT]    Input buffer offset
01726                                 OOff[IN\OUT]    Output buffer offset
01727 
01728                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
01729                                 must be updated, but are otherwise not used in the ie unpack.
01730 
01731   Return Value: Error Message
01732 
01733 *****************************************************************************/
01734 L3INT Q931Uie_LLComp(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
01735 {
01736         Q931ie_LLComp *pie = (Q931ie_LLComp*)OBuf;
01737         ie *pIE = &pMsg->LLComp;
01738         L3INT Off = 0;
01739         L3INT Octet = 0;
01740         L3INT IESize;
01741 
01742         *pIE = 0;
01743 
01744         pie->IEId = IBuf[Octet++];
01745 
01746         /* Octet 2 */
01747         IESize = IBuf[Octet++]; 
01748 
01749         /* Octet 3 */
01750         pie->CodStand  = (IBuf[Octet + Off] >> 5) & 0x03;
01751         pie->ITransCap =  IBuf[Octet + Off] & 0x1f;
01752         Octet++;
01753 
01754         /* Octet 3a*/
01755         if (IsQ931Ext(IBuf[Octet + Off - 1])) {
01756                 pie->NegotInd = (IBuf[Octet + Off] >> 6) & 0x01;
01757                 Off++;
01758         }
01759 
01760         /* Octet 4 */
01761         pie->TransMode = (IBuf[Octet + Off] >> 5) & 0x03;
01762         pie->InfoRate  =  IBuf[Octet + Off] & 0x1f;
01763 
01764         Octet++;
01765 
01766         /* Octet 4.1 */
01767         if (pie->InfoRate == 0x14) { /* Mutirate */
01768                 pie->RateMul = IBuf[Octet + Off] & 0x7f;
01769                 Off++;
01770         }
01771 
01772         /* Octet 5 - Layer 1 Ident */
01773         if ((IBuf[Octet + Off] & 0x60) == 0x20) { /* Layer 1 Ident ? */
01774                 pie->Layer1Ident = (IBuf[Octet + Off] >> 5) & 0x03;
01775                 pie->UIL1Prot    =  IBuf[Octet + Off] & 0x1f;
01776                 Octet++;
01777 
01778                 /* Octet 5a */
01779                 if (IsQ931Ext(IBuf[Octet + Off - 1])) {
01780                         pie->SyncAsync = (IBuf[Octet + Off] >> 6) & 0x01;
01781                         pie->Negot     = (IBuf[Octet + Off] >> 5) & 0x01;
01782                         pie->UserRate  =  IBuf[Octet + Off] & 0x1f;
01783                         Off++;
01784 
01785                         /* Octet 5b - 2 options */
01786                         if (IsQ931Ext(IBuf[Octet + Off - 1])) {
01787                                 if (pie->UIL1Prot == 0x01) { /* V.110, I.460 and X.30*/
01788                                         pie->InterRate = (IBuf[Octet + Off] >> 5) & 0x03;
01789                                         pie->NIConTx   = (IBuf[Octet + Off] >> 4) & 0x01;
01790                                         pie->NIConRx   = (IBuf[Octet + Off] >> 3) & 0x01;
01791                                         pie->FlowCtlTx = (IBuf[Octet + Off] >> 2) & 0x01;
01792                                         pie->FlowCtlRx = (IBuf[Octet + Off] >> 1) & 0x01;
01793                                         Off++;
01794                                 }
01795                                 else if (pie->UIL1Prot == 0x80) { /* V.120 */
01796                                         pie->HDR        = (IBuf[Octet + Off] >> 6) & 0x01;
01797                                         pie->MultiFrame = (IBuf[Octet + Off] >> 5) & 0x01;
01798                                         pie->ModeL1     = (IBuf[Octet + Off] >> 4) & 0x01;
01799                                         pie->NegotLLI   = (IBuf[Octet + Off] >> 3) & 0x01;
01800                                         pie->Assignor   = (IBuf[Octet + Off] >> 2) & 0x01;
01801                                         pie->InBandNeg  = (IBuf[Octet + Off] >> 1) & 0x01;
01802                                         Off++;
01803                                 }
01804                                 else if (pie->UIL1Prot == 0x07) { /* non standard */
01805                                         Off = Q931ReadExt(&IBuf[Octet + Off], Off);
01806                                         Off++;
01807                                 }
01808                                 else {
01809                                         Q931SetError(pTrunk,Q931E_LLCOMP, 5,2);
01810                                         return Q931E_LLCOMP;
01811                                 }
01812 
01813                                 /* Octet 5c */
01814                                 if (IsQ931Ext(IBuf[Octet + Off - 1])) {
01815                                         pie->NumStopBits = (IBuf[Octet + Off] >> 5) & 0x03;
01816                                         pie->NumDataBits = (IBuf[Octet + Off] >> 3) & 0x03;
01817                                         pie->Parity      =  IBuf[Octet + Off] & 0x07;
01818                                         Off++;
01819 
01820                                         /* Octet 5d */
01821                                         if (IsQ931Ext(IBuf[Octet + Off - 1])) {
01822                                                 pie->DuplexMode = (IBuf[Octet + Off] >> 6) & 0x01;
01823                                                 pie->ModemType  =  IBuf[Octet + Off] & 0x3f;
01824                                                 Off = Q931ReadExt(&IBuf[Octet + Off], Off);
01825                                                 Off++;
01826                                         }
01827                                 }
01828                         }
01829                 }
01830         }
01831 
01832         /* Octet 6 - Layer 2 Ident */
01833         if ((IBuf[Octet + Off] & 0x60) == 0x40) { /* Layer 1 Ident ? */
01834                 pie->Layer2Ident = (IBuf[Octet + Off] >>5) & 0x03;
01835                 pie->UIL2Prot    =  IBuf[Octet + Off] & 0x1f;
01836                 Octet++;
01837 
01838                 /* Octet 6a */
01839                 if (IsQ931Ext(IBuf[Octet + Off - 1])) {
01840                         if (pie->UIL2Prot == 0x10) { /* 2nd 6a */
01841                                 pie->UsrSpcL2Prot = IBuf[Octet + Off] & 0x7f;
01842                                 Off++;
01843                         }
01844                         else { /* assume 1st 6a */
01845                                 pie->ModeL2  = (IBuf[Octet + Off] >> 5) & 0x03;
01846                                 pie->Q933use =  IBuf[Octet + Off] & 0x03;
01847                                 Off++;
01848                         }
01849                         /* Octet 6b */
01850                         if (IsQ931Ext(IBuf[Octet + Off - 1])) {
01851                                 pie->WindowSize = IBuf[Octet + Off] & 0x7f;
01852                                 Off++;
01853                         }
01854                 }
01855         }
01856 
01857         /* Octet 7 - layer 3 Ident */
01858         if ((IBuf[Octet + Off] & 0x60) == 0x60) { /* Layer 3 Ident ? */
01859                 pie->Layer3Ident = (IBuf[Octet + Off] >> 5) & 0x03;
01860                 pie->UIL3Prot    =  IBuf[Octet + Off] & 0x1f;
01861                 Octet++;
01862 
01863                 /* Octet 7a */
01864                 if (IsQ931Ext(IBuf[Octet + Off - 1])) {
01865                         if (pie->UIL3Prot == 0x0b) {
01866                                 /* Octet 7a + 7b AddL3Info */
01867                                 pie->AddL3Info = ((IBuf[Octet + Off] << 4) & 0xf0)
01868                                                                 | (IBuf[Octet + Off + 1] & 0x0f);
01869                                 Off += 2;
01870                         }
01871                         else {
01872                                 if (pie->UIL3Prot == 0x1f) {
01873                                         pie->ModeL3 = (IBuf[Octet + Off] >> 5) & 0x03;
01874                                         Off++;
01875                                 }
01876                                 else {
01877                                         pie->OptL3Info = IBuf[Octet + Off] & 0x7f;
01878                                         Off++;
01879                                 }
01880 
01881                                 /* Octet 7b*/
01882                                 if (IsQ931Ext(IBuf[Octet + Off - 1])) {
01883                                         pie->DefPackSize = IBuf[Octet + Off] & 0x0f;
01884                                         Off++;
01885 
01886                                         /* Octet 7c */
01887                                         if (IsQ931Ext(IBuf[Octet + Off - 1])) {
01888                                                 pie->PackWinSize= IBuf[Octet + Off] & 0x7f;
01889                                         }
01890                                 }
01891                         }
01892                 }
01893         }
01894 
01895         Q931IESizeTest(Q931E_LLCOMP);
01896         Q931SetIE(*pIE, *OOff);
01897 
01898         *IOff = (*IOff) + Octet + Off;
01899         *OOff = (*OOff) + sizeof(Q931ie_LLComp);
01900         pie->Size = sizeof(Q931ie_LLComp);
01901 
01902         return Q931E_NO_ERROR;
01903 }
01904 
01905 /*****************************************************************************
01906 
01907   Function:      Q931Pie_LLComp
01908 
01909   Parameters:   IBuf[IN]                Ptr to struct.
01910                                 OBuf[OUT]               Ptr tp packed output buffer.
01911                                 Octet[IN/OUT]   Offset into OBuf.
01912 
01913   Return Value: Error code, 0 = OK
01914 
01915 *****************************************************************************/
01916 L3INT Q931Pie_LLComp(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
01917 {
01918         Q931ie_LLComp *pIE = (Q931ie_LLComp*)IBuf;
01919         L3INT rc = 0;
01920         L3INT Beg = *Octet;
01921         L3INT li;
01922 
01923         OBuf[(*Octet)++] = Q931ie_LOW_LAYER_COMPATIBILITY;
01924         li = (*Octet)++;
01925 
01926         /* Octet 3 */
01927         OBuf[(*Octet)++] = (pIE->CodStand << 6) | pIE->ITransCap;
01928 
01929         /* Octet 3a */
01930         OBuf[(*Octet)++] = 0x80 | (pIE->NegotInd << 6);
01931 
01932         /* Octet 4 */
01933         OBuf[(*Octet)++] = 0x80 | (pIE->TransMode << 5) | pIE->InfoRate;
01934 
01935         /* Octet 4.1 */
01936         if (pIE->InfoRate == 0x18) {
01937                 OBuf[(*Octet)++] = 0x80 | pIE->RateMul;
01938         }
01939 
01940         /* Octet 5 */
01941         if (pIE->Layer1Ident == 0x01) {
01942                 OBuf[(*Octet)++] = (pIE->Layer1Ident << 5) | pIE->UIL1Prot;
01943                 
01944                 /* Octet 5a */
01945                 if ((pIE->ITransCap == 0x08 && (pIE->UIL1Prot == 0x01 || pIE->UIL1Prot == 0x08))
01946                         || (pIE->ITransCap == 0x10 && (pIE->UIL1Prot == 0x02 || pIE->UIL1Prot == 0x03))) {
01947                         OBuf[(*Octet)++] = (pIE->SyncAsync<<6) | (pIE->Negot<<5) | pIE->UserRate;
01948                         
01949                         /* Octet 5b*/
01950                         if (pIE->UIL1Prot == 0x01) {
01951                                 OBuf[(*Octet)++] =  (pIE->InterRate << 5)
01952                                                         | (pIE->NIConTx << 4)
01953                                                         | (pIE->NIConTx << 3)
01954                                                         | (pIE->FlowCtlTx << 2)
01955                                                         | (pIE->FlowCtlRx << 1);
01956                         }
01957                         else if (pIE->UIL1Prot == 0x08) {
01958                                 OBuf[(*Octet)++] =  (pIE->HDR << 6)
01959                                                         | (pIE->MultiFrame << 5)
01960                                                         | (pIE->ModeL1 << 4)
01961                                                         | (pIE->NegotLLI << 3)
01962                                                         | (pIE->Assignor << 2)
01963                                                         | (pIE->InBandNeg << 1);
01964                         }
01965                         else {
01966                                 OBuf[(*Octet) - 1] |= 0x80;
01967                         }
01968 
01969                         /* How to detect wherever 5c and 5d is to present is not clear
01970                          * but they have been inculded as 'standard'
01971                          * Octet 5c
01972                          */
01973                         if (pIE->UIL1Prot == 0x01 || pIE->UIL1Prot == 0x08) {
01974                                 OBuf[(*Octet)++] = (pIE->NumStopBits << 5) | (pIE->NumDataBits << 3) | pIE->Parity ;
01975 
01976                                 /* Octet 5d */
01977                                 OBuf[(*Octet)++] = 0x80 | (pIE->DuplexMode << 6) | pIE->ModemType;
01978                         }
01979                 }
01980                 else {
01981                         OBuf[(*Octet) - 1] |= 0x80;
01982                 }
01983         }
01984 
01985         /* Octet 6 */
01986         if (pIE->Layer2Ident == 0x02) {
01987                 OBuf[(*Octet)++] = (pIE->Layer2Ident << 5) | pIE->UIL2Prot;
01988 
01989                 /* Octet 6a*/
01990                 if (pIE->UIL2Prot == 0x02 /* Q.921/I.441 */
01991                 || pIE->UIL2Prot == 0x06 /* X.25 link layer */
01992                 || pIE->UIL2Prot == 0x07 /* X.25 multilink */
01993                 || pIE->UIL2Prot == 0x09 /* HDLC ARM */
01994                 || pIE->UIL2Prot == 0x0a /* HDLC NRM */
01995                 || pIE->UIL2Prot == 0x0b /* HDLC ABM */
01996                 || pIE->UIL2Prot == 0x0d /* X.75 SLP */
01997                 || pIE->UIL2Prot == 0x0e /* Q.922 */
01998                 || pIE->UIL2Prot == 0x11) { /* ISO/ECE 7776 DTE-DCE */
01999                         OBuf[(*Octet)++] = (pIE->ModeL2 << 5) | pIE->Q933use;
02000 
02001                         /* Octet 6b */
02002                         OBuf[(*Octet)++] = 0x80 | pIE->WindowSize;
02003                 }
02004                 else if (pIE->UIL2Prot == 0x10) { /* User Specific */
02005                         OBuf[(*Octet)++] = 0x80 | pIE->UsrSpcL2Prot;
02006                 }
02007                 else {
02008                         OBuf[(*Octet) - 1] |= 0x80;
02009                 }
02010         }
02011 
02012         /* Octet 7 */
02013         if (pIE->Layer3Ident == 0x03) {
02014                 OBuf[(*Octet)++] = (pIE->Layer3Ident << 5) | pIE->UIL3Prot;
02015 
02016                 /* Octet 7a - 3 different ones */
02017                 if (pIE->UIL3Prot == 0x10) {
02018                         OBuf[(*Octet++)] = 0x80 | pIE->OptL3Info;
02019                 }
02020                 else if (pIE->UIL3Prot == 0x06
02021                         ||  pIE->UIL3Prot == 0x07
02022                         ||  pIE->UIL3Prot == 0x08) {
02023                         OBuf[(*Octet)++] = pIE->ModeL3 << 5;
02024 
02025                         /* Octet 7b note 7 */
02026                         OBuf[(*Octet)++] = pIE->DefPackSize;
02027 
02028                         /* Octet 7c note 7 */
02029                         OBuf[(*Octet)++] = 0x80 | pIE->PackWinSize;
02030                 }
02031                 else if (pIE->UIL3Prot == 0x0b) {
02032                         OBuf[(*Octet)++] = (pIE->AddL3Info >> 4) & 0x0f;
02033                         OBuf[(*Octet)++] = 0x80 | (pIE->AddL3Info & 0x0f);
02034                 }
02035                 else {
02036                         OBuf[(*Octet) - 1] |= 0x80;
02037                 }
02038         }
02039         else {
02040                 Q931SetError(pTrunk,Q931E_LLCOMP, 7,0);
02041                 rc = Q931E_LLCOMP;
02042         }
02043 
02044         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
02045         return rc;
02046 }
02047 
02048 /*****************************************************************************
02049 
02050   Function:      Q931Uie_NetFac
02051 
02052   Parameters:   pIE[OUT]                ptr to Information Element id.
02053                                 IBuf[IN]                ptr to a packed ie.
02054                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
02055                                 IOff[IN\OUT]    Input buffer offset
02056                                 OOff[IN\OUT]    Output buffer offset
02057 
02058                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
02059                                 must be updated, but are otherwise not used in the ie unpack.
02060 
02061   Return Value: Error Message
02062 
02063 *****************************************************************************/
02064 L3INT Q931Uie_NetFac(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
02065 {
02066         Q931ie_NetFac *pie = (Q931ie_NetFac*)OBuf;
02067         ie *pIE = &pMsg->NetFac;
02068         L3INT Off = 0;
02069         L3INT Octet = 0;
02070         L3INT x = 0;
02071         L3INT IESize;
02072 
02073         *pIE = 0;
02074 
02075         pie->IEId = IBuf[Octet++];
02076 
02077         /* Octet 2 */
02078         IESize = IBuf[Octet++]; 
02079 
02080         pie->LenNetID = IBuf[Octet + Off]; /* full octet is used */
02081         Octet++;
02082 
02083         if (pie->LenNetID > 0) {
02084                 /* Octet 3.1 */
02085                 pie->TypeNetID = (IBuf[Octet + Off] >> 4) & 0x0f;
02086                 pie->NetIDPlan =  IBuf[Octet + Off] & 0x0f;
02087                 Off = Q931ReadExt(&IBuf[Octet], Off);
02088                 Off++;
02089 
02090                 /* Octet 3.2*/
02091                 for (x = 0; x < pie->LenNetID; x++) {
02092                         pie->NetID[x] = IBuf[Octet + Off] & 0x7f;
02093                         Off++;
02094                 }
02095         }
02096 
02097         /* Octet 4*/
02098         pie->NetFac = IBuf[Octet + Off]; /* Full Octet is used */
02099         Octet++;
02100 
02101         Q931IESizeTest(Q931E_NETFAC);
02102         Q931SetIE(*pIE, *OOff);
02103 
02104         *IOff = (*IOff) + Octet + Off;
02105         *OOff = (*OOff) + sizeof(Q931ie_NetFac) + x - 1;
02106         pie->Size = (L3UCHAR)(sizeof(Q931ie_NetFac) + x - 1);
02107 
02108         return Q931E_NO_ERROR;
02109 }
02110 
02111 /*****************************************************************************
02112 
02113   Function:      Q931Pie_NetFac
02114 
02115   Parameters:   IBuf[IN]                Ptr to struct.
02116                                 OBuf[OUT]               Ptr tp packed output buffer.
02117                                 Octet[IN/OUT]   Offset into OBuf.
02118 
02119   Return Value: Error code, 0 = OK
02120 
02121 *****************************************************************************/
02122 L3INT Q931Pie_NetFac(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
02123 {
02124         Q931ie_NetFac *pIE = (Q931ie_NetFac*)IBuf;
02125         L3INT rc = Q931E_NO_ERROR;
02126         L3INT Beg = *Octet;
02127         L3INT li;
02128         L3INT x;
02129 
02130         OBuf[(*Octet)++] = Q931ie_NETWORK_SPECIFIC_FACILITIES;
02131         li = (*Octet)++;
02132 
02133         /* Octet 3 */
02134         OBuf[(*Octet)++] = pIE->LenNetID;
02135 
02136         if (pIE->LenNetID > 0) {
02137                 /* Octet 3.1 */
02138                 OBuf[(*Octet)++] = 0x80 | (pIE->TypeNetID << 4) | pIE->NetIDPlan;
02139 
02140                 /* Octet 3.2 */
02141                 for (x = 0; x <pIE->LenNetID; x++) {
02142                         OBuf[(*Octet)++] = pIE->NetID[x];
02143                 }
02144         }
02145 
02146         /* Octet 4 */
02147         OBuf[(*Octet)++] = pIE->NetFac;
02148 
02149         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
02150         return rc;
02151 }
02152 
02153 /*****************************************************************************
02154 
02155   Function:             Q931Uie_NotifInd
02156 
02157   Parameters:   pIE[OUT]                ptr to Information Element id.
02158                                 IBuf[IN]                ptr to a packed ie.
02159                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
02160                                 IOff[IN\OUT]    Input buffer offset
02161                                 OOff[IN\OUT]    Output buffer offset
02162 
02163                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
02164                                 must be updated, but are otherwise not used in the ie unpack.
02165 
02166   Return Value: Error Message
02167 
02168 *****************************************************************************/
02169 L3INT Q931Uie_NotifInd(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
02170 {
02171         Q931ie_NotifInd *pie = (Q931ie_NotifInd*)OBuf;
02172         ie *pIE = &pMsg->NotifInd;
02173         L3INT Off = 0;
02174         L3INT Octet = 0;
02175         L3INT IESize;
02176 
02177         *pIE = 0;
02178 
02179         pie->IEId = IBuf[Octet++];
02180 
02181         /* Octet 2*/
02182         IESize = IBuf[Octet++]; 
02183 
02184         /* Octet 3 */
02185         pie->Notification = IBuf[Octet + Off] & 0x7f;
02186 
02187         Off = Q931ReadExt(&IBuf[Octet], Off);
02188         Octet++;
02189 
02190         Q931IESizeTest(Q931E_NOTIFIND);
02191         Q931SetIE(*pIE, *OOff);
02192 
02193         *IOff = (*IOff) + Octet + Off;
02194         *OOff = (*OOff) + sizeof(Q931ie_NotifInd);
02195         pie->Size = sizeof(Q931ie_NotifInd);
02196 
02197         return Q931E_NO_ERROR;
02198 }
02199 
02200 /*****************************************************************************
02201 
02202   Function:      Q931Pie_NotifInd
02203 
02204   Parameters:   IBuf[IN]                Ptr to struct.
02205                                 OBuf[OUT]               Ptr tp packed output buffer.
02206                                 Octet[IN/OUT]   Offset into OBuf.
02207 
02208   Return Value: Error code, 0 = OK
02209 
02210 *****************************************************************************/
02211 L3INT Q931Pie_NotifInd(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
02212 {
02213         Q931ie_NotifInd *pIE = (Q931ie_NotifInd*)IBuf;
02214         L3INT rc = Q931E_NO_ERROR;
02215         L3INT Beg = *Octet;
02216         L3INT li;
02217 
02218         OBuf[(*Octet)++] = Q931ie_NOTIFICATION_INDICATOR;
02219         li = (*Octet)++;
02220 
02221         /* Octet 3 */
02222         OBuf[(*Octet)++] = pIE->Notification;
02223 
02224         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
02225         return rc;
02226 }
02227 
02228 /*****************************************************************************
02229 
02230   Function:      Q931Uie_ProgInd
02231 
02232   Parameters:   pIE[OUT]                ptr to Information Element id.
02233                                 IBuf[IN]                ptr to a packed ie.
02234                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
02235                                 IOff[IN\OUT]    Input buffer offset
02236                                 OOff[IN\OUT]    Output buffer offset
02237 
02238                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
02239                                 must be updated, but are otherwise not used in the ie unpack.
02240 
02241   Return Value: Error Message
02242 
02243 *****************************************************************************/
02244 L3INT Q931Uie_ProgInd(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
02245 {
02246         Q931ie_ProgInd *pie = (Q931ie_ProgInd*)OBuf;
02247         ie *pIE = &pMsg->ProgInd;
02248         L3INT Off = 0;
02249         L3INT Octet = 0;
02250         L3INT IESize;
02251 
02252         *pIE = 0;
02253 
02254         pie->IEId = IBuf[Octet++];
02255 
02256         /* Octet 2 */
02257         IESize = IBuf[Octet++]; 
02258 
02259         /* Octet 3 */
02260         pie->CodStand = (IBuf[Octet + Off] >> 5) & 0x03;
02261         pie->Location =  IBuf[Octet + Off] & 0x0f;
02262 
02263         Off = Q931ReadExt(&IBuf[Octet], Off);
02264         Octet++;
02265 
02266         /* Octet 4 */
02267         pie->ProgDesc = IBuf[Octet + Off] & 0x7f;
02268         Off = Q931ReadExt(&IBuf[Octet], Off);
02269         Octet++;
02270 
02271         Q931IESizeTest(Q931E_PROGIND);
02272         Q931SetIE(*pIE, *OOff);
02273 
02274         *IOff = (*IOff) + Octet + Off;
02275         *OOff = (*OOff) + sizeof(Q931ie_ProgInd);
02276         pie->Size = sizeof(Q931ie_ProgInd);
02277 
02278         return Q931E_NO_ERROR;
02279 }
02280 
02281 /*****************************************************************************
02282 
02283   Function:      Q931Pie_ProgInd
02284 
02285   Parameters:   IBuf[IN]                Ptr to struct.
02286                                 OBuf[OUT]          Ptr tp packed output buffer.
02287                                 Octet[IN/OUT]   Offset L3INTo OBuf.
02288 
02289   Return Value: Error code, 0 = OK
02290 
02291 *****************************************************************************/
02292 L3INT Q931Pie_ProgInd(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
02293 {
02294         Q931ie_ProgInd *pIE = (Q931ie_ProgInd*)IBuf;
02295         L3INT rc = Q931E_NO_ERROR;
02296         L3INT Beg = *Octet;
02297         L3INT li;
02298 
02299         OBuf[(*Octet)++] = Q931ie_PROGRESS_INDICATOR;
02300         li = (*Octet)++;
02301 
02302         /* Octet 3 */
02303         OBuf[(*Octet)++] = 0x80 | (pIE->CodStand << 5) | pIE->Location;
02304 
02305         /* Octet 4 */
02306         OBuf[(*Octet)++] = 0x80 | pIE->ProgDesc;
02307 
02308         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
02309         return rc;
02310 }
02311 
02312 /*****************************************************************************
02313 
02314   Function:      Q931Uie_RepeatInd
02315 
02316   Parameters:   pIE[OUT]                ptr to Information Element id.
02317                                 IBuf[IN]                ptr to a packed ie.
02318                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
02319                                 IOff[IN\OUT]    Input buffer offset
02320                                 OOff[IN\OUT]    Output buffer offset
02321 
02322                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
02323                                 must be updated, but are otherwise not used in the ie unpack.
02324 
02325   Return Value: Error Message
02326 
02327 *****************************************************************************/
02328 L3INT Q931Uie_RepeatInd(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
02329 {
02330         Q931ie_RepeatInd *pie = (Q931ie_RepeatInd*)OBuf;
02331         ie *pIE = &pMsg->RepeatInd;
02332         L3INT Off = 0;
02333         L3INT Octet = 0;
02334 
02335         *pIE = 0;
02336 
02337         pie->IEId      = IBuf[Octet] & 0xf0;
02338         pie->RepeatInd = IBuf[Octet] & 0x0f;
02339         Octet ++;
02340 
02341         Q931SetIE(*pIE, *OOff);
02342 
02343         *IOff = (*IOff) + Octet + Off;
02344         *OOff = (*OOff) + sizeof(Q931ie_RepeatInd);
02345         pie->Size = sizeof(Q931ie_RepeatInd);
02346 
02347         return Q931E_NO_ERROR;
02348 }
02349 
02350 /*****************************************************************************
02351 
02352   Function:      Q931Pie_RepeatInd
02353 
02354   Parameters:   IBuf[IN]                Ptr to struct.
02355                                 OBuf[OUT]               Ptr tp packed output buffer.
02356                                 Octet[IN/OUT]   Offset into OBuf.
02357 
02358   Return Value: Error code, 0 = OK
02359 
02360 *****************************************************************************/
02361 L3INT Q931Pie_RepeatInd(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
02362 {
02363         Q931ie_RepeatInd *pIE = (Q931ie_RepeatInd*)IBuf;
02364         L3INT rc = 0;
02365         /* L3INT Beg = *Octet; */
02366 
02367         OBuf[(*Octet)++] = Q931ie_REPEAT_INDICATOR | pIE->RepeatInd;
02368 
02369         return rc;
02370 }
02371 
02372 /*****************************************************************************
02373 
02374   Function:      Q931Uie_RevChargeInd
02375 
02376   Parameters:   pIE[OUT]                ptr to Information Element id.
02377                                 IBuf[IN]                ptr to a packed ie.
02378                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
02379                                 IOff[IN\OUT]    Input buffer offset
02380                                 OOff[IN\OUT]    Output buffer offset
02381 
02382                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
02383                                 must be updated, but are otherwise not used in the ie unpack.
02384 
02385   Return Value: Error Message
02386 
02387 *****************************************************************************/
02388 L3INT Q931Uie_RevChargeInd(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
02389 {
02390         ie iE;
02391         /* ie *pIE = &pMsg->RevChargeInd; */
02392         Q931SetIE(iE, *OOff);
02393 
02394         return iE;
02395 }
02396 
02397 /*****************************************************************************
02398 
02399   Function:      Q931Pie_RevChargeInd
02400 
02401   Parameters:   IBuf[IN]                Ptr to struct.
02402                                 OBuf[OUT]               Ptr tp packed output buffer.
02403                                 Octet[IN/OUT]   Offset into OBuf.
02404 
02405   Return Value: Error code, 0 = OK
02406 
02407 *****************************************************************************/
02408 L3INT Q931Pie_RevChargeInd(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
02409 {
02410         L3BOOL RetCode = L3FALSE;
02411 
02412         NoWarning(OBuf);
02413         NoWarning(IBuf);
02414 
02415         return RetCode;
02416 }
02417 
02418 /*****************************************************************************
02419 
02420   Function:      Q931Uie_RestartInd
02421 
02422   Parameters:   pIE[OUT]                ptr to Information Element id.
02423                                 IBuf[IN]                ptr to a packed ie.
02424                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
02425                                 IOff[IN\OUT]    Input buffer offset
02426                                 OOff[IN\OUT]    Output buffer offset
02427 
02428                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
02429                                 must be updated, but are otherwise not used in the ie unpack.
02430 
02431   Return Value: Error Message
02432 
02433 *****************************************************************************/
02434 L3INT Q931Uie_RestartInd(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
02435 {
02436         Q931ie_RestartInd *pie = (Q931ie_RestartInd*)OBuf;
02437         ie *pIE = &pMsg->RestartInd;
02438         L3INT Off = 0;
02439         L3INT Octet = 0;
02440         L3INT IESize;
02441 
02442         *pIE = 0;
02443 
02444         pie->IEId = IBuf[Octet++];
02445 
02446         /* Octet 2 */
02447         IESize = IBuf[Octet++]; 
02448 
02449         /* Octet 3 */
02450         pie->Class = IBuf[Octet + Off] & 0x07;
02451         pie->Spare = IBuf[Octet + Off] & 0x70;
02452 
02453         Off = Q931ReadExt(&IBuf[Octet], Off);
02454         Octet++;
02455 
02456         Q931IESizeTest(Q931E_RESTARTIND);
02457         Q931SetIE(*pIE, *OOff);
02458 
02459         *IOff = (*IOff) + Octet + Off;
02460         *OOff = (*OOff) + sizeof(Q931ie_RestartInd);
02461         pie->Size = sizeof(Q931ie_RestartInd);
02462 
02463 
02464         return Q931E_NO_ERROR;
02465 }
02466 
02467 /*****************************************************************************
02468 
02469   Function:      Q931Pie_RestartInd
02470 
02471   Parameters:   IBuf[IN]                Ptr to struct.
02472                                 OBuf[OUT]               Ptr tp packed output buffer.
02473                                 Octet[IN/OUT]   Offset into OBuf.
02474 
02475   Return Value: Error code, 0 = OK
02476 
02477 *****************************************************************************/
02478 L3INT Q931Pie_RestartInd(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
02479 {
02480         Q931ie_RestartInd *pIE = (Q931ie_RestartInd*)IBuf;
02481         L3INT rc = Q931E_NO_ERROR;
02482         L3INT Beg = *Octet;
02483         L3INT li;
02484 
02485         OBuf[(*Octet)++] = Q931ie_RESTART_INDICATOR;
02486         li = (*Octet)++;
02487 
02488         /* Octet 3*/
02489         OBuf[(*Octet)++] = 0x80 | pIE->Class;
02490 
02491         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
02492         return rc;
02493 }
02494 
02495 /*****************************************************************************
02496 
02497   Function:      Q931Uie_Segment
02498 
02499   Parameters:   pIE[OUT]                ptr to Information Element id.
02500                                 IBuf[IN]                ptr to a packed ie.
02501                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
02502                                 IOff[IN\OUT]    Input buffer offset
02503                                 OOff[IN\OUT]    Output buffer offset
02504 
02505                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
02506                                 must be updated, but are otherwise not used in the ie unpack.
02507 
02508   Return Value: Error Message
02509 
02510 *****************************************************************************/
02511 L3INT Q931Uie_Segment(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
02512 {
02513         Q931ie_Segment *pie = (Q931ie_Segment*)OBuf;
02514         ie *pIE = &pMsg->Segment;
02515         L3INT Off = 0;
02516         L3INT Octet = 0;
02517         L3INT IESize;
02518 
02519         *pIE = 0;
02520 
02521         pie->IEId = IBuf[Octet++];
02522         Octet++;
02523 
02524         /* Octet 2*/
02525         IESize = IBuf[Octet++]; 
02526 
02527         /* Octet 3 */
02528         pie->FSI       = (IBuf[Octet + Off] & 0x80) >> 7;
02529         pie->NumSegRem =  IBuf[Octet + Off] & 0x7f;
02530         Octet++;
02531 
02532         /* Octet 4 */
02533         pie->SegType = IBuf[Octet + Off] & 0x7f;
02534         Octet++;
02535         
02536         Q931IESizeTest(Q931E_SEGMENT);
02537         Q931SetIE(*pIE, *OOff);
02538 
02539         *IOff = (*IOff) + Octet + Off;
02540         *OOff = (*OOff) + sizeof(Q931ie_Segment);
02541         pie->Size = sizeof(Q931ie_Segment);
02542 
02543         return Q931E_NO_ERROR;
02544 }
02545 
02546 /*****************************************************************************
02547 
02548   Function:      Q931Pie_Segment
02549 
02550   Parameters:   IBuf[IN]                Ptr to struct.
02551                                 OBuf[OUT]               Ptr tp packed output buffer.
02552                                 Octet[IN/OUT]   Offset into OBuf.
02553 
02554   Return Value: Error code, 0 = OK
02555 
02556 *****************************************************************************/
02557 L3INT Q931Pie_Segment(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
02558 {
02559         Q931ie_Segment *pIE = (Q931ie_Segment*)IBuf;
02560         L3INT rc = Q931E_NO_ERROR;
02561         L3INT Beg = *Octet;
02562         L3INT li;
02563 
02564         OBuf[(*Octet)++] = Q931ie_SEGMENTED_MESSAGE;
02565         li = (*Octet)++;
02566 
02567         /* Octet 3 */
02568         OBuf[(*Octet)++] = (pIE->FSI << 7) | pIE->NumSegRem;
02569 
02570         /* Octet 4 */
02571         OBuf[(*Octet)++] = pIE->SegType;
02572 
02573         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
02574         return rc;
02575 }
02576 
02577 /*****************************************************************************
02578 
02579   Function:             Q931Uie_SendComplete
02580 
02581   Parameters:   pIE[OUT]                ptr to Information Element id.
02582                                 IBuf[IN]                ptr to a packed ie.
02583                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
02584                                 IOff[IN\OUT]    Input buffer offset
02585                                 OOff[IN\OUT]    Output buffer offset
02586 
02587                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
02588                                 must be updated, but are otherwise not used in the ie unpack.
02589 
02590   Return Value: Error Message
02591 
02592 *****************************************************************************/
02593 L3INT Q931Uie_SendComplete(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
02594 {
02595         Q931ie_SendComplete *pie = (Q931ie_SendComplete*)OBuf;
02596         ie *pIE = &pMsg->SendComplete;
02597         L3INT Off = 0;
02598         L3INT Octet = 0;
02599 
02600         *pIE = 0;
02601         Octet++;
02602 
02603         Q931SetIE(*pIE, *OOff);
02604 
02605         *IOff = (*IOff) + Octet + Off;
02606         *OOff = (*OOff) + sizeof(Q931ie_SendComplete);
02607         pie->Size = sizeof(Q931ie_SendComplete);
02608 
02609         return Q931E_NO_ERROR;
02610 }
02611 
02612 /*****************************************************************************
02613 
02614   Function:      Q931Pie_ProgInd
02615 
02616   Parameters:   IBuf[IN]                Ptr to struct.
02617                                 OBuf[OUT]          Ptr tp packed output buffer.
02618                                 Octet[IN/OUT]   Offset into OBuf.
02619 
02620   Return Value: Error code, 0 = OK
02621 
02622 *****************************************************************************/
02623 L3INT Q931Pie_SendComplete(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
02624 {
02625         /* Q931ie_SendComplete * pIE = (Q931ie_SendComplete*)IBuf; */
02626         L3INT rc = Q931E_NO_ERROR;
02627         /* L3INT Beg = *Octet; */
02628 
02629         OBuf[(*Octet)++] = 0x80 | (L3UCHAR)Q931ie_SENDING_COMPLETE;
02630 
02631         return rc;
02632 }
02633 
02634 /*****************************************************************************
02635 
02636   Function:      Q931Uie_Signal
02637 
02638   Parameters:   pIE[OUT]                ptr to Information Element id.
02639                                 IBuf[IN]                ptr to a packed ie.
02640                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
02641                                 IOff[IN\OUT]    Input buffer offset
02642                                 OOff[IN\OUT]    Output buffer offset
02643 
02644                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
02645                                 must be updated, but are otherwise not used in the ie unpack.
02646 
02647   Return Value: Error Message
02648 
02649 *****************************************************************************/
02650 L3INT Q931Uie_Signal(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
02651 {
02652         Q931ie_Signal *pie = (Q931ie_Signal*)OBuf;
02653         ie *pIE = &pMsg->Signal;
02654         L3INT Off = 0;
02655         L3INT Octet = 0;
02656         L3INT IESize;
02657 
02658         *pIE = 0;
02659 
02660         pie->IEId = IBuf[Octet++];
02661 
02662         /* Octet 2 */
02663         IESize = IBuf[Octet++]; 
02664 
02665         /* Octet 3 */
02666         pie->Signal = IBuf[Octet + Off];
02667         Octet++;
02668 
02669         Q931IESizeTest(Q931E_SIGNAL);
02670         Q931SetIE(*pIE, *OOff);
02671 
02672         *IOff = (*IOff) + Octet + Off;
02673         *OOff = (*OOff) + sizeof(Q931ie_Signal);
02674         pie->Size = sizeof(Q931ie_Signal);
02675 
02676         return Q931E_NO_ERROR;
02677 }
02678 
02679 /*****************************************************************************
02680 
02681   Function:      Q931Pie_Signal
02682 
02683   Parameters:   IBuf[IN]                Ptr to struct.
02684                                 OBuf[OUT]               Ptr tp packed output buffer.
02685                                 Octet[IN/OUT]   Offset into OBuf.
02686 
02687   Return Value: Error code, 0 = OK
02688 
02689 *****************************************************************************/
02690 L3INT Q931Pie_Signal(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
02691 {
02692         Q931ie_Signal *pIE = (Q931ie_Signal*)IBuf;
02693         L3INT rc = Q931E_NO_ERROR;
02694         L3INT Beg = *Octet;
02695         L3INT li;
02696 
02697         OBuf[(*Octet)++] = Q931ie_SIGNAL;
02698         li = (*Octet)++;
02699 
02700         /* Octet 3 */
02701         OBuf[(*Octet)++] = pIE->Signal;
02702 
02703         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
02704         return rc;
02705 }
02706 
02707 /*****************************************************************************
02708 
02709   Function:      Q931Uie_TransNetSel
02710 
02711   Parameters:   pIE[OUT]                ptr to Information Element id.
02712                                 IBuf[IN]                ptr to a packed ie.
02713                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
02714                                 IOff[IN\OUT]    Input buffer offset
02715                                 OOff[IN\OUT]    Output buffer offset
02716 
02717                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
02718                                 must be updated, but are otherwise not used in the ie unpack.
02719 
02720   Return Value: Error Message
02721 
02722 *****************************************************************************/
02723 L3INT Q931Uie_TransNetSel(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
02724 {
02725         Q931ie_TransNetSel *pie = (Q931ie_TransNetSel*)OBuf;
02726         ie *pIE = &pMsg->TransNetSel;
02727         L3INT Off = 0;
02728         L3INT Octet = 0;
02729         L3INT x = 0;
02730         L3INT l;
02731 
02732         *pIE = 0;
02733 
02734         pie->IEId = IBuf[Octet++];
02735 
02736         /* Octet 2 */
02737         l = IBuf[Octet++] - 3; 
02738 
02739         /* Octet 3 */
02740         pie->Type = (IBuf[Octet + Off] >> 4) & 0x07;
02741 
02742         Off = Q931ReadExt(&IBuf[Octet], Off);
02743         Octet++;
02744 
02745         for (x = 0; x < l; x++) {
02746                 pie->NetID[x] = IBuf[Octet + Off] & 0x7f;
02747                 Off++;
02748         }
02749 
02750         Q931SetIE(*pIE, *OOff);
02751 
02752         *IOff = (*IOff) + Octet + Off;
02753         *OOff = (*OOff) + sizeof(Q931ie_TransNetSel) + x - 1;
02754         pie->Size = (L3UCHAR)(sizeof(Q931ie_TransNetSel) + x - 1);
02755 
02756         return Q931E_NO_ERROR;
02757 }
02758 
02759 /*****************************************************************************
02760 
02761   Function:      Q931Pie_TransNetSel
02762 
02763   Parameters:   IBuf[IN]                Ptr to struct.
02764                                 OBuf[OUT]               Ptr tp packed output buffer.
02765                                 Octet[IN/OUT]   Offset into OBuf.
02766 
02767   Return Value: Error code, 0 = OK
02768 
02769 *****************************************************************************/
02770 L3INT Q931Pie_TransNetSel(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
02771 {
02772         Q931ie_TransNetSel *pIE = (Q931ie_TransNetSel*)IBuf;
02773         L3INT rc = Q931E_NO_ERROR;
02774         L3INT Beg = *Octet;
02775         L3INT li;
02776         L3INT x;
02777         L3INT l;
02778 
02779         OBuf[(*Octet)++] = Q931ie_TRANSIT_NETWORK_SELECTION;
02780         li = (*Octet)++;
02781 
02782         /* Octet 3 */
02783         OBuf[(*Octet)++] = 0x80 | (pIE->Type << 4) | pIE->NetIDPlan;
02784 
02785         /* Octet 4 */
02786         l = pIE->Size - sizeof(Q931ie_TransNetSel) + 1;
02787         for (x = 0; x < l; x++) {
02788                 OBuf[(*Octet)++] = pIE->NetID[x];
02789         }
02790 
02791         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
02792         return rc;
02793 }
02794 
02795 /*****************************************************************************
02796 
02797   Function:      Q931Uie_UserUser
02798 
02799   Parameters:   pIE[OUT]                ptr to Information Element id.
02800                                 IBuf[IN]                ptr to a packed ie.
02801                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
02802                                 IOff[IN\OUT]    Input buffer offset
02803                                 OOff[IN\OUT]    Output buffer offset
02804 
02805                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
02806                                 must be updated, but are otherwise not used in the ie unpack.
02807 
02808   Return Value: Error Message
02809 
02810 *****************************************************************************/
02811 L3INT Q931Uie_UserUser(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
02812 {
02813         Q931ie_UserUser *pie = (Q931ie_UserUser*)OBuf;
02814         ie *pIE = &pMsg->UserUser;
02815         L3INT Off = 0;
02816         L3INT Octet = 0;
02817         L3INT x = 0;
02818         L3INT l;
02819 
02820         *pIE = 0;
02821 
02822         pie->IEId = IBuf[Octet++];
02823 
02824         /* Octet 2 */
02825         l = IBuf[Octet++] - 3; 
02826 
02827         /* Octet 3 */
02828         pie->ProtDisc = IBuf[Octet + Off];
02829         Octet++;
02830 
02831         for (x = 0; x < l; x++) {
02832                 pie->User[x] = IBuf[Octet + Off];
02833                 Off++;
02834         }
02835 
02836         Q931SetIE(*pIE, *OOff);
02837 
02838         *IOff = (*IOff) + Octet + Off;
02839         *OOff = (*OOff) + sizeof(Q931ie_UserUser) + x - 1;
02840         pie->Size = (L3UCHAR)(sizeof(Q931ie_UserUser) + x - 1);
02841 
02842         return Q931E_NO_ERROR;
02843 }
02844 
02845 /*****************************************************************************
02846 
02847   Function:      Q931Pie_UserUser
02848 
02849   Parameters:   IBuf[IN]                Ptr to struct.
02850                                 OBuf[OUT]               Ptr tp packed output buffer.
02851                                 Octet[IN/OUT]   Offset into OBuf.
02852 
02853   Return Value: Error code, 0 = OK
02854 
02855 *****************************************************************************/
02856 L3INT Q931Pie_UserUser(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
02857 {
02858         Q931ie_UserUser *pIE = (Q931ie_UserUser*)IBuf;
02859         L3INT rc = Q931E_NO_ERROR;
02860         L3INT Beg = *Octet;
02861         L3INT li;
02862         L3INT x;
02863         L3INT l;
02864 
02865         OBuf[(*Octet)++] = Q931ie_USER_USER;
02866         li = (*Octet)++;
02867 
02868         /* Octet 3 */
02869         OBuf[(*Octet)++] = pIE->ProtDisc;
02870 
02871         /* Octet 4 */
02872         l = pIE->Size - sizeof(Q931ie_UserUser) + 1;
02873         for (x = 0; x < l; x++) {
02874                 OBuf[(*Octet)++] = pIE->User[x];
02875         }
02876 
02877         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
02878         return rc;
02879 }
02880 
02881 /*****************************************************************************
02882 
02883   Function:      Q931Uie_GenericDigits
02884 
02885   Parameters:   pIE[OUT]                ptr to Information Element id.
02886                                 IBuf[IN]                ptr to a packed ie.
02887                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
02888                                 IOff[IN\OUT]    Input buffer offset
02889                                 OOff[IN\OUT]    Output buffer offset
02890 
02891 
02892                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
02893                                 must be updated, but are otherwise not used in the ie unpack.
02894 
02895   Return Value: Error Message
02896 
02897 *****************************************************************************/
02898 L3INT Q931Uie_GenericDigits(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
02899 {
02900         Q931ie_GenericDigits *pie = (Q931ie_GenericDigits*)OBuf;
02901         ie *pIE = &pMsg->GenericDigits;
02902         L3INT Off = 0;
02903         L3INT Octet = 0;
02904         L3INT x;
02905         L3INT IESize;
02906 
02907         *pIE = 0;
02908 
02909         /* Octet 1 */
02910         pie->IEId = IBuf[Octet++];
02911 
02912         /* Octet 2 */
02913         IESize = IBuf[Octet++]; 
02914 
02915         /* Octet 3 */
02916         pie->Type     = (IBuf[Octet]) & 0x1F;
02917         pie->Encoding = (IBuf[Octet] >> 5) & 0x07;
02918         Octet++;
02919         
02920         /* Octet 4*/
02921         if (pie->Encoding == 0) { /* BCD Even */
02922                 x = 0;
02923                 do {
02924                         pie->Digit[x++] =  IBuf[Octet + Off] & 0x0f;
02925                         pie->Digit[x++] = (IBuf[Octet + Off] >> 4) & 0x0f;
02926                         Off++;
02927                 } while (Q931MoreIE());
02928         } else if (pie->Encoding == 1) { /* BCD Odd */
02929                 x = 0;
02930                 do {
02931                         pie->Digit[x++] = IBuf[Octet + Off] & 0x0f;
02932                         if (Q931MoreIE()) {
02933                                 pie->Digit[x] = (IBuf[Octet + Off] >> 4) & 0x0f;
02934                         }
02935                         x++;
02936                         Off++;
02937                 } while (Q931MoreIE());
02938         } else if (pie->Encoding == 2) { /* IA5 */
02939                 x = 0;
02940                 do {
02941                         pie->Digit[x++] = IBuf[Octet + Off] & 0x7f;
02942                         Off++;
02943                 } while (Q931MoreIE());
02944         } else {
02945                 /* Binary encoding type unkown */
02946                 Q931SetError(pTrunk, Q931E_GENERIC_DIGITS, Octet, Off);
02947                 return Q931E_GENERIC_DIGITS;
02948         }
02949 
02950         Q931IESizeTest(Q931E_GENERIC_DIGITS);
02951         Q931SetIE(*pIE, *OOff);
02952 
02953         *IOff = (*IOff) + Octet + Off;
02954         *OOff = (*OOff) + sizeof(Q931ie_CallingSub) + x - 1;
02955         pie->Size = (L3UCHAR)(sizeof(Q931ie_CallingSub) + x - 1);
02956 
02957         return Q931E_NO_ERROR;
02958 }
02959 
02960 /*****************************************************************************
02961 
02962   Function:      Q931Pie_GenericDigits
02963 
02964   Parameters:   IBuf[IN]                Ptr to struct.
02965                                 OBuf[OUT]               Ptr tp packed output buffer.
02966                                 Octet[IN/OUT]   Offset into OBuf.
02967 
02968   Return Value: Error code, 0 = OK
02969 
02970 *****************************************************************************/
02971 
02972 L3INT Q931Pie_GenericDigits(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
02973 {
02974         OBuf[(*Octet)++] = (Q931ie_GENERIC_DIGITS & 0xFF);
02975         OBuf[(*Octet)++] = 0;
02976 
02977         return Q931E_NO_ERROR;
02978 }
02979 
02980 /*****************************************************************************
02981 
02982   Function:      Q931Uie_ChangeStatus
02983 
02984   Parameters:   pIE[OUT]                ptr to Information Element id.
02985                                 IBuf[IN]                ptr to a packed ie.
02986                                 OBuf[OUT]          ptr to buffer for Unpacked ie.
02987                                 IOff[IN\OUT]    Input buffer offset
02988                                 OOff[IN\OUT]    Output buffer offset
02989 
02990                                 Ibuf and OBuf points directly to buffers. The IOff and OOff
02991                                 must be updated, but are otherwise not used in the ie unpack.
02992 
02993   Return Value: Error Message
02994 
02995 *****************************************************************************/
02996 L3INT Q931Uie_ChangeStatus(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
02997 {
02998         Q931ie_ChangeStatus *pie = (Q931ie_ChangeStatus*)OBuf;
02999         ie *pIE = &pMsg->ChangeStatus;
03000         L3INT Off = 0;
03001         L3INT Octet = 0;
03002         L3INT IESize;
03003 
03004         *pIE = 0;
03005 
03006         pie->IEId = IBuf[Octet++];
03007 
03008         /* Octet 2 */
03009         IESize = IBuf[Octet++]; 
03010 
03011         /* Octet 3 */
03012         pie->Preference = (IBuf[Octet + Off] >> 6) & 0x01;
03013         pie->Spare      =  IBuf[Octet + Off] & 0x38;
03014         pie->NewStatus  =  IBuf[Octet + Off] & 0x07;
03015         Octet++;
03016 
03017         Q931SetIE(*pIE, *OOff);
03018 
03019         *IOff = (*IOff) + Octet + Off;
03020         *OOff = (*OOff) + sizeof(Q931ie_ChangeStatus);
03021         pie->Size = sizeof(Q931ie_ChangeStatus);
03022 
03023         return Q931E_NO_ERROR;
03024 }
03025 
03026 /*****************************************************************************
03027 
03028   Function:      Q931Pie_ChangeStatus
03029 
03030   Parameters:   IBuf[IN]                Ptr to struct.
03031                                 OBuf[OUT]               Ptr tp packed output buffer.
03032                                 Octet[IN/OUT]   Offset into OBuf.
03033 
03034   Return Value: Error code, 0 = OK
03035 
03036 *****************************************************************************/
03037 L3INT Q931Pie_ChangeStatus(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
03038 {
03039         Q931ie_ChangeStatus *pIE = (Q931ie_ChangeStatus*)IBuf;
03040         L3INT rc = Q931E_NO_ERROR;
03041         L3INT Beg = *Octet;
03042         L3INT li;
03043 
03044         OBuf[(*Octet)++] = Q931ie_CHANGE_STATUS;
03045         li = (*Octet)++;
03046 
03047         /* Octet 3 */
03048         OBuf[(*Octet)++] = 0x80 | pIE->NewStatus | ((pIE->Preference & 0x01) << 6);
03049 
03050         OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
03051         return rc;
03052 }
03053 
03054 
03055 
03056 L3INT Q931Uie_Generic(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *IOff, L3INT *OOff)
03057 {
03058         L3INT Octet = 0;
03059         L3UCHAR id = 0;
03060 
03061         /* id */
03062         id = IBuf[Octet++];
03063 
03064         /* Length */
03065         if (!(id & 0x80)) {
03066                 Octet += IBuf[Octet];
03067                 Octet++;
03068 
03069                 Q931Log(pTrunk, Q931_LOG_DEBUG, "Discarding IE %#hhx with length %d\n", id, Octet - 2);
03070         } else {
03071                 Q931Log(pTrunk, Q931_LOG_DEBUG, "Discarding single Octet IE %#hhx\n", id);
03072         }
03073 
03074 
03075         *IOff += Octet;
03076         return Q931E_NO_ERROR;
03077 }
03078 
03079 L3INT Q931Pie_Generic(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
03080 {
03081         /* do nothing */
03082         return Q931E_NO_ERROR;
03083 }

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