From 2c654454cffabdd165311ac7bac3770ba975b53b Mon Sep 17 00:00:00 2001 From: Austin Date: Sat, 4 Jan 2025 14:39:37 -0500 Subject: [PATCH 01/41] meshtasticd debian source package (#5741) --- bin/.gitignore | 1 + debian/.gitignore | 6 ++++++ debian/changelog | 5 +++++ debian/control | 25 +++++++++++++++++++++++++ debian/meshtasticd.dirs | 3 +++ debian/meshtasticd.install | 6 ++++++ debian/rules | 15 +++++++++++++++ debian/source/format | 1 + debian/update_changelog.sh | 5 +++++ 9 files changed, 67 insertions(+) create mode 100644 bin/.gitignore create mode 100644 debian/.gitignore create mode 100644 debian/changelog create mode 100644 debian/control create mode 100644 debian/meshtasticd.dirs create mode 100644 debian/meshtasticd.install create mode 100755 debian/rules create mode 100644 debian/source/format create mode 100644 debian/update_changelog.sh diff --git a/bin/.gitignore b/bin/.gitignore new file mode 100644 index 000000000..5b6b0720c --- /dev/null +++ b/bin/.gitignore @@ -0,0 +1 @@ +config.yaml diff --git a/debian/.gitignore b/debian/.gitignore new file mode 100644 index 000000000..b36ab39fc --- /dev/null +++ b/debian/.gitignore @@ -0,0 +1,6 @@ +.debhelper +debhelper-build-stamp +meshtasticd +files +meshtasticd.substvars +meshtasticd.postrm.debhelper diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 000000000..5dd6fb1c0 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,5 @@ +meshtasticd (2.5.19) unstable; urgency=medium + + * Initial packaging + + -- Austin Lane Thu, 02 Jan 2025 12:00:00 +0000 \ No newline at end of file diff --git a/debian/control b/debian/control new file mode 100644 index 000000000..b00c6d78e --- /dev/null +++ b/debian/control @@ -0,0 +1,25 @@ +Source: meshtasticd +Section: misc +Priority: optional +Maintainer: Austin Lane +Build-Depends: debhelper-compat (= 13), + python3-pip, + python3-venv, + git, + g++, + pkg-config, + libyaml-cpp-dev, + libgpiod-dev, + libbluetooth-dev, + libusb-1.0-0-dev, + libi2c-dev +Standards-Version: 4.6.2 +Homepage: https://github.com/meshtastic/firmware +Rules-Requires-Root: no + +Package: meshtasticd +Architecture: any +Depends: ${misc:Depends}, ${shlibs:Depends} +Description: Meshtastic daemon for communicating with Meshtastic devices + Meshtastic is an off-grid text communication platform that uses inexpensive + LoRa radios. diff --git a/debian/meshtasticd.dirs b/debian/meshtasticd.dirs new file mode 100644 index 000000000..cf1ba7a37 --- /dev/null +++ b/debian/meshtasticd.dirs @@ -0,0 +1,3 @@ +etc/meshtasticd +etc/meshtasticd/config.d +etc/meshtasticd/available.d diff --git a/debian/meshtasticd.install b/debian/meshtasticd.install new file mode 100644 index 000000000..04bf34daf --- /dev/null +++ b/debian/meshtasticd.install @@ -0,0 +1,6 @@ +.pio/build/native/meshtasticd usr/sbin + +bin/config.yaml etc/meshtasticd +bin/config.d/* etc/meshtasticd/available.d + +bin/meshtasticd.service lib/systemd/system diff --git a/debian/rules b/debian/rules new file mode 100755 index 000000000..5486611a6 --- /dev/null +++ b/debian/rules @@ -0,0 +1,15 @@ +#!/usr/bin/make -f + +# Use the "dh" sequencer +%: + dh $@ + +override_dh_auto_build: + # Terrible hack to use modern platformio to build the native version + python3 -m venv venv + venv/bin/pip install platformio + venv/bin/platformio run -e native + rm -rf venv + # Move the binary and default config to the correct name + mv .pio/build/native/program .pio/build/native/meshtasticd + cp bin/config-dist.yaml bin/config.yaml diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 000000000..9f6742789 --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (native) \ No newline at end of file diff --git a/debian/update_changelog.sh b/debian/update_changelog.sh new file mode 100644 index 000000000..60af34511 --- /dev/null +++ b/debian/update_changelog.sh @@ -0,0 +1,5 @@ +#!/usr/bin/bash +export DEBEMAIL="github-actions[bot]@users.noreply.github.com" +dch --newversion "$(python3 bin/buildinfo.py short)-1" \ + --distribution unstable \ + "GitHub Actions Automatic version bump" From 7c21d7761cf8f63e8acdfe09be7ede63a3a9c379 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sat, 4 Jan 2025 14:12:54 -0600 Subject: [PATCH 02/41] Move the RFM9x to config.available (#5742) --- bin/config-dist.yaml | 6 ------ bin/config.d/lora-Adafruit-RFM9x | 5 +++++ 2 files changed, 5 insertions(+), 6 deletions(-) create mode 100644 bin/config.d/lora-Adafruit-RFM9x diff --git a/bin/config-dist.yaml b/bin/config-dist.yaml index 49de1675b..e68b01ba3 100644 --- a/bin/config-dist.yaml +++ b/bin/config-dist.yaml @@ -12,12 +12,6 @@ Lora: # IRQ: 17 # Reset: 22 -# Module: RF95 # Adafruit RFM9x -# Reset: 25 -# CS: 7 -# IRQ: 22 -# Busy: 23 - # Module: RF95 # Elecrow Lora RFM95 IOT https://www.elecrow.com/lora-rfm95-iot-board-for-rpi.html # Reset: 22 # CS: 7 diff --git a/bin/config.d/lora-Adafruit-RFM9x b/bin/config.d/lora-Adafruit-RFM9x new file mode 100644 index 000000000..2d64f1f91 --- /dev/null +++ b/bin/config.d/lora-Adafruit-RFM9x @@ -0,0 +1,5 @@ +# Module: RF95 # Adafruit RFM9x +# Reset: 25 +# CS: 7 +# IRQ: 22 +# Busy: 23 \ No newline at end of file From 7480378aed611dad0acf5ea0b2e288f67ba13348 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sat, 4 Jan 2025 14:37:13 -0600 Subject: [PATCH 03/41] Update debian build rules --- debian/rules | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/debian/rules b/debian/rules index 5486611a6..ee8e74c32 100755 --- a/debian/rules +++ b/debian/rules @@ -7,8 +7,10 @@ override_dh_auto_build: # Terrible hack to use modern platformio to build the native version python3 -m venv venv - venv/bin/pip install platformio - venv/bin/platformio run -e native + source venv/bin/activate + pip install platformio + platformio run -e native + deactivate rm -rf venv # Move the binary and default config to the correct name mv .pio/build/native/program .pio/build/native/meshtasticd From eb72ee0fc19b435ff435ca2f4b31f2ba24870eea Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sat, 4 Jan 2025 14:51:36 -0600 Subject: [PATCH 04/41] don't use "source" for deb builds --- debian/rules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/rules b/debian/rules index ee8e74c32..2ea031c51 100755 --- a/debian/rules +++ b/debian/rules @@ -7,7 +7,7 @@ override_dh_auto_build: # Terrible hack to use modern platformio to build the native version python3 -m venv venv - source venv/bin/activate + . venv/bin/activate pip install platformio platformio run -e native deactivate From 6aabbedc006bd48def207d5b8337f6dfffb6447f Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sat, 4 Jan 2025 15:41:49 -0600 Subject: [PATCH 05/41] Last Ditch effort for PPA build --- debian/rules | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/debian/rules b/debian/rules index 2ea031c51..c60d611a4 100755 --- a/debian/rules +++ b/debian/rules @@ -6,12 +6,12 @@ override_dh_auto_build: # Terrible hack to use modern platformio to build the native version - python3 -m venv venv - . venv/bin/activate - pip install platformio + # python3 -m venv venv + # . venv/bin/activate + pip install platformio --break-system-packages platformio run -e native - deactivate - rm -rf venv + # deactivate + # rm -rf venv # Move the binary and default config to the correct name mv .pio/build/native/program .pio/build/native/meshtasticd cp bin/config-dist.yaml bin/config.yaml From 35814fd4bc10ba38c69d95bd7079db68fd303b2f Mon Sep 17 00:00:00 2001 From: Austin Date: Sun, 5 Jan 2025 11:22:11 -0500 Subject: [PATCH 06/41] meshtasticd debian: split libs for PPA (#5745) --- .github/workflows/build_debian_src.yml | 41 +++++++++++++ .github/workflows/main_matrix.yml | 8 +++ .github/workflows/package_ppa.yml | 58 +++++++++++++++++++ .gitignore | 1 + .../{update_changelog.sh => ci_changelog.sh} | 1 + debian/ci_pack_sdeb.sh | 9 +++ debian/control | 5 +- debian/rules | 15 ++--- debian/source/include-binaries | 2 + debian/source/options | 1 + 10 files changed, 132 insertions(+), 9 deletions(-) create mode 100644 .github/workflows/build_debian_src.yml create mode 100644 .github/workflows/package_ppa.yml rename debian/{update_changelog.sh => ci_changelog.sh} (99%) mode change 100644 => 100755 create mode 100755 debian/ci_pack_sdeb.sh create mode 100644 debian/source/include-binaries create mode 100644 debian/source/options diff --git a/.github/workflows/build_debian_src.yml b/.github/workflows/build_debian_src.yml new file mode 100644 index 000000000..59e925838 --- /dev/null +++ b/.github/workflows/build_debian_src.yml @@ -0,0 +1,41 @@ +name: Build Debian Source Package + +on: workflow_call + +permissions: + contents: write + packages: write + +jobs: + build-debian-src: + runs-on: ubuntu-24.04 + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + submodules: recursive + ref: ${{github.event.pull_request.head.ref}} + repository: ${{github.event.pull_request.head.repo.full_name}} + + - name: Install deps + shell: bash + run: | + sudo apt-get update -y --fix-missing + sudo apt-get install -y devscripts equivs + + - name: Fetch libdeps, package debian source + run: debian/ci_pack_sdeb.sh + + - name: Get release version string + run: | + echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT + echo "short=$(./bin/buildinfo.py short)" >> $GITHUB_OUTPUT + id: version + + - name: Store binaries as an artifact + uses: actions/upload-artifact@v4 + with: + name: firmware-debian-${{ steps.version.outputs.long }}-src.zip + overwrite: true + path: | + ../meshtasticd_${{ steps.version.outputs.short }}* diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index a437411b5..9685ff91f 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -128,6 +128,9 @@ jobs: with: board: ${{ matrix.board }} + package-ppa: + uses: ./.github/workflows/package_ppa.yml + package-raspbian: uses: ./.github/workflows/package_raspbian.yml @@ -332,12 +335,17 @@ jobs: run: >- bin/bump_version.py + - name: Update debian changelog + run: >- + debian/ci_changelog.sh + - name: Create version.properties pull request uses: peter-evans/create-pull-request@v7 with: title: Bump version.properties add-paths: | version.properties + debian/changelog release-firmware: strategy: diff --git a/.github/workflows/package_ppa.yml b/.github/workflows/package_ppa.yml new file mode 100644 index 000000000..284048466 --- /dev/null +++ b/.github/workflows/package_ppa.yml @@ -0,0 +1,58 @@ +name: Package Launchpad PPA + +on: + workflow_call: + workflow_dispatch: + +permissions: + contents: write + packages: write + +jobs: + build-debian-src: + uses: ./.github/workflows/build_debian_src.yml + + package-ppa: + runs-on: ubuntu-24.04 + needs: build-debian-src + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + submodules: recursive + ref: ${{github.event.pull_request.head.ref}} + repository: ${{github.event.pull_request.head.repo.full_name}} + + - name: Get release version string + run: | + echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT + echo "short=$(./bin/buildinfo.py short)" >> $GITHUB_OUTPUT + id: version + + - name: Download artifacts + uses: actions/download-artifact@v4 + with: + name: firmware-debian-${{ steps.version.outputs.long }}-src.zip + merge-multiple: true + + # - name: Install deps + # shell: bash + # run: | + # sudo apt-get update -y --fix-missing + # sudo apt-get install -y dput + + - name: Display structure of downloaded files + run: ls -R + + - name: Publish PPA + if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }} + uses: yuezk/publish-ppa-package@v2 + with: + # See https://launchpad.net/~meshtastic/+archive/ubuntu/meshtastic-daily + repository: "meshtastic/meshtastic-daily" + gpg_private_key: ${{ secrets.PPA_GPG_PRIVATE_KEY }} + tarball: "meshtasticd_${{ steps.version.outputs.short }}.tar.xz" + # Supported Ubuntu versions + series: "plucky oracular noble jammy" + deb_email: "github-actions[bot]@users.noreply.github.com" + deb_fullname: "github-actions[bot]" diff --git a/.gitignore b/.gitignore index 28f9a24cc..8998b60d6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .pio +pio # ignore vscode IDE settings files .vscode/* diff --git a/debian/update_changelog.sh b/debian/ci_changelog.sh old mode 100644 new mode 100755 similarity index 99% rename from debian/update_changelog.sh rename to debian/ci_changelog.sh index 60af34511..56688f99b --- a/debian/update_changelog.sh +++ b/debian/ci_changelog.sh @@ -1,5 +1,6 @@ #!/usr/bin/bash export DEBEMAIL="github-actions[bot]@users.noreply.github.com" + dch --newversion "$(python3 bin/buildinfo.py short)-1" \ --distribution unstable \ "GitHub Actions Automatic version bump" diff --git a/debian/ci_pack_sdeb.sh b/debian/ci_pack_sdeb.sh new file mode 100755 index 000000000..97f102209 --- /dev/null +++ b/debian/ci_pack_sdeb.sh @@ -0,0 +1,9 @@ +#!/usr/bin/bash +export PLATFORMIO_LIBDEPS_DIR=pio/libdeps +export PLATFORMIO_PACKAGES_DIR=pio/packages + +# Download libraries to `libdeps` +platformio pkg install -e native + +# Build the source deb +debuild -S diff --git a/debian/control b/debian/control index b00c6d78e..9814933e3 100644 --- a/debian/control +++ b/debian/control @@ -3,8 +3,9 @@ Section: misc Priority: optional Maintainer: Austin Lane Build-Depends: debhelper-compat (= 13), - python3-pip, - python3-venv, + platformio, + python3-protobuf, + python3-grpcio, git, g++, pkg-config, diff --git a/debian/rules b/debian/rules index c60d611a4..f535ad6eb 100755 --- a/debian/rules +++ b/debian/rules @@ -1,17 +1,18 @@ #!/usr/bin/make -f +# export DH_VERBOSE = 1 # Use the "dh" sequencer %: dh $@ +# https://docs.platformio.org/en/latest/envvars.html +PIO_ENV:=\ + PLATFORMIO_LIBDEPS_DIR=pio/libdeps \ + PLATFORMIO_PACKAGES_DIR=pio/packages + override_dh_auto_build: - # Terrible hack to use modern platformio to build the native version - # python3 -m venv venv - # . venv/bin/activate - pip install platformio --break-system-packages - platformio run -e native - # deactivate - # rm -rf venv + # Build with platformio + $(PIO_ENV) platformio run -e native # Move the binary and default config to the correct name mv .pio/build/native/program .pio/build/native/meshtasticd cp bin/config-dist.yaml bin/config.yaml diff --git a/debian/source/include-binaries b/debian/source/include-binaries new file mode 100644 index 000000000..1632328ca --- /dev/null +++ b/debian/source/include-binaries @@ -0,0 +1,2 @@ +pio/libdeps +pio/packages \ No newline at end of file diff --git a/debian/source/options b/debian/source/options new file mode 100644 index 000000000..0553b485d --- /dev/null +++ b/debian/source/options @@ -0,0 +1 @@ +extend-diff-ignore = "\.pio" \ No newline at end of file From 15019e8663741d12321173c5a2dcdab0d2dc2f7b Mon Sep 17 00:00:00 2001 From: Austin Date: Sun, 5 Jan 2025 11:37:38 -0500 Subject: [PATCH 07/41] meshtasticd: deps for debian_build_src (#5748) --- .github/workflows/build_debian_src.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_debian_src.yml b/.github/workflows/build_debian_src.yml index 59e925838..6b1c014c2 100644 --- a/.github/workflows/build_debian_src.yml +++ b/.github/workflows/build_debian_src.yml @@ -21,7 +21,11 @@ jobs: shell: bash run: | sudo apt-get update -y --fix-missing - sudo apt-get install -y devscripts equivs + sudo apt-get install -y software-properties-common + sudo add-apt-repository ppa:meshtastic/meshtastic-daily -y + sudo apt-get install -y build-essential devscripts equivs \ + platformio python3-protobuf python3-grpcio \ + libyaml-cpp-dev libgpiod-dev libbluetooth-dev libusb-1.0-0-dev libi2c-dev - name: Fetch libdeps, package debian source run: debian/ci_pack_sdeb.sh From b2a89b8136fe27689805e07a84ef78efb191d919 Mon Sep 17 00:00:00 2001 From: Austin Date: Sun, 5 Jan 2025 12:06:00 -0500 Subject: [PATCH 08/41] meshtasticd: gpg tomfoolery (#5750) --- .github/workflows/build_debian_src.yml | 8 ++++++++ debian/ci_pack_sdeb.sh | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_debian_src.yml b/.github/workflows/build_debian_src.yml index 6b1c014c2..bae3e442d 100644 --- a/.github/workflows/build_debian_src.yml +++ b/.github/workflows/build_debian_src.yml @@ -27,8 +27,16 @@ jobs: platformio python3-protobuf python3-grpcio \ libyaml-cpp-dev libgpiod-dev libbluetooth-dev libusb-1.0-0-dev libi2c-dev + - name: Import GPG key + uses: crazy-max/ghaction-import-gpg@v6 + with: + gpg_private_key: ${{ secrets.PPA_GPG_PRIVATE_KEY }} + id: gpg + - name: Fetch libdeps, package debian source run: debian/ci_pack_sdeb.sh + env: + GPG_KEY_ID: ${{ steps.gpg.outputs.keyid }} - name: Get release version string run: | diff --git a/debian/ci_pack_sdeb.sh b/debian/ci_pack_sdeb.sh index 97f102209..79b484a35 100755 --- a/debian/ci_pack_sdeb.sh +++ b/debian/ci_pack_sdeb.sh @@ -6,4 +6,4 @@ export PLATFORMIO_PACKAGES_DIR=pio/packages platformio pkg install -e native # Build the source deb -debuild -S +debuild -S -k$GPG_KEY_ID From 02a5a91da0813858c5fd0c27282f3a01271968cd Mon Sep 17 00:00:00 2001 From: Austin Date: Sun, 5 Jan 2025 12:30:43 -0500 Subject: [PATCH 09/41] meshtasticd debian: secrets perms (#5751) --- .github/workflows/build_debian_src.yml | 6 +++++- .github/workflows/main_matrix.yml | 1 + .github/workflows/package_ppa.yml | 4 ++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_debian_src.yml b/.github/workflows/build_debian_src.yml index bae3e442d..cc93b5748 100644 --- a/.github/workflows/build_debian_src.yml +++ b/.github/workflows/build_debian_src.yml @@ -1,6 +1,10 @@ name: Build Debian Source Package -on: workflow_call +on: + workflow_call: + secrets: + PPA_GPG_PRIVATE_KEY: + required: true permissions: contents: write diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index 9685ff91f..f4c5de228 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -130,6 +130,7 @@ jobs: package-ppa: uses: ./.github/workflows/package_ppa.yml + secrets: inherit package-raspbian: uses: ./.github/workflows/package_raspbian.yml diff --git a/.github/workflows/package_ppa.yml b/.github/workflows/package_ppa.yml index 284048466..1fcc96e11 100644 --- a/.github/workflows/package_ppa.yml +++ b/.github/workflows/package_ppa.yml @@ -2,6 +2,9 @@ name: Package Launchpad PPA on: workflow_call: + secrets: + PPA_GPG_PRIVATE_KEY: + required: true workflow_dispatch: permissions: @@ -11,6 +14,7 @@ permissions: jobs: build-debian-src: uses: ./.github/workflows/build_debian_src.yml + secrets: inherit package-ppa: runs-on: ubuntu-24.04 From 5196ee39cb8d8122f794fe0b100e4757887028ea Mon Sep 17 00:00:00 2001 From: Austin Date: Sun, 5 Jan 2025 12:44:05 -0500 Subject: [PATCH 10/41] meshtasticd: debian checkout to subdir (#5752) --- .github/workflows/build_debian_src.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_debian_src.yml b/.github/workflows/build_debian_src.yml index cc93b5748..72e4adf3e 100644 --- a/.github/workflows/build_debian_src.yml +++ b/.github/workflows/build_debian_src.yml @@ -18,6 +18,7 @@ jobs: uses: actions/checkout@v4 with: submodules: recursive + path: meshtasticd ref: ${{github.event.pull_request.head.ref}} repository: ${{github.event.pull_request.head.repo.full_name}} @@ -38,11 +39,13 @@ jobs: id: gpg - name: Fetch libdeps, package debian source + working-directory: meshtasticd run: debian/ci_pack_sdeb.sh env: GPG_KEY_ID: ${{ steps.gpg.outputs.keyid }} - name: Get release version string + working-directory: meshtasticd run: | echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT echo "short=$(./bin/buildinfo.py short)" >> $GITHUB_OUTPUT @@ -54,4 +57,4 @@ jobs: name: firmware-debian-${{ steps.version.outputs.long }}-src.zip overwrite: true path: | - ../meshtasticd_${{ steps.version.outputs.short }}* + meshtasticd_${{ steps.version.outputs.short }}* From 7c10caa78b927e31cdd69f550ac3aaafc50c7be1 Mon Sep 17 00:00:00 2001 From: Austin Date: Sun, 5 Jan 2025 13:31:01 -0500 Subject: [PATCH 11/41] meshtastic-debian: publish with dput (#5753) --- .github/workflows/build_debian_src.yml | 8 ++--- .github/workflows/package_ppa.yml | 50 ++++++++++++++++---------- 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/.github/workflows/build_debian_src.yml b/.github/workflows/build_debian_src.yml index 72e4adf3e..dfd8b66fb 100644 --- a/.github/workflows/build_debian_src.yml +++ b/.github/workflows/build_debian_src.yml @@ -24,13 +24,13 @@ jobs: - name: Install deps shell: bash + working-directory: meshtasticd run: | sudo apt-get update -y --fix-missing sudo apt-get install -y software-properties-common sudo add-apt-repository ppa:meshtastic/meshtastic-daily -y - sudo apt-get install -y build-essential devscripts equivs \ - platformio python3-protobuf python3-grpcio \ - libyaml-cpp-dev libgpiod-dev libbluetooth-dev libusb-1.0-0-dev libi2c-dev + sudo apt-get install -y build-essential devscripts equivs + sudo mk-build-deps --install --remove --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control - name: Import GPG key uses: crazy-max/ghaction-import-gpg@v6 @@ -54,7 +54,7 @@ jobs: - name: Store binaries as an artifact uses: actions/upload-artifact@v4 with: - name: firmware-debian-${{ steps.version.outputs.long }}-src.zip + name: firmware-debian-${{ steps.version.outputs.long }}-src overwrite: true path: | meshtasticd_${{ steps.version.outputs.short }}* diff --git a/.github/workflows/package_ppa.yml b/.github/workflows/package_ppa.yml index 1fcc96e11..9d59df472 100644 --- a/.github/workflows/package_ppa.yml +++ b/.github/workflows/package_ppa.yml @@ -24,10 +24,24 @@ jobs: uses: actions/checkout@v4 with: submodules: recursive + path: meshtasticd ref: ${{github.event.pull_request.head.ref}} repository: ${{github.event.pull_request.head.repo.full_name}} + - name: Install deps + shell: bash + run: | + sudo apt-get update -y --fix-missing + sudo apt-get install -y dput + + - name: Import GPG key + uses: crazy-max/ghaction-import-gpg@v6 + with: + gpg_private_key: ${{ secrets.PPA_GPG_PRIVATE_KEY }} + id: gpg + - name: Get release version string + working-directory: meshtasticd run: | echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT echo "short=$(./bin/buildinfo.py short)" >> $GITHUB_OUTPUT @@ -36,27 +50,27 @@ jobs: - name: Download artifacts uses: actions/download-artifact@v4 with: - name: firmware-debian-${{ steps.version.outputs.long }}-src.zip + name: firmware-debian-${{ steps.version.outputs.long }}-src merge-multiple: true - # - name: Install deps - # shell: bash - # run: | - # sudo apt-get update -y --fix-missing - # sudo apt-get install -y dput - - name: Display structure of downloaded files run: ls -R - - name: Publish PPA + - name: Publish with dput if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }} - uses: yuezk/publish-ppa-package@v2 - with: - # See https://launchpad.net/~meshtastic/+archive/ubuntu/meshtastic-daily - repository: "meshtastic/meshtastic-daily" - gpg_private_key: ${{ secrets.PPA_GPG_PRIVATE_KEY }} - tarball: "meshtasticd_${{ steps.version.outputs.short }}.tar.xz" - # Supported Ubuntu versions - series: "plucky oracular noble jammy" - deb_email: "github-actions[bot]@users.noreply.github.com" - deb_fullname: "github-actions[bot]" + run: | + dput ppa:meshtastic/meshtastic-daily meshtasticd_${{ steps.version.outputs.short }}_source.changes + + # - name: Publish PPA + # if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }} + # uses: yuezk/publish-ppa-package@v2 + # with: + # # See https://launchpad.net/~meshtastic/+archive/ubuntu/meshtastic-daily + # repository: "meshtastic/meshtastic-daily" + # gpg_private_key: ${{ secrets.PPA_GPG_PRIVATE_KEY }} + # gpg_passphrase: "" + # tarball: "meshtasticd_${{ steps.version.outputs.short }}.tar.xz" + # deb_email: "github-actions[bot]@users.noreply.github.com" + # deb_fullname: "github-actions[bot]" + # # Supported Ubuntu versions + # series: "plucky oracular noble jammy" From 031aecac665c4e4ebf28026a9a3196b16037d9e2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 5 Jan 2025 13:14:56 -0600 Subject: [PATCH 12/41] [create-pull-request] automated change (#5755) Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com> --- protobufs | 2 +- src/mesh/generated/meshtastic/config.pb.cpp | 2 ++ src/mesh/generated/meshtastic/config.pb.h | 26 ++++++++++++++++---- src/mesh/generated/meshtastic/device_ui.pb.h | 16 ++++++++---- src/mesh/generated/meshtastic/localonly.pb.h | 2 +- 5 files changed, 36 insertions(+), 12 deletions(-) diff --git a/protobufs b/protobufs index c55f120a9..76f806e1b 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit c55f120a9c1ce90c85e4826907a0b9bcb2d5f5a2 +Subproject commit 76f806e1bb1e2a7b157a14fadd095775f63db5e4 diff --git a/src/mesh/generated/meshtastic/config.pb.cpp b/src/mesh/generated/meshtastic/config.pb.cpp index 6fd2161ae..5512584a7 100644 --- a/src/mesh/generated/meshtastic/config.pb.cpp +++ b/src/mesh/generated/meshtastic/config.pb.cpp @@ -63,6 +63,8 @@ PB_BIND(meshtastic_Config_SessionkeyConfig, meshtastic_Config_SessionkeyConfig, + + diff --git a/src/mesh/generated/meshtastic/config.pb.h b/src/mesh/generated/meshtastic/config.pb.h index 5e105ab17..14aed9dfe 100644 --- a/src/mesh/generated/meshtastic/config.pb.h +++ b/src/mesh/generated/meshtastic/config.pb.h @@ -139,6 +139,14 @@ typedef enum _meshtastic_Config_NetworkConfig_AddressMode { meshtastic_Config_NetworkConfig_AddressMode_STATIC = 1 } meshtastic_Config_NetworkConfig_AddressMode; +/* Available flags auxiliary network protocols */ +typedef enum _meshtastic_Config_NetworkConfig_ProtocolFlags { + /* Do not broadcast packets over any network protocol */ + meshtastic_Config_NetworkConfig_ProtocolFlags_NO_BROADCAST = 0, + /* Enable broadcasting packets via UDP over the local network */ + meshtastic_Config_NetworkConfig_ProtocolFlags_UDP_BROADCAST = 1 +} meshtastic_Config_NetworkConfig_ProtocolFlags; + /* How the GPS coordinates are displayed on the OLED screen. */ typedef enum _meshtastic_Config_DisplayConfig_GpsCoordinateFormat { /* GPS coordinates are displayed in the normal decimal degrees format: @@ -429,6 +437,8 @@ typedef struct _meshtastic_Config_NetworkConfig { meshtastic_Config_NetworkConfig_IpV4Config ipv4_config; /* rsyslog Server and Port */ char rsyslog_server[33]; + /* Flags for enabling/disabling network protocols */ + uint32_t enabled_protocols; } meshtastic_Config_NetworkConfig; /* Display Config */ @@ -613,6 +623,10 @@ extern "C" { #define _meshtastic_Config_NetworkConfig_AddressMode_MAX meshtastic_Config_NetworkConfig_AddressMode_STATIC #define _meshtastic_Config_NetworkConfig_AddressMode_ARRAYSIZE ((meshtastic_Config_NetworkConfig_AddressMode)(meshtastic_Config_NetworkConfig_AddressMode_STATIC+1)) +#define _meshtastic_Config_NetworkConfig_ProtocolFlags_MIN meshtastic_Config_NetworkConfig_ProtocolFlags_NO_BROADCAST +#define _meshtastic_Config_NetworkConfig_ProtocolFlags_MAX meshtastic_Config_NetworkConfig_ProtocolFlags_UDP_BROADCAST +#define _meshtastic_Config_NetworkConfig_ProtocolFlags_ARRAYSIZE ((meshtastic_Config_NetworkConfig_ProtocolFlags)(meshtastic_Config_NetworkConfig_ProtocolFlags_UDP_BROADCAST+1)) + #define _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN meshtastic_Config_DisplayConfig_GpsCoordinateFormat_DEC #define _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MAX meshtastic_Config_DisplayConfig_GpsCoordinateFormat_OSGR #define _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_ARRAYSIZE ((meshtastic_Config_DisplayConfig_GpsCoordinateFormat)(meshtastic_Config_DisplayConfig_GpsCoordinateFormat_OSGR+1)) @@ -674,7 +688,7 @@ extern "C" { #define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0} #define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN} #define meshtastic_Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0} -#define meshtastic_Config_NetworkConfig_init_default {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_default, ""} +#define meshtastic_Config_NetworkConfig_init_default {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_default, "", 0} #define meshtastic_Config_NetworkConfig_IpV4Config_init_default {0, 0, 0, 0} #define meshtastic_Config_DisplayConfig_init_default {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0, _meshtastic_Config_DisplayConfig_CompassOrientation_MIN} #define meshtastic_Config_LoRaConfig_init_default {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0} @@ -685,7 +699,7 @@ extern "C" { #define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0} #define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN} #define meshtastic_Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0} -#define meshtastic_Config_NetworkConfig_init_zero {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_zero, ""} +#define meshtastic_Config_NetworkConfig_init_zero {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_zero, "", 0} #define meshtastic_Config_NetworkConfig_IpV4Config_init_zero {0, 0, 0, 0} #define meshtastic_Config_DisplayConfig_init_zero {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0, _meshtastic_Config_DisplayConfig_CompassOrientation_MIN} #define meshtastic_Config_LoRaConfig_init_zero {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0} @@ -739,6 +753,7 @@ extern "C" { #define meshtastic_Config_NetworkConfig_address_mode_tag 7 #define meshtastic_Config_NetworkConfig_ipv4_config_tag 8 #define meshtastic_Config_NetworkConfig_rsyslog_server_tag 9 +#define meshtastic_Config_NetworkConfig_enabled_protocols_tag 10 #define meshtastic_Config_DisplayConfig_screen_on_secs_tag 1 #define meshtastic_Config_DisplayConfig_gps_format_tag 2 #define meshtastic_Config_DisplayConfig_auto_screen_carousel_secs_tag 3 @@ -867,7 +882,8 @@ X(a, STATIC, SINGULAR, STRING, ntp_server, 5) \ X(a, STATIC, SINGULAR, BOOL, eth_enabled, 6) \ X(a, STATIC, SINGULAR, UENUM, address_mode, 7) \ X(a, STATIC, OPTIONAL, MESSAGE, ipv4_config, 8) \ -X(a, STATIC, SINGULAR, STRING, rsyslog_server, 9) +X(a, STATIC, SINGULAR, STRING, rsyslog_server, 9) \ +X(a, STATIC, SINGULAR, UINT32, enabled_protocols, 10) #define meshtastic_Config_NetworkConfig_CALLBACK NULL #define meshtastic_Config_NetworkConfig_DEFAULT NULL #define meshtastic_Config_NetworkConfig_ipv4_config_MSGTYPE meshtastic_Config_NetworkConfig_IpV4Config @@ -972,12 +988,12 @@ extern const pb_msgdesc_t meshtastic_Config_SessionkeyConfig_msg; #define meshtastic_Config_DisplayConfig_size 30 #define meshtastic_Config_LoRaConfig_size 85 #define meshtastic_Config_NetworkConfig_IpV4Config_size 20 -#define meshtastic_Config_NetworkConfig_size 196 +#define meshtastic_Config_NetworkConfig_size 202 #define meshtastic_Config_PositionConfig_size 62 #define meshtastic_Config_PowerConfig_size 52 #define meshtastic_Config_SecurityConfig_size 178 #define meshtastic_Config_SessionkeyConfig_size 0 -#define meshtastic_Config_size 199 +#define meshtastic_Config_size 205 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/mesh/generated/meshtastic/device_ui.pb.h b/src/mesh/generated/meshtastic/device_ui.pb.h index 0c4f5384e..f090b5b4f 100644 --- a/src/mesh/generated/meshtastic/device_ui.pb.h +++ b/src/mesh/generated/meshtastic/device_ui.pb.h @@ -51,6 +51,8 @@ typedef enum _meshtastic_Language { meshtastic_Language_GREEK = 13, /* Norwegian */ meshtastic_Language_NORWEGIAN = 14, + /* Slovenian */ + meshtastic_Language_SLOVENIAN = 15, /* Simplified Chinese (experimental) */ meshtastic_Language_SIMPLIFIED_CHINESE = 30, /* Traditional Chinese (experimental) */ @@ -71,6 +73,8 @@ typedef struct _meshtastic_NodeFilter { bool position_switch; /* Filter nodes by matching name string */ char node_name[16]; + /* Filter based on channel */ + int8_t channel; } meshtastic_NodeFilter; typedef struct _meshtastic_NodeHighlight { @@ -138,10 +142,10 @@ extern "C" { /* Initializer values for message structs */ #define meshtastic_DeviceUIConfig_init_default {0, 0, 0, 0, 0, 0, _meshtastic_Theme_MIN, 0, 0, 0, _meshtastic_Language_MIN, false, meshtastic_NodeFilter_init_default, false, meshtastic_NodeHighlight_init_default, {0, {0}}} -#define meshtastic_NodeFilter_init_default {0, 0, 0, 0, 0, ""} +#define meshtastic_NodeFilter_init_default {0, 0, 0, 0, 0, "", 0} #define meshtastic_NodeHighlight_init_default {0, 0, 0, 0, ""} #define meshtastic_DeviceUIConfig_init_zero {0, 0, 0, 0, 0, 0, _meshtastic_Theme_MIN, 0, 0, 0, _meshtastic_Language_MIN, false, meshtastic_NodeFilter_init_zero, false, meshtastic_NodeHighlight_init_zero, {0, {0}}} -#define meshtastic_NodeFilter_init_zero {0, 0, 0, 0, 0, ""} +#define meshtastic_NodeFilter_init_zero {0, 0, 0, 0, 0, "", 0} #define meshtastic_NodeHighlight_init_zero {0, 0, 0, 0, ""} /* Field tags (for use in manual encoding/decoding) */ @@ -151,6 +155,7 @@ extern "C" { #define meshtastic_NodeFilter_hops_away_tag 4 #define meshtastic_NodeFilter_position_switch_tag 5 #define meshtastic_NodeFilter_node_name_tag 6 +#define meshtastic_NodeFilter_channel_tag 7 #define meshtastic_NodeHighlight_chat_switch_tag 1 #define meshtastic_NodeHighlight_position_switch_tag 2 #define meshtastic_NodeHighlight_telemetry_switch_tag 3 @@ -198,7 +203,8 @@ X(a, STATIC, SINGULAR, BOOL, offline_switch, 2) \ X(a, STATIC, SINGULAR, BOOL, public_key_switch, 3) \ X(a, STATIC, SINGULAR, INT32, hops_away, 4) \ X(a, STATIC, SINGULAR, BOOL, position_switch, 5) \ -X(a, STATIC, SINGULAR, STRING, node_name, 6) +X(a, STATIC, SINGULAR, STRING, node_name, 6) \ +X(a, STATIC, SINGULAR, INT32, channel, 7) #define meshtastic_NodeFilter_CALLBACK NULL #define meshtastic_NodeFilter_DEFAULT NULL @@ -222,8 +228,8 @@ extern const pb_msgdesc_t meshtastic_NodeHighlight_msg; /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_DEVICE_UI_PB_H_MAX_SIZE meshtastic_DeviceUIConfig_size -#define meshtastic_DeviceUIConfig_size 117 -#define meshtastic_NodeFilter_size 36 +#define meshtastic_DeviceUIConfig_size 128 +#define meshtastic_NodeFilter_size 47 #define meshtastic_NodeHighlight_size 25 #ifdef __cplusplus diff --git a/src/mesh/generated/meshtastic/localonly.pb.h b/src/mesh/generated/meshtastic/localonly.pb.h index 30f70ed90..dc0f507c9 100644 --- a/src/mesh/generated/meshtastic/localonly.pb.h +++ b/src/mesh/generated/meshtastic/localonly.pb.h @@ -187,7 +187,7 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg; /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_MAX_SIZE meshtastic_LocalConfig_size -#define meshtastic_LocalConfig_size 735 +#define meshtastic_LocalConfig_size 741 #define meshtastic_LocalModuleConfig_size 699 #ifdef __cplusplus From d21d6c1301d2a3fd06faf17f0ca411e8d6d83d0f Mon Sep 17 00:00:00 2001 From: Austin Date: Sun, 5 Jan 2025 14:24:05 -0500 Subject: [PATCH 13/41] meshtasticd-debian: Build multiple series (#5756) --- .github/workflows/build_debian_src.yml | 9 ++++++++- .github/workflows/main_matrix.yml | 6 ++++++ .github/workflows/package_ppa.yml | 11 +++++++++-- debian/ci_pack_sdeb.sh | 7 +++++++ 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build_debian_src.yml b/.github/workflows/build_debian_src.yml index dfd8b66fb..1424774b0 100644 --- a/.github/workflows/build_debian_src.yml +++ b/.github/workflows/build_debian_src.yml @@ -5,6 +5,11 @@ on: secrets: PPA_GPG_PRIVATE_KEY: required: true + inputs: + series: + description: 'Ubuntu series to target' + required: true + type: string permissions: contents: write @@ -42,7 +47,9 @@ jobs: working-directory: meshtasticd run: debian/ci_pack_sdeb.sh env: + SERIES: ${{ inputs.series }} GPG_KEY_ID: ${{ steps.gpg.outputs.keyid }} + REVISION: ${{ github.sha }} - name: Get release version string working-directory: meshtasticd @@ -54,7 +61,7 @@ jobs: - name: Store binaries as an artifact uses: actions/upload-artifact@v4 with: - name: firmware-debian-${{ steps.version.outputs.long }}-src + name: firmware-debian-${{ steps.version.outputs.long }}-${{ inputs.series }}-src overwrite: true path: | meshtasticd_${{ steps.version.outputs.short }}* diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index f4c5de228..be8cddaf3 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -129,7 +129,13 @@ jobs: board: ${{ matrix.board }} package-ppa: + strategy: + fail-fast: false + matrix: + series: [plucky, oracular, noble, jammy] uses: ./.github/workflows/package_ppa.yml + with: + series: ${{ matrix.series }} secrets: inherit package-raspbian: diff --git a/.github/workflows/package_ppa.yml b/.github/workflows/package_ppa.yml index 9d59df472..d630e8092 100644 --- a/.github/workflows/package_ppa.yml +++ b/.github/workflows/package_ppa.yml @@ -5,6 +5,11 @@ on: secrets: PPA_GPG_PRIVATE_KEY: required: true + inputs: + series: + description: 'Ubuntu series to target' + required: true + type: string workflow_dispatch: permissions: @@ -15,6 +20,8 @@ jobs: build-debian-src: uses: ./.github/workflows/build_debian_src.yml secrets: inherit + with: + series: ${{ inputs.series }} package-ppa: runs-on: ubuntu-24.04 @@ -50,11 +57,11 @@ jobs: - name: Download artifacts uses: actions/download-artifact@v4 with: - name: firmware-debian-${{ steps.version.outputs.long }}-src + name: firmware-debian-${{ steps.version.outputs.long }}-${{ inputs.series }}-src merge-multiple: true - name: Display structure of downloaded files - run: ls -R + run: ls -lah - name: Publish with dput if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }} diff --git a/debian/ci_pack_sdeb.sh b/debian/ci_pack_sdeb.sh index 79b484a35..acab2683f 100755 --- a/debian/ci_pack_sdeb.sh +++ b/debian/ci_pack_sdeb.sh @@ -1,9 +1,16 @@ #!/usr/bin/bash +export DEBEMAIL="github-actions[bot]@users.noreply.github.com" export PLATFORMIO_LIBDEPS_DIR=pio/libdeps export PLATFORMIO_PACKAGES_DIR=pio/packages # Download libraries to `libdeps` platformio pkg install -e native +package=$(dpkg-parsechangelog --show-field Source) +pkg_version=$(dpkg-parsechangelog --show-field Version | cut -d- -f1) + +dch --create --distribution $SERIES --package $package --newversion $pkg_version-ppa${REVISION::7}~$SERIES \ + "GitHub Actions Automatic packaging for $SERIES" + # Build the source deb debuild -S -k$GPG_KEY_ID From 892e0922ff32eb50211e460079d011cc41c269cc Mon Sep 17 00:00:00 2001 From: Austin Date: Sun, 5 Jan 2025 14:37:15 -0500 Subject: [PATCH 14/41] meshtastic-debian: --create requires missing changelog (#5757) --- debian/ci_pack_sdeb.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/debian/ci_pack_sdeb.sh b/debian/ci_pack_sdeb.sh index acab2683f..23490f1bd 100755 --- a/debian/ci_pack_sdeb.sh +++ b/debian/ci_pack_sdeb.sh @@ -9,6 +9,7 @@ platformio pkg install -e native package=$(dpkg-parsechangelog --show-field Source) pkg_version=$(dpkg-parsechangelog --show-field Version | cut -d- -f1) +rm -rf debian/changelog dch --create --distribution $SERIES --package $package --newversion $pkg_version-ppa${REVISION::7}~$SERIES \ "GitHub Actions Automatic packaging for $SERIES" From 2f552d15e5b272ac2a0a572fd0b414f7ca47a6b0 Mon Sep 17 00:00:00 2001 From: Austin Date: Sun, 5 Jan 2025 15:14:47 -0500 Subject: [PATCH 15/41] meshtasticd-debian: Cleanup debian versioning (#5758) --- .github/workflows/build_debian_src.yml | 19 +++++++++---------- .github/workflows/package_ppa.yml | 21 +++------------------ bin/readprops.py | 7 ++++--- debian/ci_pack_sdeb.sh | 5 ++--- 4 files changed, 18 insertions(+), 34 deletions(-) diff --git a/.github/workflows/build_debian_src.yml b/.github/workflows/build_debian_src.yml index 1424774b0..9bb7dfb9c 100644 --- a/.github/workflows/build_debian_src.yml +++ b/.github/workflows/build_debian_src.yml @@ -43,25 +43,24 @@ jobs: gpg_private_key: ${{ secrets.PPA_GPG_PRIVATE_KEY }} id: gpg + - name: Get release version string + working-directory: meshtasticd + run: | + echo "deb=$(./bin/buildinfo.py deb)" >> $GITHUB_OUTPUT + id: version + - name: Fetch libdeps, package debian source working-directory: meshtasticd run: debian/ci_pack_sdeb.sh env: SERIES: ${{ inputs.series }} GPG_KEY_ID: ${{ steps.gpg.outputs.keyid }} - REVISION: ${{ github.sha }} - - - name: Get release version string - working-directory: meshtasticd - run: | - echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT - echo "short=$(./bin/buildinfo.py short)" >> $GITHUB_OUTPUT - id: version + PKG_VERSION: ${{ steps.version.outputs.deb }} - name: Store binaries as an artifact uses: actions/upload-artifact@v4 with: - name: firmware-debian-${{ steps.version.outputs.long }}-${{ inputs.series }}-src + name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src overwrite: true path: | - meshtasticd_${{ steps.version.outputs.short }}* + meshtasticd_${{ steps.version.outputs.deb }}* diff --git a/.github/workflows/package_ppa.yml b/.github/workflows/package_ppa.yml index d630e8092..f716fdff4 100644 --- a/.github/workflows/package_ppa.yml +++ b/.github/workflows/package_ppa.yml @@ -50,14 +50,13 @@ jobs: - name: Get release version string working-directory: meshtasticd run: | - echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT - echo "short=$(./bin/buildinfo.py short)" >> $GITHUB_OUTPUT + echo "deb=$(./bin/buildinfo.py deb)" >> $GITHUB_OUTPUT id: version - name: Download artifacts uses: actions/download-artifact@v4 with: - name: firmware-debian-${{ steps.version.outputs.long }}-${{ inputs.series }}-src + name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src merge-multiple: true - name: Display structure of downloaded files @@ -66,18 +65,4 @@ jobs: - name: Publish with dput if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }} run: | - dput ppa:meshtastic/meshtastic-daily meshtasticd_${{ steps.version.outputs.short }}_source.changes - - # - name: Publish PPA - # if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }} - # uses: yuezk/publish-ppa-package@v2 - # with: - # # See https://launchpad.net/~meshtastic/+archive/ubuntu/meshtastic-daily - # repository: "meshtastic/meshtastic-daily" - # gpg_private_key: ${{ secrets.PPA_GPG_PRIVATE_KEY }} - # gpg_passphrase: "" - # tarball: "meshtasticd_${{ steps.version.outputs.short }}.tar.xz" - # deb_email: "github-actions[bot]@users.noreply.github.com" - # deb_fullname: "github-actions[bot]" - # # Supported Ubuntu versions - # series: "plucky oracular noble jammy" + dput ppa:meshtastic/meshtastic-daily meshtasticd_${{ steps.version.outputs.deb }}~${{ inputs.series }}_source.changes diff --git a/bin/readprops.py b/bin/readprops.py index 4b730658a..68516b74c 100644 --- a/bin/readprops.py +++ b/bin/readprops.py @@ -10,6 +10,7 @@ def readProps(prefsLoc): version = dict(config.items("VERSION")) verObj = dict( short="{}.{}.{}".format(version["major"], version["minor"], version["build"]), + deb="unset", long="unset", ) @@ -27,13 +28,13 @@ def readProps(prefsLoc): # if isDirty: # # short for 'dirty', we want to keep our verstrings source for protobuf reasons # suffix = sha + "-d" - verObj["long"] = "{}.{}.{}.{}".format( - version["major"], version["minor"], version["build"], suffix - ) + verObj["long"] = "{}.{}".format(verObj["short"], suffix) + verObj["deb"] = "{}-ppa{}".format(verObj["short"], sha) except: # print("Unexpected error:", sys.exc_info()[0]) # traceback.print_exc() verObj["long"] = verObj["short"] + verObj["deb"] = "{}-ppa".format(verObj["short"]) # print("firmware version " + verStr) return verObj diff --git a/debian/ci_pack_sdeb.sh b/debian/ci_pack_sdeb.sh index 23490f1bd..b8c40decb 100755 --- a/debian/ci_pack_sdeb.sh +++ b/debian/ci_pack_sdeb.sh @@ -7,11 +7,10 @@ export PLATFORMIO_PACKAGES_DIR=pio/packages platformio pkg install -e native package=$(dpkg-parsechangelog --show-field Source) -pkg_version=$(dpkg-parsechangelog --show-field Version | cut -d- -f1) rm -rf debian/changelog -dch --create --distribution $SERIES --package $package --newversion $pkg_version-ppa${REVISION::7}~$SERIES \ - "GitHub Actions Automatic packaging for $SERIES" +dch --create --distribution $SERIES --package $package --newversion $PKG_VERSION~$SERIES \ + "GitHub Actions Automatic packaging for $PKG_VERSION~$SERIES" # Build the source deb debuild -S -k$GPG_KEY_ID From 29a7866fc11411f015698f2ef7326572bfbf0a80 Mon Sep 17 00:00:00 2001 From: Austin Date: Sun, 5 Jan 2025 15:26:56 -0500 Subject: [PATCH 16/41] Use jbennett for gpg email (#5759) --- debian/ci_pack_sdeb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/ci_pack_sdeb.sh b/debian/ci_pack_sdeb.sh index b8c40decb..72d3a9399 100755 --- a/debian/ci_pack_sdeb.sh +++ b/debian/ci_pack_sdeb.sh @@ -1,5 +1,5 @@ #!/usr/bin/bash -export DEBEMAIL="github-actions[bot]@users.noreply.github.com" +export DEBEMAIL="jbennett@incomsystems.biz" export PLATFORMIO_LIBDEPS_DIR=pio/libdeps export PLATFORMIO_PACKAGES_DIR=pio/packages From fb74e1d182f13d660c0c1ca597b471871ee7eebf Mon Sep 17 00:00:00 2001 From: Austin Date: Sun, 5 Jan 2025 16:00:01 -0500 Subject: [PATCH 17/41] meshtasticd-debian: set PLATFORMIO_CORE_DIR (#5760) --- .gitignore | 1 + debian/ci_pack_sdeb.sh | 1 + debian/rules | 1 + debian/source/options | 2 +- 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 8998b60d6..d44374919 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .pio +.pio_core pio # ignore vscode IDE settings files diff --git a/debian/ci_pack_sdeb.sh b/debian/ci_pack_sdeb.sh index 72d3a9399..f78738b65 100755 --- a/debian/ci_pack_sdeb.sh +++ b/debian/ci_pack_sdeb.sh @@ -2,6 +2,7 @@ export DEBEMAIL="jbennett@incomsystems.biz" export PLATFORMIO_LIBDEPS_DIR=pio/libdeps export PLATFORMIO_PACKAGES_DIR=pio/packages +export PLATFORMIO_CORE_DIR=.pio_core # Download libraries to `libdeps` platformio pkg install -e native diff --git a/debian/rules b/debian/rules index f535ad6eb..ccff53eb3 100755 --- a/debian/rules +++ b/debian/rules @@ -7,6 +7,7 @@ # https://docs.platformio.org/en/latest/envvars.html PIO_ENV:=\ + PLATFORMIO_CORE_DIR=.pio_core \ PLATFORMIO_LIBDEPS_DIR=pio/libdeps \ PLATFORMIO_PACKAGES_DIR=pio/packages diff --git a/debian/source/options b/debian/source/options index 0553b485d..94358cb74 100644 --- a/debian/source/options +++ b/debian/source/options @@ -1 +1 @@ -extend-diff-ignore = "\.pio" \ No newline at end of file +extend-diff-ignore = "\.pio\w*?$" \ No newline at end of file From b0087fd32827df20e6910d2a8e030a0863bc6dd1 Mon Sep 17 00:00:00 2001 From: Austin Date: Sun, 5 Jan 2025 16:26:31 -0500 Subject: [PATCH 18/41] meshtasticd-debian: Include core_dir in sdeb (#5761) --- debian/ci_pack_sdeb.sh | 2 +- debian/rules | 2 +- debian/source/include-binaries | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/debian/ci_pack_sdeb.sh b/debian/ci_pack_sdeb.sh index f78738b65..9ce334859 100755 --- a/debian/ci_pack_sdeb.sh +++ b/debian/ci_pack_sdeb.sh @@ -2,7 +2,7 @@ export DEBEMAIL="jbennett@incomsystems.biz" export PLATFORMIO_LIBDEPS_DIR=pio/libdeps export PLATFORMIO_PACKAGES_DIR=pio/packages -export PLATFORMIO_CORE_DIR=.pio_core +export PLATFORMIO_CORE_DIR=pio/core # Download libraries to `libdeps` platformio pkg install -e native diff --git a/debian/rules b/debian/rules index ccff53eb3..8098c4edb 100755 --- a/debian/rules +++ b/debian/rules @@ -7,7 +7,7 @@ # https://docs.platformio.org/en/latest/envvars.html PIO_ENV:=\ - PLATFORMIO_CORE_DIR=.pio_core \ + PLATFORMIO_CORE_DIR=pio/core \ PLATFORMIO_LIBDEPS_DIR=pio/libdeps \ PLATFORMIO_PACKAGES_DIR=pio/packages diff --git a/debian/source/include-binaries b/debian/source/include-binaries index 1632328ca..aef4a7027 100644 --- a/debian/source/include-binaries +++ b/debian/source/include-binaries @@ -1,2 +1,3 @@ pio/libdeps -pio/packages \ No newline at end of file +pio/packages +pio/core \ No newline at end of file From 403fa15a3f182e1db336f8759352f69ec4801dcd Mon Sep 17 00:00:00 2001 From: Austin Date: Sun, 5 Jan 2025 16:55:04 -0500 Subject: [PATCH 19/41] meshtasticd-debian: Include run in version (#5762) --- bin/readprops.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/bin/readprops.py b/bin/readprops.py index 68516b74c..8a1d3dc47 100644 --- a/bin/readprops.py +++ b/bin/readprops.py @@ -1,6 +1,7 @@ import configparser import subprocess - +import os +run_number = os.getenv('GITHUB_RUN_NUMBER', '0') def readProps(prefsLoc): """Read the version of our project as a string""" @@ -29,12 +30,12 @@ def readProps(prefsLoc): # # short for 'dirty', we want to keep our verstrings source for protobuf reasons # suffix = sha + "-d" verObj["long"] = "{}.{}".format(verObj["short"], suffix) - verObj["deb"] = "{}-ppa{}".format(verObj["short"], sha) + verObj["deb"] = "{}-{}~ppa{}".format(verObj["short"], run_number, sha) except: # print("Unexpected error:", sys.exc_info()[0]) # traceback.print_exc() verObj["long"] = verObj["short"] - verObj["deb"] = "{}-ppa".format(verObj["short"]) + verObj["deb"] = "{}-{}~ppa".format(verObj["short"], run_number) # print("firmware version " + verStr) return verObj From 9cc79b1d1ed65ad280acb7d12e51863d700d5752 Mon Sep 17 00:00:00 2001 From: GUVWAF <78759985+GUVWAF@users.noreply.github.com> Date: Mon, 6 Jan 2025 01:55:20 +0100 Subject: [PATCH 20/41] Explicitly set CAD symbols, improve slot time calculation and adjust CW size accordingly (#5749) Co-authored-by: Ben Meadors --- src/mesh/LR11x0Interface.cpp | 9 ++++++++- src/mesh/RadioInterface.cpp | 25 ++++++++++++++++++++++--- src/mesh/RadioInterface.h | 16 +++++++--------- src/mesh/SX126xInterface.cpp | 9 ++++++++- src/mesh/SX128xInterface.cpp | 9 ++++++++- 5 files changed, 53 insertions(+), 15 deletions(-) diff --git a/src/mesh/LR11x0Interface.cpp b/src/mesh/LR11x0Interface.cpp index ce4f912ba..6a4e7404e 100644 --- a/src/mesh/LR11x0Interface.cpp +++ b/src/mesh/LR11x0Interface.cpp @@ -256,10 +256,17 @@ template void LR11x0Interface::startReceive() template bool LR11x0Interface::isChannelActive() { // check if we can detect a LoRa preamble on the current channel + ChannelScanConfig_t cfg = {.cad = {.symNum = NUM_SYM_CAD, + .detPeak = RADIOLIB_LR11X0_CAD_PARAM_DEFAULT, + .detMin = RADIOLIB_LR11X0_CAD_PARAM_DEFAULT, + .exitMode = RADIOLIB_LR11X0_CAD_PARAM_DEFAULT, + .timeout = 0, + .irqFlags = RADIOLIB_IRQ_CAD_DEFAULT_FLAGS, + .irqMask = RADIOLIB_IRQ_CAD_DEFAULT_MASK}}; int16_t result; setStandby(); - result = lora.scanChannel(); + result = lora.scanChannel(cfg); if (result == RADIOLIB_LORA_DETECTED) return true; diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index b1403f3b6..c51ad8144 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -261,7 +261,7 @@ uint8_t RadioInterface::getCWsize(float snr) const uint32_t SNR_MIN = -20; // The maximum value for a LoRa SNR - const uint32_t SNR_MAX = 15; + const uint32_t SNR_MAX = 10; return map(snr, SNR_MIN, SNR_MAX, CWmin, CWmax); } @@ -566,7 +566,7 @@ void RadioInterface::applyModemConfig() saveChannelNum(channel_num); saveFreq(freq + loraConfig.frequency_offset); - slotTimeMsec = computeSlotTimeMsec(bw, sf); + slotTimeMsec = computeSlotTimeMsec(); preambleTimeMsec = getPacketTime((uint32_t)0); maxPacketTimeMsec = getPacketTime(meshtastic_Constants_DATA_PAYLOAD_LEN + sizeof(PacketHeader)); @@ -581,6 +581,25 @@ void RadioInterface::applyModemConfig() LOG_INFO("Slot time: %u msec", slotTimeMsec); } +/** Slottime is the time to detect a transmission has started, consisting of: + - CAD duration; + - roundtrip air propagation time (assuming max. 30km between nodes); + - Tx/Rx turnaround time (maximum of SX126x and SX127x); + - MAC processing time (measured on T-beam) */ +uint32_t RadioInterface::computeSlotTimeMsec() +{ + float sumPropagationTurnaroundMACTime = 0.2 + 0.4 + 7; // in milliseconds + float symbolTime = pow(2, sf) / bw; // in milliseconds + + if (myRegion->wideLora) { + // CAD duration derived from AN1200.22 of SX1280 + return (NUM_SYM_CAD_24GHZ + (2 * sf + 3) / 32) * symbolTime + sumPropagationTurnaroundMACTime; + } else { + // CAD duration for SX127x is max. 2.25 symbols, for SX126x it is number of symbols + 0.5 symbol + return max(2.25, NUM_SYM_CAD + 0.5) * symbolTime + sumPropagationTurnaroundMACTime; + } +} + /** * Some regulatory regions limit xmit power. * This function should be called by subclasses after setting their desired power. It might lower it @@ -637,4 +656,4 @@ size_t RadioInterface::beginSending(meshtastic_MeshPacket *p) sendingPacket = p; return p->encrypted.size + sizeof(PacketHeader); -} +} \ No newline at end of file diff --git a/src/mesh/RadioInterface.h b/src/mesh/RadioInterface.h index 652b2269c..41ab0393d 100644 --- a/src/mesh/RadioInterface.h +++ b/src/mesh/RadioInterface.h @@ -83,24 +83,22 @@ class RadioInterface float bw = 125; uint8_t sf = 9; uint8_t cr = 5; - /** Slottime is the minimum time to wait, consisting of: - - CAD duration (maximum of SX126x and SX127x); - - roundtrip air propagation time (assuming max. 30km between nodes); - - Tx/Rx turnaround time (maximum of SX126x and SX127x); - - MAC processing time (measured on T-beam) */ - uint32_t slotTimeMsec = computeSlotTimeMsec(bw, sf); + + const uint8_t NUM_SYM_CAD = 2; // Number of symbols used for CAD, 2 is the default since RadioLib 6.3.0 as per AN1200.48 + const uint8_t NUM_SYM_CAD_24GHZ = 4; // Number of symbols used for CAD in 2.4 GHz, 4 is recommended in AN1200.22 of SX1280 + uint32_t slotTimeMsec = computeSlotTimeMsec(); uint16_t preambleLength = 16; // 8 is default, but we use longer to increase the amount of sleep time when receiving uint32_t preambleTimeMsec = 165; // calculated on startup, this is the default for LongFast uint32_t maxPacketTimeMsec = 3246; // calculated on startup, this is the default for LongFast const uint32_t PROCESSING_TIME_MSEC = 4500; // time to construct, process and construct a packet again (empirically determined) - const uint8_t CWmin = 2; // minimum CWsize - const uint8_t CWmax = 7; // maximum CWsize + const uint8_t CWmin = 3; // minimum CWsize + const uint8_t CWmax = 8; // maximum CWsize meshtastic_MeshPacket *sendingPacket = NULL; // The packet we are currently sending uint32_t lastTxStart = 0L; - uint32_t computeSlotTimeMsec(float bw, float sf) { return 8.5 * pow(2, sf) / bw + 0.2 + 0.4 + 7; } + uint32_t computeSlotTimeMsec(); /** * A temporary buffer used for sending/receiving packets, sized to hold the biggest buffer we might need diff --git a/src/mesh/SX126xInterface.cpp b/src/mesh/SX126xInterface.cpp index ed0267c5b..59ba139bf 100644 --- a/src/mesh/SX126xInterface.cpp +++ b/src/mesh/SX126xInterface.cpp @@ -299,10 +299,17 @@ template void SX126xInterface::startReceive() template bool SX126xInterface::isChannelActive() { // check if we can detect a LoRa preamble on the current channel + ChannelScanConfig_t cfg = {.cad = {.symNum = NUM_SYM_CAD, + .detPeak = RADIOLIB_SX126X_CAD_PARAM_DEFAULT, + .detMin = RADIOLIB_SX126X_CAD_PARAM_DEFAULT, + .exitMode = RADIOLIB_SX126X_CAD_PARAM_DEFAULT, + .timeout = 0, + .irqFlags = RADIOLIB_IRQ_CAD_DEFAULT_FLAGS, + .irqMask = RADIOLIB_IRQ_CAD_DEFAULT_MASK}}; int16_t result; setStandby(); - result = lora.scanChannel(); + result = lora.scanChannel(cfg); if (result == RADIOLIB_LORA_DETECTED) return true; if (result != RADIOLIB_CHANNEL_FREE) diff --git a/src/mesh/SX128xInterface.cpp b/src/mesh/SX128xInterface.cpp index 013164bca..1ae26db91 100644 --- a/src/mesh/SX128xInterface.cpp +++ b/src/mesh/SX128xInterface.cpp @@ -275,10 +275,17 @@ template void SX128xInterface::startReceive() template bool SX128xInterface::isChannelActive() { // check if we can detect a LoRa preamble on the current channel + ChannelScanConfig_t cfg = {.cad = {.symNum = NUM_SYM_CAD_24GHZ, + .detPeak = 0, + .detMin = 0, + .exitMode = 0, + .timeout = 0, + .irqFlags = RADIOLIB_IRQ_CAD_DEFAULT_FLAGS, + .irqMask = RADIOLIB_IRQ_CAD_DEFAULT_MASK}}; int16_t result; setStandby(); - result = lora.scanChannel(); + result = lora.scanChannel(cfg); if (result == RADIOLIB_LORA_DETECTED) return true; if (result != RADIOLIB_CHANNEL_FREE) From 4fcf7fe0277aeb02a83b99b20b2e58aaa25de91a Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Sun, 5 Jan 2025 18:55:55 -0600 Subject: [PATCH 21/41] =?UTF-8?q?Revert=20"Explicitly=20set=20CAD=20symbol?= =?UTF-8?q?s,=20improve=20slot=20time=20calculation=20and=20adjust=20?= =?UTF-8?q?=E2=80=A6"=20(#5765)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 9cc79b1d1ed65ad280acb7d12e51863d700d5752. --- src/mesh/LR11x0Interface.cpp | 9 +-------- src/mesh/RadioInterface.cpp | 25 +++---------------------- src/mesh/RadioInterface.h | 16 +++++++++------- src/mesh/SX126xInterface.cpp | 9 +-------- src/mesh/SX128xInterface.cpp | 9 +-------- 5 files changed, 15 insertions(+), 53 deletions(-) diff --git a/src/mesh/LR11x0Interface.cpp b/src/mesh/LR11x0Interface.cpp index 6a4e7404e..ce4f912ba 100644 --- a/src/mesh/LR11x0Interface.cpp +++ b/src/mesh/LR11x0Interface.cpp @@ -256,17 +256,10 @@ template void LR11x0Interface::startReceive() template bool LR11x0Interface::isChannelActive() { // check if we can detect a LoRa preamble on the current channel - ChannelScanConfig_t cfg = {.cad = {.symNum = NUM_SYM_CAD, - .detPeak = RADIOLIB_LR11X0_CAD_PARAM_DEFAULT, - .detMin = RADIOLIB_LR11X0_CAD_PARAM_DEFAULT, - .exitMode = RADIOLIB_LR11X0_CAD_PARAM_DEFAULT, - .timeout = 0, - .irqFlags = RADIOLIB_IRQ_CAD_DEFAULT_FLAGS, - .irqMask = RADIOLIB_IRQ_CAD_DEFAULT_MASK}}; int16_t result; setStandby(); - result = lora.scanChannel(cfg); + result = lora.scanChannel(); if (result == RADIOLIB_LORA_DETECTED) return true; diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index c51ad8144..b1403f3b6 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -261,7 +261,7 @@ uint8_t RadioInterface::getCWsize(float snr) const uint32_t SNR_MIN = -20; // The maximum value for a LoRa SNR - const uint32_t SNR_MAX = 10; + const uint32_t SNR_MAX = 15; return map(snr, SNR_MIN, SNR_MAX, CWmin, CWmax); } @@ -566,7 +566,7 @@ void RadioInterface::applyModemConfig() saveChannelNum(channel_num); saveFreq(freq + loraConfig.frequency_offset); - slotTimeMsec = computeSlotTimeMsec(); + slotTimeMsec = computeSlotTimeMsec(bw, sf); preambleTimeMsec = getPacketTime((uint32_t)0); maxPacketTimeMsec = getPacketTime(meshtastic_Constants_DATA_PAYLOAD_LEN + sizeof(PacketHeader)); @@ -581,25 +581,6 @@ void RadioInterface::applyModemConfig() LOG_INFO("Slot time: %u msec", slotTimeMsec); } -/** Slottime is the time to detect a transmission has started, consisting of: - - CAD duration; - - roundtrip air propagation time (assuming max. 30km between nodes); - - Tx/Rx turnaround time (maximum of SX126x and SX127x); - - MAC processing time (measured on T-beam) */ -uint32_t RadioInterface::computeSlotTimeMsec() -{ - float sumPropagationTurnaroundMACTime = 0.2 + 0.4 + 7; // in milliseconds - float symbolTime = pow(2, sf) / bw; // in milliseconds - - if (myRegion->wideLora) { - // CAD duration derived from AN1200.22 of SX1280 - return (NUM_SYM_CAD_24GHZ + (2 * sf + 3) / 32) * symbolTime + sumPropagationTurnaroundMACTime; - } else { - // CAD duration for SX127x is max. 2.25 symbols, for SX126x it is number of symbols + 0.5 symbol - return max(2.25, NUM_SYM_CAD + 0.5) * symbolTime + sumPropagationTurnaroundMACTime; - } -} - /** * Some regulatory regions limit xmit power. * This function should be called by subclasses after setting their desired power. It might lower it @@ -656,4 +637,4 @@ size_t RadioInterface::beginSending(meshtastic_MeshPacket *p) sendingPacket = p; return p->encrypted.size + sizeof(PacketHeader); -} \ No newline at end of file +} diff --git a/src/mesh/RadioInterface.h b/src/mesh/RadioInterface.h index 41ab0393d..652b2269c 100644 --- a/src/mesh/RadioInterface.h +++ b/src/mesh/RadioInterface.h @@ -83,22 +83,24 @@ class RadioInterface float bw = 125; uint8_t sf = 9; uint8_t cr = 5; - - const uint8_t NUM_SYM_CAD = 2; // Number of symbols used for CAD, 2 is the default since RadioLib 6.3.0 as per AN1200.48 - const uint8_t NUM_SYM_CAD_24GHZ = 4; // Number of symbols used for CAD in 2.4 GHz, 4 is recommended in AN1200.22 of SX1280 - uint32_t slotTimeMsec = computeSlotTimeMsec(); + /** Slottime is the minimum time to wait, consisting of: + - CAD duration (maximum of SX126x and SX127x); + - roundtrip air propagation time (assuming max. 30km between nodes); + - Tx/Rx turnaround time (maximum of SX126x and SX127x); + - MAC processing time (measured on T-beam) */ + uint32_t slotTimeMsec = computeSlotTimeMsec(bw, sf); uint16_t preambleLength = 16; // 8 is default, but we use longer to increase the amount of sleep time when receiving uint32_t preambleTimeMsec = 165; // calculated on startup, this is the default for LongFast uint32_t maxPacketTimeMsec = 3246; // calculated on startup, this is the default for LongFast const uint32_t PROCESSING_TIME_MSEC = 4500; // time to construct, process and construct a packet again (empirically determined) - const uint8_t CWmin = 3; // minimum CWsize - const uint8_t CWmax = 8; // maximum CWsize + const uint8_t CWmin = 2; // minimum CWsize + const uint8_t CWmax = 7; // maximum CWsize meshtastic_MeshPacket *sendingPacket = NULL; // The packet we are currently sending uint32_t lastTxStart = 0L; - uint32_t computeSlotTimeMsec(); + uint32_t computeSlotTimeMsec(float bw, float sf) { return 8.5 * pow(2, sf) / bw + 0.2 + 0.4 + 7; } /** * A temporary buffer used for sending/receiving packets, sized to hold the biggest buffer we might need diff --git a/src/mesh/SX126xInterface.cpp b/src/mesh/SX126xInterface.cpp index 59ba139bf..ed0267c5b 100644 --- a/src/mesh/SX126xInterface.cpp +++ b/src/mesh/SX126xInterface.cpp @@ -299,17 +299,10 @@ template void SX126xInterface::startReceive() template bool SX126xInterface::isChannelActive() { // check if we can detect a LoRa preamble on the current channel - ChannelScanConfig_t cfg = {.cad = {.symNum = NUM_SYM_CAD, - .detPeak = RADIOLIB_SX126X_CAD_PARAM_DEFAULT, - .detMin = RADIOLIB_SX126X_CAD_PARAM_DEFAULT, - .exitMode = RADIOLIB_SX126X_CAD_PARAM_DEFAULT, - .timeout = 0, - .irqFlags = RADIOLIB_IRQ_CAD_DEFAULT_FLAGS, - .irqMask = RADIOLIB_IRQ_CAD_DEFAULT_MASK}}; int16_t result; setStandby(); - result = lora.scanChannel(cfg); + result = lora.scanChannel(); if (result == RADIOLIB_LORA_DETECTED) return true; if (result != RADIOLIB_CHANNEL_FREE) diff --git a/src/mesh/SX128xInterface.cpp b/src/mesh/SX128xInterface.cpp index 1ae26db91..013164bca 100644 --- a/src/mesh/SX128xInterface.cpp +++ b/src/mesh/SX128xInterface.cpp @@ -275,17 +275,10 @@ template void SX128xInterface::startReceive() template bool SX128xInterface::isChannelActive() { // check if we can detect a LoRa preamble on the current channel - ChannelScanConfig_t cfg = {.cad = {.symNum = NUM_SYM_CAD_24GHZ, - .detPeak = 0, - .detMin = 0, - .exitMode = 0, - .timeout = 0, - .irqFlags = RADIOLIB_IRQ_CAD_DEFAULT_FLAGS, - .irqMask = RADIOLIB_IRQ_CAD_DEFAULT_MASK}}; int16_t result; setStandby(); - result = lora.scanChannel(cfg); + result = lora.scanChannel(); if (result == RADIOLIB_LORA_DETECTED) return true; if (result != RADIOLIB_CHANNEL_FREE) From c003ab0eeef1d55a5f267e113c3aa18ed8254947 Mon Sep 17 00:00:00 2001 From: isseysandei Date: Mon, 6 Jan 2025 01:58:10 +0100 Subject: [PATCH 22/41] Improved readability of Power Telemetry page (#5746) * increased buffer size to 1024 * better readability --- src/modules/Telemetry/PowerTelemetry.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/modules/Telemetry/PowerTelemetry.cpp b/src/modules/Telemetry/PowerTelemetry.cpp index 10133fca5..f1df2d361 100644 --- a/src/modules/Telemetry/PowerTelemetry.cpp +++ b/src/modules/Telemetry/PowerTelemetry.cpp @@ -99,11 +99,11 @@ bool PowerTelemetryModule::wantUIFrame() void PowerTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { display->setTextAlignment(TEXT_ALIGN_LEFT); - display->setFont(FONT_MEDIUM); + display->setFont(FONT_SMALL); display->drawString(x, y, "Power Telemetry"); if (lastMeasurementPacket == nullptr) { display->setFont(FONT_SMALL); - display->drawString(x, y += _fontHeight(FONT_MEDIUM), "No measurement"); + display->drawString(x, y += _fontHeight(FONT_SMALL), "No measurement"); return; } @@ -122,21 +122,21 @@ void PowerTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *s // Display current and voltage based on ...power_metrics.has_[channel/voltage/current]... flags display->setFont(FONT_SMALL); - display->drawString(x, y += _fontHeight(FONT_MEDIUM) - 2, "From: " + String(lastSender) + "(" + String(agoSecs) + "s)"); + display->drawString(x, y += _fontHeight(FONT_SMALL) - 2, "From: " + String(lastSender) + "(" + String(agoSecs) + "s)"); if (lastMeasurement.variant.power_metrics.has_ch1_voltage || lastMeasurement.variant.power_metrics.has_ch1_current) { display->drawString(x, y += _fontHeight(FONT_SMALL), - "Ch1 Volt: " + String(lastMeasurement.variant.power_metrics.ch1_voltage, 2) + - "V / Curr: " + String(lastMeasurement.variant.power_metrics.ch1_current, 0) + "mA"); + "Ch1: " + String(lastMeasurement.variant.power_metrics.ch1_voltage, 2) + + "V " + String(lastMeasurement.variant.power_metrics.ch1_current, 0) + "mA"); } if (lastMeasurement.variant.power_metrics.has_ch2_voltage || lastMeasurement.variant.power_metrics.has_ch2_current) { display->drawString(x, y += _fontHeight(FONT_SMALL), - "Ch2 Volt: " + String(lastMeasurement.variant.power_metrics.ch2_voltage, 2) + - "V / Curr: " + String(lastMeasurement.variant.power_metrics.ch2_current, 0) + "mA"); + "Ch2: " + String(lastMeasurement.variant.power_metrics.ch2_voltage, 2) + + "V " + String(lastMeasurement.variant.power_metrics.ch2_current, 0) + "mA"); } if (lastMeasurement.variant.power_metrics.has_ch3_voltage || lastMeasurement.variant.power_metrics.has_ch3_current) { display->drawString(x, y += _fontHeight(FONT_SMALL), - "Ch3 Volt: " + String(lastMeasurement.variant.power_metrics.ch3_voltage, 2) + - "V / Curr: " + String(lastMeasurement.variant.power_metrics.ch3_current, 0) + "mA"); + "Ch3: " + String(lastMeasurement.variant.power_metrics.ch3_voltage, 2) + + "V " + String(lastMeasurement.variant.power_metrics.ch3_current, 0) + "mA"); } } From d3cbbfd3455876e4f8b63392fe23b4c5e4821e3a Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sun, 5 Jan 2025 18:59:14 -0600 Subject: [PATCH 23/41] Try adding tar-ignore to preserve .git directories --- debian/source/options | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/debian/source/options b/debian/source/options index 94358cb74..2f3670cba 100644 --- a/debian/source/options +++ b/debian/source/options @@ -1 +1,2 @@ -extend-diff-ignore = "\.pio\w*?$" \ No newline at end of file +extend-diff-ignore = "\.pio\w*?$" +tar-ignore = "" From 2396aa77ca625bb2e749419c41465b008aba3ed8 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sun, 5 Jan 2025 19:03:44 -0600 Subject: [PATCH 24/41] don't run the clean step --- debian/ci_pack_sdeb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/ci_pack_sdeb.sh b/debian/ci_pack_sdeb.sh index 9ce334859..2b56a8578 100755 --- a/debian/ci_pack_sdeb.sh +++ b/debian/ci_pack_sdeb.sh @@ -14,4 +14,4 @@ dch --create --distribution $SERIES --package $package --newversion $PKG_VERSION "GitHub Actions Automatic packaging for $PKG_VERSION~$SERIES" # Build the source deb -debuild -S -k$GPG_KEY_ID +debuild -S -nc -k$GPG_KEY_ID From 7f280dd55609e7ce6fc2bba41956d2191ca7563d Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sun, 5 Jan 2025 19:38:08 -0600 Subject: [PATCH 25/41] Hide pio folder in a tarball to preserve .git folders --- debian/ci_pack_sdeb.sh | 1 + debian/rules | 1 + 2 files changed, 2 insertions(+) diff --git a/debian/ci_pack_sdeb.sh b/debian/ci_pack_sdeb.sh index 2b56a8578..6204855cf 100755 --- a/debian/ci_pack_sdeb.sh +++ b/debian/ci_pack_sdeb.sh @@ -6,6 +6,7 @@ export PLATFORMIO_CORE_DIR=pio/core # Download libraries to `libdeps` platformio pkg install -e native +tar -cf pio.tar pio/ package=$(dpkg-parsechangelog --show-field Source) diff --git a/debian/rules b/debian/rules index 8098c4edb..f67622c5c 100755 --- a/debian/rules +++ b/debian/rules @@ -13,6 +13,7 @@ PIO_ENV:=\ override_dh_auto_build: # Build with platformio + tar -xf pio.tar $(PIO_ENV) platformio run -e native # Move the binary and default config to the correct name mv .pio/build/native/program .pio/build/native/meshtasticd From 6edf74e8f14aa1c580809a34bc6f871590b7d196 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sun, 5 Jan 2025 19:58:34 -0600 Subject: [PATCH 26/41] Tab not spaces --- debian/rules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/rules b/debian/rules index f67622c5c..28961fd10 100755 --- a/debian/rules +++ b/debian/rules @@ -13,7 +13,7 @@ PIO_ENV:=\ override_dh_auto_build: # Build with platformio - tar -xf pio.tar + tar -xf pio.tar $(PIO_ENV) platformio run -e native # Move the binary and default config to the correct name mv .pio/build/native/program .pio/build/native/meshtasticd From 16bc89ea573a87ad40ead100dab6b150f71ddbdc Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sun, 5 Jan 2025 22:23:01 -0600 Subject: [PATCH 27/41] Explicitly install tools-scons --- debian/ci_pack_sdeb.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/debian/ci_pack_sdeb.sh b/debian/ci_pack_sdeb.sh index 6204855cf..605ddd288 100755 --- a/debian/ci_pack_sdeb.sh +++ b/debian/ci_pack_sdeb.sh @@ -6,7 +6,9 @@ export PLATFORMIO_CORE_DIR=pio/core # Download libraries to `libdeps` platformio pkg install -e native +platformio pkg install -t tool-scons -e native tar -cf pio.tar pio/ +rm -rf pio package=$(dpkg-parsechangelog --show-field Source) From f1a890028813ea8bdcbe6d0fb15d2b284db90e8e Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Sun, 5 Jan 2025 23:50:32 -0600 Subject: [PATCH 28/41] Don't push to PPA for every commit --- .github/workflows/main_matrix.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index be8cddaf3..267e34a94 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -128,16 +128,6 @@ jobs: with: board: ${{ matrix.board }} - package-ppa: - strategy: - fail-fast: false - matrix: - series: [plucky, oracular, noble, jammy] - uses: ./.github/workflows/package_ppa.yml - with: - series: ${{ matrix.series }} - secrets: inherit - package-raspbian: uses: ./.github/workflows/package_raspbian.yml From 70076a4b27193276ad22cd132c2c1e5f178d4920 Mon Sep 17 00:00:00 2001 From: isseysandei Date: Mon, 6 Jan 2025 16:14:52 +0100 Subject: [PATCH 29/41] Improved Power Telemetry page readability even more (#5770) * increased buffer size to 1024 * better readability * better readability 2 --------- Co-authored-by: BuildTools --- src/modules/Telemetry/PowerTelemetry.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/modules/Telemetry/PowerTelemetry.cpp b/src/modules/Telemetry/PowerTelemetry.cpp index f1df2d361..9c794e31e 100644 --- a/src/modules/Telemetry/PowerTelemetry.cpp +++ b/src/modules/Telemetry/PowerTelemetry.cpp @@ -100,29 +100,30 @@ void PowerTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *s { display->setTextAlignment(TEXT_ALIGN_LEFT); display->setFont(FONT_SMALL); - display->drawString(x, y, "Power Telemetry"); + if (lastMeasurementPacket == nullptr) { - display->setFont(FONT_SMALL); + // In case of no valid packet, display "Power Telemetry", "No measurement" + display->drawString(x, y, "Power Telemetry"); display->drawString(x, y += _fontHeight(FONT_SMALL), "No measurement"); return; } + // Decode the last power packet meshtastic_Telemetry lastMeasurement; - uint32_t agoSecs = service->GetTimeSinceMeshPacket(lastMeasurementPacket); const char *lastSender = getSenderShortName(*lastMeasurementPacket); const meshtastic_Data &p = lastMeasurementPacket->decoded; if (!pb_decode_from_bytes(p.payload.bytes, p.payload.size, &meshtastic_Telemetry_msg, &lastMeasurement)) { - display->setFont(FONT_SMALL); - display->drawString(x, y += _fontHeight(FONT_MEDIUM), "Measurement Error"); + display->drawString(x, y, "Measurement Error"); LOG_ERROR("Unable to decode last packet"); return; } + // Display "Pow. From: ..." + display->drawString(x, y, "Pow. From: " + String(lastSender) + "(" + String(agoSecs) + "s)"); + // Display current and voltage based on ...power_metrics.has_[channel/voltage/current]... flags - display->setFont(FONT_SMALL); - display->drawString(x, y += _fontHeight(FONT_SMALL) - 2, "From: " + String(lastSender) + "(" + String(agoSecs) + "s)"); if (lastMeasurement.variant.power_metrics.has_ch1_voltage || lastMeasurement.variant.power_metrics.has_ch1_current) { display->drawString(x, y += _fontHeight(FONT_SMALL), "Ch1: " + String(lastMeasurement.variant.power_metrics.ch1_voltage, 2) + From 35cd600c54d7ad760a1b06d4c91d1dc5b35a3ef8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Mon, 6 Jan 2025 17:08:12 +0100 Subject: [PATCH 30/41] update to 7.1.2 and remove the obsolete default_envs. (#5771) --- platformio.ini | 41 ++--------------------------------------- 1 file changed, 2 insertions(+), 39 deletions(-) diff --git a/platformio.ini b/platformio.ini index cd32ed179..6a4466c01 100644 --- a/platformio.ini +++ b/platformio.ini @@ -3,43 +3,7 @@ [platformio] default_envs = tbeam -;default_envs = pico -;default_envs = tbeam-s3-core -;default_envs = tbeam0.7 -;default_envs = heltec-v1 -;default_envs = heltec-v2_0 -;default_envs = heltec-v2_1 -;default_envs = heltec-wireless-tracker -;default_envs = chatter2 -;default_envs = tlora-v1 -;default_envs = tlora_v1_3 -;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 -;default_envs = native -;default_envs = nano-g1 -;default_envs = pca10059_diy_eink -;default_envs = meshtastic-diy-v1 -;default_envs = meshtastic-diy-v1_1 -;default_envs = meshtastic-dr-dev -;default_envs = m5stack-coreink -;default_envs = rak4631 -;default_envs = rak4631_eth_gw -;default_envs = rak2560 -;default_envs = rak11310 -;default_envs = rak_wismeshtap -;default_envs = wio-e5 -;default_envs = radiomaster_900_bandit_nano -;default_envs = radiomaster_900_bandit_micro -;default_envs = radiomaster_900_bandit -;default_envs = heltec_vision_master_t190 -;default_envs = heltec_vision_master_e213 -;default_envs = heltec_vision_master_e290 -;default_envs = heltec_mesh_node_t114 + extra_configs = arch/*/*.ini variants/*/platformio.ini @@ -124,8 +88,7 @@ lib_deps = [radiolib_base] lib_deps = - ; jgromes/RadioLib@7.1.0 - https://github.com/jgromes/RadioLib.git#92b687821ff4e6c358d866f84566f66672ab02b8 + jgromes/RadioLib@7.1.2 ; Common libs for environmental measurements in telemetry module ; (not included in native / portduino) From ca328898939edb22d50d0b3d62f475e352d29069 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Mon, 6 Jan 2025 12:23:08 -0600 Subject: [PATCH 31/41] Specify scons version --- debian/ci_pack_sdeb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/ci_pack_sdeb.sh b/debian/ci_pack_sdeb.sh index 605ddd288..07737ea31 100755 --- a/debian/ci_pack_sdeb.sh +++ b/debian/ci_pack_sdeb.sh @@ -6,7 +6,7 @@ export PLATFORMIO_CORE_DIR=pio/core # Download libraries to `libdeps` platformio pkg install -e native -platformio pkg install -t tool-scons -e native +platformio pkg install -t platformio/tool-scons@4.40801.0 tar -cf pio.tar pio/ rm -rf pio From 78371dfdb7a8892e9bc9a45d432eef8c799ac747 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Mon, 6 Jan 2025 12:26:17 -0600 Subject: [PATCH 32/41] Add PPA to nightly --- .github/workflows/nightly.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index e249823a7..5010707de 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -17,3 +17,12 @@ jobs: uses: trunk-io/trunk-action@782e83f803ca6e369f035d64c6ba2768174ba61b with: trunk-token: ${{ secrets.TRUNK_TOKEN }} + package-ppa: + strategy: + fail-fast: false + matrix: + series: [plucky, oracular, noble, jammy] + uses: ./.github/workflows/package_ppa.yml + with: + series: ${{ matrix.series }} + secrets: inherit From 4c3a3ca47d4ee50e2d946956fe614d6e7549df8a Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Mon, 6 Jan 2025 13:02:53 -0600 Subject: [PATCH 33/41] Specify the *correct* scons version --- debian/ci_pack_sdeb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/ci_pack_sdeb.sh b/debian/ci_pack_sdeb.sh index 07737ea31..427e9c79b 100755 --- a/debian/ci_pack_sdeb.sh +++ b/debian/ci_pack_sdeb.sh @@ -6,7 +6,7 @@ export PLATFORMIO_CORE_DIR=pio/core # Download libraries to `libdeps` platformio pkg install -e native -platformio pkg install -t platformio/tool-scons@4.40801.0 +platformio pkg install -t platformio/tool-scons@4.40502.0 tar -cf pio.tar pio/ rm -rf pio From e5dbcf5bcee1fd6fe8f4a71ea0105ce211c54d36 Mon Sep 17 00:00:00 2001 From: Austin Date: Mon, 6 Jan 2025 17:20:05 -0500 Subject: [PATCH 34/41] meshtasticd-debian: parameterize target PPA (#5776) --- .github/workflows/build_debian_src.yml | 8 ++++---- .github/workflows/nightly.yml | 1 + .github/workflows/package_ppa.yml | 8 ++++++-- debian/ci_pack_sdeb.sh | 4 ++-- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build_debian_src.yml b/.github/workflows/build_debian_src.yml index 9bb7dfb9c..b2fcb5262 100644 --- a/.github/workflows/build_debian_src.yml +++ b/.github/workflows/build_debian_src.yml @@ -7,7 +7,7 @@ on: required: true inputs: series: - description: 'Ubuntu series to target' + description: Ubuntu series to target required: true type: string @@ -32,9 +32,9 @@ jobs: working-directory: meshtasticd run: | sudo apt-get update -y --fix-missing - sudo apt-get install -y software-properties-common - sudo add-apt-repository ppa:meshtastic/meshtastic-daily -y - sudo apt-get install -y build-essential devscripts equivs + sudo apt-get install -y software-properties-common build-essential devscripts equivs + sudo add-apt-repository ppa:meshtastic/build-tools -y + sudo apt-get update -y --fix-missing sudo mk-build-deps --install --remove --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control - name: Import GPG key diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 5010707de..b7cf4bfc6 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -24,5 +24,6 @@ jobs: series: [plucky, oracular, noble, jammy] uses: ./.github/workflows/package_ppa.yml with: + ppa_repo: daily series: ${{ matrix.series }} secrets: inherit diff --git a/.github/workflows/package_ppa.yml b/.github/workflows/package_ppa.yml index f716fdff4..5705c6d49 100644 --- a/.github/workflows/package_ppa.yml +++ b/.github/workflows/package_ppa.yml @@ -6,8 +6,12 @@ on: PPA_GPG_PRIVATE_KEY: required: true inputs: + ppa_repo: + description: Meshtastic PPA to target + required: true + type: string series: - description: 'Ubuntu series to target' + description: Ubuntu series to target required: true type: string workflow_dispatch: @@ -65,4 +69,4 @@ jobs: - name: Publish with dput if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }} run: | - dput ppa:meshtastic/meshtastic-daily meshtasticd_${{ steps.version.outputs.deb }}~${{ inputs.series }}_source.changes + dput ppa:meshtastic/${{ inputs.ppa_repo }} meshtasticd_${{ steps.version.outputs.deb }}~${{ inputs.series }}_source.changes diff --git a/debian/ci_pack_sdeb.sh b/debian/ci_pack_sdeb.sh index 427e9c79b..3099b6569 100755 --- a/debian/ci_pack_sdeb.sh +++ b/debian/ci_pack_sdeb.sh @@ -13,8 +13,8 @@ rm -rf pio package=$(dpkg-parsechangelog --show-field Source) rm -rf debian/changelog -dch --create --distribution $SERIES --package $package --newversion $PKG_VERSION~$SERIES \ +dch --create --distribution "$SERIES" --package "$package" --newversion "$PKG_VERSION~$SERIES" \ "GitHub Actions Automatic packaging for $PKG_VERSION~$SERIES" # Build the source deb -debuild -S -nc -k$GPG_KEY_ID +debuild -S -nc -k"$GPG_KEY_ID" From 57766d47a8f9bc01c57a5e10e7fc40f7e4065e42 Mon Sep 17 00:00:00 2001 From: Austin Date: Mon, 6 Jan 2025 19:45:59 -0500 Subject: [PATCH 35/41] GitHub Actions: Trigger PPA stable builds upon release (#5777) --- .github/workflows/release_channels.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/workflows/release_channels.yml diff --git a/.github/workflows/release_channels.yml b/.github/workflows/release_channels.yml new file mode 100644 index 000000000..d572568de --- /dev/null +++ b/.github/workflows/release_channels.yml @@ -0,0 +1,20 @@ +name: Trigger release workflows upon Publish + +on: + release: + types: [published] + +permissions: read-all + +jobs: + package-ppa: + strategy: + fail-fast: false + matrix: + series: [plucky, oracular, noble, jammy] + uses: ./.github/workflows/package_ppa.yml + with: + ppa_repo: |- + ${{ contains(github.event.release.name, 'Beta') && 'beta' || contains(github.event.release.name, 'Alpha') && 'alpha' }} + series: ${{ matrix.series }} + secrets: inherit From 86170171a7a093e06423e8c78841b91a6cce2b26 Mon Sep 17 00:00:00 2001 From: Austin Date: Mon, 6 Jan 2025 20:25:05 -0500 Subject: [PATCH 36/41] meshtasticd-debian: Include web components (#5778) --- .gitignore | 6 ++++-- debian/changelog | 2 +- debian/ci_changelog.sh | 7 ++++--- debian/ci_pack_sdeb.sh | 7 +++++-- debian/control | 8 ++++++-- debian/meshtasticd.dirs | 1 + debian/meshtasticd.install | 2 ++ debian/rules | 7 +++++-- debian/source/include-binaries | 5 ++--- debian/source/options | 3 +-- 10 files changed, 31 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index d44374919..803aee139 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ .pio -.pio_core pio +pio.tar +web +web.tar # ignore vscode IDE settings files .vscode/* @@ -32,4 +34,4 @@ release/ .vscode/extensions.json /compile_commands.json src/mesh/raspihttp/certificate.pem -src/mesh/raspihttp/private_key.pem +src/mesh/raspihttp/private_key.pem \ No newline at end of file diff --git a/debian/changelog b/debian/changelog index 5dd6fb1c0..79c444aca 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -meshtasticd (2.5.19) unstable; urgency=medium +meshtasticd (2.5.19) UNRELEASED; urgency=medium * Initial packaging diff --git a/debian/ci_changelog.sh b/debian/ci_changelog.sh index 56688f99b..7925ad5eb 100755 --- a/debian/ci_changelog.sh +++ b/debian/ci_changelog.sh @@ -1,6 +1,7 @@ #!/usr/bin/bash export DEBEMAIL="github-actions[bot]@users.noreply.github.com" +PKG_VERSION=$(python3 bin/buildinfo.py short) -dch --newversion "$(python3 bin/buildinfo.py short)-1" \ - --distribution unstable \ - "GitHub Actions Automatic version bump" +dch --newversion "$PKG_VERSION-1" \ + --distribution UNRELEASED \ + "GitHub Actions Automatic version bump" diff --git a/debian/ci_pack_sdeb.sh b/debian/ci_pack_sdeb.sh index 3099b6569..d45593c50 100755 --- a/debian/ci_pack_sdeb.sh +++ b/debian/ci_pack_sdeb.sh @@ -4,11 +4,14 @@ export PLATFORMIO_LIBDEPS_DIR=pio/libdeps export PLATFORMIO_PACKAGES_DIR=pio/packages export PLATFORMIO_CORE_DIR=pio/core -# Download libraries to `libdeps` +# Download libraries to `pio` platformio pkg install -e native -platformio pkg install -t platformio/tool-scons@4.40502.0 +platformio pkg install -e native -t platformio/tool-scons@4.40502.0 +# Compress `pio` directory to prevent dh_clean from sanitizing it tar -cf pio.tar pio/ rm -rf pio +# Download the latest meshtastic/web release build.tar to `web.tar` +curl https://github.com/meshtastic/web/releases/download/latest/build.tar -o web.tar package=$(dpkg-parsechangelog --show-field Source) diff --git a/debian/control b/debian/control index 9814933e3..097f85859 100644 --- a/debian/control +++ b/debian/control @@ -13,7 +13,11 @@ Build-Depends: debhelper-compat (= 13), libgpiod-dev, libbluetooth-dev, libusb-1.0-0-dev, - libi2c-dev + libi2c-dev, + openssl, + libssl-dev, + libulfius-dev, + liborcania-dev Standards-Version: 4.6.2 Homepage: https://github.com/meshtastic/firmware Rules-Requires-Root: no @@ -23,4 +27,4 @@ Architecture: any Depends: ${misc:Depends}, ${shlibs:Depends} Description: Meshtastic daemon for communicating with Meshtastic devices Meshtastic is an off-grid text communication platform that uses inexpensive - LoRa radios. + LoRa radios. \ No newline at end of file diff --git a/debian/meshtasticd.dirs b/debian/meshtasticd.dirs index cf1ba7a37..5f57ff7be 100644 --- a/debian/meshtasticd.dirs +++ b/debian/meshtasticd.dirs @@ -1,3 +1,4 @@ etc/meshtasticd etc/meshtasticd/config.d etc/meshtasticd/available.d +usr/share/meshtasticd/web \ No newline at end of file diff --git a/debian/meshtasticd.install b/debian/meshtasticd.install index 04bf34daf..da1b0685d 100644 --- a/debian/meshtasticd.install +++ b/debian/meshtasticd.install @@ -4,3 +4,5 @@ bin/config.yaml etc/meshtasticd bin/config.d/* etc/meshtasticd/available.d bin/meshtasticd.service lib/systemd/system + +web/* usr/share/meshtasticd/web \ No newline at end of file diff --git a/debian/rules b/debian/rules index 28961fd10..31221dd80 100755 --- a/debian/rules +++ b/debian/rules @@ -12,9 +12,12 @@ PIO_ENV:=\ PLATFORMIO_PACKAGES_DIR=pio/packages override_dh_auto_build: - # Build with platformio + # Extract tarballs within source deb tar -xf pio.tar + tar -xf web.tar web + gunzip web/ -r + # Build with platformio $(PIO_ENV) platformio run -e native # Move the binary and default config to the correct name mv .pio/build/native/program .pio/build/native/meshtasticd - cp bin/config-dist.yaml bin/config.yaml + cp bin/config-dist.yaml bin/config.yaml \ No newline at end of file diff --git a/debian/source/include-binaries b/debian/source/include-binaries index aef4a7027..0c9848b72 100644 --- a/debian/source/include-binaries +++ b/debian/source/include-binaries @@ -1,3 +1,2 @@ -pio/libdeps -pio/packages -pio/core \ No newline at end of file +pio.tar +web.tar \ No newline at end of file diff --git a/debian/source/options b/debian/source/options index 2f3670cba..0553b485d 100644 --- a/debian/source/options +++ b/debian/source/options @@ -1,2 +1 @@ -extend-diff-ignore = "\.pio\w*?$" -tar-ignore = "" +extend-diff-ignore = "\.pio" \ No newline at end of file From 395469d20a8523e6e9c16e3ac43c75a839cca2d9 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Mon, 6 Jan 2025 19:59:02 -0600 Subject: [PATCH 37/41] As Per XKCD #1168 --- debian/rules | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/rules b/debian/rules index 31221dd80..a1a27c2f2 100755 --- a/debian/rules +++ b/debian/rules @@ -14,10 +14,10 @@ PIO_ENV:=\ override_dh_auto_build: # Extract tarballs within source deb tar -xf pio.tar - tar -xf web.tar web + mkdir -p web && tar -xf web.tar -C web gunzip web/ -r # Build with platformio $(PIO_ENV) platformio run -e native # Move the binary and default config to the correct name mv .pio/build/native/program .pio/build/native/meshtasticd - cp bin/config-dist.yaml bin/config.yaml \ No newline at end of file + cp bin/config-dist.yaml bin/config.yaml From cdcbf4c61550e45c125e17a20aff4275e9389655 Mon Sep 17 00:00:00 2001 From: Austin Date: Mon, 6 Jan 2025 21:51:50 -0500 Subject: [PATCH 38/41] Small fix: debian, curl follow redirs (#5780) --- debian/ci_pack_sdeb.sh | 2 +- debian/control | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/debian/ci_pack_sdeb.sh b/debian/ci_pack_sdeb.sh index d45593c50..1f311af93 100755 --- a/debian/ci_pack_sdeb.sh +++ b/debian/ci_pack_sdeb.sh @@ -11,7 +11,7 @@ platformio pkg install -e native -t platformio/tool-scons@4.40502.0 tar -cf pio.tar pio/ rm -rf pio # Download the latest meshtastic/web release build.tar to `web.tar` -curl https://github.com/meshtastic/web/releases/download/latest/build.tar -o web.tar +curl -L https://github.com/meshtastic/web/releases/download/latest/build.tar -o web.tar package=$(dpkg-parsechangelog --show-field Source) diff --git a/debian/control b/debian/control index 097f85859..bb79d1958 100644 --- a/debian/control +++ b/debian/control @@ -3,6 +3,8 @@ Section: misc Priority: optional Maintainer: Austin Lane Build-Depends: debhelper-compat (= 13), + tar, + gzip, platformio, python3-protobuf, python3-grpcio, From 353740623f3a017ecf4bdc3453452b3deb277b8c Mon Sep 17 00:00:00 2001 From: Marco Veneziano Date: Tue, 7 Jan 2025 14:09:51 +0100 Subject: [PATCH 39/41] Increase esp32c3 stability over wifi (#5774) * Increase esp32c3 stability over wifi * only apply the fix on esp32c3 based nodes --- src/mesh/wifi/WiFiAPClient.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/mesh/wifi/WiFiAPClient.cpp b/src/mesh/wifi/WiFiAPClient.cpp index 2f8138921..dcfcdc047 100644 --- a/src/mesh/wifi/WiFiAPClient.cpp +++ b/src/mesh/wifi/WiFiAPClient.cpp @@ -143,6 +143,11 @@ static int32_t reconnectWiFi() delay(5000); if (!WiFi.isConnected()) { +#ifdef CONFIG_IDF_TARGET_ESP32C3 + WiFi.mode(WIFI_MODE_NULL); + WiFi.useStaticBuffers(true); + WiFi.mode(WIFI_STA); +#endif WiFi.begin(wifiName, wifiPsw); } isReconnecting = false; From 27fbfd03d6037b44c77cc947b283bdb6af605b64 Mon Sep 17 00:00:00 2001 From: Eric Severance Date: Tue, 7 Jan 2025 05:10:42 -0800 Subject: [PATCH 40/41] Add unit tests for MQTT (#5724) * Add unit tests for MQTT * Test received fields --- src/mesh/MeshService.h | 2 +- src/mesh/NodeDB.h | 2 +- src/mesh/RadioLibInterface.cpp | 1 + src/mesh/Router.h | 2 +- src/modules/RoutingModule.h | 3 +- src/mqtt/MQTT.cpp | 18 +- test/test_mqtt/MQTT.cpp | 856 +++++++++++++++++++++++++++++++++ 7 files changed, 876 insertions(+), 8 deletions(-) create mode 100644 test/test_mqtt/MQTT.cpp diff --git a/src/mesh/MeshService.h b/src/mesh/MeshService.h index 268c4308f..175d8a595 100644 --- a/src/mesh/MeshService.h +++ b/src/mesh/MeshService.h @@ -142,7 +142,7 @@ class MeshService void sendToPhone(meshtastic_MeshPacket *p); /// Send an MQTT message to the phone for client proxying - void sendMqttMessageToClientProxy(meshtastic_MqttClientProxyMessage *m); + virtual void sendMqttMessageToClientProxy(meshtastic_MqttClientProxyMessage *m); /// Send a ClientNotification to the phone void sendClientNotification(meshtastic_ClientNotification *cn); diff --git a/src/mesh/NodeDB.h b/src/mesh/NodeDB.h index c8c0d3170..d244a94ba 100644 --- a/src/mesh/NodeDB.h +++ b/src/mesh/NodeDB.h @@ -145,7 +145,7 @@ class NodeDB return &meshNodes->at(x); } - meshtastic_NodeInfoLite *getMeshNode(NodeNum n); + virtual meshtastic_NodeInfoLite *getMeshNode(NodeNum n); size_t getNumMeshNodes() { return numMeshNodes; } // returns true if the maximum number of nodes is reached or we are running low on memory diff --git a/src/mesh/RadioLibInterface.cpp b/src/mesh/RadioLibInterface.cpp index 997b1d6fe..09266b334 100644 --- a/src/mesh/RadioLibInterface.cpp +++ b/src/mesh/RadioLibInterface.cpp @@ -431,6 +431,7 @@ void RadioLibInterface::handleReceiveInterrupt() // nodes. meshtastic_MeshPacket *mp = packetPool.allocZeroed(); + // Keep the assigned fields in sync with src/mqtt/MQTT.cpp:onReceiveProto mp->from = radioBuffer.header.from; mp->to = radioBuffer.header.to; mp->id = radioBuffer.header.id; diff --git a/src/mesh/Router.h b/src/mesh/Router.h index da44d67df..0fe2bc551 100644 --- a/src/mesh/Router.h +++ b/src/mesh/Router.h @@ -71,7 +71,7 @@ class Router : protected concurrency::OSThread * RadioInterface calls this to queue up packets that have been received from the radio. The router is now responsible for * freeing the packet */ - void enqueueReceivedMessage(meshtastic_MeshPacket *p); + virtual void enqueueReceivedMessage(meshtastic_MeshPacket *p); /** * Send a packet on a suitable interface. This routine will diff --git a/src/modules/RoutingModule.h b/src/modules/RoutingModule.h index 7c34c5bc9..c047f6e29 100644 --- a/src/modules/RoutingModule.h +++ b/src/modules/RoutingModule.h @@ -13,7 +13,8 @@ class RoutingModule : public ProtobufModule */ RoutingModule(); - void sendAckNak(meshtastic_Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex, uint8_t hopLimit = 0); + virtual void sendAckNak(meshtastic_Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex, + uint8_t hopLimit = 0); // Given the hopStart and hopLimit upon reception of a request, return the hop limit to use for the response uint8_t getHopLimitForResponse(uint8_t hopStart, uint8_t hopLimit); diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index 3db3c37bb..f642af231 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -76,12 +76,22 @@ inline void onReceiveProto(char *topic, byte *payload, size_t length) return; } LOG_INFO("Received MQTT topic %s, len=%u", topic, length); + if (e.packet->hop_limit > HOP_MAX || e.packet->hop_start > HOP_MAX) { + LOG_INFO("Invalid hop_limit(%u) or hop_start(%u)", e.packet->hop_limit, e.packet->hop_start); + return; + } - UniquePacketPoolPacket p = packetPool.allocUniqueCopy(*e.packet); + UniquePacketPoolPacket p = packetPool.allocUniqueZeroed(); + p->from = e.packet->from; + p->to = e.packet->to; + p->id = e.packet->id; + p->channel = e.packet->channel; + p->hop_limit = e.packet->hop_limit; + p->hop_start = e.packet->hop_start; + p->want_ack = e.packet->want_ack; p->via_mqtt = true; // Mark that the packet was received via MQTT - // Unset received SNR/RSSI which might have been added by the MQTT gateway - p->rx_snr = 0; - p->rx_rssi = 0; + p->which_payload_variant = e.packet->which_payload_variant; + memcpy(&p->decoded, &e.packet->decoded, std::max(sizeof(p->decoded), sizeof(p->encrypted))); if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) { if (moduleConfig.mqtt.encryption_enabled) { diff --git a/test/test_mqtt/MQTT.cpp b/test/test_mqtt/MQTT.cpp new file mode 100644 index 000000000..55ba479e2 --- /dev/null +++ b/test/test_mqtt/MQTT.cpp @@ -0,0 +1,856 @@ +#include "DebugConfiguration.h" +#include "TestUtil.h" +#include + +#ifdef ARCH_PORTDUINO +#include "mesh/CryptoEngine.h" +#include "mesh/Default.h" +#include "mesh/MeshService.h" +#include "mesh/NodeDB.h" +#include "mesh/Router.h" +#include "modules/RoutingModule.h" +#include "mqtt/MQTT.h" +#include "mqtt/ServiceEnvelope.h" + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace +{ +// Minimal router needed to receive messages from MQTT. +class MockRouter : public Router +{ + public: + ~MockRouter() + { + // cryptLock is created in the constructor for Router. + delete cryptLock; + cryptLock = NULL; + } + void enqueueReceivedMessage(meshtastic_MeshPacket *p) override + { + packets_.emplace_back(*p); + packetPool.release(p); + } + std::list packets_; // Packets received by the Router. +}; + +// Minimal MeshService needed to receive messages from MQTT for testing PKI channel. +class MockMeshService : public MeshService +{ + public: + void sendMqttMessageToClientProxy(meshtastic_MqttClientProxyMessage *m) override + { + messages_.emplace_back(*m); + releaseMqttClientProxyMessageToPool(m); + } + std::list messages_; // Messages received from the MeshService. +}; + +// Minimal NodeDB needed to return values from getMeshNode. +class MockNodeDB : public NodeDB +{ + public: + meshtastic_NodeInfoLite *getMeshNode(NodeNum n) override { return &emptyNode; } + meshtastic_NodeInfoLite emptyNode = {}; +}; + +// Minimal RoutingModule needed to return values from sendAckNak. +class MockRoutingModule : public RoutingModule +{ + public: + void sendAckNak(meshtastic_Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex, + uint8_t hopLimit = 0) override + { + ackNacks_.emplace_back(err, to, idFrom, chIndex, hopLimit); + } + std::list> + ackNacks_; // ackNacks received by the RoutingModule. +}; + +// A WiFi client used by the MQTT::PubSubClient. Implements a minimal pub/sub server. +// There isn't an easy way to mock PubSubClient due to it not having virtual methods, so we mock using +// the WiFiClinet that PubSubClient uses. +class MockPubSubServer : public WiFiClient +{ + public: + static constexpr char kTextTopic[] = "TextTopic"; + uint8_t connected() override { return connected_; } + void flush() override {} + IPAddress remoteIP() const override { return IPAddress(htonl(ipAddress_)); } + void stop() override { connected_ = false; } + + int connect(IPAddress ip, uint16_t port) override + { + if (refuseConnection_) + return 0; + connected_ = true; + return 1; + } + int connect(const char *host, uint16_t port) override + { + if (refuseConnection_) + return 0; + connected_ = true; + return 1; + } + + int available() override + { + if (buffer_.empty()) + return 0; + return buffer_.front().size(); + } + + int read() override + { + assert(available()); + std::string &front = buffer_.front(); + char ch = front[0]; + front = front.substr(1, front.size()); + if (front.empty()) + buffer_.pop_front(); + return ch; + } + + size_t write(uint8_t data) override { return write(&data, 1); } + size_t write(const uint8_t *buf, size_t size) override + { + command_ += std::string(reinterpret_cast(buf), size); + if (command_.size() < 2) + return size; + const int len = (uint8_t)command_[1] + 2; + if (command_.size() < len) + return size; + handleCommand(command_[0], command_.substr(2, len)); + command_ = command_.substr(len, command_.size()); + return size; + } + + // The pub/sub "server". + // https://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/MQTT_V3.1_Protocol_Specific.pdf + void handleCommand(uint8_t header, std::string_view message) + { + switch (header & 0xf0) { + case MQTTCONNECT: + LOG_DEBUG("MQTTCONNECT"); + buffer_.push_back(std::string("\x20\x02\x00\x00", 4)); + break; + + case MQTTSUBSCRIBE: { + LOG_DEBUG("MQTTSUBSCRIBE"); + assert(message.size() >= 5); + message.remove_prefix(2); // skip messageId + + while (message.size() >= 3) { + const uint16_t topicSize = ((uint8_t)message[0]) << 8 | (uint8_t)message[1]; + message.remove_prefix(2); + + assert(message.size() >= topicSize + 1); + std::string topic(message.data(), topicSize); + message.remove_prefix(topicSize + 1); + + LOG_DEBUG("Subscribed to topic: %s", topic.c_str()); + subscriptions_.insert(std::move(topic)); + } + break; + } + + case MQTTPINGREQ: + LOG_DEBUG("MQTTPINGREQ"); + buffer_.push_back(std::string("\xd0\x00", 2)); + break; + + case MQTTPUBLISH: { + LOG_DEBUG("MQTTPUBLISH"); + assert(message.size() >= 3); + const uint16_t topicSize = ((uint8_t)message[0]) << 8 | (uint8_t)message[1]; + message.remove_prefix(2); + + assert(message.size() >= topicSize); + std::string topic(message.data(), topicSize); + message.remove_prefix(topicSize); + + if (topic == kTextTopic) { + published_.emplace_back(std::move(topic), std::string(message.data(), message.size())); + } else { + published_.emplace_back( + std::move(topic), DecodedServiceEnvelope(reinterpret_cast(message.data()), message.size())); + } + break; + } + } + } + + bool connected_ = false; + bool refuseConnection_ = false; // Simulate a failed connection. + uint32_t ipAddress_ = 0x01010101; // IP address of the MQTT server. + std::list buffer_; // Buffer of messages for the pubSub client to receive. + std::string command_; // Current command received from the pubSub client. + std::set subscriptions_; // Topics that the pubSub client has subscribed to. + std::list>> + published_; // Messages published from the pubSub client. Each list element is a pair containing the topic name and either + // a text message (if from the kTextTopic topic) or a DecodedServiceEnvelope. +}; + +// Instances of our mocks. +class MQTTUnitTest; +MQTTUnitTest *unitTest; +MockPubSubServer *pubsub; +MockRoutingModule *mockRoutingModule; +MockMeshService *mockMeshService; +MockRouter *mockRouter; + +// Keep running the loop until either conditionMet returns true or 4 seconds elapse. +// Returns true if conditionMet returns true, returns false on timeout. +bool loopUntil(std::function conditionMet) +{ + long start = millis(); + while (start + 4000 > millis()) { + long delayMsec = concurrency::mainController.runOrDelay(); + if (conditionMet()) + return true; + concurrency::mainDelay.delay(std::min(delayMsec, 5L)); + } + return false; +} + +// Used to access protected/private members of MQTT for unit testing. +class MQTTUnitTest : public MQTT +{ + public: + MQTTUnitTest() : MQTT(std::make_unique()) + { + pubsub = reinterpret_cast(mqttClient.get()); + } + ~MQTTUnitTest() + { + // Needed because WiFiClient does not have a virtual destructor. + mqttClient.release(); + delete pubsub; + } + int queueSize() { return mqttQueue.numUsed(); } + void reportToMap(std::optional precision = std::nullopt) + { + if (precision.has_value()) + map_position_precision = precision.value(); + map_publish_interval_msecs = 0; + perhapsReportToMap(); + } + void publish(const meshtastic_MeshPacket *p, std::string gateway = "!87654321", std::string channel = "test") + { + std::stringstream topic; + topic << "msh/2/e/" << channel << "/!" << gateway; + const meshtastic_ServiceEnvelope env = {.packet = const_cast(p), + .channel_id = const_cast(channel.c_str()), + .gateway_id = const_cast(gateway.c_str())}; + uint8_t bytes[256]; + size_t numBytes = pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_ServiceEnvelope_msg, &env); + mqttCallback(const_cast(topic.str().c_str()), bytes, numBytes); + } + static void restart() + { + if (mqtt != NULL) { + delete mqtt; + mqtt = unitTest = NULL; + } + mqtt = unitTest = new MQTTUnitTest(); + mqtt->start(); + + if (!moduleConfig.mqtt.enabled || moduleConfig.mqtt.proxy_to_client_enabled || *moduleConfig.mqtt.root) { + loopUntil([] { return true; }); // Loop once + return; + } + // Wait for MQTT to subscribe to all topics. + TEST_ASSERT_TRUE(loopUntil( + [] { return pubsub->subscriptions_.count("msh/2/e/test/+") && pubsub->subscriptions_.count("msh/2/e/PKI/+"); })); + } + PubSubClient &getPubSub() { return pubSub; } +}; + +// Packets used in unit tests. +const meshtastic_MeshPacket decoded = { + .from = 1, + .to = 2, + .which_payload_variant = meshtastic_MeshPacket_decoded_tag, + .decoded = {.portnum = meshtastic_PortNum_TEXT_MESSAGE_APP, .has_bitfield = true, .bitfield = BITFIELD_OK_TO_MQTT_MASK}, + .id = 4, +}; +const meshtastic_MeshPacket encrypted = { + .from = 1, + .to = 2, + .which_payload_variant = meshtastic_MeshPacket_encrypted_tag, + .encrypted = {.size = 0}, + .id = 3, +}; +} // namespace + +// Initialize mocks and configuration before running each test. +void setUp(void) +{ + moduleConfig.mqtt = + meshtastic_ModuleConfig_MQTTConfig{.enabled = true, .map_reporting_enabled = true, .has_map_report_settings = true}; + channelFile.channels[0] = meshtastic_Channel{ + .index = 0, + .has_settings = true, + .settings = {.name = "test", .uplink_enabled = true, .downlink_enabled = true}, + .role = meshtastic_Channel_Role_PRIMARY, + }; + channelFile.channels_count = 1; + owner = meshtastic_User{.id = "!12345678"}; + myNodeInfo = meshtastic_MyNodeInfo{.my_node_num = 10}; + localPosition = + meshtastic_Position{.has_latitude_i = true, .latitude_i = 7 * 1e7, .has_longitude_i = true, .longitude_i = 3 * 1e7}; + + router = mockRouter = new MockRouter(); + service = mockMeshService = new MockMeshService(); + routingModule = mockRoutingModule = new MockRoutingModule(); + MQTTUnitTest::restart(); +} + +// Deinitialize all objects created in setUp. +void tearDown(void) +{ + delete unitTest; + mqtt = unitTest = NULL; + delete mockRoutingModule; + routingModule = mockRoutingModule = NULL; + delete mockMeshService; + service = mockMeshService = NULL; + delete mockRouter; + router = mockRouter = NULL; +} + +// Test that the decoded MeshPacket is published when encryption_enabled = false. +void test_sendDirectlyConnectedDecoded(void) +{ + mqtt->onSend(encrypted, decoded, 0); + + TEST_ASSERT_EQUAL(1, pubsub->published_.size()); + const auto &[topic, payload] = pubsub->published_.front(); + const DecodedServiceEnvelope &env = std::get(payload); + TEST_ASSERT_EQUAL_STRING("msh/2/e/test/!12345678", topic.c_str()); + TEST_ASSERT_TRUE(env.validDecode); + TEST_ASSERT_EQUAL(decoded.id, env.packet->id); +} + +// Test that the encrypted MeshPacket is published when encryption_enabled = true. +void test_sendDirectlyConnectedEncrypted(void) +{ + moduleConfig.mqtt.encryption_enabled = true; + + mqtt->onSend(encrypted, decoded, 0); + + TEST_ASSERT_EQUAL(1, pubsub->published_.size()); + const auto &[topic, payload] = pubsub->published_.front(); + const DecodedServiceEnvelope &env = std::get(payload); + TEST_ASSERT_EQUAL_STRING("msh/2/e/test/!12345678", topic.c_str()); + TEST_ASSERT_TRUE(env.validDecode); + TEST_ASSERT_EQUAL(encrypted.id, env.packet->id); +} + +// Verify that the decoded MeshPacket is proxied through the MeshService when encryption_enabled = false. +void test_proxyToMeshServiceDecoded(void) +{ + moduleConfig.mqtt.proxy_to_client_enabled = true; + MQTTUnitTest::restart(); + + mqtt->onSend(encrypted, decoded, 0); + + TEST_ASSERT_EQUAL(1, mockMeshService->messages_.size()); + const meshtastic_MqttClientProxyMessage &message = mockMeshService->messages_.front(); + TEST_ASSERT_EQUAL_STRING("msh/2/e/test/!12345678", message.topic); + TEST_ASSERT_EQUAL(meshtastic_MqttClientProxyMessage_data_tag, message.which_payload_variant); + const DecodedServiceEnvelope env(message.payload_variant.data.bytes, message.payload_variant.data.size); + TEST_ASSERT_TRUE(env.validDecode); + TEST_ASSERT_EQUAL(decoded.id, env.packet->id); +} + +// Verify that the encrypted MeshPacket is proxied through the MeshService when encryption_enabled = true. +void test_proxyToMeshServiceEncrypted(void) +{ + moduleConfig.mqtt.proxy_to_client_enabled = true; + moduleConfig.mqtt.encryption_enabled = true; + MQTTUnitTest::restart(); + + mqtt->onSend(encrypted, decoded, 0); + + TEST_ASSERT_EQUAL(1, mockMeshService->messages_.size()); + const meshtastic_MqttClientProxyMessage &message = mockMeshService->messages_.front(); + TEST_ASSERT_EQUAL_STRING("msh/2/e/test/!12345678", message.topic); + TEST_ASSERT_EQUAL(meshtastic_MqttClientProxyMessage_data_tag, message.which_payload_variant); + const DecodedServiceEnvelope env(message.payload_variant.data.bytes, message.payload_variant.data.size); + TEST_ASSERT_TRUE(env.validDecode); + TEST_ASSERT_EQUAL(encrypted.id, env.packet->id); +} + +// A packet without the OK to MQTT bit set should not be published to a public server. +void test_dontMqttMeOnPublicServer(void) +{ + meshtastic_MeshPacket p = decoded; + p.decoded.bitfield = 0; + p.decoded.has_bitfield = 0; + + mqtt->onSend(encrypted, p, 0); + + TEST_ASSERT_TRUE(pubsub->published_.empty()); +} + +// A packet without the OK to MQTT bit set should be published to a private server. +void test_okToMqttOnPrivateServer(void) +{ + // Cause a disconnect. + pubsub->connected_ = false; + pubsub->refuseConnection_ = true; + TEST_ASSERT_TRUE(loopUntil([] { return !unitTest->getPubSub().connected(); })); + + // Use 127.0.0.1 for the server's IP. + pubsub->ipAddress_ = 0x7f000001; + + // Reconnect. + pubsub->refuseConnection_ = false; + TEST_ASSERT_TRUE(loopUntil([] { return unitTest->getPubSub().connected(); })); + + // Send the same packet as test_dontMqttMeOnPublicServer. + meshtastic_MeshPacket p = decoded; + p.decoded.bitfield = 0; + p.decoded.has_bitfield = 0; + + mqtt->onSend(encrypted, p, 0); + + TEST_ASSERT_EQUAL(1, pubsub->published_.size()); +} + +// Range tests messages are not uplinked to the default server. +void test_noRangeTestAppOnDefaultServer(void) +{ + meshtastic_MeshPacket p = decoded; + p.decoded.portnum = meshtastic_PortNum_RANGE_TEST_APP; + + mqtt->onSend(encrypted, p, 0); + + TEST_ASSERT_TRUE(pubsub->published_.empty()); +} + +// Detection sensor messages are not uplinked to the default server. +void test_noDetectionSensorAppOnDefaultServer(void) +{ + meshtastic_MeshPacket p = decoded; + p.decoded.portnum = meshtastic_PortNum_DETECTION_SENSOR_APP; + + mqtt->onSend(encrypted, p, 0); + + TEST_ASSERT_TRUE(pubsub->published_.empty()); +} + +// Test that a MeshPacket is queued while the MQTT server is disconnected. +void test_sendQueued(void) +{ + // Cause a disconnect. + pubsub->connected_ = false; + pubsub->refuseConnection_ = true; + TEST_ASSERT_TRUE(loopUntil([] { return !unitTest->getPubSub().connected(); })); + + // Send while disconnected. + mqtt->onSend(encrypted, decoded, 0); + TEST_ASSERT_EQUAL(1, unitTest->queueSize()); + TEST_ASSERT_TRUE(pubsub->published_.empty()); + TEST_ASSERT_FALSE(unitTest->getPubSub().connected()); + + // Allow reconnect to happen. Expect to see the packet published now. + pubsub->refuseConnection_ = false; + TEST_ASSERT_TRUE(loopUntil([] { return !pubsub->published_.empty(); })); + + TEST_ASSERT_EQUAL(0, unitTest->queueSize()); + const auto &[topic, payload] = pubsub->published_.front(); + const DecodedServiceEnvelope &env = std::get(payload); + TEST_ASSERT_EQUAL_STRING("msh/2/e/test/!12345678", topic.c_str()); + TEST_ASSERT_TRUE(env.validDecode); + TEST_ASSERT_EQUAL(decoded.id, env.packet->id); +} + +// Verify reconnecting with the proxy enabled does not reconnect to a MQTT server. +void test_reconnectProxyDoesNotReconnectMqtt(void) +{ + moduleConfig.mqtt.proxy_to_client_enabled = true; + MQTTUnitTest::restart(); + + mqtt->reconnect(); + + TEST_ASSERT_FALSE(pubsub->connected_); +} + +// Test receiving an empty MeshPacket on a subscribed topic. +void test_receiveEmptyMeshPacket(void) +{ + unitTest->publish(NULL); + + TEST_ASSERT_TRUE(mockRouter->packets_.empty()); + TEST_ASSERT_TRUE(mockRoutingModule->ackNacks_.empty()); +} + +// Test receiving a decoded MeshPacket on a subscribed topic. +void test_receiveDecodedProto(void) +{ + unitTest->publish(&decoded); + + TEST_ASSERT_EQUAL(1, mockRouter->packets_.size()); + const meshtastic_MeshPacket &p = mockRouter->packets_.front(); + TEST_ASSERT_EQUAL(decoded.id, p.id); + TEST_ASSERT_TRUE(p.via_mqtt); +} + +// Test receiving a decoded MeshPacket from the phone proxy. +void test_receiveDecodedProtoFromProxy(void) +{ + const meshtastic_ServiceEnvelope env = { + .packet = const_cast(&decoded), .channel_id = "test", .gateway_id = "!87654321"}; + meshtastic_MqttClientProxyMessage message = meshtastic_MqttClientProxyMessage_init_default; + strcat(message.topic, "msh/2/e/test/!87654321"); + message.which_payload_variant = meshtastic_MqttClientProxyMessage_data_tag; + message.payload_variant.data.size = pb_encode_to_bytes( + message.payload_variant.data.bytes, sizeof(message.payload_variant.data.bytes), &meshtastic_ServiceEnvelope_msg, &env); + + mqtt->onClientProxyReceive(message); + + TEST_ASSERT_EQUAL(1, mockRouter->packets_.size()); + const meshtastic_MeshPacket &p = mockRouter->packets_.front(); + TEST_ASSERT_EQUAL(decoded.id, p.id); + TEST_ASSERT_TRUE(p.via_mqtt); +} + +// Properly handles the case where the received message is empty. +void test_receiveEmptyDataFromProxy(void) +{ + meshtastic_MqttClientProxyMessage message = meshtastic_MqttClientProxyMessage_init_default; + message.which_payload_variant = meshtastic_MqttClientProxyMessage_data_tag; + + mqtt->onClientProxyReceive(message); + + TEST_ASSERT_TRUE(mockRouter->packets_.empty()); +} + +// Packets should be ignored if downlink is not enabled. +void test_receiveWithoutChannelDownlink(void) +{ + channelFile.channels[0].settings.downlink_enabled = false; + + unitTest->publish(&decoded); + + TEST_ASSERT_TRUE(mockRouter->packets_.empty()); +} + +// Test receiving an encrypted MeshPacket on the PKI topic. +void test_receiveEncryptedPKITopicToUs(void) +{ + meshtastic_MeshPacket e = encrypted; + e.to = myNodeInfo.my_node_num; + + unitTest->publish(&e, "!87654321", "PKI"); + + TEST_ASSERT_EQUAL(1, mockRouter->packets_.size()); + const meshtastic_MeshPacket &p = mockRouter->packets_.front(); + TEST_ASSERT_EQUAL(encrypted.id, p.id); + TEST_ASSERT_TRUE(p.via_mqtt); +} + +// Should ignore messages published to MQTT by this gateway. +void test_receiveIgnoresOwnPublishedMessages(void) +{ + unitTest->publish(&decoded, owner.id); + + TEST_ASSERT_TRUE(mockRouter->packets_.empty()); + TEST_ASSERT_TRUE(mockRoutingModule->ackNacks_.empty()); +} + +// Considers receiving one of our packets an acknowledgement of it being sent. +void test_receiveAcksOwnSentMessages(void) +{ + meshtastic_MeshPacket p = decoded; + p.from = myNodeInfo.my_node_num; + + unitTest->publish(&p, owner.id); + + TEST_ASSERT_TRUE(mockRouter->packets_.empty()); + TEST_ASSERT_EQUAL(1, mockRoutingModule->ackNacks_.size()); + const auto &[err, to, idFrom, chIndex, hopLimit] = mockRoutingModule->ackNacks_.front(); + TEST_ASSERT_EQUAL(meshtastic_Routing_Error_NONE, err); + TEST_ASSERT_EQUAL(myNodeInfo.my_node_num, to); + TEST_ASSERT_EQUAL(p.id, idFrom); +} + +// Should ignore our own messages from MQTT that were heard by other nodes. +void test_receiveIgnoresSentMessagesFromOthers(void) +{ + meshtastic_MeshPacket p = decoded; + p.from = myNodeInfo.my_node_num; + + unitTest->publish(&p); + + TEST_ASSERT_TRUE(mockRouter->packets_.empty()); + TEST_ASSERT_TRUE(mockRoutingModule->ackNacks_.empty()); +} + +// Decoded MQTT messages should be ignored when encryption is enabled. +void test_receiveIgnoresDecodedWhenEncryptionEnabled(void) +{ + moduleConfig.mqtt.encryption_enabled = true; + + unitTest->publish(&decoded); + + TEST_ASSERT_TRUE(mockRouter->packets_.empty()); +} + +// Non-encrypted messages for the Admin App should be ignored. +void test_receiveIgnoresDecodedAdminApp(void) +{ + meshtastic_MeshPacket p = decoded; + p.decoded.portnum = meshtastic_PortNum_ADMIN_APP; + + unitTest->publish(&p); + + TEST_ASSERT_TRUE(mockRouter->packets_.empty()); +} + +// Only the same fields that are transmitted over LoRa should be set in MQTT messages. +void test_receiveIgnoresUnexpectedFields(void) +{ + meshtastic_MeshPacket input = decoded; + input.rx_snr = 10; + input.rx_rssi = 20; + + unitTest->publish(&input); + + TEST_ASSERT_EQUAL(1, mockRouter->packets_.size()); + const meshtastic_MeshPacket &p = mockRouter->packets_.front(); + TEST_ASSERT_EQUAL(0, p.rx_snr); + TEST_ASSERT_EQUAL(0, p.rx_rssi); +} + +// Messages with an invalid hop_limit are ignored. +void test_receiveIgnoresInvalidHopLimit(void) +{ + meshtastic_MeshPacket p = decoded; + p.hop_limit = 10; + + unitTest->publish(&p); + + TEST_ASSERT_TRUE(mockRouter->packets_.empty()); +} + +// Publishing to a text channel. +void test_publishTextMessageDirect(void) +{ + TEST_ASSERT_TRUE(mqtt->publish(MockPubSubServer::kTextTopic, "payload", 0)); + + TEST_ASSERT_EQUAL(1, pubsub->published_.size()); + const auto &[topic, payload] = pubsub->published_.front(); + TEST_ASSERT_EQUAL_STRING("payload", std::get(payload).c_str()); +} + +// Publishing to a text channel via the MQTT client proxy. +void test_publishTextMessageWithProxy(void) +{ + moduleConfig.mqtt.proxy_to_client_enabled = true; + + TEST_ASSERT_TRUE(mqtt->publish(MockPubSubServer::kTextTopic, "payload", 0)); + + TEST_ASSERT_EQUAL(1, mockMeshService->messages_.size()); + const meshtastic_MqttClientProxyMessage &message = mockMeshService->messages_.front(); + TEST_ASSERT_EQUAL_STRING(MockPubSubServer::kTextTopic, message.topic); + TEST_ASSERT_EQUAL(meshtastic_MqttClientProxyMessage_text_tag, message.which_payload_variant); + TEST_ASSERT_EQUAL_STRING("payload", message.payload_variant.text); +} + +// Helper method to verify the expected latitude/longitude was received. +void verifyLatLong(const DecodedServiceEnvelope &env, uint32_t latitude, uint32_t longitude) +{ + TEST_ASSERT_TRUE(env.validDecode); + const meshtastic_MeshPacket &p = *env.packet; + TEST_ASSERT_EQUAL(NODENUM_BROADCAST, p.to); + TEST_ASSERT_EQUAL(meshtastic_MeshPacket_decoded_tag, p.which_payload_variant); + TEST_ASSERT_EQUAL(meshtastic_PortNum_MAP_REPORT_APP, p.decoded.portnum); + + meshtastic_MapReport mapReport; + TEST_ASSERT_TRUE( + pb_decode_from_bytes(p.decoded.payload.bytes, p.decoded.payload.size, &meshtastic_MapReport_msg, &mapReport)); + TEST_ASSERT_EQUAL(latitude, mapReport.latitude_i); + TEST_ASSERT_EQUAL(longitude, mapReport.longitude_i); +} + +// Map reporting defaults to an imprecise location. +void test_reportToMapDefaultImprecise(void) +{ + unitTest->reportToMap(); + + TEST_ASSERT_EQUAL(1, pubsub->published_.size()); + const auto &[topic, payload] = pubsub->published_.front(); + TEST_ASSERT_EQUAL_STRING("msh/2/map/", topic.c_str()); + verifyLatLong(std::get(payload), 70123520, 30015488); +} + +// Precise location is reported when configured. +void test_reportToMapPrecise(void) +{ + unitTest->reportToMap(/*precision=*/32); + + TEST_ASSERT_EQUAL(1, pubsub->published_.size()); + const auto &[topic, payload] = pubsub->published_.front(); + TEST_ASSERT_EQUAL_STRING("msh/2/map/", topic.c_str()); + verifyLatLong(std::get(payload), localPosition.latitude_i, localPosition.longitude_i); +} + +// Location is sent over the phone proxy. +void test_reportToMapPreciseProxied(void) +{ + moduleConfig.mqtt.proxy_to_client_enabled = true; + MQTTUnitTest::restart(); + + unitTest->reportToMap(/*precision=*/32); + + TEST_ASSERT_EQUAL(1, mockMeshService->messages_.size()); + const meshtastic_MqttClientProxyMessage &message = mockMeshService->messages_.front(); + TEST_ASSERT_EQUAL_STRING("msh/2/map/", message.topic); + TEST_ASSERT_EQUAL(meshtastic_MqttClientProxyMessage_data_tag, message.which_payload_variant); + const DecodedServiceEnvelope env(message.payload_variant.data.bytes, message.payload_variant.data.size); + verifyLatLong(env, localPosition.latitude_i, localPosition.longitude_i); +} + +// No location is reported when the precision is invalid. +void test_reportToMapInvalidPrecision(void) +{ + unitTest->reportToMap(/*precision=*/0); + + TEST_ASSERT_TRUE(pubsub->published_.empty()); +} + +// isUsingDefaultServer returns true when using the default server. +void test_usingDefaultServer(void) +{ + TEST_ASSERT_TRUE(mqtt->isUsingDefaultServer()); +} + +// isUsingDefaultServer returns true when using the default server and a port. +void test_usingDefaultServerWithPort(void) +{ + std::string server = default_mqtt_address; + server += ":1883"; + strcpy(moduleConfig.mqtt.address, server.c_str()); + MQTTUnitTest::restart(); + + TEST_ASSERT_TRUE(mqtt->isUsingDefaultServer()); +} + +// isUsingDefaultServer returns true when using the default server and invalid port. +void test_usingDefaultServerWithInvalidPort(void) +{ + std::string server = default_mqtt_address; + server += ":invalid"; + strcpy(moduleConfig.mqtt.address, server.c_str()); + MQTTUnitTest::restart(); + + TEST_ASSERT_TRUE(mqtt->isUsingDefaultServer()); +} + +// isUsingDefaultServer returns false when not using the default server. +void test_usingCustomServer(void) +{ + strcpy(moduleConfig.mqtt.address, "custom"); + MQTTUnitTest::restart(); + + TEST_ASSERT_FALSE(mqtt->isUsingDefaultServer()); +} + +// Test that isEnabled returns true the MQTT module is enabled. +void test_enabled(void) +{ + TEST_ASSERT_TRUE(mqtt->isEnabled()); +} + +// Test that isEnabled returns false the MQTT module not enabled. +void test_disabled(void) +{ + moduleConfig.mqtt.enabled = false; + MQTTUnitTest::restart(); + + TEST_ASSERT_FALSE(mqtt->isEnabled()); +} + +// Subscriptions contain the moduleConfig.mqtt.root prefix. +void test_customMqttRoot(void) +{ + strcpy(moduleConfig.mqtt.root, "custom"); + MQTTUnitTest::restart(); + + TEST_ASSERT_TRUE(loopUntil( + [] { return pubsub->subscriptions_.count("custom/2/e/test/+") && pubsub->subscriptions_.count("custom/2/e/PKI/+"); })); +} + +void setup() +{ + initializeTestEnvironment(); + const std::unique_ptr mockNodeDB(new MockNodeDB()); + nodeDB = mockNodeDB.get(); + + UNITY_BEGIN(); + RUN_TEST(test_sendDirectlyConnectedDecoded); + RUN_TEST(test_sendDirectlyConnectedEncrypted); + RUN_TEST(test_proxyToMeshServiceDecoded); + RUN_TEST(test_proxyToMeshServiceEncrypted); + RUN_TEST(test_dontMqttMeOnPublicServer); + RUN_TEST(test_okToMqttOnPrivateServer); + RUN_TEST(test_noRangeTestAppOnDefaultServer); + RUN_TEST(test_noDetectionSensorAppOnDefaultServer); + RUN_TEST(test_sendQueued); + RUN_TEST(test_reconnectProxyDoesNotReconnectMqtt); + RUN_TEST(test_receiveEmptyMeshPacket); + RUN_TEST(test_receiveDecodedProto); + RUN_TEST(test_receiveDecodedProtoFromProxy); + RUN_TEST(test_receiveEmptyDataFromProxy); + RUN_TEST(test_receiveWithoutChannelDownlink); + RUN_TEST(test_receiveEncryptedPKITopicToUs); + RUN_TEST(test_receiveIgnoresOwnPublishedMessages); + RUN_TEST(test_receiveAcksOwnSentMessages); + RUN_TEST(test_receiveIgnoresSentMessagesFromOthers); + RUN_TEST(test_receiveIgnoresDecodedWhenEncryptionEnabled); + RUN_TEST(test_receiveIgnoresDecodedAdminApp); + RUN_TEST(test_receiveIgnoresUnexpectedFields); + RUN_TEST(test_receiveIgnoresInvalidHopLimit); + RUN_TEST(test_publishTextMessageDirect); + RUN_TEST(test_publishTextMessageWithProxy); + RUN_TEST(test_reportToMapDefaultImprecise); + RUN_TEST(test_reportToMapPrecise); + RUN_TEST(test_reportToMapPreciseProxied); + RUN_TEST(test_reportToMapInvalidPrecision); + RUN_TEST(test_usingDefaultServer); + RUN_TEST(test_usingDefaultServerWithPort); + RUN_TEST(test_usingDefaultServerWithInvalidPort); + RUN_TEST(test_usingCustomServer); + RUN_TEST(test_enabled); + RUN_TEST(test_disabled); + RUN_TEST(test_customMqttRoot); + exit(UNITY_END()); +} +#else +void setup() +{ + initializeTestEnvironment(); + LOG_WARN("This test requires the ARCH_PORTDUINO variant of WiFiClient"); + UNITY_BEGIN(); + UNITY_END(); +} +#endif +void loop() {} \ No newline at end of file From 9421eba0275afdc34fd2331cacd1f363485fd86e Mon Sep 17 00:00:00 2001 From: Mictronics Date: Tue, 7 Jan 2025 16:57:42 +0100 Subject: [PATCH 41/41] Fix build for Pico2 RP2350 platform. (#5783) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix LED pinout for T-Echo board marked v1.0, date 2021-6-28 * Merge PR #420 * Fixed double and missing Default class. * Use correct format specifier and fixed typo. * Removed duplicate code. * Fix error: #if with no expression * Fix warning: extra tokens at end of #endif directive. * Fix antenna switching logic. Complementary-pin control logic is required on the rp2040-lora board. * Fix deprecated macros. * Set RP2040 in dormant mode when deep sleep is triggered. * Fix array out of bounds read. * Admin key count needs to be set otherwise the key will be zero loaded after reset. * Don't reset the admin key size when loading defaults. Preserve an existing key in config if possible. * Remove log spam when reading INA voltage sensor. * Remove static declaration for admin keys from userPrefs.h. Load hard coded admin keys in case config file has empty slots. * Removed newlines from log. * Fix issue #5665. * Fix build for Pico2 RP2350 platform. --------- Co-authored-by: Ben Meadors Co-authored-by: Thomas Göttgens Co-authored-by: GUVWAF <78759985+GUVWAF@users.noreply.github.com> --- arch/rp2xx0/rp2350.ini | 6 +++--- src/platform/rp2xx0/main-rp2xx0.cpp | 22 ++++++++++++++++------ 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/arch/rp2xx0/rp2350.ini b/arch/rp2xx0/rp2350.ini index c5849ff2a..ab16e24b4 100644 --- a/arch/rp2xx0/rp2350.ini +++ b/arch/rp2xx0/rp2350.ini @@ -7,12 +7,12 @@ platform_packages = framework-arduinopico@https://github.com/earlephilhower/ardu board_build.core = earlephilhower board_build.filesystem_size = 0.5m build_flags = - ${arduino_base.build_flags} -Wno-unused-variable + ${arduino_base.build_flags} -Wno-unused-variable -Wcast-align -Isrc/platform/rp2xx0 - -D__PLAT_RP2040__ + -D__PLAT_RP2350__ # -D _POSIX_THREADS build_src_filter = - ${arduino_base.build_src_filter} - - - - - - - - - + ${arduino_base.build_src_filter} - - - - - - - - - - - lib_ignore = BluetoothOTA diff --git a/src/platform/rp2xx0/main-rp2xx0.cpp b/src/platform/rp2xx0/main-rp2xx0.cpp index a46b0face..6c73e385a 100644 --- a/src/platform/rp2xx0/main-rp2xx0.cpp +++ b/src/platform/rp2xx0/main-rp2xx0.cpp @@ -2,14 +2,11 @@ #include "hardware/xosc.h" #include #include -#include #include #include -void setBluetoothEnable(bool enable) -{ - // not needed -} +#ifdef __PLAT_RP2040__ +#include static bool awake; @@ -66,7 +63,20 @@ void cpuDeepSleep(uint32_t msecs) rp2040.reboot(); /* Set RP2040 in dormant mode. Will not wake up. */ - // xosc_dormant(); + // xosc_dormant(); +} + +#else +void cpuDeepSleep(uint32_t msecs) +{ + /* Set RP2040 in dormant mode. Will not wake up. */ + xosc_dormant(); +} +#endif + +void setBluetoothEnable(bool enable) +{ + // not needed } void updateBatteryLevel(uint8_t level)