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

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

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

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

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

自动回连机制

自动回连(Auto Reconnect)是杰理微信小程序 OTA SDK(jl_ota_2.1.1)中为单备份 OTA 设计的关键机制:当设备在升级过程中重启并重新进入可连接状态时,SDK 通过 onNeedReconnect 回调通知上层,并(可选地)在内部自动完成 BLE 重连,从而让升级流程无感续传,显著提升用户体验。

Purpose and Scope

本页面向自动回连机制这一主题,覆盖:

  • 自动回连的触发条件与使用场景(单备份 OTA)
  • 回连相关的核心接口与数据结构(OTAConfig、ReConnectMsg、OnUpgradeCallback.onNeedReconnect、OTAWrapperOption.isInnerReconnect)
  • SDK 内部回连实现机制(OTAImpl 中的回连定时器、RECONNECT_DEVICE_DELAY、超时控制)
  • 新旧两种回连方式(传统广播搜索 vs 基于 BLE MAC 的新回连方式)
  • 上层(小程序业务层)集成自动回连的完整步骤与代码示例
  • 回连相关的错误码、失败模式与边界情况

以下内容不属于本页范围,由其他目录页覆盖:

  • 蓝牙扫描/连接/收发的通用能力(OTAWrapperOption 的 sanDevice、connectDevice 等基础蓝牙操作)
  • 认证(Auth)流程本身
  • 双备份 OTA 的取消逻辑(cancelOTA 仅对双备份方案有效)
  • RCSP 协议与 jl_rcsp_ota 的具体协议实现

Overview

为什么需要自动回连

在单备份 OTA(single-backup OTA)方案中,升级流程通常包含两个阶段:

  1. 传输 BootLoader / 校验文件(UPGRADE_TYPE_CHECK_FILE)
  2. 传输固件内容(UPGRADE_TYPE_FIRMWARE)

其中"传输 BootLoader"阶段完成后,设备需要重启并进入升级模式,此时原 BLE 连接必然断开。若没有自动回连机制,上层必须手动重新扫描、重新连接设备,用户会看到"连接断开"的体验,升级也可能因错过设备重启完成的时间窗口而失败。

自动回连机制正是为了解决这个问题:SDK 在检测到设备需要重启回连时,通过 onNeedReconnect(reConnectMsg) 回调告知上层,上层只需"仅连接通讯通道(BLE 或 SPP)",随后 SDK 内部继续推进 OTA 流程。

两种回连方式

方式触发配置机制适用版本
传统回连默认行为上层重新扫描广播并连接设备全版本
新回连方式(New Reboot Way)otaConfig.isSupportNewRebootWay = true基于 RCSP 协议上报的 deviceBleMac 直接定向连接,无需重新扫描;支持设备侧新回连广播 isSupportNewReconnectADVSDK 2.1.x 起(V2.1.1 修复 iOS16 下新回连搜不到设备问题)

新回连方式的优势在于:不必依赖全量广播扫描,而是利用 RCSP 通讯中获取到的设备 BLE MAC 地址(ReConnectMsg.deviceBleMac)做定向重连,更快速、更可靠。

Architecture

下图展示了自动回连机制在整个 OTA 系统中的位置与组件关系:

flowchart TD
    subgraph sg_Business["小程序业务层(上层)"]
        BLE["蓝牙管理实例<br/>(扫描/连接/断开/收发)"]
        OTAWrapper["OTAWrapper"]
    end

    subgraph sg_SDK["JL OTA SDK (jl_ota_2.1.1)"]
        OTAImpl["OTAImpl"]
        CbHelper["UpgradeCallbackHelper"]
        Timers["回连定时器组<br/>_ReconnectTimer / _WaitDeviceOffLineTimer<br/>_TaskTimer"]
    end

    subgraph sg_Device["设备端"]
        Dev["BLE 设备<br/>(单备份升级模式)"]
    end

    BLE -->|"onConnectStateSuccess / onConnectStateDisconnect<br/>onScanFound / onReceiveData"| OTAWrapper
    OTAWrapper -->|"startOTA(config, callback)"| OTAImpl
    OTAImpl -->|"onNeedReconnect(ReConnectMsg)"| CbHelper
    CbHelper -->|"回调"| OTAWrapper
    OTAWrapper -->|"触发上层重连<br/>(仅连接通讯通道)"| BLE
    OTAImpl -->|"RECONNECT_DEVICE_DELAY=1000ms<br/>RECONNECT_DEVICE_TIMEOUT"| Timers
    BLE -->|"BLE 连接/数据传输"| Dev
    OTAImpl -->|"setDeviceBLEMac / _setReConnectMsg"| Dev

组件说明

组件角色与回连的关系
OTAWrapperSDK 面向业务层的外观类(门面)接收上层蓝牙状态同步(onConnectStateSuccess 等),转发给 OTAImpl;也负责把 onNeedReconnect 等回调透传给上层
OTAImplOTA 流程核心引擎持有 _ReConnectMsg、_ReconnectTimer、_WaitDeviceOffLineTimer;负责 _readyToReconnectDevice、_startReConnectDeviceTimeout 等内部回连逻辑
UpgradeCallbackHelper回调分发辅助类把 onNeedReconnect、onProgress、onError 等事件安全地分发给上层注册的 OnUpgradeCallback
回连定时器组回连超时/延迟控制RECONNECT_DEVICE_DELAY = 1000(回连前延迟 1 秒)、RECONNECT_DEVICE_TIMEOUT(回连总超时,超时触发 ERROR_OTA_RECONNECT_DEVICE_TIMEOUT = -112)
上层蓝牙管理小程序的 wx BLE API 封装执行实际的"仅连接通讯通道"动作;若 isInnerReconnect() 返回 false,则由上层完全接管回连

设计意图:SDK 将蓝牙连接与数据收发抽离到上层(V2.0.0 起),因此回连动作本身由上层执行,SDK 只负责"何时需要回连"的决策与超时守护。这种分工让 SDK 不依赖具体的小程序蓝牙实现,同时通过回调与定时器保证回连动作必须在规定时间内完成。

触发时机与关键接口

触发时机:OnUpgradeCallback.onNeedReconnect

回连的触发入口是升级回调中的 onNeedReconnect。SDK 在设备完成 BootLoader 传输、即将重启进入升级模式时调用它。类型定义中特别注明了两条约束:

  • 仅连接通讯通道(BLE 或 SPP)——上层在收到该回调时不要执行完整的"认证 + RCSP 初始化"流程,只需建立物理通讯链路;
  • 用于单备份 OTA——双备份方案不依赖该机制。
/** 升级流程的回调 */
interface OnUpgradeCallback {
    /** OTA开始*/
    onStartOTA(): void;
    /**需要回连的回调
     * <p>
     * 注意: 1.仅连接通讯通道(BLE or  SPP)
     * 2.用于单备份OTA</p>
     *
     * @param reConnectMsg 回连设备信息
     */
    onNeedReconnect(reConnectMsg: ReConnectMsg): void;
    /** 进度回调
     *
     * @param type     类型
     * @param progress 进度
     */
    onProgress(type: UpgradeType, progress: number): void;
    /** OTA结束*/
    onStopOTA(): void;
    /** OTA取消*/
    onCancelOTA(): void;
    /** OTA失败
     * @param error   错误码
     * @param message 错误信息
     */
    onError(error: number, message: string): void;
}

Source: libs/jl_ota_2.1.1.d.ts

回连信息:ReConnectMsg

onNeedReconnect 携带的 ReConnectMsg 封装了回连所需的设备信息:

/** 回连信息*/
declare class ReConnectMsg {
    isSupportNewReconnectADV?: boolean;
    /** rcsp协议中的BLE_Mac地址  */
    deviceBleMac?: string;
    copy(): ReConnectMsg;
    toString(): string;
}

Source: libs/jl_ota_2.1.1.d.ts

字段含义:

字段类型说明
isSupportNewReconnectADVboolean?设备是否支持"新回连广播"。支持时设备重启后会以特定广播方式快速被发现
deviceBleMacstring?RCSP 协议中上报的 BLE MAC 地址,用于新回连方式的定向重连(不必全量扫描)

这两个字段正是"新回连方式"的数据基础:只要拿到 deviceBleMac,上层即可直接按 MAC 过滤/定向连接;isSupportNewReconnectADV 则告诉上层设备是否具备快速回连广播能力。

开关一:OTAConfig.isSupportNewRebootWay

是否启用新回连方式,由 OTA 配置在开始升级前决定:

/** OTA 配置 */
declare class OTAConfig {
    static readonly COMMUNICATION_WAY_BLE = 0;
    static readonly COMMUNICATION_WAY_SPP = 1;
    static readonly COMMUNICATION_WAY_USB = 2;
    /** 通讯方式*/
    communicationWay: number;
    /** 是否支持新的回连方式*/
    isSupportNewRebootWay: boolean;
    /** 固件升级文件数据*/
    updateFileData?: Uint8Array;
    toString(): string;
}

Source: libs/jl_ota_2.1.1.d.ts

开关二:OTAWrapperOption.isInnerReconnect

是否由 SDK 内部执行回连,由 OTAWrapper 初始化选项决定。若上层自行处理回连,应返回 false,SDK 只负责回调通知:

const otaWrapperOption: OTAWrapperOption = {
    /**是否需要认证。 在上层已经认证过,就不需要认证。**/
    isUseAuth: () => {
        return this._BluetoothConfigure.isUseAuth
    },
    /**是否需要回连。 在上层进行回连,就不需要内部回连。**/
    isInnerReconnect: () => {
        return true
    },
    // ... sanDevice / connectDevice / disconnectDevice / sendData ...
}
this._OTAWrapper = new OTAWrapper(otaWrapperOption)

Source: README.md

设计意图:isInnerReconnect 与 onNeedReconnect 是一对互补开关。isInnerReconnect = true 表示 SDK 内部会利用 OTAWrapperOption 提供的 connectDevice 等能力自动完成回连;false 则表示上层收到回调后自行执行回连(例如上层有更复杂的设备过滤逻辑时)。无论哪种方式,onNeedReconnect 都会被回调,保证上层始终感知"设备即将重启回连"这一状态。

内部实现机制(OTAImpl)

SDK 内部由 OTAImpl 承载回连状态机,其私有成员与定时器直接对应回连机制的每个环节:

declare class OTAImpl {
    static readonly WAITING_CMD_TIMEOUT: number;
    static readonly WAITING_DEVICE_OFFLINE_TIMEOUT: number;
    static readonly RECONNECT_DEVICE_DELAY = 1000;
    static readonly RECONNECT_DEVICE_TIMEOUT: number;
    private _ReConnectMsg;
    private _OTADeviceBleMac;
    private _ReconnectTimer;
    private _WaitDeviceOffLineTimer;
    // ...
    /** 准备回连设备  */
    private _readyToReconnectDevice;
    private _setReConnectMsg;
    /** 读取设备升级状态  */
    private _queryUpgradeResult;
    /** 进入升级状态  */
    private _enterUpdateMode;
    private _startWaitDeviceOffLineTimeOut;
    private _stopWaitDeviceOffLineTimeOut;
    private _startReConnectDeviceTimeout;
    private _stopReConnectDeviceTimeout;
    private _callbackReConnectDevice;
    // ...
}

Source: libs/jl_ota_2.1.1.d.ts

回连机制内部的几个关键设计点:

  1. RECONNECT_DEVICE_DELAY = 1000:设备断开后并非立即回连,而是等待 1 秒。这是为了给设备留出重启、拉起升级模式广播的时间窗口,避免"设备还没准备好就连接"导致连接失败。
  2. _WaitDeviceOffLineTimer / WAITING_DEVICE_OFFLINE_TIMEOUT:SDK 先等待设备真正离线(断开连接),确认设备进入了重启流程,再进入回连准备阶段。设备离线状态通过上层 onConnectStateDisconnect 同步。
  3. _startReConnectDeviceTimeout / RECONNECT_DEVICE_TIMEOUT:从开始回连到回连成功有一个总超时。超时后 SDK 会回调 onError(ERROR_OTA_RECONNECT_DEVICE_TIMEOUT, ...) 终止升级流程,避免上层无限等待。
  4. _setReConnectMsg 与 setDeviceBLEMac:回连信息(ReConnectMsg)与设备 BLE MAC 在升级过程中被记录,_readyToReconnectDevice 阶段将其组装并通过 _callbackReConnectDevice 触发 onNeedReconnect。
  5. _queryUpgradeResult / _enterUpdateMode:回连成功后,SDK 会继续查询设备升级状态并再次进入升级模式,从断点继续传输固件,而不是从头开始。

整个流程中 SDK 通过 _removeAllTimer 统一清理定时器,保证在 release()、OTA 结束或失败时不会残留定时器导致内存泄漏或重复回调。

核心回连流程

下图描述单备份 OTA 中设备重启回连的完整时序:

sequenceDiagram
    participant App as 上层业务 (OTAWrapper)
    participant SDK as OTAImpl (SDK)
    participant Dev as BLE 设备

    App->>SDK: startOTA(config, callback)
    SDK->>Dev: 传输 BootLoader (UPGRADE_TYPE_CHECK_FILE)
    Dev-->>SDK: 需要重启进入升级模式
    SDK->>SDK: 记录 ReConnectMsg (deviceBleMac / isSupportNewReconnectADV)
    SDK->>App: onNeedReconnect(reConnectMsg)
    App->>App: 仅连接通讯通道 (BLE/SPP) 回连设备
    App->>Dev: 重新建立 BLE 连接
    App->>SDK: onConnectStateSuccess(dev) 同步连接状态
    SDK->>Dev: 查询升级状态 / 再次进入升级模式
    Dev-->>SDK: 从断点继续传输固件
    SDK->>App: onProgress(UPGRADE_TYPE_FIRMWARE, progress)
    SDK->>App: onStopOTA() / onError(...)
flowchart TD
    Start(["设备重启,连接断开"]) --> Offline{"等待设备离线<br/>(WAITING_DEVICE_OFFLINE_TIMEOUT)"}
    Offline -->|"超时未离线"| Err1["onError(OTA失败)"]
    Offline -->|"已离线"| Delay["延迟 1s<br/>(RECONNECT_DEVICE_DELAY=1000)"]
    Delay --> Notify["回调 onNeedReconnect(ReConnectMsg)"]
    Notify --> Choose{"isInnerReconnect?"}
    Choose -->|"true (内部回连)"| Inner["SDK 调用 connectDevice 定向回连"]
    Choose -->|"false (上层回连)"| Outer["上层执行回连<br/>(仅连接通讯通道)"]
    Inner --> Connected{"回连成功?"}
    Outer --> Connected
    Connected -->|"否,且超时"| Err2["onError(ERROR_OTA_RECONNECT_DEVICE_TIMEOUT = -112)"]
    Connected -->|"是"| Resume["查询升级状态,继续传输固件"]
    Resume --> Done["onProgress / onStopOTA"]
    Err1 --> End([结束])
    Err2 --> End
    Done --> End

关键点:回连阶段不重新认证、不重新初始化 RCSP(onNeedReconnect 注释明确"仅连接通讯通道")。连接成功后通过 onConnectStateSuccess 通知 OTAWrapper,SDK 据此恢复升级上下文。

使用示例

示例一:初始化 OTAWrapper 并启用内部回连

在业务层初始化 OTAWrapper 时,通过 isInnerReconnect 决定回连的执行方。true 表示 SDK 内部回连,上层仍需提供 connectDevice 等蓝牙能力:

//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 实现蓝牙发数操作
    }
}
this._OTAWrapper = new OTAWrapper(otaWrapperOption)

Source: README.md

示例二:同步蓝牙连接状态(回连成功的通知通道)

上层蓝牙连接成功/断开/失败时,必须同步给 OTAWrapper。回连成功后正是通过 onConnectStateSuccess 让 SDK 感知"设备已重新连接",从而继续升级:

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

Source: README.md

同样地,扫描结果(onScanFound)与数据推送(onReceiveData)也必须转发给 OTAWrapper,分别用于传统回连方式下的设备发现,以及回连后恢复数据收发(见 README 第三步、第四步的 addScanCallback 与 BleDataHandler.addCallbacks)。

示例三:开始 OTA 并处理回连回调

创建 OTAConfig 时开启新回连方式,并在 OnUpgradeCallback 中实现 onNeedReconnect:

/*--- 开始执行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)

Source: README.md

注意:onNeedReconnect 回调内通常只做一件事——依据 reConnectMsg(尤其是 deviceBleMac)重新连接设备;若 isInnerReconnect() 已返回 true,上层甚至可以只更新 UI 提示"正在回连",实际的连接动作由 SDK 内部完成。

配置选项

配置项位置类型默认/示例说明
isInnerReconnectOTAWrapperOption() => boolean() => true是否由 SDK 内部执行回连;上层自行回连时返回 false
isSupportNewRebootWayOTAConfigbooleantrue是否支持新回连方式(基于 BLE MAC 定向回连)
communicationWayOTAConfignumberOTAConfig.COMMUNICATION_WAY_BLE = 0通讯方式:BLE / SPP / USB;回连需与该通道一致
updateFileDataOTAConfigUint8Array?—固件升级文件数据
RECONNECT_DEVICE_DELAYOTAImpl 常量number1000设备离线后延迟 1 秒再回连,等待设备进入升级模式广播
RECONNECT_DEVICE_TIMEOUTOTAImpl 常量numberSDK 内置回连总超时;超时回调 ERROR_OTA_RECONNECT_DEVICE_TIMEOUT
WAITING_DEVICE_OFFLINE_TIMEOUTOTAImpl 常量numberSDK 内置等待设备真正离线的超时上限
isSupportNewReconnectADVReConnectMsgboolean?—设备是否支持新回连广播(由 SDK 从设备读取,只读)
deviceBleMacReConnectMsgstring?—RCSP 协议上报的 BLE MAC,用于定向回连(只读)

API 参考

onNeedReconnect(reConnectMsg: ReConnectMsg): void

OnUpgradeCallback 中的回连回调。设备完成 BootLoader 传输、即将重启进入升级模式时被调用。

参数:

  • reConnectMsg (ReConnectMsg):回连设备信息,包含 deviceBleMac(RCSP 上报的 BLE MAC)与 isSupportNewReconnectADV(是否支持新回连广播)。

返回值: 无。

注意事项:

  • 回调内仅连接通讯通道(BLE 或 SPP),不要重复执行认证与 RCSP 初始化。
  • 仅用于单备份 OTA。
  • 回连完成后必须通过 OTAWrapper.onConnectStateSuccess(dev) 同步连接状态,SDK 才能继续升级。

Source: libs/jl_ota_2.1.1.d.ts

OTAConfig.isSupportNewRebootWay: boolean

OTAConfig 配置项。置为 true 表示采用新回连方式:SDK 会记录 RCSP 上报的 deviceBleMac 并组装 ReConnectMsg,回连时按 MAC 定向连接,且支持设备的新回连广播。

ReConnectMsg.copy(): ReConnectMsg / ReConnectMsg.toString(): string

  • copy():深拷贝回连信息,供 SDK 内部保存快照使用。
  • toString():调试日志输出回连信息的字符串表示。

OTAImpl 内部方法(SDK 内部使用,供理解机制)

方法作用
_readyToReconnectDevice()准备回连设备:组装 ReConnectMsg、启动回连延迟/超时定时器
_setReConnectMsg(msg)保存回连信息快照(升级过程中由设备信息填充)
setDeviceBLEMac(mac)设置 RCSP 协议上报的设备 BLE MAC,供定向回连使用
_startReConnectDeviceTimeout() / _stopReConnectDeviceTimeout()启动/停止回连总超时守护
_startWaitDeviceOffLineTimeOut() / _stopWaitDeviceOffLineTimeOut()启动/停止"等待设备离线"超时守护
_callbackReConnectDevice(msg)触发 onNeedReconnect 回调分发
_removeAllTimer()清理全部定时器(回连、离线等待、任务超时),防止泄漏

相关错误码(OTAError)

常量值说明
ERROR_OTA_RECONNECT_DEVICE_TIMEOUT-112回连设备超时(RECONNECT_DEVICE_TIMEOUT 到期仍未连上)
ERROR_OTA_USE_CANCEL-113用户取消升级(单备份方案下 cancelOTA() 无效,因此不会出现此码)
ERROR_DEVICE_OFFLINE-33设备离线(回连前若设备长期离线可能触发)
ERROR_OTA_IN_PROGRESS-110OTA 进行中(重复触发回连/重复 startOTA 时可能遇到)

Source: libs/jl_ota_2.1.1.d.ts

失败模式、边界情况与并发

回连超时

RECONNECT_DEVICE_TIMEOUT 到期仍未能建立连接时,SDK 回调 onError(ERROR_OTA_RECONNECT_DEVICE_TIMEOUT = -112)。典型诱因:

  • 设备重启后长时间未进入可发现/可连接状态(固件异常、电量不足);
  • 用户走远导致信号丢失;
  • iOS 系统蓝牙缓存导致定向连接失败(V2.1.1 已针对性修复,见下文版本历史)。

上层应在此错误回调中提示用户"回连失败,请手动重新连接后重试升级"。

等待设备离线超时

设备在预期时间内未断开(WAITING_DEVICE_OFFLINE_TIMEOUT 到期),说明设备未按预期重启,SDK 走失败分支。这是对"假死"状态的保护:避免设备既没断开又没回连时流程卡死。

单备份方案下取消无效

cancelOTA() 在单备份方案下无效(类型注释明确说明),因此单备份升级一旦进入回连阶段,用户无法中途取消,只能等待成功或失败。业务层 UI 上应避免在回连阶段展示"取消升级"操作。

并发与状态一致性

  • 回连期间 OTAImpl 持有 _ReConnectMsg 与 _OTADeviceBleMac,升级流程串行执行;重复调用 startOTA() 会因 _checkIsNotOTA 校验(ERROR_OTA_IN_PROGRESS)被拒绝。
  • 所有定时器统一由 _removeAllTimer 清理:release()、onDeviceDisconnect() 失败路径、OTA 结束时都会调用,防止回连定时器在 OTA 结束后仍触发回调造成竞态。
  • 上层回连成功后必须尽快调用 onConnectStateSuccess,SDK 的回连超时倒计时不因上层动作而暂停,若上层回连耗时超过 RECONNECT_DEVICE_TIMEOUT,即使连接已建立也可能收到超时错误——因此"仅连接通讯通道"的要求是为了让回连动作尽量快。

性能与运维注意事项

  • 回连延迟是有意的:RECONNECT_DEVICE_DELAY = 1000(1 秒)用于等待设备重启并进入升级模式广播。不要在上层自行缩短该等待,否则设备未就绪时连接会立即失败,反而触发超时错误。
  • 定向回连优于全量扫描:启用 isSupportNewRebootWay 后,回连利用 ReConnectMsg.deviceBleMac 定向连接,避免重新发起全量 BLE 扫描,既快又省电,对 iOS 系统蓝牙队列也更友好。
  • iOS 16 兼容性:V2.1.1 版本历史明确记录"修复 iOS16 单备份升级回连搜不到设备问题"(见 README.md 版本历史)。使用自动回连时应确保小程序端使用 SDK 2.1.1 及以上版本。
  • 日志排查:SDK 提供详细日志输出,可通过日志观察"回连开始 → 连接成功 → 恢复传输"的时序;小程序端可用 vConsole 查看实时日志。回连异常时重点核对:是否收到 onNeedReconnect、onConnectStateSuccess 是否在超时前同步、ReConnectMsg.deviceBleMac 是否有值。
  • 超时参数不可运行时调整:RECONNECT_DEVICE_TIMEOUT、WAITING_DEVICE_OFFLINE_TIMEOUT 是 OTAImpl 的静态常量,由 SDK 内置,上层无法修改;若业务需要更长回连窗口,应通过 isInnerReconnect: () => false 接管回连并自行控制超时。

扩展点

  1. 上层接管回连(isInnerReconnect = false):当业务层有特殊的设备过滤、多设备选择或需要向用户展示回连进度 UI 时,可关闭内部回连,在 onNeedReconnect 回调中自行完成"仅连接通讯通道"的动作,再通过 onConnectStateSuccess 交还控制权。
  2. 新回连方式(isSupportNewRebootWay = true):设备侧若支持新回连广播(isSupportNewReconnectADV),回连更快更稳;该能力由固件与 SDK 共同决定,上层只需在创建 OTAConfig 时开启。
  3. 回调扩展(OnUpgradeCallback):onNeedReconnect 与 onProgress/onError 等回调配合,可实现完整的升级状态机展示(校验文件 → 回连 → 传输固件 → 结束),业务层可在这些回调之间自由插入 UI 与埋点逻辑。

测试覆盖观察

仓库为 SDK 集成示例项目,未发现针对回连机制的独立单元测试文件。可验证的保障来自:

  • 类型定义(libs/jl_ota_2.1.1.d.ts)对回连接口的契约约束(回调时机、仅连接通讯通道、单备份限定);
  • README 集成示例(初始化、状态同步、回调实现)构成的上层集成路径;
  • 版本历史中的回归记录(V2.1.1 修复 iOS16 回连搜不到设备)。

实际回归测试建议:在真机上模拟"传输 BootLoader 后断电重启"场景,验证 onNeedReconnect 触发、onConnectStateSuccess 同步与续传进度,并覆盖"回连超时 → onError(-112)"的失败路径。

Related Links

  • README.md — OTAWrapper 初始化与回调实现(本页示例的完整上下文)
  • libs/jl_ota_2.1.1.d.ts — 回连相关类型定义
  • libs/jl_ota_2.1.1.js — SDK 运行时实现
  • libs/jl_rcsp_ota_2.1.1.js — RCSP OTA 协议(BLE MAC 上报来源)
  • README_en.md — Auto Reconnect 特性说明(英文)
  • 相关目录页:OTA 升级主流程(单备份/双备份)、OTAWrapper 初始化、认证机制
Prev
BLE 数据发送与 MTU 管理