Package-level declarations
Types
Fuel-gauge reading from the device's "full battery info" characteristics. Read on demand via DeviceSession.readBatteryGauge; distinct from the coarse SIG Battery Level percentage carried on DeviceSession.battery.
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 throwing from the call site. Transport implementations map their stack's errors onto these.
Build identity of this SDK.
The brainaccess node of the metadata: BrainAccess-specific, not part of the XDF convention.
The cap node of the metadata.
One recorded/streamed channel: label, contract type (com.neurotec.brainaccess.protocol.ChannelType), contract unit (com.neurotec.brainaccess.protocol.ChannelUnit) and, for EEG electrodes, the standard 10-05 location (mm, X right / Y front / Z up) and electrode hardware.
The device's charging-settings service (stay-on-while-charging and idle power-off). Both values live in device RAM: they survive a disconnect but revert to the defaults (off, 20 min) at power-off.
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.
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. 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.
Per-electrode hardware description (the hardware node of a channel in the LSL contract).
One device's GATT surface. Every fallible op suspends until the stack acknowledges it (suspend-ack model). Characteristic identifiers are the UUID strings from GattUuids.
Process-lifetime in-memory store; the default when no persistence is wired.
The montage settings that make a BrainAccess device reproducible — Board's template_json (its MONTAGE_KEYS subset of the template file), key for key.
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.
Stream metadata, BrainAccess Board StreamMetadata schema v1 field for field. Unknown values are null. toJson produces the JSON BrainAccess Board uses for recording metadata; the LSL outlet writes the same data into the stream header. The lsl field (set by Board for captured streams only) is always null here.
How DeviceSession.sampleIndexAt places host times on the device's sample counter, and how well the device's clock fits the host's. For diagnostics; nothing else depends on it.
Properties
Functions
The channel list of a BrainAccess LSL stream, in BrainAccess Board LSL contract v1 column order: EEG electrodes, contact_<label> per electrode, Accel_x/y/z (if hasAccel), Gyro_x/y/z (if hasGyro), Digital (if digitalInput: type TRIG, unit value, 0 or 1 per sample, the level of the device's digital input; present only when the stream was started with it), Sample, Streaming, Battery.
Build the StreamMetadata of this session for the given channels (the LSL path passes lslContractChannels; recorders pass their own file-specific lists). Identity fields come from the Device Information Service (DeviceSession.info; null when not read or blank), the montage from DeviceSession.currentConfig. software adds entries to versions (e.g. board); the SDK adds kotlin_sdk (BrainAccessKit.VERSION) and contract.