mirror of
https://github.com/meshtastic/firmware.git
synced 2025-08-26 22:55:10 +00:00
Merge remote-tracking branch 'origin/develop' into dismiss_frames
This commit is contained in:
commit
ad71354e6c
@ -50,7 +50,7 @@ lib_deps =
|
||||
${radiolib_base.lib_deps}
|
||||
|
||||
# renovate: datasource=git-refs depName=caveman99-stm32-Crypto packageName=https://github.com/caveman99/Crypto gitBranch=main
|
||||
https://github.com/caveman99/Crypto/archive/eae9c768054118a9399690f8af202853d1ae8516.zip
|
||||
https://github.com/caveman99/Crypto/archive/1aa30eb536bd52a576fde6dfa393bf7349cf102d.zip
|
||||
|
||||
lib_ignore =
|
||||
OneButton
|
||||
|
@ -118,7 +118,7 @@ lib_deps =
|
||||
[device-ui_base]
|
||||
lib_deps =
|
||||
# renovate: datasource=git-refs depName=meshtastic/device-ui packageName=https://github.com/meshtastic/device-ui gitBranch=master
|
||||
https://github.com/meshtastic/device-ui/archive/3dc7cf3e233aaa8cc23492cca50541fc099ebfa1.zip
|
||||
https://github.com/meshtastic/device-ui/archive/0f32b64dca418c6465763ec576509a6a2bfbc50a.zip
|
||||
|
||||
; Common libs for environmental measurements in telemetry module
|
||||
[environmental_base]
|
||||
|
@ -8,6 +8,7 @@
|
||||
"replacements:all",
|
||||
"workarounds:all"
|
||||
],
|
||||
"baseBranchPatterns": ["master"],
|
||||
"forkProcessing": "enabled",
|
||||
"ignoreDeps": [
|
||||
"protobufs"
|
||||
|
10
src/main.cpp
10
src/main.cpp
@ -406,6 +406,16 @@ void setup()
|
||||
|
||||
initDeepSleep();
|
||||
|
||||
#if defined(MODEM_POWER_EN)
|
||||
pinMode(MODEM_POWER_EN, OUTPUT);
|
||||
digitalWrite(MODEM_POWER_EN, LOW);
|
||||
#endif
|
||||
|
||||
#if defined(MODEM_PWRKEY)
|
||||
pinMode(MODEM_PWRKEY, OUTPUT);
|
||||
digitalWrite(MODEM_PWRKEY, LOW);
|
||||
#endif
|
||||
|
||||
#if defined(LORA_TCXO_GPIO)
|
||||
pinMode(LORA_TCXO_GPIO, OUTPUT);
|
||||
digitalWrite(LORA_TCXO_GPIO, HIGH);
|
||||
|
@ -32,9 +32,12 @@ const RegionInfo regions[] = {
|
||||
RDEF(US, 902.0f, 928.0f, 100, 0, 30, true, false, false),
|
||||
|
||||
/*
|
||||
https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
|
||||
EN300220 ETSI V3.2.1 [Table B.1, Item H, p. 21]
|
||||
|
||||
https://www.etsi.org/deliver/etsi_en/300200_300299/30022002/03.02.01_60/en_30022002v030201p.pdf
|
||||
FIXME: https://github.com/meshtastic/firmware/issues/3371
|
||||
*/
|
||||
RDEF(EU_433, 433.0f, 434.0f, 10, 0, 12, true, false, false),
|
||||
RDEF(EU_433, 433.0f, 434.0f, 10, 0, 10, true, false, false),
|
||||
|
||||
/*
|
||||
https://www.thethingsnetwork.org/docs/lorawan/duty-cycle/
|
||||
|
@ -422,7 +422,8 @@ void RadioLibInterface::handleReceiveInterrupt()
|
||||
}
|
||||
#endif
|
||||
if (state != RADIOLIB_ERR_NONE) {
|
||||
LOG_ERROR("Ignore received packet due to error=%d", state);
|
||||
LOG_ERROR("Ignore received packet due to error=%d (maybe to=0x%08x, from=0x%08x, flags=0x%02x)", state,
|
||||
radioBuffer.header.to, radioBuffer.header.from, radioBuffer.header.flags);
|
||||
rxBad++;
|
||||
|
||||
airTime->logAirtime(RX_ALL_LOG, xmitMsec);
|
||||
|
@ -529,8 +529,9 @@ meshtastic_Routing_Error perhapsEncode(meshtastic_MeshPacket *p)
|
||||
#endif
|
||||
// Don't use PKC with Ham mode
|
||||
!owner.is_licensed &&
|
||||
// Don't use PKC if it's not explicitly requested and a non-primary channel is requested
|
||||
!(p->pki_encrypted != true && p->channel > 0) &&
|
||||
// Don't use PKC on 'serial' or 'gpio' channels unless explicitly requested
|
||||
!(p->pki_encrypted != true && (strcasecmp(channels.getName(chIndex), Channels::serialChannel) == 0 ||
|
||||
strcasecmp(channels.getName(chIndex), Channels::gpioChannel) == 0)) &&
|
||||
// Check for valid keys and single node destination
|
||||
config.security.private_key.size == 32 && !isBroadcast(p->to) && node != nullptr &&
|
||||
// Check for a known public key for the destination
|
||||
|
@ -505,7 +505,9 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
|
||||
if (mp.decoded.want_response && !myReply) {
|
||||
myReply = allocErrorResponse(meshtastic_Routing_Error_NONE, &mp);
|
||||
}
|
||||
|
||||
if (mp.pki_encrypted) {
|
||||
myReply->pki_encrypted = true;
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
@ -718,6 +720,13 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c)
|
||||
requiresReboot = false;
|
||||
}
|
||||
|
||||
#if defined(ARCH_PORTDUINO)
|
||||
// If running on portduino and using SimRadio, do not require reboot
|
||||
if (SimRadio::instance) {
|
||||
requiresReboot = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef RF95_FAN_EN
|
||||
// Turn PA off if disabled by config
|
||||
if (c.payload_variant.lora.pa_fan_disabled) {
|
||||
@ -934,6 +943,9 @@ void AdminModule::handleGetOwner(const meshtastic_MeshPacket &req)
|
||||
res.which_payload_variant = meshtastic_AdminMessage_get_owner_response_tag;
|
||||
setPassKey(&res);
|
||||
myReply = allocDataProtobuf(res);
|
||||
if (req.pki_encrypted) {
|
||||
myReply->pki_encrypted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1005,6 +1017,9 @@ void AdminModule::handleGetConfig(const meshtastic_MeshPacket &req, const uint32
|
||||
res.which_payload_variant = meshtastic_AdminMessage_get_config_response_tag;
|
||||
setPassKey(&res);
|
||||
myReply = allocDataProtobuf(res);
|
||||
if (req.pki_encrypted) {
|
||||
myReply->pki_encrypted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1092,6 +1107,9 @@ void AdminModule::handleGetModuleConfig(const meshtastic_MeshPacket &req, const
|
||||
res.which_payload_variant = meshtastic_AdminMessage_get_module_config_response_tag;
|
||||
setPassKey(&res);
|
||||
myReply = allocDataProtobuf(res);
|
||||
if (req.pki_encrypted) {
|
||||
myReply->pki_encrypted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1116,6 +1134,9 @@ void AdminModule::handleGetNodeRemoteHardwarePins(const meshtastic_MeshPacket &r
|
||||
}
|
||||
setPassKey(&r);
|
||||
myReply = allocDataProtobuf(r);
|
||||
if (req.pki_encrypted) {
|
||||
myReply->pki_encrypted = true;
|
||||
}
|
||||
}
|
||||
|
||||
void AdminModule::handleGetDeviceMetadata(const meshtastic_MeshPacket &req)
|
||||
@ -1125,6 +1146,9 @@ void AdminModule::handleGetDeviceMetadata(const meshtastic_MeshPacket &req)
|
||||
r.which_payload_variant = meshtastic_AdminMessage_get_device_metadata_response_tag;
|
||||
setPassKey(&r);
|
||||
myReply = allocDataProtobuf(r);
|
||||
if (req.pki_encrypted) {
|
||||
myReply->pki_encrypted = true;
|
||||
}
|
||||
}
|
||||
|
||||
void AdminModule::handleGetDeviceConnectionStatus(const meshtastic_MeshPacket &req)
|
||||
@ -1193,6 +1217,9 @@ void AdminModule::handleGetDeviceConnectionStatus(const meshtastic_MeshPacket &r
|
||||
r.which_payload_variant = meshtastic_AdminMessage_get_device_connection_status_response_tag;
|
||||
setPassKey(&r);
|
||||
myReply = allocDataProtobuf(r);
|
||||
if (req.pki_encrypted) {
|
||||
myReply->pki_encrypted = true;
|
||||
}
|
||||
}
|
||||
|
||||
void AdminModule::handleGetChannel(const meshtastic_MeshPacket &req, uint32_t channelIndex)
|
||||
@ -1204,6 +1231,9 @@ void AdminModule::handleGetChannel(const meshtastic_MeshPacket &req, uint32_t ch
|
||||
r.which_payload_variant = meshtastic_AdminMessage_get_channel_response_tag;
|
||||
setPassKey(&r);
|
||||
myReply = allocDataProtobuf(r);
|
||||
if (req.pki_encrypted) {
|
||||
myReply->pki_encrypted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1213,6 +1243,9 @@ void AdminModule::handleGetDeviceUIConfig(const meshtastic_MeshPacket &req)
|
||||
r.which_payload_variant = meshtastic_AdminMessage_get_ui_config_response_tag;
|
||||
r.get_ui_config_response = uiconfig;
|
||||
myReply = allocDataProtobuf(r);
|
||||
if (req.pki_encrypted) {
|
||||
myReply->pki_encrypted = true;
|
||||
}
|
||||
}
|
||||
|
||||
void AdminModule::reboot(int32_t seconds)
|
||||
|
@ -45,6 +45,9 @@
|
||||
#ifndef HAS_CUSTOM_CRYPTO_ENGINE
|
||||
#define HAS_CUSTOM_CRYPTO_ENGINE 1
|
||||
#endif
|
||||
#ifndef HAS_32768HZ
|
||||
#define HAS_32768HZ 0
|
||||
#endif
|
||||
|
||||
#if defined(HAS_AXP192) || defined(HAS_AXP2101)
|
||||
#define HAS_PMU
|
||||
@ -215,3 +218,13 @@
|
||||
#endif
|
||||
|
||||
#define SERIAL0_RX_GPIO 3 // Always GPIO3 on ESP32 // FIXME: may be different on ESP32-S3, etc.
|
||||
|
||||
// Setup flag, which indicates if our device supports power management
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
#define HAS_ESP32_PM_SUPPORT 1
|
||||
#endif
|
||||
|
||||
// Setup flag, which indicates if our device supports dynamic light sleep
|
||||
#if defined(HAS_ESP32_PM_SUPPORT) && defined(CONFIG_FREERTOS_USE_TICKLESS_IDLE)
|
||||
#define HAS_ESP32_DYNAMIC_LIGHT_SLEEP 1
|
||||
#endif
|
@ -64,7 +64,7 @@ void getMacAddr(uint8_t *dmac)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAS_32768HZ
|
||||
#if HAS_32768HZ
|
||||
#define CALIBRATE_ONE(cali_clk) calibrate_one(cali_clk, #cali_clk)
|
||||
|
||||
static uint32_t calibrate_one(rtc_cal_sel_t cal_clk, const char *name)
|
||||
@ -86,17 +86,17 @@ void enableSlowCLK()
|
||||
uint32_t cal_32k = CALIBRATE_ONE(RTC_CAL_32K_XTAL);
|
||||
|
||||
if (cal_32k == 0) {
|
||||
LOG_DEBUG("32K XTAL OSC has not started up");
|
||||
LOG_DEBUG("32k XTAL OSC has not started up");
|
||||
} else {
|
||||
rtc_clk_slow_freq_set(RTC_SLOW_FREQ_32K_XTAL);
|
||||
LOG_DEBUG("Switch RTC Source to 32.768Khz succeeded, using 32K XTAL");
|
||||
LOG_DEBUG("Switch RTC Source to 32.768kHz succeeded, using 32k XTAL");
|
||||
CALIBRATE_ONE(RTC_CAL_RTC_MUX);
|
||||
CALIBRATE_ONE(RTC_CAL_32K_XTAL);
|
||||
}
|
||||
CALIBRATE_ONE(RTC_CAL_RTC_MUX);
|
||||
CALIBRATE_ONE(RTC_CAL_32K_XTAL);
|
||||
if (rtc_clk_slow_freq_get() != RTC_SLOW_FREQ_32K_XTAL) {
|
||||
LOG_WARN("Failed to switch 32K XTAL RTC source to 32.768Khz !!! ");
|
||||
LOG_WARN("Failed to switch 32K XTAL RTC source to 32.768kHz !!! ");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -182,7 +182,7 @@ void esp32Setup()
|
||||
res = esp_task_wdt_add(NULL);
|
||||
assert(res == ESP_OK);
|
||||
|
||||
#ifdef HAS_32768HZ
|
||||
#if HAS_32768HZ
|
||||
enableSlowCLK();
|
||||
#endif
|
||||
}
|
||||
|
@ -1,42 +1,105 @@
|
||||
#include "../test_helpers.h"
|
||||
#include <memory>
|
||||
|
||||
// Helper function to test common packet fields and structure
|
||||
void verify_text_message_packet_structure(const std::string &json, const char *expected_text)
|
||||
{
|
||||
TEST_ASSERT_TRUE(json.length() > 0);
|
||||
|
||||
// Use smart pointer for automatic memory management
|
||||
std::unique_ptr<JSONValue> root(JSON::Parse(json.c_str()));
|
||||
TEST_ASSERT_NOT_NULL(root.get());
|
||||
TEST_ASSERT_TRUE(root->IsObject());
|
||||
|
||||
JSONObject jsonObj = root->AsObject();
|
||||
|
||||
// Check basic packet fields - use helper function to reduce duplication
|
||||
auto check_field = [&](const char *field, uint32_t expected_value) {
|
||||
auto it = jsonObj.find(field);
|
||||
TEST_ASSERT_TRUE(it != jsonObj.end());
|
||||
TEST_ASSERT_EQUAL(expected_value, (uint32_t)it->second->AsNumber());
|
||||
};
|
||||
|
||||
check_field("from", 0x11223344);
|
||||
check_field("to", 0x55667788);
|
||||
check_field("id", 0x9999);
|
||||
|
||||
// Check message type
|
||||
auto type_it = jsonObj.find("type");
|
||||
TEST_ASSERT_TRUE(type_it != jsonObj.end());
|
||||
TEST_ASSERT_EQUAL_STRING("text", type_it->second->AsString().c_str());
|
||||
|
||||
// Check payload
|
||||
auto payload_it = jsonObj.find("payload");
|
||||
TEST_ASSERT_TRUE(payload_it != jsonObj.end());
|
||||
TEST_ASSERT_TRUE(payload_it->second->IsObject());
|
||||
|
||||
JSONObject payload = payload_it->second->AsObject();
|
||||
auto text_it = payload.find("text");
|
||||
TEST_ASSERT_TRUE(text_it != payload.end());
|
||||
TEST_ASSERT_EQUAL_STRING(expected_text, text_it->second->AsString().c_str());
|
||||
|
||||
// No need for manual delete with smart pointer
|
||||
}
|
||||
|
||||
// Test TEXT_MESSAGE_APP port
|
||||
void test_text_message_serialization()
|
||||
{
|
||||
const char *test_text = "Hello Meshtastic!";
|
||||
meshtastic_MeshPacket packet =
|
||||
create_test_packet(meshtastic_PortNum_TEXT_MESSAGE_APP, (const uint8_t *)test_text, strlen(test_text));
|
||||
create_test_packet(meshtastic_PortNum_TEXT_MESSAGE_APP, reinterpret_cast<const uint8_t *>(test_text), strlen(test_text));
|
||||
|
||||
std::string json = MeshPacketSerializer::JsonSerialize(&packet, false);
|
||||
TEST_ASSERT_TRUE(json.length() > 0);
|
||||
|
||||
JSONValue *root = JSON::Parse(json.c_str());
|
||||
TEST_ASSERT_NOT_NULL(root);
|
||||
TEST_ASSERT_TRUE(root->IsObject());
|
||||
|
||||
JSONObject jsonObj = root->AsObject();
|
||||
|
||||
// Check basic packet fields
|
||||
TEST_ASSERT_TRUE(jsonObj.find("from") != jsonObj.end());
|
||||
TEST_ASSERT_EQUAL(0x11223344, (uint32_t)jsonObj["from"]->AsNumber());
|
||||
|
||||
TEST_ASSERT_TRUE(jsonObj.find("to") != jsonObj.end());
|
||||
TEST_ASSERT_EQUAL(0x55667788, (uint32_t)jsonObj["to"]->AsNumber());
|
||||
|
||||
TEST_ASSERT_TRUE(jsonObj.find("id") != jsonObj.end());
|
||||
TEST_ASSERT_EQUAL(0x9999, (uint32_t)jsonObj["id"]->AsNumber());
|
||||
|
||||
// Check message type
|
||||
TEST_ASSERT_TRUE(jsonObj.find("type") != jsonObj.end());
|
||||
TEST_ASSERT_EQUAL_STRING("text", jsonObj["type"]->AsString().c_str());
|
||||
|
||||
// Check payload
|
||||
TEST_ASSERT_TRUE(jsonObj.find("payload") != jsonObj.end());
|
||||
TEST_ASSERT_TRUE(jsonObj["payload"]->IsObject());
|
||||
|
||||
JSONObject payload = jsonObj["payload"]->AsObject();
|
||||
TEST_ASSERT_TRUE(payload.find("text") != payload.end());
|
||||
TEST_ASSERT_EQUAL_STRING("Hello Meshtastic!", payload["text"]->AsString().c_str());
|
||||
|
||||
delete root;
|
||||
verify_text_message_packet_structure(json, test_text);
|
||||
}
|
||||
|
||||
// Test with nullptr to check robustness
|
||||
void test_text_message_serialization_null()
|
||||
{
|
||||
meshtastic_MeshPacket packet = create_test_packet(meshtastic_PortNum_TEXT_MESSAGE_APP, nullptr, 0);
|
||||
|
||||
std::string json = MeshPacketSerializer::JsonSerialize(&packet, false);
|
||||
verify_text_message_packet_structure(json, "");
|
||||
}
|
||||
|
||||
// Test TEXT_MESSAGE_APP port with very long message (boundary testing)
|
||||
void test_text_message_serialization_long_text()
|
||||
{
|
||||
// Test with actual message size limits
|
||||
constexpr size_t MAX_MESSAGE_SIZE = 200; // Typical LoRa payload limit
|
||||
std::string long_text(MAX_MESSAGE_SIZE, 'A');
|
||||
|
||||
meshtastic_MeshPacket packet = create_test_packet(meshtastic_PortNum_TEXT_MESSAGE_APP,
|
||||
reinterpret_cast<const uint8_t *>(long_text.c_str()), long_text.length());
|
||||
|
||||
std::string json = MeshPacketSerializer::JsonSerialize(&packet, false);
|
||||
verify_text_message_packet_structure(json, long_text.c_str());
|
||||
}
|
||||
|
||||
// Test with message over size limit (should fail)
|
||||
void test_text_message_serialization_oversized()
|
||||
{
|
||||
constexpr size_t OVERSIZED_MESSAGE = 250; // Over the limit
|
||||
std::string oversized_text(OVERSIZED_MESSAGE, 'B');
|
||||
|
||||
meshtastic_MeshPacket packet = create_test_packet(
|
||||
meshtastic_PortNum_TEXT_MESSAGE_APP, reinterpret_cast<const uint8_t *>(oversized_text.c_str()), oversized_text.length());
|
||||
|
||||
// Should fail or return empty/error
|
||||
std::string json = MeshPacketSerializer::JsonSerialize(&packet, false);
|
||||
// Should only verify first 234 characters for oversized messages
|
||||
std::string expected_text = oversized_text.substr(0, 234);
|
||||
verify_text_message_packet_structure(json, expected_text.c_str());
|
||||
}
|
||||
|
||||
// Add test for malformed UTF-8 sequences
|
||||
void test_text_message_serialization_invalid_utf8()
|
||||
{
|
||||
const uint8_t invalid_utf8[] = {0xFF, 0xFE, 0xFD, 0x00}; // Invalid UTF-8
|
||||
meshtastic_MeshPacket packet =
|
||||
create_test_packet(meshtastic_PortNum_TEXT_MESSAGE_APP, invalid_utf8, sizeof(invalid_utf8) - 1);
|
||||
|
||||
// Should not crash, may produce replacement characters
|
||||
std::string json = MeshPacketSerializer::JsonSerialize(&packet, false);
|
||||
TEST_ASSERT_TRUE(json.length() > 0);
|
||||
}
|
||||
|
@ -4,6 +4,10 @@
|
||||
|
||||
// Forward declarations for test functions
|
||||
void test_text_message_serialization();
|
||||
void test_text_message_serialization_null();
|
||||
void test_text_message_serialization_long_text();
|
||||
void test_text_message_serialization_oversized();
|
||||
void test_text_message_serialization_invalid_utf8();
|
||||
void test_position_serialization();
|
||||
void test_nodeinfo_serialization();
|
||||
void test_waypoint_serialization();
|
||||
@ -21,6 +25,10 @@ void setup()
|
||||
|
||||
// Text message tests
|
||||
RUN_TEST(test_text_message_serialization);
|
||||
RUN_TEST(test_text_message_serialization_null);
|
||||
RUN_TEST(test_text_message_serialization_long_text);
|
||||
RUN_TEST(test_text_message_serialization_oversized);
|
||||
RUN_TEST(test_text_message_serialization_invalid_utf8);
|
||||
|
||||
// Position tests
|
||||
RUN_TEST(test_position_serialization);
|
||||
|
@ -40,3 +40,5 @@
|
||||
|
||||
#define SX126X_DIO2_AS_RF_SWITCH
|
||||
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
|
||||
|
||||
#define HAS_32768HZ 1
|
@ -92,3 +92,12 @@
|
||||
#define SX126X_DIO3_TCXO_VOLTAGE 2.4
|
||||
// Internally the TTGO module hooks the SX1262-DIO2 in to control the TX/RX switch (which is the default for the sx1262interface
|
||||
// code)
|
||||
|
||||
#define MODEM_POWER_EN 41
|
||||
#define MODEM_PWRKEY 40
|
||||
#define MODEM_RST 9
|
||||
#define MODEM_RI 7
|
||||
#define MODEM_DTR 8
|
||||
#define MODEM_RX 10
|
||||
#define MODEM_TX 11
|
||||
|
||||
|
@ -62,6 +62,6 @@
|
||||
// #define PCF8563_RTC 0x51 //Putting definitions in variant. h does not compile correctly
|
||||
|
||||
// has 32768 Hz crystal
|
||||
#define HAS_32768HZ
|
||||
#define HAS_32768HZ 1
|
||||
|
||||
#define USE_SH1106
|
||||
#define USE_SH1106
|
||||
|
Loading…
Reference in New Issue
Block a user