diff --git a/components/bt/CMakeLists.txt b/components/bt/CMakeLists.txt index 3f87bcce54..e64b1db713 100644 --- a/components/bt/CMakeLists.txt +++ b/components/bt/CMakeLists.txt @@ -389,6 +389,7 @@ if(CONFIG_BT_ENABLED) "esp_ble_mesh/mesh_core/provisioner_prov.c" "esp_ble_mesh/mesh_core/proxy_client.c" "esp_ble_mesh/mesh_core/proxy_server.c" + "esp_ble_mesh/mesh_core/settings_uid.c" "esp_ble_mesh/mesh_core/settings.c" "esp_ble_mesh/mesh_core/test.c" "esp_ble_mesh/mesh_core/transport.c" diff --git a/components/bt/esp_ble_mesh/Kconfig.in b/components/bt/esp_ble_mesh/Kconfig.in index cdb867b026..cbabffbf5b 100644 --- a/components/bt/esp_ble_mesh/Kconfig.in +++ b/components/bt/esp_ble_mesh/Kconfig.in @@ -320,28 +320,6 @@ if BLE_MESH if BLE_MESH_SETTINGS - config BLE_MESH_SPECIFIC_PARTITION - bool "Use a specific NVS partition for BLE Mesh" - default n - help - When selected, the mesh stack will use a specified NVS partition instead of - default NVS partition. Note that the specified partition must be registered - with NVS using nvs_flash_init_partition() API, and the partition must exists - in the csv file. - When Provisioner needs to store a large amount of nodes' information in the - flash (e.g. more than 20), this option is recommended to be enabled. - - if BLE_MESH_SPECIFIC_PARTITION - - config BLE_MESH_PARTITION_NAME - string "Name of the NVS partition for BLE Mesh" - default "ble_mesh" - help - This value defines the name of the specified NVS partition used by the - mesh stack. - - endif # BLE_MESH_SPECIFIC_PARTITION - config BLE_MESH_STORE_TIMEOUT int "Delay (in seconds) before storing anything persistently" range 0 1000000 @@ -407,6 +385,50 @@ if BLE_MESH in advance before recovering node information and make sure the node information recovering could work as expected. + config BLE_MESH_SPECIFIC_PARTITION + bool "Use a specific NVS partition for BLE Mesh" + default n + help + When selected, the mesh stack will use a specified NVS partition instead of + default NVS partition. Note that the specified partition must be registered + with NVS using nvs_flash_init_partition() API, and the partition must exists + in the csv file. + When Provisioner needs to store a large amount of nodes' information in the + flash (e.g. more than 20), this option is recommended to be enabled. + + config BLE_MESH_PARTITION_NAME + string "Name of the NVS partition for BLE Mesh" + depends on BLE_MESH_SPECIFIC_PARTITION + default "ble_mesh" + help + This value defines the name of the specified NVS partition used by the + mesh stack. + + config BLE_MESH_USE_MULTIPLE_NAMESPACE + bool "Support using multiple NVS namespaces by Provisioner" + depends on BLE_MESH_PROVISIONER + default n + help + When selected, Provisioner can use different NVS namespaces to store + different instances of mesh information. + For example, if in the first room, Provisioner uses NetKey A, AppKey + A and provisions three devices, these information will be treated as + mesh information instance A. When the Provisioner moves to the second + room, it uses NetKey B, AppKey B and provisions two devices, then the + information will be treated as mesh information instance B. + Here instance A and instance B will be stored in different namespaces. + With this option enabled, Provisioner needs to use specific functions + to open the corresponding NVS namespace, restore the mesh information, + release the mesh information or erase the mesh information. + + config BLE_MESH_MAX_NVS_NAMESPACE + int "Maximum number of NVS namespaces" + depends on BLE_MESH_USE_MULTIPLE_NAMESPACE + default 2 + range 1 255 + help + This option specifies the maximum NVS namespaces supported by Provisioner. + endif # if BLE_MESH_SETTINGS config BLE_MESH_SUBNET_COUNT 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 d4cc1d74c1..5f772fc507 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 @@ -598,6 +598,176 @@ esp_err_t esp_ble_mesh_provisioner_set_heartbeat_filter_info(uint8_t op, esp_ble } #endif /* CONFIG_BLE_MESH_PROVISIONER_RECV_HB */ +#if CONFIG_BLE_MESH_SETTINGS +esp_err_t esp_ble_mesh_provisioner_direct_erase_settings(void) +{ + btc_msg_t msg = {0}; + + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_PROV; + + msg.act = BTC_BLE_MESH_ACT_PROVISIONER_DIRECT_ERASE_SETTINGS; + + return (btc_transfer_context(&msg, NULL, 0, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} +#endif /* CONFIG_BLE_MESH_SETTINGS */ + +#if CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE +esp_err_t esp_ble_mesh_provisioner_open_settings_with_index(uint8_t index) +{ + btc_ble_mesh_prov_args_t arg = {0}; + btc_msg_t msg = {0}; + + if (index >= CONFIG_BLE_MESH_MAX_NVS_NAMESPACE) { + return ESP_ERR_INVALID_ARG; + } + + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_PROV; + msg.act = BTC_BLE_MESH_ACT_PROVISIONER_OPEN_SETTINGS_WITH_INDEX; + + arg.open_settings_with_index.index = index; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_mesh_provisioner_open_settings_with_uid(const char *uid) +{ + btc_ble_mesh_prov_args_t arg = {0}; + btc_msg_t msg = {0}; + + if (!uid || strlen(uid) > ESP_BLE_MESH_SETTINGS_UID_SIZE) { + return ESP_ERR_INVALID_ARG; + } + + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_PROV; + msg.act = BTC_BLE_MESH_ACT_PROVISIONER_OPEN_SETTINGS_WITH_UID; + + strncpy(arg.open_settings_with_uid.uid, uid, ESP_BLE_MESH_SETTINGS_UID_SIZE); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_mesh_provisioner_close_settings_with_index(uint8_t index, bool erase) +{ + btc_ble_mesh_prov_args_t arg = {0}; + btc_msg_t msg = {0}; + + if (index >= CONFIG_BLE_MESH_MAX_NVS_NAMESPACE) { + return ESP_ERR_INVALID_ARG; + } + + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_PROV; + msg.act = BTC_BLE_MESH_ACT_PROVISIONER_CLOSE_SETTINGS_WITH_INDEX; + + arg.close_settings_with_index.index = index; + arg.close_settings_with_index.erase = erase; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_mesh_provisioner_close_settings_with_uid(const char *uid, bool erase) +{ + btc_ble_mesh_prov_args_t arg = {0}; + btc_msg_t msg = {0}; + + if (!uid || strlen(uid) > ESP_BLE_MESH_SETTINGS_UID_SIZE) { + return ESP_ERR_INVALID_ARG; + } + + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_PROV; + msg.act = BTC_BLE_MESH_ACT_PROVISIONER_CLOSE_SETTINGS_WITH_UID; + + strncpy(arg.close_settings_with_uid.uid, uid, ESP_BLE_MESH_SETTINGS_UID_SIZE); + arg.close_settings_with_uid.erase = erase; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_mesh_provisioner_delete_settings_with_index(uint8_t index) +{ + btc_ble_mesh_prov_args_t arg = {0}; + btc_msg_t msg = {0}; + + if (index >= CONFIG_BLE_MESH_MAX_NVS_NAMESPACE) { + return ESP_ERR_INVALID_ARG; + } + + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_PROV; + msg.act = BTC_BLE_MESH_ACT_PROVISIONER_DELETE_SETTINGS_WITH_INDEX; + + arg.delete_settings_with_index.index = index; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_mesh_provisioner_delete_settings_with_uid(const char *uid) +{ + btc_ble_mesh_prov_args_t arg = {0}; + btc_msg_t msg = {0}; + + if (!uid || strlen(uid) > ESP_BLE_MESH_SETTINGS_UID_SIZE) { + return ESP_ERR_INVALID_ARG; + } + + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_PROV; + msg.act = BTC_BLE_MESH_ACT_PROVISIONER_DELETE_SETTINGS_WITH_UID; + + strncpy(arg.delete_settings_with_uid.uid, uid, ESP_BLE_MESH_SETTINGS_UID_SIZE); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +const char *esp_ble_mesh_provisioner_get_settings_uid(uint8_t index) +{ + if (index >= CONFIG_BLE_MESH_MAX_NVS_NAMESPACE) { + return NULL; + } + + return btc_ble_mesh_provisioner_get_settings_uid(index); +} + +uint8_t esp_ble_mesh_provisioner_get_settings_index(const char *uid) +{ + if (!uid || strlen(uid) > ESP_BLE_MESH_SETTINGS_UID_SIZE) { + return ESP_BLE_MESH_INVALID_SETTINGS_IDX; + } + + return btc_ble_mesh_provisioner_get_settings_index(uid); +} + +uint8_t esp_ble_mesh_provisioner_get_free_settings_count(void) +{ + return btc_ble_mesh_provisioner_get_free_settings_count(); +} +#endif /* CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE */ + #endif /* CONFIG_BLE_MESH_PROVISIONER */ #if (CONFIG_BLE_MESH_FAST_PROV) 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 dd880fa25a..9adf4c54d3 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 @@ -473,6 +473,171 @@ esp_err_t esp_ble_mesh_provisioner_set_heartbeat_filter_type(uint8_t type); */ esp_err_t esp_ble_mesh_provisioner_set_heartbeat_filter_info(uint8_t op, esp_ble_mesh_heartbeat_filter_info_t *info); +/** + * @brief This function is called by Provisioner to directly erase the mesh + * information from nvs namespace. + * + * @note This function can be invoked when the mesh stack is not initialized + * or has been de-initialized. + * + * @return ESP_OK on success or error code otherwise. + * + */ +esp_err_t esp_ble_mesh_provisioner_direct_erase_settings(void); + +/** + * @brief This function is called by Provisioner to open a nvs namespace + * for storing mesh information. + * + * @note Before open another nvs namespace, the previously opened nvs + * namespace must be closed firstly. + * + * @param[in] index: Settings index. + * + * @return ESP_OK on success or error code otherwise. + * + */ +esp_err_t esp_ble_mesh_provisioner_open_settings_with_index(uint8_t index); + +/** + * @brief This function is called by Provisioner to open a nvs namespace + * for storing mesh information. + * + * @note Before open another nvs namespace, the previously opened nvs + * namespace must be closed firstly. + * + * @param[in] uid: Settings user id. + * + * @return ESP_OK on success or error code otherwise. + * + */ +esp_err_t esp_ble_mesh_provisioner_open_settings_with_uid(const char *uid); + +/** + * @brief This function is called by Provisioner to close a nvs namespace + * which is opened previously for storing mesh information. + * + * @note 1. Before closing the nvs namespace, it must be open. + * 2. When the function is invoked, the Provisioner functionality + * will be disabled firstly, and: + * a) If the "erase" flag is set to false, the mesh information + * will be cleaned (e.g. removing NetKey, AppKey, nodes, etc) + * from the mesh stack. + * b) If the "erase" flag is set to true, the mesh information + * stored in the nvs namespace will also be erased besides + * been cleaned from the mesh stack. + * 3. If Provisioner tries to work properly again, we can invoke the + * open function to open a new nvs namespace or a previously added + * one, and restore the mesh information from it if not erased. + * 4. The working process shall be as following: + * a) Open settings A + * b) Start to provision and control nodes + * c) Close settings A + * d) Open settings B + * e) Start to provision and control other nodes + * f) Close settings B + * g) ...... + * + * @param[in] index: Settings index. + * @param[in] erase: Indicate if erasing mesh information. + * + * @return ESP_OK on success or error code otherwise. + * + */ +esp_err_t esp_ble_mesh_provisioner_close_settings_with_index(uint8_t index, bool erase); + +/** + * @brief This function is called by Provisioner to close a nvs namespace + * which is opened previously for storing mesh information. + * + * @note 1. Before closing the nvs namespace, it must be open. + * 2. When the function is invoked, the Provisioner functionality + * will be disabled firstly, and: + * a) If the "erase" flag is set to false, the mesh information + * will be cleaned (e.g. removing NetKey, AppKey, nodes, etc) + * from the mesh stack. + * b) If the "erase" flag is set to true, the mesh information + * stored in the nvs namespace will also be erased besides + * been cleaned from the mesh stack. + * 3. If Provisioner tries to work properly again, we can invoke the + * open function to open a new nvs namespace or a previously added + * one, and restore the mesh information from it if not erased. + * 4. The working process shall be as following: + * a) Open settings A + * b) Start to provision and control nodes + * c) Close settings A + * d) Open settings B + * e) Start to provision and control other nodes + * f) Close settings B + * g) ...... + * + * @param[in] uid: Settings user id. + * @param[in] erase: Indicate if erasing mesh information. + * + * @return ESP_OK on success or error code otherwise. + * + */ +esp_err_t esp_ble_mesh_provisioner_close_settings_with_uid(const char *uid, bool erase); + +/** + * @brief This function is called by Provisioner to erase the mesh information + * and settings user id from a nvs namespace. + * + * @note When this function is called, the nvs namespace must not be open. + * This function is used to erase the mesh information and settings + * user id which are not used currently. + * + * @param[in] index: Settings index. + * + * @return ESP_OK on success or error code otherwise. + * + */ +esp_err_t esp_ble_mesh_provisioner_delete_settings_with_index(uint8_t index); + +/** + * @brief This function is called by Provisioner to erase the mesh information + * and settings user id from a nvs namespace. + * + * @note When this function is called, the nvs namespace must not be open. + * This function is used to erase the mesh information and settings + * user id which are not used currently. + * + * @param[in] uid: Settings user id. + * + * @return ESP_OK on success or error code otherwise. + * + */ +esp_err_t esp_ble_mesh_provisioner_delete_settings_with_uid(const char *uid); + +/** + * @brief This function is called by Provisioner to get settings user id. + * + * @param[in] index: Settings index. + * + * @return Setting user id on success or NULL on failure. + * + */ +const char *esp_ble_mesh_provisioner_get_settings_uid(uint8_t index); + +/** + * @brief This function is called by Provisioner to get settings index. + * + * @param[in] uid: Settings user id. + * + * @return Settings index. + * + */ +uint8_t esp_ble_mesh_provisioner_get_settings_index(const char *uid); + +/** + * @brief This function is called by Provisioner to get the number of free + * settings user id. + * + * @return Number of free settings user id. + * + */ +uint8_t esp_ble_mesh_provisioner_get_free_settings_count(void); + /** * @brief This function is called to get fast provisioning application key. * diff --git a/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h b/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h index 71ae994932..4ff2b620df 100644 --- a/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h +++ b/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h @@ -51,6 +51,12 @@ extern "C" { /*!< The maximum length of a BLE Mesh unprovisioned device name */ #define ESP_BLE_MESH_DEVICE_NAME_MAX_LEN DEVICE_NAME_SIZE +/*!< The maximum length of settings user id */ +#define ESP_BLE_MESH_SETTINGS_UID_SIZE 20 + +/*!< Invalid settings index */ +#define ESP_BLE_MESH_INVALID_SETTINGS_IDX 0xFF + /*!< Define the BLE Mesh octet 16 bytes size */ #define ESP_BLE_MESH_OCTET16_LEN 16 typedef uint8_t esp_ble_mesh_octet16_t[ESP_BLE_MESH_OCTET16_LEN]; @@ -869,7 +875,14 @@ typedef enum { ESP_BLE_MESH_PROVISIONER_ENABLE_HEARTBEAT_RECV_COMP_EVT, /*!< Provisioner start to receive heartbeat message completion event */ ESP_BLE_MESH_PROVISIONER_SET_HEARTBEAT_FILTER_TYPE_COMP_EVT, /*!< Provisioner set the heartbeat filter type completion event */ ESP_BLE_MESH_PROVISIONER_SET_HEARTBEAT_FILTER_INFO_COMP_EVT, /*!< Provisioner set the heartbeat filter information completion event */ - ESP_BLE_MESH_PROVISIONER_RECV_HEARTBEAT_MESSAGE_EVT, /*!< Provisioner receive heartbeat message event */ + ESP_BLE_MESH_PROVISIONER_RECV_HEARTBEAT_MESSAGE_EVT, /*!< Provisioner receive heartbeat message event */ + ESP_BLE_MESH_PROVISIONER_DRIECT_ERASE_SETTINGS_COMP_EVT, /*!< Provisioner directly erase settings completion event */ + ESP_BLE_MESH_PROVISIONER_OPEN_SETTINGS_WITH_INDEX_COMP_EVT, /*!< Provisioner open settings with index completion event */ + ESP_BLE_MESH_PROVISIONER_OPEN_SETTINGS_WITH_UID_COMP_EVT, /*!< Provisioner open settings with user id completion event */ + ESP_BLE_MESH_PROVISIONER_CLOSE_SETTINGS_WITH_INDEX_COMP_EVT, /*!< Provisioner close settings with index completion event */ + ESP_BLE_MESH_PROVISIONER_CLOSE_SETTINGS_WITH_UID_COMP_EVT, /*!< Provisioner close settings with user id completion event */ + ESP_BLE_MESH_PROVISIONER_DELETE_SETTINGS_WITH_INDEX_COMP_EVT, /*!< Provisioner delete settings with index completion event */ + ESP_BLE_MESH_PROVISIONER_DELETE_SETTINGS_WITH_UID_COMP_EVT, /*!< Provisioner delete settings with user id completion event */ ESP_BLE_MESH_SET_FAST_PROV_INFO_COMP_EVT, /*!< Set fast provisioning information (e.g. unicast address range, net_idx, etc.) completion event */ ESP_BLE_MESH_SET_FAST_PROV_ACTION_COMP_EVT, /*!< Set fast provisioning action completion event */ ESP_BLE_MESH_HEARTBEAT_MESSAGE_RECV_EVT, /*!< Receive Heartbeat message event */ @@ -1272,6 +1285,57 @@ typedef union { uint16_t feature; /*!< Bit field of currently active features of the node */ int8_t rssi; /*!< RSSI of the heartbeat message */ } provisioner_recv_heartbeat; /*!< Event parameters of ESP_BLE_MESH_PROVISIONER_RECV_HEARTBEAT_MESSAGE_EVT */ + /** + * @brief ESP_BLE_MESH_PROVISIONER_DRIECT_ERASE_SETTINGS_COMP_EVT + */ + struct { + int err_code; /*!< Indicate the result of directly erasing settings by the Provisioner */ + } provisioner_direct_erase_settings_comp; /*!< Event parameters of ESP_BLE_MESH_PROVISIONER_DRIECT_ERASE_SETTINGS_COMP_EVT */ + /** + * @brief ESP_BLE_MESH_PROVISIONER_OPEN_SETTINGS_WITH_INDEX_COMP_EVT + */ + struct { + int err_code; /*!< Indicate the result of opening settings with index by the Provisioner */ + uint8_t index; /*!< Index of Provisioner settings */ + } provisioner_open_settings_with_index_comp; /*!< Event parameter of ESP_BLE_MESH_PROVISIONER_OPEN_SETTINGS_WITH_INDEX_COMP_EVT */ + /** + * @brief ESP_BLE_MESH_PROVISIONER_OPEN_SETTINGS_WITH_UID_COMP_EVT + */ + struct { + int err_code; /*!< Indicate the result of opening settings with user id by the Provisioner */ + uint8_t index; /*!< Index of Provisioner settings */ + char uid[ESP_BLE_MESH_SETTINGS_UID_SIZE + 1]; /*!< Provisioner settings user id */ + } provisioner_open_settings_with_uid_comp; /*!< Event parameters of ESP_BLE_MESH_PROVISIONER_OPEN_SETTINGS_WITH_UID_COMP_EVT */ + /** + * @brief ESP_BLE_MESH_PROVISIONER_CLOSE_SETTINGS_WITH_INDEX_COMP_EVT + */ + struct { + int err_code; /*!< Indicate the result of closing settings with index by the Provisioner */ + uint8_t index; /*!< Index of Provisioner settings */ + } provisioner_close_settings_with_index_comp; /*!< Event parameter of ESP_BLE_MESH_PROVISIONER_CLOSE_SETTINGS_WITH_INDEX_COMP_EVT */ + /** + * @brief ESP_BLE_MESH_PROVISIONER_CLOSE_SETTINGS_WITH_UID_COMP_EVT + */ + struct { + int err_code; /*!< Indicate the result of closing settings with user id by the Provisioner */ + uint8_t index; /*!< Index of Provisioner settings */ + char uid[ESP_BLE_MESH_SETTINGS_UID_SIZE + 1]; /*!< Provisioner settings user id */ + } provisioner_close_settings_with_uid_comp; /*!< Event parameters of ESP_BLE_MESH_PROVISIONER_CLOSE_SETTINGS_WITH_UID_COMP_EVT */ + /** + * @brief ESP_BLE_MESH_PROVISIONER_DELETE_SETTINGS_WITH_INDEX_COMP_EVT + */ + struct { + int err_code; /*!< Indicate the result of deleting settings with index by the Provisioner */ + uint8_t index; /*!< Index of Provisioner settings */ + } provisioner_delete_settings_with_index_comp; /*!< Event parameter of ESP_BLE_MESH_PROVISIONER_DELETE_SETTINGS_WITH_INDEX_COMP_EVT */ + /** + * @brief ESP_BLE_MESH_PROVISIONER_DELETE_SETTINGS_WITH_UID_COMP_EVT + */ + struct { + int err_code; /*!< Indicate the result of deleting settings with user id by the Provisioner */ + uint8_t index; /*!< Index of Provisioner settings */ + char uid[ESP_BLE_MESH_SETTINGS_UID_SIZE + 1]; /*!< Provisioner settings user id */ + } provisioner_delete_settings_with_uid_comp; /*!< Event parameters of ESP_BLE_MESH_PROVISIONER_DELETE_SETTINGS_WITH_UID_COMP_EVT */ /** * @brief ESP_BLE_MESH_SET_FAST_PROV_INFO_COMP_EVT */ 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 ab03be5fb7..5732805298 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 @@ -29,6 +29,7 @@ #include "mesh.h" #include "access.h" #include "prov.h" +#include "settings_uid.h" #include "proxy_server.h" #include "proxy_client.h" #include "provisioner_prov.h" @@ -840,6 +841,23 @@ static void btc_ble_mesh_provisioner_recv_heartbeat_cb(u16_t hb_src, u16_t hb_ds } #endif /* CONFIG_BLE_MESH_PROVISIONER_RECV_HB */ +#if CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE +const char *btc_ble_mesh_provisioner_get_settings_uid(uint8_t index) +{ + return bt_mesh_provisioner_get_settings_uid(index); +} + +uint8_t btc_ble_mesh_provisioner_get_settings_index(const char *uid) +{ + return bt_mesh_provisioner_get_settings_index(uid); +} + +uint8_t btc_ble_mesh_provisioner_get_free_settings_count(void) +{ + return bt_mesh_provisioner_get_free_settings_count(); +} +#endif /* CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE */ + #endif /* CONFIG_BLE_MESH_PROVISIONER */ static void btc_ble_mesh_node_recv_heartbeat_cb(u8_t hops, u16_t feature) @@ -2042,6 +2060,58 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg) arg->set_heartbeat_filter_info.hb_dst); break; #endif /* CONFIG_BLE_MESH_PROVISIONER_RECV_HB */ +#if CONFIG_BLE_MESH_SETTINGS + case BTC_BLE_MESH_ACT_PROVISIONER_DIRECT_ERASE_SETTINGS: + act = ESP_BLE_MESH_PROVISIONER_DRIECT_ERASE_SETTINGS_COMP_EVT; + param.provisioner_direct_erase_settings_comp.err_code = bt_mesh_provisioner_direct_erase_settings(); + break; +#endif /* CONFIG_BLE_MESH_SETTINGS */ +#if CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE + case BTC_BLE_MESH_ACT_PROVISIONER_OPEN_SETTINGS_WITH_INDEX: + act = ESP_BLE_MESH_PROVISIONER_OPEN_SETTINGS_WITH_INDEX_COMP_EVT; + param.provisioner_open_settings_with_index_comp.index = arg->open_settings_with_index.index; + param.provisioner_open_settings_with_index_comp.err_code = + bt_mesh_provisioner_open_settings_with_index(arg->open_settings_with_index.index); + break; + case BTC_BLE_MESH_ACT_PROVISIONER_OPEN_SETTINGS_WITH_UID: + act = ESP_BLE_MESH_PROVISIONER_OPEN_SETTINGS_WITH_UID_COMP_EVT; + strncpy(param.provisioner_open_settings_with_uid_comp.uid, + arg->open_settings_with_uid.uid, ESP_BLE_MESH_SETTINGS_UID_SIZE + 1); + param.provisioner_open_settings_with_uid_comp.err_code = + bt_mesh_provisioner_open_settings_with_uid(arg->open_settings_with_uid.uid, + ¶m.provisioner_open_settings_with_uid_comp.index); + break; + case BTC_BLE_MESH_ACT_PROVISIONER_CLOSE_SETTINGS_WITH_INDEX: + act = ESP_BLE_MESH_PROVISIONER_CLOSE_SETTINGS_WITH_INDEX_COMP_EVT; + param.provisioner_close_settings_with_index_comp.index = arg->close_settings_with_index.index; + param.provisioner_close_settings_with_index_comp.err_code = + bt_mesh_provisioner_close_settings_with_index(arg->close_settings_with_index.index, + arg->close_settings_with_index.erase); + break; + case BTC_BLE_MESH_ACT_PROVISIONER_CLOSE_SETTINGS_WITH_UID: + act = ESP_BLE_MESH_PROVISIONER_CLOSE_SETTINGS_WITH_UID_COMP_EVT; + strncpy(param.provisioner_close_settings_with_uid_comp.uid, + arg->close_settings_with_uid.uid, ESP_BLE_MESH_SETTINGS_UID_SIZE + 1); + param.provisioner_close_settings_with_uid_comp.err_code = + bt_mesh_provisioner_close_settings_with_uid(arg->close_settings_with_uid.uid, + arg->close_settings_with_uid.erase, + ¶m.provisioner_close_settings_with_uid_comp.index); + break; + case BTC_BLE_MESH_ACT_PROVISIONER_DELETE_SETTINGS_WITH_INDEX: + act = ESP_BLE_MESH_PROVISIONER_DELETE_SETTINGS_WITH_INDEX_COMP_EVT; + param.provisioner_delete_settings_with_index_comp.index = arg->delete_settings_with_index.index; + param.provisioner_delete_settings_with_index_comp.err_code = + bt_mesh_provisioner_delete_settings_with_index(arg->delete_settings_with_index.index); + break; + case BTC_BLE_MESH_ACT_PROVISIONER_DELETE_SETTINGS_WITH_UID: + act = ESP_BLE_MESH_PROVISIONER_DELETE_SETTINGS_WITH_UID_COMP_EVT; + strncpy(param.provisioner_delete_settings_with_uid_comp.uid, + arg->delete_settings_with_uid.uid, ESP_BLE_MESH_SETTINGS_UID_SIZE + 1); + param.provisioner_delete_settings_with_uid_comp.err_code = + bt_mesh_provisioner_delete_settings_with_uid(arg->delete_settings_with_uid.uid, + ¶m.provisioner_delete_settings_with_uid_comp.index); + break; +#endif /* CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE */ #endif /* CONFIG_BLE_MESH_PROVISIONER */ #if CONFIG_BLE_MESH_FAST_PROV case BTC_BLE_MESH_ACT_SET_FAST_PROV_INFO: 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 06af8c2027..6790ccabf0 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 @@ -66,6 +66,13 @@ typedef enum { BTC_BLE_MESH_ACT_PROVISIONER_ENABLE_HEARTBEAT_RECV, BTC_BLE_MESH_ACT_PROVISIONER_SET_HEARTBEAT_FILTER_TYPE, BTC_BLE_MESH_ACT_PROVISIONER_SET_HEARTBEAT_FILTER_INFO, + BTC_BLE_MESH_ACT_PROVISIONER_DIRECT_ERASE_SETTINGS, + BTC_BLE_MESH_ACT_PROVISIONER_OPEN_SETTINGS_WITH_INDEX, + BTC_BLE_MESH_ACT_PROVISIONER_OPEN_SETTINGS_WITH_UID, + BTC_BLE_MESH_ACT_PROVISIONER_CLOSE_SETTINGS_WITH_INDEX, + BTC_BLE_MESH_ACT_PROVISIONER_CLOSE_SETTINGS_WITH_UID, + BTC_BLE_MESH_ACT_PROVISIONER_DELETE_SETTINGS_WITH_INDEX, + BTC_BLE_MESH_ACT_PROVISIONER_DELETE_SETTINGS_WITH_UID, BTC_BLE_MESH_ACT_SET_FAST_PROV_INFO, BTC_BLE_MESH_ACT_SET_FAST_PROV_ACTION, BTC_BLE_MESH_ACT_LPN_ENABLE, @@ -231,6 +238,26 @@ typedef union { uint16_t hb_src; uint16_t hb_dst; } set_heartbeat_filter_info; + struct { + uint8_t index; + } open_settings_with_index; + struct { + char uid[ESP_BLE_MESH_SETTINGS_UID_SIZE + 1]; + } open_settings_with_uid; + struct { + uint8_t index; + bool erase; + } close_settings_with_index; + struct { + char uid[ESP_BLE_MESH_SETTINGS_UID_SIZE + 1]; + bool erase; + } close_settings_with_uid; + struct { + uint8_t index; + } delete_settings_with_index; + struct { + char uid[ESP_BLE_MESH_SETTINGS_UID_SIZE + 1]; + } delete_settings_with_uid; struct ble_mesh_set_fast_prov_info_args { uint16_t unicast_min; uint16_t unicast_max; @@ -363,6 +390,12 @@ esp_ble_mesh_model_t *btc_ble_mesh_model_find(const esp_ble_mesh_elem_t *elem, u const esp_ble_mesh_comp_t *btc_ble_mesh_comp_get(void); +const char *btc_ble_mesh_provisioner_get_settings_uid(uint8_t index); + +uint8_t btc_ble_mesh_provisioner_get_settings_index(const char *uid); + +uint8_t btc_ble_mesh_provisioner_get_free_settings_count(void); + void btc_ble_mesh_model_call_handler(btc_msg_t *msg); void btc_ble_mesh_model_cb_handler(btc_msg_t *msg); diff --git a/components/bt/esp_ble_mesh/mesh_core/net.c b/components/bt/esp_ble_mesh/mesh_core/net.c index eb83b9e802..891ca5e2c1 100644 --- a/components/bt/esp_ble_mesh/mesh_core/net.c +++ b/components/bt/esp_ble_mesh/mesh_core/net.c @@ -1572,16 +1572,9 @@ void bt_mesh_net_init(void) k_work_init(&bt_mesh.local_work, bt_mesh_net_local); } -#if CONFIG_BLE_MESH_DEINIT -void bt_mesh_net_deinit(void) +void bt_mesh_net_reset(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. - */ + k_delayed_work_cancel(&bt_mesh.ivu_timer); #if FRIEND_CRED_COUNT > 0 memset(friend_cred, 0, sizeof(friend_cred)); @@ -1596,4 +1589,18 @@ void bt_mesh_net_deinit(void) bt_mesh.iv_index = 0U; bt_mesh.seq = 0U; } + +#if CONFIG_BLE_MESH_DEINIT +void bt_mesh_net_deinit(void) +{ + bt_mesh_net_reset(); + + 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. + */ +} #endif /* CONFIG_BLE_MESH_DEINIT */ diff --git a/components/bt/esp_ble_mesh/mesh_core/net.h b/components/bt/esp_ble_mesh/mesh_core/net.h index 23e3d4bc16..4521401a5c 100644 --- a/components/bt/esp_ble_mesh/mesh_core/net.h +++ b/components/bt/esp_ble_mesh/mesh_core/net.h @@ -375,6 +375,7 @@ u32_t bt_mesh_next_seq(void); void bt_mesh_net_start(void); void bt_mesh_net_init(void); +void bt_mesh_net_reset(void); void bt_mesh_net_deinit(void); void bt_mesh_net_header_parse(struct net_buf_simple *buf, 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 aa0e5a6fd3..d3be4ee791 100644 --- a/components/bt/esp_ble_mesh/mesh_core/provisioner_main.c +++ b/components/bt/esp_ble_mesh/mesh_core/provisioner_main.c @@ -161,8 +161,7 @@ done: return 0; } -#if CONFIG_BLE_MESH_DEINIT -int bt_mesh_provisioner_deinit(bool erase) +void bt_mesh_provisioner_main_reset(bool erase) { int i; @@ -192,9 +191,13 @@ int bt_mesh_provisioner_deinit(bool erase) } node_count = 0U; +} +#if CONFIG_BLE_MESH_DEINIT +int bt_mesh_provisioner_deinit(bool erase) +{ + bt_mesh_provisioner_main_reset(erase); bt_mesh_provisioner_mutex_free(); - return 0; } #endif /* CONFIG_BLE_MESH_DEINIT */ 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 f81d523ec1..9523ff0c68 100644 --- a/components/bt/esp_ble_mesh/mesh_core/provisioner_main.h +++ b/components/bt/esp_ble_mesh/mesh_core/provisioner_main.h @@ -51,6 +51,8 @@ int bt_mesh_provisioner_init(void); int bt_mesh_provisioner_net_create(void); +void bt_mesh_provisioner_main_reset(bool erase); + int bt_mesh_provisioner_deinit(bool erase); bool bt_mesh_provisioner_check_is_addr_dup(u16_t addr, u8_t elem_num, bool comp_with_own); 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 4928bc860b..fc4fcf8095 100644 --- a/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.c +++ b/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.c @@ -3271,8 +3271,7 @@ int bt_mesh_provisioner_prov_init(const struct bt_mesh_prov *prov_info) return 0; } -#if CONFIG_BLE_MESH_DEINIT -int bt_mesh_provisioner_prov_deinit(bool erase) +int bt_mesh_provisioner_prov_reset(bool erase) { int i; @@ -3281,20 +3280,71 @@ int bt_mesh_provisioner_prov_deinit(bool erase) return -EINVAL; } -#if defined(CONFIG_BLE_MESH_PB_ADV) - for (i = 0; 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 */ - } + for (i = 0; i < BLE_MESH_PROV_SAME_TIME; i++) { + k_delayed_work_cancel(&link[i].timeout); + + prov_memory_free(i); + + if (i < CONFIG_BLE_MESH_PBA_SAME_TIME) { +#if CONFIG_BLE_MESH_PB_ADV + prov_clear_tx(i); +#if CONFIG_BLE_MESH_USE_DUPLICATE_SCAN + bt_mesh_update_exceptional_list(BLE_MESH_EXCEP_LIST_REMOVE, + BLE_MESH_EXCEP_INFO_MESH_LINK_ID, &link[i].link_id); +#endif + memset(&link[i], 0, offsetof(struct prov_link, tx.retransmit)); + link[i].pending_ack = XACT_NVAL; + link[i].rx.prev_id = XACT_NVAL; + link[i].rx.buf = bt_mesh_pba_get_buf(i); #endif /* CONFIG_BLE_MESH_PB_ADV */ + } else { + memset(&link[i], 0, offsetof(struct prov_link, timeout)); + } + + if (bt_mesh_pub_key_get()) { + bt_mesh_atomic_set_bit(link[i].flags, LOCAL_PUB_KEY); + } + } + + /* static_oob_len & static_oob_val are initialized during mesh init. + * When reset the Provisioner, they should not be reset. Otherwise + * users need to invoke the corresponding function to set the static + * oob information before using them. + */ + memset(&prov_ctx, 0, offsetof(struct bt_mesh_prov_ctx, static_oob_len)); + prov_ctx.match_offset = 0; + prov_ctx.match_length = 0; + prov_ctx.prov_after_match = false; + memset(prov_ctx.match_value, 0, sizeof(prov_ctx.match_value)); + memset(&prov_ctx.fast_prov, 0, sizeof(prov_ctx.fast_prov)); + + memset(unprov_dev, 0, sizeof(unprov_dev)); + + if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS) && erase) { + bt_mesh_clear_prov_info(); + } + + return 0; +} + +#if CONFIG_BLE_MESH_DEINIT +int bt_mesh_provisioner_prov_deinit(bool erase) +{ + int i; + + if (prov == NULL) { + BT_ERR("%s, No provisioning context provided", __func__); + return -EINVAL; + } + + bt_mesh_provisioner_prov_reset(erase); for (i = 0; i < BLE_MESH_PROV_SAME_TIME; i++) { - prov_memory_free(i); +#if defined(CONFIG_BLE_MESH_PB_ADV) + if (i < CONFIG_BLE_MESH_PBA_SAME_TIME) { + k_delayed_work_free(&link[i].tx.retransmit); + } +#endif k_delayed_work_free(&link[i].timeout); memset(&link[i], 0, sizeof(link[i])); } @@ -3306,17 +3356,13 @@ int bt_mesh_provisioner_prov_deinit(bool erase) #if defined(CONFIG_BLE_MESH_PB_GATT) bt_mesh_pb_gatt_mutex_free(); #endif - memset(&prov_ctx, 0, sizeof(prov_ctx)); + prov_ctx.static_oob_len = 0U; + memset(prov_ctx.static_oob_val, 0, sizeof(prov_ctx.static_oob_val)); #if defined(CONFIG_BLE_MESH_PB_ADV) memset(adv_buf, 0, sizeof(adv_buf)); memset(adv_buf_data, 0, sizeof(adv_buf_data)); #endif - memset(unprov_dev, 0, sizeof(unprov_dev)); - - if (erase && IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { - bt_mesh_clear_prov_info(); - } prov = NULL; 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 4f2b51f74c..0f877d181c 100644 --- a/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.h +++ b/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.h @@ -142,6 +142,8 @@ 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); +int bt_mesh_provisioner_prov_reset(bool erase); + /** * @brief This function de-initializes provisioner's PB-GATT and PB-ADV * related information. diff --git a/components/bt/esp_ble_mesh/mesh_core/settings.c b/components/bt/esp_ble_mesh/mesh_core/settings.c index 5a9e11ba7e..8c64604c37 100644 --- a/components/bt/esp_ble_mesh/mesh_core/settings.c +++ b/components/bt/esp_ble_mesh/mesh_core/settings.c @@ -20,6 +20,7 @@ #include "mesh_common.h" #include "settings_nvs.h" #include "settings.h" +#include "settings_uid.h" #include "provisioner_main.h" #include "provisioner_prov.h" @@ -2664,4 +2665,14 @@ int bt_mesh_settings_deinit(bool erase) } #endif /* CONFIG_BLE_MESH_DEINIT */ +void bt_mesh_settings_reset(bool erase) +{ + k_delayed_work_cancel(&pending_store); + if (erase) { + bt_mesh_clear_net(); + bt_mesh_clear_seq(); + bt_mesh_clear_role(); + } +} + #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 22bb153f10..19745c7f8b 100644 --- a/components/bt/esp_ble_mesh/mesh_core/settings.h +++ b/components/bt/esp_ble_mesh/mesh_core/settings.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2018 Intel Corporation + * Additional Copyright (c) 2020 Espressif Systems (Shanghai) PTE LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -69,6 +70,7 @@ int settings_core_erase(void); int bt_mesh_settings_init(void); int bt_mesh_settings_deinit(bool erase); +void bt_mesh_settings_reset(bool erase); #ifdef __cplusplus } diff --git a/components/bt/esp_ble_mesh/mesh_core/settings_uid.c b/components/bt/esp_ble_mesh/mesh_core/settings_uid.c new file mode 100644 index 0000000000..db42445ce9 --- /dev/null +++ b/components/bt/esp_ble_mesh/mesh_core/settings_uid.c @@ -0,0 +1,530 @@ +// Copyright 2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include + +#include "mesh.h" +#include "mesh_main.h" +#include "mesh_common.h" +#include "settings_nvs.h" +#include "settings.h" +#include "transport.h" +#include "provisioner_prov.h" + +#if CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE +/* + * key: "mesh/uid" -> write/read to set/get all the user ids. + * key: "mesh/id/xxxx" -> write/read to set/get the "xxxx" user id. + */ +#define SETTINGS_NVS_NAME_SIZE 15 +#define SETTINGS_UID_SIZE 20 +#define INVALID_SETTINGS_INDEX 0xFF +#define INVALID_SETTINGS_HANDLE UINT32_MAX + +static struct settings_uid { + bool open; /* Indicate if settings is open */ + char id[SETTINGS_UID_SIZE + 1]; /* Settings user id */ + char name[SETTINGS_NVS_NAME_SIZE + 1]; /* Settings nvs namespace */ + bt_mesh_nvs_handle_t handle; /* Core Settings nvs handle */ +} user_ids[CONFIG_BLE_MESH_MAX_NVS_NAMESPACE]; + +static int settings_direct_erase(u8_t index); + +static inline bool settings_uid_empty(struct settings_uid *uid) +{ + return (uid->id[0] == '\0') ? true : false; +} + +bt_mesh_nvs_handle_t get_core_settings_handle(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(user_ids); i++) { + if (user_ids[i].open) { + return user_ids[i].handle; + } + } + + BT_ERR("No settings handle found"); + return INVALID_SETTINGS_HANDLE; +} + +int settings_uid_init(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(user_ids); i++) { + memset(&user_ids[i], 0, sizeof(struct settings_uid)); + user_ids[i].handle = INVALID_SETTINGS_HANDLE; + } + + return 0; +} + +int settings_uid_load(void) +{ + struct net_buf_simple *buf = NULL; + char name[16] = {'\0'}; + bool exist = false; + size_t length = 0; + int err = 0; + int i; + + /* Before using user id to search settings, we need to + * restore all the settings user_ids properly. + */ + + buf = bt_mesh_get_uid_settings_item("mesh/uid"); + if (!buf) { + return 0; + } + + length = buf->len; + + for (i = 0; i < length / SETTINGS_ITEM_SIZE; i++) { + u16_t index = net_buf_simple_pull_le16(buf); + + sprintf(name, "mesh/id/%04x", index); + + err = bt_mesh_load_uid_settings(name, (u8_t *)user_ids[index].id, + SETTINGS_UID_SIZE, &exist); + if (err) { + continue; + } + + if (exist == false) { + continue; + } + + BT_INFO("Restored settings %d, uid %s", index, user_ids[index].id); + } + + bt_mesh_free_buf(buf); + return err; +} + +#if CONFIG_BLE_MESH_DEINIT +int settings_uid_deinit(bool erase) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(user_ids); i++) { + memset(&user_ids[i], 0, offsetof(struct settings_uid, handle)); + /* Can not reset handle here, since it will be used + * in the settings_uid_erase(). + */ + } + + return 0; +} + +int settings_uid_erase(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(user_ids); i++) { + if (user_ids[i].open == true) { + /* When a nvs namespace is open, which means it is + * being used currently. And its information will + * be erased when the deinit function is invoked, + * no need to erase it here. + */ + bt_mesh_settings_nvs_close(user_ids[i].handle); + } else if (settings_uid_empty(&user_ids[i]) == false) { + /* When a user id is not empty, which means the nvs + * namespace may contains mesh information, need to + * erase it here. + */ + settings_direct_erase(i); + } + + user_ids[i].handle = INVALID_SETTINGS_HANDLE; + } + + bt_mesh_erase_uid_settings("mesh/uid"); + return 0; +} +#endif /* CONFIG_BLE_MESH_DEINIT */ + +static int settings_direct_erase(u8_t index) +{ + bt_mesh_nvs_handle_t handle = 0; + char name[16] = {'\0'}; + int err = 0; + + sprintf(name, "%s_%02x", "mesh_core", index); + + /* Get handle for core settings */ + err = bt_mesh_settings_nvs_open(name, &handle); + if (err) { + BT_ERR("Open nvs failed, name %s, err %d", name, err); + return -EIO; + } + + /* Erase mesh information */ + err = bt_mesh_settings_erase_all(handle); + if (err) { + BT_ERR("Erase settings failed, index %d", index); + return err; + } + + bt_mesh_settings_nvs_close(handle); + + /* Erase settings user id */ + memset(name, 0, sizeof(name)); + sprintf(name, "mesh/id/%04x", index); + + bt_mesh_erase_uid_settings(name); + bt_mesh_remove_uid_settings_item("mesh/uid", index); + + return 0; +} + +static u8_t settings_index_get(const char *id, u8_t *index) +{ + u8_t idx = 0; + int i; + + for (i = 0; i < ARRAY_SIZE(user_ids); i++) { + if (strlen(user_ids[i].id) != strlen(id)) { + continue; + } + + if (!strncmp(user_ids[i].id, id, strlen(id))) { + idx = i; + break; + } + } + + if (i == ARRAY_SIZE(user_ids)) { + idx = INVALID_SETTINGS_INDEX; + } + + if (index) { + *index = idx; + } + return idx; +} + +static int settings_open(u8_t index) +{ + struct settings_uid *uid = &user_ids[index]; + char name[16] = {'\0'}; + int err = 0; + int i; + + /* Check if the nvs namespace is already open */ + if (uid->open == true) { + BT_WARN("Settings already open, index %d", index); + return -EALREADY; + } + + /* Check if another nvs namespace is already open */ + for (i = 0; i < ARRAY_SIZE(user_ids); i++) { + if (i != index && user_ids[i].open == true) { + BT_ERR("Settings %d is open, close it first", i); + return -EBUSY; + } + } + + memset(uid->name, 0, sizeof(uid->name)); + sprintf(uid->name, "%s_%02x", "mesh_core", index); + + err = bt_mesh_settings_nvs_open(uid->name, &uid->handle); + if (err) { + BT_ERR("Open nvs failed, name %s, err %d", uid->name, err); + return -EIO; + } + + if (settings_uid_empty(uid)) { + /* If the settings is not open with user id, then we use + * the index as the user id. Or when the device restarts, + * the user id may be restored, in this case the user id + * shall not be updated. + */ + sprintf(uid->id, "%04x", index); + } + + BT_INFO("Open settings, index %d, uid %s", index, uid->id); + + sprintf(name, "mesh/id/%04x", index); + err = bt_mesh_save_uid_settings(name, (const u8_t *)uid->id, SETTINGS_UID_SIZE); + if (err) { + BT_ERR("Save uid failed, name %s", name); + return err; + } + + err = bt_mesh_add_uid_settings_item("mesh/uid", index); + if (err) { + BT_ERR("Add uid failed, index %d", index); + return err; + } + + /* Mark this as open here, because we need this flag for + * finding nvs handle before restoring mesh information. + */ + uid->open = true; + + err = settings_core_load(); + if (err) { + BT_ERR("Load settings failed, name %s", uid->name); + return err; + } + + err = settings_core_commit(); + if (err) { + BT_ERR("Commit settings failed, name %s", uid->name); + return err; + } + + return 0; +} + +int bt_mesh_provisioner_open_settings_with_index(u8_t index) +{ + if (index >= ARRAY_SIZE(user_ids)) { + BT_ERR("Invalid settings index %d", index); + return -EINVAL; + } + + return settings_open(index); +} + +int bt_mesh_provisioner_open_settings_with_uid(const char *id, u8_t *index) +{ + u8_t idx = 0; + int i; + + if (!id || strlen(id) > SETTINGS_UID_SIZE) { + BT_ERR("Invalid settings uid"); + return -EINVAL; + } + + idx = settings_index_get(id, index); + + /* If user id not exists, try to add this as a new one. */ + if (idx >= ARRAY_SIZE(user_ids)) { + for (i = 0; i < ARRAY_SIZE(user_ids); i++) { + if (settings_uid_empty(&user_ids[i])) { + strncpy(user_ids[i].id, id, SETTINGS_UID_SIZE); + if (index) { + *index = i; + } + break; + } + } + + if (i == ARRAY_SIZE(user_ids)) { + BT_ERR("Settings uid is full!"); + return -ENOMEM; + } + + idx = i; + } + + return settings_open(idx); +} + +static int settings_close(u8_t index, bool erase) +{ + struct settings_uid *uid = &user_ids[index]; + char name[16] = {'\0'}; + int err = 0; + + if (uid->open == false) { + BT_ERR("Settings not open, index %d", index); + return -EIO; + } + + BT_INFO("Close settings, index %d, uid %s", index, uid->id); + + /* Disable Provisioner firstly */ + err = bt_mesh_provisioner_disable(BLE_MESH_PROV_ADV | BLE_MESH_PROV_GATT); + if (err && err != -EALREADY) { + BT_ERR("Disable Provisioner failed (err %d)", err); + return err; + } + + /* Reset (and erase) mesh information */ + bt_mesh_provisioner_prov_reset(erase); + bt_mesh_provisioner_main_reset(erase); + bt_mesh_net_reset(); + bt_mesh_rx_reset(erase); + bt_mesh_tx_reset(); + bt_mesh_settings_reset(erase); + + if (erase == true) { + /* Erase and reset settings user id */ + sprintf(name, "mesh/id/%04x", index); + + bt_mesh_erase_uid_settings(name); + bt_mesh_remove_uid_settings_item("mesh/uid", index); + + memset(uid->id, 0, sizeof(uid->id)); + } + + bt_mesh_settings_nvs_close(uid->handle); + uid->open = false; + + return 0; +} + +int bt_mesh_provisioner_close_settings_with_index(u8_t index, bool erase) +{ + if (index >= ARRAY_SIZE(user_ids)) { + BT_ERR("Invalid settings index %d", index); + return -EINVAL; + } + + return settings_close(index, erase); +} + +int bt_mesh_provisioner_close_settings_with_uid(const char *id, bool erase, u8_t *index) +{ + u8_t idx = 0; + + if (!id || strlen(id) > SETTINGS_UID_SIZE) { + BT_ERR("Invalid settings uid"); + return -EINVAL; + } + + idx = settings_index_get(id, index); + if (idx >= ARRAY_SIZE(user_ids)) { + BT_ERR("Settings uid %s not exists", id); + return -ENODEV; + } + + return settings_close(idx, erase); +} + +static int settings_delete(u8_t index) +{ + /* The function is used to erase mesh information from + * the nvs namespace when it is not open and restored, + * and delete the corresponding user id. + */ + struct settings_uid *uid = &user_ids[index]; + + if (uid->open == true) { + BT_ERR("Settings being used, index %d", index); + return -EBUSY; + } + + BT_INFO("Delete settings, index %d, uid %s", index, uid->id); + + settings_direct_erase(index); + + memset(uid, 0, sizeof(struct settings_uid)); + uid->handle = INVALID_SETTINGS_HANDLE; + + return 0; +} + +int bt_mesh_provisioner_delete_settings_with_index(u8_t index) +{ + if (index >= ARRAY_SIZE(user_ids)) { + BT_ERR("Invalid settings index %d", index); + return -EINVAL; + } + + return settings_delete(index); +} + +int bt_mesh_provisioner_delete_settings_with_uid(const char *id, u8_t *index) +{ + u8_t idx = 0; + + if (!id || strlen(id) > SETTINGS_UID_SIZE) { + BT_ERR("Invalid settings uid"); + return -EINVAL; + } + + idx = settings_index_get(id, index); + if (idx >= ARRAY_SIZE(user_ids)) { + BT_ERR("Settings uid %s not exists", id); + return -ENODEV; + } + + return settings_delete(idx); +} + +const char *bt_mesh_provisioner_get_settings_uid(u8_t index) +{ + if (index >= ARRAY_SIZE(user_ids)) { + BT_ERR("Invalid settings index %d", index); + return NULL; + } + + return user_ids[index].id; +} + +u8_t bt_mesh_provisioner_get_settings_index(const char *id) +{ + u8_t idx = 0; + + if (!id || strlen(id) > SETTINGS_UID_SIZE) { + BT_ERR("Invalid settings uid"); + return INVALID_SETTINGS_INDEX; + } + + idx = settings_index_get(id, NULL); + if (idx >= ARRAY_SIZE(user_ids)) { + BT_ERR("Settings uid %s not exists", id); + } + + return idx; +} + +u8_t bt_mesh_provisioner_get_free_settings_count(void) +{ + u8_t count = 0; + int i; + + for (i = 0; i < ARRAY_SIZE(user_ids); i++) { + if (settings_uid_empty(&user_ids[i])) { + count++; + } + } + + return count; +} +#endif /* CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE */ + +#if CONFIG_BLE_MESH_SETTINGS && CONFIG_BLE_MESH_PROVISIONER +int bt_mesh_provisioner_direct_erase_settings(void) +{ + bt_mesh_nvs_handle_t handle = 0; + int err = 0; + + err = bt_mesh_settings_direct_open(&handle); + if (err) { + return err; + } + +#if CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE + for (int i = 0; i < ARRAY_SIZE(user_ids); i++) { + settings_direct_erase(i); + } + + bt_mesh_erase_uid_settings("mesh/uid"); +#else + err = bt_mesh_settings_erase_all(handle); +#endif + + bt_mesh_settings_direct_close(); + return err; +} +#endif /* CONFIG_BLE_MESH_SETTINGS && CONFIG_BLE_MESH_PROVISIONER */ diff --git a/components/bt/esp_ble_mesh/mesh_core/settings_uid.h b/components/bt/esp_ble_mesh/mesh_core/settings_uid.h new file mode 100644 index 0000000000..c0348cdf3f --- /dev/null +++ b/components/bt/esp_ble_mesh/mesh_core/settings_uid.h @@ -0,0 +1,47 @@ +// Copyright 2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _SETTINGS_UID_H_ +#define _SETTINGS_UID_H_ + +#include "mesh_types.h" +#include "settings_nvs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int settings_uid_init(void); +int settings_uid_load(void); +int settings_uid_deinit(void); +int settings_uid_erase(void); + +int bt_mesh_provisioner_open_settings_with_index(u8_t index); +int bt_mesh_provisioner_open_settings_with_uid(const char *id, u8_t *index); +int bt_mesh_provisioner_close_settings_with_index(u8_t index, bool erase); +int bt_mesh_provisioner_close_settings_with_uid(const char *id, bool erase, u8_t *index); +int bt_mesh_provisioner_delete_settings_with_index(u8_t index); +int bt_mesh_provisioner_delete_settings_with_uid(const char *id, u8_t *index); + +const char *bt_mesh_provisioner_get_settings_uid(u8_t index); +u8_t bt_mesh_provisioner_get_settings_index(const char *id); +u8_t bt_mesh_provisioner_get_free_settings_count(void); + +int bt_mesh_provisioner_direct_erase_settings(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _SETTINGS_UID_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 8786598722..eb1a68c990 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 @@ -16,13 +16,16 @@ #include #include "mesh_common.h" -#include "settings_nvs.h" +#include "settings_uid.h" #include "settings.h" #if CONFIG_BLE_MESH_SETTINGS enum settings_type { SETTINGS_CORE, +#if CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE + SETTINGS_UID, +#endif }; struct settings_context { @@ -49,10 +52,36 @@ static struct settings_context settings_ctx[] = { .settings_erase = settings_core_erase, #endif /* CONFIG_BLE_MESH_DEINIT */ }, +#if CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE + [SETTINGS_UID] = { + .nvs_name = "mesh_user_id", + .settings_init = settings_uid_init, + .settings_load = settings_uid_load, + .settings_commit = NULL, +#if CONFIG_BLE_MESH_DEINIT + .settings_deinit = settings_uid_deinit, + .settings_erase = settings_uid_erase, +#endif /* CONFIG_BLE_MESH_DEINIT */ + }, +#endif /* CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE */ }; /* API used to initialize, load and commit BLE Mesh related settings */ +int bt_mesh_settings_nvs_open(const char* name, bt_mesh_nvs_handle_t *handle) +{ +#if CONFIG_BLE_MESH_SPECIFIC_PARTITION + return nvs_open_from_partition(CONFIG_BLE_MESH_PARTITION_NAME, name, NVS_READWRITE, handle); +#else + return nvs_open(name, NVS_READWRITE, handle); +#endif +} + +void bt_mesh_settings_nvs_close(bt_mesh_nvs_handle_t handle) +{ + nvs_close(handle); +} + void bt_mesh_settings_init_foreach(void) { int err = 0; @@ -61,37 +90,49 @@ void bt_mesh_settings_init_foreach(void) #if CONFIG_BLE_MESH_SPECIFIC_PARTITION err = nvs_flash_init_partition(CONFIG_BLE_MESH_PARTITION_NAME); if (err != ESP_OK) { - BT_ERR("Failed to init mesh partition, name %s, err %d", CONFIG_BLE_MESH_PARTITION_NAME, err); + BT_ERR("Init mesh partition failed, name %s, err %d", CONFIG_BLE_MESH_PARTITION_NAME, err); return; } -#endif +#endif /* CONFIG_BLE_MESH_SPECIFIC_PARTITION */ for (i = 0; i < ARRAY_SIZE(settings_ctx); i++) { struct settings_context *ctx = &settings_ctx[i]; -#if CONFIG_BLE_MESH_SPECIFIC_PARTITION - err = nvs_open_from_partition(CONFIG_BLE_MESH_PARTITION_NAME, ctx->nvs_name, NVS_READWRITE, &ctx->handle); -#else - err = nvs_open(ctx->nvs_name, NVS_READWRITE, &ctx->handle); -#endif - if (err != ESP_OK) { - BT_ERR("Open nvs failed, name %s, err %d", ctx->nvs_name, err); - continue; - } - + /* Settings initialization is always needed. */ if (ctx->settings_init && ctx->settings_init()) { BT_ERR("Init settings failed, name %s", ctx->nvs_name); + return; + } + +#if CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE + /* If multiple nvs namespace functionality is enabled, + * no need to perform the following operations during + * initialization. And they will be performed when the + * application layer tries to open settings. + */ + if (i != SETTINGS_UID) { continue; } +#endif /* CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE */ + + err = bt_mesh_settings_nvs_open(ctx->nvs_name, &ctx->handle); + if (err) { + BT_ERR("Open nvs failed, name %s, err %d", ctx->nvs_name, err); + return; + } if (ctx->settings_load && ctx->settings_load()) { BT_ERR("Load settings failed, name %s", ctx->nvs_name); - continue; + return; } + /* If not using multiple nvs namespaces, we will follow the normal + * procedure, i.e. restoring all the mesh information. + * If using multiple nvs namespaces, we will only restore user_id. + */ if (ctx->settings_commit && ctx->settings_commit()) { BT_ERR("Commit settings failed, name %s", ctx->nvs_name); - continue; + return; } } } @@ -114,7 +155,7 @@ void bt_mesh_settings_deinit_foreach(bool erase) continue; } - nvs_close(ctx->handle); + bt_mesh_settings_nvs_close(ctx->handle); } #if CONFIG_BLE_MESH_SPECIFIC_PARTITION @@ -123,10 +164,59 @@ void bt_mesh_settings_deinit_foreach(bool erase) } #endif /* CONFIG_BLE_MESH_DEINIT */ +int bt_mesh_settings_direct_open(bt_mesh_nvs_handle_t *handle) +{ + int err = 0; + int i; + +#if CONFIG_BLE_MESH_SPECIFIC_PARTITION + err = nvs_flash_init_partition(CONFIG_BLE_MESH_PARTITION_NAME); + if (err != ESP_OK) { + BT_ERR("Init mesh partition failed, name %s, err %d", CONFIG_BLE_MESH_PARTITION_NAME, err); + return -EIO; + } +#endif /* CONFIG_BLE_MESH_SPECIFIC_PARTITION */ + + for (i = 0; i < ARRAY_SIZE(settings_ctx); i++) { + struct settings_context *ctx = &settings_ctx[i]; + + err = bt_mesh_settings_nvs_open(ctx->nvs_name, &ctx->handle); + if (err) { + BT_ERR("Open nvs failed, name %s, err %d", ctx->nvs_name, err); + return -EIO; + } + + if (i == SETTINGS_CORE && handle) { + *handle = ctx->handle; + } + } + + return 0; +} + +void bt_mesh_settings_direct_close(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(settings_ctx); i++) { + bt_mesh_settings_nvs_close(settings_ctx[i].handle); + } + +#if CONFIG_BLE_MESH_SPECIFIC_PARTITION + nvs_flash_deinit_partition(CONFIG_BLE_MESH_PARTITION_NAME); +#endif +} + /* API used to get BLE Mesh related nvs handle */ static inline bt_mesh_nvs_handle_t settings_get_nvs_handle(enum settings_type type) { +#if CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE + if (type == SETTINGS_CORE) { + extern bt_mesh_nvs_handle_t get_core_settings_handle(void); + return get_core_settings_handle(); + } +#endif return settings_ctx[type].handle; } @@ -183,6 +273,14 @@ int bt_mesh_save_core_settings(const char *key, const u8_t *val, size_t len) return bt_mesh_save_settings(handle, key, val, len); } +#if CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE +int bt_mesh_save_uid_settings(const char *key, const u8_t *val, size_t len) +{ + bt_mesh_nvs_handle_t handle = settings_get_nvs_handle(SETTINGS_UID); + return bt_mesh_save_settings(handle, key, val, len); +} +#endif + int bt_mesh_erase_settings(bt_mesh_nvs_handle_t handle, const char *key) { return bt_mesh_save_settings(handle, key, NULL, 0); @@ -193,6 +291,13 @@ int bt_mesh_erase_core_settings(const char *key) return bt_mesh_save_core_settings(key, NULL, 0); } +#if CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE +int bt_mesh_erase_uid_settings(const char *name) +{ + return bt_mesh_save_uid_settings(name, NULL, 0); +} +#endif + /* API used to load BLE Mesh related settings */ static int settings_load(bt_mesh_nvs_handle_t handle, const char *key, @@ -237,6 +342,14 @@ int bt_mesh_load_core_settings(const char *key, u8_t *buf, size_t buf_len, bool return bt_mesh_load_settings(handle, key, buf, buf_len, exist); } +#if CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE +int bt_mesh_load_uid_settings(const char *key, u8_t *buf, size_t buf_len, bool *exist) +{ + bt_mesh_nvs_handle_t handle = settings_get_nvs_handle(SETTINGS_UID); + return bt_mesh_load_settings(handle, key, buf, buf_len, exist); +} +#endif + /* API used to get length of BLE Mesh related settings */ static size_t settings_get_length(bt_mesh_nvs_handle_t handle, const char *key) @@ -317,6 +430,14 @@ struct net_buf_simple *bt_mesh_get_core_settings_item(const char *key) return bt_mesh_get_settings_item(handle, key); } +#if CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE +struct net_buf_simple *bt_mesh_get_uid_settings_item(const char *key) +{ + bt_mesh_nvs_handle_t handle = settings_get_nvs_handle(SETTINGS_UID); + return bt_mesh_get_settings_item(handle, key); +} +#endif + /* API used to check if the settings item exists */ static bool is_settings_item_exist(struct net_buf_simple *buf, const u16_t val) @@ -398,6 +519,14 @@ int bt_mesh_add_core_settings_item(const char *key, const u16_t val) return bt_mesh_add_settings_item(handle, key, val); } +#if CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE +int bt_mesh_add_uid_settings_item(const char *key, const u16_t val) +{ + bt_mesh_nvs_handle_t handle = settings_get_nvs_handle(SETTINGS_UID); + return bt_mesh_add_settings_item(handle, key, val); +} +#endif + /* API used to remove the settings item */ static int settings_remove_item(bt_mesh_nvs_handle_t handle, const char *key, const u16_t val) @@ -462,4 +591,53 @@ int bt_mesh_remove_core_settings_item(const char *key, const u16_t val) return bt_mesh_remove_settings_item(handle, key, val); } +#if CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE +int bt_mesh_remove_uid_settings_item(const char *key, const u16_t val) +{ + bt_mesh_nvs_handle_t handle = settings_get_nvs_handle(SETTINGS_UID); + return bt_mesh_remove_settings_item(handle, key, val); +} +#endif + +int bt_mesh_settings_erase_key(bt_mesh_nvs_handle_t handle, const char *key) +{ + int err = 0; + + err = nvs_erase_key(handle, key); + if (err != ESP_OK) { + if (err == ESP_ERR_NVS_NOT_FOUND) { + return 0; + } + + BT_ERR("Failed to erase %s (err %d)", key, err); + return -EIO; + } + + err = nvs_commit(handle); + if (err != ESP_OK) { + BT_ERR("Failed to commit nvs (err %d)", err); + return -EIO; + } + + return 0; +} + +int bt_mesh_settings_erase_all(bt_mesh_nvs_handle_t handle) +{ + int err = 0; + + err = nvs_erase_all(handle); + if (err != ESP_OK) { + BT_ERR("Failed to erase all (err %d)", err); + return -EIO; + } + + err = nvs_commit(handle); + if (err != ESP_OK) { + BT_ERR("Failed to commit nvs (err %d)", err); + return -EIO; + } + + return 0; +} #endif /* CONFIG_BLE_MESH_SETTINGS */ 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 91c7341e67..9987a3ab6b 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,28 +30,43 @@ typedef nvs_handle_t bt_mesh_nvs_handle_t; #define BLE_MESH_GET_MODEL_IDX(x) ((u8_t)(x)) #define BLE_MESH_GET_MODEL_KEY(a, b) ((u16_t)(((u16_t)((a) << 8)) | (b))) +int bt_mesh_settings_nvs_open(const char* name, bt_mesh_nvs_handle_t *handle); +void bt_mesh_settings_nvs_close(bt_mesh_nvs_handle_t handle); + void bt_mesh_settings_init_foreach(void); void bt_mesh_settings_deinit_foreach(bool erase); +int bt_mesh_settings_direct_open(bt_mesh_nvs_handle_t *handle); +void bt_mesh_settings_direct_close(void); + int bt_mesh_save_settings(bt_mesh_nvs_handle_t handle, const char *key, const u8_t *val, size_t len); int bt_mesh_save_core_settings(const char *key, const u8_t *val, size_t len); +int bt_mesh_save_uid_settings(const char *key, const u8_t *val, size_t len); int bt_mesh_erase_settings(bt_mesh_nvs_handle_t handle, const char *key); int bt_mesh_erase_core_settings(const char *key); +int bt_mesh_erase_uid_settings(const char *name); int bt_mesh_load_settings(bt_mesh_nvs_handle_t handle, const char *key, u8_t *buf, size_t buf_len, bool *exist); int bt_mesh_load_core_settings(const char *key, u8_t *buf, size_t buf_len, bool *exist); +int bt_mesh_load_uid_settings(const char *key, u8_t *buf, size_t buf_len, bool *exist); struct net_buf_simple *bt_mesh_get_settings_item(bt_mesh_nvs_handle_t handle, const char *key); struct net_buf_simple *bt_mesh_get_core_settings_item(const char *key); +struct net_buf_simple *bt_mesh_get_uid_settings_item(const char *key); int bt_mesh_add_settings_item(bt_mesh_nvs_handle_t handle, const char *key, const u16_t val); int bt_mesh_add_core_settings_item(const char *key, const u16_t val); +int bt_mesh_add_uid_settings_item(const char *key, const u16_t val); int bt_mesh_remove_settings_item(bt_mesh_nvs_handle_t handle, const char *key, const u16_t val); int bt_mesh_remove_core_settings_item(const char *key, const u16_t val); +int bt_mesh_remove_uid_settings_item(const char *key, const u16_t val); + +int bt_mesh_settings_erase_key(bt_mesh_nvs_handle_t handle, const char *key); +int bt_mesh_settings_erase_all(bt_mesh_nvs_handle_t handle); #ifdef __cplusplus }