TCP上报

1.1主动上报方式

设备可以采用TCP或者UDP方式主动上报,上报均采用Client方式,其中TCP采用长连接上传16进制数据形式,设备具有KeepAlive机制, 会主动保持和服务区的连接并且进行无限次的断线重连。

1.2协议基本组成

协议的基本组成如下:

帧头(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位校验,算法见下文。

1.3主动上报协议

主动上报的命令字节,长度,内容如下文所示:

命令字节 长度 内容
0xC3 0x08(08) 见下文数据上报内容

数据上报内容:
数据1内容(4字节) 数据2内容(4字节) ...... 数据12内容(4字节
1.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为00000005C3是命令字节,337251010009C001 是秘钥, 本条数据长度为0008也就是8个字节。 上传的第一个数为湿度 00000292代表65.8%RH。第二个数据位温度0000ff9b代表-10.1℃(使用补码的形式标示负数), 最后两位35C0为校验和。

1.5循环冗余校验(crc)算法

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 校验所得的校验码。

1.6 CRC校验示例

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;
}
1.7 CRC校验测试

校验测试