roo_transport
API Documentation for roo_transport
Loading...
Searching...
No Matches
protocol.h
Go to the documentation of this file.
1
#pragma once
2
3
#include "
roo_transport/link/internal/seq_num.h
"
4
5
namespace
roo_transport
{
6
namespace
internal {
7
8
// Protocol description:
9
//
10
// This protocol implements reliable point-to-point bidirectional streaming over
11
// a lossy packet-based transport. It implements packet deduplication,
12
// reordering, retransmission, and flow control.
13
//
14
// The peers establish the connection by means of a handshake protocol, vaguely
15
// similar to the TCP handshake protocol. Each side generates a random 32-bit
16
// stream ID to identify itself. (The ID helps the peer to detect and ignore
17
// stale packets from previous connections, e.g. after the microcontroller has
18
// been reset). Each peer sends a handshake 'CONN' packet, including its stream
19
// ID and a randomly generated initial sequence number. Upon receiving a 'CONN'
20
// packet, the peer responds by sending a handshake 'CONN/ACK' packet,
21
// confirming reception of the peer's stream ID and initial sequence number, and
22
// sending its own stream ID and initial sequence number. The initiator of the
23
// connection responds by sending a final handshake 'ACK' packet.
24
//
25
// Once the handshake is concluded, each side may send and receive data.
26
// Increasing sequence numbers are used to label the outgoing data packets, and
27
// to acknowledge reception of incoming data packets. Each side maintains a
28
// window of incoming and outgoing data packets, to implement flow control and
29
// to allow for retransmission of lost packets.
30
//
31
// The protocol allows the following type of packets:
32
// * 'handshake', used for the handshake protocol described above;
33
// * 'data', carrying application data;
34
// * 'final data', indicating end-of-stream;
35
// * 'data ack', acknowledging reception of data packets;
36
// * 'flow control', indicating the maximum sequence number that the recipient
37
// has space to receive.
38
//
39
// Each packet consists of a 16-bit header, and an optional payload. The format
40
// of the header is the following:
41
// * bit 15 (the most significant bit): the 'control' bit;
42
// * bits 14-12: the packet type (one of the values defined in the PacketType
43
// enum below);
44
// * bits 11-0: the packet's sequence number.
45
//
46
// The 'control' bit is used to detect and ignore cross-talk packets (the
47
// packets originating from our own transmitter, rather than from the peer).
48
// Cross-talk can happen e.g. when a remote peer gets physically disconnected.
49
// The two long parallel TX and RX wires, now unconnected at the far end, act as
50
// a capacitor, and, at high baud rates, can cause electrical coupling between
51
// the local TX and RX pins.
52
//
53
// An easy way to work around cross-talk would be to include the stream ID in
54
// each packet (similarly to how it is done in IP). However, that would add 4
55
// bytes of overhead to each packet, which is significant when the packets are
56
// small. Instead, we use the single 'control' bit to differentiate between the
57
// two sides of the connection. The rule is that whichever side has the larger
58
// stream ID sets the control bit in all its outgoing packets; the other side
59
// clears the control bit in all its outgoing packets. This way, both sides can
60
// easily identify and ignore cross-talk packets.
61
//
62
// Control bit is always zero for handshake packets, since the stream IDs are
63
// not known yet at that point. During handshake, reception of a CONN packet
64
// with stream ID and sequence ID identical to our own is interpreted as
65
// cross-talk. (Probability of that happening by chance is less than 6e-14).
66
//
67
// Packet payload formats and semantics:
68
//
69
// * 'handshake' packet:
70
// Used in the handshake protocol. The payload consists of 9 bytes. The bytes
71
// 1-4 contain the sender's 32-bit stream ID (in the network order). The bytes
72
// 5-8 contain the acknowledgement of the previously received peer's 32-bit
73
// stream ID (in the network order), or zero if we don't know it yet. In the
74
// last byte, the most significant bit indicates whether the sender expects an
75
// acknowledgement of the handshake (1 indicates that the ack is requested),
76
// and the 4 least significant bits communicate the peer's receive buffer
77
// size, as a power of 2 (valid values are 0-12, indicating buffer sizes of
78
// 1-4096 packets). Remaining bits are reserved and must be zero.
79
//
80
// * 'data' packet:
81
// the payload is all application data. Must not be empty.
82
//
83
// * 'final data' packet:
84
// like 'data' packet, but indicates that the sender has no more data to
85
// transmit. The recipient's input stream transitions to 'end of stream' after
86
// reading this packet. The sender should not send any more packets after this
87
// one. The payload may be empty.
88
//
89
// * 'data ack' packet:
90
// Sent by the recipient, to confirm reception of all packets with sequence
91
// numbers preceding the sequence number carried in the header (which we call
92
// 'unack_seq_number'). The (optional) payload consists of an arbitrary number
93
// of bytes, which constitute the the lookahead 'ack' bitmap. That is,
94
// successive bits, with most-significant bit first, indicate the 'ack' status
95
// of packets with subsequent sequence numbers, starting with unack_seq_number
96
// + 1. (Knowing that some packets have been received allows the sender to
97
// avoid needless retransmissions).
98
//
99
// * 'flow control' packet:
100
// Sent by the recipient, to indicate maximum sequence number that the
101
// recipient has space to receive.
102
103
enum
PacketType
{
104
kDataPacket
= 0,
105
kFinPacket
= 1,
106
kDataAckPacket
= 2,
107
kHandshakePacket
= 3,
108
kFlowControlPacket
= 4,
109
};
110
111
inline
bool
GetPacketControlBit
(uint16_t header) {
112
return
(header & 0x8000) != 0;
113
}
114
115
inline
PacketType
GetPacketType
(uint16_t header) {
116
return
(
PacketType
)((header & 0x7FFF) >> 12);
117
}
118
119
// Control bit differentiates between the two sides of the connection. It is
120
// determined by whichever side happens to use the larger stream ID.
121
inline
uint16_t
FormatPacketHeader
(
SeqNum
seq,
PacketType
type,
122
bool
control_bit) {
123
return
(seq.
raw
() & 0x0FFF) | (type << 12) | (control_bit ? 0x8000 : 0);
124
}
125
126
inline
void
SetPacketHeaderTypeFin
(uint16_t& header) {
127
DCHECK_LE(header & 0x7000, 1) <<
"Must be 'data' or 'final data' packet"
;
128
header |= 0x1000;
// Set the 'final' type.
129
}
130
131
}
// namespace internal
132
}
// namespace roo_transport
roo_transport::internal::SeqNum
Definition
seq_num.h:29
roo_transport::internal::SeqNum::raw
uint16_t raw() const
Definition
seq_num.h:70
roo_transport::internal::SetPacketHeaderTypeFin
void SetPacketHeaderTypeFin(uint16_t &header)
Definition
protocol.h:126
roo_transport::internal::GetPacketType
PacketType GetPacketType(uint16_t header)
Definition
protocol.h:115
roo_transport::internal::FormatPacketHeader
uint16_t FormatPacketHeader(SeqNum seq, PacketType type, bool control_bit)
Definition
protocol.h:121
roo_transport::internal::PacketType
PacketType
Definition
protocol.h:103
roo_transport::internal::kFinPacket
@ kFinPacket
Definition
protocol.h:105
roo_transport::internal::kFlowControlPacket
@ kFlowControlPacket
Definition
protocol.h:108
roo_transport::internal::kHandshakePacket
@ kHandshakePacket
Definition
protocol.h:107
roo_transport::internal::kDataPacket
@ kDataPacket
Definition
protocol.h:104
roo_transport::internal::kDataAckPacket
@ kDataAckPacket
Definition
protocol.h:106
roo_transport::internal::GetPacketControlBit
bool GetPacketControlBit(uint16_t header)
Definition
protocol.h:111
roo_transport
Definition
in_buffer.h:8
seq_num.h
temp_repos
roo_transport
src
roo_transport
link
internal
protocol.h
Generated by
1.9.8