diff --git a/.clusterfuzzlite/Dockerfile b/.clusterfuzzlite/Dockerfile
index a769a976d..54b5cda0f 100644
--- a/.clusterfuzzlite/Dockerfile
+++ b/.clusterfuzzlite/Dockerfile
@@ -20,7 +20,7 @@ ENV PIP_ROOT_USER_ACTION=ignore
RUN apt-get update && apt-get install --no-install-recommends -y \
cmake git zip libgpiod-dev libbluetooth-dev libi2c-dev \
libunistring-dev libmicrohttpd-dev libgnutls28-dev libgcrypt20-dev \
- libusb-1.0-0-dev libssl-dev pkg-config && \
+ libusb-1.0-0-dev libssl-dev pkg-config libsqlite3-dev && \
apt-get clean && rm -rf /var/lib/apt/lists/* && \
pip install --no-cache-dir -U \
platformio==6.1.16 \
diff --git a/Dockerfile b/Dockerfile
index 111dd69fc..91d3f7796 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -14,7 +14,7 @@ RUN apt-get update && apt-get install --no-install-recommends -y \
curl wget g++ zip git ca-certificates pkg-config \
libgpiod-dev libyaml-cpp-dev libbluetooth-dev libi2c-dev libuv1-dev \
libusb-1.0-0-dev libulfius-dev liborcania-dev libssl-dev \
- libx11-dev libinput-dev libxkbcommon-x11-dev \
+ libx11-dev libinput-dev libxkbcommon-x11-dev libsqlite3-dev \
&& apt-get clean && rm -rf /var/lib/apt/lists/* \
&& pip install --no-cache-dir -U platformio \
&& mkdir /tmp/firmware
diff --git a/alpine.Dockerfile b/alpine.Dockerfile
index b3b384101..64c281788 100644
--- a/alpine.Dockerfile
+++ b/alpine.Dockerfile
@@ -11,7 +11,7 @@ RUN apk --no-cache add \
bash g++ libstdc++-dev linux-headers zip git ca-certificates libbsd-dev \
libgpiod-dev yaml-cpp-dev bluez-dev \
libusb-dev i2c-tools-dev libuv-dev openssl-dev pkgconf argp-standalone \
- libx11-dev libinput-dev libxkbcommon-dev \
+ libx11-dev libinput-dev libxkbcommon-dev sqlite-dev \
&& rm -rf /var/cache/apk/* \
&& pip install --no-cache-dir -U platformio \
&& mkdir /tmp/firmware
diff --git a/debian/control b/debian/control
index 679a444c9..46c932a80 100644
--- a/debian/control
+++ b/debian/control
@@ -25,7 +25,8 @@ Build-Depends: debhelper-compat (= 13),
liborcania-dev,
libx11-dev,
libinput-dev,
- libxkbcommon-x11-dev
+ libxkbcommon-x11-dev,
+ libsqlite3-dev
Standards-Version: 4.6.2
Homepage: https://github.com/meshtastic/firmware
Rules-Requires-Root: no
diff --git a/meshtasticd.spec.rpkg b/meshtasticd.spec.rpkg
index 0819d5f8d..fc14ede7f 100644
--- a/meshtasticd.spec.rpkg
+++ b/meshtasticd.spec.rpkg
@@ -39,6 +39,7 @@ BuildRequires: pkgconfig(bluez)
BuildRequires: pkgconfig(libusb-1.0)
BuildRequires: libi2c-devel
BuildRequires: pkgconfig(libuv)
+BuildRequires: pkgconfig(sqlite3)
# Web components:
BuildRequires: pkgconfig(openssl)
BuildRequires: pkgconfig(liborcania)
diff --git a/src/configuration.h b/src/configuration.h
index eb258651c..59bffe7be 100644
--- a/src/configuration.h
+++ b/src/configuration.h
@@ -445,18 +445,6 @@ along with this program. If not, see .
#endif
#endif
-// BME680 BSEC2 support detection
-#if !defined(MESHTASTIC_BME680_BSEC2_SUPPORTED)
-#if defined(RAK_4631) || defined(TBEAM_V10)
-
-#define MESHTASTIC_BME680_BSEC2_SUPPORTED 1
-#define MESHTASTIC_BME680_HEADER
-#else
-#define MESHTASTIC_BME680_BSEC2_SUPPORTED 0
-#define MESHTASTIC_BME680_HEADER
-#endif // defined(RAK_4631)
-#endif // !defined(MESHTASTIC_BME680_BSEC2_SUPPORTED)
-
// -----------------------------------------------------------------------------
// Global switches to turn off features for a minimized build
// -----------------------------------------------------------------------------
diff --git a/src/graphics/draw/DebugRenderer.cpp b/src/graphics/draw/DebugRenderer.cpp
index 75b65c65f..2dca38d66 100644
--- a/src/graphics/draw/DebugRenderer.cpp
+++ b/src/graphics/draw/DebugRenderer.cpp
@@ -438,7 +438,7 @@ void drawLoRaFocused(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x,
if (currentResolution == ScreenResolution::UltraLow) {
snprintf(frequencyslot, sizeof(frequencyslot), "%sMHz (%d)", freqStr, config.lora.channel_num);
} else {
- snprintf(frequencyslot, sizeof(frequencyslot), "Freq/Ch: %sMHz (%d)", freqStr, config.lora.channel_num);
+ snprintf(frequencyslot, sizeof(frequencyslot), "Freq: %sMHz (%d)", freqStr, config.lora.channel_num);
}
}
size_t len = strlen(frequencyslot);
diff --git a/src/graphics/draw/MenuHandler.cpp b/src/graphics/draw/MenuHandler.cpp
index 5c459d984..c5a4106e7 100644
--- a/src/graphics/draw/MenuHandler.cpp
+++ b/src/graphics/draw/MenuHandler.cpp
@@ -65,12 +65,12 @@ uint8_t test_count = 0;
void menuHandler::loraMenu()
{
- static const char *optionsArray[] = {"Back", "Device Role", "Radio Preset", "LoRa Region"};
- enum optionsNumbers { Back = 0, device_role_picker = 1, radio_preset_picker = 2, lora_picker = 3 };
+ static const char *optionsArray[] = {"Back", "Device Role", "Radio Preset", "Frequency Slot", "LoRa Region"};
+ enum optionsNumbers { Back = 0, device_role_picker = 1, radio_preset_picker = 2, frequency_slot = 3, lora_picker = 4 };
BannerOverlayOptions bannerOptions;
bannerOptions.message = "LoRa Actions";
bannerOptions.optionsArrayPtr = optionsArray;
- bannerOptions.optionsCount = 4;
+ bannerOptions.optionsCount = 5;
bannerOptions.bannerCallback = [](int selected) -> void {
if (selected == Back) {
// No action
@@ -78,6 +78,8 @@ void menuHandler::loraMenu()
menuHandler::menuQueue = menuHandler::device_role_picker;
} else if (selected == radio_preset_picker) {
menuHandler::menuQueue = menuHandler::radio_preset_picker;
+ } else if (selected == frequency_slot) {
+ menuHandler::menuQueue = menuHandler::frequency_slot;
} else if (selected == lora_picker) {
menuHandler::menuQueue = menuHandler::lora_picker;
}
@@ -248,6 +250,113 @@ void menuHandler::DeviceRolePicker()
screen->showOverlayBanner(bannerOptions);
}
+void menuHandler::FrequencySlotPicker()
+{
+
+ enum ReplyOptions : int { Back = -1 };
+ constexpr int MAX_CHANNEL_OPTIONS = 202;
+ static const char *optionsArray[MAX_CHANNEL_OPTIONS];
+ static int optionsEnumArray[MAX_CHANNEL_OPTIONS];
+ static char channelText[MAX_CHANNEL_OPTIONS - 1][12];
+ int options = 0;
+ optionsArray[options] = "Back";
+ optionsEnumArray[options++] = Back;
+ optionsArray[options] = "Slot 0 (Auto)";
+ optionsEnumArray[options++] = 0;
+
+ // Calculate number of channels (copied from RadioInterface::applyModemConfig())
+ meshtastic_Config_LoRaConfig &loraConfig = config.lora;
+ double bw = loraConfig.bandwidth;
+ if (loraConfig.use_preset) {
+ switch (loraConfig.modem_preset) {
+ case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO:
+ bw = (myRegion->wideLora) ? 1625.0 : 500;
+ break;
+ case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST:
+ bw = (myRegion->wideLora) ? 812.5 : 250;
+ break;
+ case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW:
+ bw = (myRegion->wideLora) ? 812.5 : 250;
+ break;
+ case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST:
+ bw = (myRegion->wideLora) ? 812.5 : 250;
+ break;
+ case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW:
+ bw = (myRegion->wideLora) ? 812.5 : 250;
+ break;
+ case meshtastic_Config_LoRaConfig_ModemPreset_LONG_TURBO:
+ bw = (myRegion->wideLora) ? 1625.0 : 500;
+ break;
+ default:
+ bw = (myRegion->wideLora) ? 812.5 : 250;
+ break;
+ case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE:
+ bw = (myRegion->wideLora) ? 406.25 : 125;
+ break;
+ case meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW:
+ bw = (myRegion->wideLora) ? 406.25 : 125;
+ break;
+ }
+ } else {
+ bw = loraConfig.bandwidth;
+ if (bw == 31) // This parameter is not an integer
+ bw = 31.25;
+ if (bw == 62) // Fix for 62.5Khz bandwidth
+ bw = 62.5;
+ if (bw == 200)
+ bw = 203.125;
+ if (bw == 400)
+ bw = 406.25;
+ if (bw == 800)
+ bw = 812.5;
+ if (bw == 1600)
+ bw = 1625.0;
+ }
+
+ uint32_t numChannels = 0;
+ if (myRegion) {
+ numChannels = (uint32_t)floor((myRegion->freqEnd - myRegion->freqStart) / (myRegion->spacing + (bw / 1000.0)));
+ } else {
+ LOG_WARN("Region not set, cannot calculate number of channels");
+ return;
+ }
+
+ if (numChannels > (uint32_t)(MAX_CHANNEL_OPTIONS - 2))
+ numChannels = (uint32_t)(MAX_CHANNEL_OPTIONS - 2);
+
+ for (uint32_t ch = 1; ch <= numChannels; ch++) {
+ snprintf(channelText[ch - 1], sizeof(channelText[ch - 1]), "Slot %lu", (unsigned long)ch);
+ optionsArray[options] = channelText[ch - 1];
+ optionsEnumArray[options++] = (int)ch;
+ }
+
+ BannerOverlayOptions bannerOptions;
+ bannerOptions.message = "Frequency Slot";
+ bannerOptions.optionsArrayPtr = optionsArray;
+ bannerOptions.optionsEnumPtr = optionsEnumArray;
+ bannerOptions.optionsCount = options;
+
+ // Start highlight on current channel if possible, otherwise on "1"
+ int initial = (int)config.lora.channel_num + 1;
+ if (initial < 2 || initial > (int)numChannels + 1)
+ initial = 1;
+ bannerOptions.InitialSelected = initial;
+
+ bannerOptions.bannerCallback = [](int selected) -> void {
+ if (selected == Back) {
+ menuHandler::menuQueue = menuHandler::lora_Menu;
+ screen->runNow();
+ return;
+ }
+
+ config.lora.channel_num = selected;
+ service->reloadConfig(SEGMENT_CONFIG);
+ rebootAtMsec = (millis() + DEFAULT_REBOOT_SECONDS * 1000);
+ };
+
+ screen->showOverlayBanner(bannerOptions);
+}
+
void menuHandler::RadioPresetPicker()
{
static const RadioPresetOption presetOptions[] = {
@@ -278,6 +387,8 @@ void menuHandler::RadioPresetPicker()
}
config.lora.modem_preset = option.value;
+ config.lora.channel_num = 0; // Reset to default channel for the preset
+ config.lora.override_frequency = 0; // Clear any custom frequency
service->reloadConfig(SEGMENT_CONFIG);
rebootAtMsec = (millis() + DEFAULT_REBOOT_SECONDS * 1000);
});
@@ -2551,6 +2662,9 @@ void menuHandler::handleMenuSwitch(OLEDDisplay *display)
case radio_preset_picker:
RadioPresetPicker();
break;
+ case frequency_slot:
+ FrequencySlotPicker();
+ break;
case no_timeout_lora_picker:
LoraRegionPicker(0);
break;
diff --git a/src/graphics/draw/MenuHandler.h b/src/graphics/draw/MenuHandler.h
index 121b6dfc9..45fd0bf5f 100644
--- a/src/graphics/draw/MenuHandler.h
+++ b/src/graphics/draw/MenuHandler.h
@@ -13,6 +13,7 @@ class menuHandler
lora_picker,
device_role_picker,
radio_preset_picker,
+ frequency_slot,
no_timeout_lora_picker,
TZ_picker,
twelve_hour_picker,
@@ -63,6 +64,7 @@ class menuHandler
static void loraMenu();
static void DeviceRolePicker();
static void RadioPresetPicker();
+ static void FrequencySlotPicker();
static void handleMenuSwitch(OLEDDisplay *display);
static void showConfirmationBanner(const char *message, std::function onConfirm);
static void clockMenu();
diff --git a/src/mesh/http/ContentHandler.cpp b/src/mesh/http/ContentHandler.cpp
index 7b7ebb595..ea8d6af8e 100644
--- a/src/mesh/http/ContentHandler.cpp
+++ b/src/mesh/http/ContentHandler.cpp
@@ -173,7 +173,7 @@ void handleAPIv1FromRadio(HTTPRequest *req, HTTPResponse *res)
if (req->getMethod() == "OPTIONS") {
res->setStatusCode(204); // Success with no content
- // res->print(""); @todo remove
+ res->print("");
return;
}
@@ -223,7 +223,7 @@ void handleAPIv1ToRadio(HTTPRequest *req, HTTPResponse *res)
if (req->getMethod() == "OPTIONS") {
res->setStatusCode(204); // Success with no content
- // res->print(""); @todo remove
+ res->print("");
return;
}
diff --git a/src/modules/ExternalNotificationModule.cpp b/src/modules/ExternalNotificationModule.cpp
index 04fcd8e73..8b7ce700a 100644
--- a/src/modules/ExternalNotificationModule.cpp
+++ b/src/modules/ExternalNotificationModule.cpp
@@ -460,12 +460,15 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
}
meshtastic_NodeInfoLite *sender = nodeDB->getMeshNode(mp.from);
- bool mutedNode = false;
- if (sender) {
- mutedNode = (sender->bitfield & NODEINFO_BITFIELD_IS_MUTED_MASK);
- }
meshtastic_Channel ch = channels.getByIndex(mp.channel ? mp.channel : channels.getPrimaryIndex());
+ // If we receive a broadcast message, apply channel mute setting
+ // If we receive a direct message and the receipent is us, apply DM mute setting
+ // Else we just handle it as not muted.
+ const bool directToUs = !isBroadcast(mp.to) && isToUs(&mp);
+ bool is_muted = directToUs ? (sender && ((sender->bitfield & NODEINFO_BITFIELD_IS_MUTED_MASK) != 0))
+ : (ch.settings.has_module_settings && ch.settings.module_settings.is_muted);
+
if (moduleConfig.external_notification.alert_bell) {
if (containsBell) {
LOG_INFO("externalNotificationModule - Notification Bell");
@@ -516,8 +519,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
}
}
- if (moduleConfig.external_notification.alert_message && !mutedNode &&
- (!ch.settings.has_module_settings || !ch.settings.module_settings.is_muted)) {
+ if (moduleConfig.external_notification.alert_message && !is_muted) {
LOG_INFO("externalNotificationModule - Notification Module");
isNagging = true;
setExternalState(0, true);
@@ -528,8 +530,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
}
}
- if (moduleConfig.external_notification.alert_message_vibra && !mutedNode &&
- (!ch.settings.has_module_settings || !ch.settings.module_settings.is_muted)) {
+ if (moduleConfig.external_notification.alert_message_vibra && !is_muted) {
LOG_INFO("externalNotificationModule - Notification Module (Vibra)");
isNagging = true;
setExternalState(1, true);
@@ -540,8 +541,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
}
}
- if (moduleConfig.external_notification.alert_message_buzzer && !mutedNode &&
- (!ch.settings.has_module_settings || !ch.settings.module_settings.is_muted)) {
+ if (moduleConfig.external_notification.alert_message_buzzer && !is_muted) {
LOG_INFO("externalNotificationModule - Notification Module (Buzzer)");
if (config.device.buzzer_mode != meshtastic_Config_DeviceConfig_BuzzerMode_DIRECT_MSG_ONLY ||
(!isBroadcast(mp.to) && isToUs(&mp))) {
diff --git a/src/modules/Telemetry/EnvironmentTelemetry.cpp b/src/modules/Telemetry/EnvironmentTelemetry.cpp
index ec6fe4799..86a8606c2 100644
--- a/src/modules/Telemetry/EnvironmentTelemetry.cpp
+++ b/src/modules/Telemetry/EnvironmentTelemetry.cpp
@@ -53,7 +53,7 @@ extern void drawCommonHeader(OLEDDisplay *display, int16_t x, int16_t y, const c
#include "Sensor/LTR390UVSensor.h"
#endif
-#if __has_include(MESHTASTIC_BME680_HEADER)
+#if __has_include() || __has_include()
#include "Sensor/BME680Sensor.h"
#endif
@@ -187,7 +187,7 @@ void EnvironmentTelemetryModule::i2cScanFinished(ScanI2C *i2cScanner)
#if __has_include()
addSensor(i2cScanner, ScanI2C::DeviceType::LTR390UV);
#endif
-#if __has_include(MESHTASTIC_BME680_HEADER)
+#if __has_include() || __has_include()
addSensor(i2cScanner, ScanI2C::DeviceType::BME_680);
#endif
#if __has_include()
diff --git a/src/modules/Telemetry/Sensor/BME680Sensor.cpp b/src/modules/Telemetry/Sensor/BME680Sensor.cpp
index 22330ca75..3a1eb9532 100644
--- a/src/modules/Telemetry/Sensor/BME680Sensor.cpp
+++ b/src/modules/Telemetry/Sensor/BME680Sensor.cpp
@@ -1,6 +1,6 @@
#include "configuration.h"
-#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && __has_include(MESHTASTIC_BME680_HEADER)
+#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && (__has_include() || __has_include())
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "BME680Sensor.h"
@@ -10,7 +10,7 @@
BME680Sensor::BME680Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_BME680, "BME680") {}
-#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
+#if __has_include()
int32_t BME680Sensor::runOnce()
{
if (!bme680.run()) {
@@ -18,13 +18,13 @@ int32_t BME680Sensor::runOnce()
}
return 35;
}
-#endif // defined(MESHTASTIC_BME680_BSEC2_SUPPORTED)
+#endif
bool BME680Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
{
status = 0;
-#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
+#if __has_include()
if (!bme680.begin(dev->address.address, *bus))
checkStatus("begin");
@@ -56,7 +56,7 @@ bool BME680Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
status = 1;
-#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED
+#endif
initI2CSensor();
return status;
@@ -64,7 +64,7 @@ bool BME680Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
bool BME680Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
-#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
+#if __has_include()
if (bme680.getData(BSEC_OUTPUT_RAW_PRESSURE).signal == 0)
return false;
@@ -98,11 +98,11 @@ bool BME680Sensor::getMetrics(meshtastic_Telemetry *measurement)
measurement->variant.environment_metrics.barometric_pressure = bme680->readPressure() / 100.0F;
measurement->variant.environment_metrics.gas_resistance = bme680->readGas() / 1000.0;
-#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED
+#endif
return true;
}
-#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
+#if __has_include()
void BME680Sensor::loadState()
{
#ifdef FSCom
@@ -179,6 +179,6 @@ void BME680Sensor::checkStatus(const char *functionName)
else if (bme680.sensor.status > BME68X_OK)
LOG_WARN("%s BME68X code: %d", functionName, bme680.sensor.status);
}
-#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED
+#endif
#endif
diff --git a/src/modules/Telemetry/Sensor/BME680Sensor.h b/src/modules/Telemetry/Sensor/BME680Sensor.h
index 9bef56e1e..eaeceb848 100644
--- a/src/modules/Telemetry/Sensor/BME680Sensor.h
+++ b/src/modules/Telemetry/Sensor/BME680Sensor.h
@@ -1,29 +1,29 @@
#include "configuration.h"
-#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && __has_include(MESHTASTIC_BME680_HEADER)
+#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && (__has_include() || __has_include())
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
-#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
+#if __has_include()
#include
#include
#else
#include
#include
-#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED
+#endif
#define STATE_SAVE_PERIOD UINT32_C(360 * 60 * 1000) // That's 6 hours worth of millis()
-#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
+#if __has_include()
const uint8_t bsec_config[] = {
#include "config/bme680/bme680_iaq_33v_3s_4d/bsec_iaq.txt"
};
-#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED
+#endif
class BME680Sensor : public TelemetrySensor
{
private:
-#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
+#if __has_include()
Bsec2 bme680;
#else
using BME680Ptr = std::unique_ptr;
@@ -31,10 +31,10 @@ class BME680Sensor : public TelemetrySensor
static BME680Ptr makeBME680(TwoWire *bus) { return std::make_unique(bus); }
BME680Ptr bme680;
-#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED
+#endif
protected:
-#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
+#if __has_include()
const char *bsecConfigFileName = "/prefs/bsec.dat";
uint8_t bsecState[BSEC_MAX_STATE_BLOB_SIZE] = {0};
uint8_t accuracy = 0;
@@ -51,13 +51,13 @@ class BME680Sensor : public TelemetrySensor
void loadState();
void updateState();
void checkStatus(const char *functionName);
-#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED
+#endif
public:
BME680Sensor();
-#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
+#if __has_include()
virtual int32_t runOnce() override;
-#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED
+#endif
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
};
diff --git a/src/platform/portduino/PortduinoGlue.cpp b/src/platform/portduino/PortduinoGlue.cpp
index 7430c2eae..ec9bbedca 100644
--- a/src/platform/portduino/PortduinoGlue.cpp
+++ b/src/platform/portduino/PortduinoGlue.cpp
@@ -55,6 +55,7 @@ void cpuDeepSleep(uint32_t msecs)
void updateBatteryLevel(uint8_t level) NOT_IMPLEMENTED("updateBatteryLevel");
int TCPPort = SERVER_API_DEFAULT_PORT;
+bool checkConfigPort = true;
static error_t parse_opt(int key, char *arg, struct argp_state *state)
{
@@ -63,6 +64,7 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state)
if (sscanf(arg, "%d", &TCPPort) < 1)
return ARGP_ERR_UNKNOWN;
else
+ checkConfigPort = false;
printf("Using config file %d\n", TCPPort);
break;
case 'c':
@@ -870,6 +872,14 @@ bool loadConfig(const char *configPath)
std::cout << "Cannot set both MACAddress and MACAddressSource!" << std::endl;
exit(EXIT_FAILURE);
}
+ if (checkConfigPort) {
+ portduino_config.api_port = (yamlConfig["General"]["APIPort"]).as(-1);
+ if (portduino_config.api_port != -1 &&
+ portduino_config.api_port > 1023 &&
+ portduino_config.api_port < 65536) {
+ TCPPort = (portduino_config.api_port);
+ }
+ }
portduino_config.mac_address = (yamlConfig["General"]["MACAddress"]).as("");
if (portduino_config.mac_address != "") {
portduino_config.mac_address_explicit = true;
diff --git a/src/platform/portduino/PortduinoGlue.h b/src/platform/portduino/PortduinoGlue.h
index 8992f5f1a..3a6887421 100644
--- a/src/platform/portduino/PortduinoGlue.h
+++ b/src/platform/portduino/PortduinoGlue.h
@@ -175,6 +175,7 @@ extern struct portduino_config_struct {
std::string mac_address = "";
bool mac_address_explicit = false;
std::string mac_address_source = "";
+ int api_port = -1;
std::string config_directory = "";
std::string available_directory = "/etc/meshtasticd/available.d/";
int maxtophone = 100;
@@ -508,6 +509,8 @@ extern struct portduino_config_struct {
out << YAML::Key << "General" << YAML::Value << YAML::BeginMap;
if (config_directory != "")
out << YAML::Key << "ConfigDirectory" << YAML::Value << config_directory;
+ if (api_port != -1)
+ out << YAML::Key << "TCPPort" << YAML::Value << api_port;
if (mac_address_explicit)
out << YAML::Key << "MACAddress" << YAML::Value << mac_address;
if (mac_address_source != "")
@@ -519,4 +522,4 @@ extern struct portduino_config_struct {
out << YAML::EndMap; // General
return out.c_str();
}
-} portduino_config;
\ No newline at end of file
+} portduino_config;