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:
Aleksandr Khromykh 2023-06-29 16:14:27 +02:00 committed by Carles Cufí
commit 7199425792
11 changed files with 213 additions and 23 deletions

View file

@ -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

View 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

View file

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

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

View file

@ -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()

View file

@ -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

View file

@ -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));

View file

@ -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);

View file

@ -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);

View 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;
}
}

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