use serde::{Deserialize, Serialize};
use super::Uuid;
#[derive(
Debug,
Copy,
Clone,
PartialEq,
Eq,
Serialize,
Deserialize,
postcard::experimental::max_size::MaxSize,
)]
pub struct Address {
octets: [u8; 6],
public: bool,
}
impl Address {
pub const fn new(octets: [u8; 6], public: bool) -> Self {
Self { octets, public }
}
pub fn octets(&self) -> [u8; 6] {
self.octets
}
pub fn is_public(&self) -> bool {
self.public
}
}
impl core::fmt::Display for Address {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(
f,
"{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X} Type: {}",
self.octets[0],
self.octets[1],
self.octets[2],
self.octets[3],
self.octets[4],
self.octets[5],
if self.public { "Public" } else { "Random" }
)
}
}
pub const MAX_ADVERTISED_SERVICE_UUIDS: usize = 4;
#[derive(Debug, Serialize, Deserialize)]
pub struct DiscoveredDevice {
pub address: Address,
pub advertisement: Advertisement,
}
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub struct Advertisement {
pub local_name: Option<heapless::String<32>>,
pub manufacturer_data: Option<ManufacturerData>,
pub service_uuids: heapless::Vec<Uuid, MAX_ADVERTISED_SERVICE_UUIDS>,
pub service_data: Option<ServiceData>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ManufacturerData {
pub company_identifier: u16,
pub payload: heapless::Vec<u8, 27>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServiceData {
pub uuid: Uuid,
pub payload: heapless::Vec<u8, 27>,
}
#[derive(Debug)]
pub enum SecuritySettings {
Unsecured,
StaticPasskey(u32),
}
#[cfg(all(test, feature = "alloc"))]
mod tests {
use alloc::string::ToString;
use super::*;
use crate::{mac_addr_pub, mac_addr_rand};
#[test]
fn mac_addr_pub_builds_a_public_address() {
const ADDR: Address = mac_addr_pub!("C0:98:E5:42:7A:11");
assert_eq!(ADDR.octets(), [0xC0, 0x98, 0xE5, 0x42, 0x7A, 0x11]);
assert!(ADDR.is_public());
assert_eq!("C0:98:E5:42:7A:11 Type: Public", &ADDR.to_string());
}
#[test]
fn mac_addr_rand_builds_a_random_address() {
const ADDR: Address = mac_addr_rand!("DB:67:C1:B4:11:F2");
assert_eq!(ADDR.octets(), [0xDB, 0x67, 0xC1, 0xB4, 0x11, 0xF2]);
assert!(!ADDR.is_public());
assert_eq!("DB:67:C1:B4:11:F2 Type: Random", &ADDR.to_string());
}
#[test]
fn address_postcard_encoding_is_the_six_mac_bytes_plus_a_public_flag_byte() {
const ADDR: Address = mac_addr_pub!("C0:98:E5:42:7A:11");
let bytes = postcard::to_allocvec(&ADDR).unwrap();
assert_eq!(bytes, [0xC0, 0x98, 0xE5, 0x42, 0x7A, 0x11, 0x01]);
let decoded: Address = postcard::from_bytes(&bytes).unwrap();
assert_eq!(decoded, ADDR);
}
}