⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 q931.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 2 页
字号:
                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 + -