C: TLV message encoding and Common Operations
/* 1. TLV Introduction: in the communication system, there must be message interaction between two devices before, and the message format also has various encoding types. This article only describes the Message format of TLV encoding. In the Type-length-value (TLV) format, the length of T and L is fixed, usually 1-8 4 bytes. The length of V is not fixed and is represented by the value of L, the content of V can also be nested in the subtlv format. Example: Assume that messages are stored in the big-end mode, where T occupies 4 bytes and L occupies 2 bytes. The following message is: unsigned char pMsg [] = {0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01,0x01,0x01, 0x01} T = {0x09, 0x00, 0x00, 0x00}. The value is 9. L = {0x04, 0x00}. The value is 4. V = {0x01,0x01,0x01, 0x01}. The length is 4 and the value of each byte is 1. 2. Code implementation: a. Sort a message by T value from small to large (assuming that T is not in the message ); b. Find the same cells (T, L, V) in the two messages and output the same number of cells. Author: Socrates Date: 2014-08-05 */# include "stdafx. h" # include
# Include
# Define TLV_T_LEN (4) # define TLV_L_LEN (2)/* error code */enum _ RetCode {ERR =-1, /* failed */OK = 0/* succeeded */} RETCODE;/* cell TLV structure */typedef struct _ stIE {unsigned int ulTag; /* T */unsigned short usLen;/* L */unsigned char * pValue;/* V */} IE; /* message linked list */typedef struct _ stMsg {IE ie IE; struct _ stMsg * pNext;} Msg;/* function: Create a linked list */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;}/* function: destroy the linked list */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;}/* function: insert cells into the message linked list and keep increasing by Tag */int InsertIEToMsgList (Msg * pMsgList, const IE * pIE) {if (NULL = pMsgList) | (NULL = pIE) {return ERR;}/* released when the linked list is destroyed */Msg * pInsertMsg = (Msg *) malloc (sizeof (Msg )); if (NULL = pInsertMsg) {return ERR;}/* Create a linked list node */memcpy (& (pInsertMsg-> ie), pIE, sizeof (IE )); pInsertMsg-> pNext = NULL;/* Press The Tag is inserted progressively to the node, keeping the linked list in order, without leading the node */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;}/* function: Get the first cell in the specified message */IE * GetIEFromMsg (const unsigned char * pInMsg) {if (NULL = pInMsg) {return NULL ;} /* release when the linked list is destroyed */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 ;} /* function: Create an ordered message linked list */int CreateSortMsgList (unsigned char * pInMsg, unsigned int ulMsgLen, Msg * & pOutMsgList) {if (NULL = pInMsg) | (0 = ulMsgLen) {return ERR;}/* Create a linked list */if (ERR = CreateMsgList (pOutMsgList) {return ERR ;} unsigned int iTmpMsgLen = 0; IE * pIE = NULL;/* Traversal Message, pay attention to getting cells and inserting the message linked list */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;}/* function: Message sorting */int Sort (unsigned char * pInMsg, unsigned int ulMsgLen, unsigned char * pOutMsg) {if (NULL = pInMsg) | (NULL = pOutMsg) | (0 = ulMsgLen) {return ERR;}/* Create an ordered message linked list */unsigned char * pTmp = pOutMsg; msg * pMsgList = NULL; if (ERR = CreateSortMsgList (pInMsg, ulMsgLen, pMsgList) {DestoryMsgList (pMsgList); return ERR ;} /* output ordered messages */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;}/* function: compare whether two cells are the same */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;}/* function: Compares two messages and outputs the same number of cells */int CompareMsg (unsigned char * pMsg1, unsigned int ulmsgl1, unsigned char * pMsg2, unsigned int ulmsgl2, unsigned int * ulSameNum) {/* Create an ordered message linked list 1 */Msg * pMsgList1 = NULL; if (ERR = CreateSortMsgList (pMsg1, ulmsgl1, pMsgList1 )) {DestoryMsgList (pMsgList1); return ERR;}/* Create Create an ordered message linked list 2 */Msg * pMsgList2 = NULL; if (ERR = CreateSortMsgList (pMsg2, ulmsgl2, pMsgList2) {DestoryMsgList (pMsgList1); then ); return ERR;} Msg * p = pMsgList1-> pNext; Msg * q = NULL; unsigned int iCount = 0;/* compare message */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, 0x 03,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"); 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 ;}