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

📄 q931.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "rvstdio.h"
#include "rvlog.h"
#include "psyntreeStackApi.h"
#include "pvaltree.h"
#include "emanag.h"
#include "q931.h"


#ifdef __cplusplus
extern "C" {
#endif

static RvLogSource rvQ931LogSource;
static RvLogSource rvQ931ErrLogSource;


int qILog2(RvInt32 N)
{
    int i=-1;
    while(N) {i++;N>>=1;}
    return i;
}

typedef enum
{
    ROOT_LEVEL = 0,
    MSG_LEVEL = 1,
    OTHER_IES_LEVEL = 2,
    IE_LEVEL = 3,
    OCTET_LEVEL = 4,
    FIELD_LEVEL = 5
} qLevels;


int Q931EInter(HPST synH,int nodeId,RvInt32 fieldId ,HPVT valH,int vNodeId,int level,RvUint8* buffer,int bit,int length)
{
    int lengthBit=0;
    pstTagClass  tagClass;
    pstNodeType type;
    int numOfChildren;
    int tag=pstGetTag(synH,nodeId,&tagClass);
    if (tagClass==pstTagPrivate && tag!=emQ931)
    {
        int len, ret;
        RvLogDebug(&rvQ931LogSource, (&rvQ931LogSource, "Private tag %d", tag));
        ret = emEncodeExt(valH,vNodeId,buffer+bit/8,length,&len);
        if (ret < 0)
        {
            RvLogError(&rvQ931ErrLogSource, (&rvQ931ErrLogSource,
                "Q931EInter: Private tag encoding error (%d).", tag));
            return RV_ERROR_UNKNOWN;
        }
        return bit+len*8;
    }

    if (tag != RV_ERROR_UNKNOWN)
    {
        /* See if we have to place a tag in front of the encoded element */
        if ((tagClass == pstTagEmpty) || (tagClass == pstTagApplication))
        {
            buffer[bit/8] = (RvUint8)tag;
            bit += 8;
        }

        if (level == IE_LEVEL)
        {
            /* It's an information element - we have to add a length as well... */
            lengthBit = bit;
            if (tagClass == pstTagApplication)
                bit += 16;
            else
                bit += 8;
        }
    }

    level++;
    type=pstGetNodeType(synH,nodeId);

    RvLogDebug(&rvQ931LogSource, (&rvQ931LogSource,
        "Encoding %s: %s [%d].",
        (fieldId>=0)?pstGetFieldNamePtr(synH, fieldId):"(null)", pstGetTokenName(type), bit));
    numOfChildren=pstGetNumberOfChildren(synH,nodeId);
    switch(type)
    {
        case pstSet:
        {
            int i;
            pstChildExt child;
            int childNodeId;
            RvUint32* iter = pstGetChildExt(synH,nodeId,1,&child);
            for (i=1;i<=numOfChildren;i++)
            {
                if (pvtGetChild(valH,vNodeId,child.fieldId,&childNodeId) < 0)
                {
                    if ((child.isOptional == RV_TRUE) || (child.isDefault == RV_TRUE))
                    {
                        iter = pstGetBrotherExt(synH, i+1, iter, &child);
                        continue;
                    }
                    else
                    {
                          RvLogError(&rvQ931ErrLogSource, (&rvQ931ErrLogSource,
                              "Q931EInter: non optional Child not found [%d]%s.",
                              vNodeId,
                              pstGetFieldNamePtr(synH, child.fieldId)));
                          return RV_ERROR_UNKNOWN;
                    }
                }
                bit=Q931EInter(synH,child.nodeId,child.fieldId,valH,childNodeId,level,buffer,bit,length);
                if(bit<0) return bit;
                iter = pstGetBrotherExt(synH, i+1, iter, &child);
            }
        }
        break;

        case pstSequence:
        {
            int i;
            int childNodeId;
            pstChildExt child;
            RvUint32* iter = pstGetChildExt(synH,nodeId,1,&child);
            for (i=1;;i++)
            {
                if (pstGetIsExtended(synH,nodeId) && !(bit%8))
                {
                    buffer[bit/8]=0x80;
                    bit++;
                }
                if (pvtGetChild(valH,vNodeId,child.fieldId,&childNodeId)==RV_ERROR_UNKNOWN)
                {
                    if (child.isExtended)
                    {
                        if(bit%8==1)
                        {
                            bit--;
                            buffer[bit/8-1]|=0x80;
                        }
                        else
                        {
                            bit+=8-bit%8;
                            /* ?????????????? */
                        }
                        break;
                    }
                    else if ((child.isOptional == RV_TRUE) || (child.isDefault == RV_TRUE))
                    {
                        /* Optional field - ignore and go on */
                        if (i == numOfChildren)
                            break;
                        iter = pstGetBrotherExt(synH, i+1, iter, &child);
                        continue;
                    }
                    else
                    {
                        RvLogError(&rvQ931ErrLogSource, (&rvQ931ErrLogSource,
                            "Q931EInter: non optional Child not found [%d]%s->%s.",
                            vNodeId, pstGetFieldNamePtr(synH,fieldId),
                            pstGetFieldNamePtr(synH, child.fieldId)));
                        return RV_ERROR_UNKNOWN;
                    }
                }
                bit=Q931EInter(synH,child.nodeId,child.fieldId,valH,childNodeId,level,buffer,bit,length);
                if(bit<0) return bit;
                if (i==numOfChildren) break;
                if (pstGetIsExtended(synH,nodeId) && !(bit%8)) buffer[bit/8-1]&=0x7f;
                iter = pstGetBrotherExt(synH, i+1, iter, &child);
            }
        }
        break;

        case pstSequenceOf:
        {
            /* SEQUENCE OF in Q931 is handled as if it's not there. We use it to allow several
               information elements with the same tag to be encoded/decoded together. */
            int childNodeId;
            int childSynNodeId;
            RvPstFieldId childFieldId;

            /* Loop through the array and encode each element as if it was a fresh one out
               of the box. */
            childNodeId = pvtChild(valH, vNodeId);
            pvtGet(valH, childNodeId, &childFieldId, &childSynNodeId, NULL, NULL);

            while (RV_PVT_NODEID_IS_VALID(childNodeId))
            {
                /* We go and encode our internal structures without increasing the level since we
                   don't want the SEQUENCE OF structure to show up in the encoding */
                bit = Q931EInter(synH, childSynNodeId, childFieldId, valH, childNodeId, level-1, buffer, bit, length);
                if (bit < 0)
                    return bit;

                /* Get the next one */
                childNodeId = pvtBrother(valH, childNodeId);
            }
        }
        break;

        case pstChoice:
        {
            int childNodeId=pvtChild(valH,vNodeId);
            int childSynNodeId;
            RvPstFieldId childFieldId;

            if(childNodeId==RV_ERROR_UNKNOWN)
            {
                RvLogError(&rvQ931ErrLogSource, (&rvQ931ErrLogSource,
                    "perEncodeChoice: Value node does not exist. [%s]",
                    pstGetFieldNamePtr(synH, fieldId)));
                return RV_ERROR_UNKNOWN;
            }

            pvtGet(valH,childNodeId,&childFieldId,&childSynNodeId,NULL,NULL);

            bit=Q931EInter(synH,childSynNodeId,childFieldId,valH,childNodeId,level,buffer,bit,length);
            if(bit<0) return bit;
        }
        break;

        case pstInteger:
        {
            RvUint32 value;
            int to , from, bits;
            pstGetNodeRange( synH, nodeId, &from, &to);
            bits=qILog2(to-from)+1;
            pvtGet(valH,vNodeId,NULL,NULL,(RvInt32*)&value,NULL);
            if (bits<=8)  {buffer[bit/8]&=~(((1<<bits)-1)<<(8-(bit%8)-bits));buffer[bit/8]|=value<<(8-(bit%8)-bits);}
            else if (bits==16)
            {
                buffer[bit/8]=(RvUint8)(value>>8);
                buffer[bit/8+1]=(RvUint8)value;
            }
           bit+=bits;
        }
        break;

        case pstIA5String:
        case pstOctetString:
        {
            RvUint32 strLength;
            if (bit%8) {bit+=7; bit-=bit%8;}
            pvtGet(valH,vNodeId,NULL,NULL,(RvInt32*)&strLength,NULL);
            pvtGetString(valH,vNodeId,(RvInt32)strLength,(char*)&(buffer[bit/8]));
            bit+=((int)strLength)*8;
        }
        break;

        case pstNull:
            if(bit-lengthBit==8) bit-=8;
            return bit;

        default:
            RvLogError(&rvQ931ErrLogSource, (&rvQ931ErrLogSource,
                "Q931EInter: Unknown type (node=%d) - don't know how to encode.",
                vNodeId));
            return -1;
    }

    if (level == IE_LEVEL+1)
    {
        /* We should place the length value for this field... */
        if (tagClass==pstTagApplication)
        {
            /* Application tags get a length of 2 bytes */
            buffer[lengthBit/8]=(unsigned char)(((bit-lengthBit)/8-2)>>8);
            buffer[lengthBit/8+1]=(unsigned char)((bit-lengthBit)/8-2);
        }
        else
        {
            /* Only one byte length for most fields... */
            buffer[lengthBit/8]=(unsigned char)((bit-lengthBit)/8-1);
        }
    }

    return bit;
}




int Q931Encode(HPVT valH,int vNodeId,RvUint8* buffer,int length,int*encoded)
{
    HPST synH=pvtGetSynTree(valH, vNodeId);
    int nodeId;
    pvtGet(valH, vNodeId, NULL, &nodeId, NULL, NULL);
    *encoded=Q931EInter(synH,nodeId,-1,valH,vNodeId,ROOT_LEVEL,buffer,0,length*8);
    if(*encoded<0)
      return(*encoded);
    else
    {
      *encoded /= 8;
      return 0;
    }
}


int Q931DInter(HPST synH,int nodeId,RvInt32 fieldId,HPVT valH,int vNodeId,int level,RvUint8* buffer,int bit,int length)
{
    int newBit, ret;
    int tag = buffer[bit/8];
    pstTagClass  tagClass;
    pstNodeType type;
    int numOfChildren;
    int stag;
    
    type = pstGetNodeType(synH, nodeId);
    if (type != pstSequenceOf)
    {
        /* "Regular node" - get the tag from it */
        stag = pstGetTag(synH, nodeId, &tagClass);
    }
    else
    {
        /* It's a SEQUENCE OF - the tag is one step down */
        stag = pstGetTag(synH, pstGetNodeOfId(synH, nodeId), &tagClass);
    }

    if (nodeId != RV_ERROR_UNKNOWN)
    {
        if (tagClass == pstTagPrivate && stag != emQ931)
        {
            int len;
            ret = emDecodeExt(valH, vNodeId, fieldId, buffer + bit/8, (length/8) - (bit/8), &len);
            if (ret >= 0)
                return bit + len*8;
            else
                return ret;
        }
        if ((tagClass == pstTagEmpty || tagClass == pstTagApplication) &&  stag != RV_ERROR_UNKNOWN)
        {
            if (tag == stag)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -