Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bluetooth: Controller: ISO Sync Receiver with ticks_slot_window #75760

Closed
Closed
30 changes: 30 additions & 0 deletions subsys/bluetooth/controller/Kconfig.ll_sw_split
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I always get sad when I see more Kconfig options for the LL :( It's already way too hard to configure, and we keep adding more and more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Kconfig's have been added incrementally, atleast trying to keep existing features not being disturbed too much. Most internal once should get hidden under the Advanced Features but some of them are being be used outside. But hopefully will make them defaults in the future when the options form matured options in default builds of samples. Least or seldom used Kconfigs can be delete there after.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, it doesn't look like these new Kconfig options are ever tested

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I will add modified bsim tests to cover the enhancements, the bap_broadcast_sink variant with XO clock drifts to have ACL connection in a sink drift over the BIG sync events, and measure SDU drops.

Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,13 @@ config BT_CTLR_ADV_RESERVE_MAX
corresponding to the Advertising Data present at the time of the
start/enable of Advertising is used.

config BT_CTLR_ADV_AUX_SLOT_WINDOW
bool "Reschedule Extended Advertising Auxiliary PDUs"
depends on BT_BROADCASTER && BT_CTLR_ADV_EXT
select BT_TICKER_EXT
Comment on lines +435 to +436
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the reasoning behind selecting BT_TICKER_EXT rather than depending on it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, will fix this to be depends on

help
Reschedule Extended Advertising Auxiliary PDUs.

config BT_CTLR_ADV_ISO_RESERVE_MAX
bool "Use maximum Broadcast ISO event time reservation"
depends on BT_CTLR_ADV_ISO
Expand Down Expand Up @@ -540,6 +547,16 @@ config BT_CTLR_SYNC_ISO_RESERVE_MAX
disabled, then time reservation does not include the pre-transmissions
and any Control subevents.

config BT_CTLR_SYNC_ISO_SLOT_WINDOW_JITTER
bool "Wrap ISO Synchronized Receiver event around overlapping roles"
depends on BT_CTLR_SYNC_ISO && !BT_CTLR_SYNC_ISO_RESERVE_MAX
select BT_TICKER_EXT
help
Wrap ISO Synchronized Receiver event around overlapping roles using
Comment on lines +550 to +555
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I may just be unaware, but what are roles in this context?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

roles / states are defined in BT Spec LINK LAYER STATES section, for example central peripheral are the two roles in connection state.

ticker ticks_slot_window feature with jitter in window.
LLL implementation can use the ticks_drifts value to determine the
correct subevents to setup for reception.

config BT_CTLR_ADV_ENABLE_STRICT
bool "Enforce Strict Advertising Enable/Disable"
depends on BT_BROADCASTER
Expand Down Expand Up @@ -749,6 +766,19 @@ config BT_CTLR_CENTRAL_RESERVE_MAX
Note, currently this value is only used to space multiple central
connections and not for actual ticker time reservations.

config BT_CTLR_PERIPHERAL_RESERVE_MAX
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be placed next to BT_CTLR_PERIPHERAL_ISO_EARLY_CIG_START to group the BT_CTLR_PERIPHERAL* configs?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, that is peripheral ISO related. Where as this new one is related to normal peripheral ACL scheduling.

bool "Use maximum data PDU size time reservation for Peripheral"
depends on BT_PERIPHERAL
default y
help
Use the maximum data PDU size time reservation considering the Data
length could be updated from default 27 bytes to maximum support size.

If maximum time reservation is disabled then time reservation required
for empty PDU transmission is used. Overlapping radio events will use
the is_abort_cb mechanism to decide on continuation of the connection
event.

config BT_CTLR_EVENT_OVERHEAD_RESERVE_MAX
bool "Reserve maximum event overhead in time reservations"
default y
Expand Down
4 changes: 4 additions & 0 deletions subsys/bluetooth/controller/ll_sw/lll.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,9 @@

struct lll_prepare_param {
uint32_t ticks_at_expire;
#if defined(CONFIG_BT_CTLR_SYNC_ISO_SLOT_WINDOW_JITTER)
uint32_t ticks_drift;
#endif /* CONFIG_BT_CTLR_SYNC_ISO_SLOT_WINDOW_JITTER */
uint32_t remainder;
uint16_t lazy;
#if defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
Expand Down Expand Up @@ -505,7 +508,8 @@
struct {
uint16_t trx_cnt;
uint8_t crc_valid:1;
uint8_t is_aborted:1;
#if defined(CONFIG_BT_CTLR_SYNC_ISO)

Check notice on line 512 in subsys/bluetooth/controller/ll_sw/lll.h

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

subsys/bluetooth/controller/ll_sw/lll.h:512 - uint8_t is_aborted:1; + uint8_t is_aborted: 1;
uint8_t estab_failed:1;
#endif /* CONFIG_BT_CTLR_SYNC_ISO */
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING) && \
Expand Down
11 changes: 11 additions & 0 deletions subsys/bluetooth/controller/ll_sw/lll_conn.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
uint16_t latency;

uint16_t latency_prepare;
uint16_t lazy_prepare;
uint16_t latency_event;
uint16_t event_counter;

Expand All @@ -69,12 +70,21 @@
struct {
uint8_t initiated:1;
uint8_t cancelled:1;
uint8_t forced:1;
};

struct {
uint8_t initiated:1;
uint8_t cancelled:1;
uint8_t forced:1;
} central;
Comment on lines 70 to 80
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the difference between these 2 structs now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unnamed struct is now used by a common code block and hence did not want to have a named reference as central or peripheral.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest to put that in a comment, as that is non-obvious. Looks more like a merge conflict gone wrong :P


#if defined(CONFIG_BT_PERIPHERAL)
struct {
uint8_t initiated:1;
uint8_t cancelled:1;
uint8_t forced:1;
uint8_t latency_enabled:1;

Check notice on line 87 in subsys/bluetooth/controller/ll_sw/lll_conn.h

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

subsys/bluetooth/controller/ll_sw/lll_conn.h:87 - uint8_t forced:1; + uint8_t forced: 1; }; struct { - uint8_t initiated:1; - uint8_t cancelled:1; - uint8_t forced:1; + uint8_t initiated: 1; + uint8_t cancelled: 1; + uint8_t forced: 1; } central; #if defined(CONFIG_BT_PERIPHERAL) struct { uint8_t initiated:1; uint8_t cancelled:1; - uint8_t forced:1; + uint8_t forced: 1;

uint32_t window_widening_periodic_us;
uint32_t window_widening_max_us;
Expand Down Expand Up @@ -160,6 +170,7 @@
void lll_conn_flush(uint16_t handle, struct lll_conn *lll);

void lll_conn_prepare_reset(void);
int lll_conn_is_abort_cb(void *next, void *curr, lll_prepare_cb_t *resume_cb);
void lll_conn_abort_cb(struct lll_prepare_param *prepare_param, void *param);
void lll_conn_isr_rx(void *param);
void lll_conn_isr_tx(void *param);
Expand Down
1 change: 1 addition & 0 deletions subsys/bluetooth/controller/ll_sw/lll_conn_iso.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ struct lll_conn_iso_group {

/* Accumulates LLL prepare callback latencies */
uint16_t latency_prepare;
uint16_t lazy_prepare;
uint16_t latency_event;

#if defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
Expand Down
2 changes: 2 additions & 0 deletions subsys/bluetooth/controller/ll_sw/lll_sync.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
uint8_t filter_policy:1;
uint8_t is_rx_enabled:1;
uint8_t is_aux_sched:1;
uint8_t forced:1;

Check notice on line 31 in subsys/bluetooth/controller/ll_sw/lll_sync.h

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

subsys/bluetooth/controller/ll_sw/lll_sync.h:31 - uint8_t forced:1; + uint8_t forced: 1;
#if defined(CONFIG_BT_CTLR_SYNC_ISO)
uint8_t sca:3;
#endif /* CONFIG_BT_CTLR_SYNC_ISO */
Expand All @@ -41,6 +42,7 @@
#endif /* CONFIG_BT_CTLR_SCAN_AUX_SYNC_RESERVE_MIN */

uint16_t skip_prepare;
uint16_t lazy_prepare;
uint16_t skip_event;
uint16_t event_counter;

Expand Down
2 changes: 2 additions & 0 deletions subsys/bluetooth/controller/ll_sw/lll_sync_iso.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@
uint8_t chm_chan_map[PDU_CHANNEL_MAP_SIZE];
uint8_t chm_chan_count:6;

uint8_t is_lll_resume:1;

Check notice on line 71 in subsys/bluetooth/controller/ll_sw/lll_sync_iso.h

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

subsys/bluetooth/controller/ll_sw/lll_sync_iso.h:71 - uint8_t is_lll_resume:1; + uint8_t is_lll_resume: 1;
uint8_t term_reason;

uint16_t ctrl_instant;
Expand Down
38 changes: 36 additions & 2 deletions subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@
static struct {
struct {
void *param;
uint32_t ticks_at_expire;
lll_is_abort_cb_t is_abort_cb;

Check notice on line 49 in subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c:49 - uint32_t ticks_at_expire; + uint32_t ticks_at_expire;
lll_abort_cb_t abort_cb;
} curr;

Expand Down Expand Up @@ -882,6 +883,7 @@
LL_ASSERT(!ready || &ready->prepare_param == prepare_param);

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

Expand Down Expand Up @@ -962,6 +964,8 @@
prepare_param.param = event.curr.param;
event.curr.param = NULL;

prepare_param.ticks_at_expire = event.curr.ticks_at_expire;

return ull_prepare_enqueue(event.curr.is_abort_cb, event.curr.abort_cb,
&prepare_param, resume_cb, 1);
}
Expand Down Expand Up @@ -1235,15 +1239,45 @@
}

/* Check if current event want to continue */
err = event.curr.is_abort_cb(ready->prepare_param.param, event.curr.param, &resume_cb);
err = event.curr.is_abort_cb(ready->prepare_param.param,
event.curr.param, &resume_cb);
if (!err) {
/* Let preemptor LLL know about the cancelled prepare */
/* Do not need to ask same event wants to continue */
if (event.curr.param != ready->prepare_param.param) {
/* Check if ready event want to continue */
err = ready->is_abort_cb(NULL,
ready->prepare_param.param,
&resume_cb);
if (!err) {

Check notice on line 1251 in subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c:1251 - err = event.curr.is_abort_cb(ready->prepare_param.param, - event.curr.param, &resume_cb); + err = event.curr.is_abort_cb(ready->prepare_param.param, event.curr.param, &resume_cb); if (!err) { /* Do not need to ask same event wants to continue */ if (event.curr.param != ready->prepare_param.param) { /* Check if ready event want to continue */ - err = ready->is_abort_cb(NULL, - ready->prepare_param.param, - &resume_cb); + err = ready->is_abort_cb(NULL, ready->prepare_param.param, &resume_cb);
err = -ECANCELED;

goto preempt_cancel_curr;
}
}

/* Let the prepare be dequeued from the pipeline */
ready->is_aborted = 1;

/* Check if resume requested */
if (err == -EAGAIN) {
struct lll_event *next;

next = ull_prepare_enqueue(ready->is_abort_cb,
ready->abort_cb,
&ready->prepare_param,
resume_cb, 1U);
LL_ASSERT(next);

Check notice on line 1269 in subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c:1269 - next = ull_prepare_enqueue(ready->is_abort_cb, - ready->abort_cb, - &ready->prepare_param, - resume_cb, 1U); + next = ull_prepare_enqueue(ready->is_abort_cb, ready->abort_cb, + &ready->prepare_param, resume_cb, 1U);

return;
}

/* Let preemptor LLL know about the cancelled prepare */
ready->abort_cb(&ready->prepare_param, ready->prepare_param.param);

return;
}

preempt_cancel_curr:
/* Abort the current event */
event.curr.abort_cb(NULL, event.curr.param);

Expand Down
9 changes: 8 additions & 1 deletion subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1086,8 +1086,15 @@ static int resume_prepare_cb(struct lll_prepare_param *p)
static int is_abort_cb(void *next, void *curr, lll_prepare_cb_t *resume_cb)
{
#if defined(CONFIG_BT_PERIPHERAL)
struct lll_adv *lll = curr;
struct lll_adv *lll;
struct pdu_adv *pdu;

/* Prepare being cancelled (no resume for directed adv) */
if (!next) {
return -ECANCELED;
}

lll = curr;
#endif /* CONFIG_BT_PERIPHERAL */

/* TODO: prio check */
Expand Down
3 changes: 2 additions & 1 deletion subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ static int prepare_cb(struct lll_prepare_param *p)
lll_conn_prepare_reset();

/* Calculate the current event latency */
lll->latency_event = lll->latency_prepare + p->lazy;
lll->lazy_prepare = p->lazy;
lll->latency_event = lll->latency_prepare + lll->lazy_prepare;

/* Calculate the current event counter value */
event_counter = lll->event_counter + lll->latency_event;
Expand Down
47 changes: 45 additions & 2 deletions subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@

static uint8_t crc_expire;
static uint8_t crc_valid;
static uint8_t is_aborted;
static uint16_t trx_cnt;

#if defined(CONFIG_BT_CTLR_LE_ENC)
Expand Down Expand Up @@ -142,12 +143,25 @@
trx_cnt = 0U;
crc_valid = 0U;
crc_expire = 0U;
is_aborted = 0U;

#if defined(CONFIG_BT_CTLR_LE_ENC)
mic_state = LLL_CONN_MIC_NONE;
#endif /* CONFIG_BT_CTLR_LE_ENC */
}

int lll_conn_is_abort_cb(void *next, void *curr, lll_prepare_cb_t *resume_cb)
{
struct lll_conn *lll = curr;

/* Do not abort if near supervision timeout */
if (lll->forced) {
return 0;
}

return -ECANCELED;
}

void lll_conn_abort_cb(struct lll_prepare_param *prepare_param, void *param)
{
struct event_done_extra *e;
Expand All @@ -156,6 +170,17 @@

/* NOTE: This is not a prepare being cancelled */
if (!prepare_param) {
/* Get reference to LLL connection context */
lll = param;

/* For a peripheral role, ensure at least one PDU is tx-ed
* back to central, otherwise let the supervision timeout
* countdown be started.
*/
if (lll->role && (trx_cnt <= 1U)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If role is a specific value so that role == 0 == central and role == 1 == peripheral, then please make the role check more explicit.

Suggested change
if (lll->role && (trx_cnt <= 1U)) {
if (lll->role == BT_HCI_ROLE_PERIPHERAL && (trx_cnt <= 1U)) {

The above assumes that the role field uses the HCI roles

is_aborted = 1U;
}

/* Perform event abort here.
* After event has been cleanly aborted, clean up resources
* and dispatch event done.
Expand All @@ -171,9 +196,26 @@
err = lll_hfclock_off();
LL_ASSERT(err >= 0);

/* Accumulate the latency as event is aborted while being in pipeline */
/* Get reference to LLL connection context */
lll = prepare_param->param;
lll->latency_prepare += (prepare_param->lazy + 1);

/* Accumulate the latency as event is aborted while being in pipeline */
lll->lazy_prepare = prepare_param->lazy;
lll->latency_prepare += (lll->lazy_prepare + 1U);

#if defined(CONFIG_BT_PERIPHERAL)
if (lll->role) {
/* Accumulate window widening */
lll->periph.window_widening_prepare_us +=
lll->periph.window_widening_periodic_us *
(prepare_param->lazy + 1);
if (lll->periph.window_widening_prepare_us >
lll->periph.window_widening_max_us) {
lll->periph.window_widening_prepare_us =
lll->periph.window_widening_max_us;
}

Check notice on line 216 in subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c:216 - lll->periph.window_widening_periodic_us * - (prepare_param->lazy + 1); - if (lll->periph.window_widening_prepare_us > - lll->periph.window_widening_max_us) { - lll->periph.window_widening_prepare_us = - lll->periph.window_widening_max_us; + lll->periph.window_widening_periodic_us * (prepare_param->lazy + 1); + if (lll->periph.window_widening_prepare_us > lll->periph.window_widening_max_us) { + lll->periph.window_widening_prepare_us = lll->periph.window_widening_max_us;
}
#endif /* CONFIG_BT_PERIPHERAL */

/* Extra done event, to check supervision timeout */
e = ull_event_done_extra_get();
Expand Down Expand Up @@ -867,6 +909,7 @@
e->type = EVENT_DONE_EXTRA_TYPE_CONN;
e->trx_cnt = trx_cnt;
e->crc_valid = crc_valid;
e->is_aborted = is_aborted;

#if defined(CONFIG_BT_CTLR_LE_ENC)
e->mic_state = mic_state;
Expand Down
24 changes: 13 additions & 11 deletions subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,18 +79,10 @@

lll = p->param;

/* Accumulate window widening */
lll->periph.window_widening_prepare_us +=
lll->periph.window_widening_periodic_us * (p->lazy + 1);
if (lll->periph.window_widening_prepare_us >
lll->periph.window_widening_max_us) {
lll->periph.window_widening_prepare_us =
lll->periph.window_widening_max_us;
}

/* Invoke common pipeline handling of prepare */
err = lll_prepare(lll_is_abort_cb, lll_conn_abort_cb, prepare_cb, 0, p);
err = lll_prepare(lll_conn_is_abort_cb, lll_conn_abort_cb, prepare_cb,
0U, p);
LL_ASSERT(!err || err == -EINPROGRESS);

Check notice on line 85 in subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral.c:85 - err = lll_prepare(lll_conn_is_abort_cb, lll_conn_abort_cb, prepare_cb, - 0U, p); + err = lll_prepare(lll_conn_is_abort_cb, lll_conn_abort_cb, prepare_cb, 0U, p);
}

static int init_reset(void)
Expand Down Expand Up @@ -132,7 +124,8 @@
lll_conn_prepare_reset();

/* Calculate the current event latency */
lll->latency_event = lll->latency_prepare + p->lazy;
lll->lazy_prepare = p->lazy;
lll->latency_event = lll->latency_prepare + lll->lazy_prepare;

/* Calculate the current event counter value */
event_counter = lll->event_counter + lll->latency_event;
Expand Down Expand Up @@ -160,6 +153,15 @@
lll->data_chan_count);
}

/* Accumulate window widening */
lll->periph.window_widening_prepare_us +=
lll->periph.window_widening_periodic_us * (lll->lazy_prepare + 1U);
if (lll->periph.window_widening_prepare_us >
lll->periph.window_widening_max_us) {
lll->periph.window_widening_prepare_us =
lll->periph.window_widening_max_us;
}

Check notice on line 163 in subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral.c:163 - lll->periph.window_widening_periodic_us * (lll->lazy_prepare + 1U); - if (lll->periph.window_widening_prepare_us > - lll->periph.window_widening_max_us) { - lll->periph.window_widening_prepare_us = - lll->periph.window_widening_max_us; + lll->periph.window_widening_periodic_us * (lll->lazy_prepare + 1U); + if (lll->periph.window_widening_prepare_us > lll->periph.window_widening_max_us) { + lll->periph.window_widening_prepare_us = lll->periph.window_widening_max_us;

/* current window widening */
lll->periph.window_widening_event_us +=
lll->periph.window_widening_prepare_us;
Expand Down
Loading
Loading