diff --git a/impl/src/layer2/layer2_rx.c b/impl/src/layer2/layer2_rx.c index 86a5798..ad17beb 100644 --- a/impl/src/layer2/layer2_rx.c +++ b/impl/src/layer2/layer2_rx.c @@ -29,7 +29,7 @@ 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, bool *shall_ack) { // check the CRC size_t packet_size = buf_len - crc_sizeof_key(PAYLOAD_CRC_SCHEME); @@ -52,8 +52,11 @@ 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; + *shall_ack = true; + switch(header.msg_type) { case L2_MSG_TYPE_EMPTY: + *shall_ack = false; LOG(LVL_DEBUG, "Empty packet: accepted ACK for %u.", ctx->last_acked_seq); return OK; // do not write anything to the TUN device diff --git a/impl/src/layer2/layer2_rx.h b/impl/src/layer2/layer2_rx.h index a7d5fa8..80192b8 100644 --- a/impl/src/layer2/layer2_rx.h +++ b/impl/src/layer2/layer2_rx.h @@ -2,6 +2,7 @@ #define LAYER2_RX_H #include +#include typedef struct { uint8_t last_acked_seq; @@ -28,9 +29,10 @@ void layer2_rx_destroy(layer2_rx_t *ctx); * \param ctx The receiver context. * \param buf Where to write the encoded packet data. * \param buf_len Space available in the buffer. + * \param shall_ack Pointer to a boolean that is set to indicate whether this packet should be ACKed or not. * \returns A result code from the packet handling procedure. */ -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, bool *shall_ack); /*!\brief Return the sequence number expected next by our side. */ diff --git a/impl/src/layer2/layer2_tx.c b/impl/src/layer2/layer2_tx.c index 02e7fd5..fdff035 100644 --- a/impl/src/layer2/layer2_tx.c +++ b/impl/src/layer2/layer2_tx.c @@ -160,7 +160,7 @@ void layer2_tx_restart(layer2_tx_t *ctx) } -void layer2_tx_handle_ack(layer2_tx_t *ctx, uint8_t acked_seq) +void layer2_tx_handle_ack(layer2_tx_t *ctx, uint8_t acked_seq, bool do_ack) { ctx->next_packet_index = 0; @@ -183,7 +183,7 @@ void layer2_tx_handle_ack(layer2_tx_t *ctx, uint8_t acked_seq) LOG(LVL_DEBUG, "handling ack for seq_nr %u, removing %zu packets, %zu packets remaining.", acked_seq, packets_to_remove, packets_available); - if(packets_available == 0) { + if(do_ack && packets_available == 0) { // no packets left in queue, but an acknowledgement must be // transmitted. Add an empty packet to do that. result_t res = layer2_tx_add_empty_packet(ctx, false); diff --git a/impl/src/layer2/layer2_tx.h b/impl/src/layer2/layer2_tx.h index e30ddd0..04a256d 100644 --- a/impl/src/layer2/layer2_tx.h +++ b/impl/src/layer2/layer2_tx.h @@ -63,8 +63,9 @@ void layer2_tx_restart(layer2_tx_t *ctx); * * \param ctx The transmitter context. * \param acked_seq The acknowledged (= next expected) sequence number. + * \param do_ack Whether an empty packet shall be generated if the queue is empty. */ -void layer2_tx_handle_ack(layer2_tx_t *ctx, uint8_t acked_seq); +void layer2_tx_handle_ack(layer2_tx_t *ctx, uint8_t acked_seq, bool do_ack); /*!\brief Check if there are packets queued for transmission. */ diff --git a/impl/src/main.c b/impl/src/main.c index 750cdf9..26d4242 100644 --- a/impl/src/main.c +++ b/impl/src/main.c @@ -101,10 +101,11 @@ void cb_rx(rx_evt_t evt, const struct layer1_rx_s *rx, uint8_t *packet_data, siz block_tx_for(TX_SWITCH_BACKOFF_END_OF_PACKET_MS); - result_t result = layer2_rx_handle_packet(&l2rx, packet_data, packet_len); + bool shall_ack; + result_t result = layer2_rx_handle_packet(&l2rx, packet_data, packet_len, &shall_ack); switch(result) { case OK: - layer2_tx_handle_ack(&l2tx, layer2_rx_get_last_acked_seq(&l2rx)); + layer2_tx_handle_ack(&l2tx, layer2_rx_get_last_acked_seq(&l2rx), shall_ack); m_rx_stats.successful_decodes++; break;