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,如果有什么问题,还请大家指出!
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新