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