rs_matter/pairing/
code.rs1use core::fmt::Write;
19
20use verhoeff::Verhoeff;
21
22use crate::BasicCommData;
23
24impl BasicCommData {
25 pub fn compute_pairing_code(&self) -> heapless::String<11> {
27 const VID_PID_PRESENT: u8 = 0;
29
30 let BasicCommData {
31 password,
32 discriminator,
33 ..
34 } = self;
35
36 let password = u32::from_le_bytes(*password.access());
37 let mut digits = heapless::String::<10>::new();
38 write_unwrap!(
39 &mut digits,
40 "{}{:0>5}{:0>4}",
41 (VID_PID_PRESENT << 2) | (discriminator >> 10) as u8,
42 ((discriminator & 0x300) << 6) | (password & 0x3FFF) as u16,
43 password >> 14
44 );
45
46 let mut final_digits = heapless::String::<11>::new();
47 write_unwrap!(
48 &mut final_digits,
49 "{}{}",
50 digits,
51 digits.calculate_verhoeff_check_digit()
52 );
53
54 final_digits
55 }
56
57 pub fn compute_pretty_pairing_code(&self) -> heapless::String<13> {
60 let pairing_code = self.compute_pairing_code();
61
62 let mut pretty = heapless::String::new();
63 unwrap!(pretty.push_str(&pairing_code[..4]));
64 unwrap!(pretty.push('-'));
65 unwrap!(pretty.push_str(&pairing_code[4..8]));
66 unwrap!(pretty.push('-'));
67 unwrap!(pretty.push_str(&pairing_code[8..]));
68
69 pretty
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76
77 #[test]
78 fn can_compute_pairing_code() {
79 let comm_data = BasicCommData {
80 password: 123456_u32.to_le_bytes().into(),
81 discriminator: 250,
82 };
83 let pairing_code = comm_data.compute_pairing_code();
84 assert_eq!(pairing_code, "00876800071");
85
86 let comm_data = BasicCommData {
87 password: 34567890_u32.to_le_bytes().into(),
88 discriminator: 2976,
89 };
90 let pairing_code = comm_data.compute_pairing_code();
91 assert_eq!(pairing_code, "26318621095");
92 }
93}