Handle sequence numbers

This should enable basic retransmission handling.
This commit is contained in:
Thomas Kolb 2024-07-18 23:26:57 +02:00
parent 93aa429f4f
commit 48f061e334
4 changed files with 31 additions and 3 deletions

View file

@ -13,6 +13,7 @@
result_t layer2_rx_init(layer2_rx_t *ctx, int tun_fd) result_t layer2_rx_init(layer2_rx_t *ctx, int tun_fd)
{ {
ctx->last_acked_seq = 0; ctx->last_acked_seq = 0;
ctx->next_expected_seq = 0;
ctx->tun_fd = tun_fd; ctx->tun_fd = tun_fd;
return OK; return OK;
} }
@ -45,6 +46,14 @@ result_t layer2_rx_handle_packet(layer2_rx_t *ctx, const uint8_t *buf, size_t bu
ctx->last_acked_seq = header.rx_seq_nr; ctx->last_acked_seq = header.rx_seq_nr;
if(ctx->next_expected_seq != header.tx_seq_nr) {
LOG(LVL_ERR, "Expected sequence number %u, received %u.", ctx->next_expected_seq, header.tx_seq_nr);
return ERR_SEQUENCE;
}
ctx->next_expected_seq++;
ctx->next_expected_seq &= 0xF;
size_t header_size = layer2_get_encoded_header_size(&header); size_t header_size = layer2_get_encoded_header_size(&header);
// extract the payload and forward it to the tun device // extract the payload and forward it to the tun device
@ -60,6 +69,12 @@ result_t layer2_rx_handle_packet(layer2_rx_t *ctx, const uint8_t *buf, size_t bu
} }
uint8_t layer2_rx_get_next_expected_seq(const layer2_rx_t *ctx)
{
return ctx->next_expected_seq;
}
uint8_t layer2_rx_get_last_acked_seq(const layer2_rx_t *ctx) uint8_t layer2_rx_get_last_acked_seq(const layer2_rx_t *ctx)
{ {
return ctx->last_acked_seq; return ctx->last_acked_seq;

View file

@ -5,6 +5,7 @@
typedef struct { typedef struct {
uint8_t last_acked_seq; uint8_t last_acked_seq;
uint8_t next_expected_seq;
int tun_fd; int tun_fd;
} layer2_rx_t; } layer2_rx_t;
@ -31,6 +32,10 @@ void layer2_rx_destroy(layer2_rx_t *ctx);
*/ */
result_t layer2_rx_handle_packet(layer2_rx_t *ctx, const uint8_t *buf, size_t buf_len); result_t layer2_rx_handle_packet(layer2_rx_t *ctx, const uint8_t *buf, size_t buf_len);
/*!\brief Return the sequence number expected next by our side.
*/
uint8_t layer2_rx_get_next_expected_seq(const layer2_rx_t *ctx);
/*!\brief Return the sequence number expected next by the other side. /*!\brief Return the sequence number expected next by the other side.
*/ */
uint8_t layer2_rx_get_last_acked_seq(const layer2_rx_t *ctx); uint8_t layer2_rx_get_last_acked_seq(const layer2_rx_t *ctx);

View file

@ -46,6 +46,8 @@ static double next_tx_switch_time = 0.0;
static rx_stats_t m_rx_stats; static rx_stats_t m_rx_stats;
static layer2_rx_t l2rx; static layer2_rx_t l2rx;
static layer2_tx_t l2tx;
static void signal_handler(int signal, siginfo_t *info, void *ctx) static void signal_handler(int signal, siginfo_t *info, void *ctx)
{ {
@ -100,6 +102,7 @@ void cb_rx(rx_evt_t evt, const struct layer1_rx_s *rx, uint8_t *packet_data, siz
result_t result = layer2_rx_handle_packet(&l2rx, packet_data, packet_len); result_t result = layer2_rx_handle_packet(&l2rx, packet_data, packet_len);
switch(result) { switch(result) {
case OK: case OK:
layer2_tx_handle_ack(&l2tx, layer2_rx_get_last_acked_seq(&l2rx));
m_rx_stats.successful_decodes++; m_rx_stats.successful_decodes++;
break; break;
@ -108,6 +111,10 @@ void cb_rx(rx_evt_t evt, const struct layer1_rx_s *rx, uint8_t *packet_data, siz
m_rx_stats.failed_decodes++; m_rx_stats.failed_decodes++;
break; break;
case ERR_SEQUENCE:
LOG(LVL_ERR, "Packet not in the expected sequence.");
break;
default: // all other errors default: // all other errors
LOG(LVL_ERR, "layer2_rx_handle_packet() returned error code %u.", result); LOG(LVL_ERR, "layer2_rx_handle_packet() returned error code %u.", result);
break; break;
@ -149,8 +156,6 @@ int main(int argc, char **argv)
layer1_tx_t tx; layer1_tx_t tx;
layer1_rx_t rx; layer1_rx_t rx;
layer2_tx_t l2tx;
sdr_ctx_t sdr; sdr_ctx_t sdr;
// initialize the console logger // initialize the console logger
@ -248,7 +253,9 @@ int main(int argc, char **argv)
uint8_t packet_buf[2048]; uint8_t packet_buf[2048];
size_t packet_size; size_t packet_size;
packet_size = layer2_tx_encode_next_packet(&l2tx, 0 /* FIXME */, packet_buf, sizeof(packet_buf)); packet_size = layer2_tx_encode_next_packet(&l2tx,
layer2_rx_get_next_expected_seq(&l2rx),
packet_buf, sizeof(packet_buf));
if(packet_size == 0) { if(packet_size == 0) {
// no more packets available // no more packets available

View file

@ -14,6 +14,7 @@ typedef enum {
ERR_SOAPY, // an error occurred in the SoapySDR library. ERR_SOAPY, // an error occurred in the SoapySDR library.
ERR_SDR, // an error occurred in the SDR interface. ERR_SDR, // an error occurred in the SDR interface.
ERR_INTEGRITY, // an integrity check failed (e.g. CRC of received packet is wrong) ERR_INTEGRITY, // an integrity check failed (e.g. CRC of received packet is wrong)
ERR_SEQUENCE, // an unexpected packet was received
} result_t; } result_t;
#ifdef DEBUG_LIQUID #ifdef DEBUG_LIQUID