ble_mesh: stack: Provisioner supports receiving heartbeat

pull/6275/head
lly 2020-11-17 10:41:15 +08:00 zatwierdzone przez bot
rodzic 0e42b856af
commit db4b87a771
9 zmienionych plików z 520 dodań i 4 usunięć

Wyświetl plik

@ -195,6 +195,28 @@ if BLE_MESH
This option specifies how many application keys the Provisioner can have. This option specifies how many application keys the Provisioner can have.
Indeed, this value decides the number of the application keys which can be added by a Provisioner. Indeed, this value decides the number of the application keys which can be added by a Provisioner.
config BLE_MESH_PROVISIONER_RECV_HB
bool "Support receiving Heartbeat messages"
default n
help
When this option is enabled, Provisioner can call specific functions to enable
or disable receiving Heartbeat messages and notify them to the application layer.
if BLE_MESH_PROVISIONER_RECV_HB
config BLE_MESH_PROVISIONER_RECV_HB_FILTER_SIZE
int "Maximum number of filter entries for receiving Heartbeat messages"
default 3
range 1 1000
help
This option specifies how many heartbeat filter entries Provisioner supports.
The heartbeat filter (acceptlist or rejectlist) entries are used to store a
list of SRC and DST which can be used to decide if a heartbeat message will
be processed and notified to the application layer by Provisioner.
Note: The filter is an empty rejectlist by default.
endif # BLE_MESH_PROVISIONER_RECV_HB
endif # BLE_MESH_PROVISIONER endif # BLE_MESH_PROVISIONER
# Virtual option enabled whenever Generic Provisioning layer is needed # Virtual option enabled whenever Generic Provisioning layer is needed

Wyświetl plik

@ -528,6 +528,76 @@ const uint8_t *esp_ble_mesh_provisioner_get_local_net_key(uint16_t net_idx)
{ {
return bt_mesh_provisioner_local_net_key_get(net_idx); return bt_mesh_provisioner_local_net_key_get(net_idx);
} }
#if CONFIG_BLE_MESH_PROVISIONER_RECV_HB
esp_err_t esp_ble_mesh_provisioner_recv_heartbeat(bool enable)
{
btc_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
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_PROVISIONER_ENABLE_HEARTBEAT_RECV;
arg.enable_heartbeat_recv.enable = enable;
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_provisioner_set_heartbeat_filter_type(uint8_t type)
{
btc_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
if (type > ESP_BLE_MESH_HEARTBEAT_FILTER_REJECTLIST) {
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_PROVISIONER_SET_HEARTBEAT_FILTER_TYPE;
arg.set_heartbeat_filter_type.type = type;
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_provisioner_set_heartbeat_filter_info(uint8_t op, esp_ble_mesh_heartbeat_filter_info_t *info)
{
btc_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
if (op > ESP_BLE_MESH_HEARTBEAT_FILTER_REMOVE || info == NULL) {
return ESP_ERR_INVALID_ARG;
}
if (!ESP_BLE_MESH_ADDR_IS_UNICAST(info->hb_src) &&
!ESP_BLE_MESH_ADDR_IS_UNICAST(info->hb_dst) &&
!ESP_BLE_MESH_ADDR_IS_GROUP(info->hb_dst)) {
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_PROVISIONER_SET_HEARTBEAT_FILTER_INFO;
arg.set_heartbeat_filter_info.op = op;
arg.set_heartbeat_filter_info.hb_src = info->hb_src;
arg.set_heartbeat_filter_info.hb_dst = info->hb_dst;
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_PROVISIONER_RECV_HB */
#endif /* CONFIG_BLE_MESH_PROVISIONER */ #endif /* CONFIG_BLE_MESH_PROVISIONER */
#if (CONFIG_BLE_MESH_FAST_PROV) #if (CONFIG_BLE_MESH_FAST_PROV)

Wyświetl plik

@ -413,6 +413,66 @@ esp_err_t esp_ble_mesh_provisioner_update_local_net_key(const uint8_t net_key[16
*/ */
const uint8_t *esp_ble_mesh_provisioner_get_local_net_key(uint16_t net_idx); const uint8_t *esp_ble_mesh_provisioner_get_local_net_key(uint16_t net_idx);
/**
* @brief This function is called by Provisioner to enable or disable receiving
* heartbeat messages.
*
* @note If enabling receiving heartbeat message successfully, the filter will
* be an empty rejectlist by default, which means all heartbeat messages
* received by the Provisioner will be reported to the application layer.
*
* @param[in] enable: Enable or disable receiving heartbeat messages.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_recv_heartbeat(bool enable);
/**
* @brief This function is called by Provisioner to set the heartbeat filter type.
*
* @note 1. If the filter type is not the same with the current value, then all the
* filter entries will be cleaned.
* 2. If the previous type is rejectlist, and changed to acceptlist, then the
* filter will be an empty acceptlist, which means no heartbeat messages
* will be reported. Users need to add SRC or DST into the filter entry,
* then heartbeat messages from the SRC or to the DST will be reported.
*
* @param[in] type: Heartbeat filter type (acceptlist or rejectlist).
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_set_heartbeat_filter_type(uint8_t type);
/**
* @brief This function is called by Provisioner to add or remove a heartbeat filter entry.
*
* @note 1. If the operation is "ADD", the "hb_src" can be set to the SRC (can only be a
* unicast address) of heartbeat messages, and the "hb_dst" can be set to the
* DST (unicast address or group address), at least one of them needs to be set.
* - If only one of them is set, the filter entry will only use the configured
* SRC or DST to filter heartbeat messages.
* - If both of them are set, the SRC and DST will both be used to decide if a
* heartbeat message will be handled.
* - If SRC or DST already exists in some filter entry, then the corresponding
* entry will be cleaned firstly, then a new entry will be allocated to store
* the information.
* 2. If the operation is "REMOVE", the "hb_src" can be set to the SRC (can only be
* a unicast address) of heartbeat messages, and the "hb_dst" can be set to the
* DST (unicast address or group address), at least one of them needs to be set.
* - The filter entry with the same SRC or DST will be removed.
*
* @param[in] op: Add or REMOVE
* @param[in] info: Heartbeat filter entry information, including:
* hb_src - Heartbeat source address;
* hb_dst - Heartbeat destination address;
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_set_heartbeat_filter_info(uint8_t op, esp_ble_mesh_heartbeat_filter_info_t *info);
/** /**
* @brief This function is called to get fast provisioning application key. * @brief This function is called to get fast provisioning application key.
* *

Wyświetl plik

@ -801,6 +801,20 @@ typedef struct {
uint8_t scan_rsp_data[31]; /*!< Scan response data */ uint8_t scan_rsp_data[31]; /*!< Scan response data */
} esp_ble_mesh_ble_adv_data_t; } esp_ble_mesh_ble_adv_data_t;
/*!< Provisioner heartbeat filter type */
#define ESP_BLE_MESH_HEARTBEAT_FILTER_ACCEPTLIST 0x00
#define ESP_BLE_MESH_HEARTBEAT_FILTER_REJECTLIST 0x01
/*!< Provisioner heartbeat filter operation */
#define ESP_BLE_MESH_HEARTBEAT_FILTER_ADD 0x00
#define ESP_BLE_MESH_HEARTBEAT_FILTER_REMOVE 0x01
/** Context of Provisioner heartbeat filter information to be set */
typedef struct {
uint16_t hb_src; /*!< Heartbeat source address (unicast address) */
uint16_t hb_dst; /*!< Heartbeat destination address (unicast address or group address) */
} esp_ble_mesh_heartbeat_filter_info_t;
/*!< This enum value is the event of node/provisioner/fast provisioning */ /*!< This enum value is the event of node/provisioner/fast provisioning */
typedef enum { typedef enum {
ESP_BLE_MESH_PROV_REGISTER_COMP_EVT, /*!< Initialize BLE Mesh provisioning capabilities and internal data information completion event */ ESP_BLE_MESH_PROV_REGISTER_COMP_EVT, /*!< Initialize BLE Mesh provisioning capabilities and internal data information completion event */
@ -852,6 +866,10 @@ typedef enum {
ESP_BLE_MESH_PROVISIONER_STORE_NODE_COMP_DATA_COMP_EVT, /*!< Provisioner store node composition data completion event */ ESP_BLE_MESH_PROVISIONER_STORE_NODE_COMP_DATA_COMP_EVT, /*!< Provisioner store node composition data completion event */
ESP_BLE_MESH_PROVISIONER_DELETE_NODE_WITH_UUID_COMP_EVT, /*!< Provisioner delete node with uuid completion event */ ESP_BLE_MESH_PROVISIONER_DELETE_NODE_WITH_UUID_COMP_EVT, /*!< Provisioner delete node with uuid completion event */
ESP_BLE_MESH_PROVISIONER_DELETE_NODE_WITH_ADDR_COMP_EVT, /*!< Provisioner delete node with unicast address completion event */ ESP_BLE_MESH_PROVISIONER_DELETE_NODE_WITH_ADDR_COMP_EVT, /*!< Provisioner delete node with unicast address completion event */
ESP_BLE_MESH_PROVISIONER_ENABLE_HEARTBEAT_RECV_COMP_EVT, /*!< Provisioner start to receive heartbeat message completion event */
ESP_BLE_MESH_PROVISIONER_SET_HEARTBEAT_FILTER_TYPE_COMP_EVT, /*!< Provisioner set the heartbeat filter type completion event */
ESP_BLE_MESH_PROVISIONER_SET_HEARTBEAT_FILTER_INFO_COMP_EVT, /*!< Provisioner set the heartbeat filter information completion event */
ESP_BLE_MESH_PROVISIONER_RECV_HEARTBEAT_MESSAGE_EVT, /*!< Provisioner receive heartbeat message event */
ESP_BLE_MESH_SET_FAST_PROV_INFO_COMP_EVT, /*!< Set fast provisioning information (e.g. unicast address range, net_idx, etc.) completion event */ ESP_BLE_MESH_SET_FAST_PROV_INFO_COMP_EVT, /*!< Set fast provisioning information (e.g. unicast address range, net_idx, etc.) completion event */
ESP_BLE_MESH_SET_FAST_PROV_ACTION_COMP_EVT, /*!< Set fast provisioning action completion event */ ESP_BLE_MESH_SET_FAST_PROV_ACTION_COMP_EVT, /*!< Set fast provisioning action completion event */
ESP_BLE_MESH_HEARTBEAT_MESSAGE_RECV_EVT, /*!< Receive Heartbeat message event */ ESP_BLE_MESH_HEARTBEAT_MESSAGE_RECV_EVT, /*!< Receive Heartbeat message event */
@ -1219,6 +1237,41 @@ typedef union {
int err_code; /*!< Indicate the result of deleting node with unicast address by the Provisioner */ int err_code; /*!< Indicate the result of deleting node with unicast address by the Provisioner */
uint16_t unicast_addr; /*!< Node unicast address */ uint16_t unicast_addr; /*!< Node unicast address */
} provisioner_delete_node_with_addr_comp; /*!< Event parameter of ESP_BLE_MESH_PROVISIONER_DELETE_NODE_WITH_ADDR_COMP_EVT */ } provisioner_delete_node_with_addr_comp; /*!< Event parameter of ESP_BLE_MESH_PROVISIONER_DELETE_NODE_WITH_ADDR_COMP_EVT */
/**
* @brief ESP_BLE_MESH_PROVISIONER_ENABLE_HEARTBEAT_RECV_COMP_EVT
*/
struct {
int err_code; /*!< Indicate the result of enabling/disabling to receive heartbeat messages by the Provisioner */
bool enable; /*!< Indicate enabling or disabling receiving heartbeat messages */
} provisioner_enable_heartbeat_recv_comp; /*!< Event parameters of ESP_BLE_MESH_PROVISIONER_ENABLE_HEARTBEAT_RECV_COMP_EVT */
/**
* @brief ESP_BLE_MESH_PROVISIONER_SET_HEARTBEAT_FILTER_TYPE_COMP_EVT
*/
struct {
int err_code; /*!< Indicate the result of setting the heartbeat filter type by the Provisioner */
uint8_t type; /*!< Type of the filter used for receiving heartbeat messages */
} provisioner_set_heartbeat_filter_type_comp; /*!< Event parameters of ESP_BLE_MESH_PROVISIONER_SET_HEARTBEAT_FILTER_TYPE_COMP_EVT */
/**
* @brief ESP_BLE_MESH_PROVISIONER_SET_HEARTBEAT_FILTER_INFO_COMP_EVT
*/
struct {
int err_code; /*!< Indicate the result of setting the heartbeat filter address by the Provisioner */
uint8_t op; /*!< Operation (add, remove, clean) */
uint16_t hb_src; /*!< Heartbeat source address */
uint16_t hb_dst; /*!< Heartbeat destination address */
} provisioner_set_heartbeat_filter_info_comp; /*!< Event parameters of ESP_BLE_MESH_PROVISIONER_SET_HEARTBEAT_FILTER_INFO_COMP_EVT */
/**
* @brief ESP_BLE_MESH_PROVISIONER_RECV_HEARTBEAT_MESSAGE_EVT
*/
struct {
uint16_t hb_src; /*!< Heartbeat source address */
uint16_t hb_dst; /*!< Heartbeat destination address */
uint8_t init_ttl; /*!< Heartbeat InitTTL */
uint8_t rx_ttl; /*!< Heartbeat RxTTL */
uint8_t hops; /*!< Heartbeat hops (InitTTL - RxTTL + 1) */
uint16_t feature; /*!< Bit field of currently active features of the node */
int8_t rssi; /*!< RSSI of the heartbeat message */
} provisioner_recv_heartbeat; /*!< Event parameters of ESP_BLE_MESH_PROVISIONER_RECV_HEARTBEAT_MESSAGE_EVT */
/** /**
* @brief ESP_BLE_MESH_SET_FAST_PROV_INFO_COMP_EVT * @brief ESP_BLE_MESH_SET_FAST_PROV_INFO_COMP_EVT
*/ */

Wyświetl plik

@ -820,9 +820,29 @@ const esp_ble_mesh_node_t **btc_ble_mesh_provisioner_get_node_table_entry(void)
{ {
return (const esp_ble_mesh_node_t **)bt_mesh_provisioner_get_node_table_entry(); return (const esp_ble_mesh_node_t **)bt_mesh_provisioner_get_node_table_entry();
} }
#if CONFIG_BLE_MESH_PROVISIONER_RECV_HB
static void btc_ble_mesh_provisioner_recv_heartbeat_cb(u16_t hb_src, u16_t hb_dst,
u8_t init_ttl, u8_t rx_ttl,
u8_t hops, u16_t feat, s8_t rssi)
{
esp_ble_mesh_prov_cb_param_t mesh_param = {0};
mesh_param.provisioner_recv_heartbeat.hb_src = hb_src;
mesh_param.provisioner_recv_heartbeat.hb_dst = hb_dst;
mesh_param.provisioner_recv_heartbeat.init_ttl = init_ttl;
mesh_param.provisioner_recv_heartbeat.rx_ttl = rx_ttl;
mesh_param.provisioner_recv_heartbeat.hops = hops;
mesh_param.provisioner_recv_heartbeat.feature = feat;
mesh_param.provisioner_recv_heartbeat.rssi = rssi;
btc_ble_mesh_prov_callback(&mesh_param, ESP_BLE_MESH_PROVISIONER_RECV_HEARTBEAT_MESSAGE_EVT);
}
#endif /* CONFIG_BLE_MESH_PROVISIONER_RECV_HB */
#endif /* CONFIG_BLE_MESH_PROVISIONER */ #endif /* CONFIG_BLE_MESH_PROVISIONER */
static void btc_ble_mesh_heartbeat_msg_recv_cb(u8_t hops, u16_t feature) static void btc_ble_mesh_node_recv_heartbeat_cb(u8_t hops, u16_t feature)
{ {
esp_ble_mesh_prov_cb_param_t mesh_param = {0}; esp_ble_mesh_prov_cb_param_t mesh_param = {0};
@ -1197,7 +1217,7 @@ static void btc_ble_mesh_model_op_set(esp_ble_mesh_model_t *model)
model->cb = (esp_ble_mesh_model_cbs_t *)&bt_mesh_cfg_srv_cb; model->cb = (esp_ble_mesh_model_cbs_t *)&bt_mesh_cfg_srv_cb;
struct bt_mesh_cfg_srv *srv = (struct bt_mesh_cfg_srv *)model->user_data; struct bt_mesh_cfg_srv *srv = (struct bt_mesh_cfg_srv *)model->user_data;
if (srv) { if (srv) {
srv->hb_sub.func = btc_ble_mesh_heartbeat_msg_recv_cb; srv->hb_sub.func = btc_ble_mesh_node_recv_heartbeat_cb;
} }
break; break;
} }
@ -1997,6 +2017,31 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg)
param.provisioner_delete_node_with_addr_comp.err_code = param.provisioner_delete_node_with_addr_comp.err_code =
bt_mesh_provisioner_delete_node_with_node_addr(arg->delete_node_with_addr.unicast_addr); bt_mesh_provisioner_delete_node_with_node_addr(arg->delete_node_with_addr.unicast_addr);
break; break;
#if CONFIG_BLE_MESH_PROVISIONER_RECV_HB
case BTC_BLE_MESH_ACT_PROVISIONER_ENABLE_HEARTBEAT_RECV:
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);
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);
break;
case BTC_BLE_MESH_ACT_PROVISIONER_SET_HEARTBEAT_FILTER_INFO:
act = ESP_BLE_MESH_PROVISIONER_SET_HEARTBEAT_FILTER_INFO_COMP_EVT;
param.provisioner_set_heartbeat_filter_info_comp.op = arg->set_heartbeat_filter_info.op;
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);
break;
#endif /* CONFIG_BLE_MESH_PROVISIONER_RECV_HB */
#endif /* CONFIG_BLE_MESH_PROVISIONER */ #endif /* CONFIG_BLE_MESH_PROVISIONER */
#if CONFIG_BLE_MESH_FAST_PROV #if CONFIG_BLE_MESH_FAST_PROV
case BTC_BLE_MESH_ACT_SET_FAST_PROV_INFO: case BTC_BLE_MESH_ACT_SET_FAST_PROV_INFO:

Wyświetl plik

@ -63,6 +63,9 @@ typedef enum {
BTC_BLE_MESH_ACT_PROVISIONER_STORE_NODE_COMP_DATA, BTC_BLE_MESH_ACT_PROVISIONER_STORE_NODE_COMP_DATA,
BTC_BLE_MESH_ACT_PROVISIONER_DELETE_NODE_WITH_UUID, BTC_BLE_MESH_ACT_PROVISIONER_DELETE_NODE_WITH_UUID,
BTC_BLE_MESH_ACT_PROVISIONER_DELETE_NODE_WITH_ADDR, BTC_BLE_MESH_ACT_PROVISIONER_DELETE_NODE_WITH_ADDR,
BTC_BLE_MESH_ACT_PROVISIONER_ENABLE_HEARTBEAT_RECV,
BTC_BLE_MESH_ACT_PROVISIONER_SET_HEARTBEAT_FILTER_TYPE,
BTC_BLE_MESH_ACT_PROVISIONER_SET_HEARTBEAT_FILTER_INFO,
BTC_BLE_MESH_ACT_SET_FAST_PROV_INFO, BTC_BLE_MESH_ACT_SET_FAST_PROV_INFO,
BTC_BLE_MESH_ACT_SET_FAST_PROV_ACTION, BTC_BLE_MESH_ACT_SET_FAST_PROV_ACTION,
BTC_BLE_MESH_ACT_LPN_ENABLE, BTC_BLE_MESH_ACT_LPN_ENABLE,
@ -217,6 +220,17 @@ typedef union {
struct ble_mesh_provisioner_delete_node_with_addr_args { struct ble_mesh_provisioner_delete_node_with_addr_args {
uint16_t unicast_addr; uint16_t unicast_addr;
} delete_node_with_addr; } delete_node_with_addr;
struct {
bool enable;
} enable_heartbeat_recv;
struct {
uint8_t type;
} set_heartbeat_filter_type;
struct {
uint8_t op;
uint16_t hb_src;
uint16_t hb_dst;
} set_heartbeat_filter_info;
struct ble_mesh_set_fast_prov_info_args { struct ble_mesh_set_fast_prov_info_args {
uint16_t unicast_min; uint16_t unicast_min;
uint16_t unicast_max; uint16_t unicast_max;

Wyświetl plik

@ -1544,4 +1544,235 @@ int bt_mesh_provisioner_store_node_info(struct bt_mesh_node *node)
} }
#endif /* CONFIG_BLE_MESH_TEST_AUTO_ENTER_NETWORK */ #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
#define HEARTBEAT_FILTER_WITH_SRC BIT(0)
#define HEARTBEAT_FILTER_WITH_DST BIT(1)
#define HEARTBEAT_FILTER_WITH_BOTH (BIT(1) | BIT(0))
static struct heartbeat_recv {
struct heartbeat_filter {
u8_t type; /* Indicate if using src or dst or both to filter heartbeat messages */
u16_t src; /* Heartbeat source address (unicast address) */
u16_t dst; /* Heartbeat destination address (unicast address or group address) */
} filter[CONFIG_BLE_MESH_PROVISIONER_RECV_HB_FILTER_SIZE];
u8_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(u8_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 inline u8_t get_filter_addr_type(u16_t src, u16_t dst)
{
if (BLE_MESH_ADDR_IS_UNICAST(src)) {
if (BLE_MESH_ADDR_IS_UNICAST(dst) || BLE_MESH_ADDR_IS_GROUP(dst)) {
return HEARTBEAT_FILTER_WITH_BOTH;
} else {
return HEARTBEAT_FILTER_WITH_SRC;
}
} else {
return HEARTBEAT_FILTER_WITH_DST;
}
}
static int hb_filter_alloc(u16_t src, u16_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->type = get_filter_addr_type(src, dst);
filter->src = src;
filter->dst = dst;
return 0;
}
}
BT_ERR("Heartbeat filter is full!");
return -ENOMEM;
}
static int hb_filter_add(u16_t src, u16_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 ((BLE_MESH_ADDR_IS_UNICAST(src) && filter->src == src) ||
((BLE_MESH_ADDR_IS_UNICAST(dst) || BLE_MESH_ADDR_IS_GROUP(dst)) &&
filter->dst == dst)) {
memset(filter, 0, sizeof(struct heartbeat_filter));
}
}
return hb_filter_alloc(src, dst);
}
static int hb_filter_remove(u16_t src, u16_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 ((BLE_MESH_ADDR_IS_UNICAST(src) && filter->src == src) ||
((BLE_MESH_ADDR_IS_UNICAST(dst) || BLE_MESH_ADDR_IS_GROUP(dst)) &&
filter->dst == dst)) {
memset(filter, 0, sizeof(struct heartbeat_filter));
}
}
return 0;
}
int bt_mesh_provisioner_set_heartbeat_filter_info(u8_t op, u16_t src, u16_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(struct heartbeat_filter *filter,
u16_t hb_src, u16_t hb_dst)
{
switch (filter->type) {
case HEARTBEAT_FILTER_WITH_SRC:
if (hb_src == filter->src) {
return true;
}
break;
case HEARTBEAT_FILTER_WITH_DST:
if (hb_dst == filter->dst) {
return true;
}
break;
case HEARTBEAT_FILTER_WITH_BOTH:
if (hb_src == filter->src && hb_dst == filter->dst) {
return true;
}
break;
default:
BT_WARN("Unknown filter addr type 0x%02x", filter->type);
break;
}
return false;
}
static bool filter_with_acceptlist(struct heartbeat_filter *filter,
u16_t hb_src, u16_t hb_dst)
{
switch (filter->type) {
case HEARTBEAT_FILTER_WITH_SRC:
if (hb_src == filter->src) {
return false;
}
break;
case HEARTBEAT_FILTER_WITH_DST:
if (hb_dst == filter->dst) {
return false;
}
break;
case HEARTBEAT_FILTER_WITH_BOTH:
if (hb_src == filter->src && hb_dst == filter->dst) {
return false;
}
break;
default:
BT_WARN("Unknown filter addr type 0x%02x", filter->type);
return false;
}
return true;
}
void bt_mesh_provisioner_heartbeat(u16_t hb_src, u16_t hb_dst,
u8_t init_ttl, u8_t rx_ttl,
u8_t hops, u16_t feat, s8_t rssi)
{
int i;
if (hb_rx.cb == NULL) {
BT_DBG("Receiving heartbeat is not enabled");
return;
}
for (i = 0; i < ARRAY_SIZE(hb_rx.filter); i++) {
struct heartbeat_filter *filter = &hb_rx.filter[i];
if (hb_rx.type == HEARTBEAT_FILTER_REJECTLIST) {
if (filter_with_rejectlist(filter, hb_src, hb_dst)) {
BT_DBG("Filtered by rejectlist, src 0x%04x, dst 0x%04x", hb_src, hb_dst);
return;
}
} else {
if (filter_with_acceptlist(filter, hb_src, hb_dst)) {
BT_DBG("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 */ #endif /* CONFIG_BLE_MESH_PROVISIONER */

Wyświetl plik

@ -125,6 +125,20 @@ int bt_mesh_provisioner_local_net_key_del(u16_t net_idx, bool store);
int bt_mesh_provisioner_bind_local_model_app_idx(u16_t elem_addr, u16_t mod_id, int bt_mesh_provisioner_bind_local_model_app_idx(u16_t elem_addr, u16_t mod_id,
u16_t cid, u16_t app_idx); u16_t cid, u16_t app_idx);
typedef void (* bt_mesh_heartbeat_recv_cb_t)(u16_t hb_src, u16_t hb_dst,
u8_t init_ttl, u8_t rx_ttl,
u8_t hops, u16_t feat, s8_t rssi);
int bt_mesh_provisioner_recv_heartbeat(bt_mesh_heartbeat_recv_cb_t cb);
int bt_mesh_provisioner_set_heartbeat_filter_type(u8_t filter_type);
int bt_mesh_provisioner_set_heartbeat_filter_info(u8_t op, u16_t src, u16_t dst);
void bt_mesh_provisioner_heartbeat(u16_t hb_src, u16_t hb_dst,
u8_t init_ttl, u8_t rx_ttl,
u8_t hops, u16_t feat, s8_t rssi);
/* Provisioner print own element information */ /* Provisioner print own element information */
int bt_mesh_print_local_composition_data(void); int bt_mesh_print_local_composition_data(void);

Wyświetl plik

@ -966,7 +966,8 @@ static int trans_heartbeat(struct bt_mesh_net_rx *rx,
return -EINVAL; return -EINVAL;
} }
if (rx->ctx.recv_dst != hb_sub_dst) { if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned() &&
rx->ctx.recv_dst != hb_sub_dst) {
BT_WARN("Ignoring heartbeat to non-subscribed destination"); BT_WARN("Ignoring heartbeat to non-subscribed destination");
return 0; return 0;
} }
@ -980,7 +981,13 @@ static int trans_heartbeat(struct bt_mesh_net_rx *rx,
rx->ctx.addr, rx->ctx.recv_ttl, init_ttl, hops, rx->ctx.addr, rx->ctx.recv_ttl, init_ttl, hops,
(hops == 1U) ? "" : "s", feat); (hops == 1U) ? "" : "s", feat);
bt_mesh_heartbeat(rx->ctx.addr, rx->ctx.recv_dst, hops, feat); if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) {
bt_mesh_heartbeat(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);
}
return 0; return 0;
} }