From df0150a16f2c4599189bbb3598c132c460ffda25 Mon Sep 17 00:00:00 2001 From: Luo Xu Date: Fri, 19 Dec 2025 13:43:29 +0800 Subject: [PATCH 1/3] fix(ble_mesh): Fix start callback timing when GATT and ADV bearers coexist Add BLE_MESH_SEND_START_CB macro to ensure start callback is called exactly once when both GATT and ADV bearers are used. (cherry picked from commit 48a84e82993b16e2018078af14302eac08451f34) Co-authored-by: luoxu --- components/bt/esp_ble_mesh/core/adv.c | 8 +++-- components/bt/esp_ble_mesh/core/adv_common.h | 34 +++++++++++--------- components/bt/esp_ble_mesh/core/ext_adv.c | 6 ++-- components/bt/esp_ble_mesh/core/net.c | 13 ++++++-- 4 files changed, 38 insertions(+), 23 deletions(-) diff --git a/components/bt/esp_ble_mesh/core/adv.c b/components/bt/esp_ble_mesh/core/adv.c index 9a12e8c125..e35d34c993 100644 --- a/components/bt/esp_ble_mesh/core/adv.c +++ b/components/bt/esp_ble_mesh/core/adv.c @@ -42,6 +42,7 @@ static int adv_send(struct net_buf *buf) uint8_t adv_cnt = 0; struct bt_mesh_adv_data ad = {0}; int err = 0; + bool start_cb_called = (BLE_MESH_ADV(buf)->flags & BLE_MESH_ADV_FLAG_SKIP_START_CB); BT_DBG("LegacyAdvSend, Type %u", BLE_MESH_ADV(buf)->type); BT_DBG("Len %u: %s", buf->len, bt_hex(buf->data, buf->len)); @@ -175,7 +176,10 @@ static int adv_send(struct net_buf *buf) net_buf_unref(buf); - adv_send_start(duration, err, cb, cb_data); + if (!start_cb_called && cb && cb->start) { + cb->start(duration, err, cb_data); + } + if (err) { BT_ERR("Start advertising failed: err %d", err); return err; @@ -194,7 +198,7 @@ static int adv_send(struct net_buf *buf) err = bt_le_adv_stop(); #endif /* CONFIG_BLE_MESH_USE_BLE_50 */ - adv_send_end(err, cb, cb_data); + BLE_MESH_SEND_END_CB(err, cb, cb_data); if (err) { BT_ERR("Stop advertising failed: err %d", err); return 0; diff --git a/components/bt/esp_ble_mesh/core/adv_common.h b/components/bt/esp_ble_mesh/core/adv_common.h index 54267ee522..d7810c94d0 100644 --- a/components/bt/esp_ble_mesh/core/adv_common.h +++ b/components/bt/esp_ble_mesh/core/adv_common.h @@ -48,6 +48,9 @@ extern "C" { #define BLE_MESH_ADV_INST_UNUSED 0xFF +/* Flags for struct bt_mesh_adv */ +#define BLE_MESH_ADV_FLAG_SKIP_START_CB BIT(0) /* Skip start callback (already called by GATT) */ + struct bt_mesh_adv { const struct bt_mesh_send_cb *cb; void *cb_data; @@ -61,6 +64,7 @@ struct bt_mesh_adv { uint32_t adv_itvl; uint8_t adv_cnt; uint8_t channel_map; + uint8_t flags; /* See BLE_MESH_ADV_FLAG_* */ }; #if CONFIG_BLE_MESH_USE_BLE_50 @@ -214,22 +218,22 @@ static inline TickType_t K_WAIT(int32_t val) return (val == K_FOREVER) ? portMAX_DELAY : (val / portTICK_PERIOD_MS); } -static inline void adv_send_start(uint16_t duration, int err, - const struct bt_mesh_send_cb *cb, - void *cb_data) -{ - if (cb && cb->start) { - cb->start(duration, err, cb_data); - } -} +#define BLE_MESH_SEND_START_CB(_buf, _duration, _err, _cb, _cb_data) \ + do { \ + if (!(BLE_MESH_ADV(_buf)->flags & BLE_MESH_ADV_FLAG_SKIP_START_CB)) { \ + if ((_cb) && (_cb)->start) { \ + (_cb)->start((_duration), (_err), (_cb_data)); \ + } \ + BLE_MESH_ADV(_buf)->flags |= BLE_MESH_ADV_FLAG_SKIP_START_CB; \ + } \ + } while (0) -static inline void adv_send_end(int err, const struct bt_mesh_send_cb *cb, - void *cb_data) -{ - if (cb && cb->end) { - cb->end(err, cb_data); - } -} +#define BLE_MESH_SEND_END_CB(_err, _cb, _cb_data) \ + do { \ + if ((_cb) && (_cb)->end) { \ + (_cb)->end((_err), (_cb_data)); \ + } \ + } while (0) struct bt_mesh_adv_queue *bt_mesh_adv_queue_get(void); diff --git a/components/bt/esp_ble_mesh/core/ext_adv.c b/components/bt/esp_ble_mesh/core/ext_adv.c index 8b85076aed..c4feaa7a4e 100644 --- a/components/bt/esp_ble_mesh/core/ext_adv.c +++ b/components/bt/esp_ble_mesh/core/ext_adv.c @@ -181,7 +181,7 @@ static int adv_send(struct bt_mesh_adv_inst *inst, uint16_t *adv_duration) break; } - adv_send_start(duration, err, cb, cb_data); + BLE_MESH_SEND_START_CB(buf, duration, err, cb, cb_data); if (err) { BT_ERR("Start advertising failed: err %d", err); return err; @@ -381,8 +381,8 @@ static uint32_t received_adv_evts_handle(uint32_t recv_evts) } else #endif { - adv_send_end(0, BLE_MESH_ADV(adv_insts[i].sending_buf)->cb, - BLE_MESH_ADV(adv_insts[i].sending_buf)->cb_data); + BLE_MESH_SEND_END_CB(0, BLE_MESH_ADV(adv_insts[i].sending_buf)->cb, + BLE_MESH_ADV(adv_insts[i].sending_buf)->cb_data); bt_mesh_adv_buf_ref_debug(__func__, adv_insts[i].sending_buf, 4U, BLE_MESH_BUF_REF_SMALL); diff --git a/components/bt/esp_ble_mesh/core/net.c b/components/bt/esp_ble_mesh/core/net.c index fde5b5cdda..b436ce5d6b 100644 --- a/components/bt/esp_ble_mesh/core/net.c +++ b/components/bt/esp_ble_mesh/core/net.c @@ -1239,6 +1239,15 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf, send_cb = NULL; goto done; } + + /* GATT bearer sends faster than ADV bearer, so the remote node + * may receive the message and respond before ADV bearer starts. + * To avoid issues where the start callback hasn't been called + * when the response arrives, we call the start callback here + * immediately after GATT bearer sends successfully. The ADV + * bearer will skip start callback since the flag is set. + */ + BLE_MESH_SEND_START_CB(buf, 0, 0, send_cb, cb_data); } } #endif /* CONFIG_BLE_MESH_GATT_PROXY_CLIENT */ @@ -1253,9 +1262,7 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf, * See BLEMESH24-76 for more details. */ if (BLE_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) { - if (send_cb && send_cb->start) { - send_cb->start(0, 0, cb_data); - } + BLE_MESH_SEND_START_CB(buf, 0, 0, send_cb, cb_data); net_buf_slist_put(&bt_mesh.local_queue, net_buf_ref(buf)); From 9ea0f24646046b49fec397def90c72b4ef2442c5 Mon Sep 17 00:00:00 2001 From: Luo Xu Date: Fri, 19 Dec 2025 13:43:29 +0800 Subject: [PATCH 2/3] feat(ble_mesh): update ble mesh multi connections config (cherry picked from commit b63a0c2b78edb8cea296a7160266966b75307456) Co-authored-by: luoxu --- .../esp_ble_mesh/core/include/mesh/adapter.h | 32 ++++++------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/components/bt/esp_ble_mesh/core/include/mesh/adapter.h b/components/bt/esp_ble_mesh/core/include/mesh/adapter.h index 39c359d695..20c656e690 100644 --- a/components/bt/esp_ble_mesh/core/include/mesh/adapter.h +++ b/components/bt/esp_ble_mesh/core/include/mesh/adapter.h @@ -37,21 +37,12 @@ extern "C" { */ #ifdef CONFIG_BT_BLUEDROID_ENABLED #if CONFIG_IDF_TARGET_ESP32 -#define BLE_MESH_MAX_CONN 1 +#define BLE_MESH_MAX_CONN MIN(CONFIG_BT_ACL_CONNECTIONS, CONFIG_BTDM_CTRL_BLE_MAX_CONN) #elif (CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3) -/* @todo: must ensure CONFIG_BT_CTRL_BLE_MAX_ACT is greater than 2 */ -#if CONFIG_BT_ACL_CONNECTIONS > (CONFIG_BT_CTRL_BLE_MAX_ACT - 2) -/* decrease the adv,scan */ -#define BLE_MESH_MAX_CONN (CONFIG_BT_CTRL_BLE_MAX_ACT - 2) -#else -#define BLE_MESH_MAX_CONN CONFIG_BT_ACL_CONNECTIONS -#endif /* CONFIG_BT_ACL_CONNECTIONS > (CONFIG_BT_CTRL_BLE_MAX_ACT - 2) */ -#elif CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C5 -#if CONFIG_BT_ACL_CONNECTIONS > CONFIG_BT_LE_MAX_CONNECTIONS -#define BLE_MESH_MAX_CONN CONFIG_BT_LE_MAX_CONNECTIONS -#else -#define BLE_MESH_MAX_CONN CONFIG_BT_ACL_CONNECTIONS -#endif /* CONFIG_BT_ACL_CONNECTIONS > CONFIG_BT_LE_MAX_CONNECTIONS */ +#define BLE_MESH_MAX_CONN MIN(CONFIG_BT_ACL_CONNECTIONS, (CONFIG_BT_CTRL_BLE_MAX_ACT - 2)) +#elif (CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || \ + CONFIG_IDF_TARGET_ESP32C5 || CONFIG_IDF_TARGET_ESP32C61) +#define BLE_MESH_MAX_CONN MIN(CONFIG_BT_ACL_CONNECTIONS, CONFIG_BT_LE_MAX_CONNECTIONS) #else /* default setting */ #define BLE_MESH_MAX_CONN 1 @@ -60,16 +51,11 @@ extern "C" { #ifdef CONFIG_BT_NIMBLE_ENABLED #if CONFIG_IDF_TARGET_ESP32 -#define BLE_MESH_MAX_CONN 1 +#define BLE_MESH_MAX_CONN MIN(CONFIG_BT_NIMBLE_MAX_CONNECTIONS, CONFIG_BTDM_CTRL_BLE_MAX_CONN) #elif (CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3) -/* @todo: must ensure CONFIG_BT_CTRL_BLE_MAX_ACT is greater than 2 */ -#if CONFIG_BT_NIMBLE_MAX_CONNECTIONS > (CONFIG_BT_CTRL_BLE_MAX_ACT - 2) -/* decrease the adv,scan */ -#define BLE_MESH_MAX_CONN (CONFIG_BT_CTRL_BLE_MAX_ACT - 2) -#else -#define BLE_MESH_MAX_CONN CONFIG_BT_NIMBLE_MAX_CONNECTIONS -#endif /* CONFIG_BT_NIMBLE_MAX_CONNECTIONS > (CONFIG_BT_CTRL_BLE_MAX_ACT - 2) */ -#elif CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C5 +#define BLE_MESH_MAX_CONN MIN(CONFIG_BT_NIMBLE_MAX_CONNECTIONS, (CONFIG_BT_CTRL_BLE_MAX_ACT - 2)) +#elif (CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || \ + CONFIG_IDF_TARGET_ESP32C5 || CONFIG_IDF_TARGET_ESP32C61) #define BLE_MESH_MAX_CONN CONFIG_BT_NIMBLE_MAX_CONNECTIONS #else /* default setting */ From 0d4000caf03c2ff4de484311e0a38347c97cf04c Mon Sep 17 00:00:00 2001 From: Luo Xu Date: Fri, 19 Dec 2025 13:43:29 +0800 Subject: [PATCH 3/3] feat(ble_mesh): fix issues with advtypes (cherry picked from commit 1c4f6045cfeb9d7386f931b8eeda69129e222064) Co-authored-by: luoxu --- components/bt/esp_ble_mesh/core/adv_common.c | 23 +++++++++++++++++++ components/bt/esp_ble_mesh/core/adv_common.h | 24 +------------------- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/components/bt/esp_ble_mesh/core/adv_common.c b/components/bt/esp_ble_mesh/core/adv_common.c index ff4e50ac1c..cd6157e3bc 100644 --- a/components/bt/esp_ble_mesh/core/adv_common.c +++ b/components/bt/esp_ble_mesh/core/adv_common.c @@ -55,6 +55,29 @@ static bt_mesh_ext_adv_t ext_long_relay_adv_pool[CONFIG_BLE_MESH_LONG_PACKET_REL #endif /* CONFIG_BLE_MESH_LONG_PACKET */ #endif /* CONFIG_BLE_MESH_EXT_ADV */ +const uint8_t adv_type[] = { + [BLE_MESH_ADV_PROV] = BLE_MESH_DATA_MESH_PROV, + [BLE_MESH_ADV_DATA] = BLE_MESH_DATA_MESH_MESSAGE, +#if CONFIG_BLE_MESH_EXT_ADV + [BLE_MESH_ADV_EXT_PROV] = BLE_MESH_DATA_MESH_PROV, + [BLE_MESH_ADV_EXT_RELAY_DATA] = BLE_MESH_DATA_MESH_MESSAGE, + [BLE_MESH_ADV_EXT_DATA] = BLE_MESH_DATA_MESH_MESSAGE, +#if CONFIG_BLE_MESH_LONG_PACKET + [BLE_MESH_ADV_EXT_LONG_PROV] = BLE_MESH_DATA_MESH_PROV, + [BLE_MESH_ADV_EXT_LONG_RELAY_DATA] = BLE_MESH_DATA_MESH_MESSAGE, + [BLE_MESH_ADV_EXT_LONG_DATA] = BLE_MESH_DATA_MESH_MESSAGE, +#endif /* CONFIG_BLE_MESH_LONG_PACKET */ +#endif /* CONFIG_BLE_MESH_EXT_ADV */ +#if CONFIG_BLE_MESH_FRIEND + [BLE_MESH_ADV_FRIEND] = BLE_MESH_DATA_MESH_MESSAGE, +#endif +#if CONFIG_BLE_MESH_RELAY_ADV_BUF + [BLE_MESH_ADV_RELAY_DATA] = BLE_MESH_DATA_MESH_MESSAGE, +#endif + [BLE_MESH_ADV_BEACON] = BLE_MESH_DATA_MESH_BEACON, + [BLE_MESH_ADV_URI] = BLE_MESH_DATA_URI, +}; + static inline void init_adv_with_defaults(struct bt_mesh_adv *adv, enum bt_mesh_adv_type type) { diff --git a/components/bt/esp_ble_mesh/core/adv_common.h b/components/bt/esp_ble_mesh/core/adv_common.h index d7810c94d0..c52fc18cc3 100644 --- a/components/bt/esp_ble_mesh/core/adv_common.h +++ b/components/bt/esp_ble_mesh/core/adv_common.h @@ -175,29 +175,7 @@ typedef enum { BLE_MESH_BUF_REF_MAX, } bt_mesh_buf_ref_flag_t; - -static const uint8_t adv_type[] = { - [BLE_MESH_ADV_PROV] = BLE_MESH_DATA_MESH_PROV, - [BLE_MESH_ADV_DATA] = BLE_MESH_DATA_MESH_MESSAGE, -#if CONFIG_BLE_MESH_EXT_ADV - [BLE_MESH_ADV_EXT_PROV] = BLE_MESH_DATA_MESH_PROV, - [BLE_MESH_ADV_EXT_RELAY_DATA] = BLE_MESH_DATA_MESH_MESSAGE, - [BLE_MESH_ADV_EXT_DATA] = BLE_MESH_DATA_MESH_MESSAGE, -#if CONFIG_BLE_MESH_LONG_PACKET - [BLE_MESH_ADV_EXT_LONG_PROV] = BLE_MESH_DATA_MESH_PROV, - [BLE_MESH_ADV_EXT_LONG_RELAY_DATA] = BLE_MESH_DATA_MESH_MESSAGE, - [BLE_MESH_ADV_EXT_LONG_DATA] = BLE_MESH_DATA_MESH_MESSAGE, -#endif /* CONFIG_BLE_MESH_LONG_PACKET */ -#endif /* CONFIG_BLE_MESH_EXT_ADV */ -#if CONFIG_BLE_MESH_FRIEND - [BLE_MESH_ADV_FRIEND] = BLE_MESH_DATA_MESH_MESSAGE, -#endif -#if CONFIG_BLE_MESH_RELAY_ADV_BUF - [BLE_MESH_ADV_RELAY_DATA] = BLE_MESH_DATA_MESH_MESSAGE, -#endif - [BLE_MESH_ADV_BEACON] = BLE_MESH_DATA_MESH_BEACON, - [BLE_MESH_ADV_URI] = BLE_MESH_DATA_URI, -}; +extern const uint8_t adv_type[]; typedef struct bt_mesh_adv *(*bt_mesh_pool_allocator_t)(int id, enum bt_mesh_adv_type type); typedef void (*bt_mesh_adv_queue_send_cb_t)(bt_mesh_msg_t *msg, uint32_t timeout, bool front);