-
Notifications
You must be signed in to change notification settings - Fork 7.6k
Bluetooth: Controller: Fix conn timeout due to delayed conn upd ind #92572
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
base: main
Are you sure you want to change the base?
Changes from all commits
f2e11a6
3b15397
8c72e60
a3347a3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -17,6 +17,10 @@ | |||||||||
static uint32_t phy_update_countdown; | ||||||||||
static uint8_t phy_param_idx; | ||||||||||
|
||||||||||
/* Count down number of metrics intervals before performing a param update */ | ||||||||||
#define PARAM_UPDATE_COUNTDOWN PHY_UPDATE_COUNTDOWN | ||||||||||
Comment on lines
+20
to
+21
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, this feels like even more test code that isn't related to GATT :( Would prefer that we test things like this in BSIM, instead of polluting a GATT sample with PHY tests (personal opinion) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This may not be related to GATT but a typical user application requiring a GATT Write without Response will perform both PHY update and Connection Update to tune the throughput. In that sense, is a sample that demonstrate GATT Write without Response, PHY Update and Connection Update (there are no samples for these procedures currently in the upstream repo!). |
||||||||||
static uint32_t param_update_countdown; | ||||||||||
|
||||||||||
static void phy_update_iterate(struct bt_conn *conn) | ||||||||||
{ | ||||||||||
const struct bt_conn_le_phy_param phy_param[] = { | ||||||||||
|
@@ -178,6 +182,34 @@ static void write_cmd_cb(struct bt_conn *conn, void *user_data) | |||||||||
phy_update_iterate(conn); | ||||||||||
} | ||||||||||
|
||||||||||
const struct bt_le_conn_param update_params[2] = {{ | ||||||||||
.interval_min = 0x0029, | ||||||||||
.interval_max = 0x0029, | ||||||||||
.latency = 0, | ||||||||||
.timeout = 31, | ||||||||||
}, { | ||||||||||
.interval_min = 0x0028, | ||||||||||
.interval_max = 0x0028, | ||||||||||
.latency = 0, | ||||||||||
.timeout = 30, | ||||||||||
Comment on lines
+186
to
+194
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider using the |
||||||||||
}, | ||||||||||
}; | ||||||||||
static uint8_t param_update_count; | ||||||||||
int err; | ||||||||||
|
||||||||||
if ((param_update_countdown--) != 0U) { | ||||||||||
return; | ||||||||||
} | ||||||||||
|
||||||||||
param_update_countdown = PARAM_UPDATE_COUNTDOWN; | ||||||||||
|
||||||||||
err = bt_conn_le_param_update(conn, &update_params[param_update_count & 0x1]); | ||||||||||
Comment on lines
+205
to
+206
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggest to add something like
Suggested change
Given that this is a sample |
||||||||||
if (err != 0) { | ||||||||||
printk("Parameter update failed (err %d)\n", err); | ||||||||||
} | ||||||||||
|
||||||||||
param_update_count++; | ||||||||||
|
||||||||||
} else { | ||||||||||
uint16_t len; | ||||||||||
|
||||||||||
|
@@ -256,6 +288,14 @@ static void connected(struct bt_conn *conn, uint8_t conn_err) | |||||||||
phy_update_countdown = PHY_UPDATE_COUNTDOWN; | ||||||||||
phy_param_idx = 0U; | ||||||||||
} | ||||||||||
|
||||||||||
/* Every 1 second the acknowledged total GATT Write without Response data size is used for | ||||||||||
* the throughput calculation. | ||||||||||
* PHY update is performed in reference to this calculation interval, and connection update | ||||||||||
* is offset by 1 of this interval so that connection update is initiated one such interval | ||||||||||
* after PHY update was requested. | ||||||||||
*/ | ||||||||||
param_update_countdown = PARAM_UPDATE_COUNTDOWN + 1U; | ||||||||||
} | ||||||||||
|
||||||||||
static void disconnected(struct bt_conn *conn, uint8_t reason) | ||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -127,23 +127,18 @@ static uint8_t force_md_cnt_calc(struct lll_conn *lll_conn, uint32_t tx_rate); | |||||||||||||||||||||||||||||||||||||||||||||||
(LL_LENGTH_OCTETS_TX_MAX + \ | ||||||||||||||||||||||||||||||||||||||||||||||||
BT_CTLR_USER_TX_BUFFER_OVERHEAD)) | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
#define CONN_DATA_BUFFERS CONFIG_BT_BUF_ACL_TX_COUNT | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
static MFIFO_DEFINE(conn_tx, sizeof(struct lll_tx), CONN_DATA_BUFFERS); | ||||||||||||||||||||||||||||||||||||||||||||||||
static MFIFO_DEFINE(conn_tx, sizeof(struct lll_tx), CONFIG_BT_BUF_ACL_TX_COUNT); | ||||||||||||||||||||||||||||||||||||||||||||||||
static MFIFO_DEFINE(conn_ack, sizeof(struct lll_tx), | ||||||||||||||||||||||||||||||||||||||||||||||||
(CONN_DATA_BUFFERS + | ||||||||||||||||||||||||||||||||||||||||||||||||
LLCP_TX_CTRL_BUF_COUNT)); | ||||||||||||||||||||||||||||||||||||||||||||||||
(CONFIG_BT_BUF_ACL_TX_COUNT + LLCP_TX_CTRL_BUF_COUNT)); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
static struct { | ||||||||||||||||||||||||||||||||||||||||||||||||
void *free; | ||||||||||||||||||||||||||||||||||||||||||||||||
uint8_t pool[CONN_TX_BUF_SIZE * CONN_DATA_BUFFERS]; | ||||||||||||||||||||||||||||||||||||||||||||||||
uint8_t pool[CONN_TX_BUF_SIZE * CONFIG_BT_BUF_ACL_TX_COUNT]; | ||||||||||||||||||||||||||||||||||||||||||||||||
} mem_conn_tx; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
static struct { | ||||||||||||||||||||||||||||||||||||||||||||||||
void *free; | ||||||||||||||||||||||||||||||||||||||||||||||||
uint8_t pool[sizeof(memq_link_t) * | ||||||||||||||||||||||||||||||||||||||||||||||||
(CONN_DATA_BUFFERS + | ||||||||||||||||||||||||||||||||||||||||||||||||
LLCP_TX_CTRL_BUF_COUNT)]; | ||||||||||||||||||||||||||||||||||||||||||||||||
uint8_t pool[sizeof(memq_link_t) * (CONFIG_BT_BUF_ACL_TX_COUNT + LLCP_TX_CTRL_BUF_COUNT)]; | ||||||||||||||||||||||||||||||||||||||||||||||||
} mem_link_tx; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
#if defined(CONFIG_BT_CTLR_DATA_LENGTH) | ||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -1483,6 +1478,21 @@ void ull_conn_tx_lll_enqueue(struct ll_conn *conn, uint8_t count) | |||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
uint16_t ull_conn_tx_enqueue_count_get(struct ll_conn *conn) | ||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||
uint16_t count = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||
memq_link_t *curr; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
curr = memq_peek(conn->lll.memq_tx.head, conn->lll.memq_tx.tail, NULL); | ||||||||||||||||||||||||||||||||||||||||||||||||
while (curr != NULL) { | ||||||||||||||||||||||||||||||||||||||||||||||||
count++; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
curr = memq_peek(curr->next, conn->lll.memq_tx.tail, NULL); | ||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
return count; | ||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
1478
to
+1493
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function iterates through the entire TX queue on each call (O(n) complexity); consider maintaining a counter that tracks the queue length to avoid walking the list every time.
Suggested change
Copilot uses AI. Check for mistakes. Positive FeedbackNegative Feedback |
||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
void ull_conn_link_tx_release(void *link) | ||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||
mem_release(link, &mem_link_tx.free); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -1693,14 +1703,11 @@ static int init_reset(void) | |||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
/* Initialize tx pool. */ | ||||||||||||||||||||||||||||||||||||||||||||||||
mem_init(mem_conn_tx.pool, CONN_TX_BUF_SIZE, CONN_DATA_BUFFERS, | ||||||||||||||||||||||||||||||||||||||||||||||||
&mem_conn_tx.free); | ||||||||||||||||||||||||||||||||||||||||||||||||
mem_init(mem_conn_tx.pool, CONN_TX_BUF_SIZE, CONFIG_BT_BUF_ACL_TX_COUNT, &mem_conn_tx.free); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
/* Initialize tx link pool. */ | ||||||||||||||||||||||||||||||||||||||||||||||||
mem_init(mem_link_tx.pool, sizeof(memq_link_t), | ||||||||||||||||||||||||||||||||||||||||||||||||
(CONN_DATA_BUFFERS + | ||||||||||||||||||||||||||||||||||||||||||||||||
LLCP_TX_CTRL_BUF_COUNT), | ||||||||||||||||||||||||||||||||||||||||||||||||
&mem_link_tx.free); | ||||||||||||||||||||||||||||||||||||||||||||||||
(CONFIG_BT_BUF_ACL_TX_COUNT + LLCP_TX_CTRL_BUF_COUNT), &mem_link_tx.free); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
/* Initialize control procedure system. */ | ||||||||||||||||||||||||||||||||||||||||||||||||
ull_cp_init(); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -438,7 +438,9 @@ static void lp_cu_send_conn_update_ind_finalize(struct ll_conn *conn, struct pro | |||
static void lp_cu_send_conn_update_ind(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, | ||||
void *param) | ||||
{ | ||||
if (llcp_lr_ispaused(conn) || !llcp_tx_alloc_peek(conn, ctx)) { | ||||
if (llcp_lr_ispaused(conn) || !llcp_tx_alloc_peek(conn, ctx) || | ||||
ull_conn_tx_enqueue_count_get(conn) != 0U) { | ||||
llcp_tx_pause_data(conn, LLCP_TX_QUEUE_PAUSE_DATA_CONN_UPD); | ||||
ctx->state = LP_CU_STATE_WAIT_TX_CONN_UPDATE_IND; | ||||
} else { | ||||
/* ensure alloc of TX node, before possibly waiting for NTF node */ | ||||
|
@@ -448,6 +450,7 @@ static void lp_cu_send_conn_update_ind(struct ll_conn *conn, struct proc_ctx *ct | |||
ctx->state = LP_CU_STATE_WAIT_NTF_AVAIL; | ||||
} else { | ||||
lp_cu_send_conn_update_ind_finalize(conn, ctx, evt, param); | ||||
llcp_tx_resume_data(conn, LLCP_TX_QUEUE_PAUSE_DATA_CONN_UPD); | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [nitpick] The resume call is duplicated in multiple branches; consider centralizing resume logic (e.g., in
Suggested change
Copilot uses AI. Check for mistakes. Positive FeedbackNegative Feedback |
||||
} | ||||
} | ||||
} | ||||
|
@@ -459,6 +462,7 @@ static void lp_cu_st_wait_ntf_avail(struct ll_conn *conn, struct proc_ctx *ctx, | |||
case LP_CU_EVT_RUN: | ||||
if (llcp_ntf_alloc_is_available()) { | ||||
lp_cu_send_conn_update_ind_finalize(conn, ctx, evt, param); | ||||
llcp_tx_resume_data(conn, LLCP_TX_QUEUE_PAUSE_DATA_CONN_UPD); | ||||
} | ||||
break; | ||||
default: | ||||
|
Uh oh!
There was an error while loading. Please reload this page.