diff --git a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_common_api.c b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_common_api.c index a469452f00..9a12de1710 100644 --- a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_common_api.c +++ b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_common_api.c @@ -65,7 +65,9 @@ esp_err_t esp_ble_mesh_init(esp_ble_mesh_prov_t *prov, esp_ble_mesh_comp_t *comp esp_err_t esp_ble_mesh_deinit(esp_ble_mesh_deinit_param_t *param) { btc_ble_mesh_prov_args_t arg = {0}; + SemaphoreHandle_t semaphore = NULL; btc_msg_t msg = {0}; + esp_err_t ret = ESP_OK; if (param == NULL) { return ESP_ERR_INVALID_ARG; @@ -73,13 +75,36 @@ esp_err_t esp_ble_mesh_deinit(esp_ble_mesh_deinit_param_t *param) ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); + // Create a semaphore + if ((semaphore = xSemaphoreCreateCounting(1, 0)) == NULL) { + BT_ERR("Failed to create semaphore"); + return ESP_ERR_NO_MEM; + } + arg.mesh_deinit.param.erase_flash = param->erase_flash; + /* Transport semaphore pointer to BTC layer, and will give the semaphore in the BTC task */ + arg.mesh_deinit.semaphore = semaphore; msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_PROV; msg.act = BTC_BLE_MESH_ACT_DEINIT_MESH; - return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL) - == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); + if (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL) != BT_STATUS_SUCCESS) { + vSemaphoreDelete(semaphore); + BT_ERR("Failed to start mesh deinit"); + return ESP_FAIL; + } + + /* Take the Semaphore, wait BLE Mesh de-initialization to finish. */ + xSemaphoreTake(semaphore, portMAX_DELAY); + /* Don't forget to delete the semaphore at the end. */ + vSemaphoreDelete(semaphore); + + ret = bt_mesh_host_deinit(); + if (ret != ESP_OK) { + return ret; + } + + return ESP_OK; } #endif /* CONFIG_BLE_MESH_DEINIT */ diff --git a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c index cbbee08cd4..3888268019 100644 --- a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c +++ b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c @@ -2825,6 +2825,8 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg) case BTC_BLE_MESH_ACT_DEINIT_MESH: act = ESP_BLE_MESH_DEINIT_MESH_COMP_EVT; param.deinit_mesh_comp.err_code = bt_mesh_deinit((struct bt_mesh_deinit_param *)&arg->mesh_deinit.param); + /* Give the semaphore when BLE Mesh de-initialization is finished. */ + xSemaphoreGive(arg->mesh_deinit.semaphore); break; #endif /* CONFIG_BLE_MESH_DEINIT */ default: diff --git a/components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_prov.h b/components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_prov.h index e303f43ab7..f27779270f 100644 --- a/components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_prov.h +++ b/components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_prov.h @@ -341,6 +341,7 @@ typedef union { } model_unsub_group_addr; struct ble_mesh_deinit_args { esp_ble_mesh_deinit_param_t param; + SemaphoreHandle_t semaphore; } mesh_deinit; } btc_ble_mesh_prov_args_t; 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 0e5769ba7d..0d6b9e5a3c 100644 --- a/components/bt/esp_ble_mesh/core/bluedroid_host/adapter.c +++ b/components/bt/esp_ble_mesh/core/bluedroid_host/adapter.c @@ -107,6 +107,11 @@ int bt_mesh_host_init(void) return 0; } +int bt_mesh_host_deinit(void) +{ + return 0; +} + void bt_mesh_hci_init(void) { const uint8_t *features = controller_get_interface()->get_features_ble()->as_array; 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 e1b8af79bf..d2f65759e3 100644 --- a/components/bt/esp_ble_mesh/core/include/mesh/adapter.h +++ b/components/bt/esp_ble_mesh/core/include/mesh/adapter.h @@ -682,6 +682,7 @@ struct bt_mesh_gatt_attr { } int bt_mesh_host_init(void); +int bt_mesh_host_deinit(void); int bt_le_adv_start(const struct bt_mesh_adv_param *param, const struct bt_mesh_adv_data *ad, size_t ad_len, 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 510352ce15..f055e18740 100644 --- a/components/bt/esp_ble_mesh/core/nimble_host/adapter.c +++ b/components/bt/esp_ble_mesh/core/nimble_host/adapter.c @@ -81,14 +81,15 @@ static struct bt_mesh_conn_cb *bt_mesh_gatts_conn_cb; static uint8_t bt_mesh_gatts_addr[6]; #endif /* CONFIG_BLE_MESH_NODE */ +static bool g_host_init = false; + int bt_mesh_host_init(void) { - static bool init = false; int rc; - if (init == true) { + if (g_host_init == true) { BT_WARN("Already initialized host for mesh!"); - return 0; + return -EALREADY; } rc = btc_init(); @@ -102,7 +103,30 @@ int bt_mesh_host_init(void) } osi_alarm_init(); - init = true; + g_host_init = true; + + return 0; +} + +int bt_mesh_host_deinit(void) +{ + int rc; + + if (g_host_init == false) { + return -EALREADY; + } + + osi_alarm_deinit(); + + rc = osi_alarm_delete_mux(); + if (rc != 0) { + return -1; + } + + btc_deinit(); + + g_host_init = false; + return 0; }