Bluetooth: Controller: Initial support for Periodic Sync Receive enable

Initial support for Periodic Advertising Synchronization
Receive Enable command.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
Vinayak Kariappa Chettimada 2021-12-02 07:08:34 +05:30 committed by Carles Cufí
commit 64eaa52e41
3 changed files with 68 additions and 21 deletions

View file

@ -3551,6 +3551,22 @@ static void le_per_adv_recv_enable(struct net_buf *buf, struct net_buf **evt)
status = ll_sync_recv_enable(handle, cmd->enable);
#if CONFIG_BT_CTLR_DUP_FILTER_LEN > 0
if (!status) {
if (cmd->enable &
BT_HCI_LE_SET_PER_ADV_RECV_ENABLE_FILTER_DUPLICATE) {
if (!dup_scan || (dup_count < 0)) {
dup_count = 0;
dup_curr = 0U;
} else {
/* FIXME: Invalidate dup_ext_adv_mode array entries */
}
} else if (!dup_scan) {
dup_count = DUP_FILTER_DISABLED;
}
}
#endif
ccst = hci_cmd_complete(evt, sizeof(*ccst));
ccst->status = status;
}

View file

@ -619,6 +619,7 @@ static void isr_aux_setup(void *param)
static int isr_rx(struct lll_sync *lll, uint8_t node_type, uint8_t crc_ok, uint8_t rssi_ready,
enum sync_status status)
{
uint8_t sched = 0U;
int err;
/* Check CRC and generate Periodic Advertising Report */
@ -626,7 +627,8 @@ static int isr_rx(struct lll_sync *lll, uint8_t node_type, uint8_t crc_ok, uint8
struct node_rx_pdu *node_rx;
node_rx = ull_pdu_rx_alloc_peek(3);
if (node_rx) {
if (node_rx &&
(lll->is_rx_enabled || (node_type == NODE_RX_TYPE_SYNC))) {
struct node_rx_ftr *ftr;
struct pdu_adv *pdu;
@ -660,25 +662,31 @@ static int isr_rx(struct lll_sync *lll, uint8_t node_type, uint8_t crc_ok, uint8
ull_rx_put(node_rx->hdr.link, node_rx);
#if defined(CONFIG_BT_CTLR_DF_SCAN_CTE_RX)
(void)create_iq_report(lll, rssi_ready,
BT_HCI_LE_CTE_CRC_OK);
#endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX */
ull_rx_sched();
sched = 1U;
} else {
err = 0;
}
#if defined(CONFIG_BT_CTLR_DF_SCAN_CTE_RX)
(void)create_iq_report(lll, rssi_ready, BT_HCI_LE_CTE_CRC_OK);
sched = 1U;
#endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX */
} else {
#if defined(CONFIG_BT_CTLR_DF_SAMPLE_CTE_FOR_PDU_WITH_BAD_CRC)
err = create_iq_report(lll, rssi_ready, BT_HCI_LE_CTE_CRC_ERR_CTE_BASED_TIME);
if (!err) {
ull_rx_sched();
sched = 1U;
}
#endif /* CONFIG_BT_CTLR_DF_SAMPLE_CTE_FOR_PDU_WITH_BAD_CRC */
err = 0;
}
if (sched) {
ull_rx_sched();
}
return err;
}

View file

@ -227,7 +227,7 @@ uint8_t ll_sync_create(uint8_t options, uint8_t sid, uint8_t adv_addr_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 */
/* Reporting initially enabled/disabled */
lll_sync->is_rx_enabled =
!(options & BT_HCI_LE_PER_ADV_CREATE_SYNC_FP_REPORTS_DISABLED);
@ -361,8 +361,27 @@ uint8_t ll_sync_terminate(uint16_t handle)
uint8_t ll_sync_recv_enable(uint16_t handle, uint8_t enable)
{
/* TODO: Add support for reporting enable/disable */
return BT_HCI_ERR_CMD_DISALLOWED;
struct ll_sync_set *sync;
struct lll_sync *lll;
sync = ull_sync_is_enabled_get(handle);
if (!sync) {
return BT_HCI_ERR_UNKNOWN_ADV_IDENTIFIER;
}
/* Reporting enabled/disabled */
lll = &sync->lll;
lll->is_rx_enabled = (enable &
BT_HCI_LE_SET_PER_ADV_RECV_ENABLE_ENABLE) ?
1U : 0U;
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_ADI_SUPPORT)
sync->nodups = (enable &
BT_HCI_LE_SET_PER_ADV_RECV_ENABLE_FILTER_DUPLICATE) ?
1U : 0U;
#endif
return 0;
}
int ull_sync_init(void)
@ -716,6 +735,7 @@ void ull_sync_established_report(memq_link_t *link, struct node_rx_hdr *rx)
struct lll_sync *lll;
ftr = &rx->rx_ftr;
lll = ftr->param;
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING)
enum sync_status sync_status;
@ -725,8 +745,6 @@ void ull_sync_established_report(memq_link_t *link, struct node_rx_hdr *rx)
#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,
@ -741,14 +759,14 @@ 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
#else /* !CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING */
if (1) {
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING */
#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.
*/
lll = ftr->param;
ull_sync = HDR_LLL2ULL(lll);
/* Prepare and dispatch sync notification */
@ -783,15 +801,20 @@ void ull_sync_established_report(memq_link_t *link, struct node_rx_hdr *rx)
* scanning is terminated due to wrong CTE type.
*/
if (sync_status != SYNC_STAT_TERM) {
#else
#else /* !CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING */
if (1) {
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING */
#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;
/* Change node type to appropriately handle periodic advertising PDU report */
rx->type = NODE_RX_TYPE_SYNC_REPORT;
ull_scan_aux_setup(link, rx);
if (lll->is_rx_enabled) {
/* Change node type to appropriately handle periodic
* advertising PDU report.
*/
rx->type = NODE_RX_TYPE_SYNC_REPORT;
ull_scan_aux_setup(link, rx);
}
}
}