awdl_frame_parser/tlvs/sync_elect/channel_sequence_tlv/
mod.rs1pub mod channel;
2pub mod channel_sequence;
3
4use core::num::NonZeroU8;
5
6use channel::*;
7use channel_sequence::*;
8
9use scroll::{
10 ctx::{MeasureWith, TryFromCtx, TryIntoCtx},
11 Pread, Pwrite,
12};
13
14use crate::tlvs::{AWDLTLVType, AwdlTlv};
15
16#[derive(Clone, Debug, PartialEq, Eq)]
17pub struct ChannelSequenceTLV {
18 pub step_count: NonZeroU8,
20
21 pub channel_sequence: ChannelSequence,
23}
24impl AwdlTlv for ChannelSequenceTLV {
25 const TLV_TYPE: AWDLTLVType = AWDLTLVType::ChannelSequence;
26}
27impl Default for ChannelSequenceTLV {
28 fn default() -> Self {
29 ChannelSequenceTLV {
30 step_count: NonZeroU8::new(3).unwrap(),
31 channel_sequence: Default::default(),
32 }
33 }
34}
35impl MeasureWith<()> for ChannelSequenceTLV {
36 fn measure_with(&self, ctx: &()) -> usize {
37 9 + self.channel_sequence.measure_with(ctx)
38 }
39}
40impl<'a> TryFromCtx<'a> for ChannelSequenceTLV {
41 type Error = scroll::Error;
42 fn try_from_ctx(from: &'a [u8], _ctx: ()) -> Result<(Self, usize), Self::Error> {
43 let mut offset = 0;
44
45 let channel_count = from.gread::<u8>(&mut offset)? + 1;
46 if channel_count != 16 {
47 return Err(scroll::Error::BadInput {
48 size: offset,
49 msg: "Channel sequence length wasn't 16.",
50 });
51 }
52 let channel_encoding = ChannelEncoding::from_bits(from.gread(&mut offset)?);
53 offset += 1; let step_count = NonZeroU8::new(from.gread::<u8>(&mut offset)?.checked_add(1).ok_or(
55 scroll::Error::BadInput {
56 size: offset,
57 msg: "step_count caused overflow",
58 },
59 )?)
60 .unwrap();
61 offset += 2;
62 let channel_sequence = from.gread_with(&mut offset, channel_encoding)?;
63
64 Ok((
65 Self {
66 step_count,
67 channel_sequence,
68 },
69 offset,
70 ))
71 }
72}
73impl TryIntoCtx for ChannelSequenceTLV {
74 type Error = scroll::Error;
75 fn try_into_ctx(self, buf: &mut [u8], _ctx: ()) -> Result<usize, Self::Error> {
76 let mut offset = 0;
77
78 buf.gwrite(16u8 - 1, &mut offset)?;
79 buf.gwrite(
80 self.channel_sequence.channel_encoding().into_bits(),
81 &mut offset,
82 )?;
83 offset += 1;
84 buf.gwrite(self.step_count.get() - 1, &mut offset)?;
85 buf.gwrite(0xffffu16, &mut offset)?;
86 buf.gwrite(self.channel_sequence, &mut offset)?;
87 offset += 3;
88 Ok(offset)
89 }
90}
91#[cfg(test)]
92#[test]
93fn test_channel_sequence_tlv() {
94 use alloc::vec;
95
96 let bytes = &include_bytes!("../../../../test_bins/channel_sequence_tlv.bin")[3..];
97
98 let channel_sequence_tlv = bytes.pread::<ChannelSequenceTLV>(0).unwrap();
99 assert_eq!(
100 channel_sequence_tlv,
101 ChannelSequenceTLV {
102 step_count: NonZeroU8::new(4).unwrap(),
103 channel_sequence: ChannelSequence::fixed_channel_sequence(Channel::OpClass {
104 channel: 0x6,
105 opclass: 0x51
106 },),
107 }
108 );
109 let mut buf = vec![0x00; channel_sequence_tlv.measure_with(&())];
110 buf.as_mut_slice().pwrite(channel_sequence_tlv, 0).unwrap();
111 assert_eq!(buf, bytes);
112}