SatCat5
io_checksum.h
Go to the documentation of this file.
1 // Copyright 2024-2025 The Aerospace Corporation.
3 // This file is a part of SatCat5, licensed under CERN-OHL-W v2 or later.
33 
34 #pragma once
35 
36 #include <satcat5/io_counter.h>
37 #include <satcat5/io_writeable.h>
38 #include <satcat5/utils.h>
39 
40 namespace satcat5 {
41  namespace io {
46  , public satcat5::io::Writeable {
47  public:
48  // Implement the Writeable API:
49  void write_abort() override;
50 
51  protected:
53  constexpr explicit ChecksumTxCommon(satcat5::io::Writeable* dst)
54  : m_dst(dst), m_ovr(false) {}
55 
58  bool chk_finalize();
59 
62  virtual void chk_reset() = 0;
63 
64  // Implement required API from Writeable:
65  void write_overflow() override;
66 
67  // Internal state:
69  bool m_ovr;
70  };
71 
82  template <class T, unsigned N>
84  public:
85  // Implement required API from Writeable:
86  unsigned get_write_space() const override {
87  // Reserve enough space to append FCS.
88  unsigned nbytes = m_dst->get_write_space();
89  return (m_ovr || nbytes < N) ? (0) : (nbytes - N);
90  }
91 
92  protected:
95  : ChecksumTxCommon(dst), m_chk(init), m_init(init)
96  {
97  // Nothing else to initialize
98  }
99 
101  void chk_reset() override
102  { m_chk = m_init; }
103 
104  // Templated internal state:
105  T m_chk;
106  const T m_init;
107  };
108 
113  , public satcat5::io::Writeable {
114  public:
118  inline void error_incr()
119  { ++m_err_ct; }
120 
121  // Implement required API from Writeable:
122  unsigned get_write_space() const override;
123  void write_abort() override;
124 
125  protected:
127  constexpr explicit ChecksumRxCommon(satcat5::io::Writeable* dst)
128  : m_dst(dst) {}
129 
130  // Reset the checksum calculation to its initial state.
131  // Child MUST implement this method, since data type is unknown.
132  virtual void chk_reset() = 0;
133 
134  // Internal state:
136  };
137 
148  template <class T, unsigned N>
150  protected:
153  : ChecksumRxCommon(dst), m_chk(init), m_init(init)
154  {
155  // Nothing else to initialize.
156  }
157 
159  void chk_reset() override
160  { m_chk = m_init; }
161 
164  inline bool sreg_match(T fcs) {
165  // Does the calculated FCS match the last N bytes in SREG?
166  constexpr T MASK = satcat5::util::mask_lower<T>(8*N);
167  bool ok = (m_frm_len >= N) && ((fcs & MASK) == (m_sreg & MASK));
168  // Reset internal state.
169  unsigned len = m_frm_len - N;
170  m_chk = m_init;
171  m_frm_len = 0;
172  // Call write_finalize() or write_abort().
173  if (ok && m_dst->write_finalize()) {
174  m_byte_ct += len;
175  ++m_frm_ct;
176  return true;
177  } else {
178  ++m_err_ct;
179  if (!ok) m_dst->write_abort();
180  return false;
181  }
182  }
183 
186  inline bool sreg_push(u8& data) {
187  // FCS is in the last N bytes, but we can't predict end-of-frame.
188  // Instead, buffer previous N bytes of input in a shift register.
189  constexpr unsigned SHIFT = 8 * (N - 1);
190  T tmp = static_cast<T>(data); // Copy input...
191  data = (u8)(m_sreg >> SHIFT); // Pop oldest data
192  m_sreg = (m_sreg << 8) | tmp; // Push new data
193  // Is the shift register currently full?
194  if (m_frm_len++ < N) {
195  return false; // No update to CRC
196  } else {
197  m_dst->write_u8(data); // Forward popped data
198  return true; // Request CRC update
199  }
200  }
201 
202  // Templated internal state:
203  T m_chk;
204  const T m_init;
205  T m_sreg;
206  };
207  }
208 }
Parent class for non-template elements of ChecksumRx.
Definition: io_checksum.h:113
satcat5::io::Writeable *const m_dst
Output object.
Definition: io_checksum.h:135
void error_incr()
Increment the internal error counter.
Definition: io_checksum.h:118
void write_abort() override
If possible, abort the current partially-written packet.
Definition: io_checksum.cc:42
unsigned get_write_space() const override
How many bytes can be written without blocking?
Definition: io_checksum.cc:38
constexpr ChecksumRxCommon(satcat5::io::Writeable *dst)
Only the child class has access to the constructor.
Definition: io_checksum.h:127
Check and remove FCS from each incoming frame.
Definition: io_checksum.h:149
bool sreg_match(T fcs)
Child class MUST call sreg_match(...) during write_finalize().
Definition: io_checksum.h:164
ChecksumRx(satcat5::io::Writeable *dst, T init)
Only the child class has access to the constructor.
Definition: io_checksum.h:152
T m_sreg
Big-endian input buffer.
Definition: io_checksum.h:205
const T m_init
State after reset.
Definition: io_checksum.h:204
bool sreg_push(u8 &data)
Child class MUST call sreg_push(...) during write_next().
Definition: io_checksum.h:186
T m_chk
Checksum state.
Definition: io_checksum.h:203
void chk_reset() override
Reset checksum calculation to its initial state.
Definition: io_checksum.h:159
Parent class for non-template elements of ChecksumTx.
Definition: io_checksum.h:46
constexpr ChecksumTxCommon(satcat5::io::Writeable *dst)
Only the child class has access to the constructor.
Definition: io_checksum.h:53
void write_overflow() override
Optional error handling for write overflow.
Definition: io_checksum.cc:12
virtual void chk_reset()=0
Reset the checksum calculation to its initial state.
void write_abort() override
If possible, abort the current partially-written packet.
Definition: io_checksum.cc:16
bool m_ovr
Overflow flag.
Definition: io_checksum.h:69
bool chk_finalize()
Reset internal state and return true if the frame is valid.
Definition: io_checksum.cc:24
satcat5::io::Writeable *const m_dst
Output object.
Definition: io_checksum.h:68
Inline checksum insertion, appends FCS to each outgoing frame.
Definition: io_checksum.h:83
unsigned get_write_space() const override
How many bytes can be written without blocking?
Definition: io_checksum.h:86
const T m_init
State after reset.
Definition: io_checksum.h:106
ChecksumTx(satcat5::io::Writeable *dst, T init)
Only the child class has access to the constructor.
Definition: io_checksum.h:94
void chk_reset() override
Reset checksum calculation to its initial state.
Definition: io_checksum.h:101
T m_chk
Checksum state.
Definition: io_checksum.h:105
Simple implementation of the Counter API.
Definition: io_counter.h:47
unsigned m_err_ct
Cumulative error count.
Definition: io_counter.h:70
unsigned m_frm_ct
Cumulative frame count.
Definition: io_counter.h:71
unsigned m_frm_len
Length of current frame.
Definition: io_counter.h:72
unsigned m_byte_ct
Cumulative byte count.
Definition: io_counter.h:69
Abstract API for writing byte-streams and packets.
Definition: io_writeable.h:24
virtual unsigned get_write_space() const =0
How many bytes can be written without blocking?
virtual void write_abort()
If possible, abort the current partially-written packet.
void write_u8(u8 data)
One of many functions for writing integer/floating point values, see details.
Definition: io_writeable.cc:20
virtual bool write_finalize()
Mark end of frame and release temporary working data.
Inline byte and packet counters for statistics and diagnostics.
"Writeable" I/O interface core definitions
Miscellaneous mathematical utility functions.