From d680a3949ba5c8f3f65959196d9264e7302d28cf Mon Sep 17 00:00:00 2001 From: Liu Linyan Date: Fri, 10 Nov 2023 10:54:17 +0800 Subject: [PATCH] fix(ble_mesh): Support using random adv interval for mesh packets --- components/bt/esp_ble_mesh/Kconfig.in | 8 +++++ components/bt/esp_ble_mesh/common/common.c | 5 +++ .../esp_ble_mesh/common/include/mesh/common.h | 2 ++ .../core/bluedroid_host/adapter.c | 18 ++++++++++- .../esp_ble_mesh/core/nimble_host/adapter.c | 31 +++++++++++++++---- 5 files changed, 57 insertions(+), 7 deletions(-) diff --git a/components/bt/esp_ble_mesh/Kconfig.in b/components/bt/esp_ble_mesh/Kconfig.in index af76b2240d..6b689ef3ea 100644 --- a/components/bt/esp_ble_mesh/Kconfig.in +++ b/components/bt/esp_ble_mesh/Kconfig.in @@ -6,6 +6,14 @@ if BLE_MESH help It is a temporary solution and needs further modifications. + config BLE_MESH_RANDOM_ADV_INTERVAL + bool "Support using random adv interval for mesh packets" + default n + help + Enable this option to allow using random advertising interval + for mesh packets. And this could help avoid collision of + advertising packets. + config BLE_MESH_USE_DUPLICATE_SCAN bool "Support Duplicate Scan in BLE Mesh" select BTDM_BLE_SCAN_DUPL if IDF_TARGET_ESP32 diff --git a/components/bt/esp_ble_mesh/common/common.c b/components/bt/esp_ble_mesh/common/common.c index 87f0c6a7bc..7257db930c 100644 --- a/components/bt/esp_ble_mesh/common/common.c +++ b/components/bt/esp_ble_mesh/common/common.c @@ -85,3 +85,8 @@ int bt_mesh_rand(void *buf, size_t len) return 0; } + +uint32_t bt_mesh_get_rand(void) +{ + return esp_random(); +} diff --git a/components/bt/esp_ble_mesh/common/include/mesh/common.h b/components/bt/esp_ble_mesh/common/include/mesh/common.h index db6c1d372a..a1cfa673a2 100644 --- a/components/bt/esp_ble_mesh/common/include/mesh/common.h +++ b/components/bt/esp_ble_mesh/common/include/mesh/common.h @@ -53,6 +53,8 @@ void bt_mesh_free_buf(struct net_buf_simple *buf); int bt_mesh_rand(void *buf, size_t len); +uint32_t bt_mesh_get_rand(void); + #ifdef __cplusplus } #endif diff --git a/components/bt/esp_ble_mesh/core/bluedroid_host/adapter.c b/components/bt/esp_ble_mesh/core/bluedroid_host/adapter.c index 68a768c794..0e5769ba7d 100644 --- a/components/bt/esp_ble_mesh/core/bluedroid_host/adapter.c +++ b/components/bt/esp_ble_mesh/core/bluedroid_host/adapter.c @@ -324,6 +324,7 @@ int bt_le_adv_start(const struct bt_mesh_adv_param *param, tBLE_ADDR_TYPE addr_type_own = 0U; tBLE_BD_ADDR p_dir_bda = {0}; tBTM_BLE_AFP adv_fil_pol = 0U; + uint16_t interval = 0U; uint8_t adv_type = 0U; int err = 0; @@ -387,9 +388,24 @@ int bt_le_adv_start(const struct bt_mesh_adv_param *param, adv_fil_pol = BLE_MESH_AP_SCAN_CONN_ALL; p_start_adv_cb = start_adv_completed_cb; + interval = param->interval_min; + +#if CONFIG_BLE_MESH_RANDOM_ADV_INTERVAL + /* If non-connectable mesh packets are transmitted with an adv interval + * not smaller than 10ms, then we will use a random adv interval between + * [interval / 2, interval] for them. + */ + if (adv_type == BLE_MESH_ADV_NONCONN_IND && interval >= 16) { + interval >>= 1; + interval += (bt_mesh_get_rand() % (interval + 1)); + + BT_INFO("%u->%u", param->interval_min, interval); + } +#endif + /* Check if we can start adv using BTM_BleSetAdvParamsStartAdvCheck */ BLE_MESH_BTM_CHECK_STATUS( - BTM_BleSetAdvParamsAll(param->interval_min, param->interval_max, adv_type, + BTM_BleSetAdvParamsAll(interval, interval, adv_type, addr_type_own, &p_dir_bda, channel_map, adv_fil_pol, p_start_adv_cb)); BLE_MESH_BTM_CHECK_STATUS(BTM_BleStartAdv()); diff --git a/components/bt/esp_ble_mesh/core/nimble_host/adapter.c b/components/bt/esp_ble_mesh/core/nimble_host/adapter.c index 806f4e0eb5..5df55185ef 100644 --- a/components/bt/esp_ble_mesh/core/nimble_host/adapter.c +++ b/components/bt/esp_ble_mesh/core/nimble_host/adapter.c @@ -758,15 +758,17 @@ int bt_le_adv_start(const struct bt_mesh_adv_param *param, const struct bt_mesh_adv_data *ad, size_t ad_len, const struct bt_mesh_adv_data *sd, size_t sd_len) { + struct ble_gap_adv_params adv_params; + uint8_t buf[BLE_HS_ADV_MAX_SZ]; + uint16_t interval = 0; + uint8_t buf_len = 0; + int err; + #if BLE_MESH_DEV if (bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING)) { return -EALREADY; } #endif - uint8_t buf[BLE_HS_ADV_MAX_SZ]; - uint8_t buf_len = 0; - int err; - struct ble_gap_adv_params adv_params; err = set_ad(ad, ad_len, buf, &buf_len); if (err) { @@ -797,8 +799,6 @@ int bt_le_adv_start(const struct bt_mesh_adv_param *param, } memset(&adv_params, 0, sizeof adv_params); - adv_params.itvl_min = param->interval_min; - adv_params.itvl_max = param->interval_max; if (param->options & BLE_MESH_ADV_OPT_CONNECTABLE) { adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; @@ -811,6 +811,25 @@ int bt_le_adv_start(const struct bt_mesh_adv_param *param, adv_params.disc_mode = BLE_GAP_DISC_MODE_NON; } + interval = param->interval_min; + +#if CONFIG_BLE_MESH_RANDOM_ADV_INTERVAL + /* If non-connectable mesh packets are transmitted with an adv interval + * not smaller than 10ms, then we will use a random adv interval between + * [interval / 2, interval] for them. + */ + if (adv_params.conn_mode == BLE_GAP_CONN_MODE_NON && + adv_params.disc_mode == BLE_GAP_DISC_MODE_NON && interval >= 16) { + interval >>= 1; + interval += (bt_mesh_get_rand() % (interval + 1)); + + BT_INFO("%u->%u", param->interval_min, interval); + } +#endif + + adv_params.itvl_min = interval; + adv_params.itvl_max = interval; + again: err = ble_gap_adv_start(BLE_OWN_ADDR_PUBLIC, NULL, BLE_HS_FOREVER, &adv_params, gap_event_cb, NULL);