Home | History | Annotate | Download | only in src
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 // ----------------------------------------------------------------------
     19 //
     20 // This Software is an original work of authorship of PacketVideo Corporation.
     21 // Portions of the Software were developed in collaboration with NTT  DoCoMo,
     22 // Inc. or were derived from the public domain or materials licensed from
     23 // third parties.  Title and ownership, including all intellectual property
     24 // rights in and to the Software shall remain with PacketVideo Corporation
     25 // and NTT DoCoMo, Inc.
     26 //
     27 // -----------------------------------------------------------------------
     28 // ============================================================
     29 // FILE: GenericPER.c
     30 //
     31 // DESCRIPTION: Generic PER encode/decode routines.  These are
     32 //   called by the automatically generated MiniParser code.
     33 //
     34 // Written by Ralph Neff, PacketVideo, 2/8/2000
     35 // (c) 2000 PacketVideo Corp.
     36 // ============================================================
     37 
     38 #include "per_headers.h"
     39 #include "analyzeper.h"
     40 #include "genericper.h"
     41 #include "oscl_error_codes.h"
     42 #include "oscl_mem.h"
     43 #include "oscl_stdstring.h"
     44 #include "pvlogger.h"
     45 
     46 #define STREAM_ADDITION 64      /* Output stream grows in increments */
     47 /*   of this many bytes.             */
     48 
     49 const uint8 MaskBit[] = { 0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01 };
     50 
     51 /***********************************************************/
     52 /*=========================================================*/
     53 /*============ DECODING ROUTINES (Generic PER) ============*/
     54 /*=========================================================*/
     55 /***********************************************************/
     56 
     57 /* --------------------------------------------- */
     58 /* ------------- LOW LEVEL STREAM -------------- */
     59 /* --------------------------------------------- */
     60 
     61 // =========================================================
     62 // ErrorMessage()
     63 //
     64 // This function is a generic error call for PER routines.
     65 //
     66 // NOTE: Removed the MessageBox called and replaced with a
     67 //   call to the analyzer via Show245().  Since tag informaion
     68 //   isn't easy to get (encoder/decoder autogen routines don't
     69 //   provide tags, and deleter autogen routines don't even have
     70 //   a tag defined!), we will fix to the "PER Decoder" tag for
     71 //   now.  The proper thing to do would be to use a newly
     72 //   defined "PER Error" tag.  But it's not so important to
     73 //   do this, since the source of the error is always defined
     74 //   in the message itself.  (RAN-MessageBox)  10/5/01
     75 // =========================================================
     76 void ErrorMessage(const char *msg)
     77 {
     78     OSCL_UNUSED_ARG(msg);
     79 
     80     PVLogger *logger = PVLogger::GetLoggerObject("3g324m.h245.per");
     81     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, logger, PVLOGMSG_ERR, (0, "GenericPer::ErrorMessage - %s", msg));
     82 }
     83 
     84 void ErrorMessageAndLeave(const char *msg)
     85 {
     86     ErrorMessage(msg);
     87     PVLogger *logger = PVLogger::GetLoggerObject("3g324m.h245.per");
     88     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, logger, PVLOGMSG_ERR, (0, "GenericPer::ErrorMessageAndLeave - LEAVE"));
     89     OSCL_LEAVE(OsclErrCorrupt);
     90 }
     91 
     92 // =========================================================
     93 // ReadBits()
     94 //
     95 // This function reads some number of bits from the
     96 // input stream.
     97 // =========================================================
     98 uint8 ReadBits(uint32 number, PS_InStream stream)
     99 {
    100     uint8 x;
    101     uint8 NextBit, BitSize;
    102 
    103     if (number > 8)
    104     {
    105         ErrorMessageAndLeave("ReadBits(): Max number (8) exceeded");
    106     }
    107 
    108     BitSize = (uint8)(stream->bitIndex + number);
    109     x = (uint8)(stream->data[0] & MaskBit[(int)stream->bitIndex ]);
    110     if (BitSize > 8)
    111     {
    112         NextBit = (uint8)(BitSize - 8);
    113         x <<= NextBit;
    114         ++stream->data;
    115         x |= ((stream->data[0]) & ~MaskBit[(int)stream->bitIndex ]) >> (8 - NextBit);
    116     }
    117     else if (BitSize < 8)
    118     {
    119         NextBit = BitSize;
    120         x >>= (8 - NextBit);
    121     }
    122     else
    123     {
    124         NextBit = 0;
    125         ++stream->data;
    126     }
    127 
    128     stream->bitIndex = NextBit;
    129     return(x);
    130 }
    131 
    132 // =========================================================
    133 // ReadRemainingBits()
    134 //
    135 // This function advances to the next octet boundary in
    136 // the input stream.  If the stream already points to
    137 // an octet boundary, no action is taken.
    138 // =========================================================
    139 void  ReadRemainingBits(PS_InStream stream)
    140 {
    141     if (stream->bitIndex)
    142     {
    143         stream->bitIndex = 0;
    144         ++stream->data;
    145     }
    146 }
    147 
    148 // =========================================================
    149 // ReadOctets()
    150 //
    151 // This function reads one or more octets from the input
    152 // stream.  Input arguments are:
    153 //   uint32 number;        /* Number of octets to read */
    154 //   uint8* octets;      /* Destination for octets */
    155 //   uint8 reorder;      /* Reorder for little-endian machine? */
    156 //   PS_InStream stream; /* Input stream */
    157 // =========================================================
    158 void  ReadOctets(uint32 number, uint8* octets, uint8 reorder, PS_InStream stream)
    159 {
    160     ReadRemainingBits(stream);  /* Octet alignment */
    161 
    162     if (number == 0)   /* No action */
    163     {
    164         return;
    165     }
    166     else if (number <= 4 && reorder)   /* Apply reordering */
    167     {
    168         switch (number)
    169         {
    170             case 1:
    171                 octets[0] = stream->data[0];
    172                 break;
    173             case 2:
    174                 octets[0] = stream->data[1];
    175                 octets[1] = stream->data[0];
    176                 break;
    177             case 3:
    178                 octets[0] = stream->data[2];
    179                 octets[1] = stream->data[1];
    180                 octets[2] = stream->data[0];
    181                 break;
    182             case 4:
    183                 octets[0] = stream->data[3];
    184                 octets[1] = stream->data[2];
    185                 octets[2] = stream->data[1];
    186                 octets[3] = stream->data[0];
    187                 break;
    188         }
    189     }
    190     else
    191     {
    192         oscl_memcpy(octets, stream->data, number);  /* Straight copy */
    193     }
    194 
    195     stream->data += number;
    196 }
    197 
    198 
    199 /* --------------------------------------------- */
    200 /* ------------ HIGH LEVEL ASN DATA ------------ */
    201 /* --------------------------------------------- */
    202 
    203 
    204 // =========================================================
    205 // GetBoolean()
    206 //
    207 // This function reads a boolean from the input stream.
    208 // =========================================================
    209 uint8 GetBoolean(PS_InStream stream)
    210 {
    211     return(ReadBits(1, stream));
    212 }
    213 
    214 // =========================================================
    215 // GetInteger()                           X.691 Section 10.5
    216 //
    217 // This function decodes a constrained integer, given the
    218 // lower/upper bounds.  Note that bounds are uint32, which
    219 // means min>=0, max<=4294967295.
    220 // Assumes ALIGNED variant of PER.
    221 // =========================================================
    222 uint32  GetInteger(uint32 lower, uint32 upper, PS_InStream stream)
    223 {
    224     uint32 value = 0, range;
    225     uint8 nbits, nbytes = 0;
    226 
    227     if (lower > upper)
    228     {
    229         ErrorMessageAndLeave("GetInteger(): Range is negative.");
    230         return(lower);
    231     }
    232     range = upper - lower + 1;
    233 
    234     if (range == 0)     /* Special case: int32EGER(0..4294967295) */
    235     {
    236         nbytes = (uint8)(ReadBits(2, stream) + 1);
    237         ReadOctets(nbytes, (uint8*)&value, 1, stream);
    238         return(value);
    239     }
    240     else if (range == 1)            /* 0-bits */
    241         return(lower);
    242     else if (range < 256)           /* Bit-field cases */
    243     {
    244         if (range <= 2) nbits = 1;
    245         else if (range <= 4) nbits = 2;
    246         else if (range <= 8) nbits = 3;
    247         else if (range <= 16) nbits = 4;
    248         else if (range <= 32) nbits = 5;
    249         else if (range <= 64) nbits = 6;
    250         else if (range <= 128) nbits = 7;
    251         else nbits = 8;
    252         value = ReadBits(nbits, stream);
    253         if (lower + value > upper)
    254         {
    255             ErrorMessageAndLeave("GetInteger(): Integer exceeds range");
    256         }
    257         return(lower + value);
    258     }
    259     else                            /* One or more octets */
    260     {
    261         if (range == 256) nbytes = 1;
    262         else if (range <= 65536) nbytes = 2;
    263         else nbytes = (uint8)(ReadBits(2, stream) + 1);
    264         ReadOctets(nbytes, (uint8*)&value, 1, stream);
    265         if (lower + value > upper)
    266         {
    267             ErrorMessageAndLeave("GetInteger(): exceeds range");
    268         }
    269         return(lower + value);
    270     }
    271 }
    272 
    273 // =========================================================
    274 // GetSignedInteger()                     X.691 Section 10.5
    275 //
    276 // This function decodes a constrained integer, given the
    277 // lower/upper bounds.  The only difference from GetInteger()
    278 // is that the bounds and returned values are int32, and
    279 // so may be negative.
    280 // Assumes ALIGNED variant of PER.
    281 // =========================================================
    282 int32   GetSignedInteger(int32 lower, int32 upper, PS_InStream stream)
    283 {
    284     int32 value = 0, range;
    285     uint8 nbits, nbytes = 0;
    286 
    287     if (lower > upper)
    288     {
    289         ErrorMessageAndLeave("GetSignedInteger(): Range is negative.");
    290         return(lower);
    291     }
    292     range = upper - lower + 1;
    293 
    294     if (range == 0)
    295     {
    296         ErrorMessageAndLeave("GetSignedInteger(): Range is zero.");
    297         return(lower);
    298     }
    299     else if (range == 1)            /* 0-bits */
    300         return(lower);
    301     else if (range < 256)           /* Bit-field cases */
    302     {
    303         if (range <= 2) nbits = 1;
    304         else if (range <= 4) nbits = 2;
    305         else if (range <= 8) nbits = 3;
    306         else if (range <= 16) nbits = 4;
    307         else if (range <= 32) nbits = 5;
    308         else if (range <= 64) nbits = 6;
    309         else if (range <= 128) nbits = 7;
    310         else nbits = 8;
    311         value = ReadBits(nbits, stream);
    312         if (lower + value > upper)
    313         {
    314             ErrorMessageAndLeave("GetSignedInteger(): Integer exceeds range");
    315         }
    316         return(lower + value);
    317     }
    318     else                            /* One or more octets */
    319     {
    320         if (range == 256) nbytes = 1;
    321         else if (range <= 65536) nbytes = 2;
    322         else nbytes = (uint8)(ReadBits(2, stream) + 1);
    323         ReadOctets(nbytes, (uint8*)&value, 1, stream);
    324         if (lower + value > upper)
    325         {
    326             ErrorMessageAndLeave("GetSignedInteger(): GetInteger exceeds range");
    327         }
    328         return(lower + value);
    329     }
    330 }
    331 
    332 // =========================================================
    333 // GetUnboundedInteger()                   X.691 Section 12
    334 //                                         and also 10.4, 10.9.
    335 //
    336 // This function decodes an unbounded integer.  The structure
    337 // definition can only accomodate a uint32 return type, so if
    338 // the decoded value is negative, we signal an error.
    339 // Assumes ALIGNED variant of PER.
    340 // =========================================================
    341 uint32  GetUnboundedInteger(PS_InStream stream)
    342 {
    343     uint32 nbytes, value = 0;
    344 
    345     nbytes = GetLengthDet(stream);               // Length Det (10.9)
    346     ReadOctets(nbytes, (uint8*)&value, 1, stream);  // Value (10.4)
    347 
    348     // Check for negative value
    349     if ((nbytes == 1 && value >= 0x7f) ||
    350             (nbytes == 2 && value >= 0x8000) ||
    351             (nbytes == 3 && value >= 0x800000) ||
    352             (nbytes == 4 && value >= 0x80000000))
    353     {
    354         ErrorMessageAndLeave("GetUnboundedInteger: Found a negative value!");
    355     }
    356 
    357     return(value);
    358 }
    359 
    360 // =========================================================
    361 // GetExtendedInteger()                   X.691 Section 12.1
    362 //
    363 // This function decodes a constrained integer with an
    364 // extended range.  We assume the value is unsigned, and
    365 // that the ALIGNED variant of PER is used.
    366 // =========================================================
    367 uint32  GetExtendedInteger(uint32 lower, uint32 upper, PS_InStream stream)
    368 {
    369     uint32 extension_bit, value;
    370 
    371     extension_bit = ReadBits(1, stream);
    372     if (extension_bit)
    373     {
    374         value = GetUnboundedInteger(stream);
    375     }
    376     else
    377     {
    378         value = GetInteger(lower, upper, stream);
    379     }
    380 
    381     return(value);
    382 }
    383 
    384 // =========================================================
    385 // GetOctetString()                      X.691 Section 16
    386 //
    387 // This function reads an OCTET STRING from the input stream.
    388 // Bounds on the size, if any, are included in the input
    389 // arguments.
    390 // =========================================================
    391 void GetOctetString(uint8 unbounded, uint32 min, uint32 max,
    392                     PS_OCTETSTRING x, PS_InStream stream)
    393 {
    394     if (unbounded)         /* ====Size is unbounded==== */
    395     {
    396         x->size = (uint16) GetLengthDet(stream);
    397         if (x->size)
    398         {
    399             x->data = (uint8*) OSCL_DEFAULT_MALLOC(x->size * sizeof(uint8));
    400             ReadOctets(x->size, x->data, 0, stream);
    401         }
    402         else
    403         {
    404             x->data = NULL;
    405         }
    406     }
    407     else                   /* ====Size is bounded==== */
    408     {
    409 
    410         if (min > max)            /* Error handling */
    411         {
    412             ErrorMessageAndLeave("GetOctetString(): Constraint error (min>max)");
    413         }
    414 
    415         if (min == max)           /* Fixed size (no length det!) */
    416         {
    417             x->size = (uint16) min;
    418             if (x->size)
    419             {
    420                 x->data = (uint8*) OSCL_DEFAULT_MALLOC(x->size * sizeof(uint8));
    421                 if (x->size > 2)
    422                 {
    423                     ReadOctets(x->size, x->data, 0, stream);
    424                 }
    425                 else if (x->size == 2)
    426                 {
    427                     x->data[0] = ReadBits(8, stream);
    428                     x->data[1] = ReadBits(8, stream);
    429                 }
    430                 else if (x->size == 1)
    431                 {
    432                     x->data[0] = ReadBits(8, stream);
    433                 }
    434             }
    435             else
    436             {
    437                 x->data = NULL;
    438             }
    439         }
    440         else                      /* Constrained size */
    441         {
    442             x->size = (uint16) GetInteger(min, max, stream);
    443             if (x->size)
    444             {
    445                 x->data = (uint8*) OSCL_DEFAULT_MALLOC(x->size * sizeof(uint8));
    446                 ReadOctets(x->size, x->data, 0, stream);
    447             }
    448             else
    449             {
    450                 x->data = NULL;
    451             }
    452         }
    453     }
    454 }
    455 
    456 // =========================================================
    457 // GetBitString()                      X.691 Section 16
    458 //
    459 // This function reads a BIT STRING from the input stream.
    460 // Bounds on the size, if any, are included in the input
    461 // arguments.  The BITSTRING structure (x) is returned.
    462 // =========================================================
    463 void GetBitString(uint8 unbounded, uint32 min, uint32 max,
    464                   PS_BITSTRING x, PS_InStream stream)
    465 {
    466     uint32 count;
    467     uint8* temp;
    468 
    469     if (unbounded)         /* ====Size is unbounded==== */
    470     {
    471         count = GetLengthDet(stream);
    472         x->size = (uint16) count;
    473         temp = x->data = (uint8*) OSCL_DEFAULT_MALLOC((1 + x->size / 8) * sizeof(uint8));
    474         while (count >= 8)
    475         {
    476             temp[0] = ReadBits(8, stream);
    477             ++temp;
    478             count -= 8;
    479         }
    480         temp[0] = (uint8)(ReadBits(count, stream) << (8 - count));
    481     }
    482     else                   /* ====Size is bounded==== */
    483     {
    484 
    485         if (min > max)            /* Error handling */
    486         {
    487             ErrorMessageAndLeave("GetBitString(): Constraint error (min>max)");
    488         }
    489 
    490         if (min == max)           /* Fixed size (no length det!) */
    491         {
    492             count = min;
    493             x->size = (uint16) count;
    494             temp = x->data = (uint8*) OSCL_DEFAULT_MALLOC((1 + x->size / 8) * sizeof(uint8));
    495             if (x->size > 16)
    496             {
    497                 ReadRemainingBits(stream);  /* Octet align */
    498             }
    499             while (count >= 8)
    500             {
    501                 temp[0] = ReadBits(8, stream);
    502                 ++temp;
    503                 count -= 8;
    504             }
    505             temp[0] = (uint8)(ReadBits(count, stream) << (8 - count));
    506         }
    507         else                      /* Constrained size */
    508         {
    509             count = GetInteger(min, max, stream);
    510             x->size = (uint16) count;
    511             temp = x->data = (uint8*) OSCL_DEFAULT_MALLOC((1 + x->size / 8) * sizeof(uint8));
    512             ReadRemainingBits(stream);
    513             while (count >= 8)
    514             {
    515                 temp[0] = ReadBits(8, stream);
    516                 ++temp;
    517                 count -= 8;
    518             }
    519         }
    520     }
    521 }
    522 
    523 // =========================================================
    524 // GetCharString()                             (RAN-UII)
    525 //
    526 // This function decodes a character string from a stream.
    527 // Currently it only handles the special case of DTMF user
    528 //   input (that is, signalType in UserInputIndication).
    529 // However, it should be straightforward to extend this
    530 //   to handle generic restrictions on the four common
    531 //   types (IA5String, NumericString, PrintableString,
    532 //   and VisibleString).  See X.691 Clause 26.5 for details.
    533 // NOTE: For now I'm adding NULL string termination so that
    534 //   the analyzer (ShowPERCharString() ) will correctly display
    535 //   it on the decode side.  Should correct this at some point,
    536 //   since x->data should really only contain characters that
    537 //   were pulled from the input stream.
    538 // =========================================================
    539 void GetCharString(const char *stringName,
    540                    uint8 unbounded, uint32 min, uint32 max, const char *from,
    541                    PS_int8STRING x, PS_InStream stream)
    542 {
    543     if (oscl_strncmp(stringName, "IA5String", oscl_strlen("IA5String")) == 0 &&    // Validate DTMF UII case
    544             unbounded == 0 &&
    545             min == 1 &&
    546             max == 1 &&
    547             oscl_strncmp(from, "0123456789#*ABCD!", oscl_strlen("0123456789#*ABCD!")) == 0)
    548     {
    549         x->size = 2;
    550         x->data = (uint8*) OSCL_DEFAULT_MALLOC(x->size * sizeof(uint8));
    551         x->data[0] = ReadBits(8, stream);     // Read single character,
    552         // Normal ascii value, not octet aligned
    553         x->data[1] = 0;  // NULL terminate
    554     }
    555     else if (oscl_strncmp(stringName, "GeneralString", oscl_strlen("GeneralString")) == 0)   // Validate GeneralString case  (RAN-ALPHA)
    556     {
    557         x->size = (uint16)(1 + GetLengthDet(stream)); // (leave extra space for NULL)
    558         x->data = (uint8*) OSCL_DEFAULT_MALLOC(x->size * sizeof(uint8));
    559         ReadOctets(x->size - 1, x->data, 1, stream);
    560         x->data[x->size-1] = 0;  // NULL terminate
    561     }
    562     else
    563     {
    564         x->size = 0;
    565         x->data = NULL;
    566         ErrorMessageAndLeave("GetCharString(): Not yet implemented.");
    567     }
    568 }
    569 
    570 // =========================================================
    571 // GetObjectID()                        X.691 Section 23
    572 //
    573 // This function reads an OBJECT IDENTIFIER from the input
    574 // stream.  This is just a length determinant, followed by
    575 // a variable number of octets.
    576 // =========================================================
    577 void GetObjectID(PS_OBJECTIDENT x, PS_InStream stream)
    578 {
    579     x->size = (uint16) GetLengthDet(stream);
    580     if (x->size)
    581     {
    582         x->data = (uint8*) OSCL_DEFAULT_MALLOC(x->size * sizeof(uint8));
    583         ReadOctets(x->size, x->data, 0, stream);
    584     }
    585     else
    586     {
    587         x->data = NULL;
    588     }
    589 }
    590 
    591 
    592 /* --------------------------------------------- */
    593 /* --------------- OTHER CALLS ------------------*/
    594 /* --------------------------------------------- */
    595 
    596 // =========================================================
    597 // GetLengthDet()                        X.691 Section 10.9
    598 //
    599 // Decodes a general length determinant from the input
    600 // stream.  Assumes ALIGNED variant of PER.
    601 // =========================================================
    602 uint32 GetLengthDet(PS_InStream stream)
    603 {
    604     uint32 length;
    605     uint8 byte1, byte2;
    606     uint8 mask1 = 0x80;   /* 10000000 */
    607     uint8 mask2 = 0x40;   /* 01000000 */
    608     uint8 mask3 = 0x3f;   /* 00111111 */
    609 
    610     ReadOctets(1, (uint8*)&byte1, 0, stream);  /* Get first byte */
    611     if (!(byte1&mask1))       /* 0xxxxxxx ==>Single octet case */
    612     {
    613         length = (uint32) byte1;
    614     }
    615     else if (!(byte1&mask2))  /* 10xxxxxx ==>Dual octet case */
    616     {
    617         ReadOctets(1, (uint8*)&byte2, 0, stream); /* Second byte */
    618         length = (((uint32)(byte1 & mask3)) << 8) + (int32)byte2;
    619     }
    620     else
    621     {
    622         ErrorMessageAndLeave("GetLengthDet(): Fragmented Length Dets Not Supported.");
    623         return(0);
    624     }
    625     return(length);
    626 }
    627 
    628 // =========================================================
    629 // GetNormSmallLength()              X.691 Section 10.9.3.4
    630 //
    631 // Decodes a Normally Small length determinant from the
    632 // input stream.  (In SEQUENCE, this gets the size of an
    633 // unknown extensions map).
    634 // Assumes ALIGNED variant of PER.
    635 // =========================================================
    636 uint32 GetNormSmallLength(PS_InStream stream)
    637 {
    638     uint8 value = 0;
    639     uint8 mask = 0x40;  /* 01000000 */
    640 
    641     value = ReadBits(7, stream);
    642     if (value&mask)
    643     {
    644         ErrorMessageAndLeave("GetNormSmallLength(): Range exceeded.");
    645         return(0);
    646     }
    647     return((uint32)value + 1); /* Valid range is 1...64 */
    648 }
    649 
    650 // =========================================================
    651 // GetNormSmallValue()                     X.691 Section 10.6
    652 //
    653 // Decodes a Normally Small Nonnegative Whole Number from
    654 // the input stream.
    655 // (In CHOICE, gets choice index when extension is ON.)
    656 // Assumes ALIGNED variant of PER.
    657 // =========================================================
    658 uint32 GetNormSmallValue(PS_InStream stream)
    659 {
    660     uint8 value = 0;
    661     uint8 mask = 0x40;  /* 01000000 */
    662 
    663     value = ReadBits(7, stream);
    664     if (value&mask)
    665     {
    666         ErrorMessageAndLeave("GetNormSmallValue(): range exceeded.");
    667         return(0);
    668     }
    669     return((uint32)value);    /* Valid range is 0...63 */
    670 }
    671 
    672 // =========================================================
    673 // SkipOneExtension()                X.691 Section 18.9
    674 //
    675 // The general length is first read, and that number of
    676 // octets are then skipped.
    677 // (In SEQUENCE, this skips over a single unknown extension.
    678 //  In CHOICE, this skips an item that has been chosen from
    679 //  the extension, assuming the choice index has already
    680 //  been read).
    681 // Assumes aligned variant of PER.
    682 // =========================================================
    683 void SkipOneExtension(PS_InStream stream)
    684 {
    685     uint16 length;
    686     uint8 buffer[32];
    687 
    688     length = (uint16) GetLengthDet(stream);
    689     while (length > 32)      /* Pieces of at most 32 bytes */
    690     {
    691         ReadOctets(32, buffer, 0, stream);
    692         length -= 32;
    693     }
    694     ReadOctets(length, buffer, 0, stream);  /* Leftovers */
    695 }
    696 
    697 // =========================================================
    698 // SkipAllExtensions()                X.691 Section 18.9
    699 //
    700 // For SEQUENCE, this skips over all unknown extensions.
    701 // This includes reading the SigMap, including size.
    702 // Call this routine at the location of the ext marker [...].
    703 //
    704 // NOTE: This routine may be obsolete.  Miniparser code
    705 // instead uses a combination of GetUnknownSigMap() and
    706 // SkipUnreadExtensions().
    707 // =========================================================
    708 void SkipAllExtensions(PS_InStream stream)
    709 {
    710     uint32 size, i, num_to_skip = 0;
    711 
    712     size = GetNormSmallLength(stream);  /* Length of SigMap */
    713     /* Read sigmap, counting number of significant extensions */
    714     for (i = 0; i < size; ++i)
    715     {
    716         num_to_skip += ReadBits(1, stream);
    717     }
    718     for (i = 0; i < num_to_skip; ++i)
    719     {
    720         SkipOneExtension(stream);
    721     }
    722 }
    723 
    724 // =========================================================
    725 // GetChoiceIndex()              X.691 Sections 22.4 - 22.8
    726 //
    727 // Reads the extension bit and choice index from the input
    728 // stream, and constructs a (possibly extended) choice index.
    729 // Assumes ALIGNED variant of PER.
    730 // ---------------------------------------------------------
    731 // Inputs: rootnum   (number of objects in root)
    732 //         extmarker (0 if no extension marker, 1 otherwise)
    733 // =========================================================
    734 uint16 GetChoiceIndex(uint32 rootnum, uint8 extmarker, PS_InStream stream)
    735 {
    736     uint8 extension;
    737     uint16 index;
    738 
    739     extension = 0;
    740     if (extmarker)          /* Get extension bit */
    741     {
    742         extension = ReadBits(1, stream);
    743     }
    744 
    745     if (!extension)      /* ---Item in root--- */
    746     {
    747         if (rootnum == 1)     /* Trivial index */
    748         {
    749             return(0);
    750         }
    751         else                  /* Standard index */
    752         {
    753             index = (uint16) GetInteger(0, rootnum - 1, stream);
    754         }               /* ---Item in extension--- */
    755     }
    756     else                    /* Extended index */
    757     {
    758         index = (uint16)(GetNormSmallValue(stream) + rootnum);
    759     }
    760 
    761     return(index);
    762 }
    763 
    764 // =========================================================
    765 // GetUnknownSigMap()           X.691 Sections 18.7 - 18.8
    766 //
    767 // This function reads an unknown significance map from
    768 // the input stream.  This includes the length of the
    769 // significance map, and an options bit corresponding to
    770 // each of the possible extension items.  The completed
    771 // map is returned in a special structure.
    772 // =========================================================
    773 PS_UnknownSigMap GetUnknownSigMap(PS_InStream stream)
    774 {
    775     int32 i;
    776     PS_UnknownSigMap x;
    777 
    778     x = (PS_UnknownSigMap) OSCL_DEFAULT_MALLOC(sizeof(S_UnknownSigMap));
    779 
    780     x->size = (uint16) GetNormSmallLength(stream);
    781     x->optionFlags = (uint8*) OSCL_DEFAULT_MALLOC(x->size * sizeof(uint8));
    782     for (i = 0; i < x->size; ++i)
    783     {
    784         x->optionFlags[i] = ReadBits(1, stream);
    785     }
    786     x->extensionsRead = 0;
    787 
    788     return(x);
    789 }
    790 
    791 // =========================================================
    792 // SigMapValue()
    793 //
    794 // This function reads a single options flag from an
    795 // unknown significance map (UnknownSigMap).  If the
    796 // index of the desired value exceeds the size of the
    797 // map, the return value is zero.
    798 // =========================================================
    799 uint8 SigMapValue(uint32 index, PS_UnknownSigMap map)
    800 {
    801     if (index < map->size)
    802     {
    803         return(map->optionFlags[index]);
    804     }
    805     else
    806     {
    807         return(0);
    808     }
    809 }
    810 
    811 // =========================================================
    812 // ExtensionPrep()
    813 //
    814 // This function is called immediately before reading each
    815 // unknown extension item in a SEQUENCE.  It performs two
    816 // actions:
    817 //    1. Records within the unknown sigmap that another
    818 //       extension is being read (++map->extensionsRead).
    819 //       This is so SkipUnreadExtensions() later knows
    820 //       how many extensions should be skipped.
    821 //    2. Reads and discards the length wrapper from the
    822 //       input stream.
    823 // =========================================================
    824 void ExtensionPrep(PS_UnknownSigMap map, PS_InStream stream)
    825 {
    826     ++map->extensionsRead;
    827     GetLengthDet(stream);
    828 }
    829 
    830 // =========================================================
    831 // SkipUnreadExtensions()
    832 //
    833 // This function skips any unread (and possibly unknown) items
    834 // in the extension of a SEQUENCE.  In order for this to work,
    835 // previously read extension items must have been counted in
    836 // map->extensionsRead; see ExtensionPrep() for details.
    837 //
    838 // This routine takes the following actions:
    839 //    1. Uses map->extensionsRead to determine how many
    840 //       extension items remain in the input stream.
    841 //    2. Skips remaining extension items.
    842 //    3. Frees the UnknownSigMap.
    843 //    4. Returns the number of extensions skipped.
    844 // =========================================================
    845 uint32 SkipUnreadExtensions(PS_UnknownSigMap map, PS_InStream stream)
    846 {
    847     uint32 i, numExtensions;
    848 
    849     /* Compute the number of extensions to skip */
    850     numExtensions = 0;
    851     for (i = 0; i < map->size; ++i)
    852     {
    853         numExtensions += map->optionFlags[i];
    854     }
    855     numExtensions -= map->extensionsRead;
    856 
    857     /* Skip remaining extensions */
    858     for (i = 0; i < numExtensions; ++i)
    859     {
    860         SkipOneExtension(stream);
    861     }
    862 
    863     /* Free map, return number skipped */
    864     OSCL_DEFAULT_FREE(map->optionFlags);
    865     OSCL_DEFAULT_FREE(map);
    866 
    867     return(numExtensions);
    868 }
    869 
    870 // =========================================================
    871 // SkipOneOctet()
    872 //
    873 // Skip a single octet.  This is used when a NULL is
    874 // read from the extension of a CHOICE (since an empty
    875 // octet is present)
    876 // =========================================================
    877 void SkipOneOctet(PS_InStream stream)
    878 {
    879     uint8 temp;
    880 
    881     ReadOctets(1, &temp, 0, stream);
    882 }
    883 
    884 /***********************************************************/
    885 /*=========================================================*/
    886 /*============ ENCODING ROUTINES (Generic PER) ============*/
    887 /*=========================================================*/
    888 /***********************************************************/
    889 
    890 
    891 /* --------------------------------------------- */
    892 /* ------------- LOW LEVEL STREAM -------------- */
    893 /* --------------------------------------------- */
    894 
    895 // =========================================================
    896 // WriteBits()
    897 //
    898 // This function writes some number of bits to the
    899 // output stream.
    900 // =========================================================
    901 void WriteBits(uint32 number, uint8 bits, PS_OutStream stream)
    902 {
    903     uint8 BitSize;
    904     uint8 temp;
    905 
    906     BitSize = (uint8)((stream->bitIndex) + number);
    907     temp = (uint8)(bits << (8 - number));
    908     (stream->buildByte) |= (temp >> (stream->bitIndex));
    909 
    910     if (BitSize > 8)                          /* Appended size > 8 bits */
    911     {
    912         stream->bitIndex = 8;
    913         WriteRemainingBits(stream);
    914         stream->buildByte = (uint8)((bits) << (16 - BitSize));
    915         stream->bitIndex = (uint16)(BitSize - 8);
    916         return;
    917     }
    918     else if (BitSize < 8)                 /* Appended size < 8 bits */
    919     {
    920         stream->bitIndex = BitSize;
    921         return;
    922     }
    923     else                                     /* Appended size == 8 bits */
    924     {
    925         stream->bitIndex = 8;
    926         WriteRemainingBits(stream);
    927         return;
    928     }
    929 
    930 }
    931 
    932 // =========================================================
    933 // WriteRemainingBits()
    934 //
    935 // This function advances to the next octet boundary in
    936 // the output stream.  Zero-bit padding is done, if needed.
    937 // If the stream already points to an octet boundary, no
    938 // action is taken.
    939 // =========================================================
    940 void WriteRemainingBits(PS_OutStream stream)
    941 {
    942     if (stream->bitIndex)
    943     {
    944         if (stream->byteIndex + 1 > stream->size)
    945         {
    946             ExpandOutStream(stream);
    947         }
    948         stream->data[stream->byteIndex] = stream->buildByte;
    949         ++stream->byteIndex;
    950         stream->bitIndex = 0;
    951         stream->buildByte = 0;
    952     }
    953 }
    954 
    955 // =========================================================
    956 // WriteOctets()
    957 //
    958 // This function writes one or more octets to the output
    959 // stream.  Input arguments are:
    960 //   uint32 number;         /* Number of octets to write */
    961 //   uint8* octets;       /* Source for octets */
    962 //   uint8 reorder;       /* Reorder for little-endian machine? */
    963 //   PS_OutStream stream; /* Output stream */
    964 // =========================================================
    965 void WriteOctets(uint32 number, uint8* octets, uint8 reorder, PS_OutStream stream)
    966 {
    967     uint8* destination;
    968 
    969     WriteRemainingBits(stream);  /* Octet alignment */
    970 
    971     /* Expand the stream, if needed */
    972     while (stream->byteIndex + number > stream->size)
    973     {
    974         ExpandOutStream(stream);
    975     }
    976 
    977     /* Write the octets to stream */
    978     destination = stream->data + stream->byteIndex;
    979     if (number == 0)   /* No action */
    980     {
    981         return;
    982     }
    983     else if (number <= 4 && reorder)   /* Apply reordering */
    984     {
    985         switch (number)
    986         {
    987             case 1:
    988                 destination[0] = octets[0];
    989                 break;
    990             case 2:
    991                 destination[0] = octets[1];
    992                 destination[1] = octets[0];
    993                 break;
    994             case 3:
    995                 destination[0] = octets[2];
    996                 destination[1] = octets[1];
    997                 destination[2] = octets[0];
    998                 break;
    999             case 4:
   1000                 destination[0] = octets[3];
   1001                 destination[1] = octets[2];
   1002                 destination[2] = octets[1];
   1003                 destination[3] = octets[0];
   1004                 break;
   1005         }
   1006     }
   1007     else
   1008     {
   1009         oscl_memcpy(destination, octets, number);  /* Straight copy */
   1010     }
   1011 
   1012     stream->byteIndex = (uint16)(number + stream->byteIndex);
   1013 }
   1014 
   1015 // =========================================================
   1016 // NewOutStream()
   1017 //
   1018 // This function creates a new, empty output stream.
   1019 // =========================================================
   1020 PS_OutStream NewOutStream(void)
   1021 {
   1022     PS_OutStream x;
   1023 
   1024     x = (PS_OutStream) OSCL_DEFAULT_MALLOC(sizeof(S_OutStream));
   1025     x->data = NULL;
   1026     x->size = 0;
   1027     x->byteIndex = 0;
   1028     x->bitIndex = 0;
   1029     x->buildByte = 0;
   1030 
   1031     return(x);
   1032 }
   1033 
   1034 // =========================================================
   1035 // ExpandOutStream()
   1036 //
   1037 // This function expands an output stream by some number
   1038 // of bytes, as defined by STREAM_ADDITION.
   1039 // =========================================================
   1040 void ExpandOutStream(PS_OutStream x)
   1041 {
   1042     uint8* tmp = x->data;
   1043 
   1044     x->data = (uint8*) OSCL_DEFAULT_MALLOC(x->size + STREAM_ADDITION);
   1045     oscl_memcpy(x->data, tmp, x->size);
   1046     if (tmp)
   1047         OSCL_DEFAULT_FREE(tmp);
   1048 
   1049     x->size += STREAM_ADDITION;
   1050 }
   1051 
   1052 // =========================================================
   1053 // FreeOutStream()
   1054 //
   1055 // This function frees an existing output stream.
   1056 // =========================================================
   1057 void FreeOutStream(PS_OutStream x)
   1058 {
   1059     OSCL_DEFAULT_FREE(x->data);
   1060     OSCL_DEFAULT_FREE(x);
   1061 }
   1062 
   1063 /* ----------------------------------------------- */
   1064 /* ------------- HIGH LEVEL ASN DATA ------------- */
   1065 /* ----------------------------------------------- */
   1066 
   1067 // =========================================================
   1068 // PutBoolean()
   1069 //
   1070 // This function writes a boolean to the output stream.
   1071 // =========================================================
   1072 void PutBoolean(uint32 value, PS_OutStream stream)
   1073 {
   1074     WriteBits(1, (uint8)value, stream);
   1075 }
   1076 
   1077 // =========================================================
   1078 // PutInteger()                           X.691 Section 10.5
   1079 //
   1080 // This function encodes a constrained integer, given the
   1081 // lower/upper bounds.  Note that bounds and value must be
   1082 // uint32.  This means 0<= {lower,upper,value} <=4294967295.
   1083 // Assumes ALIGNED variant of PER.
   1084 // =========================================================
   1085 void PutInteger(uint32 lower, uint32 upper, uint32 value, PS_OutStream stream)
   1086 {
   1087     uint32 range, offset;
   1088     uint8 nbits, nbytes = 0;
   1089     uint8 code_nbytes;
   1090 
   1091     if (lower > upper)
   1092     {
   1093         ErrorMessageAndLeave("PutInteger(): Negative range.");
   1094         return;
   1095     }
   1096     if (value < lower)
   1097     {
   1098         ErrorMessageAndLeave("PutInteger(): Value too small.");
   1099         return;
   1100     }
   1101     if (value > upper)
   1102     {
   1103         ErrorMessageAndLeave("PutInteger(): Value too large.");
   1104         return;
   1105     }
   1106 
   1107     range = upper - lower + 1;
   1108     offset = value - lower;
   1109 
   1110     if (range == 0 || range > 65536)     /* Range exceeds 2-octets */
   1111     {
   1112         /* (Range==0 means [0,2^32-1] case) */
   1113         if (offset < 256) nbytes = 1; /* Send using minimum #octets */
   1114         else if (offset < 65536) nbytes = 2;
   1115         else if (offset < 16777216) nbytes = 3;
   1116         else nbytes = 4;
   1117         code_nbytes = (uint8)(nbytes - 1);
   1118         WriteBits(2, code_nbytes, stream);              /* Send #octets */
   1119         WriteOctets(nbytes, (uint8*)&offset, 1, stream);  /* Offset value */
   1120         return;
   1121     }
   1122     else if (range == 1)            /* 0-bits */
   1123         return;
   1124     else if (range < 256)           /* Bit-field cases */
   1125     {
   1126         if (range <= 2) nbits = 1;
   1127         else if (range <= 4) nbits = 2;
   1128         else if (range <= 8) nbits = 3;
   1129         else if (range <= 16) nbits = 4;
   1130         else if (range <= 32) nbits = 5;
   1131         else if (range <= 64) nbits = 6;
   1132         else if (range <= 128) nbits = 7;
   1133         else nbits = 8;
   1134         WriteBits(nbits, (uint8)offset, stream);
   1135         return;
   1136     }
   1137     else if (range == 256)          /* One octet */
   1138     {
   1139         WriteOctets(1, (uint8*)(&offset), 1, stream);
   1140         return;
   1141     }
   1142     else                            /* range<=65536; Two octet */
   1143     {
   1144         WriteOctets(2, (uint8*)(&offset), 1, stream);
   1145         return;
   1146     }
   1147 }
   1148 
   1149 // =========================================================
   1150 // PutSignedInteger()                   X.691 Section 10.5
   1151 //
   1152 // This function encodes a constrained integer, given the
   1153 // lower/upper bounds.  The only difference from
   1154 // PutInteger() is that the bounds and the values are
   1155 // of type int32, and so may be negative.
   1156 // Assumes ALIGNED variant of PER.
   1157 // =========================================================
   1158 void PutSignedInteger(int32 lower, int32 upper, int32 value, PS_OutStream stream)
   1159 {
   1160     int32 range, offset;
   1161     uint8 nbits, nbytes = 0;
   1162     uint8 code_nbytes;
   1163 
   1164     if (lower > upper)
   1165     {
   1166         ErrorMessageAndLeave("PutSignedInteger(): Negative range.");
   1167         return;
   1168     }
   1169     if (value < lower)
   1170     {
   1171         ErrorMessageAndLeave("PutSignedInteger(): Value too small.");
   1172         return;
   1173     }
   1174     if (value > upper)
   1175     {
   1176         ErrorMessageAndLeave("PutSignedInteger(): Value too large.");
   1177         return;
   1178     }
   1179 
   1180     range = upper - lower + 1;
   1181     offset = value - lower;
   1182 
   1183     if (range == 0 || range > 65536)     /* Range exceeds 2-octets */
   1184     {
   1185         /* (Range==0 means [0,2^32-1] case) */
   1186         if (offset < 256) nbytes = 1; /* Send using minimum #octets */
   1187         else if (offset < 65536) nbytes = 2;
   1188         else if (offset < 16777216) nbytes = 3;
   1189         else nbytes = 4;
   1190         code_nbytes = (uint8)(nbytes - 1);
   1191         WriteBits(2, code_nbytes, stream);              /* Send #octets */
   1192         WriteOctets(nbytes, (uint8*)&offset, 1, stream);  /* Offset value */
   1193         return;
   1194     }
   1195     else if (range == 1)            /* 0-bits */
   1196         return;
   1197     else if (range < 256)           /* Bit-field cases */
   1198     {
   1199         if (range <= 2) nbits = 1;
   1200         else if (range <= 4) nbits = 2;
   1201         else if (range <= 8) nbits = 3;
   1202         else if (range <= 16) nbits = 4;
   1203         else if (range <= 32) nbits = 5;
   1204         else if (range <= 64) nbits = 6;
   1205         else if (range <= 128) nbits = 7;
   1206         else nbits = 8;
   1207         WriteBits(nbits, (uint8)offset, stream);
   1208         return;
   1209     }
   1210     else if (range == 256)          /* One octet */
   1211     {
   1212         WriteOctets(1, (uint8*)(&offset), 1, stream);
   1213         return;
   1214     }
   1215     else                            /* range<=65536; Two octet */
   1216     {
   1217         WriteOctets(2, (uint8*)(&offset), 1, stream);
   1218         return;
   1219     }
   1220 }
   1221 
   1222 // =========================================================
   1223 // PutUnboundedInteger()                   X.691 Section 12
   1224 //                                         and also 10.4, 10.9.
   1225 //
   1226 // This function encodes an unbounded integer, which we
   1227 // currently assume has type uint32.  We'd need to make
   1228 // special arrangements if negative values are allowed.
   1229 // Assumes ALIGNED variant of PER.
   1230 // =========================================================
   1231 void PutUnboundedInteger(uint32 value, PS_OutStream stream)
   1232 {
   1233     uint32 nbytes;
   1234 
   1235     /* The encoding is min-octets, and so depends on value */
   1236     if (value < 128)
   1237         nbytes = 1;
   1238     else if (value < 32768)
   1239         nbytes = 2;
   1240     else if (value < 8388608)
   1241         nbytes = 3;
   1242     else
   1243         nbytes = 4;
   1244 
   1245     /* Send length det, followed by 2's complement encoding */
   1246     PutLengthDet(nbytes, stream);
   1247     WriteOctets(nbytes, (uint8*)(&value), 1, stream);
   1248 }
   1249 
   1250 // =========================================================
   1251 // PutExtendedInteger()                   X.691 Section 12.1
   1252 //
   1253 // This function encodes a constrained integer with an
   1254 // extended range.  We assume the value is unsigned, and
   1255 // that the ALIGNED variant of PER is used.
   1256 // =========================================================
   1257 void PutExtendedInteger(uint32 lower, uint32 upper, uint32 value, PS_OutStream stream)
   1258 {
   1259     if (value > upper)              // Extension ON
   1260     {
   1261         WriteBits(1, 1, stream);
   1262         PutUnboundedInteger(value, stream);
   1263     }
   1264     else                            // Extension OFF
   1265     {
   1266         WriteBits(1, 0, stream);
   1267         PutInteger(lower, upper, value, stream);
   1268     }
   1269 }
   1270 
   1271 // =========================================================
   1272 // PutOctetString()                      X.691 Section 16
   1273 //
   1274 // This function writes an OCTET STRING to the output stream.
   1275 // Bounds on the size, if any, are included in the input
   1276 // arguments.  The OCTETSTRING structure (x) is freed at
   1277 // the end.
   1278 // =========================================================
   1279 void PutOctetString(uint8 unbounded, uint32 min, uint32 max,
   1280                     PS_OCTETSTRING x, PS_OutStream stream)
   1281 {
   1282     if (unbounded)         /* ====Size is unbounded==== */
   1283     {
   1284         PutLengthDet(x->size, stream);
   1285         WriteOctets(x->size, x->data, 0, stream);
   1286     }
   1287     else                   /* ====Size is bounded==== */
   1288     {
   1289 
   1290         if (min > max)            /* Error handling */
   1291         {
   1292             ErrorMessageAndLeave("PutOctetString(): Constraint error (min>max)");
   1293         }
   1294         else if ((x->size < min) || (x->size > max))
   1295         {
   1296             ErrorMessageAndLeave("PutOctetString(): Size out of bounds");
   1297         }
   1298 
   1299         if (min == max)           /* Fixed size (no length det!) */
   1300         {
   1301             if (x->size > 2)
   1302             {
   1303                 WriteOctets(x->size, x->data, 0, stream);
   1304             }
   1305             else if (x->size == 2)
   1306             {
   1307                 WriteBits(8, x->data[0], stream);
   1308                 WriteBits(8, x->data[1], stream);
   1309             }
   1310             else if (x->size == 1)
   1311             {
   1312                 WriteBits(8, x->data[0], stream);
   1313             }
   1314         }
   1315         else                      /* Constrained size */
   1316         {
   1317             PutInteger(min, max, x->size, stream);
   1318             WriteOctets(x->size, x->data, 0, stream);
   1319         }
   1320     }
   1321 }
   1322 
   1323 // =========================================================
   1324 // PutBitString()                      X.691 Section 16
   1325 //
   1326 // This function writes a BIT STRING to the output stream.
   1327 // Bounds on the size, if any, are included in the input
   1328 // arguments.  The BITSTRING structure (x) is freed at
   1329 // the end.
   1330 // =========================================================
   1331 void PutBitString(uint8 unbounded, uint32 min, uint32 max,
   1332                   PS_BITSTRING x, PS_OutStream stream)
   1333 {
   1334     uint32 count;
   1335     uint8* temp;
   1336 
   1337     count = x->size;
   1338     temp = x->data;
   1339 
   1340     if (unbounded)         /* ====Size is unbounded==== */
   1341     {
   1342         PutLengthDet(x->size, stream);
   1343         while (count >= 8)
   1344         {
   1345             WriteBits(8, temp[0], stream);
   1346             ++temp;
   1347             count -= 8;
   1348         }
   1349         WriteBits(count, (uint8)(temp[0] >> (8 - count)), stream);
   1350     }
   1351     else                   /* ====Size is bounded==== */
   1352     {
   1353 
   1354         if (min > max)            /* Error handling */
   1355         {
   1356             ErrorMessageAndLeave("PutBitString(): Constraint error (min>max)");
   1357         }
   1358         else if ((x->size < min) || (x->size > max))
   1359         {
   1360             ErrorMessageAndLeave("PutBitString(): Size out of bounds");
   1361         }
   1362 
   1363         if (min == max)           /* Fixed size (no length det!) */
   1364         {
   1365             if (x->size > 16)
   1366             {
   1367                 WriteRemainingBits(stream);  /* Octet align */
   1368             }
   1369             while (count >= 8)
   1370             {
   1371                 WriteBits(8, temp[0], stream);
   1372                 ++temp;
   1373                 count -= 8;
   1374             }
   1375             WriteBits(count, (uint8)(temp[0] >> (8 - count)), stream);
   1376         }
   1377         else                      /* Constrained size */
   1378         {
   1379             PutInteger(min, max, x->size, stream);
   1380             WriteRemainingBits(stream);
   1381             while (count >= 8)
   1382             {
   1383                 WriteBits(8, temp[0], stream);
   1384                 ++temp;
   1385                 count -= 8;
   1386             }
   1387             WriteBits(count, (uint8)(temp[0] >> (8 - count)), stream);
   1388         }
   1389     }
   1390 }
   1391 
   1392 // =========================================================
   1393 // PutCharString()                             (RAN-UII)
   1394 //
   1395 // This function encodes a character string to a stream.
   1396 // Currently it only handles the special case of DTMF user
   1397 //   input (that is, signalType in UserInputIndication).
   1398 // However, it should be straightforward to extend this
   1399 //   to handle generic restrictions on the four common
   1400 //   types (IA5String, NumericString, PrintableString,
   1401 //   and VisibleString).  See X.691 Clause 26.5 for details.
   1402 // =========================================================
   1403 void PutCharString(const char *stringName,
   1404                    uint8 unbounded, uint32 min, uint32 max, const char *from,
   1405                    PS_int8STRING x, PS_OutStream stream)
   1406 {
   1407     if (oscl_strncmp(stringName, "IA5String", oscl_strlen("IA5String")) == 0 &&    // Validate DTMF UII case
   1408             unbounded == 0 &&
   1409             min == 1 &&
   1410             max == 1 &&
   1411             oscl_strncmp(from, "0123456789#*ABCD!", oscl_strlen("0123456789#*ABCD!")) == 0)
   1412     {
   1413         WriteBits(8, x->data[0], stream);     // Write single character,
   1414         // Normal ascii value, not octet aligned
   1415     }
   1416     else if (oscl_strncmp(stringName, "GeneralString", oscl_strlen("GeneralString")) == 0)   // Validate GeneralString case (RAN-ALPHA)
   1417         // ------------------------------------------------------------------------
   1418         // Note on GeneralString: as far as I can tell this is treated as a
   1419         // restricted character string type which is not a known-multiplier character
   1420         // string.  As such it falls under clause 26.6 of X.691.  In this case, any
   1421         // constraints passed from the PER encoder are not considered 'PER-visible'
   1422         // and so they are not used.  Because of this, the following should be a
   1423         // complete implementation of GeneralString (regardless of constraints).
   1424         // It should work for alphanumeric, and anything else that would use
   1425         // GeneralString.
   1426         // ------------------------------------------------------------------------
   1427         // Note also: I assume you need to install the primary graphic character
   1428         // set described in T.51, i.e. that there is no default character set.
   1429         // Invoking a character set means sending an escape code.  Whether you NEED
   1430         // this to get the primary character set wasn't made clear in T.51
   1431         // itself, though I found a hint elsewhere that suggested you have to send
   1432         // the escape code.  The escape code is 27 40 66 15 (or in T.51 lingo,
   1433         // "ESC 2/8 4/2 0/15").  Sending this code shouldn't hurt anything if the
   1434         // receiving end is compliant to T.51, but if it doesn't work on the first
   1435         // try, then one thing you guys might try is removing the escape code, in
   1436         // case maybe the VIG is choking on it.  Comment out the relevant four lines
   1437         // below, and also get rid of the extra '4+' in the length calculation.
   1438         // BTW, the escape sequence breaks down into:
   1439         //   "Designate primary T.51 character set as G0" -- 27 40 66
   1440         //   "Invoke G0 as the current character set" -- 15
   1441         // ------------------------------------------------------------------------
   1442     {
   1443         // Encode length of string, in octets
   1444         PutLengthDet((x->size), stream);  // Assumes 4-byte T.51 escape sequence
   1445         // Remove the '4+' if the escape sequence is removed.
   1446         // Note: PutLengthDet() does octet alignment for us
   1447         // Send the T.51 encoded character data
   1448         WriteOctets(x->size, x->data, 1, stream);
   1449     }
   1450     else
   1451     {
   1452         ErrorMessageAndLeave("PutCharString(): Not fully implemented.");
   1453     }
   1454 }
   1455 
   1456 // =========================================================
   1457 // PutObjectID()                        X.691 Section 23
   1458 //
   1459 // This function writes an OBJECT IDENTIFIER to the output
   1460 // stream.  This is just a length determinant, followed by
   1461 // a variable number of octets.  The OBJECTID structure is
   1462 // freed at the end.
   1463 // =========================================================
   1464 void PutObjectID(PS_OBJECTIDENT x, PS_OutStream stream)
   1465 {
   1466     PutLengthDet(x->size, stream);
   1467     WriteOctets(x->size, x->data, 0, stream);
   1468 }
   1469 
   1470 // =========================================================
   1471 // PutExtensionNull()
   1472 //
   1473 // This function encodes a NULL object as an extension.
   1474 // =========================================================
   1475 void PutExtensionNull(PS_OutStream stream)
   1476 {
   1477     uint8 temp = 0;
   1478 
   1479     PutLengthDet(1, stream);        /* Length wrapper */
   1480     WriteOctets(1, &temp, 0, stream);  /* Empty octet */
   1481 }
   1482 
   1483 // =========================================================
   1484 // PutExtensionBoolean()
   1485 //
   1486 // This function encodes a boolean as an extension.
   1487 // =========================================================
   1488 void PutExtensionBoolean(uint32 value, PS_OutStream stream)
   1489 {
   1490     PutLengthDet(1, stream);        /* Length wrapper */
   1491     PutBoolean(value, stream);      /* Boolean */
   1492     WriteRemainingBits(stream);     /* Complete the octet */
   1493 }
   1494 
   1495 // =========================================================
   1496 // PutExtensionInteger()
   1497 //
   1498 // This function encodes an integer as an extension.
   1499 // =========================================================
   1500 void PutExtensionInteger(uint32 lower, uint32 upper, uint32 value, PS_OutStream stream)
   1501 {
   1502     PS_OutStream tempStream;
   1503 
   1504     tempStream = NewOutStream();              /* Create a temp stream */
   1505     PutInteger(lower, upper, value, tempStream); /* Write integer to temp */
   1506     PutTempStream(tempStream, stream); /* Transmit contents of tempStream */
   1507 }
   1508 
   1509 // =========================================================
   1510 // PutExtensionOctetString()
   1511 //
   1512 // This function encodes an octet string as an extension.
   1513 // =========================================================
   1514 void PutExtensionOctetString(uint8 unbounded,
   1515                              uint32 min, uint32 max, PS_OCTETSTRING x, PS_OutStream stream)
   1516 {
   1517     PS_OutStream tempStream;
   1518 
   1519     tempStream = NewOutStream();                  /* Create a temp stream */
   1520     PutOctetString(unbounded, min, max, x, tempStream);  /* Write to temp */
   1521     PutTempStream(tempStream, stream); /* Transmit contents of tempStream */
   1522 }
   1523 
   1524 
   1525 /* --------------------------------------------- */
   1526 /* ---------------- OTHER CALLS -----------------*/
   1527 /* --------------------------------------------- */
   1528 
   1529 // =========================================================
   1530 // PutNormSmallValue()                  X.691 Section 10.6
   1531 //
   1532 // Sends a normally small nonnegative value.  Range is
   1533 // [0,infinity].  (In CHOICE, this sends the choice index
   1534 // when extension is ON).
   1535 // Assumes ALIGNED variant of PER.
   1536 // =========================================================
   1537 void PutNormSmallValue(uint32 value, PS_OutStream stream)
   1538 {
   1539     uint8 sendval;
   1540     if (value < 64)
   1541     {
   1542         sendval = (uint8) value;
   1543         WriteBits(7, sendval, stream);
   1544     }
   1545     else
   1546     {
   1547         ErrorMessageAndLeave("PutNormSmallValue(): range exceeded.");
   1548     }
   1549 }
   1550 
   1551 // =========================================================
   1552 // PutChoiceIndex()              X.691 Sections 22.4 - 22.8
   1553 //
   1554 // Writes the extension bit (if needed) and the choice index
   1555 // to the bitstream.  Assumes ALIGNED variant of PER.
   1556 //
   1557 // Inputs: rootnum      (number of items in root)
   1558 //         extmarker    (0 if no extension marker, 1 otherwise)
   1559 //         index        (choice index, possibly extended)
   1560 // =========================================================
   1561 void PutChoiceIndex(uint32 rootnum, uint8 extmarker, uint32 index,
   1562                     PS_OutStream stream)
   1563 {
   1564     if (!extmarker)    /* ---Extension marker NOT present --- */
   1565     {
   1566         PutInteger(0, rootnum - 1, (uint32)index, stream);
   1567     }
   1568     else               /* ---Extension marker present --- */
   1569     {
   1570         if (index < rootnum)
   1571         {
   1572             WriteBits(1, 0, stream); /* Extension bit OFF */
   1573             PutInteger(0, rootnum - 1, (uint32)index, stream);
   1574         }
   1575         else
   1576         {
   1577             WriteBits(1, 1, stream); /* Extension bit ON */
   1578             PutNormSmallValue((uint32)(index - rootnum), stream);
   1579         }
   1580     }
   1581 }
   1582 
   1583 // =========================================================
   1584 // PutNormSmallLength()              X.691 Section 10.9.3.4
   1585 //
   1586 // Sends a normally small length determinant.  Range is
   1587 // [1,infinity].  (For SEQUENCE, this sends the size of
   1588 // the SigMap for unknown extensions.)
   1589 // Assumes ALIGNED variant of PER.
   1590 // =========================================================
   1591 void PutNormSmallLength(uint32 value, PS_OutStream stream)
   1592 {
   1593     uint8 sendval;
   1594     if (value < 65)
   1595     {
   1596         sendval = (uint8)(value - 1);
   1597         WriteBits(7, sendval, stream);
   1598     }
   1599     else
   1600     {
   1601         ErrorMessageAndLeave("PutNormSmallLength(): range exceeded.");
   1602     }
   1603 }
   1604 
   1605 // =========================================================
   1606 // PutLengthDet()                        X.691 Section 10.9
   1607 //
   1608 // Encodes a general length determinant to the output stream.
   1609 // (e.g. for extension wrapper).
   1610 // Assumes ALIGNED variant of PER.
   1611 // =========================================================
   1612 void PutLengthDet(uint32 value, PS_OutStream stream)
   1613 {
   1614     uint8 byte;
   1615     uint16 bytes;
   1616     uint16 mask = 0x8000;   /* 10000000 00000000 */
   1617 
   1618     if (value < 128)       /* One octet with leading '0' */
   1619     {
   1620         byte = (uint8) value;
   1621         WriteOctets(1, &byte, 0, stream);
   1622     }
   1623     else if (value < 16384)   /* Two octets with leading '10' */
   1624     {
   1625         bytes = (uint16)(value | mask);
   1626         WriteOctets(2, (uint8*)&bytes, 0, stream);
   1627     }
   1628     else
   1629     {
   1630         ErrorMessageAndLeave("PutLengthDet(): Fragmented Length Dets Not Supported.");
   1631     }
   1632 }
   1633 
   1634 // =========================================================
   1635 // PutExtensionItem()
   1636 //
   1637 // This function writes an extension item, including the
   1638 // length wrapper.  It makes a generic call to one of the
   1639 // H.245-defined PER Encoder routines.
   1640 // =========================================================
   1641 void PutExtensionItem(
   1642     void (*Func)(uint8* data, PS_OutStream stream),
   1643     uint8* x, PS_OutStream stream)
   1644 {
   1645     PS_OutStream tempStream;
   1646 
   1647     tempStream = NewOutStream();                  /* Create a temp stream */
   1648     Func(x, tempStream);               /* Encode x, writing to tempStream */
   1649     PutTempStream(tempStream, stream); /* Transmit contents of tempStream */
   1650 }
   1651 
   1652 // =========================================================
   1653 // PutTempStream()
   1654 //
   1655 // This function copies the contents of a temporary output
   1656 // stream (tempStream) to the main output stream (stream),
   1657 // preceeded by a generial length determinant.
   1658 // It also frees tempStream at the end.
   1659 // =========================================================
   1660 void PutTempStream(PS_OutStream tempStream, PS_OutStream stream)
   1661 {
   1662     WriteRemainingBits(tempStream);
   1663     PutLengthDet(tempStream->byteIndex, stream); /* Copy to real stream */
   1664     WriteOctets(tempStream->byteIndex, tempStream->data, 0, stream);
   1665     FreeOutStream(tempStream);
   1666 }
   1667 
   1668 /********************************************************/
   1669 /*======================================================*/
   1670 /*============ OTHER ROUTINES (Generic PER) ============*/
   1671 /*======================================================*/
   1672 /********************************************************/
   1673 
   1674 // =========================================================
   1675 // ConvertOutstreamToInstream()
   1676 //
   1677 // This function creates a new InStream and copies into
   1678 // it the contents of an old OutStream.  This is useful
   1679 // for internal testing.
   1680 // Note that the outstream is destroyed in the process.
   1681 // =========================================================
   1682 PS_InStream ConvertOutstreamToInstream(PS_OutStream outstream)
   1683 {
   1684     PS_InStream instream;
   1685 
   1686     WriteRemainingBits(outstream);
   1687     instream = (PS_InStream) OSCL_DEFAULT_MALLOC(sizeof(S_InStream));
   1688     instream->data = outstream->data;
   1689     instream->bitIndex = 0;
   1690 
   1691     OSCL_DEFAULT_FREE(outstream);
   1692     return(instream);
   1693 }
   1694 
   1695 // =========================================================
   1696 // NewOctetString()
   1697 //
   1698 // This function creates a new OCTETSTRING.
   1699 // For now, the data field just contains the string
   1700 // "OctetString".
   1701 // Later, I'll add input parameters and construct the
   1702 // real thing.
   1703 // THIS ROUTINE NEEDS ATTENTION!
   1704 // =========================================================
   1705 PS_OCTETSTRING NewOctetString(void)
   1706 {
   1707     PS_OCTETSTRING x;
   1708 
   1709     x = (PS_OCTETSTRING) OSCL_DEFAULT_MALLOC(sizeof(S_OCTETSTRING));
   1710     x->size = 12;
   1711     x->data = (uint8*) OSCL_DEFAULT_MALLOC(12 * sizeof(uint8));
   1712     oscl_strncpy((char *) x->data, "OctetString", x->size);
   1713 
   1714     return(x);
   1715 }
   1716 
   1717 // =========================================================
   1718 // NewBitString()
   1719 //
   1720 // This function creates a new BITSTRING.
   1721 // For now, the data field just contains the string
   1722 // "BitString".
   1723 // Later, I'll add input parameters and construct the
   1724 // real thing.
   1725 // THIS ROUTINE NEEDS ATTENTION!
   1726 // =========================================================
   1727 PS_BITSTRING NewBitString(void)
   1728 {
   1729     PS_BITSTRING x;
   1730 
   1731     x = (PS_BITSTRING) OSCL_DEFAULT_MALLOC(sizeof(S_BITSTRING));
   1732     x->size = 10;
   1733     x->data = (uint8*) OSCL_DEFAULT_MALLOC(10 * sizeof(uint8));
   1734     oscl_strncpy((char *) x->data, "BitString", x->size);
   1735 
   1736     return(x);
   1737 }
   1738 
   1739 // =========================================================
   1740 // NewCharString()
   1741 //
   1742 // This function creates a new int8STRING.
   1743 // For now, the data field just contains the string
   1744 // "CharString".
   1745 // Later, I'll add input parameters and construct the
   1746 // real thing.
   1747 // THIS ROUTINE NEEDS ATTENTION!
   1748 // =========================================================
   1749 PS_int8STRING NewCharString(void)
   1750 {
   1751     PS_int8STRING x;
   1752 
   1753     x = (PS_int8STRING) OSCL_DEFAULT_MALLOC(sizeof(S_int8STRING));
   1754     x->size = 11;
   1755     x->data = (uint8*) OSCL_DEFAULT_MALLOC(11 * sizeof(uint8));
   1756     oscl_strncpy((char *) x->data, "CharString", x->size);
   1757 
   1758     return(x);
   1759 }
   1760 
   1761 // =========================================================
   1762 // NewObjectID()
   1763 //
   1764 // This function creates a new OBJECTID.
   1765 // For now, the ID just contains the string "Object ID".
   1766 // Later, I'll add input parameters and construct the
   1767 // real thing.
   1768 // THIS ROUTINE NEEDS ATTENTION!
   1769 // =========================================================
   1770 PS_OBJECTIDENT NewObjectID(void)
   1771 {
   1772     PS_OBJECTIDENT x;
   1773 
   1774     x = (PS_OBJECTIDENT) OSCL_DEFAULT_MALLOC(sizeof(S_OBJECTIDENT));
   1775     x->size = 10;
   1776     x->data = (uint8*) OSCL_DEFAULT_MALLOC(10 * sizeof(uint8));
   1777     oscl_strncpy((char *) x->data, "Object ID", x->size);
   1778 
   1779     return(x);
   1780 }
   1781 
   1782 // =========================================================
   1783 // InitOctetString()
   1784 //
   1785 // This function inits a previously allocated OCTET STRING.
   1786 // For now, the data field just contains the string
   1787 // "OctetString".
   1788 // Later, I'll add input parameters and construct the
   1789 // real thing.
   1790 // THIS ROUTINE NEEDS ATTENTION!
   1791 // =========================================================
   1792 void InitOctetString(PS_OCTETSTRING x)
   1793 {
   1794     x->size = 12;
   1795     x->data = (uint8*) OSCL_DEFAULT_MALLOC(12 * sizeof(uint8));
   1796     oscl_strncpy((char *) x->data, "OctetString", x->size);
   1797 }
   1798 
   1799 // =========================================================
   1800 // InitBitString()
   1801 //
   1802 // This function inits a previously allocated BIT STRING.
   1803 // For now, the data field just contains the string
   1804 // "BitString".
   1805 // Later, I'll add input parameters and construct the
   1806 // real thing.
   1807 // THIS ROUTINE NEEDS ATTENTION!
   1808 // =========================================================
   1809 void InitBitString(PS_BITSTRING x)
   1810 {
   1811     x->size = 10;
   1812     x->data = (uint8*) OSCL_DEFAULT_MALLOC(10 * sizeof(uint8));
   1813     oscl_strncpy((char *) x->data, "BitString", x->size);
   1814 }
   1815 
   1816 // =========================================================
   1817 // InitCharString()
   1818 //
   1819 // This function inits a previously allocated int8 STRING.
   1820 // For now, the data field just contains the string
   1821 // "CharString".
   1822 // Later, I'll add input parameters and construct the
   1823 // real thing.
   1824 // THIS ROUTINE NEEDS ATTENTION!
   1825 // =========================================================
   1826 void InitCharString(PS_int8STRING x)
   1827 {
   1828     x->size = 11;
   1829     x->data = (uint8*) OSCL_DEFAULT_MALLOC(11 * sizeof(uint8));
   1830     oscl_strncpy((char *) x->data, "CharString", x->size);
   1831 }
   1832 
   1833 // =========================================================
   1834 // InitObjectid()
   1835 //
   1836 // This function inits a previously allocated OBJECT IDENTIFIER.
   1837 // For now, the data field just contains the string
   1838 // "ObjectID".
   1839 // Later, I'll add input parameters and construct the
   1840 // real thing.
   1841 // THIS ROUTINE NEEDS ATTENTION!
   1842 // =========================================================
   1843 void InitObjectid(PS_OBJECTIDENT x)
   1844 {
   1845     x->size = 9;
   1846     x->data = (uint8*) OSCL_DEFAULT_MALLOC(9 * sizeof(uint8));
   1847     oscl_strncpy((char *) x->data, "ObjectID", x->size);
   1848 }
   1849 
   1850 // =========================================================
   1851 // FreeOctetString()
   1852 //
   1853 // This frees an OCTET STRING.
   1854 // =========================================================
   1855 void FreeOctetString(PS_OCTETSTRING x)
   1856 {
   1857     if (x->size > 0)
   1858     {
   1859         OSCL_DEFAULT_FREE(x->data);
   1860     }
   1861     OSCL_DEFAULT_FREE(x);
   1862 }
   1863 
   1864 // =========================================================
   1865 // FreeBitString()
   1866 //
   1867 // This frees a BIT STRING.
   1868 // =========================================================
   1869 void FreeBitString(PS_BITSTRING x)
   1870 {
   1871     OSCL_DEFAULT_FREE(x->data);
   1872     OSCL_DEFAULT_FREE(x);
   1873 }
   1874 
   1875 // =========================================================
   1876 // FreeCharString()
   1877 //
   1878 // This frees a int8 STRING.
   1879 // =========================================================
   1880 void FreeCharString(PS_int8STRING x)
   1881 {
   1882     if (x->data)
   1883     {
   1884         OSCL_DEFAULT_FREE(x->data);
   1885     }
   1886     OSCL_DEFAULT_FREE(x);
   1887 }
   1888 
   1889 // =========================================================
   1890 // FreeObjectID()
   1891 //
   1892 // This frees an OBJECT IDENTIFIER.
   1893 // =========================================================
   1894 void FreeObjectID(PS_OBJECTIDENT x)
   1895 {
   1896     if (x->data)
   1897         OSCL_DEFAULT_FREE(x->data);
   1898     OSCL_DEFAULT_FREE(x);
   1899 }
   1900 
   1901 
   1902