mirror of
https://github.com/svpcom/wfb-ng.git
synced 2025-03-13 18:14:27 -03:00
Add ability to add optional attributes to session packet without breaking protocol format
This commit is contained in:
parent
9c46b4230a
commit
d2ef1edfea
@ -1,6 +1,6 @@
|
||||
% WFB-NG Data Transport Standard [Draft]
|
||||
% Vasily Evseenko <<svpcom@p2ptech.org>>
|
||||
% Sep 13, 2022
|
||||
% Aug 1, 2024
|
||||
|
||||
## Introduction
|
||||
|
||||
@ -15,7 +15,7 @@ using ordinary wifi adapters that support the transmission of "raw" packets. At
|
||||
## Areas of use:
|
||||
|
||||
- Communication between robots and ground station
|
||||
- Communication of amateur satellites (CUBESAT) with the earth
|
||||
- Communication of amateur satellites (CUBESAT) with the Earth
|
||||
- Digital radio communication on the ground
|
||||
- ...
|
||||
|
||||
@ -76,6 +76,7 @@ There are two packet types
|
||||
2. Session packet (`packet_type = 2`, has encrypted and authenticated session parameters and session key, see note below)
|
||||
|
||||
Currently only supported FEC type is Reed-Solomon on Vandermonde matrix, but new FEC algorithms can be added in future.
|
||||
Session packet can have any amount of optional tags. Receiver should ignore all unknown or unused tags.
|
||||
|
||||
``` .c
|
||||
// FEC types
|
||||
@ -105,7 +106,13 @@ Currently only supported FEC type is Reed-Solomon on Vandermonde matrix, but new
|
||||
+-- encrypted and authenticated by session key
|
||||
2. Session packet:
|
||||
wsession_hdr_t { packet_type = 2, nonce = random() }
|
||||
wsession_data_t { epoch, channel_id, fec_type, fec_k, fec_n, session_key } # -- encrypted and authenticated using crypto_box_easy(rx_publickey, tx_secretkey)
|
||||
wsession_data_t { epoch, channel_id, #
|
||||
fec_type, fec_k, fec_n, #
|
||||
session_key, #
|
||||
optional TLV list } # -- encrypted and authenticated using crypto_box_easy(rx_publickey, tx_secretkey)
|
||||
|
||||
Where TLV list is a list of optional tags with the following format:
|
||||
[{tag_id : tag_size : <tag_size bytes of value>}, ... ]
|
||||
|
||||
data nonce: 56bit block_idx + 8bit fragment_idx
|
||||
session nonce: crypto_box_NONCEBYTES of random bytes
|
||||
@ -129,8 +136,16 @@ Currently only supported FEC type is Reed-Solomon on Vandermonde matrix, but new
|
||||
uint8_t k; // FEC k
|
||||
uint8_t n; // FEC n
|
||||
uint8_t session_key[crypto_aead_chacha20poly1305_KEYBYTES];
|
||||
uint8_t tags[]; // Optional TLV attributes
|
||||
} __attribute__ ((packed)) wsession_data_t;
|
||||
|
||||
// TLV item header
|
||||
typedef struct {
|
||||
uint8_t id;
|
||||
uint16_t len;
|
||||
uint8_t value[];
|
||||
} __attribute__ ((packed)) tlv_hdr_t;
|
||||
|
||||
// Data packet. Embed FEC-encoded data
|
||||
|
||||
typedef struct {
|
||||
|
67
src/rx.cpp
67
src/rx.cpp
@ -508,12 +508,35 @@ void Aggregator::log_rssi(const sockaddr_in *sockaddr, uint8_t wlan_idx, const u
|
||||
}
|
||||
}
|
||||
|
||||
int Aggregator::get_tag(const void *buf, size_t size, uint8_t tag_id, void *value, size_t value_size)
|
||||
{
|
||||
tlv_hdr_t *p = (tlv_hdr_t*)buf;
|
||||
void *end = (uint8_t*)buf + size;
|
||||
|
||||
while((void*)(p + 1) <= end)
|
||||
{
|
||||
if(p->id != tag_id)
|
||||
{
|
||||
p = (tlv_hdr_t*)((uint8_t*)(p + 1) + p->len);
|
||||
continue;
|
||||
}
|
||||
if(p->len > value_size) return -1;
|
||||
if(p->value + p->len > end) return -1;
|
||||
memcpy(value, p->value, p->len);
|
||||
return p->len;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Aggregator::process_packet(const uint8_t *buf, size_t size, uint8_t wlan_idx, const uint8_t *antenna,
|
||||
const int8_t *rssi, const int8_t *noise, uint16_t freq, uint8_t mcs_index,
|
||||
uint8_t bandwidth, sockaddr_in *sockaddr)
|
||||
{
|
||||
wsession_data_t new_session_data;
|
||||
uint8_t session_tmp[MAX_SESSION_PACKET_SIZE - crypto_box_MACBYTES - sizeof(wsession_hdr_t)];
|
||||
wsession_data_t* new_session_data = NULL;
|
||||
//size_t new_session_tags_size = 0;
|
||||
|
||||
count_p_all += 1;
|
||||
count_b_all += size;
|
||||
|
||||
@ -537,17 +560,20 @@ void Aggregator::process_packet(const uint8_t *buf, size_t size, uint8_t wlan_id
|
||||
}
|
||||
break;
|
||||
|
||||
case WFB_PACKET_KEY:
|
||||
if(size != sizeof(wsession_hdr_t) + sizeof(wsession_data_t) + crypto_box_MACBYTES)
|
||||
case WFB_PACKET_SESSION:
|
||||
new_session_data = (wsession_data_t*)session_tmp;
|
||||
|
||||
if(size < sizeof(wsession_hdr_t) + sizeof(wsession_data_t) + crypto_box_MACBYTES || \
|
||||
size > MAX_SESSION_PACKET_SIZE)
|
||||
{
|
||||
fprintf(stderr, "Invalid session key packet\n");
|
||||
count_p_bad += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if(crypto_box_open_easy((uint8_t*)&new_session_data,
|
||||
if(crypto_box_open_easy((uint8_t*)session_tmp,
|
||||
buf + sizeof(wsession_hdr_t),
|
||||
sizeof(wsession_data_t) + crypto_box_MACBYTES,
|
||||
size - sizeof(wsession_hdr_t),
|
||||
((wsession_hdr_t*)buf)->session_nonce,
|
||||
tx_publickey, rx_secretkey) != 0)
|
||||
{
|
||||
@ -556,37 +582,39 @@ void Aggregator::process_packet(const uint8_t *buf, size_t size, uint8_t wlan_id
|
||||
return;
|
||||
}
|
||||
|
||||
if (be64toh(new_session_data.epoch) < epoch)
|
||||
//new_session_tags_size = size - (sizeof(wsession_hdr_t) + sizeof(wsession_data_t) + crypto_box_MACBYTES);
|
||||
|
||||
if (be64toh(new_session_data->epoch) < epoch)
|
||||
{
|
||||
fprintf(stderr, "Session epoch doesn't match: %" PRIu64 " < %" PRIu64 "\n", be64toh(new_session_data.epoch), epoch);
|
||||
fprintf(stderr, "Session epoch doesn't match: %" PRIu64 " < %" PRIu64 "\n", be64toh(new_session_data->epoch), epoch);
|
||||
count_p_dec_err += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (be32toh(new_session_data.channel_id) != channel_id)
|
||||
if (be32toh(new_session_data->channel_id) != channel_id)
|
||||
{
|
||||
fprintf(stderr, "Session channel_id doesn't match: %u != %u\n", be32toh(new_session_data.channel_id), channel_id);
|
||||
fprintf(stderr, "Session channel_id doesn't match: %u != %u\n", be32toh(new_session_data->channel_id), channel_id);
|
||||
count_p_dec_err += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (new_session_data.fec_type != WFB_FEC_VDM_RS)
|
||||
if (new_session_data->fec_type != WFB_FEC_VDM_RS)
|
||||
{
|
||||
fprintf(stderr, "Unsupported FEC codec type: %d\n", new_session_data.fec_type);
|
||||
fprintf(stderr, "Unsupported FEC codec type: %d\n", new_session_data->fec_type);
|
||||
count_p_dec_err += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (new_session_data.n < 1)
|
||||
if (new_session_data->n < 1)
|
||||
{
|
||||
fprintf(stderr, "Invalid FEC N: %d\n", new_session_data.n);
|
||||
fprintf(stderr, "Invalid FEC N: %d\n", new_session_data->n);
|
||||
count_p_dec_err += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (new_session_data.k < 1 || new_session_data.k > new_session_data.n)
|
||||
if (new_session_data->k < 1 || new_session_data->k > new_session_data->n)
|
||||
{
|
||||
fprintf(stderr, "Invalid FEC K: %d\n", new_session_data.k);
|
||||
fprintf(stderr, "Invalid FEC K: %d\n", new_session_data->k);
|
||||
count_p_dec_err += 1;
|
||||
return;
|
||||
}
|
||||
@ -594,22 +622,23 @@ void Aggregator::process_packet(const uint8_t *buf, size_t size, uint8_t wlan_id
|
||||
count_p_dec_ok += 1;
|
||||
log_rssi(sockaddr, wlan_idx, antenna, rssi, noise, freq, mcs_index, bandwidth);
|
||||
|
||||
if (memcmp(session_key, new_session_data.session_key, sizeof(session_key)) != 0)
|
||||
if (memcmp(session_key, new_session_data->session_key, sizeof(session_key)) != 0)
|
||||
{
|
||||
epoch = be64toh(new_session_data.epoch);
|
||||
memcpy(session_key, new_session_data.session_key, sizeof(session_key));
|
||||
epoch = be64toh(new_session_data->epoch);
|
||||
memcpy(session_key, new_session_data->session_key, sizeof(session_key));
|
||||
|
||||
if (fec_p != NULL)
|
||||
{
|
||||
deinit_fec();
|
||||
}
|
||||
|
||||
init_fec(new_session_data.k, new_session_data.n);
|
||||
init_fec(new_session_data->k, new_session_data->n);
|
||||
|
||||
fprintf(stdout, "%" PRIu64 "\tSESSION\t%" PRIu64 ":%u:%d:%d\n", get_time_ms(), epoch, WFB_FEC_VDM_RS, fec_k, fec_n);
|
||||
fflush(stdout);
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
default:
|
||||
|
@ -217,6 +217,8 @@ private:
|
||||
const int8_t *noise, uint16_t freq, uint8_t mcs_index, uint8_t bandwidth);
|
||||
int get_block_ring_idx(uint64_t block_idx);
|
||||
int rx_ring_push(void);
|
||||
int get_tag(const void *buf, size_t size, uint8_t tag_id, void *value, size_t value_size);
|
||||
|
||||
fec_t* fec_p;
|
||||
int fec_k; // RS number of primary fragments in block
|
||||
int fec_n; // RS total number of fragments in block
|
||||
|
71
src/tx.cpp
71
src/tx.cpp
@ -49,13 +49,19 @@ using namespace std;
|
||||
#include "tx.hpp"
|
||||
|
||||
|
||||
Transmitter::Transmitter(int k, int n, const string &keypair, uint64_t epoch, uint32_t channel_id, uint32_t fec_delay) : \
|
||||
Transmitter::Transmitter(int k, int n, const string &keypair, uint64_t epoch, uint32_t channel_id, uint32_t fec_delay, std::vector<tags_item_t> &tags) : \
|
||||
fec_k(k), fec_n(n), block_idx(0),
|
||||
fragment_idx(0),
|
||||
max_packet_size(0),
|
||||
epoch(epoch),
|
||||
channel_id(channel_id),
|
||||
fec_delay(fec_delay)
|
||||
fec_delay(fec_delay),
|
||||
tx_secretkey{},
|
||||
rx_publickey{},
|
||||
session_key{},
|
||||
session_packet{},
|
||||
session_packet_size(0),
|
||||
tags(tags)
|
||||
{
|
||||
fec_p = fec_new(fec_k, fec_n);
|
||||
|
||||
@ -97,33 +103,59 @@ Transmitter::~Transmitter()
|
||||
}
|
||||
|
||||
|
||||
void Transmitter::make_session_key(void)
|
||||
void Transmitter::make_session_key()
|
||||
{
|
||||
// init session key
|
||||
randombytes_buf(session_key, sizeof(session_key));
|
||||
|
||||
// fill packet header
|
||||
wsession_hdr_t *session_hdr = (wsession_hdr_t *)session_key_packet;
|
||||
session_hdr->packet_type = WFB_PACKET_KEY;
|
||||
wsession_hdr_t *session_hdr = (wsession_hdr_t *)session_packet;
|
||||
session_hdr->packet_type = WFB_PACKET_SESSION;
|
||||
|
||||
randombytes_buf(session_hdr->session_nonce, sizeof(session_hdr->session_nonce));
|
||||
|
||||
// fill packet contents
|
||||
wsession_data_t session_data = { .epoch = htobe64(epoch),
|
||||
.channel_id = htobe32(channel_id),
|
||||
.fec_type = WFB_FEC_VDM_RS,
|
||||
.k = (uint8_t)fec_k,
|
||||
.n = (uint8_t)fec_n,
|
||||
};
|
||||
|
||||
memcpy(session_data.session_key, session_key, sizeof(session_key));
|
||||
uint8_t tmp[MAX_SESSION_PACKET_SIZE - crypto_box_MACBYTES - sizeof(wsession_hdr_t)];
|
||||
|
||||
if (crypto_box_easy(session_key_packet + sizeof(wsession_hdr_t),
|
||||
(uint8_t*)&session_data, sizeof(session_data),
|
||||
// Fill fixed headers
|
||||
{
|
||||
wsession_data_t* session_data = (wsession_data_t*)tmp;
|
||||
assert(sizeof(*session_data) <= sizeof(tmp));
|
||||
|
||||
session_data->epoch = htobe64(epoch);
|
||||
session_data->channel_id = htobe32(channel_id);
|
||||
session_data->fec_type = WFB_FEC_VDM_RS;
|
||||
session_data->k = (uint8_t)fec_k;
|
||||
session_data->n = (uint8_t)fec_n;
|
||||
|
||||
assert(sizeof(session_data->session_key) == sizeof(session_key));
|
||||
memcpy(session_data->session_key, session_key, sizeof(session_key));
|
||||
}
|
||||
|
||||
// Fill optional Tags
|
||||
|
||||
uint32_t session_data_size = sizeof(wsession_data_t);
|
||||
for(auto it=tags.begin(); it != tags.end(); it++)
|
||||
{
|
||||
tlv_hdr_t* tlv = (tlv_hdr_t*)((uint8_t*)tmp + session_data_size);
|
||||
session_data_size += sizeof(tlv_hdr_t) + it->len;
|
||||
assert(session_data_size <= sizeof(tmp));
|
||||
|
||||
tlv->id = it->id;
|
||||
tlv->len = it->len;
|
||||
memcpy(tlv->value, it->value, it->len);
|
||||
}
|
||||
|
||||
if (crypto_box_easy(session_packet + sizeof(wsession_hdr_t),
|
||||
(uint8_t*)tmp, session_data_size,
|
||||
session_hdr->session_nonce, rx_publickey, tx_secretkey) != 0)
|
||||
{
|
||||
throw runtime_error("Unable to make session key!");
|
||||
}
|
||||
|
||||
session_packet_size = sizeof(wsession_hdr_t) + session_data_size + crypto_box_MACBYTES;
|
||||
assert(session_packet_size <= MAX_SESSION_PACKET_SIZE);
|
||||
}
|
||||
|
||||
void RawSocketTransmitter::set_mark(uint32_t idx)
|
||||
@ -144,9 +176,9 @@ void RawSocketTransmitter::set_mark(uint32_t idx)
|
||||
|
||||
|
||||
RawSocketTransmitter::RawSocketTransmitter(int k, int n, const string &keypair, uint64_t epoch, uint32_t channel_id, uint32_t fec_delay,
|
||||
const vector<string> &wlans, shared_ptr<uint8_t[]> radiotap_header, size_t radiotap_header_len,
|
||||
std::vector<tags_item_t> &tags, const vector<string> &wlans, shared_ptr<uint8_t[]> radiotap_header, size_t radiotap_header_len,
|
||||
uint8_t frame_type, bool use_qdisc, uint32_t fwmark) : \
|
||||
Transmitter(k, n, keypair, epoch, channel_id, fec_delay),
|
||||
Transmitter(k, n, keypair, epoch, channel_id, fec_delay, tags),
|
||||
channel_id(channel_id),
|
||||
current_output(0),
|
||||
ieee80211_seq(0),
|
||||
@ -335,7 +367,7 @@ void Transmitter::send_block_fragment(size_t packet_size)
|
||||
void Transmitter::send_session_key(void)
|
||||
{
|
||||
//fprintf(stderr, "Announce session key\n");
|
||||
inject_packet((uint8_t*)session_key_packet, sizeof(session_key_packet));
|
||||
inject_packet((uint8_t*)session_packet, session_packet_size);
|
||||
}
|
||||
|
||||
bool Transmitter::send_packet(const uint8_t *buf, size_t size, uint8_t flags)
|
||||
@ -890,6 +922,7 @@ int main(int argc, char * const *argv)
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
std::vector<tags_item_t> tags;
|
||||
shared_ptr<Transmitter> t;
|
||||
|
||||
uint32_t channel_id = (link_id << 8) + radio_port;
|
||||
@ -898,9 +931,9 @@ int main(int argc, char * const *argv)
|
||||
{
|
||||
fprintf(stderr, "Using %zu ports from %d for wlan emulation\n", wlans.size(), debug_port);
|
||||
t = shared_ptr<UdpTransmitter>(new UdpTransmitter(k, n, keypair, "127.0.0.1", debug_port, epoch, channel_id,
|
||||
fec_delay, use_qdisc, fwmark));
|
||||
fec_delay, tags, use_qdisc, fwmark));
|
||||
} else {
|
||||
t = shared_ptr<RawSocketTransmitter>(new RawSocketTransmitter(k, n, keypair, epoch, channel_id, fec_delay,
|
||||
t = shared_ptr<RawSocketTransmitter>(new RawSocketTransmitter(k, n, keypair, epoch, channel_id, fec_delay, tags,
|
||||
wlans, radiotap_header, radiotap_header_len,
|
||||
frame_type, use_qdisc, fwmark));
|
||||
}
|
||||
|
15
src/tx.hpp
15
src/tx.hpp
@ -33,7 +33,7 @@
|
||||
class Transmitter
|
||||
{
|
||||
public:
|
||||
Transmitter(int k, int m, const std::string &keypair, uint64_t epoch, uint32_t channel_id, uint32_t fec_delay);
|
||||
Transmitter(int k, int m, const std::string &keypair, uint64_t epoch, uint32_t channel_id, uint32_t fec_delay, std::vector<tags_item_t> &tags);
|
||||
virtual ~Transmitter();
|
||||
bool send_packet(const uint8_t *buf, size_t size, uint8_t flags);
|
||||
void send_session_key(void);
|
||||
@ -62,7 +62,9 @@ private:
|
||||
uint8_t tx_secretkey[crypto_box_SECRETKEYBYTES];
|
||||
uint8_t rx_publickey[crypto_box_PUBLICKEYBYTES];
|
||||
uint8_t session_key[crypto_aead_chacha20poly1305_KEYBYTES];
|
||||
uint8_t session_key_packet[sizeof(wsession_hdr_t) + sizeof(wsession_data_t) + crypto_box_MACBYTES];
|
||||
uint8_t session_packet[MAX_SESSION_PACKET_SIZE];
|
||||
uint16_t session_packet_size;
|
||||
std::vector<tags_item_t> &tags;
|
||||
};
|
||||
|
||||
class txAntennaItem
|
||||
@ -108,8 +110,9 @@ typedef std::unordered_map<uint64_t, txAntennaItem> tx_antenna_stat_t;
|
||||
class RawSocketTransmitter : public Transmitter
|
||||
{
|
||||
public:
|
||||
RawSocketTransmitter(int k, int m, const std::string &keypair, uint64_t epoch, uint32_t channel_id, uint32_t fec_delay, const std::vector<std::string> &wlans,
|
||||
shared_ptr<uint8_t[]> radiotap_header, size_t radiotap_header_len, uint8_t frame_type, bool use_qdisc, uint32_t fwmark);
|
||||
RawSocketTransmitter(int k, int m, const std::string &keypair, uint64_t epoch, uint32_t channel_id, uint32_t fec_delay, std::vector<tags_item_t> &tags,
|
||||
const std::vector<std::string> &wlans, shared_ptr<uint8_t[]> radiotap_header, size_t radiotap_header_len,
|
||||
uint8_t frame_type, bool use_qdisc, uint32_t fwmark);
|
||||
virtual ~RawSocketTransmitter();
|
||||
virtual void select_output(int idx)
|
||||
{
|
||||
@ -143,8 +146,8 @@ class UdpTransmitter : public Transmitter
|
||||
{
|
||||
public:
|
||||
UdpTransmitter(int k, int m, const std::string &keypair, const std::string &client_addr, int base_port, uint64_t epoch, uint32_t channel_id,
|
||||
uint32_t fec_delay, bool use_qdisc, uint32_t fwmark): \
|
||||
Transmitter(k, m, keypair, epoch, channel_id, fec_delay), base_port(base_port), use_qdisc(use_qdisc), fwmark(fwmark)
|
||||
uint32_t fec_delay, std::vector<tags_item_t> &tags, bool use_qdisc, uint32_t fwmark): \
|
||||
Transmitter(k, m, keypair, epoch, channel_id, fec_delay, tags), base_port(base_port), use_qdisc(use_qdisc), fwmark(fwmark)
|
||||
{
|
||||
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sockfd < 0) throw std::runtime_error(string_format("Error opening socket: %s", strerror(errno)));
|
||||
|
@ -170,7 +170,10 @@ static const uint8_t ieee80211_header[] __attribute__((unused)) = {
|
||||
+-- encrypted and authenticated by session key
|
||||
2. Session packet:
|
||||
wsession_hdr_t { packet_type = 2, nonce = random() }
|
||||
wsession_data_t { epoch, channel_id, fec_type, fec_k, fec_n, session_key } # -- encrypted and signed using rx and tx keys
|
||||
wsession_data_t { epoch, channel_id, #
|
||||
fec_type, fec_k, fec_n, #
|
||||
session_key, #
|
||||
optional TLV list } # -- encrypted and signed using rx and tx keys
|
||||
*/
|
||||
|
||||
// data nonce: 56bit block_idx + 8bit fragment_idx
|
||||
@ -180,8 +183,8 @@ static const uint8_t ieee80211_header[] __attribute__((unused)) = {
|
||||
#define MAX_BLOCK_IDX ((1LLU << 55) - 1)
|
||||
|
||||
// packet types
|
||||
#define WFB_PACKET_DATA 0x1
|
||||
#define WFB_PACKET_KEY 0x2
|
||||
#define WFB_PACKET_DATA 0x1
|
||||
#define WFB_PACKET_SESSION 0x2
|
||||
|
||||
// FEC types
|
||||
#define WFB_FEC_VDM_RS 0x1 //Reed-Solomon on Vandermonde matrix
|
||||
@ -213,15 +216,32 @@ typedef struct {
|
||||
uint8_t session_nonce[crypto_box_NONCEBYTES]; // random data
|
||||
} __attribute__ ((packed)) wsession_hdr_t;
|
||||
|
||||
typedef struct{
|
||||
typedef struct {
|
||||
uint64_t epoch; // Drop session packets from old epoch
|
||||
uint32_t channel_id; // (link_id << 8) + port_number
|
||||
uint8_t fec_type; // Now only supported type is WFB_FEC_VDM_RS
|
||||
uint8_t k; // FEC k
|
||||
uint8_t n; // FEC n
|
||||
uint8_t session_key[crypto_aead_chacha20poly1305_KEYBYTES];
|
||||
uint8_t tags[]; // Optional TLV attributes
|
||||
} __attribute__ ((packed)) wsession_data_t;
|
||||
|
||||
|
||||
// TLV attr header (in packet)
|
||||
typedef struct {
|
||||
uint8_t id;
|
||||
uint16_t len;
|
||||
uint8_t value[];
|
||||
} __attribute__ ((packed)) tlv_hdr_t;
|
||||
|
||||
|
||||
// TLV item
|
||||
typedef struct {
|
||||
uint8_t id;
|
||||
uint16_t len;
|
||||
void* value;
|
||||
} tags_item_t;
|
||||
|
||||
// Data packet. Embed FEC-encoded data
|
||||
|
||||
typedef struct {
|
||||
@ -239,6 +259,7 @@ typedef struct {
|
||||
#define MAX_PAYLOAD_SIZE (WIFI_MTU - sizeof(ieee80211_header) - sizeof(wblock_hdr_t) - crypto_aead_chacha20poly1305_ABYTES - sizeof(wpacket_hdr_t))
|
||||
#define MAX_FEC_PAYLOAD (WIFI_MTU - sizeof(ieee80211_header) - sizeof(wblock_hdr_t) - crypto_aead_chacha20poly1305_ABYTES)
|
||||
#define MAX_FORWARDER_PACKET_SIZE (WIFI_MTU - sizeof(ieee80211_header))
|
||||
#define MAX_SESSION_PACKET_SIZE (WIFI_MTU - sizeof(ieee80211_header))
|
||||
|
||||
int open_udp_socket_for_rx(int port, int rcv_buf_size);
|
||||
uint64_t get_time_ms(void);
|
||||
|
Loading…
Reference in New Issue
Block a user