mirror of
https://github.com/meshtastic/firmware.git
synced 2026-01-04 17:11:01 +00:00
Compare commits
49 Commits
c8628b3422
...
revert-nim
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
57786c1481 | ||
|
|
761bd41b35 | ||
|
|
ea4b6f321b | ||
|
|
e24e717127 | ||
|
|
510c15c581 | ||
|
|
c017cd1a02 | ||
|
|
ef30fd850d | ||
|
|
5fd61b7c83 | ||
|
|
b9a0015149 | ||
|
|
09c818d075 | ||
|
|
9673cfb0b2 | ||
|
|
757f7b68d6 | ||
|
|
5510dae8d3 | ||
|
|
52fd362720 | ||
|
|
33e1f58f6e | ||
|
|
9dc7ef612e | ||
|
|
b2c82bdc41 | ||
|
|
54a928f47f | ||
|
|
33f18659c8 | ||
|
|
3a7093a973 | ||
|
|
a4f6f4515a | ||
|
|
d609d05698 | ||
|
|
83c6161ac6 | ||
|
|
d93d68d31e | ||
|
|
1021d967da | ||
|
|
217abc4c10 | ||
|
|
e6af68bd14 | ||
|
|
530f0135ee | ||
|
|
208a873c4c | ||
|
|
f57eb6f27d | ||
|
|
155cdf9f9d | ||
|
|
661f49ad7a | ||
|
|
31e55d0b66 | ||
|
|
85aba3a4f7 | ||
|
|
5262233b2d | ||
|
|
40f1f91c0d | ||
|
|
269dee7a2d | ||
|
|
8e0547e76d | ||
|
|
8a48321555 | ||
|
|
aa8bb6c6f1 | ||
|
|
1952982896 | ||
|
|
de2b9632bb | ||
|
|
c2b7dc2641 | ||
|
|
b74238194b | ||
|
|
5d5819b876 | ||
|
|
f127702bef | ||
|
|
cce8cbfe34 | ||
|
|
a4a6c3509a | ||
|
|
68250dc937 |
2
.github/actions/build-variant/action.yml
vendored
2
.github/actions/build-variant/action.yml
vendored
@@ -100,7 +100,7 @@ runs:
|
||||
id: version
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: firmware-${{ inputs.arch }}-${{ inputs.board }}-${{ steps.version.outputs.long }}
|
||||
overwrite: true
|
||||
|
||||
2
.github/workflows/build_debian_src.yml
vendored
2
.github/workflows/build_debian_src.yml
vendored
@@ -64,7 +64,7 @@ jobs:
|
||||
PKG_VERSION: ${{ steps.version.outputs.deb }}
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
|
||||
overwrite: true
|
||||
|
||||
10
.github/workflows/build_firmware.yml
vendored
10
.github/workflows/build_firmware.yml
vendored
@@ -56,19 +56,21 @@ jobs:
|
||||
ota_firmware_source: ${{ steps.ota_dir.outputs.src || '' }}
|
||||
ota_firmware_target: ${{ steps.ota_dir.outputs.tgt || '' }}
|
||||
|
||||
- name: Echo manifest from release/firmware-*.mt.json to job summary
|
||||
if: ${{ always() }}
|
||||
- name: Job summary
|
||||
env:
|
||||
PIO_ENV: ${{ inputs.pio_env }}
|
||||
run: |
|
||||
echo "## Manifest: \`$PIO_ENV\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "## $PIO_ENV" >> $GITHUB_STEP_SUMMARY
|
||||
echo "<details><summary><strong>Manifest</strong></summary>" >> $GITHUB_STEP_SUMMARY
|
||||
echo '' >> $GITHUB_STEP_SUMMARY
|
||||
echo '```json' >> $GITHUB_STEP_SUMMARY
|
||||
cat release/firmware-*.mt.json >> $GITHUB_STEP_SUMMARY
|
||||
echo '' >> $GITHUB_STEP_SUMMARY
|
||||
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||
echo "</details>" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
id: upload
|
||||
with:
|
||||
name: firmware-${{ inputs.platform }}-${{ inputs.pio_env }}-${{ inputs.version }}
|
||||
|
||||
8
.github/workflows/build_one_target.yml
vendored
8
.github/workflows/build_one_target.yml
vendored
@@ -98,7 +98,7 @@ jobs:
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
path: ./
|
||||
pattern: firmware-*-*
|
||||
@@ -111,7 +111,7 @@ jobs:
|
||||
run: mv -b -t ./ ./bin/device-*.sh ./bin/device-*.bat
|
||||
|
||||
- name: Repackage in single firmware zip
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: firmware-${{inputs.target}}-${{ needs.version.outputs.long }}
|
||||
overwrite: true
|
||||
@@ -127,7 +127,7 @@ jobs:
|
||||
./Meshtastic_nRF52_factory_erase*.uf2
|
||||
retention-days: 30
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: firmware-*-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
@@ -146,7 +146,7 @@ jobs:
|
||||
run: zip -j -9 -r ./firmware-${{inputs.target}}-${{ needs.version.outputs.long }}.zip ./output
|
||||
|
||||
- name: Repackage in single elfs zip
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: debug-elfs-${{inputs.target}}-${{ needs.version.outputs.long }}.zip
|
||||
overwrite: true
|
||||
|
||||
22
.github/workflows/main_matrix.yml
vendored
22
.github/workflows/main_matrix.yml
vendored
@@ -173,7 +173,7 @@ jobs:
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
path: ./
|
||||
pattern: firmware-${{matrix.arch}}-*
|
||||
@@ -183,7 +183,7 @@ jobs:
|
||||
run: ls -R
|
||||
|
||||
- name: Repackage in single firmware zip
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
overwrite: true
|
||||
@@ -200,7 +200,7 @@ jobs:
|
||||
./Meshtastic_nRF52_factory_erase*.uf2
|
||||
retention-days: 30
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
@@ -219,7 +219,7 @@ jobs:
|
||||
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output
|
||||
|
||||
- name: Repackage in single elfs zip
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
overwrite: true
|
||||
@@ -260,14 +260,14 @@ jobs:
|
||||
Autogenerated by github action, developer should edit as required before publishing...
|
||||
|
||||
- name: Download source deb
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: firmware-debian-${{ needs.version.outputs.deb }}~UNRELEASED-src
|
||||
merge-multiple: true
|
||||
path: ./output/debian-src
|
||||
|
||||
- name: Download `native-tft` pio deps
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: platformio-deps-native-tft-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
@@ -291,7 +291,7 @@ jobs:
|
||||
}' > firmware-${{ needs.version.outputs.long }}.json
|
||||
|
||||
- name: Save Release manifest artifact
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: manifest-${{ needs.version.outputs.long }}
|
||||
overwrite: true
|
||||
@@ -332,7 +332,7 @@ jobs:
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
@@ -349,7 +349,7 @@ jobs:
|
||||
- name: Zip firmware
|
||||
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
@@ -388,14 +388,14 @@ jobs:
|
||||
python-version: 3.x
|
||||
|
||||
- name: Get firmware artifacts
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: firmware-{${{ env.targets }}}-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
path: ./publish
|
||||
|
||||
- name: Get manifest artifact
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: manifest-${{ needs.version.outputs.long }}
|
||||
path: ./publish
|
||||
|
||||
18
.github/workflows/merge_queue.yml
vendored
18
.github/workflows/merge_queue.yml
vendored
@@ -147,7 +147,7 @@ jobs:
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
path: ./
|
||||
pattern: firmware-${{matrix.arch}}-*
|
||||
@@ -160,7 +160,7 @@ jobs:
|
||||
run: mv -b -t ./ ./bin/device-*.sh ./bin/device-*.bat
|
||||
|
||||
- name: Repackage in single firmware zip
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
overwrite: true
|
||||
@@ -176,7 +176,7 @@ jobs:
|
||||
./Meshtastic_nRF52_factory_erase*.uf2
|
||||
retention-days: 30
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
@@ -195,7 +195,7 @@ jobs:
|
||||
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output
|
||||
|
||||
- name: Repackage in single elfs zip
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
overwrite: true
|
||||
@@ -235,14 +235,14 @@ jobs:
|
||||
Autogenerated by github action, developer should edit as required before publishing...
|
||||
|
||||
- name: Download source deb
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: firmware-debian-${{ needs.version.outputs.deb }}~UNRELEASED-src
|
||||
merge-multiple: true
|
||||
path: ./output/debian-src
|
||||
|
||||
- name: Download `native-tft` pio deps
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: platformio-deps-native-tft-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
@@ -292,7 +292,7 @@ jobs:
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
@@ -309,7 +309,7 @@ jobs:
|
||||
- name: Zip firmware
|
||||
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
@@ -347,7 +347,7 @@ jobs:
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: firmware-{${{ env.targets }}}-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
|
||||
2
.github/workflows/package_obs.yml
vendored
2
.github/workflows/package_obs.yml
vendored
@@ -58,7 +58,7 @@ jobs:
|
||||
id: version
|
||||
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
|
||||
merge-multiple: true
|
||||
|
||||
2
.github/workflows/package_pio_deps.yml
vendored
2
.github/workflows/package_pio_deps.yml
vendored
@@ -56,7 +56,7 @@ jobs:
|
||||
PLATFORMIO_CORE_DIR: pio/core
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: platformio-deps-${{ inputs.pio_env }}-${{ steps.version.outputs.long }}
|
||||
overwrite: true
|
||||
|
||||
2
.github/workflows/package_ppa.yml
vendored
2
.github/workflows/package_ppa.yml
vendored
@@ -60,7 +60,7 @@ jobs:
|
||||
id: version
|
||||
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
|
||||
merge-multiple: true
|
||||
|
||||
2
.github/workflows/pr_tests.yml
vendored
2
.github/workflows/pr_tests.yml
vendored
@@ -50,7 +50,7 @@ jobs:
|
||||
|
||||
- name: Download test artifacts
|
||||
if: needs.native-tests.result != 'skipped'
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: platformio-test-report-${{ steps.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
|
||||
2
.github/workflows/sec_sast_semgrep_cron.yml
vendored
2
.github/workflows/sec_sast_semgrep_cron.yml
vendored
@@ -33,7 +33,7 @@ jobs:
|
||||
|
||||
# step 3
|
||||
- name: save report as pipeline artifact
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: report.sarif
|
||||
overwrite: true
|
||||
|
||||
12
.github/workflows/test_native.yml
vendored
12
.github/workflows/test_native.yml
vendored
@@ -59,7 +59,7 @@ jobs:
|
||||
id: version
|
||||
|
||||
- name: Save coverage information
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
if: always() # run this step even if previous step failed
|
||||
with:
|
||||
name: lcov-coverage-info-native-simulator-test-${{ steps.version.outputs.long }}
|
||||
@@ -94,7 +94,7 @@ jobs:
|
||||
|
||||
- name: Save test results
|
||||
if: always() # run this step even if previous step failed
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: platformio-test-report-${{ steps.version.outputs.long }}
|
||||
overwrite: true
|
||||
@@ -108,7 +108,7 @@ jobs:
|
||||
sed -i -e "s#${PWD}#.#" coverage_tests.info # Make paths relative.
|
||||
|
||||
- name: Save coverage information
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
if: always() # run this step even if previous step failed
|
||||
with:
|
||||
name: lcov-coverage-info-native-platformio-tests-${{ steps.version.outputs.long }}
|
||||
@@ -137,7 +137,7 @@ jobs:
|
||||
id: version
|
||||
|
||||
- name: Download test artifacts
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: platformio-test-report-${{ steps.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
@@ -150,7 +150,7 @@ jobs:
|
||||
reporter: java-junit
|
||||
|
||||
- name: Download coverage artifacts
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: lcov-coverage-info-native-*-${{ steps.version.outputs.long }}
|
||||
path: code-coverage-report
|
||||
@@ -163,7 +163,7 @@ jobs:
|
||||
genhtml --quiet --legend --prefix "${PWD}" code-coverage-report/coverage_src.info --output-directory code-coverage-report
|
||||
|
||||
- name: Save Code Coverage Report
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: code-coverage-report-${{ steps.version.outputs.long }}
|
||||
path: code-coverage-report
|
||||
|
||||
@@ -8,15 +8,15 @@ plugins:
|
||||
uri: https://github.com/trunk-io/plugins
|
||||
lint:
|
||||
enabled:
|
||||
- checkov@3.2.495
|
||||
- renovate@42.44.0
|
||||
- checkov@3.2.496
|
||||
- renovate@42.66.11
|
||||
- prettier@3.7.4
|
||||
- trufflehog@3.92.2
|
||||
- trufflehog@3.92.4
|
||||
- yamllint@1.37.1
|
||||
- bandit@1.9.2
|
||||
- trivy@0.68.1
|
||||
- trivy@0.68.2
|
||||
- taplo@0.10.0
|
||||
- ruff@0.14.8
|
||||
- ruff@0.14.10
|
||||
- isort@7.0.0
|
||||
- markdownlint@0.47.0
|
||||
- oxipng@10.0.0
|
||||
|
||||
@@ -21,13 +21,14 @@ rm -f $BUILDDIR/firmware*
|
||||
export APP_VERSION=$VERSION
|
||||
|
||||
basename=firmware-$1-$VERSION
|
||||
ota_basename=${basename}-ota
|
||||
|
||||
pio run --environment $1 -t mtjson # -v
|
||||
|
||||
cp $BUILDDIR/$basename.elf $OUTDIR/$basename.elf
|
||||
|
||||
echo "Copying NRF52 dfu (OTA) file"
|
||||
cp $BUILDDIR/$basename.zip $OUTDIR/$basename.zip
|
||||
cp $BUILDDIR/$basename.zip $OUTDIR/$ota_basename.zip
|
||||
|
||||
echo "Copying NRF52 UF2 file"
|
||||
cp $BUILDDIR/$basename.uf2 $OUTDIR/$basename.uf2
|
||||
|
||||
@@ -184,6 +184,8 @@ Input:
|
||||
Logging:
|
||||
LogLevel: info # debug, info, warn, error
|
||||
# TraceFile: /var/log/meshtasticd.json
|
||||
# JSONFile: /packets.json # File location for JSON output of decoded packets
|
||||
# JSONFilter: position # filter for packets to save to JSON file
|
||||
# AsciiLogs: true # default if not specified is !isatty() on stdout
|
||||
|
||||
Webserver:
|
||||
|
||||
@@ -17,6 +17,8 @@ lfsbin = f"{progname.replace('firmware-', 'littlefs-')}.bin"
|
||||
|
||||
def manifest_gather(source, target, env):
|
||||
out = []
|
||||
board_platform = env.BoardConfig().get("platform")
|
||||
needs_ota_suffix = board_platform == "nordicnrf52"
|
||||
check_paths = [
|
||||
progname,
|
||||
f"{progname}.elf",
|
||||
@@ -32,8 +34,11 @@ def manifest_gather(source, target, env):
|
||||
for p in check_paths:
|
||||
f = env.File(env.subst(f"$BUILD_DIR/{p}"))
|
||||
if f.exists():
|
||||
manifest_name = p
|
||||
if needs_ota_suffix and p == f"{progname}.zip":
|
||||
manifest_name = f"{progname}-ota.zip"
|
||||
d = {
|
||||
"name": p,
|
||||
"name": manifest_name,
|
||||
"md5": f.get_content_hash(), # Returns MD5 hash
|
||||
"bytes": f.get_size() # Returns file size in bytes
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ monitor_speed = 115200
|
||||
monitor_filters = direct
|
||||
lib_deps =
|
||||
# renovate: datasource=git-refs depName=meshtastic-esp8266-oled-ssd1306 packageName=https://github.com/meshtastic/esp8266-oled-ssd1306 gitBranch=master
|
||||
https://github.com/meshtastic/esp8266-oled-ssd1306/archive/2887bf4a19f64d92c984dcc8fd5ca7429e425e4a.zip
|
||||
https://github.com/meshtastic/esp8266-oled-ssd1306/archive/b34c6817c25d6faabb3a8a162b5d14fb75395433.zip
|
||||
# renovate: datasource=git-refs depName=meshtastic-OneButton packageName=https://github.com/meshtastic/OneButton gitBranch=master
|
||||
https://github.com/meshtastic/OneButton/archive/fa352d668c53f290cfa480a5f79ad422cd828c70.zip
|
||||
# renovate: datasource=git-refs depName=meshtastic-arduino-fsm packageName=https://github.com/meshtastic/arduino-fsm gitBranch=master
|
||||
@@ -123,7 +123,7 @@ lib_deps =
|
||||
[device-ui_base]
|
||||
lib_deps =
|
||||
# renovate: datasource=git-refs depName=meshtastic/device-ui packageName=https://github.com/meshtastic/device-ui gitBranch=master
|
||||
https://github.com/meshtastic/device-ui/archive/2746a1ce3804998460a2cb319b8ea8a238dfd8c9.zip
|
||||
https://github.com/meshtastic/device-ui/archive/7656d49ea2bdb81a43afc1e8552f1cc86b8dce3c.zip
|
||||
|
||||
; Common libs for environmental measurements in telemetry module
|
||||
[environmental_base]
|
||||
|
||||
Submodule protobufs updated: 4095e59890...9beb80f1d3
@@ -31,6 +31,9 @@ const char *DisplayFormatters::getModemPresetDisplayName(meshtastic_Config_LoRaC
|
||||
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST:
|
||||
return useShortName ? "LongF" : "LongFast";
|
||||
break;
|
||||
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_TURBO:
|
||||
return useShortName ? "LongT" : "LongTurbo";
|
||||
break;
|
||||
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE:
|
||||
return useShortName ? "LongM" : "LongMod";
|
||||
break;
|
||||
|
||||
@@ -20,12 +20,41 @@
|
||||
#include "modules/KeyVerificationModule.h"
|
||||
|
||||
#include "modules/TraceRouteModule.h"
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
|
||||
extern uint16_t TFT_MESH;
|
||||
|
||||
namespace graphics
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
// Caller must ensure the provided options array outlives the banner callback.
|
||||
template <typename T, size_t N, typename Callback>
|
||||
BannerOverlayOptions createStaticBannerOptions(const char *message, const MenuOption<T> (&options)[N],
|
||||
std::array<const char *, N> &labels, Callback &&onSelection)
|
||||
{
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
labels[i] = options[i].label;
|
||||
}
|
||||
|
||||
const MenuOption<T> *optionsPtr = options;
|
||||
auto callback = std::function<void(const MenuOption<T> &, int)>(std::forward<Callback>(onSelection));
|
||||
|
||||
BannerOverlayOptions bannerOptions;
|
||||
bannerOptions.message = message;
|
||||
bannerOptions.optionsArrayPtr = labels.data();
|
||||
bannerOptions.optionsCount = static_cast<uint8_t>(N);
|
||||
bannerOptions.bannerCallback = [optionsPtr, callback](int selected) -> void { callback(optionsPtr[selected], selected); };
|
||||
return bannerOptions;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
menuHandler::screenMenus menuHandler::menuQueue = menu_none;
|
||||
bool test_enabled = false;
|
||||
uint8_t test_count = 0;
|
||||
@@ -197,48 +226,38 @@ void menuHandler::DeviceRolePicker()
|
||||
|
||||
void menuHandler::RadioPresetPicker()
|
||||
{
|
||||
static const char *optionsArray[] = {"Back", "LongSlow", "LongModerate", "LongFast", "MediumSlow",
|
||||
"MediumFast", "ShortSlow", "ShortFast", "ShortTurbo"};
|
||||
enum optionsNumbers {
|
||||
Back = 0,
|
||||
radiopreset_LongSlow = 1,
|
||||
radiopreset_LongModerate = 2,
|
||||
radiopreset_LongFast = 3,
|
||||
radiopreset_MediumSlow = 4,
|
||||
radiopreset_MediumFast = 5,
|
||||
radiopreset_ShortSlow = 6,
|
||||
radiopreset_ShortFast = 7,
|
||||
radiopreset_ShortTurbo = 8
|
||||
};
|
||||
BannerOverlayOptions bannerOptions;
|
||||
bannerOptions.message = "Radio Preset";
|
||||
bannerOptions.optionsArrayPtr = optionsArray;
|
||||
bannerOptions.optionsCount = 9;
|
||||
bannerOptions.bannerCallback = [](int selected) -> void {
|
||||
if (selected == Back) {
|
||||
menuHandler::menuQueue = menuHandler::lora_Menu;
|
||||
screen->runNow();
|
||||
return;
|
||||
} else if (selected == radiopreset_LongSlow) {
|
||||
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW;
|
||||
} else if (selected == radiopreset_LongModerate) {
|
||||
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE;
|
||||
} else if (selected == radiopreset_LongFast) {
|
||||
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST;
|
||||
} else if (selected == radiopreset_MediumSlow) {
|
||||
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW;
|
||||
} else if (selected == radiopreset_MediumFast) {
|
||||
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST;
|
||||
} else if (selected == radiopreset_ShortSlow) {
|
||||
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW;
|
||||
} else if (selected == radiopreset_ShortFast) {
|
||||
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST;
|
||||
} else if (selected == radiopreset_ShortTurbo) {
|
||||
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO;
|
||||
}
|
||||
service->reloadConfig(SEGMENT_CONFIG);
|
||||
rebootAtMsec = (millis() + DEFAULT_REBOOT_SECONDS * 1000);
|
||||
static const RadioPresetOption presetOptions[] = {
|
||||
{"Back", OptionsAction::Back},
|
||||
{"LongTurbo", OptionsAction::Select, meshtastic_Config_LoRaConfig_ModemPreset_LONG_TURBO},
|
||||
{"LongModerate", OptionsAction::Select, meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE},
|
||||
{"LongFast", OptionsAction::Select, meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST},
|
||||
{"MediumSlow", OptionsAction::Select, meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW},
|
||||
{"MediumFast", OptionsAction::Select, meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST},
|
||||
{"ShortSlow", OptionsAction::Select, meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW},
|
||||
{"ShortFast", OptionsAction::Select, meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST},
|
||||
{"ShortTurbo", OptionsAction::Select, meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO},
|
||||
};
|
||||
|
||||
constexpr size_t presetCount = sizeof(presetOptions) / sizeof(presetOptions[0]);
|
||||
static std::array<const char *, presetCount> presetLabels{};
|
||||
|
||||
auto bannerOptions =
|
||||
createStaticBannerOptions("Radio Preset", presetOptions, presetLabels, [](const RadioPresetOption &option, int) -> void {
|
||||
if (option.action == OptionsAction::Back) {
|
||||
menuHandler::menuQueue = menuHandler::lora_Menu;
|
||||
screen->runNow();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!option.hasValue) {
|
||||
return;
|
||||
}
|
||||
|
||||
config.lora.modem_preset = option.value;
|
||||
service->reloadConfig(SEGMENT_CONFIG);
|
||||
rebootAtMsec = (millis() + DEFAULT_REBOOT_SECONDS * 1000);
|
||||
});
|
||||
|
||||
screen->showOverlayBanner(bannerOptions);
|
||||
}
|
||||
|
||||
|
||||
@@ -99,5 +99,24 @@ class menuHandler
|
||||
static void BluetoothToggleMenu();
|
||||
};
|
||||
|
||||
/* Generic Menu Options designations */
|
||||
enum class OptionsAction { Back, Select };
|
||||
|
||||
template <typename T> struct MenuOption {
|
||||
const char *label;
|
||||
OptionsAction action;
|
||||
bool hasValue;
|
||||
T value;
|
||||
|
||||
MenuOption(const char *labelIn, OptionsAction actionIn, T valueIn)
|
||||
: label(labelIn), action(actionIn), hasValue(true), value(valueIn)
|
||||
{
|
||||
}
|
||||
|
||||
MenuOption(const char *labelIn, OptionsAction actionIn) : label(labelIn), action(actionIn), hasValue(false), value() {}
|
||||
};
|
||||
|
||||
using RadioPresetOption = MenuOption<meshtastic_Config_LoRaConfig_ModemPreset>;
|
||||
|
||||
} // namespace graphics
|
||||
#endif
|
||||
@@ -27,7 +27,9 @@ bool RotaryEncoderInterruptImpl1::init()
|
||||
RotaryEncoderInterruptImpl1::handleIntA, RotaryEncoderInterruptImpl1::handleIntB,
|
||||
RotaryEncoderInterruptImpl1::handleIntPressed);
|
||||
inputBroker->registerSource(this);
|
||||
#ifndef HAS_PHYSICAL_KEYBOARD
|
||||
osk_found = true;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,9 @@ void TrackballInterruptBase::init(uint8_t pinDown, uint8_t pinUp, uint8_t pinLef
|
||||
|
||||
LOG_DEBUG("Trackball GPIO initialized - UP:%d DOWN:%d LEFT:%d RIGHT:%d PRESS:%d", this->_pinUp, this->_pinDown,
|
||||
this->_pinLeft, this->_pinRight, pinPress);
|
||||
#ifndef HAS_PHYSICAL_KEYBOARD
|
||||
osk_found = true;
|
||||
#endif
|
||||
this->setInterval(100);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,9 @@ bool UpDownInterruptImpl1::init()
|
||||
eventDownLong, UpDownInterruptImpl1::handleIntDown, UpDownInterruptImpl1::handleIntUp,
|
||||
UpDownInterruptImpl1::handleIntPressed);
|
||||
inputBroker->registerSource(this);
|
||||
#ifndef HAS_PHYSICAL_KEYBOARD
|
||||
osk_found = true;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -440,9 +440,11 @@ void setup()
|
||||
LOG_INFO("\n\n//\\ E S H T /\\ S T / C\n");
|
||||
|
||||
#if defined(ARCH_ESP32) && defined(BOARD_HAS_PSRAM)
|
||||
#ifndef SENSECAP_INDICATOR
|
||||
// use PSRAM for malloc calls > 256 bytes
|
||||
heap_caps_malloc_extmem_enable(256);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG_MUTE) && defined(DEBUG_PORT)
|
||||
DEBUG_PORT.printf("\r\n\r\n//\\ E S H T /\\ S T / C\r\n");
|
||||
@@ -1456,8 +1458,10 @@ void setup()
|
||||
#endif
|
||||
|
||||
#if defined(HAS_TRACKBALL) || (defined(INPUTDRIVER_ENCODER_TYPE) && INPUTDRIVER_ENCODER_TYPE == 2)
|
||||
#ifndef HAS_PHYSICAL_KEYBOARD
|
||||
osk_found = true;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(ARCH_ESP32) && !MESHTASTIC_EXCLUDE_WEBSERVER
|
||||
// Start web server thread.
|
||||
|
||||
@@ -124,6 +124,10 @@ void FloodingRouter::perhapsCancelDupe(const meshtastic_MeshPacket *p)
|
||||
if (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER_LATE && iface) {
|
||||
iface->clampToLateRebroadcastWindow(getFrom(p), p->id);
|
||||
}
|
||||
if (config.device.role == meshtastic_Config_DeviceConfig_Role_CLIENT_BASE && iface && nodeDB &&
|
||||
nodeDB->isFromOrToFavoritedNode(*p)) {
|
||||
iface->clampToLateRebroadcastWindow(getFrom(p), p->id);
|
||||
}
|
||||
}
|
||||
|
||||
bool FloodingRouter::isRebroadcaster()
|
||||
|
||||
@@ -225,4 +225,4 @@ class MeshModule
|
||||
/** set the destination and packet parameters of packet p intended as a reply to a particular "to" packet
|
||||
* This ensures that if the request packet was sent reliably, the reply is sent that way as well.
|
||||
*/
|
||||
void setReplyTo(meshtastic_MeshPacket *p, const meshtastic_MeshPacket &to);
|
||||
void setReplyTo(meshtastic_MeshPacket *p, const meshtastic_MeshPacket &to);
|
||||
|
||||
@@ -276,6 +276,10 @@ bool MeshService::trySendPosition(NodeNum dest, bool wantReplies)
|
||||
if (nodeDB->hasValidPosition(node)) {
|
||||
#if HAS_GPS && !MESHTASTIC_EXCLUDE_GPS
|
||||
if (positionModule) {
|
||||
if (!config.position.fixed_position && !nodeDB->hasLocalPositionSinceBoot()) {
|
||||
LOG_DEBUG("Skip position ping; no fresh position since boot");
|
||||
return false;
|
||||
}
|
||||
LOG_INFO("Send position ping to 0x%x, wantReplies=%d, channel=%d", dest, wantReplies, node->channel);
|
||||
positionModule->sendOurPosition(dest, wantReplies, node->channel);
|
||||
return true;
|
||||
|
||||
@@ -805,11 +805,12 @@ void NodeDB::installDefaultModuleConfig()
|
||||
moduleConfig.external_notification.output_ms = 500;
|
||||
moduleConfig.external_notification.nag_timeout = 2;
|
||||
#endif
|
||||
#if defined(RAK4630) || defined(RAK11310) || defined(RAK3312) || defined(MUZI_BASE)
|
||||
// Default to RAK led pin 2 (blue)
|
||||
#if defined(RAK4630) || defined(RAK11310) || defined(RAK3312) || defined(MUZI_BASE) || defined(ELECROW_ThinkNode_M3) || \
|
||||
defined(ELECROW_ThinkNode_M6)
|
||||
// Default to PIN_LED2 for external notification output (LED color depends on device variant)
|
||||
moduleConfig.external_notification.enabled = true;
|
||||
moduleConfig.external_notification.output = PIN_LED2;
|
||||
#if defined(MUZI_BASE)
|
||||
#if defined(MUZI_BASE) || defined(ELECROW_ThinkNode_M3)
|
||||
moduleConfig.external_notification.active = false;
|
||||
#else
|
||||
moduleConfig.external_notification.active = true;
|
||||
@@ -1043,6 +1044,7 @@ void NodeDB::clearLocalPosition()
|
||||
node->position.altitude = 0;
|
||||
node->position.time = 0;
|
||||
setLocalPosition(meshtastic_Position_init_default);
|
||||
localPositionUpdatedSinceBoot = false;
|
||||
}
|
||||
|
||||
void NodeDB::cleanupMeshDB()
|
||||
|
||||
@@ -279,9 +279,13 @@ class NodeDB
|
||||
LOG_DEBUG("Set local position: lat=%i lon=%i time=%u timestamp=%u", position.latitude_i, position.longitude_i,
|
||||
position.time, position.timestamp);
|
||||
localPosition = position;
|
||||
if (position.latitude_i != 0 || position.longitude_i != 0) {
|
||||
localPositionUpdatedSinceBoot = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool hasValidPosition(const meshtastic_NodeInfoLite *n);
|
||||
bool hasLocalPositionSinceBoot() const { return localPositionUpdatedSinceBoot; }
|
||||
|
||||
#if !defined(MESHTASTIC_EXCLUDE_PKI)
|
||||
bool checkLowEntropyPublicKey(const meshtastic_Config_SecurityConfig_public_key_t &keyToTest);
|
||||
@@ -301,6 +305,7 @@ class NodeDB
|
||||
|
||||
private:
|
||||
bool duplicateWarned = false;
|
||||
bool localPositionUpdatedSinceBoot = false;
|
||||
uint32_t lastNodeDbSave = 0; // when we last saved our db to flash
|
||||
uint32_t lastBackupAttempt = 0; // when we last tried a backup automatically or manually
|
||||
uint32_t lastSort = 0; // When last sorted the nodeDB
|
||||
|
||||
@@ -296,11 +296,6 @@ bool RadioInterface::shouldRebroadcastEarlyLikeRouter(meshtastic_MeshPacket *p)
|
||||
return true;
|
||||
}
|
||||
|
||||
// If we are a CLIENT_BASE and the packet is from or to a favorited node, we should rebroadcast early
|
||||
if (config.device.role == meshtastic_Config_DeviceConfig_Role_CLIENT_BASE) {
|
||||
return nodeDB->isFromOrToFavoritedNode(*p);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -503,6 +498,11 @@ void RadioInterface::applyModemConfig()
|
||||
cr = 5;
|
||||
sf = 10;
|
||||
break;
|
||||
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_TURBO:
|
||||
bw = (myRegion->wideLora) ? 1625.0 : 500;
|
||||
cr = 8;
|
||||
sf = 11;
|
||||
break;
|
||||
default: // Config_LoRaConfig_ModemPreset_LONG_FAST is default. Gracefully use this is preset is something illegal.
|
||||
bw = (myRegion->wideLora) ? 812.5 : 250;
|
||||
cr = 5;
|
||||
@@ -539,13 +539,26 @@ void RadioInterface::applyModemConfig()
|
||||
}
|
||||
|
||||
if ((myRegion->freqEnd - myRegion->freqStart) < bw / 1000) {
|
||||
static const char *err_string = "Regional frequency range is smaller than bandwidth. Fall back to default preset";
|
||||
LOG_ERROR(err_string);
|
||||
const float regionSpanKHz = (myRegion->freqEnd - myRegion->freqStart) * 1000.0f;
|
||||
const float requestedBwKHz = bw;
|
||||
const bool isWideRequest = requestedBwKHz >= 499.5f; // treat as 500 kHz preset
|
||||
const char *presetName =
|
||||
DisplayFormatters::getModemPresetDisplayName(loraConfig.modem_preset, false, loraConfig.use_preset);
|
||||
|
||||
char err_string[160];
|
||||
if (isWideRequest) {
|
||||
snprintf(err_string, sizeof(err_string), "%s region too narrow for 500kHz preset (%s). Falling back to LongFast.",
|
||||
myRegion->name, presetName);
|
||||
} else {
|
||||
snprintf(err_string, sizeof(err_string), "%s region span %.0fkHz < requested %.0fkHz. Falling back to LongFast.",
|
||||
myRegion->name, regionSpanKHz, requestedBwKHz);
|
||||
}
|
||||
LOG_ERROR("%s", err_string);
|
||||
RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING);
|
||||
|
||||
meshtastic_ClientNotification *cn = clientNotificationPool.allocZeroed();
|
||||
cn->level = meshtastic_LogRecord_Level_ERROR;
|
||||
sprintf(cn->message, err_string);
|
||||
snprintf(cn->message, sizeof(cn->message), "%s", err_string);
|
||||
service->sendClientNotification(cn);
|
||||
|
||||
// Set to default modem preset
|
||||
|
||||
@@ -150,7 +150,9 @@ void ReliableRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtas
|
||||
PacketId nakId = (c && c->error_reason != meshtastic_Routing_Error_NONE) ? p->decoded.request_id : 0;
|
||||
|
||||
// We intentionally don't check wasSeenRecently, because it is harmless to delete non existent retransmission records
|
||||
if (ackId || nakId) {
|
||||
if ((ackId || nakId) &&
|
||||
// Implicit ACKs from MQTT should not stop retransmissions
|
||||
!(isFromUs(p) && p->transport_mechanism == meshtastic_MeshPacket_TransportMechanism_TRANSPORT_MQTT)) {
|
||||
LOG_DEBUG("Received a %s for 0x%x, stopping retransmissions", ackId ? "ACK" : "NAK", ackId);
|
||||
if (ackId) {
|
||||
stopRetransmission(p->to, ackId);
|
||||
|
||||
@@ -526,6 +526,10 @@ DecodeState perhapsDecode(meshtastic_MeshPacket *p)
|
||||
#elif ARCH_PORTDUINO
|
||||
if (portduino_config.traceFilename != "" || portduino_config.logoutputlevel == level_trace) {
|
||||
LOG_TRACE("%s", MeshPacketSerializer::JsonSerialize(p, false).c_str());
|
||||
} else if (portduino_config.JSONFilename != "") {
|
||||
if (portduino_config.JSONFilter == (_meshtastic_PortNum)0 || portduino_config.JSONFilter == p->decoded.portnum) {
|
||||
JSONFile << MeshPacketSerializer::JsonSerialize(p, false) << std::endl;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return DecodeState::DECODE_SUCCESS;
|
||||
|
||||
@@ -293,7 +293,8 @@ typedef enum _meshtastic_Config_LoRaConfig_RegionCode {
|
||||
typedef enum _meshtastic_Config_LoRaConfig_ModemPreset {
|
||||
/* Long Range - Fast */
|
||||
meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST = 0,
|
||||
/* Long Range - Slow */
|
||||
/* Long Range - Slow
|
||||
Deprecated in 2.7: Unpopular slow preset. */
|
||||
meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW = 1,
|
||||
/* Very Long Range - Slow
|
||||
Deprecated in 2.5: Works only with txco and is unusably slow */
|
||||
@@ -311,7 +312,10 @@ typedef enum _meshtastic_Config_LoRaConfig_ModemPreset {
|
||||
/* Short Range - Turbo
|
||||
This is the fastest preset and the only one with 500kHz bandwidth.
|
||||
It is not legal to use in all regions due to this wider bandwidth. */
|
||||
meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO = 8
|
||||
meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO = 8,
|
||||
/* Long Range - Turbo
|
||||
This preset performs similarly to LongFast, but with 500Khz bandwidth. */
|
||||
meshtastic_Config_LoRaConfig_ModemPreset_LONG_TURBO = 9
|
||||
} meshtastic_Config_LoRaConfig_ModemPreset;
|
||||
|
||||
typedef enum _meshtastic_Config_BluetoothConfig_PairingMode {
|
||||
@@ -689,8 +693,8 @@ extern "C" {
|
||||
#define _meshtastic_Config_LoRaConfig_RegionCode_ARRAYSIZE ((meshtastic_Config_LoRaConfig_RegionCode)(meshtastic_Config_LoRaConfig_RegionCode_BR_902+1))
|
||||
|
||||
#define _meshtastic_Config_LoRaConfig_ModemPreset_MIN meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST
|
||||
#define _meshtastic_Config_LoRaConfig_ModemPreset_MAX meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO
|
||||
#define _meshtastic_Config_LoRaConfig_ModemPreset_ARRAYSIZE ((meshtastic_Config_LoRaConfig_ModemPreset)(meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO+1))
|
||||
#define _meshtastic_Config_LoRaConfig_ModemPreset_MAX meshtastic_Config_LoRaConfig_ModemPreset_LONG_TURBO
|
||||
#define _meshtastic_Config_LoRaConfig_ModemPreset_ARRAYSIZE ((meshtastic_Config_LoRaConfig_ModemPreset)(meshtastic_Config_LoRaConfig_ModemPreset_LONG_TURBO+1))
|
||||
|
||||
#define _meshtastic_Config_BluetoothConfig_PairingMode_MIN meshtastic_Config_BluetoothConfig_PairingMode_RANDOM_PIN
|
||||
#define _meshtastic_Config_BluetoothConfig_PairingMode_MAX meshtastic_Config_BluetoothConfig_PairingMode_NO_PIN
|
||||
|
||||
@@ -417,6 +417,9 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
|
||||
}
|
||||
case meshtastic_AdminMessage_enter_dfu_mode_request_tag: {
|
||||
LOG_INFO("Client requesting to enter DFU mode");
|
||||
#if HAS_SCREEN
|
||||
IF_SCREEN(screen->showSimpleBanner("Device is rebooting\ninto DFU mode.", 0));
|
||||
#endif
|
||||
#if defined(ARCH_NRF52) || defined(ARCH_RP2040)
|
||||
enterDfuMode();
|
||||
#endif
|
||||
|
||||
@@ -7,17 +7,41 @@
|
||||
#include "configuration.h"
|
||||
#include "main.h"
|
||||
#include <Throttle.h>
|
||||
#include <algorithm>
|
||||
|
||||
#ifndef USERPREFS_NODEINFO_REPLY_SUPPRESS_SECS
|
||||
#define USERPREFS_NODEINFO_REPLY_SUPPRESS_SECS (12 * 60 * 60)
|
||||
#endif
|
||||
|
||||
NodeInfoModule *nodeInfoModule;
|
||||
|
||||
static constexpr uint32_t NodeInfoReplySuppressSeconds = USERPREFS_NODEINFO_REPLY_SUPPRESS_SECS;
|
||||
|
||||
bool NodeInfoModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_User *pptr)
|
||||
{
|
||||
suppressReplyForCurrentRequest = false;
|
||||
|
||||
if (mp.from == nodeDB->getNodeNum()) {
|
||||
LOG_WARN("Ignoring packet supposed to be from our own node: %08x", mp.from);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto p = *pptr;
|
||||
|
||||
if (mp.decoded.want_response) {
|
||||
const NodeNum sender = getFrom(&mp);
|
||||
const uint32_t now = mp.rx_time ? mp.rx_time : getTime();
|
||||
auto it = lastNodeInfoSeen.find(sender);
|
||||
if (it != lastNodeInfoSeen.end()) {
|
||||
uint32_t sinceLast = now >= it->second ? now - it->second : 0;
|
||||
if (sinceLast < NodeInfoReplySuppressSeconds) {
|
||||
suppressReplyForCurrentRequest = true;
|
||||
}
|
||||
}
|
||||
lastNodeInfoSeen[sender] = now;
|
||||
pruneLastNodeInfoCache();
|
||||
}
|
||||
|
||||
if (p.is_licensed != owner.is_licensed) {
|
||||
LOG_WARN("Invalid nodeInfo detected, is_licensed mismatch!");
|
||||
return true;
|
||||
@@ -42,6 +66,8 @@ bool NodeInfoModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes
|
||||
service->sendToPhone(packetCopy);
|
||||
}
|
||||
|
||||
pruneLastNodeInfoCache();
|
||||
|
||||
// LOG_DEBUG("did handleReceived");
|
||||
return false; // Let others look at this message also if they want
|
||||
}
|
||||
@@ -68,9 +94,11 @@ void NodeInfoModule::sendOurNodeInfo(NodeNum dest, bool wantReplies, uint8_t cha
|
||||
|
||||
if (p) { // Check whether we didn't ignore it
|
||||
p->to = dest;
|
||||
p->decoded.want_response = (config.device.role != meshtastic_Config_DeviceConfig_Role_TRACKER &&
|
||||
bool requestWantResponse = (config.device.role != meshtastic_Config_DeviceConfig_Role_TRACKER &&
|
||||
config.device.role != meshtastic_Config_DeviceConfig_Role_SENSOR) &&
|
||||
wantReplies;
|
||||
|
||||
p->decoded.want_response = requestWantResponse;
|
||||
if (_shorterTimeout)
|
||||
p->priority = meshtastic_MeshPacket_Priority_DEFAULT;
|
||||
else
|
||||
@@ -89,6 +117,13 @@ void NodeInfoModule::sendOurNodeInfo(NodeNum dest, bool wantReplies, uint8_t cha
|
||||
|
||||
meshtastic_MeshPacket *NodeInfoModule::allocReply()
|
||||
{
|
||||
if (suppressReplyForCurrentRequest) {
|
||||
LOG_DEBUG("Skip send NodeInfo since we heard the requester <12h ago");
|
||||
ignoreRequest = true;
|
||||
suppressReplyForCurrentRequest = false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!airTime->isTxAllowedChannelUtil(false)) {
|
||||
ignoreRequest = true; // Mark it as ignored for MeshModule
|
||||
LOG_DEBUG("Skip send NodeInfo > 40%% ch. util");
|
||||
@@ -125,6 +160,29 @@ meshtastic_MeshPacket *NodeInfoModule::allocReply()
|
||||
}
|
||||
}
|
||||
|
||||
void NodeInfoModule::pruneLastNodeInfoCache()
|
||||
{
|
||||
if (!nodeDB || !nodeDB->meshNodes)
|
||||
return;
|
||||
|
||||
const size_t maxEntries = nodeDB->meshNodes->size();
|
||||
|
||||
for (auto it = lastNodeInfoSeen.begin(); it != lastNodeInfoSeen.end();) {
|
||||
if (!nodeDB->getMeshNode(it->first)) {
|
||||
it = lastNodeInfoSeen.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
while (!lastNodeInfoSeen.empty() && lastNodeInfoSeen.size() > maxEntries) {
|
||||
auto oldestIt = std::min_element(lastNodeInfoSeen.begin(), lastNodeInfoSeen.end(),
|
||||
[](const std::pair<const NodeNum, uint32_t> &lhs,
|
||||
const std::pair<const NodeNum, uint32_t> &rhs) { return lhs.second < rhs.second; });
|
||||
lastNodeInfoSeen.erase(oldestIt);
|
||||
}
|
||||
}
|
||||
|
||||
NodeInfoModule::NodeInfoModule()
|
||||
: ProtobufModule("nodeinfo", meshtastic_PortNum_NODEINFO_APP, &meshtastic_User_msg), concurrency::OSThread("NodeInfo")
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "ProtobufModule.h"
|
||||
#include <map>
|
||||
|
||||
/**
|
||||
* NodeInfo module for sending/receiving NodeInfos into the mesh
|
||||
@@ -43,6 +44,10 @@ class NodeInfoModule : public ProtobufModule<meshtastic_User>, private concurren
|
||||
private:
|
||||
uint32_t lastSentToMesh = 0; // Last time we sent our NodeInfo to the mesh
|
||||
bool shorterTimeout = false;
|
||||
bool suppressReplyForCurrentRequest = false;
|
||||
std::map<NodeNum, uint32_t> lastNodeInfoSeen;
|
||||
|
||||
void pruneLastNodeInfoCache();
|
||||
};
|
||||
|
||||
extern NodeInfoModule *nodeInfoModule;
|
||||
|
||||
@@ -349,6 +349,11 @@ void PositionModule::sendOurPosition()
|
||||
|
||||
void PositionModule::sendOurPosition(NodeNum dest, bool wantReplies, uint8_t channel)
|
||||
{
|
||||
if (!config.position.fixed_position && !nodeDB->hasLocalPositionSinceBoot()) {
|
||||
LOG_DEBUG("Skip position send; no fresh position since boot");
|
||||
return;
|
||||
}
|
||||
|
||||
// cancel any not yet sent (now stale) position packets
|
||||
if (prevPacketId) // if we wrap around to zero, we'll simply fail to cancel in that rare case (no big deal)
|
||||
service->cancelSending(prevPacketId);
|
||||
@@ -420,8 +425,14 @@ int32_t PositionModule::runOnce()
|
||||
return RUNONCE_INTERVAL;
|
||||
}
|
||||
|
||||
bool waitingForFreshPosition = (lastGpsSend == 0) && !config.position.fixed_position && !nodeDB->hasLocalPositionSinceBoot();
|
||||
|
||||
if (lastGpsSend == 0 || msSinceLastSend >= intervalMs) {
|
||||
if (nodeDB->hasValidPosition(node)) {
|
||||
if (waitingForFreshPosition) {
|
||||
#ifdef GPS_DEBUG
|
||||
LOG_DEBUG("Skip initial position send; no fresh position since boot");
|
||||
#endif
|
||||
} else if (nodeDB->hasValidPosition(node)) {
|
||||
lastGpsSend = now;
|
||||
|
||||
lastGpsLatitude = node->position.latitude_i;
|
||||
|
||||
@@ -75,6 +75,12 @@ uint8_t RoutingModule::getHopLimitForResponse(uint8_t hopStart, uint8_t hopLimit
|
||||
return Default::getConfiguredOrDefaultHopLimit(config.lora.hop_limit); // Use the default hop limit
|
||||
}
|
||||
|
||||
meshtastic_MeshPacket *RoutingModule::allocAckNak(meshtastic_Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex,
|
||||
uint8_t hopLimit)
|
||||
{
|
||||
return MeshModule::allocAckNak(err, to, idFrom, chIndex, hopLimit);
|
||||
}
|
||||
|
||||
RoutingModule::RoutingModule() : ProtobufModule("routing", meshtastic_PortNum_ROUTING_APP, &meshtastic_Routing_msg)
|
||||
{
|
||||
isPromiscuous = true;
|
||||
|
||||
@@ -16,6 +16,9 @@ class RoutingModule : public ProtobufModule<meshtastic_Routing>
|
||||
virtual void sendAckNak(meshtastic_Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex, uint8_t hopLimit = 0,
|
||||
bool ackWantsAck = false);
|
||||
|
||||
meshtastic_MeshPacket *allocAckNak(meshtastic_Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex,
|
||||
uint8_t hopLimit = 0);
|
||||
|
||||
// Given the hopStart and hopLimit upon reception of a request, return the hop limit to use for the response
|
||||
uint8_t getHopLimitForResponse(uint8_t hopStart, uint8_t hopLimit);
|
||||
|
||||
|
||||
@@ -20,13 +20,17 @@ int StatusLEDModule::handleStatusUpdate(const meshtastic::Status *arg)
|
||||
switch (arg->getStatusType()) {
|
||||
case STATUS_TYPE_POWER: {
|
||||
meshtastic::PowerStatus *powerStatus = (meshtastic::PowerStatus *)arg;
|
||||
if (powerStatus->getHasUSB()) {
|
||||
if (powerStatus->getHasUSB() || powerStatus->getIsCharging()) {
|
||||
power_state = charging;
|
||||
if (powerStatus->getBatteryChargePercent() >= 100) {
|
||||
power_state = charged;
|
||||
}
|
||||
} else {
|
||||
power_state = discharging;
|
||||
if (powerStatus->getBatteryChargePercent() > 5) {
|
||||
power_state = discharging;
|
||||
} else {
|
||||
power_state = critical;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -58,16 +62,33 @@ int StatusLEDModule::handleStatusUpdate(const meshtastic::Status *arg)
|
||||
|
||||
int32_t StatusLEDModule::runOnce()
|
||||
{
|
||||
my_interval = 1000;
|
||||
|
||||
if (power_state == charging) {
|
||||
CHARGE_LED_state = !CHARGE_LED_state;
|
||||
} else if (power_state == charged) {
|
||||
CHARGE_LED_state = LED_STATE_ON;
|
||||
} else if (power_state == critical) {
|
||||
if (POWER_LED_starttime + 30000 < millis() && !doing_fast_blink) {
|
||||
doing_fast_blink = true;
|
||||
POWER_LED_starttime = millis();
|
||||
}
|
||||
if (doing_fast_blink) {
|
||||
PAIRING_LED_state = LED_STATE_OFF;
|
||||
CHARGE_LED_state = !CHARGE_LED_state;
|
||||
my_interval = 250;
|
||||
if (POWER_LED_starttime + 2000 < millis()) {
|
||||
doing_fast_blink = false;
|
||||
}
|
||||
} else {
|
||||
CHARGE_LED_state = LED_STATE_OFF;
|
||||
}
|
||||
|
||||
} else {
|
||||
CHARGE_LED_state = LED_STATE_OFF;
|
||||
}
|
||||
|
||||
if (!config.bluetooth.enabled || PAIRING_LED_starttime + 30 * 1000 < millis()) {
|
||||
if (!config.bluetooth.enabled || PAIRING_LED_starttime + 30 * 1000 < millis() || doing_fast_blink) {
|
||||
PAIRING_LED_state = LED_STATE_OFF;
|
||||
} else if (ble_state == unpaired) {
|
||||
if (slowTrack) {
|
||||
|
||||
@@ -31,8 +31,10 @@ class StatusLEDModule : private concurrency::OSThread
|
||||
bool PAIRING_LED_state = LED_STATE_OFF;
|
||||
|
||||
uint32_t PAIRING_LED_starttime = 0;
|
||||
uint32_t POWER_LED_starttime = 0;
|
||||
bool doing_fast_blink = false;
|
||||
|
||||
enum PowerState { discharging, charging, charged };
|
||||
enum PowerState { discharging, charging, charged, critical };
|
||||
|
||||
PowerState power_state = discharging;
|
||||
|
||||
|
||||
@@ -87,10 +87,13 @@ inline void onReceiveProto(char *topic, byte *payload, size_t length)
|
||||
// Generate an implicit ACK towards ourselves (handled and processed only locally!) for this message.
|
||||
// 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 (isFromUs(e.packet))
|
||||
routingModule->sendAckNak(meshtastic_Routing_Error_NONE, getFrom(e.packet), e.packet->id, ch.index);
|
||||
else
|
||||
if (isFromUs(e.packet)) {
|
||||
auto pAck = routingModule->allocAckNak(meshtastic_Routing_Error_NONE, getFrom(e.packet), e.packet->id, ch.index);
|
||||
pAck->transport_mechanism = meshtastic_MeshPacket_TransportMechanism_TRANSPORT_MQTT;
|
||||
router->sendLocal(pAck);
|
||||
} else {
|
||||
LOG_INFO("Ignore downlink message we originally sent");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (isFromUs(e.packet)) {
|
||||
|
||||
@@ -14,11 +14,9 @@
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
|
||||
#ifdef NIMBLE_TWO
|
||||
#include "NimBLEAdvertising.h"
|
||||
#include "NimBLEExtAdvertising.h"
|
||||
#include "PowerStatus.h"
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_NIMBLE_CPP_IDF)
|
||||
#include "host/ble_gap.h"
|
||||
@@ -26,15 +24,12 @@
|
||||
#include "nimble/nimble/host/include/host/ble_gap.h"
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C6)
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr uint16_t kPreferredBleMtu = 517;
|
||||
constexpr uint16_t kPreferredBleTxOctets = 251;
|
||||
constexpr uint16_t kPreferredBleTxTimeUs = (kPreferredBleTxOctets + 14) * 8;
|
||||
} // namespace
|
||||
#endif
|
||||
|
||||
// Debugging options: careful, they slow things down quite a bit!
|
||||
// #define DEBUG_NIMBLE_ON_READ_TIMING // uncomment to time onRead duration
|
||||
@@ -313,11 +308,11 @@ class BluetoothPhoneAPI : public PhoneAPI, public concurrency::OSThread
|
||||
{
|
||||
PhoneAPI::onNowHasData(fromRadioNum);
|
||||
|
||||
#ifdef DEBUG_NIMBLE_NOTIFY
|
||||
int currentNotifyCount = notifyCount.fetch_add(1);
|
||||
|
||||
uint8_t cc = bleServer->getConnectedCount();
|
||||
|
||||
#ifdef DEBUG_NIMBLE_NOTIFY
|
||||
// This logging slows things down when there are lots of packets going to the phone, like initial connection:
|
||||
LOG_DEBUG("BLE notify(%d) fromNum: %d connections: %d", currentNotifyCount, fromRadioNum, cc);
|
||||
#endif
|
||||
@@ -326,13 +321,7 @@ class BluetoothPhoneAPI : public PhoneAPI, public concurrency::OSThread
|
||||
put_le32(val, fromRadioNum);
|
||||
|
||||
fromNumCharacteristic->setValue(val, sizeof(val));
|
||||
#ifdef NIMBLE_TWO
|
||||
// NOTE: I don't have any NIMBLE_TWO devices, but this line makes me suspicious, and I suspect it needs to just be
|
||||
// notify().
|
||||
fromNumCharacteristic->notify(val, sizeof(val), BLE_HS_CONN_HANDLE_NONE);
|
||||
#else
|
||||
fromNumCharacteristic->notify();
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Check the current underlying physical link to see if the client is currently connected
|
||||
@@ -397,13 +386,9 @@ static uint8_t lastToRadio[MAX_TO_FROM_RADIO_SIZE];
|
||||
|
||||
class NimbleBluetoothToRadioCallback : public NimBLECharacteristicCallbacks
|
||||
{
|
||||
#ifdef NIMBLE_TWO
|
||||
virtual void onWrite(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo &connInfo)
|
||||
#else
|
||||
virtual void onWrite(NimBLECharacteristic *pCharacteristic)
|
||||
|
||||
#endif
|
||||
{
|
||||
(void)connInfo;
|
||||
// CAUTION: This callback runs in the NimBLE task!!! Don't do anything except communicate with the main task's runOnce.
|
||||
// Assumption: onWrite is serialized by NimBLE, so we don't need to lock here against multiple concurrent onWrite calls.
|
||||
|
||||
@@ -449,12 +434,9 @@ class NimbleBluetoothToRadioCallback : public NimBLECharacteristicCallbacks
|
||||
|
||||
class NimbleBluetoothFromRadioCallback : public NimBLECharacteristicCallbacks
|
||||
{
|
||||
#ifdef NIMBLE_TWO
|
||||
virtual void onRead(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo &connInfo)
|
||||
#else
|
||||
virtual void onRead(NimBLECharacteristic *pCharacteristic)
|
||||
#endif
|
||||
{
|
||||
(void)connInfo;
|
||||
// CAUTION: This callback runs in the NimBLE task!!! Don't do anything except communicate with the main task's runOnce.
|
||||
|
||||
int currentReadCount = bluetoothPhoneAPI->readCount.fetch_add(1);
|
||||
@@ -561,17 +543,13 @@ class NimbleBluetoothFromRadioCallback : public NimBLECharacteristicCallbacks
|
||||
|
||||
class NimbleBluetoothServerCallback : public NimBLEServerCallbacks
|
||||
{
|
||||
#ifdef NIMBLE_TWO
|
||||
public:
|
||||
NimbleBluetoothServerCallback(NimbleBluetooth *ble) { this->ble = ble; }
|
||||
explicit NimbleBluetoothServerCallback(NimbleBluetooth *ble) : ble(ble) {}
|
||||
|
||||
private:
|
||||
NimbleBluetooth *ble;
|
||||
|
||||
virtual uint32_t onPassKeyDisplay()
|
||||
#else
|
||||
virtual uint32_t onPassKeyRequest()
|
||||
#endif
|
||||
uint32_t onPassKeyDisplay() override
|
||||
{
|
||||
uint32_t passkey = config.bluetooth.fixed_pin;
|
||||
|
||||
@@ -620,11 +598,7 @@ class NimbleBluetoothServerCallback : public NimBLEServerCallbacks
|
||||
return passkey;
|
||||
}
|
||||
|
||||
#ifdef NIMBLE_TWO
|
||||
virtual void onAuthenticationComplete(NimBLEConnInfo &connInfo)
|
||||
#else
|
||||
virtual void onAuthenticationComplete(ble_gap_conn_desc *desc)
|
||||
#endif
|
||||
void onAuthenticationComplete(NimBLEConnInfo &connInfo) override
|
||||
{
|
||||
LOG_INFO("BLE authentication complete");
|
||||
|
||||
@@ -639,15 +613,10 @@ class NimbleBluetoothServerCallback : public NimBLEServerCallbacks
|
||||
}
|
||||
|
||||
// Store the connection handle for future use
|
||||
#ifdef NIMBLE_TWO
|
||||
nimbleBluetoothConnHandle = connInfo.getConnHandle();
|
||||
#else
|
||||
nimbleBluetoothConnHandle = desc->conn_handle;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef NIMBLE_TWO
|
||||
virtual void onConnect(NimBLEServer *pServer, NimBLEConnInfo &connInfo)
|
||||
void onConnect(NimBLEServer *pServer, NimBLEConnInfo &connInfo) override
|
||||
{
|
||||
LOG_INFO("BLE incoming connection %s", connInfo.getAddress().toString().c_str());
|
||||
|
||||
@@ -672,21 +641,13 @@ class NimbleBluetoothServerCallback : public NimBLEServerCallbacks
|
||||
LOG_INFO("BLE conn %u initial MTU %u (target %u)", connHandle, connInfo.getMTU(), kPreferredBleMtu);
|
||||
pServer->updateConnParams(connHandle, 6, 12, 0, 200);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NIMBLE_TWO
|
||||
virtual void onDisconnect(NimBLEServer *pServer, NimBLEConnInfo &connInfo, int reason)
|
||||
void onDisconnect(NimBLEServer *pServer, NimBLEConnInfo &connInfo, int reason) override
|
||||
{
|
||||
(void)pServer;
|
||||
(void)connInfo;
|
||||
LOG_INFO("BLE disconnect reason: %d", reason);
|
||||
#else
|
||||
virtual void onDisconnect(NimBLEServer *pServer, ble_gap_conn_desc *desc)
|
||||
{
|
||||
LOG_INFO("BLE disconnect");
|
||||
#endif
|
||||
#ifdef NIMBLE_TWO
|
||||
if (ble->isDeInit)
|
||||
return;
|
||||
#endif
|
||||
|
||||
meshtastic::BluetoothStatus newStatus(meshtastic::BluetoothStatus::ConnectionState::DISCONNECTED);
|
||||
bluetoothStatus->updateStatus(&newStatus);
|
||||
@@ -715,19 +676,8 @@ class NimbleBluetoothServerCallback : public NimBLEServerCallbacks
|
||||
|
||||
nimbleBluetoothConnHandle = BLE_HS_CONN_HANDLE_NONE; // BLE_HS_CONN_HANDLE_NONE means "no connection"
|
||||
|
||||
#ifdef NIMBLE_TWO
|
||||
// Restart Advertising
|
||||
ble->startAdvertising();
|
||||
#else
|
||||
NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising();
|
||||
if (!pAdvertising->start(0)) {
|
||||
if (pAdvertising->isAdvertising()) {
|
||||
LOG_DEBUG("BLE advertising already running");
|
||||
} else {
|
||||
LOG_ERROR("BLE failed to restart advertising");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
@@ -760,9 +710,6 @@ void NimbleBluetooth::deinit()
|
||||
digitalWrite(BLE_LED, LOW);
|
||||
#endif
|
||||
#endif
|
||||
#ifndef NIMBLE_TWO
|
||||
NimBLEDevice::deinit();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -851,11 +798,7 @@ void NimbleBluetooth::setup()
|
||||
NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_ONLY);
|
||||
}
|
||||
bleServer = NimBLEDevice::createServer();
|
||||
#ifdef NIMBLE_TWO
|
||||
NimbleBluetoothServerCallback *serverCallbacks = new NimbleBluetoothServerCallback(this);
|
||||
#else
|
||||
NimbleBluetoothServerCallback *serverCallbacks = new NimbleBluetoothServerCallback();
|
||||
#endif
|
||||
bleServer->setCallbacks(serverCallbacks, true);
|
||||
setupService();
|
||||
startAdvertising();
|
||||
@@ -900,11 +843,7 @@ void NimbleBluetooth::setupService()
|
||||
NimBLEService *batteryService = bleServer->createService(NimBLEUUID((uint16_t)0x180f)); // 0x180F is the Battery Service
|
||||
BatteryCharacteristic = batteryService->createCharacteristic( // 0x2A19 is the Battery Level characteristic)
|
||||
(uint16_t)0x2a19, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY, 1);
|
||||
#ifdef NIMBLE_TWO
|
||||
NimBLE2904 *batteryLevelDescriptor = BatteryCharacteristic->create2904();
|
||||
#else
|
||||
NimBLE2904 *batteryLevelDescriptor = (NimBLE2904 *)BatteryCharacteristic->createDescriptor((uint16_t)0x2904);
|
||||
#endif
|
||||
batteryLevelDescriptor->setFormat(NimBLE2904::FORMAT_UINT8);
|
||||
batteryLevelDescriptor->setNamespace(1);
|
||||
batteryLevelDescriptor->setUnit(0x27ad);
|
||||
@@ -914,7 +853,7 @@ void NimbleBluetooth::setupService()
|
||||
|
||||
void NimbleBluetooth::startAdvertising()
|
||||
{
|
||||
#ifdef NIMBLE_TWO
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6)
|
||||
NimBLEExtAdvertising *pAdvertising = NimBLEDevice::getAdvertising();
|
||||
NimBLEExtAdvertisement legacyAdvertising;
|
||||
|
||||
@@ -943,10 +882,17 @@ void NimbleBluetooth::startAdvertising()
|
||||
}
|
||||
#else
|
||||
NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising();
|
||||
pAdvertising->reset();
|
||||
pAdvertising->addServiceUUID(MESH_SERVICE_UUID);
|
||||
pAdvertising->addServiceUUID(NimBLEUUID((uint16_t)0x180f)); // 0x180F is the Battery Service
|
||||
pAdvertising->start(0);
|
||||
pAdvertising->addServiceUUID(NimBLEUUID(MESH_SERVICE_UUID));
|
||||
if (powerStatus->getHasBattery() == 1) {
|
||||
pAdvertising->addServiceUUID(NimBLEUUID((uint16_t)0x180f));
|
||||
}
|
||||
pAdvertising->setName(getDeviceName());
|
||||
// Optionally, set scan response data (not required unless you want to advertise more info)
|
||||
// pAdvertising->setScanResponseData(...); // if needed
|
||||
|
||||
if (!pAdvertising->start()) {
|
||||
LOG_ERROR("BLE failed to start advertising");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -955,11 +901,7 @@ void updateBatteryLevel(uint8_t level)
|
||||
{
|
||||
if ((config.bluetooth.enabled == true) && bleServer && nimbleBluetooth->isConnected()) {
|
||||
BatteryCharacteristic->setValue(&level, 1);
|
||||
#ifdef NIMBLE_TWO
|
||||
BatteryCharacteristic->notify(&level, 1, BLE_HS_CONN_HANDLE_NONE);
|
||||
#else
|
||||
BatteryCharacteristic->notify();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -974,11 +916,7 @@ void NimbleBluetooth::sendLog(const uint8_t *logMessage, size_t length)
|
||||
if (!bleServer || !isConnected() || length > 512) {
|
||||
return;
|
||||
}
|
||||
#ifdef NIMBLE_TWO
|
||||
logRadioCharacteristic->notify(logMessage, length, BLE_HS_CONN_HANDLE_NONE);
|
||||
#else
|
||||
logRadioCharacteristic->notify(logMessage, length, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
void clearNVS()
|
||||
|
||||
@@ -12,16 +12,11 @@ class NimbleBluetooth : BluetoothApi
|
||||
bool isConnected();
|
||||
int getRssi();
|
||||
void sendLog(const uint8_t *logMessage, size_t length);
|
||||
#if defined(NIMBLE_TWO)
|
||||
void startAdvertising();
|
||||
#endif
|
||||
bool isDeInit = false;
|
||||
|
||||
private:
|
||||
void setupService();
|
||||
#if !defined(NIMBLE_TWO)
|
||||
void startAdvertising();
|
||||
#endif
|
||||
};
|
||||
|
||||
void setBluetoothEnable(bool enable);
|
||||
|
||||
@@ -337,7 +337,7 @@ void cpuDeepSleep(uint32_t msecToWake)
|
||||
#endif
|
||||
|
||||
#ifdef TTGO_T_ECHO
|
||||
// To power off the T-Echo, the display must be set
|
||||
// To power off the T-Echo, the display must be set
|
||||
// as an input pin; otherwise, there will be leakage current.
|
||||
pinMode(PIN_EINK_CS, INPUT);
|
||||
pinMode(PIN_EINK_DC, INPUT);
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
portduino_config_struct portduino_config;
|
||||
std::ofstream traceFile;
|
||||
std::ofstream JSONFile;
|
||||
Ch341Hal *ch341Hal = nullptr;
|
||||
char *configPath = nullptr;
|
||||
char *optionMac = nullptr;
|
||||
@@ -278,7 +279,7 @@ void portduinoSetup()
|
||||
// RAK6421-13300-S1:aabbcc123456:5ba85807d92138b7519cfb60460573af:3061e8d8
|
||||
// <model string>:mac address :<16 random unique bytes in hexidecimal> : crc32
|
||||
// crc32 is calculated on the eeprom string up to but not including the final colon
|
||||
if (strlen(autoconf_product) < 6) {
|
||||
if (strlen(autoconf_product) < 6 && portduino_config.i2cdev != "") {
|
||||
try {
|
||||
char *mac_start = nullptr;
|
||||
char *devID_start = nullptr;
|
||||
@@ -463,6 +464,7 @@ void portduinoSetup()
|
||||
if (portduino_config.lora_spi_dev != "" && portduino_config.lora_spi_dev != "ch341") {
|
||||
SPI.begin(portduino_config.lora_spi_dev.c_str());
|
||||
}
|
||||
|
||||
if (portduino_config.traceFilename != "") {
|
||||
try {
|
||||
traceFile.open(portduino_config.traceFilename, std::ios::out | std::ios::app);
|
||||
@@ -470,6 +472,21 @@ void portduinoSetup()
|
||||
std::cout << "*** traceFile Exception " << e.what() << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (!traceFile.is_open()) {
|
||||
std::cout << "*** traceFile open failure" << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
} else if (portduino_config.JSONFilename != "") {
|
||||
try {
|
||||
JSONFile.open(portduino_config.JSONFilename, std::ios::out | std::ios::app);
|
||||
} catch (std::ofstream::failure &e) {
|
||||
std::cout << "*** JSONFile Exception " << e.what() << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (!JSONFile.is_open()) {
|
||||
std::cout << "*** JSONFile open failure" << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
if (verboseEnabled && portduino_config.logoutputlevel != level_trace) {
|
||||
portduino_config.logoutputlevel = level_debug;
|
||||
@@ -517,6 +534,29 @@ bool loadConfig(const char *configPath)
|
||||
portduino_config.logoutputlevel = level_error;
|
||||
}
|
||||
portduino_config.traceFilename = yamlConfig["Logging"]["TraceFile"].as<std::string>("");
|
||||
portduino_config.JSONFilename = yamlConfig["Logging"]["JSONFile"].as<std::string>("");
|
||||
portduino_config.JSONFilter = (_meshtastic_PortNum)yamlConfig["Logging"]["JSONFilter"].as<int>(0);
|
||||
if (yamlConfig["Logging"]["JSONFilter"].as<std::string>("") == "textmessage")
|
||||
portduino_config.JSONFilter = meshtastic_PortNum_TEXT_MESSAGE_APP;
|
||||
else if (yamlConfig["Logging"]["JSONFilter"].as<std::string>("") == "telemetry")
|
||||
portduino_config.JSONFilter = meshtastic_PortNum_TELEMETRY_APP;
|
||||
else if (yamlConfig["Logging"]["JSONFilter"].as<std::string>("") == "nodeinfo")
|
||||
portduino_config.JSONFilter = meshtastic_PortNum_NODEINFO_APP;
|
||||
else if (yamlConfig["Logging"]["JSONFilter"].as<std::string>("") == "position")
|
||||
portduino_config.JSONFilter = meshtastic_PortNum_POSITION_APP;
|
||||
else if (yamlConfig["Logging"]["JSONFilter"].as<std::string>("") == "waypoint")
|
||||
portduino_config.JSONFilter = meshtastic_PortNum_WAYPOINT_APP;
|
||||
else if (yamlConfig["Logging"]["JSONFilter"].as<std::string>("") == "neighborinfo")
|
||||
portduino_config.JSONFilter = meshtastic_PortNum_NEIGHBORINFO_APP;
|
||||
else if (yamlConfig["Logging"]["JSONFilter"].as<std::string>("") == "traceroute")
|
||||
portduino_config.JSONFilter = meshtastic_PortNum_TRACEROUTE_APP;
|
||||
else if (yamlConfig["Logging"]["JSONFilter"].as<std::string>("") == "detection")
|
||||
portduino_config.JSONFilter = meshtastic_PortNum_DETECTION_SENSOR_APP;
|
||||
else if (yamlConfig["Logging"]["JSONFilter"].as<std::string>("") == "paxcounter")
|
||||
portduino_config.JSONFilter = meshtastic_PortNum_PAXCOUNTER_APP;
|
||||
else if (yamlConfig["Logging"]["JSONFilter"].as<std::string>("") == "remotehardware")
|
||||
portduino_config.JSONFilter = meshtastic_PortNum_REMOTE_HARDWARE_APP;
|
||||
|
||||
if (yamlConfig["Logging"]["AsciiLogs"]) {
|
||||
// Default is !isatty(1) but can be set explicitly in config.yaml
|
||||
portduino_config.ascii_logs = yamlConfig["Logging"]["AsciiLogs"].as<bool>();
|
||||
@@ -827,4 +867,4 @@ void readGPIOFromYaml(YAML::Node sourceNode, pinMapping &destPin, int pinDefault
|
||||
destPin.line = destPin.pin;
|
||||
destPin.gpiochip = portduino_config.lora_default_gpiochip;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "LR11x0Interface.h"
|
||||
#include "Module.h"
|
||||
#include "mesh/generated/meshtastic/mesh.pb.h"
|
||||
#include "platform/portduino/USBHal.h"
|
||||
#include "yaml-cpp/yaml.h"
|
||||
|
||||
@@ -46,6 +47,8 @@ struct pinMapping {
|
||||
};
|
||||
|
||||
extern std::ofstream traceFile;
|
||||
extern std::ofstream JSONFile;
|
||||
|
||||
extern Ch341Hal *ch341Hal;
|
||||
int initGPIOPin(int pinNum, std::string gpioChipname, int line);
|
||||
bool loadConfig(const char *configPath);
|
||||
@@ -148,6 +151,9 @@ extern struct portduino_config_struct {
|
||||
bool ascii_logs = !isatty(1);
|
||||
bool ascii_logs_explicit = false;
|
||||
|
||||
std::string JSONFilename;
|
||||
meshtastic_PortNum JSONFilter = (_meshtastic_PortNum)0;
|
||||
|
||||
// Webserver
|
||||
std::string webserver_root_path = "";
|
||||
std::string webserver_ssl_key_path = "/etc/meshtasticd/ssl/private_key.pem";
|
||||
@@ -413,6 +419,29 @@ extern struct portduino_config_struct {
|
||||
}
|
||||
if (traceFilename != "")
|
||||
out << YAML::Key << "TraceFile" << YAML::Value << traceFilename;
|
||||
if (JSONFilename != "") {
|
||||
out << YAML::Key << "JSONFile" << YAML::Value << JSONFilename;
|
||||
if (JSONFilter == meshtastic_PortNum_TEXT_MESSAGE_APP)
|
||||
out << YAML::Key << "JSONFilter" << YAML::Value << "textmessage";
|
||||
else if (JSONFilter == meshtastic_PortNum_TELEMETRY_APP)
|
||||
out << YAML::Key << "JSONFilter" << YAML::Value << "telemetry";
|
||||
else if (JSONFilter == meshtastic_PortNum_NODEINFO_APP)
|
||||
out << YAML::Key << "JSONFilter" << YAML::Value << "nodeinfo";
|
||||
else if (JSONFilter == meshtastic_PortNum_POSITION_APP)
|
||||
out << YAML::Key << "JSONFilter" << YAML::Value << "position";
|
||||
else if (JSONFilter == meshtastic_PortNum_WAYPOINT_APP)
|
||||
out << YAML::Key << "JSONFilter" << YAML::Value << "waypoint";
|
||||
else if (JSONFilter == meshtastic_PortNum_NEIGHBORINFO_APP)
|
||||
out << YAML::Key << "JSONFilter" << YAML::Value << "neighborinfo";
|
||||
else if (JSONFilter == meshtastic_PortNum_TRACEROUTE_APP)
|
||||
out << YAML::Key << "JSONFilter" << YAML::Value << "traceroute";
|
||||
else if (JSONFilter == meshtastic_PortNum_DETECTION_SENSOR_APP)
|
||||
out << YAML::Key << "JSONFilter" << YAML::Value << "detection";
|
||||
else if (JSONFilter == meshtastic_PortNum_PAXCOUNTER_APP)
|
||||
out << YAML::Key << "JSONFilter" << YAML::Value << "paxcounter";
|
||||
else if (JSONFilter == meshtastic_PortNum_REMOTE_HARDWARE_APP)
|
||||
out << YAML::Key << "JSONFilter" << YAML::Value << "remotehardware";
|
||||
}
|
||||
if (ascii_logs_explicit) {
|
||||
out << YAML::Key << "AsciiLogs" << YAML::Value << ascii_logs;
|
||||
}
|
||||
|
||||
@@ -605,12 +605,13 @@ void test_receiveAcksOwnSentMessages(void)
|
||||
|
||||
unitTest->publish(&p, nodeDB->getNodeId().c_str());
|
||||
|
||||
TEST_ASSERT_TRUE(mockRouter->packets_.empty());
|
||||
TEST_ASSERT_EQUAL(1, mockRoutingModule->ackNacks_.size());
|
||||
const auto &[err, to, idFrom, chIndex, hopLimit] = mockRoutingModule->ackNacks_.front();
|
||||
TEST_ASSERT_EQUAL(meshtastic_Routing_Error_NONE, err);
|
||||
TEST_ASSERT_EQUAL(myNodeInfo.my_node_num, to);
|
||||
TEST_ASSERT_EQUAL(p.id, idFrom);
|
||||
// FIXME: Better assertion for this test
|
||||
// TEST_ASSERT_TRUE(mockRouter->packets_.empty());
|
||||
// TEST_ASSERT_EQUAL(1, mockRoutingModule->ackNacks_.size());
|
||||
// const auto &[err, to, idFrom, chIndex, hopLimit] = mockRoutingModule->ackNacks_.front();
|
||||
// TEST_ASSERT_EQUAL(meshtastic_Routing_Error_NONE, err);
|
||||
// TEST_ASSERT_EQUAL(myNodeInfo.my_node_num, to);
|
||||
// TEST_ASSERT_EQUAL(p.id, idFrom);
|
||||
}
|
||||
|
||||
// Should ignore our own messages from MQTT that were heard by other nodes.
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
// "USERPREFS_MQTT_TLS_ENABLED": "false",
|
||||
// "USERPREFS_MQTT_ROOT_TOPIC": "event/REPLACEME",
|
||||
// "USERPREFS_RINGTONE_NAG_SECS": "60",
|
||||
// "USERPREFS_NODEINFO_REPLY_SUPPRESS_SECS": "43200",
|
||||
"USERPREFS_RINGTONE_RTTTL": "24:d=32,o=5,b=565:f6,p,f6,4p,p,f6,p,f6,2p,p,b6,p,b6,p,b6,p,b6,p,b,p,b,p,b,p,b,p,b,p,b,p,b,p,b,1p.,2p.,p",
|
||||
// "USERPREFS_NETWORK_IPV6_ENABLED": "1",
|
||||
"USERPREFS_TZ_STRING": "tzplaceholder "
|
||||
|
||||
@@ -37,6 +37,9 @@ build_flags =
|
||||
-DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL
|
||||
-DAXP_DEBUG_PORT=Serial
|
||||
-DCONFIG_BT_NIMBLE_ENABLED
|
||||
-DCONFIG_BT_NIMBLE_ROLE_CENTRAL_DISABLED
|
||||
-DCONFIG_BT_NIMBLE_ROLE_OBSERVER_DISABLED
|
||||
-DCONFIG_BT_NIMBLE_NVS_PERSIST=1
|
||||
-DCONFIG_BT_NIMBLE_MAX_BONDS=6 # default is 3
|
||||
-DCONFIG_NIMBLE_CPP_LOG_LEVEL=2
|
||||
-DCONFIG_BT_NIMBLE_MAX_CCCDS=20
|
||||
@@ -59,7 +62,7 @@ lib_deps =
|
||||
# renovate: datasource=git-refs depName=meshtastic-esp32_https_server packageName=https://github.com/meshtastic/esp32_https_server gitBranch=master
|
||||
https://github.com/meshtastic/esp32_https_server/archive/3223704846752e6d545139204837bdb2a55459ca.zip
|
||||
# renovate: datasource=custom.pio depName=NimBLE-Arduino packageName=h2zero/library/NimBLE-Arduino
|
||||
h2zero/NimBLE-Arduino@^1.4.3
|
||||
h2zero/NimBLE-Arduino@^2.3.7
|
||||
# renovate: datasource=git-refs depName=libpax packageName=https://github.com/dbinfrago/libpax gitBranch=master
|
||||
https://github.com/dbinfrago/libpax/archive/3cdc0371c375676a97967547f4065607d4c53fd1.zip
|
||||
# renovate: datasource=github-tags depName=XPowersLib packageName=lewisxhe/XPowersLib
|
||||
|
||||
@@ -4,3 +4,8 @@ custom_esp32_kind = esp32c3
|
||||
|
||||
monitor_speed = 115200
|
||||
monitor_filters = esp32_c3_exception_decoder
|
||||
|
||||
build_flags =
|
||||
${esp32_base.build_flags}
|
||||
-DCONFIG_BT_NIMBLE_EXT_ADV=1
|
||||
-DCONFIG_BT_NIMBLE_MAX_EXT_ADV_INSTANCES=2
|
||||
|
||||
@@ -3,7 +3,7 @@ extends = esp32c3_base
|
||||
board = esp32-c3-devkitm-1
|
||||
board_level = pr
|
||||
build_flags =
|
||||
${esp32_base.build_flags}
|
||||
${esp32c3_base.build_flags}
|
||||
-D HELTEC_HT62
|
||||
-I variants/esp32c3/heltec_esp32c3
|
||||
monitor_speed = 115200
|
||||
|
||||
@@ -20,6 +20,8 @@ build_flags =
|
||||
-DHAS_BLUETOOTH=0
|
||||
-DMESHTASTIC_EXCLUDE_PAXCOUNTER
|
||||
-DMESHTASTIC_EXCLUDE_BLUETOOTH
|
||||
-DCONFIG_BT_NIMBLE_EXT_ADV=1
|
||||
-DCONFIG_BT_NIMBLE_MAX_EXT_ADV_INSTANCES=2
|
||||
|
||||
lib_deps =
|
||||
${arduino_base.lib_deps}
|
||||
|
||||
@@ -13,7 +13,7 @@ build_unflags =
|
||||
lib_deps =
|
||||
${esp32c6_base.lib_deps}
|
||||
adafruit/Adafruit NeoPixel@^1.12.3
|
||||
h2zero/NimBLE-Arduino@^2.3.6
|
||||
h2zero/NimBLE-Arduino@^2.3.7
|
||||
build_flags =
|
||||
${esp32c6_base.build_flags}
|
||||
-D M5STACK_UNITC6L
|
||||
@@ -24,7 +24,6 @@ build_flags =
|
||||
-D HAS_BLUETOOTH=1
|
||||
-DCONFIG_BT_NIMBLE_EXT_ADV=1
|
||||
-DCONFIG_BT_NIMBLE_MAX_EXT_ADV_INSTANCES=2
|
||||
-D NIMBLE_TWO
|
||||
monitor_speed=115200
|
||||
lib_ignore =
|
||||
NonBlockingRTTTL
|
||||
|
||||
@@ -3,3 +3,7 @@ extends = esp32_base
|
||||
custom_esp32_kind = esp32s3
|
||||
|
||||
monitor_speed = 115200
|
||||
build_flags =
|
||||
${esp32_base.build_flags}
|
||||
-DCONFIG_BT_NIMBLE_EXT_ADV=1
|
||||
-DCONFIG_BT_NIMBLE_MAX_EXT_ADV_INSTANCES=2
|
||||
|
||||
@@ -6,6 +6,6 @@ board_check = true
|
||||
upload_protocol = esptool
|
||||
|
||||
build_flags =
|
||||
${esp32_base.build_flags}
|
||||
${esp32s3_base.build_flags}
|
||||
-D RAK3312
|
||||
-I variants/esp32s3/rak3312
|
||||
|
||||
@@ -9,7 +9,7 @@ board_check = true
|
||||
board_build.partitions = partition-table-8MB.csv
|
||||
upload_protocol = esptool
|
||||
|
||||
build_flags = ${esp32_base.build_flags}
|
||||
build_flags = ${esp32s3_base.build_flags}
|
||||
-Ivariants/esp32s3/seeed-sensecap-indicator
|
||||
-DSENSECAP_INDICATOR
|
||||
-DCONFIG_ARDUHAL_LOG_COLORS
|
||||
|
||||
@@ -100,3 +100,5 @@
|
||||
#define MODEM_DTR 8
|
||||
#define MODEM_RX 10
|
||||
#define MODEM_TX 11
|
||||
|
||||
#define HAS_PHYSICAL_KEYBOARD 1
|
||||
@@ -23,6 +23,7 @@
|
||||
#define SCREEN_TRANSITION_FRAMERATE 5
|
||||
#define BRIGHTNESS_DEFAULT 130 // Medium Low Brightness
|
||||
#define USE_TFTDISPLAY 1
|
||||
#define HAS_PHYSICAL_KEYBOARD 1
|
||||
|
||||
#define HAS_TOUCHSCREEN 1
|
||||
#define SCREEN_TOUCH_INT 16
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#define SCREEN_TRANSITION_FRAMERATE 5
|
||||
#define BRIGHTNESS_DEFAULT 130 // Medium Low Brightness
|
||||
#define USE_TFTDISPLAY 1
|
||||
#define HAS_PHYSICAL_KEYBOARD 1
|
||||
|
||||
#define I2C_SDA SDA
|
||||
#define I2C_SCL SCL
|
||||
|
||||
@@ -54,6 +54,7 @@ extern "C" {
|
||||
#define LED_POWER red_LED_PIN
|
||||
#define LED_CHARGE LED_POWER // Signals the Status LED Module to handle this LED
|
||||
#define green_LED_PIN 35
|
||||
#define PIN_LED2 green_LED_PIN
|
||||
#define LED_BLUE 37
|
||||
#define LED_PAIRING LED_BLUE // Signals the Status LED Module to handle this LED
|
||||
|
||||
|
||||
@@ -41,3 +41,30 @@ void initVariant()
|
||||
pinMode(VDD_FLASH_EN, OUTPUT);
|
||||
digitalWrite(VDD_FLASH_EN, HIGH);
|
||||
}
|
||||
|
||||
// called from main-nrf52.cpp during the cpuDeepSleep() function
|
||||
void variant_shutdown()
|
||||
{
|
||||
// This sets the pin to OUTPUT and LOW for the pins *not* in the if block.
|
||||
for (int pin = 0; pin < 48; pin++) {
|
||||
if (pin == PIN_GPS_EN || pin == ADC_CTRL || pin == PIN_BUTTON1 || pin == PIN_SPI_MISO || pin == PIN_SPI_MOSI ||
|
||||
pin == PIN_SPI_SCK) {
|
||||
continue;
|
||||
}
|
||||
pinMode(pin, OUTPUT);
|
||||
digitalWrite(pin, LOW);
|
||||
if (pin >= 32) {
|
||||
NRF_P1->DIRCLR = (1 << (pin - 32));
|
||||
} else {
|
||||
NRF_GPIO->DIRCLR = (1 << pin);
|
||||
}
|
||||
}
|
||||
|
||||
digitalWrite(PIN_GPS_EN, LOW);
|
||||
digitalWrite(ADC_CTRL, LOW);
|
||||
// digitalWrite(RTC_POWER, LOW);
|
||||
|
||||
nrf_gpio_cfg_input(PIN_BUTTON1, NRF_GPIO_PIN_PULLUP); // Configure the pin to be woken up as an input
|
||||
nrf_gpio_pin_sense_t sense1 = NRF_GPIO_PIN_SENSE_LOW;
|
||||
nrf_gpio_cfg_sense_set(PIN_BUTTON1, sense1);
|
||||
}
|
||||
|
||||
@@ -44,8 +44,10 @@ extern "C" {
|
||||
#define LED_BLUE -1
|
||||
#define LED_CHARGE (12)
|
||||
#define LED_PAIRING (7)
|
||||
#define PIN_LED2 LED_PAIRING
|
||||
|
||||
#define LED_STATE_ON 1
|
||||
#define LED_STATE_ON HIGH
|
||||
#define LED_STATE_OFF LOW
|
||||
|
||||
// USB power detection
|
||||
#define EXT_PWR_DETECT (13)
|
||||
|
||||
@@ -90,16 +90,16 @@ NRF52 PRO MICRO PIN ASSIGNMENT
|
||||
#define BUTTON_PIN (32 + 0) // P1.00
|
||||
|
||||
// GPS
|
||||
#define PIN_GPS_TX (0 + 20) // P0.20 - This is data from the MCU
|
||||
#define PIN_GPS_RX (0 + 22) // P0.22 - This is data from the GNSS
|
||||
#define GPS_TX_PIN (0 + 20) // P0.20 - This is data from the MCU
|
||||
#define GPS_RX_PIN (0 + 22) // P0.22 - This is data from the GNSS
|
||||
|
||||
#define PIN_GPS_EN (0 + 24) // P0.24
|
||||
#define GPS_UBLOX
|
||||
// define GPS_DEBUG
|
||||
|
||||
// UART interfaces
|
||||
#define PIN_SERIAL1_TX PIN_GPS_TX
|
||||
#define PIN_SERIAL1_RX PIN_GPS_RX
|
||||
#define PIN_SERIAL1_TX GPS_TX_PIN
|
||||
#define PIN_SERIAL1_RX GPS_RX_PIN
|
||||
|
||||
#define PIN_SERIAL2_RX (0 + 6) // P0.06
|
||||
#define PIN_SERIAL2_TX (0 + 8) // P0.08
|
||||
|
||||
@@ -132,13 +132,13 @@ External serial flash W25Q16JV_IQ
|
||||
#define GPS_L76K
|
||||
|
||||
#define PIN_GPS_STANDBY (0 + 13) // An output to wake GPS, low means allow sleep, high means force wake STANDBY
|
||||
#define PIN_GPS_TX (0 + 10) // This is for bits going TOWARDS the CPU
|
||||
#define PIN_GPS_RX (0 + 9) // This is for bits going TOWARDS the GPS
|
||||
#define GPS_TX_PIN (0 + 10) // This is for bits going FROM the CPU
|
||||
#define GPS_RX_PIN (0 + 9) // This is for bits going FROM the GPS
|
||||
|
||||
// #define GPS_THREAD_INTERVAL 50
|
||||
|
||||
#define PIN_SERIAL1_TX PIN_GPS_TX
|
||||
#define PIN_SERIAL1_RX PIN_GPS_RX
|
||||
#define PIN_SERIAL1_TX GPS_TX_PIN
|
||||
#define PIN_SERIAL1_RX GPS_RX_PIN
|
||||
|
||||
// PCF8563 RTC Module
|
||||
#define PCF8563_RTC 0x51
|
||||
|
||||
@@ -19,7 +19,6 @@ build_type = release
|
||||
build_flags =
|
||||
-include variants/nrf52840/cpp_overrides/lfs_util.h
|
||||
${arduino_base.build_flags}
|
||||
-DSERIAL_BUFFER_SIZE=1024
|
||||
-Wno-unused-variable
|
||||
-Isrc/platform/nrf52
|
||||
-DLFS_NO_ASSERT ; Disable LFS assertions , see https://github.com/meshtastic/firmware/pull/3818
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
[nrf52832_base]
|
||||
extends = nrf52_base
|
||||
|
||||
build_flags = ${nrf52_base.build_flags}
|
||||
build_flags =
|
||||
${nrf52_base.build_flags}
|
||||
-DSERIAL_BUFFER_SIZE=1024
|
||||
|
||||
lib_deps =
|
||||
${nrf52_base.lib_deps}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
[nrf52840_base]
|
||||
extends = nrf52_base
|
||||
|
||||
build_flags = ${nrf52_base.build_flags}
|
||||
build_flags =
|
||||
${nrf52_base.build_flags}
|
||||
-DSERIAL_BUFFER_SIZE=4096
|
||||
|
||||
lib_deps =
|
||||
${nrf52_base.lib_deps}
|
||||
|
||||
@@ -116,13 +116,13 @@ static const uint8_t SCL = PIN_WIRE_SCL;
|
||||
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
#define GPS_L76K
|
||||
#ifdef GPS_L76K
|
||||
#define PIN_GPS_TX D6 // 44
|
||||
#define PIN_GPS_RX D7 // 43
|
||||
#define GPS_TX_PIN D6 // 44
|
||||
#define GPS_RX_PIN D7 // 43
|
||||
#define HAS_GPS 1
|
||||
#define GPS_BAUDRATE 9600
|
||||
#define GPS_THREAD_INTERVAL 50
|
||||
#define PIN_SERIAL1_TX PIN_GPS_TX
|
||||
#define PIN_SERIAL1_RX PIN_GPS_RX
|
||||
#define PIN_SERIAL1_TX GPS_TX_PIN
|
||||
#define PIN_SERIAL1_RX GPS_RX_PIN
|
||||
#define PIN_GPS_STANDBY D0
|
||||
#define GPS_EN D18 // P1.05
|
||||
#endif
|
||||
|
||||
@@ -119,16 +119,14 @@ static const uint8_t SCL = PIN_WIRE_SCL;
|
||||
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
#define GPS_L76K
|
||||
#ifdef GPS_L76K
|
||||
#define PIN_GPS_RX D6 // P0.26
|
||||
#define PIN_GPS_TX D7
|
||||
#define GPS_TX_PIN D6 // P0.26 - This is data from the MCU
|
||||
#define GPS_RX_PIN D7 // P0.27 - This is data from the GNSS
|
||||
#define HAS_GPS 1
|
||||
#define GPS_BAUDRATE 9600
|
||||
#define GPS_THREAD_INTERVAL 50
|
||||
#define PIN_SERIAL1_RX PIN_GPS_TX
|
||||
#define PIN_SERIAL1_TX PIN_GPS_RX
|
||||
#define PIN_SERIAL1_RX GPS_RX_PIN
|
||||
#define PIN_SERIAL1_TX GPS_TX_PIN
|
||||
|
||||
#define GPS_RX_PIN PIN_GPS_TX
|
||||
#define GPS_TX_PIN PIN_GPS_RX
|
||||
#define PIN_GPS_STANDBY D0
|
||||
|
||||
// #define GPS_DEBUG
|
||||
|
||||
@@ -129,16 +129,14 @@ static const uint8_t SCL = PIN_WIRE_SCL;
|
||||
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
#define GPS_L76K
|
||||
#ifdef GPS_L76K
|
||||
#define PIN_GPS_RX D6 // P0.26
|
||||
#define PIN_GPS_TX D7
|
||||
#define GPS_TX_PIN D6 // P0.26 - This is data from the MCU
|
||||
#define GPS_RX_PIN D7 // P0.27 - This is data from the GNSS
|
||||
#define HAS_GPS 1
|
||||
#define GPS_BAUDRATE 9600
|
||||
#define GPS_THREAD_INTERVAL 50
|
||||
#define PIN_SERIAL1_RX PIN_GPS_TX
|
||||
#define PIN_SERIAL1_TX PIN_GPS_RX
|
||||
#define PIN_SERIAL1_RX GPS_RX_PIN
|
||||
#define PIN_SERIAL1_TX GPS_TX_PIN
|
||||
|
||||
#define GPS_RX_PIN PIN_GPS_TX
|
||||
#define GPS_TX_PIN PIN_GPS_RX
|
||||
#define PIN_GPS_STANDBY D0
|
||||
|
||||
// #define GPS_DEBUG
|
||||
|
||||
@@ -147,12 +147,12 @@ static const uint8_t SCK = PIN_SPI_SCK;
|
||||
*/
|
||||
// GPS L76K
|
||||
#ifdef GPS_L76K
|
||||
#define PIN_GPS_TX D6
|
||||
#define PIN_GPS_RX D7
|
||||
#define GPS_TX_PIN D6 // This is data from the MCU
|
||||
#define GPS_RX_PIN D7 // This is data from the GNSS module
|
||||
#define HAS_GPS 1
|
||||
#define GPS_THREAD_INTERVAL 50
|
||||
#define PIN_SERIAL1_TX PIN_GPS_TX
|
||||
#define PIN_SERIAL1_RX PIN_GPS_RX
|
||||
#define PIN_SERIAL1_TX GPS_TX_PIN
|
||||
#define PIN_SERIAL1_RX GPS_RX_PIN
|
||||
#define PIN_GPS_STANDBY D0
|
||||
#else
|
||||
#define PIN_SERIAL1_RX (-1)
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
[rp2040_base]
|
||||
platform =
|
||||
# TODO renovate
|
||||
https://github.com/maxgerhardt/platform-raspberrypi#76ecf3c7e9dd4503af0331154c4ca1cddc4b03e5
|
||||
; For arduino-pico >= 4.4.3
|
||||
https://github.com/maxgerhardt/platform-raspberrypi#cc24cfef37ed22ca9f2a6aead28c2deb76c39f24
|
||||
; For arduino-pico >= 5.4.4
|
||||
extends = arduino_base
|
||||
platform_packages =
|
||||
# TODO renovate
|
||||
framework-arduinopico@https://github.com/earlephilhower/arduino-pico#4.4.3
|
||||
arduino-pico@https://github.com/earlephilhower/arduino-pico/releases/download/5.4.4/rp2040-5.4.4.zip
|
||||
|
||||
board_build.core = earlephilhower
|
||||
board_build.filesystem_size = 0.5m
|
||||
@@ -17,6 +17,7 @@ build_flags =
|
||||
-Isrc/platform/rp2xx0/hardware_rosc/include
|
||||
-Isrc/platform/rp2xx0/pico_sleep/include
|
||||
-D__PLAT_RP2040__
|
||||
-D__FREERTOS=1
|
||||
# -D _POSIX_THREADS
|
||||
build_src_filter =
|
||||
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<modules/esp32> -<platform/nrf52/> -<platform/stm32wl> -<mesh/eth/> -<mesh/wifi/> -<mesh/http/> -<mesh/raspihttp>
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
[rp2350_base]
|
||||
platform =
|
||||
# TODO renovate
|
||||
https://github.com/maxgerhardt/platform-raspberrypi#76ecf3c7e9dd4503af0331154c4ca1cddc4b03e5
|
||||
; For arduino-pico >= 4.4.3
|
||||
https://github.com/maxgerhardt/platform-raspberrypi#cc24cfef37ed22ca9f2a6aead28c2deb76c39f24
|
||||
; For arduino-pico >= 5.4.4
|
||||
extends = arduino_base
|
||||
platform_packages =
|
||||
# TODO renovate
|
||||
framework-arduinopico@https://github.com/earlephilhower/arduino-pico#4.4.3
|
||||
arduino-pico@https://github.com/earlephilhower/arduino-pico/releases/download/5.4.4/rp2040-5.4.4.zip
|
||||
|
||||
board_build.core = earlephilhower
|
||||
board_build.filesystem_size = 0.5m
|
||||
@@ -15,6 +15,7 @@ build_flags =
|
||||
${arduino_base.build_flags} -Wno-unused-variable -Wcast-align
|
||||
-Isrc/platform/rp2xx0
|
||||
-D__PLAT_RP2350__
|
||||
-D__FREERTOS=1
|
||||
build_src_filter =
|
||||
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<modules/esp32> -<platform/nrf52/> -<platform/stm32wl> -<mesh/eth/> -<mesh/wifi/> -<mesh/http/> -<mesh/raspihttp> -<platform/rp2xx0/pico_sleep> -<platform/rp2xx0/hardware_rosc>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user