mirror of
https://github.com/meshtastic/firmware.git
synced 2025-12-17 08:12:32 +00:00
Compare commits
20 Commits
Thinknode-
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8e0547e76d | ||
|
|
8a48321555 | ||
|
|
aa8bb6c6f1 | ||
|
|
1952982896 | ||
|
|
de2b9632bb | ||
|
|
c2b7dc2641 | ||
|
|
b74238194b | ||
|
|
5d5819b876 | ||
|
|
f127702bef | ||
|
|
cce8cbfe34 | ||
|
|
a4a6c3509a | ||
|
|
68250dc937 | ||
|
|
c8628b3422 | ||
|
|
2ac74d6677 | ||
|
|
9d487ddc0d | ||
|
|
bcfe069997 | ||
|
|
4fc96bdf83 | ||
|
|
4ef943f204 | ||
|
|
a8fa5f25cb | ||
|
|
467c042bf7 |
4
.github/actions/build-variant/action.yml
vendored
4
.github/actions/build-variant/action.yml
vendored
@@ -76,7 +76,7 @@ runs:
|
|||||||
done
|
done
|
||||||
|
|
||||||
- name: PlatformIO ${{ inputs.arch }} download cache
|
- name: PlatformIO ${{ inputs.arch }} download cache
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v5
|
||||||
with:
|
with:
|
||||||
path: ~/.platformio/.cache
|
path: ~/.platformio/.cache
|
||||||
key: pio-cache-${{ inputs.arch }}-${{ hashFiles('.github/actions/**', '**.ini') }}
|
key: pio-cache-${{ inputs.arch }}-${{ hashFiles('.github/actions/**', '**.ini') }}
|
||||||
@@ -100,7 +100,7 @@ runs:
|
|||||||
id: version
|
id: version
|
||||||
|
|
||||||
- name: Store binaries as an artifact
|
- name: Store binaries as an artifact
|
||||||
uses: actions/upload-artifact@v5
|
uses: actions/upload-artifact@v6
|
||||||
with:
|
with:
|
||||||
name: firmware-${{ inputs.arch }}-${{ inputs.board }}-${{ steps.version.outputs.long }}
|
name: firmware-${{ inputs.arch }}-${{ inputs.board }}-${{ steps.version.outputs.long }}
|
||||||
overwrite: true
|
overwrite: true
|
||||||
|
|||||||
2
.github/workflows/build_debian_src.yml
vendored
2
.github/workflows/build_debian_src.yml
vendored
@@ -64,7 +64,7 @@ jobs:
|
|||||||
PKG_VERSION: ${{ steps.version.outputs.deb }}
|
PKG_VERSION: ${{ steps.version.outputs.deb }}
|
||||||
|
|
||||||
- name: Store binaries as an artifact
|
- name: Store binaries as an artifact
|
||||||
uses: actions/upload-artifact@v5
|
uses: actions/upload-artifact@v6
|
||||||
with:
|
with:
|
||||||
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
|
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
|
||||||
overwrite: true
|
overwrite: true
|
||||||
|
|||||||
2
.github/workflows/build_firmware.yml
vendored
2
.github/workflows/build_firmware.yml
vendored
@@ -68,7 +68,7 @@ jobs:
|
|||||||
echo '```' >> $GITHUB_STEP_SUMMARY
|
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
- name: Store binaries as an artifact
|
- name: Store binaries as an artifact
|
||||||
uses: actions/upload-artifact@v5
|
uses: actions/upload-artifact@v6
|
||||||
id: upload
|
id: upload
|
||||||
with:
|
with:
|
||||||
name: firmware-${{ inputs.platform }}-${{ inputs.pio_env }}-${{ inputs.version }}
|
name: firmware-${{ inputs.platform }}-${{ inputs.pio_env }}-${{ inputs.version }}
|
||||||
|
|||||||
8
.github/workflows/build_one_target.yml
vendored
8
.github/workflows/build_one_target.yml
vendored
@@ -98,7 +98,7 @@ jobs:
|
|||||||
ref: ${{github.event.pull_request.head.ref}}
|
ref: ${{github.event.pull_request.head.ref}}
|
||||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||||
|
|
||||||
- uses: actions/download-artifact@v6
|
- uses: actions/download-artifact@v7
|
||||||
with:
|
with:
|
||||||
path: ./
|
path: ./
|
||||||
pattern: firmware-*-*
|
pattern: firmware-*-*
|
||||||
@@ -111,7 +111,7 @@ jobs:
|
|||||||
run: mv -b -t ./ ./bin/device-*.sh ./bin/device-*.bat
|
run: mv -b -t ./ ./bin/device-*.sh ./bin/device-*.bat
|
||||||
|
|
||||||
- name: Repackage in single firmware zip
|
- name: Repackage in single firmware zip
|
||||||
uses: actions/upload-artifact@v5
|
uses: actions/upload-artifact@v6
|
||||||
with:
|
with:
|
||||||
name: firmware-${{inputs.target}}-${{ needs.version.outputs.long }}
|
name: firmware-${{inputs.target}}-${{ needs.version.outputs.long }}
|
||||||
overwrite: true
|
overwrite: true
|
||||||
@@ -127,7 +127,7 @@ jobs:
|
|||||||
./Meshtastic_nRF52_factory_erase*.uf2
|
./Meshtastic_nRF52_factory_erase*.uf2
|
||||||
retention-days: 30
|
retention-days: 30
|
||||||
|
|
||||||
- uses: actions/download-artifact@v6
|
- uses: actions/download-artifact@v7
|
||||||
with:
|
with:
|
||||||
pattern: firmware-*-${{ needs.version.outputs.long }}
|
pattern: firmware-*-${{ needs.version.outputs.long }}
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
@@ -146,7 +146,7 @@ jobs:
|
|||||||
run: zip -j -9 -r ./firmware-${{inputs.target}}-${{ needs.version.outputs.long }}.zip ./output
|
run: zip -j -9 -r ./firmware-${{inputs.target}}-${{ needs.version.outputs.long }}.zip ./output
|
||||||
|
|
||||||
- name: Repackage in single elfs zip
|
- name: Repackage in single elfs zip
|
||||||
uses: actions/upload-artifact@v5
|
uses: actions/upload-artifact@v6
|
||||||
with:
|
with:
|
||||||
name: debug-elfs-${{inputs.target}}-${{ needs.version.outputs.long }}.zip
|
name: debug-elfs-${{inputs.target}}-${{ needs.version.outputs.long }}.zip
|
||||||
overwrite: true
|
overwrite: true
|
||||||
|
|||||||
39
.github/workflows/main_matrix.yml
vendored
39
.github/workflows/main_matrix.yml
vendored
@@ -77,16 +77,21 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
check: ${{ fromJson(needs.setup.outputs.check) }}
|
check: ${{ fromJson(needs.setup.outputs.check) }}
|
||||||
|
# Use 'arctastic' self-hosted runner pool when checking in the main repo
|
||||||
runs-on: ubuntu-latest
|
runs-on: ${{ github.repository_owner == 'meshtastic' && 'arctastic' || 'ubuntu-latest' }}
|
||||||
if: ${{ github.event_name != 'workflow_dispatch' && github.repository == 'meshtastic/firmware' }}
|
if: ${{ github.event_name != 'workflow_dispatch' && github.repository == 'meshtastic/firmware' }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
- name: Build base
|
with:
|
||||||
id: base
|
submodules: recursive
|
||||||
uses: ./.github/actions/setup-base
|
ref: ${{github.event.pull_request.head.ref}}
|
||||||
|
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||||
- name: Check ${{ matrix.check.board }}
|
- name: Check ${{ matrix.check.board }}
|
||||||
run: bin/check-all.sh ${{ matrix.check.board }}
|
uses: meshtastic/gh-action-firmware@main
|
||||||
|
with:
|
||||||
|
pio_platform: ${{ matrix.check.platform }}
|
||||||
|
pio_env: ${{ matrix.check.board }}
|
||||||
|
pio_target: check
|
||||||
|
|
||||||
build:
|
build:
|
||||||
needs: [setup, version]
|
needs: [setup, version]
|
||||||
@@ -168,7 +173,7 @@ jobs:
|
|||||||
ref: ${{github.event.pull_request.head.ref}}
|
ref: ${{github.event.pull_request.head.ref}}
|
||||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||||
|
|
||||||
- uses: actions/download-artifact@v6
|
- uses: actions/download-artifact@v7
|
||||||
with:
|
with:
|
||||||
path: ./
|
path: ./
|
||||||
pattern: firmware-${{matrix.arch}}-*
|
pattern: firmware-${{matrix.arch}}-*
|
||||||
@@ -178,7 +183,7 @@ jobs:
|
|||||||
run: ls -R
|
run: ls -R
|
||||||
|
|
||||||
- name: Repackage in single firmware zip
|
- name: Repackage in single firmware zip
|
||||||
uses: actions/upload-artifact@v5
|
uses: actions/upload-artifact@v6
|
||||||
with:
|
with:
|
||||||
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||||
overwrite: true
|
overwrite: true
|
||||||
@@ -195,7 +200,7 @@ jobs:
|
|||||||
./Meshtastic_nRF52_factory_erase*.uf2
|
./Meshtastic_nRF52_factory_erase*.uf2
|
||||||
retention-days: 30
|
retention-days: 30
|
||||||
|
|
||||||
- uses: actions/download-artifact@v6
|
- uses: actions/download-artifact@v7
|
||||||
with:
|
with:
|
||||||
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
@@ -214,7 +219,7 @@ jobs:
|
|||||||
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output
|
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output
|
||||||
|
|
||||||
- name: Repackage in single elfs zip
|
- name: Repackage in single elfs zip
|
||||||
uses: actions/upload-artifact@v5
|
uses: actions/upload-artifact@v6
|
||||||
with:
|
with:
|
||||||
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||||
overwrite: true
|
overwrite: true
|
||||||
@@ -255,14 +260,14 @@ jobs:
|
|||||||
Autogenerated by github action, developer should edit as required before publishing...
|
Autogenerated by github action, developer should edit as required before publishing...
|
||||||
|
|
||||||
- name: Download source deb
|
- name: Download source deb
|
||||||
uses: actions/download-artifact@v6
|
uses: actions/download-artifact@v7
|
||||||
with:
|
with:
|
||||||
pattern: firmware-debian-${{ needs.version.outputs.deb }}~UNRELEASED-src
|
pattern: firmware-debian-${{ needs.version.outputs.deb }}~UNRELEASED-src
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
path: ./output/debian-src
|
path: ./output/debian-src
|
||||||
|
|
||||||
- name: Download `native-tft` pio deps
|
- name: Download `native-tft` pio deps
|
||||||
uses: actions/download-artifact@v6
|
uses: actions/download-artifact@v7
|
||||||
with:
|
with:
|
||||||
pattern: platformio-deps-native-tft-${{ needs.version.outputs.long }}
|
pattern: platformio-deps-native-tft-${{ needs.version.outputs.long }}
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
@@ -286,7 +291,7 @@ jobs:
|
|||||||
}' > firmware-${{ needs.version.outputs.long }}.json
|
}' > firmware-${{ needs.version.outputs.long }}.json
|
||||||
|
|
||||||
- name: Save Release manifest artifact
|
- name: Save Release manifest artifact
|
||||||
uses: actions/upload-artifact@v5
|
uses: actions/upload-artifact@v6
|
||||||
with:
|
with:
|
||||||
name: manifest-${{ needs.version.outputs.long }}
|
name: manifest-${{ needs.version.outputs.long }}
|
||||||
overwrite: true
|
overwrite: true
|
||||||
@@ -327,7 +332,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
python-version: 3.x
|
python-version: 3.x
|
||||||
|
|
||||||
- uses: actions/download-artifact@v6
|
- uses: actions/download-artifact@v7
|
||||||
with:
|
with:
|
||||||
pattern: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
pattern: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
@@ -344,7 +349,7 @@ jobs:
|
|||||||
- name: Zip firmware
|
- name: Zip firmware
|
||||||
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output
|
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output
|
||||||
|
|
||||||
- uses: actions/download-artifact@v6
|
- uses: actions/download-artifact@v7
|
||||||
with:
|
with:
|
||||||
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
@@ -383,14 +388,14 @@ jobs:
|
|||||||
python-version: 3.x
|
python-version: 3.x
|
||||||
|
|
||||||
- name: Get firmware artifacts
|
- name: Get firmware artifacts
|
||||||
uses: actions/download-artifact@v6
|
uses: actions/download-artifact@v7
|
||||||
with:
|
with:
|
||||||
pattern: firmware-{${{ env.targets }}}-${{ needs.version.outputs.long }}
|
pattern: firmware-{${{ env.targets }}}-${{ needs.version.outputs.long }}
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
path: ./publish
|
path: ./publish
|
||||||
|
|
||||||
- name: Get manifest artifact
|
- name: Get manifest artifact
|
||||||
uses: actions/download-artifact@v6
|
uses: actions/download-artifact@v7
|
||||||
with:
|
with:
|
||||||
pattern: manifest-${{ needs.version.outputs.long }}
|
pattern: manifest-${{ needs.version.outputs.long }}
|
||||||
path: ./publish
|
path: ./publish
|
||||||
|
|||||||
18
.github/workflows/merge_queue.yml
vendored
18
.github/workflows/merge_queue.yml
vendored
@@ -147,7 +147,7 @@ jobs:
|
|||||||
ref: ${{github.event.pull_request.head.ref}}
|
ref: ${{github.event.pull_request.head.ref}}
|
||||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||||
|
|
||||||
- uses: actions/download-artifact@v6
|
- uses: actions/download-artifact@v7
|
||||||
with:
|
with:
|
||||||
path: ./
|
path: ./
|
||||||
pattern: firmware-${{matrix.arch}}-*
|
pattern: firmware-${{matrix.arch}}-*
|
||||||
@@ -160,7 +160,7 @@ jobs:
|
|||||||
run: mv -b -t ./ ./bin/device-*.sh ./bin/device-*.bat
|
run: mv -b -t ./ ./bin/device-*.sh ./bin/device-*.bat
|
||||||
|
|
||||||
- name: Repackage in single firmware zip
|
- name: Repackage in single firmware zip
|
||||||
uses: actions/upload-artifact@v5
|
uses: actions/upload-artifact@v6
|
||||||
with:
|
with:
|
||||||
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||||
overwrite: true
|
overwrite: true
|
||||||
@@ -176,7 +176,7 @@ jobs:
|
|||||||
./Meshtastic_nRF52_factory_erase*.uf2
|
./Meshtastic_nRF52_factory_erase*.uf2
|
||||||
retention-days: 30
|
retention-days: 30
|
||||||
|
|
||||||
- uses: actions/download-artifact@v6
|
- uses: actions/download-artifact@v7
|
||||||
with:
|
with:
|
||||||
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
@@ -195,7 +195,7 @@ jobs:
|
|||||||
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output
|
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output
|
||||||
|
|
||||||
- name: Repackage in single elfs zip
|
- name: Repackage in single elfs zip
|
||||||
uses: actions/upload-artifact@v5
|
uses: actions/upload-artifact@v6
|
||||||
with:
|
with:
|
||||||
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||||
overwrite: true
|
overwrite: true
|
||||||
@@ -235,14 +235,14 @@ jobs:
|
|||||||
Autogenerated by github action, developer should edit as required before publishing...
|
Autogenerated by github action, developer should edit as required before publishing...
|
||||||
|
|
||||||
- name: Download source deb
|
- name: Download source deb
|
||||||
uses: actions/download-artifact@v6
|
uses: actions/download-artifact@v7
|
||||||
with:
|
with:
|
||||||
pattern: firmware-debian-${{ needs.version.outputs.deb }}~UNRELEASED-src
|
pattern: firmware-debian-${{ needs.version.outputs.deb }}~UNRELEASED-src
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
path: ./output/debian-src
|
path: ./output/debian-src
|
||||||
|
|
||||||
- name: Download `native-tft` pio deps
|
- name: Download `native-tft` pio deps
|
||||||
uses: actions/download-artifact@v6
|
uses: actions/download-artifact@v7
|
||||||
with:
|
with:
|
||||||
pattern: platformio-deps-native-tft-${{ needs.version.outputs.long }}
|
pattern: platformio-deps-native-tft-${{ needs.version.outputs.long }}
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
@@ -292,7 +292,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
python-version: 3.x
|
python-version: 3.x
|
||||||
|
|
||||||
- uses: actions/download-artifact@v6
|
- uses: actions/download-artifact@v7
|
||||||
with:
|
with:
|
||||||
pattern: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
pattern: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
@@ -309,7 +309,7 @@ jobs:
|
|||||||
- name: Zip firmware
|
- name: Zip firmware
|
||||||
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output
|
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output
|
||||||
|
|
||||||
- uses: actions/download-artifact@v6
|
- uses: actions/download-artifact@v7
|
||||||
with:
|
with:
|
||||||
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
@@ -347,7 +347,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
python-version: 3.x
|
python-version: 3.x
|
||||||
|
|
||||||
- uses: actions/download-artifact@v6
|
- uses: actions/download-artifact@v7
|
||||||
with:
|
with:
|
||||||
pattern: firmware-{${{ env.targets }}}-${{ needs.version.outputs.long }}
|
pattern: firmware-{${{ env.targets }}}-${{ needs.version.outputs.long }}
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
|
|||||||
2
.github/workflows/package_obs.yml
vendored
2
.github/workflows/package_obs.yml
vendored
@@ -58,7 +58,7 @@ jobs:
|
|||||||
id: version
|
id: version
|
||||||
|
|
||||||
- name: Download artifacts
|
- name: Download artifacts
|
||||||
uses: actions/download-artifact@v6
|
uses: actions/download-artifact@v7
|
||||||
with:
|
with:
|
||||||
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
|
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
|
|||||||
2
.github/workflows/package_pio_deps.yml
vendored
2
.github/workflows/package_pio_deps.yml
vendored
@@ -56,7 +56,7 @@ jobs:
|
|||||||
PLATFORMIO_CORE_DIR: pio/core
|
PLATFORMIO_CORE_DIR: pio/core
|
||||||
|
|
||||||
- name: Store binaries as an artifact
|
- name: Store binaries as an artifact
|
||||||
uses: actions/upload-artifact@v5
|
uses: actions/upload-artifact@v6
|
||||||
with:
|
with:
|
||||||
name: platformio-deps-${{ inputs.pio_env }}-${{ steps.version.outputs.long }}
|
name: platformio-deps-${{ inputs.pio_env }}-${{ steps.version.outputs.long }}
|
||||||
overwrite: true
|
overwrite: true
|
||||||
|
|||||||
2
.github/workflows/package_ppa.yml
vendored
2
.github/workflows/package_ppa.yml
vendored
@@ -60,7 +60,7 @@ jobs:
|
|||||||
id: version
|
id: version
|
||||||
|
|
||||||
- name: Download artifacts
|
- name: Download artifacts
|
||||||
uses: actions/download-artifact@v6
|
uses: actions/download-artifact@v7
|
||||||
with:
|
with:
|
||||||
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
|
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
|
|||||||
2
.github/workflows/pr_tests.yml
vendored
2
.github/workflows/pr_tests.yml
vendored
@@ -50,7 +50,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Download test artifacts
|
- name: Download test artifacts
|
||||||
if: needs.native-tests.result != 'skipped'
|
if: needs.native-tests.result != 'skipped'
|
||||||
uses: actions/download-artifact@v6
|
uses: actions/download-artifact@v7
|
||||||
with:
|
with:
|
||||||
name: platformio-test-report-${{ steps.version.outputs.long }}
|
name: platformio-test-report-${{ steps.version.outputs.long }}
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
|
|||||||
2
.github/workflows/sec_sast_semgrep_cron.yml
vendored
2
.github/workflows/sec_sast_semgrep_cron.yml
vendored
@@ -33,7 +33,7 @@ jobs:
|
|||||||
|
|
||||||
# step 3
|
# step 3
|
||||||
- name: save report as pipeline artifact
|
- name: save report as pipeline artifact
|
||||||
uses: actions/upload-artifact@v5
|
uses: actions/upload-artifact@v6
|
||||||
with:
|
with:
|
||||||
name: report.sarif
|
name: report.sarif
|
||||||
overwrite: true
|
overwrite: true
|
||||||
|
|||||||
12
.github/workflows/test_native.yml
vendored
12
.github/workflows/test_native.yml
vendored
@@ -59,7 +59,7 @@ jobs:
|
|||||||
id: version
|
id: version
|
||||||
|
|
||||||
- name: Save coverage information
|
- name: Save coverage information
|
||||||
uses: actions/upload-artifact@v5
|
uses: actions/upload-artifact@v6
|
||||||
if: always() # run this step even if previous step failed
|
if: always() # run this step even if previous step failed
|
||||||
with:
|
with:
|
||||||
name: lcov-coverage-info-native-simulator-test-${{ steps.version.outputs.long }}
|
name: lcov-coverage-info-native-simulator-test-${{ steps.version.outputs.long }}
|
||||||
@@ -94,7 +94,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Save test results
|
- name: Save test results
|
||||||
if: always() # run this step even if previous step failed
|
if: always() # run this step even if previous step failed
|
||||||
uses: actions/upload-artifact@v5
|
uses: actions/upload-artifact@v6
|
||||||
with:
|
with:
|
||||||
name: platformio-test-report-${{ steps.version.outputs.long }}
|
name: platformio-test-report-${{ steps.version.outputs.long }}
|
||||||
overwrite: true
|
overwrite: true
|
||||||
@@ -108,7 +108,7 @@ jobs:
|
|||||||
sed -i -e "s#${PWD}#.#" coverage_tests.info # Make paths relative.
|
sed -i -e "s#${PWD}#.#" coverage_tests.info # Make paths relative.
|
||||||
|
|
||||||
- name: Save coverage information
|
- name: Save coverage information
|
||||||
uses: actions/upload-artifact@v5
|
uses: actions/upload-artifact@v6
|
||||||
if: always() # run this step even if previous step failed
|
if: always() # run this step even if previous step failed
|
||||||
with:
|
with:
|
||||||
name: lcov-coverage-info-native-platformio-tests-${{ steps.version.outputs.long }}
|
name: lcov-coverage-info-native-platformio-tests-${{ steps.version.outputs.long }}
|
||||||
@@ -137,7 +137,7 @@ jobs:
|
|||||||
id: version
|
id: version
|
||||||
|
|
||||||
- name: Download test artifacts
|
- name: Download test artifacts
|
||||||
uses: actions/download-artifact@v6
|
uses: actions/download-artifact@v7
|
||||||
with:
|
with:
|
||||||
name: platformio-test-report-${{ steps.version.outputs.long }}
|
name: platformio-test-report-${{ steps.version.outputs.long }}
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
@@ -150,7 +150,7 @@ jobs:
|
|||||||
reporter: java-junit
|
reporter: java-junit
|
||||||
|
|
||||||
- name: Download coverage artifacts
|
- name: Download coverage artifacts
|
||||||
uses: actions/download-artifact@v6
|
uses: actions/download-artifact@v7
|
||||||
with:
|
with:
|
||||||
pattern: lcov-coverage-info-native-*-${{ steps.version.outputs.long }}
|
pattern: lcov-coverage-info-native-*-${{ steps.version.outputs.long }}
|
||||||
path: code-coverage-report
|
path: code-coverage-report
|
||||||
@@ -163,7 +163,7 @@ jobs:
|
|||||||
genhtml --quiet --legend --prefix "${PWD}" code-coverage-report/coverage_src.info --output-directory code-coverage-report
|
genhtml --quiet --legend --prefix "${PWD}" code-coverage-report/coverage_src.info --output-directory code-coverage-report
|
||||||
|
|
||||||
- name: Save Code Coverage Report
|
- name: Save Code Coverage Report
|
||||||
uses: actions/upload-artifact@v5
|
uses: actions/upload-artifact@v6
|
||||||
with:
|
with:
|
||||||
name: code-coverage-report-${{ steps.version.outputs.long }}
|
name: code-coverage-report-${{ steps.version.outputs.long }}
|
||||||
path: code-coverage-report
|
path: code-coverage-report
|
||||||
|
|||||||
@@ -9,14 +9,14 @@ plugins:
|
|||||||
lint:
|
lint:
|
||||||
enabled:
|
enabled:
|
||||||
- checkov@3.2.495
|
- checkov@3.2.495
|
||||||
- renovate@42.44.0
|
- renovate@42.57.1
|
||||||
- prettier@3.7.4
|
- prettier@3.7.4
|
||||||
- trufflehog@3.92.2
|
- trufflehog@3.92.3
|
||||||
- yamllint@1.37.1
|
- yamllint@1.37.1
|
||||||
- bandit@1.9.2
|
- bandit@1.9.2
|
||||||
- trivy@0.68.1
|
- trivy@0.68.1
|
||||||
- taplo@0.10.0
|
- taplo@0.10.0
|
||||||
- ruff@0.14.8
|
- ruff@0.14.9
|
||||||
- isort@7.0.0
|
- isort@7.0.0
|
||||||
- markdownlint@0.47.0
|
- markdownlint@0.47.0
|
||||||
- oxipng@10.0.0
|
- oxipng@10.0.0
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export APP_VERSION=$VERSION
|
|||||||
|
|
||||||
basename=firmware-$1-$VERSION
|
basename=firmware-$1-$VERSION
|
||||||
|
|
||||||
pio run --environment $1 # -v
|
pio run --environment $1 -t mtjson # -v
|
||||||
|
|
||||||
cp $BUILDDIR/$basename.elf $OUTDIR/$basename.elf
|
cp $BUILDDIR/$basename.elf $OUTDIR/$basename.elf
|
||||||
|
|
||||||
@@ -32,20 +32,10 @@ cp $BUILDDIR/$basename.factory.bin $OUTDIR/$basename.factory.bin
|
|||||||
echo "Copying ESP32 update bin file"
|
echo "Copying ESP32 update bin file"
|
||||||
cp $BUILDDIR/$basename.bin $OUTDIR/$basename.bin
|
cp $BUILDDIR/$basename.bin $OUTDIR/$basename.bin
|
||||||
|
|
||||||
echo "Building Filesystem for ESP32 targets"
|
echo "Copying Filesystem for ESP32 targets"
|
||||||
# If you want to build the webui, uncomment the following lines
|
|
||||||
# pio run --environment $1 -t buildfs
|
|
||||||
# cp .pio/build/$1/littlefs.bin $OUTDIR/littlefswebui-$1-$VERSION.bin
|
|
||||||
# # Remove webserver files from the filesystem and rebuild
|
|
||||||
# ls -l data/static # Diagnostic list of files
|
|
||||||
# rm -rf data/static
|
|
||||||
pio run --environment $1 -t buildfs --disable-auto-clean
|
|
||||||
cp $BUILDDIR/littlefs-$1-$VERSION.bin $OUTDIR/littlefs-$1-$VERSION.bin
|
cp $BUILDDIR/littlefs-$1-$VERSION.bin $OUTDIR/littlefs-$1-$VERSION.bin
|
||||||
cp bin/device-install.* $OUTDIR/
|
cp bin/device-install.* $OUTDIR/
|
||||||
cp bin/device-update.* $OUTDIR/
|
cp bin/device-update.* $OUTDIR/
|
||||||
|
|
||||||
# Generate the manifest file
|
echo "Copying manifest"
|
||||||
echo "Generating Meshtastic manifest"
|
|
||||||
TIMEFORMAT="Generated manifest in %E seconds"
|
|
||||||
time pio run --environment $1 -t mtjson --silent --disable-auto-clean
|
|
||||||
cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json
|
cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export APP_VERSION=$VERSION
|
|||||||
|
|
||||||
basename=firmware-$1-$VERSION
|
basename=firmware-$1-$VERSION
|
||||||
|
|
||||||
pio run --environment $1 # -v
|
pio run --environment $1 -t mtjson # -v
|
||||||
|
|
||||||
cp $BUILDDIR/$basename.elf $OUTDIR/$basename.elf
|
cp $BUILDDIR/$basename.elf $OUTDIR/$basename.elf
|
||||||
|
|
||||||
@@ -47,8 +47,5 @@ if (echo $1 | grep -q "rak4631"); then
|
|||||||
cp $SRCHEX $OUTDIR/
|
cp $SRCHEX $OUTDIR/
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Generate the manifest file
|
echo "Copying manifest"
|
||||||
echo "Generating Meshtastic manifest"
|
|
||||||
TIMEFORMAT="Generated manifest in %E seconds"
|
|
||||||
time pio run --environment $1 -t mtjson --silent --disable-auto-clean
|
|
||||||
cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json
|
cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json
|
||||||
|
|||||||
@@ -22,15 +22,12 @@ export APP_VERSION=$VERSION
|
|||||||
|
|
||||||
basename=firmware-$1-$VERSION
|
basename=firmware-$1-$VERSION
|
||||||
|
|
||||||
pio run --environment $1 # -v
|
pio run --environment $1 -t mtjson # -v
|
||||||
|
|
||||||
cp $BUILDDIR/$basename.elf $OUTDIR/$basename.elf
|
cp $BUILDDIR/$basename.elf $OUTDIR/$basename.elf
|
||||||
|
|
||||||
echo "Copying uf2 file"
|
echo "Copying uf2 file"
|
||||||
cp $BUILDDIR/$basename.uf2 $OUTDIR/$basename.uf2
|
cp $BUILDDIR/$basename.uf2 $OUTDIR/$basename.uf2
|
||||||
|
|
||||||
# Generate the manifest file
|
echo "Copying manifest"
|
||||||
echo "Generating Meshtastic manifest"
|
|
||||||
TIMEFORMAT="Generated manifest in %E seconds"
|
|
||||||
time pio run --environment $1 -t mtjson --silent --disable-auto-clean
|
|
||||||
cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json
|
cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json
|
||||||
|
|||||||
@@ -22,15 +22,12 @@ export APP_VERSION=$VERSION
|
|||||||
|
|
||||||
basename=firmware-$1-$VERSION
|
basename=firmware-$1-$VERSION
|
||||||
|
|
||||||
pio run --environment $1 # -v
|
pio run --environment $1 -t mtjson # -v
|
||||||
|
|
||||||
cp $BUILDDIR/$basename.elf $OUTDIR/$basename.elf
|
cp $BUILDDIR/$basename.elf $OUTDIR/$basename.elf
|
||||||
|
|
||||||
echo "Copying STM32 bin file"
|
echo "Copying STM32 bin file"
|
||||||
cp $BUILDDIR/$basename.bin $OUTDIR/$basename.bin
|
cp $BUILDDIR/$basename.bin $OUTDIR/$basename.bin
|
||||||
|
|
||||||
# Generate the manifest file
|
echo "Copying manifest"
|
||||||
echo "Generating Meshtastic manifest"
|
|
||||||
TIMEFORMAT="Generated manifest in %E seconds"
|
|
||||||
time pio run --environment $1 -t mtjson --silent --disable-auto-clean
|
|
||||||
cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json
|
cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json
|
||||||
|
|||||||
@@ -184,6 +184,8 @@ Input:
|
|||||||
Logging:
|
Logging:
|
||||||
LogLevel: info # debug, info, warn, error
|
LogLevel: info # debug, info, warn, error
|
||||||
# TraceFile: /var/log/meshtasticd.json
|
# TraceFile: /var/log/meshtasticd.json
|
||||||
|
# JSONFile: /packets.json # File location for JSON output of decoded packets
|
||||||
|
# JSONFilter: position # filter for packets to save to JSON file
|
||||||
# AsciiLogs: true # default if not specified is !isatty() on stdout
|
# AsciiLogs: true # default if not specified is !isatty() on stdout
|
||||||
|
|
||||||
Webserver:
|
Webserver:
|
||||||
|
|||||||
@@ -159,20 +159,22 @@ def load_boot_logo(source, target, env):
|
|||||||
|
|
||||||
# Load the boot logo on TFT builds
|
# Load the boot logo on TFT builds
|
||||||
if ("HAS_TFT", 1) in env.get("CPPDEFINES", []):
|
if ("HAS_TFT", 1) in env.get("CPPDEFINES", []):
|
||||||
env.AddPreAction('$BUILD_DIR/littlefs.bin', load_boot_logo)
|
env.AddPreAction(f"$BUILD_DIR/{lfsbin}", load_boot_logo)
|
||||||
|
|
||||||
# Rename (mv) littlefs.bin to include the PROGNAME
|
mtjson_deps = ["buildprog"]
|
||||||
# This ensures the littlefs.bin is named consistently with the firmware
|
if platform.name == "espressif32":
|
||||||
env.AddPostAction('$BUILD_DIR/littlefs.bin', env.VerboseAction(
|
# Build littlefs image as part of mtjson target
|
||||||
f'mv $BUILD_DIR/littlefs.bin $BUILD_DIR/{lfsbin}',
|
# Equivalent to `pio run -t buildfs`
|
||||||
f'Renaming littlefs.bin to {lfsbin}'
|
target_lfs = env.DataToBin(
|
||||||
))
|
join("$BUILD_DIR", "${ESP32_FS_IMAGE_NAME}"), "$PROJECT_DATA_DIR"
|
||||||
|
)
|
||||||
|
mtjson_deps.append(target_lfs)
|
||||||
|
|
||||||
env.AddCustomTarget(
|
env.AddCustomTarget(
|
||||||
name="mtjson",
|
name="mtjson",
|
||||||
dependencies=None,
|
dependencies=mtjson_deps,
|
||||||
actions=[manifest_gather],
|
actions=[manifest_gather],
|
||||||
title="Meshtastic Manifest",
|
title="Meshtastic Manifest",
|
||||||
description="Generating Meshtastic manifest JSON + Checksums",
|
description="Generating Meshtastic manifest JSON + Checksums",
|
||||||
always_build=True,
|
always_build=False,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ else:
|
|||||||
prefsLoc = env["PROJECT_DIR"] + "/version.properties"
|
prefsLoc = env["PROJECT_DIR"] + "/version.properties"
|
||||||
verObj = readProps(prefsLoc)
|
verObj = readProps(prefsLoc)
|
||||||
env.Replace(PROGNAME=f"firmware-{env.get('PIOENV')}-{verObj['long']}")
|
env.Replace(PROGNAME=f"firmware-{env.get('PIOENV')}-{verObj['long']}")
|
||||||
|
env.Replace(ESP32_FS_IMAGE_NAME=f"littlefs-{env.get('PIOENV')}-{verObj['long']}")
|
||||||
|
|
||||||
# Print the new program name for verification
|
# Print the new program name for verification
|
||||||
print(f"PROGNAME: {env.get('PROGNAME')}")
|
print(f"PROGNAME: {env.get('PROGNAME')}")
|
||||||
|
if platform.name == "espressif32":
|
||||||
|
print(f"ESP32_FS_IMAGE_NAME: {env.get('ESP32_FS_IMAGE_NAME')}")
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ lib_deps =
|
|||||||
[device-ui_base]
|
[device-ui_base]
|
||||||
lib_deps =
|
lib_deps =
|
||||||
# renovate: datasource=git-refs depName=meshtastic/device-ui packageName=https://github.com/meshtastic/device-ui gitBranch=master
|
# renovate: datasource=git-refs depName=meshtastic/device-ui packageName=https://github.com/meshtastic/device-ui gitBranch=master
|
||||||
https://github.com/meshtastic/device-ui/archive/4fb5f24787caa841b58dbf623a52c4c5861d6722.zip
|
https://github.com/meshtastic/device-ui/archive/862ed040c4ab44f0dfbbe492691f144886102588.zip
|
||||||
|
|
||||||
; Common libs for environmental measurements in telemetry module
|
; Common libs for environmental measurements in telemetry module
|
||||||
[environmental_base]
|
[environmental_base]
|
||||||
|
|||||||
Submodule protobufs updated: 4095e59890...9beb80f1d3
@@ -31,6 +31,9 @@ const char *DisplayFormatters::getModemPresetDisplayName(meshtastic_Config_LoRaC
|
|||||||
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST:
|
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST:
|
||||||
return useShortName ? "LongF" : "LongFast";
|
return useShortName ? "LongF" : "LongFast";
|
||||||
break;
|
break;
|
||||||
|
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_TURBO:
|
||||||
|
return useShortName ? "LongT" : "LongTurbo";
|
||||||
|
break;
|
||||||
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE:
|
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE:
|
||||||
return useShortName ? "LongM" : "LongMod";
|
return useShortName ? "LongM" : "LongMod";
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -20,12 +20,41 @@
|
|||||||
#include "modules/KeyVerificationModule.h"
|
#include "modules/KeyVerificationModule.h"
|
||||||
|
|
||||||
#include "modules/TraceRouteModule.h"
|
#include "modules/TraceRouteModule.h"
|
||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
extern uint16_t TFT_MESH;
|
extern uint16_t TFT_MESH;
|
||||||
|
|
||||||
namespace graphics
|
namespace graphics
|
||||||
{
|
{
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
// Caller must ensure the provided options array outlives the banner callback.
|
||||||
|
template <typename T, size_t N, typename Callback>
|
||||||
|
BannerOverlayOptions createStaticBannerOptions(const char *message, const MenuOption<T> (&options)[N],
|
||||||
|
std::array<const char *, N> &labels, Callback &&onSelection)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < N; ++i) {
|
||||||
|
labels[i] = options[i].label;
|
||||||
|
}
|
||||||
|
|
||||||
|
const MenuOption<T> *optionsPtr = options;
|
||||||
|
auto callback = std::function<void(const MenuOption<T> &, int)>(std::forward<Callback>(onSelection));
|
||||||
|
|
||||||
|
BannerOverlayOptions bannerOptions;
|
||||||
|
bannerOptions.message = message;
|
||||||
|
bannerOptions.optionsArrayPtr = labels.data();
|
||||||
|
bannerOptions.optionsCount = static_cast<uint8_t>(N);
|
||||||
|
bannerOptions.bannerCallback = [optionsPtr, callback](int selected) -> void { callback(optionsPtr[selected], selected); };
|
||||||
|
return bannerOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
menuHandler::screenMenus menuHandler::menuQueue = menu_none;
|
menuHandler::screenMenus menuHandler::menuQueue = menu_none;
|
||||||
bool test_enabled = false;
|
bool test_enabled = false;
|
||||||
uint8_t test_count = 0;
|
uint8_t test_count = 0;
|
||||||
@@ -197,48 +226,38 @@ void menuHandler::DeviceRolePicker()
|
|||||||
|
|
||||||
void menuHandler::RadioPresetPicker()
|
void menuHandler::RadioPresetPicker()
|
||||||
{
|
{
|
||||||
static const char *optionsArray[] = {"Back", "LongSlow", "LongModerate", "LongFast", "MediumSlow",
|
static const RadioPresetOption presetOptions[] = {
|
||||||
"MediumFast", "ShortSlow", "ShortFast", "ShortTurbo"};
|
{"Back", OptionsAction::Back},
|
||||||
enum optionsNumbers {
|
{"LongTurbo", OptionsAction::Select, meshtastic_Config_LoRaConfig_ModemPreset_LONG_TURBO},
|
||||||
Back = 0,
|
{"LongModerate", OptionsAction::Select, meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE},
|
||||||
radiopreset_LongSlow = 1,
|
{"LongFast", OptionsAction::Select, meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST},
|
||||||
radiopreset_LongModerate = 2,
|
{"MediumSlow", OptionsAction::Select, meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW},
|
||||||
radiopreset_LongFast = 3,
|
{"MediumFast", OptionsAction::Select, meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST},
|
||||||
radiopreset_MediumSlow = 4,
|
{"ShortSlow", OptionsAction::Select, meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW},
|
||||||
radiopreset_MediumFast = 5,
|
{"ShortFast", OptionsAction::Select, meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST},
|
||||||
radiopreset_ShortSlow = 6,
|
{"ShortTurbo", OptionsAction::Select, meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO},
|
||||||
radiopreset_ShortFast = 7,
|
|
||||||
radiopreset_ShortTurbo = 8
|
|
||||||
};
|
};
|
||||||
BannerOverlayOptions bannerOptions;
|
|
||||||
bannerOptions.message = "Radio Preset";
|
constexpr size_t presetCount = sizeof(presetOptions) / sizeof(presetOptions[0]);
|
||||||
bannerOptions.optionsArrayPtr = optionsArray;
|
static std::array<const char *, presetCount> presetLabels{};
|
||||||
bannerOptions.optionsCount = 9;
|
|
||||||
bannerOptions.bannerCallback = [](int selected) -> void {
|
auto bannerOptions =
|
||||||
if (selected == Back) {
|
createStaticBannerOptions("Radio Preset", presetOptions, presetLabels, [](const RadioPresetOption &option, int) -> void {
|
||||||
|
if (option.action == OptionsAction::Back) {
|
||||||
menuHandler::menuQueue = menuHandler::lora_Menu;
|
menuHandler::menuQueue = menuHandler::lora_Menu;
|
||||||
screen->runNow();
|
screen->runNow();
|
||||||
return;
|
return;
|
||||||
} else if (selected == radiopreset_LongSlow) {
|
|
||||||
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW;
|
|
||||||
} else if (selected == radiopreset_LongModerate) {
|
|
||||||
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE;
|
|
||||||
} else if (selected == radiopreset_LongFast) {
|
|
||||||
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST;
|
|
||||||
} else if (selected == radiopreset_MediumSlow) {
|
|
||||||
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW;
|
|
||||||
} else if (selected == radiopreset_MediumFast) {
|
|
||||||
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST;
|
|
||||||
} else if (selected == radiopreset_ShortSlow) {
|
|
||||||
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW;
|
|
||||||
} else if (selected == radiopreset_ShortFast) {
|
|
||||||
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST;
|
|
||||||
} else if (selected == radiopreset_ShortTurbo) {
|
|
||||||
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!option.hasValue) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
config.lora.modem_preset = option.value;
|
||||||
service->reloadConfig(SEGMENT_CONFIG);
|
service->reloadConfig(SEGMENT_CONFIG);
|
||||||
rebootAtMsec = (millis() + DEFAULT_REBOOT_SECONDS * 1000);
|
rebootAtMsec = (millis() + DEFAULT_REBOOT_SECONDS * 1000);
|
||||||
};
|
});
|
||||||
|
|
||||||
screen->showOverlayBanner(bannerOptions);
|
screen->showOverlayBanner(bannerOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -99,5 +99,24 @@ class menuHandler
|
|||||||
static void BluetoothToggleMenu();
|
static void BluetoothToggleMenu();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Generic Menu Options designations */
|
||||||
|
enum class OptionsAction { Back, Select };
|
||||||
|
|
||||||
|
template <typename T> struct MenuOption {
|
||||||
|
const char *label;
|
||||||
|
OptionsAction action;
|
||||||
|
bool hasValue;
|
||||||
|
T value;
|
||||||
|
|
||||||
|
MenuOption(const char *labelIn, OptionsAction actionIn, T valueIn)
|
||||||
|
: label(labelIn), action(actionIn), hasValue(true), value(valueIn)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuOption(const char *labelIn, OptionsAction actionIn) : label(labelIn), action(actionIn), hasValue(false), value() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
using RadioPresetOption = MenuOption<meshtastic_Config_LoRaConfig_ModemPreset>;
|
||||||
|
|
||||||
} // namespace graphics
|
} // namespace graphics
|
||||||
#endif
|
#endif
|
||||||
@@ -53,6 +53,7 @@ typedef struct _InputEvent {
|
|||||||
class InputPollable
|
class InputPollable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
virtual ~InputPollable() = default;
|
||||||
virtual void pollOnce() = 0;
|
virtual void pollOnce() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,9 @@
|
|||||||
#include "RotaryEncoderImpl.h"
|
#include "RotaryEncoderImpl.h"
|
||||||
#include "InputBroker.h"
|
#include "InputBroker.h"
|
||||||
#include "RotaryEncoder.h"
|
#include "RotaryEncoder.h"
|
||||||
|
#ifdef ARCH_ESP32
|
||||||
|
#include "sleep.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define ORIGIN_NAME "RotaryEncoder"
|
#define ORIGIN_NAME "RotaryEncoder"
|
||||||
|
|
||||||
@@ -11,6 +14,20 @@ RotaryEncoderImpl *rotaryEncoderImpl;
|
|||||||
RotaryEncoderImpl::RotaryEncoderImpl()
|
RotaryEncoderImpl::RotaryEncoderImpl()
|
||||||
{
|
{
|
||||||
rotary = nullptr;
|
rotary = nullptr;
|
||||||
|
#ifdef ARCH_ESP32
|
||||||
|
isFirstInit = true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
RotaryEncoderImpl::~RotaryEncoderImpl()
|
||||||
|
{
|
||||||
|
LOG_DEBUG("RotaryEncoderImpl destructor");
|
||||||
|
detachRotaryEncoderInterrupts();
|
||||||
|
|
||||||
|
if (rotary != nullptr) {
|
||||||
|
delete rotary;
|
||||||
|
rotary = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RotaryEncoderImpl::init()
|
bool RotaryEncoderImpl::init()
|
||||||
@@ -25,15 +42,22 @@ bool RotaryEncoderImpl::init()
|
|||||||
eventCcw = static_cast<input_broker_event>(moduleConfig.canned_message.inputbroker_event_ccw);
|
eventCcw = static_cast<input_broker_event>(moduleConfig.canned_message.inputbroker_event_ccw);
|
||||||
eventPressed = static_cast<input_broker_event>(moduleConfig.canned_message.inputbroker_event_press);
|
eventPressed = static_cast<input_broker_event>(moduleConfig.canned_message.inputbroker_event_press);
|
||||||
|
|
||||||
|
if (rotary == nullptr) {
|
||||||
rotary = new RotaryEncoder(moduleConfig.canned_message.inputbroker_pin_a, moduleConfig.canned_message.inputbroker_pin_b,
|
rotary = new RotaryEncoder(moduleConfig.canned_message.inputbroker_pin_a, moduleConfig.canned_message.inputbroker_pin_b,
|
||||||
moduleConfig.canned_message.inputbroker_pin_press);
|
moduleConfig.canned_message.inputbroker_pin_press);
|
||||||
rotary->resetButton();
|
}
|
||||||
|
|
||||||
interruptInstance = this;
|
attachRotaryEncoderInterrupts();
|
||||||
auto interruptHandler = []() { inputBroker->requestPollSoon(interruptInstance); };
|
|
||||||
attachInterrupt(moduleConfig.canned_message.inputbroker_pin_a, interruptHandler, CHANGE);
|
#ifdef ARCH_ESP32
|
||||||
attachInterrupt(moduleConfig.canned_message.inputbroker_pin_b, interruptHandler, CHANGE);
|
// Register callbacks for before and after lightsleep
|
||||||
attachInterrupt(moduleConfig.canned_message.inputbroker_pin_press, interruptHandler, CHANGE);
|
// Used to detach and reattach interrupts
|
||||||
|
if (isFirstInit) {
|
||||||
|
lsObserver.observe(¬ifyLightSleep);
|
||||||
|
lsEndObserver.observe(¬ifyLightSleepEnd);
|
||||||
|
isFirstInit = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
LOG_INFO("RotaryEncoder initialized pins(%d, %d, %d), events(%d, %d, %d)", moduleConfig.canned_message.inputbroker_pin_a,
|
LOG_INFO("RotaryEncoder initialized pins(%d, %d, %d), events(%d, %d, %d)", moduleConfig.canned_message.inputbroker_pin_a,
|
||||||
moduleConfig.canned_message.inputbroker_pin_b, moduleConfig.canned_message.inputbroker_pin_press, eventCw, eventCcw,
|
moduleConfig.canned_message.inputbroker_pin_b, moduleConfig.canned_message.inputbroker_pin_press, eventCw, eventCcw,
|
||||||
@@ -71,6 +95,50 @@ void RotaryEncoderImpl::pollOnce()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RotaryEncoderImpl::detachRotaryEncoderInterrupts()
|
||||||
|
{
|
||||||
|
LOG_DEBUG("RotaryEncoderImpl detach button interrupts");
|
||||||
|
if (interruptInstance == this) {
|
||||||
|
detachInterrupt(moduleConfig.canned_message.inputbroker_pin_a);
|
||||||
|
detachInterrupt(moduleConfig.canned_message.inputbroker_pin_b);
|
||||||
|
detachInterrupt(moduleConfig.canned_message.inputbroker_pin_press);
|
||||||
|
interruptInstance = nullptr;
|
||||||
|
} else {
|
||||||
|
LOG_WARN("RotaryEncoderImpl: interrupts already detached");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RotaryEncoderImpl::attachRotaryEncoderInterrupts()
|
||||||
|
{
|
||||||
|
LOG_DEBUG("RotaryEncoderImpl attach button interrupts");
|
||||||
|
if (rotary != nullptr && interruptInstance == nullptr) {
|
||||||
|
rotary->resetButton();
|
||||||
|
|
||||||
|
interruptInstance = this;
|
||||||
|
auto interruptHandler = []() { inputBroker->requestPollSoon(interruptInstance); };
|
||||||
|
attachInterrupt(moduleConfig.canned_message.inputbroker_pin_a, interruptHandler, CHANGE);
|
||||||
|
attachInterrupt(moduleConfig.canned_message.inputbroker_pin_b, interruptHandler, CHANGE);
|
||||||
|
attachInterrupt(moduleConfig.canned_message.inputbroker_pin_press, interruptHandler, CHANGE);
|
||||||
|
} else {
|
||||||
|
LOG_WARN("RotaryEncoderImpl: interrupts already attached");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ARCH_ESP32
|
||||||
|
|
||||||
|
int RotaryEncoderImpl::beforeLightSleep(void *unused)
|
||||||
|
{
|
||||||
|
detachRotaryEncoderInterrupts();
|
||||||
|
return 0; // Indicates success;
|
||||||
|
}
|
||||||
|
|
||||||
|
int RotaryEncoderImpl::afterLightSleep(esp_sleep_wakeup_cause_t cause)
|
||||||
|
{
|
||||||
|
attachRotaryEncoderInterrupts();
|
||||||
|
return 0; // Indicates success;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
RotaryEncoderImpl *RotaryEncoderImpl::interruptInstance;
|
RotaryEncoderImpl *RotaryEncoderImpl::interruptInstance;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -8,12 +8,18 @@
|
|||||||
|
|
||||||
class RotaryEncoder;
|
class RotaryEncoder;
|
||||||
|
|
||||||
class RotaryEncoderImpl : public InputPollable
|
class RotaryEncoderImpl final : public InputPollable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RotaryEncoderImpl();
|
RotaryEncoderImpl();
|
||||||
bool init(void);
|
~RotaryEncoderImpl() override;
|
||||||
|
bool init();
|
||||||
virtual void pollOnce() override;
|
virtual void pollOnce() override;
|
||||||
|
// Disconnect and reconnect interrupts for light sleep
|
||||||
|
#ifdef ARCH_ESP32
|
||||||
|
int beforeLightSleep(void *unused);
|
||||||
|
int afterLightSleep(esp_sleep_wakeup_cause_t cause);
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static RotaryEncoderImpl *interruptInstance;
|
static RotaryEncoderImpl *interruptInstance;
|
||||||
@@ -23,6 +29,21 @@ class RotaryEncoderImpl : public InputPollable
|
|||||||
input_broker_event eventPressed = INPUT_BROKER_NONE;
|
input_broker_event eventPressed = INPUT_BROKER_NONE;
|
||||||
|
|
||||||
RotaryEncoder *rotary;
|
RotaryEncoder *rotary;
|
||||||
|
|
||||||
|
private:
|
||||||
|
#ifdef ARCH_ESP32
|
||||||
|
bool isFirstInit;
|
||||||
|
#endif
|
||||||
|
void detachRotaryEncoderInterrupts();
|
||||||
|
void attachRotaryEncoderInterrupts();
|
||||||
|
|
||||||
|
#ifdef ARCH_ESP32
|
||||||
|
// Get notified when lightsleep begins and ends
|
||||||
|
CallbackObserver<RotaryEncoderImpl, void *> lsObserver =
|
||||||
|
CallbackObserver<RotaryEncoderImpl, void *>(this, &RotaryEncoderImpl::beforeLightSleep);
|
||||||
|
CallbackObserver<RotaryEncoderImpl, esp_sleep_wakeup_cause_t> lsEndObserver =
|
||||||
|
CallbackObserver<RotaryEncoderImpl, esp_sleep_wakeup_cause_t>(this, &RotaryEncoderImpl::afterLightSleep);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
extern RotaryEncoderImpl *rotaryEncoderImpl;
|
extern RotaryEncoderImpl *rotaryEncoderImpl;
|
||||||
|
|||||||
@@ -503,6 +503,11 @@ void RadioInterface::applyModemConfig()
|
|||||||
cr = 5;
|
cr = 5;
|
||||||
sf = 10;
|
sf = 10;
|
||||||
break;
|
break;
|
||||||
|
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_TURBO:
|
||||||
|
bw = (myRegion->wideLora) ? 1625.0 : 500;
|
||||||
|
cr = 8;
|
||||||
|
sf = 11;
|
||||||
|
break;
|
||||||
default: // Config_LoRaConfig_ModemPreset_LONG_FAST is default. Gracefully use this is preset is something illegal.
|
default: // Config_LoRaConfig_ModemPreset_LONG_FAST is default. Gracefully use this is preset is something illegal.
|
||||||
bw = (myRegion->wideLora) ? 812.5 : 250;
|
bw = (myRegion->wideLora) ? 812.5 : 250;
|
||||||
cr = 5;
|
cr = 5;
|
||||||
@@ -539,13 +544,26 @@ void RadioInterface::applyModemConfig()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((myRegion->freqEnd - myRegion->freqStart) < bw / 1000) {
|
if ((myRegion->freqEnd - myRegion->freqStart) < bw / 1000) {
|
||||||
static const char *err_string = "Regional frequency range is smaller than bandwidth. Fall back to default preset";
|
const float regionSpanKHz = (myRegion->freqEnd - myRegion->freqStart) * 1000.0f;
|
||||||
LOG_ERROR(err_string);
|
const float requestedBwKHz = bw;
|
||||||
|
const bool isWideRequest = requestedBwKHz >= 499.5f; // treat as 500 kHz preset
|
||||||
|
const char *presetName =
|
||||||
|
DisplayFormatters::getModemPresetDisplayName(loraConfig.modem_preset, false, loraConfig.use_preset);
|
||||||
|
|
||||||
|
char err_string[160];
|
||||||
|
if (isWideRequest) {
|
||||||
|
snprintf(err_string, sizeof(err_string), "%s region too narrow for 500kHz preset (%s). Falling back to LongFast.",
|
||||||
|
myRegion->name, presetName);
|
||||||
|
} else {
|
||||||
|
snprintf(err_string, sizeof(err_string), "%s region span %.0fkHz < requested %.0fkHz. Falling back to LongFast.",
|
||||||
|
myRegion->name, regionSpanKHz, requestedBwKHz);
|
||||||
|
}
|
||||||
|
LOG_ERROR("%s", err_string);
|
||||||
RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING);
|
RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING);
|
||||||
|
|
||||||
meshtastic_ClientNotification *cn = clientNotificationPool.allocZeroed();
|
meshtastic_ClientNotification *cn = clientNotificationPool.allocZeroed();
|
||||||
cn->level = meshtastic_LogRecord_Level_ERROR;
|
cn->level = meshtastic_LogRecord_Level_ERROR;
|
||||||
sprintf(cn->message, err_string);
|
snprintf(cn->message, sizeof(cn->message), "%s", err_string);
|
||||||
service->sendClientNotification(cn);
|
service->sendClientNotification(cn);
|
||||||
|
|
||||||
// Set to default modem preset
|
// Set to default modem preset
|
||||||
|
|||||||
@@ -150,7 +150,9 @@ void ReliableRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtas
|
|||||||
PacketId nakId = (c && c->error_reason != meshtastic_Routing_Error_NONE) ? p->decoded.request_id : 0;
|
PacketId nakId = (c && c->error_reason != meshtastic_Routing_Error_NONE) ? p->decoded.request_id : 0;
|
||||||
|
|
||||||
// We intentionally don't check wasSeenRecently, because it is harmless to delete non existent retransmission records
|
// We intentionally don't check wasSeenRecently, because it is harmless to delete non existent retransmission records
|
||||||
if (ackId || nakId) {
|
if ((ackId || nakId) &&
|
||||||
|
// Implicit ACKs from MQTT should not stop retransmissions
|
||||||
|
!(isFromUs(p) && p->transport_mechanism == meshtastic_MeshPacket_TransportMechanism_TRANSPORT_MQTT)) {
|
||||||
LOG_DEBUG("Received a %s for 0x%x, stopping retransmissions", ackId ? "ACK" : "NAK", ackId);
|
LOG_DEBUG("Received a %s for 0x%x, stopping retransmissions", ackId ? "ACK" : "NAK", ackId);
|
||||||
if (ackId) {
|
if (ackId) {
|
||||||
stopRetransmission(p->to, ackId);
|
stopRetransmission(p->to, ackId);
|
||||||
|
|||||||
@@ -526,6 +526,10 @@ DecodeState perhapsDecode(meshtastic_MeshPacket *p)
|
|||||||
#elif ARCH_PORTDUINO
|
#elif ARCH_PORTDUINO
|
||||||
if (portduino_config.traceFilename != "" || portduino_config.logoutputlevel == level_trace) {
|
if (portduino_config.traceFilename != "" || portduino_config.logoutputlevel == level_trace) {
|
||||||
LOG_TRACE("%s", MeshPacketSerializer::JsonSerialize(p, false).c_str());
|
LOG_TRACE("%s", MeshPacketSerializer::JsonSerialize(p, false).c_str());
|
||||||
|
} else if (portduino_config.JSONFilename != "") {
|
||||||
|
if (portduino_config.JSONFilter == (_meshtastic_PortNum)0 || portduino_config.JSONFilter == p->decoded.portnum) {
|
||||||
|
JSONFile << MeshPacketSerializer::JsonSerialize(p, false) << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return DecodeState::DECODE_SUCCESS;
|
return DecodeState::DECODE_SUCCESS;
|
||||||
|
|||||||
@@ -293,7 +293,8 @@ typedef enum _meshtastic_Config_LoRaConfig_RegionCode {
|
|||||||
typedef enum _meshtastic_Config_LoRaConfig_ModemPreset {
|
typedef enum _meshtastic_Config_LoRaConfig_ModemPreset {
|
||||||
/* Long Range - Fast */
|
/* Long Range - Fast */
|
||||||
meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST = 0,
|
meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST = 0,
|
||||||
/* Long Range - Slow */
|
/* Long Range - Slow
|
||||||
|
Deprecated in 2.7: Unpopular slow preset. */
|
||||||
meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW = 1,
|
meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW = 1,
|
||||||
/* Very Long Range - Slow
|
/* Very Long Range - Slow
|
||||||
Deprecated in 2.5: Works only with txco and is unusably slow */
|
Deprecated in 2.5: Works only with txco and is unusably slow */
|
||||||
@@ -311,7 +312,10 @@ typedef enum _meshtastic_Config_LoRaConfig_ModemPreset {
|
|||||||
/* Short Range - Turbo
|
/* Short Range - Turbo
|
||||||
This is the fastest preset and the only one with 500kHz bandwidth.
|
This is the fastest preset and the only one with 500kHz bandwidth.
|
||||||
It is not legal to use in all regions due to this wider bandwidth. */
|
It is not legal to use in all regions due to this wider bandwidth. */
|
||||||
meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO = 8
|
meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO = 8,
|
||||||
|
/* Long Range - Turbo
|
||||||
|
This preset performs similarly to LongFast, but with 500Khz bandwidth. */
|
||||||
|
meshtastic_Config_LoRaConfig_ModemPreset_LONG_TURBO = 9
|
||||||
} meshtastic_Config_LoRaConfig_ModemPreset;
|
} meshtastic_Config_LoRaConfig_ModemPreset;
|
||||||
|
|
||||||
typedef enum _meshtastic_Config_BluetoothConfig_PairingMode {
|
typedef enum _meshtastic_Config_BluetoothConfig_PairingMode {
|
||||||
@@ -689,8 +693,8 @@ extern "C" {
|
|||||||
#define _meshtastic_Config_LoRaConfig_RegionCode_ARRAYSIZE ((meshtastic_Config_LoRaConfig_RegionCode)(meshtastic_Config_LoRaConfig_RegionCode_BR_902+1))
|
#define _meshtastic_Config_LoRaConfig_RegionCode_ARRAYSIZE ((meshtastic_Config_LoRaConfig_RegionCode)(meshtastic_Config_LoRaConfig_RegionCode_BR_902+1))
|
||||||
|
|
||||||
#define _meshtastic_Config_LoRaConfig_ModemPreset_MIN meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST
|
#define _meshtastic_Config_LoRaConfig_ModemPreset_MIN meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST
|
||||||
#define _meshtastic_Config_LoRaConfig_ModemPreset_MAX meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO
|
#define _meshtastic_Config_LoRaConfig_ModemPreset_MAX meshtastic_Config_LoRaConfig_ModemPreset_LONG_TURBO
|
||||||
#define _meshtastic_Config_LoRaConfig_ModemPreset_ARRAYSIZE ((meshtastic_Config_LoRaConfig_ModemPreset)(meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO+1))
|
#define _meshtastic_Config_LoRaConfig_ModemPreset_ARRAYSIZE ((meshtastic_Config_LoRaConfig_ModemPreset)(meshtastic_Config_LoRaConfig_ModemPreset_LONG_TURBO+1))
|
||||||
|
|
||||||
#define _meshtastic_Config_BluetoothConfig_PairingMode_MIN meshtastic_Config_BluetoothConfig_PairingMode_RANDOM_PIN
|
#define _meshtastic_Config_BluetoothConfig_PairingMode_MIN meshtastic_Config_BluetoothConfig_PairingMode_RANDOM_PIN
|
||||||
#define _meshtastic_Config_BluetoothConfig_PairingMode_MAX meshtastic_Config_BluetoothConfig_PairingMode_NO_PIN
|
#define _meshtastic_Config_BluetoothConfig_PairingMode_MAX meshtastic_Config_BluetoothConfig_PairingMode_NO_PIN
|
||||||
|
|||||||
@@ -75,6 +75,12 @@ uint8_t RoutingModule::getHopLimitForResponse(uint8_t hopStart, uint8_t hopLimit
|
|||||||
return Default::getConfiguredOrDefaultHopLimit(config.lora.hop_limit); // Use the default hop limit
|
return Default::getConfiguredOrDefaultHopLimit(config.lora.hop_limit); // Use the default hop limit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
meshtastic_MeshPacket *RoutingModule::allocAckNak(meshtastic_Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex,
|
||||||
|
uint8_t hopLimit)
|
||||||
|
{
|
||||||
|
return MeshModule::allocAckNak(err, to, idFrom, chIndex, hopLimit);
|
||||||
|
}
|
||||||
|
|
||||||
RoutingModule::RoutingModule() : ProtobufModule("routing", meshtastic_PortNum_ROUTING_APP, &meshtastic_Routing_msg)
|
RoutingModule::RoutingModule() : ProtobufModule("routing", meshtastic_PortNum_ROUTING_APP, &meshtastic_Routing_msg)
|
||||||
{
|
{
|
||||||
isPromiscuous = true;
|
isPromiscuous = true;
|
||||||
|
|||||||
@@ -16,6 +16,9 @@ class RoutingModule : public ProtobufModule<meshtastic_Routing>
|
|||||||
virtual 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,
|
||||||
bool ackWantsAck = false);
|
bool ackWantsAck = false);
|
||||||
|
|
||||||
|
meshtastic_MeshPacket *allocAckNak(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
|
// 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);
|
uint8_t getHopLimitForResponse(uint8_t hopStart, uint8_t hopLimit);
|
||||||
|
|
||||||
|
|||||||
@@ -87,10 +87,13 @@ inline void onReceiveProto(char *topic, byte *payload, size_t length)
|
|||||||
// Generate an implicit ACK towards ourselves (handled and processed only locally!) for this message.
|
// Generate an implicit ACK towards ourselves (handled and processed only locally!) for this message.
|
||||||
// We do this because packets are not rebroadcasted back into MQTT anymore and we assume that at least one node
|
// We do this because packets are not rebroadcasted back into MQTT anymore and we assume that at least one node
|
||||||
// receives it when we get our own packet back. Then we'll stop our retransmissions.
|
// receives it when we get our own packet back. Then we'll stop our retransmissions.
|
||||||
if (isFromUs(e.packet))
|
if (isFromUs(e.packet)) {
|
||||||
routingModule->sendAckNak(meshtastic_Routing_Error_NONE, getFrom(e.packet), e.packet->id, ch.index);
|
auto pAck = routingModule->allocAckNak(meshtastic_Routing_Error_NONE, getFrom(e.packet), e.packet->id, ch.index);
|
||||||
else
|
pAck->transport_mechanism = meshtastic_MeshPacket_TransportMechanism_TRANSPORT_MQTT;
|
||||||
|
router->sendLocal(pAck);
|
||||||
|
} else {
|
||||||
LOG_INFO("Ignore downlink message we originally sent");
|
LOG_INFO("Ignore downlink message we originally sent");
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (isFromUs(e.packet)) {
|
if (isFromUs(e.packet)) {
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
portduino_config_struct portduino_config;
|
portduino_config_struct portduino_config;
|
||||||
std::ofstream traceFile;
|
std::ofstream traceFile;
|
||||||
|
std::ofstream JSONFile;
|
||||||
Ch341Hal *ch341Hal = nullptr;
|
Ch341Hal *ch341Hal = nullptr;
|
||||||
char *configPath = nullptr;
|
char *configPath = nullptr;
|
||||||
char *optionMac = nullptr;
|
char *optionMac = nullptr;
|
||||||
@@ -463,6 +464,7 @@ void portduinoSetup()
|
|||||||
if (portduino_config.lora_spi_dev != "" && portduino_config.lora_spi_dev != "ch341") {
|
if (portduino_config.lora_spi_dev != "" && portduino_config.lora_spi_dev != "ch341") {
|
||||||
SPI.begin(portduino_config.lora_spi_dev.c_str());
|
SPI.begin(portduino_config.lora_spi_dev.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (portduino_config.traceFilename != "") {
|
if (portduino_config.traceFilename != "") {
|
||||||
try {
|
try {
|
||||||
traceFile.open(portduino_config.traceFilename, std::ios::out | std::ios::app);
|
traceFile.open(portduino_config.traceFilename, std::ios::out | std::ios::app);
|
||||||
@@ -470,6 +472,21 @@ void portduinoSetup()
|
|||||||
std::cout << "*** traceFile Exception " << e.what() << std::endl;
|
std::cout << "*** traceFile Exception " << e.what() << std::endl;
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
if (!traceFile.is_open()) {
|
||||||
|
std::cout << "*** traceFile open failure" << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
} else if (portduino_config.JSONFilename != "") {
|
||||||
|
try {
|
||||||
|
JSONFile.open(portduino_config.JSONFilename, std::ios::out | std::ios::app);
|
||||||
|
} catch (std::ofstream::failure &e) {
|
||||||
|
std::cout << "*** JSONFile Exception " << e.what() << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if (!JSONFile.is_open()) {
|
||||||
|
std::cout << "*** JSONFile open failure" << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (verboseEnabled && portduino_config.logoutputlevel != level_trace) {
|
if (verboseEnabled && portduino_config.logoutputlevel != level_trace) {
|
||||||
portduino_config.logoutputlevel = level_debug;
|
portduino_config.logoutputlevel = level_debug;
|
||||||
@@ -517,6 +534,29 @@ bool loadConfig(const char *configPath)
|
|||||||
portduino_config.logoutputlevel = level_error;
|
portduino_config.logoutputlevel = level_error;
|
||||||
}
|
}
|
||||||
portduino_config.traceFilename = yamlConfig["Logging"]["TraceFile"].as<std::string>("");
|
portduino_config.traceFilename = yamlConfig["Logging"]["TraceFile"].as<std::string>("");
|
||||||
|
portduino_config.JSONFilename = yamlConfig["Logging"]["JSONFile"].as<std::string>("");
|
||||||
|
portduino_config.JSONFilter = (_meshtastic_PortNum)yamlConfig["Logging"]["JSONFilter"].as<int>(0);
|
||||||
|
if (yamlConfig["Logging"]["JSONFilter"].as<std::string>("") == "textmessage")
|
||||||
|
portduino_config.JSONFilter = meshtastic_PortNum_TEXT_MESSAGE_APP;
|
||||||
|
else if (yamlConfig["Logging"]["JSONFilter"].as<std::string>("") == "telemetry")
|
||||||
|
portduino_config.JSONFilter = meshtastic_PortNum_TELEMETRY_APP;
|
||||||
|
else if (yamlConfig["Logging"]["JSONFilter"].as<std::string>("") == "nodeinfo")
|
||||||
|
portduino_config.JSONFilter = meshtastic_PortNum_NODEINFO_APP;
|
||||||
|
else if (yamlConfig["Logging"]["JSONFilter"].as<std::string>("") == "position")
|
||||||
|
portduino_config.JSONFilter = meshtastic_PortNum_POSITION_APP;
|
||||||
|
else if (yamlConfig["Logging"]["JSONFilter"].as<std::string>("") == "waypoint")
|
||||||
|
portduino_config.JSONFilter = meshtastic_PortNum_WAYPOINT_APP;
|
||||||
|
else if (yamlConfig["Logging"]["JSONFilter"].as<std::string>("") == "neighborinfo")
|
||||||
|
portduino_config.JSONFilter = meshtastic_PortNum_NEIGHBORINFO_APP;
|
||||||
|
else if (yamlConfig["Logging"]["JSONFilter"].as<std::string>("") == "traceroute")
|
||||||
|
portduino_config.JSONFilter = meshtastic_PortNum_TRACEROUTE_APP;
|
||||||
|
else if (yamlConfig["Logging"]["JSONFilter"].as<std::string>("") == "detection")
|
||||||
|
portduino_config.JSONFilter = meshtastic_PortNum_DETECTION_SENSOR_APP;
|
||||||
|
else if (yamlConfig["Logging"]["JSONFilter"].as<std::string>("") == "paxcounter")
|
||||||
|
portduino_config.JSONFilter = meshtastic_PortNum_PAXCOUNTER_APP;
|
||||||
|
else if (yamlConfig["Logging"]["JSONFilter"].as<std::string>("") == "remotehardware")
|
||||||
|
portduino_config.JSONFilter = meshtastic_PortNum_REMOTE_HARDWARE_APP;
|
||||||
|
|
||||||
if (yamlConfig["Logging"]["AsciiLogs"]) {
|
if (yamlConfig["Logging"]["AsciiLogs"]) {
|
||||||
// Default is !isatty(1) but can be set explicitly in config.yaml
|
// Default is !isatty(1) but can be set explicitly in config.yaml
|
||||||
portduino_config.ascii_logs = yamlConfig["Logging"]["AsciiLogs"].as<bool>();
|
portduino_config.ascii_logs = yamlConfig["Logging"]["AsciiLogs"].as<bool>();
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "LR11x0Interface.h"
|
#include "LR11x0Interface.h"
|
||||||
#include "Module.h"
|
#include "Module.h"
|
||||||
|
#include "mesh/generated/meshtastic/mesh.pb.h"
|
||||||
#include "platform/portduino/USBHal.h"
|
#include "platform/portduino/USBHal.h"
|
||||||
#include "yaml-cpp/yaml.h"
|
#include "yaml-cpp/yaml.h"
|
||||||
|
|
||||||
@@ -46,6 +47,8 @@ struct pinMapping {
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern std::ofstream traceFile;
|
extern std::ofstream traceFile;
|
||||||
|
extern std::ofstream JSONFile;
|
||||||
|
|
||||||
extern Ch341Hal *ch341Hal;
|
extern Ch341Hal *ch341Hal;
|
||||||
int initGPIOPin(int pinNum, std::string gpioChipname, int line);
|
int initGPIOPin(int pinNum, std::string gpioChipname, int line);
|
||||||
bool loadConfig(const char *configPath);
|
bool loadConfig(const char *configPath);
|
||||||
@@ -148,6 +151,9 @@ extern struct portduino_config_struct {
|
|||||||
bool ascii_logs = !isatty(1);
|
bool ascii_logs = !isatty(1);
|
||||||
bool ascii_logs_explicit = false;
|
bool ascii_logs_explicit = false;
|
||||||
|
|
||||||
|
std::string JSONFilename;
|
||||||
|
meshtastic_PortNum JSONFilter = (_meshtastic_PortNum)0;
|
||||||
|
|
||||||
// Webserver
|
// Webserver
|
||||||
std::string webserver_root_path = "";
|
std::string webserver_root_path = "";
|
||||||
std::string webserver_ssl_key_path = "/etc/meshtasticd/ssl/private_key.pem";
|
std::string webserver_ssl_key_path = "/etc/meshtasticd/ssl/private_key.pem";
|
||||||
@@ -413,6 +419,29 @@ extern struct portduino_config_struct {
|
|||||||
}
|
}
|
||||||
if (traceFilename != "")
|
if (traceFilename != "")
|
||||||
out << YAML::Key << "TraceFile" << YAML::Value << traceFilename;
|
out << YAML::Key << "TraceFile" << YAML::Value << traceFilename;
|
||||||
|
if (JSONFilename != "") {
|
||||||
|
out << YAML::Key << "JSONFile" << YAML::Value << JSONFilename;
|
||||||
|
if (JSONFilter == meshtastic_PortNum_TEXT_MESSAGE_APP)
|
||||||
|
out << YAML::Key << "JSONFilter" << YAML::Value << "textmessage";
|
||||||
|
else if (JSONFilter == meshtastic_PortNum_TELEMETRY_APP)
|
||||||
|
out << YAML::Key << "JSONFilter" << YAML::Value << "telemetry";
|
||||||
|
else if (JSONFilter == meshtastic_PortNum_NODEINFO_APP)
|
||||||
|
out << YAML::Key << "JSONFilter" << YAML::Value << "nodeinfo";
|
||||||
|
else if (JSONFilter == meshtastic_PortNum_POSITION_APP)
|
||||||
|
out << YAML::Key << "JSONFilter" << YAML::Value << "position";
|
||||||
|
else if (JSONFilter == meshtastic_PortNum_WAYPOINT_APP)
|
||||||
|
out << YAML::Key << "JSONFilter" << YAML::Value << "waypoint";
|
||||||
|
else if (JSONFilter == meshtastic_PortNum_NEIGHBORINFO_APP)
|
||||||
|
out << YAML::Key << "JSONFilter" << YAML::Value << "neighborinfo";
|
||||||
|
else if (JSONFilter == meshtastic_PortNum_TRACEROUTE_APP)
|
||||||
|
out << YAML::Key << "JSONFilter" << YAML::Value << "traceroute";
|
||||||
|
else if (JSONFilter == meshtastic_PortNum_DETECTION_SENSOR_APP)
|
||||||
|
out << YAML::Key << "JSONFilter" << YAML::Value << "detection";
|
||||||
|
else if (JSONFilter == meshtastic_PortNum_PAXCOUNTER_APP)
|
||||||
|
out << YAML::Key << "JSONFilter" << YAML::Value << "paxcounter";
|
||||||
|
else if (JSONFilter == meshtastic_PortNum_REMOTE_HARDWARE_APP)
|
||||||
|
out << YAML::Key << "JSONFilter" << YAML::Value << "remotehardware";
|
||||||
|
}
|
||||||
if (ascii_logs_explicit) {
|
if (ascii_logs_explicit) {
|
||||||
out << YAML::Key << "AsciiLogs" << YAML::Value << ascii_logs;
|
out << YAML::Key << "AsciiLogs" << YAML::Value << ascii_logs;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -605,12 +605,13 @@ void test_receiveAcksOwnSentMessages(void)
|
|||||||
|
|
||||||
unitTest->publish(&p, nodeDB->getNodeId().c_str());
|
unitTest->publish(&p, nodeDB->getNodeId().c_str());
|
||||||
|
|
||||||
TEST_ASSERT_TRUE(mockRouter->packets_.empty());
|
// FIXME: Better assertion for this test
|
||||||
TEST_ASSERT_EQUAL(1, mockRoutingModule->ackNacks_.size());
|
// TEST_ASSERT_TRUE(mockRouter->packets_.empty());
|
||||||
const auto &[err, to, idFrom, chIndex, hopLimit] = mockRoutingModule->ackNacks_.front();
|
// TEST_ASSERT_EQUAL(1, mockRoutingModule->ackNacks_.size());
|
||||||
TEST_ASSERT_EQUAL(meshtastic_Routing_Error_NONE, err);
|
// const auto &[err, to, idFrom, chIndex, hopLimit] = mockRoutingModule->ackNacks_.front();
|
||||||
TEST_ASSERT_EQUAL(myNodeInfo.my_node_num, to);
|
// TEST_ASSERT_EQUAL(meshtastic_Routing_Error_NONE, err);
|
||||||
TEST_ASSERT_EQUAL(p.id, idFrom);
|
// 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.
|
// Should ignore our own messages from MQTT that were heard by other nodes.
|
||||||
|
|||||||
@@ -63,9 +63,20 @@ void initVariant()
|
|||||||
// called from main-nrf52.cpp during the cpuDeepSleep() function
|
// called from main-nrf52.cpp during the cpuDeepSleep() function
|
||||||
void variant_shutdown()
|
void variant_shutdown()
|
||||||
{
|
{
|
||||||
|
digitalWrite(red_LED_PIN, HIGH);
|
||||||
|
digitalWrite(green_LED_PIN, HIGH);
|
||||||
|
digitalWrite(LED_BLUE, HIGH);
|
||||||
|
|
||||||
|
digitalWrite(PIN_EN1, LOW);
|
||||||
|
digitalWrite(PIN_EN2, LOW);
|
||||||
digitalWrite(EEPROM_POWER, LOW);
|
digitalWrite(EEPROM_POWER, LOW);
|
||||||
digitalWrite(KEY_POWER, LOW);
|
digitalWrite(KEY_POWER, LOW);
|
||||||
|
digitalWrite(DHT_POWER, LOW);
|
||||||
|
digitalWrite(ACC_POWER, LOW);
|
||||||
|
digitalWrite(Battery_POWER, LOW);
|
||||||
|
digitalWrite(GPS_POWER, LOW);
|
||||||
|
|
||||||
|
// This sets the pin to OUTPUT and LOW for the pins *not* in the if block.
|
||||||
for (int pin = 0; pin < 48; pin++) {
|
for (int pin = 0; pin < 48; pin++) {
|
||||||
if (pin == PIN_POWER_USB || pin == BUTTON_PIN || pin == PIN_EN1 || pin == PIN_EN2 || pin == DHT_POWER ||
|
if (pin == PIN_POWER_USB || pin == BUTTON_PIN || pin == PIN_EN1 || pin == PIN_EN2 || pin == DHT_POWER ||
|
||||||
pin == ACC_POWER || pin == Battery_POWER || pin == GPS_POWER || pin == LR1110_SPI_MISO_PIN ||
|
pin == ACC_POWER || pin == Battery_POWER || pin == GPS_POWER || pin == LR1110_SPI_MISO_PIN ||
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ build_type = release
|
|||||||
build_flags =
|
build_flags =
|
||||||
-include variants/nrf52840/cpp_overrides/lfs_util.h
|
-include variants/nrf52840/cpp_overrides/lfs_util.h
|
||||||
${arduino_base.build_flags}
|
${arduino_base.build_flags}
|
||||||
-DSERIAL_BUFFER_SIZE=1024
|
|
||||||
-Wno-unused-variable
|
-Wno-unused-variable
|
||||||
-Isrc/platform/nrf52
|
-Isrc/platform/nrf52
|
||||||
-DLFS_NO_ASSERT ; Disable LFS assertions , see https://github.com/meshtastic/firmware/pull/3818
|
-DLFS_NO_ASSERT ; Disable LFS assertions , see https://github.com/meshtastic/firmware/pull/3818
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
[nrf52832_base]
|
[nrf52832_base]
|
||||||
extends = nrf52_base
|
extends = nrf52_base
|
||||||
|
|
||||||
build_flags = ${nrf52_base.build_flags}
|
build_flags =
|
||||||
|
${nrf52_base.build_flags}
|
||||||
|
-DSERIAL_BUFFER_SIZE=1024
|
||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${nrf52_base.lib_deps}
|
${nrf52_base.lib_deps}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
[nrf52840_base]
|
[nrf52840_base]
|
||||||
extends = nrf52_base
|
extends = nrf52_base
|
||||||
|
|
||||||
build_flags = ${nrf52_base.build_flags}
|
build_flags =
|
||||||
|
${nrf52_base.build_flags}
|
||||||
|
-DSERIAL_BUFFER_SIZE=4096
|
||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${nrf52_base.lib_deps}
|
${nrf52_base.lib_deps}
|
||||||
|
|||||||
Reference in New Issue
Block a user