From cabeb40c303fb8fc4da2b477c75c7d7a2b9201b9 Mon Sep 17 00:00:00 2001 From: Austin Date: Tue, 10 Dec 2024 14:58:16 -0500 Subject: [PATCH 01/25] Portduino: Move meshtasticd/web out of /usr/share/doc/ (#5548) --- .github/workflows/package_amd64.yml | 17 +++++++++++------ .github/workflows/package_raspbian.yml | 17 +++++++++++------ .github/workflows/package_raspbian_armv7l.yml | 17 +++++++++++------ bin/config-dist.yaml | 2 +- 4 files changed, 34 insertions(+), 19 deletions(-) diff --git a/.github/workflows/package_amd64.yml b/.github/workflows/package_amd64.yml index ce2c85d540..aec3bca30a 100644 --- a/.github/workflows/package_amd64.yml +++ b/.github/workflows/package_amd64.yml @@ -47,18 +47,18 @@ jobs: - name: build .debpkg run: | mkdir -p .debpkg/DEBIAN - mkdir -p .debpkg/usr/share/doc/meshtasticd/web + mkdir -p .debpkg/usr/share/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 + tar -xf build.tar -C .debpkg/usr/share/meshtasticd/web shopt -s dotglob nullglob - if [ -d .debpkg/usr/share/doc/meshtasticd/web/build ]; then mv .debpkg/usr/share/doc/meshtasticd/web/build/* .debpkg/usr/share/doc/meshtasticd/web/; fi - if [ -d .debpkg/usr/share/doc/meshtasticd/web/build ]; then rmdir .debpkg/usr/share/doc/meshtasticd/web/build; fi - if [ -d .debpkg/usr/share/doc/meshtasticd/web/.DS_Store ]; then rm -f .debpkg/usr/share/doc/meshtasticd/web/.DS_Store; fi - gunzip .debpkg/usr/share/doc/meshtasticd/web/ -r + if [ -d .debpkg/usr/share/meshtasticd/web/build ]; then mv .debpkg/usr/share/meshtasticd/web/build/* .debpkg/usr/share/meshtasticd/web/; fi + if [ -d .debpkg/usr/share/meshtasticd/web/build ]; then rmdir .debpkg/usr/share/meshtasticd/web/build; fi + if [ -d .debpkg/usr/share/meshtasticd/web/.DS_Store ]; then rm -f .debpkg/usr/share/meshtasticd/web/.DS_Store; fi + gunzip .debpkg/usr/share/meshtasticd/web/ -r 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/ -r @@ -66,6 +66,11 @@ jobs: cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles chmod +x .debpkg/DEBIAN/conffiles + # Transition /usr/share/doc/meshtasticd to /usr/share/meshtasticd + echo "rm -rf /usr/share/doc/meshtasticd" > .debpkg/DEBIAN/preinst + chmod +x .debpkg/DEBIAN/preinst + echo "/usr/share/meshtasticd /usr/share/doc/meshtasticd" > .debpkg/DEBIAN/meshtasticd.links + chmod +x .debpkg/DEBIAN/meshtasticd.links - uses: jiro4989/build-deb-action@v3 with: diff --git a/.github/workflows/package_raspbian.yml b/.github/workflows/package_raspbian.yml index 46039b6ea9..b0a4a40d76 100644 --- a/.github/workflows/package_raspbian.yml +++ b/.github/workflows/package_raspbian.yml @@ -47,18 +47,18 @@ jobs: - name: build .debpkg run: | mkdir -p .debpkg/DEBIAN - mkdir -p .debpkg/usr/share/doc/meshtasticd/web + mkdir -p .debpkg/usr/share/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 + tar -xf build.tar -C .debpkg/usr/share/meshtasticd/web shopt -s dotglob nullglob - if [ -d .debpkg/usr/share/doc/meshtasticd/web/build ]; then mv .debpkg/usr/share/doc/meshtasticd/web/build/* .debpkg/usr/share/doc/meshtasticd/web/; fi - if [ -d .debpkg/usr/share/doc/meshtasticd/web/build ]; then rmdir .debpkg/usr/share/doc/meshtasticd/web/build; fi - if [ -d .debpkg/usr/share/doc/meshtasticd/web/.DS_Store ]; then rm -f .debpkg/usr/share/doc/meshtasticd/web/.DS_Store; fi - gunzip .debpkg/usr/share/doc/meshtasticd/web/ -r + if [ -d .debpkg/usr/share/meshtasticd/web/build ]; then mv .debpkg/usr/share/meshtasticd/web/build/* .debpkg/usr/share/meshtasticd/web/; fi + if [ -d .debpkg/usr/share/meshtasticd/web/build ]; then rmdir .debpkg/usr/share/meshtasticd/web/build; fi + if [ -d .debpkg/usr/share/meshtasticd/web/.DS_Store ]; then rm -f .debpkg/usr/share/meshtasticd/web/.DS_Store; fi + gunzip .debpkg/usr/share/meshtasticd/web/ -r 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/available.d/ -r @@ -66,6 +66,11 @@ jobs: cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles chmod +x .debpkg/DEBIAN/conffiles + # Transition /usr/share/doc/meshtasticd to /usr/share/meshtasticd + echo "rm -rf /usr/share/doc/meshtasticd" > .debpkg/DEBIAN/preinst + chmod +x .debpkg/DEBIAN/preinst + echo "/usr/share/meshtasticd /usr/share/doc/meshtasticd" > .debpkg/DEBIAN/meshtasticd.links + chmod +x .debpkg/DEBIAN/meshtasticd.links - uses: jiro4989/build-deb-action@v3 with: diff --git a/.github/workflows/package_raspbian_armv7l.yml b/.github/workflows/package_raspbian_armv7l.yml index 2eda103ca8..d66b46dc27 100644 --- a/.github/workflows/package_raspbian_armv7l.yml +++ b/.github/workflows/package_raspbian_armv7l.yml @@ -47,18 +47,18 @@ jobs: - name: build .debpkg run: | mkdir -p .debpkg/DEBIAN - mkdir -p .debpkg/usr/share/doc/meshtasticd/web + mkdir -p .debpkg/usr/share/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 + tar -xf build.tar -C .debpkg/usr/share/meshtasticd/web shopt -s dotglob nullglob - if [ -d .debpkg/usr/share/doc/meshtasticd/web/build ]; then mv .debpkg/usr/share/doc/meshtasticd/web/build/* .debpkg/usr/share/doc/meshtasticd/web/; fi - if [ -d .debpkg/usr/share/doc/meshtasticd/web/build ]; then rmdir .debpkg/usr/share/doc/meshtasticd/web/build; fi - if [ -d .debpkg/usr/share/doc/meshtasticd/web/.DS_Store ]; then rm -f .debpkg/usr/share/doc/meshtasticd/web/.DS_Store; fi - gunzip .debpkg/usr/share/doc/meshtasticd/web/ -r + if [ -d .debpkg/usr/share/meshtasticd/web/build ]; then mv .debpkg/usr/share/meshtasticd/web/build/* .debpkg/usr/share/meshtasticd/web/; fi + if [ -d .debpkg/usr/share/meshtasticd/web/build ]; then rmdir .debpkg/usr/share/meshtasticd/web/build; fi + if [ -d .debpkg/usr/share/meshtasticd/web/.DS_Store ]; then rm -f .debpkg/usr/share/meshtasticd/web/.DS_Store; fi + gunzip .debpkg/usr/share/meshtasticd/web/ -r 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/ -r @@ -66,6 +66,11 @@ jobs: cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles chmod +x .debpkg/DEBIAN/conffiles + # Transition /usr/share/doc/meshtasticd to /usr/share/meshtasticd + echo "rm -rf /usr/share/doc/meshtasticd" > .debpkg/DEBIAN/preinst + chmod +x .debpkg/DEBIAN/preinst + echo "/usr/share/meshtasticd /usr/share/doc/meshtasticd" > .debpkg/DEBIAN/meshtasticd.links + chmod +x .debpkg/DEBIAN/meshtasticd.links - uses: jiro4989/build-deb-action@v3 with: diff --git a/bin/config-dist.yaml b/bin/config-dist.yaml index cb25b36e7a..ec262536f6 100644 --- a/bin/config-dist.yaml +++ b/bin/config-dist.yaml @@ -155,7 +155,7 @@ Logging: Webserver: # Port: 443 # Port for Webserver & Webservices -# RootPath: /usr/share/doc/meshtasticd/web # Root Dir of WebServer +# RootPath: /usr/share/meshtasticd/web # Root Dir of WebServer General: MaxNodes: 200 From 7dd362950111fbf6ca134b678ec1975d3b6eb1fd Mon Sep 17 00:00:00 2001 From: Austin Date: Tue, 10 Dec 2024 16:02:38 -0500 Subject: [PATCH 02/25] Portduino: fix transitional symlinks (#5550) --- .github/workflows/package_amd64.yml | 4 ++-- .github/workflows/package_raspbian.yml | 4 ++-- .github/workflows/package_raspbian_armv7l.yml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/package_amd64.yml b/.github/workflows/package_amd64.yml index aec3bca30a..782ef479bc 100644 --- a/.github/workflows/package_amd64.yml +++ b/.github/workflows/package_amd64.yml @@ -69,8 +69,8 @@ jobs: # Transition /usr/share/doc/meshtasticd to /usr/share/meshtasticd echo "rm -rf /usr/share/doc/meshtasticd" > .debpkg/DEBIAN/preinst chmod +x .debpkg/DEBIAN/preinst - echo "/usr/share/meshtasticd /usr/share/doc/meshtasticd" > .debpkg/DEBIAN/meshtasticd.links - chmod +x .debpkg/DEBIAN/meshtasticd.links + echo "ln -sf /usr/share/meshtasticd /usr/share/doc/meshtasticd" > .debpkg/DEBIAN/postinst + chmod +x .debpkg/DEBIAN/postinst - uses: jiro4989/build-deb-action@v3 with: diff --git a/.github/workflows/package_raspbian.yml b/.github/workflows/package_raspbian.yml index b0a4a40d76..aef8905f82 100644 --- a/.github/workflows/package_raspbian.yml +++ b/.github/workflows/package_raspbian.yml @@ -69,8 +69,8 @@ jobs: # Transition /usr/share/doc/meshtasticd to /usr/share/meshtasticd echo "rm -rf /usr/share/doc/meshtasticd" > .debpkg/DEBIAN/preinst chmod +x .debpkg/DEBIAN/preinst - echo "/usr/share/meshtasticd /usr/share/doc/meshtasticd" > .debpkg/DEBIAN/meshtasticd.links - chmod +x .debpkg/DEBIAN/meshtasticd.links + echo "ln -sf /usr/share/meshtasticd /usr/share/doc/meshtasticd" > .debpkg/DEBIAN/postinst + chmod +x .debpkg/DEBIAN/postinst - uses: jiro4989/build-deb-action@v3 with: diff --git a/.github/workflows/package_raspbian_armv7l.yml b/.github/workflows/package_raspbian_armv7l.yml index d66b46dc27..ddb84d4a7e 100644 --- a/.github/workflows/package_raspbian_armv7l.yml +++ b/.github/workflows/package_raspbian_armv7l.yml @@ -69,8 +69,8 @@ jobs: # Transition /usr/share/doc/meshtasticd to /usr/share/meshtasticd echo "rm -rf /usr/share/doc/meshtasticd" > .debpkg/DEBIAN/preinst chmod +x .debpkg/DEBIAN/preinst - echo "/usr/share/meshtasticd /usr/share/doc/meshtasticd" > .debpkg/DEBIAN/meshtasticd.links - chmod +x .debpkg/DEBIAN/meshtasticd.links + echo "ln -sf /usr/share/meshtasticd /usr/share/doc/meshtasticd" > .debpkg/DEBIAN/postinst + chmod +x .debpkg/DEBIAN/postinst - uses: jiro4989/build-deb-action@v3 with: From 1790407078c4648f5fd15a7e6938e3b2b405cb32 Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Fri, 13 Dec 2024 02:58:19 +1100 Subject: [PATCH 03/25] Windows Support - Trunk and Platformio (#5397) (#5518) * Add support for GPG * Add usb device support * Add trunk.io to devcontainer * Trunk things * trunk fmt * formatting * fix trivy/DS002, checkov/CKV_DOCKER_3 * hide docker extension popup * fix trivy/DS026, checkov/CKV_DOCKER_2 Co-authored-by: Kalle Lilja <15094562+ThatKalle@users.noreply.github.com> --- .devcontainer/99-platformio-udev.rules | 183 +++++++++++++++++++++++++ .devcontainer/Dockerfile | 17 ++- .devcontainer/devcontainer.json | 13 +- 3 files changed, 210 insertions(+), 3 deletions(-) create mode 100644 .devcontainer/99-platformio-udev.rules diff --git a/.devcontainer/99-platformio-udev.rules b/.devcontainer/99-platformio-udev.rules new file mode 100644 index 0000000000..83c7b87317 --- /dev/null +++ b/.devcontainer/99-platformio-udev.rules @@ -0,0 +1,183 @@ +# Copyright (c) 2014-present PlatformIO +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +##################################################################################### +# +# INSTALLATION +# +# Please visit > https://docs.platformio.org/en/latest/core/installation/udev-rules.html +# +##################################################################################### + +# +# Boards +# + +# CP210X USB UART +ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea[67][013]", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" +ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="80a9", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# FT231XS USB UART +ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6015", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# Prolific Technology, Inc. PL2303 Serial Port +ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# QinHeng Electronics HL-340 USB-Serial adapter +ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" +# QinHeng Electronics CH343 USB-Serial adapter +ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="55d3", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" +# QinHeng Electronics CH9102 USB-Serial adapter +ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="55d4", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# Arduino boards +ATTRS{idVendor}=="2341", ATTRS{idProduct}=="[08][023]*", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" +ATTRS{idVendor}=="2a03", ATTRS{idProduct}=="[08][02]*", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# Arduino SAM-BA +ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="6124", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{MTP_NO_PROBE}="1" + +# Digistump boards +ATTRS{idVendor}=="16d0", ATTRS{idProduct}=="0753", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# Maple with DFU +ATTRS{idVendor}=="1eaf", ATTRS{idProduct}=="000[34]", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# USBtiny +ATTRS{idProduct}=="0c9f", ATTRS{idVendor}=="1781", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# USBasp V2.0 +ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="05dc", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# Teensy boards +ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789B]?", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" +ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789A]?", ENV{MTP_NO_PROBE}="1" +SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789ABCD]?", MODE:="0666" +KERNEL=="ttyACM*", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789B]?", MODE:="0666" + +# TI Stellaris Launchpad +ATTRS{idVendor}=="1cbe", ATTRS{idProduct}=="00fd", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# TI MSP430 Launchpad +ATTRS{idVendor}=="0451", ATTRS{idProduct}=="f432", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# GD32V DFU Bootloader +ATTRS{idVendor}=="28e9", ATTRS{idProduct}=="0189", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# FireBeetle-ESP32 +ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7522", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# Wio Terminal +ATTRS{idVendor}=="2886", ATTRS{idProduct}=="[08]02d", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# Raspberry Pi Pico +ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="[01]*", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# AIR32F103 +ATTRS{idVendor}=="0d28", ATTRS{idProduct}=="0204", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# STM32 virtual COM port +ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# +# Debuggers +# + +# Black Magic Probe +SUBSYSTEM=="tty", ATTRS{interface}=="Black Magic GDB Server", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" +SUBSYSTEM=="tty", ATTRS{interface}=="Black Magic UART Port", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# opendous and estick +ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="204f", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# Original FT232/FT245/FT2232/FT232H/FT4232 +ATTRS{idVendor}=="0403", ATTRS{idProduct}=="60[01][104]", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# DISTORTEC JTAG-lock-pick Tiny 2 +ATTRS{idVendor}=="0403", ATTRS{idProduct}=="8220", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# TUMPA, TUMPA Lite +ATTRS{idVendor}=="0403", ATTRS{idProduct}=="8a9[89]", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# XDS100v2 +ATTRS{idVendor}=="0403", ATTRS{idProduct}=="a6d0", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# Xverve Signalyzer Tool (DT-USB-ST), Signalyzer LITE (DT-USB-SLITE) +ATTRS{idVendor}=="0403", ATTRS{idProduct}=="bca[01]", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# TI/Luminary Stellaris Evaluation Board FTDI (several) +ATTRS{idVendor}=="0403", ATTRS{idProduct}=="bcd[9a]", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# egnite Turtelizer 2 +ATTRS{idVendor}=="0403", ATTRS{idProduct}=="bdc8", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# Section5 ICEbear +ATTRS{idVendor}=="0403", ATTRS{idProduct}=="c14[01]", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# Amontec JTAGkey and JTAGkey-tiny +ATTRS{idVendor}=="0403", ATTRS{idProduct}=="cff8", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# TI ICDI +ATTRS{idVendor}=="0451", ATTRS{idProduct}=="c32a", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# STLink probes +ATTRS{idVendor}=="0483", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# Hilscher NXHX Boards +ATTRS{idVendor}=="0640", ATTRS{idProduct}=="0028", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# Hitex probes +ATTRS{idVendor}=="0640", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# Altera USB Blaster +ATTRS{idVendor}=="09fb", ATTRS{idProduct}=="6001", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# Amontec JTAGkey-HiSpeed +ATTRS{idVendor}=="0fbb", ATTRS{idProduct}=="1000", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# SEGGER J-Link +ATTRS{idVendor}=="1366", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# Raisonance RLink +ATTRS{idVendor}=="138e", ATTRS{idProduct}=="9000", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# Debug Board for Neo1973 +ATTRS{idVendor}=="1457", ATTRS{idProduct}=="5118", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# Olimex probes +ATTRS{idVendor}=="15ba", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# USBprog with OpenOCD firmware +ATTRS{idVendor}=="1781", ATTRS{idProduct}=="0c63", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# TI/Luminary Stellaris In-Circuit Debug Interface (ICDI) Board +ATTRS{idVendor}=="1cbe", ATTRS{idProduct}=="00fd", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# Marvell Sheevaplug +ATTRS{idVendor}=="9e88", ATTRS{idProduct}=="9e8f", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# Keil Software, Inc. ULink +ATTRS{idVendor}=="c251", ATTRS{idProduct}=="2710", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# CMSIS-DAP compatible adapters +ATTRS{product}=="*CMSIS-DAP*", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# Atmel AVR Dragon +ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2107", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# Espressif USB JTAG/serial debug unit +ATTRS{idVendor}=="303a", ATTRS{idProduct}=="1001", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + +# Zephyr framework USB CDC-ACM +ATTRS{idVendor}=="2fe3", ATTRS{idProduct}=="0100", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" \ No newline at end of file diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index c21564491f..62f0b7eadc 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,6 +1,9 @@ FROM mcr.microsoft.com/devcontainers/cpp:1-debian-12 -# [Optional] Uncomment this section to install additional packages. +USER root + +# trunk-ignore(terrascan/AC_DOCKER_0002): Known terrascan issue +# trunk-ignore(hadolint/DL3008): Use latest version of packages RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ && apt-get -y install --no-install-recommends \ ca-certificates \ @@ -20,6 +23,16 @@ RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ python3-wheel \ wget \ zip \ + usbutils \ + hwdata \ + gpg \ + gnupg2 \ && apt-get clean && rm -rf /var/lib/apt/lists/* -RUN pipx install platformio==6.1.15 \ No newline at end of file +RUN pipx install platformio==6.1.15 + +COPY 99-platformio-udev.rules /etc/udev/rules.d/99-platformio-udev.rules + +USER vscode + +HEALTHCHECK NONE \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index d83d052b0a..bf1c509820 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -13,13 +13,24 @@ }, "customizations": { "vscode": { - "extensions": ["ms-vscode.cpptools", "platformio.platformio-ide"] + "extensions": [ + "ms-vscode.cpptools", + "platformio.platformio-ide", + "Trunk.io" + ], + "unwantedRecommendations": ["ms-azuretools.vscode-docker"], + "settings": { + "extensions.ignoreRecommendations": true + } } }, // Use 'forwardPorts' to make a list of ports inside the container available locally. "forwardPorts": [4403], + // Use "--device=" to make a local device available inside the container. + // "runArgs": ["--device=/dev/ttyACM0"], + // Run commands to prepare the container for use "postCreateCommand": ".devcontainer/setup.sh" } From 03770b799f7821275945ba70896012ec60bfea85 Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Fri, 13 Dec 2024 03:42:41 +1100 Subject: [PATCH 04/25] Synch minor changes from TFT branch (#5520) * Synch minor changes from TFT branch Includes: * New nordicnrf52 minor version (10.5.0 --> 10.6.0) * Optimisations for T_DECK * preparation for MESH_TAB * add ext notification module to portduino --------- Co-authored-by: mverch67 --- arch/nrf52/nrf52.ini | 3 ++- src/main.cpp | 5 ++--- src/mesh/NodeDB.cpp | 4 ++-- src/modules/Modules.cpp | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/nrf52/nrf52.ini b/arch/nrf52/nrf52.ini index d75f863064..778be55232 100644 --- a/arch/nrf52/nrf52.ini +++ b/arch/nrf52/nrf52.ini @@ -1,10 +1,11 @@ [nrf52_base] ; Instead of the standard nordicnrf52 platform, we use our fork which has our added variant files -platform = platformio/nordicnrf52@^10.5.0 +platform = platformio/nordicnrf52@^10.6.0 extends = arduino_base platform_packages = ; our custom Git version until they merge our PR framework-arduinoadafruitnrf52 @ https://github.com/geeksville/Adafruit_nRF52_Arduino.git + toolchain-gccarmnoneeabi@~1.90301.0 build_type = debug build_flags = diff --git a/src/main.cpp b/src/main.cpp index 53a6622722..2357a00de5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -409,13 +409,13 @@ void setup() digitalWrite(AQ_SET_PIN, HIGH); #endif -#ifdef T_DECK +#if defined(T_DECK) // enable keyboard pinMode(KB_POWERON, OUTPUT); digitalWrite(KB_POWERON, HIGH); // There needs to be a delay after power on, give LILYGO-KEYBOARD some startup time // otherwise keyboard and touch screen will not work - delay(800); + delay(200); #endif // Currently only the tbeam has a PMU @@ -577,7 +577,6 @@ void setup() scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::INA3221, meshtastic_TelemetrySensorType_INA3221); scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::MAX17048, meshtastic_TelemetrySensorType_MAX17048); scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::MCP9808, meshtastic_TelemetrySensorType_MCP9808); - scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::MCP9808, meshtastic_TelemetrySensorType_MCP9808); scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::SHT31, meshtastic_TelemetrySensorType_SHT31); scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::SHTC3, meshtastic_TelemetrySensorType_SHTC3); scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::LPS22HB, meshtastic_TelemetrySensorType_LPS22); diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 90b3e07477..6ad1a953d5 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -541,7 +541,7 @@ void NodeDB::initConfigIntervals() config.display.screen_on_secs = default_screen_on_secs; -#if defined(T_WATCH_S3) || defined(T_DECK) || defined(RAK14014) +#if defined(T_WATCH_S3) || defined(T_DECK) || defined(MESH_TAB) || defined(RAK14014) config.power.is_power_saving = true; config.display.screen_on_secs = 30; config.power.wait_bluetooth_secs = 30; @@ -1422,4 +1422,4 @@ void recordCriticalError(meshtastic_CriticalErrorCode code, uint32_t address, co LOG_ERROR("A critical failure occurred, portduino is exiting"); exit(2); #endif -} \ No newline at end of file +} diff --git a/src/modules/Modules.cpp b/src/modules/Modules.cpp index ad3f0ace45..9baed824c9 100644 --- a/src/modules/Modules.cpp +++ b/src/modules/Modules.cpp @@ -74,7 +74,7 @@ #include "modules/StoreForwardModule.h" #endif #endif -#if defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040) +#if defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040) || defined(ARCH_PORTDUINO) #if !MESHTASTIC_EXCLUDE_EXTERNALNOTIFICATION #include "modules/ExternalNotificationModule.h" #endif @@ -223,7 +223,7 @@ void setupModules() storeForwardModule = new StoreForwardModule(); #endif #endif -#if defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040) +#if defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040) || defined(ARCH_PORTDUINO) #if !MESHTASTIC_EXCLUDE_EXTERNALNOTIFICATION externalNotificationModule = new ExternalNotificationModule(); #endif @@ -245,4 +245,4 @@ void setupModules() // NOTE! This module must be added LAST because it likes to check for replies from other modules and avoid sending extra // acks routingModule = new RoutingModule(); -} \ No newline at end of file +} From 92225eb6c3ac60a12995432a4bfac0ee3641f093 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Fri, 13 Dec 2024 11:48:27 -0600 Subject: [PATCH 05/25] DIO3_TCXO_VOLTAGE in config.yaml can now take an exact voltage (#5558) --- src/mesh/LR11x0Interface.cpp | 4 +++- src/mesh/SX126xInterface.cpp | 4 +--- src/platform/portduino/PortduinoGlue.cpp | 5 ++++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/mesh/LR11x0Interface.cpp b/src/mesh/LR11x0Interface.cpp index 30ef8f9afe..ce4f912ba6 100644 --- a/src/mesh/LR11x0Interface.cpp +++ b/src/mesh/LR11x0Interface.cpp @@ -48,8 +48,10 @@ template bool LR11x0Interface::init() digitalWrite(LR11X0_POWER_EN, HIGH); #endif +#if ARCH_PORTDUINO + float tcxoVoltage = (float)settingsMap[dio3_tcxo_voltage] / 1000; // FIXME: correct logic to default to not using TCXO if no voltage is specified for LR11x0_DIO3_TCXO_VOLTAGE -#if !defined(LR11X0_DIO3_TCXO_VOLTAGE) +#elif !defined(LR11X0_DIO3_TCXO_VOLTAGE) float tcxoVoltage = 0; // "TCXO reference voltage to be set on DIO3. Defaults to 1.6 V, set to 0 to skip." per // https://github.com/jgromes/RadioLib/blob/690a050ebb46e6097c5d00c371e961c1caa3b52e/src/modules/LR11x0/LR11x0.h#L471C26-L471C104 diff --git a/src/mesh/SX126xInterface.cpp b/src/mesh/SX126xInterface.cpp index 002fb41ca1..ed0267c5b9 100644 --- a/src/mesh/SX126xInterface.cpp +++ b/src/mesh/SX126xInterface.cpp @@ -50,9 +50,7 @@ template bool SX126xInterface::init() #endif #if ARCH_PORTDUINO - float tcxoVoltage = 0; - if (settingsMap[dio3_tcxo_voltage]) - tcxoVoltage = 1.8; + float tcxoVoltage = (float)settingsMap[dio3_tcxo_voltage] / 1000; if (settingsMap[sx126x_ant_sw] != RADIOLIB_NC) { digitalWrite(settingsMap[sx126x_ant_sw], HIGH); pinMode(settingsMap[sx126x_ant_sw], OUTPUT); diff --git a/src/platform/portduino/PortduinoGlue.cpp b/src/platform/portduino/PortduinoGlue.cpp index 50b5c5b7b8..fa0c8c5027 100644 --- a/src/platform/portduino/PortduinoGlue.cpp +++ b/src/platform/portduino/PortduinoGlue.cpp @@ -365,7 +365,10 @@ bool loadConfig(const char *configPath) settingsMap[use_sx1268] = true; } settingsMap[dio2_as_rf_switch] = yamlConfig["Lora"]["DIO2_AS_RF_SWITCH"].as(false); - settingsMap[dio3_tcxo_voltage] = yamlConfig["Lora"]["DIO3_TCXO_VOLTAGE"].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)) { + settingsMap[dio3_tcxo_voltage] = 1800; // default millivolts for "true" + } settingsMap[cs] = yamlConfig["Lora"]["CS"].as(RADIOLIB_NC); settingsMap[irq] = yamlConfig["Lora"]["IRQ"].as(RADIOLIB_NC); settingsMap[busy] = yamlConfig["Lora"]["Busy"].as(RADIOLIB_NC); From 332dbaf57376cf93befaf8cf35e244e4ef9bf982 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Sat, 14 Dec 2024 10:59:15 +0100 Subject: [PATCH 06/25] Support TLORA_V3.0 (#5563) - Support TLORA_V3.0. Update of the legendary 2.1_1.6.1 with solar charger, TCXO and IPEX connector. - 'extra' some short-lived EOL intermediate boards in that range. If possible use T3S3 instead of all of these! - update trunk to latest version --- .trunk/trunk.yaml | 25 +++++++++++----------- platformio.ini | 1 + variants/tlora_v2_1_16_tcxo/platformio.ini | 1 + variants/tlora_v2_1_18/platformio.ini | 1 + variants/tlora_v3_3_0_tcxo/platformio.ini | 11 ++++++++++ 5 files changed, 27 insertions(+), 12 deletions(-) create mode 100644 variants/tlora_v3_3_0_tcxo/platformio.ini diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 743f4214da..f2393592c5 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -4,31 +4,32 @@ cli: plugins: sources: - id: trunk - ref: v1.6.4 + ref: v1.6.6 uri: https://github.com/trunk-io/plugins lint: enabled: - - trufflehog@3.83.6 + - prettier@3.4.2 + - trufflehog@3.86.1 - yamllint@1.35.1 - - bandit@1.7.10 - - checkov@3.2.287 + - bandit@1.8.0 + - checkov@3.2.334 - terrascan@1.19.9 - - trivy@0.56.2 + - trivy@0.58.0 #- trufflehog@3.63.2-rc0 - taplo@0.9.3 - - ruff@0.7.3 + - ruff@0.8.3 - isort@5.13.2 - - markdownlint@0.42.0 - - oxipng@9.1.2 + - markdownlint@0.43.0 + - oxipng@9.1.3 - svgo@3.3.2 - actionlint@1.7.4 - flake8@7.1.1 - - hadolint@2.12.0 + - hadolint@2.12.1-beta - shfmt@3.6.0 - shellcheck@0.10.0 - black@24.10.0 - git-diff-check - - gitleaks@8.21.1 + - gitleaks@8.21.2 - clang-format@16.0.3 #- prettier@3.3.3 ignore: @@ -39,11 +40,11 @@ runtimes: enabled: - python@3.10.8 - go@1.21.0 - - node@18.12.1 + - node@18.20.5 actions: disabled: - trunk-announce enabled: - trunk-fmt-pre-commit - trunk-check-pre-push - - trunk-upgrade-available \ No newline at end of file + - trunk-upgrade-available diff --git a/platformio.ini b/platformio.ini index cc08b33a00..08d21665f7 100644 --- a/platformio.ini +++ b/platformio.ini @@ -16,6 +16,7 @@ default_envs = tbeam ;default_envs = tlora-v2 ;default_envs = tlora-v2-1-1_6 ;default_envs = tlora-v2-1-1_6-tcxo +;default_envs = tlora-v3-3-0-tcxo ;default_envs = tlora-t3s3-v1 ;default_envs = t-echo ;default_envs = canaryone diff --git a/variants/tlora_v2_1_16_tcxo/platformio.ini b/variants/tlora_v2_1_16_tcxo/platformio.ini index e54c1a9207..538fd81b06 100644 --- a/variants/tlora_v2_1_16_tcxo/platformio.ini +++ b/variants/tlora_v2_1_16_tcxo/platformio.ini @@ -1,5 +1,6 @@ [env:tlora-v2-1-1_6-tcxo] extends = esp32_base +board_level = extra board = ttgo-lora32-v21 build_flags = ${esp32_base.build_flags} diff --git a/variants/tlora_v2_1_18/platformio.ini b/variants/tlora_v2_1_18/platformio.ini index 36d6a3157f..48a001ced1 100644 --- a/variants/tlora_v2_1_18/platformio.ini +++ b/variants/tlora_v2_1_18/platformio.ini @@ -1,5 +1,6 @@ [env:tlora-v2-1-1_8] extends = esp32_base +board_level = extra board = ttgo-lora32-v21 build_flags = diff --git a/variants/tlora_v3_3_0_tcxo/platformio.ini b/variants/tlora_v3_3_0_tcxo/platformio.ini new file mode 100644 index 0000000000..4066d64b05 --- /dev/null +++ b/variants/tlora_v3_3_0_tcxo/platformio.ini @@ -0,0 +1,11 @@ +[env:tlora-v3-3-0-tcxo] +extends = esp32_base +board = ttgo-lora32-v21 +board_level = extra +build_flags = + ${esp32_base.build_flags} + -D TLORA_V2_1_16 + -I variants/tlora_v2_1_16 + -D GPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely. + -D LORA_TCXO_GPIO=12 + -D BUTTON_PIN=0 \ No newline at end of file From c3f89a6db8feeb304b0969841db2c4ffba53a9c9 Mon Sep 17 00:00:00 2001 From: Mark Trevor Birss Date: Sat, 14 Dec 2024 12:46:35 +0200 Subject: [PATCH 07/25] Create OpenWRT-One-mikroBUS-LR-IOT-CLICK.yaml (#5564) --- bin/config.d/OpenWRT-One-mikroBUS-LR-IOT-CLICK.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 bin/config.d/OpenWRT-One-mikroBUS-LR-IOT-CLICK.yaml diff --git a/bin/config.d/OpenWRT-One-mikroBUS-LR-IOT-CLICK.yaml b/bin/config.d/OpenWRT-One-mikroBUS-LR-IOT-CLICK.yaml new file mode 100644 index 0000000000..ca5b27ebca --- /dev/null +++ b/bin/config.d/OpenWRT-One-mikroBUS-LR-IOT-CLICK.yaml @@ -0,0 +1,9 @@ +## https://www.mikroe.com/lr-iot-click +Lora: + Module: lr1110 # OpenWRT ONE mikroBUS with LR-IOT-CLICK +# CS: 25 + IRQ: 10 + Busy: 12 +# Reset: 2 + spidev: spidev2.0 + DIO3_TCXO_VOLTAGE: 1.6 From 44cf6d388ebd9d284e490c150cc568f3199fba0f Mon Sep 17 00:00:00 2001 From: GUVWAF <78759985+GUVWAF@users.noreply.github.com> Date: Sat, 14 Dec 2024 11:55:32 +0100 Subject: [PATCH 08/25] Portduino: fix setting hwId via argument (#5565) --- src/platform/portduino/PortduinoGlue.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/platform/portduino/PortduinoGlue.cpp b/src/platform/portduino/PortduinoGlue.cpp index fa0c8c5027..750cc16309 100644 --- a/src/platform/portduino/PortduinoGlue.cpp +++ b/src/platform/portduino/PortduinoGlue.cpp @@ -87,7 +87,8 @@ void getMacAddr(uint8_t *dmac) if (strlen(optionMac) >= 12) { MAC_from_string(optionMac, dmac); } else { - uint32_t hwId = sscanf(optionMac, "%u", &hwId); + uint32_t hwId; + sscanf(optionMac, "%u", &hwId); dmac[0] = 0x80; dmac[1] = 0; dmac[2] = hwId >> 24; @@ -532,4 +533,4 @@ bool MAC_from_string(std::string mac_str, uint8_t *dmac) } else { return false; } -} +} \ No newline at end of file From 4a1239f811a803b2103cf99d27c9db7dd2f2efc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Perdig=C3=A3o=20Gon=C3=A7alves?= Date: Sun, 15 Dec 2024 00:43:41 +0000 Subject: [PATCH 09/25] Add new endpoint to retrieve node info (#5557) --- src/mesh/http/ContentHandler.cpp | 74 ++++++++++++++++++++++++++++++++ src/mesh/http/ContentHandler.h | 1 + 2 files changed, 75 insertions(+) diff --git a/src/mesh/http/ContentHandler.cpp b/src/mesh/http/ContentHandler.cpp index 64f7164c99..2b88702ed2 100644 --- a/src/mesh/http/ContentHandler.cpp +++ b/src/mesh/http/ContentHandler.cpp @@ -93,6 +93,7 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer) ResourceNode *nodeJsonScanNetworks = new ResourceNode("/json/scanNetworks", "GET", &handleScanNetworks); ResourceNode *nodeJsonBlinkLED = new ResourceNode("/json/blink", "POST", &handleBlinkLED); ResourceNode *nodeJsonReport = new ResourceNode("/json/report", "GET", &handleReport); + ResourceNode *nodeJsonNodes = new ResourceNode("/json/nodes", "GET", &handleNodes); ResourceNode *nodeJsonFsBrowseStatic = new ResourceNode("/json/fs/browse/static", "GET", &handleFsBrowseStatic); ResourceNode *nodeJsonDelete = new ResourceNode("/json/fs/delete/static", "DELETE", &handleFsDeleteStatic); @@ -112,6 +113,7 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer) secureServer->registerNode(nodeJsonFsBrowseStatic); secureServer->registerNode(nodeJsonDelete); secureServer->registerNode(nodeJsonReport); + secureServer->registerNode(nodeJsonNodes); // secureServer->registerNode(nodeUpdateFs); // secureServer->registerNode(nodeDeleteFs); secureServer->registerNode(nodeAdmin); @@ -680,6 +682,78 @@ void handleReport(HTTPRequest *req, HTTPResponse *res) delete value; } +void handleNodes(HTTPRequest *req, HTTPResponse *res) +{ + ResourceParameters *params = req->getParams(); + std::string content; + + if (!params->getQueryParameter("content", content)) { + content = "json"; + } + + if (content == "json") { + res->setHeader("Content-Type", "application/json"); + res->setHeader("Access-Control-Allow-Origin", "*"); + res->setHeader("Access-Control-Allow-Methods", "GET"); + } else { + res->setHeader("Content-Type", "text/html"); + res->println("
");
+    }
+
+    JSONArray nodesArray;
+
+    uint32_t readIndex = 0;
+    const meshtastic_NodeInfoLite *tempNodeInfo = nodeDB->readNextMeshNode(readIndex);
+    while (tempNodeInfo != NULL) {
+        if (tempNodeInfo->has_user) {
+            JSONObject node;
+
+            char id[16];
+            snprintf(id, sizeof(id), "!%08x", tempNodeInfo->num);
+
+            node["id"] = new JSONValue(id);
+            node["snr"] = new JSONValue(tempNodeInfo->snr);
+            node["via_mqtt"] = new JSONValue(BoolToString(tempNodeInfo->via_mqtt));
+            node["last_heard"] = new JSONValue((int)tempNodeInfo->last_heard);
+            node["position"] = new JSONValue();
+
+            if (nodeDB->hasValidPosition(tempNodeInfo)) {
+                JSONObject position;
+                position["latitude"] = new JSONValue((float)tempNodeInfo->position.latitude_i * 1e-7);
+                position["longitude"] = new JSONValue((float)tempNodeInfo->position.longitude_i * 1e-7);
+                position["altitude"] = new JSONValue((int)tempNodeInfo->position.altitude);
+                node["position"] = new JSONValue(position);
+            }
+
+            JSONObject user;
+            node["long_name"] = new JSONValue(tempNodeInfo->user.long_name);
+            node["short_name"] = new JSONValue(tempNodeInfo->user.short_name);
+            char macStr[18];
+            snprintf(macStr, sizeof(macStr), "%02X:%02X:%02X:%02X:%02X:%02X", tempNodeInfo->user.macaddr[0],
+                     tempNodeInfo->user.macaddr[1], tempNodeInfo->user.macaddr[2], tempNodeInfo->user.macaddr[3],
+                     tempNodeInfo->user.macaddr[4], tempNodeInfo->user.macaddr[5]);
+            node["mac_address"] = new JSONValue(macStr);
+            node["hw_model"] = new JSONValue(tempNodeInfo->user.hw_model);
+
+            nodesArray.push_back(new JSONValue(node));
+        }
+        tempNodeInfo = nodeDB->readNextMeshNode(readIndex);
+    }
+
+    // collect data to inner data object
+    JSONObject jsonObjInner;
+    jsonObjInner["nodes"] = new JSONValue(nodesArray);
+
+    // create json output structure
+    JSONObject jsonObjOuter;
+    jsonObjOuter["data"] = new JSONValue(jsonObjInner);
+    jsonObjOuter["status"] = new JSONValue("ok");
+    // serialize and write it to the stream
+    JSONValue *value = new JSONValue(jsonObjOuter);
+    res->print(value->Stringify().c_str());
+    delete value;
+}
+
 /*
     This supports the Apple Captive Network Assistant (CNA) Portal
 */
diff --git a/src/mesh/http/ContentHandler.h b/src/mesh/http/ContentHandler.h
index 987e3ffef9..2066a6d575 100644
--- a/src/mesh/http/ContentHandler.h
+++ b/src/mesh/http/ContentHandler.h
@@ -13,6 +13,7 @@ void handleFsBrowseStatic(HTTPRequest *req, HTTPResponse *res);
 void handleFsDeleteStatic(HTTPRequest *req, HTTPResponse *res);
 void handleBlinkLED(HTTPRequest *req, HTTPResponse *res);
 void handleReport(HTTPRequest *req, HTTPResponse *res);
+void handleNodes(HTTPRequest *req, HTTPResponse *res);
 void handleUpdateFs(HTTPRequest *req, HTTPResponse *res);
 void handleDeleteFsContent(HTTPRequest *req, HTTPResponse *res);
 void handleFs(HTTPRequest *req, HTTPResponse *res);

From 6d8be13266c9e07caa42dc7a3420a9424c1aca89 Mon Sep 17 00:00:00 2001
From: Austin 
Date: Sat, 14 Dec 2024 20:19:19 -0500
Subject: [PATCH 10/25] Portduino-buildroot: Remove pkg-config optional libs
 (#5573)

---
 variants/portduino-buildroot/platformio.ini | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/variants/portduino-buildroot/platformio.ini b/variants/portduino-buildroot/platformio.ini
index 3c8f215379..683a3cecc8 100644
--- a/variants/portduino-buildroot/platformio.ini
+++ b/variants/portduino-buildroot/platformio.ini
@@ -1,11 +1,9 @@
 [env:buildroot]
 extends = portduino_base
-; The pkg-config commands below optionally add link flags.
-; the || : is just a "or run the null command" to avoid returning an error code
+; Optional libraries should be appended to `PLATFORMIO_BUILD_FLAGS`
+; environment variable in the buildroot environment.
 build_flags = ${portduino_base.build_flags} -O0 -I variants/portduino-buildroot
   -std=c++17
-  !pkg-config --libs libulfius --silence-errors || :
-  !pkg-config --libs openssl --silence-errors || :
 board = buildroot
 lib_deps = ${portduino_base.lib_deps}
 build_src_filter = ${portduino_base.build_src_filter}

From 4024bfdeeb57f8c213577d576a08ff63bd835e83 Mon Sep 17 00:00:00 2001
From: "Aaron.Lee" <32860565+Heltec-Aaron-Lee@users.noreply.github.com>
Date: Sun, 15 Dec 2024 10:20:29 +0800
Subject: [PATCH 11/25] Add screen detection function (#5533)

---
 src/mesh/NodeDB.cpp | 77 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 77 insertions(+)

diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp
index 6ad1a953d5..201304395f 100644
--- a/src/mesh/NodeDB.cpp
+++ b/src/mesh/NodeDB.cpp
@@ -70,6 +70,76 @@ static unsigned char userprefs_admin_key_1[] = USERPREFS_USE_ADMIN_KEY_1;
 static unsigned char userprefs_admin_key_2[] = USERPREFS_USE_ADMIN_KEY_2;
 #endif
 
+#ifdef HELTEC_MESH_NODE_T114
+
+uint32_t read8(uint8_t bits, uint8_t dummy,uint8_t cs,uint8_t sck,uint8_t mosi,uint8_t dc,uint8_t rst)
+{
+    uint32_t ret = 0;
+    uint8_t SDAPIN = mosi;
+    pinMode(SDAPIN, INPUT_PULLUP);
+    digitalWrite(dc, HIGH);
+    for (int i = 0; i < dummy; i++) {  //any dummy clocks
+        digitalWrite(sck, HIGH);
+        delay(1);
+        digitalWrite(sck, LOW);
+        delay(1);
+    }
+    for (int i = 0; i < bits; i++) {  // read results
+        ret <<= 1;
+        delay(1);
+        if (digitalRead(SDAPIN)) ret |= 1;;
+        digitalWrite(sck, HIGH);
+        delay(1);
+        digitalWrite(sck, LOW);
+    }
+    return ret;
+}
+
+void write9(uint8_t val, uint8_t dc_val,uint8_t cs,uint8_t sck,uint8_t mosi,uint8_t dc,uint8_t rst)
+{
+    pinMode(mosi, OUTPUT);
+    digitalWrite(dc, dc_val);
+    for (int i = 0; i < 8; i++) {   //send command
+        digitalWrite(mosi, (val & 0x80) != 0);
+        delay(1);
+        digitalWrite(sck, HIGH);
+        delay(1);
+        digitalWrite(sck, LOW);
+        val <<= 1;
+    }
+}
+
+uint32_t readwrite8(uint8_t cmd, uint8_t bits, uint8_t dummy,uint8_t cs,uint8_t sck,uint8_t mosi,uint8_t dc,uint8_t rst)
+{
+    digitalWrite(cs, LOW);
+    write9(cmd, 0,cs,sck,mosi,dc,rst);
+    uint32_t ret = read8(bits, dummy,cs,sck,mosi,dc,rst);
+    digitalWrite(cs, HIGH);
+    return ret;
+}
+
+uint32_t get_st7789_id(uint8_t cs,uint8_t sck,uint8_t mosi,uint8_t dc,uint8_t rst)
+{
+    pinMode(cs, OUTPUT);
+    digitalWrite(cs, HIGH);
+    pinMode(cs, OUTPUT);
+    pinMode(sck, OUTPUT);
+    pinMode(mosi, OUTPUT);
+    pinMode(dc, OUTPUT);
+    pinMode(rst, OUTPUT);
+    digitalWrite(rst, LOW);   //Hardware Reset
+    delay(10);
+    digitalWrite(rst, HIGH);
+    delay(10);
+
+    uint32_t ID = 0;
+    ID = readwrite8(0x04, 24, 1,cs,sck,mosi,dc,rst);
+    ID = readwrite8(0x04, 24, 1,cs,sck,mosi,dc,rst);  //ST7789 needs twice
+    return ID;
+}
+
+#endif
+
 bool meshtastic_DeviceState_callback(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_iter_t *field)
 {
     if (ostream) {
@@ -489,6 +559,13 @@ void NodeDB::installDefaultConfig(bool preserveKey = false)
 #if defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7789_CS) ||       \
     defined(HX8357_CS) || defined(USE_ST7789)
     bool hasScreen = true;
+#ifdef HELTEC_MESH_NODE_T114
+    uint32_t st7789_id=get_st7789_id(ST7789_NSS,ST7789_SCK,ST7789_SDA,ST7789_RS,ST7789_RESET);
+    if(st7789_id==0xFFFFFF)
+    {
+        hasScreen = false;
+    }
+#endif
 #elif ARCH_PORTDUINO
     bool hasScreen = false;
     if (settingsMap[displayPanel])

From ea72abff22e416b4c813d7ba6810c38d0c2755a4 Mon Sep 17 00:00:00 2001
From: Ben Meadors 
Date: Sat, 14 Dec 2024 20:21:19 -0600
Subject: [PATCH 12/25] Posthumous tronk

---
 src/mesh/NodeDB.cpp | 33 +++++++++++++++++----------------
 1 file changed, 17 insertions(+), 16 deletions(-)

diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp
index 201304395f..7fe5bd6568 100644
--- a/src/mesh/NodeDB.cpp
+++ b/src/mesh/NodeDB.cpp
@@ -72,22 +72,24 @@ static unsigned char userprefs_admin_key_2[] = USERPREFS_USE_ADMIN_KEY_2;
 
 #ifdef HELTEC_MESH_NODE_T114
 
-uint32_t read8(uint8_t bits, uint8_t dummy,uint8_t cs,uint8_t sck,uint8_t mosi,uint8_t dc,uint8_t rst)
+uint32_t read8(uint8_t bits, uint8_t dummy, uint8_t cs, uint8_t sck, uint8_t mosi, uint8_t dc, uint8_t rst)
 {
     uint32_t ret = 0;
     uint8_t SDAPIN = mosi;
     pinMode(SDAPIN, INPUT_PULLUP);
     digitalWrite(dc, HIGH);
-    for (int i = 0; i < dummy; i++) {  //any dummy clocks
+    for (int i = 0; i < dummy; i++) { // any dummy clocks
         digitalWrite(sck, HIGH);
         delay(1);
         digitalWrite(sck, LOW);
         delay(1);
     }
-    for (int i = 0; i < bits; i++) {  // read results
+    for (int i = 0; i < bits; i++) { // read results
         ret <<= 1;
         delay(1);
-        if (digitalRead(SDAPIN)) ret |= 1;;
+        if (digitalRead(SDAPIN))
+            ret |= 1;
+        ;
         digitalWrite(sck, HIGH);
         delay(1);
         digitalWrite(sck, LOW);
@@ -95,11 +97,11 @@ uint32_t read8(uint8_t bits, uint8_t dummy,uint8_t cs,uint8_t sck,uint8_t mosi,u
     return ret;
 }
 
-void write9(uint8_t val, uint8_t dc_val,uint8_t cs,uint8_t sck,uint8_t mosi,uint8_t dc,uint8_t rst)
+void write9(uint8_t val, uint8_t dc_val, uint8_t cs, uint8_t sck, uint8_t mosi, uint8_t dc, uint8_t rst)
 {
     pinMode(mosi, OUTPUT);
     digitalWrite(dc, dc_val);
-    for (int i = 0; i < 8; i++) {   //send command
+    for (int i = 0; i < 8; i++) { // send command
         digitalWrite(mosi, (val & 0x80) != 0);
         delay(1);
         digitalWrite(sck, HIGH);
@@ -109,16 +111,16 @@ void write9(uint8_t val, uint8_t dc_val,uint8_t cs,uint8_t sck,uint8_t mosi,uint
     }
 }
 
-uint32_t readwrite8(uint8_t cmd, uint8_t bits, uint8_t dummy,uint8_t cs,uint8_t sck,uint8_t mosi,uint8_t dc,uint8_t rst)
+uint32_t readwrite8(uint8_t cmd, uint8_t bits, uint8_t dummy, uint8_t cs, uint8_t sck, uint8_t mosi, uint8_t dc, uint8_t rst)
 {
     digitalWrite(cs, LOW);
-    write9(cmd, 0,cs,sck,mosi,dc,rst);
-    uint32_t ret = read8(bits, dummy,cs,sck,mosi,dc,rst);
+    write9(cmd, 0, cs, sck, mosi, dc, rst);
+    uint32_t ret = read8(bits, dummy, cs, sck, mosi, dc, rst);
     digitalWrite(cs, HIGH);
     return ret;
 }
 
-uint32_t get_st7789_id(uint8_t cs,uint8_t sck,uint8_t mosi,uint8_t dc,uint8_t rst)
+uint32_t get_st7789_id(uint8_t cs, uint8_t sck, uint8_t mosi, uint8_t dc, uint8_t rst)
 {
     pinMode(cs, OUTPUT);
     digitalWrite(cs, HIGH);
@@ -127,14 +129,14 @@ uint32_t get_st7789_id(uint8_t cs,uint8_t sck,uint8_t mosi,uint8_t dc,uint8_t rs
     pinMode(mosi, OUTPUT);
     pinMode(dc, OUTPUT);
     pinMode(rst, OUTPUT);
-    digitalWrite(rst, LOW);   //Hardware Reset
+    digitalWrite(rst, LOW); // Hardware Reset
     delay(10);
     digitalWrite(rst, HIGH);
     delay(10);
 
     uint32_t ID = 0;
-    ID = readwrite8(0x04, 24, 1,cs,sck,mosi,dc,rst);
-    ID = readwrite8(0x04, 24, 1,cs,sck,mosi,dc,rst);  //ST7789 needs twice
+    ID = readwrite8(0x04, 24, 1, cs, sck, mosi, dc, rst);
+    ID = readwrite8(0x04, 24, 1, cs, sck, mosi, dc, rst); // ST7789 needs twice
     return ID;
 }
 
@@ -560,9 +562,8 @@ void NodeDB::installDefaultConfig(bool preserveKey = false)
     defined(HX8357_CS) || defined(USE_ST7789)
     bool hasScreen = true;
 #ifdef HELTEC_MESH_NODE_T114
-    uint32_t st7789_id=get_st7789_id(ST7789_NSS,ST7789_SCK,ST7789_SDA,ST7789_RS,ST7789_RESET);
-    if(st7789_id==0xFFFFFF)
-    {
+    uint32_t st7789_id = get_st7789_id(ST7789_NSS, ST7789_SCK, ST7789_SDA, ST7789_RS, ST7789_RESET);
+    if (st7789_id == 0xFFFFFF) {
         hasScreen = false;
     }
 #endif

From 547a57256d7be033a598c713eaf4b41615a67daa Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
 <41898282+github-actions[bot]@users.noreply.github.com>
Date: Sun, 15 Dec 2024 05:23:15 -0600
Subject: [PATCH 13/25] [create-pull-request] automated change (#5577)

Co-authored-by: fifieldt <1287116+fifieldt@users.noreply.github.com>
---
 protobufs                                    | 2 +-
 src/mesh/generated/meshtastic/mesh.pb.h      | 5 +++++
 src/mesh/generated/meshtastic/telemetry.pb.h | 8 +++++---
 3 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/protobufs b/protobufs
index 00c9c9932e..4a4e81951d 160000
--- a/protobufs
+++ b/protobufs
@@ -1 +1 @@
-Subproject commit 00c9c9932ea50c14cdc44d497d2672a0031641ce
+Subproject commit 4a4e81951d64821a96a5131e50d2b44e5356372e
diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h
index da439c375a..2c5213cff3 100644
--- a/src/mesh/generated/meshtastic/mesh.pb.h
+++ b/src/mesh/generated/meshtastic/mesh.pb.h
@@ -220,6 +220,9 @@ typedef enum _meshtastic_HardwareModel {
  the same frame format.
  Runs on linux, see https://github.com/Jorropo/routastic */
     meshtastic_HardwareModel_ROUTASTIC = 85,
+    /* Mesh-Tab, esp32 based
+ https://github.com/valzzu/Mesh-Tab */
+    meshtastic_HardwareModel_MESH_TAB = 86,
     /* ------------------------------------------------------------------------------------------------------------------------------------------
  Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits.
  ------------------------------------------------------------------------------------------------------------------------------------------ */
@@ -414,6 +417,8 @@ typedef enum _meshtastic_MeshPacket_Priority {
     meshtastic_MeshPacket_Priority_RESPONSE = 80,
     /* Higher priority for specific message types (portnums) to distinguish between other reliable packets. */
     meshtastic_MeshPacket_Priority_HIGH = 100,
+    /* Higher priority alert message used for critical alerts which take priority over other reliable packets. */
+    meshtastic_MeshPacket_Priority_ALERT = 110,
     /* Ack/naks are sent with very high priority to ensure that retransmission
  stops as soon as possible */
     meshtastic_MeshPacket_Priority_ACK = 120,
diff --git a/src/mesh/generated/meshtastic/telemetry.pb.h b/src/mesh/generated/meshtastic/telemetry.pb.h
index 874eef60fe..a6102e07dd 100644
--- a/src/mesh/generated/meshtastic/telemetry.pb.h
+++ b/src/mesh/generated/meshtastic/telemetry.pb.h
@@ -79,7 +79,9 @@ typedef enum _meshtastic_TelemetrySensorType {
     /* SCD40/SCD41 CO2, humidity, temperature sensor */
     meshtastic_TelemetrySensorType_SCD4X = 32,
     /* ClimateGuard RadSens, radiation, Geiger-Muller Tube */
-    meshtastic_TelemetrySensorType_RADSENS = 33
+    meshtastic_TelemetrySensorType_RADSENS = 33,
+    /* High accuracy current and voltage */
+    meshtastic_TelemetrySensorType_INA226 = 34
 } meshtastic_TelemetrySensorType;
 
 /* Struct definitions */
@@ -304,8 +306,8 @@ extern "C" {
 
 /* Helper constants for enums */
 #define _meshtastic_TelemetrySensorType_MIN meshtastic_TelemetrySensorType_SENSOR_UNSET
-#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_RADSENS
-#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_RADSENS+1))
+#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_INA226
+#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_INA226+1))
 
 
 

From 56002155c68c90121692b6e327c44aeb96fd2904 Mon Sep 17 00:00:00 2001
From: Tom Fifield 
Date: Sun, 15 Dec 2024 23:23:27 +1100
Subject: [PATCH 14/25] Based default Node Names on NodeNum, rather than MAC
 address (#5576)

Presently we base the default long name (Meshtastic XXXX) and short
names (XXXX) on a node's MAC address. This works fine, unless you
have a node with no bluetooth, like Portduino.

Our logic for node numbers is also based on MAC address. However,
it has the added feature that it will create a random node number
if the Mac address is no good. The name is always "Meshtastic 0001".

This change switches node names (long and short) to instead rely
on the node number for defaults. For nodes with mac addresses,
there should be no user-visible change. For nodes without, they'll
now have a name other than "Meshtastic 0001".

Fixes https://github.com/meshtastic/firmware/issues/5370

Co-authored-by: Ben Meadors 
---
 src/mesh/NodeDB.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp
index 7fe5bd6568..2af85e4f52 100644
--- a/src/mesh/NodeDB.cpp
+++ b/src/mesh/NodeDB.cpp
@@ -852,12 +852,12 @@ void NodeDB::installDefaultDeviceState()
 #ifdef USERPREFS_CONFIG_OWNER_LONG_NAME
     snprintf(owner.long_name, sizeof(owner.long_name), USERPREFS_CONFIG_OWNER_LONG_NAME);
 #else
-    snprintf(owner.long_name, sizeof(owner.long_name), "Meshtastic %02x%02x", ourMacAddr[4], ourMacAddr[5]);
+    snprintf(owner.long_name, sizeof(owner.long_name), "Meshtastic %04x", getNodeNum() & 0x0ffff);
 #endif
 #ifdef USERPREFS_CONFIG_OWNER_SHORT_NAME
     snprintf(owner.short_name, sizeof(owner.short_name), USERPREFS_CONFIG_OWNER_SHORT_NAME);
 #else
-    snprintf(owner.short_name, sizeof(owner.short_name), "%02x%02x", ourMacAddr[4], ourMacAddr[5]);
+    snprintf(owner.short_name, sizeof(owner.short_name), "%04x", getNodeNum() & 0x0ffff);
 #endif
     snprintf(owner.id, sizeof(owner.id), "!%08x", getNodeNum()); // Default node ID now based on nodenum
     memcpy(owner.macaddr, ourMacAddr, sizeof(owner.macaddr));

From 2d45afafe56091b757b7e23839564770ae1dfc1a Mon Sep 17 00:00:00 2001
From: Ben Meadors 
Date: Sun, 15 Dec 2024 06:52:45 -0600
Subject: [PATCH 15/25] Try docker authentication with command-line instead

---
 .github/workflows/build_native.yml | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/.github/workflows/build_native.yml b/.github/workflows/build_native.yml
index d4b0c8d58c..d9591e72c8 100644
--- a/.github/workflows/build_native.yml
+++ b/.github/workflows/build_native.yml
@@ -53,20 +53,18 @@ jobs:
 
       - name: Docker login
         if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
-        uses: docker/login-action@v3
-        continue-on-error: true # FIXME: Failing docker login auth
-        with:
-          username: meshtastic
-          password: ${{ secrets.DOCKER_FIRMWARE_TOKEN }}
+        run: |
+          echo ${{ secrets.DOCKER_FIRMWARE_TOKEN }} | docker login -u meshtastic --password-stdin
+        continue-on-error: true
 
       - name: Docker setup
         if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
-        continue-on-error: true # FIXME: Failing docker login auth
+        continue-on-error: true
         uses: docker/setup-buildx-action@v3
 
       - name: Docker build and push tagged versions
         if: ${{ github.event_name == 'workflow_dispatch' }}
-        continue-on-error: true # FIXME: Failing docker login auth
+        continue-on-error: true
         uses: docker/build-push-action@v6
         with:
           context: .
@@ -76,7 +74,7 @@ jobs:
 
       - name: Docker build and push
         if: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
-        continue-on-error: true # FIXME: Failing docker login auth
+        continue-on-error: true
         uses: docker/build-push-action@v6
         with:
           context: .

From 020e9102a8277a40cbbbb260cbca9582be14fa87 Mon Sep 17 00:00:00 2001
From: Tom Fifield 
Date: Mon, 16 Dec 2024 00:14:48 +1100
Subject: [PATCH 16/25] Define BUTTON_PIN as -1 for RP2040-lora (#5574)

The previous approach of undef'ing meant that it was impossible
for users to change the button pin in the apps.

Fixes https://github.com/meshtastic/firmware/issues/5566
---
 variants/rp2040-lora/variant.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/variants/rp2040-lora/variant.h b/variants/rp2040-lora/variant.h
index f1826605f5..92b0674573 100644
--- a/variants/rp2040-lora/variant.h
+++ b/variants/rp2040-lora/variant.h
@@ -15,7 +15,7 @@
 // rxd = 9
 
 #define EXT_NOTIFY_OUT 22
-#undef BUTTON_PIN // Pin 17 used for antenna switching via DIO4
+#define BUTTON_PIN -1 // Pin 17 used for antenna switching via DIO4
 
 #define LED_PIN PIN_LED
 
@@ -57,4 +57,4 @@
 #define SX126X_DIO2_AS_RF_SWITCH // Antenna switch CTRL
 #define SX126X_RXEN LORA_DIO4    // Antenna switch !CTRL via GPIO17
 // #define SX126X_DIO3_TCXO_VOLTAGE 1.8
-#endif
\ No newline at end of file
+#endif

From 09c082fd004423374f1decd880ee7a448d6e3999 Mon Sep 17 00:00:00 2001
From: Ben Meadors 
Date: Sun, 15 Dec 2024 09:59:14 -0600
Subject: [PATCH 17/25] Fix omission of AQ metrics (#5584)

---
 src/modules/Telemetry/AirQualityTelemetry.cpp | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/modules/Telemetry/AirQualityTelemetry.cpp b/src/modules/Telemetry/AirQualityTelemetry.cpp
index 362d60252f..6a8077f033 100644
--- a/src/modules/Telemetry/AirQualityTelemetry.cpp
+++ b/src/modules/Telemetry/AirQualityTelemetry.cpp
@@ -113,12 +113,18 @@ bool AirQualityTelemetryModule::getAirQualityTelemetry(meshtastic_Telemetry *m)
 
     m->time = getTime();
     m->which_variant = meshtastic_Telemetry_air_quality_metrics_tag;
+    m->variant.air_quality_metrics.has_pm10_standard = true;
     m->variant.air_quality_metrics.pm10_standard = data.pm10_standard;
+    m->variant.air_quality_metrics.has_pm25_standard = true;
     m->variant.air_quality_metrics.pm25_standard = data.pm25_standard;
+    m->variant.air_quality_metrics.has_pm100_standard = true;
     m->variant.air_quality_metrics.pm100_standard = data.pm100_standard;
 
+    m->variant.air_quality_metrics.has_pm10_environmental = true;
     m->variant.air_quality_metrics.pm10_environmental = data.pm10_env;
+    m->variant.air_quality_metrics.has_pm25_environmental = true;
     m->variant.air_quality_metrics.pm25_environmental = data.pm25_env;
+    m->variant.air_quality_metrics.has_pm100_environmental = true;
     m->variant.air_quality_metrics.pm100_environmental = data.pm100_env;
 
     LOG_INFO("Send: PM1.0(Standard)=%i, PM2.5(Standard)=%i, PM10.0(Standard)=%i", m->variant.air_quality_metrics.pm10_standard,

From 69d01a8088d89753cea18502e44777764774d765 Mon Sep 17 00:00:00 2001
From: GUVWAF <78759985+GUVWAF@users.noreply.github.com>
Date: Sun, 15 Dec 2024 20:11:13 +0100
Subject: [PATCH 18/25] StoreForward: (tapback) reply support (#5585)

---
 src/modules/StoreForwardModule.cpp | 12 +++++++++---
 src/modules/StoreForwardModule.h   |  3 +++
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/src/modules/StoreForwardModule.cpp b/src/modules/StoreForwardModule.cpp
index 4cf06f5d25..0a6e1b4c49 100644
--- a/src/modules/StoreForwardModule.cpp
+++ b/src/modules/StoreForwardModule.cpp
@@ -73,11 +73,11 @@ void StoreForwardModule::populatePSRAM()
     LOG_DEBUG("Before PSRAM init: heap %d/%d PSRAM %d/%d", memGet.getFreeHeap(), memGet.getHeapSize(), memGet.getFreePsram(),
               memGet.getPsramSize());
 
-    /* Use a maximum of 2/3 the available PSRAM unless otherwise specified.
+    /* Use a maximum of 3/4 the available PSRAM unless otherwise specified.
         Note: This needs to be done after every thing that would use PSRAM
     */
     uint32_t numberOfPackets =
-        (this->records ? this->records : (((memGet.getFreePsram() / 3) * 2) / sizeof(PacketHistoryStruct)));
+        (this->records ? this->records : (((memGet.getFreePsram() / 4) * 3) / sizeof(PacketHistoryStruct)));
     this->records = numberOfPackets;
 #if defined(ARCH_ESP32)
     this->packetHistory = static_cast(ps_calloc(numberOfPackets, sizeof(PacketHistoryStruct)));
@@ -198,6 +198,9 @@ void StoreForwardModule::historyAdd(const meshtastic_MeshPacket &mp)
     this->packetHistory[this->packetHistoryTotalCount].to = mp.to;
     this->packetHistory[this->packetHistoryTotalCount].channel = mp.channel;
     this->packetHistory[this->packetHistoryTotalCount].from = getFrom(&mp);
+    this->packetHistory[this->packetHistoryTotalCount].id = mp.id;
+    this->packetHistory[this->packetHistoryTotalCount].reply_id = p.reply_id;
+    this->packetHistory[this->packetHistoryTotalCount].emoji = (bool)p.emoji;
     this->packetHistory[this->packetHistoryTotalCount].payload_size = p.payload.size;
     memcpy(this->packetHistory[this->packetHistoryTotalCount].payload, p.payload.bytes, meshtastic_Constants_DATA_PAYLOAD_LEN);
 
@@ -244,8 +247,11 @@ meshtastic_MeshPacket *StoreForwardModule::preparePayload(NodeNum dest, uint32_t
 
                 p->to = local ? this->packetHistory[i].to : dest; // PhoneAPI can handle original `to`
                 p->from = this->packetHistory[i].from;
+                p->id = this->packetHistory[i].id;
                 p->channel = this->packetHistory[i].channel;
+                p->decoded.reply_id = this->packetHistory[i].reply_id;
                 p->rx_time = this->packetHistory[i].time;
+                p->decoded.emoji = (uint32_t)this->packetHistory[i].emoji;
 
                 // Let's assume that if the server received the S&F request that the client is in range.
                 //   TODO: Make this configurable.
@@ -617,4 +623,4 @@ StoreForwardModule::StoreForwardModule()
         disable();
     }
 #endif
-}
+}
\ No newline at end of file
diff --git a/src/modules/StoreForwardModule.h b/src/modules/StoreForwardModule.h
index e3273470b6..30db1625cf 100644
--- a/src/modules/StoreForwardModule.h
+++ b/src/modules/StoreForwardModule.h
@@ -13,7 +13,10 @@ struct PacketHistoryStruct {
     uint32_t time;
     uint32_t to;
     uint32_t from;
+    uint32_t id;
     uint8_t channel;
+    uint32_t reply_id;
+    bool emoji;
     uint8_t payload[meshtastic_Constants_DATA_PAYLOAD_LEN];
     pb_size_t payload_size;
 };

From 1b2fc00b99f18c55f3643d6853505f35d0e9aec6 Mon Sep 17 00:00:00 2001
From: Ben Meadors 
Date: Tue, 17 Dec 2024 05:45:31 -0600
Subject: [PATCH 19/25] Update main_matrix.yml

---
 .github/workflows/main_matrix.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml
index 37164b7589..86fb6e6991 100644
--- a/.github/workflows/main_matrix.yml
+++ b/.github/workflows/main_matrix.yml
@@ -37,7 +37,7 @@ jobs:
           else  
             TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}} quick)
           fi
-          echo "Name: ${{ github.ref_name }} Base: ${{ github.base_ref }} Head: ${{ github.head_ref }} Ref: ${{ github.ref }} Targets: $TARGETS"
+          echo "Name: ${{ github.ref_name }} Base: ${{ github.base_ref }} } Ref: ${{ github.ref }} Targets: $TARGETS"
           echo "${{matrix.arch}}=$(jq -cn --argjson environments "$TARGETS" '{board: $environments}')" >> $GITHUB_OUTPUT
     outputs:
       esp32: ${{ steps.jsonStep.outputs.esp32 }}

From b0a4087a0c4fc1b6aedbe2ae41291378291437b2 Mon Sep 17 00:00:00 2001
From: Ben Meadors 
Date: Tue, 17 Dec 2024 06:12:23 -0600
Subject: [PATCH 20/25] Bump nano-pb

---
 .github/workflows/update_protobufs.yml | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/update_protobufs.yml b/.github/workflows/update_protobufs.yml
index f1c92b8604..2732ab7603 100644
--- a/.github/workflows/update_protobufs.yml
+++ b/.github/workflows/update_protobufs.yml
@@ -17,9 +17,9 @@ jobs:
 
       - name: Download nanopb
         run: |
-          wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.9-linux-x86.tar.gz
-          tar xvzf nanopb-0.4.9-linux-x86.tar.gz
-          mv nanopb-0.4.9-linux-x86 nanopb-0.4.9
+          wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.9.1-linux-x86.tar.gz
+          tar xvzf nanopb-0.4.9.1-linux-x86.tar.gz
+          mv nanopb-0.4.9.1-linux-x86 nanopb-0.4.9
 
       - name: Re-generate protocol buffers
         run: |

From 92511ab10b0d97735fb7dd1bd6234808cfc3ab95 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
 <41898282+github-actions[bot]@users.noreply.github.com>
Date: Tue, 17 Dec 2024 06:33:17 -0600
Subject: [PATCH 21/25] [create-pull-request] automated change (#5597)

Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
---
 protobufs                                              | 2 +-
 src/mesh/generated/meshtastic/admin.pb.cpp             | 2 +-
 src/mesh/generated/meshtastic/admin.pb.h               | 2 +-
 src/mesh/generated/meshtastic/apponly.pb.cpp           | 2 +-
 src/mesh/generated/meshtastic/apponly.pb.h             | 2 +-
 src/mesh/generated/meshtastic/atak.pb.cpp              | 2 +-
 src/mesh/generated/meshtastic/atak.pb.h                | 2 +-
 src/mesh/generated/meshtastic/cannedmessages.pb.cpp    | 2 +-
 src/mesh/generated/meshtastic/cannedmessages.pb.h      | 2 +-
 src/mesh/generated/meshtastic/channel.pb.cpp           | 2 +-
 src/mesh/generated/meshtastic/channel.pb.h             | 2 +-
 src/mesh/generated/meshtastic/clientonly.pb.cpp        | 2 +-
 src/mesh/generated/meshtastic/clientonly.pb.h          | 2 +-
 src/mesh/generated/meshtastic/config.pb.cpp            | 2 +-
 src/mesh/generated/meshtastic/config.pb.h              | 2 +-
 src/mesh/generated/meshtastic/connection_status.pb.cpp | 2 +-
 src/mesh/generated/meshtastic/connection_status.pb.h   | 2 +-
 src/mesh/generated/meshtastic/device_ui.pb.cpp         | 2 +-
 src/mesh/generated/meshtastic/device_ui.pb.h           | 2 +-
 src/mesh/generated/meshtastic/deviceonly.pb.cpp        | 2 +-
 src/mesh/generated/meshtastic/deviceonly.pb.h          | 2 +-
 src/mesh/generated/meshtastic/localonly.pb.cpp         | 2 +-
 src/mesh/generated/meshtastic/localonly.pb.h           | 2 +-
 src/mesh/generated/meshtastic/mesh.pb.cpp              | 2 +-
 src/mesh/generated/meshtastic/mesh.pb.h                | 2 +-
 src/mesh/generated/meshtastic/module_config.pb.cpp     | 2 +-
 src/mesh/generated/meshtastic/module_config.pb.h       | 2 +-
 src/mesh/generated/meshtastic/mqtt.pb.cpp              | 2 +-
 src/mesh/generated/meshtastic/mqtt.pb.h                | 2 +-
 src/mesh/generated/meshtastic/paxcount.pb.cpp          | 2 +-
 src/mesh/generated/meshtastic/paxcount.pb.h            | 2 +-
 src/mesh/generated/meshtastic/portnums.pb.cpp          | 2 +-
 src/mesh/generated/meshtastic/portnums.pb.h            | 4 +++-
 src/mesh/generated/meshtastic/powermon.pb.cpp          | 2 +-
 src/mesh/generated/meshtastic/powermon.pb.h            | 2 +-
 src/mesh/generated/meshtastic/remote_hardware.pb.cpp   | 2 +-
 src/mesh/generated/meshtastic/remote_hardware.pb.h     | 2 +-
 src/mesh/generated/meshtastic/rtttl.pb.cpp             | 2 +-
 src/mesh/generated/meshtastic/rtttl.pb.h               | 2 +-
 src/mesh/generated/meshtastic/storeforward.pb.cpp      | 2 +-
 src/mesh/generated/meshtastic/storeforward.pb.h        | 2 +-
 src/mesh/generated/meshtastic/telemetry.pb.cpp         | 2 +-
 src/mesh/generated/meshtastic/telemetry.pb.h           | 2 +-
 src/mesh/generated/meshtastic/xmodem.pb.cpp            | 2 +-
 src/mesh/generated/meshtastic/xmodem.pb.h              | 2 +-
 45 files changed, 47 insertions(+), 45 deletions(-)

diff --git a/protobufs b/protobufs
index 4a4e81951d..2cffaf53e3 160000
--- a/protobufs
+++ b/protobufs
@@ -1 +1 @@
-Subproject commit 4a4e81951d64821a96a5131e50d2b44e5356372e
+Subproject commit 2cffaf53e3faf1b6e41a8b8f05312f2f893be413
diff --git a/src/mesh/generated/meshtastic/admin.pb.cpp b/src/mesh/generated/meshtastic/admin.pb.cpp
index 8b3fd3d1bc..7ce3c74ceb 100644
--- a/src/mesh/generated/meshtastic/admin.pb.cpp
+++ b/src/mesh/generated/meshtastic/admin.pb.cpp
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb constant definitions */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #include "meshtastic/admin.pb.h"
 #if PB_PROTO_HEADER_VERSION != 40
diff --git a/src/mesh/generated/meshtastic/admin.pb.h b/src/mesh/generated/meshtastic/admin.pb.h
index bbf633ef58..d9b8de384c 100644
--- a/src/mesh/generated/meshtastic/admin.pb.h
+++ b/src/mesh/generated/meshtastic/admin.pb.h
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb header */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #ifndef PB_MESHTASTIC_MESHTASTIC_ADMIN_PB_H_INCLUDED
 #define PB_MESHTASTIC_MESHTASTIC_ADMIN_PB_H_INCLUDED
diff --git a/src/mesh/generated/meshtastic/apponly.pb.cpp b/src/mesh/generated/meshtastic/apponly.pb.cpp
index 64d43b7ee1..8b1b3da19e 100644
--- a/src/mesh/generated/meshtastic/apponly.pb.cpp
+++ b/src/mesh/generated/meshtastic/apponly.pb.cpp
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb constant definitions */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #include "meshtastic/apponly.pb.h"
 #if PB_PROTO_HEADER_VERSION != 40
diff --git a/src/mesh/generated/meshtastic/apponly.pb.h b/src/mesh/generated/meshtastic/apponly.pb.h
index dc08d9ff35..f4c33bd793 100644
--- a/src/mesh/generated/meshtastic/apponly.pb.h
+++ b/src/mesh/generated/meshtastic/apponly.pb.h
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb header */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #ifndef PB_MESHTASTIC_MESHTASTIC_APPONLY_PB_H_INCLUDED
 #define PB_MESHTASTIC_MESHTASTIC_APPONLY_PB_H_INCLUDED
diff --git a/src/mesh/generated/meshtastic/atak.pb.cpp b/src/mesh/generated/meshtastic/atak.pb.cpp
index 6dbc69fb4c..a0368cf6b2 100644
--- a/src/mesh/generated/meshtastic/atak.pb.cpp
+++ b/src/mesh/generated/meshtastic/atak.pb.cpp
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb constant definitions */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #include "meshtastic/atak.pb.h"
 #if PB_PROTO_HEADER_VERSION != 40
diff --git a/src/mesh/generated/meshtastic/atak.pb.h b/src/mesh/generated/meshtastic/atak.pb.h
index 15a86788b3..8533bcbf9d 100644
--- a/src/mesh/generated/meshtastic/atak.pb.h
+++ b/src/mesh/generated/meshtastic/atak.pb.h
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb header */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #ifndef PB_MESHTASTIC_MESHTASTIC_ATAK_PB_H_INCLUDED
 #define PB_MESHTASTIC_MESHTASTIC_ATAK_PB_H_INCLUDED
diff --git a/src/mesh/generated/meshtastic/cannedmessages.pb.cpp b/src/mesh/generated/meshtastic/cannedmessages.pb.cpp
index 9f51e9634d..1f4ebc9271 100644
--- a/src/mesh/generated/meshtastic/cannedmessages.pb.cpp
+++ b/src/mesh/generated/meshtastic/cannedmessages.pb.cpp
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb constant definitions */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #include "meshtastic/cannedmessages.pb.h"
 #if PB_PROTO_HEADER_VERSION != 40
diff --git a/src/mesh/generated/meshtastic/cannedmessages.pb.h b/src/mesh/generated/meshtastic/cannedmessages.pb.h
index 06d14b98f4..8343c4d6eb 100644
--- a/src/mesh/generated/meshtastic/cannedmessages.pb.h
+++ b/src/mesh/generated/meshtastic/cannedmessages.pb.h
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb header */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #ifndef PB_MESHTASTIC_MESHTASTIC_CANNEDMESSAGES_PB_H_INCLUDED
 #define PB_MESHTASTIC_MESHTASTIC_CANNEDMESSAGES_PB_H_INCLUDED
diff --git a/src/mesh/generated/meshtastic/channel.pb.cpp b/src/mesh/generated/meshtastic/channel.pb.cpp
index 52f923b135..6670a40fc1 100644
--- a/src/mesh/generated/meshtastic/channel.pb.cpp
+++ b/src/mesh/generated/meshtastic/channel.pb.cpp
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb constant definitions */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #include "meshtastic/channel.pb.h"
 #if PB_PROTO_HEADER_VERSION != 40
diff --git a/src/mesh/generated/meshtastic/channel.pb.h b/src/mesh/generated/meshtastic/channel.pb.h
index 3d617ae39e..ca4310bf12 100644
--- a/src/mesh/generated/meshtastic/channel.pb.h
+++ b/src/mesh/generated/meshtastic/channel.pb.h
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb header */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #ifndef PB_MESHTASTIC_MESHTASTIC_CHANNEL_PB_H_INCLUDED
 #define PB_MESHTASTIC_MESHTASTIC_CHANNEL_PB_H_INCLUDED
diff --git a/src/mesh/generated/meshtastic/clientonly.pb.cpp b/src/mesh/generated/meshtastic/clientonly.pb.cpp
index d99af8cf5d..8f380a9720 100644
--- a/src/mesh/generated/meshtastic/clientonly.pb.cpp
+++ b/src/mesh/generated/meshtastic/clientonly.pb.cpp
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb constant definitions */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #include "meshtastic/clientonly.pb.h"
 #if PB_PROTO_HEADER_VERSION != 40
diff --git a/src/mesh/generated/meshtastic/clientonly.pb.h b/src/mesh/generated/meshtastic/clientonly.pb.h
index bf32d78756..5109e20b20 100644
--- a/src/mesh/generated/meshtastic/clientonly.pb.h
+++ b/src/mesh/generated/meshtastic/clientonly.pb.h
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb header */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #ifndef PB_MESHTASTIC_MESHTASTIC_CLIENTONLY_PB_H_INCLUDED
 #define PB_MESHTASTIC_MESHTASTIC_CLIENTONLY_PB_H_INCLUDED
diff --git a/src/mesh/generated/meshtastic/config.pb.cpp b/src/mesh/generated/meshtastic/config.pb.cpp
index 23f4d542b9..6fd2161ae9 100644
--- a/src/mesh/generated/meshtastic/config.pb.cpp
+++ b/src/mesh/generated/meshtastic/config.pb.cpp
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb constant definitions */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #include "meshtastic/config.pb.h"
 #if PB_PROTO_HEADER_VERSION != 40
diff --git a/src/mesh/generated/meshtastic/config.pb.h b/src/mesh/generated/meshtastic/config.pb.h
index fab23ae34f..8e2264e936 100644
--- a/src/mesh/generated/meshtastic/config.pb.h
+++ b/src/mesh/generated/meshtastic/config.pb.h
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb header */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #ifndef PB_MESHTASTIC_MESHTASTIC_CONFIG_PB_H_INCLUDED
 #define PB_MESHTASTIC_MESHTASTIC_CONFIG_PB_H_INCLUDED
diff --git a/src/mesh/generated/meshtastic/connection_status.pb.cpp b/src/mesh/generated/meshtastic/connection_status.pb.cpp
index d1495bb832..b0df459ad3 100644
--- a/src/mesh/generated/meshtastic/connection_status.pb.cpp
+++ b/src/mesh/generated/meshtastic/connection_status.pb.cpp
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb constant definitions */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #include "meshtastic/connection_status.pb.h"
 #if PB_PROTO_HEADER_VERSION != 40
diff --git a/src/mesh/generated/meshtastic/connection_status.pb.h b/src/mesh/generated/meshtastic/connection_status.pb.h
index c433e370b1..55559dcefb 100644
--- a/src/mesh/generated/meshtastic/connection_status.pb.h
+++ b/src/mesh/generated/meshtastic/connection_status.pb.h
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb header */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #ifndef PB_MESHTASTIC_MESHTASTIC_CONNECTION_STATUS_PB_H_INCLUDED
 #define PB_MESHTASTIC_MESHTASTIC_CONNECTION_STATUS_PB_H_INCLUDED
diff --git a/src/mesh/generated/meshtastic/device_ui.pb.cpp b/src/mesh/generated/meshtastic/device_ui.pb.cpp
index 6e0cf0cc8b..3a9e28725a 100644
--- a/src/mesh/generated/meshtastic/device_ui.pb.cpp
+++ b/src/mesh/generated/meshtastic/device_ui.pb.cpp
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb constant definitions */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #include "meshtastic/device_ui.pb.h"
 #if PB_PROTO_HEADER_VERSION != 40
diff --git a/src/mesh/generated/meshtastic/device_ui.pb.h b/src/mesh/generated/meshtastic/device_ui.pb.h
index 107aa88462..0c4f5384e1 100644
--- a/src/mesh/generated/meshtastic/device_ui.pb.h
+++ b/src/mesh/generated/meshtastic/device_ui.pb.h
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb header */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #ifndef PB_MESHTASTIC_MESHTASTIC_DEVICE_UI_PB_H_INCLUDED
 #define PB_MESHTASTIC_MESHTASTIC_DEVICE_UI_PB_H_INCLUDED
diff --git a/src/mesh/generated/meshtastic/deviceonly.pb.cpp b/src/mesh/generated/meshtastic/deviceonly.pb.cpp
index 92853f00dd..aa020467aa 100644
--- a/src/mesh/generated/meshtastic/deviceonly.pb.cpp
+++ b/src/mesh/generated/meshtastic/deviceonly.pb.cpp
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb constant definitions */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #include "meshtastic/deviceonly.pb.h"
 #if PB_PROTO_HEADER_VERSION != 40
diff --git a/src/mesh/generated/meshtastic/deviceonly.pb.h b/src/mesh/generated/meshtastic/deviceonly.pb.h
index e52a914e02..c0a0fee91b 100644
--- a/src/mesh/generated/meshtastic/deviceonly.pb.h
+++ b/src/mesh/generated/meshtastic/deviceonly.pb.h
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb header */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #ifndef PB_MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_INCLUDED
 #define PB_MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_INCLUDED
diff --git a/src/mesh/generated/meshtastic/localonly.pb.cpp b/src/mesh/generated/meshtastic/localonly.pb.cpp
index 0a752a5a80..34391df73e 100644
--- a/src/mesh/generated/meshtastic/localonly.pb.cpp
+++ b/src/mesh/generated/meshtastic/localonly.pb.cpp
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb constant definitions */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #include "meshtastic/localonly.pb.h"
 #if PB_PROTO_HEADER_VERSION != 40
diff --git a/src/mesh/generated/meshtastic/localonly.pb.h b/src/mesh/generated/meshtastic/localonly.pb.h
index 8f92b2a778..30f70ed901 100644
--- a/src/mesh/generated/meshtastic/localonly.pb.h
+++ b/src/mesh/generated/meshtastic/localonly.pb.h
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb header */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #ifndef PB_MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_INCLUDED
 #define PB_MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_INCLUDED
diff --git a/src/mesh/generated/meshtastic/mesh.pb.cpp b/src/mesh/generated/meshtastic/mesh.pb.cpp
index a9f42f9793..6c5c7a4be2 100644
--- a/src/mesh/generated/meshtastic/mesh.pb.cpp
+++ b/src/mesh/generated/meshtastic/mesh.pb.cpp
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb constant definitions */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #include "meshtastic/mesh.pb.h"
 #if PB_PROTO_HEADER_VERSION != 40
diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h
index 2c5213cff3..14ed76f70c 100644
--- a/src/mesh/generated/meshtastic/mesh.pb.h
+++ b/src/mesh/generated/meshtastic/mesh.pb.h
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb header */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #ifndef PB_MESHTASTIC_MESHTASTIC_MESH_PB_H_INCLUDED
 #define PB_MESHTASTIC_MESHTASTIC_MESH_PB_H_INCLUDED
diff --git a/src/mesh/generated/meshtastic/module_config.pb.cpp b/src/mesh/generated/meshtastic/module_config.pb.cpp
index c40041eabd..9843f0e91f 100644
--- a/src/mesh/generated/meshtastic/module_config.pb.cpp
+++ b/src/mesh/generated/meshtastic/module_config.pb.cpp
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb constant definitions */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #include "meshtastic/module_config.pb.h"
 #if PB_PROTO_HEADER_VERSION != 40
diff --git a/src/mesh/generated/meshtastic/module_config.pb.h b/src/mesh/generated/meshtastic/module_config.pb.h
index 8f7bb701da..697b965c55 100644
--- a/src/mesh/generated/meshtastic/module_config.pb.h
+++ b/src/mesh/generated/meshtastic/module_config.pb.h
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb header */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #ifndef PB_MESHTASTIC_MESHTASTIC_MODULE_CONFIG_PB_H_INCLUDED
 #define PB_MESHTASTIC_MESHTASTIC_MODULE_CONFIG_PB_H_INCLUDED
diff --git a/src/mesh/generated/meshtastic/mqtt.pb.cpp b/src/mesh/generated/meshtastic/mqtt.pb.cpp
index 74536cb79d..2c32ef2e47 100644
--- a/src/mesh/generated/meshtastic/mqtt.pb.cpp
+++ b/src/mesh/generated/meshtastic/mqtt.pb.cpp
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb constant definitions */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #include "meshtastic/mqtt.pb.h"
 #if PB_PROTO_HEADER_VERSION != 40
diff --git a/src/mesh/generated/meshtastic/mqtt.pb.h b/src/mesh/generated/meshtastic/mqtt.pb.h
index 4d10273740..1726bc470c 100644
--- a/src/mesh/generated/meshtastic/mqtt.pb.h
+++ b/src/mesh/generated/meshtastic/mqtt.pb.h
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb header */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #ifndef PB_MESHTASTIC_MESHTASTIC_MQTT_PB_H_INCLUDED
 #define PB_MESHTASTIC_MESHTASTIC_MQTT_PB_H_INCLUDED
diff --git a/src/mesh/generated/meshtastic/paxcount.pb.cpp b/src/mesh/generated/meshtastic/paxcount.pb.cpp
index 4032881471..ff738bde90 100644
--- a/src/mesh/generated/meshtastic/paxcount.pb.cpp
+++ b/src/mesh/generated/meshtastic/paxcount.pb.cpp
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb constant definitions */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #include "meshtastic/paxcount.pb.h"
 #if PB_PROTO_HEADER_VERSION != 40
diff --git a/src/mesh/generated/meshtastic/paxcount.pb.h b/src/mesh/generated/meshtastic/paxcount.pb.h
index b6b51fdd5e..06078aef79 100644
--- a/src/mesh/generated/meshtastic/paxcount.pb.h
+++ b/src/mesh/generated/meshtastic/paxcount.pb.h
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb header */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #ifndef PB_MESHTASTIC_MESHTASTIC_PAXCOUNT_PB_H_INCLUDED
 #define PB_MESHTASTIC_MESHTASTIC_PAXCOUNT_PB_H_INCLUDED
diff --git a/src/mesh/generated/meshtastic/portnums.pb.cpp b/src/mesh/generated/meshtastic/portnums.pb.cpp
index 8fca9af793..15a6ba372f 100644
--- a/src/mesh/generated/meshtastic/portnums.pb.cpp
+++ b/src/mesh/generated/meshtastic/portnums.pb.cpp
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb constant definitions */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #include "meshtastic/portnums.pb.h"
 #if PB_PROTO_HEADER_VERSION != 40
diff --git a/src/mesh/generated/meshtastic/portnums.pb.h b/src/mesh/generated/meshtastic/portnums.pb.h
index df6cf32c22..d7dc47785b 100644
--- a/src/mesh/generated/meshtastic/portnums.pb.h
+++ b/src/mesh/generated/meshtastic/portnums.pb.h
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb header */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #ifndef PB_MESHTASTIC_MESHTASTIC_PORTNUMS_PB_H_INCLUDED
 #define PB_MESHTASTIC_MESHTASTIC_PORTNUMS_PB_H_INCLUDED
@@ -72,6 +72,8 @@ typedef enum _meshtastic_PortNum {
     /* Same as Text Message but originating from Detection Sensor Module.
  NOTE: This portnum traffic is not sent to the public MQTT starting at firmware version 2.2.9 */
     meshtastic_PortNum_DETECTION_SENSOR_APP = 10,
+    /* Same as Text Message but used for critical alerts. */
+    meshtastic_PortNum_ALERT_APP = 11,
     /* Provides a 'ping' service that replies to any packet it receives.
  Also serves as a small example module.
  ENCODING: ASCII Plaintext */
diff --git a/src/mesh/generated/meshtastic/powermon.pb.cpp b/src/mesh/generated/meshtastic/powermon.pb.cpp
index 6a9b7551ad..8838e165fc 100644
--- a/src/mesh/generated/meshtastic/powermon.pb.cpp
+++ b/src/mesh/generated/meshtastic/powermon.pb.cpp
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb constant definitions */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #include "meshtastic/powermon.pb.h"
 #if PB_PROTO_HEADER_VERSION != 40
diff --git a/src/mesh/generated/meshtastic/powermon.pb.h b/src/mesh/generated/meshtastic/powermon.pb.h
index 5add85b852..9d4d94193c 100644
--- a/src/mesh/generated/meshtastic/powermon.pb.h
+++ b/src/mesh/generated/meshtastic/powermon.pb.h
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb header */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #ifndef PB_MESHTASTIC_MESHTASTIC_POWERMON_PB_H_INCLUDED
 #define PB_MESHTASTIC_MESHTASTIC_POWERMON_PB_H_INCLUDED
diff --git a/src/mesh/generated/meshtastic/remote_hardware.pb.cpp b/src/mesh/generated/meshtastic/remote_hardware.pb.cpp
index 239950e7ef..8942104b5a 100644
--- a/src/mesh/generated/meshtastic/remote_hardware.pb.cpp
+++ b/src/mesh/generated/meshtastic/remote_hardware.pb.cpp
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb constant definitions */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #include "meshtastic/remote_hardware.pb.h"
 #if PB_PROTO_HEADER_VERSION != 40
diff --git a/src/mesh/generated/meshtastic/remote_hardware.pb.h b/src/mesh/generated/meshtastic/remote_hardware.pb.h
index ade250e932..9ab3413c3f 100644
--- a/src/mesh/generated/meshtastic/remote_hardware.pb.h
+++ b/src/mesh/generated/meshtastic/remote_hardware.pb.h
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb header */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #ifndef PB_MESHTASTIC_MESHTASTIC_REMOTE_HARDWARE_PB_H_INCLUDED
 #define PB_MESHTASTIC_MESHTASTIC_REMOTE_HARDWARE_PB_H_INCLUDED
diff --git a/src/mesh/generated/meshtastic/rtttl.pb.cpp b/src/mesh/generated/meshtastic/rtttl.pb.cpp
index 61ad8b73f6..c994741f34 100644
--- a/src/mesh/generated/meshtastic/rtttl.pb.cpp
+++ b/src/mesh/generated/meshtastic/rtttl.pb.cpp
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb constant definitions */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #include "meshtastic/rtttl.pb.h"
 #if PB_PROTO_HEADER_VERSION != 40
diff --git a/src/mesh/generated/meshtastic/rtttl.pb.h b/src/mesh/generated/meshtastic/rtttl.pb.h
index 0572265f7a..b6e152dbf8 100644
--- a/src/mesh/generated/meshtastic/rtttl.pb.h
+++ b/src/mesh/generated/meshtastic/rtttl.pb.h
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb header */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #ifndef PB_MESHTASTIC_MESHTASTIC_RTTTL_PB_H_INCLUDED
 #define PB_MESHTASTIC_MESHTASTIC_RTTTL_PB_H_INCLUDED
diff --git a/src/mesh/generated/meshtastic/storeforward.pb.cpp b/src/mesh/generated/meshtastic/storeforward.pb.cpp
index 71a232bf61..82db566a19 100644
--- a/src/mesh/generated/meshtastic/storeforward.pb.cpp
+++ b/src/mesh/generated/meshtastic/storeforward.pb.cpp
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb constant definitions */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #include "meshtastic/storeforward.pb.h"
 #if PB_PROTO_HEADER_VERSION != 40
diff --git a/src/mesh/generated/meshtastic/storeforward.pb.h b/src/mesh/generated/meshtastic/storeforward.pb.h
index 44ffd098c7..75cff52058 100644
--- a/src/mesh/generated/meshtastic/storeforward.pb.h
+++ b/src/mesh/generated/meshtastic/storeforward.pb.h
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb header */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #ifndef PB_MESHTASTIC_MESHTASTIC_STOREFORWARD_PB_H_INCLUDED
 #define PB_MESHTASTIC_MESHTASTIC_STOREFORWARD_PB_H_INCLUDED
diff --git a/src/mesh/generated/meshtastic/telemetry.pb.cpp b/src/mesh/generated/meshtastic/telemetry.pb.cpp
index f6d39da6eb..c79941fa5d 100644
--- a/src/mesh/generated/meshtastic/telemetry.pb.cpp
+++ b/src/mesh/generated/meshtastic/telemetry.pb.cpp
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb constant definitions */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #include "meshtastic/telemetry.pb.h"
 #if PB_PROTO_HEADER_VERSION != 40
diff --git a/src/mesh/generated/meshtastic/telemetry.pb.h b/src/mesh/generated/meshtastic/telemetry.pb.h
index a6102e07dd..85fe4bdc10 100644
--- a/src/mesh/generated/meshtastic/telemetry.pb.h
+++ b/src/mesh/generated/meshtastic/telemetry.pb.h
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb header */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #ifndef PB_MESHTASTIC_MESHTASTIC_TELEMETRY_PB_H_INCLUDED
 #define PB_MESHTASTIC_MESHTASTIC_TELEMETRY_PB_H_INCLUDED
diff --git a/src/mesh/generated/meshtastic/xmodem.pb.cpp b/src/mesh/generated/meshtastic/xmodem.pb.cpp
index 3960ccdaa0..09ae41d35b 100644
--- a/src/mesh/generated/meshtastic/xmodem.pb.cpp
+++ b/src/mesh/generated/meshtastic/xmodem.pb.cpp
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb constant definitions */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #include "meshtastic/xmodem.pb.h"
 #if PB_PROTO_HEADER_VERSION != 40
diff --git a/src/mesh/generated/meshtastic/xmodem.pb.h b/src/mesh/generated/meshtastic/xmodem.pb.h
index 76edc0df65..3410fda0f4 100644
--- a/src/mesh/generated/meshtastic/xmodem.pb.h
+++ b/src/mesh/generated/meshtastic/xmodem.pb.h
@@ -1,5 +1,5 @@
 /* Automatically generated nanopb header */
-/* Generated by nanopb-0.4.9 */
+/* Generated by nanopb-0.4.9.1 */
 
 #ifndef PB_MESHTASTIC_MESHTASTIC_XMODEM_PB_H_INCLUDED
 #define PB_MESHTASTIC_MESHTASTIC_XMODEM_PB_H_INCLUDED

From b0e3039732059aba7714ffb61039c75220bde7aa Mon Sep 17 00:00:00 2001
From: Ben Meadors 
Date: Tue, 17 Dec 2024 06:52:26 -0600
Subject: [PATCH 22/25] Bump platform

---
 arch/nrf52/nrf52.ini | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/nrf52/nrf52.ini b/arch/nrf52/nrf52.ini
index 778be55232..57b276978c 100644
--- a/arch/nrf52/nrf52.ini
+++ b/arch/nrf52/nrf52.ini
@@ -1,6 +1,6 @@
 [nrf52_base]
 ; Instead of the standard nordicnrf52 platform, we use our fork which has our added variant files
-platform = platformio/nordicnrf52@^10.6.0
+platform = platformio/nordicnrf52@^10.7.0
 extends = arduino_base
 platform_packages =
   ; our custom Git version until they merge our PR
@@ -29,4 +29,4 @@ lib_deps=
 
 lib_ignore =
   BluetoothOTA
-  lvgl
+  lvgl
\ No newline at end of file

From 4edeca5f846024365bbd8855a454d42d2eae4d57 Mon Sep 17 00:00:00 2001
From: Tom <116762865+Nestpebble@users.noreply.github.com>
Date: Tue, 17 Dec 2024 16:25:37 +0000
Subject: [PATCH 23/25] Added support for the LR1121 radio to the NRF52
 Pro-Micro (#5515)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* Added support for the LR1121 radio

Added support for the LR1121 radio, tested as functional with an E80-900M2213S from CDEbyte.

* Swap PNG for PDF

* remove PNG

* put TCXO voltage to 1.8, as in example file

It worked at 1.6v, but ¯\_(ツ)_/¯

* Hopefully this will appease Trunk

* Update rf switch pins and Schematic

---------

Co-authored-by: Ben Meadors 
---
 ...Schematic_Pro-Micro_Pinouts 2024-12-14.pdf | Bin 0 -> 119617 bytes
 .../diy/nrf52_promicro_diy_tcxo/rfswitch.h    |  17 ++++++++++++++
 .../diy/nrf52_promicro_diy_tcxo/variant.h     |  21 +++++++++++++++---
 3 files changed, 35 insertions(+), 3 deletions(-)
 create mode 100644 variants/diy/nrf52_promicro_diy_tcxo/Schematic_Pro-Micro_Pinouts 2024-12-14.pdf
 create mode 100644 variants/diy/nrf52_promicro_diy_tcxo/rfswitch.h

diff --git a/variants/diy/nrf52_promicro_diy_tcxo/Schematic_Pro-Micro_Pinouts 2024-12-14.pdf b/variants/diy/nrf52_promicro_diy_tcxo/Schematic_Pro-Micro_Pinouts 2024-12-14.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..de87af141f9b2952df23a04e864c3f71b17a0e70
GIT binary patch
literal 119617
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 RFSW0_V1
+// DIO6 -> RFSW1_V2
+// DIO7 -> ANT_CTRL_ON + ESP_IO9/LR_GPS_ANT_DC_EN -> RFI_GPS (Bias-T GPS) (LR11x0 only)
+
+static const uint32_t rfswitch_dio_pins[] = {RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6, RADIOLIB_LR11X0_DIO7, RADIOLIB_NC,
+                                             RADIOLIB_NC};
+
+static const Module::RfSwitchMode_t rfswitch_table[] = {
+    // mode                  DIO5  DIO6  DIO7
+    {LR11x0::MODE_STBY, {LOW, LOW, LOW}},  {LR11x0::MODE_RX, {HIGH, LOW, LOW}},
+    {LR11x0::MODE_TX, {LOW, HIGH, LOW}},   {LR11x0::MODE_TX_HP, {LOW, HIGH, LOW}},
+    {LR11x0::MODE_TX_HF, {LOW, LOW, LOW}}, {LR11x0::MODE_GNSS, {LOW, LOW, HIGH}},
+    {LR11x0::MODE_WIFI, {LOW, LOW, LOW}},  END_OF_MODE_TABLE,
+};
\ No newline at end of file
diff --git a/variants/diy/nrf52_promicro_diy_tcxo/variant.h b/variants/diy/nrf52_promicro_diy_tcxo/variant.h
index 5c535ba1e8..6ffb86cff9 100644
--- a/variants/diy/nrf52_promicro_diy_tcxo/variant.h
+++ b/variants/diy/nrf52_promicro_diy_tcxo/variant.h
@@ -122,12 +122,13 @@ NRF52 PRO MICRO PIN ASSIGNMENT
 #define USE_SX1262
 #define USE_RF95
 #define USE_SX1268
+#define USE_LR1121
 
 // RF95 CONFIG
 
-#define LORA_DIO0 (0 + 29) // P0.10 IRQ
+#define LORA_DIO0 (0 + 29) // P0.29 BUSY
 #define LORA_DIO1 (0 + 10) // P0.10 IRQ
-#define LORA_RESET (0 + 9) // P0.09
+#define LORA_RESET (0 + 9) // P0.09 NRST
 
 // RX/TX for RFM95/SX127x
 #define RF95_RXEN (0 + 17)    // P0.17
@@ -143,6 +144,19 @@ NRF52 PRO MICRO PIN ASSIGNMENT
 #define SX126X_RXEN (0 + 17)     // P0.17
 #define SX126X_TXEN RADIOLIB_NC  // Assuming that DIO2 is connected to TXEN pin. If not, TXEN must be connected.
 
+// LR1121
+#ifdef USE_LR1121
+#define LR1121_IRQ_PIN (0 + 10)      // P0.10 IRQ
+#define LR1121_NRESET_PIN LORA_RESET // P0.09 NRST
+#define LR1121_BUSY_PIN (0 + 29)     // P0.29 BUSY
+#define LR1121_SPI_NSS_PIN LORA_CS   // P1.13
+#define LR1121_SPI_SCK_PIN LORA_SCK
+#define LR1121_SPI_MOSI_PIN LORA_MOSI
+#define LR1121_SPI_MISO_PIN LORA_MISO
+#define LR11X0_DIO3_TCXO_VOLTAGE 1.8
+#define LR11X0_DIO_AS_RF_SWITCH
+#endif
+
 // #define SX126X_MAX_POWER 8 set this if using a high-power board!
 
 /*
@@ -164,6 +178,7 @@ settings.
 | Seeed        | Wio-SX1262       | yes  | Int       | Sooooo cute!                          |
 | AI-Thinker   | RA-02            | No   | Int       | SX1278 **433mhz band only**           |
 | RF Solutions | RFM95            | No   | Int       | Untested                              |
+| Ebyte        | E80-900M2213S    | Yes  | Int       | LR1121 radio                          |
 
 */
 
@@ -179,4 +194,4 @@ extern float tcxoVoltage; // make this available everywhere
  *        Arduino objects - C++ only
  *----------------------------------------------------------------------------*/
 
-#endif
+#endif
\ No newline at end of file

From af79970ad7a4f6f10d0a1cdc9374a07c78ddae96 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=F0=9F=93=A1=20WatskeBart=20=F0=9F=A4=96?=
 
Date: Wed, 18 Dec 2024 05:46:18 +0100
Subject: [PATCH 24/25] Added product url (#5594)

---
 boards/t-echo.json | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/boards/t-echo.json b/boards/t-echo.json
index fcfc8c50b1..f891da94fe 100644
--- a/boards/t-echo.json
+++ b/boards/t-echo.json
@@ -48,6 +48,6 @@
     "require_upload_port": true,
     "wait_for_upload_port": true
   },
-  "url": "FIXME",
-  "vendor": "TTGO"
+  "url": "https://lilygo.cc/products/t-echo-lilygo",
+  "vendor": "LILYGO"
 }

From 68413486e3401d7503efffa60723a352f6ab5fa2 Mon Sep 17 00:00:00 2001
From: Ben Meadors 
Date: Wed, 18 Dec 2024 07:15:48 -0600
Subject: [PATCH 25/25] Switch back docker/login-action

---
 .github/workflows/build_native.yml | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/build_native.yml b/.github/workflows/build_native.yml
index d9591e72c8..b1b0127054 100644
--- a/.github/workflows/build_native.yml
+++ b/.github/workflows/build_native.yml
@@ -53,9 +53,12 @@ jobs:
 
       - name: Docker login
         if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
-        run: |
-          echo ${{ secrets.DOCKER_FIRMWARE_TOKEN }} | docker login -u meshtastic --password-stdin
-        continue-on-error: true
+        uses: docker/login-action@v3
+        continue-on-error: true # FIXME: Failing docker login auth
+        with:
+          logout: true
+          username: meshtastic
+          password: ${{ secrets.DOCKER_FIRMWARE_TOKEN }}
 
       - name: Docker setup
         if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}