问题排查与技术支持
本页汇总 HarmonyOS-JL_OTA 杰理 OTA SDK 的排障方法、错误码体系、日志定位技巧以及官方技术支持渠道,帮助开发者快速定位并解决 BLE/SPP 固件升级过程中的问题。
Purpose and Scope
本页是问题排查与技术支持的工程参考,覆盖以下内容:
- SDK 的日志体系与 Logcat 调试方法(
Log.d/Log.e、TAG 约定、蓝牙状态事件日志) BluetoothErrorConstant错误码全表及每个错误码的触发场景、可能原因与排查建议- 基于源码的常见问题排查路径(扫描、连接、MTU、特征订阅、OTA 升级)
- 版本兼容性与已知问题(来自版本历史)
- 官方支持渠道(GitHub Issues、文档中心、杰理官网)与问题上报规范
本页不涵盖的内容(请参考对应页面):
- OTA 升级流程本身的完整实现与 RCSP 协议细节——见 OTA 升级与 RCSP 协议相关页面
- 蓝牙连接/扫描 API 的完整用法——见蓝牙连接与扫描相关页面
- 依赖库的接入与工程配置——见快速开始与配置说明相关页面
Overview
HarmonyOS-JL_OTA 是珠海市杰理科技股份有限公司为杰理蓝牙产品(AC707N、AC703N、AC701N、AC697N、AC696N、AC695N 等)提供的 RCSP OTA 固件升级 SDK,支持 BLE 与 SPP 两种传输通道。由于 OTA 升级是一个跨设备、跨协议、跨系统权限的长链路过程(应用层 → 蓝牙栈 → 设备端固件),任何一个环节异常都可能导致升级失败,因此系统化的排查能力是 SDK 可用性的关键一环。
该 SDK 从三个层面支撑问题排查:
- 分层日志:
BleImpl等核心类通过tool/log/Log输出带 TAG 的分级日志,可在 DevEco Studio 的 Logcat 中实时观察连接状态与数据交互。 - 结构化错误码:
BluetoothErrorConstant枚举将蓝牙各阶段(适配器初始化、扫描、连接、服务发现、特征订阅、MTU 协商)的失败统一编码,业务层可根据错误码精确分流处理。 - 社区支持闭环:GitHub Issues 提供问题反馈入口,官方文档中心提供《测试调试》等排障专题文档。
正确使用这三层能力,可以将"OTA 升级失败"这类模糊问题快速拆解为"错误码 + 日志时序 + 设备行为"的具体证据,从而定位到确切的失败环节。
Architecture
SDK 的问题排查体系由"日志采集层 → 错误码层 → 应用层处理 → 支持渠道"四层构成:
flowchart TD
subgraph sg_App["应用层 (Demo / 集成方)"]
App["HarmonyOS 应用"]
UI["升级界面 / 业务逻辑"]
end
subgraph sg_SDK["JL OTA SDK (HAR 依赖)"]
BleImpl["BleImpl (BLE 扫描/连接/收发)"]
SendHandler["BleSendDataHandler (数据分包发送)"]
LogTool["tool/log/Log (分级日志)"]
ErrConst["BluetoothErrorConstant (错误码)"]
RCSP["JL_RCSP / JL_Auth / JL_OTA 核心库"]
end
subgraph sg_OS["HarmonyOS 系统层"]
ConnectivityKit["@kit.ConnectivityKit (ble/access/connection)"]
Logcat["DevEco Studio Logcat"]
end
subgraph sg_Device["设备端"]
Target["杰理蓝牙芯片 (RCSP OTA 固件)"]
end
subgraph sg_Support["官方支持"]
Issues["GitHub Issues"]
DocCenter["杰理文档中心 (测试调试)"]
end
App --> BleImpl
BleImpl --> SendHandler
BleImpl --> LogTool
BleImpl --> ErrConst
BleImpl --> ConnectivityKit
SendHandler --> ConnectivityKit
ConnectivityKit --> Target
LogTool --> Logcat
ErrConst --> UI
UI -->|"问题上报"| Issues
DocCenter -->|"排障指导"| App
各层职责与设计意图:
BleImpl(bluetooth/ble/BleImpl.ets):BLE 通道的统一实现类,实现IBleScan与IBleConnect两个接口。它是日志与错误码的主要产出者:内部维护waitDisconnectDevices、callbacksMap等状态,任何异常路径都会先写日志再向上抛出结构化错误码。设计上日志先行、错误码并行,确保开发者既能看"发生了什么",也能拿到"程序可处理的错误标识"。BluetoothErrorConstant:错误码的唯一事实来源。错误码按阶段分段编号(1xxxx 为适配器/连接层,2xxxx 为 MTU/服务/特征层),业务层只需 switch 该枚举即可分类处理,避免散落魔法数字。tool/log/Log:封装的分级日志工具。核心类统一声明模块级TAG(如BleImpl的TAG = 'BleImpl'),Logcat 中可按 TAG 过滤,快速聚焦某个模块的运行轨迹。@kit.ConnectivityKit:HarmonyOS 系统蓝牙能力(ble、access、connection)。系统回调中的BusinessError会被捕获并转为Log.e输出errCode与errMessage,这是连接失败时的第一手证据。
关于 BleImpl 错误处理与日志调用的源码依据,详见下文"主内容"与"Usage Examples"。
日志体系与调试方法
分级日志与 TAG 约定
SDK 的核心类通过 tool/log/Log 工具输出日志,且每个类声明独立 TAG。以 BleImpl 为例:
const TAG: string = 'BleImpl'
export class BleImpl implements IBleScan, IBleConnect {
// ...
on(type: BaseConnectEventTypeConstant.CONNECT_STATE_CHANGE, callback: Callback<ConnectStateInfo<BleDevice>>): void;
// ...
}
Source: BleImpl.ets
设计意图:TAG 是日志过滤的"命名空间"。BleImpl 同时承担扫描、连接、收发三类职责,若不加 TAG,Logcat 中多模块日志混在一起将难以追溯。排查时可直接在 Logcat 中按 BleImpl 过滤,按时间顺序回放该模块的完整操作轨迹。
日志调用贯穿关键路径:
- 正常路径用
Log.d(debug):如Log.d(TAG, "_startScan")标记扫描开始。 - 异常路径用
Log.e(error):如蓝牙状态变化、发送数据找不到设备/特征时输出错误日志。
private _startScan() {
Log.d(TAG, "_startScan")
try {
try {
this._onBluetoothDeviceFound();
} catch (e) {
Log.d(TAG, "catch _onBluetoothDeviceFound")
}
let scanOptions: ble.ScanOptions = {
interval: 500,
dutyMode: ble.ScanDuty.SCAN_MODE_BALANCED,
matchMode: ble.MatchMode.MATCH_MODE_AGGRESSIVE,
};
ble.startBLEScan(null, scanOptions);
this.mIsScanning = true
this._onScanStart()
}
// ...
}
Source: BleImpl.ets
系统回调错误的上报模式
BleImpl 对 HarmonyOS 系统回调(BusinessError)采用统一的捕获模式:try/catch 包裹 + (err as BusinessError).code/.message 写入 Log.e。这一模式保证系统层异常不会静默丢失:
this.waitDisconnectDevices.forEach(deviceId => {
try {
let device: ble.GattClientDevice = ble.createGattClientDevice(deviceId);
device.disconnect();
device.close();
} catch (err) {
Log.e(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' +
(err as BusinessError).message);
}
})
Source: BleImpl.ets
排查时若看到 Log.e 中出现 errCode / errMessage,即为系统蓝牙栈直接报错(如权限不足、设备不可达),应优先核对系统蓝牙状态与权限配置。
蓝牙状态事件日志
BleImpl 构造函数中注册了系统蓝牙开关状态监听,并将状态变化写入日志;同时体现了断电自动清理、来电自动重连的恢复策略:
access.on('stateChange', (data) => {
let btStateMessage = '';
switch (data) {
case access.BluetoothState.STATE_OFF:
btStateMessage += 'STATE_OFF';
this.isAccessOn = false
this._connectedDeviceArray.forEach(device => {
this.disconnect(device)
})
break;
case access.BluetoothState.STATE_ON:
btStateMessage += 'STATE_ON';
this.isAccessOn = true
this.waitDisconnectDevices.forEach(deviceId => {
// 重建 GattClientDevice 并断开清理
})
this.waitDisconnectDevices = []
break;
}
Log.e(TAG, `bluetooth status:${btStateMessage}`);
})
Source: BleImpl.ets
排查要点:升级过程中若日志出现 bluetooth status:STATE_OFF,说明系统蓝牙被关闭(用户手动关闭、系统省电策略等),OTA 必然中断。此时应提示用户重新开启蓝牙,SDK 会在 STATE_ON 后对 waitDisconnectDevices 中的设备执行清理,等待上层重新连接。
DevEco Studio Logcat 使用流程
- 连接真机(OTA 涉及 BLE 硬件,模拟器无法验证),在 DevEco Studio 中打开 Logcat 面板。
- 过滤条件输入
BleImpl(或对应模块 TAG),必要时叠加关键字如errCode、sendData、bluetooth status。 - 按"复现步骤 → 观察日志 → 对照错误码表"的顺序记录现场信息,再提交 Issues 或咨询官方支持。
错误码体系(BluetoothErrorConstant)
错误码定义在 bluetooth/base/BluetoothErrorConstant.ets,是蓝牙链路全部异常的结构化编码。源码原文:
export enum BluetoothErrorConstant {
//蓝牙错误
ERROR_NONE = 0, //ok | 正常 |adapter
ERROR_CONNECTED = -1, // already connect | 已连接 |
ERROR_ADAPTER_NOT_INIT = 10000, // not init | 未初始化蓝牙适配器 |
ERROR_ADAPTER_NOT_AVAILABLE = 10001, // not available | 当前蓝牙适配器不可用 |
ERROR_NO_DEV = 10002, // no device | 没有找到指定设备 |
ERROR_CONNECTION_FAIL = 10003, // connection fail | 连接失败 |
ERROR_NO_SERVICE = 10004, // no service | 没有找到指定服务 |
ERROR_NO_CHARACTERISTIC = 10005, // no characteristic | 没有找到指定特征 |
ERROR_NO_CONNECTION = 10006, // no connection | 当前连接已断开 |
ERROR_PROPERTY_NOT_SUPPORT = 10007, // property not support | 当前特征不支持此操作 |
ERROR_SYSTEM_ERROR = 10008, // system error | 其余所有系统上报的异常 |
ERROR_SYSTEM_NOT_SUPPORT = 10009, // system not support | Android 系统特有,系统版本低于 4.3 不支持 BLE |
ERROR_OPERATE_TIME_OUT = 10012, // operate time out | 连接超时 |
ERROR_INVALID_DATA = 10013, // invalid_data | 连接 deviceId 为空或者是格式不正确 |
ERROR_INIT_MTU_FAIL = 20000, // init mtu fail | 初始化MTU失败 |
ERROR_GET_SERVICE_FAIL = 20001, // get service fail | 获取服务失败 |
ERROR_NOTIFY_NECESSARY_CHARACTERISTIC_FAIL = 20002, // notify necessary characteristic fail | 使能必须的特征失败 |
ERROR_IS_CONNECTING = 20003, // is connecting | 正在连接 |
}
Source: BluetoothErrorConstant.ets
错误码分段规则与排查建议
错误码按链路阶段分段,便于快速定位问题发生的环节:
| 错误码 | 枚举名 | 触发环节 | 可能原因 | 排查建议 |
|---|---|---|---|---|
| 0 | ERROR_NONE | 全局 | 正常 | 无需处理 |
| -1 | ERROR_CONNECTED | 连接 | 设备已连接,重复发起连接 | 先断开或复用现有连接 |
| 10000 | ERROR_ADAPTER_NOT_INIT | 适配器 | 蓝牙适配器未初始化 | 检查是否先调用初始化流程 |
| 10001 | ERROR_ADAPTER_NOT_AVAILABLE | 适配器 | 系统蓝牙关闭或不可用 | 确认系统蓝牙已开启;观察 bluetooth status:STATE_OFF 日志 |
| 10002 | ERROR_NO_DEV | 扫描/连接 | 未找到指定设备 | 确认设备已进入广播状态、扫描过滤条件正确 |
| 10003 | ERROR_CONNECTION_FAIL | 连接 | GATT 连接建立失败 | 查看 Logcat 中系统 errCode/errMessage;确认设备未离开射频范围 |
| 10004 | ERROR_NO_SERVICE | 服务发现 | 未找到目标 GATT Service | 确认设备固件支持 RCSP OTA 服务 UUID |
| 10005 | ERROR_NO_CHARACTERISTIC | 特征发现 | 未找到指定 Characteristic | 确认固件版本与 SDK 版本匹配 |
| 10006 | ERROR_NO_CONNECTION | 收发 | 当前连接已断开 | 触发重连流程;检查设备是否关机/断电 |
| 10007 | ERROR_PROPERTY_NOT_SUPPORT | 特征操作 | 特征不支持 write/notify 属性 | 核对设备端特征属性配置 |
| 10008 | ERROR_SYSTEM_ERROR | 全局 | 系统上报的其他异常 | 以 Logcat 中 errMessage 为准 |
| 10009 | ERROR_SYSTEM_NOT_SUPPORT | 适配器 | 系统版本过旧不支持 BLE | 升级 HarmonyOS 版本(本项目要求 5.0+) |
| 10012 | ERROR_OPERATE_TIME_OUT | 连接 | 连接/操作超时 | 检查设备是否可被发现、连接参数是否合理 |
| 10013 | ERROR_INVALID_DATA | 连接 | deviceId 为空或格式错误 | 校验传入的设备地址(MAC)格式 |
| 20000 | ERROR_INIT_MTU_FAIL | MTU | MTU 协商失败 | 检查设备端 MTU 支持范围;重新连接后重试 |
| 20001 | ERROR_GET_SERVICE_FAIL | 服务发现 | 获取服务列表失败 | 查看系统 errCode;确认设备固件正常运行 |
| 20002 | ERROR_NOTIFY_NECESSARY_CHARACTERISTIC_FAIL | 特征订阅 | 使能必要特征的通知失败 | OTA 数据通道依赖 notify,确认固件支持并已正确使能 |
| 20003 | ERROR_IS_CONNECTING | 连接 | 正在连接中,重复操作 | 等待当前连接流程结束或先取消 |
设计意图:将错误码分段(1xxxx / 2xxxx)而非平铺,是为了让业务层在 switch 时能按"阶段"批量处理——例如 20000~20002 都发生在连接建立后的服务/MTU 协商阶段,可统一走"断开重连"策略;而 10000~10001 属于环境问题,应引导用户检查系统设置而非重试。
核心排查流程
面对"OTA 升级失败"类问题,推荐按以下流程系统化收敛问题范围:
flowchart TD
Start([发现问题]) --> Step1["复现并采集日志<br/>(Logcat 按 TAG 过滤)"]
Step1 --> Step2{"存在 errCode/<br/>errMessage?"}
Step2 -->|"是"| Step3["对照 BluetoothErrorConstant<br/>定位失败阶段"]
Step2 -->|"否"| Step4["按日志时序回放<br/>扫描→连接→MTU→服务→特征→收发"]
Step3 --> Step5{"属于环境问题?<br/>(1xxxx 段)"}
Step5 -->|"是"| Step6["检查系统蓝牙/权限/设备广播状态"]
Step5 -->|"否"| Step7["按阶段重试或断开重连<br/>(2xxxx 段)"]
Step4 --> Step8{"日志是否完整?"}
Step8 -->|"是"| Step9["检查设备端固件行为<br/>与 SDK 版本匹配"]
Step8 -->|"否"| Step10["补充日志埋点/复现路径"]
Step6 --> Res{"问题解决?"}
Step7 --> Res
Step9 --> Res
Step10 --> Res
Res -->|"是"| Done([完成])
Res -->|"否"| Esc["升级到官方支持<br/>(附错误码+日志+复现步骤)"]
Esc --> Done
各阶段排查要点
- 采集现场:按上文 Logcat 流程复现问题,务必同时记录 SDK 日志(
BleImpl等 TAG)与系统日志,二者缺一不可——SDK 日志说明 SDK 侧行为,系统errCode说明 HarmonyOS 蓝牙栈行为。 - 映射错误码:用
BluetoothErrorConstant将日志中的异常映射到具体阶段。1xxxx 段多为环境/参数问题(权限、适配器、超时),2xxxx 段多为链路协商问题(MTU、服务、特征)。 - 回放时序:OTA 升级是严格顺序链路(扫描 → 连接 → MTU → 服务发现 → 特征订阅 → 数据收发),日志中出现跳步或缺失即说明该环节失败。例如
sendData报device is not connected说明上层状态与底层连接状态不一致。 - 边界分流:区分"环境问题"(蓝牙没开、设备没广播、权限没授)与"链路问题"(MTU 协商失败、特征属性不支持)。环境问题重试无效,链路问题通常断开重连即可恢复。
常见问题场景
场景一:扫描不到目标设备
- 现象:
startScan后设备列表为空,或目标设备未出现。 - 证据链:Logcat 过滤
BleImpl,观察_startScan、bluetooth status日志;确认系统蓝牙处于STATE_ON。 - 原因与对策:
- 系统蓝牙关闭 → 开启蓝牙后 SDK 自动清理
waitDisconnectDevices并恢复; - 设备未进入广播/配对模式 → 参考设备厂商说明进入可发现状态;
- 扫描参数不当 → 默认
scanOptions为interval: 500、SCAN_MODE_BALANCED、MATCH_MODE_AGGRESSIVE,可通过setScanSettingConfigure调整。
- 系统蓝牙关闭 → 开启蓝牙后 SDK 自动清理
场景二:连接失败 / 连接超时
- 现象:返回
ERROR_CONNECTION_FAIL(10003) 或ERROR_OPERATE_TIME_OUT(10012)。 - 证据链:查看 Logcat 中
(err as BusinessError).code/.message,这是系统蓝牙栈的直接反馈。 - 原因与对策:
- 设备不在射频范围或已连接其他主机 → 靠近设备并断开其他连接;
deviceId为空/格式错误 → 触发ERROR_INVALID_DATA(10013),校验 MAC 地址格式;- 正在连接中重复操作 → 触发
ERROR_IS_CONNECTING(20003),等待当前流程结束。
场景三:OTA 升级中数据收发中断
- 现象:升级进度停滞或失败,日志出现
ERROR_NO_CONNECTION(10006) 或sendData device is not connected。 - 证据链:
sendData(bluetoothDevice: BleDevice, serviceId: string, characteristicId: string, data: Uint8Array) {
const devInfo = this.getConnectedDevInfo(bluetoothDevice)
if (devInfo) {
const characteristic = devInfo.writeCharacteristics.find(item => item.serviceUuid === serviceId &&
item.characteristicUuid === characteristicId)
if (characteristic) {
this.bleSendDataHandler.sendData(devInfo, characteristic, data)
} else {
Log.e(TAG, "sendData device is not find write characteristic")
}
} else {
Log.e(TAG, "sendData device is not connected")
}
}
Source: BleImpl.ets
- 原因与对策:
device is not connected:连接已断(设备断电、系统蓝牙关闭、超出范围),需走重连流程;STATE_OFF日志可佐证系统级断开;device is not find write characteristic:服务/特征发现不完整或固件不支持写特征,返回ERROR_NO_SERVICE(10004) /ERROR_NO_CHARACTERISTIC(10005),核对固件与 SDK 版本;- MTU 过小导致分包异常:升级前应完成 MTU 协商,
ERROR_INIT_MTU_FAIL(20000) 时重连重试。
场景四:升级功能与版本兼容性
根据版本历史,排查时先确认 SDK 版本是否满足功能要求:
| 日期 | 版本 | 发布内容 |
|---|---|---|
| 2024/12/12 | Jieli_OTA_SDK_HarmonyOS_V1.0.1 | 修复功能:兼容支持 SPP 升级方式 |
| 2024/09/03 | Jieli_OTA_SDK_HarmonyOS_V1.0.0 | 增加功能:OTA 升级 |
Source: README.md
- 使用 SPP 升级必须升级到 V1.0.1 及以上;
- 升级异常时核对 Demo 引用的
JL_Auth/JL_OTA/JL_RCSP三个 HAR 的版本号是否一致(oh-package.json5中的file:./lib/xxx.har依赖)。
Usage Examples
以下示例均提取自仓库源码,展示如何在实际代码中落地"日志 + 错误码 + 事件订阅"的排障模式。
示例一:统一错误处理(try/catch + BusinessError)
系统蓝牙回调异常时,将 errCode 与 errMessage 一并写入日志,避免异常被静默吞掉:
} catch (err) {
Log.e(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' +
(err as BusinessError).message);
}
Source: BleImpl.ets
示例二:事件订阅与退订(callbacksMap)
BleImpl 用 callbacksMap: Map<string, Array<Callback>> 管理事件回调,支持按类型订阅多个回调、按引用精确退订、或清空某类型全部回调。排查"事件未触发"问题时,先确认订阅已成功注册:
on(type: ScanEventType | BleConnectEventType,
callback: Callback<ScanStateInfo, void> | Callback<BleDevice[], void> | Callback<MTUInfo, void> | Callback<ConnectStateInfo<BleDevice>, void>
| Callback<BLECharacteristicInfo, void>
): void {
let typeCallbackArray = this.callbacksMap.get(type)
if (typeCallbackArray == undefined) {
typeCallbackArray = new Array()
}
typeCallbackArray.push(callback)
this.callbacksMap.set(type, typeCallbackArray)
}
off(type: ScanEventType | BleConnectEventType,
callback?: ... | undefined
): void {
let typeCallbackArray = this.callbacksMap.get(type)
if (typeCallbackArray == undefined) {
return;
}
if (callback == undefined) { //清除该type类型的所有回调
typeCallbackArray = new Array()
} else {
const index = typeCallbackArray.indexOf(callback)
if (index > -1) {
typeCallbackArray.splice(index, 1)
}
}
this.callbacksMap.set(type, typeCallbackArray)
}
Source: BleImpl.ets
排障提示:若回调未触发,检查 ① 是否在 on 之后才发起扫描/连接;② 事件类型常量(ScanEventType.SCAN_DEVICE_FIND、BleConnectEventTypeConstant.CONNECT_MTU_CHANGE 等)是否匹配;③ 是否误调用了 off(type)(不带 callback 会清空该类型全部回调)。
示例三:错误码枚举的使用模式
业务层可直接引用 BluetoothErrorConstant 进行分支处理,例如根据错误码决定"重试 / 引导用户 / 上报":
import { BluetoothErrorConstant } from '../base/BluetoothErrorConstant';
// 业务侧伪流程(错误码分流示意)
if (errCode === BluetoothErrorConstant.ERROR_ADAPTER_NOT_AVAILABLE) {
// 引导用户打开系统蓝牙
} else if (errCode === BluetoothErrorConstant.ERROR_OPERATE_TIME_OUT) {
// 提示重试
} else if (errCode >= BluetoothErrorConstant.ERROR_INIT_MTU_FAIL) {
// 2xxxx 段:链路协商类错误,走断开重连
}
Source: BluetoothErrorConstant.ets
API Reference
enum BluetoothErrorConstant
蓝牙链路统一错误码枚举,定义于 BluetoothErrorConstant.ets。
成员取值与含义:
| 成员 | 值 | 含义 |
|---|---|---|
ERROR_NONE | 0 | 正常 |
ERROR_CONNECTED | -1 | 已连接 |
ERROR_ADAPTER_NOT_INIT | 10000 | 未初始化蓝牙适配器 |
ERROR_ADAPTER_NOT_AVAILABLE | 10001 | 当前蓝牙适配器不可用 |
ERROR_NO_DEV | 10002 | 没有找到指定设备 |
ERROR_CONNECTION_FAIL | 10003 | 连接失败 |
ERROR_NO_SERVICE | 10004 | 没有找到指定服务 |
ERROR_NO_CHARACTERISTIC | 10005 | 没有找到指定特征 |
ERROR_NO_CONNECTION | 10006 | 当前连接已断开 |
ERROR_PROPERTY_NOT_SUPPORT | 10007 | 当前特征不支持此操作 |
ERROR_SYSTEM_ERROR | 10008 | 其余所有系统上报的异常 |
ERROR_SYSTEM_NOT_SUPPORT | 10009 | 系统版本过低不支持 BLE |
ERROR_OPERATE_TIME_OUT | 10012 | 连接超时 |
ERROR_INVALID_DATA | 10013 | 连接 deviceId 为空或格式不正确 |
ERROR_INIT_MTU_FAIL | 20000 | 初始化 MTU 失败 |
ERROR_GET_SERVICE_FAIL | 20001 | 获取服务失败 |
ERROR_NOTIFY_NECESSARY_CHARACTERISTIC_FAIL | 20002 | 使能必须的特征失败 |
ERROR_IS_CONNECTING | 20003 | 正在连接 |
设计意图:枚举注释中同时保留了英文与中文语义(如 // not init | 未初始化蓝牙适配器 |),保证跨团队沟通(硬件、固件、App 三方)时术语一致。
BleImpl 关键排障相关 API
| 方法/属性 | 说明 | 排障价值 |
|---|---|---|
waitDisconnectDevices: string[] | 等待断开连接的设备列表 | STATE_OFF 时记录异常断开设备,STATE_ON 时清理 |
isScanning(): boolean | 是否正在扫描 | 排查扫描状态是否被错误占用 |
getScanSettingConfigure() | 获取扫描配置 | 核对扫描超时等参数 |
on/off(type, callback) | 事件订阅/退订 | 确认回调注册状态 |
sendData(device, serviceId, characteristicId, data) | 向设备写数据 | 日志中 not connected / not find write characteristic 定位收发故障 |
Source: BleImpl.ets
Configuration Options(运行环境与依赖配置)
排查问题前,先核对运行环境是否符合 SDK 要求(配置不满足时优先表现为环境类错误码 10000/10001/10009):
| 配置项 | 要求/默认 | 说明 |
|---|---|---|
| 操作系统 | HarmonyOS 5.0+ | 支持 BLE 功能;低于 5.0 可能触发 ERROR_SYSTEM_NOT_SUPPORT |
| 硬件平台 | 支持 RCSP OTA 的杰理 SDK | AC707N、AC703N、AC701N、AC697N、AC696N、AC695N 等 |
| 开发平台 | DevEco Studio(建议最新版) | 提供 Logcat 等调试工具 |
| 语言 | ArkTS | SDK 提供完整 ArkTS API |
jl-ota | file:./lib/JL_OTA_x.x.x-release.har | OTA 升级核心库 |
jl-rcsp | file:./lib/JL_RCSP_x.x.x-release.har | RCSP 协议库 |
jl-auth | file:./lib/JL_Auth_x.x.x-release.har | RCSP 认证库 |
Source: README.md
三个 HAR 版本号应保持一致(如均为 1.0.1),混用版本可能导致服务/特征发现阶段出现 20001/20002 类错误。
Failure Modes、Edge Cases 与并发注意事项
系统蓝牙关闭(STATE_OFF)
BleImpl 监听 access.on('stateChange'):蓝牙关闭时遍历 _connectedDeviceArray 主动断开所有设备;蓝牙重新开启时,对 waitDisconnectDevices 中的设备逐一重建 GattClientDevice 执行 disconnect() + close() 清理,再清空该队列。注意:STATE_ON 后 SDK 只做资源清理,不会自动重连业务连接——上层需根据 CONNECT_STATE_CHANGE 事件触发重连。
并发注意:waitDisconnectDevices 的读写与 stateChange 回调处于同一线程模型中,但若上层在 STATE_ON 清理过程中再次发起 disconnect(),可能因设备已 close 抛出 BusinessError——这正是代码中用 try/catch 包裹的原因。
重复操作保护
- 扫描:
mIsScanning标志位防止重复启动扫描,startScan在扫描中调用时转为refreshScan(清空设备列表并重新计时),避免扫描定时器叠加。 - 连接:
ERROR_IS_CONNECTING(20003) 表示连接流程进行中,业务层应在收到CONNECT_STATE_CHANGE之前避免重复发起连接。 - 回调管理:
off(type)不带 callback 会清空该类型全部回调,属于"全量退订"语义;若只想退订单个回调,必须传入原 callback 引用(基于indexOf+splice),否则会造成回调泄漏或误删其他监听者。
数据收发的一致性边界
sendData 依赖 getConnectedDevInfo 与 writeCharacteristics 查找结果:设备已断开时日志输出 device is not connected;特征未找到时输出 device is not find write characteristic。这两种情况说明上层业务状态与底层连接状态出现不一致,通常是断开事件尚未上抛、或服务发现不完整所致。排查时应优先核对 CONNECT_STATE_CHANGE 事件的处理是否及时、MTU/服务协商是否在升级前完成。
边界值
ERROR_INVALID_DATA(10013):deviceId为空或格式不正确时触发,属于参数校验层防御,排查时先确认地址来源。ERROR_SYSTEM_NOT_SUPPORT(10009):注释明确为"Android 系统特有"的历史兼容项,在 HarmonyOS 上一般不会触发,但枚举保留以兼容跨平台代码路径。
官方支持渠道
问题经上述流程仍无法解决时,按以下渠道获取官方支持:
| 平台 | 链接 | 用途 |
|---|---|---|
| GitHub Issues | 问题反馈 | 提交 bug 报告、功能建议,官方活跃维护 |
| 在线文档中心 | 杰理OTA外接库开发文档(HarmonyOS) | 含《测试调试》专题排障文档、版本发布记录 |
| 官方网站 | 杰理科技 | 产品与技术信息 |
| SDK 版本历史 | 版本历史 | 确认已知问题与修复版本 |
Source: README.md
问题上报规范
提交 GitHub Issues 时建议附带以下信息,可显著提升处理效率:
- 环境:HarmonyOS 版本(≥5.0)、DevEco Studio 版本、手机型号、杰理芯片型号(如 AC697N);
- 版本:
JL_Auth/JL_OTA/JL_RCSP三个 HAR 的版本号; - 复现步骤:从添加升级文件到失败的完整操作序列;
- 日志:Logcat 中按
BleImplTAG 过滤的完整日志(含errCode/errMessage、bluetooth status); - 错误码:
BluetoothErrorConstant中命中的错误码及出现阶段。
Related Links
- README(项目总览与快速开始)
- README_en(英文版说明)
- BluetoothErrorConstant.ets(错误码定义)
- BleImpl.ets(BLE 实现与日志/错误处理)
- 蓝牙连接与扫描 API 的完整用法,见"蓝牙连接与扫描"页面
- OTA 升级流程与 RCSP 协议实现,见"OTA 升级"页面
- 依赖库接入与工程配置,见"配置说明"页面