From 3f6116c9ffbadc775e04e4cc1becbe6875869035 Mon Sep 17 00:00:00 2001 From: OueslatiGhaith Date: Thu, 4 Jan 2024 15:07:07 +0100 Subject: [PATCH] feat(vendor GAP command): add ADV Set AAdvertising Data command --- src/types/extended_advertisement.rs | 18 +++++++++++++ src/vendor/command/gap.rs | 40 +++++++++++++++++++++++++++-- 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/src/types/extended_advertisement.rs b/src/types/extended_advertisement.rs index 94b703b..727c02e 100644 --- a/src/types/extended_advertisement.rs +++ b/src/types/extended_advertisement.rs @@ -147,6 +147,8 @@ pub enum ExtendedAdvertisingIntervalError { } /// Advertising PHY +#[derive(Clone, Copy, Debug)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum AdvertisingPhy { /// Advertisement PHY is LE 1M Le1M = 0x01, @@ -181,3 +183,19 @@ impl AdvSet { bytes[3] = self.max_extended_adv_events; } } + +/// Advertising Operation +#[derive(Clone, Copy, Debug)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum AdvertisingOperation { + /// Intermediate fragment of fragmented extended advertising data + IntermediateFragment = 0x00, + /// First fragment of fragmented extended advertising data + FirstFragment = 0x01, + /// Last fragment of fragmented extended advertising data + LastFragment = 0x02, + /// Complete extended advertising data + CompleteData = 0x03, + /// Unchanged data (just update the advertising DID) + UnchangedData = 0x04, +} diff --git a/src/vendor/command/gap.rs b/src/vendor/command/gap.rs index d1a8af4..f44f171 100644 --- a/src/vendor/command/gap.rs +++ b/src/vendor/command/gap.rs @@ -4,7 +4,7 @@ extern crate byteorder; pub use crate::host::{AdvertisingFilterPolicy, AdvertisingType, OwnAddressType}; use crate::types::extended_advertisement::{ - AdvSet, AdvertisingEvent, AdvertisingPhy, ExtendedAdvertisingInterval, + AdvSet, AdvertisingEvent, AdvertisingOperation, AdvertisingPhy, ExtendedAdvertisingInterval, }; pub use crate::types::{ConnectionInterval, ExpectedConnectionLength, ScanWindow}; use crate::{ @@ -804,12 +804,15 @@ pub trait GapCommands { /// legacy advertising. // TODO: add adv_set_scan_response_data // TODO: add adv_set_advertising_data - // TODO: add adv_set_enable async fn adv_set_config(&mut self, params: &AdvSetConfig); /// This command is used to request the Controller to enable or disbale one /// or more extended advertising sets. async fn adv_set_enable<'a>(&mut self, params: &AdvSetEnable<'a>); + + /// This command is used to set the data used in extended advertising PDUs + /// that have a data field + async fn adv_set_advertising_data(&mut self, params: &AdvSetAdvertisingData); } impl GapCommands for T { @@ -1235,6 +1238,12 @@ impl GapCommands for T { AdvSetEnable<'a>, crate::vendor::opcode::GAP_ADV_SET_ENABLE ); + + impl_variable_length_params!( + adv_set_advertising_data<'a>, + AdvSetAdvertisingData<'a>, + crate::vendor::opcode::GAP_ADV_SET_ADV_DATA + ); } /// Potential errors from parameter validation. @@ -2510,3 +2519,30 @@ impl<'a> AdvSetEnable<'a> { } } } + +/// Params for the [adv_set_advertising_data](GapCommands::adv_set_advertising_data) command +pub struct AdvSetAdvertisingData<'a> { + /// Used to identify an advertising set + pub adv_handle: AdvertisingHandle, + /// Advertising operation + pub operation: AdvertisingOperation, + /// Fragment preference. If set to `true`, the Controller may fragment all data, else + /// the Controller should not fragment or should minimize fragmentation of data + pub fragment: bool, + pub data: &'a [u8], +} + +impl<'a> AdvSetAdvertisingData<'a> { + const MAX_LENGTH: usize = 255; + + fn copy_into_slice(&self, bytes: &mut [u8]) { + assert!(bytes.len() >= Self::MAX_LENGTH); + + bytes[0] = self.adv_handle.0; + bytes[1] = self.operation as u8; + bytes[2] = (!self.fragment) as u8; + let length = self.data.len(); + bytes[3] = length as u8; + bytes[4..(4 + length)].copy_from_slice(self.data); + } +}