mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
pkg/nimble/scanner: rework to enable BLE5 scanning
This commit is contained in:
parent
34b009fcc1
commit
586ba70c5b
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Freie Universität Berlin
|
||||
* Copyright (C) 2019-2021 Freie Universität Berlin
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
@ -31,31 +31,100 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Flag to mark type for extended advertisements
|
||||
*/
|
||||
#define NIMBLE_SCANNER_EXT_ADV 0x80
|
||||
|
||||
/**
|
||||
* @brief Scan procedure configuration flags
|
||||
*/
|
||||
enum {
|
||||
NIMBLE_SCANNER_PASSIVE = 0x01, /**< do a passive scan */
|
||||
NIMBLE_SCANNER_LIMITED = 0x02, /**< do limited discovery */
|
||||
NIMBLE_SCANNER_FILTER_DUPS = 0x04, /**< filter duplicates */
|
||||
NIMBLE_SCANNER_PHY_1M = 0x10, /**< scan on 1Mbit PHY */
|
||||
NIMBLE_SCANNER_PHY_CODED = 0x20, /**< scan on CODED PHY */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Status flags for received advertising packets
|
||||
*/
|
||||
enum {
|
||||
/**
|
||||
* All fragments of a advertising message were received
|
||||
*/
|
||||
NIMBLE_SCANNER_COMPLETE = BLE_HCI_ADV_DATA_STATUS_COMPLETE,
|
||||
/**
|
||||
* The advertising message is incomplete
|
||||
*/
|
||||
NIMBLE_SCANNER_INCOMPLETE = BLE_HCI_ADV_DATA_STATUS_INCOMPLETE,
|
||||
/**
|
||||
* Advertising message is truncated
|
||||
*/
|
||||
NIMBLE_SCANNER_TRUNCATED = BLE_HCI_ADV_DATA_STATUS_TRUNCATED,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Scanner configuration parameters
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t itvl_ms; /**< scan interval [ms] */
|
||||
uint16_t win_ms; /**< scan window [ms] */
|
||||
uint8_t flags; /**< scan configuration flags */
|
||||
} nimble_scanner_cfg_t;
|
||||
|
||||
/**
|
||||
* @brief Additional information about received advertising packets
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* Status of received packet. Possible values:
|
||||
* - NIMBLE_SCANNER_COMPLETE
|
||||
* - NIMBLE_SCANNER_INCOMPLETE
|
||||
* - NIMBLE_SCANNER_TRUNCATED
|
||||
*/
|
||||
uint8_t status;
|
||||
uint8_t phy_pri; /**< PHY used on primary advertisement channels */
|
||||
uint8_t phy_sec; /**< PHY used on secondary advertisement channels */
|
||||
int8_t rssi; /**< RSSI value of received advertisement */
|
||||
} nimble_scanner_info_t;
|
||||
|
||||
/**
|
||||
* @brief Callback signature triggered by this module for each discovered
|
||||
* advertising packet
|
||||
*
|
||||
* @param[in] type type of advertising packet, e.g
|
||||
* BLE_HCI_ADV_RPT_EVTYPE_ADV_IND
|
||||
* @param[in] type type of advertising packet.
|
||||
* For legacy advertisements on of the following:
|
||||
* - BLE_HCI_ADV_RPT_EVTYPE_ADV_IND
|
||||
* - BLE_HCI_ADV_RPT_EVTYPE_DIR_IND
|
||||
* - BLE_HCI_ADV_RPT_EVTYPE_SCAN_IND
|
||||
* - BLE_HCI_ADV_RPT_EVTYPE_NONCONN_IND
|
||||
* - BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP
|
||||
* For extended advertisements NIMBLE_SCANNER_EXT_ADV ORed
|
||||
* with any set out of the following:
|
||||
* - BLE_HCI_ADV_CONN_MASK
|
||||
* - BLE_HCI_ADV_SCAN_MASK
|
||||
* - BLE_HCI_ADV_DIRECT_MASK
|
||||
* - BLE_HCI_ADV_SCAN_RSP_MASK
|
||||
* @param[in] addr advertising address of the source node
|
||||
* @param[in] rssi RSSI value for the received packet
|
||||
* @param[in] info additional information about the advertiser
|
||||
* @param[in] ad advertising data
|
||||
* @param[in] ad_len length of @p ad in bytes
|
||||
*/
|
||||
typedef void(*nimble_scanner_cb)(uint8_t type,
|
||||
const ble_addr_t *addr, int8_t rssi,
|
||||
typedef void(*nimble_scanner_cb)(uint8_t type, const ble_addr_t *addr,
|
||||
const nimble_scanner_info_t *info,
|
||||
const uint8_t *ad, size_t ad_len);
|
||||
|
||||
/**
|
||||
* @brief Initialize the scanner module
|
||||
*
|
||||
* @param[in] params scan parameters to use, pass NULL to use NimBLE's
|
||||
* default parameters
|
||||
* @param[in] params scan parameters to use
|
||||
* @param[in] disc_cb callback triggered of each received advertising packet
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int nimble_scanner_init(const struct ble_gap_disc_params *params,
|
||||
int nimble_scanner_init(const nimble_scanner_cfg_t *params,
|
||||
nimble_scanner_cb disc_cb);
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Freie Universität Berlin
|
||||
* Copyright (C) 2019-2021 Freie Universität Berlin
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
@ -30,22 +30,60 @@
|
||||
#include "debug.h"
|
||||
|
||||
static nimble_scanner_cb _disc_cb = NULL;
|
||||
|
||||
#if MYNEWT_VAL_BLE_EXT_ADV
|
||||
static struct ble_gap_ext_disc_params _scan_params = { 0 };
|
||||
static uint8_t _scan_flags = 0;
|
||||
#else
|
||||
static struct ble_gap_disc_params _scan_params = { 0 };
|
||||
#endif
|
||||
|
||||
/* duration of the scanning procedure */
|
||||
static int32_t _scan_duration = BLE_HS_FOREVER;
|
||||
|
||||
static int _on_scan_evt(struct ble_gap_event *event, void *arg)
|
||||
{
|
||||
/* only interested in the DISC event */
|
||||
if (event->type == BLE_GAP_EVENT_DISC) {
|
||||
_disc_cb(event->disc.event_type, &event->disc.addr, event->disc.rssi,
|
||||
switch (event->type) {
|
||||
#if MYNEWT_VAL_BLE_EXT_ADV
|
||||
case BLE_GAP_EVENT_EXT_DISC: {
|
||||
uint8_t type;
|
||||
nimble_scanner_info_t info;
|
||||
info.rssi = event->ext_disc.rssi;
|
||||
|
||||
if (event->ext_disc.props & BLE_HCI_ADV_LEGACY_MASK) {
|
||||
type = event->ext_disc.legacy_event_type;
|
||||
info.status = NIMBLE_SCANNER_COMPLETE;
|
||||
info.phy_pri = BLE_HCI_LE_PHY_1M;
|
||||
info.phy_sec = BLE_HCI_LE_PHY_1M;
|
||||
}
|
||||
else {
|
||||
type = (event->ext_disc.props | NIMBLE_SCANNER_EXT_ADV);
|
||||
info.status = event->ext_disc.data_status;
|
||||
info.phy_pri = event->ext_disc.prim_phy;
|
||||
info.phy_sec = event->ext_disc.sec_phy;
|
||||
}
|
||||
|
||||
_disc_cb(type, &event->ext_disc.addr, &info,
|
||||
event->ext_disc.data, event->ext_disc.length_data);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
case BLE_GAP_EVENT_DISC: {
|
||||
nimble_scanner_info_t info = {
|
||||
.status = NIMBLE_SCANNER_COMPLETE,
|
||||
.phy_pri = BLE_HCI_LE_PHY_1M,
|
||||
.phy_sec = BLE_HCI_LE_PHY_1M,
|
||||
.rssi = event->disc.rssi,
|
||||
};
|
||||
_disc_cb(event->disc.event_type, &event->disc.addr, &info,
|
||||
event->disc.data, (size_t)event->disc.length_data);
|
||||
break;
|
||||
}
|
||||
else if (event->type == BLE_GAP_EVENT_DISC_COMPLETE) {
|
||||
#endif
|
||||
case BLE_GAP_EVENT_DISC_COMPLETE:
|
||||
DEBUG("[scanner] scan cycle completed\n");
|
||||
}
|
||||
else {
|
||||
break;
|
||||
default:
|
||||
/* this should never happen */
|
||||
DEBUG("[scanner] unknown event triggered (%i)\n", (int)event->type);
|
||||
assert(0);
|
||||
@ -57,8 +95,23 @@ static int _on_scan_evt(struct ble_gap_event *event, void *arg)
|
||||
int nimble_scanner_start(void)
|
||||
{
|
||||
if (ble_gap_disc_active() == 0) {
|
||||
int res = ble_gap_disc(nimble_riot_own_addr_type, _scan_duration,
|
||||
#if MYNEWT_VAL_BLE_EXT_ADV
|
||||
uint8_t dups = (_scan_flags & NIMBLE_SCANNER_FILTER_DUPS) ? 1 : 0;
|
||||
uint8_t limited = (_scan_flags & NIMBLE_SCANNER_LIMITED) ? 1 : 0;
|
||||
const struct ble_gap_ext_disc_params *uncoded =
|
||||
(_scan_flags & NIMBLE_SCANNER_PHY_1M) ? &_scan_params : NULL;
|
||||
const struct ble_gap_ext_disc_params *coded =
|
||||
(_scan_flags & NIMBLE_SCANNER_PHY_CODED) ? &_scan_params : NULL;
|
||||
|
||||
int res = ble_gap_ext_disc(nimble_riot_own_addr_type,
|
||||
_scan_duration / 10, 0, dups,
|
||||
BLE_HCI_SCAN_FILT_NO_WL, limited,
|
||||
uncoded, coded,
|
||||
_on_scan_evt, NULL);
|
||||
#else
|
||||
int res = ble_gap_disc(nimble_riot_own_addr_type, 0,
|
||||
&_scan_params, _on_scan_evt, NULL);
|
||||
#endif
|
||||
if (res != 0) {
|
||||
DEBUG("[scanner] err: start failed (%i)\n", res);
|
||||
return -ECANCELED;
|
||||
@ -87,17 +140,23 @@ void nimble_scanner_set_scan_duration(int32_t duration_ms)
|
||||
}
|
||||
}
|
||||
|
||||
int nimble_scanner_init(const struct ble_gap_disc_params *params,
|
||||
int nimble_scanner_init(const nimble_scanner_cfg_t *params,
|
||||
nimble_scanner_cb disc_cb)
|
||||
{
|
||||
assert(params);
|
||||
assert(disc_cb);
|
||||
|
||||
if (params) {
|
||||
memcpy(&_scan_params, params, sizeof(_scan_params));
|
||||
}
|
||||
else {
|
||||
memset(&_scan_params, 0, sizeof(_scan_params));
|
||||
}
|
||||
_scan_params.itvl = BLE_GAP_SCAN_ITVL_MS(params->itvl_ms);
|
||||
_scan_params.window = BLE_GAP_SCAN_WIN_MS(params->win_ms);
|
||||
_scan_params.passive = (params->flags & NIMBLE_SCANNER_PASSIVE) ? 1 : 0;
|
||||
#if MYNEWT_VAL_BLE_EXT_ADV
|
||||
_scan_flags = params->flags;
|
||||
#else
|
||||
_scan_params.limited = (params->flags & NIMBLE_SCANNER_LIMITED) ? 1 : 0;
|
||||
_scan_params.filter_duplicates =
|
||||
(params->flags & NIMBLE_SCANNER_FILTER_DUPS) ? 1 : 0;
|
||||
#endif
|
||||
|
||||
_disc_cb = disc_cb;
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user