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库使用
Note
v2.1.1版本修改了OTA库的使用方式。增加了otaWrapper类,对OTA库进行进一层封装,方便使用。
Note
v2.1.1版本修改了OTA库的打包结构,将ota-rcsp.ts文件也打包进了SDK文件内,但是export保留了 RcspOTAManager
和 OTAImpl
。不影响v2.1.0之前的使用方式。
2.3.1 使用OTAWrapper进行OTA
通常情况下,我们只需要通过使用OTAWrapper就可以完成OTA功能。不需要实现和使用OTA库的接口。
第一步:初始化OTAWrapper
//OTAWrapper 初始化
const otaWrapperOption: OTAWrapperOption = {
/**是否需要认证。 在上层已经认证过,就不需要认证。**/
isUseAuth: () => {
return this._BluetoothConfigure.isUseAuth
},
/**是否需要回连。 在上层进行回连,就不需要内部回连。**/
isInnerReconnect: () => {
return true
},
/**扫描设备**/
sanDevice: () => {
//todo 实现蓝牙扫描操作
},
/**连接设备**/
connectDevice: (device: BluetoothDevice) => {
//todo 实现蓝牙连接操作
},
/**断开设备**/
disconnectDevice: (device: BluetoothDevice) => {
//todo 实现蓝牙断开操作
},
/**发送数据(非必须实现),
* 必须实现的情况:
* - 1.内部创建并管理RCSPImpl, 即OTAWrapperOption.getRCSPImpl未实现
* - 2.需要进行认证, 即OTAWrapperOption.isUseAuth返回false
* **/
sendData: (device: BluetoothDevice, data: Uint8Array) => {
//todo 实现蓝牙发数操作
}
/**获取RCSPImpl(非必须实现)。
* - 上层管理RCSPImpl则需要实现,如使用jl-rcsp-op时需要实现。
* - 上层不管理RCSPImpl则不需要实现,由内部创建并管理RCSPImpl
* **/
//getRCSPImpl?(device: BluetoothDevice): RCSPProtocol.RcspImpl | undefined
}
this._OTAWrapper = new OTAWrapper(otaWrapperOption)
第二步:监听蓝牙连接状态并同步OTAWrapper
this._bluetoothInstance.addConnectCallback({
onMTUChange: (dev: any, mtu) => {
BleSendDataHandler.setMtu(dev.deviceId, mtu)
this._onConnectStateMTUChange(dev, mtu)
}, onConnectSuccess: (dev: any) => {
// 通知 OTAWrapper 蓝牙连接成功
this._OTAWrapper.onConnectStateSuccess(dev)
this._onConnectStateSuccess(dev)
}, onConnectFailed: (dev: any, _err) => {
// 通知 OTAWrapper 蓝牙连接失败
this._OTAWrapper.onConnectStateFailed(dev)
this._onConnectStateFailed(dev)
}, onConnectDisconnect: (dev: any) => {
// 通知 OTAWrapper 蓝牙连接断开
this._OTAWrapper.onConnectStateDisconnect(dev)
this._onConnectStateDisconnect(dev)
}
})
第三步:监听蓝牙扫描状态并同步OTAWrapper
this._bluetoothInstance.addScanCallback({
onFound: (devs: BTBean.BluetoothDevice[]) => {
// 通知 OTAWrapper 发现设备
this._OTAWrapper.onScanFound(devs)
this._onScanFound(devs)
}, onScanStart: () => {
this._onScanStart()
}, onScanFailed: (err: BTBean.BluetoothError) => {
this._onScanFailed(err)
}, onScanFinish: () => {
// 通知 OTAWrapper 扫描设备停止
this._OTAWrapper.onSanDeviceStop()
this._onScanFinish()
}
})
第四步:监听蓝牙数据推送并同步OTAWrapper
const bleDataCallback: BleDataCallback = {
onReceiveData: (res: WechatMiniprogram.OnBLECharacteristicValueChangeCallbackResult) => {
// 通知 OTAWrapper 收到数据
this._OTAWrapper.onReceiveData(this._toDevice(res.deviceId), res.value)
}
}
BleDataHandler.addCallbacks(bleDataCallback)
第五步:连接设备
连接设备时,会进行RCSP的认证和RCSP的初始化。当认证失败或者初始化失败时,SDK会主动断开设备(OTAWrapperOption.disconnectDevice)。
若需要监听设备的初始化状态。可在OTAWrapper注册RCSP回调(OTAWrapper.registerRcspCallback)。
若需要判断设备是否初始化成功,可调用IOTAWrapper.isRCSPInit方法。
第六步:开始OTA
/*--- 开始执行OTA升级 ---*/
//创建OTA配置项
const otaConfig: OTAConfig = new OTAConfig()
//是否支持新的回连方式
otaConfig.isSupportNewRebootWay = true
//固件升级文件数据
otaConfig.updateFileData = this.upgradeData
//升级目标设备
const device = connectedDevices[0]
const onUgradeCallback: OnUpgradeCallback = {
onStartOTA: () => {
// 开始升级
},
onNeedReconnect: (reConnectMsg: ReConnectMsg) => {
// 正在回连
},
onProgress: (type: UpgradeType, progress: number) => {
// 升级进度回调
if (type == UpgradeType.UPGRADE_TYPE_CHECK_FILE) {
// 校验文件(传输BootLoader)
} else if (type == UpgradeType.UPGRADE_TYPE_FIRMWARE) {
// 传输升级内容
}
},
onStopOTA: () => {
// 升级结束
},
onCancelOTA: () => {
// 升级取消
},
onError: (error: number, message: string) => {
// 升级失败
},
}
this._OTAWrapper.startOTA(device, otaConfig, onUgradeCallback)
关于如何获取设备的固件版本信息:
Important
OTAWrapper.getDeviceInfo()
),设备信息中包含了固件的版本信息( deviceInfo.versionName
和 deviceInfo.versionCode
)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
双备份方案, 不需要回连过程,直接开始升级流程