Skip to content

Commit 81136cb

Browse files
ppryga-nordiccfriedt
authored andcommitted
Bluetooth: controller: ULL: add per sync filtering by CTE type
Follow up on changes in lower link layer to add filtering of periodic advertisements synchronization by CTE type. The NODE_RX_TYPE_SYNC is used to transport information that: - Sync is established. In such situation the node_rx includes data related with received PDU - Sync scanning is terminated. In first case ULL will generate NODE_RX_TYPE_SYNC_REPORT after sending NODE_RX_TYPE_SYNC. Also EVENT_DONE_EXTRA_TYPE_SYNC handling has additional execution path that terminates sync scanning if requested by lower link layer. In other case it adjusts sync scan window and maintains timeout as usual. Signed-off-by: Piotr Pryga <[email protected]>
1 parent 42276f5 commit 81136cb

File tree

4 files changed

+133
-91
lines changed

4 files changed

+133
-91
lines changed

subsys/bluetooth/controller/ll_sw/ull.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2392,6 +2392,14 @@ static inline int rx_demux_rx(memq_link_t *link, struct node_rx_hdr *rx)
23922392
ull_scan_aux_release(link, rx);
23932393
}
23942394
break;
2395+
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC)
2396+
case NODE_RX_TYPE_SYNC:
2397+
{
2398+
(void)memq_dequeue(memq_ull_rx.tail, &memq_ull_rx.head, NULL);
2399+
ull_sync_established_report(link, rx);
2400+
}
2401+
break;
2402+
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */
23952403
#endif /* CONFIG_BT_CTLR_ADV_EXT */
23962404
#endif /* CONFIG_BT_OBSERVER */
23972405

subsys/bluetooth/controller/ll_sw/ull_scan_types.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ struct ll_scan_set {
2626

2727
uint8_t adv_addr[BDADDR_SIZE];
2828

29-
struct node_rx_hdr *node_rx_estab;
30-
3129
/* Non-Null when creating sync, reset in ISR context on
3230
* synchronisation state and checked in Thread context when
3331
* cancelling sync create, hence the volatile keyword.

subsys/bluetooth/controller/ll_sw/ull_sync.c

Lines changed: 124 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151

5252
static int init_reset(void);
5353
static inline struct ll_sync_set *sync_acquire(void);
54-
static void timeout_cleanup(struct ll_sync_set *sync);
54+
static void sync_ticker_cleanup(struct ll_sync_set *sync, ticker_op_func stop_of_cb);
5555
static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
5656
uint32_t remainder, uint16_t lazy, uint8_t force,
5757
void *param);
@@ -72,6 +72,9 @@ static void *sync_free;
7272
static struct k_sem sem_ticker_cb;
7373
#endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX */
7474

75+
static memq_link_t link_lll_prepare;
76+
static struct mayfly mfy_lll_prepare = { 0, 0, &link_lll_prepare, NULL, lll_sync_prepare };
77+
7578
uint8_t ll_sync_create(uint8_t options, uint8_t sid, uint8_t adv_addr_type,
7679
uint8_t *adv_addr, uint16_t skip,
7780
uint16_t sync_timeout, uint8_t sync_cte_type)
@@ -125,14 +128,10 @@ uint8_t ll_sync_create(uint8_t options, uint8_t sid, uint8_t adv_addr_type,
125128
return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
126129
}
127130

128-
node_rx->link = link_sync_estab;
129-
scan->per_scan.node_rx_estab = node_rx;
130131
scan->per_scan.state = LL_SYNC_STATE_IDLE;
131132
scan->per_scan.filter_policy = options & BIT(0);
132133
if (IS_ENABLED(CONFIG_BT_CTLR_PHY_CODED)) {
133134
scan_coded->per_scan.state = LL_SYNC_STATE_IDLE;
134-
scan_coded->per_scan.node_rx_estab =
135-
scan->per_scan.node_rx_estab;
136135
scan_coded->per_scan.filter_policy =
137136
scan->per_scan.filter_policy;
138137
}
@@ -154,9 +153,9 @@ uint8_t ll_sync_create(uint8_t options, uint8_t sid, uint8_t adv_addr_type,
154153
sync->skip = skip;
155154
sync->timeout = sync_timeout;
156155

157-
/* TODO: Support for CTE type */
158-
159156
/* Initialize sync context */
157+
node_rx->link = link_sync_estab;
158+
sync->node_rx_sync_estab = node_rx;
160159
sync->timeout_reload = 0U;
161160
sync->timeout_expire = 0U;
162161

@@ -171,6 +170,8 @@ uint8_t ll_sync_create(uint8_t options, uint8_t sid, uint8_t adv_addr_type,
171170
lll_sync->skip_event = 0U;
172171
lll_sync->window_widening_prepare_us = 0U;
173172
lll_sync->window_widening_event_us = 0U;
173+
lll_sync->cte_type = sync_cte_type;
174+
lll_sync->filter_policy = scan->per_scan.filter_policy;
174175

175176
/* Reporting initially enabled/disabled */
176177
lll_sync->is_rx_enabled = options & BIT(1);
@@ -235,7 +236,7 @@ uint8_t ll_sync_create_cancel(void **rx)
235236
return BT_HCI_ERR_CMD_DISALLOWED;
236237
}
237238

238-
node_rx = (void *)scan->per_scan.node_rx_estab;
239+
node_rx = (void *)sync->node_rx_sync_estab;
239240
link_sync_estab = node_rx->hdr.link;
240241
link_sync_lost = sync->node_rx_lost.hdr.link;
241242

@@ -465,19 +466,15 @@ void ull_sync_setup(struct ll_scan_set *scan, struct ll_scan_aux_set *aux,
465466
sync_handle = ull_sync_handle_get(sync);
466467

467468
/* Prepare and dispatch sync notification */
468-
rx = (void *)scan->per_scan.node_rx_estab;
469+
rx = (void *)sync->node_rx_sync_estab;
469470
rx->hdr.type = NODE_RX_TYPE_SYNC;
470471
rx->hdr.handle = sync_handle;
471472
rx->hdr.rx_ftr.param = scan;
472473
se = (void *)rx->pdu;
473-
se->status = BT_HCI_ERR_SUCCESS;
474474
se->interval = interval;
475475
se->phy = lll->phy;
476476
se->sca = sca;
477477

478-
ll_rx_put(rx->hdr.link, rx);
479-
ll_rx_sched();
480-
481478
/* Calculate offset and schedule sync radio events */
482479
ftr = &node_rx->rx_ftr;
483480
pdu = (void *)((struct node_rx_pdu *)node_rx)->pdu;
@@ -515,6 +512,8 @@ void ull_sync_setup(struct ll_scan_set *scan, struct ll_scan_aux_set *aux,
515512
}
516513
ticks_slot_offset += HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US);
517514

515+
mfy_lll_prepare.fp = lll_sync_create_prepare;
516+
518517
ret = ticker_start(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_ULL_HIGH,
519518
(TICKER_ID_SCAN_SYNC_BASE + sync_handle),
520519
ftr->ticks_anchor - ticks_slot_offset,
@@ -528,6 +527,52 @@ void ull_sync_setup(struct ll_scan_set *scan, struct ll_scan_aux_set *aux,
528527
(ret == TICKER_STATUS_BUSY));
529528
}
530529

530+
void ull_sync_established_report(memq_link_t *link, struct node_rx_hdr *rx)
531+
{
532+
struct node_rx_pdu *rx_establ;
533+
struct ll_sync_set *ull_sync;
534+
struct node_rx_ftr *ftr;
535+
struct node_rx_sync *se;
536+
struct lll_sync *lll;
537+
538+
ftr = &rx->rx_ftr;
539+
540+
/* Send periodic advertisement sync established report when sync has correct CTE type
541+
* or the CTE type is incorrect and filter policy doesn't allow to continue scanning.
542+
*/
543+
if (ftr->sync_status != SYNC_STAT_READY) {
544+
/* Set the sync handle corresponding to the LLL context passed in the node rx
545+
* footer field.
546+
*/
547+
lll = ftr->param;
548+
ull_sync = HDR_LLL2ULL(lll);
549+
550+
/* Prepare and dispatch sync notification */
551+
rx_establ = (void *)ull_sync->node_rx_sync_estab;
552+
rx_establ->hdr.type = NODE_RX_TYPE_SYNC;
553+
se = (void *)rx_establ->pdu;
554+
se->status = (ftr->sync_status == SYNC_STAT_TERM) ?
555+
BT_HCI_ERR_UNSUPP_REMOTE_FEATURE :
556+
BT_HCI_ERR_SUCCESS;
557+
558+
ll_rx_put(rx_establ->hdr.link, rx_establ);
559+
ll_rx_sched();
560+
}
561+
562+
/* Handle periodic advertising PDU and send periodic advertising scan report when
563+
* the sync was found or was established in the past. The report is not send if
564+
* scanning is terminated due to wrong CTE type.
565+
*/
566+
if (ftr->sync_status != SYNC_STAT_TERM) {
567+
/* Switch sync event prepare function to one reposnsible for regular PDUs receive */
568+
mfy_lll_prepare.fp = lll_sync_prepare;
569+
570+
/* Change node type to appropriately handle periodic advertising PDU report */
571+
rx->type = NODE_RX_TYPE_SYNC_REPORT;
572+
ull_scan_aux_setup(link, rx);
573+
}
574+
}
575+
531576
void ull_sync_done(struct node_rx_event_done *done)
532577
{
533578
uint32_t ticks_drift_minus;
@@ -543,84 +588,79 @@ void ull_sync_done(struct node_rx_event_done *done)
543588
sync = CONTAINER_OF(done->param, struct ll_sync_set, ull);
544589
lll = &sync->lll;
545590

546-
/* Events elapsed used in timeout checks below */
547-
skip_event = lll->skip_event;
548-
elapsed_event = skip_event + 1;
549-
550-
/* Sync drift compensation and new skip calculation
551-
*/
552-
ticks_drift_plus = 0U;
553-
ticks_drift_minus = 0U;
554-
if (done->extra.trx_cnt) {
555-
/* Calculate drift in ticks unit */
556-
ull_drift_ticks_get(done, &ticks_drift_plus,
557-
&ticks_drift_minus);
558-
559-
/* Enforce skip */
560-
lll->skip_event = sync->skip;
561-
}
562-
563-
/* Reset supervision countdown */
564-
if (done->extra.crc_valid) {
565-
sync->timeout_expire = 0U;
566-
}
591+
if (done->extra.sync_term) {
592+
/* Stop periodic advertising scan ticker */
593+
sync_ticker_cleanup(sync, NULL);
594+
} else {
595+
/* Events elapsed used in timeout checks below */
596+
skip_event = lll->skip_event;
597+
elapsed_event = skip_event + 1;
598+
599+
/* Sync drift compensation and new skip calculation */
600+
ticks_drift_plus = 0U;
601+
ticks_drift_minus = 0U;
602+
if (done->extra.trx_cnt) {
603+
/* Calculate drift in ticks unit */
604+
ull_drift_ticks_get(done, &ticks_drift_plus, &ticks_drift_minus);
605+
606+
/* Enforce skip */
607+
lll->skip_event = sync->skip;
608+
}
567609

568-
/* if anchor point not sync-ed, start timeout countdown, and break
569-
* skip if any.
570-
*/
571-
else {
572-
if (!sync->timeout_expire) {
610+
/* Reset supervision countdown */
611+
if (done->extra.crc_valid) {
612+
sync->timeout_expire = 0U;
613+
}
614+
/* If anchor point not sync-ed, start timeout countdown, and break skip if any */
615+
else if (!sync->timeout_expire) {
573616
sync->timeout_expire = sync->timeout_reload;
574617
}
575-
}
576618

577-
/* check timeout */
578-
force = 0U;
579-
if (sync->timeout_expire) {
580-
if (sync->timeout_expire > elapsed_event) {
581-
sync->timeout_expire -= elapsed_event;
619+
/* check timeout */
620+
force = 0U;
621+
if (sync->timeout_expire) {
622+
if (sync->timeout_expire > elapsed_event) {
623+
sync->timeout_expire -= elapsed_event;
582624

583-
/* break skip */
584-
lll->skip_event = 0U;
625+
/* break skip */
626+
lll->skip_event = 0U;
585627

586-
if (skip_event) {
587-
force = 1U;
588-
}
589-
} else {
590-
timeout_cleanup(sync);
628+
if (skip_event) {
629+
force = 1U;
630+
}
631+
} else {
632+
sync_ticker_cleanup(sync, ticker_stop_op_cb);
591633

592-
return;
634+
return;
635+
}
593636
}
594-
}
595637

596-
/* check if skip needs update */
597-
lazy = 0U;
598-
if ((force) || (skip_event != lll->skip_event)) {
599-
lazy = lll->skip_event + 1U;
600-
}
638+
/* Check if skip needs update */
639+
lazy = 0U;
640+
if ((force) || (skip_event != lll->skip_event)) {
641+
lazy = lll->skip_event + 1U;
642+
}
601643

602-
/* Update Sync ticker instance */
603-
if (ticks_drift_plus || ticks_drift_minus || lazy || force) {
604-
uint16_t sync_handle = ull_sync_handle_get(sync);
605-
uint32_t ticker_status;
644+
/* Update Sync ticker instance */
645+
if (ticks_drift_plus || ticks_drift_minus || lazy || force) {
646+
uint16_t sync_handle = ull_sync_handle_get(sync);
647+
uint32_t ticker_status;
606648

607-
/* Call to ticker_update can fail under the race
608-
* condition where in the periodic sync role is being stopped
609-
* but at the same time it is preempted by periodic sync event
610-
* that gets into close state. Accept failure when periodic sync
611-
* role is being stopped.
612-
*/
613-
ticker_status = ticker_update(TICKER_INSTANCE_ID_CTLR,
614-
TICKER_USER_ID_ULL_HIGH,
615-
(TICKER_ID_SCAN_SYNC_BASE +
616-
sync_handle),
617-
ticks_drift_plus,
618-
ticks_drift_minus, 0, 0,
619-
lazy, force,
620-
ticker_update_sync_op_cb, sync);
621-
LL_ASSERT((ticker_status == TICKER_STATUS_SUCCESS) ||
622-
(ticker_status == TICKER_STATUS_BUSY) ||
623-
((void *)sync == ull_disable_mark_get()));
649+
/* Call to ticker_update can fail under the race
650+
* condition where in the periodic sync role is being stopped
651+
* but at the same time it is preempted by periodic sync event
652+
* that gets into close state. Accept failure when periodic sync
653+
* role is being stopped.
654+
*/
655+
ticker_status =
656+
ticker_update(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_ULL_HIGH,
657+
(TICKER_ID_SCAN_SYNC_BASE + sync_handle),
658+
ticks_drift_plus, ticks_drift_minus, 0, 0, lazy,
659+
force, ticker_update_sync_op_cb, sync);
660+
LL_ASSERT((ticker_status == TICKER_STATUS_SUCCESS) ||
661+
(ticker_status == TICKER_STATUS_BUSY) ||
662+
((void *)sync == ull_disable_mark_get()));
663+
}
624664
}
625665
}
626666

@@ -762,15 +802,14 @@ static inline struct ll_sync_set *sync_acquire(void)
762802
return mem_acquire(&sync_free);
763803
}
764804

765-
static void timeout_cleanup(struct ll_sync_set *sync)
805+
static void sync_ticker_cleanup(struct ll_sync_set *sync, ticker_op_func stop_of_cb)
766806
{
767807
uint16_t sync_handle = ull_sync_handle_get(sync);
768808
uint32_t ret;
769809

770810
/* Stop Periodic Sync Ticker */
771811
ret = ticker_stop(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_ULL_HIGH,
772-
TICKER_ID_SCAN_SYNC_BASE + sync_handle,
773-
ticker_stop_op_cb, (void *)sync);
812+
TICKER_ID_SCAN_SYNC_BASE + sync_handle, stop_of_cb, (void *)sync);
774813
LL_ASSERT((ret == TICKER_STATUS_SUCCESS) ||
775814
(ret == TICKER_STATUS_BUSY));
776815
}
@@ -779,8 +818,6 @@ static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
779818
uint32_t remainder, uint16_t lazy, uint8_t force,
780819
void *param)
781820
{
782-
static memq_link_t link;
783-
static struct mayfly mfy = {0, 0, &link, NULL, lll_sync_prepare};
784821
static struct lll_prepare_param p;
785822
struct ll_sync_set *sync = param;
786823
struct lll_sync *lll;
@@ -801,11 +838,10 @@ static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
801838
p.lazy = lazy;
802839
p.force = force;
803840
p.param = lll;
804-
mfy.param = &p;
841+
mfy_lll_prepare.param = &p;
805842

806843
/* Kick LLL prepare */
807-
ret = mayfly_enqueue(TICKER_USER_ID_ULL_HIGH,
808-
TICKER_USER_ID_LLL, 0, &mfy);
844+
ret = mayfly_enqueue(TICKER_USER_ID_ULL_HIGH, TICKER_USER_ID_LLL, 0, &mfy_lll_prepare);
809845
LL_ASSERT(!ret);
810846

811847
DEBUG_RADIO_PREPARE_O(1);
@@ -814,7 +850,6 @@ static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
814850
static void ticker_op_cb(uint32_t status, void *param)
815851
{
816852
ARG_UNUSED(param);
817-
818853
LL_ASSERT(status == TICKER_STATUS_SUCCESS);
819854
}
820855

subsys/bluetooth/controller/ll_sw/ull_sync_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ struct ll_sync_set *ull_sync_is_enabled_get(uint16_t handle);
1111
void ull_sync_release(struct ll_sync_set *sync);
1212
void ull_sync_setup(struct ll_scan_set *scan, struct ll_scan_aux_set *aux,
1313
struct node_rx_hdr *node_rx, struct pdu_adv_sync_info *si);
14+
void ull_sync_established_report(memq_link_t *link, struct node_rx_hdr *rx);
1415
void ull_sync_done(struct node_rx_event_done *done);
1516
void ull_sync_chm_update(uint8_t sync_handle, uint8_t *acad, uint8_t acad_len);
1617
int ull_sync_slot_update(struct ll_sync_set *sync, uint32_t slot_plus_us,

0 commit comments

Comments
 (0)