Compare commits

...

53 Commits

Author SHA1 Message Date
Tom Fifield
e182ae75c2 Remove ancient .gitignore lines (#4952)
The files referenced here have not existed for some time.
2024-10-05 05:15:20 -05:00
Jonathan Bennett
7e946d15ca Move ifndef to fix test (#4950) 2024-10-04 22:59:00 -05:00
Ben Meadors
c3b9d493b6 Leave the build epoch commented and uncomment when CI runs (#4943) 2024-10-04 15:07:10 -05:00
Jonathan Bennett
4db0c75c8e Don't use a static decleration in a header file (#4944)
* Don't use a static decleration in a header file

* Actually add the rest of the commit
2024-10-04 12:06:02 -05:00
Ludovic BOUÉ
e7cfadacd8 Add Panel_ILI9342 to TFTDisplay.cpp (#4822)
* Add Panel_ILI9342 to TFTDisplay.cpp

[Panel_ILI9342](https://github.com/lovyan03/LovyanGFX/blob/master/src/lgfx/v1/panel/Panel_ILI9342.hpp)

* Add ILI9342_DRIVER to TFTDisplay.cpp

* Add ILI9342_DRIVER to Screen.cpp

* Add ILI9342_DRIVER to ScreenFonts.h

* Add ILI9342_DRIVER to main.cpp

* Add ILI9342_DRIVER to images.h

* Add ILI9342_DRIVER to NodeDB.cpp

* Add ILI9342 to PortduinoGlue.cpp

* Add ili9342 to PortduinoGlue.h

* Fix formatting

* Update Screen.cpp to add ILI9342_DRIVER

* Update TFTDisplay.cpp

* Update TFTDisplay.cpp

* Update Screen.cpp

* Update Screen.cpp

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Tom Fifield <tom@tomfifield.net>
2024-10-04 07:47:14 -05:00
GUVWAF
673fe294f3 Add rxDupe, txRelay and txRelayCanceled to LocalStats (#4936)
* Introduce `isFromUs()` and `isToUs()`

* Add rxDupe, txRelay and txRelayCanceled to LocalStats
2024-10-04 06:28:51 -05:00
gitbisector
236374491b cleanupNeighbors() time difference fix (#4941) 2024-10-04 06:17:23 -05:00
HarukiToreda
d6f26c682d Enabling Ve pin on T114 (#4940)
* Enabling Ve pin on T114

Problem:
The Ve pin was not enabled in the firmware, and it was supposed to control the power to the GPS via the GPS_EN pin. As a result, users were forced to rely on the 3.3V pin to power their additional peripherals, which caused a constant power draw from the battery, even when the node was in deep sleep mode.

Solution:
To resolve this, Todd_Hervert and I decided to remove the GPS power toggle after testing revealed that the GPS only consumes 1mA in soft sleep mode. This minimal power consumption allowed us to enable the Ve pin without causing significant battery drain. Additionally, we added a delay to the I2C initialization process, as the Ve pin requires a few milliseconds to stabilize, which could prevent some peripherals from booting up in time.

Result:

The GPS operates as usual, drawing only 1mA of power.
The keyboard and other peripherals attached to the Ve pin now power off correctly when the node is shut down.
The I2C check initiates without issues after the delay, allowing all peripherals to function smoothly.

* trunk format

---------

Co-authored-by: Tom Fifield <tom@tomfifield.net>
2024-10-04 06:15:59 -05:00
Jonathan Bennett
befc2ece6f Add a Userprefs Timezone String, to be replaced in the web flasher (#4938)
* Add a Userprefs Timezone String, to be replaced in the web flasher

* Use a volatile char buffer for slipstreamed strings.

* More refinement
2024-10-03 20:51:22 -05:00
github-actions[bot]
b2b60eccdb [create-pull-request] automated change (#4937)
Co-authored-by: GUVWAF <78759985+GUVWAF@users.noreply.github.com>
2024-10-03 14:54:18 -05:00
dependabot[bot]
07d4e6f5be Bump protobufs from 62c4b00 to b419706 (#4934)
Bumps [protobufs](https://github.com/meshtastic/protobufs) from `62c4b00` to `b419706`.
- [Release notes](https://github.com/meshtastic/protobufs/releases)
- [Commits](62c4b0081c...b419706693)

---
updated-dependencies:
- dependency-name: protobufs
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-03 07:57:34 -05:00
github-actions[bot]
0a93261c06 [create-pull-request] automated change (#4926)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
2024-10-02 06:14:55 -05:00
Ben Meadors
00f15459ec Userprefs prefix macros for clarity and consistency (#4923)
* Convert userprefs macros to prefixed ones for clarity

* Fix key
2024-10-02 06:14:24 -05:00
todd-herbert
b8044c4983 Tweak dimensions for Canned Message Notifications (#4924) 2024-10-02 05:37:08 -05:00
Ben Meadors
18f12584ab Consolidate and shrink down the re-used strings in logs (#4907)
* Consolidate and shrink down the re-used strings in GPS

* Condense all the things

---------

Co-authored-by: GUVWAF <thijs@havinga.eu>
2024-10-01 15:38:36 -05:00
github-actions[bot]
e1e7bbc420 [create-pull-request] automated change (#4918)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
2024-10-01 14:04:44 -05:00
Thomas Göttgens
5f974d2961 save a couple of bytes (#4922) 2024-10-01 14:04:23 -05:00
Thomas Göttgens
cae2e43dc6 revert .... revert .... 2024-10-01 16:36:44 +02:00
Thomas Göttgens
0d175a918c misc library updates and compiler warnings, trunk upgrade 2024-10-01 16:02:10 +02:00
Thomas Göttgens
3440c640c3 keep for 30 days only 2024-10-01 13:46:02 +02:00
Thomas Göttgens
b769d9f854 change workflow to build one zip per processor arch 2024-10-01 13:14:51 +02:00
Ben Meadors
8d288d5a3c Only on pull request 2024-09-30 19:26:35 -05:00
Ben Meadors
dc55d7dd98 Trunk it 2024-09-30 18:07:11 -05:00
TheMalkavien
553514e3b7 Fix #4911 : Partially rework some code to remove warnings about potential non-aligned memory accesses (#4912)
* * Adding the -Wcast-align compilation flag for
  the rp2040.

* * Some rework to use a struct to access radio data
* Buffer will not be accessed by arithmetic pointer anymore

* * Remplace arithmetic pointer to avoid Warning

* * Avoid 2 little artitmetic pointer

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2024-09-30 17:56:29 -05:00
github-actions[bot]
1dace9a508 [create-pull-request] automated change (#4917)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
2024-09-30 17:35:35 -05:00
Jonathan Bennett
dd587419c7 Regenerate public key on boot, to avoid accidental mismatch. (#4916)
* Regenerate public key on boot, to avoid accidental mismatch.

* Fix ifdefs
2024-09-30 17:06:31 -05:00
Thomas Göttgens
bce7d73cc6 Merge pull request #4915 from meshtastic/radiolib-701
Radiolib 702
2024-09-30 21:55:14 +02:00
Thomas Göttgens
810a79668c 7.0.2 dropped 2024-09-30 21:54:00 +02:00
Thomas Göttgens
51ee6c11ea Merge branch 'radiolib-701' of github.com:meshtastic/firmware into radiolib-701 2024-09-30 21:53:31 +02:00
Thomas Göttgens
cb06ab10da Merge pull request #4913 from meshtastic/radiolib-701
Welp it's 7.0.2 now but the branch is still open :-)
2024-09-30 21:12:59 +02:00
Thomas Göttgens
199566a996 let's see if this works 2024-09-30 21:11:48 +02:00
Thomas Göttgens
5fcad1d8c5 Welp it's 7.0.2 now but the branch is still open :-) 2024-09-30 18:15:48 +02:00
Thomas Göttgens
a5bcf48240 Welp it's 7.0.2 now but the branch is still open :-) 2024-09-30 18:12:35 +02:00
Ben Meadors
8ad89ba724 Allow for better target level Radiolib exclude plumbing (#4906)
* WIP

* LR11x0

* Anothern

* =1
2024-09-30 05:14:22 -05:00
Thomas Göttgens
fd6e8613c6 Merge pull request #4908 from scruplelesswizard/fix-artifact-comments
Fix duplicate PR comments
2024-09-30 11:55:35 +02:00
Jason Murray
b529099f90 Update main_matrix.yml 2024-09-29 20:08:23 -07:00
Thomas Göttgens
3896009e55 Merge pull request #4905 from meshtastic/radiolib-701
Update radiolib to 7.0.1
2024-09-29 23:32:47 +02:00
KodinLanewave
6f506cead5 Update INA3221 to 1.0.1 (#4877)
Added new release with compiler error fixes for INA3221 library - updating dependencies so new release will be included

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2024-09-29 16:17:43 -05:00
GUVWAF
3492c9aa99 Construct StoreForwardModule for Portduino as well (#4903)
* Construct StoreForwardModule for Portduino as well

* Remove duplicate variables
2024-09-29 16:17:23 -05:00
Thomas Göttgens
19f45d282f Update radiolib to 7.0.1 2024-09-29 23:12:20 +02:00
Michael Gjelsø
d73cbf14d5 Get accelerometerThread running from AdminModule. (#4886) 2024-09-29 11:49:16 -05:00
dahanc
d41d4c930e When importing config, keep Bluetooth on and defer rebooting until co… (#4898)
* When importing config, keep Bluetooth on and defer rebooting until config is committed

* One more place that was prematurely disabling Bluetooth

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2024-09-29 07:30:10 -05:00
Ben Meadors
403e5c304e Fix: Not being able to stop Ext. Notification nagging for screenless devices (#4899)
* Move logic up to button thread for screen-less devices

* Comment doesn't apply

* Fiddy

---------

Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2024-09-29 07:29:53 -05:00
Ben Meadors
dcb2707d94 Return queue status on rate limit throttling (#4901) 2024-09-29 07:28:20 -05:00
Thomas Göttgens
2e935fd943 why is this different than github docs? 2024-09-29 14:03:22 +02:00
Thomas Göttgens
88af23319c Aha! 2024-09-29 14:00:36 +02:00
Thomas Göttgens
42a3301188 Update main_matrix.yml 2024-09-29 13:58:07 +02:00
Thomas Göttgens
57b8b55fc5 Merge pull request #4900 from meshtastic/caveman99-patch-1
runner debug
2024-09-29 13:55:00 +02:00
Thomas Göttgens
d0440f3cac don't interfere with the trunk check 2024-09-29 13:54:46 +02:00
Thomas Göttgens
ef2035a60c runner debug 2024-09-29 13:52:47 +02:00
Thomas Göttgens
fa29386eb7 Update main_matrix.yml 2024-09-29 12:40:17 +02:00
Jason Murray
7e0665a5cd comment on PR with artifact link (#4896) 2024-09-29 05:01:20 -05:00
github-actions[bot]
233962104c [create-pull-request] automated change (#4897)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
2024-09-28 19:12:10 -05:00
110 changed files with 768 additions and 562 deletions

View File

@@ -31,6 +31,10 @@ inputs:
description: Include the web UI in the build
required: false
default: "false"
arch:
description: Processor arch name
required: true
default: "esp32"
runs:
using: composite
@@ -84,7 +88,7 @@ runs:
- name: Store binaries as an artifact
uses: actions/upload-artifact@v4
with:
name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip
name: firmware-${{ inputs.arch }}-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip
overwrite: true
path: |
${{ inputs.artifact-paths }}

View File

@@ -11,6 +11,11 @@ runs:
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Uncomment build epoch
shell: bash
run: |
sed -i 's/#-DBUILD_EPOCH=$UNIX_TIME/-DBUILD_EPOCH=$UNIX_TIME/' platformio.ini
- name: Install dependencies
shell: bash
run: |

View File

@@ -31,3 +31,4 @@ jobs:
release/*.bin
release/*.elf
include-web-ui: true
arch: esp32

View File

@@ -32,3 +32,4 @@ jobs:
artifact-paths: |
release/*.bin
release/*.elf
arch: esp32c3

View File

@@ -33,3 +33,4 @@ jobs:
artifact-paths: |
release/*.bin
release/*.elf
arch: esp32c6

View File

@@ -31,3 +31,4 @@ jobs:
release/*.bin
release/*.elf
include-web-ui: true
arch: esp32s3

View File

@@ -25,3 +25,4 @@ jobs:
release/*.uf2
release/*.elf
release/*.zip
arch: nrf52840

View File

@@ -23,3 +23,4 @@ jobs:
artifact-paths: |
release/*.uf2
release/*.elf
arch: rp2040

View File

@@ -23,3 +23,5 @@ jobs:
artifact-paths: |
release/*.hex
release/*.bin
release/*.elf
arch: stm32

View File

@@ -1,10 +1,7 @@
name: CI
concurrency:
group: ${{ github.head_ref || github.run_id }}
group: ci-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
#concurrency:
# group: ${{ github.ref }}
# cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
on:
# # Triggers the workflow on push but only for the master branch
push:
@@ -35,12 +32,12 @@ jobs:
name: Checkout base
- id: jsonStep
run: |
if [[ "${{ github.ref }}" == "refs/heads/master" ]]; then
if [[ "${{ github.head_ref }}" == "" ]]; then
TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}})
else
TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}} quick)
fi
echo "$TARGETS"
echo "Name: ${{ github.ref_name }} Base: ${{ github.base_ref }} Head: ${{ github.head_ref }} Ref: ${{ github.ref }} Targets: $TARGETS"
echo "${{matrix.arch}}=$(jq -cn --argjson environments "$TARGETS" '{board: $environments}')" >> $GITHUB_OUTPUT
outputs:
esp32: ${{ steps.jsonStep.outputs.esp32 }}
@@ -155,8 +152,13 @@ jobs:
permissions:
contents: write
pull-requests: write
strategy:
fail-fast: false
matrix:
arch: [esp32, esp32s3, esp32c3, esp32c6, nrf52840, rp2040, stm32]
runs-on: ubuntu-latest
needs: [
needs:
[
build-esp32,
build-esp32-s3,
build-esp32-c3,
@@ -164,9 +166,6 @@ jobs:
build-nrf52,
build-rpi2040,
build-stm32,
package-raspbian,
package-raspbian-armv7l,
# package-native,
]
steps:
- name: Checkout code
@@ -178,6 +177,7 @@ jobs:
- uses: actions/download-artifact@v4
with:
path: ./
pattern: firmware-${{matrix.arch}}-*
merge-multiple: true
- name: Display structure of downloaded files
@@ -188,12 +188,12 @@ jobs:
id: version
- name: Move files up
run: mv -b -t ./ ./release/meshtasticd_linux_* ./bin/config-dist.yaml ./bin/device-*.sh ./bin/device-*.bat
run: mv -b -t ./ ./bin/device-*.sh ./bin/device-*.bat
- name: Repackage in single firmware zip
uses: actions/upload-artifact@v4
with:
name: firmware-${{ steps.version.outputs.version }}
name: firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}
overwrite: true
path: |
./firmware-*.bin
@@ -202,16 +202,14 @@ jobs:
./firmware-*-ota.zip
./device-*.sh
./device-*.bat
./meshtasticd_linux_*
./config-dist.yaml
./littlefs-*.bin
./bleota*bin
./Meshtastic_nRF52_factory_erase*.uf2
retention-days: 90
retention-days: 30
- uses: actions/download-artifact@v4
with:
name: firmware-${{ steps.version.outputs.version }}
name: firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}
merge-multiple: true
path: ./output
@@ -225,32 +223,34 @@ jobs:
chmod +x ./output/device-update.sh
- name: Zip firmware
run: zip -j -9 -r ./firmware-${{ steps.version.outputs.version }}.zip ./output
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip ./output
- name: Repackage in single elfs zip
uses: actions/upload-artifact@v4
with:
name: debug-elfs-${{ steps.version.outputs.version }}.zip
name: debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
overwrite: true
path: ./*.elf
retention-days: 30
- name: Create request artifacts
continue-on-error: true # FIXME: Why are we getting 502, but things still work?
if: ${{ github.event_name == 'pull_request_target' || github.event_name == 'pull_request' }}
uses: gavv/pull-request-artifacts@v2.1.0
- uses: scruplelesswizard/comment-artifact@main
if: ${{ github.event_name == 'pull_request' }}
with:
commit: ${{ (github.event.pull_request_target || github.event.pull_request).head.sha }}
repo-token: ${{ secrets.GITHUB_TOKEN }}
artifacts-token: ${{ secrets.ARTIFACTS_TOKEN }}
artifacts-repo: meshtastic/artifacts
artifacts-branch: device
artifacts: ./firmware-${{ steps.version.outputs.version }}.zip
name: firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}
description: "Download firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip. This artifact will be available for 90 days from creation"
github-token: ${{ secrets.GITHUB_TOKEN }}
release-artifacts:
runs-on: ubuntu-latest
if: ${{ github.event_name == 'workflow_dispatch' }}
needs: [gather-artifacts]
outputs:
upload_url: ${{ steps.create_release.outputs.upload_url }}
needs: [
gather-artifacts,
package-raspbian,
package-raspbian-armv7l,
# package-native,
]
steps:
- name: Checkout
uses: actions/checkout@v4
@@ -264,36 +264,6 @@ jobs:
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- uses: actions/download-artifact@v4
with:
name: firmware-${{ steps.version.outputs.version }}
merge-multiple: true
path: ./output
- name: Display structure of downloaded files
run: ls -R
- name: Device scripts permissions
run: |
chmod +x ./output/device-install.sh
chmod +x ./output/device-update.sh
- name: Zip firmware
run: zip -j -9 -r ./firmware-${{ steps.version.outputs.version }}.zip ./output -x meshtasticd_*
- uses: actions/download-artifact@v4
with:
name: debug-elfs-${{ steps.version.outputs.version }}.zip
merge-multiple: true
path: ./elfs
- name: Zip Elfs
run: zip -j -9 -r ./debug-elfs-${{ steps.version.outputs.version }}.zip ./elfs
# For diagnostics
- name: Show artifacts
run: ls -lR
- name: Create release
uses: actions/create-release@v1
id: create_release
@@ -307,32 +277,17 @@ jobs:
env:
GITHUB_TOKEN: ${{ github.token }}
- name: Add bins to release
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ github.token }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./firmware-${{ steps.version.outputs.version }}.zip
asset_name: firmware-${{ steps.version.outputs.version }}.zip
asset_content_type: application/zip
- name: Add debug elfs to release
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ github.token }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./debug-elfs-${{ steps.version.outputs.version }}.zip
asset_name: debug-elfs-${{ steps.version.outputs.version }}.zip
asset_content_type: application/zip
- uses: actions/download-artifact@v4
- name: Download deb files
uses: actions/download-artifact@v4
with:
pattern: meshtasticd_${{ steps.version.outputs.version }}_*.deb
merge-multiple: true
path: ./output
# For diagnostics
- name: Display structure of downloaded files
run: ls -lR
- name: Add raspbian aarch64 .deb
uses: actions/upload-release-asset@v1
env:
@@ -374,29 +329,73 @@ jobs:
add-paths: |
version.properties
- name: Checkout meshtastic/meshtastic.github.io
release-firmware:
strategy:
fail-fast: false
matrix:
arch: [esp32, esp32s3, esp32c3, esp32c6, nrf52840, rp2040, stm32]
runs-on: ubuntu-latest
if: ${{ github.event_name == 'workflow_dispatch' }}
needs: [release-artifacts]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
repository: meshtastic/meshtastic.github.io
token: ${{ secrets.ARTIFACTS_TOKEN }}
path: meshtastic.github.io
python-version: 3.x
- name: Get release version string
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- uses: actions/download-artifact@v4
with:
pattern: firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}
merge-multiple: true
path: ./output
- name: Display structure of downloaded files
run: ls -R
run: ls -lR
- name: Extract firmware.zip
- name: Device scripts permissions
run: |
unzip ./firmware-${{ steps.version.outputs.version }}.zip -d meshtastic.github.io/firmware-${{ steps.version.outputs.version }}
chmod +x ./output/device-install.sh
chmod +x ./output/device-update.sh
- name: Zip firmware
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip ./output
- uses: actions/download-artifact@v4
with:
name: debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
merge-multiple: true
path: ./elfs
- name: Zip firmware
run: zip -j -9 -r ./debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip ./elfs
# For diagnostics
- name: Display structure of downloaded files
run: ls -R
run: ls -lR
- name: Commit and push changes
run: |
cd meshtastic.github.io
find . -type f -name 'meshtasticd_*' -exec rm -f {} +
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git add .
git commit -m "Add firmware version ${{ steps.version.outputs.version }}"
git push
- name: Add bins to release
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ github.token }}
with:
upload_url: ${{needs.release-artifacts.outputs.upload_url}}
asset_path: ./firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
asset_name: firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
asset_content_type: application/zip
- name: Add debug elfs to release
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ github.token }}
with:
upload_url: ${{needs.release-artifacts.outputs.upload_url}}
asset_path: ./debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
asset_name: debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
asset_content_type: application/zip

4
.gitignore vendored
View File

@@ -1,6 +1,4 @@
.pio
main/configuration.h
main/credentials.h
# ignore vscode IDE settings files
.vscode/*
@@ -32,4 +30,4 @@ release/
.vscode/extensions.json
/compile_commands.json
src/mesh/raspihttp/certificate.pem
src/mesh/raspihttp/private_key.pem
src/mesh/raspihttp/private_key.pem

View File

@@ -1,14 +1,14 @@
version: 0.1
cli:
version: 1.22.5
version: 1.22.6
plugins:
sources:
- id: trunk
ref: v1.6.2
ref: v1.6.3
uri: https://github.com/trunk-io/plugins
lint:
enabled:
- trufflehog@3.82.5
- trufflehog@3.82.6
- yamllint@1.35.1
- bandit@1.7.10
- checkov@3.2.255
@@ -16,19 +16,19 @@ lint:
- trivy@0.55.2
#- trufflehog@3.63.2-rc0
- taplo@0.9.3
- ruff@0.6.7
- ruff@0.6.8
- isort@5.13.2
- markdownlint@0.42.0
- oxipng@9.1.2
- svgo@3.3.2
- actionlint@1.7.2
- actionlint@1.7.3
- flake8@7.1.1
- hadolint@2.12.0
- shfmt@3.6.0
- shellcheck@0.10.0
- black@24.8.0
- git-diff-check
- gitleaks@8.19.2
- gitleaks@8.19.3
- clang-format@16.0.3
- prettier@3.3.3
ignore:

View File

@@ -2,7 +2,7 @@
[esp32_base]
extends = arduino_base
custom_esp32_kind = esp32
platform = platformio/espressif32@6.7.0
platform = platformio/espressif32@6.9.0
build_src_filter =
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2xx0> -<mesh/eth/> -<mesh/raspihttp>
@@ -46,7 +46,7 @@ lib_deps =
https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2
h2zero/NimBLE-Arduino@^1.4.2
https://github.com/dbSuS/libpax.git#7bcd3fcab75037505be9b122ab2b24cc5176b587
https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
lewisxhe/XPowersLib@^0.2.6
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
rweather/Crypto@^0.4.0

View File

@@ -23,7 +23,7 @@ lib_deps =
${arduino_base.lib_deps}
${networking_base.lib_deps}
${environmental_base.lib_deps}
https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
lewisxhe/XPowersLib@^0.2.6
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
rweather/Crypto@^0.4.0

View File

@@ -24,7 +24,7 @@ lib_deps =
${env.lib_deps}
${networking_base.lib_deps}
rweather/Crypto@^0.4.0
https://github.com/lovyan03/LovyanGFX.git#5a39989aa2c9492572255b22f033843ec8900233
lovyan03/LovyanGFX@^1.1.16
build_flags =
${arduino_base.build_flags}

View File

@@ -7,7 +7,7 @@ platform_packages = framework-arduinopico@https://github.com/earlephilhower/ardu
board_build.core = earlephilhower
board_build.filesystem_size = 0.5m
build_flags =
${arduino_base.build_flags} -Wno-unused-variable
${arduino_base.build_flags} -Wno-unused-variable -Wcast-align
-Isrc/platform/rp2xx0
-D__PLAT_RP2040__
# -D _POSIX_THREADS

View File

@@ -1,7 +1,7 @@
[stm32_base]
extends = arduino_base
platform = ststm32
platform_packages = platformio/framework-arduinoststm32@https://github.com/stm32duino/Arduino_Core_STM32.git#361a7fdb67e2a7104e99b4f42a802469eef8b129
platform_packages = platformio/framework-arduinoststm32@https://github.com/stm32duino/Arduino_Core_STM32.git#ea74156acd823b6d14739f389e6cdc648f8ee36e
build_type = release
@@ -33,5 +33,5 @@ lib_deps =
https://github.com/caveman99/Crypto.git#f61ae26a53f7a2d0ba5511625b8bf8eff3a35d5e
lib_ignore =
https://github.com/mathertel/OneButton@~2.6.1
mathertel/OneButton@~2.6.1
Wire

View File

@@ -60,44 +60,42 @@ build_flags = -Wno-missing-field-initializers
-DUSE_THREAD_NAMES
-DTINYGPS_OPTION_NO_CUSTOM_FIELDS
-DPB_ENABLE_MALLOC=1
-DRADIOLIB_EXCLUDE_CC1101
-DRADIOLIB_EXCLUDE_NRF24
-DRADIOLIB_EXCLUDE_RF69
-DRADIOLIB_EXCLUDE_SX1231
-DRADIOLIB_EXCLUDE_SX1233
-DRADIOLIB_EXCLUDE_SI443X
-DRADIOLIB_EXCLUDE_RFM2X
-DRADIOLIB_EXCLUDE_AFSK
-DRADIOLIB_EXCLUDE_BELL
-DRADIOLIB_EXCLUDE_HELLSCHREIBER
-DRADIOLIB_EXCLUDE_MORSE
-DRADIOLIB_EXCLUDE_RTTY
-DRADIOLIB_EXCLUDE_SSTV
-DRADIOLIB_EXCLUDE_AX25
-DRADIOLIB_EXCLUDE_DIRECT_RECEIVE
-DRADIOLIB_EXCLUDE_BELL
-DRADIOLIB_EXCLUDE_PAGER
-DRADIOLIB_EXCLUDE_FSK4
-DRADIOLIB_EXCLUDE_APRS
-DRADIOLIB_EXCLUDE_LORAWAN
-DRADIOLIB_EXCLUDE_CC1101=1
-DRADIOLIB_EXCLUDE_NRF24=1
-DRADIOLIB_EXCLUDE_RF69=1
-DRADIOLIB_EXCLUDE_SX1231=1
-DRADIOLIB_EXCLUDE_SX1233=1
-DRADIOLIB_EXCLUDE_SI443X=1
-DRADIOLIB_EXCLUDE_RFM2X=1
-DRADIOLIB_EXCLUDE_AFSK=1
-DRADIOLIB_EXCLUDE_BELL=1
-DRADIOLIB_EXCLUDE_HELLSCHREIBER=1
-DRADIOLIB_EXCLUDE_MORSE=1
-DRADIOLIB_EXCLUDE_RTTY=1
-DRADIOLIB_EXCLUDE_SSTV=1
-DRADIOLIB_EXCLUDE_AX25=1
-DRADIOLIB_EXCLUDE_DIRECT_RECEIVE=1
-DRADIOLIB_EXCLUDE_BELL=1
-DRADIOLIB_EXCLUDE_PAGER=1
-DRADIOLIB_EXCLUDE_FSK4=1
-DRADIOLIB_EXCLUDE_APRS=1
-DRADIOLIB_EXCLUDE_LORAWAN=1
-DMESHTASTIC_EXCLUDE_DROPZONE=1
-DMESHTASTIC_EXCLUDE_REMOTEHARDWARE=1
-DBUILD_EPOCH=$UNIX_TIME
#-DBUILD_EPOCH=$UNIX_TIME
;-D OLED_PL
monitor_speed = 115200
monitor_filters = direct
lib_deps =
;jgromes/RadioLib@~7.0.0
;7.0.1pre needed for LR1121 support and SX127x CRC Bugfix
https://github.com/jgromes/RadioLib.git#38fc7a97a4c195b7c10aa94215a1c53ec18a56ef
jgromes/RadioLib@~7.0.2
https://github.com/meshtastic/esp8266-oled-ssd1306.git#e16cee124fe26490cb14880c679321ad8ac89c95 ; ESP8266_SSD1306
https://github.com/mathertel/OneButton@~2.6.1 ; OneButton library for non-blocking button debounce
mathertel/OneButton@~2.6.1 ; OneButton library for non-blocking button debounce
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
https://github.com/meshtastic/TinyGPSPlus.git#71a82db35f3b973440044c476d4bcdc673b104f4
https://github.com/meshtastic/ArduinoThread.git#1ae8778c85d0a2a729f989e0b1e7d7c4dc84eef0
nanopb/Nanopb@^0.4.8
nanopb/Nanopb@^0.4.9
erriez/ErriezCRC32@^1.0.1
; Used for the code analysis in PIO Home / Inspect
@@ -130,7 +128,7 @@ lib_deps =
; (not included in native / portduino)
[environmental_base]
lib_deps =
adafruit/Adafruit BusIO@^1.15.0
adafruit/Adafruit BusIO@^1.16.1
adafruit/Adafruit Unified Sensor@^1.1.11
adafruit/Adafruit BMP280 Library@^2.6.8
adafruit/Adafruit BMP085 Library@^1.2.4
@@ -143,9 +141,9 @@ lib_deps =
adafruit/Adafruit SHTC3 Library@^1.0.0
adafruit/Adafruit LPS2X@^2.0.4
adafruit/Adafruit SHT31 Library@^2.2.2
adafruit/Adafruit PM25 AQI Sensor@^1.0.6
adafruit/Adafruit PM25 AQI Sensor@^1.1.1
adafruit/Adafruit MPU6050@^2.2.4
adafruit/Adafruit LIS3DH@^1.2.4
adafruit/Adafruit LIS3DH@^1.3.0
adafruit/Adafruit AHTX0@^2.0.5
adafruit/Adafruit LSM6DS@^4.7.2
adafruit/Adafruit VEML7700 Library@^2.1.6
@@ -159,9 +157,9 @@ lib_deps =
https://github.com/boschsensortec/Bosch-BSEC2-Library#v1.7.2502
boschsensortec/BME68x Sensor Library@^1.1.40407
https://github.com/KodinLanewave/INA3221@^1.0.0
https://github.com/KodinLanewave/INA3221@^1.0.1
lewisxhe/SensorLib@0.2.0
mprograms/QMC5883LCompass@^1.2.0
https://github.com/meshtastic/DFRobot_LarkWeatherStation#dee914270dc7cb3e43fbf034edd85a63a16a12ee
https://github.com/meshtastic/DFRobot_LarkWeatherStation#4de3a9cadef0f6a5220a8a906cf9775b02b0040d
https://github.com/gjelsoe/STK8xxx-Accelerometer.git#v0.1.1

View File

@@ -124,6 +124,11 @@ int32_t ButtonThread::runOnce()
switch (btnEvent) {
case BUTTON_EVENT_PRESSED: {
LOG_BUTTON("press!\n");
// If a nag notification is running, stop it and prevent other actions
if (moduleConfig.external_notification.enabled && (externalNotificationModule->nagCycleCutoff != UINT32_MAX)) {
externalNotificationModule->stopNow();
return 50;
}
#ifdef BUTTON_PIN
if (((config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN) !=
moduleConfig.canned_message.inputbroker_pin_press) ||

View File

@@ -971,7 +971,6 @@ bool Power::axpChipInit()
PMU->enableVbusVoltageMeasure();
PMU->enableBattVoltageMeasure();
LOG_DEBUG("=======================================================================\n");
if (PMU->isChannelAvailable(XPOWERS_DCDC1)) {
LOG_DEBUG("DC1 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC1) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_DCDC1));
@@ -1020,7 +1019,6 @@ bool Power::axpChipInit()
LOG_DEBUG("BLDO2: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO2) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_BLDO2));
}
LOG_DEBUG("=======================================================================\n");
// We can safely ignore this approach for most (or all) boards because MCU turned off
// earlier than battery discharged to 2.6V.

View File

@@ -13,17 +13,17 @@ void AirTime::logAirtime(reportTypes reportType, uint32_t airtime_ms)
{
if (reportType == TX_LOG) {
LOG_DEBUG("AirTime - Packet transmitted : %ums\n", airtime_ms);
LOG_DEBUG("Packet transmitted : %ums\n", airtime_ms);
this->airtimes.periodTX[0] = this->airtimes.periodTX[0] + airtime_ms;
air_period_tx[0] = air_period_tx[0] + airtime_ms;
this->utilizationTX[this->getPeriodUtilHour()] = this->utilizationTX[this->getPeriodUtilHour()] + airtime_ms;
} else if (reportType == RX_LOG) {
LOG_DEBUG("AirTime - Packet received : %ums\n", airtime_ms);
LOG_DEBUG("Packet received : %ums\n", airtime_ms);
this->airtimes.periodRX[0] = this->airtimes.periodRX[0] + airtime_ms;
air_period_rx[0] = air_period_rx[0] + airtime_ms;
} else if (reportType == RX_ALL_LOG) {
LOG_DEBUG("AirTime - Packet received (noise?) : %ums\n", airtime_ms);
LOG_DEBUG("Packet received (noise?) : %ums\n", airtime_ms);
this->airtimes.periodRX_ALL[0] = this->airtimes.periodRX_ALL[0] + airtime_ms;
}

View File

@@ -91,9 +91,9 @@ void GPS::CASChecksum(uint8_t *message, size_t length)
// Iterate over the payload as a series of uint32_t's and
// accumulate the cksum
uint32_t const *payload = (uint32_t *)(message + 6);
for (size_t i = 0; i < (length - 10) / 4; i++) {
uint32_t pl = payload[i];
uint32_t pl = 0;
memcpy(&pl, (message + 6) + (i * sizeof(uint32_t)), sizeof(uint32_t)); // avoid pointer dereference
cksum += pl;
}
@@ -530,23 +530,23 @@ bool GPS::setup()
_serial_gps->write("$PAIR513*3D\r\n"); // save configuration
} else if (gnssModel == GNSS_MODEL_UBLOX6) {
clearBuffer();
SEND_UBX_PACKET(0x06, 0x02, _message_DISABLE_TXT_INFO, "Unable to disable text info messages.\n", 500);
SEND_UBX_PACKET(0x06, 0x39, _message_JAM_6_7, "Unable to enable interference resistance.\n", 500);
SEND_UBX_PACKET(0x06, 0x23, _message_NAVX5, "Unable to configure NAVX5 settings.\n", 500);
SEND_UBX_PACKET(0x06, 0x02, _message_DISABLE_TXT_INFO, "disable text info messages", 500);
SEND_UBX_PACKET(0x06, 0x39, _message_JAM_6_7, "enable interference resistance", 500);
SEND_UBX_PACKET(0x06, 0x23, _message_NAVX5, "configure NAVX5 settings", 500);
// Turn off unwanted NMEA messages, set update rate
SEND_UBX_PACKET(0x06, 0x08, _message_1HZ, "Unable to set GPS update rate.\n", 500);
SEND_UBX_PACKET(0x06, 0x01, _message_GLL, "Unable to disable NMEA GLL.\n", 500);
SEND_UBX_PACKET(0x06, 0x01, _message_GSA, "Unable to Enable NMEA GSA.\n", 500);
SEND_UBX_PACKET(0x06, 0x01, _message_GSV, "Unable to disable NMEA GSV.\n", 500);
SEND_UBX_PACKET(0x06, 0x01, _message_VTG, "Unable to disable NMEA VTG.\n", 500);
SEND_UBX_PACKET(0x06, 0x01, _message_RMC, "Unable to enable NMEA RMC.\n", 500);
SEND_UBX_PACKET(0x06, 0x01, _message_GGA, "Unable to enable NMEA GGA.\n", 500);
SEND_UBX_PACKET(0x06, 0x08, _message_1HZ, "set GPS update rate", 500);
SEND_UBX_PACKET(0x06, 0x01, _message_GLL, "disable NMEA GLL", 500);
SEND_UBX_PACKET(0x06, 0x01, _message_GSA, "enable NMEA GSA", 500);
SEND_UBX_PACKET(0x06, 0x01, _message_GSV, "disable NMEA GSV", 500);
SEND_UBX_PACKET(0x06, 0x01, _message_VTG, "disable NMEA VTG", 500);
SEND_UBX_PACKET(0x06, 0x01, _message_RMC, "enable NMEA RMC", 500);
SEND_UBX_PACKET(0x06, 0x01, _message_GGA, "enable NMEA GGA", 500);
clearBuffer();
SEND_UBX_PACKET(0x06, 0x11, _message_CFG_RXM_ECO, "Unable to enable powersaving ECO mode for Neo-6.\n", 500);
SEND_UBX_PACKET(0x06, 0x3B, _message_CFG_PM2, "Unable to enable powersaving details for GPS.\n", 500);
SEND_UBX_PACKET(0x06, 0x01, _message_AID, "Unable to disable UBX-AID.\n", 500);
SEND_UBX_PACKET(0x06, 0x11, _message_CFG_RXM_ECO, "enable powersaving ECO mode for Neo-6", 500);
SEND_UBX_PACKET(0x06, 0x3B, _message_CFG_PM2, "enable powersaving details for GPS", 500);
SEND_UBX_PACKET(0x06, 0x01, _message_AID, "disable UBX-AID", 500);
msglen = makeUBXPacket(0x06, 0x09, sizeof(_message_SAVE), _message_SAVE);
_serial_gps->write(UBXscratch, msglen);
@@ -567,7 +567,7 @@ bool GPS::setup()
if (getACK(0x06, 0x3e, 800) == GNSS_RESPONSE_NAK) {
// It's not critical if the module doesn't acknowledge this configuration.
LOG_INFO("Unable to reconfigure GNSS - defaults maintained. Is this module GPS-only?\n");
LOG_INFO("reconfigure GNSS - defaults maintained. Is this module GPS-only?\n");
} else {
if (gnssModel == GNSS_MODEL_UBLOX7) {
LOG_INFO("GNSS configured for GPS+SBAS.\n");
@@ -581,40 +581,40 @@ bool GPS::setup()
// Disable Text Info messages //6,7,8,9
clearBuffer();
SEND_UBX_PACKET(0x06, 0x02, _message_DISABLE_TXT_INFO, "Unable to disable text info messages.\n", 500);
SEND_UBX_PACKET(0x06, 0x02, _message_DISABLE_TXT_INFO, "disable text info messages", 500);
if (gnssModel == GNSS_MODEL_UBLOX8) { // 8
clearBuffer();
SEND_UBX_PACKET(0x06, 0x39, _message_JAM_8, "Unable to enable interference resistance.\n", 500);
SEND_UBX_PACKET(0x06, 0x39, _message_JAM_8, "enable interference resistance", 500);
clearBuffer();
SEND_UBX_PACKET(0x06, 0x23, _message_NAVX5_8, "Unable to configure NAVX5_8 settings.\n", 500);
SEND_UBX_PACKET(0x06, 0x23, _message_NAVX5_8, "configure NAVX5_8 settings", 500);
} else { // 6,7,9
SEND_UBX_PACKET(0x06, 0x39, _message_JAM_6_7, "Unable to enable interference resistance.\n", 500);
SEND_UBX_PACKET(0x06, 0x23, _message_NAVX5, "Unable to configure NAVX5 settings.\n", 500);
SEND_UBX_PACKET(0x06, 0x39, _message_JAM_6_7, "enable interference resistance", 500);
SEND_UBX_PACKET(0x06, 0x23, _message_NAVX5, "configure NAVX5 settings", 500);
}
// Turn off unwanted NMEA messages, set update rate
SEND_UBX_PACKET(0x06, 0x08, _message_1HZ, "Unable to set GPS update rate.\n", 500);
SEND_UBX_PACKET(0x06, 0x01, _message_GLL, "Unable to disable NMEA GLL.\n", 500);
SEND_UBX_PACKET(0x06, 0x01, _message_GSA, "Unable to Enable NMEA GSA.\n", 500);
SEND_UBX_PACKET(0x06, 0x01, _message_GSV, "Unable to disable NMEA GSV.\n", 500);
SEND_UBX_PACKET(0x06, 0x01, _message_VTG, "Unable to disable NMEA VTG.\n", 500);
SEND_UBX_PACKET(0x06, 0x01, _message_RMC, "Unable to enable NMEA RMC.\n", 500);
SEND_UBX_PACKET(0x06, 0x01, _message_GGA, "Unable to enable NMEA GGA.\n", 500);
SEND_UBX_PACKET(0x06, 0x08, _message_1HZ, "set GPS update rate", 500);
SEND_UBX_PACKET(0x06, 0x01, _message_GLL, "disable NMEA GLL", 500);
SEND_UBX_PACKET(0x06, 0x01, _message_GSA, "enable NMEA GSA", 500);
SEND_UBX_PACKET(0x06, 0x01, _message_GSV, "disable NMEA GSV", 500);
SEND_UBX_PACKET(0x06, 0x01, _message_VTG, "disable NMEA VTG", 500);
SEND_UBX_PACKET(0x06, 0x01, _message_RMC, "enable NMEA RMC", 500);
SEND_UBX_PACKET(0x06, 0x01, _message_GGA, "enable NMEA GGA", 500);
if (uBloxProtocolVersion >= 18) {
clearBuffer();
SEND_UBX_PACKET(0x06, 0x86, _message_PMS, "Unable to enable powersaving for GPS.\n", 500);
SEND_UBX_PACKET(0x06, 0x3B, _message_CFG_PM2, "Unable to enable powersaving details for GPS.\n", 500);
SEND_UBX_PACKET(0x06, 0x86, _message_PMS, "enable powersaving for GPS", 500);
SEND_UBX_PACKET(0x06, 0x3B, _message_CFG_PM2, "enable powersaving details for GPS", 500);
// For M8 we want to enable NMEA vserion 4.10 so we can see the additional sats.
if (gnssModel == GNSS_MODEL_UBLOX8) {
clearBuffer();
SEND_UBX_PACKET(0x06, 0x17, _message_NMEA, "Unable to enable NMEA 4.10.\n", 500);
SEND_UBX_PACKET(0x06, 0x17, _message_NMEA, "enable NMEA 4.10", 500);
}
} else {
SEND_UBX_PACKET(0x06, 0x11, _message_CFG_RXM_PSM, "Unable to enable powersaving mode for GPS.\n", 500);
SEND_UBX_PACKET(0x06, 0x3B, _message_CFG_PM2, "Unable to enable powersaving details for GPS.\n", 500);
SEND_UBX_PACKET(0x06, 0x11, _message_CFG_RXM_PSM, "enable powersaving mode for GPS", 500);
SEND_UBX_PACKET(0x06, 0x3B, _message_CFG_PM2, "enable powersaving details for GPS", 500);
}
msglen = makeUBXPacket(0x06, 0x09, sizeof(_message_SAVE), _message_SAVE);
@@ -627,40 +627,38 @@ bool GPS::setup()
} else if (gnssModel == GNSS_MODEL_UBLOX10) {
delay(1000);
clearBuffer();
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_NMEA_RAM, "Unable to disable NMEA messages in M10 RAM.\n", 300);
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_NMEA_RAM, "disable NMEA messages in M10 RAM", 300);
delay(750);
clearBuffer();
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_NMEA_BBR, "Unable to disable NMEA messages in M10 BBR.\n", 300);
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_NMEA_BBR, "disable NMEA messages in M10 BBR", 300);
delay(750);
clearBuffer();
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_TXT_INFO_RAM,
"Unable to disable Info messages for M10 GPS RAM.\n", 300);
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_TXT_INFO_RAM, "disable Info messages for M10 GPS RAM", 300);
delay(750);
// Next disable Info txt messages in BBR layer
clearBuffer();
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_TXT_INFO_BBR,
"Unable to disable Info messages for M10 GPS BBR.\n", 300);
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_TXT_INFO_BBR, "disable Info messages for M10 GPS BBR", 300);
delay(750);
// Do M10 configuration for Power Management.
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_PM_RAM, "Unable to enable powersaving for M10 GPS RAM.\n", 300);
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_PM_RAM, "enable powersaving for M10 GPS RAM", 300);
delay(750);
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_PM_BBR, "Unable to enable powersaving for M10 GPS BBR.\n", 300);
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_PM_BBR, "enable powersaving for M10 GPS BBR", 300);
delay(750);
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_ITFM_RAM, "Unable to enable Jamming detection M10 GPS RAM.\n", 300);
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_ITFM_RAM, "enable Jamming detection M10 GPS RAM", 300);
delay(750);
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_ITFM_BBR, "Unable to enable Jamming detection M10 GPS BBR.\n", 300);
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_ITFM_BBR, "enable Jamming detection M10 GPS BBR", 300);
delay(750);
// Here is where the init commands should go to do further M10 initialization.
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_SBAS_RAM, "Unable to disable SBAS M10 GPS RAM.\n", 300);
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_SBAS_RAM, "disable SBAS M10 GPS RAM", 300);
delay(750); // will cause a receiver restart so wait a bit
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_SBAS_BBR, "Unable to disable SBAS M10 GPS BBR.\n", 300);
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_SBAS_BBR, "disable SBAS M10 GPS BBR", 300);
delay(750); // will cause a receiver restart so wait a bit
// Done with initialization, Now enable wanted NMEA messages in BBR layer so they will survive a periodic sleep.
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_ENABLE_NMEA_BBR, "Unable to enable messages for M10 GPS BBR.\n", 300);
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_ENABLE_NMEA_BBR, "enable messages for M10 GPS BBR", 300);
delay(750);
// Next enable wanted NMEA messages in RAM layer
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_ENABLE_NMEA_RAM, "Unable to enable messages for M10 GPS RAM.\n", 500);
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_ENABLE_NMEA_RAM, "enable messages for M10 GPS RAM", 500);
delay(750);
// As the M10 has no flash, the best we can do to preserve the config is to set it in RAM and BBR.
@@ -1073,12 +1071,15 @@ int GPS::prepareDeepSleep(void *unused)
return 0;
}
const char *PROBE_MESSAGE = "Trying %s (%s)...\n";
const char *DETECTED_MESSAGE = "%s detected, using %s Module\n";
#define PROBE_SIMPLE(CHIP, TOWRITE, RESPONSE, DRIVER, TIMEOUT, ...) \
LOG_DEBUG("Trying " TOWRITE " (" CHIP ") ...\n"); \
LOG_DEBUG(PROBE_MESSAGE, TOWRITE, CHIP); \
clearBuffer(); \
_serial_gps->write(TOWRITE "\r\n"); \
if (getACK(RESPONSE, TIMEOUT) == GNSS_RESPONSE_OK) { \
LOG_INFO(CHIP " detected, using " #DRIVER " Module\n"); \
LOG_INFO(DETECTED_MESSAGE, CHIP, #DRIVER); \
return DRIVER; \
}
@@ -1367,21 +1368,21 @@ bool GPS::factoryReset()
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1C, 0xA2};
_serial_gps->write(_message_reset1, sizeof(_message_reset1));
if (getACK(0x05, 0x01, 10000)) {
LOG_INFO("Get ack success!\n");
LOG_INFO(ACK_SUCCESS_MESSAGE);
}
delay(100);
byte _message_reset2[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1B, 0xA1};
_serial_gps->write(_message_reset2, sizeof(_message_reset2));
if (getACK(0x05, 0x01, 10000)) {
LOG_INFO("Get ack success!\n");
LOG_INFO(ACK_SUCCESS_MESSAGE);
}
delay(100);
byte _message_reset3[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0x1D, 0xB3};
_serial_gps->write(_message_reset3, sizeof(_message_reset3));
if (getACK(0x05, 0x01, 10000)) {
LOG_INFO("Get ack success!\n");
LOG_INFO(ACK_SUCCESS_MESSAGE);
}
// Reset device ram to COLDSTART state
// byte _message_CFG_RST_COLDSTART[] = {0xB5, 0x62, 0x06, 0x04, 0x04, 0x00, 0xFF, 0xB9, 0x00, 0x00, 0xC6, 0x8B};

View File

@@ -156,6 +156,8 @@ class GPS : private concurrency::OSThread
static const uint8_t _message_CAS_CFG_NAVX_CONF[];
static const uint8_t _message_CAS_CFG_RATE_1HZ[];
const char *ACK_SUCCESS_MESSAGE = "Get ack success!\n";
meshtastic_Position p = meshtastic_Position_init_default;
/** This is normally bound to config.position.gps_en_gpio but some rare boards (like heltec tracker) need more advanced

View File

@@ -75,10 +75,13 @@ uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_Position &pos, const
uint32_t printGGA(char *buf, size_t bufsz, const meshtastic_Position &pos)
{
GeoCoord geoCoord(pos.latitude_i, pos.longitude_i, pos.altitude);
tm *t = gmtime((time_t *)&pos.timestamp);
time_t timestamp = pos.timestamp;
tm *t = gmtime(&timestamp);
if (getRTCQuality() > 0) { // use the device clock if we got time from somewhere. If not, use the GPS timestamp.
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice);
t = gmtime((time_t *)&rtc_sec);
timestamp = rtc_sec;
t = gmtime(&timestamp);
}
uint32_t len = snprintf(

View File

@@ -1,8 +1,10 @@
const char *failMessage = "Unable to %s\n";
#define SEND_UBX_PACKET(TYPE, ID, DATA, ERRMSG, TIMEOUT) \
msglen = makeUBXPacket(TYPE, ID, sizeof(DATA), DATA); \
_serial_gps->write(UBXscratch, msglen); \
if (getACK(TYPE, ID, TIMEOUT) != GNSS_RESPONSE_OK) { \
LOG_WARN(#ERRMSG); \
LOG_WARN(failMessage, #ERRMSG); \
}
// Power Management

View File

@@ -163,8 +163,8 @@ static void drawIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDispl
display->setFont(FONT_MEDIUM);
display->setTextAlignment(TEXT_ALIGN_LEFT);
#ifdef SPLASH_TITLE_USERPREFS
const char *title = SPLASH_TITLE_USERPREFS;
#ifdef USERPREFS_SPLASH_TITLE
const char *title = USERPREFS_SPLASH_TITLE;
#else
const char *title = "meshtastic.org";
#endif
@@ -1097,8 +1097,8 @@ static void drawNodes(OLEDDisplay *display, int16_t x, int16_t y, const NodeStat
{
char usersString[20];
snprintf(usersString, sizeof(usersString), "%d/%d", nodeStatus->getNumOnline(), nodeStatus->getNumTotal());
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || defined(ST7789_CS) || \
defined(USE_ST7789) || defined(HX8357_CS)) && \
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS)) && \
!defined(DISPLAY_FORCE_SMALL_FONTS)
display->drawFastImage(x, y + 3, 8, 8, imgUser);
#else
@@ -1534,8 +1534,8 @@ Screen::Screen(ScanI2C::DeviceAddress address, meshtastic_Config_DisplayConfig_O
#elif defined(USE_SSD1306)
dispdev = new SSD1306Wire(address.address, -1, -1, geometry,
(address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE);
#elif defined(ST7735_CS) || defined(ILI9341_DRIVER) || defined(ST7701_CS) || defined(ST7789_CS) || defined(RAK14014) || \
defined(HX8357_CS)
#elif defined(ST7735_CS) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7789_CS) || \
defined(RAK14014) || defined(HX8357_CS)
dispdev = new TFTDisplay(address.address, -1, -1, geometry,
(address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE);
#elif defined(USE_EINK) && !defined(USE_EINK_DYNAMICDISPLAY)
@@ -1732,8 +1732,8 @@ void Screen::setup()
// Standard behaviour is to FLIP the screen (needed on T-Beam). If this config item is set, unflip it, and thereby logically
// flip it. If you have a headache now, you're welcome.
if (!config.display.flip_screen) {
#if defined(ST7701_CS) || defined(ST7735_CS) || defined(ILI9341_DRIVER) || defined(ST7701_CS) || defined(ST7789_CS) || \
defined(RAK14014) || defined(HX8357_CS)
#if defined(ST7701_CS) || defined(ST7735_CS) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || \
defined(ST7789_CS) || defined(RAK14014) || defined(HX8357_CS)
static_cast<TFTDisplay *>(dispdev)->flipScreenVertically();
#elif defined(USE_ST7789)
static_cast<ST7789Spi *>(dispdev)->flipScreenVertically();
@@ -1884,13 +1884,7 @@ int32_t Screen::runOnce()
handleSetOn(false);
break;
case Cmd::ON_PRESS:
// If a nag notification is running, stop it
if (moduleConfig.external_notification.enabled && (externalNotificationModule->nagCycleCutoff != UINT32_MAX)) {
externalNotificationModule->stopNow();
} else {
// Don't advance the screen if we just wanted to switch off the nag notification
handleOnPress();
}
handleOnPress();
break;
case Cmd::SHOW_PREV_FRAME:
handleShowPrevFrame();
@@ -2478,8 +2472,8 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
#ifdef ARCH_ESP32
if (!Throttle::isWithinTimespanMs(storeForwardModule->lastHeartbeat,
(storeForwardModule->heartbeatInterval * 1200))) { // no heartbeat, overlap a bit
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || defined(ST7789_CS) || \
defined(USE_ST7789) || defined(HX8357_CS)) && \
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS) || ARCH_PORTDUINO) && \
!defined(DISPLAY_FORCE_SMALL_FONTS)
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8,
imgQuestionL1);
@@ -2490,8 +2484,8 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
imgQuestion);
#endif
} else {
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || defined(ST7789_CS) || \
defined(USE_ST7789) || defined(HX8357_CS)) && \
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS)) && \
!defined(DISPLAY_FORCE_SMALL_FONTS)
display->drawFastImage(x + SCREEN_WIDTH - 18 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 16, 8,
imgSFL1);
@@ -2505,8 +2499,8 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
#endif
} else {
// TODO: Raspberry Pi supports more than just the one screen size
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || defined(ST7789_CS) || \
defined(USE_ST7789) || defined(HX8357_CS) || ARCH_PORTDUINO) && \
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS) || ARCH_PORTDUINO) && \
!defined(DISPLAY_FORCE_SMALL_FONTS)
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8,
imgInfoL1);
@@ -2823,4 +2817,4 @@ int Screen::handleAdminMessage(const meshtastic_AdminMessage *arg)
} // namespace graphics
#else
graphics::Screen::Screen(ScanI2C::DeviceAddress, meshtastic_Config_DisplayConfig_OledType, OLEDDISPLAY_GEOMETRY) {}
#endif // HAS_SCREEN
#endif // HAS_SCREEN

View File

@@ -12,8 +12,8 @@
#include "graphics/fonts/OLEDDisplayFontsUA.h"
#endif
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || defined(ST7789_CS) || \
defined(USE_ST7789) || defined(HX8357_CS)) && \
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS)) && \
!defined(DISPLAY_FORCE_SMALL_FONTS)
// The screen is bigger so use bigger fonts
#define FONT_SMALL ArialMT_Plain_16 // Height: 19
@@ -41,4 +41,4 @@
#define FONT_HEIGHT_SMALL _fontHeight(FONT_SMALL)
#define FONT_HEIGHT_MEDIUM _fontHeight(FONT_MEDIUM)
#define FONT_HEIGHT_LARGE _fontHeight(FONT_LARGE)
#define FONT_HEIGHT_LARGE _fontHeight(FONT_LARGE)

View File

@@ -244,9 +244,9 @@ class LGFX : public lgfx::LGFX_Device
static LGFX *tft = nullptr;
#elif defined(ILI9341_DRIVER)
#elif defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER)
#include <LovyanGFX.hpp> // Graphics and font library for ILI9341 driver chip
#include <LovyanGFX.hpp> // Graphics and font library for ILI9341/ILI9342 driver chip
#if defined(ILI9341_BACKLIGHT_EN) && !defined(TFT_BL)
#define TFT_BL ILI9341_BACKLIGHT_EN
@@ -254,7 +254,11 @@ static LGFX *tft = nullptr;
class LGFX : public lgfx::LGFX_Device
{
#if defined(ILI9341_DRIVER)
lgfx::Panel_ILI9341 _panel_instance;
#elif defined(ILI9342_DRIVER)
lgfx::Panel_ILI9342 _panel_instance;
#endif
lgfx::Bus_SPI _bus_instance;
lgfx::Light_PWM _light_instance;
@@ -265,7 +269,11 @@ class LGFX : public lgfx::LGFX_Device
auto cfg = _bus_instance.config();
// configure SPI
#if defined(ILI9341_DRIVER)
cfg.spi_host = ILI9341_SPI_HOST; // ESP32-S2,S3,C3 : SPI2_HOST or SPI3_HOST / ESP32 : VSPI_HOST or HSPI_HOST
#elif defined(ILI9342_DRIVER)
cfg.spi_host = ILI9342_SPI_HOST; // ESP32-S2,S3,C3 : SPI2_HOST or SPI3_HOST / ESP32 : VSPI_HOST or HSPI_HOST
#endif
cfg.spi_mode = 0;
cfg.freq_write = SPI_FREQUENCY; // SPI clock for transmission (up to 80MHz, rounded to the value obtained by dividing
// 80MHz by an integer)
@@ -336,7 +344,7 @@ class LGFX : public lgfx::LGFX_Device
static LGFX *tft = nullptr;
#elif defined(ST7735_CS)
#include <TFT_eSPI.h> // Graphics and font library for ILI9341 driver chip
#include <TFT_eSPI.h> // Graphics and font library for ILI9342 driver chip
static TFT_eSPI *tft = nullptr; // Invoke library, pins defined in User_Setup.h
#elif ARCH_PORTDUINO && HAS_SCREEN != 0
@@ -360,6 +368,8 @@ class LGFX : public lgfx::LGFX_Device
_panel_instance = new lgfx::Panel_ST7735S;
else if (settingsMap[displayPanel] == ili9341)
_panel_instance = new lgfx::Panel_ILI9341;
else if (settingsMap[displayPanel] == ili9342)
_panel_instance = new lgfx::Panel_ILI9342;
auto buscfg = _bus_instance.config();
buscfg.spi_mode = 0;
buscfg.spi_host = settingsMap[displayspidev];
@@ -618,8 +628,8 @@ static LGFX *tft = nullptr;
#endif
#if defined(ST7701_CS) || defined(ST7735_CS) || defined(ST7789_CS) || defined(ILI9341_DRIVER) || defined(RAK14014) || \
defined(HX8357_CS) || (ARCH_PORTDUINO && HAS_SCREEN != 0)
#if defined(ST7701_CS) || defined(ST7735_CS) || defined(ST7789_CS) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || \
defined(RAK14014) || defined(HX8357_CS) || (ARCH_PORTDUINO && HAS_SCREEN != 0)
#include "SPILock.h"
#include "TFTDisplay.h"
#include <SPI.h>
@@ -850,4 +860,4 @@ bool TFTDisplay::connect()
return true;
}
#endif
#endif

View File

@@ -20,8 +20,8 @@ const uint8_t bluetoothConnectedIcon[36] PROGMEM = {0xfe, 0x01, 0xff, 0x03, 0x03
0xfe, 0x31, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0xf0, 0x3f, 0xe0, 0x1f};
#endif
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || defined(ST7789_CS) || \
defined(USE_ST7789) || defined(HX8357_CS) || ARCH_PORTDUINO) && \
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS) || ARCH_PORTDUINO) && \
!defined(DISPLAY_FORCE_SMALL_FONTS)
const uint8_t imgQuestionL1[] PROGMEM = {0xff, 0x01, 0x01, 0x32, 0x7b, 0x49, 0x49, 0x6f, 0x26, 0x01, 0x01, 0xff};
const uint8_t imgQuestionL2[] PROGMEM = {0x0f, 0x08, 0x08, 0x08, 0x06, 0x0f, 0x0f, 0x06, 0x08, 0x08, 0x08, 0x0f};

View File

@@ -1,4 +1,4 @@
#ifndef HAS_USERPREFS_SPLASH
#ifndef USERPREFS_HAS_SPLASH
#define icon_width 50
#define icon_height 28
static uint8_t icon_bits[] = {

View File

@@ -1,3 +1,4 @@
#include "../userPrefs.h"
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_GPS
#include "GPS.h"
@@ -119,6 +120,8 @@ float tcxoVoltage = SX126X_DIO3_TCXO_VOLTAGE; // if TCXO is optional, put this h
using namespace concurrency;
volatile static const char slipstreamTZString[] = USERPREFS_TZ_STRING;
// We always create a screen object, but we only init it if we find the hardware
graphics::Screen *screen = nullptr;
@@ -706,10 +709,16 @@ void setup()
// setup TZ prior to time actions.
#if !MESHTASTIC_EXCLUDE_TZ
if (*config.device.tzdef) {
LOG_DEBUG("Using compiled/slipstreamed %s\n", slipstreamTZString); // important, removing this clobbers our magic string
if (*config.device.tzdef && config.device.tzdef[0] != 0) {
LOG_DEBUG("Saved TZ: %s \n", config.device.tzdef);
setenv("TZ", config.device.tzdef, 1);
} else {
setenv("TZ", "GMT0", 1);
if (strncmp((const char *)slipstreamTZString, "tzpl", 4) == 0) {
setenv("TZ", "GMT0", 1);
} else {
setenv("TZ", (const char *)slipstreamTZString, 1);
}
}
tzset();
LOG_DEBUG("Set Timezone to %s\n", getenv("TZ"));
@@ -766,8 +775,8 @@ void setup()
#if !MESHTASTIC_EXCLUDE_I2C
// Don't call screen setup until after nodedb is setup (because we need
// the current region name)
#if defined(ST7701_CS) || defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7789_CS) || \
defined(HX8357_CS) || defined(USE_ST7789)
#if defined(ST7701_CS) || defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || \
defined(ST7789_CS) || defined(HX8357_CS) || defined(USE_ST7789)
screen->setup();
#elif defined(ARCH_PORTDUINO)
if (screen_found.port != ScanI2C::I2CPort::NO_I2C || settingsMap[displayPanel]) {
@@ -885,7 +894,7 @@ void setup()
}
#endif
#if defined(RF95_IRQ)
#if defined(RF95_IRQ) && RADIOLIB_EXCLUDE_SX127X != 1
if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) {
rIf = new RF95Interface(RadioLibHAL, LORA_CS, RF95_IRQ, RF95_RESET, RF95_DIO1);
if (!rIf->init()) {
@@ -899,7 +908,7 @@ void setup()
}
#endif
#if defined(USE_SX1262) && !defined(ARCH_PORTDUINO) && !defined(TCXO_OPTIONAL)
#if defined(USE_SX1262) && !defined(ARCH_PORTDUINO) && !defined(TCXO_OPTIONAL) && RADIOLIB_EXCLUDE_SX126X != 1
if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) {
rIf = new SX1262Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY);
if (!rIf->init()) {
@@ -975,7 +984,7 @@ void setup()
}
#endif
#if defined(USE_LR1110)
#if defined(USE_LR1110) && RADIOLIB_EXCLUDE_LR11X0 != 1
if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) {
rIf = new LR1110Interface(RadioLibHAL, LR1110_SPI_NSS_PIN, LR1110_IRQ_PIN, LR1110_NRESET_PIN, LR1110_BUSY_PIN);
if (!rIf->init()) {
@@ -989,7 +998,7 @@ void setup()
}
#endif
#if defined(USE_LR1120)
#if defined(USE_LR1120) && RADIOLIB_EXCLUDE_LR11X0 != 1
if (!rIf) {
rIf = new LR1120Interface(RadioLibHAL, LR1120_SPI_NSS_PIN, LR1120_IRQ_PIN, LR1120_NRESET_PIN, LR1120_BUSY_PIN);
if (!rIf->init()) {
@@ -1003,7 +1012,7 @@ void setup()
}
#endif
#if defined(USE_LR1121)
#if defined(USE_LR1121) && RADIOLIB_EXCLUDE_LR11X0 != 1
if (!rIf) {
rIf = new LR1121Interface(RadioLibHAL, LR1121_SPI_NSS_PIN, LR1121_IRQ_PIN, LR1121_NRESET_PIN, LR1121_BUSY_PIN);
if (!rIf->init()) {
@@ -1017,7 +1026,7 @@ void setup()
}
#endif
#if defined(USE_SX1280)
#if defined(USE_SX1280) && RADIOLIB_EXCLUDE_SX128X != 1
if (!rIf) {
rIf = new SX1280Interface(RadioLibHAL, SX128X_CS, SX128X_DIO1, SX128X_RESET, SX128X_BUSY);
if (!rIf->init()) {
@@ -1032,7 +1041,6 @@ void setup()
#endif
// check if the radio chip matches the selected region
if ((config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_LORA_24) && (!rIf->wideLora())) {
LOG_WARN("Radio chip does not support 2.4GHz LoRa. Reverting to unset.\n");
config.lora.region = meshtastic_Config_LoRaConfig_RegionCode_UNSET;
@@ -1159,4 +1167,4 @@ void loop()
mainDelay.delay(delayMsec);
}
}
#endif
#endif

View File

@@ -99,26 +99,26 @@ void Channels::initDefaultChannel(ChannelIndex chIndex)
ch.has_settings = true;
ch.role = meshtastic_Channel_Role_PRIMARY;
#ifdef LORACONFIG_MODEM_PRESET_USERPREFS
loraConfig.modem_preset = LORACONFIG_MODEM_PRESET_USERPREFS;
#ifdef USERPREFS_LORACONFIG_MODEM_PRESET
loraConfig.modem_preset = USERPREFS_LORACONFIG_MODEM_PRESET;
#endif
#ifdef LORACONFIG_CHANNEL_NUM_USERPREFS
loraConfig.channel_num = LORACONFIG_CHANNEL_NUM_USERPREFS;
#ifdef USERPREFS_LORACONFIG_CHANNEL_NUM
loraConfig.channel_num = USERPREFS_LORACONFIG_CHANNEL_NUM;
#endif
// Install custom defaults. Will eventually support setting multiple default channels
if (chIndex == 0) {
#ifdef CHANNEL_0_PSK_USERPREFS
static const uint8_t defaultpsk[] = CHANNEL_0_PSK_USERPREFS;
#ifdef USERPREFS_CHANNEL_0_PSK
static const uint8_t defaultpsk[] = USERPREFS_CHANNEL_0_PSK;
memcpy(channelSettings.psk.bytes, defaultpsk, sizeof(defaultpsk));
channelSettings.psk.size = sizeof(defaultpsk);
#endif
#ifdef CHANNEL_0_NAME_USERPREFS
strcpy(channelSettings.name, CHANNEL_0_NAME_USERPREFS);
#ifdef USERPREFS_CHANNEL_0_NAME
strcpy(channelSettings.name, USERPREFS_CHANNEL_0_NAME);
#endif
#ifdef CHANNEL_0_PRECISION_USERPREFS
channelSettings.module_settings.position_precision = CHANNEL_0_PRECISION_USERPREFS;
#ifdef USERPREFS_CHANNEL_0_PRECISION
channelSettings.module_settings.position_precision = USERPREFS_CHANNEL_0_PRECISION;
#endif
}
}
@@ -273,7 +273,7 @@ void Channels::setChannel(const meshtastic_Channel &c)
bool Channels::anyMqttEnabled()
{
#if EVENT_MODE
#if USERPREFS_EVENT_MODE
// Don't publish messages on the public MQTT broker if we are in event mode
if (strcmp(moduleConfig.mqtt.address, default_mqtt_address) == 0) {
return false;

View File

@@ -66,12 +66,10 @@ bool CryptoEngine::encryptCurve25519(uint32_t toNode, uint32_t fromNode, uint64_
uint8_t *bytesOut)
{
uint8_t *auth;
uint32_t *extraNonce;
long extraNonceTmp = random();
auth = bytesOut + numBytes;
extraNonce = (uint32_t *)(auth + 8);
memcpy(extraNonce, &extraNonceTmp,
4); // do not use dereference on potential non aligned pointers : *extraNonce = extraNonceTmp;
memcpy((uint8_t *)(auth + 8), &extraNonceTmp,
sizeof(uint32_t)); // do not use dereference on potential non aligned pointers : *extraNonce = extraNonceTmp;
LOG_INFO("Random nonce value: %d\n", extraNonceTmp);
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(toNode);
if (node->num < 1 || node->user.public_key.size == 0) {
@@ -88,8 +86,8 @@ bool CryptoEngine::encryptCurve25519(uint32_t toNode, uint32_t fromNode, uint64_
printBytes("Attempting encrypt using shared_key starting with: ", shared_key, 8);
aes_ccm_ae(shared_key, 32, nonce, 8, bytes, numBytes, nullptr, 0, bytesOut,
auth); // this can write up to 15 bytes longer than numbytes past bytesOut
memcpy(extraNonce, &extraNonceTmp,
4); // do not use dereference on potential non aligned pointers : *extraNonce = extraNonceTmp;
memcpy((uint8_t *)(auth + 8), &extraNonceTmp,
sizeof(uint32_t)); // do not use dereference on potential non aligned pointers : *extraNonce = extraNonceTmp;
return true;
}
@@ -104,8 +102,9 @@ bool CryptoEngine::decryptCurve25519(uint32_t fromNode, uint64_t packetNum, size
uint8_t *auth; // set to last 8 bytes of text?
uint32_t extraNonce; // pointer was not really used
auth = bytes + numBytes - 12;
memcpy(&extraNonce, auth + 8,
sizeof(uint32_t)); // do not use dereference on potential non aligned pointers : (uint32_t *)(auth + 8);
#ifndef PIO_UNIT_TESTING
memcpy(&extraNonce, auth + 8, 4); // do not use dereference on potential non aligned pointers : (uint32_t *)(auth + 8);
LOG_INFO("Random nonce value: %d\n", extraNonce);
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(fromNode);

View File

@@ -45,7 +45,7 @@ uint32_t Default::getConfiguredOrDefaultMsScaled(uint32_t configured, uint32_t d
uint8_t Default::getConfiguredOrDefaultHopLimit(uint8_t configured)
{
#if EVENT_MODE
#if USERPREFS_EVENT_MODE
return (configured > HOP_RELIABLE) ? HOP_RELIABLE : config.lora.hop_limit;
#else
return (configured >= HOP_MAX) ? HOP_MAX : config.lora.hop_limit;

View File

@@ -21,11 +21,13 @@ ErrorCode FloodingRouter::send(meshtastic_MeshPacket *p)
bool FloodingRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
{
if (wasSeenRecently(p)) { // Note: this will also add a recent packet record
printPacket("Ignoring incoming msg we've already seen", p);
printPacket("Ignoring dupe incoming msg", p);
rxDupe++;
if (config.device.role != meshtastic_Config_DeviceConfig_Role_ROUTER &&
config.device.role != meshtastic_Config_DeviceConfig_Role_REPEATER) {
// cancel rebroadcast of this message *if* there was already one, unless we're a router/repeater!
Router::cancelSending(p->from, p->id);
if (Router::cancelSending(p->from, p->id))
txRelayCanceled++;
}
return true;
}
@@ -36,18 +38,18 @@ bool FloodingRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
void FloodingRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtastic_Routing *c)
{
bool isAckorReply = (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) && (p->decoded.request_id != 0);
if (isAckorReply && p->to != getNodeNum() && p->to != NODENUM_BROADCAST) {
if (isAckorReply && !isToUs(p) && p->to != NODENUM_BROADCAST) {
// do not flood direct message that is ACKed or replied to
LOG_DEBUG("Receiving an ACK or reply not for me, but don't need to rebroadcast this direct message anymore.\n");
LOG_DEBUG("Rxd an ACK/reply not for me, cancel rebroadcast.\n");
Router::cancelSending(p->to, p->decoded.request_id); // cancel rebroadcast for this DM
}
if ((p->to != getNodeNum()) && (p->hop_limit > 0) && (getFrom(p) != getNodeNum())) {
if (!isToUs(p) && (p->hop_limit > 0) && !isFromUs(p)) {
if (p->id != 0) {
if (config.device.role != meshtastic_Config_DeviceConfig_Role_CLIENT_MUTE) {
meshtastic_MeshPacket *tosend = packetPool.allocCopy(*p); // keep a copy because we will be sending it
tosend->hop_limit--; // bump down the hop count
#if EVENT_MODE
#if USERPREFS_EVENT_MODE
if (tosend->hop_limit > 2) {
// if we are "correcting" the hop_limit, "correct" the hop_start by the same amount to preserve hops away.
tosend->hop_start -= (tosend->hop_limit - 2);
@@ -55,7 +57,7 @@ void FloodingRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtas
}
#endif
LOG_INFO("Rebroadcasting received floodmsg to neighbors\n");
LOG_INFO("Rebroadcasting received floodmsg\n");
// Note: we are careful to resend using the original senders node id
// We are careful not to call our hooked version of send() - because we don't want to check this again
Router::send(tosend);
@@ -63,7 +65,7 @@ void FloodingRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtas
LOG_DEBUG("Not rebroadcasting. Role = Role_ClientMute\n");
}
} else {
LOG_DEBUG("Ignoring a simple (0 id) broadcast\n");
LOG_DEBUG("Ignoring 0 id broadcast\n");
}
}
// handle the packet as normal

View File

@@ -8,13 +8,19 @@
#include "api/ServerAPI.h"
// We need this declaration for proper linking in derived classes
#if RADIOLIB_EXCLUDE_SX126X != 1
template class SX126xInterface<SX1262>;
template class SX126xInterface<SX1268>;
template class SX126xInterface<LLCC68>;
#endif
#if RADIOLIB_EXCLUDE_SX128X != 1
template class SX128xInterface<SX1280>;
#endif
#if RADIOLIB_EXCLUDE_LR11X0 != 1
template class LR11x0Interface<LR1110>;
template class LR11x0Interface<LR1120>;
template class LR11x0Interface<LR1121>;
#endif
#ifdef ARCH_STM32WL
template class SX126xInterface<STM32WLx>;
#endif

View File

@@ -1,3 +1,4 @@
#if RADIOLIB_EXCLUDE_SX126X != 1
#include "LLCC68Interface.h"
#include "configuration.h"
#include "error.h"
@@ -6,4 +7,5 @@ LLCC68Interface::LLCC68Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, R
RADIOLIB_PIN_TYPE busy)
: SX126xInterface(hal, cs, irq, rst, busy)
{
}
}
#endif

View File

@@ -1,5 +1,5 @@
#pragma once
#if RADIOLIB_EXCLUDE_SX126X != 1
#include "SX126xInterface.h"
/**
@@ -15,4 +15,5 @@ class LLCC68Interface : public SX126xInterface<LLCC68>
public:
LLCC68Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst,
RADIOLIB_PIN_TYPE busy);
};
};
#endif

View File

@@ -1,3 +1,5 @@
#if RADIOLIB_EXCLUDE_LR11X0 != 1
#include "LR1110Interface.h"
#include "configuration.h"
#include "error.h"
@@ -6,4 +8,5 @@ LR1110Interface::LR1110Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, R
RADIOLIB_PIN_TYPE busy)
: LR11x0Interface(hal, cs, irq, rst, busy)
{
}
}
#endif

View File

@@ -1,5 +1,5 @@
#pragma once
#if RADIOLIB_EXCLUDE_LR11X0 != 1
#include "LR11x0Interface.h"
/**
@@ -10,4 +10,5 @@ class LR1110Interface : public LR11x0Interface<LR1110>
public:
LR1110Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst,
RADIOLIB_PIN_TYPE busy);
};
};
#endif

View File

@@ -1,3 +1,5 @@
#if RADIOLIB_EXCLUDE_LR11X0 != 1
#include "LR1120Interface.h"
#include "configuration.h"
#include "error.h"
@@ -11,4 +13,5 @@ LR1120Interface::LR1120Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, R
bool LR1120Interface::wideLora()
{
return true;
}
}
#endif

View File

@@ -1,7 +1,7 @@
#pragma once
#if RADIOLIB_EXCLUDE_LR11X0 != 1
#include "LR11x0Interface.h"
/**
* Our adapter for LR1120 wideband radios
*/
@@ -11,4 +11,5 @@ class LR1120Interface : public LR11x0Interface<LR1120>
LR1120Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst,
RADIOLIB_PIN_TYPE busy);
bool wideLora() override;
};
};
#endif

View File

@@ -1,3 +1,4 @@
#if RADIOLIB_EXCLUDE_LR11X0 != 1
#include "LR1121Interface.h"
#include "configuration.h"
#include "error.h"
@@ -11,4 +12,5 @@ LR1121Interface::LR1121Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, R
bool LR1121Interface::wideLora()
{
return true;
}
}
#endif

View File

@@ -1,4 +1,5 @@
#pragma once
#if RADIOLIB_EXCLUDE_LR11X0 != 1
#include "LR11x0Interface.h"
@@ -11,4 +12,5 @@ class LR1121Interface : public LR11x0Interface<LR1121>
LR1121Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst,
RADIOLIB_PIN_TYPE busy);
bool wideLora() override;
};
};
#endif

View File

@@ -1,3 +1,4 @@
#if RADIOLIB_EXCLUDE_LR11X0 != 1
#include "LR11x0Interface.h"
#include "Throttle.h"
#include "configuration.h"
@@ -284,4 +285,5 @@ template <typename T> bool LR11x0Interface<T>::sleep()
#endif
return true;
}
}
#endif

View File

@@ -1,5 +1,5 @@
#pragma once
#if RADIOLIB_EXCLUDE_LR11X0 != 1
#include "RadioLibInterface.h"
/**
@@ -66,3 +66,4 @@ template <class T> class LR11x0Interface : public RadioLibInterface
virtual void setStandby() override;
};
#endif

View File

@@ -86,7 +86,7 @@ void MeshModule::callModules(meshtastic_MeshPacket &mp, RxSource src)
// Was this message directed to us specifically? Will be false if we are sniffing someone elses packets
auto ourNodeNum = nodeDB->getNodeNum();
bool toUs = mp.to == NODENUM_BROADCAST || mp.to == ourNodeNum;
bool toUs = mp.to == NODENUM_BROADCAST || isToUs(&mp);
for (auto i = modules->begin(); i != modules->end(); ++i) {
auto &pi = **i;
@@ -141,8 +141,7 @@ void MeshModule::callModules(meshtastic_MeshPacket &mp, RxSource src)
// because currently when the phone sends things, it sends things using the local node ID as the from address. A
// better solution (FIXME) would be to let phones have their own distinct addresses and we 'route' to them like
// any other node.
if (isDecoded && mp.decoded.want_response && toUs && (getFrom(&mp) != ourNodeNum || mp.to == ourNodeNum) &&
!currentReply) {
if (isDecoded && mp.decoded.want_response && toUs && (!isFromUs(&mp) || isToUs(&mp)) && !currentReply) {
pi.sendResponse(mp);
ignoreRequest = ignoreRequest || pi.ignoreRequest; // If at least one module asks it, we may ignore a request
LOG_INFO("Asked module '%s' to send a response\n", pi.name);

View File

@@ -19,7 +19,7 @@ bool CompareMeshPacketFunc(const meshtastic_MeshPacket *p1, const meshtastic_Mes
auto p1p = getPriority(p1), p2p = getPriority(p2);
// If priorities differ, use that
// for equal priorities, prefer packets already on mesh.
return (p1p != p2p) ? (p1p > p2p) : (getFrom(p1) != nodeDB->getNodeNum() && getFrom(p2) == nodeDB->getNodeNum());
return (p1p != p2p) ? (p1p > p2p) : (!isFromUs(p1) && isFromUs(p2));
}
MeshPacketQueue::MeshPacketQueue(size_t _maxLen) : maxLen(_maxLen) {}

View File

@@ -80,12 +80,11 @@ int MeshService::handleFromRadio(const meshtastic_MeshPacket *mp)
nodeDB->updateFrom(*mp); // update our DB state based off sniffing every RX packet from the radio
if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag &&
mp->decoded.portnum == meshtastic_PortNum_TELEMETRY_APP && mp->decoded.request_id > 0) {
LOG_DEBUG(
"Received telemetry response. Skip sending our NodeInfo because this potentially a Repeater which will ignore our "
"request for its NodeInfo.\n");
LOG_DEBUG("Received telemetry response. Skip sending our NodeInfo.\n"); // because this potentially a Repeater which will
// ignore our request for its NodeInfo
} else if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag && !nodeDB->getMeshNode(mp->from)->has_user &&
nodeInfoModule) {
LOG_INFO("Heard a node on channel %d we don't know, sending NodeInfo and asking for a response.\n", mp->channel);
LOG_INFO("Heard new node on channel %d, sending NodeInfo and asking for a response.\n", mp->channel);
if (airTime->isTxAllowedChannelUtil(true)) {
nodeInfoModule->sendOurNodeInfo(mp->from, true, mp->channel);
} else {
@@ -223,7 +222,7 @@ ErrorCode MeshService::sendQueueStatusToPhone(const meshtastic_QueueStatus &qs,
copied->mesh_packet_id = mesh_packet_id;
if (toPhoneQueueStatusQueue.numFree() == 0) {
LOG_DEBUG("NOTE: tophone queue status queue is full, discarding oldest\n");
LOG_INFO("tophone queue status queue is full, discarding oldest\n");
meshtastic_QueueStatus *d = toPhoneQueueStatusQueue.dequeuePtr(0);
if (d)
releaseQueueStatusToPool(d);
@@ -317,7 +316,7 @@ void MeshService::sendToPhone(meshtastic_MeshPacket *p)
void MeshService::sendMqttMessageToClientProxy(meshtastic_MqttClientProxyMessage *m)
{
LOG_DEBUG("Sending mqtt message on topic '%s' to client for proxying to server\n", m->topic);
LOG_DEBUG("Sending mqtt message on topic '%s' to client for proxy\n", m->topic);
if (toPhoneMqttProxyQueue.numFree() == 0) {
LOG_WARN("MqttClientProxyMessagePool queue is full, discarding oldest\n");
meshtastic_MqttClientProxyMessage *d = toPhoneMqttProxyQueue.dequeuePtr(0);
@@ -407,4 +406,4 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
bool MeshService::isToPhoneQueueEmpty()
{
return toPhoneQueue.isEmpty();
}
}

View File

@@ -50,5 +50,11 @@ extern Allocator<meshtastic_MeshPacket> &packetPool;
*/
NodeNum getFrom(const meshtastic_MeshPacket *p);
// Returns true if the packet originated from the local node
bool isFromUs(const meshtastic_MeshPacket *p);
// Returns true if the packet is destined to us
bool isToUs(const meshtastic_MeshPacket *p);
/* Some clients might not properly set priority, therefore we fix it here. */
void fixPriority(meshtastic_MeshPacket *p);

View File

@@ -132,39 +132,31 @@ NodeDB::NodeDB()
config.security.serial_enabled = config.device.serial_enabled;
config.security.is_managed = config.device.is_managed;
}
#if !(MESHTASTIC_EXCLUDE_PKI)
#if !(MESHTASTIC_EXCLUDE_PKI_KEYGEN || MESHTASTIC_EXCLUDE_PKI)
bool keygenSuccess = false;
if (config.security.private_key.size == 32) {
if (crypto->regeneratePublicKey(config.security.public_key.bytes, config.security.private_key.bytes)) {
keygenSuccess = true;
}
} else {
LOG_INFO("Generating new PKI keys\n");
crypto->generateKeyPair(config.security.public_key.bytes, config.security.private_key.bytes);
keygenSuccess = true;
}
if (keygenSuccess) {
config.security.public_key.size = 32;
config.security.private_key.size = 32;
owner.public_key.size = 32;
memcpy(owner.public_key.bytes, config.security.public_key.bytes, 32);
}
#elif !(MESHTASTIC_EXCLUDE_PKI)
// Calculate Curve25519 public and private keys
printBytes("Old Pubkey", config.security.public_key.bytes, 32);
if (config.security.private_key.size == 32 && config.security.public_key.size == 32) {
LOG_INFO("Using saved PKI keys\n");
owner.public_key.size = config.security.public_key.size;
memcpy(owner.public_key.bytes, config.security.public_key.bytes, config.security.public_key.size);
crypto->setDHPrivateKey(config.security.private_key.bytes);
} else {
#if !(MESHTASTIC_EXCLUDE_PKI_KEYGEN)
bool keygenSuccess = false;
if (config.security.private_key.size == 32) {
LOG_INFO("Calculating PKI Public Key\n");
if (crypto->regeneratePublicKey(config.security.public_key.bytes, config.security.private_key.bytes)) {
keygenSuccess = true;
}
} else {
LOG_INFO("Generating new PKI keys\n");
crypto->generateKeyPair(config.security.public_key.bytes, config.security.private_key.bytes);
keygenSuccess = true;
}
if (keygenSuccess) {
config.security.public_key.size = 32;
config.security.private_key.size = 32;
printBytes("New Pubkey", config.security.public_key.bytes, 32);
owner.public_key.size = 32;
memcpy(owner.public_key.bytes, config.security.public_key.bytes, 32);
}
#else
LOG_INFO("No PKI keys set, and generation disabled!\n");
#endif
}
#endif
info->user = TypeConversions::ConvertToUserLite(owner);
@@ -204,6 +196,18 @@ NodeNum getFrom(const meshtastic_MeshPacket *p)
return (p->from == 0) ? nodeDB->getNodeNum() : p->from;
}
// Returns true if the packet originated from the local node
bool isFromUs(const meshtastic_MeshPacket *p)
{
return p->from == 0 || p->from == nodeDB->getNodeNum();
}
// Returns true if the packet is destined to us
bool isToUs(const meshtastic_MeshPacket *p)
{
return p->to == nodeDB->getNodeNum();
}
bool NodeDB::resetRadioConfig(bool factory_reset)
{
bool didFactoryReset = false;
@@ -294,24 +298,24 @@ void NodeDB::installDefaultConfig(bool preserveKey = false)
true; // FIXME: maybe false in the future, and setting region to enable it. (unset region forces it off)
config.lora.override_duty_cycle = false;
config.lora.config_ok_to_mqtt = false;
#ifdef CONFIG_LORA_REGION_USERPREFS
config.lora.region = CONFIG_LORA_REGION_USERPREFS;
#ifdef USERPREFS_CONFIG_LORA_REGION
config.lora.region = USERPREFS_CONFIG_LORA_REGION;
#else
config.lora.region = meshtastic_Config_LoRaConfig_RegionCode_UNSET;
#endif
#ifdef LORACONFIG_MODEM_PRESET_USERPREFS
config.lora.modem_preset = LORACONFIG_MODEM_PRESET_USERPREFS;
#ifdef USERPREFS_LORACONFIG_MODEM_PRESET
config.lora.modem_preset = USERPREFS_LORACONFIG_MODEM_PRESET;
#else
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST;
#endif
config.lora.hop_limit = HOP_RELIABLE;
#ifdef CONFIG_LORA_IGNORE_MQTT_USERPREFS
config.lora.ignore_mqtt = CONFIG_LORA_IGNORE_MQTT_USERPREFS;
#ifdef USERPREFS_CONFIG_LORA_IGNORE_MQTT
config.lora.ignore_mqtt = USERPREFS_CONFIG_LORA_IGNORE_MQTT;
#else
config.lora.ignore_mqtt = false;
#endif
#ifdef ADMIN_KEY_USERPREFS
memcpy(config.security.admin_key[0].bytes, admin_key_userprefs, 32);
#ifdef USERPREFS_USE_ADMIN_KEY
memcpy(config.security.admin_key[0].bytes, USERPREFS_ADMIN_KEY, 32);
config.security.admin_key[0].size = 32;
#else
config.security.admin_key[0].size = 0;
@@ -354,8 +358,8 @@ void NodeDB::installDefaultConfig(bool preserveKey = false)
// FIXME: Default to bluetooth capability of platform as default
config.bluetooth.enabled = true;
config.bluetooth.fixed_pin = defaultBLEPin;
#if defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7789_CS) || defined(HX8357_CS) || \
defined(USE_ST7789)
#if defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7789_CS) || \
defined(HX8357_CS) || defined(USE_ST7789)
bool hasScreen = true;
#elif ARCH_PORTDUINO
bool hasScreen = false;
@@ -625,13 +629,13 @@ void NodeDB::installDefaultDeviceState()
// Set default owner name
pickNewNodeNum(); // based on macaddr now
#ifdef CONFIG_OWNER_LONG_NAME_USERPREFS
snprintf(owner.long_name, sizeof(owner.long_name), CONFIG_OWNER_LONG_NAME_USERPREFS);
#ifdef USERPREFS_CONFIG_OWNER_LONG_NAME
snprintf(owner.long_name, sizeof(owner.long_name), USERPREFS_CONFIG_OWNER_LONG_NAME);
#else
snprintf(owner.long_name, sizeof(owner.long_name), "Meshtastic %02x%02x", ourMacAddr[4], ourMacAddr[5]);
#endif
#ifdef CONFIG_OWNER_SHORT_NAME_USERPREFS
snprintf(owner.short_name, sizeof(owner.short_name), CONFIG_OWNER_SHORT_NAME_USERPREFS);
#ifdef USERPREFS_CONFIG_OWNER_SHORT_NAME
snprintf(owner.short_name, sizeof(owner.short_name), USERPREFS_CONFIG_OWNER_SHORT_NAME);
#else
snprintf(owner.short_name, sizeof(owner.short_name), "%02x%02x", ourMacAddr[4], ourMacAddr[5]);
#endif
@@ -1087,7 +1091,7 @@ bool NodeDB::updateUser(uint32_t nodeId, meshtastic_User &p, uint8_t channelInde
// We just changed something about the user, store our DB
Throttle::execute(
&lastNodeDbSave, ONE_MINUTE_MS, []() { nodeDB->saveToDisk(SEGMENT_DEVICESTATE); },
[]() { LOG_DEBUG("Deferring NodeDB saveToDisk for now, since we saved less than a minute ago\n"); });
[]() { LOG_DEBUG("Deferring NodeDB saveToDisk for now\n"); }); // since we saved less than a minute ago
}
return changed;
@@ -1213,4 +1217,4 @@ void recordCriticalError(meshtastic_CriticalErrorCode code, uint32_t address, co
LOG_ERROR("A critical failure occurred, portduino is exiting...");
exit(2);
#endif
}
}

View File

@@ -605,10 +605,14 @@ bool PhoneAPI::handleToRadioPacket(meshtastic_MeshPacket &p)
Throttle::isWithinTimespanMs(lastPortNumToRadio[p.decoded.portnum], THIRTY_SECONDS_MS)) {
LOG_WARN("Rate limiting portnum %d\n", p.decoded.portnum);
sendNotification(meshtastic_LogRecord_Level_WARNING, p.id, "TraceRoute can only be sent once every 30 seconds");
meshtastic_QueueStatus qs = router->getQueueStatus();
service->sendQueueStatusToPhone(qs, 0, p.id);
return false;
} else if (p.decoded.portnum == meshtastic_PortNum_POSITION_APP && lastPortNumToRadio[p.decoded.portnum] &&
Throttle::isWithinTimespanMs(lastPortNumToRadio[p.decoded.portnum], FIVE_SECONDS_MS)) {
LOG_WARN("Rate limiting portnum %d\n", p.decoded.portnum);
meshtastic_QueueStatus qs = router->getQueueStatus();
service->sendQueueStatusToPhone(qs, 0, p.id);
// FIXME: Figure out why this continues to happen
// sendNotification(meshtastic_LogRecord_Level_WARNING, p.id, "Position can only be sent once every 5 seconds");
return false;

View File

@@ -1,3 +1,4 @@
#if RADIOLIB_EXCLUDE_SX127X != 1
#include "RF95Interface.h"
#include "MeshRadio.h" // kinda yucky, but we need to know which region we are in
#include "RadioLibRF95.h"
@@ -219,17 +220,17 @@ bool RF95Interface::reconfigure()
err = lora->setSyncWord(syncWord);
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("Radiolib error %d when attempting RF95 setSyncWord!\n", err);
LOG_ERROR("RF95 setSyncWord %s%d\n", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
err = lora->setCurrentLimit(currentLimit);
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("Radiolib error %d when attempting RF95 setCurrentLimit!\n", err);
LOG_ERROR("RF95 setCurrentLimit %s%d\n", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
err = lora->setPreambleLength(preambleLength);
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("Radiolib error %d when attempting RF95 setPreambleLength!\n", err);
LOG_ERROR(" RF95 setPreambleLength %s%d\n", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
err = lora->setFrequency(getFreq());
@@ -265,7 +266,7 @@ void RF95Interface::setStandby()
{
int err = lora->standby();
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("Radiolib error %d when attempting RF95 standby!\n", err);
LOG_ERROR("RF95 standby %s%d\n", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
isReceiving = false; // If we were receiving, not any more
@@ -289,7 +290,7 @@ void RF95Interface::startReceive()
setStandby();
int err = lora->startReceive();
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("Radiolib error %d when attempting RF95 startReceive!\n", err);
LOG_ERROR("RF95 startReceive %s%d\n", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
isReceiving = true;
@@ -311,7 +312,7 @@ bool RF95Interface::isChannelActive()
return true;
}
if (result != RADIOLIB_CHANNEL_FREE)
LOG_ERROR("Radiolib error %d when attempting RF95 isChannelActive!\n", result);
LOG_ERROR("RF95 isChannelActive %s%d\n", radioLibErr, result);
assert(result != RADIOLIB_ERR_WRONG_MODEM);
// LOG_DEBUG("Channel is free!\n");
@@ -336,3 +337,4 @@ bool RF95Interface::sleep()
return true;
}
#endif

View File

@@ -1,5 +1,5 @@
#pragma once
#if RADIOLIB_EXCLUDE_SX127X != 1
#include "MeshRadio.h" // kinda yucky, but we need to know which region we are in
#include "RadioLibInterface.h"
#include "RadioLibRF95.h"
@@ -69,3 +69,4 @@ class RF95Interface : public RadioLibInterface
/** Some boards require GPIO control of tx vs rx paths */
void setTransmitEnable(bool txon);
};
#endif

View File

@@ -202,8 +202,6 @@ uint32_t RadioInterface::getPacketTime(uint32_t pl)
uint32_t msecs = tPacket * 1000;
LOG_DEBUG("(bw=%d, sf=%d, cr=4/%d) packet symLen=%d ms, payloadSize=%u, time %d ms\n", (int)bw, sf, cr, (int)(tSym * 1000),
pl, msecs);
return msecs;
}
@@ -550,11 +548,11 @@ void RadioInterface::applyModemConfig()
LOG_INFO("Radio freq=%.3f, config.lora.frequency_offset=%.3f\n", freq, loraConfig.frequency_offset);
LOG_INFO("Set radio: region=%s, name=%s, config=%u, ch=%d, power=%d\n", myRegion->name, channelName, loraConfig.modem_preset,
channel_num, power);
LOG_INFO("Radio myRegion->freqStart -> myRegion->freqEnd: %f -> %f (%f MHz)\n", myRegion->freqStart, myRegion->freqEnd,
LOG_INFO("myRegion->freqStart -> myRegion->freqEnd: %f -> %f (%f MHz)\n", myRegion->freqStart, myRegion->freqEnd,
myRegion->freqEnd - myRegion->freqStart);
LOG_INFO("Radio myRegion->numChannels: %d x %.3fkHz\n", numChannels, bw);
LOG_INFO("Radio channel_num: %d\n", channel_num + 1);
LOG_INFO("Radio frequency: %f\n", getFreq());
LOG_INFO("numChannels: %d x %.3fkHz\n", numChannels, bw);
LOG_INFO("channel_num: %d\n", channel_num + 1);
LOG_INFO("frequency: %f\n", getFreq());
LOG_INFO("Slot time: %u msec\n", slotTimeMsec);
}
@@ -595,26 +593,25 @@ size_t RadioInterface::beginSending(meshtastic_MeshPacket *p)
lastTxStart = millis();
PacketHeader *h = (PacketHeader *)radiobuf;
h->from = p->from;
h->to = p->to;
h->id = p->id;
h->channel = p->channel;
h->next_hop = 0; // *** For future use ***
h->relay_node = 0; // *** For future use ***
radioBuffer.header.from = p->from;
radioBuffer.header.to = p->to;
radioBuffer.header.id = p->id;
radioBuffer.header.channel = p->channel;
radioBuffer.header.next_hop = 0; // *** For future use ***
radioBuffer.header.relay_node = 0; // *** For future use ***
if (p->hop_limit > HOP_MAX) {
LOG_WARN("hop limit %d is too high, setting to %d\n", p->hop_limit, HOP_RELIABLE);
p->hop_limit = HOP_RELIABLE;
}
h->flags = p->hop_limit | (p->want_ack ? PACKET_FLAGS_WANT_ACK_MASK : 0) | (p->via_mqtt ? PACKET_FLAGS_VIA_MQTT_MASK : 0);
h->flags |= (p->hop_start << PACKET_FLAGS_HOP_START_SHIFT) & PACKET_FLAGS_HOP_START_MASK;
radioBuffer.header.flags =
p->hop_limit | (p->want_ack ? PACKET_FLAGS_WANT_ACK_MASK : 0) | (p->via_mqtt ? PACKET_FLAGS_VIA_MQTT_MASK : 0);
radioBuffer.header.flags |= (p->hop_start << PACKET_FLAGS_HOP_START_SHIFT) & PACKET_FLAGS_HOP_START_MASK;
// if the sender nodenum is zero, that means uninitialized
assert(h->from);
assert(radioBuffer.header.from);
memcpy(radiobuf + sizeof(PacketHeader), p->encrypted.bytes, p->encrypted.size);
memcpy(radioBuffer.payload, p->encrypted.bytes, p->encrypted.size);
sendingPacket = p;
return p->encrypted.size + sizeof(PacketHeader);
}
}

View File

@@ -45,6 +45,20 @@ typedef struct {
uint8_t relay_node;
} PacketHeader;
/**
* This structure represent the structured buffer : a PacketHeader then the payload. The whole is
* MAX_LORA_PAYLOAD_LEN + 1 length
* It makes the use of its data easier, and avoids manipulating pointers (and potential non aligned accesses)
*/
typedef struct {
/** The header, as defined just before */
PacketHeader header;
/** The payload, of maximum length minus the header, aligned just to be sure */
uint8_t payload[MAX_LORA_PAYLOAD_LEN + 1 - sizeof(PacketHeader)] __attribute__ ((__aligned__));
} RadioBuffer;
/**
* Basic operations all radio chipsets must implement.
*
@@ -91,8 +105,7 @@ class RadioInterface
/**
* A temporary buffer used for sending/receiving packets, sized to hold the biggest buffer we might need
* */
uint8_t radiobuf[MAX_LORA_PAYLOAD_LEN + 1];
RadioBuffer radioBuffer __attribute__ ((__aligned__));
/**
* Enqueue a received packet for the registered receiver
*/

View File

@@ -186,7 +186,7 @@ ErrorCode RadioLibInterface::send(meshtastic_MeshPacket *p)
#ifndef LORA_DISABLE_SENDING
printPacket("enqueuing for send", p);
LOG_DEBUG("txGood=%d,rxGood=%d,rxBad=%d\n", txGood, rxGood, rxBad);
LOG_DEBUG("txGood=%d,txRelay=%d,rxGood=%d,rxBad=%d\n", txGood, txRelay, rxGood, rxBad);
ErrorCode res = txQueue.enqueue(p) ? ERRNO_OK : ERRNO_UNKNOWN;
if (res != ERRNO_OK) { // we weren't able to queue it, so we must drop it to prevent leaks
@@ -353,6 +353,8 @@ void RadioLibInterface::completeSending()
if (p) {
txGood++;
if (!isFromUs(p))
txRelay++;
printPacket("Completed sending", p);
// We are done sending that packet, release it
@@ -387,7 +389,7 @@ void RadioLibInterface::handleReceiveInterrupt()
}
#endif
int state = iface->readData(radiobuf, length);
int state = iface->readData((uint8_t *)&radioBuffer, length);
if (state != RADIOLIB_ERR_NONE) {
LOG_ERROR("ignoring received packet due to error=%d\n", state);
rxBad++;
@@ -397,7 +399,6 @@ void RadioLibInterface::handleReceiveInterrupt()
} else {
// Skip the 4 headers that are at the beginning of the rxBuf
int32_t payloadLen = length - sizeof(PacketHeader);
const uint8_t *payload = radiobuf + sizeof(PacketHeader);
// check for short packets
if (payloadLen < 0) {
@@ -405,10 +406,9 @@ void RadioLibInterface::handleReceiveInterrupt()
rxBad++;
airTime->logAirtime(RX_ALL_LOG, xmitMsec);
} else {
const PacketHeader *h = (PacketHeader *)radiobuf;
rxGood++;
// altered packet with "from == 0" can do Remote Node Administration without permission
if (h->from == 0) {
if (radioBuffer.header.from == 0) {
LOG_WARN("ignoring received packet without sender\n");
return;
}
@@ -418,22 +418,22 @@ void RadioLibInterface::handleReceiveInterrupt()
// nodes.
meshtastic_MeshPacket *mp = packetPool.allocZeroed();
mp->from = h->from;
mp->to = h->to;
mp->id = h->id;
mp->channel = h->channel;
mp->from = radioBuffer.header.from;
mp->to = radioBuffer.header.to;
mp->id = radioBuffer.header.id;
mp->channel = radioBuffer.header.channel;
assert(HOP_MAX <= PACKET_FLAGS_HOP_LIMIT_MASK); // If hopmax changes, carefully check this code
mp->hop_limit = h->flags & PACKET_FLAGS_HOP_LIMIT_MASK;
mp->hop_start = (h->flags & PACKET_FLAGS_HOP_START_MASK) >> PACKET_FLAGS_HOP_START_SHIFT;
mp->want_ack = !!(h->flags & PACKET_FLAGS_WANT_ACK_MASK);
mp->via_mqtt = !!(h->flags & PACKET_FLAGS_VIA_MQTT_MASK);
mp->hop_limit = radioBuffer.header.flags & PACKET_FLAGS_HOP_LIMIT_MASK;
mp->hop_start = (radioBuffer.header.flags & PACKET_FLAGS_HOP_START_MASK) >> PACKET_FLAGS_HOP_START_SHIFT;
mp->want_ack = !!(radioBuffer.header.flags & PACKET_FLAGS_WANT_ACK_MASK);
mp->via_mqtt = !!(radioBuffer.header.flags & PACKET_FLAGS_VIA_MQTT_MASK);
addReceiveMetadata(mp);
mp->which_payload_variant =
meshtastic_MeshPacket_encrypted_tag; // Mark that the payload is still encrypted at this point
assert(((uint32_t)payloadLen) <= sizeof(mp->encrypted.bytes));
memcpy(mp->encrypted.bytes, payload, payloadLen);
memcpy(mp->encrypted.bytes, radioBuffer.payload, payloadLen);
mp->encrypted.size = payloadLen;
printPacket("Lora RX", mp);
@@ -468,14 +468,14 @@ void RadioLibInterface::startSend(meshtastic_MeshPacket *txp)
{
printPacket("Starting low level send", txp);
if (disabled || !config.lora.tx_enabled) {
LOG_WARN("startSend is dropping tx packet because we are disabled\n");
LOG_WARN("Drop Tx packet because LoRa Tx disabled\n");
packetPool.release(txp);
} else {
configHardwareForSend(); // must be after setStandby
size_t numbytes = beginSending(txp);
int res = iface->startTransmit(radiobuf, numbytes);
int res = iface->startTransmit((uint8_t *)&radioBuffer, numbytes);
if (res != RADIOLIB_ERR_NONE) {
LOG_ERROR("startTransmit failed, error=%d\n", res);
RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_RADIO_SPI_BUG);

View File

@@ -107,7 +107,7 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
/**
* Debugging counts
*/
uint32_t rxBad = 0, rxGood = 0, txGood = 0;
uint32_t rxBad = 0, rxGood = 0, txGood = 0, txRelay = 0;
public:
RadioLibInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst,
@@ -196,4 +196,6 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
* Subclasses must override, implement and then call into this base class implementation
*/
virtual void setStandby();
const char *radioLibErr = "RadioLib err=\n";
};

View File

@@ -1,3 +1,4 @@
#if RADIOLIB_EXCLUDE_SX127X != 1
#include "RadioLibRF95.h"
#include "configuration.h"
@@ -81,4 +82,5 @@ uint8_t RadioLibRF95::readReg(uint8_t addr)
{
Module *mod = this->getMod();
return mod->SPIreadRegister(addr);
}
}
#endif

View File

@@ -1,4 +1,5 @@
#pragma once
#if RADIOLIB_EXCLUDE_SX127X != 1
#include <RadioLib.h>
/*!
@@ -69,3 +70,4 @@ class RadioLibRF95 : public SX1278
// use the previous value
float currentLimit = 100;
};
#endif

View File

@@ -78,7 +78,7 @@ bool ReliableRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
* Resending real ACKs is omitted, as you might receive a packet multiple times due to flooding and
* flooding this ACK back to the original sender already adds redundancy. */
bool isRepeated = p->hop_start == 0 ? (p->hop_limit == HOP_RELIABLE) : (p->hop_start == p->hop_limit);
if (wasSeenRecently(p, false) && isRepeated && !MeshModule::currentReply && p->to != nodeDB->getNodeNum()) {
if (wasSeenRecently(p, false) && isRepeated && !MeshModule::currentReply && !isToUs(p)) {
LOG_DEBUG("Resending implicit ack for a repeated floodmsg\n");
meshtastic_MeshPacket *tosend = packetPool.allocCopy(*p);
tosend->hop_limit--; // bump down the hop count
@@ -102,17 +102,15 @@ bool ReliableRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
*/
void ReliableRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtastic_Routing *c)
{
NodeNum ourNode = getNodeNum();
if (p->to == ourNode) { // ignore ack/nak/want_ack packets that are not address to us (we only handle 0 hop reliability)
if (isToUs(p)) { // ignore ack/nak/want_ack packets that are not address to us (we only handle 0 hop reliability)
if (p->want_ack) {
if (MeshModule::currentReply) {
LOG_DEBUG("Some other module has replied to this message, no need for a 2nd ack\n");
LOG_DEBUG("Another module replied to this message, no need for 2nd ack\n");
} else if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
sendAckNak(meshtastic_Routing_Error_NONE, getFrom(p), p->id, p->channel, p->hop_start, p->hop_limit);
} else if (p->which_payload_variant == meshtastic_MeshPacket_encrypted_tag && p->channel == 0 &&
(nodeDB->getMeshNode(p->from) == nullptr || nodeDB->getMeshNode(p->from)->user.public_key.size == 0)) {
LOG_INFO("This looks like it might be a PKI packet from an unknown node, so send PKI_UNKNOWN_PUBKEY\n");
LOG_INFO("PKI packet from unknown node, send PKI_UNKNOWN_PUBKEY\n");
sendAckNak(meshtastic_Routing_Error_PKI_UNKNOWN_PUBKEY, getFrom(p), p->id, channels.getPrimaryIndex(),
p->hop_start, p->hop_limit);
} else {
@@ -124,7 +122,7 @@ void ReliableRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtas
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag && c &&
c->error_reason == meshtastic_Routing_Error_PKI_UNKNOWN_PUBKEY) {
if (owner.public_key.size == 32) {
LOG_INFO("This seems like a remote PKI decrypt failure, so send a NodeInfo");
LOG_INFO("PKI decrypt failure, send a NodeInfo");
nodeInfoModule->sendOurNodeInfo(p->from, false, p->channel, true);
}
}
@@ -136,11 +134,10 @@ void ReliableRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtas
// We intentionally don't check wasSeenRecently, because it is harmless to delete non existent retransmission records
if (ackId || nakId) {
LOG_DEBUG("Received a %s for 0x%x, stopping retransmissions\n", ackId ? "ACK" : "NAK", ackId);
if (ackId) {
LOG_DEBUG("Received an ack for 0x%x, stopping retransmissions\n", ackId);
stopRetransmission(p->to, ackId);
} else {
LOG_DEBUG("Received a nak for 0x%x, stopping retransmissions\n", nakId);
stopRetransmission(p->to, nakId);
}
}

View File

@@ -36,8 +36,8 @@ static MemoryDynamic<meshtastic_MeshPacket> staticPool;
Allocator<meshtastic_MeshPacket> &packetPool = staticPool;
static uint8_t bytes[MAX_LORA_PAYLOAD_LEN + 1] __attribute__ ((__aligned__));
static uint8_t ScratchEncrypted[MAX_LORA_PAYLOAD_LEN + 1] __attribute__ ((__aligned__));
static uint8_t bytes[MAX_LORA_PAYLOAD_LEN + 1] __attribute__((__aligned__));
static uint8_t ScratchEncrypted[MAX_LORA_PAYLOAD_LEN + 1] __attribute__((__aligned__));
/**
* Constructor
@@ -169,7 +169,7 @@ ErrorCode Router::sendLocal(meshtastic_MeshPacket *p, RxSource src)
LOG_ERROR("Packet received with to: of 0!\n");
}
// No need to deliver externally if the destination is the local node
if (p->to == nodeDB->getNodeNum()) {
if (isToUs(p)) {
printPacket("Enqueued local", p);
enqueueReceivedMessage(p);
return ERRNO_OK;
@@ -204,7 +204,7 @@ ErrorCode Router::sendLocal(meshtastic_MeshPacket *p, RxSource src)
*/
ErrorCode Router::send(meshtastic_MeshPacket *p)
{
if (p->to == nodeDB->getNodeNum()) {
if (isToUs(p)) {
LOG_ERROR("BUG! send() called with packet destined for local node!\n");
packetPool.release(p);
return meshtastic_Routing_Error_BAD_REQUEST;
@@ -226,7 +226,7 @@ ErrorCode Router::send(meshtastic_MeshPacket *p)
service->sendClientNotification(cn);
#endif
meshtastic_Routing_Error err = meshtastic_Routing_Error_DUTY_CYCLE_LIMIT;
if (getFrom(p) == nodeDB->getNodeNum()) { // only send NAK to API, not to the mesh
if (isFromUs(p)) { // only send NAK to API, not to the mesh
abortSendAndNak(err, p);
} else {
packetPool.release(p);
@@ -248,7 +248,7 @@ ErrorCode Router::send(meshtastic_MeshPacket *p)
p->from = getFrom(p);
// If we are the original transmitter, set the hop limit with which we start
if (p->from == getNodeNum())
if (isFromUs(p))
p->hop_start = p->hop_limit;
// If the packet hasn't yet been encrypted, do so now (it might already be encrypted if we are just forwarding it)
@@ -273,7 +273,7 @@ ErrorCode Router::send(meshtastic_MeshPacket *p)
}
#if !MESHTASTIC_EXCLUDE_MQTT
// Only publish to MQTT if we're the original transmitter of the packet
if (moduleConfig.mqtt.enabled && p->from == nodeDB->getNodeNum() && mqtt) {
if (moduleConfig.mqtt.enabled && isFromUs(p) && mqtt) {
mqtt->onSend(*p, *p_decoded, chIndex);
}
#endif
@@ -328,9 +328,9 @@ bool perhapsDecode(meshtastic_MeshPacket *p)
memcpy(ScratchEncrypted, p->encrypted.bytes, rawSize);
#if !(MESHTASTIC_EXCLUDE_PKI)
// Attempt PKI decryption first
if (p->channel == 0 && p->to == nodeDB->getNodeNum() && p->to > 0 && p->to != NODENUM_BROADCAST &&
nodeDB->getMeshNode(p->from) != nullptr && nodeDB->getMeshNode(p->from)->user.public_key.size > 0 &&
nodeDB->getMeshNode(p->to)->user.public_key.size > 0 && rawSize > MESHTASTIC_PKC_OVERHEAD) {
if (p->channel == 0 && isToUs(p) && p->to > 0 && p->to != NODENUM_BROADCAST && nodeDB->getMeshNode(p->from) != nullptr &&
nodeDB->getMeshNode(p->from)->user.public_key.size > 0 && nodeDB->getMeshNode(p->to)->user.public_key.size > 0 &&
rawSize > MESHTASTIC_PKC_OVERHEAD) {
LOG_DEBUG("Attempting PKI decryption\n");
if (crypto->decryptCurve25519(p->from, p->id, rawSize, ScratchEncrypted, bytes)) {
@@ -432,7 +432,7 @@ meshtastic_Routing_Error perhapsEncode(meshtastic_MeshPacket *p)
// If the packet is not yet encrypted, do so now
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
if (p->from == nodeDB->getNodeNum()) {
if (isFromUs(p)) {
p->decoded.has_bitfield = true;
p->decoded.bitfield |= (config.lora.config_ok_to_mqtt << BITFIELD_OK_TO_MQTT_SHIFT);
p->decoded.bitfield |= (p->decoded.want_response << BITFIELD_WANT_RESPONSE_SHIFT);
@@ -503,8 +503,8 @@ meshtastic_Routing_Error perhapsEncode(meshtastic_MeshPacket *p)
return meshtastic_Routing_Error_TOO_LARGE;
if (p->pki_encrypted && !memfll(p->public_key.bytes, 0, 32) &&
memcmp(p->public_key.bytes, node->user.public_key.bytes, 32) != 0) {
LOG_WARN("Client public key for client differs from requested! Requested 0x%02x, but stored key begins 0x%02x\n",
*p->public_key.bytes, *node->user.public_key.bytes);
LOG_WARN("Client public key differs from requested: 0x%02x, stored key begins 0x%02x\n", *p->public_key.bytes,
*node->user.public_key.bytes);
return meshtastic_Routing_Error_PKI_FAILED;
}
crypto->encryptCurve25519(p->to, getFrom(p), p->id, numbytes, bytes, ScratchEncrypted);
@@ -590,7 +590,7 @@ void Router::handleReceived(meshtastic_MeshPacket *p, RxSource src)
skipHandle = true;
}
#if EVENT_MODE
#if USERPREFS_EVENT_MODE
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag &&
(p->decoded.portnum == meshtastic_PortNum_ATAK_FORWARDER || p->decoded.portnum == meshtastic_PortNum_ATAK_PLUGIN ||
p->decoded.portnum == meshtastic_PortNum_PAXCOUNTER_APP || p->decoded.portnum == meshtastic_PortNum_IP_TUNNEL_APP ||
@@ -613,7 +613,7 @@ void Router::handleReceived(meshtastic_MeshPacket *p, RxSource src)
#if !MESHTASTIC_EXCLUDE_MQTT
// After potentially altering it, publish received message to MQTT if we're not the original transmitter of the packet
if (decoded && moduleConfig.mqtt.enabled && getFrom(p) != nodeDB->getNodeNum() && mqtt)
if (decoded && moduleConfig.mqtt.enabled && !isFromUs(p) && mqtt)
mqtt->onSend(*p_encrypted, *p, p->channel);
#endif
}

View File

@@ -82,6 +82,10 @@ class Router : protected concurrency::OSThread
*/
virtual ErrorCode send(meshtastic_MeshPacket *p);
/* Statistics for the amount of duplicate received packets and the amount of times we cancel a relay because someone did it
before us */
uint32_t rxDupe = 0, txRelayCanceled = 0;
protected:
friend class RoutingModule;

View File

@@ -1,3 +1,4 @@
#if RADIOLIB_EXCLUDE_SX126X != 1
#include "SX1262Interface.h"
#include "configuration.h"
#include "error.h"
@@ -6,4 +7,5 @@ SX1262Interface::SX1262Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, R
RADIOLIB_PIN_TYPE busy)
: SX126xInterface(hal, cs, irq, rst, busy)
{
}
}
#endif

View File

@@ -1,3 +1,4 @@
#if RADIOLIB_EXCLUDE_SX126X != 1
#pragma once
#include "SX126xInterface.h"
@@ -10,4 +11,5 @@ class SX1262Interface : public SX126xInterface<SX1262>
public:
SX1262Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst,
RADIOLIB_PIN_TYPE busy);
};
};
#endif

View File

@@ -1,3 +1,4 @@
#if RADIOLIB_EXCLUDE_SX126X != 1
#include "SX1268Interface.h"
#include "configuration.h"
#include "error.h"
@@ -15,4 +16,5 @@ float SX1268Interface::getFreq()
return 433.125f;
else
return savedFreq;
}
}
#endif

View File

@@ -1,4 +1,5 @@
#pragma once
#if RADIOLIB_EXCLUDE_SX126X != 1
#include "SX126xInterface.h"
@@ -13,3 +14,4 @@ class SX1268Interface : public SX126xInterface<SX1268>
SX1268Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst,
RADIOLIB_PIN_TYPE busy);
};
#endif

View File

@@ -1,3 +1,4 @@
#if RADIOLIB_EXCLUDE_SX126X != 1
#include "SX126xInterface.h"
#include "configuration.h"
#include "error.h"
@@ -202,17 +203,17 @@ template <typename T> bool SX126xInterface<T>::reconfigure()
err = lora.setSyncWord(syncWord);
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("Radiolib error %d when attempting SX126X setSyncWord!\n", err);
LOG_ERROR("SX126X setSyncWord %s%d\n", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
err = lora.setCurrentLimit(currentLimit);
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("Radiolib error %d when attempting SX126X setCurrentLimit!\n", err);
LOG_ERROR("SX126X setCurrentLimit %s%d\n", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
err = lora.setPreambleLength(preambleLength);
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("Radiolib error %d when attempting SX126X setPreambleLength!\n", err);
LOG_ERROR("SX126X setPreambleLength %s%d\n", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
err = lora.setFrequency(getFreq());
@@ -224,7 +225,7 @@ template <typename T> bool SX126xInterface<T>::reconfigure()
err = lora.setOutputPower(power);
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("Radiolib error %d when attempting SX126X setOutputPower!\n", err);
LOG_ERROR("SX126X setOutputPower %s%d\n", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
startReceive(); // restart receiving
@@ -244,7 +245,7 @@ template <typename T> void SX126xInterface<T>::setStandby()
int err = lora.standby();
if (err != RADIOLIB_ERR_NONE)
LOG_DEBUG("SX126x standby failed with error %d\n", err);
LOG_DEBUG("SX126x standby %s%d\n", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
isReceiving = false; // If we were receiving, not any more
@@ -286,7 +287,7 @@ template <typename T> void SX126xInterface<T>::startReceive()
// Furthermore, we need the PREAMBLE_DETECTED and HEADER_VALID IRQ flag to detect whether we are actively receiving
int err = lora.startReceiveDutyCycleAuto(preambleLength, 8, RADIOLIB_IRQ_RX_DEFAULT_FLAGS | RADIOLIB_IRQ_PREAMBLE_DETECTED);
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("Radiolib error %d when attempting SX126X startReceiveDutyCycleAuto!\n", err);
LOG_ERROR("SX126X startReceiveDutyCycleAuto %s%d\n", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
RadioLibInterface::startReceive();
@@ -307,7 +308,7 @@ template <typename T> bool SX126xInterface<T>::isChannelActive()
if (result == RADIOLIB_LORA_DETECTED)
return true;
if (result != RADIOLIB_CHANNEL_FREE)
LOG_ERROR("Radiolib error %d when attempting SX126X scanChannel!\n", result);
LOG_ERROR("SX126X scanChannel %s%d\n", radioLibErr, result);
assert(result != RADIOLIB_ERR_WRONG_MODEM);
return false;
@@ -325,8 +326,8 @@ template <typename T> bool SX126xInterface<T>::sleep()
{
// Not keeping config is busted - next time nrf52 board boots lora sending fails tcxo related? - see datasheet
// \todo Display actual typename of the adapter, not just `SX126x`
LOG_DEBUG("SX126x entering sleep mode (FIXME, don't keep config)\n");
setStandby(); // Stop any pending operations
LOG_DEBUG("SX126x entering sleep mode\n"); // (FIXME, don't keep config)
setStandby(); // Stop any pending operations
// turn off TCXO if it was powered
// FIXME - this isn't correct
@@ -341,4 +342,5 @@ template <typename T> bool SX126xInterface<T>::sleep()
#endif
return true;
}
}
#endif

View File

@@ -1,4 +1,5 @@
#pragma once
#if RADIOLIB_EXCLUDE_SX126X != 1
#include "RadioLibInterface.h"
@@ -68,3 +69,4 @@ template <class T> class SX126xInterface : public RadioLibInterface
virtual void setStandby() override;
};
#endif

View File

@@ -1,3 +1,4 @@
#if RADIOLIB_EXCLUDE_SX128X != 1
#include "SX1280Interface.h"
#include "configuration.h"
#include "error.h"
@@ -7,3 +8,4 @@ SX1280Interface::SX1280Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, R
: SX128xInterface(hal, cs, irq, rst, busy)
{
}
#endif

View File

@@ -1,5 +1,5 @@
#pragma once
#if RADIOLIB_EXCLUDE_SX128X != 1
#include "SX128xInterface.h"
/**
@@ -12,3 +12,4 @@ class SX1280Interface : public SX128xInterface<SX1280>
SX1280Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst,
RADIOLIB_PIN_TYPE busy);
};
#endif

View File

@@ -1,3 +1,4 @@
#if RADIOLIB_EXCLUDE_SX128X != 1
#include "SX128xInterface.h"
#include "Throttle.h"
#include "configuration.h"
@@ -128,12 +129,12 @@ template <typename T> bool SX128xInterface<T>::reconfigure()
err = lora.setSyncWord(syncWord);
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("Radiolib error %d when attempting SX128X setSyncWord!\n", err);
LOG_ERROR("SX128X setSyncWord %s%d\n", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
err = lora.setPreambleLength(preambleLength);
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("Radiolib error %d when attempting SX128X setPreambleLength!\n", err);
LOG_ERROR("SX128X setPreambleLength %s%d\n", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
err = lora.setFrequency(getFreq());
@@ -145,7 +146,7 @@ template <typename T> bool SX128xInterface<T>::reconfigure()
err = lora.setOutputPower(power);
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("Radiolib error %d when attempting SX128X setOutputPower!\n", err);
LOG_ERROR("SX128X setOutputPower %s%d\n", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
startReceive(); // restart receiving
@@ -170,7 +171,7 @@ template <typename T> void SX128xInterface<T>::setStandby()
int err = lora.standby();
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("SX128x standby failed with error %d\n", err);
LOG_ERROR("SX128x standby %s%d\n", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
#if ARCH_PORTDUINO
if (settingsMap[rxen] != RADIOLIB_NC) {
@@ -260,7 +261,7 @@ template <typename T> void SX128xInterface<T>::startReceive()
int err = lora.startReceive(RADIOLIB_SX128X_RX_TIMEOUT_INF, RADIOLIB_IRQ_RX_DEFAULT_FLAGS | RADIOLIB_IRQ_PREAMBLE_DETECTED);
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("Radiolib error %d when attempting SX128X startReceive!\n", err);
LOG_ERROR("SX128X startReceive %s%d\n", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
RadioLibInterface::startReceive();
@@ -281,7 +282,7 @@ template <typename T> bool SX128xInterface<T>::isChannelActive()
if (result == RADIOLIB_LORA_DETECTED)
return true;
if (result != RADIOLIB_CHANNEL_FREE)
LOG_ERROR("Radiolib error %d when attempting SX128X scanChannel!\n", result);
LOG_ERROR("SX128X scanChannel %s%d\n", radioLibErr, result);
assert(result != RADIOLIB_ERR_WRONG_MODEM);
return false;
@@ -297,8 +298,8 @@ template <typename T> bool SX128xInterface<T>::sleep()
{
// Not keeping config is busted - next time nrf52 board boots lora sending fails tcxo related? - see datasheet
// \todo Display actual typename of the adapter, not just `SX128x`
LOG_DEBUG("SX128x entering sleep mode (FIXME, don't keep config)\n");
setStandby(); // Stop any pending operations
LOG_DEBUG("SX128x entering sleep mode\n"); // (FIXME, don't keep config)
setStandby(); // Stop any pending operations
// turn off TCXO if it was powered
// FIXME - this isn't correct
@@ -313,4 +314,5 @@ template <typename T> bool SX128xInterface<T>::sleep()
#endif
return true;
}
}
#endif

View File

@@ -141,7 +141,7 @@ typedef struct _meshtastic_TAKPacket {
/* ATAK GeoChat message */
meshtastic_GeoChat chat;
/* Generic CoT detail XML
May be compressed / truncated by the sender */
May be compressed / truncated by the sender (EUD) */
meshtastic_TAKPacket_detail_t detail;
} payload_variant;
} meshtastic_TAKPacket;

View File

@@ -359,7 +359,7 @@ extern const pb_msgdesc_t meshtastic_OEMStore_msg;
#define MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_MAX_SIZE meshtastic_OEMStore_size
#define meshtastic_ChannelFile_size 718
#define meshtastic_NodeInfoLite_size 183
#define meshtastic_OEMStore_size 3568
#define meshtastic_OEMStore_size 3576
#define meshtastic_PositionLite_size 28
#define meshtastic_UserLite_size 96

View File

@@ -188,7 +188,7 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg;
/* Maximum encoded size of messages (where known) */
#define MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_MAX_SIZE meshtastic_LocalConfig_size
#define meshtastic_LocalConfig_size 735
#define meshtastic_LocalModuleConfig_size 687
#define meshtastic_LocalModuleConfig_size 695
#ifdef __cplusplus
} /* extern "C" */

View File

@@ -336,6 +336,12 @@ typedef struct _meshtastic_ModuleConfig_TelemetryConfig {
/* Interval in seconds of how often we should try to send our
air quality metrics to the mesh */
bool power_screen_enabled;
/* Preferences for the (Health) Telemetry Module
Enable/Disable the telemetry measurement module measurement collection */
bool health_measurement_enabled;
/* Interval in seconds of how often we should try to send our
health metrics to the mesh */
uint32_t health_update_interval;
} meshtastic_ModuleConfig_TelemetryConfig;
/* TODO: REPLACE */
@@ -503,7 +509,7 @@ extern "C" {
#define meshtastic_ModuleConfig_ExternalNotificationConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_ModuleConfig_StoreForwardConfig_init_default {0, 0, 0, 0, 0, 0}
#define meshtastic_ModuleConfig_RangeTestConfig_init_default {0, 0, 0}
#define meshtastic_ModuleConfig_TelemetryConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_ModuleConfig_TelemetryConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_ModuleConfig_CannedMessageConfig_init_default {0, 0, 0, 0, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, 0, 0, "", 0}
#define meshtastic_ModuleConfig_AmbientLightingConfig_init_default {0, 0, 0, 0, 0}
#define meshtastic_RemoteHardwarePin_init_default {0, "", _meshtastic_RemoteHardwarePinType_MIN}
@@ -519,7 +525,7 @@ extern "C" {
#define meshtastic_ModuleConfig_ExternalNotificationConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_ModuleConfig_StoreForwardConfig_init_zero {0, 0, 0, 0, 0, 0}
#define meshtastic_ModuleConfig_RangeTestConfig_init_zero {0, 0, 0}
#define meshtastic_ModuleConfig_TelemetryConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_ModuleConfig_TelemetryConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_ModuleConfig_CannedMessageConfig_init_zero {0, 0, 0, 0, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, 0, 0, "", 0}
#define meshtastic_ModuleConfig_AmbientLightingConfig_init_zero {0, 0, 0, 0, 0}
#define meshtastic_RemoteHardwarePin_init_zero {0, "", _meshtastic_RemoteHardwarePinType_MIN}
@@ -601,6 +607,8 @@ extern "C" {
#define meshtastic_ModuleConfig_TelemetryConfig_power_measurement_enabled_tag 8
#define meshtastic_ModuleConfig_TelemetryConfig_power_update_interval_tag 9
#define meshtastic_ModuleConfig_TelemetryConfig_power_screen_enabled_tag 10
#define meshtastic_ModuleConfig_TelemetryConfig_health_measurement_enabled_tag 11
#define meshtastic_ModuleConfig_TelemetryConfig_health_update_interval_tag 12
#define meshtastic_ModuleConfig_CannedMessageConfig_rotary1_enabled_tag 1
#define meshtastic_ModuleConfig_CannedMessageConfig_inputbroker_pin_a_tag 2
#define meshtastic_ModuleConfig_CannedMessageConfig_inputbroker_pin_b_tag 3
@@ -793,7 +801,9 @@ X(a, STATIC, SINGULAR, BOOL, air_quality_enabled, 6) \
X(a, STATIC, SINGULAR, UINT32, air_quality_interval, 7) \
X(a, STATIC, SINGULAR, BOOL, power_measurement_enabled, 8) \
X(a, STATIC, SINGULAR, UINT32, power_update_interval, 9) \
X(a, STATIC, SINGULAR, BOOL, power_screen_enabled, 10)
X(a, STATIC, SINGULAR, BOOL, power_screen_enabled, 10) \
X(a, STATIC, SINGULAR, BOOL, health_measurement_enabled, 11) \
X(a, STATIC, SINGULAR, UINT32, health_update_interval, 12)
#define meshtastic_ModuleConfig_TelemetryConfig_CALLBACK NULL
#define meshtastic_ModuleConfig_TelemetryConfig_DEFAULT NULL
@@ -878,7 +888,7 @@ extern const pb_msgdesc_t meshtastic_RemoteHardwarePin_msg;
#define meshtastic_ModuleConfig_RemoteHardwareConfig_size 96
#define meshtastic_ModuleConfig_SerialConfig_size 28
#define meshtastic_ModuleConfig_StoreForwardConfig_size 24
#define meshtastic_ModuleConfig_TelemetryConfig_size 36
#define meshtastic_ModuleConfig_TelemetryConfig_size 44
#define meshtastic_ModuleConfig_size 257
#define meshtastic_RemoteHardwarePin_size 21

View File

@@ -21,6 +21,9 @@ PB_BIND(meshtastic_AirQualityMetrics, meshtastic_AirQualityMetrics, AUTO)
PB_BIND(meshtastic_LocalStats, meshtastic_LocalStats, AUTO)
PB_BIND(meshtastic_HealthMetrics, meshtastic_HealthMetrics, AUTO)
PB_BIND(meshtastic_Telemetry, meshtastic_Telemetry, AUTO)

View File

@@ -71,7 +71,11 @@ typedef enum _meshtastic_TelemetrySensorType {
/* MAX17048 1S lipo battery sensor (voltage, state of charge, time to go) */
meshtastic_TelemetrySensorType_MAX17048 = 28,
/* Custom I2C sensor implementation based on https://github.com/meshtastic/i2c-sensor */
meshtastic_TelemetrySensorType_CUSTOM_SENSOR = 29
meshtastic_TelemetrySensorType_CUSTOM_SENSOR = 29,
/* MAX30102 Pulse Oximeter and Heart-Rate Sensor */
meshtastic_TelemetrySensorType_MAX30102 = 30,
/* MLX90614 non-contact IR temperature sensor. */
meshtastic_TelemetrySensorType_MLX90614 = 31
} meshtastic_TelemetrySensorType;
/* Struct definitions */
@@ -223,7 +227,7 @@ typedef struct _meshtastic_LocalStats {
float air_util_tx;
/* Number of packets sent */
uint32_t num_packets_tx;
/* Number of packets received good */
/* Number of packets received (both good and bad) */
uint32_t num_packets_rx;
/* Number of packets received that are malformed or violate the protocol */
uint32_t num_packets_rx_bad;
@@ -231,8 +235,29 @@ typedef struct _meshtastic_LocalStats {
uint16_t num_online_nodes;
/* Number of nodes total */
uint16_t num_total_nodes;
/* Number of received packets that were duplicates (due to multiple nodes relaying).
If this number is high, there are nodes in the mesh relaying packets when it's unnecessary, for example due to the ROUTER/REPEATER role. */
uint32_t num_rx_dupe;
/* Number of packets we transmitted that were a relay for others (not originating from ourselves). */
uint32_t num_tx_relay;
/* Number of times we canceled a packet to be relayed, because someone else did it before us.
This will always be zero for ROUTERs/REPEATERs. If this number is high, some other node(s) is/are relaying faster than you. */
uint32_t num_tx_relay_canceled;
} meshtastic_LocalStats;
/* Health telemetry metrics */
typedef struct _meshtastic_HealthMetrics {
/* Heart rate (beats per minute) */
bool has_heart_bpm;
uint8_t heart_bpm;
/* SpO2 (blood oxygen saturation) level */
bool has_spO2;
uint8_t spO2;
/* Body temperature in degrees Celsius */
bool has_temperature;
float temperature;
} meshtastic_HealthMetrics;
/* Types of Measurements the telemetry module is equipped to handle */
typedef struct _meshtastic_Telemetry {
/* Seconds since 1970 - or 0 for unknown/unset */
@@ -249,6 +274,8 @@ typedef struct _meshtastic_Telemetry {
meshtastic_PowerMetrics power_metrics;
/* Local device mesh statistics */
meshtastic_LocalStats local_stats;
/* Health telemetry metrics */
meshtastic_HealthMetrics health_metrics;
} variant;
} meshtastic_Telemetry;
@@ -267,8 +294,9 @@ extern "C" {
/* Helper constants for enums */
#define _meshtastic_TelemetrySensorType_MIN meshtastic_TelemetrySensorType_SENSOR_UNSET
#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_CUSTOM_SENSOR
#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_CUSTOM_SENSOR+1))
#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_MLX90614
#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_MLX90614+1))
@@ -283,14 +311,16 @@ extern "C" {
#define meshtastic_EnvironmentMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_PowerMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_AirQualityMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_LocalStats_init_default {0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_LocalStats_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_HealthMetrics_init_default {false, 0, false, 0, false, 0}
#define meshtastic_Telemetry_init_default {0, 0, {meshtastic_DeviceMetrics_init_default}}
#define meshtastic_Nau7802Config_init_default {0, 0}
#define meshtastic_DeviceMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_EnvironmentMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_PowerMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_AirQualityMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_LocalStats_init_zero {0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_LocalStats_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_HealthMetrics_init_zero {false, 0, false, 0, false, 0}
#define meshtastic_Telemetry_init_zero {0, 0, {meshtastic_DeviceMetrics_init_zero}}
#define meshtastic_Nau7802Config_init_zero {0, 0}
@@ -343,12 +373,19 @@ extern "C" {
#define meshtastic_LocalStats_num_packets_rx_bad_tag 6
#define meshtastic_LocalStats_num_online_nodes_tag 7
#define meshtastic_LocalStats_num_total_nodes_tag 8
#define meshtastic_LocalStats_num_rx_dupe_tag 9
#define meshtastic_LocalStats_num_tx_relay_tag 10
#define meshtastic_LocalStats_num_tx_relay_canceled_tag 11
#define meshtastic_HealthMetrics_heart_bpm_tag 1
#define meshtastic_HealthMetrics_spO2_tag 2
#define meshtastic_HealthMetrics_temperature_tag 3
#define meshtastic_Telemetry_time_tag 1
#define meshtastic_Telemetry_device_metrics_tag 2
#define meshtastic_Telemetry_environment_metrics_tag 3
#define meshtastic_Telemetry_air_quality_metrics_tag 4
#define meshtastic_Telemetry_power_metrics_tag 5
#define meshtastic_Telemetry_local_stats_tag 6
#define meshtastic_Telemetry_health_metrics_tag 7
#define meshtastic_Nau7802Config_zeroOffset_tag 1
#define meshtastic_Nau7802Config_calibrationFactor_tag 2
@@ -417,17 +454,28 @@ X(a, STATIC, SINGULAR, UINT32, num_packets_tx, 4) \
X(a, STATIC, SINGULAR, UINT32, num_packets_rx, 5) \
X(a, STATIC, SINGULAR, UINT32, num_packets_rx_bad, 6) \
X(a, STATIC, SINGULAR, UINT32, num_online_nodes, 7) \
X(a, STATIC, SINGULAR, UINT32, num_total_nodes, 8)
X(a, STATIC, SINGULAR, UINT32, num_total_nodes, 8) \
X(a, STATIC, SINGULAR, UINT32, num_rx_dupe, 9) \
X(a, STATIC, SINGULAR, UINT32, num_tx_relay, 10) \
X(a, STATIC, SINGULAR, UINT32, num_tx_relay_canceled, 11)
#define meshtastic_LocalStats_CALLBACK NULL
#define meshtastic_LocalStats_DEFAULT NULL
#define meshtastic_HealthMetrics_FIELDLIST(X, a) \
X(a, STATIC, OPTIONAL, UINT32, heart_bpm, 1) \
X(a, STATIC, OPTIONAL, UINT32, spO2, 2) \
X(a, STATIC, OPTIONAL, FLOAT, temperature, 3)
#define meshtastic_HealthMetrics_CALLBACK NULL
#define meshtastic_HealthMetrics_DEFAULT NULL
#define meshtastic_Telemetry_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, FIXED32, time, 1) \
X(a, STATIC, ONEOF, MESSAGE, (variant,device_metrics,variant.device_metrics), 2) \
X(a, STATIC, ONEOF, MESSAGE, (variant,environment_metrics,variant.environment_metrics), 3) \
X(a, STATIC, ONEOF, MESSAGE, (variant,air_quality_metrics,variant.air_quality_metrics), 4) \
X(a, STATIC, ONEOF, MESSAGE, (variant,power_metrics,variant.power_metrics), 5) \
X(a, STATIC, ONEOF, MESSAGE, (variant,local_stats,variant.local_stats), 6)
X(a, STATIC, ONEOF, MESSAGE, (variant,local_stats,variant.local_stats), 6) \
X(a, STATIC, ONEOF, MESSAGE, (variant,health_metrics,variant.health_metrics), 7)
#define meshtastic_Telemetry_CALLBACK NULL
#define meshtastic_Telemetry_DEFAULT NULL
#define meshtastic_Telemetry_variant_device_metrics_MSGTYPE meshtastic_DeviceMetrics
@@ -435,6 +483,7 @@ X(a, STATIC, ONEOF, MESSAGE, (variant,local_stats,variant.local_stats),
#define meshtastic_Telemetry_variant_air_quality_metrics_MSGTYPE meshtastic_AirQualityMetrics
#define meshtastic_Telemetry_variant_power_metrics_MSGTYPE meshtastic_PowerMetrics
#define meshtastic_Telemetry_variant_local_stats_MSGTYPE meshtastic_LocalStats
#define meshtastic_Telemetry_variant_health_metrics_MSGTYPE meshtastic_HealthMetrics
#define meshtastic_Nau7802Config_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, INT32, zeroOffset, 1) \
@@ -447,6 +496,7 @@ extern const pb_msgdesc_t meshtastic_EnvironmentMetrics_msg;
extern const pb_msgdesc_t meshtastic_PowerMetrics_msg;
extern const pb_msgdesc_t meshtastic_AirQualityMetrics_msg;
extern const pb_msgdesc_t meshtastic_LocalStats_msg;
extern const pb_msgdesc_t meshtastic_HealthMetrics_msg;
extern const pb_msgdesc_t meshtastic_Telemetry_msg;
extern const pb_msgdesc_t meshtastic_Nau7802Config_msg;
@@ -456,6 +506,7 @@ extern const pb_msgdesc_t meshtastic_Nau7802Config_msg;
#define meshtastic_PowerMetrics_fields &meshtastic_PowerMetrics_msg
#define meshtastic_AirQualityMetrics_fields &meshtastic_AirQualityMetrics_msg
#define meshtastic_LocalStats_fields &meshtastic_LocalStats_msg
#define meshtastic_HealthMetrics_fields &meshtastic_HealthMetrics_msg
#define meshtastic_Telemetry_fields &meshtastic_Telemetry_msg
#define meshtastic_Nau7802Config_fields &meshtastic_Nau7802Config_msg
@@ -464,7 +515,8 @@ extern const pb_msgdesc_t meshtastic_Nau7802Config_msg;
#define meshtastic_AirQualityMetrics_size 72
#define meshtastic_DeviceMetrics_size 27
#define meshtastic_EnvironmentMetrics_size 85
#define meshtastic_LocalStats_size 42
#define meshtastic_HealthMetrics_size 11
#define meshtastic_LocalStats_size 60
#define meshtastic_Nau7802Config_size 16
#define meshtastic_PowerMetrics_size 30
#define meshtastic_Telemetry_size 92

View File

@@ -776,7 +776,7 @@ void handleRestart(HTTPRequest *req, HTTPResponse *res)
res->println("<h1>Meshtastic</h1>\n");
res->println("Restarting");
LOG_DEBUG("***** Restarted on HTTP(s) Request *****\n");
LOG_DEBUG("Restarted on HTTP(s) Request\n");
webServerThread->requestRestart = (millis() / 1000) + 5;
}

View File

@@ -66,7 +66,7 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
// if handled == false, then let others look at this message also if they want
bool handled = false;
assert(r);
bool fromOthers = mp.from != 0 && mp.from != nodeDB->getNodeNum();
bool fromOthers = !isFromUs(&mp);
if (mp.which_payload_variant != meshtastic_MeshPacket_decoded_tag) {
return handled;
}
@@ -432,6 +432,8 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c)
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
if (config.device.double_tap_as_button_press == false && c.payload_variant.device.double_tap_as_button_press == true &&
accelerometerThread->enabled == false) {
config.device.double_tap_as_button_press = c.payload_variant.device.double_tap_as_button_press;
accelerometerThread->enabled = true;
accelerometerThread->start();
}
#endif
@@ -465,7 +467,7 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c)
requiresReboot = true;
}
}
#if EVENT_MODE
#if USERPREFS_EVENT_MODE
// If we're in event mode, nobody is a Router or Repeater
if (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER ||
config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER) {
@@ -511,6 +513,8 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c)
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
if (config.display.wake_on_tap_or_motion == false && c.payload_variant.display.wake_on_tap_or_motion == true &&
accelerometerThread->enabled == false) {
config.display.wake_on_tap_or_motion = c.payload_variant.display.wake_on_tap_or_motion;
accelerometerThread->enabled = true;
accelerometerThread->start();
}
#endif
@@ -583,7 +587,7 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c)
break;
}
if (requiresReboot) {
if (requiresReboot && !hasOpenEditTransaction) {
disableBluetooth();
}
@@ -592,7 +596,8 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c)
void AdminModule::handleSetModuleConfig(const meshtastic_ModuleConfig &c)
{
disableBluetooth();
if (!hasOpenEditTransaction)
disableBluetooth();
switch (c.which_payload_variant) {
case meshtastic_ModuleConfig_mqtt_tag:
LOG_INFO("Setting module config: MQTT\n");
@@ -966,7 +971,7 @@ void AdminModule::saveChanges(int saveWhat, bool shouldReboot)
} else {
LOG_INFO("Delaying save of changes to disk until the open transaction is committed\n");
}
if (shouldReboot) {
if (shouldReboot && !hasOpenEditTransaction) {
reboot(DEFAULT_REBOOT_SECONDS);
}
}

View File

@@ -998,7 +998,7 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
int16_t rssiY = 130;
// If dislay is *slighly* too small for the original consants, squish up a bit
if (display->getHeight() < rssiY) {
if (display->getHeight() < rssiY + FONT_HEIGHT_SMALL) {
snrY = display->getHeight() - ((1.5) * FONT_HEIGHT_SMALL);
rssiY = display->getHeight() - ((2.5) * FONT_HEIGHT_SMALL);
}

View File

@@ -428,7 +428,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
drv.setWaveform(2, 0);
drv.go();
#endif
if (getFrom(&mp) != nodeDB->getNodeNum()) {
if (!isFromUs(&mp)) {
// Check if the message contains a bell character. Don't do this loop for every pin, just once.
auto &p = mp.decoded;
bool containsBell = false;
@@ -593,4 +593,4 @@ void ExternalNotificationModule::handleSetRingtone(const char *from_msg)
if (changed) {
nodeDB->saveProto(rtttlConfigFile, meshtastic_RTTTLConfig_size, &meshtastic_RTTTLConfig_msg, &rtttlConfig);
}
}
}

View File

@@ -209,13 +209,15 @@ void setupModules()
#if defined(USE_SX1280) && !MESHTASTIC_EXCLUDE_AUDIO
audioModule = new AudioModule();
#endif
#if !MESHTASTIC_EXCLUDE_STOREFORWARD
storeForwardModule = new StoreForwardModule();
#endif
#if !MESHTASTIC_EXCLUDE_PAXCOUNTER
paxcounterModule = new PaxcounterModule();
#endif
#endif
#if defined(ARCH_ESP32) || defined(ARCH_PORTDUINO)
#if !MESHTASTIC_EXCLUDE_STOREFORWARD
storeForwardModule = new StoreForwardModule();
#endif
#endif
#if defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040)
#if !MESHTASTIC_EXCLUDE_EXTERNALNOTIFICATION
externalNotificationModule = new ExternalNotificationModule();

View File

@@ -62,7 +62,8 @@ uint32_t NeighborInfoModule::collectNeighborInfo(meshtastic_NeighborInfo *neighb
NodeNum my_node_id = nodeDB->getNodeNum();
neighborInfo->node_id = my_node_id;
neighborInfo->last_sent_by_id = my_node_id;
neighborInfo->node_broadcast_interval_secs = moduleConfig.neighbor_info.update_interval;
neighborInfo->node_broadcast_interval_secs =
Default::getConfiguredOrDefault(moduleConfig.neighbor_info.update_interval, default_telemetry_broadcast_interval_secs);
cleanUpNeighbors();
@@ -84,11 +85,12 @@ uint32_t NeighborInfoModule::collectNeighborInfo(meshtastic_NeighborInfo *neighb
*/
void NeighborInfoModule::cleanUpNeighbors()
{
uint32_t now = getTime();
NodeNum my_node_id = nodeDB->getNodeNum();
for (auto it = neighbors.rbegin(); it != neighbors.rend();) {
// We will remove a neighbor if we haven't heard from them in twice the broadcast interval
if (!Throttle::isWithinTimespanMs(it->last_rx_time, it->node_broadcast_interval_secs * 2) &&
(it->node_id != my_node_id)) {
// cannot use isWithinTimespanMs() as it->last_rx_time is seconds since 1970
if ((now - it->last_rx_time > it->node_broadcast_interval_secs * 2) && (it->node_id != my_node_id)) {
LOG_DEBUG("Removing neighbor with node ID 0x%x\n", it->node_id);
it = std::vector<meshtastic_Neighbor>::reverse_iterator(
neighbors.erase(std::next(it).base())); // Erase the element and update the iterator

View File

@@ -26,7 +26,7 @@ bool NodeInfoModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes
}
// if user has changed while packet was not for us, inform phone
if (hasChanged && !wasBroadcast && mp.to != nodeDB->getNodeNum())
if (hasChanged && !wasBroadcast && !isToUs(&mp))
service->sendToPhone(packetPool.allocCopy(mp));
// LOG_DEBUG("did handleReceived\n");

View File

@@ -54,7 +54,7 @@ bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes
// 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)
bool isLocal = false;
if (nodeDB->getNodeNum() == getFrom(&mp)) {
if (isFromUs(&mp)) {
isLocal = true;
if (config.position.fixed_position) {
LOG_DEBUG("Ignore incoming position update from myself except for time, because position.fixed_position is true\n");
@@ -110,7 +110,7 @@ bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes
void PositionModule::alterReceivedProtobuf(meshtastic_MeshPacket &mp, meshtastic_Position *p)
{
// Phone position packets need to be truncated to the channel precision
if (nodeDB->getNodeNum() == getFrom(&mp) && (precision < 32 && precision > 0)) {
if (isFromUs(&mp) && (precision < 32 && precision > 0)) {
LOG_DEBUG("Truncating phone position to channel precision %i\n", precision);
p->latitude_i = p->latitude_i & (UINT32_MAX << (32 - precision));
p->longitude_i = p->longitude_i & (UINT32_MAX << (32 - precision));

View File

@@ -139,7 +139,7 @@ ProcessMessage RangeTestModuleRadio::handleReceived(const meshtastic_MeshPacket
LOG_INFO.getNodeNum(), mp.from, mp.to, mp.id, p.payload.size, p.payload.bytes);
*/
if (getFrom(&mp) != nodeDB->getNodeNum()) {
if (!isFromUs(&mp)) {
if (moduleConfig.range_test.save) {
appendFile(mp);

View File

@@ -28,7 +28,7 @@ bool RoutingModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mesh
// FIXME - move this to a non promsicious PhoneAPI module?
// Note: we are careful not to send back packets that started with the phone back to the phone
if ((mp.to == NODENUM_BROADCAST || mp.to == nodeDB->getNodeNum()) && (mp.from != 0)) {
if ((mp.to == NODENUM_BROADCAST || isToUs(&mp)) && (mp.from != 0)) {
printPacket("Delivering rx packet", &mp);
service->handleFromRadio(&mp);
}

View File

@@ -310,7 +310,7 @@ ProcessMessage SerialModuleRadio::handleReceived(const meshtastic_MeshPacket &mp
// LOG_DEBUG("Received text msg self=0x%0x, from=0x%0x, to=0x%0x, id=%d, msg=%.*s\n",
// nodeDB->getNodeNum(), mp.from, mp.to, mp.id, p.payload.size, p.payload.bytes);
if (getFrom(&mp) == nodeDB->getNodeNum()) {
if (!isFromUs(&mp)) {
/*
* If moduleConfig.serial.echo is true, then echo the packets that are sent out

View File

@@ -30,9 +30,6 @@
StoreForwardModule *storeForwardModule;
uint32_t lastHeartbeat = 0;
uint32_t heartbeatInterval = 60; // Default to 60 seconds, adjust as needed
int32_t StoreForwardModule::runOnce()
{
#if defined(ARCH_ESP32) || defined(ARCH_PORTDUINO)
@@ -49,7 +46,7 @@ int32_t StoreForwardModule::runOnce()
} else if (this->heartbeat && (!Throttle::isWithinTimespanMs(lastHeartbeat, heartbeatInterval * 1000)) &&
airTime->isTxAllowedChannelUtil(true)) {
lastHeartbeat = millis();
LOG_INFO("*** Sending heartbeat\n");
LOG_INFO("Sending heartbeat\n");
meshtastic_StoreAndForward sf = meshtastic_StoreAndForward_init_zero;
sf.rr = meshtastic_StoreAndForward_RequestResponse_ROUTER_HEARTBEAT;
sf.which_variant = meshtastic_StoreAndForward_heartbeat_tag;
@@ -73,8 +70,8 @@ void StoreForwardModule::populatePSRAM()
https://learn.upesy.com/en/programmation/psram.html#psram-tab
*/
LOG_DEBUG("*** Before PSRAM initialization: heap %d/%d PSRAM %d/%d\n", memGet.getFreeHeap(), memGet.getHeapSize(),
memGet.getFreePsram(), memGet.getPsramSize());
LOG_DEBUG("Before PSRAM init: heap %d/%d PSRAM %d/%d\n", memGet.getFreeHeap(), memGet.getHeapSize(), memGet.getFreePsram(),
memGet.getPsramSize());
/* Use a maximum of 2/3 the available PSRAM unless otherwise specified.
Note: This needs to be done after every thing that would use PSRAM
@@ -89,9 +86,9 @@ void StoreForwardModule::populatePSRAM()
#endif
LOG_DEBUG("*** After PSRAM initialization: heap %d/%d PSRAM %d/%d\n", memGet.getFreeHeap(), memGet.getHeapSize(),
memGet.getFreePsram(), memGet.getPsramSize());
LOG_DEBUG("*** numberOfPackets for packetHistory - %u\n", numberOfPackets);
LOG_DEBUG("After PSRAM init: heap %d/%d PSRAM %d/%d\n", memGet.getFreeHeap(), memGet.getHeapSize(), memGet.getFreePsram(),
memGet.getPsramSize());
LOG_DEBUG("numberOfPackets for packetHistory - %u\n", numberOfPackets);
}
/**
@@ -108,11 +105,11 @@ void StoreForwardModule::historySend(uint32_t secAgo, uint32_t to)
queueSize = this->historyReturnMax;
if (queueSize) {
LOG_INFO("*** S&F - Sending %u message(s)\n", queueSize);
LOG_INFO("S&F - Sending %u message(s)\n", queueSize);
this->busy = true; // runOnce() will pickup the next steps once busy = true.
this->busyTo = to;
} else {
LOG_INFO("*** S&F - No history to send\n");
LOG_INFO("S&F - No history\n");
}
meshtastic_StoreAndForward sf = meshtastic_StoreAndForward_init_zero;
sf.rr = meshtastic_StoreAndForward_RequestResponse_ROUTER_HISTORY;
@@ -190,7 +187,7 @@ void StoreForwardModule::historyAdd(const meshtastic_MeshPacket &mp)
const auto &p = mp.decoded;
if (this->packetHistoryTotalCount == this->records) {
LOG_WARN("*** S&F - PSRAM Full. Starting overwrite now.\n");
LOG_WARN("S&F - PSRAM Full. Starting overwrite.\n");
this->packetHistoryTotalCount = 0;
for (auto &i : lastRequest) {
i.second = 0; // Clear the last request index for each client device
@@ -218,7 +215,7 @@ bool StoreForwardModule::sendPayload(NodeNum dest, uint32_t last_time)
{
meshtastic_MeshPacket *p = preparePayload(dest, last_time);
if (p) {
LOG_INFO("*** Sending S&F Payload\n");
LOG_INFO("Sending S&F Payload\n");
service->sendToMesh(p);
this->requestCount++;
return true;
@@ -334,9 +331,9 @@ void StoreForwardModule::sendErrorTextMessage(NodeNum dest, bool want_response)
pr->decoded.portnum = meshtastic_PortNum_TEXT_MESSAGE_APP;
const char *str;
if (this->busy) {
str = "** S&F - Busy. Try again shortly.";
str = "S&F - Busy. Try again shortly.";
} else {
str = "** S&F - Not available on this channel.";
str = "S&F not permitted on the public channel.";
}
LOG_WARN("%s\n", str);
memcpy(pr->decoded.payload.bytes, str, strlen(str));
@@ -368,7 +365,7 @@ void StoreForwardModule::statsSend(uint32_t to)
sf.variant.stats.return_max = this->historyReturnMax;
sf.variant.stats.return_window = this->historyReturnWindow;
LOG_DEBUG("*** Sending S&F Stats\n");
LOG_DEBUG("Sending S&F Stats\n");
storeForwardModule->sendMessage(to, sf);
}
@@ -385,9 +382,8 @@ ProcessMessage StoreForwardModule::handleReceived(const meshtastic_MeshPacket &m
if ((mp.decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP) && is_server) {
auto &p = mp.decoded;
if (mp.to == nodeDB->getNodeNum() && (p.payload.bytes[0] == 'S') && (p.payload.bytes[1] == 'F') &&
(p.payload.bytes[2] == 0x00)) {
LOG_DEBUG("*** Legacy Request to send\n");
if (isToUs(&mp) && (p.payload.bytes[0] == 'S') && (p.payload.bytes[1] == 'F') && (p.payload.bytes[2] == 0x00)) {
LOG_DEBUG("Legacy Request to send\n");
// Send the last 60 minutes of messages.
if (this->busy || channels.isDefaultChannel(mp.channel)) {
@@ -397,9 +393,9 @@ ProcessMessage StoreForwardModule::handleReceived(const meshtastic_MeshPacket &m
}
} else {
storeForwardModule->historyAdd(mp);
LOG_INFO("*** S&F stored. Message history contains %u records now.\n", this->packetHistoryTotalCount);
LOG_INFO("S&F stored. Message history contains %u records now.\n", this->packetHistoryTotalCount);
}
} else if (getFrom(&mp) != nodeDB->getNodeNum() && mp.decoded.portnum == meshtastic_PortNum_STORE_FORWARD_APP) {
} else if (!isFromUs(&mp) && mp.decoded.portnum == meshtastic_PortNum_STORE_FORWARD_APP) {
auto &p = mp.decoded;
meshtastic_StoreAndForward scratch;
meshtastic_StoreAndForward *decoded = NULL;
@@ -443,7 +439,7 @@ bool StoreForwardModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp,
if (is_server) {
// stop sending stuff, the client wants to abort or has another error
if ((this->busy) && (this->busyTo == getFrom(&mp))) {
LOG_ERROR("*** Client in ERROR or ABORT requested\n");
LOG_ERROR("Client in ERROR or ABORT requested\n");
this->requestCount = 0;
this->busy = false;
}
@@ -453,7 +449,7 @@ bool StoreForwardModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp,
case meshtastic_StoreAndForward_RequestResponse_CLIENT_HISTORY:
if (is_server) {
requests_history++;
LOG_INFO("*** Client Request to send HISTORY\n");
LOG_INFO("Client Request to send HISTORY\n");
// Send the last 60 minutes of messages.
if (this->busy || channels.isDefaultChannel(mp.channel)) {
sendErrorTextMessage(getFrom(&mp), mp.decoded.want_response);
@@ -470,7 +466,6 @@ bool StoreForwardModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp,
case meshtastic_StoreAndForward_RequestResponse_CLIENT_PING:
if (is_server) {
LOG_INFO("*** StoreAndForward_RequestResponse_CLIENT_PING\n");
// respond with a ROUTER PONG
storeForwardModule->sendMessage(getFrom(&mp), meshtastic_StoreAndForward_RequestResponse_ROUTER_PONG);
}
@@ -478,17 +473,16 @@ bool StoreForwardModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp,
case meshtastic_StoreAndForward_RequestResponse_CLIENT_PONG:
if (is_server) {
LOG_INFO("*** StoreAndForward_RequestResponse_CLIENT_PONG\n");
// NodeDB is already updated
}
break;
case meshtastic_StoreAndForward_RequestResponse_CLIENT_STATS:
if (is_server) {
LOG_INFO("*** Client Request to send STATS\n");
LOG_INFO("Client Request to send STATS\n");
if (this->busy) {
storeForwardModule->sendMessage(getFrom(&mp), meshtastic_StoreAndForward_RequestResponse_ROUTER_BUSY);
LOG_INFO("*** S&F - Busy. Try again shortly.\n");
LOG_INFO("S&F - Busy. Try again shortly.\n");
} else {
storeForwardModule->statsSend(getFrom(&mp));
}
@@ -498,7 +492,7 @@ bool StoreForwardModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp,
case meshtastic_StoreAndForward_RequestResponse_ROUTER_ERROR:
case meshtastic_StoreAndForward_RequestResponse_ROUTER_BUSY:
if (is_client) {
LOG_DEBUG("*** StoreAndForward_RequestResponse_ROUTER_BUSY\n");
LOG_DEBUG("StoreAndForward_RequestResponse_ROUTER_BUSY\n");
// retry in messages_saved * packetTimeMax ms
retry_delay = millis() + getNumAvailablePackets(this->busyTo, this->last_time) * packetTimeMax *
(meshtastic_StoreAndForward_RequestResponse_ROUTER_ERROR ? 2 : 1);
@@ -514,13 +508,12 @@ bool StoreForwardModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp,
heartbeatInterval = p->variant.heartbeat.period;
}
lastHeartbeat = millis();
LOG_INFO("*** StoreAndForward Heartbeat received\n");
LOG_INFO("StoreAndForward Heartbeat received\n");
}
break;
case meshtastic_StoreAndForward_RequestResponse_ROUTER_PING:
if (is_client) {
LOG_DEBUG("*** StoreAndForward_RequestResponse_ROUTER_PING\n");
// respond with a CLIENT PONG
storeForwardModule->sendMessage(getFrom(&mp), meshtastic_StoreAndForward_RequestResponse_CLIENT_PONG);
}
@@ -528,7 +521,7 @@ bool StoreForwardModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp,
case meshtastic_StoreAndForward_RequestResponse_ROUTER_STATS:
if (is_client) {
LOG_DEBUG("*** Router Response STATS\n");
LOG_DEBUG("Router Response STATS\n");
// These fields only have informational purpose on a client. Fill them to consume later.
if (p->which_variant == meshtastic_StoreAndForward_stats_tag) {
this->records = p->variant.stats.messages_max;
@@ -546,7 +539,7 @@ bool StoreForwardModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp,
// These fields only have informational purpose on a client. Fill them to consume later.
if (p->which_variant == meshtastic_StoreAndForward_history_tag) {
this->historyReturnWindow = p->variant.history.window / 60000;
LOG_INFO("*** Router Response HISTORY - Sending %d messages from last %d minutes\n",
LOG_INFO("Router Response HISTORY - Sending %d messages from last %d minutes\n",
p->variant.history.history_messages, this->historyReturnWindow);
}
}
@@ -580,7 +573,7 @@ StoreForwardModule::StoreForwardModule()
// Router
if ((config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER || moduleConfig.store_forward.is_server)) {
LOG_INFO("*** Initializing Store & Forward Module in Server mode\n");
LOG_INFO("Initializing Store & Forward Module in Server mode\n");
if (memGet.getPsramSize() > 0) {
if (memGet.getFreePsram() >= 1024 * 1024) {
@@ -608,18 +601,17 @@ StoreForwardModule::StoreForwardModule()
this->populatePSRAM();
is_server = true;
} else {
LOG_INFO("*** Device has less than 1M of PSRAM free.\n");
LOG_INFO("*** Store & Forward Module - disabling server.\n");
LOG_INFO(".\n");
LOG_INFO("S&F: not enough PSRAM free, disabling.\n");
}
} else {
LOG_INFO("*** Device doesn't have PSRAM.\n");
LOG_INFO("*** Store & Forward Module - disabling server.\n");
LOG_INFO("S&F: device doesn't have PSRAM, disabling.\n");
}
// Client
} else {
is_client = true;
LOG_INFO("*** Initializing Store & Forward Module in Client mode\n");
LOG_INFO("Initializing Store & Forward Module in Client mode\n");
}
} else {
disable();

View File

@@ -127,6 +127,11 @@ void DeviceTelemetryModule::sendLocalStatsToPhone()
telemetry.variant.local_stats.num_packets_tx = RadioLibInterface::instance->txGood;
telemetry.variant.local_stats.num_packets_rx = RadioLibInterface::instance->rxGood + RadioLibInterface::instance->rxBad;
telemetry.variant.local_stats.num_packets_rx_bad = RadioLibInterface::instance->rxBad;
telemetry.variant.local_stats.num_tx_relay = RadioLibInterface::instance->txRelay;
}
if (router) {
telemetry.variant.local_stats.num_rx_dupe = router->rxDupe;
telemetry.variant.local_stats.num_tx_relay_canceled = router->txRelayCanceled;
}
LOG_INFO(

View File

@@ -255,7 +255,7 @@ bool PowerTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
service->sendToMesh(p, RX_SRC_LOCAL, true);
if (config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR && config.power.is_power_saving) {
LOG_DEBUG("Starting next execution in 5 seconds and then going to sleep.\n");
LOG_DEBUG("Starting next execution in 5s then going to sleep.\n");
sleepOnNextExecution = true;
setIntervalFromNow(5000);
}

View File

@@ -19,7 +19,7 @@ MAX17048Singleton *MAX17048Singleton::pinstance{nullptr};
bool MAX17048Singleton::runOnce(TwoWire *theWire)
{
initialized = begin(theWire);
LOG_DEBUG("MAX17048Sensor::runOnce %s\n", initialized ? "began ok" : "begin failed");
LOG_DEBUG("%s::runOnce %s\n", sensorStr, initialized ? "began ok" : "begin failed");
return initialized;
}
@@ -27,7 +27,7 @@ bool MAX17048Singleton::isBatteryCharging()
{
float volts = cellVoltage();
if (isnan(volts)) {
LOG_DEBUG("MAX17048Sensor::isBatteryCharging is not connected\n");
LOG_DEBUG("%s::isBatteryCharging is not connected\n", sensorStr);
return 0;
}
@@ -53,7 +53,7 @@ bool MAX17048Singleton::isBatteryCharging()
chargeState = MAX17048ChargeState::IDLE;
}
LOG_DEBUG("MAX17048Sensor::isBatteryCharging %s volts: %.3f soc: %.3f rate: %.3f\n", chargeLabels[chargeState], volts,
LOG_DEBUG("%s::isBatteryCharging %s volts: %.3f soc: %.3f rate: %.3f\n", sensorStr, chargeLabels[chargeState], volts,
sample.cellPercent, sample.chargeRate);
return chargeState == MAX17048ChargeState::IMPORT;
}
@@ -62,17 +62,17 @@ uint16_t MAX17048Singleton::getBusVoltageMv()
{
float volts = cellVoltage();
if (isnan(volts)) {
LOG_DEBUG("MAX17048Sensor::getBusVoltageMv is not connected\n");
LOG_DEBUG("%s::getBusVoltageMv is not connected\n", sensorStr);
return 0;
}
LOG_DEBUG("MAX17048Sensor::getBusVoltageMv %.3fmV\n", volts);
LOG_DEBUG("%s::getBusVoltageMv %.3fmV\n", sensorStr, volts);
return (uint16_t)(volts * 1000.0f);
}
uint8_t MAX17048Singleton::getBusBatteryPercent()
{
float soc = cellPercent();
LOG_DEBUG("MAX17048Sensor::getBusBatteryPercent %.1f%%\n", soc);
LOG_DEBUG("%s::getBusBatteryPercent %.1f%%\n", sensorStr, soc);
return clamp(static_cast<uint8_t>(round(soc)), static_cast<uint8_t>(0), static_cast<uint8_t>(100));
}
@@ -82,7 +82,7 @@ uint16_t MAX17048Singleton::getTimeToGoSecs()
float soc = cellPercent(); // state of charge in percent 0 to 100
soc = clamp(soc, 0.0f, 100.0f); // clamp soc between 0 and 100%
float ttg = ((100.0f - soc) / rate) * 3600.0f; // calculate seconds to charge/discharge
LOG_DEBUG("MAX17048Sensor::getTimeToGoSecs %.0f seconds\n", ttg);
LOG_DEBUG("%s::getTimeToGoSecs %.0f seconds\n", sensorStr, ttg);
return (uint16_t)ttg;
}
@@ -90,7 +90,7 @@ bool MAX17048Singleton::isBatteryConnected()
{
float volts = cellVoltage();
if (isnan(volts)) {
LOG_DEBUG("MAX17048Sensor::isBatteryConnected is not connected\n");
LOG_DEBUG("%s::isBatteryConnected is not connected\n", sensorStr);
return false;
}
@@ -103,12 +103,12 @@ bool MAX17048Singleton::isExternallyPowered()
float volts = cellVoltage();
if (isnan(volts)) {
// if the battery is not connected then there must be external power
LOG_DEBUG("MAX17048Sensor::isExternallyPowered battery is\n");
LOG_DEBUG("%s::isExternallyPowered battery is\n", sensorStr);
return true;
}
// if the bus voltage is over MAX17048_BUS_POWER_VOLTS, then the external power
// is assumed to be connected
LOG_DEBUG("MAX17048Sensor::isExternallyPowered %s connected\n", volts >= MAX17048_BUS_POWER_VOLTS ? "is" : "is not");
LOG_DEBUG("%s::isExternallyPowered %s connected\n", sensorStr, volts >= MAX17048_BUS_POWER_VOLTS ? "is" : "is not");
return volts >= MAX17048_BUS_POWER_VOLTS;
}

View File

@@ -40,6 +40,7 @@ class MAX17048Singleton : public Adafruit_MAX17048
std::queue<MAX17048ChargeSample> chargeSamples;
MAX17048ChargeState chargeState = IDLE;
const String chargeLabels[3] = {F("idle"), F("export"), F("import")};
const char *sensorStr = "MAX17048Sensor";
protected:
MAX17048Singleton();

View File

@@ -16,8 +16,8 @@ void TraceRouteModule::alterReceivedProtobuf(meshtastic_MeshPacket &p, meshtasti
// Insert unknown hops if necessary
insertUnknownHops(p, r, !incoming.request_id);
// Append ID and SNR. For the last hop (p.to == nodeDB->getNodeNum()), we only need to append the SNR
appendMyIDandSNR(r, p.rx_snr, !incoming.request_id, p.to == nodeDB->getNodeNum());
// Append ID and SNR. If the last hop is to us, we only need to append the SNR
appendMyIDandSNR(r, p.rx_snr, !incoming.request_id, isToUs(&p));
if (!incoming.request_id)
printRoute(r, p.from, p.to, true);
else
@@ -101,7 +101,7 @@ void TraceRouteModule::appendMyIDandSNR(meshtastic_RouteDiscovery *updated, floa
route[*route_count] = myNodeInfo.my_node_num;
*route_count += 1;
} else {
LOG_WARN("Route exceeded maximum hop limit, are you bridging networks?\n");
LOG_WARN("Route exceeded maximum hop limit!\n"); // Are you bridging networks?
}
}

View File

@@ -273,7 +273,7 @@ ProcessMessage AudioModule::handleReceived(const meshtastic_MeshPacket &mp)
{
if ((moduleConfig.audio.codec2_enabled) && (myRegion->audioPermitted)) {
auto &p = mp.decoded;
if (getFrom(&mp) != nodeDB->getNodeNum()) {
if (!isFromUs(&mp)) {
memcpy(rx_encode_frame, p.payload.bytes, p.payload.size);
radio_state = RadioState::rx;
rx_encode_frame_index = p.payload.size;

View File

@@ -150,7 +150,7 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length)
// 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
// receives it when we get our own packet back. Then we'll stop our retransmissions.
if (e.packet && getFrom(e.packet) == nodeDB->getNodeNum())
if (e.packet && isFromUs(e.packet))
routingModule->sendAckNak(meshtastic_Routing_Error_NONE, getFrom(e.packet), e.packet->id, ch.index);
else
LOG_INFO("Ignoring downlink message we originally sent.\n");
@@ -162,7 +162,7 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length)
meshtastic_MeshPacket *p = packetPool.allocCopy(*e.packet);
p->via_mqtt = true; // Mark that the packet was received via MQTT
if (p->from == 0 || p->from == nodeDB->getNodeNum()) {
if (isFromUs(p)) {
LOG_INFO("Ignoring downlink message we originally sent.\n");
packetPool.release(p);
return;
@@ -188,7 +188,7 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length)
const meshtastic_NodeInfoLite *rx = nodeDB->getMeshNode(p->to);
// Only accept PKI messages to us, or if we have both the sender and receiver in our nodeDB, as then it's
// likely they discovered each other via a channel we have downlink enabled for
if (p->to == nodeDB->getNodeNum() || (tx && tx->has_user && rx && rx->has_user))
if (isToUs(p) || (tx && tx->has_user && rx && rx->has_user))
router->enqueueReceivedMessage(p);
} else if (router && perhapsDecode(p)) // ignore messages if we don't have the channel key
router->enqueueReceivedMessage(p);
@@ -542,7 +542,7 @@ void MQTT::onSend(const meshtastic_MeshPacket &mp, const meshtastic_MeshPacket &
}
// check for the lowest bit of the data bitfield set false, and the use of one of the default keys.
if (mp_decoded.from != nodeDB->getNodeNum() && mp_decoded.decoded.has_bitfield &&
if (!isFromUs(&mp_decoded) && mp_decoded.decoded.has_bitfield &&
!(mp_decoded.decoded.bitfield & BITFIELD_OK_TO_MQTT_MASK) &&
(ch.settings.psk.size < 2 || (ch.settings.psk.size == 16 && memcmp(ch.settings.psk.bytes, defaultpsk, 16)) ||
(ch.settings.psk.size == 32 && memcmp(ch.settings.psk.bytes, eventpsk, 32)))) {
@@ -692,4 +692,4 @@ bool MQTT::isValidJsonEnvelope(JSONObject &json)
(json["from"]->AsNumber() == nodeDB->getNodeNum()) && // only accept message if the "from" is us
(json.find("type") != json.end()) && json["type"]->IsString() && // should specify a type
(json.find("payload") != json.end()); // should have a payload
}
}

View File

@@ -223,6 +223,8 @@ void portduinoSetup()
settingsMap[displayPanel] = st7796;
else if (yamlConfig["Display"]["Panel"].as<std::string>("") == "ILI9341")
settingsMap[displayPanel] = ili9341;
else if (yamlConfig["Display"]["Panel"].as<std::string>("") == "ILI9342")
settingsMap[displayPanel] = ili9342;
else if (yamlConfig["Display"]["Panel"].as<std::string>("") == "ILI9488")
settingsMap[displayPanel] = ili9488;
else if (yamlConfig["Display"]["Panel"].as<std::string>("") == "HX8357D")

View File

@@ -57,7 +57,7 @@ enum configNames {
maxnodes,
ascii_logs
};
enum { no_screen, x11, st7789, st7735, st7735s, st7796, ili9341, ili9488, hx8357d };
enum { no_screen, x11, st7789, st7735, st7735s, st7796, ili9341, ili9342, ili9488, hx8357d };
enum { no_touchscreen, xpt2046, stmpe610, gt911, ft5x06 };
enum { level_error, level_warn, level_info, level_debug, level_trace };

Some files were not shown because too many files have changed in this diff Show More