2. 开发说明
2.1 认证库使用
Warning
每次蓝牙连接只可以与设备进行一次认证,重复认证会导致认证失败。若设备端打开认证,小程序端未认证就与设备进行RCSP命令通讯(包含OTA),设备不会回应命令。若设备端不打开认证,则不需要进行认证流程。
//初始化认证
let auth = new Auth()
//设备回复数据callback
let bleDataCallback: BleDataCallback = {
onReceiveData(res: WechatMiniprogram.OnBLECharacteristicValueChangeCallbackResult) {
//数据传输给认证库
auth.handlerAuth(res.deviceId, res.value)
}
}
//认证结果监听
let authListener: AuthListener = {
//发送认证数据回调
onSendData: (deviceId: string, data: ArrayBuffer) => {
//调用发数接口
this._SendData(deviceId, new Uint8Array(data))
},
//认证成功回调
onAuthSuccess: () => {
//移除设备回复数据callback
BleDataHandler.removeCallbacks(bleDataCallback)
//通知RCSP_SDK连接成功
this.rcspOp.transmitDeviceStatus(new Device(device.deviceId), Connection.CONNECTION_CONNECTED)
},
//认证失败回调
onAuthFailed: () => {
//移除设备回复数据callback
BleDataHandler.removeCallbacks(bleDataCallback)
this.bleConnect.disconnect()
},
}
//添加设备回复数据callback
BleDataHandler.addCallbacks(bleDataCallback)
//开始认证
auth.startAuth(device.deviceId, authListener)
2.2 RCSP库使用
RCSP命令架构图:
Note
目前这个渠道的RCSP库只支持OTA命令
SDK初始化:
//初始化
let rcspOp = new RcspOpImpl();
//设置RCSP发送数据回调
rcspOp.setOnSendDataCallback({
sendDataToDevice: (device: Device, data: Uint8Array): boolean => {
//调用发数接口
return this._SendData(device.mac, data)
}
})
//设备回复数据callback
const bleDataCallback = {
onReceiveData(res: WechatMiniprogram.OnBLECharacteristicValueChangeCallbackResult) {
//数据传输给RCSP库
rcspOp.transmitDeviceData(new Device(res.deviceId), new Uint8Array(res.value))
}
}
//添加设备回复数据callback
BleDataHandler.addCallbacks(bleDataCallback)
//RCSP事件回调
const onRcspCallback: OnRcspCallback = {
/**
* Rcsp协议初始化回调
*
* @param device 已连接设备
* @param isInit 初始化结果
*/
onRcspInit(device?: Device | null, isInit?: boolean){},
/**
* 设备主动发送的rcsp命令回调
*
* @param device 已连接设备
* @param command RCSP命令
*/
onRcspCommand(device: Device | null, command: CommandBase){},
/**
* 设备主动发送的数据命令回调
*
* @param device 已连接设备
* @param dataCmd 数据命令
*/
onRcspDataCmd(device: Device | null, dataCmd: CommandBase){},
/**
* RCSP错误事件回调
*
* @param device 设备对象
* @param error 错误码 (参考{@link com.jieli.rcsp.data.constant.ErrorCode})
* @param message 错误描述
*/
onRcspError(device: Device | null, error: number, message: string){},
/**
* 需要强制升级回调
*
* @param device 需要强制升级的设备
*/
onMandatoryUpgrade(device: Device | null){},
/**
* 设备连接状态
*
* @param device 蓝牙设备
* @param status 连接状态
*/
onConnectStateChange(device: Device | null, status: Connection){}
}
//添加RCSP事件回调
rcspOp.addOnRcspCallback(onRcspCallback)
如何传输设备的连接状态:
Important
当传输设备状态之后,SDK就会开始与设备进行RCSP协议初始化(获取设备相关信息等)。初始化结果从 OnRcspCallback.onRcspInit()
回调
Warning
打开认证时,先认证成功,再传输连接状态
//设备连接已连接(打开认证时,先认证成功,再传输连接状态)
this.rcspOp.transmitDeviceStatus(new Device(result.deviceId), Connection.CONNECTION_CONNECTED)
//设备连接已断开
this.rcspOp.transmitDeviceStatus(new Device(result.deviceId), Connection.CONNECTION_DISCONNECT)
如何发送命令给设备:
//创建一条命令(例如:获取固件特征信息)
let devcie: Device | null = this.rcspOp.getUsingDevice();
//构建命令
const param = new ParamTargetInfo(0xffffffff, 2);//android平台:0,iOS:1,小程序:2
let command = new CmdGetTargetInfo(param);
//构建命令回复回调
const commandCallback: CommandCallback ={
onCmdResponse(device: Device, command: CommandBase) {
//命令状态是否成功
if (command.getStatus() != ResponseBase.STATUS_SUCCESS) {
const code = ErrorCode.ERROR_REPLY_BAD_STATUS;
return
}
const response = command.response
//命令是否有回复
if (null == response) {
return;
}
//强制转换成对应的Response
const responseTargetInfo = response as ResponseTargetInfo
//获取命令回复解析后的属性(举例:设备的版本名称)
responseTargetInfo.versionName;
},
onError(device: Device, code: number, message: string) {
//命令异常
}
}
//发送命令
if(device!=null){
//命令超时时间
const timeoutMs = RcspConstant.DEFAULT_SEND_CMD_TIMEOUT;
this.rcspOp.sendRCSPCommand(device,command,timeoutMs,commandCallback);
}
2.3 OTA库使用
目前小程序的OTA_SDK只处理OTA流程的控制,没有做命令解析和构建的处理。所以在使用的时候需要通过 ota-rcsp.ts
与RCSP_SDK建立命令解析和命令构建的联系。
关于如何获取设备的固件版本信息:
Important
RcspOpImpl.transmitDeviceStatus()
)。当OnRcspCallback 回调初始化成功后( OnRcspCallback.onRcspInit()
),上层可获取设备信息( RcspOpImpl.getDeviceInfo()
),设备信息中包含了固件的版本信息( deviceInfo.versionName
和 deviceInfo.versionCode
)2.3.1 OTA_SDK接口使用
使用
OTAImpl
之前,需要先实现IOTAOp
接口,对OTA每个流程的数据进行处理(ota-rcsp.ts
已做了处理)。ota-rcsp中的 RcspOTAManager 已封装好了OTA_SDK的相关接口,可直接使用RcspOTAManager代替OTAImpl接口。1.设备初始化(当RCSP库初始化成功后,单备份回连成功也需要调用)
OTAImpl接口
OTAImpl.onDeviceInit(deviceUpgradeInfo: DeviceUpgradeInfo | undefined, isInit: boolean | undefined)RcspOTAManager 对应的接口(无),内部已处理
2.开始升级
OTAImpl接口
OTAImpl.startOTA(config: OTAConfig, callback: OnUpgradeCallback)RcspOTAManager 对应的接口
RcspOTAManager.startOTA(config: OTAConfig, callback: OnUpgradeCallback)3.取消升级(仅双备份有效)
OTAImpl接口
OTAImpl.cancelOTA()RcspOTAManager 对应的接口
RcspOTAManager.cancelOTA()4.状态同步,设备断开(正常单备份升级会断开设备进行回连)
OTAImpl接口
OTAImpl.onDeviceDisconnect()RcspOTAManager 对应的接口(无),内部已处理
5.释放缓存
OTAImpl接口
OTAImpl.release()RcspOTAManager 对应的接口
RcspOTAManager.release()
2.4 单备份升级注意事项
关于单备份的强制升级有以下几点注意事项:
Important
关于单备份如何检查设备是否需要强制升级:
Important
RcspOpImpl.transmitDeviceStatus()
)。当OnRcspCallback 回调初始化成功后( OnRcspCallback.onRcspInit()
),上层可获取设备信息( RcspOpImpl.getDeviceInfo()
),设备信息中包含了是否需要强制升级( deviceInfo.mandatoryUpgradeFlag==1
)RcspOpImpl.transmitDeviceStatus()
)。当OnRcspCallback 回调需要强制升级时( OnRcspCallback.onMandatoryUpgrade()
) ,则表示该设备需要强制升级。不需要强制升级的设备是不会回调的。2.5 单备份升级的新回连广播包
该功能可选用:在设备端或小程序端之一选择不使用新回连,设备就会使用旧的广播包。小程序端配置 OTAConfig.isSupportNewRebootWay
部分设备和部分手机单备份升级时,在回连过程中,系统会直接回连上设备,导致SDK回连设备超时。故此在切换到Loader系统时,设备换了一个新的蓝牙地址,App端通过设备的广播包去判断设备是不是当前升级设备。
新回连广播包格式:
Byte0-4 |
Byte5 |
Byte6-11 |
Byte12-13 |
Byte14-15 |
Byte16 |
Byte17 |
Byte18-26 |
---|---|---|---|---|---|---|---|
JLOTA(标识) |
0 |
原BLE地址 |
|||||
JLOTA(标识) |
1 |
原BLE地址 |
UID |
PID |
Bit7-4:Type Bit3-0:Version |
电量 |
保留位 |
2.6 注意事项
为了防止单备份升级失败导致固件变”砖”, 因此固件单备份升级失败后会进入强制升级模式
因为未连接设备时, 不知道设备状态, 所以库初始化成功后需要查询设备升级状态()
当连接上设备(若打开认证,需要先认证成功)后,可以将设备连接状态传输给RcspOpImpl
用户SDK或APP应该具备回连上一次连接的蓝牙设备的功能, 用于强制升级时自动回连设备, 再通过OTA升级更新固件
单备份方案,下载boot完成后,会先断开已连接的蓝牙(SPP或BLE), 进入uboot后,然后回连BLE
双备份方案, 不需要回连过程,直接开始升级流程