export interface DiscoveredDevice { address: string; name: string | null; } export interface BleCharacteristic { uuid: string; write(data: Buffer, withoutResponse: boolean): Promise; subscribe(onData: (data: Buffer) => void): Promise; unsubscribe(): Promise; } export interface BleBackend { readonly name: string; init(): Promise; scanFor( matcher: (device: DiscoveredDevice) => boolean, timeoutMs: number, ): Promise; scanForAll( matcher: (device: DiscoveredDevice) => boolean, timeoutMs: number, onDeviceFound?: (device: DiscoveredDevice) => void, signal?: AbortSignal, ): Promise; stopScan(): Promise; connect(address: string): Promise; onDisconnect(callback: () => void): void; discoverCharacteristics( writeUUID: string, notifyUUID: string, normalizeUUID: (uuid: string) => string, ): Promise<{ write: BleCharacteristic; notify: BleCharacteristic }>; disconnect(): Promise; } export type BleBackendType = "noble" | "dbus"; /** * Uses dbus on Linux and noble on other platforms. * You can override with BEAMBOXCTL_BLE_BACKEND=noble|dbus. */ export function resolveBackendType(): BleBackendType { const override = process.env.BEAMBOXCTL_BLE_BACKEND?.toLowerCase().trim(); if (override === "noble" || override === "dbus") { return override; } return process.platform === "linux" ? "dbus" : "noble"; }