From 207b1074fab736a381e06e22e58f30d2908e87c2 Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Mon, 18 Nov 2024 11:14:19 +0100 Subject: [PATCH] nimble/ll: Add vs hci cmd with additional scan cfg This allows to configure scanner to: - ignore either legacy or extended packets, - set minimal RSSI filter on primary channel. If scan is enabled command returns command disallowed error. --- .../include/controller/ble_ll_scan.h | 16 +++++++ nimble/controller/src/ble_ll_hci_vs.c | 35 ++++++++++++++ nimble/controller/src/ble_ll_scan.c | 46 ++++++++++++++++++- nimble/controller/syscfg.yml | 11 +++++ nimble/include/nimble/hci_common.h | 10 ++++ 5 files changed, 116 insertions(+), 2 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_scan.h b/nimble/controller/include/controller/ble_ll_scan.h index 07e4c9208a..19d9cdd9c6 100644 --- a/nimble/controller/include/controller/ble_ll_scan.h +++ b/nimble/controller/include/controller/ble_ll_scan.h @@ -99,6 +99,14 @@ struct ble_ll_scan_pdu_data { uint8_t adva[BLE_DEV_ADDR_LEN]; }; +struct ble_ll_scan_vs_config { + uint8_t ignore_legacy : 1; + uint8_t ignore_ext : 1; + uint8_t rssi_filter : 1; + + int8_t rssi_threshold; +}; + struct ble_ll_scan_addr_data { uint8_t *adva; uint8_t *targeta; @@ -156,6 +164,10 @@ struct ble_ll_scan_sm /* Connection sm for initiator scan */ struct ble_ll_conn_sm *connsm; #endif + +#if MYNEWT_VAL(BLE_LL_HCI_VS_SET_SCAN_CFG) + struct ble_ll_scan_vs_config vs_config; +#endif }; /* Scan types */ @@ -259,6 +271,10 @@ ble_ll_scan_rx_filter(uint8_t own_addr_type, uint8_t scan_filt_policy, struct ble_ll_scan_addr_data *addrd, uint8_t *scan_ok); int ble_ll_scan_rx_check_init(struct ble_ll_scan_addr_data *addrd); +#if MYNEWT_VAL(BLE_LL_HCI_VS_SET_SCAN_CFG) +int ble_ll_scan_set_vs_config(uint32_t flags, int8_t rssi_threshold); +#endif + #ifdef __cplusplus } #endif diff --git a/nimble/controller/src/ble_ll_hci_vs.c b/nimble/controller/src/ble_ll_hci_vs.c index 1710e456fe..df8b688697 100644 --- a/nimble/controller/src/ble_ll_hci_vs.c +++ b/nimble/controller/src/ble_ll_hci_vs.c @@ -356,6 +356,37 @@ ble_ll_hci_vs_set_local_irk(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, } #endif +#if MYNEWT_VAL(BLE_LL_HCI_VS_SET_SCAN_CFG) +static int +ble_ll_hci_vs_set_scan_cfg(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, + uint8_t *rspbuf, uint8_t *rsplen) +{ + const struct ble_hci_vs_set_scan_cfg_cp *cmd = (const void *)cmdbuf; + uint32_t flags; + int rc; + + if (cmdlen != sizeof(*cmd)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + flags = le32toh(cmd->flags); + + if ((flags & BLE_HCI_VS_SET_SCAN_CFG_FLAG_NO_LEGACY) && + (flags & BLE_HCI_VS_SET_SCAN_CFG_FLAG_NO_EXT)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + rc = ble_ll_scan_set_vs_config(flags, cmd->rssi_threshold); + if (rc != 0) { + return BLE_ERR_CMD_DISALLOWED; + } + + *rsplen = 0; + + return 0; +} +#endif + static struct ble_ll_hci_vs_cmd g_ble_ll_hci_vs_cmds[] = { BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_RD_STATIC_ADDR, ble_ll_hci_vs_rd_static_addr), @@ -386,6 +417,10 @@ static struct ble_ll_hci_vs_cmd g_ble_ll_hci_vs_cmds[] = { BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_SET_LOCAL_IRK, ble_ll_hci_vs_set_local_irk), #endif +#if MYNEWT_VAL(BLE_LL_HCI_VS_SET_SCAN_CFG) + BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_SET_SCAN_CFG, + ble_ll_hci_vs_set_scan_cfg) +#endif }; static struct ble_ll_hci_vs_cmd * diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 670f6b38cb..157ba94c1b 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -2000,8 +2000,10 @@ ble_ll_scan_rx_pkt_in_on_legacy(uint8_t pdu_type, struct os_mbuf *om, void ble_ll_scan_rx_pkt_in(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hdr) { +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_HCI_VS_SET_SCAN_CFG) + struct ble_mbuf_hdr_rxinfo *rxinfo = &hdr->rxinfo; +#endif #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - struct ble_mbuf_hdr_rxinfo *rxinfo; uint8_t *targeta; #endif struct ble_ll_scan_sm *scansm; @@ -2023,6 +2025,26 @@ ble_ll_scan_rx_pkt_in(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hd return; } +#if MYNEWT_VAL(BLE_LL_HCI_VS_SET_SCAN_CFG) + if ((scansm->vs_config.ignore_ext) && + (ptype == BLE_ADV_PDU_TYPE_ADV_EXT_IND)) { + ble_ll_scan_chk_resume(); + return; + } + + if ((scansm->vs_config.ignore_legacy) && + (ptype != BLE_ADV_PDU_TYPE_ADV_EXT_IND)) { + ble_ll_scan_chk_resume(); + return; + } + + if ((scansm->vs_config.rssi_filter) && + (rxinfo->rssi < scansm->vs_config.rssi_threshold)) { + ble_ll_scan_chk_resume(); + return; + } +#endif + #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) if (ptype == BLE_ADV_PDU_TYPE_ADV_EXT_IND) { ble_ll_scan_aux_pkt_in_on_ext(om, hdr); @@ -2034,7 +2056,6 @@ ble_ll_scan_rx_pkt_in(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hd switch (scansm->scanp->scan_type) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_SCAN_TYPE_INITIATE: - rxinfo = &hdr->rxinfo; if (rxinfo->flags & BLE_MBUF_HDR_F_CONNECT_IND_TXD) { /* We need to keep original TargetA in case it was resolved, so rl * can be updated properly. @@ -2258,6 +2279,27 @@ ble_ll_scan_hci_set_ext_params(const uint8_t *cmdbuf, uint8_t len) #endif +#if MYNEWT_VAL(BLE_LL_HCI_VS_SET_SCAN_CFG) +int +ble_ll_scan_set_vs_config(uint32_t flags, int8_t rssi_threshold) +{ + struct ble_ll_scan_sm *scansm; + + scansm = &g_ble_ll_scan_sm; + + if (scansm->scan_enabled || scansm->connsm) { + return 1; + } + + scansm->vs_config.ignore_legacy = !!(flags & BLE_HCI_VS_SET_SCAN_CFG_FLAG_NO_LEGACY); + scansm->vs_config.ignore_ext = !!(flags & BLE_HCI_VS_SET_SCAN_CFG_FLAG_NO_EXT); + scansm->vs_config.rssi_filter = !!(flags & BLE_HCI_VS_SET_SCAN_CFG_FLAG_RSSI_FILTER); + scansm->vs_config.rssi_threshold = rssi_threshold; + + return 0; +} +#endif + #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) static void ble_ll_scan_duration_period_timers_restart(struct ble_ll_scan_sm *scansm) diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 862a36a523..bc4860c1bd 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -422,6 +422,17 @@ syscfg.defs: value: 0 restrictions: - BLE_LL_HCI_VS if 1 + BLE_LL_HCI_VS_SET_SCAN_CFG: + description: > + Enables HCI command to set global PDU filter for scanner. + It allows: + - ignoring extended or legacy PDUs while scanning, + - setting minimal RSSI filter on primary channel + value: 0 + restrictions: + - BLE_LL_HCI_VS if 1 + - BLE_LL_CFG_FEAT_LL_EXT_ADV if 1 + - BLE_LL_ROLE_OBSERVER if 1 BLE_LL_HCI_VS_EVENT_ON_ASSERT: diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index 252b033973..6d9ba85db5 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1396,6 +1396,16 @@ struct ble_hci_vs_set_local_irk_cp { uint8_t irk[16]; } __attribute__((packed)); +#define BLE_HCI_VS_SET_SCAN_CFG_FLAG_NO_LEGACY (0x00000001) +#define BLE_HCI_VS_SET_SCAN_CFG_FLAG_NO_EXT (0x00000002) +#define BLE_HCI_VS_SET_SCAN_CFG_FLAG_RSSI_FILTER (0x00000004) + +#define BLE_HCI_OCF_VS_SET_SCAN_CFG (MYNEWT_VAL(BLE_HCI_VS_OCF_OFFSET) + (0x000B)) +struct ble_hci_vs_set_scan_cfg_cp { + uint32_t flags; + int8_t rssi_threshold; +} __attribute__((packed)); + /* Command Specific Definitions */ /* --- Set controller to host flow control (OGF 0x03, OCF 0x0031) --- */ #define BLE_HCI_CTLR_TO_HOST_FC_OFF (0)