OTAWrapper 高层封装
OTAWrapper 是杰理 OTA SDK 面向微信小程序提供的高层封装类,它将 OTA 库底层接口(蓝牙扫描、连接、RCSP 协议认证、固件传输)整合为一套面向业务场景的简易 API,使开发者无需直接接触 OTA 库内部实现即可完成设备 OTA 升级。
Purpose and Scope
本文档介绍 OTAWrapper 高层封装的设计意图、核心职责与使用方式,内容包括:
OTAWrapper在 SDK 分层中的位置及其与底层库(jl_ota_2.1.1.js、jl_rcsp_ota_2.1.1.js、jl_auth_2.0.0.js)的关系OTAWrapperOption配置项契约及每项回调的职责- 蓝牙连接/扫描/数据事件的同步机制(
onConnectStateSuccess、onScanFound、onReceiveData等) - 连接设备时的 RCSP 认证与初始化流程
startOTA升级入口与OnUpgradeCallback回调语义- 典型使用步骤与失败模式
本页聚焦"高层封装"这一主题;底层 RCSP 协议细节、蓝牙扫描/连接实现、以及小程序页面业务逻辑属于其他目录页的范畴,此处仅在必要时引用。SDK 的具体调用方式与配置说明见仓库根目录 README.md。
Overview
在微信小程序环境中进行蓝牙 OTA 升级,涉及一条完整且复杂的链路:蓝牙扫描与连接、MTU 协商、RCSP(杰理私有通信协议)的认证握手、固件文件校验、BootLoader 传输、双备份/单备份升级等。若让业务方直接调用 OTA 库的底层接口,开发者需要自行管理 RCSP 协议栈生命周期、认证状态机与升级流程,出错概率极高。
OTAWrapper 正是为此而设计的一层"门面(Facade)":它内部持有并管理 RCSPImpl(RCSP 协议实现),对外只暴露少量高内聚的 API:
- 配置注入:通过
OTAWrapperOption将蓝牙操作(扫描、连接、断开、发数)以回调形式注入,SDK 不关心具体蓝牙实现; - 事件同步:业务层把微信小程序的蓝牙状态/数据事件转发给 OTAWrapper,由它驱动内部协议状态机;
- 一键升级:业务层只需构造
OTAConfig(升级文件数据、回连方式)并传入OnUpgradeCallback,即可启动完整升级流程。
这种设计把"协议细节"与"业务场景"解耦:上层只需关心"设备连上了没、升级到多少进度、是否失败",协议层的认证、回连、校验全部由封装内部完成。
SDK 版本对应关系(见 README.md 版本历史):
| 版本 | 发布时间 | 要点 |
|---|---|---|
| V1.0.0 | 2022/03/17 | 首次增加 OTA 功能,支持单备份、双备份 OTA |
| V2.0.0 | 2023/01/11 | 抽离 SDK 中的蓝牙连接和收发数据部分,优化 SDK API(即 OTAWrapper 分层雏形) |
| V2.1.1 | 2024/09/09 | 修复 iOS16 单备份升级回连搜不到设备、AC695 升级失败问题 |
Architecture
flowchart TD
subgraph sg_Biz["业务层(小程序页面)"]
Page["Page / 业务逻辑"]
Wrapper["OTAWrapper 实例"]
end
subgraph sg_Options["OTAWrapperOption 回调注入"]
OptScan["sanDevice() 扫描设备"]
OptConnect["connectDevice() 连接设备"]
OptDisconnect["disconnectDevice() 断开设备"]
OptSend["sendData() 发送数据"]
OptAuth["isUseAuth() 是否认证"]
OptReconnect["isInnerReconnect() 是否内部回连"]
OptRCSP["getRCSPImpl() 获取 RCSPImpl"]
end
subgraph sg_BLE["微信小程序蓝牙层"]
Ble["Bluetooth 实例<br/>(连接/扫描回调)"]
BleData["BleDataHandler 数据回调"]
end
subgraph sg_SDK["OTA SDK 内部"]
OtaLib["jl_ota_2.1.1.js"]
RcspLib["jl_rcsp_ota_2.1.1.js"]
AuthLib["jl_auth_2.0.0.js"]
RCSPImpl["RCSPImpl(协议实现)"]
UpgradeEngine["升级流程引擎<br/>(认证/校验/传输)"]
end
Page -->|"new OTAWrapper(option)"| Wrapper
Wrapper -->|"回调实现"| OptScan
Wrapper -->|"回调实现"| OptConnect
Wrapper -->|"回调实现"| OptDisconnect
Wrapper -->|"回调实现"| OptSend
Wrapper -->|"读取配置"| OptAuth
Wrapper -->|"读取配置"| OptReconnect
Wrapper -->|"可选"| OptRCSP
Ble -->|"onConnectSuccess/onScanFound<br/>同步事件"| Wrapper
BleData -->|"onReceiveData 同步数据"| Wrapper
Wrapper -->|"内部创建/管理"| RCSPImpl
RCSPImpl --> RcspLib
RCSPImpl --> AuthLib
UpgradeEngine --> OtaLib
RCSPImpl --> UpgradeEngine
架构图说明:
- 业务层是唯一需要开发者编写的部分:创建
OTAWrapper实例,并通过回调把蓝牙能力注入封装。页面的业务回调(如onConnectSuccess)同时转发给 OTAWrapper,实现状态同步。 - OTAWrapperOption 回调注入是解耦的关键:SDK 不直接调用微信小程序的蓝牙 API,而是通过
sanDevice、connectDevice、sendData等回调反向调用业务层,保证 SDK 与具体蓝牙框架无关。 - OTA SDK 内部(
code/JLOTA/miniprogram/lib/jl_lib/下的jl_ota_2.1.1.js、jl_rcsp_ota_2.1.1.js、jl_auth_2.0.0.js,仓库根目录libs/下另有同版本副本)由 OTAWrapper 统一驱动:RCSPImpl 负责协议栈与认证,升级引擎负责文件校验与固件传输,业务层不直接触碰这些实现。
说明:OTAWrapper 类本体位于闭源/压缩的 SDK 库文件中(
jl_ota_2.1.1.js等),仓库源码中不包含其类定义;本文档基于仓库 README 的使用契约与其在示例中的调用方式归纳其行为。
OTAWrapperOption 配置契约
OTAWrapper 通过构造参数 OTAWrapperOption 获得全部外部依赖与策略配置。该配置的设计意图是将蓝牙操作倒置为回调:SDK 定义"需要做什么",业务层实现"具体怎么做",从而让同一套 OTA 逻辑可以运行在任意蓝牙封装之上(微信小程序原生 API、自研 BLE 框架等)。
初始化示例(摘自 README.md):
//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)
回调语义与设计意图
| 配置项 | 类型 | 必须实现? | 职责与设计意图 |
|---|---|---|---|
isUseAuth | () => boolean | 是 | 决定连接后是否执行 RCSP 认证。若上层(如业务 App)已完成认证,返回 false 可跳过认证握手,避免重复认证导致协议状态错乱 |
isInnerReconnect | () => boolean | 是 | 决定升级过程中的回连(如设备重启进入 BootLoader)由 SDK 内部处理还是上层处理。返回 true 时由内部回连,简化上层逻辑 |
sanDevice | () => void | 是 | 触发蓝牙扫描。SDK 在需要回连/搜索目标设备时回调该函数,具体扫描实现(如 wx.startBluetoothDevicesDiscovery)由上层完成 |
connectDevice | (device) => void | 是 | 建立蓝牙连接。SDK 内部决定"连谁",上层决定"怎么连" |
disconnectDevice | (device) => void | 是 | 断开蓝牙连接。重要用途:当 RCSP 认证失败或初始化失败时,SDK 会主动回调此函数断开设备,防止设备停留在异常连接状态 |
sendData | (device, data: Uint8Array) => void | 条件必须 | 通过 BLE 特征值写入通道发送数据。当 OTAWrapper 内部创建并管理 RCSPImpl(未实现 getRCSPImpl)或需要进行认证(isUseAuth 返回 false)时必须实现——因为这两条路径下协议数据的收发由 SDK 内部驱动 |
getRCSPImpl | (device) => RcspImpl | undefined | 否 | 若上层自行管理 RCSPImpl(例如同时使用 jl-rcsp-op 做其他 RCSP 操作),则实现此函数交还协议实例;否则由 OTAWrapper 内部创建并管理 |
设计要点:sendData 的"条件必须"规则体现了封装的分层策略——当上层已管理 RCSPImpl 时,数据收发走上层通道,SDK 不再重复接管;当 SDK 内部管理 RCSPImpl 时,必须通过 sendData 回调获得发送能力。这种"谁管理协议栈,谁负责发数"的约定避免了双写数据通道的冲突。
蓝牙状态事件同步
OTAWrapper 本身不监听微信小程序的蓝牙事件,而是要求业务层主动转发连接、扫描与数据事件。这样做的好处是:SDK 不依赖任何特定蓝牙库的注册机制,业务层已有的 Bluetooth 实例和回调管线可以原样复用,只需在原有回调里"顺带"通知 OTAWrapper。
连接状态同步
摘自 README.md:
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)
}
})
onConnectStateSuccess(dev):通知 OTAWrapper 设备已连接,SDK 随即进入 RCSP 认证/初始化流程(见下文)。onConnectStateFailed(dev):连接失败,SDK 清理本次连接上下文,避免悬挂状态。onConnectStateDisconnect(dev):连接断开(含升级完成后设备重启断开),SDK 据此判断回连时机或终止升级。onMTUChange与BleSendDataHandler.setMtu:MTU 协商结果用于分片发送,保证sendData发送的数据包不超出单次 BLE 写入上限。
扫描状态同步
摘自 README.md:
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()
}
})
onScanFound(devs):扫描到设备时上报设备列表。升级回连场景下,SDK 依赖该回调发现重启后的设备(如 BootLoader 状态的新设备名/地址)以完成自动重连。onSanDeviceStop():扫描停止后必须通知 SDK,否则 SDK 内部可能一直认为扫描仍在进行而无法发起后续连接。
数据接收同步
摘自 README.md:
const bleDataCallback: BleDataCallback = {
onReceiveData: (res: WechatMiniprogram.OnBLECharacteristicValueChangeCallbackResult) => {
// 通知 OTAWrapper 收到数据
this._OTAWrapper.onReceiveData(this._toDevice(res.deviceId), res.value)
}
}
BleDataHandler.addCallbacks(bleDataCallback)
onReceiveData(device, value) 是 SDK 内部协议栈(RCSPImpl)的数据入口。微信小程序通过 wx.onBLECharacteristicValueChange 收到通知后,业务层将其转换为 (device, Uint8Array) 形式转交 OTAWrapper,SDK 解析 RCSP 帧并驱动升级状态机。注意 _toDevice(res.deviceId) 的作用:把字符串形式的 deviceId 还原为 BluetoothDevice 对象,保证与 connectDevice/sendData 回调收到的是同一对象引用,这是协议栈按设备区分会话的前提。
连接设备与 RCSP 认证/初始化
当业务层通过蓝牙实例建立物理连接并同步 onConnectStateSuccess 后,OTAWrapper 会自动执行协议层初始化,业务层无需干预。README 对该阶段的行为描述如下(摘自 README.md):
连接设备时,会进行RCSP的认证和RCSP的初始化。当认证失败或者初始化失败时,SDK会主动断开设备(OTAWrapperOption.disconnectDevice)。 若需要监听设备的初始化状态。可在OTAWrapper注册RCSP回调(OTAWrapper.registerRcspCallback)。 若需要判断设备是否初始化成功,可调用IOTAWrapper.isRCSPInit方法。
该阶段的内部行为可归纳为:
- RCSP 认证(可选):依据
isUseAuth()返回值决定。若需要认证,SDK 通过sendData/onReceiveData通道与设备完成认证握手;认证失败则调用disconnectDevice(device)主动断开,避免设备停留在半连接状态。 - RCSP 初始化:认证通过后初始化 RCSPImpl(若未通过
getRCSPImpl注入则内部创建),建立协议会话。 - 结果查询与监听:
IOTAWrapper.isRCSPInit:同步判断指定设备是否初始化成功;OTAWrapper.registerRcspCallback:注册 RCSP 级回调,监听初始化等状态变化。
设计意图:认证与初始化失败时"主动断开"而非"静默重试",是因为蓝牙协议栈状态机不允许在认证失败后继续复用连接——保留异常连接只会让后续 sendData 产生无意义的数据帧并占用设备资源。主动断开把恢复控制权交还上层(上层可决定重新扫描或提示用户)。
startOTA 升级入口
设备完成 RCSP 初始化后,即可调用 startOTA(device, otaConfig, onUpgradeCallback) 启动升级。示例摘自 README.md:
/*--- 开始执行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)
OTAConfig 关键字段
| 字段 | 类型 | 说明 |
|---|---|---|
isSupportNewRebootWay | boolean | 是否支持新的回连方式。V2.1.1 修复的 iOS16 单备份升级回连问题即与此相关;开启后 SDK 采用新的设备重启寻址流程 |
updateFileData | Uint8Array | 固件升级文件数据,由业务层从聊天文件/本地文件读取后注入 |
OnUpgradeCallback 回调语义
| 回调 | 触发时机 | 设计意图 |
|---|---|---|
onStartOTA | 升级流程启动 | 页面可在此进入升级中 UI,锁定操作 |
onNeedReconnect(reConnectMsg) | 设备重启、需要回连 | 通知上层"设备正在重启",配合 isInnerReconnect 由内部或上层执行重新扫描/连接(sanDevice、onScanFound、onConnectStateSuccess 链路) |
onProgress(type, progress) | 传输进度变化 | UPGRADE_TYPE_CHECK_FILE 表示校验文件/传输 BootLoader 阶段,UPGRADE_TYPE_FIRMWARE 表示固件内容传输阶段;页面据此展示不同进度条 |
onStopOTA | 升级正常结束 | 页面提示升级完成并清理状态 |
onCancelOTA | 升级被取消 | 页面恢复可操作状态 |
onError(error, message) | 升级失败 | 携带错误码与可读信息,页面提示失败原因 |
Core Flow
sequenceDiagram
participant Page as 业务层 Page
participant W as OTAWrapper
participant BLE as 微信蓝牙层
participant SDK as SDK内部(RCSPImpl/升级引擎)
participant Dev as 蓝牙设备
Page->>W: new OTAWrapper(option)
Note over Page,W: 注入 sanDevice/connectDevice/sendData 等回调
Page->>BLE: 开始扫描
BLE-->>Page: onScanFound(devs)
Page->>W: onScanFound(devs)
Page->>BLE: connectDevice(device)
BLE-->>Page: onConnectSuccess(dev)
Page->>W: onConnectStateSuccess(dev)
W->>SDK: 发起 RCSP 认证(isUseAuth=true 时)
SDK->>Page: sendData(device, frame) 回调
Page->>BLE: 写入特征值
BLE-->>Page: onReceiveData(res)
Page->>W: onReceiveData(device, value)
Note over W,SDK: 认证通过 → RCSP 初始化
Page->>W: startOTA(device, otaConfig, callback)
W->>SDK: 校验文件 / 传输 BootLoader
SDK-->>W: onProgress(CHECK_FILE, p)
W-->>Page: onProgress(type, progress)
SDK->>Dev: 设备重启(回连触发)
SDK-->>W: onNeedReconnect(msg)
W-->>Page: onNeedReconnect(msg)
W->>Page: sanDevice() 回调 → 重新扫描
BLE-->>Page: onConnectStateSuccess(dev)
Page->>W: onConnectStateSuccess(dev)
SDK->>Dev: 传输固件内容
SDK-->>W: onProgress(FIRMWARE, p)
W-->>Page: onProgress(type, progress)
SDK-->>W: 升级完成
W-->>Page: onStopOTA()
时序说明:整个升级生命周期中,业务层扮演"事件搬运工"与"能力提供者"双重角色——既要把蓝牙层事件转给 OTAWrapper,又要在 SDK 需要时执行扫描/连接/发数。所有协议决策(何时认证、何时回连、何时校验)都在 OTAWrapper 内部完成,页面代码只维护一条薄薄的转发管线。
使用流程总览
README 第 5.2 节给出的端到端业务流(摘自 README.md):
- 打开小程序:初次打开需授予蓝牙等对应权限;
- 添加升级文件:支持从聊天文件选择固件;
- 连接目标设备:搜索并连接需要升级的蓝牙设备;
- 开始 OTA 升级:选择目标升级文件,开始 OTA 升级。
对应到 OTAWrapper 的 API 使用顺序为:初始化 OTAWrapper → 转发扫描/连接/数据事件 → 等待 isRCSPInit 成功 → 构造 OTAConfig 与 OnUpgradeCallback → startOTA。
API Reference
以下为 README 与示例中实际出现、可供业务层调用的 OTAWrapper 公开 API 归纳。
new OTAWrapper(option: OTAWrapperOption)
构造并初始化高层封装实例。
参数:
option(OTAWrapperOption):全部外部依赖回调与策略配置,见上文「OTAWrapperOption 配置契约」。
说明: 构造时不会立即连接或扫描设备,仅保存配置;实际行为由后续事件驱动。典型用法为页面 onLoad 时创建单例并持有(this._OTAWrapper)。
onConnectStateSuccess(dev: BluetoothDevice): void
通知 OTAWrapper 指定设备蓝牙连接成功,触发 RCSP 认证与初始化流程。
参数:
dev(BluetoothDevice):已连接的设备对象。
onConnectStateFailed(dev: BluetoothDevice): void
通知 OTAWrapper 指定设备连接失败。
参数:
dev(BluetoothDevice):连接失败的设备对象。
onConnectStateDisconnect(dev: BluetoothDevice): void
通知 OTAWrapper 指定设备连接已断开(含升级重启断开)。
参数:
dev(BluetoothDevice):断开的设备对象。
onScanFound(devs: BluetoothDevice[]): void
上报扫描发现的设备列表,供 SDK 回连时识别目标设备。
参数:
devs(BluetoothDevice[]):扫描到的设备数组。
onSanDeviceStop(): void
通知 OTAWrapper 扫描已停止,结束 SDK 内部扫描等待状态。
onReceiveData(dev: BluetoothDevice, value: Uint8Array): void
上报设备下发的 BLE 数据(RCSP 帧),是协议栈的数据入口。
参数:
dev(BluetoothDevice):数据来源设备(需与connectDevice/sendData使用同一对象)。value(Uint8Array):收到的原始数据。
startOTA(device: BluetoothDevice, config: OTAConfig, callback: OnUpgradeCallback): void
对指定设备启动 OTA 升级。前置条件:设备已完成 RCSP 初始化(isRCSPInit 为真)。
参数:
device(BluetoothDevice):升级目标设备。config(OTAConfig):升级配置,至少设置updateFileData(固件数据)与isSupportNewRebootWay(回连方式)。callback(OnUpgradeCallback):升级生命周期回调(onStartOTA/onNeedReconnect/onProgress/onStopOTA/onCancelOTA/onError)。
registerRcspCallback(cb): void
注册 RCSP 级回调,用于监听设备 RCSP 初始化等协议层状态。
isRCSPInit(device: BluetoothDevice): boolean
同步查询指定设备是否已完成 RCSP 初始化,用于判断是否可以开始升级。
返回: true 表示设备协议栈就绪。
注意:
registerRcspCallback、isRCSPInit的完整签名(回调结构、参数)定义于闭源 SDK 库文件(code/JLOTA/miniprogram/lib/jl_lib/jl_ota_2.1.1.js),仓库源码中未包含其类型声明;此处仅按 README 使用说明归纳其行为,具体参数以 SDK 类型定义为准。
Failure Modes, Edge Cases & Concurrency
认证/初始化失败 → 主动断开
README 明确说明:RCSP 认证失败或初始化失败时,SDK 会调用 OTAWrapperOption.disconnectDevice 主动断开设备。业务层必须实现 disconnectDevice,否则异常设备将滞留连接池。页面应在收到 onConnectStateDisconnect 后给出"连接失败/设备异常"提示并复位 UI。
回连失败(尤其 iOS 场景)
升级过程中设备重启后,SDK 依赖 sanDevice → onScanFound → connectDevice → onConnectStateSuccess 链路重新发现并连接设备。V2.1.1 专门修复了 iOS16 单备份升级回连搜不到设备的问题——若业务运行在 iOS16+ 且升级方案为单备份,务必使用 V2.1.1 及以上 SDK,并在 OTAConfig 中按需设置 isSupportNewRebootWay。
数据分片与 MTU
onMTUChange 中调用 BleSendDataHandler.setMtu(dev.deviceId, mtu) 是 sendData 正确工作的前提:MTU 决定单帧 BLE 写入长度,若 MTU 未设置或过小,长固件数据包可能写入失败或被设备丢弃,表现为进度卡死或 onError。业务层应在每次连接成功后最先处理 MTU 变更事件。
事件顺序约束(时序敏感性)
OTAWrapper 的状态机依赖事件顺序:onConnectStateSuccess 必须发生在 startOTA 之前,onSanDeviceStop 必须发生在下一次扫描之前,onReceiveData 必须与发送通道(sendData)配对。微信小程序的蓝牙回调与页面 JS 同属单线程事件循环,正常情况下顺序有保证,但若业务层在回调里做了异步等待(如 await 弹窗),可能打乱 SDK 期待的节奏,建议转发逻辑保持同步、无阻塞。
多设备并发
SDK 的 API 均以 device 对象区分会话,README 示例中 startOTA 的目标设备为 connectedDevices[0](单设备升级)。若业务需要多设备同时升级,必须确保 connectDevice/sendData/onReceiveData 等回调按 device 正确路由数据,避免跨设备数据串扰导致 RCSP 帧错乱。
Performance & Operational Notes
- 固件数据内存占用:
otaConfig.updateFileData直接持有完整固件文件的Uint8Array,大固件(数 MB)会占用小程序内存;建议在开始升级前再赋值,升级结束后及时释放引用。 - 进度回调频率:
onProgress可能高频触发,页面应避免在回调内执行重操作(如 setData 大对象、绘制动画的每帧计算),可做节流。 - 日志与调试:SDK 提供详细日志输出,可观察连接状态与数据交互;真机调试可用
vConsole查看实时日志(见 README.md 调试技巧),问题排查参考官方 SDK 调试说明。 - 版本选择:升级场景建议直接使用 V2.1.1(
jl_ota_2.1.1.js/jl_rcsp_ota_2.1.1.js/jl_auth_2.0.0.js),仓库code/JLOTA/miniprogram/lib/jl_lib/与根目录libs/两处均提供了同版本库文件,二选一引用即可。
Extension Points
OTAWrapper 的扩展性主要体现为回调注入与可选覆盖:
- 自定义蓝牙层:通过
sanDevice/connectDevice/disconnectDevice/sendData四件套,可将任意 BLE 框架(原生wxAPI、自研封装、第三方桥接)接入 OTAWrapper,SDK 逻辑零改动。 - 共享 RCSPImpl:若业务同时使用
jl-rcsp-op等库执行 RCSP 操作,可实现getRCSPImpl把协议实例交给 OTAWrapper,避免同一设备上两个协议栈实例并存;反之则让 SDK 内部管理,简化上层。 - 认证策略:
isUseAuth允许上层已认证过的场景跳过认证握手;isInnerReconnect允许上层接管回连流程——两条策略开关使同一封装可适配不同业务架构。