fix(nimble): Fix issues found in review for nimble examples

This commit is contained in:
Rahul Tank
2026-07-24 17:50:29 +08:00
committed by BOT
parent 99b87ca81f
commit fa1bf5e2fc
73 changed files with 1299 additions and 635 deletions
@@ -22,7 +22,7 @@
static const char *TAG = "l2cap_coc_cent";
#define L2CAP_COC_PSM 0x1002
#define L2CAP_COC_PSM 0x0080 /* valid dynamic LE L2CAP CoC PSM (0x0080-0x00FF) */
#define L2CAP_COC_MTU CONFIG_EXAMPLE_L2CAP_COC_MTU
#define COC_BUF_COUNT (6 * MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM))
/* Block size must include mbuf headers so each SDU fits in one pool entry. */
@@ -130,12 +130,9 @@ static void cent_l2cap_coc_connect(uint16_t conn_handle)
if (rc != 0) {
ESP_LOGE(TAG, "L2CAP COC connect failed; rc=%d", rc);
l2cap_connecting = false;
/* EINVAL: NimBLE returns before chan alloc, sdu_rx not consumed — free it.
* ENOTCONN: NimBLE frees sdu_rx on all ENOTCONN paths (early !conn check
* and late TX failure via ble_l2cap_coc_cleanup_chan). Do not free here. */
if (rc == BLE_HS_EINVAL) {
os_mbuf_free_chain(sdu_rx);
}
/* NimBLE takes ownership of sdu_rx on ALL error paths from ble_l2cap_connect
* (freed via ble_l2cap_chan_free → ble_l2cap_coc_cleanup_chan or directly in
* ble_l2cap_sig_coc_connect validation). Never free here to avoid double-free. */
}
}
@@ -713,6 +710,8 @@ void app_main(void)
ret = nimble_port_init();
if (ret != ESP_OK) {
ESP_LOGE(TAG, "nimble_port_init failed; rc=%d", ret);
vEventGroupDelete(coc_event_group);
coc_event_group = NULL;
return;
}
@@ -731,6 +730,9 @@ void app_main(void)
if (xTaskCreate(cent_send_task, "cent_send_task", 4096, NULL, 5, NULL) != pdPASS) {
ESP_LOGE(TAG, "Failed to create cent_send_task");
nimble_port_deinit();
vEventGroupDelete(coc_event_group);
coc_event_group = NULL;
return;
}
@@ -20,7 +20,7 @@
static const char *TAG = "l2cap_coc_prph";
#define L2CAP_COC_PSM 0x1002
#define L2CAP_COC_PSM 0x0080 /* valid dynamic LE L2CAP CoC PSM (0x0080-0x00FF) */
#define L2CAP_COC_MTU CONFIG_EXAMPLE_L2CAP_COC_MTU
#define COC_BUF_COUNT (6 * MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM))
/* Block size must include mbuf headers so each SDU fits in one pool entry. */
@@ -149,7 +149,11 @@ static void prph_advertise(void)
fields.name_len = strlen(name);
fields.name_is_complete = 1;
#endif
fields.uuids16 = (ble_uuid16_t[]){ BLE_UUID16_INIT(L2CAP_COC_UUID) };
/* Must be static: ble_gap_adv_set_fields copies the pointer, not the data.
* A stack compound literal becomes dangling after prph_advertise returns,
* causing corruption when BLE_NIMBLE_ENABLE_CONN_REATTEMPT re-uses the pointer. */
static const ble_uuid16_t adv_uuids16[] = { BLE_UUID16_INIT(L2CAP_COC_UUID) };
fields.uuids16 = adv_uuids16;
fields.num_uuids16 = 1;
fields.uuids16_is_complete = 1;
@@ -188,7 +192,11 @@ static int prph_l2cap_coc_accept(struct ble_l2cap_chan *chan)
return BLE_HS_ENOMEM;
}
int rc = ble_l2cap_recv_ready(chan, sdu_rx);
if (rc != 0) {
/* ble_l2cap_coc_recv_ready stores sdu_rx AFTER the BLE_HS_EBUSY check but
* BEFORE the BLE_HS_ENOENT check. On BLE_HS_EBUSY the buffer was never
* stored and must be freed here; on success or BLE_HS_ENOENT the buffer is
* owned by chan->coc_rx.sdus[] and freed by ble_l2cap_coc_cleanup_chan. */
if (rc != 0 && rc != BLE_HS_ENOENT) {
os_mbuf_free_chain(sdu_rx);
}
return rc;