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