diff --git a/.github/actions/setup-base/action.yml b/.github/actions/setup-base/action.yml
index 7f8659523..61466655d 100644
--- a/.github/actions/setup-base/action.yml
+++ b/.github/actions/setup-base/action.yml
@@ -11,7 +11,7 @@ runs:
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- - name: Install dependencies
+ - name: Install dependencies
shell: bash
run: |
sudo apt-get -y update --fix-missing
@@ -22,19 +22,20 @@ runs:
with:
python-version: 3.x
- - name: Cache python libs
- uses: actions/cache@v4
- id: cache-pip # needed in if test
- with:
- path: ~/.cache/pip
- key: ${{ runner.os }}-pip
+ # - name: Cache python libs
+ # uses: actions/cache@v4
+ # id: cache-pip # needed in if test
+ # with:
+ # path: ~/.cache/pip
+ # key: ${{ runner.os }}-pip
- name: Upgrade python tools
shell: bash
run: |
python -m pip install --upgrade pip
- pip install -U platformio adafruit-nrfutil
- pip install -U meshtastic --pre
+ pip install -U --no-build-isolation --no-cache-dir "setuptools<72"
+ pip install -U platformio adafruit-nrfutil --no-build-isolation
+ pip install -U meshtastic --pre --no-build-isolation
- name: Upgrade platformio
shell: bash
diff --git a/bin/config-dist.yaml b/bin/config-dist.yaml
index 333d6eadc..0ec5a440b 100644
--- a/bin/config-dist.yaml
+++ b/bin/config-dist.yaml
@@ -135,10 +135,11 @@ Input:
Logging:
LogLevel: info # debug, info, warn, error
+# TraceFile: /var/log/meshtasticd.json
Webserver:
# Port: 443 # Port for Webserver & Webservices
# RootPath: /usr/share/doc/meshtasticd/web # Root Dir of WebServer
General:
- MaxNodes: 200
+ MaxNodes: 200
\ No newline at end of file
diff --git a/src/RedirectablePrint.cpp b/src/RedirectablePrint.cpp
index 9c3dcdc98..05d349de9 100644
--- a/src/RedirectablePrint.cpp
+++ b/src/RedirectablePrint.cpp
@@ -49,7 +49,11 @@ size_t RedirectablePrint::write(uint8_t c)
size_t RedirectablePrint::vprintf(const char *logLevel, const char *format, va_list arg)
{
va_list copy;
+#if ENABLE_JSON_LOGGING || ARCH_PORTDUINO
+ static char printBuf[512];
+#else
static char printBuf[160];
+#endif
va_copy(copy, arg);
size_t len = vsnprintf(printBuf, sizeof(printBuf), format, copy);
@@ -98,6 +102,8 @@ void RedirectablePrint::log_to_serial(const char *logLevel, const char *format,
Print::write("\u001b[33m", 6);
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_ERROR) == 0)
Print::write("\u001b[31m", 6);
+ if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_TRACE) == 0)
+ Print::write("\u001b[35m", 6);
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice, true); // display local time on logfile
if (rtc_sec > 0) {
long hms = rtc_sec % SEC_PER_DAY;
@@ -244,7 +250,21 @@ meshtastic_LogRecord_Level RedirectablePrint::getLogLevel(const char *logLevel)
void RedirectablePrint::log(const char *logLevel, const char *format, ...)
{
-#ifdef ARCH_PORTDUINO
+#if ARCH_PORTDUINO
+ // level trace is special, two possible ways to handle it.
+ if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_TRACE) == 0) {
+ if (settingsStrings[traceFilename] != "") {
+ va_list arg;
+ va_start(arg, format);
+ try {
+ traceFile << va_arg(arg, char *) << std::endl;
+ } catch (const std::ios_base::failure &e) {
+ }
+ va_end(arg);
+ }
+ if (settingsMap[logoutputlevel] < level_trace && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_TRACE) == 0)
+ return;
+ }
if (settingsMap[logoutputlevel] < level_debug && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_DEBUG) == 0)
return;
else if (settingsMap[logoutputlevel] < level_info && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_INFO) == 0)
diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp
index b2059b71c..54fd1ea4d 100644
--- a/src/graphics/Screen.cpp
+++ b/src/graphics/Screen.cpp
@@ -20,6 +20,7 @@ along with this program. If not, see .
*/
#include "Screen.h"
+#include "../userPrefs.h"
#include "configuration.h"
#if HAS_SCREEN
#include
@@ -156,7 +157,11 @@ static void drawIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDispl
display->setFont(FONT_MEDIUM);
display->setTextAlignment(TEXT_ALIGN_LEFT);
+#ifdef SPLASH_TITLE_USERPREFS
+ const char *title = SPLASH_TITLE_USERPREFS;
+#else
const char *title = "meshtastic.org";
+#endif
display->drawString(x + getStringCenteredX(title), y + SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM, title);
display->setFont(FONT_SMALL);
diff --git a/src/graphics/img/icon.xbm b/src/graphics/img/icon.xbm
index 297f31ed6..f90cf4946 100644
--- a/src/graphics/img/icon.xbm
+++ b/src/graphics/img/icon.xbm
@@ -1,3 +1,4 @@
+#ifndef HAS_USERPREFS_SPLASH
#define icon_width 50
#define icon_height 28
static uint8_t icon_bits[] = {
@@ -17,4 +18,5 @@ static uint8_t icon_bits[] = {
0xFE, 0x00, 0x00, 0xFC, 0x01, 0x7E, 0x00, 0x7F, 0x00, 0x00, 0xF8, 0x01,
0x7E, 0x00, 0x3E, 0x00, 0x00, 0xF8, 0x01, 0x38, 0x00, 0x3C, 0x00, 0x00,
0x70, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, };
\ No newline at end of file
+ 0x00, 0x00, 0x00, 0x00, };
+#endif
\ No newline at end of file
diff --git a/src/mesh/Channels.cpp b/src/mesh/Channels.cpp
index bb4d629e7..1a23c7861 100644
--- a/src/mesh/Channels.cpp
+++ b/src/mesh/Channels.cpp
@@ -1,4 +1,5 @@
#include "Channels.h"
+#include "../userPrefs.h"
#include "CryptoEngine.h"
#include "DisplayFormatters.h"
#include "NodeDB.h"
@@ -90,6 +91,7 @@ void Channels::initDefaultChannel(ChannelIndex chIndex)
loraConfig.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST; // Default to Long Range & Fast
loraConfig.use_preset = true;
loraConfig.tx_power = 0; // default
+ loraConfig.channel_num = 0;
uint8_t defaultpskIndex = 1;
channelSettings.psk.bytes[0] = defaultpskIndex;
channelSettings.psk.size = 1;
@@ -99,6 +101,29 @@ void Channels::initDefaultChannel(ChannelIndex chIndex)
ch.has_settings = true;
ch.role = meshtastic_Channel_Role_PRIMARY;
+
+#ifdef LORACONFIG_MODEM_PRESET_USERPREFS
+ loraConfig.modem_preset = LORACONFIG_MODEM_PRESET_USERPREFS;
+#endif
+#ifdef LORACONFIG_CHANNEL_NUM_USERPREFS
+ loraConfig.channel_num = LORACONFIG_CHANNEL_NUM_USERPREFS;
+#endif
+
+ // Install custom defaults. Will eventually support setting multiple default channels
+ if (chIndex == 0) {
+#ifdef CHANNEL_0_PSK_USERPREFS
+ static const uint8_t defaultpsk[] = CHANNEL_0_PSK_USERPREFS;
+ memcpy(channelSettings.psk.bytes, defaultpsk, sizeof(defaultpsk));
+ channelSettings.psk.size = sizeof(defaultpsk);
+
+#endif
+#ifdef CHANNEL_0_NAME_USERPREFS
+ strcpy(channelSettings.name, CHANNEL_0_NAME_USERPREFS);
+#endif
+#ifdef CHANNEL_0_PRECISION_USERPREFS
+ channelSettings.module_settings.position_precision = CHANNEL_0_PRECISION_USERPREFS;
+#endif
+ }
}
CryptoKey Channels::getKey(ChannelIndex chIndex)
@@ -330,4 +355,4 @@ bool Channels::decryptForHash(ChannelIndex chIndex, ChannelHash channelHash)
int16_t Channels::setActiveByIndex(ChannelIndex channelIndex)
{
return setCrypto(channelIndex);
-}
+}
\ No newline at end of file
diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp
index 4257837b3..b4b5ec286 100644
--- a/src/mesh/NodeDB.cpp
+++ b/src/mesh/NodeDB.cpp
@@ -1,3 +1,4 @@
+#include "../userPrefs.h"
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_GPS
#include "GPS.h"
@@ -237,10 +238,22 @@ void NodeDB::installDefaultConfig()
config.lora.tx_enabled =
true; // FIXME: maybe false in the future, and setting region to enable it. (unset region forces it off)
config.lora.override_duty_cycle = false;
+#ifdef CONFIG_LORA_REGION_USERPREFS
+ config.lora.region = CONFIG_LORA_REGION_USERPREFS;
+#else
config.lora.region = meshtastic_Config_LoRaConfig_RegionCode_UNSET;
+#endif
+#ifdef LORACONFIG_MODEM_PRESET_USERPREFS
+ config.lora.modem_preset = LORACONFIG_MODEM_PRESET_USERPREFS;
+#else
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST;
+#endif
config.lora.hop_limit = HOP_RELIABLE;
+#ifdef CONFIG_LORA_IGNORE_MQTT_USERPREFS
+ config.lora.ignore_mqtt = CONFIG_LORA_IGNORE_MQTT_USERPREFS;
+#else
config.lora.ignore_mqtt = false;
+#endif
#ifdef PIN_GPS_EN
config.position.gps_en_gpio = PIN_GPS_EN;
#endif
diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp
index 35536e714..c1801d419 100644
--- a/src/mesh/Router.cpp
+++ b/src/mesh/Router.cpp
@@ -11,6 +11,12 @@
#if !MESHTASTIC_EXCLUDE_MQTT
#include "mqtt/MQTT.h"
#endif
+#if ARCH_PORTDUINO
+#include "platform/portduino/PortduinoGlue.h"
+#endif
+#if ENABLE_JSON_LOGGING || ARCH_PORTDUINO
+#include "serialization/MeshPacketSerializer.h"
+#endif
/**
* Router todo
*
@@ -356,6 +362,13 @@ bool perhapsDecode(meshtastic_MeshPacket *p)
} */
printPacket("decoded message", p);
+#if ENABLE_JSON_LOGGING
+ LOG_TRACE("%s\n", MeshPacketSerializer::JsonSerialize(p, false).c_str());
+#elif ARCH_PORTDUINO
+ if (settingsStrings[traceFilename] != "" || settingsMap[logoutputlevel] == level_trace) {
+ LOG_TRACE("%s\n", MeshPacketSerializer::JsonSerialize(p, false).c_str());
+ }
+#endif
return true;
}
}
@@ -491,6 +504,17 @@ void Router::handleReceived(meshtastic_MeshPacket *p, RxSource src)
void Router::perhapsHandleReceived(meshtastic_MeshPacket *p)
{
+#if ENABLE_JSON_LOGGING
+ // Even ignored packets get logged in the trace
+ p->rx_time = getValidTime(RTCQualityFromNet); // store the arrival timestamp for the phone
+ LOG_TRACE("%s\n", MeshPacketSerializer::JsonSerializeEncrypted(p).c_str());
+#elif ARCH_PORTDUINO
+ // Even ignored packets get logged in the trace
+ if (settingsStrings[traceFilename] != "" || settingsMap[logoutputlevel] == level_trace) {
+ p->rx_time = getValidTime(RTCQualityFromNet); // store the arrival timestamp for the phone
+ LOG_TRACE("%s\n", MeshPacketSerializer::JsonSerializeEncrypted(p).c_str());
+ }
+#endif
// assert(radioConfig.has_preferences);
bool ignore = is_in_repeated(config.lora.ignore_incoming, p->from) || (config.lora.ignore_mqtt && p->via_mqtt);
diff --git a/src/platform/portduino/PortduinoGlue.cpp b/src/platform/portduino/PortduinoGlue.cpp
index 89ac806dd..b910206ec 100644
--- a/src/platform/portduino/PortduinoGlue.cpp
+++ b/src/platform/portduino/PortduinoGlue.cpp
@@ -17,6 +17,7 @@
std::map settingsMap;
std::map settingsStrings;
+std::ofstream traceFile;
char *configPath = nullptr;
// FIXME - move setBluetoothEnable into a HALPlatform class
@@ -134,7 +135,9 @@ void portduinoSetup()
try {
if (yamlConfig["Logging"]) {
- if (yamlConfig["Logging"]["LogLevel"].as("info") == "debug") {
+ if (yamlConfig["Logging"]["LogLevel"].as("info") == "trace") {
+ settingsMap[logoutputlevel] = level_trace;
+ } else if (yamlConfig["Logging"]["LogLevel"].as("info") == "debug") {
settingsMap[logoutputlevel] = level_debug;
} else if (yamlConfig["Logging"]["LogLevel"].as("info") == "info") {
settingsMap[logoutputlevel] = level_info;
@@ -143,6 +146,7 @@ void portduinoSetup()
} else if (yamlConfig["Logging"]["LogLevel"].as("info") == "error") {
settingsMap[logoutputlevel] = level_error;
}
+ settingsStrings[traceFilename] = yamlConfig["Logging"]["TraceFile"].as("");
}
if (yamlConfig["Lora"]) {
settingsMap[use_sx1262] = false;
@@ -346,6 +350,14 @@ void portduinoSetup()
if (settingsStrings[spidev] != "") {
SPI.begin(settingsStrings[spidev].c_str());
}
+ if (settingsStrings[traceFilename] != "") {
+ try {
+ traceFile.open(settingsStrings[traceFilename], std::ios::out | std::ios::app);
+ } catch (std::ofstream::failure &e) {
+ std::cout << "*** traceFile Exception " << e.what() << std::endl;
+ exit(EXIT_FAILURE);
+ }
+ }
return;
}
diff --git a/src/platform/portduino/PortduinoGlue.h b/src/platform/portduino/PortduinoGlue.h
index ca935ea3b..6b9a8eb8e 100644
--- a/src/platform/portduino/PortduinoGlue.h
+++ b/src/platform/portduino/PortduinoGlue.h
@@ -1,4 +1,5 @@
#pragma once
+#include
#include