ble_mesh: Local model (un)subscribes group address

This commit is contained in:
lly 2020-04-14 10:17:52 +08:00
parent 11cfb44e58
commit cd40f3ad52
8 changed files with 295 additions and 0 deletions

View file

@ -348,6 +348,7 @@ if(CONFIG_BT_ENABLED)
"esp_ble_mesh/mesh_core/friend.c" "esp_ble_mesh/mesh_core/friend.c"
"esp_ble_mesh/mesh_core/health_cli.c" "esp_ble_mesh/mesh_core/health_cli.c"
"esp_ble_mesh/mesh_core/health_srv.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/lpn.c"
"esp_ble_mesh/mesh_core/main.c" "esp_ble_mesh/mesh_core/main.c"
"esp_ble_mesh/mesh_core/net.c" "esp_ble_mesh/mesh_core/net.c"

View file

@ -75,3 +75,54 @@ const esp_ble_mesh_comp_t *esp_ble_mesh_get_composition_data(void)
return btc_ble_mesh_comp_get(); 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);
}

View file

@ -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); 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 #ifdef __cplusplus
} }
#endif #endif

View file

@ -847,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_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_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_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_DEINIT_MESH_COMP_EVT, /*!< De-initialize BLE Mesh stack completion event */
ESP_BLE_MESH_PROV_EVT_MAX, ESP_BLE_MESH_PROV_EVT_MAX,
} esp_ble_mesh_prov_cb_event_t; } esp_ble_mesh_prov_cb_event_t;
@ -1329,6 +1331,26 @@ typedef union {
int err_code; /*!< Indicate the result of stopping BLE advertising */ int err_code; /*!< Indicate the result of stopping BLE advertising */
uint8_t index; /*!< Index of the 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 */ } 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 * @brief ESP_BLE_MESH_DEINIT_MESH_COMP_EVT
*/ */

View file

@ -44,6 +44,7 @@
#include "time_scene_client.h" #include "time_scene_client.h"
#include "client_common.h" #include "client_common.h"
#include "state_binding.h" #include "state_binding.h"
#include "local_operation.h"
#include "esp_ble_mesh_common_api.h" #include "esp_ble_mesh_common_api.h"
#include "esp_ble_mesh_provisioning_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); bt_mesh_stop_ble_advertising(arg->stop_ble_advertising.index);
break; break;
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */ #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: case BTC_BLE_MESH_ACT_DEINIT_MESH:
act = ESP_BLE_MESH_DEINIT_MESH_COMP_EVT; 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); param.deinit_mesh_comp.err_code = bt_mesh_deinit((struct bt_mesh_deinit_param *)&arg->mesh_deinit.param);

View file

@ -70,6 +70,8 @@ typedef enum {
BTC_BLE_MESH_ACT_PROXY_CLIENT_REMOVE_FILTER_ADDR, BTC_BLE_MESH_ACT_PROXY_CLIENT_REMOVE_FILTER_ADDR,
BTC_BLE_MESH_ACT_START_BLE_ADVERTISING, BTC_BLE_MESH_ACT_START_BLE_ADVERTISING,
BTC_BLE_MESH_ACT_STOP_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_ACT_DEINIT_MESH,
} btc_ble_mesh_prov_act_t; } btc_ble_mesh_prov_act_t;
@ -249,6 +251,18 @@ typedef union {
struct ble_mesh_stop_ble_advertising_args { struct ble_mesh_stop_ble_advertising_args {
uint8_t index; uint8_t index;
} stop_ble_advertising; } 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 { struct ble_mesh_deinit_args {
esp_ble_mesh_deinit_param_t param; esp_ble_mesh_deinit_param_t param;
} mesh_deinit; } mesh_deinit;

View file

@ -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 <string.h>
#include <errno.h>
#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;
}

View file

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