杰理 SDK 文档中心
首页
首页
  • 项目概览与入门

    • 项目概述
    • 快速开始
  • OTA SDK 核心库

    • RCSP 认证库(jl_auth)
    • OTA 流程库(jl_ota)
    • RCSP-OTA 协议库(jl_rcsp_ota)
    • OTAWrapper 高层封装
  • 蓝牙通信与设备管理

    • 蓝牙连接生命周期管理
    • BLE 数据发送与 MTU 管理
    • 自动回连机制
  • 参考 Demo 小程序

    • 应用入口与页面导航
    • 设备连接页(pageConnect)
    • 固件升级页(pageUpdate)
    • 设置与调试页(pageSetting)
    • 自定义 UI 组件
    • 固件文件解析工具(upgradeFileUtil)
    • 日志系统

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.02022/03/17首次增加 OTA 功能,支持单备份、双备份 OTA
V2.0.02023/01/11抽离 SDK 中的蓝牙连接和收发数据部分,优化 SDK API(即 OTAWrapper 分层雏形)
V2.1.12024/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方法。

该阶段的内部行为可归纳为:

  1. RCSP 认证(可选):依据 isUseAuth() 返回值决定。若需要认证,SDK 通过 sendData/onReceiveData 通道与设备完成认证握手;认证失败则调用 disconnectDevice(device) 主动断开,避免设备停留在半连接状态。
  2. RCSP 初始化:认证通过后初始化 RCSPImpl(若未通过 getRCSPImpl 注入则内部创建),建立协议会话。
  3. 结果查询与监听:
    • 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 关键字段

字段类型说明
isSupportNewRebootWayboolean是否支持新的回连方式。V2.1.1 修复的 iOS16 单备份升级回连问题即与此相关;开启后 SDK 采用新的设备重启寻址流程
updateFileDataUint8Array固件升级文件数据,由业务层从聊天文件/本地文件读取后注入

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):

  1. 打开小程序:初次打开需授予蓝牙等对应权限;
  2. 添加升级文件:支持从聊天文件选择固件;
  3. 连接目标设备:搜索并连接需要升级的蓝牙设备;
  4. 开始 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 框架(原生 wx API、自研封装、第三方桥接)接入 OTAWrapper,SDK 逻辑零改动。
  • 共享 RCSPImpl:若业务同时使用 jl-rcsp-op 等库执行 RCSP 操作,可实现 getRCSPImpl 把协议实例交给 OTAWrapper,避免同一设备上两个协议栈实例并存;反之则让 SDK 内部管理,简化上层。
  • 认证策略:isUseAuth 允许上层已认证过的场景跳过认证握手;isInnerReconnect 允许上层接管回连流程——两条策略开关使同一封装可适配不同业务架构。

Related Links

  • README.md 使用说明(OTAWrapper 六步流程)
  • README_en.md(English version)
  • SDK 库文件:jl_ota_2.1.1.js、jl_rcsp_ota_2.1.1.js、jl_auth_2.0.0.js
  • 认证封装:jl_auth_2.0.0.js(libs 目录副本)
  • 官方 SDK 在线文档:杰理 OTA SDK 开发文档
Prev
RCSP-OTA 协议库(jl_rcsp_ota)