2018-12-18 05:48:20 +01:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2016-2019 Nordic Semiconductor ASA
|
|
|
|
* Copyright (c) 2016 Vinayak Kariappa Chettimada
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
*/
|
|
|
|
|
includes: prefer <zephyr/kernel.h> over <zephyr/zephyr.h>
As of today <zephyr/zephyr.h> is 100% equivalent to <zephyr/kernel.h>.
This patch proposes to then include <zephyr/kernel.h> instead of
<zephyr/zephyr.h> since it is more clear that you are including the
Kernel APIs and (probably) nothing else. <zephyr/zephyr.h> sounds like a
catch-all header that may be confusing. Most applications need to
include a bunch of other things to compile, e.g. driver headers or
subsystem headers like BT, logging, etc.
The idea of a catch-all header in Zephyr is probably not feasible
anyway. Reason is that Zephyr is not a library, like it could be for
example `libpython`. Zephyr provides many utilities nowadays: a kernel,
drivers, subsystems, etc and things will likely grow. A catch-all header
would be massive, difficult to keep up-to-date. It is also likely that
an application will only build a small subset. Note that subsystem-level
headers may use a catch-all approach to make things easier, though.
NOTE: This patch is **NOT** removing the header, just removing its usage
in-tree. I'd advocate for its deprecation (add a #warning on it), but I
understand many people will have concerns.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
2022-08-25 09:58:46 +02:00
|
|
|
#include <zephyr/kernel.h>
|
2020-08-19 10:09:58 +05:30
|
|
|
#include <soc.h>
|
2023-06-09 13:33:53 +02:00
|
|
|
#include <zephyr/bluetooth/hci_types.h>
|
2018-12-18 05:48:20 +01:00
|
|
|
|
2020-08-19 10:09:58 +05:30
|
|
|
#include "hal/cpu.h"
|
2018-12-18 05:48:20 +01:00
|
|
|
#include "hal/ccm.h"
|
2020-06-15 20:43:54 +05:30
|
|
|
#include "hal/radio.h"
|
2018-12-18 05:48:20 +01:00
|
|
|
#include "hal/ticker.h"
|
|
|
|
|
|
|
|
#include "util/util.h"
|
2019-09-17 11:55:55 +05:30
|
|
|
#include "util/mem.h"
|
2018-12-18 05:48:20 +01:00
|
|
|
#include "util/memq.h"
|
|
|
|
#include "util/mayfly.h"
|
2021-10-30 23:40:52 +02:00
|
|
|
#include "util/dbuf.h"
|
2018-12-18 05:48:20 +01:00
|
|
|
|
|
|
|
#include "ticker/ticker.h"
|
|
|
|
|
2023-01-20 18:07:24 +05:30
|
|
|
#include "pdu_df.h"
|
|
|
|
#include "lll/pdu_vendor.h"
|
2018-12-18 05:48:20 +01:00
|
|
|
#include "pdu.h"
|
|
|
|
|
|
|
|
#include "lll.h"
|
2021-02-24 16:42:02 +05:30
|
|
|
#include "lll/lll_vendor.h"
|
|
|
|
#include "lll/lll_adv_types.h"
|
2018-12-18 05:48:20 +01:00
|
|
|
#include "lll_adv.h"
|
2021-02-24 16:42:02 +05:30
|
|
|
#include "lll/lll_adv_pdu.h"
|
2018-12-18 05:48:20 +01:00
|
|
|
#include "lll_scan.h"
|
2021-07-27 08:47:45 +02:00
|
|
|
#include "lll/lll_df_types.h"
|
2018-12-18 05:48:20 +01:00
|
|
|
#include "lll_conn.h"
|
|
|
|
#include "lll_filter.h"
|
|
|
|
|
2022-09-19 11:58:43 +02:00
|
|
|
#include "ll_sw/ull_tx_queue.h"
|
2022-05-12 07:50:26 -07:00
|
|
|
|
2018-12-18 05:48:20 +01:00
|
|
|
#include "ull_adv_types.h"
|
2019-05-09 18:39:26 +05:30
|
|
|
#include "ull_filter.h"
|
2018-12-18 05:48:20 +01:00
|
|
|
|
2022-05-12 04:48:32 -07:00
|
|
|
#include "ull_conn_types.h"
|
2018-12-18 05:48:20 +01:00
|
|
|
#include "ull_internal.h"
|
|
|
|
#include "ull_adv_internal.h"
|
2021-11-15 09:41:12 +01:00
|
|
|
#include "ull_scan_types.h"
|
2018-12-18 05:48:20 +01:00
|
|
|
#include "ull_scan_internal.h"
|
|
|
|
#include "ull_sched_internal.h"
|
|
|
|
|
2021-02-24 16:42:02 +05:30
|
|
|
#include "ll.h"
|
|
|
|
|
2018-12-18 05:48:20 +01:00
|
|
|
#include "hal/debug.h"
|
|
|
|
|
2019-02-04 22:21:55 +05:30
|
|
|
static int init_reset(void);
|
2021-09-15 11:48:21 +05:30
|
|
|
static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
|
|
|
|
uint32_t remainder, uint16_t lazy, uint8_t force,
|
|
|
|
void *param);
|
2020-04-08 16:17:48 +05:30
|
|
|
static uint8_t disable(uint8_t handle);
|
2018-12-18 05:48:20 +01:00
|
|
|
|
2020-10-12 21:56:59 +05:30
|
|
|
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
2022-04-04 13:35:53 +05:30
|
|
|
#define IS_PHY_ENABLED(scan_ctx, scan_phy) ((scan_ctx)->lll.phy & (scan_phy))
|
|
|
|
|
2020-10-16 10:06:43 +05:30
|
|
|
static uint8_t is_scan_update(uint8_t handle, uint16_t duration,
|
|
|
|
uint16_t period, struct ll_scan_set **scan,
|
|
|
|
struct node_rx_pdu **node_rx_scan_term);
|
|
|
|
static uint8_t duration_period_setup(struct ll_scan_set *scan,
|
|
|
|
uint16_t duration, uint16_t period,
|
|
|
|
struct node_rx_pdu **node_rx_scan_term);
|
|
|
|
static uint8_t duration_period_update(struct ll_scan_set *scan,
|
|
|
|
uint8_t is_update);
|
2021-08-17 14:34:39 +05:30
|
|
|
static void ticker_stop_ext_op_cb(uint32_t status, void *param);
|
2021-08-16 16:50:07 +05:30
|
|
|
static void ext_disable(void *param);
|
2020-08-04 07:29:52 +02:00
|
|
|
static void ext_disabled_cb(void *param);
|
2020-10-12 21:56:59 +05:30
|
|
|
#endif /* CONFIG_BT_CTLR_ADV_EXT */
|
2020-08-04 07:29:52 +02:00
|
|
|
|
2020-05-04 17:32:48 +05:30
|
|
|
static struct ll_scan_set ll_scan[BT_CTLR_SCAN_SET];
|
2018-12-18 05:48:20 +01:00
|
|
|
|
2023-02-12 11:19:00 +05:30
|
|
|
#if defined(CONFIG_BT_TICKER_EXT)
|
|
|
|
static struct ticker_ext ll_scan_ticker_ext[BT_CTLR_SCAN_SET];
|
|
|
|
#endif /* CONFIG_BT_TICKER_EXT */
|
|
|
|
|
2020-05-27 11:26:57 -05:00
|
|
|
uint8_t ll_scan_params_set(uint8_t type, uint16_t interval, uint16_t window,
|
|
|
|
uint8_t own_addr_type, uint8_t filter_policy)
|
2018-12-18 05:48:20 +01:00
|
|
|
{
|
|
|
|
struct ll_scan_set *scan;
|
2020-04-08 16:43:15 +05:30
|
|
|
struct lll_scan *lll;
|
2018-12-18 05:48:20 +01:00
|
|
|
|
2020-04-08 16:43:15 +05:30
|
|
|
scan = ull_scan_is_disabled_get(SCAN_HANDLE_1M);
|
2018-12-18 05:48:20 +01:00
|
|
|
if (!scan) {
|
|
|
|
return BT_HCI_ERR_CMD_DISALLOWED;
|
|
|
|
}
|
|
|
|
|
2020-04-08 16:43:15 +05:30
|
|
|
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
|
|
|
uint8_t phy;
|
|
|
|
|
|
|
|
phy = type >> 1;
|
|
|
|
if (phy & BT_HCI_LE_EXT_SCAN_PHY_CODED) {
|
2020-05-04 15:49:08 +05:30
|
|
|
struct ll_scan_set *scan_coded;
|
|
|
|
|
|
|
|
if (!IS_ENABLED(CONFIG_BT_CTLR_PHY_CODED)) {
|
|
|
|
return BT_HCI_ERR_CMD_DISALLOWED;
|
|
|
|
}
|
|
|
|
|
|
|
|
scan_coded = ull_scan_is_disabled_get(SCAN_HANDLE_PHY_CODED);
|
|
|
|
if (!scan_coded) {
|
|
|
|
return BT_HCI_ERR_CMD_DISALLOWED;
|
|
|
|
}
|
|
|
|
|
2020-04-08 16:43:15 +05:30
|
|
|
scan = scan_coded;
|
|
|
|
}
|
|
|
|
|
|
|
|
lll = &scan->lll;
|
2020-04-16 14:14:34 +05:30
|
|
|
|
2021-04-27 12:26:15 +05:30
|
|
|
/* NOTE: Pass invalid interval value to not start scanning using this
|
|
|
|
* scan instance.
|
|
|
|
*/
|
2020-04-16 14:14:34 +05:30
|
|
|
if (!interval) {
|
2021-04-27 12:26:15 +05:30
|
|
|
/* Set PHY to 0 to not start scanning on this instance */
|
2020-04-16 14:14:34 +05:30
|
|
|
lll->phy = 0U;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-04-04 13:35:53 +05:30
|
|
|
/* If phy assigned is PHY_1M or PHY_CODED, then scanning on that
|
|
|
|
* PHY is enabled.
|
|
|
|
*/
|
2020-04-08 16:43:15 +05:30
|
|
|
lll->phy = phy;
|
|
|
|
|
|
|
|
#else /* !CONFIG_BT_CTLR_ADV_EXT */
|
|
|
|
lll = &scan->lll;
|
|
|
|
#endif /* !CONFIG_BT_CTLR_ADV_EXT */
|
|
|
|
|
2019-05-09 18:39:26 +05:30
|
|
|
scan->own_addr_type = own_addr_type;
|
|
|
|
|
2023-02-12 08:54:06 +05:30
|
|
|
scan->ticks_window = ull_scan_params_set(lll, type, interval, window,
|
|
|
|
filter_policy);
|
2019-05-09 18:39:26 +05:30
|
|
|
|
|
|
|
return 0;
|
2018-12-18 05:48:20 +01:00
|
|
|
}
|
|
|
|
|
2020-10-12 21:56:59 +05:30
|
|
|
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
2020-10-14 19:18:14 +05:30
|
|
|
uint8_t ll_scan_enable(uint8_t enable, uint16_t duration, uint16_t period)
|
2020-10-23 06:00:14 +05:30
|
|
|
{
|
|
|
|
struct node_rx_pdu *node_rx_scan_term = NULL;
|
|
|
|
uint8_t is_update_coded = 0U;
|
|
|
|
uint8_t is_update_1m = 0U;
|
2020-10-12 21:56:59 +05:30
|
|
|
#else /* !CONFIG_BT_CTLR_ADV_EXT */
|
|
|
|
uint8_t ll_scan_enable(uint8_t enable)
|
2018-12-18 05:48:20 +01:00
|
|
|
{
|
2020-10-23 06:00:14 +05:30
|
|
|
#endif /* !CONFIG_BT_CTLR_ADV_EXT */
|
2020-04-08 16:43:15 +05:30
|
|
|
struct ll_scan_set *scan_coded = NULL;
|
|
|
|
uint8_t own_addr_type = 0U;
|
|
|
|
uint8_t is_coded_phy = 0U;
|
2020-10-16 10:06:43 +05:30
|
|
|
struct ll_scan_set *scan;
|
2020-04-08 16:43:15 +05:30
|
|
|
uint8_t err;
|
2018-12-18 05:48:20 +01:00
|
|
|
|
|
|
|
if (!enable) {
|
2020-04-08 16:43:15 +05:30
|
|
|
err = disable(SCAN_HANDLE_1M);
|
|
|
|
|
2020-05-04 15:49:08 +05:30
|
|
|
if (IS_ENABLED(CONFIG_BT_CTLR_ADV_EXT) &&
|
|
|
|
IS_ENABLED(CONFIG_BT_CTLR_PHY_CODED)) {
|
2020-04-08 16:43:15 +05:30
|
|
|
uint8_t err_coded;
|
|
|
|
|
|
|
|
err_coded = disable(SCAN_HANDLE_PHY_CODED);
|
|
|
|
if (!err_coded) {
|
|
|
|
err = 0U;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return err;
|
2018-12-18 05:48:20 +01:00
|
|
|
}
|
|
|
|
|
2020-04-08 16:43:15 +05:30
|
|
|
scan = ull_scan_is_disabled_get(SCAN_HANDLE_1M);
|
2018-12-18 05:48:20 +01:00
|
|
|
if (!scan) {
|
2020-10-16 10:06:43 +05:30
|
|
|
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
|
|
|
is_update_1m = is_scan_update(SCAN_HANDLE_1M, duration, period,
|
|
|
|
&scan, &node_rx_scan_term);
|
|
|
|
if (!is_update_1m)
|
|
|
|
#endif /* CONFIG_BT_CTLR_ADV_EXT */
|
|
|
|
{
|
|
|
|
return BT_HCI_ERR_CMD_DISALLOWED;
|
|
|
|
}
|
2018-12-18 05:48:20 +01:00
|
|
|
}
|
|
|
|
|
2020-05-04 15:49:08 +05:30
|
|
|
#if defined(CONFIG_BT_CTLR_ADV_EXT) && defined(CONFIG_BT_CTLR_PHY_CODED)
|
2020-04-14 17:26:19 +05:30
|
|
|
scan_coded = ull_scan_is_disabled_get(SCAN_HANDLE_PHY_CODED);
|
|
|
|
if (!scan_coded) {
|
2020-10-16 10:06:43 +05:30
|
|
|
is_update_coded = is_scan_update(SCAN_HANDLE_PHY_CODED,
|
|
|
|
duration, period, &scan_coded,
|
|
|
|
&node_rx_scan_term);
|
2020-10-24 06:43:23 +05:30
|
|
|
if (!is_update_coded) {
|
2020-10-16 10:06:43 +05:30
|
|
|
return BT_HCI_ERR_CMD_DISALLOWED;
|
|
|
|
}
|
2020-04-08 16:43:15 +05:30
|
|
|
}
|
|
|
|
|
2020-04-14 17:26:19 +05:30
|
|
|
own_addr_type = scan_coded->own_addr_type;
|
|
|
|
is_coded_phy = (scan_coded->lll.phy &
|
|
|
|
BT_HCI_LE_EXT_SCAN_PHY_CODED);
|
2020-05-04 15:49:08 +05:30
|
|
|
#endif /* CONFIG_BT_CTLR_ADV_EXT && CONFIG_BT_CTLR_PHY_CODED */
|
2020-04-14 17:26:19 +05:30
|
|
|
|
2020-10-16 10:06:43 +05:30
|
|
|
if ((is_coded_phy && (own_addr_type & 0x1)) ||
|
|
|
|
(!is_coded_phy && (scan->own_addr_type & 0x1))) {
|
2021-09-28 06:09:13 +05:30
|
|
|
if (!mem_nz(ll_addr_get(BT_ADDR_LE_RANDOM), BDADDR_SIZE)) {
|
2019-09-17 11:55:55 +05:30
|
|
|
return BT_HCI_ERR_INVALID_PARAM;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-12 21:56:59 +05:30
|
|
|
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
2020-10-16 10:06:43 +05:30
|
|
|
#if defined(CONFIG_BT_CTLR_PHY_CODED)
|
2022-04-04 13:35:53 +05:30
|
|
|
if (!is_coded_phy || IS_PHY_ENABLED(scan, PHY_1M))
|
2020-10-16 10:06:43 +05:30
|
|
|
#endif /* CONFIG_BT_CTLR_PHY_CODED */
|
|
|
|
{
|
|
|
|
err = duration_period_setup(scan, duration, period,
|
|
|
|
&node_rx_scan_term);
|
|
|
|
if (err) {
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
}
|
2020-04-08 16:43:15 +05:30
|
|
|
|
2020-10-16 10:06:43 +05:30
|
|
|
if (IS_ENABLED(CONFIG_BT_CTLR_PHY_CODED) &&
|
|
|
|
is_coded_phy) {
|
|
|
|
err = duration_period_setup(scan_coded, duration, period,
|
|
|
|
&node_rx_scan_term);
|
|
|
|
if (err) {
|
|
|
|
return err;
|
2020-10-12 21:56:59 +05:30
|
|
|
}
|
|
|
|
}
|
2020-10-16 10:06:43 +05:30
|
|
|
#endif /* CONFIG_BT_CTLR_ADV_EXT */
|
2020-10-12 21:56:59 +05:30
|
|
|
|
|
|
|
#if defined(CONFIG_BT_CTLR_PRIVACY)
|
2020-10-16 10:06:43 +05:30
|
|
|
struct lll_scan *lll;
|
|
|
|
|
2020-04-08 16:43:15 +05:30
|
|
|
if (IS_ENABLED(CONFIG_BT_CTLR_ADV_EXT) && is_coded_phy) {
|
|
|
|
lll = &scan_coded->lll;
|
|
|
|
|
|
|
|
/* TODO: Privacy support in Advertising Extensions */
|
|
|
|
} else {
|
|
|
|
lll = &scan->lll;
|
|
|
|
own_addr_type = scan->own_addr_type;
|
|
|
|
}
|
|
|
|
|
2019-05-15 16:10:43 +02:00
|
|
|
ull_filter_scan_update(lll->filter_policy);
|
|
|
|
|
|
|
|
lll->rl_idx = FILTER_IDX_NONE;
|
|
|
|
lll->rpa_gen = 0;
|
|
|
|
|
|
|
|
if ((lll->type & 0x1) &&
|
2020-04-08 16:43:15 +05:30
|
|
|
(own_addr_type == BT_ADDR_LE_PUBLIC_ID ||
|
|
|
|
own_addr_type == BT_ADDR_LE_RANDOM_ID)) {
|
2019-05-15 16:10:43 +02:00
|
|
|
/* Generate RPAs if required */
|
|
|
|
ull_filter_rpa_update(false);
|
|
|
|
lll->rpa_gen = 1;
|
|
|
|
}
|
2020-10-16 10:06:43 +05:30
|
|
|
#endif /* CONFIG_BT_CTLR_PRIVACY */
|
2019-05-15 16:10:43 +02:00
|
|
|
|
2020-10-16 10:06:43 +05:30
|
|
|
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
|
|
|
#if defined(CONFIG_BT_CTLR_PHY_CODED)
|
2022-04-04 13:35:53 +05:30
|
|
|
if (!is_coded_phy || IS_PHY_ENABLED(scan, PHY_1M))
|
2020-10-16 10:06:43 +05:30
|
|
|
#endif /* CONFIG_BT_CTLR_PHY_CODED */
|
|
|
|
{
|
|
|
|
err = duration_period_update(scan, is_update_1m);
|
|
|
|
if (err) {
|
|
|
|
return err;
|
|
|
|
} else if (is_update_1m) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (IS_ENABLED(CONFIG_BT_CTLR_PHY_CODED) &&
|
|
|
|
is_coded_phy) {
|
|
|
|
err = duration_period_update(scan_coded, is_update_coded);
|
|
|
|
if (err) {
|
|
|
|
return err;
|
|
|
|
} else if (is_update_coded) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined(CONFIG_BT_CTLR_PHY_CODED)
|
2022-04-04 13:35:53 +05:30
|
|
|
if (!is_coded_phy || IS_PHY_ENABLED(scan, PHY_1M))
|
2020-10-16 10:06:43 +05:30
|
|
|
#endif /* CONFIG_BT_CTLR_PHY_CODED */
|
|
|
|
#endif /* CONFIG_BT_CTLR_ADV_EXT */
|
2020-04-14 17:26:19 +05:30
|
|
|
{
|
2020-04-08 16:43:15 +05:30
|
|
|
err = ull_scan_enable(scan);
|
|
|
|
if (err) {
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (IS_ENABLED(CONFIG_BT_CTLR_ADV_EXT) &&
|
2020-10-16 10:06:43 +05:30
|
|
|
IS_ENABLED(CONFIG_BT_CTLR_PHY_CODED) &&
|
2020-04-08 16:43:15 +05:30
|
|
|
is_coded_phy) {
|
|
|
|
err = ull_scan_enable(scan_coded);
|
|
|
|
if (err) {
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2018-12-18 05:48:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
int ull_scan_init(void)
|
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
2020-04-21 11:12:41 +05:30
|
|
|
if (IS_ENABLED(CONFIG_BT_CTLR_ADV_EXT)) {
|
|
|
|
err = ull_scan_aux_init();
|
|
|
|
if (err) {
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-04 22:21:55 +05:30
|
|
|
err = init_reset();
|
2018-12-18 05:48:20 +01:00
|
|
|
if (err) {
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ull_scan_reset(void)
|
|
|
|
{
|
2020-04-08 16:17:48 +05:30
|
|
|
uint8_t handle;
|
2018-12-18 05:48:20 +01:00
|
|
|
int err;
|
|
|
|
|
2020-05-04 17:32:48 +05:30
|
|
|
for (handle = 0U; handle < BT_CTLR_SCAN_SET; handle++) {
|
2018-12-18 05:48:20 +01:00
|
|
|
(void)disable(handle);
|
2022-06-09 16:52:44 +05:30
|
|
|
|
|
|
|
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
|
|
|
/* Initialize PHY value to 0 to not start scanning on the scan
|
|
|
|
* instance if an explicit ll_scan_params_set() has not been
|
|
|
|
* invoked from HCI to enable scanning on that PHY.
|
|
|
|
*/
|
|
|
|
ll_scan[handle].lll.phy = 0U;
|
|
|
|
#endif /* CONFIG_BT_CTLR_ADV_EXT */
|
2018-12-18 05:48:20 +01:00
|
|
|
}
|
|
|
|
|
2020-04-21 11:12:41 +05:30
|
|
|
if (IS_ENABLED(CONFIG_BT_CTLR_ADV_EXT)) {
|
|
|
|
err = ull_scan_aux_reset();
|
|
|
|
if (err) {
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-04 22:21:55 +05:30
|
|
|
err = init_reset();
|
2018-12-18 05:48:20 +01:00
|
|
|
if (err) {
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-02-12 08:54:06 +05:30
|
|
|
uint32_t ull_scan_params_set(struct lll_scan *lll, uint8_t type,
|
|
|
|
uint16_t interval, uint16_t window,
|
|
|
|
uint8_t filter_policy)
|
2018-12-18 05:48:20 +01:00
|
|
|
{
|
|
|
|
/* type value:
|
|
|
|
* 0000b - legacy 1M passive
|
|
|
|
* 0001b - legacy 1M active
|
|
|
|
* 0010b - Ext. 1M passive
|
|
|
|
* 0011b - Ext. 1M active
|
|
|
|
* 0100b - invalid
|
|
|
|
* 0101b - invalid
|
|
|
|
* 0110b - invalid
|
|
|
|
* 0111b - invalid
|
|
|
|
* 1000b - Ext. Coded passive
|
|
|
|
* 1001b - Ext. Coded active
|
|
|
|
*/
|
|
|
|
lll->type = type;
|
|
|
|
lll->filter_policy = filter_policy;
|
|
|
|
lll->interval = interval;
|
2020-10-15 15:58:17 +05:30
|
|
|
lll->ticks_window = HAL_TICKER_US_TO_TICKS((uint64_t)window *
|
2021-01-16 13:38:07 +01:00
|
|
|
SCAN_INT_UNIT_US);
|
2023-02-12 08:54:06 +05:30
|
|
|
|
|
|
|
return lll->ticks_window;
|
2018-12-18 05:48:20 +01:00
|
|
|
}
|
|
|
|
|
2020-05-27 11:26:57 -05:00
|
|
|
uint8_t ull_scan_enable(struct ll_scan_set *scan)
|
2018-12-18 05:48:20 +01:00
|
|
|
{
|
2020-05-27 11:26:57 -05:00
|
|
|
uint32_t ticks_slot_overhead;
|
2020-07-16 12:34:23 +05:30
|
|
|
uint32_t volatile ret_cb;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint32_t ticks_interval;
|
|
|
|
uint32_t ticks_anchor;
|
2022-03-28 07:20:56 +05:30
|
|
|
uint32_t ticks_offset;
|
2021-12-13 07:04:53 +05:30
|
|
|
struct lll_scan *lll;
|
2022-03-28 07:20:56 +05:30
|
|
|
uint8_t handle;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint32_t ret;
|
2018-12-18 05:48:20 +01:00
|
|
|
|
2021-12-13 07:04:53 +05:30
|
|
|
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
|
|
|
/* Initialize extend scan stop request */
|
|
|
|
scan->is_stop = 0U;
|
|
|
|
#endif /* CONFIG_BT_CTLR_ADV_EXT */
|
|
|
|
|
|
|
|
/* Initialize LLL scan context */
|
|
|
|
lll = &scan->lll;
|
2018-12-18 05:48:20 +01:00
|
|
|
lll->init_addr_type = scan->own_addr_type;
|
2021-09-28 06:09:13 +05:30
|
|
|
(void)ll_addr_read(lll->init_addr_type, lll->init_addr);
|
2021-04-27 12:35:27 +05:30
|
|
|
lll->chan = 0U;
|
|
|
|
lll->is_stop = 0U;
|
2018-12-18 05:48:20 +01:00
|
|
|
|
|
|
|
ull_hdr_init(&scan->ull);
|
|
|
|
lll_hdr_init(lll, scan);
|
|
|
|
|
2020-10-15 15:58:17 +05:30
|
|
|
ticks_interval = HAL_TICKER_US_TO_TICKS((uint64_t)lll->interval *
|
2021-01-16 13:38:07 +01:00
|
|
|
SCAN_INT_UNIT_US);
|
2018-12-18 05:48:20 +01:00
|
|
|
|
|
|
|
/* TODO: active_to_start feature port */
|
2021-04-05 12:56:51 +05:30
|
|
|
scan->ull.ticks_active_to_start = 0U;
|
|
|
|
scan->ull.ticks_prepare_to_start =
|
2018-12-18 05:48:20 +01:00
|
|
|
HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_XTAL_US);
|
2021-04-05 12:56:51 +05:30
|
|
|
scan->ull.ticks_preempt_to_start =
|
2018-12-18 05:48:20 +01:00
|
|
|
HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_PREEMPT_MIN_US);
|
2022-06-24 17:56:55 +05:30
|
|
|
|
|
|
|
if (IS_ENABLED(CONFIG_BT_CTLR_LOW_LAT)) {
|
|
|
|
ticks_slot_overhead = MAX(scan->ull.ticks_active_to_start,
|
|
|
|
scan->ull.ticks_prepare_to_start);
|
|
|
|
} else {
|
|
|
|
ticks_slot_overhead = 0U;
|
|
|
|
}
|
|
|
|
|
2023-02-12 11:19:00 +05:30
|
|
|
handle = ull_scan_handle_get(scan);
|
|
|
|
|
2023-02-12 08:54:06 +05:30
|
|
|
lll->ticks_window = scan->ticks_window;
|
2018-12-18 05:48:20 +01:00
|
|
|
if ((lll->ticks_window +
|
|
|
|
HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US)) <
|
2022-06-24 17:56:55 +05:30
|
|
|
(ticks_interval - ticks_slot_overhead)) {
|
2021-04-05 12:56:51 +05:30
|
|
|
scan->ull.ticks_slot =
|
2018-12-18 05:48:20 +01:00
|
|
|
(lll->ticks_window +
|
|
|
|
HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US));
|
2023-02-12 11:19:00 +05:30
|
|
|
|
|
|
|
#if defined(CONFIG_BT_TICKER_EXT)
|
|
|
|
ll_scan_ticker_ext[handle].ticks_slot_window =
|
|
|
|
scan->ull.ticks_slot + ticks_slot_overhead;
|
|
|
|
#endif /* CONFIG_BT_TICKER_EXT */
|
|
|
|
|
2018-12-18 05:48:20 +01:00
|
|
|
} else {
|
2020-09-07 13:54:30 +05:30
|
|
|
if (IS_ENABLED(CONFIG_BT_CTLR_SCAN_UNRESERVED)) {
|
2021-04-05 12:56:51 +05:30
|
|
|
scan->ull.ticks_slot = 0U;
|
2020-09-07 13:54:30 +05:30
|
|
|
} else {
|
2021-04-05 12:56:51 +05:30
|
|
|
scan->ull.ticks_slot = ticks_interval -
|
2022-06-24 17:56:55 +05:30
|
|
|
ticks_slot_overhead;
|
2020-09-07 13:54:30 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
lll->ticks_window = 0U;
|
2018-12-18 05:48:20 +01:00
|
|
|
|
2023-02-12 11:19:00 +05:30
|
|
|
#if defined(CONFIG_BT_TICKER_EXT)
|
|
|
|
ll_scan_ticker_ext[handle].ticks_slot_window = ticks_interval;
|
|
|
|
#endif /* CONFIG_BT_TICKER_EXT */
|
|
|
|
}
|
2022-06-24 17:56:55 +05:30
|
|
|
|
|
|
|
if (false) {
|
|
|
|
|
|
|
|
#if defined(CONFIG_BT_CTLR_ADV_EXT) && defined(CONFIG_BT_CTLR_PHY_CODED)
|
|
|
|
} else if (handle == SCAN_HANDLE_1M) {
|
|
|
|
const struct ll_scan_set *scan_coded;
|
|
|
|
|
|
|
|
scan_coded = ull_scan_set_get(SCAN_HANDLE_PHY_CODED);
|
|
|
|
if (IS_PHY_ENABLED(scan_coded, PHY_CODED) &&
|
|
|
|
(lll->ticks_window != 0U)) {
|
|
|
|
const struct lll_scan *lll_coded;
|
|
|
|
uint32_t ticks_interval_coded;
|
2022-08-16 13:07:14 +05:30
|
|
|
uint32_t ticks_window_sum_min;
|
|
|
|
uint32_t ticks_window_sum_max;
|
2022-06-24 17:56:55 +05:30
|
|
|
|
|
|
|
lll_coded = &scan_coded->lll;
|
|
|
|
ticks_interval_coded = HAL_TICKER_US_TO_TICKS(
|
|
|
|
(uint64_t)lll_coded->interval *
|
|
|
|
SCAN_INT_UNIT_US);
|
2022-08-16 13:07:14 +05:30
|
|
|
ticks_window_sum_min = lll->ticks_window +
|
|
|
|
lll_coded->ticks_window;
|
|
|
|
ticks_window_sum_max = ticks_window_sum_min +
|
|
|
|
HAL_TICKER_US_TO_TICKS(EVENT_TICKER_RES_MARGIN_US << 1);
|
2022-06-24 17:56:55 +05:30
|
|
|
/* Check if 1M and Coded PHY scanning use same interval
|
|
|
|
* and the sum of the scan window duration equals their
|
|
|
|
* interval then use continuous scanning and avoid time
|
|
|
|
* reservation from overlapping.
|
|
|
|
*/
|
|
|
|
if ((ticks_interval == ticks_interval_coded) &&
|
2022-08-16 13:07:14 +05:30
|
|
|
IN_RANGE(ticks_interval, ticks_window_sum_min,
|
|
|
|
ticks_window_sum_max)) {
|
2022-06-24 17:56:55 +05:30
|
|
|
if (IS_ENABLED(CONFIG_BT_CTLR_SCAN_UNRESERVED)) {
|
|
|
|
scan->ull.ticks_slot = 0U;
|
|
|
|
} else {
|
|
|
|
scan->ull.ticks_slot =
|
|
|
|
lll->ticks_window -
|
|
|
|
ticks_slot_overhead -
|
|
|
|
HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US) -
|
|
|
|
HAL_TICKER_US_TO_TICKS(EVENT_TICKER_RES_MARGIN_US);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Continuous scanning, no scan window stop
|
|
|
|
* ticker to be started but we will zero the
|
|
|
|
* ticks_window value when coded PHY scan is
|
|
|
|
* enabled (the next following else clause).
|
|
|
|
* Due to this the first scan window will have
|
|
|
|
* the stop ticker started but consecutive
|
|
|
|
* scan window will not have the stop ticker
|
|
|
|
* started once coded PHY scan window has been
|
|
|
|
* enabled.
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 1M scan window starts without any offset */
|
|
|
|
ticks_offset = 0U;
|
|
|
|
|
|
|
|
} else if (handle == SCAN_HANDLE_PHY_CODED) {
|
|
|
|
struct ll_scan_set *scan_1m;
|
|
|
|
|
|
|
|
scan_1m = ull_scan_set_get(SCAN_HANDLE_1M);
|
|
|
|
if (IS_PHY_ENABLED(scan_1m, PHY_1M) &&
|
|
|
|
(lll->ticks_window != 0U)) {
|
2022-08-16 13:07:14 +05:30
|
|
|
uint32_t ticks_window_sum_min;
|
|
|
|
uint32_t ticks_window_sum_max;
|
2022-06-24 17:56:55 +05:30
|
|
|
uint32_t ticks_interval_1m;
|
|
|
|
struct lll_scan *lll_1m;
|
|
|
|
|
|
|
|
lll_1m = &scan_1m->lll;
|
|
|
|
ticks_interval_1m = HAL_TICKER_US_TO_TICKS(
|
|
|
|
(uint64_t)lll_1m->interval *
|
|
|
|
SCAN_INT_UNIT_US);
|
2022-08-16 13:07:14 +05:30
|
|
|
ticks_window_sum_min = lll->ticks_window +
|
|
|
|
lll_1m->ticks_window;
|
|
|
|
ticks_window_sum_max = ticks_window_sum_min +
|
|
|
|
HAL_TICKER_US_TO_TICKS(EVENT_TICKER_RES_MARGIN_US << 1);
|
2022-06-24 17:56:55 +05:30
|
|
|
/* Check if 1M and Coded PHY scanning use same interval
|
|
|
|
* and the sum of the scan window duration equals their
|
|
|
|
* interval then use continuous scanning and avoid time
|
|
|
|
* reservation from overlapping.
|
|
|
|
*/
|
|
|
|
if ((ticks_interval == ticks_interval_1m) &&
|
2022-08-16 13:07:14 +05:30
|
|
|
IN_RANGE(ticks_interval, ticks_window_sum_min,
|
|
|
|
ticks_window_sum_max)) {
|
2022-06-24 17:56:55 +05:30
|
|
|
if (IS_ENABLED(CONFIG_BT_CTLR_SCAN_UNRESERVED)) {
|
|
|
|
scan->ull.ticks_slot = 0U;
|
|
|
|
} else {
|
|
|
|
scan->ull.ticks_slot =
|
|
|
|
lll->ticks_window -
|
|
|
|
ticks_slot_overhead -
|
|
|
|
HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US) -
|
|
|
|
HAL_TICKER_US_TO_TICKS(EVENT_TICKER_RES_MARGIN_US);
|
|
|
|
}
|
|
|
|
/* Offset the coded PHY scan window, place
|
|
|
|
* after 1M scan window.
|
|
|
|
* Have some margin for jitter due to ticker
|
|
|
|
* resolution.
|
|
|
|
*/
|
|
|
|
ticks_offset = lll_1m->ticks_window;
|
|
|
|
ticks_offset += HAL_TICKER_US_TO_TICKS(
|
|
|
|
EVENT_TICKER_RES_MARGIN_US << 1);
|
|
|
|
|
|
|
|
/* Continuous scanning, no scan window stop
|
|
|
|
* ticker started for both 1M and coded PHY.
|
|
|
|
*/
|
|
|
|
lll->ticks_window = 0U;
|
|
|
|
lll_1m->ticks_window = 0U;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
ticks_offset = 0U;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ticks_offset = 0U;
|
|
|
|
}
|
|
|
|
#endif /* CONFIG_BT_CTLR_ADV_EXT && CONFIG_BT_CTLR_PHY_CODED */
|
|
|
|
|
2018-12-18 05:48:20 +01:00
|
|
|
} else {
|
2022-06-24 17:56:55 +05:30
|
|
|
ticks_offset = 0U;
|
2018-12-18 05:48:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
ticks_anchor = ticker_ticks_now_get();
|
2022-09-09 11:11:46 +02:00
|
|
|
ticks_anchor += HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US);
|
|
|
|
|
2018-12-18 05:48:20 +01:00
|
|
|
#if defined(CONFIG_BT_CENTRAL) && defined(CONFIG_BT_CTLR_SCHED_ADVANCED)
|
|
|
|
if (!lll->conn) {
|
2020-05-27 11:26:57 -05:00
|
|
|
uint32_t ticks_ref = 0U;
|
|
|
|
uint32_t offset_us = 0U;
|
2022-02-16 07:05:26 +05:30
|
|
|
int err;
|
2018-12-18 05:48:20 +01:00
|
|
|
|
2022-02-23 11:16:05 +05:30
|
|
|
err = ull_sched_after_cen_slot_get(TICKER_USER_ID_THREAD,
|
|
|
|
(scan->ull.ticks_slot +
|
|
|
|
ticks_slot_overhead),
|
|
|
|
&ticks_ref, &offset_us);
|
2018-12-18 05:48:20 +01:00
|
|
|
|
|
|
|
/* Use the ticks_ref as scanner's anchor if a free time space
|
2021-09-20 16:25:06 +02:00
|
|
|
* after any central role is available (indicated by a non-zero
|
2018-12-18 05:48:20 +01:00
|
|
|
* offset_us value).
|
|
|
|
*/
|
2022-02-16 07:05:26 +05:30
|
|
|
if (!err) {
|
2018-12-18 05:48:20 +01:00
|
|
|
ticks_anchor = ticks_ref +
|
|
|
|
HAL_TICKER_US_TO_TICKS(offset_us);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* CONFIG_BT_CENTRAL && CONFIG_BT_CTLR_SCHED_ADVANCED */
|
|
|
|
|
2020-07-16 12:34:23 +05:30
|
|
|
ret_cb = TICKER_STATUS_BUSY;
|
2023-02-12 11:19:00 +05:30
|
|
|
|
|
|
|
#if defined(CONFIG_BT_TICKER_EXT)
|
|
|
|
ret = ticker_start_ext(
|
|
|
|
#else
|
|
|
|
ret = ticker_start(
|
|
|
|
#endif /* CONFIG_BT_TICKER_EXT */
|
|
|
|
TICKER_INSTANCE_ID_CTLR,
|
2020-04-08 16:43:15 +05:30
|
|
|
TICKER_USER_ID_THREAD, TICKER_ID_SCAN_BASE + handle,
|
2022-03-28 07:20:56 +05:30
|
|
|
(ticks_anchor + ticks_offset), 0, ticks_interval,
|
2020-10-15 15:58:17 +05:30
|
|
|
HAL_TICKER_REMAINDER((uint64_t)lll->interval *
|
2021-01-16 13:38:07 +01:00
|
|
|
SCAN_INT_UNIT_US),
|
2018-12-18 05:48:20 +01:00
|
|
|
TICKER_NULL_LAZY,
|
2021-04-05 12:56:51 +05:30
|
|
|
(scan->ull.ticks_slot + ticks_slot_overhead),
|
2018-12-18 05:48:20 +01:00
|
|
|
ticker_cb, scan,
|
2023-02-12 11:19:00 +05:30
|
|
|
ull_ticker_status_give, (void *)&ret_cb
|
|
|
|
#if defined(CONFIG_BT_TICKER_EXT)
|
|
|
|
,
|
|
|
|
&ll_scan_ticker_ext[handle]
|
|
|
|
#endif /* CONFIG_BT_TICKER_EXT */
|
|
|
|
);
|
2018-12-18 05:48:20 +01:00
|
|
|
ret = ull_ticker_status_take(ret, &ret_cb);
|
|
|
|
if (ret != TICKER_STATUS_SUCCESS) {
|
|
|
|
return BT_HCI_ERR_CMD_DISALLOWED;
|
|
|
|
}
|
|
|
|
|
2019-03-26 19:57:45 -06:00
|
|
|
scan->is_enabled = 1U;
|
2018-12-18 05:48:20 +01:00
|
|
|
|
|
|
|
#if defined(CONFIG_BT_CTLR_PRIVACY)
|
|
|
|
#if defined(CONFIG_BT_BROADCASTER)
|
|
|
|
if (!ull_adv_is_enabled_get(0))
|
|
|
|
#endif
|
|
|
|
{
|
2019-05-09 18:39:26 +05:30
|
|
|
ull_filter_adv_scan_state_cb(BIT(1));
|
2018-12-18 05:48:20 +01:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-04-08 16:17:48 +05:30
|
|
|
uint8_t ull_scan_disable(uint8_t handle, struct ll_scan_set *scan)
|
2018-12-18 05:48:20 +01:00
|
|
|
{
|
2020-11-12 15:11:43 +01:00
|
|
|
int err;
|
2018-12-18 05:48:20 +01:00
|
|
|
|
2021-12-13 07:04:53 +05:30
|
|
|
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
|
|
|
/* Request Extended Scan stop */
|
|
|
|
scan->is_stop = 1U;
|
|
|
|
cpu_dmb();
|
|
|
|
#endif /* CONFIG_BT_CTLR_ADV_EXT */
|
|
|
|
|
2020-11-12 15:11:43 +01:00
|
|
|
err = ull_ticker_stop_with_mark(TICKER_ID_SCAN_BASE + handle,
|
|
|
|
scan, &scan->lll);
|
|
|
|
LL_ASSERT(err == 0 || err == -EALREADY);
|
|
|
|
if (err) {
|
2018-12-18 05:48:20 +01:00
|
|
|
return BT_HCI_ERR_CMD_DISALLOWED;
|
|
|
|
}
|
|
|
|
|
2021-12-13 07:04:53 +05:30
|
|
|
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
|
|
|
/* Find and stop associated auxiliary scan contexts */
|
|
|
|
for (uint8_t aux_handle = 0; aux_handle < CONFIG_BT_CTLR_SCAN_AUX_SET;
|
|
|
|
aux_handle++) {
|
|
|
|
struct lll_scan_aux *aux_scan_lll;
|
|
|
|
struct ll_scan_set *aux_scan;
|
|
|
|
struct ll_scan_aux_set *aux;
|
|
|
|
|
|
|
|
aux = ull_scan_aux_set_get(aux_handle);
|
|
|
|
aux_scan_lll = aux->parent;
|
|
|
|
if (!aux_scan_lll) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
aux_scan = HDR_LLL2ULL(aux_scan_lll);
|
|
|
|
if (aux_scan == scan) {
|
2022-09-21 09:52:08 +05:30
|
|
|
void *parent;
|
|
|
|
|
2021-12-13 07:04:53 +05:30
|
|
|
err = ull_scan_aux_stop(aux);
|
|
|
|
if (err && (err != -EALREADY)) {
|
|
|
|
return BT_HCI_ERR_CMD_DISALLOWED;
|
|
|
|
}
|
2022-03-09 11:19:24 +05:30
|
|
|
|
2022-09-21 09:52:08 +05:30
|
|
|
/* Use a local variable to assert on auxiliary context's
|
|
|
|
* release.
|
|
|
|
* Under race condition a released aux context can be
|
|
|
|
* allocated for reception of chain PDU of a periodic
|
|
|
|
* sync role.
|
|
|
|
*/
|
|
|
|
parent = aux->parent;
|
|
|
|
LL_ASSERT(!parent || (parent != aux_scan_lll));
|
2021-12-13 07:04:53 +05:30
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* CONFIG_BT_CTLR_ADV_EXT */
|
|
|
|
|
2018-12-18 05:48:20 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-10-16 10:06:43 +05:30
|
|
|
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
|
|
|
void ull_scan_done(struct node_rx_event_done *done)
|
|
|
|
{
|
|
|
|
struct node_rx_hdr *rx_hdr;
|
|
|
|
struct ll_scan_set *scan;
|
|
|
|
struct lll_scan *lll;
|
|
|
|
uint8_t handle;
|
|
|
|
uint32_t ret;
|
|
|
|
|
2021-04-05 12:56:51 +05:30
|
|
|
/* Get reference to ULL context */
|
|
|
|
scan = CONTAINER_OF(done->param, struct ll_scan_set, ull);
|
|
|
|
lll = &scan->lll;
|
|
|
|
|
2020-10-16 10:06:43 +05:30
|
|
|
if (likely(scan->duration_lazy || !lll->duration_reload ||
|
|
|
|
lll->duration_expire)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-10-07 12:00:17 +05:30
|
|
|
/* Prevent duplicate terminate event generation */
|
|
|
|
lll->duration_reload = 0U;
|
2020-10-16 10:06:43 +05:30
|
|
|
|
|
|
|
handle = ull_scan_handle_get(scan);
|
|
|
|
LL_ASSERT(handle < BT_CTLR_SCAN_SET);
|
|
|
|
|
|
|
|
#if defined(CONFIG_BT_CTLR_PHY_CODED)
|
2021-10-07 12:00:17 +05:30
|
|
|
/* Prevent duplicate terminate event if ull_scan_done get called by
|
|
|
|
* the other scan instance.
|
2020-10-16 10:06:43 +05:30
|
|
|
*/
|
|
|
|
struct ll_scan_set *scan_other;
|
|
|
|
|
|
|
|
if (handle == SCAN_HANDLE_1M) {
|
|
|
|
scan_other = ull_scan_set_get(SCAN_HANDLE_PHY_CODED);
|
|
|
|
} else {
|
|
|
|
scan_other = ull_scan_set_get(SCAN_HANDLE_1M);
|
|
|
|
}
|
2021-10-07 12:00:17 +05:30
|
|
|
scan_other->lll.duration_reload = 0U;
|
2020-10-16 10:06:43 +05:30
|
|
|
#endif /* CONFIG_BT_CTLR_PHY_CODED */
|
|
|
|
|
2021-10-07 12:00:17 +05:30
|
|
|
rx_hdr = (void *)scan->node_rx_scan_term;
|
2020-10-16 10:06:43 +05:30
|
|
|
rx_hdr->type = NODE_RX_TYPE_EXT_SCAN_TERMINATE;
|
|
|
|
rx_hdr->handle = handle;
|
|
|
|
|
|
|
|
ret = ticker_stop(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_ULL_HIGH,
|
2021-08-17 14:34:39 +05:30
|
|
|
(TICKER_ID_SCAN_BASE + handle), ticker_stop_ext_op_cb,
|
2020-10-16 10:06:43 +05:30
|
|
|
scan);
|
|
|
|
|
|
|
|
LL_ASSERT((ret == TICKER_STATUS_SUCCESS) ||
|
|
|
|
(ret == TICKER_STATUS_BUSY));
|
|
|
|
}
|
|
|
|
|
|
|
|
void ull_scan_term_dequeue(uint8_t handle)
|
|
|
|
{
|
|
|
|
struct ll_scan_set *scan;
|
|
|
|
|
|
|
|
scan = ull_scan_set_get(handle);
|
|
|
|
LL_ASSERT(scan);
|
|
|
|
|
|
|
|
scan->is_enabled = 0U;
|
|
|
|
|
|
|
|
#if defined(CONFIG_BT_CTLR_PHY_CODED)
|
|
|
|
if (handle == SCAN_HANDLE_1M) {
|
|
|
|
struct ll_scan_set *scan_coded;
|
|
|
|
|
|
|
|
scan_coded = ull_scan_set_get(SCAN_HANDLE_PHY_CODED);
|
2022-04-04 13:35:53 +05:30
|
|
|
if (IS_PHY_ENABLED(scan_coded, PHY_CODED)) {
|
2020-10-16 10:06:43 +05:30
|
|
|
uint8_t err;
|
|
|
|
|
|
|
|
err = disable(SCAN_HANDLE_PHY_CODED);
|
|
|
|
LL_ASSERT(!err);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
struct ll_scan_set *scan_1m;
|
|
|
|
|
|
|
|
scan_1m = ull_scan_set_get(SCAN_HANDLE_1M);
|
2022-04-04 13:35:53 +05:30
|
|
|
if (IS_PHY_ENABLED(scan_1m, PHY_1M)) {
|
2020-10-16 10:06:43 +05:30
|
|
|
uint8_t err;
|
|
|
|
|
|
|
|
err = disable(SCAN_HANDLE_1M);
|
|
|
|
LL_ASSERT(!err);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* CONFIG_BT_CTLR_PHY_CODED */
|
|
|
|
}
|
|
|
|
#endif /* CONFIG_BT_CTLR_ADV_EXT */
|
|
|
|
|
2020-04-08 16:17:48 +05:30
|
|
|
struct ll_scan_set *ull_scan_set_get(uint8_t handle)
|
2018-12-18 05:48:20 +01:00
|
|
|
{
|
2020-05-04 17:32:48 +05:30
|
|
|
if (handle >= BT_CTLR_SCAN_SET) {
|
2018-12-18 05:48:20 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return &ll_scan[handle];
|
|
|
|
}
|
|
|
|
|
2020-04-08 16:17:48 +05:30
|
|
|
uint8_t ull_scan_handle_get(struct ll_scan_set *scan)
|
2018-12-18 05:48:20 +01:00
|
|
|
{
|
2020-05-27 11:26:57 -05:00
|
|
|
return ((uint8_t *)scan - (uint8_t *)ll_scan) / sizeof(*scan);
|
2018-12-18 05:48:20 +01:00
|
|
|
}
|
|
|
|
|
2020-04-08 16:17:48 +05:30
|
|
|
uint8_t ull_scan_lll_handle_get(struct lll_scan *lll)
|
2019-07-03 12:02:52 +05:30
|
|
|
{
|
|
|
|
return ull_scan_handle_get((void *)lll->hdr.parent);
|
|
|
|
}
|
|
|
|
|
2020-11-05 18:13:25 +05:30
|
|
|
struct ll_scan_set *ull_scan_is_valid_get(struct ll_scan_set *scan)
|
|
|
|
{
|
|
|
|
if (((uint8_t *)scan < (uint8_t *)ll_scan) ||
|
|
|
|
((uint8_t *)scan > ((uint8_t *)ll_scan +
|
|
|
|
(sizeof(struct ll_scan_set) *
|
|
|
|
(BT_CTLR_SCAN_SET - 1))))) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return scan;
|
|
|
|
}
|
|
|
|
|
2021-12-19 06:34:21 +05:30
|
|
|
struct lll_scan *ull_scan_lll_is_valid_get(struct lll_scan *lll)
|
|
|
|
{
|
|
|
|
struct ll_scan_set *scan;
|
|
|
|
|
|
|
|
scan = HDR_LLL2ULL(lll);
|
|
|
|
scan = ull_scan_is_valid_get(scan);
|
|
|
|
if (scan) {
|
|
|
|
return &scan->lll;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2020-04-08 16:17:48 +05:30
|
|
|
struct ll_scan_set *ull_scan_is_enabled_get(uint8_t handle)
|
2018-12-18 05:48:20 +01:00
|
|
|
{
|
|
|
|
struct ll_scan_set *scan;
|
|
|
|
|
|
|
|
scan = ull_scan_set_get(handle);
|
|
|
|
if (!scan || !scan->is_enabled) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return scan;
|
|
|
|
}
|
|
|
|
|
2020-04-08 16:17:48 +05:30
|
|
|
struct ll_scan_set *ull_scan_is_disabled_get(uint8_t handle)
|
2018-12-18 05:48:20 +01:00
|
|
|
{
|
|
|
|
struct ll_scan_set *scan;
|
|
|
|
|
|
|
|
scan = ull_scan_set_get(handle);
|
|
|
|
if (!scan || scan->is_enabled) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return scan;
|
|
|
|
}
|
|
|
|
|
2020-04-08 16:17:48 +05:30
|
|
|
uint32_t ull_scan_is_enabled(uint8_t handle)
|
2018-12-18 05:48:20 +01:00
|
|
|
{
|
|
|
|
struct ll_scan_set *scan;
|
|
|
|
|
|
|
|
scan = ull_scan_is_enabled_get(handle);
|
|
|
|
if (!scan) {
|
2021-09-09 15:45:49 +05:30
|
|
|
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC)
|
|
|
|
scan = ull_scan_set_get(handle);
|
|
|
|
|
2021-12-09 06:08:30 +05:30
|
|
|
return scan->periodic.sync ? ULL_SCAN_IS_SYNC : 0U;
|
2021-09-09 15:45:49 +05:30
|
|
|
#else
|
2021-09-27 09:15:45 +05:30
|
|
|
return 0U;
|
2021-09-09 15:45:49 +05:30
|
|
|
#endif
|
2018-12-18 05:48:20 +01:00
|
|
|
}
|
|
|
|
|
2020-05-27 11:26:57 -05:00
|
|
|
return (((uint32_t)scan->is_enabled << scan->lll.type) |
|
2018-12-18 05:48:20 +01:00
|
|
|
#if defined(CONFIG_BT_CENTRAL)
|
2021-09-27 09:15:45 +05:30
|
|
|
(scan->lll.conn ? ULL_SCAN_IS_INITIATOR : 0U) |
|
2021-09-09 15:45:49 +05:30
|
|
|
#endif
|
|
|
|
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC)
|
2021-12-09 06:08:30 +05:30
|
|
|
(scan->periodic.sync ? ULL_SCAN_IS_SYNC : 0U) |
|
2018-12-18 05:48:20 +01:00
|
|
|
#endif
|
2021-09-27 09:15:45 +05:30
|
|
|
0U);
|
2018-12-18 05:48:20 +01:00
|
|
|
}
|
|
|
|
|
2020-04-08 16:17:48 +05:30
|
|
|
uint32_t ull_scan_filter_pol_get(uint8_t handle)
|
2018-12-18 05:48:20 +01:00
|
|
|
{
|
|
|
|
struct ll_scan_set *scan;
|
|
|
|
|
|
|
|
scan = ull_scan_is_enabled_get(handle);
|
|
|
|
if (!scan) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return scan->lll.filter_policy;
|
|
|
|
}
|
|
|
|
|
2019-02-04 22:21:55 +05:30
|
|
|
static int init_reset(void)
|
2018-12-18 05:48:20 +01:00
|
|
|
{
|
2020-09-01 20:44:43 +10:00
|
|
|
#if defined(CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL) && \
|
|
|
|
!defined(CONFIG_BT_CTLR_ADV_EXT)
|
|
|
|
ll_scan[0].lll.tx_pwr_lvl = RADIO_TXP_DEFAULT;
|
|
|
|
#endif /* CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL && !CONFIG_BT_CTLR_ADV_EXT */
|
|
|
|
|
2018-12-18 05:48:20 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-09-15 11:48:21 +05:30
|
|
|
static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
|
|
|
|
uint32_t remainder, uint16_t lazy, uint8_t force,
|
|
|
|
void *param)
|
2018-12-18 05:48:20 +01:00
|
|
|
{
|
2019-02-04 22:21:55 +05:30
|
|
|
static memq_link_t link;
|
|
|
|
static struct mayfly mfy = {0, 0, &link, NULL, lll_scan_prepare};
|
2018-12-18 05:48:20 +01:00
|
|
|
static struct lll_prepare_param p;
|
2020-10-12 21:56:59 +05:30
|
|
|
struct ll_scan_set *scan;
|
|
|
|
struct lll_scan *lll;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint32_t ret;
|
|
|
|
uint8_t ref;
|
2018-12-18 05:48:20 +01:00
|
|
|
|
2020-10-12 21:56:59 +05:30
|
|
|
DEBUG_RADIO_PREPARE_O(1);
|
|
|
|
|
|
|
|
scan = param;
|
|
|
|
lll = &scan->lll;
|
2021-08-03 06:37:09 +05:30
|
|
|
|
|
|
|
/* Increment prepare reference count */
|
|
|
|
ref = ull_ref_inc(&scan->ull);
|
|
|
|
LL_ASSERT(ref);
|
|
|
|
|
|
|
|
/* Append timing parameters */
|
|
|
|
p.ticks_at_expire = ticks_at_expire;
|
|
|
|
p.remainder = remainder;
|
|
|
|
p.lazy = lazy;
|
|
|
|
p.param = lll;
|
|
|
|
p.force = force;
|
|
|
|
mfy.param = &p;
|
|
|
|
|
|
|
|
/* Kick LLL prepare */
|
|
|
|
ret = mayfly_enqueue(TICKER_USER_ID_ULL_HIGH, TICKER_USER_ID_LLL,
|
|
|
|
0, &mfy);
|
|
|
|
LL_ASSERT(!ret);
|
|
|
|
|
2020-10-12 21:56:59 +05:30
|
|
|
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
|
|
|
if (lll->duration_expire) {
|
|
|
|
uint16_t elapsed;
|
|
|
|
|
|
|
|
elapsed = lazy + 1;
|
|
|
|
if (lll->duration_expire > elapsed) {
|
|
|
|
lll->duration_expire -= elapsed;
|
|
|
|
} else {
|
|
|
|
if (scan->duration_lazy) {
|
|
|
|
uint8_t handle;
|
|
|
|
uint16_t duration_lazy;
|
|
|
|
|
|
|
|
duration_lazy = lll->duration_expire +
|
|
|
|
scan->duration_lazy - elapsed;
|
|
|
|
|
|
|
|
handle = ull_scan_handle_get(scan);
|
|
|
|
LL_ASSERT(handle < BT_CTLR_SCAN_SET);
|
|
|
|
|
|
|
|
ret = ticker_update(TICKER_INSTANCE_ID_CTLR,
|
|
|
|
TICKER_USER_ID_ULL_HIGH,
|
|
|
|
(TICKER_ID_SCAN_BASE +
|
|
|
|
handle), 0, 0, 0, 0,
|
|
|
|
duration_lazy, 0,
|
|
|
|
NULL, NULL);
|
|
|
|
LL_ASSERT((ret == TICKER_STATUS_SUCCESS) ||
|
|
|
|
(ret == TICKER_STATUS_BUSY));
|
2020-08-04 07:29:52 +02:00
|
|
|
}
|
|
|
|
|
2020-10-12 21:56:59 +05:30
|
|
|
lll->duration_expire = 0U;
|
|
|
|
}
|
2020-10-16 10:06:43 +05:30
|
|
|
} else if (lll->duration_reload && lazy) {
|
|
|
|
uint8_t handle;
|
|
|
|
|
|
|
|
handle = ull_scan_handle_get(scan);
|
|
|
|
LL_ASSERT(handle < BT_CTLR_SCAN_SET);
|
|
|
|
|
2020-10-12 21:56:59 +05:30
|
|
|
lll->duration_expire = lll->duration_reload;
|
|
|
|
ret = ticker_update(TICKER_INSTANCE_ID_CTLR,
|
|
|
|
TICKER_USER_ID_ULL_HIGH,
|
2020-10-16 10:06:43 +05:30
|
|
|
(TICKER_ID_SCAN_BASE + handle),
|
2020-10-12 21:56:59 +05:30
|
|
|
0, 0, 0, 0, 1, 1, NULL, NULL);
|
|
|
|
LL_ASSERT((ret == TICKER_STATUS_SUCCESS) ||
|
|
|
|
(ret == TICKER_STATUS_BUSY));
|
|
|
|
}
|
|
|
|
#endif /* CONFIG_BT_CTLR_ADV_EXT */
|
2018-12-18 05:48:20 +01:00
|
|
|
|
|
|
|
DEBUG_RADIO_PREPARE_O(1);
|
|
|
|
}
|
|
|
|
|
2020-10-12 21:56:59 +05:30
|
|
|
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
2020-10-16 10:06:43 +05:30
|
|
|
static uint8_t is_scan_update(uint8_t handle, uint16_t duration,
|
|
|
|
uint16_t period, struct ll_scan_set **scan,
|
|
|
|
struct node_rx_pdu **node_rx_scan_term)
|
|
|
|
{
|
|
|
|
*scan = ull_scan_set_get(handle);
|
|
|
|
*node_rx_scan_term = (void *)(*scan)->node_rx_scan_term;
|
|
|
|
return duration && period && (*scan)->lll.duration_reload &&
|
|
|
|
(*scan)->duration_lazy;
|
|
|
|
}
|
|
|
|
|
|
|
|
static uint8_t duration_period_setup(struct ll_scan_set *scan,
|
|
|
|
uint16_t duration, uint16_t period,
|
|
|
|
struct node_rx_pdu **node_rx_scan_term)
|
2020-08-04 07:29:52 +02:00
|
|
|
{
|
2020-10-12 21:56:59 +05:30
|
|
|
struct lll_scan *lll;
|
2020-08-04 07:29:52 +02:00
|
|
|
|
2020-10-16 10:06:43 +05:30
|
|
|
lll = &scan->lll;
|
|
|
|
if (duration) {
|
2020-10-17 05:48:31 +05:30
|
|
|
lll->duration_reload =
|
|
|
|
ULL_SCAN_DURATION_TO_EVENTS(duration,
|
|
|
|
scan->lll.interval);
|
2020-10-16 10:06:43 +05:30
|
|
|
if (period) {
|
|
|
|
if (IS_ENABLED(CONFIG_BT_CTLR_PARAM_CHECK) &&
|
2020-10-17 05:48:31 +05:30
|
|
|
(duration >= ULL_SCAN_PERIOD_TO_DURATION(period))) {
|
2020-10-16 10:06:43 +05:30
|
|
|
return BT_HCI_ERR_INVALID_PARAM;
|
|
|
|
}
|
|
|
|
|
2020-10-17 05:48:31 +05:30
|
|
|
scan->duration_lazy =
|
|
|
|
ULL_SCAN_PERIOD_TO_EVENTS(period,
|
|
|
|
scan->lll.interval);
|
2020-10-16 10:06:43 +05:30
|
|
|
scan->duration_lazy -= lll->duration_reload;
|
|
|
|
scan->node_rx_scan_term = NULL;
|
|
|
|
} else {
|
|
|
|
struct node_rx_pdu *node_rx;
|
|
|
|
void *link_scan_term;
|
|
|
|
|
|
|
|
scan->duration_lazy = 0U;
|
|
|
|
|
|
|
|
if (*node_rx_scan_term) {
|
|
|
|
scan->node_rx_scan_term =
|
|
|
|
(void *)*node_rx_scan_term;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The alloc here used for ext scan termination event */
|
|
|
|
link_scan_term = ll_rx_link_alloc();
|
|
|
|
if (!link_scan_term) {
|
|
|
|
return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
|
|
|
|
}
|
|
|
|
|
|
|
|
node_rx = ll_rx_alloc();
|
|
|
|
if (!node_rx) {
|
|
|
|
ll_rx_link_release(link_scan_term);
|
|
|
|
|
|
|
|
return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
|
|
|
|
}
|
|
|
|
|
|
|
|
node_rx->hdr.link = (void *)link_scan_term;
|
|
|
|
scan->node_rx_scan_term = (void *)node_rx;
|
|
|
|
*node_rx_scan_term = node_rx;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
lll->duration_reload = 0U;
|
|
|
|
scan->duration_lazy = 0U;
|
|
|
|
scan->node_rx_scan_term = NULL;
|
2020-08-04 07:29:52 +02:00
|
|
|
}
|
|
|
|
|
2020-10-16 10:06:43 +05:30
|
|
|
return 0;
|
|
|
|
}
|
2020-08-04 07:29:52 +02:00
|
|
|
|
2020-10-16 10:06:43 +05:30
|
|
|
static uint8_t duration_period_update(struct ll_scan_set *scan,
|
|
|
|
uint8_t is_update)
|
|
|
|
{
|
|
|
|
if (is_update) {
|
|
|
|
uint32_t volatile ret_cb;
|
|
|
|
uint32_t ret;
|
2020-10-12 21:56:59 +05:30
|
|
|
|
2020-10-16 10:06:43 +05:30
|
|
|
scan->lll.duration_expire = 0U;
|
2020-08-04 07:29:52 +02:00
|
|
|
|
2020-10-16 10:06:43 +05:30
|
|
|
ret_cb = TICKER_STATUS_BUSY;
|
|
|
|
ret = ticker_update(TICKER_INSTANCE_ID_CTLR,
|
|
|
|
TICKER_USER_ID_THREAD,
|
|
|
|
(TICKER_ID_SCAN_BASE +
|
|
|
|
ull_scan_handle_get(scan)),
|
|
|
|
0, 0, 0, 0, 1, 1,
|
|
|
|
ull_ticker_status_give, (void *)&ret_cb);
|
|
|
|
ret = ull_ticker_status_take(ret, &ret_cb);
|
|
|
|
if (ret != TICKER_STATUS_SUCCESS) {
|
|
|
|
return BT_HCI_ERR_CMD_DISALLOWED;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
scan->lll.duration_expire = scan->lll.duration_reload;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2020-08-04 07:29:52 +02:00
|
|
|
}
|
|
|
|
|
2021-08-17 14:34:39 +05:30
|
|
|
static void ticker_stop_ext_op_cb(uint32_t status, void *param)
|
2020-08-04 07:29:52 +02:00
|
|
|
{
|
|
|
|
static memq_link_t link;
|
2021-08-16 16:50:07 +05:30
|
|
|
static struct mayfly mfy = {0, 0, &link, NULL, ext_disable};
|
|
|
|
uint32_t ret;
|
2020-08-04 07:29:52 +02:00
|
|
|
|
|
|
|
/* Ignore if race between thread and ULL */
|
|
|
|
if (status != TICKER_STATUS_SUCCESS) {
|
|
|
|
/* TODO: detect race */
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-08-16 16:50:07 +05:30
|
|
|
/* Check if any pending LLL events that need to be aborted */
|
|
|
|
mfy.param = param;
|
|
|
|
ret = mayfly_enqueue(TICKER_USER_ID_ULL_LOW,
|
|
|
|
TICKER_USER_ID_ULL_HIGH, 0, &mfy);
|
|
|
|
LL_ASSERT(!ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ext_disable(void *param)
|
|
|
|
{
|
|
|
|
struct ll_scan_set *scan;
|
|
|
|
struct ull_hdr *hdr;
|
|
|
|
|
|
|
|
/* Check ref count to determine if any pending LLL events in pipeline */
|
2020-08-04 07:29:52 +02:00
|
|
|
scan = param;
|
2020-10-16 10:06:43 +05:30
|
|
|
hdr = &scan->ull;
|
|
|
|
if (ull_ref_get(hdr)) {
|
2021-08-16 16:50:07 +05:30
|
|
|
static memq_link_t link;
|
|
|
|
static struct mayfly mfy = {0, 0, &link, NULL, lll_disable};
|
2021-04-05 18:54:49 +05:30
|
|
|
uint32_t ret;
|
|
|
|
|
2021-08-16 16:50:07 +05:30
|
|
|
mfy.param = &scan->lll;
|
2021-04-06 12:10:00 +05:30
|
|
|
|
2021-08-16 16:50:07 +05:30
|
|
|
/* Setup disabled callback to be called when ref count
|
|
|
|
* returns to zero.
|
|
|
|
*/
|
|
|
|
LL_ASSERT(!hdr->disabled_cb);
|
2020-10-16 10:06:43 +05:30
|
|
|
hdr->disabled_param = mfy.param;
|
|
|
|
hdr->disabled_cb = ext_disabled_cb;
|
|
|
|
|
2021-08-16 16:50:07 +05:30
|
|
|
/* Trigger LLL disable */
|
|
|
|
ret = mayfly_enqueue(TICKER_USER_ID_ULL_HIGH,
|
2020-10-16 10:06:43 +05:30
|
|
|
TICKER_USER_ID_LLL, 0, &mfy);
|
|
|
|
LL_ASSERT(!ret);
|
|
|
|
} else {
|
2021-08-16 16:50:07 +05:30
|
|
|
/* No pending LLL events */
|
|
|
|
ext_disabled_cb(&scan->lll);
|
2020-10-16 10:06:43 +05:30
|
|
|
}
|
2020-08-04 07:29:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ext_disabled_cb(void *param)
|
|
|
|
{
|
2020-10-12 21:56:59 +05:30
|
|
|
struct node_rx_hdr *rx_hdr;
|
|
|
|
struct ll_scan_set *scan;
|
|
|
|
struct lll_scan *lll;
|
2020-08-04 07:29:52 +02:00
|
|
|
|
|
|
|
/* Under race condition, if a connection has been established then
|
|
|
|
* node_rx is already utilized to send terminate event on connection
|
|
|
|
*/
|
2020-10-12 21:56:59 +05:30
|
|
|
lll = (void *)param;
|
2021-04-05 12:56:51 +05:30
|
|
|
scan = HDR_LLL2ULL(lll);
|
2020-10-12 21:56:59 +05:30
|
|
|
rx_hdr = (void *)scan->node_rx_scan_term;
|
2020-08-04 07:29:52 +02:00
|
|
|
if (!rx_hdr) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* NOTE: parameters are already populated on disable,
|
|
|
|
* just enqueue here
|
|
|
|
*/
|
2022-11-15 09:31:44 +01:00
|
|
|
ll_rx_put_sched(rx_hdr->link, rx_hdr);
|
2020-08-04 07:29:52 +02:00
|
|
|
}
|
2020-10-12 21:56:59 +05:30
|
|
|
#endif /* CONFIG_BT_CTLR_ADV_EXT */
|
2020-08-04 07:29:52 +02:00
|
|
|
|
2020-04-08 16:17:48 +05:30
|
|
|
static uint8_t disable(uint8_t handle)
|
2018-12-18 05:48:20 +01:00
|
|
|
{
|
|
|
|
struct ll_scan_set *scan;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint8_t ret;
|
2018-12-18 05:48:20 +01:00
|
|
|
|
|
|
|
scan = ull_scan_is_enabled_get(handle);
|
2019-02-12 17:09:22 +05:30
|
|
|
if (!scan) {
|
|
|
|
return BT_HCI_ERR_CMD_DISALLOWED;
|
|
|
|
}
|
|
|
|
|
2019-05-01 15:14:12 +05:30
|
|
|
#if defined(CONFIG_BT_CENTRAL)
|
2019-02-12 17:09:22 +05:30
|
|
|
if (scan->lll.conn) {
|
2018-12-18 05:48:20 +01:00
|
|
|
return BT_HCI_ERR_CMD_DISALLOWED;
|
|
|
|
}
|
2019-02-12 17:09:22 +05:30
|
|
|
#endif
|
2018-12-18 05:48:20 +01:00
|
|
|
|
|
|
|
ret = ull_scan_disable(handle, scan);
|
|
|
|
if (ret) {
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2019-03-26 19:57:45 -06:00
|
|
|
scan->is_enabled = 0U;
|
2018-12-18 05:48:20 +01:00
|
|
|
|
2020-10-12 21:56:59 +05:30
|
|
|
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
2020-08-04 07:29:52 +02:00
|
|
|
if (scan->node_rx_scan_term) {
|
|
|
|
struct node_rx_pdu *node_rx_scan_term =
|
|
|
|
(void *)scan->node_rx_scan_term;
|
|
|
|
|
|
|
|
scan->node_rx_scan_term = NULL;
|
|
|
|
|
|
|
|
ll_rx_link_release(node_rx_scan_term->hdr.link);
|
|
|
|
ll_rx_release(node_rx_scan_term);
|
|
|
|
}
|
2020-10-12 21:56:59 +05:30
|
|
|
#endif /* CONFIG_BT_CTLR_ADV_EXT */
|
|
|
|
|
|
|
|
#if defined(CONFIG_BT_CTLR_PRIVACY)
|
|
|
|
#if defined(CONFIG_BT_BROADCASTER)
|
|
|
|
if (!ull_adv_is_enabled_get(0))
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
ull_filter_adv_scan_state_cb(0);
|
|
|
|
}
|
|
|
|
#endif
|
2020-08-04 07:29:52 +02:00
|
|
|
|
2018-12-18 05:48:20 +01:00
|
|
|
return 0;
|
|
|
|
}
|