trouble_host/types/
uuid.rs1use bt_hci::uuid::BluetoothUuid16;
4
5use crate::codec::{Decode, Encode, Error, Type};
6
7#[cfg_attr(feature = "defmt", derive(defmt::Format))]
9#[derive(Debug, PartialEq, Clone)]
10pub enum Uuid {
11 Uuid16([u8; 2]),
13 Uuid128([u8; 16]),
15}
16
17impl From<BluetoothUuid16> for Uuid {
18 fn from(data: bt_hci::uuid::BluetoothUuid16) -> Self {
19 Uuid::Uuid16(data.into())
20 }
21}
22
23impl From<u128> for Uuid {
24 fn from(data: u128) -> Self {
25 Uuid::Uuid128(data.to_le_bytes())
26 }
27}
28
29impl From<[u8; 16]> for Uuid {
30 fn from(data: [u8; 16]) -> Self {
31 Uuid::Uuid128(data)
32 }
33}
34
35impl From<[u8; 2]> for Uuid {
36 fn from(data: [u8; 2]) -> Self {
37 Uuid::Uuid16(data)
38 }
39}
40
41impl From<u16> for Uuid {
42 fn from(data: u16) -> Self {
43 Uuid::Uuid16(data.to_le_bytes())
44 }
45}
46
47impl Uuid {
48 pub const fn new_short(val: u16) -> Self {
50 Self::Uuid16(val.to_le_bytes())
51 }
52
53 pub const fn new_long(val: [u8; 16]) -> Self {
55 Self::Uuid128(val)
56 }
57
58 pub fn bytes(&self, data: &mut [u8]) {
60 match self {
61 Uuid::Uuid16(uuid) => data.copy_from_slice(uuid),
62 Uuid::Uuid128(uuid) => data.copy_from_slice(uuid),
63 }
64 }
65
66 pub fn get_type(&self) -> u8 {
68 match self {
69 Uuid::Uuid16(_) => 0x01,
70 Uuid::Uuid128(_) => 0x02,
71 }
72 }
73
74 pub(crate) fn size(&self) -> usize {
75 match self {
76 Uuid::Uuid16(_) => 6,
77 Uuid::Uuid128(_) => 20,
78 }
79 }
80
81 pub fn as_short(&self) -> u16 {
83 match self {
84 Uuid::Uuid16(data) => u16::from_le_bytes([data[0], data[1]]),
85 _ => panic!("wrong type"),
86 }
87 }
88
89 pub fn as_raw(&self) -> &[u8] {
91 match self {
92 Uuid::Uuid16(uuid) => uuid,
93 Uuid::Uuid128(uuid) => uuid,
94 }
95 }
96}
97
98impl TryFrom<&[u8]> for Uuid {
99 type Error = crate::Error;
100
101 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
102 match value.len() {
103 2 => Ok(Uuid::Uuid16(value.try_into().unwrap())),
105 16 => {
106 let mut bytes = [0; 16];
107 bytes.copy_from_slice(value);
108 Ok(Uuid::Uuid128(bytes))
109 }
110 _ => Err(crate::Error::InvalidUuidLength(value.len())),
111 }
112 }
113}
114
115impl Type for Uuid {
116 fn size(&self) -> usize {
117 self.as_raw().len()
118 }
119}
120
121impl Decode<'_> for Uuid {
122 fn decode(src: &[u8]) -> Result<Self, Error> {
123 if src.len() < 2 {
124 Err(Error::InvalidValue)
125 } else {
126 let val: u16 = u16::from_le_bytes([src[0], src[1]]);
127 if val == 0 {
129 if src.len() < 16 {
130 return Err(Error::InvalidValue);
131 }
132 Ok(Uuid::Uuid128(src[0..16].try_into().map_err(|_| Error::InvalidValue)?))
133 } else {
134 Ok(Uuid::new_short(val))
135 }
136 }
137 }
138}
139
140impl Encode for Uuid {
141 fn encode(&self, dest: &mut [u8]) -> Result<(), Error> {
142 self.bytes(dest);
143 Ok(())
144 }
145}