blob: c7efbca18df7b75b1aa87edad373dac79e612e2b [file] [log] [blame]
// Copyright 2023 The Fuchsia Authors. All rights reserved.
// 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");
}
}