Merge branch 'feat/ble_mesh_node_local_data_func_v4.0' into 'release/v4.0'

ble_mesh: stack: Add node local netkey/appkey func (v4.0)

See merge request espressif/esp-idf!11364
This commit is contained in:
Island 2020-11-25 20:23:01 +08:00
commit 5630b17e11
7 changed files with 473 additions and 0 deletions

View File

@ -13,6 +13,7 @@
// limitations under the License.
#include <stdint.h>
#include <string.h>
#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 company_id,
uint16_t model_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 */

View File

@ -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] company_id: Node local company id
* @param[in] model_id: Node local model id
* @param[in] app_idx: Node local appkey index
*
* @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 company_id,
uint16_t model_id, uint16_t app_idx);
#ifdef __cplusplus
}
#endif

View File

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

View File

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

View File

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

View File

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

View File

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