From 5de452e12a9891a983b990e66cd625da583e324f Mon Sep 17 00:00:00 2001 From: Liu Linyan Date: Thu, 28 Sep 2023 10:44:06 +0800 Subject: [PATCH] feat(ble_mesh): Use a separate file for heartbeat handling --- components/bt/CMakeLists.txt | 1 + .../bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c | 13 +- components/bt/esp_ble_mesh/core/cfg_srv.c | 36 +-- components/bt/esp_ble_mesh/core/foundation.h | 2 - components/bt/esp_ble_mesh/core/heartbeat.c | 298 ++++++++++++++++++ components/bt/esp_ble_mesh/core/heartbeat.h | 43 +++ components/bt/esp_ble_mesh/core/lpn.c | 1 + components/bt/esp_ble_mesh/core/pvnr_mgmt.c | 177 ----------- components/bt/esp_ble_mesh/core/pvnr_mgmt.h | 14 - components/bt/esp_ble_mesh/core/transport.c | 210 +++++------- components/bt/esp_ble_mesh/core/transport.h | 14 +- .../models/client/client_common.c | 4 +- 12 files changed, 434 insertions(+), 379 deletions(-) create mode 100644 components/bt/esp_ble_mesh/core/heartbeat.c create mode 100644 components/bt/esp_ble_mesh/core/heartbeat.h diff --git a/components/bt/CMakeLists.txt b/components/bt/CMakeLists.txt index 616d01c2d5..c284a54a55 100644 --- a/components/bt/CMakeLists.txt +++ b/components/bt/CMakeLists.txt @@ -487,6 +487,7 @@ if(CONFIG_BT_ENABLED) "esp_ble_mesh/core/friend.c" "esp_ble_mesh/core/health_cli.c" "esp_ble_mesh/core/health_srv.c" + "esp_ble_mesh/core/heartbeat.c" "esp_ble_mesh/core/local.c" "esp_ble_mesh/core/lpn.c" "esp_ble_mesh/core/main.c" 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 927e923ec5..826fbf02c1 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 @@ -37,6 +37,7 @@ #include "proxy_client.h" #include "prov_pvnr.h" #include "pvnr_mgmt.h" +#include "heartbeat.h" #if CONFIG_BLE_MESH_CFG_CLI #include "mesh/cfg_cli.h" @@ -2550,14 +2551,14 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg) act = ESP_BLE_MESH_PROVISIONER_ENABLE_HEARTBEAT_RECV_COMP_EVT; param.provisioner_enable_heartbeat_recv_comp.enable = arg->enable_heartbeat_recv.enable; param.provisioner_enable_heartbeat_recv_comp.err_code = - bt_mesh_provisioner_recv_heartbeat(arg->enable_heartbeat_recv.enable ? - btc_ble_mesh_provisioner_recv_heartbeat_cb : NULL); + bt_mesh_pvnr_register_hb_recv_cb(arg->enable_heartbeat_recv.enable ? + btc_ble_mesh_provisioner_recv_heartbeat_cb : NULL); break; case BTC_BLE_MESH_ACT_PROVISIONER_SET_HEARTBEAT_FILTER_TYPE: act = ESP_BLE_MESH_PROVISIONER_SET_HEARTBEAT_FILTER_TYPE_COMP_EVT; param.provisioner_set_heartbeat_filter_type_comp.type = arg->set_heartbeat_filter_type.type; param.provisioner_set_heartbeat_filter_type_comp.err_code = - bt_mesh_provisioner_set_heartbeat_filter_type(arg->set_heartbeat_filter_type.type); + bt_mesh_pvnr_set_hb_recv_filter_type(arg->set_heartbeat_filter_type.type); break; case BTC_BLE_MESH_ACT_PROVISIONER_SET_HEARTBEAT_FILTER_INFO: act = ESP_BLE_MESH_PROVISIONER_SET_HEARTBEAT_FILTER_INFO_COMP_EVT; @@ -2565,9 +2566,9 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg) param.provisioner_set_heartbeat_filter_info_comp.hb_src = arg->set_heartbeat_filter_info.hb_src; param.provisioner_set_heartbeat_filter_info_comp.hb_dst = arg->set_heartbeat_filter_info.hb_dst; param.provisioner_set_heartbeat_filter_info_comp.err_code = - bt_mesh_provisioner_set_heartbeat_filter_info(arg->set_heartbeat_filter_info.op, - arg->set_heartbeat_filter_info.hb_src, - arg->set_heartbeat_filter_info.hb_dst); + bt_mesh_pvnr_set_hb_recv_filter_info(arg->set_heartbeat_filter_info.op, + arg->set_heartbeat_filter_info.hb_src, + arg->set_heartbeat_filter_info.hb_dst); break; #endif /* CONFIG_BLE_MESH_PROVISIONER_RECV_HB */ #if CONFIG_BLE_MESH_SETTINGS diff --git a/components/bt/esp_ble_mesh/core/cfg_srv.c b/components/bt/esp_ble_mesh/core/cfg_srv.c index 5e77a7a589..614387405c 100644 --- a/components/bt/esp_ble_mesh/core/cfg_srv.c +++ b/components/bt/esp_ble_mesh/core/cfg_srv.c @@ -28,6 +28,7 @@ #include "proxy_server.h" #include "mesh/main.h" #include "mesh/common.h" +#include "heartbeat.h" #include "mesh_v1.1/utils.h" @@ -3565,41 +3566,6 @@ void bt_mesh_cfg_reset(bool store) (void)memset(labels, 0, sizeof(labels)); } -void bt_mesh_heartbeat(uint16_t src, uint16_t dst, uint8_t hops, uint16_t feat) -{ - struct bt_mesh_cfg_srv *cfg = conf; - - if (!cfg) { - BT_WARN("No configuration server context available"); - return; - } - - if (src != cfg->hb_sub.src || dst != cfg->hb_sub.dst) { - BT_WARN("No subscription for received heartbeat"); - return; - } - - if (k_uptime_get() > cfg->hb_sub.expiry) { - BT_WARN("Heartbeat subscription period expired"); - return; - } - - cfg->hb_sub.min_hops = MIN(cfg->hb_sub.min_hops, hops); - cfg->hb_sub.max_hops = MAX(cfg->hb_sub.max_hops, hops); - - if (cfg->hb_sub.count < 0xffff) { - cfg->hb_sub.count++; - } - - BT_DBG("src 0x%04x dst 0x%04x hops %u min %u max %u count %u", src, - dst, hops, cfg->hb_sub.min_hops, cfg->hb_sub.max_hops, - cfg->hb_sub.count); - - if (cfg->hb_sub.func) { - cfg->hb_sub.func(hops, feat); - } -} - uint8_t bt_mesh_net_transmit_get(void) { if (conf) { diff --git a/components/bt/esp_ble_mesh/core/foundation.h b/components/bt/esp_ble_mesh/core/foundation.h index 53b70f6980..0a07e70b02 100644 --- a/components/bt/esp_ble_mesh/core/foundation.h +++ b/components/bt/esp_ble_mesh/core/foundation.h @@ -266,8 +266,6 @@ void bt_mesh_mod_sub_reset(bool store); void bt_mesh_cfg_reset(bool store); -void bt_mesh_heartbeat(uint16_t src, uint16_t dst, uint8_t hops, uint16_t feat); - void bt_mesh_attention(struct bt_mesh_model *model, uint8_t time); struct label *get_label(uint16_t index); diff --git a/components/bt/esp_ble_mesh/core/heartbeat.c b/components/bt/esp_ble_mesh/core/heartbeat.c new file mode 100644 index 0000000000..4ff63a13ab --- /dev/null +++ b/components/bt/esp_ble_mesh/core/heartbeat.c @@ -0,0 +1,298 @@ +/* + * SPDX-FileCopyrightText: 2017 Intel Corporation + * SPDX-FileContributor: 2018-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include "lpn.h" +#include "mesh.h" +#include "mesh/main.h" +#include "access.h" +#include "foundation.h" +#include "transport.h" +#include "heartbeat.h" +#include "mesh/cfg_srv.h" + +static uint16_t hb_sub_dst = BLE_MESH_ADDR_UNASSIGNED; + +void bt_mesh_set_hb_sub_dst(uint16_t addr) +{ + hb_sub_dst = addr; +} + +uint16_t bt_mesh_get_hb_sub_dst(void) +{ + return hb_sub_dst; +} + +void bt_mesh_heartbeat_recv(uint16_t src, uint16_t dst, uint8_t hops, uint16_t feat) +{ + struct bt_mesh_cfg_srv *cfg = bt_mesh_cfg_get(); + + if (cfg == NULL) { + BT_WARN("No configuration server context available"); + return; + } + + if (src != cfg->hb_sub.src || dst != cfg->hb_sub.dst) { + BT_WARN("No subscription for received heartbeat"); + return; + } + + if (k_uptime_get() > cfg->hb_sub.expiry) { + BT_WARN("Heartbeat subscription period expired"); + return; + } + + cfg->hb_sub.min_hops = MIN(cfg->hb_sub.min_hops, hops); + cfg->hb_sub.max_hops = MAX(cfg->hb_sub.max_hops, hops); + + if (cfg->hb_sub.count < 0xffff) { + cfg->hb_sub.count++; + } + + BT_DBG("src 0x%04x dst 0x%04x hops %u min %u max %u count %u", src, + dst, hops, cfg->hb_sub.min_hops, cfg->hb_sub.max_hops, + cfg->hb_sub.count); + + if (cfg->hb_sub.func) { + cfg->hb_sub.func(hops, feat); + } +} + +void bt_mesh_heartbeat_send(void) +{ + struct bt_mesh_cfg_srv *cfg = bt_mesh_cfg_get(); + uint16_t feat = 0U; + struct __attribute__((packed)) { + uint8_t init_ttl; + uint16_t feat; + } hb; + struct bt_mesh_msg_ctx ctx = { + .net_idx = cfg->hb_pub.net_idx, + .app_idx = BLE_MESH_KEY_UNUSED, + .addr = cfg->hb_pub.dst, + .send_ttl = cfg->hb_pub.ttl, + .send_cred = BLE_MESH_FLOODING_CRED, + }; + struct bt_mesh_net_tx tx = { + .sub = bt_mesh_subnet_get(cfg->hb_pub.net_idx), + .ctx = &ctx, + .src = bt_mesh_model_elem(cfg->model)->addr, + .xmit = bt_mesh_net_transmit_get(), + }; + + /* Do nothing if heartbeat publication is not enabled */ + if (cfg->hb_pub.dst == BLE_MESH_ADDR_UNASSIGNED) { + return; + } + + hb.init_ttl = cfg->hb_pub.ttl; + + if (bt_mesh_relay_get() == BLE_MESH_RELAY_ENABLED) { + feat |= BLE_MESH_FEAT_RELAY; + } + + if (bt_mesh_gatt_proxy_get() == BLE_MESH_GATT_PROXY_ENABLED) { + feat |= BLE_MESH_FEAT_PROXY; + } + + if (bt_mesh_friend_get() == BLE_MESH_FRIEND_ENABLED) { + feat |= BLE_MESH_FEAT_FRIEND; + } + + if (bt_mesh_lpn_established()) { + feat |= BLE_MESH_FEAT_LOW_POWER; + } + + hb.feat = sys_cpu_to_be16(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); +} + +#if CONFIG_BLE_MESH_PROVISIONER_RECV_HB + +#define HEARTBEAT_FILTER_ACCEPTLIST 0x00 +#define HEARTBEAT_FILTER_REJECTLIST 0x01 + +#define HEARTBEAT_FILTER_ADD 0x00 +#define HEARTBEAT_FILTER_REMOVE 0x01 + +static struct heartbeat_recv { + struct heartbeat_filter { + uint16_t src; /* Heartbeat SRC (unicast address) */ + uint16_t dst; /* Heartbeat DST (unicast address or group address) */ + } filter[CONFIG_BLE_MESH_PROVISIONER_RECV_HB_FILTER_SIZE]; + + uint8_t type; /* Heartbeat filter type */ + + bt_mesh_pvnr_hb_recv_cb_t cb; /* Heartbeat receive callback */ +} hb_rx; + +int bt_mesh_pvnr_register_hb_recv_cb(bt_mesh_pvnr_hb_recv_cb_t cb) +{ + memset(&hb_rx, 0, sizeof(hb_rx)); + + /* Start with an empty rejectlist, which means all heartbeat messages will be reported */ + hb_rx.type = HEARTBEAT_FILTER_REJECTLIST; + hb_rx.cb = cb; + + return 0; +} + +int bt_mesh_pvnr_set_hb_recv_filter_type(uint8_t type) +{ + if (type > HEARTBEAT_FILTER_REJECTLIST) { + BT_ERR("Invalid heartbeat filter type 0x%02x", type); + return -EINVAL; + } + + /* If the heartbeat filter type is different with previous one, + * clear the existing filter entries. + */ + if (hb_rx.type != type) { + memset(&hb_rx, 0, offsetof(struct heartbeat_recv, cb)); + hb_rx.type = type; + } + + return 0; +} + +static int hb_filter_alloc(uint16_t src, uint16_t dst) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(hb_rx.filter); i++) { + struct heartbeat_filter *filter = &hb_rx.filter[i]; + + if (filter->src == BLE_MESH_ADDR_UNASSIGNED && + filter->dst == BLE_MESH_ADDR_UNASSIGNED) { + filter->src = src; + filter->dst = dst; + return 0; + } + } + + BT_ERR("Heartbeat filter is full!"); + return -ENOMEM; +} + +static int hb_filter_add(uint16_t src, uint16_t dst) +{ + int i; + + if (!(BLE_MESH_ADDR_IS_UNICAST(src) && + (BLE_MESH_ADDR_IS_UNICAST(dst) || BLE_MESH_ADDR_IS_GROUP(dst)))) { + BT_ERR("Invalid filter address, src 0x%04x, dst 0x%04x", src, dst); + return -EINVAL; + } + + /* Check if filter entries with the same src or dst exist. */ + for (i = 0; i < ARRAY_SIZE(hb_rx.filter); i++) { + struct heartbeat_filter *filter = &hb_rx.filter[i]; + + if (filter->src == src && filter->dst == dst) { + BT_WARN("Filter already exists, src 0x%04x dst 0x%04x", filter->src, filter->dst); + return 0; + } + } + + return hb_filter_alloc(src, dst); +} + +static int hb_filter_remove(uint16_t src, uint16_t dst) +{ + int i; + + if (!(BLE_MESH_ADDR_IS_UNICAST(src) && + (BLE_MESH_ADDR_IS_UNICAST(dst) || BLE_MESH_ADDR_IS_GROUP(dst)))) { + BT_ERR("Invalid filter address, src 0x%04x, dst 0x%04x", src, dst); + return -EINVAL; + } + + for (i = 0; i < ARRAY_SIZE(hb_rx.filter); i++) { + struct heartbeat_filter *filter = &hb_rx.filter[i]; + + if (filter->src == src && filter->dst == dst) { + memset(filter, 0, sizeof(struct heartbeat_filter)); + } + } + + return 0; +} + +int bt_mesh_pvnr_set_hb_recv_filter_info(uint8_t op, uint16_t src, uint16_t dst) +{ + switch (op) { + case HEARTBEAT_FILTER_ADD: + return hb_filter_add(src, dst); + case HEARTBEAT_FILTER_REMOVE: + return hb_filter_remove(src, dst); + default: + BT_ERR("Invalid heartbeat filter opcode 0x%02x", op); + return -EINVAL; + } +} + +static bool filter_with_rejectlist(uint16_t hb_src, uint16_t hb_dst) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(hb_rx.filter); i++) { + struct heartbeat_filter *filter = &hb_rx.filter[i]; + if (hb_src == filter->src && hb_dst == filter->dst) { + return true; + } + } + + return false; +} + +static bool filter_with_acceptlist(uint16_t hb_src, uint16_t hb_dst) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(hb_rx.filter); i++) { + struct heartbeat_filter *filter = &hb_rx.filter[i]; + if (hb_src == filter->src && hb_dst == filter->dst) { + return false; + } + } + + return true; +} + +void bt_mesh_pvnr_heartbeat_recv(uint16_t hb_src, uint16_t hb_dst, + uint8_t init_ttl, uint8_t rx_ttl, + uint8_t hops, uint16_t feat, int8_t rssi) +{ + if (hb_rx.cb == NULL) { + BT_DBG("Receiving heartbeat is not enabled"); + return; + } + + if (hb_rx.type == HEARTBEAT_FILTER_REJECTLIST) { + if (filter_with_rejectlist(hb_src, hb_dst)) { + BT_INFO("Filtered by rejectlist, src 0x%04x, dst 0x%04x", hb_src, hb_dst); + return; + } + } else { + if (filter_with_acceptlist(hb_src, hb_dst)) { + BT_INFO("Filtered by acceptlist, src 0x%04x, dst 0x%04x", hb_src, hb_dst); + return; + } + } + + if (hb_rx.cb) { + hb_rx.cb(hb_src, hb_dst, init_ttl, rx_ttl, hops, feat, rssi); + } +} + +#endif /* CONFIG_BLE_MESH_PROVISIONER_RECV_HB */ diff --git a/components/bt/esp_ble_mesh/core/heartbeat.h b/components/bt/esp_ble_mesh/core/heartbeat.h new file mode 100644 index 0000000000..c19de37675 --- /dev/null +++ b/components/bt/esp_ble_mesh/core/heartbeat.h @@ -0,0 +1,43 @@ +/* + * SPDX-FileCopyrightText: 2017 Intel Corporation + * SPDX-FileContributor: 2018-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _HEARTBEAT_H_ +#define _HEARTBEAT_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void bt_mesh_set_hb_sub_dst(uint16_t addr); + +uint16_t bt_mesh_get_hb_sub_dst(void); + +void bt_mesh_heartbeat_recv(uint16_t src, uint16_t dst, uint8_t hops, uint16_t feat); + +void bt_mesh_heartbeat_send(void); + +typedef void (* bt_mesh_pvnr_hb_recv_cb_t)(uint16_t hb_src, uint16_t hb_dst, + uint8_t init_ttl, uint8_t rx_ttl, + uint8_t hops, uint16_t feat, int8_t rssi); + +int bt_mesh_pvnr_register_hb_recv_cb(bt_mesh_pvnr_hb_recv_cb_t cb); + +int bt_mesh_pvnr_set_hb_recv_filter_type(uint8_t filter_type); + +int bt_mesh_pvnr_set_hb_recv_filter_info(uint8_t op, uint16_t src, uint16_t dst); + +void bt_mesh_pvnr_heartbeat_recv(uint16_t hb_src, uint16_t hb_dst, + uint8_t init_ttl, uint8_t rx_ttl, + uint8_t hops, uint16_t feat, int8_t rssi); + +#ifdef __cplusplus +} +#endif + +#endif /* _HEARTBEAT_H_ */ diff --git a/components/bt/esp_ble_mesh/core/lpn.c b/components/bt/esp_ble_mesh/core/lpn.c index 52b01a9c57..98c24a323b 100644 --- a/components/bt/esp_ble_mesh/core/lpn.c +++ b/components/bt/esp_ble_mesh/core/lpn.c @@ -21,6 +21,7 @@ #include "foundation.h" #include "mesh/main.h" #include "mesh/cfg_srv.h" +#include "heartbeat.h" #include "mesh_v1.1/utils.h" diff --git a/components/bt/esp_ble_mesh/core/pvnr_mgmt.c b/components/bt/esp_ble_mesh/core/pvnr_mgmt.c index 55d18ad51e..2531a2d2fd 100644 --- a/components/bt/esp_ble_mesh/core/pvnr_mgmt.c +++ b/components/bt/esp_ble_mesh/core/pvnr_mgmt.c @@ -1435,181 +1435,4 @@ int bt_mesh_provisioner_store_node_info(struct bt_mesh_node *node) } #endif /* CONFIG_BLE_MESH_TEST_AUTO_ENTER_NETWORK */ -#if CONFIG_BLE_MESH_PROVISIONER_RECV_HB - -#define HEARTBEAT_FILTER_ACCEPTLIST 0x00 -#define HEARTBEAT_FILTER_REJECTLIST 0x01 - -#define HEARTBEAT_FILTER_ADD 0x00 -#define HEARTBEAT_FILTER_REMOVE 0x01 - -static struct heartbeat_recv { - struct heartbeat_filter { - uint16_t src; /* Heartbeat source address (unicast address) */ - uint16_t dst; /* Heartbeat destination address (unicast address or group address) */ - } filter[CONFIG_BLE_MESH_PROVISIONER_RECV_HB_FILTER_SIZE]; - uint8_t type; /* Heartbeat filter type */ - bt_mesh_heartbeat_recv_cb_t cb; /* Heartbeat receive callback */ -} hb_rx; - -int bt_mesh_provisioner_recv_heartbeat(bt_mesh_heartbeat_recv_cb_t cb) -{ - memset(&hb_rx, 0, sizeof(hb_rx)); - - /* Start with an empty rejectlist, which means all heartbeat messages will be reported */ - hb_rx.type = HEARTBEAT_FILTER_REJECTLIST; - hb_rx.cb = cb; - - return 0; -} - -int bt_mesh_provisioner_set_heartbeat_filter_type(uint8_t type) -{ - if (type > HEARTBEAT_FILTER_REJECTLIST) { - BT_ERR("Invalid heartbeat filter type 0x%02x", type); - return -EINVAL; - } - - /* If the heartbeat filter type is different with previous one, - * clear the existing filter entries. - */ - if (hb_rx.type != type) { - memset(&hb_rx, 0, offsetof(struct heartbeat_recv, cb)); - hb_rx.type = type; - } - - return 0; -} - -static int hb_filter_alloc(uint16_t src, uint16_t dst) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(hb_rx.filter); i++) { - struct heartbeat_filter *filter = &hb_rx.filter[i]; - - if (filter->src == BLE_MESH_ADDR_UNASSIGNED && - filter->dst == BLE_MESH_ADDR_UNASSIGNED) { - filter->src = src; - filter->dst = dst; - return 0; - } - } - - BT_ERR("Heartbeat filter is full!"); - return -ENOMEM; -} - -static int hb_filter_add(uint16_t src, uint16_t dst) -{ - int i; - - if (!(BLE_MESH_ADDR_IS_UNICAST(src) && - (BLE_MESH_ADDR_IS_UNICAST(dst) || BLE_MESH_ADDR_IS_GROUP(dst)))) { - BT_ERR("Invalid filter address, src 0x%04x, dst 0x%04x", src, dst); - return -EINVAL; - } - - /* Check if filter entries with the same src or dst exist. */ - for (i = 0; i < ARRAY_SIZE(hb_rx.filter); i++) { - struct heartbeat_filter *filter = &hb_rx.filter[i]; - - if (filter->src == src && filter->dst == dst) { - BT_WARN("Filter already exists, src 0x%04x dst 0x%04x", filter->src, filter->dst); - return 0; - } - } - - return hb_filter_alloc(src, dst); -} - -static int hb_filter_remove(uint16_t src, uint16_t dst) -{ - int i; - - if (!(BLE_MESH_ADDR_IS_UNICAST(src) && - (BLE_MESH_ADDR_IS_UNICAST(dst) || BLE_MESH_ADDR_IS_GROUP(dst)))) { - BT_ERR("Invalid filter address, src 0x%04x, dst 0x%04x", src, dst); - return -EINVAL; - } - - for (i = 0; i < ARRAY_SIZE(hb_rx.filter); i++) { - struct heartbeat_filter *filter = &hb_rx.filter[i]; - - if (filter->src == src && filter->dst == dst) { - memset(filter, 0, sizeof(struct heartbeat_filter)); - } - } - - return 0; -} - -int bt_mesh_provisioner_set_heartbeat_filter_info(uint8_t op, uint16_t src, uint16_t dst) -{ - switch (op) { - case HEARTBEAT_FILTER_ADD: - return hb_filter_add(src, dst); - case HEARTBEAT_FILTER_REMOVE: - return hb_filter_remove(src, dst); - default: - BT_ERR("Invalid heartbeat filter opcode 0x%02x", op); - return -EINVAL; - } -} - -static bool filter_with_rejectlist(uint16_t hb_src, uint16_t hb_dst) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(hb_rx.filter); i++) { - struct heartbeat_filter *filter = &hb_rx.filter[i]; - if (hb_src == filter->src && hb_dst == filter->dst) { - return true; - } - } - - return false; -} - -static bool filter_with_acceptlist(uint16_t hb_src, uint16_t hb_dst) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(hb_rx.filter); i++) { - struct heartbeat_filter *filter = &hb_rx.filter[i]; - if (hb_src == filter->src && hb_dst == filter->dst) { - return false; - } - } - - return true; -} - -void bt_mesh_provisioner_heartbeat(uint16_t hb_src, uint16_t hb_dst, - uint8_t init_ttl, uint8_t rx_ttl, - uint8_t hops, uint16_t feat, int8_t rssi) -{ - if (hb_rx.cb == NULL) { - BT_DBG("Receiving heartbeat is not enabled"); - return; - } - - if (hb_rx.type == HEARTBEAT_FILTER_REJECTLIST) { - if (filter_with_rejectlist(hb_src, hb_dst)) { - BT_INFO("Filtered by rejectlist, src 0x%04x, dst 0x%04x", hb_src, hb_dst); - return; - } - } else { - if (filter_with_acceptlist(hb_src, hb_dst)) { - BT_INFO("Filtered by acceptlist, src 0x%04x, dst 0x%04x", hb_src, hb_dst); - return; - } - } - - if (hb_rx.cb) { - hb_rx.cb(hb_src, hb_dst, init_ttl, rx_ttl, hops, feat, rssi); - } -} -#endif /* CONFIG_BLE_MESH_PROVISIONER_RECV_HB */ - #endif /* CONFIG_BLE_MESH_PROVISIONER */ diff --git a/components/bt/esp_ble_mesh/core/pvnr_mgmt.h b/components/bt/esp_ble_mesh/core/pvnr_mgmt.h index 20fdc6d130..574586ea62 100644 --- a/components/bt/esp_ble_mesh/core/pvnr_mgmt.h +++ b/components/bt/esp_ble_mesh/core/pvnr_mgmt.h @@ -113,20 +113,6 @@ int bt_mesh_provisioner_local_net_key_del(uint16_t net_idx, bool store); int bt_mesh_provisioner_bind_local_model_app_idx(uint16_t elem_addr, uint16_t mod_id, uint16_t cid, uint16_t app_idx); -typedef void (* bt_mesh_heartbeat_recv_cb_t)(uint16_t hb_src, uint16_t hb_dst, - uint8_t init_ttl, uint8_t rx_ttl, - uint8_t hops, uint16_t feat, int8_t rssi); - -int bt_mesh_provisioner_recv_heartbeat(bt_mesh_heartbeat_recv_cb_t cb); - -int bt_mesh_provisioner_set_heartbeat_filter_type(uint8_t filter_type); - -int bt_mesh_provisioner_set_heartbeat_filter_info(uint8_t op, uint16_t src, uint16_t dst); - -void bt_mesh_provisioner_heartbeat(uint16_t hb_src, uint16_t hb_dst, - uint8_t init_ttl, uint8_t rx_ttl, - uint8_t hops, uint16_t feat, int8_t rssi); - int bt_mesh_provisioner_store_node_info(struct bt_mesh_node *node); #ifdef __cplusplus diff --git a/components/bt/esp_ble_mesh/core/transport.c b/components/bt/esp_ble_mesh/core/transport.c index b3428216e6..785dc1c543 100644 --- a/components/bt/esp_ble_mesh/core/transport.c +++ b/components/bt/esp_ble_mesh/core/transport.c @@ -24,6 +24,7 @@ #include "fast_prov.h" #include "mesh/common.h" #include "mesh/cfg_srv.h" +#include "heartbeat.h" #include "mesh_v1.1/utils.h" @@ -116,8 +117,6 @@ static struct seg_rx { static uint8_t seg_rx_buf_data[(CONFIG_BLE_MESH_RX_SEG_MSG_COUNT * CONFIG_BLE_MESH_RX_SDU_MAX)]; -static uint16_t hb_sub_dst = BLE_MESH_ADDR_UNASSIGNED; - static bt_mesh_mutex_t seg_tx_lock; static bt_mesh_mutex_t seg_rx_lock; @@ -141,12 +140,12 @@ static inline void bt_mesh_seg_rx_unlock(void) bt_mesh_mutex_unlock(&seg_rx_lock); } -uint8_t bt_mesh_get_seg_retrans_num(void) +uint8_t bt_mesh_get_seg_rtx_num(void) { return SEG_RETRANSMIT_ATTEMPTS; } -int32_t bt_mesh_get_seg_retrans_timeout(uint8_t ttl) +int32_t bt_mesh_get_seg_rtx_timeout(uint8_t ttl) { /* This function will be used when a client model sending an * acknowledged message. And if the dst of a message is not @@ -160,9 +159,72 @@ int32_t bt_mesh_get_seg_retrans_timeout(uint8_t ttl) return SEG_RETRANSMIT_TIMEOUT_UNICAST(&tx); } -void bt_mesh_set_hb_sub_dst(uint16_t addr) +struct bt_mesh_app_key *bt_mesh_app_key_get(uint16_t app_idx) { - hb_sub_dst = addr; + if (bt_mesh_is_provisioned()) { +#if CONFIG_BLE_MESH_NODE + if (!IS_ENABLED(CONFIG_BLE_MESH_FAST_PROV)) { + for (int i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) { + if (bt_mesh.app_keys[i].net_idx != BLE_MESH_KEY_UNUSED && + bt_mesh.app_keys[i].app_idx == app_idx) { + return &bt_mesh.app_keys[i]; + } + } + } else { + return bt_mesh_fast_prov_app_key_find(app_idx); + } +#endif + } else if (bt_mesh_is_provisioner_en()) { +#if CONFIG_BLE_MESH_PROVISIONER + for (int i = 0; i < ARRAY_SIZE(bt_mesh.p_app_keys); i++) { + if (bt_mesh.p_app_keys[i] && + bt_mesh.p_app_keys[i]->net_idx != BLE_MESH_KEY_UNUSED && + bt_mesh.p_app_keys[i]->app_idx == app_idx) { + return bt_mesh.p_app_keys[i]; + } + } +#endif + } + + return NULL; +} + +int bt_mesh_upper_key_get(const struct bt_mesh_subnet *subnet, uint16_t app_idx, + const uint8_t **key, uint8_t *aid, uint16_t dst) +{ + struct bt_mesh_app_key *app_key = NULL; + + if (app_idx == BLE_MESH_KEY_DEV) { + *key = bt_mesh_dev_key_get(dst); + if (!*key) { + BT_ERR("DevKey of 0x%04x not found", dst); + return -EINVAL; + } + + *aid = 0U; + return 0; + } + + if (!subnet) { + BT_ERR("Invalid subnet"); + return -EINVAL; + } + + app_key = bt_mesh_app_key_get(app_idx); + if (!app_key) { + BT_ERR("AppKey 0x%04x not found", app_idx); + return -ENOENT; + } + + if (subnet->kr_phase == BLE_MESH_KR_PHASE_2 && app_key->updated) { + *key = app_key->keys[1].val; + *aid = app_key->keys[1].id; + } else { + *key = app_key->keys[0].val; + *aid = app_key->keys[0].id; + } + + return 0; } static int send_unseg(struct bt_mesh_net_tx *tx, struct net_buf_simple *sdu, @@ -575,36 +637,6 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu, return 0; } -struct bt_mesh_app_key *bt_mesh_app_key_get(uint16_t app_idx) -{ - if (bt_mesh_is_provisioned()) { -#if CONFIG_BLE_MESH_NODE - if (!IS_ENABLED(CONFIG_BLE_MESH_FAST_PROV)) { - for (int i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) { - if (bt_mesh.app_keys[i].net_idx != BLE_MESH_KEY_UNUSED && - bt_mesh.app_keys[i].app_idx == app_idx) { - return &bt_mesh.app_keys[i]; - } - } - } else { - return bt_mesh_fast_prov_app_key_find(app_idx); - } -#endif - } else if (bt_mesh_is_provisioner_en()) { -#if CONFIG_BLE_MESH_PROVISIONER - for (int i = 0; i < ARRAY_SIZE(bt_mesh.p_app_keys); i++) { - if (bt_mesh.p_app_keys[i] && - bt_mesh.p_app_keys[i]->net_idx != BLE_MESH_KEY_UNUSED && - bt_mesh.p_app_keys[i]->app_idx == app_idx) { - return bt_mesh.p_app_keys[i]; - } - } -#endif - } - - return NULL; -} - int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct net_buf_simple *msg, const struct bt_mesh_send_cb *cb, void *cb_data) { @@ -945,7 +977,7 @@ static int trans_heartbeat(struct bt_mesh_net_rx *rx, } if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned() && - rx->ctx.recv_dst != hb_sub_dst) { + rx->ctx.recv_dst != bt_mesh_get_hb_sub_dst()) { BT_WARN("Ignoring heartbeat to non-subscribed destination"); return 0; } @@ -956,15 +988,15 @@ static int trans_heartbeat(struct bt_mesh_net_rx *rx, hops = (init_ttl - rx->ctx.recv_ttl + 1); 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); + rx->ctx.addr, rx->ctx.recv_ttl, init_ttl, hops, + (hops == 1U) ? "" : "s", feat); if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) { - bt_mesh_heartbeat(rx->ctx.addr, rx->ctx.recv_dst, hops, feat); + bt_mesh_heartbeat_recv(rx->ctx.addr, rx->ctx.recv_dst, hops, feat); } else if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER_RECV_HB) && bt_mesh_is_provisioner_en()) { - bt_mesh_provisioner_heartbeat(rx->ctx.addr, rx->ctx.recv_dst, - init_ttl, rx->ctx.recv_ttl, - hops, feat, rx->ctx.recv_rssi); + bt_mesh_pvnr_heartbeat_recv(rx->ctx.addr, rx->ctx.recv_dst, + init_ttl, rx->ctx.recv_ttl, + hops, feat, rx->ctx.recv_rssi); } return 0; @@ -1563,6 +1595,7 @@ found_rx: *pdu_type = BLE_MESH_FRIEND_PDU_COMPLETE; k_delayed_work_cancel(&rx->ack); + send_ack(net_rx->sub, net_rx->ctx.recv_dst, net_rx->ctx.addr, net_rx->ctx.send_ttl, seq_auth, rx->block, rx->obo); @@ -1756,94 +1789,3 @@ void bt_mesh_trans_deinit(bool erase) bt_mesh_mutex_free(&seg_rx_lock); } #endif /* CONFIG_BLE_MESH_DEINIT */ - -void bt_mesh_heartbeat_send(void) -{ - struct bt_mesh_cfg_srv *cfg = bt_mesh_cfg_get(); - uint16_t feat = 0U; - struct __attribute__((packed)) { - uint8_t init_ttl; - uint16_t feat; - } hb; - struct bt_mesh_msg_ctx ctx = { - .net_idx = cfg->hb_pub.net_idx, - .app_idx = BLE_MESH_KEY_UNUSED, - .addr = cfg->hb_pub.dst, - .send_ttl = cfg->hb_pub.ttl, - .send_cred = BLE_MESH_FLOODING_CRED, - }; - struct bt_mesh_net_tx tx = { - .sub = bt_mesh_subnet_get(cfg->hb_pub.net_idx), - .ctx = &ctx, - .src = bt_mesh_model_elem(cfg->model)->addr, - .xmit = bt_mesh_net_transmit_get(), - }; - - /* Do nothing if heartbeat publication is not enabled */ - if (cfg->hb_pub.dst == BLE_MESH_ADDR_UNASSIGNED) { - return; - } - - hb.init_ttl = cfg->hb_pub.ttl; - - if (bt_mesh_relay_get() == BLE_MESH_RELAY_ENABLED) { - feat |= BLE_MESH_FEAT_RELAY; - } - - if (bt_mesh_gatt_proxy_get() == BLE_MESH_GATT_PROXY_ENABLED) { - feat |= BLE_MESH_FEAT_PROXY; - } - - if (bt_mesh_friend_get() == BLE_MESH_FRIEND_ENABLED) { - feat |= BLE_MESH_FEAT_FRIEND; - } - - if (bt_mesh_lpn_established()) { - feat |= BLE_MESH_FEAT_LOW_POWER; - } - - hb.feat = sys_cpu_to_be16(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); -} - -int bt_mesh_upper_key_get(const struct bt_mesh_subnet *subnet, uint16_t app_idx, - const uint8_t **key, uint8_t *aid, uint16_t dst) -{ - struct bt_mesh_app_key *app_key = NULL; - - if (app_idx == BLE_MESH_KEY_DEV) { - *key = bt_mesh_dev_key_get(dst); - if (!*key) { - BT_ERR("DevKey of 0x%04x not found", dst); - return -EINVAL; - } - - *aid = 0U; - return 0; - } - - if (!subnet) { - BT_ERR("Invalid subnet"); - return -EINVAL; - } - - app_key = bt_mesh_app_key_get(app_idx); - if (!app_key) { - BT_ERR("AppKey 0x%04x not found", app_idx); - return -ENOENT; - } - - if (subnet->kr_phase == BLE_MESH_KR_PHASE_2 && app_key->updated) { - *key = app_key->keys[1].val; - *aid = app_key->keys[1].id; - } else { - *key = app_key->keys[0].val; - *aid = app_key->keys[0].id; - } - - return 0; -} diff --git a/components/bt/esp_ble_mesh/core/transport.h b/components/bt/esp_ble_mesh/core/transport.h index 1feccb9980..056ccc5b87 100644 --- a/components/bt/esp_ble_mesh/core/transport.h +++ b/components/bt/esp_ble_mesh/core/transport.h @@ -94,14 +94,15 @@ struct bt_mesh_ctl_friend_sub_confirm { uint8_t xact; } __attribute__((packed)); -uint8_t bt_mesh_get_seg_retrans_num(void); +uint8_t bt_mesh_get_seg_rtx_num(void); -int32_t bt_mesh_get_seg_retrans_timeout(uint8_t ttl); - -void bt_mesh_set_hb_sub_dst(uint16_t addr); +int32_t bt_mesh_get_seg_rtx_timeout(uint8_t ttl); struct bt_mesh_app_key *bt_mesh_app_key_get(uint16_t app_idx); +int bt_mesh_upper_key_get(const struct bt_mesh_subnet *subnet, uint16_t app_idx, + const uint8_t **key, uint8_t *aid, uint16_t dst); + bool bt_mesh_tx_in_progress(void); void bt_mesh_rx_reset(void); @@ -121,11 +122,6 @@ int bt_mesh_trans_recv(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx); void bt_mesh_trans_init(void); void bt_mesh_trans_deinit(bool erase); -void bt_mesh_heartbeat_send(void); - -int bt_mesh_upper_key_get(const struct bt_mesh_subnet *subnet, uint16_t app_idx, - const uint8_t **key, uint8_t *aid, uint16_t dst); - #ifdef __cplusplus } #endif diff --git a/components/bt/esp_ble_mesh/models/client/client_common.c b/components/bt/esp_ble_mesh/models/client/client_common.c index 3b4495fe53..9abce3d884 100644 --- a/components/bt/esp_ble_mesh/models/client/client_common.c +++ b/components/bt/esp_ble_mesh/models/client/client_common.c @@ -197,8 +197,8 @@ static int32_t bt_mesh_client_calc_timeout(struct bt_mesh_msg_ctx *ctx, /* Based on the message length, calculate how many segments are needed. * All the messages sent from here are access messages. */ - seg_rtx_num = bt_mesh_get_seg_retrans_num(); - seg_rtx_to = bt_mesh_get_seg_retrans_timeout(ctx->send_ttl); + seg_rtx_num = bt_mesh_get_seg_rtx_num(); + seg_rtx_to = bt_mesh_get_seg_rtx_timeout(ctx->send_ttl); seg_count = (msg->len + mic_size - 1) / 12U + 1U; duration = bt_mesh_get_adv_duration(ctx);