#include <stdio.h> #define X_LEN_OF_TAG_MAX ( 2 )
#define X_LEN_OF_LEN_MAX ( 2 ) struct st_tlv_t {
unsigned int TAG;
unsigned char isCustructed;
unsigned int valLen;
unsigned char *pVal; }; static int skipZeroBytes( unsigned char **pcur, unsigned char *end )
{
while( **pcur == && (*pcur < end) )
(*pcur)++; if( *pcur < end )
return ; return ;
} static int parseTag( unsigned char **pcur, unsigned char *end, struct st_tlv_t *tlv )
{
unsigned char *pp;
int lenOfTag;
int i; if( *pcur >= end )
return ; pp = *pcur; lenOfTag = ;
if( (*pp++ & 0x1f) == 0x1f )
{
do {
if( pp >= end )
return ; lenOfTag++;
} while( (*pp++) & 0x80 );
}
if( lenOfTag > X_LEN_OF_TAG_MAX )
{
return ;
} tlv->isCustructed = ( **pcur & ( << ) ) ? : ; tlv->TAG = ;
for( i = ; i < lenOfTag; i++ )
{
tlv->TAG <<= ;
tlv->TAG |= *(*pcur + i );
} (*pcur) += lenOfTag;
//printf("tlv->TAG:%x\r\n", tlv->TAG);
return ;
} static int parseLength( unsigned char **pcur, unsigned char *end, struct st_tlv_t *tlv )
{
unsigned char *pp;
int lenOfLen;
int i; if( *pcur >= end || **pcur == )
return ; pp = *pcur; if( *pp & 0x80 )
{
lenOfLen = *pp & 0x7F;
if( pp + lenOfLen >= end )
return ;
if( lenOfLen > X_LEN_OF_LEN_MAX )
return ;
pp++;
tlv->valLen = ;
for( i = ; i < lenOfLen; i++ )
{
tlv->valLen <<= ;
tlv->valLen |= *(pp + i );
}
(*pcur) += (lenOfLen+);
}
else
{
tlv->valLen = **pcur;
(*pcur)++;
}
//printf("tlv->valLen:%d\r\n", tlv->valLen);
return ;
} static int parseValue( unsigned char **pcur, unsigned char *end, struct st_tlv_t *tlv )
{
if( (*pcur + tlv->valLen) > end )
return ; tlv->pVal = ( unsigned char *)(*pcur); return ;
} int parseTlv( unsigned char *buffer, int length, struct st_tlv_t *tlv )
{
unsigned char *cur;
unsigned char *end; cur = buffer;
end = buffer + length; if( !skipZeroBytes( &cur, end ) )
return ; if( !parseTag( &cur, end, tlv ) )
return ; if( !parseLength( &cur, end, tlv ) )
return ; if( !parseValue( &cur, end, tlv ) )
return ; return ;
} int printTlv( struct st_tlv_t *tlv )
{
int i;
printf("\r\n[%x] len:%d\r\n", tlv->TAG, tlv->valLen);
for( i = ; i < tlv->valLen; i++ )
printf("%02x", tlv->pVal[i]);
printf("\r\n"); return ;
} int parseTlvXXX( unsigned char *buffer, int length, int reverse )
{
unsigned char *cur;
unsigned char *end;
struct st_tlv_t tlv; cur = buffer;
end = buffer + length; while( cur < end )
{
if( !parseTlv( cur, end-cur, &tlv ) )
return ; printTlv( &tlv ); // 如果是复合型的TAG,则进入复合TAG内部继续分析
if( tlv.isCustructed && reverse )
{
cur = tlv.pVal;
}
else // 如果是简单型的TAG,则分析下一个TAG
{
cur = tlv.pVal + tlv.valLen;
}
} if( cur > end )
return ; return ;
} int main( void )
{
int ret; unsigned char tlv_buf0[] = {
0x70,0x28,0x61,0x26,0x4f,0x07,0xa0,0x00,
0x00,0x03,0x33,0x01,0x01,0x50,0x0b,0x50,
0x42,0x4f,0x43,0x20,0x43,0x72,0x65,0x64,
0x69,0x74,0x87,0x01,0x01,0x9f,0x12,0x0a,
0x50,0x42,0x4f,0x43,0x20,0x44,0x45,0x42,
0x49,0x54,0x90,0x00
};
unsigned char tlv_buf1[] = {
0x00,0x00,0x00,
0x70,0x81,0x83,0x90,0x81,0x80,0x25,0x3c,
0x3c,0x1f,0xd9,0x92,0x8d,0x88,0x21,0x11,
0xa6,0xac,0x4c,0xa2,0x07,0xdf,0x93,0x10,
0x64,0x23,0x95,0xea,0x09,0x7b,0x3c,0xb1,
0x6d,0x51,0x76,0x53,0x35,0x38,0x03,0xc2,
0xc1,0x03,0x3e,0x4a,0xac,0xb9,0x73,0x5d,
0x2e,0x69,0xca,0x49,0x8f,0xeb,0x4c,0xc0,
0xae,0xe1,0xff,0xc7,0xf5,0x44,0x83,0x09,
0x3a,0x30,0xcc,0xbf,0x6b,0x20,0x11,0xd6,
0x09,0xe5,0x2f,0xd7,0x87,0x76,0xb6,0x6b,
0x6d,0x86,0x95,0xcb,0xc0,0x46,0x21,0x6b,
0xf8,0x1c,0x52,0xd5,0xc2,0xf9,0x47,0xde,
0xe3,0xad,0xd7,0x20,0x9a,0xb3,0x27,0xf2,
0x9c,0x10,0x6b,0xfa,0x0e,0x29,0x1d,0x9d,
0xab,0x00,0x91,0x06,0xf4,0x89,0xba,0x59,
0x43,0x6d,0xa9,0x46,0x75,0xdf,0x9d,0x31,
0xdc,0xaf,0xbd,0x6a,0xbe,0x20,
};
unsigned char tlv_buf2[] = {
0x6f,0x24,0x84,0x0e,0x31,0x50,0x41,0x59,
0x2e,0x53,0x59,0x53,0x2e,0x44,0x44,0x46,
0x30,0x31,0xa5,0x12,0x88,0x01,0x01,0x5f,
0x2d,0x08,0x7a,0x68,0x65,0x6e,0x66,0x72,
0x64,0x65,0x9f,0x11,0x01,0x01
}; ret = parseTlvXXX( tlv_buf0, sizeof(tlv_buf0), );
printf("0-parseTlvXX: %d\r\n", ret); ret = parseTlvXXX( tlv_buf1, sizeof(tlv_buf1), );
printf("1-parseTlvXX: %d\r\n", ret); ret = parseTlvXXX( tlv_buf2, sizeof(tlv_buf2), );
printf("2-parseTlvXX: %d\r\n", ret); return ;
}