Bluetooth: Controller: Fix LLCP event_counter value used during prepare

Fix LLCP to use event_counter value used during prepare to
compare instant to be the value as when in prepare and not
incorrectly use a stale value (when two radio events
overlap).

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
Vinayak Kariappa Chettimada
2025-07-05 18:34:13 +02:00
committed by Anas Nashif
parent e6ea5644b3
commit e3e410aeed
6 changed files with 46 additions and 16 deletions

View File

@@ -2177,6 +2177,11 @@ void ull_conn_resume_rx_data(struct ll_conn *conn)
}
#endif /* CONFIG_BT_CTLR_LE_ENC */
uint16_t ull_conn_event_counter_at_prepare(const struct ll_conn *conn)
{
return conn->lll.event_counter + conn->lll.latency_prepare + conn->llcp.prep.lazy;
}
uint16_t ull_conn_event_counter(struct ll_conn *conn)
{
struct lll_conn *lll;
@@ -2204,6 +2209,7 @@ uint16_t ull_conn_event_counter(struct ll_conn *conn)
return event_counter;
}
static void ull_conn_update_ticker(struct ll_conn *conn,
uint32_t ticks_win_offset,
uint32_t ticks_slot_overhead,
@@ -2281,7 +2287,7 @@ void ull_conn_update_parameters(struct ll_conn *conn, uint8_t is_cu_proc, uint8_
lll = &conn->lll;
/* Calculate current event counter */
event_counter = ull_conn_event_counter(conn);
event_counter = ull_conn_event_counter_at_prepare(conn);
instant_latency = (event_counter - instant) & 0xFFFF;

View File

@@ -84,6 +84,7 @@ static inline void cpr_active_reset(void)
void ull_conn_past_sender_offset_request(struct ll_conn *conn);
#endif /* CONFIG_BT_CTLR_SYNC_TRANSFER_SENDER */
uint16_t ull_conn_event_counter_at_prepare(const struct ll_conn *conn);
uint16_t ull_conn_event_counter(struct ll_conn *conn);
void ull_conn_update_parameters(struct ll_conn *conn, uint8_t is_cu_proc,

View File

@@ -130,8 +130,8 @@ enum {
RP_CC_EVT_UNKNOWN,
};
static void rp_cc_check_instant(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
void *param);
static void rp_cc_check_instant_rx_cis_ind(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
void *param);
/*
* LLCP Remote Procedure FSM
@@ -485,7 +485,7 @@ static void rp_cc_state_wait_rx_cis_ind(struct ll_conn *conn, struct proc_ctx *c
llcp_rx_node_retain(ctx);
/* Check if this connection event is where we need to start the CIS */
rp_cc_check_instant(conn, ctx, evt, param);
rp_cc_check_instant_rx_cis_ind(conn, ctx, evt, param);
break;
}
/* If we get to here the CIG_ID referred in req/acquire has become void/invalid */
@@ -523,13 +523,11 @@ static void rp_cc_state_wait_ntf_avail(struct ll_conn *conn, struct proc_ctx *ct
}
static void rp_cc_check_instant(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
void *param)
static void rp_cc_check_instant_by_counter(struct ll_conn *conn, struct proc_ctx *ctx,
uint16_t event_counter, uint8_t evt, void *param)
{
uint16_t start_event_count;
uint16_t event_counter;
event_counter = ull_conn_event_counter(conn);
start_event_count = ctx->data.cis_create.conn_event_count;
if (is_instant_reached_or_passed(start_event_count, event_counter)) {
@@ -546,6 +544,26 @@ static void rp_cc_check_instant(struct ll_conn *conn, struct proc_ctx *ctx, uint
}
}
static void rp_cc_check_instant(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
void *param)
{
uint16_t event_counter;
event_counter = ull_conn_event_counter_at_prepare(conn);
rp_cc_check_instant_by_counter(conn, ctx, event_counter, evt, param);
}
static void rp_cc_check_instant_rx_cis_ind(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
void *param)
{
uint16_t event_counter;
event_counter = ull_conn_event_counter(conn);
rp_cc_check_instant_by_counter(conn, ctx, event_counter, evt, param);
}
static void rp_cc_state_wait_reply(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
void *param)
{
@@ -1078,7 +1096,7 @@ static void lp_cc_check_instant(struct ll_conn *conn, struct proc_ctx *ctx, uint
uint16_t instant_latency;
uint16_t event_counter;
event_counter = ull_conn_event_counter(conn);
event_counter = ull_conn_event_counter_at_prepare(conn);
start_event_count = ctx->data.cis_create.conn_event_count;
instant_latency = (event_counter - start_event_count) & 0xffff;

View File

@@ -118,7 +118,8 @@ static void lp_chmu_send_channel_map_update_ind(struct ll_conn *conn, struct pro
} else {
llcp_rr_set_incompat(conn, INCOMPAT_RESOLVABLE);
ctx->data.chmu.instant = ull_conn_event_counter(conn) + CHMU_INSTANT_DELTA;
ctx->data.chmu.instant = ull_conn_event_counter(conn) + conn->lll.latency +
CHMU_INSTANT_DELTA;
lp_chmu_tx(conn, ctx);
@@ -142,7 +143,7 @@ static void lp_chmu_st_wait_tx_chan_map_ind(struct ll_conn *conn, struct proc_ct
static void lp_chmu_check_instant(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
void *param)
{
uint16_t event_counter = ull_conn_event_counter(conn);
uint16_t event_counter = ull_conn_event_counter_at_prepare(conn);
if (is_instant_reached_or_passed(ctx->data.chmu.instant, event_counter)) {
llcp_rr_set_incompat(conn, INCOMPAT_NO_COLLISION);
@@ -257,7 +258,7 @@ static void rp_chmu_st_wait_rx_channel_map_update_ind(struct ll_conn *conn, stru
static void rp_chmu_check_instant(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
void *param)
{
uint16_t event_counter = ull_conn_event_counter(conn);
uint16_t event_counter = ull_conn_event_counter_at_prepare(conn);
if (((event_counter - ctx->data.chmu.instant) & 0xFFFF) <= 0x7FFF) {
rp_chmu_complete(conn, ctx, evt, param);

View File

@@ -637,7 +637,7 @@ static void lp_cu_st_wait_rx_conn_update_ind(struct ll_conn *conn, struct proc_c
static void lp_cu_check_instant(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
void *param)
{
uint16_t event_counter = ull_conn_event_counter(conn);
uint16_t event_counter = ull_conn_event_counter_at_prepare(conn);
if (is_instant_reached_or_passed(ctx->data.cu.instant, event_counter)) {
bool notify;
@@ -1222,7 +1222,7 @@ static void rp_cu_st_wait_tx_conn_update_ind(struct ll_conn *conn, struct proc_c
static void rp_cu_check_instant(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
void *param)
{
uint16_t event_counter = ull_conn_event_counter(conn);
uint16_t event_counter = ull_conn_event_counter_at_prepare(conn);
if (is_instant_reached_or_passed(ctx->data.cu.instant, event_counter)) {
bool notify;

View File

@@ -770,7 +770,9 @@ static void lp_pu_st_wait_rx_phy_update_ind(struct ll_conn *conn, struct proc_ct
static void lp_pu_check_instant(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
void *param)
{
if (is_instant_reached_or_passed(ctx->data.pu.instant, ull_conn_event_counter(conn))) {
uint16_t event_counter = ull_conn_event_counter_at_prepare(conn);
if (is_instant_reached_or_passed(ctx->data.pu.instant, event_counter)) {
const uint8_t phy_changed = pu_apply_phy_update(conn, ctx);
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
if (phy_changed) {
@@ -1191,7 +1193,9 @@ static void rp_pu_st_wait_rx_phy_update_ind(struct ll_conn *conn, struct proc_ct
static void rp_pu_check_instant(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
void *param)
{
if (is_instant_reached_or_passed(ctx->data.pu.instant, ull_conn_event_counter(conn))) {
uint16_t event_counter = ull_conn_event_counter_at_prepare(conn);
if (is_instant_reached_or_passed(ctx->data.pu.instant, event_counter)) {
ctx->data.pu.error = BT_HCI_ERR_SUCCESS;
const uint8_t phy_changed = pu_apply_phy_update(conn, ctx);
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)