Skip to Content
硬件接入概念底层传输插件

底层传输插件(Low-level Transport Plugin)

仅在 WebUSB / React Native BLE / 官方原生适配器无法满足需求时使用。你需要自管原生 BLE 生命周期和有序收发,维护成本更高。

注意: lowlevel 环境和 LowlevelTransportSharedPlugin 仅用于 BLE(蓝牙) 通信。对于 Node.js/CLI 环境下的 USB 通信,请使用 NodeUsbTransport(env 为 node-usb)—— 它通过 libusb 直接处理协议编解码和 USB I/O,不需要插件。

我们的蓝牙 SDK 基于 React Native。如果你使用 Swift/Kotlin/Flutter 等非 RN 技术栈,引入 RN 依赖可能不合适。可通过 LowlevelTransportSharedPlugin 自行适配底层传输,负责”连接/断开/收发数据”协议。

快速参考

OneKey BLE UUID

用途UUID
服务00000001-0000-1000-8000-00805f9b34fb
写入特征00000002-0000-1000-8000-00805f9b34fb
通知特征00000003-0000-1000-8000-00805f9b34fb

Protocol V1 BLE 头部数据示例

以下帧头仅适用于 Protocol V1,不能用于解析 Protocol V2 通知。

原始数据: 3F 23 23 00 02 00 00 00 0A 12 08 ... │ │ │ │ │ │ │ └─ Protobuf 载荷开始 │ │ │ │ │ └────────┴─ 载荷长度: 0x0000000A = 10 字节 │ │ │ └──┴─ 消息类型: 0x0002 └──┴──┴─ Magic: 0x3F 0x23 0x23 (固定标识)

检测头部包:前 3 字节为 3F 23 23

原生示例(均基于低层插件):

LowlevelTransportSharedPlugin 接口

import type { OneKeyDeviceInfoBase } from '@onekeyfe/hd-transport'; export type LowLevelDevice = OneKeyDeviceInfoBase & { id: string; name: string }; export type LowlevelTransportSharedPlugin = { enumerate: () => Promise<LowLevelDevice[]>; send: (uuid: string, data: string, options?: { withoutResponse?: boolean }) => Promise<void>; receive: (uuid?: string) => Promise<string>; connect: (uuid: string) => Promise<void>; disconnect: (uuid: string) => Promise<void>; getProtocolV2PacketCapacity?: (uuid: string) => number | undefined | Promise<number | undefined>; init: () => Promise<void>; version: string; };

WebUSB vs BLE:Protocol V1 帧格式

下表描述 Protocol V1。低层插件是 BLE 适配器;协议探测、编码和重组由 SDK 负责。

WebUSB (桌面端)BLE (原生移动端)
数据包大小固定 64 字节可变长度 (取决于 MTU)
每个包前缀所有包都有 0x3F仅头部包有 0x3F 0x23 0x23
填充零填充到 64 字节无需填充
receive() 返回每次一个 64 字节帧原始 BLE 通知数据块(hex)

WebUSB Protocol V1(桌面端)

传输使用固定 64 字节帧,SDK 负责消息组装。

Magic bytes 说明: 0x3F 0x23 0x23 是协议固定的标识字节,用于识别数据包的起始位置。

首帧:

OffsetLengthContent
03Magic: 0x3F 0x23 0x23
32消息类型 (大端 u16)
54载荷长度 (大端 u32)
955前 55 字节 protobuf(零填充)

后续帧:

OffsetLengthContent
01Magic: 0x3F
163剩余 protobuf 字节(零填充)

BLE 协议(原生移动端)

每次 receive(uuid) 从队列返回一个未经修改的 BLE 通知数据块,编码为 hex。保留通知顺序,并缓存早于读取请求到达的数据。插件不要删除协议头、填充为 USB 的 64 字节包或解码 protobuf。

  • Protocol V1: SDK 识别 3F2323 帧头、读取载荷长度并收集后续数据块。为兼容旧插件,V1 也接受预先重组的 type + length + payload 消息。
  • Protocol V2: SDK 将原始数据块组装为帧,处理 CRC、序号和消息重组。不能用仅支持 V1 的帧头检测或重组逻辑处理这些数据。
  • send(uuid, data, options) 接收 SDK 准备好的 hex 数据,按顺序写入字节,传递 I/O 错误,并在提供 withoutResponse 时遵循该选项。
  • 通过 getProtocolV2PacketCapacity 返回单次 BLE 特征写入实际支持的最大字节数。SDK 默认使用 192 字节,V2 包上限为 244 字节。返回可写入容量,不是包含协议开销的 ATT MTU。
  • 断开时拒绝待处理的读取并清除旧连接的通知队列,不要在重连后继续交付旧数据。

初始化示例

以下适配片段委托给实现上述接口的原生桥接层。各方法应在对应操作完成后 resolve,失败时 reject。

import HardwareSDK from '@onekeyfe/hd-common-connect-sdk'; import type { LowlevelTransportSharedPlugin } from '@onekeyfe/hd-transport'; // Implement these methods in your native BLE bridge before initialization. declare const nativeBle: LowlevelTransportSharedPlugin; const plugin: LowlevelTransportSharedPlugin = { enumerate: () => nativeBle.enumerate(), send: (uuid, data, options) => nativeBle.send(uuid, data, options), receive: uuid => nativeBle.receive(uuid), connect: uuid => nativeBle.connect(uuid), disconnect: uuid => nativeBle.disconnect(uuid), getProtocolV2PacketCapacity: uuid => nativeBle.getProtocolV2PacketCapacity?.(uuid), init: () => nativeBle.init(), version: nativeBle.version, }; const result = await HardwareSDK.init({ env: 'lowlevel', debug: false }, undefined, plugin); if (!result) throw new Error('SDK initialization failed');

下一步

最后更新于