Skip to content

Commit 01c9c67

Browse files
cvinayakdanieldegrasse
authored andcommitted
Bluetooth: Controller: Fix incorrect elapsed events value
Fix incorrect elapsed events value when LLL event prepare_cb was invoked but was aborted before anchor point sync. This caused premature supervision timeouts under applications configured with CONFIG_BT_CTLR_EVENT_OVERHEAD_RESERVE_MAX=n and CONFIG_BT_CTLR_PERIPHERAL_RESERVE_MAX=n. Fixes commit 247037b ("Bluetooth: Controller: Fix incorrect elapsed events value"). Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
1 parent 0969148 commit 01c9c67

File tree

6 files changed

+74
-92
lines changed

6 files changed

+74
-92
lines changed

subsys/bluetooth/controller/ll_sw/lll_sync_iso.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,10 @@ struct lll_sync_iso {
3030

3131
uint16_t iso_interval;
3232

33+
uint16_t lazy_prepare;
3334
uint16_t latency_prepare;
3435
uint16_t latency_event;
36+
3537
union {
3638
struct lll_sync_iso_data_chan data_chan;
3739

subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync.c

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@
4646
#include "hal/debug.h"
4747

4848
static int init_reset(void);
49-
static void prepare(void *param);
5049
static int create_prepare_cb(struct lll_prepare_param *p);
5150
static int prepare_cb(struct lll_prepare_param *p);
5251
static int prepare_cb_common(struct lll_prepare_param *p, uint8_t chan_idx);
@@ -100,7 +99,9 @@ void lll_sync_create_prepare(void *param)
10099
{
101100
int err;
102101

103-
prepare(param);
102+
/* Request to start HF Clock */
103+
err = lll_hfclock_on();
104+
LL_ASSERT(err >= 0);
104105

105106
/* Invoke common pipeline handling of prepare */
106107
err = lll_prepare(is_abort_cb, abort_cb, create_prepare_cb, 0, param);
@@ -111,35 +112,13 @@ void lll_sync_prepare(void *param)
111112
{
112113
int err;
113114

114-
prepare(param);
115-
116-
/* Invoke common pipeline handling of prepare */
117-
err = lll_prepare(is_abort_cb, abort_cb, prepare_cb, 0, param);
118-
LL_ASSERT(!err || err == -EINPROGRESS);
119-
}
120-
121-
static void prepare(void *param)
122-
{
123-
struct lll_prepare_param *p;
124-
struct lll_sync *lll;
125-
int err;
126-
127115
/* Request to start HF Clock */
128116
err = lll_hfclock_on();
129117
LL_ASSERT(err >= 0);
130118

131-
p = param;
132-
133-
lll = p->param;
134-
135-
lll->lazy_prepare = p->lazy;
136-
137-
/* Accumulate window widening */
138-
lll->window_widening_prepare_us += lll->window_widening_periodic_us *
139-
(lll->lazy_prepare + 1U);
140-
if (lll->window_widening_prepare_us > lll->window_widening_max_us) {
141-
lll->window_widening_prepare_us = lll->window_widening_max_us;
142-
}
119+
/* Invoke common pipeline handling of prepare */
120+
err = lll_prepare(is_abort_cb, abort_cb, prepare_cb, 0, param);
121+
LL_ASSERT(err == 0 || err == -EINPROGRESS);
143122
}
144123

145124
void lll_sync_aux_prepare_cb(struct lll_sync *lll,
@@ -274,6 +253,7 @@ static int create_prepare_cb(struct lll_prepare_param *p)
274253
lll = p->param;
275254

276255
/* Calculate the current event latency */
256+
lll->lazy_prepare = p->lazy;
277257
lll->skip_event = lll->skip_prepare + lll->lazy_prepare;
278258

279259
/* Calculate the current event counter value */
@@ -362,6 +342,7 @@ static int prepare_cb(struct lll_prepare_param *p)
362342
lll = p->param;
363343

364344
/* Calculate the current event latency */
345+
lll->lazy_prepare = p->lazy;
365346
lll->skip_event = lll->skip_prepare + lll->lazy_prepare;
366347

367348
/* Calculate the current event counter value */
@@ -442,6 +423,13 @@ static int prepare_cb_common(struct lll_prepare_param *p, uint8_t chan_idx)
442423

443424
lll = p->param;
444425

426+
/* Accumulate window widening */
427+
lll->window_widening_prepare_us += lll->window_widening_periodic_us *
428+
(lll->lazy_prepare + 1U);
429+
if (lll->window_widening_prepare_us > lll->window_widening_max_us) {
430+
lll->window_widening_prepare_us = lll->window_widening_max_us;
431+
}
432+
445433
/* Current window widening */
446434
lll->window_widening_event_us += lll->window_widening_prepare_us;
447435
lll->window_widening_prepare_us = 0;
@@ -631,10 +619,20 @@ static void abort_cb(struct lll_prepare_param *prepare_param, void *param)
631619
err = lll_hfclock_off();
632620
LL_ASSERT(err >= 0);
633621

634-
/* Accumulate the latency as event is aborted while being in pipeline */
622+
/* Get reference to LLL connection context */
635623
lll = prepare_param->param;
624+
625+
/* Accumulate the latency as event is aborted while being in pipeline */
626+
lll->lazy_prepare = prepare_param->lazy;
636627
lll->skip_prepare += (lll->lazy_prepare + 1U);
637628

629+
/* Accumulate window widening */
630+
lll->window_widening_prepare_us += lll->window_widening_periodic_us *
631+
(prepare_param->lazy + 1);
632+
if (lll->window_widening_prepare_us > lll->window_widening_max_us) {
633+
lll->window_widening_prepare_us = lll->window_widening_max_us;
634+
}
635+
638636
/* Extra done event, to check sync lost */
639637
e = ull_event_done_extra_get();
640638
LL_ASSERT(e);

subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync_iso.c

Lines changed: 41 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,6 @@
4040
#include "hal/debug.h"
4141

4242
static int init_reset(void);
43-
static void prepare(void *param);
44-
static void create_prepare_bh(void *param);
45-
static void prepare_bh(void *param);
4643
static int create_prepare_cb(struct lll_prepare_param *p);
4744
static int prepare_cb(struct lll_prepare_param *p);
4845
static int prepare_cb_common(struct lll_prepare_param *p);
@@ -101,72 +98,36 @@ int lll_sync_iso_reset(void)
10198

10299
void lll_sync_iso_create_prepare(void *param)
103100
{
104-
prepare(param);
105-
create_prepare_bh(param);
106-
}
107-
108-
void lll_sync_iso_prepare(void *param)
109-
{
110-
prepare(param);
111-
prepare_bh(param);
112-
}
101+
int err;
113102

114-
void lll_sync_iso_flush(uint8_t handle, struct lll_sync_iso *lll)
115-
{
116-
ARG_UNUSED(handle);
117-
ARG_UNUSED(lll);
118-
}
103+
err = lll_hfclock_on();
104+
LL_ASSERT(err >= 0);
119105

120-
static int init_reset(void)
121-
{
122-
return 0;
106+
err = lll_prepare(is_abort_cb, abort_cb, create_prepare_cb, 0U,
107+
param);
108+
LL_ASSERT(err == 0 || err == -EINPROGRESS);
123109
}
124110

125-
static void prepare(void *param)
111+
void lll_sync_iso_prepare(void *param)
126112
{
127-
struct lll_prepare_param *p;
128-
struct lll_sync_iso *lll;
129-
uint16_t elapsed;
130113
int err;
131114

132115
err = lll_hfclock_on();
133116
LL_ASSERT(err >= 0);
134117

135-
p = param;
136-
137-
/* Instants elapsed */
138-
elapsed = p->lazy + 1U;
139-
140-
lll = p->param;
141-
142-
/* Save the (latency + 1) for use in event */
143-
lll->latency_prepare += elapsed;
144-
145-
/* Accumulate window widening */
146-
lll->window_widening_prepare_us += lll->window_widening_periodic_us *
147-
elapsed;
148-
if (lll->window_widening_prepare_us > lll->window_widening_max_us) {
149-
lll->window_widening_prepare_us = lll->window_widening_max_us;
150-
}
118+
err = lll_prepare(is_abort_cb, abort_cb, prepare_cb, 0U, param);
119+
LL_ASSERT(err == 0 || err == -EINPROGRESS);
151120
}
152121

153-
static void create_prepare_bh(void *param)
122+
void lll_sync_iso_flush(uint8_t handle, struct lll_sync_iso *lll)
154123
{
155-
int err;
156-
157-
/* Invoke common pipeline handling of prepare */
158-
err = lll_prepare(is_abort_cb, abort_cb, create_prepare_cb, 0U,
159-
param);
160-
LL_ASSERT(!err || err == -EINPROGRESS);
124+
ARG_UNUSED(handle);
125+
ARG_UNUSED(lll);
161126
}
162127

163-
static void prepare_bh(void *param)
128+
static int init_reset(void)
164129
{
165-
int err;
166-
167-
/* Invoke common pipeline handling of prepare */
168-
err = lll_prepare(is_abort_cb, abort_cb, prepare_cb, 0U, param);
169-
LL_ASSERT(!err || err == -EINPROGRESS);
130+
return 0;
170131
}
171132

172133
static int create_prepare_cb(struct lll_prepare_param *p)
@@ -225,18 +186,26 @@ static int prepare_cb_common(struct lll_prepare_param *p)
225186

226187
lll = p->param;
227188

228-
/* Deduce the latency */
229-
lll->latency_event = lll->latency_prepare - 1U;
189+
/* Calculate the current event latency */
190+
lll->lazy_prepare = p->lazy;
191+
lll->latency_event = lll->latency_prepare + lll->lazy_prepare;
230192

231193
/* Calculate the current event counter value */
232194
event_counter = (lll->payload_count / lll->bn) + lll->latency_event;
233195

234196
/* Update BIS packet counter to next value */
235-
lll->payload_count += (lll->latency_prepare * lll->bn);
197+
lll->payload_count += (lll->latency_event + 1U) * lll->bn;
236198

237199
/* Reset accumulated latencies */
238200
lll->latency_prepare = 0U;
239201

202+
/* Accumulate window widening */
203+
lll->window_widening_prepare_us += lll->window_widening_periodic_us *
204+
(lll->lazy_prepare + 1U);
205+
if (lll->window_widening_prepare_us > lll->window_widening_max_us) {
206+
lll->window_widening_prepare_us = lll->window_widening_max_us;
207+
}
208+
240209
/* Current window widening */
241210
lll->window_widening_event_us += lll->window_widening_prepare_us;
242211
lll->window_widening_prepare_us = 0U;
@@ -476,6 +445,7 @@ static int is_abort_cb(void *next, void *curr, lll_prepare_cb_t *resume_cb)
476445
static void abort_cb(struct lll_prepare_param *prepare_param, void *param)
477446
{
478447
struct event_done_extra *e;
448+
struct lll_sync_iso *lll;
479449
int err;
480450

481451
/* NOTE: This is not a prepare being cancelled */
@@ -484,7 +454,7 @@ static void abort_cb(struct lll_prepare_param *prepare_param, void *param)
484454
radio_disable();
485455

486456
if (IS_ENABLED(CONFIG_BT_CTLR_BROADCAST_ISO_ENC)) {
487-
const struct lll_sync_iso *lll = param;
457+
lll = param;
488458

489459
if (lll->enc) {
490460
radio_ccm_disable();
@@ -500,6 +470,20 @@ static void abort_cb(struct lll_prepare_param *prepare_param, void *param)
500470
err = lll_hfclock_off();
501471
LL_ASSERT(err >= 0);
502472

473+
/* Get reference to LLL connection context */
474+
lll = prepare_param->param;
475+
476+
/* Accumulate the latency as event is aborted while being in pipeline */
477+
lll->lazy_prepare = prepare_param->lazy;
478+
lll->latency_prepare += (lll->lazy_prepare + 1U);
479+
480+
/* Accumulate window widening */
481+
lll->window_widening_prepare_us += lll->window_widening_periodic_us *
482+
(prepare_param->lazy + 1);
483+
if (lll->window_widening_prepare_us > lll->window_widening_max_us) {
484+
lll->window_widening_prepare_us = lll->window_widening_max_us;
485+
}
486+
503487
/* Extra done event, to check sync lost */
504488
e = ull_event_done_extra_get();
505489
LL_ASSERT(e);

subsys/bluetooth/controller/ll_sw/ull_conn.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1129,7 +1129,7 @@ void ull_conn_done(struct node_rx_event_done *done)
11291129
#endif /* CONFIG_BT_PERIPHERAL */
11301130
}
11311131

1132-
elapsed_event = latency_event + lll->lazy_prepare + 1U;
1132+
elapsed_event = lll->lazy_prepare + 1U;
11331133

11341134
/* Reset supervision countdown */
11351135
if (done->extra.crc_valid && !done->extra.is_aborted) {

subsys/bluetooth/controller/ll_sw/ull_sync.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1342,7 +1342,7 @@ void ull_sync_done(struct node_rx_event_done *done)
13421342
sync->sync_expire = 0U;
13431343
}
13441344

1345-
elapsed_event = skip_event + lll->lazy_prepare + 1U;
1345+
elapsed_event = lll->lazy_prepare + 1U;
13461346

13471347
/* Reset supervision countdown */
13481348
if (done->extra.crc_valid) {

subsys/bluetooth/controller/ll_sw/ull_sync_iso.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ uint8_t ll_big_sync_create(uint8_t big_handle, uint16_t sync_handle,
185185

186186
/* Initialize sync LLL context */
187187
lll = &sync_iso->lll;
188+
lll->lazy_prepare = 0U;
188189
lll->latency_prepare = 0U;
189190
lll->latency_event = 0U;
190191
lll->window_widening_prepare_us = 0U;
@@ -762,11 +763,6 @@ void ull_sync_iso_done(struct node_rx_event_done *done)
762763

763764
/* Events elapsed used in timeout checks below */
764765
latency_event = lll->latency_event;
765-
if (lll->latency_prepare) {
766-
elapsed_event = latency_event + lll->latency_prepare;
767-
} else {
768-
elapsed_event = latency_event + 1U;
769-
}
770766

771767
/* Check for establishmet failure */
772768
if (done->extra.estab_failed) {
@@ -800,6 +796,8 @@ void ull_sync_iso_done(struct node_rx_event_done *done)
800796
}
801797
}
802798

799+
elapsed_event = lll->lazy_prepare + 1U;
800+
803801
/* check timeout */
804802
force = 0U;
805803
if (sync_iso->timeout_expire) {

0 commit comments

Comments
 (0)