mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-15 22:38:08 +00:00
Many architectural and functional changes. Main changes are threading model chanes (many thread in ooh323 stack instead of one), modifications and improvements in signalling part, additional codecs support (726, speex), t38 mode support. This module tested and used in production environment. (closes issue #15285) Reported by: may213 Tested by: sles, c0w, OrNix Review: https://reviewboard.asterisk.org/r/324/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@227898 65c4cc65-6c06-0410-ace0-fbb531ad65f3
291 lines
8.1 KiB
C
291 lines
8.1 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 <asterisk.h>
|
|
#include <asterisk/lock.h>
|
|
|
|
#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;
|
|
|
|
}
|
|
|