6 #include <satcat5/net_tpipe.h>
7 #include <satcat5/udp_dispatch.h>
10 namespace eth = satcat5::eth;
11 namespace net = satcat5::net;
12 namespace udp = satcat5::udp;
18 : BufferedIO(m_txbuff, MAX_WINDOW, 0, m_rxbuff, MAX_WINDOW, 0)
36 #if SATCAT5_ALLOW_DELETION
37 net::Tpipe::~Tpipe() {
38 m_iface->iface()->remove(
this);
44 set_mask_u16(m_state, STATE_CLOSING);
45 if (m_state & STATE_READY) send_block();
53 return (m_state & STATE_READY) && !m_tx.get_read_ready();
58 m_state |= STATE_READY;
59 m_state |= STATE_TXONLY;
65 if (!(m_state & STATE_TXBUSY)) send_block();
70 u16 flags = src.read_u16();
71 u16 txpos = src.read_u16();
72 u16 rxpos = src.read_u16();
75 unsigned rxlen = unsigned(flags & FLAG_LEN);
77 if (rxlen > MAX_WINDOW)
return;
80 bool send_reply =
false;
81 if (flags & FLAG_START) {
83 m_iface->save_reply_address();
84 m_state = STATE_READY;
89 bool dupe_request = (m_state & STATE_READY)
90 && (m_txref == rxpos) && (m_rxref == txpos);
98 }
else if (m_state & STATE_OPENREQ) {
101 clr_mask_u16(m_state, STATE_OPENREQ);
102 set_mask_u16(m_state, STATE_READY);
105 if (!(m_state & STATE_READY))
return;
112 u16 rxdiff = rxpos - m_txpos;
113 if (s16(rxdiff) > 0) {
115 m_tx.read_consume(rxdiff);
117 clr_mask_u16(m_state, STATE_TXBUSY);
123 unsigned skip = unsigned(m_rxpos - txpos);
127 unsigned rdlen = min_unsigned(rxlen - skip, m_rx.get_write_space());
132 m_rx.write_bytes(rdlen, tmp);
133 if (m_rx.write_finalize()) {
143 if (flags & FLAG_STOP) {
149 }
else if (send_reply) {
157 if ((m_retry < m_timeout) || (m_state & STATE_TXONLY)) {
166 unsigned txlen = min_unsigned(MAX_WINDOW, m_tx.get_peek_ready());
170 auto wr = m_iface->open_write(txlen + 6);
174 unsigned timeout = m_retransmit + util::prng.
next(0, m_retransmit/2);
176 set_mask_u16(m_state, STATE_TXBUSY);
180 u16 flags = u16(txlen);
181 if (m_state & STATE_OPENREQ) flags |= FLAG_START;
182 if (m_state & STATE_CLOSING) flags |= FLAG_STOP;
185 wr->write_u16(flags);
186 wr->write_u16(m_txpos);
187 wr->write_u16(m_rxpos);
188 if (txlen) wr->write_bytes(txlen, m_tx.peek(txlen));
189 bool sent = wr->write_finalize();
192 if (sent && (m_state & STATE_TXONLY)) {
193 m_tx.read_consume(txlen);
199 constexpr u16 POLL_MSEC = 10;
200 m_retry += POLL_MSEC;
201 timer_once(POLL_MSEC);
208 m_state = STATE_OPENREQ;
209 m_txpos = u16(util::prng.next());
210 m_rxpos = u16(util::prng.next());
218 , net::
Tpipe(&m_addr)
234 m_addr.connect(addr, etype, vtag);
241 , net::
Tpipe(&m_addr)
257 udp::Port srcport = m_addr.udp()->next_free_port();
258 m_addr.connect(dstaddr, dstport, srcport, vtag);
Inheritable container for a eth::Address.
Implemention of "net::Dispatch" for Ethernet frames.
Simple network pipe service over raw Ethernet.
void connect(const satcat5::eth::MacAddr &addr, const satcat5::eth::MacType &etype, const satcat5::eth::VlanTag &vtag=satcat5::eth::VTAG_NONE)
Create an outgoing connection with the specified server.
Tpipe(satcat5::eth::Dispatch *iface)
Create an idle network pipe.
void bind(const satcat5::eth::MacType &etype, const satcat5::eth::VlanTag &vtag=satcat5::eth::VTAG_NONE)
Wait for incoming connections to the specified EtherType.
Limited read of next N bytes.
bool read_consume(unsigned nbytes) override
Read and discard 0 or more bytes.
bool read_bytes(unsigned nbytes, void *dst) override
Read 0 or more bytes into a buffer.
unsigned get_read_ready() const override
How many bytes can be read without blocking?
Abstract API for reading byte-streams and packets.
Defines a generic API for sending data to a specific destination, such as a MAC address,...
virtual satcat5::net::Dispatch * iface() const =0
Fetch a pointer to the underlying interface.
void add(satcat5::net::Protocol *proto)
Register a Protocol object.
A net::Protocol is the counterpart to net::Dispatch that handles a particular data stream,...
bool completed() const
Has all queued data been acknowledged?
void timer_event() override
Child class MUST override this method.
void close()
Close the active connection.
void send_start()
Special case of send_block used to open a new connection.
Tpipe(satcat5::net::Address *dst)
Create link and set the transport service.
satcat5::net::Address *const m_iface
Network interface.
void set_txonly()
Enable unidirectional transmission? Transmit-only endpoints do not wait for acknowledgements.
void data_rcvd(satcat5::io::Readable *src) override
The data_rcvd() callback is polled whenever data is available.
void frame_rcvd(satcat5::io::LimitedRead &src) override
Dispatch calls frame_rcvd(...) for each incoming frame with with a matching net::Type value.
void send_block()
Send a synchronization packet, with data if applicable.
Inheritable container for a udp::Address.
Dispatcher sorts incoming UDP messages by port index.
Simple network pipe service over raw Ethernet.
void bind(const satcat5::udp::Port &port)
Wait for incoming connections to the specified UDP port.
void connect(const satcat5::ip::Addr &addr, const satcat5::udp::Port &port, const satcat5::eth::VlanTag &vtag=satcat5::eth::VTAG_NONE)
Create an outgoing connection with the specified server.
Tpipe(satcat5::udp::Dispatch *iface)
Create an idle network pipe.
u32 next()
Range [0..2^32)
constexpr satcat5::net::Type TYPE_NONE
The TYPE_NONE mask blocks all incoming frames.
An Ethernet MAC address (with serializable interface).
EtherType field (uint16) is used a protocol-ID [1536..65535].
u16 value
The 16-bit value is stored in processor-native order.
Header contents for an 802.1Q Virtual-LAN tag.
u16 vid() const
Accessors for each individual field.
IPv4 address is a 32-bit unsigned integer.
UDP and TCP ports are both 16-bit unsigned integers.
u16 value
Raw access to the underlying representation.
Multipurpose filter for matching fields in network packets.
Miscellaneous mathematical utility functions.
constexpr unsigned min_unsigned(unsigned a, unsigned b)
Min and max functions.
void clr_mask_u16(u16 &val, u16 mask)
Set or clear bit masks.
void set_mask_u16(u16 &val, u16 mask)
Set or clear bit masks.