Skip to content

Commit a5fb434

Browse files
cvinayakcarlescufi
authored andcommitted
Bluetooth: Controller: Fix to stop Extended Auxiliary Scan context
Fix any stray Extended Auxiliary PDU from being scanned when disabling Extended Scanning. Updated Extended Scan disable implementation to find any active auxiliary scan context and stop them. Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
1 parent ffeee6c commit a5fb434

File tree

4 files changed

+115
-10
lines changed

4 files changed

+115
-10
lines changed

subsys/bluetooth/controller/ll_sw/ull_scan.c

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,13 +355,20 @@ void ull_scan_params_set(struct lll_scan *lll, uint8_t type, uint16_t interval,
355355

356356
uint8_t ull_scan_enable(struct ll_scan_set *scan)
357357
{
358-
struct lll_scan *lll = &scan->lll;
359358
uint32_t ticks_slot_overhead;
360359
uint32_t volatile ret_cb;
361360
uint32_t ticks_interval;
362361
uint32_t ticks_anchor;
362+
struct lll_scan *lll;
363363
uint32_t ret;
364364

365+
#if defined(CONFIG_BT_CTLR_ADV_EXT)
366+
/* Initialize extend scan stop request */
367+
scan->is_stop = 0U;
368+
#endif /* CONFIG_BT_CTLR_ADV_EXT */
369+
370+
/* Initialize LLL scan context */
371+
lll = &scan->lll;
365372
lll->init_addr_type = scan->own_addr_type;
366373
(void)ll_addr_read(lll->init_addr_type, lll->init_addr);
367374
lll->chan = 0U;
@@ -462,13 +469,43 @@ uint8_t ull_scan_disable(uint8_t handle, struct ll_scan_set *scan)
462469
{
463470
int err;
464471

472+
#if defined(CONFIG_BT_CTLR_ADV_EXT)
473+
/* Request Extended Scan stop */
474+
scan->is_stop = 1U;
475+
cpu_dmb();
476+
#endif /* CONFIG_BT_CTLR_ADV_EXT */
477+
465478
err = ull_ticker_stop_with_mark(TICKER_ID_SCAN_BASE + handle,
466479
scan, &scan->lll);
467480
LL_ASSERT(err == 0 || err == -EALREADY);
468481
if (err) {
469482
return BT_HCI_ERR_CMD_DISALLOWED;
470483
}
471484

485+
#if defined(CONFIG_BT_CTLR_ADV_EXT)
486+
/* Find and stop associated auxiliary scan contexts */
487+
for (uint8_t aux_handle = 0; aux_handle < CONFIG_BT_CTLR_SCAN_AUX_SET;
488+
aux_handle++) {
489+
struct lll_scan_aux *aux_scan_lll;
490+
struct ll_scan_set *aux_scan;
491+
struct ll_scan_aux_set *aux;
492+
493+
aux = ull_scan_aux_set_get(aux_handle);
494+
aux_scan_lll = aux->parent;
495+
if (!aux_scan_lll) {
496+
continue;
497+
}
498+
499+
aux_scan = HDR_LLL2ULL(aux_scan_lll);
500+
if (aux_scan == scan) {
501+
err = ull_scan_aux_stop(aux);
502+
if (err && (err != -EALREADY)) {
503+
return BT_HCI_ERR_CMD_DISALLOWED;
504+
}
505+
}
506+
}
507+
#endif /* CONFIG_BT_CTLR_ADV_EXT */
508+
472509
return 0;
473510
}
474511

subsys/bluetooth/controller/ll_sw/ull_scan_aux.c

Lines changed: 72 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,14 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_hdr *rx)
552552

553553
/* Switching to ULL scheduling to receive auxiliary PDUs */
554554
if (!IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC) || lll) {
555+
/* Do not ULL schedule if scan disable requested */
556+
if (unlikely(scan->is_stop)) {
557+
goto ull_scan_aux_rx_flush;
558+
}
559+
560+
/* Remove auxiliary context association with scan context so
561+
* that LLL can differentiate it to being ULL scheduling.
562+
*/
555563
lll->lll_aux = NULL;
556564
} else {
557565
struct ll_sync_set *sync;
@@ -747,13 +755,36 @@ void ull_scan_aux_done(struct node_rx_event_done *done)
747755

748756
aux = HDR_LLL2ULL(sync->lll.lll_aux);
749757
} else {
758+
struct ll_scan_set *scan;
759+
760+
scan = HDR_LLL2ULL(aux->parent);
761+
LL_ASSERT(ull_scan_is_valid_get(scan));
762+
763+
/* Auxiliary context will be flushed by ull_scan_aux_stop() */
764+
if (unlikely(scan->is_stop)) {
765+
return;
766+
}
767+
750768
/* Setup the disabled callback to flush the auxiliary PDUs */
751769
hdr = &aux->ull;
752770
}
753771

754-
LL_ASSERT(!hdr->disabled_cb);
755-
hdr->disabled_param = aux;
756-
hdr->disabled_cb = done_disabled_cb;
772+
if (ull_ref_get(hdr) == 0U) {
773+
flush(aux);
774+
} else {
775+
LL_ASSERT(!hdr->disabled_cb);
776+
hdr->disabled_param = aux;
777+
hdr->disabled_cb = done_disabled_cb;
778+
}
779+
}
780+
781+
struct ll_scan_aux_set *ull_scan_aux_set_get(uint8_t handle)
782+
{
783+
if (handle >= CONFIG_BT_CTLR_SCAN_AUX_SET) {
784+
return NULL;
785+
}
786+
787+
return &ll_scan_aux_pool[handle];
757788
}
758789

759790
uint8_t ull_scan_aux_lll_handle_get(struct lll_scan_aux *lll)
@@ -856,7 +887,7 @@ void ull_scan_aux_release(memq_link_t *link, struct node_rx_hdr *rx)
856887
scan = HDR_LLL2ULL(lll);
857888
scan = ull_scan_is_valid_get(scan);
858889
if (scan) {
859-
is_stop = 0U;
890+
is_stop = scan->is_stop;
860891
} else {
861892
struct lll_sync *sync_lll;
862893
struct ll_sync_set *sync;
@@ -926,15 +957,37 @@ int ull_scan_aux_stop(struct ll_scan_aux_set *aux)
926957

927958
/* Abort LLL event if ULL scheduling not used or already in prepare */
928959
if (err == -EALREADY) {
929-
ret = ull_disable(&aux->lll);
930-
if (ret) {
931-
return -EBUSY;
960+
err = ull_disable(&aux->lll);
961+
if (err) {
962+
return err;
932963
}
933964

934965
mfy.fp = flush;
966+
967+
} else if (!IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC)) {
968+
/* ULL scan auxiliary PDU reception scheduling stopped
969+
* before prepare.
970+
*/
971+
mfy.fp = flush;
972+
935973
} else {
936-
/* ULL scheduling stopped before prepare */
937-
mfy.fp = aux_sync_incomplete;
974+
struct ll_scan_set *scan;
975+
struct lll_scan *lll;
976+
977+
lll = aux->parent;
978+
scan = HDR_LLL2ULL(lll);
979+
scan = ull_scan_is_valid_get(scan);
980+
if (scan) {
981+
/* ULL scan auxiliary PDU reception scheduling stopped
982+
* before prepare.
983+
*/
984+
mfy.fp = flush;
985+
} else {
986+
/* ULL sync chain reception scheduling stopped before
987+
* prepare.
988+
*/
989+
mfy.fp = aux_sync_incomplete;
990+
}
938991
}
939992

940993
/* Release auxiliary context in ULL execution context */
@@ -963,6 +1016,16 @@ static inline struct ll_scan_aux_set *aux_acquire(void)
9631016

9641017
static inline void aux_release(struct ll_scan_aux_set *aux)
9651018
{
1019+
/* Debug check that parent was assigned when allocated for reception of
1020+
* auxiliary channel PDUs.
1021+
*/
1022+
LL_ASSERT(aux->parent);
1023+
1024+
/* Clear the parent so that when scan is being disabled then this
1025+
* auxiliary context shall not associate itself from being disable.
1026+
*/
1027+
aux->parent = NULL;
1028+
9661029
mem_release(aux, &scan_aux_free);
9671030
}
9681031

subsys/bluetooth/controller/ll_sw/ull_scan_internal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_hdr *rx);
8080
/* Helper to clean up auxiliary channel scanning */
8181
void ull_scan_aux_done(struct node_rx_event_done *done);
8282

83+
/* Return the scan aux set instance given the handle */
84+
struct ll_scan_aux_set *ull_scan_aux_set_get(uint8_t handle);
85+
8386
/* Helper function to check and return if a valid aux scan context */
8487
struct ll_scan_aux_set *ull_scan_aux_is_valid_get(struct ll_scan_aux_set *aux);
8588

subsys/bluetooth/controller/ll_sw/ull_scan_types.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ struct ll_scan_set {
1111
#if defined(CONFIG_BT_CTLR_ADV_EXT)
1212
uint16_t duration_lazy;
1313
struct node_rx_hdr *node_rx_scan_term;
14+
15+
uint8_t is_stop:1;
1416
#endif /* CONFIG_BT_CTLR_ADV_EXT */
1517

1618
uint8_t is_enabled:1;

0 commit comments

Comments
 (0)