📄 q931.c
字号:
bit += 8;
else
return bit;
}
}
else
bit += 8;
newBit = bit;
if ((level == IE_LEVEL) && !(tag & 0x80))
{
int ieLen;
int lenLen;
if (nodeId != RV_ERROR_UNKNOWN && tagClass == pstTagApplication)
{
lenLen = 16;
ieLen = (buffer[bit/8]*256 + buffer[bit/8 + 1])*8;
}
else
{
lenLen = 8;
ieLen = buffer[bit/8]*8;
}
bit += lenLen;
newBit = ieLen + bit;
}
level++;
if (nodeId != RV_ERROR_UNKNOWN)
{
int i;
int oldBit;
int vcNodeId=vNodeId;
pstChildExt child;
numOfChildren = pstGetNumberOfChildren(synH,nodeId);
switch (type)
{
case pstSet:
{
int searchedTag = -1;
int lastTag;
RvUint32* iter;
RvBool firstRun = RV_TRUE;
if (fieldId!=RV_ERROR_UNKNOWN)
if ((vcNodeId = pvtAdd(valH, vNodeId, fieldId, 0, NULL, NULL)) < 0)
return vcNodeId;
iter = pstGetChildExt(synH, nodeId, 1, &child);
i = 0;
while (bit < length)
{
lastTag = searchedTag;
searchedTag = buffer[bit/8];
if (searchedTag < lastTag)
{
/* Seems like this Q931 buffer has its tags unsorted (which is not standard) */
RvLogWarning(&rvQ931ErrLogSource, (&rvQ931ErrLogSource,
"Q931DInter: tags not sorted [%d].", nodeId));
/* Make sure the iterator starts all over again - we must search it all */
iter = pstGetChildExt(synH, nodeId, 1, &child);
}
else if (searchedTag == lastTag)
{
if (pstGetNodeType(synH, child.nodeId) != pstSequenceOf)
{
/* Oh - same tag twice - let's see if our application is ready for this one */
/* If it's ready, then it will have a SEQUENCE OF field right after the current
one, which will have the same tag */
pstChildExt nextChild;
RvUint32* nextIter = pstGetBrotherExt(synH, 1, iter, &nextChild);
if ((nextIter != NULL) && (pstGetNodeType(synH, nextChild.nodeId) == pstSequenceOf))
{
if (pstGetTag(synH, pstGetNodeOfId(synH, nextChild.nodeId), NULL) == searchedTag)
{
/* Definition has a SEQUENCE OF with the same tag value for the elements
let's use them */
iter = nextIter;
child = nextChild;
i++;
}
}
}
/* If we didn't use the SEQUENCE OF, then we'll just rewrite the current value,
as was the case in previous versions */
}
else
{
if (firstRun == RV_FALSE)
{
/* Skip the current field - we don't really have to check it */
iter = pstGetBrotherExt(synH, 1, iter, &child);
i++;
}
else
firstRun = RV_FALSE; /* We should make sure to check the first field */
}
/* Start searching for the tag and decode it while we're at it */
while (i < numOfChildren)
{
oldBit = bit;
bit = Q931DInter(synH, child.nodeId, child.fieldId, valH, vcNodeId, level, buffer, bit, length);
if (bit < 0)
{
/* Had an error */
return bit;
}
if (bit != oldBit)
{
/* We actually decoded it - we can get out of this while loop */
break;
}
/* Try the next one */
iter = pstGetBrotherExt(synH, 1, iter, &child);
i++;
}
if (i == numOfChildren)
{
/* Didn't find this tag - we should decode it and skip it */
bit = Q931DInter(synH, RV_ERROR_UNKNOWN, RV_ERROR_UNKNOWN, valH, RV_ERROR_UNKNOWN, level, buffer, bit, length);
if (bit < 0)
return bit;
/* We want to start the search again so the tags we're going to see next
are going to be handled (iter==NULL) */
firstRun = RV_TRUE;
iter = pstGetChildExt(synH, nodeId, 1, &child);
searchedTag = -1;
i = 0;
}
}
/* No real value: pvtSet(valH, vcNodeId, fieldId, pvtNumChilds(valH, vcNodeId), NULL); */
}
break;
case pstChoice:
{
RvUint32* iter;
if (fieldId!=RV_ERROR_UNKNOWN)
{
if ((vcNodeId = pvtAdd(valH, vNodeId, fieldId, 0, NULL, NULL)) < 0)
return vcNodeId;
}
iter = pstGetChildExt(synH, nodeId, 1, &child);
for (i = 1; i <= numOfChildren; i++)
{
oldBit = bit;
bit = Q931DInter(synH, child.nodeId, child.fieldId, valH, vcNodeId, level, buffer, bit, length);
if (bit < 0)
return bit;
if (bit != oldBit)
{
pvtSet(valH, vcNodeId, fieldId, child.fieldId, NULL);
break;
}
iter = pstGetBrotherExt(synH, i+1, iter, &child);
}
if (i > numOfChildren)
{
RvLogError(&rvQ931ErrLogSource, (&rvQ931ErrLogSource,
"Q931DInter: Choice value out of range [%d].", nodeId));
return RV_ERROR_UNKNOWN;
}
}
break;
case pstSequence:
{
RvUint32* iter;
RvBool extended = RV_FALSE;
RvBool extendedNode=pstGetIsExtended(synH,nodeId);
if (fieldId != RV_ERROR_UNKNOWN)
{
if ((vcNodeId = pvtAdd(valH, vNodeId, fieldId, 0, NULL, NULL)) < 0)
return vcNodeId;
}
if (newBit != bit)
length = newBit;
iter = pstGetChildExt(synH, nodeId, 1, &child);
for (i = 1; i <= numOfChildren; i++)
{
if (extendedNode && !(bit%8))
{
extended=!(buffer[bit/8]&0x80);
bit++;
}
bit = Q931DInter(synH, child.nodeId, child.fieldId, valH, vcNodeId, level, buffer, bit, length);
if (bit < 0)
return bit;
if (extendedNode && !(bit%8) && !extended)
break;
iter = pstGetBrotherExt(synH, i+1, iter, &child);
}
pvtSet(valH, vcNodeId, fieldId, pvtNumChilds(valH, vcNodeId), NULL);
if (extendedNode && extended)
while (!(buffer[bit/8]&0x80)) bit += 8;
}
break;
case pstSequenceOf:
{
/* Seems like we should simulate receiving several information elements */
int vSeqOfNode;
/* Let's make sure first that we have the SEQUENCE OF in the PVT */
vSeqOfNode = pvtAdd(valH, vNodeId, fieldId, 0, NULL, NULL);
if (vSeqOfNode < 0)
return vSeqOfNode;
/* Now let's add a new last element to this array by decoding the field - make sure
we go back in the buffer and up in level to simulate proper type and position. */
bit = Q931DInter(synH, pstGetNodeOfId(synH, nodeId), -1, valH, vSeqOfNode, level-1, buffer, bit-16, length);
}
break;
case pstInteger:
{
RvUint32 value = 0;
int to , from, bits;
pstGetNodeRange( synH, nodeId, &from, &to);
bits=qILog2(to-from)+1;
if (bits <= 8)
value = (buffer[bit/8] >> ((8 - (bit%8)) - bits))&((1 << bits) - 1);
else
if (bits == 16)
value = (buffer[bit/8] << 8) + buffer[bit/8 + 1];
if ((ret = pvtAdd(valH, vNodeId, fieldId, (RvInt32)value, NULL, NULL)) < 0)
return ret;
bit += bits;
}
break;
case pstNull:
{
if ((ret = pvtAdd(valH, vNodeId, fieldId, 0, NULL, NULL)) < 0)
return ret;
}
break;
case pstIA5String:
case pstOctetString:
{
RvUint32 strLength;
char buff[256];
strLength = (((level != IE_LEVEL + 1) ? length:newBit) - bit)/8;
if (bit%8)
{
bit += 7;
bit -= bit%8;
}
strLength = RvMin(strLength, 255);
memcpy(buff, &(buffer[bit/8]), (int)strLength);
if ((ret = pvtAdd(valH, vNodeId, fieldId, (RvInt32)strLength, buff, NULL)) < 0)
return ret;
}
break;
default:
RvLogError(&rvQ931ErrLogSource, (&rvQ931ErrLogSource,
"Q931DInter: Unknown type (node=%d) - don't know how to decode.",
vNodeId));
return -1;
}
}
if (level == IE_LEVEL + 1)
{
bit = newBit;
}
return bit;
}
int Q931Decode(HPVT valH,int vNodeId,RvInt32 fieldId,RvUint8* buffer,int length,int *decoded)
{
HPST synH=pvtGetSynTree(valH, vNodeId);
int nodeId,ret;
pvtGet(valH, vNodeId, NULL, &nodeId, NULL, NULL);
ret=Q931DInter(synH,nodeId,fieldId,valH,vNodeId,ROOT_LEVEL,buffer,0,length*8);
if (ret < 0)
{
RvLogError(&rvQ931ErrLogSource, (&rvQ931ErrLogSource,
"Q931Decode: Error decoding Q931 message (%d).", ret));
return ret;
}
*decoded=ret/8;
return 0;
}
int q931Install(void)
{
emTypeOfEncoding eSys;
static RvBool q931ConstructFirstTime = RV_TRUE;
eSys.Encode = Q931Encode;
eSys.Decode = Q931Decode;
if (q931ConstructFirstTime)
{
/* First time we call q931Install() - make sure we register our log sources */
q931ConstructFirstTime = RV_FALSE;
RvLogSourceConstruct(RvLogGet(), &rvQ931LogSource, RV_LOG_LIBCODE_ASN1, "Q931", "PER Encoder/Decoder");
RvLogSourceConstruct(RvLogGet(), &rvQ931ErrLogSource, RV_LOG_LIBCODE_ASN1, "Q931ERR", "Q931 Errors");
}
return emSetEncoding(emQ931,&eSys);
}
#ifdef __cplusplus
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -