diff --git a/matter/src/pairing/qr.rs b/matter/src/pairing/qr.rs index dce8229..7dbf47b 100644 --- a/matter/src/pairing/qr.rs +++ b/matter/src/pairing/qr.rs @@ -373,13 +373,10 @@ fn generate_tlv_from_optional_data( let data = payload.get_all_optional_data(); for (tag, value) in data { - println!("tag: {tag:?}"); match &value.data { QRCodeInfoType::String(data) => tw.utf8(TagType::Context(*tag), data.as_bytes())?, - // todo: check i32 -> u32?? - QRCodeInfoType::Int32(data) => tw.u32(TagType::Context(*tag), *data as u32)?, - // todo: check i64 -> u64?? - QRCodeInfoType::Int64(data) => tw.u64(TagType::Context(*tag), *data as u64)?, + QRCodeInfoType::Int32(data) => tw.i32(TagType::Context(*tag), *data)?, + QRCodeInfoType::Int64(data) => tw.i64(TagType::Context(*tag), *data)?, QRCodeInfoType::UInt32(data) => tw.u32(TagType::Context(*tag), *data)?, QRCodeInfoType::UInt64(data) => tw.u64(TagType::Context(*tag), *data)?, } @@ -406,7 +403,6 @@ fn generate_bit_set( }; if bits.len() * 8 < total_payload_size_in_bits { - println!("{:?} vs {total_payload_size_in_bits}", bits.len() * 8); return Err(Error::BufferTooSmall); }; @@ -562,12 +558,13 @@ mod tests { #[test] fn can_base38_encode_with_optional_data() { - const QR_CODE: &str = "MT:-24J0AFN00KA064IJ3P0IXZB0DK5N1K8SQ1RYCU1UXH34YY0V3KY.O39C40"; + const QR_CODE: &str = + "MT:-24J0AFN00KA064IJ3P0IXZB0DK5N1K8SQ1RYCU1UXH34YY0V3KY.O3DKN440F710Q940"; const OPTIONAL_DEFAULT_STRING_TAG: u8 = 0x82; // Vendor "test" tag const OPTIONAL_DEFAULT_STRING_VALUE: &str = "myData"; - // const OPTIONAL_DEFAULT_INT_TAG: u8 = 0x83; // Vendor "test" tag - // const OPTIONAL_DEFAULT_INT_VALUE: u32 = 12; + const OPTIONAL_DEFAULT_INT_TAG: u8 = 0x83; // Vendor "test" tag + const OPTIONAL_DEFAULT_INT_VALUE: i32 = 65550; let comm_data = CommissioningData { passwd: 20202021, @@ -593,13 +590,14 @@ mod tests { ) .expect("Failed to add optional data"); - // todo: check why u32 is not accepted by 'chip-tool payload parse-setup-payload' - // qr_code_data - // .add_optional_vendor_data( - // OPTIONAL_DEFAULT_INT_TAG, - // QRCodeInfoType::UInt32(OPTIONAL_DEFAULT_INT_VALUE), - // ) - // .expect("Failed to add optional data"); + // todo: check why unsigned ints are not accepted by 'chip-tool payload parse-setup-payload' + + qr_code_data + .add_optional_vendor_data( + OPTIONAL_DEFAULT_INT_TAG, + QRCodeInfoType::Int32(OPTIONAL_DEFAULT_INT_VALUE), + ) + .expect("Failed to add optional data"); let data_str = payload_base38_representation(&qr_code_data).expect("Failed to encode"); assert_eq!(data_str, QR_CODE) diff --git a/matter/src/tlv/writer.rs b/matter/src/tlv/writer.rs index 9cefb0f..7459aa3 100644 --- a/matter/src/tlv/writer.rs +++ b/matter/src/tlv/writer.rs @@ -95,6 +95,15 @@ impl<'a, 'b> TLVWriter<'a, 'b> { self.buf.le_u8(data) } + pub fn i16(&mut self, tag_type: TagType, data: i16) -> Result<(), Error> { + if data >= i8::MIN as i16 && data <= i8::MAX as i16 { + self.i8(tag_type, data as i8) + } else { + self.put_control_tag(tag_type, WriteElementType::S16)?; + self.buf.le_i16(data) + } + } + pub fn u16(&mut self, tag_type: TagType, data: u16) -> Result<(), Error> { if data <= 0xff { self.u8(tag_type, data as u8) @@ -104,6 +113,17 @@ impl<'a, 'b> TLVWriter<'a, 'b> { } } + pub fn i32(&mut self, tag_type: TagType, data: i32) -> Result<(), Error> { + if data >= i8::MIN as i32 && data <= i8::MAX as i32 { + self.i8(tag_type, data as i8) + } else if data >= i16::MIN as i32 && data <= i16::MAX as i32 { + self.i16(tag_type, data as i16) + } else { + self.put_control_tag(tag_type, WriteElementType::S32)?; + self.buf.le_i32(data) + } + } + pub fn u32(&mut self, tag_type: TagType, data: u32) -> Result<(), Error> { if data <= 0xff { self.u8(tag_type, data as u8) @@ -115,6 +135,19 @@ impl<'a, 'b> TLVWriter<'a, 'b> { } } + pub fn i64(&mut self, tag_type: TagType, data: i64) -> Result<(), Error> { + if data >= i8::MIN as i64 && data <= i8::MAX as i64 { + self.i8(tag_type, data as i8) + } else if data >= i16::MIN as i64 && data <= i16::MAX as i64 { + self.i16(tag_type, data as i16) + } else if data >= i32::MIN as i64 && data <= i32::MAX as i64 { + self.i32(tag_type, data as i32) + } else { + self.put_control_tag(tag_type, WriteElementType::S64)?; + self.buf.le_i64(data) + } + } + pub fn u64(&mut self, tag_type: TagType, data: u64) -> Result<(), Error> { if data <= 0xff { self.u8(tag_type, data as u8) diff --git a/matter/src/utils/writebuf.rs b/matter/src/utils/writebuf.rs index b82bb02..00c5e88 100644 --- a/matter/src/utils/writebuf.rs +++ b/matter/src/utils/writebuf.rs @@ -131,6 +131,11 @@ impl<'a> WriteBuf<'a> { LittleEndian::write_u16(&mut x.buf[x.end..], data); }) } + pub fn le_i16(&mut self, data: i16) -> Result<(), Error> { + self.append_with(2, |x| { + LittleEndian::write_i16(&mut x.buf[x.end..], data); + }) + } pub fn le_u32(&mut self, data: u32) -> Result<(), Error> { self.append_with(4, |x| { @@ -138,12 +143,24 @@ impl<'a> WriteBuf<'a> { }) } + pub fn le_i32(&mut self, data: i32) -> Result<(), Error> { + self.append_with(4, |x| { + LittleEndian::write_i32(&mut x.buf[x.end..], data); + }) + } + pub fn le_u64(&mut self, data: u64) -> Result<(), Error> { self.append_with(8, |x| { LittleEndian::write_u64(&mut x.buf[x.end..], data); }) } + pub fn le_i64(&mut self, data: i64) -> Result<(), Error> { + self.append_with(8, |x| { + LittleEndian::write_i64(&mut x.buf[x.end..], data); + }) + } + pub fn le_uint(&mut self, nbytes: usize, data: u64) -> Result<(), Error> { self.append_with(nbytes, |x| { LittleEndian::write_uint(&mut x.buf[x.end..], data, nbytes);