diff --git a/include/bluetooth/hci.h b/include/bluetooth/hci.h index ceed69e92b1..58dca42c7e2 100644 --- a/include/bluetooth/hci.h +++ b/include/bluetooth/hci.h @@ -1445,7 +1445,7 @@ struct bt_hci_cp_le_ext_create_conn { #define BT_HCI_OP_LE_PER_ADV_CREATE_SYNC BT_OP(BT_OGF_LE, 0x0044) struct bt_hci_cp_le_per_adv_create_sync { - uint8_t options; + uint8_t options; uint8_t sid; bt_addr_le_t addr; uint16_t skip; diff --git a/subsys/bluetooth/controller/Kconfig b/subsys/bluetooth/controller/Kconfig index 68348f33ad4..46f8fcdf5da 100644 --- a/subsys/bluetooth/controller/Kconfig +++ b/subsys/bluetooth/controller/Kconfig @@ -519,6 +519,14 @@ config BT_CTLR_SYNC_PERIODIC_ADV_LIST_SIZE Set Periodic Advertiser List size, this will be return in the HCI LE Read Periodic Advertiser List Command. +config BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING + bool "LE Periodic Advertiser filtering by CTE type" + depends on BT_CTLR_SYNC_PERIODIC + default y + help + Enable filtering of periodic advertisements depending on type of + Constant Tone Extension. + 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 diff --git a/subsys/bluetooth/controller/hci/hci.c b/subsys/bluetooth/controller/hci/hci.c index c1ee0f8e81b..413c4ef79db 100644 --- a/subsys/bluetooth/controller/hci/hci.c +++ b/subsys/bluetooth/controller/hci/hci.c @@ -3331,8 +3331,13 @@ static void le_per_adv_create_sync(struct net_buf *buf, struct net_buf **evt) skip = sys_le16_to_cpu(cmd->skip); sync_timeout = sys_le16_to_cpu(cmd->sync_timeout); +#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING) if ((cmd->cte_type & BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_INVALID_VALUE) != 0) { status = BT_HCI_ERR_CMD_DISALLOWED; +#else + if (cmd->cte_type != BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_FILTERING) { + status = BT_HCI_ERR_INVALID_PARAM; +#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING */ } else { status = ll_sync_create(cmd->options, cmd->sid, cmd->addr.type, cmd->addr.a.val, skip, sync_timeout, cmd->cte_type); diff --git a/subsys/bluetooth/controller/ll_sw/lll.h b/subsys/bluetooth/controller/ll_sw/lll.h index 9fbf80e46a0..414fb833a75 100644 --- a/subsys/bluetooth/controller/ll_sw/lll.h +++ b/subsys/bluetooth/controller/ll_sw/lll.h @@ -404,12 +404,13 @@ struct event_done_extra { struct { uint16_t trx_cnt; uint8_t crc_valid:1; -#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC) && defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT) +#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING) && \ + defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT) /* Used to inform ULL that periodic advertising sync scan should be * terminated. */ uint8_t sync_term:1; -#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC && CONFIG_BT_CTLR_CTEINLINE_SUPPORT */ +#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING && CONFIG_BT_CTLR_CTEINLINE_SUPPORT */ #if defined(CONFIG_BT_CTLR_LE_ENC) uint8_t mic_state; #endif /* CONFIG_BT_CTLR_LE_ENC */ diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync.c index fc853194587..8a39c97fca1 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync.c @@ -186,6 +186,7 @@ void lll_sync_aux_prepare_cb(struct lll_sync *lll, } } +#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING) enum sync_status lll_sync_cte_is_allowed(uint8_t cte_type_mask, uint8_t filter_policy, uint8_t rx_cte_time, uint8_t rx_cte_type) { @@ -236,6 +237,7 @@ enum sync_status lll_sync_cte_is_allowed(uint8_t cte_type_mask, uint8_t filter_p return SYNC_STAT_ALLOWED; } +#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING */ static int init_reset(void) { @@ -745,11 +747,12 @@ static void isr_rx_adv_sync_estab(void *param) } isr_rx_done: -#if defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT) +#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING) && \ + defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT) isr_rx_done_cleanup(lll, crc_ok, sync_ok == SYNC_STAT_TERM); #else isr_rx_done_cleanup(lll, crc_ok, false); -#endif /* CONFIG_BT_CTLR_CTEINLINE_SUPPORT */ +#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING && CONFIG_BT_CTLR_CTEINLINE_SUPPORT */ } static void isr_rx_adv_sync(void *param) @@ -889,9 +892,10 @@ static void isr_rx_done_cleanup(struct lll_sync *lll, uint8_t crc_ok, bool sync_ e->type = EVENT_DONE_EXTRA_TYPE_SYNC; e->trx_cnt = trx_cnt; e->crc_valid = crc_ok; -#if defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT) +#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING) && \ + defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT) e->sync_term = sync_term; -#endif /* CONFIG_BT_CTLR_CTEINLINE_SUPPORT */ +#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING && CONFIG_BT_CTLR_CTEINLINE_SUPPORT */ if (trx_cnt) { e->drift.preamble_to_addr_us = addr_us_get(lll->phy); e->drift.start_to_address_actual_us = @@ -987,7 +991,8 @@ static uint8_t data_channel_calc(struct lll_sync *lll) static enum sync_status sync_filtrate_by_cte_type(uint8_t cte_type_mask, uint8_t filter_policy) { -#if defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT) +#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING) && \ + defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT) uint8_t rx_cte_time; uint8_t rx_cte_type; @@ -996,6 +1001,6 @@ static enum sync_status sync_filtrate_by_cte_type(uint8_t cte_type_mask, uint8_t return lll_sync_cte_is_allowed(cte_type_mask, filter_policy, rx_cte_time, rx_cte_type); -#endif /* CONFIG_BT_CTLR_CTEINLINE_SUPPORT */ +#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING && CONFIG_BT_CTLR_CTEINLINE_SUPPORT */ return SYNC_STAT_ALLOWED; } diff --git a/subsys/bluetooth/controller/ll_sw/ull_sync.c b/subsys/bluetooth/controller/ll_sw/ull_sync.c index 8d81a12906d..b9a275478f2 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_sync.c +++ b/subsys/bluetooth/controller/ll_sw/ull_sync.c @@ -60,9 +60,10 @@ static void ticker_op_cb(uint32_t status, void *param); static void ticker_update_sync_op_cb(uint32_t status, void *param); static void ticker_stop_op_cb(uint32_t status, void *param); static void sync_lost(void *param); -#if !defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT) +#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING) && \ + !defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT) static struct pdu_cte_info *pdu_cte_info_get(struct pdu_adv *pdu); -#endif /* CONFIG_BT_CTLR_CTEINLINE_SUPPORT */ +#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING && !CONFIG_BT_CTLR_CTEINLINE_SUPPORT */ #if defined(CONFIG_BT_CTLR_DF_SCAN_CTE_RX) static void ticker_update_op_status_give(uint32_t status, void *param); @@ -182,8 +183,10 @@ uint8_t ll_sync_create(uint8_t options, uint8_t sid, uint8_t adv_addr_type, lll_sync->skip_event = 0U; lll_sync->window_widening_prepare_us = 0U; lll_sync->window_widening_event_us = 0U; +#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING) lll_sync->cte_type = sync_cte_type; lll_sync->filter_policy = scan->per_scan.filter_policy; +#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING */ /* TODO: Add support for reporting initially enabled/disabled */ lll_sync->is_rx_enabled = @@ -594,7 +597,6 @@ void ull_sync_setup(struct ll_scan_set *scan, struct ll_scan_aux_set *aux, void ull_sync_established_report(memq_link_t *link, struct node_rx_hdr *rx) { - enum sync_status sync_status; struct node_rx_pdu *rx_establ; struct ll_sync_set *ull_sync; struct node_rx_ftr *ftr; @@ -603,6 +605,9 @@ void ull_sync_established_report(memq_link_t *link, struct node_rx_hdr *rx) ftr = &rx->rx_ftr; +#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING) + enum sync_status sync_status; + #if defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT) sync_status = ftr->sync_status; #else @@ -624,35 +629,46 @@ void ull_sync_established_report(memq_link_t *link, struct node_rx_hdr *rx) * or the CTE type is incorrect and filter policy doesn't allow to continue scanning. */ if (sync_status != SYNC_STAT_READY_OR_CONT_SCAN) { +#else + if (1) { +#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING */ + /* Set the sync handle corresponding to the LLL context passed in the node rx * footer field. */ -#if defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT) lll = ftr->param; -#endif /* CONFIG_BT_CTLR_CTEINLINE_SUPPORT */ ull_sync = HDR_LLL2ULL(lll); /* Prepare and dispatch sync notification */ rx_establ = (void *)ull_sync->node_rx_sync_estab; rx_establ->hdr.type = NODE_RX_TYPE_SYNC; se = (void *)rx_establ->pdu; + +#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING) se->status = (ftr->sync_status == SYNC_STAT_TERM) ? BT_HCI_ERR_UNSUPP_REMOTE_FEATURE : BT_HCI_ERR_SUCCESS; - /* Notify done event handler to terminate sync scan */ #if !defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT) + /* Notify done event handler to terminate sync scan if required. */ ull_sync->sync_term = sync_status == SYNC_STAT_TERM; -#endif /* CONFIG_BT_CTLR_CTEINLINE_SUPPORT */ +#endif /* !CONFIG_BT_CTLR_CTEINLINE_SUPPORT */ +#else + se->status = BT_HCI_ERR_SUCCESS; +#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING */ ll_rx_put(rx_establ->hdr.link, rx_establ); ll_rx_sched(); } +#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING) /* Handle periodic advertising PDU and send periodic advertising scan report when * the sync was found or was established in the past. The report is not send if * scanning is terminated due to wrong CTE type. */ if (sync_status != SYNC_STAT_TERM) { +#else + if (1) { +#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING */ /* Switch sync event prepare function to one reposnsible for regular PDUs receive */ mfy_lll_prepare.fp = lll_sync_prepare; @@ -677,6 +693,7 @@ void ull_sync_done(struct node_rx_event_done *done) sync = CONTAINER_OF(done->param, struct ll_sync_set, ull); lll = &sync->lll; +#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING) #if defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT) if (done->extra.sync_term) { #else @@ -684,7 +701,9 @@ void ull_sync_done(struct node_rx_event_done *done) #endif /* CONFIG_BT_CTLR_CTEINLINE_SUPPORT */ /* Stop periodic advertising scan ticker */ sync_ticker_cleanup(sync, NULL); - } else { + } else +#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING */ + { /* Events elapsed used in timeout checks below */ skip_event = lll->skip_event; elapsed_event = skip_event + 1; @@ -992,7 +1011,8 @@ static void ticker_update_op_status_give(uint32_t status, void *param) } #endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX */ -#if !defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT) +#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING) && \ + !defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT) static struct pdu_cte_info *pdu_cte_info_get(struct pdu_adv *pdu) { struct pdu_adv_com_ext_adv *com_hdr; @@ -1015,4 +1035,4 @@ static struct pdu_cte_info *pdu_cte_info_get(struct pdu_adv *pdu) return (struct pdu_cte_info *)hdr->data; } -#endif /* CONFIG_BT_CTLR_CTEINLINE_SUPPORT */ +#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING && !CONFIG_BT_CTLR_CTEINLINE_SUPPORT */ diff --git a/subsys/bluetooth/controller/ll_sw/ull_sync_types.h b/subsys/bluetooth/controller/ll_sw/ull_sync_types.h index 39326a12bd5..0ca51a32a68 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_sync_types.h +++ b/subsys/bluetooth/controller/ll_sw/ull_sync_types.h @@ -21,12 +21,13 @@ struct ll_sync_set { uint16_t volatile timeout_reload; /* Non-zero when sync established */ uint16_t timeout_expire; -#if !defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT) +#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING) && \ + !defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT) /* Member used to notify event done handler to terminate sync scanning. * Used only when no HW support for parsing PDU for CTEInfo. */ uint8_t sync_term:1; -#endif /* CONFIG_BT_CTLR_CTEINLINE_SUPPORT */ +#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING && !CONFIG_BT_CTLR_CTEINLINE_SUPPORT */ /* node rx type with memory aligned storage for sync lost reason. * HCI will reference the value using the pdu member of