Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bluetooth: Controller: Implement Periodic Advertiser List #38338

Merged
merged 5 commits into from
Oct 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions subsys/bluetooth/controller/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,12 @@ if(CONFIG_BT_LL_SW_SPLIT)
ll_sw/lll_chan.c
)
endif()
zephyr_library_sources_ifdef(
CONFIG_BT_CTLR_FILTER_ACCEPT_LIST
ll_sw/ull_filter.c
)
if(CONFIG_BT_CTLR_FILTER_ACCEPT_LIST OR
CONFIG_BT_CTLR_SYNC_PERIODIC_ADV_LIST)
zephyr_library_sources(
ll_sw/ull_filter.c
)
endif()
zephyr_library_sources_ifdef(
CONFIG_BT_HCI_MESH_EXT
ll_sw/ll_mesh.c
Expand Down
18 changes: 17 additions & 1 deletion subsys/bluetooth/controller/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ config BT_CTLR_FAL_SIZE
range 1 8 if (SOC_COMPATIBLE_NRF || SOC_OPENISA_RV32M1_RISCV32)
range 1 16 if !(SOC_COMPATIBLE_NRF || SOC_OPENISA_RV32M1_RISCV32)
help
Set the size of the White List for LE Controller-based Privacy.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@carlescufi Do you want to send a separate PR for this being missed upstream?

Set the size of the Filter Accept List for LE Controller-based Privacy.
On nRF5x-based controllers, the hardware imposes a limit of 8 devices.
On OpenISA-based controllers, the hardware imposes a limit of 8 devices.

Expand Down Expand Up @@ -497,6 +497,22 @@ config BT_CTLR_SYNC_PERIODIC
config BT_CTLR_SYNC_PERIODIC
bool "LE Periodic Advertising in Synchronization State [EXPERIMENTAL]" if BT_LL_SW_SPLIT

config BT_CTLR_SYNC_PERIODIC_ADV_LIST
Copy link
Contributor

@saleh-unikie saleh-unikie Sep 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to use this parameter option "BT_LE_PER_ADV_SYNC_OPT_USE_PER_ADV_LIST" (defined at bluetooth.h) automatically instead of defining a new kconfig? or at least generating a warning when this option is used but this config is not set.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, that is an API parameter, and this is a Controller feature.

bool "LE Periodic Advertiser List support"
depends on BT_CTLR_SYNC_PERIODIC
default y
help
Enable support for LE Periodic Advertiser List support.

config BT_CTLR_SYNC_PERIODIC_ADV_LIST_SIZE
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this config a redundant to the "CONFIG_BT_PER_ADV_SYNC_MAX"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, maximum supported simultaneous synchronizations can be lower than listed number of advertisers; only one advertiser is synchronized for every LE Periodic Advertising Create Sync Command, and Memory Capacity Exceeded error is used to convey insufficient resources to handle any more periodic advertising trains.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it! so setting the "CONFIG_BT_PER_ADV_SYNC_MAX" to a number greater than the "BT_CTLR_SYNC_PERIODIC_ADV_LIST_SIZE" is useless, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maximum simultaneous synchronizations CONFIG_BT_PER_ADV_SYNC_MAX can be greater than, says number of trusted peer device stored in a list CONFIG_BT_CTLR_SYNC_PERIODIC_ADV_LIST_SIZE. List is just a convenience, to be able to synchronize to any of the listed peers on a first-seen basis. Applications are permitted to use explicit peer device address to create additional synchronizations beyond the number of entries that be accommodated in the Periodic Advertiser List.

int "LE Periodic Advertiser List size"
depends on BT_CTLR_SYNC_PERIODIC_ADV_LIST
range 1 255
default 8
help
Set Periodic Advertiser List size, this will be return in the HCI LE
Read Periodic Advertiser List Command.

config BT_CTLR_ADV_ISO
bool "LE Broadcast Isochronous Channel advertising" if !BT_LL_SW_SPLIT
depends on BT_BROADCASTER && BT_CTLR_ADV_ISO_SUPPORT
Expand Down
88 changes: 83 additions & 5 deletions subsys/bluetooth/controller/hci/hci.c
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,14 @@ static void read_supported_commands(struct net_buf *buf, struct net_buf **evt)
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC)
/* LE PA Create Sync, LE PA Create Sync Cancel, LE PA Terminate Sync */
rp->commands[38] |= BIT(0) | BIT(1) | BIT(2);
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_ADV_LIST)
/* LE PA Add Device to Periodic Advertiser List,
* LE PA Remove Device from Periodic Advertiser List,
* LE Clear Periodic Advertiser List,
* LE Read Periodic Adveritiser List Size
*/
rp->commands[38] |= BIT(3) | BIT(4) | BIT(5) | BIT(6);
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_ADV_LIST */
/* LE Set PA Receive Enable */
rp->commands[40] |= BIT(5);
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */
Expand Down Expand Up @@ -806,11 +814,6 @@ static void read_supported_commands(struct net_buf *buf, struct net_buf **evt)
rp->commands[40] |= BIT(4);
#endif /* CONFIG_BT_CTLR_DF */

#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC)
/* LE Set Periodic Advertising Receive Enable */
rp->commands[40] |= BIT(5);
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */

#if defined(CONFIG_BT_HCI_RAW) && defined(CONFIG_BT_TINYCRYPT_ECC)
bt_hci_ecc_supported_commands(rp->commands);
#endif /* CONFIG_BT_HCI_RAW && CONFIG_BT_TINYCRYPT_ECC */
Expand Down Expand Up @@ -3341,6 +3344,63 @@ static void le_per_adv_recv_enable(struct net_buf *buf, struct net_buf **evt)
ccst = hci_cmd_complete(evt, sizeof(*ccst));
ccst->status = status;
}

#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_ADV_LIST)
static void le_add_dev_to_pal(struct net_buf *buf, struct net_buf **evt)
ppryga-nordic marked this conversation as resolved.
Show resolved Hide resolved
{
struct bt_hci_cp_le_add_dev_to_per_adv_list *cmd = (void *)buf->data;
uint8_t status;

if (adv_cmds_ext_check(evt)) {
return;
}

status = ll_pal_add(&cmd->addr, cmd->sid);

*evt = cmd_complete_status(status);
}

static void le_rem_dev_from_pal(struct net_buf *buf, struct net_buf **evt)
ppryga-nordic marked this conversation as resolved.
Show resolved Hide resolved
{
struct bt_hci_cp_le_rem_dev_from_per_adv_list *cmd = (void *)buf->data;
uint8_t status;

if (adv_cmds_ext_check(evt)) {
return;
}

status = ll_pal_remove(&cmd->addr, cmd->sid);

*evt = cmd_complete_status(status);
}

static void le_clear_pal(struct net_buf *buf, struct net_buf **evt)
ppryga-nordic marked this conversation as resolved.
Show resolved Hide resolved
{
uint8_t status;

if (adv_cmds_ext_check(evt)) {
return;
}

status = ll_pal_clear();

*evt = cmd_complete_status(status);
}

static void le_read_pal_size(struct net_buf *buf, struct net_buf **evt)
ppryga-nordic marked this conversation as resolved.
Show resolved Hide resolved
{
struct bt_hci_rp_le_read_per_adv_list_size *rp;

if (adv_cmds_ext_check(evt)) {
return;
}

rp = hci_cmd_complete(evt, sizeof(*rp));
rp->status = 0x00;

rp->list_size = ll_pal_size_get();
}
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_ADV_LIST */
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */
#endif /* CONFIG_BT_OBSERVER */

Expand Down Expand Up @@ -3870,6 +3930,24 @@ static int controller_cmd_handle(uint16_t ocf, struct net_buf *cmd,
case BT_OCF(BT_HCI_OP_LE_SET_PER_ADV_RECV_ENABLE):
le_per_adv_recv_enable(cmd, evt);
break;

#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_ADV_LIST)
case BT_OCF(BT_HCI_OP_LE_ADD_DEV_TO_PER_ADV_LIST):
le_add_dev_to_pal(cmd, evt);
break;

case BT_OCF(BT_HCI_OP_LE_REM_DEV_FROM_PER_ADV_LIST):
le_rem_dev_from_pal(cmd, evt);
break;

case BT_OCF(BT_HCI_OP_LE_CLEAR_PER_ADV_LIST):
le_clear_pal(cmd, evt);
break;

case BT_OCF(BT_HCI_OP_LE_READ_PER_ADV_LIST_SIZE):
le_read_pal_size(cmd, evt);
break;
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_ADV_LIST */
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */
#endif /* CONFIG_BT_OBSERVER */

Expand Down
5 changes: 5 additions & 0 deletions subsys/bluetooth/controller/include/ll.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,11 @@ uint8_t ll_fal_clear(void);
uint8_t ll_fal_add(bt_addr_le_t *addr);
uint8_t ll_fal_remove(bt_addr_le_t *addr);

uint8_t ll_pal_size_get(void);
uint8_t ll_pal_clear(void);
uint8_t ll_pal_add(const bt_addr_le_t *const addr, const uint8_t sid);
uint8_t ll_pal_remove(const bt_addr_le_t *const addr, const uint8_t sid);

void ll_rl_id_addr_get(uint8_t rl_idx, uint8_t *id_addr_type, uint8_t *id_addr);
uint8_t ll_rl_size_get(void);
uint8_t ll_rl_clear(void);
Expand Down
48 changes: 33 additions & 15 deletions subsys/bluetooth/controller/ll_sw/lll_filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#define FAL_SIZE 8
#endif /* CONFIG_BT_CTLR_FAL_SIZE */

#define IRK_SIZE 16
#define FILTER_IDX_NONE 0xFF
#define LLL_FILTER_BITMASK_ALL (BIT(FAL_SIZE) - 1)

Expand All @@ -28,42 +29,59 @@ struct lll_filter {

/* Filter Accept List peer list */
struct lll_fal {
uint8_t taken:1;
uint8_t id_addr_type:1;
uint8_t rl_idx;
uint8_t taken:1;
uint8_t id_addr_type:1;
uint8_t rl_idx;
bt_addr_t id_addr;
};

struct lll_resolvelist {
uint8_t taken:1;
uint8_t rpas_ready:1;
uint8_t pirk:1;
uint8_t lirk:1;
uint8_t dev:1;
uint8_t fal:1;
/* Periodic Advertising List */
struct lll_pal {
ppryga-nordic marked this conversation as resolved.
Show resolved Hide resolved
bt_addr_t id_addr;
uint8_t taken:1;
uint8_t id_addr_type:1;
uint8_t sid;

#if defined(CONFIG_BT_CTLR_PRIVACY)
uint8_t rl_idx;
#endif /* CONFIG_BT_CTLR_PRIVACY */
};

uint8_t id_addr_type:1;
/* Resolve list */
struct lll_resolve_list {
uint8_t taken:1;
uint8_t rpas_ready:1;
uint8_t pirk:1;
uint8_t lirk:1;
uint8_t dev:1;
uint8_t fal:1;

uint8_t id_addr_type:1;
bt_addr_t id_addr;

uint8_t local_irk[16];
uint8_t pirk_idx;
uint8_t local_irk[IRK_SIZE];
uint8_t pirk_idx;
bt_addr_t curr_rpa;
bt_addr_t peer_rpa;
bt_addr_t *local_rpa;
#if defined(CONFIG_BT_CTLR_SW_DEFERRED_PRIVACY)
bt_addr_t target_rpa;
#endif

#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_ADV_LIST)
uint16_t pal:9; /* 0 - not present, 1 to 256 - lll_pal entry index */
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_ADV_LIST */
};

bool ull_filter_lll_lrpa_used(uint8_t rl_idx);
extern bool ull_filter_lll_lrpa_used(uint8_t rl_idx);
extern bt_addr_t *ull_filter_lll_lrpa_get(uint8_t rl_idx);
extern uint8_t *ull_filter_lll_irks_get(uint8_t *count);
extern uint8_t ull_filter_lll_rl_idx(bool fal, uint8_t devmatch_id);
extern uint8_t ull_filter_lll_rl_irk_idx(uint8_t irkmatch_id);
extern bool ull_filter_lll_irk_in_fal(uint8_t rl_idx);
extern struct lll_filter *ull_filter_lll_get(bool fal);
extern struct lll_fal *ull_filter_lll_fal_get(void);
extern struct lll_resolvelist *ull_filter_lll_resolvelist_get(void);
extern struct lll_resolve_list *ull_filter_lll_resolve_list_get(void);
extern bool ull_filter_lll_rl_idx_allowed(uint8_t irkmatch_ok, uint8_t rl_idx);
extern bool ull_filter_lll_rl_addr_allowed(uint8_t id_addr_type, uint8_t *id_addr,
uint8_t *rl_idx);
Expand Down
1 change: 0 additions & 1 deletion subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv.c
Original file line number Diff line number Diff line change
Expand Up @@ -910,7 +910,6 @@ static int prepare_cb(struct lll_prepare_param *p)
/* Setup Radio Filter */
struct lll_filter *fal = ull_filter_lll_get(true);


radio_filter_configure(fal->enable_bitmask,
fal->addr_type_bitmask,
(uint8_t *)fal->bdaddr);
Expand Down
1 change: 0 additions & 1 deletion subsys/bluetooth/controller/ll_sw/openisa/lll/lll_adv.c
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,6 @@ static int prepare_cb(struct lll_prepare_param *prepare_param)
/* Setup Radio Filter */
struct lll_filter *fal = ull_filter_lll_get(true);


radio_filter_configure(fal->enable_bitmask,
fal->addr_type_bitmask,
(uint8_t *)fal->bdaddr);
Expand Down
1 change: 0 additions & 1 deletion subsys/bluetooth/controller/ll_sw/openisa/lll/lll_scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,6 @@ static int prepare_cb(struct lll_prepare_param *prepare_param)

if (IS_ENABLED(CONFIG_BT_CTLR_FILTER_ACCEPT_LIST) && lll->filter_policy) {
/* Setup Radio Filter */

struct lll_filter *fal = ull_filter_lll_get(true);

radio_filter_configure(fal->enable_bitmask,
Expand Down
4 changes: 2 additions & 2 deletions subsys/bluetooth/controller/ll_sw/ull_adv.c
Original file line number Diff line number Diff line change
Expand Up @@ -2697,7 +2697,7 @@ static inline uint8_t *adv_pdu_adva_get(struct pdu_adv *pdu)
static const uint8_t *adva_update(struct ll_adv_set *adv, struct pdu_adv *pdu)
{
#if defined(CONFIG_BT_CTLR_PRIVACY)
const uint8_t *rpa = ull_filter_adva_get(adv);
const uint8_t *rpa = ull_filter_adva_get(adv->lll.rl_idx);
#else
const uint8_t *rpa = NULL;
#endif
Expand Down Expand Up @@ -2739,7 +2739,7 @@ static void tgta_update(struct ll_adv_set *adv, struct pdu_adv *pdu)
const uint8_t *rx_addr = NULL;
uint8_t *tgt_addr;

rx_addr = ull_filter_tgta_get(adv);
rx_addr = ull_filter_tgta_get(adv->lll.rl_idx);
if (rx_addr) {
pdu->rx_addr = 1;

Expand Down
Loading