SatCat5
io_buffer.cc
1 // Copyright 2021-2025 The Aerospace Corporation.
3 // This file is a part of SatCat5, licensed under CERN-OHL-W v2 or later.
5 
6 #include <satcat5/io_buffer.h>
7 #include <satcat5/net_address.h>
8 #include <satcat5/utils.h>
9 
15 
16 BufferedIO::BufferedIO(
17  u8* txbuff, unsigned txbytes, unsigned txpkt,
18  u8* rxbuff, unsigned rxbytes, unsigned rxpkt)
19  : satcat5::io::ReadableRedirect(&m_rx)
20  , satcat5::io::WriteableRedirect(&m_tx)
21  , m_tx(txbuff, txbytes, txpkt)
22  , m_rx(rxbuff, rxbytes, rxpkt)
23 {
24  m_tx.set_callback(this); // Tx notifies local callback
25  m_rx.set_callback(0); // Rx notifies user callback
26 }
27 
32  : m_src(src)
33  , m_dst(dst)
34  , m_mode(mode)
35 {
36  if (m_src) m_src->set_callback(this);
37 }
38 
39 #if SATCAT5_ALLOW_DELETION
40 BufferedCopy::~BufferedCopy() {
41  if (m_src) m_src->set_callback(0);
42 }
43 #endif
44 
46  src->copy_and_finalize(m_dst, m_mode);
47 }
48 
49 void BufferedCopy::data_unlink(satcat5::io::Readable* src) {m_src = 0;} // GCOVR_EXCL_LINE
50 
54  unsigned max_chunk,
55  unsigned min_txnow)
56  : m_src(src)
57  , m_dst(dst)
58  , m_max_chunk(max_chunk)
59  , m_min_txnow(min_unsigned(max_chunk, min_txnow))
60  , m_timeout_msec(10)
61  , m_tref{nullptr, 0}
62 {
63  if (m_src) m_src->set_callback(this);
64 }
65 
66 #if SATCAT5_ALLOW_DELETION
67 BufferedStream::~BufferedStream() {
68  if (m_src) m_src->set_callback(0);
69 }
70 #endif
71 
73  // Are we ready to read a chunk of data?
74  unsigned nread = src->get_read_ready(), ncopy = 0;
75  if (nread >= m_min_txnow) {
76  // Enough data to justify immediate transmission.
77  ncopy = min_unsigned(nread, m_max_chunk);
78  } else if (m_tref.clk) {
79  // Wait for partial-chunk timeout.
80  if (m_tref.checkpoint_elapsed()) ncopy = nread;
81  } else if (m_timeout_msec) {
82  // Start new partial-chunk timeout.
83  m_tref = SATCAT5_CLOCK->checkpoint_msec(m_timeout_msec);
84  }
85 
86  // Attempt to send a packet?
87  satcat5::io::Writeable* wr = nullptr;
88  if (ncopy) wr = m_dst->open_write(ncopy);
89  if (wr) {
90  // Copy the next chunk of data.
91  satcat5::io::LimitedRead chunk(src, ncopy);
92  chunk.copy_and_finalize(wr);
93  // Reset state for next time around.
94  m_tref = {nullptr, 0};
95  if (ncopy == nread) src->read_finalize();
96  }
97 }
98 
99 void BufferedStream::data_unlink(satcat5::io::Readable* src) {m_src = 0;} // GCOVR_EXCL_LINE
100 
104  : m_src(src)
105  , m_dst(dst)
106 {
107  if (m_src) m_src->set_callback(this);
108 }
109 
110 #if SATCAT5_ALLOW_DELETION
111 BufferedPackets::~BufferedPackets() {
112  if (m_src) m_src->set_callback(0);
113 }
114 #endif
115 
117  // One-for-one copy from source to destination.
118  while (src->get_read_ready()) {
119  auto wr = m_dst->open_write(src->get_read_ready());
120  if (wr) src->copy_and_finalize(wr);
121  else break;
122  }
123 }
124 
125 void BufferedPackets::data_unlink(satcat5::io::Readable* src) {m_src = 0;} // GCOVR_EXCL_LINE
126 
127 satcat5::io::BufferedWriter::BufferedWriter(
129  u8* txbuff, unsigned txbytes, unsigned txpkt)
130  : io::WriteableRedirect(&m_buff) // Upstream writes to buffer
131  , m_buff(txbuff, txbytes, txpkt) // Initialize working buffer
132  , m_copy(&m_buff, dst) // Auto-copy buffer contents
133 {
134  // Nothing else to initialize.
135 }
136 
BufferedCopy copies from any Readable source to any Writeable sink.
Definition: io_buffer.h:68
BufferedCopy(satcat5::io::Readable *src, satcat5::io::Writeable *dst, satcat5::io::CopyMode mode=CopyMode::PACKET)
Create an object that copies data from src to dst.
Definition: io_buffer.cc:28
void data_unlink(satcat5::io::Readable *src) override
Unlink this EventListener from the designated source, because the designated Readable object is being...
Definition: io_buffer.cc:49
satcat5::io::Readable * src()
Other accessors.
Definition: io_buffer.h:87
void data_rcvd(satcat5::io::Readable *src) override
The data_rcvd() callback is polled whenever data is available.
Definition: io_buffer.cc:45
Extensible transmit and receive buffer.
Definition: io_buffer.h:42
satcat5::io::PacketBuffer m_tx
Transmit data (user writes, child reads)
Definition: io_buffer.h:57
satcat5::io::PacketBuffer m_rx
Receive data (user reads, child writes)
Definition: io_buffer.h:60
Copy packets from a Readable source to a network address.
Definition: io_buffer.h:163
void data_rcvd(satcat5::io::Readable *src) override
The data_rcvd() callback is polled whenever data is available.
Definition: io_buffer.cc:116
void data_unlink(satcat5::io::Readable *src) override
Unlink this EventListener from the designated source, because the designated Readable object is being...
Definition: io_buffer.cc:125
BufferedPackets(satcat5::io::Readable *src, satcat5::net::Address *dst)
Set source, destination, APID, and chunk-size.
Definition: io_buffer.cc:101
Copy bytes from a Readable source to a network address.
Definition: io_buffer.h:126
void data_unlink(satcat5::io::Readable *src) override
Unlink this EventListener from the designated source, because the designated Readable object is being...
Definition: io_buffer.cc:99
BufferedStream(satcat5::io::Readable *src, satcat5::net::Address *dst, unsigned max_chunk=512, unsigned min_txnow=UINT_MAX)
Set source, destination, APID, and chunk-size.
Definition: io_buffer.cc:51
void data_rcvd(satcat5::io::Readable *src) override
The data_rcvd() callback is polled whenever data is available.
Definition: io_buffer.cc:72
Limited read of next N bytes.
Definition: io_readable.h:255
Abstract API for reading byte-streams and packets.
Definition: io_readable.h:68
virtual void read_finalize()
Consume any remaining bytes in this frame, if applicable.
Definition: io_readable.cc:270
bool copy_and_finalize(satcat5::io::Writeable *dst, satcat5::io::CopyMode mode=CopyMode::PACKET)
Copy data to a Writeable object, then finalize.
Definition: io_readable.cc:234
virtual void set_callback(satcat5::io::EventListener *callback)
Update registered callback for data_rcvd() events.
Definition: io_readable.cc:39
virtual unsigned get_read_ready() const =0
How many bytes can be read without blocking?
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
Wrapper class for forwarding writes to another object.
Definition: io_writeable.h:218
Defines a generic API for sending data to a specific destination, such as a MAC address,...
Definition: net_address.h:30
virtual satcat5::io::Writeable * open_write(unsigned len)=0
Open a new frame to the designated address and type.
Buffered I/O wrappers for PacketBuffer.
CopyMode
Specify read and write behavior for Readable::copy_and_finalize().
Definition: io_readable.h:23
Generic network Address API.
TimeRef * clk
Pointer to the parent time reference.
Definition: timeref.h:49
bool checkpoint_elapsed()
Test if an oven-timer checkpoint has elapsed.
Definition: timeref.cc:77
Miscellaneous mathematical utility functions.
constexpr unsigned min_unsigned(unsigned a, unsigned b)
Min and max functions.
Definition: utils.h:111