roo_transport
API Documentation for roo_transport
Loading...
Searching...
No Matches
transmitter.h
Go to the documentation of this file.
1#pragma once
2
3#include <memory>
4
7
8namespace roo_transport {
9namespace internal {
10
12 public:
13 enum State {
14 // Connect was not locally called; no handshake shall be initialized; the
15 // send queue is empty.
16 kIdle = 0,
17
18 // We initiated the handshake, but the peer has not yet acknowledged receipt
19 // of our stream ID. We may buffer data locally, but we should refrain from
20 // trying to send it. Send queue is empty.
22
23 // Indicates that the peer acknowledged receipt of our stream ID and seq, so
24 // that we can be sending messages to it.
26
27 // Indicates that peer has abruptly terminated a previously valid
28 // connection. Send queue is empty.
30 };
31
32 Transmitter(unsigned int sendbuf_log2);
33
34 // Sets the state to kIdle.
35 void reset();
36
37 // Sets the state to kConnecting.
38 void init(uint32_t my_stream_id, SeqNum new_start);
39
40 uint32_t packets_sent() const { return packets_sent_; }
41
42 uint32_t packets_delivered() const { return packets_delivered_; }
43
44 size_t tryWrite(const roo::byte* buf, size_t count, bool& made_space);
45 size_t availableForWrite() const;
46 bool flush();
47
48 // Returns true if there are some unacked buffers in the queue.
49 bool hasPendingData() const;
50
51 // If connected, sets state to kClosed.
52 void close();
53
54 void setConnected(uint16_t peer_receive_buffer_size, bool control_bit) {
55 state_ = kConnected;
56 peer_receive_buffer_size_ = peer_receive_buffer_size;
57 control_bit_ = control_bit;
58 // Update the recv himark to reflect the peer's receive buffer size.
59 recv_himark_ = out_ring_.begin() + peer_receive_buffer_size;
60 }
61
62 void setBroken();
63
64 State state() const { return state_; }
65
66 uint32_t my_stream_id() const { return my_stream_id_; }
67
68 const OutBuffer* getBufferToSend(long& next_send_micros);
69 size_t send(roo::byte* buf, long& next_send_micros);
70
71 SeqNum front() const { return out_ring_.begin(); }
72
73 // Called when an 'ack' package is received. Removes acked packages from the
74 // send queue. Returns true if there is a packet that should be immediately
75 // re-delivered, without waiting for its expiration.
76 bool ack(bool control_bit, uint16_t seq_id, const roo::byte* ack_bitmap,
77 size_t ack_bitmap_len);
78
79 // Returns true if the recv himark has changed, making room for new data to
80 // send.
81 bool updateRecvHimark(bool control_bit, uint16_t recv_himark);
82
83 private:
84 OutBuffer& getOutBuffer(SeqNum seq) {
85 return out_buffers_[out_ring_.offset_for(seq)];
86 }
87
88 void addEosPacket();
89
90 uint32_t my_stream_id_;
91
92 State state_;
93
94 // Set to true by close(). Independent of state, because the writer can write
95 // all the input and close the stream even before we manage to establish the
96 // connection.
97 bool end_of_stream_;
98
99 std::unique_ptr<OutBuffer[]> out_buffers_;
100 OutBuffer* current_out_buffer_;
101 RingBuffer out_ring_;
102
103 // Pointer used to cycle through packets to send, so that we generally send
104 // packets in order before trying any retransmissions.
105 SeqNum next_to_send_;
106
107 // Ceiling beyond which the receiver currently isn't able to process data.
108 // Used in flow control, stopping the sender from sending more than the
109 // receiver can accept. Updated by the receiver by means of
110 // kFlowControlPacket.
111 SeqNum recv_himark_;
112
113 // Indicates that the sender has closed the stream, but we were unable to
114 // update the send queue to reflect that, because it was full. This flag
115 // signals that a sentinel termination packet needs to be appended to the
116 // output queue at the nearest opportunity.
117 bool has_pending_eof_;
118
119 uint32_t packets_sent_;
120 uint32_t packets_delivered_;
121
122 // Used to check validity of incoming flow control updates.
123 uint16_t peer_receive_buffer_size_;
124
125 // Indicates whether we are the 'control' side of the connection, which is
126 // determined by whoever has the larger stream ID.
127 // This bit is sent in the packet header to differentiate between the two
128 // sides, and to detect cross-talk (e.g. due to wiring mistakes).
129 bool control_bit_;
130};
131
132} // namespace internal
133} // namespace roo_transport
uint16_t offset_for(SeqNum seq) const
Definition ring_buffer.h:49
void init(uint32_t my_stream_id, SeqNum new_start)
size_t tryWrite(const roo::byte *buf, size_t count, bool &made_space)
const OutBuffer * getBufferToSend(long &next_send_micros)
size_t send(roo::byte *buf, long &next_send_micros)
bool updateRecvHimark(bool control_bit, uint16_t recv_himark)
void setConnected(uint16_t peer_receive_buffer_size, bool control_bit)
Definition transmitter.h:54
bool ack(bool control_bit, uint16_t seq_id, const roo::byte *ack_bitmap, size_t ack_bitmap_len)