Merge branch 'bugfix/ble_mesh_rpl_list_size_v4.0' into 'release/v4.0'

ble_mesh: Associate replay protection list size with nodes count (v4.0)

See merge request espressif/esp-idf!8495
This commit is contained in:
Island 2020-05-06 11:14:21 +08:00
commit 5f71ec3640
12 changed files with 208 additions and 225 deletions

View file

@ -56,7 +56,7 @@ if BLE_MESH
config BLE_MESH_WAIT_FOR_PROV_MAX_DEV_NUM
int "Maximum number of unprovisioned devices that can be added to device queue"
default 20
default 10
range 1 100
help
This option specifies how many unprovisioned devices can be added to device
@ -64,20 +64,9 @@ if BLE_MESH
queue in the bottom layer which is used to store unprovisioned device
information (e.g. Device UUID, address).
config BLE_MESH_MAX_STORED_NODES
int "Maximum number of nodes whose information can be stored"
default 20
range BLE_MESH_MAX_PROV_NODES 1000
help
This option specifies the maximum number of nodes whose information can be
stored by a Provisioner in its upper layer.
Users can change this value according to the number of nodes whose information
(e.g. Device UUID, unicast address, element number) are going to be stored by
a Provisioner. And the nodes include the provisioned ones and user-added ones.
config BLE_MESH_MAX_PROV_NODES
int "Maximum number of devices that can be provisioned by Provisioner"
default 20
default 10
range 1 1000
help
This option specifies how many devices can be provisioned by a Provisioner.
@ -348,6 +337,11 @@ if BLE_MESH
The replay protection list is used to prevent a node from replay attack,
which will store the source address and sequence number of the received
mesh messages.
For Provisioner, the replay protection list size should not be smaller than
the maximum number of nodes whose information can be stored. And the element
number of each node should also be taken into consideration. For example, if
Provisioner can provision up to 20 nodes and each node contains two elements,
then the replay protection list size of Provisioner should be at least 40.
config BLE_MESH_MSG_CACHE_SIZE
int "Network message cache size"

View file

@ -994,7 +994,7 @@ const esp_ble_mesh_comp_t *btc_ble_mesh_comp_get(void)
u16_t btc_ble_mesh_provisioner_get_prov_node_count(void)
{
return bt_mesh_provisioner_get_prov_node_count();
return bt_mesh_provisioner_get_node_count();
}
/* Configuration Models */
@ -1783,7 +1783,7 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg)
act = ESP_BLE_MESH_PROVISIONER_DELETE_NODE_WITH_ADDR_COMP_EVT;
param.provisioner_delete_node_with_addr_comp.unicast_addr = arg->delete_node_with_addr.unicast_addr;
param.provisioner_delete_node_with_addr_comp.err_code =
bt_mesh_provisioner_delete_node_with_addr(arg->delete_node_with_addr.unicast_addr);
bt_mesh_provisioner_delete_node_with_node_addr(arg->delete_node_with_addr.unicast_addr);
break;
#endif /* CONFIG_BLE_MESH_PROVISIONER */
#if CONFIG_BLE_MESH_FAST_PROV

View file

@ -269,7 +269,7 @@ static bool ready_to_send(void)
}
if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) && bt_mesh_is_provisioner_en()) {
if (bt_mesh_provisioner_get_all_node_count()) {
if (bt_mesh_provisioner_get_node_count()) {
return true;
}
}

View file

@ -1389,7 +1389,7 @@ static bool ready_to_recv(void)
if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) {
return true;
} else if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) && bt_mesh_is_provisioner_en()) {
if (bt_mesh_provisioner_get_all_node_count()) {
if (bt_mesh_provisioner_get_node_count()) {
return true;
}
}

View file

@ -29,10 +29,9 @@
#if CONFIG_BLE_MESH_PROVISIONER
static struct bt_mesh_node *mesh_nodes[CONFIG_BLE_MESH_MAX_STORED_NODES];
static struct bt_mesh_node *mesh_nodes[CONFIG_BLE_MESH_MAX_PROV_NODES];
static bt_mesh_mutex_t provisioner_lock;
static u16_t all_node_count;
static u16_t prov_node_count;
static u16_t node_count;
static int provisioner_remove_node(u16_t index, bool erase);
@ -195,12 +194,11 @@ int bt_mesh_provisioner_deinit(bool erase)
bt_mesh_clear_p_app_idx();
}
for (i = 0; i < CONFIG_BLE_MESH_MAX_STORED_NODES; i++) {
for (i = 0; i < CONFIG_BLE_MESH_MAX_PROV_NODES; i++) {
provisioner_remove_node(i, erase);
}
all_node_count = 0U;
prov_node_count = 0U;
node_count = 0U;
bt_mesh_provisioner_mutex_free();
@ -249,45 +247,31 @@ bool bt_mesh_provisioner_check_is_addr_dup(u16_t addr, u8_t elem_num, bool comp_
return false;
}
static void provisioner_node_count_inc(bool prov)
static void provisioner_node_count_inc(void)
{
all_node_count++;
if (prov) {
prov_node_count++;
node_count++;
}
static void provisioner_node_count_dec(void)
{
if (node_count) {
node_count--;
}
}
static void provisioner_node_count_dec(bool prov)
u16_t bt_mesh_provisioner_get_node_count(void)
{
if (all_node_count) {
all_node_count--;
}
if (prov) {
if (prov_node_count) {
prov_node_count--;
}
}
return node_count;
}
u16_t bt_mesh_provisioner_get_prov_node_count(void)
static int provisioner_store_node(struct bt_mesh_node *node, bool store, u16_t *index)
{
return prov_node_count;
}
u16_t bt_mesh_provisioner_get_all_node_count(void)
{
return all_node_count;
}
static int provisioner_store_node(struct bt_mesh_node *node, bool prov, bool store, u16_t *index)
{
u16_t min = 0U, max = 0U;
size_t i = 0U;
int i;
bt_mesh_provisioner_lock();
/* Check if the node already exists */
for (i = 0U; i < ARRAY_SIZE(mesh_nodes); i++) {
for (i = 0; i < ARRAY_SIZE(mesh_nodes); i++) {
if (mesh_nodes[i] && !memcmp(mesh_nodes[i]->dev_uuid, node->dev_uuid, 16)) {
BT_WARN("Node already exists, uuid %s", bt_hex(node->dev_uuid, 16));
bt_mesh_provisioner_unlock();
@ -295,19 +279,7 @@ static int provisioner_store_node(struct bt_mesh_node *node, bool prov, bool sto
}
}
/**
* 0 ~ (CONFIG_BLE_MESH_MAX_PROV_NODES - 1) are used to store
* the information of self-provisioned nodes.
*/
if (prov) {
min = 0U;
max = CONFIG_BLE_MESH_MAX_PROV_NODES;
} else {
min = CONFIG_BLE_MESH_MAX_PROV_NODES;
max = ARRAY_SIZE(mesh_nodes);
}
for (i = min; i < max; i++) {
for (i = 0; i < ARRAY_SIZE(mesh_nodes); i++) {
if (mesh_nodes[i] == NULL) {
mesh_nodes[i] = bt_mesh_calloc(sizeof(struct bt_mesh_node));
if (!mesh_nodes[i]) {
@ -317,13 +289,13 @@ static int provisioner_store_node(struct bt_mesh_node *node, bool prov, bool sto
}
memcpy(mesh_nodes[i], node, sizeof(struct bt_mesh_node));
provisioner_node_count_inc(prov);
provisioner_node_count_inc();
if (index) {
*index = i;
}
if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS) && store) {
bt_mesh_store_node_info(mesh_nodes[i], prov);
bt_mesh_store_node_info(mesh_nodes[i]);
}
bt_mesh_provisioner_unlock();
@ -336,14 +308,14 @@ static int provisioner_store_node(struct bt_mesh_node *node, bool prov, bool sto
return -ENOMEM;
}
int bt_mesh_provisioner_restore_node_info(struct bt_mesh_node *node, bool prov)
int bt_mesh_provisioner_restore_node_info(struct bt_mesh_node *node)
{
if (!node) {
BT_ERR("%s, Invalid parameter", __func__);
return -EINVAL;
}
return provisioner_store_node(node, prov, false, NULL);
return provisioner_store_node(node, false, NULL);
}
int bt_mesh_provisioner_provision(const bt_mesh_addr_t *addr, const u8_t uuid[16], u16_t oob_info,
@ -375,13 +347,12 @@ int bt_mesh_provisioner_provision(const bt_mesh_addr_t *addr, const u8_t uuid[16
node.iv_index = iv_index;
memcpy(node.dev_key, dev_key, 16);
return provisioner_store_node(&node, true, true, index);
return provisioner_store_node(&node, true, index);
}
static int provisioner_remove_node(u16_t index, bool erase)
{
struct bt_mesh_node *node = NULL;
bool is_prov = false;
int i;
BT_DBG("%s, reset node %d", __func__, index);
@ -410,10 +381,8 @@ static int provisioner_remove_node(u16_t index, bool erase)
bt_mesh_friend_remove_lpn(node->unicast_addr);
}
is_prov = index < CONFIG_BLE_MESH_MAX_PROV_NODES ? true : false;
if (erase && IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
bt_mesh_clear_node_info(node->unicast_addr, is_prov);
bt_mesh_clear_node_info(node->unicast_addr);
}
if (mesh_nodes[index]->comp_data) {
@ -422,7 +391,7 @@ static int provisioner_remove_node(u16_t index, bool erase)
bt_mesh_free(mesh_nodes[index]);
mesh_nodes[index] = NULL;
provisioner_node_count_dec(is_prov);
provisioner_node_count_dec();
bt_mesh_provisioner_unlock();
return 0;
@ -455,41 +424,6 @@ static struct bt_mesh_node *provisioner_find_node_with_uuid(const u8_t uuid[16],
return NULL;
}
bool bt_mesh_provisioner_find_node_with_uuid(const u8_t uuid[16], bool reset)
{
struct bt_mesh_node *node = NULL;
u16_t index = 0U;
node = provisioner_find_node_with_uuid(uuid, &index);
if (!node) {
return false;
}
if (reset) {
provisioner_remove_node(index, true);
}
return true;
}
bool bt_mesh_provisioner_find_node_with_addr(const bt_mesh_addr_t *addr, bool reset)
{
int i;
for (i = 0; i < ARRAY_SIZE(mesh_nodes); i++) {
if (mesh_nodes[i]) {
if (!memcmp(mesh_nodes[i]->addr, addr->val, BLE_MESH_ADDR_LEN) &&
mesh_nodes[i]->addr_type == addr->type) {
if (reset) {
provisioner_remove_node(i, true);
}
return true;
}
}
}
return false;
}
int bt_mesh_provisioner_remove_node(const u8_t uuid[16])
{
struct bt_mesh_node *node = NULL;
@ -559,7 +493,7 @@ int bt_mesh_provisioner_restore_node_name(u16_t addr, const char *name)
return 0;
}
int bt_mesh_provisioner_restore_node_comp_data(u16_t addr, const u8_t *data, u16_t length, bool prov)
int bt_mesh_provisioner_restore_node_comp_data(u16_t addr, const u8_t *data, u16_t length)
{
struct bt_mesh_node *node = NULL;
@ -611,7 +545,7 @@ int bt_mesh_provisioner_delete_node_with_uuid(const u8_t uuid[16])
return 0;
}
int bt_mesh_provisioner_delete_node_with_addr(u16_t unicast_addr)
int bt_mesh_provisioner_delete_node_with_node_addr(u16_t unicast_addr)
{
struct bt_mesh_node *node = NULL;
u16_t index = 0U;
@ -626,6 +560,21 @@ int bt_mesh_provisioner_delete_node_with_addr(u16_t unicast_addr)
return 0;
}
int bt_mesh_provisioner_delete_node_with_dev_addr(const bt_mesh_addr_t *addr)
{
int i;
for (i = 0; i < ARRAY_SIZE(mesh_nodes); i++) {
if (mesh_nodes[i] && mesh_nodes[i]->addr_type == addr->type &&
!memcmp(mesh_nodes[i]->addr, addr->val, BLE_MESH_ADDR_LEN)) {
return provisioner_remove_node(i, true);
}
}
BT_WARN("Node not exist, device address %s", bt_hex(addr->val, BLE_MESH_ADDR_LEN));
return -ENODEV;
}
static int provisioner_check_node_index(u16_t index)
{
BT_DBG("%s", __func__);
@ -677,11 +626,10 @@ int bt_mesh_provisioner_set_node_name(u16_t index, const char *name)
}
memset(mesh_nodes[index]->name, 0, BLE_MESH_NODE_NAME_SIZE);
strncpy(mesh_nodes[index]->name, name, length);
if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
bt_mesh_store_node_name(mesh_nodes[index],
index < CONFIG_BLE_MESH_MAX_PROV_NODES ? true : false);
bt_mesh_store_node_name(mesh_nodes[index]);
}
return 0;
@ -757,8 +705,7 @@ int bt_mesh_provisioner_store_node_comp_data(u16_t addr, const u8_t *data, u16_t
node->comp_length = length;
if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
bt_mesh_store_node_comp_data(node,
index < CONFIG_BLE_MESH_MAX_PROV_NODES ? true : false);
bt_mesh_store_node_comp_data(node);
}
return 0;
@ -1545,6 +1492,8 @@ int bt_mesh_print_local_composition_data(void)
#if CONFIG_BLE_MESH_TEST_AUTO_ENTER_NETWORK
int bt_mesh_provisioner_store_node_info(struct bt_mesh_node *node)
{
int err = 0;
if (!node) {
BT_ERR("%s, Invalid parameter", __func__);
return -EINVAL;
@ -1565,12 +1514,24 @@ int bt_mesh_provisioner_store_node_info(struct bt_mesh_node *node)
return -EINVAL;
}
if (node->unicast_addr + node->element_num - 1 > 0x7FFF) {
BT_ERR("%s, Not enough unicast address for the node", __func__);
return -EIO;
}
if (bt_mesh_provisioner_net_key_get(node->net_idx) == NULL) {
BT_ERR("%s, Invalid NetKey Index 0x%03x", __func__, node->net_idx);
return -EINVAL;
}
return provisioner_store_node(node, false, true, NULL);
err = provisioner_store_node(node, true, NULL);
if (err) {
BT_ERR("%s, Failed to store node info", __func__);
return err;
}
bt_mesh_test_provisioner_update_alloc_addr(node->unicast_addr, node->element_num);
return 0;
}
#endif /* CONFIG_BLE_MESH_TEST_AUTO_ENTER_NETWORK */

View file

@ -55,25 +55,19 @@ 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);
u16_t bt_mesh_provisioner_get_prov_node_count(void);
u16_t bt_mesh_provisioner_get_node_count(void);
u16_t bt_mesh_provisioner_get_all_node_count(void);
int bt_mesh_provisioner_restore_node_info(struct bt_mesh_node *node, bool prov);
int bt_mesh_provisioner_restore_node_info(struct bt_mesh_node *node);
int bt_mesh_provisioner_provision(const bt_mesh_addr_t *addr, const u8_t uuid[16], u16_t oob_info,
u16_t unicast_addr, u8_t element_num, u16_t net_idx, u8_t flags,
u32_t iv_index, const u8_t dev_key[16], u16_t *index);
bool bt_mesh_provisioner_find_node_with_uuid(const u8_t uuid[16], bool reset);
bool bt_mesh_provisioner_find_node_with_addr(const bt_mesh_addr_t *addr, bool reset);
int bt_mesh_provisioner_remove_node(const u8_t uuid[16]);
int bt_mesh_provisioner_restore_node_name(u16_t addr, const char *name);
int bt_mesh_provisioner_restore_node_comp_data(u16_t addr, const u8_t *data, u16_t length, bool prov);
int bt_mesh_provisioner_restore_node_comp_data(u16_t addr, const u8_t *data, u16_t length);
struct bt_mesh_node *bt_mesh_provisioner_get_node_with_uuid(const u8_t uuid[16]);
@ -81,7 +75,9 @@ struct bt_mesh_node *bt_mesh_provisioner_get_node_with_addr(u16_t unicast_addr);
int bt_mesh_provisioner_delete_node_with_uuid(const u8_t uuid[16]);
int bt_mesh_provisioner_delete_node_with_addr(u16_t unicast_addr);
int bt_mesh_provisioner_delete_node_with_node_addr(u16_t unicast_addr);
int bt_mesh_provisioner_delete_node_with_dev_addr(const bt_mesh_addr_t *addr);
int bt_mesh_provisioner_set_node_name(u16_t index, const char *name);

View file

@ -552,7 +552,7 @@ static bool is_unprov_dev_being_provision(const u8_t uuid[16])
* Unprovisioned Device Beacon when Transaction ACK for Provisioning Complete
* is received). So in Fast Provisioning the Provisioner should ignore this.
*/
if (bt_mesh_provisioner_find_node_with_uuid(uuid, false)) {
if (bt_mesh_provisioner_get_node_with_uuid(uuid)) {
BT_WARN("Device has already been provisioned");
return true;
}
@ -625,17 +625,11 @@ static int provisioner_check_unprov_dev_info(const u8_t uuid[16], bt_mesh_prov_b
}
/* Check if the device has already been provisioned */
if (bt_mesh_provisioner_find_node_with_uuid(uuid, false)) {
BT_WARN("Provisioned before, start to provision again");
if (bt_mesh_provisioner_get_node_with_uuid(uuid)) {
BT_INFO("Provisioned before, start to provision again");
return 0;
}
/* Check if the provisioned nodes queue is full */
if (bt_mesh_provisioner_get_prov_node_count() == CONFIG_BLE_MESH_MAX_PROV_NODES) {
BT_WARN("Current provisioned devices reach max limit");
return -ENOMEM;
}
return 0;
}
@ -660,6 +654,7 @@ static int provisioner_start_prov_pb_adv(const u8_t uuid[16], const bt_mesh_addr
if (assign_addr == BLE_MESH_ADDR_UNASSIGNED &&
prov_ctx.curr_alloc_addr == BLE_MESH_ADDR_UNASSIGNED) {
BT_ERR("No available unicast address to assign");
bt_mesh_pb_adv_unlock();
return -EIO;
}
@ -718,6 +713,7 @@ static int provisioner_start_prov_pb_gatt(const u8_t uuid[16], const bt_mesh_add
if (assign_addr == BLE_MESH_ADDR_UNASSIGNED &&
prov_ctx.curr_alloc_addr == BLE_MESH_ADDR_UNASSIGNED) {
BT_ERR("No available unicast address to assign");
bt_mesh_pb_gatt_unlock();
return -EIO;
}
@ -818,6 +814,14 @@ int bt_mesh_provisioner_add_unprov_dev(struct bt_mesh_unprov_dev_add *add_dev, u
#endif
}
/* Check if the provisioned nodes array is full */
if (bt_mesh_provisioner_get_node_with_uuid(add_dev->uuid) == NULL) {
if (bt_mesh_provisioner_get_node_count() == CONFIG_BLE_MESH_MAX_PROV_NODES) {
BT_WARN("Current provisioned devices reach max limit");
return -ENOMEM;
}
}
add_addr.type = add_dev->addr_type;
memcpy(add_addr.val, add_dev->addr, BLE_MESH_ADDR_LEN);
@ -877,10 +881,12 @@ start:
}
/* Check if current provisioned node count + active link reach max limit */
if (bt_mesh_provisioner_get_prov_node_count() + prov_ctx.pba_count + \
prov_ctx.pbg_count >= CONFIG_BLE_MESH_MAX_PROV_NODES) {
BT_ERR("Node count + active link count reach max limit");
return -EIO;
if (bt_mesh_provisioner_get_node_with_uuid(add_dev->uuid) == NULL) {
if (bt_mesh_provisioner_get_node_count() + prov_ctx.pba_count + \
prov_ctx.pbg_count >= CONFIG_BLE_MESH_MAX_PROV_NODES) {
BT_WARN("Node count + active link count reach max limit");
return -EIO;
}
}
if ((err = provisioner_check_unprov_dev_info(add_dev->uuid, add_dev->bearer))) {
@ -952,11 +958,19 @@ int bt_mesh_provisioner_prov_device_with_addr(const u8_t uuid[16], const u8_t ad
* can not know the exactly allocated addresses of them.
*/
/* Check if current provisioned node count + active link reach max limit */
if (bt_mesh_provisioner_get_prov_node_count() + prov_ctx.pba_count + \
prov_ctx.pbg_count >= CONFIG_BLE_MESH_MAX_PROV_NODES) {
BT_ERR("Node count + active link count reach max limit");
return -EIO;
if (bt_mesh_provisioner_get_node_with_uuid(uuid) == NULL) {
/* Check if the provisioned nodes array is full */
if (bt_mesh_provisioner_get_node_count() == CONFIG_BLE_MESH_MAX_PROV_NODES) {
BT_WARN("Current provisioned devices reach max limit");
return -ENOMEM;
}
/* Check if current provisioned node count + active link reach max limit */
if (bt_mesh_provisioner_get_node_count() + prov_ctx.pba_count + \
prov_ctx.pbg_count >= CONFIG_BLE_MESH_MAX_PROV_NODES) {
BT_WARN("Node count + active link count reach max limit");
return -EIO;
}
}
if ((err = provisioner_check_unprov_dev_info(uuid, bearer))) {
@ -1049,15 +1063,11 @@ int bt_mesh_provisioner_delete_device(struct bt_mesh_device_delete *del_dev)
/* Third: find if the device is been provisioned */
if (addr_cmp && (del_dev->addr_type <= BLE_MESH_ADDR_RANDOM)) {
if (bt_mesh_provisioner_find_node_with_addr(&del_addr, true)) {
return 0;
}
bt_mesh_provisioner_delete_node_with_dev_addr(&del_addr);
}
if (uuid_cmp) {
if (bt_mesh_provisioner_find_node_with_uuid(del_dev->uuid, true)) {
return 0;
}
bt_mesh_provisioner_delete_node_with_uuid(del_dev->uuid);
}
return 0;
@ -1243,6 +1253,26 @@ int bt_mesh_provisioner_set_primary_elem_addr(u16_t addr)
return 0;
}
#if CONFIG_BLE_MESH_TEST_AUTO_ENTER_NETWORK
int bt_mesh_test_provisioner_update_alloc_addr(u16_t unicast_addr, u16_t element_num)
{
u16_t max_addr = FAST_PROV_ENABLE() ? prov_ctx.fast_prov.unicast_addr_max : PROV_MAX_ADDR_TO_ASSIGN;
if (unicast_addr + element_num > max_addr) {
BT_WARN("%s, Not enough unicast address to allocate", __func__);
prov_ctx.curr_alloc_addr = BLE_MESH_ADDR_UNASSIGNED;
} else {
prov_ctx.curr_alloc_addr = unicast_addr + element_num;
}
if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
bt_mesh_store_prov_info(prov_ctx.primary_addr, prov_ctx.curr_alloc_addr);
}
return 0;
}
#endif /* CONFIG_BLE_MESH_TEST_AUTO_ENTER_NETWORK */
/* The following APIs are for fast provisioning */
void bt_mesh_provisioner_fast_prov_enable(bool enable)
@ -2470,38 +2500,35 @@ static void send_prov_data(const u8_t idx)
sys_put_be16(prev_addr, &pdu[23]);
link[idx].unicast_addr = prev_addr;
} else {
u16_t alloc_addr = BLE_MESH_ADDR_UNASSIGNED;
if (BLE_MESH_ADDR_IS_UNICAST(link[idx].assign_addr)) {
if (link[idx].assign_addr + link[idx].element_num - 1 > max_addr) {
BT_ERR("%s, Too large assigned address for the device", __func__);
goto fail;
}
/* Make sure the assigned unicast address is not identical with any unicast address
* of other nodes. Also need to make sure the address is not identical with any
* address of Provisioner.
*/
if (bt_mesh_provisioner_check_is_addr_dup(link[idx].assign_addr, link[idx].element_num, true)) {
BT_ERR("%s, Assigned address 0x%04x is duplicated", __func__, link[idx].assign_addr);
goto fail;
}
sys_put_be16(link[idx].assign_addr, &pdu[23]);
link[idx].unicast_addr = link[idx].assign_addr;
alloc_addr = link[idx].assign_addr;
} else {
/* If this device to be provisioned is a new device */
if (prov_ctx.curr_alloc_addr == BLE_MESH_ADDR_UNASSIGNED) {
BT_ERR("%s, No unicast address can be allocated", __func__);
goto fail;
}
if (prov_ctx.curr_alloc_addr + link[idx].element_num - 1 > max_addr) {
BT_ERR("%s, Not enough unicast address for the device", __func__);
goto fail;
}
sys_put_be16(prov_ctx.curr_alloc_addr, &pdu[23]);
link[idx].unicast_addr = prov_ctx.curr_alloc_addr;
alloc_addr = prov_ctx.curr_alloc_addr;
}
if (alloc_addr + link[idx].element_num - 1 > max_addr) {
BT_ERR("%s, Not enough unicast address for the device", __func__);
goto fail;
}
/* Make sure the assigned unicast address is not identical with any unicast
* address of other nodes. And make sure the address is not identical with
* any unicast address of Provisioner.
*/
if (bt_mesh_provisioner_check_is_addr_dup(alloc_addr, link[idx].element_num, true)) {
BT_ERR("%s, Assigned address 0x%04x is duplicated", __func__, alloc_addr);
goto fail;
}
sys_put_be16(alloc_addr, &pdu[23]);
link[idx].unicast_addr = alloc_addr;
}
prov_buf_init(&buf, PROV_DATA);

View file

@ -335,6 +335,18 @@ u16_t bt_mesh_provisioner_get_primary_elem_addr(void);
*/
int bt_mesh_provisioner_set_primary_elem_addr(u16_t addr);
/**
* @brief This function is used to update next allocated address by Provisioner.
*
* @note This function is used for mesh internal test.
*
* @param[in] unicast_addr: unicast address of the node
* @param[in] element_num: element count of the node
*
* @return Zero - success, otherwise - fail
*/
int bt_mesh_test_provisioner_update_alloc_addr(u16_t unicast_addr, u16_t element_num);
/**
* @brief This function is called to input number/string out-put by unprovisioned device.
*

View file

@ -1039,14 +1039,14 @@ free:
return err;
}
static int node_info_set(u16_t addr, bool prov, bool *exist)
static int node_info_set(u16_t addr, bool *exist)
{
struct bt_mesh_node node = {0};
struct node_info info = {0};
char get[16] = {'\0'};
int err = 0;
sprintf(get, prov ? "mesh/pn/%04x/i" : "mesh/sn/%04x/i", addr);
sprintf(get, "mesh/pn/%04x/i", addr);
err = bt_mesh_load_core_settings(get, (u8_t *)&info, sizeof(info), exist);
if (err) {
BT_ERR("%s, Failed to load node %s", __func__, get);
@ -1068,7 +1068,7 @@ static int node_info_set(u16_t addr, bool prov, bool *exist)
node.iv_index = info.iv_index;
memcpy(node.dev_key, info.dev_key, 16);
err = bt_mesh_provisioner_restore_node_info(&node, prov);
err = bt_mesh_provisioner_restore_node_info(&node);
if (err) {
BT_ERR("%s, Failed to restore node 0x%04x", __func__, addr);
return -EIO;
@ -1079,14 +1079,14 @@ static int node_info_set(u16_t addr, bool prov, bool *exist)
return 0;
}
static int node_name_set(u16_t addr, bool prov)
static int node_name_set(u16_t addr)
{
char name[BLE_MESH_NODE_NAME_SIZE] = {0};
char get[16] = {'\0'};
bool exist = false;
int err = 0;
sprintf(get, prov ? "mesh/pn/%04x/n" : "mesh/sn/%04x/n", addr);
sprintf(get, "mesh/pn/%04x/n", addr);
err = bt_mesh_load_core_settings(get, (u8_t *)name, BLE_MESH_NODE_NAME_SIZE, &exist);
if (err) {
BT_ERR("%s, Failed to load node name %s", __func__, get);
@ -1108,19 +1108,19 @@ static int node_name_set(u16_t addr, bool prov)
return 0;
}
static int node_comp_data_set(u16_t addr, bool prov)
static int node_comp_data_set(u16_t addr)
{
struct net_buf_simple *buf = NULL;
char get[16] = {'\0'};
int err = 0;
sprintf(get, prov ? "mesh/pn/%04x/c" : "mesh/sn/%04x/c", addr);
sprintf(get, "mesh/pn/%04x/c", addr);
buf = bt_mesh_get_core_settings_item(get);
if (!buf) {
return 0;
}
err = bt_mesh_provisioner_restore_node_comp_data(addr, buf->data, buf->len, prov);
err = bt_mesh_provisioner_restore_node_comp_data(addr, buf->data, buf->len);
if (err) {
BT_ERR("%s, Failed to restore node comp data 0x%04x", __func__, addr);
}
@ -1134,7 +1134,7 @@ static int node_comp_data_set(u16_t addr, bool prov)
static int p_node_set(const char *name)
{
struct net_buf_simple *buf = NULL;
bool exist = false, prov = false;
bool exist = false;
size_t length = 0U;
int err = 0;
int i;
@ -1144,40 +1144,38 @@ static int p_node_set(const char *name)
return 0;
}
prov = strcmp(name, "mesh/p_pnode") == 0 ? true : false;
length = buf->len;
for (i = 0; i < length / SETTINGS_ITEM_SIZE; i++) {
u16_t addr = net_buf_simple_pull_le16(buf);
if (!BLE_MESH_ADDR_IS_UNICAST(addr)) {
BT_ERR("%s, 0x%04x is not a unicast address", __func__, addr);
goto free;
continue;
}
err = node_info_set(addr, prov, &exist);
err = node_info_set(addr, &exist);
if (err) {
BT_ERR("%s, Failed to load node 0x%04x info", __func__, addr);
goto free;
continue;
}
if (exist == false) {
continue;
}
err = node_name_set(addr, prov);
err = node_name_set(addr);
if (err) {
BT_ERR("%s, Failed to load node 0x%04x name", __func__, addr);
goto free;
continue;
}
err = node_comp_data_set(addr, prov);
err = node_comp_data_set(addr);
if (err) {
BT_ERR("%s, Failed to load node 0x%04x comp data", __func__, addr);
goto free;
continue;
}
}
free:
bt_mesh_free_buf(buf);
return err;
}
@ -1207,8 +1205,7 @@ const struct bt_mesh_setting {
{ "mesh/p_appidx", p_app_idx_set },
{ "mesh/p_netkey", p_net_key_set },
{ "mesh/p_appkey", p_app_key_set },
{ "mesh/p_pnode", p_node_set },
{ "mesh/p_snode", p_node_set },
{ "mesh/p_node", p_node_set },
#endif
};
@ -1248,8 +1245,7 @@ int settings_core_load(void)
!strcmp(settings[i].name, "mesh/p_appidx") ||
!strcmp(settings[i].name, "mesh/p_netkey") ||
!strcmp(settings[i].name, "mesh/p_appkey") ||
!strcmp(settings[i].name, "mesh/p_pnode") ||
!strcmp(settings[i].name, "mesh/p_snode")) &&
!strcmp(settings[i].name, "mesh/p_node")) &&
(!IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) || bt_mesh_is_node())) {
BT_DBG("Not restoring %s for node", settings[i].name);
continue;
@ -2252,14 +2248,10 @@ void bt_mesh_store_label(void)
* key: "mesh/pnk/xxxx" -> write/read to set/get the "xxxx" NetKey
* key: "mesh/p_appkey" -> write/read to set/get all Provisioner AppKey Index
* key: "mesh/pak/xxxx" -> write/read to set/get the "xxxx" AppKey
* key: "mesh/p_pnode" -> write/read to set/get all self-provisioned nodes info
* key: "mesh/p_node" -> write/read to set/get all self-provisioned nodes info
* key: "mesh/pn/xxxx/i" -> write/read to set/get the "xxxx" provisioned node info
* key: "mesh/pn/xxxx/n" -> write/read to set/get the "xxxx" provisioned node name
* key: "mesh/pn/xxxx/c" -> write/read to set/get the "xxxx" provisioned node composition data
* key: "mesh/p_snode" -> write/read to set/get all locally stored nodes info
* key: "mesh/sn/xxxx/i" -> write/read to set/get the "xxxx" stored node info
* key: "mesh/sn/xxxx/n" -> write/read to set/get the "xxxx" stored node name
* key: "mesh/sn/xxxx/c" -> write/read to set/get the "xxxx" stored node composition data
*/
void bt_mesh_store_prov_info(u16_t primary_addr, u16_t alloc_addr)
{
@ -2449,7 +2441,7 @@ void bt_mesh_clear_rpl_single(u16_t src)
}
}
void bt_mesh_store_node_info(struct bt_mesh_node *node, bool prov)
void bt_mesh_store_node_info(struct bt_mesh_node *node)
{
struct node_info val = {0};
char name[16] = {'\0'};
@ -2471,43 +2463,43 @@ void bt_mesh_store_node_info(struct bt_mesh_node *node, bool prov)
val.iv_index = node->iv_index;
memcpy(val.dev_key, node->dev_key, 16);
sprintf(name, prov ? "mesh/pn/%04x/i" : "mesh/sn/%04x/i", node->unicast_addr);
sprintf(name, "mesh/pn/%04x/i", node->unicast_addr);
err = bt_mesh_save_core_settings(name, (const u8_t *)&val, sizeof(val));
if (err) {
BT_ERR("%s, Failed to save node %s", __func__, name);
return;
}
err = bt_mesh_add_core_settings_item(prov ? "mesh/p_pnode" : "mesh/p_snode", node->unicast_addr);
err = bt_mesh_add_core_settings_item("mesh/p_node", node->unicast_addr);
if (err) {
BT_ERR("%s, Failed to add node 0x%04x", __func__, node->unicast_addr);
}
}
static void clear_node(u16_t addr, bool prov)
static void clear_node(u16_t addr)
{
char name[16] = {'\0'};
int err = 0;
/* Clear node information */
sprintf(name, prov ? "mesh/pn/%04x/i" : "mesh/sn/%04x/i", addr);
sprintf(name, "mesh/pn/%04x/i", addr);
bt_mesh_save_core_settings(name, NULL, 0);
/* Clear node name */
sprintf(name, prov ? "mesh/pn/%04x/n" : "mesh/sn/%04x/n", addr);
sprintf(name, "mesh/pn/%04x/n", addr);
bt_mesh_save_core_settings(name, NULL, 0);
/* Clear node composition data */
sprintf(name, prov ? "mesh/pn/%04x/c" : "mesh/sn/%04x/c", addr);
sprintf(name, "mesh/pn/%04x/c", addr);
bt_mesh_save_core_settings(name, NULL, 0);
err = bt_mesh_remove_core_settings_item(prov ? "mesh/p_pnode" : "mesh/p_snode", addr);
err = bt_mesh_remove_core_settings_item("mesh/p_node", addr);
if (err) {
BT_ERR("%s, Failed to remove node 0x%04x", __func__, addr);
}
}
void bt_mesh_clear_node_info(u16_t unicast_addr, bool prov)
void bt_mesh_clear_node_info(u16_t unicast_addr)
{
if (!BLE_MESH_ADDR_IS_UNICAST(unicast_addr)) {
BT_ERR("%s, Invalid unicast address 0x%04x", __func__, unicast_addr);
@ -2516,10 +2508,10 @@ void bt_mesh_clear_node_info(u16_t unicast_addr, bool prov)
BT_DBG("Unicast address 0x%04x", unicast_addr);
clear_node(unicast_addr, prov);
clear_node(unicast_addr);
}
void bt_mesh_store_node_name(struct bt_mesh_node *node, bool prov)
void bt_mesh_store_node_name(struct bt_mesh_node *node)
{
char node_name[BLE_MESH_NODE_NAME_SIZE] = {0};
char name[16] = {'\0'};
@ -2532,14 +2524,14 @@ void bt_mesh_store_node_name(struct bt_mesh_node *node, bool prov)
strncpy(node_name, node->name, BLE_MESH_NODE_NAME_SIZE);
sprintf(name, prov ? "mesh/pn/%04x/n" : "mesh/sn/%04x/n", node->unicast_addr);
sprintf(name, "mesh/pn/%04x/n", node->unicast_addr);
err = bt_mesh_save_core_settings(name, (const u8_t *)node_name, BLE_MESH_NODE_NAME_SIZE);
if (err) {
BT_ERR("%s, Failed to save node name %s", __func__, name);
}
}
void bt_mesh_store_node_comp_data(struct bt_mesh_node *node, bool prov)
void bt_mesh_store_node_comp_data(struct bt_mesh_node *node)
{
char name[16] = {'\0'};
int err = 0;
@ -2549,7 +2541,7 @@ void bt_mesh_store_node_comp_data(struct bt_mesh_node *node, bool prov)
return;
}
sprintf(name, prov ? "mesh/pn/%04x/c" : "mesh/sn/%04x/c", node->unicast_addr);
sprintf(name, "mesh/pn/%04x/c", node->unicast_addr);
err = bt_mesh_save_core_settings(name, (const u8_t *)node->comp_data, node->comp_length);
if (err) {
BT_ERR("%s, Failed to save node comp data %s", __func__, name);

View file

@ -53,10 +53,10 @@ void bt_mesh_store_p_app_key(struct bt_mesh_app_key *key);
void bt_mesh_clear_p_subnet(struct bt_mesh_subnet *sub);
void bt_mesh_clear_p_app_key(struct bt_mesh_app_key *key);
void bt_mesh_clear_rpl_single(u16_t src);
void bt_mesh_store_node_info(struct bt_mesh_node *node, bool prov);
void bt_mesh_clear_node_info(u16_t unicast_addr, bool prov);
void bt_mesh_store_node_name(struct bt_mesh_node *node, bool prov);
void bt_mesh_store_node_comp_data(struct bt_mesh_node *node, bool prov);
void bt_mesh_store_node_info(struct bt_mesh_node *node);
void bt_mesh_clear_node_info(u16_t unicast_addr);
void bt_mesh_store_node_name(struct bt_mesh_node *node);
void bt_mesh_store_node_comp_data(struct bt_mesh_node *node);
#endif
int bt_mesh_settings_init(void);

View file

@ -178,10 +178,10 @@ static s32_t bt_mesh_client_calc_timeout(struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *msg,
u32_t opcode, s32_t timeout)
{
s32_t seg_retrans_to, duration, time;
u8_t seg_count, seg_retrans_num;
u8_t mic_size;
bool need_seg;
s32_t seg_retrans_to = 0, duration = 0, time = 0;
u8_t seg_count = 0, seg_retrans_num = 0;
bool need_seg = false;
u8_t mic_size = 0;
if (msg->len > UNSEG_ACCESS_MSG_MAX_LEN || ctx->send_rel) {
need_seg = true; /* Needs segmentation */

View file

@ -12,6 +12,7 @@ CONFIG_BT_BTU_TASK_STACK_SIZE=4512
# Override some defaults of ESP BLE Mesh
CONFIG_BLE_MESH=y
CONFIG_BLE_MESH_PROVISIONER=y
CONFIG_BLE_MESH_MAX_PROV_NODES=40
CONFIG_BLE_MESH_PB_GATT=y
CONFIG_BLE_MESH_PBA_SAME_TIME=10
CONFIG_BLE_MESH_PBG_SAME_TIME=3
@ -19,7 +20,7 @@ CONFIG_BLE_MESH_TX_SEG_MSG_COUNT=3
CONFIG_BLE_MESH_RX_SEG_MSG_COUNT=3
CONFIG_BLE_MESH_CFG_CLI=y
CONFIG_BLE_MESH_GENERIC_ONOFF_CLI=y
CONFIG_BLE_MESH_MAX_STORED_NODES=40
CONFIG_BLE_MESH_MSG_CACHE_SIZE=60
CONFIG_BLE_MESH_ADV_BUF_COUNT=200
CONFIG_BLE_MESH_CRPL=40
CONFIG_BLE_MESH_SELF_TEST=y