The purpose of this document is to standardize the data transfer protocol
via raw wifi radio over long distances. In this context, "long distance" is the distance over which the standard 802.11 ACK mechanism does not work.
Many areas of robotics require an inexpensive and long-range point-to-point or point-to-multipoint communication channel.
The proposed solution allows you to transmit arbitrary data streams at speeds up to 8mbps (MCS # 1 modulation) over a distance of tens of kilometers
using ordinary wifi adapters that support the transmission of "raw" packets. At the moment, these are adapters based on Realtek RTL8812AU chips.
## Areas of use:
- Communication between robots and ground station
- Communication of amateur satellites (CUBESAT) with the earth
- Digital radio communication on the ground
- ...
## Work principles
The main limitation of the transmission range of standard WiFi is the requirement to receive an ACK packet from the receiver in a strictly defined time interval after transmission.
When the distance between two stations exceeds ~200m, then the receiver does not have time to confirm the receipt of the packet and data transmission becomes impossible.
Some WiFi adapters have a so-called "raw" mode for receiving and transmitting packets.
In "raw" WiFi mode, the adapter can receive and transmit packets bypassing the standard 802.11 protocol stack. In particular, you can turn off the requirements for sending and receiving ACK packets.
In this case, the limitation on the maximum range is removed (the range now depends only on the sensitivity of the receiver and the power of the transmitter).
But requires to make own medium access control layer (MAC layer).
## Protocol description
The protocol supports point-to-point links. But each of two peers can simultaneously participate in an arbitrary number of links.
Each link has:
- Own set of encryption keys
- Up to 256 unidirectional data streams.
The last four bytes of the sender's MAC address are used to set the connection membership.
Thus the MAC address has the format: `0x57, 0x42, 0xaa, 0xbb, 0xcc, 0xdd`, where the first two bytes are the protocol header (`'W'`,`'B'`),
then three bytes - the link id and the last byte - the number of the stream inside the link.
First address byte `'W'`(0x57) has two lower bits set which means that address is multicast and locally administred.
1. The initial data transfer quantum is a UDP packet. The contents of the packet is opaque and can be any of:
- RTP packet with video or audio.
- Mavlink packet
- IP tunnel data packet.
- ...
2. Next, the packet stream is processed by the FEC codec (using [zfec](http://info.iet.unipi.it/~luigi/fec.html) -- Erasure codes based on Vandermonde matrices.)
When TX starts, it generates new session key, encrypts it using public key authenticated encryption (cryptobox) and announce it every SESSION_KEY_ANNOUNCE_MSEC (default 1s).
Session packet encryption and authentication are done using X25519 ECDH key generated from (RX public key, TX secret key) on the TX side and (TX public key, RX secret key) on the RX side.
Due to multiple RX radios with own internal queues incoming packets can arrive out of order and you need a method to rearrange them.
RX-Ring is a circular buffer, where you store packets, grouped by FEC blocks. It has two parameters: *rx_ring_front* (index of the first allocated FEC block) and
*alloc_size* -- number of allocated blocks. So rx_ring is like a queue of FEC blocks (each block can hold up to N fragments) - you append
new fragments to block(s) in the tail and fetch them from the head.
By default WFB-NG doesn't close TX FEC block if less than ``K`` packets was sent and no new packets available.
This can be an issue for interactive protocols or for protocols with variable data stream speed such as mavlink or IP tunnel.
In such cases TX can issue empty packets with ``WFB_PACKET_FEC_ONLY`` flag to close non-empty FEC blocks if no new packets are available in some timeout.