Do not transmit an empty packet if an empty packet was received

This commit is contained in:
Thomas Kolb 2024-07-27 00:33:47 +02:00
parent 9990aa5fbb
commit 04dcfff6fd
5 changed files with 14 additions and 7 deletions

View file

@ -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 // check the CRC
size_t packet_size = buf_len - crc_sizeof_key(PAYLOAD_CRC_SCHEME); 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; ctx->last_acked_seq = header.rx_seq_nr;
*shall_ack = true;
switch(header.msg_type) { switch(header.msg_type) {
case L2_MSG_TYPE_EMPTY: case L2_MSG_TYPE_EMPTY:
*shall_ack = false;
LOG(LVL_DEBUG, "Empty packet: accepted ACK for %u.", ctx->last_acked_seq); LOG(LVL_DEBUG, "Empty packet: accepted ACK for %u.", ctx->last_acked_seq);
return OK; // do not write anything to the TUN device return OK; // do not write anything to the TUN device

View file

@ -2,6 +2,7 @@
#define LAYER2_RX_H #define LAYER2_RX_H
#include <results.h> #include <results.h>
#include <stdbool.h>
typedef struct { typedef struct {
uint8_t last_acked_seq; uint8_t last_acked_seq;
@ -28,9 +29,10 @@ void layer2_rx_destroy(layer2_rx_t *ctx);
* \param ctx The receiver context. * \param ctx The receiver context.
* \param buf Where to write the encoded packet data. * \param buf Where to write the encoded packet data.
* \param buf_len Space available in the buffer. * \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. * \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. /*!\brief Return the sequence number expected next by our side.
*/ */

View file

@ -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; 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); 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 // no packets left in queue, but an acknowledgement must be
// transmitted. Add an empty packet to do that. // transmitted. Add an empty packet to do that.
result_t res = layer2_tx_add_empty_packet(ctx, false); result_t res = layer2_tx_add_empty_packet(ctx, false);

View file

@ -63,8 +63,9 @@ void layer2_tx_restart(layer2_tx_t *ctx);
* *
* \param ctx The transmitter context. * \param ctx The transmitter context.
* \param acked_seq The acknowledged (= next expected) sequence number. * \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. /*!\brief Check if there are packets queued for transmission.
*/ */

View file

@ -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); 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) { switch(result) {
case OK: 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++; m_rx_stats.successful_decodes++;
break; break;