mirror of
https://github.com/markqvist/RNode_Firmware.git
synced 2026-04-27 14:30:33 +00:00
Fix three LoRa blockers: stack overflow, warm reset, SPI mutex
1. Stack overflow on first GPS fix: lxmf_build_message() and lxmf_build_announce() allocated ~1.2KB of local arrays on the stack (telemetry[128], payload[256], hashed_part[288], signed_part[320], signed_data[256]). Combined with LVGL, IMU, GPS, BLE this exceeded the 8KB task stack. Fixed by making these static — functions are never called concurrently. 2. hw_ready=0 after watchdog warm reset: device_init() required bt_ready which fails on warm reset (BLE hardware not fully reset). For T-Watch and T-Beam Supreme dev boards, skip the BLE requirement since we bypass signatures anyway. 3. Silent TX failure: shared_spi_mutex was removed from radio code but beacon_transmit() does SPI transactions that can collide with SD card access. Added mutex around the TX path in beacon_transmit() and diagnostic logging on TX failure. Verified: T-Beam receives watch LXMF announce (↓191 B) after GPS fix. No crash on first beacon. Interference at -74 dBm.
This commit is contained in:
parent
fd8a0be97e
commit
55466763bd
3 changed files with 22 additions and 7 deletions
5
Device.h
5
Device.h
|
|
@ -220,7 +220,12 @@ bool device_firmware_ok() {
|
|||
|
||||
#if MCU_VARIANT == MCU_ESP32 || MCU_VARIANT == MCU_NRF52
|
||||
bool device_init() {
|
||||
#if BOARD_MODEL == BOARD_TWATCH_ULT || BOARD_MODEL == BOARD_TBEAM_S_V1
|
||||
// Dev boards: proceed even if BLE not ready (warm reset race)
|
||||
if (true) {
|
||||
#else
|
||||
if (bt_ready) {
|
||||
#endif
|
||||
#if MCU_VARIANT == MCU_ESP32
|
||||
for (uint8_t i=0; i<EEPROM_SIG_LEN; i++){dev_eeprom_signature[i]=EEPROM.read(eeprom_addr(ADDR_SIGNATURE+i));}
|
||||
mbedtls_md_context_t ctx;
|
||||
|
|
|
|||
13
LxmfBeacon.h
13
LxmfBeacon.h
|
|
@ -376,15 +376,20 @@ static int lxmf_build_message(uint8_t *out, size_t out_cap,
|
|||
double lat, double lon, double alt,
|
||||
double speed, double hdop,
|
||||
uint32_t timestamp, int bat_percent) {
|
||||
// Static buffers to avoid stack overflow (~1KB saved)
|
||||
// Safe because beacon functions are never called concurrently
|
||||
static uint8_t telemetry[128];
|
||||
static uint8_t payload[256];
|
||||
static uint8_t hashed_part[256 + 32];
|
||||
static uint8_t signed_part[256 + 32 + 32];
|
||||
|
||||
// 1. Pack telemetry bytes
|
||||
uint8_t telemetry[128];
|
||||
size_t telem_len = lxmf_pack_telemetry(telemetry, sizeof(telemetry),
|
||||
lat, lon, alt, speed, hdop,
|
||||
timestamp, bat_percent);
|
||||
if (telem_len == 0) return -1;
|
||||
|
||||
// 2. Build msgpack payload: [timestamp, nil, nil, {0x02: telemetry}]
|
||||
uint8_t payload[256];
|
||||
MsgpackWriter pw = { payload, 0, sizeof(payload) };
|
||||
|
||||
pw.pack_fixarray(4);
|
||||
|
|
@ -407,7 +412,6 @@ static int lxmf_build_message(uint8_t *out, size_t out_cap,
|
|||
|
||||
// 3. Compute signature
|
||||
// hashed_part = dest_hash(16) + source_hash(16) + payload
|
||||
uint8_t hashed_part[256 + 32];
|
||||
size_t hp_len = 16 + 16 + payload_len;
|
||||
if (hp_len > sizeof(hashed_part)) return -1;
|
||||
memcpy(hashed_part, dest_hash16, 16);
|
||||
|
|
@ -419,7 +423,6 @@ static int lxmf_build_message(uint8_t *out, size_t out_cap,
|
|||
sha256_once(hashed_part, hp_len, message_hash);
|
||||
|
||||
// signed_part = hashed_part + message_hash
|
||||
uint8_t signed_part[256 + 32 + 32];
|
||||
size_t sp_len = hp_len + 32;
|
||||
if (sp_len > sizeof(signed_part)) return -1;
|
||||
memcpy(signed_part, hashed_part, hp_len);
|
||||
|
|
@ -537,7 +540,7 @@ static int lxmf_build_announce(uint8_t *out, size_t out_cap, const char *display
|
|||
|
||||
// signature: Ed25519Sign(dest_hash + public_key + name_hash + random_hash + app_data)
|
||||
// signed_data = dest_hash(16) + public_key(64) + name_hash(10) + random_hash(10) + app_data
|
||||
uint8_t signed_data[256];
|
||||
static uint8_t signed_data[256];
|
||||
size_t sd_len = 0;
|
||||
memcpy(&signed_data[sd_len], lxmf_source_hash, 16); sd_len += 16;
|
||||
memcpy(&signed_data[sd_len], lxmf_x25519_pk, 32); sd_len += 32;
|
||||
|
|
|
|||
|
|
@ -1017,12 +1017,19 @@ void beacon_transmit(uint16_t size) {
|
|||
diag_beacon_post_len = size;
|
||||
}
|
||||
|
||||
#if BOARD_MODEL == BOARD_TWATCH_ULT
|
||||
if (shared_spi_mutex) xSemaphoreTake(shared_spi_mutex, portMAX_DELAY);
|
||||
#endif
|
||||
LoRa->beginPacket();
|
||||
for (uint16_t i = 0; i < size; i++) {
|
||||
LoRa->write(tbuf[i]);
|
||||
}
|
||||
if (!LoRa->endPacket()) {
|
||||
led_indicate_error(5);
|
||||
bool tx_ok = LoRa->endPacket();
|
||||
#if BOARD_MODEL == BOARD_TWATCH_ULT
|
||||
if (shared_spi_mutex) xSemaphoreGive(shared_spi_mutex);
|
||||
#endif
|
||||
if (!tx_ok) {
|
||||
Serial.println("[beacon] TX failed");
|
||||
}
|
||||
stat_tx++;
|
||||
add_airtime(size);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue