From 8f6231ab39d6f76944b4d91d2bac82eddaf4c69f Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Fri, 17 Jun 2022 00:48:27 +0200 Subject: Add Conn::ignore_slave_latency. --- nrf-softdevice/src/ble/connection.rs | 63 ++++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/nrf-softdevice/src/ble/connection.rs b/nrf-softdevice/src/ble/connection.rs index 1ed33d5..961f883 100644 --- a/nrf-softdevice/src/ble/connection.rs +++ b/nrf-softdevice/src/ble/connection.rs @@ -27,13 +27,32 @@ pub enum SetConnParamsError { impl From for SetConnParamsError { fn from(_err: DisconnectedError) -> Self { - SetConnParamsError::Disconnected + Self::Disconnected } } impl From for SetConnParamsError { fn from(err: RawError) -> Self { - SetConnParamsError::Raw(err) + Self::Raw(err) + } +} + +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum IgnoreSlaveLatencyError { + Disconnected, + Raw(RawError), +} + +impl From for IgnoreSlaveLatencyError { + fn from(_err: DisconnectedError) -> Self { + Self::Disconnected + } +} + +impl From for IgnoreSlaveLatencyError { + fn from(err: RawError) -> Self { + Self::Raw(err) } } @@ -297,6 +316,46 @@ impl Connection { Ok(()) } + /// Temporarily ignore slave latency for peripehral connections. + /// + /// "Slave latency" is a setting in the conn params that allows the peripheral + /// to intentionally sleep through and miss up to N connection events if it doesn't + /// have any data to send to the central. + /// + /// Slave latency is useful because it can yield the same power savings on the peripheral + /// as increasing the conn interval, but it only impacts latency in the central->peripheral + /// direction, not both. + /// + /// However, in some cases, if the peripheral knows the central will send it some data soon + /// it might be useful to temporarily force ignoring the slave latency setting, ie waking up + /// at every single conn interval, to lower the latency. + /// + /// This only works on peripheral connections. + pub fn ignore_slave_latency(&mut self, ignore: bool) -> Result<(), IgnoreSlaveLatencyError> { + let conn_handle = self.with_state(|state| state.check_connected())?; + + let mut disable: raw::ble_gap_opt_slave_latency_disable_t = unsafe { core::mem::zeroed() }; + disable.conn_handle = conn_handle; + disable.set_disable(ignore as u8); // 0 or 1 + + let ret = unsafe { + raw::sd_ble_opt_set( + raw::BLE_GAP_OPTS_BLE_GAP_OPT_SLAVE_LATENCY_DISABLE, + &raw::ble_opt_t { + gap_opt: raw::ble_gap_opt_t { + slave_latency_disable: disable, + }, + }, + ) + }; + if let Err(err) = RawError::convert(ret) { + warn!("ignore_slave_latency sd_ble_opt_set err {:?}", err); + return Err(err.into()); + } + + Ok(()) + } + pub(crate) fn with_state(&self, f: impl FnOnce(&mut ConnectionState) -> T) -> T { with_state(self.index, f) } -- cgit v1.2.3