diff --git a/components/bt/CMakeLists.txt b/components/bt/CMakeLists.txt index e9a2a0f4e..4ceb08b63 100644 --- a/components/bt/CMakeLists.txt +++ b/components/bt/CMakeLists.txt @@ -364,6 +364,7 @@ if(CONFIG_BT_ENABLED) "esp_ble_mesh/mesh_core/friend.c" "esp_ble_mesh/mesh_core/health_cli.c" "esp_ble_mesh/mesh_core/health_srv.c" + "esp_ble_mesh/mesh_core/local_operation.c" "esp_ble_mesh/mesh_core/lpn.c" "esp_ble_mesh/mesh_core/main.c" "esp_ble_mesh/mesh_core/net.c" 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 95a8039ff..943c91bff 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 @@ -75,3 +75,54 @@ const esp_ble_mesh_comp_t *esp_ble_mesh_get_composition_data(void) return btc_ble_mesh_comp_get(); } +esp_err_t esp_ble_mesh_model_subscribe_group_addr(uint16_t element_addr, uint16_t company_id, + uint16_t model_id, uint16_t group_addr) +{ + btc_ble_mesh_prov_args_t arg = {0}; + btc_msg_t msg = {0}; + + if (!ESP_BLE_MESH_ADDR_IS_UNICAST(element_addr) || + !ESP_BLE_MESH_ADDR_IS_GROUP(group_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_MODEL_SUBSCRIBE_GROUP_ADDR; + + arg.model_sub_group_addr.element_addr = element_addr; + arg.model_sub_group_addr.company_id = company_id; + arg.model_sub_group_addr.model_id = model_id; + arg.model_sub_group_addr.group_addr = group_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_model_unsubscribe_group_addr(uint16_t element_addr, uint16_t company_id, + uint16_t model_id, uint16_t group_addr) +{ + btc_ble_mesh_prov_args_t arg = {0}; + btc_msg_t msg = {0}; + + if (!ESP_BLE_MESH_ADDR_IS_UNICAST(element_addr) || + !ESP_BLE_MESH_ADDR_IS_GROUP(group_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_MODEL_UNSUBSCRIBE_GROUP_ADDR; + + arg.model_unsub_group_addr.element_addr = element_addr; + arg.model_unsub_group_addr.company_id = company_id; + arg.model_unsub_group_addr.model_id = model_id; + arg.model_unsub_group_addr.group_addr = group_addr; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} 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 df8e2428a..0cd702e69 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 @@ -108,6 +108,38 @@ esp_ble_mesh_model_t *esp_ble_mesh_find_sig_model(const esp_ble_mesh_elem_t *ele */ const esp_ble_mesh_comp_t *esp_ble_mesh_get_composition_data(void); +/** + * @brief A local model of node or Provisioner subscribes a group address. + * + * @note This function shall not be invoked before node is provisioned or Provisioner is enabled. + * + * @param[in] element_addr: Unicast address of the element to which the model belongs. + * @param[in] company_id: A 16-bit company identifier. + * @param[in] model_id: A 16-bit model identifier. + * @param[in] group_addr: The group address to be subscribed. + * + * @return ESP_OK on success or error code otherwise. + * + */ +esp_err_t esp_ble_mesh_model_subscribe_group_addr(uint16_t element_addr, uint16_t company_id, + uint16_t model_id, uint16_t group_addr); + +/** + * @brief A local model of node or Provisioner unsubscribes a group address. + * + * @note This function shall not be invoked before node is provisioned or Provisioner is enabled. + * + * @param[in] element_addr: Unicast address of the element to which the model belongs. + * @param[in] company_id: A 16-bit company identifier. + * @param[in] model_id: A 16-bit model identifier. + * @param[in] group_addr: The subscribed group address. + * + * @return ESP_OK on success or error code otherwise. + * + */ +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); + #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 8b7a30128..35916db12 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 @@ -58,6 +58,9 @@ typedef uint8_t esp_ble_mesh_octet16_t[ESP_BLE_MESH_OCTET16_LEN]; #define ESP_BLE_MESH_OCTET8_LEN 8 typedef uint8_t esp_ble_mesh_octet8_t[ESP_BLE_MESH_OCTET8_LEN]; +/*!< Invalid Company ID */ +#define ESP_BLE_MESH_CID_NVAL 0xFFFF + #define ESP_BLE_MESH_ADDR_UNASSIGNED 0x0000 #define ESP_BLE_MESH_ADDR_ALL_NODES 0xFFFF #define ESP_BLE_MESH_ADDR_PROXIES 0xFFFC @@ -844,6 +847,8 @@ typedef enum { ESP_BLE_MESH_PROXY_CLIENT_REMOVE_FILTER_ADDR_COMP_EVT, /*!< Proxy Client remove filter address completion event */ ESP_BLE_MESH_START_BLE_ADVERTISING_COMP_EVT, /*!< Start BLE advertising completion event */ ESP_BLE_MESH_STOP_BLE_ADVERTISING_COMP_EVT, /*!< Stop BLE advertising completion event */ + ESP_BLE_MESH_MODEL_SUBSCRIBE_GROUP_ADDR_COMP_EVT, /*!< Local model subscribes group address completion event */ + ESP_BLE_MESH_MODEL_UNSUBSCRIBE_GROUP_ADDR_COMP_EVT, /*!< Local model unsubscribes group address completion event */ ESP_BLE_MESH_DEINIT_MESH_COMP_EVT, /*!< De-initialize BLE Mesh stack completion event */ ESP_BLE_MESH_PROV_EVT_MAX, } esp_ble_mesh_prov_cb_event_t; @@ -1326,6 +1331,26 @@ typedef union { int err_code; /*!< Indicate the result of stopping BLE advertising */ uint8_t index; /*!< Index of the BLE advertising */ } stop_ble_advertising_comp; /*!< Event parameter of ESP_BLE_MESH_STOP_BLE_ADVERTISING_COMP_EVT */ + /** + * @brief ESP_BLE_MESH_MODEL_SUBSCRIBE_GROUP_ADDR_COMP_EVT + */ + struct ble_mesh_model_sub_group_addr_comp_param { + int err_code; /*!< Indicate the result of local model subscribing group address */ + uint16_t element_addr; /*!< Element address */ + uint16_t company_id; /*!< Company ID */ + uint16_t model_id; /*!< Model ID */ + uint16_t group_addr; /*!< Group Address */ + } model_sub_group_addr_comp; /*!< Event parameters of ESP_BLE_MESH_MODEL_SUBSCRIBE_GROUP_ADDR_COMP_EVT */ + /** + * @brief ESP_BLE_MESH_MODEL_UNSUBSCRIBE_GROUP_ADDR_COMP_EVT + */ + struct ble_mesh_model_unsub_group_addr_comp_param { + int err_code; /*!< Indicate the result of local model unsubscribing group address */ + uint16_t element_addr; /*!< Element address */ + uint16_t company_id; /*!< Company ID */ + uint16_t model_id; /*!< Model ID */ + uint16_t group_addr; /*!< Group Address */ + } model_unsub_group_addr_comp; /*!< Event parameters of ESP_BLE_MESH_MODEL_UNSUBSCRIBE_GROUP_ADDR_COMP_EVT */ /** * @brief ESP_BLE_MESH_DEINIT_MESH_COMP_EVT */ diff --git a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_config_model.c b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_config_model.c index f5bb75edb..36501553a 100644 --- a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_config_model.c +++ b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_config_model.c @@ -20,8 +20,6 @@ #include "cfg_cli.h" #include "esp_ble_mesh_config_model_api.h" -#define CID_NVAL 0xffff - extern s32_t config_msg_timeout; /* Configuration Client Model related functions */ 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 d4c063011..f0d4ea066 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 @@ -44,6 +44,7 @@ #include "time_scene_client.h" #include "client_common.h" #include "state_binding.h" +#include "local_operation.h" #include "esp_ble_mesh_common_api.h" #include "esp_ble_mesh_provisioning_api.h" @@ -1898,6 +1899,30 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg) bt_mesh_stop_ble_advertising(arg->stop_ble_advertising.index); break; #endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */ + case BTC_BLE_MESH_ACT_MODEL_SUBSCRIBE_GROUP_ADDR: + act = ESP_BLE_MESH_MODEL_SUBSCRIBE_GROUP_ADDR_COMP_EVT; + param.model_sub_group_addr_comp.element_addr = arg->model_sub_group_addr.element_addr; + param.model_sub_group_addr_comp.company_id = arg->model_sub_group_addr.company_id; + param.model_sub_group_addr_comp.model_id = arg->model_sub_group_addr.model_id; + param.model_sub_group_addr_comp.group_addr = arg->model_sub_group_addr.group_addr; + param.model_sub_group_addr_comp.err_code = + bt_mesh_model_subscribe_group_addr(arg->model_sub_group_addr.element_addr, + arg->model_sub_group_addr.company_id, + arg->model_sub_group_addr.model_id, + arg->model_sub_group_addr.group_addr); + break; + case BTC_BLE_MESH_ACT_MODEL_UNSUBSCRIBE_GROUP_ADDR: + act = ESP_BLE_MESH_MODEL_UNSUBSCRIBE_GROUP_ADDR_COMP_EVT; + param.model_unsub_group_addr_comp.element_addr = arg->model_unsub_group_addr.element_addr; + param.model_unsub_group_addr_comp.company_id = arg->model_unsub_group_addr.company_id; + param.model_unsub_group_addr_comp.model_id = arg->model_unsub_group_addr.model_id; + param.model_unsub_group_addr_comp.group_addr = arg->model_unsub_group_addr.group_addr; + param.model_unsub_group_addr_comp.err_code = + bt_mesh_model_unsubscribe_group_addr(arg->model_unsub_group_addr.element_addr, + arg->model_unsub_group_addr.company_id, + arg->model_unsub_group_addr.model_id, + arg->model_unsub_group_addr.group_addr); + break; case BTC_BLE_MESH_ACT_DEINIT_MESH: act = ESP_BLE_MESH_DEINIT_MESH_COMP_EVT; param.deinit_mesh_comp.err_code = bt_mesh_deinit((struct bt_mesh_deinit_param *)&arg->mesh_deinit.param); 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 62f52ccee..e56425f15 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 @@ -70,6 +70,8 @@ typedef enum { BTC_BLE_MESH_ACT_PROXY_CLIENT_REMOVE_FILTER_ADDR, BTC_BLE_MESH_ACT_START_BLE_ADVERTISING, BTC_BLE_MESH_ACT_STOP_BLE_ADVERTISING, + BTC_BLE_MESH_ACT_MODEL_SUBSCRIBE_GROUP_ADDR, + BTC_BLE_MESH_ACT_MODEL_UNSUBSCRIBE_GROUP_ADDR, BTC_BLE_MESH_ACT_DEINIT_MESH, } btc_ble_mesh_prov_act_t; @@ -249,6 +251,18 @@ typedef union { struct ble_mesh_stop_ble_advertising_args { uint8_t index; } stop_ble_advertising; + struct ble_mesh_model_sub_group_addr_args { + uint16_t element_addr; + uint16_t company_id; + uint16_t model_id; + uint16_t group_addr; + } model_sub_group_addr; + struct ble_mesh_model_unsub_group_addr_args { + uint16_t element_addr; + uint16_t company_id; + uint16_t model_id; + uint16_t group_addr; + } model_unsub_group_addr; struct ble_mesh_deinit_args { esp_ble_mesh_deinit_param_t param; } mesh_deinit; 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 3138079fd..0390f4923 100644 --- a/components/bt/esp_ble_mesh/mesh_core/cfg_cli.c +++ b/components/bt/esp_ble_mesh/mesh_core/cfg_cli.c @@ -20,8 +20,6 @@ #include "mesh_common.h" #include "cfg_cli.h" -#define CID_NVAL 0xffff - /* 2 byte dummy opcode for getting compile time buffer sizes. */ #define DUMMY_2_BYTE_OP BLE_MESH_MODEL_OP_2(0xff, 0xff) @@ -384,7 +382,7 @@ static void mod_app_status(struct bt_mesh_model *model, if (buf->len >= 4) { status.cid = net_buf_simple_pull_le16(buf); } else { - status.cid = CID_NVAL; + status.cid = BLE_MESH_CID_NVAL; } status.mod_id = net_buf_simple_pull_le16(buf); @@ -413,7 +411,7 @@ static void mod_pub_status(struct bt_mesh_model *model, if (buf->len >= 4) { status.cid = net_buf_simple_pull_le16(buf); } else { - status.cid = CID_NVAL; + status.cid = BLE_MESH_CID_NVAL; } status.mod_id = net_buf_simple_pull_le16(buf); @@ -436,7 +434,7 @@ static void mod_sub_status(struct bt_mesh_model *model, if (buf->len >= 4) { status.cid = net_buf_simple_pull_le16(buf); } else { - status.cid = CID_NVAL; + status.cid = BLE_MESH_CID_NVAL; } status.mod_id = net_buf_simple_pull_le16(buf); @@ -511,7 +509,7 @@ static void mod_sub_list(struct bt_mesh_model *model, if (ctx->recv_op == OP_MOD_SUB_LIST_VND) { list.cid = net_buf_simple_pull_le16(buf); } else { - list.cid = CID_NVAL; + list.cid = BLE_MESH_CID_NVAL; } list.mod_id = net_buf_simple_pull_le16(buf); @@ -599,7 +597,7 @@ static void mod_app_list(struct bt_mesh_model *model, if (ctx->recv_op == OP_VND_MOD_APP_LIST) { list.cid = net_buf_simple_pull_le16(buf); } else { - list.cid = CID_NVAL; + list.cid = BLE_MESH_CID_NVAL; } list.mod_id = net_buf_simple_pull_le16(buf); @@ -908,7 +906,7 @@ int bt_mesh_cfg_mod_app_bind(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr, bt_mesh_model_msg_init(&msg, OP_MOD_APP_BIND); net_buf_simple_add_le16(&msg, elem_addr); net_buf_simple_add_le16(&msg, mod_app_idx); - if (cid != CID_NVAL) { + if (cid != BLE_MESH_CID_NVAL) { net_buf_simple_add_le16(&msg, cid); } net_buf_simple_add_le16(&msg, mod_id); @@ -932,7 +930,7 @@ static int mod_sub(u32_t op, struct bt_mesh_msg_ctx *ctx, u16_t elem_addr, bt_mesh_model_msg_init(&msg, op); net_buf_simple_add_le16(&msg, elem_addr); net_buf_simple_add_le16(&msg, sub_addr); - if (cid != CID_NVAL) { + if (cid != BLE_MESH_CID_NVAL) { net_buf_simple_add_le16(&msg, cid); } net_buf_simple_add_le16(&msg, mod_id); @@ -986,7 +984,7 @@ static int mod_sub_va(u32_t op, struct bt_mesh_msg_ctx *ctx, u16_t elem_addr, bt_mesh_model_msg_init(&msg, op); net_buf_simple_add_le16(&msg, elem_addr); net_buf_simple_add_mem(&msg, label, 16); - if (cid != CID_NVAL) { + if (cid != BLE_MESH_CID_NVAL) { net_buf_simple_add_le16(&msg, cid); } net_buf_simple_add_le16(&msg, mod_id); @@ -1039,7 +1037,7 @@ int bt_mesh_cfg_mod_pub_get(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr, bt_mesh_model_msg_init(&msg, OP_MOD_PUB_GET); net_buf_simple_add_le16(&msg, elem_addr); - if (cid != CID_NVAL) { + if (cid != BLE_MESH_CID_NVAL) { net_buf_simple_add_le16(&msg, cid); } net_buf_simple_add_le16(&msg, mod_id); @@ -1072,7 +1070,7 @@ int bt_mesh_cfg_mod_pub_set(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr, net_buf_simple_add_u8(&msg, pub->ttl); net_buf_simple_add_u8(&msg, pub->period); net_buf_simple_add_u8(&msg, pub->transmit); - if (cid != CID_NVAL) { + if (cid != BLE_MESH_CID_NVAL) { net_buf_simple_add_le16(&msg, cid); } net_buf_simple_add_le16(&msg, mod_id); @@ -1221,7 +1219,7 @@ int bt_mesh_cfg_mod_pub_va_set(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr, net_buf_simple_add_u8(&msg, pub->ttl); net_buf_simple_add_u8(&msg, pub->period); net_buf_simple_add_u8(&msg, pub->transmit); - if (cid != CID_NVAL) { + if (cid != BLE_MESH_CID_NVAL) { net_buf_simple_add_le16(&msg, cid); } net_buf_simple_add_le16(&msg, mod_id); @@ -1248,7 +1246,7 @@ int bt_mesh_cfg_mod_sub_del_all(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr, bt_mesh_model_msg_init(&msg, OP_MOD_SUB_DEL_ALL); net_buf_simple_add_le16(&msg, elem_addr); - if (cid != CID_NVAL) { + if (cid != BLE_MESH_CID_NVAL) { net_buf_simple_add_le16(&msg, cid); } net_buf_simple_add_le16(&msg, mod_id); @@ -1271,7 +1269,7 @@ static int mod_sub_get(u32_t op, struct bt_mesh_msg_ctx *ctx, bt_mesh_model_msg_init(&msg, op); net_buf_simple_add_le16(&msg, elem_addr); - if (cid != CID_NVAL) { + if (cid != BLE_MESH_CID_NVAL) { net_buf_simple_add_le16(&msg, cid); } net_buf_simple_add_le16(&msg, mod_id); @@ -1290,13 +1288,13 @@ int bt_mesh_cfg_mod_sub_get(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr, u16_t if (!ctx || !ctx->addr) { return -EINVAL; } - return mod_sub_get(OP_MOD_SUB_GET, ctx, elem_addr, mod_id, CID_NVAL); + return mod_sub_get(OP_MOD_SUB_GET, ctx, elem_addr, mod_id, BLE_MESH_CID_NVAL); } int bt_mesh_cfg_mod_sub_get_vnd(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr, u16_t mod_id, u16_t cid) { - if (!ctx || !ctx->addr || cid == CID_NVAL) { + if (!ctx || !ctx->addr || cid == BLE_MESH_CID_NVAL) { return -EINVAL; } return mod_sub_get(OP_MOD_SUB_GET_VND, ctx, elem_addr, mod_id, cid); @@ -1487,7 +1485,7 @@ int bt_mesh_cfg_mod_app_unbind(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr, bt_mesh_model_msg_init(&msg, OP_MOD_APP_UNBIND); net_buf_simple_add_le16(&msg, elem_addr); net_buf_simple_add_le16(&msg, app_idx); - if (cid != CID_NVAL) { + if (cid != BLE_MESH_CID_NVAL) { net_buf_simple_add_le16(&msg, cid); } net_buf_simple_add_le16(&msg, mod_id); @@ -1510,7 +1508,7 @@ static int mod_app_get(u32_t op, struct bt_mesh_msg_ctx *ctx, bt_mesh_model_msg_init(&msg, op); net_buf_simple_add_le16(&msg, elem_addr); - if (cid != CID_NVAL) { + if (cid != BLE_MESH_CID_NVAL) { net_buf_simple_add_le16(&msg, cid); } net_buf_simple_add_le16(&msg, mod_id); @@ -1529,13 +1527,13 @@ int bt_mesh_cfg_mod_app_get(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr, u16_t if (!ctx || !ctx->addr) { return -EINVAL; } - return mod_app_get(OP_SIG_MOD_APP_GET, ctx, elem_addr, mod_id, CID_NVAL); + return mod_app_get(OP_SIG_MOD_APP_GET, ctx, elem_addr, mod_id, BLE_MESH_CID_NVAL); } int bt_mesh_cfg_mod_app_get_vnd(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr, u16_t mod_id, u16_t cid) { - if (!ctx || !ctx->addr || cid == CID_NVAL) { + if (!ctx || !ctx->addr || cid == BLE_MESH_CID_NVAL) { return -EINVAL; } return mod_app_get(OP_VND_MOD_APP_GET, ctx, elem_addr, mod_id, cid); diff --git a/components/bt/esp_ble_mesh/mesh_core/include/mesh_access.h b/components/bt/esp_ble_mesh/mesh_core/include/mesh_access.h index 99992dba3..dd3985a8d 100644 --- a/components/bt/esp_ble_mesh/mesh_core/include/mesh_access.h +++ b/components/bt/esp_ble_mesh/mesh_core/include/mesh_access.h @@ -26,6 +26,8 @@ extern "C" { #endif +#define BLE_MESH_CID_NVAL 0xFFFF + #define BLE_MESH_ADDR_UNASSIGNED 0x0000 #define BLE_MESH_ADDR_ALL_NODES 0xffff #define BLE_MESH_ADDR_PROXIES 0xfffc diff --git a/components/bt/esp_ble_mesh/mesh_core/local_operation.c b/components/bt/esp_ble_mesh/mesh_core/local_operation.c new file mode 100644 index 000000000..9e2ab3f5e --- /dev/null +++ b/components/bt/esp_ble_mesh/mesh_core/local_operation.c @@ -0,0 +1,121 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2017 Intel Corporation + * Additional Copyright (c) 2020 Espressif Systems (Shanghai) PTE LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include + +#include "mesh.h" +#include "lpn.h" +#include "crypto.h" +#include "access.h" +#include "foundation.h" +#include "transport.h" +#include "mesh_main.h" +#include "settings.h" + +static struct bt_mesh_model *find_model(u16_t elem_addr, u16_t cid, u16_t mod_id) +{ + struct bt_mesh_elem *elem = NULL; + + if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) { + BT_ERR("%s, Not a unicast address 0x%04x", __func__, elem_addr); + return NULL; + } + + elem = bt_mesh_elem_find(elem_addr); + if (elem == NULL) { + BT_ERR("%s, No element found, addr 0x%04x", __func__, elem_addr); + return NULL; + } + + if (cid == BLE_MESH_CID_NVAL) { + return bt_mesh_model_find(elem, mod_id); + } else { + return bt_mesh_model_find_vnd(elem, cid, mod_id); + } +} + +int bt_mesh_model_subscribe_group_addr(u16_t elem_addr, u16_t cid, + u16_t mod_id, u16_t group_addr) +{ + struct bt_mesh_model *model = NULL; + int i; + + model = find_model(elem_addr, cid, mod_id); + if (model == NULL) { + BT_ERR("Subscribe, model not found, cid 0x%04x, mod_id 0x%04x", cid, mod_id); + return -ENODEV; + } + + if (!BLE_MESH_ADDR_IS_GROUP(group_addr)) { + BT_ERR("Subscribe, not a group address 0x%04x", group_addr); + return -EINVAL; + } + + if (bt_mesh_model_find_group(model, group_addr)) { + BT_INFO("Group address 0x%04x already exists", group_addr); + return 0; + } + + for (i = 0; i < ARRAY_SIZE(model->groups); i++) { + if (model->groups[i] == BLE_MESH_ADDR_UNASSIGNED) { + model->groups[i] = group_addr; + + if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { + bt_mesh_store_mod_sub(model); + } + + if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER)) { + bt_mesh_lpn_group_add(group_addr); + } + + BT_INFO("Subscribe group address 0x%04x", group_addr); + return 0; + } + } + + BT_ERR("Subscribe, model sub is full!"); + return -ENOMEM; +} + +int bt_mesh_model_unsubscribe_group_addr(u16_t elem_addr, u16_t cid, + u16_t mod_id, u16_t group_addr) +{ + struct bt_mesh_model *model = NULL; + u16_t *match = NULL; + + model = find_model(elem_addr, cid, mod_id); + if (model == NULL) { + BT_ERR("Unsubscribe, model not found, cid 0x%04x, mod_id 0x%04x", cid, mod_id); + return -ENODEV; + } + + if (!BLE_MESH_ADDR_IS_GROUP(group_addr)) { + BT_ERR("Unsubscribe, not a group address 0x%04x", group_addr); + return -EINVAL; + } + + match = bt_mesh_model_find_group(model, group_addr); + if (match == NULL) { + BT_WARN("Group address 0x%04x not exists", group_addr); + return -EEXIST; + } + + *match = BLE_MESH_ADDR_UNASSIGNED; + + if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { + bt_mesh_store_mod_sub(model); + } + + if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER)) { + bt_mesh_lpn_group_del(&group_addr, 1); + } + + BT_INFO("Unsubscribe group address 0x%04x", group_addr); + return 0; +} diff --git a/components/bt/esp_ble_mesh/mesh_core/local_operation.h b/components/bt/esp_ble_mesh/mesh_core/local_operation.h new file mode 100644 index 000000000..3c51ec502 --- /dev/null +++ b/components/bt/esp_ble_mesh/mesh_core/local_operation.h @@ -0,0 +1,29 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2017 Intel Corporation + * Additional Copyright (c) 2020 Espressif Systems (Shanghai) PTE LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _LOCAL_OPERATION_H_ +#define _LOCAL_OPERATION_H_ + +#include "mesh_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int bt_mesh_model_subscribe_group_addr(u16_t elem_addr, u16_t mod_id, + u16_t cid, u16_t group_addr); + +int bt_mesh_model_unsubscribe_group_addr(u16_t elem_addr, u16_t cid, + u16_t mod_id, u16_t group_addr); + +#ifdef __cplusplus +} +#endif + +#endif /* _LOCAL_OPERATION_H_ */ diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/fast_prov_client/main/main.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/fast_prov_client/main/main.c index 1770ffbcb..7b590d312 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/fast_prov_client/main/main.c +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/fast_prov_client/main/main.c @@ -288,7 +288,7 @@ static void example_provisioning_callback(esp_ble_mesh_prov_cb_event_t event, esp_err_t err; prov_info.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_info.app_idx, - ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_CLI, CID_NVAL); + ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_CLI, ESP_BLE_MESH_CID_NVAL); if (err != ESP_OK) { ESP_LOGE(TAG, "%s: Failed to bind AppKey with OnOff Client Model", __func__); return; diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/fast_prov_client/tutorial/BLE_Mesh_Fast_Prov_Client_Example_Walkthrough.md b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/fast_prov_client/tutorial/BLE_Mesh_Fast_Prov_Client_Example_Walkthrough.md index 60d27304e..dea6469b6 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/fast_prov_client/tutorial/BLE_Mesh_Fast_Prov_Client_Example_Walkthrough.md +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/fast_prov_client/tutorial/BLE_Mesh_Fast_Prov_Client_Example_Walkthrough.md @@ -101,7 +101,7 @@ To control the server model, the client model uses messages to control the serve ```c prov_info.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_info.app_idx, - ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_CLI, CID_NVAL); + ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_CLI, ESP_BLE_MESH_CID_NVAL); if (err != ESP_OK) { ESP_LOGE(TAG, "%s: Failed to bind AppKey with OnOff Client Model", __func__); return; diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/main/main.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/main/main.c index 18ff3c449..7521adb1c 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/main/main.c +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_provisioner/main/main.c @@ -25,7 +25,6 @@ #define LED_ON 0x1 #define CID_ESP 0x02E5 -#define CID_NVAL 0xFFFF #define PROV_OWN_ADDR 0x0001 @@ -323,7 +322,7 @@ static void example_ble_mesh_provisioning_cb(esp_ble_mesh_prov_cb_event_t event, 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, - ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_CLI, CID_NVAL); + ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_CLI, ESP_BLE_MESH_CID_NVAL); if (err != ESP_OK) { ESP_LOGE(TAG, "Provisioner bind local model appkey failed"); return; @@ -397,7 +396,7 @@ static void example_ble_mesh_config_client_cb(esp_ble_mesh_cfg_client_cb_event_t set_state.model_app_bind.element_addr = node->unicast; set_state.model_app_bind.model_app_idx = prov_key.app_idx; set_state.model_app_bind.model_id = ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_SRV; - set_state.model_app_bind.company_id = CID_NVAL; + set_state.model_app_bind.company_id = ESP_BLE_MESH_CID_NVAL; err = esp_ble_mesh_config_client_set_state(&common, &set_state); if (err) { ESP_LOGE(TAG, "%s: Config Model App Bind failed", __func__); @@ -463,7 +462,7 @@ static void example_ble_mesh_config_client_cb(esp_ble_mesh_cfg_client_cb_event_t set_state.model_app_bind.element_addr = node->unicast; set_state.model_app_bind.model_app_idx = prov_key.app_idx; set_state.model_app_bind.model_id = ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_SRV; - set_state.model_app_bind.company_id = CID_NVAL; + set_state.model_app_bind.company_id = ESP_BLE_MESH_CID_NVAL; err = esp_ble_mesh_config_client_set_state(&common, &set_state); if (err) { ESP_LOGE(TAG, "%s: Config Model App Bind failed", __func__); diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_sensor_model/sensor_client/main/main.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_sensor_model/sensor_client/main/main.c index 31a8a825d..60e7d9c55 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_sensor_model/sensor_client/main/main.c +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_sensor_model/sensor_client/main/main.c @@ -23,7 +23,6 @@ #include "board.h" #define CID_ESP 0x02E5 -#define CID_NVAL 0xFFFF #define PROV_OWN_ADDR 0x0001 @@ -225,7 +224,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 == 0) { prov_key.app_idx = param->provisioner_add_app_key_comp.app_idx; esp_err_t err = esp_ble_mesh_provisioner_bind_app_key_to_local_model(PROV_OWN_ADDR, prov_key.app_idx, - ESP_BLE_MESH_MODEL_ID_SENSOR_CLI, CID_NVAL); + ESP_BLE_MESH_MODEL_ID_SENSOR_CLI, ESP_BLE_MESH_CID_NVAL); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to bind AppKey to sensor client"); } @@ -334,31 +333,31 @@ static void example_ble_mesh_config_client_cb(esp_ble_mesh_cfg_client_cb_event_t set.model_app_bind.element_addr = node->unicast_addr; set.model_app_bind.model_app_idx = prov_key.app_idx; set.model_app_bind.model_id = ESP_BLE_MESH_MODEL_ID_SENSOR_SRV; - set.model_app_bind.company_id = CID_NVAL; + set.model_app_bind.company_id = ESP_BLE_MESH_CID_NVAL; err = esp_ble_mesh_config_client_set_state(&common, &set); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to send Config Model App Bind"); return; } wait_model_id = ESP_BLE_MESH_MODEL_ID_SENSOR_SRV; - wait_cid = CID_NVAL; + wait_cid = ESP_BLE_MESH_CID_NVAL; } else if (param->params->opcode == ESP_BLE_MESH_MODEL_OP_MODEL_APP_BIND) { if (param->status_cb.model_app_status.model_id == ESP_BLE_MESH_MODEL_ID_SENSOR_SRV && - param->status_cb.model_app_status.company_id == CID_NVAL) { + param->status_cb.model_app_status.company_id == ESP_BLE_MESH_CID_NVAL) { example_ble_mesh_set_msg_common(&common, node, config_client.model, ESP_BLE_MESH_MODEL_OP_MODEL_APP_BIND); set.model_app_bind.element_addr = node->unicast_addr; set.model_app_bind.model_app_idx = prov_key.app_idx; set.model_app_bind.model_id = ESP_BLE_MESH_MODEL_ID_SENSOR_SETUP_SRV; - set.model_app_bind.company_id = CID_NVAL; + set.model_app_bind.company_id = ESP_BLE_MESH_CID_NVAL; err = esp_ble_mesh_config_client_set_state(&common, &set); if (err) { ESP_LOGE(TAG, "Failed to send Config Model App Bind"); return; } wait_model_id = ESP_BLE_MESH_MODEL_ID_SENSOR_SETUP_SRV; - wait_cid = CID_NVAL; + wait_cid = ESP_BLE_MESH_CID_NVAL; } else if (param->status_cb.model_app_status.model_id == ESP_BLE_MESH_MODEL_ID_SENSOR_SETUP_SRV && - param->status_cb.model_app_status.company_id == CID_NVAL) { + param->status_cb.model_app_status.company_id == ESP_BLE_MESH_CID_NVAL) { ESP_LOGW(TAG, "Provision and config successfully"); } } diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_sensor_model/sensor_server/main/main.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_sensor_model/sensor_server/main/main.c index 7573cdba6..f0f1bfb13 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_sensor_model/sensor_server/main/main.c +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_sensor_model/sensor_server/main/main.c @@ -24,7 +24,6 @@ #include "board.h" #define CID_ESP 0x02E5 -#define CID_NVAL 0xFFFF /* Sensor Property ID */ #define SENSOR_PROPERTY_ID_0 0x0056 /* Present Indoor Ambient Temperature */ diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_vendor_model/vendor_client/main/main.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_vendor_model/vendor_client/main/main.c index 1c5fd7e3c..8249c008b 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_vendor_model/vendor_client/main/main.c +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_vendor_model/vendor_client/main/main.c @@ -23,7 +23,6 @@ #include "board.h" #define CID_ESP 0x02E5 -#define CID_NVAL 0xFFFF #define PROV_OWN_ADDR 0x0001 diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_vendor_model/vendor_server/main/main.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_vendor_model/vendor_server/main/main.c index 94d0e36d6..af91c84bd 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_vendor_model/vendor_server/main/main.c +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_vendor_model/vendor_server/main/main.c @@ -25,7 +25,6 @@ #include "ble_mesh_example_init.h" #define CID_ESP 0x02E5 -#define CID_NVAL 0xFFFF #define ESP_BLE_MESH_VND_MODEL_ID_CLIENT 0x0000 #define ESP_BLE_MESH_VND_MODEL_ID_SERVER 0x0001 diff --git a/examples/bluetooth/esp_ble_mesh/common_components/fast_provisioning/ble_mesh_fast_prov_client_model.c b/examples/bluetooth/esp_ble_mesh/common_components/fast_provisioning/ble_mesh_fast_prov_client_model.c index da3e6c200..b04f5becd 100644 --- a/examples/bluetooth/esp_ble_mesh/common_components/fast_provisioning/ble_mesh_fast_prov_client_model.c +++ b/examples/bluetooth/esp_ble_mesh/common_components/fast_provisioning/ble_mesh_fast_prov_client_model.c @@ -379,7 +379,7 @@ esp_err_t example_fast_prov_client_recv_status(esp_ble_mesh_model_t *model, return ESP_FAIL; } cli_model = example_find_model(esp_ble_mesh_get_primary_element_address(), - ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_CLI, CID_NVAL); + ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_CLI, ESP_BLE_MESH_CID_NVAL); if (!cli_model) { ESP_LOGE(TAG, "%s: Failed to get Generic OnOff Client Model info", __func__); return ESP_FAIL; diff --git a/examples/bluetooth/esp_ble_mesh/common_components/fast_provisioning/ble_mesh_fast_prov_common.h b/examples/bluetooth/esp_ble_mesh/common_components/fast_provisioning/ble_mesh_fast_prov_common.h index b888d6030..f4588db44 100644 --- a/examples/bluetooth/esp_ble_mesh/common_components/fast_provisioning/ble_mesh_fast_prov_common.h +++ b/examples/bluetooth/esp_ble_mesh/common_components/fast_provisioning/ble_mesh_fast_prov_common.h @@ -22,7 +22,6 @@ #define LED_ON 0x01 #define CID_ESP 0x02E5 -#define CID_NVAL 0xFFFF /* Fast Prov Model ID */ #define ESP_BLE_MESH_VND_MODEL_ID_FAST_PROV_CLI 0x0000 diff --git a/examples/bluetooth/esp_ble_mesh/common_components/fast_provisioning/ble_mesh_fast_prov_operation.c b/examples/bluetooth/esp_ble_mesh/common_components/fast_provisioning/ble_mesh_fast_prov_operation.c index 2664caeaf..5f1f0a89b 100644 --- a/examples/bluetooth/esp_ble_mesh/common_components/fast_provisioning/ble_mesh_fast_prov_operation.c +++ b/examples/bluetooth/esp_ble_mesh/common_components/fast_provisioning/ble_mesh_fast_prov_operation.c @@ -150,7 +150,7 @@ esp_ble_mesh_model_t *example_find_model(uint16_t element_addr, uint16_t model_i return NULL; } - if (company_id == CID_NVAL) { + if (company_id == ESP_BLE_MESH_CID_NVAL) { return esp_ble_mesh_find_sig_model(element, model_id); } else { return esp_ble_mesh_find_vendor_model(element, company_id, model_id); diff --git a/examples/bluetooth/esp_ble_mesh/common_components/fast_provisioning/ble_mesh_fast_prov_server_model.c b/examples/bluetooth/esp_ble_mesh/common_components/fast_provisioning/ble_mesh_fast_prov_server_model.c index ec0ff2f4b..63b5e7e86 100644 --- a/examples/bluetooth/esp_ble_mesh/common_components/fast_provisioning/ble_mesh_fast_prov_server_model.c +++ b/examples/bluetooth/esp_ble_mesh/common_components/fast_provisioning/ble_mesh_fast_prov_server_model.c @@ -62,7 +62,7 @@ esp_ble_mesh_cfg_srv_t *get_cfg_srv_user_data(void) esp_ble_mesh_model_t *model = NULL; model = example_find_model(esp_ble_mesh_get_primary_element_address(), - ESP_BLE_MESH_MODEL_ID_CONFIG_SRV, CID_NVAL); + ESP_BLE_MESH_MODEL_ID_CONFIG_SRV, ESP_BLE_MESH_CID_NVAL); if (!model) { ESP_LOGE(TAG, "%s: Failed to get config server model", __func__); return NULL;