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 <piotr.pryga@nordicsemi.no>
This commit is contained in:
parent
fba51111cf
commit
e03f9c3042
10 changed files with 153 additions and 80 deletions
|
@ -26,6 +26,9 @@ config BT_CTLR_DF_ANT_SWITCH_2US_SUPPORT
|
||||||
config BT_CTLR_DF_ANT_SWITCH_1US_SUPPORT
|
config BT_CTLR_DF_ANT_SWITCH_1US_SUPPORT
|
||||||
bool
|
bool
|
||||||
|
|
||||||
|
config BT_CTLR_CTEINLINE_SUPPORT
|
||||||
|
bool
|
||||||
|
|
||||||
menuconfig BT_CTLR_DF
|
menuconfig BT_CTLR_DF
|
||||||
bool "LE Direction Finding [Experimental]"
|
bool "LE Direction Finding [Experimental]"
|
||||||
depends on BT_CTLR_DF_SUPPORT
|
depends on BT_CTLR_DF_SUPPORT
|
||||||
|
|
|
@ -35,6 +35,7 @@ config BT_LLL_VENDOR_NORDIC
|
||||||
select BT_CTLR_ADV_ISO_SUPPORT
|
select BT_CTLR_ADV_ISO_SUPPORT
|
||||||
select BT_CTLR_SYNC_ISO_SUPPORT
|
select BT_CTLR_SYNC_ISO_SUPPORT
|
||||||
select BT_CTLR_DF_SUPPORT if $(DT_NORDIC_RADIO_DFE_SUPPORTED)
|
select BT_CTLR_DF_SUPPORT if $(DT_NORDIC_RADIO_DFE_SUPPORTED)
|
||||||
|
select BT_CTLR_CTEINLINE_SUPPORT if $(DT_NORDIC_RADIO_DFE_SUPPORTED)
|
||||||
select BT_CTLR_CHAN_SEL_2_SUPPORT
|
select BT_CTLR_CHAN_SEL_2_SUPPORT
|
||||||
select BT_CTLR_MIN_USED_CHAN_SUPPORT
|
select BT_CTLR_MIN_USED_CHAN_SUPPORT
|
||||||
select BT_CTLR_DTM_HCI_SUPPORT
|
select BT_CTLR_DTM_HCI_SUPPORT
|
||||||
|
|
|
@ -404,12 +404,12 @@ struct event_done_extra {
|
||||||
struct {
|
struct {
|
||||||
uint16_t trx_cnt;
|
uint16_t trx_cnt;
|
||||||
uint8_t crc_valid:1;
|
uint8_t crc_valid:1;
|
||||||
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC)
|
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC) && defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT)
|
||||||
/* Used to inform ULL that periodic advertising sync scan should be
|
/* Used to inform ULL that periodic advertising sync scan should be
|
||||||
* terminated.
|
* terminated.
|
||||||
*/
|
*/
|
||||||
uint8_t sync_term:1;
|
uint8_t sync_term:1;
|
||||||
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */
|
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC && CONFIG_BT_CTLR_CTEINLINE_SUPPORT */
|
||||||
#if defined(CONFIG_BT_CTLR_LE_ENC)
|
#if defined(CONFIG_BT_CTLR_LE_ENC)
|
||||||
uint8_t mic_state;
|
uint8_t mic_state;
|
||||||
#endif /* CONFIG_BT_CTLR_LE_ENC */
|
#endif /* CONFIG_BT_CTLR_LE_ENC */
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
|
|
||||||
/* Periodic advertisements synchronization status. */
|
/* Periodic advertisements synchronization status. */
|
||||||
enum sync_status {
|
enum sync_status {
|
||||||
SYNC_STAT_FOUND,
|
SYNC_STAT_ALLOWED,
|
||||||
SYNC_STAT_READY,
|
SYNC_STAT_READY_OR_CONT_SCAN,
|
||||||
SYNC_STAT_TERM
|
SYNC_STAT_TERM
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -58,5 +58,6 @@ int lll_sync_init(void);
|
||||||
int lll_sync_reset(void);
|
int lll_sync_reset(void);
|
||||||
void lll_sync_create_prepare(void *param);
|
void lll_sync_create_prepare(void *param);
|
||||||
void lll_sync_prepare(void *param);
|
void lll_sync_prepare(void *param);
|
||||||
|
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);
|
||||||
extern uint16_t ull_sync_lll_handle_get(struct lll_sync *lll);
|
extern uint16_t ull_sync_lll_handle_get(struct lll_sync *lll);
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
#include "ll_sw/pdu.h"
|
#include "ll_sw/pdu.h"
|
||||||
|
|
||||||
#include "radio_internal.h"
|
#include "radio_internal.h"
|
||||||
#include "radio_df.h"
|
|
||||||
|
|
||||||
#if defined(CONFIG_BT_CTLR_GPIO_PA_PIN)
|
#if defined(CONFIG_BT_CTLR_GPIO_PA_PIN)
|
||||||
#if ((CONFIG_BT_CTLR_GPIO_PA_PIN) > 31)
|
#if ((CONFIG_BT_CTLR_GPIO_PA_PIN) > 31)
|
||||||
|
@ -1518,7 +1517,7 @@ void radio_ar_resolve(uint8_t *addr)
|
||||||
*/
|
*/
|
||||||
void radio_df_cte_inline_set_enabled(bool cte_info_in_s1)
|
void radio_df_cte_inline_set_enabled(bool cte_info_in_s1)
|
||||||
{
|
{
|
||||||
#if defined(HAS_CTEINLINE_SUPPORT)
|
#if defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT)
|
||||||
const nrf_radio_cteinline_conf_t inline_conf = {
|
const nrf_radio_cteinline_conf_t inline_conf = {
|
||||||
.enable = true,
|
.enable = true,
|
||||||
/* Indicates whether CTEInfo is in S1 byte or not. */
|
/* 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)
|
||||||
};
|
};
|
||||||
|
|
||||||
nrf_radio_cteinline_configure(NRF_RADIO, &inline_conf);
|
nrf_radio_cteinline_configure(NRF_RADIO, &inline_conf);
|
||||||
#endif /* HAS_CTEINLINE_SUPPORT */
|
#endif /* CONFIG_BT_CTLR_CTEINLINE_SUPPORT */
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,9 @@
|
||||||
#include "radio_df.h"
|
#include "radio_df.h"
|
||||||
#include "radio_internal.h"
|
#include "radio_internal.h"
|
||||||
|
|
||||||
|
/* Devicetree node identifier for the radio node. */
|
||||||
|
#define RADIO_NODE DT_NODELABEL(radio)
|
||||||
|
|
||||||
/* Value to set for unconnected antenna GPIO pins. */
|
/* Value to set for unconnected antenna GPIO pins. */
|
||||||
#define DFE_PSEL_NOT_SET 0xFF
|
#define DFE_PSEL_NOT_SET 0xFF
|
||||||
/* Number of PSEL_DFEGPIO[n] registers in the radio peripheral. */
|
/* Number of PSEL_DFEGPIO[n] registers in the radio peripheral. */
|
||||||
|
|
|
@ -4,13 +4,6 @@
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Devicetree node identifier for the radio node. */
|
|
||||||
#define RADIO_NODE DT_NODELABEL(radio)
|
|
||||||
/* Check if radio has hardware support to parse PDU for CTE info */
|
|
||||||
#if IS_ENABLED(DT_PROP_OR(RADIO_NODE, dfe_supported, 0))
|
|
||||||
#define HAS_CTEINLINE_SUPPORT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Function configures Radio with information about GPIO pins that may be
|
/* Function configures Radio with information about GPIO pins that may be
|
||||||
* used to drive antenna switching during CTE Tx/RX.
|
* used to drive antenna switching during CTE Tx/RX.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -42,13 +42,6 @@
|
||||||
#include <soc.h>
|
#include <soc.h>
|
||||||
#include "hal/debug.h"
|
#include "hal/debug.h"
|
||||||
|
|
||||||
/* Periodic advertisements filtering results. */
|
|
||||||
enum sync_filtering_result {
|
|
||||||
SYNC_ALLOWED,
|
|
||||||
SYNC_SCAN_CONTINUE,
|
|
||||||
SYNC_SCAN_TERM
|
|
||||||
};
|
|
||||||
|
|
||||||
static int init_reset(void);
|
static int init_reset(void);
|
||||||
static void prepare(void *param);
|
static void prepare(void *param);
|
||||||
static int create_prepare_cb(struct lll_prepare_param *p);
|
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,
|
||||||
uint8_t packet_status);
|
uint8_t packet_status);
|
||||||
#endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX */
|
#endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX */
|
||||||
static uint8_t data_channel_calc(struct lll_sync *lll);
|
static uint8_t data_channel_calc(struct lll_sync *lll);
|
||||||
static enum sync_filtering_result sync_filtrate_by_cte_type(uint8_t cte_type_mask,
|
static enum sync_status sync_filtrate_by_cte_type(uint8_t cte_type_mask, uint8_t filter_policy);
|
||||||
uint8_t filter_policy);
|
|
||||||
|
|
||||||
static uint8_t trx_cnt;
|
static uint8_t trx_cnt;
|
||||||
|
|
||||||
|
@ -194,6 +186,57 @@ void lll_sync_aux_prepare_cb(struct lll_sync *lll,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
bool cte_ok;
|
||||||
|
|
||||||
|
if (cte_type_mask == BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_FILTERING) {
|
||||||
|
return SYNC_STAT_ALLOWED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rx_cte_time > 0) {
|
||||||
|
if ((cte_type_mask & BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_CTE) != 0) {
|
||||||
|
cte_ok = false;
|
||||||
|
} else {
|
||||||
|
switch (rx_cte_type) {
|
||||||
|
case BT_HCI_LE_AOA_CTE:
|
||||||
|
cte_ok = !(cte_type_mask &
|
||||||
|
BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_AOA);
|
||||||
|
break;
|
||||||
|
case BT_HCI_LE_AOD_CTE_1US:
|
||||||
|
cte_ok = !(cte_type_mask &
|
||||||
|
BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_AOD_1US);
|
||||||
|
break;
|
||||||
|
case BT_HCI_LE_AOD_CTE_2US:
|
||||||
|
cte_ok = !(cte_type_mask &
|
||||||
|
BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_AOD_2US);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Unknown or forbidden CTE type */
|
||||||
|
cte_ok = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* If there is no CTEInfo in advertising PDU, Radio will not parse the S0 byte and
|
||||||
|
* CTESTATUS register will hold zeros only.
|
||||||
|
* Zero value in CTETime field of CTESTATUS may be used to distinguish between PDU
|
||||||
|
* that includes CTEInfo or not. Allowed range for CTETime is 2-20.
|
||||||
|
*/
|
||||||
|
if ((cte_type_mask & BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_ONLY_CTE) != 0) {
|
||||||
|
cte_ok = false;
|
||||||
|
} else {
|
||||||
|
cte_ok = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cte_ok) {
|
||||||
|
return filter_policy ? SYNC_STAT_READY_OR_CONT_SCAN : SYNC_STAT_TERM;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SYNC_STAT_ALLOWED;
|
||||||
|
}
|
||||||
|
|
||||||
static int init_reset(void)
|
static int init_reset(void)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -630,7 +673,7 @@ static int isr_rx(struct lll_sync *lll, uint8_t node_type, uint8_t crc_ok, uint8
|
||||||
|
|
||||||
static void isr_rx_adv_sync_estab(void *param)
|
static void isr_rx_adv_sync_estab(void *param)
|
||||||
{
|
{
|
||||||
enum sync_filtering_result sync_ok;
|
enum sync_status sync_ok;
|
||||||
struct lll_sync *lll;
|
struct lll_sync *lll;
|
||||||
uint8_t rssi_ready;
|
uint8_t rssi_ready;
|
||||||
uint8_t trx_done;
|
uint8_t trx_done;
|
||||||
|
@ -651,7 +694,7 @@ static void isr_rx_adv_sync_estab(void *param)
|
||||||
/* Initiated as allowed, crc_ok takes precended during handling of PDU
|
/* Initiated as allowed, crc_ok takes precended during handling of PDU
|
||||||
* reception in the situation.
|
* reception in the situation.
|
||||||
*/
|
*/
|
||||||
sync_ok = SYNC_ALLOWED;
|
sync_ok = SYNC_STAT_ALLOWED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear radio rx status and events */
|
/* Clear radio rx status and events */
|
||||||
|
@ -671,12 +714,12 @@ static void isr_rx_adv_sync_estab(void *param)
|
||||||
radio_tmr_ready_save(radio_tmr_ready_get());
|
radio_tmr_ready_save(radio_tmr_ready_get());
|
||||||
|
|
||||||
/* Handle regular PDU reception if CTE type is acceptable */
|
/* Handle regular PDU reception if CTE type is acceptable */
|
||||||
if (sync_ok == SYNC_ALLOWED) {
|
if (sync_ok == SYNC_STAT_ALLOWED) {
|
||||||
err = isr_rx(lll, NODE_RX_TYPE_SYNC, crc_ok, rssi_ready, SYNC_STAT_FOUND);
|
err = isr_rx(lll, NODE_RX_TYPE_SYNC, crc_ok, rssi_ready, SYNC_STAT_ALLOWED);
|
||||||
if (err == -EBUSY) {
|
if (err == -EBUSY) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (sync_ok == SYNC_SCAN_TERM) {
|
} else if (sync_ok == SYNC_STAT_TERM) {
|
||||||
struct node_rx_pdu *node_rx;
|
struct node_rx_pdu *node_rx;
|
||||||
|
|
||||||
/* Verify if there are free RX buffers for:
|
/* Verify if there are free RX buffers for:
|
||||||
|
@ -702,7 +745,11 @@ static void isr_rx_adv_sync_estab(void *param)
|
||||||
}
|
}
|
||||||
|
|
||||||
isr_rx_done:
|
isr_rx_done:
|
||||||
isr_rx_done_cleanup(lll, crc_ok, sync_ok == SYNC_SCAN_TERM);
|
#if 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 */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void isr_rx_adv_sync(void *param)
|
static void isr_rx_adv_sync(void *param)
|
||||||
|
@ -745,7 +792,8 @@ static void isr_rx_adv_sync(void *param)
|
||||||
* affect sychronization even when new CTE type is not allowed by sync parameters.
|
* affect sychronization even when new CTE type is not allowed by sync parameters.
|
||||||
* Hence the SYNC_STAT_READY is set.
|
* Hence the SYNC_STAT_READY is set.
|
||||||
*/
|
*/
|
||||||
err = isr_rx(lll, NODE_RX_TYPE_SYNC_REPORT, crc_ok, rssi_ready, SYNC_STAT_READY);
|
err = isr_rx(lll, NODE_RX_TYPE_SYNC_REPORT, crc_ok, rssi_ready,
|
||||||
|
SYNC_STAT_READY_OR_CONT_SCAN);
|
||||||
if (err == -EBUSY) {
|
if (err == -EBUSY) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -798,7 +846,8 @@ static void isr_rx_aux_chain(void *param)
|
||||||
* affect sychronization even when new CTE type is not allowed by sync parameters.
|
* affect sychronization even when new CTE type is not allowed by sync parameters.
|
||||||
* Hence the SYNC_STAT_READY is set.
|
* Hence the SYNC_STAT_READY is set.
|
||||||
*/
|
*/
|
||||||
err = isr_rx(lll, NODE_RX_TYPE_EXT_AUX_REPORT, crc_ok, rssi_ready, SYNC_STAT_READY);
|
err = isr_rx(lll, NODE_RX_TYPE_EXT_AUX_REPORT, crc_ok, rssi_ready,
|
||||||
|
SYNC_STAT_READY_OR_CONT_SCAN);
|
||||||
|
|
||||||
if (err == -EBUSY) {
|
if (err == -EBUSY) {
|
||||||
return;
|
return;
|
||||||
|
@ -840,8 +889,9 @@ static void isr_rx_done_cleanup(struct lll_sync *lll, uint8_t crc_ok, bool sync_
|
||||||
e->type = EVENT_DONE_EXTRA_TYPE_SYNC;
|
e->type = EVENT_DONE_EXTRA_TYPE_SYNC;
|
||||||
e->trx_cnt = trx_cnt;
|
e->trx_cnt = trx_cnt;
|
||||||
e->crc_valid = crc_ok;
|
e->crc_valid = crc_ok;
|
||||||
|
#if defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT)
|
||||||
e->sync_term = sync_term;
|
e->sync_term = sync_term;
|
||||||
|
#endif /* CONFIG_BT_CTLR_CTEINLINE_SUPPORT */
|
||||||
if (trx_cnt) {
|
if (trx_cnt) {
|
||||||
e->drift.preamble_to_addr_us = addr_us_get(lll->phy);
|
e->drift.preamble_to_addr_us = addr_us_get(lll->phy);
|
||||||
e->drift.start_to_address_actual_us =
|
e->drift.start_to_address_actual_us =
|
||||||
|
@ -935,57 +985,17 @@ static uint8_t data_channel_calc(struct lll_sync *lll)
|
||||||
data_chan_map, data_chan_count);
|
data_chan_map, data_chan_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum sync_filtering_result sync_filtrate_by_cte_type(uint8_t cte_type_mask,
|
static enum sync_status sync_filtrate_by_cte_type(uint8_t cte_type_mask, uint8_t filter_policy)
|
||||||
uint8_t filter_policy)
|
|
||||||
{
|
{
|
||||||
if (cte_type_mask & BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_FILTERING) {
|
#if defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT)
|
||||||
return SYNC_ALLOWED;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(HAS_CTEINLINE_SUPPORT)
|
|
||||||
uint8_t rx_cte_time;
|
uint8_t rx_cte_time;
|
||||||
uint8_t rx_cte_type;
|
uint8_t rx_cte_type;
|
||||||
bool cte_ok;
|
|
||||||
|
|
||||||
rx_cte_time = nrf_radio_cte_time_get(NRF_RADIO);
|
rx_cte_time = nrf_radio_cte_time_get(NRF_RADIO);
|
||||||
rx_cte_type = nrf_radio_cte_type_get(NRF_RADIO);
|
rx_cte_type = nrf_radio_cte_type_get(NRF_RADIO);
|
||||||
|
|
||||||
/* If there is no CTEInfo in advertising PDU, Radio will not parse the S0 byte and
|
return lll_sync_cte_is_allowed(cte_type_mask, filter_policy, rx_cte_time, rx_cte_type);
|
||||||
* CTESTATUS register will hold zeros only.
|
|
||||||
* Zero value in CTETime field of CTESTATUS may be used to distinguish between PDU that
|
|
||||||
* includes CTEInfo or not. Allowed range for CTETime is 2-20.
|
|
||||||
*/
|
|
||||||
if (rx_cte_time == 0 && cte_type_mask & BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_ONLY_CTE) {
|
|
||||||
cte_ok = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rx_cte_time > 0) {
|
#endif /* CONFIG_BT_CTLR_CTEINLINE_SUPPORT */
|
||||||
if (cte_type_mask & BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_CTE) {
|
return SYNC_STAT_ALLOWED;
|
||||||
cte_ok = false;
|
|
||||||
} else {
|
|
||||||
switch (rx_cte_type) {
|
|
||||||
case BT_HCI_LE_AOA_CTE:
|
|
||||||
cte_ok = !(cte_type_mask &
|
|
||||||
BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_AOA);
|
|
||||||
break;
|
|
||||||
case BT_HCI_LE_AOD_CTE_1US:
|
|
||||||
cte_ok = !(cte_type_mask &
|
|
||||||
BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_AOD_1US);
|
|
||||||
break;
|
|
||||||
case BT_HCI_LE_AOD_CTE_2US:
|
|
||||||
cte_ok = !(cte_type_mask &
|
|
||||||
BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_AOD_2US);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* Unknown or forbidden CTE type */
|
|
||||||
cte_ok = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cte_ok) {
|
|
||||||
return filter_policy ? SYNC_SCAN_CONTINUE : SYNC_SCAN_TERM;
|
|
||||||
}
|
|
||||||
#endif /* HAS_CTEINLINE_SUPPORT */
|
|
||||||
return SYNC_ALLOWED;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,9 @@ 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_update_sync_op_cb(uint32_t status, void *param);
|
||||||
static void ticker_stop_op_cb(uint32_t status, void *param);
|
static void ticker_stop_op_cb(uint32_t status, void *param);
|
||||||
static void sync_lost(void *param);
|
static void sync_lost(void *param);
|
||||||
|
#if !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 */
|
||||||
|
|
||||||
#if defined(CONFIG_BT_CTLR_DF_SCAN_CTE_RX)
|
#if defined(CONFIG_BT_CTLR_DF_SCAN_CTE_RX)
|
||||||
static void ticker_update_op_status_give(uint32_t status, void *param);
|
static void ticker_update_op_status_give(uint32_t status, void *param);
|
||||||
|
@ -591,6 +594,7 @@ 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)
|
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 node_rx_pdu *rx_establ;
|
||||||
struct ll_sync_set *ull_sync;
|
struct ll_sync_set *ull_sync;
|
||||||
struct node_rx_ftr *ftr;
|
struct node_rx_ftr *ftr;
|
||||||
|
@ -599,14 +603,33 @@ void ull_sync_established_report(memq_link_t *link, struct node_rx_hdr *rx)
|
||||||
|
|
||||||
ftr = &rx->rx_ftr;
|
ftr = &rx->rx_ftr;
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT)
|
||||||
|
sync_status = ftr->sync_status;
|
||||||
|
#else
|
||||||
|
struct pdu_cte_info *rx_cte_info;
|
||||||
|
|
||||||
|
lll = ftr->param;
|
||||||
|
|
||||||
|
rx_cte_info = pdu_cte_info_get((struct pdu_adv *)((struct node_rx_pdu *)rx)->pdu);
|
||||||
|
if (rx_cte_info != NULL) {
|
||||||
|
sync_status = lll_sync_cte_is_allowed(lll->cte_type, lll->filter_policy,
|
||||||
|
rx_cte_info->time, rx_cte_info->type);
|
||||||
|
} else {
|
||||||
|
sync_status = lll_sync_cte_is_allowed(lll->cte_type, lll->filter_policy, 0,
|
||||||
|
BT_HCI_LE_NO_CTE);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BT_CTLR_CTEINLINE_SUPPORT */
|
||||||
|
|
||||||
/* Send periodic advertisement sync established report when sync has correct CTE type
|
/* Send periodic advertisement sync established report when sync has correct CTE type
|
||||||
* or the CTE type is incorrect and filter policy doesn't allow to continue scanning.
|
* or the CTE type is incorrect and filter policy doesn't allow to continue scanning.
|
||||||
*/
|
*/
|
||||||
if (ftr->sync_status != SYNC_STAT_READY) {
|
if (sync_status != SYNC_STAT_READY_OR_CONT_SCAN) {
|
||||||
/* Set the sync handle corresponding to the LLL context passed in the node rx
|
/* Set the sync handle corresponding to the LLL context passed in the node rx
|
||||||
* footer field.
|
* footer field.
|
||||||
*/
|
*/
|
||||||
|
#if defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT)
|
||||||
lll = ftr->param;
|
lll = ftr->param;
|
||||||
|
#endif /* CONFIG_BT_CTLR_CTEINLINE_SUPPORT */
|
||||||
ull_sync = HDR_LLL2ULL(lll);
|
ull_sync = HDR_LLL2ULL(lll);
|
||||||
|
|
||||||
/* Prepare and dispatch sync notification */
|
/* Prepare and dispatch sync notification */
|
||||||
|
@ -617,6 +640,10 @@ void ull_sync_established_report(memq_link_t *link, struct node_rx_hdr *rx)
|
||||||
BT_HCI_ERR_UNSUPP_REMOTE_FEATURE :
|
BT_HCI_ERR_UNSUPP_REMOTE_FEATURE :
|
||||||
BT_HCI_ERR_SUCCESS;
|
BT_HCI_ERR_SUCCESS;
|
||||||
|
|
||||||
|
/* Notify done event handler to terminate sync scan */
|
||||||
|
#if !defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT)
|
||||||
|
ull_sync->sync_term = sync_status == SYNC_STAT_TERM;
|
||||||
|
#endif /* CONFIG_BT_CTLR_CTEINLINE_SUPPORT */
|
||||||
ll_rx_put(rx_establ->hdr.link, rx_establ);
|
ll_rx_put(rx_establ->hdr.link, rx_establ);
|
||||||
ll_rx_sched();
|
ll_rx_sched();
|
||||||
}
|
}
|
||||||
|
@ -625,7 +652,7 @@ void ull_sync_established_report(memq_link_t *link, struct node_rx_hdr *rx)
|
||||||
* the sync was found or was established in the past. The report is not send if
|
* the sync was found or was established in the past. The report is not send if
|
||||||
* scanning is terminated due to wrong CTE type.
|
* scanning is terminated due to wrong CTE type.
|
||||||
*/
|
*/
|
||||||
if (ftr->sync_status != SYNC_STAT_TERM) {
|
if (sync_status != SYNC_STAT_TERM) {
|
||||||
/* Switch sync event prepare function to one reposnsible for regular PDUs receive */
|
/* Switch sync event prepare function to one reposnsible for regular PDUs receive */
|
||||||
mfy_lll_prepare.fp = lll_sync_prepare;
|
mfy_lll_prepare.fp = lll_sync_prepare;
|
||||||
|
|
||||||
|
@ -650,7 +677,11 @@ void ull_sync_done(struct node_rx_event_done *done)
|
||||||
sync = CONTAINER_OF(done->param, struct ll_sync_set, ull);
|
sync = CONTAINER_OF(done->param, struct ll_sync_set, ull);
|
||||||
lll = &sync->lll;
|
lll = &sync->lll;
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT)
|
||||||
if (done->extra.sync_term) {
|
if (done->extra.sync_term) {
|
||||||
|
#else
|
||||||
|
if (sync->sync_term) {
|
||||||
|
#endif /* CONFIG_BT_CTLR_CTEINLINE_SUPPORT */
|
||||||
/* Stop periodic advertising scan ticker */
|
/* Stop periodic advertising scan ticker */
|
||||||
sync_ticker_cleanup(sync, NULL);
|
sync_ticker_cleanup(sync, NULL);
|
||||||
} else {
|
} else {
|
||||||
|
@ -960,3 +991,28 @@ static void ticker_update_op_status_give(uint32_t status, void *param)
|
||||||
k_sem_give(&sem_ticker_cb);
|
k_sem_give(&sem_ticker_cb);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX */
|
#endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX */
|
||||||
|
|
||||||
|
#if !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;
|
||||||
|
struct pdu_adv_ext_hdr *hdr;
|
||||||
|
uint8_t *dptr;
|
||||||
|
|
||||||
|
com_hdr = &pdu->adv_ext_ind;
|
||||||
|
hdr = &com_hdr->ext_hdr;
|
||||||
|
|
||||||
|
if (!com_hdr->ext_hdr_len || (com_hdr->ext_hdr_len != 0 && !hdr->cte_info)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip flags in extended advertising header */
|
||||||
|
dptr = hdr->data;
|
||||||
|
|
||||||
|
/* Make sure there are no fields that are not allowd for AUX_SYNC_IND and AUX_CHAIN_IND */
|
||||||
|
LL_ASSERT(!hdr->adv_addr);
|
||||||
|
LL_ASSERT(!hdr->tgt_addr);
|
||||||
|
|
||||||
|
return (struct pdu_cte_info *)hdr->data;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BT_CTLR_CTEINLINE_SUPPORT */
|
||||||
|
|
|
@ -21,6 +21,13 @@ struct ll_sync_set {
|
||||||
uint16_t volatile timeout_reload; /* Non-zero when sync established */
|
uint16_t volatile timeout_reload; /* Non-zero when sync established */
|
||||||
uint16_t timeout_expire;
|
uint16_t timeout_expire;
|
||||||
|
|
||||||
|
#if !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 */
|
||||||
|
|
||||||
/* node rx type with memory aligned storage for sync lost reason.
|
/* node rx type with memory aligned storage for sync lost reason.
|
||||||
* HCI will reference the value using the pdu member of
|
* HCI will reference the value using the pdu member of
|
||||||
* struct node_rx_pdu.
|
* struct node_rx_pdu.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue