Merge upstream dev through 5846fa19

Import Airoha GPS RTC backup sleep, 24 contact search results, and the T-Echo Lite USB companion target. Preserve existing GPS telemetry and power-saving controls, crypto alignment checks, ESP32 RTC recovery, and RAK11310 dynamic-preference compatibility.

Validate GPS sleep acknowledgments with their NMEA checksum and add six native regression tests covering retry, drain, corruption, grace timeout, and timer rollover.

Verified: 1648 native and KISS modem tests; targeted nRF52, companion routing, one-key DM, and clock checks; T1000-E BLE, MeshTracker X1 USB, and T-Echo Lite USB companion builds.
This commit is contained in:
mikecarper committed 2026-09-30 02:13:25 -07:00
commit 062a835f09
14 files changed
+242 -83

No files matched your search

+1 -1
View File
@@ -50,7 +50,7 @@ public:
/**
* \brief checks the MAC (in leading bytes of 'src'), then if valid, decrypts remaining bytes in src.
* \returns zero if MAC is invalid, otherwise the length of decrypted bytes in 'dest'
* \returns zero if MAC is invalid or ciphertext is not block-aligned, otherwise the length of decrypted bytes in 'dest'
*/
static int MACThenDecrypt(const uint8_t* shared_secret, uint8_t* dest, const uint8_t* src, int src_len);
+1 -1
View File
@@ -16,7 +16,7 @@ static_assert(MAX_CORRELATED_CLI_TEXT_LEN <= MAX_TEXT_LEN,
#include "ContactInfo.h"
#define MAX_SEARCH_RESULTS 8
#define MAX_SEARCH_RESULTS 24
#define MSG_SEND_FAILED 0
#define MSG_SEND_SENT_FLOOD 1
+24
View File
@@ -0,0 +1,24 @@
#pragma once
#include <helpers/sensors/LocationProvider.h>
#ifdef GPS_NMEA_DEBUG
#include <helpers/UsbLogging.h>
#endif
// Board must keep the GPS RTC backup pin powered and can cut GPS power once we return.
// Returns true if the command was acked within 3 attempts, otherwise returns false.
static inline bool airohaEnterSleep(LocationProvider* nmea) {
for (uint8_t attempt = 0; attempt < 3; attempt++) {
nmea->drain();
nmea->sendSentence("$PAIR650,0");
if (nmea->waitFor("$PAIR001,650,0", 50)) { // wait for the command received signal
#ifdef GPS_NMEA_DEBUG
if (mesh::isUsbLoggingEnabled()) {
mesh::usbLoggingPort().printf("Airoha RTC Backup sleep command accepted by GPS after %u attempts\r\n", attempt + 1);
}
#endif
nmea->waitFor("$PAIR650,0", 50); // give the GPS 50ms grace to signal it is ready for sleep
return true;
}
}
return false;
}
+2
View File
@@ -73,6 +73,8 @@ public:
virtual bool isValid() = 0;
virtual long getTimestamp() = 0;
virtual void sendSentence(const char * sentence);
virtual bool waitFor(const char* prefix, uint32_t timeout_ms) { return false; }
virtual void drain() { }
virtual void reset() = 0;
virtual void begin() = 0;
virtual void stop() = 0;
@@ -198,10 +198,34 @@ public :
return timestamp <= 0x7FFFFFFFUL ? static_cast<long>(timestamp) : 0;
}
void drain() override { while (_gps_serial->available()) _gps_serial->read(); }
const char* getSentence() const { return nmea.getSentence(); }
void sendSentence(const char *sentence) override {
nmea.sendSentence(*_gps_serial, sentence);
}
bool waitFor(const char* prefix, uint32_t timeout_ms) override {
size_t plen = strlen(prefix);
uint32_t timeout = millis() + timeout_ms;
while ((int32_t)(millis() - timeout) < 0) {
if (_gps_serial->available()) {
char c = _gps_serial->read();
#ifdef GPS_NMEA_DEBUG
if (mesh::isUsbLoggingEnabled()) mesh::usbLoggingPort().print(c);
#endif
// MicroNMEA also returns true for a complete sentence with a
// bad checksum. A damaged ACK must not confirm GPS sleep.
if (nmea.process(c) && MicroNMEA::testChecksum(nmea.getSentence())
&& strncmp(nmea.getSentence(), prefix, plen) == 0) return true;
} else {
yield();
}
}
return false;
}
void loop() override {
size_t processed = 0;