Bluetooth: Mesh: add statistic module
PR adds the statistic module to estimate frame handling. The module helps to understand the ratio of the received\relayed\dropped\transmited frames. That shows the efficiency of the current configuration\implementation. Signed-off-by: Aleksandr Khromykh <aleksandr.khromykh@nordicsemi.no>
This commit is contained in:
parent
3f2daa256c
commit
7199425792
11 changed files with 213 additions and 23 deletions
|
@ -21,4 +21,5 @@ Read more about Bluetooth mesh on the
|
|||
mesh/proxy.rst
|
||||
mesh/heartbeat.rst
|
||||
mesh/cfg.rst
|
||||
mesh/statistic.rst
|
||||
mesh/shell.rst
|
||||
|
|
19
doc/connectivity/bluetooth/api/mesh/statistic.rst
Normal file
19
doc/connectivity/bluetooth/api/mesh/statistic.rst
Normal file
|
@ -0,0 +1,19 @@
|
|||
.. _bluetooth_mesh_stat:
|
||||
|
||||
Frame statistic
|
||||
###############
|
||||
|
||||
The frame statistic API allows monitoring the number of received frames over
|
||||
different interfaces, and the number of planned and succeeded transmission and
|
||||
relaying attempts.
|
||||
|
||||
The API helps the user to estimate the efficiency of the advertiser configuration
|
||||
parameters and the scanning ability of the device. The number of the monitored
|
||||
parameters can be easily extended by customer values.
|
||||
|
||||
An application can read out and clean up statistics at any time.
|
||||
|
||||
API reference
|
||||
*************
|
||||
|
||||
.. doxygengroup:: bt_mesh_stat
|
|
@ -48,5 +48,6 @@
|
|||
#include <zephyr/bluetooth/mesh/od_priv_proxy_cli.h>
|
||||
#include <zephyr/bluetooth/mesh/sol_pdu_rpl_srv.h>
|
||||
#include <zephyr/bluetooth/mesh/sol_pdu_rpl_cli.h>
|
||||
#include <zephyr/bluetooth/mesh/statistic.h>
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_H_ */
|
||||
|
|
69
include/zephyr/bluetooth/mesh/statistic.h
Normal file
69
include/zephyr/bluetooth/mesh/statistic.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
/** @file
|
||||
* @brief BLE mesh statistic APIs.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2023 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_STATISTIC_H_
|
||||
#define ZEPHYR_INCLUDE_BLUETOOTH_MESH_STATISTIC_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @brief Statistic
|
||||
* @defgroup bt_mesh_stat Statistic
|
||||
* @ingroup bt_mesh
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** The structure that keeps statistics of mesh frames handling. */
|
||||
struct bt_mesh_statistic {
|
||||
/** All received frames passed basic validation and decryption. */
|
||||
/** Received frames over advertiser. */
|
||||
uint32_t rx_adv;
|
||||
/** Received frames over loopback. */
|
||||
uint32_t rx_loopback;
|
||||
/** Received frames over proxy. */
|
||||
uint32_t rx_proxy;
|
||||
/** Received over unknown interface. */
|
||||
uint32_t rx_uknown;
|
||||
/** Counter of frames that were initiated to relay over advertiser bearer. */
|
||||
uint32_t tx_adv_relay_planned;
|
||||
/** Counter of frames that succeeded relaying over advertiser bearer. */
|
||||
uint32_t tx_adv_relay_succeeded;
|
||||
/** Counter of frames that were initiated to send over advertiser bearer locally. */
|
||||
uint32_t tx_local_planned;
|
||||
/** Counter of frames that succeeded to send over advertiser bearer locally. */
|
||||
uint32_t tx_local_succeeded;
|
||||
/** Counter of frames that were initiated to send over friend bearer. */
|
||||
uint32_t tx_friend_planned;
|
||||
/** Counter of frames that succeeded to send over friend bearer. */
|
||||
uint32_t tx_friend_succeeded;
|
||||
};
|
||||
|
||||
/** @brief Get mesh frame handling statistic.
|
||||
*
|
||||
* @param st BLE mesh statistic.
|
||||
*/
|
||||
void bt_mesh_stat_get(struct bt_mesh_statistic *st);
|
||||
|
||||
/** @brief Reset mesh frame handling statistic.
|
||||
*/
|
||||
void bt_mesh_stat_reset(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_STATISTIC_H_ */
|
|
@ -120,6 +120,8 @@ zephyr_library_sources_ifdef(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV sol_pdu_rpl_srv.c)
|
|||
|
||||
zephyr_library_sources_ifdef(CONFIG_BT_MESH_SOLICITATION solicitation.c)
|
||||
|
||||
zephyr_library_sources_ifdef(CONFIG_BT_MESH_STATISTIC statistic.c)
|
||||
|
||||
if (CONFIG_BT_MESH_USES_TINYCRYPT)
|
||||
zephyr_library_sources(crypto_tc.c)
|
||||
else()
|
||||
|
|
|
@ -1666,4 +1666,12 @@ config BT_MESH_DEBUG_USE_ID_ADDR
|
|||
|
||||
endif # BT_MESH_LOG_LEVEL_DBG
|
||||
|
||||
config BT_MESH_STATISTIC
|
||||
bool "The frame handling statistics [EXPERIMENTAL]"
|
||||
select EXPERIMENTAL
|
||||
help
|
||||
The module gathers statistics of received, relayed, and transmitted
|
||||
frames. This helps to estimate the quality of the communication and
|
||||
the sufficiency of configured advertiser instances.
|
||||
|
||||
endif # BT_MESH
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "proxy.h"
|
||||
#include "pb_gatt_srv.h"
|
||||
#include "solicitation.h"
|
||||
#include "statistic.h"
|
||||
|
||||
#define LOG_LEVEL CONFIG_BT_MESH_ADV_LOG_LEVEL
|
||||
#include <zephyr/logging/log.h>
|
||||
|
@ -46,6 +47,30 @@ static K_FIFO_DEFINE(bt_mesh_adv_queue);
|
|||
static K_FIFO_DEFINE(bt_mesh_relay_queue);
|
||||
static K_FIFO_DEFINE(bt_mesh_friend_queue);
|
||||
|
||||
void bt_mesh_adv_send_start(uint16_t duration, int err, struct bt_mesh_adv *adv)
|
||||
{
|
||||
if (!adv->started) {
|
||||
adv->started = 1;
|
||||
|
||||
if (adv->cb && adv->cb->start) {
|
||||
adv->cb->start(duration, err, adv->cb_data);
|
||||
}
|
||||
|
||||
if (err) {
|
||||
adv->cb = NULL;
|
||||
} else if (IS_ENABLED(CONFIG_BT_MESH_STATISTIC)) {
|
||||
bt_mesh_stat_succeeded_count(adv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void bt_mesh_adv_send_end(int err, struct bt_mesh_adv const *adv)
|
||||
{
|
||||
if (adv->started && adv->cb && adv->cb->end) {
|
||||
adv->cb->end(err, adv->cb_data);
|
||||
}
|
||||
}
|
||||
|
||||
static void adv_buf_destroy(struct net_buf *buf)
|
||||
{
|
||||
struct bt_mesh_adv adv = *BT_MESH_ADV(buf);
|
||||
|
@ -230,6 +255,10 @@ void bt_mesh_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb,
|
|||
BT_MESH_ADV(buf)->cb_data = cb_data;
|
||||
BT_MESH_ADV(buf)->busy = 1U;
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_MESH_STATISTIC)) {
|
||||
bt_mesh_stat_planned_count(BT_MESH_ADV(buf));
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) &&
|
||||
BT_MESH_ADV(buf)->tag == BT_MESH_FRIEND_ADV) {
|
||||
net_buf_put(&bt_mesh_friend_queue, net_buf_ref(buf));
|
||||
|
|
|
@ -83,29 +83,7 @@ int bt_mesh_adv_gatt_start(const struct bt_le_adv_param *param, int32_t duration
|
|||
const struct bt_data *ad, size_t ad_len,
|
||||
const struct bt_data *sd, size_t sd_len);
|
||||
|
||||
static inline void bt_mesh_adv_send_start(uint16_t duration, int err,
|
||||
struct bt_mesh_adv *adv)
|
||||
{
|
||||
if (!adv->started) {
|
||||
adv->started = 1;
|
||||
|
||||
if (adv->cb && adv->cb->start) {
|
||||
adv->cb->start(duration, err, adv->cb_data);
|
||||
}
|
||||
|
||||
if (err) {
|
||||
adv->cb = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void bt_mesh_adv_send_end(
|
||||
int err, struct bt_mesh_adv const *adv)
|
||||
{
|
||||
if (adv->started && adv->cb && adv->cb->end) {
|
||||
adv->cb->end(err, adv->cb_data);
|
||||
}
|
||||
}
|
||||
void bt_mesh_adv_send_start(uint16_t duration, int err, struct bt_mesh_adv *adv);
|
||||
|
||||
int bt_mesh_scan_active_set(bool active);
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "settings.h"
|
||||
#include "prov.h"
|
||||
#include "cfg.h"
|
||||
#include "statistic.h"
|
||||
|
||||
#ifdef CONFIG_BT_MESH_V1d1
|
||||
#include "sar_cfg_internal.h"
|
||||
|
@ -851,6 +852,10 @@ void bt_mesh_net_recv(struct net_buf_simple *data, int8_t rssi,
|
|||
return;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_MESH_STATISTIC)) {
|
||||
bt_mesh_stat_rx(net_if);
|
||||
}
|
||||
|
||||
/* Save the state so the buffer can later be relayed */
|
||||
net_buf_simple_save(&buf, &state);
|
||||
|
||||
|
|
64
subsys/bluetooth/mesh/statistic.c
Normal file
64
subsys/bluetooth/mesh/statistic.c
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/bluetooth/mesh.h>
|
||||
|
||||
#include "adv.h"
|
||||
#include "net.h"
|
||||
#include "statistic.h"
|
||||
|
||||
static struct bt_mesh_statistic stat;
|
||||
|
||||
void bt_mesh_stat_get(struct bt_mesh_statistic *st)
|
||||
{
|
||||
memcpy(st, &stat, sizeof(struct bt_mesh_statistic));
|
||||
}
|
||||
|
||||
void bt_mesh_stat_reset(void)
|
||||
{
|
||||
memset(&stat, 0, sizeof(struct bt_mesh_statistic));
|
||||
}
|
||||
|
||||
void bt_mesh_stat_planned_count(struct bt_mesh_adv *adv)
|
||||
{
|
||||
if (adv->tag & BT_MESH_LOCAL_ADV) {
|
||||
stat.tx_local_planned++;
|
||||
} else if (adv->tag & BT_MESH_RELAY_ADV) {
|
||||
stat.tx_adv_relay_planned++;
|
||||
} else if (adv->tag & BT_MESH_FRIEND_ADV) {
|
||||
stat.tx_friend_planned++;
|
||||
}
|
||||
}
|
||||
|
||||
void bt_mesh_stat_succeeded_count(struct bt_mesh_adv *adv)
|
||||
{
|
||||
if (adv->tag & BT_MESH_LOCAL_ADV) {
|
||||
stat.tx_local_succeeded++;
|
||||
} else if (adv->tag & BT_MESH_RELAY_ADV) {
|
||||
stat.tx_adv_relay_succeeded++;
|
||||
} else if (adv->tag & BT_MESH_FRIEND_ADV) {
|
||||
stat.tx_friend_succeeded++;
|
||||
}
|
||||
}
|
||||
|
||||
void bt_mesh_stat_rx(enum bt_mesh_net_if net_if)
|
||||
{
|
||||
switch (net_if) {
|
||||
case BT_MESH_NET_IF_ADV:
|
||||
stat.rx_adv++;
|
||||
break;
|
||||
case BT_MESH_NET_IF_LOCAL:
|
||||
stat.rx_loopback++;
|
||||
break;
|
||||
case BT_MESH_NET_IF_PROXY:
|
||||
case BT_MESH_NET_IF_PROXY_CFG:
|
||||
stat.rx_proxy++;
|
||||
break;
|
||||
default:
|
||||
stat.rx_uknown++;
|
||||
break;
|
||||
}
|
||||
}
|
14
subsys/bluetooth/mesh/statistic.h
Normal file
14
subsys/bluetooth/mesh/statistic.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_SUBSYS_BLUETOOTH_MESH_STATISTIC_H_
|
||||
#define ZEPHYR_SUBSYS_BLUETOOTH_MESH_STATISTIC_H_
|
||||
|
||||
void bt_mesh_stat_planned_count(struct bt_mesh_adv *adv);
|
||||
void bt_mesh_stat_succeeded_count(struct bt_mesh_adv *adv);
|
||||
void bt_mesh_stat_rx(enum bt_mesh_net_if net_if);
|
||||
|
||||
#endif /* ZEPHYR_SUBSYS_BLUETOOTH_MESH_STATISTIC_H_ */
|
Loading…
Add table
Add a link
Reference in a new issue