12 #if SATCAT5_CBOR_ENABLE
14 #include <qcbor/qcbor.h>
36 :
Protocol(satcat5::net::Type(type.value))
43 #if SATCAT5_ALLOW_DELETION
44 satcat5::eth::TelemetryRx::~TelemetryRx() {
45 m_iface->remove(
this);
66 : Protocol(satcat5::net::Type(port.value))
73 #if SATCAT5_ALLOW_DELETION
74 satcat5::udp::TelemetryRx::~TelemetryRx() {
75 m_iface->remove(
this);
95 TelemetryAggregator::TelemetryAggregator(
bool concat_tiers)
96 : m_tlm_concat(concat_tiers)
107 tier->telem_poll(cbor);
109 tier = m_tiers.
next(tier);
116 tier->telem_poll(cbor);
117 tier = m_tiers.
next(tier);
125 if (!cbor.
close()) {
return; }
130 if (encoded.len < 2)
return;
135 sink->
telem_ready(tier_id, encoded.len, encoded.ptr);
136 sink = m_sinks.
next(sink);
140 TelemetryKey::TelemetryKey(
const char* label)
142 , hash(crc32(strlen(label), label))
160 u32 key,
const QCBORItem& item,
161 QCBORDecodeContext* cbor)
164 if (m_filter && m_filter.
value() != key)
return;
191 QCBORDecodeContext cbor;
192 QCBORDecode_Init(&cbor, {buff, len}, QCBOR_DECODE_MODE_NORMAL);
194 QCBORDecode_EnterMap(&cbor, &item);
195 if (QCBORDecode_GetError(&cbor) != QCBOR_SUCCESS)
return;
201 int errcode = QCBORDecode_PeekNext(&cbor, &item);
202 if (errcode || item.uNestingLevel < 1)
break;
203 if (item.uDataType == QCBOR_TYPE_ARRAY) {
204 QCBORDecode_EnterArray(&cbor, &item);
206 QCBORDecode_ExitArray(&cbor);
207 }
else if (item.uDataType == QCBOR_TYPE_MAP) {
208 QCBORDecode_EnterMap(&cbor, &item);
210 QCBORDecode_ExitMap(&cbor);
212 QCBORDecode_GetNext(&cbor, &item);
220 if (item.uNestingLevel > 1)
return;
223 u32 key = u32(item.label.int64);
224 if (item.uLabelType == QCBOR_TYPE_BYTE_STRING ||
225 item.uLabelType == QCBOR_TYPE_TEXT_STRING) {
226 key = crc32(item.label.string.len, item.label.string.ptr);
236 if (cbor) QCBORDecode_Rewind(cbor);
248 #if SATCAT5_ALLOW_DELETION
249 TelemetrySink::~TelemetrySink() {
259 unsigned interval_msec)
271 m_tlm->m_tiers.
add(
this);
274 #if SATCAT5_ALLOW_DELETION
275 TelemetryTier::~TelemetryTier() {
277 m_tlm->m_tiers.
remove(
this);
290 m_time_interval = interval_msec;
293 if (!interval_msec)
return;
302 m_time_count = m_time_count % m_time_interval;
310 if (m_time_interval > 0 && m_time_count >= m_time_interval) {
311 m_time_count -= m_time_interval;
323 #if SATCAT5_ALLOW_DELETION
324 TelemetryWatcher::~TelemetryWatcher() {
bool close()
Close the QCBOR encoder by calling QCBOREncode_Finish and copy the resulting bytes to m_dst,...
UsefulBufC get_encoded()
Get encoded data as a UsefulBuf, useful if no dst was given.
Inheritable container for a eth::Address.
Implemention of "net::Dispatch" for Ethernet frames.
Accept incoming Ethernet packets by EtherType.
Telemetry(satcat5::eth::Dispatch *eth, bool concat_tiers=true)
Link this object to a network interface.
Thin wrapper for receiving CBOR telemetry over raw-Ethernet.
void frame_rcvd(satcat5::io::LimitedRead &src)
Dispatch calls frame_rcvd(...) for each incoming frame with with a matching net::Type value.
Ephemeral Readable interface for a simple array.
Limited read of next N bytes.
bool read_bytes(unsigned nbytes, void *dst) override
Read 0 or more bytes into a buffer.
unsigned get_read_ready() const override
How many bytes can be read without blocking?
The Log class creates and formats one log message.
Log & write_obj(const T &obj)
Templated wrapper for custom output formatting.
void add(satcat5::net::Protocol *proto)
Register a Protocol object.
Protocol-agnostic handler for one or more TelemetryTier objects.
void telem_send(TelemetryCbor &cbor, u32 tier_id)
Send data to all attached TelemetrySink objects.
void timer_event() override
Child class MUST override this method.
unsigned timer_interval() const
Query the polling interval for this aggregator.
Legacy ephemeral wrapper class for the CBOR encoder.
Example TelemetryWatcher that logs received key/value pairs.
TelemetryLogger(satcat5::net::TelemetryRx *rx, const char *kstr=nullptr)
Constructor for string keys, or default null = no filter.
void telem_rcvd(u32 key, const QCBORItem &item, QCBORDecodeContext *cbor) override
Callback for each received key/value pair.
Loopback adapter for telemetry messages.
TelemetryLoopback(satcat5::net::TelemetryAggregator *src, satcat5::net::TelemetryRx *dst)
Link source and destination interfaces.
void telem_ready(u32 tier_id, unsigned nbytes, const void *data) override
Carbon-copy outgoing messages to the designated interface.
Parse incoming CBOR telemetry and notify TelemetryWatcher callbacks.
void telem_item(QCBORDecodeContext *cbor, const QCBORItem &item)
Internal callback delivers one item to each watcher.
satcat5::util::List< satcat5::net::TelemetryWatcher > m_watchers
Linked list of registered callback objects.
void telem_packet(satcat5::io::LimitedRead &src)
The child object MUST call this method for each received message.
void remove_watcher(TelemetryWatcher *callback)
Manage the list of registered callback objects.
TelemetryRx()
Constructor is only accessible to the child object.
void add_watcher(TelemetryWatcher *callback)
Manage the list of registered callback objects.
User data sinks must inherit from the TelemetrySink class.
satcat5::net::TelemetryAggregator *const m_tlm
Pointer to the parent object.
TelemetrySink(satcat5::net::TelemetryAggregator *tlm)
Only children can safely access constructor/destructor.
virtual void telem_ready(u32 tier_id, unsigned nbytes, const void *data)=0
This method is called for each outgoing telemetry message.
User data sources must inherit from the TelemetrySource class.
virtual void telem_event(u32 tier_id, satcat5::net::TelemetryCbor &cbor)=0
User method for writing each telemetry message.
Rate control for a particular telemetry "tier".
void set_interval(unsigned interval_msec)
Set the reporting interval for this tier, or zero to disable.
void send_now()
Immediately send a message at this tier.
TelemetryTier(satcat5::net::TelemetryAggregator *tlm, satcat5::net::TelemetrySource *src, u32 tier_id, unsigned interval_msec=0)
Constructor is typically called by the TelemetrySource.
const u32 m_tier_id
Tier-ID for this object.
Callback API for incoming telemetry items.
satcat5::net::TelemetryRx *const m_rx
Pointer to the receive-and-decode object.
virtual void telem_rcvd(u32 key, const QCBORItem &item, QCBORDecodeContext *cbor)=0
Callback for each received key/value pair.
TelemetryWatcher(satcat5::net::TelemetryRx *rx)
Constructor and destructor are accessible to the child only.
void timer_every(unsigned msec)
Configure a repeating notification every X milliseconds.
Inheritable container for a udp::Address.
Dispatcher sorts incoming UDP messages by port index.
Telemetry(satcat5::udp::Dispatch *udp, bool concat_tiers=true)
Link this object to a network interface.
Thin wrapper for receiving CBOR telemetry over UDP.
void frame_rcvd(satcat5::io::LimitedRead &src)
Dispatch calls frame_rcvd(...) for each incoming frame with with a matching net::Type value.
T * next(const T *item) const
Fetch pointer to the next item.
void add(T *item)
Add new item to front or back, whichever is simpler.
void remove(T *item)
Remove the designated item from the list.
Inline Ethernet Checksum insertion and verification.
u32 crc32(unsigned nbytes, const void *data)
Directly calculate CRC32 on a block of data.
#define SATCAT5_QCBOR_BUFFER
Set the default size for the QCBOR buffer.
Diagnostic logging to UART and/or Ethernet ports.
State-of-health telemetry using QCBOR.
Helper object for logging contents a QCBOR item.
EtherType field (uint16) is used a protocol-ID [1536..65535].
UDP and TCP ports are both 16-bit unsigned integers.
String constant, plus the CRC32 hash of that string.
const u32 hash
CRC32 of that string.
T value() const
Fetch the inner value.
Miscellaneous mathematical utility functions.
constexpr unsigned min_unsigned(unsigned a, unsigned b)
Min and max functions.