1 // Copyright 2023 Google LLC
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 pub use pdl_runtime::{Error, Packet};
16 
17 use crate::internal::hci::packets::{Acl, Command, Event, Sco};
18 use pdl_derive::pdl;
19 
20 #[allow(missing_docs, warnings, clippy::all)]
21 #[pdl("src/internal/hci/packets.pdl")]
22 pub mod packets {}
23 #[cfg(test)]
24 mod tests;
25 
26 /// HCI Packet type, prepended to the packet.
27 /// Rootcanal's PDL declaration excludes this from ser/deser and instead is implemented in code.
28 /// To maintain the ability to easily use future versions of their packet PDL, packet type is
29 /// implemented here.
30 #[derive(Debug, PartialEq)]
31 pub(crate) enum PacketType {
32     Command = 0x01,
33     Acl = 0x02,
34     Sco = 0x03,
35     Event = 0x04,
36 }
37 
38 impl TryFrom<u8> for PacketType {
39     type Error = PacketTypeParseError;
40 
try_from(value: u8) -> Result<Self, Self::Error>41     fn try_from(value: u8) -> Result<Self, Self::Error> {
42         match value {
43             0x01 => Ok(PacketType::Command),
44             0x02 => Ok(PacketType::Acl),
45             0x03 => Ok(PacketType::Sco),
46             0x04 => Ok(PacketType::Event),
47             _ => Err(PacketTypeParseError::InvalidPacketType { value }),
48         }
49     }
50 }
51 
52 impl From<PacketType> for u8 {
from(packet_type: PacketType) -> Self53     fn from(packet_type: PacketType) -> Self {
54         match packet_type {
55             PacketType::Command => 0x01,
56             PacketType::Acl => 0x02,
57             PacketType::Sco => 0x03,
58             PacketType::Event => 0x04,
59         }
60     }
61 }
62 
63 /// Allows for smoother interoperability between a [Packet] and a bytes representation of it that
64 /// includes its type as a header
65 pub(crate) trait WithPacketType<T: Packet> {
66     /// Converts the [Packet] into bytes, prefixed with its type
to_vec_with_packet_type(self) -> Vec<u8>67     fn to_vec_with_packet_type(self) -> Vec<u8>;
68 
69     /// Parses a [Packet] out of bytes that are prefixed with the packet's type
parse_with_packet_type(bytes: &[u8]) -> Result<T, PacketTypeParseError>70     fn parse_with_packet_type(bytes: &[u8]) -> Result<T, PacketTypeParseError>;
71 }
72 
73 /// Errors that may arise when parsing a packet that is prefixed with its type
74 #[derive(Debug, PartialEq, thiserror::Error)]
75 pub(crate) enum PacketTypeParseError {
76     #[error("The slice being parsed was empty")]
77     EmptySlice,
78     #[error("Packet type ({value:#X}) is invalid")]
79     InvalidPacketType { value: u8 },
80     #[error("Expected packet type: {expected:?}, but got: {actual:?}")]
81     PacketTypeMismatch {
82         expected: PacketType,
83         actual: PacketType,
84     },
85     #[error("Failed to parse packet after header: {error}")]
86     PacketParse { error: Error },
87 }
88 
89 impl From<Error> for PacketTypeParseError {
from(error: Error) -> Self90     fn from(error: Error) -> Self {
91         Self::PacketParse { error }
92     }
93 }
94 
95 impl WithPacketType<Self> for Command {
to_vec_with_packet_type(self) -> Vec<u8>96     fn to_vec_with_packet_type(self) -> Vec<u8> {
97         prepend_packet_type(PacketType::Command, self)
98     }
99 
parse_with_packet_type(bytes: &[u8]) -> Result<Self, PacketTypeParseError>100     fn parse_with_packet_type(bytes: &[u8]) -> Result<Self, PacketTypeParseError> {
101         parse_with_expected_packet_type(Command::parse, PacketType::Command, bytes)
102     }
103 }
104 
105 impl WithPacketType<Self> for Acl {
to_vec_with_packet_type(self) -> Vec<u8>106     fn to_vec_with_packet_type(self) -> Vec<u8> {
107         prepend_packet_type(PacketType::Acl, self)
108     }
109 
parse_with_packet_type(bytes: &[u8]) -> Result<Self, PacketTypeParseError>110     fn parse_with_packet_type(bytes: &[u8]) -> Result<Self, PacketTypeParseError> {
111         parse_with_expected_packet_type(Acl::parse, PacketType::Acl, bytes)
112     }
113 }
114 
115 impl WithPacketType<Self> for Sco {
to_vec_with_packet_type(self) -> Vec<u8>116     fn to_vec_with_packet_type(self) -> Vec<u8> {
117         prepend_packet_type(PacketType::Sco, self)
118     }
119 
parse_with_packet_type(bytes: &[u8]) -> Result<Self, PacketTypeParseError>120     fn parse_with_packet_type(bytes: &[u8]) -> Result<Self, PacketTypeParseError> {
121         parse_with_expected_packet_type(Sco::parse, PacketType::Sco, bytes)
122     }
123 }
124 
125 impl WithPacketType<Self> for Event {
to_vec_with_packet_type(self) -> Vec<u8>126     fn to_vec_with_packet_type(self) -> Vec<u8> {
127         prepend_packet_type(PacketType::Event, self)
128     }
129 
parse_with_packet_type(bytes: &[u8]) -> Result<Self, PacketTypeParseError>130     fn parse_with_packet_type(bytes: &[u8]) -> Result<Self, PacketTypeParseError> {
131         parse_with_expected_packet_type(Event::parse, PacketType::Event, bytes)
132     }
133 }
134 
prepend_packet_type<T: Packet>(packet_type: PacketType, packet: T) -> Vec<u8>135 fn prepend_packet_type<T: Packet>(packet_type: PacketType, packet: T) -> Vec<u8> {
136     // TODO: refactor if `pdl` crate adds API for writing into buffer (github.com/google/pdl/issues/74)
137     let mut packet_bytes = packet.to_vec();
138     packet_bytes.insert(0, packet_type.into());
139     packet_bytes
140 }
141 
parse_with_expected_packet_type<T: Packet, F, E>( parser: F, expected_packet_type: PacketType, bytes: &[u8], ) -> Result<T, PacketTypeParseError> where F: Fn(&[u8]) -> Result<T, E>, PacketTypeParseError: From<E>,142 fn parse_with_expected_packet_type<T: Packet, F, E>(
143     parser: F,
144     expected_packet_type: PacketType,
145     bytes: &[u8],
146 ) -> Result<T, PacketTypeParseError>
147 where
148     F: Fn(&[u8]) -> Result<T, E>,
149     PacketTypeParseError: From<E>,
150 {
151     let (first_byte, packet_bytes) = bytes
152         .split_first()
153         .ok_or(PacketTypeParseError::EmptySlice)?;
154     let actual_packet_type = PacketType::try_from(*first_byte)?;
155     if actual_packet_type == expected_packet_type {
156         Ok(parser(packet_bytes)?)
157     } else {
158         Err(PacketTypeParseError::PacketTypeMismatch {
159             expected: expected_packet_type,
160             actual: actual_packet_type,
161         })
162     }
163 }
164