From 30a31a3a13caec27fa1d09e119e97fdb2881b8a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 28 Jan 2025 15:38:22 +0100 Subject: [PATCH 1/6] Oem logo (#5939) * reinstate oemlogo, add to userPrefs.jsonc * disable from default build --- src/graphics/Screen.cpp | 76 ++++++++++++++++++++++++++++++++++++++--- userPrefs.jsonc | 10 ++++-- 2 files changed, 78 insertions(+), 8 deletions(-) diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 198dcc235..c9004432f 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -123,7 +123,7 @@ static bool heartbeat = false; #define getStringCenteredX(s) ((SCREEN_WIDTH - display->getStringWidth(s)) / 2) -/// Check if the display can render a string (detect special chars; emoji) +// Check if the display can render a string (detect special chars; emoji) static bool haveGlyphs(const char *str) { #if defined(OLED_PL) || defined(OLED_UA) || defined(OLED_RU) || defined(OLED_CS) @@ -162,11 +162,7 @@ static void drawIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDispl display->setFont(FONT_MEDIUM); display->setTextAlignment(TEXT_ALIGN_LEFT); -#ifdef USERPREFS_SPLASH_TITLE - const char *title = USERPREFS_SPLASH_TITLE; -#else const char *title = "meshtastic.org"; -#endif display->drawString(x + getStringCenteredX(title), y + SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM, title); display->setFont(FONT_SMALL); @@ -185,6 +181,56 @@ static void drawIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDispl display->setTextAlignment(TEXT_ALIGN_LEFT); // Restore left align, just to be kind to any other unsuspecting code } +#ifdef USERPREFS_OEM_TEXT + +static void drawOEMIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) +{ + static const uint8_t xbm[] = USERPREFS_OEM_IMAGE_DATA; + display->drawXbm(x + (SCREEN_WIDTH - USERPREFS_OEM_IMAGE_WIDTH) / 2, + y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - USERPREFS_OEM_IMAGE_HEIGHT) / 2 + 2, USERPREFS_OEM_IMAGE_WIDTH, + USERPREFS_OEM_IMAGE_HEIGHT, xbm); + + switch (USERPREFS_OEM_FONT_SIZE) { + case 0: + display->setFont(FONT_SMALL); + break; + case 2: + display->setFont(FONT_LARGE); + break; + default: + display->setFont(FONT_MEDIUM); + break; + } + + display->setTextAlignment(TEXT_ALIGN_LEFT); + const char *title = USERPREFS_OEM_TEXT; + display->drawString(x + getStringCenteredX(title), y + SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM, title); + display->setFont(FONT_SMALL); + + // Draw region in upper left + if (upperMsg) + display->drawString(x + 0, y + 0, upperMsg); + + // Draw version and shortname in upper right + char buf[25]; + snprintf(buf, sizeof(buf), "%s\n%s", xstr(APP_VERSION_SHORT), haveGlyphs(owner.short_name) ? owner.short_name : ""); + + display->setTextAlignment(TEXT_ALIGN_RIGHT); + display->drawString(x + SCREEN_WIDTH, y + 0, buf); + screen->forceDisplay(); + + display->setTextAlignment(TEXT_ALIGN_LEFT); // Restore left align, just to be kind to any other unsuspecting code +} + +static void drawOEMBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) +{ + // Draw region in upper left + const char *region = myRegion ? myRegion->name : NULL; + drawOEMIconScreen(region, display, state, x, y); +} + +#endif + void Screen::drawFrameText(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y, const char *message) { uint16_t x_offset = display->width() / 2; @@ -1658,6 +1704,10 @@ void Screen::setup() // Set the utf8 conversion function dispdev->setFontTableLookupFunction(customFontTableLookup); +#ifdef USERPREFS_OEM_TEXT + logo_timeout *= 2; // Double the time if we have a custom logo +#endif + // Add frames. EINK_ADD_FRAMEFLAG(dispdev, DEMAND_FAST); alertFrames[0] = [this](OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -> void { @@ -1803,6 +1853,22 @@ int32_t Screen::runOnce() showingBootScreen = false; } +#ifdef USERPREFS_OEM_TEXT + static bool showingOEMBootScreen = true; + if (showingOEMBootScreen && (millis() > ((logo_timeout / 2) + serialSinceMsec))) { + LOG_INFO("Switch to OEM screen..."); + // Change frames. + static FrameCallback bootOEMFrames[] = {drawOEMBootScreen}; + static const int bootOEMFrameCount = sizeof(bootOEMFrames) / sizeof(bootOEMFrames[0]); + ui->setFrames(bootOEMFrames, bootOEMFrameCount); + ui->update(); +#ifndef USE_EINK + ui->update(); +#endif + showingOEMBootScreen = false; + } +#endif + #ifndef DISABLE_WELCOME_UNSET if (showingNormalScreen && config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_UNSET) { setWelcomeFrames(); diff --git a/userPrefs.jsonc b/userPrefs.jsonc index 055f59273..de610464d 100644 --- a/userPrefs.jsonc +++ b/userPrefs.jsonc @@ -29,9 +29,13 @@ // "USERPREFS_FIXED_GPS_LON": "2.294508368", // "USERPREFS_LORACONFIG_CHANNEL_NUM": "31", // "USERPREFS_LORACONFIG_MODEM_PRESET": "meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST", - // "USERPREFS_SPLASH_TITLE": "DEFCONtastic", "USERPREFS_TZ_STRING": "tzplaceholder " // "USERPREFS_USE_ADMIN_KEY_0": "{ 0xcd, 0xc0, 0xb4, 0x3c, 0x53, 0x24, 0xdf, 0x13, 0xca, 0x5a, 0xa6, 0x0c, 0x0d, 0xec, 0x85, 0x5a, 0x4c, 0xf6, 0x1a, 0x96, 0x04, 0x1a, 0x3e, 0xfc, 0xbb, 0x8e, 0x33, 0x71, 0xe5, 0xfc, 0xff, 0x3c }", // "USERPREFS_USE_ADMIN_KEY_1": "{}", - // "USERPREFS_USE_ADMIN_KEY_2": "{}" -} \ No newline at end of file + // "USERPREFS_USE_ADMIN_KEY_2": "{}", + // "USERPREFS_OEM_TEXT": "Caterham Car Club", + // "USERPREFS_OEM_FONT_SIZE": "0", + // "USERPREFS_OEM_IMAGE_WIDTH": "50", + // "USERPREFS_OEM_IMAGE_HEIGHT": "28", + // "USERPREFS_OEM_IMAGE_DATA": "{ 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x80, 0x0F, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x18, 0xFF, 0xFF, 0x61, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0xFF, 0xC7, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0xFF, 0xC7, 0x00, 0x00, 0x00, 0x18, 0xFF, 0xFF, 0x67, 0x00, 0x00, 0x00, 0x18, 0x1F, 0xF0, 0x67, 0x00, 0x00, 0x00, 0x30, 0x1F, 0xF8, 0x33, 0x00, 0x00, 0x00, 0x30, 0x00, 0xFC, 0x31, 0x00, 0x00, 0x00, 0x60, 0x00, 0xFE, 0x18, 0x00, 0x00, 0x00, 0x60, 0x00, 0x7E, 0x18, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x3F, 0x0C, 0x00, 0x00, 0x00, 0xC0, 0x80, 0x1F, 0x0C, 0x00, 0x00, 0x00, 0x80, 0x81, 0x1F, 0x06, 0x00, 0x00, 0x00, 0x80, 0xC1, 0x0F, 0x06, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x0F, 0x03, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x0F, 0x03, 0x00, 0x00, 0x00, 0x00, 0xE6, 0x8F, 0x01, 0x00, 0x00, 0x00, 0x00, 0xEE, 0xC7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00}" +} From 6a12760c3d07805b5af614820af8732751be6037 Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Wed, 29 Jan 2025 09:57:52 +0800 Subject: [PATCH 2/6] Fix off-by-one error with log writes (#5959) As reported by @jstockdale, when writing coloured logs we were writing the full string, including a null terminator. This caused issues for programs consuming our logs. The fix as identified is not to write the null. Fixes https://github.com/meshtastic/firmware/issues/5945 --- src/RedirectablePrint.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/RedirectablePrint.cpp b/src/RedirectablePrint.cpp index 57f53019d..07f873864 100644 --- a/src/RedirectablePrint.cpp +++ b/src/RedirectablePrint.cpp @@ -79,17 +79,17 @@ size_t RedirectablePrint::vprintf(const char *logLevel, const char *format, va_l } if (color && logLevel != nullptr) { if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_DEBUG) == 0) - Print::write("\u001b[34m", 6); + Print::write("\u001b[34m", 5); if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_INFO) == 0) - Print::write("\u001b[32m", 6); + Print::write("\u001b[32m", 5); if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_WARN) == 0) - Print::write("\u001b[33m", 6); + Print::write("\u001b[33m", 5); if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_ERROR) == 0) - Print::write("\u001b[31m", 6); + Print::write("\u001b[31m", 5); } len = Print::write(printBuf, len); if (color && logLevel != nullptr) { - Print::write("\u001b[0m", 5); + Print::write("\u001b[0m", 4); } return len; } @@ -107,15 +107,15 @@ void RedirectablePrint::log_to_serial(const char *logLevel, const char *format, // include the header if (color) { if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_DEBUG) == 0) - Print::write("\u001b[34m", 6); + Print::write("\u001b[34m", 5); if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_INFO) == 0) - Print::write("\u001b[32m", 6); + Print::write("\u001b[32m", 5); if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_WARN) == 0) - Print::write("\u001b[33m", 6); + Print::write("\u001b[33m", 5); if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_ERROR) == 0) - Print::write("\u001b[31m", 6); + Print::write("\u001b[31m", 5); if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_TRACE) == 0) - Print::write("\u001b[35m", 6); + Print::write("\u001b[35m", 5); } uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice, true); // display local time on logfile @@ -393,4 +393,4 @@ std::string RedirectablePrint::mt_sprintf(const std::string fmt_str, ...) break; } return std::string(formatted.get()); -} +} \ No newline at end of file From 78da8f6fc43591d9fbd5822fb2a885d9e8a93258 Mon Sep 17 00:00:00 2001 From: Austin Date: Wed, 29 Jan 2025 06:51:26 -0500 Subject: [PATCH 3/6] Portduino: Allow limiting TX Power from yaml (#5954) --- bin/config-dist.yaml | 4 +++- bin/config.d/lora-MeshAdv-900M30S.yaml | 3 +++ src/mesh/LR11x0Interface.cpp | 6 ++++++ src/mesh/RF95Interface.cpp | 5 ++++- src/mesh/SX126xInterface.cpp | 5 ++++- src/mesh/SX128xInterface.cpp | 5 ++++- src/platform/portduino/PortduinoGlue.cpp | 8 +++++++- src/platform/portduino/PortduinoGlue.h | 7 ++++++- 8 files changed, 37 insertions(+), 6 deletions(-) diff --git a/bin/config-dist.yaml b/bin/config-dist.yaml index c8f181308..1bf52fda2 100644 --- a/bin/config-dist.yaml +++ b/bin/config-dist.yaml @@ -78,6 +78,8 @@ Lora: # TXen: x # TX and RX enable pins # RXen: x +# SX126X_MAX_POWER: 8 # Limit the output power to 8 dBm, useful for amped nodes + # spiSpeed: 2000000 ### Set default/fallback gpio chip to use in /dev/. Defaults to 0. @@ -188,4 +190,4 @@ General: MaxMessageQueue: 100 ConfigDirectory: /etc/meshtasticd/config.d/ # MACAddress: AA:BB:CC:DD:EE:FF -# MACAddressSource: eth0 +# MACAddressSource: eth0 \ No newline at end of file diff --git a/bin/config.d/lora-MeshAdv-900M30S.yaml b/bin/config.d/lora-MeshAdv-900M30S.yaml index 07dada620..113901d5e 100644 --- a/bin/config.d/lora-MeshAdv-900M30S.yaml +++ b/bin/config.d/lora-MeshAdv-900M30S.yaml @@ -7,3 +7,6 @@ Lora: TXen: 13 RXen: 12 DIO3_TCXO_VOLTAGE: true + # Only for E22-900M33S: + # Limit the output power to 8 dBm + # SX126X_MAX_POWER: 8 \ No newline at end of file diff --git a/src/mesh/LR11x0Interface.cpp b/src/mesh/LR11x0Interface.cpp index ce4f912ba..5a9a53d2d 100644 --- a/src/mesh/LR11x0Interface.cpp +++ b/src/mesh/LR11x0Interface.cpp @@ -20,12 +20,18 @@ static const Module::RfSwitchMode_t rfswitch_table[] = { // Particular boards might define a different max power based on what their hardware can do, default to max power output if not // specified (may be dangerous if using external PA and LR11x0 power config forgotten) +#if ARCH_PORTDUINO +#define LR1110_MAX_POWER settingsMap[lr1110_max_power] +#endif #ifndef LR1110_MAX_POWER #define LR1110_MAX_POWER 22 #endif // the 2.4G part maxes at 13dBm +#if ARCH_PORTDUINO +#define LR1120_MAX_POWER settingsMap[lr1120_max_power] +#endif #ifndef LR1120_MAX_POWER #define LR1120_MAX_POWER 13 #endif diff --git a/src/mesh/RF95Interface.cpp b/src/mesh/RF95Interface.cpp index d4d9ad23c..1dfc72708 100644 --- a/src/mesh/RF95Interface.cpp +++ b/src/mesh/RF95Interface.cpp @@ -9,6 +9,9 @@ #include "PortduinoGlue.h" #endif +#if ARCH_PORTDUINO +#define RF95_MAX_POWER settingsMap[rf95_max_power] +#endif #ifndef RF95_MAX_POWER #define RF95_MAX_POWER 20 #endif @@ -337,4 +340,4 @@ bool RF95Interface::sleep() return true; } -#endif +#endif \ No newline at end of file diff --git a/src/mesh/SX126xInterface.cpp b/src/mesh/SX126xInterface.cpp index 5710de7ea..7c950bc8e 100644 --- a/src/mesh/SX126xInterface.cpp +++ b/src/mesh/SX126xInterface.cpp @@ -11,6 +11,9 @@ // Particular boards might define a different max power based on what their hardware can do, default to max power output if not // specified (may be dangerous if using external PA and SX126x power config forgotten) +#if ARCH_PORTDUINO +#define SX126X_MAX_POWER settingsMap[sx126x_max_power] +#endif #ifndef SX126X_MAX_POWER #define SX126X_MAX_POWER 22 #endif @@ -333,4 +336,4 @@ template bool SX126xInterface::sleep() return true; } -#endif +#endif \ No newline at end of file diff --git a/src/mesh/SX128xInterface.cpp b/src/mesh/SX128xInterface.cpp index ee3408456..1032934b8 100644 --- a/src/mesh/SX128xInterface.cpp +++ b/src/mesh/SX128xInterface.cpp @@ -10,6 +10,9 @@ #endif // Particular boards might define a different max power based on what their hardware can do +#if ARCH_PORTDUINO +#define SX128X_MAX_POWER settingsMap[sx128x_max_power] +#endif #ifndef SX128X_MAX_POWER #define SX128X_MAX_POWER 13 #endif @@ -315,4 +318,4 @@ template bool SX128xInterface::sleep() return true; } -#endif +#endif \ No newline at end of file diff --git a/src/platform/portduino/PortduinoGlue.cpp b/src/platform/portduino/PortduinoGlue.cpp index ab78baa1a..d7ff4fc65 100644 --- a/src/platform/portduino/PortduinoGlue.cpp +++ b/src/platform/portduino/PortduinoGlue.cpp @@ -369,6 +369,12 @@ bool loadConfig(const char *configPath) } } + settingsMap[sx126x_max_power] = yamlConfig["Lora"]["SX126X_MAX_POWER"].as(22); + settingsMap[sx128x_max_power] = yamlConfig["Lora"]["SX128X_MAX_POWER"].as(13); + settingsMap[lr1110_max_power] = yamlConfig["Lora"]["LR1110_MAX_POWER"].as(22); + settingsMap[lr1120_max_power] = yamlConfig["Lora"]["LR1120_MAX_POWER"].as(13); + settingsMap[rf95_max_power] = yamlConfig["Lora"]["RF95_MAX_POWER"].as(20); + settingsMap[dio2_as_rf_switch] = yamlConfig["Lora"]["DIO2_AS_RF_SWITCH"].as(false); settingsMap[dio3_tcxo_voltage] = yamlConfig["Lora"]["DIO3_TCXO_VOLTAGE"].as(0) * 1000; if (settingsMap[dio3_tcxo_voltage] == 0 && yamlConfig["Lora"]["DIO3_TCXO_VOLTAGE"].as(false)) { @@ -569,4 +575,4 @@ bool MAC_from_string(std::string mac_str, uint8_t *dmac) } else { return false; } -} +} \ No newline at end of file diff --git a/src/platform/portduino/PortduinoGlue.h b/src/platform/portduino/PortduinoGlue.h index d1e91956d..c6b5f8b41 100644 --- a/src/platform/portduino/PortduinoGlue.h +++ b/src/platform/portduino/PortduinoGlue.h @@ -27,6 +27,11 @@ enum configNames { sx126x_ant_sw_pin, sx126x_ant_sw_line, sx126x_ant_sw_gpiochip, + sx126x_max_power, + sx128x_max_power, + lr1110_max_power, + lr1120_max_power, + rf95_max_power, dio2_as_rf_switch, dio3_tcxo_voltage, use_rf95, @@ -94,4 +99,4 @@ int initGPIOPin(int pinNum, std::string gpioChipname, int line); bool loadConfig(const char *configPath); static bool ends_with(std::string_view str, std::string_view suffix); void getMacAddr(uint8_t *dmac); -bool MAC_from_string(std::string mac_str, uint8_t *dmac); +bool MAC_from_string(std::string mac_str, uint8_t *dmac); \ No newline at end of file From cd8592ef4accb3e758e8bae80744eacc93df7015 Mon Sep 17 00:00:00 2001 From: Jason P Date: Wed, 29 Jan 2025 06:14:43 -0600 Subject: [PATCH 4/6] Fixes #5766 Updated MQTT privateCidrRanges to add Tailscale (#5957) --- src/mqtt/MQTT.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index f642af231..f808a66ef 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -217,6 +217,7 @@ bool isPrivateIpAddress(const IPAddress &ip) {.network = 169u << 24 | 254 << 16, .mask = 0xffff0000}, // 169.254.0.0/16 {.network = 10u << 24, .mask = 0xff000000}, // 10.0.0.0/8 {.network = 127u << 24 | 1, .mask = 0xffffffff}, // 127.0.0.1/32 + {.network = 100u << 24 | 64 << 16, .mask = 0xffc00000}, // 100.64.0.0/10 }; const uint32_t addr = ntohl(ip); for (const auto &cidrRange : privateCidrRanges) { From b5cad2b65e934efac1bbf1d92a6616c12e680a39 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Wed, 29 Jan 2025 20:52:24 -0600 Subject: [PATCH 5/6] Fix negative decimal value detection in userPrefs (#5963) --- bin/platformio-custom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/platformio-custom.py b/bin/platformio-custom.py index acfeae10c..09e8e6d83 100644 --- a/bin/platformio-custom.py +++ b/bin/platformio-custom.py @@ -102,7 +102,7 @@ pref_flags = [] for pref in userPrefs: if userPrefs[pref].startswith("{"): pref_flags.append("-D" + pref + "=" + userPrefs[pref]) - elif userPrefs[pref].replace(".", "").isdigit(): + elif userPrefs[pref].lstrip("-").replace(".", "").isdigit(): pref_flags.append("-D" + pref + "=" + userPrefs[pref]) elif userPrefs[pref] == "true" or userPrefs[pref] == "false": pref_flags.append("-D" + pref + "=" + userPrefs[pref]) From 4c0e0b84712e08371d84400187e42996bb5bc254 Mon Sep 17 00:00:00 2001 From: Austin Date: Sat, 1 Feb 2025 03:58:58 -0500 Subject: [PATCH 6/6] Portduino: Set Web SSL Cert / Key paths from yaml (#5961) --- Dockerfile | 3 ++- alpine.Dockerfile | 3 ++- bin/config-dist.yaml | 2 ++ debian/meshtasticd.dirs | 3 ++- meshtasticd.spec.rpkg | 3 +++ src/mesh/raspihttp/PiWebServer.cpp | 18 +++++++++++------- src/platform/portduino/PortduinoGlue.cpp | 7 ++++++- src/platform/portduino/PortduinoGlue.h | 2 ++ 8 files changed, 30 insertions(+), 11 deletions(-) diff --git a/Dockerfile b/Dockerfile index f3b294a5b..f9a3b9962 100644 --- a/Dockerfile +++ b/Dockerfile @@ -38,7 +38,8 @@ USER root RUN apt-get update && apt-get --no-install-recommends -y install libc-bin libc6 libgpiod2 libyaml-cpp0.7 libi2c0 libulfius2.7 libusb-1.0-0-dev liborcania2.3 libssl3 && \ apt-get clean && rm -rf /var/lib/apt/lists/* \ && mkdir -p /var/lib/meshtasticd \ - && mkdir -p /etc/meshtasticd/config.d + && mkdir -p /etc/meshtasticd/config.d \ + && mkdir -p /etc/meshtasticd/ssl # Fetch compiled binary from the builder COPY --from=builder /tmp/firmware/release/meshtasticd /usr/sbin/ diff --git a/alpine.Dockerfile b/alpine.Dockerfile index 115602b3b..8b48eeca3 100644 --- a/alpine.Dockerfile +++ b/alpine.Dockerfile @@ -29,7 +29,8 @@ USER root RUN apk add libstdc++ libgpiod yaml-cpp libusb i2c-tools \ && mkdir -p /var/lib/meshtasticd \ - && mkdir -p /etc/meshtasticd/config.d + && mkdir -p /etc/meshtasticd/config.d \ + && mkdir -p /etc/meshtasticd/ssl COPY --from=builder /tmp/firmware/release/meshtasticd /usr/sbin/ WORKDIR /var/lib/meshtasticd diff --git a/bin/config-dist.yaml b/bin/config-dist.yaml index 1bf52fda2..da4c192c7 100644 --- a/bin/config-dist.yaml +++ b/bin/config-dist.yaml @@ -184,6 +184,8 @@ Logging: Webserver: # Port: 443 # Port for Webserver & Webservices # RootPath: /usr/share/meshtasticd/web # Root Dir of WebServer +# SSLKey: /etc/meshtasticd/ssl/private_key.pem # Path to SSL Key, generated if not present +# SSLCert: /etc/meshtasticd/ssl/certificate.pem # Path to SSL Certificate, generated if not present General: MaxNodes: 200 diff --git a/debian/meshtasticd.dirs b/debian/meshtasticd.dirs index 5f57ff7be..45a1ca3db 100644 --- a/debian/meshtasticd.dirs +++ b/debian/meshtasticd.dirs @@ -1,4 +1,5 @@ etc/meshtasticd etc/meshtasticd/config.d etc/meshtasticd/available.d -usr/share/meshtasticd/web \ No newline at end of file +usr/share/meshtasticd/web +etc/meshtasticd/ssl \ No newline at end of file diff --git a/meshtasticd.spec.rpkg b/meshtasticd.spec.rpkg index 1819897b0..720e94408 100644 --- a/meshtasticd.spec.rpkg +++ b/meshtasticd.spec.rpkg @@ -72,6 +72,8 @@ install -D -m 0644 bin/meshtasticd.service %{buildroot}%{_unitdir}/meshtasticd.s # Install the web files under /usr/share/meshtasticd/web mkdir -p %{buildroot}%{_datadir}/meshtasticd/web cp -r web/* %{buildroot}%{_datadir}/meshtasticd/web +# Install default SSL storage directory (for web) +mkdir -p %{buildroot}%{_sysconfdir}/meshtasticd/ssl %files %license LICENSE @@ -86,6 +88,7 @@ cp -r web/* %{buildroot}%{_datadir}/meshtasticd/web %dir %{_datadir}/meshtasticd %dir %{_datadir}/meshtasticd/web %{_datadir}/meshtasticd/web/* +%dir %{_sysconfdir}/meshtasticd/ssl %changelog %autochangelog \ No newline at end of file diff --git a/src/mesh/raspihttp/PiWebServer.cpp b/src/mesh/raspihttp/PiWebServer.cpp index 9d2625410..4fae0bc3d 100644 --- a/src/mesh/raspihttp/PiWebServer.cpp +++ b/src/mesh/raspihttp/PiWebServer.cpp @@ -65,6 +65,9 @@ mail: marchammermann@googlemail.com #define DEFAULT_REALM "default_realm" #define PREFIX "" +#define KEY_PATH settingsStrings[websslkeypath].c_str() +#define CERT_PATH settingsStrings[websslcertpath].c_str() + struct _file_config configWeb; // We need to specify some content-type mapping, so the resources get delivered with the @@ -384,13 +387,13 @@ char *read_file_into_string(const char *filename) int PiWebServerThread::CheckSSLandLoad() { // read certificate - cert_pem = read_file_into_string("certificate.pem"); + cert_pem = read_file_into_string(CERT_PATH); if (cert_pem == NULL) { LOG_ERROR("ERROR SSL Certificate File can't be loaded or is missing"); return 1; } // read private key - key_pem = read_file_into_string("private_key.pem"); + key_pem = read_file_into_string(KEY_PATH); if (key_pem == NULL) { LOG_ERROR("ERROR file private_key can't be loaded or is missing"); return 2; @@ -415,8 +418,8 @@ int PiWebServerThread::CreateSSLCertificate() return 2; } - // Ope file to write private key file - FILE *pkey_file = fopen("private_key.pem", "wb"); + // Open file to write private key file + FILE *pkey_file = fopen(KEY_PATH, "wb"); if (!pkey_file) { LOG_ERROR("Error opening private key file"); return 3; @@ -426,18 +429,19 @@ int PiWebServerThread::CreateSSLCertificate() fclose(pkey_file); // open Certificate file - FILE *x509_file = fopen("certificate.pem", "wb"); + FILE *x509_file = fopen(CERT_PATH, "wb"); if (!x509_file) { LOG_ERROR("Error opening cert"); return 4; } - // write cirtificate + // write certificate PEM_write_X509(x509_file, x509); fclose(x509_file); EVP_PKEY_free(pkey); + LOG_INFO("Create SSL Key %s successful", KEY_PATH); X509_free(x509); - LOG_INFO("Create SSL Cert -certificate.pem- succesfull "); + LOG_INFO("Create SSL Cert %s successful", CERT_PATH); return 0; } diff --git a/src/platform/portduino/PortduinoGlue.cpp b/src/platform/portduino/PortduinoGlue.cpp index d7ff4fc65..9da65c92c 100644 --- a/src/platform/portduino/PortduinoGlue.cpp +++ b/src/platform/portduino/PortduinoGlue.cpp @@ -524,7 +524,12 @@ bool loadConfig(const char *configPath) if (yamlConfig["Webserver"]) { settingsMap[webserverport] = (yamlConfig["Webserver"]["Port"]).as(-1); - settingsStrings[webserverrootpath] = (yamlConfig["Webserver"]["RootPath"]).as(""); + settingsStrings[webserverrootpath] = + (yamlConfig["Webserver"]["RootPath"]).as("/usr/share/meshtasticd/web"); + settingsStrings[websslkeypath] = + (yamlConfig["Webserver"]["SSLKey"]).as("/etc/meshtasticd/ssl/private_key.pem"); + settingsStrings[websslcertpath] = + (yamlConfig["Webserver"]["SSLCert"]).as("/etc/meshtasticd/ssl/certificate.pem"); } if (yamlConfig["General"]) { diff --git a/src/platform/portduino/PortduinoGlue.h b/src/platform/portduino/PortduinoGlue.h index c6b5f8b41..a52ca88f8 100644 --- a/src/platform/portduino/PortduinoGlue.h +++ b/src/platform/portduino/PortduinoGlue.h @@ -81,6 +81,8 @@ enum configNames { webserver, webserverport, webserverrootpath, + websslkeypath, + websslcertpath, maxtophone, maxnodes, ascii_logs,