diff --git a/components/bt/CMakeLists.txt b/components/bt/CMakeLists.txt index 03b1106069..f01107ca28 100644 --- a/components/bt/CMakeLists.txt +++ b/components/bt/CMakeLists.txt @@ -342,7 +342,6 @@ if(CONFIG_BT_ENABLED) "esp_ble_mesh/mesh_core/main.c" "esp_ble_mesh/mesh_core/net.c" "esp_ble_mesh/mesh_core/prov.c" - "esp_ble_mesh/mesh_core/provisioner_beacon.c" "esp_ble_mesh/mesh_core/provisioner_main.c" "esp_ble_mesh/mesh_core/provisioner_prov.c" "esp_ble_mesh/mesh_core/proxy_client.c" diff --git a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_networking_api.c b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_networking_api.c index e6e70284fa..bffbafe814 100644 --- a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_networking_api.c +++ b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_networking_api.c @@ -161,6 +161,9 @@ esp_err_t esp_ble_mesh_client_model_init(esp_ble_mesh_model_t *model) if (model == NULL) { return ESP_ERR_INVALID_ARG; } + + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); + return btc_ble_mesh_client_model_init(model); } @@ -169,6 +172,9 @@ esp_err_t esp_ble_mesh_client_model_deinit(esp_ble_mesh_model_t *model) if (model == NULL) { return ESP_ERR_INVALID_ARG; } + + ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); + return btc_ble_mesh_client_model_deinit(model); } @@ -282,6 +288,15 @@ int esp_ble_mesh_provisioner_get_node_index(const char *name) return bt_mesh_provisioner_get_node_index(name); } +esp_ble_mesh_node_t *esp_ble_mesh_provisioner_get_node_info(const uint8_t uuid[16]) +{ + if (!uuid) { + return NULL; + } + + return (esp_ble_mesh_node_t *)bt_mesh_provisioner_get_prov_node_info(uuid); +} + esp_err_t esp_ble_mesh_provisioner_add_local_app_key(const uint8_t app_key[16], uint16_t net_idx, uint16_t app_idx) { diff --git a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_provisioning_api.c b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_provisioning_api.c index e121250684..6512ec850a 100644 --- a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_provisioning_api.c +++ b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_provisioning_api.c @@ -285,6 +285,35 @@ esp_err_t esp_ble_mesh_provisioner_add_unprov_dev(esp_ble_mesh_unprov_dev_add_t == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } +esp_err_t esp_ble_mesh_provisioner_prov_device_with_addr(const uint8_t uuid[16], + esp_ble_mesh_bd_addr_t addr, esp_ble_mesh_addr_type_t addr_type, + esp_ble_mesh_prov_bearer_t bearer, uint16_t oob_info, uint16_t unicast_addr) +{ + btc_ble_mesh_prov_args_t arg = {0}; + btc_msg_t msg = {0}; + + if (uuid == NULL || addr == NULL || addr_type > ESP_BLE_MESH_ADDR_TYPE_RANDOM || + (bearer != ESP_BLE_MESH_PROV_ADV && bearer != ESP_BLE_MESH_PROV_GATT) || + !ESP_BLE_MESH_ADDR_IS_UNICAST(unicast_addr)) { + 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_PROV_DEV_WITH_ADDR; + + memcpy(arg.provisioner_prov_dev_with_addr.uuid, uuid, 16); + memcpy(arg.provisioner_prov_dev_with_addr.addr, addr, BD_ADDR_LEN); + arg.provisioner_prov_dev_with_addr.addr_type = addr_type; + arg.provisioner_prov_dev_with_addr.bearer = bearer; + arg.provisioner_prov_dev_with_addr.oob_info = oob_info; + arg.provisioner_prov_dev_with_addr.unicast_addr = unicast_addr; + 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_dev(esp_ble_mesh_device_delete_t *del_dev) { uint8_t val = DEL_DEV_ADDR_FLAG | DEL_DEV_UUID_FLAG; @@ -383,6 +412,26 @@ esp_err_t esp_ble_mesh_provisioner_set_static_oob_value(const uint8_t *value, ui == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } +esp_err_t esp_ble_mesh_provisioner_set_primary_elem_addr(uint16_t addr) +{ + btc_ble_mesh_prov_args_t arg = {0}; + btc_msg_t msg = {0}; + + if (!ESP_BLE_MESH_ADDR_IS_UNICAST(addr)) { + 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_SET_PRIMARY_ELEM_ADDR; + + arg.set_primary_elem_addr.addr = addr; + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + #endif /* CONFIG_BLE_MESH_PROVISIONER */ /* The following APIs are for fast provisioning */ diff --git a/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_networking_api.h b/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_networking_api.h index 341b6675ec..72ac9cd53c 100644 --- a/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_networking_api.h +++ b/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_networking_api.h @@ -212,6 +212,16 @@ const char *esp_ble_mesh_provisioner_get_node_name(uint16_t index); */ int esp_ble_mesh_provisioner_get_node_index(const char *name); +/** + * @brief This function is called to get the provisioned node information. + * + * @param[in] uuid: Device UUID of the node + * + * @return Pointer of the node info struct or NULL on failure. + * + */ +esp_ble_mesh_node_t *esp_ble_mesh_provisioner_get_node_info(const uint8_t uuid[16]); + /** * @brief This function is called to set the app key for the local BLE Mesh stack. * diff --git a/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_provisioning_api.h b/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_provisioning_api.h index 9145cc91cc..b2ebe07c9a 100644 --- a/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_provisioning_api.h +++ b/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_provisioning_api.h @@ -230,6 +230,32 @@ esp_err_t esp_ble_mesh_provisioner_prov_disable(esp_ble_mesh_prov_bearer_t beare esp_err_t esp_ble_mesh_provisioner_add_unprov_dev(esp_ble_mesh_unprov_dev_add_t *add_dev, esp_ble_mesh_dev_add_flag_t flags); +/** @brief Provision an unprovisioned device with fixed unicast address. + * + * @param[in] uuid: Device UUID of the unprovisioned device + * @param[in] addr: Device address of the unprovisioned device + * @param[in] addr_type: Device address type of the unprovisioned device + * @param[in] bearer: Provisioning bearer going to be used by Provisioner + * @param[in] oob_info: OOB info of the unprovisioned device + * @param[in] unicast_addr: Unicast address going to be allocated for the unprovisioned device + * + * @return Zero on success or (negative) error code otherwise. + * + * @note: 1. Currently address type only supports public address and static random address. + * 2. Bearer must be equal to ESP_BLE_MESH_PROV_ADV or ESP_BLE_MESH_PROV_GATT, since + * Provisioner will start to provision a device immediately once this function is + * invked. And the input bearer must be identical with the one within the parameters + * of the ESP_BLE_MESH_PROVISIONER_RECV_UNPROV_ADV_PKT_EVT event. + * 3. If this function is used by a Provisioner to provision devices, the application + * should take care of the assigned unicast address and avoid overlap of the unicast + * addresses of different nodes. + * 4. Recommend to use only one of the functions "esp_ble_mesh_provisioner_add_unprov_dev" + * and "esp_ble_mesh_provisioner_prov_device_with_addr" by a Provisioner. + */ +esp_err_t esp_ble_mesh_provisioner_prov_device_with_addr(const uint8_t uuid[16], + esp_ble_mesh_bd_addr_t addr, esp_ble_mesh_addr_type_t addr_type, + esp_ble_mesh_prov_bearer_t bearer, uint16_t oob_info, uint16_t unicast_addr); + /** * @brief Delete device from queue, reset current provisioning link and reset the node. * @@ -301,6 +327,25 @@ esp_err_t esp_ble_mesh_provisioner_set_prov_data_info(esp_ble_mesh_prov_data_inf */ esp_err_t esp_ble_mesh_provisioner_set_static_oob_value(const uint8_t *value, uint8_t length); +/** + * @brief This function is called by Provisioner to set own Primary element address. + * + * @note This API must be invoked when BLE Mesh initialization is completed successfully, + * and can be invoked before Provisioner functionality is enabled. + * Once this API is invoked successfully, the prov_unicast_addr value in the struct + * esp_ble_mesh_prov_t will be ignored, and Provisioner will use this address as its + * own primary element address. + * And if the unicast address going to assigned for the next unprovisioned device is + * smaller than the input address + element number of Provisioner, then the address + * for the next unprovisioned device will be recalculated internally. + * + * @param[in] addr: Unicast address of the Primary element of Provisioner. + * + * @return ESP_OK on success or error code otherwise. + * + */ +esp_err_t esp_ble_mesh_provisioner_set_primary_elem_addr(uint16_t addr); + /** * @brief This function is called to set provisioning data information before starting * fast provisioning. diff --git a/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h b/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h index f421706958..b2dadedc8d 100644 --- a/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h +++ b/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h @@ -321,13 +321,12 @@ typedef uint8_t BD_ADDR[BD_ADDR_LEN]; typedef uint8_t esp_ble_mesh_bd_addr_t[BD_ADDR_LEN]; +#define ESP_BLE_MESH_ADDR_TYPE_PUBLIC 0x00 +#define ESP_BLE_MESH_ADDR_TYPE_RANDOM 0x01 +#define ESP_BLE_MESH_ADDR_TYPE_RPA_PUBLIC 0x02 +#define ESP_BLE_MESH_ADDR_TYPE_RPA_RANDOM 0x03 /// BLE device address type -typedef enum { - ESP_BLE_MESH_ADDR_TYPE_PUBLIC = 0x00, - ESP_BLE_MESH_ADDR_TYPE_RANDOM = 0x01, - ESP_BLE_MESH_ADDR_TYPE_RPA_PUBLIC = 0x02, - ESP_BLE_MESH_ADDR_TYPE_RPA_RANDOM = 0x03, -} esp_ble_mesh_addr_type_t; +typedef uint8_t esp_ble_mesh_addr_type_t; typedef struct esp_ble_mesh_model esp_ble_mesh_model_t; @@ -677,6 +676,21 @@ typedef struct { uint8_t flag; /*!< BIT0: net_idx; BIT1: flags; BIT2: iv_index */ } esp_ble_mesh_prov_data_info_t; +/* Each node information stored by provisioner */ +typedef struct { + char name[ESP_BLE_MESH_NODE_NAME_MAX_LEN]; /*!< Node name */ + esp_ble_mesh_bd_addr_t addr; /*!< Node device address */ + esp_ble_mesh_addr_type_t addr_type; /*!< Node device address type */ + uint8_t dev_uuid[16]; /*!< Device UUID */ + uint16_t oob_info; /*!< Node OOB information */ + uint16_t unicast_addr; /*!< Node unicast address */ + uint8_t element_num; /*!< Node element number */ + uint16_t net_idx; /*!< Node NetKey Index */ + uint8_t flags; /*!< Node key refresh flag and iv update flag */ + uint32_t iv_index; /*!< Node IV Index */ + uint8_t dev_key[16]; /*!< Node device key */ +} __attribute__((packed)) esp_ble_mesh_node_t; + /** Context of fast provisioning which need to be set. */ typedef struct { uint16_t unicast_min; /*!< Minimum unicast address used for fast provisioning */ @@ -734,10 +748,12 @@ typedef enum { ESP_BLE_MESH_PROVISIONER_PROV_LINK_CLOSE_EVT, /*!< Provisioner close a BLE Mesh link event */ ESP_BLE_MESH_PROVISIONER_PROV_COMPLETE_EVT, /*!< Provisioner provisioning done event */ ESP_BLE_MESH_PROVISIONER_ADD_UNPROV_DEV_COMP_EVT, /*!< Provisioner add a device to the list which contains devices that are waiting/going to be provisioned completion event */ + ESP_BLE_MESH_PROVISIONER_PROV_DEV_WITH_ADDR_COMP_EVT, /*!< Provisioner start to provision an unprovisioned device completion event */ ESP_BLE_MESH_PROVISIONER_DELETE_DEV_COMP_EVT, /*!< Provisioner delete a device from the list, close provisioning link with the device if it exists and remove the device from network completion event */ ESP_BLE_MESH_PROVISIONER_SET_DEV_UUID_MATCH_COMP_EVT, /*!< Provisioner set the value to be compared with part of the unprovisioned device UUID completion event */ ESP_BLE_MESH_PROVISIONER_SET_PROV_DATA_INFO_COMP_EVT, /*!< Provisioner set net_idx/flags/iv_index used for provisioning completion event */ ESP_BLE_MESH_PROVISIONER_SET_STATIC_OOB_VALUE_COMP_EVT, /*!< Provisioner set static oob value used for provisioning completion event */ + ESP_BLE_MESH_PROVISIONER_SET_PRIMARY_ELEM_ADDR_COMP_EVT, /*!< Provisioner set unicast address of primary element completion event */ ESP_BLE_MESH_PROVISIONER_PROV_READ_OOB_PUB_KEY_COMP_EVT, /*!< Provisioner read unprovisioned device OOB public key completion event */ ESP_BLE_MESH_PROVISIONER_PROV_INPUT_NUMBER_COMP_EVT, /*!< Provisioner input number completion event */ ESP_BLE_MESH_PROVISIONER_PROV_INPUT_STRING_COMP_EVT, /*!< Provisioner input string completion event */ @@ -889,6 +905,7 @@ typedef union { uint16_t oob_info; /*!< OOB Info of the unprovisoned device */ uint8_t adv_type; /*!< Avertising type of the unprovisoned device */ esp_ble_mesh_prov_bearer_t bearer; /*!< Bearer of the unprovisoned device */ + int8_t rssi; /*!< RSSI of the received advertising packet */ } provisioner_recv_unprov_adv_pkt; /*!< Event parameter of ESP_BLE_MESH_PROVISIONER_RECV_UNPROV_ADV_PKT_EVT */ /** * @brief ESP_BLE_MESH_PROVISIONER_PROV_ENABLE_COMP_EVT @@ -959,6 +976,12 @@ typedef union { struct ble_mesh_provisioner_add_unprov_dev_comp_param { int err_code; /*!< Indicate the result of adding device into queue by the Provisioner */ } provisioner_add_unprov_dev_comp; /*!< Event parameter of ESP_BLE_MESH_PROVISIONER_ADD_UNPROV_DEV_COMP_EVT */ + /** + * @brief ESP_BLE_MESH_PROVISIONER_PROV_DEV_WITH_ADDR_COMP_EVT + */ + struct ble_mesh_provisioner_prov_dev_with_addr_comp_param { + int err_code; /*!< Indicate the result of Provisioner starting to provision a device */ + } provisioner_prov_dev_with_addr_comp; /*!< Event parameter of ESP_BLE_MESH_PROVISIONER_PROV_DEV_WITH_ADDR_COMP_EVT */ /** * @brief ESP_BLE_MESH_PROVISIONER_DELETE_DEV_COMP_EVT */ @@ -983,6 +1006,12 @@ typedef union { struct ble_mesh_provisioner_set_static_oob_val_comp_param { int err_code; /*!< Indicate the result of setting static oob value by the Provisioner */ } provisioner_set_static_oob_val_comp; /*!< Event parameter of ESP_BLE_MESH_PROVISIONER_SET_STATIC_OOB_VALUE_COMP_EVT */ + /** + * @brief ESP_BLE_MESH_PROVISIONER_SET_PRIMARY_ELEM_ADDR_COMP_EVT + */ + struct ble_mesh_provisioner_set_primary_elem_addr_comp_param { + int err_code; /*!< Indicate the result of setting unicast address of primary element by the Provisioner */ + } provisioner_set_primary_elem_addr_comp; /*!< Event parameter of ESP_BLE_MESH_PROVISIONER_SET_PRIMARY_ELEM_ADDR_COMP_EVT */ /** * @brief ESP_BLE_MESH_PROVISIONER_PROV_READ_OOB_PUB_KEY_COMP_EVT */ @@ -1107,6 +1136,7 @@ typedef union { esp_ble_mesh_addr_type_t addr_type; /*!< Device address type */ uint16_t net_idx; /*!< Network ID related NetKey Index */ uint8_t net_id[8]; /*!< Network ID contained in the advertising packet */ + int8_t rssi; /*!< RSSI of the received advertising packet */ } proxy_client_recv_adv_pkt; /*!< Event parameter of ESP_BLE_MESH_PROXY_CLIENT_RECV_ADV_PKT_EVT */ /** * @brief ESP_BLE_MESH_PROXY_CLIENT_CONNECTED_EVT diff --git a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c index c9e0afa011..77cd2e1430 100644 --- a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c +++ b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c @@ -418,9 +418,8 @@ static void btc_ble_mesh_client_model_op_cb(struct bt_mesh_model *model, mesh_param.model_operation.length = buf->len; mesh_param.model_operation.msg = buf->data; if (!k_delayed_work_free(&node->timer)) { - btc_ble_mesh_model_callback(&mesh_param, ESP_BLE_MESH_MODEL_OPERATION_EVT); - // Don't forget to release the node at the end. bt_mesh_client_free_node(node); + btc_ble_mesh_model_callback(&mesh_param, ESP_BLE_MESH_MODEL_OPERATION_EVT); } } @@ -433,6 +432,7 @@ static void btc_ble_mesh_client_model_timeout_cb(struct k_work *work) esp_ble_mesh_model_cb_param_t mesh_param = {0}; struct k_delayed_work *timer = NULL; bt_mesh_client_node_t *node = NULL; + struct bt_mesh_msg_ctx ctx = {0}; bt_mesh_client_model_lock(); @@ -441,12 +441,12 @@ static void btc_ble_mesh_client_model_timeout_cb(struct k_work *work) if (timer && !k_delayed_work_free(timer)) { node = CONTAINER_OF(work, bt_mesh_client_node_t, timer.work); if (node) { + memcpy(&ctx, &node->ctx, sizeof(ctx)); mesh_param.client_send_timeout.opcode = node->opcode; - mesh_param.client_send_timeout.model = (esp_ble_mesh_model_t *)node->ctx.model; - mesh_param.client_send_timeout.ctx = (esp_ble_mesh_msg_ctx_t *)&node->ctx; - btc_ble_mesh_model_callback(&mesh_param, ESP_BLE_MESH_CLIENT_MODEL_SEND_TIMEOUT_EVT); - // Don't forget to release the node at the end. + mesh_param.client_send_timeout.model = (esp_ble_mesh_model_t *)ctx.model; + mesh_param.client_send_timeout.ctx = (esp_ble_mesh_msg_ctx_t *)&ctx; bt_mesh_client_free_node(node); + btc_ble_mesh_model_callback(&mesh_param, ESP_BLE_MESH_CLIENT_MODEL_SEND_TIMEOUT_EVT); } } @@ -650,7 +650,7 @@ static void btc_ble_mesh_prov_set_complete_cb(esp_ble_mesh_prov_cb_param_t *para static void btc_ble_mesh_provisioner_recv_unprov_adv_pkt_cb( const u8_t addr[6], const u8_t addr_type, const u8_t adv_type, const u8_t dev_uuid[16], - u16_t oob_info, bt_mesh_prov_bearer_t bearer) + u16_t oob_info, bt_mesh_prov_bearer_t bearer, s8_t rssi) { esp_ble_mesh_prov_cb_param_t mesh_param = {0}; @@ -668,6 +668,7 @@ static void btc_ble_mesh_provisioner_recv_unprov_adv_pkt_cb( mesh_param.provisioner_recv_unprov_adv_pkt.oob_info = oob_info; mesh_param.provisioner_recv_unprov_adv_pkt.adv_type = adv_type; mesh_param.provisioner_recv_unprov_adv_pkt.bearer = bearer; + mesh_param.provisioner_recv_unprov_adv_pkt.rssi = rssi; btc_ble_mesh_prov_callback(&mesh_param, ESP_BLE_MESH_PROVISIONER_RECV_UNPROV_ADV_PKT_EVT); return; @@ -833,7 +834,7 @@ void btc_ble_mesh_friend_cb(bool establish, u16_t lpn_addr, u8_t reason) #if CONFIG_BLE_MESH_GATT_PROXY_CLIENT static void btc_ble_mesh_proxy_client_adv_recv_cb(const bt_mesh_addr_t *addr, - u8_t type, bt_mesh_proxy_adv_ctx_t *ctx) + u8_t type, bt_mesh_proxy_adv_ctx_t *ctx, s8_t rssi) { esp_ble_mesh_prov_cb_param_t mesh_param = {0}; @@ -848,6 +849,7 @@ static void btc_ble_mesh_proxy_client_adv_recv_cb(const bt_mesh_addr_t *addr, memcpy(mesh_param.proxy_client_recv_adv_pkt.addr, addr->val, BD_ADDR_LEN); mesh_param.proxy_client_recv_adv_pkt.net_idx = ctx->net_id.net_idx; memcpy(mesh_param.proxy_client_recv_adv_pkt.net_id, ctx->net_id.net_id, 8); + mesh_param.proxy_client_recv_adv_pkt.rssi = rssi; btc_ble_mesh_prov_callback(&mesh_param, ESP_BLE_MESH_PROXY_CLIENT_RECV_ADV_PKT_EVT); return; @@ -1635,6 +1637,14 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg) bt_mesh_provisioner_add_unprov_dev(&add_dev, arg->provisioner_dev_add.flags); break; } + case BTC_BLE_MESH_ACT_PROVISIONER_PROV_DEV_WITH_ADDR: + act = ESP_BLE_MESH_PROVISIONER_PROV_DEV_WITH_ADDR_COMP_EVT; + param.provisioner_prov_dev_with_addr_comp.err_code = + bt_mesh_provisioner_prov_device_with_addr(arg->provisioner_prov_dev_with_addr.uuid, + arg->provisioner_prov_dev_with_addr.addr, arg->provisioner_prov_dev_with_addr.addr_type, + arg->provisioner_prov_dev_with_addr.bearer, arg->provisioner_prov_dev_with_addr.oob_info, + arg->provisioner_prov_dev_with_addr.unicast_addr); + break; case BTC_BLE_MESH_ACT_PROVISIONER_DEV_DEL: { struct bt_mesh_device_delete del_dev = {0}; if (arg->provisioner_dev_del.del_dev.flag & DEL_DEV_ADDR_FLAG) { @@ -1676,6 +1686,11 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg) bt_mesh_provisioner_set_static_oob_value( arg->set_static_oob_val.value, arg->set_static_oob_val.length); break; + case BTC_BLE_MESH_ACT_PROVISIONER_SET_PRIMARY_ELEM_ADDR: + act = ESP_BLE_MESH_PROVISIONER_SET_PRIMARY_ELEM_ADDR_COMP_EVT; + param.provisioner_set_primary_elem_addr_comp.err_code = + bt_mesh_provisioner_set_primary_elem_addr(arg->set_primary_elem_addr.addr); + break; case BTC_BLE_MESH_ACT_PROVISIONER_SET_NODE_NAME: act = ESP_BLE_MESH_PROVISIONER_SET_NODE_NAME_COMP_EVT; param.provisioner_set_node_name_comp.err_code = diff --git a/components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_prov.h b/components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_prov.h index 3929a5cb26..2744232ab2 100644 --- a/components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_prov.h +++ b/components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_prov.h @@ -46,10 +46,12 @@ typedef enum { BTC_BLE_MESH_ACT_PROVISIONER_ENABLE, BTC_BLE_MESH_ACT_PROVISIONER_DISABLE, BTC_BLE_MESH_ACT_PROVISIONER_DEV_ADD, + BTC_BLE_MESH_ACT_PROVISIONER_PROV_DEV_WITH_ADDR, BTC_BLE_MESH_ACT_PROVISIONER_DEV_DEL, BTC_BLE_MESH_ACT_PROVISIONER_SET_DEV_UUID_MATCH, BTC_BLE_MESH_ACT_PROVISIONER_SET_PROV_DATA_INFO, BTC_BLE_MESH_ACT_PROVISIONER_SET_STATIC_OOB_VAL, + BTC_BLE_MESH_ACT_PROVISIONER_SET_PRIMARY_ELEM_ADDR, BTC_BLE_MESH_ACT_PROVISIONER_SET_NODE_NAME, BTC_BLE_MESH_ACT_PROVISIONER_SET_LOCAL_APP_KEY, BTC_BLE_MESH_ACT_PROVISIONER_BIND_LOCAL_MOD_APP, @@ -122,6 +124,14 @@ typedef union { esp_ble_mesh_unprov_dev_add_t add_dev; esp_ble_mesh_dev_add_flag_t flags; } provisioner_dev_add; + struct ble_mesh_provisioner_prov_dev_with_addr_args { + uint8_t uuid[16]; + esp_ble_mesh_bd_addr_t addr; + esp_ble_mesh_addr_type_t addr_type; + esp_ble_mesh_prov_bearer_t bearer; + uint16_t oob_info; + uint16_t unicast_addr; + } provisioner_prov_dev_with_addr; struct ble_mesh_provisioner_dev_del_args { esp_ble_mesh_device_delete_t del_dev; } provisioner_dev_del; @@ -138,6 +148,9 @@ typedef union { uint8_t value[16]; uint8_t length; } set_static_oob_val; + struct ble_mesh_provisioner_set_primary_elem_addr_args { + uint16_t addr; + } set_primary_elem_addr; struct ble_mesh_provisioner_set_node_name_args { uint16_t index; char name[ESP_BLE_MESH_NODE_NAME_MAX_LEN]; diff --git a/components/bt/esp_ble_mesh/mesh_core/access.c b/components/bt/esp_ble_mesh/mesh_core/access.c index d716f20cdd..3756e9fa21 100644 --- a/components/bt/esp_ble_mesh/mesh_core/access.c +++ b/components/bt/esp_ble_mesh/mesh_core/access.c @@ -325,7 +325,7 @@ static s32_t next_period(struct bt_mesh_model *mod) elapsed = k_uptime_get_32() - pub->period_start; - BT_DBG("Publishing took %ums", elapsed); + BT_INFO("Publishing took %ums", elapsed); if (elapsed > period) { BT_WARN("Publication sending took longer than the period"); @@ -355,7 +355,7 @@ static void publish_sent(int err, void *user_data) } if (delay) { - BT_DBG("Publishing next time in %dms", delay); + BT_INFO("Publishing next time in %dms", delay); k_delayed_work_submit(&mod->pub->timer, delay); } } @@ -443,7 +443,7 @@ static void mod_publish(struct k_work *work) BT_DBG("%s", __func__); period_ms = bt_mesh_model_pub_period_get(pub->mod); - BT_DBG("period %u ms", period_ms); + BT_INFO("period %u ms", period_ms); if (pub->count) { err = publish_retransmit(pub->mod); @@ -621,7 +621,7 @@ void bt_mesh_comp_provision(u16_t addr) dev_primary_addr = addr; - BT_DBG("addr 0x%04x elem_count %u", addr, dev_comp->elem_count); + BT_INFO("addr 0x%04x elem_count %u", addr, dev_comp->elem_count); for (i = 0; i < dev_comp->elem_count; i++) { struct bt_mesh_elem *elem = &dev_comp->elem[i]; @@ -823,16 +823,16 @@ void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf) u8_t count; int i; - BT_DBG("app_idx 0x%04x src 0x%04x dst 0x%04x", rx->ctx.app_idx, + BT_INFO("app_idx 0x%04x src 0x%04x dst 0x%04x", rx->ctx.app_idx, rx->ctx.addr, rx->ctx.recv_dst); - BT_DBG("len %u: %s", buf->len, bt_hex(buf->data, buf->len)); + BT_INFO("len %u: %s", buf->len, bt_hex(buf->data, buf->len)); if (get_opcode(buf, &opcode) < 0) { BT_WARN("%s, Unable to decode OpCode", __func__); return; } - BT_DBG("OpCode 0x%08x", opcode); + BT_INFO("OpCode 0x%08x", opcode); for (i = 0; i < dev_comp->elem_count; i++) { struct bt_mesh_elem *elem = &dev_comp->elem[i]; @@ -925,48 +925,17 @@ void bt_mesh_model_msg_init(struct net_buf_simple *msg, u32_t opcode) static bool ready_to_send(u8_t role, u16_t dst) { -#if CONFIG_BLE_MESH_NODE && !CONFIG_BLE_MESH_PROVISIONER - if (role == NODE) { - if (!bt_mesh_is_provisioned()) { - BT_ERR("%s, Local node is not yet provisioned", __func__); - return false; - } - if (!bt_mesh_is_provisioner_en()) { - return true; - } - } -#endif - -#if !CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER - if (role == PROVISIONER) { + if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned() && role == NODE) { + return true; + } else if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) && bt_mesh_is_provisioner_en() && role == PROVISIONER) { if (!bt_mesh_provisioner_check_msg_dst(dst)) { BT_ERR("%s, Failed to find DST 0x%04x", __func__, dst); return false; } - if (bt_mesh_is_provisioner_en()) { - return true; - } - } -#endif - -#if CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER - if (role == PROVISIONER) { - if (!bt_mesh_provisioner_check_msg_dst(dst)) { - BT_ERR("%s, Failed to check DST", __func__); - return false; - } - if (bt_mesh_is_provisioner_en()) { - return true; - } - } else { - if (!bt_mesh_is_provisioned()) { - BT_ERR("%s, Local node is not yet provisioned", __func__); - return false; - } - + return true; + } else if (IS_ENABLED(CONFIG_BLE_MESH_FAST_PROV) && bt_mesh_is_provisioned() && role == FAST_PROV) { return true; } -#endif return false; } @@ -984,9 +953,9 @@ static int model_send(struct bt_mesh_model *model, return -EINVAL; } - BT_DBG("net_idx 0x%04x app_idx 0x%04x dst 0x%04x", tx->ctx->net_idx, + BT_INFO("net_idx 0x%04x app_idx 0x%04x dst 0x%04x", tx->ctx->net_idx, tx->ctx->app_idx, tx->ctx->addr); - BT_DBG("len %u: %s", msg->len, bt_hex(msg->data, msg->len)); + BT_INFO("len %u: %s", msg->len, bt_hex(msg->data, msg->len)); if (!ready_to_send(role, tx->ctx->addr)) { BT_ERR("%s, fail", __func__); @@ -1070,7 +1039,7 @@ int bt_mesh_model_publish(struct bt_mesh_model *model) return -EADDRNOTAVAIL; } - key = bt_mesh_tx_appkey_get(pub->dev_role, pub->key, BLE_MESH_KEY_ANY); + key = bt_mesh_tx_appkey_get(pub->dev_role, pub->key); if (!key) { BT_ERR("%s, Failed to get AppKey", __func__); return -EADDRNOTAVAIL; @@ -1102,7 +1071,7 @@ int bt_mesh_model_publish(struct bt_mesh_model *model) pub->count = BLE_MESH_PUB_TRANSMIT_COUNT(pub->retransmit); - BT_DBG("Publish Retransmit Count %u Interval %ums", pub->count, + BT_INFO("Publish Retransmit Count %u Interval %ums", pub->count, BLE_MESH_PUB_TRANSMIT_INT(pub->retransmit)); sdu = bt_mesh_alloc_buf(pub->msg->len + 4); @@ -1164,37 +1133,13 @@ struct bt_mesh_subnet *bt_mesh_tx_netkey_get(u8_t role, u16_t net_idx) { struct bt_mesh_subnet *sub = NULL; -#if CONFIG_BLE_MESH_NODE && !CONFIG_BLE_MESH_PROVISIONER - if (role == NODE) { - if (bt_mesh_is_provisioned()) { - sub = bt_mesh_subnet_get(net_idx); - } - } -#endif - -#if !CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER - if (role == PROVISIONER) { - if (bt_mesh_is_provisioner_en()) { - sub = bt_mesh_provisioner_subnet_get(net_idx); - } - } -#endif - -#if CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER - if (role == NODE) { - if (bt_mesh_is_provisioned()) { - sub = bt_mesh_subnet_get(net_idx); - } - } else if (role == PROVISIONER) { - if (bt_mesh_is_provisioner_en()) { - sub = bt_mesh_provisioner_subnet_get(net_idx); - } - } else if (role == FAST_PROV) { -#if CONFIG_BLE_MESH_FAST_PROV + if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned() && role == NODE) { + sub = bt_mesh_subnet_get(net_idx); + } else if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) && bt_mesh_is_provisioner_en() && role == PROVISIONER) { + sub = bt_mesh_provisioner_subnet_get(net_idx); + } else if (IS_ENABLED(CONFIG_BLE_MESH_FAST_PROV) && bt_mesh_is_provisioned() && role == FAST_PROV) { sub = bt_mesh_fast_prov_subnet_get(net_idx); -#endif } -#endif return sub; } @@ -1203,76 +1148,28 @@ const u8_t *bt_mesh_tx_devkey_get(u8_t role, u16_t dst) { const u8_t *key = NULL; -#if CONFIG_BLE_MESH_NODE && !CONFIG_BLE_MESH_PROVISIONER - if (role == NODE) { - if (bt_mesh_is_provisioned()) { - key = bt_mesh.dev_key; - } - } -#endif - -#if !CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER - if (role == PROVISIONER) { - if (bt_mesh_is_provisioner_en()) { - key = bt_mesh_provisioner_dev_key_get(dst); - } - } -#endif - -#if CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER - if (role == NODE) { - if (bt_mesh_is_provisioned()) { - key = bt_mesh.dev_key; - } - } else if (role == PROVISIONER) { - if (bt_mesh_is_provisioner_en()) { - key = bt_mesh_provisioner_dev_key_get(dst); - } - } else if (role == FAST_PROV) { -#if CONFIG_BLE_MESH_FAST_PROV + if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned() && role == NODE) { + key = bt_mesh.dev_key; + } else if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) && bt_mesh_is_provisioner_en() && role == PROVISIONER) { + key = bt_mesh_provisioner_dev_key_get(dst); + } else if (IS_ENABLED(CONFIG_BLE_MESH_FAST_PROV) && bt_mesh_is_provisioned() && role == FAST_PROV) { key = bt_mesh_fast_prov_dev_key_get(dst); -#endif } -#endif return key; } -struct bt_mesh_app_key *bt_mesh_tx_appkey_get(u8_t role, u16_t app_idx, u16_t net_idx) +struct bt_mesh_app_key *bt_mesh_tx_appkey_get(u8_t role, u16_t app_idx) { struct bt_mesh_app_key *key = NULL; -#if CONFIG_BLE_MESH_NODE && !CONFIG_BLE_MESH_PROVISIONER - if (role == NODE) { - if (bt_mesh_is_provisioned()) { - key = bt_mesh_app_key_find(app_idx); - } + if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned() && role == NODE) { + key = bt_mesh_app_key_find(app_idx); + } else if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) && bt_mesh_is_provisioner_en() && role == PROVISIONER) { + key = bt_mesh_provisioner_app_key_find(app_idx); + } else if (IS_ENABLED(CONFIG_BLE_MESH_FAST_PROV) && bt_mesh_is_provisioned() && role == FAST_PROV) { + key = bt_mesh_fast_prov_app_key_find(app_idx); } -#endif - -#if !CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER - if (role == PROVISIONER) { - if (bt_mesh_is_provisioner_en()) { - key = bt_mesh_provisioner_app_key_find(app_idx); - } - } -#endif - -#if CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER - if (role == NODE) { - if (bt_mesh_is_provisioned()) { - key = bt_mesh_app_key_find(app_idx); - } - } else if (role == PROVISIONER) { - if (bt_mesh_is_provisioner_en()) { - key = bt_mesh_provisioner_app_key_find(app_idx); - } - } else if (role == FAST_PROV) { -#if CONFIG_BLE_MESH_FAST_PROV - key = bt_mesh_fast_prov_app_key_find(net_idx, app_idx); -#endif - } -#endif return key; } @@ -1336,7 +1233,7 @@ size_t bt_mesh_rx_devkey_size(void) size_t size = 0; #if CONFIG_BLE_MESH_NODE && !CONFIG_BLE_MESH_PROVISIONER - if (!bt_mesh_is_provisioner_en()) { + if (bt_mesh_is_provisioned()) { size = 1; } #endif diff --git a/components/bt/esp_ble_mesh/mesh_core/access.h b/components/bt/esp_ble_mesh/mesh_core/access.h index 3e46fd7692..e34521e590 100644 --- a/components/bt/esp_ble_mesh/mesh_core/access.h +++ b/components/bt/esp_ble_mesh/mesh_core/access.h @@ -62,7 +62,7 @@ struct bt_mesh_subnet *bt_mesh_tx_netkey_get(u8_t role, u16_t net_idx); const u8_t *bt_mesh_tx_devkey_get(u8_t role, u16_t dst); -struct bt_mesh_app_key *bt_mesh_tx_appkey_get(u8_t role, u16_t app_idx, u16_t net_idx); +struct bt_mesh_app_key *bt_mesh_tx_appkey_get(u8_t role, u16_t app_idx); size_t bt_mesh_rx_netkey_size(void); diff --git a/components/bt/esp_ble_mesh/mesh_core/adv.c b/components/bt/esp_ble_mesh/mesh_core/adv.c index c3162d1a0b..088e85e3e9 100644 --- a/components/bt/esp_ble_mesh/mesh_core/adv.c +++ b/components/bt/esp_ble_mesh/mesh_core/adv.c @@ -31,10 +31,8 @@ #include "beacon.h" #include "prov.h" #include "proxy_server.h" - -#include "provisioner_prov.h" #include "proxy_client.h" -#include "provisioner_beacon.h" +#include "provisioner_prov.h" /* Convert from ms to 0.625ms units */ #define ADV_SCAN_UNIT(_ms) ((_ms) * 8 / 5) @@ -278,7 +276,7 @@ static void adv_thread(void *p) /* If the interval between "current time - msg.timestamp" is bigger than * BLE_MESH_RELAY_TIME_INTERVAL, this relay packet will not be sent. */ - BT_DBG("%s, Ignore relay packet", __func__); + BT_INFO("%s, Ignore relay packet", __func__); net_buf_unref(*buf); } else { if (adv_send(*buf)) { @@ -477,7 +475,7 @@ static void ble_mesh_relay_task_post(bt_mesh_msg_t *msg, uint32_t timeout) */ handle = xQueueSelectFromSet(xBleMeshQueueSet, K_NO_WAIT); if (handle && uxQueueMessagesWaiting(xBleMeshRelayQueue)) { - BT_DBG("%s, Full queue, remove the oldest relay packet", __func__); + BT_INFO("%s, Full queue, remove the oldest relay packet", __func__); /* Remove the oldest relay packet from queue */ if (xQueueReceive(xBleMeshRelayQueue, &old_msg, K_NO_WAIT) != pdTRUE) { BT_ERR("%s, Failed to remove item from queue", __func__); @@ -584,7 +582,7 @@ static bool bt_mesh_is_adv_srv_uuid_valid(struct net_buf_simple *buf, u16_t *uui #define BLE_MESH_PROXY_SRV_DATA_LEN1 0x09 #define BLE_MESH_PROXY_SRV_DATA_LEN2 0x11 -static void bt_mesh_adv_srv_data_recv(struct net_buf_simple *buf, const bt_mesh_addr_t *addr, u16_t uuid) +static void bt_mesh_adv_srv_data_recv(struct net_buf_simple *buf, const bt_mesh_addr_t *addr, u16_t uuid, s8_t rssi) { u16_t type; @@ -609,7 +607,7 @@ static void bt_mesh_adv_srv_data_recv(struct net_buf_simple *buf, const bt_mesh_ } BT_DBG("Start to handle Mesh Prov Service Data"); - bt_mesh_provisioner_prov_adv_ind_recv(buf, addr); + bt_mesh_provisioner_prov_adv_ind_recv(buf, addr, rssi); } break; #endif @@ -622,7 +620,7 @@ static void bt_mesh_adv_srv_data_recv(struct net_buf_simple *buf, const bt_mesh_ } BT_DBG("Start to handle Mesh Proxy Service Data"); - bt_mesh_proxy_client_adv_ind_recv(buf, addr); + bt_mesh_proxy_client_adv_ind_recv(buf, addr, rssi); break; #endif default: @@ -684,29 +682,16 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr, s8_t rssi, break; #if CONFIG_BLE_MESH_PB_ADV case BLE_MESH_DATA_MESH_PROV: -#if CONFIG_BLE_MESH_NODE - if (!bt_mesh_is_provisioner_en()) { + if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_node()) { bt_mesh_pb_adv_recv(buf); } -#endif -#if CONFIG_BLE_MESH_PROVISIONER - if (bt_mesh_is_provisioner_en()) { + if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) && bt_mesh_is_provisioner_en()) { bt_mesh_provisioner_pb_adv_recv(buf); } -#endif break; #endif /* CONFIG_BLE_MESH_PB_ADV */ case BLE_MESH_DATA_MESH_BEACON: -#if CONFIG_BLE_MESH_NODE - if (!bt_mesh_is_provisioner_en()) { - bt_mesh_beacon_recv(buf); - } -#endif -#if CONFIG_BLE_MESH_PROVISIONER - if (bt_mesh_is_provisioner_en()) { - bt_mesh_provisioner_beacon_recv(buf); - } -#endif + bt_mesh_beacon_recv(buf, rssi); break; #if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \ CONFIG_BLE_MESH_GATT_PROXY_CLIENT @@ -723,7 +708,7 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr, s8_t rssi, } break; case BLE_MESH_DATA_SVC_DATA16: - bt_mesh_adv_srv_data_recv(buf, addr, uuid); + bt_mesh_adv_srv_data_recv(buf, addr, uuid, rssi); break; #endif default: diff --git a/components/bt/esp_ble_mesh/mesh_core/beacon.c b/components/bt/esp_ble_mesh/mesh_core/beacon.c index 32772b494c..114cc48d17 100644 --- a/components/bt/esp_ble_mesh/mesh_core/beacon.c +++ b/components/bt/esp_ble_mesh/mesh_core/beacon.c @@ -26,8 +26,9 @@ #include "beacon.h" #include "foundation.h" #include "proxy_client.h" - -#if CONFIG_BLE_MESH_NODE +#include "access.h" +#include "provisioner_prov.h" +#include "provisioner_main.h" #if defined(CONFIG_BLE_MESH_FAST_PROV) #define UNPROVISIONED_INTERVAL K_SECONDS(3) @@ -53,12 +54,15 @@ static struct k_delayed_work beacon_timer; static struct bt_mesh_subnet *cache_check(u8_t data[21]) { + size_t subnet_size; int i; - for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { - struct bt_mesh_subnet *sub = &bt_mesh.sub[i]; + subnet_size = bt_mesh_rx_netkey_size(); - if (sub->net_idx == BLE_MESH_KEY_UNUSED) { + for (i = 0; i < subnet_size; i++) { + struct bt_mesh_subnet *sub = bt_mesh_rx_netkey_get(i); + + if (sub == NULL || sub->net_idx == BLE_MESH_KEY_UNUSED) { continue; } @@ -108,9 +112,9 @@ void bt_mesh_beacon_create(struct bt_mesh_subnet *sub, net_buf_simple_add_mem(buf, sub->auth, 8); - BT_DBG("net_idx 0x%04x flags 0x%02x NetID %s", sub->net_idx, + BT_INFO("net_idx 0x%04x flags 0x%02x NetID %s", sub->net_idx, flags, bt_hex(keys->net_id, 8)); - BT_DBG("IV Index 0x%08x Auth %s", bt_mesh.iv_index, + BT_INFO("IV Index 0x%08x Auth %s", bt_mesh.iv_index, bt_hex(sub->auth, 8)); } @@ -124,16 +128,19 @@ static int secure_beacon_send(void) .end = beacon_complete, }; u32_t now = k_uptime_get_32(); + size_t subnet_size; int i; BT_DBG("%s", __func__); - for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { - struct bt_mesh_subnet *sub = &bt_mesh.sub[i]; + subnet_size = bt_mesh_rx_netkey_size(); + + for (i = 0; i < subnet_size; i++) { + struct bt_mesh_subnet *sub = bt_mesh_rx_netkey_get(i); struct net_buf *buf; u32_t time_diff; - if (sub->net_idx == BLE_MESH_KEY_UNUSED) { + if (sub == NULL || sub->net_idx == BLE_MESH_KEY_UNUSED) { continue; } @@ -171,6 +178,7 @@ static int secure_beacon_send(void) return 0; } +#if defined(CONFIG_BLE_MESH_NODE) static int unprovisioned_beacon_send(void) { #if defined(CONFIG_BLE_MESH_PB_ADV) @@ -228,10 +236,17 @@ static int unprovisioned_beacon_send(void) #endif /* CONFIG_BLE_MESH_PB_ADV */ return 0; } +#else /* CONFIG_BLE_MESH_NODE */ +static int unprovisioned_beacon_send(void) +{ + return 0; +} +#endif /* CONFIG_BLE_MESH_NODE */ static void update_beacon_observation(void) { static bool first_half; + size_t subnet_size; int i; /* Observation period is 20 seconds, whereas the beacon timer @@ -243,10 +258,12 @@ static void update_beacon_observation(void) return; } - for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { - struct bt_mesh_subnet *sub = &bt_mesh.sub[i]; + subnet_size = bt_mesh_rx_netkey_size(); - if (sub->net_idx == BLE_MESH_KEY_UNUSED) { + for (i = 0; i < subnet_size; i++) { + struct bt_mesh_subnet *sub = bt_mesh_rx_netkey_get(i); + + if (sub == NULL || sub->net_idx == BLE_MESH_KEY_UNUSED) { continue; } @@ -255,17 +272,33 @@ static void update_beacon_observation(void) } } +static bool ready_to_send(void) +{ + if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) { + return true; + } + + if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) && bt_mesh_is_provisioner_en()) { + if (bt_mesh_provisioner_get_all_node_count()) { + return true; + } + } + + return false; +} + static void beacon_send(struct k_work *work) { /* Don't send anything if we have an active provisioning link */ - if (IS_ENABLED(CONFIG_BLE_MESH_PROV) && bt_prov_active()) { + if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_node() && + IS_ENABLED(CONFIG_BLE_MESH_PROV) && bt_prov_active()) { k_delayed_work_submit(&beacon_timer, UNPROVISIONED_INTERVAL); return; } BT_DBG("%s", __func__); - if (bt_mesh_is_provisioned()) { + if (ready_to_send()) { update_beacon_observation(); secure_beacon_send(); @@ -276,8 +309,10 @@ static void beacon_send(struct k_work *work) PROVISIONED_INTERVAL); } } else { - unprovisioned_beacon_send(); - k_delayed_work_submit(&beacon_timer, UNPROVISIONED_INTERVAL); + if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_node()) { + unprovisioned_beacon_send(); + k_delayed_work_submit(&beacon_timer, UNPROVISIONED_INTERVAL); + } } } @@ -326,13 +361,13 @@ static void secure_beacon_recv(struct net_buf_simple *buf) cache_add(data, sub); /* If we have NetKey0 accept initiation only from it */ - if (bt_mesh_subnet_get(BLE_MESH_KEY_PRIMARY) && + if (bt_mesh_primary_subnet_exist() && sub->net_idx != BLE_MESH_KEY_PRIMARY) { BT_WARN("Ignoring secure beacon on non-primary subnet"); goto update_stats; } - BT_DBG("net_idx 0x%04x iv_index 0x%08x, current iv_index 0x%08x", + BT_INFO("net_idx 0x%04x iv_index 0x%08x, current iv_index 0x%08x", sub->net_idx, iv_index, bt_mesh.iv_index); if (bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_IVU_INITIATOR) && @@ -363,7 +398,7 @@ update_stats: } } -void bt_mesh_beacon_recv(struct net_buf_simple *buf) +void bt_mesh_beacon_recv(struct net_buf_simple *buf, s8_t rssi) { u8_t type; @@ -377,7 +412,11 @@ void bt_mesh_beacon_recv(struct net_buf_simple *buf) type = net_buf_simple_pull_u8(buf); switch (type) { case BEACON_TYPE_UNPROVISIONED: - BT_DBG("Ignoring unprovisioned device beacon"); + BT_DBG("Unprovisioned device beacon received"); + if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) && + bt_mesh_is_provisioner_en()) { + bt_mesh_provisioner_unprov_beacon_recv(buf, rssi); + } break; case BEACON_TYPE_SECURE: secure_beacon_recv(buf); @@ -411,17 +450,21 @@ void bt_mesh_beacon_ivu_initiator(bool enable) void bt_mesh_beacon_enable(void) { + size_t subnet_size; int i; - if (!bt_mesh_is_provisioned()) { + if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_node() && + !bt_mesh_is_provisioned()) { k_work_submit(&beacon_timer.work); return; } - for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { - struct bt_mesh_subnet *sub = &bt_mesh.sub[i]; + subnet_size = bt_mesh_rx_netkey_size(); - if (sub->net_idx == BLE_MESH_KEY_UNUSED) { + for (i = 0; i < subnet_size; i++) { + struct bt_mesh_subnet *sub = bt_mesh_rx_netkey_get(i); + + if (sub == NULL || sub->net_idx == BLE_MESH_KEY_UNUSED) { continue; } @@ -440,5 +483,3 @@ void bt_mesh_beacon_disable(void) k_delayed_work_cancel(&beacon_timer); } } - -#endif /* CONFIG_BLE_MESH_NODE */ diff --git a/components/bt/esp_ble_mesh/mesh_core/beacon.h b/components/bt/esp_ble_mesh/mesh_core/beacon.h index fbddedb63c..a3fd980f25 100644 --- a/components/bt/esp_ble_mesh/mesh_core/beacon.h +++ b/components/bt/esp_ble_mesh/mesh_core/beacon.h @@ -14,7 +14,7 @@ void bt_mesh_beacon_disable(void); void bt_mesh_beacon_ivu_initiator(bool enable); -void bt_mesh_beacon_recv(struct net_buf_simple *buf); +void bt_mesh_beacon_recv(struct net_buf_simple *buf, s8_t rssi); void bt_mesh_beacon_create(struct bt_mesh_subnet *sub, struct net_buf_simple *buf); diff --git a/components/bt/esp_ble_mesh/mesh_core/cfg_cli.c b/components/bt/esp_ble_mesh/mesh_core/cfg_cli.c index 3afbd8c572..377ec768d8 100644 --- a/components/bt/esp_ble_mesh/mesh_core/cfg_cli.c +++ b/components/bt/esp_ble_mesh/mesh_core/cfg_cli.c @@ -122,6 +122,8 @@ static void timeout_handler(struct k_work *work) { struct k_delayed_work *timer = NULL; bt_mesh_client_node_t *node = NULL; + struct bt_mesh_msg_ctx ctx = {0}; + u32_t opcode; BT_WARN("Receive configuration status message timeout"); @@ -132,10 +134,11 @@ static void timeout_handler(struct k_work *work) if (timer && !k_delayed_work_free(timer)) { node = CONTAINER_OF(work, bt_mesh_client_node_t, timer.work); if (node) { - bt_mesh_config_client_cb_evt_to_btc(node->opcode, - BTC_BLE_MESH_EVT_CONFIG_CLIENT_TIMEOUT, node->ctx.model, &node->ctx, NULL, 0); - // Don't forget to release the node at the end. + memcpy(&ctx, &node->ctx, sizeof(ctx)); + opcode = node->opcode; bt_mesh_client_free_node(node); + bt_mesh_config_client_cb_evt_to_btc( + opcode, BTC_BLE_MESH_EVT_CONFIG_CLIENT_TIMEOUT, ctx.model, &ctx, NULL, 0); } } @@ -224,10 +227,10 @@ static void cfg_client_cancel(struct bt_mesh_model *model, } if (!k_delayed_work_free(&node->timer)) { - bt_mesh_config_client_cb_evt_to_btc( - node->opcode, evt_type, model, ctx, (const u8_t *)status, len); - // Don't forget to release the node at the end. + u32_t opcode = node->opcode; bt_mesh_client_free_node(node); + bt_mesh_config_client_cb_evt_to_btc( + opcode, evt_type, model, ctx, (const u8_t *)status, len); } } diff --git a/components/bt/esp_ble_mesh/mesh_core/cfg_srv.c b/components/bt/esp_ble_mesh/mesh_core/cfg_srv.c index 9fd8071820..9906bb6070 100644 --- a/components/bt/esp_ble_mesh/mesh_core/cfg_srv.c +++ b/components/bt/esp_ble_mesh/mesh_core/cfg_srv.c @@ -697,13 +697,11 @@ static void beacon_set(struct bt_mesh_model *model, bt_mesh_store_cfg(); } -#if CONFIG_BLE_MESH_NODE if (cfg->beacon) { bt_mesh_beacon_enable(); } else { bt_mesh_beacon_disable(); } -#endif } } else { BT_WARN("Invalid Config Beacon value 0x%02x", buf->data[0]); @@ -2754,9 +2752,9 @@ static void node_reset(struct bt_mesh_model *model, BT_ERR("%s, Unable to send Config Node Reset Status", __func__); } -#if CONFIG_BLE_MESH_NODE - bt_mesh_reset(); -#endif + if (IS_ENABLED(CONFIG_BLE_MESH_NODE)) { + bt_mesh_reset(); + } } static void send_friend_status(struct bt_mesh_model *model, diff --git a/components/bt/esp_ble_mesh/mesh_core/friend.c b/components/bt/esp_ble_mesh/mesh_core/friend.c index 38d7932f62..965e1d31c6 100644 --- a/components/bt/esp_ble_mesh/mesh_core/friend.c +++ b/components/bt/esp_ble_mesh/mesh_core/friend.c @@ -615,7 +615,7 @@ static void friend_recv_delay(struct bt_mesh_friend *frnd) { frnd->pending_req = 1U; k_delayed_work_submit(&frnd->timer, recv_delay(frnd)); - BT_DBG("Waiting RecvDelay of %d ms", recv_delay(frnd)); + BT_INFO("Waiting RecvDelay of %d ms", recv_delay(frnd)); } int bt_mesh_friend_sub_add(struct bt_mesh_net_rx *rx, @@ -739,7 +739,7 @@ int bt_mesh_friend_poll(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf) friend_recv_delay(frnd); if (!frnd->established) { - BT_DBG("Friendship established with 0x%04x", frnd->lpn); + BT_INFO("Friendship established with 0x%04x", frnd->lpn); frnd->established = 1U; if (friend_cb) { friend_cb(true, frnd->lpn, 0); @@ -944,7 +944,7 @@ static s32_t offer_delay(struct bt_mesh_friend *frnd, s8_t rssi, u8_t crit) static const u8_t fact[] = { 10, 15, 20, 25 }; s32_t delay; - BT_DBG("ReceiveWindowFactor %u ReceiveWindow %u RSSIFactor %u RSSI %d", + BT_INFO("ReceiveWindowFactor %u ReceiveWindow %u RSSIFactor %u RSSI %d", fact[RECV_WIN_FACT(crit)], RECV_WIN, fact[RSSI_FACT(crit)], rssi); @@ -1039,7 +1039,7 @@ init_friend: frnd->lpn_counter = sys_be16_to_cpu(msg->lpn_counter); frnd->clear.frnd = sys_be16_to_cpu(msg->prev_addr); - BT_DBG("LPN 0x%04x rssi %d recv_delay %u poll_to %ums", + BT_INFO("LPN 0x%04x rssi %d recv_delay %u poll_to %ums", frnd->lpn, rx->ctx.recv_rssi, frnd->recv_delay, frnd->poll_to); /** diff --git a/components/bt/esp_ble_mesh/mesh_core/health_cli.c b/components/bt/esp_ble_mesh/mesh_core/health_cli.c index 30fcec24ce..1924ffb61f 100644 --- a/components/bt/esp_ble_mesh/mesh_core/health_cli.c +++ b/components/bt/esp_ble_mesh/mesh_core/health_cli.c @@ -75,6 +75,8 @@ static void timeout_handler(struct k_work *work) { struct k_delayed_work *timer = NULL; bt_mesh_client_node_t *node = NULL; + struct bt_mesh_msg_ctx ctx = {0}; + u32_t opcode; BT_WARN("Receive health status message timeout"); @@ -85,10 +87,11 @@ static void timeout_handler(struct k_work *work) if (timer && !k_delayed_work_free(timer)) { node = CONTAINER_OF(work, bt_mesh_client_node_t, timer.work); if (node) { - bt_mesh_health_client_cb_evt_to_btc(node->opcode, - BTC_BLE_MESH_EVT_HEALTH_CLIENT_TIMEOUT, node->ctx.model, &node->ctx, NULL, 0); - // Don't forget to release the node at the end. + memcpy(&ctx, &node->ctx, sizeof(ctx)); + opcode = node->opcode; bt_mesh_client_free_node(node); + bt_mesh_health_client_cb_evt_to_btc( + opcode, BTC_BLE_MESH_EVT_HEALTH_CLIENT_TIMEOUT, ctx.model, &ctx, NULL, 0); } } @@ -137,10 +140,10 @@ static void health_client_cancel(struct bt_mesh_model *model, } if (!k_delayed_work_free(&node->timer)) { - bt_mesh_health_client_cb_evt_to_btc( - node->opcode, evt_type, model, ctx, (const u8_t *)status, len); - // Don't forget to release the node at the end. + u32_t opcode = node->opcode; bt_mesh_client_free_node(node); + bt_mesh_health_client_cb_evt_to_btc( + opcode, evt_type, model, ctx, (const u8_t *)status, len); } } diff --git a/components/bt/esp_ble_mesh/mesh_core/include/mesh_main.h b/components/bt/esp_ble_mesh/mesh_core/include/mesh_main.h index 47df7974e7..38d7d91025 100644 --- a/components/bt/esp_ble_mesh/mesh_core/include/mesh_main.h +++ b/components/bt/esp_ble_mesh/mesh_core/include/mesh_main.h @@ -352,12 +352,6 @@ int bt_mesh_prov_enable(bt_mesh_prov_bearer_t bearers); */ int bt_mesh_prov_disable(bt_mesh_prov_bearer_t bearers); -/** @brief Indicate whether provisioner is enabled - * - * @return true - enabled, false - disabled. - */ -bool bt_mesh_is_provisioner_en(void); - /* The following API is for BLE Mesh Fast Provisioning */ /** @brief Change the device action @@ -393,6 +387,14 @@ int bt_mesh_prov_input_string(const char *str); */ int bt_mesh_prov_input_number(u32_t num); +/** @brief Enable Provisioner corresponding functionalities, e.g. scan, etc. + * + * @param bearers Bit-wise OR of provisioning bearers. + * + * @return Zero on success or (negative) error code otherwise. + */ +int bt_mesh_provisioner_net_start(bt_mesh_prov_bearer_t bearers); + /** @brief Enable specific provisioning bearers * * Enable one or more provisioning bearers. @@ -528,6 +530,13 @@ int bt_mesh_provision(const u8_t net_key[16], u16_t net_idx, u8_t flags, u32_t iv_index, u16_t addr, const u8_t dev_key[16]); +/** @brief Check if the device is an unprovisioned device + * and will act as a node once provisioned. + * + * @return true - yes, false - no. + */ +bool bt_mesh_is_node(void); + /** @brief Check if the local node has been provisioned. * * This API can be used to check if the local node has been provisioned @@ -539,6 +548,18 @@ int bt_mesh_provision(const u8_t net_key[16], u16_t net_idx, */ bool bt_mesh_is_provisioned(void); +/** @brief Check if the device is a Provisioner. + * + * @return true - yes, false - no. + */ +bool bt_mesh_is_provisioner(void); + +/** @brief Check if the Provisioner is enabled + * + * @return true - enabled, false - disabled. + */ +bool bt_mesh_is_provisioner_en(void); + /** @brief Toggle the IV Update test mode * * This API is only available if the IV Update test mode has been enabled diff --git a/components/bt/esp_ble_mesh/mesh_core/lpn.c b/components/bt/esp_ble_mesh/mesh_core/lpn.c index 5fa56855c1..3495237c0b 100644 --- a/components/bt/esp_ble_mesh/mesh_core/lpn.c +++ b/components/bt/esp_ble_mesh/mesh_core/lpn.c @@ -534,7 +534,7 @@ int bt_mesh_lpn_friend_offer(struct bt_mesh_net_rx *rx, frnd_counter = sys_be16_to_cpu(msg->frnd_counter); - BT_DBG("recv_win %u queue_size %u sub_list_size %u rssi %d counter %u", + BT_INFO("recv_win %u queue_size %u sub_list_size %u rssi %d counter %u", msg->recv_win, msg->queue_size, msg->sub_list_size, msg->rssi, frnd_counter); @@ -1020,7 +1020,7 @@ int bt_mesh_lpn_friend_update(struct bt_mesh_net_rx *rx, iv_index = sys_be32_to_cpu(msg->iv_index); - BT_DBG("flags 0x%02x iv_index 0x%08x md %u", msg->flags, iv_index, + BT_INFO("flags 0x%02x iv_index 0x%08x md %u", msg->flags, iv_index, msg->md); if (bt_mesh_kr_update(sub, BLE_MESH_KEY_REFRESH(msg->flags), diff --git a/components/bt/esp_ble_mesh/mesh_core/main.c b/components/bt/esp_ble_mesh/mesh_core/main.c index 96cde51736..a2087b5bee 100644 --- a/components/bt/esp_ble_mesh/mesh_core/main.c +++ b/components/bt/esp_ble_mesh/mesh_core/main.c @@ -35,8 +35,6 @@ #include "proxy_client.h" #include "provisioner_main.h" -static volatile bool provisioner_en = false; - #define ACTION_ENTER 0x01 #define ACTION_SUSPEND 0x02 #define ACTION_EXIT 0x03 @@ -49,8 +47,9 @@ int bt_mesh_provision(const u8_t net_key[16], u16_t net_idx, int err; BT_INFO("Primary Element: 0x%04x", addr); - BT_DBG("net_idx 0x%04x flags 0x%02x iv_index 0x%04x", + BT_INFO("net_idx 0x%04x flags 0x%02x iv_index 0x%04x", net_idx, flags, iv_index); + BT_INFO("dev_key %s", bt_hex(dev_key, 16)); if (bt_mesh_atomic_test_and_set_bit(bt_mesh.flags, BLE_MESH_VALID)) { return -EALREADY; @@ -149,9 +148,32 @@ void bt_mesh_reset(void) } } +bool bt_mesh_is_node(void) +{ + return bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_NODE); +} + bool bt_mesh_is_provisioned(void) { - return bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_VALID); + if (bt_mesh_is_node()) { + return bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_VALID); + } else { + return false; + } +} + +bool bt_mesh_is_provisioner(void) +{ + return bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_PROVISIONER); +} + +bool bt_mesh_is_provisioner_en(void) +{ + if (bt_mesh_is_provisioner()) { + return bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_VALID_PROV); + } else { + return false; + } } int bt_mesh_prov_enable(bt_mesh_prov_bearer_t bearers) @@ -160,6 +182,12 @@ int bt_mesh_prov_enable(bt_mesh_prov_bearer_t bearers) return -EALREADY; } + bt_mesh_atomic_set_bit(bt_mesh.flags, BLE_MESH_NODE); + + if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { + bt_mesh_store_role(); + } + if (IS_ENABLED(CONFIG_BLE_MESH_PB_ADV) && (bearers & BLE_MESH_PROV_ADV)) { /* Make sure we're scanning for provisioning inviations */ @@ -174,10 +202,6 @@ int bt_mesh_prov_enable(bt_mesh_prov_bearer_t bearers) bt_mesh_adv_update(); } - if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { - bt_mesh_store_role(NODE); - } - return 0; } @@ -187,6 +211,12 @@ int bt_mesh_prov_disable(bt_mesh_prov_bearer_t bearers) return -EALREADY; } + bt_mesh_atomic_clear_bit(bt_mesh.flags, BLE_MESH_NODE); + + if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { + bt_mesh_clear_role(); + } + if (IS_ENABLED(CONFIG_BLE_MESH_PB_ADV) && (bearers & BLE_MESH_PROV_ADV)) { bt_mesh_beacon_disable(); @@ -198,10 +228,6 @@ int bt_mesh_prov_disable(bt_mesh_prov_bearer_t bearers) bt_mesh_proxy_prov_disable(true); } - if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { - bt_mesh_clear_role(); - } - return 0; } @@ -327,9 +353,7 @@ int bt_mesh_init(const struct bt_mesh_prov *prov, vTaskDelay((delay % 3000) / portTICK_PERIOD_MS); } - if (IS_ENABLED(CONFIG_BLE_MESH_NODE)) { - bt_mesh_beacon_init(); - } + bt_mesh_beacon_init(); bt_mesh_adv_init(); @@ -376,7 +400,7 @@ int bt_mesh_deinit(void) } bt_mesh_scan_disable(); - provisioner_en = false; + bt_mesh_atomic_clear_bit(bt_mesh.flags, BLE_MESH_VALID_PROV); } if (IS_ENABLED(CONFIG_BLE_MESH_PROV)) { @@ -446,34 +470,10 @@ int bt_mesh_deinit(void) return 0; } -bool bt_mesh_is_provisioner_en(void) +#if defined(CONFIG_BLE_MESH_PROVISIONER) +int bt_mesh_provisioner_net_start(bt_mesh_prov_bearer_t bearers) { - return provisioner_en; -} - -/* The following APIs are for fast provisioning */ - -#if CONFIG_BLE_MESH_PROVISIONER -int bt_mesh_provisioner_enable(bt_mesh_prov_bearer_t bearers) -{ - int err; - - if (bt_mesh_is_provisioner_en()) { - BT_WARN("%s, Already", __func__); - return -EALREADY; - } - - err = bt_mesh_provisioner_set_prov_info(); - if (err) { - BT_ERR("%s, Failed to set provisioning info", __func__); - return err; - } - - err = bt_mesh_provisioner_net_create(); - if (err) { - BT_ERR("%s, Failed to create network", __func__); - return err; - } + bt_mesh_provisioner_set_prov_bearer(bearers, false); #if defined(CONFIG_BLE_MESH_USE_DUPLICATE_SCAN) if (IS_ENABLED(CONFIG_BLE_MESH_PB_ADV) && @@ -505,44 +505,92 @@ int bt_mesh_provisioner_enable(bt_mesh_prov_bearer_t bearers) bt_mesh_friend_init(); } - if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { - bt_mesh_store_role(PROVISIONER); - } - - provisioner_en = true; + bt_mesh_atomic_set_bit(bt_mesh.flags, BLE_MESH_VALID_PROV); return 0; } -int bt_mesh_provisioner_disable(bt_mesh_prov_bearer_t bearers) +int bt_mesh_provisioner_enable(bt_mesh_prov_bearer_t bearers) { - if (!bt_mesh_is_provisioner_en()) { - BT_WARN("%s, Provisioner is already disabled", __func__); + int err; + + if (bt_mesh_is_provisioner_en()) { + BT_WARN("%s, Already", __func__); return -EALREADY; } - if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) && - (bearers & BLE_MESH_PROV_GATT)) { - bt_mesh_provisioner_pb_gatt_disable(); + err = bt_mesh_provisioner_set_prov_info(); + if (err) { + BT_ERR("%s, Failed to set provisioning info", __func__); + return err; } - if ((IS_ENABLED(CONFIG_BLE_MESH_PB_ADV) && - (bearers & BLE_MESH_PROV_ADV)) && - (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) && - (bearers & BLE_MESH_PROV_GATT))) { + err = bt_mesh_provisioner_net_create(); + if (err) { + BT_ERR("%s, Failed to create network", __func__); + return err; + } + + bt_mesh_atomic_set_bit(bt_mesh.flags, BLE_MESH_PROVISIONER); + + if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { + bt_mesh_store_role(); + } + + return bt_mesh_provisioner_net_start(bearers); +} + +int bt_mesh_provisioner_disable(bt_mesh_prov_bearer_t bearers) +{ + bt_mesh_prov_bearer_t enable; + + if (!bt_mesh_is_provisioner_en()) { + BT_WARN("%s, Already", __func__); + return -EALREADY; + } + + enable = bt_mesh_provisioner_get_prov_bearer(); + if (!(enable & bearers)) { + BT_ERR("%s, Bearers mismatch", __func__); + return -EINVAL; + } + + bt_mesh_provisioner_set_prov_bearer(bearers, true); + + if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) && + (enable & BLE_MESH_PROV_GATT) && + (bearers & BLE_MESH_PROV_GATT)) { + bt_mesh_provisioner_pb_gatt_disable(); +#if defined(CONFIG_BLE_MESH_USE_DUPLICATE_SCAN) + bt_mesh_update_exceptional_list(BLE_MESH_EXCEP_LIST_REMOVE, + BLE_MESH_EXCEP_INFO_MESH_PROV_ADV, NULL); +#endif + } + + if (!(enable & (~bearers))) { + /* Provisioner is disabled completely, disable scan here */ bt_mesh_scan_disable(); + +#if defined(CONFIG_BLE_MESH_USE_DUPLICATE_SCAN) + if (IS_ENABLED(CONFIG_BLE_MESH_PB_ADV) && + (enable & BLE_MESH_PROV_ADV)) { + bt_mesh_update_exceptional_list(BLE_MESH_EXCEP_LIST_REMOVE, + BLE_MESH_EXCEP_INFO_MESH_BEACON, NULL); + } +#endif + + /* Clear corresponding flags */ + bt_mesh_atomic_and(bt_mesh.flags, ~(BIT(BLE_MESH_PROVISIONER) | BIT(BLE_MESH_VALID_PROV))); + + /* When Provisioner is disabled, the device role indicated by bt_mesh.flags + * will not be cleared. + */ } if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) { bt_mesh_friend_clear_net_idx(BLE_MESH_KEY_ANY); } - if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { - bt_mesh_clear_role(); - } - - provisioner_en = false; - return 0; } #endif /* CONFIG_BLE_MESH_PROVISIONER */ @@ -556,9 +604,9 @@ u8_t bt_mesh_set_fast_prov_action(u8_t action) return 0x01; } - if ((!provisioner_en && (action == ACTION_SUSPEND || action == ACTION_EXIT)) || - (provisioner_en && (action == ACTION_ENTER))) { - BT_WARN("%s, Action is already done", __func__); + if ((!bt_mesh_is_provisioner_en() && (action == ACTION_SUSPEND || action == ACTION_EXIT)) || + (bt_mesh_is_provisioner_en() && (action == ACTION_ENTER))) { + BT_WARN("%s, Already", __func__); return 0x0; } @@ -579,8 +627,8 @@ u8_t bt_mesh_set_fast_prov_action(u8_t action) if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT)) { bt_mesh_provisioner_pb_gatt_enable(); } - bt_mesh_provisioner_set_fast_prov_flag(true); - provisioner_en = true; + bt_mesh_provisioner_fast_prov_enable(true); + bt_mesh_atomic_or(bt_mesh.flags, BIT(BLE_MESH_PROVISIONER) | BIT(BLE_MESH_VALID_PROV)); } else { if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT)) { bt_mesh_provisioner_pb_gatt_disable(); @@ -596,8 +644,8 @@ u8_t bt_mesh_set_fast_prov_action(u8_t action) bt_mesh_adv_update(); } #endif - bt_mesh_provisioner_set_fast_prov_flag(false); - provisioner_en = false; + bt_mesh_atomic_and(bt_mesh.flags, ~(BIT(BLE_MESH_PROVISIONER) | BIT(BLE_MESH_VALID_PROV))); + bt_mesh_provisioner_fast_prov_enable(false); if (action == ACTION_EXIT) { bt_mesh_provisioner_remove_node(NULL); } diff --git a/components/bt/esp_ble_mesh/mesh_core/net.c b/components/bt/esp_ble_mesh/mesh_core/net.c index 3887ba4adc..9ca852a262 100644 --- a/components/bt/esp_ble_mesh/mesh_core/net.c +++ b/components/bt/esp_ble_mesh/mesh_core/net.c @@ -541,7 +541,7 @@ bool bt_mesh_kr_update(struct bt_mesh_subnet *sub, u8_t new_kr, bool new_key) if (sub->kr_flag) { if (sub->kr_phase == BLE_MESH_KR_PHASE_1) { - BT_DBG("Phase 1 -> Phase 2"); + BT_INFO("Phase 1 -> Phase 2"); sub->kr_phase = BLE_MESH_KR_PHASE_2; return true; } @@ -560,7 +560,7 @@ bool bt_mesh_kr_update(struct bt_mesh_subnet *sub, u8_t new_kr, bool new_key) * Intentional fall-through. */ case BLE_MESH_KR_PHASE_2: - BT_DBG("KR Phase 0x%02x -> Normal", sub->kr_phase); + BT_INFO("KR Phase 0x%02x -> Normal", sub->kr_phase); bt_mesh_net_revoke_keys(sub); if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER) || IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) { @@ -708,12 +708,12 @@ do_update: if (iv_update) { bt_mesh.iv_index = iv_index; - BT_DBG("IV Update state entered. New index 0x%08x", + BT_INFO("IV Update state entered. New index 0x%08x", bt_mesh.iv_index); bt_mesh_rpl_reset(); } else { - BT_DBG("Normal mode entered"); + BT_INFO("Normal mode entered"); bt_mesh.seq = 0U; } @@ -732,6 +732,21 @@ do_update: return true; } +bool bt_mesh_primary_subnet_exist(void) +{ + if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) { + if (bt_mesh_subnet_get(BLE_MESH_KEY_PRIMARY)) { + return true; + } + } else if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) && bt_mesh_is_provisioner_en()) { + if (bt_mesh_provisioner_subnet_get(BLE_MESH_KEY_PRIMARY)) { + return true; + } + } + + return false; +} + u32_t bt_mesh_next_seq(void) { u32_t seq = bt_mesh.seq++; @@ -742,10 +757,8 @@ u32_t bt_mesh_next_seq(void) if (!bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_IVU_IN_PROGRESS) && bt_mesh.seq > IV_UPDATE_SEQ_LIMIT && - bt_mesh_subnet_get(BLE_MESH_KEY_PRIMARY)) { -#if CONFIG_BLE_MESH_NODE + bt_mesh_primary_subnet_exist()) { bt_mesh_beacon_ivu_initiator(true); -#endif bt_mesh_net_iv_update(bt_mesh.iv_index + 1, true); bt_mesh_net_sec_update(NULL); } @@ -992,12 +1005,15 @@ struct bt_mesh_subnet *bt_mesh_subnet_find(const u8_t net_id[8], u8_t flags, u32_t iv_index, const u8_t auth[8], bool *new_key) { + size_t subnet_size; int i; - for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { - struct bt_mesh_subnet *sub = &bt_mesh.sub[i]; + subnet_size = bt_mesh_rx_netkey_size(); - if (sub->net_idx == BLE_MESH_KEY_UNUSED) { + for (i = 0; i < subnet_size; i++) { + struct bt_mesh_subnet *sub = bt_mesh_rx_netkey_get(i); + + if (sub == NULL || sub->net_idx == BLE_MESH_KEY_UNUSED) { continue; } @@ -1374,25 +1390,15 @@ int bt_mesh_net_decode(struct net_buf_simple *data, enum bt_mesh_net_if net_if, static bool ready_to_recv(void) { -#if CONFIG_BLE_MESH_NODE - if (!bt_mesh_is_provisioner_en()) { - if (!bt_mesh_is_provisioned()) { - return false; + 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()) { + return true; } } -#endif -#if !CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER - if (!bt_mesh_is_provisioner_en()) { - BT_WARN("%s, Provisioner is disabled", __func__); - return false; - } - if (!bt_mesh_provisioner_get_all_node_count()) { - return false; - } -#endif - - return true; + return false; } void bt_mesh_net_recv(struct net_buf_simple *data, s8_t rssi, @@ -1452,7 +1458,7 @@ static void ivu_refresh(struct k_work *work) { bt_mesh.ivu_duration += BLE_MESH_IVU_HOURS; - BT_DBG("%s for %u hour%s", + BT_INFO("%s for %u hour%s", bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_IVU_IN_PROGRESS) ? "IVU in Progress" : "IVU Normal mode", bt_mesh.ivu_duration, bt_mesh.ivu_duration == 1U ? "" : "s"); @@ -1467,9 +1473,7 @@ static void ivu_refresh(struct k_work *work) } if (bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_IVU_IN_PROGRESS)) { -#if CONFIG_BLE_MESH_NODE bt_mesh_beacon_ivu_initiator(true); -#endif bt_mesh_net_iv_update(bt_mesh.iv_index, false); } else if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { bt_mesh_store_iv(true); diff --git a/components/bt/esp_ble_mesh/mesh_core/net.h b/components/bt/esp_ble_mesh/mesh_core/net.h index b9ac823771..35874029f0 100644 --- a/components/bt/esp_ble_mesh/mesh_core/net.h +++ b/components/bt/esp_ble_mesh/mesh_core/net.h @@ -208,7 +208,10 @@ struct bt_mesh_lpn { /* bt_mesh_net.flags */ enum { + BLE_MESH_NODE, /* Device is a node */ + BLE_MESH_PROVISIONER, /* Device is a Provisioner */ BLE_MESH_VALID, /* We have been provisioned */ + BLE_MESH_VALID_PROV, /* Provisioner has been enabled */ BLE_MESH_SUSPENDED, /* Network is temporarily suspended */ BLE_MESH_IVU_IN_PROGRESS, /* IV Update in Progress */ BLE_MESH_IVU_INITIATOR, /* IV Update initiated by us */ @@ -363,6 +366,8 @@ int bt_mesh_net_decode(struct net_buf_simple *data, enum bt_mesh_net_if net_if, void bt_mesh_net_recv(struct net_buf_simple *data, s8_t rssi, enum bt_mesh_net_if net_if); +bool bt_mesh_primary_subnet_exist(void); + u32_t bt_mesh_next_seq(void); void bt_mesh_net_start(void); diff --git a/components/bt/esp_ble_mesh/mesh_core/prov.c b/components/bt/esp_ble_mesh/mesh_core/prov.c index 9d7581bdea..d7e7a44232 100644 --- a/components/bt/esp_ble_mesh/mesh_core/prov.c +++ b/components/bt/esp_ble_mesh/mesh_core/prov.c @@ -809,11 +809,11 @@ static int prov_auth(u8_t method, u8_t action, u8_t size) static void prov_start(const u8_t *data) { - BT_DBG("Algorithm: 0x%02x", data[0]); - BT_DBG("Public Key: 0x%02x", data[1]); - BT_DBG("Auth Method: 0x%02x", data[2]); - BT_DBG("Auth Action: 0x%02x", data[3]); - BT_DBG("Auth Size: 0x%02x", data[4]); + BT_INFO("Algorithm: 0x%02x", data[0]); + BT_INFO("Public Key: 0x%02x", data[1]); + BT_INFO("Auth Method: 0x%02x", data[2]); + BT_INFO("Auth Action: 0x%02x", data[3]); + BT_INFO("Auth Size: 0x%02x", data[4]); if (data[0] != PROV_ALG_P256) { BT_ERR("%s, Unknown algorithm 0x%02x", __func__, data[0]); @@ -909,7 +909,7 @@ static void send_input_complete(void) int bt_mesh_input_number(u32_t num) { - BT_DBG("%u", num); + BT_INFO("%u", num); if (!bt_mesh_atomic_test_and_clear_bit(link.flags, WAIT_NUMBER)) { return -EINVAL; @@ -932,7 +932,7 @@ int bt_mesh_input_number(u32_t num) int bt_mesh_input_string(const char *str) { - BT_DBG("%s", str); + BT_INFO("%s", str); if (!bt_mesh_atomic_test_and_clear_bit(link.flags, WAIT_STRING)) { return -EINVAL; @@ -1736,7 +1736,7 @@ bool bt_prov_active(void) static void protocol_timeout(struct k_work *work) { - BT_DBG("Protocol timeout"); + BT_WARN("Protocol timeout"); #if defined(CONFIG_BLE_MESH_PB_GATT) if (link.conn) { diff --git a/components/bt/esp_ble_mesh/mesh_core/provisioner_beacon.c b/components/bt/esp_ble_mesh/mesh_core/provisioner_beacon.c deleted file mode 100644 index df6ac3c740..0000000000 --- a/components/bt/esp_ble_mesh/mesh_core/provisioner_beacon.c +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2017-2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include -#include - -#include "sdkconfig.h" -#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLE_MESH_DEBUG_BEACON) - -#include "mesh_util.h" -#include "mesh_buf.h" -#include "mesh_main.h" -#include "mesh_trace.h" - -#include "adv.h" -#include "mesh.h" -#include "net.h" -#include "prov.h" -#include "crypto.h" -#include "beacon.h" -#include "foundation.h" -#include "provisioner_prov.h" - -#define BEACON_TYPE_UNPROVISIONED 0x00 -#define BEACON_TYPE_SECURE 0x01 - -#if CONFIG_BLE_MESH_PROVISIONER - -static void provisioner_secure_beacon_recv(struct net_buf_simple *buf) -{ - // TODO: Provisioner receive and handle Secure Network Beacon -} - -void bt_mesh_provisioner_beacon_recv(struct net_buf_simple *buf) -{ - u8_t type; - - BT_DBG("%u bytes: %s", buf->len, bt_hex(buf->data, buf->len)); - - if (buf->len < 1) { - BT_ERR("%s, Too short beacon", __func__); - return; - } - - type = net_buf_simple_pull_u8(buf); - switch (type) { - case BEACON_TYPE_UNPROVISIONED: - BT_DBG("Unprovisioned device beacon received"); - bt_mesh_provisioner_unprov_beacon_recv(buf); - break; - case BEACON_TYPE_SECURE: - provisioner_secure_beacon_recv(buf); - break; - default: - BT_DBG("%s, Unknown beacon type 0x%02x", __func__, type); - break; - } -} - -#endif /* CONFIG_BLE_MESH_PROVISIONER */ diff --git a/components/bt/esp_ble_mesh/mesh_core/provisioner_beacon.h b/components/bt/esp_ble_mesh/mesh_core/provisioner_beacon.h deleted file mode 100644 index 8daa49f898..0000000000 --- a/components/bt/esp_ble_mesh/mesh_core/provisioner_beacon.h +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2017-2019 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 _PROVISIONER_BEACON_H_ -#define _PROVISIONER_BEACON_H_ - -void bt_mesh_provisioner_beacon_recv(struct net_buf_simple *buf); - -#endif /* _PROVISIONER_BEACON_H_ */ \ No newline at end of file diff --git a/components/bt/esp_ble_mesh/mesh_core/provisioner_main.c b/components/bt/esp_ble_mesh/mesh_core/provisioner_main.c index 6be6d2440e..5e27a4fbcb 100644 --- a/components/bt/esp_ble_mesh/mesh_core/provisioner_main.c +++ b/components/bt/esp_ble_mesh/mesh_core/provisioner_main.c @@ -190,12 +190,13 @@ int bt_mesh_provisioner_provision(const bt_mesh_addr_t *addr, const u8_t uuid[16 return -EINVAL; } - BT_DBG("unicast_addr: 0x%x, element_num: 0x%x, net_idx: 0x%x", + BT_INFO("unicast_addr 0x%04x, elem_num %d, net_idx 0x%04x", unicast_addr, element_num, net_idx); - BT_DBG("dev_uuid: %s", bt_hex(uuid, 16)); - BT_DBG("dev_key: %s", bt_hex(dev_key, 16)); + BT_INFO("dev_uuid %s", bt_hex(uuid, 16)); + BT_INFO("dev_key %s", bt_hex(dev_key, 16)); - memcpy(&node.addr, addr, sizeof(bt_mesh_addr_t)); + memcpy(node.addr, addr->val, BLE_MESH_ADDR_LEN); + node.addr_type = addr->type; memcpy(node.dev_uuid, uuid, 16); node.oob_info = oob_info; node.unicast_addr = unicast_addr; @@ -285,8 +286,8 @@ bool bt_mesh_provisioner_find_node_with_addr(const bt_mesh_addr_t *addr, bool re for (i = 0U; i < CONFIG_BLE_MESH_MAX_PROV_NODES; i++) { if (mesh_nodes[i]) { - if (!memcmp(mesh_nodes[i]->addr.val, addr->val, BLE_MESH_ADDR_LEN) && - mesh_nodes[i]->addr.type == addr->type) { + 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); } @@ -333,17 +334,63 @@ struct bt_mesh_node *bt_mesh_provisioner_get_prov_node_info(const u8_t uuid[16]) return NULL; } + bt_mesh_provisioner_lock(); + for (i = 0U; i < CONFIG_BLE_MESH_MAX_PROV_NODES; i++) { if (mesh_nodes[i]) { if (!memcmp(mesh_nodes[i]->dev_uuid, uuid, 16)) { + bt_mesh_provisioner_unlock(); return mesh_nodes[i]; } } } + bt_mesh_provisioner_unlock(); return NULL; } +bool bt_mesh_provisioner_check_is_addr_dup(u16_t addr, u8_t elem_num, bool comp_with_own) +{ + const struct bt_mesh_comp *comp = NULL; + struct bt_mesh_node *node = NULL; + u16_t primary_addr = BLE_MESH_ADDR_UNASSIGNED; + u16_t comp_addr; + size_t i; + + if (comp_with_own) { + comp = bt_mesh_comp_get(); + if (!comp) { + BT_ERR("NULL composition data"); + return true; + } + + primary_addr = bt_mesh_provisioner_get_primary_elem_addr(); + if (!BLE_MESH_ADDR_IS_UNICAST(primary_addr)) { + BT_ERR("%s, Not a unicast address 0x%04x", __func__, primary_addr); + return true; + } + } + + for (comp_addr = addr; comp_addr < addr + elem_num; comp_addr++) { + for (i = 0U; i < ARRAY_SIZE(mesh_nodes); i++) { + node = mesh_nodes[i]; + if (node && comp_addr >= node->unicast_addr && + comp_addr < node->unicast_addr + node->element_num) { + BT_ERR("Duplicate with node address 0x%04x", comp_addr); + return true; + } + + if (comp_with_own && comp_addr >= primary_addr && + comp_addr < primary_addr + comp->elem_count) { + BT_ERR("Duplicate with Provisioner address 0x%04x", comp_addr); + return true; + } + } + } + + return false; +} + int bt_mesh_provisioner_init(void) { bt_mesh_provisioner_mutex_new(); @@ -373,10 +420,13 @@ int bt_mesh_provisioner_net_create(void) /* If the device only acts as a Provisioner, need to initialize * each element's address. */ - bt_mesh_comp_provision(prov->prov_unicast_addr); + bt_mesh_comp_provision(bt_mesh_provisioner_get_primary_elem_addr()); if (bt_mesh.p_sub[0]) { - BT_DBG("Keys of Provisioner restored from flash"); + /* Provisioner is already enabled (enable -> disable -> enable), + * or Provisioner is restored from flash. + */ + BT_INFO("Provisioner already created network"); sub = bt_mesh.p_sub[0]; goto done; } @@ -441,7 +491,7 @@ int bt_mesh_provisioner_net_create(void) } done: - BT_DBG("net_idx 0x%03x, netkey %s, nid 0x%02x", + BT_INFO("net_idx 0x%03x, netkey %s, nid 0x%02x", sub->net_idx, bt_hex(sub->keys[0].net, 16), sub->keys[0].nid); return 0; @@ -490,7 +540,7 @@ int bt_mesh_provisioner_deinit(void) return 0; } -/* The following APIs are for provisioner upper layers internal use */ +/* The following APIs are for Provisioner internal usage */ const u8_t *bt_mesh_provisioner_net_key_get(u16_t net_idx) { @@ -501,13 +551,13 @@ const u8_t *bt_mesh_provisioner_net_key_get(u16_t net_idx) for (i = 0U; i < ARRAY_SIZE(bt_mesh.p_sub); i++) { sub = bt_mesh.p_sub[i]; - if (!sub || (sub->net_idx != net_idx)) { - continue; + if (sub && sub->net_idx == net_idx) { + if (sub->kr_flag) { + return sub->keys[1].net; + } else { + return sub->keys[0].net; + } } - if (sub->kr_flag) { - return sub->keys[1].net; - } - return sub->keys[0].net; } return NULL; @@ -526,10 +576,9 @@ struct bt_mesh_subnet *bt_mesh_provisioner_subnet_get(u16_t net_idx) for (i = 0U; i < ARRAY_SIZE(bt_mesh.p_sub); i++) { sub = bt_mesh.p_sub[i]; - if (!sub || (sub->net_idx != net_idx)) { - continue; + if (sub && sub->net_idx == net_idx) { + return sub; } - return sub; } return NULL; @@ -592,10 +641,7 @@ struct bt_mesh_app_key *bt_mesh_provisioner_app_key_find(u16_t app_idx) for (i = 0U; i < ARRAY_SIZE(bt_mesh.p_app_keys); i++) { key = bt_mesh.p_app_keys[i]; - if (!key) { - continue; - } - if (key->net_idx != BLE_MESH_KEY_UNUSED && + if (key && key->net_idx != BLE_MESH_KEY_UNUSED && key->app_idx == app_idx) { return key; } @@ -614,6 +660,8 @@ int bt_mesh_provisioner_restore_node_info(struct bt_mesh_node *node, bool prov) return provisioner_store_node(node, prov, false, NULL); } +/* Provisioner related internal test functions */ + int bt_mesh_provisioner_store_node_info(struct bt_mesh_node *node) { if (!node) { @@ -636,20 +684,23 @@ struct bt_mesh_node *bt_mesh_provisioner_get_node_info(u16_t unicast_addr) return NULL; } + bt_mesh_provisioner_lock(); + for (i = 0U; i < ARRAY_SIZE(mesh_nodes); i++) { node = mesh_nodes[i]; - if (!node) { - continue; - } - if (unicast_addr >= node->unicast_addr && + if (node && unicast_addr >= node->unicast_addr && unicast_addr < (node->unicast_addr + node->element_num)) { + bt_mesh_provisioner_unlock(); return node; } } + bt_mesh_provisioner_unlock(); return NULL; } +/* Provisioner related node name management functions */ + int bt_mesh_provisioner_set_node_name(u16_t index, const char *name) { size_t length, name_len; @@ -669,22 +720,22 @@ int bt_mesh_provisioner_set_node_name(u16_t index, const char *name) BT_DBG("name len is %d, name is %s", strlen(name), name); - length = (strlen(name) <= MESH_NAME_SIZE) ? strlen(name) : MESH_NAME_SIZE; + length = (strlen(name) <= NODE_NAME_SIZE) ? strlen(name) : NODE_NAME_SIZE; for (i = 0U; i < ARRAY_SIZE(mesh_nodes); i++) { - if (!mesh_nodes[i] || !mesh_nodes[i]->node_name) { + if (!mesh_nodes[i] || !mesh_nodes[i]->name) { continue; } - name_len = strlen(mesh_nodes[i]->node_name); + name_len = strlen(mesh_nodes[i]->name); if (length != name_len) { continue; } - if (!strncmp(mesh_nodes[i]->node_name, name, length)) { + if (!strncmp(mesh_nodes[i]->name, name, length)) { BT_WARN("Node name %s already exists", name); return -EEXIST; } } - strncpy(mesh_nodes[index]->node_name, name, length); + strncpy(mesh_nodes[index]->name, name, length); return 0; } @@ -698,7 +749,7 @@ const char *bt_mesh_provisioner_get_node_name(u16_t index) return NULL; } - return mesh_nodes[index]->node_name; + return mesh_nodes[index]->name; } int bt_mesh_provisioner_get_node_index(const char *name) @@ -712,16 +763,16 @@ int bt_mesh_provisioner_get_node_index(const char *name) return -EINVAL; } - length = (strlen(name) <= MESH_NAME_SIZE) ? strlen(name) : MESH_NAME_SIZE; + length = (strlen(name) <= NODE_NAME_SIZE) ? strlen(name) : NODE_NAME_SIZE; for (i = 0U; i < ARRAY_SIZE(mesh_nodes); i++) { - if (!mesh_nodes[i] || !mesh_nodes[i]->node_name) { + if (!mesh_nodes[i] || !mesh_nodes[i]->name) { continue; } - name_len = strlen(mesh_nodes[i]->node_name); + name_len = strlen(mesh_nodes[i]->name); if (length != name_len) { continue; } - if (!strncmp(mesh_nodes[i]->node_name, name, length)) { + if (!strncmp(mesh_nodes[i]->name, name, length)) { return i; } } @@ -729,6 +780,8 @@ int bt_mesh_provisioner_get_node_index(const char *name) return -ENODEV; } +/* Provisioner related NetKey and AppKey functions */ + static int provisioner_check_app_key(const u8_t app_key[16], u16_t *app_idx) { struct bt_mesh_app_key *key = NULL; @@ -1287,23 +1340,23 @@ int bt_mesh_print_local_composition_data(void) return -EINVAL; } - BT_WARN("************************************************"); - BT_WARN("* cid: 0x%04x pid: 0x%04x vid: 0x%04x *", comp->cid, comp->pid, comp->vid); - BT_WARN("* Element Number: 0x%02x *", comp->elem_count); + BT_INFO("************************************************"); + BT_INFO("* cid: 0x%04x pid: 0x%04x vid: 0x%04x *", comp->cid, comp->pid, comp->vid); + BT_INFO("* Element Number: 0x%02x *", comp->elem_count); for (i = 0U; i < comp->elem_count; i++) { elem = &comp->elem[i]; - BT_WARN("* Element %d: 0x%04x *", i, elem->addr); - BT_WARN("* Loc: 0x%04x NumS: 0x%02x NumV: 0x%02x *", elem->loc, elem->model_count, elem->vnd_model_count); + BT_INFO("* Element %d: 0x%04x *", i, elem->addr); + BT_INFO("* Loc: 0x%04x NumS: 0x%02x NumV: 0x%02x *", elem->loc, elem->model_count, elem->vnd_model_count); for (j = 0U; j < elem->model_count; j++) { model = &elem->models[j]; - BT_WARN("* sig_model %d: id - 0x%04x *", j, model->id); + BT_INFO("* sig_model %d: id - 0x%04x *", j, model->id); } for (j = 0U; j < elem->vnd_model_count; j++) { model = &elem->vnd_models[j]; - BT_WARN("* vnd_model %d: id - 0x%04x, cid - 0x%04x *", j, model->vnd.id, model->vnd.company); + BT_INFO("* vnd_model %d: id - 0x%04x, cid - 0x%04x *", j, model->vnd.id, model->vnd.company); } } - BT_WARN("************************************************"); + BT_INFO("************************************************"); return 0; } @@ -1364,7 +1417,7 @@ struct bt_mesh_subnet *bt_mesh_fast_prov_subnet_get(u16_t net_idx) return NULL; } -struct bt_mesh_app_key *bt_mesh_fast_prov_app_key_find(u16_t net_idx, u16_t app_idx) +struct bt_mesh_app_key *bt_mesh_fast_prov_app_key_find(u16_t app_idx) { struct bt_mesh_app_key *key = NULL; size_t i; @@ -1373,14 +1426,16 @@ struct bt_mesh_app_key *bt_mesh_fast_prov_app_key_find(u16_t net_idx, u16_t app_ for (i = 0U; i < ARRAY_SIZE(bt_mesh.app_keys); i++) { key = &bt_mesh.app_keys[i]; - if (key->net_idx == net_idx && key->app_idx == app_idx) { + if (key->net_idx != BLE_MESH_KEY_UNUSED && + key->app_idx == app_idx) { return key; } } for (i = 0U; i < ARRAY_SIZE(bt_mesh.p_app_keys); i++) { key = bt_mesh.p_app_keys[i]; - if (key && key->net_idx == net_idx && key->app_idx == app_idx) { + if (key && key->net_idx != BLE_MESH_KEY_UNUSED && + key->app_idx == app_idx) { return key; } } @@ -1443,7 +1498,7 @@ const u8_t *bt_mesh_get_fast_prov_app_key(u16_t net_idx, u16_t app_idx) { struct bt_mesh_app_key *key = NULL; - key = bt_mesh_fast_prov_app_key_find(net_idx, app_idx); + key = bt_mesh_fast_prov_app_key_find(app_idx); if (!key) { BT_ERR("%s, Failed to get AppKey", __func__); return NULL; diff --git a/components/bt/esp_ble_mesh/mesh_core/provisioner_main.h b/components/bt/esp_ble_mesh/mesh_core/provisioner_main.h index 00855ce4e5..cf19ac69f9 100644 --- a/components/bt/esp_ble_mesh/mesh_core/provisioner_main.h +++ b/components/bt/esp_ble_mesh/mesh_core/provisioner_main.h @@ -20,20 +20,21 @@ #include "mesh_access.h" #include "net.h" -#define MESH_NAME_SIZE 31 +#define NODE_NAME_SIZE 31 /* Each node information stored by provisioner */ struct bt_mesh_node { - char node_name[MESH_NAME_SIZE]; /* Node name */ - bt_mesh_addr_t addr; /* Device address */ - u8_t dev_uuid[16]; /* Device UUID */ - u16_t oob_info; /* Node OOB information */ - u16_t unicast_addr; /* Node unicast address */ - u8_t element_num; /* Node element number */ - u16_t net_idx; /* Node provision net_idx */ - u8_t flags; /* Node key refresh flag and iv update flag */ - u32_t iv_index; /* Node IV Index */ - u8_t dev_key[16]; /* Node device key */ + char name[NODE_NAME_SIZE]; /* Node name */ + u8_t addr[6]; /* Node device address */ + u8_t addr_type; /* Node device address type */ + u8_t dev_uuid[16]; /* Device UUID */ + u16_t oob_info; /* Node OOB information */ + u16_t unicast_addr; /* Node unicast address */ + u8_t element_num; /* Node element number */ + u16_t net_idx; /* Node NetKey Index */ + u8_t flags; /* Node key refresh flag and iv update flag */ + u32_t iv_index; /* Node IV Index */ + u8_t dev_key[16]; /* Node device key */ } __packed; /* The following APIs are for key init, node provision & node reset. */ @@ -54,6 +55,8 @@ int bt_mesh_provisioner_remove_node(const u8_t uuid[16]); struct bt_mesh_node *bt_mesh_provisioner_get_prov_node_info(const u8_t uuid[16]); +bool bt_mesh_provisioner_check_is_addr_dup(u16_t addr, u8_t elem_num, bool comp_with_own); + int bt_mesh_provisioner_init(void); int bt_mesh_provisioner_deinit(void); @@ -110,7 +113,7 @@ const u8_t *bt_mesh_fast_prov_dev_key_get(u16_t dst); struct bt_mesh_subnet *bt_mesh_fast_prov_subnet_get(u16_t net_idx); -struct bt_mesh_app_key *bt_mesh_fast_prov_app_key_find(u16_t net_idx, u16_t app_idx); +struct bt_mesh_app_key *bt_mesh_fast_prov_app_key_find(u16_t app_idx); u8_t bt_mesh_set_fast_prov_net_idx(u16_t net_idx); diff --git a/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.c b/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.c index 12b77af8be..2b21434356 100644 --- a/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.c +++ b/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.c @@ -146,8 +146,9 @@ struct prov_link { u8_t auth_method; /* choosed authentication method */ u8_t auth_action; /* choosed authentication action */ u8_t auth_size; /* choosed authentication size */ - u16_t unicast_addr; /* unicast address assigned for device */ - bt_mesh_addr_t addr; /* Device address */ + u16_t assign_addr; /* Application assigned address for the device */ + u16_t unicast_addr; /* unicast address allocated for device */ + bt_mesh_addr_t addr; /* Device address */ #if defined(CONFIG_BLE_MESH_PB_GATT) bool connecting; /* start connecting with device */ struct bt_mesh_conn *conn; /* GATT connection */ @@ -220,7 +221,13 @@ struct prov_rx { u8_t gpc; }; -struct prov_ctx_t { +struct bt_mesh_prov_ctx { + /* Primary element address of Provisioner */ + u16_t primary_addr; + + /* Provisioning bearers used by Provisioner */ + bt_mesh_prov_bearer_t bearers; + /* If provisioning random have been generated, set BIT0 to 1 */ u8_t rand_gen_done; @@ -233,8 +240,8 @@ struct prov_ctx_t { /* Current number of PB-GATT provisioned devices simultaneously */ u8_t pbg_count; - /* Current unicast address going to assigned */ - u16_t current_addr; + /* Current unicast address going to allocated */ + u16_t curr_alloc_addr; /* Current net_idx going to be used in provisioning data */ u16_t curr_net_idx; @@ -249,7 +256,7 @@ struct prov_ctx_t { u8_t static_oob_len; /* Static OOB value */ - u8_t *static_oob_val; + u8_t static_oob_val[16]; /* Offset of the device uuid to be matched, based on zero */ u8_t match_offset; @@ -258,7 +265,7 @@ struct prov_ctx_t { u8_t match_length; /* Value of the device uuid to be matched */ - u8_t *match_value; + u8_t match_value[16]; /* Indicate when received uuid_match adv_pkts, can provision it at once */ bool prov_after_match; @@ -275,9 +282,22 @@ struct prov_ctx_t { /* Mutex used to protect the PB-GATT procedure */ osi_mutex_t pb_gatt_lock; #endif + + /* Fast provisioning related information */ + struct { + bool enable; + u16_t net_idx; + const u8_t *net_key; + u8_t flags; + u32_t iv_index; + u16_t unicast_addr_min; + u16_t unicast_addr_max; + } fast_prov; }; -static struct prov_ctx_t prov_ctx; +static struct bt_mesh_prov_ctx prov_ctx; + +#define FAST_PROV_ENABLE() (prov_ctx.fast_prov.enable) struct unprov_dev_queue { bt_mesh_addr_t addr; @@ -293,7 +313,7 @@ struct unprov_dev_queue { }, }; -static unprov_adv_pkt_cb_t notify_unprov_adv_pkt_cb; +static unprov_adv_pkt_cb_t notify_unprov_adv_pkt_cb; #define BUF_TIMEOUT K_MSEC(400) @@ -340,7 +360,7 @@ static struct prov_adv_buf { } adv_buf[CONFIG_BLE_MESH_PBA_SAME_TIME]; static u8_t adv_buf_data[ADV_BUF_SIZE * CONFIG_BLE_MESH_PBA_SAME_TIME]; -#endif +#endif /* CONFIG_BLE_MESH_PB_ADV */ #define PROV_FREE_MEM(_idx, member) \ { \ @@ -350,20 +370,6 @@ static u8_t adv_buf_data[ADV_BUF_SIZE * CONFIG_BLE_MESH_PBA_SAME_TIME]; } \ } -/* Fast provisioning uses this structure for provisioning data */ -static struct bt_mesh_fast_prov_info { - u16_t net_idx; - const u8_t *net_key; - u8_t flags; - u32_t iv_index; - u16_t unicast_addr_min; - u16_t unicast_addr_max; -} fast_prov_info; - -static bool fast_prov_flag; - -#define FAST_PROV_FLAG_GET() fast_prov_flag - #if defined(CONFIG_BLE_MESH_PB_ADV) static void bt_mesh_pb_adv_mutex_new(void) { @@ -507,9 +513,10 @@ const struct bt_mesh_prov *bt_mesh_provisioner_get_prov_info(void) return prov; } -void bt_mesh_provisoner_restore_prov_info(u16_t addr) +void bt_mesh_provisoner_restore_prov_info(u16_t primary_addr, u16_t alloc_addr) { - prov_ctx.current_addr = addr; + prov_ctx.primary_addr = primary_addr; + prov_ctx.curr_alloc_addr = alloc_addr; } static int provisioner_dev_find(const bt_mesh_addr_t *addr, const u8_t uuid[16], u16_t *index) @@ -611,7 +618,7 @@ static bool is_unprov_dev_being_provision(const u8_t uuid[16]) static bool is_unprov_dev_uuid_match(const u8_t uuid[16]) { - if (prov_ctx.match_length && prov_ctx.match_value) { + if (prov_ctx.match_length) { if (memcmp(uuid + prov_ctx.match_offset, prov_ctx.match_value, prov_ctx.match_length)) { return false; @@ -621,7 +628,7 @@ static bool is_unprov_dev_uuid_match(const u8_t uuid[16]) return true; } -static int provisioner_check_unprov_dev_info(const u8_t uuid[16]) +static int provisioner_check_unprov_dev_info(const u8_t uuid[16], bt_mesh_prov_bearer_t bearer) { if (!uuid) { BT_ERR("%s, Invalid parameter", __func__); @@ -630,7 +637,7 @@ static int provisioner_check_unprov_dev_info(const u8_t uuid[16]) /* Check if the device uuid matches configured value */ if (is_unprov_dev_uuid_match(uuid) == false) { - BT_DBG("%s, Device uuid is not matched", __func__); + BT_DBG("%s, Device uuid mismatch", __func__); return -EIO; } @@ -644,9 +651,16 @@ static int provisioner_check_unprov_dev_info(const u8_t uuid[16]) return -EALREADY; } - if (prov_ctx.current_addr == BLE_MESH_ADDR_UNASSIGNED) { - BT_WARN("No available unicast address to assign"); - return -EIO; + /* Check if the current PB-ADV link is full */ + if (bearer == BLE_MESH_PROV_ADV && prov_ctx.pba_count == CONFIG_BLE_MESH_PBA_SAME_TIME) { + BT_INFO("Current PB-ADV links reach max limit"); + return -ENOMEM; + } + + /* Check if the current PB-GATT link is full */ + if (bearer == BLE_MESH_PROV_GATT && prov_ctx.pbg_count == CONFIG_BLE_MESH_PBG_SAME_TIME) { + BT_INFO("Current PB-GATT links reach max limit"); + return -ENOMEM; } /* Check if the device has already been provisioned */ @@ -665,8 +679,8 @@ static int provisioner_check_unprov_dev_info(const u8_t uuid[16]) } #if defined(CONFIG_BLE_MESH_PB_ADV) -static int provisioner_start_prov_pb_adv(const u8_t uuid[16], - const bt_mesh_addr_t *addr, u16_t oob_info) +static int provisioner_start_prov_pb_adv(const u8_t uuid[16], const bt_mesh_addr_t *addr, + u16_t oob_info, u16_t assign_addr) { u8_t zero[6] = {0}; int addr_cmp; @@ -679,6 +693,15 @@ static int provisioner_start_prov_pb_adv(const u8_t uuid[16], bt_mesh_pb_adv_lock(); + /* If the unicast address of the node is going to be allocated internally, + * then we need to check if there are addresses can be allocated. + */ + if (assign_addr == BLE_MESH_ADDR_UNASSIGNED && + prov_ctx.curr_alloc_addr == BLE_MESH_ADDR_UNASSIGNED) { + BT_ERR("No available unicast address to assign"); + return -EIO; + } + if (is_unprov_dev_being_provision(uuid)) { bt_mesh_pb_adv_unlock(); return -EALREADY; @@ -695,6 +718,12 @@ static int provisioner_start_prov_pb_adv(const u8_t uuid[16], memcpy(link[i].addr.val, addr->val, BLE_MESH_ADDR_LEN); } send_link_open(i); + /* If the application layer assigned a specific unicast address for the device, + * then Provisioner will use this address in the Provisoning Data PDU. + */ + if (BLE_MESH_ADDR_IS_UNICAST(assign_addr)) { + link[i].assign_addr = assign_addr; + } bt_mesh_pb_adv_unlock(); return 0; } @@ -708,8 +737,8 @@ static int provisioner_start_prov_pb_adv(const u8_t uuid[16], #endif /* CONFIG_BLE_MESH_PB_ADV */ #if defined(CONFIG_BLE_MESH_PB_GATT) -static int provisioner_start_prov_pb_gatt(const u8_t uuid[16], - const bt_mesh_addr_t *addr, u16_t oob_info) +static int provisioner_start_prov_pb_gatt(const u8_t uuid[16], const bt_mesh_addr_t *addr, + u16_t oob_info, u16_t assign_addr) { u8_t zero[6] = {0}; int addr_cmp; @@ -722,6 +751,15 @@ static int provisioner_start_prov_pb_gatt(const u8_t uuid[16], bt_mesh_pb_gatt_lock(); + /* If the unicast address of the node is going to be allocated internally, + * then we need to check if there are addresses can be allocated. + */ + if (assign_addr == BLE_MESH_ADDR_UNASSIGNED && + prov_ctx.curr_alloc_addr == BLE_MESH_ADDR_UNASSIGNED) { + BT_ERR("No available unicast address to assign"); + return -EIO; + } + if (is_unprov_dev_being_provision(uuid)) { bt_mesh_pb_gatt_unlock(); return -EALREADY; @@ -744,6 +782,12 @@ static int provisioner_start_prov_pb_gatt(const u8_t uuid[16], bt_mesh_pb_gatt_unlock(); return -EIO; } + /* If the application layer assigned a specific unicast address for the device, + * then Provisioner will use this address in the Provisoning Data PDU. + */ + if (BLE_MESH_ADDR_IS_UNICAST(assign_addr)) { + link[i].assign_addr = assign_addr; + } /* If creating connection successfully, set connecting flag to 1 */ link[i].connecting = true; provisioner_pbg_count_inc(); @@ -874,33 +918,102 @@ 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_WARN("Node count + active link count reach max limit"); + BT_ERR("Node count + active link count reach max limit"); return -EIO; } - if ((err = provisioner_check_unprov_dev_info(add_dev->uuid))) { + if ((err = provisioner_check_unprov_dev_info(add_dev->uuid, add_dev->bearer))) { return err; } - if (add_dev->bearer & BLE_MESH_PROV_ADV) { + if (add_dev->bearer == BLE_MESH_PROV_ADV) { #if defined(CONFIG_BLE_MESH_PB_ADV) - if (prov_ctx.pba_count == CONFIG_BLE_MESH_PBA_SAME_TIME) { - BT_WARN("Current PB-ADV links reach max limit"); - return -EIO; - } if ((err = provisioner_start_prov_pb_adv( - add_dev->uuid, &add_addr, add_dev->oob_info))) { + add_dev->uuid, &add_addr, add_dev->oob_info, BLE_MESH_ADDR_UNASSIGNED))) { return err; } #endif - } else if (add_dev->bearer & BLE_MESH_PROV_GATT) { + } else if (add_dev->bearer == BLE_MESH_PROV_GATT) { #if defined(CONFIG_BLE_MESH_PB_GATT) - if (prov_ctx.pbg_count == CONFIG_BLE_MESH_PBG_SAME_TIME) { - BT_WARN("Current PB-GATT links reach max limit"); - return -EIO; - } if ((err = provisioner_start_prov_pb_gatt( - add_dev->uuid, &add_addr, add_dev->oob_info))) { + add_dev->uuid, &add_addr, add_dev->oob_info, BLE_MESH_ADDR_UNASSIGNED))) { + return err; + } +#endif + } + + return 0; +} + +int bt_mesh_provisioner_prov_device_with_addr(const u8_t uuid[16], const u8_t addr[6], + u8_t addr_type, bt_mesh_prov_bearer_t bearer, + u16_t oob_info, u16_t unicast_addr) +{ + bt_mesh_addr_t dev_addr = {0}; + int err; + + if (uuid == NULL) { + BT_ERR("%s, NULL device uuid", __func__); + return -EINVAL; + } + + if (bearer != BLE_MESH_PROV_ADV && bearer != BLE_MESH_PROV_GATT) { + BT_ERR("%s, Invalid provisioning bearer 0x%02x", __func__, bearer); + return -EINVAL; + } + + if (!IS_ENABLED(CONFIG_BLE_MESH_PB_ADV) && bearer == BLE_MESH_PROV_ADV) { + BT_ERR("%s, Not support PB-ADV", __func__); + return -ENOTSUP; + } + + if (!IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) && bearer == BLE_MESH_PROV_GATT) { + BT_ERR("%s, Not support PB-GATT", __func__); + return -ENOTSUP; + } + + if (addr == NULL || addr_type > BLE_MESH_ADDR_RANDOM) { + BT_ERR("%s, Invalid device address info", __func__); + return -EINVAL; + } + + if (!BLE_MESH_ADDR_IS_UNICAST(unicast_addr)) { + BT_ERR("%s, Invalid unicast address 0x%04x", __func__, unicast_addr); + return -EINVAL; + } + + /* Here we will not check if the assigned unicast address is overlapped + * with the unicast addresses of other nodes or Provisioner, beacuse: + * 1. At this moment, the element number of the device is unknown + * 2. If the node is a reprovisioned device, then the original allocated + * unicast address will be used. + * 3. Some other devices may be just being provisioning, and currently we + * 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 ((err = provisioner_check_unprov_dev_info(uuid, bearer))) { + return err; + } + + dev_addr.type = addr_type; + memcpy(dev_addr.val, addr, BLE_MESH_ADDR_LEN); + + if (bearer == BLE_MESH_PROV_ADV) { +#if defined(CONFIG_BLE_MESH_PB_ADV) + if ((err = provisioner_start_prov_pb_adv(uuid, &dev_addr, oob_info, unicast_addr))) { + return err; + } +#endif + } else if (bearer == BLE_MESH_PROV_GATT) { +#if defined(CONFIG_BLE_MESH_PB_GATT) + if ((err = provisioner_start_prov_pb_gatt(uuid, &dev_addr, oob_info, unicast_addr))) { return err; } #endif @@ -995,13 +1108,7 @@ int bt_mesh_provisioner_set_dev_uuid_match(u8_t offset, u8_t length, return -EINVAL; } - if (length && !prov_ctx.match_value) { - prov_ctx.match_value = osi_calloc(16); - if (!prov_ctx.match_value) { - BT_ERR("%s, Failed to allocate memory", __func__); - return -ENOMEM; - } - } + (void)memset(prov_ctx.match_value, 0, 16); prov_ctx.match_offset = offset; prov_ctx.match_length = length; @@ -1052,25 +1159,35 @@ int bt_mesh_provisioner_set_prov_info(void) { const struct bt_mesh_comp *comp = NULL; - if (!BLE_MESH_ADDR_IS_UNICAST(prov->prov_unicast_addr) || - !BLE_MESH_ADDR_IS_UNICAST(prov->prov_start_address)) { - BT_ERR("%s, Invalid address, own 0x%04x, start 0x%04x", - __func__, prov->prov_unicast_addr, prov->prov_start_address); - return -EINVAL; - } + if (prov_ctx.primary_addr == BLE_MESH_ADDR_UNASSIGNED) { + /* If unicast address of primary element of Provisioner has not been set + * before, then the following initilization procedure will be used. + */ + if (!BLE_MESH_ADDR_IS_UNICAST(prov->prov_unicast_addr) || + !BLE_MESH_ADDR_IS_UNICAST(prov->prov_start_address)) { + BT_ERR("%s, Invalid address, own 0x%04x, start 0x%04x", + __func__, prov->prov_unicast_addr, prov->prov_start_address); + return -EINVAL; + } - comp = bt_mesh_comp_get(); - if (!comp) { - BT_ERR("%s, NULL composition data", __func__); - return -EINVAL; - } + comp = bt_mesh_comp_get(); + if (!comp) { + BT_ERR("%s, NULL composition data", __func__); + return -EINVAL; + } - if (prov->prov_unicast_addr + comp->elem_count > prov->prov_start_address) { - BT_WARN("Too small start address 0x%04x, update to 0x%04x", - prov->prov_start_address, prov->prov_unicast_addr + comp->elem_count); - prov_ctx.current_addr = prov->prov_unicast_addr + comp->elem_count; - } else { - prov_ctx.current_addr = prov->prov_start_address; + if (prov->prov_unicast_addr + comp->elem_count > prov->prov_start_address) { + BT_WARN("Too small start address 0x%04x, update to 0x%04x", + prov->prov_start_address, prov->prov_unicast_addr + comp->elem_count); + prov_ctx.curr_alloc_addr = prov->prov_unicast_addr + comp->elem_count; + } else { + prov_ctx.curr_alloc_addr = prov->prov_start_address; + } + prov_ctx.primary_addr = prov->prov_unicast_addr; + + if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { + bt_mesh_store_prov_info(prov_ctx.primary_addr, prov_ctx.curr_alloc_addr); + } } prov_ctx.curr_net_idx = BLE_MESH_KEY_PRIMARY; prov_ctx.curr_flags = prov->flags; @@ -1079,6 +1196,20 @@ int bt_mesh_provisioner_set_prov_info(void) return 0; } +void bt_mesh_provisioner_set_prov_bearer(bt_mesh_prov_bearer_t bearers, bool clear) +{ + if (clear == false) { + prov_ctx.bearers |= bearers; + } else { + prov_ctx.bearers &= ~bearers; + } +} + +bt_mesh_prov_bearer_t bt_mesh_provisioner_get_prov_bearer(void) +{ + return prov_ctx.bearers; +} + int bt_mesh_provisioner_set_static_oob_value(const u8_t *value, u8_t length) { size_t i; @@ -1096,13 +1227,7 @@ int bt_mesh_provisioner_set_static_oob_value(const u8_t *value, u8_t length) } } - if (prov_ctx.static_oob_val == NULL) { - prov_ctx.static_oob_val = osi_calloc(16); - if (!prov_ctx.static_oob_val) { - BT_ERR("%s, Failed to allocate memory", __func__); - return -ENOMEM; - } - } + (void)memset(prov_ctx.static_oob_val, 0, 16); prov_ctx.static_oob_len = MIN(16, length); memcpy(prov_ctx.static_oob_val, value, prov_ctx.static_oob_len); @@ -1110,17 +1235,62 @@ int bt_mesh_provisioner_set_static_oob_value(const u8_t *value, u8_t length) return 0; } +u16_t bt_mesh_provisioner_get_primary_elem_addr(void) +{ + return prov_ctx.primary_addr; +} + +int bt_mesh_provisioner_set_primary_elem_addr(u16_t addr) +{ + const struct bt_mesh_comp *comp = NULL; + + if (!BLE_MESH_ADDR_IS_UNICAST(addr)) { + BT_ERR("Invalid primary address 0x%04x", addr); + return -EINVAL; + } + + comp = bt_mesh_comp_get(); + if (!comp) { + BT_ERR("NULL composition data"); + return -EINVAL; + } + + /* Make sure Provisioner address is not identical with the addresses of nodes */ + if (bt_mesh_provisioner_check_is_addr_dup(addr, comp->elem_count, false)) { + BT_ERR("Address 0x%04x is duplicated with node address", addr); + return -EINVAL; + } + + /* If the current can-be allocated address is bigger than primary address + + * element number, then the curr_alloc_addr will not be changed, and only + * the Provisioner related addresses will be updated. + */ + if (addr + comp->elem_count > prov_ctx.curr_alloc_addr) { + prov_ctx.curr_alloc_addr = addr + comp->elem_count; + } + BT_INFO("Provisioner primary address updated, old 0x%04x, new 0x%04x", prov_ctx.primary_addr, addr); + prov_ctx.primary_addr = addr; + + if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { + bt_mesh_store_prov_info(prov_ctx.primary_addr, prov_ctx.curr_alloc_addr); + } + + bt_mesh_comp_provision(addr); + + return 0; +} + /* The following APIs are for fast provisioning */ -void bt_mesh_provisioner_set_fast_prov_flag(bool flag) +void bt_mesh_provisioner_fast_prov_enable(bool enable) { - fast_prov_flag = flag; + prov_ctx.fast_prov.enable = enable; } u8_t bt_mesh_provisioner_set_fast_prov_net_idx(const u8_t *net_key, u16_t net_idx) { - fast_prov_info.net_idx = net_idx; - fast_prov_info.net_key = net_key; + prov_ctx.fast_prov.net_idx = net_idx; + prov_ctx.fast_prov.net_key = net_key; if (!net_key) { BT_WARN("Wait for NetKey for fast provisioning"); @@ -1132,7 +1302,7 @@ u8_t bt_mesh_provisioner_set_fast_prov_net_idx(const u8_t *net_key, u16_t net_id u16_t bt_mesh_provisioner_get_fast_prov_net_idx(void) { - return fast_prov_info.net_idx; + return prov_ctx.fast_prov.net_idx; } u8_t bt_mesh_set_fast_prov_unicast_addr_range(u16_t min, u16_t max) @@ -1147,15 +1317,15 @@ u8_t bt_mesh_set_fast_prov_unicast_addr_range(u16_t min, u16_t max) return 0x02; /* status: min is bigger than max */ } - if (min <= fast_prov_info.unicast_addr_max) { + if (min <= prov_ctx.fast_prov.unicast_addr_max) { BT_ERR("%s, Address overlap", __func__); return 0x03; /* status: address overlaps with current value */ } - fast_prov_info.unicast_addr_min = min; - fast_prov_info.unicast_addr_max = max; + prov_ctx.fast_prov.unicast_addr_min = min; + prov_ctx.fast_prov.unicast_addr_max = max; - prov_ctx.current_addr = fast_prov_info.unicast_addr_min; + prov_ctx.curr_alloc_addr = prov_ctx.fast_prov.unicast_addr_min; return 0x0; /* status: success */ } @@ -1163,8 +1333,8 @@ u8_t bt_mesh_set_fast_prov_unicast_addr_range(u16_t min, u16_t max) void bt_mesh_set_fast_prov_flags_iv_index(u8_t flags, u32_t iv_index) { /* BIT0: Key Refreash flag, BIT1: IV Update flag */ - fast_prov_info.flags = flags & BIT_MASK(2); - fast_prov_info.iv_index = iv_index; + prov_ctx.fast_prov.flags = flags & BIT_MASK(2); + prov_ctx.fast_prov.iv_index = iv_index; } #if defined(CONFIG_BLE_MESH_PB_ADV) @@ -1643,7 +1813,7 @@ static void prov_capabilities(const u8_t idx, const u8_t *data) u8_t auth_method, auth_action, auth_size; element_num = data[0]; - BT_DBG("Elements: %u", element_num); + BT_INFO("Elements: %u", element_num); if (!element_num) { BT_ERR("%s, Invalid element number", __func__); goto fail; @@ -1651,14 +1821,14 @@ static void prov_capabilities(const u8_t idx, const u8_t *data) link[idx].element_num = element_num; algorithms = sys_get_be16(&data[1]); - BT_DBG("Algorithms: %u", algorithms); + BT_INFO("Algorithms: %u", algorithms); if (algorithms != BIT(PROV_ALG_P256)) { BT_ERR("%s, Invalid algorithms", __func__); goto fail; } pub_key_oob = data[3]; - BT_DBG("Public Key Type: 0x%02x", pub_key_oob); + BT_INFO("Public Key Type: 0x%02x", pub_key_oob); if (pub_key_oob > 0x01) { BT_ERR("%s, Invalid public key type", __func__); goto fail; @@ -1667,22 +1837,22 @@ static void prov_capabilities(const u8_t idx, const u8_t *data) prov->prov_pub_key_oob_cb) ? pub_key_oob : 0x00); static_oob = data[4]; - BT_DBG("Static OOB Type: 0x%02x", static_oob); + BT_INFO("Static OOB Type: 0x%02x", static_oob); if (static_oob > 0x01) { BT_ERR("%s, Invalid Static OOB type", __func__); goto fail; } - static_oob = (prov_ctx.static_oob_val ? static_oob : 0x00); + static_oob = (prov_ctx.static_oob_len ? static_oob : 0x00); output_size = data[5]; - BT_DBG("Output OOB Size: %u", output_size); + BT_INFO("Output OOB Size: %u", output_size); if (output_size > 0x08) { BT_ERR("%s, Invalid Output OOB size", __func__); goto fail; } output_action = sys_get_be16(&data[6]); - BT_DBG("Output OOB Action: 0x%04x", output_action); + BT_INFO("Output OOB Action: 0x%04x", output_action); if (output_action > 0x1f) { BT_ERR("%s, Invalid Output OOB action", __func__); goto fail; @@ -1697,14 +1867,14 @@ static void prov_capabilities(const u8_t idx, const u8_t *data) } input_size = data[8]; - BT_DBG("Input OOB Size: %u", input_size); + BT_INFO("Input OOB Size: %u", input_size); if (input_size > 0x08) { BT_ERR("%s, Invalid Input OOB size", __func__); goto fail; } input_action = sys_get_be16(&data[9]); - BT_DBG("Input OOB Action: 0x%04x", input_action); + BT_INFO("Input OOB Action: 0x%04x", input_action); if (input_action > 0x0f) { BT_ERR("%s, Invalid Input OOB action", __func__); goto fail; @@ -2003,6 +2173,8 @@ int bt_mesh_provisioner_set_oob_input_data(const u8_t idx, const u8_t *val, bool return -EINVAL; } + BT_INFO("Link idx %d, type %s", idx, num_flag ? "number" : "string"); + memset(link[idx].auth, 0, 16); if (num_flag) { /* Provisioner inputs number */ @@ -2032,6 +2204,8 @@ int bt_mesh_provisioner_set_oob_output_data(const u8_t idx, const u8_t *num, u8_ return -EINVAL; } + BT_INFO("Link idx %d, type %s", idx, num_flag ? "number" : "string"); + if (num_flag) { /* Provisioner output number */ memset(link[idx].auth, 0, 16); @@ -2298,16 +2472,16 @@ static void send_prov_data(const u8_t idx) * will be added to the primary subnet, and may add an API to choose to which * subnet will the device be provisioned later. */ - if (FAST_PROV_FLAG_GET()) { - netkey = fast_prov_info.net_key; + if (FAST_PROV_ENABLE()) { + netkey = prov_ctx.fast_prov.net_key; if (!netkey) { BT_ERR("%s, Failed to get NetKey for fast provisioning", __func__); goto fail; } memcpy(pdu, netkey, 16); - sys_put_be16(fast_prov_info.net_idx, &pdu[16]); - pdu[18] = fast_prov_info.flags; - sys_put_be32(fast_prov_info.iv_index, &pdu[19]); + sys_put_be16(prov_ctx.fast_prov.net_idx, &pdu[16]); + pdu[18] = prov_ctx.fast_prov.flags; + sys_put_be32(prov_ctx.fast_prov.iv_index, &pdu[19]); } else { netkey = bt_mesh_provisioner_net_key_get(prov_ctx.curr_net_idx); if (!netkey) { @@ -2341,25 +2515,44 @@ static void send_prov_data(const u8_t idx) bt_mesh_provisioner_remove_node(link[idx].uuid); } - max_addr = FAST_PROV_FLAG_GET() ? fast_prov_info.unicast_addr_max : PROV_MAX_ADDR_TO_ASSIGN; + max_addr = FAST_PROV_ENABLE() ? prov_ctx.fast_prov.unicast_addr_max : PROV_MAX_ADDR_TO_ASSIGN; if (BLE_MESH_ADDR_IS_UNICAST(prev_addr)) { sys_put_be16(prev_addr, &pdu[23]); link[idx].unicast_addr = prev_addr; } else { - /* If this device to be provisioned is a new device */ - if (prov_ctx.current_addr == BLE_MESH_ADDR_UNASSIGNED) { - BT_ERR("%s, No unicast address can be assigned", __func__); - goto fail; - } + 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; + } - if (prov_ctx.current_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. 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(prov_ctx.current_addr, &pdu[23]); - link[idx].unicast_addr = prov_ctx.current_addr; + sys_put_be16(link[idx].assign_addr, &pdu[23]); + link[idx].unicast_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; + } } prov_buf_init(&buf, PROV_DATA); @@ -2376,27 +2569,39 @@ static void send_prov_data(const u8_t idx) } /** - * We update the next unicast address to be assigned here because if + * We update the next unicast address to be allocated here because if * Provisioner is provisioning two devices at the same time, we need * to assign the unicast address for them correctly. Hence we should - * not update the prov_ctx.current_addr after the proper provisioning + * not update the prov_ctx.curr_alloc_addr after the proper provisioning * complete pdu is received. */ if (!BLE_MESH_ADDR_IS_UNICAST(prev_addr)) { - prov_ctx.current_addr += link[idx].element_num; - if (prov_ctx.current_addr > max_addr) { - /* No unicast address will be used for further provisioning */ - prov_ctx.current_addr = BLE_MESH_ADDR_UNASSIGNED; + if (BLE_MESH_ADDR_IS_UNICAST(link[idx].assign_addr)) { + /* Even if the unicast address of the node is assigned by the + * application, we will also update the prov_ctx.curr_alloc_addr + * here, in case Users use the two methods together (i.e. allocate + * the unicast address for the node internally and assign the + * unicast address for the node from application). + */ + if (prov_ctx.curr_alloc_addr < link[idx].assign_addr + link[idx].element_num) { + prov_ctx.curr_alloc_addr = link[idx].assign_addr + link[idx].element_num; + } + } else { + prov_ctx.curr_alloc_addr += link[idx].element_num; + if (prov_ctx.curr_alloc_addr > max_addr) { + /* No unicast address will be used for further provisioning */ + prov_ctx.curr_alloc_addr = BLE_MESH_ADDR_UNASSIGNED; + } } /* Store the available unicast address range to flash */ if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { - bt_mesh_store_prov_info(prov_ctx.current_addr); + bt_mesh_store_prov_info(prov_ctx.primary_addr, prov_ctx.curr_alloc_addr); } } - if (FAST_PROV_FLAG_GET()) { - link[idx].ki_flags = fast_prov_info.flags; - link[idx].iv_index = fast_prov_info.iv_index; + if (FAST_PROV_ENABLE()) { + link[idx].ki_flags = prov_ctx.fast_prov.flags; + link[idx].iv_index = prov_ctx.fast_prov.iv_index; } else { link[idx].ki_flags = prov_ctx.curr_flags; link[idx].iv_index = prov_ctx.curr_iv_index; @@ -2482,8 +2687,8 @@ static void prov_complete(const u8_t idx, const u8_t *data) return; } - if (FAST_PROV_FLAG_GET()) { - net_idx = fast_prov_info.net_idx; + if (FAST_PROV_ENABLE()) { + net_idx = prov_ctx.fast_prov.net_idx; } else { net_idx = prov_ctx.curr_net_idx; } @@ -2568,7 +2773,7 @@ static void prov_timeout(struct k_work *work) { u8_t idx = (u8_t)work->index; - BT_DBG("%s", __func__); + BT_WARN("%s", __func__); close_link(idx, CLOSE_REASON_TIMEOUT); } @@ -3139,12 +3344,9 @@ int bt_mesh_provisioner_prov_init(const struct bt_mesh_prov *prov_info) prov = prov_info; + prov_ctx.primary_addr = BLE_MESH_ADDR_UNASSIGNED; + if (prov->prov_static_oob_val && prov->prov_static_oob_len) { - prov_ctx.static_oob_val = osi_calloc(16); - if (!prov_ctx.static_oob_val) { - BT_ERR("%s, Failed to allocate memory", __func__); - return -ENOMEM; - } prov_ctx.static_oob_len = MIN(16, prov->prov_static_oob_len); memcpy(prov_ctx.static_oob_val, prov->prov_static_oob_val, prov_ctx.static_oob_len); } @@ -3206,14 +3408,6 @@ int bt_mesh_provisioner_prov_deinit(void) memset(&link[i], 0, sizeof(link[i])); } - if (prov_ctx.static_oob_val) { - osi_free(prov_ctx.static_oob_val); - prov_ctx.static_oob_val = NULL; - } - if (prov_ctx.match_value) { - osi_free(prov_ctx.match_value); - prov_ctx.match_value = NULL; - } #if defined(CONFIG_BLE_MESH_PB_ADV) bt_mesh_pb_adv_mutex_free(); bt_mesh_pb_buf_mutex_free(); @@ -3223,13 +3417,19 @@ int bt_mesh_provisioner_prov_deinit(void) #endif memset(&prov_ctx, 0, sizeof(prov_ctx)); +#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)); + prov = NULL; return 0; } static bool is_unprov_dev_info_callback_to_app(bt_mesh_prov_bearer_t bearer, - const u8_t uuid[16], const bt_mesh_addr_t *addr, u16_t oob_info) + const u8_t uuid[16], const bt_mesh_addr_t *addr, u16_t oob_info, s8_t rssi) { u16_t index; @@ -3240,7 +3440,7 @@ static bool is_unprov_dev_info_callback_to_app(bt_mesh_prov_bearer_t bearer, if (provisioner_dev_find(addr, uuid, &index)) { BT_DBG("%s, Device is not in queue, notify to upper layer", __func__); if (notify_unprov_adv_pkt_cb) { - notify_unprov_adv_pkt_cb(addr->val, addr->type, adv_type, uuid, oob_info, bearer); + notify_unprov_adv_pkt_cb(addr->val, addr->type, adv_type, uuid, oob_info, bearer, rssi); } return true; } @@ -3249,7 +3449,7 @@ static bool is_unprov_dev_info_callback_to_app(bt_mesh_prov_bearer_t bearer, BT_WARN("Device in queue not support PB-%s", (bearer == BLE_MESH_PROV_ADV) ? "ADV" : "GATT"); if (notify_unprov_adv_pkt_cb) { - notify_unprov_adv_pkt_cb(addr->val, addr->type, adv_type, uuid, oob_info, bearer); + notify_unprov_adv_pkt_cb(addr->val, addr->type, adv_type, uuid, oob_info, bearer, rssi); } return true; } @@ -3258,20 +3458,20 @@ static bool is_unprov_dev_info_callback_to_app(bt_mesh_prov_bearer_t bearer, return false; } -void bt_mesh_provisioner_unprov_beacon_recv(struct net_buf_simple *buf) +void bt_mesh_provisioner_unprov_beacon_recv(struct net_buf_simple *buf, s8_t rssi) { #if defined(CONFIG_BLE_MESH_PB_ADV) const bt_mesh_addr_t *addr = NULL; const u8_t *uuid = NULL; u16_t oob_info; - if (buf->len != 0x12 && buf->len != 0x16) { - BT_ERR("%s, Invalid Unprovisioned Device Beacon length", __func__); + if (!(prov_ctx.bearers & BLE_MESH_PROV_ADV)) { + BT_WARN("Provisioner not support PB-ADV bearer"); return; } - if (prov_ctx.pba_count == CONFIG_BLE_MESH_PBA_SAME_TIME) { - BT_DBG("Current PB-ADV devices reach max limit"); + if (buf->len != 0x12 && buf->len != 0x16) { + BT_ERR("%s, Invalid Unprovisioned Device Beacon length", __func__); return; } @@ -3281,32 +3481,32 @@ void bt_mesh_provisioner_unprov_beacon_recv(struct net_buf_simple *buf) /* Mesh beacon uses big-endian to send beacon data */ oob_info = net_buf_simple_pull_be16(buf); - if (provisioner_check_unprov_dev_info(uuid)) { + if (provisioner_check_unprov_dev_info(uuid, BLE_MESH_PROV_ADV)) { return; } if (is_unprov_dev_info_callback_to_app( - BLE_MESH_PROV_ADV, uuid, addr, oob_info)) { + BLE_MESH_PROV_ADV, uuid, addr, oob_info, rssi)) { return; } - provisioner_start_prov_pb_adv(uuid, addr, oob_info); + provisioner_start_prov_pb_adv(uuid, addr, oob_info, BLE_MESH_ADDR_UNASSIGNED); #endif /* CONFIG_BLE_MESH_PB_ADV */ } -void bt_mesh_provisioner_prov_adv_ind_recv(struct net_buf_simple *buf, const bt_mesh_addr_t *addr) +void bt_mesh_provisioner_prov_adv_ind_recv(struct net_buf_simple *buf, const bt_mesh_addr_t *addr, s8_t rssi) { #if defined(CONFIG_BLE_MESH_PB_GATT) const u8_t *uuid = NULL; u16_t oob_info; - if (prov_ctx.pbg_count == CONFIG_BLE_MESH_PBG_SAME_TIME) { - BT_DBG("Current PB-GATT devices reach max limit"); + if (!(prov_ctx.bearers & BLE_MESH_PROV_GATT)) { + BT_WARN("Provisioner not support PB-GATT bearer"); return; } if (bt_mesh_gattc_get_free_conn_count() == 0) { - BT_WARN("BLE connections for mesh reach max limit"); + BT_INFO("BLE connections for mesh reach max limit"); return; } @@ -3315,12 +3515,12 @@ void bt_mesh_provisioner_prov_adv_ind_recv(struct net_buf_simple *buf, const bt_ /* Mesh beacon uses big-endian to send beacon data */ oob_info = net_buf_simple_pull_be16(buf); - if (provisioner_check_unprov_dev_info(uuid)) { + if (provisioner_check_unprov_dev_info(uuid, BLE_MESH_PROV_GATT)) { return; } if (is_unprov_dev_info_callback_to_app( - BLE_MESH_PROV_GATT, uuid, addr, oob_info)) { + BLE_MESH_PROV_GATT, uuid, addr, oob_info, rssi)) { return; } @@ -3336,7 +3536,7 @@ void bt_mesh_provisioner_prov_adv_ind_recv(struct net_buf_simple *buf, const bt_ * Use connecting flag to prevent if two devices's adv pkts are both received, * the previous one info will be replaced by the second one. */ - provisioner_start_prov_pb_gatt(uuid, addr, oob_info); + provisioner_start_prov_pb_gatt(uuid, addr, oob_info, BLE_MESH_ADDR_UNASSIGNED); #endif /* CONFIG_BLE_MESH_PB_GATT */ } diff --git a/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.h b/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.h index b819fc2dec..1d532e2eb3 100644 --- a/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.h +++ b/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.h @@ -160,13 +160,14 @@ int bt_mesh_provisioner_prov_deinit(void); * beacon advertising packets, and if checked, starts to provision this device * using PB-ADV bearer. * - * @param[in] buf: Pointer to the buffer containing unprovisioned device beacon + * @param[in] buf: Pointer to the buffer containing unprovisioned device beacon + * @param[in] rssi: RSSI of the received unprovisioned device beacon * * @return None */ -void bt_mesh_provisioner_unprov_beacon_recv(struct net_buf_simple *buf); +void bt_mesh_provisioner_unprov_beacon_recv(struct net_buf_simple *buf, s8_t rssi); -void bt_mesh_provisioner_prov_adv_ind_recv(struct net_buf_simple *buf, const bt_mesh_addr_t *addr); +void bt_mesh_provisioner_prov_adv_ind_recv(struct net_buf_simple *buf, const bt_mesh_addr_t *addr, s8_t rssi); /** * @brief This function gets the bt_mesh_prov pointer. @@ -175,7 +176,7 @@ void bt_mesh_provisioner_prov_adv_ind_recv(struct net_buf_simple *buf, const bt_ */ const struct bt_mesh_prov *bt_mesh_provisioner_get_prov_info(void); -void bt_mesh_provisoner_restore_prov_info(u16_t addr); +void bt_mesh_provisoner_restore_prov_info(u16_t primary_addr, u16_t alloc_addr); /* The following APIs are for primary provisioner application use */ @@ -189,7 +190,7 @@ void bt_mesh_provisoner_restore_prov_info(u16_t addr); * * @return Zero on success or (negative) error code otherwise. * - * @Note: 1. Currently address type only supports public address and static random address. + * @note 1. Currently address type only supports public address and static random address. * 2. If device UUID and/or device address and address type already exist in the * device queue, but the bearer differs from the existing one, add operation * will also be successful and it will update the provision bearer supported by @@ -197,6 +198,24 @@ void bt_mesh_provisoner_restore_prov_info(u16_t addr); */ int bt_mesh_provisioner_add_unprov_dev(struct bt_mesh_unprov_dev_add *add_dev, u8_t flags); +/** @brief Provision an unprovisioned device with fixed unicast address. + * + * @param[in] uuid: Device UUID of the unprovisioned device + * @param[in] addr: Device address of the unprovisioned device + * @param[in] addr_type: Device address type of the unprovisioned device + * @param[in] bearer: Provisioning bearer going to be used + * @param[in] oob_info: OOB info of the unprovisioned device + * @param[in] unicast_addr: Unicast address going to be allocated for the unprovisioned device + * + * @return Zero on success or (negative) error code otherwise. + * + * @note 1. Currently address type only supports public address and static random address. + * 2. Bearer must be equal to BLE_MESH_PROV_ADV or BLE_MESH_PROV_GATT + */ +int bt_mesh_provisioner_prov_device_with_addr(const u8_t uuid[16], const u8_t addr[6], + u8_t addr_type, bt_mesh_prov_bearer_t bearer, + u16_t oob_info, u16_t unicast_addr); + /** @brief Delete device from queue, reset current provisioning link and reset the node * * @param[in] del_dev: Pointer to the structure containing the device information @@ -232,11 +251,12 @@ int bt_mesh_provisioner_set_dev_uuid_match(u8_t offset, u8_t length, * @param adv_type Adv packet type, currently this is not used and we can use bearer to device * the adv_type(ADV_IND or ADV_NONCONN_IND). This parameter will be used, when * scan response data will be supported. + * @param rssi RSSI of the received advertising packet * */ typedef void (*unprov_adv_pkt_cb_t)(const u8_t addr[6], const u8_t addr_type, const u8_t adv_type, const u8_t dev_uuid[16], - u16_t oob_info, bt_mesh_prov_bearer_t bearer); + u16_t oob_info, bt_mesh_prov_bearer_t bearer, s8_t rssi); /** * @brief This function registers the callback which notifies the application @@ -266,6 +286,23 @@ int bt_mesh_provisioner_set_prov_data_info(struct bt_mesh_prov_data_info *info); */ int bt_mesh_provisioner_set_prov_info(void); +/** + * @brief This function sets the provisioning bearer type used by Provisioner. + * + * @param[in] bearers: Provisioning bearer type + * @param[in] clear: Indicate if the corresponding bearer type will be cleared + * + * @return None + */ +void bt_mesh_provisioner_set_prov_bearer(bt_mesh_prov_bearer_t bearers, bool clear); + +/** + * @brief This function gets the provisioning bearer type used by Provisioner. + * + * @return Currently supported provisioning bearer type + */ +bt_mesh_prov_bearer_t bt_mesh_provisioner_get_prov_bearer(void); + /** * @brief This function sets the Static OOB value used by Provisioner. * @@ -276,6 +313,22 @@ int bt_mesh_provisioner_set_prov_info(void); */ int bt_mesh_provisioner_set_static_oob_value(const u8_t *value, u8_t length); +/** + * @brief This function gets the unicast address of primary element of Provisioner. + * + * @return Unicast address of primary element of Provisioner. + */ +u16_t bt_mesh_provisioner_get_primary_elem_addr(void); + +/** + * @brief This function sets the unicast address of primary element of Provisioner. + * + * @param[in] addr: unicast address of primary element + * + * @return Zero - success, otherwise - fail + */ +int bt_mesh_provisioner_set_primary_elem_addr(u16_t addr); + /** * @brief This function is called to input number/string out-put by unprovisioned device. * @@ -315,11 +368,11 @@ int bt_mesh_provisioner_read_oob_pub_key(const u8_t idx, const u8_t pub_key_x[32 /** * @brief This function is called to set fast_prov_flag. * - * @param[in] flag: Flag set to fast_prov_flag + * @param[in] enable: Enable or disable fast provisioning * * @return None */ -void bt_mesh_provisioner_set_fast_prov_flag(bool flag); +void bt_mesh_provisioner_fast_prov_enable(bool enable); /** * @brief This function is called to set netkey index used for fast provisioning. diff --git a/components/bt/esp_ble_mesh/mesh_core/proxy_client.c b/components/bt/esp_ble_mesh/mesh_core/proxy_client.c index 2f6a66096b..737eb81d80 100644 --- a/components/bt/esp_ble_mesh/mesh_core/proxy_client.c +++ b/components/bt/esp_ble_mesh/mesh_core/proxy_client.c @@ -26,9 +26,8 @@ #include "access.h" #include "beacon.h" #include "foundation.h" -#include "provisioner_prov.h" #include "proxy_client.h" -#include "provisioner_beacon.h" +#include "provisioner_prov.h" #include "provisioner_main.h" #define PDU_TYPE(data) (data[0] & BIT_MASK(6)) @@ -82,7 +81,7 @@ static void proxy_sar_timeout(struct k_work *work) { struct bt_mesh_proxy_server *server = NULL; - BT_DBG("%s", __func__); + BT_WARN("%s", __func__); server = CONTAINER_OF(work, struct bt_mesh_proxy_server, sar_timer.work); if (!server || !server->conn) { @@ -144,7 +143,7 @@ static void filter_status(struct bt_mesh_proxy_server *server, list_size = net_buf_simple_pull_be16(buf); - BT_DBG("%s, filter_type 0x%02x list_size %d", __func__, filter_type, list_size); + BT_INFO("%s, filter_type 0x%02x list_size %d", __func__, filter_type, list_size); if (proxy_client_filter_status_recv_cb) { proxy_client_filter_status_recv_cb(server - servers, rx->ctx.addr, server->net_idx, filter_type, list_size); @@ -205,15 +204,7 @@ static void proxy_complete_pdu(struct bt_mesh_proxy_server *server) break; case BLE_MESH_PROXY_BEACON: BT_DBG("Mesh Beacon PDU"); - if (bt_mesh_is_provisioner_en()) { -#if CONFIG_BLE_MESH_PROVISIONER - bt_mesh_provisioner_beacon_recv(&server->buf); -#endif - } else { -#if CONFIG_BLE_MESH_NODE - bt_mesh_beacon_recv(&server->buf); -#endif - } + bt_mesh_beacon_recv(&server->buf, 0); break; case BLE_MESH_PROXY_CONFIG: BT_DBG("Mesh Configuration PDU"); @@ -659,14 +650,14 @@ static struct bt_mesh_subnet *bt_mesh_is_net_id_exist(const u8_t net_id[8]) return NULL; } -void bt_mesh_proxy_client_adv_ind_recv(struct net_buf_simple *buf, const bt_mesh_addr_t *addr) +void bt_mesh_proxy_client_adv_ind_recv(struct net_buf_simple *buf, const bt_mesh_addr_t *addr, s8_t rssi) { bt_mesh_proxy_adv_ctx_t ctx = {0}; u8_t type; /* Check if connection reaches the maximum limitation */ if (bt_mesh_gattc_get_free_conn_count() == 0) { - BT_WARN("%s, max connections", __func__); + BT_INFO("BLE connections for mesh reach max limit"); return; } @@ -697,7 +688,7 @@ void bt_mesh_proxy_client_adv_ind_recv(struct net_buf_simple *buf, const bt_mesh } if (proxy_client_adv_recv_cb) { - proxy_client_adv_recv_cb(addr, type, &ctx); + proxy_client_adv_recv_cb(addr, type, &ctx, rssi); } } @@ -751,8 +742,6 @@ bool bt_mesh_proxy_client_send(struct net_buf_simple *buf, u16_t dst) int err; u8_t i; - BT_DBG("%u bytes to dst 0x%04x", buf->len, dst); - for (i = 0U; i < ARRAY_SIZE(servers); i++) { struct bt_mesh_proxy_server *server = &servers[i]; NET_BUF_SIMPLE_DEFINE(msg, 32); @@ -771,6 +760,7 @@ bool bt_mesh_proxy_client_send(struct net_buf_simple *buf, u16_t dst) if (err) { BT_ERR("%s, Failed to send proxy net message (err %d)", __func__, err); } else { + BT_INFO("%u bytes to dst 0x%04x", buf->len, dst); send = true; } } @@ -796,22 +786,18 @@ bool bt_mesh_proxy_client_beacon_send(struct bt_mesh_subnet *sub) /* NULL means we send Secure Network Beacon on all subnets */ if (!sub) { - if (bt_mesh_is_provisioner_en()) { -#if CONFIG_BLE_MESH_PROVISIONER - for (i = 0U; i < ARRAY_SIZE(bt_mesh.p_sub); i++) { - if (bt_mesh.p_sub[i] && bt_mesh.p_sub[i]->net_idx != BLE_MESH_KEY_UNUSED) { - send = bt_mesh_proxy_client_beacon_send(bt_mesh.p_sub[i]); - } - } -#endif - } else { -#if CONFIG_BLE_MESH_NODE + if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) { for (i = 0U; i < ARRAY_SIZE(bt_mesh.sub); i++) { if (bt_mesh.sub[i].net_idx != BLE_MESH_KEY_UNUSED) { send = bt_mesh_proxy_client_beacon_send(&bt_mesh.sub[i]); } } -#endif + } else if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) && bt_mesh_is_provisioner_en()) { + for (i = 0U; i < ARRAY_SIZE(bt_mesh.p_sub); i++) { + if (bt_mesh.p_sub[i] && bt_mesh.p_sub[i]->net_idx != BLE_MESH_KEY_UNUSED) { + send = bt_mesh_proxy_client_beacon_send(bt_mesh.p_sub[i]); + } + } } return send; @@ -847,14 +833,10 @@ static int send_proxy_cfg(struct bt_mesh_conn *conn, u16_t net_idx, struct bt_me u16_t alloc_len; int err; - if (bt_mesh_is_provisioner_en()) { -#if CONFIG_BLE_MESH_PROVISIONER - tx.sub = bt_mesh_provisioner_subnet_get(net_idx); -#endif - } else { -#if CONFIG_BLE_MESH_NODE + if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) { tx.sub = bt_mesh_subnet_get(net_idx); -#endif + } else if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) && bt_mesh_is_provisioner_en()) { + tx.sub = bt_mesh_provisioner_subnet_get(net_idx); } if (!tx.sub) { BT_ERR("%s, Failed to find subnet", __func__); diff --git a/components/bt/esp_ble_mesh/mesh_core/proxy_client.h b/components/bt/esp_ble_mesh/mesh_core/proxy_client.h index d3a1efaf10..43ad270f5f 100644 --- a/components/bt/esp_ble_mesh/mesh_core/proxy_client.h +++ b/components/bt/esp_ble_mesh/mesh_core/proxy_client.h @@ -78,7 +78,7 @@ int bt_mesh_provisioner_pb_gatt_disable(void); int bt_mesh_proxy_client_enable(void); int bt_mesh_proxy_client_disable(void); -typedef void (*proxy_client_recv_adv_cb_t)(const bt_mesh_addr_t *addr, u8_t type, bt_mesh_proxy_adv_ctx_t *ctx); +typedef void (*proxy_client_recv_adv_cb_t)(const bt_mesh_addr_t *addr, u8_t type, bt_mesh_proxy_adv_ctx_t *ctx, s8_t rssi); typedef void (*proxy_client_connect_cb_t)(const bt_mesh_addr_t *addr, u8_t conn_handle, u16_t net_idx); typedef void (*proxy_client_disconnect_cb_t)(const bt_mesh_addr_t *addr, u8_t conn_handle, u16_t net_idx, u8_t reason); typedef void (*proxy_client_recv_filter_status_cb_t)(u8_t conn_handle, u16_t src, u16_t net_idx, u8_t filter_type, u16_t list_size); @@ -88,7 +88,7 @@ void bt_mesh_proxy_client_set_conn_cb(proxy_client_connect_cb_t cb); void bt_mesh_proxy_client_set_disconn_cb(proxy_client_disconnect_cb_t cb); void bt_mesh_proxy_client_set_filter_status_cb(proxy_client_recv_filter_status_cb_t cb); -void bt_mesh_proxy_client_adv_ind_recv(struct net_buf_simple *buf, const bt_mesh_addr_t *addr); +void bt_mesh_proxy_client_adv_ind_recv(struct net_buf_simple *buf, const bt_mesh_addr_t *addr, s8_t rssi); int bt_mesh_proxy_client_connect(const u8_t addr[6], u8_t addr_type, u16_t net_idx); int bt_mesh_proxy_client_disconnect(u8_t conn_handle); diff --git a/components/bt/esp_ble_mesh/mesh_core/proxy_server.c b/components/bt/esp_ble_mesh/mesh_core/proxy_server.c index f5b692f0a0..fc4fc29942 100644 --- a/components/bt/esp_ble_mesh/mesh_core/proxy_server.c +++ b/components/bt/esp_ble_mesh/mesh_core/proxy_server.c @@ -452,7 +452,7 @@ static void proxy_complete_pdu(struct bt_mesh_proxy_client *client) break; case BLE_MESH_PROXY_BEACON: BT_DBG("Mesh Beacon PDU"); - bt_mesh_beacon_recv(&client->buf); + bt_mesh_beacon_recv(&client->buf, 0); break; case BLE_MESH_PROXY_CONFIG: BT_DBG("Mesh Configuration PDU"); @@ -905,7 +905,7 @@ void bt_mesh_proxy_addr_add(struct net_buf_simple *buf, u16_t addr) struct bt_mesh_proxy_client *client = CONTAINER_OF(buf, struct bt_mesh_proxy_client, buf); - BT_DBG("filter_type %u addr 0x%04x", client->filter_type, addr); + BT_INFO("filter_type %u addr 0x%04x", client->filter_type, addr); if (client->filter_type == WHITELIST) { filter_add(client, addr); diff --git a/components/bt/esp_ble_mesh/mesh_core/settings.c b/components/bt/esp_ble_mesh/mesh_core/settings.c index 4ebd221e0b..5035111baa 100644 --- a/components/bt/esp_ble_mesh/mesh_core/settings.c +++ b/components/bt/esp_ble_mesh/mesh_core/settings.c @@ -161,16 +161,12 @@ static struct { struct cfg_val cfg; } stored_cfg; -struct node_update { - bt_mesh_addr_t addr; /* Device address */ - u8_t dev_uuid[16]; /* Device UUID */ - u16_t oob_info; /* Node OOB information */ - u16_t unicast_addr; /* Node unicast address */ - u8_t element_num; /* Node element number */ - u8_t dev_key[16]; /* Node device key */ -} __packed; +struct prov_info { + u16_t primary_addr; + u16_t alloc_addr; +}; -static u8_t dev_role = ROLE_NVAL; +#define DEVICE_ROLE_BITS (BIT(BLE_MESH_NODE) | BIT(BLE_MESH_PROVISIONER)) static int role_set(const char *name) { @@ -179,7 +175,7 @@ static int role_set(const char *name) BT_DBG("%s", __func__); - err = bt_mesh_load_core_settings(name, (u8_t *)&dev_role, sizeof(dev_role), &exist); + err = bt_mesh_load_core_settings(name, (u8_t *)bt_mesh.flags, sizeof(bt_mesh.flags), &exist); if (err) { return err; } @@ -188,7 +184,7 @@ static int role_set(const char *name) return 0; } - BT_DBG("Device role 0x%02x", dev_role); + BT_INFO("Restored mesh device role %lu", bt_mesh_atomic_get(bt_mesh.flags) & DEVICE_ROLE_BITS); return 0; } @@ -216,8 +212,8 @@ static int net_set(const char *name) memcpy(bt_mesh.dev_key, net.dev_key, sizeof(bt_mesh.dev_key)); bt_mesh_comp_provision(net.primary_addr); - BT_DBG("Provisioned with primary address 0x%04x", net.primary_addr); - BT_DBG("Recovered DevKey %s", bt_hex(bt_mesh.dev_key, 16)); + BT_INFO("Restored primary address 0x%04x", net.primary_addr); + BT_INFO("Restored DevKey %s", bt_hex(bt_mesh.dev_key, 16)); return 0; } @@ -246,7 +242,7 @@ static int iv_set(const char *name) bt_mesh_atomic_set_bit_to(bt_mesh.flags, BLE_MESH_IVU_IN_PROGRESS, iv.iv_update); bt_mesh.ivu_duration = iv.iv_duration; - BT_DBG("IV Index 0x%04x (IV Update Flag %u) duration %u hours", + BT_INFO("Restored IV Index 0x%04x (IV Update Flag %u) duration %u hours", iv.iv_index, iv.iv_update, iv.iv_duration); return 0; @@ -284,7 +280,7 @@ static int seq_set(const char *name) bt_mesh.seq--; #endif - BT_DBG("Sequence Number 0x%06x", bt_mesh.seq); + BT_INFO("Restored Sequence Number 0x%06x", bt_mesh.seq); return 0; } @@ -361,7 +357,7 @@ static int rpl_set(const char *name) } } - BT_DBG("RPL 0x%04x: Seq 0x%06x, old_iv %u", src, rpl.seq, rpl.old_iv); + BT_INFO("Restored RPL 0x%04x: Seq 0x%06x, old_iv %u", src, rpl.seq, rpl.old_iv); entry->src = src; entry->seq = rpl.seq; entry->old_iv = rpl.old_iv; @@ -430,7 +426,7 @@ static int net_key_set(const char *name) } } - BT_DBG("NetKeyIndex 0x%03x recovered from storage", net_idx); + BT_INFO("Restored NetKey Index 0x%03x", net_idx); sub->net_idx = net_idx; sub->kr_flag = key.kr_flag; sub->kr_phase = key.kr_phase; @@ -495,7 +491,7 @@ static int app_key_set(const char *name) } } - BT_DBG("AppKeyIndex 0x%03x recovered from storage", app_idx); + BT_INFO("Restored AppKey Index 0x%03x", app_idx); app->net_idx = key.net_idx; app->app_idx = app_idx; app->updated = key.updated; @@ -550,7 +546,7 @@ static int hb_pub_set(const char *name) hb_pub->count = 0U; } - BT_DBG("Restore Heartbeat Publication"); + BT_INFO("Restored heartbeat publication, dst 0x%04x", hb_pub->dst); return 0; } @@ -583,7 +579,7 @@ static int cfg_set(const char *name) memcpy(&stored_cfg.cfg, &val, sizeof(val)); stored_cfg.valid = true; - BT_DBG("Restore configuration state"); + BT_INFO("Restored configuration state"); return 0; } @@ -667,7 +663,7 @@ static int model_set_pub(bool vnd, struct bt_mesh_model *model, u16_t model_key) model->pub->retransmit = pub.retransmit; model->pub->count = 0U; - BT_DBG("Restore model publication, pub_addr 0x%04x app_idx 0x%03x", + BT_INFO("Restored model publication, pub_addr 0x%04x, app_idx 0x%03x", pub.addr, pub.key); return 0; @@ -789,7 +785,7 @@ static int va_set(const char *name) lab->addr = va.addr; lab->ref = va.ref; - BT_DBG("Restore virtual address 0x%04x ref 0x%04x", index, lab->ref); + BT_INFO("Restored virtual address 0x%04x ref 0x%04x", index, lab->ref); } free: @@ -799,32 +795,15 @@ free: #endif #if CONFIG_BLE_MESH_PROVISIONER - -static int subnet_init(struct bt_mesh_subnet *sub); - -/** - * The following variable is used to check whether Provisioner - * needs to continue restoring network keys and application keys - * during initialization. - * Because if a Provisioner starts to work at the first time, and - * after trying to restore the "bt_mesh.p_net_idx_next", nothing - * will be recovered. Hence there will be no need to restore the - * network keys and application keys. And during the Provisioner - * initialization, it will generate the primary network key. - * And if "p_key_exist" is false, which also means the Provisioner - * has not provisioned any node. - */ -static bool p_key_exist; - static int p_prov_set(const char *name) { - u16_t address; + struct prov_info val = {0}; bool exist; int err; BT_DBG("%s", __func__); - err = bt_mesh_load_core_settings(name, (u8_t *)&address, sizeof(address), &exist); + err = bt_mesh_load_core_settings(name, (u8_t *)&val, sizeof(val), &exist); if (err) { BT_ERR("%s, Failed to load Provisioner prov info", __func__); return 0; @@ -834,9 +813,10 @@ static int p_prov_set(const char *name) return 0; } - bt_mesh_provisoner_restore_prov_info(address); + bt_mesh_provisoner_restore_prov_info(val.primary_addr, val.alloc_addr); - BT_DBG("curr_addr 0x%04x", address); + BT_INFO("Restored primary_addr 0x%04x, alloc_addr 0x%04x", + val.primary_addr, val.alloc_addr); return 0; } @@ -852,19 +832,16 @@ static int p_net_idx_set(const char *name) err = bt_mesh_load_core_settings(name, (u8_t *)&net_idx, sizeof(net_idx), &exist); if (err) { BT_ERR("%s, Failed to load Provisioner keys", __func__); - p_key_exist = false; return 0; } if (exist == false) { - p_key_exist = false; return 0; } bt_mesh.p_net_idx_next = net_idx; - p_key_exist = true; - BT_DBG("p_net_idx_next 0x%04x", bt_mesh.p_net_idx_next); + BT_INFO("Restored p_net_idx_next 0x%04x", bt_mesh.p_net_idx_next); return 0; } @@ -877,15 +854,6 @@ static int p_app_idx_set(const char *name) BT_DBG("%s", __func__); - if (p_key_exist == false) { - /** - * Directly return here if a Provisioner fails to restore the - * bt_mesh.p_net_idx_next, which means the corresponding keys - * have not be stored in the flash for the Provisioner. - */ - return 0; - } - err = bt_mesh_load_core_settings(name, (u8_t *)&app_idx, sizeof(app_idx), &exist); if (err) { return 0; @@ -897,7 +865,7 @@ static int p_app_idx_set(const char *name) bt_mesh.p_app_idx_next = app_idx; - BT_DBG("p_app_idx_next 0x%04x", bt_mesh.p_app_idx_next); + BT_INFO("Restored p_app_idx_next 0x%04x", bt_mesh.p_app_idx_next); return 0; } @@ -953,10 +921,6 @@ static int p_net_key_set(const char *name) BT_DBG("%s", __func__); - if (p_key_exist == false) { - return 0; - } - buf = bt_mesh_get_core_settings_item(name); if (!buf) { return 0; @@ -988,17 +952,12 @@ static int p_net_key_set(const char *name) } } - BT_DBG("NetKeyIndex 0x%03x recovered from storage", net_idx); + BT_INFO("Restored NetKey Index 0x%03x", net_idx); sub->net_idx = net_idx; sub->kr_flag = key.kr_flag; sub->kr_phase = key.kr_phase; memcpy(sub->keys[0].net, &key.val[0], 16); memcpy(sub->keys[1].net, &key.val[1], 16); - err = subnet_init(sub); - if (err) { - BT_ERR("%s, Failed to init Provisioner subnet 0x%03x", __func__, sub->net_idx); - } - sub->node_id = BLE_MESH_NODE_IDENTITY_NOT_SUPPORTED; } free: @@ -1020,10 +979,6 @@ static int p_app_key_set(const char *name) BT_DBG("%s", __func__); - if (p_key_exist == false) { - return 0; - } - buf = bt_mesh_get_core_settings_item(name); if (!buf) { return 0; @@ -1062,7 +1017,7 @@ static int p_app_key_set(const char *name) } } - BT_DBG("AppKeyIndex 0x%03x recovered from storage", app_idx); + BT_INFO("Restored AppKey Index 0x%03x", app_idx); app->net_idx = key.net_idx; app->app_idx = app_idx; app->updated = key.updated; @@ -1081,17 +1036,12 @@ static int p_node_set(const char *name) { struct net_buf_simple *buf = NULL; struct bt_mesh_node node = {0}; - struct node_update val = {0}; char get[16] = {'\0'}; bool exist, prov; size_t length; int err = 0; size_t i; - if (p_key_exist == false) { - return 0; - } - buf = bt_mesh_get_core_settings_item(name); if (!buf) { return 0; @@ -1104,7 +1054,7 @@ static int p_node_set(const char *name) u16_t addr = net_buf_simple_pull_le16(buf); sprintf(get, prov ? "mesh/pnd/%04x" : "mesh/snd/%04x", addr); - err = bt_mesh_load_core_settings(get, (u8_t *)&val, sizeof(val), &exist); + err = bt_mesh_load_core_settings(get, (u8_t *)&node, sizeof(node), &exist); if (err) { BT_ERR("%s, Failed to load node %s", __func__, get); goto free; @@ -1114,18 +1064,13 @@ static int p_node_set(const char *name) continue; } - memcpy(&node.addr, &val.addr, sizeof(bt_mesh_addr_t)); - memcpy(node.dev_uuid, val.dev_uuid, 16); - node.oob_info = val.oob_info; - node.unicast_addr = val.unicast_addr; - node.element_num = val.element_num; - memcpy(node.dev_key, val.dev_key, 16); - err = bt_mesh_provisioner_restore_node_info(&node, prov); if (err) { BT_ERR("%s, Failed to store node 0x%04x", __func__, node.unicast_addr); goto free; } + + BT_INFO("Restored node 0x%04x, uuid %s", node.unicast_addr, bt_hex(node.dev_uuid, 16)); } free: @@ -1179,7 +1124,7 @@ const struct bt_mesh_setting { */ int settings_core_load(void) { - u8_t i; + size_t i; BT_DBG("%s", __func__); @@ -1189,7 +1134,7 @@ int settings_core_load(void) !strcmp(settings[i].name, "mesh/appkey") || !strcmp(settings[i].name, "mesh/hb_pub") || !strcmp(settings[i].name, "mesh/cfg")) && - (!IS_ENABLED(CONFIG_BLE_MESH_NODE) || (dev_role == PROVISIONER))) { + (!IS_ENABLED(CONFIG_BLE_MESH_NODE) || bt_mesh_is_provisioner())) { BT_DBG("Not restoring %s for Provisioner", settings[i].name); continue; } @@ -1201,15 +1146,16 @@ int settings_core_load(void) !strcmp(settings[i].name, "mesh/p_appkey") || !strcmp(settings[i].name, "mesh/p_pnode") || !strcmp(settings[i].name, "mesh/p_snode")) && - (!IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) || (dev_role == NODE))) { + (!IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) || bt_mesh_is_node())) { BT_DBG("Not restoring %s for node", settings[i].name); continue; } settings[i].func(settings[i].name); - if (!strcmp(settings[i].name, "mesh/role") && (dev_role == ROLE_NVAL)) { - BT_DBG("Device just starts up"); + if (!strcmp(settings[i].name, "mesh/role") && + !bt_mesh_is_node() && !bt_mesh_is_provisioner()) { + BT_INFO("Device just starts up"); return 0; } } @@ -1263,12 +1209,13 @@ static void commit_model(struct bt_mesh_model *model, struct bt_mesh_elem *elem, int settings_core_commit(void) { - struct bt_mesh_hb_pub *hb_pub = NULL; - struct bt_mesh_cfg_srv *cfg = NULL; - int i; + struct bt_mesh_subnet *sub = NULL; + size_t i; + int err; - if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && (dev_role == NODE)) { - BT_DBG("sub[0].net_idx 0x%03x", bt_mesh.sub[0].net_idx); +#if defined(CONFIG_BLE_MESH_NODE) + if (bt_mesh_is_node()) { + BT_INFO("sub[0].net_idx 0x%03x", bt_mesh.sub[0].net_idx); if (bt_mesh.sub[0].net_idx == BLE_MESH_KEY_UNUSED) { /* Nothing to do since we're not yet provisioned */ @@ -1279,9 +1226,8 @@ int settings_core_commit(void) bt_mesh_proxy_prov_disable(true); } - for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { - struct bt_mesh_subnet *sub = &bt_mesh.sub[i]; - int err; + for (i = 0U; i < ARRAY_SIZE(bt_mesh.sub); i++) { + sub = &bt_mesh.sub[i]; if (sub->net_idx == BLE_MESH_KEY_UNUSED) { continue; @@ -1293,6 +1239,34 @@ int settings_core_commit(void) } } } +#endif /* CONFIG_BLE_MESH_NODE */ + +#if defined(CONFIG_BLE_MESH_PROVISIONER) + if (bt_mesh_is_provisioner()) { + if (bt_mesh.p_sub[0] == NULL || + bt_mesh.p_sub[0]->net_idx == BLE_MESH_KEY_UNUSED) { + return 0; + } + + BT_INFO("p_sub[0]->net_idx 0x%03x", bt_mesh.p_sub[0]->net_idx); + + bt_mesh_comp_provision(bt_mesh_provisioner_get_primary_elem_addr()); + + for (i = 0U; i < ARRAY_SIZE(bt_mesh.p_sub); i++) { + sub = bt_mesh.p_sub[i]; + + if (sub == NULL || sub->net_idx == BLE_MESH_KEY_UNUSED) { + continue; + } + + err = subnet_init(sub); + if (err) { + BT_ERR("%s, Failed to init subnet 0x%03x", __func__, sub->net_idx); + } + sub->node_id = BLE_MESH_NODE_IDENTITY_NOT_SUPPORTED; + } + } +#endif /* CONFIG_BLE_MESH_PROVISIONER */ if (bt_mesh.ivu_duration < BLE_MESH_IVU_MIN_HOURS) { k_delayed_work_submit(&bt_mesh.ivu_timer, BLE_MESH_IVU_TIMEOUT); @@ -1300,7 +1274,11 @@ int settings_core_commit(void) bt_mesh_model_foreach(commit_model, NULL); - if(IS_ENABLED(CONFIG_BLE_MESH_NODE) && (dev_role == NODE)) { +#if defined(CONFIG_BLE_MESH_NODE) + if (bt_mesh_is_node()) { + struct bt_mesh_hb_pub *hb_pub = NULL; + struct bt_mesh_cfg_srv *cfg = NULL; + hb_pub = bt_mesh_hb_pub_get(); if (hb_pub && hb_pub->dst != BLE_MESH_ADDR_UNASSIGNED && hb_pub->count && hb_pub->period) { @@ -1322,6 +1300,13 @@ int settings_core_commit(void) bt_mesh_atomic_set_bit(bt_mesh.flags, BLE_MESH_VALID); bt_mesh_net_start(); } +#endif /* CONFIG_BLE_MESH_NODE */ + +#if defined(CONFIG_BLE_MESH_PROVISIONER) + if (bt_mesh_is_provisioner()) { + bt_mesh_provisioner_net_start(BLE_MESH_PROV_ADV | BLE_MESH_PROV_GATT); + } +#endif /* CONFIG_BLE_MESH_PROVISIONER */ return 0; } @@ -1394,12 +1379,11 @@ static void store_pending_net(void) bt_mesh_save_core_settings("mesh/net", (const u8_t *)&net, sizeof(net)); } -void bt_mesh_store_role(u8_t role) +void bt_mesh_store_role(void) { - BT_DBG("Device role 0x%02x", dev_role); + BT_DBG("Store, device role %lu", bt_mesh_atomic_get(bt_mesh.flags) & DEVICE_ROLE_BITS); - dev_role = role; - bt_mesh_save_core_settings("mesh/role", (const u8_t *)&role, sizeof(role)); + bt_mesh_save_core_settings("mesh/role", (const u8_t *)bt_mesh.flags, sizeof(bt_mesh.flags)); } void bt_mesh_store_net(void) @@ -1713,8 +1697,8 @@ static void store_pending_mod_bind(struct bt_mesh_model *model, bool vnd) sprintf(name, "mesh/%s/%04x/b", vnd ? "v" : "s", model_key); - if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && (dev_role == NODE) && - !bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_VALID)) { + if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_node() && + !bt_mesh_is_provisioned()) { bt_mesh_save_core_settings(name, NULL, 0); return; } @@ -1744,8 +1728,8 @@ static void store_pending_mod_sub(struct bt_mesh_model *model, bool vnd) sprintf(name, "mesh/%s/%04x/s", vnd ? "v" : "s", model_key); - if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && (dev_role == NODE) && - !bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_VALID)) { + if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_node() && + !bt_mesh_is_provisioned()) { bt_mesh_save_core_settings(name, NULL, 0); return; } @@ -1789,8 +1773,8 @@ static void store_pending_mod_pub(struct bt_mesh_model *model, bool vnd) sprintf(name, "mesh/%s/%04x/p", vnd ? "v" : "s", model_key); - if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && (dev_role == NODE) && - !bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_VALID)) { + if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_node() && + !bt_mesh_is_provisioned()) { bt_mesh_save_core_settings(name, NULL, 0); return; } @@ -1885,22 +1869,21 @@ static void store_pending(struct k_work *work) BT_DBG("%s", __func__); if (bt_mesh_atomic_test_and_clear_bit(bt_mesh.flags, BLE_MESH_RPL_PENDING)) { - if (!IS_ENABLED(CONFIG_BLE_MESH_NODE) || - bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_VALID)) { + if (!IS_ENABLED(CONFIG_BLE_MESH_NODE) || bt_mesh_is_provisioned()) { store_pending_rpl(); } else { clear_rpl(); } } - if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && (dev_role == NODE) && + if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_node() && bt_mesh_atomic_test_and_clear_bit(bt_mesh.flags, BLE_MESH_KEYS_PENDING)) { store_pending_keys(); } - if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && (dev_role == NODE) && + if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_node() && bt_mesh_atomic_test_and_clear_bit(bt_mesh.flags, BLE_MESH_NET_PENDING)) { - if (bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_VALID)) { + if (bt_mesh_is_provisioned()) { store_pending_net(); } else { clear_net(); @@ -1908,8 +1891,7 @@ static void store_pending(struct k_work *work) } if (bt_mesh_atomic_test_and_clear_bit(bt_mesh.flags, BLE_MESH_IV_PENDING)) { - if (!IS_ENABLED(CONFIG_BLE_MESH_NODE) || - bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_VALID)) { + if (!IS_ENABLED(CONFIG_BLE_MESH_NODE) || bt_mesh_is_provisioned()) { store_pending_iv(); } else { clear_iv(); @@ -1920,14 +1902,14 @@ static void store_pending(struct k_work *work) store_pending_seq(); } - if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && (dev_role == NODE) && + if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_node() && bt_mesh_atomic_test_and_clear_bit(bt_mesh.flags, BLE_MESH_HB_PUB_PENDING)) { store_pending_hb_pub(); } - if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && (dev_role == NODE) && + if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_node() && bt_mesh_atomic_test_and_clear_bit(bt_mesh.flags, BLE_MESH_CFG_PENDING)) { - if (bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_VALID)) { + if (bt_mesh_is_provisioned()) { store_pending_cfg(); } else { clear_cfg(); @@ -1936,8 +1918,8 @@ static void store_pending(struct k_work *work) if (bt_mesh_atomic_test_and_clear_bit(bt_mesh.flags, BLE_MESH_MOD_PENDING)) { bt_mesh_model_foreach(store_pending_mod, NULL); - if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && (dev_role == NODE) && - !bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_VALID)) { + if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_node() && + !bt_mesh_is_provisioned()) { bt_mesh_save_core_settings("mesh/sig", NULL, 0); bt_mesh_save_core_settings("mesh/vnd", NULL, 0); } @@ -2048,7 +2030,7 @@ void bt_mesh_store_cfg(void) void bt_mesh_clear_role(void) { - BT_DBG("Clearing device role"); + BT_DBG("Clear device role"); bt_mesh_save_core_settings("mesh/role", NULL, 0); } @@ -2155,12 +2137,17 @@ void bt_mesh_store_label(void) * key: "mesh/p_snode" -> write/read to set/get all locally stored nodes info * key: "mesh/snd/xxxx" -> write/read to set/get the "xxxx" stored node info */ -void bt_mesh_store_prov_info(u16_t curr_addr) +void bt_mesh_store_prov_info(u16_t primary_addr, u16_t alloc_addr) { - BT_DBG("curr_addr 0x%04x", curr_addr); + struct prov_info val = {0}; + + BT_DBG("primary_addr 0x%04x, alloc_addr 0x%04x", primary_addr, alloc_addr); + + val.primary_addr = primary_addr; + val.alloc_addr = alloc_addr; bt_mesh_save_core_settings("mesh/p_prov", - (const u8_t *)&curr_addr, sizeof(curr_addr)); + (const u8_t *)&val, sizeof(val)); } static void clear_p_net_key(u16_t net_idx) @@ -2336,7 +2323,6 @@ void bt_mesh_clear_rpl_single(u16_t src) void bt_mesh_store_node_info(struct bt_mesh_node *node, bool prov) { - struct node_update val = {0}; char name[16] = {'\0'}; int err; @@ -2345,15 +2331,8 @@ void bt_mesh_store_node_info(struct bt_mesh_node *node, bool prov) return; } - memcpy(&val.addr, &node->addr, sizeof(bt_mesh_addr_t)); - memcpy(val.dev_uuid, node->dev_uuid, 16); - val.oob_info = node->oob_info; - val.unicast_addr = node->unicast_addr; - val.element_num = node->element_num; - memcpy(val.dev_key, node->dev_key, 16); - sprintf(name, prov ? "mesh/pnd/%04x" : "mesh/snd/%04x", node->unicast_addr); - err = bt_mesh_save_core_settings(name, (const u8_t *)&val, sizeof(val)); + err = bt_mesh_save_core_settings(name, (const u8_t *)node, sizeof(struct bt_mesh_node)); if (err) { BT_ERR("%s, Failed to save node %s", __func__, name); return; diff --git a/components/bt/esp_ble_mesh/mesh_core/settings.h b/components/bt/esp_ble_mesh/mesh_core/settings.h index 844bc90a70..2f9126a983 100644 --- a/components/bt/esp_ble_mesh/mesh_core/settings.h +++ b/components/bt/esp_ble_mesh/mesh_core/settings.h @@ -19,7 +19,7 @@ int settings_core_load(void); int settings_core_commit(void); int settings_core_deinit(void); -void bt_mesh_store_role(u8_t role); +void bt_mesh_store_role(void); void bt_mesh_store_net(void); void bt_mesh_store_iv(bool only_duration); void bt_mesh_store_seq(void); @@ -40,7 +40,7 @@ void bt_mesh_clear_app_key(struct bt_mesh_app_key *key); void bt_mesh_clear_rpl(void); #if CONFIG_BLE_MESH_PROVISIONER -void bt_mesh_store_prov_info(u16_t curr_addr); +void bt_mesh_store_prov_info(u16_t primary_addr, u16_t alloc_addr); void bt_mesh_store_p_net_idx(void); void bt_mesh_clear_p_net_idx(void); void bt_mesh_store_p_app_idx(void); diff --git a/components/bt/esp_ble_mesh/mesh_core/transport.c b/components/bt/esp_ble_mesh/mesh_core/transport.c index 4e6f15b3c5..3c95028bbb 100644 --- a/components/bt/esp_ble_mesh/mesh_core/transport.c +++ b/components/bt/esp_ble_mesh/mesh_core/transport.c @@ -912,7 +912,7 @@ static int trans_heartbeat(struct bt_mesh_net_rx *rx, hops = (init_ttl - rx->ctx.recv_ttl + 1); - BT_DBG("src 0x%04x TTL %u InitTTL %u (%u hop%s) feat 0x%04x", + BT_INFO("src 0x%04x TTL %u InitTTL %u (%u hop%s) feat 0x%04x", rx->ctx.addr, rx->ctx.recv_ttl, init_ttl, hops, (hops == 1U) ? "" : "s", feat); @@ -1454,7 +1454,7 @@ found_rx: /* Location in buffer can be calculated based on seg_o & rx->ctl */ memcpy(rx->buf.data + (seg_o * seg_len(rx->ctl)), buf->data, buf->len); - BT_DBG("Received %u/%u", seg_o, seg_n); + BT_INFO("Received %u/%u", seg_o, seg_n); /* Mark segment as received */ rx->block |= BIT(seg_o); @@ -1689,7 +1689,7 @@ void bt_mesh_heartbeat_send(void) hb.feat = sys_cpu_to_be16(feat); - BT_DBG("InitTTL %u feat 0x%04x", cfg->hb_pub.ttl, feat); + BT_INFO("InitTTL %u feat 0x%04x", cfg->hb_pub.ttl, feat); bt_mesh_ctl_send(&tx, TRANS_CTL_OP_HEARTBEAT, &hb, sizeof(hb), NULL, NULL, NULL); @@ -1716,7 +1716,7 @@ int bt_mesh_app_key_get(const struct bt_mesh_subnet *subnet, u16_t app_idx, return -EINVAL; } - app_key = bt_mesh_tx_appkey_get(role, app_idx, subnet->net_idx); + app_key = bt_mesh_tx_appkey_get(role, app_idx); if (!app_key) { BT_ERR("%s, Failed to get AppKey", __func__); return -ENOENT; diff --git a/components/bt/esp_ble_mesh/mesh_models/client/generic_client.c b/components/bt/esp_ble_mesh/mesh_models/client/generic_client.c index 5105072b5e..dfb74386a0 100644 --- a/components/bt/esp_ble_mesh/mesh_models/client/generic_client.c +++ b/components/bt/esp_ble_mesh/mesh_models/client/generic_client.c @@ -156,6 +156,8 @@ static void timeout_handler(struct k_work *work) { struct k_delayed_work *timer = NULL; bt_mesh_client_node_t *node = NULL; + struct bt_mesh_msg_ctx ctx = {0}; + u32_t opcode; BT_WARN("Receive generic status message timeout"); @@ -166,10 +168,11 @@ static void timeout_handler(struct k_work *work) if (timer && !k_delayed_work_free(timer)) { node = CONTAINER_OF(work, bt_mesh_client_node_t, timer.work); if (node) { - bt_mesh_generic_client_cb_evt_to_btc(node->opcode, - BTC_BLE_MESH_EVT_GENERIC_CLIENT_TIMEOUT, node->ctx.model, &node->ctx, NULL, 0); - // Don't forget to release the node at the end. + memcpy(&ctx, &node->ctx, sizeof(ctx)); + opcode = node->opcode; bt_mesh_client_free_node(node); + bt_mesh_generic_client_cb_evt_to_btc( + opcode, BTC_BLE_MESH_EVT_GENERIC_CLIENT_TIMEOUT, ctx.model, &ctx, NULL, 0); } } @@ -592,9 +595,9 @@ static void generic_status(struct bt_mesh_model *model, } if (!k_delayed_work_free(&node->timer)) { - bt_mesh_generic_client_cb_evt_to_btc(node->opcode, evt, model, ctx, val, len); - // Don't forget to release the node at the end. + u32_t opcode = node->opcode; bt_mesh_client_free_node(node); + bt_mesh_generic_client_cb_evt_to_btc(opcode, evt, model, ctx, val, len); } } diff --git a/components/bt/esp_ble_mesh/mesh_models/client/lighting_client.c b/components/bt/esp_ble_mesh/mesh_models/client/lighting_client.c index 203959ba34..ce7c91f281 100644 --- a/components/bt/esp_ble_mesh/mesh_models/client/lighting_client.c +++ b/components/bt/esp_ble_mesh/mesh_models/client/lighting_client.c @@ -165,6 +165,8 @@ static void timeout_handler(struct k_work *work) { struct k_delayed_work *timer = NULL; bt_mesh_client_node_t *node = NULL; + struct bt_mesh_msg_ctx ctx = {0}; + u32_t opcode; BT_WARN("Receive light status message timeout"); @@ -175,10 +177,11 @@ static void timeout_handler(struct k_work *work) if (timer && !k_delayed_work_free(timer)) { node = CONTAINER_OF(work, bt_mesh_client_node_t, timer.work); if (node) { - bt_mesh_lighting_client_cb_evt_to_btc(node->opcode, - BTC_BLE_MESH_EVT_LIGHTING_CLIENT_TIMEOUT, node->ctx.model, &node->ctx, NULL, 0); - // Don't forget to release the node at the end. + memcpy(&ctx, &node->ctx, sizeof(ctx)); + opcode = node->opcode; bt_mesh_client_free_node(node); + bt_mesh_lighting_client_cb_evt_to_btc( + opcode, BTC_BLE_MESH_EVT_LIGHTING_CLIENT_TIMEOUT, ctx.model, &ctx, NULL, 0); } } @@ -718,9 +721,9 @@ static void light_status(struct bt_mesh_model *model, } if (!k_delayed_work_free(&node->timer)) { - bt_mesh_lighting_client_cb_evt_to_btc(node->opcode, evt, model, ctx, val, len); - // Don't forget to release the node at the end. + u32_t opcode = node->opcode; bt_mesh_client_free_node(node); + bt_mesh_lighting_client_cb_evt_to_btc(opcode, evt, model, ctx, val, len); } } diff --git a/components/bt/esp_ble_mesh/mesh_models/client/sensor_client.c b/components/bt/esp_ble_mesh/mesh_models/client/sensor_client.c index ca6186c00a..01c58d9a02 100644 --- a/components/bt/esp_ble_mesh/mesh_models/client/sensor_client.c +++ b/components/bt/esp_ble_mesh/mesh_models/client/sensor_client.c @@ -94,6 +94,8 @@ static void timeout_handler(struct k_work *work) { struct k_delayed_work *timer = NULL; bt_mesh_client_node_t *node = NULL; + struct bt_mesh_msg_ctx ctx = {0}; + u32_t opcode; BT_WARN("Receive sensor status message timeout"); @@ -104,10 +106,11 @@ static void timeout_handler(struct k_work *work) if (timer && !k_delayed_work_free(timer)) { node = CONTAINER_OF(work, bt_mesh_client_node_t, timer.work); if (node) { - bt_mesh_sensor_client_cb_evt_to_btc(node->opcode, - BTC_BLE_MESH_EVT_SENSOR_CLIENT_TIMEOUT, node->ctx.model, &node->ctx, NULL, 0); - // Don't forget to release the node at the end. + memcpy(&ctx, &node->ctx, sizeof(ctx)); + opcode = node->opcode; bt_mesh_client_free_node(node); + bt_mesh_sensor_client_cb_evt_to_btc( + opcode, BTC_BLE_MESH_EVT_SENSOR_CLIENT_TIMEOUT, ctx.model, &ctx, NULL, 0); } } @@ -297,9 +300,9 @@ static void sensor_status(struct bt_mesh_model *model, } if (!k_delayed_work_free(&node->timer)) { - bt_mesh_sensor_client_cb_evt_to_btc(node->opcode, evt, model, ctx, val, len); - // Don't forget to release the node at the end. + u32_t opcode = node->opcode; bt_mesh_client_free_node(node); + bt_mesh_sensor_client_cb_evt_to_btc(opcode, evt, model, ctx, val, len); } } diff --git a/components/bt/esp_ble_mesh/mesh_models/client/time_scene_client.c b/components/bt/esp_ble_mesh/mesh_models/client/time_scene_client.c index 7971a6ee58..cde654156b 100644 --- a/components/bt/esp_ble_mesh/mesh_models/client/time_scene_client.c +++ b/components/bt/esp_ble_mesh/mesh_models/client/time_scene_client.c @@ -110,6 +110,8 @@ static void timeout_handler(struct k_work *work) { struct k_delayed_work *timer = NULL; bt_mesh_client_node_t *node = NULL; + struct bt_mesh_msg_ctx ctx = {0}; + u32_t opcode; BT_WARN("Receive time scene status message timeout"); @@ -120,10 +122,11 @@ static void timeout_handler(struct k_work *work) if (timer && !k_delayed_work_free(timer)) { node = CONTAINER_OF(work, bt_mesh_client_node_t, timer.work); if (node) { - bt_mesh_time_scene_client_cb_evt_to_btc(node->opcode, - BTC_BLE_MESH_EVT_TIME_SCENE_CLIENT_TIMEOUT, node->ctx.model, &node->ctx, NULL, 0); - // Don't forget to release the node at the end. + memcpy(&ctx, &node->ctx, sizeof(ctx)); + opcode = node->opcode; bt_mesh_client_free_node(node); + bt_mesh_time_scene_client_cb_evt_to_btc( + opcode, BTC_BLE_MESH_EVT_TIME_SCENE_CLIENT_TIMEOUT, ctx.model, &ctx, NULL, 0); } } @@ -341,9 +344,9 @@ static void time_scene_status(struct bt_mesh_model *model, } if (!k_delayed_work_free(&node->timer)) { - bt_mesh_time_scene_client_cb_evt_to_btc(node->opcode, evt, model, ctx, val, len); - // Don't forget to release the node at the end. + u32_t opcode = node->opcode; bt_mesh_client_free_node(node); + bt_mesh_time_scene_client_cb_evt_to_btc(opcode, evt, model, ctx, val, len); } } diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/ble_mesh_demo_main.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/ble_mesh_demo_main.c index 9777e8a641..2bf3003091 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/ble_mesh_demo_main.c +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/ble_mesh_demo_main.c @@ -146,8 +146,6 @@ static esp_ble_mesh_prov_t prov = { .uuid = dev_uuid, .output_size = 0, .output_actions = 0, - .prov_unicast_addr = 0x0001, - .prov_start_address = 0x0005, .prov_attention = 0x00, .prov_algorithm = 0x00, .prov_pub_key_oob = 0x00, @@ -352,10 +350,6 @@ static void example_ble_mesh_provisioning_cb(esp_ble_mesh_prov_cb_event_t event, } prov_start = true; break; - case ESP_BLE_MESH_PROVISIONER_PROV_ENABLE_COMP_EVT: - ESP_LOGI(TAG, "ESP_BLE_MESH_PROVISIONER_PROV_ENABLE_COMP_EVT, err_code: %d", - param->provisioner_prov_enable_comp.err_code); - break; case ESP_BLE_MESH_PROVISIONER_RECV_UNPROV_ADV_PKT_EVT: example_recv_unprov_adv_pkt(param->provisioner_recv_unprov_adv_pkt.dev_uuid, param->provisioner_recv_unprov_adv_pkt.addr, param->provisioner_recv_unprov_adv_pkt.addr_type, param->provisioner_recv_unprov_adv_pkt.oob_info, @@ -701,37 +695,6 @@ static esp_err_t ble_mesh_init(void) esp_ble_mesh_register_config_server_callback(example_ble_mesh_config_server_cb); esp_ble_mesh_register_generic_server_callback(example_ble_mesh_generic_server_cb); - ESP_LOGW(TAG, "prev, free heap size %d", esp_get_free_heap_size()); - vTaskDelay(10 / portTICK_PERIOD_MS); - ESP_LOGW(TAG, "start, free heap size %d", esp_get_free_heap_size()); - /* First time (make erase_flash, then make flash monitor), 72 bytes will be cost - * during first (start - end) circle. - * Second time (make monitor), 0 byte will be cost during first (start - end) cycle. - */ - for (int i = 0; i < 1000; i++) { - err = esp_ble_mesh_init(&prov, &comp); - if (err != ESP_OK) { - ESP_LOGE(TAG, "%s: Failed to initialize BLE Mesh", __func__); - return err; - } - err = esp_ble_mesh_client_model_init(&vnd_models[1]); - if (err != ESP_OK) { - ESP_LOGE(TAG, "%s: Failed to initialize fast prov client model", __func__); - return err; - } - err = esp_ble_mesh_client_model_deinit(&vnd_models[1]); - if (err != ESP_OK) { - ESP_LOGE(TAG, "%s: Failed to deinitialize fast prov client model", __func__); - return err; - } - err = esp_ble_mesh_deinit(); - if (err != ESP_OK) { - ESP_LOGE(TAG, "%s: Failed to de-initialize BLE Mesh", __func__); - return err; - } - ESP_LOGW(TAG, "end, free heap size %d", esp_get_free_heap_size()); - } - err = esp_ble_mesh_init(&prov, &comp); if (err != ESP_OK) { ESP_LOGE(TAG, "%s: Failed to initialize BLE Mesh", __func__); diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_tx_rx_test/coex_a2dp_mini/components/mesh_tx/ble_mesh_demo_main.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_tx_rx_test/coex_a2dp_mini/components/mesh_tx/ble_mesh_demo_main.c index 33392ffa68..0dab41028e 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_tx_rx_test/coex_a2dp_mini/components/mesh_tx/ble_mesh_demo_main.c +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_tx_rx_test/coex_a2dp_mini/components/mesh_tx/ble_mesh_demo_main.c @@ -24,6 +24,7 @@ #include "esp_ble_mesh_networking_api.h" #include "esp_ble_mesh_config_model_api.h" #include "esp_ble_mesh_generic_model_api.h" +#include "esp_ble_mesh_local_data_operation_api.h" #include "board.h" #include "ble_mesh_demo_init.h" @@ -67,7 +68,10 @@ static void example_start_interval_timer(void); static SemaphoreHandle_t test_mutex; +static uint8_t match[2] = {0xec, 0xa6}; static uint8_t dev_uuid[16]; +bool example_deinit_test; +static uint16_t primary_addr; typedef struct { uint8_t uuid[16]; @@ -351,6 +355,9 @@ static void example_ble_mesh_provisioning_cb(esp_ble_mesh_prov_cb_event_t event, esp_ble_mesh_prov_cb_param_t *param) { switch (event) { + case ESP_BLE_MESH_PROV_REGISTER_COMP_EVT: + ESP_LOGI(TAG, "ESP_BLE_MESH_PROV_REGISTER_COMP_EVT, err_code %d", param->prov_register_comp.err_code); + break; case ESP_BLE_MESH_PROVISIONER_PROV_ENABLE_COMP_EVT: ESP_LOGI(TAG, "ESP_BLE_MESH_PROVISIONER_PROV_ENABLE_COMP_EVT, err_code %d", param->provisioner_prov_enable_comp.err_code); if (iperf_test == true) { @@ -387,6 +394,12 @@ static void example_ble_mesh_provisioning_cb(esp_ble_mesh_prov_cb_event_t event, case ESP_BLE_MESH_PROVISIONER_SET_DEV_UUID_MATCH_COMP_EVT: ESP_LOGI(TAG, "ESP_BLE_MESH_PROVISIONER_SET_DEV_UUID_MATCH_COMP_EVT, err_code %d", param->provisioner_set_dev_uuid_match_comp.err_code); break; + case ESP_BLE_MESH_PROVISIONER_SET_PRIMARY_ELEM_ADDR_COMP_EVT: + ESP_LOGI(TAG, "ESP_BLE_MESH_PROVISIONER_SET_PRIMARY_ELEM_ADDR_COMP_EVT, err_code %d", param->provisioner_set_primary_elem_addr_comp.err_code); + if (!param->provisioner_set_primary_elem_addr_comp.err_code) { + primary_addr = esp_ble_mesh_get_primary_element_address(); + } + break; case ESP_BLE_MESH_PROVISIONER_SET_NODE_NAME_COMP_EVT: ESP_LOGI(TAG, "ESP_BLE_MESH_PROVISIONER_SET_NODE_NAME_COMP_EVT, err_code %d", param->provisioner_set_node_name_comp.err_code); if (param->provisioner_set_node_name_comp.err_code == ESP_OK) { @@ -404,7 +417,7 @@ static void example_ble_mesh_provisioning_cb(esp_ble_mesh_prov_cb_event_t event, if (param->provisioner_add_app_key_comp.err_code == ESP_OK) { esp_err_t err = 0; prov_key.app_idx = param->provisioner_add_app_key_comp.app_idx; - err = esp_ble_mesh_provisioner_bind_app_key_to_local_model(PROV_OWN_ADDR, prov_key.app_idx, + err = esp_ble_mesh_provisioner_bind_app_key_to_local_model(primary_addr, prov_key.app_idx, ESP_BLE_MESH_VND_MODEL_ID_TEST_CLI, CID_ESP); if (err != ESP_OK) { ESP_LOGE(TAG, "Provisioner bind local model appkey failed"); @@ -467,6 +480,7 @@ static void example_ble_mesh_config_client_cb(esp_ble_mesh_cfg_client_cb_event_t ESP_LOGE(TAG, "%s: Config Model App Bind failed", __func__); } } else if (param->params->opcode == ESP_BLE_MESH_MODEL_OP_MODEL_APP_BIND) { + ESP_LOGW(TAG, "%s, Primary element address 0x%04x", __func__, esp_ble_mesh_get_primary_element_address()); ESP_LOGW(TAG, "%s, Provisioning and config successfully", __func__); } break; @@ -542,8 +556,8 @@ static void example_ble_mesh_custom_model_cb(esp_ble_mesh_model_cb_event_t event break; case ESP_BLE_MESH_CLIENT_MODEL_RECV_PUBLISH_MSG_EVT: example_test_lock(); - if (param->model_operation.opcode == ESP_BLE_MESH_VND_MODEL_OP_TEST_STATUS) { - uint16_t value = *(uint16_t *)param->model_operation.msg; + if (param->client_recv_publish_msg.opcode == ESP_BLE_MESH_VND_MODEL_OP_TEST_STATUS) { + uint16_t value = *(uint16_t *)param->client_recv_publish_msg.msg; ESP_LOGI(TAG, "%d %d %d", msg_index, value, trans_num); if (value == trans_num && retrans_timer_start == true) { msg_record[msg_index].acked = true; @@ -647,11 +661,49 @@ const esp_timer_create_args_t interval_timer_args = { .name = "interval", }; -static esp_err_t ble_mesh_init(void) +esp_err_t example_ble_mesh_start(void) { - uint8_t match[2] = {0xec, 0xa6}; esp_err_t err; + err = esp_ble_mesh_init(&provision, &composition); + if (err) { + return err; + } + + err = esp_ble_mesh_client_model_init(&vnd_models[0]); + if (err) { + return err; + } + + err = esp_ble_mesh_provisioner_set_dev_uuid_match(match, sizeof(match), 0x0, false); + if (err) { + return err; + } + + err = esp_ble_mesh_provisioner_prov_enable(ESP_BLE_MESH_PROV_ADV | ESP_BLE_MESH_PROV_GATT); + if (err) { + return err; + } + + err = esp_ble_mesh_provisioner_set_primary_elem_addr(0x0006); + if (err) { + return err; + } + + err = esp_ble_mesh_provisioner_add_local_app_key(prov_key.app_key, prov_key.net_idx, prov_key.app_idx); + if (err) { + return err; + } + + ESP_LOGW(TAG, "BLE Mesh start"); + return 0; +} + +static esp_err_t ble_mesh_init(void) +{ + esp_err_t err; + + primary_addr = PROV_OWN_ADDR; prov_key.net_idx = ESP_BLE_MESH_KEY_PRIMARY; prov_key.app_idx = APP_KEY_IDX; memset(prov_key.app_key, APP_KEY_OCTET, sizeof(prov_key.app_key)); @@ -660,19 +712,44 @@ static esp_err_t ble_mesh_init(void) esp_ble_mesh_register_config_client_callback(example_ble_mesh_config_client_cb); esp_ble_mesh_register_custom_model_callback(example_ble_mesh_custom_model_cb); - err = esp_ble_mesh_init(&provision, &composition); - if (err) { - ESP_LOGE(TAG, "Initializing mesh failed (err %d)", err); - return err; + if (example_deinit_test == true) { + ESP_LOGW(TAG, "prev, free heap size %d", esp_get_free_heap_size()); + vTaskDelay(10 / portTICK_PERIOD_MS); + ESP_LOGW(TAG, "start, free heap size %d", esp_get_free_heap_size()); + /* First time (make erase_flash, then make flash monitor), 72 bytes will be cost + * during first (start - end) circle. + * Second time (make monitor), 0 byte will be cost during first (start - end) cycle. + */ + for (int i = 0; i < 100; i++) { + err = esp_ble_mesh_init(&provision, &composition); + if (err != ESP_OK) { + ESP_LOGE(TAG, "%s: Failed to initialize BLE Mesh", __func__); + return err; + } + err = esp_ble_mesh_client_model_init(&vnd_models[0]); + if (err != ESP_OK) { + ESP_LOGE(TAG, "%s: Failed to initialize vnd client model", __func__); + return err; + } + err = esp_ble_mesh_client_model_deinit(&vnd_models[0]); + if (err != ESP_OK) { + ESP_LOGE(TAG, "%s: Failed to deinitialize vnd client model", __func__); + return err; + } + err = esp_ble_mesh_deinit(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "%s: Failed to de-initialize BLE Mesh", __func__); + return err; + } + ESP_LOGW(TAG, "end, free heap size %d", esp_get_free_heap_size()); + } } - esp_ble_mesh_client_model_init(&vnd_models[0]); - - esp_ble_mesh_provisioner_set_dev_uuid_match(match, sizeof(match), 0x0, false); - - esp_ble_mesh_provisioner_prov_enable(ESP_BLE_MESH_PROV_ADV | ESP_BLE_MESH_PROV_GATT); - - esp_ble_mesh_provisioner_add_local_app_key(prov_key.app_key, prov_key.net_idx, prov_key.app_idx); + err = example_ble_mesh_start(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "%s, BLE Mesh start failed", __func__); + return err; + } ESP_LOGI(TAG, "BLE Mesh Provisioner initialized"); diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_tx_rx_test/coex_a2dp_mini/components/mesh_tx/board.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_tx_rx_test/coex_a2dp_mini/components/mesh_tx/board.c index 1053354ff8..286d3ddf8c 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_tx_rx_test/coex_a2dp_mini/components/mesh_tx/board.c +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_tx_rx_test/coex_a2dp_mini/components/mesh_tx/board.c @@ -15,6 +15,7 @@ #include "iot_button.h" #include "board.h" #include "esp_coexist_internal.h" +#include "esp_ble_mesh_common_api.h" #define TAG "BOARD" @@ -27,6 +28,8 @@ extern void example_ble_mesh_send_test_msg(bool resend); extern void example_ble_mesh_test_init(void); +extern esp_err_t example_ble_mesh_start(void); +extern bool example_deinit_test; struct _led_state led_state[3] = { { LED_OFF, LED_OFF, LED_R, "red" }, @@ -66,12 +69,27 @@ static void button_tap_cb(void* arg) { ESP_LOGI(TAG, "tap cb (%s)", (char *)arg); - coex_schm_status_set(COEX_SCHM_ST_TYPE_BLE, COEX_SCHM_BLE_ST_MESH_TRAFFIC); + if (example_deinit_test == true) { + static uint8_t count; + if (count++ % 2 == 0) { + if (esp_ble_mesh_deinit() != ESP_OK) { + ESP_LOGE(TAG, "%s, BLE Mesh deinit failed", __func__); + } else { + ESP_LOGW(TAG, "BLE Mesh deinit"); + } + } else { + if (example_ble_mesh_start() != ESP_OK) { + ESP_LOGE(TAG, "%s, BLE Mesh start failed", __func__); + } + } + } else { + coex_schm_status_set(COEX_SCHM_ST_TYPE_BLE, COEX_SCHM_BLE_ST_MESH_TRAFFIC); - ESP_LOGW(TAG, "BLE Mesh enters Traffic mode"); + ESP_LOGW(TAG, "BLE Mesh enters Traffic mode"); - example_ble_mesh_test_init(); - example_ble_mesh_send_test_msg(false); + example_ble_mesh_test_init(); + example_ble_mesh_send_test_msg(false); + } } static void board_button_init(void) diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_tx_rx_test/coex_a2dp_mini/main/main.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_tx_rx_test/coex_a2dp_mini/main/main.c index bd1e29907c..a6eda40975 100755 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_tx_rx_test/coex_a2dp_mini/main/main.c +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_tx_rx_test/coex_a2dp_mini/main/main.c @@ -211,7 +211,7 @@ void app_main() iperf_console_start(); } else { initialise_wifi(); - wifi_sta_join("ASUS", "1234567890"); + wifi_sta_join("ble_mesh_xiaomi_3g", "1234567890"); } }