use embassy_sync::blocking_mutex::raw::RawMutex;
use heapless::String;
use static_cell::StaticCell;
use crate::prelude::*;
const DEVICE_NAME_MAX_LENGTH: usize = 22;
pub const GAP_SERVICE_ATTRIBUTE_COUNT: usize = 6;
pub enum GapConfig<'a> {
Peripheral(PeripheralConfig<'a>),
Central(CentralConfig<'a>),
}
pub struct PeripheralConfig<'a> {
pub name: &'a str,
pub appearance: &'a BluetoothUuid16,
}
pub struct CentralConfig<'a> {
pub name: &'a str,
pub appearance: &'a BluetoothUuid16,
}
impl<'a> GapConfig<'a> {
pub fn default(name: &'a str) -> Self {
GapConfig::Peripheral(PeripheralConfig {
name,
appearance: &appearance::UNKNOWN,
})
}
pub fn build<M: RawMutex, const MAX: usize>(
self,
table: &mut AttributeTable<'a, M, MAX>,
) -> Result<(), &'static str> {
match self {
GapConfig::Peripheral(config) => config.build(table),
GapConfig::Central(config) => config.build(table),
}
}
}
impl<'a> PeripheralConfig<'a> {
fn build<M: RawMutex, const MAX: usize>(self, table: &mut AttributeTable<'a, M, MAX>) -> Result<(), &'static str> {
static PERIPHERAL_NAME: StaticCell<String<DEVICE_NAME_MAX_LENGTH>> = StaticCell::new();
let peripheral_name = PERIPHERAL_NAME.init(String::new());
peripheral_name
.push_str(self.name)
.map_err(|_| "Device name is too long. Max length is 22 bytes")?;
let mut gap_builder = table.add_service(Service::new(service::GAP));
gap_builder.add_characteristic_ro(characteristic::DEVICE_NAME, peripheral_name);
gap_builder.add_characteristic_ro(characteristic::APPEARANCE, self.appearance);
gap_builder.build();
table.add_service(Service::new(service::GATT));
Ok(())
}
}
impl<'a> CentralConfig<'a> {
fn build<M: RawMutex, const MAX: usize>(self, table: &mut AttributeTable<'a, M, MAX>) -> Result<(), &'static str> {
static CENTRAL_NAME: StaticCell<String<DEVICE_NAME_MAX_LENGTH>> = StaticCell::new();
let central_name = CENTRAL_NAME.init(String::new());
central_name
.push_str(self.name)
.map_err(|_| "Device name is too long. Max length is 22 bytes")?;
let mut gap_builder = table.add_service(Service::new(service::GAP));
gap_builder.add_characteristic_ro(characteristic::DEVICE_NAME, central_name);
gap_builder.add_characteristic_ro(characteristic::APPEARANCE, self.appearance);
gap_builder.build();
table.add_service(Service::new(service::GATT));
Ok(())
}
}