C:TLV訊息編碼及常用操作

來源:互聯網
上載者:User

標籤:tlv c 鏈表

/*1、TLV簡介:在通訊系統中,兩個裝置之前必然存在訊息互動,訊息的格式也存在各種編碼類別型,本文僅描述TLV編碼的訊息格式。Type-length-value(TLV)格式中T、L的長度固定,通常為1-8個4個位元組,V的長度不固定,由L的值表示,V的內容也可以嵌套子TLV格式。舉例:假設訊息按大端模式存放,T佔4個位元組,L佔2個位元組,下面的訊息: unsigned char pMsg[] = {0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01,0x01,0x01, 0x01} T = {0x09, 0x00, 0x00, 0x00},值為9。 L = {0x04, 0x00},值為4。 V = {0x01,0x01,0x01, 0x01} ,長度為4,每個位元組的值均為1。2、代碼實現:a、按T的值由小到大排序一個訊息(假定訊息中不存在T相同的信元);             b、在兩個訊息中尋找相同的信元(T、L、V)均相同,並輸出信元個數。       作者:Socrates日期:2014-08-05*/#include "stdafx.h"#include <stdlib.h>#include <memory.h>#define TLV_T_LEN (4)#define TLV_L_LEN (2)/*錯誤碼*/enum _RetCode{    ERR = -1, /*失敗*/    OK = 0    /*成功*/}RETCODE;/*信元TLV結構*/typedef struct _stIE {    unsigned int ulTag;    /*T*/    unsigned short usLen;  /*L*/    unsigned char *pValue; /*V*/}IE;/*訊息鏈表*/typedef struct _stMsg {    IE ie;    struct _stMsg *pNext;}Msg;/*功能:建立鏈表*/int CreateMsgList(Msg *&pList){    pList = (Msg *)malloc(sizeof(Msg));    if (NULL == pList)    {        return ERR;    }    memset(&(pList->ie), 0, sizeof(IE));    pList->pNext = NULL;    return OK;}/*功能:銷毀鏈表*/void DestoryMsgList(Msg *pList){    if (NULL == pList)    {        return;    }        Msg *p = pList;    while(NULL != p)    {        p = p->pNext;        free(pList);        pList = p;    }      free(pList);    pList = NULL;    return;}/*功能:向訊息鏈表中插入信元,並保持按Tag遞增*/int InsertIEToMsgList(Msg *pMsgList, const IE *pIE){    if ((NULL == pMsgList)        || (NULL == pIE))    {        return ERR;    }    /*鏈表銷毀時釋放*/    Msg *pInsertMsg = (Msg *)malloc(sizeof(Msg));    if (NULL == pInsertMsg)    {        return ERR;    }    /*建立鏈表結點*/    memcpy(&(pInsertMsg->ie), pIE, sizeof(IE));    pInsertMsg->pNext = NULL;    /*按Tag遞增插入結點,保持鏈表有序,不帶頭結點*/    Msg *p = pMsgList;    while(NULL != p->pNext)    {        if ((p->pNext->ie.ulTag) > (pIE->ulTag))        {            break;        }        p = p->pNext;    }    pInsertMsg->pNext = p->pNext;    p->pNext = pInsertMsg;        return OK;}/*功能:擷取指定訊息中的第一個信元*/IE *GetIEFromMsg(const unsigned char *pInMsg){    if (NULL == pInMsg)    {        return NULL;    }    /*鏈表銷毀時釋放*/    IE *pIE = (IE *)malloc(sizeof(IE));    if (NULL == pIE)    {        return NULL;    }    memset(pIE, 0, sizeof(IE));        pIE->ulTag = *(unsigned int *)pInMsg;    pIE->usLen = *(unsigned short *)(pInMsg + TLV_T_LEN);    pIE->pValue = (unsigned char *)(pInMsg + TLV_T_LEN + TLV_L_LEN);    return pIE;}/*功能:構造有序訊息鏈表*/int CreateSortMsgList(unsigned char *pInMsg, unsigned int ulMsgLen, Msg *&pOutMsgList){    if ((NULL == pInMsg)        ||(0 == ulMsgLen))    {        return ERR;    }    /*建立鏈表*/    if (ERR == CreateMsgList(pOutMsgList))    {        return ERR;    }    unsigned int iTmpMsgLen = 0;    IE *pIE = NULL;    /*遍曆訊息,注意擷取信元並插入訊息鏈表*/    while(iTmpMsgLen < ulMsgLen)    {        pIE = GetIEFromMsg(pInMsg);        if (NULL == pIE)        {            return ERR;        }        if(ERR == InsertIEToMsgList(pOutMsgList, pIE))        {            return ERR;        }        pInMsg += (TLV_T_LEN + TLV_L_LEN + pIE->usLen);        iTmpMsgLen += (TLV_T_LEN + TLV_L_LEN + pIE->usLen);    }        return OK;  }/*功能:訊息排序*/int Sort(unsigned char *pInMsg, unsigned int ulMsgLen, unsigned char *pOutMsg){    if ((NULL == pInMsg)        || (NULL == pOutMsg)        || (0 == ulMsgLen))    {        return ERR;    }    /*建立有序訊息鏈表*/    unsigned char *pTmp = pOutMsg;    Msg *pMsgList = NULL;    if (ERR == CreateSortMsgList(pInMsg, ulMsgLen, pMsgList))    {        DestoryMsgList(pMsgList);        return ERR;    }    /*輸出排序後的訊息*/    Msg *pList = pMsgList->pNext;    while(NULL != pList)    {        memcpy(pTmp, &(pList->ie), TLV_T_LEN + TLV_L_LEN);        memcpy(pTmp + TLV_T_LEN + TLV_L_LEN, pList->ie.pValue, pList->ie.usLen);        pTmp += (TLV_T_LEN + TLV_L_LEN + pList->ie.usLen);        pList = pList->pNext;    }    DestoryMsgList(pMsgList);    return OK;}/*功能:比較兩個信元是否相同*/int IsSameIE(IE *pIE1, IE *pIE2){    if ((NULL == pIE1)        || (NULL == pIE2))    {        return ERR;     }    if ((pIE1->ulTag == pIE2->ulTag)        && (pIE1->usLen == pIE2->usLen)        && (0 == memcmp(pIE1->pValue, pIE2->pValue, pIE1->usLen)))    {        return OK;    }            return ERR;}/*功能:比較兩個訊息,並輸出相同信元個數*/int CompareMsg(unsigned char *pMsg1,                unsigned int ulMsgLen1,                unsigned char *pMsg2,               unsigned int ulMsgLen2,               unsigned int *ulSameNum){    /*建立有序訊息鏈表1*/    Msg *pMsgList1 = NULL;    if (ERR == CreateSortMsgList(pMsg1, ulMsgLen1, pMsgList1))    {        DestoryMsgList(pMsgList1);        return ERR;    }    /*建立有序訊息鏈表2*/    Msg *pMsgList2 = NULL;    if (ERR == CreateSortMsgList(pMsg2, ulMsgLen2, pMsgList2))    {        DestoryMsgList(pMsgList1);        DestoryMsgList(pMsgList2);        return ERR;    }    Msg *p = pMsgList1->pNext;    Msg *q = NULL;    unsigned int iCount = 0;    /*比較訊息*/    while(NULL != p)    {        q = pMsgList2->pNext;        while(NULL != q)        {            if (OK == IsSameIE(&(p->ie), &(q->ie)))            {                iCount++;            }                 q = q->pNext;        }        p = p->pNext;    }    DestoryMsgList(pMsgList1);    DestoryMsgList(pMsgList2);        *ulSameNum = iCount;    return OK;}int main(int argc, char* argv[]){    unsigned char pMsg[] = {0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01,0x01,0x01, 0x01,                            0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x02,0x02,0x02, 0x02, 0x02, 0x02, 0x02,                            0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03,0x03,0x03, 0x03, 0x03,                            0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01,0x01,0x01, 0x01,                            0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x08,0x08,                            0x01, 0x00, 0x01, 0x00, 0x04, 0x00, 0x09,0x09,0x09, 0x09};    unsigned char pMsg2[] = {0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01,0x01,0x01, 0x01,                            0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x02,0x02,0x02, 0x02, 0x02, 0x02, 0x02,                            0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03,0x03,0x03, 0x03, 0x03,                            0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01,0x01,0x01, 0x01,                            0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x08,0x08,                            0x01, 0x00, 0x01, 0x00, 0x04, 0x00, 0x09,0x09,0x09, 0x09};    int iLen = sizeof(pMsg) / sizeof(pMsg[0]);    for (int i = 0; i < iLen; i++)    {        printf("0x%x,", pMsg[i]);    }    printf("\n\n");    unsigned char *pSortMsg = (unsigned char *)malloc(iLen);    if (NULL == pSortMsg)    {        return ERR;    }    if (ERR != Sort(pMsg, iLen, pSortMsg))    {        for (int i = 0; i < iLen; i++)        {            printf("0x%x,", pSortMsg[i]);        }    }    int iLen2 = sizeof(pMsg2) / sizeof(pMsg2[0]);    unsigned int iSameNum = 0;        if (ERR != CompareMsg(pMsg, iLen, pMsg2, iLen2, &iSameNum))    {        printf("\nSame Number is %d", iSameNum);    }        getchar();    return 0;}



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.