diff --git a/impl/src/layer2/connection.c b/impl/src/layer2/connection.c index afa371e..8b623ea 100644 --- a/impl/src/layer2/connection.c +++ b/impl/src/layer2/connection.c @@ -7,6 +7,7 @@ #include "layer2/ham64.h" #include "layer2/packet_queue.h" #include "results.h" +#include "utils.h" #define SEQ_NR_MASK 0xF @@ -367,7 +368,9 @@ void connection_handle_ack(connection_ctx_t *ctx, uint8_t acked_seq, bool do_ack packets_available = packet_queue_get_used_space(&ctx->packet_queue); - 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, removed %zu packets, %zu packets remaining.", acked_seq, packets_to_remove, packets_available); + + ctx->retransmit_time = get_hires_time() + HRTIME_MS(RETRANSMIT_TIMEOUT_MS); if(do_ack && packets_available == 0) { // no packets left in queue, but an acknowledgement must be @@ -387,3 +390,17 @@ bool connection_can_transmit(const connection_ctx_t *ctx) return (packet_queue_get_used_space(&ctx->packet_queue) != 0) && (packet_queue_get(&ctx->packet_queue, ctx->next_packet_index) != NULL); } + + +result_t connection_maintain(connection_ctx_t *ctx) +{ + uint64_t now = get_hires_time(); + + if(ctx->retransmit_time != 0 && now >= ctx->retransmit_time) { + LOG(LVL_INFO, "Retransmit triggered."); + ctx->retransmit_time = 0; + connection_restart_tx(ctx); + } + + return OK; +} diff --git a/impl/src/layer2/connection.h b/impl/src/layer2/connection.h index 0d7669f..f1a2f7f 100644 --- a/impl/src/layer2/connection.h +++ b/impl/src/layer2/connection.h @@ -42,6 +42,9 @@ typedef struct connection_ctx_s { size_t next_packet_index; //!< Index in the packet queue of the next packet to transmit. uint8_t next_seq_nr; //!< Sequence number to tag the next transmitted packet with. + + uint64_t retransmit_time; //!< Time when a retransmit shall be triggered. + uint64_t last_rx_time; //!< Time when a packet was last received and decoded. } connection_ctx_t; @@ -129,4 +132,10 @@ void connection_handle_ack(connection_ctx_t *ctx, uint8_t acked_seq, bool do_ack */ bool connection_can_transmit(const connection_ctx_t *ctx); +/*!\brief Handle internal maintenance tasks. + * + * This should be called periodically to handle timeouts and retransmissions. + */ +result_t connection_maintain(connection_ctx_t *ctx); + #endif // CONNECTION_H