SatCat5
io_multiplexer.cc
1 // Copyright 2024 The Aerospace Corporation.
3 // This file is a part of SatCat5, licensed under CERN-OHL-W v2 or later.
5 
7 
11 using satcat5::io::MuxUp;
14 
15 MuxDown::MuxDown(unsigned size, MuxPort* ports, Readable* src, Writeable* dst)
16  : m_size(size), m_index(-1), m_ports(ports), m_src(src), m_dst(dst)
17 {
18  m_src->set_callback(this);
19 }
20 
21 #if SATCAT5_ALLOW_DELETION
23  // Unlink callback if applicable.
24  if (m_src) m_src->set_callback(0);
25 }
26 #endif
27 
28 void MuxDown::select(unsigned idx) {
29  // Note the active port index.
30  m_index = idx;
31 
32  // Link selected virtual port to the shared port, others to a placeholder.
33  for (unsigned a = 0 ; a < m_size ; ++a) {
34  Readable* src = (a == idx) ? m_src : 0;
35  Writeable* dst = (a == idx) ? m_dst : &null_write;
36  m_ports[a].attach(src, dst);
37  }
38 }
39 
41  // Forward events to the active controller, if any.
42  if (m_index < m_size) m_ports[m_index].read_notify();
43 }
44 
45 void MuxDown::data_unlink(satcat5::io::Readable* src) {m_src = 0;} // GCOVR_EXCL_LINE
46 
47 #if SATCAT5_ALLOW_DELETION
49  // Cleanup all associated callback pointers.
50  for (unsigned a = 0 ; a < m_size ; ++a) {
51  if (m_src[a]) m_src[a]->set_callback(0);
52  }
53 }
54 #endif
55 
56 void MuxUp::port_set(unsigned idx, Readable* src, Writeable* dst) {
57  // Register ourselves as the callback for all new ports.
58  if (idx < m_size) {
59  m_src[idx] = src;
60  m_dst[idx] = dst;
61  if (src) src->set_callback(this);
62  }
63 }
64 
65 void MuxUp::select(unsigned idx) {
66  // Note the active port index.
67  m_index = idx;
68 
69  // Redirect the upstream controller to the designated port.
70  Readable* src = (idx < m_size) ? m_src[idx] : 0;
71  Writeable* dst = (idx < m_size) ? m_dst[idx] : &null_write;
72  attach(src, dst);
73 }
74 
76  Readable* ref = (m_index < m_size) ? m_src[m_index] : 0;
77  if (src == ref) {
78  // Forward events from the active source to the upstream callback.
79  read_notify();
80  } else {
81  // Data from all other sources is immediately discarded.
82  src->read_consume(src->get_read_ready());
83  src->read_finalize();
84  }
85 }
86 
88  // Cleanup any matching source pointers.
89  for (unsigned a = 0 ; a < m_size ; ++a) {
90  if (m_src[a] == src) m_src[a] = 0;
91  }
92 }
Event-handler interface for newly received data.
Definition: io_readable.h:43
Multiplexer connecting a port to one of several controllers.
void data_rcvd(satcat5::io::Readable *src) override
The data_rcvd() callback is polled whenever data is available.
void data_unlink(satcat5::io::Readable *src) override
Unlink this EventListener from the designated source, because the designated Readable object is being...
void select(unsigned idx)
Select the active controller index, or UINT_MAX for none.
~MuxDown() SATCAT5_OPTIONAL_DTOR
Constructor and destructor should only be called by children.
Helper object used inside io::MuxDown.
void attach(Readable *src, Writeable *dst)
Update the redirect configuration to attach or detach this port.
Multiplexer connecting a controller to one of several ports.
void port_set(unsigned idx, Readable *src, Writeable *dst)
Designate the read and write interfaces for the Nth port.
void data_unlink(satcat5::io::Readable *src) override
Unlink this EventListener from the designated source, because the designated Readable object is being...
void data_rcvd(satcat5::io::Readable *src) override
The data_rcvd() callback is polled whenever data is available.
~MuxUp() SATCAT5_OPTIONAL_DTOR
Constructor and destructor should only be called by children.
void select(unsigned idx)
Select the active port index, or UINT_MAX for none.
Abstract API for reading byte-streams and packets.
Definition: io_readable.h:68
void read_notify()
Attempt notification by calling m_callback->data_rcvd().
Definition: io_readable.cc:254
virtual void read_finalize()
Consume any remaining bytes in this frame, if applicable.
Definition: io_readable.cc:270
virtual bool read_consume(unsigned nbytes)
Read and discard 0 or more bytes.
Definition: io_readable.cc:204
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?
Abstract API for writing byte-streams and packets.
Definition: io_writeable.h:24
Multiplexers for selecting one of several I/O interfaces.
satcat5::io::NullWrite null_write
Global instance of the basic NullWrite object.