Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 23 additions & 15 deletions ports/zephyr/common/metrics/memfault_platform_bluetooth_metrics.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,18 @@
#include "memfault/metrics/platform/timer.h"
#include "memfault/ports/zephyr/version.h"

#define BT_LE_INTERVAL_UNIT_US (1250U)

static struct bt_conn *s_mflt_bt_current_conn = NULL;
static uint16_t s_mflt_bt_connection_interval = 0;
static uint32_t s_mflt_bt_connection_interval_us = 0;
struct k_work_delayable s_mflt_bt_delayed_metrics_work;

static void prv_record_gatt_mtu(struct bt_conn *conn) {
uint16_t mtu = bt_gatt_get_mtu(conn);
MEMFAULT_METRIC_SET_UNSIGNED(bt_gatt_mtu_size, mtu);
}

static void prv_count_connection_events(uint16_t interval, bool reset_time) {
static void prv_count_connection_events(uint32_t interval_us, bool reset_time) {
// to accumulate data correctly on:
// - connection interval change
// - connection up/down
Expand All @@ -47,10 +49,9 @@ static void prv_count_connection_events(uint16_t interval, bool reset_time) {
return;
}

if (interval) {
// connection interval is in units of 1.25ms
// calculate events per second: 1000ms / (interval * 1.25ms)
int32_t events_per_second = 800 / interval; // 1000 / 1.25 = 800
if (interval_us) {
// calculate events per second: 1000000us / interval_us
int32_t events_per_second = 1000000 / interval_us;

// compute connection events accumulated
const uint64_t current_time_ms = memfault_platform_get_time_since_boot_ms();
Expand Down Expand Up @@ -138,13 +139,18 @@ static void prv_delayed_metrics_work_handler(struct k_work *work) {
static void prv_record_connection_params(struct bt_conn *conn) {
struct bt_conn_info info;
if (bt_conn_get_info(conn, &info) == 0) {
MEMFAULT_METRIC_SET_UNSIGNED(bt_connection_interval, info.le.interval);
MEMFAULT_METRIC_SET_UNSIGNED(bt_connection_interval_us, info.le.interval_us);
MEMFAULT_METRIC_SET_UNSIGNED(bt_connection_latency, info.le.latency);
MEMFAULT_METRIC_SET_UNSIGNED(bt_connection_timeout, info.le.timeout);
s_mflt_bt_connection_interval = info.le.interval;
#if (defined(MEMFAULT_ZEPHYR_VERSION_GT) && MEMFAULT_ZEPHYR_VERSION_GT(4, 3)) || \
(defined(MEMFAULT_NCS_VERSION_GT) && MEMFAULT_NCS_VERSION_GT(3, 1))
s_mflt_bt_connection_interval_us = info.le.interval_us;
#else
s_mflt_bt_connection_interval_us = info.le.interval * BT_LE_INTERVAL_UNIT_US;
#endif
} else {
MEMFAULT_LOG_ERROR("Failed to get connection info");
s_mflt_bt_connection_interval = 0;
s_mflt_bt_connection_interval_us = 0;
}
}

Expand Down Expand Up @@ -172,8 +178,8 @@ static void prv_bt_connected_cb(struct bt_conn *conn, uint8_t err) {

static void prv_bt_disconnected_cb(struct bt_conn *conn, uint8_t reason) {
// tally connection events
prv_count_connection_events(s_mflt_bt_connection_interval, false);
s_mflt_bt_connection_interval = 0;
prv_count_connection_events(s_mflt_bt_connection_interval_us, false);
s_mflt_bt_connection_interval_us = 0;

if (s_mflt_bt_current_conn == conn) {
bt_conn_unref(s_mflt_bt_current_conn);
Expand Down Expand Up @@ -203,16 +209,18 @@ static void prv_record_remote_info_cb(struct bt_conn *conn,

static void prv_bt_le_param_updated_cb(struct bt_conn *conn, uint16_t interval, uint16_t latency,
uint16_t timeout) {
uint32_t interval_us = interval * BT_LE_INTERVAL_UNIT_US;

// Record LE connection parameters
MEMFAULT_METRIC_SET_UNSIGNED(bt_connection_interval, interval);
MEMFAULT_METRIC_SET_UNSIGNED(bt_connection_interval_us, interval_us);
MEMFAULT_METRIC_SET_UNSIGNED(bt_connection_latency, latency);
MEMFAULT_METRIC_SET_UNSIGNED(bt_connection_timeout, timeout);

// Tally connection event counts received with the previous interval setting
prv_count_connection_events(s_mflt_bt_connection_interval, false);
prv_count_connection_events(s_mflt_bt_connection_interval_us, false);

// Update connection interval for computing connection event count
s_mflt_bt_connection_interval = interval;
s_mflt_bt_connection_interval_us = interval_us;
}

BT_CONN_CB_DEFINE(bt_metrics_conn_callbacks) = {
Expand All @@ -238,7 +246,7 @@ static struct bt_gatt_cb prv_gatt_callbacks = {
void memfault_bluetooth_metrics_heartbeat_update(void) {
if (s_mflt_bt_current_conn != NULL) {
// Update connection event count estimate
prv_count_connection_events(s_mflt_bt_connection_interval, false);
prv_count_connection_events(s_mflt_bt_connection_interval_us, false);

// Record current RSSI (if available)
prv_record_connection_rssi(s_mflt_bt_current_conn);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ MEMFAULT_METRICS_KEY_DEFINE(bt_gatt_mtu_size, kMemfaultMetricType_Unsigned)
MEMFAULT_METRICS_STRING_KEY_DEFINE(bt_connection_remote_info, sizeof("ff:ffff.ffff") - 1)
#endif // defined(CONFIG_BT_REMOTE_VERSION)
MEMFAULT_METRICS_KEY_DEFINE(bt_connection_event_count, kMemfaultMetricType_Unsigned)
MEMFAULT_METRICS_KEY_DEFINE(bt_connection_interval, kMemfaultMetricType_Unsigned)
MEMFAULT_METRICS_KEY_DEFINE(bt_connection_interval_us, kMemfaultMetricType_Unsigned)
MEMFAULT_METRICS_KEY_DEFINE(bt_connection_latency, kMemfaultMetricType_Unsigned)
MEMFAULT_METRICS_KEY_DEFINE(bt_connection_timeout, kMemfaultMetricType_Unsigned)
#if defined(CONFIG_BT_CTLR_CONN_RSSI)
Expand Down