RadioInterfaceService
Interface for the low-level radio interface that handles raw byte communication.
This is the transport layer — it manages the raw hardware connection (BLE, TCP, Serial, USB) to a Meshtastic radio. Its connectionState reflects whether the physical link is up or down, before any handshake or config-loading logic is applied.
Important: UI and feature modules should never observe connectionState directly. Instead, they should use ServiceRepository.connectionState, which is the canonical app-level connection state that accounts for handshake progress, light-sleep policy, and other higher-level concerns. The only legitimate consumer of this transport-level flow is MeshConnectionManager, which bridges transport state changes into the app-level ServiceRepository.connectionState.
See also
Properties
The transport session that still owns lifecycle completion, or null after teardown drains every admitted operation. Implementations close admission before teardown, so isSessionActive and the run helpers reject new work immediately even while this flow temporarily retains the draining session.
Flow of user-facing connection error messages (e.g. permission failures).
Transport-level connection state of the radio hardware.
Flow of the current device address.
Whether this build carries the packet capture the replay transport needs. False means selecting a replay address would fall back to the plain mock, so callers offering a replay device must hide it.
Flow of radio activity events.
Whether the virtual demo transports may be offered and bound right now.
Flow of raw data received from the radio, bound to the transport session that admitted each frame.
The scope in which interface-related coroutines should run.
Monotonically increasing generation bumped on every transport start (including same-address reconnect). Consumers use this to discard state retained from a previous transport instance. Stub implementations that never start a real transport expose a constant zero flow.
The device types supported by this platform's radio interface.
Functions
Consumes and returns the GATT cache invalidation request. Returns true exactly once after requestGattCacheInvalidationOnNextConnect was called, then resets to false.
Explicitly tears down the active transport, sending a polite ToRadio(disconnect = true) goodbye frame first when a transport is live. Safe to call when nothing is connected — implementations must no-op in that case. Suspends until the teardown completes.
Returns the current device address.
Called when the transport has received raw data from the radio.
Returns whether session still owns transport admission. Implementations must make this reflect the admission gate, not only activeSession, because the draining session may remain published after new work is rejected.
Called when the transport has disconnected.
Requests that the next BLE transport connection invalidates Android's GATT service cache before service discovery. Used after OTA firmware updates where the device reboots with a potentially different BLE service table on the same MAC address.
Drains any bytes currently buffered in receivedData without emitting them to collectors.
Silent in-place transport restart for handshake stalls: tears down the active transport and re-establishes it in place, without touching the connection-request gate or the selected device address.
Runs block while holding the same lifecycle lease, without exposing the lease token. Implementations may serialize this convenience path to preserve handshake ordering; independently deferred work should use runWithSessionLease so it can acquire its own lease before its parent operation returns.
Acquires a lifecycle lease for suspend block. Once admitted, teardown closes admission to later work and waits for this block to finish before publishing session completion or starting a replacement transport. block may use RadioSessionLease.isCurrent for transaction-bound checks that must remain valid through commit even after teardown has closed new admission. Implementations must acquire and release the lease through the same admission state used by teardown; comparing only activeSession cannot satisfy the draining contract. Callers must keep the block bounded and must not invoke transport lifecycle methods from inside it.
Sends bytes when a transport is available; callers that need admission evidence use trySendToRadio.
Sets the device address to connect to.
Constructs a full radio address for the specific interface type.
Attempts to dispatch bytes to the active transport.