DeviceEnv

Trait DeviceEnv 

Source
pub trait DeviceEnv {
Show 31 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) -> !; async fn reboot(&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> { ... } async fn clear_ble_bonds(&mut self) -> bool { ... } async fn set_ble_pairing(&mut self, open: bool) -> bool { ... } fn set_alert(&mut self, state: AlertState) { ... } fn gnss_switched(&mut self, enabled: bool) { ... } fn set_ble_enabled(&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§

Source

async fn persist_snapshot(&mut self, bytes: &[u8]) -> Result<(), ()>

Durably persist the encoded protocol snapshot (CMD_SAVE / host wipe).

Source

async fn clear_snapshot(&mut self) -> Result<(), ()>

Tombstone the snapshot journal (CMD_CLEAR).

Source

async fn persist_identity(&mut self, bytes: &[u8]) -> Result<(), ()>

Durably persist the encoded device identity.

Source

async fn clear_identity(&mut self) -> Result<(), ()>

Tombstone the identity journal (CMD_CLEAR).

Source

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.

Source

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.

Source

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. Unlike clear_ble_bonds it need not empty the live BLE stack, because the reboot reloads bonds from the now-erased journal.

Source

async fn reboot(&mut self) -> !

CMD_REBOOT: restart the hardware, keeping every persisted journal intact. Never returns. Only reached on a board whose SessionConfig::reboot advertises the capability, so there is no default — a board that sets the flag owes an implementation.

A board with a mesh node owes it two courtesies before the reset (device_node::quiesce_for_reboot provides both): airing the MAC acknowledgment of the frame that carried the command — a reset-class command is answered by that acknowledgment and nothing else — and forcing the frame-counter boundaries to durable storage. Skipping the flush re-opens the replay window the command was admitted through, and the administrator’s retries of that same command are then accepted again after boot: one reboot per retry.

Source

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.

Source

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).

Source

fn publish_dev_domain(&mut self, snapshot: DevDomainSnapshot)

Deliver a device-domain mirror to the board’s device node.

Provided Methods§

Source

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.

Source

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.

Source

async fn clear_counters(&mut self)

Drop persisted frame-counter boundaries after a successful identity clear. Boards without a device node keep the default.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

async fn clear_ble_bonds(&mut self) -> bool

CMD_BLE_CLEAR_BONDS: delete every stored bond, the pairing PIN, and the pairing lockout, then open a pairing window. true once the deletion is durable.

Unlike the factory reset below, this runs with the board still up, so the live BLE stack has to be emptied alongside the journal — a bond forgotten on flash but still held in RAM would keep working until the next boot. Boards that do not manage their own bonds never see this and keep the default, which refuses.

Source

async fn set_ble_pairing(&mut self, open: bool) -> bool

A PROP_BLE_PAIRING write: open (or renew) the pairing window, or close it. false when the requested state cannot be entered — only ever an open the board must refuse, because it is locked out after repeated pairing failures or its Bluetooth is off; a close always succeeds.

Source

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.

Source

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.

Source

fn set_ble_enabled(&mut self, enabled: bool)

Make the Bluetooth transport reachable, or stop it being so.

Called from the device-domain mirror rather than from any one gesture, so it arrives for a host write, a boot restore, a CMD_RST and a menu entry alike — and arrives again whenever anything else in the domain moves. Implementations must therefore be idempotent, and boards without CAP_BLE never see anything but the default.

Disabled means unreachable, not powered down: dropping the attached host and stopping advertising is what a user turns this off for, and a stack that cannot be torn down at runtime is no reason to refuse them that.

Source

fn request_attention(&mut self)

A covered frame was queued for an attached-or-future host (T-1000E: request the attention LED).

Source

fn clear_attention(&mut self)

The host-facing queue drained to empty (T-1000E: clear it).

Source

fn note_transmit_load(&mut self)

A transmit is about to start; boards with a battery-level estimator mark the load spike.

Source

fn trace(&mut self, args: Arguments<'_>)

Diagnostic trace line (routed to the board’s debug channel; the default discards).

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.

Implementors§