pub trait DeviceEnv {
Show 27 methods
// Required methods
async fn persist_snapshot(&mut self, bytes: &[u8]) -> Result<(), ()>;
async fn clear_snapshot(&mut self) -> Result<(), ()>;
async fn persist_identity(&mut self, bytes: &[u8]) -> Result<(), ()>;
async fn clear_identity(&mut self) -> Result<(), ()>;
fn fill_secret(&mut self, secret: &mut [u8; 32]) -> Result<(), ()>;
async fn apply_pairing_pin(&mut self, pin: Option<u32>) -> bool;
async fn factory_reset(&mut self) -> !;
fn set_advertising_allowed(&mut self, allowed: bool);
async fn publish_device_name(&mut self, name: &str);
fn publish_dev_domain(&mut self, snapshot: DevDomainSnapshot);
// Provided methods
async fn older_snapshot(&mut self, out: &mut [u8]) -> Option<usize> { ... }
fn report_snapshot_rejected(&mut self, fell_back: bool) { ... }
async fn clear_counters(&mut self) { ... }
async fn sample_battery(&mut self) -> Result<BatteryStatus, ()> { ... }
async fn sample_illuminance(&mut self) -> Option<u32> { ... }
async fn battery_event(&mut self) -> BatteryStatus { ... }
async fn publish_event(&mut self) -> PublishEvent { ... }
async fn read_time(&mut self) -> Option<u32> { ... }
async fn apply_time(&mut self, epoch: Option<u32>) { ... }
async fn sample_gnss(&mut self) -> Result<GnssSnapshot, ()> { ... }
async fn sign_identity(&mut self, out: &mut [u8]) -> Option<usize> { ... }
fn set_alert(&mut self, state: AlertState) { ... }
fn gnss_switched(&mut self, enabled: bool) { ... }
fn request_attention(&mut self) { ... }
fn clear_attention(&mut self) { ... }
fn note_transmit_load(&mut self) { ... }
fn trace(&mut self, args: Arguments<'_>) { ... }
}Expand description
Board couplings of the session driver. Everything the loop needs from
the platform, expressed as one trait so the driver itself stays free
of HAL types and cfg board forks. Hooks a board doesn’t have keep
their no-op defaults (e.g. only the T-1000E implements the attention
indicator and transmit-load hooks today).
Required Methods§
Sourceasync fn persist_snapshot(&mut self, bytes: &[u8]) -> Result<(), ()>
async fn persist_snapshot(&mut self, bytes: &[u8]) -> Result<(), ()>
Durably persist the encoded protocol snapshot (CMD_SAVE / host wipe).
Sourceasync fn clear_snapshot(&mut self) -> Result<(), ()>
async fn clear_snapshot(&mut self) -> Result<(), ()>
Tombstone the snapshot journal (CMD_CLEAR).
Sourceasync fn persist_identity(&mut self, bytes: &[u8]) -> Result<(), ()>
async fn persist_identity(&mut self, bytes: &[u8]) -> Result<(), ()>
Durably persist the encoded device identity.
Sourceasync fn clear_identity(&mut self) -> Result<(), ()>
async fn clear_identity(&mut self) -> Result<(), ()>
Tombstone the identity journal (CMD_CLEAR).
Sourcefn fill_secret(&mut self, secret: &mut [u8; 32]) -> Result<(), ()>
fn fill_secret(&mut self, secret: &mut [u8; 32]) -> Result<(), ()>
Fill secret from the platform’s cryptographic RNG. Fails closed:
an error refuses identity generation rather than degrading.
Sourceasync fn apply_pairing_pin(&mut self, pin: Option<u32>) -> bool
async fn apply_pairing_pin(&mut self, pin: Option<u32>) -> bool
Apply a PROP_BLE_PAIRING_PIN write against the bond journal and
the live BLE stack; true when it took effect.
Sourceasync fn factory_reset(&mut self) -> !
async fn factory_reset(&mut self) -> !
CMD_FACTORY_RESET: erase EVERY piece of persistent state the
platform owns — saved snapshot, device identity, frame-counter
boundaries, BLE bonds, pairing PIN, and any other journal — then
reboot. Never returns: the reset discards in-RAM state and the
board comes back factory-fresh. There is no separate “clear bonds”
hook because a reboot reloads bonds from the (now-erased) journal,
so the live BLE stack never has to be touched.
Sourcefn set_advertising_allowed(&mut self, allowed: bool)
fn set_advertising_allowed(&mut self, allowed: bool)
Publish the transport-arbitration advertising policy (a wired
attach suppresses BLE advertising). Diagnostic builds may
deliberately ignore allowed.
Sourceasync fn publish_device_name(&mut self, name: &str)
async fn publish_device_name(&mut self, name: &str)
Publish the session’s device name to the board’s consumers (advertising data, device node, UI).
Sourcefn publish_dev_domain(&mut self, snapshot: DevDomainSnapshot)
fn publish_dev_domain(&mut self, snapshot: DevDomainSnapshot)
Deliver a device-domain mirror to the board’s device node.
Provided Methods§
Sourceasync fn older_snapshot(&mut self, out: &mut [u8]) -> Option<usize>
async fn older_snapshot(&mut self, out: &mut [u8]) -> Option<usize>
Copy the newest committed snapshot generation strictly older than
the one last handed to the driver into out, returning its
length.
Called only after a payload is rejected, so the cost is paid on a boot that is already going wrong. Implementations re-scan the journal rather than retaining a runner-up, keeping the mount path’s “never buffers a second copy” discipline. The default refuses, which makes rejection terminal for boards whose journal cannot walk back.
Sourcefn report_snapshot_rejected(&mut self, fell_back: bool)
fn report_snapshot_rejected(&mut self, fell_back: bool)
A stored snapshot was rejected at boot. Boards with an indicator surface it locally: the host-visible report reaches nobody on an unattended repeater, which is exactly the deployment this matters for.
Sourceasync fn clear_counters(&mut self)
async fn clear_counters(&mut self)
Drop persisted frame-counter boundaries after a successful identity clear. Boards without a device node keep the default.
Sourceasync fn sample_battery(&mut self) -> Result<BatteryStatus, ()>
async fn sample_battery(&mut self) -> Result<BatteryStatus, ()>
One fresh battery measurement (Effect::SampleBattery). Only
emitted when the board’s SessionConfig::battery advertises
fields, so the default refuses.
Sourceasync fn sample_illuminance(&mut self) -> Option<u32>
async fn sample_illuminance(&mut self) -> Option<u32>
One fresh ambient light measurement in millilux
(Effect::SampleIlluminance). Only emitted on a board whose
SessionConfig::illuminance is set, so the default reports nothing.
None is a legitimate answer — the sensor exists but could not be
read — and reaches the host as the empty value rather than an error.
Sourceasync fn battery_event(&mut self) -> BatteryStatus
async fn battery_event(&mut self) -> BatteryStatus
Wait for a battery measurement the board considers worth
announcing, for publication as an unsolicited PROP_BATTERY
(Session::publish_battery).
The board owns the whole policy: the sampling cadence, the charge-state edges, and which changes matter. It is the only layer that sees every sample, so filtering there keeps the session free of cached readings and keeps this hook’s contract simple — every value it yields is published.
Cancellation-safe: the driver drops and re-creates this future on
every other loop iteration, so an implementation must not lose an
update it was cancelled on (an embassy_sync::watch::Watch
receiver behaves correctly here; a bare Signal does not).
The default never completes, so boards without battery push add nothing to the select.
Sourceasync fn publish_event(&mut self) -> PublishEvent
async fn publish_event(&mut self) -> PublishEvent
Wait for anything the board wants to publish unasked, across every property it pushes.
This is the driver’s single select arm for device-initiated
publication. The default delegates to
battery_event, so a board that pushes only
battery measurements implements that and nothing else. A board that
also pushes time or position overrides this instead and selects
over its own sources — which it can do without fighting the
borrow checker, since those are its own fields rather than three
&mut self calls.
Cancellation-safe on the same terms as
battery_event.
Sourceasync fn read_time(&mut self) -> Option<u32>
async fn read_time(&mut self) -> Option<u32>
Read the platform wall clock (Effect::ReadTime): Unix seconds,
or None when the device does not know what time it is.
Not knowing is the honest answer for a board that has never had a
fix and was never told, and it is what stops a display from
showing a clock. The default is exactly that, so a board without
CAP_TIME never has to implement it.
Sourceasync fn apply_time(&mut self, epoch: Option<u32>)
async fn apply_time(&mut self, epoch: Option<u32>)
Apply a PROP_TIME write (Effect::ApplyTime): set the wall
clock, or return it to not knowing.
A manual set outranks every receiver-derived one, so this applies
regardless of PROP_GNSS_TIME_TRUST.
Sourceasync fn sample_gnss(&mut self) -> Result<GnssSnapshot, ()>
async fn sample_gnss(&mut self) -> Result<GnssSnapshot, ()>
Sample the receiver’s current view of position and constellation
(Effect::SampleGnss). Only emitted on a board whose
SessionConfig::gnss advertises the capability, so the default
refuses.
Sourceasync fn sign_identity(&mut self, out: &mut [u8]) -> Option<usize>
async fn sign_identity(&mut self, out: &mut [u8]) -> Option<usize>
Build and sign the device identity’s node-identity blob into
out (Effect::SignIdentity), returning its length.
The board owns both halves the session does not: the signing key, and the advertised profile the Identity Request responder uses. Boards without a device node keep the default, which refuses.
Sourcefn set_alert(&mut self, state: AlertState)
fn set_alert(&mut self, state: AlertState)
Start or stop the board’s locate indication (PROP_ALERT).
Carries the authoritative state and is called for every
transition — host write, local cancellation, and deadline — so an
implementation can treat it as idempotent and needs no notion of
why the alert ended. AlertState::Locate must override a local
silence setting without clearing it (spec §PROP_ALERT); boards
without CAP_ALERT never see this and keep the default.
Sourcefn gnss_switched(&mut self, enabled: bool)
fn gnss_switched(&mut self, enabled: bool)
The receiver switch was flipped at the device, and is now
enabled.
Only for the local gesture: a host write already knows what it asked for, and a board that indicated one would announce the phone’s own settings screen back at it. Carries the resulting state rather than the fact of a press, because “on” and “off” are what the operator needs told apart.
Sourcefn request_attention(&mut self)
fn request_attention(&mut self)
A covered frame was queued for an attached-or-future host (T-1000E: request the attention LED).
Sourcefn clear_attention(&mut self)
fn clear_attention(&mut self)
The host-facing queue drained to empty (T-1000E: clear it).
Sourcefn note_transmit_load(&mut self)
fn note_transmit_load(&mut self)
A transmit is about to start; boards with a battery-level estimator mark the load spike.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.