SatCat5
ccsds_spp.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.
17 
18 #pragma once
19 
20 #include <satcat5/io_buffer.h>
21 #include <satcat5/net_core.h>
22 #include <satcat5/pkt_buffer.h>
23 
24 namespace satcat5 {
25  namespace ccsds_spp {
26  // Constants and conversion functions for specific fields.
27  // (Refer to 133.0-B-2 Section 4.1 for details.)
28  constexpr u32 VERSION_MASK = 0xE0000000u; // Packet version number
29  constexpr u32 TYPE_MASK = 0x10000000u; // Packet type (cmd/tlm)
30  constexpr u32 SEC_HDR_FLAG = 0x08000000u; // Secondary header flag
31  constexpr u32 APID_MASK = 0x07FF0000u; // APID field
32  constexpr u32 SEQF_MASK = 0x0000C000u; // Sequence flags
33  constexpr u32 SEQC_MASK = 0x00003FFFu; // Sequence count
34  constexpr u32 VERSION_1 = (0 << 29);
35  constexpr u32 TYPE_CMD = (1 << 28);
36  constexpr u32 TYPE_TLM = (0 << 28);
37  constexpr u32 SEQF_CONTINUE = (0 << 14);
38  constexpr u32 SEQF_FIRST = (1 << 14);
39  constexpr u32 SEQF_LAST = (2 << 14);
40  constexpr u32 SEQF_UNSEG = (3 << 14);
41 
42  // Reserved APID values:
43  constexpr u16 APID_IDLE = 0x7FF; // Idle Packets
44 
47  struct Header {
48  u32 value; // All fields concatenated.
49 
50  Header() = default;
51  Header(const Header& t) = default;
52  Header& operator=(const Header& t) = default;
53 
55  static constexpr u32 pack_apid(u16 apid)
56  { return (u32(apid) << 16) & APID_MASK; }
58  static constexpr u32 pack_seqc(u16 seqc)
59  { return u32(seqc) & SEQC_MASK; }
60 
61  // Convenience accessors.
62  u32 version() const
63  { return value & VERSION_MASK; }
64  bool type_cmd() const
65  { return (value & TYPE_MASK) == TYPE_CMD; }
66  bool type_tlm() const
67  { return (value & TYPE_MASK) == TYPE_TLM; }
68  bool sec_hdr() const
69  { return !!(value & SEC_HDR_FLAG); }
70  u16 apid() const
71  { return u16((value & APID_MASK) >> 16); }
72  u32 seqf() const
73  { return value & SEQF_MASK; }
74  u16 seqc() const
75  { return u16(value & SEQC_MASK); }
76 
78  void set(bool cmd, u16 apid, u16 seq);
79 
81  Header& operator++();
82  };
83 
98  class Packetizer
100  , public satcat5::io::Writeable
101  , public satcat5::poll::Timer {
102  public:
105  { return &m_buff; }
106 
109  { return this; }
110 
113  { return &m_copy; }
114 
117  { return m_buff; }
118 
121  void flush();
122 
125  void reset();
126 
128  void set_timeout(unsigned timeout_msec)
129  { m_timeout = timeout_msec; }
130 
131  // Required methods from the Writeable API.
132  unsigned get_write_space() const override;
133 
134  protected:
137  Packetizer(
138  u8* buff, unsigned rxbytes, unsigned rxpkt,
139  satcat5::io::Readable* src = nullptr);
140 
141  // Required event handlers.
142  void timer_event() override;
143  void write_next(u8 data) override;
144 
145  // Internal state:
148  unsigned m_rem;
149  unsigned m_timeout;
150  u8 m_wridx;
151  u16 m_sreg;
152  };
153 
156  template<unsigned SIZE=1600>
158  public:
160  explicit PacketizerStatic(satcat5::io::Readable* src = nullptr)
161  : Packetizer(m_raw, SIZE, 32, src), m_raw{} {}
162  private:
163  u8 m_raw[SIZE];
164  };
165 
170  public:
173  : m_iface(iface), m_dst{0} {}
174 
177  inline void connect(bool cmd, u16 apid)
178  { m_dst.set(cmd, apid, 0); }
179 
180  // Implement the required net::Address API.
181  satcat5::net::Dispatch* iface() const override;
182  satcat5::io::Writeable* open_write(unsigned len) override;
183  void close() override;
184  bool ready() const override;
185  bool is_multicast() const override {return false;}
186  bool matches_reply_address() const override;
187  bool reply_is_multicast() const override {return false;}
188  void save_reply_address() override;
189 
190  protected:
191  satcat5::ccsds_spp::Dispatch* const m_iface;
193  };
194 
197  class Dispatch final
199  , public satcat5::net::Dispatch {
200  public:
205  Dispatch(
208  ~Dispatch() SATCAT5_OPTIONAL_DTOR;
209 
213  const satcat5::net::Type& type, unsigned len) override;
214 
218  const satcat5::ccsds_spp::Header& hdr, unsigned len);
219 
221  inline const satcat5::ccsds_spp::Header& rcvd_hdr() const
222  { return m_rcvd_hdr; }
223 
224  protected:
225  // Required event handlers.
226  void data_rcvd(satcat5::io::Readable* src) override;
227  void data_unlink(satcat5::io::Readable* src) override;
228 
229  // Sink and source objects for the parent interface.
230  satcat5::io::Readable* m_src;
231  satcat5::io::Writeable* const m_dst;
232 
233  // Store most recent received header parameters.
234  satcat5::ccsds_spp::Header m_rcvd_hdr;
235  };
236 
240  protected:
243  Protocol(satcat5::ccsds_spp::Dispatch* iface, u16 apid);
244  ~Protocol() SATCAT5_OPTIONAL_DTOR;
245 
246  // Child class must define the frame_rcvd() method.
247  // void frame_rcvd(satcat5::io::LimitedRead& src) override;
248 
251  };
252 
258  class BytesToSpp {
259  public:
261  BytesToSpp(
264  bool cmd, u16 apid, unsigned max_chunk = 256);
265 
268  { return &m_strm; }
269 
270  protected:
273  };
274 
281  public:
283  SppToBytes(
285  satcat5::io::Writeable* dst, u16 apid);
286 
288  void frame_rcvd(satcat5::io::LimitedRead& src) override;
289 
290  protected:
291  satcat5::io::Writeable* const m_dst;
292  };
293  }
294 }
Implemention of "net::Address" API for CCSDS-SPP packets.
Definition: ccsds_spp.h:169
bool ready() const override
Is this address object ready for use? Child MUST override this method.
Definition: ccsds_spp.cc:115
void close() override
Close any open connections and revert to idle.
Definition: ccsds_spp.cc:111
void connect(bool cmd, u16 apid)
Set the packet type and APID.
Definition: ccsds_spp.h:177
void save_reply_address() override
Bind this Address object to the parent interface's current reply address, as provided in net::Dispatc...
Definition: ccsds_spp.cc:123
constexpr Address(satcat5::ccsds_spp::Dispatch *iface)
Attach this address to a specified interface.
Definition: ccsds_spp.h:172
satcat5::net::Dispatch * iface() const override
Fetch a pointer to the underlying interface.
Definition: ccsds_spp.cc:101
satcat5::io::Writeable * open_write(unsigned len) override
Open a new frame to the designated address and type.
Definition: ccsds_spp.cc:105
bool matches_reply_address() const override
Does this Address object match the parent interface's current reply address? Multicast destinations s...
Definition: ccsds_spp.cc:119
bool reply_is_multicast() const override
Was the parent interface's incoming message sent to a multicast address? (i.e., Could that message ha...
Definition: ccsds_spp.h:187
bool is_multicast() const override
Is the destination a broadcast or multicast address? Child MUST override these method.
Definition: ccsds_spp.h:185
Convert a raw byte-stream by inserting CCSDS-SPP headers.
Definition: ccsds_spp.h:258
BytesToSpp(satcat5::io::Readable *src, satcat5::ccsds_spp::Dispatch *dst, bool cmd, u16 apid, unsigned max_chunk=256)
Set source, destination, APID, and chunk-size.
Definition: ccsds_spp.cc:204
satcat5::io::BufferedStream * strm()
Access the inner io::BufferedStream.
Definition: ccsds_spp.h:267
Implemention of "net::Dispatch" API for CCSDS-SPP packets.
Definition: ccsds_spp.h:199
void data_rcvd(satcat5::io::Readable *src) override
The data_rcvd() callback is polled whenever data is available.
Definition: ccsds_spp.cc:167
void data_unlink(satcat5::io::Readable *src) override
Unlink this EventListener from the designated source, because the designated Readable object is being...
Definition: ccsds_spp.cc:189
satcat5::io::Writeable * open_write(const satcat5::ccsds_spp::Header &hdr, unsigned len)
Write CCSDS-SPP frame header and get Writeable object.
Definition: ccsds_spp.cc:150
satcat5::io::Writeable * open_reply(const satcat5::net::Type &type, unsigned len) override
Write CCSDS-SPP frame header and get Writeable object.
Definition: ccsds_spp.cc:142
const satcat5::ccsds_spp::Header & rcvd_hdr() const
Fetch the last received CCSDS-SPP header.
Definition: ccsds_spp.h:221
Find packet boundaries in a raw CCSDS-SPP byte-stream.
Definition: ccsds_spp.h:101
void timer_event() override
Child class MUST override this method.
Definition: ccsds_spp.cc:72
satcat5::io::BufferedCopy m_copy
Push-pull adapter.
Definition: ccsds_spp.h:146
void reset()
Full reset of buffer and synchronization state.
Definition: ccsds_spp.cc:67
void flush()
Reset partial packets and synchronization state.
Definition: ccsds_spp.cc:59
unsigned get_write_space() const override
How many bytes can be written without blocking?
Definition: ccsds_spp.cc:55
Packetizer(u8 *buff, unsigned rxbytes, unsigned rxpkt, satcat5::io::Readable *src=nullptr)
Child class must provide a working buffer.
Definition: ccsds_spp.cc:43
void write_next(u8 data) override
Write the next byte to the underlying buffer or device.
Definition: ccsds_spp.cc:77
void set_timeout(unsigned timeout_msec)
If sync is lost, rely on idle periods to resync.
Definition: ccsds_spp.h:128
unsigned m_rem
Bytes remaining in current packet.
Definition: ccsds_spp.h:148
unsigned m_timeout
User-configurable resync timeout.
Definition: ccsds_spp.h:149
satcat5::io::Writeable * packet()
Write-access with CCSDS-SPP packetization.
Definition: ccsds_spp.h:108
u16 m_sreg
Packet header working buffer.
Definition: ccsds_spp.h:151
satcat5::io::PacketBuffer m_buff
Output buffer.
Definition: ccsds_spp.h:147
satcat5::io::Writeable * bypass()
Direct write-access to the internal buffer.
Definition: ccsds_spp.h:104
satcat5::io::EventListener * listen()
Access the event-listener used for read/pull mode.
Definition: ccsds_spp.h:112
u8 m_wridx
Packet header write pointer.
Definition: ccsds_spp.h:150
satcat5::io::Counter & counter()
Access the internal statistics counters.
Definition: ccsds_spp.h:116
Packetizer variant with a statically-allocated buffer.
Definition: ccsds_spp.h:157
PacketizerStatic(satcat5::io::Readable *src=nullptr)
Optionally link this object to a source byte-stream.
Definition: ccsds_spp.h:160
Implemention of "net::Protocol" API for CCSDS-SPP packets.
Definition: ccsds_spp.h:239
satcat5::ccsds_spp::Dispatch *const m_iface
Pointer to the parent interface.
Definition: ccsds_spp.h:250
Protocol(satcat5::ccsds_spp::Dispatch *iface, u16 apid)
Constructor and destructor access restricted to children.
Definition: ccsds_spp.cc:191
Convert a CCSDS-SPP packet stream by removing CCSDS-SPP headers.
Definition: ccsds_spp.h:280
void frame_rcvd(satcat5::io::LimitedRead &src) override
For each SPP frame, remove header and forward data.
Definition: ccsds_spp.cc:219
SppToBytes(satcat5::ccsds_spp::Dispatch *src, satcat5::io::Writeable *dst, u16 apid)
Set source, destination, and APID.
Definition: ccsds_spp.cc:212
BufferedCopy copies from any Readable source to any Writeable sink.
Definition: io_buffer.h:68
Copy bytes from a Readable source to a network address.
Definition: io_buffer.h:126
Define a generic API for reporting traffic statistics.
Definition: io_counter.h:26
Event-handler interface for newly received data.
Definition: io_readable.h:43
Limited read of next N bytes.
Definition: io_readable.h:255
The PacketBuffer class is a wrapper for a circular buffer, with optional logic to support retention o...
Definition: pkt_buffer.h:66
Abstract API for reading byte-streams and packets.
Definition: io_readable.h:68
Wrapper class for forwarding reads to another object.
Definition: io_readable.h:299
Abstract API for writing byte-streams and packets.
Definition: io_writeable.h:24
Defines a generic API for sending data to a specific destination, such as a MAC address,...
Definition: net_address.h:30
The "Dispatch" is a generic interface that knows how to read a designated protocol layer and sort inc...
Definition: net_dispatch.h:36
Dispatch()
Constructor and destructor access restricted to children.
Definition: net_dispatch.h:68
A net::Protocol is the counterpart to net::Dispatch that handles a particular data stream,...
Definition: net_protocol.h:28
Timer objects are polled after a fixed delay or at a regular interval.
Definition: polling.h:213
Buffered I/O wrappers for PacketBuffer.
Generic network Dispatch API.
Helper object for the CCSDS-SPP primary packet header.
Definition: ccsds_spp.h:47
void set(bool cmd, u16 apid, u16 seq)
Construct a basic single-part SPP header.
Definition: ccsds_spp.cc:29
static constexpr u32 pack_seqc(u16 seqc)
Convert raw SEQC to the packed internal format.
Definition: ccsds_spp.h:58
bool type_tlm() const
< Type field is telemetry?
Definition: ccsds_spp.h:66
bool type_cmd() const
< Type field is command?
Definition: ccsds_spp.h:64
static constexpr u32 pack_apid(u16 apid)
Convert raw APID to the packed internal format.
Definition: ccsds_spp.h:55
bool sec_hdr() const
< Secondary header present?
Definition: ccsds_spp.h:68
u32 seqf() const
< Sequence flags
Definition: ccsds_spp.h:72
Header & operator++()
Increment the sequence-count field.
Definition: ccsds_spp.cc:35
u16 seqc() const
< Sequence counter
Definition: ccsds_spp.h:74
u32 version() const
< Version field
Definition: ccsds_spp.h:62
u16 apid() const
< Application process identifier (APID)
Definition: ccsds_spp.h:70
Multipurpose filter for matching fields in network packets.
Definition: net_type.h:38