mirror of
https://github.com/meshtastic/firmware.git
synced 2026-01-01 15:40:49 +00:00
Compare commits
138 Commits
v1.3.43.aa
...
v1.3.48.82
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
82bcd391cd | ||
|
|
058689709f | ||
|
|
23c9fa0b56 | ||
|
|
eb29f10634 | ||
|
|
d5a9e3114a | ||
|
|
7417729482 | ||
|
|
d5c407c098 | ||
|
|
a1256818d9 | ||
|
|
689cec14aa | ||
|
|
04225826f6 | ||
|
|
86787e60f3 | ||
|
|
0c3ec9254d | ||
|
|
c0770402ce | ||
|
|
d7c98062ce | ||
|
|
497c0b7a47 | ||
|
|
d588dde007 | ||
|
|
3de0a3adfc | ||
|
|
b7ebe03ca8 | ||
|
|
a7fb88e293 | ||
|
|
6e1b1e3ed7 | ||
|
|
a66538fe55 | ||
|
|
b2913be086 | ||
|
|
602e65d898 | ||
|
|
338c9c1e0c | ||
|
|
9fac57b713 | ||
|
|
761804b17a | ||
|
|
c47401d729 | ||
|
|
aab52f1e8d | ||
|
|
4d2e44d64b | ||
|
|
41267a42f7 | ||
|
|
568434d0fa | ||
|
|
2c1bbf1ac6 | ||
|
|
1e97dcbb4c | ||
|
|
103c82bc2c | ||
|
|
f3fee5f4fb | ||
|
|
564feadc0d | ||
|
|
f05e0f3a81 | ||
|
|
cb26bc3871 | ||
|
|
f6251eef27 | ||
|
|
a9d6ef5990 | ||
|
|
60da55d6dd | ||
|
|
05147c016c | ||
|
|
f7655f3abe | ||
|
|
62b3509009 | ||
|
|
d817889255 | ||
|
|
d4ddcdd91e | ||
|
|
0bda4c2f76 | ||
|
|
be8da851a6 | ||
|
|
d4459a48b9 | ||
|
|
197bd2c3e1 | ||
|
|
d4ea9568ac | ||
|
|
97968213ff | ||
|
|
995885962d | ||
|
|
ddc1928bbb | ||
|
|
056a93f0c9 | ||
|
|
3d9845ff6d | ||
|
|
b615463981 | ||
|
|
d3540e82ff | ||
|
|
15ec8ba6a3 | ||
|
|
db12eab083 | ||
|
|
7d8c77a4b2 | ||
|
|
7c8c479b96 | ||
|
|
e29ae1cc91 | ||
|
|
089dd5b4d7 | ||
|
|
06285b599c | ||
|
|
1b6395b4e4 | ||
|
|
2236f74a55 | ||
|
|
43c9ab1faa | ||
|
|
b56f9b3b16 | ||
|
|
303396dfc3 | ||
|
|
075a53ced0 | ||
|
|
18ccb38824 | ||
|
|
c97831963b | ||
|
|
7c3dc076d2 | ||
|
|
b859347ecd | ||
|
|
ea87193c8f | ||
|
|
c1381b9ebd | ||
|
|
227cd93e67 | ||
|
|
f68f8e5547 | ||
|
|
943e6f02d4 | ||
|
|
01298a7b01 | ||
|
|
46aee8274f | ||
|
|
f76a2eeb9e | ||
|
|
3b7c0be842 | ||
|
|
49378a9145 | ||
|
|
139f61d03e | ||
|
|
f10d04591d | ||
|
|
e65d9e8ccd | ||
|
|
1fc3c0af70 | ||
|
|
e4751e34ae | ||
|
|
e922169e72 | ||
|
|
2b851ef6ae | ||
|
|
5f4b93aba2 | ||
|
|
b66d1a5dab | ||
|
|
867525eff8 | ||
|
|
7dcc981a2c | ||
|
|
38fed8a61e | ||
|
|
31c2c8a7a3 | ||
|
|
a081d28e36 | ||
|
|
93bb4f84f9 | ||
|
|
72e04edd7f | ||
|
|
b0d05522c0 | ||
|
|
f6119639bb | ||
|
|
fc57a9daa4 | ||
|
|
d8f44d7b1b | ||
|
|
efe2e90a03 | ||
|
|
45f9dee89a | ||
|
|
cc73d2c2f2 | ||
|
|
b1f789dddd | ||
|
|
d3e9dbf6a9 | ||
|
|
44529620ad | ||
|
|
7a9673dc37 | ||
|
|
27bcf67c0c | ||
|
|
7fde56b8ac | ||
|
|
6b614a2d6a | ||
|
|
1e1509fbf5 | ||
|
|
a3e67f8e4b | ||
|
|
028b25cfe8 | ||
|
|
2555e082d6 | ||
|
|
f8fa721c72 | ||
|
|
a7e0127793 | ||
|
|
603f60d86a | ||
|
|
6febf6b17c | ||
|
|
53aaf766dd | ||
|
|
4fa8d02b08 | ||
|
|
efa423c8ad | ||
|
|
43fb0d80f1 | ||
|
|
b25ace14e5 | ||
|
|
8734751bc4 | ||
|
|
5559a1edb0 | ||
|
|
bf503354f3 | ||
|
|
7b10441a28 | ||
|
|
994e396c00 | ||
|
|
6e22ee9061 | ||
|
|
b5fb0f60b0 | ||
|
|
a7fe69ed6b | ||
|
|
7f05298172 | ||
|
|
92a2505056 |
58
.github/workflows/main_matrix.yml
vendored
58
.github/workflows/main_matrix.yml
vendored
@@ -57,12 +57,12 @@ jobs:
|
||||
sudo apt-get install -y cppcheck
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v2
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- name: Cache python libs
|
||||
uses: actions/cache@v1
|
||||
uses: actions/cache@v3
|
||||
id: cache-pip # needed in if test
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
@@ -112,12 +112,12 @@ jobs:
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v2
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- name: Cache python libs
|
||||
uses: actions/cache@v1
|
||||
uses: actions/cache@v3
|
||||
id: cache-pip # needed in if test
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
@@ -157,11 +157,11 @@ jobs:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Get release version string
|
||||
run: echo "::set-output name=version::$(./bin/buildinfo.py long)"
|
||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||
id: version
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: firmware-${{ matrix.board }}-${{ steps.version.outputs.version }}.zip
|
||||
path: |
|
||||
@@ -190,12 +190,12 @@ jobs:
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v2
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- name: Cache python libs
|
||||
uses: actions/cache@v1
|
||||
uses: actions/cache@v3
|
||||
id: cache-pip # needed in if test
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
@@ -214,11 +214,11 @@ jobs:
|
||||
run: bin/build-nrf52.sh ${{ matrix.board }}
|
||||
|
||||
- name: Get release version string
|
||||
run: echo "::set-output name=version::$(./bin/buildinfo.py long)"
|
||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||
id: version
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: firmware-${{ matrix.board }}-${{ steps.version.outputs.version }}.zip
|
||||
path: |
|
||||
@@ -245,12 +245,12 @@ jobs:
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v2
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- name: Cache python libs
|
||||
uses: actions/cache@v1
|
||||
uses: actions/cache@v3
|
||||
id: cache-pip # needed in if test
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
@@ -269,11 +269,11 @@ jobs:
|
||||
run: ./bin/build-rpi2040.sh ${{ matrix.board }}
|
||||
|
||||
- name: Get release version string
|
||||
run: echo "::set-output name=version::$(./bin/buildinfo.py long)"
|
||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||
id: version
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: firmware-${{ matrix.board }}-${{ steps.version.outputs.version }}.zip
|
||||
path: |
|
||||
@@ -292,12 +292,12 @@ jobs:
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v2
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- name: Cache python libs
|
||||
uses: actions/cache@v1
|
||||
uses: actions/cache@v3
|
||||
id: cache-pip # needed in if test
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
@@ -327,11 +327,11 @@ jobs:
|
||||
run: bin/build-native.sh
|
||||
|
||||
- name: Get release version string
|
||||
run: echo "::set-output name=version::$(./bin/buildinfo.py long)"
|
||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||
id: version
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: firmware-native-${{ steps.version.outputs.version }}.zip
|
||||
path: |
|
||||
@@ -360,19 +360,19 @@ jobs:
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- uses: actions/download-artifact@v2
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
path: ./
|
||||
|
||||
- name: Get release version string
|
||||
run: echo "::set-output name=version::$(./bin/buildinfo.py long)"
|
||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||
id: version
|
||||
|
||||
- name: Move files up
|
||||
run: mv -b -t ./ ./*tbeam-1*/littlefs*.bin ./*tbeam-1*/bleota.bin ./**/firmware*.bin ./*t-echo*/Meshtastic_nRF52_factory_erase.uf2 ./**/firmware-*.uf2 ./**/firmware-*-ota.zip ./**/*.elf ./**/meshtasticd_linux_amd64 ./*native*/*device-*.sh ./*native*/*device-*.bat
|
||||
|
||||
- name: Repackage in single firmware zip
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: firmware-${{ steps.version.outputs.version }}
|
||||
path: |
|
||||
@@ -384,7 +384,7 @@ jobs:
|
||||
./device-*.bat
|
||||
retention-days: 90
|
||||
|
||||
- uses: actions/download-artifact@v2
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: firmware-${{ steps.version.outputs.version }}
|
||||
path: ./output
|
||||
@@ -402,7 +402,7 @@ jobs:
|
||||
run: zip -j -r ./firmware-${{ steps.version.outputs.version }}.zip ./output
|
||||
|
||||
- name: Repackage in single elfs zip
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: debug-elfs-${{ steps.version.outputs.version }}.zip
|
||||
path: ./*.elf
|
||||
@@ -426,18 +426,18 @@ jobs:
|
||||
needs: [gather-artifacts, after-checks]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v2
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- name: Get release version string
|
||||
run: echo "::set-output name=version::$(./bin/buildinfo.py long)"
|
||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||
id: version
|
||||
|
||||
- uses: actions/download-artifact@v2
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: firmware-${{ steps.version.outputs.version }}
|
||||
path: ./output
|
||||
@@ -450,7 +450,7 @@ jobs:
|
||||
- name: Zip firmware
|
||||
run: zip -j -r ./firmware-${{ steps.version.outputs.version }}.zip ./output
|
||||
|
||||
- uses: actions/download-artifact@v2
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: debug-elfs-${{ steps.version.outputs.version }}.zip
|
||||
path: ./elfs
|
||||
@@ -468,7 +468,7 @@ jobs:
|
||||
with:
|
||||
draft: true
|
||||
prerelease: true
|
||||
release_name: Meshtastic Device ${{ steps.version.outputs.version }} alpha - Public Preview
|
||||
release_name: Meshtastic Device ${{ steps.version.outputs.version }} Alpha
|
||||
tag_name: v${{ steps.version.outputs.version }}
|
||||
body: |
|
||||
Autogenerated by github action, developer should edit as required before publishing...
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
extends = arduino_base
|
||||
platform = platformio/espressif32@^5.2.0
|
||||
build_src_filter =
|
||||
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040>
|
||||
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040> -<mesh/eth/>
|
||||
upload_speed = 921600
|
||||
debug_init_break = tbreak setup
|
||||
monitor_filters = esp32_exception_decoder
|
||||
@@ -33,8 +33,7 @@ lib_deps =
|
||||
${environmental_base.lib_deps}
|
||||
https://github.com/meshtastic/esp32_https_server.git#657509856ce97e9dddeffb89a559f544faefd5cd
|
||||
h2zero/NimBLE-Arduino@^1.4.0
|
||||
arduino-libraries/NTPClient@^3.1.0
|
||||
https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
|
||||
https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
|
||||
|
||||
lib_ignore =
|
||||
segger_rtt
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
extends = arduino_base
|
||||
platform = platformio/espressif32@^5.2.0
|
||||
build_src_filter =
|
||||
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040>
|
||||
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040> -<mesh/eth/>
|
||||
upload_speed = 961200
|
||||
monitor_speed = 115200
|
||||
debug_init_break = tbreak setup
|
||||
@@ -33,7 +33,6 @@ lib_deps =
|
||||
${environmental_base.lib_deps}
|
||||
https://github.com/meshtastic/esp32_https_server.git#657509856ce97e9dddeffb89a559f544faefd5cd
|
||||
h2zero/NimBLE-Arduino@^1.4.0
|
||||
arduino-libraries/NTPClient@^3.1.0
|
||||
https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
|
||||
|
||||
lib_ignore =
|
||||
|
||||
@@ -8,7 +8,7 @@ build_flags =
|
||||
${arduino_base.build_flags} -Wno-unused-variable
|
||||
-Isrc/platform/nrf52
|
||||
build_src_filter =
|
||||
${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mqtt/> -<platform/rp2040>
|
||||
${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mqtt/> -<platform/rp2040> -<mesh/eth/>
|
||||
lib_ignore =
|
||||
BluetoothOTA
|
||||
|
||||
|
||||
@@ -7,7 +7,8 @@ build_src_filter =
|
||||
-<platform/nrf52/>
|
||||
-<platform/stm32wl/>
|
||||
-<platform/rp2040>
|
||||
-<mesh/http/>
|
||||
-<mesh/http/>
|
||||
-<mesh/eth/>
|
||||
-<modules/esp32>
|
||||
-<modules/Telemetry>
|
||||
+<../variants/portduino>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
; Common settings for rp2040 Processor based targets
|
||||
[rp2040_base]
|
||||
platform = https://github.com/maxgerhardt/platform-raspberrypi.git
|
||||
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#5ce1a228e7cae453f366deb8962252b9b7356bbc
|
||||
extends = arduino_base
|
||||
board_build.core = earlephilhower
|
||||
board_build.filesystem_size = 0.5m
|
||||
@@ -10,7 +10,7 @@ build_flags =
|
||||
-D__PLAT_RP2040__
|
||||
# -D _POSIX_THREADS
|
||||
build_src_filter =
|
||||
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mqtt/> -<platform/nrf52/> -<platform/stm32wl>
|
||||
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mqtt/> -<platform/nrf52/> -<platform/stm32wl> -<mesh/eth/>
|
||||
lib_ignore =
|
||||
BluetoothOTA
|
||||
lib_deps =
|
||||
|
||||
@@ -10,7 +10,7 @@ build_flags =
|
||||
# Arduino/PlatformIO framework-arduinoststm32 package does not presently have SUBGHZSPI support
|
||||
# -DPIN_SPI_MOSI=PINSUBGHZSPIMOSI -DPIN_SPI_MISO=PINSUBGHZSPIMISO -DPIN_SPI_SCK=PINSUBGHZSPISCK
|
||||
build_src_filter =
|
||||
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mqtt/> -<graphics> -<input> -<buzz> -<modules/Telemetry> -<platform/nrf52> -<platform/portduino> -<platform/rp2040>
|
||||
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<mqtt/> -<graphics> -<input> -<buzz> -<modules/Telemetry> -<platform/nrf52> -<platform/portduino> -<platform/rp2040>
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
https://github.com/kokke/tiny-AES-c.git#f06ac37fc31dfdaca2e0d9bec83f90d5663c319b
|
||||
|
||||
@@ -57,6 +57,9 @@ lib_deps =
|
||||
; Used for the code analysis in PIO Home / Inspect
|
||||
check_tool = cppcheck
|
||||
check_skip_packages = yes
|
||||
check_flags =
|
||||
--common-flag
|
||||
cppcheck: --enable=--inline-suppr
|
||||
|
||||
; Common settings for conventional (non Portduino) Arduino targets
|
||||
[arduino_base]
|
||||
@@ -65,6 +68,7 @@ lib_deps =
|
||||
${env.lib_deps}
|
||||
; Portduino is using meshtastic fork for now
|
||||
jgromes/RadioLib@5.4.1
|
||||
https://github.com/meshtastic/SparkFun_ATECCX08a_Arduino_Library.git#52b5282639d08a8cbd4b748363089eed6102dc76
|
||||
|
||||
build_flags = ${env.build_flags} -Os
|
||||
-DRADIOLIB_SPI_PARANOID=0
|
||||
@@ -75,6 +79,7 @@ build_src_filter = ${env.build_src_filter} -<platform/portduino/>
|
||||
[networking_base]
|
||||
lib_deps =
|
||||
knolleary/PubSubClient@^2.8
|
||||
arduino-libraries/NTPClient@^3.1.0
|
||||
meshtastic/json11@^1.0.2
|
||||
|
||||
; Common libs for environmental measurements in telemetry module
|
||||
@@ -89,4 +94,5 @@ lib_deps =
|
||||
adafruit/Adafruit MCP9808 Library@^2.0.0
|
||||
adafruit/Adafruit INA260 Library@^1.5.0
|
||||
adafruit/Adafruit INA219@^1.2.0
|
||||
|
||||
adafruit/Adafruit SHTC3 Library@^1.0.0
|
||||
adafruit/Adafruit LPS2X@^2.0.4
|
||||
Submodule protobufs updated: d3dfaa63a5...a79e3aef81
@@ -7,7 +7,7 @@ const uint8_t MESH_SERVICE_UUID_16[16u] = {0xfd, 0xea, 0x73, 0xe2, 0xca, 0x5d, 0
|
||||
0x1f, 0x46, 0xa8, 0x15, 0x18, 0xb2, 0xa1, 0x6b};
|
||||
const uint8_t TORADIO_UUID_16[16u] = {0xe7, 0x01, 0x44, 0x12, 0x66, 0x78, 0xdd, 0xa1,
|
||||
0xad, 0x4d, 0x9e, 0x12, 0xd2, 0x76, 0x5c, 0xf7};
|
||||
const uint8_t FROMRADIO_UUID_16[16u] = {0xd5, 0x54, 0xe4, 0xc5, 0x25, 0xc5, 0x31, 0xa5,
|
||||
0x55, 0x4a, 0x02, 0xee, 0xc2, 0xbc, 0xa2, 0x8b};
|
||||
const uint8_t FROMRADIO_UUID_16[16u] = {0x02, 0x00, 0x12, 0xac, 0x42, 0x02, 0x78, 0xb8,
|
||||
0xed, 0x11, 0x93, 0x49, 0x9e, 0xe6, 0x55, 0x2c};
|
||||
const uint8_t FROMNUM_UUID_16[16u] = {0x53, 0x44, 0xe3, 0x47, 0x75, 0xaa, 0x70, 0xa6,
|
||||
0x66, 0x4f, 0x00, 0xa8, 0x8c, 0xa1, 0x9d, 0xed};
|
||||
@@ -159,21 +159,16 @@ class ButtonThread : public concurrency::OSThread
|
||||
|
||||
static void userButtonDoublePressed()
|
||||
{
|
||||
#ifdef ARCH_ESP32
|
||||
disablePin();
|
||||
#elif defined(USE_EINK)
|
||||
#if defined(USE_EINK)
|
||||
digitalWrite(PIN_EINK_EN, digitalRead(PIN_EINK_EN) == LOW);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void userButtonMultiPressed()
|
||||
{
|
||||
#ifdef ARCH_ESP32
|
||||
clearNVS();
|
||||
#endif
|
||||
#ifdef ARCH_NRF52
|
||||
clearBonds();
|
||||
#endif
|
||||
screen->print("Sent ad-hoc ping\n");
|
||||
service.refreshMyNodeInfo();
|
||||
service.sendNetworkPing(NODENUM_BROADCAST, true);
|
||||
}
|
||||
|
||||
static void userButtonPressedLongStart()
|
||||
|
||||
@@ -44,10 +44,15 @@ size_t RedirectablePrint::vprintf(const char *format, va_list arg)
|
||||
static char printBuf[160];
|
||||
|
||||
va_copy(copy, arg);
|
||||
int len = vsnprintf(printBuf, sizeof(printBuf), format, copy);
|
||||
size_t len = vsnprintf(printBuf, sizeof(printBuf), format, copy);
|
||||
va_end(copy);
|
||||
|
||||
if (len < 0) return 0;
|
||||
// If the resulting string is longer than sizeof(printBuf)-1 characters, the remaining characters are still counted for the return value
|
||||
|
||||
if (len > sizeof(printBuf) - 1) {
|
||||
len = sizeof(printBuf) - 1;
|
||||
printBuf[sizeof(printBuf) - 2] = '\n';
|
||||
}
|
||||
|
||||
len = Print::write(printBuf, len);
|
||||
return len;
|
||||
@@ -103,4 +108,4 @@ size_t RedirectablePrint::logDebug(const char *format, ...)
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "buzz.h"
|
||||
#include "configuration.h"
|
||||
#include "NodeDB.h"
|
||||
|
||||
#ifndef PIN_BUZZER
|
||||
|
||||
@@ -42,17 +43,19 @@ const int DURATION_1_8 = 125; // 1/8 note
|
||||
const int DURATION_1_4 = 250; // 1/4 note
|
||||
|
||||
void playTones(const ToneDuration *tone_durations, int size) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
const auto &tone_duration = tone_durations[i];
|
||||
if (config.network.eth_enabled != true) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
const auto &tone_duration = tone_durations[i];
|
||||
#ifdef M5STACK
|
||||
Tone.tone(tone_duration.frequency_khz);
|
||||
delay(tone_duration.duration_ms);
|
||||
Tone.mute();
|
||||
Tone.tone(tone_duration.frequency_khz);
|
||||
delay(tone_duration.duration_ms);
|
||||
Tone.mute();
|
||||
#else
|
||||
tone(PIN_BUZZER, tone_duration.frequency_khz, tone_duration.duration_ms);
|
||||
tone(PIN_BUZZER, tone_duration.frequency_khz, tone_duration.duration_ms);
|
||||
#endif
|
||||
// to distinguish the notes, set a minimum time between them.
|
||||
delay(1.3 * tone_duration.duration_ms);
|
||||
// to distinguish the notes, set a minimum time between them.
|
||||
delay(1.3 * tone_duration.duration_ms);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -110,6 +110,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define INA_ADDR_ALTERNATE 0x41
|
||||
#define QMC6310_ADDR 0x1C
|
||||
#define QMI8658_ADDR 0x6B
|
||||
#define SHTC3_ADDR 0x70
|
||||
#define LPS22HB_ADDR 0x5C
|
||||
#define LPS22HB_ADDR_ALT 0x5D
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Security
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#define ATECC608B_ADDR 0x35
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// GPS
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -132,6 +142,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#ifndef HAS_WIFI
|
||||
#define HAS_WIFI 0
|
||||
#endif
|
||||
#ifndef HAS_ETHERNET
|
||||
#define ETHERNET 0
|
||||
#endif
|
||||
#ifndef HAS_SCREEN
|
||||
#define HAS_SCREEN 0
|
||||
#endif
|
||||
|
||||
@@ -9,6 +9,41 @@
|
||||
#endif
|
||||
|
||||
#if HAS_WIRE
|
||||
|
||||
void printATECCInfo()
|
||||
{
|
||||
#ifndef ARCH_PORTDUINO
|
||||
atecc.readConfigZone(false);
|
||||
|
||||
DEBUG_MSG("ATECC608B Serial Number: ");
|
||||
for (int i = 0 ; i < 9 ; i++) {
|
||||
DEBUG_MSG("%02x",atecc.serialNumber[i]);
|
||||
}
|
||||
|
||||
DEBUG_MSG(", Rev Number: ");
|
||||
for (int i = 0 ; i < 4 ; i++) {
|
||||
DEBUG_MSG("%02x",atecc.revisionNumber[i]);
|
||||
}
|
||||
DEBUG_MSG("\n");
|
||||
|
||||
DEBUG_MSG("ATECC608B Config %s",atecc.configLockStatus ? "Locked" : "Unlocked");
|
||||
DEBUG_MSG(", Data %s",atecc.dataOTPLockStatus ? "Locked" : "Unlocked");
|
||||
DEBUG_MSG(", Slot 0 %s\n",atecc.slot0LockStatus ? "Locked" : "Unlocked");
|
||||
|
||||
if (atecc.configLockStatus && atecc.dataOTPLockStatus && atecc.slot0LockStatus) {
|
||||
if (atecc.generatePublicKey() == false) {
|
||||
DEBUG_MSG("ATECC608B Error generating public key\n");
|
||||
} else {
|
||||
DEBUG_MSG("ATECC608B Public Key: ");
|
||||
for (int i = 0 ; i < 64 ; i++) {
|
||||
DEBUG_MSG("%02x",atecc.publicKey64Bytes[i]);
|
||||
}
|
||||
DEBUG_MSG("\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
uint16_t getRegisterValue(uint8_t address, uint8_t reg, uint8_t length) {
|
||||
uint16_t value = 0x00;
|
||||
Wire.beginTransmission(address);
|
||||
@@ -79,6 +114,17 @@ void scanI2Cdevice(void)
|
||||
DEBUG_MSG("unknown display found\n");
|
||||
}
|
||||
}
|
||||
#ifndef ARCH_PORTDUINO
|
||||
if (addr == ATECC608B_ADDR){
|
||||
keystore_found = addr;
|
||||
if (atecc.begin(keystore_found) == true) {
|
||||
DEBUG_MSG("ATECC608B initialized\n");
|
||||
} else {
|
||||
DEBUG_MSG("ATECC608B initialization failed\n");
|
||||
}
|
||||
printATECCInfo();
|
||||
}
|
||||
#endif
|
||||
#ifdef RV3028_RTC
|
||||
if (addr == RV3028_RTC){
|
||||
rtc_found = addr;
|
||||
@@ -145,14 +191,22 @@ void scanI2Cdevice(void)
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_MCP9808] = addr;
|
||||
DEBUG_MSG("MCP9808 sensor found at address 0x%x\n", (uint8_t)addr);
|
||||
}
|
||||
if(addr == QMC6310_ADDR){
|
||||
if (addr == QMC6310_ADDR) {
|
||||
DEBUG_MSG("QMC6310 3-Axis magnetic sensor found at address 0x%x\n", (uint8_t)addr);
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_QMC6310] = addr;
|
||||
}
|
||||
if(addr == QMI8658_ADDR){
|
||||
if (addr == QMI8658_ADDR) {
|
||||
DEBUG_MSG("QMI8658 6-Axis inertial measurement sensor found at address 0x%x\n", (uint8_t)addr);
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_QMI8658] = addr;
|
||||
}
|
||||
if (addr == SHTC3_ADDR) {
|
||||
DEBUG_MSG("SHTC3 sensor found at address 0x%x\n", (uint8_t)addr);
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_SHTC3] = addr;
|
||||
}
|
||||
if (addr == LPS22HB_ADDR || addr == LPS22HB_ADDR_ALT) {
|
||||
DEBUG_MSG("LPS22HB sensor found at address 0x%x\n", (uint8_t)addr);
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_LPS22] = addr;
|
||||
}
|
||||
} else if (err == 4) {
|
||||
DEBUG_MSG("Unknow error at address 0x%x\n", addr);
|
||||
}
|
||||
|
||||
76
src/gps/NMEAWPL.cpp
Normal file
76
src/gps/NMEAWPL.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
#include "NMEAWPL.h"
|
||||
|
||||
/* -------------------------------------------
|
||||
* 1 2 3 4 5 6
|
||||
* | | | | | |
|
||||
* $--WPL,llll.ll,a,yyyyy.yy,a,c--c*hh<CR><LF>
|
||||
*
|
||||
* Field Number:
|
||||
* 1 Latitude
|
||||
* 2 N or S (North or South)
|
||||
* 3 Longitude
|
||||
* 4 E or W (East or West)
|
||||
* 5 Waypoint name
|
||||
* 6 Checksum
|
||||
* -------------------------------------------
|
||||
*/
|
||||
|
||||
uint printWPL(char *buf, const Position &pos, const char *name)
|
||||
{
|
||||
uint len = sprintf(buf, "$GNWPL,%07.2f,%c,%08.2f,%c,%s", pos.latitude_i * 1e-5, pos.latitude_i < 0 ? 'S' : 'N', pos.longitude_i * 1e-5, pos.longitude_i < 0 ? 'W' : 'E', name);
|
||||
uint chk = 0;
|
||||
for (uint i = 1; i < len; i++) {
|
||||
chk ^= buf[i];
|
||||
}
|
||||
len += sprintf(buf + len, "*%02X\r\n", chk);
|
||||
return len;
|
||||
}
|
||||
|
||||
/* -------------------------------------------
|
||||
* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
* | | | | | | | | | | | | | | |
|
||||
* $--GGA,hhmmss.ss,ddmm.mm,a,ddmm.mm,a,x,xx,x.x,x.x,M,x.x,M,x.x,xxxx*hh<CR><LF>
|
||||
*
|
||||
* Field Number:
|
||||
* 1 UTC of this position report, hh is hours, mm is minutes, ss.ss is seconds.
|
||||
* 2 Latitude
|
||||
* 3 N or S (North or South)
|
||||
* 4 Longitude
|
||||
* 5 E or W (East or West)
|
||||
* 6 GPS Quality Indicator (non null)
|
||||
* 7 Number of satellites in use, 00 - 12
|
||||
* 8 Horizontal Dilution of precision (meters)
|
||||
* 9 Antenna Altitude above/below mean-sea-level (geoid) (in meters)
|
||||
* 10 Units of antenna altitude, meters
|
||||
* 11 Geoidal separation, the difference between the WGS-84 earth ellipsoid and mean-sea-level (geoid), "-" means mean-sea-level below ellipsoid
|
||||
* 12 Units of geoidal separation, meters
|
||||
* 13 Age of differential GPS data, time in seconds since last SC104 type 1 or 9 update, null field when DGPS is not used
|
||||
* 14 Differential reference station ID, 0000-1023
|
||||
* 15 Checksum
|
||||
* -------------------------------------------
|
||||
*/
|
||||
|
||||
uint printGGA(char *buf, const Position &pos)
|
||||
{
|
||||
uint len = sprintf(buf, "$GNGGA,%06u.%03u,%07.2f,%c,%08.2f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d",
|
||||
pos.time / 1000,
|
||||
pos.time % 1000,
|
||||
pos.latitude_i * 1e-5, pos.latitude_i < 0 ? 'S' : 'N',
|
||||
pos.longitude_i * 1e-5, pos.longitude_i < 0 ? 'W' : 'E',
|
||||
pos.fix_type,
|
||||
pos.sats_in_view,
|
||||
pos.HDOP,
|
||||
pos.altitude,
|
||||
'M',
|
||||
pos.altitude_geoidal_separation,
|
||||
'M',
|
||||
0,
|
||||
0);
|
||||
|
||||
uint chk = 0;
|
||||
for (uint i = 1; i < len; i++) {
|
||||
chk ^= buf[i];
|
||||
}
|
||||
len += sprintf(buf + len, "*%02X\r\n", chk);
|
||||
return len;
|
||||
}
|
||||
7
src/gps/NMEAWPL.h
Normal file
7
src/gps/NMEAWPL.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "main.h"
|
||||
|
||||
uint printWPL(char *buf, const Position &pos, const char *name);
|
||||
uint printGGA(char *buf, const Position &pos);
|
||||
@@ -16,7 +16,7 @@ enum RTCQuality {
|
||||
RTCQualityFromNet = 2,
|
||||
|
||||
/// Our time is based on NTP
|
||||
RTCQualityNTP= 3,
|
||||
RTCQualityNTP = 3,
|
||||
|
||||
/// Our time is based on our own GPS
|
||||
RTCQualityGPS = 4
|
||||
|
||||
@@ -84,10 +84,6 @@ static char ourId[5];
|
||||
// GeoCoord object for the screen
|
||||
GeoCoord geoCoord;
|
||||
|
||||
// OEM Config File
|
||||
static const char *oemConfigFile = "/oem/oem.proto";
|
||||
OEMStore oemStore;
|
||||
|
||||
#ifdef SHOW_REDRAWS
|
||||
static bool heartbeat = false;
|
||||
#endif
|
||||
@@ -928,9 +924,6 @@ void Screen::setup()
|
||||
dispdev.setDetected(screen_model);
|
||||
#endif
|
||||
|
||||
// Load OEM config from Proto file if existent
|
||||
loadProto(oemConfigFile, OEMStore_size, sizeof(oemConfigFile), OEMStore_fields, &oemStore);
|
||||
|
||||
// Initialising the UI will init the display too.
|
||||
ui.init();
|
||||
|
||||
@@ -1397,7 +1390,6 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
|
||||
{
|
||||
#if HAS_WIFI
|
||||
const char *wifiName = config.network.wifi_ssid;
|
||||
const char *wifiPsw = config.network.wifi_psk;
|
||||
|
||||
displayedNodeNum = 0; // Not currently showing a node pane
|
||||
|
||||
@@ -1406,11 +1398,7 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
|
||||
// The coordinates define the left starting point of the text
|
||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
|
||||
if (isSoftAPForced()) {
|
||||
display->drawString(x, y, String("WiFi: Software AP (Admin)"));
|
||||
} else if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT || config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN) {
|
||||
display->drawString(x, y, String("WiFi: Software AP"));
|
||||
} else if (WiFi.status() != WL_CONNECTED) {
|
||||
if (WiFi.status() != WL_CONNECTED) {
|
||||
display->drawString(x, y, String("WiFi: Not Connected"));
|
||||
} else {
|
||||
display->drawString(x, y, String("WiFi: Connected"));
|
||||
@@ -1431,25 +1419,14 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
|
||||
- WL_NO_SHIELD: assigned when no WiFi shield is present;
|
||||
|
||||
*/
|
||||
if (WiFi.status() == WL_CONNECTED || isSoftAPForced() || config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT || config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN) {
|
||||
if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT || config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN || isSoftAPForced()) {
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "IP: " + String(WiFi.softAPIP().toString().c_str()));
|
||||
|
||||
// Number of connections to the AP. Default max for the esp32 is 4
|
||||
display->drawString(x + SCREEN_WIDTH - display->getStringWidth("(" + String(WiFi.softAPgetStationNum()) + "/4)"),
|
||||
y + FONT_HEIGHT_SMALL * 1, "(" + String(WiFi.softAPgetStationNum()) + "/4)");
|
||||
} else {
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "IP: " + String(WiFi.localIP().toString().c_str()));
|
||||
}
|
||||
|
||||
if (WiFi.status() == WL_CONNECTED) {
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "IP: " + String(WiFi.localIP().toString().c_str()));
|
||||
} else if (WiFi.status() == WL_NO_SSID_AVAIL) {
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "SSID Not Found");
|
||||
} else if (WiFi.status() == WL_CONNECTION_LOST) {
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Connection Lost");
|
||||
} else if (WiFi.status() == WL_CONNECT_FAILED) {
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Connection Failed");
|
||||
//} else if (WiFi.status() == WL_DISCONNECTED) {
|
||||
// display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Disconnected");
|
||||
} else if (WiFi.status() == WL_IDLE_STATUS) {
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Idle ... Reconnecting");
|
||||
} else {
|
||||
@@ -1516,24 +1493,8 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
|
||||
}
|
||||
}
|
||||
|
||||
if (isSoftAPForced()) {
|
||||
if ((millis() / 10000) % 2) {
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "SSID: meshtasticAdmin");
|
||||
} else {
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "PWD: 12345678");
|
||||
}
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "SSID: " + String(wifiName));
|
||||
|
||||
} else {
|
||||
if (config.network.wifi_mode== Config_NetworkConfig_WiFiMode_ACCESS_POINT || config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN) {
|
||||
if ((millis() / 10000) % 2) {
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "SSID: " + String(wifiName));
|
||||
} else {
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "PWD: " + String(wifiPsw));
|
||||
}
|
||||
} else {
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "SSID: " + String(wifiName));
|
||||
}
|
||||
}
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 3, "http://meshtastic.local");
|
||||
|
||||
/* Display a heartbeat pixel that blinks every time the frame is redrawn */
|
||||
|
||||
61
src/main.cpp
61
src/main.cpp
@@ -30,6 +30,7 @@
|
||||
// #include <driver/rtc_io.h>
|
||||
|
||||
#include "mesh/http/WiFiAPClient.h"
|
||||
#include "mesh/eth/ethClient.h"
|
||||
|
||||
#ifdef ARCH_ESP32
|
||||
#include "mesh/http/WebServer.h"
|
||||
@@ -41,10 +42,16 @@
|
||||
#include "mqtt/MQTT.h"
|
||||
#endif
|
||||
|
||||
#if HAS_ETHERNET
|
||||
#include "mesh/eth/ethServerAPI.h"
|
||||
#include "mqtt/MQTT.h"
|
||||
#endif
|
||||
|
||||
#include "LLCC68Interface.h"
|
||||
#include "RF95Interface.h"
|
||||
#include "SX1262Interface.h"
|
||||
#include "SX1268Interface.h"
|
||||
#include "SX1281Interface.h"
|
||||
#if !HAS_RADIO && defined(ARCH_PORTDUINO)
|
||||
#include "platform/portduino/SimRadio.h"
|
||||
#endif
|
||||
@@ -80,6 +87,14 @@ uint8_t kb_model;
|
||||
// The I2C address of the RTC Module (if found)
|
||||
uint8_t rtc_found;
|
||||
|
||||
bool rIf_wide_lora = false;
|
||||
|
||||
// Keystore Chips
|
||||
uint8_t keystore_found;
|
||||
#ifndef ARCH_PORTDUINO
|
||||
ATECCX08A atecc;
|
||||
#endif
|
||||
|
||||
bool eink_found = true;
|
||||
|
||||
uint32_t serialSinceMsec;
|
||||
@@ -182,8 +197,6 @@ void setup()
|
||||
digitalWrite(RESET_OLED, 1);
|
||||
#endif
|
||||
|
||||
bool forceSoftAP = 0;
|
||||
|
||||
#ifdef BUTTON_PIN
|
||||
#ifdef ARCH_ESP32
|
||||
|
||||
@@ -196,12 +209,6 @@ void setup()
|
||||
delay(10);
|
||||
#endif
|
||||
|
||||
// BUTTON_PIN is pulled high by a 12k resistor.
|
||||
if (!digitalRead(BUTTON_PIN)) {
|
||||
forceSoftAP = 1;
|
||||
DEBUG_MSG("Setting forceSoftAP = 1\n");
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -233,6 +240,12 @@ void setup()
|
||||
delay(1);
|
||||
#endif
|
||||
|
||||
#ifdef RAK4630
|
||||
// We need to enable 3.3V periphery in order to scan it
|
||||
pinMode(PIN_3V3_EN, OUTPUT);
|
||||
digitalWrite(PIN_3V3_EN, 1);
|
||||
#endif
|
||||
|
||||
// We need to scan here to decide if we have a screen for nodeDB.init()
|
||||
scanI2Cdevice();
|
||||
#ifdef RAK4630
|
||||
@@ -263,11 +276,12 @@ void setup()
|
||||
#ifdef ARCH_NRF52
|
||||
nrf52Setup();
|
||||
#endif
|
||||
playStartMelody();
|
||||
// We do this as early as possible because this loads preferences from flash
|
||||
// but we need to do this after main cpu iniot (esp32setup), because we need the random seed set
|
||||
nodeDB.init();
|
||||
|
||||
playStartMelody();
|
||||
|
||||
// Currently only the tbeam has a PMU
|
||||
power = new Power();
|
||||
power->setStatusHandler(powerStatus);
|
||||
@@ -275,12 +289,10 @@ void setup()
|
||||
power->setup(); // Must be after status handler is installed, so that handler gets notified of the initial configuration
|
||||
|
||||
/*
|
||||
* Repeat the scanning for I2C devices after power initialization.
|
||||
* Repeat the scanning for I2C devices after power initialization or look for 'latecomers'.
|
||||
* Boards with an PMU need to be powered on to correctly scan to the device address, such as t-beam-s3-core
|
||||
*/
|
||||
if ((HW_VENDOR == HardwareModel_LILYGO_TBEAM_S3_CORE) || (HW_VENDOR == HardwareModel_TBEAM)) {
|
||||
scanI2Cdevice();
|
||||
}
|
||||
scanI2Cdevice();
|
||||
|
||||
// Init our SPI controller (must be before screen and lora)
|
||||
initSPI();
|
||||
@@ -360,6 +372,20 @@ void setup()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USE_SX1281) && !defined(ARCH_PORTDUINO)
|
||||
if (!rIf) {
|
||||
rIf = new SX1281Interface(SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY, SPI);
|
||||
if (!rIf->init()) {
|
||||
DEBUG_MSG("Warning: Failed to find SX1281 radio\n");
|
||||
delete rIf;
|
||||
rIf = NULL;
|
||||
} else {
|
||||
DEBUG_MSG("SX1281 Radio init succeeded, using SX1281 radio\n");
|
||||
rIf_wide_lora = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USE_SX1262)
|
||||
if (!rIf) {
|
||||
rIf = new SX1262Interface(SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY, SPI);
|
||||
@@ -412,12 +438,17 @@ void setup()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_WIFI
|
||||
#if HAS_WIFI || HAS_ETHERNET
|
||||
mqttInit();
|
||||
#endif
|
||||
|
||||
#ifndef ARCH_PORTDUINO
|
||||
// Initialize Wifi
|
||||
initWifi(forceSoftAP);
|
||||
initWifi();
|
||||
|
||||
// Initialize Ethernet
|
||||
initEthernet();
|
||||
#endif
|
||||
|
||||
#ifdef ARCH_ESP32
|
||||
// Start web server thread.
|
||||
|
||||
@@ -6,18 +6,27 @@
|
||||
#include "PowerStatus.h"
|
||||
#include "graphics/Screen.h"
|
||||
#include "mesh/generated/telemetry.pb.h"
|
||||
#ifndef ARCH_PORTDUINO
|
||||
#include <SparkFun_ATECCX08a_Arduino_Library.h>
|
||||
#endif
|
||||
|
||||
extern uint8_t screen_found;
|
||||
extern uint8_t screen_model;
|
||||
extern uint8_t cardkb_found;
|
||||
extern uint8_t kb_model;
|
||||
extern uint8_t rtc_found;
|
||||
extern uint8_t keystore_found;
|
||||
|
||||
extern bool rIf_wide_lora;
|
||||
extern bool eink_found;
|
||||
extern bool pmu_found;
|
||||
extern bool isCharging;
|
||||
extern bool isUSBPowered;
|
||||
|
||||
#ifndef ARCH_PORTDUINO
|
||||
extern ATECCX08A atecc;
|
||||
#endif
|
||||
|
||||
extern uint8_t nodeTelemetrySensorsMap[TelemetrySensorType_QMI8658+1];
|
||||
|
||||
extern int TCPPort; // set by Portduino
|
||||
|
||||
@@ -62,13 +62,6 @@ Channel &Channels::fixupChannel(ChannelIndex chIndex)
|
||||
// Convert the old string "Default" to our new short representation
|
||||
if (strcmp(channelSettings.name, "Default") == 0)
|
||||
*channelSettings.name = '\0';
|
||||
|
||||
/* Convert any old usage of the defaultpsk into our new short representation.
|
||||
if (channelSettings.psk.size == sizeof(defaultpsk) &&
|
||||
memcmp(channelSettings.psk.bytes, defaultpsk, sizeof(defaultpsk)) == 0) {
|
||||
*channelSettings.psk.bytes = 1;
|
||||
channelSettings.psk.size = 1;
|
||||
} */
|
||||
}
|
||||
|
||||
hashes[chIndex] = generateHash(chIndex);
|
||||
@@ -86,7 +79,7 @@ void Channels::initDefaultChannel(ChannelIndex chIndex)
|
||||
Config_LoRaConfig &loraConfig = config.lora;
|
||||
|
||||
loraConfig.modem_preset = Config_LoRaConfig_ModemPreset_LONG_FAST; // Default to Long Range & Fast
|
||||
|
||||
loraConfig.use_preset = true;
|
||||
loraConfig.tx_power = 0; // default
|
||||
uint8_t defaultpskIndex = 1;
|
||||
channelSettings.psk.bytes[0] = defaultpskIndex;
|
||||
@@ -124,7 +117,22 @@ CryptoKey Channels::getKey(ChannelIndex chIndex)
|
||||
DEBUG_MSG("Expanding short PSK #%d\n", pskIndex);
|
||||
if (pskIndex == 0)
|
||||
k.length = 0; // Turn off encryption
|
||||
else {
|
||||
else if (oemStore.oem_aes_key.size > 1) {
|
||||
// Use the OEM key
|
||||
DEBUG_MSG("Using OEM Key with %d bytes\n", oemStore.oem_aes_key.size);
|
||||
memcpy(k.bytes, oemStore.oem_aes_key.bytes , oemStore.oem_aes_key.size);
|
||||
k.length = oemStore.oem_aes_key.size;
|
||||
// Bump up the last byte of PSK as needed
|
||||
uint8_t *last = k.bytes + oemStore.oem_aes_key.size - 1;
|
||||
*last = *last + pskIndex - 1; // index of 1 means no change vs defaultPSK
|
||||
if (k.length < 16) {
|
||||
DEBUG_MSG("Warning: OEM provided a too short AES128 key - padding\n");
|
||||
k.length = 16;
|
||||
} else if (k.length < 32 && k.length != 16) {
|
||||
DEBUG_MSG("Warning: OEM provided a too short AES256 key - padding\n");
|
||||
k.length = 32;
|
||||
}
|
||||
} else {
|
||||
memcpy(k.bytes, defaultpsk, sizeof(defaultpsk));
|
||||
k.length = sizeof(defaultpsk);
|
||||
// Bump up the last byte of PSK as needed
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
#include "SX126xInterface.h"
|
||||
#include "SX126xInterface.cpp"
|
||||
#include "SX128xInterface.h"
|
||||
#include "SX128xInterface.cpp"
|
||||
|
||||
// We need this declaration for proper linking in derived classes
|
||||
template class SX126xInterface<SX1262>;
|
||||
template class SX126xInterface<SX1268>;
|
||||
template class SX126xInterface<LLCC68>;
|
||||
template class SX126xInterface<LLCC68>;
|
||||
|
||||
#if !defined(ARCH_PORTDUINO)
|
||||
template class SX128xInterface<SX1281>;
|
||||
#endif
|
||||
@@ -15,6 +15,7 @@ struct RegionInfo {
|
||||
uint8_t powerLimit; // Or zero for not set
|
||||
bool audioPermitted;
|
||||
bool freqSwitching;
|
||||
bool wideLora;
|
||||
const char *name; // EU433 etc
|
||||
};
|
||||
|
||||
|
||||
@@ -283,3 +283,8 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool MeshService::isToPhoneQueueEmpty()
|
||||
{
|
||||
return toPhoneQueue.isEmpty();
|
||||
}
|
||||
@@ -89,6 +89,8 @@ class MeshService
|
||||
/// Send a packet to the phone
|
||||
void sendToPhone(MeshPacket *p);
|
||||
|
||||
bool isToPhoneQueueEmpty();
|
||||
|
||||
private:
|
||||
/// Called when our gps position has changed - updates nodedb and sends Location message out into the mesh
|
||||
/// returns 0 to allow futher processing
|
||||
|
||||
@@ -38,6 +38,7 @@ MyNodeInfo &myNodeInfo = devicestate.my_node;
|
||||
LocalConfig config;
|
||||
LocalModuleConfig moduleConfig;
|
||||
ChannelFile channelFile;
|
||||
OEMStore oemStore;
|
||||
|
||||
/** The current change # for radio settings. Starts at 0 on boot and any time the radio settings
|
||||
* might have changed is incremented. Allows others to detect they might now be on a new channel.
|
||||
@@ -129,6 +130,8 @@ bool NodeDB::factoryReset()
|
||||
// second, install default state (this will deal with the duplicate mac address issue)
|
||||
installDefaultDeviceState();
|
||||
installDefaultConfig();
|
||||
installDefaultModuleConfig();
|
||||
installDefaultChannels();
|
||||
// third, write everything to disk
|
||||
saveToDisk();
|
||||
#ifdef ARCH_ESP32
|
||||
@@ -354,6 +357,8 @@ static const char *prefFileName = "/prefs/db.proto";
|
||||
static const char *configFileName = "/prefs/config.proto";
|
||||
static const char *moduleConfigFileName = "/prefs/module.proto";
|
||||
static const char *channelFileName = "/prefs/channels.proto";
|
||||
static const char *oemConfigFile = "/oem/oem.proto";
|
||||
|
||||
|
||||
/** Load a protobuf from a file, return true for success */
|
||||
bool loadProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, void *dest_struct)
|
||||
@@ -433,6 +438,9 @@ void NodeDB::loadFromDisk()
|
||||
DEBUG_MSG("Loaded saved channelFile version %d\n", channelFile.version);
|
||||
}
|
||||
}
|
||||
|
||||
if (loadProto(oemConfigFile, OEMStore_size, sizeof(OEMStore), OEMStore_fields, &oemStore))
|
||||
DEBUG_MSG("Loaded OEMStore\n");
|
||||
}
|
||||
|
||||
/** Save a protobuf from a file, return true for success */
|
||||
|
||||
@@ -18,7 +18,7 @@ DeviceState versions used to be defined in the .proto file but really only this
|
||||
#define SEGMENT_DEVICESTATE 4
|
||||
#define SEGMENT_CHANNELS 8
|
||||
|
||||
#define DEVICESTATE_CUR_VER 19
|
||||
#define DEVICESTATE_CUR_VER 20
|
||||
#define DEVICESTATE_MIN_VER DEVICESTATE_CUR_VER
|
||||
|
||||
extern DeviceState devicestate;
|
||||
@@ -26,6 +26,7 @@ extern ChannelFile channelFile;
|
||||
extern MyNodeInfo &myNodeInfo;
|
||||
extern LocalConfig config;
|
||||
extern LocalModuleConfig moduleConfig;
|
||||
extern OEMStore oemStore;
|
||||
extern User &owner;
|
||||
|
||||
/// Given a node, return how many seconds in the past (vs now) that we last heard from it
|
||||
|
||||
@@ -6,15 +6,16 @@
|
||||
#include "Router.h"
|
||||
#include "assert.h"
|
||||
#include "configuration.h"
|
||||
#include "main.h"
|
||||
#include "sleep.h"
|
||||
#include <assert.h>
|
||||
#include <pb_decode.h>
|
||||
#include <pb_encode.h>
|
||||
|
||||
#define RDEF(name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, frequency_switching) \
|
||||
#define RDEF(name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, frequency_switching, wide_lora) \
|
||||
{ \
|
||||
Config_LoRaConfig_RegionCode_##name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, \
|
||||
frequency_switching, #name \
|
||||
frequency_switching, wide_lora, #name \
|
||||
}
|
||||
|
||||
const RegionInfo regions[] = {
|
||||
@@ -22,12 +23,12 @@ const RegionInfo regions[] = {
|
||||
https://link.springer.com/content/pdf/bbm%3A978-1-4842-4357-2%2F1.pdf
|
||||
https://www.thethingsnetwork.org/docs/lorawan/regional-parameters/
|
||||
*/
|
||||
RDEF(US, 902.0f, 928.0f, 100, 0, 30, true, false),
|
||||
RDEF(US, 902.0f, 928.0f, 100, 0, 30, true, false, false),
|
||||
|
||||
/*
|
||||
https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
|
||||
*/
|
||||
RDEF(EU_433, 433.0f, 434.0f, 10, 0, 12, true, false),
|
||||
RDEF(EU_433, 433.0f, 434.0f, 10, 0, 12, true, false, false),
|
||||
|
||||
/*
|
||||
https://www.thethingsnetwork.org/docs/lorawan/duty-cycle/
|
||||
@@ -43,23 +44,23 @@ const RegionInfo regions[] = {
|
||||
(Please refer to section 4.21 in the following document)
|
||||
https://ec.europa.eu/growth/tools-databases/tris/index.cfm/ro/search/?trisaction=search.detail&year=2021&num=528&dLang=EN
|
||||
*/
|
||||
RDEF(EU_868, 869.4f, 869.65f, 10, 0, 27, false, false),
|
||||
RDEF(EU_868, 869.4f, 869.65f, 10, 0, 27, false, false, false),
|
||||
|
||||
/*
|
||||
https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
|
||||
*/
|
||||
RDEF(CN, 470.0f, 510.0f, 100, 0, 19, true, false),
|
||||
RDEF(CN, 470.0f, 510.0f, 100, 0, 19, true, false, false),
|
||||
|
||||
/*
|
||||
https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
|
||||
*/
|
||||
RDEF(JP, 920.8f, 927.8f, 100, 0, 16, true, false),
|
||||
RDEF(JP, 920.8f, 927.8f, 100, 0, 16, true, false, false),
|
||||
|
||||
/*
|
||||
https://www.iot.org.au/wp/wp-content/uploads/2016/12/IoTSpectrumFactSheet.pdf
|
||||
https://iotalliance.org.nz/wp-content/uploads/sites/4/2019/05/IoT-Spectrum-in-NZ-Briefing-Paper.pdf
|
||||
*/
|
||||
RDEF(ANZ, 915.0f, 928.0f, 100, 0, 30, true, false),
|
||||
RDEF(ANZ, 915.0f, 928.0f, 100, 0, 30, true, false, false),
|
||||
|
||||
/*
|
||||
https://digital.gov.ru/uploaded/files/prilozhenie-12-k-reshenyu-gkrch-18-46-03-1.pdf
|
||||
@@ -67,38 +68,44 @@ const RegionInfo regions[] = {
|
||||
Note:
|
||||
- We do LBT, so 100% is allowed.
|
||||
*/
|
||||
RDEF(RU, 868.7f, 869.2f, 100, 0, 20, true, false),
|
||||
RDEF(RU, 868.7f, 869.2f, 100, 0, 20, true, false, false),
|
||||
|
||||
/*
|
||||
???
|
||||
*/
|
||||
RDEF(KR, 920.0f, 923.0f, 100, 0, 0, true, false),
|
||||
RDEF(KR, 920.0f, 923.0f, 100, 0, 0, true, false, false),
|
||||
|
||||
/*
|
||||
???
|
||||
*/
|
||||
RDEF(TW, 920.0f, 925.0f, 100, 0, 0, true, false),
|
||||
RDEF(TW, 920.0f, 925.0f, 100, 0, 0, true, false, false),
|
||||
|
||||
/*
|
||||
https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
|
||||
*/
|
||||
RDEF(IN, 865.0f, 867.0f, 100, 0, 30, true, false),
|
||||
RDEF(IN, 865.0f, 867.0f, 100, 0, 30, true, false, false),
|
||||
|
||||
/*
|
||||
https://rrf.rsm.govt.nz/smart-web/smart/page/-smart/domain/licence/LicenceSummary.wdk?id=219752
|
||||
https://iotalliance.org.nz/wp-content/uploads/sites/4/2019/05/IoT-Spectrum-in-NZ-Briefing-Paper.pdf
|
||||
*/
|
||||
RDEF(NZ_865, 864.0f, 868.0f, 100, 0, 0, true, false),
|
||||
RDEF(NZ_865, 864.0f, 868.0f, 100, 0, 0, true, false, false),
|
||||
|
||||
/*
|
||||
https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
|
||||
*/
|
||||
RDEF(TH, 920.0f, 925.0f, 100, 0, 16, true, false),
|
||||
RDEF(TH, 920.0f, 925.0f, 100, 0, 16, true, false, false),
|
||||
|
||||
/*
|
||||
2.4 GHZ WLAN Band equivalent. Only for SX128x chips.
|
||||
*/
|
||||
|
||||
RDEF(LORA_24, 2400.0f, 2483.5f, 100, 0, 10, true, false, true),
|
||||
|
||||
/*
|
||||
This needs to be last. Same as US.
|
||||
*/
|
||||
RDEF(UNSET, 902.0f, 928.0f, 100, 0, 30, true, false)
|
||||
RDEF(UNSET, 902.0f, 928.0f, 100, 0, 30, true, false, false)
|
||||
|
||||
};
|
||||
|
||||
@@ -354,40 +361,41 @@ void RadioInterface::applyModemConfig()
|
||||
// Set up default configuration
|
||||
// No Sync Words in LORA mode
|
||||
Config_LoRaConfig &loraConfig = config.lora;
|
||||
if (loraConfig.spread_factor == 0) {
|
||||
if (loraConfig.use_preset) {
|
||||
|
||||
switch (loraConfig.modem_preset) {
|
||||
case Config_LoRaConfig_ModemPreset_SHORT_FAST:
|
||||
bw = 250;
|
||||
bw = (myRegion->wideLora && rIf_wide_lora) ? 800 : 250;
|
||||
cr = 8;
|
||||
sf = 7;
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_SHORT_SLOW:
|
||||
bw = 250;
|
||||
bw = (myRegion->wideLora && rIf_wide_lora) ? 800 : 250;
|
||||
cr = 8;
|
||||
sf = 8;
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_MEDIUM_FAST:
|
||||
bw = 250;
|
||||
bw = (myRegion->wideLora && rIf_wide_lora) ? 800 : 250;
|
||||
cr = 8;
|
||||
sf = 9;
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_MEDIUM_SLOW:
|
||||
bw = 250;
|
||||
bw = (myRegion->wideLora && rIf_wide_lora) ? 800 : 250;
|
||||
cr = 8;
|
||||
sf = 10;
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_LONG_FAST:
|
||||
bw = 250;
|
||||
bw = (myRegion->wideLora && rIf_wide_lora) ? 800 : 250;
|
||||
cr = 8;
|
||||
sf = 11;
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_LONG_SLOW:
|
||||
bw = 125;
|
||||
bw = (myRegion->wideLora && rIf_wide_lora) ? 400 : 125;
|
||||
cr = 8;
|
||||
sf = 12;
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW:
|
||||
bw = 31.25;
|
||||
bw = (myRegion->wideLora && rIf_wide_lora) ? 200 : 31.25;
|
||||
cr = 8;
|
||||
sf = 12;
|
||||
break;
|
||||
@@ -415,7 +423,7 @@ void RadioInterface::applyModemConfig()
|
||||
power = 17; // Default to default power if we don't have a valid power
|
||||
|
||||
// Set final tx_power back onto config
|
||||
loraConfig.tx_power = power;
|
||||
loraConfig.tx_power = (int8_t)power; // cppcheck-suppress assignmentAddressToInteger
|
||||
|
||||
// Calculate the number of channels
|
||||
uint32_t numChannels = floor((myRegion->freqEnd - myRegion->freqStart) / (myRegion->spacing + (bw / 1000)));
|
||||
|
||||
@@ -63,7 +63,7 @@ bool ReliableRouter::shouldFilterReceived(MeshPacket *p)
|
||||
sendAckNak(Routing_Error_NONE, getFrom(p), p->id, p->channel);
|
||||
DEBUG_MSG("acking a repeated want_ack packet\n");
|
||||
}
|
||||
} else if (wasSeenRecently(p, false) && p->hop_limit == HOP_RELIABLE && !MeshModule::currentReply) {
|
||||
} else if (wasSeenRecently(p, false) && p->hop_limit == HOP_RELIABLE && !MeshModule::currentReply && p->to != nodeDB.getNodeNum()) {
|
||||
// retransmission on broadcast has hop_limit still equal to HOP_RELIABLE
|
||||
DEBUG_MSG("Resending implicit ack for a repeated floodmsg\n");
|
||||
MeshPacket *tosend = packetPool.allocCopy(*p);
|
||||
|
||||
13
src/mesh/SX1281Interface.cpp
Normal file
13
src/mesh/SX1281Interface.cpp
Normal file
@@ -0,0 +1,13 @@
|
||||
#include "configuration.h"
|
||||
#include "SX1281Interface.h"
|
||||
#include "error.h"
|
||||
|
||||
#if !defined(ARCH_PORTDUINO)
|
||||
|
||||
SX1281Interface::SX1281Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
|
||||
SPIClass &spi)
|
||||
: SX128xInterface(cs, irq, rst, busy, spi)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
17
src/mesh/SX1281Interface.h
Normal file
17
src/mesh/SX1281Interface.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "SX128xInterface.h"
|
||||
|
||||
/**
|
||||
* Our adapter for SX1281 radios
|
||||
*/
|
||||
|
||||
#if !defined(ARCH_PORTDUINO)
|
||||
|
||||
class SX1281Interface : public SX128xInterface<SX1281>
|
||||
{
|
||||
public:
|
||||
SX1281Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi);
|
||||
};
|
||||
|
||||
#endif
|
||||
247
src/mesh/SX128xInterface.cpp
Normal file
247
src/mesh/SX128xInterface.cpp
Normal file
@@ -0,0 +1,247 @@
|
||||
#include "configuration.h"
|
||||
#include "SX128xInterface.h"
|
||||
#include "error.h"
|
||||
|
||||
#if !defined(ARCH_PORTDUINO)
|
||||
|
||||
// Particular boards might define a different max power based on what their hardware can do
|
||||
#ifndef SX128X_MAX_POWER
|
||||
#define SX128X_MAX_POWER 22
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
SX128xInterface<T>::SX128xInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
|
||||
SPIClass &spi)
|
||||
: RadioLibInterface(cs, irq, rst, busy, spi, &lora), lora(&module)
|
||||
{
|
||||
}
|
||||
|
||||
/// Initialise the Driver transport hardware and software.
|
||||
/// Make sure the Driver is properly configured before calling init().
|
||||
/// \return true if initialisation succeeded.
|
||||
template<typename T>
|
||||
bool SX128xInterface<T>::init()
|
||||
{
|
||||
#ifdef SX128X_POWER_EN
|
||||
digitalWrite(SX128X_POWER_EN, HIGH);
|
||||
pinMode(SX128X_POWER_EN, OUTPUT);
|
||||
#endif
|
||||
|
||||
#ifdef SX128X_RXEN // set not rx or tx mode
|
||||
digitalWrite(SX128X_RXEN, LOW); // Set low before becoming an output
|
||||
pinMode(SX128X_RXEN, OUTPUT);
|
||||
#endif
|
||||
#ifdef SX128X_TXEN
|
||||
digitalWrite(SX128X_TXEN, LOW);
|
||||
pinMode(SX128X_TXEN, OUTPUT);
|
||||
#endif
|
||||
|
||||
RadioLibInterface::init();
|
||||
|
||||
if (power == 0)
|
||||
power = SX128X_MAX_POWER;
|
||||
|
||||
if (power > SX128X_MAX_POWER) // This chip has lower power limits than some
|
||||
power = SX128X_MAX_POWER;
|
||||
|
||||
limitPower();
|
||||
|
||||
int res = lora.begin(getFreq(), bw, sf, cr, syncWord, power, preambleLength);
|
||||
// \todo Display actual typename of the adapter, not just `SX128x`
|
||||
DEBUG_MSG("SX128x init result %d\n", res);
|
||||
|
||||
DEBUG_MSG("Frequency set to %f\n", getFreq());
|
||||
DEBUG_MSG("Bandwidth set to %f\n", bw);
|
||||
DEBUG_MSG("Power output set to %d\n", power);
|
||||
|
||||
#ifdef SX128X_TXEN
|
||||
// lora.begin sets Dio2 as RF switch control, which is not true if we are manually controlling RX and TX
|
||||
if (res == RADIOLIB_ERR_NONE)
|
||||
res = lora.setDio2AsRfSwitch(true);
|
||||
#endif
|
||||
|
||||
if (res == RADIOLIB_ERR_NONE)
|
||||
res = lora.setCRC(RADIOLIB_SX128X_LORA_CRC_ON);
|
||||
|
||||
if (res == RADIOLIB_ERR_NONE)
|
||||
startReceive(); // start receiving
|
||||
|
||||
return res == RADIOLIB_ERR_NONE;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool SX128xInterface<T>::reconfigure()
|
||||
{
|
||||
RadioLibInterface::reconfigure();
|
||||
|
||||
// set mode to standby
|
||||
setStandby();
|
||||
|
||||
// configure publicly accessible settings
|
||||
int err = lora.setSpreadingFactor(sf);
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING);
|
||||
|
||||
err = lora.setBandwidth(bw);
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING);
|
||||
|
||||
err = lora.setCodingRate(cr);
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING);
|
||||
|
||||
// Hmm - seems to lower SNR when the signal levels are high. Leaving off for now...
|
||||
// TODO: Confirm gain registers are okay now
|
||||
// err = lora.setRxGain(true);
|
||||
// assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
err = lora.setSyncWord(syncWord);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
err = lora.setPreambleLength(preambleLength);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
err = lora.setFrequency(getFreq());
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING);
|
||||
|
||||
if (power > 22) // This chip has lower power limits than some
|
||||
power = 22;
|
||||
err = lora.setOutputPower(power);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
startReceive(); // restart receiving
|
||||
|
||||
return RADIOLIB_ERR_NONE;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void INTERRUPT_ATTR SX128xInterface<T>::disableInterrupt()
|
||||
{
|
||||
lora.clearDio1Action();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void SX128xInterface<T>::setStandby()
|
||||
{
|
||||
checkNotification(); // handle any pending interrupts before we force standby
|
||||
|
||||
int err = lora.standby();
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
#ifdef SX128X_RXEN // we have RXEN/TXEN control - turn off RX and TX power
|
||||
digitalWrite(SX128X_RXEN, LOW);
|
||||
#endif
|
||||
#ifdef SX128X_TXEN
|
||||
digitalWrite(SX128X_TXEN, LOW);
|
||||
#endif
|
||||
|
||||
isReceiving = false; // If we were receiving, not any more
|
||||
disableInterrupt();
|
||||
completeSending(); // If we were sending, not anymore
|
||||
}
|
||||
|
||||
/**
|
||||
* Add SNR data to received messages
|
||||
*/
|
||||
template<typename T>
|
||||
void SX128xInterface<T>::addReceiveMetadata(MeshPacket *mp)
|
||||
{
|
||||
// DEBUG_MSG("PacketStatus %x\n", lora.getPacketStatus());
|
||||
mp->rx_snr = lora.getSNR();
|
||||
mp->rx_rssi = lround(lora.getRSSI());
|
||||
}
|
||||
|
||||
/** We override to turn on transmitter power as needed.
|
||||
*/
|
||||
template<typename T>
|
||||
void SX128xInterface<T>::configHardwareForSend()
|
||||
{
|
||||
#ifdef SX128X_TXEN // we have RXEN/TXEN control - turn on TX power / off RX power
|
||||
digitalWrite(SX128X_TXEN, HIGH);
|
||||
#endif
|
||||
#ifdef SX128X_RXEN
|
||||
digitalWrite(SX128X_RXEN, LOW);
|
||||
#endif
|
||||
|
||||
RadioLibInterface::configHardwareForSend();
|
||||
}
|
||||
|
||||
// For power draw measurements, helpful to force radio to stay sleeping
|
||||
// #define SLEEP_ONLY
|
||||
|
||||
template<typename T>
|
||||
void SX128xInterface<T>::startReceive()
|
||||
{
|
||||
#ifdef SLEEP_ONLY
|
||||
sleep();
|
||||
#else
|
||||
|
||||
setStandby();
|
||||
|
||||
#ifdef SX128X_RXEN // we have RXEN/TXEN control - turn on RX power / off TX power
|
||||
digitalWrite(SX128X_RXEN, HIGH);
|
||||
#endif
|
||||
#ifdef SX128X_TXEN
|
||||
digitalWrite(SX128X_TXEN, LOW);
|
||||
#endif
|
||||
|
||||
int err = lora.startReceive();
|
||||
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
isReceiving = true;
|
||||
|
||||
// Must be done AFTER, starting transmit, because startTransmit clears (possibly stale) interrupt pending register bits
|
||||
enableInterrupt(isrRxLevel0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Could we send right now (i.e. either not actively receving or transmitting)? */
|
||||
template<typename T>
|
||||
bool SX128xInterface<T>::isChannelActive()
|
||||
{
|
||||
// check if we can detect a LoRa preamble on the current channel
|
||||
int16_t result;
|
||||
|
||||
setStandby();
|
||||
result = lora.scanChannel();
|
||||
if (result == RADIOLIB_PREAMBLE_DETECTED)
|
||||
return true;
|
||||
|
||||
assert(result != RADIOLIB_ERR_WRONG_MODEM);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Could we send right now (i.e. either not actively receving or transmitting)? */
|
||||
template<typename T>
|
||||
bool SX128xInterface<T>::isActivelyReceiving()
|
||||
{
|
||||
return isChannelActive();
|
||||
}
|
||||
|
||||
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`
|
||||
DEBUG_MSG("SX128x entering sleep mode (FIXME, don't keep config)\n");
|
||||
setStandby(); // Stop any pending operations
|
||||
|
||||
// turn off TCXO if it was powered
|
||||
// FIXME - this isn't correct
|
||||
// lora.setTCXO(0);
|
||||
|
||||
// put chipset into sleep mode (we've already disabled interrupts by now)
|
||||
bool keepConfig = true;
|
||||
lora.sleep(keepConfig); // Note: we do not keep the config, full reinit will be needed
|
||||
|
||||
#ifdef SX128X_POWER_EN
|
||||
digitalWrite(SX128X_POWER_EN, LOW);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
75
src/mesh/SX128xInterface.h
Normal file
75
src/mesh/SX128xInterface.h
Normal file
@@ -0,0 +1,75 @@
|
||||
#pragma once
|
||||
|
||||
#if !defined(ARCH_PORTDUINO)
|
||||
|
||||
#include "RadioLibInterface.h"
|
||||
|
||||
/**
|
||||
* \brief Adapter for SX128x radio family. Implements common logic for child classes.
|
||||
* \tparam T RadioLib module type for SX128x: SX1281.
|
||||
*/
|
||||
template<class T>
|
||||
class SX128xInterface : public RadioLibInterface
|
||||
{
|
||||
public:
|
||||
SX128xInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi);
|
||||
|
||||
/// Initialise the Driver transport hardware and software.
|
||||
/// Make sure the Driver is properly configured before calling init().
|
||||
/// \return true if initialisation succeeded.
|
||||
virtual bool init() override;
|
||||
|
||||
/// Apply any radio provisioning changes
|
||||
/// Make sure the Driver is properly configured before calling init().
|
||||
/// \return true if initialisation succeeded.
|
||||
virtual bool reconfigure() override;
|
||||
|
||||
/// Prepare hardware for sleep. Call this _only_ for deep sleep, not needed for light sleep.
|
||||
virtual bool sleep() override;
|
||||
|
||||
protected:
|
||||
|
||||
float currentLimit = 140; // Higher OCP limit for SX128x PA
|
||||
|
||||
/**
|
||||
* Specific module instance
|
||||
*/
|
||||
T lora;
|
||||
|
||||
/**
|
||||
* Glue functions called from ISR land
|
||||
*/
|
||||
virtual void disableInterrupt() override;
|
||||
|
||||
/**
|
||||
* Enable a particular ISR callback glue function
|
||||
*/
|
||||
virtual void enableInterrupt(void (*callback)()) { lora.setDio1Action(callback); }
|
||||
|
||||
/** can we detect a LoRa preamble on the current channel? */
|
||||
virtual bool isChannelActive() override;
|
||||
|
||||
/** are we actively receiving a packet (only called during receiving state) */
|
||||
virtual bool isActivelyReceiving() override;
|
||||
|
||||
/**
|
||||
* Start waiting to receive a message
|
||||
*/
|
||||
virtual void startReceive() override;
|
||||
|
||||
/**
|
||||
* We override to turn on transmitter power as needed.
|
||||
*/
|
||||
virtual void configHardwareForSend() override;
|
||||
|
||||
/**
|
||||
* Add SNR data to received messages
|
||||
*/
|
||||
virtual void addReceiveMetadata(MeshPacket *mp) override;
|
||||
|
||||
virtual void setStandby() override;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif
|
||||
148
src/mesh/eth/ethClient.cpp
Normal file
148
src/mesh/eth/ethClient.cpp
Normal file
@@ -0,0 +1,148 @@
|
||||
#include "mesh/eth/ethClient.h"
|
||||
#include "NodeDB.h"
|
||||
#include "RTC.h"
|
||||
#include "concurrency/Periodic.h"
|
||||
#include <SPI.h>
|
||||
#include <RAK13800_W5100S.h>
|
||||
#include "target_specific.h"
|
||||
#include "mesh/eth/ethServerAPI.h"
|
||||
#include "mqtt/MQTT.h"
|
||||
|
||||
#ifndef DISABLE_NTP
|
||||
#include <NTPClient.h>
|
||||
|
||||
// NTP
|
||||
EthernetUDP ntpUDP;
|
||||
NTPClient timeClient(ntpUDP, config.network.ntp_server);
|
||||
uint32_t ntp_renew = 0;
|
||||
#endif
|
||||
|
||||
bool ethStartupComplete = 0;
|
||||
|
||||
using namespace concurrency;
|
||||
|
||||
static Periodic *ethEvent;
|
||||
|
||||
static int32_t reconnectETH()
|
||||
{
|
||||
if (config.network.eth_enabled) {
|
||||
Ethernet.maintain();
|
||||
if (!ethStartupComplete) {
|
||||
// Start web server
|
||||
DEBUG_MSG("... Starting network services\n");
|
||||
|
||||
#ifndef DISABLE_NTP
|
||||
DEBUG_MSG("Starting NTP time client\n");
|
||||
timeClient.begin();
|
||||
timeClient.setUpdateInterval(60 * 60); // Update once an hour
|
||||
#endif
|
||||
// initWebServer();
|
||||
initApiServer();
|
||||
|
||||
ethStartupComplete = true;
|
||||
}
|
||||
|
||||
// FIXME this is kinda yucky, instead we should just have an observable for 'wifireconnected'
|
||||
if (mqtt && !mqtt->connected()) {
|
||||
mqtt->reconnect();
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef DISABLE_NTP
|
||||
if (isEthernetAvailable() && (ntp_renew < millis())) {
|
||||
|
||||
DEBUG_MSG("Updating NTP time from %s\n", config.network.ntp_server);
|
||||
if (timeClient.update()) {
|
||||
DEBUG_MSG("NTP Request Success - Setting RTCQualityNTP if needed\n");
|
||||
|
||||
struct timeval tv;
|
||||
tv.tv_sec = timeClient.getEpochTime();
|
||||
tv.tv_usec = 0;
|
||||
|
||||
perhapsSetRTC(RTCQualityNTP, &tv);
|
||||
|
||||
ntp_renew = millis() + 43200 * 1000; // success, refresh every 12 hours
|
||||
|
||||
} else {
|
||||
DEBUG_MSG("NTP Update failed\n");
|
||||
ntp_renew = millis() + 300 * 1000; // failure, retry every 5 minutes
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 5000; // every 5 seconds
|
||||
}
|
||||
|
||||
// Startup Ethernet
|
||||
bool initEthernet()
|
||||
{
|
||||
if (config.network.eth_enabled) {
|
||||
|
||||
#ifdef PIN_ETHERNET_RESET
|
||||
pinMode(PIN_ETHERNET_RESET, OUTPUT);
|
||||
digitalWrite(PIN_ETHERNET_RESET, LOW); // Reset Time.
|
||||
delay(100);
|
||||
digitalWrite(PIN_ETHERNET_RESET, HIGH); // Reset Time.
|
||||
#endif
|
||||
|
||||
Ethernet.init( ETH_SPI_PORT, PIN_ETHERNET_SS );
|
||||
|
||||
uint8_t mac[6];
|
||||
|
||||
int status = 0;
|
||||
|
||||
// createSSLCert();
|
||||
|
||||
getMacAddr(mac); // FIXME use the BLE MAC for now...
|
||||
|
||||
if (config.network.eth_mode == Config_NetworkConfig_EthMode_DHCP) {
|
||||
DEBUG_MSG("starting Ethernet DHCP\n");
|
||||
status = Ethernet.begin(mac);
|
||||
} else if (config.network.eth_mode == Config_NetworkConfig_EthMode_STATIC) {
|
||||
DEBUG_MSG("starting Ethernet Static\n");
|
||||
Ethernet.begin(mac, config.network.ipv4_config.ip, config.network.ipv4_config.dns, config.network.ipv4_config.subnet);
|
||||
} else {
|
||||
DEBUG_MSG("Ethernet Disabled\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (status == 0) {
|
||||
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
|
||||
DEBUG_MSG("Ethernet shield was not found.\n");
|
||||
return false;
|
||||
} else if (Ethernet.linkStatus() == LinkOFF) {
|
||||
DEBUG_MSG("Ethernet cable is not connected.\n");
|
||||
return false;
|
||||
} else{
|
||||
DEBUG_MSG("Unknown Ethernet error.\n");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
DEBUG_MSG("Local IP %u.%u.%u.%u\n",Ethernet.localIP()[0], Ethernet.localIP()[1], Ethernet.localIP()[2], Ethernet.localIP()[3]);
|
||||
DEBUG_MSG("Subnet Mask %u.%u.%u.%u\n",Ethernet.subnetMask()[0], Ethernet.subnetMask()[1], Ethernet.subnetMask()[2], Ethernet.subnetMask()[3]);
|
||||
DEBUG_MSG("Gateway IP %u.%u.%u.%u\n",Ethernet.gatewayIP()[0], Ethernet.gatewayIP()[1], Ethernet.gatewayIP()[2], Ethernet.gatewayIP()[3]);
|
||||
DEBUG_MSG("DNS Server IP %u.%u.%u.%u\n",Ethernet.dnsServerIP()[0], Ethernet.dnsServerIP()[1], Ethernet.dnsServerIP()[2], Ethernet.dnsServerIP()[3]);
|
||||
}
|
||||
|
||||
ethEvent = new Periodic("ethConnect", reconnectETH);
|
||||
|
||||
return true;
|
||||
|
||||
} else {
|
||||
DEBUG_MSG("Not using Ethernet\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool isEthernetAvailable() {
|
||||
|
||||
if (!config.network.eth_enabled) {
|
||||
return false;
|
||||
} else if (Ethernet.hardwareStatus() == EthernetNoHardware) {
|
||||
return false;
|
||||
} else if (Ethernet.linkStatus() == LinkOFF) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
8
src/mesh/eth/ethClient.h
Normal file
8
src/mesh/eth/ethClient.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "configuration.h"
|
||||
#include <Arduino.h>
|
||||
#include <functional>
|
||||
|
||||
bool initEthernet();
|
||||
bool isEthernetAvailable();
|
||||
82
src/mesh/eth/ethServerAPI.cpp
Normal file
82
src/mesh/eth/ethServerAPI.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
#include "ethServerAPI.h"
|
||||
#include "configuration.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
static ethServerPort *apiPort;
|
||||
|
||||
void initApiServer(int port)
|
||||
{
|
||||
// Start API server on port 4403
|
||||
if (!apiPort) {
|
||||
apiPort = new ethServerPort(port);
|
||||
DEBUG_MSG("API server listening on TCP port %d\n", port);
|
||||
apiPort->init();
|
||||
}
|
||||
}
|
||||
|
||||
ethServerAPI::ethServerAPI(EthernetClient &_client) : StreamAPI(&client), client(_client)
|
||||
{
|
||||
DEBUG_MSG("Incoming ethernet connection\n");
|
||||
}
|
||||
|
||||
ethServerAPI::~ethServerAPI()
|
||||
{
|
||||
client.stop();
|
||||
|
||||
// FIXME - delete this if the client dropps the connection!
|
||||
}
|
||||
|
||||
/// override close to also shutdown the TCP link
|
||||
void ethServerAPI::close()
|
||||
{
|
||||
client.stop(); // drop tcp connection
|
||||
StreamAPI::close();
|
||||
}
|
||||
|
||||
/// Check the current underlying physical link to see if the client is currently connected
|
||||
bool ethServerAPI::checkIsConnected()
|
||||
{
|
||||
return client.connected();
|
||||
}
|
||||
|
||||
int32_t ethServerAPI::runOnce()
|
||||
{
|
||||
if (client.connected()) {
|
||||
return StreamAPI::runOnce();
|
||||
} else {
|
||||
DEBUG_MSG("Client dropped connection, suspending API service\n");
|
||||
enabled = false; // we no longer need to run
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// If an api server is running, we try to spit out debug 'serial' characters there
|
||||
void ethServerPort::debugOut(char c)
|
||||
{
|
||||
if (apiPort && apiPort->openAPI)
|
||||
apiPort->openAPI->debugOut(c);
|
||||
}
|
||||
|
||||
|
||||
ethServerPort::ethServerPort(int port) : EthernetServer(port), concurrency::OSThread("ApiServer") {}
|
||||
|
||||
void ethServerPort::init()
|
||||
{
|
||||
begin();
|
||||
}
|
||||
|
||||
int32_t ethServerPort::runOnce()
|
||||
{
|
||||
auto client = available();
|
||||
if (client) {
|
||||
// Close any previous connection (see FIXME in header file)
|
||||
if (openAPI) {
|
||||
DEBUG_MSG("Force closing previous TCP connection\n");
|
||||
delete openAPI;
|
||||
}
|
||||
|
||||
openAPI = new ethServerAPI(client);
|
||||
}
|
||||
|
||||
return 100; // only check occasionally for incoming connections
|
||||
}
|
||||
58
src/mesh/eth/ethServerAPI.h
Normal file
58
src/mesh/eth/ethServerAPI.h
Normal file
@@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
|
||||
#include "StreamAPI.h"
|
||||
#include <RAK13800_W5100S.h>
|
||||
|
||||
/**
|
||||
* Provides both debug printing and, if the client starts sending protobufs to us, switches to send/receive protobufs
|
||||
* (and starts dropping debug printing - FIXME, eventually those prints should be encapsulated in protobufs).
|
||||
*/
|
||||
class ethServerAPI : public StreamAPI
|
||||
{
|
||||
private:
|
||||
EthernetClient client;
|
||||
|
||||
public:
|
||||
explicit ethServerAPI(EthernetClient &_client);
|
||||
|
||||
virtual ~ethServerAPI();
|
||||
|
||||
/// override close to also shutdown the TCP link
|
||||
virtual void close();
|
||||
|
||||
protected:
|
||||
/// We override this method to prevent publishing EVENT_SERIAL_CONNECTED/DISCONNECTED for wifi links (we want the board to
|
||||
/// stay in the POWERED state to prevent disabling wifi)
|
||||
virtual void onConnectionChanged(bool connected) override {}
|
||||
|
||||
virtual int32_t runOnce() override; // Check for dropped client connections
|
||||
|
||||
/// Check the current underlying physical link to see if the client is currently connected
|
||||
virtual bool checkIsConnected() override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Listens for incoming connections and does accepts and creates instances of WiFiServerAPI as needed
|
||||
*/
|
||||
class ethServerPort : public EthernetServer, private concurrency::OSThread
|
||||
{
|
||||
/** The currently open port
|
||||
*
|
||||
* FIXME: We currently only allow one open TCP connection at a time, because we depend on the loop() call in this class to
|
||||
* delegate to the worker. Once coroutines are implemented we can relax this restriction.
|
||||
*/
|
||||
ethServerAPI *openAPI = NULL;
|
||||
|
||||
public:
|
||||
explicit ethServerPort(int port);
|
||||
|
||||
void init();
|
||||
|
||||
/// If an api server is running, we try to spit out debug 'serial' characters there
|
||||
static void debugOut(char c);
|
||||
|
||||
protected:
|
||||
int32_t runOnce() override;
|
||||
};
|
||||
|
||||
void initApiServer(int port=4403);
|
||||
@@ -54,7 +54,7 @@ extern const pb_msgdesc_t ChannelSet_msg;
|
||||
#define ChannelSet_fields &ChannelSet_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define ChannelSet_size 581
|
||||
#define ChannelSet_size 582
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
||||
@@ -21,6 +21,9 @@ PB_BIND(Config_PowerConfig, Config_PowerConfig, AUTO)
|
||||
PB_BIND(Config_NetworkConfig, Config_NetworkConfig, AUTO)
|
||||
|
||||
|
||||
PB_BIND(Config_NetworkConfig_IpV4Config, Config_NetworkConfig_IpV4Config, AUTO)
|
||||
|
||||
|
||||
PB_BIND(Config_DisplayConfig, Config_DisplayConfig, AUTO)
|
||||
|
||||
|
||||
@@ -39,3 +42,4 @@ PB_BIND(Config_BluetoothConfig, Config_BluetoothConfig, AUTO)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -37,6 +37,11 @@ typedef enum _Config_NetworkConfig_WiFiMode {
|
||||
Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN = 2
|
||||
} Config_NetworkConfig_WiFiMode;
|
||||
|
||||
typedef enum _Config_NetworkConfig_EthMode {
|
||||
Config_NetworkConfig_EthMode_DHCP = 0,
|
||||
Config_NetworkConfig_EthMode_STATIC = 1
|
||||
} Config_NetworkConfig_EthMode;
|
||||
|
||||
typedef enum _Config_DisplayConfig_GpsCoordinateFormat {
|
||||
Config_DisplayConfig_GpsCoordinateFormat_DEC = 0,
|
||||
Config_DisplayConfig_GpsCoordinateFormat_DMS = 1,
|
||||
@@ -64,7 +69,8 @@ typedef enum _Config_LoRaConfig_RegionCode {
|
||||
Config_LoRaConfig_RegionCode_RU = 9,
|
||||
Config_LoRaConfig_RegionCode_IN = 10,
|
||||
Config_LoRaConfig_RegionCode_NZ_865 = 11,
|
||||
Config_LoRaConfig_RegionCode_TH = 12
|
||||
Config_LoRaConfig_RegionCode_TH = 12,
|
||||
Config_LoRaConfig_RegionCode_LORA_24 = 13
|
||||
} Config_LoRaConfig_RegionCode;
|
||||
|
||||
typedef enum _Config_LoRaConfig_ModemPreset {
|
||||
@@ -116,18 +122,17 @@ typedef struct _Config_LoRaConfig {
|
||||
uint32_t hop_limit;
|
||||
bool tx_enabled;
|
||||
int8_t tx_power;
|
||||
uint8_t channel_num;
|
||||
uint16_t channel_num;
|
||||
pb_size_t ignore_incoming_count;
|
||||
uint32_t ignore_incoming[3];
|
||||
} Config_LoRaConfig;
|
||||
|
||||
typedef struct _Config_NetworkConfig {
|
||||
bool wifi_enabled;
|
||||
Config_NetworkConfig_WiFiMode wifi_mode;
|
||||
char wifi_ssid[33];
|
||||
char wifi_psk[64];
|
||||
char ntp_server[33];
|
||||
} Config_NetworkConfig;
|
||||
typedef struct _Config_NetworkConfig_IpV4Config {
|
||||
uint32_t ip;
|
||||
uint32_t gateway;
|
||||
uint32_t subnet;
|
||||
uint32_t dns;
|
||||
} Config_NetworkConfig_IpV4Config;
|
||||
|
||||
typedef struct _Config_PositionConfig {
|
||||
uint32_t position_broadcast_secs;
|
||||
@@ -150,6 +155,17 @@ typedef struct _Config_PowerConfig {
|
||||
uint32_t min_wake_secs;
|
||||
} Config_PowerConfig;
|
||||
|
||||
typedef struct _Config_NetworkConfig {
|
||||
bool wifi_enabled;
|
||||
char wifi_ssid[33];
|
||||
char wifi_psk[64];
|
||||
char ntp_server[33];
|
||||
bool eth_enabled;
|
||||
Config_NetworkConfig_EthMode eth_mode;
|
||||
bool has_ipv4_config;
|
||||
Config_NetworkConfig_IpV4Config ipv4_config;
|
||||
} Config_NetworkConfig;
|
||||
|
||||
typedef struct _Config {
|
||||
pb_size_t which_payload_variant;
|
||||
union {
|
||||
@@ -177,6 +193,10 @@ typedef struct _Config {
|
||||
#define _Config_NetworkConfig_WiFiMode_MAX Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN
|
||||
#define _Config_NetworkConfig_WiFiMode_ARRAYSIZE ((Config_NetworkConfig_WiFiMode)(Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN+1))
|
||||
|
||||
#define _Config_NetworkConfig_EthMode_MIN Config_NetworkConfig_EthMode_DHCP
|
||||
#define _Config_NetworkConfig_EthMode_MAX Config_NetworkConfig_EthMode_STATIC
|
||||
#define _Config_NetworkConfig_EthMode_ARRAYSIZE ((Config_NetworkConfig_EthMode)(Config_NetworkConfig_EthMode_STATIC+1))
|
||||
|
||||
#define _Config_DisplayConfig_GpsCoordinateFormat_MIN Config_DisplayConfig_GpsCoordinateFormat_DEC
|
||||
#define _Config_DisplayConfig_GpsCoordinateFormat_MAX Config_DisplayConfig_GpsCoordinateFormat_OSGR
|
||||
#define _Config_DisplayConfig_GpsCoordinateFormat_ARRAYSIZE ((Config_DisplayConfig_GpsCoordinateFormat)(Config_DisplayConfig_GpsCoordinateFormat_OSGR+1))
|
||||
@@ -186,8 +206,8 @@ typedef struct _Config {
|
||||
#define _Config_DisplayConfig_DisplayUnits_ARRAYSIZE ((Config_DisplayConfig_DisplayUnits)(Config_DisplayConfig_DisplayUnits_IMPERIAL+1))
|
||||
|
||||
#define _Config_LoRaConfig_RegionCode_MIN Config_LoRaConfig_RegionCode_UNSET
|
||||
#define _Config_LoRaConfig_RegionCode_MAX Config_LoRaConfig_RegionCode_TH
|
||||
#define _Config_LoRaConfig_RegionCode_ARRAYSIZE ((Config_LoRaConfig_RegionCode)(Config_LoRaConfig_RegionCode_TH+1))
|
||||
#define _Config_LoRaConfig_RegionCode_MAX Config_LoRaConfig_RegionCode_LORA_24
|
||||
#define _Config_LoRaConfig_RegionCode_ARRAYSIZE ((Config_LoRaConfig_RegionCode)(Config_LoRaConfig_RegionCode_LORA_24+1))
|
||||
|
||||
#define _Config_LoRaConfig_ModemPreset_MIN Config_LoRaConfig_ModemPreset_LONG_FAST
|
||||
#define _Config_LoRaConfig_ModemPreset_MAX Config_LoRaConfig_ModemPreset_SHORT_FAST
|
||||
@@ -207,7 +227,8 @@ extern "C" {
|
||||
#define Config_DeviceConfig_init_default {_Config_DeviceConfig_Role_MIN, 0, 0}
|
||||
#define Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0}
|
||||
#define Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0}
|
||||
#define Config_NetworkConfig_init_default {0, _Config_NetworkConfig_WiFiMode_MIN, "", "", ""}
|
||||
#define Config_NetworkConfig_init_default {0, "", "", "", 0, _Config_NetworkConfig_EthMode_MIN, false, Config_NetworkConfig_IpV4Config_init_default}
|
||||
#define Config_NetworkConfig_IpV4Config_init_default {0, 0, 0, 0}
|
||||
#define Config_DisplayConfig_init_default {0, _Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _Config_DisplayConfig_DisplayUnits_MIN}
|
||||
#define Config_LoRaConfig_init_default {0, _Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, {0, 0, 0}}
|
||||
#define Config_BluetoothConfig_init_default {0, _Config_BluetoothConfig_PairingMode_MIN, 0}
|
||||
@@ -215,7 +236,8 @@ extern "C" {
|
||||
#define Config_DeviceConfig_init_zero {_Config_DeviceConfig_Role_MIN, 0, 0}
|
||||
#define Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0}
|
||||
#define Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0}
|
||||
#define Config_NetworkConfig_init_zero {0, _Config_NetworkConfig_WiFiMode_MIN, "", "", ""}
|
||||
#define Config_NetworkConfig_init_zero {0, "", "", "", 0, _Config_NetworkConfig_EthMode_MIN, false, Config_NetworkConfig_IpV4Config_init_zero}
|
||||
#define Config_NetworkConfig_IpV4Config_init_zero {0, 0, 0, 0}
|
||||
#define Config_DisplayConfig_init_zero {0, _Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _Config_DisplayConfig_DisplayUnits_MIN}
|
||||
#define Config_LoRaConfig_init_zero {0, _Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, {0, 0, 0}}
|
||||
#define Config_BluetoothConfig_init_zero {0, _Config_BluetoothConfig_PairingMode_MIN, 0}
|
||||
@@ -245,11 +267,10 @@ extern "C" {
|
||||
#define Config_LoRaConfig_tx_power_tag 10
|
||||
#define Config_LoRaConfig_channel_num_tag 11
|
||||
#define Config_LoRaConfig_ignore_incoming_tag 103
|
||||
#define Config_NetworkConfig_wifi_enabled_tag 1
|
||||
#define Config_NetworkConfig_wifi_mode_tag 2
|
||||
#define Config_NetworkConfig_wifi_ssid_tag 3
|
||||
#define Config_NetworkConfig_wifi_psk_tag 4
|
||||
#define Config_NetworkConfig_ntp_server_tag 5
|
||||
#define Config_NetworkConfig_IpV4Config_ip_tag 1
|
||||
#define Config_NetworkConfig_IpV4Config_gateway_tag 2
|
||||
#define Config_NetworkConfig_IpV4Config_subnet_tag 3
|
||||
#define Config_NetworkConfig_IpV4Config_dns_tag 4
|
||||
#define Config_PositionConfig_position_broadcast_secs_tag 1
|
||||
#define Config_PositionConfig_position_broadcast_smart_enabled_tag 2
|
||||
#define Config_PositionConfig_fixed_position_tag 3
|
||||
@@ -265,6 +286,13 @@ extern "C" {
|
||||
#define Config_PowerConfig_sds_secs_tag 6
|
||||
#define Config_PowerConfig_ls_secs_tag 7
|
||||
#define Config_PowerConfig_min_wake_secs_tag 8
|
||||
#define Config_NetworkConfig_wifi_enabled_tag 1
|
||||
#define Config_NetworkConfig_wifi_ssid_tag 3
|
||||
#define Config_NetworkConfig_wifi_psk_tag 4
|
||||
#define Config_NetworkConfig_ntp_server_tag 5
|
||||
#define Config_NetworkConfig_eth_enabled_tag 6
|
||||
#define Config_NetworkConfig_eth_mode_tag 7
|
||||
#define Config_NetworkConfig_ipv4_config_tag 8
|
||||
#define Config_device_tag 1
|
||||
#define Config_position_tag 2
|
||||
#define Config_power_tag 3
|
||||
@@ -324,12 +352,23 @@ X(a, STATIC, SINGULAR, UINT32, min_wake_secs, 8)
|
||||
|
||||
#define Config_NetworkConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, BOOL, wifi_enabled, 1) \
|
||||
X(a, STATIC, SINGULAR, UENUM, wifi_mode, 2) \
|
||||
X(a, STATIC, SINGULAR, STRING, wifi_ssid, 3) \
|
||||
X(a, STATIC, SINGULAR, STRING, wifi_psk, 4) \
|
||||
X(a, STATIC, SINGULAR, STRING, ntp_server, 5)
|
||||
X(a, STATIC, SINGULAR, STRING, ntp_server, 5) \
|
||||
X(a, STATIC, SINGULAR, BOOL, eth_enabled, 6) \
|
||||
X(a, STATIC, SINGULAR, UENUM, eth_mode, 7) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, ipv4_config, 8)
|
||||
#define Config_NetworkConfig_CALLBACK NULL
|
||||
#define Config_NetworkConfig_DEFAULT NULL
|
||||
#define Config_NetworkConfig_ipv4_config_MSGTYPE Config_NetworkConfig_IpV4Config
|
||||
|
||||
#define Config_NetworkConfig_IpV4Config_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, FIXED32, ip, 1) \
|
||||
X(a, STATIC, SINGULAR, FIXED32, gateway, 2) \
|
||||
X(a, STATIC, SINGULAR, FIXED32, subnet, 3) \
|
||||
X(a, STATIC, SINGULAR, FIXED32, dns, 4)
|
||||
#define Config_NetworkConfig_IpV4Config_CALLBACK NULL
|
||||
#define Config_NetworkConfig_IpV4Config_DEFAULT NULL
|
||||
|
||||
#define Config_DisplayConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT32, screen_on_secs, 1) \
|
||||
@@ -369,6 +408,7 @@ extern const pb_msgdesc_t Config_DeviceConfig_msg;
|
||||
extern const pb_msgdesc_t Config_PositionConfig_msg;
|
||||
extern const pb_msgdesc_t Config_PowerConfig_msg;
|
||||
extern const pb_msgdesc_t Config_NetworkConfig_msg;
|
||||
extern const pb_msgdesc_t Config_NetworkConfig_IpV4Config_msg;
|
||||
extern const pb_msgdesc_t Config_DisplayConfig_msg;
|
||||
extern const pb_msgdesc_t Config_LoRaConfig_msg;
|
||||
extern const pb_msgdesc_t Config_BluetoothConfig_msg;
|
||||
@@ -379,6 +419,7 @@ extern const pb_msgdesc_t Config_BluetoothConfig_msg;
|
||||
#define Config_PositionConfig_fields &Config_PositionConfig_msg
|
||||
#define Config_PowerConfig_fields &Config_PowerConfig_msg
|
||||
#define Config_NetworkConfig_fields &Config_NetworkConfig_msg
|
||||
#define Config_NetworkConfig_IpV4Config_fields &Config_NetworkConfig_IpV4Config_msg
|
||||
#define Config_DisplayConfig_fields &Config_DisplayConfig_msg
|
||||
#define Config_LoRaConfig_fields &Config_LoRaConfig_msg
|
||||
#define Config_BluetoothConfig_fields &Config_BluetoothConfig_msg
|
||||
@@ -387,11 +428,12 @@ extern const pb_msgdesc_t Config_BluetoothConfig_msg;
|
||||
#define Config_BluetoothConfig_size 10
|
||||
#define Config_DeviceConfig_size 6
|
||||
#define Config_DisplayConfig_size 20
|
||||
#define Config_LoRaConfig_size 67
|
||||
#define Config_NetworkConfig_size 137
|
||||
#define Config_LoRaConfig_size 68
|
||||
#define Config_NetworkConfig_IpV4Config_size 20
|
||||
#define Config_NetworkConfig_size 161
|
||||
#define Config_PositionConfig_size 30
|
||||
#define Config_PowerConfig_size 43
|
||||
#define Config_size 140
|
||||
#define Config_size 164
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
||||
@@ -69,6 +69,7 @@ typedef struct _DeviceState {
|
||||
} DeviceState;
|
||||
|
||||
typedef PB_BYTES_ARRAY_T(2048) OEMStore_oem_icon_bits_t;
|
||||
typedef PB_BYTES_ARRAY_T(32) OEMStore_oem_aes_key_t;
|
||||
/* This can be used for customizing the firmware distribution. If populated,
|
||||
show a secondary bootup screen with cuatom logo and text for 2.5 seconds. */
|
||||
typedef struct _OEMStore {
|
||||
@@ -82,6 +83,8 @@ typedef struct _OEMStore {
|
||||
ScreenFonts oem_font;
|
||||
/* Use this font for the OEM text. */
|
||||
char oem_text[40];
|
||||
/* The default device encryption key, 16 or 32 byte */
|
||||
OEMStore_oem_aes_key_t oem_aes_key;
|
||||
} OEMStore;
|
||||
|
||||
|
||||
@@ -98,10 +101,10 @@ extern "C" {
|
||||
/* Initializer values for message structs */
|
||||
#define DeviceState_init_default {false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default}, false, MeshPacket_init_default, 0, 0, 0}
|
||||
#define ChannelFile_init_default {0, {Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default}, 0}
|
||||
#define OEMStore_init_default {0, 0, {0, {0}}, _ScreenFonts_MIN, ""}
|
||||
#define OEMStore_init_default {0, 0, {0, {0}}, _ScreenFonts_MIN, "", {0, {0}}}
|
||||
#define DeviceState_init_zero {false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero}, false, MeshPacket_init_zero, 0, 0, 0}
|
||||
#define ChannelFile_init_zero {0, {Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero}, 0}
|
||||
#define OEMStore_init_zero {0, 0, {0, {0}}, _ScreenFonts_MIN, ""}
|
||||
#define OEMStore_init_zero {0, 0, {0, {0}}, _ScreenFonts_MIN, "", {0, {0}}}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define ChannelFile_channels_tag 1
|
||||
@@ -119,6 +122,7 @@ extern "C" {
|
||||
#define OEMStore_oem_icon_bits_tag 3
|
||||
#define OEMStore_oem_font_tag 4
|
||||
#define OEMStore_oem_text_tag 5
|
||||
#define OEMStore_oem_aes_key_tag 6
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
#define DeviceState_FIELDLIST(X, a) \
|
||||
@@ -150,7 +154,8 @@ X(a, STATIC, SINGULAR, UINT32, oem_icon_width, 1) \
|
||||
X(a, STATIC, SINGULAR, UINT32, oem_icon_height, 2) \
|
||||
X(a, STATIC, SINGULAR, BYTES, oem_icon_bits, 3) \
|
||||
X(a, STATIC, SINGULAR, UENUM, oem_font, 4) \
|
||||
X(a, STATIC, SINGULAR, STRING, oem_text, 5)
|
||||
X(a, STATIC, SINGULAR, STRING, oem_text, 5) \
|
||||
X(a, STATIC, SINGULAR, BYTES, oem_aes_key, 6)
|
||||
#define OEMStore_CALLBACK NULL
|
||||
#define OEMStore_DEFAULT NULL
|
||||
|
||||
@@ -166,7 +171,7 @@ extern const pb_msgdesc_t OEMStore_msg;
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define ChannelFile_size 638
|
||||
#define DeviceState_size 21800
|
||||
#define OEMStore_size 2106
|
||||
#define OEMStore_size 2140
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
||||
@@ -144,7 +144,7 @@ extern const pb_msgdesc_t LocalModuleConfig_msg;
|
||||
#define LocalModuleConfig_fields &LocalModuleConfig_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define LocalConfig_size 334
|
||||
#define LocalConfig_size 359
|
||||
#define LocalModuleConfig_size 270
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -42,9 +42,6 @@ PB_BIND(FromRadio, FromRadio, 2)
|
||||
PB_BIND(ToRadio, ToRadio, 2)
|
||||
|
||||
|
||||
PB_BIND(ToRadio_PeerInfo, ToRadio_PeerInfo, AUTO)
|
||||
|
||||
|
||||
PB_BIND(Compressed, Compressed, AUTO)
|
||||
|
||||
|
||||
|
||||
@@ -243,8 +243,11 @@ typedef enum _LogRecord_Level {
|
||||
|
||||
/* Struct definitions */
|
||||
typedef PB_BYTES_ARRAY_T(237) Compressed_data_t;
|
||||
/* Compressed message payload */
|
||||
typedef struct _Compressed {
|
||||
/* PortNum to determine the how to handle the compressed payload. */
|
||||
PortNum portnum;
|
||||
/* Compressed data. */
|
||||
Compressed_data_t data;
|
||||
} Compressed;
|
||||
|
||||
@@ -352,7 +355,7 @@ typedef struct _MyNodeInfo {
|
||||
|
||||
/* a gps position */
|
||||
typedef struct _Position {
|
||||
/* The new preferred location encoding, divide by 1e-7 to get degrees
|
||||
/* The new preferred location encoding, multiply by 1e-7 to get degrees
|
||||
in floating point */
|
||||
int32_t latitude_i;
|
||||
/* TODO: REPLACE */
|
||||
@@ -425,14 +428,6 @@ typedef struct _RouteDiscovery {
|
||||
uint32_t route[8];
|
||||
} RouteDiscovery;
|
||||
|
||||
/* Compressed message payload */
|
||||
typedef struct _ToRadio_PeerInfo {
|
||||
/* PortNum to determine the how to handle the compressed payload. */
|
||||
uint32_t app_version;
|
||||
/* Compressed data. */
|
||||
bool mqtt_gateway;
|
||||
} ToRadio_PeerInfo;
|
||||
|
||||
/* Broadcast when a newly powered mesh node wants to find a node num it can use
|
||||
Sent from the phone over bluetooth to set the user id for the owner of this node.
|
||||
Also sent from nodes to each other when a new node signs on (so all clients can have this info)
|
||||
@@ -665,9 +660,6 @@ typedef struct _ToRadio {
|
||||
union {
|
||||
/* Send this packet on the mesh */
|
||||
MeshPacket packet;
|
||||
/* Information about the peer, sent after the phone sneds want_config_id.
|
||||
Old clients do not send this, which is fine. */
|
||||
ToRadio_PeerInfo peer_info;
|
||||
/* Phone wants radio to send full node db to the phone, This is
|
||||
typically the first packet sent to the radio when the phone gets a
|
||||
bluetooth connection. The radio will respond by sending back a
|
||||
@@ -740,7 +732,6 @@ extern "C" {
|
||||
#define LogRecord_init_default {"", 0, "", _LogRecord_Level_MIN}
|
||||
#define FromRadio_init_default {0, 0, {MeshPacket_init_default}}
|
||||
#define ToRadio_init_default {0, {MeshPacket_init_default}}
|
||||
#define ToRadio_PeerInfo_init_default {0, 0}
|
||||
#define Compressed_init_default {_PortNum_MIN, {0, {0}}}
|
||||
#define Position_init_zero {0, 0, 0, 0, _Position_LocSource_MIN, _Position_AltSource_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
#define User_init_zero {"", "", "", {0}, _HardwareModel_MIN, 0}
|
||||
@@ -754,7 +745,6 @@ extern "C" {
|
||||
#define LogRecord_init_zero {"", 0, "", _LogRecord_Level_MIN}
|
||||
#define FromRadio_init_zero {0, 0, {MeshPacket_init_zero}}
|
||||
#define ToRadio_init_zero {0, {MeshPacket_init_zero}}
|
||||
#define ToRadio_PeerInfo_init_zero {0, 0}
|
||||
#define Compressed_init_zero {_PortNum_MIN, {0, {0}}}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
@@ -811,8 +801,6 @@ extern "C" {
|
||||
#define Position_next_update_tag 21
|
||||
#define Position_seq_number_tag 22
|
||||
#define RouteDiscovery_route_tag 1
|
||||
#define ToRadio_PeerInfo_app_version_tag 1
|
||||
#define ToRadio_PeerInfo_mqtt_gateway_tag 2
|
||||
#define User_id_tag 1
|
||||
#define User_long_name_tag 2
|
||||
#define User_short_name_tag 3
|
||||
@@ -859,7 +847,6 @@ extern "C" {
|
||||
#define FromRadio_moduleConfig_tag 9
|
||||
#define FromRadio_channel_tag 10
|
||||
#define ToRadio_packet_tag 1
|
||||
#define ToRadio_peer_info_tag 2
|
||||
#define ToRadio_want_config_id_tag 3
|
||||
#define ToRadio_disconnect_tag 4
|
||||
|
||||
@@ -1019,19 +1006,11 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,channel,channel), 10)
|
||||
|
||||
#define ToRadio_FIELDLIST(X, a) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,packet,packet), 1) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,peer_info,peer_info), 2) \
|
||||
X(a, STATIC, ONEOF, UINT32, (payload_variant,want_config_id,want_config_id), 3) \
|
||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,disconnect,disconnect), 4)
|
||||
#define ToRadio_CALLBACK NULL
|
||||
#define ToRadio_DEFAULT NULL
|
||||
#define ToRadio_payload_variant_packet_MSGTYPE MeshPacket
|
||||
#define ToRadio_payload_variant_peer_info_MSGTYPE ToRadio_PeerInfo
|
||||
|
||||
#define ToRadio_PeerInfo_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT32, app_version, 1) \
|
||||
X(a, STATIC, SINGULAR, BOOL, mqtt_gateway, 2)
|
||||
#define ToRadio_PeerInfo_CALLBACK NULL
|
||||
#define ToRadio_PeerInfo_DEFAULT NULL
|
||||
|
||||
#define Compressed_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UENUM, portnum, 1) \
|
||||
@@ -1051,7 +1030,6 @@ extern const pb_msgdesc_t MyNodeInfo_msg;
|
||||
extern const pb_msgdesc_t LogRecord_msg;
|
||||
extern const pb_msgdesc_t FromRadio_msg;
|
||||
extern const pb_msgdesc_t ToRadio_msg;
|
||||
extern const pb_msgdesc_t ToRadio_PeerInfo_msg;
|
||||
extern const pb_msgdesc_t Compressed_msg;
|
||||
|
||||
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
|
||||
@@ -1067,7 +1045,6 @@ extern const pb_msgdesc_t Compressed_msg;
|
||||
#define LogRecord_fields &LogRecord_msg
|
||||
#define FromRadio_fields &FromRadio_msg
|
||||
#define ToRadio_fields &ToRadio_msg
|
||||
#define ToRadio_PeerInfo_fields &ToRadio_PeerInfo_msg
|
||||
#define Compressed_fields &Compressed_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
@@ -1081,7 +1058,6 @@ extern const pb_msgdesc_t Compressed_msg;
|
||||
#define Position_size 137
|
||||
#define RouteDiscovery_size 40
|
||||
#define Routing_size 42
|
||||
#define ToRadio_PeerInfo_size 8
|
||||
#define ToRadio_size 324
|
||||
#define User_size 77
|
||||
#define Waypoint_size 156
|
||||
|
||||
@@ -33,7 +33,8 @@ typedef enum _ModuleConfig_SerialConfig_Serial_Mode {
|
||||
ModuleConfig_SerialConfig_Serial_Mode_DEFAULT = 0,
|
||||
ModuleConfig_SerialConfig_Serial_Mode_SIMPLE = 1,
|
||||
ModuleConfig_SerialConfig_Serial_Mode_PROTO = 2,
|
||||
ModuleConfig_SerialConfig_Serial_Mode_TEXTMSG = 3
|
||||
ModuleConfig_SerialConfig_Serial_Mode_TEXTMSG = 3,
|
||||
ModuleConfig_SerialConfig_Serial_Mode_NMEA = 4
|
||||
} ModuleConfig_SerialConfig_Serial_Mode;
|
||||
|
||||
typedef enum _ModuleConfig_CannedMessageConfig_InputEventChar {
|
||||
@@ -140,8 +141,8 @@ typedef struct _ModuleConfig {
|
||||
#define _ModuleConfig_SerialConfig_Serial_Baud_ARRAYSIZE ((ModuleConfig_SerialConfig_Serial_Baud)(ModuleConfig_SerialConfig_Serial_Baud_BAUD_921600+1))
|
||||
|
||||
#define _ModuleConfig_SerialConfig_Serial_Mode_MIN ModuleConfig_SerialConfig_Serial_Mode_DEFAULT
|
||||
#define _ModuleConfig_SerialConfig_Serial_Mode_MAX ModuleConfig_SerialConfig_Serial_Mode_TEXTMSG
|
||||
#define _ModuleConfig_SerialConfig_Serial_Mode_ARRAYSIZE ((ModuleConfig_SerialConfig_Serial_Mode)(ModuleConfig_SerialConfig_Serial_Mode_TEXTMSG+1))
|
||||
#define _ModuleConfig_SerialConfig_Serial_Mode_MAX ModuleConfig_SerialConfig_Serial_Mode_NMEA
|
||||
#define _ModuleConfig_SerialConfig_Serial_Mode_ARRAYSIZE ((ModuleConfig_SerialConfig_Serial_Mode)(ModuleConfig_SerialConfig_Serial_Mode_NMEA+1))
|
||||
|
||||
#define _ModuleConfig_CannedMessageConfig_InputEventChar_MIN ModuleConfig_CannedMessageConfig_InputEventChar_NONE
|
||||
#define _ModuleConfig_CannedMessageConfig_InputEventChar_MAX ModuleConfig_CannedMessageConfig_InputEventChar_BACK
|
||||
|
||||
@@ -75,12 +75,12 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
|
||||
ResourceNode *nodeAPIv1ToRadio = new ResourceNode("/api/v1/toradio", "PUT", &handleAPIv1ToRadio);
|
||||
ResourceNode *nodeAPIv1FromRadio = new ResourceNode("/api/v1/fromradio", "GET", &handleAPIv1FromRadio);
|
||||
|
||||
ResourceNode *nodeHotspotApple = new ResourceNode("/hotspot-detect.html", "GET", &handleHotspot);
|
||||
ResourceNode *nodeHotspotAndroid = new ResourceNode("/generate_204", "GET", &handleHotspot);
|
||||
// ResourceNode *nodeHotspotApple = new ResourceNode("/hotspot-detect.html", "GET", &handleHotspot);
|
||||
// ResourceNode *nodeHotspotAndroid = new ResourceNode("/generate_204", "GET", &handleHotspot);
|
||||
|
||||
ResourceNode *nodeAdmin = new ResourceNode("/admin", "GET", &handleAdmin);
|
||||
ResourceNode *nodeAdminSettings = new ResourceNode("/admin/settings", "GET", &handleAdminSettings);
|
||||
ResourceNode *nodeAdminSettingsApply = new ResourceNode("/admin/settings/apply", "POST", &handleAdminSettingsApply);
|
||||
// ResourceNode *nodeAdminSettings = new ResourceNode("/admin/settings", "GET", &handleAdminSettings);
|
||||
// ResourceNode *nodeAdminSettingsApply = new ResourceNode("/admin/settings/apply", "POST", &handleAdminSettingsApply);
|
||||
// ResourceNode *nodeAdminFs = new ResourceNode("/admin/fs", "GET", &handleFs);
|
||||
// ResourceNode *nodeUpdateFs = new ResourceNode("/admin/fs/update", "POST", &handleUpdateFs);
|
||||
// ResourceNode *nodeDeleteFs = new ResourceNode("/admin/fs/delete", "GET", &handleDeleteFsContent);
|
||||
@@ -100,8 +100,8 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
|
||||
secureServer->registerNode(nodeAPIv1ToRadioOptions);
|
||||
secureServer->registerNode(nodeAPIv1ToRadio);
|
||||
secureServer->registerNode(nodeAPIv1FromRadio);
|
||||
secureServer->registerNode(nodeHotspotApple);
|
||||
secureServer->registerNode(nodeHotspotAndroid);
|
||||
// secureServer->registerNode(nodeHotspotApple);
|
||||
// secureServer->registerNode(nodeHotspotAndroid);
|
||||
secureServer->registerNode(nodeRestart);
|
||||
secureServer->registerNode(nodeFormUpload);
|
||||
secureServer->registerNode(nodeJsonScanNetworks);
|
||||
@@ -113,16 +113,16 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
|
||||
// secureServer->registerNode(nodeDeleteFs);
|
||||
secureServer->registerNode(nodeAdmin);
|
||||
// secureServer->registerNode(nodeAdminFs);
|
||||
secureServer->registerNode(nodeAdminSettings);
|
||||
secureServer->registerNode(nodeAdminSettingsApply);
|
||||
// secureServer->registerNode(nodeAdminSettings);
|
||||
// secureServer->registerNode(nodeAdminSettingsApply);
|
||||
secureServer->registerNode(nodeRoot); // This has to be last
|
||||
|
||||
// Insecure nodes
|
||||
insecureServer->registerNode(nodeAPIv1ToRadioOptions);
|
||||
insecureServer->registerNode(nodeAPIv1ToRadio);
|
||||
insecureServer->registerNode(nodeAPIv1FromRadio);
|
||||
insecureServer->registerNode(nodeHotspotApple);
|
||||
insecureServer->registerNode(nodeHotspotAndroid);
|
||||
// insecureServer->registerNode(nodeHotspotApple);
|
||||
// insecureServer->registerNode(nodeHotspotAndroid);
|
||||
insecureServer->registerNode(nodeRestart);
|
||||
insecureServer->registerNode(nodeFormUpload);
|
||||
insecureServer->registerNode(nodeJsonScanNetworks);
|
||||
@@ -134,8 +134,8 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
|
||||
// insecureServer->registerNode(nodeDeleteFs);
|
||||
insecureServer->registerNode(nodeAdmin);
|
||||
// insecureServer->registerNode(nodeAdminFs);
|
||||
insecureServer->registerNode(nodeAdminSettings);
|
||||
insecureServer->registerNode(nodeAdminSettingsApply);
|
||||
// insecureServer->registerNode(nodeAdminSettings);
|
||||
// insecureServer->registerNode(nodeAdminSettingsApply);
|
||||
insecureServer->registerNode(nodeRoot); // This has to be last
|
||||
}
|
||||
|
||||
@@ -251,7 +251,7 @@ void htmlDeleteDir(const char *dirname)
|
||||
std::vector<std::map<char *, char *>> *htmlListDir(std::vector<std::map<char *, char *>> *fileList, const char *dirname,
|
||||
uint8_t levels)
|
||||
{
|
||||
File root = FSCom.open(dirname);
|
||||
File root = FSCom.open(dirname, FILE_O_READ);
|
||||
if (!root) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -264,14 +264,27 @@ std::vector<std::map<char *, char *>> *htmlListDir(std::vector<std::map<char *,
|
||||
while (file) {
|
||||
if (file.isDirectory() && !String(file.name()).endsWith(".")) {
|
||||
if (levels) {
|
||||
#ifdef ARCH_ESP32
|
||||
htmlListDir(fileList, file.path(), levels - 1);
|
||||
#else
|
||||
htmlListDir(fileList, file.name(), levels - 1);
|
||||
#endif
|
||||
file.close();
|
||||
}
|
||||
} else {
|
||||
std::map<char *, char *> thisFileMap;
|
||||
thisFileMap[strdup("size")] = strdup(String(file.size()).c_str());
|
||||
#ifdef ARCH_ESP32
|
||||
thisFileMap[strdup("name")] = strdup(String(file.path()).substring(1).c_str());
|
||||
#else
|
||||
thisFileMap[strdup("name")] = strdup(String(file.name()).substring(1).c_str());
|
||||
#endif
|
||||
if (String(file.name()).substring(1).endsWith(".gz")) {
|
||||
#ifdef ARCH_ESP32
|
||||
String modifiedFile = String(file.path()).substring(1);
|
||||
#else
|
||||
String modifiedFile = String(file.name()).substring(1);
|
||||
#endif
|
||||
modifiedFile.remove((modifiedFile.length() - 3), 3);
|
||||
thisFileMap[strdup("nameModified")] = strdup(modifiedFile.c_str());
|
||||
}
|
||||
@@ -291,7 +304,7 @@ void handleFsBrowseStatic(HTTPRequest *req, HTTPResponse *res)
|
||||
res->setHeader("Access-Control-Allow-Methods", "GET");
|
||||
|
||||
using namespace json11;
|
||||
auto fileList = htmlListDir(new std::vector<std::map<char *, char *>>(), "/", 10);
|
||||
auto fileList = htmlListDir(new std::vector<std::map<char *, char *>>(), "/static", 10);
|
||||
|
||||
// create json output structure
|
||||
Json filesystemObj = Json::object{
|
||||
@@ -607,12 +620,8 @@ void handleReport(HTTPRequest *req, HTTPResponse *res)
|
||||
};
|
||||
|
||||
// data->wifi
|
||||
String ipStr;
|
||||
if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT || config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN || isSoftAPForced()) {
|
||||
ipStr = String(WiFi.softAPIP().toString());
|
||||
} else {
|
||||
ipStr = String(WiFi.localIP().toString());
|
||||
}
|
||||
String ipStr = String(WiFi.localIP().toString());
|
||||
|
||||
Json jsonObjWifi = Json::object{{"rssi", String(WiFi.RSSI())}, {"ip", ipStr.c_str()}};
|
||||
|
||||
// data->memory
|
||||
@@ -694,8 +703,8 @@ void handleAdmin(HTTPRequest *req, HTTPResponse *res)
|
||||
res->setHeader("Access-Control-Allow-Methods", "GET");
|
||||
|
||||
res->println("<h1>Meshtastic</h1>\n");
|
||||
res->println("<a href=/admin/settings>Settings</a><br>\n");
|
||||
res->println("<a href=/admin/fs>Manage Web Content</a><br>\n");
|
||||
// res->println("<a href=/admin/settings>Settings</a><br>\n");
|
||||
// res->println("<a href=/admin/fs>Manage Web Content</a><br>\n");
|
||||
res->println("<a href=/json/report>Device Report</a><br>\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -55,10 +55,6 @@ static void handleWebResponse()
|
||||
if (isWifiAvailable()) {
|
||||
|
||||
if (isWebServerReady) {
|
||||
// We're going to handle the DNS responder here so it
|
||||
// will be ignored by the NRF boards.
|
||||
handleDNSResponse();
|
||||
|
||||
if (secureServer)
|
||||
secureServer->loop();
|
||||
insecureServer->loop();
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "mesh/wifi/WiFiServerAPI.h"
|
||||
#include "mqtt/MQTT.h"
|
||||
#include "target_specific.h"
|
||||
#include <DNSServer.h>
|
||||
#include <ESPmDNS.h>
|
||||
#include <esp_wifi.h>
|
||||
#include <WiFi.h>
|
||||
@@ -22,9 +21,6 @@ using namespace concurrency;
|
||||
|
||||
static void WiFiEvent(WiFiEvent_t event);
|
||||
|
||||
// DNS Server for the Captive Portal
|
||||
DNSServer dnsServer;
|
||||
|
||||
// NTP
|
||||
WiFiUDP ntpUDP;
|
||||
|
||||
@@ -37,46 +33,29 @@ uint8_t wifiDisconnectReason = 0;
|
||||
// Stores our hostname
|
||||
char ourHost[16];
|
||||
|
||||
bool forcedSoftAP = 0;
|
||||
|
||||
bool APStartupComplete = 0;
|
||||
|
||||
static bool needReconnect = true; // If we create our reconnector, run it once at the beginning
|
||||
|
||||
// FIXME, veto light sleep if we have a TCP server running
|
||||
#if 0
|
||||
class WifiSleepObserver : public Observer<uint32_t> {
|
||||
protected:
|
||||
|
||||
/// Return 0 if sleep is okay
|
||||
virtual int onNotify(uint32_t newValue) {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
static WifiSleepObserver wifiSleepObserver;
|
||||
//preflightSleepObserver.observe(&preflightSleep);
|
||||
#endif
|
||||
|
||||
static int32_t reconnectWiFi()
|
||||
{
|
||||
const char *wifiName = config.network.wifi_ssid;
|
||||
const char *wifiPsw = config.network.wifi_psk;
|
||||
|
||||
if (config.network.wifi_enabled && needReconnect && !WiFi.isConnected()) {
|
||||
// if (radioConfig.has_preferences && needReconnect && !WiFi.isConnected()) {
|
||||
|
||||
|
||||
if (!*wifiPsw) // Treat empty password as no password
|
||||
wifiPsw = NULL;
|
||||
|
||||
if (*wifiName) {
|
||||
needReconnect = false;
|
||||
|
||||
// Make sure we clear old connection credentials
|
||||
WiFi.disconnect(false, true);
|
||||
|
||||
DEBUG_MSG("... Reconnecting to WiFi access point\n");
|
||||
WiFi.mode(WIFI_MODE_STA);
|
||||
WiFi.begin(wifiName, wifiPsw);
|
||||
|
||||
// Starting timeClient;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,16 +82,10 @@ static int32_t reconnectWiFi()
|
||||
|
||||
static Periodic *wifiReconnect;
|
||||
|
||||
bool isSoftAPForced()
|
||||
{
|
||||
return forcedSoftAP;
|
||||
}
|
||||
|
||||
bool isWifiAvailable()
|
||||
{
|
||||
|
||||
if (config.network.wifi_enabled && ((config.network.wifi_ssid[0]) || forcedSoftAP)) {
|
||||
|
||||
if (config.network.wifi_enabled && (config.network.wifi_ssid[0])) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@@ -176,100 +149,48 @@ static void onNetworkConnected()
|
||||
}
|
||||
|
||||
// Startup WiFi
|
||||
bool initWifi(bool forceSoftAP)
|
||||
bool initWifi()
|
||||
{
|
||||
forcedSoftAP = forceSoftAP;
|
||||
if (config.network.wifi_enabled && config.network.wifi_ssid[0]) {
|
||||
|
||||
if (config.network.wifi_enabled && ((config.network.wifi_ssid[0]) || forceSoftAP)) {
|
||||
// if ((radioConfig.has_preferences && config.wifi.ssid[0]) || forceSoftAP) {
|
||||
const char *wifiName = config.network.wifi_ssid;
|
||||
const char *wifiPsw = config.network.wifi_psk;
|
||||
|
||||
if (forceSoftAP) {
|
||||
DEBUG_MSG("WiFi ... Forced AP Mode\n");
|
||||
} else if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT) {
|
||||
DEBUG_MSG("WiFi ... AP Mode\n");
|
||||
} else if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN) {
|
||||
DEBUG_MSG("WiFi ... Hidden AP Mode\n");
|
||||
} else if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_CLIENT) {
|
||||
DEBUG_MSG("WiFi ... Client Mode\n");
|
||||
} else {
|
||||
DEBUG_MSG("WiFi ... WiFi Disabled\n");
|
||||
}
|
||||
|
||||
createSSLCert();
|
||||
|
||||
if (!*wifiPsw) // Treat empty password as no password
|
||||
wifiPsw = NULL;
|
||||
|
||||
if (*wifiName || forceSoftAP) {
|
||||
if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT || config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN || forceSoftAP) {
|
||||
if (*wifiName) {
|
||||
uint8_t dmac[6];
|
||||
getMacAddr(dmac);
|
||||
sprintf(ourHost, "Meshtastic-%02x%02x", dmac[4], dmac[5]);
|
||||
|
||||
IPAddress apIP(192, 168, 42, 1);
|
||||
WiFi.onEvent(WiFiEvent);
|
||||
WiFi.mode(WIFI_AP);
|
||||
WiFi.mode(WIFI_MODE_STA);
|
||||
WiFi.setHostname(ourHost);
|
||||
WiFi.onEvent(WiFiEvent);
|
||||
|
||||
if (forcedSoftAP) {
|
||||
const char *softAPssid = "meshtasticAdmin";
|
||||
const char *softAPpasswd = "12345678";
|
||||
int ok = WiFi.softAP(softAPssid, softAPpasswd);
|
||||
DEBUG_MSG("Starting (Forced) WIFI AP: ssid=%s, ok=%d\n", softAPssid, ok);
|
||||
// This is needed to improve performance.
|
||||
esp_wifi_set_ps(WIFI_PS_NONE); // Disable radio power saving
|
||||
|
||||
} else {
|
||||
WiFi.onEvent(
|
||||
[](WiFiEvent_t event, WiFiEventInfo_t info) {
|
||||
Serial.print("\nWiFi lost connection. Reason: ");
|
||||
Serial.println(info.wifi_sta_disconnected.reason);
|
||||
|
||||
// If AP is configured to be hidden hidden
|
||||
if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN) {
|
||||
/*
|
||||
If we are disconnected from the AP for some reason,
|
||||
save the error code.
|
||||
|
||||
// The configurations on softAP are from the espresif library
|
||||
int ok = WiFi.softAP(wifiName, wifiPsw, 1, 1, 4);
|
||||
DEBUG_MSG("Starting hidden WIFI AP: ssid=%s, ok=%d\n", wifiName, ok);
|
||||
} else {
|
||||
int ok = WiFi.softAP(wifiName, wifiPsw);
|
||||
DEBUG_MSG("Starting WIFI AP: ssid=%s, ok=%d\n", wifiName, ok);
|
||||
}
|
||||
int ok = WiFi.softAP(wifiName, wifiPsw);
|
||||
DEBUG_MSG("Starting WIFI AP: ssid=%s, ok=%d\n", wifiName, ok);
|
||||
}
|
||||
For a reference to the codes:
|
||||
https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html#wi-fi-reason-code
|
||||
*/
|
||||
wifiDisconnectReason = info.wifi_sta_disconnected.reason;
|
||||
},
|
||||
WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_DISCONNECTED);
|
||||
|
||||
WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
|
||||
DEBUG_MSG("MY IP AP ADDRESS: %s\n", WiFi.softAPIP().toString().c_str());
|
||||
|
||||
// This is needed to improve performance.
|
||||
esp_wifi_set_ps(WIFI_PS_NONE); // Disable radio power saving
|
||||
|
||||
dnsServer.start(53, "*", apIP);
|
||||
|
||||
} else {
|
||||
uint8_t dmac[6];
|
||||
getMacAddr(dmac);
|
||||
sprintf(ourHost, "Meshtastic-%02x%02x", dmac[4], dmac[5]);
|
||||
|
||||
WiFi.mode(WIFI_MODE_STA);
|
||||
WiFi.setHostname(ourHost);
|
||||
WiFi.onEvent(WiFiEvent);
|
||||
|
||||
// This is needed to improve performance.
|
||||
esp_wifi_set_ps(WIFI_PS_NONE); // Disable radio power saving
|
||||
|
||||
WiFi.onEvent(
|
||||
[](WiFiEvent_t event, WiFiEventInfo_t info) {
|
||||
Serial.print("\nWiFi lost connection. Reason: ");
|
||||
Serial.println(info.wifi_sta_disconnected.reason);
|
||||
|
||||
/*
|
||||
If we are disconnected from the AP for some reason,
|
||||
save the error code.
|
||||
|
||||
For a reference to the codes:
|
||||
https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html#wi-fi-reason-code
|
||||
*/
|
||||
wifiDisconnectReason = info.wifi_sta_disconnected.reason;
|
||||
},
|
||||
WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_DISCONNECTED);
|
||||
|
||||
DEBUG_MSG("JOINING WIFI soon: ssid=%s\n", wifiName);
|
||||
wifiReconnect = new Periodic("WifiConnect", reconnectWiFi);
|
||||
}
|
||||
DEBUG_MSG("JOINING WIFI soon: ssid=%s\n", wifiName);
|
||||
wifiReconnect = new Periodic("WifiConnect", reconnectWiFi);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
@@ -371,13 +292,6 @@ static void WiFiEvent(WiFiEvent_t event)
|
||||
}
|
||||
}
|
||||
|
||||
void handleDNSResponse()
|
||||
{
|
||||
if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT || config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN || isSoftAPForced()) {
|
||||
dnsServer.processNextRequest();
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t getWifiDisconnectReason()
|
||||
{
|
||||
return wifiDisconnectReason;
|
||||
|
||||
@@ -5,19 +5,14 @@
|
||||
#include <functional>
|
||||
|
||||
#ifdef ARCH_ESP32
|
||||
#include <DNSServer.h>
|
||||
#include <WiFi.h>
|
||||
#endif
|
||||
|
||||
/// @return true if wifi is now in use
|
||||
bool initWifi(bool forceSoftAP);
|
||||
bool initWifi();
|
||||
|
||||
void deinitWifi();
|
||||
|
||||
bool isWifiAvailable();
|
||||
|
||||
void handleDNSResponse();
|
||||
|
||||
bool isSoftAPForced();
|
||||
|
||||
uint8_t getWifiDisconnectReason();
|
||||
|
||||
@@ -101,9 +101,7 @@ bool AdminModule::handleReceivedProtobuf(const MeshPacket &mp, AdminMessage *r)
|
||||
* Other
|
||||
*/
|
||||
case AdminMessage_reboot_seconds_tag: {
|
||||
int32_t s = r->reboot_seconds;
|
||||
DEBUG_MSG("Rebooting in %d seconds\n", s);
|
||||
rebootAtMsec = (s < 0) ? 0 : (millis() + s * 1000);
|
||||
reboot(r->reboot_seconds);
|
||||
break;
|
||||
}
|
||||
case AdminMessage_reboot_ota_seconds_tag: {
|
||||
@@ -135,13 +133,13 @@ bool AdminModule::handleReceivedProtobuf(const MeshPacket &mp, AdminMessage *r)
|
||||
case AdminMessage_factory_reset_tag: {
|
||||
DEBUG_MSG("Initiating factory reset\n");
|
||||
nodeDB.factoryReset();
|
||||
rebootAtMsec = millis() + (5 * 1000);
|
||||
reboot(5);
|
||||
break;
|
||||
}
|
||||
case AdminMessage_nodedb_reset_tag: {
|
||||
DEBUG_MSG("Initiating node-db reset\n");
|
||||
nodeDB.resetNodes();
|
||||
rebootAtMsec = millis() + (5 * 1000);
|
||||
reboot(5);
|
||||
break;
|
||||
}
|
||||
#ifdef ARCH_PORTDUINO
|
||||
@@ -196,14 +194,12 @@ void AdminModule::handleSetOwner(const User &o)
|
||||
if (changed) { // If nothing really changed, don't broadcast on the network or write to flash
|
||||
service.reloadOwner();
|
||||
DEBUG_MSG("Rebooting due to owner changes\n");
|
||||
screen->startRebootScreen();
|
||||
rebootAtMsec = millis() + (5 * 1000);
|
||||
reboot(5);
|
||||
}
|
||||
}
|
||||
|
||||
void AdminModule::handleSetConfig(const Config &c)
|
||||
{
|
||||
bool requiresReboot = false;
|
||||
bool isRouter = (config.device.role == Config_DeviceConfig_Role_ROUTER);
|
||||
bool isRegionUnset = (config.lora.region == Config_LoRaConfig_RegionCode_UNSET);
|
||||
|
||||
@@ -218,12 +214,13 @@ void AdminModule::handleSetConfig(const Config &c)
|
||||
nodeDB.initConfigIntervals();
|
||||
nodeDB.initModuleConfigIntervals();
|
||||
}
|
||||
requiresReboot = true;
|
||||
break;
|
||||
case Config_position_tag:
|
||||
DEBUG_MSG("Setting config: Position\n");
|
||||
config.has_position = true;
|
||||
config.position = c.payload_variant.position;
|
||||
// Save nodedb as well in case we got a fixed position packet
|
||||
nodeDB.saveToDisk(SEGMENT_DEVICESTATE);
|
||||
break;
|
||||
case Config_power_tag:
|
||||
DEBUG_MSG("Setting config: Power\n");
|
||||
@@ -234,7 +231,6 @@ void AdminModule::handleSetConfig(const Config &c)
|
||||
DEBUG_MSG("Setting config: WiFi\n");
|
||||
config.has_network = true;
|
||||
config.network = c.payload_variant.network;
|
||||
requiresReboot = true;
|
||||
break;
|
||||
case Config_display_tag:
|
||||
DEBUG_MSG("Setting config: Display\n");
|
||||
@@ -249,23 +245,16 @@ void AdminModule::handleSetConfig(const Config &c)
|
||||
config.lora.region > Config_LoRaConfig_RegionCode_UNSET) {
|
||||
config.lora.tx_enabled = true;
|
||||
}
|
||||
requiresReboot = true;
|
||||
break;
|
||||
case Config_bluetooth_tag:
|
||||
DEBUG_MSG("Setting config: Bluetooth\n");
|
||||
config.has_bluetooth = true;
|
||||
config.bluetooth = c.payload_variant.bluetooth;
|
||||
requiresReboot = true;
|
||||
break;
|
||||
}
|
||||
|
||||
service.reloadConfig(SEGMENT_CONFIG);
|
||||
// Reboot 5 seconds after a config that requires rebooting is set
|
||||
if (requiresReboot) {
|
||||
DEBUG_MSG("Rebooting due to config changes\n");
|
||||
screen->startRebootScreen();
|
||||
rebootAtMsec = millis() + (5 * 1000);
|
||||
}
|
||||
reboot(5);
|
||||
}
|
||||
|
||||
void AdminModule::handleSetModuleConfig(const ModuleConfig &c)
|
||||
@@ -307,8 +296,9 @@ void AdminModule::handleSetModuleConfig(const ModuleConfig &c)
|
||||
moduleConfig.canned_message = c.payload_variant.canned_message;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
service.reloadConfig(SEGMENT_MODULECONFIG);
|
||||
reboot(5);
|
||||
}
|
||||
|
||||
void AdminModule::handleSetChannel(const Channel &cc)
|
||||
@@ -468,6 +458,13 @@ void AdminModule::handleGetChannel(const MeshPacket &req, uint32_t channelIndex)
|
||||
}
|
||||
}
|
||||
|
||||
void AdminModule::reboot(int32_t seconds)
|
||||
{
|
||||
DEBUG_MSG("Rebooting in %d seconds\n", seconds);
|
||||
screen->startRebootScreen();
|
||||
rebootAtMsec = (seconds < 0) ? 0 : (millis() + seconds * 1000);
|
||||
}
|
||||
|
||||
AdminModule::AdminModule() : ProtobufModule("Admin", PortNum_ADMIN_APP, AdminMessage_fields)
|
||||
{
|
||||
// restrict to the admin channel for rx
|
||||
|
||||
@@ -37,6 +37,7 @@ class AdminModule : public ProtobufModule<AdminMessage>
|
||||
void handleSetConfig(const Config &c);
|
||||
void handleSetModuleConfig(const ModuleConfig &c);
|
||||
void handleSetChannel();
|
||||
void reboot(int32_t seconds);
|
||||
};
|
||||
|
||||
extern AdminModule *adminModule;
|
||||
|
||||
@@ -225,7 +225,7 @@ int32_t CannedMessageModule::runOnce()
|
||||
this->cursor = 0;
|
||||
this->destSelect = false;
|
||||
this->notifyObservers(&e);
|
||||
} else if (((this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT)) && (millis() - this->lastTouchMillis) > INACTIVATE_AFTER_MS) {
|
||||
} else if (((this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT)) && ((millis() - this->lastTouchMillis) > INACTIVATE_AFTER_MS)) {
|
||||
// Reset module
|
||||
DEBUG_MSG("Reset due to lack of activity.\n");
|
||||
e.frameChanged = true;
|
||||
@@ -430,6 +430,8 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
|
||||
{
|
||||
displayedNodeNum = 0; // Not currently showing a node pane
|
||||
|
||||
char buffer[50];
|
||||
|
||||
if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE) {
|
||||
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
||||
display->setFont(FONT_MEDIUM);
|
||||
@@ -445,7 +447,6 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
|
||||
display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
|
||||
display->setColor(BLACK);
|
||||
}
|
||||
char buffer[50];
|
||||
display->drawStringf(0 + x, 0 + y, buffer, "To: %s", cannedMessageModule->getNodeName(this->dest));
|
||||
// used chars right aligned
|
||||
sprintf(buffer, "%d left", Constants_DATA_PAYLOAD_LEN - this->freetext.length());
|
||||
@@ -456,11 +457,13 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
|
||||
if (this->messagesCount > 0) {
|
||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
display->setFont(FONT_SMALL);
|
||||
display->drawString(0 + x, 0 + y, cannedMessageModule->getPrevMessage());
|
||||
display->setFont(FONT_MEDIUM);
|
||||
display->drawString(0 + x, 0 + y + FONT_HEIGHT_SMALL, cannedMessageModule->getCurrentMessage());
|
||||
display->setFont(FONT_SMALL);
|
||||
display->drawString(0 + x, 0 + y + FONT_HEIGHT_MEDIUM, cannedMessageModule->getNextMessage());
|
||||
display->drawStringf(0 + x, 0 + y, buffer, "To: %s", cannedMessageModule->getNodeName(this->dest));
|
||||
display->drawString(0 + x, 0 + y + FONT_HEIGHT_SMALL, cannedMessageModule->getPrevMessage());
|
||||
display->fillRect(0 + x, 0 + y + FONT_HEIGHT_SMALL * 2, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
|
||||
display->setColor(BLACK);
|
||||
display->drawString(0 + x, 0 + y + FONT_HEIGHT_SMALL * 2, cannedMessageModule->getCurrentMessage());
|
||||
display->setColor(WHITE);
|
||||
display->drawString(0 + x, 0 + y + FONT_HEIGHT_SMALL * 3, cannedMessageModule->getNextMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,4 +87,4 @@ class CannedMessageModule :
|
||||
};
|
||||
|
||||
extern CannedMessageModule *cannedMessageModule;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -3,9 +3,14 @@
|
||||
#include "NodeDB.h"
|
||||
#include "RTC.h"
|
||||
#include "Router.h"
|
||||
#include "buzz/buzz.h"
|
||||
#include "configuration.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
#ifndef PIN_BUZZER
|
||||
#define PIN_BUZZER false
|
||||
#endif
|
||||
|
||||
//#include <assert.h>
|
||||
|
||||
/*
|
||||
@@ -44,7 +49,11 @@
|
||||
*/
|
||||
|
||||
// Default configurations
|
||||
#ifdef EXT_NOTIFY_OUT
|
||||
#define EXT_NOTIFICATION_MODULE_OUTPUT EXT_NOTIFY_OUT
|
||||
#else
|
||||
#define EXT_NOTIFICATION_MODULE_OUTPUT 0
|
||||
#endif
|
||||
#define EXT_NOTIFICATION_MODULE_OUTPUT_MS 1000
|
||||
|
||||
#define ASCII_BELL 0x07
|
||||
@@ -75,7 +84,9 @@ int32_t ExternalNotificationModule::runOnce()
|
||||
: EXT_NOTIFICATION_MODULE_OUTPUT_MS) <
|
||||
millis()) {
|
||||
DEBUG_MSG("Turning off external notification\n");
|
||||
setExternalOff();
|
||||
if (output != PIN_BUZZER) {
|
||||
setExternalOff();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,27 +95,19 @@ int32_t ExternalNotificationModule::runOnce()
|
||||
|
||||
void ExternalNotificationModule::setExternalOn()
|
||||
{
|
||||
#ifdef EXT_NOTIFY_OUT
|
||||
externalCurrentState = 1;
|
||||
externalTurnedOn = millis();
|
||||
|
||||
digitalWrite((moduleConfig.external_notification.output
|
||||
? moduleConfig.external_notification.output
|
||||
: EXT_NOTIFICATION_MODULE_OUTPUT),
|
||||
digitalWrite(output,
|
||||
(moduleConfig.external_notification.active ? true : false));
|
||||
#endif
|
||||
}
|
||||
|
||||
void ExternalNotificationModule::setExternalOff()
|
||||
{
|
||||
#ifdef EXT_NOTIFY_OUT
|
||||
externalCurrentState = 0;
|
||||
|
||||
digitalWrite((moduleConfig.external_notification.output
|
||||
? moduleConfig.external_notification.output
|
||||
: EXT_NOTIFICATION_MODULE_OUTPUT),
|
||||
digitalWrite(output,
|
||||
(moduleConfig.external_notification.active ? false : true));
|
||||
#endif
|
||||
}
|
||||
|
||||
// --------
|
||||
@@ -116,8 +119,6 @@ ExternalNotificationModule::ExternalNotificationModule()
|
||||
// restrict to the admin channel for rx
|
||||
boundChannel = Channels::gpioChannel;
|
||||
|
||||
#ifdef EXT_NOTIFY_OUT
|
||||
|
||||
/*
|
||||
Uncomment the preferences below if you want to use the module
|
||||
without having to configure it from the PythonAPI or WebUI.
|
||||
@@ -135,25 +136,27 @@ ExternalNotificationModule::ExternalNotificationModule()
|
||||
|
||||
DEBUG_MSG("Initializing External Notification Module\n");
|
||||
|
||||
// Set the direction of a pin
|
||||
pinMode((moduleConfig.external_notification.output
|
||||
? moduleConfig.external_notification.output
|
||||
: EXT_NOTIFICATION_MODULE_OUTPUT),
|
||||
OUTPUT);
|
||||
output = moduleConfig.external_notification.output
|
||||
? moduleConfig.external_notification.output
|
||||
: EXT_NOTIFICATION_MODULE_OUTPUT;
|
||||
|
||||
// Turn off the pin
|
||||
setExternalOff();
|
||||
if (output != PIN_BUZZER) {
|
||||
// Set the direction of a pin
|
||||
DEBUG_MSG("Using Pin %i in digital mode\n", output);
|
||||
pinMode(output, OUTPUT);
|
||||
// Turn off the pin
|
||||
setExternalOff();
|
||||
} else{
|
||||
DEBUG_MSG("Using Pin %i in PWM mode\n", output);
|
||||
}
|
||||
} else {
|
||||
DEBUG_MSG("External Notification Module Disabled\n");
|
||||
enabled = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
ProcessMessage ExternalNotificationModule::handleReceived(const MeshPacket &mp)
|
||||
{
|
||||
#ifdef EXT_NOTIFY_OUT
|
||||
|
||||
if (moduleConfig.external_notification.enabled) {
|
||||
|
||||
if (getFrom(&mp) != nodeDB.getNodeNum()) {
|
||||
@@ -165,21 +168,28 @@ ProcessMessage ExternalNotificationModule::handleReceived(const MeshPacket &mp)
|
||||
DEBUG_MSG("externalNotificationModule - Notification Bell\n");
|
||||
for (int i = 0; i < p.payload.size; i++) {
|
||||
if (p.payload.bytes[i] == ASCII_BELL) {
|
||||
setExternalOn();
|
||||
if (output != PIN_BUZZER) {
|
||||
setExternalOn();
|
||||
} else {
|
||||
playBeep();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (moduleConfig.external_notification.alert_message) {
|
||||
DEBUG_MSG("externalNotificationModule - Notification Module\n");
|
||||
setExternalOn();
|
||||
if (output != PIN_BUZZER) {
|
||||
setExternalOn();
|
||||
} else {
|
||||
playBeep();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
DEBUG_MSG("External Notification Module Disabled\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
return ProcessMessage::CONTINUE; // Let others look at this message also if they want
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
*/
|
||||
class ExternalNotificationModule : public SinglePortModule, private concurrency::OSThread
|
||||
{
|
||||
uint32_t output = 0;
|
||||
|
||||
public:
|
||||
ExternalNotificationModule();
|
||||
|
||||
|
||||
@@ -60,13 +60,15 @@ void setupModules()
|
||||
new DeviceTelemetryModule();
|
||||
new EnvironmentTelemetryModule();
|
||||
#endif
|
||||
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(TTGO_T_ECHO)
|
||||
new SerialModule();
|
||||
#endif
|
||||
#ifdef ARCH_ESP32
|
||||
// Only run on an esp32 based device.
|
||||
|
||||
/*
|
||||
Maintained by MC Hamster (Jm Casler) jm@casler.org
|
||||
*/
|
||||
new SerialModule();
|
||||
new ExternalNotificationModule();
|
||||
|
||||
storeForwardModule = new StoreForwardModule();
|
||||
|
||||
@@ -108,7 +108,7 @@ MeshPacket *PositionModule::allocReply()
|
||||
// Strip out any time information before sending packets to other nodes - to keep the wire size small (and because other
|
||||
// nodes shouldn't trust it anyways) Note: we allow a device with a local GPS to include the time, so that gpsless
|
||||
// devices can get time.
|
||||
if (getRTCQuality() < RTCQualityGPS) {
|
||||
if (getRTCQuality() < RTCQualityDevice) {
|
||||
DEBUG_MSG("Stripping time %u from position send\n", p.time);
|
||||
p.time = 0;
|
||||
} else
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "MeshService.h"
|
||||
#include "NodeDB.h"
|
||||
#include "RTC.h"
|
||||
#include "NMEAWPL.h"
|
||||
#include "Router.h"
|
||||
#include "configuration.h"
|
||||
#include <Arduino.h>
|
||||
@@ -40,7 +41,7 @@
|
||||
KNOWN PROBLEMS
|
||||
* Until the module is initilized by the startup sequence, the TX pin is in a floating
|
||||
state. Device connected to that pin may see this as "noise".
|
||||
* Will not work on NRF and the Linux device targets.
|
||||
* Will not work on T-Echo and the Linux device targets.
|
||||
|
||||
|
||||
*/
|
||||
@@ -62,16 +63,19 @@ char serialStringChar[Constants_DATA_PAYLOAD_LEN];
|
||||
|
||||
SerialModuleRadio::SerialModuleRadio() : MeshModule("SerialModuleRadio")
|
||||
{
|
||||
// restrict to the admin channel for rx
|
||||
boundChannel = Channels::serialChannel;
|
||||
|
||||
switch (moduleConfig.serial.mode)
|
||||
{
|
||||
case ModuleConfig_SerialConfig_Serial_Mode_TEXTMSG:
|
||||
ourPortNum = PortNum_TEXT_MESSAGE_APP;
|
||||
break;
|
||||
case ModuleConfig_SerialConfig_Serial_Mode_NMEA:
|
||||
ourPortNum = PortNum_POSITION_APP;
|
||||
break;
|
||||
default:
|
||||
ourPortNum = PortNum_SERIAL_APP;
|
||||
// restrict to the serial channel for rx
|
||||
boundChannel = Channels::serialChannel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -175,15 +179,25 @@ int32_t SerialModule::runOnce()
|
||||
firstTime = 0;
|
||||
|
||||
} else {
|
||||
String serialString;
|
||||
|
||||
while (Serial2.available()) {
|
||||
serialString = Serial2.readString();
|
||||
serialString.toCharArray(serialStringChar, Constants_DATA_PAYLOAD_LEN);
|
||||
// in NMEA mode send out GGA every 2 seconds, Don't read from Port
|
||||
if (moduleConfig.serial.mode == ModuleConfig_SerialConfig_Serial_Mode_NMEA) {
|
||||
if (millis() - lastNmeaTime > 2000) {
|
||||
lastNmeaTime = millis();
|
||||
printGGA(outbuf, nodeDB.getNode(myNodeInfo.my_node_num)->position);
|
||||
Serial2.printf("%s", outbuf);
|
||||
}
|
||||
} else {
|
||||
String serialString;
|
||||
|
||||
serialModuleRadio->sendPayload();
|
||||
while (Serial2.available()) {
|
||||
serialString = Serial2.readString();
|
||||
serialString.toCharArray(serialStringChar, Constants_DATA_PAYLOAD_LEN);
|
||||
|
||||
DEBUG_MSG("Received: %s\n", serialStringChar);
|
||||
serialModuleRadio->sendPayload();
|
||||
|
||||
DEBUG_MSG("Received: %s\n", serialStringChar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,7 +205,7 @@ int32_t SerialModule::runOnce()
|
||||
} else {
|
||||
DEBUG_MSG("Serial Module Disabled\n");
|
||||
|
||||
return (INT32_MAX);
|
||||
return INT32_MAX;
|
||||
}
|
||||
#else
|
||||
return INT32_MAX;
|
||||
@@ -255,6 +269,19 @@ ProcessMessage SerialModuleRadio::handleReceived(const MeshPacket &mp)
|
||||
|
||||
} else if (moduleConfig.serial.mode == ModuleConfig_SerialConfig_Serial_Mode_PROTO) {
|
||||
// TODO this needs to be implemented
|
||||
} else if (moduleConfig.serial.mode == ModuleConfig_SerialConfig_Serial_Mode_NMEA) {
|
||||
// Decode the Payload some more
|
||||
Position scratch;
|
||||
Position *decoded = NULL;
|
||||
if (mp.which_payload_variant == MeshPacket_decoded_tag && mp.decoded.portnum == ourPortNum) {
|
||||
memset(&scratch, 0, sizeof(scratch));
|
||||
if (pb_decode_from_bytes(p.payload.bytes, p.payload.size, Position_fields, &scratch)) {
|
||||
decoded = &scratch;
|
||||
}
|
||||
// send position packet as WPL to the serial port
|
||||
printWPL(outbuf, *decoded, nodeDB.getNode(getFrom(&mp))->user.long_name);
|
||||
Serial2.printf("%s", outbuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
class SerialModule : private concurrency::OSThread
|
||||
{
|
||||
bool firstTime = 1;
|
||||
unsigned long lastNmeaTime = millis();
|
||||
char outbuf[90] = "";
|
||||
|
||||
public:
|
||||
SerialModule();
|
||||
@@ -28,6 +30,7 @@ extern SerialModule *serialModule;
|
||||
class SerialModuleRadio : public MeshModule
|
||||
{
|
||||
uint32_t lastRxID = 0;
|
||||
char outbuf[90] = "";
|
||||
|
||||
public:
|
||||
SerialModuleRadio();
|
||||
|
||||
@@ -9,17 +9,20 @@
|
||||
#include "main.h"
|
||||
#include <OLEDDisplay.h>
|
||||
#include <OLEDDisplayUi.h>
|
||||
#include "MeshService.h"
|
||||
|
||||
int32_t DeviceTelemetryModule::runOnce()
|
||||
{
|
||||
#ifndef ARCH_PORTDUINO
|
||||
uint32_t now = millis();
|
||||
if ((lastSentToMesh == 0 || (now - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.telemetry.device_update_interval))
|
||||
&& airTime->channelUtilizationPercent() < max_channel_util_percent) {
|
||||
if ((lastSentToMesh == 0 ||
|
||||
(now - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.telemetry.device_update_interval)) &&
|
||||
airTime->channelUtilizationPercent() < max_channel_util_percent) {
|
||||
sendTelemetry();
|
||||
lastSentToMesh = now;
|
||||
} else {
|
||||
} else if (service.isToPhoneQueueEmpty()) {
|
||||
// Just send to phone when it's not our time to send to mesh yet
|
||||
// Only send while queue is empty (phone assumed connected)
|
||||
sendTelemetry(NODENUM_BROADCAST, true);
|
||||
}
|
||||
return sendToPhoneIntervalMs;
|
||||
@@ -30,14 +33,13 @@ bool DeviceTelemetryModule::handleReceivedProtobuf(const MeshPacket &mp, Telemet
|
||||
{
|
||||
if (t->which_variant == Telemetry_device_metrics_tag) {
|
||||
const char *sender = getSenderShortName(mp);
|
||||
|
||||
DEBUG_MSG("-----------------------------------------\n");
|
||||
DEBUG_MSG("Device Telemetry: Received data from %s\n", sender);
|
||||
DEBUG_MSG("Telemetry->time: %i\n", t->time);
|
||||
DEBUG_MSG("Telemetry->air_util_tx: %f\n", t->variant.device_metrics.air_util_tx);
|
||||
DEBUG_MSG("Telemetry->battery_level: %i\n", t->variant.device_metrics.battery_level);
|
||||
DEBUG_MSG("Telemetry->channel_utilization: %f\n", t->variant.device_metrics.channel_utilization);
|
||||
DEBUG_MSG("Telemetry->voltage: %f\n", t->variant.device_metrics.voltage);
|
||||
|
||||
DEBUG_MSG("(Received from %s): air_util_tx=%f, channel_utilization=%f, battery_level=%i, voltage=%f\n",
|
||||
sender,
|
||||
t->variant.device_metrics.air_util_tx,
|
||||
t->variant.device_metrics.channel_utilization,
|
||||
t->variant.device_metrics.battery_level,
|
||||
t->variant.device_metrics.voltage);
|
||||
|
||||
lastMeasurementPacket = packetPool.allocCopy(mp);
|
||||
|
||||
@@ -58,26 +60,24 @@ bool DeviceTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
|
||||
t.variant.device_metrics.channel_utilization = myNodeInfo.channel_utilization;
|
||||
t.variant.device_metrics.voltage = powerStatus->getBatteryVoltageMv() / 1000.0;
|
||||
|
||||
DEBUG_MSG("-----------------------------------------\n");
|
||||
DEBUG_MSG("Device Telemetry: Read data\n");
|
||||
|
||||
DEBUG_MSG("Telemetry->time: %i\n", t.time);
|
||||
DEBUG_MSG("Telemetry->air_util_tx: %f\n", t.variant.device_metrics.air_util_tx);
|
||||
DEBUG_MSG("Telemetry->battery_level: %i\n", t.variant.device_metrics.battery_level);
|
||||
DEBUG_MSG("Telemetry->channel_utilization: %f\n", t.variant.device_metrics.channel_utilization);
|
||||
DEBUG_MSG("Telemetry->voltage: %f\n", t.variant.device_metrics.voltage);
|
||||
DEBUG_MSG("(Sending): air_util_tx=%f, channel_utilization=%f, battery_level=%i, voltage=%f\n",
|
||||
t.variant.device_metrics.air_util_tx,
|
||||
t.variant.device_metrics.channel_utilization,
|
||||
t.variant.device_metrics.battery_level,
|
||||
t.variant.device_metrics.voltage);
|
||||
|
||||
MeshPacket *p = allocDataProtobuf(t);
|
||||
p->to = dest;
|
||||
p->decoded.want_response = false;
|
||||
p->priority = MeshPacket_Priority_MIN;
|
||||
|
||||
lastMeasurementPacket = packetPool.allocCopy(*p);
|
||||
nodeDB.updateTelemetry(nodeDB.getNodeNum(), t, RX_SRC_LOCAL);
|
||||
if (phoneOnly) {
|
||||
DEBUG_MSG("Device Telemetry: Sending packet to phone\n");
|
||||
DEBUG_MSG("Sending packet to phone\n");
|
||||
service.sendToPhone(p);
|
||||
} else {
|
||||
DEBUG_MSG("Device Telemetry: Sending packet to mesh\n");
|
||||
DEBUG_MSG("Sending packet to mesh\n");
|
||||
service.sendToMesh(p, RX_SRC_LOCAL, true);
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -11,7 +11,8 @@ class DeviceTelemetryModule : private concurrency::OSThread, public ProtobufModu
|
||||
DeviceTelemetryModule()
|
||||
: concurrency::OSThread("DeviceTelemetryModule"), ProtobufModule("DeviceTelemetry", PortNum_TELEMETRY_APP, &Telemetry_msg)
|
||||
{
|
||||
lastMeasurementPacket = nullptr;
|
||||
lastMeasurementPacket = nullptr;
|
||||
setIntervalFromNow(10 * 1000);
|
||||
}
|
||||
virtual bool wantUIFrame() { return false; }
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "main.h"
|
||||
#include <OLEDDisplay.h>
|
||||
#include <OLEDDisplayUi.h>
|
||||
#include "MeshService.h"
|
||||
|
||||
// Sensors
|
||||
#include "Sensor/BMP280Sensor.h"
|
||||
@@ -17,6 +18,8 @@
|
||||
#include "Sensor/MCP9808Sensor.h"
|
||||
#include "Sensor/INA260Sensor.h"
|
||||
#include "Sensor/INA219Sensor.h"
|
||||
#include "Sensor/SHTC3Sensor.h"
|
||||
#include "Sensor/LPS22HBSensor.h"
|
||||
|
||||
BMP280Sensor bmp280Sensor;
|
||||
BME280Sensor bme280Sensor;
|
||||
@@ -24,6 +27,8 @@ BME680Sensor bme680Sensor;
|
||||
MCP9808Sensor mcp9808Sensor;
|
||||
INA260Sensor ina260Sensor;
|
||||
INA219Sensor ina219Sensor;
|
||||
SHTC3Sensor shtc3Sensor;
|
||||
LPS22HBSensor lps22hbSensor;
|
||||
|
||||
#define FAILED_STATE_SENSOR_READ_MULTIPLIER 10
|
||||
#define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true
|
||||
@@ -83,21 +88,31 @@ int32_t EnvironmentTelemetryModule::runOnce()
|
||||
result = ina260Sensor.runOnce();
|
||||
if (ina219Sensor.hasSensor())
|
||||
result = ina219Sensor.runOnce();
|
||||
if (shtc3Sensor.hasSensor())
|
||||
result = shtc3Sensor.runOnce();
|
||||
if (lps22hbSensor.hasSensor()) {
|
||||
result = lps22hbSensor.runOnce();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
// if we somehow got to a second run of this module with measurement disabled, then just wait forever
|
||||
if (!moduleConfig.telemetry.environment_measurement_enabled)
|
||||
return result;
|
||||
// this is not the first time OSThread library has called this function
|
||||
// so just do what we intend to do on the interval
|
||||
if (!sendOurTelemetry()) {
|
||||
// if we failed to read the sensor, then try again
|
||||
// as soon as we can according to the maximum polling frequency
|
||||
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
|
||||
|
||||
uint32_t now = millis();
|
||||
if ((lastSentToMesh == 0 ||
|
||||
(now - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.telemetry.environment_update_interval)) &&
|
||||
airTime->channelUtilizationPercent() < max_channel_util_percent) {
|
||||
sendTelemetry();
|
||||
lastSentToMesh = now;
|
||||
} else if (service.isToPhoneQueueEmpty()) {
|
||||
// Just send to phone when it's not our time to send to mesh yet
|
||||
// Only send while queue is empty (phone assumed connected)
|
||||
sendTelemetry(NODENUM_BROADCAST, true);
|
||||
}
|
||||
}
|
||||
return getConfiguredOrDefaultMs(moduleConfig.telemetry.environment_update_interval);
|
||||
return sendToPhoneIntervalMs;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -143,7 +158,7 @@ void EnvironmentTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiSt
|
||||
if (!pb_decode_from_bytes(p.payload.bytes, p.payload.size, Telemetry_fields, &lastMeasurement)) {
|
||||
display->setFont(FONT_SMALL);
|
||||
display->drawString(x, y += fontHeight(FONT_MEDIUM), "Measurement Error");
|
||||
DEBUG_MSG("Environment Telemetry: unable to decode last packet");
|
||||
DEBUG_MSG("Unable to decode last packet");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -168,15 +183,14 @@ bool EnvironmentTelemetryModule::handleReceivedProtobuf(const MeshPacket &mp, Te
|
||||
if (t->which_variant == Telemetry_environment_metrics_tag) {
|
||||
const char *sender = getSenderShortName(mp);
|
||||
|
||||
DEBUG_MSG("-----------------------------------------\n");
|
||||
DEBUG_MSG("Environment Telemetry: Received data from %s\n", sender);
|
||||
DEBUG_MSG("Telemetry->time: %i\n", t->time);
|
||||
DEBUG_MSG("Telemetry->barometric_pressure: %f\n", t->variant.environment_metrics.barometric_pressure);
|
||||
DEBUG_MSG("Telemetry->current: %f\n", t->variant.environment_metrics.current);
|
||||
DEBUG_MSG("Telemetry->gas_resistance: %f\n", t->variant.environment_metrics.gas_resistance);
|
||||
DEBUG_MSG("Telemetry->relative_humidity: %f\n", t->variant.environment_metrics.relative_humidity);
|
||||
DEBUG_MSG("Telemetry->temperature: %f\n", t->variant.environment_metrics.temperature);
|
||||
DEBUG_MSG("Telemetry->voltage: %f\n", t->variant.environment_metrics.voltage);
|
||||
DEBUG_MSG("(Received from %s): barometric_pressure=%f, current=%f, gas_resistance=%f, relative_humidity=%f, temperature=%f, voltage=%f\n",
|
||||
sender,
|
||||
t->variant.environment_metrics.barometric_pressure,
|
||||
t->variant.environment_metrics.current,
|
||||
t->variant.environment_metrics.gas_resistance,
|
||||
t->variant.environment_metrics.relative_humidity,
|
||||
t->variant.environment_metrics.temperature,
|
||||
t->variant.environment_metrics.voltage);
|
||||
|
||||
lastMeasurementPacket = packetPool.allocCopy(mp);
|
||||
}
|
||||
@@ -184,7 +198,7 @@ bool EnvironmentTelemetryModule::handleReceivedProtobuf(const MeshPacket &mp, Te
|
||||
return false; // Let others look at this message also if they want
|
||||
}
|
||||
|
||||
bool EnvironmentTelemetryModule::sendOurTelemetry(NodeNum dest, bool wantReplies)
|
||||
bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
|
||||
{
|
||||
Telemetry m;
|
||||
m.time = getTime();
|
||||
@@ -197,9 +211,10 @@ bool EnvironmentTelemetryModule::sendOurTelemetry(NodeNum dest, bool wantReplies
|
||||
m.variant.environment_metrics.temperature = 0;
|
||||
m.variant.environment_metrics.voltage = 0;
|
||||
|
||||
DEBUG_MSG("-----------------------------------------\n");
|
||||
DEBUG_MSG("Environment Telemetry: Read data\n");
|
||||
|
||||
if (lps22hbSensor.hasSensor())
|
||||
lps22hbSensor.getMetrics(&m);
|
||||
if (shtc3Sensor.hasSensor())
|
||||
shtc3Sensor.getMetrics(&m);
|
||||
if (bmp280Sensor.hasSensor())
|
||||
bmp280Sensor.getMetrics(&m);
|
||||
if (bme280Sensor.hasSensor())
|
||||
@@ -213,22 +228,28 @@ bool EnvironmentTelemetryModule::sendOurTelemetry(NodeNum dest, bool wantReplies
|
||||
if (ina260Sensor.hasSensor())
|
||||
ina260Sensor.getMetrics(&m);
|
||||
|
||||
DEBUG_MSG("Telemetry->time: %i\n", m.time);
|
||||
DEBUG_MSG("Telemetry->barometric_pressure: %f\n", m.variant.environment_metrics.barometric_pressure);
|
||||
DEBUG_MSG("Telemetry->current: %f\n", m.variant.environment_metrics.current);
|
||||
DEBUG_MSG("Telemetry->gas_resistance: %f\n", m.variant.environment_metrics.gas_resistance);
|
||||
DEBUG_MSG("Telemetry->relative_humidity: %f\n", m.variant.environment_metrics.relative_humidity);
|
||||
DEBUG_MSG("Telemetry->temperature: %f\n", m.variant.environment_metrics.temperature);
|
||||
DEBUG_MSG("Telemetry->voltage: %f\n", m.variant.environment_metrics.voltage);
|
||||
DEBUG_MSG("(Sending): barometric_pressure=%f, current=%f, gas_resistance=%f, relative_humidity=%f, temperature=%f, voltage=%f\n",
|
||||
m.variant.environment_metrics.barometric_pressure,
|
||||
m.variant.environment_metrics.current,
|
||||
m.variant.environment_metrics.gas_resistance,
|
||||
m.variant.environment_metrics.relative_humidity,
|
||||
m.variant.environment_metrics.temperature,
|
||||
m.variant.environment_metrics.voltage);
|
||||
|
||||
sensor_read_error_count = 0;
|
||||
|
||||
MeshPacket *p = allocDataProtobuf(m);
|
||||
p->to = dest;
|
||||
p->decoded.want_response = wantReplies;
|
||||
p->decoded.want_response = false;
|
||||
p->priority = MeshPacket_Priority_MIN;
|
||||
|
||||
lastMeasurementPacket = packetPool.allocCopy(*p);
|
||||
DEBUG_MSG("Environment Telemetry: Sending packet to mesh");
|
||||
service.sendToMesh(p, RX_SRC_LOCAL, true);
|
||||
if (phoneOnly) {
|
||||
DEBUG_MSG("Sending packet to phone\n");
|
||||
service.sendToPhone(p);
|
||||
} else {
|
||||
DEBUG_MSG("Sending packet to mesh\n");
|
||||
service.sendToMesh(p, RX_SRC_LOCAL, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,8 @@ class EnvironmentTelemetryModule : private concurrency::OSThread, public Protobu
|
||||
: concurrency::OSThread("EnvironmentTelemetryModule"),
|
||||
ProtobufModule("EnvironmentTelemetry", PortNum_TELEMETRY_APP, &Telemetry_msg)
|
||||
{
|
||||
lastMeasurementPacket = nullptr;
|
||||
lastMeasurementPacket = nullptr;
|
||||
setIntervalFromNow(10 * 1000);
|
||||
}
|
||||
virtual bool wantUIFrame() override;
|
||||
#if !HAS_SCREEN
|
||||
@@ -30,11 +31,13 @@ class EnvironmentTelemetryModule : private concurrency::OSThread, public Protobu
|
||||
/**
|
||||
* Send our Telemetry into the mesh
|
||||
*/
|
||||
bool sendOurTelemetry(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false);
|
||||
bool sendTelemetry(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false);
|
||||
|
||||
private:
|
||||
float CelsiusToFahrenheit(float c);
|
||||
bool firstTime = 1;
|
||||
const MeshPacket *lastMeasurementPacket;
|
||||
uint32_t sendToPhoneIntervalMs = SECONDS_IN_MINUTE * 1000; // Send to phone every minute
|
||||
uint32_t lastSentToMesh = 0;
|
||||
uint32_t sensor_read_error_count = 0;
|
||||
};
|
||||
|
||||
36
src/modules/Telemetry/Sensor/LPS22HBSensor.cpp
Normal file
36
src/modules/Telemetry/Sensor/LPS22HBSensor.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#include "../mesh/generated/telemetry.pb.h"
|
||||
#include "configuration.h"
|
||||
#include "TelemetrySensor.h"
|
||||
#include "LPS22HBSensor.h"
|
||||
#include <Adafruit_LPS2X.h>
|
||||
#include <Adafruit_Sensor.h>
|
||||
|
||||
LPS22HBSensor::LPS22HBSensor() :
|
||||
TelemetrySensor(TelemetrySensorType_LPS22, "LPS22HB")
|
||||
{
|
||||
}
|
||||
|
||||
int32_t LPS22HBSensor::runOnce() {
|
||||
DEBUG_MSG("Init sensor: %s\n", sensorName);
|
||||
if (!hasSensor()) {
|
||||
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
|
||||
}
|
||||
status = lps22hb.begin_I2C(nodeTelemetrySensorsMap[sensorType]);
|
||||
return initI2CSensor();
|
||||
}
|
||||
|
||||
void LPS22HBSensor::setup()
|
||||
{
|
||||
lps22hb.setDataRate(LPS22_RATE_10_HZ);
|
||||
}
|
||||
|
||||
bool LPS22HBSensor::getMetrics(Telemetry *measurement) {
|
||||
sensors_event_t temp;
|
||||
sensors_event_t pressure;
|
||||
lps22hb.getEvent(&pressure, &temp);
|
||||
|
||||
measurement->variant.environment_metrics.temperature = temp.temperature;
|
||||
measurement->variant.environment_metrics.barometric_pressure = pressure.pressure;
|
||||
|
||||
return true;
|
||||
}
|
||||
17
src/modules/Telemetry/Sensor/LPS22HBSensor.h
Normal file
17
src/modules/Telemetry/Sensor/LPS22HBSensor.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "../mesh/generated/telemetry.pb.h"
|
||||
#include "TelemetrySensor.h"
|
||||
#include <Adafruit_LPS2X.h>
|
||||
#include <Adafruit_Sensor.h>
|
||||
|
||||
class LPS22HBSensor : virtual public TelemetrySensor {
|
||||
private:
|
||||
Adafruit_LPS22 lps22hb;
|
||||
|
||||
protected:
|
||||
virtual void setup() override;
|
||||
|
||||
public:
|
||||
LPS22HBSensor();
|
||||
virtual int32_t runOnce() override;
|
||||
virtual bool getMetrics(Telemetry *measurement) override;
|
||||
};
|
||||
34
src/modules/Telemetry/Sensor/SHTC3Sensor.cpp
Normal file
34
src/modules/Telemetry/Sensor/SHTC3Sensor.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
#include "../mesh/generated/telemetry.pb.h"
|
||||
#include "configuration.h"
|
||||
#include "TelemetrySensor.h"
|
||||
#include "SHTC3Sensor.h"
|
||||
#include <Adafruit_SHTC3.h>
|
||||
|
||||
SHTC3Sensor::SHTC3Sensor() :
|
||||
TelemetrySensor(TelemetrySensorType_SHTC3, "SHTC3")
|
||||
{
|
||||
}
|
||||
|
||||
int32_t SHTC3Sensor::runOnce() {
|
||||
DEBUG_MSG("Init sensor: %s\n", sensorName);
|
||||
if (!hasSensor()) {
|
||||
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
|
||||
}
|
||||
status = shtc3.begin();
|
||||
return initI2CSensor();
|
||||
}
|
||||
|
||||
void SHTC3Sensor::setup()
|
||||
{
|
||||
// Set up oversampling and filter initialization
|
||||
}
|
||||
|
||||
bool SHTC3Sensor::getMetrics(Telemetry *measurement) {
|
||||
sensors_event_t humidity, temp;
|
||||
shtc3.getEvent(&humidity, &temp);
|
||||
|
||||
measurement->variant.environment_metrics.temperature = temp.temperature;
|
||||
measurement->variant.environment_metrics.relative_humidity = humidity.relative_humidity;
|
||||
|
||||
return true;
|
||||
}
|
||||
16
src/modules/Telemetry/Sensor/SHTC3Sensor.h
Normal file
16
src/modules/Telemetry/Sensor/SHTC3Sensor.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#include "../mesh/generated/telemetry.pb.h"
|
||||
#include "TelemetrySensor.h"
|
||||
#include <Adafruit_SHTC3.h>
|
||||
|
||||
class SHTC3Sensor : virtual public TelemetrySensor {
|
||||
private:
|
||||
Adafruit_SHTC3 shtc3 = Adafruit_SHTC3();
|
||||
|
||||
protected:
|
||||
virtual void setup() override;
|
||||
|
||||
public:
|
||||
SHTC3Sensor();
|
||||
virtual int32_t runOnce() override;
|
||||
virtual bool getMetrics(Telemetry *measurement) override;
|
||||
};
|
||||
@@ -8,7 +8,9 @@
|
||||
#include "mesh/generated/mqtt.pb.h"
|
||||
#include "mesh/generated/telemetry.pb.h"
|
||||
#include "sleep.h"
|
||||
#if HAS_WIFI
|
||||
#include <WiFi.h>
|
||||
#endif
|
||||
#include <assert.h>
|
||||
#include <json11.hpp>
|
||||
|
||||
@@ -27,8 +29,9 @@ void MQTT::onPublish(char *topic, byte *payload, unsigned int length)
|
||||
{
|
||||
// parsing ServiceEnvelope
|
||||
ServiceEnvelope e = ServiceEnvelope_init_default;
|
||||
if (!pb_decode_from_bytes(payload, length, ServiceEnvelope_fields, &e) && moduleConfig.mqtt.json_enabled) {
|
||||
// check if this is a json payload message
|
||||
|
||||
if (moduleConfig.mqtt.json_enabled && (strncmp(topic, jsonTopic.c_str(), jsonTopic.length()) == 0)) {
|
||||
// check if this is a json payload message by comparing the topic start
|
||||
using namespace json11;
|
||||
char payloadStr[length + 1];
|
||||
memcpy(payloadStr, payload, length);
|
||||
@@ -36,36 +39,37 @@ void MQTT::onPublish(char *topic, byte *payload, unsigned int length)
|
||||
std::string err;
|
||||
auto json = Json::parse(payloadStr, err);
|
||||
if (err.empty()) {
|
||||
DEBUG_MSG("Received json payload on MQTT, parsing..\n");
|
||||
DEBUG_MSG("JSON Received on MQTT, parsing..\n");
|
||||
// check if it is a valid envelope
|
||||
if (json.object_items().count("sender") != 0 && json.object_items().count("payload") != 0) {
|
||||
if (json.object_items().count("sender") != 0 && json.object_items().count("payload") != 0 && json["type"].string_value().compare("sendtext") == 0) {
|
||||
// this is a valid envelope
|
||||
if (json["sender"].string_value().compare(owner.id) != 0) {
|
||||
std::string jsonPayloadStr = json["payload"].dump();
|
||||
DEBUG_MSG("Received json payload %s, length %u\n", jsonPayloadStr.c_str(), jsonPayloadStr.length());
|
||||
// FIXME Not sure we need to be doing this
|
||||
DEBUG_MSG("JSON payload %s, length %u\n", jsonPayloadStr.c_str(), jsonPayloadStr.length());
|
||||
|
||||
// construct protobuf data packet using TEXT_MESSAGE, send it to the mesh
|
||||
// MeshPacket *p = router->allocForSending();
|
||||
// p->decoded.portnum = PortNum_TEXT_MESSAGE_APP;
|
||||
// if (jsonPayloadStr.length() <= sizeof(p->decoded.payload.bytes)) {
|
||||
// memcpy(p->decoded.payload.bytes, jsonPayloadStr.c_str(), jsonPayloadStr.length());
|
||||
// p->decoded.payload.size = jsonPayloadStr.length();
|
||||
// MeshPacket *packet = packetPool.allocCopy(*p);
|
||||
// service.sendToMesh(packet, RX_SRC_LOCAL);
|
||||
// } else {
|
||||
// DEBUG_MSG("Received MQTT json payload too long, dropping\n");
|
||||
// }
|
||||
MeshPacket *p = router->allocForSending();
|
||||
p->decoded.portnum = PortNum_TEXT_MESSAGE_APP;
|
||||
if (jsonPayloadStr.length() <= sizeof(p->decoded.payload.bytes)) {
|
||||
memcpy(p->decoded.payload.bytes, jsonPayloadStr.c_str(), jsonPayloadStr.length());
|
||||
p->decoded.payload.size = jsonPayloadStr.length();
|
||||
MeshPacket *packet = packetPool.allocCopy(*p);
|
||||
service.sendToMesh(packet, RX_SRC_LOCAL);
|
||||
} else {
|
||||
DEBUG_MSG("Received MQTT json payload too long, dropping\n");
|
||||
}
|
||||
} else {
|
||||
DEBUG_MSG("Ignoring downlink message we originally sent.\n");
|
||||
DEBUG_MSG("JSON Ignoring downlink message we originally sent.\n");
|
||||
}
|
||||
} else {
|
||||
DEBUG_MSG("Received json payload on MQTT but not a valid envelope\n");
|
||||
DEBUG_MSG("JSON Received payload on MQTT but not a valid envelope\n");
|
||||
}
|
||||
} else {
|
||||
// no json, this is an invalid payload
|
||||
DEBUG_MSG("Invalid MQTT service envelope, topic %s, len %u!\n", topic, length);
|
||||
}
|
||||
} else {
|
||||
pb_decode_from_bytes(payload, length, ServiceEnvelope_fields, &e);
|
||||
if (strcmp(e.gateway_id, owner.id) == 0)
|
||||
DEBUG_MSG("Ignoring downlink message we originally sent.\n");
|
||||
else {
|
||||
@@ -103,6 +107,11 @@ MQTT::MQTT() : concurrency::OSThread("mqtt"), pubSub(mqttClient)
|
||||
// preflightSleepObserver.observe(&preflightSleep);
|
||||
}
|
||||
|
||||
bool MQTT::connected()
|
||||
{
|
||||
return pubSub.connected();
|
||||
}
|
||||
|
||||
void MQTT::reconnect()
|
||||
{
|
||||
if (wantsLink()) {
|
||||
@@ -187,7 +196,13 @@ bool MQTT::wantsLink() const
|
||||
}
|
||||
}
|
||||
|
||||
#if HAS_WIFI
|
||||
return hasChannel && WiFi.isConnected();
|
||||
#endif
|
||||
#if HAS_ETHERNET
|
||||
return hasChannel && (Ethernet.linkStatus() == LinkON);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t MQTT::runOnce()
|
||||
@@ -243,7 +258,7 @@ void MQTT::onSend(const MeshPacket &mp, ChannelIndex chIndex)
|
||||
auto jsonString = this->downstreamPacketToJson((MeshPacket *)&mp);
|
||||
if (jsonString.length() != 0) {
|
||||
String topicJson = jsonTopic + channelId + "/" + owner.id;
|
||||
DEBUG_MSG("publish json message to %s, %u bytes: %s\n", topicJson.c_str(), jsonString.length(), jsonString.c_str());
|
||||
DEBUG_MSG("JSON publish message to %s, %u bytes: %s\n", topicJson.c_str(), jsonString.length(), jsonString.c_str());
|
||||
pubSub.publish(topicJson.c_str(), jsonString.c_str(), false);
|
||||
}
|
||||
}
|
||||
@@ -251,7 +266,7 @@ void MQTT::onSend(const MeshPacket &mp, ChannelIndex chIndex)
|
||||
}
|
||||
|
||||
// converts a downstream packet into a json message
|
||||
String MQTT::downstreamPacketToJson(MeshPacket *mp)
|
||||
std::string MQTT::downstreamPacketToJson(MeshPacket *mp)
|
||||
{
|
||||
using namespace json11;
|
||||
|
||||
@@ -279,7 +294,7 @@ String MQTT::downstreamPacketToJson(MeshPacket *mp)
|
||||
// if it isn't, then we need to create a json object
|
||||
// with the string as the value
|
||||
DEBUG_MSG("text message payload is of type plaintext\n");
|
||||
msgPayload = Json::object({{"text", payloadStr}});
|
||||
msgPayload = Json::object{{"text", payloadStr}};
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -344,9 +359,9 @@ String MQTT::downstreamPacketToJson(MeshPacket *mp)
|
||||
msgPayload = Json::object{
|
||||
{"time", (int)decoded->time},
|
||||
{"pos_timestamp", (int)decoded->timestamp},
|
||||
{"latitude_i", decoded->latitude_i},
|
||||
{"longitude_i", decoded->longitude_i},
|
||||
{"altitude", decoded->altitude}
|
||||
{"latitude_i", (int)decoded->latitude_i},
|
||||
{"longitude_i", (int)decoded->longitude_i},
|
||||
{"altitude", (int)decoded->altitude}
|
||||
};
|
||||
} else {
|
||||
DEBUG_MSG("Error decoding protobuf for position message!\n");
|
||||
@@ -369,8 +384,8 @@ String MQTT::downstreamPacketToJson(MeshPacket *mp)
|
||||
{"description", decoded->description},
|
||||
{"expire", (int)decoded->expire},
|
||||
{"locked", decoded->locked},
|
||||
{"latitude_i", decoded->latitude_i},
|
||||
{"longitude_i", decoded->longitude_i},
|
||||
{"latitude_i", (int)decoded->latitude_i},
|
||||
{"longitude_i", (int)decoded->longitude_i},
|
||||
};
|
||||
} else {
|
||||
DEBUG_MSG("Error decoding protobuf for position message!\n");
|
||||
@@ -396,8 +411,8 @@ String MQTT::downstreamPacketToJson(MeshPacket *mp)
|
||||
};
|
||||
|
||||
// serialize and return it
|
||||
static std::string jsonStr = jsonObj.dump();
|
||||
std::string jsonStr = jsonObj.dump();
|
||||
DEBUG_MSG("serialized json message: %s\n", jsonStr.c_str());
|
||||
|
||||
return jsonStr.c_str();
|
||||
return jsonStr;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,12 @@
|
||||
#include "concurrency/OSThread.h"
|
||||
#include "mesh/Channels.h"
|
||||
#include <PubSubClient.h>
|
||||
#if HAS_WIFI
|
||||
#include <WiFiClient.h>
|
||||
#endif
|
||||
#if HAS_ETHERNET
|
||||
#include <EthernetClient.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Our wrapper/singleton for sending/receiving MQTT "udp" packets. This object isolates the MQTT protocol implementation from
|
||||
@@ -16,7 +21,12 @@ class MQTT : private concurrency::OSThread
|
||||
// supposedly the current version is busted:
|
||||
// http://www.iotsharing.com/2017/08/how-to-use-esp32-mqtts-with-mqtts-mosquitto-broker-tls-ssl.html
|
||||
// WiFiClientSecure wifiClient;
|
||||
#if HAS_WIFI
|
||||
WiFiClient mqttClient;
|
||||
#endif
|
||||
#if HAS_ETHERNET
|
||||
EthernetClient mqttClient;
|
||||
#endif
|
||||
PubSubClient pubSub;
|
||||
|
||||
// instead we supress sleep from our runOnce() callback
|
||||
@@ -38,6 +48,8 @@ class MQTT : private concurrency::OSThread
|
||||
/** Attempt to connect to server if necessary
|
||||
*/
|
||||
void reconnect();
|
||||
|
||||
bool connected();
|
||||
|
||||
protected:
|
||||
virtual int32_t runOnce() override;
|
||||
@@ -58,7 +70,7 @@ class MQTT : private concurrency::OSThread
|
||||
void onPublish(char *topic, byte *payload, unsigned int length);
|
||||
|
||||
/// Called when a new publish arrives from the MQTT server
|
||||
String downstreamPacketToJson(MeshPacket *mp);
|
||||
std::string downstreamPacketToJson(MeshPacket *mp);
|
||||
|
||||
/// Return 0 if sleep is okay, veto sleep if we are connected to pubsub server
|
||||
// int preflightSleepCb(void *unused = NULL) { return pubSub.connected() ? 1 : 0; }
|
||||
|
||||
27
src/network-stubs.cpp
Normal file
27
src/network-stubs.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include "configuration.h"
|
||||
|
||||
#if (HAS_WIFI == 0)
|
||||
|
||||
bool initWifi() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void deinitWifi() {}
|
||||
|
||||
bool isWifiAvailable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if (HAS_ETHERNET == 0)
|
||||
|
||||
bool initEthernet() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isEthernetAvailable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -12,7 +12,6 @@ NimBLECharacteristic *fromNumCharacteristic;
|
||||
NimBLEServer *bleServer;
|
||||
|
||||
static bool passkeyShowing;
|
||||
static uint32_t doublepressed;
|
||||
|
||||
class BluetoothPhoneAPI : public PhoneAPI
|
||||
{
|
||||
@@ -71,12 +70,8 @@ class NimbleBluetoothServerCallback : public NimBLEServerCallbacks
|
||||
{
|
||||
virtual uint32_t onPassKeyRequest() {
|
||||
uint32_t passkey = config.bluetooth.fixed_pin;
|
||||
|
||||
if (doublepressed > 0 && (doublepressed + (30 * 1000)) > millis()) {
|
||||
DEBUG_MSG("User has set BLE pairing mode to fixed-pin\n");
|
||||
config.bluetooth.mode = Config_BluetoothConfig_PairingMode_FIXED_PIN;
|
||||
nodeDB.saveToDisk(SEGMENT_CONFIG);
|
||||
} else if (config.bluetooth.mode == Config_BluetoothConfig_PairingMode_RANDOM_PIN) {
|
||||
|
||||
if (config.bluetooth.mode == Config_BluetoothConfig_PairingMode_RANDOM_PIN) {
|
||||
DEBUG_MSG("Using random passkey\n");
|
||||
// This is the passkey to be entered on peer - we pick a number >100,000 to ensure 6 digits
|
||||
passkey = random(100000, 999999);
|
||||
@@ -202,24 +197,3 @@ void clearNVS()
|
||||
ESP.restart();
|
||||
#endif
|
||||
}
|
||||
|
||||
void disablePin()
|
||||
{
|
||||
DEBUG_MSG("User Override, disabling bluetooth pin requirement\n");
|
||||
// keep track of when it was pressed, so we know it was within X seconds
|
||||
|
||||
// Flash the LED
|
||||
setLed(true);
|
||||
delay(100);
|
||||
setLed(false);
|
||||
delay(100);
|
||||
setLed(true);
|
||||
delay(100);
|
||||
setLed(false);
|
||||
delay(100);
|
||||
setLed(true);
|
||||
delay(100);
|
||||
setLed(false);
|
||||
|
||||
doublepressed = millis();
|
||||
}
|
||||
|
||||
@@ -15,4 +15,3 @@ class NimbleBluetooth
|
||||
|
||||
void setBluetoothEnable(bool on);
|
||||
void clearNVS();
|
||||
void disablePin();
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
//#include "mesh/wifi/WebServer.h"
|
||||
#include "configuration.h"
|
||||
|
||||
#ifndef ARCH_ESP32
|
||||
|
||||
//#include "mesh/wifi/WiFiAPClient.h"
|
||||
|
||||
bool initWifi(bool forceSoftAP) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void deinitWifi() {}
|
||||
|
||||
bool isWifiAvailable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -59,7 +59,7 @@ static const uint8_t SCK = 33;
|
||||
|
||||
// https://docs.rakwireless.com/Product-Categories/WisBlock/RAK13300/
|
||||
|
||||
#define LORA_DIO0 26 // a No connect on the SX1262/SX1268 module
|
||||
#define LORA_DIO0 -1 // a No connect on the SX1262/SX1268 module
|
||||
#define LORA_RESET WB_IO4 // RST for SX1276, and for SX1262/SX1268
|
||||
#define LORA_DIO1 WB_IO6 // IRQ for SX1262/SX1268
|
||||
#define LORA_DIO2 WB_IO5 // BUSY for SX1262/SX1268
|
||||
|
||||
@@ -3,10 +3,12 @@
|
||||
extends = nrf52840_base
|
||||
board = wiscore_rak4631
|
||||
build_flags = ${nrf52840_base.build_flags} -Ivariants/rak4631 -D RAK_4631
|
||||
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/rak4631>
|
||||
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/rak4631> +<mesh/eth/> +<mqtt/>
|
||||
lib_deps =
|
||||
${nrf52840_base.lib_deps}
|
||||
${networking_base.lib_deps}
|
||||
melopero/Melopero RV3028@^1.1.0
|
||||
https://github.com/meshtastic/RAK13800-W5100S.git#b680706eb8006cd62c919ac74c8af1950eb82c81
|
||||
debug_tool = jlink
|
||||
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
|
||||
;upload_protocol = jlink
|
||||
@@ -185,6 +185,9 @@ static const uint8_t SCK = PIN_SPI_SCK;
|
||||
#define SX126X_RXEN (37)
|
||||
#define SX126X_E22 // DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
|
||||
|
||||
// enables 3.3V periphery like GPS or IO Module
|
||||
#define PIN_3V3_EN (34)
|
||||
|
||||
// RAK1910 GPS module
|
||||
// If using the wisblock GPS module and pluged into Port A on WisBlock base
|
||||
// IO1 is hooked to PPS (pin 12 on header) = gpio 17
|
||||
@@ -192,7 +195,7 @@ static const uint8_t SCK = PIN_SPI_SCK;
|
||||
// Therefore must be 1 to keep peripherals powered
|
||||
// Power is on the controllable 3V3_S rail
|
||||
// #define PIN_GPS_RESET (34)
|
||||
#define PIN_GPS_EN (34)
|
||||
#define PIN_GPS_EN PIN_3V3_EN
|
||||
#define PIN_GPS_PPS (17) // Pulse per second input from the GPS
|
||||
|
||||
#define GPS_RX_PIN PIN_SERIAL1_RX
|
||||
@@ -226,6 +229,12 @@ static const uint8_t SCK = PIN_SPI_SCK;
|
||||
|
||||
#define HAS_RTC 1
|
||||
|
||||
#define HAS_ETHERNET 1
|
||||
|
||||
#define PIN_ETHERNET_RESET 21
|
||||
#define PIN_ETHERNET_SS PIN_EINK_CS
|
||||
#define ETH_SPI_PORT SPI1
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -185,6 +185,9 @@ static const uint8_t SCK = PIN_SPI_SCK;
|
||||
#define SX126X_RXEN (37)
|
||||
#define SX126X_E22 // DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
|
||||
|
||||
// enables 3.3V periphery like GPS or IO Module
|
||||
#define PIN_3V3_EN (34)
|
||||
|
||||
// RAK1910 GPS module
|
||||
// If using the wisblock GPS module and pluged into Port A on WisBlock base
|
||||
// IO1 is hooked to PPS (pin 12 on header) = gpio 17
|
||||
@@ -192,7 +195,7 @@ static const uint8_t SCK = PIN_SPI_SCK;
|
||||
// Therefore must be 1 to keep peripherals powered
|
||||
// Power is on the controllable 3V3_S rail
|
||||
// #define PIN_GPS_RESET (34)
|
||||
#define PIN_GPS_EN (34)
|
||||
#define PIN_GPS_EN PIN_3V3_EN
|
||||
#define PIN_GPS_PPS (17) // Pulse per second input from the GPS
|
||||
|
||||
#define GPS_RX_PIN PIN_SERIAL1_RX
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
[env:pico]
|
||||
extends = rp2040_base
|
||||
board = pico
|
||||
board = rpipico
|
||||
upload_protocol = picotool
|
||||
|
||||
# add our variants files to the include and src paths
|
||||
build_flags = ${rp2040_base.build_flags}
|
||||
-DPRIVATE_HW
|
||||
-Ivariants/pico
|
||||
-Ivariants/rpipico
|
||||
-DARDUINO_AVR_NANO_EVERY
|
||||
-DDEBUG_RP2040_WIRE
|
||||
-DDEBUG_RP2040_SPI
|
||||
17
variants/rpipicow/platformio.ini
Normal file
17
variants/rpipicow/platformio.ini
Normal file
@@ -0,0 +1,17 @@
|
||||
[env:picow]
|
||||
extends = rp2040_base
|
||||
board = rpipicow
|
||||
upload_protocol = picotool
|
||||
|
||||
# add our variants files to the include and src paths
|
||||
build_flags = ${rp2040_base.build_flags}
|
||||
-DPRIVATE_HW
|
||||
-Ivariants/rpipicow
|
||||
-DARDUINO_AVR_NANO_EVERY
|
||||
-DDEBUG_RP2040_WIRE
|
||||
-DDEBUG_RP2040_SPI
|
||||
-DDEBUG_RP2040_CORE
|
||||
-DDEBUG_RP2040_PORT=Serial
|
||||
-DUSE_TINYUSB
|
||||
lib_deps =
|
||||
${rp2040_base.lib_deps}
|
||||
52
variants/rpipicow/variant.h
Normal file
52
variants/rpipicow/variant.h
Normal file
@@ -0,0 +1,52 @@
|
||||
// #define RADIOLIB_CUSTOM_ARDUINO 1
|
||||
// #define RADIOLIB_TONE_UNSUPPORTED 1
|
||||
// #define RADIOLIB_SOFTWARE_SERIAL_UNSUPPORTED 1
|
||||
|
||||
#define ARDUINO_ARCH_AVR
|
||||
|
||||
#define CBC 0
|
||||
#define CTR 1
|
||||
#define ECB 0
|
||||
|
||||
#define NO_GPS 1
|
||||
#define USE_SH1106 1
|
||||
#undef GPS_SERIAL_NUM
|
||||
|
||||
// #define I2C_SDA 6
|
||||
// #define I2C_SCL 7
|
||||
|
||||
#define BUTTON_PIN 17
|
||||
#define EXT_NOTIFY_OUT 4
|
||||
|
||||
#define BATTERY_PIN 26
|
||||
// ratio of voltage divider = 3.0 (R17=200k, R18=100k)
|
||||
#define ADC_MULTIPLIER 3.1 // 3.0 + a bit for being optimistic
|
||||
|
||||
#define USE_RF95
|
||||
#define USE_SX1262
|
||||
|
||||
#undef RF95_SCK
|
||||
#undef RF95_MISO
|
||||
#undef RF95_MOSI
|
||||
#undef RF95_NSS
|
||||
|
||||
#define RF95_SCK 10
|
||||
#define RF95_MISO 12
|
||||
#define RF95_MOSI 11
|
||||
#define RF95_NSS 3
|
||||
|
||||
#define LORA_DIO0 RADIOLIB_NC
|
||||
#define LORA_RESET 15
|
||||
#define LORA_DIO1 20
|
||||
#define LORA_DIO2 2
|
||||
#define LORA_DIO3 RADIOLIB_NC
|
||||
|
||||
#ifdef USE_SX1262
|
||||
#define SX126X_CS RF95_NSS
|
||||
#define SX126X_DIO1 LORA_DIO1
|
||||
#define SX126X_BUSY LORA_DIO2
|
||||
#define SX126X_RESET LORA_RESET
|
||||
#define SX126X_E22
|
||||
#endif
|
||||
|
||||
#include <Adafruit_TinyUSB.h>
|
||||
@@ -1,4 +1,4 @@
|
||||
[VERSION]
|
||||
major = 1
|
||||
minor = 3
|
||||
build = 43
|
||||
build = 48
|
||||
|
||||
Reference in New Issue
Block a user