Remove heapless::String from QR API

This commit is contained in:
ivmarkov 2023-04-29 17:20:55 +00:00
parent 2a2bdab9c5
commit 5fc3d2d510
5 changed files with 70 additions and 42 deletions

View file

@ -54,8 +54,8 @@ fn main() -> Result<(), impl Error> {
device_name: "OnOff Light",
};
let mut mdns = matter::mdns::astro::AstroMdns::new()?;
//let mut mdns = matter::mdns::libmdns::LibMdns::new()?;
//let mut mdns = matter::mdns::astro::AstroMdns::new()?;
let mut mdns = matter::mdns::libmdns::LibMdns::new()?;
//let mut mdns = matter::mdns::DummyMdns {};
let matter = Matter::new_default(&dev_info, &mut mdns, matter::transport::udp::MATTER_PORT);
@ -77,7 +77,7 @@ fn main() -> Result<(), impl Error> {
matter.load_fabrics(data)?;
}
matter.start::<4096>(
matter.start(
CommissioningData {
// TODO: Hard-coded for now
verifier: VerifierData::new_with_pw(123456, *matter.borrow()),

View file

@ -116,19 +116,15 @@ impl<'a> Matter<'a> {
self.acl_mgr.borrow_mut().store(buf)
}
pub fn start<const N: usize>(
&self,
dev_comm: CommissioningData,
buf: &mut [u8],
) -> Result<(), Error> {
pub fn start(&self, dev_comm: CommissioningData, buf: &mut [u8]) -> Result<(), Error> {
let open_comm_window = self.fabric_mgr.borrow().is_empty();
if open_comm_window {
print_pairing_code_and_qr::<N>(
print_pairing_code_and_qr(
self.dev_det,
&dev_comm,
DiscoveryCapabilities::default(),
buf,
);
)?;
self.pase_mgr.borrow_mut().enable_pase_session(
dev_comm.verifier,

View file

@ -19,7 +19,7 @@ use core::fmt::Write;
use super::*;
pub(super) fn compute_pairing_code(comm_data: &CommissioningData) -> heapless::String<32> {
pub fn compute_pairing_code(comm_data: &CommissioningData) -> heapless::String<32> {
// 0: no Vendor ID and Product ID present in Manual Pairing Code
const VID_PID_PRESENT: u8 = 0;

View file

@ -31,7 +31,7 @@ use crate::{
use self::{
code::{compute_pairing_code, pretty_print_pairing_code},
qr::{payload_base38_representation, print_qr_code, QrSetupPayload},
qr::{compute_qr_code, print_qr_code},
};
pub struct DiscoveryCapabilities {
@ -81,19 +81,19 @@ impl DiscoveryCapabilities {
}
/// Prepares and prints the pairing code and the QR code for easy pairing.
pub fn print_pairing_code_and_qr<const N: usize>(
pub fn print_pairing_code_and_qr(
dev_det: &BasicInfoConfig,
comm_data: &CommissioningData,
discovery_capabilities: DiscoveryCapabilities,
buf: &mut [u8],
) {
) -> Result<(), Error> {
let pairing_code = compute_pairing_code(comm_data);
let qr_code_data = QrSetupPayload::new(dev_det, comm_data, discovery_capabilities);
let data_str =
payload_base38_representation::<N>(&qr_code_data, buf).expect("Failed to encode");
let qr_code = compute_qr_code(dev_det, comm_data, discovery_capabilities, buf)?;
pretty_print_pairing_code(&pairing_code);
print_qr_code(&data_str);
print_qr_code(&qr_code);
Ok(())
}
pub(self) fn passwd_from_comm_data(comm_data: &CommissioningData) -> u32 {

View file

@ -253,20 +253,24 @@ pub enum CommissionningFlowType {
Custom = 2,
}
pub(super) fn payload_base38_representation<const N: usize>(
pub(super) fn payload_base38_representation<'a>(
payload: &QrSetupPayload,
buf: &mut [u8],
) -> Result<heapless::String<N>, Error> {
buf: &'a mut [u8],
) -> Result<&'a str, Error> {
if payload.is_valid() {
let (bits_buf, tlv_buf) = if payload.has_tlv() {
let (bits_buf, tlv_buf) = buf.split_at_mut(buf.len() / 2);
let (str_buf, bits_buf, tlv_buf) = if payload.has_tlv() {
let (str_buf, buf) = buf.split_at_mut(buf.len() / 3 * 2);
(bits_buf, Some(tlv_buf))
let (bits_buf, tlv_buf) = buf.split_at_mut(buf.len() / 3);
(str_buf, bits_buf, Some(tlv_buf))
} else {
(buf, None)
let (str_buf, buf) = buf.split_at_mut(buf.len() / 3 * 2);
(str_buf, buf, None)
};
payload_base38_representation_with_tlv(payload, bits_buf, tlv_buf)
payload_base38_representation_with_tlv(payload, str_buf, bits_buf, tlv_buf)
} else {
Err(ErrorCode::InvalidArgument.into())
}
@ -315,16 +319,16 @@ fn estimate_struct_overhead(first_field_size: usize) -> usize {
first_field_size + 4 + 2
}
pub(super) fn print_qr_code(qr_data: &str) {
info!("QR Code: {}", qr_data);
pub(super) fn print_qr_code(qr_code: &str) {
info!("QR Code: {}", qr_code);
#[cfg(feature = "std")]
{
use qrcode::{render::unicode, QrCode, Version};
let needed_version = compute_qr_version(qr_data);
let needed_version = compute_qr_version(qr_code);
let code =
QrCode::with_version(qr_data, Version::Normal(needed_version), qrcode::EcLevel::M)
QrCode::with_version(qr_code, Version::Normal(needed_version), qrcode::EcLevel::M)
.unwrap();
let image = code
.render::<unicode::Dense1x2>()
@ -336,6 +340,16 @@ pub(super) fn print_qr_code(qr_data: &str) {
}
}
pub fn compute_qr_code<'a>(
dev_det: &BasicInfoConfig,
comm_data: &CommissioningData,
discovery_capabilities: DiscoveryCapabilities,
buf: &'a mut [u8],
) -> Result<&'a str, Error> {
let qr_code_data = QrSetupPayload::new(dev_det, comm_data, discovery_capabilities);
payload_base38_representation(&qr_code_data, buf)
}
fn compute_qr_version(qr_data: &str) -> i16 {
match qr_data.len() {
0..=38 => 2,
@ -375,11 +389,12 @@ fn populate_bits(
Ok(())
}
fn payload_base38_representation_with_tlv<const N: usize>(
fn payload_base38_representation_with_tlv<'a>(
payload: &QrSetupPayload,
str_buf: &'a mut [u8],
bits_buf: &mut [u8],
tlv_buf: Option<&mut [u8]>,
) -> Result<heapless::String<N>, Error> {
) -> Result<&'a str, Error> {
let tlv_data = if let Some(tlv_buf) = tlv_buf {
Some(generate_tlv_from_optional_data(payload, tlv_buf)?)
} else {
@ -388,13 +403,30 @@ fn payload_base38_representation_with_tlv<const N: usize>(
let bits = generate_bit_set(payload, bits_buf, tlv_data)?;
let mut base38_encoded: heapless::String<N> = "MT:".into();
let prefix = "MT:";
for c in base38::encode(bits) {
base38_encoded.push(c).map_err(|_| ErrorCode::NoSpace)?;
if str_buf.len() < prefix.as_bytes().len() {
Err(ErrorCode::NoSpace)?;
}
Ok(base38_encoded)
str_buf[..prefix.as_bytes().len()].copy_from_slice(prefix.as_bytes());
let mut offset = prefix.len();
for c in base38::encode(bits) {
let mut char_buf = [0; 4];
let str = c.encode_utf8(&mut char_buf);
if str_buf.len() - offset < str.as_bytes().len() {
Err(ErrorCode::NoSpace)?;
}
str_buf[offset..offset + str.as_bytes().len()].copy_from_slice(str.as_bytes());
offset += str.as_bytes().len();
}
Ok(core::str::from_utf8(&str_buf[..offset])?)
}
fn generate_tlv_from_optional_data<'a>(
@ -557,8 +589,8 @@ mod tests {
let disc_cap = DiscoveryCapabilities::new(false, true, false);
let qr_code_data = QrSetupPayload::new(&dev_det, &comm_data, disc_cap);
let mut buf = [0; 1024];
let data_str = payload_base38_representation::<128>(&qr_code_data, &mut buf)
.expect("Failed to encode");
let data_str =
payload_base38_representation(&qr_code_data, &mut buf).expect("Failed to encode");
assert_eq!(data_str, QR_CODE)
}
@ -580,8 +612,8 @@ mod tests {
let disc_cap = DiscoveryCapabilities::new(true, false, false);
let qr_code_data = QrSetupPayload::new(&dev_det, &comm_data, disc_cap);
let mut buf = [0; 1024];
let data_str = payload_base38_representation::<128>(&qr_code_data, &mut buf)
.expect("Failed to encode");
let data_str =
payload_base38_representation(&qr_code_data, &mut buf).expect("Failed to encode");
assert_eq!(data_str, QR_CODE)
}
@ -626,8 +658,8 @@ mod tests {
.expect("Failed to add optional data");
let mut buf = [0; 1024];
let data_str = payload_base38_representation::<{ QR_CODE.len() }>(&qr_code_data, &mut buf)
.expect("Failed to encode");
let data_str =
payload_base38_representation(&qr_code_data, &mut buf).expect("Failed to encode");
assert_eq!(data_str, QR_CODE)
}
}