From 48f061e33434e78bb479c54ef4678434921714eb Mon Sep 17 00:00:00 2001 From: Thomas Kolb Date: Thu, 18 Jul 2024 23:26:57 +0200 Subject: [PATCH] Handle sequence numbers This should enable basic retransmission handling. --- impl/src/layer2/layer2_rx.c | 15 +++++++++++++++ impl/src/layer2/layer2_rx.h | 5 +++++ impl/src/main.c | 13 ++++++++++--- impl/src/results.h | 1 + 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/impl/src/layer2/layer2_rx.c b/impl/src/layer2/layer2_rx.c index c145b64..c463144 100644 --- a/impl/src/layer2/layer2_rx.c +++ b/impl/src/layer2/layer2_rx.c @@ -13,6 +13,7 @@ result_t layer2_rx_init(layer2_rx_t *ctx, int tun_fd) { ctx->last_acked_seq = 0; + ctx->next_expected_seq = 0; ctx->tun_fd = tun_fd; 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; + 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); // 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) { return ctx->last_acked_seq; diff --git a/impl/src/layer2/layer2_rx.h b/impl/src/layer2/layer2_rx.h index 8e305dc..a7d5fa8 100644 --- a/impl/src/layer2/layer2_rx.h +++ b/impl/src/layer2/layer2_rx.h @@ -5,6 +5,7 @@ typedef struct { uint8_t last_acked_seq; + uint8_t next_expected_seq; int tun_fd; } 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); +/*!\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. */ uint8_t layer2_rx_get_last_acked_seq(const layer2_rx_t *ctx); diff --git a/impl/src/main.c b/impl/src/main.c index 7ed6b7f..9eda3e8 100644 --- a/impl/src/main.c +++ b/impl/src/main.c @@ -46,6 +46,8 @@ static double next_tx_switch_time = 0.0; static rx_stats_t m_rx_stats; static layer2_rx_t l2rx; +static layer2_tx_t l2tx; + 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); switch(result) { case OK: + layer2_tx_handle_ack(&l2tx, layer2_rx_get_last_acked_seq(&l2rx)); m_rx_stats.successful_decodes++; 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++; break; + case ERR_SEQUENCE: + LOG(LVL_ERR, "Packet not in the expected sequence."); + break; + default: // all other errors LOG(LVL_ERR, "layer2_rx_handle_packet() returned error code %u.", result); break; @@ -149,8 +156,6 @@ int main(int argc, char **argv) layer1_tx_t tx; layer1_rx_t rx; - layer2_tx_t l2tx; - sdr_ctx_t sdr; // initialize the console logger @@ -248,7 +253,9 @@ int main(int argc, char **argv) uint8_t packet_buf[2048]; 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) { // no more packets available diff --git a/impl/src/results.h b/impl/src/results.h index 6606521..3a7da97 100644 --- a/impl/src/results.h +++ b/impl/src/results.h @@ -14,6 +14,7 @@ typedef enum { ERR_SOAPY, // an error occurred in the SoapySDR library. ERR_SDR, // an error occurred in the SDR interface. ERR_INTEGRITY, // an integrity check failed (e.g. CRC of received packet is wrong) + ERR_SEQUENCE, // an unexpected packet was received } result_t; #ifdef DEBUG_LIQUID