Package-level declarations
Types
Entry point: owns the scanner (app-scoped, independent of connections, so scan-while- connected is trivial) and the live DeviceSessions. Multiple simultaneous devices are supported — each connection is an independent session with its own scope.
Typed failures surfaced by the SDK. Fallible operations return Result carrying one of these instead of crashing or swallowing the error (the legacy code returned false / dropped silently). Transport implementations map their stack's errors onto these.
JSON (de)serialization for DeviceConfig. Lives in :core (not :protocol) to keep the protocol module dependency-free. Electrode labels ARE stored: they are user-edited, so deriving them from the model would silently discard a custom montage on reconnect.
Per-headset config persistence, behind an interface so it is swappable (SharedPreferences today, DataStore later) and fakeable in tests. Replaces the legacy mutable static companion { var currentConfig } shared across instances.
Device Information Service strings, read best-effort during DeviceSession.initialize. A characteristic the device does not expose — or a failed read — yields null; device info is never a reason to fail the handshake.
One connected device. Owns a supervised CoroutineScope cancelled on disconnect; the handshake awaits suspend acks from the GattConnection instead of polling a shared event log with magic delays (the legacy design). Fallible ops return Result.
Lifecycle of a BrainAccessDevice, exposed as a StateFlow.
A scan result: enough to identify the device and pick its DeviceModel.
A batch of decoded samples from one stream packet — the efficient public unit (one object per packet, not per sample). Channel labels + srate travel with the data so consumers never reconstruct layout by hand (the legacy positional FloatArray contract is gone).
One device's GATT surface. Every fallible op suspends until the stack acknowledges it (the suspend-ack model that replaces the legacy poll-the-event-log state machine). Characteristic identifiers are the UUID strings from GattUuids.
Process-lifetime in-memory store; the default when no persistence is wired.
Progress of a DeviceSession.updateFirmware transfer.
ConfigStore backed by SharedPreferences (one JSON entry per headset, keyed by the BLE address carried in DeviceId). Zero extra dependency beyond the platform. Exercised on-device (not in JVM unit tests); the JSON round-trip is covered by ConfigCodecTest.