MobileUlcpSession

Struct MobileUlcpSession 

Source
pub struct MobileUlcpSession { /* private fields */ }
Expand description

Stateful mobile host session for the ULCP.

This is the protocol boundary: it consumes complete reassembled ULCP frames and owns TIDs, response matching, capability-driven synchronization, host ownership, and claim/save choreography. Platform code owns only the transport lifecycle, byte shuttling, and timers.

Implementations§

Source§

impl MobileUlcpSession

Source

pub fn new() -> Arc<Self>

A session for the phone’s own radio: the one it tethers to.

Source

pub fn administrative() -> Arc<Self>

A session for a radio this phone administers but does not claim. Self::claim is refused; everything else behaves identically.

Source

pub fn attach_mode(&self) -> UlcpAttachMode

Which relationship this session represents.

Source

pub fn begin( &self, selected_host_key: Option<Vec<u8>>, ) -> Result<UlcpSessionUpdateRecord, MobileError>

Begin post-attach synchronization for a new transport generation.

Source

pub fn claim( &self, host_key: Vec<u8>, ) -> Result<UlcpSessionUpdateRecord, MobileError>

Replace an unclaimed or other-host configuration with this phone’s key.

Source

pub fn factory_reset(&self) -> Result<UlcpSessionUpdateRecord, MobileError>

Erase ALL mutable state on the radio (saved provisioning, device identity, BLE bonds, pairing PIN, every persisted journal) and reboot it. The radio does not reply — the reset drops the link — so this is fire-and-forget: send the frame, then treat the ensuing disconnect as completion. Permitted from any stage so a misbehaving radio can always be wiped; unlike claim/configure it makes no stage or ownership demands.

Source

pub fn set_alert( &self, state: UlcpAlertState, ) -> Result<UlcpSessionUpdateRecord, MobileError>

Start or stop the radio’s locate alert (PROP_ALERT) so a misplaced radio can be found.

Not part of configure_device, and never saved: this is live behavior rather than configuration, and it deliberately survives the phone walking out of BLE range — which is precisely when a search needs it. What ends it is this call, a button press at the radio, or the radio’s own deadline; the latter two arrive as an unsolicited PROP_ALERT carried on the session snapshot.

Re-sending Locate while an alert is running restarts that deadline, which is how a longer search keeps the alert alive.

Source

pub fn set_time( &self, epoch_seconds: Option<u32>, ) -> Result<UlcpSessionUpdateRecord, MobileError>

Set — or clear — the device’s wall clock (PROP_TIME).

Live state rather than configuration, and never saved: an epoch written to flash would come back arbitrarily wrong, since nothing bounds how long a device spends powered off. So this is not part of Self::configure_device, which carries the time zone — where the device is meant to be is worth persisting even when what time it is is not.

None clears the clock back to unknown, which is what a device reports before its first fix. On a device whose receiver is trusted for time, a fix will overwrite whatever is set here.

The device answers with the epoch it now holds; that answer, not the value written, is what the session snapshot reports.

Source

pub fn configure( &self, settings: UlcpRadioSettingsRecord, ) -> Result<UlcpSessionUpdateRecord, MobileError>

Apply, verify, and persist a complete radio-settings snapshot.

Source

pub fn configure_device( &self, configuration: UlcpDeviceConfigRecord, ) -> Result<UlcpSessionUpdateRecord, MobileError>

Apply, verify, and persist a complete configuration of the device’s own domain: its radio, the role it advertises, and whether and how it forwards for the mesh on its own.

This is what commissioning writes. It touches nothing in the host domain — no host key, no filters, no queues — so it is equally valid from an administrative session on someone else’s radio and from a tethered session on this phone’s own.

Source

pub fn configure_positioning( &self, gnss: Option<UlcpGnssSettingsRecord>, tz_offset_min: Option<i16>, ) -> Result<UlcpSessionUpdateRecord, MobileError>

Apply and persist the time zone and the positioning policy, and nothing else.

Self::configure_device can write these too, as part of a whole device domain — that is what commissioning does. This exists for the case commissioning does not cover: a phone changing the positioning settings of the radio it is tethered to, which has no reason to restate that radio’s role, discoverability, or forwarding policy in order to switch a receiver on.

Each argument must be present exactly when the device advertises the matching capability, and the four positioning properties travel together for the reason UlcpGnssSettingsRecord gives. The write is echo-verified property by property and closed with a save, like any other configuration pass.

Source

pub fn configure_advertising( &self, advert: Option<UlcpAdvertSettingsRecord>, ) -> Result<UlcpSessionUpdateRecord, MobileError>

Apply and persist the advertisement policy, and nothing else.

The tethered-radio counterpart of Self::configure_positioning: a phone changing how often its own radio announces itself has no reason to restate that radio’s role, forwarding policy, or receiver settings to do it.

Source

pub fn refresh(&self) -> Result<UlcpSessionUpdateRecord, MobileError>

Re-read every capability-gated property represented by the mobile snapshot. The existing snapshot remains usable while the bounded refresh is in flight; authoritative provisioning is published when the full capability-gated read completes.

Source

pub fn refresh_positioning( &self, ) -> Result<UlcpSessionUpdateRecord, MobileError>

Sample where the device is, and how well it knows.

The device announces a fix indicator and nothing else about a position — a receiver reports about a fix a second and ordinary noise moves the reading, so announcing any of this would keep the radio transmitting for a host that may not be looking. A host that is looking asks, at whatever rate it can use the answer.

Deliberately narrower than refresh: the five positioning properties and nothing else, so a screen watching a position does not re-read the PHY triple every time it looks.

Source

pub fn insert_device_channel_key( &self, channel_key: Vec<u8>, ) -> Result<UlcpSessionUpdateRecord, MobileError>

Store one channel key on the radio’s device identity (PROP_DEV_CHANNEL_KEYS), then persist with a chained CMD_SAVE when the device can.

This is the device’s own channel membership, independent of the phone’s: it is what the device uses for its own advertisements, blind-unicast addressing, and repeater filtering, and it survives host replacement.

Requires an attached, otherwise-idle session on a device advertising CAP_DEV_IDENTITY, and the device additionally requires an encrypted link before it will accept key material. Failures surface as operation_error with the device’s status name — NOMEM when the list is full (capacity ulcp_max_dev_channels), ALREADY when the key is already stored, which callers should treat as success.

Source

pub fn remove_device_channel_key( &self, channel_key: Vec<u8>, ) -> Result<UlcpSessionUpdateRecord, MobileError>

Remove one channel key from the radio’s device identity (PROP_DEV_CHANNEL_KEYS), then persist with a chained CMD_SAVE when the device can.

The remove selector is the key itself, so only a channel the caller still holds the key for can be removed this way. Same preconditions as Self::insert_device_channel_key; ITEM_NOT_FOUND surfaces as operation_error and callers should treat it as success.

Source

pub fn reconcile_host_channel_keys( &self, keys: Vec<Vec<u8>>, ) -> Result<UlcpSessionUpdateRecord, MobileError>

Make the radio’s host channel-key table (PROP_HOST_CHANNEL_KEYS) match the phone identity’s joined channels.

The radio needs these keys to recognize multicast and blind-unicast traffic addressed to channels this phone has joined, and to queue it while the phone is away. That is bookkeeping between the app and its own radio, not a user-facing setting: callers reconcile on attach and after every join or leave, and never surface it.

The host domain is volatile — the device does not persist it — so no CMD_SAVE is chained and reconciling on attach is what makes it stick. Requires an attached, idle session on a device advertising CAP_HOST_KEYS; otherwise the table is not this session’s to manage and the call reports that the capability is missing.

Returns without any frames when the device already holds exactly the requested set.

Source

pub fn insert_device_peer( &self, public_key: Vec<u8>, ) -> Result<UlcpSessionUpdateRecord, MobileError>

Store one peer public key on the radio’s device identity (PROP_DEV_PEERS), then persist with a chained CMD_SAVE when the device can.

Requires an attached, otherwise-idle session on a device advertising CAP_DEV_IDENTITY. Failures surface as operation_error with the device’s status name — NOMEM when the list is full (capacity ulcp_max_dev_peers), ALREADY when the key is already stored, which callers should treat as success.

Source

pub fn remove_device_peer( &self, public_key: Vec<u8>, ) -> Result<UlcpSessionUpdateRecord, MobileError>

Remove one peer public key from the radio’s device identity (PROP_DEV_PEERS), then persist with a chained CMD_SAVE when the device can.

Same preconditions as Self::insert_device_peer. ITEM_NOT_FOUND surfaces as operation_error and callers should treat it as success — the key is not on the device either way.

Source

pub fn transmit_raw( &self, data: Vec<u8>, nocca: bool, ) -> Result<UlcpSessionUpdateRecord, MobileError>

Queue one complete raw UMSH frame on STR_PHY_RAW.

The platform adapter supplies only opaque bytes from MobileMeshSession; Rust owns the ULCP command, stream identifier, metadata, TID, and confirmation matching. nocca sets TX_FLAG_NOCCA so the device transmits without its pre-transmit channel-activity check — used for immediate MAC acks (see [MobileMeshOutboundFrameRecord::nocca]).

Source

pub fn consume( &self, frame: Vec<u8>, ) -> Result<UlcpSessionUpdateRecord, MobileError>

Consume one complete ULCP frame and advance the session reducer.

Source

pub fn reset(&self) -> UlcpSessionUpdateRecord

Invalidate all outstanding transactions for a disconnected transport.

Source

pub fn abandon_raw_transmits( &self, transaction_ids: Vec<u8>, ) -> UlcpSessionUpdateRecord

Abandon raw transactions whose GATT writes were rejected locally. Their late correlated responses are ignored once; the attachment and all non-raw session state remain intact.

Trait Implementations§

Source§

impl<UT> LiftRef<UT> for MobileUlcpSession

Source§

impl<UT> LowerError<UT> for MobileUlcpSession

Source§

fn lower_error(obj: Self) -> RustBuffer

Lower this value for scaffolding function return Read more
Source§

impl<UT> LowerReturn<UT> for MobileUlcpSession

Source§

type ReturnType = <Arc<MobileUlcpSession> as LowerReturn<UniFfiTag>>::ReturnType

The type that should be returned by scaffolding functions for this type. Read more
Source§

fn lower_return(obj: Self) -> Result<Self::ReturnType, RustCallError>

Lower the return value from an scaffolding call Read more
Source§

fn handle_failed_lift( error: LiftArgsError, ) -> Result<Self::ReturnType, RustCallError>

Lower the return value for failed argument lifts Read more
Source§

impl<UT> TypeId<UT> for MobileUlcpSession

Auto Trait Implementations§

Blanket Implementations§

§

impl<T> Any for T
where T: 'static + ?Sized,

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> Borrow<T> for T
where T: ?Sized,

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

impl<T> BorrowMut<T> for T
where T: ?Sized,

§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, UT> HandleAlloc<UT> for T
where T: Send + Sync,

Source§

fn new_handle(value: Arc<T>) -> Handle

Create a new handle for an Arc value Read more
Source§

unsafe fn clone_handle(handle: Handle) -> Handle

Clone a handle Read more
Source§

unsafe fn consume_handle(handle: Handle) -> Arc<T>

Consume a handle, getting back the initial Arc<> Read more
Source§

unsafe fn get_arc(handle: Handle) -> Arc<Self>

Get a clone of the Arc<> using a “borrowed” handle. Read more
§

impl<T, U> Into<U> for T
where U: From<T>,

§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.