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