• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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