| // 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"); | 
 |     } | 
 | } |