From eab1f75d0b2ace72045f75a5f1bda559e4fbb1d1 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sun, 27 Oct 2024 18:37:38 -0500 Subject: [PATCH 1/3] Add support for loading yaml from a config directory --- src/platform/portduino/PortduinoGlue.cpp | 257 ++++++++++++----------- src/platform/portduino/PortduinoGlue.h | 7 +- 2 files changed, 140 insertions(+), 124 deletions(-) diff --git a/src/platform/portduino/PortduinoGlue.cpp b/src/platform/portduino/PortduinoGlue.cpp index e56016a5b0..7f3012c015 100644 --- a/src/platform/portduino/PortduinoGlue.cpp +++ b/src/platform/portduino/PortduinoGlue.cpp @@ -11,6 +11,7 @@ #include "PortduinoGlue.h" #include "linux/gpio/LinuxGPIOPin.h" #include "yaml-cpp/yaml.h" +#include #include #include #include @@ -100,33 +101,20 @@ void portduinoSetup() settingsStrings[displayspidev] = ""; settingsMap[spiSpeed] = 2000000; settingsMap[ascii_logs] = !isatty(1); + settingsMap[displayPanel] = no_screen; + settingsMap[touchscreenModule] = no_touchscreen; YAML::Node yamlConfig; if (configPath != nullptr) { std::cout << "Using " << configPath << " as config file" << std::endl; - try { - yamlConfig = YAML::LoadFile(configPath); - } catch (YAML::Exception &e) { - std::cout << "Could not open " << configPath << " because of error: " << e.what() << std::endl; - exit(EXIT_FAILURE); - } + loadConfig(configPath); } else if (access("config.yaml", R_OK) == 0) { std::cout << "Using local config.yaml as config file" << std::endl; - try { - yamlConfig = YAML::LoadFile("config.yaml"); - } catch (YAML::Exception &e) { - std::cout << "*** Exception " << e.what() << std::endl; - exit(EXIT_FAILURE); - } + loadConfig("config.yaml"); } else if (access("/etc/meshtasticd/config.yaml", R_OK) == 0) { std::cout << "Using /etc/meshtasticd/config.yaml as config file" << std::endl; - try { - yamlConfig = YAML::LoadFile("/etc/meshtasticd/config.yaml"); - } catch (YAML::Exception &e) { - std::cout << "*** Exception " << e.what() << std::endl; - exit(EXIT_FAILURE); - } + loadConfig("/etc/meshtasticd/config.yaml"); } else { std::cout << "No 'config.yaml' found, running simulated." << std::endl; settingsMap[maxnodes] = 200; // Default to 200 nodes @@ -136,10 +124,130 @@ void portduinoSetup() return; } + if (settingsStrings[config_directory] != "") { + std::string filetype = ".yaml"; + for (const std::filesystem::directory_entry &entry : + std::filesystem::directory_iterator{settingsStrings[config_directory]}) { + if (ends_with(entry.path().string(), ".yaml")) { + std::cout << "Also using " << entry << " as additional config file" << std::endl; + loadConfig(entry.path().c_str()); + } + } + } + // Rather important to set this, if not running simulated. randomSeed(time(NULL)); + gpioChipName += std::to_string(settingsMap[gpiochip]); + + for (configNames i : GPIO_lines) { + if (settingsMap.count(i) && settingsMap[i] > max_GPIO) + max_GPIO = settingsMap[i]; + } + + gpioInit(max_GPIO + 1); // Done here so we can inform Portduino how many GPIOs we need. + + // Need to bind all the configured GPIO pins so they're not simulated + // TODO: Can we do this in the for loop above? + // TODO: If one of these fails, we should log and terminate + if (settingsMap.count(cs) > 0 && settingsMap[cs] != RADIOLIB_NC) { + if (initGPIOPin(settingsMap[cs], gpioChipName) != ERRNO_OK) { + settingsMap[cs] = RADIOLIB_NC; + } + } + if (settingsMap.count(irq) > 0 && settingsMap[irq] != RADIOLIB_NC) { + if (initGPIOPin(settingsMap[irq], gpioChipName) != ERRNO_OK) { + settingsMap[irq] = RADIOLIB_NC; + } + } + if (settingsMap.count(busy) > 0 && settingsMap[busy] != RADIOLIB_NC) { + if (initGPIOPin(settingsMap[busy], gpioChipName) != ERRNO_OK) { + settingsMap[busy] = RADIOLIB_NC; + } + } + if (settingsMap.count(reset) > 0 && settingsMap[reset] != RADIOLIB_NC) { + if (initGPIOPin(settingsMap[reset], gpioChipName) != ERRNO_OK) { + settingsMap[reset] = RADIOLIB_NC; + } + } + if (settingsMap.count(sx126x_ant_sw) > 0 && settingsMap[sx126x_ant_sw] != RADIOLIB_NC) { + if (initGPIOPin(settingsMap[sx126x_ant_sw], gpioChipName) != ERRNO_OK) { + settingsMap[sx126x_ant_sw] = RADIOLIB_NC; + } + } + if (settingsMap.count(user) > 0 && settingsMap[user] != RADIOLIB_NC) { + if (initGPIOPin(settingsMap[user], gpioChipName) != ERRNO_OK) { + settingsMap[user] = RADIOLIB_NC; + } + } + if (settingsMap.count(rxen) > 0 && settingsMap[rxen] != RADIOLIB_NC) { + if (initGPIOPin(settingsMap[rxen], gpioChipName) != ERRNO_OK) { + settingsMap[rxen] = RADIOLIB_NC; + } + } + if (settingsMap.count(txen) > 0 && settingsMap[txen] != RADIOLIB_NC) { + if (initGPIOPin(settingsMap[txen], gpioChipName) != ERRNO_OK) { + settingsMap[txen] = RADIOLIB_NC; + } + } + + if (settingsMap[displayPanel] != no_screen) { + if (settingsMap[displayCS] > 0) + initGPIOPin(settingsMap[displayCS], gpioChipName); + if (settingsMap[displayDC] > 0) + initGPIOPin(settingsMap[displayDC], gpioChipName); + if (settingsMap[displayBacklight] > 0) + initGPIOPin(settingsMap[displayBacklight], gpioChipName); + if (settingsMap[displayReset] > 0) + initGPIOPin(settingsMap[displayReset], gpioChipName); + } + if (settingsMap[touchscreenModule] != no_touchscreen) { + if (settingsMap[touchscreenCS] > 0) + initGPIOPin(settingsMap[touchscreenCS], gpioChipName); + if (settingsMap[touchscreenIRQ] > 0) + initGPIOPin(settingsMap[touchscreenIRQ], gpioChipName); + } + + 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; +} + +int initGPIOPin(int pinNum, const std::string gpioChipName) +{ +#ifdef PORTDUINO_LINUX_HARDWARE + std::string gpio_name = "GPIO" + std::to_string(pinNum); try { + GPIOPin *csPin; + csPin = new LinuxGPIOPin(pinNum, gpioChipName.c_str(), pinNum, gpio_name.c_str()); + csPin->setSilent(); + gpioBind(csPin); + return ERRNO_OK; + } catch (...) { + std::exception_ptr p = std::current_exception(); + std::cout << "Warning, cannot claim pin " << gpio_name << (p ? p.__cxa_exception_type()->name() : "null") << std::endl; + return ERRNO_DISABLED; + } +#else + return ERRNO_OK; +#endif +} + +bool loadConfig(const char *configPath) +{ + YAML::Node yamlConfig; + try { + yamlConfig = YAML::LoadFile(configPath); if (yamlConfig["Logging"]) { if (yamlConfig["Logging"]["LogLevel"].as("info") == "trace") { settingsMap[logoutputlevel] = level_trace; @@ -185,7 +293,6 @@ void portduinoSetup() settingsMap[gpiochip] = yamlConfig["Lora"]["gpiochip"].as(0); settingsMap[ch341Quirk] = yamlConfig["Lora"]["ch341_quirk"].as(false); settingsMap[spiSpeed] = yamlConfig["Lora"]["spiSpeed"].as(2000000); - gpioChipName += std::to_string(settingsMap[gpiochip]); settingsStrings[spidev] = "/dev/" + yamlConfig["Lora"]["spidev"].as("spidev0.0"); if (settingsStrings[spidev].length() == 14) { @@ -211,7 +318,6 @@ void portduinoSetup() if (yamlConfig["I2C"]) { settingsStrings[i2cdev] = yamlConfig["I2C"]["I2CDevice"].as(""); } - settingsMap[displayPanel] = no_screen; if (yamlConfig["Display"]) { if (yamlConfig["Display"]["Panel"].as("") == "ST7789") settingsMap[displayPanel] = st7789; @@ -258,7 +364,6 @@ void portduinoSetup() } } } - settingsMap[touchscreenModule] = no_touchscreen; if (yamlConfig["Touchscreen"]) { if (yamlConfig["Touchscreen"]["Module"].as("") == "XPT2046") settingsMap[touchscreenModule] = xpt2046; @@ -293,113 +398,21 @@ void portduinoSetup() settingsStrings[webserverrootpath] = (yamlConfig["Webserver"]["RootPath"]).as(""); } - settingsMap[maxnodes] = (yamlConfig["General"]["MaxNodes"]).as(200); - settingsMap[maxtophone] = (yamlConfig["General"]["MaxMessageQueue"]).as(100); + if (yamlConfig["General"]) { + settingsMap[maxnodes] = (yamlConfig["General"]["MaxNodes"]).as(200); + settingsMap[maxtophone] = (yamlConfig["General"]["MaxMessageQueue"]).as(100); + settingsStrings[config_directory] = (yamlConfig["General"]["ConfigDirectory"]).as(""); + } } catch (YAML::Exception &e) { std::cout << "*** Exception " << e.what() << std::endl; exit(EXIT_FAILURE); } - - for (configNames i : GPIO_lines) { - if (settingsMap.count(i) && settingsMap[i] > max_GPIO) - max_GPIO = settingsMap[i]; - } - - gpioInit(max_GPIO + 1); // Done here so we can inform Portduino how many GPIOs we need. - - // Need to bind all the configured GPIO pins so they're not simulated - // TODO: Can we do this in the for loop above? - // TODO: If one of these fails, we should log and terminate - if (settingsMap.count(cs) > 0 && settingsMap[cs] != RADIOLIB_NC) { - if (initGPIOPin(settingsMap[cs], gpioChipName) != ERRNO_OK) { - settingsMap[cs] = RADIOLIB_NC; - } - } - if (settingsMap.count(irq) > 0 && settingsMap[irq] != RADIOLIB_NC) { - if (initGPIOPin(settingsMap[irq], gpioChipName) != ERRNO_OK) { - settingsMap[irq] = RADIOLIB_NC; - } - } - if (settingsMap.count(busy) > 0 && settingsMap[busy] != RADIOLIB_NC) { - if (initGPIOPin(settingsMap[busy], gpioChipName) != ERRNO_OK) { - settingsMap[busy] = RADIOLIB_NC; - } - } - if (settingsMap.count(reset) > 0 && settingsMap[reset] != RADIOLIB_NC) { - if (initGPIOPin(settingsMap[reset], gpioChipName) != ERRNO_OK) { - settingsMap[reset] = RADIOLIB_NC; - } - } - if (settingsMap.count(sx126x_ant_sw) > 0 && settingsMap[sx126x_ant_sw] != RADIOLIB_NC) { - if (initGPIOPin(settingsMap[sx126x_ant_sw], gpioChipName) != ERRNO_OK) { - settingsMap[sx126x_ant_sw] = RADIOLIB_NC; - } - } - if (settingsMap.count(user) > 0 && settingsMap[user] != RADIOLIB_NC) { - if (initGPIOPin(settingsMap[user], gpioChipName) != ERRNO_OK) { - settingsMap[user] = RADIOLIB_NC; - } - } - if (settingsMap.count(rxen) > 0 && settingsMap[rxen] != RADIOLIB_NC) { - if (initGPIOPin(settingsMap[rxen], gpioChipName) != ERRNO_OK) { - settingsMap[rxen] = RADIOLIB_NC; - } - } - if (settingsMap.count(txen) > 0 && settingsMap[txen] != RADIOLIB_NC) { - if (initGPIOPin(settingsMap[txen], gpioChipName) != ERRNO_OK) { - settingsMap[txen] = RADIOLIB_NC; - } - } - - if (settingsMap[displayPanel] != no_screen) { - if (settingsMap[displayCS] > 0) - initGPIOPin(settingsMap[displayCS], gpioChipName); - if (settingsMap[displayDC] > 0) - initGPIOPin(settingsMap[displayDC], gpioChipName); - if (settingsMap[displayBacklight] > 0) - initGPIOPin(settingsMap[displayBacklight], gpioChipName); - if (settingsMap[displayReset] > 0) - initGPIOPin(settingsMap[displayReset], gpioChipName); - } - if (settingsMap[touchscreenModule] != no_touchscreen) { - if (settingsMap[touchscreenCS] > 0) - initGPIOPin(settingsMap[touchscreenCS], gpioChipName); - if (settingsMap[touchscreenIRQ] > 0) - initGPIOPin(settingsMap[touchscreenIRQ], gpioChipName); - } - - 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; + return true; } -int initGPIOPin(int pinNum, const std::string gpioChipName) +// https://stackoverflow.com/questions/874134/find-out-if-string-ends-with-another-string-in-c +static bool ends_with(std::string_view str, std::string_view suffix) { -#ifdef PORTDUINO_LINUX_HARDWARE - std::string gpio_name = "GPIO" + std::to_string(pinNum); - try { - GPIOPin *csPin; - csPin = new LinuxGPIOPin(pinNum, gpioChipName.c_str(), pinNum, gpio_name.c_str()); - csPin->setSilent(); - gpioBind(csPin); - return ERRNO_OK; - } catch (...) { - std::exception_ptr p = std::current_exception(); - std::cout << "Warning, cannot claim pin " << gpio_name << (p ? p.__cxa_exception_type()->name() : "null") << std::endl; - return ERRNO_DISABLED; - } -#else - return ERRNO_OK; -#endif + return str.size() >= suffix.size() && str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0; } \ No newline at end of file diff --git a/src/platform/portduino/PortduinoGlue.h b/src/platform/portduino/PortduinoGlue.h index 8ee96717e5..95d82c1a21 100644 --- a/src/platform/portduino/PortduinoGlue.h +++ b/src/platform/portduino/PortduinoGlue.h @@ -55,7 +55,8 @@ enum configNames { webserverrootpath, maxtophone, maxnodes, - ascii_logs + ascii_logs, + config_directory }; enum { no_screen, x11, st7789, st7735, st7735s, st7796, ili9341, ili9342, ili9488, hx8357d }; enum { no_touchscreen, xpt2046, stmpe610, gt911, ft5x06 }; @@ -64,4 +65,6 @@ enum { level_error, level_warn, level_info, level_debug, level_trace }; extern std::map settingsMap; extern std::map settingsStrings; extern std::ofstream traceFile; -int initGPIOPin(int pinNum, std::string gpioChipname); \ No newline at end of file +int initGPIOPin(int pinNum, std::string gpioChipname); +bool loadConfig(const char *configPath); +static bool ends_with(std::string_view str, std::string_view suffix); \ No newline at end of file From 10f18446b4e34bbeff765d61a7d2aa8d1ac1d798 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sun, 27 Oct 2024 18:55:11 -0500 Subject: [PATCH 2/3] Add waveshare hats to the new config.d approach --- .github/workflows/package_raspbian.yml | 2 ++ bin/config-dist.yaml | 11 ++++------- .../display-waveshare-2.8.yaml.inactive | 18 ++++++++++++++++++ bin/config.d/lora-waveshare-sxxx.yaml.inactive | 8 ++++++++ 4 files changed, 32 insertions(+), 7 deletions(-) create mode 100644 bin/config.d/display-waveshare-2.8.yaml.inactive create mode 100644 bin/config.d/lora-waveshare-sxxx.yaml.inactive diff --git a/.github/workflows/package_raspbian.yml b/.github/workflows/package_raspbian.yml index bcbda53e27..bab2bacc3c 100644 --- a/.github/workflows/package_raspbian.yml +++ b/.github/workflows/package_raspbian.yml @@ -50,11 +50,13 @@ jobs: mkdir -p .debpkg/usr/share/doc/meshtasticd/web mkdir -p .debpkg/usr/sbin mkdir -p .debpkg/etc/meshtasticd + mkdir -p .debpkg/etc/meshtasticd/config.d mkdir -p .debpkg/usr/lib/systemd/system/ tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz cp release/meshtasticd_linux_aarch64 .debpkg/usr/sbin/meshtasticd cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml + cp bin/config.d/* .debpkg/etc/meshtasticd/config.d/ chmod +x .debpkg/usr/sbin/meshtasticd cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles diff --git a/bin/config-dist.yaml b/bin/config-dist.yaml index a755954b1f..023a2e365c 100644 --- a/bin/config-dist.yaml +++ b/bin/config-dist.yaml @@ -1,15 +1,11 @@ +### Many device configs have been moved to config.d, and named [device].yaml.inactive. +### To activate, simply rename the file to end in .yaml + ### Define your devices here using Broadcom pin numbering ### Uncomment the block that corresponds to your hardware ### Including the "Module:" line! --- Lora: -# Module: sx1262 # Waveshare SX126X XXXM -# DIO2_AS_RF_SWITCH: true -# CS: 21 -# IRQ: 16 -# Busy: 20 -# Reset: 18 -# SX126X_ANT_SW: 6 # Module: sx1262 # Waveshare SX1302 LISTEN ONLY AT THIS TIME! # CS: 7 @@ -156,3 +152,4 @@ Webserver: General: MaxNodes: 200 MaxMessageQueue: 100 + ConfigDirectory: /etc/meshtasticd/config.d/ \ No newline at end of file diff --git a/bin/config.d/display-waveshare-2.8.yaml.inactive b/bin/config.d/display-waveshare-2.8.yaml.inactive new file mode 100644 index 0000000000..2e28276d8a --- /dev/null +++ b/bin/config.d/display-waveshare-2.8.yaml.inactive @@ -0,0 +1,18 @@ +Display: + +### Waveshare 2.8inch RPi LCD + Panel: ST7789 + CS: 8 + DC: 22 # Data/Command pin + Backlight: 18 + Width: 240 + Height: 320 + Reset: 27 + Rotate: true + Invert: true + +Touchscreen: +### Note, at least for now, the touchscreen must have a CS pin defined, even if you let Linux manage the CS switching. + Module: XPT2046 # Waveshare 2.8inch + CS: 7 + IRQ: 17 \ No newline at end of file diff --git a/bin/config.d/lora-waveshare-sxxx.yaml.inactive b/bin/config.d/lora-waveshare-sxxx.yaml.inactive new file mode 100644 index 0000000000..a9ff136530 --- /dev/null +++ b/bin/config.d/lora-waveshare-sxxx.yaml.inactive @@ -0,0 +1,8 @@ +Lora: + Module: sx1262 # Waveshare SX126X XXXM + DIO2_AS_RF_SWITCH: true + CS: 21 + IRQ: 16 + Busy: 20 + Reset: 18 + SX126X_ANT_SW: 6 From 6b38e9e6277562afc302c42986a0d2691e334cae Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Mon, 28 Oct 2024 21:22:27 -0500 Subject: [PATCH 3/3] Move to available.d for module inactive module configs --- .github/workflows/package_amd64.yml | 3 +++ .github/workflows/package_raspbian.yml | 3 ++- .github/workflows/package_raspbian_armv7l.yml | 3 +++ bin/config-dist.yaml | 4 ++-- ....yaml.inactive => display-waveshare-2.8.yaml} | 0 ...xx.yaml.inactive => lora-waveshare-sxxx.yaml} | 0 src/platform/portduino/PortduinoGlue.cpp | 16 +++++++++------- 7 files changed, 19 insertions(+), 10 deletions(-) rename bin/config.d/{display-waveshare-2.8.yaml.inactive => display-waveshare-2.8.yaml} (100%) rename bin/config.d/{lora-waveshare-sxxx.yaml.inactive => lora-waveshare-sxxx.yaml} (100%) diff --git a/.github/workflows/package_amd64.yml b/.github/workflows/package_amd64.yml index 0b5093f248..a5442246aa 100644 --- a/.github/workflows/package_amd64.yml +++ b/.github/workflows/package_amd64.yml @@ -50,11 +50,14 @@ jobs: mkdir -p .debpkg/usr/share/doc/meshtasticd/web mkdir -p .debpkg/usr/sbin mkdir -p .debpkg/etc/meshtasticd + mkdir -p .debpkg/etc/meshtasticd/config.d + mkdir -p .debpkg/etc/meshtasticd/available.d mkdir -p .debpkg/usr/lib/systemd/system/ tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz cp release/meshtasticd_linux_x86_64 .debpkg/usr/sbin/meshtasticd cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml + cp bin/config.d/* .debpkg/etc/meshtasticd/available.d/ chmod +x .debpkg/usr/sbin/meshtasticd cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles diff --git a/.github/workflows/package_raspbian.yml b/.github/workflows/package_raspbian.yml index bab2bacc3c..89efba1ded 100644 --- a/.github/workflows/package_raspbian.yml +++ b/.github/workflows/package_raspbian.yml @@ -51,12 +51,13 @@ jobs: mkdir -p .debpkg/usr/sbin mkdir -p .debpkg/etc/meshtasticd mkdir -p .debpkg/etc/meshtasticd/config.d + mkdir -p .debpkg/etc/meshtasticd/available.d mkdir -p .debpkg/usr/lib/systemd/system/ tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz cp release/meshtasticd_linux_aarch64 .debpkg/usr/sbin/meshtasticd cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml - cp bin/config.d/* .debpkg/etc/meshtasticd/config.d/ + cp bin/config.d/* .debpkg/etc/meshtasticd/available.d/ chmod +x .debpkg/usr/sbin/meshtasticd cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles diff --git a/.github/workflows/package_raspbian_armv7l.yml b/.github/workflows/package_raspbian_armv7l.yml index 1308fe925f..5cbc270974 100644 --- a/.github/workflows/package_raspbian_armv7l.yml +++ b/.github/workflows/package_raspbian_armv7l.yml @@ -50,11 +50,14 @@ jobs: mkdir -p .debpkg/usr/share/doc/meshtasticd/web mkdir -p .debpkg/usr/sbin mkdir -p .debpkg/etc/meshtasticd + mkdir -p .debpkg/etc/meshtasticd/config.d + mkdir -p .debpkg/etc/meshtasticd/available.d mkdir -p .debpkg/usr/lib/systemd/system/ tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz cp release/meshtasticd_linux_armv7l .debpkg/usr/sbin/meshtasticd cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml + cp bin/config.d/* .debpkg/etc/meshtasticd/available.d/ chmod +x .debpkg/usr/sbin/meshtasticd cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles diff --git a/bin/config-dist.yaml b/bin/config-dist.yaml index 50980442c6..bf1331a2b0 100644 --- a/bin/config-dist.yaml +++ b/bin/config-dist.yaml @@ -1,5 +1,5 @@ -### Many device configs have been moved to config.d, and named [device].yaml.inactive. -### To activate, simply rename the file to end in .yaml +### Many device configs have been moved to /etc/meshtasticd/available.d +### To activate, simply copy or link the appropriate file into /etc/meshtasticd/config.d ### Define your devices here using Broadcom pin numbering ### Uncomment the block that corresponds to your hardware diff --git a/bin/config.d/display-waveshare-2.8.yaml.inactive b/bin/config.d/display-waveshare-2.8.yaml similarity index 100% rename from bin/config.d/display-waveshare-2.8.yaml.inactive rename to bin/config.d/display-waveshare-2.8.yaml diff --git a/bin/config.d/lora-waveshare-sxxx.yaml.inactive b/bin/config.d/lora-waveshare-sxxx.yaml similarity index 100% rename from bin/config.d/lora-waveshare-sxxx.yaml.inactive rename to bin/config.d/lora-waveshare-sxxx.yaml diff --git a/src/platform/portduino/PortduinoGlue.cpp b/src/platform/portduino/PortduinoGlue.cpp index 7f3012c015..78562e47a7 100644 --- a/src/platform/portduino/PortduinoGlue.cpp +++ b/src/platform/portduino/PortduinoGlue.cpp @@ -107,14 +107,16 @@ void portduinoSetup() YAML::Node yamlConfig; if (configPath != nullptr) { - std::cout << "Using " << configPath << " as config file" << std::endl; - loadConfig(configPath); - } else if (access("config.yaml", R_OK) == 0) { + if (loadConfig(configPath)) { + std::cout << "Using " << configPath << " as config file" << std::endl; + } else { + std::cout << "Unable to use " << configPath << " as config file" << std::endl; + exit(EXIT_FAILURE); + } + } else if (access("config.yaml", R_OK) == 0 && loadConfig("config.yaml")) { std::cout << "Using local config.yaml as config file" << std::endl; - loadConfig("config.yaml"); - } else if (access("/etc/meshtasticd/config.yaml", R_OK) == 0) { + } else if (access("/etc/meshtasticd/config.yaml", R_OK) == 0 && loadConfig("/etc/meshtasticd/config.yaml")) { std::cout << "Using /etc/meshtasticd/config.yaml as config file" << std::endl; - loadConfig("/etc/meshtasticd/config.yaml"); } else { std::cout << "No 'config.yaml' found, running simulated." << std::endl; settingsMap[maxnodes] = 200; // Default to 200 nodes @@ -406,7 +408,7 @@ bool loadConfig(const char *configPath) } catch (YAML::Exception &e) { std::cout << "*** Exception " << e.what() << std::endl; - exit(EXIT_FAILURE); + return false; } return true; }