awdl_frame_parser/tlvs/sync_elect/
election_parameters_v2_tlv.rs

1use mac_parser::MACAddress;
2use scroll::{
3    ctx::{MeasureWith, TryFromCtx, TryIntoCtx},
4    Endian, Pread, Pwrite,
5};
6
7use crate::tlvs::{AWDLTLVType, AwdlTlv};
8
9#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
10/// Another TLV describing the election parameters of the peer.
11pub struct ElectionParametersV2TLV {
12    /// MAC address of the master
13    pub master_address: MACAddress,
14
15    /// MAC address of the peer this peer is syncing to
16    pub sync_address: MACAddress,
17
18    /// Counter value of the master
19    pub master_counter: u32,
20
21    /// Distance to the current master
22    pub distance_to_master: u32,
23
24    /// Metric of the master
25    pub master_metric: u32,
26
27    /// Self metric of the peer
28    pub self_metric: u32,
29
30    /// Always zero, but found in some files.
31    pub election_id: u32,
32
33    /// Self counter of the peer
34    pub self_counter: u32,
35}
36impl ElectionParametersV2TLV {
37    pub const fn size_in_bytes() -> usize {
38        40
39    }
40}
41impl AwdlTlv for ElectionParametersV2TLV {
42    const TLV_TYPE: AWDLTLVType = AWDLTLVType::ElectionParametersV2;
43}
44impl MeasureWith<()> for ElectionParametersV2TLV {
45    fn measure_with(&self, _ctx: &()) -> usize {
46        Self::size_in_bytes()
47    }
48}
49impl<'a> TryFromCtx<'a> for ElectionParametersV2TLV {
50    type Error = scroll::Error;
51    fn try_from_ctx(from: &'a [u8], _ctx: ()) -> Result<(Self, usize), Self::Error> {
52        let mut offset = 0;
53
54        let master_address = MACAddress::new(from.gread(&mut offset)?);
55        let sync_address = MACAddress::new(from.gread(&mut offset)?);
56        let master_counter = from.gread_with(&mut offset, Endian::Little)?;
57        let distance_to_master = from.gread_with(&mut offset, Endian::Little)?;
58        let master_metric = from.gread_with(&mut offset, Endian::Little)?;
59        let self_metric = from.gread_with(&mut offset, Endian::Little)?;
60        let election_id = from.gread_with(&mut offset, Endian::Little)?;
61        offset += 4;
62        let self_counter = from.gread_with(&mut offset, Endian::Little)?;
63        Ok((
64            Self {
65                master_address,
66                sync_address,
67                master_counter,
68                distance_to_master,
69                master_metric,
70                self_metric,
71                election_id,
72                self_counter,
73            },
74            offset,
75        ))
76    }
77}
78impl TryIntoCtx for ElectionParametersV2TLV {
79    type Error = scroll::Error;
80    fn try_into_ctx(self, buf: &mut [u8], _ctx: ()) -> Result<usize, Self::Error> {
81        let mut offset = 0;
82
83        buf.gwrite(self.master_address.as_slice(), &mut offset)?;
84        buf.gwrite(self.sync_address.as_slice(), &mut offset)?;
85        buf.gwrite_with(self.master_counter, &mut offset, Endian::Little)?;
86        buf.gwrite_with(self.distance_to_master, &mut offset, Endian::Little)?;
87        buf.gwrite_with(self.master_metric, &mut offset, Endian::Little)?;
88        buf.gwrite_with(self.self_metric, &mut offset, Endian::Little)?;
89        buf.gwrite_with(self.election_id, &mut offset, Endian::Little)?;
90        offset += 4;
91        buf.gwrite_with(self.self_counter, &mut offset, Endian::Little)?;
92
93        Ok(offset)
94    }
95}
96#[cfg(test)]
97#[test]
98fn test_election_parameters_v2_tlv() {
99    let bytes = &include_bytes!("../../../test_bins/election_parameters_v2_tlv.bin")[3..];
100
101    let election_parameters_v2_tlv = bytes.pread::<ElectionParametersV2TLV>(0).unwrap();
102
103    assert_eq!(
104        election_parameters_v2_tlv,
105        ElectionParametersV2TLV {
106            master_address: [0xce, 0x21, 0x1f, 0x62, 0x21, 0x22].into(),
107            sync_address: [0xce, 0x21, 0x1f, 0x62, 0x21, 0x22].into(),
108            master_counter: 960,
109            distance_to_master: 1,
110            master_metric: 650,
111            self_metric: 650,
112            election_id: 0,
113            self_counter: 30,
114        }
115    );
116
117    let mut buf = [0x00; ElectionParametersV2TLV::size_in_bytes()];
118    buf.pwrite(election_parameters_v2_tlv, 0).unwrap();
119
120    assert_eq!(buf, bytes);
121}