# 中移云YAT对接协议
杭研平台识别码为:0x0A
#产品配置格式
模块连接杭研平台时,需要烧录平台配置参数,采用一型一密的方式,平台产生可以由庆科烧录也可以由客户自己烧录,同时模组需要烧录的andlink_cmei码暂定由庆科烧录。sn为可选项,当没有烧录sn时,默认sn为cmei码。sn的烧录方法:1.可以通过交互串口烧录(方法同其他平台参数设置),2.可以通过lota的方式烧录。
平台产品参数可以不通过指令设置,可以是WiFi模组固件的出厂时默认配置,如果默认请联系mxchip。
MCU->WiFi:
TYPE | PAYLOAD | ||
Cloud code | CONFIG | 说明 | |
0x04 | 1 Byte | n Byte | Cloud code:云平台识别码 CONFIG:云平台配置,格式见附件 |
pid: andlink product id 产品ID
ptoken: andlink product token 产品验证码
token: andlink token 平台验证码
cmei: andlink cmei 平台入库唯一标识,由庆科烧录时可以不加此行。
sn: andlnk sn 设备唯一识别码(可选项)
qlink:无感配网使能的配置项,默认关闭。1:为打开无感配网功能,0:为关闭无感配网功能(可选项)
ahs: 即AHSversion,是杭研DM上报需要的参数,格式为:庆科模组型号(MX)-厂家产品型号(DM);
psmode: powerSupplyMode,供电方式,如 USB、220V
dvendor: device vendor 设备制造商
dbrand: device brand 设备品牌
dmodel: device model 设备型号
dmanudate: device manudate 设备生产日期 (可选项)
注:AHSVersion提测前必须上报(后台可见完整字串,拷贝作为邮件标题【AHSVersion:"AOS-IOT-RTOS-模组型号-产品型号-版本号"】发到邮箱 chenqingqing@cmhi.chinamobile.com,加快杭研入库提测。接受加速提测的庆科模组型号请写成:EMW3080V2/EMW3090V2/EMC3080/EMC3090/EMC3020
Payload格式如下:
{
"pid": "123", //平台获取
"ptoken": "456", //平台获取
"token": "asd", //平台获取
"qlink":"0", // (可选项)
"ahs":"EMW3080V2-abc", //杭研DM要求参数,
"psmode":"USB", //供电方式
"dvendor":"MXCHIP", //设备制造商
"dbrand":"EMW", //设备品牌
"dmodel":"abc", //设备型号
"dmanudate":"yyyy-mm" //设备生产日期,格式:年-月
"cmei": "zxc", //平台获取,一机一密
"sn":"789" , //平台获取,一机一密
}
WiFi->MCU:
TYPE | PAYLOAD | 说明 |
0x04 | 0x00 | 设置成功 |
0x01 | 设置错误 |
【注意】模块生产阶段使用BAT批量生产时,可通过配置文件的方式烧录。如只烧录cmei则id类型选择cmei-kv,如其他阐述也需要烧录则需要新增id类型,id类型选择 UCPP(一型一密)
(其中平台参数设置中andlink_sn和andlink_qlink_enable为可选项)。
json文件:📎平台参数配置.json
{
"andlink_product_id":"xx",
"andlink_product_token":"xx",
"andlink_token":"xx",
"andlink_sn":"xx",
"andlink_qlink_enable":"0",
"andlink_device_vendor":"xx",
"andlink_device_brand":"xx",
"andlink_device_model":"DM",
"andlink_ahs_version":"MX-DM"
}
#配网方式
杭研的配网方式为:设备热点配网和蓝牙配网。
格式如下:
MCU->WiFi
CMD | PAYLOAD | |||
Cloud Code | Type | TimeOut | 说明 | |
0x13 | 0A | 0x02 | 2 Byte | 设备热点配网 |
0x03 | 2 Byte | 蓝牙配网 |
WiFi->MCU
TYPE | PAYLOAD | 说明 |
0x13 | 0x00 | 设置成功 |
0x01 | 设置错误 |
#数据通信
MCU与WiFi模组的属性通信为JSON格式。
#属性上报
MCU->WiFi
CMD | PAYLOAD | 说明 |
0x27 | n Byte | 上报JSON格式数据 n取值范围 1~1024 |
WiFi->MCU
无
上报Payload格式如下:
{"params":[{"paramCode":"xxx","paramValue":1},{"paramCode":"xx","paramValue":2}]}
{"params":[{"paramCode":"xxx","paramValue":1},{"paramCode":"xx","paramValue":2}]},"timestamp":1000
#属性下发
WiFi->MCU
CMD | PAYLOAD | 说明 |
0x27 | n Byte | 下发JSON格式数据 n取值范围 1~1024 |
Payload格式如下:
# function = "Control",表示app下发控制指令
{"data":{"params":[{"paramCode":"xx","paramValue":"x"}]},"function":"Control","deviceId":"xx","seqId":"xx"}
# function = "Query",表示app下发查询指令
{"data":{"paramCodes":[{"paramCode":"xx"},{"paramCode":"xx"}]},"function":"Query","deviceId":"xx","seqId":"xx"}
#智能锁临时密码
该命令仅用于具有临时密码功能的智能锁产品。
资料来源于杭研:
#申请临时密码
MCU->WiFi
CMD | PAYLOAD | |
0x28 | 0x00 | 申请获取云端临时密码 |
WiFi->MCU
CMD | PAYLOAD | 说明 | |
0x28 | 0x00 | n Byte | 临时密码请求成功,JSON格式数据 |
0x01 | 没有临时密码 | ||
0x02 | 设备没有连上服务器 | ||
0x03 | 正在请求临时密码,请求超时时间5s | ||
0x04 | 请求临时密码的过程中出现未知错误 |
[{
"tmpPwdEndTime": "2022-03-06 22:49:21",
"tmpPwdId": 3245,
"tmpPwdKey": "500704",
"tmpPwdNum": "1",
"tmpPwdNumAvailable": 1,
"tmpPwdStartTime": "2022-03-06 21:49:19",
"tmpPwdUserId": "146763",
"tmpPwdUserName": "d:1880XXXXXXX"
}]
#剩余次数上报
MCU->WiFi
CMD | PAYLOAD | 说明 |
0x27 | n Byte | 上报临时密码剩余次数,JSON格式数据, n取值范围 1~1024 |
Payload组包格式同属性上报,剩余次数字段需与平台下发相同,即 "tmpPwdNumAvailable":次数。
{"params":{"paramCode":"tmpPwdInfo","paramValue":[
{"tmpPwdId":3250,"tmpPwdNumAvailable":5},
{"tmpPwdId":3252,"tmpPwdNumAvailable":13}]}} //其中3250/3252需对应获取时的返回
#测试蓝牙配网的APP
#MCU OTA 指令集
#特别说明
注意:杭研平台下发的ota升级消息中没有 版本号 和 校验,需要MCU自己保证固件的完整性。
{
"data": {
"downMode": 1,
"fileMode": "DOWN",
"fileUrl": "http://oss.komect.com/ota-prod/64877b42d1f1e30352b78d19eb26f2e2/a105.bin",
"fileType": "APP"
},
"function": "File",
"deviceId": "CMCC-590248-80A036D7417B",
"seqId": "3fa05dc1"
}
Wi-Fi模组根据 fileType 字段识别是Wi-Fi固件更新还是MCU固件更新。
- fileType = FIRM ,表示 Wi-Fi 固件更新
- fileType = APP ,表示 MCU 固件更新
#获取MCU固件版本号
WiFi->MCU
CMD | PAYLOAD | 说明 |
0x31 | 0x00 | 预留 |
MCU->WiFi
无
#上报MCU固件版本号
MCU->WiFi
CMD | PAYLOAD | 说明 |
0x32 | n bytes (string) | MCU固件版本号; 最大值32 |
WiFi->MCU
CMD | PAYLOAD | 说明 |
0x32 | 0x00 | MCU固件版本号设置成功 |
0x01 | MCU固件版本号设置失败 |
mcu 版本号,必须是 a.b.c****
- abc 必须是数字 0~9
- 例如:1.0.0
#MCU请求开始固件升级
MCU->WiFi
CMD | PAYLOAD | 说明 |
0x34 | 0x00 | 进入MCU OTA模式,128字节 |
0x01 | 进入MCU OTA模式,1024字节 |
WiFi->MCU
CMD | PAYLOAD | 说明 |
0x34 | 0x00 | WiFi模组进入Ymodem模式成功 |
0x01 | WiFi模组进入Ymodem模式失败 |
#MCU查询MCU OTA固件版本
MCU->WiFi
CMD | PAYLOAD | 说明 |
0x35 | 0x00 | 查询MCU OTA固件版本信息 |
WiFi->MCU
CMD | PAYLOAD | 说明 |
0x35 | 0x00 | 没有MCU OTA固件 |
n bytes | json 字符串格式,后续会扩展 |
该指令可以在指令模式下任意时间发送。由于杭研平台在ota消息中没有提供版本号,故用 “APP” 替代为版本号。
{
"fw_ver": "APP",
"fw_len": 886864
}
#通知MCU开始WiFi模组自身固件升级
WiFi->MCU
CMD | PAYLOAD | 说明 |
0x36 | n bytes(string) | 设备当前WiFi固件版本号(OTA之前的版本) |
MCU->WiFi
无
该指令说明,固件已经下载完成,并且校验正确,模组将重启启动,开始模组自身的更新,持续时间20s~30s不等。
#通知MCU OTA的版本、长度
WiFi->MCU
CMD | PAYLOAD | 说明 |
0x37 | n bytes | json 字符串格式,后续会扩展 |
MCU->WiFi
无
该指令的数据格式与0x35指令的数据格式一致
#升级流程
#流程说明
- WiFi模组接收到云端下发的 MCU OTA 升级指令
- WiFi模组下载固件并校验固件完整性
- WiFi模组发送通知MCU开启固件升级的指令
- MCU请求WiFi模组进入Ymode模式,
- WIFI响应请求应答,如果检查到WiFi模组中存在MCU固件,WiFi模组进入 Ymodem 模式, WiFi模组关闭所有串口指令,MCU端延时 200ms 后,再进入Ymodem模式
- MCU与WiFi模组通过 Ymodem 协议,传输 mcu 的ota 固件,固件传输完成后,WiFi模组打开所有串口指令
- MCU OTA成功后,发送 重启指令
- WiFi模组应答指令
- 重启模组
- 模组通过获取MCU固件版本号指令,请求MCU固件版本号
- MCU通知上报MCU固件版本号指令,上报MCU固件版本号
- WiFi模组应答指令
- WiFi模组向云端上报MCU固件版本号
#升级要求
- MCU应用程序必须要有bootloader模式
- bootloader必须支持Ymodem协议
- OTA固件必须包含完整性校验
- MCU应用程序应该在适当的时候上报版本号,一是在WiFi请求mcu版本时;二是在mcu升级成功后
- MCU可以在模组启动初期上报版本号
- 如果模组在发送请求固件版本号之前收到了MCU上报的固件版本,模组将不再发送请求MCU固件版本号指令
#Ymodem 协议
Ymodem协议是由XModem协议演变而来的,每包数据可以达到1024字节,是一个非常高效的文件传输协议。
YModem-1K用1024字节信息块传输取代标准的128字节传输,数据的发送会使用CRC校验,保证数据传输的正确性。它每传输一个信息块数据时,就会等待接收端回应ACK信号,接收到回应后,才会继续传输下一个信息块,保证数据已经全部接收。
Ymodem支持128字节和1024字节一个数据包。128字节以(SOH)开始,1024字节以(STX)开始。
1.起始帧的数据格式
YModem的起始帧并不直接传输文件的数据,而是将文件名与文件的大小放在数据帧中传输,它的帧长=3字节数据首部+128字节数据+2字节CRC16校验码=133字节。它的数据结构如下:
SOH 00 FF filename filezise NUL CRCH CRCL
其中SOH=0x01,表示这个数据帧中包含着128个字节的数据(STX表示1024字节,初始帧只有128个),00表示数据帧序号,初始是0,依次向下排,FF是帧序号的取反,filename是要传输的文件名,如USTB_V3_1.0.1.26_NMEA.Bin,它在数据帧中的格式为:55 53 54 42 5F 56 33 5F 31 2E 30 2E 31 2E 32 36 5F 4E 4D 45 41 2E 42 69 6E 00,也就是把ASCII码转成十六进制,但是最后一定要在文件名后加上00,表示文件名的结束;filesize表示文件的大小,如上面的USTB_V3_1.0.1.26_NMEA.Bin大小是132KB,也就是135168Byte,它在数据帧中的格式就是31 33 35 31 36 38 ,也就是ASCII的“135168”,同样最后要加上00表示结束,NUL就是数据部分的128字节中除去文件名和文件大小占据的剩下的字节都用00填充,CRCH和CRCL分别表示16位CRC校验码的高8位与低8位。
2.数据帧的数据格式
YModem的数据帧中会预留1024字节空间用来传输文件数据,它跟起始帧接收差不多,如下:
STX 01 FEdata[1024] CRCH CRCL
其中STX=0x02,表示这帧数据帧后面包含着1024字节的数据部分;01是表示帧序号,FE是它的取反,再下一帧数据就是02 FD,以此类推;data[1024]表示存放着1024字节的文件数据;CRCH与CRCL是CRC16检验码的高8位与低8位。
如果文件数据的最后剩余的数据在128~1024之间,则是使用SOH的128字节传输,
有一种特殊的情况:如果数据不满128字节,剩余的数据用0x1A填充这是数据帧的结构就变成了:
文件大小小于128字节
SOH 01 FE data[ ] 1A ...1A CRCH CRCL
文件最后剩余数据小于128字节
SOH 01 FE data[ ] 1A...1A CRCH CRCL
3.结束帧数据结构
YModem的结束帧数据也采用SOH的128字节数据帧,它的结构如下:
SOH 00 FF NUL[128] CRCH CRCL
结束帧同样以SOH开头,表示后面跟着128字节大小的数据;结束帧的帧序也认为是00 FF;结束帧的128字节的数据部分不存放任何信息,即全部用00填充。
#示例
以 128字节为一个数据包的Ymodem例。数据交互以MCU为视角,OTA数据包大小为 656 bytes。
Phase Data Description
----- -------------------------------------------------------------- ------------
OUT c0 34 00 00 d0 MCU 请求开启 MCU OTA
IN c0 34 00 00 d0 WiFi 响应 MCU 成功
OUT 43 C
IN 01 00 ff 6d 63 75 2d 31 30 31 00 36 35 36 00 00 ... CRC16 文件名:mcu-101 ;长度:656
OUT 06 ACK
OUT 43 C
IN 01 01 fe 31 32 33 34 35 36 37 38 39 30 31 32 33 ... CRC16 128 Data
OUT 06 ACK
IN 01 02 fd 37 38 39 30 31 32 33 34 35 36 37 38 39 ... CRC16 128 Data
OUT 06 ACK
IN 01 03 fc 31 32 33 34 35 36 37 38 39 30 31 32 33 ... CRC16 128 Data
OUT 06 ACK
IN 01 04 fb 37 38 39 30 31 32 33 34 35 36 37 38 39 ... CRC16 128 Data
OUT 06 ACK
IN 01 05 fa 31 32 33 34 35 36 37 38 39 30 31 32 33 ... CRC16 128 Data
OUT 06 ACK
IN 01 06 f9 37 38 39 30 31 32 33 34 35 36 37 38 39 ... CRC16 128 Data
OUT 06 ACK
IN 04 EOT
OUT 15 NAK
IN 04 EOT
OUT 06 ACK
OUT 43 C
IN 01 00 ff 00 00 00 00 00 00 00 00 00 00 00 00 00 ... CRC16 结束包
OUT 06 ACK
通过 Bus Hound 抓包,完整的交互流程如下图。