From d33caa02c86961daeac6f77759776b473d59c607 Mon Sep 17 00:00:00 2001 From: lly Date: Wed, 18 Dec 2019 21:18:59 +0800 Subject: [PATCH] ble_mesh: Add ble mesh deinit functions --- .../api/core/esp_ble_mesh_common_api.c | 5 + .../api/core/esp_ble_mesh_networking_api.c | 8 + .../core/include/esp_ble_mesh_common_api.h | 10 + .../include/esp_ble_mesh_networking_api.h | 12 + .../bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c | 10 + .../btc/include/btc_ble_mesh_prov.h | 4 + .../mesh_common/include/mesh_kernel.h | 1 + .../bt/esp_ble_mesh/mesh_common/mesh_kernel.c | 44 ++++ components/bt/esp_ble_mesh/mesh_core/access.c | 145 +++++++++++ components/bt/esp_ble_mesh/mesh_core/access.h | 1 + components/bt/esp_ble_mesh/mesh_core/adv.c | 42 +++- components/bt/esp_ble_mesh/mesh_core/adv.h | 3 + components/bt/esp_ble_mesh/mesh_core/beacon.c | 5 + components/bt/esp_ble_mesh/mesh_core/beacon.h | 1 + .../bluedroid_host/mesh_bearer_adapt.c | 48 ++++ .../bt/esp_ble_mesh/mesh_core/cfg_cli.c | 44 ++++ .../bt/esp_ble_mesh/mesh_core/cfg_srv.c | 19 ++ .../bt/esp_ble_mesh/mesh_core/foundation.h | 6 + components/bt/esp_ble_mesh/mesh_core/friend.c | 21 ++ components/bt/esp_ble_mesh/mesh_core/friend.h | 1 + .../bt/esp_ble_mesh/mesh_core/health_cli.c | 41 +++ .../bt/esp_ble_mesh/mesh_core/health_srv.c | 36 +++ .../mesh_core/include/mesh_bearer_adapt.h | 5 + .../mesh_core/include/mesh_main.h | 6 + components/bt/esp_ble_mesh/mesh_core/lpn.c | 11 + components/bt/esp_ble_mesh/mesh_core/lpn.h | 1 + components/bt/esp_ble_mesh/mesh_core/main.c | 91 +++++++ components/bt/esp_ble_mesh/mesh_core/net.c | 26 ++ components/bt/esp_ble_mesh/mesh_core/net.h | 2 + components/bt/esp_ble_mesh/mesh_core/prov.c | 38 +++ components/bt/esp_ble_mesh/mesh_core/prov.h | 1 + .../esp_ble_mesh/mesh_core/provisioner_main.c | 51 ++++ .../esp_ble_mesh/mesh_core/provisioner_main.h | 1 + .../esp_ble_mesh/mesh_core/provisioner_prov.c | 73 ++++++ .../esp_ble_mesh/mesh_core/provisioner_prov.h | 8 + .../bt/esp_ble_mesh/mesh_core/proxy_client.c | 18 ++ .../bt/esp_ble_mesh/mesh_core/proxy_client.h | 1 + .../bt/esp_ble_mesh/mesh_core/proxy_server.c | 29 +++ .../bt/esp_ble_mesh/mesh_core/proxy_server.h | 1 + .../bt/esp_ble_mesh/mesh_core/settings.c | 24 ++ .../bt/esp_ble_mesh/mesh_core/settings.h | 4 + .../mesh_core/storage/settings_nvs.c | 19 ++ .../mesh_core/storage/settings_nvs.h | 1 + .../bt/esp_ble_mesh/mesh_core/transport.c | 26 ++ .../bt/esp_ble_mesh/mesh_core/transport.h | 1 + .../mesh_models/client/client_common.c | 37 +++ .../mesh_models/client/generic_client.c | 77 ++++++ .../client/include/client_common.h | 2 + .../client/include/generic_client.h | 81 ++++++ .../client/include/lighting_client.h | 50 ++++ .../client/include/sensor_client.h | 10 + .../client/include/time_scene_client.h | 30 +++ .../mesh_models/client/lighting_client.c | 62 +++++ .../mesh_models/client/sensor_client.c | 37 +++ .../mesh_models/client/time_scene_client.c | 52 ++++ .../mesh_models/server/generic_server.c | 179 ++++++++++++++ .../server/include/generic_server.h | 15 ++ .../server/include/lighting_server.h | 14 ++ .../server/include/sensor_server.h | 3 + .../server/include/server_common.h | 1 + .../server/include/time_scene_server.h | 7 + .../mesh_models/server/lighting_server.c | 234 ++++++++++++++++++ .../mesh_models/server/sensor_server.c | 30 +++ .../mesh_models/server/server_common.c | 9 + .../mesh_models/server/time_scene_server.c | 93 ++++++- .../main/ble_mesh_demo_main.c | 37 +++ 66 files changed, 2003 insertions(+), 2 deletions(-) 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 b946a16c2c..43a2da9a1e 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 @@ -73,3 +73,8 @@ esp_err_t esp_ble_mesh_init(esp_ble_mesh_prov_t *prov, esp_ble_mesh_comp_t *comp return ESP_OK; } +esp_err_t esp_ble_mesh_deinit(void) +{ + return btc_ble_mesh_deinit(); +} + diff --git a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_networking_api.c b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_networking_api.c index 1dbc66ef24..e6e70284fa 100644 --- a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_networking_api.c +++ b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_networking_api.c @@ -164,6 +164,14 @@ esp_err_t esp_ble_mesh_client_model_init(esp_ble_mesh_model_t *model) return btc_ble_mesh_client_model_init(model); } +esp_err_t esp_ble_mesh_client_model_deinit(esp_ble_mesh_model_t *model) +{ + if (model == NULL) { + return ESP_ERR_INVALID_ARG; + } + return btc_ble_mesh_client_model_deinit(model); +} + esp_err_t esp_ble_mesh_server_model_send_msg(esp_ble_mesh_model_t *model, esp_ble_mesh_msg_ctx_t *ctx, uint32_t opcode, uint16_t length, uint8_t *data) diff --git a/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_common_api.h b/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_common_api.h index 7f48436685..618059444e 100644 --- a/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_common_api.h +++ b/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_common_api.h @@ -34,4 +34,14 @@ */ esp_err_t esp_ble_mesh_init(esp_ble_mesh_prov_t *prov, esp_ble_mesh_comp_t *comp); +/** + * @brief De-initialize BLE Mesh module. + * + * @note This function shall be invoked after esp_ble_mesh_client_model_deinit(). + * + * @return ESP_OK on success or error code otherwise. + * + */ +esp_err_t esp_ble_mesh_deinit(void); + #endif /* _ESP_BLE_MESH_COMMON_API_H_ */ diff --git a/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_networking_api.h b/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_networking_api.h index 54e46b12a2..341b6675ec 100644 --- a/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_networking_api.h +++ b/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_networking_api.h @@ -75,6 +75,18 @@ esp_err_t esp_ble_mesh_model_msg_opcode_init(uint8_t *data, uint32_t opcode); */ esp_err_t esp_ble_mesh_client_model_init(esp_ble_mesh_model_t *model); +/** + * @brief De-initialize the user-defined client model. + * + * @note This function shall be invoked before esp_ble_mesh_deinit() is called. + * + * @param[in] model: Pointer of the Client model. + * + * @return ESP_OK on success or error code otherwise. + * + */ +esp_err_t esp_ble_mesh_client_model_deinit(esp_ble_mesh_model_t *model); + /** * @brief Send server model messages(such as server model status messages). * 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 08660588f2..c9e0afa011 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 @@ -919,6 +919,11 @@ static void btc_ble_mesh_proxy_client_filter_status_recv_cb(u8_t conn_handle, } #endif /* CONFIG_BLE_MESH_GATT_PROXY_CLIENT */ +int btc_ble_mesh_deinit(void) +{ + return bt_mesh_deinit(); +} + int btc_ble_mesh_client_model_init(esp_ble_mesh_model_t *model) { __ASSERT(model && model->op, "%s, Invalid parameter", __func__); @@ -930,6 +935,11 @@ int btc_ble_mesh_client_model_init(esp_ble_mesh_model_t *model) return bt_mesh_client_init((struct bt_mesh_model *)model); } +int btc_ble_mesh_client_model_deinit(esp_ble_mesh_model_t *model) +{ + return bt_mesh_client_deinit((struct bt_mesh_model *)model); +} + int32_t btc_ble_mesh_model_pub_period_get(esp_ble_mesh_model_t *mod) { return bt_mesh_model_pub_period_get((struct bt_mesh_model *)mod); 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 c871534c02..3929a5cb26 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 @@ -232,8 +232,12 @@ void btc_ble_mesh_prov_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src); void btc_ble_mesh_model_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src); +int btc_ble_mesh_deinit(void); + int btc_ble_mesh_client_model_init(esp_ble_mesh_model_t *model); +int btc_ble_mesh_client_model_deinit(esp_ble_mesh_model_t *model); + int32_t btc_ble_mesh_model_pub_period_get(esp_ble_mesh_model_t *mod); uint16_t btc_ble_mesh_get_primary_addr(void); diff --git a/components/bt/esp_ble_mesh/mesh_common/include/mesh_kernel.h b/components/bt/esp_ble_mesh/mesh_common/include/mesh_kernel.h index 5e95e3b1a0..fc409825aa 100644 --- a/components/bt/esp_ble_mesh/mesh_common/include/mesh_kernel.h +++ b/components/bt/esp_ble_mesh/mesh_common/include/mesh_kernel.h @@ -278,6 +278,7 @@ void bt_mesh_atomic_lock(void); void bt_mesh_atomic_unlock(void); void bt_mesh_k_init(void); +void bt_mesh_k_deinit(void); #endif /* _BLE_MESH_KERNEL_H_ */ diff --git a/components/bt/esp_ble_mesh/mesh_common/mesh_kernel.c b/components/bt/esp_ble_mesh/mesh_common/mesh_kernel.c index 3d75efe15f..6eb4c671ff 100644 --- a/components/bt/esp_ble_mesh/mesh_common/mesh_kernel.c +++ b/components/bt/esp_ble_mesh/mesh_common/mesh_kernel.c @@ -45,6 +45,14 @@ static void bt_mesh_alarm_mutex_new(void) } } +static void bt_mesh_alarm_mutex_free(void) +{ + if (bm_alarm_lock) { + osi_mutex_free(&bm_alarm_lock); + bm_alarm_lock = NULL; + } +} + static void bt_mesh_alarm_lock(void) { if (bm_alarm_lock) { @@ -67,6 +75,14 @@ static void bt_mesh_list_mutex_new(void) } } +static void bt_mesh_list_mutex_free(void) +{ + if (bm_list_lock) { + osi_mutex_free(&bm_list_lock); + bm_list_lock = NULL; + } +} + void bt_mesh_list_lock(void) { if (bm_list_lock) { @@ -89,6 +105,14 @@ static void bt_mesh_buf_mutex_new(void) } } +static void bt_mesh_buf_mutex_free(void) +{ + if (bm_buf_lock) { + osi_mutex_free(&bm_buf_lock); + bm_buf_lock = NULL; + } +} + void bt_mesh_buf_lock(void) { if (bm_buf_lock) { @@ -111,6 +135,14 @@ static void bt_mesh_atomic_mutex_new(void) } } +static void bt_mesh_atomic_mutex_free(void) +{ + if (bm_atomic_lock) { + osi_mutex_free(&bm_atomic_lock); + bm_atomic_lock = NULL; + } +} + void bt_mesh_atomic_lock(void) { if (bm_atomic_lock) { @@ -159,6 +191,18 @@ void bt_mesh_k_init(void) assert(bm_alarm_hash_map != NULL); } +void bt_mesh_k_deinit(void) +{ + bt_mesh_alarm_mutex_free(); + bt_mesh_list_mutex_free(); + bt_mesh_buf_mutex_free(); + bt_mesh_atomic_mutex_free(); + if (bm_alarm_hash_map) { + hash_map_free(bm_alarm_hash_map); + bm_alarm_hash_map = NULL; + } +} + void k_delayed_work_init(struct k_delayed_work *work, k_work_handler_t handler) { osi_alarm_t *alarm = NULL; diff --git a/components/bt/esp_ble_mesh/mesh_core/access.c b/components/bt/esp_ble_mesh/mesh_core/access.c index 1acae2b767..d716f20cdd 100644 --- a/components/bt/esp_ble_mesh/mesh_core/access.c +++ b/components/bt/esp_ble_mesh/mesh_core/access.c @@ -145,6 +145,106 @@ static const struct { { BLE_MESH_MODEL_ID_SENSOR_SETUP_SRV, bt_mesh_sensor_setup_srv_init }, }; +static const struct { + const u16_t id; + int (*const deinit)(struct bt_mesh_model *model, bool primary); +} model_deinit[] = { + { BLE_MESH_MODEL_ID_CFG_SRV, bt_mesh_cfg_srv_deinit }, + { BLE_MESH_MODEL_ID_HEALTH_SRV, bt_mesh_health_srv_deinit }, +#if defined(CONFIG_BLE_MESH_CFG_CLI) + { BLE_MESH_MODEL_ID_CFG_CLI, bt_mesh_cfg_cli_deinit }, +#endif +#if defined(CONFIG_BLE_MESH_HEALTH_CLI) + { BLE_MESH_MODEL_ID_HEALTH_CLI, bt_mesh_health_cli_deinit }, +#endif +#if defined(CONFIG_BLE_MESH_GENERIC_ONOFF_CLI) + { BLE_MESH_MODEL_ID_GEN_ONOFF_CLI, bt_mesh_gen_onoff_cli_deinit }, +#endif +#if defined(CONFIG_BLE_MESH_GENERIC_LEVEL_CLI) + { BLE_MESH_MODEL_ID_GEN_LEVEL_CLI, bt_mesh_gen_level_cli_deinit }, +#endif +#if defined(CONFIG_BLE_MESH_GENERIC_DEF_TRANS_TIME_CLI) + { BLE_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_CLI, bt_mesh_gen_def_trans_time_cli_deinit }, +#endif +#if defined(CONFIG_BLE_MESH_GENERIC_POWER_ONOFF_CLI) + { BLE_MESH_MODEL_ID_GEN_POWER_ONOFF_CLI, bt_mesh_gen_pwr_onoff_cli_deinit }, +#endif +#if defined(CONFIG_BLE_MESH_GENERIC_POWER_LEVEL_CLI) + { BLE_MESH_MODEL_ID_GEN_POWER_LEVEL_CLI, bt_mesh_gen_pwr_level_cli_deinit }, +#endif +#if defined(CONFIG_BLE_MESH_GENERIC_BATTERY_CLI) + { BLE_MESH_MODEL_ID_GEN_BATTERY_CLI, bt_mesh_gen_battery_cli_deinit }, +#endif +#if defined(CONFIG_BLE_MESH_GENERIC_LOCATION_CLI) + { BLE_MESH_MODEL_ID_GEN_LOCATION_CLI, bt_mesh_gen_location_cli_deinit }, +#endif +#if defined(CONFIG_BLE_MESH_GENERIC_PROPERTY_CLI) + { BLE_MESH_MODEL_ID_GEN_PROP_CLI, bt_mesh_gen_property_cli_deinit }, +#endif +#if defined(CONFIG_BLE_MESH_SENSOR_CLI) + { BLE_MESH_MODEL_ID_SENSOR_CLI, bt_mesh_sensor_cli_deinit }, +#endif +#if defined(CONFIG_BLE_MESH_TIME_CLI) + { BLE_MESH_MODEL_ID_TIME_CLI, bt_mesh_time_cli_deinit }, +#endif +#if defined(CONFIG_BLE_MESH_SCENE_CLI) + { BLE_MESH_MODEL_ID_SCENE_CLI, bt_mesh_scene_cli_deinit }, +#endif +#if defined(CONFIG_BLE_MESH_SCHEDULER_CLI) + { BLE_MESH_MODEL_ID_SCHEDULER_CLI, bt_mesh_scheduler_cli_deinit }, +#endif +#if defined(CONFIG_BLE_MESH_LIGHT_LIGHTNESS_CLI) + { BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_CLI, bt_mesh_light_lightness_cli_deinit }, +#endif +#if defined(CONFIG_BLE_MESH_LIGHT_CTL_CLI) + { BLE_MESH_MODEL_ID_LIGHT_CTL_CLI, bt_mesh_light_ctl_cli_deinit }, +#endif +#if defined(CONFIG_BLE_MESH_LIGHT_HSL_CLI) + { BLE_MESH_MODEL_ID_LIGHT_HSL_CLI, bt_mesh_light_hsl_cli_deinit }, +#endif +#if defined(CONFIG_BLE_MESH_LIGHT_XYL_CLI) + { BLE_MESH_MODEL_ID_LIGHT_XYL_CLI, bt_mesh_light_xyl_cli_deinit }, +#endif +#if defined(CONFIG_BLE_MESH_LIGHT_LC_CLI) + { BLE_MESH_MODEL_ID_LIGHT_LC_CLI, bt_mesh_light_lc_cli_deinit }, +#endif + { BLE_MESH_MODEL_ID_GEN_ONOFF_SRV, bt_mesh_gen_onoff_srv_deinit }, + { BLE_MESH_MODEL_ID_GEN_LEVEL_SRV, bt_mesh_gen_level_srv_deinit }, + { BLE_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_SRV, bt_mesh_gen_def_trans_time_srv_deinit }, + { BLE_MESH_MODEL_ID_GEN_POWER_ONOFF_SRV, bt_mesh_gen_power_onoff_srv_deinit }, + { BLE_MESH_MODEL_ID_GEN_POWER_ONOFF_SETUP_SRV, bt_mesh_gen_power_onoff_setup_srv_deinit }, + { BLE_MESH_MODEL_ID_GEN_POWER_LEVEL_SRV, bt_mesh_gen_power_level_srv_deinit }, + { BLE_MESH_MODEL_ID_GEN_POWER_LEVEL_SETUP_SRV, bt_mesh_gen_power_level_setup_srv_deinit }, + { BLE_MESH_MODEL_ID_GEN_BATTERY_SRV, bt_mesh_gen_battery_srv_deinit }, + { BLE_MESH_MODEL_ID_GEN_LOCATION_SRV, bt_mesh_gen_location_srv_deinit }, + { BLE_MESH_MODEL_ID_GEN_LOCATION_SETUP_SRV, bt_mesh_gen_location_setup_srv_deinit }, + { BLE_MESH_MODEL_ID_GEN_USER_PROP_SRV, bt_mesh_gen_user_prop_srv_deinit }, + { BLE_MESH_MODEL_ID_GEN_ADMIN_PROP_SRV, bt_mesh_gen_admin_prop_srv_deinit }, + { BLE_MESH_MODEL_ID_GEN_MANUFACTURER_PROP_SRV, bt_mesh_gen_manu_prop_srv_deinit }, + { BLE_MESH_MODEL_ID_GEN_CLIENT_PROP_SRV, bt_mesh_gen_client_prop_srv_deinit }, + { BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV, bt_mesh_light_lightness_srv_deinit }, + { BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SETUP_SRV, bt_mesh_light_lightness_setup_srv_deinit }, + { BLE_MESH_MODEL_ID_LIGHT_CTL_SRV, bt_mesh_light_ctl_srv_deinit }, + { BLE_MESH_MODEL_ID_LIGHT_CTL_SETUP_SRV, bt_mesh_light_ctl_setup_srv_deinit }, + { BLE_MESH_MODEL_ID_LIGHT_CTL_TEMP_SRV, bt_mesh_light_ctl_temp_srv_deinit }, + { BLE_MESH_MODEL_ID_LIGHT_HSL_SRV, bt_mesh_light_hsl_srv_deinit }, + { BLE_MESH_MODEL_ID_LIGHT_HSL_HUE_SRV, bt_mesh_light_hsl_hue_srv_deinit }, + { BLE_MESH_MODEL_ID_LIGHT_HSL_SAT_SRV, bt_mesh_light_hsl_sat_srv_deinit }, + { BLE_MESH_MODEL_ID_LIGHT_HSL_SETUP_SRV, bt_mesh_light_hsl_setup_srv_deinit }, + { BLE_MESH_MODEL_ID_LIGHT_XYL_SRV, bt_mesh_light_xyl_srv_deinit }, + { BLE_MESH_MODEL_ID_LIGHT_XYL_SETUP_SRV, bt_mesh_light_xyl_setup_srv_deinit }, + { BLE_MESH_MODEL_ID_LIGHT_LC_SRV, bt_mesh_light_lc_srv_deinit }, + { BLE_MESH_MODEL_ID_LIGHT_LC_SETUP_SRV, bt_mesh_light_lc_setup_srv_deinit }, + { BLE_MESH_MODEL_ID_TIME_SRV, bt_mesh_time_srv_deinit }, + { BLE_MESH_MODEL_ID_TIME_SETUP_SRV, bt_mesh_time_setup_srv_deinit }, + { BLE_MESH_MODEL_ID_SCENE_SRV, bt_mesh_scene_srv_deinit }, + { BLE_MESH_MODEL_ID_SCENE_SETUP_SRV, bt_mesh_scene_setup_srv_deinit }, + { BLE_MESH_MODEL_ID_SCHEDULER_SRV, bt_mesh_scheduler_srv_deinit }, + { BLE_MESH_MODEL_ID_SCHEDULER_SETUP_SRV, bt_mesh_scheduler_setup_srv_deinit }, + { BLE_MESH_MODEL_ID_SENSOR_SRV, bt_mesh_sensor_srv_deinit }, + { BLE_MESH_MODEL_ID_SENSOR_SETUP_SRV, bt_mesh_sensor_setup_srv_deinit }, +}; + void bt_mesh_model_foreach(void (*func)(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, bool vnd, bool primary, @@ -456,6 +556,37 @@ static void mod_init(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, } } +static void mod_deinit(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, + bool vnd, bool primary, void *user_data) +{ + size_t i; + + mod->elem = NULL; + + if (mod->pub) { + mod->pub->mod = NULL; + k_delayed_work_free(&mod->pub->timer); + } + + for (i = 0U; i < ARRAY_SIZE(mod->keys); i++) { + mod->keys[i] = BLE_MESH_KEY_UNUSED; + } + + mod->flags = 0U; + mod->elem_idx = 0U; + mod->model_idx = 0U; + + if (vnd) { + return; + } + + for (i = 0; i < ARRAY_SIZE(model_deinit); i++) { + if (model_deinit[i].id == mod->id) { + model_deinit[i].deinit(mod, primary); + } + } +} + int bt_mesh_comp_register(const struct bt_mesh_comp *comp) { /* There must be at least one element */ @@ -470,6 +601,20 @@ int bt_mesh_comp_register(const struct bt_mesh_comp *comp) return 0; } +int bt_mesh_comp_deregister(void) +{ + if (dev_comp == NULL) { + return -EINVAL; + } + + bt_mesh_model_foreach(mod_deinit, NULL); + + dev_primary_addr = BLE_MESH_ADDR_UNASSIGNED; + dev_comp = NULL; + + return 0; +} + void bt_mesh_comp_provision(u16_t addr) { int i; diff --git a/components/bt/esp_ble_mesh/mesh_core/access.h b/components/bt/esp_ble_mesh/mesh_core/access.h index 119ad23627..3e46fd7692 100644 --- a/components/bt/esp_ble_mesh/mesh_core/access.h +++ b/components/bt/esp_ble_mesh/mesh_core/access.h @@ -56,6 +56,7 @@ struct bt_mesh_model *bt_mesh_model_get(bool vnd, u8_t elem_idx, u8_t mod_idx); void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf); int bt_mesh_comp_register(const struct bt_mesh_comp *comp); +int bt_mesh_comp_deregister(void); struct bt_mesh_subnet *bt_mesh_tx_netkey_get(u8_t role, u16_t net_idx); diff --git a/components/bt/esp_ble_mesh/mesh_core/adv.c b/components/bt/esp_ble_mesh/mesh_core/adv.c index b82422a9e9..c3162d1a0b 100644 --- a/components/bt/esp_ble_mesh/mesh_core/adv.c +++ b/components/bt/esp_ble_mesh/mesh_core/adv.c @@ -94,6 +94,8 @@ static QueueSetHandle_t xBleMeshQueueSet; static bool ignore_relay_packet(u32_t timestamp); #endif /* defined(CONFIG_BLE_MESH_RELAY_ADV_BUF) */ +static TaskHandle_t adv_task_handle; + static struct bt_mesh_adv *adv_alloc(int id) { return &adv_pool[id]; @@ -326,6 +328,24 @@ struct net_buf *bt_mesh_adv_create_from_pool(struct net_buf_pool *pool, return buf; } +void bt_mesh_unref_buf_from_pool(struct net_buf_pool *pool) +{ + size_t i; + + if (pool == NULL) { + BT_ERR("%s, Invalid parameter", __func__); + return; + } + + for (i = 0U; i < pool->buf_count; i++) { + struct net_buf *buf = &pool->__bufs[i]; + if (buf->ref > 1U) { + buf->ref = 1U; + net_buf_unref(buf); + } + } +} + struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, u8_t xmit, s32_t timeout) { @@ -733,10 +753,30 @@ void bt_mesh_adv_init(void) xQueueAddToSet(xBleMeshRelayQueue, xBleMeshQueueSet); #endif /* defined(CONFIG_BLE_MESH_RELAY_ADV_BUF) */ int ret = xTaskCreatePinnedToCore(adv_thread, "BLE_Mesh_ADV_Task", 3072, NULL, - configMAX_PRIORITIES - 5, NULL, ADV_TASK_CORE); + configMAX_PRIORITIES - 5, &adv_task_handle, ADV_TASK_CORE); configASSERT(ret == pdTRUE); } +void bt_mesh_adv_deinit(void) +{ + if (xBleMeshQueue == NULL) { + return; + } + +#if defined(CONFIG_BLE_MESH_RELAY_ADV_BUF) + xQueueRemoveFromSet(xBleMeshQueue, xBleMeshQueueSet); + xQueueRemoveFromSet(xBleMeshRelayQueue, xBleMeshQueueSet); + vQueueDelete(xBleMeshRelayQueue); + bt_mesh_unref_buf_from_pool(&relay_adv_buf_pool); + memset(relay_adv_pool, 0, sizeof(relay_adv_pool)); + vQueueDelete(xBleMeshQueueSet); +#endif /* defined(CONFIG_BLE_MESH_RELAY_ADV_BUF) */ + vQueueDelete(xBleMeshQueue); + bt_mesh_unref_buf_from_pool(&adv_buf_pool); + memset(adv_pool, 0, sizeof(adv_pool)); + vTaskDelete(adv_task_handle); +} + int bt_mesh_scan_enable(void) { int err; diff --git a/components/bt/esp_ble_mesh/mesh_core/adv.h b/components/bt/esp_ble_mesh/mesh_core/adv.h index 7d7cce63f3..f095fe58d9 100644 --- a/components/bt/esp_ble_mesh/mesh_core/adv.h +++ b/components/bt/esp_ble_mesh/mesh_core/adv.h @@ -72,6 +72,8 @@ struct net_buf *bt_mesh_adv_create_from_pool(struct net_buf_pool *pool, enum bt_mesh_adv_type type, u8_t xmit, s32_t timeout); +void bt_mesh_unref_buf_from_pool(struct net_buf_pool *pool); + void bt_mesh_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb, void *cb_data); @@ -88,6 +90,7 @@ u16_t bt_mesh_get_stored_relay_count(void); void bt_mesh_adv_update(void); void bt_mesh_adv_init(void); +void bt_mesh_adv_deinit(void); int bt_mesh_scan_enable(void); diff --git a/components/bt/esp_ble_mesh/mesh_core/beacon.c b/components/bt/esp_ble_mesh/mesh_core/beacon.c index c39b709c64..32772b494c 100644 --- a/components/bt/esp_ble_mesh/mesh_core/beacon.c +++ b/components/bt/esp_ble_mesh/mesh_core/beacon.c @@ -393,6 +393,11 @@ void bt_mesh_beacon_init(void) k_delayed_work_init(&beacon_timer, beacon_send); } +void bt_mesh_beacon_deinit(void) +{ + k_delayed_work_free(&beacon_timer); +} + void bt_mesh_beacon_ivu_initiator(bool enable) { bt_mesh_atomic_set_bit_to(bt_mesh.flags, BLE_MESH_IVU_INITIATOR, enable); diff --git a/components/bt/esp_ble_mesh/mesh_core/beacon.h b/components/bt/esp_ble_mesh/mesh_core/beacon.h index f410fa5d59..fbddedb63c 100644 --- a/components/bt/esp_ble_mesh/mesh_core/beacon.h +++ b/components/bt/esp_ble_mesh/mesh_core/beacon.h @@ -20,5 +20,6 @@ void bt_mesh_beacon_create(struct bt_mesh_subnet *sub, struct net_buf_simple *buf); void bt_mesh_beacon_init(void); +void bt_mesh_beacon_deinit(void); #endif /* _BEACON_H_ */ diff --git a/components/bt/esp_ble_mesh/mesh_core/bluedroid_host/mesh_bearer_adapt.c b/components/bt/esp_ble_mesh/mesh_core/bluedroid_host/mesh_bearer_adapt.c index e9196257e7..0cba1de1ca 100644 --- a/components/bt/esp_ble_mesh/mesh_core/bluedroid_host/mesh_bearer_adapt.c +++ b/components/bt/esp_ble_mesh/mesh_core/bluedroid_host/mesh_bearer_adapt.c @@ -105,6 +105,11 @@ esp_err_t bt_mesh_host_init(void) return ESP_OK; } +esp_err_t bt_mesh_host_deinit(void) +{ + return ESP_OK; +} + void bt_mesh_hci_init(void) { const uint8_t *features = controller_get_interface()->get_features_ble()->as_array; @@ -605,6 +610,11 @@ void bt_mesh_gatts_conn_cb_register(struct bt_mesh_conn_cb *cb) bt_mesh_gatts_conn_cb = cb; } +void bt_mesh_gatts_conn_cb_deregister(void) +{ + bt_mesh_gatts_conn_cb = NULL; +} + static struct bt_mesh_gatt_attr *bt_mesh_gatts_find_attr_by_handle(u16_t handle) { struct bt_mesh_gatt_service *svc = NULL; @@ -818,6 +828,16 @@ populate: return 0; } +static int gatts_deregister(struct bt_mesh_gatt_service *svc) +{ + if (sys_slist_is_empty(&bt_mesh_gatts_db)) { + return 0; + } + + sys_slist_find_and_remove(&bt_mesh_gatts_db, &svc->node); + return 0; +} + static tBTA_GATT_PERM bt_mesh_perm_to_bta_perm(u8_t perm) { tBTA_GATT_PERM bta_perm = 0; @@ -938,6 +958,17 @@ int bt_mesh_gatts_service_register(struct bt_mesh_gatt_service *svc) return 0; } +int bt_mesh_gatts_service_deregister(struct bt_mesh_gatt_service *svc) +{ + assert(svc != NULL); + + gatts_deregister(svc); + + BTA_GATTS_DeleteService(svc->attrs[0].handle); + + return 0; +} + int bt_mesh_gatts_disconnect(struct bt_mesh_conn *conn, u8_t reason) { UNUSED(reason); @@ -1027,6 +1058,11 @@ void bt_mesh_gattc_conn_cb_register(struct bt_mesh_prov_conn_cb *cb) bt_mesh_gattc_conn_cb = cb; } +void bt_mesh_gattc_conn_cb_deregister(void) +{ + bt_mesh_gattc_conn_cb = NULL; +} + u8_t bt_mesh_gattc_get_free_conn_count(void) { u8_t count = 0; @@ -1668,6 +1704,18 @@ void bt_mesh_gatt_init(void) #endif } +void bt_mesh_gatt_deinit(void) +{ +#if CONFIG_BLE_MESH_NODE + BTA_GATTS_AppDeregister(bt_mesh_gatts_if); +#endif + +#if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \ + CONFIG_BLE_MESH_GATT_PROXY_CLIENT + BTA_GATTC_AppDeregister(bt_mesh_gattc_if); +#endif +} + void bt_mesh_adapt_init(void) { BT_DBG("%s", __func__); diff --git a/components/bt/esp_ble_mesh/mesh_core/cfg_cli.c b/components/bt/esp_ble_mesh/mesh_core/cfg_cli.c index 343eff9e86..3afbd8c572 100644 --- a/components/bt/esp_ble_mesh/mesh_core/cfg_cli.c +++ b/components/bt/esp_ble_mesh/mesh_core/cfg_cli.c @@ -96,6 +96,14 @@ static void bt_mesh_cfg_client_mutex_new(void) } } +static void bt_mesh_cfg_client_mutex_free(void) +{ + if (cfg_client_lock) { + osi_mutex_free(&cfg_client_lock); + cfg_client_lock = NULL; + } +} + static void bt_mesh_cfg_client_lock(void) { if (cfg_client_lock) { @@ -1680,3 +1688,39 @@ int bt_mesh_cfg_cli_init(struct bt_mesh_model *model, bool primary) return 0; } + +int bt_mesh_cfg_cli_deinit(struct bt_mesh_model *model, bool primary) +{ + bt_mesh_config_client_t *client = NULL; + + if (!primary) { + BT_ERR("Configuration Client only allowed in primary element"); + return -EINVAL; + } + + if (!model) { + BT_ERR("Configuration Client model is NULL"); + return -EINVAL; + } + + client = (bt_mesh_config_client_t *)model->user_data; + if (!client) { + BT_ERR("No Configuration Client context provided"); + return -EINVAL; + } + + if (client->internal_data) { + /* Remove items from the list */ + bt_mesh_client_clear_list(client->internal_data); + + /* Free the allocated internal data */ + osi_free(client->internal_data); + cli->internal_data = NULL; + } + + client = NULL; + + bt_mesh_cfg_client_mutex_free(); + + return 0; +} diff --git a/components/bt/esp_ble_mesh/mesh_core/cfg_srv.c b/components/bt/esp_ble_mesh/mesh_core/cfg_srv.c index 1897422958..9fd8071820 100644 --- a/components/bt/esp_ble_mesh/mesh_core/cfg_srv.c +++ b/components/bt/esp_ble_mesh/mesh_core/cfg_srv.c @@ -3423,6 +3423,25 @@ int bt_mesh_cfg_srv_init(struct bt_mesh_model *model, bool primary) return 0; } +int bt_mesh_cfg_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + struct bt_mesh_cfg_srv *cfg = model->user_data; + + if (!cfg) { + BT_ERR("%s, No Configuration Server context provided", __func__); + return -EINVAL; + } + + bt_mesh_cfg_reset(); + + k_delayed_work_free(&cfg->hb_pub.timer); + cfg->hb_pub.dst = BLE_MESH_ADDR_UNASSIGNED; + + conf = NULL; + + return 0; +} + static void mod_reset(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data) { diff --git a/components/bt/esp_ble_mesh/mesh_core/foundation.h b/components/bt/esp_ble_mesh/mesh_core/foundation.h index 19bc96dd70..dba564c411 100644 --- a/components/bt/esp_ble_mesh/mesh_core/foundation.h +++ b/components/bt/esp_ble_mesh/mesh_core/foundation.h @@ -131,9 +131,15 @@ struct label { int bt_mesh_cfg_srv_init(struct bt_mesh_model *model, bool primary); int bt_mesh_health_srv_init(struct bt_mesh_model *model, bool primary); +int bt_mesh_cfg_srv_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_health_srv_deinit(struct bt_mesh_model *model, bool primary); + int bt_mesh_cfg_cli_init(struct bt_mesh_model *model, bool primary); int bt_mesh_health_cli_init(struct bt_mesh_model *model, bool primary); +int bt_mesh_cfg_cli_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_health_cli_deinit(struct bt_mesh_model *model, bool primary); + void bt_mesh_cfg_reset(void); void bt_mesh_heartbeat(u16_t src, u16_t dst, u8_t hops, u16_t feat); diff --git a/components/bt/esp_ble_mesh/mesh_core/friend.c b/components/bt/esp_ble_mesh/mesh_core/friend.c index 0a1851612f..38d7932f62 100644 --- a/components/bt/esp_ble_mesh/mesh_core/friend.c +++ b/components/bt/esp_ble_mesh/mesh_core/friend.c @@ -1272,6 +1272,27 @@ int bt_mesh_friend_init(void) return 0; } +int bt_mesh_friend_deinit(void) +{ + size_t i; + + bt_mesh_friend_clear_net_idx(BLE_MESH_KEY_ANY); + + for (i = 0U; i < ARRAY_SIZE(bt_mesh.frnd); i++) { + struct bt_mesh_friend *frnd = &bt_mesh.frnd[i]; + + frnd->net_idx = BLE_MESH_KEY_UNUSED; + + k_delayed_work_free(&frnd->timer); + k_delayed_work_free(&frnd->clear.timer); + } + + bt_mesh_unref_buf_from_pool(&friend_buf_pool); + memset(adv_pool, 0, sizeof(adv_pool)); + + return 0; +} + static bool is_segack(struct net_buf *buf, u64_t *seqauth, u16_t src) { struct net_buf_simple_state state; diff --git a/components/bt/esp_ble_mesh/mesh_core/friend.h b/components/bt/esp_ble_mesh/mesh_core/friend.h index 8c1fbe57b7..955d37166f 100644 --- a/components/bt/esp_ble_mesh/mesh_core/friend.h +++ b/components/bt/esp_ble_mesh/mesh_core/friend.h @@ -50,6 +50,7 @@ int bt_mesh_friend_sub_rem(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf); int bt_mesh_friend_init(void); +int bt_mesh_friend_deinit(void); void bt_mesh_friend_remove_lpn(u16_t lpn_addr); diff --git a/components/bt/esp_ble_mesh/mesh_core/health_cli.c b/components/bt/esp_ble_mesh/mesh_core/health_cli.c index b34a0c47f3..30fcec24ce 100644 --- a/components/bt/esp_ble_mesh/mesh_core/health_cli.c +++ b/components/bt/esp_ble_mesh/mesh_core/health_cli.c @@ -49,6 +49,14 @@ static void bt_mesh_health_client_mutex_new(void) } } +static void bt_mesh_health_client_mutex_free(void) +{ + if (health_client_lock) { + osi_mutex_free(&health_client_lock); + health_client_lock = NULL; + } +} + static void bt_mesh_health_client_lock(void) { if (health_client_lock) { @@ -482,3 +490,36 @@ int bt_mesh_health_cli_init(struct bt_mesh_model *model, bool primary) return 0; } + +int bt_mesh_health_cli_deinit(struct bt_mesh_model *model, bool primary) +{ + bt_mesh_health_client_t *client = NULL; + + if (!model) { + BT_ERR("%s, Invalid parameter", __func__); + return -EINVAL; + } + + client = (bt_mesh_health_client_t *)model->user_data; + if (!client) { + BT_ERR("%s, No Health Client context provided", __func__); + return -EINVAL; + } + + if (client->internal_data) { + /* Remove items from the list */ + bt_mesh_client_clear_list(client->internal_data); + + /* Free the allocated internal data */ + osi_free(client->internal_data); + client->internal_data = NULL; + } + + bt_mesh_health_client_mutex_free(); + + if (health_cli) { + health_cli = NULL; + } + + return 0; +} diff --git a/components/bt/esp_ble_mesh/mesh_core/health_srv.c b/components/bt/esp_ble_mesh/mesh_core/health_srv.c index 6b039b6f45..3624696ee7 100644 --- a/components/bt/esp_ble_mesh/mesh_core/health_srv.c +++ b/components/bt/esp_ble_mesh/mesh_core/health_srv.c @@ -484,6 +484,42 @@ int bt_mesh_health_srv_init(struct bt_mesh_model *model, bool primary) return 0; } +int bt_mesh_health_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + struct bt_mesh_health_srv *srv = model->user_data; + + if (!srv) { + if (!primary) { + /* If Health Server is in the secondary element with NULL user_data. */ + return 0; + } + + BT_ERR("%s, No Health Server context provided", __func__); + return -EINVAL; + } + + if (srv->test.id_count == 0 || !srv->test.test_ids) { + BT_ERR("%s, No Health Test ID provided", __func__); + return -EINVAL; + } + + if (!model->pub) { + BT_ERR("%s, Health Server has no publication support", __func__); + return -EINVAL; + } + + model->pub->addr = BLE_MESH_ADDR_UNASSIGNED; + model->pub->update = NULL; + + k_delayed_work_free(&srv->attn_timer); + + if (primary) { + health_srv = NULL; + } + + return 0; +} + void bt_mesh_attention(struct bt_mesh_model *model, u8_t time) { struct bt_mesh_health_srv *srv; diff --git a/components/bt/esp_ble_mesh/mesh_core/include/mesh_bearer_adapt.h b/components/bt/esp_ble_mesh/mesh_core/include/mesh_bearer_adapt.h index 46c2d361d2..7ebb19507b 100644 --- a/components/bt/esp_ble_mesh/mesh_core/include/mesh_bearer_adapt.h +++ b/components/bt/esp_ble_mesh/mesh_core/include/mesh_bearer_adapt.h @@ -641,6 +641,7 @@ struct bt_mesh_gatt_attr { } esp_err_t bt_mesh_host_init(void); +esp_err_t 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, @@ -653,10 +654,12 @@ int bt_le_scan_start(const struct bt_mesh_scan_param *param, bt_mesh_scan_cb_t c int bt_le_scan_stop(void); void bt_mesh_gatts_conn_cb_register(struct bt_mesh_conn_cb *cb); +void bt_mesh_gatts_conn_cb_deregister(void); int bt_mesh_gatts_disconnect(struct bt_mesh_conn *conn, u8_t reason); int bt_mesh_gatts_service_register(struct bt_mesh_gatt_service *svc); +int bt_mesh_gatts_service_deregister(struct bt_mesh_gatt_service *svc); int bt_mesh_gatts_service_unregister(struct bt_mesh_gatt_service *svc); @@ -688,6 +691,7 @@ int bt_mesh_gatts_service_start(struct bt_mesh_gatt_service *svc); int bt_mesh_gatts_set_local_device_name(const char *name); void bt_mesh_gattc_conn_cb_register(struct bt_mesh_prov_conn_cb *cb); +void bt_mesh_gattc_conn_cb_deregister(void); u8_t bt_mesh_gattc_get_free_conn_count(void); @@ -711,6 +715,7 @@ struct bt_mesh_conn *bt_mesh_conn_ref(struct bt_mesh_conn *conn); void bt_mesh_conn_unref(struct bt_mesh_conn *conn); void bt_mesh_gatt_init(void); +void bt_mesh_gatt_deinit(void); void bt_mesh_adapt_init(void); diff --git a/components/bt/esp_ble_mesh/mesh_core/include/mesh_main.h b/components/bt/esp_ble_mesh/mesh_core/include/mesh_main.h index 0f2135b4c8..47df7974e7 100644 --- a/components/bt/esp_ble_mesh/mesh_core/include/mesh_main.h +++ b/components/bt/esp_ble_mesh/mesh_core/include/mesh_main.h @@ -470,6 +470,12 @@ int bt_mesh_provisioner_disable(bt_mesh_prov_bearer_t bearers); int bt_mesh_init(const struct bt_mesh_prov *prov, const struct bt_mesh_comp *comp); +/** @brief De-initialize Mesh support + * + * @return Zero on success or (negative) error code otherwise. + */ +int bt_mesh_deinit(void); + /** @brief Reset the state of the local Mesh node. * * Resets the state of the node, which means that it needs to be diff --git a/components/bt/esp_ble_mesh/mesh_core/lpn.c b/components/bt/esp_ble_mesh/mesh_core/lpn.c index 06358cac4d..5fa56855c1 100644 --- a/components/bt/esp_ble_mesh/mesh_core/lpn.c +++ b/components/bt/esp_ble_mesh/mesh_core/lpn.c @@ -1094,4 +1094,15 @@ int bt_mesh_lpn_init(void) return 0; } +int bt_mesh_lpn_deinit(void) +{ + struct bt_mesh_lpn *lpn = &bt_mesh.lpn; + + bt_mesh_lpn_disable(true); + + k_delayed_work_free(&lpn->timer); + + return 0; +} + #endif /* CONFIG_BLE_MESH_LOW_POWER */ diff --git a/components/bt/esp_ble_mesh/mesh_core/lpn.h b/components/bt/esp_ble_mesh/mesh_core/lpn.h index ad870e99e1..c2b726322f 100644 --- a/components/bt/esp_ble_mesh/mesh_core/lpn.h +++ b/components/bt/esp_ble_mesh/mesh_core/lpn.h @@ -63,5 +63,6 @@ void bt_mesh_lpn_group_del(u16_t *groups, size_t group_count); void bt_mesh_lpn_disable(bool force); int bt_mesh_lpn_init(void); +int bt_mesh_lpn_deinit(void); #endif /* _LPN_H_ */ diff --git a/components/bt/esp_ble_mesh/mesh_core/main.c b/components/bt/esp_ble_mesh/mesh_core/main.c index b523007911..96cde51736 100644 --- a/components/bt/esp_ble_mesh/mesh_core/main.c +++ b/components/bt/esp_ble_mesh/mesh_core/main.c @@ -355,6 +355,97 @@ int bt_mesh_init(const struct bt_mesh_prov *prov, return 0; } +int bt_mesh_deinit(void) +{ + int err; + + if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) { + if (IS_ENABLED(CONFIG_BLE_MESH_PB_ADV)) { + bt_mesh_beacon_disable(); + bt_mesh_scan_disable(); + } + + if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT)) { + bt_mesh_proxy_prov_disable(true); + } + } + + if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) && bt_mesh_is_provisioner_en()) { + if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT)) { + bt_mesh_provisioner_pb_gatt_disable(); + } + + bt_mesh_scan_disable(); + provisioner_en = false; + } + + if (IS_ENABLED(CONFIG_BLE_MESH_PROV)) { + if (IS_ENABLED(CONFIG_BLE_MESH_NODE)) { + err = bt_mesh_prov_deinit(); + if (err) { + return err; + } + } + if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER)) { + err = bt_mesh_provisioner_prov_deinit(); + if (err) { + return err; + } + } + } + + bt_mesh_trans_deinit(); + bt_mesh_net_deinit(); + + if (IS_ENABLED(CONFIG_BLE_MESH_NODE)) { + bt_mesh_beacon_deinit(); + } + + if (IS_ENABLED(CONFIG_BLE_MESH_PROXY)) { + if (IS_ENABLED(CONFIG_BLE_MESH_NODE)) { + bt_mesh_proxy_deinit(); + } + } + + if ((IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) && + IS_ENABLED(CONFIG_BLE_MESH_PB_GATT)) || + IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_CLIENT)) { + bt_mesh_proxy_prov_client_deinit(); + } + + bt_mesh_gatt_deinit(); + + if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER)) { + err = bt_mesh_provisioner_deinit(); + if (err) { + return err; + } + } + + if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) { + bt_mesh_friend_deinit(); + } + + if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER)) { + bt_mesh_lpn_deinit(); + } + + bt_mesh_adv_deinit(); + + err = bt_mesh_comp_deregister(); + if (err) { + return err; + } + + if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { + bt_mesh_settings_deinit(); + } + + bt_mesh_k_deinit(); + + return 0; +} + bool bt_mesh_is_provisioner_en(void) { return provisioner_en; diff --git a/components/bt/esp_ble_mesh/mesh_core/net.c b/components/bt/esp_ble_mesh/mesh_core/net.c index 2e55f306a8..3887ba4adc 100644 --- a/components/bt/esp_ble_mesh/mesh_core/net.c +++ b/components/bt/esp_ble_mesh/mesh_core/net.c @@ -1527,3 +1527,29 @@ void bt_mesh_net_init(void) k_work_init(&bt_mesh.local_work, bt_mesh_net_local); } + +void bt_mesh_net_deinit(void) +{ + k_delayed_work_free(&bt_mesh.ivu_timer); + + k_work_init(&bt_mesh.local_work, NULL); + + /* Local queue uses a while loop, currently no need + * to handle this. + */ + +#if FRIEND_CRED_COUNT > 0 + memset(friend_cred, 0, sizeof(friend_cred)); +#endif + + memset(msg_cache, 0, sizeof(msg_cache)); + msg_cache_next = 0U; + + memset(dup_cache, 0, sizeof(dup_cache)); + dup_cache_next = 0U; + + bt_mesh.iv_index = 0U; + bt_mesh.seq = 0U; + + memset(bt_mesh.flags, 0, sizeof(bt_mesh.flags)); +} diff --git a/components/bt/esp_ble_mesh/mesh_core/net.h b/components/bt/esp_ble_mesh/mesh_core/net.h index 6064f5035c..b9ac823771 100644 --- a/components/bt/esp_ble_mesh/mesh_core/net.h +++ b/components/bt/esp_ble_mesh/mesh_core/net.h @@ -368,6 +368,8 @@ u32_t bt_mesh_next_seq(void); void bt_mesh_net_start(void); void bt_mesh_net_init(void); +void bt_mesh_net_deinit(void); + void bt_mesh_net_header_parse(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx); diff --git a/components/bt/esp_ble_mesh/mesh_core/prov.c b/components/bt/esp_ble_mesh/mesh_core/prov.c index d64359aeaf..9d7581bdea 100644 --- a/components/bt/esp_ble_mesh/mesh_core/prov.c +++ b/components/bt/esp_ble_mesh/mesh_core/prov.c @@ -221,6 +221,14 @@ static void bt_mesh_pb_buf_mutex_new(void) } } +static void bt_mesh_pb_buf_mutex_free(void) +{ + if (pb_buf_lock) { + osi_mutex_free(&pb_buf_lock); + pb_buf_lock = NULL; + } +} + static void bt_mesh_pb_buf_lock(void) { if (pb_buf_lock) { @@ -1780,6 +1788,36 @@ int bt_mesh_prov_init(const struct bt_mesh_prov *prov_info) return 0; } +int bt_mesh_prov_deinit(void) +{ + if (prov == NULL) { + BT_ERR("%s, No provisioning context provided", __func__); + return -EINVAL; + } + + k_delayed_work_free(&link.prot_timer); + +#if defined(CONFIG_BLE_MESH_PB_ADV) + prov_clear_tx(); + k_delayed_work_free(&link.tx.retransmit); +#if defined(CONFIG_BLE_MESH_USE_DUPLICATE_SCAN) + /* Remove the link id from exceptional list */ + bt_mesh_update_exceptional_list(BLE_MESH_EXCEP_LIST_REMOVE, + BLE_MESH_EXCEP_INFO_MESH_LINK_ID, &link.id); +#endif /* CONFIG_BLE_MESH_USE_DUPLICATE_SCAN */ +#endif /* CONFIG_BLE_MESH_PB_ADV */ + + (void)memset(&link, 0, sizeof(link)); + +#if defined(CONFIG_BLE_MESH_PB_ADV) + bt_mesh_pb_buf_mutex_free(); +#endif + + prov = NULL; + + return 0; +} + void bt_mesh_prov_complete(u16_t net_idx, const u8_t net_key[16], u16_t addr, u8_t flags, u32_t iv_index) { if (prov->complete) { diff --git a/components/bt/esp_ble_mesh/mesh_core/prov.h b/components/bt/esp_ble_mesh/mesh_core/prov.h index 756cd011f5..9079471742 100644 --- a/components/bt/esp_ble_mesh/mesh_core/prov.h +++ b/components/bt/esp_ble_mesh/mesh_core/prov.h @@ -27,6 +27,7 @@ int bt_mesh_set_oob_pub_key(const u8_t pub_key_x[32], const u8_t pub_key_y[32], const struct bt_mesh_prov *bt_mesh_prov_get(void); int bt_mesh_prov_init(const struct bt_mesh_prov *prov); +int bt_mesh_prov_deinit(void); void bt_mesh_prov_complete(u16_t net_idx, const u8_t net_key[16], u16_t addr, u8_t flags, u32_t iv_index); void bt_mesh_prov_reset(void); diff --git a/components/bt/esp_ble_mesh/mesh_core/provisioner_main.c b/components/bt/esp_ble_mesh/mesh_core/provisioner_main.c index a23f9045d9..6be6d2440e 100644 --- a/components/bt/esp_ble_mesh/mesh_core/provisioner_main.c +++ b/components/bt/esp_ble_mesh/mesh_core/provisioner_main.c @@ -51,6 +51,14 @@ static void bt_mesh_provisioner_mutex_new(void) } } +static void bt_mesh_provisioner_mutex_free(void) +{ + if (provisioner_lock) { + osi_mutex_free(&provisioner_lock); + provisioner_lock = NULL; + } +} + static void bt_mesh_provisioner_lock(void) { if (provisioner_lock) { @@ -439,6 +447,49 @@ done: return 0; } +int bt_mesh_provisioner_deinit(void) +{ + size_t i; + + for (i = 0U; i < CONFIG_BLE_MESH_PROVISIONER_SUBNET_COUNT; i++) { + if (bt_mesh.p_sub[i]) { + if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { + bt_mesh_clear_p_subnet(bt_mesh.p_sub[i]); + } + osi_free(bt_mesh.p_sub[i]); + bt_mesh.p_sub[i] = NULL; + } + } + + for (i = 0U; i < CONFIG_BLE_MESH_PROVISIONER_APP_KEY_COUNT; i++) { + if (bt_mesh.p_app_keys[i]) { + if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { + bt_mesh_clear_p_app_key(bt_mesh.p_app_keys[i]); + } + osi_free(bt_mesh.p_app_keys[i]); + bt_mesh.p_app_keys[i] = NULL; + } + } + + bt_mesh.p_net_idx_next = 0U; + bt_mesh.p_app_idx_next = 0U; + if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { + bt_mesh_clear_p_net_idx(); + bt_mesh_clear_p_app_idx(); + } + + for (i = 0U; i < CONFIG_BLE_MESH_MAX_STORED_NODES; i++) { + provisioner_remove_node(i); + } + + all_node_count = 0U; + prov_node_count = 0U; + + bt_mesh_provisioner_mutex_free(); + + return 0; +} + /* The following APIs are for provisioner upper layers internal use */ const u8_t *bt_mesh_provisioner_net_key_get(u16_t net_idx) diff --git a/components/bt/esp_ble_mesh/mesh_core/provisioner_main.h b/components/bt/esp_ble_mesh/mesh_core/provisioner_main.h index 90306785cf..00855ce4e5 100644 --- a/components/bt/esp_ble_mesh/mesh_core/provisioner_main.h +++ b/components/bt/esp_ble_mesh/mesh_core/provisioner_main.h @@ -55,6 +55,7 @@ int bt_mesh_provisioner_remove_node(const u8_t uuid[16]); struct bt_mesh_node *bt_mesh_provisioner_get_prov_node_info(const u8_t uuid[16]); int bt_mesh_provisioner_init(void); +int bt_mesh_provisioner_deinit(void); int bt_mesh_provisioner_net_create(void); diff --git a/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.c b/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.c index fb9bbca826..12b77af8be 100644 --- a/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.c +++ b/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.c @@ -373,6 +373,14 @@ static void bt_mesh_pb_adv_mutex_new(void) } } +static void bt_mesh_pb_adv_mutex_free(void) +{ + if (prov_ctx.pb_adv_lock) { + osi_mutex_free(&prov_ctx.pb_adv_lock); + prov_ctx.pb_adv_lock = NULL; + } +} + static void bt_mesh_pb_adv_lock(void) { if (prov_ctx.pb_adv_lock) { @@ -395,6 +403,14 @@ static void bt_mesh_pb_buf_mutex_new(void) } } +static void bt_mesh_pb_buf_mutex_free(void) +{ + if (prov_ctx.pb_buf_lock) { + osi_mutex_free(&prov_ctx.pb_buf_lock); + prov_ctx.pb_buf_lock = NULL; + } +} + static void bt_mesh_pb_buf_lock(void) { if (prov_ctx.pb_buf_lock) { @@ -419,6 +435,14 @@ static void bt_mesh_pb_gatt_mutex_new(void) } } +static void bt_mesh_pb_gatt_mutex_free(void) +{ + if (prov_ctx.pb_gatt_lock) { + osi_mutex_free(&prov_ctx.pb_gatt_lock); + prov_ctx.pb_gatt_lock = NULL; + } +} + static void bt_mesh_pb_gatt_lock(void) { if (prov_ctx.pb_gatt_lock) { @@ -3155,6 +3179,55 @@ int bt_mesh_provisioner_prov_init(const struct bt_mesh_prov *prov_info) return 0; } +int bt_mesh_provisioner_prov_deinit(void) +{ + size_t i; + + if (prov == NULL) { + BT_ERR("%s, No provisioning context provided", __func__); + return -EINVAL; + } + +#if defined(CONFIG_BLE_MESH_PB_ADV) + for (i = 0U; i < CONFIG_BLE_MESH_PBA_SAME_TIME; i++) { + prov_clear_tx(i); + k_delayed_work_free(&link[i].tx.retransmit); +#if defined(CONFIG_BLE_MESH_USE_DUPLICATE_SCAN) + /* Remove the link id from exceptional list */ + bt_mesh_update_exceptional_list(BLE_MESH_EXCEP_LIST_REMOVE, + BLE_MESH_EXCEP_INFO_MESH_LINK_ID, &link[i].link_id); +#endif /* CONFIG_BLE_MESH_USE_DUPLICATE_SCAN */ + } +#endif /* CONFIG_BLE_MESH_PB_ADV */ + + for (i = 0U; i < BLE_MESH_PROV_SAME_TIME; i++) { + prov_memory_free(i); + k_delayed_work_free(&link[i].timeout); + memset(&link[i], 0, sizeof(link[i])); + } + + if (prov_ctx.static_oob_val) { + osi_free(prov_ctx.static_oob_val); + prov_ctx.static_oob_val = NULL; + } + if (prov_ctx.match_value) { + osi_free(prov_ctx.match_value); + prov_ctx.match_value = NULL; + } +#if defined(CONFIG_BLE_MESH_PB_ADV) + bt_mesh_pb_adv_mutex_free(); + bt_mesh_pb_buf_mutex_free(); +#endif +#if defined(CONFIG_BLE_MESH_PB_GATT) + bt_mesh_pb_gatt_mutex_free(); +#endif + memset(&prov_ctx, 0, sizeof(prov_ctx)); + + prov = NULL; + + return 0; +} + static bool is_unprov_dev_info_callback_to_app(bt_mesh_prov_bearer_t bearer, const u8_t uuid[16], const bt_mesh_addr_t *addr, u16_t oob_info) { diff --git a/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.h b/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.h index 724bb38094..b819fc2dec 100644 --- a/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.h +++ b/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.h @@ -147,6 +147,14 @@ int bt_mesh_provisioner_pb_gatt_recv(struct bt_mesh_conn *conn, struct net_buf_s */ int bt_mesh_provisioner_prov_init(const struct bt_mesh_prov *prov_info); +/** + * @brief This function deinitializes provisioner's PB-GATT and PB-ADV + * related information. + * + * @return Zero - success, otherwise - fail + */ +int bt_mesh_provisioner_prov_deinit(void); + /** * @brief This function parses the received unprovisioned device * beacon advertising packets, and if checked, starts to provision this device diff --git a/components/bt/esp_ble_mesh/mesh_core/proxy_client.c b/components/bt/esp_ble_mesh/mesh_core/proxy_client.c index 76c55e2edb..2f6a66096b 100644 --- a/components/bt/esp_ble_mesh/mesh_core/proxy_client.c +++ b/components/bt/esp_ble_mesh/mesh_core/proxy_client.c @@ -995,4 +995,22 @@ int bt_mesh_proxy_prov_client_init(void) return 0; } +int bt_mesh_proxy_prov_client_deinit(void) +{ + size_t i; + + /* Initialize the server receive buffers */ + for (i = 0U; i < ARRAY_SIZE(servers); i++) { + struct bt_mesh_proxy_server *server = &servers[i]; + k_delayed_work_free(&server->sar_timer); + memset(server, 0, sizeof(struct bt_mesh_proxy_server)); + } + + memset(server_buf_data, 0, sizeof(server_buf_data)); + + bt_mesh_gattc_conn_cb_deregister(); + + return 0; +} + #endif /* (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || CONFIG_BLE_MESH_GATT_PROXY_CLIENT */ diff --git a/components/bt/esp_ble_mesh/mesh_core/proxy_client.h b/components/bt/esp_ble_mesh/mesh_core/proxy_client.h index b8c9b4676d..d3a1efaf10 100644 --- a/components/bt/esp_ble_mesh/mesh_core/proxy_client.h +++ b/components/bt/esp_ble_mesh/mesh_core/proxy_client.h @@ -98,5 +98,6 @@ bool bt_mesh_proxy_client_send(struct net_buf_simple *buf, u16_t dst); int bt_mesh_proxy_client_send_cfg(u8_t conn_handle, u16_t net_idx, struct bt_mesh_proxy_cfg_pdu *pdu); int bt_mesh_proxy_prov_client_init(void); +int bt_mesh_proxy_prov_client_deinit(void); #endif /* _PROVISIONER_PROXY_H_ */ diff --git a/components/bt/esp_ble_mesh/mesh_core/proxy_server.c b/components/bt/esp_ble_mesh/mesh_core/proxy_server.c index 73562b3593..f5b692f0a0 100644 --- a/components/bt/esp_ble_mesh/mesh_core/proxy_server.c +++ b/components/bt/esp_ble_mesh/mesh_core/proxy_server.c @@ -1434,4 +1434,33 @@ int bt_mesh_proxy_init(void) return bt_mesh_gatts_set_local_device_name(device_name); } +int bt_mesh_proxy_deinit(void) +{ + int i; + + proxy_adv_enabled = false; + gatt_svc = MESH_GATT_NONE; + +#if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER) + bt_mesh_gatts_service_deregister(&proxy_svc); +#endif + +#if defined(CONFIG_BLE_MESH_PB_GATT) + bt_mesh_gatts_service_deregister(&prov_svc); +#endif + + for (i = 0; i < ARRAY_SIZE(clients); i++) { + struct bt_mesh_proxy_client *client = &clients[i]; + k_delayed_work_free(&client->sar_timer); + memset(client, 0, sizeof(struct bt_mesh_proxy_client)); + } + + memset(client_buf_data, 0, sizeof(client_buf_data)); + memset(device_name, 0, sizeof(device_name)); + + bt_mesh_gatts_conn_cb_deregister(); + + return 0; +} + #endif /* CONFIG_BLE_MESH_NODE */ diff --git a/components/bt/esp_ble_mesh/mesh_core/proxy_server.h b/components/bt/esp_ble_mesh/mesh_core/proxy_server.h index 41b89c3693..158f89b127 100644 --- a/components/bt/esp_ble_mesh/mesh_core/proxy_server.h +++ b/components/bt/esp_ble_mesh/mesh_core/proxy_server.h @@ -61,5 +61,6 @@ bool bt_mesh_proxy_relay(struct net_buf_simple *buf, u16_t dst); void bt_mesh_proxy_addr_add(struct net_buf_simple *buf, u16_t addr); int bt_mesh_proxy_init(void); +int bt_mesh_proxy_deinit(void); #endif /* _PROXY_H_ */ diff --git a/components/bt/esp_ble_mesh/mesh_core/settings.c b/components/bt/esp_ble_mesh/mesh_core/settings.c index df1d7bea83..4ebd221e0b 100644 --- a/components/bt/esp_ble_mesh/mesh_core/settings.c +++ b/components/bt/esp_ble_mesh/mesh_core/settings.c @@ -2247,6 +2247,11 @@ void bt_mesh_store_p_net_idx(void) (const u8_t *)&bt_mesh.p_net_idx_next, sizeof(bt_mesh.p_net_idx_next)); } +void bt_mesh_clear_p_net_idx(void) +{ + bt_mesh_save_core_settings("mesh/p_netidx", NULL, 0); +} + void bt_mesh_store_p_app_idx(void) { BT_DBG("p_app_idx_next 0x%03x", bt_mesh.p_app_idx_next); @@ -2255,6 +2260,11 @@ void bt_mesh_store_p_app_idx(void) (const u8_t *)&bt_mesh.p_app_idx_next, sizeof(bt_mesh.p_app_idx_next)); } +void bt_mesh_clear_p_app_idx(void) +{ + bt_mesh_save_core_settings("mesh/p_appidx", NULL, 0); +} + void bt_mesh_store_p_subnet(struct bt_mesh_subnet *sub) { if (sub == NULL) { @@ -2400,4 +2410,18 @@ int bt_mesh_settings_init(void) return 0; } +int settings_core_deinit(void) +{ + k_delayed_work_free(&pending_store); + + return 0; +} + +int bt_mesh_settings_deinit(void) +{ + bt_mesh_settings_deforeach(); + + return 0; +} + #endif /* CONFIG_BLE_MESH_SETTINGS */ diff --git a/components/bt/esp_ble_mesh/mesh_core/settings.h b/components/bt/esp_ble_mesh/mesh_core/settings.h index b72845096c..844bc90a70 100644 --- a/components/bt/esp_ble_mesh/mesh_core/settings.h +++ b/components/bt/esp_ble_mesh/mesh_core/settings.h @@ -17,6 +17,7 @@ int settings_core_init(void); int settings_core_load(void); int settings_core_commit(void); +int settings_core_deinit(void); void bt_mesh_store_role(u8_t role); void bt_mesh_store_net(void); @@ -41,7 +42,9 @@ void bt_mesh_clear_rpl(void); #if CONFIG_BLE_MESH_PROVISIONER void bt_mesh_store_prov_info(u16_t curr_addr); void bt_mesh_store_p_net_idx(void); +void bt_mesh_clear_p_net_idx(void); void bt_mesh_store_p_app_idx(void); +void bt_mesh_clear_p_app_idx(void); void bt_mesh_store_p_subnet(struct bt_mesh_subnet *sub); void bt_mesh_store_p_app_key(struct bt_mesh_app_key *key); void bt_mesh_clear_p_subnet(struct bt_mesh_subnet *sub); @@ -52,5 +55,6 @@ void bt_mesh_clear_node_info(u16_t unicast_addr, bool prov); #endif int bt_mesh_settings_init(void); +int bt_mesh_settings_deinit(void); #endif /* _SETTINGS_H_ */ diff --git a/components/bt/esp_ble_mesh/mesh_core/storage/settings_nvs.c b/components/bt/esp_ble_mesh/mesh_core/storage/settings_nvs.c index 96ef197ad0..f0e1f87f5a 100644 --- a/components/bt/esp_ble_mesh/mesh_core/storage/settings_nvs.c +++ b/components/bt/esp_ble_mesh/mesh_core/storage/settings_nvs.c @@ -41,6 +41,8 @@ struct settings_context { int (*settings_init)(void); int (*settings_load)(void); int (*settings_commit)(void); + int (*settings_deinit)(void); + int (*settings_erase)(void); }; static struct settings_context settings_ctx[] = { @@ -49,6 +51,7 @@ static struct settings_context settings_ctx[] = { .settings_init = settings_core_init, .settings_load = settings_core_load, .settings_commit = settings_core_commit, + .settings_deinit = settings_core_deinit, }, [SETTINGS_SERVER] = { .nvs_name = "mesh_server", @@ -90,6 +93,22 @@ void bt_mesh_settings_foreach(void) } } +void bt_mesh_settings_deforeach(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(settings_ctx); i++) { + struct settings_context *ctx = &settings_ctx[i]; + + if (ctx->settings_deinit && ctx->settings_deinit()) { + BT_ERR("%s, Deinit settings failed, name %s", __func__, ctx->nvs_name); + continue; + } + + nvs_close(ctx->handle); + } +} + /* API used to get BLE Mesh related nvs handle */ static inline nvs_handle settings_get_nvs_handle(enum settings_type type) diff --git a/components/bt/esp_ble_mesh/mesh_core/storage/settings_nvs.h b/components/bt/esp_ble_mesh/mesh_core/storage/settings_nvs.h index c4d5ad064f..7fa236de95 100644 --- a/components/bt/esp_ble_mesh/mesh_core/storage/settings_nvs.h +++ b/components/bt/esp_ble_mesh/mesh_core/storage/settings_nvs.h @@ -30,6 +30,7 @@ extern "C" { #define BLE_MESH_GET_MODEL_KEY(a, b) ((u16_t)(((u16_t)((a) << 8)) | b)) void bt_mesh_settings_foreach(void); +void bt_mesh_settings_deforeach(void); int bt_mesh_save_core_settings(const char *key, const u8_t *val, size_t len); diff --git a/components/bt/esp_ble_mesh/mesh_core/transport.c b/components/bt/esp_ble_mesh/mesh_core/transport.c index bda7533a96..4e6f15b3c5 100644 --- a/components/bt/esp_ble_mesh/mesh_core/transport.c +++ b/components/bt/esp_ble_mesh/mesh_core/transport.c @@ -120,6 +120,14 @@ static void bt_mesh_tx_seg_mutex_new(void) } } +static void bt_mesh_tx_seg_mutex_free(void) +{ + if (tx_seg_lock) { + osi_mutex_free(&tx_seg_lock); + tx_seg_lock = NULL; + } +} + static void bt_mesh_tx_seg_lock(void) { if (tx_seg_lock) { @@ -1611,6 +1619,24 @@ void bt_mesh_trans_init(void) bt_mesh_tx_seg_mutex_new(); } +void bt_mesh_trans_deinit(void) +{ + size_t i; + + bt_mesh_rx_reset(); + bt_mesh_tx_reset(); + + for (i = 0U; i < ARRAY_SIZE(seg_tx); i++) { + k_delayed_work_free(&seg_tx[i].retransmit); + } + + for (i = 0U; i < ARRAY_SIZE(seg_rx); i++) { + k_delayed_work_free(&seg_rx[i].ack); + } + + bt_mesh_tx_seg_mutex_free(); +} + void bt_mesh_rpl_clear(void) { BT_DBG("%s", __func__); diff --git a/components/bt/esp_ble_mesh/mesh_core/transport.h b/components/bt/esp_ble_mesh/mesh_core/transport.h index 6fc81fdf2b..7869a7e6e3 100644 --- a/components/bt/esp_ble_mesh/mesh_core/transport.h +++ b/components/bt/esp_ble_mesh/mesh_core/transport.h @@ -97,6 +97,7 @@ int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct net_buf_simple *msg, int bt_mesh_trans_recv(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx); void bt_mesh_trans_init(void); +void bt_mesh_trans_deinit(void); void bt_mesh_rpl_clear(void); diff --git a/components/bt/esp_ble_mesh/mesh_models/client/client_common.c b/components/bt/esp_ble_mesh/mesh_models/client/client_common.c index 649c58c760..c7c8b9afde 100644 --- a/components/bt/esp_ble_mesh/mesh_models/client/client_common.c +++ b/components/bt/esp_ble_mesh/mesh_models/client/client_common.c @@ -242,6 +242,14 @@ static void bt_mesh_client_model_mutex_new(void) } } +static void bt_mesh_client_model_mutex_free(void) +{ + if (client_model_lock) { + osi_mutex_free(&client_model_lock); + client_model_lock = NULL; + } +} + void bt_mesh_client_model_lock(void) { if (client_model_lock) { @@ -298,6 +306,35 @@ int bt_mesh_client_init(struct bt_mesh_model *model) return 0; } +int bt_mesh_client_deinit(struct bt_mesh_model *model) +{ + bt_mesh_client_user_data_t *client = NULL; + + if (!model) { + BT_ERR("%s, Invalid parameter", __func__); + return -EINVAL; + } + + client = (bt_mesh_client_user_data_t *)model->user_data; + if (!client) { + BT_ERR("%s, Client user_data is NULL", __func__); + return -EINVAL; + } + + if (client->internal_data) { + /* Remove items from the list */ + bt_mesh_client_clear_list(client->internal_data); + + /* Free the allocated internal data */ + osi_free(client->internal_data); + client->internal_data = NULL; + } + + bt_mesh_client_model_mutex_free(); + + return 0; +} + int bt_mesh_client_free_node(bt_mesh_client_node_t *node) { bt_mesh_client_internal_data_t *internal = NULL; diff --git a/components/bt/esp_ble_mesh/mesh_models/client/generic_client.c b/components/bt/esp_ble_mesh/mesh_models/client/generic_client.c index 6862dca739..5105072b5e 100644 --- a/components/bt/esp_ble_mesh/mesh_models/client/generic_client.c +++ b/components/bt/esp_ble_mesh/mesh_models/client/generic_client.c @@ -130,6 +130,14 @@ static void bt_mesh_generic_client_mutex_new(void) } } +static void bt_mesh_generic_client_mutex_free(void) +{ + if (generic_client_lock) { + osi_mutex_free(&generic_client_lock); + generic_client_lock = NULL; + } +} + static void bt_mesh_generic_client_lock(void) { if (generic_client_lock) { @@ -1235,3 +1243,72 @@ int bt_mesh_gen_property_cli_init(struct bt_mesh_model *model, bool primary) { return generic_client_init(model, primary); } + +static int generic_client_deinit(struct bt_mesh_model *model, bool primary) +{ + bt_mesh_generic_client_t *client = NULL; + + if (!model) { + BT_ERR("%s, Invalid parameter", __func__); + return -EINVAL; + } + + client = (bt_mesh_generic_client_t *)model->user_data; + if (!client) { + BT_ERR("%s, Generic Client user_data is NULL", __func__); + return -EINVAL; + } + + if (client->internal_data) { + /* Remove items from the list */ + bt_mesh_client_clear_list(client->internal_data); + + /* Free the allocated internal data */ + osi_free(client->internal_data); + client->internal_data = NULL; + } + + bt_mesh_generic_client_mutex_free(); + + return 0; +} + +int bt_mesh_gen_onoff_cli_deinit(struct bt_mesh_model *model, bool primary) +{ + return generic_client_deinit(model, primary); +} + +int bt_mesh_gen_level_cli_deinit(struct bt_mesh_model *model, bool primary) +{ + return generic_client_deinit(model, primary); +} + +int bt_mesh_gen_def_trans_time_cli_deinit(struct bt_mesh_model *model, bool primary) +{ + return generic_client_deinit(model, primary); +} + +int bt_mesh_gen_pwr_onoff_cli_deinit(struct bt_mesh_model *model, bool primary) +{ + return generic_client_deinit(model, primary); +} + +int bt_mesh_gen_pwr_level_cli_deinit(struct bt_mesh_model *model, bool primary) +{ + return generic_client_deinit(model, primary); +} + +int bt_mesh_gen_battery_cli_deinit(struct bt_mesh_model *model, bool primary) +{ + return generic_client_deinit(model, primary); +} + +int bt_mesh_gen_location_cli_deinit(struct bt_mesh_model *model, bool primary) +{ + return generic_client_deinit(model, primary); +} + +int bt_mesh_gen_property_cli_deinit(struct bt_mesh_model *model, bool primary) +{ + return generic_client_deinit(model, primary); +} diff --git a/components/bt/esp_ble_mesh/mesh_models/client/include/client_common.h b/components/bt/esp_ble_mesh/mesh_models/client/include/client_common.h index 86fae9bad6..0e337d34bc 100644 --- a/components/bt/esp_ble_mesh/mesh_models/client/include/client_common.h +++ b/components/bt/esp_ble_mesh/mesh_models/client/include/client_common.h @@ -84,6 +84,8 @@ void bt_mesh_client_model_unlock(void); int bt_mesh_client_init(struct bt_mesh_model *model); +int bt_mesh_client_deinit(struct bt_mesh_model *model); + /** * @brief Check if the msg received by client model is a publish msg or not * diff --git a/components/bt/esp_ble_mesh/mesh_models/client/include/generic_client.h b/components/bt/esp_ble_mesh/mesh_models/client/include/generic_client.h index a5c72b638d..27a56ad1a7 100644 --- a/components/bt/esp_ble_mesh/mesh_models/client/include/generic_client.h +++ b/components/bt/esp_ble_mesh/mesh_models/client/include/generic_client.h @@ -466,6 +466,87 @@ int bt_mesh_gen_location_cli_init(struct bt_mesh_model *model, bool primary); */ int bt_mesh_gen_property_cli_init(struct bt_mesh_model *model, bool primary); +/** + * @brief This function is called to de-initialize generic onoff client model user_data. + * + * @param[in] model: Pointer to generic onoff client model + * @param[in] primary: Whether belongs to primary element + * + * @return Zero-success, other-fail + */ +int bt_mesh_gen_onoff_cli_deinit(struct bt_mesh_model *model, bool primary); + +/** + * @brief This function is called to de-initialize generic level client model user_data. + * + * @param[in] model: Pointer to generic level client model + * @param[in] primary: Whether belongs to primary element + * + * @return Zero-success, other-fail + */ +int bt_mesh_gen_level_cli_deinit(struct bt_mesh_model *model, bool primary); + +/** + * @brief This function is called to de-initialize generic default transition time + * client model user_data. + * + * @param[in] model: Pointer to generic default transition time client model + * @param[in] primary: Whether belongs to primary element + * + * @return Zero-success, other-fail + */ +int bt_mesh_gen_def_trans_time_cli_deinit(struct bt_mesh_model *model, bool primary); + +/** + * @brief This function is called to de-initialize generic power onoff client model user_data. + * + * @param[in] model: Pointer to generic power onoff client model + * @param[in] primary: Whether belongs to primary element + * + * @return Zero-success, other-fail + */ +int bt_mesh_gen_pwr_onoff_cli_deinit(struct bt_mesh_model *model, bool primary); + +/** + * @brief This function is called to de-initialize generic power level client model user_data. + * + * @param[in] model: Pointer to generic power level client model + * @param[in] primary: Whether belongs to primary element + * + * @return Zero-success, other-fail + */ +int bt_mesh_gen_pwr_level_cli_deinit(struct bt_mesh_model *model, bool primary); + +/** + * @brief This function is called to de-initialize generic battery client model user_data. + * + * @param[in] model: Pointer to generic battery client model + * @param[in] primary: Whether belongs to primary element + * + * @return Zero-success, other-fail + */ +int bt_mesh_gen_battery_cli_deinit(struct bt_mesh_model *model, bool primary); + +/** + * @brief This function is called to de-initialize generic location client model user_data. + * + * @param[in] model: Pointer to generic location client model + * @param[in] primary: Whether belongs to primary element + * + * @return Zero-success, other-fail + */ +int bt_mesh_gen_location_cli_deinit(struct bt_mesh_model *model, bool primary); + +/** + * @brief This function is called to de-initialize generic property client model user_data. + * + * @param[in] model: Pointer to generic property client model + * @param[in] primary: Whether belongs to primary element + * + * @return Zero-success, other-fail + */ +int bt_mesh_gen_property_cli_deinit(struct bt_mesh_model *model, bool primary); + /** * @brief This function is called to get generic states. * diff --git a/components/bt/esp_ble_mesh/mesh_models/client/include/lighting_client.h b/components/bt/esp_ble_mesh/mesh_models/client/include/lighting_client.h index 8502052155..7d24c408ff 100644 --- a/components/bt/esp_ble_mesh/mesh_models/client/include/lighting_client.h +++ b/components/bt/esp_ble_mesh/mesh_models/client/include/lighting_client.h @@ -467,6 +467,56 @@ int bt_mesh_light_xyl_cli_init(struct bt_mesh_model *model, bool primary); */ int bt_mesh_light_lc_cli_init(struct bt_mesh_model *model, bool primary); +/** + * @brief This function is called to de-initialize light lightness client model user_data. + * + * @param[in] model: Pointer to light lightness client model + * @param[in] primary: Whether belongs to primary element + * + * @return Zero-success, other-fail + */ +int bt_mesh_light_lightness_cli_deinit(struct bt_mesh_model *model, bool primary); + +/** + * @brief This function is called to de-initialize light ctl client model user_data. + * + * @param[in] model: Pointer to light ctl client model + * @param[in] primary: Whether belongs to primary element + * + * @return Zero-success, other-fail + */ +int bt_mesh_light_ctl_cli_deinit(struct bt_mesh_model *model, bool primary); + +/** + * @brief This function is called to de-initialize light hsl client model user_data. + * + * @param[in] model: Pointer to light hsl client model + * @param[in] primary: Whether belongs to primary element + * + * @return Zero-success, other-fail + */ +int bt_mesh_light_hsl_cli_deinit(struct bt_mesh_model *model, bool primary); + +/** + * @brief This function is called to de-initialize light xyl client model user_data. + * + * @param[in] model: Pointer to light xyl client model + * @param[in] primary: Whether belongs to primary element + * + * @return Zero-success, other-fail + */ +int bt_mesh_light_xyl_cli_deinit(struct bt_mesh_model *model, bool primary); + +/** + * @brief This function is called to de-initialize light lc client model user_data. + * + * @param[in] model: Pointer to light lc client model + * @param[in] primary: Whether belongs to primary element + * + * @return Zero-success, other-fail + */ +int bt_mesh_light_lc_cli_deinit(struct bt_mesh_model *model, bool primary); + /** * @brief This function is called to get light states. * diff --git a/components/bt/esp_ble_mesh/mesh_models/client/include/sensor_client.h b/components/bt/esp_ble_mesh/mesh_models/client/include/sensor_client.h index 39855bd9a7..3bcd96cd14 100644 --- a/components/bt/esp_ble_mesh/mesh_models/client/include/sensor_client.h +++ b/components/bt/esp_ble_mesh/mesh_models/client/include/sensor_client.h @@ -142,6 +142,16 @@ struct bt_mesh_sensor_series_get { */ int bt_mesh_sensor_cli_init(struct bt_mesh_model *model, bool primary); +/** + * @brief This function is called to de-initialize sensor client model user_data. + * + * @param[in] model: Pointer to sensor client model + * @param[in] primary: Whether belongs to primary element + * + * @return Zero-success, other-fail + */ +int bt_mesh_sensor_cli_deinit(struct bt_mesh_model *model, bool primary); + /** * @brief This function is called to get sensor states. * diff --git a/components/bt/esp_ble_mesh/mesh_models/client/include/time_scene_client.h b/components/bt/esp_ble_mesh/mesh_models/client/include/time_scene_client.h index 182316e05d..094d43bc98 100644 --- a/components/bt/esp_ble_mesh/mesh_models/client/include/time_scene_client.h +++ b/components/bt/esp_ble_mesh/mesh_models/client/include/time_scene_client.h @@ -232,6 +232,36 @@ int bt_mesh_scene_cli_init(struct bt_mesh_model *model, bool primary); */ int bt_mesh_scheduler_cli_init(struct bt_mesh_model *model, bool primary); +/** + * @brief This function is called to de-initialize time client model user_data. + * + * @param[in] model: Pointer to time client model + * @param[in] primary: Whether belongs to primary element + * + * @return Zero-success, other-fail + */ +int bt_mesh_time_cli_deinit(struct bt_mesh_model *model, bool primary); + +/** + * @brief This function is called to de-initialize scene client model user_data. + * + * @param[in] model: Pointer to scene client model + * @param[in] primary: Whether belongs to primary element + * + * @return Zero-success, other-fail + */ +int bt_mesh_scene_cli_deinit(struct bt_mesh_model *model, bool primary); + +/** + * @brief This function is called to de-initialize scheduler client model user_data. + * + * @param[in] model: Pointer to scheduler client model + * @param[in] primary: Whether belongs to primary element + * + * @return Zero-success, other-fail + */ +int bt_mesh_scheduler_cli_deinit(struct bt_mesh_model *model, bool primary); + /** * @brief This function is called to get scene states. * diff --git a/components/bt/esp_ble_mesh/mesh_models/client/lighting_client.c b/components/bt/esp_ble_mesh/mesh_models/client/lighting_client.c index 9816466fa0..203959ba34 100644 --- a/components/bt/esp_ble_mesh/mesh_models/client/lighting_client.c +++ b/components/bt/esp_ble_mesh/mesh_models/client/lighting_client.c @@ -139,6 +139,14 @@ static void bt_mesh_light_client_mutex_new(void) } } +static void bt_mesh_light_client_mutex_free(void) +{ + if (light_client_lock) { + osi_mutex_free(&light_client_lock); + light_client_lock = NULL; + } +} + static void bt_mesh_light_client_lock(void) { if (light_client_lock) { @@ -1409,4 +1417,58 @@ int bt_mesh_light_xyl_cli_init(struct bt_mesh_model *model, bool primary) int bt_mesh_light_lc_cli_init(struct bt_mesh_model *model, bool primary) { return light_client_init(model, primary); +} + +static int light_client_deinit(struct bt_mesh_model *model, bool primary) +{ + bt_mesh_light_client_t *client = NULL; + + if (!model) { + BT_ERR("%s, Invalid parameter", __func__); + return -EINVAL; + } + + client = (bt_mesh_light_client_t *)model->user_data; + if (!client) { + BT_ERR("%s, Lighting Client user_data is NULL", __func__); + return -EINVAL; + } + + if (client->internal_data) { + /* Remove items from the list */ + bt_mesh_client_clear_list(client->internal_data); + + /* Free the allocated internal data */ + osi_free(client->internal_data); + client->internal_data = NULL; + } + + bt_mesh_light_client_mutex_free(); + + return 0; +} + +int bt_mesh_light_lightness_cli_deinit(struct bt_mesh_model *model, bool primary) +{ + return light_client_deinit(model, primary); +} + +int bt_mesh_light_ctl_cli_deinit(struct bt_mesh_model *model, bool primary) +{ + return light_client_deinit(model, primary); +} + +int bt_mesh_light_hsl_cli_deinit(struct bt_mesh_model *model, bool primary) +{ + return light_client_deinit(model, primary); +} + +int bt_mesh_light_xyl_cli_deinit(struct bt_mesh_model *model, bool primary) +{ + return light_client_deinit(model, primary); +} + +int bt_mesh_light_lc_cli_deinit(struct bt_mesh_model *model, bool primary) +{ + return light_client_deinit(model, primary); } \ No newline at end of file diff --git a/components/bt/esp_ble_mesh/mesh_models/client/sensor_client.c b/components/bt/esp_ble_mesh/mesh_models/client/sensor_client.c index 1017591e06..ca6186c00a 100644 --- a/components/bt/esp_ble_mesh/mesh_models/client/sensor_client.c +++ b/components/bt/esp_ble_mesh/mesh_models/client/sensor_client.c @@ -68,6 +68,14 @@ static void bt_mesh_sensor_client_mutex_new(void) } } +static void bt_mesh_sensor_client_mutex_free(void) +{ + if (sensor_client_lock) { + osi_mutex_free(&sensor_client_lock); + sensor_client_lock = NULL; + } +} + static void bt_mesh_sensor_client_lock(void) { if (sensor_client_lock) { @@ -625,5 +633,34 @@ int bt_mesh_sensor_cli_init(struct bt_mesh_model *model, bool primary) bt_mesh_sensor_client_mutex_new(); + return 0; +} + +int bt_mesh_sensor_cli_deinit(struct bt_mesh_model *model, bool primary) +{ + bt_mesh_sensor_client_t *client = NULL; + + if (!model) { + BT_ERR("%s, Invalid parameter", __func__); + return -EINVAL; + } + + client = (bt_mesh_sensor_client_t *)model->user_data; + if (!client) { + BT_ERR("%s, Sensor Client user_data is NULL", __func__); + return -EINVAL; + } + + if (client->internal_data) { + /* Remove items from the list */ + bt_mesh_client_clear_list(client->internal_data); + + /* Free the allocated internal data */ + osi_free(client->internal_data); + client->internal_data = NULL; + } + + bt_mesh_sensor_client_mutex_free(); + return 0; } \ No newline at end of file diff --git a/components/bt/esp_ble_mesh/mesh_models/client/time_scene_client.c b/components/bt/esp_ble_mesh/mesh_models/client/time_scene_client.c index 035f970bd1..7971a6ee58 100644 --- a/components/bt/esp_ble_mesh/mesh_models/client/time_scene_client.c +++ b/components/bt/esp_ble_mesh/mesh_models/client/time_scene_client.c @@ -84,6 +84,14 @@ static void bt_mesh_time_scene_client_mutex_new(void) } } +static void bt_mesh_time_scene_client_mutex_free(void) +{ + if (time_scene_client_lock) { + osi_mutex_free(&time_scene_client_lock); + time_scene_client_lock = NULL; + } +} + static void bt_mesh_time_scene_client_lock(void) { if (time_scene_client_lock) { @@ -704,4 +712,48 @@ int bt_mesh_scene_cli_init(struct bt_mesh_model *model, bool primary) int bt_mesh_scheduler_cli_init(struct bt_mesh_model *model, bool primary) { return time_scene_client_init(model, primary); +} + +static int time_scene_client_deinit(struct bt_mesh_model *model, bool primary) +{ + bt_mesh_time_scene_client_t *client = NULL; + + if (!model) { + BT_ERR("%s, Invalid parameter", __func__); + return -EINVAL; + } + + client = (bt_mesh_time_scene_client_t *)model->user_data; + if (!client) { + BT_ERR("%s, Time Scene Client user_data is NULL", __func__); + return -EINVAL; + } + + if (client->internal_data) { + /* Remove items from the list */ + bt_mesh_client_clear_list(client->internal_data); + + /* Free the allocated internal data */ + osi_free(client->internal_data); + client->internal_data = NULL; + } + + bt_mesh_time_scene_client_mutex_free(); + + return 0; +} + +int bt_mesh_time_cli_deinit(struct bt_mesh_model *model, bool primary) +{ + return time_scene_client_deinit(model, primary); +} + +int bt_mesh_scene_cli_deinit(struct bt_mesh_model *model, bool primary) +{ + return time_scene_client_deinit(model, primary); +} + +int bt_mesh_scheduler_cli_deinit(struct bt_mesh_model *model, bool primary) +{ + return time_scene_client_deinit(model, primary); } \ No newline at end of file diff --git a/components/bt/esp_ble_mesh/mesh_models/server/generic_server.c b/components/bt/esp_ble_mesh/mesh_models/server/generic_server.c index 54b3a417dd..1d4b47b90f 100644 --- a/components/bt/esp_ble_mesh/mesh_models/server/generic_server.c +++ b/components/bt/esp_ble_mesh/mesh_models/server/generic_server.c @@ -39,6 +39,14 @@ static void bt_mesh_generic_server_mutex_new(void) } } +static void bt_mesh_generic_server_mutex_free(void) +{ + if (generic_server_lock) { + osi_mutex_free(&generic_server_lock); + generic_server_lock = NULL; + } +} + void bt_mesh_generic_server_lock(void) { if (generic_server_lock) { @@ -2634,4 +2642,175 @@ int bt_mesh_gen_client_prop_srv_init(struct bt_mesh_model *model, bool primary) } return generic_server_init(model); +} + +static int generic_server_deinit(struct bt_mesh_model *model) +{ + if (model->user_data == NULL) { + BT_ERR("%s, No Generic Server context provided, model_id 0x%04x", __func__, model->id); + return -EINVAL; + } + + switch (model->id) { + case BLE_MESH_MODEL_ID_GEN_ONOFF_SRV: { + struct bt_mesh_gen_onoff_srv *srv = model->user_data; + if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) { + bt_mesh_server_free_ctx(&srv->transition.timer.work); + k_delayed_work_free(&srv->transition.timer); + } + break; + } + case BLE_MESH_MODEL_ID_GEN_LEVEL_SRV: { + struct bt_mesh_gen_level_srv *srv = model->user_data; + if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) { + bt_mesh_server_free_ctx(&srv->transition.timer.work); + k_delayed_work_free(&srv->transition.timer); + } + break; + } + case BLE_MESH_MODEL_ID_GEN_POWER_LEVEL_SRV: { + struct bt_mesh_gen_power_level_srv *srv = model->user_data; + if (srv->state == NULL) { + BT_ERR("%s, NULL Generic Power Level State", __func__); + return -EINVAL; + } + if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) { + bt_mesh_server_free_ctx(&srv->transition.timer.work); + k_delayed_work_free(&srv->transition.timer); + } + break; + } + default: + BT_WARN("%s, Unknown Generic Server Model, model_id 0x%04x", __func__, model->id); + return -EINVAL; + } + + bt_mesh_generic_server_mutex_free(); + + return 0; +} + +int bt_mesh_gen_onoff_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + if (model->pub == NULL) { + BT_ERR("%s, Generic OnOff Server has no publication support", __func__); + return -EINVAL; + } + + return generic_server_deinit(model); +} + +int bt_mesh_gen_level_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + if (model->pub == NULL) { + BT_ERR("%s, Generic Level Server has no publication support", __func__); + return -EINVAL; + } + + return generic_server_deinit(model); +} + +int bt_mesh_gen_def_trans_time_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + if (model->pub == NULL) { + BT_ERR("%s, Generic Default Trans Time Server has no publication support", __func__); + return -EINVAL; + } + + return generic_server_deinit(model); +} + +int bt_mesh_gen_power_onoff_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + if (model->pub == NULL) { + BT_ERR("%s, Generic Power OnOff Server has no publication support", __func__); + return -EINVAL; + } + + return generic_server_deinit(model); +} + +int bt_mesh_gen_power_onoff_setup_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + return generic_server_deinit(model); +} + +int bt_mesh_gen_power_level_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + if (model->pub == NULL) { + BT_ERR("%s, Generic Power Level Server has no publication support", __func__); + return -EINVAL; + } + + return generic_server_deinit(model); +} + +int bt_mesh_gen_power_level_setup_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + return generic_server_deinit(model); +} + +int bt_mesh_gen_battery_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + if (model->pub == NULL) { + BT_ERR("%s, Generic Battery Server has no publication support", __func__); + return -EINVAL; + } + + return generic_server_deinit(model); +} + +int bt_mesh_gen_location_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + if (model->pub == NULL) { + BT_ERR("%s, Generic Location Server has no publication support", __func__); + return -EINVAL; + } + + return generic_server_deinit(model); +} + +int bt_mesh_gen_location_setup_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + return generic_server_deinit(model); +} + +int bt_mesh_gen_user_prop_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + if (model->pub == NULL) { + BT_ERR("%s, Generic User Property has no publication support", __func__); + return -EINVAL; + } + + return generic_server_deinit(model); +} + +int bt_mesh_gen_admin_prop_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + if (model->pub == NULL) { + BT_ERR("%s, Generic Admin Property has no publication support", __func__); + return -EINVAL; + } + + return generic_server_deinit(model); +} + +int bt_mesh_gen_manu_prop_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + if (model->pub == NULL) { + BT_ERR("%s, Generic Manufacturer Property has no publication support", __func__); + return -EINVAL; + } + + return generic_server_deinit(model); +} + +int bt_mesh_gen_client_prop_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + if (model->pub == NULL) { + BT_ERR("%s, Generic Client Property has no publication support", __func__); + return -EINVAL; + } + + return generic_server_deinit(model); } \ No newline at end of file diff --git a/components/bt/esp_ble_mesh/mesh_models/server/include/generic_server.h b/components/bt/esp_ble_mesh/mesh_models/server/include/generic_server.h index a1465aba7d..4ab53eddab 100644 --- a/components/bt/esp_ble_mesh/mesh_models/server/include/generic_server.h +++ b/components/bt/esp_ble_mesh/mesh_models/server/include/generic_server.h @@ -371,4 +371,19 @@ int bt_mesh_gen_admin_prop_srv_init(struct bt_mesh_model *model, bool primary); int bt_mesh_gen_manu_prop_srv_init(struct bt_mesh_model *model, bool primary); int bt_mesh_gen_client_prop_srv_init(struct bt_mesh_model *model, bool primary); +int bt_mesh_gen_onoff_srv_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_gen_level_srv_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_gen_def_trans_time_srv_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_gen_power_onoff_srv_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_gen_power_onoff_setup_srv_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_gen_power_level_srv_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_gen_power_level_setup_srv_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_gen_battery_srv_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_gen_location_srv_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_gen_location_setup_srv_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_gen_user_prop_srv_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_gen_admin_prop_srv_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_gen_manu_prop_srv_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_gen_client_prop_srv_deinit(struct bt_mesh_model *model, bool primary); + #endif /* _GENERIC_SERVER_H_ */ diff --git a/components/bt/esp_ble_mesh/mesh_models/server/include/lighting_server.h b/components/bt/esp_ble_mesh/mesh_models/server/include/lighting_server.h index 9ac1124661..dd39ce0068 100644 --- a/components/bt/esp_ble_mesh/mesh_models/server/include/lighting_server.h +++ b/components/bt/esp_ble_mesh/mesh_models/server/include/lighting_server.h @@ -513,4 +513,18 @@ int bt_mesh_light_xyl_setup_srv_init(struct bt_mesh_model *model, bool primary); int bt_mesh_light_lc_srv_init(struct bt_mesh_model *model, bool primary); int bt_mesh_light_lc_setup_srv_init(struct bt_mesh_model *model, bool primary); +int bt_mesh_light_lightness_srv_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_light_lightness_setup_srv_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_light_ctl_srv_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_light_ctl_setup_srv_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_light_ctl_temp_srv_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_light_hsl_srv_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_light_hsl_setup_srv_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_light_hsl_hue_srv_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_light_hsl_sat_srv_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_light_xyl_srv_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_light_xyl_setup_srv_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_light_lc_srv_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_light_lc_setup_srv_deinit(struct bt_mesh_model *model, bool primary); + #endif /* _LIGHTING_SERVER_H_ */ diff --git a/components/bt/esp_ble_mesh/mesh_models/server/include/sensor_server.h b/components/bt/esp_ble_mesh/mesh_models/server/include/sensor_server.h index de92a7ad5c..79be44bb7a 100644 --- a/components/bt/esp_ble_mesh/mesh_models/server/include/sensor_server.h +++ b/components/bt/esp_ble_mesh/mesh_models/server/include/sensor_server.h @@ -246,4 +246,7 @@ typedef union { int bt_mesh_sensor_srv_init(struct bt_mesh_model *model, bool primary); int bt_mesh_sensor_setup_srv_init(struct bt_mesh_model *model, bool primary); +int bt_mesh_sensor_srv_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_sensor_setup_srv_deinit(struct bt_mesh_model *model, bool primary); + #endif /* _SENSOR_SERVER_H_ */ diff --git a/components/bt/esp_ble_mesh/mesh_models/server/include/server_common.h b/components/bt/esp_ble_mesh/mesh_models/server/include/server_common.h index d1a313ee73..4f18aebfa9 100644 --- a/components/bt/esp_ble_mesh/mesh_models/server/include/server_common.h +++ b/components/bt/esp_ble_mesh/mesh_models/server/include/server_common.h @@ -116,6 +116,7 @@ int bt_mesh_server_get_optional(struct bt_mesh_model *model, bool *optional); void bt_mesh_server_alloc_ctx(struct k_work *work); +void bt_mesh_server_free_ctx(struct k_work *work); bool bt_mesh_is_server_recv_last_msg(struct bt_mesh_last_msg_info *last, u8_t tid, u16_t src, u16_t dst, s64_t *now); diff --git a/components/bt/esp_ble_mesh/mesh_models/server/include/time_scene_server.h b/components/bt/esp_ble_mesh/mesh_models/server/include/time_scene_server.h index 846677699f..e5b2a8c295 100644 --- a/components/bt/esp_ble_mesh/mesh_models/server/include/time_scene_server.h +++ b/components/bt/esp_ble_mesh/mesh_models/server/include/time_scene_server.h @@ -390,4 +390,11 @@ int bt_mesh_scene_setup_srv_init(struct bt_mesh_model *model, bool primary); int bt_mesh_scheduler_srv_init(struct bt_mesh_model *model, bool primary); int bt_mesh_scheduler_setup_srv_init(struct bt_mesh_model *model, bool primary); +int bt_mesh_time_srv_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_time_setup_srv_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_scene_srv_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_scene_setup_srv_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_scheduler_srv_deinit(struct bt_mesh_model *model, bool primary); +int bt_mesh_scheduler_setup_srv_deinit(struct bt_mesh_model *model, bool primary); + #endif /* _TIME_SCENE_SERVER_H_ */ diff --git a/components/bt/esp_ble_mesh/mesh_models/server/lighting_server.c b/components/bt/esp_ble_mesh/mesh_models/server/lighting_server.c index 20664056a1..d5bc91ade9 100644 --- a/components/bt/esp_ble_mesh/mesh_models/server/lighting_server.c +++ b/components/bt/esp_ble_mesh/mesh_models/server/lighting_server.c @@ -36,6 +36,14 @@ static void bt_mesh_light_server_mutex_new(void) } } +static void bt_mesh_light_server_mutex_free(void) +{ + if (light_server_lock) { + osi_mutex_free(&light_server_lock); + light_server_lock = NULL; + } +} + void bt_mesh_light_server_lock(void) { if (light_server_lock) { @@ -3335,3 +3343,229 @@ int bt_mesh_light_lc_setup_srv_init(struct bt_mesh_model *model, bool primary) } return light_server_init(model); } + +static int light_server_deinit(struct bt_mesh_model *model) +{ + if (model->user_data == NULL) { + BT_ERR("%s, No Light Server context provided, model_id 0x%04x", __func__, model->id); + return -EINVAL; + } + + switch (model->id) { + case BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV: { + struct bt_mesh_light_lightness_srv *srv = model->user_data; + if (srv->state == NULL) { + BT_ERR("%s, NULL Light Lightness State", __func__); + return -EINVAL; + } + if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) { + bt_mesh_server_free_ctx(&srv->actual_transition.timer.work); + bt_mesh_server_free_ctx(&srv->linear_transition.timer.work); + k_delayed_work_free(&srv->actual_transition.timer); + k_delayed_work_free(&srv->linear_transition.timer); + } + break; + } + case BLE_MESH_MODEL_ID_LIGHT_CTL_SRV: { + struct bt_mesh_light_ctl_srv *srv = model->user_data; + if (srv->state == NULL) { + BT_ERR("%s, NULL Light CTL State", __func__); + return -EINVAL; + } + if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) { + bt_mesh_server_free_ctx(&srv->transition.timer.work); + k_delayed_work_free(&srv->transition.timer); + } + break; + } + case BLE_MESH_MODEL_ID_LIGHT_CTL_TEMP_SRV: { + struct bt_mesh_light_ctl_temp_srv *srv = model->user_data; + if (srv->state == NULL) { + BT_ERR("%s, NULL Light CTL State", __func__); + return -EINVAL; + } + if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) { + bt_mesh_server_free_ctx(&srv->transition.timer.work); + k_delayed_work_free(&srv->transition.timer); + } + break; + } + case BLE_MESH_MODEL_ID_LIGHT_HSL_SRV: { + struct bt_mesh_light_hsl_srv *srv = model->user_data; + if (srv->state == NULL) { + BT_ERR("%s, NULL Light HSL State", __func__); + return -EINVAL; + } + if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) { + bt_mesh_server_free_ctx(&srv->transition.timer.work); + k_delayed_work_free(&srv->transition.timer); + } + break; + } + case BLE_MESH_MODEL_ID_LIGHT_HSL_HUE_SRV: { + struct bt_mesh_light_hsl_hue_srv *srv = model->user_data; + if (srv->state == NULL) { + BT_ERR("%s, NULL Light HSL State", __func__); + return -EINVAL; + } + if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) { + bt_mesh_server_free_ctx(&srv->transition.timer.work); + k_delayed_work_free(&srv->transition.timer); + } + break; + } + case BLE_MESH_MODEL_ID_LIGHT_HSL_SAT_SRV: { + struct bt_mesh_light_hsl_sat_srv *srv = model->user_data; + if (srv->state == NULL) { + BT_ERR("%s, NULL Light HSL State", __func__); + return -EINVAL; + } + if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) { + bt_mesh_server_free_ctx(&srv->transition.timer.work); + k_delayed_work_free(&srv->transition.timer); + } + break; + } + case BLE_MESH_MODEL_ID_LIGHT_XYL_SRV: { + struct bt_mesh_light_xyl_srv *srv = model->user_data; + if (srv->state == NULL) { + BT_ERR("%s, NULL Light xyL State", __func__); + return -EINVAL; + } + if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) { + bt_mesh_server_free_ctx(&srv->transition.timer.work); + k_delayed_work_free(&srv->transition.timer); + } + break; + } + case BLE_MESH_MODEL_ID_LIGHT_LC_SRV: { + struct bt_mesh_light_lc_srv *srv = model->user_data; + if (srv->lc == NULL) { + BT_ERR("%s, NULL Light LC State", __func__); + return -EINVAL; + } + if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) { + bt_mesh_server_free_ctx(&srv->transition.timer.work); + k_delayed_work_free(&srv->transition.timer); + } + break; + } + default: + BT_WARN("%s, Unknown Light Server Model, model_id 0x%04x", __func__, model->id); + return -EINVAL; + } + + bt_mesh_light_server_mutex_free(); + + return 0; +} + +int bt_mesh_light_lightness_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + if (model->pub == NULL) { + BT_ERR("%s, Light Lightness Server has no publication support", __func__); + return -EINVAL; + } + + return light_server_deinit(model); +} + +int bt_mesh_light_lightness_setup_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + return light_server_deinit(model); +} + +int bt_mesh_light_ctl_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + if (model->pub == NULL) { + BT_ERR("%s, Light CTL Server has no publication support", __func__); + return -EINVAL; + } + + return light_server_deinit(model); +} + +int bt_mesh_light_ctl_setup_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + return light_server_deinit(model); +} + +int bt_mesh_light_ctl_temp_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + if (model->pub == NULL) { + BT_ERR("%s, Light CTL Temperature Server has no publication support", __func__); + return -EINVAL; + } + + return light_server_deinit(model); +} + +int bt_mesh_light_hsl_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + if (model->pub == NULL) { + BT_ERR("%s, Light HSL Server has no publication support", __func__); + return -EINVAL; + } + + return light_server_deinit(model); +} + +int bt_mesh_light_hsl_setup_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + return light_server_deinit(model); +} + +int bt_mesh_light_hsl_hue_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + if (model->pub == NULL) { + BT_ERR("%s, Light HSL Hue Server has no publication support", __func__); + return -EINVAL; + } + + return light_server_deinit(model); +} + +int bt_mesh_light_hsl_sat_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + if (model->pub == NULL) { + BT_ERR("%s, Light HSL Saturation Server has no publication support", __func__); + return -EINVAL; + } + + return light_server_deinit(model); +} + +int bt_mesh_light_xyl_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + if (model->pub == NULL) { + BT_ERR("%s, Light xyL Server has no publication support", __func__); + return -EINVAL; + } + + return light_server_deinit(model); +} + +int bt_mesh_light_xyl_setup_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + return light_server_deinit(model); +} + +int bt_mesh_light_lc_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + if (model->pub == NULL) { + BT_ERR("%s, Light LC Server has no publication support", __func__); + return -EINVAL; + } + + return light_server_deinit(model); +} + +int bt_mesh_light_lc_setup_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + if (model->pub == NULL) { + BT_ERR("%s, Light LC Setup Server has no publication support", __func__); + return -EINVAL; + } + + return light_server_deinit(model); +} diff --git a/components/bt/esp_ble_mesh/mesh_models/server/sensor_server.c b/components/bt/esp_ble_mesh/mesh_models/server/sensor_server.c index a28930f759..ad1709e007 100644 --- a/components/bt/esp_ble_mesh/mesh_models/server/sensor_server.c +++ b/components/bt/esp_ble_mesh/mesh_models/server/sensor_server.c @@ -1086,3 +1086,33 @@ int bt_mesh_sensor_setup_srv_init(struct bt_mesh_model *model, bool primary) return sensor_server_init(model); } + +static int sensor_server_deinit(struct bt_mesh_model *model) +{ + if (model->user_data == NULL) { + BT_ERR("%s, No Sensor Server context provided, model_id 0x%04x", __func__, model->id); + return -EINVAL; + } + + return 0; +} + +int bt_mesh_sensor_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + if (model->pub == NULL) { + BT_ERR("%s, Sensor Server has no publication support", __func__); + return -EINVAL; + } + + return sensor_server_deinit(model); +} + +int bt_mesh_sensor_setup_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + if (model->pub == NULL) { + BT_ERR("%s, Sensor Setup Server has no publication support", __func__); + return -EINVAL; + } + + return sensor_server_deinit(model); +} diff --git a/components/bt/esp_ble_mesh/mesh_models/server/server_common.c b/components/bt/esp_ble_mesh/mesh_models/server/server_common.c index 041cc3b002..a2ab17286c 100644 --- a/components/bt/esp_ble_mesh/mesh_models/server/server_common.c +++ b/components/bt/esp_ble_mesh/mesh_models/server/server_common.c @@ -199,6 +199,15 @@ void bt_mesh_server_alloc_ctx(struct k_work *work) } } +void bt_mesh_server_free_ctx(struct k_work *work) +{ + __ASSERT(work, "%s, Invalid parameter", __func__); + if (work->_reserved) { + osi_free(work->_reserved); + work->_reserved = NULL; + } +} + bool bt_mesh_is_server_recv_last_msg(struct bt_mesh_last_msg_info *last, u8_t tid, u16_t src, u16_t dst, s64_t *now) { diff --git a/components/bt/esp_ble_mesh/mesh_models/server/time_scene_server.c b/components/bt/esp_ble_mesh/mesh_models/server/time_scene_server.c index 1b10e42344..d50bd72643 100644 --- a/components/bt/esp_ble_mesh/mesh_models/server/time_scene_server.c +++ b/components/bt/esp_ble_mesh/mesh_models/server/time_scene_server.c @@ -43,6 +43,14 @@ static void bt_mesh_time_scene_server_mutex_new(void) } } +static void bt_mesh_time_scene_server_mutex_free(void) +{ + if (time_scene_server_lock) { + osi_mutex_free(&time_scene_server_lock); + time_scene_server_lock = NULL; + } +} + void bt_mesh_time_scene_server_lock(void) { if (time_scene_server_lock) { @@ -1425,4 +1433,87 @@ int bt_mesh_scheduler_setup_srv_init(struct bt_mesh_model *model, bool primary) /* Just give a warning here, continue with the initialization */ } return time_scene_server_init(model); -} \ No newline at end of file +} + +static int time_scene_server_deinit(struct bt_mesh_model *model) +{ + if (model->user_data == NULL) { + BT_ERR("%s, No Time Scene Server context provided, model_id 0x%04x", __func__, model->id); + return -EINVAL; + } + + switch (model->id) { + case BLE_MESH_MODEL_ID_SCENE_SRV: { + struct bt_mesh_scene_srv *srv = model->user_data; + if (srv->state == NULL) { + BT_ERR("%s, NULL Scene State", __func__); + return -EINVAL; + } + if (check_scene_server_init(srv->state)) { + return -EINVAL; + } + if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) { + bt_mesh_server_free_ctx(&srv->transition.timer.work); + k_delayed_work_free(&srv->transition.timer); + } + break; + } + default: + BT_WARN("%s, Unknown Time Scene Server Model, model_id 0x%04x", __func__, model->id); + return -EINVAL; + } + + bt_mesh_time_scene_server_mutex_free(); + + return 0; +} + +int bt_mesh_time_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + if (model->pub == NULL) { + BT_ERR("%s, Time Server has no publication support", __func__); + return -EINVAL; + } + + return time_scene_server_deinit(model); +} + +int bt_mesh_time_setup_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + if (model->pub) { + BT_ERR("%s, Time Setup Server shall not support publication", __func__); + return -EINVAL; + } + + return time_scene_server_deinit(model); +} + +int bt_mesh_scene_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + if (model->pub == NULL) { + BT_ERR("%s, Scene Server has no publication support", __func__); + return -EINVAL; + } + + return time_scene_server_deinit(model); +} + +int bt_mesh_scene_setup_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + return time_scene_server_deinit(model); +} + +int bt_mesh_scheduler_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + if (model->pub == NULL) { + BT_ERR("%s, Scheduler Server has no publication support", __func__); + return -EINVAL; + } + + return time_scene_server_deinit(model); +} + +int bt_mesh_scheduler_setup_srv_deinit(struct bt_mesh_model *model, bool primary) +{ + return time_scene_server_deinit(model); +} diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/ble_mesh_demo_main.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/ble_mesh_demo_main.c index 2bf3003091..9777e8a641 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/ble_mesh_demo_main.c +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/ble_mesh_demo_main.c @@ -146,6 +146,8 @@ static esp_ble_mesh_prov_t prov = { .uuid = dev_uuid, .output_size = 0, .output_actions = 0, + .prov_unicast_addr = 0x0001, + .prov_start_address = 0x0005, .prov_attention = 0x00, .prov_algorithm = 0x00, .prov_pub_key_oob = 0x00, @@ -350,6 +352,10 @@ static void example_ble_mesh_provisioning_cb(esp_ble_mesh_prov_cb_event_t event, } prov_start = true; break; + case ESP_BLE_MESH_PROVISIONER_PROV_ENABLE_COMP_EVT: + ESP_LOGI(TAG, "ESP_BLE_MESH_PROVISIONER_PROV_ENABLE_COMP_EVT, err_code: %d", + param->provisioner_prov_enable_comp.err_code); + break; case ESP_BLE_MESH_PROVISIONER_RECV_UNPROV_ADV_PKT_EVT: example_recv_unprov_adv_pkt(param->provisioner_recv_unprov_adv_pkt.dev_uuid, param->provisioner_recv_unprov_adv_pkt.addr, param->provisioner_recv_unprov_adv_pkt.addr_type, param->provisioner_recv_unprov_adv_pkt.oob_info, @@ -695,6 +701,37 @@ static esp_err_t ble_mesh_init(void) esp_ble_mesh_register_config_server_callback(example_ble_mesh_config_server_cb); esp_ble_mesh_register_generic_server_callback(example_ble_mesh_generic_server_cb); + ESP_LOGW(TAG, "prev, free heap size %d", esp_get_free_heap_size()); + vTaskDelay(10 / portTICK_PERIOD_MS); + ESP_LOGW(TAG, "start, free heap size %d", esp_get_free_heap_size()); + /* First time (make erase_flash, then make flash monitor), 72 bytes will be cost + * during first (start - end) circle. + * Second time (make monitor), 0 byte will be cost during first (start - end) cycle. + */ + for (int i = 0; i < 1000; i++) { + err = esp_ble_mesh_init(&prov, &comp); + if (err != ESP_OK) { + ESP_LOGE(TAG, "%s: Failed to initialize BLE Mesh", __func__); + return err; + } + err = esp_ble_mesh_client_model_init(&vnd_models[1]); + if (err != ESP_OK) { + ESP_LOGE(TAG, "%s: Failed to initialize fast prov client model", __func__); + return err; + } + err = esp_ble_mesh_client_model_deinit(&vnd_models[1]); + if (err != ESP_OK) { + ESP_LOGE(TAG, "%s: Failed to deinitialize fast prov client model", __func__); + return err; + } + err = esp_ble_mesh_deinit(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "%s: Failed to de-initialize BLE Mesh", __func__); + return err; + } + ESP_LOGW(TAG, "end, free heap size %d", esp_get_free_heap_size()); + } + err = esp_ble_mesh_init(&prov, &comp); if (err != ESP_OK) { ESP_LOGE(TAG, "%s: Failed to initialize BLE Mesh", __func__);