blob: 685bcc93c87edf5720a756ef283e3f6b5d09d737 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef GARNET_LIB_WLAN_COMMON_INCLUDE_WLAN_COMMON_STATS_H_
#define GARNET_LIB_WLAN_COMMON_INCLUDE_WLAN_COMMON_STATS_H_
#include <fuchsia/wlan/stats/cpp/fidl.h>
#include <wlan/common/logging.h>
#include <atomic>
#include <string>
namespace wlan {
constexpr bool kStatsDebugEnabled = false;
#define WLAN_STATS_ADD(i, v) \
do { \
stats_.stats.v.Inc(i); \
if (kStatsDebugEnabled) { \
if (stats_.stats.v.name.empty()) { \
stats_.stats.v.name = __PRETTY_FUNCTION__; \
debugf("Enabled statistics for %s\n", stats_.stats.v.name.c_str()); \
} \
} \
} while (0)
#define WLAN_STATS_INC(v) WLAN_STATS_ADD(1UL, v)
#define WLAN_RSSI_HIST_INC(s, r) stats_.stats.s.Inc(r, 1UL)
namespace common {
struct Counter {
std::atomic_uint64_t count{0};
std::string name; // Dynamically set at run-time
::fuchsia::wlan::stats::Counter ToFidl() const {
return ::fuchsia::wlan::stats::Counter{.count = count.load(std::memory_order_relaxed),
.name = name};
};
void Reset() { count = 0; }
uint64_t Inc(uint64_t i) { return count.fetch_add(i, std::memory_order_relaxed); }
};
struct PacketCounter {
Counter in;
Counter out;
Counter drop;
Counter in_bytes;
Counter out_bytes;
Counter drop_bytes;
::fuchsia::wlan::stats::PacketCounter ToFidl() const {
return ::fuchsia::wlan::stats::PacketCounter{.in = in.ToFidl(),
.out = out.ToFidl(),
.drop = drop.ToFidl(),
.in_bytes = in_bytes.ToFidl(),
.out_bytes = out_bytes.ToFidl(),
.drop_bytes = drop_bytes.ToFidl()};
};
void Reset() {
in.Reset();
out.Reset();
drop.Reset();
in_bytes.Reset();
out_bytes.Reset();
drop_bytes.Reset();
}
};
// LINT.IfChange
struct DispatcherStats {
PacketCounter any_packet;
PacketCounter mgmt_frame;
PacketCounter ctrl_frame;
PacketCounter data_frame;
::fuchsia::wlan::stats::DispatcherStats ToFidl() const {
return ::fuchsia::wlan::stats::DispatcherStats{.any_packet = any_packet.ToFidl(),
.mgmt_frame = mgmt_frame.ToFidl(),
.ctrl_frame = ctrl_frame.ToFidl(),
.data_frame = data_frame.ToFidl()};
};
void Reset() {
any_packet.Reset();
mgmt_frame.Reset();
ctrl_frame.Reset();
data_frame.Reset();
}
};
struct RssiStats {
RssiStats() { std::fill(std::begin(hist), std::end(hist), 0); }
::fuchsia::wlan::stats::RssiStats ToFidl() const {
std::lock_guard<std::mutex> guard(lock);
::fuchsia::wlan::stats::RssiStats rssi_stats{};
rssi_stats.hist =
std::vector<uint64_t>(hist, hist + ::fuchsia::wlan::stats::RSSI_BINS);
return rssi_stats;
};
void Reset() {
std::lock_guard<std::mutex> guard(lock);
std::fill(std::begin(hist), std::end(hist), 0);
}
uint64_t Inc(const int8_t r, const uint64_t delta) {
if (r > 0 || -r >= ::fuchsia::wlan::stats::RSSI_BINS) { return 0; }
std::lock_guard<std::mutex> guard(lock);
return hist[-r] += delta;
}
uint64_t Get(const int8_t r) {
if (r > 0 || -r >= ::fuchsia::wlan::stats::RSSI_BINS) { return 0; }
std::lock_guard<std::mutex> guard(lock);
return hist[-r];
}
private:
uint64_t hist[::fuchsia::wlan::stats::RSSI_BINS] __TA_GUARDED(lock);
mutable std::mutex lock;
};
struct ClientMlmeStats {
PacketCounter svc_msg;
PacketCounter data_frame;
PacketCounter mgmt_frame;
PacketCounter tx_frame;
PacketCounter rx_frame;
RssiStats assoc_data_rssi;
RssiStats beacon_rssi;
::fuchsia::wlan::stats::ClientMlmeStats ToFidl() const {
return ::fuchsia::wlan::stats::ClientMlmeStats{.svc_msg = svc_msg.ToFidl(),
.data_frame = data_frame.ToFidl(),
.mgmt_frame = mgmt_frame.ToFidl(),
.tx_frame = tx_frame.ToFidl(),
.rx_frame = rx_frame.ToFidl(),
.assoc_data_rssi = assoc_data_rssi.ToFidl(),
.beacon_rssi = beacon_rssi.ToFidl()};
};
void Reset() {
svc_msg.Reset();
data_frame.Reset();
mgmt_frame.Reset();
tx_frame.Reset();
rx_frame.Reset();
assoc_data_rssi.Reset();
beacon_rssi.Reset();
}
};
// LINT.ThenChange(//garnet/public/lib/wlan/fidl/wlan_stats.fidl)
template <typename T, typename U> class WlanStats {
public:
T stats;
U ToFidl() const { return stats.ToFidl(); };
void Reset() { stats.Reset(); }
};
} // namespace common
} // namespace wlan
#endif // GARNET_LIB_WLAN_COMMON_INCLUDE_WLAN_COMMON_STATS_H_