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:
committed by
Anas Nashif
parent
e6ea5644b3
commit
e3e410aeed
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user