Skip to content

Commit d9eb21a

Browse files
ppryga-nordiccfriedt
authored andcommitted
Bluetooth: controller: Add per sync filt by CTE type for SOC w/o DFE
First implementation of periodic advertising sync filtering requires existence of Direction Finding Extension in Radio peripheral. To add the filtering support for other Nodric SOCs software based PDU traversing for CTEInfo should be implemented. In case there is no DFE in Radio peripheral, actual filtering is done in ULL. The commit provides necessary changes to previous solution. Signed-off-by: Piotr Pryga <[email protected]>
1 parent 2b8079a commit d9eb21a

File tree

10 files changed

+153
-80
lines changed

10 files changed

+153
-80
lines changed

subsys/bluetooth/controller/Kconfig.df

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ config BT_CTLR_DF_ANT_SWITCH_2US_SUPPORT
2626
config BT_CTLR_DF_ANT_SWITCH_1US_SUPPORT
2727
bool
2828

29+
config BT_CTLR_CTEINLINE_SUPPORT
30+
bool
31+
2932
menuconfig BT_CTLR_DF
3033
bool "LE Direction Finding [Experimental]"
3134
depends on BT_CTLR_DF_SUPPORT

subsys/bluetooth/controller/Kconfig.ll_sw_split

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ config BT_LLL_VENDOR_NORDIC
3535
select BT_CTLR_ADV_ISO_SUPPORT
3636
select BT_CTLR_SYNC_ISO_SUPPORT
3737
select BT_CTLR_DF_SUPPORT if $(DT_NORDIC_RADIO_DFE_SUPPORTED)
38+
select BT_CTLR_CTEINLINE_SUPPORT if $(DT_NORDIC_RADIO_DFE_SUPPORTED)
3839
select BT_CTLR_CHAN_SEL_2_SUPPORT
3940
select BT_CTLR_MIN_USED_CHAN_SUPPORT
4041
select BT_CTLR_DTM_HCI_SUPPORT

subsys/bluetooth/controller/ll_sw/lll.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -404,12 +404,12 @@ struct event_done_extra {
404404
struct {
405405
uint16_t trx_cnt;
406406
uint8_t crc_valid:1;
407-
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC)
407+
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC) && defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT)
408408
/* Used to inform ULL that periodic advertising sync scan should be
409409
* terminated.
410410
*/
411411
uint8_t sync_term:1;
412-
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */
412+
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC && CONFIG_BT_CTLR_CTEINLINE_SUPPORT */
413413
#if defined(CONFIG_BT_CTLR_LE_ENC)
414414
uint8_t mic_state;
415415
#endif /* CONFIG_BT_CTLR_LE_ENC */

subsys/bluetooth/controller/ll_sw/lll_sync.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66

77
/* Periodic advertisements synchronization status. */
88
enum sync_status {
9-
SYNC_STAT_FOUND,
10-
SYNC_STAT_READY,
9+
SYNC_STAT_ALLOWED,
10+
SYNC_STAT_READY_OR_CONT_SCAN,
1111
SYNC_STAT_TERM
1212
};
1313

@@ -58,5 +58,6 @@ int lll_sync_init(void);
5858
int lll_sync_reset(void);
5959
void lll_sync_create_prepare(void *param);
6060
void lll_sync_prepare(void *param);
61-
61+
enum sync_status lll_sync_cte_is_allowed(uint8_t cte_type_mask, uint8_t filter_policy,
62+
uint8_t rx_cte_time, uint8_t rx_cte_type);
6263
extern uint16_t ull_sync_lll_handle_get(struct lll_sync *lll);

subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
#include "ll_sw/pdu.h"
2323

2424
#include "radio_internal.h"
25-
#include "radio_df.h"
2625

2726
#if defined(CONFIG_BT_CTLR_GPIO_PA_PIN)
2827
#if ((CONFIG_BT_CTLR_GPIO_PA_PIN) > 31)
@@ -1518,7 +1517,7 @@ void radio_ar_resolve(uint8_t *addr)
15181517
*/
15191518
void radio_df_cte_inline_set_enabled(bool cte_info_in_s1)
15201519
{
1521-
#if defined(HAS_CTEINLINE_SUPPORT)
1520+
#if defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT)
15221521
const nrf_radio_cteinline_conf_t inline_conf = {
15231522
.enable = true,
15241523
/* Indicates whether CTEInfo is in S1 byte or not. */
@@ -1542,5 +1541,5 @@ void radio_df_cte_inline_set_enabled(bool cte_info_in_s1)
15421541
};
15431542

15441543
nrf_radio_cteinline_configure(NRF_RADIO, &inline_conf);
1545-
#endif /* HAS_CTEINLINE_SUPPORT */
1544+
#endif /* CONFIG_BT_CTLR_CTEINLINE_SUPPORT */
15461545
}

subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_df.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
#include "radio_df.h"
1919
#include "radio_internal.h"
2020

21+
/* Devicetree node identifier for the radio node. */
22+
#define RADIO_NODE DT_NODELABEL(radio)
23+
2124
/* Value to set for unconnected antenna GPIO pins. */
2225
#define DFE_PSEL_NOT_SET 0xFF
2326
/* Number of PSEL_DFEGPIO[n] registers in the radio peripheral. */

subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_df.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,6 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7-
/* Devicetree node identifier for the radio node. */
8-
#define RADIO_NODE DT_NODELABEL(radio)
9-
/* Check if radio has hardware support to parse PDU for CTE info */
10-
#if IS_ENABLED(DT_PROP_OR(RADIO_NODE, dfe_supported, 0))
11-
#define HAS_CTEINLINE_SUPPORT
12-
#endif
13-
147
/* Function configures Radio with information about GPIO pins that may be
158
* used to drive antenna switching during CTE Tx/RX.
169
*/

subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync.c

Lines changed: 73 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,6 @@
4242
#include <soc.h>
4343
#include "hal/debug.h"
4444

45-
/* Periodic advertisements filtering results. */
46-
enum sync_filtering_result {
47-
SYNC_ALLOWED,
48-
SYNC_SCAN_CONTINUE,
49-
SYNC_SCAN_TERM
50-
};
51-
5245
static int init_reset(void);
5346
static void prepare(void *param);
5447
static int create_prepare_cb(struct lll_prepare_param *p);
@@ -67,8 +60,7 @@ static int create_iq_report(struct lll_sync *lll, uint8_t rssi_ready,
6760
uint8_t packet_status);
6861
#endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX */
6962
static uint8_t data_channel_calc(struct lll_sync *lll);
70-
static enum sync_filtering_result sync_filtrate_by_cte_type(uint8_t cte_type_mask,
71-
uint8_t filter_policy);
63+
static enum sync_status sync_filtrate_by_cte_type(uint8_t cte_type_mask, uint8_t filter_policy);
7264

7365
static uint8_t trx_cnt;
7466

@@ -194,6 +186,57 @@ void lll_sync_aux_prepare_cb(struct lll_sync *lll,
194186
}
195187
}
196188

189+
enum sync_status lll_sync_cte_is_allowed(uint8_t cte_type_mask, uint8_t filter_policy,
190+
uint8_t rx_cte_time, uint8_t rx_cte_type)
191+
{
192+
bool cte_ok;
193+
194+
if (cte_type_mask == BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_FILTERING) {
195+
return SYNC_STAT_ALLOWED;
196+
}
197+
198+
if (rx_cte_time > 0) {
199+
if ((cte_type_mask & BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_CTE) != 0) {
200+
cte_ok = false;
201+
} else {
202+
switch (rx_cte_type) {
203+
case BT_HCI_LE_AOA_CTE:
204+
cte_ok = !(cte_type_mask &
205+
BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_AOA);
206+
break;
207+
case BT_HCI_LE_AOD_CTE_1US:
208+
cte_ok = !(cte_type_mask &
209+
BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_AOD_1US);
210+
break;
211+
case BT_HCI_LE_AOD_CTE_2US:
212+
cte_ok = !(cte_type_mask &
213+
BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_AOD_2US);
214+
break;
215+
default:
216+
/* Unknown or forbidden CTE type */
217+
cte_ok = false;
218+
}
219+
}
220+
} else {
221+
/* If there is no CTEInfo in advertising PDU, Radio will not parse the S0 byte and
222+
* CTESTATUS register will hold zeros only.
223+
* Zero value in CTETime field of CTESTATUS may be used to distinguish between PDU
224+
* that includes CTEInfo or not. Allowed range for CTETime is 2-20.
225+
*/
226+
if ((cte_type_mask & BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_ONLY_CTE) != 0) {
227+
cte_ok = false;
228+
} else {
229+
cte_ok = true;
230+
}
231+
}
232+
233+
if (!cte_ok) {
234+
return filter_policy ? SYNC_STAT_READY_OR_CONT_SCAN : SYNC_STAT_TERM;
235+
}
236+
237+
return SYNC_STAT_ALLOWED;
238+
}
239+
197240
static int init_reset(void)
198241
{
199242
return 0;
@@ -630,7 +673,7 @@ static int isr_rx(struct lll_sync *lll, uint8_t node_type, uint8_t crc_ok, uint8
630673

631674
static void isr_rx_adv_sync_estab(void *param)
632675
{
633-
enum sync_filtering_result sync_ok;
676+
enum sync_status sync_ok;
634677
struct lll_sync *lll;
635678
uint8_t rssi_ready;
636679
uint8_t trx_done;
@@ -651,7 +694,7 @@ static void isr_rx_adv_sync_estab(void *param)
651694
/* Initiated as allowed, crc_ok takes precended during handling of PDU
652695
* reception in the situation.
653696
*/
654-
sync_ok = SYNC_ALLOWED;
697+
sync_ok = SYNC_STAT_ALLOWED;
655698
}
656699

657700
/* Clear radio rx status and events */
@@ -671,12 +714,12 @@ static void isr_rx_adv_sync_estab(void *param)
671714
radio_tmr_ready_save(radio_tmr_ready_get());
672715

673716
/* Handle regular PDU reception if CTE type is acceptable */
674-
if (sync_ok == SYNC_ALLOWED) {
675-
err = isr_rx(lll, NODE_RX_TYPE_SYNC, crc_ok, rssi_ready, SYNC_STAT_FOUND);
717+
if (sync_ok == SYNC_STAT_ALLOWED) {
718+
err = isr_rx(lll, NODE_RX_TYPE_SYNC, crc_ok, rssi_ready, SYNC_STAT_ALLOWED);
676719
if (err == -EBUSY) {
677720
return;
678721
}
679-
} else if (sync_ok == SYNC_SCAN_TERM) {
722+
} else if (sync_ok == SYNC_STAT_TERM) {
680723
struct node_rx_pdu *node_rx;
681724

682725
/* Verify if there are free RX buffers for:
@@ -702,7 +745,11 @@ static void isr_rx_adv_sync_estab(void *param)
702745
}
703746

704747
isr_rx_done:
705-
isr_rx_done_cleanup(lll, crc_ok, sync_ok == SYNC_SCAN_TERM);
748+
#if defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT)
749+
isr_rx_done_cleanup(lll, crc_ok, sync_ok == SYNC_STAT_TERM);
750+
#else
751+
isr_rx_done_cleanup(lll, crc_ok, false);
752+
#endif /* CONFIG_BT_CTLR_CTEINLINE_SUPPORT */
706753
}
707754

708755
static void isr_rx_adv_sync(void *param)
@@ -745,7 +792,8 @@ static void isr_rx_adv_sync(void *param)
745792
* affect sychronization even when new CTE type is not allowed by sync parameters.
746793
* Hence the SYNC_STAT_READY is set.
747794
*/
748-
err = isr_rx(lll, NODE_RX_TYPE_SYNC_REPORT, crc_ok, rssi_ready, SYNC_STAT_READY);
795+
err = isr_rx(lll, NODE_RX_TYPE_SYNC_REPORT, crc_ok, rssi_ready,
796+
SYNC_STAT_READY_OR_CONT_SCAN);
749797
if (err == -EBUSY) {
750798
return;
751799
}
@@ -798,7 +846,8 @@ static void isr_rx_aux_chain(void *param)
798846
* affect sychronization even when new CTE type is not allowed by sync parameters.
799847
* Hence the SYNC_STAT_READY is set.
800848
*/
801-
err = isr_rx(lll, NODE_RX_TYPE_EXT_AUX_REPORT, crc_ok, rssi_ready, SYNC_STAT_READY);
849+
err = isr_rx(lll, NODE_RX_TYPE_EXT_AUX_REPORT, crc_ok, rssi_ready,
850+
SYNC_STAT_READY_OR_CONT_SCAN);
802851

803852
if (err == -EBUSY) {
804853
return;
@@ -840,8 +889,9 @@ static void isr_rx_done_cleanup(struct lll_sync *lll, uint8_t crc_ok, bool sync_
840889
e->type = EVENT_DONE_EXTRA_TYPE_SYNC;
841890
e->trx_cnt = trx_cnt;
842891
e->crc_valid = crc_ok;
892+
#if defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT)
843893
e->sync_term = sync_term;
844-
894+
#endif /* CONFIG_BT_CTLR_CTEINLINE_SUPPORT */
845895
if (trx_cnt) {
846896
e->drift.preamble_to_addr_us = addr_us_get(lll->phy);
847897
e->drift.start_to_address_actual_us =
@@ -935,57 +985,17 @@ static uint8_t data_channel_calc(struct lll_sync *lll)
935985
data_chan_map, data_chan_count);
936986
}
937987

938-
static enum sync_filtering_result sync_filtrate_by_cte_type(uint8_t cte_type_mask,
939-
uint8_t filter_policy)
988+
static enum sync_status sync_filtrate_by_cte_type(uint8_t cte_type_mask, uint8_t filter_policy)
940989
{
941-
if (cte_type_mask & BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_FILTERING) {
942-
return SYNC_ALLOWED;
943-
}
944-
945-
#if defined(HAS_CTEINLINE_SUPPORT)
990+
#if defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT)
946991
uint8_t rx_cte_time;
947992
uint8_t rx_cte_type;
948-
bool cte_ok;
949993

950994
rx_cte_time = nrf_radio_cte_time_get(NRF_RADIO);
951995
rx_cte_type = nrf_radio_cte_type_get(NRF_RADIO);
952996

953-
/* If there is no CTEInfo in advertising PDU, Radio will not parse the S0 byte and
954-
* CTESTATUS register will hold zeros only.
955-
* Zero value in CTETime field of CTESTATUS may be used to distinguish between PDU that
956-
* includes CTEInfo or not. Allowed range for CTETime is 2-20.
957-
*/
958-
if (rx_cte_time == 0 && cte_type_mask & BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_ONLY_CTE) {
959-
cte_ok = false;
960-
}
961-
962-
if (rx_cte_time > 0) {
963-
if (cte_type_mask & BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_CTE) {
964-
cte_ok = false;
965-
} else {
966-
switch (rx_cte_type) {
967-
case BT_HCI_LE_AOA_CTE:
968-
cte_ok = !(cte_type_mask &
969-
BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_AOA);
970-
break;
971-
case BT_HCI_LE_AOD_CTE_1US:
972-
cte_ok = !(cte_type_mask &
973-
BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_AOD_1US);
974-
break;
975-
case BT_HCI_LE_AOD_CTE_2US:
976-
cte_ok = !(cte_type_mask &
977-
BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_AOD_2US);
978-
break;
979-
default:
980-
/* Unknown or forbidden CTE type */
981-
cte_ok = false;
982-
}
983-
}
984-
}
997+
return lll_sync_cte_is_allowed(cte_type_mask, filter_policy, rx_cte_time, rx_cte_type);
985998

986-
if (!cte_ok) {
987-
return filter_policy ? SYNC_SCAN_CONTINUE : SYNC_SCAN_TERM;
988-
}
989-
#endif /* HAS_CTEINLINE_SUPPORT */
990-
return SYNC_ALLOWED;
999+
#endif /* CONFIG_BT_CTLR_CTEINLINE_SUPPORT */
1000+
return SYNC_STAT_ALLOWED;
9911001
}

0 commit comments

Comments
 (0)