mirror of
https://github.com/meshtastic/firmware.git
synced 2025-12-28 13:40:32 +00:00
Compare commits
328 Commits
v1.3.40.e8
...
v1.3.44.4f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4fa8d02b08 | ||
|
|
43fb0d80f1 | ||
|
|
b25ace14e5 | ||
|
|
8734751bc4 | ||
|
|
5559a1edb0 | ||
|
|
bf503354f3 | ||
|
|
7b10441a28 | ||
|
|
994e396c00 | ||
|
|
6e22ee9061 | ||
|
|
b5fb0f60b0 | ||
|
|
a7fe69ed6b | ||
|
|
7f05298172 | ||
|
|
92a2505056 | ||
|
|
aae9d2fcf6 | ||
|
|
b59e928589 | ||
|
|
1db08b3b0e | ||
|
|
2cf3c105a1 | ||
|
|
505e4e8176 | ||
|
|
49a9973548 | ||
|
|
18af9d734d | ||
|
|
3e22aafea8 | ||
|
|
434db4347b | ||
|
|
b2c3b405b1 | ||
|
|
4bc8f6a6b9 | ||
|
|
4534d17d79 | ||
|
|
f88dde2f60 | ||
|
|
f8982ddaf8 | ||
|
|
784cd8c6f1 | ||
|
|
c3ab8f12cf | ||
|
|
b5adb7babc | ||
|
|
62c809a596 | ||
|
|
d2fe4426c1 | ||
|
|
984f0ca12c | ||
|
|
9d3eba9ea4 | ||
|
|
323f81eaba | ||
|
|
8d0e25fd82 | ||
|
|
20eaddee58 | ||
|
|
30b1bd85d9 | ||
|
|
09cce094d1 | ||
|
|
33a208e3c4 | ||
|
|
dd4c4fba80 | ||
|
|
a17c40ad09 | ||
|
|
9d73e606ac | ||
|
|
da12360105 | ||
|
|
ee1ae627a3 | ||
|
|
137a8dcfdf | ||
|
|
b2d753ed86 | ||
|
|
6e40102f26 | ||
|
|
511fe23b8a | ||
|
|
e433895873 | ||
|
|
5572195af9 | ||
|
|
cb956cd35b | ||
|
|
b551c7738e | ||
|
|
3d45c4dbd8 | ||
|
|
8681489cb7 | ||
|
|
ed328766b2 | ||
|
|
fb852ee6eb | ||
|
|
a6ee708b90 | ||
|
|
c9398e7b8a | ||
|
|
b591e35442 | ||
|
|
e50e15dc04 | ||
|
|
d4e65d8607 | ||
|
|
63ced7da7c | ||
|
|
03868d05db | ||
|
|
186374525a | ||
|
|
f116585c2a | ||
|
|
f4945729bc | ||
|
|
a3c76232c8 | ||
|
|
5bc41118e2 | ||
|
|
9445a96b3a | ||
|
|
a5761069ca | ||
|
|
2d4bfe183c | ||
|
|
bf4115a80f | ||
|
|
b2e84dfd29 | ||
|
|
004f6fa4d6 | ||
|
|
cefd4cd647 | ||
|
|
fd2ae61e3e | ||
|
|
7cda61ca01 | ||
|
|
98e1d52eaa | ||
|
|
1d09beb8a7 | ||
|
|
d44cce2928 | ||
|
|
51b3d4d06e | ||
|
|
a17ddaa951 | ||
|
|
9bd925226c | ||
|
|
e34ada3ff1 | ||
|
|
1ec1ff0773 | ||
|
|
7f935717db | ||
|
|
5b1d3a0c51 | ||
|
|
484f340023 | ||
|
|
ab0cf025c5 | ||
|
|
b384d9ea88 | ||
|
|
bb2094c4de | ||
|
|
6708121ba6 | ||
|
|
46a9bb3f7d | ||
|
|
62498d0935 | ||
|
|
c70184fbed | ||
|
|
4d2cb45f9f | ||
|
|
e5605cc6fe | ||
|
|
f7331a2e41 | ||
|
|
838271a14f | ||
|
|
b6b23907ed | ||
|
|
b240b9a088 | ||
|
|
b3a484f1e5 | ||
|
|
f3042ddf37 | ||
|
|
54816231e9 | ||
|
|
1c168d7d62 | ||
|
|
063c4904ff | ||
|
|
fefcbb147b | ||
|
|
53d48e8f61 | ||
|
|
ce5bce5cdc | ||
|
|
3597685b23 | ||
|
|
dc097c7230 | ||
|
|
b148781e4b | ||
|
|
5d8826e8ef | ||
|
|
39a51c7fbb | ||
|
|
129edde338 | ||
|
|
93cc278eee | ||
|
|
c34198264a | ||
|
|
054b12325d | ||
|
|
0f7a126828 | ||
|
|
7ff72fb981 | ||
|
|
0fe99595a9 | ||
|
|
b2ff628cec | ||
|
|
86a3bd6db8 | ||
|
|
73a5357d0e | ||
|
|
2faf507c0d | ||
|
|
cf124d97b8 | ||
|
|
482c0766af | ||
|
|
7e5a26fde5 | ||
|
|
e85af2f732 | ||
|
|
4df81008bc | ||
|
|
803dc69ccd | ||
|
|
42308cca5b | ||
|
|
ea991a4eee | ||
|
|
04db2d4410 | ||
|
|
076c1ed2ee | ||
|
|
75aa4ea325 | ||
|
|
e54be07dc0 | ||
|
|
d439d00e25 | ||
|
|
c4bea793af | ||
|
|
b53dcb932e | ||
|
|
371428d6ab | ||
|
|
1970d0c00f | ||
|
|
1dd7aa935f | ||
|
|
6b40f9d95c | ||
|
|
b3717d0396 | ||
|
|
82ba95833b | ||
|
|
28384df702 | ||
|
|
aee06f4738 | ||
|
|
ab282765d4 | ||
|
|
5d464badc8 | ||
|
|
68282682de | ||
|
|
2696b04138 | ||
|
|
31dc37150b | ||
|
|
e66d9d0add | ||
|
|
067bde321b | ||
|
|
84ec364ac2 | ||
|
|
32990856e3 | ||
|
|
a1bd5c9ea0 | ||
|
|
51f0e7879a | ||
|
|
0bdb90d133 | ||
|
|
e98c11ff89 | ||
|
|
8f84d7089c | ||
|
|
b0712c4186 | ||
|
|
8f92383ce4 | ||
|
|
c571fc9e24 | ||
|
|
05126bc6dc | ||
|
|
de56a370c6 | ||
|
|
daf189bf4b | ||
|
|
d95ec7e6b9 | ||
|
|
ac235bcabb | ||
|
|
ab4b3a50ee | ||
|
|
7f0fb2a2b6 | ||
|
|
ade1edfdfc | ||
|
|
4723faa95f | ||
|
|
93f83b0fcb | ||
|
|
8f84f7c0a5 | ||
|
|
48e4101f1c | ||
|
|
e6bb79f4c1 | ||
|
|
0bef3464f5 | ||
|
|
3c038a8c50 | ||
|
|
b8eb751316 | ||
|
|
5332db1eca | ||
|
|
9deda962aa | ||
|
|
c53434539b | ||
|
|
7f179deaf3 | ||
|
|
da29fa139f | ||
|
|
1d8a562fd9 | ||
|
|
0dbf97afab | ||
|
|
e5720fba3e | ||
|
|
498ac00b92 | ||
|
|
226a2dfe04 | ||
|
|
7e9a233296 | ||
|
|
ae311c838e | ||
|
|
de769db3bc | ||
|
|
5fa96c7fd1 | ||
|
|
2ee0c9a67a | ||
|
|
347af0210e | ||
|
|
d8455d687c | ||
|
|
34fef4c4e7 | ||
|
|
18bb373219 | ||
|
|
2f74f9ca15 | ||
|
|
5775c390f3 | ||
|
|
80826b8712 | ||
|
|
664d18cf58 | ||
|
|
bc2cddcb11 | ||
|
|
4949bda606 | ||
|
|
b4f75ad042 | ||
|
|
af4d11e17b | ||
|
|
e8f4a8b739 | ||
|
|
fae6693f8f | ||
|
|
0646ecdec4 | ||
|
|
544c89460f | ||
|
|
15089f5b01 | ||
|
|
8ef510035d | ||
|
|
864b1f754c | ||
|
|
883a2ebac0 | ||
|
|
bbe5b2e42c | ||
|
|
1b316b111f | ||
|
|
d0720620e8 | ||
|
|
cf4947d898 | ||
|
|
b5a8efa16b | ||
|
|
b38ae783b9 | ||
|
|
cbd8346c93 | ||
|
|
c0bfb979fd | ||
|
|
7c5a36ce38 | ||
|
|
fc729b0cbb | ||
|
|
0b81a25fda | ||
|
|
011db443ba | ||
|
|
b73e240f4d | ||
|
|
6de77ee310 | ||
|
|
0a8293a2d6 | ||
|
|
d0ad5dd4cf | ||
|
|
ab342ce904 | ||
|
|
140250ef03 | ||
|
|
ed90275370 | ||
|
|
e8b28faaf1 | ||
|
|
afcc7b6a56 | ||
|
|
e27a507a28 | ||
|
|
207f701f0a | ||
|
|
dd8cb1c7fb | ||
|
|
ccf93b8c23 | ||
|
|
4c6f3ead60 | ||
|
|
2d81d359b8 | ||
|
|
1f96d5d957 | ||
|
|
033f45d4da | ||
|
|
ae2c514ee7 | ||
|
|
80ddb81fac | ||
|
|
4bc29200be | ||
|
|
55c55fb705 | ||
|
|
0e2ab75bb0 | ||
|
|
128d20b290 | ||
|
|
ad9cc40b97 | ||
|
|
e0d3ac01b0 | ||
|
|
0f87adad7b | ||
|
|
9481461145 | ||
|
|
accd23eddc | ||
|
|
7c202b6069 | ||
|
|
e93b98ff98 | ||
|
|
b1ac2cf821 | ||
|
|
bfd1fecc2a | ||
|
|
c622a9b4be | ||
|
|
ade66cd8f4 | ||
|
|
397030b5a6 | ||
|
|
adc50f40b1 | ||
|
|
32d92d9b75 | ||
|
|
18f37981bb | ||
|
|
a8711bc54a | ||
|
|
eac2613743 | ||
|
|
4a0c18c4cd | ||
|
|
e376a3a28e | ||
|
|
a6bdff53c9 | ||
|
|
b5c5483ced | ||
|
|
601422e92b | ||
|
|
dbbe5e59ae | ||
|
|
b96dd6d36d | ||
|
|
e6b6e175b8 | ||
|
|
2ff549d458 | ||
|
|
a1230500fd | ||
|
|
17db87e042 | ||
|
|
42d2986cb8 | ||
|
|
cc054a13e2 | ||
|
|
60b4dbfdcd | ||
|
|
c446a0f222 | ||
|
|
f98e96cf1b | ||
|
|
3102777a71 | ||
|
|
ed95f382cf | ||
|
|
7f18c0fb77 | ||
|
|
52e4f93760 | ||
|
|
0167304300 | ||
|
|
7aaca3d486 | ||
|
|
bf3306fbc8 | ||
|
|
e375a8460b | ||
|
|
ff88900982 | ||
|
|
7f293bfda3 | ||
|
|
99de0a76a5 | ||
|
|
47ffb9c70d | ||
|
|
1231f926ea | ||
|
|
e05e888fca | ||
|
|
03580f5be8 | ||
|
|
90dabfea30 | ||
|
|
c8d7b1aba0 | ||
|
|
6065ef3a54 | ||
|
|
86c7eefc91 | ||
|
|
f7b12f0695 | ||
|
|
0c46ad91ef | ||
|
|
96cab75ccd | ||
|
|
a7138b7213 | ||
|
|
11590e33d3 | ||
|
|
a3a92d2d13 | ||
|
|
2088036521 | ||
|
|
7d0e16d1b6 | ||
|
|
35c77ef99c | ||
|
|
9244d03cf9 | ||
|
|
a50a461675 | ||
|
|
f78911666e | ||
|
|
f1e6585726 | ||
|
|
b8f862ac46 | ||
|
|
94a572aee6 | ||
|
|
a9e7a33473 | ||
|
|
5621719eef | ||
|
|
a27a07956f | ||
|
|
f54f60c31c | ||
|
|
f767fd5075 | ||
|
|
8d5ffb7262 | ||
|
|
84f1edab18 | ||
|
|
0063ae6512 | ||
|
|
1b25ea714d |
25
.github/workflows/main_matrix.yml
vendored
25
.github/workflows/main_matrix.yml
vendored
@@ -5,7 +5,6 @@ on:
|
||||
branches: [master]
|
||||
paths-ignore:
|
||||
- "**.md"
|
||||
- "**.yml"
|
||||
- "version.properties"
|
||||
|
||||
# Note: This is different from "pull_request". Need to specify ref when doing checkouts.
|
||||
@@ -13,7 +12,7 @@ on:
|
||||
branches: [master]
|
||||
paths-ignore:
|
||||
- "**.md"
|
||||
- "**.yml"
|
||||
#- "**.yml"
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
@@ -41,6 +40,7 @@ jobs:
|
||||
- board: station-g1
|
||||
- board: m5stack-core
|
||||
- board: m5stack-coreink
|
||||
- board: tbeam-s3-core
|
||||
# - board: pico
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
@@ -100,6 +100,7 @@ jobs:
|
||||
- board: station-g1
|
||||
- board: m5stack-core
|
||||
- board: m5stack-coreink
|
||||
- board: tbeam-s3-core
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@@ -125,12 +126,12 @@ jobs:
|
||||
- name: Upgrade python tools
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -U platformio adafruit-nrfutil littlefs-python
|
||||
pip install -U platformio adafruit-nrfutil
|
||||
|
||||
- name: Upgrade platformio
|
||||
run: |
|
||||
pio upgrade
|
||||
|
||||
|
||||
- name: Pull web ui
|
||||
uses: dsaltares/fetch-gh-release-asset@master
|
||||
with:
|
||||
@@ -146,7 +147,15 @@ jobs:
|
||||
|
||||
- name: Build ESP32
|
||||
run: bin/build-esp32.sh ${{ matrix.board }}
|
||||
|
||||
|
||||
- name: Pull OTA Firmware
|
||||
uses: dsaltares/fetch-gh-release-asset@master
|
||||
with:
|
||||
repo: "meshtastic/Meshtastic-OTA"
|
||||
file: "firmware.bin"
|
||||
target: "release/bleota.bin"
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Get release version string
|
||||
run: echo "::set-output name=version::$(./bin/buildinfo.py long)"
|
||||
id: version
|
||||
@@ -215,6 +224,7 @@ jobs:
|
||||
path: |
|
||||
release/*.uf2
|
||||
release/*.elf
|
||||
release/*.zip
|
||||
retention-days: 90
|
||||
|
||||
build-rpi2040:
|
||||
@@ -297,7 +307,7 @@ jobs:
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -U platformio adafruit-nrfutil
|
||||
pip install -U --pre meshtastic
|
||||
pip install -U meshtastic --pre
|
||||
|
||||
- name: Upgrade platformio
|
||||
run: |
|
||||
@@ -359,7 +369,7 @@ jobs:
|
||||
id: version
|
||||
|
||||
- name: Move files up
|
||||
run: mv -b -t ./ ./*tbeam-*/littlefs*.bin ./*tbeam-*/system-info.bin ./**/firmware*.bin ./**/*.uf2 ./**/*.elf ./**/meshtasticd_linux_amd64 ./*native*/*device-*.sh ./*native*/*device-*.bat
|
||||
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
|
||||
@@ -368,6 +378,7 @@ jobs:
|
||||
path: |
|
||||
./*.bin
|
||||
./*.uf2
|
||||
./firmware-*-ota.zip
|
||||
./meshtasticd_linux_amd64
|
||||
./device-*.sh
|
||||
./device-*.bat
|
||||
|
||||
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -53,7 +53,8 @@
|
||||
"iostream": "cpp",
|
||||
"esp_nimble_hci.h": "c",
|
||||
"map": "cpp",
|
||||
"random": "cpp"
|
||||
"random": "cpp",
|
||||
"*.tpp": "cpp"
|
||||
},
|
||||
"cSpell.words": [
|
||||
"Blox",
|
||||
|
||||
53
arch/esp32/esp32.ini
Normal file
53
arch/esp32/esp32.ini
Normal file
@@ -0,0 +1,53 @@
|
||||
; Common settings for ESP targes, mixin with extends = esp32_base
|
||||
[esp32_base]
|
||||
extends = arduino_base
|
||||
platform = platformio/espressif32@^5.2.0
|
||||
build_src_filter =
|
||||
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040>
|
||||
upload_speed = 921600
|
||||
debug_init_break = tbreak setup
|
||||
monitor_filters = esp32_exception_decoder
|
||||
board_build.filesystem = littlefs
|
||||
|
||||
# Remove -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL for low level BLE logging.
|
||||
# See library directory for BLE logging possible values: .pio/libdeps/tbeam/NimBLE-Arduino/src/log_common/log_common.h
|
||||
# This overrides the BLE logging default of LOG_LEVEL_INFO (1) from: .pio/libdeps/tbeam/NimBLE-Arduino/src/esp_nimble_cfg.h
|
||||
build_flags =
|
||||
${arduino_base.build_flags}
|
||||
-Wall
|
||||
-Wextra
|
||||
-Isrc/platform/esp32
|
||||
-std=c++11
|
||||
-DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG
|
||||
-DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
|
||||
-DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL
|
||||
-DAXP_DEBUG_PORT=Serial
|
||||
-DCONFIG_BT_NIMBLE_ENABLED
|
||||
-DCONFIG_NIMBLE_CPP_LOG_LEVEL=2
|
||||
-DCONFIG_BT_NIMBLE_MAX_CCCDS=20
|
||||
-DESP_OPENSSL_SUPPRESS_LEGACY_WARNING
|
||||
|
||||
lib_deps =
|
||||
${arduino_base.lib_deps}
|
||||
${networking_base.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 =
|
||||
segger_rtt
|
||||
ESP32 BLE Arduino
|
||||
|
||||
; leave this commented out to avoid breaking Windows
|
||||
;upload_port = /dev/ttyUSB0
|
||||
;monitor_port = /dev/ttyUSB0
|
||||
|
||||
; Please don't delete these lines. JM uses them.
|
||||
;upload_port = /dev/cu.SLAB_USBtoUART
|
||||
;monitor_port = /dev/cu.SLAB_USBtoUART
|
||||
|
||||
; customize the partition table
|
||||
; http://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables
|
||||
board_build.partitions = partition-table.csv
|
||||
46
arch/esp32/esp32s3.ini
Normal file
46
arch/esp32/esp32s3.ini
Normal file
@@ -0,0 +1,46 @@
|
||||
[esp32s3_base]
|
||||
extends = arduino_base
|
||||
platform = platformio/espressif32@^5.2.0
|
||||
build_src_filter =
|
||||
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040>
|
||||
upload_speed = 961200
|
||||
monitor_speed = 115200
|
||||
debug_init_break = tbreak setup
|
||||
monitor_filters = esp32_exception_decoder
|
||||
board_build.filesystem = littlefs
|
||||
|
||||
# Remove -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL for low level BLE logging.
|
||||
# See library directory for BLE logging possible values: .pio/libdeps/tbeam/NimBLE-Arduino/src/log_common/log_common.h
|
||||
# This overrides the BLE logging default of LOG_LEVEL_INFO (1) from: .pio/libdeps/tbeam/NimBLE-Arduino/src/esp_nimble_cfg.h
|
||||
build_flags =
|
||||
${arduino_base.build_flags}
|
||||
-Wall
|
||||
-Wextra
|
||||
-Isrc/platform/esp32
|
||||
-std=c++11
|
||||
-DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG
|
||||
-DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
|
||||
-DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL
|
||||
-DAXP_DEBUG_PORT=Serial
|
||||
-DCONFIG_BT_NIMBLE_ENABLED
|
||||
-DCONFIG_NIMBLE_CPP_LOG_LEVEL=2
|
||||
-DCONFIG_BT_NIMBLE_MAX_CCCDS=20
|
||||
-DESP_OPENSSL_SUPPRESS_LEGACY_WARNING
|
||||
|
||||
lib_deps =
|
||||
${arduino_base.lib_deps}
|
||||
${networking_base.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 =
|
||||
segger_rtt
|
||||
ESP32 BLE Arduino
|
||||
|
||||
; customize the partition table
|
||||
; http://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables
|
||||
board_build.partitions = partition-table.csv
|
||||
|
||||
18
arch/nrf52/nrf52.ini
Normal file
18
arch/nrf52/nrf52.ini
Normal file
@@ -0,0 +1,18 @@
|
||||
[nrf52_base]
|
||||
; Instead of the standard nordicnrf52 platform, we use our fork which has our added variant files
|
||||
platform = platformio/nordicnrf52@^9.4.0
|
||||
|
||||
extends = arduino_base
|
||||
build_type = debug ; I'm debugging with ICE a lot now
|
||||
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>
|
||||
lib_ignore =
|
||||
BluetoothOTA
|
||||
|
||||
; Note: By default no lora device is created for this build - it uses a simulated interface
|
||||
[env:feather_nrf52832]
|
||||
extends = nrf52_base
|
||||
board = adafruit_feather_nrf52832
|
||||
14
arch/nrf52/nrf52840.ini
Normal file
14
arch/nrf52/nrf52840.ini
Normal file
@@ -0,0 +1,14 @@
|
||||
[nrf52840_base]
|
||||
extends = nrf52_base
|
||||
build_flags = ${nrf52_base.build_flags}
|
||||
lib_deps =
|
||||
${arduino_base.lib_deps}
|
||||
${environmental_base.lib_deps}
|
||||
https://github.com/Kongduino/Adafruit_nRFCrypto.git#e31a8825ea3300b163a0a3c1ddd5de34e10e1371
|
||||
|
||||
; Note: By default no lora device is created for this build - it uses a simulated interface
|
||||
[env:nrf52840dk]
|
||||
extends = nrf52840_base
|
||||
board = nrf52840_dk
|
||||
|
||||
|
||||
19
arch/portduino/portduino.ini
Normal file
19
arch/portduino/portduino.ini
Normal file
@@ -0,0 +1,19 @@
|
||||
; The Portduino based sim environment on top of any host OS, all hardware will be simulated
|
||||
[portduino_base]
|
||||
build_src_filter =
|
||||
${env.build_src_filter}
|
||||
-<platform/esp32/>
|
||||
-<nimble/>
|
||||
-<platform/nrf52/>
|
||||
-<platform/stm32wl/>
|
||||
-<platform/rp2040>
|
||||
-<mesh/http/>
|
||||
-<modules/esp32>
|
||||
-<modules/Telemetry>
|
||||
+<../variants/portduino>
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
${networking_base.lib_deps}
|
||||
rweather/Crypto@^0.4.0
|
||||
https://github.com/meshtastic/RadioLib.git#5582ac30578ff3f53f20630a00b2a8a4b8f92c74
|
||||
build_flags = ${arduino_base.build_flags} -Isrc/platform/portduino
|
||||
19
arch/rp2040/rp2040.ini
Normal file
19
arch/rp2040/rp2040.ini
Normal file
@@ -0,0 +1,19 @@
|
||||
; Common settings for rp2040 Processor based targets
|
||||
[rp2040_base]
|
||||
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#5ce1a228e7cae453f366deb8962252b9b7356bbc
|
||||
extends = arduino_base
|
||||
board_build.core = earlephilhower
|
||||
board_build.filesystem_size = 0.5m
|
||||
build_flags =
|
||||
${arduino_base.build_flags} -Wno-unused-variable
|
||||
-Isrc/platform/rp2040
|
||||
-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>
|
||||
lib_ignore =
|
||||
BluetoothOTA
|
||||
lib_deps =
|
||||
${arduino_base.lib_deps}
|
||||
${environmental_base.lib_deps}
|
||||
https://github.com/kokke/tiny-AES-c.git#f06ac37fc31dfdaca2e0d9bec83f90d5663c319b
|
||||
18
arch/stm32/stm32wl5e.ini
Normal file
18
arch/stm32/stm32wl5e.ini
Normal file
@@ -0,0 +1,18 @@
|
||||
[stm32wl5e_base]
|
||||
platform = platformio/ststm32@^15.4.1
|
||||
board = generic_wl5e
|
||||
framework = arduino
|
||||
build_type = debug
|
||||
build_flags =
|
||||
${arduino_base.build_flags}
|
||||
-Isrc/platform/stm32wl -g
|
||||
-DHAL_SUBGHZ_MODULE_ENABLED
|
||||
# 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>
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
https://github.com/kokke/tiny-AES-c.git#f06ac37fc31dfdaca2e0d9bec83f90d5663c319b
|
||||
lib_ignore =
|
||||
mathertel/OneButton@^2.0.3
|
||||
BIN
bin/Meshtastic_nRF52_factory_erase.uf2
Normal file
BIN
bin/Meshtastic_nRF52_factory_erase.uf2
Normal file
Binary file not shown.
@@ -29,13 +29,11 @@ SRCELF=.pio/build/$1/firmware.elf
|
||||
cp $SRCELF $OUTDIR/$basename.elf
|
||||
|
||||
echo "Copying ESP32 bin file"
|
||||
SRCBIN=.pio/build/$1/firmware.bin
|
||||
SRCBIN=.pio/build/$1/firmware.factory.bin
|
||||
cp $SRCBIN $OUTDIR/$basename.bin
|
||||
|
||||
echo "Building Filesystem for ESP32 targets"
|
||||
pio run --environment tbeam -t buildfs
|
||||
cp .pio/build/tbeam/spiffs.bin $OUTDIR/littlefs-$VERSION.bin
|
||||
cp images/system-info.bin $OUTDIR/system-info.bin
|
||||
|
||||
cp .pio/build/tbeam/littlefs.bin $OUTDIR/littlefs-$VERSION.bin
|
||||
cp bin/device-install.* $OUTDIR
|
||||
cp bin/device-update.* $OUTDIR
|
||||
|
||||
@@ -26,7 +26,9 @@ basename=firmware-$1-$VERSION
|
||||
|
||||
pio run --environment $1 # -v
|
||||
SRCELF=.pio/build/$1/firmware.elf
|
||||
DFUPKG=.pio/build/$1/firmware.zip
|
||||
cp $SRCELF $OUTDIR/$basename.elf
|
||||
cp $DFUPKG $OUTDIR/$basename-ota.zip
|
||||
|
||||
echo "Generating NRF52 uf2 file"
|
||||
SRCHEX=.pio/build/$1/firmware.hex
|
||||
@@ -34,3 +36,4 @@ bin/uf2conv.py $SRCHEX -c -o $OUTDIR/$basename.uf2 -f 0xADA52840
|
||||
|
||||
cp bin/device-install.* $OUTDIR
|
||||
cp bin/device-update.* $OUTDIR
|
||||
cp bin/*.uf2 $OUTDIR
|
||||
|
||||
23
bin/check-dependencies.sh
Normal file
23
bin/check-dependencies.sh
Normal file
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Note: This is a prototype for how we could add static code analysis to the CI.
|
||||
|
||||
set -e
|
||||
|
||||
if [[ $# -gt 0 ]]; then
|
||||
# can override which environment by passing arg
|
||||
BOARDS="$@"
|
||||
else
|
||||
BOARDS="rak4631 rak4631_eink t-echo pca10059_diy_eink pico rak11200 tlora-v2 tlora-v1 tlora_v1_3 tlora-v2-1-1.6 tbeam heltec-v1 heltec-v2.0 heltec-v2.1 tbeam0.7 meshtastic-diy-v1 nano-g1 station-g1 m5stack-core m5stack-coreink tbeam-s3-core"
|
||||
fi
|
||||
|
||||
echo "BOARDS:${BOARDS}"
|
||||
|
||||
CHECK=""
|
||||
for BOARD in $BOARDS; do
|
||||
CHECK="${CHECK} -e ${BOARD}"
|
||||
done
|
||||
|
||||
echo $CHECK
|
||||
|
||||
pio pkg outdated -e $CHECK
|
||||
@@ -29,11 +29,11 @@ IF "__%FILENAME%__" == "____" (
|
||||
IF EXIST %FILENAME% (
|
||||
echo Trying to flash update %FILENAME%, but first erasing and writing system information"
|
||||
%PYTHON% -m esptool --baud 115200 erase_flash
|
||||
%PYTHON% -m esptool --baud 115200 write_flash 0x1000 system-info.bin
|
||||
%PYTHON% -m esptool --baud 115200 write_flash 0x00 %FILENAME%
|
||||
%PYTHON% -m esptool --baud 115200 write_flash 0x260000 bleota.bin
|
||||
for %%f in (littlefs-*.bin) do (
|
||||
%PYTHON% -m esptool --baud 115200 write_flash 0x2B0000 %%f
|
||||
%PYTHON% -m esptool --baud 115200 write_flash 0x300000 %%f
|
||||
)
|
||||
%PYTHON% -m esptool --baud 115200 write_flash 0x10000 %FILENAME%
|
||||
) else (
|
||||
echo "Invalid file: %FILENAME%"
|
||||
goto HELP
|
||||
|
||||
@@ -47,9 +47,10 @@ shift "$((OPTIND-1))"
|
||||
if [ -f "${FILENAME}" ]; then
|
||||
echo "Trying to flash ${FILENAME}, but first erasing and writing system information"
|
||||
"$PYTHON" -m esptool erase_flash
|
||||
"$PYTHON" -m esptool write_flash 0x1000 system-info.bin
|
||||
"$PYTHON" -m esptool write_flash 0x2B0000 littlefs-*.bin
|
||||
"$PYTHON" -m esptool write_flash 0x10000 ${FILENAME}
|
||||
"$PYTHON" -m esptool write_flash 0x00 ${FILENAME}
|
||||
"$PYTHON" -m esptool write_flash 0x260000 bleota.bin
|
||||
"$PYTHON" -m esptool write_flash 0x300000 littlefs-*.bin
|
||||
|
||||
else
|
||||
echo "Invalid file: ${FILENAME}"
|
||||
show_help
|
||||
|
||||
@@ -28,7 +28,7 @@ IF "__%FILENAME%__" == "____" (
|
||||
)
|
||||
IF EXIST %FILENAME% (
|
||||
echo Trying to flash update %FILENAME%
|
||||
%PYTHON% -m esptool --baud 115200 write_flash 0x10000 %FILENAME%
|
||||
%PYTHON% -m esptool --baud 115200 write_flash 0x00 %FILENAME%
|
||||
) else (
|
||||
echo "Invalid file: %FILENAME%"
|
||||
goto HELP
|
||||
|
||||
@@ -44,7 +44,7 @@ shift "$((OPTIND-1))"
|
||||
|
||||
if [ -f "${FILENAME}" ]; then
|
||||
echo "Trying to flash update ${FILENAME}."
|
||||
$PYTHON -m esptool --baud 115200 write_flash 0x10000 ${FILENAME}
|
||||
$PYTHON -m esptool --baud 115200 write_flash 0x00 ${FILENAME}
|
||||
else
|
||||
echo "Invalid file: ${FILENAME}"
|
||||
show_help
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
import getopt
|
||||
import sys
|
||||
import os
|
||||
from littlefs import LittleFS
|
||||
from pathlib import Path
|
||||
|
||||
print( "Building LittleFS image..." )
|
||||
|
||||
argList = sys.argv[1:]
|
||||
arxx = { argList[i]: argList[i+1] for i in range(0, len(argList)-1, 2) }
|
||||
|
||||
dataPath = arxx["-c"]
|
||||
blockSize = int(arxx["-b"])
|
||||
blockCount = int(arxx["-s"]) / blockSize
|
||||
|
||||
cwd = os.getcwd()
|
||||
|
||||
os.chdir(dataPath)
|
||||
|
||||
fileList = []
|
||||
dirList = []
|
||||
|
||||
for (dirpath, dirnames, filenames) in os.walk('.'):
|
||||
for f in filenames:
|
||||
if (f[:1] != '.'):
|
||||
fileList.append( os.path.join(dirpath, f) )
|
||||
for d in dirnames:
|
||||
if (d[:1] != '.'):
|
||||
dirList.append( os.path.join(dirpath, d) )
|
||||
|
||||
fs = LittleFS(block_size=blockSize, block_count=blockCount) # create a 448kB partition
|
||||
|
||||
for curDir in dirList:
|
||||
print( "Creating dir " + curDir )
|
||||
fs.mkdir( curDir )
|
||||
|
||||
for curFile in fileList:
|
||||
print( "Adding file " + curFile )
|
||||
with open( curFile, 'rb' ) as f:
|
||||
data = f.read()
|
||||
|
||||
with fs.open( curFile, 'wb') as fh:
|
||||
fh.write( data )
|
||||
|
||||
outName = argList[-1]
|
||||
|
||||
os.chdir(cwd)
|
||||
|
||||
with open(outName, 'wb') as fh:
|
||||
fh.write(fs.context.buffer)
|
||||
@@ -1,24 +1,70 @@
|
||||
|
||||
|
||||
import subprocess
|
||||
import configparser
|
||||
import traceback
|
||||
import sys
|
||||
from os.path import join
|
||||
from readprops import readProps
|
||||
|
||||
Import("env")
|
||||
env.Replace( MKSPIFFSTOOL=env.get("PROJECT_DIR") + '/bin/mklittlefs.py' )
|
||||
try:
|
||||
import littlefs
|
||||
except ImportError:
|
||||
env.Execute("$PYTHONEXE -m pip install littlefs-python")
|
||||
platform = env.PioPlatform()
|
||||
|
||||
def esp32_create_combined_bin(source, target, env):
|
||||
# this sub is borrowed from ESPEasy build toolchain. It's licensed under GPL V3
|
||||
# https://github.com/letscontrolit/ESPEasy/blob/mega/tools/pio/post_esp32.py
|
||||
print("Generating combined binary for serial flashing")
|
||||
|
||||
app_offset = 0x10000
|
||||
|
||||
new_file_name = env.subst("$BUILD_DIR/${PROGNAME}.factory.bin")
|
||||
sections = env.subst(env.get("FLASH_EXTRA_IMAGES"))
|
||||
firmware_name = env.subst("$BUILD_DIR/${PROGNAME}.bin")
|
||||
chip = env.get("BOARD_MCU")
|
||||
flash_size = env.BoardConfig().get("upload.flash_size")
|
||||
flash_freq = env.BoardConfig().get("build.f_flash", '40m')
|
||||
flash_freq = flash_freq.replace('000000L', 'm')
|
||||
flash_mode = env.BoardConfig().get("build.flash_mode", "dio")
|
||||
memory_type = env.BoardConfig().get("build.arduino.memory_type", "qio_qspi")
|
||||
if flash_mode == "qio" or flash_mode == "qout":
|
||||
flash_mode = "dio"
|
||||
if memory_type == "opi_opi" or memory_type == "opi_qspi":
|
||||
flash_mode = "dout"
|
||||
cmd = [
|
||||
"--chip",
|
||||
chip,
|
||||
"merge_bin",
|
||||
"-o",
|
||||
new_file_name,
|
||||
"--flash_mode",
|
||||
flash_mode,
|
||||
"--flash_freq",
|
||||
flash_freq,
|
||||
"--flash_size",
|
||||
flash_size,
|
||||
]
|
||||
|
||||
print(" Offset | File")
|
||||
for section in sections:
|
||||
sect_adr, sect_file = section.split(" ", 1)
|
||||
print(f" - {sect_adr} | {sect_file}")
|
||||
cmd += [sect_adr, sect_file]
|
||||
|
||||
print(f" - {hex(app_offset)} | {firmware_name}")
|
||||
cmd += [hex(app_offset), firmware_name]
|
||||
|
||||
print('Using esptool.py arguments: %s' % ' '.join(cmd))
|
||||
|
||||
esptool.main(cmd)
|
||||
|
||||
if (platform.name == "espressif32"):
|
||||
sys.path.append(join(platform.get_package_dir("tool-esptoolpy")))
|
||||
import esptool
|
||||
env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", esp32_create_combined_bin)
|
||||
|
||||
Import("projenv")
|
||||
|
||||
prefsLoc = projenv["PROJECT_DIR"] + "/version.properties"
|
||||
verObj = readProps(prefsLoc)
|
||||
print("Using meshtastic platformio-custom.py, firmware version " + verObj['long'])
|
||||
# print("path is" + ','.join(sys.path))
|
||||
|
||||
# General options that are passed to the C and C++ compilers
|
||||
projenv.Append(CCFLAGS=[
|
||||
|
||||
48
boards/tbeam-s3-core.json
Normal file
48
boards/tbeam-s3-core.json
Normal file
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino":{
|
||||
"ldscript": "esp32s3_out.ld"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"-DBOARD_HAS_PSRAM",
|
||||
"-DLILYGO_TBEAM_S3_CORE",
|
||||
"-DARDUINO_USB_CDC_ON_BOOT=1",
|
||||
"-DARDUINO_USB_DFU_ON_BOOT=1",
|
||||
"-DARDUINO_USB_MSC_ON_BOOT=1",
|
||||
"-DARDUINO_USB_MODE=1",
|
||||
"-DARDUINO_RUNNING_CORE=1",
|
||||
"-DARDUINO_EVENT_RUNNING_CORE=1"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "80000000L",
|
||||
"flash_mode": "dio",
|
||||
"hwids": [
|
||||
[
|
||||
"0X303A",
|
||||
"0x1001"
|
||||
]
|
||||
],
|
||||
"mcu": "esp32s3",
|
||||
"variant": "tbeam-s3-core"
|
||||
},
|
||||
"connectivity": [
|
||||
"wifi"
|
||||
],
|
||||
"debug": {
|
||||
"openocd_target": "esp32s3.cfg"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"name": "LilyGo TBeam-S3-Core",
|
||||
"upload": {
|
||||
"flash_size": "8MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 8388608,
|
||||
"require_upload_port": true,
|
||||
"speed": 921600
|
||||
},
|
||||
"url": "http://www.lilygo.cn/",
|
||||
"vendor": "LilyGo"
|
||||
}
|
||||
Binary file not shown.
@@ -1,7 +1,8 @@
|
||||
# FIXME! using the genpartitions based table doesn't work on TTGO so for now I stay with my old memory map
|
||||
# This is a layout for 4MB of flash
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
nvs, data, nvs, 0x9000, 0x5000,
|
||||
otadata, data, ota, 0xe000, 0x2000,
|
||||
app0, app, ota_0, 0x10000, 0x2A0000,
|
||||
spiffs, data, spiffs, 0x2B0000,0x150000,
|
||||
nvs, data, nvs, 0x009000, 0x005000,
|
||||
otadata, data, ota, 0x00e000, 0x002000,
|
||||
app, app, ota_0, 0x010000, 0x250000,
|
||||
flashApp, app, ota_1, 0x260000, 0x0A0000,
|
||||
spiffs, data, spiffs, 0x300000, 0x100000,
|
||||
|
140
platformio.ini
140
platformio.ini
@@ -2,7 +2,9 @@
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[platformio]
|
||||
default_envs = tbeam
|
||||
;default_envs = tbeam
|
||||
;default_envs = pico
|
||||
;default_envs = tbeam-s3-core
|
||||
;default_envs = tbeam0.7
|
||||
;default_envs = heltec-v1
|
||||
;default_envs = heltec-v2.0
|
||||
@@ -23,7 +25,9 @@ default_envs = tbeam
|
||||
;default_envs = m5stack-coreink
|
||||
;default_envs = rak4631
|
||||
|
||||
extra_configs = variants/*/platformio.ini
|
||||
extra_configs =
|
||||
arch/*/*.ini
|
||||
variants/*/platformio.ini
|
||||
|
||||
[env]
|
||||
extra_scripts = bin/platformio-custom.py
|
||||
@@ -44,13 +48,11 @@ monitor_speed = 115200
|
||||
lib_deps =
|
||||
https://github.com/meshtastic/esp8266-oled-ssd1306.git#53580644255b48ebb7a737343c6b4e71c7e11cf2 ; ESP8266_SSD1306
|
||||
mathertel/OneButton@^2.0.3 ; OneButton library for non-blocking button debounce
|
||||
1202 ; CRC32, explicitly needed because dependency is missing in the ble ota update lib
|
||||
https://github.com/meshtastic/arduino-fsm.git
|
||||
https://github.com/meshtastic/TinyGPSPlus.git
|
||||
Wire ; explicitly needed here because the AXP202 library forgets to add it
|
||||
SPI
|
||||
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
|
||||
https://github.com/meshtastic/TinyGPSPlus.git#2f0d0528d737000043e949f4c3bdfb623cf0b902
|
||||
https://github.com/meshtastic/ArduinoThread.git#72921ac222eed6f526ba1682023cee290d9aa1b3
|
||||
nanopb/Nanopb@^0.4.6
|
||||
erriez/ErriezCRC32@^1.0.1
|
||||
|
||||
; Used for the code analysis in PIO Home / Inspect
|
||||
check_tool = cppcheck
|
||||
@@ -62,16 +64,18 @@ framework = arduino
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
; Portduino is using meshtastic fork for now
|
||||
https://github.com/jgromes/RadioLib.git
|
||||
jgromes/RadioLib@5.4.1
|
||||
https://github.com/caveman99/SparkFun_ATECCX08a_Arduino_Library.git#008e7f9d40bad66b2f7a0074aaac05b7c424339d
|
||||
|
||||
build_flags = ${env.build_flags} -Os
|
||||
-DRADIOLIB_SPI_PARANOID=0
|
||||
# -DRADIOLIB_GODMODE
|
||||
build_src_filter = ${env.build_src_filter} -<platform/portduino/>
|
||||
|
||||
; Common libs for communicating over TCP/IP networks such as MQTT
|
||||
[networking_base]
|
||||
lib_deps =
|
||||
PubSubClient
|
||||
knolleary/PubSubClient@^2.8
|
||||
meshtastic/json11@^1.0.2
|
||||
|
||||
; Common libs for environmental measurements in telemetry module
|
||||
@@ -80,126 +84,10 @@ lib_deps =
|
||||
lib_deps =
|
||||
adafruit/Adafruit BusIO@^1.11.4
|
||||
adafruit/Adafruit Unified Sensor@^1.1.4
|
||||
adafruit/Adafruit BMP280 Library@^2.6.3
|
||||
adafruit/Adafruit BMP280 Library@^2.6.6
|
||||
adafruit/Adafruit BME280 Library@^2.2.2
|
||||
adafruit/Adafruit BME680 Library@^2.0.1
|
||||
adafruit/Adafruit MCP9808 Library@^2.0.0
|
||||
adafruit/Adafruit INA260 Library@^1.5.0
|
||||
adafruit/Adafruit INA219@^1.2.0
|
||||
; Common settings for ESP targes, mixin with extends = esp32_base
|
||||
[esp32_base]
|
||||
extends = arduino_base
|
||||
platform = espressif32@3.5.0
|
||||
build_src_filter =
|
||||
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040>
|
||||
upload_speed = 115200
|
||||
debug_init_break = tbreak setup
|
||||
|
||||
# Remove -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL for low level BLE logging.
|
||||
# See library directory for BLE logging possible values: .pio/libdeps/tbeam/NimBLE-Arduino/src/log_common/log_common.h
|
||||
# This overrides the BLE logging default of LOG_LEVEL_INFO (1) from: .pio/libdeps/tbeam/NimBLE-Arduino/src/esp_nimble_cfg.h
|
||||
build_flags =
|
||||
${arduino_base.build_flags} -Wall -Wextra -Isrc/platform/esp32 -lnimble -std=c++11
|
||||
-DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL
|
||||
-DAXP_DEBUG_PORT=Serial -DCONFIG_BT_NIMBLE_ENABLED -DCONFIG_NIMBLE_CPP_LOG_LEVEL=2 -DCONFIG_BT_NIMBLE_MAX_CCCDS=20
|
||||
lib_deps =
|
||||
${arduino_base.lib_deps}
|
||||
${networking_base.lib_deps}
|
||||
${environmental_base.lib_deps}
|
||||
https://github.com/meshtastic/esp32_https_server.git
|
||||
h2zero/NimBLE-Arduino@1.4.0
|
||||
arduino-libraries/NTPClient@^3.1.0
|
||||
lorol/LittleFS_esp32@^1.0.6
|
||||
https://github.com/meshtastic/AXP202X_Library.git#8404abb6d4b486748636bc6ad72d2a47baaf5460
|
||||
|
||||
lib_ignore =
|
||||
segger_rtt
|
||||
ESP32 BLE Arduino
|
||||
platform_packages =
|
||||
framework-arduinoespressif32@https://github.com/meshtastic/arduino-esp32.git#4cde0f5d412d2695184f32e8a47e9bea57b45276
|
||||
|
||||
; leave this commented out to avoid breaking Windows
|
||||
;upload_port = /dev/ttyUSB0
|
||||
;monitor_port = /dev/ttyUSB0
|
||||
|
||||
; Please don't delete these lines. JM uses them.
|
||||
;upload_port = /dev/cu.SLAB_USBtoUART
|
||||
;monitor_port = /dev/cu.SLAB_USBtoUART
|
||||
|
||||
; customize the partition table
|
||||
; http://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables
|
||||
board_build.partitions = partition-table.csv
|
||||
|
||||
[nrf52_base]
|
||||
; Instead of the standard nordicnrf52 platform, we use our fork which has our added variant files
|
||||
; platform = nordicnrf52 ;pending https://github.com/platformio/builder-framework-arduino-nrf5/pull/7
|
||||
platform = https://github.com/meshtastic/platform-nordicnrf52.git#merge
|
||||
|
||||
extends = arduino_base
|
||||
build_type = debug ; I'm debugging with ICE a lot now
|
||||
; note: liboberon provides the AES256 implementation for NRF52 (though not using the hardware acceleration of the NRF52840 - FIXME)
|
||||
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>
|
||||
lib_ignore =
|
||||
BluetoothOTA
|
||||
|
||||
[nrf52840_base]
|
||||
extends = nrf52_base
|
||||
build_flags = ${nrf52_base.build_flags}
|
||||
lib_deps =
|
||||
${arduino_base.lib_deps}
|
||||
${environmental_base.lib_deps}
|
||||
https://github.com/Kongduino/Adafruit_nRFCrypto.git
|
||||
|
||||
; Note: By default no lora device is created for this build - it uses a simulated interface
|
||||
[env:nrf52840dk]
|
||||
extends = nrf52840_base
|
||||
board = nrf52840_dk
|
||||
|
||||
; Note: By default no lora device is created for this build - it uses a simulated interface
|
||||
[env:feather_nrf52832]
|
||||
extends = nrf52_base
|
||||
board = adafruit_feather_nrf52832
|
||||
|
||||
; Common settings for rp2040 Processor based targets
|
||||
[rp2040_base]
|
||||
platform = https://github.com/maxgerhardt/platform-raspberrypi.git
|
||||
extends = arduino_base
|
||||
board_build.core = earlephilhower
|
||||
board_build.filesystem_size = 0.5m
|
||||
build_flags =
|
||||
${arduino_base.build_flags} -Wno-unused-variable
|
||||
-Isrc/platform/rp2040
|
||||
-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>
|
||||
lib_ignore =
|
||||
BluetoothOTA
|
||||
lib_deps =
|
||||
${arduino_base.lib_deps}
|
||||
${environmental_base.lib_deps}
|
||||
https://github.com/kokke/tiny-AES-c.git
|
||||
|
||||
[stm32wl5e_base]
|
||||
platform = ststm32
|
||||
board = generic_wl5e
|
||||
framework = arduino
|
||||
build_type = debug
|
||||
build_flags =
|
||||
${arduino_base.build_flags}
|
||||
-Isrc/platform/stm32wl -g
|
||||
-DHAL_SUBGHZ_MODULE_ENABLED
|
||||
# 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>
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
https://github.com/jgromes/RadioLib.git
|
||||
https://github.com/kokke/tiny-AES-c.git
|
||||
lib_ignore =
|
||||
mathertel/OneButton@^2.0.3
|
||||
|
||||
Submodule protobufs updated: a72983993c...d3dfaa63a5
@@ -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};
|
||||
@@ -9,7 +9,7 @@
|
||||
#define MESH_SERVICE_UUID "6ba1b218-15a8-461f-9fa8-5dcae273eafd"
|
||||
|
||||
#define TORADIO_UUID "f75c76d2-129e-4dad-a1dd-7866124401e7"
|
||||
#define FROMRADIO_UUID "8ba2bcc2-ee02-4a55-a531-c525c5e454d5"
|
||||
#define FROMRADIO_UUID "2c55e69e-4993-11ed-b878-0242ac120002"
|
||||
#define FROMNUM_UUID "ed9da18c-a800-4f66-a670-aa7547e34453"
|
||||
|
||||
// NRF52 wants these constants as byte arrays
|
||||
|
||||
@@ -128,8 +128,8 @@ class ButtonThread : public concurrency::OSThread
|
||||
#endif
|
||||
// If user button is held down for 5 seconds, shutdown the device.
|
||||
if ((millis() - longPressTime > 5 * 1000) && (longPressTime > 0)) {
|
||||
#ifdef HAS_AXP192
|
||||
if (axp192_found == true) {
|
||||
#ifdef HAS_PMU
|
||||
if (pmu_found == true) {
|
||||
setLed(false);
|
||||
power->shutdown();
|
||||
}
|
||||
|
||||
132
src/FSCommon.cpp
132
src/FSCommon.cpp
@@ -9,13 +9,13 @@ bool copyFile(const char* from, const char* to)
|
||||
|
||||
File f1 = FSCom.open(from, FILE_O_READ);
|
||||
if (!f1){
|
||||
DEBUG_MSG("Failed to open file");
|
||||
DEBUG_MSG("Failed to open source file %s\n", from);
|
||||
return false;
|
||||
}
|
||||
|
||||
File f2 = FSCom.open(to, FILE_O_WRITE);
|
||||
if (!f2) {
|
||||
DEBUG_MSG("Failed to open file");
|
||||
DEBUG_MSG("Failed to open destination file %s\n", to);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -33,17 +33,25 @@ bool copyFile(const char* from, const char* to)
|
||||
bool renameFile(const char* pathFrom, const char* pathTo)
|
||||
{
|
||||
#ifdef FSCom
|
||||
#ifdef ARCH_ESP32
|
||||
// rename was fixed for ESP32 IDF LittleFS in April
|
||||
return FSCom.rename(pathFrom, pathTo);
|
||||
#else
|
||||
if (copyFile(pathFrom, pathTo) && FSCom.remove(pathFrom) ) {
|
||||
return true;
|
||||
} else{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void listDir(const char * dirname, uint8_t levels)
|
||||
void listDir(const char * dirname, uint8_t levels, boolean del = false)
|
||||
{
|
||||
#ifdef FSCom
|
||||
#if (defined(ARCH_ESP32) || defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
|
||||
char buffer[255];
|
||||
#endif
|
||||
File root = FSCom.open(dirname, FILE_O_READ);
|
||||
if(!root){
|
||||
return;
|
||||
@@ -56,55 +64,92 @@ void listDir(const char * dirname, uint8_t levels)
|
||||
while(file){
|
||||
if(file.isDirectory() && !String(file.name()).endsWith(".")) {
|
||||
if(levels){
|
||||
listDir(file.name(), levels -1);
|
||||
#ifdef ARCH_ESP32
|
||||
listDir(file.path(), levels -1, del);
|
||||
if(del) {
|
||||
DEBUG_MSG("Removing %s\n", file.path());
|
||||
strcpy(buffer, file.path());
|
||||
file.close();
|
||||
FSCom.rmdir(buffer);
|
||||
} else {
|
||||
file.close();
|
||||
}
|
||||
#elif (defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
|
||||
listDir(file.name(), levels -1, del);
|
||||
if(del) {
|
||||
DEBUG_MSG("Removing %s\n", file.name());
|
||||
strcpy(buffer, file.name());
|
||||
file.close();
|
||||
FSCom.rmdir(buffer);
|
||||
} else {
|
||||
file.close();
|
||||
}
|
||||
#else
|
||||
listDir(file.name(), levels -1, del);
|
||||
file.close();
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
DEBUG_MSG(" %s (%i Bytes)\n", file.name(), file.size());
|
||||
#ifdef ARCH_ESP32
|
||||
if(del) {
|
||||
DEBUG_MSG("Deleting %s\n", file.path());
|
||||
strcpy(buffer, file.path());
|
||||
file.close();
|
||||
FSCom.remove(buffer);
|
||||
} else {
|
||||
DEBUG_MSG(" %s (%i Bytes)\n", file.path(), file.size());
|
||||
file.close();
|
||||
}
|
||||
#elif (defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
|
||||
if(del) {
|
||||
DEBUG_MSG("Deleting %s\n", file.name());
|
||||
strcpy(buffer, file.name());
|
||||
file.close();
|
||||
FSCom.remove(buffer);
|
||||
} else {
|
||||
DEBUG_MSG(" %s (%i Bytes)\n", file.name(), file.size());
|
||||
file.close();
|
||||
}
|
||||
#else
|
||||
DEBUG_MSG(" %s (%i Bytes)\n", file.name(), file.size());
|
||||
file.close();
|
||||
#endif
|
||||
}
|
||||
file.close();
|
||||
file = root.openNextFile();
|
||||
}
|
||||
file.close();
|
||||
#ifdef ARCH_ESP32
|
||||
if(del) {
|
||||
DEBUG_MSG("Removing %s\n", root.path());
|
||||
strcpy(buffer, root.path());
|
||||
root.close();
|
||||
FSCom.rmdir(buffer);
|
||||
} else {
|
||||
root.close();
|
||||
}
|
||||
#elif (defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
|
||||
if(del) {
|
||||
DEBUG_MSG("Removing %s\n", root.name());
|
||||
strcpy(buffer, root.name());
|
||||
root.close();
|
||||
FSCom.rmdir(buffer);
|
||||
} else {
|
||||
root.close();
|
||||
}
|
||||
#else
|
||||
root.close();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void rmDir(const char * dirname)
|
||||
{
|
||||
#ifdef FSCom
|
||||
File file = FSCom.open(dirname, FILE_O_READ);
|
||||
if(!file){
|
||||
return;
|
||||
}
|
||||
if(!file.isDirectory()){
|
||||
file.close();
|
||||
FSCom.remove(file.name());
|
||||
// DEBUG_MSG("Remove FILE %s\n", file.name());
|
||||
return;
|
||||
}
|
||||
|
||||
file.rewindDirectory();
|
||||
while (true) {
|
||||
File entry = file.openNextFile();
|
||||
if (!entry) {
|
||||
break;
|
||||
}
|
||||
char dirpath[100]; // array to hold the result.
|
||||
strcpy(dirpath, dirname); // copy string one into the result.
|
||||
strcat(dirpath,"/"); // append string two to the result.
|
||||
strcat(dirpath,entry.name()); // append string two to the result.
|
||||
if(entry.isDirectory() && !String(entry.name()).endsWith(".")) {
|
||||
entry.close();
|
||||
// DEBUG_MSG("Descend DIR %s\n", dirpath);
|
||||
rmDir(dirpath);
|
||||
} else {
|
||||
entry.close();
|
||||
// DEBUG_MSG("Remove FILE %s\n", entry.name());
|
||||
FSCom.remove(entry.name());
|
||||
}
|
||||
}
|
||||
FSCom.rmdir(dirname);
|
||||
// DEBUG_MSG("Remove DIR %s\n", dirname);
|
||||
file.close();
|
||||
#if (defined(ARCH_ESP32) || defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
|
||||
listDir(dirname, 10, true);
|
||||
#elif defined(ARCH_NRF52)
|
||||
// nRF52 implementation of LittleFS has a recursive delete function
|
||||
FSCom.rmdir_r(dirname);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -116,8 +161,11 @@ void fsInit()
|
||||
DEBUG_MSG("ERROR filesystem mount Failed. Formatting...\n");
|
||||
assert(0); // FIXME - report failure to phone
|
||||
}
|
||||
|
||||
#ifdef ARCH_ESP32
|
||||
DEBUG_MSG("Filesystem files (%d/%d Bytes):\n", FSCom.usedBytes(), FSCom.totalBytes());
|
||||
#else
|
||||
DEBUG_MSG("Filesystem files:\n");
|
||||
#endif
|
||||
listDir("/", 10);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
|
||||
#if defined(ARCH_ESP32)
|
||||
// ESP32 version
|
||||
#include "LITTLEFS.h"
|
||||
#define FSCom LITTLEFS
|
||||
#include "LittleFS.h"
|
||||
#define FSCom LittleFS
|
||||
#define FSBegin() FSCom.begin(true)
|
||||
#define FILE_O_WRITE "w"
|
||||
#define FILE_O_READ "r"
|
||||
@@ -40,6 +40,7 @@ using namespace Adafruit_LittleFS_Namespace;
|
||||
#endif
|
||||
|
||||
void fsInit();
|
||||
bool copyFile(const char* from, const char* to);
|
||||
bool renameFile(const char* pathFrom, const char* pathTo);
|
||||
void listDir(const char * dirname, uint8_t levels);
|
||||
void listDir(const char * dirname, uint8_t levels, boolean del);
|
||||
void rmDir(const char * dirname);
|
||||
|
||||
@@ -25,21 +25,21 @@ class GPSStatus : public Status
|
||||
public:
|
||||
GPSStatus() { statusType = STATUS_TYPE_GPS; }
|
||||
|
||||
// proposed for deprecation
|
||||
GPSStatus(bool hasLock, bool isConnected, int32_t latitude, int32_t longitude, int32_t altitude, uint32_t dop,
|
||||
uint32_t heading, uint32_t numSatellites)
|
||||
: Status()
|
||||
{
|
||||
this->hasLock = hasLock;
|
||||
this->isConnected = isConnected;
|
||||
// // proposed for deprecation
|
||||
// GPSStatus(bool hasLock, bool isConnected, int32_t latitude, int32_t longitude, int32_t altitude, uint32_t dop,
|
||||
// uint32_t heading, uint32_t numSatellites)
|
||||
// : Status()
|
||||
// {
|
||||
// this->hasLock = hasLock;
|
||||
// this->isConnected = isConnected;
|
||||
|
||||
this->p.latitude_i = latitude;
|
||||
this->p.longitude_i = longitude;
|
||||
this->p.altitude = altitude;
|
||||
this->p.PDOP = dop;
|
||||
this->p.ground_track = heading;
|
||||
this->p.sats_in_view = numSatellites;
|
||||
}
|
||||
// this->p.latitude_i = latitude;
|
||||
// this->p.longitude_i = longitude;
|
||||
// this->p.altitude = altitude;
|
||||
// this->p.PDOP = dop;
|
||||
// this->p.ground_track = heading;
|
||||
// this->p.sats_in_view = numSatellites;
|
||||
// }
|
||||
|
||||
// preferred method
|
||||
GPSStatus(bool hasLock, bool isConnected, const Position &pos) : Status()
|
||||
@@ -114,6 +114,7 @@ class GPSStatus : public Status
|
||||
newStatus->p.latitude_i != p.latitude_i || newStatus->p.longitude_i != p.longitude_i ||
|
||||
newStatus->p.altitude != p.altitude || newStatus->p.altitude_hae != p.altitude_hae ||
|
||||
newStatus->p.PDOP != p.PDOP || newStatus->p.ground_track != p.ground_track ||
|
||||
newStatus->p.ground_speed != p.ground_speed ||
|
||||
newStatus->p.sats_in_view != p.sats_in_view);
|
||||
}
|
||||
|
||||
@@ -122,7 +123,7 @@ class GPSStatus : public Status
|
||||
// Only update the status if values have actually changed
|
||||
bool isDirty = matches(newStatus);
|
||||
|
||||
if (isDirty && p.pos_timestamp && (newStatus->p.pos_timestamp == p.pos_timestamp)) {
|
||||
if (isDirty && p.timestamp && (newStatus->p.timestamp == p.timestamp)) {
|
||||
// We can NEVER be in two locations at the same time! (also PR #886)
|
||||
DEBUG_MSG("BUG!! positional timestamp unchanged from prev solution\n");
|
||||
}
|
||||
@@ -136,9 +137,9 @@ class GPSStatus : public Status
|
||||
if (isDirty) {
|
||||
if (hasLock) {
|
||||
// In debug logs, identify position by @timestamp:stage (stage 3 = notify)
|
||||
DEBUG_MSG("New GPS pos@%x:3 lat=%f, lon=%f, alt=%d, pdop=%.2f, track=%.2f, sats=%d\n", p.pos_timestamp,
|
||||
DEBUG_MSG("New GPS pos@%x:3 lat=%f, lon=%f, alt=%d, pdop=%.2f, track=%.2f, speed=%.2f, sats=%d\n", p.timestamp,
|
||||
p.latitude_i * 1e-7, p.longitude_i * 1e-7, p.altitude, p.PDOP * 1e-2, p.ground_track * 1e-5,
|
||||
p.sats_in_view);
|
||||
p.ground_speed * 1e-2, p.sats_in_view);
|
||||
} else
|
||||
DEBUG_MSG("No GPS lock\n");
|
||||
onNewStatus.notifyObservers(this);
|
||||
|
||||
445
src/Power.cpp
445
src/Power.cpp
@@ -7,10 +7,11 @@
|
||||
#include "utils.h"
|
||||
#include "buzz/buzz.h"
|
||||
|
||||
#ifdef HAS_AXP192
|
||||
#include "axp20x.h"
|
||||
|
||||
AXP20X_Class axp;
|
||||
#ifdef HAS_PMU
|
||||
#include "XPowersLibInterface.hpp"
|
||||
#include "XPowersAXP2101.tpp"
|
||||
#include "XPowersAXP192.tpp"
|
||||
XPowersLibInterface *PMU = NULL;
|
||||
#else
|
||||
// Copy of the base class defined in axp20x.h.
|
||||
// I'd rather not inlude axp20x.h as it brings Wire dependency.
|
||||
@@ -20,20 +21,20 @@ class HasBatteryLevel
|
||||
/**
|
||||
* Battery state of charge, from 0 to 100 or -1 for unknown
|
||||
*/
|
||||
virtual int getBattPercentage() { return -1; }
|
||||
virtual int getBatteryPercent() { return -1; }
|
||||
|
||||
/**
|
||||
* The raw voltage of the battery or NAN if unknown
|
||||
*/
|
||||
virtual float getBattVoltage() { return NAN; }
|
||||
virtual uint16_t getBattVoltage() { return 0; }
|
||||
|
||||
/**
|
||||
* return true if there is a battery installed in this unit
|
||||
*/
|
||||
virtual bool isBatteryConnect() { return false; }
|
||||
|
||||
virtual bool isVBUSPlug() { return false; }
|
||||
virtual bool isChargeing() { return false; }
|
||||
virtual bool isVbusIn() { return false; }
|
||||
virtual bool isCharging() { return false; }
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -75,7 +76,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
*
|
||||
* FIXME - use a lipo lookup table, the current % full is super wrong
|
||||
*/
|
||||
virtual int getBattPercentage() override
|
||||
virtual int getBatteryPercent() override
|
||||
{
|
||||
float v = getBattVoltage();
|
||||
|
||||
@@ -94,7 +95,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
/**
|
||||
* The raw voltage of the batteryin millivolts or NAN if unknown
|
||||
*/
|
||||
virtual float getBattVoltage() override
|
||||
virtual uint16_t getBattVoltage() override
|
||||
{
|
||||
|
||||
#ifndef ADC_MULTIPLIER
|
||||
@@ -135,22 +136,22 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
return last_read_value;
|
||||
}
|
||||
#else
|
||||
return NAN;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* return true if there is a battery installed in this unit
|
||||
*/
|
||||
virtual bool isBatteryConnect() override { return getBattPercentage() != -1; }
|
||||
virtual bool isBatteryConnect() override { return getBatteryPercent() != -1; }
|
||||
|
||||
/// If we see a battery voltage higher than physics allows - assume charger is pumping
|
||||
/// in power
|
||||
virtual bool isVBUSPlug() override { return getBattVoltage() > chargingVolt; }
|
||||
virtual bool isVbusIn() override { return getBattVoltage() > chargingVolt; }
|
||||
|
||||
/// Assume charging if we have a battery and external power is connected.
|
||||
/// we can't be smart enough to say 'full'?
|
||||
virtual bool isChargeing() override { return isBatteryConnect() && isVBUSPlug(); }
|
||||
virtual bool isCharging() override { return isBatteryConnect() && isVbusIn(); }
|
||||
|
||||
private:
|
||||
/// If we see a battery voltage higher than physics allows - assume charger is pumping
|
||||
@@ -219,7 +220,7 @@ bool Power::analogInit()
|
||||
|
||||
bool Power::setup()
|
||||
{
|
||||
bool found = axp192Init();
|
||||
bool found = axpChipInit();
|
||||
|
||||
if (!found) {
|
||||
found = analogInit();
|
||||
@@ -232,10 +233,14 @@ bool Power::setup()
|
||||
|
||||
void Power::shutdown()
|
||||
{
|
||||
#ifdef HAS_AXP192
|
||||
|
||||
|
||||
#ifdef HAS_PMU
|
||||
DEBUG_MSG("Shutting down\n");
|
||||
axp.setChgLEDMode(AXP20X_LED_OFF);
|
||||
axp.shutdown();
|
||||
if(PMU){
|
||||
PMU->setChargingLedMode(XPOWERS_CHG_LED_OFF);
|
||||
PMU->shutdown();
|
||||
}
|
||||
#elif defined(ARCH_NRF52)
|
||||
playBeep();
|
||||
ledOff(PIN_LED1);
|
||||
@@ -256,8 +261,8 @@ void Power::readPowerStatus()
|
||||
if (hasBattery) {
|
||||
batteryVoltageMv = batteryLevel->getBattVoltage();
|
||||
// If the AXP192 returns a valid battery percentage, use it
|
||||
if (batteryLevel->getBattPercentage() >= 0) {
|
||||
batteryChargePercent = batteryLevel->getBattPercentage();
|
||||
if (batteryLevel->getBatteryPercent() >= 0) {
|
||||
batteryChargePercent = batteryLevel->getBatteryPercent();
|
||||
} else {
|
||||
// If the AXP192 returns a percentage less than 0, the feature is either not supported or there is an error
|
||||
// In that case, we compute an estimate of the charge percent based on maximum and minimum voltages defined in
|
||||
@@ -270,8 +275,8 @@ void Power::readPowerStatus()
|
||||
|
||||
// Notify any status instances that are observing us
|
||||
const PowerStatus powerStatus2 =
|
||||
PowerStatus(hasBattery ? OptTrue : OptFalse, batteryLevel->isVBUSPlug() ? OptTrue : OptFalse,
|
||||
batteryLevel->isChargeing() ? OptTrue : OptFalse, batteryVoltageMv, batteryChargePercent);
|
||||
PowerStatus(hasBattery ? OptTrue : OptFalse, batteryLevel->isVbusIn() ? OptTrue : OptFalse,
|
||||
batteryLevel->isCharging() ? OptTrue : OptFalse, batteryVoltageMv, batteryChargePercent);
|
||||
DEBUG_MSG("Battery: usbPower=%d, isCharging=%d, batMv=%d, batPct=%d\n", powerStatus2.getHasUSB(),
|
||||
powerStatus2.getIsCharging(), powerStatus2.getBatteryVoltageMv(), powerStatus2.getBatteryChargePercent());
|
||||
newStatus.notifyObservers(&powerStatus2);
|
||||
@@ -304,41 +309,46 @@ int32_t Power::runOnce()
|
||||
{
|
||||
readPowerStatus();
|
||||
|
||||
#ifdef HAS_AXP192
|
||||
#ifdef HAS_PMU
|
||||
// WE no longer use the IRQ line to wake the CPU (due to false wakes from sleep), but we do poll
|
||||
// the IRQ status by reading the registers over I2C
|
||||
axp.readIRQ();
|
||||
if(PMU){
|
||||
|
||||
if (axp.isVbusRemoveIRQ()) {
|
||||
DEBUG_MSG("USB unplugged\n");
|
||||
powerFSM.trigger(EVENT_POWER_DISCONNECTED);
|
||||
}
|
||||
if (axp.isVbusPlugInIRQ()) {
|
||||
DEBUG_MSG("USB plugged In\n");
|
||||
powerFSM.trigger(EVENT_POWER_CONNECTED);
|
||||
}
|
||||
/*
|
||||
Other things we could check if we cared...
|
||||
PMU->getIrqStatus();
|
||||
|
||||
if (axp.isChargingIRQ()) {
|
||||
DEBUG_MSG("Battery start charging\n");
|
||||
if(PMU->isVbusRemoveIrq()){
|
||||
DEBUG_MSG("USB unplugged\n");
|
||||
powerFSM.trigger(EVENT_POWER_DISCONNECTED);
|
||||
}
|
||||
|
||||
if (PMU->isVbusInsertIrq()) {
|
||||
DEBUG_MSG("USB plugged In\n");
|
||||
powerFSM.trigger(EVENT_POWER_CONNECTED);
|
||||
}
|
||||
|
||||
/*
|
||||
Other things we could check if we cared...
|
||||
|
||||
if (PMU->isBatChagerStartIrq()) {
|
||||
DEBUG_MSG("Battery start charging\n");
|
||||
}
|
||||
if (PMU->isBatChagerDoneIrq()) {
|
||||
DEBUG_MSG("Battery fully charged\n");
|
||||
}
|
||||
if (PMU->isBatInsertIrq()) {
|
||||
DEBUG_MSG("Battery inserted\n");
|
||||
}
|
||||
if (PMU->isBatRemoveIrq()) {
|
||||
DEBUG_MSG("Battery removed\n");
|
||||
}
|
||||
if (PMU->isPekeyShortPressIrq()) {
|
||||
DEBUG_MSG("PEK short button press\n");
|
||||
}
|
||||
*/
|
||||
|
||||
PMU->clearIrqStatus();
|
||||
}
|
||||
if (axp.isChargingDoneIRQ()) {
|
||||
DEBUG_MSG("Battery fully charged\n");
|
||||
}
|
||||
if (axp.isBattPlugInIRQ()) {
|
||||
DEBUG_MSG("Battery inserted\n");
|
||||
}
|
||||
if (axp.isBattRemoveIRQ()) {
|
||||
DEBUG_MSG("Battery removed\n");
|
||||
}
|
||||
if (axp.isPEKShortPressIRQ()) {
|
||||
DEBUG_MSG("PEK short button press\n");
|
||||
}
|
||||
*/
|
||||
axp.clearIRQ();
|
||||
#endif
|
||||
|
||||
// Only read once every 20 seconds once the power status for the app has been initialized
|
||||
return (statusHandler && statusHandler->isInitialized()) ? (1000 * 20) : RUN_SAME;
|
||||
}
|
||||
@@ -351,128 +361,239 @@ int32_t Power::runOnce()
|
||||
share the same i2c bus, instead use ssd1306 sleep mode DCDC2 -> unused DCDC3 0.7-3.5V @ 700mA max -> ESP32 (keep this on!) LDO1
|
||||
30mA -> charges GPS backup battery // charges the tiny J13 battery by the GPS to power the GPS ram (for a couple of days), can
|
||||
not be turned off LDO2 200mA -> LORA LDO3 200mA -> GPS
|
||||
*
|
||||
*/
|
||||
bool Power::axp192Init()
|
||||
bool Power::axpChipInit()
|
||||
{
|
||||
#ifdef HAS_AXP192
|
||||
if (axp192_found) {
|
||||
if (!axp.begin(Wire, AXP192_SLAVE_ADDRESS)) {
|
||||
batteryLevel = &axp;
|
||||
|
||||
DEBUG_MSG("AXP192 Begin PASS\n");
|
||||
#ifdef HAS_PMU
|
||||
|
||||
// axp.setChgLEDMode(LED_BLINK_4HZ);
|
||||
DEBUG_MSG("DCDC1: %s\n", axp.isDCDC1Enable() ? "ENABLE" : "DISABLE");
|
||||
DEBUG_MSG("DCDC2: %s\n", axp.isDCDC2Enable() ? "ENABLE" : "DISABLE");
|
||||
DEBUG_MSG("LDO2: %s\n", axp.isLDO2Enable() ? "ENABLE" : "DISABLE");
|
||||
DEBUG_MSG("LDO3: %s\n", axp.isLDO3Enable() ? "ENABLE" : "DISABLE");
|
||||
DEBUG_MSG("DCDC3: %s\n", axp.isDCDC3Enable() ? "ENABLE" : "DISABLE");
|
||||
DEBUG_MSG("Exten: %s\n", axp.isExtenEnable() ? "ENABLE" : "DISABLE");
|
||||
DEBUG_MSG("----------------------------------------\n");
|
||||
TwoWire * w = NULL;
|
||||
|
||||
axp.setPowerOutPut(AXP192_LDO2, AXP202_ON); // LORA radio
|
||||
// axp.setPowerOutPut(AXP192_LDO3, AXP202_ON); // GPS main power - now turned on in setGpsPower
|
||||
axp.setPowerOutPut(AXP192_DCDC2, AXP202_ON);
|
||||
axp.setPowerOutPut(AXP192_EXTEN, AXP202_ON);
|
||||
axp.setPowerOutPut(AXP192_DCDC1, AXP202_ON);
|
||||
axp.setDCDC1Voltage(3300); // for the OLED power
|
||||
|
||||
DEBUG_MSG("DCDC1: %s\n", axp.isDCDC1Enable() ? "ENABLE" : "DISABLE");
|
||||
DEBUG_MSG("DCDC2: %s\n", axp.isDCDC2Enable() ? "ENABLE" : "DISABLE");
|
||||
DEBUG_MSG("LDO2: %s\n", axp.isLDO2Enable() ? "ENABLE" : "DISABLE");
|
||||
DEBUG_MSG("LDO3: %s\n", axp.isLDO3Enable() ? "ENABLE" : "DISABLE");
|
||||
DEBUG_MSG("DCDC3: %s\n", axp.isDCDC3Enable() ? "ENABLE" : "DISABLE");
|
||||
DEBUG_MSG("Exten: %s\n", axp.isExtenEnable() ? "ENABLE" : "DISABLE");
|
||||
|
||||
switch (config.power.charge_current) {
|
||||
case Config_PowerConfig_ChargeCurrent_MAUnset:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_450MA);
|
||||
break;
|
||||
case Config_PowerConfig_ChargeCurrent_MA100:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_100MA);
|
||||
break;
|
||||
case Config_PowerConfig_ChargeCurrent_MA190:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_190MA);
|
||||
break;
|
||||
case Config_PowerConfig_ChargeCurrent_MA280:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_280MA);
|
||||
break;
|
||||
case Config_PowerConfig_ChargeCurrent_MA360:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_360MA);
|
||||
break;
|
||||
case Config_PowerConfig_ChargeCurrent_MA450:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_450MA);
|
||||
break;
|
||||
case Config_PowerConfig_ChargeCurrent_MA550:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_550MA);
|
||||
break;
|
||||
case Config_PowerConfig_ChargeCurrent_MA630:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_630MA);
|
||||
break;
|
||||
case Config_PowerConfig_ChargeCurrent_MA700:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_700MA);
|
||||
break;
|
||||
case Config_PowerConfig_ChargeCurrent_MA780:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_780MA);
|
||||
break;
|
||||
case Config_PowerConfig_ChargeCurrent_MA880:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_880MA);
|
||||
break;
|
||||
case Config_PowerConfig_ChargeCurrent_MA960:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_960MA);
|
||||
break;
|
||||
case Config_PowerConfig_ChargeCurrent_MA1000:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_1000MA);
|
||||
break;
|
||||
case Config_PowerConfig_ChargeCurrent_MA1080:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_1080MA);
|
||||
break;
|
||||
case Config_PowerConfig_ChargeCurrent_MA1160:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_1160MA);
|
||||
break;
|
||||
case Config_PowerConfig_ChargeCurrent_MA1240:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_1240MA);
|
||||
break;
|
||||
case Config_PowerConfig_ChargeCurrent_MA1320:
|
||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_1320MA);
|
||||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
// Not connected
|
||||
//val = 0xfc;
|
||||
//axp._writeByte(AXP202_VHTF_CHGSET, 1, &val); // Set temperature protection
|
||||
|
||||
//not used
|
||||
//val = 0x46;
|
||||
//axp._writeByte(AXP202_OFF_CTL, 1, &val); // enable bat detection
|
||||
// Use macro to distinguish which wire is used by PMU
|
||||
#ifdef PMU_USE_WIRE1
|
||||
w = &Wire1;
|
||||
#else
|
||||
w = &Wire;
|
||||
#endif
|
||||
axp.debugCharging();
|
||||
|
||||
#ifdef PMU_IRQ
|
||||
pinMode(PMU_IRQ, INPUT);
|
||||
attachInterrupt(
|
||||
PMU_IRQ, [] { pmu_irq = true; }, FALLING);
|
||||
|
||||
axp.adc1Enable(AXP202_BATT_CUR_ADC1, 1);
|
||||
// we do not look for AXP202_CHARGING_FINISHED_IRQ & AXP202_CHARGING_IRQ because it occurs repeatedly while there is
|
||||
// no battery also it could cause inadvertent waking from light sleep just because the battery filled
|
||||
// we don't look for AXP202_BATT_REMOVED_IRQ because it occurs repeatedly while no battery installed
|
||||
// we don't look at AXP202_VBUS_REMOVED_IRQ because we don't have anything hooked to vbus
|
||||
axp.enableIRQ(AXP202_BATT_CONNECT_IRQ | AXP202_VBUS_CONNECT_IRQ | AXP202_PEK_SHORTPRESS_IRQ, 1);
|
||||
|
||||
axp.clearIRQ();
|
||||
#endif
|
||||
readPowerStatus();
|
||||
/**
|
||||
* It is not necessary to specify the wire pin,
|
||||
* just input the wire, because the wire has been initialized in main.cpp
|
||||
*/
|
||||
if (!PMU) {
|
||||
PMU = new XPowersAXP2101(*w);
|
||||
if (!PMU->init()) {
|
||||
DEBUG_MSG("Warning: Failed to find AXP2101 power management\n");
|
||||
delete PMU;
|
||||
PMU = NULL;
|
||||
} else {
|
||||
DEBUG_MSG("AXP192 Begin FAIL\n");
|
||||
DEBUG_MSG("AXP2101 PMU init succeeded, using AXP2101 PMU\n");
|
||||
}
|
||||
} else {
|
||||
DEBUG_MSG("AXP192 not found\n");
|
||||
}
|
||||
|
||||
return axp192_found;
|
||||
if (!PMU) {
|
||||
PMU = new XPowersAXP192(*w);
|
||||
if (!PMU->init()) {
|
||||
DEBUG_MSG("Warning: Failed to find AXP192 power management\n");
|
||||
delete PMU;
|
||||
PMU = NULL;
|
||||
} else {
|
||||
DEBUG_MSG("AXP192 PMU init succeeded, using AXP192 PMU\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (!PMU) {
|
||||
/*
|
||||
* In XPowersLib, if the XPowersAXPxxx object is released, Wire.end() will be called at the same time.
|
||||
* In order not to affect other devices, if the initialization of the PMU fails, Wire needs to be re-initialized once,
|
||||
* if there are multiple devices sharing the bus.
|
||||
* * */
|
||||
#ifndef PMU_USE_WIRE1
|
||||
w->begin(I2C_SDA, I2C_SCL);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
batteryLevel = PMU;
|
||||
|
||||
if (PMU->getChipModel() == XPOWERS_AXP192) {
|
||||
|
||||
// lora radio power channel
|
||||
PMU->setPowerChannelVoltage(XPOWERS_LDO2, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_LDO2);
|
||||
|
||||
|
||||
// oled module power channel,
|
||||
// disable it will cause abnormal communication between boot and AXP power supply,
|
||||
// do not turn it off
|
||||
PMU->setPowerChannelVoltage(XPOWERS_DCDC1, 3300);
|
||||
// enable oled power
|
||||
PMU->enablePowerOutput(XPOWERS_DCDC1);
|
||||
|
||||
|
||||
// gnss module power channel - now turned on in setGpsPower
|
||||
PMU->setPowerChannelVoltage(XPOWERS_LDO3, 3300);
|
||||
// PMU->enablePowerOutput(XPOWERS_LDO3);
|
||||
|
||||
|
||||
//protected oled power source
|
||||
PMU->setProtectedChannel(XPOWERS_DCDC1);
|
||||
//protected esp32 power source
|
||||
PMU->setProtectedChannel(XPOWERS_DCDC3);
|
||||
|
||||
//disable not use channel
|
||||
PMU->disablePowerOutput(XPOWERS_DCDC2);
|
||||
|
||||
//disable all axp chip interrupt
|
||||
PMU->disableIRQ(XPOWERS_AXP192_ALL_IRQ);
|
||||
|
||||
// Set constant current charging current
|
||||
PMU->setChargerConstantCurr(XPOWERS_AXP192_CHG_CUR_450MA);
|
||||
|
||||
|
||||
} else if (PMU->getChipModel() == XPOWERS_AXP2101) {
|
||||
|
||||
// t-beam s3 core
|
||||
|
||||
/**
|
||||
* gnss module power channel
|
||||
* The default ALDO4 is off, you need to turn on the GNSS power first, otherwise it will be invalid during initialization
|
||||
*/
|
||||
PMU->setPowerChannelVoltage(XPOWERS_ALDO4, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_ALDO4);
|
||||
|
||||
// lora radio power channel
|
||||
PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_ALDO3);
|
||||
|
||||
// m.2 interface
|
||||
PMU->setPowerChannelVoltage(XPOWERS_DCDC3, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_DCDC3);
|
||||
|
||||
/**
|
||||
* ALDO2 cannot be turned off.
|
||||
* It is a necessary condition for sensor communication.
|
||||
* It must be turned on to properly access the sensor and screen
|
||||
* It is also responsible for the power supply of PCF8563
|
||||
*/
|
||||
PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_ALDO2);
|
||||
|
||||
// 6-axis , magnetometer ,bme280 , oled screen power channel
|
||||
PMU->setPowerChannelVoltage(XPOWERS_ALDO1, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_ALDO1);
|
||||
|
||||
// sdcard power channle
|
||||
PMU->setPowerChannelVoltage(XPOWERS_BLDO1, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_BLDO1);
|
||||
|
||||
// PMU->setPowerChannelVoltage(XPOWERS_DCDC4, 3300);
|
||||
// PMU->enablePowerOutput(XPOWERS_DCDC4);
|
||||
|
||||
//not use channel
|
||||
PMU->disablePowerOutput(XPOWERS_DCDC2); //not elicited
|
||||
PMU->disablePowerOutput(XPOWERS_DCDC5); //not elicited
|
||||
PMU->disablePowerOutput(XPOWERS_DLDO1); //Invalid power channel, it does not exist
|
||||
PMU->disablePowerOutput(XPOWERS_DLDO2); //Invalid power channel, it does not exist
|
||||
PMU->disablePowerOutput(XPOWERS_VBACKUP);
|
||||
|
||||
//disable all axp chip interrupt
|
||||
PMU->disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
|
||||
|
||||
//Set the constant current charging current of AXP2101, temporarily use 500mA by default
|
||||
PMU->setChargerConstantCurr(XPOWERS_AXP2101_CHG_CUR_500MA);
|
||||
|
||||
}
|
||||
|
||||
|
||||
PMU->clearIrqStatus();
|
||||
|
||||
// TBeam1.1 /T-Beam S3-Core has no external TS detection,
|
||||
// it needs to be disabled, otherwise it will cause abnormal charging
|
||||
PMU->disableTSPinMeasure();
|
||||
|
||||
// PMU->enableSystemVoltageMeasure();
|
||||
PMU->enableVbusVoltageMeasure();
|
||||
PMU->enableBattVoltageMeasure();
|
||||
|
||||
DEBUG_MSG("=======================================================================\n");
|
||||
if (PMU->isChannelAvailable(XPOWERS_DCDC1)) {
|
||||
DEBUG_MSG("DC1 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC1));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_DCDC2)) {
|
||||
DEBUG_MSG("DC2 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC2));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_DCDC3)) {
|
||||
DEBUG_MSG("DC3 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC3));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_DCDC4)) {
|
||||
DEBUG_MSG("DC4 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC4) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC4));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_LDO2)) {
|
||||
DEBUG_MSG("LDO2 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_LDO2));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_LDO3)) {
|
||||
DEBUG_MSG("LDO3 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_LDO3));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_ALDO1)) {
|
||||
DEBUG_MSG("ALDO1: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO1));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_ALDO2)) {
|
||||
DEBUG_MSG("ALDO2: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO2));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_ALDO3)) {
|
||||
DEBUG_MSG("ALDO3: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO3));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_ALDO4)) {
|
||||
DEBUG_MSG("ALDO4: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO4) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO4));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_BLDO1)) {
|
||||
DEBUG_MSG("BLDO1: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_BLDO1));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_BLDO2)) {
|
||||
DEBUG_MSG("BLDO2: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_BLDO2));
|
||||
}
|
||||
DEBUG_MSG("=======================================================================\n");
|
||||
|
||||
|
||||
//Set up the charging voltage, AXP2101/AXP192 4.2V gear is the same
|
||||
// XPOWERS_AXP192_CHG_VOL_4V2 = XPOWERS_AXP2101_CHG_VOL_4V2
|
||||
PMU->setChargeTargetVoltage(XPOWERS_AXP192_CHG_VOL_4V2);
|
||||
|
||||
// Set PMU shutdown voltage at 2.6V to maximize battery utilization
|
||||
PMU->setSysPowerDownVoltage(2600);
|
||||
|
||||
|
||||
|
||||
#ifdef PMU_IRQ
|
||||
uint64_t pmuIrqMask = 0;
|
||||
|
||||
if (PMU->getChipModel() == XPOWERS_AXP192) {
|
||||
pmuIrqMask = XPOWERS_AXP192_VBUS_INSERT_IRQ | XPOWERS_AXP192_BAT_INSERT_IRQ | XPOWERS_AXP192_PKEY_SHORT_IRQ;
|
||||
} else if (PMU->getChipModel() == XPOWERS_AXP2101) {
|
||||
pmuIrqMask = XPOWERS_AXP2101_VBUS_INSERT_IRQ | XPOWERS_AXP2101_BAT_INSERT_IRQ | XPOWERS_AXP2101_PKEY_SHORT_IRQ;
|
||||
}
|
||||
|
||||
pinMode(PMU_IRQ, INPUT);
|
||||
attachInterrupt(
|
||||
PMU_IRQ, [] { pmu_irq = true; }, FALLING);
|
||||
|
||||
// we do not look for AXPXXX_CHARGING_FINISHED_IRQ & AXPXXX_CHARGING_IRQ because it occurs repeatedly while there is
|
||||
// no battery also it could cause inadvertent waking from light sleep just because the battery filled
|
||||
// we don't look for AXPXXX_BATT_REMOVED_IRQ because it occurs repeatedly while no battery installed
|
||||
// we don't look at AXPXXX_VBUS_REMOVED_IRQ because we don't have anything hooked to vbus
|
||||
PMU->enableIRQ(pmuIrqMask);
|
||||
|
||||
PMU->clearIrqStatus();
|
||||
#endif /*PMU_IRQ*/
|
||||
|
||||
readPowerStatus();
|
||||
|
||||
pmu_found = true;
|
||||
|
||||
return pmu_found;
|
||||
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
|
||||
@@ -12,11 +12,11 @@
|
||||
static bool isPowered()
|
||||
{
|
||||
// Circumvent the battery sensing logic and assumes constant power if no battery pin or power mgmt IC
|
||||
#if !defined(BATTERY_PIN) && !defined(HAS_AXP192)
|
||||
#if !defined(BATTERY_PIN) && !defined(HAS_AXP192) && !defined(HAS_AXP2101)
|
||||
return true;
|
||||
#endif
|
||||
|
||||
bool isRouter = (config.device.role == Config_DeviceConfig_Role_Router ? 1 : 0);
|
||||
bool isRouter = (config.device.role == Config_DeviceConfig_Role_ROUTER ? 1 : 0);
|
||||
|
||||
// If we are not a router and we already have AC power go to POWER state after init, otherwise go to ON
|
||||
// We assume routers might be powered all the time, but from a low current (solar) source
|
||||
@@ -34,7 +34,7 @@ static void sdsEnter()
|
||||
{
|
||||
DEBUG_MSG("Enter state: SDS\n");
|
||||
// FIXME - make sure GPS and LORA radio are off first - because we want close to zero current draw
|
||||
doDeepSleep(config.power.sds_secs ? config.power.sds_secs : default_sds_secs * 1000LL);
|
||||
doDeepSleep(config.power.sds_secs * 1000);
|
||||
}
|
||||
|
||||
extern Power *power;
|
||||
@@ -51,7 +51,7 @@ static uint32_t secsSlept;
|
||||
|
||||
static void lsEnter()
|
||||
{
|
||||
DEBUG_MSG("lsEnter begin, ls_secs=%u\n", config.power.ls_secs > 0 ? config.power.ls_secs : default_ls_secs);
|
||||
DEBUG_MSG("lsEnter begin, ls_secs=%u\n", config.power.ls_secs);
|
||||
screen->setOn(false);
|
||||
secsSlept = 0; // How long have we been sleeping this time
|
||||
|
||||
@@ -65,7 +65,7 @@ static void lsIdle()
|
||||
#ifdef ARCH_ESP32
|
||||
|
||||
// Do we have more sleeping to do?
|
||||
if (secsSlept < config.power.ls_secs ? config.power.ls_secs : default_ls_secs) {
|
||||
if (secsSlept < config.power.ls_secs) {
|
||||
// Briefly come out of sleep long enough to blink the led once every few seconds
|
||||
uint32_t sleepTime = 30;
|
||||
|
||||
@@ -237,10 +237,10 @@ Fsm powerFSM(&stateBOOT);
|
||||
|
||||
void PowerFSM_setup()
|
||||
{
|
||||
bool isRouter = (config.device.role == Config_DeviceConfig_Role_Router ? 1 : 0);
|
||||
bool isRouter = (config.device.role == Config_DeviceConfig_Role_ROUTER ? 1 : 0);
|
||||
bool hasPower = isPowered();
|
||||
|
||||
DEBUG_MSG("PowerFSM init, USB power=%d\n", hasPower);
|
||||
DEBUG_MSG("PowerFSM init, USB power=%d\n", hasPower ? 1 : 0);
|
||||
powerFSM.add_timed_transition(&stateBOOT, hasPower ? &statePOWER : &stateON, 3 * 1000, NULL, "boot timeout");
|
||||
|
||||
// wake timer expired or a packet arrived
|
||||
@@ -334,8 +334,6 @@ void PowerFSM_setup()
|
||||
// On most boards we use light-sleep to be our main state, but on NRF52 we just stay in DARK
|
||||
State *lowPowerState = &stateLS;
|
||||
|
||||
uint32_t meshSds = 0;
|
||||
|
||||
#ifdef ARCH_ESP32
|
||||
// We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally)
|
||||
|
||||
@@ -343,20 +341,14 @@ void PowerFSM_setup()
|
||||
if (isRouter || config.power.is_power_saving) {
|
||||
powerFSM.add_timed_transition(&stateNB, &stateLS, getConfiguredOrDefaultMs(config.power.min_wake_secs, default_min_wake_secs), NULL, "Min wake timeout");
|
||||
powerFSM.add_timed_transition(&stateDARK, &stateLS, getConfiguredOrDefaultMs(config.power.wait_bluetooth_secs, default_wait_bluetooth_secs), NULL, "Bluetooth timeout");
|
||||
meshSds = config.power.mesh_sds_timeout_secs ? config.power.mesh_sds_timeout_secs : default_mesh_sds_timeout_secs;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
meshSds = UINT32_MAX;
|
||||
}
|
||||
|
||||
#else
|
||||
#elif defined (ARCH_NRF52)
|
||||
lowPowerState = &stateDARK;
|
||||
meshSds = UINT32_MAX; // Workaround for now: Don't go into deep sleep on the RAK4631
|
||||
#endif
|
||||
|
||||
if (meshSds != UINT32_MAX)
|
||||
powerFSM.add_timed_transition(lowPowerState, &stateSDS, meshSds * 1000, NULL, "mesh timeout");
|
||||
if (config.power.sds_secs != UINT32_MAX)
|
||||
powerFSM.add_timed_transition(lowPowerState, &stateSDS, config.power.sds_secs * 1000, NULL, "mesh timeout");
|
||||
|
||||
powerFSM.run_machine(); // run one interation of the state machine, so we run our on enter tasks for the initial DARK state
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "configuration.h"
|
||||
#include "RedirectablePrint.h"
|
||||
#include "RTC.h"
|
||||
#include "NodeDB.h"
|
||||
#include "concurrency/OSThread.h"
|
||||
// #include "wifi/WiFiServerAPI.h"
|
||||
#include <assert.h>
|
||||
@@ -30,7 +31,9 @@ size_t RedirectablePrint::write(uint8_t c)
|
||||
// optionally send chars to TCP also
|
||||
//WiFiServerPort::debugOut(c);
|
||||
|
||||
dest->write(c);
|
||||
if (!config.has_lora || config.device.serial_enabled)
|
||||
dest->write(c);
|
||||
|
||||
return 1; // We always claim one was written, rather than trusting what the
|
||||
// serial port said (which could be zero)
|
||||
}
|
||||
|
||||
@@ -20,6 +20,9 @@ void consolePrintf(const char *format, ...)
|
||||
va_start(arg, format);
|
||||
console->vprintf(format, arg);
|
||||
va_end(arg);
|
||||
#ifdef ARCH_ESP32
|
||||
console->flush();
|
||||
#endif
|
||||
}
|
||||
|
||||
SerialConsole::SerialConsole() : StreamAPI(&Port), RedirectablePrint(&Port)
|
||||
@@ -57,10 +60,15 @@ bool SerialConsole::checkIsConnected()
|
||||
*/
|
||||
bool SerialConsole::handleToRadio(const uint8_t *buf, size_t len)
|
||||
{
|
||||
// Turn off debug serial printing once the API is activated, because other threads could print and corrupt packets
|
||||
if (!config.device.debug_log_enabled)
|
||||
setDestination(&noopPrint);
|
||||
canWrite = true;
|
||||
// only talk to the API once the configuration has been loaded and we're sure the serial port is not disabled.
|
||||
if (config.has_lora && config.device.serial_enabled) {
|
||||
// Turn off debug serial printing once the API is activated, because other threads could print and corrupt packets
|
||||
if (!config.device.debug_log_enabled)
|
||||
setDestination(&noopPrint);
|
||||
canWrite = true;
|
||||
|
||||
return StreamAPI::handleToRadio(buf, len);
|
||||
}
|
||||
return StreamAPI::handleToRadio(buf, len);
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,7 @@ struct ToneDuration {
|
||||
#define NOTE_A3 220
|
||||
#define NOTE_AS3 233
|
||||
#define NOTE_B3 247
|
||||
#define NOTE_CS4 277
|
||||
|
||||
const int DURATION_1_8 = 125; // 1/8 note
|
||||
const int DURATION_1_4 = 250; // 1/4 note
|
||||
@@ -65,16 +66,17 @@ void playBeep() { tone(PIN_BUZZER, NOTE_B3, DURATION_1_4); }
|
||||
#endif
|
||||
|
||||
void playStartMelody() {
|
||||
ToneDuration melody[] = {{NOTE_B3, DURATION_1_4},
|
||||
{NOTE_B3, DURATION_1_8},
|
||||
{NOTE_B3, DURATION_1_8}};
|
||||
ToneDuration melody[] = {{NOTE_FS3, DURATION_1_8},
|
||||
{NOTE_AS3, DURATION_1_8},
|
||||
{NOTE_CS4, DURATION_1_4}};
|
||||
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
|
||||
}
|
||||
|
||||
|
||||
void playShutdownMelody() {
|
||||
ToneDuration melody[] = {{NOTE_B3, DURATION_1_4},
|
||||
{NOTE_G3, DURATION_1_8},
|
||||
{NOTE_D3, DURATION_1_8}};
|
||||
ToneDuration melody[] = {{NOTE_CS4, DURATION_1_8},
|
||||
{NOTE_AS3, DURATION_1_8},
|
||||
{NOTE_FS3, DURATION_1_4}};
|
||||
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
|
||||
}
|
||||
#endif
|
||||
@@ -94,19 +94,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
// Define this if you know you have that controller or your "SSD1306" misbehaves.
|
||||
//#define USE_SH1106
|
||||
|
||||
// Flip the screen upside down by default as it makes more sense on T-BEAM
|
||||
// devices. Comment this out to not rotate screen 180 degrees.
|
||||
#define SCREEN_FLIP_VERTICALLY
|
||||
|
||||
// Define if screen should be mirrored left to right
|
||||
// #define SCREEN_MIRROR
|
||||
|
||||
// The m5stack I2C Keyboard (also RAK14004)
|
||||
#define CARDKB_ADDR 0x5F
|
||||
|
||||
// The older M5 Faces I2C Keyboard
|
||||
#define FACESKB_ADDR 0x88
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// SENSOR
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -115,6 +108,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define MCP9808_ADDR 0x18
|
||||
#define INA_ADDR 0x40
|
||||
#define INA_ADDR_ALTERNATE 0x41
|
||||
#define QMC6310_ADDR 0x1C
|
||||
#define QMI8658_ADDR 0x6B
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Security
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#define ATECC608B_ADDR 0x35
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// GPS
|
||||
|
||||
@@ -3,11 +3,47 @@
|
||||
#include <Wire.h>
|
||||
#include "mesh/generated/telemetry.pb.h"
|
||||
|
||||
#ifdef HAS_AXP192
|
||||
#include "axp20x.h"
|
||||
// AXP192 and AXP2101 have the same device address, we just need to identify it in Power.cpp
|
||||
#ifndef XPOWERS_AXP192_AXP2101_ADDRESS
|
||||
#define XPOWERS_AXP192_AXP2101_ADDRESS 0x34
|
||||
#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);
|
||||
@@ -78,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;
|
||||
@@ -106,18 +153,14 @@ void scanI2Cdevice(void)
|
||||
kb_model = 0x00;
|
||||
}
|
||||
}
|
||||
if (addr == FACESKB_ADDR) {
|
||||
faceskb_found = addr;
|
||||
DEBUG_MSG("m5 Faces found\n");
|
||||
}
|
||||
if (addr == ST7567_ADDRESS) {
|
||||
screen_found = addr;
|
||||
DEBUG_MSG("st7567 display found\n");
|
||||
}
|
||||
#ifdef HAS_AXP192
|
||||
if (addr == AXP192_SLAVE_ADDRESS) {
|
||||
axp192_found = true;
|
||||
DEBUG_MSG("axp192 PMU found\n");
|
||||
#ifdef HAS_PMU
|
||||
if (addr == XPOWERS_AXP192_AXP2101_ADDRESS) {
|
||||
pmu_found = true;
|
||||
DEBUG_MSG("axp192/axp2101 PMU found\n");
|
||||
}
|
||||
#endif
|
||||
if (addr == BME_ADDR || addr == BME_ADDR_ALTERNATE) {
|
||||
@@ -148,6 +191,14 @@ void scanI2Cdevice(void)
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_MCP9808] = addr;
|
||||
DEBUG_MSG("MCP9808 sensor found at address 0x%x\n", (uint8_t)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){
|
||||
DEBUG_MSG("QMI8658 6-Axis inertial measurement sensor found at address 0x%x\n", (uint8_t)addr);
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_QMI8658] = addr;
|
||||
}
|
||||
} else if (err == 4) {
|
||||
DEBUG_MSG("Unknow error at address 0x%x\n", addr);
|
||||
}
|
||||
|
||||
@@ -8,4 +8,4 @@
|
||||
#define RECORD_CRITICALERROR(code) recordCriticalError(code, __LINE__, __FILE__)
|
||||
|
||||
/// Record an error that should be reported via analytics
|
||||
void recordCriticalError(CriticalErrorCode code = CriticalErrorCode_Unspecified, uint32_t address = 0, const char *filename = NULL);
|
||||
void recordCriticalError(CriticalErrorCode code = CriticalErrorCode_UNSPECIFIED, uint32_t address = 0, const char *filename = NULL);
|
||||
|
||||
401
src/gps/GPS.cpp
401
src/gps/GPS.cpp
@@ -59,98 +59,192 @@ bool GPS::getACK(uint8_t c, uint8_t i) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @note New method, this method can wait for the specified class and message ID, and return the payload
|
||||
* @param *buffer: The message buffer, if there is a response payload message, it will be returned through the buffer parameter
|
||||
* @param size: size of buffer
|
||||
* @param requestedClass: request class constant
|
||||
* @param requestedID: request message ID constant
|
||||
* @retval length of payload message
|
||||
*/
|
||||
int GPS::getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID)
|
||||
{
|
||||
uint16_t ubxFrameCounter = 0;
|
||||
uint32_t startTime = millis();
|
||||
uint16_t needRead;
|
||||
|
||||
while (millis() - startTime < 800) {
|
||||
while (_serial_gps->available()) {
|
||||
int c = _serial_gps->read();
|
||||
switch (ubxFrameCounter) {
|
||||
case 0:
|
||||
//ubxFrame 'μ'
|
||||
if (c == 0xB5) {
|
||||
ubxFrameCounter++;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
//ubxFrame 'b'
|
||||
if (c == 0x62) {
|
||||
ubxFrameCounter++;
|
||||
} else {
|
||||
ubxFrameCounter = 0;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
//Class
|
||||
if (c == requestedClass) {
|
||||
ubxFrameCounter++;
|
||||
} else {
|
||||
ubxFrameCounter = 0;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
//Message ID
|
||||
if (c == requestedID) {
|
||||
ubxFrameCounter++;
|
||||
} else {
|
||||
ubxFrameCounter = 0;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
//Payload lenght lsb
|
||||
needRead = c;
|
||||
ubxFrameCounter++;
|
||||
break;
|
||||
case 5:
|
||||
//Payload lenght msb
|
||||
needRead |= (c << 8);
|
||||
ubxFrameCounter++;
|
||||
break;
|
||||
case 6:
|
||||
// Check for buffer overflow
|
||||
if (needRead >= size) {
|
||||
ubxFrameCounter = 0;
|
||||
break;
|
||||
}
|
||||
if (_serial_gps->readBytes(buffer, needRead) != needRead) {
|
||||
ubxFrameCounter = 0;
|
||||
} else {
|
||||
// return payload lenght
|
||||
return needRead;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool GPS::setupGPS()
|
||||
{
|
||||
if (_serial_gps && !didSerialInit) {
|
||||
didSerialInit = true;
|
||||
|
||||
#ifdef ARCH_ESP32
|
||||
// In esp32 framework, setRxBufferSize needs to be initialized before Serial
|
||||
_serial_gps->setRxBufferSize(2048); // the default is 256
|
||||
#endif
|
||||
|
||||
// ESP32 has a special set of parameters vs other arduino ports
|
||||
#if defined(GPS_RX_PIN) && defined(ARCH_ESP32)
|
||||
_serial_gps->begin(GPS_BAUDRATE, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN);
|
||||
#else
|
||||
_serial_gps->begin(GPS_BAUDRATE);
|
||||
#endif
|
||||
#ifdef ARCH_ESP32
|
||||
_serial_gps->setRxBufferSize(2048); // the default is 256
|
||||
#endif
|
||||
#ifdef TTGO_T_ECHO
|
||||
// Switch to 9600 baud, then close and reopen port
|
||||
_serial_gps->end();
|
||||
delay(250);
|
||||
_serial_gps->begin(4800);
|
||||
delay(250);
|
||||
_serial_gps->write("$PCAS01,1*1D\r\n");
|
||||
delay(250);
|
||||
_serial_gps->end();
|
||||
delay(250);
|
||||
_serial_gps->begin(9600);
|
||||
delay(250);
|
||||
// Initialize the L76K Chip, use GPS + GLONASS
|
||||
_serial_gps->write("$PCAS04,5*1C\r\n");
|
||||
delay(250);
|
||||
// only ask for RMC and GGA
|
||||
_serial_gps->write("$PCAS03,1,0,0,0,1,0,0,0,0,0,,,0,0*02\r\n");
|
||||
delay(250);
|
||||
// Switch to Vehicle Mode, since SoftRF enables Aviation < 2g
|
||||
_serial_gps->write("$PCAS11,3*1E\r\n");
|
||||
delay(250);
|
||||
#endif
|
||||
#ifdef GPS_UBLOX
|
||||
delay(250);
|
||||
// Set the UART port to output NMEA only
|
||||
byte _message_nmea[] = {0xB5, 0x62, 0x06, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0xC0, 0x08, 0x00, 0x00,
|
||||
0x80, 0x25, 0x00, 0x00, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0xAF};
|
||||
_serial_gps->write(_message_nmea, sizeof(_message_nmea));
|
||||
if (!getACK(0x06, 0x00)) {
|
||||
DEBUG_MSG("WARNING: Unable to enable NMEA Mode.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
// disable GGL
|
||||
byte _message_GGL[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x05, 0x3A};
|
||||
_serial_gps->write(_message_GGL, sizeof(_message_GGL));
|
||||
if (!getACK(0x06, 0x01)) {
|
||||
DEBUG_MSG("WARNING: Unable to disable NMEA GGL.\n");
|
||||
return true;
|
||||
/*
|
||||
* T-Beam-S3-Core will be preset to use gps Probe here, and other boards will not be changed first
|
||||
*/
|
||||
gnssModel = probe();
|
||||
|
||||
if(gnssModel == GNSS_MODEL_MTK){
|
||||
/*
|
||||
* t-beam-s3-core uses the same L76K GNSS module as t-echo.
|
||||
* Unlike t-echo, L76K uses 9600 baud rate for communication by default.
|
||||
* */
|
||||
// _serial_gps->begin(9600); //The baud rate of 9600 has been initialized at the beginning of setupGPS, this line is the redundant part
|
||||
// delay(250);
|
||||
|
||||
// Initialize the L76K Chip, use GPS + GLONASS
|
||||
_serial_gps->write("$PCAS04,5*1C\r\n");
|
||||
delay(250);
|
||||
// only ask for RMC and GGA
|
||||
_serial_gps->write("$PCAS03,1,0,0,0,1,0,0,0,0,0,,,0,0*02\r\n");
|
||||
delay(250);
|
||||
// Switch to Vehicle Mode, since SoftRF enables Aviation < 2g
|
||||
_serial_gps->write("$PCAS11,3*1E\r\n");
|
||||
delay(250);
|
||||
|
||||
}else if(gnssModel == GNSS_MODEL_UBLOX){
|
||||
|
||||
/*
|
||||
tips: NMEA Only should not be set here, otherwise initializing Ublox gnss module again after
|
||||
setting will not output command messages in UART1, resulting in unrecognized module information
|
||||
|
||||
// Set the UART port to output NMEA only
|
||||
byte _message_nmea[] = {0xB5, 0x62, 0x06, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0xC0, 0x08, 0x00, 0x00,
|
||||
0x80, 0x25, 0x00, 0x00, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0xAF};
|
||||
_serial_gps->write(_message_nmea, sizeof(_message_nmea));
|
||||
if (!getACK(0x06, 0x00)) {
|
||||
DEBUG_MSG("WARNING: Unable to enable NMEA Mode.\n");
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
// ublox-M10S can be compatible with UBLOX traditional protocol, so the following sentence settings are also valid
|
||||
|
||||
// disable GGL
|
||||
byte _message_GGL[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x05, 0x3A};
|
||||
_serial_gps->write(_message_GGL, sizeof(_message_GGL));
|
||||
if (!getACK(0x06, 0x01)) {
|
||||
DEBUG_MSG("WARNING: Unable to disable NMEA GGL.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
// disable GSA
|
||||
byte _message_GSA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x06, 0x41};
|
||||
_serial_gps->write(_message_GSA, sizeof(_message_GSA));
|
||||
if (!getACK(0x06, 0x01)) {
|
||||
DEBUG_MSG("WARNING: Unable to disable NMEA GSA.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
// disable GSV
|
||||
byte _message_GSV[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x03, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x07, 0x48};
|
||||
_serial_gps->write(_message_GSV, sizeof(_message_GSV));
|
||||
if (!getACK(0x06, 0x01)) {
|
||||
DEBUG_MSG("WARNING: Unable to disable NMEA GSV.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
// disable VTG
|
||||
byte _message_VTG[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x05, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x09, 0x56};
|
||||
_serial_gps->write(_message_VTG, sizeof(_message_VTG));
|
||||
if (!getACK(0x06, 0x01)) {
|
||||
DEBUG_MSG("WARNING: Unable to disable NMEA VTG.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
// enable RMC
|
||||
byte _message_RMC[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x09, 0x54};
|
||||
_serial_gps->write(_message_RMC, sizeof(_message_RMC));
|
||||
if (!getACK(0x06, 0x01)) {
|
||||
DEBUG_MSG("WARNING: Unable to enable NMEA RMC.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
// enable GGA
|
||||
byte _message_GGA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x05, 0x38};
|
||||
_serial_gps->write(_message_GGA, sizeof(_message_GGA));
|
||||
if (!getACK(0x06, 0x01)) {
|
||||
DEBUG_MSG("WARNING: Unable to enable NMEA GGA.\n");
|
||||
}
|
||||
}
|
||||
|
||||
// disable GSA
|
||||
byte _message_GSA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x06, 0x41};
|
||||
_serial_gps->write(_message_GSA, sizeof(_message_GSA));
|
||||
if (!getACK(0x06, 0x01)) {
|
||||
DEBUG_MSG("WARNING: Unable to disable NMEA GSA.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
// disable GSV
|
||||
byte _message_GSV[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x03, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x07, 0x48};
|
||||
_serial_gps->write(_message_GSV, sizeof(_message_GSV));
|
||||
if (!getACK(0x06, 0x01)) {
|
||||
DEBUG_MSG("WARNING: Unable to disable NMEA GSV.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
// disable VTG
|
||||
byte _message_VTG[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x05, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x09, 0x56};
|
||||
_serial_gps->write(_message_VTG, sizeof(_message_VTG));
|
||||
if (!getACK(0x06, 0x01)) {
|
||||
DEBUG_MSG("WARNING: Unable to disable NMEA VTG.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
// enable RMC
|
||||
byte _message_RMC[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x09, 0x54};
|
||||
_serial_gps->write(_message_RMC, sizeof(_message_RMC));
|
||||
if (!getACK(0x06, 0x01)) {
|
||||
DEBUG_MSG("WARNING: Unable to enable NMEA RMC.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
// enable GGA
|
||||
byte _message_GGA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x05, 0x38};
|
||||
_serial_gps->write(_message_GGA, sizeof(_message_GGA));
|
||||
if (!getACK(0x06, 0x01)) DEBUG_MSG("WARNING: Unable to enable NMEA GGA.\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -271,16 +365,7 @@ uint32_t GPS::getWakeTime() const
|
||||
|
||||
if (t == UINT32_MAX)
|
||||
return t; // already maxint
|
||||
|
||||
if (t == 0)
|
||||
t = (config.device.role == Config_DeviceConfig_Role_Router)
|
||||
? 5 * 60
|
||||
: 15 * 60; // Allow up to 15 mins for each attempt (probably will be much
|
||||
// less if we can find sats) or less if a router
|
||||
|
||||
t *= 1000; // msecs
|
||||
|
||||
return t;
|
||||
return t * 1000;
|
||||
}
|
||||
|
||||
/** Get how long we should sleep between aqusition attempts in msecs
|
||||
@@ -288,21 +373,15 @@ uint32_t GPS::getWakeTime() const
|
||||
uint32_t GPS::getSleepTime() const
|
||||
{
|
||||
uint32_t t = config.position.gps_update_interval;
|
||||
bool gps_disabled = config.position.gps_disabled;
|
||||
bool gps_enabled = config.position.gps_enabled;
|
||||
|
||||
if (gps_disabled)
|
||||
if (!gps_enabled)
|
||||
t = UINT32_MAX; // Sleep forever now
|
||||
|
||||
if (t == UINT32_MAX)
|
||||
return t; // already maxint
|
||||
|
||||
if (t == 0) // default - unset in preferences
|
||||
t = (config.device.role == Config_DeviceConfig_Role_Router) ? 24 * 60 * 60
|
||||
: 2 * 60; // 2 mins or once per day for routers
|
||||
|
||||
t *= 1000;
|
||||
|
||||
return t;
|
||||
|
||||
return t * 1000;
|
||||
}
|
||||
|
||||
void GPS::publishUpdate()
|
||||
@@ -311,7 +390,7 @@ void GPS::publishUpdate()
|
||||
shouldPublish = false;
|
||||
|
||||
// In debug logs, identify position by @timestamp:stage (stage 2 = publish)
|
||||
DEBUG_MSG("publishing pos@%x:2, hasVal=%d, GPSlock=%d\n", p.pos_timestamp, hasValidLocation, hasLock());
|
||||
DEBUG_MSG("publishing pos@%x:2, hasVal=%d, GPSlock=%d\n", p.timestamp, hasValidLocation, hasLock());
|
||||
|
||||
// Notify any status instances that are observing us
|
||||
const meshtastic::GPSStatus status = meshtastic::GPSStatus(hasValidLocation, isConnected(), p);
|
||||
@@ -325,14 +404,14 @@ int32_t GPS::runOnce()
|
||||
// if we have received valid NMEA claim we are connected
|
||||
setConnected();
|
||||
} else {
|
||||
#ifdef GPS_UBLOX
|
||||
// reset the GPS on next bootup
|
||||
if(devicestate.did_gps_reset && (millis() > 60000) && !hasFlow()) {
|
||||
DEBUG_MSG("GPS is not communicating, trying factory reset on next bootup.\n");
|
||||
devicestate.did_gps_reset = false;
|
||||
nodeDB.saveDeviceStateToDisk();
|
||||
if(gnssModel == GNSS_MODEL_UBLOX){
|
||||
// reset the GPS on next bootup
|
||||
if(devicestate.did_gps_reset && (millis() > 60000) && !hasFlow()) {
|
||||
DEBUG_MSG("GPS is not communicating, trying factory reset on next bootup.\n");
|
||||
devicestate.did_gps_reset = false;
|
||||
nodeDB.saveDeviceStateToDisk();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// If we are overdue for an update, turn on the GPS and at least publish the current status
|
||||
@@ -432,6 +511,112 @@ int GPS::prepareDeepSleep(void *unused)
|
||||
return 0;
|
||||
}
|
||||
|
||||
GnssModel_t GPS::probe()
|
||||
{
|
||||
// return immediately if the model is set by the variant.h file
|
||||
#ifdef GPS_UBLOX
|
||||
return GNSS_MODEL_UBLOX;
|
||||
#elif defined(GPS_L76K)
|
||||
return GNSS_MODEL_MTK;
|
||||
#else
|
||||
// we use autodetect, only T-BEAM S3 for now...
|
||||
uint8_t buffer[256];
|
||||
/*
|
||||
* The GNSS module information variable is temporarily placed inside the function body,
|
||||
* if it needs to be used elsewhere, it can be moved to the outside
|
||||
* */
|
||||
struct uBloxGnssModelInfo info ;
|
||||
|
||||
memset(&info, 0, sizeof(struct uBloxGnssModelInfo));
|
||||
|
||||
// Close all NMEA sentences , Only valid for MTK platform
|
||||
_serial_gps->write("$PCAS03,0,0,0,0,0,0,0,0,0,0,,,0,0*02\r\n");
|
||||
delay(20);
|
||||
|
||||
// Get version information
|
||||
_serial_gps->write("$PCAS06,0*1B\r\n");
|
||||
uint32_t startTimeout = millis() + 500;
|
||||
while (millis() < startTimeout) {
|
||||
if (_serial_gps->available()) {
|
||||
String ver = _serial_gps->readStringUntil('\r');
|
||||
// Get module info , If the correct header is returned,
|
||||
// it can be determined that it is the MTK chip
|
||||
int index = ver.indexOf("$");
|
||||
if(index != -1){
|
||||
ver = ver.substring(index);
|
||||
if (ver.startsWith("$GPTXT,01,01,02")) {
|
||||
DEBUG_MSG("L76K GNSS init succeeded, using L76K GNSS Module\n");
|
||||
return GNSS_MODEL_MTK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x0E, 0x30};
|
||||
_serial_gps->write(cfg_rate, sizeof(cfg_rate));
|
||||
// Check that the returned response class and message ID are correct
|
||||
if (!getAck(buffer, 256, 0x06, 0x08)) {
|
||||
DEBUG_MSG("Warning: Failed to find UBlox & MTK GNSS Module\n");
|
||||
return GNSS_MODEL_UNKONW;
|
||||
}
|
||||
|
||||
// Get Ublox gnss module hardware and software info
|
||||
uint8_t cfg_get_hw[] = {0xB5, 0x62, 0x0A, 0x04, 0x00, 0x00, 0x0E, 0x34};
|
||||
_serial_gps->write(cfg_get_hw, sizeof(cfg_get_hw));
|
||||
|
||||
uint16_t len = getAck(buffer, 256, 0x0A, 0x04);
|
||||
if (len) {
|
||||
|
||||
uint16_t position = 0;
|
||||
for (int i = 0; i < 30; i++) {
|
||||
info.swVersion[i] = buffer[position];
|
||||
position++;
|
||||
}
|
||||
for (int i = 0; i < 10; i++) {
|
||||
info.hwVersion[i] = buffer[position];
|
||||
position++;
|
||||
}
|
||||
|
||||
while (len >= position + 30) {
|
||||
for (int i = 0; i < 30; i++) {
|
||||
info.extension[info.extensionNo][i] = buffer[position];
|
||||
position++;
|
||||
}
|
||||
info.extensionNo++;
|
||||
if (info.extensionNo > 9)
|
||||
break;
|
||||
}
|
||||
|
||||
DEBUG_MSG("Module Info : \n");
|
||||
DEBUG_MSG("Soft version: %s\n",info.swVersion);
|
||||
DEBUG_MSG("Hard version: %s\n",info.hwVersion);
|
||||
DEBUG_MSG("Extensions:%d\n",info.extensionNo);
|
||||
for (int i = 0; i < info.extensionNo; i++) {
|
||||
DEBUG_MSG(" %s\n",info.extension[i]);
|
||||
}
|
||||
|
||||
memset(buffer,0,sizeof(buffer));
|
||||
|
||||
//tips: extensionNo field is 0 on some 6M GNSS modules
|
||||
for (int i = 0; i < info.extensionNo; ++i) {
|
||||
if (!strncmp(info.extension[i], "OD=", 3)) {
|
||||
strcpy((char *)buffer, &(info.extension[i][3]));
|
||||
DEBUG_MSG("GetModel:%s\n",(char *)buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (strlen((char*)buffer)) {
|
||||
DEBUG_MSG("UBlox GNSS init succeeded, using UBlox %s GNSS Module\n" , buffer);
|
||||
}else{
|
||||
DEBUG_MSG("UBlox GNSS init succeeded, using UBlox GNSS Module\n");
|
||||
}
|
||||
|
||||
return GNSS_MODEL_UBLOX;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if HAS_GPS
|
||||
#include "NMEAGPS.h"
|
||||
#endif
|
||||
@@ -442,7 +627,7 @@ GPS *createGps()
|
||||
#if !HAS_GPS
|
||||
return nullptr;
|
||||
#else
|
||||
if (!config.position.gps_disabled) {
|
||||
if (config.position.gps_enabled) {
|
||||
#ifdef GPS_ALTITUDE_HAE
|
||||
DEBUG_MSG("Using HAE altitude model\n");
|
||||
#else
|
||||
|
||||
@@ -4,6 +4,20 @@
|
||||
#include "Observer.h"
|
||||
#include "concurrency/OSThread.h"
|
||||
|
||||
|
||||
struct uBloxGnssModelInfo {
|
||||
char swVersion[30];
|
||||
char hwVersion[10];
|
||||
uint8_t extensionNo;
|
||||
char extension[10][30];
|
||||
} ;
|
||||
|
||||
typedef enum{
|
||||
GNSS_MODEL_MTK,
|
||||
GNSS_MODEL_UBLOX,
|
||||
GNSS_MODEL_UNKONW,
|
||||
}GnssModel_t;
|
||||
|
||||
// Generate a string representation of DOP
|
||||
const char *getDOPString(uint32_t dop);
|
||||
|
||||
@@ -146,6 +160,14 @@ class GPS : private concurrency::OSThread
|
||||
void publishUpdate();
|
||||
|
||||
virtual int32_t runOnce() override;
|
||||
|
||||
// Get GNSS model
|
||||
GnssModel_t probe();
|
||||
|
||||
int getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID);
|
||||
|
||||
protected:
|
||||
GnssModel_t gnssModel = GNSS_MODEL_UNKONW;
|
||||
};
|
||||
|
||||
// Creates an instance of the GPS class.
|
||||
|
||||
@@ -19,14 +19,21 @@ static int32_t toDegInt(RawDegrees d)
|
||||
|
||||
bool NMEAGPS::factoryReset()
|
||||
{
|
||||
#ifdef GPS_UBLOX
|
||||
#ifdef PIN_GPS_REINIT
|
||||
//The L76K GNSS on the T-Echo requires the RESET pin to be pulled LOW
|
||||
digitalWrite(PIN_GPS_REINIT, 0);
|
||||
pinMode(PIN_GPS_REINIT, OUTPUT);
|
||||
delay(150); //The L76K datasheet calls for at least 100MS delay
|
||||
digitalWrite(PIN_GPS_REINIT, 1);
|
||||
#endif
|
||||
|
||||
// send the UBLOX Factory Reset Command regardless of detect state, something is very wrong, just assume it's UBLOX.
|
||||
// Factory Reset
|
||||
byte _message_reset[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF,
|
||||
0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0x00, 0x00, 0x17, 0x2B, 0x7E};
|
||||
_serial_gps->write(_message_reset,sizeof(_message_reset));
|
||||
delay(1000);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -155,7 +162,7 @@ bool NMEAGPS::lookForLocation()
|
||||
return false;
|
||||
}
|
||||
|
||||
p.location_source = Position_LocSource_LOCSRC_GPS_INTERNAL;
|
||||
p.location_source = Position_LocSource_LOC_INTERNAL;
|
||||
|
||||
// Dilution of precision (an accuracy metric) is reported in 10^2 units, so we need to scale down when we use it
|
||||
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
|
||||
@@ -176,8 +183,8 @@ bool NMEAGPS::lookForLocation()
|
||||
p.latitude_i = toDegInt(loc.lat);
|
||||
p.longitude_i = toDegInt(loc.lng);
|
||||
|
||||
p.alt_geoid_sep = reader.geoidHeight.meters();
|
||||
p.altitude_hae = reader.altitude.meters() + p.alt_geoid_sep;
|
||||
p.altitude_geoidal_separation = reader.geoidHeight.meters();
|
||||
p.altitude_hae = reader.altitude.meters() + p.altitude_geoidal_separation;
|
||||
p.altitude = reader.altitude.meters();
|
||||
|
||||
p.fix_quality = fixQual;
|
||||
@@ -194,7 +201,7 @@ bool NMEAGPS::lookForLocation()
|
||||
t.tm_mon = reader.date.month() - 1;
|
||||
t.tm_year = reader.date.year() - 1900;
|
||||
t.tm_isdst = false;
|
||||
p.pos_timestamp = mktime(&t);
|
||||
p.timestamp = mktime(&t);
|
||||
|
||||
// Nice to have, if available
|
||||
if (reader.satellites.isUpdated()) {
|
||||
@@ -210,13 +217,10 @@ bool NMEAGPS::lookForLocation()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// REDUNDANT?
|
||||
// expect gps pos lat=37.520825, lon=-122.309162, alt=158
|
||||
DEBUG_MSG("new NMEA GPS pos lat=%f, lon=%f, alt=%d, dop=%g, heading=%f\n",
|
||||
latitude * 1e-7, longitude * 1e-7, altitude, dop * 1e-2,
|
||||
heading * 1e-5);
|
||||
*/
|
||||
if (reader.speed.isUpdated() && reader.speed.isValid()) {
|
||||
p.ground_speed = reader.speed.kmph();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,8 +47,8 @@ void readFromRTC()
|
||||
rtc.begin();
|
||||
auto tc = rtc.getDateTime();
|
||||
tm t;
|
||||
t.tm_year = tc.year;
|
||||
t.tm_mon = tc.month;
|
||||
t.tm_year = tc.year - 1900;
|
||||
t.tm_mon = tc.month - 1;
|
||||
t.tm_mday = tc.day;
|
||||
t.tm_hour = tc.hour;
|
||||
t.tm_min = tc.minute;
|
||||
@@ -112,7 +112,7 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
|
||||
PCF8563_Class rtc;
|
||||
rtc.begin();
|
||||
tm *t = localtime(&tv->tv_sec);
|
||||
rtc.setDateTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_wday, t->tm_hour, t->tm_min, t->tm_sec);
|
||||
rtc.setDateTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
|
||||
DEBUG_MSG("PCF8563_RTC setDateTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec);
|
||||
}
|
||||
#elif defined(ARCH_ESP32)
|
||||
|
||||
@@ -57,7 +57,6 @@ namespace graphics
|
||||
|
||||
// This means the *visible* area (sh1106 can address 132, but shows 128 for example)
|
||||
#define IDLE_FRAMERATE 1 // in fps
|
||||
#define COMPASS_DIAM 44
|
||||
|
||||
// DEBUG
|
||||
#define NUM_EXTRA_FRAMES 3 // text message and debug frame
|
||||
@@ -86,7 +85,7 @@ static char ourId[5];
|
||||
GeoCoord geoCoord;
|
||||
|
||||
// OEM Config File
|
||||
static const char *oemConfigFile = "/prefs/oem.proto";
|
||||
static const char *oemConfigFile = "/oem/oem.proto";
|
||||
OEMStore oemStore;
|
||||
|
||||
#ifdef SHOW_REDRAWS
|
||||
@@ -98,7 +97,7 @@ static uint16_t displayWidth, displayHeight;
|
||||
#define SCREEN_WIDTH displayWidth
|
||||
#define SCREEN_HEIGHT displayHeight
|
||||
|
||||
#if defined(USE_EINK) || defined(ILI9341_DRIVER)
|
||||
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS)
|
||||
// The screen is bigger so use bigger fonts
|
||||
#define FONT_SMALL ArialMT_Plain_16
|
||||
#define FONT_MEDIUM ArialMT_Plain_24
|
||||
@@ -117,6 +116,7 @@ static uint16_t displayWidth, displayHeight;
|
||||
|
||||
#define FONT_HEIGHT_SMALL fontHeight(FONT_SMALL)
|
||||
#define FONT_HEIGHT_MEDIUM fontHeight(FONT_MEDIUM)
|
||||
#define FONT_HEIGHT_LARGE fontHeight(FONT_LARGE)
|
||||
|
||||
#define getStringCenteredX(s) ((SCREEN_WIDTH - display->getStringWidth(s)) / 2)
|
||||
|
||||
@@ -522,6 +522,8 @@ static void drawGPSAltitude(OLEDDisplay *display, int16_t x, int16_t y, const GP
|
||||
} else {
|
||||
geoCoord.updateCoords(int32_t(gps->getLatitude()), int32_t(gps->getLongitude()), int32_t(gps->getAltitude()));
|
||||
displayLine = "Altitude: " + String(geoCoord.getAltitude()) + "m";
|
||||
if (config.display.units == Config_DisplayConfig_DisplayUnits_IMPERIAL)
|
||||
displayLine = "Altitude: " + String(geoCoord.getAltitude() * METERS_TO_FEET) + "ft";
|
||||
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(displayLine))) / 2, y, displayLine);
|
||||
}
|
||||
}
|
||||
@@ -540,21 +542,21 @@ static void drawGPScoordinates(OLEDDisplay *display, int16_t x, int16_t y, const
|
||||
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(displayLine))) / 2, y, displayLine);
|
||||
} else {
|
||||
|
||||
if (gpsFormat != Config_DisplayConfig_GpsCoordinateFormat_GpsFormatDMS) {
|
||||
if (gpsFormat != Config_DisplayConfig_GpsCoordinateFormat_DMS) {
|
||||
char coordinateLine[22];
|
||||
geoCoord.updateCoords(int32_t(gps->getLatitude()), int32_t(gps->getLongitude()), int32_t(gps->getAltitude()));
|
||||
if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_GpsFormatDec) { // Decimal Degrees
|
||||
if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_DEC) { // Decimal Degrees
|
||||
sprintf(coordinateLine, "%f %f", geoCoord.getLatitude() * 1e-7, geoCoord.getLongitude() * 1e-7);
|
||||
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_GpsFormatUTM) { // Universal Transverse Mercator
|
||||
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_UTM) { // Universal Transverse Mercator
|
||||
sprintf(coordinateLine, "%2i%1c %06u %07u", geoCoord.getUTMZone(), geoCoord.getUTMBand(),
|
||||
geoCoord.getUTMEasting(), geoCoord.getUTMNorthing());
|
||||
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_GpsFormatMGRS) { // Military Grid Reference System
|
||||
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_MGRS) { // Military Grid Reference System
|
||||
sprintf(coordinateLine, "%2i%1c %1c%1c %05u %05u", geoCoord.getMGRSZone(), geoCoord.getMGRSBand(),
|
||||
geoCoord.getMGRSEast100k(), geoCoord.getMGRSNorth100k(), geoCoord.getMGRSEasting(),
|
||||
geoCoord.getMGRSNorthing());
|
||||
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_GpsFormatOLC) { // Open Location Code
|
||||
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_OLC) { // Open Location Code
|
||||
geoCoord.getOLCCode(coordinateLine);
|
||||
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_GpsFormatOSGR) { // Ordnance Survey Grid Reference
|
||||
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_OSGR) { // Ordnance Survey Grid Reference
|
||||
if (geoCoord.getOSGRE100k() == 'I' || geoCoord.getOSGRN100k() == 'I') // OSGR is only valid around the UK region
|
||||
sprintf(coordinateLine, "%s", "Out of Boundary");
|
||||
else
|
||||
@@ -666,6 +668,26 @@ static bool hasPosition(NodeInfo *n)
|
||||
return n->has_position && (n->position.latitude_i != 0 || n->position.longitude_i != 0);
|
||||
}
|
||||
|
||||
static uint16_t getCompassDiam(OLEDDisplay *display)
|
||||
{
|
||||
uint16_t diam = 0;
|
||||
// get the smaller of the 2 dimensions and subtract 20
|
||||
if(display->getWidth() > display->getHeight()) {
|
||||
diam = display->getHeight();
|
||||
// if 2/3 of the other size would be smaller, use that
|
||||
if (diam > (display->getWidth() * 2 / 3)) {
|
||||
diam = display->getWidth() * 2 / 3;
|
||||
}
|
||||
} else {
|
||||
diam = display->getWidth();
|
||||
if (diam > (display->getHeight() * 2 / 3)) {
|
||||
diam = display->getHeight() * 2 / 3;
|
||||
}
|
||||
}
|
||||
|
||||
return diam - 20;
|
||||
};
|
||||
|
||||
/// We will skip one node - the one for us, so we just blindly loop over all
|
||||
/// nodes
|
||||
static size_t nodeIndex;
|
||||
@@ -682,7 +704,7 @@ static void drawNodeHeading(OLEDDisplay *display, int16_t compassX, int16_t comp
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
arrowPoints[i]->rotate(headingRadian);
|
||||
arrowPoints[i]->scale(COMPASS_DIAM * 0.6);
|
||||
arrowPoints[i]->scale(getCompassDiam(display) * 0.6);
|
||||
arrowPoints[i]->translate(compassX, compassY);
|
||||
}
|
||||
drawLine(display, tip, tail);
|
||||
@@ -704,7 +726,7 @@ static void drawCompassNorth(OLEDDisplay *display, int16_t compassX, int16_t com
|
||||
for (int i = 0; i < 4; i++) {
|
||||
// North on compass will be negative of heading
|
||||
rosePoints[i]->rotate(-myHeading);
|
||||
rosePoints[i]->scale(COMPASS_DIAM);
|
||||
rosePoints[i]->scale(getCompassDiam(display));
|
||||
rosePoints[i]->translate(compassX, compassY);
|
||||
}
|
||||
drawLine(display, N1, N3);
|
||||
@@ -769,7 +791,7 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
|
||||
const char *fields[] = {username, distStr, signalStr, lastStr, NULL};
|
||||
|
||||
// coordinates for the center of the compass/circle
|
||||
int16_t compassX = x + SCREEN_WIDTH - COMPASS_DIAM / 2 - 5, compassY = y + SCREEN_HEIGHT / 2;
|
||||
int16_t compassX = x + SCREEN_WIDTH - getCompassDiam(display) / 2 - 5, compassY = y + SCREEN_HEIGHT / 2;
|
||||
bool hasNodeHeading = false;
|
||||
|
||||
if (ourNode && hasPosition(ourNode)) {
|
||||
@@ -783,10 +805,18 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
|
||||
Position &p = node->position;
|
||||
float d =
|
||||
GeoCoord::latLongToMeter(DegD(p.latitude_i), DegD(p.longitude_i), DegD(op.latitude_i), DegD(op.longitude_i));
|
||||
if (d < 2000)
|
||||
snprintf(distStr, sizeof(distStr), "%.0f m", d);
|
||||
else
|
||||
snprintf(distStr, sizeof(distStr), "%.1f km", d / 1000);
|
||||
|
||||
if (config.display.units == Config_DisplayConfig_DisplayUnits_IMPERIAL) {
|
||||
if (d < (2 * MILES_TO_FEET))
|
||||
snprintf(distStr, sizeof(distStr), "%.0f ft", d * METERS_TO_FEET);
|
||||
else
|
||||
snprintf(distStr, sizeof(distStr), "%.1f mi", d * METERS_TO_FEET / MILES_TO_FEET);
|
||||
} else {
|
||||
if (d < 2000)
|
||||
snprintf(distStr, sizeof(distStr), "%.0f m", d);
|
||||
else
|
||||
snprintf(distStr, sizeof(distStr), "%.1f km", d / 1000);
|
||||
}
|
||||
|
||||
float bearingToOther =
|
||||
GeoCoord::bearing(DegD(op.latitude_i), DegD(op.longitude_i), DegD(p.latitude_i), DegD(p.longitude_i));
|
||||
@@ -802,7 +832,7 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
|
||||
// Debug info for gps lock errors
|
||||
// DEBUG_MSG("ourNode %d, ourPos %d, theirPos %d\n", !!ourNode, ourNode && hasPosition(ourNode), hasPosition(node));
|
||||
display->drawString(compassX - FONT_HEIGHT_SMALL / 4, compassY - FONT_HEIGHT_SMALL / 2, "?");
|
||||
display->drawCircle(compassX, compassY, COMPASS_DIAM / 2);
|
||||
display->drawCircle(compassX, compassY, getCompassDiam(display) / 2);
|
||||
|
||||
// Must be after distStr is populated
|
||||
drawColumns(display, x, y, fields);
|
||||
@@ -936,8 +966,12 @@ void Screen::setup()
|
||||
|
||||
#ifdef SCREEN_MIRROR
|
||||
dispdev.mirrorScreen();
|
||||
#elif defined(SCREEN_FLIP_VERTICALLY)
|
||||
dispdev.flipScreenVertically();
|
||||
#else
|
||||
// Standard behaviour is to FLIP the screen (needed on T-Beam). If this config item is set, unflip it, and thereby logically flip it.
|
||||
// If you have a headache now, you're welcome.
|
||||
if (!config.display.flip_screen) {
|
||||
dispdev.flipScreenVertically();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Get our hardware ID
|
||||
@@ -1010,7 +1044,7 @@ int32_t Screen::runOnce()
|
||||
}
|
||||
|
||||
#ifndef DISABLE_WELCOME_UNSET
|
||||
if (showingNormalScreen && config.lora.region == Config_LoRaConfig_RegionCode_Unset) {
|
||||
if (showingNormalScreen && config.lora.region == Config_LoRaConfig_RegionCode_UNSET) {
|
||||
setWelcomeFrames();
|
||||
}
|
||||
#endif
|
||||
@@ -1071,7 +1105,6 @@ int32_t Screen::runOnce()
|
||||
// otherwise that breaks animations.
|
||||
if (targetFramerate != IDLE_FRAMERATE && ui.getUiState()->frameState == FIXED) {
|
||||
// oldFrameState = ui.getUiState()->frameState;
|
||||
DEBUG_MSG("Setting idle framerate\n");
|
||||
targetFramerate = IDLE_FRAMERATE;
|
||||
|
||||
ui.setTargetFPS(targetFramerate);
|
||||
@@ -1297,7 +1330,6 @@ void Screen::handleOnPress()
|
||||
// If we are in a transition, the press must have bounced, drop it.
|
||||
if (ui.getUiState()->frameState == FIXED) {
|
||||
ui.nextFrame();
|
||||
DEBUG_MSG("Setting LastScreenTransition\n");
|
||||
lastScreenTransition = millis();
|
||||
setFastFramerate();
|
||||
}
|
||||
@@ -1309,8 +1341,6 @@ void Screen::handleOnPress()
|
||||
|
||||
void Screen::setFastFramerate()
|
||||
{
|
||||
DEBUG_MSG("Setting fast framerate\n");
|
||||
|
||||
// We are about to start a transition so speed up fps
|
||||
targetFramerate = SCREEN_TRANSITION_FRAMERATE;
|
||||
|
||||
@@ -1366,8 +1396,8 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
|
||||
void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||
{
|
||||
#if HAS_WIFI
|
||||
const char *wifiName = config.wifi.ssid;
|
||||
const char *wifiPsw = config.wifi.psk;
|
||||
const char *wifiName = config.network.wifi_ssid;
|
||||
const char *wifiPsw = config.network.wifi_psk;
|
||||
|
||||
displayedNodeNum = 0; // Not currently showing a node pane
|
||||
|
||||
@@ -1378,7 +1408,7 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
|
||||
|
||||
if (isSoftAPForced()) {
|
||||
display->drawString(x, y, String("WiFi: Software AP (Admin)"));
|
||||
} else if (config.wifi.mode == Config_WiFiConfig_WiFiMode_AccessPoint || config.wifi.mode == Config_WiFiConfig_WiFiMode_AccessPointHidden) {
|
||||
} 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) {
|
||||
display->drawString(x, y, String("WiFi: Not Connected"));
|
||||
@@ -1401,8 +1431,8 @@ 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.wifi.mode == Config_WiFiConfig_WiFiMode_AccessPoint || config.wifi.mode == Config_WiFiConfig_WiFiMode_AccessPointHidden) {
|
||||
if (config.wifi.mode == Config_WiFiConfig_WiFiMode_AccessPoint || config.wifi.mode == Config_WiFiConfig_WiFiMode_AccessPointHidden || isSoftAPForced()) {
|
||||
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
|
||||
@@ -1494,7 +1524,7 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
|
||||
}
|
||||
|
||||
} else {
|
||||
if (config.wifi.mode == Config_WiFiConfig_WiFiMode_AccessPoint || config.wifi.mode == Config_WiFiConfig_WiFiMode_AccessPointHidden) {
|
||||
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 {
|
||||
@@ -1542,25 +1572,25 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
|
||||
auto mode = "";
|
||||
|
||||
switch (config.lora.modem_preset) {
|
||||
case Config_LoRaConfig_ModemPreset_ShortSlow:
|
||||
case Config_LoRaConfig_ModemPreset_SHORT_SLOW:
|
||||
mode = "ShortS";
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_ShortFast:
|
||||
case Config_LoRaConfig_ModemPreset_SHORT_FAST:
|
||||
mode = "ShortF";
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_MedSlow:
|
||||
case Config_LoRaConfig_ModemPreset_MEDIUM_SLOW:
|
||||
mode = "MedS";
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_MedFast:
|
||||
case Config_LoRaConfig_ModemPreset_MEDIUM_FAST:
|
||||
mode = "MedF";
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_LongSlow:
|
||||
case Config_LoRaConfig_ModemPreset_LONG_SLOW:
|
||||
mode = "LongS";
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_LongFast:
|
||||
case Config_LoRaConfig_ModemPreset_LONG_FAST:
|
||||
mode = "LongF";
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_VLongSlow:
|
||||
case Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW:
|
||||
mode = "VeryL";
|
||||
break;
|
||||
default:
|
||||
@@ -1619,7 +1649,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
|
||||
|
||||
// Line 3
|
||||
if (config.display.gps_format !=
|
||||
Config_DisplayConfig_GpsCoordinateFormat_GpsFormatDMS) // if DMS then don't draw altitude
|
||||
Config_DisplayConfig_GpsCoordinateFormat_DMS) // if DMS then don't draw altitude
|
||||
drawGPSAltitude(display, x, y + FONT_HEIGHT_SMALL * 2, gpsStatus);
|
||||
|
||||
// Line 4
|
||||
@@ -1635,6 +1665,9 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
|
||||
// adjust Brightness cycle trough 1 to 254 as long as attachDuringLongPress is true
|
||||
void Screen::adjustBrightness()
|
||||
{
|
||||
if (!useDisplay)
|
||||
return;
|
||||
|
||||
if (brightness == 254) {
|
||||
brightness = 0;
|
||||
} else {
|
||||
|
||||
@@ -57,6 +57,16 @@ class Screen
|
||||
#define BRIGHTNESS_DEFAULT 150
|
||||
#endif
|
||||
|
||||
// Meters to feet conversion
|
||||
#ifndef METERS_TO_FEET
|
||||
#define METERS_TO_FEET 3.28
|
||||
#endif
|
||||
|
||||
// Feet to miles conversion
|
||||
#ifndef MILES_TO_FEET
|
||||
#define MILES_TO_FEET 5280
|
||||
#endif
|
||||
|
||||
namespace graphics
|
||||
{
|
||||
|
||||
@@ -213,27 +223,29 @@ class Screen : public concurrency::OSThread
|
||||
LASTCHAR = ch;
|
||||
|
||||
switch (last) { // conversion depending on first UTF8-character
|
||||
case 0xC2: {
|
||||
SKIPREST = false;
|
||||
return (uint8_t)ch;
|
||||
}
|
||||
case 0xC3: {
|
||||
SKIPREST = false;
|
||||
return (uint8_t)(ch | 0xC0);
|
||||
}
|
||||
// map UTF-8 cyrillic chars to it Windows-1251 (CP-1251) ASCII codes
|
||||
// note: in this case we must use compatible font - provided ArialMT_Plain_10/16/24 by 'ThingPulse/esp8266-oled-ssd1306' library
|
||||
// have empty chars for non-latin ASCII symbols
|
||||
case 0xD0: {
|
||||
SKIPREST = false;
|
||||
if (ch == 129) return (uint8_t)(168); // Ё
|
||||
if (ch > 143 && ch < 192) return (uint8_t)(ch + 48);
|
||||
}
|
||||
case 0xD1: {
|
||||
SKIPREST = false;
|
||||
if (ch == 145) return (uint8_t)(184); // ё
|
||||
if (ch > 127 && ch < 144) return (uint8_t)(ch + 112);
|
||||
}
|
||||
case 0xC2: {
|
||||
SKIPREST = false;
|
||||
return (uint8_t)ch;
|
||||
}
|
||||
case 0xC3: {
|
||||
SKIPREST = false;
|
||||
return (uint8_t)(ch | 0xC0);
|
||||
}
|
||||
// map UTF-8 cyrillic chars to it Windows-1251 (CP-1251) ASCII codes
|
||||
// note: in this case we must use compatible font - provided ArialMT_Plain_10/16/24 by 'ThingPulse/esp8266-oled-ssd1306' library
|
||||
// have empty chars for non-latin ASCII symbols
|
||||
case 0xD0: {
|
||||
SKIPREST = false;
|
||||
if (ch == 129) return (uint8_t)(168); // Ё
|
||||
if (ch > 143 && ch < 192) return (uint8_t)(ch + 48);
|
||||
break;
|
||||
}
|
||||
case 0xD1: {
|
||||
SKIPREST = false;
|
||||
if (ch == 145) return (uint8_t)(184); // ё
|
||||
if (ch > 127 && ch < 144) return (uint8_t)(ch + 112);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// We want to strip out prefix chars for two-byte char formats
|
||||
|
||||
@@ -22,13 +22,23 @@ void TFTDisplay::display(void)
|
||||
{
|
||||
concurrency::LockGuard g(spiLock);
|
||||
|
||||
// FIXME - only draw bits have changed (use backbuf similar to the other displays)
|
||||
// tft.drawBitmap(0, 0, buffer, 128, 64, TFT_YELLOW, TFT_BLACK);
|
||||
for (uint16_t y = 0; y < displayHeight; y++) {
|
||||
for (uint16_t x = 0; x < displayWidth; x++) {
|
||||
uint16_t x,y;
|
||||
|
||||
for (y = 0; y < displayHeight; y++) {
|
||||
for (x = 0; x < displayWidth; x++) {
|
||||
// get src pixel in the page based ordering the OLED lib uses FIXME, super inefficent
|
||||
auto isset = buffer[x + (y / 8) * displayWidth] & (1 << (y & 7));
|
||||
tft.drawPixel(x, y, isset ? TFT_WHITE : TFT_BLACK);
|
||||
auto dblbuf_isset = buffer_back[x + (y / 8) * displayWidth] & (1 << (y & 7));
|
||||
if (isset != dblbuf_isset) {
|
||||
tft.drawPixel(x, y, isset ? TFT_WHITE : TFT_BLACK);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Copy the Buffer to the Back Buffer
|
||||
for (y = 0; y < (displayHeight / 8); y++) {
|
||||
for (x = 0; x < displayWidth; x++) {
|
||||
uint16_t pos = x + y * displayWidth;
|
||||
buffer_back[pos] = buffer[pos];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
#pragma once
|
||||
#include "Observer.h"
|
||||
|
||||
#define ANYKEY 0xFF
|
||||
#define MATRIXKEY 0xFE
|
||||
|
||||
typedef struct _InputEvent {
|
||||
const char* source;
|
||||
char inputEvent;
|
||||
char kbchar;
|
||||
} InputEvent;
|
||||
class InputBroker :
|
||||
public Observable<const InputEvent *>
|
||||
|
||||
@@ -34,7 +34,7 @@ void RotaryEncoderInterruptBase::init(
|
||||
int32_t RotaryEncoderInterruptBase::runOnce()
|
||||
{
|
||||
InputEvent e;
|
||||
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE;
|
||||
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
|
||||
e.source = this->_originName;
|
||||
|
||||
if (this->action == ROTARY_ACTION_PRESSED) {
|
||||
@@ -48,7 +48,7 @@ int32_t RotaryEncoderInterruptBase::runOnce()
|
||||
e.inputEvent = this->_eventCcw;
|
||||
}
|
||||
|
||||
if (e.inputEvent != ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE) {
|
||||
if (e.inputEvent != ModuleConfig_CannedMessageConfig_InputEventChar_NONE) {
|
||||
this->notifyObservers(&e);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,8 +33,8 @@ class RotaryEncoderInterruptBase : public Observable<const InputEvent *>, privat
|
||||
private:
|
||||
uint8_t _pinA = 0;
|
||||
uint8_t _pinB = 0;
|
||||
char _eventCw = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE;
|
||||
char _eventCcw = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE;
|
||||
char _eventPressed = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE;
|
||||
char _eventCw = ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
|
||||
char _eventCcw = ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
|
||||
char _eventPressed = ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
|
||||
const char *_originName;
|
||||
};
|
||||
|
||||
@@ -16,8 +16,8 @@ class UpDownInterruptBase : public Observable<const InputEvent *>
|
||||
private:
|
||||
uint8_t _pinDown = 0;
|
||||
uint8_t _pinUp = 0;
|
||||
char _eventDown = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE;
|
||||
char _eventUp = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE;
|
||||
char _eventPressed = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE;
|
||||
char _eventDown = ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
|
||||
char _eventUp = ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
|
||||
char _eventPressed = ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
|
||||
const char *_originName;
|
||||
};
|
||||
|
||||
@@ -17,9 +17,9 @@ void UpDownInterruptImpl1::init()
|
||||
uint8_t pinDown = moduleConfig.canned_message.inputbroker_pin_b;
|
||||
uint8_t pinPress = moduleConfig.canned_message.inputbroker_pin_press;
|
||||
|
||||
char eventDown = static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_KEY_DOWN);
|
||||
char eventUp = static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_KEY_UP);
|
||||
char eventPressed = static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_KEY_SELECT);
|
||||
char eventDown = static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_DOWN);
|
||||
char eventUp = static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_UP);
|
||||
char eventPressed = static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_SELECT);
|
||||
|
||||
UpDownInterruptBase::init(pinDown, pinUp, pinPress, eventDown, eventUp, eventPressed, UpDownInterruptImpl1::handleIntDown,
|
||||
UpDownInterruptImpl1::handleIntUp, UpDownInterruptImpl1::handleIntPressed);
|
||||
|
||||
@@ -16,6 +16,5 @@ void CardKbI2cImpl::init()
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_MSG("registerSource\n");
|
||||
inputBroker->registerSource(this);
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
#include "facesKbI2cImpl.h"
|
||||
#include "InputBroker.h"
|
||||
|
||||
FacesKbI2cImpl *facesKbI2cImpl;
|
||||
|
||||
FacesKbI2cImpl::FacesKbI2cImpl() :
|
||||
KbI2cBase("facesKB")
|
||||
{
|
||||
}
|
||||
|
||||
void FacesKbI2cImpl::init()
|
||||
{
|
||||
if (faceskb_found != FACESKB_ADDR)
|
||||
{
|
||||
// Input device is not detected.
|
||||
return;
|
||||
}
|
||||
|
||||
inputBroker->registerSource(this);
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
#pragma once
|
||||
#include "kbI2cBase.h"
|
||||
#include "main.h"
|
||||
|
||||
/**
|
||||
* @brief The idea behind this class to have static methods for the event handlers.
|
||||
* Check attachInterrupt() at RotaryEncoderInteruptBase.cpp
|
||||
* Technically you can have as many rotary encoders hardver attached
|
||||
* to your device as you wish, but you always need to have separate event
|
||||
* handlers, thus you need to have a RotaryEncoderInterrupt implementation.
|
||||
*/
|
||||
class FacesKbI2cImpl :
|
||||
public KbI2cBase
|
||||
{
|
||||
public:
|
||||
FacesKbI2cImpl();
|
||||
void init();
|
||||
};
|
||||
|
||||
extern FacesKbI2cImpl *facesKbI2cImpl;
|
||||
@@ -2,48 +2,114 @@
|
||||
#include "configuration.h"
|
||||
#include <Wire.h>
|
||||
|
||||
extern uint8_t cardkb_found;
|
||||
extern uint8_t kb_model;
|
||||
|
||||
KbI2cBase::KbI2cBase(const char *name) : concurrency::OSThread(name)
|
||||
{
|
||||
this->_originName = name;
|
||||
}
|
||||
|
||||
uint8_t read_from_14004(uint8_t reg, uint8_t *data, uint8_t length)
|
||||
{
|
||||
uint8_t readflag = 0;
|
||||
Wire.beginTransmission(CARDKB_ADDR);
|
||||
Wire.write(reg);
|
||||
Wire.endTransmission(); // stop transmitting
|
||||
delay(20);
|
||||
Wire.requestFrom(CARDKB_ADDR, (int)length);
|
||||
int i = 0;
|
||||
while ( Wire.available() ) // slave may send less than requested
|
||||
{
|
||||
data[i++] = Wire.read(); // receive a byte as a proper uint8_t
|
||||
readflag = 1;
|
||||
}
|
||||
return readflag;
|
||||
}
|
||||
|
||||
void write_to_14004(uint8_t reg, uint8_t data)
|
||||
{
|
||||
Wire.beginTransmission(CARDKB_ADDR);
|
||||
Wire.write(reg);
|
||||
Wire.write(data);
|
||||
Wire.endTransmission(); // stop transmitting
|
||||
}
|
||||
|
||||
int32_t KbI2cBase::runOnce()
|
||||
{
|
||||
InputEvent e;
|
||||
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE;
|
||||
e.source = this->_originName;
|
||||
|
||||
Wire.requestFrom(CARDKB_ADDR, 1);
|
||||
|
||||
while (Wire.available()) {
|
||||
char c = Wire.read();
|
||||
switch (c) {
|
||||
case 0x1b: // ESC
|
||||
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_CANCEL;
|
||||
break;
|
||||
case 0x08: // Back
|
||||
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_BACK;
|
||||
break;
|
||||
case 0xb5: // Up
|
||||
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_UP;
|
||||
break;
|
||||
case 0xb6: // Down
|
||||
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_DOWN;
|
||||
break;
|
||||
case 0xb4: // Left
|
||||
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_LEFT;
|
||||
break;
|
||||
case 0xb7: // Right
|
||||
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_RIGHT;
|
||||
break;
|
||||
case 0x0d: // Enter
|
||||
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_SELECT;
|
||||
break;
|
||||
}
|
||||
if (cardkb_found != CARDKB_ADDR){
|
||||
// Input device is not detected.
|
||||
return INT32_MAX;
|
||||
}
|
||||
|
||||
if (e.inputEvent != ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE) {
|
||||
this->notifyObservers(&e);
|
||||
if (kb_model == 0x02) {
|
||||
// RAK14004
|
||||
uint8_t rDataBuf[8] = {0};
|
||||
uint8_t PrintDataBuf = 0;
|
||||
if (read_from_14004(0x01, rDataBuf, 0x04) == 1) {
|
||||
for (uint8_t aCount = 0; aCount < 0x04; aCount++) {
|
||||
for (uint8_t bCount = 0; bCount < 0x04; bCount++ ) {
|
||||
if (((rDataBuf[aCount] >> bCount) & 0x01) == 0x01) {
|
||||
PrintDataBuf = aCount * 0x04 + bCount + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (PrintDataBuf != 0) {
|
||||
DEBUG_MSG("RAK14004 key 0x%x pressed\n", PrintDataBuf);
|
||||
InputEvent e;
|
||||
e.inputEvent = MATRIXKEY;
|
||||
e.source = this->_originName;
|
||||
e.kbchar = PrintDataBuf;
|
||||
this->notifyObservers(&e);
|
||||
}
|
||||
} else {
|
||||
// m5 cardkb
|
||||
Wire.requestFrom(CARDKB_ADDR, 1);
|
||||
|
||||
while (Wire.available()) {
|
||||
char c = Wire.read();
|
||||
InputEvent e;
|
||||
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
|
||||
e.source = this->_originName;
|
||||
switch (c) {
|
||||
case 0x1b: // ESC
|
||||
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL;
|
||||
break;
|
||||
case 0x08: // Back
|
||||
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_BACK;
|
||||
e.kbchar = c;
|
||||
break;
|
||||
case 0xb5: // Up
|
||||
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_UP;
|
||||
break;
|
||||
case 0xb6: // Down
|
||||
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_DOWN;
|
||||
break;
|
||||
case 0xb4: // Left
|
||||
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_LEFT;
|
||||
e.kbchar = c;
|
||||
break;
|
||||
case 0xb7: // Right
|
||||
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT;
|
||||
e.kbchar = c;
|
||||
break;
|
||||
case 0x0d: // Enter
|
||||
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_SELECT;
|
||||
break;
|
||||
case 0x00: //nopress
|
||||
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
|
||||
break;
|
||||
default: // all other keys
|
||||
e.inputEvent = ANYKEY;
|
||||
e.kbchar = c;
|
||||
break;
|
||||
}
|
||||
|
||||
if (e.inputEvent != ModuleConfig_CannedMessageConfig_InputEventChar_NONE) {
|
||||
this->notifyObservers(&e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 500;
|
||||
}
|
||||
|
||||
47
src/main.cpp
47
src/main.cpp
@@ -36,7 +36,7 @@
|
||||
#include "nimble/NimbleBluetooth.h"
|
||||
#endif
|
||||
|
||||
#if HAS_WIFI
|
||||
#if HAS_WIFI || defined(ARCH_PORTDUINO)
|
||||
#include "mesh/wifi/WiFiServerAPI.h"
|
||||
#include "mqtt/MQTT.h"
|
||||
#endif
|
||||
@@ -45,6 +45,9 @@
|
||||
#include "RF95Interface.h"
|
||||
#include "SX1262Interface.h"
|
||||
#include "SX1268Interface.h"
|
||||
#if !HAS_RADIO && defined(ARCH_PORTDUINO)
|
||||
#include "platform/portduino/SimRadio.h"
|
||||
#endif
|
||||
|
||||
#if HAS_BUTTON
|
||||
#include "ButtonThread.h"
|
||||
@@ -74,20 +77,23 @@ uint8_t cardkb_found;
|
||||
// 0x02 for RAK14004 and 0x00 for cardkb
|
||||
uint8_t kb_model;
|
||||
|
||||
// The I2C address of the Faces Keyboard (if found)
|
||||
uint8_t faceskb_found;
|
||||
|
||||
// The I2C address of the RTC Module (if found)
|
||||
uint8_t rtc_found;
|
||||
|
||||
// Keystore Chips
|
||||
uint8_t keystore_found;
|
||||
#ifndef ARCH_PORTDUINO
|
||||
ATECCX08A atecc;
|
||||
#endif
|
||||
|
||||
bool eink_found = true;
|
||||
|
||||
uint32_t serialSinceMsec;
|
||||
|
||||
bool axp192_found;
|
||||
bool pmu_found;
|
||||
|
||||
// Array map of sensor types (as array index) and i2c address as value we'll find in the i2c scan
|
||||
uint8_t nodeTelemetrySensorsMap[7] = { 0, 0, 0, 0, 0, 0, 0 };
|
||||
uint8_t nodeTelemetrySensorsMap[TelemetrySensorType_QMI8658+1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
Router *router = NULL; // Users of router don't care what sort of subclass implements that API
|
||||
|
||||
@@ -157,9 +163,7 @@ void setup()
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_PORT
|
||||
if (!config.device.serial_disabled) {
|
||||
consoleInit(); // Set serial baud rate and init our mesh console
|
||||
}
|
||||
#endif
|
||||
|
||||
serialSinceMsec = millis();
|
||||
@@ -216,6 +220,10 @@ void setup()
|
||||
// router = new DSRRouter();
|
||||
router = new ReliableRouter();
|
||||
|
||||
#ifdef I2C_SDA1
|
||||
Wire1.begin(I2C_SDA1, I2C_SCL1);
|
||||
#endif
|
||||
|
||||
#ifdef I2C_SDA
|
||||
Wire.begin(I2C_SDA, I2C_SCL);
|
||||
#elif HAS_WIRE
|
||||
@@ -231,6 +239,7 @@ void setup()
|
||||
delay(1);
|
||||
#endif
|
||||
|
||||
// We need to scan here to decide if we have a screen for nodeDB.init()
|
||||
scanI2Cdevice();
|
||||
#ifdef RAK4630
|
||||
// scanEInkDevice();
|
||||
@@ -271,6 +280,14 @@ void setup()
|
||||
powerStatus->observe(&power->newStatus);
|
||||
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.
|
||||
* 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();
|
||||
}
|
||||
|
||||
// Init our SPI controller (must be before screen and lora)
|
||||
initSPI();
|
||||
#ifndef ARCH_ESP32
|
||||
@@ -301,9 +318,9 @@ void setup()
|
||||
setupModules();
|
||||
|
||||
// Do this after service.init (because that clears error_code)
|
||||
#ifdef HAS_AXP192
|
||||
if (!axp192_found)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_NoAXP192); // Record a hardware fault for missing hardware
|
||||
#ifdef HAS_PMU
|
||||
if (!pmu_found)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_NO_AXP192); // Record a hardware fault for missing hardware
|
||||
#endif
|
||||
|
||||
// Don't call screen setup until after nodedb is setup (because we need
|
||||
@@ -324,7 +341,7 @@ void setup()
|
||||
DEBUG_MSG("GPS FactoryReset requested\n");
|
||||
if (gps->factoryReset()) { // If we don't succeed try again next time
|
||||
devicestate.did_gps_reset = true;
|
||||
nodeDB.saveToDisk();
|
||||
nodeDB.saveToDisk(SEGMENT_DEVICESTATE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -388,7 +405,7 @@ void setup()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !HAS_RADIO
|
||||
#ifdef ARCH_PORTDUINO
|
||||
if (!rIf) {
|
||||
rIf = new SimRadio;
|
||||
if (!rIf->init()) {
|
||||
@@ -414,14 +431,14 @@ void setup()
|
||||
#endif
|
||||
|
||||
#ifdef ARCH_PORTDUINO
|
||||
initApiServer();
|
||||
initApiServer(TCPPort);
|
||||
#endif
|
||||
|
||||
// Start airtime logger thread.
|
||||
airTime = new AirTime();
|
||||
|
||||
if (!rIf)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_NoRadio);
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_NO_RADIO);
|
||||
else {
|
||||
router->addInterface(rIf);
|
||||
|
||||
|
||||
15
src/main.h
15
src/main.h
@@ -6,20 +6,29 @@
|
||||
#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 faceskb_found;
|
||||
extern uint8_t rtc_found;
|
||||
extern uint8_t keystore_found;
|
||||
|
||||
extern bool eink_found;
|
||||
extern bool axp192_found;
|
||||
extern bool pmu_found;
|
||||
extern bool isCharging;
|
||||
extern bool isUSBPowered;
|
||||
|
||||
extern uint8_t nodeTelemetrySensorsMap[7];
|
||||
#ifndef ARCH_PORTDUINO
|
||||
extern ATECCX08A atecc;
|
||||
#endif
|
||||
|
||||
extern uint8_t nodeTelemetrySensorsMap[TelemetrySensorType_QMI8658+1];
|
||||
|
||||
extern int TCPPort; // set by Portduino
|
||||
|
||||
// Global Screen singleton.
|
||||
extern graphics::Screen *screen;
|
||||
|
||||
@@ -85,7 +85,7 @@ void Channels::initDefaultChannel(ChannelIndex chIndex)
|
||||
ChannelSettings &channelSettings = ch.settings;
|
||||
Config_LoRaConfig &loraConfig = config.lora;
|
||||
|
||||
loraConfig.modem_preset = Config_LoRaConfig_ModemPreset_LongFast; // Default to Long Range & Fast
|
||||
loraConfig.modem_preset = Config_LoRaConfig_ModemPreset_LONG_FAST; // Default to Long Range & Fast
|
||||
|
||||
loraConfig.tx_power = 0; // default
|
||||
uint8_t defaultpskIndex = 1;
|
||||
@@ -214,26 +214,26 @@ const char *Channels::getName(size_t chIndex)
|
||||
channelName = "Custom";
|
||||
else
|
||||
switch (config.lora.modem_preset) {
|
||||
case Config_LoRaConfig_ModemPreset_ShortSlow:
|
||||
channelName = "ShortS";
|
||||
case Config_LoRaConfig_ModemPreset_SHORT_SLOW:
|
||||
channelName = "ShortSlow";
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_ShortFast:
|
||||
channelName = "ShortF";
|
||||
case Config_LoRaConfig_ModemPreset_SHORT_FAST:
|
||||
channelName = "ShortFast";
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_MedSlow:
|
||||
channelName = "MedS";
|
||||
case Config_LoRaConfig_ModemPreset_MEDIUM_SLOW:
|
||||
channelName = "MediumSlow";
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_MedFast:
|
||||
channelName = "MedF";
|
||||
case Config_LoRaConfig_ModemPreset_MEDIUM_FAST:
|
||||
channelName = "MediumFast";
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_LongSlow:
|
||||
channelName = "LongS";
|
||||
case Config_LoRaConfig_ModemPreset_LONG_SLOW:
|
||||
channelName = "LongSlow";
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_LongFast:
|
||||
channelName = "LongF";
|
||||
case Config_LoRaConfig_ModemPreset_LONG_FAST:
|
||||
channelName = "LongFast";
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_VLongSlow:
|
||||
channelName = "VeryL";
|
||||
case Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW:
|
||||
channelName = "VLongSlow";
|
||||
break;
|
||||
default:
|
||||
channelName = "Invalid";
|
||||
|
||||
@@ -36,7 +36,7 @@ void FloodingRouter::sniffReceived(const MeshPacket *p, const Routing *c)
|
||||
Router::cancelSending(p->to, p->decoded.request_id); // cancel rebroadcast for this DM
|
||||
} else if ((p->to != getNodeNum()) && (p->hop_limit > 0) && (getFrom(p) != getNodeNum())) {
|
||||
if (p->id != 0) {
|
||||
if (config.device.role != Config_DeviceConfig_Role_ClientMute) {
|
||||
if (config.device.role != Config_DeviceConfig_Role_CLIENT_MUTE) {
|
||||
MeshPacket *tosend = packetPool.allocCopy(*p); // keep a copy because we will be sending it
|
||||
|
||||
tosend->hop_limit--; // bump down the hop count
|
||||
|
||||
@@ -72,7 +72,7 @@ void MeshModule::callPlugins(const MeshPacket &mp, RxSource src)
|
||||
bool moduleFound = false;
|
||||
|
||||
// We now allow **encrypted** packets to pass through the modules
|
||||
bool isDecoded = mp.which_payloadVariant == MeshPacket_decoded_tag;
|
||||
bool isDecoded = mp.which_payload_variant == MeshPacket_decoded_tag;
|
||||
|
||||
currentReply = NULL; // No reply yet
|
||||
|
||||
@@ -112,7 +112,7 @@ void MeshModule::callPlugins(const MeshPacket &mp, RxSource src)
|
||||
bool rxChannelOk = !pi.boundChannel || (mp.from == 0) ||
|
||||
!ch ||
|
||||
strlen(ch->settings.name) > 0 ||
|
||||
strcmp(ch->settings.name, pi.boundChannel);
|
||||
(strcasecmp(ch->settings.name, pi.boundChannel) == 0);
|
||||
|
||||
if (!rxChannelOk) {
|
||||
// no one should have already replied!
|
||||
@@ -211,7 +211,7 @@ void MeshModule::sendResponse(const MeshPacket &req)
|
||||
*/
|
||||
void setReplyTo(MeshPacket *p, const MeshPacket &to)
|
||||
{
|
||||
assert(p->which_payloadVariant == MeshPacket_decoded_tag); // Should already be set by now
|
||||
assert(p->which_payload_variant == MeshPacket_decoded_tag); // Should already be set by now
|
||||
p->to = getFrom(&to); // Make sure that if we are sending to the local node, we use our local node addr, not 0
|
||||
p->channel = to.channel; // Use the same channel that the request came in on
|
||||
|
||||
@@ -266,7 +266,7 @@ AdminMessageHandleResult MeshModule::handleAdminMessageForAllPlugins(const MeshP
|
||||
// In case we have a response it always has priority.
|
||||
DEBUG_MSG("Reply prepared by module '%s' of variant: %d\n",
|
||||
pi.name,
|
||||
response->which_variant);
|
||||
response->which_payload_variant);
|
||||
handled = h;
|
||||
}
|
||||
else if ((handled != AdminMessageHandleResult::HANDLED_WITH_RESPONSE) &&
|
||||
|
||||
@@ -90,7 +90,7 @@ void MeshService::loop()
|
||||
}
|
||||
|
||||
/// The radioConfig object just changed, call this to force the hw to change to the new settings
|
||||
bool MeshService::reloadConfig()
|
||||
bool MeshService::reloadConfig(int saveWhat)
|
||||
{
|
||||
// If we can successfully set this radio to these settings, save them to disk
|
||||
|
||||
@@ -98,7 +98,7 @@ bool MeshService::reloadConfig()
|
||||
bool didReset = nodeDB.resetRadioConfig(); // Don't let the phone send us fatally bad settings
|
||||
|
||||
configChanged.notifyObservers(NULL); // This will cause radio hardware to change freqs etc
|
||||
nodeDB.saveToDisk();
|
||||
nodeDB.saveToDisk(saveWhat);
|
||||
|
||||
return didReset;
|
||||
}
|
||||
@@ -113,7 +113,7 @@ void MeshService::reloadOwner()
|
||||
// update everyone else
|
||||
if (nodeInfoModule)
|
||||
nodeInfoModule->sendOurNodeInfo();
|
||||
nodeDB.saveToDisk();
|
||||
nodeDB.saveToDisk(SEGMENT_DEVICESTATE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -123,6 +123,29 @@ void MeshService::reloadOwner()
|
||||
*/
|
||||
void MeshService::handleToRadio(MeshPacket &p)
|
||||
{
|
||||
#ifdef ARCH_PORTDUINO
|
||||
// Simulates device is receiving a packet via the LoRa chip
|
||||
if (p.decoded.portnum == PortNum_SIMULATOR_APP) {
|
||||
// Simulator packet (=Compressed packet) is encapsulated in a MeshPacket, so need to unwrap first
|
||||
Compressed scratch;
|
||||
Compressed *decoded = NULL;
|
||||
if (p.which_payload_variant == MeshPacket_decoded_tag) {
|
||||
memset(&scratch, 0, sizeof(scratch));
|
||||
p.decoded.payload.size = pb_decode_from_bytes(p.decoded.payload.bytes, p.decoded.payload.size, &Compressed_msg, &scratch);
|
||||
if (p.decoded.payload.size) {
|
||||
decoded = &scratch;
|
||||
// Extract the original payload and replace
|
||||
memcpy(&p.decoded.payload, &decoded->data, sizeof(decoded->data));
|
||||
// Switch the port from PortNum_SIMULATOR_APP back to the original PortNum
|
||||
p.decoded.portnum = decoded->portnum;
|
||||
} else
|
||||
DEBUG_MSG("Error decoding protobuf for simulator message!\n");
|
||||
}
|
||||
// Let SimRadio receive as if it did via its LoRa chip
|
||||
SimRadio::instance->startReceive(&p);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (p.from != 0) { // We don't let phones assign nodenums to their sent messages
|
||||
DEBUG_MSG("Warning: phone tried to pick a nodenum, we don't allow that.\n");
|
||||
p.from = 0;
|
||||
@@ -252,7 +275,7 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
|
||||
pos.time = getValidTime(RTCQualityGPS);
|
||||
|
||||
// In debug logs, identify position by @timestamp:stage (stage 4 = nodeDB)
|
||||
DEBUG_MSG("onGPSChanged() pos@%x, time=%u, lat=%d, lon=%d, alt=%d\n", pos.pos_timestamp, pos.time, pos.latitude_i,
|
||||
DEBUG_MSG("onGPSChanged() pos@%x, time=%u, lat=%d, lon=%d, alt=%d\n", pos.timestamp, pos.time, pos.latitude_i,
|
||||
pos.longitude_i, pos.altitude);
|
||||
|
||||
// Update our current position in the local DB
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
#include "MeshTypes.h"
|
||||
#include "Observer.h"
|
||||
#include "PointerQueue.h"
|
||||
#ifdef ARCH_PORTDUINO
|
||||
#include "../platform/portduino/SimRadio.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Top level app for this service. keeps the mesh, the radio config and the queue of received packets.
|
||||
@@ -63,7 +66,7 @@ class MeshService
|
||||
/** The radioConfig object just changed, call this to force the hw to change to the new settings
|
||||
* @return true if client devices should be sent a new set of radio configs
|
||||
*/
|
||||
bool reloadConfig();
|
||||
bool reloadConfig(int saveWhat=SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS);
|
||||
|
||||
/// The owner User record just got updated, update our node DB and broadcast the info into the mesh
|
||||
void reloadOwner();
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "mesh-pb-constants.h"
|
||||
#include <pb_decode.h>
|
||||
#include <pb_encode.h>
|
||||
#include <ErriezCRC32.h>
|
||||
|
||||
#ifdef ARCH_ESP32
|
||||
#include "mesh/http/WiFiAPClient.h"
|
||||
@@ -73,14 +74,13 @@ NodeNum getFrom(const MeshPacket *p)
|
||||
return (p->from == 0) ? nodeDB.getNodeNum() : p->from;
|
||||
}
|
||||
|
||||
bool NodeDB::resetRadioConfig()
|
||||
bool NodeDB::resetRadioConfig(bool factory_reset)
|
||||
{
|
||||
bool didFactoryReset = false;
|
||||
|
||||
radioGeneration++;
|
||||
|
||||
// radioConfig.has_preferences = true;
|
||||
if (config.device.factory_reset) {
|
||||
if (factory_reset) {
|
||||
didFactoryReset = factoryReset();
|
||||
}
|
||||
|
||||
@@ -113,7 +113,6 @@ bool NodeDB::resetRadioConfig()
|
||||
initRegion();
|
||||
|
||||
if (didFactoryReset) {
|
||||
config.device.factory_reset = false;
|
||||
DEBUG_MSG("Rebooting due to factory reset");
|
||||
screen->startRebootScreen();
|
||||
rebootAtMsec = millis() + (5 * 1000);
|
||||
@@ -130,7 +129,7 @@ bool NodeDB::factoryReset()
|
||||
// second, install default state (this will deal with the duplicate mac address issue)
|
||||
installDefaultDeviceState();
|
||||
installDefaultConfig();
|
||||
// third, write to disk
|
||||
// third, write everything to disk
|
||||
saveToDisk();
|
||||
#ifdef ARCH_ESP32
|
||||
// This will erase what's in NVS including ssl keys, persistant variables and ble pairing
|
||||
@@ -157,13 +156,17 @@ void NodeDB::installDefaultConfig()
|
||||
config.has_lora = true;
|
||||
config.has_position = true;
|
||||
config.has_power = true;
|
||||
config.has_wifi = true;
|
||||
config.has_network = true;
|
||||
config.has_bluetooth = true;
|
||||
|
||||
config.lora.region = Config_LoRaConfig_RegionCode_Unset;
|
||||
config.lora.modem_preset = Config_LoRaConfig_ModemPreset_LongFast;
|
||||
config.lora.tx_enabled = true; // FIXME: maybe false in the future, and setting region to enable it. (unset region forces it off)
|
||||
config.lora.region = Config_LoRaConfig_RegionCode_UNSET;
|
||||
config.lora.modem_preset = Config_LoRaConfig_ModemPreset_LONG_FAST;
|
||||
config.lora.hop_limit = HOP_RELIABLE;
|
||||
config.position.gps_enabled = true;
|
||||
config.position.position_broadcast_smart_enabled = true;
|
||||
config.device.serial_enabled = true;
|
||||
resetRadioConfig();
|
||||
strncpy(config.device.ntp_server, "0.pool.ntp.org", 32);
|
||||
strncpy(config.network.ntp_server, "0.pool.ntp.org", 32);
|
||||
// FIXME: Default to bluetooth capability of platform as default
|
||||
config.bluetooth.enabled = true;
|
||||
config.bluetooth.fixed_pin = defaultBLEPin;
|
||||
@@ -172,9 +175,26 @@ void NodeDB::installDefaultConfig()
|
||||
#else
|
||||
bool hasScreen = screen_found;
|
||||
#endif
|
||||
config.bluetooth.mode = hasScreen ? Config_BluetoothConfig_PairingMode_RandomPin : Config_BluetoothConfig_PairingMode_FixedPin;
|
||||
config.bluetooth.mode = hasScreen ? Config_BluetoothConfig_PairingMode_RANDOM_PIN : Config_BluetoothConfig_PairingMode_FIXED_PIN;
|
||||
// for backward compat, default position flags are ALT+MSL
|
||||
config.position.position_flags = (Config_PositionConfig_PositionFlags_POS_ALTITUDE | Config_PositionConfig_PositionFlags_POS_ALT_MSL);
|
||||
config.position.position_flags = (Config_PositionConfig_PositionFlags_ALTITUDE | Config_PositionConfig_PositionFlags_ALTITUDE_MSL);
|
||||
|
||||
initConfigIntervals();
|
||||
}
|
||||
|
||||
void NodeDB::initConfigIntervals()
|
||||
{
|
||||
config.position.gps_update_interval = default_gps_update_interval;
|
||||
config.position.gps_attempt_time = default_gps_attempt_time;
|
||||
config.position.position_broadcast_secs = default_broadcast_interval_secs;
|
||||
|
||||
config.power.ls_secs = default_ls_secs;
|
||||
config.power.mesh_sds_timeout_secs = default_mesh_sds_timeout_secs;
|
||||
config.power.min_wake_secs = default_min_wake_secs;
|
||||
config.power.sds_secs = default_sds_secs;
|
||||
config.power.wait_bluetooth_secs = default_wait_bluetooth_secs;
|
||||
|
||||
config.display.screen_on_secs = default_screen_on_secs;
|
||||
}
|
||||
|
||||
void NodeDB::installDefaultModuleConfig()
|
||||
@@ -189,6 +209,14 @@ void NodeDB::installDefaultModuleConfig()
|
||||
moduleConfig.has_telemetry = true;
|
||||
moduleConfig.has_external_notification = true;
|
||||
moduleConfig.has_canned_message = true;
|
||||
|
||||
initModuleConfigIntervals();
|
||||
}
|
||||
|
||||
void NodeDB::initModuleConfigIntervals()
|
||||
{
|
||||
moduleConfig.telemetry.device_update_interval = default_broadcast_interval_secs;
|
||||
moduleConfig.telemetry.environment_update_interval = default_broadcast_interval_secs;
|
||||
}
|
||||
|
||||
void NodeDB::installDefaultChannels()
|
||||
@@ -198,13 +226,20 @@ void NodeDB::installDefaultChannels()
|
||||
channelFile.version = DEVICESTATE_CUR_VER;
|
||||
}
|
||||
|
||||
void NodeDB::resetNodes()
|
||||
{
|
||||
devicestate.node_db_count = 0;
|
||||
memset(devicestate.node_db, 0, sizeof(devicestate.node_db));
|
||||
saveDeviceStateToDisk();
|
||||
}
|
||||
|
||||
void NodeDB::installDefaultDeviceState()
|
||||
{
|
||||
DEBUG_MSG("Installing default DeviceState\n");
|
||||
memset(&devicestate, 0, sizeof(DeviceState));
|
||||
|
||||
*numNodes = 0; // Forget node DB
|
||||
|
||||
*numNodes = 0;
|
||||
|
||||
// init our devicestate with valid flags so protobuf writing/reading will work
|
||||
devicestate.has_my_node = true;
|
||||
devicestate.has_owner = true;
|
||||
@@ -232,12 +267,17 @@ void NodeDB::installDefaultDeviceState()
|
||||
void NodeDB::init()
|
||||
{
|
||||
DEBUG_MSG("Initializing NodeDB\n");
|
||||
// saveToDisk();
|
||||
loadFromDisk();
|
||||
|
||||
uint32_t devicestateCRC = crc32Buffer(&devicestate, sizeof(devicestate));
|
||||
uint32_t configCRC = crc32Buffer(&config, sizeof(config));
|
||||
uint32_t channelFileCRC = crc32Buffer(&channelFile, sizeof(channelFile));
|
||||
|
||||
int saveWhat = 0;
|
||||
|
||||
myNodeInfo.max_channels = MAX_NUM_CHANNELS; // tell others the max # of channels we can understand
|
||||
|
||||
myNodeInfo.error_code = CriticalErrorCode_None; // For the error code, only show values from this boot (discard value from flash)
|
||||
myNodeInfo.error_code = CriticalErrorCode_NONE; // For the error code, only show values from this boot (discard value from flash)
|
||||
myNodeInfo.error_address = 0;
|
||||
|
||||
// likewise - we always want the app requirements to come from the running appload
|
||||
@@ -272,7 +312,15 @@ void NodeDB::init()
|
||||
|
||||
resetRadioConfig(); // If bogus settings got saved, then fix them
|
||||
DEBUG_MSG("region=%d, NODENUM=0x%x, dbsize=%d\n", config.lora.region, myNodeInfo.my_node_num, *numNodes);
|
||||
saveToDisk();
|
||||
|
||||
if (devicestateCRC != crc32Buffer(&devicestate, sizeof(devicestate)))
|
||||
saveWhat |= SEGMENT_DEVICESTATE;
|
||||
if (configCRC != crc32Buffer(&config, sizeof(config)))
|
||||
saveWhat |= SEGMENT_CONFIG;
|
||||
if (channelFileCRC != crc32Buffer(&channelFile, sizeof(channelFile)))
|
||||
saveWhat |= SEGMENT_CHANNELS;
|
||||
|
||||
saveToDisk(saveWhat);
|
||||
}
|
||||
|
||||
// We reserve a few nodenums for future use
|
||||
@@ -347,19 +395,7 @@ void NodeDB::loadFromDisk()
|
||||
} else {
|
||||
if (devicestate.version < DEVICESTATE_MIN_VER) {
|
||||
DEBUG_MSG("Warn: devicestate %d is old, discarding\n", devicestate.version);
|
||||
installDefaultDeviceState();
|
||||
#ifdef ARCH_ESP32
|
||||
// This will erase what's in NVS including ssl keys, persistant variables and ble pairing
|
||||
nvs_flash_erase();
|
||||
#endif
|
||||
#ifdef ARCH_NRF52
|
||||
Bluefruit.begin();
|
||||
DEBUG_MSG("Clearing bluetooth bonds!\n");
|
||||
bond_print_list(BLE_GAP_ROLE_PERIPH);
|
||||
bond_print_list(BLE_GAP_ROLE_CENTRAL);
|
||||
Bluefruit.Periph.clearBonds();
|
||||
Bluefruit.Central.clearBonds();
|
||||
#endif
|
||||
factoryReset();
|
||||
} else {
|
||||
DEBUG_MSG("Loaded saved devicestate version %d\n", devicestate.version);
|
||||
}
|
||||
@@ -417,7 +453,6 @@ bool saveProto(const char *filename, size_t protoSize, size_t objSize, const pb_
|
||||
} else {
|
||||
okay = true;
|
||||
}
|
||||
|
||||
f.close();
|
||||
|
||||
// brief window of risk here ;-)
|
||||
@@ -440,7 +475,7 @@ void NodeDB::saveChannelsToDisk()
|
||||
#ifdef FSCom
|
||||
FSCom.mkdir("/prefs");
|
||||
#endif
|
||||
saveProto(channelFileName, ChannelFile_size, sizeof(ChannelFile), ChannelFile_fields, &channelFile);
|
||||
saveProto(channelFileName, ChannelFile_size, sizeof(channelFile), ChannelFile_fields, &channelFile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -454,34 +489,41 @@ void NodeDB::saveDeviceStateToDisk()
|
||||
}
|
||||
}
|
||||
|
||||
void NodeDB::saveToDisk()
|
||||
void NodeDB::saveToDisk(int saveWhat)
|
||||
{
|
||||
if (!devicestate.no_save) {
|
||||
#ifdef FSCom
|
||||
FSCom.mkdir("/prefs");
|
||||
#endif
|
||||
saveProto(prefFileName, DeviceState_size, sizeof(devicestate), DeviceState_fields, &devicestate);
|
||||
if (saveWhat & SEGMENT_DEVICESTATE) {
|
||||
saveDeviceStateToDisk();
|
||||
}
|
||||
|
||||
// save all config segments
|
||||
config.has_device = true;
|
||||
config.has_display = true;
|
||||
config.has_lora = true;
|
||||
config.has_position = true;
|
||||
config.has_power = true;
|
||||
config.has_wifi = true;
|
||||
config.has_bluetooth = true;
|
||||
saveProto(configFileName, LocalConfig_size, sizeof(LocalConfig), LocalConfig_fields, &config);
|
||||
if (saveWhat & SEGMENT_CONFIG) {
|
||||
config.has_device = true;
|
||||
config.has_display = true;
|
||||
config.has_lora = true;
|
||||
config.has_position = true;
|
||||
config.has_power = true;
|
||||
config.has_network = true;
|
||||
config.has_bluetooth = true;
|
||||
saveProto(configFileName, LocalConfig_size, sizeof(config), LocalConfig_fields, &config);
|
||||
}
|
||||
|
||||
moduleConfig.has_canned_message = true;
|
||||
moduleConfig.has_external_notification = true;
|
||||
moduleConfig.has_mqtt = true;
|
||||
moduleConfig.has_range_test = true;
|
||||
moduleConfig.has_serial = true;
|
||||
moduleConfig.has_store_forward = true;
|
||||
moduleConfig.has_telemetry = true;
|
||||
saveProto(moduleConfigFileName, LocalModuleConfig_size, sizeof(LocalModuleConfig), LocalModuleConfig_fields, &moduleConfig);
|
||||
if (saveWhat & SEGMENT_MODULECONFIG) {
|
||||
moduleConfig.has_canned_message = true;
|
||||
moduleConfig.has_external_notification = true;
|
||||
moduleConfig.has_mqtt = true;
|
||||
moduleConfig.has_range_test = true;
|
||||
moduleConfig.has_serial = true;
|
||||
moduleConfig.has_store_forward = true;
|
||||
moduleConfig.has_telemetry = true;
|
||||
saveProto(moduleConfigFileName, LocalModuleConfig_size, sizeof(moduleConfig), LocalModuleConfig_fields, &moduleConfig);
|
||||
}
|
||||
|
||||
saveChannelsToDisk();
|
||||
if (saveWhat & SEGMENT_CHANNELS) {
|
||||
saveChannelsToDisk();
|
||||
}
|
||||
} else {
|
||||
DEBUG_MSG("***** DEVELOPMENT MODE - DO NOT RELEASE - not saving to flash *****\n");
|
||||
}
|
||||
@@ -534,11 +576,11 @@ void NodeDB::updatePosition(uint32_t nodeId, const Position &p, RxSource src)
|
||||
|
||||
if (src == RX_SRC_LOCAL) {
|
||||
// Local packet, fully authoritative
|
||||
DEBUG_MSG("updatePosition LOCAL pos@%x, time=%u, latI=%d, lonI=%d, alt=%d\n", p.pos_timestamp, p.time, p.latitude_i,
|
||||
DEBUG_MSG("updatePosition LOCAL pos@%x, time=%u, latI=%d, lonI=%d, alt=%d\n", p.timestamp, p.time, p.latitude_i,
|
||||
p.longitude_i, p.altitude);
|
||||
info->position = p;
|
||||
|
||||
} else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.pos_timestamp && !p.location_source) {
|
||||
} else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.timestamp && !p.location_source) {
|
||||
// FIXME SPECIAL TIME SETTING PACKET FROM EUD TO RADIO
|
||||
// (stop-gap fix for issue #900)
|
||||
DEBUG_MSG("updatePosition SPECIAL time setting time=%u\n", p.time);
|
||||
@@ -623,7 +665,7 @@ void NodeDB::updateUser(uint32_t nodeId, const User &p)
|
||||
/// we updateGUI and updateGUIforNode if we think our this change is big enough for a redraw
|
||||
void NodeDB::updateFrom(const MeshPacket &mp)
|
||||
{
|
||||
if (mp.which_payloadVariant == MeshPacket_decoded_tag && mp.from) {
|
||||
if (mp.which_payload_variant == MeshPacket_decoded_tag && mp.from) {
|
||||
DEBUG_MSG("Update DB node 0x%x, rx_time=%u\n", mp.from, mp.rx_time);
|
||||
|
||||
NodeInfo *info = getOrCreateNode(getFrom(&mp));
|
||||
@@ -657,11 +699,23 @@ NodeInfo *NodeDB::getOrCreateNode(NodeNum n)
|
||||
|
||||
if (!info) {
|
||||
if (*numNodes >= MAX_NUM_NODES) {
|
||||
screen->print("error: node_db full!\n");
|
||||
DEBUG_MSG("ERROR! could not create new node, node_db is full! (%d nodes)", *numNodes);
|
||||
return NULL;
|
||||
screen->print("warning: node_db full! erasing oldest entry\n");
|
||||
// look for oldest node and erase it
|
||||
uint32_t oldest = UINT32_MAX;
|
||||
int oldestIndex = -1;
|
||||
for (int i = 0; i < *numNodes; i++) {
|
||||
if (nodes[i].last_heard < oldest) {
|
||||
oldest = nodes[i].last_heard;
|
||||
oldestIndex = i;
|
||||
}
|
||||
}
|
||||
// Shove the remaining nodes down the chain
|
||||
for (int i = oldestIndex; i < *numNodes - 1; i++) {
|
||||
nodes[i] = nodes[i + 1];
|
||||
}
|
||||
(*numNodes)--;
|
||||
}
|
||||
// add the node
|
||||
// add the node at the end
|
||||
info = &nodes[(*numNodes)++];
|
||||
|
||||
// everything is missing except the nodenum
|
||||
|
||||
@@ -13,7 +13,12 @@ DeviceState versions used to be defined in the .proto file but really only this
|
||||
#define here.
|
||||
*/
|
||||
|
||||
#define DEVICESTATE_CUR_VER 16
|
||||
#define SEGMENT_CONFIG 1
|
||||
#define SEGMENT_MODULECONFIG 2
|
||||
#define SEGMENT_DEVICESTATE 4
|
||||
#define SEGMENT_CHANNELS 8
|
||||
|
||||
#define DEVICESTATE_CUR_VER 19
|
||||
#define DEVICESTATE_MIN_VER DEVICESTATE_CUR_VER
|
||||
|
||||
extern DeviceState devicestate;
|
||||
@@ -52,7 +57,7 @@ class NodeDB
|
||||
void init();
|
||||
|
||||
/// write to flash
|
||||
void saveToDisk(), saveChannelsToDisk(), saveDeviceStateToDisk();
|
||||
void saveToDisk(int saveWhat=SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS), saveChannelsToDisk(), saveDeviceStateToDisk();
|
||||
|
||||
/** Reinit radio config if needed, because either:
|
||||
* a) sometimes a buggy android app might send us bogus settings or
|
||||
@@ -60,7 +65,7 @@ class NodeDB
|
||||
*
|
||||
* @return true if the config was completely reset, in that case, we should send it back to the client
|
||||
*/
|
||||
bool resetRadioConfig();
|
||||
bool resetRadioConfig(bool factory_reset = false);
|
||||
|
||||
/// given a subpacket sniffed from the network, update our DB state
|
||||
/// we updateGUI and updateGUIforNode if we think our this change is big enough for a redraw
|
||||
@@ -115,6 +120,10 @@ class NodeDB
|
||||
/// Return the number of nodes we've heard from recently (within the last 2 hrs?)
|
||||
size_t getNumOnlineNodes();
|
||||
|
||||
void initConfigIntervals(), initModuleConfigIntervals(), resetNodes();
|
||||
|
||||
bool factoryReset();
|
||||
|
||||
private:
|
||||
/// Find a node in our DB, create an empty NodeInfo if missing
|
||||
NodeInfo *getOrCreateNode(NodeNum n);
|
||||
@@ -127,7 +136,6 @@ class NodeDB
|
||||
newStatus.notifyObservers(&status);
|
||||
}
|
||||
|
||||
bool factoryReset();
|
||||
|
||||
/// read our db from flash
|
||||
void loadFromDisk();
|
||||
@@ -171,13 +179,17 @@ extern NodeDB nodeDB;
|
||||
// Our delay functions check for this for times that should never expire
|
||||
#define NODE_DELAY_FOREVER 0xffffffff
|
||||
|
||||
#define IF_ROUTER(routerVal, normalVal) ((config.device.role == Config_DeviceConfig_Role_Router) ? (routerVal) : (normalVal))
|
||||
#define IF_ROUTER(routerVal, normalVal) ((config.device.role == Config_DeviceConfig_Role_ROUTER) ? (routerVal) : (normalVal))
|
||||
|
||||
#define default_broadcast_interval_secs IF_ROUTER(12 * 60 * 60, 15 * 60)
|
||||
#define ONE_DAY 24 * 60 * 60
|
||||
|
||||
#define default_gps_attempt_time IF_ROUTER(5 * 60, 15 * 60)
|
||||
#define default_gps_update_interval IF_ROUTER(ONE_DAY, 2 * 60)
|
||||
#define default_broadcast_interval_secs IF_ROUTER(ONE_DAY / 2, 15 * 60)
|
||||
#define default_wait_bluetooth_secs IF_ROUTER(1, 60)
|
||||
#define default_mesh_sds_timeout_secs IF_ROUTER(NODE_DELAY_FOREVER, 2 * 60 * 60)
|
||||
#define default_sds_secs 365 * 24 * 60 * 60
|
||||
#define default_ls_secs IF_ROUTER(24 * 60 * 60, 5 * 60)
|
||||
#define default_sds_secs IF_ROUTER(ONE_DAY, UINT32_MAX) // Default to forever super deep sleep
|
||||
#define default_ls_secs IF_ROUTER(ONE_DAY, 5 * 60)
|
||||
#define default_min_wake_secs 10
|
||||
#define default_screen_on_secs 60 * 10
|
||||
|
||||
@@ -198,4 +210,4 @@ inline uint32_t getConfiguredOrDefaultMs(uint32_t configuredInterval, uint32_t d
|
||||
*/
|
||||
extern uint32_t radioGeneration;
|
||||
|
||||
#define Module_Config_size (ModuleConfig_CannedMessageConfig_size + ModuleConfig_ExternalNotificationConfig_size + ModuleConfig_MQTTConfig_size + ModuleConfig_RangeTestConfig_size + ModuleConfig_SerialConfig_size + ModuleConfig_StoreForwardConfig_size + ModuleConfig_TelemetryConfig_size + ModuleConfig_size)
|
||||
#define Module_Config_size (ModuleConfig_CannedMessageConfig_size + ModuleConfig_ExternalNotificationConfig_size + ModuleConfig_MQTTConfig_size + ModuleConfig_RangeTestConfig_size + ModuleConfig_SerialConfig_size + ModuleConfig_StoreForwardConfig_size + ModuleConfig_TelemetryConfig_size + ModuleConfig_size)
|
||||
|
||||
@@ -78,18 +78,18 @@ bool PhoneAPI::handleToRadio(const uint8_t *buf, size_t bufLength)
|
||||
|
||||
memset(&toRadioScratch, 0, sizeof(toRadioScratch));
|
||||
if (pb_decode_from_bytes(buf, bufLength, ToRadio_fields, &toRadioScratch)) {
|
||||
switch (toRadioScratch.which_payloadVariant) {
|
||||
case ToRadio_packet_tag:
|
||||
return handleToRadioPacket(toRadioScratch.packet);
|
||||
case ToRadio_want_config_id_tag:
|
||||
config_nonce = toRadioScratch.want_config_id;
|
||||
DEBUG_MSG("Client wants config, nonce=%u\n", config_nonce);
|
||||
handleStartConfig();
|
||||
break;
|
||||
case ToRadio_disconnect_tag:
|
||||
DEBUG_MSG("Disconnecting from phone\n");
|
||||
close();
|
||||
break;
|
||||
switch (toRadioScratch.which_payload_variant) {
|
||||
case ToRadio_packet_tag:
|
||||
return handleToRadioPacket(toRadioScratch.packet);
|
||||
case ToRadio_want_config_id_tag:
|
||||
config_nonce = toRadioScratch.want_config_id;
|
||||
DEBUG_MSG("Client wants config, nonce=%u\n", config_nonce);
|
||||
handleStartConfig();
|
||||
break;
|
||||
case ToRadio_disconnect_tag:
|
||||
DEBUG_MSG("Disconnecting from phone\n");
|
||||
close();
|
||||
break;
|
||||
default:
|
||||
// Ignore nop messages
|
||||
// DEBUG_MSG("Error: unexpected ToRadio variant\n");
|
||||
@@ -109,15 +109,17 @@ bool PhoneAPI::handleToRadio(const uint8_t *buf, size_t bufLength)
|
||||
*
|
||||
* Our sending states progress in the following sequence (the client app ASSUMES THIS SEQUENCE, DO NOT CHANGE IT):
|
||||
* STATE_SEND_MY_INFO, // send our my info record
|
||||
* STATE_SEND_CHANNELS
|
||||
* STATE_SEND_NODEINFO, // states progress in this order as the device sends to the client
|
||||
STATE_SEND_CONFIG,
|
||||
STATE_SEND_MODULE_CONFIG,
|
||||
STATE_SEND_COMPLETE_ID,
|
||||
STATE_SEND_PACKETS // send packets or debug strings
|
||||
*/
|
||||
size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
||||
{
|
||||
if (!available()) {
|
||||
DEBUG_MSG("getFromRadio=not available\n");
|
||||
// DEBUG_MSG("getFromRadio=not available\n");
|
||||
return 0;
|
||||
}
|
||||
// In case we send a FromRadio packet
|
||||
@@ -128,13 +130,13 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
||||
case STATE_SEND_NOTHING:
|
||||
DEBUG_MSG("getFromRadio=STATE_SEND_NOTHING\n");
|
||||
break;
|
||||
|
||||
|
||||
case STATE_SEND_MY_INFO:
|
||||
DEBUG_MSG("getFromRadio=STATE_SEND_MY_INFO\n");
|
||||
// If the user has specified they don't want our node to share its location, make sure to tell the phone
|
||||
// app not to send locations on our behalf.
|
||||
myNodeInfo.has_gps = gps && gps->isConnected(); // Update with latest GPS connect info
|
||||
fromRadioScratch.which_payloadVariant = FromRadio_my_info_tag;
|
||||
fromRadioScratch.which_payload_variant = FromRadio_my_info_tag;
|
||||
fromRadioScratch.my_info = myNodeInfo;
|
||||
state = STATE_SEND_NODEINFO;
|
||||
|
||||
@@ -149,56 +151,68 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
||||
if (info) {
|
||||
DEBUG_MSG("Sending nodeinfo: num=0x%x, lastseen=%u, id=%s, name=%s\n", info->num, info->last_heard, info->user.id,
|
||||
info->user.long_name);
|
||||
fromRadioScratch.which_payloadVariant = FromRadio_node_info_tag;
|
||||
fromRadioScratch.which_payload_variant = FromRadio_node_info_tag;
|
||||
fromRadioScratch.node_info = *info;
|
||||
// Stay in current state until done sending nodeinfos
|
||||
} else {
|
||||
DEBUG_MSG("Done sending nodeinfos\n");
|
||||
state = STATE_SEND_CONFIG;
|
||||
state = STATE_SEND_CHANNELS;
|
||||
// Go ahead and send that ID right now
|
||||
return getFromRadio(buf);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case STATE_SEND_CHANNELS:
|
||||
DEBUG_MSG("getFromRadio=STATE_SEND_CHANNELS\n");
|
||||
fromRadioScratch.which_payload_variant = FromRadio_channel_tag;
|
||||
fromRadioScratch.channel = channels.getByIndex(config_state);
|
||||
config_state++;
|
||||
// Advance when we have sent all of our Channels
|
||||
if (config_state >= MAX_NUM_CHANNELS) {
|
||||
state = STATE_SEND_CONFIG;
|
||||
config_state = Config_device_tag;
|
||||
}
|
||||
break;
|
||||
|
||||
case STATE_SEND_CONFIG:
|
||||
DEBUG_MSG("getFromRadio=STATE_SEND_CONFIG\n");
|
||||
fromRadioScratch.which_payloadVariant = FromRadio_config_tag;
|
||||
fromRadioScratch.which_payload_variant = FromRadio_config_tag;
|
||||
switch (config_state) {
|
||||
case Config_device_tag:
|
||||
fromRadioScratch.config.which_payloadVariant = Config_device_tag;
|
||||
fromRadioScratch.config.payloadVariant.device = config.device;
|
||||
break;
|
||||
case Config_position_tag:
|
||||
fromRadioScratch.config.which_payloadVariant = Config_position_tag;
|
||||
fromRadioScratch.config.payloadVariant.position = config.position;
|
||||
break;
|
||||
case Config_power_tag:
|
||||
fromRadioScratch.config.which_payloadVariant = Config_power_tag;
|
||||
fromRadioScratch.config.payloadVariant.power = config.power;
|
||||
fromRadioScratch.config.payloadVariant.power.ls_secs = default_ls_secs;
|
||||
break;
|
||||
case Config_wifi_tag:
|
||||
fromRadioScratch.config.which_payloadVariant = Config_wifi_tag;
|
||||
fromRadioScratch.config.payloadVariant.wifi = config.wifi;
|
||||
break;
|
||||
case Config_display_tag:
|
||||
fromRadioScratch.config.which_payloadVariant = Config_display_tag;
|
||||
fromRadioScratch.config.payloadVariant.display = config.display;
|
||||
break;
|
||||
case Config_lora_tag:
|
||||
fromRadioScratch.config.which_payloadVariant = Config_lora_tag;
|
||||
fromRadioScratch.config.payloadVariant.lora = config.lora;
|
||||
break;
|
||||
case Config_bluetooth_tag:
|
||||
fromRadioScratch.config.which_payloadVariant = Config_bluetooth_tag;
|
||||
fromRadioScratch.config.payloadVariant.bluetooth = config.bluetooth;
|
||||
break;
|
||||
case Config_device_tag:
|
||||
fromRadioScratch.config.which_payload_variant = Config_device_tag;
|
||||
fromRadioScratch.config.payload_variant.device = config.device;
|
||||
break;
|
||||
case Config_position_tag:
|
||||
fromRadioScratch.config.which_payload_variant = Config_position_tag;
|
||||
fromRadioScratch.config.payload_variant.position = config.position;
|
||||
break;
|
||||
case Config_power_tag:
|
||||
fromRadioScratch.config.which_payload_variant = Config_power_tag;
|
||||
fromRadioScratch.config.payload_variant.power = config.power;
|
||||
fromRadioScratch.config.payload_variant.power.ls_secs = default_ls_secs;
|
||||
break;
|
||||
case Config_network_tag:
|
||||
fromRadioScratch.config.which_payload_variant = Config_network_tag;
|
||||
fromRadioScratch.config.payload_variant.network = config.network;
|
||||
break;
|
||||
case Config_display_tag:
|
||||
fromRadioScratch.config.which_payload_variant = Config_display_tag;
|
||||
fromRadioScratch.config.payload_variant.display = config.display;
|
||||
break;
|
||||
case Config_lora_tag:
|
||||
fromRadioScratch.config.which_payload_variant = Config_lora_tag;
|
||||
fromRadioScratch.config.payload_variant.lora = config.lora;
|
||||
break;
|
||||
case Config_bluetooth_tag:
|
||||
fromRadioScratch.config.which_payload_variant = Config_bluetooth_tag;
|
||||
fromRadioScratch.config.payload_variant.bluetooth = config.bluetooth;
|
||||
break;
|
||||
}
|
||||
// NOTE: The phone app needs to know the ls_secs value so it can properly expect sleep behavior.
|
||||
// So even if we internally use 0 to represent 'use default' we still need to send the value we are
|
||||
// using to the app (so that even old phone apps work with new device loads).
|
||||
|
||||
|
||||
config_state++;
|
||||
// Advance when we have sent all of our config objects
|
||||
if (config_state > Config_bluetooth_tag) {
|
||||
@@ -209,45 +223,45 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
||||
|
||||
case STATE_SEND_MODULECONFIG:
|
||||
DEBUG_MSG("getFromRadio=STATE_SEND_MODULECONFIG\n");
|
||||
fromRadioScratch.which_payloadVariant = FromRadio_moduleConfig_tag;
|
||||
fromRadioScratch.which_payload_variant = FromRadio_moduleConfig_tag;
|
||||
switch (config_state) {
|
||||
case ModuleConfig_mqtt_tag:
|
||||
fromRadioScratch.moduleConfig.which_payloadVariant = ModuleConfig_mqtt_tag;
|
||||
fromRadioScratch.moduleConfig.payloadVariant.mqtt = moduleConfig.mqtt;
|
||||
break;
|
||||
case ModuleConfig_serial_tag:
|
||||
fromRadioScratch.moduleConfig.which_payloadVariant = ModuleConfig_serial_tag;
|
||||
fromRadioScratch.moduleConfig.payloadVariant.serial = moduleConfig.serial;
|
||||
break;
|
||||
case ModuleConfig_external_notification_tag:
|
||||
fromRadioScratch.moduleConfig.which_payloadVariant = ModuleConfig_external_notification_tag;
|
||||
fromRadioScratch.moduleConfig.payloadVariant.external_notification = moduleConfig.external_notification;
|
||||
break;
|
||||
case ModuleConfig_range_test_tag:
|
||||
fromRadioScratch.moduleConfig.which_payloadVariant = ModuleConfig_range_test_tag;
|
||||
fromRadioScratch.moduleConfig.payloadVariant.range_test = moduleConfig.range_test;
|
||||
break;
|
||||
case ModuleConfig_telemetry_tag:
|
||||
fromRadioScratch.moduleConfig.which_payloadVariant = ModuleConfig_telemetry_tag;
|
||||
fromRadioScratch.moduleConfig.payloadVariant.telemetry = moduleConfig.telemetry;
|
||||
break;
|
||||
case ModuleConfig_canned_message_tag:
|
||||
fromRadioScratch.moduleConfig.which_payloadVariant = ModuleConfig_canned_message_tag;
|
||||
fromRadioScratch.moduleConfig.payloadVariant.canned_message = moduleConfig.canned_message;
|
||||
break;
|
||||
case ModuleConfig_mqtt_tag:
|
||||
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_mqtt_tag;
|
||||
fromRadioScratch.moduleConfig.payload_variant.mqtt = moduleConfig.mqtt;
|
||||
break;
|
||||
case ModuleConfig_serial_tag:
|
||||
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_serial_tag;
|
||||
fromRadioScratch.moduleConfig.payload_variant.serial = moduleConfig.serial;
|
||||
break;
|
||||
case ModuleConfig_external_notification_tag:
|
||||
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_external_notification_tag;
|
||||
fromRadioScratch.moduleConfig.payload_variant.external_notification = moduleConfig.external_notification;
|
||||
break;
|
||||
case ModuleConfig_range_test_tag:
|
||||
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_range_test_tag;
|
||||
fromRadioScratch.moduleConfig.payload_variant.range_test = moduleConfig.range_test;
|
||||
break;
|
||||
case ModuleConfig_telemetry_tag:
|
||||
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_telemetry_tag;
|
||||
fromRadioScratch.moduleConfig.payload_variant.telemetry = moduleConfig.telemetry;
|
||||
break;
|
||||
case ModuleConfig_canned_message_tag:
|
||||
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_canned_message_tag;
|
||||
fromRadioScratch.moduleConfig.payload_variant.canned_message = moduleConfig.canned_message;
|
||||
break;
|
||||
}
|
||||
|
||||
config_state++;
|
||||
// Advance when we have sent all of our ModuleConfig objects
|
||||
if (config_state > ModuleConfig_canned_message_tag) {
|
||||
state = STATE_SEND_COMPLETE_ID;
|
||||
config_state = Config_device_tag;
|
||||
config_state = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case STATE_SEND_COMPLETE_ID:
|
||||
DEBUG_MSG("getFromRadio=STATE_SEND_COMPLETE_ID\n");
|
||||
fromRadioScratch.which_payloadVariant = FromRadio_config_complete_id_tag;
|
||||
fromRadioScratch.which_payload_variant = FromRadio_config_complete_id_tag;
|
||||
fromRadioScratch.config_complete_id = config_nonce;
|
||||
config_nonce = 0;
|
||||
state = STATE_SEND_PACKETS;
|
||||
@@ -260,7 +274,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
||||
printPacket("phone downloaded packet", packetForPhone);
|
||||
|
||||
// Encapsulate as a FromRadio packet
|
||||
fromRadioScratch.which_payloadVariant = FromRadio_packet_tag;
|
||||
fromRadioScratch.which_payload_variant = FromRadio_packet_tag;
|
||||
fromRadioScratch.packet = *packetForPhone;
|
||||
}
|
||||
releasePhonePacket();
|
||||
@@ -271,10 +285,11 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
||||
}
|
||||
|
||||
// Do we have a message from the mesh?
|
||||
if (fromRadioScratch.which_payloadVariant != 0) {
|
||||
if (fromRadioScratch.which_payload_variant != 0) {
|
||||
// Encapsulate as a FromRadio packet
|
||||
size_t numbytes = pb_encode_to_bytes(buf, FromRadio_size, FromRadio_fields, &fromRadioScratch);
|
||||
// DEBUG_MSG("encoding toPhone packet to phone variant=%d, %d bytes\n", fromRadioScratch.which_payloadVariant, numbytes);
|
||||
|
||||
DEBUG_MSG("encoding toPhone packet to phone variant=%d, %d bytes\n", fromRadioScratch.which_payload_variant, numbytes);
|
||||
return numbytes;
|
||||
}
|
||||
|
||||
@@ -282,7 +297,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PhoneAPI::handleDisconnect()
|
||||
void PhoneAPI::handleDisconnect()
|
||||
{
|
||||
DEBUG_MSG("PhoneAPI disconnect\n");
|
||||
}
|
||||
@@ -301,26 +316,25 @@ void PhoneAPI::releasePhonePacket()
|
||||
bool PhoneAPI::available()
|
||||
{
|
||||
switch (state) {
|
||||
case STATE_SEND_NOTHING:
|
||||
return false;
|
||||
case STATE_SEND_MY_INFO:
|
||||
return true;
|
||||
case STATE_SEND_CONFIG:
|
||||
return true;
|
||||
case STATE_SEND_MODULECONFIG:
|
||||
return true;
|
||||
case STATE_SEND_NODEINFO:
|
||||
if (!nodeInfoForPhone)
|
||||
nodeInfoForPhone = nodeDB.readNextInfo();
|
||||
return true; // Always say we have something, because we might need to advance our state machine
|
||||
case STATE_SEND_COMPLETE_ID:
|
||||
return true;
|
||||
case STATE_SEND_PACKETS: {
|
||||
if (!packetForPhone)
|
||||
packetForPhone = service.getForPhone();
|
||||
bool hasPacket = !!packetForPhone;
|
||||
DEBUG_MSG("available hasPacket=%d\n", hasPacket);
|
||||
return hasPacket;
|
||||
case STATE_SEND_NOTHING:
|
||||
return false;
|
||||
case STATE_SEND_MY_INFO:
|
||||
case STATE_SEND_CHANNELS:
|
||||
case STATE_SEND_CONFIG:
|
||||
case STATE_SEND_MODULECONFIG:
|
||||
case STATE_SEND_COMPLETE_ID:
|
||||
return true;
|
||||
case STATE_SEND_NODEINFO:
|
||||
if (!nodeInfoForPhone)
|
||||
nodeInfoForPhone = nodeDB.readNextInfo();
|
||||
return true; // Always say we have something, because we might need to advance our state machine
|
||||
|
||||
case STATE_SEND_PACKETS: {
|
||||
if (!packetForPhone)
|
||||
packetForPhone = service.getForPhone();
|
||||
bool hasPacket = !!packetForPhone;
|
||||
// DEBUG_MSG("available hasPacket=%d\n", hasPacket);
|
||||
return hasPacket;
|
||||
}
|
||||
default:
|
||||
assert(0); // unexpected state - FIXME, make an error code and reboot
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
* Eventually there should be once instance of this class for each live connection (because it has a bit of state
|
||||
* for that connection)
|
||||
*/
|
||||
class PhoneAPI
|
||||
: public Observer<uint32_t> // FIXME, we shouldn't be inheriting from Observer, instead use CallbackObserver as a member
|
||||
class PhoneAPI : public Observer<uint32_t> // FIXME, we shouldn't be inheriting from Observer, instead use CallbackObserver as a member
|
||||
{
|
||||
enum State {
|
||||
STATE_SEND_NOTHING, // Initial state, don't send anything until the client starts asking for config
|
||||
STATE_SEND_MY_INFO, // send our my info record
|
||||
STATE_SEND_NODEINFO, // states progress in this order as the device sends to to the client
|
||||
STATE_SEND_CHANNELS, // Send all channels
|
||||
STATE_SEND_CONFIG, // Replacement for the old Radioconfig
|
||||
STATE_SEND_MODULECONFIG, // Send Module specific config
|
||||
STATE_SEND_COMPLETE_ID,
|
||||
@@ -31,7 +31,7 @@ class PhoneAPI
|
||||
|
||||
State state = STATE_SEND_NOTHING;
|
||||
|
||||
int8_t config_state = Config_device_tag;
|
||||
uint8_t config_state = 0;
|
||||
|
||||
/**
|
||||
* Each packet sent to the phone has an incrementing count
|
||||
|
||||
@@ -75,7 +75,7 @@ template <class T> class ProtobufModule : protected SinglePortModule
|
||||
|
||||
T scratch;
|
||||
T *decoded = NULL;
|
||||
if (mp.which_payloadVariant == MeshPacket_decoded_tag && mp.decoded.portnum == ourPortNum) {
|
||||
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, fields, &scratch)) {
|
||||
decoded = &scratch;
|
||||
|
||||
@@ -104,15 +104,15 @@ bool RF95Interface::reconfigure()
|
||||
// configure publicly accessible settings
|
||||
int err = lora->setSpreadingFactor(sf);
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING);
|
||||
|
||||
err = lora->setBandwidth(bw);
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING);
|
||||
|
||||
err = lora->setCodingRate(cr);
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING);
|
||||
|
||||
err = lora->setSyncWord(syncWord);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
@@ -125,13 +125,13 @@ bool RF95Interface::reconfigure()
|
||||
|
||||
err = lora->setFrequency(getFreq());
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING);
|
||||
|
||||
if (power > MAX_POWER) // This chip has lower power limits than some
|
||||
power = MAX_POWER;
|
||||
err = lora->setOutputPower(power);
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING);
|
||||
|
||||
startReceive(); // restart receiving
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ const RegionInfo regions[] = {
|
||||
/*
|
||||
https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
|
||||
*/
|
||||
RDEF(EU433, 433.0f, 434.0f, 10, 0, 12, true, false),
|
||||
RDEF(EU_433, 433.0f, 434.0f, 10, 0, 12, true, false),
|
||||
|
||||
/*
|
||||
https://www.thethingsnetwork.org/docs/lorawan/duty-cycle/
|
||||
@@ -43,7 +43,7 @@ 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(EU868, 869.4f, 869.65f, 10, 0, 27, false, false),
|
||||
RDEF(EU_868, 869.4f, 869.65f, 10, 0, 27, false, false),
|
||||
|
||||
/*
|
||||
https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
|
||||
@@ -88,7 +88,7 @@ const RegionInfo regions[] = {
|
||||
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(NZ865, 864.0f, 868.0f, 100, 0, 0, true, false),
|
||||
RDEF(NZ_865, 864.0f, 868.0f, 100, 0, 0, true, false),
|
||||
|
||||
/*
|
||||
https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
|
||||
@@ -98,7 +98,7 @@ const RegionInfo regions[] = {
|
||||
/*
|
||||
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)
|
||||
|
||||
};
|
||||
|
||||
@@ -107,7 +107,7 @@ const RegionInfo *myRegion;
|
||||
void initRegion()
|
||||
{
|
||||
const RegionInfo *r = regions;
|
||||
for (; r->code != Config_LoRaConfig_RegionCode_Unset && r->code != config.lora.region; r++)
|
||||
for (; r->code != Config_LoRaConfig_RegionCode_UNSET && r->code != config.lora.region; r++)
|
||||
;
|
||||
myRegion = r;
|
||||
DEBUG_MSG("Wanted region %d, using %s\n", config.lora.region, r->name);
|
||||
@@ -157,7 +157,7 @@ uint32_t RadioInterface::getPacketTime(uint32_t pl)
|
||||
|
||||
uint32_t RadioInterface::getPacketTime(MeshPacket *p)
|
||||
{
|
||||
assert(p->which_payloadVariant == MeshPacket_encrypted_tag); // It should have already been encoded by now
|
||||
assert(p->which_payload_variant == MeshPacket_encrypted_tag); // It should have already been encoded by now
|
||||
uint32_t pl = p->encrypted.size + sizeof(PacketHeader);
|
||||
|
||||
return getPacketTime(pl);
|
||||
@@ -204,8 +204,8 @@ uint32_t RadioInterface::getTxDelayMsecWeighted(float snr)
|
||||
uint32_t delay = 0;
|
||||
uint8_t CWsize = map(snr, SNR_MIN, SNR_MAX, CWmin, CWmax);
|
||||
// DEBUG_MSG("rx_snr of %f so setting CWsize to:%d\n", snr, CWsize);
|
||||
if (config.device.role == Config_DeviceConfig_Role_Router ||
|
||||
config.device.role == Config_DeviceConfig_Role_RouterClient) {
|
||||
if (config.device.role == Config_DeviceConfig_Role_ROUTER ||
|
||||
config.device.role == Config_DeviceConfig_Role_ROUTER_CLIENT) {
|
||||
delay = random(0, 2*CWsize) * slotTimeMsec;
|
||||
DEBUG_MSG("rx_snr found in packet. As a router, setting tx delay:%d\n", delay);
|
||||
} else {
|
||||
@@ -220,7 +220,7 @@ void printPacket(const char *prefix, const MeshPacket *p)
|
||||
{
|
||||
DEBUG_MSG("%s (id=0x%08x Fr0x%02x To0x%02x, WantAck%d, HopLim%d Ch0x%x", prefix, p->id, p->from & 0xff, p->to & 0xff,
|
||||
p->want_ack, p->hop_limit, p->channel);
|
||||
if (p->which_payloadVariant == MeshPacket_decoded_tag) {
|
||||
if (p->which_payload_variant == MeshPacket_decoded_tag) {
|
||||
auto &s = p->decoded;
|
||||
|
||||
DEBUG_MSG(" Portnum=%d", s.portnum);
|
||||
@@ -354,40 +354,39 @@ void RadioInterface::applyModemConfig()
|
||||
// Set up default configuration
|
||||
// No Sync Words in LORA mode
|
||||
Config_LoRaConfig &loraConfig = config.lora;
|
||||
auto channelSettings = channels.getPrimary();
|
||||
if (loraConfig.spread_factor == 0) {
|
||||
switch (loraConfig.modem_preset) {
|
||||
case Config_LoRaConfig_ModemPreset_ShortFast:
|
||||
case Config_LoRaConfig_ModemPreset_SHORT_FAST:
|
||||
bw = 250;
|
||||
cr = 8;
|
||||
sf = 7;
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_ShortSlow:
|
||||
case Config_LoRaConfig_ModemPreset_SHORT_SLOW:
|
||||
bw = 250;
|
||||
cr = 8;
|
||||
sf = 8;
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_MedFast:
|
||||
case Config_LoRaConfig_ModemPreset_MEDIUM_FAST:
|
||||
bw = 250;
|
||||
cr = 8;
|
||||
sf = 9;
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_MedSlow:
|
||||
case Config_LoRaConfig_ModemPreset_MEDIUM_SLOW:
|
||||
bw = 250;
|
||||
cr = 8;
|
||||
sf = 10;
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_LongFast:
|
||||
case Config_LoRaConfig_ModemPreset_LONG_FAST:
|
||||
bw = 250;
|
||||
cr = 8;
|
||||
sf = 11;
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_LongSlow:
|
||||
case Config_LoRaConfig_ModemPreset_LONG_SLOW:
|
||||
bw = 125;
|
||||
cr = 8;
|
||||
sf = 12;
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_VLongSlow:
|
||||
case Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW:
|
||||
bw = 31.25;
|
||||
cr = 8;
|
||||
sf = 12;
|
||||
@@ -414,13 +413,16 @@ void RadioInterface::applyModemConfig()
|
||||
|
||||
if (power == 0)
|
||||
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;
|
||||
|
||||
// Calculate the number of channels
|
||||
uint32_t numChannels = floor((myRegion->freqEnd - myRegion->freqStart) / (myRegion->spacing + (bw / 1000)));
|
||||
|
||||
// If user has manually specified a channel num, then use that, otherwise generate one by hashing the name
|
||||
const char *channelName = channels.getName(channels.getPrimaryIndex());
|
||||
int channel_num = channelSettings.channel_num ? channelSettings.channel_num - 1 : hash(channelName) % numChannels;
|
||||
int channel_num = (loraConfig.channel_num ? loraConfig.channel_num - 1 : hash(channelName)) % numChannels;
|
||||
|
||||
// Old frequency selection formula
|
||||
// float freq = myRegion->freqStart + ((((myRegion->freqEnd - myRegion->freqStart) / numChannels) / 2) * channel_num);
|
||||
@@ -458,12 +460,6 @@ void RadioInterface::limitPower()
|
||||
DEBUG_MSG("Set radio: final power level=%d\n", power);
|
||||
}
|
||||
|
||||
ErrorCode SimRadio::send(MeshPacket *p)
|
||||
{
|
||||
DEBUG_MSG("SimRadio.send\n");
|
||||
packetPool.release(p);
|
||||
return ERRNO_OK;
|
||||
}
|
||||
|
||||
void RadioInterface::deliverToReceiver(MeshPacket *p)
|
||||
{
|
||||
@@ -479,7 +475,7 @@ size_t RadioInterface::beginSending(MeshPacket *p)
|
||||
assert(!sendingPacket);
|
||||
|
||||
// DEBUG_MSG("sending queued packet on mesh (txGood=%d,rxGood=%d,rxBad=%d)\n", rf95.txGood(), rf95.rxGood(), rf95.rxBad());
|
||||
assert(p->which_payloadVariant == MeshPacket_encrypted_tag); // It should have already been encoded by now
|
||||
assert(p->which_payload_variant == MeshPacket_encrypted_tag); // It should have already been encoded by now
|
||||
|
||||
lastTxStart = millis();
|
||||
|
||||
|
||||
@@ -212,11 +212,6 @@ class RadioInterface
|
||||
}
|
||||
};
|
||||
|
||||
class SimRadio : public RadioInterface
|
||||
{
|
||||
public:
|
||||
virtual ErrorCode send(MeshPacket *p) override;
|
||||
};
|
||||
|
||||
/// Debug printing for packets
|
||||
void printPacket(const char *prefix, const MeshPacket *p);
|
||||
|
||||
@@ -99,7 +99,7 @@ bool RadioLibInterface::canSendImmediately()
|
||||
// TX IRQ from the radio, the radio is probably broken.
|
||||
if (busyTx && (millis() - lastTxStart > 60000)) {
|
||||
DEBUG_MSG("Hardware Failure! busyTx for more than 60s\n");
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_TransmitFailed);
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_TRANSMIT_FAILED);
|
||||
#ifdef ARCH_ESP32
|
||||
if (busyTx && (millis() - lastTxStart > 65000)) // After 5s more, reboot
|
||||
ESP.restart();
|
||||
@@ -120,18 +120,18 @@ ErrorCode RadioLibInterface::send(MeshPacket *p)
|
||||
|
||||
#ifndef DISABLE_WELCOME_UNSET
|
||||
|
||||
if (config.lora.region != Config_LoRaConfig_RegionCode_Unset) {
|
||||
if (disabled || config.lora.tx_disabled) {
|
||||
if (config.lora.region != Config_LoRaConfig_RegionCode_UNSET) {
|
||||
if (disabled || !config.lora.tx_enabled) {
|
||||
|
||||
if (config.lora.region != Config_LoRaConfig_RegionCode_Unset) {
|
||||
if (disabled || config.lora.tx_disabled) {
|
||||
DEBUG_MSG("send - lora_tx_disabled\n");
|
||||
if (config.lora.region != Config_LoRaConfig_RegionCode_UNSET) {
|
||||
if (disabled || !config.lora.tx_enabled) {
|
||||
DEBUG_MSG("send - !config.lora.tx_enabled\n");
|
||||
packetPool.release(p);
|
||||
return ERRNO_DISABLED;
|
||||
}
|
||||
|
||||
} else {
|
||||
DEBUG_MSG("send - lora_tx_disabled because RegionCode_Unset\n");
|
||||
DEBUG_MSG("send - lora tx disable because RegionCode_Unset\n");
|
||||
packetPool.release(p);
|
||||
return ERRNO_DISABLED;
|
||||
}
|
||||
@@ -140,8 +140,8 @@ ErrorCode RadioLibInterface::send(MeshPacket *p)
|
||||
|
||||
#else
|
||||
|
||||
if (disabled || config.lora.tx_disabled) {
|
||||
DEBUG_MSG("send - lora_tx_disabled\n");
|
||||
if (disabled || !config.lora.tx_enabled) {
|
||||
DEBUG_MSG("send - !config.lora.tx_enabled\n");
|
||||
packetPool.release(p);
|
||||
return ERRNO_DISABLED;
|
||||
}
|
||||
@@ -362,7 +362,7 @@ ErrorCode RadioLibInterface::send(MeshPacket *p)
|
||||
|
||||
addReceiveMetadata(mp);
|
||||
|
||||
mp->which_payloadVariant = MeshPacket_encrypted_tag; // Mark that the payload is still encrypted at this point
|
||||
mp->which_payload_variant = MeshPacket_encrypted_tag; // Mark that the payload is still encrypted at this point
|
||||
assert(((uint32_t)payloadLen) <= sizeof(mp->encrypted.bytes));
|
||||
memcpy(mp->encrypted.bytes, payload, payloadLen);
|
||||
mp->encrypted.size = payloadLen;
|
||||
@@ -381,7 +381,7 @@ ErrorCode RadioLibInterface::send(MeshPacket *p)
|
||||
void RadioLibInterface::startSend(MeshPacket * txp)
|
||||
{
|
||||
printPacket("Starting low level send", txp);
|
||||
if (disabled || config.lora.tx_disabled) {
|
||||
if (disabled || !config.lora.tx_enabled) {
|
||||
DEBUG_MSG("startSend is dropping tx packet because we are disabled\n");
|
||||
packetPool.release(txp);
|
||||
} else {
|
||||
@@ -393,7 +393,7 @@ ErrorCode RadioLibInterface::send(MeshPacket *p)
|
||||
|
||||
int res = iface->startTransmit(radiobuf, numbytes);
|
||||
if (res != RADIOLIB_ERR_NONE) {
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_RadioSpiBug);
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_RADIO_SPI_BUG);
|
||||
|
||||
// This send failed, but make sure to 'complete' it properly
|
||||
completeSending();
|
||||
|
||||
@@ -17,11 +17,7 @@ ErrorCode ReliableRouter::send(MeshPacket *p)
|
||||
// message will rebroadcast. But asking for hop_limit 0 in that context means the client app has no preference on hop
|
||||
// counts and we want this message to get through the whole mesh, so use the default.
|
||||
if (p->hop_limit == 0) {
|
||||
if (config.lora.hop_limit && config.lora.hop_limit <= HOP_MAX) {
|
||||
p->hop_limit = (config.lora.hop_limit >= HOP_MAX) ? HOP_MAX : config.lora.hop_limit;
|
||||
} else {
|
||||
p->hop_limit = HOP_RELIABLE;
|
||||
}
|
||||
p->hop_limit = (config.lora.hop_limit >= HOP_MAX) ? HOP_MAX : config.lora.hop_limit;
|
||||
}
|
||||
|
||||
auto copy = packetPool.allocCopy(*p);
|
||||
@@ -62,12 +58,12 @@ bool ReliableRouter::shouldFilterReceived(MeshPacket *p)
|
||||
* this way if an ACK is dropped and a packet is resent we'll ACK the resent packet
|
||||
* make sure wasSeenRecently _doesn't_ update
|
||||
* finding the channel requires decoding the packet. */
|
||||
if (p->want_ack && (p->to == getNodeNum()) && wasSeenRecently(p, false)) {
|
||||
if (p->want_ack && (p->to == getNodeNum()) && wasSeenRecently(p, false) && !MeshModule::currentReply) {
|
||||
if (perhapsDecode(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) {
|
||||
} else if (wasSeenRecently(p, false) && p->hop_limit == HOP_RELIABLE && !MeshModule::currentReply) {
|
||||
// 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);
|
||||
@@ -98,7 +94,7 @@ void ReliableRouter::sniffReceived(const MeshPacket *p, const Routing *c)
|
||||
// - not DSR routing)
|
||||
if (p->want_ack) {
|
||||
if (MeshModule::currentReply)
|
||||
DEBUG_MSG("Someone else has replied to this message, no need for a 2nd ack\n");
|
||||
DEBUG_MSG("Some other module has replied to this message, no need for a 2nd ack\n");
|
||||
else
|
||||
sendAckNak(Routing_Error_NONE, getFrom(p), p->id, p->channel);
|
||||
}
|
||||
|
||||
@@ -115,14 +115,10 @@ MeshPacket *Router::allocForSending()
|
||||
{
|
||||
MeshPacket *p = packetPool.allocZeroed();
|
||||
|
||||
p->which_payloadVariant = MeshPacket_decoded_tag; // Assume payload is decoded at start.
|
||||
p->which_payload_variant = MeshPacket_decoded_tag; // Assume payload is decoded at start.
|
||||
p->from = nodeDB.getNodeNum();
|
||||
p->to = NODENUM_BROADCAST;
|
||||
if (config.lora.hop_limit && config.lora.hop_limit <= HOP_MAX) {
|
||||
p->hop_limit = (config.lora.hop_limit >= HOP_MAX) ? HOP_MAX : config.lora.hop_limit;
|
||||
} else {
|
||||
p->hop_limit = HOP_RELIABLE;
|
||||
}
|
||||
p->hop_limit = (config.lora.hop_limit >= HOP_MAX) ? HOP_MAX : config.lora.hop_limit;
|
||||
p->id = generatePacketId();
|
||||
p->rx_time =
|
||||
getValidTime(RTCQualityFromNet); // Just in case we process the packet locally - make sure it has a valid timestamp
|
||||
@@ -206,11 +202,11 @@ ErrorCode Router::send(MeshPacket *p)
|
||||
|
||||
// If the packet hasn't yet been encrypted, do so now (it might already be encrypted if we are just forwarding it)
|
||||
|
||||
assert(p->which_payloadVariant == MeshPacket_encrypted_tag ||
|
||||
p->which_payloadVariant == MeshPacket_decoded_tag); // I _think_ all packets should have a payload by now
|
||||
assert(p->which_payload_variant == MeshPacket_encrypted_tag ||
|
||||
p->which_payload_variant == MeshPacket_decoded_tag); // I _think_ all packets should have a payload by now
|
||||
|
||||
// If the packet is not yet encrypted, do so now
|
||||
if (p->which_payloadVariant == MeshPacket_decoded_tag) {
|
||||
if (p->which_payload_variant == MeshPacket_decoded_tag) {
|
||||
ChannelIndex chIndex = p->channel; // keep as a local because we are about to change it
|
||||
|
||||
#if HAS_WIFI
|
||||
@@ -277,7 +273,7 @@ bool perhapsDecode(MeshPacket *p)
|
||||
|
||||
// DEBUG_MSG("\n\n** perhapsDecode payloadVariant - %d\n\n", p->which_payloadVariant);
|
||||
|
||||
if (p->which_payloadVariant == MeshPacket_decoded_tag)
|
||||
if (p->which_payload_variant == MeshPacket_decoded_tag)
|
||||
return true; // If packet was already decoded just return
|
||||
|
||||
// assert(p->which_payloadVariant == MeshPacket_encrypted_tag);
|
||||
@@ -304,7 +300,7 @@ bool perhapsDecode(MeshPacket *p)
|
||||
DEBUG_MSG("Invalid portnum (bad psk?)!\n");
|
||||
} else {
|
||||
// parsing was successful
|
||||
p->which_payloadVariant = MeshPacket_decoded_tag; // change type to decoded
|
||||
p->which_payload_variant = MeshPacket_decoded_tag; // change type to decoded
|
||||
p->channel = chIndex; // change to store the index instead of the hash
|
||||
|
||||
/*
|
||||
@@ -349,7 +345,7 @@ bool perhapsDecode(MeshPacket *p)
|
||||
Routing_Error perhapsEncode(MeshPacket *p)
|
||||
{
|
||||
// If the packet is not yet encrypted, do so now
|
||||
if (p->which_payloadVariant == MeshPacket_decoded_tag) {
|
||||
if (p->which_payload_variant == MeshPacket_decoded_tag) {
|
||||
static uint8_t bytes[MAX_RHPACKETLEN]; // we have to use a scratch buffer because a union
|
||||
|
||||
size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), Data_fields, &p->decoded);
|
||||
@@ -407,7 +403,7 @@ Routing_Error perhapsEncode(MeshPacket *p)
|
||||
// Copy back into the packet and set the variant type
|
||||
memcpy(p->encrypted.bytes, bytes, numbytes);
|
||||
p->encrypted.size = numbytes;
|
||||
p->which_payloadVariant = MeshPacket_encrypted_tag;
|
||||
p->which_payload_variant = MeshPacket_encrypted_tag;
|
||||
}
|
||||
|
||||
return Routing_Error_NONE;
|
||||
|
||||
@@ -116,15 +116,15 @@ bool SX126xInterface<T>::reconfigure()
|
||||
// configure publicly accessible settings
|
||||
int err = lora.setSpreadingFactor(sf);
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING);
|
||||
|
||||
err = lora.setBandwidth(bw);
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING);
|
||||
|
||||
err = lora.setCodingRate(cr);
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
|
||||
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
|
||||
@@ -142,7 +142,7 @@ bool SX126xInterface<T>::reconfigure()
|
||||
|
||||
err = lora.setFrequency(getFreq());
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING);
|
||||
|
||||
if (power > 22) // This chip has lower power limits than some
|
||||
power = 22;
|
||||
|
||||
@@ -18,6 +18,9 @@ class SinglePortModule : public MeshModule
|
||||
SinglePortModule(const char *_name, PortNum _ourPortNum) : MeshModule(_name), ourPortNum(_ourPortNum) {}
|
||||
|
||||
protected:
|
||||
uint32_t max_channel_util_percent = 40;
|
||||
uint32_t polite_channel_util_percent = 25;
|
||||
|
||||
/**
|
||||
* @return true if you want to receive the specified portnum
|
||||
*/
|
||||
|
||||
@@ -103,10 +103,7 @@ void StreamAPI::emitTxBuffer(size_t len)
|
||||
|
||||
auto totalLen = len + HEADER_LEN;
|
||||
stream->write(txBuf, totalLen);
|
||||
/* for(size_t i = 0; i < totalLen; i++) {
|
||||
stream->write(txBuf[i]);
|
||||
// stream->flush();
|
||||
} */
|
||||
stream->flush();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,7 +111,7 @@ void StreamAPI::emitRebooted()
|
||||
{
|
||||
// In case we send a FromRadio packet
|
||||
memset(&fromRadioScratch, 0, sizeof(fromRadioScratch));
|
||||
fromRadioScratch.which_payloadVariant = FromRadio_rebooted_tag;
|
||||
fromRadioScratch.which_payload_variant = FromRadio_rebooted_tag;
|
||||
fromRadioScratch.rebooted = true;
|
||||
|
||||
// DEBUG_MSG("Emitting reboot packet for serial shell\n");
|
||||
@@ -133,4 +130,4 @@ void StreamAPI::onConnectionChanged(bool connected)
|
||||
// received a packet in a while
|
||||
powerFSM.trigger(EVENT_SERIAL_DISCONNECTED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
#endif
|
||||
|
||||
PB_BIND(AdminMessage, AdminMessage, AUTO)
|
||||
PB_BIND(AdminMessage, AdminMessage, 2)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ typedef enum _AdminMessage_ConfigType {
|
||||
AdminMessage_ConfigType_DEVICE_CONFIG = 0,
|
||||
AdminMessage_ConfigType_POSITION_CONFIG = 1,
|
||||
AdminMessage_ConfigType_POWER_CONFIG = 2,
|
||||
AdminMessage_ConfigType_WIFI_CONFIG = 3,
|
||||
AdminMessage_ConfigType_NETWORK_CONFIG = 3,
|
||||
AdminMessage_ConfigType_DISPLAY_CONFIG = 4,
|
||||
AdminMessage_ConfigType_LORA_CONFIG = 5,
|
||||
AdminMessage_ConfigType_BLUETOOTH_CONFIG = 6
|
||||
@@ -40,16 +40,8 @@ typedef enum _AdminMessage_ModuleConfigType {
|
||||
This message is used to do settings operations to both remote AND local nodes.
|
||||
(Prior to 1.2 these operations were done via special ToRadio operations) */
|
||||
typedef struct _AdminMessage {
|
||||
pb_size_t which_variant;
|
||||
pb_size_t which_payload_variant;
|
||||
union {
|
||||
/* Set the owner for this node */
|
||||
User set_owner;
|
||||
/* Set channels (using the new API).
|
||||
A special channel is the "primary channel".
|
||||
The other records are secondary channels.
|
||||
Note: only one channel can be marked as primary.
|
||||
If the client sets a particular channel to be primary, the previous channel will be set to SECONDARY automatically. */
|
||||
Channel set_channel;
|
||||
/* Send the specified channel in the response to this message
|
||||
NOTE: This field is sent with the channel index + 1 (to ensure we never try to send 'zero' - which protobufs treats as not present) */
|
||||
uint32_t get_channel_request;
|
||||
@@ -63,20 +55,36 @@ typedef struct _AdminMessage {
|
||||
AdminMessage_ConfigType get_config_request;
|
||||
/* Send the current Config in the response to this message. */
|
||||
Config get_config_response;
|
||||
/* Set the current Config */
|
||||
Config set_config;
|
||||
/* Sent immediatly after a config change has been sent to ensure comms, if this is not recieved, the config will be reverted after 10 mins */
|
||||
bool confirm_set_config;
|
||||
/* Ask for the following config data to be sent */
|
||||
AdminMessage_ModuleConfigType get_module_config_request;
|
||||
/* Send the current Config in the response to this message. */
|
||||
ModuleConfig get_module_config_response;
|
||||
/* Get the Canned Message Module messages in the response to this message. */
|
||||
bool get_canned_message_module_messages_request;
|
||||
/* Get the Canned Message Module messages in the response to this message. */
|
||||
char get_canned_message_module_messages_response[201];
|
||||
/* Request the node to send device metadata (firmware, protobuf version, etc) */
|
||||
bool get_device_metadata_request;
|
||||
/* Device metadata response */
|
||||
DeviceMetadata get_device_metadata_response;
|
||||
/* Set the owner for this node */
|
||||
User set_owner;
|
||||
/* Set channels (using the new API).
|
||||
A special channel is the "primary channel".
|
||||
The other records are secondary channels.
|
||||
Note: only one channel can be marked as primary.
|
||||
If the client sets a particular channel to be primary, the previous channel will be set to SECONDARY automatically. */
|
||||
Channel set_channel;
|
||||
/* Set the current Config */
|
||||
Config set_config;
|
||||
/* Set the current Config */
|
||||
ModuleConfig set_module_config;
|
||||
/* Set the Canned Message Module messages text. */
|
||||
char set_canned_message_module_messages[201];
|
||||
/* Sent immediatly after a config change has been sent to ensure comms, if this is not recieved, the config will be reverted after 10 mins */
|
||||
bool confirm_set_config;
|
||||
/* Sent immediatly after a config change has been sent to ensure comms, if this is not recieved, the config will be reverted after 10 mins */
|
||||
bool confirm_set_module_config;
|
||||
/* Send all channels in the response to this message */
|
||||
bool get_all_channel_request;
|
||||
/* Setting channels/radio config remotely carries the risk that you might send an invalid config and the radio never talks to your mesh again.
|
||||
Therefore if setting either of these properties remotely, you must send a confirm_xxx message within 10 minutes.
|
||||
If you fail to do so, the radio will assume loss of comms and revert your changes.
|
||||
@@ -84,23 +92,20 @@ typedef struct _AdminMessage {
|
||||
bool confirm_set_channel;
|
||||
/* TODO: REPLACE */
|
||||
bool confirm_set_radio;
|
||||
/* Tell the node to reboot into the OTA Firmware in this many seconds (or <0 to cancel reboot)
|
||||
Only Implemented for ESP32 Devices. This needs to be issued to send a new main firmware via bluetooth. */
|
||||
int32_t reboot_ota_seconds;
|
||||
/* This message is only supported for the simulator porduino build.
|
||||
If received the simulator will exit successfully. */
|
||||
bool exit_simulator;
|
||||
/* Tell the node to reboot in this many seconds (or <0 to cancel reboot) */
|
||||
int32_t reboot_seconds;
|
||||
/* Get the Canned Message Module messages in the response to this message. */
|
||||
bool get_canned_message_module_messages_request;
|
||||
/* Get the Canned Message Module messages in the response to this message. */
|
||||
char get_canned_message_module_messages_response[201];
|
||||
/* Set the Canned Message Module messages text. */
|
||||
char set_canned_message_module_messages[201];
|
||||
/* Tell the node to shutdown in this many seconds (or <0 to cancel shutdown) */
|
||||
int32_t shutdown_seconds;
|
||||
/* Request the node to send device metadata (firmware, protobuf version, etc) */
|
||||
uint32_t get_device_metadata_request;
|
||||
/* Device metadata response */
|
||||
DeviceMetadata get_device_metadata_response;
|
||||
/* Tell the node to factory reset, all device settings will be returned to factory defaults. */
|
||||
int32_t factory_reset;
|
||||
/* Tell the node to reset the nodedb. */
|
||||
int32_t nodedb_reset;
|
||||
};
|
||||
} AdminMessage;
|
||||
|
||||
@@ -120,74 +125,78 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define AdminMessage_init_default {0, {User_init_default}}
|
||||
#define AdminMessage_init_zero {0, {User_init_zero}}
|
||||
#define AdminMessage_init_default {0, {0}}
|
||||
#define AdminMessage_init_zero {0, {0}}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define AdminMessage_set_owner_tag 2
|
||||
#define AdminMessage_set_channel_tag 3
|
||||
#define AdminMessage_get_channel_request_tag 6
|
||||
#define AdminMessage_get_channel_response_tag 7
|
||||
#define AdminMessage_get_owner_request_tag 8
|
||||
#define AdminMessage_get_owner_response_tag 9
|
||||
#define AdminMessage_get_config_request_tag 10
|
||||
#define AdminMessage_get_config_response_tag 11
|
||||
#define AdminMessage_set_config_tag 12
|
||||
#define AdminMessage_confirm_set_config_tag 13
|
||||
#define AdminMessage_get_module_config_request_tag 14
|
||||
#define AdminMessage_get_module_config_response_tag 15
|
||||
#define AdminMessage_set_module_config_tag 16
|
||||
#define AdminMessage_confirm_set_module_config_tag 17
|
||||
#define AdminMessage_get_all_channel_request_tag 18
|
||||
#define AdminMessage_confirm_set_channel_tag 32
|
||||
#define AdminMessage_confirm_set_radio_tag 33
|
||||
#define AdminMessage_exit_simulator_tag 34
|
||||
#define AdminMessage_reboot_seconds_tag 35
|
||||
#define AdminMessage_get_canned_message_module_messages_request_tag 36
|
||||
#define AdminMessage_get_canned_message_module_messages_response_tag 37
|
||||
#define AdminMessage_set_canned_message_module_messages_tag 44
|
||||
#define AdminMessage_shutdown_seconds_tag 51
|
||||
#define AdminMessage_get_device_metadata_request_tag 52
|
||||
#define AdminMessage_get_device_metadata_response_tag 53
|
||||
#define AdminMessage_get_channel_request_tag 1
|
||||
#define AdminMessage_get_channel_response_tag 2
|
||||
#define AdminMessage_get_owner_request_tag 3
|
||||
#define AdminMessage_get_owner_response_tag 4
|
||||
#define AdminMessage_get_config_request_tag 5
|
||||
#define AdminMessage_get_config_response_tag 6
|
||||
#define AdminMessage_get_module_config_request_tag 7
|
||||
#define AdminMessage_get_module_config_response_tag 8
|
||||
#define AdminMessage_get_canned_message_module_messages_request_tag 10
|
||||
#define AdminMessage_get_canned_message_module_messages_response_tag 11
|
||||
#define AdminMessage_get_device_metadata_request_tag 12
|
||||
#define AdminMessage_get_device_metadata_response_tag 13
|
||||
#define AdminMessage_set_owner_tag 32
|
||||
#define AdminMessage_set_channel_tag 33
|
||||
#define AdminMessage_set_config_tag 34
|
||||
#define AdminMessage_set_module_config_tag 35
|
||||
#define AdminMessage_set_canned_message_module_messages_tag 36
|
||||
#define AdminMessage_confirm_set_config_tag 64
|
||||
#define AdminMessage_confirm_set_module_config_tag 65
|
||||
#define AdminMessage_confirm_set_channel_tag 66
|
||||
#define AdminMessage_confirm_set_radio_tag 67
|
||||
#define AdminMessage_reboot_ota_seconds_tag 95
|
||||
#define AdminMessage_exit_simulator_tag 96
|
||||
#define AdminMessage_reboot_seconds_tag 97
|
||||
#define AdminMessage_shutdown_seconds_tag 98
|
||||
#define AdminMessage_factory_reset_tag 99
|
||||
#define AdminMessage_nodedb_reset_tag 100
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
#define AdminMessage_FIELDLIST(X, a) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (variant,set_owner,set_owner), 2) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (variant,set_channel,set_channel), 3) \
|
||||
X(a, STATIC, ONEOF, UINT32, (variant,get_channel_request,get_channel_request), 6) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (variant,get_channel_response,get_channel_response), 7) \
|
||||
X(a, STATIC, ONEOF, BOOL, (variant,get_owner_request,get_owner_request), 8) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (variant,get_owner_response,get_owner_response), 9) \
|
||||
X(a, STATIC, ONEOF, UENUM, (variant,get_config_request,get_config_request), 10) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (variant,get_config_response,get_config_response), 11) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (variant,set_config,set_config), 12) \
|
||||
X(a, STATIC, ONEOF, BOOL, (variant,confirm_set_config,confirm_set_config), 13) \
|
||||
X(a, STATIC, ONEOF, UENUM, (variant,get_module_config_request,get_module_config_request), 14) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (variant,get_module_config_response,get_module_config_response), 15) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (variant,set_module_config,set_module_config), 16) \
|
||||
X(a, STATIC, ONEOF, BOOL, (variant,confirm_set_module_config,confirm_set_module_config), 17) \
|
||||
X(a, STATIC, ONEOF, BOOL, (variant,get_all_channel_request,get_all_channel_request), 18) \
|
||||
X(a, STATIC, ONEOF, BOOL, (variant,confirm_set_channel,confirm_set_channel), 32) \
|
||||
X(a, STATIC, ONEOF, BOOL, (variant,confirm_set_radio,confirm_set_radio), 33) \
|
||||
X(a, STATIC, ONEOF, BOOL, (variant,exit_simulator,exit_simulator), 34) \
|
||||
X(a, STATIC, ONEOF, INT32, (variant,reboot_seconds,reboot_seconds), 35) \
|
||||
X(a, STATIC, ONEOF, BOOL, (variant,get_canned_message_module_messages_request,get_canned_message_module_messages_request), 36) \
|
||||
X(a, STATIC, ONEOF, STRING, (variant,get_canned_message_module_messages_response,get_canned_message_module_messages_response), 37) \
|
||||
X(a, STATIC, ONEOF, STRING, (variant,set_canned_message_module_messages,set_canned_message_module_messages), 44) \
|
||||
X(a, STATIC, ONEOF, INT32, (variant,shutdown_seconds,shutdown_seconds), 51) \
|
||||
X(a, STATIC, ONEOF, UINT32, (variant,get_device_metadata_request,get_device_metadata_request), 52) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (variant,get_device_metadata_response,get_device_metadata_response), 53)
|
||||
X(a, STATIC, ONEOF, UINT32, (payload_variant,get_channel_request,get_channel_request), 1) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,get_channel_response,get_channel_response), 2) \
|
||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,get_owner_request,get_owner_request), 3) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,get_owner_response,get_owner_response), 4) \
|
||||
X(a, STATIC, ONEOF, UENUM, (payload_variant,get_config_request,get_config_request), 5) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,get_config_response,get_config_response), 6) \
|
||||
X(a, STATIC, ONEOF, UENUM, (payload_variant,get_module_config_request,get_module_config_request), 7) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,get_module_config_response,get_module_config_response), 8) \
|
||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,get_canned_message_module_messages_request,get_canned_message_module_messages_request), 10) \
|
||||
X(a, STATIC, ONEOF, STRING, (payload_variant,get_canned_message_module_messages_response,get_canned_message_module_messages_response), 11) \
|
||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,get_device_metadata_request,get_device_metadata_request), 12) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,get_device_metadata_response,get_device_metadata_response), 13) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_owner,set_owner), 32) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_channel,set_channel), 33) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_config,set_config), 34) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_module_config,set_module_config), 35) \
|
||||
X(a, STATIC, ONEOF, STRING, (payload_variant,set_canned_message_module_messages,set_canned_message_module_messages), 36) \
|
||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,confirm_set_config,confirm_set_config), 64) \
|
||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,confirm_set_module_config,confirm_set_module_config), 65) \
|
||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,confirm_set_channel,confirm_set_channel), 66) \
|
||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,confirm_set_radio,confirm_set_radio), 67) \
|
||||
X(a, STATIC, ONEOF, INT32, (payload_variant,reboot_ota_seconds,reboot_ota_seconds), 95) \
|
||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,exit_simulator,exit_simulator), 96) \
|
||||
X(a, STATIC, ONEOF, INT32, (payload_variant,reboot_seconds,reboot_seconds), 97) \
|
||||
X(a, STATIC, ONEOF, INT32, (payload_variant,shutdown_seconds,shutdown_seconds), 98) \
|
||||
X(a, STATIC, ONEOF, INT32, (payload_variant,factory_reset,factory_reset), 99) \
|
||||
X(a, STATIC, ONEOF, INT32, (payload_variant,nodedb_reset,nodedb_reset), 100)
|
||||
#define AdminMessage_CALLBACK NULL
|
||||
#define AdminMessage_DEFAULT NULL
|
||||
#define AdminMessage_variant_set_owner_MSGTYPE User
|
||||
#define AdminMessage_variant_set_channel_MSGTYPE Channel
|
||||
#define AdminMessage_variant_get_channel_response_MSGTYPE Channel
|
||||
#define AdminMessage_variant_get_owner_response_MSGTYPE User
|
||||
#define AdminMessage_variant_get_config_response_MSGTYPE Config
|
||||
#define AdminMessage_variant_set_config_MSGTYPE Config
|
||||
#define AdminMessage_variant_get_module_config_response_MSGTYPE ModuleConfig
|
||||
#define AdminMessage_variant_set_module_config_MSGTYPE ModuleConfig
|
||||
#define AdminMessage_variant_get_device_metadata_response_MSGTYPE DeviceMetadata
|
||||
#define AdminMessage_payload_variant_get_channel_response_MSGTYPE Channel
|
||||
#define AdminMessage_payload_variant_get_owner_response_MSGTYPE User
|
||||
#define AdminMessage_payload_variant_get_config_response_MSGTYPE Config
|
||||
#define AdminMessage_payload_variant_get_module_config_response_MSGTYPE ModuleConfig
|
||||
#define AdminMessage_payload_variant_get_device_metadata_response_MSGTYPE DeviceMetadata
|
||||
#define AdminMessage_payload_variant_set_owner_MSGTYPE User
|
||||
#define AdminMessage_payload_variant_set_channel_MSGTYPE Channel
|
||||
#define AdminMessage_payload_variant_set_config_MSGTYPE Config
|
||||
#define AdminMessage_payload_variant_set_module_config_MSGTYPE ModuleConfig
|
||||
|
||||
extern const pb_msgdesc_t AdminMessage_msg;
|
||||
|
||||
|
||||
@@ -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 573
|
||||
#define ChannelSet_size 581
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
||||
@@ -38,6 +38,8 @@ typedef PB_BYTES_ARRAY_T(32) ChannelSettings_psk_t;
|
||||
FIXME: explain how apps use channels for security.
|
||||
explain how remote settings and remote gpio are managed as an example */
|
||||
typedef struct _ChannelSettings {
|
||||
/* Deprecated in favor of LoraConfig.channel_num */
|
||||
uint32_t channel_num;
|
||||
/* A simple pre-shared key for now for crypto.
|
||||
Must be either 0 bytes (no crypto), 16 bytes (AES128), or 32 bytes (AES256).
|
||||
A special shorthand is used for 1 byte long psks.
|
||||
@@ -58,25 +60,6 @@ typedef struct _ChannelSettings {
|
||||
For channel_num hashing empty string will be treated as "X".
|
||||
Where "X" is selected based on the English words listed above for ModemPreset */
|
||||
char name[12];
|
||||
/* NOTE: this field is _independent_ and unrelated to the concepts in channel.proto.
|
||||
this is controlling the actual hardware frequency the radio is transmitting on.
|
||||
In a perfect world we would have called it something else (band?) but I forgot to make this change during the big 1.2 renaming.
|
||||
Most users should never need to be exposed to this field/concept.
|
||||
A channel number between 1 and 13 (or whatever the max is in the current
|
||||
region). If ZERO then the rule is "use the old channel name hash based
|
||||
algorithm to derive the channel number")
|
||||
If using the hash algorithm the channel number will be: hash(channel_name) %
|
||||
NUM_CHANNELS (Where num channels depends on the regulatory region).
|
||||
NUM_CHANNELS_US is 13, for other values see MeshRadio.h in the device code.
|
||||
hash a string into an integer - djb2 by Dan Bernstein. -
|
||||
http://www.cse.yorku.ca/~oz/hash.html
|
||||
unsigned long hash(char *str) {
|
||||
unsigned long hash = 5381; int c;
|
||||
while ((c = *str++) != 0)
|
||||
hash = ((hash << 5) + hash) + (unsigned char) c;
|
||||
return hash;
|
||||
} */
|
||||
uint8_t channel_num;
|
||||
/* Used to construct a globally unique channel ID.
|
||||
The full globally unique ID will be: "name.id" where ID is shown as base36.
|
||||
Assuming that the number of meshtastic users is below 20K (true for a long time)
|
||||
@@ -120,30 +103,30 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define ChannelSettings_init_default {{0, {0}}, "", 0, 0, 0, 0}
|
||||
#define ChannelSettings_init_default {0, {0, {0}}, "", 0, 0, 0}
|
||||
#define Channel_init_default {0, false, ChannelSettings_init_default, _Channel_Role_MIN}
|
||||
#define ChannelSettings_init_zero {{0, {0}}, "", 0, 0, 0, 0}
|
||||
#define ChannelSettings_init_zero {0, {0, {0}}, "", 0, 0, 0}
|
||||
#define Channel_init_zero {0, false, ChannelSettings_init_zero, _Channel_Role_MIN}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define ChannelSettings_psk_tag 4
|
||||
#define ChannelSettings_name_tag 5
|
||||
#define ChannelSettings_channel_num_tag 9
|
||||
#define ChannelSettings_id_tag 10
|
||||
#define ChannelSettings_uplink_enabled_tag 16
|
||||
#define ChannelSettings_downlink_enabled_tag 17
|
||||
#define ChannelSettings_channel_num_tag 1
|
||||
#define ChannelSettings_psk_tag 2
|
||||
#define ChannelSettings_name_tag 3
|
||||
#define ChannelSettings_id_tag 4
|
||||
#define ChannelSettings_uplink_enabled_tag 5
|
||||
#define ChannelSettings_downlink_enabled_tag 6
|
||||
#define Channel_index_tag 1
|
||||
#define Channel_settings_tag 2
|
||||
#define Channel_role_tag 3
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
#define ChannelSettings_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, BYTES, psk, 4) \
|
||||
X(a, STATIC, SINGULAR, STRING, name, 5) \
|
||||
X(a, STATIC, SINGULAR, UINT32, channel_num, 9) \
|
||||
X(a, STATIC, SINGULAR, FIXED32, id, 10) \
|
||||
X(a, STATIC, SINGULAR, BOOL, uplink_enabled, 16) \
|
||||
X(a, STATIC, SINGULAR, BOOL, downlink_enabled, 17)
|
||||
X(a, STATIC, SINGULAR, UINT32, channel_num, 1) \
|
||||
X(a, STATIC, SINGULAR, BYTES, psk, 2) \
|
||||
X(a, STATIC, SINGULAR, STRING, name, 3) \
|
||||
X(a, STATIC, SINGULAR, FIXED32, id, 4) \
|
||||
X(a, STATIC, SINGULAR, BOOL, uplink_enabled, 5) \
|
||||
X(a, STATIC, SINGULAR, BOOL, downlink_enabled, 6)
|
||||
#define ChannelSettings_CALLBACK NULL
|
||||
#define ChannelSettings_DEFAULT NULL
|
||||
|
||||
@@ -163,8 +146,8 @@ extern const pb_msgdesc_t Channel_msg;
|
||||
#define Channel_fields &Channel_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define ChannelSettings_size 61
|
||||
#define Channel_size 76
|
||||
#define ChannelSettings_size 62
|
||||
#define Channel_size 77
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
||||
@@ -18,7 +18,7 @@ PB_BIND(Config_PositionConfig, Config_PositionConfig, AUTO)
|
||||
PB_BIND(Config_PowerConfig, Config_PowerConfig, AUTO)
|
||||
|
||||
|
||||
PB_BIND(Config_WiFiConfig, Config_WiFiConfig, AUTO)
|
||||
PB_BIND(Config_NetworkConfig, Config_NetworkConfig, AUTO)
|
||||
|
||||
|
||||
PB_BIND(Config_DisplayConfig, Config_DisplayConfig, AUTO)
|
||||
|
||||
@@ -11,66 +11,51 @@
|
||||
|
||||
/* Enum definitions */
|
||||
typedef enum _Config_DeviceConfig_Role {
|
||||
Config_DeviceConfig_Role_Client = 0,
|
||||
Config_DeviceConfig_Role_ClientMute = 1,
|
||||
Config_DeviceConfig_Role_Router = 2,
|
||||
Config_DeviceConfig_Role_RouterClient = 3
|
||||
Config_DeviceConfig_Role_CLIENT = 0,
|
||||
Config_DeviceConfig_Role_CLIENT_MUTE = 1,
|
||||
Config_DeviceConfig_Role_ROUTER = 2,
|
||||
Config_DeviceConfig_Role_ROUTER_CLIENT = 3
|
||||
} Config_DeviceConfig_Role;
|
||||
|
||||
typedef enum _Config_PositionConfig_PositionFlags {
|
||||
Config_PositionConfig_PositionFlags_POS_UNDEFINED = 0,
|
||||
Config_PositionConfig_PositionFlags_POS_ALTITUDE = 1,
|
||||
Config_PositionConfig_PositionFlags_POS_ALT_MSL = 2,
|
||||
Config_PositionConfig_PositionFlags_POS_GEO_SEP = 4,
|
||||
Config_PositionConfig_PositionFlags_POS_DOP = 8,
|
||||
Config_PositionConfig_PositionFlags_POS_HVDOP = 16,
|
||||
Config_PositionConfig_PositionFlags_POS_SATINVIEW = 32,
|
||||
Config_PositionConfig_PositionFlags_POS_SEQ_NOS = 64,
|
||||
Config_PositionConfig_PositionFlags_POS_TIMESTAMP = 128,
|
||||
Config_PositionConfig_PositionFlags_POS_HEADING = 256,
|
||||
Config_PositionConfig_PositionFlags_POS_SPEED = 512
|
||||
Config_PositionConfig_PositionFlags_UNSET = 0,
|
||||
Config_PositionConfig_PositionFlags_ALTITUDE = 1,
|
||||
Config_PositionConfig_PositionFlags_ALTITUDE_MSL = 2,
|
||||
Config_PositionConfig_PositionFlags_GEOIDAL_SEPARATION = 4,
|
||||
Config_PositionConfig_PositionFlags_DOP = 8,
|
||||
Config_PositionConfig_PositionFlags_HVDOP = 16,
|
||||
Config_PositionConfig_PositionFlags_SATINVIEW = 32,
|
||||
Config_PositionConfig_PositionFlags_SEQ_NO = 64,
|
||||
Config_PositionConfig_PositionFlags_TIMESTAMP = 128,
|
||||
Config_PositionConfig_PositionFlags_HEADING = 256,
|
||||
Config_PositionConfig_PositionFlags_SPEED = 512
|
||||
} Config_PositionConfig_PositionFlags;
|
||||
|
||||
typedef enum _Config_PowerConfig_ChargeCurrent {
|
||||
Config_PowerConfig_ChargeCurrent_MAUnset = 0,
|
||||
Config_PowerConfig_ChargeCurrent_MA100 = 1,
|
||||
Config_PowerConfig_ChargeCurrent_MA190 = 2,
|
||||
Config_PowerConfig_ChargeCurrent_MA280 = 3,
|
||||
Config_PowerConfig_ChargeCurrent_MA360 = 4,
|
||||
Config_PowerConfig_ChargeCurrent_MA450 = 5,
|
||||
Config_PowerConfig_ChargeCurrent_MA550 = 6,
|
||||
Config_PowerConfig_ChargeCurrent_MA630 = 7,
|
||||
Config_PowerConfig_ChargeCurrent_MA700 = 8,
|
||||
Config_PowerConfig_ChargeCurrent_MA780 = 9,
|
||||
Config_PowerConfig_ChargeCurrent_MA880 = 10,
|
||||
Config_PowerConfig_ChargeCurrent_MA960 = 11,
|
||||
Config_PowerConfig_ChargeCurrent_MA1000 = 12,
|
||||
Config_PowerConfig_ChargeCurrent_MA1080 = 13,
|
||||
Config_PowerConfig_ChargeCurrent_MA1160 = 14,
|
||||
Config_PowerConfig_ChargeCurrent_MA1240 = 15,
|
||||
Config_PowerConfig_ChargeCurrent_MA1320 = 16
|
||||
} Config_PowerConfig_ChargeCurrent;
|
||||
|
||||
typedef enum _Config_WiFiConfig_WiFiMode {
|
||||
Config_WiFiConfig_WiFiMode_Client = 0,
|
||||
Config_WiFiConfig_WiFiMode_AccessPoint = 1,
|
||||
Config_WiFiConfig_WiFiMode_AccessPointHidden = 2
|
||||
} Config_WiFiConfig_WiFiMode;
|
||||
typedef enum _Config_NetworkConfig_WiFiMode {
|
||||
Config_NetworkConfig_WiFiMode_CLIENT = 0,
|
||||
Config_NetworkConfig_WiFiMode_ACCESS_POINT = 1,
|
||||
Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN = 2
|
||||
} Config_NetworkConfig_WiFiMode;
|
||||
|
||||
typedef enum _Config_DisplayConfig_GpsCoordinateFormat {
|
||||
Config_DisplayConfig_GpsCoordinateFormat_GpsFormatDec = 0,
|
||||
Config_DisplayConfig_GpsCoordinateFormat_GpsFormatDMS = 1,
|
||||
Config_DisplayConfig_GpsCoordinateFormat_GpsFormatUTM = 2,
|
||||
Config_DisplayConfig_GpsCoordinateFormat_GpsFormatMGRS = 3,
|
||||
Config_DisplayConfig_GpsCoordinateFormat_GpsFormatOLC = 4,
|
||||
Config_DisplayConfig_GpsCoordinateFormat_GpsFormatOSGR = 5
|
||||
Config_DisplayConfig_GpsCoordinateFormat_DEC = 0,
|
||||
Config_DisplayConfig_GpsCoordinateFormat_DMS = 1,
|
||||
Config_DisplayConfig_GpsCoordinateFormat_UTM = 2,
|
||||
Config_DisplayConfig_GpsCoordinateFormat_MGRS = 3,
|
||||
Config_DisplayConfig_GpsCoordinateFormat_OLC = 4,
|
||||
Config_DisplayConfig_GpsCoordinateFormat_OSGR = 5
|
||||
} Config_DisplayConfig_GpsCoordinateFormat;
|
||||
|
||||
typedef enum _Config_DisplayConfig_DisplayUnits {
|
||||
Config_DisplayConfig_DisplayUnits_METRIC = 0,
|
||||
Config_DisplayConfig_DisplayUnits_IMPERIAL = 1
|
||||
} Config_DisplayConfig_DisplayUnits;
|
||||
|
||||
typedef enum _Config_LoRaConfig_RegionCode {
|
||||
Config_LoRaConfig_RegionCode_Unset = 0,
|
||||
Config_LoRaConfig_RegionCode_UNSET = 0,
|
||||
Config_LoRaConfig_RegionCode_US = 1,
|
||||
Config_LoRaConfig_RegionCode_EU433 = 2,
|
||||
Config_LoRaConfig_RegionCode_EU868 = 3,
|
||||
Config_LoRaConfig_RegionCode_EU_433 = 2,
|
||||
Config_LoRaConfig_RegionCode_EU_868 = 3,
|
||||
Config_LoRaConfig_RegionCode_CN = 4,
|
||||
Config_LoRaConfig_RegionCode_JP = 5,
|
||||
Config_LoRaConfig_RegionCode_ANZ = 6,
|
||||
@@ -78,24 +63,24 @@ typedef enum _Config_LoRaConfig_RegionCode {
|
||||
Config_LoRaConfig_RegionCode_TW = 8,
|
||||
Config_LoRaConfig_RegionCode_RU = 9,
|
||||
Config_LoRaConfig_RegionCode_IN = 10,
|
||||
Config_LoRaConfig_RegionCode_NZ865 = 11,
|
||||
Config_LoRaConfig_RegionCode_NZ_865 = 11,
|
||||
Config_LoRaConfig_RegionCode_TH = 12
|
||||
} Config_LoRaConfig_RegionCode;
|
||||
|
||||
typedef enum _Config_LoRaConfig_ModemPreset {
|
||||
Config_LoRaConfig_ModemPreset_LongFast = 0,
|
||||
Config_LoRaConfig_ModemPreset_LongSlow = 1,
|
||||
Config_LoRaConfig_ModemPreset_VLongSlow = 2,
|
||||
Config_LoRaConfig_ModemPreset_MedSlow = 3,
|
||||
Config_LoRaConfig_ModemPreset_MedFast = 4,
|
||||
Config_LoRaConfig_ModemPreset_ShortSlow = 5,
|
||||
Config_LoRaConfig_ModemPreset_ShortFast = 6
|
||||
Config_LoRaConfig_ModemPreset_LONG_FAST = 0,
|
||||
Config_LoRaConfig_ModemPreset_LONG_SLOW = 1,
|
||||
Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW = 2,
|
||||
Config_LoRaConfig_ModemPreset_MEDIUM_SLOW = 3,
|
||||
Config_LoRaConfig_ModemPreset_MEDIUM_FAST = 4,
|
||||
Config_LoRaConfig_ModemPreset_SHORT_SLOW = 5,
|
||||
Config_LoRaConfig_ModemPreset_SHORT_FAST = 6
|
||||
} Config_LoRaConfig_ModemPreset;
|
||||
|
||||
typedef enum _Config_BluetoothConfig_PairingMode {
|
||||
Config_BluetoothConfig_PairingMode_RandomPin = 0,
|
||||
Config_BluetoothConfig_PairingMode_FixedPin = 1,
|
||||
Config_BluetoothConfig_PairingMode_NoPin = 2
|
||||
Config_BluetoothConfig_PairingMode_RANDOM_PIN = 0,
|
||||
Config_BluetoothConfig_PairingMode_FIXED_PIN = 1,
|
||||
Config_BluetoothConfig_PairingMode_NO_PIN = 2
|
||||
} Config_BluetoothConfig_PairingMode;
|
||||
|
||||
/* Struct definitions */
|
||||
@@ -107,10 +92,8 @@ typedef struct _Config_BluetoothConfig {
|
||||
|
||||
typedef struct _Config_DeviceConfig {
|
||||
Config_DeviceConfig_Role role;
|
||||
bool serial_disabled;
|
||||
bool factory_reset;
|
||||
bool serial_enabled;
|
||||
bool debug_log_enabled;
|
||||
char ntp_server[33];
|
||||
} Config_DeviceConfig;
|
||||
|
||||
typedef struct _Config_DisplayConfig {
|
||||
@@ -118,34 +101,45 @@ typedef struct _Config_DisplayConfig {
|
||||
Config_DisplayConfig_GpsCoordinateFormat gps_format;
|
||||
uint32_t auto_screen_carousel_secs;
|
||||
bool compass_north_top;
|
||||
bool flip_screen;
|
||||
Config_DisplayConfig_DisplayUnits units;
|
||||
} Config_DisplayConfig;
|
||||
|
||||
typedef struct _Config_LoRaConfig {
|
||||
int32_t tx_power;
|
||||
bool use_preset;
|
||||
Config_LoRaConfig_ModemPreset modem_preset;
|
||||
uint32_t bandwidth;
|
||||
uint16_t bandwidth;
|
||||
uint32_t spread_factor;
|
||||
uint32_t coding_rate;
|
||||
uint8_t coding_rate;
|
||||
float frequency_offset;
|
||||
Config_LoRaConfig_RegionCode region;
|
||||
uint32_t hop_limit;
|
||||
bool tx_disabled;
|
||||
bool tx_enabled;
|
||||
int8_t tx_power;
|
||||
uint8_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_PositionConfig {
|
||||
uint32_t position_broadcast_secs;
|
||||
bool position_broadcast_smart_disabled;
|
||||
bool position_broadcast_smart_enabled;
|
||||
bool fixed_position;
|
||||
bool gps_disabled;
|
||||
bool gps_enabled;
|
||||
uint32_t gps_update_interval;
|
||||
uint32_t gps_attempt_time;
|
||||
uint32_t position_flags;
|
||||
} Config_PositionConfig;
|
||||
|
||||
typedef struct _Config_PowerConfig {
|
||||
Config_PowerConfig_ChargeCurrent charge_current;
|
||||
bool is_power_saving;
|
||||
uint32_t on_battery_shutdown_after_secs;
|
||||
float adc_multiplier_override;
|
||||
@@ -156,59 +150,52 @@ typedef struct _Config_PowerConfig {
|
||||
uint32_t min_wake_secs;
|
||||
} Config_PowerConfig;
|
||||
|
||||
typedef struct _Config_WiFiConfig {
|
||||
bool enabled;
|
||||
Config_WiFiConfig_WiFiMode mode;
|
||||
char ssid[33];
|
||||
char psk[64];
|
||||
} Config_WiFiConfig;
|
||||
|
||||
typedef struct _Config {
|
||||
pb_size_t which_payloadVariant;
|
||||
pb_size_t which_payload_variant;
|
||||
union {
|
||||
Config_DeviceConfig device;
|
||||
Config_PositionConfig position;
|
||||
Config_PowerConfig power;
|
||||
Config_WiFiConfig wifi;
|
||||
Config_NetworkConfig network;
|
||||
Config_DisplayConfig display;
|
||||
Config_LoRaConfig lora;
|
||||
Config_BluetoothConfig bluetooth;
|
||||
} payloadVariant;
|
||||
} payload_variant;
|
||||
} Config;
|
||||
|
||||
|
||||
/* Helper constants for enums */
|
||||
#define _Config_DeviceConfig_Role_MIN Config_DeviceConfig_Role_Client
|
||||
#define _Config_DeviceConfig_Role_MAX Config_DeviceConfig_Role_RouterClient
|
||||
#define _Config_DeviceConfig_Role_ARRAYSIZE ((Config_DeviceConfig_Role)(Config_DeviceConfig_Role_RouterClient+1))
|
||||
#define _Config_DeviceConfig_Role_MIN Config_DeviceConfig_Role_CLIENT
|
||||
#define _Config_DeviceConfig_Role_MAX Config_DeviceConfig_Role_ROUTER_CLIENT
|
||||
#define _Config_DeviceConfig_Role_ARRAYSIZE ((Config_DeviceConfig_Role)(Config_DeviceConfig_Role_ROUTER_CLIENT+1))
|
||||
|
||||
#define _Config_PositionConfig_PositionFlags_MIN Config_PositionConfig_PositionFlags_POS_UNDEFINED
|
||||
#define _Config_PositionConfig_PositionFlags_MAX Config_PositionConfig_PositionFlags_POS_SPEED
|
||||
#define _Config_PositionConfig_PositionFlags_ARRAYSIZE ((Config_PositionConfig_PositionFlags)(Config_PositionConfig_PositionFlags_POS_SPEED+1))
|
||||
#define _Config_PositionConfig_PositionFlags_MIN Config_PositionConfig_PositionFlags_UNSET
|
||||
#define _Config_PositionConfig_PositionFlags_MAX Config_PositionConfig_PositionFlags_SPEED
|
||||
#define _Config_PositionConfig_PositionFlags_ARRAYSIZE ((Config_PositionConfig_PositionFlags)(Config_PositionConfig_PositionFlags_SPEED+1))
|
||||
|
||||
#define _Config_PowerConfig_ChargeCurrent_MIN Config_PowerConfig_ChargeCurrent_MAUnset
|
||||
#define _Config_PowerConfig_ChargeCurrent_MAX Config_PowerConfig_ChargeCurrent_MA1320
|
||||
#define _Config_PowerConfig_ChargeCurrent_ARRAYSIZE ((Config_PowerConfig_ChargeCurrent)(Config_PowerConfig_ChargeCurrent_MA1320+1))
|
||||
#define _Config_NetworkConfig_WiFiMode_MIN Config_NetworkConfig_WiFiMode_CLIENT
|
||||
#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_WiFiConfig_WiFiMode_MIN Config_WiFiConfig_WiFiMode_Client
|
||||
#define _Config_WiFiConfig_WiFiMode_MAX Config_WiFiConfig_WiFiMode_AccessPointHidden
|
||||
#define _Config_WiFiConfig_WiFiMode_ARRAYSIZE ((Config_WiFiConfig_WiFiMode)(Config_WiFiConfig_WiFiMode_AccessPointHidden+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))
|
||||
|
||||
#define _Config_DisplayConfig_GpsCoordinateFormat_MIN Config_DisplayConfig_GpsCoordinateFormat_GpsFormatDec
|
||||
#define _Config_DisplayConfig_GpsCoordinateFormat_MAX Config_DisplayConfig_GpsCoordinateFormat_GpsFormatOSGR
|
||||
#define _Config_DisplayConfig_GpsCoordinateFormat_ARRAYSIZE ((Config_DisplayConfig_GpsCoordinateFormat)(Config_DisplayConfig_GpsCoordinateFormat_GpsFormatOSGR+1))
|
||||
#define _Config_DisplayConfig_DisplayUnits_MIN Config_DisplayConfig_DisplayUnits_METRIC
|
||||
#define _Config_DisplayConfig_DisplayUnits_MAX Config_DisplayConfig_DisplayUnits_IMPERIAL
|
||||
#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_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_ModemPreset_MIN Config_LoRaConfig_ModemPreset_LongFast
|
||||
#define _Config_LoRaConfig_ModemPreset_MAX Config_LoRaConfig_ModemPreset_ShortFast
|
||||
#define _Config_LoRaConfig_ModemPreset_ARRAYSIZE ((Config_LoRaConfig_ModemPreset)(Config_LoRaConfig_ModemPreset_ShortFast+1))
|
||||
#define _Config_LoRaConfig_ModemPreset_MIN Config_LoRaConfig_ModemPreset_LONG_FAST
|
||||
#define _Config_LoRaConfig_ModemPreset_MAX Config_LoRaConfig_ModemPreset_SHORT_FAST
|
||||
#define _Config_LoRaConfig_ModemPreset_ARRAYSIZE ((Config_LoRaConfig_ModemPreset)(Config_LoRaConfig_ModemPreset_SHORT_FAST+1))
|
||||
|
||||
#define _Config_BluetoothConfig_PairingMode_MIN Config_BluetoothConfig_PairingMode_RandomPin
|
||||
#define _Config_BluetoothConfig_PairingMode_MAX Config_BluetoothConfig_PairingMode_NoPin
|
||||
#define _Config_BluetoothConfig_PairingMode_ARRAYSIZE ((Config_BluetoothConfig_PairingMode)(Config_BluetoothConfig_PairingMode_NoPin+1))
|
||||
#define _Config_BluetoothConfig_PairingMode_MIN Config_BluetoothConfig_PairingMode_RANDOM_PIN
|
||||
#define _Config_BluetoothConfig_PairingMode_MAX Config_BluetoothConfig_PairingMode_NO_PIN
|
||||
#define _Config_BluetoothConfig_PairingMode_ARRAYSIZE ((Config_BluetoothConfig_PairingMode)(Config_BluetoothConfig_PairingMode_NO_PIN+1))
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -217,20 +204,20 @@ extern "C" {
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define Config_init_default {0, {Config_DeviceConfig_init_default}}
|
||||
#define Config_DeviceConfig_init_default {_Config_DeviceConfig_Role_MIN, 0, 0, 0, ""}
|
||||
#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 {_Config_PowerConfig_ChargeCurrent_MIN, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
#define Config_WiFiConfig_init_default {0, _Config_WiFiConfig_WiFiMode_MIN, "", ""}
|
||||
#define Config_DisplayConfig_init_default {0, _Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0}
|
||||
#define Config_LoRaConfig_init_default {0, _Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _Config_LoRaConfig_RegionCode_MIN, 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_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}
|
||||
#define Config_init_zero {0, {Config_DeviceConfig_init_zero}}
|
||||
#define Config_DeviceConfig_init_zero {_Config_DeviceConfig_Role_MIN, 0, 0, 0, ""}
|
||||
#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 {_Config_PowerConfig_ChargeCurrent_MIN, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
#define Config_WiFiConfig_init_zero {0, _Config_WiFiConfig_WiFiMode_MIN, "", ""}
|
||||
#define Config_DisplayConfig_init_zero {0, _Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0}
|
||||
#define Config_LoRaConfig_init_zero {0, _Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _Config_LoRaConfig_RegionCode_MIN, 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_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}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
@@ -238,15 +225,15 @@ extern "C" {
|
||||
#define Config_BluetoothConfig_mode_tag 2
|
||||
#define Config_BluetoothConfig_fixed_pin_tag 3
|
||||
#define Config_DeviceConfig_role_tag 1
|
||||
#define Config_DeviceConfig_serial_disabled_tag 2
|
||||
#define Config_DeviceConfig_factory_reset_tag 3
|
||||
#define Config_DeviceConfig_debug_log_enabled_tag 4
|
||||
#define Config_DeviceConfig_ntp_server_tag 5
|
||||
#define Config_DeviceConfig_serial_enabled_tag 2
|
||||
#define Config_DeviceConfig_debug_log_enabled_tag 3
|
||||
#define Config_DisplayConfig_screen_on_secs_tag 1
|
||||
#define Config_DisplayConfig_gps_format_tag 2
|
||||
#define Config_DisplayConfig_auto_screen_carousel_secs_tag 3
|
||||
#define Config_DisplayConfig_compass_north_top_tag 4
|
||||
#define Config_LoRaConfig_tx_power_tag 1
|
||||
#define Config_DisplayConfig_flip_screen_tag 5
|
||||
#define Config_DisplayConfig_units_tag 6
|
||||
#define Config_LoRaConfig_use_preset_tag 1
|
||||
#define Config_LoRaConfig_modem_preset_tag 2
|
||||
#define Config_LoRaConfig_bandwidth_tag 3
|
||||
#define Config_LoRaConfig_spread_factor_tag 4
|
||||
@@ -254,106 +241,108 @@ extern "C" {
|
||||
#define Config_LoRaConfig_frequency_offset_tag 6
|
||||
#define Config_LoRaConfig_region_tag 7
|
||||
#define Config_LoRaConfig_hop_limit_tag 8
|
||||
#define Config_LoRaConfig_tx_disabled_tag 9
|
||||
#define Config_LoRaConfig_tx_enabled_tag 9
|
||||
#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_PositionConfig_position_broadcast_secs_tag 1
|
||||
#define Config_PositionConfig_position_broadcast_smart_disabled_tag 2
|
||||
#define Config_PositionConfig_position_broadcast_smart_enabled_tag 2
|
||||
#define Config_PositionConfig_fixed_position_tag 3
|
||||
#define Config_PositionConfig_gps_disabled_tag 5
|
||||
#define Config_PositionConfig_gps_update_interval_tag 6
|
||||
#define Config_PositionConfig_gps_attempt_time_tag 7
|
||||
#define Config_PositionConfig_position_flags_tag 10
|
||||
#define Config_PowerConfig_charge_current_tag 1
|
||||
#define Config_PowerConfig_is_power_saving_tag 2
|
||||
#define Config_PowerConfig_on_battery_shutdown_after_secs_tag 4
|
||||
#define Config_PowerConfig_adc_multiplier_override_tag 6
|
||||
#define Config_PowerConfig_wait_bluetooth_secs_tag 7
|
||||
#define Config_PowerConfig_mesh_sds_timeout_secs_tag 9
|
||||
#define Config_PowerConfig_sds_secs_tag 10
|
||||
#define Config_PowerConfig_ls_secs_tag 11
|
||||
#define Config_PowerConfig_min_wake_secs_tag 12
|
||||
#define Config_WiFiConfig_enabled_tag 1
|
||||
#define Config_WiFiConfig_mode_tag 2
|
||||
#define Config_WiFiConfig_ssid_tag 3
|
||||
#define Config_WiFiConfig_psk_tag 4
|
||||
#define Config_PositionConfig_gps_enabled_tag 4
|
||||
#define Config_PositionConfig_gps_update_interval_tag 5
|
||||
#define Config_PositionConfig_gps_attempt_time_tag 6
|
||||
#define Config_PositionConfig_position_flags_tag 7
|
||||
#define Config_PowerConfig_is_power_saving_tag 1
|
||||
#define Config_PowerConfig_on_battery_shutdown_after_secs_tag 2
|
||||
#define Config_PowerConfig_adc_multiplier_override_tag 3
|
||||
#define Config_PowerConfig_wait_bluetooth_secs_tag 4
|
||||
#define Config_PowerConfig_mesh_sds_timeout_secs_tag 5
|
||||
#define Config_PowerConfig_sds_secs_tag 6
|
||||
#define Config_PowerConfig_ls_secs_tag 7
|
||||
#define Config_PowerConfig_min_wake_secs_tag 8
|
||||
#define Config_device_tag 1
|
||||
#define Config_position_tag 2
|
||||
#define Config_power_tag 3
|
||||
#define Config_wifi_tag 4
|
||||
#define Config_network_tag 4
|
||||
#define Config_display_tag 5
|
||||
#define Config_lora_tag 6
|
||||
#define Config_bluetooth_tag 7
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
#define Config_FIELDLIST(X, a) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,device,payloadVariant.device), 1) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,position,payloadVariant.position), 2) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,power,payloadVariant.power), 3) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,wifi,payloadVariant.wifi), 4) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,display,payloadVariant.display), 5) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,lora,payloadVariant.lora), 6) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,bluetooth,payloadVariant.bluetooth), 7)
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,device,payload_variant.device), 1) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,position,payload_variant.position), 2) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,power,payload_variant.power), 3) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,network,payload_variant.network), 4) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,display,payload_variant.display), 5) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,lora,payload_variant.lora), 6) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,bluetooth,payload_variant.bluetooth), 7)
|
||||
#define Config_CALLBACK NULL
|
||||
#define Config_DEFAULT NULL
|
||||
#define Config_payloadVariant_device_MSGTYPE Config_DeviceConfig
|
||||
#define Config_payloadVariant_position_MSGTYPE Config_PositionConfig
|
||||
#define Config_payloadVariant_power_MSGTYPE Config_PowerConfig
|
||||
#define Config_payloadVariant_wifi_MSGTYPE Config_WiFiConfig
|
||||
#define Config_payloadVariant_display_MSGTYPE Config_DisplayConfig
|
||||
#define Config_payloadVariant_lora_MSGTYPE Config_LoRaConfig
|
||||
#define Config_payloadVariant_bluetooth_MSGTYPE Config_BluetoothConfig
|
||||
#define Config_payload_variant_device_MSGTYPE Config_DeviceConfig
|
||||
#define Config_payload_variant_position_MSGTYPE Config_PositionConfig
|
||||
#define Config_payload_variant_power_MSGTYPE Config_PowerConfig
|
||||
#define Config_payload_variant_network_MSGTYPE Config_NetworkConfig
|
||||
#define Config_payload_variant_display_MSGTYPE Config_DisplayConfig
|
||||
#define Config_payload_variant_lora_MSGTYPE Config_LoRaConfig
|
||||
#define Config_payload_variant_bluetooth_MSGTYPE Config_BluetoothConfig
|
||||
|
||||
#define Config_DeviceConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UENUM, role, 1) \
|
||||
X(a, STATIC, SINGULAR, BOOL, serial_disabled, 2) \
|
||||
X(a, STATIC, SINGULAR, BOOL, factory_reset, 3) \
|
||||
X(a, STATIC, SINGULAR, BOOL, debug_log_enabled, 4) \
|
||||
X(a, STATIC, SINGULAR, STRING, ntp_server, 5)
|
||||
X(a, STATIC, SINGULAR, BOOL, serial_enabled, 2) \
|
||||
X(a, STATIC, SINGULAR, BOOL, debug_log_enabled, 3)
|
||||
#define Config_DeviceConfig_CALLBACK NULL
|
||||
#define Config_DeviceConfig_DEFAULT NULL
|
||||
|
||||
#define Config_PositionConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT32, position_broadcast_secs, 1) \
|
||||
X(a, STATIC, SINGULAR, BOOL, position_broadcast_smart_disabled, 2) \
|
||||
X(a, STATIC, SINGULAR, BOOL, position_broadcast_smart_enabled, 2) \
|
||||
X(a, STATIC, SINGULAR, BOOL, fixed_position, 3) \
|
||||
X(a, STATIC, SINGULAR, BOOL, gps_disabled, 5) \
|
||||
X(a, STATIC, SINGULAR, UINT32, gps_update_interval, 6) \
|
||||
X(a, STATIC, SINGULAR, UINT32, gps_attempt_time, 7) \
|
||||
X(a, STATIC, SINGULAR, UINT32, position_flags, 10)
|
||||
X(a, STATIC, SINGULAR, BOOL, gps_enabled, 4) \
|
||||
X(a, STATIC, SINGULAR, UINT32, gps_update_interval, 5) \
|
||||
X(a, STATIC, SINGULAR, UINT32, gps_attempt_time, 6) \
|
||||
X(a, STATIC, SINGULAR, UINT32, position_flags, 7)
|
||||
#define Config_PositionConfig_CALLBACK NULL
|
||||
#define Config_PositionConfig_DEFAULT NULL
|
||||
|
||||
#define Config_PowerConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UENUM, charge_current, 1) \
|
||||
X(a, STATIC, SINGULAR, BOOL, is_power_saving, 2) \
|
||||
X(a, STATIC, SINGULAR, UINT32, on_battery_shutdown_after_secs, 4) \
|
||||
X(a, STATIC, SINGULAR, FLOAT, adc_multiplier_override, 6) \
|
||||
X(a, STATIC, SINGULAR, UINT32, wait_bluetooth_secs, 7) \
|
||||
X(a, STATIC, SINGULAR, UINT32, mesh_sds_timeout_secs, 9) \
|
||||
X(a, STATIC, SINGULAR, UINT32, sds_secs, 10) \
|
||||
X(a, STATIC, SINGULAR, UINT32, ls_secs, 11) \
|
||||
X(a, STATIC, SINGULAR, UINT32, min_wake_secs, 12)
|
||||
X(a, STATIC, SINGULAR, BOOL, is_power_saving, 1) \
|
||||
X(a, STATIC, SINGULAR, UINT32, on_battery_shutdown_after_secs, 2) \
|
||||
X(a, STATIC, SINGULAR, FLOAT, adc_multiplier_override, 3) \
|
||||
X(a, STATIC, SINGULAR, UINT32, wait_bluetooth_secs, 4) \
|
||||
X(a, STATIC, SINGULAR, UINT32, mesh_sds_timeout_secs, 5) \
|
||||
X(a, STATIC, SINGULAR, UINT32, sds_secs, 6) \
|
||||
X(a, STATIC, SINGULAR, UINT32, ls_secs, 7) \
|
||||
X(a, STATIC, SINGULAR, UINT32, min_wake_secs, 8)
|
||||
#define Config_PowerConfig_CALLBACK NULL
|
||||
#define Config_PowerConfig_DEFAULT NULL
|
||||
|
||||
#define Config_WiFiConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, BOOL, enabled, 1) \
|
||||
X(a, STATIC, SINGULAR, UENUM, mode, 2) \
|
||||
X(a, STATIC, SINGULAR, STRING, ssid, 3) \
|
||||
X(a, STATIC, SINGULAR, STRING, psk, 4)
|
||||
#define Config_WiFiConfig_CALLBACK NULL
|
||||
#define Config_WiFiConfig_DEFAULT NULL
|
||||
#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)
|
||||
#define Config_NetworkConfig_CALLBACK NULL
|
||||
#define Config_NetworkConfig_DEFAULT NULL
|
||||
|
||||
#define Config_DisplayConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT32, screen_on_secs, 1) \
|
||||
X(a, STATIC, SINGULAR, UENUM, gps_format, 2) \
|
||||
X(a, STATIC, SINGULAR, UINT32, auto_screen_carousel_secs, 3) \
|
||||
X(a, STATIC, SINGULAR, BOOL, compass_north_top, 4)
|
||||
X(a, STATIC, SINGULAR, BOOL, compass_north_top, 4) \
|
||||
X(a, STATIC, SINGULAR, BOOL, flip_screen, 5) \
|
||||
X(a, STATIC, SINGULAR, UENUM, units, 6)
|
||||
#define Config_DisplayConfig_CALLBACK NULL
|
||||
#define Config_DisplayConfig_DEFAULT NULL
|
||||
|
||||
#define Config_LoRaConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, INT32, tx_power, 1) \
|
||||
X(a, STATIC, SINGULAR, BOOL, use_preset, 1) \
|
||||
X(a, STATIC, SINGULAR, UENUM, modem_preset, 2) \
|
||||
X(a, STATIC, SINGULAR, UINT32, bandwidth, 3) \
|
||||
X(a, STATIC, SINGULAR, UINT32, spread_factor, 4) \
|
||||
@@ -361,7 +350,9 @@ X(a, STATIC, SINGULAR, UINT32, coding_rate, 5) \
|
||||
X(a, STATIC, SINGULAR, FLOAT, frequency_offset, 6) \
|
||||
X(a, STATIC, SINGULAR, UENUM, region, 7) \
|
||||
X(a, STATIC, SINGULAR, UINT32, hop_limit, 8) \
|
||||
X(a, STATIC, SINGULAR, BOOL, tx_disabled, 9) \
|
||||
X(a, STATIC, SINGULAR, BOOL, tx_enabled, 9) \
|
||||
X(a, STATIC, SINGULAR, INT32, tx_power, 10) \
|
||||
X(a, STATIC, SINGULAR, UINT32, channel_num, 11) \
|
||||
X(a, STATIC, REPEATED, UINT32, ignore_incoming, 103)
|
||||
#define Config_LoRaConfig_CALLBACK NULL
|
||||
#define Config_LoRaConfig_DEFAULT NULL
|
||||
@@ -377,7 +368,7 @@ extern const pb_msgdesc_t Config_msg;
|
||||
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_WiFiConfig_msg;
|
||||
extern const pb_msgdesc_t Config_NetworkConfig_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;
|
||||
@@ -387,20 +378,20 @@ extern const pb_msgdesc_t Config_BluetoothConfig_msg;
|
||||
#define Config_DeviceConfig_fields &Config_DeviceConfig_msg
|
||||
#define Config_PositionConfig_fields &Config_PositionConfig_msg
|
||||
#define Config_PowerConfig_fields &Config_PowerConfig_msg
|
||||
#define Config_WiFiConfig_fields &Config_WiFiConfig_msg
|
||||
#define Config_NetworkConfig_fields &Config_NetworkConfig_msg
|
||||
#define Config_DisplayConfig_fields &Config_DisplayConfig_msg
|
||||
#define Config_LoRaConfig_fields &Config_LoRaConfig_msg
|
||||
#define Config_BluetoothConfig_fields &Config_BluetoothConfig_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define Config_BluetoothConfig_size 10
|
||||
#define Config_DeviceConfig_size 42
|
||||
#define Config_DisplayConfig_size 16
|
||||
#define Config_DeviceConfig_size 6
|
||||
#define Config_DisplayConfig_size 20
|
||||
#define Config_LoRaConfig_size 67
|
||||
#define Config_NetworkConfig_size 137
|
||||
#define Config_PositionConfig_size 30
|
||||
#define Config_PowerConfig_size 45
|
||||
#define Config_WiFiConfig_size 103
|
||||
#define Config_size 105
|
||||
#define Config_PowerConfig_size 43
|
||||
#define Config_size 140
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
||||
@@ -164,8 +164,8 @@ extern const pb_msgdesc_t OEMStore_msg;
|
||||
#define OEMStore_fields &OEMStore_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define ChannelFile_size 630
|
||||
#define DeviceState_size 22218
|
||||
#define ChannelFile_size 638
|
||||
#define DeviceState_size 21800
|
||||
#define OEMStore_size 2106
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -23,8 +23,8 @@ typedef struct _LocalConfig {
|
||||
bool has_power;
|
||||
Config_PowerConfig power;
|
||||
/* The part of the config that is specific to the Wifi Settings */
|
||||
bool has_wifi;
|
||||
Config_WiFiConfig wifi;
|
||||
bool has_network;
|
||||
Config_NetworkConfig network;
|
||||
/* The part of the config that is specific to the Display */
|
||||
bool has_display;
|
||||
Config_DisplayConfig display;
|
||||
@@ -74,16 +74,16 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define LocalConfig_init_default {false, Config_DeviceConfig_init_default, false, Config_PositionConfig_init_default, false, Config_PowerConfig_init_default, false, Config_WiFiConfig_init_default, false, Config_DisplayConfig_init_default, false, Config_LoRaConfig_init_default, false, Config_BluetoothConfig_init_default, 0}
|
||||
#define LocalConfig_init_default {false, Config_DeviceConfig_init_default, false, Config_PositionConfig_init_default, false, Config_PowerConfig_init_default, false, Config_NetworkConfig_init_default, false, Config_DisplayConfig_init_default, false, Config_LoRaConfig_init_default, false, Config_BluetoothConfig_init_default, 0}
|
||||
#define LocalModuleConfig_init_default {false, ModuleConfig_MQTTConfig_init_default, false, ModuleConfig_SerialConfig_init_default, false, ModuleConfig_ExternalNotificationConfig_init_default, false, ModuleConfig_StoreForwardConfig_init_default, false, ModuleConfig_RangeTestConfig_init_default, false, ModuleConfig_TelemetryConfig_init_default, false, ModuleConfig_CannedMessageConfig_init_default, 0}
|
||||
#define LocalConfig_init_zero {false, Config_DeviceConfig_init_zero, false, Config_PositionConfig_init_zero, false, Config_PowerConfig_init_zero, false, Config_WiFiConfig_init_zero, false, Config_DisplayConfig_init_zero, false, Config_LoRaConfig_init_zero, false, Config_BluetoothConfig_init_zero, 0}
|
||||
#define LocalConfig_init_zero {false, Config_DeviceConfig_init_zero, false, Config_PositionConfig_init_zero, false, Config_PowerConfig_init_zero, false, Config_NetworkConfig_init_zero, false, Config_DisplayConfig_init_zero, false, Config_LoRaConfig_init_zero, false, Config_BluetoothConfig_init_zero, 0}
|
||||
#define LocalModuleConfig_init_zero {false, ModuleConfig_MQTTConfig_init_zero, false, ModuleConfig_SerialConfig_init_zero, false, ModuleConfig_ExternalNotificationConfig_init_zero, false, ModuleConfig_StoreForwardConfig_init_zero, false, ModuleConfig_RangeTestConfig_init_zero, false, ModuleConfig_TelemetryConfig_init_zero, false, ModuleConfig_CannedMessageConfig_init_zero, 0}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define LocalConfig_device_tag 1
|
||||
#define LocalConfig_position_tag 2
|
||||
#define LocalConfig_power_tag 3
|
||||
#define LocalConfig_wifi_tag 4
|
||||
#define LocalConfig_network_tag 4
|
||||
#define LocalConfig_display_tag 5
|
||||
#define LocalConfig_lora_tag 6
|
||||
#define LocalConfig_bluetooth_tag 7
|
||||
@@ -102,7 +102,7 @@ extern "C" {
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, device, 1) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, position, 2) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, power, 3) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, wifi, 4) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, network, 4) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, display, 5) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, lora, 6) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, bluetooth, 7) \
|
||||
@@ -112,7 +112,7 @@ X(a, STATIC, SINGULAR, UINT32, version, 8)
|
||||
#define LocalConfig_device_MSGTYPE Config_DeviceConfig
|
||||
#define LocalConfig_position_MSGTYPE Config_PositionConfig
|
||||
#define LocalConfig_power_MSGTYPE Config_PowerConfig
|
||||
#define LocalConfig_wifi_MSGTYPE Config_WiFiConfig
|
||||
#define LocalConfig_network_MSGTYPE Config_NetworkConfig
|
||||
#define LocalConfig_display_MSGTYPE Config_DisplayConfig
|
||||
#define LocalConfig_lora_MSGTYPE Config_LoRaConfig
|
||||
#define LocalConfig_bluetooth_MSGTYPE Config_BluetoothConfig
|
||||
@@ -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 333
|
||||
#define LocalConfig_size 334
|
||||
#define LocalModuleConfig_size 270
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#ifndef PB_MESH_PB_H_INCLUDED
|
||||
#define PB_MESH_PB_H_INCLUDED
|
||||
#include <pb.h>
|
||||
#include "channel.pb.h"
|
||||
#include "config.pb.h"
|
||||
#include "module_config.pb.h"
|
||||
#include "portnums.pb.h"
|
||||
@@ -26,18 +27,18 @@ typedef enum _HardwareModel {
|
||||
/* TODO: REPLACE */
|
||||
HardwareModel_TLORA_V1 = 2,
|
||||
/* TODO: REPLACE */
|
||||
HardwareModel_TLORA_V2_1_1p6 = 3,
|
||||
HardwareModel_TLORA_V2_1_1P6 = 3,
|
||||
/* TODO: REPLACE */
|
||||
HardwareModel_TBEAM = 4,
|
||||
/* The original heltec WiFi_Lora_32_V2, which had battery voltage sensing hooked to GPIO 13
|
||||
(see HELTEC_V2 for the new version). */
|
||||
HardwareModel_HELTEC_V2_0 = 5,
|
||||
/* TODO: REPLACE */
|
||||
HardwareModel_TBEAM0p7 = 6,
|
||||
HardwareModel_TBEAM_V0P7 = 6,
|
||||
/* TODO: REPLACE */
|
||||
HardwareModel_T_ECHO = 7,
|
||||
/* TODO: REPLACE */
|
||||
HardwareModel_TLORA_V1_1p3 = 8,
|
||||
HardwareModel_TLORA_V1_1P3 = 8,
|
||||
/* TODO: REPLACE */
|
||||
HardwareModel_RAK4631 = 9,
|
||||
/* The new version of the heltec WiFi_Lora_32_V2 board that has battery sensing hooked to GPIO 37.
|
||||
@@ -45,6 +46,14 @@ typedef enum _HardwareModel {
|
||||
HardwareModel_HELTEC_V2_1 = 10,
|
||||
/* Ancient heltec WiFi_Lora_32 board */
|
||||
HardwareModel_HELTEC_V1 = 11,
|
||||
/* New T-BEAM with ESP32-S3 CPU */
|
||||
HardwareModel_LILYGO_TBEAM_S3_CORE = 12,
|
||||
/* RAK WisBlock ESP32 core: https://docs.rakwireless.com/Product-Categories/WisBlock/RAK11200/Overview/ */
|
||||
HardwareModel_RAK11200 = 13,
|
||||
/* B&Q Consulting Nano Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:nano */
|
||||
HardwareModel_NANO_G1 = 14,
|
||||
/* B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station */
|
||||
HardwareModel_STATION_G1 = 25,
|
||||
/* Less common/prototype boards listed here (needs one more byte over the air) */
|
||||
HardwareModel_LORA_RELAY_V1 = 32,
|
||||
/* TODO: REPLACE */
|
||||
@@ -61,18 +70,12 @@ typedef enum _HardwareModel {
|
||||
HardwareModel_ANDROID_SIM = 38,
|
||||
/* Custom DIY device based on @NanoVHF schematics: https://github.com/NanoVHF/Meshtastic-DIY/tree/main/Schematics */
|
||||
HardwareModel_DIY_V1 = 39,
|
||||
/* RAK WisBlock ESP32 core: https://docs.rakwireless.com/Product-Categories/WisBlock/RAK11200/Overview/ */
|
||||
HardwareModel_RAK11200 = 40,
|
||||
/* B&Q Consulting Nano Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:nano */
|
||||
HardwareModel_NANO_G1 = 41,
|
||||
/* nRF52840 Dongle : https://www.nordicsemi.com/Products/Development-hardware/nrf52840-dongle/ */
|
||||
HardwareModel_NRF52840_PCA10059 = 42,
|
||||
HardwareModel_NRF52840_PCA10059 = 40,
|
||||
/* Custom Disaster Radio esp32 v3 device https://github.com/sudomesh/disaster-radio/tree/master/hardware/board_esp32_v3 */
|
||||
HardwareModel_DR_DEV = 43,
|
||||
HardwareModel_DR_DEV = 41,
|
||||
/* M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, Paper) https://m5stack.com/ */
|
||||
HardwareModel_M5STACK = 44,
|
||||
/* B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station */
|
||||
HardwareModel_STATION_G1 = 45,
|
||||
HardwareModel_M5STACK = 42,
|
||||
/* Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits. */
|
||||
HardwareModel_PRIVATE_HW = 255
|
||||
} HardwareModel;
|
||||
@@ -81,7 +84,7 @@ typedef enum _HardwareModel {
|
||||
typedef enum _Constants {
|
||||
/* First enum must be zero, and we are just using this enum to
|
||||
pass int constants between two very different environments */
|
||||
Constants_Unused = 0,
|
||||
Constants_ZERO = 0,
|
||||
/* From mesh.options
|
||||
note: this payload length is ONLY the bytes that are sent inside of the Data protobuf (excluding protobuf overhead). The 16 byte header is
|
||||
outside of this envelope */
|
||||
@@ -94,32 +97,32 @@ typedef enum _Constants {
|
||||
and we'll try to help. */
|
||||
typedef enum _CriticalErrorCode {
|
||||
/* TODO: REPLACE */
|
||||
CriticalErrorCode_None = 0,
|
||||
CriticalErrorCode_NONE = 0,
|
||||
/* A software bug was detected while trying to send lora */
|
||||
CriticalErrorCode_TxWatchdog = 1,
|
||||
CriticalErrorCode_TX_WATCHDOG = 1,
|
||||
/* A software bug was detected on entry to sleep */
|
||||
CriticalErrorCode_SleepEnterWait = 2,
|
||||
CriticalErrorCode_SLEEP_ENTER_WAIT = 2,
|
||||
/* No Lora radio hardware could be found */
|
||||
CriticalErrorCode_NoRadio = 3,
|
||||
CriticalErrorCode_NO_RADIO = 3,
|
||||
/* Not normally used */
|
||||
CriticalErrorCode_Unspecified = 4,
|
||||
CriticalErrorCode_UNSPECIFIED = 4,
|
||||
/* We failed while configuring a UBlox GPS */
|
||||
CriticalErrorCode_UBloxInitFailed = 5,
|
||||
CriticalErrorCode_UBLOX_UNIT_FAILED = 5,
|
||||
/* This board was expected to have a power management chip and it is missing or broken */
|
||||
CriticalErrorCode_NoAXP192 = 6,
|
||||
CriticalErrorCode_NO_AXP192 = 6,
|
||||
/* The channel tried to set a radio setting which is not supported by this chipset,
|
||||
radio comms settings are now undefined. */
|
||||
CriticalErrorCode_InvalidRadioSetting = 7,
|
||||
CriticalErrorCode_INVALID_RADIO_SETTING = 7,
|
||||
/* Radio transmit hardware failure. We sent data to the radio chip, but it didn't
|
||||
reply with an interrupt. */
|
||||
CriticalErrorCode_TransmitFailed = 8,
|
||||
CriticalErrorCode_TRANSMIT_FAILED = 8,
|
||||
/* We detected that the main CPU voltage dropped below the minumum acceptable value */
|
||||
CriticalErrorCode_Brownout = 9,
|
||||
CriticalErrorCode_BROWNOUT = 9,
|
||||
/* Selftest of SX1262 radio chip failed */
|
||||
CriticalErrorCode_SX1262Failure = 10,
|
||||
CriticalErrorCode_SX1262_FAILURE = 10,
|
||||
/* A (likely software but possibly hardware) failure was detected while trying to send packets.
|
||||
If this occurs on your board, please post in the forum so that we can ask you to collect some information to allow fixing this bug */
|
||||
CriticalErrorCode_RadioSpiBug = 11
|
||||
CriticalErrorCode_RADIO_SPI_BUG = 11
|
||||
} CriticalErrorCode;
|
||||
|
||||
/* Note: these enum names must EXACTLY match the string used in the device
|
||||
@@ -128,27 +131,27 @@ typedef enum _CriticalErrorCode {
|
||||
To match the old style filenames, _ is converted to -, p is converted to . */
|
||||
typedef enum _Position_LocSource {
|
||||
/* TODO: REPLACE */
|
||||
Position_LocSource_LOCSRC_UNSPECIFIED = 0,
|
||||
Position_LocSource_LOC_UNSET = 0,
|
||||
/* TODO: REPLACE */
|
||||
Position_LocSource_LOCSRC_MANUAL_ENTRY = 1,
|
||||
Position_LocSource_LOC_MANUAL = 1,
|
||||
/* TODO: REPLACE */
|
||||
Position_LocSource_LOCSRC_GPS_INTERNAL = 2,
|
||||
Position_LocSource_LOC_INTERNAL = 2,
|
||||
/* TODO: REPLACE */
|
||||
Position_LocSource_LOCSRC_GPS_EXTERNAL = 3
|
||||
Position_LocSource_LOC_EXTERNAL = 3
|
||||
} Position_LocSource;
|
||||
|
||||
/* Shared constants between device and phone */
|
||||
typedef enum _Position_AltSource {
|
||||
/* First enum must be zero, and we are just using this enum to
|
||||
pass int constants between two very different environments */
|
||||
Position_AltSource_ALTSRC_UNSPECIFIED = 0,
|
||||
Position_AltSource_ALT_UNSET = 0,
|
||||
/* From mesh.options
|
||||
note: this payload length is ONLY the bytes that are sent inside of the Data protobuf (excluding protobuf overhead). The 16 byte header is
|
||||
outside of this envelope */
|
||||
Position_AltSource_ALTSRC_MANUAL_ENTRY = 1,
|
||||
Position_AltSource_ALTSRC_GPS_INTERNAL = 2,
|
||||
Position_AltSource_ALTSRC_GPS_EXTERNAL = 3,
|
||||
Position_AltSource_ALTSRC_BAROMETRIC = 4
|
||||
Position_AltSource_ALT_MANUAL = 1,
|
||||
Position_AltSource_ALT_INTERNAL = 2,
|
||||
Position_AltSource_ALT_EXTERNAL = 3,
|
||||
Position_AltSource_ALT_BAROMETRIC = 4
|
||||
} Position_AltSource;
|
||||
|
||||
/* Note: these enum names must EXACTLY match the string used in the device
|
||||
@@ -304,6 +307,8 @@ typedef struct _MyNodeInfo {
|
||||
/* Note: This flag merely means we detected a hardware GPS in our node.
|
||||
Not the same as UserPreferences.location_sharing */
|
||||
bool has_gps;
|
||||
/* The maximum number of 'software' channels that can be set on this node. */
|
||||
uint32_t max_channels;
|
||||
/* 0.0.5 etc... */
|
||||
char firmware_version[18];
|
||||
/* An error message we'd like to report back to the mothership through analytics.
|
||||
@@ -331,8 +336,6 @@ typedef struct _MyNodeInfo {
|
||||
/* The minimum app version that can talk to this device.
|
||||
Phone/PC apps should compare this to their build number and if too low tell the user they must update their app */
|
||||
uint32_t min_app_version;
|
||||
/* The maximum number of 'software' channels that can be set on this node. */
|
||||
uint32_t max_channels;
|
||||
/* 24 time windows of 1hr each with the airtime transmitted out of the device per hour. */
|
||||
pb_size_t air_period_tx_count;
|
||||
uint32_t air_period_tx[8];
|
||||
@@ -367,13 +370,13 @@ typedef struct _Position {
|
||||
/* TODO: REPLACE */
|
||||
Position_AltSource altitude_source;
|
||||
/* Positional timestamp (actual timestamp of GPS solution) in integer epoch seconds */
|
||||
uint32_t pos_timestamp;
|
||||
uint32_t timestamp;
|
||||
/* Pos. timestamp milliseconds adjustment (rarely available or required) */
|
||||
int32_t pos_time_millis;
|
||||
int32_t timestamp_millis_adjust;
|
||||
/* HAE altitude in meters - can be used instead of MSL altitude */
|
||||
int32_t altitude_hae;
|
||||
/* Geoidal separation in meters */
|
||||
int32_t alt_geoid_sep;
|
||||
int32_t altitude_geoidal_separation;
|
||||
/* Horizontal, Vertical and Position Dilution of Precision, in 1/100 units
|
||||
- PDOP is sufficient for most cases
|
||||
- for higher precision scenarios, HDOP and VDOP can be used instead,
|
||||
@@ -409,10 +412,10 @@ typedef struct _Position {
|
||||
- if we update at fixed intervals of X seconds, use X
|
||||
- if we update at dynamic intervals (based on relative movement etc),
|
||||
but "AT LEAST every Y seconds", use Y */
|
||||
uint32_t pos_next_update;
|
||||
uint32_t next_update;
|
||||
/* A sequence number, incremented with each Position message to help
|
||||
detect lost updates if needed */
|
||||
uint32_t pos_seq_number;
|
||||
uint32_t seq_number;
|
||||
} Position;
|
||||
|
||||
/* A message used in our Dynamic Source Routing protocol (RFC 4728 based) */
|
||||
@@ -496,7 +499,7 @@ typedef struct _Waypoint {
|
||||
|
||||
typedef PB_BYTES_ARRAY_T(256) MeshPacket_encrypted_t;
|
||||
/* A packet envelope sent/received over the mesh
|
||||
only payloadVariant is sent in the payload portion of the LORA packet.
|
||||
only payload_variant is sent in the payload portion of the LORA packet.
|
||||
The other fields are either not sent at all, or sent in the special 16 byte LORA header. */
|
||||
typedef struct _MeshPacket {
|
||||
/* The sending node number.
|
||||
@@ -513,9 +516,9 @@ typedef struct _MeshPacket {
|
||||
Therefore channel_index is inherently a local concept and meaningless to send between nodes.
|
||||
Very briefly, while sending and receiving deep inside the device Router code, this field instead
|
||||
contains the 'channel hash' instead of the index.
|
||||
This 'trick' is only used while the payloadVariant is an 'encrypted'. */
|
||||
This 'trick' is only used while the payload_variant is an 'encrypted'. */
|
||||
uint8_t channel;
|
||||
pb_size_t which_payloadVariant;
|
||||
pb_size_t which_payload_variant;
|
||||
union {
|
||||
/* TODO: REPLACE */
|
||||
Data decoded;
|
||||
@@ -624,8 +627,10 @@ typedef struct _FromRadio {
|
||||
/* The packet id, used to allow the phone to request missing read packets from the FIFO,
|
||||
see our bluetooth docs */
|
||||
uint32_t id;
|
||||
pb_size_t which_payloadVariant;
|
||||
pb_size_t which_payload_variant;
|
||||
union {
|
||||
/* Log levels, chosen to match python logging conventions. */
|
||||
MeshPacket packet;
|
||||
/* Tells the phone what our node number is, can be -1 if we've not yet joined a mesh.
|
||||
NOTE: This ID must not change - to keep (minimal) compatibility with <1.2 version of android apps. */
|
||||
MyNodeInfo my_info;
|
||||
@@ -648,15 +653,15 @@ typedef struct _FromRadio {
|
||||
bool rebooted;
|
||||
/* Include module config */
|
||||
ModuleConfig moduleConfig;
|
||||
/* Log levels, chosen to match python logging conventions. */
|
||||
MeshPacket packet;
|
||||
/* One packet is sent for each channel */
|
||||
Channel channel;
|
||||
};
|
||||
} FromRadio;
|
||||
|
||||
/* Packets/commands to the radio will be written (reliably) to the toRadio characteristic.
|
||||
Once the write completes the phone can assume it is handled. */
|
||||
typedef struct _ToRadio {
|
||||
pb_size_t which_payloadVariant;
|
||||
pb_size_t which_payload_variant;
|
||||
union {
|
||||
/* Send this packet on the mesh */
|
||||
MeshPacket packet;
|
||||
@@ -685,21 +690,21 @@ typedef struct _ToRadio {
|
||||
#define _HardwareModel_MAX HardwareModel_PRIVATE_HW
|
||||
#define _HardwareModel_ARRAYSIZE ((HardwareModel)(HardwareModel_PRIVATE_HW+1))
|
||||
|
||||
#define _Constants_MIN Constants_Unused
|
||||
#define _Constants_MIN Constants_ZERO
|
||||
#define _Constants_MAX Constants_DATA_PAYLOAD_LEN
|
||||
#define _Constants_ARRAYSIZE ((Constants)(Constants_DATA_PAYLOAD_LEN+1))
|
||||
|
||||
#define _CriticalErrorCode_MIN CriticalErrorCode_None
|
||||
#define _CriticalErrorCode_MAX CriticalErrorCode_RadioSpiBug
|
||||
#define _CriticalErrorCode_ARRAYSIZE ((CriticalErrorCode)(CriticalErrorCode_RadioSpiBug+1))
|
||||
#define _CriticalErrorCode_MIN CriticalErrorCode_NONE
|
||||
#define _CriticalErrorCode_MAX CriticalErrorCode_RADIO_SPI_BUG
|
||||
#define _CriticalErrorCode_ARRAYSIZE ((CriticalErrorCode)(CriticalErrorCode_RADIO_SPI_BUG+1))
|
||||
|
||||
#define _Position_LocSource_MIN Position_LocSource_LOCSRC_UNSPECIFIED
|
||||
#define _Position_LocSource_MAX Position_LocSource_LOCSRC_GPS_EXTERNAL
|
||||
#define _Position_LocSource_ARRAYSIZE ((Position_LocSource)(Position_LocSource_LOCSRC_GPS_EXTERNAL+1))
|
||||
#define _Position_LocSource_MIN Position_LocSource_LOC_UNSET
|
||||
#define _Position_LocSource_MAX Position_LocSource_LOC_EXTERNAL
|
||||
#define _Position_LocSource_ARRAYSIZE ((Position_LocSource)(Position_LocSource_LOC_EXTERNAL+1))
|
||||
|
||||
#define _Position_AltSource_MIN Position_AltSource_ALTSRC_UNSPECIFIED
|
||||
#define _Position_AltSource_MAX Position_AltSource_ALTSRC_BAROMETRIC
|
||||
#define _Position_AltSource_ARRAYSIZE ((Position_AltSource)(Position_AltSource_ALTSRC_BAROMETRIC+1))
|
||||
#define _Position_AltSource_MIN Position_AltSource_ALT_UNSET
|
||||
#define _Position_AltSource_MAX Position_AltSource_ALT_BAROMETRIC
|
||||
#define _Position_AltSource_ARRAYSIZE ((Position_AltSource)(Position_AltSource_ALT_BAROMETRIC+1))
|
||||
|
||||
#define _Routing_Error_MIN Routing_Error_NONE
|
||||
#define _Routing_Error_MAX Routing_Error_NOT_AUTHORIZED
|
||||
@@ -731,9 +736,9 @@ extern "C" {
|
||||
#define Waypoint_init_default {0, 0, 0, 0, 0, "", ""}
|
||||
#define MeshPacket_init_default {0, 0, 0, 0, {Data_init_default}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN, 0, _MeshPacket_Delayed_MIN}
|
||||
#define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0, 0, false, DeviceMetrics_init_default}
|
||||
#define MyNodeInfo_init_default {0, 0, "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}
|
||||
#define MyNodeInfo_init_default {0, 0, 0, "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}
|
||||
#define LogRecord_init_default {"", 0, "", _LogRecord_Level_MIN}
|
||||
#define FromRadio_init_default {0, 0, {MyNodeInfo_init_default}}
|
||||
#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}}}
|
||||
@@ -745,9 +750,9 @@ extern "C" {
|
||||
#define Waypoint_init_zero {0, 0, 0, 0, 0, "", ""}
|
||||
#define MeshPacket_init_zero {0, 0, 0, 0, {Data_init_zero}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN, 0, _MeshPacket_Delayed_MIN}
|
||||
#define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0, 0, false, DeviceMetrics_init_zero}
|
||||
#define MyNodeInfo_init_zero {0, 0, "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}
|
||||
#define MyNodeInfo_init_zero {0, 0, 0, "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}
|
||||
#define LogRecord_init_zero {"", 0, "", _LogRecord_Level_MIN}
|
||||
#define FromRadio_init_zero {0, 0, {MyNodeInfo_init_zero}}
|
||||
#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}}}
|
||||
@@ -769,51 +774,51 @@ extern "C" {
|
||||
#define LogRecord_level_tag 4
|
||||
#define MyNodeInfo_my_node_num_tag 1
|
||||
#define MyNodeInfo_has_gps_tag 2
|
||||
#define MyNodeInfo_firmware_version_tag 6
|
||||
#define MyNodeInfo_error_code_tag 7
|
||||
#define MyNodeInfo_error_address_tag 8
|
||||
#define MyNodeInfo_error_count_tag 9
|
||||
#define MyNodeInfo_reboot_count_tag 10
|
||||
#define MyNodeInfo_bitrate_tag 11
|
||||
#define MyNodeInfo_message_timeout_msec_tag 13
|
||||
#define MyNodeInfo_min_app_version_tag 14
|
||||
#define MyNodeInfo_max_channels_tag 15
|
||||
#define MyNodeInfo_air_period_tx_tag 16
|
||||
#define MyNodeInfo_air_period_rx_tag 17
|
||||
#define MyNodeInfo_has_wifi_tag 18
|
||||
#define MyNodeInfo_channel_utilization_tag 19
|
||||
#define MyNodeInfo_air_util_tx_tag 20
|
||||
#define MyNodeInfo_max_channels_tag 3
|
||||
#define MyNodeInfo_firmware_version_tag 4
|
||||
#define MyNodeInfo_error_code_tag 5
|
||||
#define MyNodeInfo_error_address_tag 6
|
||||
#define MyNodeInfo_error_count_tag 7
|
||||
#define MyNodeInfo_reboot_count_tag 8
|
||||
#define MyNodeInfo_bitrate_tag 9
|
||||
#define MyNodeInfo_message_timeout_msec_tag 10
|
||||
#define MyNodeInfo_min_app_version_tag 11
|
||||
#define MyNodeInfo_air_period_tx_tag 12
|
||||
#define MyNodeInfo_air_period_rx_tag 13
|
||||
#define MyNodeInfo_has_wifi_tag 14
|
||||
#define MyNodeInfo_channel_utilization_tag 15
|
||||
#define MyNodeInfo_air_util_tx_tag 16
|
||||
#define Position_latitude_i_tag 1
|
||||
#define Position_longitude_i_tag 2
|
||||
#define Position_altitude_tag 3
|
||||
#define Position_time_tag 9
|
||||
#define Position_location_source_tag 10
|
||||
#define Position_altitude_source_tag 11
|
||||
#define Position_pos_timestamp_tag 12
|
||||
#define Position_pos_time_millis_tag 13
|
||||
#define Position_altitude_hae_tag 14
|
||||
#define Position_alt_geoid_sep_tag 15
|
||||
#define Position_PDOP_tag 16
|
||||
#define Position_HDOP_tag 17
|
||||
#define Position_VDOP_tag 18
|
||||
#define Position_gps_accuracy_tag 19
|
||||
#define Position_ground_speed_tag 20
|
||||
#define Position_ground_track_tag 21
|
||||
#define Position_fix_quality_tag 22
|
||||
#define Position_fix_type_tag 23
|
||||
#define Position_sats_in_view_tag 24
|
||||
#define Position_sensor_id_tag 25
|
||||
#define Position_pos_next_update_tag 40
|
||||
#define Position_pos_seq_number_tag 41
|
||||
#define RouteDiscovery_route_tag 2
|
||||
#define Position_time_tag 4
|
||||
#define Position_location_source_tag 5
|
||||
#define Position_altitude_source_tag 6
|
||||
#define Position_timestamp_tag 7
|
||||
#define Position_timestamp_millis_adjust_tag 8
|
||||
#define Position_altitude_hae_tag 9
|
||||
#define Position_altitude_geoidal_separation_tag 10
|
||||
#define Position_PDOP_tag 11
|
||||
#define Position_HDOP_tag 12
|
||||
#define Position_VDOP_tag 13
|
||||
#define Position_gps_accuracy_tag 14
|
||||
#define Position_ground_speed_tag 15
|
||||
#define Position_ground_track_tag 16
|
||||
#define Position_fix_quality_tag 17
|
||||
#define Position_fix_type_tag 18
|
||||
#define Position_sats_in_view_tag 19
|
||||
#define Position_sensor_id_tag 20
|
||||
#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
|
||||
#define User_macaddr_tag 4
|
||||
#define User_hw_model_tag 6
|
||||
#define User_is_licensed_tag 7
|
||||
#define User_hw_model_tag 5
|
||||
#define User_is_licensed_tag 6
|
||||
#define Waypoint_id_tag 1
|
||||
#define Waypoint_latitude_i_tag 2
|
||||
#define Waypoint_longitude_i_tag 3
|
||||
@@ -829,11 +834,11 @@ extern "C" {
|
||||
#define MeshPacket_id_tag 6
|
||||
#define MeshPacket_rx_time_tag 7
|
||||
#define MeshPacket_rx_snr_tag 8
|
||||
#define MeshPacket_hop_limit_tag 10
|
||||
#define MeshPacket_want_ack_tag 11
|
||||
#define MeshPacket_priority_tag 12
|
||||
#define MeshPacket_rx_rssi_tag 13
|
||||
#define MeshPacket_delayed_tag 15
|
||||
#define MeshPacket_hop_limit_tag 9
|
||||
#define MeshPacket_want_ack_tag 10
|
||||
#define MeshPacket_priority_tag 11
|
||||
#define MeshPacket_rx_rssi_tag 12
|
||||
#define MeshPacket_delayed_tag 13
|
||||
#define NodeInfo_num_tag 1
|
||||
#define NodeInfo_user_tag 2
|
||||
#define NodeInfo_position_tag 3
|
||||
@@ -844,43 +849,44 @@ extern "C" {
|
||||
#define Routing_route_reply_tag 2
|
||||
#define Routing_error_reason_tag 3
|
||||
#define FromRadio_id_tag 1
|
||||
#define FromRadio_packet_tag 2
|
||||
#define FromRadio_my_info_tag 3
|
||||
#define FromRadio_node_info_tag 4
|
||||
#define FromRadio_config_tag 6
|
||||
#define FromRadio_log_record_tag 7
|
||||
#define FromRadio_config_complete_id_tag 8
|
||||
#define FromRadio_rebooted_tag 9
|
||||
#define FromRadio_moduleConfig_tag 10
|
||||
#define FromRadio_packet_tag 11
|
||||
#define ToRadio_packet_tag 2
|
||||
#define ToRadio_peer_info_tag 3
|
||||
#define ToRadio_want_config_id_tag 100
|
||||
#define ToRadio_disconnect_tag 104
|
||||
#define FromRadio_config_tag 5
|
||||
#define FromRadio_log_record_tag 6
|
||||
#define FromRadio_config_complete_id_tag 7
|
||||
#define FromRadio_rebooted_tag 8
|
||||
#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
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
#define Position_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, SFIXED32, latitude_i, 1) \
|
||||
X(a, STATIC, SINGULAR, SFIXED32, longitude_i, 2) \
|
||||
X(a, STATIC, SINGULAR, INT32, altitude, 3) \
|
||||
X(a, STATIC, SINGULAR, FIXED32, time, 9) \
|
||||
X(a, STATIC, SINGULAR, UENUM, location_source, 10) \
|
||||
X(a, STATIC, SINGULAR, UENUM, altitude_source, 11) \
|
||||
X(a, STATIC, SINGULAR, FIXED32, pos_timestamp, 12) \
|
||||
X(a, STATIC, SINGULAR, INT32, pos_time_millis, 13) \
|
||||
X(a, STATIC, SINGULAR, SINT32, altitude_hae, 14) \
|
||||
X(a, STATIC, SINGULAR, SINT32, alt_geoid_sep, 15) \
|
||||
X(a, STATIC, SINGULAR, UINT32, PDOP, 16) \
|
||||
X(a, STATIC, SINGULAR, UINT32, HDOP, 17) \
|
||||
X(a, STATIC, SINGULAR, UINT32, VDOP, 18) \
|
||||
X(a, STATIC, SINGULAR, UINT32, gps_accuracy, 19) \
|
||||
X(a, STATIC, SINGULAR, UINT32, ground_speed, 20) \
|
||||
X(a, STATIC, SINGULAR, UINT32, ground_track, 21) \
|
||||
X(a, STATIC, SINGULAR, UINT32, fix_quality, 22) \
|
||||
X(a, STATIC, SINGULAR, UINT32, fix_type, 23) \
|
||||
X(a, STATIC, SINGULAR, UINT32, sats_in_view, 24) \
|
||||
X(a, STATIC, SINGULAR, UINT32, sensor_id, 25) \
|
||||
X(a, STATIC, SINGULAR, UINT32, pos_next_update, 40) \
|
||||
X(a, STATIC, SINGULAR, UINT32, pos_seq_number, 41)
|
||||
X(a, STATIC, SINGULAR, FIXED32, time, 4) \
|
||||
X(a, STATIC, SINGULAR, UENUM, location_source, 5) \
|
||||
X(a, STATIC, SINGULAR, UENUM, altitude_source, 6) \
|
||||
X(a, STATIC, SINGULAR, FIXED32, timestamp, 7) \
|
||||
X(a, STATIC, SINGULAR, INT32, timestamp_millis_adjust, 8) \
|
||||
X(a, STATIC, SINGULAR, SINT32, altitude_hae, 9) \
|
||||
X(a, STATIC, SINGULAR, SINT32, altitude_geoidal_separation, 10) \
|
||||
X(a, STATIC, SINGULAR, UINT32, PDOP, 11) \
|
||||
X(a, STATIC, SINGULAR, UINT32, HDOP, 12) \
|
||||
X(a, STATIC, SINGULAR, UINT32, VDOP, 13) \
|
||||
X(a, STATIC, SINGULAR, UINT32, gps_accuracy, 14) \
|
||||
X(a, STATIC, SINGULAR, UINT32, ground_speed, 15) \
|
||||
X(a, STATIC, SINGULAR, UINT32, ground_track, 16) \
|
||||
X(a, STATIC, SINGULAR, UINT32, fix_quality, 17) \
|
||||
X(a, STATIC, SINGULAR, UINT32, fix_type, 18) \
|
||||
X(a, STATIC, SINGULAR, UINT32, sats_in_view, 19) \
|
||||
X(a, STATIC, SINGULAR, UINT32, sensor_id, 20) \
|
||||
X(a, STATIC, SINGULAR, UINT32, next_update, 21) \
|
||||
X(a, STATIC, SINGULAR, UINT32, seq_number, 22)
|
||||
#define Position_CALLBACK NULL
|
||||
#define Position_DEFAULT NULL
|
||||
|
||||
@@ -889,13 +895,13 @@ X(a, STATIC, SINGULAR, STRING, id, 1) \
|
||||
X(a, STATIC, SINGULAR, STRING, long_name, 2) \
|
||||
X(a, STATIC, SINGULAR, STRING, short_name, 3) \
|
||||
X(a, STATIC, SINGULAR, FIXED_LENGTH_BYTES, macaddr, 4) \
|
||||
X(a, STATIC, SINGULAR, UENUM, hw_model, 6) \
|
||||
X(a, STATIC, SINGULAR, BOOL, is_licensed, 7)
|
||||
X(a, STATIC, SINGULAR, UENUM, hw_model, 5) \
|
||||
X(a, STATIC, SINGULAR, BOOL, is_licensed, 6)
|
||||
#define User_CALLBACK NULL
|
||||
#define User_DEFAULT NULL
|
||||
|
||||
#define RouteDiscovery_FIELDLIST(X, a) \
|
||||
X(a, STATIC, REPEATED, FIXED32, route, 2)
|
||||
X(a, STATIC, REPEATED, FIXED32, route, 1)
|
||||
#define RouteDiscovery_CALLBACK NULL
|
||||
#define RouteDiscovery_DEFAULT NULL
|
||||
|
||||
@@ -935,19 +941,19 @@ X(a, STATIC, SINGULAR, STRING, description, 7)
|
||||
X(a, STATIC, SINGULAR, FIXED32, from, 1) \
|
||||
X(a, STATIC, SINGULAR, FIXED32, to, 2) \
|
||||
X(a, STATIC, SINGULAR, UINT32, channel, 3) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,decoded,decoded), 4) \
|
||||
X(a, STATIC, ONEOF, BYTES, (payloadVariant,encrypted,encrypted), 5) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,decoded,decoded), 4) \
|
||||
X(a, STATIC, ONEOF, BYTES, (payload_variant,encrypted,encrypted), 5) \
|
||||
X(a, STATIC, SINGULAR, FIXED32, id, 6) \
|
||||
X(a, STATIC, SINGULAR, FIXED32, rx_time, 7) \
|
||||
X(a, STATIC, SINGULAR, FLOAT, rx_snr, 8) \
|
||||
X(a, STATIC, SINGULAR, UINT32, hop_limit, 10) \
|
||||
X(a, STATIC, SINGULAR, BOOL, want_ack, 11) \
|
||||
X(a, STATIC, SINGULAR, UENUM, priority, 12) \
|
||||
X(a, STATIC, SINGULAR, INT32, rx_rssi, 13) \
|
||||
X(a, STATIC, SINGULAR, UENUM, delayed, 15)
|
||||
X(a, STATIC, SINGULAR, UINT32, hop_limit, 9) \
|
||||
X(a, STATIC, SINGULAR, BOOL, want_ack, 10) \
|
||||
X(a, STATIC, SINGULAR, UENUM, priority, 11) \
|
||||
X(a, STATIC, SINGULAR, INT32, rx_rssi, 12) \
|
||||
X(a, STATIC, SINGULAR, UENUM, delayed, 13)
|
||||
#define MeshPacket_CALLBACK NULL
|
||||
#define MeshPacket_DEFAULT NULL
|
||||
#define MeshPacket_payloadVariant_decoded_MSGTYPE Data
|
||||
#define MeshPacket_payload_variant_decoded_MSGTYPE Data
|
||||
|
||||
#define NodeInfo_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT32, num, 1) \
|
||||
@@ -965,20 +971,20 @@ X(a, STATIC, OPTIONAL, MESSAGE, device_metrics, 6)
|
||||
#define MyNodeInfo_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT32, my_node_num, 1) \
|
||||
X(a, STATIC, SINGULAR, BOOL, has_gps, 2) \
|
||||
X(a, STATIC, SINGULAR, STRING, firmware_version, 6) \
|
||||
X(a, STATIC, SINGULAR, UENUM, error_code, 7) \
|
||||
X(a, STATIC, SINGULAR, UINT32, error_address, 8) \
|
||||
X(a, STATIC, SINGULAR, UINT32, error_count, 9) \
|
||||
X(a, STATIC, SINGULAR, UINT32, reboot_count, 10) \
|
||||
X(a, STATIC, SINGULAR, FLOAT, bitrate, 11) \
|
||||
X(a, STATIC, SINGULAR, UINT32, message_timeout_msec, 13) \
|
||||
X(a, STATIC, SINGULAR, UINT32, min_app_version, 14) \
|
||||
X(a, STATIC, SINGULAR, UINT32, max_channels, 15) \
|
||||
X(a, STATIC, REPEATED, UINT32, air_period_tx, 16) \
|
||||
X(a, STATIC, REPEATED, UINT32, air_period_rx, 17) \
|
||||
X(a, STATIC, SINGULAR, BOOL, has_wifi, 18) \
|
||||
X(a, STATIC, SINGULAR, FLOAT, channel_utilization, 19) \
|
||||
X(a, STATIC, SINGULAR, FLOAT, air_util_tx, 20)
|
||||
X(a, STATIC, SINGULAR, UINT32, max_channels, 3) \
|
||||
X(a, STATIC, SINGULAR, STRING, firmware_version, 4) \
|
||||
X(a, STATIC, SINGULAR, UENUM, error_code, 5) \
|
||||
X(a, STATIC, SINGULAR, UINT32, error_address, 6) \
|
||||
X(a, STATIC, SINGULAR, UINT32, error_count, 7) \
|
||||
X(a, STATIC, SINGULAR, UINT32, reboot_count, 8) \
|
||||
X(a, STATIC, SINGULAR, FLOAT, bitrate, 9) \
|
||||
X(a, STATIC, SINGULAR, UINT32, message_timeout_msec, 10) \
|
||||
X(a, STATIC, SINGULAR, UINT32, min_app_version, 11) \
|
||||
X(a, STATIC, REPEATED, UINT32, air_period_tx, 12) \
|
||||
X(a, STATIC, REPEATED, UINT32, air_period_rx, 13) \
|
||||
X(a, STATIC, SINGULAR, BOOL, has_wifi, 14) \
|
||||
X(a, STATIC, SINGULAR, FLOAT, channel_utilization, 15) \
|
||||
X(a, STATIC, SINGULAR, FLOAT, air_util_tx, 16)
|
||||
#define MyNodeInfo_CALLBACK NULL
|
||||
#define MyNodeInfo_DEFAULT NULL
|
||||
|
||||
@@ -992,32 +998,34 @@ X(a, STATIC, SINGULAR, UENUM, level, 4)
|
||||
|
||||
#define FromRadio_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT32, id, 1) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,my_info,my_info), 3) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,node_info,node_info), 4) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,config,config), 6) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,log_record,log_record), 7) \
|
||||
X(a, STATIC, ONEOF, UINT32, (payloadVariant,config_complete_id,config_complete_id), 8) \
|
||||
X(a, STATIC, ONEOF, BOOL, (payloadVariant,rebooted,rebooted), 9) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,moduleConfig,moduleConfig), 10) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,packet,packet), 11)
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,packet,packet), 2) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,my_info,my_info), 3) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,node_info,node_info), 4) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,config,config), 5) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,log_record,log_record), 6) \
|
||||
X(a, STATIC, ONEOF, UINT32, (payload_variant,config_complete_id,config_complete_id), 7) \
|
||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,rebooted,rebooted), 8) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,moduleConfig,moduleConfig), 9) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,channel,channel), 10)
|
||||
#define FromRadio_CALLBACK NULL
|
||||
#define FromRadio_DEFAULT NULL
|
||||
#define FromRadio_payloadVariant_my_info_MSGTYPE MyNodeInfo
|
||||
#define FromRadio_payloadVariant_node_info_MSGTYPE NodeInfo
|
||||
#define FromRadio_payloadVariant_config_MSGTYPE Config
|
||||
#define FromRadio_payloadVariant_log_record_MSGTYPE LogRecord
|
||||
#define FromRadio_payloadVariant_moduleConfig_MSGTYPE ModuleConfig
|
||||
#define FromRadio_payloadVariant_packet_MSGTYPE MeshPacket
|
||||
#define FromRadio_payload_variant_packet_MSGTYPE MeshPacket
|
||||
#define FromRadio_payload_variant_my_info_MSGTYPE MyNodeInfo
|
||||
#define FromRadio_payload_variant_node_info_MSGTYPE NodeInfo
|
||||
#define FromRadio_payload_variant_config_MSGTYPE Config
|
||||
#define FromRadio_payload_variant_log_record_MSGTYPE LogRecord
|
||||
#define FromRadio_payload_variant_moduleConfig_MSGTYPE ModuleConfig
|
||||
#define FromRadio_payload_variant_channel_MSGTYPE Channel
|
||||
|
||||
#define ToRadio_FIELDLIST(X, a) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,packet,packet), 2) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,peer_info,peer_info), 3) \
|
||||
X(a, STATIC, ONEOF, UINT32, (payloadVariant,want_config_id,want_config_id), 100) \
|
||||
X(a, STATIC, ONEOF, BOOL, (payloadVariant,disconnect,disconnect), 104)
|
||||
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_payloadVariant_packet_MSGTYPE MeshPacket
|
||||
#define ToRadio_payloadVariant_peer_info_MSGTYPE ToRadio_PeerInfo
|
||||
#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) \
|
||||
@@ -1068,9 +1076,9 @@ extern const pb_msgdesc_t Compressed_msg;
|
||||
#define FromRadio_size 330
|
||||
#define LogRecord_size 81
|
||||
#define MeshPacket_size 321
|
||||
#define MyNodeInfo_size 197
|
||||
#define NodeInfo_size 263
|
||||
#define Position_size 142
|
||||
#define MyNodeInfo_size 179
|
||||
#define NodeInfo_size 258
|
||||
#define Position_size 137
|
||||
#define RouteDiscovery_size 40
|
||||
#define Routing_size 42
|
||||
#define ToRadio_PeerInfo_size 8
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
/* Enum definitions */
|
||||
typedef enum _ModuleConfig_SerialConfig_Serial_Baud {
|
||||
ModuleConfig_SerialConfig_Serial_Baud_BAUD_Default = 0,
|
||||
ModuleConfig_SerialConfig_Serial_Baud_BAUD_DEFAULT = 0,
|
||||
ModuleConfig_SerialConfig_Serial_Baud_BAUD_110 = 1,
|
||||
ModuleConfig_SerialConfig_Serial_Baud_BAUD_300 = 2,
|
||||
ModuleConfig_SerialConfig_Serial_Baud_BAUD_600 = 3,
|
||||
@@ -30,20 +30,21 @@ typedef enum _ModuleConfig_SerialConfig_Serial_Baud {
|
||||
} ModuleConfig_SerialConfig_Serial_Baud;
|
||||
|
||||
typedef enum _ModuleConfig_SerialConfig_Serial_Mode {
|
||||
ModuleConfig_SerialConfig_Serial_Mode_MODE_Default = 0,
|
||||
ModuleConfig_SerialConfig_Serial_Mode_MODE_SIMPLE = 1,
|
||||
ModuleConfig_SerialConfig_Serial_Mode_MODE_PROTO = 2
|
||||
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;
|
||||
|
||||
typedef enum _ModuleConfig_CannedMessageConfig_InputEventChar {
|
||||
ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE = 0,
|
||||
ModuleConfig_CannedMessageConfig_InputEventChar_KEY_UP = 17,
|
||||
ModuleConfig_CannedMessageConfig_InputEventChar_KEY_DOWN = 18,
|
||||
ModuleConfig_CannedMessageConfig_InputEventChar_KEY_LEFT = 19,
|
||||
ModuleConfig_CannedMessageConfig_InputEventChar_KEY_RIGHT = 20,
|
||||
ModuleConfig_CannedMessageConfig_InputEventChar_KEY_SELECT = 10,
|
||||
ModuleConfig_CannedMessageConfig_InputEventChar_KEY_BACK = 27,
|
||||
ModuleConfig_CannedMessageConfig_InputEventChar_KEY_CANCEL = 24
|
||||
ModuleConfig_CannedMessageConfig_InputEventChar_NONE = 0,
|
||||
ModuleConfig_CannedMessageConfig_InputEventChar_UP = 17,
|
||||
ModuleConfig_CannedMessageConfig_InputEventChar_DOWN = 18,
|
||||
ModuleConfig_CannedMessageConfig_InputEventChar_LEFT = 19,
|
||||
ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT = 20,
|
||||
ModuleConfig_CannedMessageConfig_InputEventChar_SELECT = 10,
|
||||
ModuleConfig_CannedMessageConfig_InputEventChar_BACK = 27,
|
||||
ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL = 24
|
||||
} ModuleConfig_CannedMessageConfig_InputEventChar;
|
||||
|
||||
/* Struct definitions */
|
||||
@@ -113,7 +114,7 @@ typedef struct _ModuleConfig_TelemetryConfig {
|
||||
|
||||
/* Module Config */
|
||||
typedef struct _ModuleConfig {
|
||||
pb_size_t which_payloadVariant;
|
||||
pb_size_t which_payload_variant;
|
||||
union {
|
||||
/* TODO: REPLACE */
|
||||
ModuleConfig_MQTTConfig mqtt;
|
||||
@@ -129,22 +130,22 @@ typedef struct _ModuleConfig {
|
||||
ModuleConfig_TelemetryConfig telemetry;
|
||||
/* TODO: REPLACE */
|
||||
ModuleConfig_CannedMessageConfig canned_message;
|
||||
} payloadVariant;
|
||||
} payload_variant;
|
||||
} ModuleConfig;
|
||||
|
||||
|
||||
/* Helper constants for enums */
|
||||
#define _ModuleConfig_SerialConfig_Serial_Baud_MIN ModuleConfig_SerialConfig_Serial_Baud_BAUD_Default
|
||||
#define _ModuleConfig_SerialConfig_Serial_Baud_MIN ModuleConfig_SerialConfig_Serial_Baud_BAUD_DEFAULT
|
||||
#define _ModuleConfig_SerialConfig_Serial_Baud_MAX ModuleConfig_SerialConfig_Serial_Baud_BAUD_921600
|
||||
#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_MODE_Default
|
||||
#define _ModuleConfig_SerialConfig_Serial_Mode_MAX ModuleConfig_SerialConfig_Serial_Mode_MODE_PROTO
|
||||
#define _ModuleConfig_SerialConfig_Serial_Mode_ARRAYSIZE ((ModuleConfig_SerialConfig_Serial_Mode)(ModuleConfig_SerialConfig_Serial_Mode_MODE_PROTO+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_CannedMessageConfig_InputEventChar_MIN ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE
|
||||
#define _ModuleConfig_CannedMessageConfig_InputEventChar_MAX ModuleConfig_CannedMessageConfig_InputEventChar_KEY_BACK
|
||||
#define _ModuleConfig_CannedMessageConfig_InputEventChar_ARRAYSIZE ((ModuleConfig_CannedMessageConfig_InputEventChar)(ModuleConfig_CannedMessageConfig_InputEventChar_KEY_BACK+1))
|
||||
#define _ModuleConfig_CannedMessageConfig_InputEventChar_MIN ModuleConfig_CannedMessageConfig_InputEventChar_NONE
|
||||
#define _ModuleConfig_CannedMessageConfig_InputEventChar_MAX ModuleConfig_CannedMessageConfig_InputEventChar_BACK
|
||||
#define _ModuleConfig_CannedMessageConfig_InputEventChar_ARRAYSIZE ((ModuleConfig_CannedMessageConfig_InputEventChar)(ModuleConfig_CannedMessageConfig_InputEventChar_BACK+1))
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -212,7 +213,7 @@ extern "C" {
|
||||
#define ModuleConfig_TelemetryConfig_environment_update_interval_tag 2
|
||||
#define ModuleConfig_TelemetryConfig_environment_measurement_enabled_tag 3
|
||||
#define ModuleConfig_TelemetryConfig_environment_screen_enabled_tag 4
|
||||
#define ModuleConfig_TelemetryConfig_environment_display_fahrenheit_tag 7
|
||||
#define ModuleConfig_TelemetryConfig_environment_display_fahrenheit_tag 5
|
||||
#define ModuleConfig_mqtt_tag 1
|
||||
#define ModuleConfig_serial_tag 2
|
||||
#define ModuleConfig_external_notification_tag 3
|
||||
@@ -223,22 +224,22 @@ extern "C" {
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
#define ModuleConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,mqtt,payloadVariant.mqtt), 1) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,serial,payloadVariant.serial), 2) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,external_notification,payloadVariant.external_notification), 3) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,store_forward,payloadVariant.store_forward), 4) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,range_test,payloadVariant.range_test), 5) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,telemetry,payloadVariant.telemetry), 6) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,canned_message,payloadVariant.canned_message), 7)
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,mqtt,payload_variant.mqtt), 1) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,serial,payload_variant.serial), 2) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,external_notification,payload_variant.external_notification), 3) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,store_forward,payload_variant.store_forward), 4) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,range_test,payload_variant.range_test), 5) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,telemetry,payload_variant.telemetry), 6) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,canned_message,payload_variant.canned_message), 7)
|
||||
#define ModuleConfig_CALLBACK NULL
|
||||
#define ModuleConfig_DEFAULT NULL
|
||||
#define ModuleConfig_payloadVariant_mqtt_MSGTYPE ModuleConfig_MQTTConfig
|
||||
#define ModuleConfig_payloadVariant_serial_MSGTYPE ModuleConfig_SerialConfig
|
||||
#define ModuleConfig_payloadVariant_external_notification_MSGTYPE ModuleConfig_ExternalNotificationConfig
|
||||
#define ModuleConfig_payloadVariant_store_forward_MSGTYPE ModuleConfig_StoreForwardConfig
|
||||
#define ModuleConfig_payloadVariant_range_test_MSGTYPE ModuleConfig_RangeTestConfig
|
||||
#define ModuleConfig_payloadVariant_telemetry_MSGTYPE ModuleConfig_TelemetryConfig
|
||||
#define ModuleConfig_payloadVariant_canned_message_MSGTYPE ModuleConfig_CannedMessageConfig
|
||||
#define ModuleConfig_payload_variant_mqtt_MSGTYPE ModuleConfig_MQTTConfig
|
||||
#define ModuleConfig_payload_variant_serial_MSGTYPE ModuleConfig_SerialConfig
|
||||
#define ModuleConfig_payload_variant_external_notification_MSGTYPE ModuleConfig_ExternalNotificationConfig
|
||||
#define ModuleConfig_payload_variant_store_forward_MSGTYPE ModuleConfig_StoreForwardConfig
|
||||
#define ModuleConfig_payload_variant_range_test_MSGTYPE ModuleConfig_RangeTestConfig
|
||||
#define ModuleConfig_payload_variant_telemetry_MSGTYPE ModuleConfig_TelemetryConfig
|
||||
#define ModuleConfig_payload_variant_canned_message_MSGTYPE ModuleConfig_CannedMessageConfig
|
||||
|
||||
#define ModuleConfig_MQTTConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, BOOL, enabled, 1) \
|
||||
@@ -292,7 +293,7 @@ X(a, STATIC, SINGULAR, UINT32, device_update_interval, 1) \
|
||||
X(a, STATIC, SINGULAR, UINT32, environment_update_interval, 2) \
|
||||
X(a, STATIC, SINGULAR, BOOL, environment_measurement_enabled, 3) \
|
||||
X(a, STATIC, SINGULAR, BOOL, environment_screen_enabled, 4) \
|
||||
X(a, STATIC, SINGULAR, BOOL, environment_display_fahrenheit, 7)
|
||||
X(a, STATIC, SINGULAR, BOOL, environment_display_fahrenheit, 5)
|
||||
#define ModuleConfig_TelemetryConfig_CALLBACK NULL
|
||||
#define ModuleConfig_TelemetryConfig_DEFAULT NULL
|
||||
|
||||
|
||||
@@ -74,6 +74,11 @@ typedef enum _PortNum {
|
||||
Maintained by Github user a-f-G-U-C (a Meshtastic contributor)
|
||||
Project files at https://github.com/a-f-G-U-C/Meshtastic-ZPS */
|
||||
PortNum_ZPS_APP = 68,
|
||||
/* Used to let multiple instances of Linux native applications communicate
|
||||
as if they did using their LoRa chip.
|
||||
Maintained by GitHub user GUVWAF.
|
||||
Project files at https://github.com/GUVWAF/Meshtasticator */
|
||||
PortNum_SIMULATOR_APP = 69,
|
||||
/* Private applications should use portnums >= 256.
|
||||
To simplify initial development and testing you can use "PRIVATE_APP"
|
||||
in your code without needing to rebuild protobuf files (via [regen-protos.sh](https://github.com/meshtastic/Meshtastic-device/blob/master/bin/regen-protos.sh)) */
|
||||
|
||||
@@ -31,7 +31,7 @@ typedef enum _HardwareMessage_Type {
|
||||
(a special channel once multichannel support is included?) */
|
||||
typedef struct _HardwareMessage {
|
||||
/* What type of HardwareMessage is this? */
|
||||
HardwareMessage_Type typ;
|
||||
HardwareMessage_Type type;
|
||||
/* What gpios are we changing. Not used for all MessageTypes, see MessageType for details */
|
||||
uint64_t gpio_mask;
|
||||
/* For gpios that were listed in gpio_mask as valid, what are the signal levels for those gpios.
|
||||
@@ -55,13 +55,13 @@ extern "C" {
|
||||
#define HardwareMessage_init_zero {_HardwareMessage_Type_MIN, 0, 0}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define HardwareMessage_typ_tag 1
|
||||
#define HardwareMessage_type_tag 1
|
||||
#define HardwareMessage_gpio_mask_tag 2
|
||||
#define HardwareMessage_gpio_value_tag 3
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
#define HardwareMessage_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UENUM, typ, 1) \
|
||||
X(a, STATIC, SINGULAR, UENUM, type, 1) \
|
||||
X(a, STATIC, SINGULAR, UINT64, gpio_mask, 2) \
|
||||
X(a, STATIC, SINGULAR, UINT64, gpio_value, 3)
|
||||
#define HardwareMessage_CALLBACK NULL
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
/* TODO: REPLACE */
|
||||
typedef enum _TelemetrySensorType {
|
||||
/* No external telemetry sensor explicitly set */
|
||||
TelemetrySensorType_NotSet = 0,
|
||||
TelemetrySensorType_SENSOR_UNSET = 0,
|
||||
/* High accuracy temperature, pressure, humidity */
|
||||
TelemetrySensorType_BME280 = 1,
|
||||
/* High accuracy temperature, pressure, humidity, and air resistance */
|
||||
@@ -25,7 +25,15 @@ typedef enum _TelemetrySensorType {
|
||||
/* Moderate accuracy current and voltage */
|
||||
TelemetrySensorType_INA219 = 5,
|
||||
/* High accuracy temperature and pressure */
|
||||
TelemetrySensorType_BMP280 = 6
|
||||
TelemetrySensorType_BMP280 = 6,
|
||||
/* High accuracy temperature and humidity */
|
||||
TelemetrySensorType_SHTC3 = 7,
|
||||
/* High accuracy pressure */
|
||||
TelemetrySensorType_LPS22 = 8,
|
||||
/* 3-Axis magnetic sensor */
|
||||
TelemetrySensorType_QMC6310 = 9,
|
||||
/* 6-Axis inertial measurement sensor */
|
||||
TelemetrySensorType_QMI8658 = 10
|
||||
} TelemetrySensorType;
|
||||
|
||||
/* Struct definitions */
|
||||
@@ -76,9 +84,9 @@ typedef struct _Telemetry {
|
||||
|
||||
|
||||
/* Helper constants for enums */
|
||||
#define _TelemetrySensorType_MIN TelemetrySensorType_NotSet
|
||||
#define _TelemetrySensorType_MAX TelemetrySensorType_BMP280
|
||||
#define _TelemetrySensorType_ARRAYSIZE ((TelemetrySensorType)(TelemetrySensorType_BMP280+1))
|
||||
#define _TelemetrySensorType_MIN TelemetrySensorType_SENSOR_UNSET
|
||||
#define _TelemetrySensorType_MAX TelemetrySensorType_QMI8658
|
||||
#define _TelemetrySensorType_ARRAYSIZE ((TelemetrySensorType)(TelemetrySensorType_QMI8658+1))
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -48,8 +48,6 @@ using namespace httpsserver;
|
||||
HTTPClient httpClient;
|
||||
|
||||
#define DEST_FS_USES_LITTLEFS
|
||||
#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch))
|
||||
#define ESP_ARDUINO_VERSION ESP_ARDUINO_VERSION_VAL(1, 0, 4)
|
||||
|
||||
// We need to specify some content-type mapping, so the resources get delivered with the
|
||||
// right content type and are displayed correctly in the browser
|
||||
@@ -610,7 +608,7 @@ void handleReport(HTTPRequest *req, HTTPResponse *res)
|
||||
|
||||
// data->wifi
|
||||
String ipStr;
|
||||
if (config.wifi.mode == Config_WiFiConfig_WiFiMode_AccessPoint || config.wifi.mode == Config_WiFiConfig_WiFiMode_AccessPointHidden || isSoftAPForced()) {
|
||||
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());
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "target_specific.h"
|
||||
#include <DNSServer.h>
|
||||
#include <ESPmDNS.h>
|
||||
#include <esp_wifi.h>
|
||||
#include <WiFi.h>
|
||||
#include <WiFiUdp.h>
|
||||
|
||||
@@ -28,7 +29,7 @@ DNSServer dnsServer;
|
||||
WiFiUDP ntpUDP;
|
||||
|
||||
#ifndef DISABLE_NTP
|
||||
NTPClient timeClient(ntpUDP, config.device.ntp_server);
|
||||
NTPClient timeClient(ntpUDP, config.network.ntp_server);
|
||||
#endif
|
||||
|
||||
uint8_t wifiDisconnectReason = 0;
|
||||
@@ -59,10 +60,10 @@ static WifiSleepObserver wifiSleepObserver;
|
||||
|
||||
static int32_t reconnectWiFi()
|
||||
{
|
||||
const char *wifiName = config.wifi.ssid;
|
||||
const char *wifiPsw = config.wifi.psk;
|
||||
const char *wifiName = config.network.wifi_ssid;
|
||||
const char *wifiPsw = config.network.wifi_psk;
|
||||
|
||||
if (config.wifi.enabled && needReconnect && !WiFi.isConnected()) {
|
||||
if (config.network.wifi_enabled && needReconnect && !WiFi.isConnected()) {
|
||||
// if (radioConfig.has_preferences && needReconnect && !WiFi.isConnected()) {
|
||||
|
||||
if (!*wifiPsw) // Treat empty password as no password
|
||||
@@ -109,14 +110,9 @@ bool isSoftAPForced()
|
||||
|
||||
bool isWifiAvailable()
|
||||
{
|
||||
// If wifi status is connected, return true regardless of the radio configuration.
|
||||
if (isSoftAPForced()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *wifiName = config.wifi.ssid;
|
||||
if (config.network.wifi_enabled && ((config.network.wifi_ssid[0]) || forcedSoftAP)) {
|
||||
|
||||
if (*wifiName) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@@ -184,18 +180,18 @@ bool initWifi(bool forceSoftAP)
|
||||
{
|
||||
forcedSoftAP = forceSoftAP;
|
||||
|
||||
if (config.wifi.enabled && ((config.wifi.ssid[0]) || forceSoftAP)) {
|
||||
if (config.network.wifi_enabled && ((config.network.wifi_ssid[0]) || forceSoftAP)) {
|
||||
// if ((radioConfig.has_preferences && config.wifi.ssid[0]) || forceSoftAP) {
|
||||
const char *wifiName = config.wifi.ssid;
|
||||
const char *wifiPsw = config.wifi.psk;
|
||||
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.wifi.mode == Config_WiFiConfig_WiFiMode_AccessPoint) {
|
||||
} else if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT) {
|
||||
DEBUG_MSG("WiFi ... AP Mode\n");
|
||||
} else if (config.wifi.mode == Config_WiFiConfig_WiFiMode_AccessPointHidden) {
|
||||
} else if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN) {
|
||||
DEBUG_MSG("WiFi ... Hidden AP Mode\n");
|
||||
} else if (config.wifi.mode == Config_WiFiConfig_WiFiMode_Client) {
|
||||
} else if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_CLIENT) {
|
||||
DEBUG_MSG("WiFi ... Client Mode\n");
|
||||
} else {
|
||||
DEBUG_MSG("WiFi ... WiFi Disabled\n");
|
||||
@@ -207,7 +203,7 @@ bool initWifi(bool forceSoftAP)
|
||||
wifiPsw = NULL;
|
||||
|
||||
if (*wifiName || forceSoftAP) {
|
||||
if (config.wifi.mode == Config_WiFiConfig_WiFiMode_AccessPoint || config.wifi.mode == Config_WiFiConfig_WiFiMode_AccessPointHidden || forceSoftAP) {
|
||||
if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT || config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN || forceSoftAP) {
|
||||
|
||||
IPAddress apIP(192, 168, 42, 1);
|
||||
WiFi.onEvent(WiFiEvent);
|
||||
@@ -222,7 +218,7 @@ bool initWifi(bool forceSoftAP)
|
||||
} else {
|
||||
|
||||
// If AP is configured to be hidden hidden
|
||||
if (config.wifi.mode == Config_WiFiConfig_WiFiMode_AccessPointHidden) {
|
||||
if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN) {
|
||||
|
||||
// The configurations on softAP are from the espresif library
|
||||
int ok = WiFi.softAP(wifiName, wifiPsw, 1, 1, 4);
|
||||
@@ -258,7 +254,7 @@ bool initWifi(bool forceSoftAP)
|
||||
WiFi.onEvent(
|
||||
[](WiFiEvent_t event, WiFiEventInfo_t info) {
|
||||
Serial.print("\nWiFi lost connection. Reason: ");
|
||||
Serial.println(info.disconnected.reason);
|
||||
Serial.println(info.wifi_sta_disconnected.reason);
|
||||
|
||||
/*
|
||||
If we are disconnected from the AP for some reason,
|
||||
@@ -267,9 +263,9 @@ bool initWifi(bool forceSoftAP)
|
||||
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.disconnected.reason;
|
||||
wifiDisconnectReason = info.wifi_sta_disconnected.reason;
|
||||
},
|
||||
WiFiEvent_t::SYSTEM_EVENT_STA_DISCONNECTED);
|
||||
WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_DISCONNECTED);
|
||||
|
||||
DEBUG_MSG("JOINING WIFI soon: ssid=%s\n", wifiName);
|
||||
wifiReconnect = new Periodic("WifiConnect", reconnectWiFi);
|
||||
@@ -377,7 +373,7 @@ static void WiFiEvent(WiFiEvent_t event)
|
||||
|
||||
void handleDNSResponse()
|
||||
{
|
||||
if (config.wifi.mode == Config_WiFiConfig_WiFiMode_AccessPoint || config.wifi.mode == Config_WiFiConfig_WiFiMode_AccessPointHidden || isSoftAPForced()) {
|
||||
if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT || config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN || isSoftAPForced()) {
|
||||
dnsServer.processNextRequest();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
/// returns the encoded packet size
|
||||
size_t pb_encode_to_bytes(uint8_t *destbuf, size_t destbufsize, const pb_msgdesc_t *fields, const void *src_struct)
|
||||
{
|
||||
|
||||
pb_ostream_t stream = pb_ostream_from_buffer(destbuf, destbufsize);
|
||||
if (!pb_encode(&stream, fields, src_struct)) {
|
||||
DEBUG_MSG("Panic: can't encode protobuf reason='%s'\n", PB_GET_ERROR(&stream));
|
||||
|
||||
@@ -4,11 +4,12 @@
|
||||
|
||||
static WiFiServerPort *apiPort;
|
||||
|
||||
void initApiServer()
|
||||
void initApiServer(int port)
|
||||
{
|
||||
// Start API server on port 4403
|
||||
if (!apiPort) {
|
||||
apiPort = new WiFiServerPort();
|
||||
apiPort = new WiFiServerPort(port);
|
||||
DEBUG_MSG("API server listening on TCP port %d\n", port);
|
||||
apiPort->init();
|
||||
}
|
||||
}
|
||||
@@ -56,13 +57,11 @@ void WiFiServerPort::debugOut(char c)
|
||||
apiPort->openAPI->debugOut(c);
|
||||
}
|
||||
|
||||
#define MESHTASTIC_PORTNUM 4403
|
||||
|
||||
WiFiServerPort::WiFiServerPort() : WiFiServer(MESHTASTIC_PORTNUM), concurrency::OSThread("ApiServer") {}
|
||||
WiFiServerPort::WiFiServerPort(int port) : WiFiServer(port), concurrency::OSThread("ApiServer") {}
|
||||
|
||||
void WiFiServerPort::init()
|
||||
{
|
||||
DEBUG_MSG("API server listening on TCP port %d\n", MESHTASTIC_PORTNUM);
|
||||
begin();
|
||||
}
|
||||
|
||||
@@ -80,4 +79,4 @@ int32_t WiFiServerPort::runOnce()
|
||||
}
|
||||
|
||||
return 100; // only check occasionally for incoming connections
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ class WiFiServerPort : public WiFiServer, private concurrency::OSThread
|
||||
WiFiServerAPI *openAPI = NULL;
|
||||
|
||||
public:
|
||||
WiFiServerPort();
|
||||
explicit WiFiServerPort(int port);
|
||||
|
||||
void init();
|
||||
|
||||
@@ -55,4 +55,4 @@ class WiFiServerPort : public WiFiServer, private concurrency::OSThread
|
||||
int32_t runOnce() override;
|
||||
};
|
||||
|
||||
void initApiServer();
|
||||
void initApiServer(int port=4403);
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
#include "Channels.h"
|
||||
#include "MeshService.h"
|
||||
#include "NodeDB.h"
|
||||
#ifdef ARCH_ESP32
|
||||
#include "BleOta.h"
|
||||
#endif
|
||||
#include "Router.h"
|
||||
#include "configuration.h"
|
||||
#include "main.h"
|
||||
@@ -38,7 +41,7 @@ bool AdminModule::handleReceivedProtobuf(const MeshPacket &mp, AdminMessage *r)
|
||||
bool handled = false;
|
||||
assert(r);
|
||||
|
||||
switch (r->which_variant) {
|
||||
switch (r->which_payload_variant) {
|
||||
|
||||
/**
|
||||
* Getters
|
||||
@@ -103,6 +106,21 @@ bool AdminModule::handleReceivedProtobuf(const MeshPacket &mp, AdminMessage *r)
|
||||
rebootAtMsec = (s < 0) ? 0 : (millis() + s * 1000);
|
||||
break;
|
||||
}
|
||||
case AdminMessage_reboot_ota_seconds_tag: {
|
||||
int32_t s = r->reboot_ota_seconds;
|
||||
#ifdef ARCH_ESP32
|
||||
if (BleOta::getOtaAppVersion().isEmpty()) {
|
||||
DEBUG_MSG("No OTA firmware available, scheduling regular reboot in %d seconds\n", s);
|
||||
}else{
|
||||
BleOta::switchToOtaApp();
|
||||
DEBUG_MSG("Rebooting to OTA in %d seconds\n", s);
|
||||
}
|
||||
#else
|
||||
DEBUG_MSG("Not on ESP32, scheduling regular reboot in %d seconds\n", s);
|
||||
#endif
|
||||
rebootAtMsec = (s < 0) ? 0 : (millis() + s * 1000);
|
||||
break;
|
||||
}
|
||||
case AdminMessage_shutdown_seconds_tag: {
|
||||
int32_t s = r->shutdown_seconds;
|
||||
DEBUG_MSG("Shutdown in %d seconds\n", s);
|
||||
@@ -114,7 +132,18 @@ bool AdminModule::handleReceivedProtobuf(const MeshPacket &mp, AdminMessage *r)
|
||||
handleGetDeviceMetadata(mp);
|
||||
break;
|
||||
}
|
||||
|
||||
case AdminMessage_factory_reset_tag: {
|
||||
DEBUG_MSG("Initiating factory reset\n");
|
||||
nodeDB.factoryReset();
|
||||
rebootAtMsec = millis() + (5 * 1000);
|
||||
break;
|
||||
}
|
||||
case AdminMessage_nodedb_reset_tag: {
|
||||
DEBUG_MSG("Initiating node-db reset\n");
|
||||
nodeDB.resetNodes();
|
||||
rebootAtMsec = millis() + (5 * 1000);
|
||||
break;
|
||||
}
|
||||
#ifdef ARCH_PORTDUINO
|
||||
case AdminMessage_exit_simulator_tag:
|
||||
DEBUG_MSG("Exiting simulator\n");
|
||||
@@ -129,10 +158,10 @@ bool AdminModule::handleReceivedProtobuf(const MeshPacket &mp, AdminMessage *r)
|
||||
if (handleResult == AdminMessageHandleResult::HANDLED_WITH_RESPONSE) {
|
||||
myReply = allocDataProtobuf(res);
|
||||
} else if (mp.decoded.want_response) {
|
||||
DEBUG_MSG("We did not responded to a request that wanted a respond. req.variant=%d\n", r->which_variant);
|
||||
DEBUG_MSG("We did not responded to a request that wanted a respond. req.variant=%d\n", r->which_payload_variant);
|
||||
} else if (handleResult != AdminMessageHandleResult::HANDLED) {
|
||||
// Probably a message sent by us or sent to our local node. FIXME, we should avoid scanning these messages
|
||||
DEBUG_MSG("Ignoring nonrelevant admin %d\n", r->which_variant);
|
||||
DEBUG_MSG("Ignoring nonrelevant admin %d\n", r->which_payload_variant);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -164,55 +193,73 @@ void AdminModule::handleSetOwner(const User &o)
|
||||
owner.is_licensed = o.is_licensed;
|
||||
}
|
||||
|
||||
if (changed) // If nothing really changed, don't broadcast on the network or write to flash
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void AdminModule::handleSetConfig(const Config &c)
|
||||
{
|
||||
bool requiresReboot = false;
|
||||
switch (c.which_payloadVariant) {
|
||||
bool isRouter = (config.device.role == Config_DeviceConfig_Role_ROUTER);
|
||||
bool isRegionUnset = (config.lora.region == Config_LoRaConfig_RegionCode_UNSET);
|
||||
|
||||
switch (c.which_payload_variant) {
|
||||
case Config_device_tag:
|
||||
DEBUG_MSG("Setting config: Device\n");
|
||||
config.has_device = true;
|
||||
config.device = c.payloadVariant.device;
|
||||
config.device = c.payload_variant.device;
|
||||
// If we're setting router role for the first time, install its intervals
|
||||
if (!isRouter &&
|
||||
c.payload_variant.device.role == Config_DeviceConfig_Role_ROUTER) {
|
||||
nodeDB.initConfigIntervals();
|
||||
nodeDB.initModuleConfigIntervals();
|
||||
}
|
||||
requiresReboot = true;
|
||||
break;
|
||||
case Config_position_tag:
|
||||
DEBUG_MSG("Setting config: Position\n");
|
||||
config.has_position = true;
|
||||
config.position = c.payloadVariant.position;
|
||||
config.position = c.payload_variant.position;
|
||||
break;
|
||||
case Config_power_tag:
|
||||
DEBUG_MSG("Setting config: Power\n");
|
||||
config.has_power = true;
|
||||
config.power = c.payloadVariant.power;
|
||||
config.power = c.payload_variant.power;
|
||||
break;
|
||||
case Config_wifi_tag:
|
||||
case Config_network_tag:
|
||||
DEBUG_MSG("Setting config: WiFi\n");
|
||||
config.has_wifi = true;
|
||||
config.wifi = c.payloadVariant.wifi;
|
||||
config.has_network = true;
|
||||
config.network = c.payload_variant.network;
|
||||
requiresReboot = true;
|
||||
break;
|
||||
case Config_display_tag:
|
||||
DEBUG_MSG("Setting config: Display\n");
|
||||
config.has_display = true;
|
||||
config.display = c.payloadVariant.display;
|
||||
config.display = c.payload_variant.display;
|
||||
break;
|
||||
case Config_lora_tag:
|
||||
DEBUG_MSG("Setting config: LoRa\n");
|
||||
config.has_lora = true;
|
||||
config.lora = c.payloadVariant.lora;
|
||||
config.lora = c.payload_variant.lora;
|
||||
if (isRegionUnset &&
|
||||
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.payloadVariant.bluetooth;
|
||||
config.bluetooth = c.payload_variant.bluetooth;
|
||||
requiresReboot = true;
|
||||
break;
|
||||
}
|
||||
|
||||
service.reloadConfig();
|
||||
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");
|
||||
@@ -223,45 +270,45 @@ void AdminModule::handleSetConfig(const Config &c)
|
||||
|
||||
void AdminModule::handleSetModuleConfig(const ModuleConfig &c)
|
||||
{
|
||||
switch (c.which_payloadVariant) {
|
||||
switch (c.which_payload_variant) {
|
||||
case ModuleConfig_mqtt_tag:
|
||||
DEBUG_MSG("Setting module config: MQTT\n");
|
||||
moduleConfig.has_mqtt = true;
|
||||
moduleConfig.mqtt = c.payloadVariant.mqtt;
|
||||
moduleConfig.mqtt = c.payload_variant.mqtt;
|
||||
break;
|
||||
case ModuleConfig_serial_tag:
|
||||
DEBUG_MSG("Setting module config: Serial\n");
|
||||
moduleConfig.has_serial = true;
|
||||
moduleConfig.serial = c.payloadVariant.serial;
|
||||
moduleConfig.serial = c.payload_variant.serial;
|
||||
break;
|
||||
case ModuleConfig_external_notification_tag:
|
||||
DEBUG_MSG("Setting module config: External Notification\n");
|
||||
moduleConfig.has_external_notification = true;
|
||||
moduleConfig.external_notification = c.payloadVariant.external_notification;
|
||||
moduleConfig.external_notification = c.payload_variant.external_notification;
|
||||
break;
|
||||
case ModuleConfig_store_forward_tag:
|
||||
DEBUG_MSG("Setting module config: Store & Forward\n");
|
||||
moduleConfig.has_store_forward = true;
|
||||
moduleConfig.store_forward = c.payloadVariant.store_forward;
|
||||
moduleConfig.store_forward = c.payload_variant.store_forward;
|
||||
break;
|
||||
case ModuleConfig_range_test_tag:
|
||||
DEBUG_MSG("Setting module config: Range Test\n");
|
||||
moduleConfig.has_range_test = true;
|
||||
moduleConfig.range_test = c.payloadVariant.range_test;
|
||||
moduleConfig.range_test = c.payload_variant.range_test;
|
||||
break;
|
||||
case ModuleConfig_telemetry_tag:
|
||||
DEBUG_MSG("Setting module config: Telemetry\n");
|
||||
moduleConfig.has_telemetry = true;
|
||||
moduleConfig.telemetry = c.payloadVariant.telemetry;
|
||||
moduleConfig.telemetry = c.payload_variant.telemetry;
|
||||
break;
|
||||
case ModuleConfig_canned_message_tag:
|
||||
DEBUG_MSG("Setting module config: Canned Message\n");
|
||||
moduleConfig.has_canned_message = true;
|
||||
moduleConfig.canned_message = c.payloadVariant.canned_message;
|
||||
moduleConfig.canned_message = c.payload_variant.canned_message;
|
||||
break;
|
||||
}
|
||||
|
||||
service.reloadConfig();
|
||||
service.reloadConfig(SEGMENT_MODULECONFIG);
|
||||
}
|
||||
|
||||
void AdminModule::handleSetChannel(const Channel &cc)
|
||||
@@ -282,7 +329,7 @@ void AdminModule::handleGetOwner(const MeshPacket &req)
|
||||
AdminMessage res = AdminMessage_init_default;
|
||||
res.get_owner_response = owner;
|
||||
|
||||
res.which_variant = AdminMessage_get_owner_response_tag;
|
||||
res.which_payload_variant = AdminMessage_get_owner_response_tag;
|
||||
myReply = allocDataProtobuf(res);
|
||||
}
|
||||
}
|
||||
@@ -295,39 +342,39 @@ void AdminModule::handleGetConfig(const MeshPacket &req, const uint32_t configTy
|
||||
switch (configType) {
|
||||
case AdminMessage_ConfigType_DEVICE_CONFIG:
|
||||
DEBUG_MSG("Getting config: Device\n");
|
||||
res.get_config_response.which_payloadVariant = Config_device_tag;
|
||||
res.get_config_response.payloadVariant.device = config.device;
|
||||
res.get_config_response.which_payload_variant = Config_device_tag;
|
||||
res.get_config_response.payload_variant.device = config.device;
|
||||
break;
|
||||
case AdminMessage_ConfigType_POSITION_CONFIG:
|
||||
DEBUG_MSG("Getting config: Position\n");
|
||||
res.get_config_response.which_payloadVariant = Config_position_tag;
|
||||
res.get_config_response.payloadVariant.position = config.position;
|
||||
res.get_config_response.which_payload_variant = Config_position_tag;
|
||||
res.get_config_response.payload_variant.position = config.position;
|
||||
break;
|
||||
case AdminMessage_ConfigType_POWER_CONFIG:
|
||||
DEBUG_MSG("Getting config: Power\n");
|
||||
res.get_config_response.which_payloadVariant = Config_power_tag;
|
||||
res.get_config_response.payloadVariant.power = config.power;
|
||||
res.get_config_response.which_payload_variant = Config_power_tag;
|
||||
res.get_config_response.payload_variant.power = config.power;
|
||||
break;
|
||||
case AdminMessage_ConfigType_WIFI_CONFIG:
|
||||
DEBUG_MSG("Getting config: WiFi\n");
|
||||
res.get_config_response.which_payloadVariant = Config_wifi_tag;
|
||||
res.get_config_response.payloadVariant.wifi = config.wifi;
|
||||
writeSecret(res.get_config_response.payloadVariant.wifi.psk, config.wifi.psk);
|
||||
case AdminMessage_ConfigType_NETWORK_CONFIG:
|
||||
DEBUG_MSG("Getting config: Network\n");
|
||||
res.get_config_response.which_payload_variant = Config_network_tag;
|
||||
res.get_config_response.payload_variant.network = config.network;
|
||||
writeSecret(res.get_config_response.payload_variant.network.wifi_psk, config.network.wifi_psk);
|
||||
break;
|
||||
case AdminMessage_ConfigType_DISPLAY_CONFIG:
|
||||
DEBUG_MSG("Getting config: Display\n");
|
||||
res.get_config_response.which_payloadVariant = Config_display_tag;
|
||||
res.get_config_response.payloadVariant.display = config.display;
|
||||
res.get_config_response.which_payload_variant = Config_display_tag;
|
||||
res.get_config_response.payload_variant.display = config.display;
|
||||
break;
|
||||
case AdminMessage_ConfigType_LORA_CONFIG:
|
||||
DEBUG_MSG("Getting config: LoRa\n");
|
||||
res.get_config_response.which_payloadVariant = Config_lora_tag;
|
||||
res.get_config_response.payloadVariant.lora = config.lora;
|
||||
res.get_config_response.which_payload_variant = Config_lora_tag;
|
||||
res.get_config_response.payload_variant.lora = config.lora;
|
||||
break;
|
||||
case AdminMessage_ConfigType_BLUETOOTH_CONFIG:
|
||||
DEBUG_MSG("Getting config: Bluetooth\n");
|
||||
res.get_config_response.which_payloadVariant = Config_bluetooth_tag;
|
||||
res.get_config_response.payloadVariant.bluetooth = config.bluetooth;
|
||||
res.get_config_response.which_payload_variant = Config_bluetooth_tag;
|
||||
res.get_config_response.payload_variant.bluetooth = config.bluetooth;
|
||||
break;
|
||||
}
|
||||
// NOTE: The phone app needs to know the ls_secs value so it can properly expect sleep behavior.
|
||||
@@ -337,7 +384,7 @@ void AdminModule::handleGetConfig(const MeshPacket &req, const uint32_t configTy
|
||||
// hideSecret(r.get_radio_response.preferences.wifi_ssid); // hmm - leave public for now, because only minimally private
|
||||
// and useful for users to know current provisioning) hideSecret(r.get_radio_response.preferences.wifi_password);
|
||||
// r.get_config_response.which_payloadVariant = Config_ModuleConfig_telemetry_tag;
|
||||
res.which_variant = AdminMessage_get_config_response_tag;
|
||||
res.which_payload_variant = AdminMessage_get_config_response_tag;
|
||||
myReply = allocDataProtobuf(res);
|
||||
}
|
||||
}
|
||||
@@ -350,39 +397,39 @@ void AdminModule::handleGetModuleConfig(const MeshPacket &req, const uint32_t co
|
||||
switch (configType) {
|
||||
case AdminMessage_ModuleConfigType_MQTT_CONFIG:
|
||||
DEBUG_MSG("Getting module config: MQTT\n");
|
||||
res.get_module_config_response.which_payloadVariant = ModuleConfig_mqtt_tag;
|
||||
res.get_module_config_response.payloadVariant.mqtt = moduleConfig.mqtt;
|
||||
res.get_module_config_response.which_payload_variant = ModuleConfig_mqtt_tag;
|
||||
res.get_module_config_response.payload_variant.mqtt = moduleConfig.mqtt;
|
||||
break;
|
||||
case AdminMessage_ModuleConfigType_SERIAL_CONFIG:
|
||||
DEBUG_MSG("Getting module config: Serial\n");
|
||||
res.get_module_config_response.which_payloadVariant = ModuleConfig_serial_tag;
|
||||
res.get_module_config_response.payloadVariant.serial = moduleConfig.serial;
|
||||
res.get_module_config_response.which_payload_variant = ModuleConfig_serial_tag;
|
||||
res.get_module_config_response.payload_variant.serial = moduleConfig.serial;
|
||||
break;
|
||||
case AdminMessage_ModuleConfigType_EXTNOTIF_CONFIG:
|
||||
DEBUG_MSG("Getting module config: External Notification\n");
|
||||
res.get_module_config_response.which_payloadVariant = ModuleConfig_external_notification_tag;
|
||||
res.get_module_config_response.payloadVariant.external_notification =
|
||||
res.get_module_config_response.which_payload_variant = ModuleConfig_external_notification_tag;
|
||||
res.get_module_config_response.payload_variant.external_notification =
|
||||
moduleConfig.external_notification;
|
||||
break;
|
||||
case AdminMessage_ModuleConfigType_STOREFORWARD_CONFIG:
|
||||
DEBUG_MSG("Getting module config: Store & Forward\n");
|
||||
res.get_module_config_response.which_payloadVariant = ModuleConfig_store_forward_tag;
|
||||
res.get_module_config_response.payloadVariant.store_forward = moduleConfig.store_forward;
|
||||
res.get_module_config_response.which_payload_variant = ModuleConfig_store_forward_tag;
|
||||
res.get_module_config_response.payload_variant.store_forward = moduleConfig.store_forward;
|
||||
break;
|
||||
case AdminMessage_ModuleConfigType_RANGETEST_CONFIG:
|
||||
DEBUG_MSG("Getting module config: Range Test\n");
|
||||
res.get_module_config_response.which_payloadVariant = ModuleConfig_range_test_tag;
|
||||
res.get_module_config_response.payloadVariant.range_test = moduleConfig.range_test;
|
||||
res.get_module_config_response.which_payload_variant = ModuleConfig_range_test_tag;
|
||||
res.get_module_config_response.payload_variant.range_test = moduleConfig.range_test;
|
||||
break;
|
||||
case AdminMessage_ModuleConfigType_TELEMETRY_CONFIG:
|
||||
DEBUG_MSG("Getting module config: Telemetry\n");
|
||||
res.get_module_config_response.which_payloadVariant = ModuleConfig_telemetry_tag;
|
||||
res.get_module_config_response.payloadVariant.telemetry = moduleConfig.telemetry;
|
||||
res.get_module_config_response.which_payload_variant = ModuleConfig_telemetry_tag;
|
||||
res.get_module_config_response.payload_variant.telemetry = moduleConfig.telemetry;
|
||||
break;
|
||||
case AdminMessage_ModuleConfigType_CANNEDMSG_CONFIG:
|
||||
DEBUG_MSG("Getting module config: Canned Message\n");
|
||||
res.get_module_config_response.which_payloadVariant = ModuleConfig_canned_message_tag;
|
||||
res.get_module_config_response.payloadVariant.canned_message = moduleConfig.canned_message;
|
||||
res.get_module_config_response.which_payload_variant = ModuleConfig_canned_message_tag;
|
||||
res.get_module_config_response.payload_variant.canned_message = moduleConfig.canned_message;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -393,7 +440,7 @@ void AdminModule::handleGetModuleConfig(const MeshPacket &req, const uint32_t co
|
||||
// hideSecret(r.get_radio_response.preferences.wifi_ssid); // hmm - leave public for now, because only minimally private
|
||||
// and useful for users to know current provisioning) hideSecret(r.get_radio_response.preferences.wifi_password);
|
||||
// r.get_config_response.which_payloadVariant = Config_ModuleConfig_telemetry_tag;
|
||||
res.which_variant = AdminMessage_get_module_config_response_tag;
|
||||
res.which_payload_variant = AdminMessage_get_module_config_response_tag;
|
||||
myReply = allocDataProtobuf(res);
|
||||
}
|
||||
}
|
||||
@@ -406,7 +453,7 @@ void AdminModule::handleGetDeviceMetadata(const MeshPacket &req) {
|
||||
deviceMetadata.device_state_version = DEVICESTATE_CUR_VER;
|
||||
|
||||
r.get_device_metadata_response = deviceMetadata;
|
||||
r.which_variant = AdminMessage_get_device_metadata_response_tag;
|
||||
r.which_payload_variant = AdminMessage_get_device_metadata_response_tag;
|
||||
myReply = allocDataProtobuf(r);
|
||||
}
|
||||
|
||||
@@ -416,7 +463,7 @@ void AdminModule::handleGetChannel(const MeshPacket &req, uint32_t channelIndex)
|
||||
// We create the reply here
|
||||
AdminMessage r = AdminMessage_init_default;
|
||||
r.get_channel_response = channels.getByIndex(channelIndex);
|
||||
r.which_variant = AdminMessage_get_channel_response_tag;
|
||||
r.which_payload_variant = AdminMessage_get_channel_response_tag;
|
||||
myReply = allocDataProtobuf(r);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,18 +2,41 @@
|
||||
#if HAS_SCREEN
|
||||
#include "CannedMessageModule.h"
|
||||
#include "FSCommon.h"
|
||||
#include "NodeDB.h"
|
||||
#include "MeshService.h"
|
||||
#include "PowerFSM.h" // neede for button bypass
|
||||
#include "mesh/generated/cannedmessages.pb.h"
|
||||
|
||||
// TODO: reuse defined from Screen.cpp
|
||||
#ifdef OLED_RU
|
||||
#include "graphics/fonts/OLEDDisplayFontsRU.h"
|
||||
#endif
|
||||
|
||||
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS)
|
||||
// The screen is bigger so use bigger fonts
|
||||
#define FONT_SMALL ArialMT_Plain_16
|
||||
#define FONT_MEDIUM ArialMT_Plain_24
|
||||
#define FONT_LARGE ArialMT_Plain_24
|
||||
#else
|
||||
#ifdef OLED_RU
|
||||
#define FONT_SMALL ArialMT_Plain_10_RU
|
||||
#else
|
||||
#define FONT_SMALL ArialMT_Plain_10
|
||||
#endif
|
||||
#define FONT_MEDIUM ArialMT_Plain_16
|
||||
#define FONT_LARGE ArialMT_Plain_24
|
||||
#endif
|
||||
|
||||
#define fontHeight(font) ((font)[1] + 1) // height is position 1
|
||||
|
||||
#define FONT_HEIGHT_SMALL fontHeight(FONT_SMALL)
|
||||
#define FONT_HEIGHT_MEDIUM fontHeight(FONT_MEDIUM)
|
||||
#define FONT_HEIGHT_LARGE fontHeight(FONT_LARGE)
|
||||
|
||||
// Remove Canned message screen if no action is taken for some milliseconds
|
||||
#define INACTIVATE_AFTER_MS 20000
|
||||
|
||||
extern uint8_t cardkb_found;
|
||||
|
||||
static const char *cannedMessagesConfigFile = "/prefs/cannedConf.proto";
|
||||
|
||||
CannedMessageModuleConfig cannedMessageModuleConfig;
|
||||
@@ -30,7 +53,7 @@ CannedMessageModule::CannedMessageModule()
|
||||
{
|
||||
if (moduleConfig.canned_message.enabled) {
|
||||
this->loadProtoForModule();
|
||||
if (this->splitConfiguredMessages() <= 0) {
|
||||
if ((this->splitConfiguredMessages() <= 0) && (cardkb_found != CARDKB_ADDR)) {
|
||||
DEBUG_MSG("CannedMessageModule: No messages are configured. Module is disabled\n");
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_DISABLED;
|
||||
} else {
|
||||
@@ -100,26 +123,64 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
|
||||
}
|
||||
|
||||
bool validEvent = false;
|
||||
if (event->inputEvent == static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_KEY_UP)) {
|
||||
if (event->inputEvent == static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_UP)) {
|
||||
DEBUG_MSG("Canned message event UP\n");
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_UP;
|
||||
validEvent = true;
|
||||
}
|
||||
if (event->inputEvent == static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_KEY_DOWN)) {
|
||||
if (event->inputEvent == static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_DOWN)) {
|
||||
DEBUG_MSG("Canned message event DOWN\n");
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_DOWN;
|
||||
validEvent = true;
|
||||
}
|
||||
if (event->inputEvent == static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_KEY_SELECT)) {
|
||||
if (event->inputEvent == static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_SELECT)) {
|
||||
DEBUG_MSG("Canned message event Select\n");
|
||||
// when inactive, call the onebutton shortpress instead. Activate Module only on up/down
|
||||
if ((this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_DISABLED)) {
|
||||
powerFSM.trigger(EVENT_PRESS);
|
||||
} else {
|
||||
this->payload = this->runState;
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_SELECT;
|
||||
validEvent = true;
|
||||
}
|
||||
}
|
||||
if (event->inputEvent == static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL)) {
|
||||
DEBUG_MSG("Canned message event Cancel\n");
|
||||
// emulate a timeout. Same result
|
||||
this->lastTouchMillis = 0;
|
||||
validEvent = true;
|
||||
}
|
||||
if ((event->inputEvent == static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_BACK)) ||
|
||||
(event->inputEvent == static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) ||
|
||||
(event->inputEvent == static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT))) {
|
||||
DEBUG_MSG("Canned message event (%x)\n",event->kbchar);
|
||||
if (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
|
||||
// pass the pressed key
|
||||
this->payload = event->kbchar;
|
||||
this->lastTouchMillis = millis();
|
||||
validEvent = true;
|
||||
}
|
||||
}
|
||||
if (event->inputEvent == static_cast<char>(ANYKEY)) {
|
||||
DEBUG_MSG("Canned message event any key pressed\n");
|
||||
// when inactive, this will switch to the freetext mode
|
||||
if ((this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_DISABLED)) {
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_FREETEXT;
|
||||
}
|
||||
// pass the pressed key
|
||||
this->payload = event->kbchar;
|
||||
this->lastTouchMillis = millis();
|
||||
validEvent = true;
|
||||
}
|
||||
if (event->inputEvent == static_cast<char>(MATRIXKEY)) {
|
||||
DEBUG_MSG("Canned message event Matrix key pressed\n");
|
||||
// this will send the text immediately on matrix press
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_SELECT;
|
||||
this->payload = event->kbchar;
|
||||
this->currentMessageIndex = event->kbchar -1;
|
||||
this->lastTouchMillis = millis();
|
||||
validEvent = true;
|
||||
}
|
||||
|
||||
if (validEvent) {
|
||||
// Let runOnce to be called immediately.
|
||||
@@ -142,7 +203,7 @@ void CannedMessageModule::sendText(NodeNum dest, const char *message, bool wantR
|
||||
p->decoded.payload.size++;
|
||||
}
|
||||
|
||||
DEBUG_MSG("Sending message id=%d, msg=%.*s\n", p->id, p->decoded.payload.size, p->decoded.payload.bytes);
|
||||
DEBUG_MSG("Sending message id=%d, dest=%x, msg=%.*s\n", p->id, p->to, p->decoded.payload.size, p->decoded.payload.bytes);
|
||||
|
||||
service.sendToMesh(p);
|
||||
}
|
||||
@@ -151,7 +212,7 @@ int32_t CannedMessageModule::runOnce()
|
||||
{
|
||||
if ((!moduleConfig.canned_message.enabled) || (this->runState == CANNED_MESSAGE_RUN_STATE_DISABLED) ||
|
||||
(this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE)) {
|
||||
return 30000; // TODO: should return MAX_VAL
|
||||
return INT32_MAX;
|
||||
}
|
||||
DEBUG_MSG("Check status\n");
|
||||
UIFrameEvent e = {false, true};
|
||||
@@ -160,33 +221,149 @@ int32_t CannedMessageModule::runOnce()
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
||||
e.frameChanged = true;
|
||||
this->currentMessageIndex = -1;
|
||||
this->freetext = ""; // clear freetext
|
||||
this->cursor = 0;
|
||||
this->destSelect = false;
|
||||
this->notifyObservers(&e);
|
||||
} else if ((this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) && (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 the lack of activity.\n");
|
||||
DEBUG_MSG("Reset due to lack of activity.\n");
|
||||
e.frameChanged = true;
|
||||
this->currentMessageIndex = -1;
|
||||
this->freetext = ""; // clear freetext
|
||||
this->cursor = 0;
|
||||
this->destSelect = false;
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
||||
this->notifyObservers(&e);
|
||||
} else if (this->currentMessageIndex == -1) {
|
||||
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_SELECT) {
|
||||
if (this->payload == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
|
||||
if (this->freetext.length() > 0) {
|
||||
sendText(this->dest, this->freetext.c_str(), true);
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE;
|
||||
} else {
|
||||
DEBUG_MSG("Reset message is empty.\n");
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
||||
}
|
||||
} else {
|
||||
if ((this->messagesCount > this->currentMessageIndex) && (strlen(this->messages[this->currentMessageIndex]) > 0)) {
|
||||
sendText(NODENUM_BROADCAST, this->messages[this->currentMessageIndex], true);
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE;
|
||||
} else {
|
||||
DEBUG_MSG("Reset message is empty.\n");
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
||||
}
|
||||
}
|
||||
e.frameChanged = true;
|
||||
this->currentMessageIndex = -1;
|
||||
this->freetext = ""; // clear freetext
|
||||
this->cursor = 0;
|
||||
this->destSelect = false;
|
||||
this->notifyObservers(&e);
|
||||
return 2000;
|
||||
} else if ((this->runState != CANNED_MESSAGE_RUN_STATE_FREETEXT) && (this->currentMessageIndex == -1)) {
|
||||
this->currentMessageIndex = 0;
|
||||
DEBUG_MSG("First touch (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage());
|
||||
e.frameChanged = true;
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
|
||||
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_SELECT) {
|
||||
sendText(NODENUM_BROADCAST, this->messages[this->currentMessageIndex], true);
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE;
|
||||
this->currentMessageIndex = -1;
|
||||
this->notifyObservers(&e);
|
||||
return 2000;
|
||||
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_UP) {
|
||||
this->currentMessageIndex = getPrevIndex();
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
|
||||
DEBUG_MSG("MOVE UP (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage());
|
||||
if (this->messagesCount > 0) {
|
||||
this->currentMessageIndex = getPrevIndex();
|
||||
this->freetext = ""; // clear freetext
|
||||
this->cursor = 0;
|
||||
this->destSelect = false;
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
|
||||
DEBUG_MSG("MOVE UP (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage());
|
||||
}
|
||||
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_DOWN) {
|
||||
this->currentMessageIndex = this->getNextIndex();
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
|
||||
DEBUG_MSG("MOVE DOWN (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage());
|
||||
if (this->messagesCount > 0) {
|
||||
this->currentMessageIndex = this->getNextIndex();
|
||||
this->freetext = ""; // clear freetext
|
||||
this->cursor = 0;
|
||||
this->destSelect = false;
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
|
||||
DEBUG_MSG("MOVE DOWN (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage());
|
||||
}
|
||||
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
|
||||
e.frameChanged = true;
|
||||
switch (this->payload) {
|
||||
case 0xb4: // left
|
||||
if (this->destSelect){
|
||||
size_t numNodes = nodeDB.getNumNodes();
|
||||
if(this->dest == NODENUM_BROADCAST) {
|
||||
this->dest = nodeDB.getNodeNum();
|
||||
}
|
||||
for (unsigned int i = 0; i < numNodes; i++) {
|
||||
if (nodeDB.getNodeByIndex(i)->num == this->dest) {
|
||||
this->dest = (i > 0) ? nodeDB.getNodeByIndex(i-1)->num : nodeDB.getNodeByIndex(numNodes-1)->num;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(this->dest == nodeDB.getNodeNum()) {
|
||||
this->dest = NODENUM_BROADCAST;
|
||||
}
|
||||
}else{
|
||||
if (this->cursor > 0) {
|
||||
this->cursor--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0xb7: // right
|
||||
if (this->destSelect){
|
||||
size_t numNodes = nodeDB.getNumNodes();
|
||||
if(this->dest == NODENUM_BROADCAST) {
|
||||
this->dest = nodeDB.getNodeNum();
|
||||
}
|
||||
for (unsigned int i = 0; i < numNodes; i++) {
|
||||
if (nodeDB.getNodeByIndex(i)->num == this->dest) {
|
||||
this->dest = (i < numNodes-1) ? nodeDB.getNodeByIndex(i+1)->num : nodeDB.getNodeByIndex(0)->num;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(this->dest == nodeDB.getNodeNum()) {
|
||||
this->dest = NODENUM_BROADCAST;
|
||||
}
|
||||
}else{
|
||||
if (this->cursor < this->freetext.length()) {
|
||||
this->cursor++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x08: // backspace
|
||||
if (this->freetext.length() > 0) {
|
||||
if(this->cursor == this->freetext.length()) {
|
||||
this->freetext = this->freetext.substring(0, this->freetext.length() - 1);
|
||||
} else {
|
||||
this->freetext = this->freetext.substring(0, this->cursor - 1) + this->freetext.substring(this->cursor, this->freetext.length());
|
||||
}
|
||||
this->cursor--;
|
||||
}
|
||||
break;
|
||||
case 0x09: // tab
|
||||
if(this->destSelect) {
|
||||
this->destSelect = false;
|
||||
} else {
|
||||
this->destSelect = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if(this->cursor == this->freetext.length()) {
|
||||
this->freetext += this->payload;
|
||||
} else {
|
||||
this->freetext = this->freetext.substring(0, this->cursor)
|
||||
+ this->payload
|
||||
+ this->freetext.substring(this->cursor);
|
||||
}
|
||||
this->cursor += 1;
|
||||
if (this->freetext.length() > Constants_DATA_PAYLOAD_LEN) {
|
||||
this->cursor = Constants_DATA_PAYLOAD_LEN;
|
||||
this->freetext = this->freetext.substring(0, Constants_DATA_PAYLOAD_LEN);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
this->lastTouchMillis = millis();
|
||||
this->notifyObservers(&e);
|
||||
return INACTIVATE_AFTER_MS;
|
||||
}
|
||||
|
||||
if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) {
|
||||
@@ -195,7 +372,7 @@ int32_t CannedMessageModule::runOnce()
|
||||
return INACTIVATE_AFTER_MS;
|
||||
}
|
||||
|
||||
return 30000; // TODO: should return MAX_VAL
|
||||
return INT32_MAX;
|
||||
}
|
||||
|
||||
const char *CannedMessageModule::getCurrentMessage()
|
||||
@@ -210,6 +387,19 @@ const char *CannedMessageModule::getNextMessage()
|
||||
{
|
||||
return this->messages[this->getNextIndex()];
|
||||
}
|
||||
const char* CannedMessageModule::getNodeName(NodeNum node) {
|
||||
if (node == NODENUM_BROADCAST){
|
||||
return "Broadcast";
|
||||
}else{
|
||||
NodeInfo *info = nodeDB.getNode(node);
|
||||
if(info != NULL) {
|
||||
return info->user.long_name;
|
||||
}else{
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CannedMessageModule::shouldDraw()
|
||||
{
|
||||
if (!moduleConfig.canned_message.enabled) {
|
||||
@@ -240,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);
|
||||
@@ -247,15 +439,32 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
|
||||
} else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_DISABLED) {
|
||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
display->setFont(FONT_SMALL);
|
||||
display->drawString(10 + x, 0 + y + 16, "Canned Message\nModule disabled.");
|
||||
} else {
|
||||
display->drawString(10 + x, 0 + y + FONT_HEIGHT_SMALL, "Canned Message\nModule disabled.");
|
||||
}else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
|
||||
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 + 8, cannedMessageModule->getCurrentMessage());
|
||||
display->setFont(FONT_SMALL);
|
||||
display->drawString(0 + x, 0 + y + 24, cannedMessageModule->getNextMessage());
|
||||
if (this->destSelect) {
|
||||
display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
|
||||
display->setColor(BLACK);
|
||||
}
|
||||
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());
|
||||
display->drawString(x + display->getWidth() - display->getStringWidth(buffer), y + 0, buffer);
|
||||
display->setColor(WHITE);
|
||||
display->drawStringMaxWidth(0 + x, 0 + y + FONT_HEIGHT_SMALL, x + display->getWidth(), cannedMessageModule->drawWithCursor(cannedMessageModule->freetext, cannedMessageModule->cursor));
|
||||
} else {
|
||||
if (this->messagesCount > 0) {
|
||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
display->setFont(FONT_SMALL);
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,7 +490,7 @@ bool CannedMessageModule::saveProtoForModule()
|
||||
FS.mkdir("/prefs");
|
||||
#endif
|
||||
|
||||
okay &= saveProto(cannedMessagesConfigFile, CannedMessageModuleConfig_size, sizeof(CannedMessageModuleConfig),
|
||||
okay &= saveProto(cannedMessagesConfigFile, CannedMessageModuleConfig_size, sizeof(cannedMessageModuleConfig),
|
||||
CannedMessageModuleConfig_fields, &cannedMessageModuleConfig);
|
||||
|
||||
return okay;
|
||||
@@ -309,7 +518,7 @@ AdminMessageHandleResult CannedMessageModule::handleAdminMessageForModule(const
|
||||
{
|
||||
AdminMessageHandleResult result;
|
||||
|
||||
switch (request->which_variant) {
|
||||
switch (request->which_payload_variant) {
|
||||
case AdminMessage_get_canned_message_module_messages_request_tag:
|
||||
DEBUG_MSG("Client is getting radio canned messages\n");
|
||||
this->handleGetCannedMessageModuleMessages(mp, response);
|
||||
@@ -334,7 +543,7 @@ void CannedMessageModule::handleGetCannedMessageModuleMessages(const MeshPacket
|
||||
DEBUG_MSG("*** handleGetCannedMessageModuleMessages\n");
|
||||
assert(req.decoded.want_response);
|
||||
|
||||
response->which_variant = AdminMessage_get_canned_message_module_messages_response_tag;
|
||||
response->which_payload_variant = AdminMessage_get_canned_message_module_messages_response_tag;
|
||||
strcpy(response->get_canned_message_module_messages_response, cannedMessageModuleConfig.messages);
|
||||
}
|
||||
|
||||
@@ -354,4 +563,12 @@ void CannedMessageModule::handleSetCannedMessageModuleMessages(const char *from_
|
||||
}
|
||||
}
|
||||
|
||||
String CannedMessageModule::drawWithCursor(String text, int cursor)
|
||||
{
|
||||
String result = text.substring(0, cursor)
|
||||
+ "_"
|
||||
+ text.substring(cursor);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -8,6 +8,7 @@ enum cannedMessageModuleRunState
|
||||
CANNED_MESSAGE_RUN_STATE_DISABLED,
|
||||
CANNED_MESSAGE_RUN_STATE_INACTIVE,
|
||||
CANNED_MESSAGE_RUN_STATE_ACTIVE,
|
||||
CANNED_MESSAGE_RUN_STATE_FREETEXT,
|
||||
CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE,
|
||||
CANNED_MESSAGE_RUN_STATE_ACTION_SELECT,
|
||||
CANNED_MESSAGE_RUN_STATE_ACTION_UP,
|
||||
@@ -34,6 +35,7 @@ class CannedMessageModule :
|
||||
const char* getCurrentMessage();
|
||||
const char* getPrevMessage();
|
||||
const char* getNextMessage();
|
||||
const char* getNodeName(NodeNum node);
|
||||
bool shouldDraw();
|
||||
void eventUp();
|
||||
void eventDown();
|
||||
@@ -42,6 +44,8 @@ class CannedMessageModule :
|
||||
void handleGetCannedMessageModuleMessages(const MeshPacket &req, AdminMessage *response);
|
||||
void handleSetCannedMessageModuleMessages(const char *from_msg);
|
||||
|
||||
String drawWithCursor(String text, int cursor);
|
||||
|
||||
protected:
|
||||
|
||||
virtual int32_t runOnce() override;
|
||||
@@ -70,6 +74,11 @@ class CannedMessageModule :
|
||||
|
||||
int currentMessageIndex = -1;
|
||||
cannedMessageModuleRunState runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
||||
char payload = 0x00;
|
||||
unsigned int cursor = 0;
|
||||
String freetext = ""; // Text Buffer for Freetext Editor
|
||||
bool destSelect = false; // Freetext Editor Mode
|
||||
NodeNum dest = NODENUM_BROADCAST;
|
||||
|
||||
char messageStore[CANNED_MESSAGE_MODULE_MESSAGES_SIZE+1];
|
||||
char *messages[CANNED_MESSAGE_MODULE_MESSAGE_MAX_COUNT];
|
||||
@@ -78,4 +87,4 @@ class CannedMessageModule :
|
||||
};
|
||||
|
||||
extern CannedMessageModule *cannedMessageModule;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include "input/RotaryEncoderInterruptImpl1.h"
|
||||
#include "input/UpDownInterruptImpl1.h"
|
||||
#include "input/cardKbI2cImpl.h"
|
||||
#include "input/facesKbI2cImpl.h"
|
||||
#include "modules/AdminModule.h"
|
||||
#include "modules/CannedMessageModule.h"
|
||||
#include "modules/NodeInfoModule.h"
|
||||
@@ -19,11 +18,13 @@
|
||||
#endif
|
||||
#ifdef ARCH_ESP32
|
||||
#include "modules/esp32/RangeTestModule.h"
|
||||
#include "modules/esp32/SerialModule.h"
|
||||
#include "modules/esp32/StoreForwardModule.h"
|
||||
#endif
|
||||
#if defined(ARCH_ESP32) || defined(ARCH_NRF52)
|
||||
#include "modules/ExternalNotificationModule.h"
|
||||
#if !defined(TTGO_T_ECHO)
|
||||
#include "modules/SerialModule.h"
|
||||
#endif
|
||||
#endif
|
||||
/**
|
||||
* Create module instances here. If you are adding a new module, you must 'new' it here (or somewhere else)
|
||||
@@ -51,8 +52,6 @@ void setupModules()
|
||||
upDownInterruptImpl1->init();
|
||||
cardKbI2cImpl = new CardKbI2cImpl();
|
||||
cardKbI2cImpl->init();
|
||||
facesKbI2cImpl = new FacesKbI2cImpl();
|
||||
facesKbI2cImpl->init();
|
||||
#endif
|
||||
#if HAS_SCREEN
|
||||
cannedMessageModule = new CannedMessageModule();
|
||||
|
||||
@@ -34,8 +34,8 @@ bool PositionModule::handleReceivedProtobuf(const MeshPacket &mp, Position *pptr
|
||||
// Log packet size and list of fields
|
||||
DEBUG_MSG("POSITION node=%08x l=%d %s%s%s%s%s%s%s%s%s%s%s%s%s\n", getFrom(&mp), mp.decoded.payload.size,
|
||||
p.latitude_i ? "LAT " : "", p.longitude_i ? "LON " : "", p.altitude ? "MSL " : "", p.altitude_hae ? "HAE " : "",
|
||||
p.alt_geoid_sep ? "GEO " : "", p.PDOP ? "PDOP " : "", p.HDOP ? "HDOP " : "", p.VDOP ? "VDOP " : "",
|
||||
p.sats_in_view ? "SIV " : "", p.fix_quality ? "FXQ " : "", p.fix_type ? "FXT " : "", p.pos_timestamp ? "PTS " : "",
|
||||
p.altitude_geoidal_separation ? "GEO " : "", p.PDOP ? "PDOP " : "", p.HDOP ? "HDOP " : "", p.VDOP ? "VDOP " : "",
|
||||
p.sats_in_view ? "SIV " : "", p.fix_quality ? "FXQ " : "", p.fix_type ? "FXT " : "", p.timestamp ? "PTS " : "",
|
||||
p.time ? "TIME " : "");
|
||||
|
||||
if (p.time) {
|
||||
@@ -58,6 +58,8 @@ MeshPacket *PositionModule::allocReply()
|
||||
NodeInfo *node = service.refreshMyNodeInfo(); // should guarantee there is now a position
|
||||
assert(node->has_position);
|
||||
|
||||
node->position.seq_number++;
|
||||
|
||||
// configuration of POSITION packet
|
||||
// consider making this a function argument?
|
||||
uint32_t pos_flags = config.position.position_flags;
|
||||
@@ -70,29 +72,38 @@ MeshPacket *PositionModule::allocReply()
|
||||
p.longitude_i = node->position.longitude_i;
|
||||
p.time = node->position.time;
|
||||
|
||||
if (pos_flags & Config_PositionConfig_PositionFlags_POS_ALTITUDE) {
|
||||
if (pos_flags & Config_PositionConfig_PositionFlags_POS_ALT_MSL)
|
||||
if (pos_flags & Config_PositionConfig_PositionFlags_ALTITUDE) {
|
||||
if (pos_flags & Config_PositionConfig_PositionFlags_ALTITUDE_MSL)
|
||||
p.altitude = node->position.altitude;
|
||||
else
|
||||
p.altitude_hae = node->position.altitude_hae;
|
||||
|
||||
if (pos_flags & Config_PositionConfig_PositionFlags_POS_GEO_SEP)
|
||||
p.alt_geoid_sep = node->position.alt_geoid_sep;
|
||||
if (pos_flags & Config_PositionConfig_PositionFlags_GEOIDAL_SEPARATION)
|
||||
p.altitude_geoidal_separation = node->position.altitude_geoidal_separation;
|
||||
}
|
||||
|
||||
if (pos_flags & Config_PositionConfig_PositionFlags_POS_DOP) {
|
||||
if (pos_flags & Config_PositionConfig_PositionFlags_POS_HVDOP) {
|
||||
if (pos_flags & Config_PositionConfig_PositionFlags_DOP) {
|
||||
if (pos_flags & Config_PositionConfig_PositionFlags_HVDOP) {
|
||||
p.HDOP = node->position.HDOP;
|
||||
p.VDOP = node->position.VDOP;
|
||||
} else
|
||||
p.PDOP = node->position.PDOP;
|
||||
}
|
||||
|
||||
if (pos_flags & Config_PositionConfig_PositionFlags_POS_SATINVIEW)
|
||||
if (pos_flags & Config_PositionConfig_PositionFlags_SATINVIEW)
|
||||
p.sats_in_view = node->position.sats_in_view;
|
||||
|
||||
if (pos_flags & Config_PositionConfig_PositionFlags_POS_TIMESTAMP)
|
||||
p.pos_timestamp = node->position.pos_timestamp;
|
||||
if (pos_flags & Config_PositionConfig_PositionFlags_TIMESTAMP)
|
||||
p.timestamp = node->position.timestamp;
|
||||
|
||||
if (pos_flags & Config_PositionConfig_PositionFlags_SEQ_NO)
|
||||
p.seq_number = node->position.seq_number;
|
||||
|
||||
if (pos_flags & Config_PositionConfig_PositionFlags_HEADING)
|
||||
p.ground_track = node->position.ground_track;
|
||||
|
||||
if (pos_flags & Config_PositionConfig_PositionFlags_SPEED)
|
||||
p.ground_speed = node->position.ground_speed;
|
||||
|
||||
// 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
|
||||
@@ -133,7 +144,7 @@ int32_t PositionModule::runOnce()
|
||||
if (lastGpsSend == 0 || (now - lastGpsSend) >= intervalMs) {
|
||||
|
||||
// Only send packets if the channel is less than 40% utilized.
|
||||
if (airTime->channelUtilizationPercent() < 40) {
|
||||
if (airTime->channelUtilizationPercent() < max_channel_util_percent) {
|
||||
if (node->has_position && (node->position.latitude_i != 0 || node->position.longitude_i != 0)) {
|
||||
lastGpsSend = now;
|
||||
|
||||
@@ -144,17 +155,17 @@ int32_t PositionModule::runOnce()
|
||||
bool requestReplies = currentGeneration != radioGeneration;
|
||||
currentGeneration = radioGeneration;
|
||||
|
||||
DEBUG_MSG("Sending pos@%x:6 to mesh (wantReplies=%d)\n", node->position.pos_timestamp, requestReplies);
|
||||
DEBUG_MSG("Sending pos@%x:6 to mesh (wantReplies=%d)\n", node->position.timestamp, requestReplies);
|
||||
sendOurPosition(NODENUM_BROADCAST, requestReplies);
|
||||
}
|
||||
} else {
|
||||
DEBUG_MSG("Channel utilization is >40 percent. Skipping this opportunity to send.\n");
|
||||
}
|
||||
|
||||
} else if (!config.position.position_broadcast_smart_disabled) {
|
||||
} else if (config.position.position_broadcast_smart_enabled) {
|
||||
|
||||
// Only send packets if the channel is less than 25% utilized.
|
||||
if (airTime->channelUtilizationPercent() < 25) {
|
||||
if (airTime->channelUtilizationPercent() < polite_channel_util_percent) {
|
||||
|
||||
NodeInfo *node2 = service.refreshMyNodeInfo(); // should guarantee there is now a position
|
||||
|
||||
@@ -183,7 +194,7 @@ int32_t PositionModule::runOnce()
|
||||
bool requestReplies = currentGeneration != radioGeneration;
|
||||
currentGeneration = radioGeneration;
|
||||
|
||||
DEBUG_MSG("Sending smart pos@%x:6 to mesh (wantReplies=%d, d=%d, dtt=%d, tt=%d)\n", node2->position.pos_timestamp,
|
||||
DEBUG_MSG("Sending smart pos@%x:6 to mesh (wantReplies=%d, d=%d, dtt=%d, tt=%d)\n", node2->position.timestamp,
|
||||
requestReplies, distance, distanceTravelThreshold, timeTravel);
|
||||
sendOurPosition(NODENUM_BROADCAST, requestReplies);
|
||||
|
||||
|
||||
@@ -55,9 +55,9 @@ RemoteHardwareModule::RemoteHardwareModule()
|
||||
bool RemoteHardwareModule::handleReceivedProtobuf(const MeshPacket &req, HardwareMessage *pptr)
|
||||
{
|
||||
auto p = *pptr;
|
||||
DEBUG_MSG("Received RemoteHardware typ=%d\n", p.typ);
|
||||
DEBUG_MSG("Received RemoteHardware typ=%d\n", p.type);
|
||||
|
||||
switch (p.typ) {
|
||||
switch (p.type) {
|
||||
case HardwareMessage_Type_WRITE_GPIOS:
|
||||
// Print notification to LCD screen
|
||||
screen->print("Write GPIOs\n");
|
||||
@@ -81,7 +81,7 @@ bool RemoteHardwareModule::handleReceivedProtobuf(const MeshPacket &req, Hardwar
|
||||
|
||||
// Send the reply
|
||||
HardwareMessage r = HardwareMessage_init_default;
|
||||
r.typ = HardwareMessage_Type_READ_GPIOS_REPLY;
|
||||
r.type = HardwareMessage_Type_READ_GPIOS_REPLY;
|
||||
r.gpio_value = res;
|
||||
r.gpio_mask = p.gpio_mask;
|
||||
MeshPacket *p2 = allocDataProtobuf(r);
|
||||
@@ -104,7 +104,7 @@ bool RemoteHardwareModule::handleReceivedProtobuf(const MeshPacket &req, Hardwar
|
||||
break; // Ignore - we might see our own replies
|
||||
|
||||
default:
|
||||
DEBUG_MSG("Hardware operation %d not yet implemented! FIXME\n", p.typ);
|
||||
DEBUG_MSG("Hardware operation %d not yet implemented! FIXME\n", p.type);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ int32_t RemoteHardwareModule::runOnce()
|
||||
|
||||
// Something changed! Tell the world with a broadcast message
|
||||
HardwareMessage r = HardwareMessage_init_default;
|
||||
r.typ = HardwareMessage_Type_GPIOS_CHANGED;
|
||||
r.type = HardwareMessage_Type_GPIOS_CHANGED;
|
||||
r.gpio_value = curVal;
|
||||
MeshPacket *p = allocDataProtobuf(r);
|
||||
service.sendToMesh(p);
|
||||
|
||||
@@ -27,8 +27,7 @@
|
||||
TXD 15
|
||||
3) Set timeout to the amount of time to wait before we consider
|
||||
your packet as "done".
|
||||
4) (Optional) In SerialModule.h set the port to PortNum_TEXT_MESSAGE_APP if you want to
|
||||
send messages to/from the general text message channel.
|
||||
4) not applicable any more
|
||||
5) Connect to your device over the serial interface at 38400 8N1.
|
||||
6) Send a packet up to 240 bytes in length. This will get relayed over the mesh network.
|
||||
7) (Optional) Set echo to 1 and any message you send out will be echoed back
|
||||
@@ -61,16 +60,25 @@ SerialModule::SerialModule() : concurrency::OSThread("SerialModule") {}
|
||||
|
||||
char serialStringChar[Constants_DATA_PAYLOAD_LEN];
|
||||
|
||||
SerialModuleRadio::SerialModuleRadio() : SinglePortModule("SerialModuleRadio", PortNum_SERIAL_APP)
|
||||
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;
|
||||
default:
|
||||
ourPortNum = PortNum_SERIAL_APP;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t SerialModule::runOnce()
|
||||
{
|
||||
#ifdef ARCH_ESP32
|
||||
|
||||
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(TTGO_T_ECHO)
|
||||
/*
|
||||
Uncomment the preferences below if you want to use the module
|
||||
without having to configure it from the PythonAPI or WebUI.
|
||||
@@ -91,7 +99,7 @@ int32_t SerialModule::runOnce()
|
||||
|
||||
uint32_t baud = 0;
|
||||
|
||||
if (moduleConfig.serial.baud == ModuleConfig_SerialConfig_Serial_Baud_BAUD_Default) {
|
||||
if (moduleConfig.serial.baud == ModuleConfig_SerialConfig_Serial_Baud_BAUD_DEFAULT) {
|
||||
baud = 38400;
|
||||
|
||||
} else if (moduleConfig.serial.baud == ModuleConfig_SerialConfig_Serial_Baud_BAUD_110) {
|
||||
@@ -140,23 +148,28 @@ int32_t SerialModule::runOnce()
|
||||
baud = 921600;
|
||||
}
|
||||
|
||||
#ifdef ARCH_ESP32
|
||||
Serial2.setRxBufferSize(RX_BUFFER);
|
||||
|
||||
if (moduleConfig.serial.rxd && moduleConfig.serial.txd) {
|
||||
Serial2.begin(baud, SERIAL_8N1, moduleConfig.serial.rxd, moduleConfig.serial.txd);
|
||||
|
||||
} else {
|
||||
Serial2.begin(baud, SERIAL_8N1, RXD2, TXD2);
|
||||
}
|
||||
#else
|
||||
if (moduleConfig.serial.rxd && moduleConfig.serial.txd)
|
||||
Serial2.setPins(moduleConfig.serial.rxd, moduleConfig.serial.txd);
|
||||
|
||||
Serial2.begin(baud, SERIAL_8N1);
|
||||
|
||||
#endif
|
||||
if (moduleConfig.serial.timeout) {
|
||||
Serial2.setTimeout(
|
||||
moduleConfig.serial.timeout); // Number of MS to wait to set the timeout for the string.
|
||||
|
||||
Serial2.setTimeout(moduleConfig.serial.timeout); // Number of MS to wait to set the timeout for the string.
|
||||
} else {
|
||||
Serial2.setTimeout(TIMEOUT); // Number of MS to wait to set the timeout for the string.
|
||||
}
|
||||
|
||||
Serial2.setRxBufferSize(RX_BUFFER);
|
||||
|
||||
serialModuleRadio = new SerialModuleRadio();
|
||||
|
||||
firstTime = 0;
|
||||
@@ -209,8 +222,7 @@ void SerialModuleRadio::sendPayload(NodeNum dest, bool wantReplies)
|
||||
|
||||
ProcessMessage SerialModuleRadio::handleReceived(const MeshPacket &mp)
|
||||
{
|
||||
#ifdef ARCH_ESP32
|
||||
|
||||
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(TTGO_T_ECHO)
|
||||
if (moduleConfig.serial.enabled) {
|
||||
|
||||
auto &p = mp.decoded;
|
||||
@@ -237,13 +249,12 @@ ProcessMessage SerialModuleRadio::handleReceived(const MeshPacket &mp)
|
||||
|
||||
} else {
|
||||
|
||||
if (moduleConfig.serial.mode == ModuleConfig_SerialConfig_Serial_Mode_MODE_Default ||
|
||||
moduleConfig.serial.mode == ModuleConfig_SerialConfig_Serial_Mode_MODE_SIMPLE) {
|
||||
// DEBUG_MSG("* * Message came from the mesh\n");
|
||||
// Serial2.println("* * Message came from the mesh");
|
||||
if (moduleConfig.serial.mode == ModuleConfig_SerialConfig_Serial_Mode_DEFAULT ||
|
||||
moduleConfig.serial.mode == ModuleConfig_SerialConfig_Serial_Mode_SIMPLE) {
|
||||
Serial2.printf("%s", p.payload.bytes);
|
||||
|
||||
} else if (moduleConfig.serial.mode == ModuleConfig_SerialConfig_Serial_Mode_MODE_PROTO) {
|
||||
} else if (moduleConfig.serial.mode == ModuleConfig_SerialConfig_Serial_Mode_PROTO) {
|
||||
// TODO this needs to be implemented
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user