Cache encoded inflight payload for retry efficiency

This commit is contained in:
2026-02-17 01:13:27 +01:00
parent cc5881974c
commit 07d0e6c3e0

View File

@@ -90,6 +90,11 @@ static uint8_t g_inflight_count = 0;
static uint16_t g_inflight_batch_id = 0; static uint16_t g_inflight_batch_id = 0;
static bool g_inflight_active = false; static bool g_inflight_active = false;
static bool g_inflight_sync_request = 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_last_debug_log_ms = 0;
static uint32_t g_sender_rx_window_ms = 0; static uint32_t g_sender_rx_window_ms = 0;
static uint32_t g_sender_sleep_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 watchdog_kick();
static void finish_inflight_batch(); static void finish_inflight_batch();
static void invalidate_inflight_encode_cache();
static void serial_debug_printf(const char *fmt, ...) { static void serial_debug_printf(const char *fmt, ...) {
if (!SERIAL_DEBUG_MODE) { if (!SERIAL_DEBUG_MODE) {
@@ -218,6 +224,13 @@ static void sender_log_diagnostics(uint32_t now_ms) {
static_cast<unsigned long>(g_sender_sleep_ms)); static_cast<unsigned long>(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) { static uint8_t bit_count32(uint32_t value) {
uint8_t count = 0; uint8_t count = 0;
while (value != 0) { while (value != 0) {
@@ -477,6 +490,7 @@ static bool batch_queue_drop_oldest() {
g_inflight_count = 0; g_inflight_count = 0;
g_inflight_batch_id = 0; g_inflight_batch_id = 0;
g_inflight_sync_request = false; g_inflight_sync_request = false;
invalidate_inflight_encode_cache();
} }
g_batch_tail = (g_batch_tail + 1) % BATCH_QUEUE_DEPTH; g_batch_tail = (g_batch_tail + 1) % BATCH_QUEUE_DEPTH;
g_batch_count--; g_batch_count--;
@@ -872,6 +886,33 @@ static bool send_inflight_batch(uint32_t ts_for_display) {
if (!g_inflight_active) { if (!g_inflight_active) {
return false; 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<unsigned long>(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<unsigned>(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 = {}; BatchInput input = {};
input.sender_id = sender_id_from_short_id(g_short_id); input.sender_id = sender_id_from_short_id(g_short_id);
input.batch_id = g_inflight_batch_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(); uint32_t encode_start = millis();
if (!encode_batch(input, encoded, sizeof(encoded), &encoded_len)) { if (!encode_batch(input, encoded, sizeof(encoded), &encoded_len)) {
g_last_tx_build_error = TxBuildError::Encode; g_last_tx_build_error = TxBuildError::Encode;
invalidate_inflight_encode_cache();
return false; 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; uint32_t encode_ms = millis() - encode_start;
if (SERIAL_DEBUG_MODE) { if (SERIAL_DEBUG_MODE) {
serial_debug_printf("tx: batch_id=%u count=%u mask=%08lX bin_len=%u", 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_count = 0;
g_inflight_batch_id = 0; g_inflight_batch_id = 0;
g_inflight_sync_request = false; g_inflight_sync_request = false;
invalidate_inflight_encode_cache();
} }
return ok; return ok;
} }
@@ -1057,6 +1105,7 @@ static bool send_sync_request() {
g_inflight_active = false; g_inflight_active = false;
g_inflight_sync_request = false; g_inflight_sync_request = false;
g_inflight_batch_id = 0; g_inflight_batch_id = 0;
invalidate_inflight_encode_cache();
} }
return ok; return ok;
} }
@@ -1078,6 +1127,7 @@ static void finish_inflight_batch() {
g_inflight_count = 0; g_inflight_count = 0;
g_inflight_batch_id = 0; g_inflight_batch_id = 0;
g_inflight_sync_request = false; g_inflight_sync_request = false;
invalidate_inflight_encode_cache();
g_batch_id++; g_batch_id++;
} }
@@ -1449,6 +1499,7 @@ static void sender_loop() {
g_inflight_count = 0; g_inflight_count = 0;
g_inflight_batch_id = 0; g_inflight_batch_id = 0;
g_inflight_sync_request = false; 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); 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); display_set_last_error(g_sender_last_error, g_sender_last_error_utc, g_sender_last_error_ms);