ble_mesh: stack: Provisioner supports multiple nvs namespaces

Now Provisioner can use different NVS namespaces to store
different instances of mesh information, for example, for
different user accounts.
This commit is contained in:
lly 2020-11-24 20:51:09 +08:00
parent 9fd5138ce2
commit a90e3cdf95
19 changed files with 1439 additions and 70 deletions

View File

@ -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"

View File

@ -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

View File

@ -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)

View File

@ -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.
*

View File

@ -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
*/

View File

@ -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,
&param.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,
&param.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,
&param.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:

View File

@ -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);

View File

@ -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 */

View File

@ -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,

View File

@ -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 */

View File

@ -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);

View File

@ -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;

View File

@ -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.

View File

@ -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 */

View File

@ -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
}

View File

@ -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 <errno.h>
#include <string.h>
#include <stdint.h>
#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 */

View File

@ -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_ */

View File

@ -16,13 +16,16 @@
#include <errno.h>
#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 */

View File

@ -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
}