|  | // Copyright 2023 Google LLC | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | /// Traits and utilities to handle length-type-value structures. | 
|  | pub mod ltv; | 
|  |  | 
|  | use crate::packet_encoding::{Encodable, Error as PacketError}; | 
|  |  | 
|  | /// Represents the Advertising Set ID which is 1 byte long. | 
|  | /// Follows little endian encoding. | 
|  | #[derive(Debug, Clone, Copy, PartialEq)] | 
|  | pub struct AdvertisingSetId(pub u8); | 
|  |  | 
|  | impl AdvertisingSetId { | 
|  | // Byte size if this is to be encoded. | 
|  | pub const BYTE_SIZE: usize = 1; | 
|  | } | 
|  |  | 
|  | /// Represents the SyncInfo Interval value which is 2 bytes long. | 
|  | /// Follows little endian encoding. | 
|  | #[derive(Debug, Clone, Copy, PartialEq)] | 
|  | pub struct PaInterval(pub u16); | 
|  |  | 
|  | impl PaInterval { | 
|  | pub const BYTE_SIZE: usize = 2; | 
|  | pub const UNKNOWN_VALUE: u16 = 0xFFFF; | 
|  |  | 
|  | pub const fn unknown() -> Self { | 
|  | Self(Self::UNKNOWN_VALUE) | 
|  | } | 
|  | } | 
|  |  | 
|  | impl Encodable for PaInterval { | 
|  | type Error = PacketError; | 
|  |  | 
|  | /// Encodees the PaInterval to 2 byte value using little endian encoding. | 
|  | fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> { | 
|  | if buf.len() < Self::BYTE_SIZE { | 
|  | return Err(PacketError::BufferTooSmall); | 
|  | } | 
|  | buf[0..Self::BYTE_SIZE].copy_from_slice(&self.0.to_le_bytes()); | 
|  | Ok(()) | 
|  | } | 
|  |  | 
|  | fn encoded_len(&self) -> core::primitive::usize { | 
|  | Self::BYTE_SIZE | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Coding Format as defined by the Assigned Numbers Document. Section 2.11. | 
|  | /// Referenced in the Core Spec 5.3, Volume 4, Part E, Section 7 as well as | 
|  | /// various other profile specifications. | 
|  | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] | 
|  | pub enum CodingFormat { | 
|  | MuLawLog, | 
|  | ALawLog, | 
|  | Cvsd, | 
|  | Transparent, | 
|  | LinearPcm, | 
|  | Msbc, | 
|  | Lc3, | 
|  | G729a, | 
|  | VendorSpecific, | 
|  | Unrecognized(u8), | 
|  | } | 
|  |  | 
|  | impl From<u8> for CodingFormat { | 
|  | fn from(value: u8) -> Self { | 
|  | match value { | 
|  | 0x00 => Self::MuLawLog, | 
|  | 0x01 => Self::ALawLog, | 
|  | 0x02 => Self::Cvsd, | 
|  | 0x03 => Self::Transparent, | 
|  | 0x04 => Self::LinearPcm, | 
|  | 0x05 => Self::Msbc, | 
|  | 0x06 => Self::Lc3, | 
|  | 0x07 => Self::G729a, | 
|  | 0xFF => Self::VendorSpecific, | 
|  | x => Self::Unrecognized(x), | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | impl From<CodingFormat> for u8 { | 
|  | fn from(value: CodingFormat) -> Self { | 
|  | match value { | 
|  | CodingFormat::MuLawLog => 0x00, | 
|  | CodingFormat::ALawLog => 0x01, | 
|  | CodingFormat::Cvsd => 0x02, | 
|  | CodingFormat::Transparent => 0x03, | 
|  | CodingFormat::LinearPcm => 0x04, | 
|  | CodingFormat::Msbc => 0x05, | 
|  | CodingFormat::Lc3 => 0x06, | 
|  | CodingFormat::G729a => 0x07, | 
|  | CodingFormat::VendorSpecific => 0xFF, | 
|  | CodingFormat::Unrecognized(x) => x, | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | impl core::fmt::Display for CodingFormat { | 
|  | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | 
|  | match self { | 
|  | CodingFormat::MuLawLog => write!(f, "ยต-law log"), | 
|  | CodingFormat::ALawLog => write!(f, "A-law log"), | 
|  | CodingFormat::Cvsd => write!(f, "CVSD"), | 
|  | CodingFormat::Transparent => write!(f, "Transparent"), | 
|  | CodingFormat::LinearPcm => write!(f, "Linear PCM"), | 
|  | CodingFormat::Msbc => write!(f, "mSBC"), | 
|  | CodingFormat::Lc3 => write!(f, "LC3"), | 
|  | CodingFormat::G729a => write!(f, "G.729A"), | 
|  | CodingFormat::VendorSpecific => write!(f, "Vendor Specific"), | 
|  | CodingFormat::Unrecognized(x) => write!(f, "Unrecognized ({x})"), | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | #[cfg(test)] | 
|  | mod tests { | 
|  | use super::*; | 
|  |  | 
|  | #[test] | 
|  | fn encode_pa_interval() { | 
|  | let mut buf = [0; PaInterval::BYTE_SIZE]; | 
|  | let interval = PaInterval(0x1004); | 
|  |  | 
|  | interval.encode(&mut buf[..]).expect("should succeed"); | 
|  | assert_eq!(buf, [0x04, 0x10]); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn encode_pa_interval_fails() { | 
|  | let mut buf = [0; 1]; // Not enough buffer space. | 
|  | let interval = PaInterval(0x1004); | 
|  |  | 
|  | interval.encode(&mut buf[..]).expect_err("should fail"); | 
|  | } | 
|  | } |