Skip to content
Permalink
Browse files

Bluetooth: controller: split: Fix pipeline for continuous events

Fix the pipeline prepare-resume implementation to correctly
handle multiple continuous events that request resume on
being pre-empted.

Symptoms of the bug being, when having continuous scanning,
and an active peripheral if a directed advertising is
started the peripheral event are not scheduled causing link
supervision timeout.

This is fixed by not having an enqueued resume event
prepared if there is an enqueued new non-resume event in the
pipeline.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
  • Loading branch information...
cvinayak authored and carlescufi committed Aug 8, 2019
1 parent d90f3db commit 3e0e378dcae7b5eda0ae6e1f5c38e55f165aafc5
Showing with 9 additions and 19 deletions.
  1. +9 −19 subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c
@@ -191,21 +191,9 @@ void lll_resume(void *param)
struct lll_event *next = param;
int ret;

if (event.curr.abort_cb) {
ret = prepare(next->is_abort_cb, next->abort_cb,
next->prepare_cb, next->prio,
&next->prepare_param, next->is_resume);
LL_ASSERT(!ret || ret == -EINPROGRESS);

return;
}

event.curr.is_abort_cb = next->is_abort_cb;
event.curr.abort_cb = next->abort_cb;
event.curr.param = next->prepare_param.param;

ret = next->prepare_cb(&next->prepare_param);
LL_ASSERT(!ret);
ret = prepare(next->is_abort_cb, next->abort_cb, next->prepare_cb,
next->prio, &next->prepare_param, next->is_resume);
LL_ASSERT(!ret || ret == -EINPROGRESS);
}

void lll_disable(void *param)
@@ -426,12 +414,14 @@ static int prepare(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb,
struct lll_event *p;
u8_t idx = UINT8_MAX;

/* Find the ready prepare in the pipeline */
p = ull_prepare_dequeue_iter(&idx);
while (p && p->is_aborted) {
while (p && (p->is_aborted || p->is_resume)) {
p = ull_prepare_dequeue_iter(&idx);
}

if (event.curr.abort_cb || p) {
/* Current event active or another prepare is ready in the pipeline */
if (event.curr.abort_cb || (p && is_resume)) {
#if !defined(CONFIG_BT_CTLR_LOW_LAT)
u32_t preempt_anchor;
struct evt_hdr *evt;
@@ -453,11 +443,11 @@ static int prepare(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb,
prepare_cb, prio, is_resume);
LL_ASSERT(!ret);

#if !defined(CONFIG_BT_CTLR_LOW_LAT)
if (is_resume) {
return -EINPROGRESS;
}

#if !defined(CONFIG_BT_CTLR_LOW_LAT)
/* Calc the preempt timeout */
evt = HDR_LLL2EVT(prepare_param->param);
preempt_anchor = prepare_param->ticks_at_expire;
@@ -571,7 +561,7 @@ static void preempt(void *param)
return;
}

while (next && next->is_resume) {
while (next && (next->is_aborted || next->is_resume)) {
next = ull_prepare_dequeue_iter(&idx);
}

0 comments on commit 3e0e378

Please sign in to comment.
You can’t perform that action at this time.