设备可以采用TCP或者UDP方式主动上报,上报均采用Client方式,其中TCP采用长连接上传16进制数据形式,设备具有KeepAlive机制, 会主动保持和服务区的连接并且进行无限次的断线重连。
协议的基本组成如下:
帧头(2)+版本 (1)+设备ID(6)+传输Session(4)+命令字节(1)+传输秘钥(8)+长度(2)+内容(n)+校验和(2)
其中帧头2字节,固定为0xfe 0xdc。 设备版本号1字节,在本协议中为0x02。 设备ID为6字节,每一个设备均有一个唯一的设备ID,设备号错误不保存上传数据。 传输Session为4字节,由设备指定,每次发送自增1,用来标识设备的传输顺序。 命令字节,长度1字节,内容见下文。 传输秘钥为平台发放,对接时索取。 校验和为2字节,本协议中校验采用crc16位校验,算法见下文。
主动上报的命令字节,长度,内容如下文所示:
命令字节 长度 内容 0xC3 0x08(08) 见下文数据上报内容
数据上报内容: 数据1内容(4字节) 数据2内容(4字节) ...... 数据12内容(4字节
如下文是一个设备主动上传的数据:
FE DC 02 16 35 61 84 52 32 00 00 00 05 C3 33 72 51 01 00 09 C0 01 00 08 00 00 02 92 00 00 FF 9B 35 C0其中fe dc为固定帧头,02为版本号,设备唯一id为163561845232 ,本条指令的session为00000005,C3是命令字节,337251010009C001 是秘钥, 本条数据长度为0008也就是8个字节。 上传的第一个数为湿度 00000292代表65.8%RH。第二个数据位温度0000ff9b代表-10.1℃(使用补码的形式标示负数), 最后两位35C0为校验和。
CRC 校验(Cyclic Redundancy Check)是一种数据传输错误检查方法。本标准采用 ANSI CRC16,简称 CRC16。
CRC16 码由传输设备计算后加入到数据包中。接收设备重新计算接收数据包的 CRC16 码,并与接收到的 CRC16 码比较,如果两值不同,则有误。
CRC16 校验字节的生成步骤如下:
1) CRC16 校验寄存器赋值为 0xFFFF;
2) 取被校验串的第一个字节赋值给临时寄存器;
3) 临时寄存器与 CRC16 校验寄存器的高位字节进行“异或”运算,赋值给 CRC16 校验寄存器;
4) 取 CRC16 校验寄存器最后一位赋值给检测寄存器;
5) 把 CRC16 校验寄存器右移一位;
6) 若检测寄存器值为 1,CRC16 校验寄存器与多项式 0xA001 进行“异或”运算,赋值给 CRC16校验寄存器;
7) 重复步骤 4~6,直至移出 8 位;
8) 取被校验串的下一个字节赋值给临时寄存器;
9) 重复步骤 3~8,直至被校验串的所有字节均被校验;
10) 返回 CRC16 校验寄存器的值。
示例:
FEDC 02 163561845232 00000005 C3 337251010009C001 0008 00000292 0000FF9B 35C0
其中 35C0 为 CRC16 校验码,是对数据段
FEDC 02 163561845232 00000005 C3 337251010009C001 0008 00000292 0000FF9B
进 行CRC16 校验所得的校验码。
CRC校验算法示例:
/****************************************************************************************
函 数:CRC16_Checkout
描 述:CRC16 循环冗余校验算法
参 数 一:*puchMsg:需要校验的字符串指针
参 数 二:usDataLen:要校验的字符串长度
返 回 值:返回 CRC16 校验码
****************************************************************************************/
unsigned int CRC16_Checkout(unsigned char * puchMsg, unsigned int usDataLen) { unsigned int i, j,crc_reg,check; crc_reg = 0xFFFF; for (i = 0; i < usDataLen; i++) { crc_reg = (crc_reg >> 8) ^ puchMsg[i]; for (j = 0; j < 8; j++) { check = crc_reg & 0x0001; crc_reg >>= 1; if (check == 0x0001) { crc_reg ^= 0xA001; } } } return crc_reg; }
校验测试