Skip to content

Commit

Permalink
Merge pull request #225 from AliMoal/gatt-server-cpfd
Browse files Browse the repository at this point in the history
GATT Server CPFD
  • Loading branch information
alexmoon authored Feb 1, 2024
2 parents 0e94b00 + 971c360 commit 8ba471d
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 19 deletions.
10 changes: 8 additions & 2 deletions examples/src/bin/ble_dis_bas_peripheral_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use nrf_softdevice::ble::advertisement_builder::{
Flag, LegacyAdvertisementBuilder, LegacyAdvertisementPayload, ServiceList, ServiceUuid16,
};
use nrf_softdevice::ble::gatt_server::builder::ServiceBuilder;
use nrf_softdevice::ble::gatt_server::characteristic::{Attribute, Metadata, Properties};
use nrf_softdevice::ble::gatt_server::characteristic::{Attribute, Metadata, Presentation, Properties};
use nrf_softdevice::ble::gatt_server::{CharacteristicHandles, RegisterError, WriteOp};
use nrf_softdevice::ble::{gatt_server, peripheral, Connection, Uuid};
use nrf_softdevice::{raw, Softdevice};
Expand Down Expand Up @@ -114,7 +114,13 @@ impl BatteryService {
let mut service_builder = ServiceBuilder::new(sd, BATTERY_SERVICE)?;

let attr = Attribute::new(&[0u8]);
let metadata = Metadata::new(Properties::new().read().notify());
let metadata = Metadata::new(Properties::new().read().notify()).presentation(Presentation {
format: raw::BLE_GATT_CPF_FORMAT_UINT8 as u8,
exponent: 0, /* Value * 10 ^ 0 */
unit: 0x27AD, /* Percentage */
name_space: raw::BLE_GATT_CPF_NAMESPACE_BTSIG as u8,
description: raw::BLE_GATT_CPF_NAMESPACE_DESCRIPTION_UNKNOWN as u16,
});
let characteristic_builder = service_builder.add_characteristic(BATTERY_LEVEL, attr, metadata)?;
let characteristic_handles = characteristic_builder.build();

Expand Down
5 changes: 3 additions & 2 deletions nrf-softdevice/src/ble/gatt_server/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ extern crate alloc;
#[cfg(feature = "alloc")]
use alloc::boxed::Box;

use super::characteristic::{self, AttributeMetadata};
use super::characteristic::{self, AttributeMetadata, Presentation};
use super::{CharacteristicHandles, DescriptorHandle, IncludedServiceHandle, RegisterError, ServiceHandle};
use crate::ble::Uuid;
use crate::{raw, RawError, Softdevice};
Expand Down Expand Up @@ -83,6 +83,7 @@ impl<'a> ServiceBuilder<'a> {
let user_desc_md = char_md
.user_description
.and_then(|x| x.metadata.map(AttributeMetadata::into_raw));
let cpfd_md = char_md.cpfd.map(Presentation::into_raw);
let cccd_md = char_md.cccd.map(AttributeMetadata::into_raw);
let sccd_md = char_md.sccd.map(AttributeMetadata::into_raw);

Expand All @@ -92,7 +93,7 @@ impl<'a> ServiceBuilder<'a> {
p_char_user_desc: char_md.user_description.map_or(null(), |x| x.value.as_ptr()),
char_user_desc_max_size: char_md.user_description.map_or(0, |x| x.max_len),
char_user_desc_size: char_md.user_description.map_or(0, |x| x.value.len() as u16),
p_char_pf: null(),
p_char_pf: cpfd_md.as_ref().map_or(null(), |x| x as _),
p_user_desc_md: user_desc_md.as_ref().map_or(null(), |x| x as _),
p_cccd_md: cccd_md.as_ref().map_or(null(), |x| x as _),
p_sccd_md: sccd_md.as_ref().map_or(null(), |x| x as _),
Expand Down
51 changes: 36 additions & 15 deletions nrf-softdevice/src/ble/gatt_server/characteristic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,11 +218,34 @@ impl Properties {
}
}

#[derive(Default, Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct Presentation {
pub format: u8,
pub exponent: i8,
pub unit: u16,
pub name_space: u8,
pub description: u16,
}

impl Presentation {
pub(crate) fn into_raw(self) -> raw::ble_gatts_char_pf_t {
raw::ble_gatts_char_pf_t {
format: self.format.into(),
exponent: self.exponent.into(),
unit: self.unit.into(),
name_space: self.name_space.into(),
desc: self.description.into(),
}
}
}

#[derive(Default, Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct Metadata {
pub properties: Properties,
pub user_description: Option<UserDescription>,
pub cpfd: Option<Presentation>,
pub cccd: Option<AttributeMetadata>,
pub sccd: Option<AttributeMetadata>,
}
Expand All @@ -249,24 +272,22 @@ impl Metadata {
}
}

pub fn with_security(properties: Properties, write_security: SecurityMode) -> Self {
let cccd = if properties.indicate || properties.notify {
Some(AttributeMetadata::default().write_security(write_security))
} else {
None
pub fn presentation(self, presentation: Presentation) -> Self {
let cpfd = Some(presentation);
Metadata { cpfd, ..self }
}

pub fn security(self, security: SecurityMode) -> Self {
let cccd = match self.cccd {
Some(cccd) => Some(cccd.write_security(security)),
None => None,
};

let sccd = if properties.broadcast {
Some(AttributeMetadata::default().write_security(write_security))
} else {
None
let sccd = match self.sccd {
Some(sccd) => Some(sccd.write_security(security)),
None => None,
};

Metadata {
properties,
cccd,
sccd,
..Default::default()
}
Metadata { cccd, sccd, ..self }
}
}

0 comments on commit 8ba471d

Please sign in to comment.