diff --git a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_local_data_operation_api.c b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_local_data_operation_api.c index 568b079925..932f8a82b3 100644 --- a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_local_data_operation_api.c +++ b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_local_data_operation_api.c @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include "esp_err.h" @@ -128,3 +129,87 @@ esp_err_t esp_ble_mesh_model_unsubscribe_group_addr(uint16_t element_addr, uint1 return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } + +#if CONFIG_BLE_MESH_NODE + +const uint8_t *esp_ble_mesh_node_get_local_net_key(uint16_t net_idx) +{ + return btc_ble_mesh_node_get_local_net_key(net_idx); +} + +const uint8_t *esp_ble_mesh_node_get_local_app_key(uint16_t app_idx) +{ + return btc_ble_mesh_node_get_local_app_key(app_idx); +} + +esp_err_t esp_ble_mesh_node_add_local_net_key(const uint8_t net_key[16], uint16_t net_idx) +{ + btc_ble_mesh_prov_args_t arg = {0}; + btc_msg_t msg = {0}; + + if (net_key == NULL || net_idx > 0xFFF) { + 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_NODE_ADD_LOCAL_NET_KEY; + + arg.node_add_local_net_key.net_idx = net_idx; + memcpy(arg.node_add_local_net_key.net_key, net_key, 16); + + 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_node_add_local_app_key(const uint8_t app_key[16], uint16_t net_idx, uint16_t app_idx) +{ + btc_ble_mesh_prov_args_t arg = {0}; + btc_msg_t msg = {0}; + + if (app_key == NULL || net_idx > 0xFFF || app_idx > 0xFFF) { + 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_NODE_ADD_LOCAL_APP_KEY; + + arg.node_add_local_app_key.net_idx = net_idx; + arg.node_add_local_app_key.app_idx = app_idx; + memcpy(arg.node_add_local_app_key.app_key, app_key, 16); + + 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_node_bind_app_key_to_local_model(uint16_t element_addr, uint16_t model_id, + uint16_t company_id, uint16_t app_idx) +{ + btc_ble_mesh_prov_args_t arg = {0}; + btc_msg_t msg = {0}; + + if (!ESP_BLE_MESH_ADDR_IS_UNICAST(element_addr) || app_idx > 0xFFF) { + 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_NODE_BIND_APP_KEY_TO_MODEL; + + arg.node_local_mod_app_bind.element_addr = element_addr; + arg.node_local_mod_app_bind.model_id = model_id; + arg.node_local_mod_app_bind.company_id = company_id; + arg.node_local_mod_app_bind.app_idx = app_idx; + + 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_NODE */ diff --git a/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_local_data_operation_api.h b/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_local_data_operation_api.h index 7dd4f7a547..4cbffabdb2 100644 --- a/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_local_data_operation_api.h +++ b/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_local_data_operation_api.h @@ -142,6 +142,72 @@ esp_err_t esp_ble_mesh_model_subscribe_group_addr(uint16_t element_addr, uint16_ esp_err_t esp_ble_mesh_model_unsubscribe_group_addr(uint16_t element_addr, uint16_t company_id, uint16_t model_id, uint16_t group_addr); +/** + * @brief This function is called by Node to get the local NetKey. + * + * @param[in] net_idx: NetKey index. + * + * @return NetKey on success, or NULL on failure. + * + */ +const uint8_t *esp_ble_mesh_node_get_local_net_key(uint16_t net_idx); + +/** + * @brief This function is called by Node to get the local AppKey. + * + * @param[in] app_idx: AppKey index. + * + * @return AppKey on success, or NULL on failure. + * + */ +const uint8_t *esp_ble_mesh_node_get_local_app_key(uint16_t app_idx); + +/** + * @brief This function is called by Node to add a local NetKey. + * + * @param[in] net_key: NetKey to be added. + * @param[in] net_idx: NetKey Index. + * + * @note This function can only be called after the device is provisioned. + * + * @return ESP_OK on success or error code otherwise. + * + */ +esp_err_t esp_ble_mesh_node_add_local_net_key(const uint8_t net_key[16], uint16_t net_idx); + +/** + * @brief This function is called by Node to add a local AppKey. + * + * @param[in] app_key: AppKey to be added. + * @param[in] net_idx: NetKey Index. + * @param[in] app_idx: AppKey Index. + * + * @note The net_idx must be an existing one. + * This function can only be called after the device is provisioned. + * + * @return ESP_OK on success or error code otherwise. + * + */ +esp_err_t esp_ble_mesh_node_add_local_app_key(const uint8_t app_key[16], uint16_t net_idx, uint16_t app_idx); + +/** + * @brief This function is called by Node to bind AppKey to model locally. + * + * @param[in] element_addr: Node local element address + * @param[in] app_idx: Node local appkey index + * @param[in] model_id: Node local model id + * @param[in] company_id: Node local company id + * + * @note If going to bind app_key with local vendor model, the company_id + * shall be set to 0xFFFF. + * This function can only be called after the device is provisioned. + * + * @return ESP_OK on success or error code otherwise. + * + */ +esp_err_t esp_ble_mesh_node_bind_app_key_to_local_model(uint16_t element_addr, uint16_t app_idx, + uint16_t model_id, uint16_t company_id); + #ifdef __cplusplus } #endif 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 330f82096d..c2216a4bf9 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 @@ -821,6 +821,9 @@ typedef enum { ESP_BLE_MESH_NODE_PROXY_IDENTITY_ENABLE_COMP_EVT, /*!< Enable BLE Mesh Proxy Identity advertising completion event */ ESP_BLE_MESH_NODE_PROXY_GATT_ENABLE_COMP_EVT, /*!< Enable BLE Mesh GATT Proxy Service completion event */ ESP_BLE_MESH_NODE_PROXY_GATT_DISABLE_COMP_EVT, /*!< Disable BLE Mesh GATT Proxy Service completion event */ + ESP_BLE_MESH_NODE_ADD_LOCAL_NET_KEY_COMP_EVT, /*!< Node add NetKey locally completion event */ + ESP_BLE_MESH_NODE_ADD_LOCAL_APP_KEY_COMP_EVT, /*!< Node add AppKey locally completion event */ + ESP_BLE_MESH_NODE_BIND_APP_KEY_TO_MODEL_COMP_EVT, /*!< Node bind AppKey to model locally completion event */ ESP_BLE_MESH_PROVISIONER_PROV_ENABLE_COMP_EVT, /*!< Provisioner enable provisioning functionality completion event */ ESP_BLE_MESH_PROVISIONER_PROV_DISABLE_COMP_EVT, /*!< Provisioner disable provisioning functionality completion event */ ESP_BLE_MESH_PROVISIONER_RECV_UNPROV_ADV_PKT_EVT, /*!< Provisioner receives unprovisioned device beacon event */ @@ -988,6 +991,31 @@ typedef union { struct ble_mesh_proxy_gatt_disable_comp_param { int err_code; /*!< Indicate the result of disabling Mesh Proxy Service */ } node_proxy_gatt_disable_comp; /*!< Event parameter of ESP_BLE_MESH_NODE_PROXY_GATT_DISABLE_COMP_EVT */ + /** + * @brief ESP_BLE_MESH_NODE_ADD_LOCAL_NET_KEY_COMP_EVT + */ + struct ble_mesh_node_add_local_net_key_comp_param { + int err_code; /*!< Indicate the result of adding local NetKey by the node */ + uint16_t net_idx; /*!< NetKey Index */ + } node_add_net_key_comp; /*!< Event parameter of ESP_BLE_MESH_NODE_ADD_LOCAL_NET_KEY_COMP_EVT */ + /** + * @brief ESP_BLE_MESH_NODE_ADD_LOCAL_APP_KEY_COMP_EVT + */ + struct ble_mesh_node_add_local_app_key_comp_param { + int err_code; /*!< Indicate the result of adding local AppKey by the node */ + uint16_t net_idx; /*!< NetKey Index */ + uint16_t app_idx; /*!< AppKey Index */ + } node_add_app_key_comp; /*!< Event parameter of ESP_BLE_MESH_NODE_ADD_LOCAL_APP_KEY_COMP_EVT */ + /** + * @brief ESP_BLE_MESH_NODE_BIND_APP_KEY_TO_MODEL_COMP_EVT + */ + struct ble_mesh_node_bind_local_mod_app_comp_param { + int err_code; /*!< Indicate the result of binding AppKey with model by the node */ + uint16_t element_addr; /*!< Element address */ + uint16_t app_idx; /*!< AppKey Index */ + uint16_t company_id; /*!< Company ID */ + uint16_t model_id; /*!< Model ID */ + } node_bind_app_key_to_model_comp; /*!< Event parameter of ESP_BLE_MESH_NODE_BIND_APP_KEY_TO_MODEL_COMP_EVT */ /** * @brief ESP_BLE_MESH_PROVISIONER_RECV_UNPROV_ADV_PKT_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 1365aeced0..2a87d7a26f 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 @@ -641,6 +641,16 @@ static void btc_ble_mesh_reset_cb(void) btc_ble_mesh_prov_callback(NULL, ESP_BLE_MESH_NODE_PROV_RESET_EVT); return; } + +const uint8_t *btc_ble_mesh_node_get_local_net_key(uint16_t net_idx) +{ + return bt_mesh_node_get_local_net_key(net_idx); +} + +const uint8_t *btc_ble_mesh_node_get_local_app_key(uint16_t app_idx) +{ + return bt_mesh_node_get_local_app_key(app_idx); +} #endif /* CONFIG_BLE_MESH_NODE */ static void btc_ble_mesh_prov_register_complete_cb(int err_code) @@ -1763,6 +1773,34 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg) act = ESP_BLE_MESH_NODE_PROV_INPUT_STRING_COMP_EVT; param.node_prov_input_str_comp.err_code = bt_mesh_input_string(arg->input_string.string); break; + case BTC_BLE_MESH_ACT_NODE_ADD_LOCAL_NET_KEY: + act = ESP_BLE_MESH_NODE_ADD_LOCAL_NET_KEY_COMP_EVT; + param.node_add_net_key_comp.net_idx = arg->node_add_local_net_key.net_idx; + param.node_add_net_key_comp.err_code = + bt_mesh_node_local_net_key_add(arg->node_add_local_net_key.net_idx, + arg->node_add_local_net_key.net_key); + break; + case BTC_BLE_MESH_ACT_NODE_ADD_LOCAL_APP_KEY: + act = ESP_BLE_MESH_NODE_ADD_LOCAL_APP_KEY_COMP_EVT; + param.node_add_app_key_comp.net_idx = arg->node_add_local_app_key.net_idx; + param.node_add_app_key_comp.app_idx = arg->node_add_local_app_key.app_idx; + param.node_add_app_key_comp.err_code = + bt_mesh_node_local_app_key_add(arg->node_add_local_app_key.net_idx, + arg->node_add_local_app_key.app_idx, + arg->node_add_local_app_key.app_key); + break; + case BTC_BLE_MESH_ACT_NODE_BIND_APP_KEY_TO_MODEL: + act = ESP_BLE_MESH_NODE_BIND_APP_KEY_TO_MODEL_COMP_EVT; + param.node_bind_app_key_to_model_comp.element_addr = arg->node_local_mod_app_bind.element_addr; + param.node_bind_app_key_to_model_comp.model_id = arg->node_local_mod_app_bind.model_id; + param.node_bind_app_key_to_model_comp.company_id = arg->node_local_mod_app_bind.company_id; + param.node_bind_app_key_to_model_comp.app_idx = arg->node_local_mod_app_bind.app_idx; + param.node_bind_app_key_to_model_comp.err_code = + bt_mesh_node_bind_app_key_to_model(arg->node_local_mod_app_bind.element_addr, + arg->node_local_mod_app_bind.model_id, + arg->node_local_mod_app_bind.company_id, + arg->node_local_mod_app_bind.app_idx); + break; #endif /* CONFIG_BLE_MESH_NODE */ #if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \ CONFIG_BLE_MESH_GATT_PROXY_SERVER 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 eeb3782f5b..11e34c0192 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 @@ -39,6 +39,9 @@ typedef enum { BTC_BLE_MESH_ACT_PROXY_IDENTITY_ENABLE, BTC_BLE_MESH_ACT_PROXY_GATT_ENABLE, BTC_BLE_MESH_ACT_PROXY_GATT_DISABLE, + BTC_BLE_MESH_ACT_NODE_ADD_LOCAL_NET_KEY, + BTC_BLE_MESH_ACT_NODE_ADD_LOCAL_APP_KEY, + BTC_BLE_MESH_ACT_NODE_BIND_APP_KEY_TO_MODEL, BTC_BLE_MESH_ACT_PROVISIONER_READ_OOB_PUB_KEY, BTC_BLE_MESH_ACT_PROVISIONER_INPUT_STR, BTC_BLE_MESH_ACT_PROVISIONER_INPUT_NUM, @@ -110,6 +113,21 @@ typedef union { struct ble_mesh_set_device_name_args { char name[ESP_BLE_MESH_DEVICE_NAME_MAX_LEN + 1]; } set_device_name; + struct ble_mesh_node_add_local_net_key_args { + uint8_t net_key[16]; + uint16_t net_idx; + } node_add_local_net_key; + struct ble_mesh_node_add_local_app_key_args { + uint8_t app_key[16]; + uint16_t net_idx; + uint16_t app_idx; + } node_add_local_app_key; + struct ble_mesh_node_bind_local_mod_app_args { + uint16_t element_addr; + uint16_t company_id; + uint16_t model_id; + uint16_t app_idx; + } node_local_mod_app_bind; struct ble_mesh_provisioner_read_oob_pub_key_args { uint8_t link_idx; uint8_t pub_key_x[32]; @@ -296,6 +314,10 @@ void btc_ble_mesh_prov_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src); void btc_ble_mesh_model_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src); +const uint8_t *btc_ble_mesh_node_get_local_net_key(uint16_t net_idx); + +const uint8_t *btc_ble_mesh_node_get_local_app_key(uint16_t app_idx); + esp_ble_mesh_node_t *btc_ble_mesh_provisioner_get_node_with_uuid(const uint8_t uuid[16]); esp_ble_mesh_node_t *btc_ble_mesh_provisioner_get_node_with_addr(uint16_t unicast_addr); diff --git a/components/bt/esp_ble_mesh/mesh_core/local_operation.c b/components/bt/esp_ble_mesh/mesh_core/local_operation.c index e3c2c5051e..6a78989af5 100644 --- a/components/bt/esp_ble_mesh/mesh_core/local_operation.c +++ b/components/bt/esp_ble_mesh/mesh_core/local_operation.c @@ -119,3 +119,225 @@ int bt_mesh_model_unsubscribe_group_addr(u16_t elem_addr, u16_t cid, BT_INFO("Unsubscribe group address 0x%04x", group_addr); return 0; } + +#if CONFIG_BLE_MESH_NODE + +const u8_t *bt_mesh_node_get_local_net_key(u16_t net_idx) +{ + struct bt_mesh_subnet *sub = NULL; + + if (net_idx > 0xFFF) { + BT_ERR("Invalid NetKeyIndex 0x%04x", net_idx); + return NULL; + } + + sub = bt_mesh_subnet_get(net_idx); + if (!sub) { + BT_ERR("NetKey 0x%04x not exists", net_idx); + return NULL; + } + + return sub->kr_flag ? sub->keys[1].net : sub->keys[0].net; +} + +const u8_t *bt_mesh_node_get_local_app_key(u16_t app_idx) +{ + struct bt_mesh_app_key *key = NULL; + + if (app_idx > 0xFFF) { + BT_ERR("Invalid AppKeyIndex 0x%04x", app_idx); + return NULL; + } + + key = bt_mesh_app_key_find(app_idx); + if (!key) { + BT_ERR("AppKey 0x%04x not exists", app_idx); + return NULL; + } + + return key->updated ? key->keys[1].val : key->keys[0].val; +} + +int bt_mesh_node_local_net_key_add(u16_t net_idx, const u8_t net_key[16]) +{ + struct bt_mesh_subnet *sub = NULL; + int err = 0; + int i; + + if (net_idx > 0xFFF || net_key == NULL) { + BT_ERR("%s, Invalid parameter", __func__); + return -EINVAL; + } + + if (!bt_mesh_is_provisioned()) { + BT_ERR("Not provisioned, failed to add NetKey"); + return -EIO; + } + + sub = bt_mesh_subnet_get(net_idx); + if (sub) { + BT_WARN("NetKey 0x%04x already exists", net_idx); + return -EEXIST; + } + + for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { + if (bt_mesh.sub[i].net_idx != BLE_MESH_KEY_UNUSED) { + if ((bt_mesh.sub[i].kr_flag == false && + memcmp(bt_mesh.sub[i].keys[0].net, net_key, 16) == 0) || + (bt_mesh.sub[i].kr_flag == true && + memcmp(bt_mesh.sub[i].keys[1].net, net_key, 16) == 0)) { + BT_WARN("Key value %s already exists", bt_hex(net_key, 16)); + return -EEXIST; + } + } + } + + for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { + if (bt_mesh.sub[i].net_idx == BLE_MESH_KEY_UNUSED) { + sub = &bt_mesh.sub[i]; + break; + } + } + + if (sub == NULL) { + BT_ERR("NetKey is full!"); + return -ENOMEM; + } + + err = bt_mesh_net_keys_create(&sub->keys[0], net_key); + if (err) { + BT_ERR("Failed to create keys for NetKey 0x%04x", net_idx); + return -EIO; + } + + sub->net_idx = net_idx; + sub->kr_flag = false; + sub->kr_phase = BLE_MESH_KR_NORMAL; + if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER)) { + sub->node_id = BLE_MESH_NODE_IDENTITY_STOPPED; + } else { + sub->node_id = BLE_MESH_NODE_IDENTITY_NOT_SUPPORTED; + } + + if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { + BT_DBG("Storing NetKey persistently"); + bt_mesh_store_subnet(sub); + } + + /* Make sure we have valid beacon data to be sent */ + bt_mesh_net_beacon_update(sub); + + return 0; +} + +int bt_mesh_node_local_app_key_add(u16_t net_idx, u16_t app_idx, + const u8_t app_key[16]) +{ + struct bt_mesh_app_key *key = NULL; + + if (net_idx > 0xFFF || app_idx > 0xFFF || app_key == NULL) { + BT_ERR("%s, Invalid parameter", __func__); + return -EINVAL; + } + + if (!bt_mesh_is_provisioned()) { + BT_ERR("Not provisioned, failed to add AppKey"); + return -EIO; + } + + if (bt_mesh_subnet_get(net_idx) == NULL) { + BT_ERR("Subnet 0x%04x not exists", net_idx); + return -EIO; + } + + key = bt_mesh_app_key_find(app_idx); + if (key) { + BT_WARN("AppKey 0x%04x already exists", app_idx); + return -EEXIST; + } + + for (int i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) { + if (bt_mesh.app_keys[i].net_idx != BLE_MESH_KEY_UNUSED) { + if ((bt_mesh.app_keys[i].updated == false && + memcmp(bt_mesh.app_keys[i].keys[0].val, app_key, 16) == 0) || + (bt_mesh.app_keys[i].updated == true && + memcmp(bt_mesh.app_keys[i].keys[1].val, app_key, 16) == 0)) { + BT_WARN("Key value %s already exists", bt_hex(app_key, 16)); + return -EEXIST; + } + } + } + + key = bt_mesh_app_key_alloc(app_idx); + if (key) { + struct bt_mesh_app_keys *keys = &key->keys[0]; + + if (bt_mesh_app_id(app_key, &keys->id)) { + BT_ERR("Failed to generate AID"); + return -EIO; + } + + key->net_idx = net_idx; + key->app_idx = app_idx; + key->updated = false; + memcpy(keys->val, app_key, 16); + + if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { + BT_DBG("Storing AppKey persistently"); + bt_mesh_store_app_key(key); + } + + BT_INFO("Add AppKey 0x%04x, NetKeyIndex 0x%04x", app_idx, net_idx); + return 0; + } + + BT_ERR("AppKey is full!"); + return -ENOMEM; +} + +int bt_mesh_node_bind_app_key_to_model(u16_t elem_addr, u16_t mod_id, + u16_t cid, u16_t app_idx) +{ + struct bt_mesh_model *model = NULL; + int i; + + if (!bt_mesh_is_provisioned()) { + BT_ERR("Not provisioned, failed to bind AppKey"); + return -EIO; + } + + model = find_model(elem_addr, cid, mod_id); + if (model == NULL) { + BT_ERR("Bind, model(id 0x%04x, cid 0x%04x) not found", mod_id, cid); + return -ENODEV; + } + + if (bt_mesh_app_key_find(app_idx) == NULL) { + BT_ERR("Bind, AppKey 0x%03x not exists", app_idx); + return -ENODEV; + } + + for (i = 0; i < ARRAY_SIZE(model->keys); i++) { + if (model->keys[i] == app_idx) { + BT_WARN("Already bound to AppKey 0x%04x", app_idx); + return -EALREADY; + } + } + + for (i = 0; i < ARRAY_SIZE(model->keys); i++) { + if (model->keys[i] == BLE_MESH_KEY_UNUSED) { + model->keys[i] = app_idx; + if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { + bt_mesh_store_mod_bind(model); + } + + BT_INFO("Model(id 0x%04x, cid 0x%04x) bound to AppKey 0x%04x", mod_id, cid, app_idx); + return 0; + } + } + + BT_ERR("Model bound is full!"); + return -ENOMEM; +} + +#endif /* CONFIG_BLE_MESH_NODE */ diff --git a/components/bt/esp_ble_mesh/mesh_core/local_operation.h b/components/bt/esp_ble_mesh/mesh_core/local_operation.h index 3c51ec5021..bdfcda385e 100644 --- a/components/bt/esp_ble_mesh/mesh_core/local_operation.h +++ b/components/bt/esp_ble_mesh/mesh_core/local_operation.h @@ -22,6 +22,18 @@ int bt_mesh_model_subscribe_group_addr(u16_t elem_addr, u16_t mod_id, int bt_mesh_model_unsubscribe_group_addr(u16_t elem_addr, u16_t cid, u16_t mod_id, u16_t group_addr); +const u8_t *bt_mesh_node_get_local_net_key(u16_t net_idx); + +const u8_t *bt_mesh_node_get_local_app_key(u16_t app_idx); + +int bt_mesh_node_local_net_key_add(u16_t net_idx, const u8_t net_key[16]); + +int bt_mesh_node_local_app_key_add(u16_t net_idx, u16_t app_idx, + const u8_t app_key[16]); + +int bt_mesh_node_bind_app_key_to_model(u16_t elem_addr, u16_t mod_id, + u16_t cid, u16_t app_idx); + #ifdef __cplusplus } #endif