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)
{
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;

View file

@ -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);

View file

@ -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

View file

@ -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