awdl_frame_parser/tlvs/sync_elect/
election_parameters_tlv.rs1use mac_parser::MACAddress;
2use scroll::{
3 ctx::{MeasureWith, SizeWith, TryFromCtx, TryIntoCtx},
4 Endian, Pread, Pwrite,
5};
6
7use crate::tlvs::{AWDLTLVType, AwdlTlv};
8
9#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
10pub struct ElectionParametersTLV {
12 pub flags: u8,
14
15 pub id: u16,
17
18 pub distance_to_master: u8,
20
21 pub master_address: MACAddress,
23
24 pub master_metric: u32,
26
27 pub self_metric: u32,
29}
30impl ElectionParametersTLV {
31 pub const fn size_in_bytes() -> usize {
32 21
33 }
34}
35impl AwdlTlv for ElectionParametersTLV {
36 const TLV_TYPE: AWDLTLVType = AWDLTLVType::ElectionParameters;
37}
38impl SizeWith for ElectionParametersTLV {
39 fn size_with(_ctx: &()) -> usize {
40 Self::size_in_bytes()
41 }
42}
43impl MeasureWith<()> for ElectionParametersTLV {
44 fn measure_with(&self, _ctx: &()) -> usize {
45 Self::size_in_bytes()
46 }
47}
48impl<'a> TryFromCtx<'a> for ElectionParametersTLV {
49 type Error = scroll::Error;
50 fn try_from_ctx(from: &'a [u8], _ctx: ()) -> Result<(Self, usize), Self::Error> {
51 let mut offset = 0;
52
53 let flags = from.gread(&mut offset)?;
54 let id = from.gread_with(&mut offset, Endian::Little)?;
55 let distance_to_master = from.gread(&mut offset)?;
56 offset += 1;
57 let master_address = MACAddress::new(from.gread(&mut offset)?);
58 let master_metric = from.gread_with(&mut offset, Endian::Little)?;
59 let self_metric = from.gread_with(&mut offset, Endian::Little)?;
60
61 offset += 2;
62
63 Ok((
64 Self {
65 flags,
66 id,
67 distance_to_master,
68 master_address,
69 master_metric,
70 self_metric,
71 },
72 offset,
73 ))
74 }
75}
76impl TryIntoCtx for ElectionParametersTLV {
77 type Error = scroll::Error;
78 fn try_into_ctx(self, buf: &mut [u8], _ctx: ()) -> Result<usize, Self::Error> {
79 let mut offset = 0;
80 buf.gwrite(self.flags, &mut offset)?;
81 buf.gwrite_with(self.id, &mut offset, Endian::Little)?;
82 buf.gwrite(self.distance_to_master, &mut offset)?;
83 offset += 1;
84 buf.gwrite(self.master_address.as_slice(), &mut offset)?;
85 buf.gwrite_with(self.master_metric, &mut offset, Endian::Little)?;
86 buf.gwrite_with(self.self_metric, &mut offset, Endian::Little)?;
87
88 offset += 2;
89
90 Ok(offset)
91 }
92}
93
94#[cfg(test)]
95#[test]
96fn test_election_parameters_tlv() {
97 let bytes = &include_bytes!("../../../test_bins/election_parameters_tlv.bin")[3..];
98
99 let election_parameters_tlv = bytes.pread::<ElectionParametersTLV>(0).unwrap();
100
101 assert_eq!(
102 election_parameters_tlv,
103 ElectionParametersTLV {
104 flags: 0x00,
105 id: 0x00,
106 distance_to_master: 0x02,
107 master_address: [0x3a, 0xb4, 0x08, 0x6e, 0x66, 0x3d].into(),
108 master_metric: 541,
109 self_metric: 60
110 }
111 );
112 let mut buf = [0x00; ElectionParametersTLV::size_in_bytes()];
113 buf.pwrite(election_parameters_tlv, 0).unwrap();
114 assert_eq!(buf, bytes);
115}