diff --git a/src/main.cpp b/src/main.cpp index 6b89782..fa3218a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -90,6 +90,11 @@ static uint8_t g_inflight_count = 0; static uint16_t g_inflight_batch_id = 0; static bool g_inflight_active = false; static bool g_inflight_sync_request = false; +static uint8_t g_inflight_encoded_payload[BATCH_MAX_COMPRESSED]; +static size_t g_inflight_encoded_payload_len = 0; +static uint16_t g_inflight_encoded_batch_id = 0; +static bool g_inflight_encoded_sync_request = false; +static bool g_inflight_encoded_valid = false; static uint32_t g_last_debug_log_ms = 0; static uint32_t g_sender_rx_window_ms = 0; static uint32_t g_sender_sleep_ms = 0; @@ -145,6 +150,7 @@ static TxBuildError g_last_tx_build_error = TxBuildError::None; static void watchdog_kick(); static void finish_inflight_batch(); +static void invalidate_inflight_encode_cache(); static void serial_debug_printf(const char *fmt, ...) { if (!SERIAL_DEBUG_MODE) { @@ -218,6 +224,13 @@ static void sender_log_diagnostics(uint32_t now_ms) { static_cast(g_sender_sleep_ms)); } +static void invalidate_inflight_encode_cache() { + g_inflight_encoded_payload_len = 0; + g_inflight_encoded_batch_id = 0; + g_inflight_encoded_sync_request = false; + g_inflight_encoded_valid = false; +} + static uint8_t bit_count32(uint32_t value) { uint8_t count = 0; while (value != 0) { @@ -477,6 +490,7 @@ static bool batch_queue_drop_oldest() { g_inflight_count = 0; g_inflight_batch_id = 0; g_inflight_sync_request = false; + invalidate_inflight_encode_cache(); } g_batch_tail = (g_batch_tail + 1) % BATCH_QUEUE_DEPTH; g_batch_count--; @@ -872,6 +886,33 @@ static bool send_inflight_batch(uint32_t ts_for_display) { if (!g_inflight_active) { return false; } + + bool cache_match = g_inflight_encoded_valid && + g_inflight_encoded_batch_id == g_inflight_batch_id && + g_inflight_encoded_sync_request == g_inflight_sync_request; + if (cache_match) { + g_batch_ack_timeout_ms = compute_batch_ack_timeout_ms(g_inflight_encoded_payload_len); + uint32_t send_start = millis(); + bool ok = send_batch_payload(g_inflight_encoded_payload, g_inflight_encoded_payload_len, ts_for_display, g_inflight_batch_id); + uint32_t send_ms = millis() - send_start; + if (SERIAL_DEBUG_MODE && send_ms > 1000) { + serial_debug_printf("tx: resend batch took %lums", static_cast(send_ms)); + } + if (ok) { + g_last_batch_send_ms = millis(); + if (g_inflight_sync_request) { + serial_debug_printf("sync: request tx batch_id=%u", g_inflight_batch_id); + } else { + serial_debug_printf("tx: resent batch_id=%u len=%u", g_inflight_batch_id, static_cast(g_inflight_encoded_payload_len)); + } + } else if (g_inflight_sync_request) { + serial_debug_printf("sync: request tx failed batch_id=%u", g_inflight_batch_id); + } else { + serial_debug_printf("tx: resend failed batch_id=%u", g_inflight_batch_id); + } + return ok; + } + BatchInput input = {}; input.sender_id = sender_id_from_short_id(g_short_id); input.batch_id = g_inflight_batch_id; @@ -966,8 +1007,14 @@ static bool send_inflight_batch(uint32_t ts_for_display) { uint32_t encode_start = millis(); if (!encode_batch(input, encoded, sizeof(encoded), &encoded_len)) { g_last_tx_build_error = TxBuildError::Encode; + invalidate_inflight_encode_cache(); return false; } + memcpy(g_inflight_encoded_payload, encoded, encoded_len); + g_inflight_encoded_payload_len = encoded_len; + g_inflight_encoded_batch_id = g_inflight_batch_id; + g_inflight_encoded_sync_request = g_inflight_sync_request; + g_inflight_encoded_valid = true; uint32_t encode_ms = millis() - encode_start; if (SERIAL_DEBUG_MODE) { serial_debug_printf("tx: batch_id=%u count=%u mask=%08lX bin_len=%u", @@ -1025,6 +1072,7 @@ static bool send_meter_batch(uint32_t ts_for_display) { g_inflight_count = 0; g_inflight_batch_id = 0; g_inflight_sync_request = false; + invalidate_inflight_encode_cache(); } return ok; } @@ -1057,6 +1105,7 @@ static bool send_sync_request() { g_inflight_active = false; g_inflight_sync_request = false; g_inflight_batch_id = 0; + invalidate_inflight_encode_cache(); } return ok; } @@ -1078,6 +1127,7 @@ static void finish_inflight_batch() { g_inflight_count = 0; g_inflight_batch_id = 0; g_inflight_sync_request = false; + invalidate_inflight_encode_cache(); g_batch_id++; } @@ -1449,6 +1499,7 @@ static void sender_loop() { g_inflight_count = 0; g_inflight_batch_id = 0; g_inflight_sync_request = false; + invalidate_inflight_encode_cache(); } note_fault(g_sender_faults, g_sender_last_error, g_sender_last_error_utc, g_sender_last_error_ms, FaultType::LoraTx); display_set_last_error(g_sender_last_error, g_sender_last_error_utc, g_sender_last_error_ms);