awdl_frame_parser/tlvs/
version.rs

1use crate::common::AWDLVersion;
2use macro_bits::serializable_enum;
3use scroll::{
4    ctx::{MeasureWith, TryFromCtx, TryIntoCtx},
5    Pread, Pwrite,
6};
7
8use super::{AWDLTLVType, AwdlTlv};
9
10serializable_enum! {
11    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
12    /// The device class of the peer.
13    pub enum AWDLDeviceClass: u8 {
14        /// A macOS X device.
15        #[default]
16        MacOS => 0x1,
17
18        /// A iOS device.
19        IOS => 0x2,
20
21        /// A watchOS device.
22        WatchOS => 0x4,
23
24        /// A tvOS device.
25        TVOS => 0x8
26    }
27}
28
29#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
30/// A TLV containing the actual version of the AWDL protocol.
31pub struct VersionTLV {
32    ///  The AWDL protocol version.
33    pub version: AWDLVersion,
34
35    /// The device class.
36    pub device_class: AWDLDeviceClass,
37}
38impl AwdlTlv for VersionTLV {
39    const TLV_TYPE: AWDLTLVType = AWDLTLVType::Version;
40}
41impl MeasureWith<()> for VersionTLV {
42    fn measure_with(&self, _ctx: &()) -> usize {
43        2
44    }
45}
46impl<'a> TryFromCtx<'a> for VersionTLV {
47    type Error = scroll::Error;
48    fn try_from_ctx(from: &'a [u8], _ctx: ()) -> Result<(Self, usize), Self::Error> {
49        let mut offset = 0;
50        let version = AWDLVersion::from_bits(from.gread(&mut offset)?);
51        let device_class = AWDLDeviceClass::from_bits(from.gread(&mut offset)?);
52        Ok((
53            Self {
54                version,
55                device_class,
56            },
57            offset,
58        ))
59    }
60}
61impl TryIntoCtx for VersionTLV {
62    type Error = scroll::Error;
63    fn try_into_ctx(self, buf: &mut [u8], _ctx: ()) -> Result<usize, Self::Error> {
64        let mut offset = 0;
65        buf.gwrite(self.version.into_bits(), &mut offset)?;
66        buf.gwrite(self.device_class.into_bits(), &mut offset)?;
67        Ok(offset)
68    }
69}
70//impl_tlv_conversion!(true, VersionTLV, TLVType::Version, 2);
71
72#[cfg(test)]
73#[test]
74fn test_version_tlv() {
75    let bytes = [0x3e, 0x01];
76
77    let version_tlv = bytes.pread::<VersionTLV>(0).unwrap();
78
79    assert_eq!(
80        version_tlv,
81        VersionTLV {
82            version: AWDLVersion {
83                major: 3,
84                minor: 14
85            },
86            device_class: AWDLDeviceClass::MacOS,
87        }
88    );
89    let mut buf = [0x00; 2];
90    buf.pwrite(version_tlv, 0).unwrap();
91    assert_eq!(buf, bytes);
92}