浅谈自定义通讯协议——TLV(封装)_tlv协议,2024年最新【2024物联网嵌入式开发最新学习路线】

114 阅读3分钟

TLV的封包代码示例

下面是我用c代码实现的TLV报文格式的发送信息:

#include <stdio.h>
#include <string.h>
#include "header.h"
#include "tlv.crc-itu-t.h"


#define HEAD 0xFD //定义一个报文头
#define BUF\_SIZE 128 //定义一个buffer的大小
#define TLV\_FIXED\_SIZE 5 //固定TLV字节流大小,不包含value的值
#define TLV\_MINI\_SIZE (TLV\_FIXED\_SIZE+1) //TLV字节流的最小值,value的最小值为1个字节
 
enum   //使用枚举 Tag的值会自加
{
	TAG_ACK = 1,
	TAG_SN,    //树莓派上的id
  	TAG_TEMP,   //温度
	TAG_TIME,   //时间

 };

int pack_ack (char \*buf , int size);  //声明ack封装函数
int pack_sn  (char \*buf , int size);//声明id封装函数
int pack_temp (char \*buf , int size);//声明温度封装函数
int pack_time  (char \*buf , int size);//声明时间温度封装函数

int  main (int argc, char \*\*argv)
{
	char buf[BUF_SIZE];
	int   bytes;  //一个封装函数的字节流的个数

	bytes =  pack_ack (buf , sizeof(buf));
	dump\_buf("ack", buf, bytes);//设置dump\_buf函数,把所有的字节流都放到dump\_buf里面
	
	bytes =  pack\_sn(buf , sizeof(buf));
	dump\_buf("sn", buf, bytes);

	bytes =  pack\_temp(buf , sizeof(buf));
	dump\_buf("temp", buf, bytes);

	bytes =  pack_time (buf , sizeof(buf));
	dump\_buf("time", buf, bytes);
	
	return 0;
}

/\*树莓派的编号ID=RPI0001报文
 \* H T L Value CRC1 CRC2
 \* 0xFD 0x01 0x01 0x07 0x12 0x34
 \* \*/

int pack\_sn(char \*buf, int size)//声明id封装函数
{
    unsigned short crc16 = 0;
    char           \*id = "RPI0001";
    int     ofset = 0;
    int         pack_len = 0;
    int     data_len = 0;

    if(!buf || size < TLV_MINI_SIZE)
    {
        printf("Invalid input argument \n");
        return 0;
    }

    buf[ofset]=HEAD;
    ofset+=1;

    buf[ofset]=TAG_SN;
    ofset +=1;

    data_len=strlen(id);
    pack_len = data_len + TLV_FIXED_SIZE;
    buf[ofset]=pack_len;
    ofset +=1;

    memcpy(&buf[ofset], id, data_len);
    ofset += data_len;

    crc16=crc\_itu\_t(MAGIC_CRC, buf, ofset);
    ushort\_to\_bytes(&buf[ofset], crc16);
    ofset +=2;

    return ofset; //返回索引值
}

/\* 树莓派上获取温度30.5C报文
 \* H T L Value CRC1 CRC2
 \* 0xFD 0x03 0x00 0x14 0x3A 0x12 0x34
\*/

int  pack\_temp(char \*buf, int size)
{
    unsigned short crc16=0;
    int     pack_len = 0;
    int     data_len = 0;
    int     ofset = 0;
    float   temp;
    char    datatime[32];
    int     i,j;

    if(!buf || size < TLV_MINI_SIZE)
     {

        printf("Invalid input adgument\n");
        return 0;

    }
    buf[ofset]=HEAD;
    ofset +=1;

    buf[ofset]=TAG_TEMP;
    ofset +=1;

    ds18b20\_get\_temperature(&temp);
    i=(int)temp; //整数部分
    j=(int) ((temp-i) \*100);//小数部分

    data_len = sizeof(temp);
    pack_len= data_len + TLV_FIXED_SIZE;
    buf[ofset]=pack_len;
    ofset +=1;

    buf[ofset]=i;
    ofset+=1;
    buf[ofset]=j;
    ofset+=1;

    crc\_itu\_t(MAGIC_CRC, buf, ofset);
    ushort\_to\_bytes(&buf[ofset], crc16);
 ushort\_to\_bytes(&buf[ofset], crc16);
    ofset +=2;
    return ofset;//返回索引值
}
/\* 获取系统时间的报文 2020-4-12 23:22:00
 \* H T L Value 
CRC1 CRC2
 \* 0xFD 0x04 0x06 0x14 0x04 0x0c 0x17 0x16 0x00 0x12 0x34
 \* \*/

int pack_time (char \*buf, int size)
{
    unsigned short crc16=0;
    int  ofset = 0;
    int  pack_len = 0;
    int  data_len = 0;
    char  datatime[32];
    char \*datime;
    if( !buf || size < TLV_MINI_SIZE)
    {
        printf("Invald input argument\n");
        return 0;
    }

    buf[ofset]=HEAD;
    ofset+=1;

    buf[ofset]=TAG_TIME;
    ofset +=1;
    memset(datatime, 0, sizeof(datatime));
    int time=get\_sys\_time(datatime);
    data_len = time;
    pack_len =data_len + TLV_MINI_SIZE;
    buf[ofset]=pack_len;
    ofset+=1;

    for(int i=0; i< data_len; i++, ofset++)
        buf[data_len]=datatime[i];

    crc16=crc\_itu\_t(MAGIC_CRC,buf, ofset);
    ushort\_to\_bytes(&buf[ofset], crc16);
    ofset +=2;
    return ofset;//返回索引值

}

void dump\_buf(char \*type, char \*data, int len)//data指针,指向buf的首地址,len是buf的长度
{
    if(type)
    {
        printf("%s:\n", type);
    }

    int i;
    for(i=0; i<len; i++)
    {
        printf("0x%02x\n",data[i]);
             printf("0x%02x\n",data[i]);
    }
    printf("\n");

}


后续我将会更新TLV的解包过程!代码可能存在bug,如果有什么问题,还请大家指出!

img img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取