SatCat5
switch_telemetry.cc
1 // Copyright 2024-2025 The Aerospace Corporation.
3 // This file is a part of SatCat5, licensed under CERN-OHL-W v2 or later.
5 
6 #include <satcat5/cfgbus_stats.h>
7 #include <satcat5/switch_cfg.h>
8 #include <satcat5/switch_telemetry.h>
9 
10 // Enable this feature? (See types.h)
11 #if SATCAT5_CBOR_ENABLE
12 
18 
19 static void copy_mactbl_array(QCBOREncodeContext* cbor, SwitchConfig* cfg) {
20  unsigned port_idx;
21  satcat5::eth::MacAddr mac_addr;
22  unsigned table_size = cfg->mactbl_size();
23 
24  // Write a CBOR array containing MAC table information.
25  QCBOREncode_OpenArray(cbor);
26  for (unsigned tbl_idx = 0 ; tbl_idx < table_size ; ++tbl_idx) {
27  if (cfg->mactbl_read(tbl_idx, port_idx, mac_addr)) {
28  // Each table entry is a paired MAC address + port-index.
29  QCBOREncode_OpenArray(cbor);
30  QCBOREncode_AddBytes(cbor, {mac_addr.addr, 6});
31  QCBOREncode_AddUInt64(cbor, port_idx);
32  QCBOREncode_CloseArray(cbor);
33  }
34  }
35  QCBOREncode_CloseArray(cbor);
36 }
37 
38 static void copy_traffic_array(QCBOREncodeContext* cbor, unsigned port_count, NetworkStats* stats) {
39  // Write a CBOR array containing traffic statistics for each port.
40  QCBOREncode_OpenArray(cbor);
41  for (unsigned a = 0 ; a < port_count ; ++a) {
42  // Read port data, then write out a CBOR key/value dictionary.
43  TrafficStats data = stats->get_port(a);
44  QCBOREncode_OpenMap(cbor);
45  QCBOREncode_AddUInt64ToMap(cbor, "rxb", data.rcvd_bytes);
46  QCBOREncode_AddUInt64ToMap(cbor, "rxf", data.rcvd_frames);
47  QCBOREncode_AddUInt64ToMap(cbor, "txb", data.sent_bytes);
48  QCBOREncode_AddUInt64ToMap(cbor, "txf", data.sent_frames);
49  if (data.errct_mac) QCBOREncode_AddUInt64ToMap(cbor, "err_mac", data.errct_mac);
50  if (data.errct_ovr_tx) QCBOREncode_AddUInt64ToMap(cbor, "err_ovr_tx", data.errct_ovr_tx);
51  if (data.errct_ovr_rx) QCBOREncode_AddUInt64ToMap(cbor, "err_ovr_rx", data.errct_ovr_rx);
52  if (data.errct_pkt) QCBOREncode_AddUInt64ToMap(cbor, "err_pkt", data.errct_pkt);
53  if (data.errct_ptp_tx) QCBOREncode_AddUInt64ToMap(cbor, "err_ptp_tx", data.errct_ptp_tx);
54  if (data.errct_ptp_rx) QCBOREncode_AddUInt64ToMap(cbor, "err_ptp_rx", data.errct_ptp_rx);
55  QCBOREncode_CloseMap(cbor);
56  }
57  QCBOREncode_CloseArray(cbor);
58 }
59 
60 SwitchTelemetry::SwitchTelemetry(
64  : m_cfg(cfg) // Required
65  , m_stats(stats) // Optional
66  , m_tier1(tlm, this, 1, 30000)
67  , m_tier2(tlm, this, 2, 1000)
68 {
69  // Nothing else to initialize.
70 }
71 
72 void SwitchTelemetry::telem_event(u32 tier_id, TelemetryCbor& cbor) {
73  if (tier_id == 1) {
74  // Switch status information.
75  u32 pmask = m_cfg->get_promiscuous_mask();
76  cbor.add_item("bmask", m_cfg->get_miss_mask());
77  if (pmask) cbor.add_item("pmask", pmask);
78  // Write the MAC table contents as a nested array.
79  QCBOREncode_AddSZString(cbor.cbor, "mactbl");
80  copy_mactbl_array(cbor.cbor, m_cfg);
81  } else {
82  // Total traffic statistics from the switch itself.
83  u16 filter = m_cfg->get_traffic_filter();
84  if (filter) cbor.add_item("traffic_etype_filter", filter);
85  cbor.add_item("traffic_total_frm", m_cfg->get_traffic_count());
86  // Per-port counters, if available.
87  if (m_stats) {
88  m_stats->refresh_now();
89  QCBOREncode_AddSZString(cbor.cbor, "traffic_by_port");
90  copy_traffic_array(cbor.cbor, m_cfg->port_count(), m_stats);
91  }
92  }
93 }
94 
95 #endif // SATCAT5_CBOR_ENABLE
QCBOREncodeContext *const cbor
QCBOR context pointer.
Definition: io_cbor.h:124
void add_item(KEYTYPE key, s8 value) const
Write a scalar value to the Map.
Definition: io_cbor.h:312
Traffic statistics polling.
Definition: cfgbus_stats.h:49
satcat5::cfg::TrafficStats get_port(unsigned idx)
Read most recent statistics for the Nth port.
Definition: cfgbus_stats.cc:36
void refresh_now()
Immediately refresh statistics for every port.
Definition: cfgbus_stats.cc:31
Management functions for a SatCat5 Ethernet switch.
Definition: switch_cfg.h:166
u32 get_miss_mask()
Identify which ports are currently in "miss-as-broadcast" mode.
Definition: switch_cfg.cc:91
unsigned mactbl_size()
Read the maximum size of the MAC-address table.
Definition: switch_cfg.cc:273
u32 get_promiscuous_mask()
Identify which ports are currently promiscuous.
Definition: switch_cfg.cc:106
u16 get_traffic_filter() const
Query the current traffic filter setting.
Definition: switch_cfg.h:211
u32 get_traffic_count()
Report matching frames since last call to get_traffic_count().
Definition: switch_cfg.cc:115
u32 port_count()
Number of ports on this switch.
Definition: switch_cfg.cc:44
bool mactbl_read(unsigned tbl_idx, unsigned &port_idx, satcat5::eth::MacAddr &mac_addr)
Read the Nth entry from the MAC-address table.
Definition: switch_cfg.cc:232
Diagnostic telemetry for a SatCat5 switch.
void telem_event(u32 tier_id, satcat5::net::TelemetryCbor &cbor) override
User method for writing each telemetry message.
Protocol-agnostic handler for one or more TelemetryTier objects.
Legacy ephemeral wrapper class for the CBOR encoder.
Data structure for reading per-port traffic statistics.
Definition: cfgbus_stats.h:19
u8 errct_ovr_rx
Rx-FIFO overflow (rare)
Definition: cfgbus_stats.h:35
u32 sent_frames
Total frames sent from switch to device.
Definition: cfgbus_stats.h:30
u8 errct_ptp_tx
TX PTP packets with bad tstamps.
Definition: cfgbus_stats.h:38
u8 errct_mac
MAC/PHY errors.
Definition: cfgbus_stats.h:33
u8 errct_ovr_tx
Tx-FIFO overflow (common)
Definition: cfgbus_stats.h:34
u8 errct_pkt
Packet errors (bad checksum, length, etc.)
Definition: cfgbus_stats.h:36
u32 rcvd_bytes
Total bytes received from device.
Definition: cfgbus_stats.h:27
u32 sent_bytes
Total bytes sent from switch to device.
Definition: cfgbus_stats.h:29
u32 rcvd_frames
Total frames received from device.
Definition: cfgbus_stats.h:28
u8 errct_ptp_rx
RX PTP packets with bad tstamps.
Definition: cfgbus_stats.h:37
An Ethernet MAC address (with serializable interface).
Definition: eth_header.h:29
u8 addr[6]
Byte array in network order (Index 0 = MSB)
Definition: eth_header.h:31
Configuration for a managed SatCat5 switch.