dect
/
asterisk
Archived
13
0
Fork 0
This repository has been archived on 2022-02-17. You can view files and clone it, but cannot push or open issues or pull requests.
asterisk/addons/ooh323c/src/perutil.c

288 lines
8.0 KiB
C

/*
* Copyright (C) 1997-2005 by Objective Systems, Inc.
*
* This software is furnished under an open source license and may be
* used and copied only in accordance with the terms of this license.
* The text of the license may generally be found in the root
* directory of this installation in the COPYING file. It
* can also be viewed online at the following URL:
*
* http://www.obj-sys.com/open/license.html
*
* Any redistributions of this file including modified versions must
* maintain this copyright notice.
*
*****************************************************************************/
#include "ooasn1.h"
#include "ooper.h"
ASN1BOOL isExtendableSize (Asn1SizeCnst* pSizeList);
static ASN1BOOL isFixedSize (Asn1SizeCnst* pSizeList);
ASN1BOOL alignCharStr
(OOCTXT* pctxt, ASN1UINT len, ASN1UINT nbits, Asn1SizeCnst* pSize)
{
if (TRUE) {
ASN1UINT lower, upper;
ASN1BOOL doAlign = (len > 0), extendable;
pSize = checkSize (pSize, len, &extendable);
if (0 != pSize) {
lower = pSize->lower;
upper = pSize->upper;
}
else {
lower = 0;
upper = ASN1UINT_MAX;
}
if (!extendable && upper < 65536) {
ASN1UINT bitRange = upper * nbits;
if (upper == lower) {
/* X.691, clause 26.5.6 */
if (bitRange <= 16) doAlign = FALSE;
}
else {
/* X.691, clause 26.5.7 */
if (bitRange < 16) doAlign = FALSE;
}
}
return doAlign;
}
else
return FALSE;
}
int bitAndOctetStringAlignmentTest (Asn1SizeCnst* pSizeList,
ASN1UINT itemCount,
ASN1BOOL bitStrFlag,
ASN1BOOL* pAlignFlag)
{
ASN1UINT threshold = (bitStrFlag) ? 16 : 2;
if (pSizeList == 0 || itemCount > threshold)
*pAlignFlag = TRUE;
else if (isFixedSize(pSizeList))
*pAlignFlag = FALSE;
else {
/* Variable length case: check size.. no alignment required if */
/* lower == upper and not extended.. */
ASN1BOOL extended;
Asn1SizeCnst* pSize = checkSize (pSizeList, itemCount, &extended);
if (pSize != 0)
*pAlignFlag = ((pSize->upper != pSize->lower) || pSize->extended);
else {
/* Note: we never should get here because constraint */
/* violation should have been caught when length was encoded */
/* or decoded.. */
return (ASN_E_CONSVIO);
}
}
return (ASN_OK);
}
Asn1SizeCnst* checkSize (Asn1SizeCnst* pSizeList,
ASN1UINT value,
ASN1BOOL* pExtendable)
{
Asn1SizeCnst* lpSize = pSizeList;
*pExtendable = isExtendableSize (lpSize);
while (lpSize) {
if (value >= lpSize->lower && value <= lpSize->upper) {
return (lpSize);
}
else lpSize = lpSize->next;
}
return 0;
}
int getPERMsgLen (OOCTXT* pctxt)
{
return (pctxt->buffer.bitOffset == 8) ?
pctxt->buffer.byteIndex : pctxt->buffer.byteIndex + 1;
}
int addSizeConstraint (OOCTXT* pctxt, Asn1SizeCnst* pSize)
{
Asn1SizeCnst* lpSize;
int stat = ASN_OK;
/* If constraint does not already exist, add it */
if (!pctxt->pSizeConstraint) {
pctxt->pSizeConstraint = pSize;
}
/* Otherwise, check to make sure given constraint is larger than */
/* the existing constraint.. */
else {
lpSize = pSize;
while (lpSize) {
if (pctxt->pSizeConstraint->lower <= lpSize->lower ||
pctxt->pSizeConstraint->upper >= lpSize->upper)
{
/* Set the extension flag to the value of the size */
/* constraint structure that the item falls within.. */
/* pctxt->pSizeConstraint->extended = lpSize->extended; */
break;
}
lpSize = lpSize->next;
}
if (!lpSize)
stat = ASN_E_CONSVIO;
}
return stat;
}
Asn1SizeCnst* getSizeConstraint (OOCTXT* pctxt, ASN1BOOL extbit)
{
Asn1SizeCnst* lpSize = pctxt->pSizeConstraint;
while (lpSize) {
if (lpSize->extended == extbit)
return lpSize;
else
lpSize = lpSize->next;
}
return NULL;
}
int checkSizeConstraint(OOCTXT* pctxt, int size)
{
Asn1SizeCnst* pSize;
ASN1UINT lower, upper;
ASN1BOOL extbit;
int stat;
/* If size constraint is present and extendable, decode extension */
/* bit.. */
if (isExtendableSize(pctxt->pSizeConstraint)) {
stat = DE_BIT (pctxt, &extbit);
if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
}
else extbit = 0;
/* Now use the value of the extension bit to select the proper */
/* size constraint range specification.. */
pSize = getSizeConstraint (pctxt, extbit);
lower = (pSize) ? pSize->lower : 0;
upper = (pSize) ? pSize->upper : ASN1UINT_MAX;
if (upper < (ASN1UINT)size) {
return LOG_ASN1ERR (pctxt, ASN_E_CONSVIO);
}
return ASN_OK;
}
ASN1UINT getUIntBitCount (ASN1UINT value)
{
/* Binary search - decision tree (5 tests, rarely 6) */
return
((value < 1<<15) ?
((value < 1<<7) ?
((value < 1<<3) ?
((value < 1<<1) ? ((value < 1<<0) ? 0 : 1) :
((value < 1<<2) ? 2 : 3)) :
((value < 1<<5) ? ((value < 1<<4) ? 4 : 5) :
((value < 1<<6) ? 6 : 7))) :
((value < 1<<11) ?
((value < 1<<9) ? ((value < 1<<8) ? 8 : 9) :
((value < 1<<10) ? 10 : 11)) :
((value < 1<<13) ? ((value < 1<<12) ? 12 : 13) :
((value < 1<<14) ? 14 : 15)))) :
((value < 1<<23) ?
((value < 1<<19) ?
((value < 1<<17) ? ((value < 1<<16) ? 16 : 17) :
((value < 1<<18) ? 18 : 19)) :
((value < 1<<21) ? ((value < 1<<20) ? 20 : 21) :
((value < 1<<22) ? 22 : 23))) :
((value < 1<<27) ?
((value < 1<<25) ? ((value < 1<<24) ? 24 : 25) :
((value < 1<<26) ? 26 : 27)) :
((value < 1<<29) ? ((value < 1<<28) ? 28 : 29) :
((value < 1<<30) ? 30 :
((value < 1UL<<31) ? 31 : 32))))));
}
void init16BitCharSet (Asn116BitCharSet* pCharSet, ASN116BITCHAR first,
ASN116BITCHAR last, ASN1UINT abits, ASN1UINT ubits)
{
pCharSet->charSet.nchars = 0;
pCharSet->charSet.data = 0;
pCharSet->firstChar = first;
pCharSet->lastChar = last;
pCharSet->unalignedBits = ubits;
pCharSet->alignedBits = abits;
}
ASN1BOOL isExtendableSize (Asn1SizeCnst* pSizeList)
{
Asn1SizeCnst* lpSize = pSizeList;
while (lpSize) {
if (lpSize->extended)
return TRUE;
else
lpSize = lpSize->next;
}
return FALSE;
}
static ASN1BOOL isFixedSize (Asn1SizeCnst* pSizeList)
{
Asn1SizeCnst* lpSize = pSizeList;
if (lpSize && !lpSize->extended && !lpSize->next) {
return (ASN1BOOL) (lpSize->lower == lpSize->upper);
}
return FALSE;
}
void set16BitCharSet
(OOCTXT* pctxt, Asn116BitCharSet* pCharSet, Asn116BitCharSet* pAlphabet)
{
/* Permitted alphabet range can either be specified as a range of */
/* characters or as a discrete set.. */
if (pAlphabet->charSet.data) {
int nocts = pAlphabet->charSet.nchars * 2;
pCharSet->charSet.nchars = pAlphabet->charSet.nchars;
pCharSet->charSet.data =
(ASN116BITCHAR*) ASN1MALLOC (pctxt, nocts);
if (pCharSet->charSet.data != NULL)
memcpy (pCharSet->charSet.data, pAlphabet->charSet.data, nocts);
}
else {
pCharSet->firstChar = pAlphabet->firstChar;
pCharSet->lastChar = pAlphabet->lastChar;
pCharSet->charSet.nchars = pCharSet->lastChar - pCharSet->firstChar;
}
pCharSet->unalignedBits = getUIntBitCount (pCharSet->charSet.nchars);
pCharSet->alignedBits = 1;
while (pCharSet->unalignedBits > pCharSet->alignedBits)
pCharSet->alignedBits <<= 1;
}