1 // Copyright 2024, The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 use crate::reader::{Read, Reader};
16 use crate::writer::{Write, Writer};
17
18 /// HCI Event Packet, as defined in Part E - 5.4.4
19 #[derive(Debug)]
20 pub enum Event {
21 /// 7.7.5 Disconnection Complete
22 DisconnectionComplete(DisconnectionComplete),
23 /// 7.7.14 Command Complete
24 CommandComplete(CommandComplete),
25 /// 7.7.15 Command Status
26 CommandStatus(CommandStatus),
27 /// 7.7.19 Number Of Completed Packets
28 NumberOfCompletedPackets(NumberOfCompletedPackets),
29 /// 7.7.65.25 LE CIS Established
30 LeCisEstablished(LeCisEstablished),
31 /// 7.7.65.27 LE Create BIG Complete
32 LeCreateBigComplete(LeCreateBigComplete),
33 /// 7.7.65.28 LE Terminate BIG Complete
34 LeTerminateBigComplete(LeTerminateBigComplete),
35 /// Unknown Event
36 Unknown(Code),
37 }
38
39 impl Event {
40 /// Read an HCI Event packet
from_bytes(data: &[u8]) -> Result<Self, Option<Code>>41 pub fn from_bytes(data: &[u8]) -> Result<Self, Option<Code>> {
42 fn parse_packet(data: &[u8]) -> Option<(Code, Reader)> {
43 let mut r = Reader::new(data);
44 let code = r.read_u8()?;
45 let len = r.read_u8()? as usize;
46
47 let mut r = Reader::new(r.get(len)?);
48 let code = match code {
49 Code::LE_META => Code(Code::LE_META, Some(r.read_u8()?)),
50 _ => Code(code, None),
51 };
52
53 Some((code, r))
54 }
55
56 let Some((code, mut r)) = parse_packet(data) else {
57 return Err(None);
58 };
59 Self::dispatch_read(code, &mut r).ok_or(Some(code))
60 }
61
dispatch_read(code: Code, r: &mut Reader) -> Option<Event>62 fn dispatch_read(code: Code, r: &mut Reader) -> Option<Event> {
63 Some(match code {
64 CommandComplete::CODE => Self::CommandComplete(r.read()?),
65 CommandStatus::CODE => Self::CommandStatus(r.read()?),
66 DisconnectionComplete::CODE => Self::DisconnectionComplete(r.read()?),
67 NumberOfCompletedPackets::CODE => Self::NumberOfCompletedPackets(r.read()?),
68 LeCisEstablished::CODE => Self::LeCisEstablished(r.read()?),
69 LeCreateBigComplete::CODE => Self::LeCreateBigComplete(r.read()?),
70 LeTerminateBigComplete::CODE => Self::LeTerminateBigComplete(r.read()?),
71 code => Self::Unknown(code),
72 })
73 }
74
to_bytes<T: EventCode + Write>(event: &T) -> Vec<u8>75 fn to_bytes<T: EventCode + Write>(event: &T) -> Vec<u8> {
76 let mut w = Writer::new(Vec::with_capacity(2 + 255));
77 w.write_u8(T::CODE.0);
78 w.write_u8(0);
79 if let Some(sub_code) = T::CODE.1 {
80 w.write_u8(sub_code)
81 }
82 w.write(event);
83
84 let mut vec = w.into_vec();
85 vec[1] = (vec.len() - 2).try_into().unwrap();
86 vec
87 }
88 }
89
90 /// Code of HCI Event, as defined in Part E - 5.4.4
91 #[derive(Debug, Clone, Copy, PartialEq)]
92 pub struct Code(u8, Option<u8>);
93
94 impl Code {
95 const LE_META: u8 = 0x3e;
96 }
97
98 /// Define event Code
99 pub trait EventCode {
100 /// Code of the event
101 const CODE: Code;
102 }
103
104 /// Build event from definition
105 pub trait EventToBytes: EventCode + Write {
106 /// Output the HCI Event packet
to_bytes(&self) -> Vec<u8> where Self: Sized + EventCode + Write107 fn to_bytes(&self) -> Vec<u8>
108 where
109 Self: Sized + EventCode + Write;
110 }
111
112 pub use defs::*;
113
114 #[allow(missing_docs)]
115 #[rustfmt::skip]
116 mod defs {
117
118 use super::*;
119 use crate::derive::{Read, Write, EventToBytes};
120 use crate::command::{OpCode, ReturnParameters};
121 use crate::status::Status;
122
123
124 // 7.7.5 Disconnection Complete
125
126 impl EventCode for DisconnectionComplete {
127 const CODE: Code = Code(0x05, None);
128 }
129
130 #[derive(Debug, Read, Write, EventToBytes)]
131 pub struct DisconnectionComplete {
132 pub status: Status,
133 pub connection_handle: u16,
134 pub reason: u8,
135 }
136
137 #[test]
test_disconnection_complete()138 fn test_disconnection_complete() {
139 let dump = [0x05, 0x04, 0x00, 0x60, 0x00, 0x16];
140 let Ok(Event::DisconnectionComplete(e)) = Event::from_bytes(&dump) else { panic!() };
141 assert_eq!(e.status, Status::Success);
142 assert_eq!(e.connection_handle, 0x60);
143 assert_eq!(e.reason, 0x16);
144 assert_eq!(e.to_bytes(), &dump[..]);
145 }
146
147
148 // 7.7.14 Command Complete
149
150 impl EventCode for CommandComplete {
151 const CODE: Code = Code(0x0e, None);
152 }
153
154 #[derive(Debug, Read, Write, EventToBytes)]
155 pub struct CommandComplete {
156 pub num_hci_command_packets: u8,
157 pub return_parameters: ReturnParameters,
158 }
159
160 #[test]
test_command_complete()161 fn test_command_complete() {
162 let dump = [0x0e, 0x04, 0x01, 0x03, 0x0c, 0x00];
163 let Ok(Event::CommandComplete(e)) = Event::from_bytes(&dump) else { panic!() };
164 assert_eq!(e.num_hci_command_packets, 1);
165 assert_eq!(e.to_bytes(), &dump[..]);
166 }
167
168
169 // 7.7.15 Command Status
170
171 impl EventCode for CommandStatus {
172 const CODE: Code = Code(0x0f, None);
173 }
174
175 #[derive(Debug, Read, Write, EventToBytes)]
176 pub struct CommandStatus {
177 pub status: Status,
178 pub num_hci_command_packets: u8,
179 pub opcode: OpCode,
180 }
181
182 #[test]
test_command_status()183 fn test_command_status() {
184 let dump = [0x0f, 0x04, 0x00, 0x01, 0x01, 0x04];
185 let Ok(Event::CommandStatus(e)) = Event::from_bytes(&dump) else { panic!() };
186 assert_eq!(e.status, Status::Success);
187 assert_eq!(e.num_hci_command_packets, 1);
188 assert_eq!(e.opcode, OpCode::from(0x01, 0x001));
189 assert_eq!(e.to_bytes(), &dump[..]);
190 }
191
192
193 // 7.7.19 Number Of Completed Packets
194
195 impl EventCode for NumberOfCompletedPackets {
196 const CODE: Code = Code(0x13, None);
197 }
198
199 #[derive(Debug, Read, Write, EventToBytes)]
200 pub struct NumberOfCompletedPackets {
201 pub handles: Vec<NumberOfCompletedPacketsHandle>,
202 }
203
204 #[derive(Debug, Copy, Clone, Read, Write)]
205 pub struct NumberOfCompletedPacketsHandle {
206 pub connection_handle: u16,
207 pub num_completed_packets: u16,
208 }
209
210 #[test]
test_number_of_completed_packets()211 fn test_number_of_completed_packets() {
212 let dump = [0x13, 0x09, 0x02, 0x40, 0x00, 0x01, 0x00, 0x41, 0x00, 0x01, 0x00];
213 let Ok(Event::NumberOfCompletedPackets(e)) = Event::from_bytes(&dump) else { panic!() };
214 assert_eq!(e.handles.len(), 2);
215 assert_eq!(e.handles[0].connection_handle, 0x40);
216 assert_eq!(e.handles[0].num_completed_packets, 1);
217 assert_eq!(e.handles[1].connection_handle, 0x41);
218 assert_eq!(e.handles[1].num_completed_packets, 1);
219 assert_eq!(e.to_bytes(), &dump[..]);
220 }
221
222
223 // 7.7.65.25 LE CIS Established
224
225 impl EventCode for LeCisEstablished {
226 const CODE: Code = Code(Code::LE_META, Some(0x19));
227 }
228
229 #[derive(Debug, Read, Write, EventToBytes)]
230 pub struct LeCisEstablished {
231 pub status: Status,
232 pub connection_handle: u16,
233 #[N(3)] pub cig_sync_delay: u32,
234 #[N(3)] pub cis_sync_delay: u32,
235 #[N(3)] pub transport_latency_c_to_p: u32,
236 #[N(3)] pub transport_latency_p_to_c: u32,
237 pub phy_c_to_p: u8,
238 pub phy_p_to_c: u8,
239 pub nse: u8,
240 pub bn_c_to_p: u8,
241 pub bn_p_to_c: u8,
242 pub ft_c_to_p: u8,
243 pub ft_p_to_c: u8,
244 pub max_pdu_c_to_p: u16,
245 pub max_pdu_p_to_c: u16,
246 pub iso_interval: u16,
247 }
248
249 #[test]
test_le_cis_established()250 fn test_le_cis_established() {
251 let dump = [
252 0x3e, 0x1d, 0x19, 0x00, 0x60, 0x00, 0x40, 0x2c, 0x00, 0x40, 0x2c, 0x00, 0xd0, 0x8b, 0x01, 0x60,
253 0x7a, 0x00, 0x02, 0x02, 0x06, 0x02, 0x00, 0x05, 0x01, 0x78, 0x00, 0x00, 0x00, 0x10, 0x00 ];
254 let Ok(Event::LeCisEstablished(e)) = Event::from_bytes(&dump) else { panic!() };
255 assert_eq!(e.status, Status::Success);
256 assert_eq!(e.connection_handle, 0x60);
257 assert_eq!(e.cig_sync_delay, 11_328);
258 assert_eq!(e.cis_sync_delay, 11_328);
259 assert_eq!(e.transport_latency_c_to_p, 101_328);
260 assert_eq!(e.transport_latency_p_to_c, 31_328);
261 assert_eq!(e.phy_c_to_p, 0x02);
262 assert_eq!(e.phy_p_to_c, 0x02);
263 assert_eq!(e.nse, 6);
264 assert_eq!(e.bn_c_to_p, 2);
265 assert_eq!(e.bn_p_to_c, 0);
266 assert_eq!(e.ft_c_to_p, 5);
267 assert_eq!(e.ft_p_to_c, 1);
268 assert_eq!(e.max_pdu_c_to_p, 120);
269 assert_eq!(e.max_pdu_p_to_c, 0);
270 assert_eq!(e.iso_interval, 16);
271 assert_eq!(e.to_bytes(), &dump[..]);
272 }
273
274
275 // 7.7.65.27 LE Create BIG Complete
276
277 impl EventCode for LeCreateBigComplete {
278 const CODE: Code = Code(Code::LE_META, Some(0x1b));
279 }
280
281 #[derive(Debug, Read, Write, EventToBytes)]
282 pub struct LeCreateBigComplete {
283 pub status: Status,
284 pub big_handle: u8,
285 #[N(3)] pub big_sync_delay: u32,
286 #[N(3)] pub big_transport_latency: u32,
287 pub phy: u8,
288 pub nse: u8,
289 pub bn: u8,
290 pub pto: u8,
291 pub irc: u8,
292 pub max_pdu: u16,
293 pub iso_interval: u16,
294 pub bis_handles: Vec<u16>,
295 }
296
297 #[test]
test_le_create_big_complete()298 fn test_le_create_big_complete() {
299 let dump = [
300 0x3e, 0x17, 0x1b, 0x00, 0x00, 0x46, 0x50, 0x00, 0x66, 0x9e, 0x00, 0x02, 0x0f, 0x03, 0x00, 0x05,
301 0x78, 0x00, 0x18, 0x00, 0x02, 0x00, 0x04, 0x01, 0x04
302 ];
303 let Ok(Event::LeCreateBigComplete(e)) = Event::from_bytes(&dump) else { panic!() };
304 assert_eq!(e.status, Status::Success);
305 assert_eq!(e.big_handle, 0x00);
306 assert_eq!(e.big_sync_delay, 20_550);
307 assert_eq!(e.big_transport_latency, 40_550);
308 assert_eq!(e.phy, 0x02);
309 assert_eq!(e.nse, 15);
310 assert_eq!(e.bn, 3);
311 assert_eq!(e.pto, 0);
312 assert_eq!(e.irc, 5);
313 assert_eq!(e.max_pdu, 120);
314 assert_eq!(e.iso_interval, 24);
315 assert_eq!(e.bis_handles.len(), 2);
316 assert_eq!(e.bis_handles[0], 0x400);
317 assert_eq!(e.bis_handles[1], 0x401);
318 assert_eq!(e.to_bytes(), &dump[..]);
319 }
320
321
322 // 7.7.65.28 LE Terminate BIG Complete
323
324 impl EventCode for LeTerminateBigComplete {
325 const CODE: Code = Code(Code::LE_META, Some(0x1c));
326 }
327
328 #[derive(Debug, Read, Write, EventToBytes)]
329 pub struct LeTerminateBigComplete {
330 pub big_handle: u8,
331 pub reason: u8,
332 }
333
334 #[test]
test_le_terminate_big_complete()335 fn test_le_terminate_big_complete() {
336 let dump = [0x3e, 0x03, 0x1c, 0x00, 0x16];
337 let Ok(Event::LeTerminateBigComplete(e)) = Event::from_bytes(&dump) else { panic!() };
338 assert_eq!(e.big_handle, 0x00);
339 assert_eq!(e.reason, 0x16);
340 assert_eq!(e.to_bytes(), &dump[..]);
341 }
342
343 }
344