蓝牙设备通常需要空中升级(OTA)的能力进行固件更新,本规范定义了空中升级(OTA)的基本流程和指令集。本规范基于《天猫精灵智能家居蓝牙设备GATT规范》实现。
为了保证OTA的的安全性,在进行设备OTA之前,必须完成安全认证流程。若认证失败则不允许进行OTA。安全认证详情参考《天猫精灵智能家居蓝牙设备GATT规范》。
空中升级(OTA)是可选功能,如果蓝牙设备实现了此功能,需要在广播规范的FMSK字段中标示。
传输过程使用基础规范已定义的Service和Characteristics,采用指令类型区分。手机App发送固件时,采用WriteWithNoRsp Characteristics(0xFED7),用于加快传输速度。同时蓝牙设备收到数据包后,对App应答。接收固件过程中,发现数据序号错误的时候,蓝牙设备上报最后一次正确的序号。
数据传输完全使用基础规范定义的数据格式和规则。
固件类型为一个1字节数字,用来区分同一个设备不同类型固件。版本格式为一个4字节数字,如:0x00010302,表示固件版本号为:“1.3.2”,版本号只允许递增,最大版本号为:“99.99.99”。版本格式规则如下:
字节序 |
说明 |
取值范围 |
示例 |
0 | 修订号 |
0x00~0x63 |
“1.3.2”,修订号为0x02 |
1 |
次版本号 |
0x00~0x63 |
“1.3.2”,次版本号为0x03 |
2 | 主版本号 |
0x00~0x63 |
“1.3.2”,主版本号为0x01 |
3 |
保留 |
无 |
无 |
1、升级用固件推送到服务端,并填写固件版本信息和升级原因。
2、当服务端确认推送的固件版本比设备端上报的固件版本新时,服务端推送升级通知到手机App。
3、手机App转发升级请求及固件版本信息(仅包含应用版本信息)和固件大小,CRC。
4、蓝牙设备检查固件的应用版本信息,当App下发的应用版本信息比设备运行的固件的应用版本新时,蓝牙设备进入升级模式,否则退出升级模式。
5、协议设计支持固件断点续传能力,参考“交互流程”第12步,蓝牙设备可以回复上次传输固件的中断的位置,手机App会从指定位置续传。断点续传非强制要求能力,可根据情况实现。
6、协议设计支持快速传输模式,即手机App会连续传输TotalFrame(0<TotalFrame<=16)个数据包而不需要对每个数据包等待蓝牙设备的回复,TotalFrame个数据包发送完成后,蓝牙设备才给予回复,然后手机App进行下一轮数据的传输。
7、除了0x2F指令(下发固件分包)不需要加密外,其余指令通过鉴权流程后均需要加密。
1、0x20:手机查询设备固件版本
Header(1Byte) |
CmdType(1 Byte) |
FrameDesc(2 Byte) |
PayLoad(1 Byte) |
0x00 |
0x20 |
0x00 0x01 |
0x00 |
固件类型为1字节,默认填0x00。设备端根据固件类型从 0x21 返回对应类型固件的版本号信息。
2、0x21:设备上报设备固件版本,版本为0x00000002
Header(1Byte) |
CmdType(1 Byte) |
FrameDesc(2 Byte) |
PayLoad(5 Byte) |
0x00 |
0x21 |
0x00 0x05 |
0x00 0x00000002 |
固件类型为1字节,默认填0x00。遇到不支持的固件类型,固件类型上报 0xFF。固件版本号为4字节。
3、0x22:手机下发升级请求,升级请求包含五个字段,分别为:固件类型、固件版本号、固件大小、CRC16、升级标示符。
Header(1Byte) |
CmdType(1 Byte) |
FrameDesc(2 Byte) |
PayLoad(12 Byte) |
0x00 |
0x22 |
0x00 0x0C |
0x00 0x00000001 0x00123456 0x7890 0x00 |
固件类型、固件版本号、固件大小、CRC16、升级标示符按照顺序拼接下发。固件类型为1个字节,固件版本号为4个字节,固件大小为4个字节,CRC16为2个字节,升级标示符为1个字节。CRC16算法采用CRC16_CCITT(参考资料 1)。升级标示符含义,0:全量升级 1:增量升级,默认设为0。
4、0x23:设备应答升级请求,1:允许升级 0:不可以升级。
Header(1Byte) |
CmdType(1 Byte) |
FrameDesc(2 Byte) |
PayLoad(5 Byte) |
0x00 |
0x23 |
0x00 0x06 |
0x01 0x00000000 0x0F |
是否允许升级(1字节)+ 上次传输字节数(4字节)+ 允许一次循环可传输的包个数(1字节,0x00~0x0f,表示1~16包)
5、0x24:设备上报当前已接收的帧序号和接收的数据长度
Header(1Byte) |
CmdType(1 Byte) |
FrameDesc(2 Byte) |
PayLoad(5 Byte) |
0x00 |
0x24 |
0x00 0x05 |
0x20 0x00000200 |
注:PayLoad 由接收的帧数和接收数据长度组成,帧数1字节(totalFrame 4bit + frameSeq 4bit),数据长度4字节。当设备发现有丢帧时,设备端上报最后一次收到正确的帧序和数据长度。手机端重新从丢失的帧开始发送,并且发送完本次循环的剩余帧。
6、0x25:手机通知设备固件下发结束,可以做固件检查
Header(1Byte) |
CmdType(1 Byte) |
FrameDesc(2 Byte) |
PayLoad(1 Byte) |
0x00 |
0x25 |
0x00 0x01 |
0x01 |
7、0x26:设备收完包后,上报固件检查结果; 1:固件检查成功;0:固件检查失败
Header(1Byte) |
CmdType(1 Byte) |
FrameDesc(2 Byte) |
PayLoad(1 Byte) |
0x00 |
0x26 |
0x00 0x00 |
0x01 |
9、0x2F:手机下发固件的分包数据
Header(1Byte) |
CmdType(1Byte) |
FrameDesc(2 Byte) |
FwData(N Byte) |
0x00 |
0x2F |
0xF0 0x10 |
0x1234… |
注:固件按规范的数据长度分包,发送16包作为一次循环,Header中帧序号按照0~15循环。