Skip to Content
MatérielConceptsTransport de bas niveau

Plugin de transport de bas niveau

À utiliser uniquement lorsque WebUSB / React Native BLE / les adaptateurs natifs officiels ne répondent pas à votre cas d’usage. Vous serez responsable du cycle de vie BLE natif et des E/S ordonnées ; prévoyez donc un coût de maintenance supérieur.

Remarque : L’environnement lowlevel et LowlevelTransportSharedPlugin sont conçus uniquement pour les communications BLE (Bluetooth). Pour les communications USB dans les environnements Node.js/CLI, utilisez NodeUsbTransport (environnement node-usb) à la place — il gère l’encodage du protocole et les E/S USB directement via libusb, sans plugin.

Notre SDK Bluetooth est développé avec React Native. Vous utilisez peut-être une autre technologie pour votre application, par exemple Swift, Kotlin ou Flutter. Dans ce cas, ajouter une dépendance React Native à votre projet n’est pas forcément judicieux.

Nous proposons un nouveau mode de communication permettant d’utiliser LowlevelTransportSharedPlugin pour communiquer avec le matériel. Vous pouvez choisir librement votre pile technique. Vous devrez implémenter le protocole de connexion, de déconnexion, d’envoi et de réception des données de l’appareil.

Référence rapide

UUID BLE OneKey

RôleUUID
Service00000001-0000-1000-8000-00805f9b34fb
Caractéristique d’écriture00000002-0000-1000-8000-00805f9b34fb
Caractéristique de notification00000003-0000-1000-8000-00805f9b34fb

Exemple de données d’en-tête BLE Protocol V1

L’en-tête suivant est propre à Protocol V1 ; ne l’utilisez pas pour analyser les notifications Protocol V2.

Raw data: 3F 23 23 00 02 00 00 00 0A 12 08 ... │ │ │ │ │ │ │ └─ Protobuf payload starts │ │ │ │ │ └────────┴─ Payload length: 0x0000000A = 10 bytes │ │ │ └──┴─ Message type: 0x0002 └──┴──┴─ Magic: 0x3F 0x23 0x23 (fixed identifier)

Détecter le paquet d’en-tête : Les 3 premiers octets sont 3F 23 23

Exemples natifs (tous basés sur le plugin de transport de bas niveau) :

Interface 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 et BLE : cadrage Protocol V1

Il s’agit de détails de transport Protocol V1. Le plugin de bas niveau est un adaptateur BLE ; le SDK assure la détection du protocole, l’encodage et le réassemblage.

WebUSB (ordinateur)BLE (mobile natif)
Taille des paquetsFixe : 64 octetsVariable (selon le MTU)
Préfixe de paquet0x3F sur chaque paquet0x3F 0x23 0x23 uniquement sur l’en-tête
RemplissageCompléter avec des zéros jusqu’à 64 octetsAucun remplissage nécessaire
receive() renvoieUne trame de 64 octets à la foisBloc brut de notification BLE (hex)

Protocol V1 WebUSB (ordinateur)

Le transport utilise des trames fixes de 64 octets ; le SDK gère l’assemblage des messages.

Octets magiques : 0x3F 0x23 0x23 sont des octets fixes d’identification du protocole utilisés pour détecter les limites des paquets.

Premier paquet :

DécalageLongueurContenu
03Marqueur magique : 0x3F 0x23 0x23
32Type de message (uint16 BE)
54Longueur des données (uint32 BE)
95555 premiers octets de protobuf (complétés par des zéros)

Paquets suivants :

DécalageLongueurContenu
01Marqueur magique : 0x3F
163Octets protobuf restants (complétés par des zéros)

Protocole BLE (mobile natif)

Renvoyez un bloc de notification BLE en attente, non modifié et en hexadécimal, pour chaque appel receive(uuid). Conservez l’ordre des notifications et les blocs reçus avant qu’un lecteur soit en attente. Ne supprimez pas les en-têtes de protocole, ne complétez pas les blocs pour atteindre les paquets USB de 64 octets et ne décodez pas protobuf dans le plugin.

  • Protocol V1 : le SDK reconnaît l’en-tête 3F2323, lit la longueur des données et collecte les blocs de continuation. Il accepte aussi l’ancien message préassemblé type + length + payload pour la compatibilité V1.
  • Protocol V2 : le SDK assemble les blocs bruts en trames et gère le CRC, la séquence et le réassemblage des messages. Un détecteur d’en-tête ou un assembleur limité à V1 ne doit pas traiter ces données.
  • send(uuid, data, options) reçoit l’hexadécimal préparé par le SDK. Écrivez les octets dans l’ordre, propagez les échecs d’E/S et respectez withoutResponse lorsqu’il est fourni.
  • Indiquez le nombre maximal réel d’octets acceptés par une écriture de caractéristique BLE via getProtocolV2PacketCapacity. Le SDK utilise une valeur de repli de 192 octets et limite les paquets V2 à 244 octets. Renvoyez la capacité d’écriture, pas le MTU ATT incluant son surcoût.
  • À la déconnexion, rejetez les lectures en attente et supprimez les notifications en file de l’ancienne connexion. Ne les transmettez pas après la reconnexion.

Exemple d’initialisation

Ce fragment d’adaptateur délègue à un pont natif qui doit implémenter l’interface ci-dessus. Ses méthodes ne doivent se résoudre qu’une fois l’opération correspondante terminée, ou être rejetées en cas d’échec.

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');

Étapes suivantes

Dernière mise à jour le