|
SatCat5
|
The PacketBuffer class is a wrapper for a circular buffer, with optional logic to support retention of frame/packet boundaries.
It implements the "Readable" and "Writeable" interfaces so that it can be used with many other SatCat5 stream-processing tools.
PacketBuffer also acts as a thread-safe barrier, e.g., for data that is written in the interrupt context and read in the general-use context, or vice-versa. For performance reasons, these protections are applied at write_finalize() and read_finalize(). Users writing from multiple threads or reading from multiple threads should provide their own safety systems.
To allow greater flexibility in memory allocation, the underlying working memory is NOT declared as part of this class. Instead, its address and size are arguments to the constructor.
Example unpacketized stream:
Example packetized stream (up to 16 queued packets):
io::Writeable methods are used as normal to construct a packet field by field. The packet is committed to the buffer during the call to write_finalize(). In the event of an overflow in the middle of this process, the incomplete partial frame is discarded via a call to write_abort().
Maximum size of each frame is limited to the main buffer size or 64 kiB, whichever is smaller.
Definition at line 62 of file pkt_buffer.h.
#include <pkt_buffer.h>
Public Member Functions | |
| constexpr | PacketBuffer (void *buff, unsigned nbytes, unsigned max_pkt=0) |
| Configure this object and link to the underlying working memory. More... | |
| void | clear () |
| Reset buffer contents. More... | |
| unsigned | byte_count (bool reset=true) override |
| Bytes transferred since the last query. | |
| unsigned | frame_count (bool reset=true) override |
| Frames transferred since the last query. | |
| u8 | get_percent_full () const |
| Get overall buffer occupancy as percentage full (0-100%). | |
| unsigned | get_write_partial () const |
| Get number of bytes in a partial packet, or -1 on overflow. | |
| unsigned | get_write_space () const override |
| How many bytes can be written without blocking? More... | |
| void | write_bytes (unsigned nbytes, const void *src) override |
| Write 0 or more bytes from a buffer. More... | |
| void | write_abort () override |
| If possible, abort the current partially-written packet. More... | |
| bool | write_finalize () override |
| Mark end of frame and release temporary working data. More... | |
| void | zcw_write (unsigned nbytes) |
| Zero-copy write (zcw) mode, required for UART interface. More... | |
| unsigned | zcw_maxlen () const |
| Max contiguous write length (ZCW). | |
| u8 * | zcw_start () |
| Pointer to a contiguous buffer (ZCW). | |
| unsigned | get_read_ready () const override |
| How many bytes can be read without blocking? More... | |
| bool | read_bytes (unsigned nbytes, void *dst) override |
| Read 0 or more bytes into a buffer. More... | |
| bool | read_consume (unsigned nbytes) override |
| Read and discard 0 or more bytes. More... | |
| void | read_finalize () override |
| Consume any remaining bytes in this frame, if applicable. More... | |
| const u8 * | peek (unsigned nbytes) const |
Peek nbytes into the circular buffer. More... | |
| unsigned | get_peek_ready () const |
| Find the longest available contiguous segment that can be requested by peek(). | |
| void | write_u8 (u8 data) |
| One of many functions for writing integer/floating point values, see details. More... | |
| void | write_str (const char *str) |
| Write the contents of a null-terminated string. More... | |
| template<class T > | |
| void | write_obj (const T &obj) |
Templated wrapper for any object with the following method: void write_to(satcat5::io::Writeable* wr) const; | |
| virtual void | set_callback (satcat5::io::EventListener *callback) |
| Update registered callback for data_rcvd() events. More... | |
| u8 | read_u8 () |
| One of many functions for reading integer/floating point values, see details. More... | |
| unsigned | read_str (unsigned dst_size, char *dst) |
| Safely read a null-terminated input string. More... | |
| template<class T > | |
| bool | read_obj (T &t) |
Templated wrapper for any object with the following method: bool read_from(satcat5::io::Readable* rd); | |
| unsigned | copy_to (satcat5::io::Writeable *dst) |
| Copy data to a Writeable object, without finalizing. More... | |
| bool | copy_and_finalize (satcat5::io::Writeable *dst, satcat5::io::CopyMode mode=CopyMode::PACKET) |
| Copy data to a Writeable object, then finalize. More... | |
| void | request_poll () |
| Call this method to request polling at a later time. More... | |
| void | request_cancel () |
| Call this method to cancel a previous request_poll(). | |
| virtual unsigned | error_count (bool reset=true) |
| (Optional) Error events since the last query. | |
| u8 * | get_buff_dtor () const |
| Accessor for children that need to delete underlying buffer. More... | |
| unsigned | get_buff_size () const |
| Accessor for children that need to delete underlying buffer. More... | |
Static Public Member Functions | |
| static unsigned | count_ondemand () |
| Count queued objects of this type (i.e., non-idle). | |
Protected Member Functions | |
| void | write_next (u8 data) override |
| Write the next byte to the underlying buffer or device. More... | |
| void | write_overflow () override |
| Optional error handling for write overflow. More... | |
| u8 | read_next () override |
| Read the next byte from the underlying buffer or device. More... | |
| bool | can_read_internal (unsigned nbytes) const |
| void | consume_internal (unsigned nbytes) |
| void | read_notify () |
Attempt notification by calling m_callback->data_rcvd(). More... | |
| virtual void | read_underflow () |
| Optional error handling for read underflow. More... | |
Protected Attributes | |
| friend | LimitedWrite |
| friend | WriteableBroadcast |
| friend | WriteableRedirect |
Private Member Functions | |
| void | poll_demand () |
| Event handler for on-demand polling. | |
Private Attributes | |
| satcat5::io::EventListener * | m_callback |
| Pointer to the callback object, or NULL. More... | |
| satcat5::poll::OnDemand * | m_next |
| bool | m_idle |
| u8 *const | m_buff |
| State for the main circular buffer (read domain) | |
| const unsigned | m_buff_size |
| State for the main circular buffer (read domain) | |
| unsigned | m_buff_rdidx |
| State for the main circular buffer (read domain) | |
| unsigned | m_buff_rdcount |
| State for the main circular buffer (read domain) | |
| u16 *const | m_pkt_lbuff |
| Store packet lengths in an auxiliary buffer (read domain) | |
| const unsigned | m_pkt_maxct |
| Store packet lengths in an auxiliary buffer (read domain) | |
| unsigned | m_pkt_rdidx |
| Store packet lengths in an auxiliary buffer (read domain) | |
| unsigned | m_total_bytes |
| Cumulative total-bytes and total-frames statistics counters. | |
| unsigned | m_total_frames |
| Cumulative total-bytes and total-frames statistics counters. | |
| unsigned | m_next_wrpos |
| Working state for writes (write domain) | |
| unsigned | m_next_wrlen |
| Working state for writes (write domain) | |
| volatile unsigned | m_shared_rdavail |
| Shared state is constant except for cross-domain events. | |
| volatile unsigned | m_shared_pktcount |
| Shared state is constant except for cross-domain events. | |
|
inlineconstexpr |
Configure this object and link to the underlying working memory.
Note: If max_pkt = 0, then packet boundaries are ignored.
Definition at line 70 of file pkt_buffer.h.
| void PacketBuffer::clear | ( | ) |
Reset buffer contents.
Note: This does not reset byte_count and frame_count.
Definition at line 22 of file pkt_buffer.cc.
|
inherited |
Copy data to a Writeable object, then finalize.
As copy_to(), but also calls read_finalize() and/or write_finalize() depending on the input/output mode.
In packet mode (the default), call both read_finalize() and write_finalize() if the operation copies all available data. Use this mode whenever the input is packetized.
In byte-stream mode, call write_finalize() if the operation copies any data, but never call read_finalize(). Use this mode for inputs that do not delimit packet boundaries.
| dst | The destination object. |
| mode | Select packet mode or stream mode. |
Definition at line 234 of file io_readable.cc.
|
inherited |
Copy data to a Writeable object, without finalizing.
Copy the contents of this Readable to a Writeable object, stopping at end-of-input, end-of-frame, or the capacity of the destination buffer (whichever comes first). This method does not call read_finalize or write_finalize(). To automatically make finalize calls,
Definition at line 214 of file io_readable.cc.
|
inline |
Accessor for children that need to delete underlying buffer.
Returned value matches pointer passed to the constructor.
Definition at line 137 of file pkt_buffer.h.
|
inline |
Accessor for children that need to delete underlying buffer.
Returned value matches pointer passed to the constructor.
Definition at line 138 of file pkt_buffer.h.
|
overridevirtual |
How many bytes can be read without blocking?
Child objects of io::Readable MUST override this method.
Implements satcat5::io::Readable.
Definition at line 177 of file pkt_buffer.cc.
|
overridevirtual |
How many bytes can be written without blocking?
Child objects of io::Writeable MUST override this method.
Implements satcat5::io::Writeable.
Definition at line 52 of file pkt_buffer.cc.
| const u8 * PacketBuffer::peek | ( | unsigned | nbytes | ) | const |
Peek nbytes into the circular buffer.
Due to this circular buffer, packet data may not be contiguous. Use get_peek_ready() to find the longest available contiguous segment.
nbytes > get_peek_ready(). Definition at line 248 of file pkt_buffer.cc.
|
overridevirtual |
Read 0 or more bytes into a buffer.
Child objects of io::Readable MAY override this method for improved performance.
Reimplemented from satcat5::io::Readable.
Definition at line 187 of file pkt_buffer.cc.
|
overridevirtual |
Read and discard 0 or more bytes.
Child objects of io::Readable MAY override this method for improved performance.
Reimplemented from satcat5::io::Readable.
Definition at line 256 of file pkt_buffer.cc.
|
overridevirtual |
Consume any remaining bytes in this frame, if applicable.
Child objects of io::Readable SHOULD override this method if they support framing.
Reimplemented from satcat5::io::Readable.
Definition at line 266 of file pkt_buffer.cc.
|
overrideprotectedvirtual |
Read the next byte from the underlying buffer or device.
Child objects of io::Readable MUST override this method.
Implements satcat5::io::Readable.
Definition at line 206 of file pkt_buffer.cc.
|
protectedinherited |
Attempt notification by calling m_callback->data_rcvd().
Child objects of io::Readable MAY call this to override default notifications.
Definition at line 254 of file io_readable.cc.
|
inherited |
Safely read a null-terminated input string.
The input is always consumed up to the end-of-input or the first zero byte, whichever comes first.
Definition at line 179 of file io_readable.cc.
|
inherited |
One of many functions for reading integer/floating point values, see details.
Several functions are provided for reading and writing scalar types to/from io::Readable and io::Writeable instances. Since there are many of these that are frequently inherited, they are hidden from documentation. These functions follow a shared template:
read_ or write_ prefix.u for unsigned, s for signed, f for floating-point.l suffix if little-endian, no suffix if big-endian.Example: write_s48l is "Write 48 bits (6 bytes) to this
io::Writeable as a signed value in little-endian order".
Definition at line 44 of file io_readable.cc.
|
protectedvirtualinherited |
Optional error handling for read underflow.
Child objects of io::Readable MAY override this method.
Reimplemented in satcat5::port::Mailmap, and satcat5::io::ReadableRedirect.
Definition at line 271 of file io_readable.cc.
|
inherited |
Call this method to request polling at a later time.
Safe to stack requests, but only one call to poll().
Definition at line 208 of file polling.cc.
|
virtualinherited |
Update registered callback for data_rcvd() events.
Child objects of io::Readable SHOULD usually leave this method as-is.
Reimplemented in satcat5::io::ReadableRedirect, satcat5::io::Override, satcat5::io::MuxPort, and satcat5::test::EthernetInterface.
Definition at line 39 of file io_readable.cc.
|
overridevirtual |
If possible, abort the current partially-written packet.
Child objects of io::Writeable SHOULD override this method if it is practical to prevent in-progress data from being relayed downstream.
Reimplemented from satcat5::io::Writeable.
Definition at line 89 of file pkt_buffer.cc.
|
overridevirtual |
Write 0 or more bytes from a buffer.
Child objects of io::Writeable MAY override write_bytes as needed for performance.
Reimplemented from satcat5::io::Writeable.
Definition at line 73 of file pkt_buffer.cc.
|
overridevirtual |
Mark end of frame and release temporary working data.
Child objects of io::Writeable SHOULD override this method to mark frame bounds.
Reimplemented from satcat5::io::Writeable.
Definition at line 105 of file pkt_buffer.cc.
|
overrideprotectedvirtual |
Write the next byte to the underlying buffer or device.
Child objects of io::Writeable MUST override this method.
Implements satcat5::io::Writeable.
Definition at line 93 of file pkt_buffer.cc.
|
overrideprotectedvirtual |
Optional error handling for write overflow.
Child objects of io::Writeable MAY override this method for error handling.
Reimplemented from satcat5::io::Writeable.
Definition at line 101 of file pkt_buffer.cc.
|
inherited |
Write the contents of a null-terminated string.
Note: Null-termination is not copied to the output.
Definition at line 180 of file io_writeable.cc.
|
inherited |
One of many functions for writing integer/floating point values, see details.
Several functions are provided for reading and writing scalar types to/from io::Readable and io::Writeable instances. Since there are many of these that are frequently inherited, they are hidden from documentation. These functions follow a shared template:
read_ or write_ prefix.u for unsigned, s for signed, f for floating-point.l suffix if little-endian, no suffix if big-endian.Example: write_s48l is "Write 48 bits (6 bytes) to this
io::Writeable as a signed value in little-endian order".
Definition at line 20 of file io_writeable.cc.
| void PacketBuffer::zcw_write | ( | unsigned | nbytes | ) |
Zero-copy write (zcw) mode, required for UART interface.
Definition at line 164 of file pkt_buffer.cc.
|
privateinherited |
Pointer to the callback object, or NULL.
This can only be modified through the set_callback(...) method.
Definition at line 199 of file io_readable.h.