1 // Copyright 2022 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 //! V0 data elements and core trait impls.
16 
17 use crate::{
18     extended::serialize::CapacityLimitedVec,
19     legacy::{
20         data_elements::de_type::{DeActualLength, DeEncodedLength, DeTypeCode},
21         PacketFlavor, PacketFlavorEnum, NP_MAX_ADV_CONTENT_LEN,
22     },
23     private::Sealed,
24     DeLengthOutOfRange,
25 };
26 use core::marker;
27 use nom::error::{self};
28 use sink::Sink;
29 
30 pub mod actions;
31 pub mod de_type;
32 pub mod tx_power;
33 
34 #[cfg(test)]
35 pub(in crate::legacy) mod tests;
36 
37 /// Deserialization for a specific data element type.
38 ///
39 /// See also [SerializeDataElement] for flavor-specific, infallible serialization.
40 pub(in crate::legacy) trait DeserializeDataElement: Sized + Sealed {
41     const DE_TYPE_CODE: DeTypeCode;
42 
43     /// Define how length mapping is done for this DE type
44     type LengthMapper: LengthMapper;
45 
46     /// Deserialize `Self` from the provided DE contents (not including the
47     /// DE header).
48     ///
49     /// Returns `Err` if the flavor is not supported or if parsing fails.
50     ///
51     /// `<F>` is the flavor of the packet being deserialized.
deserialize<F: PacketFlavor>( de_contents: &[u8], ) -> Result<Self, DataElementDeserializeError>52     fn deserialize<F: PacketFlavor>(
53         de_contents: &[u8],
54     ) -> Result<Self, DataElementDeserializeError>;
55 }
56 
57 /// Errors possible when deserializing a DE
58 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
59 pub enum DataElementDeserializeError {
60     /// The data element doesn't support the [PacketFlavor] of the advertisement packet.
61     FlavorNotSupported {
62         /// The DE type attempting to be deserialized
63         de_type: DeTypeCode,
64         /// The flavor that was not supported
65         flavor: PacketFlavorEnum,
66     },
67     /// The data element couldn't be deserialized from the supplied data.
68     DeserializeError {
69         /// The DE type attempting to be deserialized
70         de_type: DeTypeCode,
71     },
72     /// Invalid DE type
73     InvalidDeType {
74         /// The unknown type
75         de_type: DeTypeCode,
76     },
77     /// Invalid DE length
78     InvalidDeLength {
79         /// The DE type attempting to be deserialized
80         de_type: DeTypeCode,
81         /// The invalid length
82         len: DeEncodedLength,
83     },
84     /// Other parse error, e.g. the adv is truncated
85     InvalidStructure,
86 }
87 
88 impl error::FromExternalError<&[u8], DataElementDeserializeError> for DataElementDeserializeError {
from_external_error( _input: &[u8], _kind: error::ErrorKind, e: DataElementDeserializeError, ) -> Self89     fn from_external_error(
90         _input: &[u8],
91         _kind: error::ErrorKind,
92         e: DataElementDeserializeError,
93     ) -> Self {
94         e
95     }
96 }
97 
98 impl error::ParseError<&[u8]> for DataElementDeserializeError {
99     /// Creates an error from the input position and an [error::ErrorKind]
from_error_kind(_input: &[u8], _kind: error::ErrorKind) -> Self100     fn from_error_kind(_input: &[u8], _kind: error::ErrorKind) -> Self {
101         Self::InvalidStructure
102     }
103 
104     /// Combines an existing error with a new one created from the input
105     /// position and an [error::ErrorKind]. This is useful when backtracking
106     /// through a parse tree, accumulating error context on the way
append(_input: &[u8], _kind: error::ErrorKind, _other: Self) -> Self107     fn append(_input: &[u8], _kind: error::ErrorKind, _other: Self) -> Self {
108         Self::InvalidStructure
109     }
110 }
111 
112 /// Serialization of a DE for a particular flavor.
113 ///
114 /// The flavor is a type parameter on the trait, rather than on the method,
115 /// so that a DE can indicate its flavor support by implementing this trait
116 /// only with the relevant flavors. Deserialization, on the other hand, can
117 /// express "flavor not supported" for invalid input.
118 pub trait SerializeDataElement<F: PacketFlavor>: Sealed {
119     /// Returns the DE type code this DE uses in the header.
de_type_code(&self) -> DeTypeCode120     fn de_type_code(&self) -> DeTypeCode;
121 
122     /// Convert the actual DE content length to the encoded length included in the header.
123     ///
124     /// This has a `&self` receiver only so that it can be object-safe; it
125     /// should not be relevant in the calculation.
126     ///
127     /// # Panics
128     ///
129     /// Panics if the actual length is invalid for this DE type, or if the
130     /// encoded length cannot fit in [DeEncodedLength], either of which means
131     /// that the serialization impl is broken.
map_actual_len_to_encoded_len(&self, actual_len: DeActualLength) -> DeEncodedLength132     fn map_actual_len_to_encoded_len(&self, actual_len: DeActualLength) -> DeEncodedLength;
133 
134     /// Serialize the data element's data (not including the header) into the sink.
serialize_contents( &self, sink: &mut DataElementSerializationBuffer, ) -> Result<(), DataElementSerializeError>135     fn serialize_contents(
136         &self,
137         sink: &mut DataElementSerializationBuffer,
138     ) -> Result<(), DataElementSerializeError>;
139 }
140 
141 /// Errors possible when serializing a DE
142 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
143 pub enum DataElementSerializeError {
144     /// Not enough available space
145     InsufficientSpace,
146 }
147 
148 /// Buffer to serialize a DE, including the header, into.
149 pub struct DataElementSerializationBuffer {
150     vec: CapacityLimitedVec<u8, NP_MAX_ADV_CONTENT_LEN>,
151 }
152 
153 impl DataElementSerializationBuffer {
154     /// Returns `None` if `capacity` exceeds [NP_MAX_ADV_CONTENT_LEN].
new(capacity: usize) -> Option<Self>155     pub(crate) fn new(capacity: usize) -> Option<Self> {
156         CapacityLimitedVec::new(capacity).map(|vec| Self { vec })
157     }
158 
len(&self) -> usize159     pub(crate) fn len(&self) -> usize {
160         self.vec.len()
161     }
162 
into_inner(self) -> CapacityLimitedVec<u8, NP_MAX_ADV_CONTENT_LEN>163     pub(crate) fn into_inner(self) -> CapacityLimitedVec<u8, NP_MAX_ADV_CONTENT_LEN> {
164         self.vec
165     }
166 }
167 
168 impl Sink<u8> for DataElementSerializationBuffer {
try_extend_from_slice(&mut self, items: &[u8]) -> Option<()>169     fn try_extend_from_slice(&mut self, items: &[u8]) -> Option<()> {
170         Sink::try_extend_from_slice(&mut self.vec, items)
171     }
172 
try_push(&mut self, item: u8) -> Option<()>173     fn try_push(&mut self, item: u8) -> Option<()> {
174         Sink::try_push(&mut self.vec, item)
175     }
176 }
177 
178 /// Trait object reference to a `ToDataElementBundle<I>` with lifetime `'a`.
179 /// Implements [SerializeDataElement] by deferring to the wrapped trait object.
180 pub struct DynamicSerializeDataElement<'a, I: PacketFlavor> {
181     wrapped: &'a dyn SerializeDataElement<I>,
182 }
183 
184 impl<'a, I: PacketFlavor> From<&'a dyn SerializeDataElement<I>>
185     for DynamicSerializeDataElement<'a, I>
186 {
from(wrapped: &'a dyn SerializeDataElement<I>) -> Self187     fn from(wrapped: &'a dyn SerializeDataElement<I>) -> Self {
188         DynamicSerializeDataElement { wrapped }
189     }
190 }
191 
192 impl<'a, F: PacketFlavor> Sealed for DynamicSerializeDataElement<'a, F> {}
193 
194 impl<'a, F: PacketFlavor> SerializeDataElement<F> for DynamicSerializeDataElement<'a, F> {
de_type_code(&self) -> DeTypeCode195     fn de_type_code(&self) -> DeTypeCode {
196         self.wrapped.de_type_code()
197     }
198 
map_actual_len_to_encoded_len(&self, actual_len: DeActualLength) -> DeEncodedLength199     fn map_actual_len_to_encoded_len(&self, actual_len: DeActualLength) -> DeEncodedLength {
200         self.wrapped.map_actual_len_to_encoded_len(actual_len)
201     }
202 
serialize_contents( &self, sink: &mut DataElementSerializationBuffer, ) -> Result<(), DataElementSerializeError>203     fn serialize_contents(
204         &self,
205         sink: &mut DataElementSerializationBuffer,
206     ) -> Result<(), DataElementSerializeError> {
207         self.wrapped.serialize_contents(sink)
208     }
209 }
210 
211 /// Maps encoded to actual lengths and vice versa.
212 ///
213 /// Each v0 DE type has their own length mapping rules.
214 pub(in crate::legacy) trait LengthMapper {
215     /// Convert the encoded DE content length in the header to the actual length to consume from
216     /// the advertisement, or an error if the encoded length is invalid for the DE type.
map_encoded_len_to_actual_len( encoded_len: DeEncodedLength, ) -> Result<DeActualLength, DeLengthOutOfRange>217     fn map_encoded_len_to_actual_len(
218         encoded_len: DeEncodedLength,
219     ) -> Result<DeActualLength, DeLengthOutOfRange>;
220 
221     /// Convert the actual DE content length to the encoded length included in the header.
222     ///
223     /// # Panics
224     ///
225     /// Panics if the actual length is invalid for this DE type, or if the
226     /// encoded length cannot fit in [DeEncodedLength], either of which means
227     /// that the serialization impl is broken.
map_actual_len_to_encoded_len(actual_len: DeActualLength) -> DeEncodedLength228     fn map_actual_len_to_encoded_len(actual_len: DeActualLength) -> DeEncodedLength;
229 }
230 
231 /// A length predicate used with [DirectMapper].
232 pub(in crate::legacy) trait DirectMapPredicate {
233     /// Return `true` iff the len is valid as a DE encoded len _and_ actual len.
is_valid(len: usize) -> bool234     fn is_valid(len: usize) -> bool;
235 }
236 
237 /// A [LengthMapper] that maps the input number directly to the output number without any scaling or
238 /// shifting.
239 ///
240 /// Iff `predicate` evaluates to true, the input number will be transformed into the output type,
241 /// for both directions.
242 pub(in crate::legacy) struct DirectMapper<P: DirectMapPredicate> {
243     _marker: marker::PhantomData<P>,
244 }
245 
246 impl<P: DirectMapPredicate> LengthMapper for DirectMapper<P> {
map_encoded_len_to_actual_len( encoded_len: DeEncodedLength, ) -> Result<DeActualLength, DeLengthOutOfRange>247     fn map_encoded_len_to_actual_len(
248         encoded_len: DeEncodedLength,
249     ) -> Result<DeActualLength, DeLengthOutOfRange> {
250         let enc = encoded_len.as_usize();
251         if P::is_valid(enc) {
252             DeActualLength::try_from(enc)
253         } else {
254             Err(DeLengthOutOfRange)
255         }
256     }
257 
map_actual_len_to_encoded_len(actual_len: DeActualLength) -> DeEncodedLength258     fn map_actual_len_to_encoded_len(actual_len: DeActualLength) -> DeEncodedLength {
259         assert!(
260             P::is_valid(actual_len.as_usize()),
261             "Broken DE implementation produced invalid length"
262         );
263         DeEncodedLength::try_from(actual_len.as_u8())
264             .expect("Actual length has already been validated")
265     }
266 }
267