1 //! custom types to be imported by hci packet pdl
2 //! (since hci depends on the packet library, we need to split these out)
3 
4 use std::convert::TryFrom;
5 use std::fmt;
6 
7 /// Signal for "empty" address
8 pub const EMPTY_ADDRESS: Address = Address { bytes: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00] };
9 /// Signal for "any" address
10 pub const ANY_ADDRESS: Address = Address { bytes: [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF] };
11 
12 /// A Bluetooth address
13 #[derive(Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)]
14 pub struct Address {
15     /// the actual bytes representing this address
16     pub bytes: [u8; 6],
17 }
18 
19 impl Address {
20     /// whether this address is empty
is_empty(&self) -> bool21     pub fn is_empty(&self) -> bool {
22         *self == EMPTY_ADDRESS
23     }
24 }
25 
26 impl fmt::Display for Address {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result27     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28         write!(
29             f,
30             "{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}",
31             self.bytes[5],
32             self.bytes[4],
33             self.bytes[3],
34             self.bytes[2],
35             self.bytes[1],
36             self.bytes[0]
37         )
38     }
39 }
40 
41 /// When you parse an address and it's not valid
42 #[derive(Debug, Clone)]
43 pub struct InvalidAddressError;
44 
45 impl TryFrom<&[u8]> for Address {
46     type Error = InvalidAddressError;
47 
try_from(slice: &[u8]) -> Result<Self, Self::Error>48     fn try_from(slice: &[u8]) -> Result<Self, Self::Error> {
49         if slice.len() == 6 {
50             match <[u8; 6]>::try_from(slice) {
51                 Ok(bytes) => Ok(Self { bytes }),
52                 Err(_) => Err(InvalidAddressError),
53             }
54         } else {
55             Err(InvalidAddressError)
56         }
57     }
58 }
59 
60 impl From<Address> for [u8; 6] {
from(addr: Address) -> [u861     fn from(addr: Address) -> [u8; 6] {
62         addr.bytes
63     }
64 }
65 
66 /// A Bluetooth class of device
67 #[derive(Clone, Eq, Copy, PartialEq, Hash, Ord, PartialOrd, Debug)]
68 pub struct ClassOfDevice {
69     /// the actual bytes representing this class of device
70     pub bytes: [u8; 3],
71 }
72 
73 impl fmt::Display for ClassOfDevice {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result74     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75         write!(
76             f,
77             "{:03X}-{:01X}-{:02X}",
78             ((self.bytes[2] as u16) << 4) | ((self.bytes[1] as u16) >> 4),
79             self.bytes[1] & 0x0F,
80             self.bytes[0]
81         )
82     }
83 }
84 
85 /// When you parse a class of device and it's not valid
86 #[derive(Debug, Clone)]
87 pub struct InvalidClassOfDeviceError;
88 
89 impl TryFrom<&[u8]> for ClassOfDevice {
90     type Error = InvalidClassOfDeviceError;
91 
try_from(slice: &[u8]) -> Result<Self, Self::Error>92     fn try_from(slice: &[u8]) -> Result<Self, Self::Error> {
93         if slice.len() == 3 {
94             match <[u8; 3]>::try_from(slice) {
95                 Ok(bytes) => Ok(Self { bytes }),
96                 Err(_) => Err(InvalidClassOfDeviceError),
97             }
98         } else {
99             Err(InvalidClassOfDeviceError)
100         }
101     }
102 }
103 
104 impl From<ClassOfDevice> for [u8; 3] {
from(cod: ClassOfDevice) -> [u8105     fn from(cod: ClassOfDevice) -> [u8; 3] {
106         cod.bytes
107     }
108 }
109