mirror of
https://github.com/meshtastic/firmware.git
synced 2025-12-18 00:32:38 +00:00
Compare commits
48 Commits
refactor-n
...
sfpp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
28058527e0 | ||
|
|
1847271b4f | ||
|
|
a6c7d239d0 | ||
|
|
2691e6cd4b | ||
|
|
ebab74a360 | ||
|
|
f1aefc4eef | ||
|
|
203826374c | ||
|
|
8e0547e76d | ||
|
|
8a48321555 | ||
|
|
6c3315025a | ||
|
|
11c2b67223 | ||
|
|
917794ebab | ||
|
|
ed77ba5612 | ||
|
|
eafa8c7b47 | ||
|
|
aa8bb6c6f1 | ||
|
|
1952982896 | ||
|
|
024ac74f5c | ||
|
|
de2b9632bb | ||
|
|
c2b7dc2641 | ||
|
|
d0d375f1ff | ||
|
|
e8ebfc0513 | ||
|
|
bf32f17f28 | ||
|
|
b74238194b | ||
|
|
5d5819b876 | ||
|
|
f127702bef | ||
|
|
cce8cbfe34 | ||
|
|
a4a6c3509a | ||
|
|
68250dc937 | ||
|
|
c8628b3422 | ||
|
|
2ac74d6677 | ||
|
|
9d487ddc0d | ||
|
|
bcfe069997 | ||
|
|
4fc96bdf83 | ||
|
|
4ef943f204 | ||
|
|
a8fa5f25cb | ||
|
|
3b2a1547de | ||
|
|
6f725a1996 | ||
|
|
467c042bf7 | ||
|
|
cc4c41167c | ||
|
|
fff2bbf4a0 | ||
|
|
fba92229a6 | ||
|
|
ff0a4ea320 | ||
|
|
83b603827c | ||
|
|
ee80ec7b68 | ||
|
|
ec0dfb7337 | ||
|
|
817f3b9ec8 | ||
|
|
0726bb4b56 | ||
|
|
6b11991be0 |
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
|
||||||
|
|||||||
10
.github/workflows/build_firmware.yml
vendored
10
.github/workflows/build_firmware.yml
vendored
@@ -56,19 +56,21 @@ jobs:
|
|||||||
ota_firmware_source: ${{ steps.ota_dir.outputs.src || '' }}
|
ota_firmware_source: ${{ steps.ota_dir.outputs.src || '' }}
|
||||||
ota_firmware_target: ${{ steps.ota_dir.outputs.tgt || '' }}
|
ota_firmware_target: ${{ steps.ota_dir.outputs.tgt || '' }}
|
||||||
|
|
||||||
- name: Echo manifest from release/firmware-*.mt.json to job summary
|
- name: Job summary
|
||||||
if: ${{ always() }}
|
|
||||||
env:
|
env:
|
||||||
PIO_ENV: ${{ inputs.pio_env }}
|
PIO_ENV: ${{ inputs.pio_env }}
|
||||||
run: |
|
run: |
|
||||||
echo "## Manifest: \`$PIO_ENV\`" >> $GITHUB_STEP_SUMMARY
|
echo "## $PIO_ENV" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "<details><summary><strong>Manifest</strong></summary>" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo '' >> $GITHUB_STEP_SUMMARY
|
||||||
echo '```json' >> $GITHUB_STEP_SUMMARY
|
echo '```json' >> $GITHUB_STEP_SUMMARY
|
||||||
cat release/firmware-*.mt.json >> $GITHUB_STEP_SUMMARY
|
cat release/firmware-*.mt.json >> $GITHUB_STEP_SUMMARY
|
||||||
echo '' >> $GITHUB_STEP_SUMMARY
|
echo '' >> $GITHUB_STEP_SUMMARY
|
||||||
echo '```' >> $GITHUB_STEP_SUMMARY
|
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "</details>" >> $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/release_channels.yml
vendored
2
.github/workflows/release_channels.yml
vendored
@@ -102,7 +102,7 @@ jobs:
|
|||||||
PIP_DISABLE_PIP_VERSION_CHECK: 1
|
PIP_DISABLE_PIP_VERSION_CHECK: 1
|
||||||
|
|
||||||
- name: Create Bumps pull request
|
- name: Create Bumps pull request
|
||||||
uses: peter-evans/create-pull-request@v7
|
uses: peter-evans/create-pull-request@v8
|
||||||
with:
|
with:
|
||||||
base: ${{ github.event.repository.default_branch }}
|
base: ${{ github.event.repository.default_branch }}
|
||||||
branch: create-pull-request/bump-version
|
branch: create-pull-request/bump-version
|
||||||
|
|||||||
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
|
||||||
|
|||||||
2
.github/workflows/update_protobufs.yml
vendored
2
.github/workflows/update_protobufs.yml
vendored
@@ -31,7 +31,7 @@ jobs:
|
|||||||
./bin/regen-protos.sh
|
./bin/regen-protos.sh
|
||||||
|
|
||||||
- name: Create pull request
|
- name: Create pull request
|
||||||
uses: peter-evans/create-pull-request@v7
|
uses: peter-evans/create-pull-request@v8
|
||||||
with:
|
with:
|
||||||
branch: create-pull-request/update-protobufs
|
branch: create-pull-request/update-protobufs
|
||||||
labels: submodules
|
labels: submodules
|
||||||
|
|||||||
@@ -9,24 +9,24 @@ plugins:
|
|||||||
lint:
|
lint:
|
||||||
enabled:
|
enabled:
|
||||||
- checkov@3.2.495
|
- checkov@3.2.495
|
||||||
- renovate@42.30.4
|
- renovate@42.57.1
|
||||||
- prettier@3.7.4
|
- prettier@3.7.4
|
||||||
- trufflehog@3.91.2
|
- trufflehog@3.92.3
|
||||||
- yamllint@1.37.1
|
- yamllint@1.37.1
|
||||||
- bandit@1.9.2
|
- bandit@1.9.2
|
||||||
- trivy@0.67.2
|
- trivy@0.68.1
|
||||||
- taplo@0.10.0
|
- taplo@0.10.0
|
||||||
- ruff@0.14.7
|
- ruff@0.14.9
|
||||||
- isort@7.0.0
|
- isort@7.0.0
|
||||||
- markdownlint@0.46.0
|
- markdownlint@0.47.0
|
||||||
- oxipng@9.1.5
|
- oxipng@10.0.0
|
||||||
- svgo@4.0.0
|
- svgo@4.0.0
|
||||||
- actionlint@1.7.9
|
- actionlint@1.7.9
|
||||||
- flake8@7.3.0
|
- flake8@7.3.0
|
||||||
- hadolint@2.14.0
|
- hadolint@2.14.0
|
||||||
- shfmt@3.6.0
|
- shfmt@3.6.0
|
||||||
- shellcheck@0.11.0
|
- shellcheck@0.11.0
|
||||||
- black@25.11.0
|
- black@25.12.0
|
||||||
- git-diff-check
|
- git-diff-check
|
||||||
- gitleaks@8.30.0
|
- gitleaks@8.30.0
|
||||||
- clang-format@16.0.3
|
- clang-format@16.0.3
|
||||||
|
|||||||
@@ -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')}")
|
||||||
|
|||||||
@@ -10,6 +10,12 @@ Import("env")
|
|||||||
platform = env.PioPlatform()
|
platform = env.PioPlatform()
|
||||||
|
|
||||||
sys.path.append(join(platform.get_package_dir("tool-esptoolpy")))
|
sys.path.append(join(platform.get_package_dir("tool-esptoolpy")))
|
||||||
|
# IntelHex workaround, remove after fixed upstream
|
||||||
|
# https://github.com/platformio/platform-espressif32/issues/1632
|
||||||
|
try:
|
||||||
|
import intelhex
|
||||||
|
except ImportError:
|
||||||
|
env.Execute("$PYTHONEXE -m pip install intelhex")
|
||||||
import esptool
|
import esptool
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -532,8 +532,10 @@ void drawSystemScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x
|
|||||||
const int labelX = x;
|
const int labelX = x;
|
||||||
int barsOffset = (isHighResolution) ? 24 : 0;
|
int barsOffset = (isHighResolution) ? 24 : 0;
|
||||||
#ifdef USE_EINK
|
#ifdef USE_EINK
|
||||||
|
#ifndef T_DECK_PRO
|
||||||
barsOffset -= 12;
|
barsOffset -= 12;
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
#if defined(M5STACK_UNITC6L)
|
#if defined(M5STACK_UNITC6L)
|
||||||
const int barX = x + 45 + barsOffset;
|
const int barX = x + 45 + barsOffset;
|
||||||
#else
|
#else
|
||||||
@@ -574,7 +576,7 @@ void drawSystemScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x
|
|||||||
#endif
|
#endif
|
||||||
// Value string
|
// Value string
|
||||||
display->setTextAlignment(TEXT_ALIGN_RIGHT);
|
display->setTextAlignment(TEXT_ALIGN_RIGHT);
|
||||||
display->drawString(SCREEN_WIDTH - 2, getTextPositions(display)[line], combinedStr);
|
display->drawString(SCREEN_WIDTH, getTextPositions(display)[line], combinedStr);
|
||||||
};
|
};
|
||||||
|
|
||||||
// === Memory values ===
|
// === Memory values ===
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -428,10 +428,17 @@ void setup()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ARCH_PORTDUINO
|
#if ARCH_PORTDUINO
|
||||||
|
RTCQuality ourQuality = RTCQualityDevice;
|
||||||
|
|
||||||
|
std::string timeCommandResult = exec("timedatectl status | grep synchronized | grep yes -c");
|
||||||
|
if (timeCommandResult[0] == '1') {
|
||||||
|
ourQuality = RTCQualityNTP;
|
||||||
|
}
|
||||||
|
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
tv.tv_sec = time(NULL);
|
tv.tv_sec = time(NULL);
|
||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
perhapsSetRTC(RTCQualityDevice, &tv);
|
perhapsSetRTC(ourQuality, &tv);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
powerMonInit();
|
powerMonInit();
|
||||||
|
|||||||
@@ -96,6 +96,8 @@ class Channels
|
|||||||
|
|
||||||
bool setDefaultPresetCryptoForHash(ChannelHash channelHash);
|
bool setDefaultPresetCryptoForHash(ChannelHash channelHash);
|
||||||
|
|
||||||
|
int16_t getHash(ChannelIndex i) { return hashes[i]; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/** Given a channel index, change to use the crypto key specified by that index
|
/** Given a channel index, change to use the crypto key specified by that index
|
||||||
*
|
*
|
||||||
@@ -113,8 +115,6 @@ class Channels
|
|||||||
*/
|
*/
|
||||||
int16_t generateHash(ChannelIndex channelNum);
|
int16_t generateHash(ChannelIndex channelNum);
|
||||||
|
|
||||||
int16_t getHash(ChannelIndex i) { return hashes[i]; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate a channel, fixing any errors as needed
|
* Validate a channel, fixing any errors as needed
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -805,11 +805,15 @@ void NodeDB::installDefaultModuleConfig()
|
|||||||
moduleConfig.external_notification.output_ms = 500;
|
moduleConfig.external_notification.output_ms = 500;
|
||||||
moduleConfig.external_notification.nag_timeout = 2;
|
moduleConfig.external_notification.nag_timeout = 2;
|
||||||
#endif
|
#endif
|
||||||
#if defined(RAK4630) || defined(RAK11310) || defined(RAK3312)
|
#if defined(RAK4630) || defined(RAK11310) || defined(RAK3312) || defined(MUZI_BASE)
|
||||||
// Default to RAK led pin 2 (blue)
|
// Default to RAK led pin 2 (blue)
|
||||||
moduleConfig.external_notification.enabled = true;
|
moduleConfig.external_notification.enabled = true;
|
||||||
moduleConfig.external_notification.output = PIN_LED2;
|
moduleConfig.external_notification.output = PIN_LED2;
|
||||||
|
#if defined(MUZI_BASE)
|
||||||
|
moduleConfig.external_notification.active = false;
|
||||||
|
#else
|
||||||
moduleConfig.external_notification.active = true;
|
moduleConfig.external_notification.active = true;
|
||||||
|
#endif
|
||||||
moduleConfig.external_notification.alert_message = true;
|
moduleConfig.external_notification.alert_message = true;
|
||||||
moduleConfig.external_notification.output_ms = 1000;
|
moduleConfig.external_notification.output_ms = 1000;
|
||||||
moduleConfig.external_notification.nag_timeout = default_ringtone_nag_secs;
|
moduleConfig.external_notification.nag_timeout = default_ringtone_nag_secs;
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -688,7 +692,7 @@ void Router::handleReceived(meshtastic_MeshPacket *p, RxSource src)
|
|||||||
|
|
||||||
// Store a copy of encrypted packet for MQTT
|
// Store a copy of encrypted packet for MQTT
|
||||||
DEBUG_HEAP_BEFORE;
|
DEBUG_HEAP_BEFORE;
|
||||||
meshtastic_MeshPacket *p_encrypted = packetPool.allocCopy(*p);
|
p_encrypted = packetPool.allocCopy(*p);
|
||||||
DEBUG_HEAP_AFTER("Router::handleReceived", p_encrypted);
|
DEBUG_HEAP_AFTER("Router::handleReceived", p_encrypted);
|
||||||
|
|
||||||
// Take those raw bytes and convert them back into a well structured protobuf we can understand
|
// Take those raw bytes and convert them back into a well structured protobuf we can understand
|
||||||
|
|||||||
@@ -91,6 +91,9 @@ class Router : protected concurrency::OSThread, protected PacketHistory
|
|||||||
before us */
|
before us */
|
||||||
uint32_t rxDupe = 0, txRelayCanceled = 0;
|
uint32_t rxDupe = 0, txRelayCanceled = 0;
|
||||||
|
|
||||||
|
// pointer to the encrypted packet
|
||||||
|
meshtastic_MeshPacket *p_encrypted;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class RoutingModule;
|
friend class RoutingModule;
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -24,6 +24,9 @@ PB_BIND(meshtastic_Data, meshtastic_Data, 2)
|
|||||||
PB_BIND(meshtastic_KeyVerification, meshtastic_KeyVerification, AUTO)
|
PB_BIND(meshtastic_KeyVerification, meshtastic_KeyVerification, AUTO)
|
||||||
|
|
||||||
|
|
||||||
|
PB_BIND(meshtastic_StoreForwardPlusPlus, meshtastic_StoreForwardPlusPlus, 2)
|
||||||
|
|
||||||
|
|
||||||
PB_BIND(meshtastic_Waypoint, meshtastic_Waypoint, AUTO)
|
PB_BIND(meshtastic_Waypoint, meshtastic_Waypoint, AUTO)
|
||||||
|
|
||||||
|
|
||||||
@@ -121,6 +124,8 @@ PB_BIND(meshtastic_ChunkedPayloadResponse, meshtastic_ChunkedPayloadResponse, AU
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -478,6 +478,17 @@ typedef enum _meshtastic_Routing_Error {
|
|||||||
meshtastic_Routing_Error_RATE_LIMIT_EXCEEDED = 38
|
meshtastic_Routing_Error_RATE_LIMIT_EXCEEDED = 38
|
||||||
} meshtastic_Routing_Error;
|
} meshtastic_Routing_Error;
|
||||||
|
|
||||||
|
/* enum message type? */
|
||||||
|
typedef enum _meshtastic_StoreForwardPlusPlus_SFPP_message_type {
|
||||||
|
/* message hash without chain hash means that no, it is not on the chain */
|
||||||
|
meshtastic_StoreForwardPlusPlus_SFPP_message_type_CANON_ANNOUNCE = 0,
|
||||||
|
meshtastic_StoreForwardPlusPlus_SFPP_message_type_CHAIN_QUERY = 1,
|
||||||
|
meshtastic_StoreForwardPlusPlus_SFPP_message_type_LINK_REQUEST = 3,
|
||||||
|
meshtastic_StoreForwardPlusPlus_SFPP_message_type_LINK_PROVIDE = 4,
|
||||||
|
meshtastic_StoreForwardPlusPlus_SFPP_message_type_LINK_PROVIDE_FIRSTHALF = 5,
|
||||||
|
meshtastic_StoreForwardPlusPlus_SFPP_message_type_LINK_PROVIDE_SECONDHALF = 6
|
||||||
|
} meshtastic_StoreForwardPlusPlus_SFPP_message_type;
|
||||||
|
|
||||||
/* The priority of this message for sending.
|
/* The priority of this message for sending.
|
||||||
Higher priorities are sent first (when managing the transmit queue).
|
Higher priorities are sent first (when managing the transmit queue).
|
||||||
This field is never sent over the air, it is only used internally inside of a local device node.
|
This field is never sent over the air, it is only used internally inside of a local device node.
|
||||||
@@ -782,6 +793,24 @@ typedef struct _meshtastic_KeyVerification {
|
|||||||
meshtastic_KeyVerification_hash2_t hash2;
|
meshtastic_KeyVerification_hash2_t hash2;
|
||||||
} meshtastic_KeyVerification;
|
} meshtastic_KeyVerification;
|
||||||
|
|
||||||
|
typedef PB_BYTES_ARRAY_T(32) meshtastic_StoreForwardPlusPlus_message_hash_t;
|
||||||
|
typedef PB_BYTES_ARRAY_T(32) meshtastic_StoreForwardPlusPlus_commit_hash_t;
|
||||||
|
typedef PB_BYTES_ARRAY_T(32) meshtastic_StoreForwardPlusPlus_root_hash_t;
|
||||||
|
typedef PB_BYTES_ARRAY_T(240) meshtastic_StoreForwardPlusPlus_message_t;
|
||||||
|
/* The actual over-the-mesh message doing store and forward++ */
|
||||||
|
typedef struct _meshtastic_StoreForwardPlusPlus { /* */
|
||||||
|
meshtastic_StoreForwardPlusPlus_SFPP_message_type sfpp_message_type;
|
||||||
|
meshtastic_StoreForwardPlusPlus_message_hash_t message_hash;
|
||||||
|
meshtastic_StoreForwardPlusPlus_commit_hash_t commit_hash;
|
||||||
|
meshtastic_StoreForwardPlusPlus_root_hash_t root_hash;
|
||||||
|
/* encapsulated message to share (may be split in half) */
|
||||||
|
meshtastic_StoreForwardPlusPlus_message_t message;
|
||||||
|
uint32_t encapsulated_id;
|
||||||
|
uint32_t encapsulated_to;
|
||||||
|
uint32_t encapsulated_from;
|
||||||
|
uint32_t encapsulated_rxtime;
|
||||||
|
} meshtastic_StoreForwardPlusPlus;
|
||||||
|
|
||||||
/* Waypoint message, used to share arbitrary locations across the mesh */
|
/* Waypoint message, used to share arbitrary locations across the mesh */
|
||||||
typedef struct _meshtastic_Waypoint {
|
typedef struct _meshtastic_Waypoint {
|
||||||
/* Id of the waypoint */
|
/* Id of the waypoint */
|
||||||
@@ -1310,6 +1339,10 @@ extern "C" {
|
|||||||
#define _meshtastic_Routing_Error_MAX meshtastic_Routing_Error_RATE_LIMIT_EXCEEDED
|
#define _meshtastic_Routing_Error_MAX meshtastic_Routing_Error_RATE_LIMIT_EXCEEDED
|
||||||
#define _meshtastic_Routing_Error_ARRAYSIZE ((meshtastic_Routing_Error)(meshtastic_Routing_Error_RATE_LIMIT_EXCEEDED+1))
|
#define _meshtastic_Routing_Error_ARRAYSIZE ((meshtastic_Routing_Error)(meshtastic_Routing_Error_RATE_LIMIT_EXCEEDED+1))
|
||||||
|
|
||||||
|
#define _meshtastic_StoreForwardPlusPlus_SFPP_message_type_MIN meshtastic_StoreForwardPlusPlus_SFPP_message_type_CANON_ANNOUNCE
|
||||||
|
#define _meshtastic_StoreForwardPlusPlus_SFPP_message_type_MAX meshtastic_StoreForwardPlusPlus_SFPP_message_type_LINK_PROVIDE_SECONDHALF
|
||||||
|
#define _meshtastic_StoreForwardPlusPlus_SFPP_message_type_ARRAYSIZE ((meshtastic_StoreForwardPlusPlus_SFPP_message_type)(meshtastic_StoreForwardPlusPlus_SFPP_message_type_LINK_PROVIDE_SECONDHALF+1))
|
||||||
|
|
||||||
#define _meshtastic_MeshPacket_Priority_MIN meshtastic_MeshPacket_Priority_UNSET
|
#define _meshtastic_MeshPacket_Priority_MIN meshtastic_MeshPacket_Priority_UNSET
|
||||||
#define _meshtastic_MeshPacket_Priority_MAX meshtastic_MeshPacket_Priority_MAX
|
#define _meshtastic_MeshPacket_Priority_MAX meshtastic_MeshPacket_Priority_MAX
|
||||||
#define _meshtastic_MeshPacket_Priority_ARRAYSIZE ((meshtastic_MeshPacket_Priority)(meshtastic_MeshPacket_Priority_MAX+1))
|
#define _meshtastic_MeshPacket_Priority_ARRAYSIZE ((meshtastic_MeshPacket_Priority)(meshtastic_MeshPacket_Priority_MAX+1))
|
||||||
@@ -1338,6 +1371,8 @@ extern "C" {
|
|||||||
#define meshtastic_Data_portnum_ENUMTYPE meshtastic_PortNum
|
#define meshtastic_Data_portnum_ENUMTYPE meshtastic_PortNum
|
||||||
|
|
||||||
|
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_sfpp_message_type_ENUMTYPE meshtastic_StoreForwardPlusPlus_SFPP_message_type
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define meshtastic_MeshPacket_priority_ENUMTYPE meshtastic_MeshPacket_Priority
|
#define meshtastic_MeshPacket_priority_ENUMTYPE meshtastic_MeshPacket_Priority
|
||||||
@@ -1380,6 +1415,7 @@ extern "C" {
|
|||||||
#define meshtastic_Routing_init_default {0, {meshtastic_RouteDiscovery_init_default}}
|
#define meshtastic_Routing_init_default {0, {meshtastic_RouteDiscovery_init_default}}
|
||||||
#define meshtastic_Data_init_default {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0}
|
#define meshtastic_Data_init_default {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0}
|
||||||
#define meshtastic_KeyVerification_init_default {0, {0, {0}}, {0, {0}}}
|
#define meshtastic_KeyVerification_init_default {0, {0, {0}}, {0, {0}}}
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_init_default {_meshtastic_StoreForwardPlusPlus_SFPP_message_type_MIN, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, 0, 0, 0, 0}
|
||||||
#define meshtastic_Waypoint_init_default {0, false, 0, false, 0, 0, 0, "", "", 0}
|
#define meshtastic_Waypoint_init_default {0, false, 0, false, 0, 0, 0, "", "", 0}
|
||||||
#define meshtastic_MqttClientProxyMessage_init_default {"", 0, {{0, {0}}}, 0}
|
#define meshtastic_MqttClientProxyMessage_init_default {"", 0, {{0, {0}}}, 0}
|
||||||
#define meshtastic_MeshPacket_init_default {0, 0, 0, 0, {meshtastic_Data_init_default}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0, 0, 0, 0, _meshtastic_MeshPacket_TransportMechanism_MIN}
|
#define meshtastic_MeshPacket_init_default {0, 0, 0, 0, {meshtastic_Data_init_default}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0, 0, 0, 0, _meshtastic_MeshPacket_TransportMechanism_MIN}
|
||||||
@@ -1411,6 +1447,7 @@ extern "C" {
|
|||||||
#define meshtastic_Routing_init_zero {0, {meshtastic_RouteDiscovery_init_zero}}
|
#define meshtastic_Routing_init_zero {0, {meshtastic_RouteDiscovery_init_zero}}
|
||||||
#define meshtastic_Data_init_zero {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0}
|
#define meshtastic_Data_init_zero {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0}
|
||||||
#define meshtastic_KeyVerification_init_zero {0, {0, {0}}, {0, {0}}}
|
#define meshtastic_KeyVerification_init_zero {0, {0, {0}}, {0, {0}}}
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_init_zero {_meshtastic_StoreForwardPlusPlus_SFPP_message_type_MIN, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, 0, 0, 0, 0}
|
||||||
#define meshtastic_Waypoint_init_zero {0, false, 0, false, 0, 0, 0, "", "", 0}
|
#define meshtastic_Waypoint_init_zero {0, false, 0, false, 0, 0, 0, "", "", 0}
|
||||||
#define meshtastic_MqttClientProxyMessage_init_zero {"", 0, {{0, {0}}}, 0}
|
#define meshtastic_MqttClientProxyMessage_init_zero {"", 0, {{0, {0}}}, 0}
|
||||||
#define meshtastic_MeshPacket_init_zero {0, 0, 0, 0, {meshtastic_Data_init_zero}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0, 0, 0, 0, _meshtastic_MeshPacket_TransportMechanism_MIN}
|
#define meshtastic_MeshPacket_init_zero {0, 0, 0, 0, {meshtastic_Data_init_zero}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0, 0, 0, 0, _meshtastic_MeshPacket_TransportMechanism_MIN}
|
||||||
@@ -1489,6 +1526,15 @@ extern "C" {
|
|||||||
#define meshtastic_KeyVerification_nonce_tag 1
|
#define meshtastic_KeyVerification_nonce_tag 1
|
||||||
#define meshtastic_KeyVerification_hash1_tag 2
|
#define meshtastic_KeyVerification_hash1_tag 2
|
||||||
#define meshtastic_KeyVerification_hash2_tag 3
|
#define meshtastic_KeyVerification_hash2_tag 3
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_sfpp_message_type_tag 1
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_message_hash_tag 2
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_commit_hash_tag 3
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_root_hash_tag 4
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_message_tag 5
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_encapsulated_id_tag 6
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_encapsulated_to_tag 7
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_encapsulated_from_tag 8
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_encapsulated_rxtime_tag 9
|
||||||
#define meshtastic_Waypoint_id_tag 1
|
#define meshtastic_Waypoint_id_tag 1
|
||||||
#define meshtastic_Waypoint_latitude_i_tag 2
|
#define meshtastic_Waypoint_latitude_i_tag 2
|
||||||
#define meshtastic_Waypoint_longitude_i_tag 3
|
#define meshtastic_Waypoint_longitude_i_tag 3
|
||||||
@@ -1705,6 +1751,19 @@ X(a, STATIC, SINGULAR, BYTES, hash2, 3)
|
|||||||
#define meshtastic_KeyVerification_CALLBACK NULL
|
#define meshtastic_KeyVerification_CALLBACK NULL
|
||||||
#define meshtastic_KeyVerification_DEFAULT NULL
|
#define meshtastic_KeyVerification_DEFAULT NULL
|
||||||
|
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_FIELDLIST(X, a) \
|
||||||
|
X(a, STATIC, SINGULAR, UENUM, sfpp_message_type, 1) \
|
||||||
|
X(a, STATIC, SINGULAR, BYTES, message_hash, 2) \
|
||||||
|
X(a, STATIC, SINGULAR, BYTES, commit_hash, 3) \
|
||||||
|
X(a, STATIC, SINGULAR, BYTES, root_hash, 4) \
|
||||||
|
X(a, STATIC, SINGULAR, BYTES, message, 5) \
|
||||||
|
X(a, STATIC, SINGULAR, UINT32, encapsulated_id, 6) \
|
||||||
|
X(a, STATIC, SINGULAR, UINT32, encapsulated_to, 7) \
|
||||||
|
X(a, STATIC, SINGULAR, UINT32, encapsulated_from, 8) \
|
||||||
|
X(a, STATIC, SINGULAR, UINT32, encapsulated_rxtime, 9)
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_CALLBACK NULL
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_DEFAULT NULL
|
||||||
|
|
||||||
#define meshtastic_Waypoint_FIELDLIST(X, a) \
|
#define meshtastic_Waypoint_FIELDLIST(X, a) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, id, 1) \
|
X(a, STATIC, SINGULAR, UINT32, id, 1) \
|
||||||
X(a, STATIC, OPTIONAL, SFIXED32, latitude_i, 2) \
|
X(a, STATIC, OPTIONAL, SFIXED32, latitude_i, 2) \
|
||||||
@@ -1980,6 +2039,7 @@ extern const pb_msgdesc_t meshtastic_RouteDiscovery_msg;
|
|||||||
extern const pb_msgdesc_t meshtastic_Routing_msg;
|
extern const pb_msgdesc_t meshtastic_Routing_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_Data_msg;
|
extern const pb_msgdesc_t meshtastic_Data_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_KeyVerification_msg;
|
extern const pb_msgdesc_t meshtastic_KeyVerification_msg;
|
||||||
|
extern const pb_msgdesc_t meshtastic_StoreForwardPlusPlus_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_Waypoint_msg;
|
extern const pb_msgdesc_t meshtastic_Waypoint_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_MqttClientProxyMessage_msg;
|
extern const pb_msgdesc_t meshtastic_MqttClientProxyMessage_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_MeshPacket_msg;
|
extern const pb_msgdesc_t meshtastic_MeshPacket_msg;
|
||||||
@@ -2013,6 +2073,7 @@ extern const pb_msgdesc_t meshtastic_ChunkedPayloadResponse_msg;
|
|||||||
#define meshtastic_Routing_fields &meshtastic_Routing_msg
|
#define meshtastic_Routing_fields &meshtastic_Routing_msg
|
||||||
#define meshtastic_Data_fields &meshtastic_Data_msg
|
#define meshtastic_Data_fields &meshtastic_Data_msg
|
||||||
#define meshtastic_KeyVerification_fields &meshtastic_KeyVerification_msg
|
#define meshtastic_KeyVerification_fields &meshtastic_KeyVerification_msg
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_fields &meshtastic_StoreForwardPlusPlus_msg
|
||||||
#define meshtastic_Waypoint_fields &meshtastic_Waypoint_msg
|
#define meshtastic_Waypoint_fields &meshtastic_Waypoint_msg
|
||||||
#define meshtastic_MqttClientProxyMessage_fields &meshtastic_MqttClientProxyMessage_msg
|
#define meshtastic_MqttClientProxyMessage_fields &meshtastic_MqttClientProxyMessage_msg
|
||||||
#define meshtastic_MeshPacket_fields &meshtastic_MeshPacket_msg
|
#define meshtastic_MeshPacket_fields &meshtastic_MeshPacket_msg
|
||||||
@@ -2069,6 +2130,7 @@ extern const pb_msgdesc_t meshtastic_ChunkedPayloadResponse_msg;
|
|||||||
#define meshtastic_QueueStatus_size 23
|
#define meshtastic_QueueStatus_size 23
|
||||||
#define meshtastic_RouteDiscovery_size 256
|
#define meshtastic_RouteDiscovery_size 256
|
||||||
#define meshtastic_Routing_size 259
|
#define meshtastic_Routing_size 259
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_size 371
|
||||||
#define meshtastic_ToRadio_size 504
|
#define meshtastic_ToRadio_size 504
|
||||||
#define meshtastic_User_size 115
|
#define meshtastic_User_size 115
|
||||||
#define meshtastic_Waypoint_size 165
|
#define meshtastic_Waypoint_size 165
|
||||||
|
|||||||
@@ -86,6 +86,9 @@ typedef enum _meshtastic_PortNum {
|
|||||||
/* Paxcounter lib included in the firmware
|
/* Paxcounter lib included in the firmware
|
||||||
ENCODING: protobuf */
|
ENCODING: protobuf */
|
||||||
meshtastic_PortNum_PAXCOUNTER_APP = 34,
|
meshtastic_PortNum_PAXCOUNTER_APP = 34,
|
||||||
|
/* Store and Forward++ module included in the firmware
|
||||||
|
ENCODING: protobuf */
|
||||||
|
meshtastic_PortNum_STORE_FORWARD_PLUSPLUS_APP = 35,
|
||||||
/* Provides a hardware serial interface to send and receive from the Meshtastic network.
|
/* Provides a hardware serial interface to send and receive from the Meshtastic network.
|
||||||
Connect to the RX/TX pins of a device with 38400 8N1. Packets received from the Meshtastic
|
Connect to the RX/TX pins of a device with 38400 8N1. Packets received from the Meshtastic
|
||||||
network is forwarded to the RX pin while sending a packet to TX will go out to the Mesh network.
|
network is forwarded to the RX pin while sending a packet to TX will go out to the Mesh network.
|
||||||
|
|||||||
@@ -417,6 +417,9 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
|
|||||||
}
|
}
|
||||||
case meshtastic_AdminMessage_enter_dfu_mode_request_tag: {
|
case meshtastic_AdminMessage_enter_dfu_mode_request_tag: {
|
||||||
LOG_INFO("Client requesting to enter DFU mode");
|
LOG_INFO("Client requesting to enter DFU mode");
|
||||||
|
#if HAS_SCREEN
|
||||||
|
IF_SCREEN(screen->showSimpleBanner("Device is rebooting\ninto DFU mode.", 0));
|
||||||
|
#endif
|
||||||
#if defined(ARCH_NRF52) || defined(ARCH_RP2040)
|
#if defined(ARCH_NRF52) || defined(ARCH_RP2040)
|
||||||
enterDfuMode();
|
enterDfuMode();
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -61,6 +61,7 @@
|
|||||||
#if ARCH_PORTDUINO
|
#if ARCH_PORTDUINO
|
||||||
#include "input/LinuxInputImpl.h"
|
#include "input/LinuxInputImpl.h"
|
||||||
#include "input/SeesawRotary.h"
|
#include "input/SeesawRotary.h"
|
||||||
|
#include "modules/Native/StoreForwardPlusPlus.h"
|
||||||
#include "modules/Telemetry/HostMetrics.h"
|
#include "modules/Telemetry/HostMetrics.h"
|
||||||
#if !MESHTASTIC_EXCLUDE_STOREFORWARD
|
#if !MESHTASTIC_EXCLUDE_STOREFORWARD
|
||||||
#include "modules/StoreForwardModule.h"
|
#include "modules/StoreForwardModule.h"
|
||||||
@@ -217,7 +218,7 @@ void setupModules()
|
|||||||
}
|
}
|
||||||
#endif // HAS_BUTTON
|
#endif // HAS_BUTTON
|
||||||
#if ARCH_PORTDUINO
|
#if ARCH_PORTDUINO
|
||||||
if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR) {
|
if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR && portduino_config.i2cdev != "") {
|
||||||
seesawRotary = new SeesawRotary("SeesawRotary");
|
seesawRotary = new SeesawRotary("SeesawRotary");
|
||||||
if (!seesawRotary->init()) {
|
if (!seesawRotary->init()) {
|
||||||
delete seesawRotary;
|
delete seesawRotary;
|
||||||
@@ -243,6 +244,7 @@ void setupModules()
|
|||||||
#endif
|
#endif
|
||||||
#if ARCH_PORTDUINO
|
#if ARCH_PORTDUINO
|
||||||
new HostMetricsModule();
|
new HostMetricsModule();
|
||||||
|
new StoreForwardPlusPlusModule();
|
||||||
#endif
|
#endif
|
||||||
#if HAS_TELEMETRY
|
#if HAS_TELEMETRY
|
||||||
new DeviceTelemetryModule();
|
new DeviceTelemetryModule();
|
||||||
|
|||||||
976
src/modules/Native/StoreForwardPlusPlus.cpp
Normal file
976
src/modules/Native/StoreForwardPlusPlus.cpp
Normal file
@@ -0,0 +1,976 @@
|
|||||||
|
// I've done a lot of this in SQLite for now, but honestly it needs to happen in memory, and get saved to sqlite during downtime
|
||||||
|
|
||||||
|
// TODO: Put some channel usage limits on this: Should be limited to 25% utilization, for instance
|
||||||
|
|
||||||
|
// TODO: custom hops. 1 maybe 0
|
||||||
|
|
||||||
|
// TODO: non-stratum0 nodes need to be pointed at their upstream source? Maybe
|
||||||
|
|
||||||
|
// TODO: Work without sending some of the hashes/ short hashes
|
||||||
|
|
||||||
|
// things may get weird if there are multiple stratum-0 nodes on a single mesh. Come up with mitigations
|
||||||
|
|
||||||
|
// Basic design:
|
||||||
|
// This module watches a channel for text messages.
|
||||||
|
// each message gets sha256 summed, and then appended to a git-style blockchain. Probably need a counter, too
|
||||||
|
// then the message, metadata, hash, and git hash information are saved. sqlite?
|
||||||
|
|
||||||
|
// nodes/sub-controllers can subscribe to a database
|
||||||
|
|
||||||
|
// A node can DM the controller, querying if a single message is on the chain, or asking for the last message hash
|
||||||
|
|
||||||
|
// if the message is not on the chain, the node can resend the message
|
||||||
|
|
||||||
|
// if the node lacks messages, it can request them
|
||||||
|
|
||||||
|
// will need the concept of sub-controllers, that subscribe to the central controller, can help push updates
|
||||||
|
|
||||||
|
// catch-up messages only go out when the mesh is low use %
|
||||||
|
|
||||||
|
// Normal firmware will only attempt to sync the chain a few times, then just ask for the latest few messages. A phone app can try
|
||||||
|
// harder
|
||||||
|
|
||||||
|
// host will periodically advertise its presence
|
||||||
|
|
||||||
|
// at least initially, there can only be one authoritative host
|
||||||
|
|
||||||
|
// message objects get a hash value
|
||||||
|
// the message chain gets a commit hash
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "StoreForwardPlusPlus.h"
|
||||||
|
#include "MeshService.h"
|
||||||
|
#include "RTC.h"
|
||||||
|
#include "SHA256.h"
|
||||||
|
#include "meshUtils.h"
|
||||||
|
#include "modules/RoutingModule.h"
|
||||||
|
|
||||||
|
StoreForwardPlusPlusModule::StoreForwardPlusPlusModule()
|
||||||
|
: ProtobufModule("StoreForwardpp", meshtastic_PortNum_STORE_FORWARD_PLUSPLUS_APP, &meshtastic_StoreForwardPlusPlus_msg),
|
||||||
|
concurrency::OSThread("StoreForwardpp")
|
||||||
|
{
|
||||||
|
LOG_WARN("StoreForwardPlusPlusModule init");
|
||||||
|
|
||||||
|
if (portduino_config.sfpp_stratum0)
|
||||||
|
LOG_WARN("SF++ stratum0");
|
||||||
|
|
||||||
|
int res = sqlite3_open("test.db", &ppDb);
|
||||||
|
LOG_WARN("Result1 %u", res);
|
||||||
|
|
||||||
|
char *err = nullptr;
|
||||||
|
|
||||||
|
res = sqlite3_exec(ppDb, " \
|
||||||
|
CREATE TABLE channel_messages( \
|
||||||
|
destination INT NOT NULL, \
|
||||||
|
sender INT NOT NULL, \
|
||||||
|
packet_id INT NOT NULL, \
|
||||||
|
rx_time INT NOT NULL, \
|
||||||
|
root_hash BLOB NOT NULL, \
|
||||||
|
encrypted_bytes BLOB NOT NULL, \
|
||||||
|
message_hash BLOB NOT NULL, \
|
||||||
|
commit_hash BLOB NOT NULL, \
|
||||||
|
payload TEXT, \
|
||||||
|
PRIMARY KEY (message_hash) \
|
||||||
|
);",
|
||||||
|
NULL, NULL, &err);
|
||||||
|
LOG_WARN("Result2 %u", res);
|
||||||
|
if (err != nullptr)
|
||||||
|
LOG_ERROR("%s", err);
|
||||||
|
sqlite3_free(err);
|
||||||
|
|
||||||
|
res = sqlite3_exec(ppDb, " \
|
||||||
|
CREATE TABLE local_messages( \
|
||||||
|
destination INT NOT NULL, \
|
||||||
|
sender INT NOT NULL, \
|
||||||
|
packet_id INT NOT NULL, \
|
||||||
|
rx_time INT NOT NULL, \
|
||||||
|
channel_hash INT NOT NULL, \
|
||||||
|
encrypted_bytes BLOB NOT NULL, \
|
||||||
|
message_hash BLOB NOT NULL, \
|
||||||
|
payload TEXT, \
|
||||||
|
PRIMARY KEY (message_hash) \
|
||||||
|
);",
|
||||||
|
NULL, NULL, &err);
|
||||||
|
LOG_WARN("Result2 %u", res);
|
||||||
|
if (err != nullptr)
|
||||||
|
LOG_ERROR("%s", err);
|
||||||
|
sqlite3_free(err);
|
||||||
|
|
||||||
|
// create table DMs
|
||||||
|
res = sqlite3_exec(ppDb, " \
|
||||||
|
CREATE TABLE direct_messages( \
|
||||||
|
destination INT NOT NULL, \
|
||||||
|
sender INT NOT NULL, \
|
||||||
|
packet_id INT NOT NULL, \
|
||||||
|
rx_time INT NOT NULL, \
|
||||||
|
channel_hash INT NOT NULL, \
|
||||||
|
commit_hash BLOB NOT NULL, \
|
||||||
|
encrypted_bytes BLOB NOT NULL, \
|
||||||
|
message_hash BLOB NOT NULL, \
|
||||||
|
payload TEXT, \
|
||||||
|
PRIMARY KEY (message_hash) \
|
||||||
|
);",
|
||||||
|
NULL, NULL, &err);
|
||||||
|
LOG_WARN("Result2 %u", res);
|
||||||
|
if (err != nullptr)
|
||||||
|
LOG_ERROR("%s", err);
|
||||||
|
sqlite3_free(err);
|
||||||
|
|
||||||
|
// mappings table -- connects the root hashes to channel hashes and DM identifiers
|
||||||
|
res = sqlite3_exec(ppDb, " \
|
||||||
|
CREATE TABLE mappings( \
|
||||||
|
chain_type INT NOT NULL, \
|
||||||
|
identifier INT NOT NULL, \
|
||||||
|
root_hash BLOB NOT NULL, \
|
||||||
|
PRIMARY KEY (identifier) \
|
||||||
|
);",
|
||||||
|
NULL, NULL, &err);
|
||||||
|
LOG_WARN("Result2 %u", res);
|
||||||
|
if (err != nullptr)
|
||||||
|
LOG_ERROR("%s", err);
|
||||||
|
sqlite3_free(err);
|
||||||
|
|
||||||
|
// store schema version somewhere
|
||||||
|
|
||||||
|
// prepared statements *should* make this faster.
|
||||||
|
sqlite3_prepare_v2(ppDb, "INSERT INTO channel_messages (destination, sender, packet_id, root_hash, \
|
||||||
|
encrypted_bytes, message_hash, rx_time, commit_hash, payload) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?);",
|
||||||
|
-1, &chain_insert_stmt, NULL);
|
||||||
|
|
||||||
|
sqlite3_prepare_v2(ppDb, "INSERT INTO local_messages (destination, sender, packet_id, channel_hash, \
|
||||||
|
encrypted_bytes, message_hash, rx_time, payload) VALUES(?, ?, ?, ?, ?, ?, ?, ?);",
|
||||||
|
-1, &scratch_insert_stmt, NULL);
|
||||||
|
|
||||||
|
sqlite3_prepare_v2(ppDb, "select destination, sender, packet_id, encrypted_bytes, message_hash, rx_time, channel_hash \
|
||||||
|
from local_messages where channel_hash=? order by rx_time asc LIMIT 1;", // earliest first
|
||||||
|
-1, &fromScratchStmt, NULL);
|
||||||
|
|
||||||
|
sqlite3_prepare_v2(ppDb,
|
||||||
|
"select destination, sender, packet_id, encrypted_bytes, message_hash, rx_time, channel_hash, payload \
|
||||||
|
from local_messages where message_hash=? order by rx_time asc LIMIT 1;", // earliest first
|
||||||
|
-1, &fromScratchByHashStmt, NULL);
|
||||||
|
|
||||||
|
sqlite3_prepare_v2(ppDb, "SELECT COUNT(*) from channel_messages where message_hash=?", -1, &checkDup, NULL);
|
||||||
|
|
||||||
|
sqlite3_prepare_v2(ppDb, "SELECT COUNT(*) from local_messages where message_hash=?", -1, &checkScratch, NULL);
|
||||||
|
|
||||||
|
sqlite3_prepare_v2(ppDb, "DELETE from local_messages where message_hash=?", -1, &removeScratch, NULL);
|
||||||
|
|
||||||
|
sqlite3_prepare_v2(ppDb, "UPDATE channel_messages SET payload=? WHERE message_hash=?", -1, &updatePayloadStmt, NULL);
|
||||||
|
|
||||||
|
sqlite3_prepare_v2(ppDb, "select commit_hash from channel_messages where root_hash=? order by rowid ASC;", -1,
|
||||||
|
&getNextHashStmt, NULL);
|
||||||
|
|
||||||
|
sqlite3_prepare_v2(
|
||||||
|
ppDb, "select commit_hash, message_hash, rx_time from channel_messages where root_hash=? order by rowid desc LIMIT 1;",
|
||||||
|
-1, &getChainEndStmt, NULL);
|
||||||
|
|
||||||
|
sqlite3_prepare_v2(ppDb, "select destination, sender, packet_id, encrypted_bytes, message_hash, rx_time \
|
||||||
|
from channel_messages where commit_hash=?;",
|
||||||
|
-1, &getLinkStmt, NULL);
|
||||||
|
encryptedOk = true;
|
||||||
|
|
||||||
|
// wait about 15 seconds after boot for the first runOnce()
|
||||||
|
// TODO: When not doing active development, adjust this to a longer time
|
||||||
|
this->setInterval(15 * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t StoreForwardPlusPlusModule::runOnce()
|
||||||
|
{
|
||||||
|
LOG_WARN("StoreForward++ runONce");
|
||||||
|
if (getRTCQuality() < RTCQualityNTP) {
|
||||||
|
LOG_WARN("StoreForward++ deferred due to time quality %u", getRTCQuality());
|
||||||
|
return 5 * 60 * 1000;
|
||||||
|
}
|
||||||
|
uint8_t root_hash_bytes[32] = {0};
|
||||||
|
ChannelHash hash = channels.getHash(0);
|
||||||
|
getOrAddRootFromChannelHash(hash, root_hash_bytes);
|
||||||
|
|
||||||
|
// get tip of chain for this channel
|
||||||
|
uint8_t last_message_commit_hash[32] = {0};
|
||||||
|
uint8_t last_message_hash[32] = {0};
|
||||||
|
uint32_t chain_end_rx_time = getChainEnd(hash, last_message_commit_hash, last_message_hash);
|
||||||
|
if (chain_end_rx_time == 0) {
|
||||||
|
LOG_WARN("Store and Forward++ database lookup returned null");
|
||||||
|
return 60 * 60 * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
// broadcast the tip of the chain
|
||||||
|
canonAnnounce(last_message_hash, last_message_commit_hash, root_hash_bytes, chain_end_rx_time);
|
||||||
|
|
||||||
|
// eventually timeout things on the scratch queue
|
||||||
|
return 60 * 60 * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StoreForwardPlusPlusModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_StoreForwardPlusPlus *t)
|
||||||
|
{
|
||||||
|
LOG_WARN("in handleReceivedProtobuf");
|
||||||
|
LOG_WARN("Sfp++ node %u sent us sf++ packet", mp.from);
|
||||||
|
printBytes("commit_hash ", t->commit_hash.bytes, t->commit_hash.size);
|
||||||
|
printBytes("root_hash ", t->root_hash.bytes, t->root_hash.size);
|
||||||
|
|
||||||
|
if (t->sfpp_message_type == meshtastic_StoreForwardPlusPlus_SFPP_message_type_CANON_ANNOUNCE) {
|
||||||
|
// check commit_hash.size
|
||||||
|
|
||||||
|
if (portduino_config.sfpp_stratum0) {
|
||||||
|
LOG_WARN("Received a CANON_ANNOUNCE while stratum 0");
|
||||||
|
uint8_t next_commit_hash[32] = {0};
|
||||||
|
|
||||||
|
if (getNextHash(t->root_hash.bytes, t->commit_hash.bytes, next_commit_hash)) {
|
||||||
|
printBytes("next chain hash: ", next_commit_hash, 32);
|
||||||
|
|
||||||
|
broadcastLink(next_commit_hash, t->root_hash.bytes);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
uint8_t tmp_root_hash_bytes[32] = {0};
|
||||||
|
|
||||||
|
LOG_WARN("Received a CANON_ANNOUNCE");
|
||||||
|
if (getRootFromChannelHash(router->p_encrypted->channel, tmp_root_hash_bytes)) {
|
||||||
|
// we found the hash, check if it's the right one
|
||||||
|
if (memcmp(tmp_root_hash_bytes, t->root_hash.bytes, 32) != 0) {
|
||||||
|
LOG_WARN("Found root hash, and it doesn't match!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
addRootToMappings(router->p_encrypted->channel, t->root_hash.bytes);
|
||||||
|
LOG_WARN("Adding root hash to mappings");
|
||||||
|
}
|
||||||
|
|
||||||
|
// get tip of chain for this channel
|
||||||
|
uint8_t last_message_commit_hash[32] = {0};
|
||||||
|
uint8_t last_message_hash[32] = {0};
|
||||||
|
|
||||||
|
// get chain tip
|
||||||
|
if (getChainEnd(router->p_encrypted->channel, last_message_commit_hash, last_message_hash)) {
|
||||||
|
if (memcmp(last_message_commit_hash, t->commit_hash.bytes, 32) == 0) {
|
||||||
|
LOG_WARN("End of chain matches!");
|
||||||
|
sendFromScratch(router->p_encrypted->channel);
|
||||||
|
// TODO: Send a message from the local queue
|
||||||
|
} else {
|
||||||
|
("End of chain does not match!");
|
||||||
|
|
||||||
|
// We just got an end of chain announce, checking if we have seen this message and have it in scratch.
|
||||||
|
if (isInScratch(t->message_hash.bytes)) {
|
||||||
|
link_object scratch_object = getFromScratch(t->message_hash.bytes, t->message_hash.size);
|
||||||
|
// if this matches, we don't need to request the message
|
||||||
|
// we know exactly what it is
|
||||||
|
if (checkCommitHash(scratch_object, t->commit_hash.bytes, t->message_hash.size)) {
|
||||||
|
scratch_object.has_commit_hash = true;
|
||||||
|
memcpy(scratch_object.commit_hash, t->commit_hash.bytes, 32);
|
||||||
|
|
||||||
|
addToChain(scratch_object);
|
||||||
|
removeFromScratch(t->message_hash.bytes);
|
||||||
|
// short circuit and return
|
||||||
|
// falls through to a request for the message
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
requestNextMessage(t->root_hash.bytes, last_message_commit_hash);
|
||||||
|
}
|
||||||
|
} else { // if chainEnd()
|
||||||
|
LOG_WARN("No Messages on this chain, request!");
|
||||||
|
requestNextMessage(t->root_hash.bytes, t->root_hash.bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (t->sfpp_message_type == meshtastic_StoreForwardPlusPlus_SFPP_message_type_LINK_REQUEST) {
|
||||||
|
uint8_t next_commit_hash[32] = {0};
|
||||||
|
|
||||||
|
LOG_WARN("Received link request");
|
||||||
|
if (getNextHash(t->root_hash.bytes, t->commit_hash.bytes, next_commit_hash)) {
|
||||||
|
printBytes("next chain hash: ", next_commit_hash, 32);
|
||||||
|
|
||||||
|
broadcastLink(next_commit_hash, t->root_hash.bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if root and chain hashes are the same, grab the first message on the chain
|
||||||
|
// if different, get the message directly after.
|
||||||
|
// check if the root
|
||||||
|
|
||||||
|
} else if (t->sfpp_message_type == meshtastic_StoreForwardPlusPlus_SFPP_message_type_LINK_PROVIDE) {
|
||||||
|
LOG_WARN("Link Provide received!");
|
||||||
|
// TODO: Check for root hash in mappings
|
||||||
|
|
||||||
|
link_object incoming_link = ingestLinkMessage(t);
|
||||||
|
|
||||||
|
if (portduino_config.sfpp_stratum0) {
|
||||||
|
if (isInDB(incoming_link.message_hash)) {
|
||||||
|
LOG_WARN("Received link already in chain");
|
||||||
|
// TODO: respond with last link?
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!getRootFromChannelHash(router->p_encrypted->channel, incoming_link.root_hash)) {
|
||||||
|
LOG_WARN("Hash bytes not found for incoming link");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate the commit_hash
|
||||||
|
addToChain(incoming_link);
|
||||||
|
// not super thrilled about doing two broadcasts. Maybe just schedule the canonAnnounce?
|
||||||
|
canonAnnounce(incoming_link.message_hash, incoming_link.commit_hash, incoming_link.root_hash, incoming_link.rx_time);
|
||||||
|
rebroadcastLinkObject(incoming_link);
|
||||||
|
} else {
|
||||||
|
addToChain(incoming_link);
|
||||||
|
if (isInScratch(incoming_link.message_hash)) {
|
||||||
|
link_object scratch_object = getFromScratch(incoming_link.message_hash, 32);
|
||||||
|
if (scratch_object.payload != "") {
|
||||||
|
updatePayload(incoming_link.message_hash, scratch_object.payload);
|
||||||
|
}
|
||||||
|
removeFromScratch(incoming_link.message_hash);
|
||||||
|
} else {
|
||||||
|
// TODO: compare the time, and don't rebroadcast really old messages
|
||||||
|
// if this packet is new to us, we rebroadcast it
|
||||||
|
LOG_WARN("Attempting to Rebroadcast2");
|
||||||
|
rebroadcastLinkObject(incoming_link);
|
||||||
|
}
|
||||||
|
requestNextMessage(t->root_hash.bytes, t->commit_hash.bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessMessage StoreForwardPlusPlusModule::handleReceived(const meshtastic_MeshPacket &mp)
|
||||||
|
{
|
||||||
|
// To avoid terrible time problems, require NTP or GPS time
|
||||||
|
if (getRTCQuality() < RTCQualityNTP) {
|
||||||
|
return ProcessMessage::CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For the moment, this is strictly LoRa
|
||||||
|
if (mp.transport_mechanism != meshtastic_MeshPacket_TransportMechanism_TRANSPORT_LORA) {
|
||||||
|
return ProcessMessage::CONTINUE; // Let others look at this message also if they want
|
||||||
|
}
|
||||||
|
|
||||||
|
// will eventually host DMs and other undecodable messages
|
||||||
|
if (mp.which_payload_variant != meshtastic_MeshPacket_decoded_tag) {
|
||||||
|
return ProcessMessage::CONTINUE; // Let others look at this message also if they want
|
||||||
|
}
|
||||||
|
LOG_WARN("in handleReceived");
|
||||||
|
if (mp.decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP && mp.to == NODENUM_BROADCAST) {
|
||||||
|
link_object lo = ingestTextPacket(mp, router->p_encrypted);
|
||||||
|
|
||||||
|
if (isInDB(lo.message_hash)) {
|
||||||
|
LOG_WARN("found message in db");
|
||||||
|
// We may have this message already, but we may not have the payload
|
||||||
|
// if we do, we can update the payload in the database
|
||||||
|
if (lo.payload != "")
|
||||||
|
updatePayload(lo.message_hash, lo.payload);
|
||||||
|
return ProcessMessage::CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!portduino_config.sfpp_stratum0) {
|
||||||
|
if (!isInDB(lo.message_hash)) {
|
||||||
|
addToScratch(lo);
|
||||||
|
LOG_WARN("added message to scratch");
|
||||||
|
// send link to upstream?
|
||||||
|
}
|
||||||
|
return ProcessMessage::CONTINUE;
|
||||||
|
}
|
||||||
|
addToChain(lo);
|
||||||
|
|
||||||
|
// TODO: Limit to 25% bandwidth
|
||||||
|
canonAnnounce(lo.message_hash, lo.commit_hash, lo.root_hash, lo.rx_time);
|
||||||
|
return ProcessMessage::CONTINUE; // Let others look at this message also if they want
|
||||||
|
} else if (mp.decoded.portnum == meshtastic_PortNum_STORE_FORWARD_PLUSPLUS_APP) {
|
||||||
|
LOG_WARN("Got a STORE_FORWARD++ packet");
|
||||||
|
meshtastic_StoreForwardPlusPlus scratch;
|
||||||
|
pb_decode_from_bytes(mp.decoded.payload.bytes, mp.decoded.payload.size, meshtastic_StoreForwardPlusPlus_fields, &scratch);
|
||||||
|
handleReceivedProtobuf(mp, &scratch);
|
||||||
|
return ProcessMessage::CONTINUE;
|
||||||
|
}
|
||||||
|
return ProcessMessage::CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StoreForwardPlusPlusModule::getRootFromChannelHash(ChannelHash _ch_hash, uint8_t *_root_hash)
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
sqlite3_stmt *getHash;
|
||||||
|
int rc = sqlite3_prepare_v2(ppDb, "select root_hash from mappings where identifier=?;", -1, &getHash, NULL);
|
||||||
|
sqlite3_bind_int(getHash, 1, _ch_hash);
|
||||||
|
sqlite3_step(getHash);
|
||||||
|
uint8_t *tmp_root_hash = (uint8_t *)sqlite3_column_blob(getHash, 0);
|
||||||
|
if (tmp_root_hash) {
|
||||||
|
LOG_WARN("Found root hash!");
|
||||||
|
memcpy(_root_hash, tmp_root_hash, 32);
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
sqlite3_finalize(getHash);
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChannelHash StoreForwardPlusPlusModule::getChannelHashFromRoot(uint8_t *_root_hash)
|
||||||
|
{
|
||||||
|
sqlite3_stmt *getHash;
|
||||||
|
int rc = sqlite3_prepare_v2(ppDb, "select identifier from mappings where root_hash=?;", -1, &getHash, NULL);
|
||||||
|
sqlite3_bind_blob(getHash, 1, _root_hash, 32, NULL);
|
||||||
|
sqlite3_step(getHash);
|
||||||
|
ChannelHash tmp_hash = (ChannelHash)sqlite3_column_int(getHash, 0);
|
||||||
|
sqlite3_finalize(getHash);
|
||||||
|
return tmp_hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return code indicates newly created chain
|
||||||
|
bool StoreForwardPlusPlusModule::getOrAddRootFromChannelHash(ChannelHash _ch_hash, uint8_t *_root_hash)
|
||||||
|
{
|
||||||
|
LOG_WARN("getOrAddRootFromChannelHash()");
|
||||||
|
bool isNew = !getRootFromChannelHash(_ch_hash, _root_hash);
|
||||||
|
|
||||||
|
if (isNew) {
|
||||||
|
if (portduino_config.sfpp_stratum0) {
|
||||||
|
LOG_WARN("Generating Root hash!");
|
||||||
|
// generate root hash
|
||||||
|
SHA256 commit_hash;
|
||||||
|
commit_hash.update(&_ch_hash, sizeof(_ch_hash));
|
||||||
|
NodeNum ourNode = nodeDB->getNodeNum();
|
||||||
|
commit_hash.update(&ourNode, sizeof(ourNode));
|
||||||
|
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice, true);
|
||||||
|
commit_hash.update(&rtc_sec, sizeof(rtc_sec));
|
||||||
|
commit_hash.finalize(_root_hash, 32);
|
||||||
|
addRootToMappings(_ch_hash, _root_hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return isNew;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StoreForwardPlusPlusModule::addRootToMappings(ChannelHash _ch_hash, uint8_t *_root_hash)
|
||||||
|
{
|
||||||
|
LOG_WARN("addRootToMappings()");
|
||||||
|
printBytes("_root_hash", _root_hash, 32);
|
||||||
|
sqlite3_stmt *getHash;
|
||||||
|
|
||||||
|
// write to the table
|
||||||
|
int rc =
|
||||||
|
sqlite3_prepare_v2(ppDb, "INSERT INTO mappings (chain_type, identifier, root_hash) VALUES(?, ?, ?);", -1, &getHash, NULL);
|
||||||
|
LOG_WARN("%d", rc);
|
||||||
|
int type = chain_types::channel_chain;
|
||||||
|
// note, must be an int variable
|
||||||
|
|
||||||
|
sqlite3_bind_int(getHash, 1, type);
|
||||||
|
sqlite3_bind_int(getHash, 2, _ch_hash);
|
||||||
|
sqlite3_bind_blob(getHash, 3, _root_hash, 32, NULL);
|
||||||
|
// sqlite3_bind_int(getHash, 4, nodeToAdd);
|
||||||
|
rc = sqlite3_step(getHash);
|
||||||
|
LOG_WARN("result %u, %s", rc, sqlite3_errmsg(ppDb));
|
||||||
|
sqlite3_finalize(getHash);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t StoreForwardPlusPlusModule::getChainEnd(ChannelHash _ch_hash, uint8_t *_commit_hash, uint8_t *_message_hash)
|
||||||
|
{
|
||||||
|
LOG_WARN("getChainEnd");
|
||||||
|
uint8_t _root_hash[32] = {0};
|
||||||
|
if (!getRootFromChannelHash(_ch_hash, _root_hash)) {
|
||||||
|
LOG_WARN("No root hash found for channel %u", _ch_hash);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rc;
|
||||||
|
sqlite3_bind_blob(getChainEndStmt, 1, _root_hash, 32, NULL);
|
||||||
|
sqlite3_step(getChainEndStmt);
|
||||||
|
uint8_t *last_message_commit_hash = (uint8_t *)sqlite3_column_blob(getChainEndStmt, 0);
|
||||||
|
uint8_t *last_message_hash = (uint8_t *)sqlite3_column_blob(getChainEndStmt, 1);
|
||||||
|
uint32_t _rx_time = sqlite3_column_int(getChainEndStmt, 2);
|
||||||
|
if (last_message_commit_hash != nullptr) {
|
||||||
|
memcpy(_commit_hash, last_message_commit_hash, 32);
|
||||||
|
}
|
||||||
|
if (last_message_hash != nullptr) {
|
||||||
|
memcpy(_message_hash, last_message_hash, 32);
|
||||||
|
}
|
||||||
|
if (last_message_commit_hash == nullptr || last_message_hash == nullptr) {
|
||||||
|
LOG_WARN("Store and Forward++ database lookup returned null");
|
||||||
|
sqlite3_reset(getChainEndStmt);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
sqlite3_reset(getChainEndStmt);
|
||||||
|
return _rx_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoreForwardPlusPlusModule::requestNextMessage(uint8_t *_root_hash, uint8_t *_commit_hash)
|
||||||
|
{
|
||||||
|
|
||||||
|
meshtastic_StoreForwardPlusPlus storeforward = meshtastic_StoreForwardPlusPlus_init_zero;
|
||||||
|
storeforward.sfpp_message_type = meshtastic_StoreForwardPlusPlus_SFPP_message_type_LINK_REQUEST;
|
||||||
|
// set root hash
|
||||||
|
|
||||||
|
// set chain hash
|
||||||
|
storeforward.commit_hash.size = 32;
|
||||||
|
memcpy(storeforward.commit_hash.bytes, _commit_hash, 32);
|
||||||
|
|
||||||
|
// set root hash
|
||||||
|
storeforward.root_hash.size = 32;
|
||||||
|
memcpy(storeforward.root_hash.bytes, _root_hash, 32);
|
||||||
|
|
||||||
|
// storeforward.
|
||||||
|
meshtastic_MeshPacket *p = allocDataProtobuf(storeforward);
|
||||||
|
p->to = NODENUM_BROADCAST;
|
||||||
|
p->decoded.want_response = false;
|
||||||
|
p->priority = meshtastic_MeshPacket_Priority_BACKGROUND;
|
||||||
|
p->channel = 0;
|
||||||
|
LOG_INFO("Send packet to mesh");
|
||||||
|
service->sendToMesh(p, RX_SRC_LOCAL, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StoreForwardPlusPlusModule::getNextHash(uint8_t *_root_hash, uint8_t *_commit_hash, uint8_t *next_commit_hash)
|
||||||
|
{
|
||||||
|
LOG_WARN("getNextHash");
|
||||||
|
|
||||||
|
ChannelHash _channel_hash = getChannelHashFromRoot(_root_hash);
|
||||||
|
LOG_WARN("_channel_hash %u", _channel_hash);
|
||||||
|
|
||||||
|
int rc;
|
||||||
|
sqlite3_bind_blob(getNextHashStmt, 1, _root_hash, 32, NULL);
|
||||||
|
|
||||||
|
bool next_hash = false;
|
||||||
|
|
||||||
|
// asking for the first entry on the chain
|
||||||
|
if (memcmp(_root_hash, _commit_hash, 32) == 0) {
|
||||||
|
rc = sqlite3_step(getNextHashStmt);
|
||||||
|
if (rc != SQLITE_OK) {
|
||||||
|
LOG_WARN("here2 %u, %s", rc, sqlite3_errmsg(ppDb));
|
||||||
|
}
|
||||||
|
uint8_t *tmp_commit_hash = (uint8_t *)sqlite3_column_blob(getNextHashStmt, 0);
|
||||||
|
printBytes("commit_hash", tmp_commit_hash, 32);
|
||||||
|
memcpy(next_commit_hash, tmp_commit_hash, 32);
|
||||||
|
next_hash = true;
|
||||||
|
} else {
|
||||||
|
bool found_hash = false;
|
||||||
|
|
||||||
|
LOG_WARN("Looking for next hashes");
|
||||||
|
uint8_t *tmp_commit_hash;
|
||||||
|
while (sqlite3_step(getNextHashStmt) != SQLITE_DONE) {
|
||||||
|
tmp_commit_hash = (uint8_t *)sqlite3_column_blob(getNextHashStmt, 0);
|
||||||
|
|
||||||
|
if (found_hash) {
|
||||||
|
LOG_WARN("Found hash");
|
||||||
|
memcpy(next_commit_hash, tmp_commit_hash, 32);
|
||||||
|
next_hash = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (memcmp(tmp_commit_hash, _commit_hash, 32) == 0)
|
||||||
|
found_hash = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_reset(getNextHashStmt);
|
||||||
|
return next_hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StoreForwardPlusPlusModule::broadcastLink(uint8_t *_commit_hash, uint8_t *_root_hash)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
LOG_WARN("%d", rc);
|
||||||
|
if (rc != SQLITE_OK) {
|
||||||
|
LOG_WARN("here2 %u, %s", rc, sqlite3_errmsg(ppDb));
|
||||||
|
}
|
||||||
|
sqlite3_bind_blob(getLinkStmt, 1, _commit_hash, 32, NULL);
|
||||||
|
sqlite3_step(getLinkStmt);
|
||||||
|
|
||||||
|
meshtastic_StoreForwardPlusPlus storeforward = meshtastic_StoreForwardPlusPlus_init_zero;
|
||||||
|
storeforward.sfpp_message_type = meshtastic_StoreForwardPlusPlus_SFPP_message_type_LINK_PROVIDE;
|
||||||
|
|
||||||
|
storeforward.encapsulated_to = sqlite3_column_int(getLinkStmt, 0);
|
||||||
|
storeforward.encapsulated_from = sqlite3_column_int(getLinkStmt, 1);
|
||||||
|
storeforward.encapsulated_id = sqlite3_column_int(getLinkStmt, 2);
|
||||||
|
|
||||||
|
uint8_t *_payload = (uint8_t *)sqlite3_column_blob(getLinkStmt, 3);
|
||||||
|
storeforward.message.size = sqlite3_column_bytes(getLinkStmt, 3);
|
||||||
|
memcpy(storeforward.message.bytes, _payload, storeforward.message.size);
|
||||||
|
|
||||||
|
uint8_t *_message_hash = (uint8_t *)sqlite3_column_blob(getLinkStmt, 4);
|
||||||
|
storeforward.message_hash.size = 32;
|
||||||
|
memcpy(storeforward.message_hash.bytes, _message_hash, storeforward.message_hash.size);
|
||||||
|
|
||||||
|
storeforward.encapsulated_rxtime = sqlite3_column_int(getLinkStmt, 5);
|
||||||
|
storeforward.commit_hash.size = 32;
|
||||||
|
memcpy(storeforward.commit_hash.bytes, _commit_hash, 32);
|
||||||
|
|
||||||
|
storeforward.root_hash.size = 32;
|
||||||
|
memcpy(storeforward.root_hash.bytes, _root_hash, 32);
|
||||||
|
|
||||||
|
sqlite3_reset(getLinkStmt);
|
||||||
|
|
||||||
|
meshtastic_MeshPacket *p = allocDataProtobuf(storeforward);
|
||||||
|
p->to = NODENUM_BROADCAST;
|
||||||
|
p->decoded.want_response = false;
|
||||||
|
p->priority = meshtastic_MeshPacket_Priority_BACKGROUND;
|
||||||
|
p->channel = 0;
|
||||||
|
LOG_INFO("Send link to mesh");
|
||||||
|
service->sendToMesh(p, RX_SRC_LOCAL, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StoreForwardPlusPlusModule::sendFromScratch(uint8_t _channel_hash)
|
||||||
|
{
|
||||||
|
LOG_WARN("sendFromScratch");
|
||||||
|
// "select destination, sender, packet_id, channel_hash, encrypted_bytes, message_hash, rx_time \
|
||||||
|
// from local_messages order by rx_time desc LIMIT 1;"
|
||||||
|
sqlite3_bind_int(fromScratchStmt, 1, _channel_hash);
|
||||||
|
if (sqlite3_step(fromScratchStmt) == SQLITE_DONE) {
|
||||||
|
LOG_WARN("No messages in scratch to forward");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
uint8_t _root_hash[32] = {0};
|
||||||
|
if (!getRootFromChannelHash(_channel_hash, _root_hash)) {
|
||||||
|
LOG_ERROR("Error getting root hash");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
meshtastic_StoreForwardPlusPlus storeforward = meshtastic_StoreForwardPlusPlus_init_zero;
|
||||||
|
storeforward.sfpp_message_type = meshtastic_StoreForwardPlusPlus_SFPP_message_type_LINK_PROVIDE;
|
||||||
|
|
||||||
|
storeforward.encapsulated_to = sqlite3_column_int(fromScratchStmt, 0);
|
||||||
|
storeforward.encapsulated_from = sqlite3_column_int(fromScratchStmt, 1);
|
||||||
|
storeforward.encapsulated_id = sqlite3_column_int(fromScratchStmt, 2);
|
||||||
|
|
||||||
|
uint8_t *_encrypted = (uint8_t *)sqlite3_column_blob(fromScratchStmt, 3);
|
||||||
|
storeforward.message.size = sqlite3_column_bytes(fromScratchStmt, 3);
|
||||||
|
memcpy(storeforward.message.bytes, _encrypted, storeforward.message.size);
|
||||||
|
|
||||||
|
uint8_t *_message_hash = (uint8_t *)sqlite3_column_blob(fromScratchStmt, 4);
|
||||||
|
storeforward.message_hash.size = 32;
|
||||||
|
memcpy(storeforward.message_hash.bytes, _message_hash, storeforward.message_hash.size);
|
||||||
|
|
||||||
|
storeforward.encapsulated_rxtime = sqlite3_column_int(fromScratchStmt, 5);
|
||||||
|
|
||||||
|
storeforward.root_hash.size = 32;
|
||||||
|
memcpy(storeforward.root_hash.bytes, _root_hash, 32);
|
||||||
|
|
||||||
|
sqlite3_reset(fromScratchStmt);
|
||||||
|
|
||||||
|
meshtastic_MeshPacket *p = allocDataProtobuf(storeforward);
|
||||||
|
p->to = NODENUM_BROADCAST;
|
||||||
|
p->decoded.want_response = false;
|
||||||
|
p->priority = meshtastic_MeshPacket_Priority_BACKGROUND;
|
||||||
|
p->channel = 0;
|
||||||
|
LOG_INFO("Send link to mesh");
|
||||||
|
service->sendToMesh(p, RX_SRC_LOCAL, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StoreForwardPlusPlusModule::addToChain(link_object &lo)
|
||||||
|
{
|
||||||
|
LOG_WARN("Add to chain");
|
||||||
|
// we may need to calculate the commit hash at this point
|
||||||
|
if (!lo.has_commit_hash) {
|
||||||
|
SHA256 commit_hash;
|
||||||
|
|
||||||
|
uint8_t last_message_hash[32] = {0};
|
||||||
|
uint8_t last_commit_hash[32] = {0};
|
||||||
|
|
||||||
|
commit_hash.reset();
|
||||||
|
|
||||||
|
if (getChainEnd(lo.channel_hash, last_commit_hash, last_message_hash)) {
|
||||||
|
printBytes("last message: 0x", last_commit_hash, 32);
|
||||||
|
commit_hash.update(last_commit_hash, 32);
|
||||||
|
} else {
|
||||||
|
printBytes("new chain root: 0x", lo.root_hash, 32);
|
||||||
|
commit_hash.update(lo.root_hash, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
commit_hash.update(lo.message_hash, 32);
|
||||||
|
// message_hash.update(&mp.rx_time, sizeof(mp.rx_time));
|
||||||
|
commit_hash.finalize(lo.commit_hash, 32);
|
||||||
|
}
|
||||||
|
// push a message into the local chain DB
|
||||||
|
// destination
|
||||||
|
sqlite3_bind_int(chain_insert_stmt, 1, lo.to);
|
||||||
|
// sender
|
||||||
|
sqlite3_bind_int(chain_insert_stmt, 2, lo.from);
|
||||||
|
// packet_id
|
||||||
|
sqlite3_bind_int(chain_insert_stmt, 3, lo.id);
|
||||||
|
// root_hash
|
||||||
|
sqlite3_bind_blob(chain_insert_stmt, 4, lo.root_hash, 32, NULL);
|
||||||
|
// encrypted_bytes
|
||||||
|
sqlite3_bind_blob(chain_insert_stmt, 5, lo.encrypted_bytes, lo.encrypted_len, NULL);
|
||||||
|
// message_hash
|
||||||
|
sqlite3_bind_blob(chain_insert_stmt, 6, lo.message_hash, 32, NULL);
|
||||||
|
// rx_time
|
||||||
|
sqlite3_bind_int(chain_insert_stmt, 7, lo.rx_time);
|
||||||
|
// commit_hash
|
||||||
|
sqlite3_bind_blob(chain_insert_stmt, 8, lo.commit_hash, 32, NULL);
|
||||||
|
// payload
|
||||||
|
sqlite3_bind_text(chain_insert_stmt, 9, lo.payload.c_str(), lo.payload.length(), NULL);
|
||||||
|
sqlite3_step(chain_insert_stmt);
|
||||||
|
sqlite3_reset(chain_insert_stmt);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StoreForwardPlusPlusModule::addToScratch(link_object &lo)
|
||||||
|
{
|
||||||
|
// TODO: Make a data structure for this data
|
||||||
|
|
||||||
|
// push a message into the local chain DB
|
||||||
|
// destination
|
||||||
|
sqlite3_bind_int(scratch_insert_stmt, 1, lo.to);
|
||||||
|
// sender
|
||||||
|
sqlite3_bind_int(scratch_insert_stmt, 2, lo.from);
|
||||||
|
// packet_id
|
||||||
|
sqlite3_bind_int(scratch_insert_stmt, 3, lo.id);
|
||||||
|
// root_hash
|
||||||
|
sqlite3_bind_blob(scratch_insert_stmt, 4, lo.root_hash, 32, NULL);
|
||||||
|
// encrypted_bytes
|
||||||
|
sqlite3_bind_blob(scratch_insert_stmt, 5, lo.encrypted_bytes, lo.encrypted_len, NULL);
|
||||||
|
// message_hash
|
||||||
|
sqlite3_bind_blob(scratch_insert_stmt, 6, lo.message_hash, 32, NULL);
|
||||||
|
// rx_time
|
||||||
|
sqlite3_bind_int(scratch_insert_stmt, 7, lo.rx_time);
|
||||||
|
// payload
|
||||||
|
sqlite3_bind_text(scratch_insert_stmt, 8, lo.payload.c_str(), lo.payload.length(), NULL);
|
||||||
|
const char *_error_mesg = sqlite3_errmsg(ppDb);
|
||||||
|
|
||||||
|
LOG_WARN("step %u, %s", sqlite3_step(scratch_insert_stmt), _error_mesg);
|
||||||
|
sqlite3_reset(scratch_insert_stmt);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoreForwardPlusPlusModule::canonAnnounce(uint8_t *_message_hash, uint8_t *_commit_hash, uint8_t *_root_hash,
|
||||||
|
uint32_t _rx_time)
|
||||||
|
{
|
||||||
|
meshtastic_StoreForwardPlusPlus storeforward = meshtastic_StoreForwardPlusPlus_init_zero;
|
||||||
|
storeforward.sfpp_message_type = meshtastic_StoreForwardPlusPlus_SFPP_message_type_CANON_ANNOUNCE;
|
||||||
|
// set root hash
|
||||||
|
|
||||||
|
// set message hash
|
||||||
|
storeforward.message_hash.size = 32;
|
||||||
|
memcpy(storeforward.message_hash.bytes, _message_hash, 32);
|
||||||
|
|
||||||
|
// set chain hash
|
||||||
|
storeforward.commit_hash.size = 32;
|
||||||
|
memcpy(storeforward.commit_hash.bytes, _commit_hash, 32);
|
||||||
|
|
||||||
|
// set root hash
|
||||||
|
storeforward.root_hash.size = 32;
|
||||||
|
memcpy(storeforward.root_hash.bytes, _root_hash, 32);
|
||||||
|
|
||||||
|
storeforward.encapsulated_rxtime = _rx_time;
|
||||||
|
// storeforward.
|
||||||
|
meshtastic_MeshPacket *p = allocDataProtobuf(storeforward);
|
||||||
|
p->to = NODENUM_BROADCAST;
|
||||||
|
p->decoded.want_response = false;
|
||||||
|
p->priority = meshtastic_MeshPacket_Priority_BACKGROUND;
|
||||||
|
p->channel = 0;
|
||||||
|
LOG_INFO("Send packet to mesh");
|
||||||
|
service->sendToMesh(p, RX_SRC_LOCAL, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StoreForwardPlusPlusModule::isInDB(uint8_t *message_hash_bytes)
|
||||||
|
{
|
||||||
|
sqlite3_bind_blob(checkDup, 1, message_hash_bytes, 32, NULL);
|
||||||
|
sqlite3_step(checkDup);
|
||||||
|
int numberFound = sqlite3_column_int(checkDup, 0);
|
||||||
|
sqlite3_reset(checkDup);
|
||||||
|
if (numberFound > 0)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StoreForwardPlusPlusModule::isInScratch(uint8_t *message_hash_bytes)
|
||||||
|
{
|
||||||
|
LOG_WARN("isInScratch");
|
||||||
|
sqlite3_bind_blob(checkScratch, 1, message_hash_bytes, 32, NULL);
|
||||||
|
sqlite3_step(checkScratch);
|
||||||
|
int numberFound = sqlite3_column_int(checkScratch, 0);
|
||||||
|
sqlite3_reset(checkScratch);
|
||||||
|
if (numberFound > 0)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoreForwardPlusPlusModule::removeFromScratch(uint8_t *message_hash_bytes)
|
||||||
|
{
|
||||||
|
LOG_WARN("removeFromScratch");
|
||||||
|
sqlite3_bind_blob(removeScratch, 1, message_hash_bytes, 32, NULL);
|
||||||
|
sqlite3_step(removeScratch);
|
||||||
|
int numberFound = sqlite3_column_int(removeScratch, 0);
|
||||||
|
sqlite3_reset(removeScratch);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoreForwardPlusPlusModule::updatePayload(uint8_t *message_hash_bytes, std::string payload)
|
||||||
|
{
|
||||||
|
LOG_WARN("updatePayload");
|
||||||
|
sqlite3_bind_text(updatePayloadStmt, 1, payload.c_str(), payload.length(), NULL);
|
||||||
|
sqlite3_bind_blob(updatePayloadStmt, 2, message_hash_bytes, 32, NULL);
|
||||||
|
auto res = sqlite3_step(updatePayloadStmt);
|
||||||
|
const char *_error_mesg = sqlite3_errmsg(ppDb);
|
||||||
|
LOG_WARN("step %u, %s", res, _error_mesg);
|
||||||
|
sqlite3_reset(updatePayloadStmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
StoreForwardPlusPlusModule::link_object StoreForwardPlusPlusModule::getFromScratch(uint8_t *message_hash_bytes, size_t hash_len)
|
||||||
|
{
|
||||||
|
|
||||||
|
// vscode wrote this
|
||||||
|
LOG_WARN("getFromScratch");
|
||||||
|
link_object lo;
|
||||||
|
|
||||||
|
sqlite3_bind_blob(fromScratchByHashStmt, 1, message_hash_bytes, hash_len, NULL);
|
||||||
|
auto res = sqlite3_step(fromScratchByHashStmt);
|
||||||
|
const char *_error_mesg = sqlite3_errmsg(ppDb);
|
||||||
|
LOG_WARN("step %u, %s", res, _error_mesg);
|
||||||
|
lo.to = sqlite3_column_int(fromScratchByHashStmt, 0);
|
||||||
|
lo.from = sqlite3_column_int(fromScratchByHashStmt, 1);
|
||||||
|
lo.id = sqlite3_column_int(fromScratchByHashStmt, 2);
|
||||||
|
|
||||||
|
uint8_t *encrypted_bytes = (uint8_t *)sqlite3_column_blob(fromScratchByHashStmt, 3);
|
||||||
|
lo.encrypted_len = sqlite3_column_bytes(fromScratchByHashStmt, 3);
|
||||||
|
memcpy(lo.encrypted_bytes, encrypted_bytes, lo.encrypted_len);
|
||||||
|
uint8_t *message_hash = (uint8_t *)sqlite3_column_blob(fromScratchByHashStmt, 4);
|
||||||
|
memcpy(lo.message_hash, message_hash, 32);
|
||||||
|
lo.rx_time = sqlite3_column_int(fromScratchByHashStmt, 5);
|
||||||
|
lo.channel_hash - sqlite3_column_int(fromScratchByHashStmt, 6);
|
||||||
|
lo.payload =
|
||||||
|
std::string((char *)sqlite3_column_text(fromScratchByHashStmt, 7), sqlite3_column_bytes(fromScratchByHashStmt, 7));
|
||||||
|
sqlite3_reset(fromScratchByHashStmt);
|
||||||
|
return lo;
|
||||||
|
}
|
||||||
|
|
||||||
|
StoreForwardPlusPlusModule::link_object
|
||||||
|
StoreForwardPlusPlusModule::ingestTextPacket(const meshtastic_MeshPacket &mp, const meshtastic_MeshPacket *encrypted_meshpacket)
|
||||||
|
{
|
||||||
|
link_object lo;
|
||||||
|
SHA256 message_hash;
|
||||||
|
lo.to = mp.to;
|
||||||
|
lo.from = mp.from;
|
||||||
|
lo.id = mp.id;
|
||||||
|
lo.rx_time = mp.rx_time;
|
||||||
|
lo.channel_hash = encrypted_meshpacket->channel;
|
||||||
|
memcpy(lo.encrypted_bytes, encrypted_meshpacket->encrypted.bytes, encrypted_meshpacket->encrypted.size);
|
||||||
|
lo.encrypted_len = encrypted_meshpacket->encrypted.size;
|
||||||
|
lo.payload = std::string((char *)mp.decoded.payload.bytes, mp.decoded.payload.size);
|
||||||
|
|
||||||
|
message_hash.reset();
|
||||||
|
message_hash.update(encrypted_meshpacket->encrypted.bytes, encrypted_meshpacket->encrypted.size);
|
||||||
|
message_hash.update(&mp.to, sizeof(mp.to));
|
||||||
|
message_hash.update(&mp.from, sizeof(mp.from));
|
||||||
|
message_hash.update(&mp.id, sizeof(mp.id));
|
||||||
|
message_hash.finalize(lo.message_hash, 32);
|
||||||
|
|
||||||
|
getOrAddRootFromChannelHash(encrypted_meshpacket->channel, lo.root_hash);
|
||||||
|
return lo;
|
||||||
|
}
|
||||||
|
|
||||||
|
StoreForwardPlusPlusModule::link_object StoreForwardPlusPlusModule::ingestLinkMessage(meshtastic_StoreForwardPlusPlus *t)
|
||||||
|
{
|
||||||
|
link_object lo;
|
||||||
|
|
||||||
|
lo.to = t->encapsulated_to;
|
||||||
|
lo.from = t->encapsulated_from;
|
||||||
|
lo.id = t->encapsulated_id;
|
||||||
|
lo.rx_time = t->encapsulated_rxtime;
|
||||||
|
|
||||||
|
// What if we don't have this root hash? Should drop this packet before this point.
|
||||||
|
lo.channel_hash = getChannelHashFromRoot(t->root_hash.bytes);
|
||||||
|
|
||||||
|
SHA256 message_hash;
|
||||||
|
|
||||||
|
memcpy(lo.encrypted_bytes, t->message.bytes, t->message.size);
|
||||||
|
lo.encrypted_len = t->message.size;
|
||||||
|
|
||||||
|
memcpy(lo.message_hash, t->message_hash.bytes, t->message_hash.size);
|
||||||
|
memcpy(lo.root_hash, t->root_hash.bytes, t->root_hash.size);
|
||||||
|
memcpy(lo.commit_hash, t->commit_hash.bytes, t->commit_hash.size);
|
||||||
|
if (t->commit_hash.size == 32)
|
||||||
|
lo.has_commit_hash = true;
|
||||||
|
// we don't ever get the payload here, so it's always an empty string
|
||||||
|
lo.payload = "";
|
||||||
|
|
||||||
|
return lo;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoreForwardPlusPlusModule::rebroadcastLinkObject(StoreForwardPlusPlusModule::link_object &lo)
|
||||||
|
{
|
||||||
|
LOG_WARN("Attempting to Rebroadcast1");
|
||||||
|
meshtastic_MeshPacket *p = router->allocForSending();
|
||||||
|
p->to = lo.to;
|
||||||
|
p->from = lo.from;
|
||||||
|
p->id = lo.id;
|
||||||
|
p->channel = lo.channel_hash;
|
||||||
|
p->which_payload_variant = meshtastic_MeshPacket_encrypted_tag;
|
||||||
|
p->encrypted.size = lo.encrypted_len;
|
||||||
|
memcpy(p->encrypted.bytes, lo.encrypted_bytes, lo.encrypted_len);
|
||||||
|
p->transport_mechanism = meshtastic_MeshPacket_TransportMechanism_TRANSPORT_LORA; // only a tiny white lie
|
||||||
|
service->sendToMesh(p, RX_SRC_RADIO, true); // Send to mesh, cc to phone
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StoreForwardPlusPlusModule::checkCommitHash(StoreForwardPlusPlusModule::link_object &lo, uint8_t *commit_hash_bytes,
|
||||||
|
size_t hash_len)
|
||||||
|
{
|
||||||
|
SHA256 commit_hash;
|
||||||
|
uint8_t last_message_hash[32] = {0};
|
||||||
|
uint8_t last_commit_hash[32] = {0};
|
||||||
|
|
||||||
|
commit_hash.reset();
|
||||||
|
|
||||||
|
if (getChainEnd(lo.channel_hash, last_commit_hash, last_message_hash)) {
|
||||||
|
printBytes("last message: 0x", last_commit_hash, 32);
|
||||||
|
commit_hash.update(last_commit_hash, 32);
|
||||||
|
} else {
|
||||||
|
printBytes("new chain root: 0x", lo.root_hash, 32);
|
||||||
|
commit_hash.update(lo.root_hash, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
commit_hash.update(lo.message_hash, 32);
|
||||||
|
commit_hash.finalize(commit_hash_bytes, 32);
|
||||||
|
|
||||||
|
if (memcmp(commit_hash_bytes, lo.commit_hash, 32) == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// announce latest hash
|
||||||
|
// chain_end_announce
|
||||||
|
|
||||||
|
// check if hash is known
|
||||||
|
// hash_query
|
||||||
|
|
||||||
|
// request next message
|
||||||
|
// link_request
|
||||||
|
|
||||||
|
// send encapsulated message
|
||||||
|
// link_provide_whole
|
||||||
|
// link_provide_half1
|
||||||
|
// link_provide_half2
|
||||||
|
|
||||||
|
// onboard request message?
|
||||||
|
|
||||||
|
// get x from top?
|
||||||
|
|
||||||
|
// messages
|
||||||
|
// Given this chain root, do you have a packet that matches this message hash?
|
||||||
|
// responds with chain hash etc
|
||||||
|
|
||||||
|
// given this chain root, what is your last chain and message hash?
|
||||||
|
// given this chain root, what is your next message after this chain hash? (do we have an overhead problem here?) (blegh,
|
||||||
|
// fragmentation) (but also, trunking)
|
||||||
|
|
||||||
|
// broadcast on this chain root, here is my last chain hash
|
||||||
|
|
||||||
|
// consider third-order nodes
|
||||||
|
|
||||||
|
// I can't talk directly to strata, I can talk to a satellite. Inform sat of a message. Sat stores it as if had seen it locally,
|
||||||
|
// and pushes it to central
|
||||||
|
|
||||||
|
// message Eventually works out through chain
|
||||||
|
|
||||||
|
// sat can capture time of receipt
|
||||||
|
|
||||||
|
// terms:
|
||||||
|
// CANON
|
||||||
|
// stratum
|
||||||
|
// chain
|
||||||
|
// links on the chain
|
||||||
|
|
||||||
|
// the sender+destination pair is an interesting unique id (though ordering) (smaller one goes first?)
|
||||||
|
// so messages with a unique pair become a chain
|
||||||
|
// These get a table
|
||||||
|
|
||||||
|
// message to broadcast get a chain per channel hash
|
||||||
|
// second table
|
||||||
|
// for now, channel messages are limited to decryptable
|
||||||
|
// limited to text messages
|
||||||
|
|
||||||
|
// create a unique-from-nodenums() class that returns a 64-bit value
|
||||||
125
src/modules/Native/StoreForwardPlusPlus.h
Normal file
125
src/modules/Native/StoreForwardPlusPlus.h
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Channels.h"
|
||||||
|
#include "ProtobufModule.h"
|
||||||
|
#include "Router.h"
|
||||||
|
#include "SinglePortModule.h"
|
||||||
|
#include "sqlite3.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple example module that just replies with "Message received" to any message it receives.
|
||||||
|
*/
|
||||||
|
class StoreForwardPlusPlusModule : public ProtobufModule<meshtastic_StoreForwardPlusPlus>, private concurrency::OSThread
|
||||||
|
{
|
||||||
|
struct link_object {
|
||||||
|
uint32_t to;
|
||||||
|
uint32_t from;
|
||||||
|
uint32_t id;
|
||||||
|
uint32_t rx_time;
|
||||||
|
ChannelHash channel_hash;
|
||||||
|
uint8_t encrypted_bytes[256] = {0};
|
||||||
|
size_t encrypted_len;
|
||||||
|
uint8_t message_hash[32] = {0};
|
||||||
|
uint8_t root_hash[32] = {0};
|
||||||
|
uint8_t commit_hash[32] = {0};
|
||||||
|
// TODO: Make these sizes instead?
|
||||||
|
bool has_commit_hash = false;
|
||||||
|
std::string payload;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** Constructor
|
||||||
|
* name is for debugging output
|
||||||
|
*/
|
||||||
|
StoreForwardPlusPlusModule();
|
||||||
|
|
||||||
|
/*
|
||||||
|
-Override the wantPacket method.
|
||||||
|
*/
|
||||||
|
virtual bool wantPacket(const meshtastic_MeshPacket *p) override
|
||||||
|
{
|
||||||
|
// if encrypted but not too FFFF
|
||||||
|
// want
|
||||||
|
switch (p->decoded.portnum) {
|
||||||
|
case meshtastic_PortNum_TEXT_MESSAGE_APP:
|
||||||
|
case 35:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** Called to handle a particular incoming message
|
||||||
|
@return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered for
|
||||||
|
it
|
||||||
|
*/
|
||||||
|
virtual ProcessMessage handleReceived(const meshtastic_MeshPacket &mp) override;
|
||||||
|
virtual bool handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_StoreForwardPlusPlus *t) override;
|
||||||
|
|
||||||
|
virtual int32_t runOnce() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
sqlite3 *ppDb;
|
||||||
|
sqlite3_stmt *chain_insert_stmt;
|
||||||
|
sqlite3_stmt *scratch_insert_stmt;
|
||||||
|
sqlite3_stmt *checkDup;
|
||||||
|
sqlite3_stmt *checkScratch;
|
||||||
|
sqlite3_stmt *removeScratch;
|
||||||
|
sqlite3_stmt *updatePayloadStmt;
|
||||||
|
sqlite3_stmt *getPayloadFromScratchStmt;
|
||||||
|
sqlite3_stmt *fromScratchStmt;
|
||||||
|
sqlite3_stmt *fromScratchByHashStmt;
|
||||||
|
sqlite3_stmt *getNextHashStmt;
|
||||||
|
sqlite3_stmt *getChainEndStmt;
|
||||||
|
sqlite3_stmt *getLinkStmt;
|
||||||
|
|
||||||
|
// returns wasfound
|
||||||
|
bool getRootFromChannelHash(ChannelHash, uint8_t *);
|
||||||
|
|
||||||
|
ChannelHash getChannelHashFromRoot(uint8_t *_root_hash);
|
||||||
|
|
||||||
|
bool getNextHash(uint8_t *_root_hash, uint8_t *, uint8_t *);
|
||||||
|
|
||||||
|
// returns isnew
|
||||||
|
bool getOrAddRootFromChannelHash(ChannelHash, uint8_t *);
|
||||||
|
|
||||||
|
bool addRootToMappings(ChannelHash, uint8_t *);
|
||||||
|
|
||||||
|
// return indicates message found
|
||||||
|
uint32_t getChainEnd(ChannelHash, uint8_t *, uint8_t *);
|
||||||
|
|
||||||
|
void requestNextMessage(uint8_t *, uint8_t *);
|
||||||
|
|
||||||
|
bool broadcastLink(uint8_t *, uint8_t *);
|
||||||
|
|
||||||
|
bool sendFromScratch(uint8_t);
|
||||||
|
|
||||||
|
bool addToChain(link_object &);
|
||||||
|
|
||||||
|
bool addToScratch(link_object &);
|
||||||
|
|
||||||
|
void canonAnnounce(uint8_t *, uint8_t *, uint8_t *, uint32_t);
|
||||||
|
|
||||||
|
bool isInDB(uint8_t *);
|
||||||
|
|
||||||
|
bool isInScratch(uint8_t *);
|
||||||
|
|
||||||
|
link_object getFromScratch(uint8_t *, size_t);
|
||||||
|
|
||||||
|
void removeFromScratch(uint8_t *);
|
||||||
|
|
||||||
|
void updatePayload(uint8_t *, std::string);
|
||||||
|
|
||||||
|
// does not set the root hash
|
||||||
|
link_object ingestTextPacket(const meshtastic_MeshPacket &, const meshtastic_MeshPacket *);
|
||||||
|
|
||||||
|
link_object ingestLinkMessage(meshtastic_StoreForwardPlusPlus *);
|
||||||
|
|
||||||
|
void rebroadcastLinkObject(link_object &);
|
||||||
|
|
||||||
|
bool checkCommitHash(link_object &lo, uint8_t *commit_hash_bytes, size_t hash_len);
|
||||||
|
|
||||||
|
enum chain_types {
|
||||||
|
channel_chain = 0,
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -45,8 +45,12 @@ bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes
|
|||||||
{
|
{
|
||||||
auto p = *pptr;
|
auto p = *pptr;
|
||||||
|
|
||||||
// If inbound message is a replay (or spoof!) of our own messages, we shouldn't process
|
const auto transport = mp.transport_mechanism;
|
||||||
// (why use second-hand sources for our own data?)
|
if (isFromUs(&mp) && !IS_ONE_OF(transport, meshtastic_MeshPacket_TransportMechanism_TRANSPORT_INTERNAL,
|
||||||
|
meshtastic_MeshPacket_TransportMechanism_TRANSPORT_API)) {
|
||||||
|
LOG_WARN("Ignoring packet supposedly from us over external transport");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME this can in fact happen with packets sent from EUD (src=RX_SRC_USER)
|
// FIXME this can in fact happen with packets sent from EUD (src=RX_SRC_USER)
|
||||||
// to set fixed location, EUD-GPS location or just the time (see also issue #900)
|
// to set fixed location, EUD-GPS location or just the time (see also issue #900)
|
||||||
@@ -472,19 +476,53 @@ void PositionModule::sendLostAndFoundText()
|
|||||||
delete[] message;
|
delete[] message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper: return imprecise (truncated + centered) lat/lon as int32 using current precision
|
||||||
|
static inline void computeImpreciseLatLon(int32_t inLat, int32_t inLon, uint8_t precisionBits, int32_t &outLat, int32_t &outLon)
|
||||||
|
{
|
||||||
|
if (precisionBits > 0 && precisionBits < 32) {
|
||||||
|
// Build mask for top 'precisionBits' bits of a 32-bit unsigned field
|
||||||
|
const uint32_t mask = (precisionBits == 32) ? UINT32_MAX : (UINT32_MAX << (32 - precisionBits));
|
||||||
|
// Note: latitude_i/longitude_i are stored as signed 32-bit in meshtastic code but
|
||||||
|
// the bitmask logic used previously operated as unsigned—preserve that behavior by
|
||||||
|
// casting to uint32_t for masking, then back to int32_t.
|
||||||
|
uint32_t lat_u = static_cast<uint32_t>(inLat) & mask;
|
||||||
|
uint32_t lon_u = static_cast<uint32_t>(inLon) & mask;
|
||||||
|
|
||||||
|
// Add the "center of cell" offset used elsewhere:
|
||||||
|
// The code previously added (1 << (31 - precision)) to produce the middle of the possible location.
|
||||||
|
uint32_t center_offset = (1u << (31 - precisionBits));
|
||||||
|
lat_u += center_offset;
|
||||||
|
lon_u += center_offset;
|
||||||
|
|
||||||
|
outLat = static_cast<int32_t>(lat_u);
|
||||||
|
outLon = static_cast<int32_t>(lon_u);
|
||||||
|
} else {
|
||||||
|
// full precision: return input unchanged
|
||||||
|
outLat = inLat;
|
||||||
|
outLon = inLon;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct SmartPosition PositionModule::getDistanceTraveledSinceLastSend(meshtastic_PositionLite currentPosition)
|
struct SmartPosition PositionModule::getDistanceTraveledSinceLastSend(meshtastic_PositionLite currentPosition)
|
||||||
{
|
{
|
||||||
// The minimum distance to travel before we are able to send a new position packet.
|
|
||||||
const uint32_t distanceTravelThreshold =
|
const uint32_t distanceTravelThreshold =
|
||||||
Default::getConfiguredOrDefault(config.position.broadcast_smart_minimum_distance, 100);
|
Default::getConfiguredOrDefault(config.position.broadcast_smart_minimum_distance, 100);
|
||||||
|
|
||||||
// Determine the distance in meters between two points on the globe
|
int32_t lastLatImprecise, lastLonImprecise;
|
||||||
float distanceTraveledSinceLastSend = GeoCoord::latLongToMeter(
|
int32_t currentLatImprecise, currentLonImprecise;
|
||||||
lastGpsLatitude * 1e-7, lastGpsLongitude * 1e-7, currentPosition.latitude_i * 1e-7, currentPosition.longitude_i * 1e-7);
|
|
||||||
|
|
||||||
return SmartPosition{.distanceTraveled = abs(distanceTraveledSinceLastSend),
|
computeImpreciseLatLon(lastGpsLatitude, lastGpsLongitude, precision, lastLatImprecise, lastLonImprecise);
|
||||||
|
computeImpreciseLatLon(currentPosition.latitude_i, currentPosition.longitude_i, precision, currentLatImprecise,
|
||||||
|
currentLonImprecise);
|
||||||
|
|
||||||
|
float distMeters = GeoCoord::latLongToMeter(lastLatImprecise * 1e-7, lastLonImprecise * 1e-7, currentLatImprecise * 1e-7,
|
||||||
|
currentLonImprecise * 1e-7);
|
||||||
|
|
||||||
|
float distanceTraveled = fabsf(distMeters);
|
||||||
|
|
||||||
|
return SmartPosition{.distanceTraveled = distanceTraveled,
|
||||||
.distanceThreshold = distanceTravelThreshold,
|
.distanceThreshold = distanceTravelThreshold,
|
||||||
.hasTraveledOverThreshold = abs(distanceTraveledSinceLastSend) >= distanceTravelThreshold};
|
.hasTraveledOverThreshold = distanceTraveled >= distanceTravelThreshold};
|
||||||
}
|
}
|
||||||
|
|
||||||
void PositionModule::handleNewPosition()
|
void PositionModule::handleNewPosition()
|
||||||
|
|||||||
@@ -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>();
|
||||||
@@ -746,6 +786,10 @@ bool loadConfig(const char *configPath)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (yamlConfig["StoreAndForward"]) {
|
||||||
|
portduino_config.sfpp_stratum0 = (yamlConfig["StoreAndForward"]["Stratum0"]).as<bool>(false);
|
||||||
|
}
|
||||||
|
|
||||||
if (yamlConfig["General"]) {
|
if (yamlConfig["General"]) {
|
||||||
portduino_config.MaxNodes = (yamlConfig["General"]["MaxNodes"]).as<int>(200);
|
portduino_config.MaxNodes = (yamlConfig["General"]["MaxNodes"]).as<int>(200);
|
||||||
portduino_config.maxtophone = (yamlConfig["General"]["MaxMessageQueue"]).as<int>(100);
|
portduino_config.maxtophone = (yamlConfig["General"]["MaxMessageQueue"]).as<int>(100);
|
||||||
|
|||||||
@@ -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";
|
||||||
@@ -163,6 +169,9 @@ extern struct portduino_config_struct {
|
|||||||
int configDisplayMode = 0;
|
int configDisplayMode = 0;
|
||||||
bool has_configDisplayMode = false;
|
bool has_configDisplayMode = false;
|
||||||
|
|
||||||
|
// Store and Forward++
|
||||||
|
bool sfpp_stratum0 = false;
|
||||||
|
|
||||||
// General
|
// General
|
||||||
std::string mac_address = "";
|
std::string mac_address = "";
|
||||||
bool mac_address_explicit = false;
|
bool mac_address_explicit = false;
|
||||||
@@ -413,6 +422,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.
|
||||||
|
|||||||
@@ -15,4 +15,4 @@ upload_protocol = esptool
|
|||||||
upload_speed = 460800
|
upload_speed = 460800
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32_base.lib_deps}
|
${esp32_base.lib_deps}
|
||||||
adafruit/Adafruit NeoPixel @ ^1.12.0
|
adafruit/Adafruit NeoPixel@1.15.2
|
||||||
|
|||||||
@@ -13,5 +13,3 @@ board_build.f_cpu = 240000000L
|
|||||||
upload_protocol = esptool
|
upload_protocol = esptool
|
||||||
;upload_port = /dev/ttyUSB0
|
;upload_port = /dev/ttyUSB0
|
||||||
upload_speed = 460800
|
upload_speed = 460800
|
||||||
lib_deps =
|
|
||||||
${esp32_base.lib_deps}
|
|
||||||
|
|||||||
@@ -9,4 +9,4 @@ build_flags =
|
|||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32_base.lib_deps}
|
${esp32_base.lib_deps}
|
||||||
lovyan03/LovyanGFX@^1.2.0
|
lovyan03/LovyanGFX@1.2.7
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
[env:meshtastic-dr-dev]
|
[env:meshtastic-dr-dev]
|
||||||
extends = esp32_base
|
extends = esp32_base
|
||||||
board = esp32doit-devkit-v1
|
board = esp32doit-devkit-v1
|
||||||
|
board_level = extra
|
||||||
board_upload.maximum_size = 4194304
|
board_upload.maximum_size = 4194304
|
||||||
board_upload.maximum_ram_size = 532480
|
board_upload.maximum_ram_size = 532480
|
||||||
build_flags =
|
build_flags =
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ custom_esp32_kind = esp32
|
|||||||
custom_mtjson_part =
|
custom_mtjson_part =
|
||||||
platform =
|
platform =
|
||||||
# renovate: datasource=custom.pio depName=platformio/espressif32 packageName=platformio/platform/espressif32
|
# renovate: datasource=custom.pio depName=platformio/espressif32 packageName=platformio/platform/espressif32
|
||||||
platformio/espressif32@6.11.0
|
platformio/espressif32@6.12.0
|
||||||
|
|
||||||
extra_scripts =
|
extra_scripts =
|
||||||
${env.extra_scripts}
|
${env.extra_scripts}
|
||||||
@@ -59,7 +59,7 @@ lib_deps =
|
|||||||
# renovate: datasource=git-refs depName=meshtastic-esp32_https_server packageName=https://github.com/meshtastic/esp32_https_server gitBranch=master
|
# renovate: datasource=git-refs depName=meshtastic-esp32_https_server packageName=https://github.com/meshtastic/esp32_https_server gitBranch=master
|
||||||
https://github.com/meshtastic/esp32_https_server/archive/3223704846752e6d545139204837bdb2a55459ca.zip
|
https://github.com/meshtastic/esp32_https_server/archive/3223704846752e6d545139204837bdb2a55459ca.zip
|
||||||
# renovate: datasource=custom.pio depName=NimBLE-Arduino packageName=h2zero/library/NimBLE-Arduino
|
# renovate: datasource=custom.pio depName=NimBLE-Arduino packageName=h2zero/library/NimBLE-Arduino
|
||||||
h2zero/NimBLE-Arduino@^1.4.3
|
h2zero/NimBLE-Arduino@1.4.3
|
||||||
# renovate: datasource=git-refs depName=libpax packageName=https://github.com/dbinfrago/libpax gitBranch=master
|
# renovate: datasource=git-refs depName=libpax packageName=https://github.com/dbinfrago/libpax gitBranch=master
|
||||||
https://github.com/dbinfrago/libpax/archive/3cdc0371c375676a97967547f4065607d4c53fd1.zip
|
https://github.com/dbinfrago/libpax/archive/3cdc0371c375676a97967547f4065607d4c53fd1.zip
|
||||||
# renovate: datasource=github-tags depName=XPowersLib packageName=lewisxhe/XPowersLib
|
# renovate: datasource=github-tags depName=XPowersLib packageName=lewisxhe/XPowersLib
|
||||||
|
|||||||
@@ -25,4 +25,4 @@ lib_ignore =
|
|||||||
m5stack-core
|
m5stack-core
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32_base.lib_deps}
|
${esp32_base.lib_deps}
|
||||||
lovyan03/LovyanGFX@^1.2.0
|
lovyan03/LovyanGFX@1.2.7
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ build_flags =
|
|||||||
-DM5STACK
|
-DM5STACK
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32_base.lib_deps}
|
${esp32_base.lib_deps}
|
||||||
zinggjm/GxEPD2@^1.6.2
|
zinggjm/GxEPD2@1.6.5
|
||||||
lewisxhe/PCF8563_Library@^1.0.1
|
lewisxhe/PCF8563_Library@1.0.1
|
||||||
lib_ignore =
|
lib_ignore =
|
||||||
m5stack-coreink
|
m5stack-coreink
|
||||||
monitor_filters = esp32_exception_decoder
|
monitor_filters = esp32_exception_decoder
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
[env:nano-g1-explorer]
|
[env:nano-g1-explorer]
|
||||||
extends = esp32_base
|
extends = esp32_base
|
||||||
board = ttgo-t-beam
|
board = ttgo-t-beam
|
||||||
lib_deps =
|
|
||||||
${esp32_base.lib_deps}
|
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags}
|
${esp32_base.build_flags}
|
||||||
-D NANO_G1_EXPLORER
|
-D NANO_G1_EXPLORER
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
[env:nano-g1]
|
[env:nano-g1]
|
||||||
extends = esp32_base
|
extends = esp32_base
|
||||||
board = ttgo-t-beam
|
board = ttgo-t-beam
|
||||||
lib_deps =
|
|
||||||
${esp32_base.lib_deps}
|
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags}
|
${esp32_base.build_flags}
|
||||||
-D NANO_G1
|
-D NANO_G1
|
||||||
|
|||||||
@@ -15,5 +15,3 @@ build_flags =
|
|||||||
-I variants/esp32/radiomaster_900_bandit_nano
|
-I variants/esp32/radiomaster_900_bandit_nano
|
||||||
board_build.f_cpu = 240000000L
|
board_build.f_cpu = 240000000L
|
||||||
upload_protocol = esptool
|
upload_protocol = esptool
|
||||||
lib_deps =
|
|
||||||
${esp32_base.lib_deps}
|
|
||||||
|
|||||||
@@ -10,5 +10,3 @@ build_flags =
|
|||||||
-I variants/esp32/radiomaster_900_bandit_nano
|
-I variants/esp32/radiomaster_900_bandit_nano
|
||||||
board_build.f_cpu = 240000000L
|
board_build.f_cpu = 240000000L
|
||||||
upload_protocol = esptool
|
upload_protocol = esptool
|
||||||
lib_deps =
|
|
||||||
${esp32_base.lib_deps}
|
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
[env:station-g1]
|
[env:station-g1]
|
||||||
extends = esp32_base
|
extends = esp32_base
|
||||||
board = ttgo-t-beam
|
board = ttgo-t-beam
|
||||||
lib_deps =
|
|
||||||
${esp32_base.lib_deps}
|
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags}
|
${esp32_base.build_flags}
|
||||||
-D STATION_G1
|
-D STATION_G1
|
||||||
|
|||||||
@@ -2,9 +2,8 @@
|
|||||||
[env:tbeam]
|
[env:tbeam]
|
||||||
extends = esp32_base
|
extends = esp32_base
|
||||||
board = ttgo-t-beam
|
board = ttgo-t-beam
|
||||||
board_level = pr
|
board_level = extra
|
||||||
board_check = true
|
board_check = true
|
||||||
lib_deps = ${esp32_base.lib_deps}
|
|
||||||
build_flags = ${esp32_base.build_flags}
|
build_flags = ${esp32_base.build_flags}
|
||||||
-D TBEAM_V10
|
-D TBEAM_V10
|
||||||
-I variants/esp32/tbeam
|
-I variants/esp32/tbeam
|
||||||
|
|||||||
@@ -10,6 +10,6 @@ build_flags =
|
|||||||
-I variants/esp32/wiphone
|
-I variants/esp32/wiphone
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32_base.lib_deps}
|
${esp32_base.lib_deps}
|
||||||
lovyan03/LovyanGFX@^1.2.0
|
lovyan03/LovyanGFX@1.2.7
|
||||||
sparkfun/SX1509 IO Expander@^3.0.5
|
sparkfun/SX1509 IO Expander@3.0.6
|
||||||
pololu/APA102@^3.0.0
|
pololu/APA102@3.0.0
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
extends = esp32c3_base
|
extends = esp32c3_base
|
||||||
board = esp32-c3-devkitm-1
|
board = esp32-c3-devkitm-1
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags}
|
${esp32c3_base.build_flags}
|
||||||
-D PRIVATE_HW
|
-D PRIVATE_HW
|
||||||
-I variants/esp32c3/diy/esp32c3_super_mini
|
-I variants/esp32c3/diy/esp32c3_super_mini
|
||||||
-D ARDUINO_USB_MODE=1
|
-D ARDUINO_USB_MODE=1
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ extends = esp32c3_base
|
|||||||
board = esp32-c3-devkitm-1
|
board = esp32-c3-devkitm-1
|
||||||
board_level = extra
|
board_level = extra
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags}
|
${esp32c3_base.build_flags}
|
||||||
-D PRIVATE_HW
|
-D PRIVATE_HW
|
||||||
-D ARDUINO_USB_MODE=1
|
-D ARDUINO_USB_MODE=1
|
||||||
-D ARDUINO_USB_CDC_ON_BOOT=1
|
-D ARDUINO_USB_CDC_ON_BOOT=1
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ extends = esp32c3_base
|
|||||||
board = esp32-c3-devkitm-1
|
board = esp32-c3-devkitm-1
|
||||||
board_level = pr
|
board_level = pr
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags}
|
${esp32c3_base.build_flags}
|
||||||
-D HELTEC_HT62
|
-D HELTEC_HT62
|
||||||
-I variants/esp32c3/heltec_esp32c3
|
-I variants/esp32c3/heltec_esp32c3
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
extends = esp32c3_base
|
extends = esp32c3_base
|
||||||
board = adafruit_qtpy_esp32c3
|
board = adafruit_qtpy_esp32c3
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags}
|
${esp32c3_base.build_flags}
|
||||||
-D HELTEC_HRU_3601
|
-D HELTEC_HRU_3601
|
||||||
-I variants/esp32c3/heltec_hru_3601
|
-I variants/esp32c3/heltec_hru_3601
|
||||||
lib_deps = ${esp32c3_base.lib_deps}
|
lib_deps = ${esp32c3_base.lib_deps}
|
||||||
adafruit/Adafruit NeoPixel @ ^1.12.0
|
adafruit/Adafruit NeoPixel@1.15.2
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ extends = esp32c3_base
|
|||||||
board = esp32-c3-devkitm-1
|
board = esp32-c3-devkitm-1
|
||||||
board_level = extra
|
board_level = extra
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags}
|
${esp32c3_base.build_flags}
|
||||||
-D PRIVATE_HW
|
-D PRIVATE_HW
|
||||||
-I variants/esp32c3/m5stack-stamp-c3
|
-I variants/esp32c3/m5stack-stamp-c3
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ build_unflags =
|
|||||||
-D HAS_WIFI
|
-D HAS_WIFI
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32c6_base.lib_deps}
|
${esp32c6_base.lib_deps}
|
||||||
adafruit/Adafruit NeoPixel@^1.12.3
|
adafruit/Adafruit NeoPixel@1.15.2
|
||||||
h2zero/NimBLE-Arduino@^2.3.6
|
h2zero/NimBLE-Arduino@2.3.7
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32c6_base.build_flags}
|
${esp32c6_base.build_flags}
|
||||||
-D M5STACK_UNITC6L
|
-D M5STACK_UNITC6L
|
||||||
|
|||||||
@@ -17,5 +17,5 @@ build_flags =
|
|||||||
|
|
||||||
lib_deps = ${esp32s3_base.lib_deps}
|
lib_deps = ${esp32s3_base.lib_deps}
|
||||||
https://github.com/meshtastic/GxEPD2/archive/1655054ba298e0e29fc2044741940f927f9c2a43.zip
|
https://github.com/meshtastic/GxEPD2/archive/1655054ba298e0e29fc2044741940f927f9c2a43.zip
|
||||||
lewisxhe/PCF8563_Library@^1.0.1
|
lewisxhe/PCF8563_Library@1.0.1
|
||||||
maxpromer/PCA9557-arduino @ ^1.0.0
|
maxpromer/PCA9557-arduino@1.0.0
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ board_level = extra
|
|||||||
upload_protocol = esptool
|
upload_protocol = esptool
|
||||||
;upload_port = /dev/ttyACM2
|
;upload_port = /dev/ttyACM2
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32_base.lib_deps}
|
${esp32s3_base.lib_deps}
|
||||||
caveman99/ESP32 Codec2@^1.0.1
|
caveman99/ESP32 Codec2@1.0.1
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags}
|
${esp32s3_base.build_flags}
|
||||||
-D PRIVATE_HW
|
-D PRIVATE_HW
|
||||||
-I variants/esp32s3/bpi_picow_esp32_s3
|
-I variants/esp32s3/bpi_picow_esp32_s3
|
||||||
|
|||||||
@@ -9,14 +9,14 @@ upload_protocol = esptool
|
|||||||
;upload_port = /dev/ttyACM1
|
;upload_port = /dev/ttyACM1
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32_base.lib_deps}
|
${esp32s3_base.lib_deps}
|
||||||
zinggjm/GxEPD2@^1.6.2
|
zinggjm/GxEPD2@1.6.5
|
||||||
adafruit/Adafruit NeoPixel @ ^1.12.0
|
adafruit/Adafruit NeoPixel@1.15.2
|
||||||
build_unflags =
|
build_unflags =
|
||||||
${esp32s3_base.build_unflags}
|
${esp32s3_base.build_unflags}
|
||||||
-DARDUINO_USB_MODE=1
|
-DARDUINO_USB_MODE=1
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags}
|
${esp32s3_base.build_flags}
|
||||||
-D PRIVATE_HW
|
-D PRIVATE_HW
|
||||||
-I variants/esp32s3/diy/my_esp32s3_diy_eink
|
-I variants/esp32s3/diy/my_esp32s3_diy_eink
|
||||||
-Dmy
|
-Dmy
|
||||||
|
|||||||
@@ -9,13 +9,13 @@ upload_protocol = esptool
|
|||||||
;upload_port = /dev/ttyACM0
|
;upload_port = /dev/ttyACM0
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32_base.lib_deps}
|
${esp32s3_base.lib_deps}
|
||||||
adafruit/Adafruit NeoPixel @ ^1.12.0
|
adafruit/Adafruit NeoPixel@1.15.2
|
||||||
build_unflags =
|
build_unflags =
|
||||||
${esp32s3_base.build_unflags}
|
${esp32s3_base.build_unflags}
|
||||||
-DARDUINO_USB_MODE=1
|
-DARDUINO_USB_MODE=1
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags}
|
${esp32s3_base.build_flags}
|
||||||
-D PRIVATE_HW
|
-D PRIVATE_HW
|
||||||
-I variants/esp32s3/diy/my_esp32s3_diy_oled
|
-I variants/esp32s3/diy/my_esp32s3_diy_oled
|
||||||
-DBOARD_HAS_PSRAM
|
-DBOARD_HAS_PSRAM
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ build_flags =
|
|||||||
-D ARDUINO_USB_CDC_ON_BOOT=1
|
-D ARDUINO_USB_CDC_ON_BOOT=1
|
||||||
|
|
||||||
lib_deps = ${esp32s3_base.lib_deps}
|
lib_deps = ${esp32s3_base.lib_deps}
|
||||||
earlephilhower/ESP8266Audio@^1.9.9
|
earlephilhower/ESP8266Audio@1.9.9
|
||||||
earlephilhower/ESP8266SAM@^1.0.1
|
earlephilhower/ESP8266SAM@1.1.0
|
||||||
|
|
||||||
[env:dreamcatcher-2206]
|
[env:dreamcatcher-2206]
|
||||||
extends = esp32s3_base
|
extends = esp32s3_base
|
||||||
|
|||||||
@@ -22,5 +22,5 @@ build_flags = ${esp32s3_base.build_flags}
|
|||||||
-DEINK_HEIGHT=128
|
-DEINK_HEIGHT=128
|
||||||
|
|
||||||
lib_deps = ${esp32s3_base.lib_deps}
|
lib_deps = ${esp32s3_base.lib_deps}
|
||||||
zinggjm/GxEPD2@^1.6.2
|
zinggjm/GxEPD2@1.6.5
|
||||||
adafruit/Adafruit NeoPixel @ ^1.12.0
|
adafruit/Adafruit NeoPixel@1.15.2
|
||||||
|
|||||||
@@ -9,4 +9,4 @@ build_flags =
|
|||||||
-D HELTEC_SENSOR_HUB
|
-D HELTEC_SENSOR_HUB
|
||||||
|
|
||||||
lib_deps = ${esp32s3_base.lib_deps}
|
lib_deps = ${esp32s3_base.lib_deps}
|
||||||
adafruit/Adafruit NeoPixel @ ^1.12.0
|
adafruit/Adafruit NeoPixel@1.15.2
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ build_flags =
|
|||||||
${esp32s3_base.build_flags}
|
${esp32s3_base.build_flags}
|
||||||
-D HELTEC_V4
|
-D HELTEC_V4
|
||||||
-I variants/esp32s3/heltec_v4
|
-I variants/esp32s3/heltec_v4
|
||||||
lib_deps =
|
|
||||||
${esp32s3_base.lib_deps}
|
|
||||||
|
|
||||||
|
|
||||||
[env:heltec-v4]
|
[env:heltec-v4]
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ build_flags =
|
|||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32s3_base.lib_deps}
|
${esp32s3_base.lib_deps}
|
||||||
https://github.com/meshtastic/GxEPD2/archive/1655054ba298e0e29fc2044741940f927f9c2a43.zip
|
https://github.com/meshtastic/GxEPD2/archive/1655054ba298e0e29fc2044741940f927f9c2a43.zip
|
||||||
lewisxhe/PCF8563_Library@^1.0.1
|
lewisxhe/PCF8563_Library@1.0.1
|
||||||
upload_speed = 115200
|
upload_speed = 115200
|
||||||
|
|
||||||
[env:heltec-vision-master-e213-inkhud]
|
[env:heltec-vision-master-e213-inkhud]
|
||||||
@@ -27,7 +27,7 @@ board = heltec_vision_master_e213
|
|||||||
board_level = pr
|
board_level = pr
|
||||||
board_build.partitions = default_8MB.csv
|
board_build.partitions = default_8MB.csv
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
${esp32_base.build_src_filter}
|
${esp32s3_base.build_src_filter}
|
||||||
${inkhud.build_src_filter}
|
${inkhud.build_src_filter}
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32s3_base.build_flags}
|
${esp32s3_base.build_flags}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ build_flags =
|
|||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32s3_base.lib_deps}
|
${esp32s3_base.lib_deps}
|
||||||
https://github.com/meshtastic/GxEPD2/archive/448c8538129fde3d02a7cb5e6fc81971ad92547f.zip
|
https://github.com/meshtastic/GxEPD2/archive/448c8538129fde3d02a7cb5e6fc81971ad92547f.zip
|
||||||
lewisxhe/PCF8563_Library@^1.0.1
|
lewisxhe/PCF8563_Library@1.0.1
|
||||||
upload_speed = 115200
|
upload_speed = 115200
|
||||||
|
|
||||||
[env:heltec-vision-master-e290-inkhud]
|
[env:heltec-vision-master-e290-inkhud]
|
||||||
@@ -29,7 +29,7 @@ extends = esp32s3_base, inkhud
|
|||||||
board = heltec_vision_master_e290
|
board = heltec_vision_master_e290
|
||||||
board_build.partitions = default_8MB.csv
|
board_build.partitions = default_8MB.csv
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
${esp32_base.build_src_filter}
|
${esp32s3_base.build_src_filter}
|
||||||
${inkhud.build_src_filter}
|
${inkhud.build_src_filter}
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32s3_base.build_flags}
|
${esp32s3_base.build_flags}
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ build_flags =
|
|||||||
-D HELTEC_VISION_MASTER_T190
|
-D HELTEC_VISION_MASTER_T190
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32s3_base.lib_deps}
|
${esp32s3_base.lib_deps}
|
||||||
lewisxhe/PCF8563_Library@^1.0.1
|
lewisxhe/PCF8563_Library@1.0.1
|
||||||
https://github.com/meshtastic/st7789/archive/bd33ea58ddfe4a5e4a66d53300ccbd38d66ac21f.zip
|
https://github.com/meshtastic/st7789/archive/bd33ea58ddfe4a5e4a66d53300ccbd38d66ac21f.zip
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ build_flags =
|
|||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32s3_base.lib_deps}
|
${esp32s3_base.lib_deps}
|
||||||
https://github.com/meshtastic/GxEPD2/archive/1655054ba298e0e29fc2044741940f927f9c2a43.zip
|
https://github.com/meshtastic/GxEPD2/archive/1655054ba298e0e29fc2044741940f927f9c2a43.zip
|
||||||
lewisxhe/PCF8563_Library@^1.0.1
|
lewisxhe/PCF8563_Library@1.0.1
|
||||||
upload_speed = 115200
|
upload_speed = 115200
|
||||||
|
|
||||||
[env:heltec-wireless-paper-inkhud]
|
[env:heltec-wireless-paper-inkhud]
|
||||||
@@ -27,7 +27,7 @@ extends = esp32s3_base, inkhud
|
|||||||
board = heltec_wifi_lora_32_V3
|
board = heltec_wifi_lora_32_V3
|
||||||
board_build.partitions = default_8MB.csv
|
board_build.partitions = default_8MB.csv
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
${esp32_base.build_src_filter}
|
${esp32s3_base.build_src_filter}
|
||||||
${inkhud.build_src_filter}
|
${inkhud.build_src_filter}
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32s3_base.build_flags}
|
${esp32s3_base.build_flags}
|
||||||
|
|||||||
@@ -16,5 +16,5 @@ build_flags =
|
|||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32s3_base.lib_deps}
|
${esp32s3_base.lib_deps}
|
||||||
https://github.com/meshtastic/GxEPD2/archive/55f618961db45a23eff0233546430f1e5a80f63a.zip
|
https://github.com/meshtastic/GxEPD2/archive/55f618961db45a23eff0233546430f1e5a80f63a.zip
|
||||||
lewisxhe/PCF8563_Library@^1.0.1
|
lewisxhe/PCF8563_Library@1.0.1
|
||||||
upload_speed = 115200
|
upload_speed = 115200
|
||||||
|
|||||||
@@ -12,4 +12,4 @@ build_flags =
|
|||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32s3_base.lib_deps}
|
${esp32s3_base.lib_deps}
|
||||||
lovyan03/LovyanGFX@^1.2.0
|
lovyan03/LovyanGFX@1.2.7
|
||||||
|
|||||||
@@ -11,4 +11,4 @@ build_flags =
|
|||||||
;-D DEBUG_DISABLED ; uncomment this line to disable DEBUG output
|
;-D DEBUG_DISABLED ; uncomment this line to disable DEBUG output
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32s3_base.lib_deps}
|
${esp32s3_base.lib_deps}
|
||||||
lovyan03/LovyanGFX@^1.2.0
|
lovyan03/LovyanGFX@1.2.7
|
||||||
|
|||||||
@@ -10,4 +10,4 @@ build_flags =
|
|||||||
-D HELTEC_WIRELESS_TRACKER_V2
|
-D HELTEC_WIRELESS_TRACKER_V2
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32s3_base.lib_deps}
|
${esp32s3_base.lib_deps}
|
||||||
lovyan03/LovyanGFX@^1.2.0
|
lovyan03/LovyanGFX@1.2.7
|
||||||
|
|||||||
@@ -8,8 +8,6 @@ board_build.partitions = default_8MB.csv
|
|||||||
upload_protocol = esptool
|
upload_protocol = esptool
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
platform_packages = platformio/framework-arduinoespressif32@https://github.com/PowerFeather/powerfeather-meshtastic-arduino-lib/releases/download/2.0.16a/esp32-2.0.16.zip
|
platform_packages = platformio/framework-arduinoespressif32@https://github.com/PowerFeather/powerfeather-meshtastic-arduino-lib/releases/download/2.0.16a/esp32-2.0.16.zip
|
||||||
lib_deps =
|
|
||||||
${esp32s3_base.lib_deps}
|
|
||||||
build_unflags =
|
build_unflags =
|
||||||
${esp32s3_base.build_unflags}
|
${esp32s3_base.build_unflags}
|
||||||
-DARDUINO_USB_MODE=1
|
-DARDUINO_USB_MODE=1
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
[env:link32-s3-v1]
|
[env:link32-s3-v1]
|
||||||
extends = esp32s3_base
|
extends = esp32s3_base
|
||||||
board = esp32-s3-devkitc-1
|
board = esp32-s3-devkitc-1
|
||||||
|
board_level = extra
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags}
|
${esp32s3_base.build_flags}
|
||||||
-D LINK_32
|
-D LINK_32
|
||||||
-I variants/esp32s3/link32_s3_v1
|
-I variants/esp32s3/link32_s3_v1
|
||||||
-DARDUINO_USB_CDC_ON_BOOT
|
-DARDUINO_USB_CDC_ON_BOOT
|
||||||
|
|||||||
@@ -6,8 +6,7 @@ board_check = true
|
|||||||
board_build.partitions = default_16MB.csv
|
board_build.partitions = default_16MB.csv
|
||||||
upload_protocol = esptool
|
upload_protocol = esptool
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags}
|
${esp32s3_base.build_flags}
|
||||||
-D PRIVATE_HW
|
-D PRIVATE_HW
|
||||||
-D M5STACK_CORES3
|
-D M5STACK_CORES3
|
||||||
-I variants/esp32s3/m5stack_cores3
|
-I variants/esp32s3/m5stack_cores3
|
||||||
lib_deps = ${esp32_base.lib_deps}
|
|
||||||
|
|||||||
@@ -46,11 +46,11 @@ build_flags = ${esp32s3_base.build_flags}
|
|||||||
-D VIEW_320x240
|
-D VIEW_320x240
|
||||||
-D USE_PACKET_API
|
-D USE_PACKET_API
|
||||||
-I variants/esp32s3/mesh-tab
|
-I variants/esp32s3/mesh-tab
|
||||||
build_src_filter = ${esp32_base.build_src_filter}
|
build_src_filter = ${esp32s3_base.build_src_filter}
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32_base.lib_deps}
|
${esp32s3_base.lib_deps}
|
||||||
${device-ui_base.lib_deps}
|
${device-ui_base.lib_deps}
|
||||||
lovyan03/LovyanGFX@^1.2.0
|
lovyan03/LovyanGFX@1.2.7
|
||||||
|
|
||||||
[mesh_tab_xpt2046]
|
[mesh_tab_xpt2046]
|
||||||
extends = mesh_tab_base
|
extends = mesh_tab_base
|
||||||
|
|||||||
@@ -3,6 +3,6 @@ extends = esp32s3_base
|
|||||||
board = esp32-s3-zero
|
board = esp32-s3-zero
|
||||||
board_level = extra
|
board_level = extra
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags}
|
${esp32s3_base.build_flags}
|
||||||
-D PRIVATE_HW
|
-D PRIVATE_HW
|
||||||
-I variants/esp32s3/nibble_esp32
|
-I variants/esp32s3/nibble_esp32
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ build_flags =
|
|||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32s3_base.lib_deps}
|
${esp32s3_base.lib_deps}
|
||||||
lovyan03/LovyanGFX@^1.2.0
|
lovyan03/LovyanGFX@1.2.7
|
||||||
|
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
${esp32s3_base.build_src_filter}
|
${esp32s3_base.build_src_filter}
|
||||||
|
|||||||
@@ -6,6 +6,6 @@ board_check = true
|
|||||||
upload_protocol = esptool
|
upload_protocol = esptool
|
||||||
|
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags}
|
${esp32s3_base.build_flags}
|
||||||
-D RAK3312
|
-D RAK3312
|
||||||
-I variants/esp32s3/rak3312
|
-I variants/esp32s3/rak3312
|
||||||
|
|||||||
@@ -8,14 +8,14 @@ upload_protocol = esptool
|
|||||||
board_build.partitions = default_8MB.csv
|
board_build.partitions = default_8MB.csv
|
||||||
|
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags}
|
${esp32s3_base.build_flags}
|
||||||
-D RAK3312
|
-D RAK3312
|
||||||
-D RAK_WISMESH_TAP_V2
|
-D RAK_WISMESH_TAP_V2
|
||||||
-I variants/esp32s3/rak_wismesh_tap_v2
|
-I variants/esp32s3/rak_wismesh_tap_v2
|
||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32s3_base.lib_deps}
|
${esp32s3_base.lib_deps}
|
||||||
lovyan03/LovyanGFX@^1.2.0
|
lovyan03/LovyanGFX@1.2.7
|
||||||
|
|
||||||
[ft5x06]
|
[ft5x06]
|
||||||
extends = mesh_tab_base
|
extends = mesh_tab_base
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ board_check = true
|
|||||||
board_build.partitions = partition-table-8MB.csv
|
board_build.partitions = partition-table-8MB.csv
|
||||||
upload_protocol = esptool
|
upload_protocol = esptool
|
||||||
|
|
||||||
build_flags = ${esp32_base.build_flags}
|
build_flags = ${esp32s3_base.build_flags}
|
||||||
-Ivariants/esp32s3/seeed-sensecap-indicator
|
-Ivariants/esp32s3/seeed-sensecap-indicator
|
||||||
-DSENSECAP_INDICATOR
|
-DSENSECAP_INDICATOR
|
||||||
-DCONFIG_ARDUHAL_LOG_COLORS
|
-DCONFIG_ARDUHAL_LOG_COLORS
|
||||||
@@ -25,8 +25,8 @@ build_flags = ${esp32_base.build_flags}
|
|||||||
|
|
||||||
lib_deps = ${esp32s3_base.lib_deps}
|
lib_deps = ${esp32s3_base.lib_deps}
|
||||||
https://github.com/mverch67/LovyanGFX/archive/4c76238c1344162a234ae917b27651af146d6fb2.zip
|
https://github.com/mverch67/LovyanGFX/archive/4c76238c1344162a234ae917b27651af146d6fb2.zip
|
||||||
earlephilhower/ESP8266Audio@^1.9.9
|
earlephilhower/ESP8266Audio@1.9.9
|
||||||
earlephilhower/ESP8266SAM@^1.0.1
|
earlephilhower/ESP8266SAM@1.1.0
|
||||||
|
|
||||||
|
|
||||||
[env:seeed-sensecap-indicator-tft]
|
[env:seeed-sensecap-indicator-tft]
|
||||||
|
|||||||
@@ -6,8 +6,6 @@ board_check = true
|
|||||||
board_build.partitions = default_8MB.csv
|
board_build.partitions = default_8MB.csv
|
||||||
upload_protocol = esptool
|
upload_protocol = esptool
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
lib_deps =
|
|
||||||
${esp32s3_base.lib_deps}
|
|
||||||
build_unflags =
|
build_unflags =
|
||||||
${esp32s3_base.build_unflags}
|
${esp32s3_base.build_unflags}
|
||||||
-DARDUINO_USB_MODE=1
|
-DARDUINO_USB_MODE=1
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user