Skip to content

Commit

Permalink
unify and improve central config structs
Browse files Browse the repository at this point in the history
  • Loading branch information
Dirbaio committed Feb 3, 2021
1 parent 1c82130 commit 96e625f
Show file tree
Hide file tree
Showing 10 changed files with 135 additions and 125 deletions.
6 changes: 3 additions & 3 deletions examples/src/bin/ble_bas_central.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ async fn ble_central_task(sd: &'static Softdevice) {
AddressType::RandomStatic,
[0x06, 0x6b, 0x71, 0x2c, 0xf5, 0xc0],
)];

let config = central::Config::default();
let conn = unwrap!(central::connect(sd, addrs, &config).await);
let mut config = central::ConnectConfig::default();
config.scan_config.whitelist = Some(addrs);
let conn = unwrap!(central::connect(sd, &config).await);
info!("connected");

let client: BatteryServiceClient = unwrap!(gatt_client::discover(&conn).await);
Expand Down
6 changes: 4 additions & 2 deletions examples/src/bin/ble_l2cap_central.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ async fn ble_central_task(sd: &'static Softdevice) {
let config = central::ScanConfig {
whitelist: None,
tx_power: TxPower::ZerodBm,
..Default::default()
};
let res = central::scan(sd, &config, |params| unsafe {
let mut data = slice::from_raw_parts(params.data.p_data, params.data.len as usize);
Expand Down Expand Up @@ -72,8 +73,9 @@ async fn ble_central_task(sd: &'static Softdevice) {

let addrs = &[&address];

let config = central::Config::default();
let conn = unwrap!(central::connect(sd, addrs, &config).await);
let mut config = central::ConnectConfig::default();
config.scan_config.whitelist = Some(addrs);
let conn = unwrap!(central::connect(sd, &config).await);
info!("connected");

let l = l2cap::L2cap::<Packet>::init(sd);
Expand Down
5 changes: 1 addition & 4 deletions examples/src/bin/ble_scan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,7 @@ async fn softdevice_task(sd: &'static Softdevice) {

#[task]
async fn ble_task(sd: &'static Softdevice) {
let config = central::ScanConfig {
whitelist: None,
tx_power: TxPower::ZerodBm,
};
let config = central::ScanConfig::default();
let res = central::scan(sd, &config, |params| unsafe {
info!("AdvReport!");
info!(
Expand Down
185 changes: 88 additions & 97 deletions nrf-softdevice/src/ble/central.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,28 +33,17 @@ pub(crate) static CONNECT_PORTAL: Portal<*const raw::ble_evt_t> = Portal::new();
// Begins an ATT MTU exchange procedure, followed by a data length update request as necessary.
pub async fn connect(
sd: &Softdevice,
addresses: &[&Address],
config: &Config,
config: &ConnectConfig<'_>,
) -> Result<Connection, ConnectError> {
if addresses.len() == 0 {
if let Some(w) = config.scan_config.whitelist {
if w.len() == 0 {
return Err(ConnectError::NoAddresses);
}
} else {
return Err(ConnectError::NoAddresses);
}

// Set tx power
let ret = unsafe {
raw::sd_ble_gap_tx_power_set(
raw::BLE_GAP_TX_POWER_ROLES_BLE_GAP_TX_POWER_ROLE_SCAN_INIT as _,
0,
config.tx_power as i8,
)
};
RawError::convert(ret).map_err(|err| {
warn!("sd_ble_gap_tx_power_set err {:?}", err);
err
})?;

let mut scan_params = raw::ble_gap_scan_params_t::from(&config.scan_params);
scan_params.set_filter_policy(raw::BLE_GAP_SCAN_FP_WHITELIST as _);
let scan_params = config.scan_config.to_raw()?;

let d = OnDrop::new(|| {
let ret = unsafe { raw::sd_ble_gap_connect_cancel() };
Expand All @@ -63,16 +52,7 @@ pub async fn connect(
}
});

assert!(addresses.len() <= u8::MAX as usize);
let ret =
unsafe { raw::sd_ble_gap_whitelist_set(addresses.as_ptr() as _, addresses.len() as u8) };
if let Err(err) = RawError::convert(ret) {
warn!("sd_ble_gap_connect err {:?}", err);
return Err(err.into());
}

let ret =
unsafe { raw::sd_ble_gap_connect(ptr::null(), &mut scan_params, &config.conn_params, 1) };
let ret = unsafe { raw::sd_ble_gap_connect(ptr::null(), &scan_params, &config.conn_params, 1) };
if let Err(err) = RawError::convert(ret) {
warn!("sd_ble_gap_connect err {:?}", err);
return Err(err.into());
Expand Down Expand Up @@ -113,11 +93,6 @@ pub async fn connect(
})
.await?;

conn.with_state(|state| {
state.rx_phys = config.tx_phys;
state.tx_phys = config.rx_phys;
});

d.defuse();

#[cfg(feature = "ble-gatt-client")]
Expand All @@ -130,30 +105,21 @@ pub async fn connect(
}

#[derive(Copy, Clone)]
pub struct Config {
pub tx_power: TxPower,

pub struct ConnectConfig<'a> {
/// Requested ATT_MTU size for the next connection that is established.
#[cfg(feature = "ble-gatt-client")]
pub att_mtu: Option<u16>,
// bits of BLE_GAP_PHY_
pub tx_phys: u8,
// bits of BLE_GAP_PHY_
pub rx_phys: u8,

pub scan_params: ScanParams,
pub scan_config: ScanConfig<'a>,
pub conn_params: raw::ble_gap_conn_params_t,
}

impl Default for Config {
impl<'a> Default for ConnectConfig<'a> {
fn default() -> Self {
Self {
tx_power: TxPower::ZerodBm,
#[cfg(feature = "ble-gatt-client")]
att_mtu: None,
tx_phys: raw::BLE_GAP_PHY_AUTO as _,
rx_phys: raw::BLE_GAP_PHY_AUTO as _,
scan_params: ScanParams::default(),
scan_config: ScanConfig::default(),
conn_params: raw::ble_gap_conn_params_t {
min_conn_interval: 40,
max_conn_interval: 200,
Expand Down Expand Up @@ -186,20 +152,7 @@ pub async fn scan<'a, F, R>(
where
F: for<'b> FnMut(&'b raw::ble_gap_evt_adv_report_t) -> Option<R>,
{
// Set tx power
let ret = unsafe {
raw::sd_ble_gap_tx_power_set(
raw::BLE_GAP_TX_POWER_ROLES_BLE_GAP_TX_POWER_ROLE_SCAN_INIT as _,
0,
config.tx_power as i8,
)
};
RawError::convert(ret).map_err(|err| {
warn!("sd_ble_gap_tx_power_set err {:?}", err);
err
})?;

let mut scan_params = raw::ble_gap_scan_params_t::from(&config.scan_params);
let scan_params = config.to_raw()?;

// Buffer to store received advertisement data.
const BUF_LEN: usize = 256;
Expand Down Expand Up @@ -258,68 +211,106 @@ where

#[derive(Copy, Clone)]
pub struct ScanConfig<'a> {
pub whitelist: Option<&'a [Address]>,
/// Whitelist of addresses to scan. If None, all advertisements
/// will be processed when scanning.
///
/// For connecting this must be Some, and have least 1 address.
pub whitelist: Option<&'a [&'a Address]>,

/// Support extended advertisements.
///
/// If true, the scanner will accept extended advertising packets.
/// If false, the scanner will not receive advertising packets
/// on secondary advertising channels, and will not be able
/// to receive long advertising PDUs.
pub extended: bool,

/// If true, scan actively by sending scan requests.
/// Ignored when using for connecting.
pub active: bool,

/// Set of PHYs to scan
pub phys: PhySet,

/// Scan interval, in units of 625us
pub interval: u32,

/// Scan window, in units of 625us
pub window: u32,

/// Timeout in units of 10ms. If set to 0, scan forever.
pub timeout: u16,

/// Radio TX power. This is used for scanning, and is inherited
/// as the connection TX power if this ScanConfig is used for connect().
pub tx_power: TxPower,
pub scan_params: ScanParams,
}

impl<'a> Default for ScanConfig<'a> {
fn default() -> Self {
Self {
extended: true,
active: true,
phys: PhySet::M1,
interval: 2732,
window: 500,
timeout: raw::BLE_GAP_SCAN_TIMEOUT_UNLIMITED as _,
whitelist: None,
tx_power: TxPower::ZerodBm,
scan_params: ScanParams::default(),
}
}
}

#[derive(Copy, Clone)]
pub struct ScanParams {
pub extended: bool,
pub active: bool,
pub filter_policy: u8,
pub scan_phys: u8,
pub interval: u32,
pub window: u32,
pub timeout: u16,
}
impl From<&ScanParams> for raw::ble_gap_scan_params_t {
fn from(res: &ScanParams) -> raw::ble_gap_scan_params_t {
impl<'a> ScanConfig<'a> {
fn to_raw(&self) -> Result<raw::ble_gap_scan_params_t, RawError> {
let mut scan_params: raw::ble_gap_scan_params_t = unsafe { mem::zeroed() };
if res.extended {
if self.extended {
scan_params.set_extended(1);
}
if res.active {
if self.active {
scan_params.set_active(1);
}
scan_params.set_filter_policy(res.filter_policy);
scan_params.scan_phys = res.scan_phys;
scan_params.timeout = res.timeout;
scan_params.scan_phys = self.phys as u8;
scan_params.timeout = self.timeout;

// s122 has these in us instead of 625us :shrug:
#[cfg(not(feature = "s122"))]
{
scan_params.interval = res.interval as u16;
scan_params.window = res.window as u16;
scan_params.interval = self.interval as u16;
scan_params.window = self.window as u16;
}
#[cfg(feature = "s122")]
{
scan_params.interval_us = res.interval * 625;
scan_params.window_us = res.window * 625;
scan_params.interval_us = self.interval * 625;
scan_params.window_us = self.window * 625;
}
return scan_params;
}
}
impl Default for ScanParams {
fn default() -> Self {
Self {
extended: true,
active: true,
filter_policy: raw::BLE_GAP_SCAN_FP_ACCEPT_ALL as _,
scan_phys: raw::BLE_GAP_PHY_1MBPS as _,
interval: 2732,
window: 500,
timeout: raw::BLE_GAP_SCAN_TIMEOUT_UNLIMITED as _,

// Set whitelist
if let Some(w) = self.whitelist {
assert!(w.len() <= u8::MAX as usize);
let ret = unsafe { raw::sd_ble_gap_whitelist_set(w.as_ptr() as _, w.len() as u8) };
if let Err(err) = RawError::convert(ret) {
warn!("sd_ble_gap_whitelist_set err {:?}", err);
return Err(err.into());
}
scan_params.set_filter_policy(raw::BLE_GAP_SCAN_FP_WHITELIST as _);
} else {
scan_params.set_filter_policy(raw::BLE_GAP_SCAN_FP_ACCEPT_ALL as _);
}

// Set tx power
let ret = unsafe {
raw::sd_ble_gap_tx_power_set(
raw::BLE_GAP_TX_POWER_ROLES_BLE_GAP_TX_POWER_ROLE_SCAN_INIT as _,
0,
self.tx_power as i8,
)
};
RawError::convert(ret).map_err(|err| {
warn!("sd_ble_gap_tx_power_set err {:?}", err);
err
})?;

Ok(scan_params)
}
}
8 changes: 0 additions & 8 deletions nrf-softdevice/src/ble/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@ pub(crate) struct ConnectionState {
pub att_mtu: u16, // Effective ATT_MTU size (in bytes).
#[cfg(any(feature = "s113", feature = "s132", feature = "s140"))]
pub data_length_effective: u8, // Effective data length (in bytes).

pub rx_phys: u8,
pub tx_phys: u8,
}

impl ConnectionState {
Expand All @@ -66,8 +63,6 @@ impl ConnectionState {
att_mtu: 0,
#[cfg(any(feature = "s113", feature = "s132", feature = "s140"))]
data_length_effective: 0,
rx_phys: 0,
tx_phys: 0,
}
}
pub(crate) fn check_connected(&mut self) -> Result<u16, DisconnectedError> {
Expand Down Expand Up @@ -188,9 +183,6 @@ impl Connection {

#[cfg(any(feature = "s113", feature = "s132", feature = "s140"))]
data_length_effective: BLE_GAP_DATA_LENGTH_DEFAULT,

rx_phys: 0,
tx_phys: 0,
};

// Update index_by_handle
Expand Down
9 changes: 4 additions & 5 deletions nrf-softdevice/src/ble/gap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,10 @@ pub(crate) unsafe fn on_evt(ble_evt: *const raw::ble_evt_t) {
peer_preferred_phys.tx_phys
);

let phys =
connection::with_state_by_conn_handle(conn_handle, |state| raw::ble_gap_phys_t {
rx_phys: state.rx_phys,
tx_phys: state.tx_phys,
});
let phys = raw::ble_gap_phys_t {
rx_phys: peer_preferred_phys.rx_phys,
tx_phys: peer_preferred_phys.tx_phys,
};

let ret = raw::sd_ble_gap_phy_update(conn_handle, &phys as *const raw::ble_gap_phys_t);

Expand Down
2 changes: 1 addition & 1 deletion nrf-softdevice/src/ble/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use crate::fmt::*;
use crate::{raw, RawError, Softdevice};

pub(crate) unsafe fn on_evt(ble_evt: *const raw::ble_evt_t) {
defmt::trace!("ble evt {:u32}", (*ble_evt).header.evt_id as u32);
trace!("ble evt {:?}", (*ble_evt).header.evt_id as u32);
match (*ble_evt).header.evt_id as u32 {
raw::BLE_EVT_BASE..=raw::BLE_EVT_LAST => common::on_evt(ble_evt),
raw::BLE_GAP_EVT_BASE..=raw::BLE_GAP_EVT_LAST => gap::on_evt(ble_evt),
Expand Down
4 changes: 2 additions & 2 deletions nrf-softdevice/src/ble/peripheral.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,8 @@ pub struct Config {
impl Default for Config {
fn default() -> Self {
Self {
primary_phy: Phy::_1M,
secondary_phy: Phy::_1M,
primary_phy: Phy::M1,
secondary_phy: Phy::M1,
tx_power: TxPower::ZerodBm,
timeout: None,
max_events: None,
Expand Down
Loading

0 comments on commit 96e625f

Please sign in to comment.