Handle sequence numbers
This should enable basic retransmission handling.
This commit is contained in:
parent
93aa429f4f
commit
48f061e334
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue