Skip to main content

QrPayload

Struct QrPayload 

Source
pub struct QrPayload<'a, T> { /* private fields */ }
Expand description

QR Code payload type

Implementations§

Source§

impl<'a, T, I> QrPayload<'a, T>
where T: Fn() -> I, I: Iterator<Item = Result<u8, Error>> + 'a,

Source

pub const fn new_from_basic_info( discovery_capabilities: DiscoveryCapabilities, comm_flow: CommFlowType, comm_data: BasicCommData, dev_det: &'a BasicInfoConfig<'_>, optional_data: T, ) -> QrPayload<'a, T>

Create a new QR payload from the device basic info config

§Arguments
  • discovery_capabilities - Discovery capabilities of the device
  • comm_flow - Commissioning flow type
  • comm_data - Basic commissioning data
  • dev_det - Device basic info config
  • optional_data - Function that provides an iterator over optional TLV data bytes. NOTE: Should be ordered by tag number in ascending order.
Source

pub const fn new( discovery_capabilities: DiscoveryCapabilities, comm_flow: CommFlowType, comm_data: BasicCommData, vid: u16, pid: u16, serial_no: &'a str, optional_data: T, ) -> QrPayload<'a, T>

Create a new QR payload

§Arguments
  • discovery_capabilities - Discovery capabilities of the device
  • comm_flow - Commissioning flow type
  • comm_data - Basic commissioning data
  • vid - Vendor ID
  • pid - Product ID
  • serial_no - Serial number of the device
  • optional_data - Function that provides an iterator over optional TLV data bytes. NOTE: Should be ordered by tag number in ascending order.
Source

pub fn is_valid(&self) -> bool

Check if the QR payload is valid

§Returns
  • true if the payload is valid
  • false otherwise
Source

pub fn as_str<'b>( &self, buf: &'b mut [u8], ) -> Result<(&'b str, &'b mut [u8]), Error>

Encode the QR text of this payload as a string into the provided buffer

§Arguments
  • buf - Buffer to store the QR code string
§Returns
  • On success, returns a tuple containing the QR code string and the remaining buffer
  • On failure, returns an error
Source

pub fn emit_chars(&self) -> impl Iterator<Item = Result<char, Error>>

Emit the QR text of this payload as an iterator of characters

Source§

impl<'a> QrPayload<'a, &'a [u8]>

Source

pub fn parse( qr: &str, buf: &'a mut [u8], ) -> Result<QrPayload<'a, &'a [u8]>, Error>

Parse a Matter onboarding QR-code text (an MT: payload) into a QrPayload.

This is the inverse of the QrPayload::as_str / QrPayload::emit_chars encoding path, and the entry point a commissioner uses to turn a scanned QR string into the discriminator, passcode, VID/PID etc. it needs to commission the device.

buf is a scratch buffer that the parsed payload borrows from: the trailing optional-TLV data (and hence any serial number decoded out of it) points into it, so buf must outlive the returned payload. A buffer of TOTAL_PAYLOAD_DATA_SIZE_IN_BYTES plus the optional-data length is enough; the base38 body never decodes to more bytes than the input string.

The returned payload’s optional_data is the raw optional-TLV byte slice (an anonymous TLV structure), which is empty when the QR carries no optional data.

§Errors

Returns ErrorCode::InvalidData if the string is not a well-formed MT: payload (missing prefix, invalid base38, too short, or an out-of-range field).

Source

pub const fn version(&self) -> u8

The payload version (always 0 for v1 QR codes).

Source

pub const fn discovery_capabilities(&self) -> DiscoveryCapabilities

The device’s advertised discovery capabilities.

Source

pub const fn comm_flow(&self) -> CommFlowType

The commissioning flow type.

Source

pub const fn discriminator(&self) -> u16

The 12-bit discriminator.

Source

pub fn passcode(&self) -> u32

The setup passcode (PIN).

Source

pub const fn vid(&self) -> u16

The Vendor ID.

Source

pub const fn pid(&self) -> u16

The Product ID.

Source

pub const fn serial_no(&self) -> &'a str

The serial number, or an empty string if the QR carries none.

Source

pub const fn optional_data(&self) -> &'a [u8]

The raw optional-TLV data (an anonymous TLV structure), empty if absent.

Source

pub fn commissionable_filter(&self) -> CommissionableFilter

A CommissionableFilter that discovers the device this QR code describes.

A QR code carries the full 12-bit discriminator, so this filters on discriminator and can narrow discovery to a single device. (Contrast QrPayload::<()>::commissionable_filter, built from a manual pairing code, which can only filter on the short discriminator.)

Only the discriminator is set. The vendor and product IDs are deliberately not included even though the QR carries them: per the Matter Core spec a device may advertise an anonymized Product ID of 0 during discovery, so filtering on the QR’s PID would fail to find such a device. Add them to the returned filter if the extra selectivity is wanted and the device is known not to anonymize.

Source§

impl<'a> QrPayload<'a, ()>

Source

pub fn parse_pairing_code(code: &str) -> Result<QrPayload<'a, ()>, Error>

Parse a Matter manual pairing code (the 11- or 21-digit decimal string printed on a device, e.g. 34970112332 / 3497-0112-332) into a QrPayload.

This is the “typed by a human” onboarding format, and it is the counterpart of BasicCommData::compute_pairing_code. It is deliberately a different T from QrPayload::parse (() rather than &[u8]), because a manual pairing code carries strictly less information than a QR code, and the resulting payload must not be mistaken for one:

  • Only the upper 4 bits of the discriminator are carried (the “short discriminator”). Per the Matter Core spec: “For machine-readable formats, the full 12-bit Discriminator is used. For the Manual Pairing Code, only the upper 4 bits out of the 12-bit Discriminator are used.” Read it via Self::short_discriminator - there is deliberately no discriminator() accessor on this T, so a 4-bit value can never be mistaken for a 12-bit one.
  • No discovery capabilities are carried, so a commissioner cannot know whether to look for the device over BLE, SoftAP or IP, and must try all of them.
  • No serial number and no optional TLV data are carried (hence T = ()).
  • The commissioning flow is only implied - see Self::comm_flow.

The Verhoeff check digit is verified. Separators (- and spaces) are ignored, so both the compact and the “pretty” printed forms are accepted.

§Errors

Returns ErrorCode::InvalidData if the code is not a well-formed v1 manual pairing code: wrong length, a non-digit, a bad check digit, a first digit of 8 or 9 (which per spec indicates a future format version), a VID/PID-present flag inconsistent with the length, or an out-of-range digit group.

Source

pub const fn short_discriminator(&self) -> u8

The short (4-bit) discriminator - the upper 4 bits of the device’s full 12-bit discriminator.

This is all a manual pairing code carries, so it can only narrow discovery to 1-in-16 devices. Feed it to CommissionableFilter::short_discriminator, not to the full-discriminator filter.

Source

pub fn passcode(&self) -> u32

The setup passcode (PIN). Carried in full (27 bits).

Source

pub fn vid_pid(&self) -> Option<(u16, u16)>

The Vendor and Product IDs, if this is the 21-digit variant that carries them (None for the 11-digit variant).

Source

pub fn comm_flow(&self) -> Option<CommFlowType>

The commissioning flow, as far as the code determines it.

A manual pairing code has no dedicated commissioning-flow field; per the Matter Core spec the variant implies it:

  • The 11-digit variant (no VID/PID) means the commissioner “SHALL assume it is a standard flow device” - so this returns Some(CommFlowType::Standard).
  • The 21-digit variant (with VID/PID) is used for both the User-intent and the Custom flow, and the code alone cannot distinguish them - so this returns None. To resolve it, look the VID/PID up in the Distributed Compliance Ledger (see Self::vid_pid).
Source

pub fn commissionable_filter(&self) -> CommissionableFilter

A CommissionableFilter that discovers the device this manual pairing code describes.

A manual pairing code only carries the short (4-bit) discriminator, so this necessarily filters on short_discriminator - which narrows discovery to 1-in-16 devices rather than to exactly one. Getting this right is the whole point of the method: the short value must not end up in the filter’s full-discriminator field, where it would match nothing.

The vendor and product IDs are not included even when the 21-digit variant carries them, since a device may advertise an anonymized Product ID of 0 during discovery.

Trait Implementations§

Source§

impl<'a, T> Clone for QrPayload<'a, T>
where T: Clone,

Source§

fn clone(&self) -> QrPayload<'a, T>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'a, T> Debug for QrPayload<'a, T>
where T: Debug,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a, T> Freeze for QrPayload<'a, T>
where T: Freeze,

§

impl<'a, T> RefUnwindSafe for QrPayload<'a, T>
where T: RefUnwindSafe,

§

impl<'a, T> Send for QrPayload<'a, T>
where T: Send,

§

impl<'a, T> Sync for QrPayload<'a, T>
where T: Sync,

§

impl<'a, T> Unpin for QrPayload<'a, T>
where T: Unpin,

§

impl<'a, T> UnsafeUnpin for QrPayload<'a, T>
where T: UnsafeUnpin,

§

impl<'a, T> UnwindSafe for QrPayload<'a, T>
where T: UnwindSafe,

Blanket Implementations§

Source§

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

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

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

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

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

Source§

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

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, E> Init<T, E> for T

Source§

unsafe fn __init(self, slot: *mut T) -> Result<(), E>

Initializes slot. Read more
Source§

fn chain<F>(self, f: F) -> ChainInit<Self, F, T, E>
where F: FnOnce(&mut T) -> Result<(), E>,

First initializes the value using self then calls the function f with the initialized value. Read more
Source§

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

Source§

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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T, I> IntoFallibleInit<T> for I
where I: Init<T>,

Source§

fn into_fallible<E>(self) -> impl Init<T, E>

Convert the infallible initializer to a fallible one.
Source§

impl<Source, Target> OctetsInto<Target> for Source
where Target: OctetsFrom<Source>,

Source§

type Error = <Target as OctetsFrom<Source>>::Error

Source§

fn try_octets_into( self, ) -> Result<Target, <Source as OctetsInto<Target>>::Error>

Performs the conversion.
Source§

fn octets_into(self) -> Target
where Self::Error: Into<Infallible>,

Performs an infallible conversion.
Source§

impl<T, E> PinInit<T, E> for T

Source§

unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E>

Initializes slot. Read more
Source§

fn pin_chain<F>(self, f: F) -> ChainPinInit<Self, F, T, E>
where F: FnOnce(Pin<&mut T>) -> Result<(), E>,

First initializes the value using self then calls the function f with the initialized value. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

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

Source§

type Error = Infallible

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

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

Performs the conversion.
Source§

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

Source§

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

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

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

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V