From a47e89c4e49d569ef84cd22dd5fd03a576b51c33 Mon Sep 17 00:00:00 2001 From: lly Date: Tue, 26 May 2020 18:17:41 +0800 Subject: [PATCH] ble_mesh: stack: Add role check before enabling device --- components/bt/esp_ble_mesh/mesh_core/main.c | 51 +++++++++++++++---- components/bt/esp_ble_mesh/mesh_core/mesh.h | 13 ++--- .../bt/esp_ble_mesh/mesh_core/settings.c | 11 ++-- .../bt/esp_ble_mesh/mesh_core/settings.h | 5 ++ 4 files changed, 59 insertions(+), 21 deletions(-) diff --git a/components/bt/esp_ble_mesh/mesh_core/main.c b/components/bt/esp_ble_mesh/mesh_core/main.c index 727edea92a..e9878c0101 100644 --- a/components/bt/esp_ble_mesh/mesh_core/main.c +++ b/components/bt/esp_ble_mesh/mesh_core/main.c @@ -199,10 +199,27 @@ int bt_mesh_prov_enable(bt_mesh_prov_bearer_t bearers) return -EINVAL; } - bt_mesh_atomic_set_bit(bt_mesh.flags, BLE_MESH_NODE); + /* Add this judgement here in case the device worked as a + * Provisioner previously. Before the corresponding info + * of Provisioner is erased from flash, users try to use + * the device as a node, which will cause the information + * in NVS been handled incorrectly. + */ + u8_t role = bt_mesh_atomic_get(bt_mesh.flags) & BLE_MESH_SETTINGS_ROLE_BIT_MASK; + if (role != BLE_MESH_SETTINGS_ROLE_NONE && + role != BLE_MESH_SETTINGS_ROLE_NODE) { + BT_ERR("%s, Mismatch role %u", __func__, role); + return -EIO; + } - if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { - bt_mesh_store_role(); + if (role == BLE_MESH_SETTINGS_ROLE_NONE) { + bt_mesh_atomic_set_bit(bt_mesh.flags, BLE_MESH_NODE); + } + if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS_BACKWARD_COMPATIBILITY) || + role == BLE_MESH_SETTINGS_ROLE_NONE) { + if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { + bt_mesh_store_role(); + } } if (IS_ENABLED(CONFIG_BLE_MESH_PB_ADV) && @@ -225,6 +242,7 @@ int bt_mesh_prov_enable(bt_mesh_prov_bearer_t bearers) int bt_mesh_prov_disable(bt_mesh_prov_bearer_t bearers) { if (bt_mesh_is_provisioned()) { + BT_WARN("%s, Already provisioned", __func__); return -EALREADY; } @@ -532,6 +550,27 @@ int bt_mesh_provisioner_enable(bt_mesh_prov_bearer_t bearers) return -EINVAL; } + /* Add this judgement here in case the device worked as a + * node previously. Before the corresponding information + * of the node is erased from flash, users try to use the + * device as a Provisioner, which will cause the information + * in NVS been handled incorrectly. + */ + u8_t role = bt_mesh_atomic_get(bt_mesh.flags) & BLE_MESH_SETTINGS_ROLE_BIT_MASK; + if (role != BLE_MESH_SETTINGS_ROLE_NONE && + role != BLE_MESH_SETTINGS_ROLE_PROV) { + BT_ERR("%s, Mismatch role %u", __func__, role); + return -EIO; + } + + if (role == BLE_MESH_SETTINGS_ROLE_NONE) { + bt_mesh_atomic_set_bit(bt_mesh.flags, BLE_MESH_PROVISIONER); + + if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { + bt_mesh_store_role(); + } + } + err = bt_mesh_provisioner_net_create(); if (err) { BT_ERR("Failed to create network"); @@ -548,12 +587,6 @@ int bt_mesh_provisioner_enable(bt_mesh_prov_bearer_t bearers) bt_mesh_comp_provision(bt_mesh_provisioner_get_primary_elem_addr()); - bt_mesh_atomic_set_bit(bt_mesh.flags, BLE_MESH_PROVISIONER); - - if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { - bt_mesh_store_role(); - } - #if defined(CONFIG_BLE_MESH_USE_DUPLICATE_SCAN) if (IS_ENABLED(CONFIG_BLE_MESH_PB_ADV) && (bearers & BLE_MESH_PROV_ADV)) { diff --git a/components/bt/esp_ble_mesh/mesh_core/mesh.h b/components/bt/esp_ble_mesh/mesh_core/mesh.h index 5a409a891b..8387470a44 100644 --- a/components/bt/esp_ble_mesh/mesh_core/mesh.h +++ b/components/bt/esp_ble_mesh/mesh_core/mesh.h @@ -2,6 +2,7 @@ /* * Copyright (c) 2017 Intel Corporation + * Additional Copyright (c) 2020 Espressif Systems (Shanghai) PTE LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,13 +16,13 @@ extern "C" { #endif -#define BLE_MESH_KEY_PRIMARY 0x0000 -#define BLE_MESH_KEY_ANY 0xffff +#define BLE_MESH_KEY_PRIMARY 0x0000 +#define BLE_MESH_KEY_ANY 0xffff -#define BLE_MESH_ADDR_IS_UNICAST(addr) ((addr) && (addr) < 0x8000) -#define BLE_MESH_ADDR_IS_GROUP(addr) ((addr) >= 0xc000 && (addr) <= 0xff00) -#define BLE_MESH_ADDR_IS_VIRTUAL(addr) ((addr) >= 0x8000 && (addr) < 0xc000) -#define BLE_MESH_ADDR_IS_RFU(addr) ((addr) >= 0xff00 && (addr) <= 0xfffb) +#define BLE_MESH_ADDR_IS_UNICAST(addr) ((addr) && (addr) < 0x8000) +#define BLE_MESH_ADDR_IS_GROUP(addr) ((addr) >= 0xc000 && (addr) <= 0xff00) +#define BLE_MESH_ADDR_IS_VIRTUAL(addr) ((addr) >= 0x8000 && (addr) < 0xc000) +#define BLE_MESH_ADDR_IS_RFU(addr) ((addr) >= 0xff00 && (addr) <= 0xfffb) struct bt_mesh_net; diff --git a/components/bt/esp_ble_mesh/mesh_core/settings.c b/components/bt/esp_ble_mesh/mesh_core/settings.c index 97893b66aa..a102f39379 100644 --- a/components/bt/esp_ble_mesh/mesh_core/settings.c +++ b/components/bt/esp_ble_mesh/mesh_core/settings.c @@ -19,6 +19,7 @@ #include "cfg_srv.h" #include "mesh_common.h" #include "settings_nvs.h" +#include "settings.h" #include "provisioner_main.h" #include "provisioner_prov.h" @@ -167,8 +168,6 @@ struct node_info { u8_t dev_key[16]; } __packed; -#define DEVICE_ROLE_BITS (BIT(BLE_MESH_NODE) | BIT(BLE_MESH_PROVISIONER)) - static int role_set(const char *name) { bool exist = false; @@ -1257,15 +1256,15 @@ int settings_core_load(void) settings[i].func(settings[i].name); if (!strcmp(settings[i].name, "mesh/role")) { - u8_t role = bt_mesh_atomic_get(bt_mesh.flags) & DEVICE_ROLE_BITS; + u8_t role = bt_mesh_atomic_get(bt_mesh.flags) & BLE_MESH_SETTINGS_ROLE_BIT_MASK; switch (role) { case 0U: BT_INFO("Mesh device just starts up, no restore"); return 0; - case BIT(BLE_MESH_NODE): + case BLE_MESH_SETTINGS_ROLE_NODE: BT_INFO("Restored mesh device role: Node"); break; - case BIT(BLE_MESH_PROVISIONER): + case BLE_MESH_SETTINGS_ROLE_PROV: BT_INFO("Restored mesh device role: Provisioner"); break; default: @@ -1486,7 +1485,7 @@ static void store_pending_net(void) void bt_mesh_store_role(void) { - BT_DBG("Store, device role %lu", bt_mesh_atomic_get(bt_mesh.flags) & DEVICE_ROLE_BITS); + BT_DBG("Store, device role %lu", bt_mesh_atomic_get(bt_mesh.flags) & BLE_MESH_SETTINGS_ROLE_BIT_MASK); bt_mesh_save_core_settings("mesh/role", (const u8_t *)bt_mesh.flags, sizeof(bt_mesh.flags)); } diff --git a/components/bt/esp_ble_mesh/mesh_core/settings.h b/components/bt/esp_ble_mesh/mesh_core/settings.h index 52a7b2cd0f..5bb50bda04 100644 --- a/components/bt/esp_ble_mesh/mesh_core/settings.h +++ b/components/bt/esp_ble_mesh/mesh_core/settings.h @@ -14,6 +14,11 @@ extern "C" { #endif +#define BLE_MESH_SETTINGS_ROLE_NONE 0 +#define BLE_MESH_SETTINGS_ROLE_NODE (BIT(BLE_MESH_NODE)) +#define BLE_MESH_SETTINGS_ROLE_PROV (BIT(BLE_MESH_PROVISIONER)) +#define BLE_MESH_SETTINGS_ROLE_BIT_MASK (BIT(BLE_MESH_NODE) | BIT(BLE_MESH_PROVISIONER)) + int settings_core_init(void); int settings_core_load(void); int settings_core_commit(void);