Compare commits

...

135 Commits

Author SHA1 Message Date
Jm Casler
cf00ac593f Update to 1.3.21 2022-06-20 16:44:33 -07:00
Ben Meadors
7a50ab4de2 Re-init config_state after we switch to nodeinfo (#1526) 2022-06-20 13:28:50 -05:00
Ben Meadors
a7d527c3c3 Pins for m5stack-core 2022-06-20 12:41:03 -05:00
Mark Trevor Birss
2e2c485f4c M5Stack CoreInk Pins_Arduino.h (#1527)
* Update EInkDisplay2.cpp

* Create pins_arduino.h

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2022-06-20 12:33:44 -05:00
Ben Meadors
388865aba7 Dashes not underscores 2022-06-20 11:19:20 -05:00
Ben Meadors
21c6e595a1 Update build-all.sh 2022-06-20 11:18:30 -05:00
Ben Meadors
4a2522dbd3 Add m5stack core targets to release 2022-06-20 09:16:00 -05:00
Ben Meadors
877d72cbad Helps if you get the name right 2022-06-20 09:15:30 -05:00
Ben Meadors
63238cb810 Add m5stack core boards to CI 2022-06-20 09:13:27 -05:00
Mark Trevor Birss
e87c5d8d34 Update EInkDisplay2.cpp (#1524)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2022-06-20 09:08:35 -05:00
Ben Meadors
f9bbbfccb3 Fix typo 2022-06-18 14:03:58 -05:00
Ben Meadors
9a5ff935f9 Bump to 1.3.20 2022-06-17 16:40:33 -05:00
Ben Meadors
52f299ec49 Remove is_always_pwoered (#1525) 2022-06-17 13:35:12 -05:00
Ben Meadors
9285316c78 Upgrade to nanopb 0.4.6 (#1523) 2022-06-17 08:37:52 -05:00
Thomas Göttgens
c3c359c0cb Merge pull request #1519 from meshtastic/LocalConfig
Push of Config-Protos on PhoneAPI init
2022-06-17 08:47:41 +02:00
Thomas Göttgens
68465f294a Merge branch 'master' into LocalConfig 2022-06-16 21:59:55 +02:00
Thomas Göttgens
f63b876b71 Send config chunks one by one 2022-06-16 21:56:18 +02:00
Thomas Göttgens
22fca01323 Merge pull request #1522 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-06-16 21:41:23 +02:00
caveman99
d4a4bcf91a [create-pull-request] automated change 2022-06-16 19:31:21 +00:00
Thomas Göttgens
d726ed6e7c Merge pull request #1425 from holdenk/sketch
Configure bluetooth name based on owner's short name
2022-06-16 21:26:39 +02:00
Thomas Göttgens
349f6bf502 Merge branch 'master' into sketch 2022-06-16 21:13:19 +02:00
Thomas Göttgens
192c10d6d7 Merge pull request #1521 from meshtastic/1510-enhancement-change-default-device-name-from-unknown-xxxx-to-meshtastic-xxxx-to-match-ble-name
Fix #1510
2022-06-16 21:13:09 +02:00
Thomas Göttgens
be8fb73204 Merge branch 'master' into sketch 2022-06-16 20:59:11 +02:00
Thomas Göttgens
bc9a4367d1 Fix #1510 2022-06-16 20:58:15 +02:00
Thomas Göttgens
3d3511ceeb Change to a different logic 2022-06-16 20:54:50 +02:00
Ben Meadors
f3a433f906 Merge branch 'master' into LocalConfig 2022-06-16 08:10:20 -05:00
Jm Casler
3c6a2f7bb6 Bump to 1.3.19 2022-06-16 05:24:08 -07:00
Thomas Göttgens
1996a2a193 Merge pull request #1520 from meshtastic/radiolib-fix
Tryfix Portduino Radiolib
2022-06-16 12:30:23 +02:00
Thomas Göttgens
b40abbf3ad Tryfix Portduino Radiolib 2022-06-16 12:22:01 +02:00
Jm Casler
8684fd1c49 Bump to .18 2022-06-15 19:00:40 -07:00
Thomas Göttgens
49e47f3e6d Let's try this 2022-06-15 21:50:33 +02:00
Thomas Göttgens
d0a8a3018d Merge branch 'LocalConfig' of github.com:meshtastic/Meshtastic-device 2022-06-15 20:03:53 +02:00
Thomas Göttgens
7566ee1fea C++ is a weird language... 2022-06-15 20:03:08 +02:00
Thomas Göttgens
43d48d4fb9 Merge branch 'master' into LocalConfig 2022-06-15 19:43:47 +02:00
Thomas Göttgens
2a6633a666 Merge pull request #1518 from meshtastic/create-pull-request/patch
TEST: Push out LocalConfig Object on app Handshake
2022-06-15 19:43:05 +02:00
Thomas Göttgens
0146761850 TEST - Push of LocalConfig 2022-06-15 19:42:16 +02:00
caveman99
0943e5f500 [create-pull-request] automated change 2022-06-15 17:40:08 +00:00
Ben Meadors
a1dc350231 Changed default baud to 115200 (#1517)
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2022-06-15 11:44:37 -05:00
Thomas Göttgens
d5a258cebd Merge pull request #1516 from meshtastic/LocalConfig
add file version to local savefiles
2022-06-15 18:05:52 +02:00
Thomas Göttgens
125f76d984 Don't use rmdir_r but roll our own version. 2022-06-15 17:52:37 +02:00
Thomas Göttgens
b127479961 - Refactored factory reset a bit to not installDefaultDeviceState twice on ESP32
- clear BLE bonds on settings version increase
2022-06-15 17:09:42 +02:00
Thomas Göttgens
d18aa2e7cb add file version to local savefiles 2022-06-15 16:52:04 +02:00
Thomas Göttgens
d301144efe Merge pull request #1515 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-06-15 16:45:11 +02:00
caveman99
058b5ceddd [create-pull-request] automated change 2022-06-15 14:44:33 +00:00
Thomas Göttgens
e85baf00c4 Merge pull request #1511 from meshtastic/radiolib-fix
Set TX Power to some meaningful value
2022-06-13 23:24:37 +02:00
Thomas Göttgens
4a6cad6e46 Set TX Power to some meaningful value 2022-06-13 23:00:50 +02:00
Thomas Göttgens
bc05f98685 Merge pull request #1499 from meshtastic/radiolib-fix
new radiolib version (use upstream)
2022-06-13 21:33:51 +02:00
Thomas Göttgens
6e671d808a Our mod was accepted by RadioLib 2022-06-13 21:25:27 +02:00
Thomas Göttgens
1df3dd5f78 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-13 21:21:46 +02:00
Jm Casler
c9822dee93 Update to 1.13.17 2022-06-13 09:38:33 -07:00
Thomas Göttgens
e1783df49f Merge branch 'radiolib-fix' of github.com:meshtastic/Meshtastic-device
# Conflicts:
#	src/mesh/RadioLibInterface.h
2022-06-13 16:13:13 +02:00
Thomas Göttgens
6b8afdadc2 New variant of Radiolib patch 2022-06-13 16:10:16 +02:00
Thomas Göttgens
f918548e44 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-13 16:08:50 +02:00
GUVWAF
a1b07ed6aa Introduce contention window (CW) (#1500)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2022-06-13 08:21:18 -05:00
Thomas Göttgens
b059fb9e8e Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-13 12:23:51 +02:00
Ben Meadors
553b35d0ad Consolidate power saving prefs (#1507)
* Fixed conversion linter warning

* Power saving consolidation

* Whoops
2022-06-12 19:56:32 -05:00
Thomas Göttgens
04478081c6 Merge pull request #1508 from meshtastic/crpytfix
Remove nRF Crypt Debug
2022-06-12 23:52:16 +02:00
Thomas Göttgens
7bd07db2a8 Remove nRF Crypt Debug 2022-06-12 23:35:59 +02:00
Thomas Göttgens
5c44c4f772 Remove Debug Code for Encryption 2022-06-12 23:29:27 +02:00
Thomas Göttgens
7ff940409e Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-12 23:28:04 +02:00
Ben Meadors
cb5c32490c Merge branch 'master' into radiolib-fix 2022-06-12 15:27:58 -05:00
Thomas Göttgens
e0b63c6692 Merge pull request #1506 from meshtastic/1504-proposal-default-short-name-to-mac-last-4
implement #1504
2022-06-12 22:05:04 +02:00
Thomas Göttgens
dc8d1d9a84 implement #1504 2022-06-12 21:52:46 +02:00
Thomas Göttgens
710e2694ef Merge branch 'master' into radiolib-fix 2022-06-12 20:32:00 +02:00
Thomas Göttgens
7594140afc actual change to our interface 2022-06-12 20:31:23 +02:00
Thomas Göttgens
e793d933c6 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-12 20:28:39 +02:00
Thomas Göttgens
9d8f9613d4 Merge branch 'master' into sketch 2022-06-12 18:48:08 +02:00
Thomas Göttgens
61427528b6 Merge pull request #1505 from meshtastic/caveman99-patch-1
fix C++ warnings
2022-06-12 18:39:46 +02:00
Thomas Göttgens
47ad27f9f6 fix C++ warnings
The cast throws errors about ambiguous conversions. There's a prototype of requestFrom(uint8_t address, uint8_t length) so just use that one.
2022-06-12 17:59:16 +02:00
Thomas Göttgens
77f096e56c Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-12 17:37:43 +02:00
Ben Meadors
5106433572 Removed phone_timeout_secs pref references (#1503) 2022-06-12 09:44:23 -05:00
Ben Meadors
4458b470aa Don't enable environmental telemetry by default (#1502)
* INA219 + INA260 support in telemetry

* Protobuf update

* Fixes + debug statement

* Fix size

* Fix conversion from mv

* Added getRegisterValue for i2cscan

* Accidentally left this in

* Removed line
2022-06-12 07:14:33 -05:00
Ben Meadors
90957e6994 INA260 + INA219 sensor support (#1501)
* INA219 + INA260 support in telemetry

* Protobuf update

* Fixes + debug statement

* Fix size

* Fix conversion from mv

* Added getRegisterValue for i2cscan
2022-06-11 16:44:56 -05:00
Thomas Göttgens
b73fd32f71 Merge branch 'master' into radiolib-fix 2022-06-10 20:39:50 +02:00
Thomas Göttgens
2a3272b7d0 patch radiolib on-the-fly while building. 2022-06-10 20:38:56 +02:00
Ben Meadors
3fd756900a Refactoring some of the i2c boilerplate (#1498)
* Refactoring some of the i2c boilerplate

* Default value

* Debug statement
2022-06-10 12:04:04 -05:00
Thomas Göttgens
beb8bc9e72 Merge pull request #1496 from benner/fix/NodeDB_without_FSCom
Compile when FSCom is not defined (NodeDB.cpp)
2022-06-07 22:22:20 +02:00
Thomas Göttgens
1ad5cdc93c Merge branch 'master' into fix/NodeDB_without_FSCom 2022-06-07 21:57:26 +02:00
Nerijus Bendžiūnas
e8e72d2e08 Compile when FSCom is not defined (NodeDB.cpp) 2022-06-07 20:55:05 +03:00
Thomas Göttgens
1d0badd468 Merge pull request #1495 from benner/fix/typo
Correctly print script name in platformio-custom.py
2022-06-07 11:39:47 +02:00
Nerijus Bendžiūnas
9e87be4f22 Correctly print script name in platformio-custom.py 2022-06-07 12:26:01 +03:00
Jm Casler
97899aed26 1.3.16 2022-06-06 22:10:18 -07:00
Thomas Göttgens
0ee4ba4975 Merge pull request #1494 from meshtastic/fix-1493
fixes power LED on T-Echo and T-Beam
2022-06-06 19:23:23 +02:00
Thomas Göttgens
bbcccde787 Merge branch 'fix-1493' of github.com:meshtastic/Meshtastic-device 2022-06-06 19:15:14 +02:00
Thomas Göttgens
42c285bc31 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-06 19:14:43 +02:00
Thomas Göttgens
c831242f25 fix nrf build 2022-06-06 19:14:30 +02:00
Thomas Göttgens
3c6f36c8f7 Merge branch 'master' into fix-1493 2022-06-06 18:57:51 +02:00
Thomas Göttgens
dfde6cc9c1 Merge pull request #1490 from meshtastic/CryptFix
Crypt fix. Please leave branch open
2022-06-06 18:57:27 +02:00
Thomas Göttgens
7816800012 Merge branch 'master' into CryptFix 2022-06-06 18:49:38 +02:00
Thomas Göttgens
ebf132ad21 Bug-1493 2022-06-06 18:48:22 +02:00
Thomas Göttgens
67cf3018b5 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-06 18:27:28 +02:00
Ben Meadors
eafbef0c2f Scan for i2c sensors in environmental telemetry if enabled (#1492)
* Scan for i2c sensors in environmental telemetry if enabled

* Update TelemetrySensor.h

* Added surpression.

* Remove suppression and fix real bug

* Interrogate BME sensor id registers
2022-06-05 09:50:06 -05:00
Ben Meadors
4ab831c103 Fix nagging bool linter warnings (#1491) 2022-06-04 07:28:58 -05:00
Thomas Göttgens
3df5ec0b11 Merge pull request #1479 from meshtastic/ProtoFix
If we get an unreadable buffer, don't try to process it.
2022-06-04 11:07:00 +02:00
Thomas Göttgens
c5c2765fb4 Merge branch 'master' into ProtoFix 2022-06-04 10:49:36 +02:00
Thomas Göttgens
df9e9bc223 Bugfix for nRF Crypto 90% done, includes heavy debug code, do not merge for now. 2022-06-04 10:37:24 +02:00
Thomas Göttgens
1ff0032c20 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-04 10:35:42 +02:00
Jm Casler
18024f1d25 Merge pull request #1489 from mc-hamster/master
Disabled the unset welcome screen
2022-06-04 01:19:44 -07:00
Jm Casler
313c50d6cf Merge branch 'master' into master 2022-06-03 21:55:27 -07:00
Jm Casler
80e08f6de9 Disabled the unset welcome screen 2022-06-03 21:51:47 -07:00
Jm Casler
5a256323e2 Merge pull request #1488 from mc-hamster/master
Change default screen on to 10 minutes
2022-06-03 20:57:23 -07:00
Jm Casler
45495c51e6 Merge branch 'meshtastic:master' into master 2022-06-03 20:38:28 -07:00
Jm Casler
40ded630d0 Change default screen on to 10 minutes 2022-06-03 20:38:13 -07:00
Jm Casler
432d06741e Update version.properties 2022-06-03 18:49:18 -07:00
Jm Casler
03b7f2f837 Merge pull request #1487 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-06-03 18:47:52 -07:00
mc-hamster
2e1b895791 [create-pull-request] automated change 2022-06-04 01:47:29 +00:00
Jm Casler
9821a0535b Bump to 1.3.14 2022-06-03 14:32:32 -07:00
Thomas Göttgens
0b666b827d Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-03 15:38:50 +02:00
Thomas Göttgens
235cacf9b9 Merge pull request #1485 from markbirss/master
Update EInkDisplay2.cpp
2022-06-03 15:09:56 +02:00
Mark Trevor Birss
db28a1562e Update EInkDisplay2.cpp
Fix E-Ink not powering up bug at startup
2022-06-03 14:21:27 +02:00
Jm Casler
f61d2d9eb4 Merge pull request #1484 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-06-02 18:12:35 -07:00
mc-hamster
5aef58e87f [create-pull-request] automated change 2022-06-03 01:07:08 +00:00
Thomas Göttgens
77a2054254 Merge pull request #1480 from markbirss/master
Add M5Stack CoreInk 1.54 inch e-Ink - HopeRF95 Support
2022-06-01 20:56:05 +02:00
Mark Trevor Birss
48ee995e0d Update EInkDisplay2.cpp 2022-06-01 20:33:51 +02:00
Mark Trevor Birss
c7dfd245e3 Update EInkDisplay2.cpp 2022-06-01 20:31:39 +02:00
Mark Trevor Birss
4e813b098a Update platformio.ini 2022-06-01 20:30:21 +02:00
Thomas Göttgens
e57dbdd26c Merge branch 'master' into master 2022-06-01 20:28:12 +02:00
Mark Trevor Birss
9512ea45de Update EInkDisplay2.cpp 2022-06-01 19:27:38 +02:00
Mark Trevor Birss
0d09767efd Update variant.h 2022-06-01 18:11:06 +02:00
Mark Trevor Birss
5828e6f423 Update variant.h 2022-06-01 18:08:40 +02:00
Mark Trevor Birss
c7a9ce7f49 Update variant.h 2022-06-01 18:08:13 +02:00
Mark Trevor Birss
95f091041b Update variant.h 2022-06-01 17:53:19 +02:00
Mark Trevor Birss
f33e6a0e66 Update platformio.ini 2022-06-01 17:49:10 +02:00
Mark Trevor Birss
fe8bfdb762 Update variant.h 2022-06-01 17:48:31 +02:00
Thomas Göttgens
e8afd4fb4b If we get an unreadable buffer, don't try to process it. 2022-06-01 17:09:57 +02:00
Mark Trevor Birss
b34b26518b Update EInkDisplay2.cpp 2022-06-01 11:28:18 +02:00
Mark Trevor Birss
b9f25eb85c Update EInkDisplay2.cpp 2022-06-01 11:21:09 +02:00
Mark Trevor Birss
a7fbe024e4 Create variant.h 2022-06-01 11:12:45 +02:00
Mark Trevor Birss
1f7fee8e2a Create platformio.ini 2022-06-01 11:10:49 +02:00
Mark Trevor Birss
b8e7c6ee7a Update platformio.ini 2022-06-01 11:09:21 +02:00
Ben Meadors
06b2ed4ebe Merge branch 'master' into sketch 2022-05-30 18:07:40 -05:00
Ben Meadors
2ee003f2a1 Merge branch 'master' into sketch 2022-05-25 06:33:42 -05:00
Jm Casler
1ef70a2489 Merge branch 'master' into sketch 2022-05-24 00:23:17 -07:00
Holden Karau
ca3192b3dc Clear the existing data before we start advertising 2022-04-30 18:20:41 -07:00
Holden Karau
e1f28982cf When configured set meshtastic bluetooth name based on owner shortname. 2022-04-30 14:48:31 -07:00
92 changed files with 1302 additions and 751 deletions

View File

@@ -38,7 +38,9 @@ jobs:
- board: rak4631_eink
- board: t-echo
- board: nano-g1
- board: m5stack-core
- board: m5stack-coreink
runs-on: ubuntu-latest
steps:
- name: Checkout code
@@ -93,6 +95,8 @@ jobs:
- board: tbeam0.7
- board: meshtastic-diy-v1
- board: nano-g1
- board: m5stack-core
- board: m5stack-coreink
runs-on: ubuntu-latest
steps:

View File

@@ -17,9 +17,9 @@ jobs:
- name: Download nanopb
run: |
wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.5-linux-x86.tar.gz
tar xvzf nanopb-0.4.5-linux-x86.tar.gz
mv nanopb-0.4.5-linux-x86 nanopb-0.4.5
wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.6-linux-x86.tar.gz
tar xvzf nanopb-0.4.6-linux-x86.tar.gz
mv nanopb-0.4.6-linux-x86 nanopb-0.4.6
- name: Re-generate protocol buffers
run: |

View File

@@ -51,7 +51,8 @@
"iterator": "cpp",
"shared_mutex": "cpp",
"iostream": "cpp",
"esp_nimble_hci.h": "c"
"esp_nimble_hci.h": "c",
"map": "cpp"
},
"cSpell.words": [
"Blox",

View File

@@ -5,7 +5,7 @@ set -e
VERSION=`bin/buildinfo.py long`
SHORT_VERSION=`bin/buildinfo.py short`
BOARDS_ESP32="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"
BOARDS_ESP32="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 m5stack-core m5stack-coreink"
#BOARDS_ESP32=tbeam
# FIXME note nrf52840dk build is for some reason only generating a BIN file but not a HEX file nrf52840dk-geeksville is fine

View File

@@ -28,12 +28,12 @@ IF "__%FILENAME%__" == "____" (
)
IF EXIST %FILENAME% (
echo Trying to flash update %FILENAME%, but first erasing and writing system information"
%PYTHON% -m esptool --baud 921600 erase_flash
%PYTHON% -m esptool --baud 921600 write_flash 0x1000 system-info.bin
%PYTHON% -m esptool --baud 115200 erase_flash
%PYTHON% -m esptool --baud 115200 write_flash 0x1000 system-info.bin
for %%f in (littlefs-*.bin) do (
%PYTHON% -m esptool --baud 921600 write_flash 0x00390000 %%f
%PYTHON% -m esptool --baud 115200 write_flash 0x00390000 %%f
)
%PYTHON% -m esptool --baud 921600 write_flash 0x10000 %FILENAME%
%PYTHON% -m esptool --baud 115200 write_flash 0x10000 %FILENAME%
) else (
echo "Invalid file: %FILENAME%"
goto HELP

View File

@@ -28,9 +28,9 @@ IF "__%FILENAME%__" == "____" (
)
IF EXIST %FILENAME% (
echo Trying to flash update %FILENAME%
%PYTHON% -m esptool --baud 921600 write_flash 0x10000 %FILENAME%
%PYTHON% -m esptool --baud 115200 write_flash 0x10000 %FILENAME%
echo Erasing the otadata partition, which will turn off flash flippy-flop and force the first image to be used
%PYTHON% -m esptool --baud 921600 erase_region 0xe000 0x2000
%PYTHON% -m esptool --baud 115200 erase_region 0xe000 0x2000
) else (
echo "Invalid file: %FILENAME%"
goto HELP

View File

@@ -44,9 +44,9 @@ shift "$((OPTIND-1))"
if [ -f "${FILENAME}" ]; then
echo "Trying to flash update ${FILENAME}."
$PYTHON -m esptool --baud 921600 write_flash 0x10000 ${FILENAME}
$PYTHON -m esptool --baud 115200 write_flash 0x10000 ${FILENAME}
echo "Erasing the otadata partition, which will turn off flash flippy-flop and force the first image to be used"
$PYTHON -m esptool --baud 921600 erase_region 0xe000 0x2000
$PYTHON -m esptool --baud 115200 erase_region 0xe000 0x2000
else
echo "Invalid file: ${FILENAME}"
show_help

View File

@@ -17,7 +17,7 @@ Import("projenv")
prefsLoc = projenv["PROJECT_DIR"] + "/version.properties"
verObj = readProps(prefsLoc)
print("Using meshtastic platform-custom.py, firmare version " + verObj['long'])
print("Using meshtastic platformio-custom.py, firmare version " + verObj['long'])
# print("path is" + ','.join(sys.path))
# General options that are passed to the C and C++ compilers

View File

@@ -1,3 +1,3 @@
#!/usr/bin/env bash
esptool.py --baud 921600 read_flash 0x1000 0xf000 system-info.img
esptool.py --baud 115200 read_flash 0x1000 0xf000 system-info.img

View File

@@ -1 +1 @@
cd protobufs && ..\nanopb-0.4.5\generator-bin\protoc.exe --nanopb_out=-v:..\src\mesh\generated -I=..\protobufs *.proto
cd protobufs && ..\nanopb-0.4.6\generator-bin\protoc.exe --nanopb_out=-v:..\src\mesh\generated -I=..\protobufs *.proto

View File

@@ -2,13 +2,13 @@
set -e
echo "This script requires https://jpa.kapsi.fi/nanopb/download/ version 0.4.5 to be located in the"
echo "This script requires https://jpa.kapsi.fi/nanopb/download/ version 0.4.6 to be located in the"
echo "meshtastic-device root directory if the following step fails, you should download the correct"
echo "prebuilt binaries for your computer into nanopb-0.4.5"
echo "prebuilt binaries for your computer into nanopb-0.4.6"
# the nanopb tool seems to require that the .options file be in the current directory!
cd protobufs
../nanopb-0.4.5/generator-bin/protoc --nanopb_out=-v:../src/mesh/generated -I=../protobufs *.proto
../nanopb-0.4.6/generator-bin/protoc --nanopb_out=-v:../src/mesh/generated -I=../protobufs *.proto
#echo "Regenerating protobuf documentation - if you see an error message"
#echo "you can ignore it unless doing a new protobuf release to github."

View File

@@ -20,6 +20,7 @@ default_envs = tbeam
;default_envs = pca10059_diy_eink
;default_envs = meshtastic-diy-v1
;default_envs = meshtastic-diy-v1.1
;default_envs = m5stack-coreink
extra_configs = variants/*/platformio.ini
@@ -37,7 +38,7 @@ build_flags = -Wno-missing-field-initializers
-DTINYGPS_OPTION_NO_CUSTOM_FIELDS
-DPB_ENABLE_MALLOC=1
monitor_speed = 921600
monitor_speed = 115200
lib_deps =
https://github.com/meshtastic/esp8266-oled-ssd1306.git#53580644255b48ebb7a737343c6b4e71c7e11cf2 ; ESP8266_SSD1306
@@ -60,7 +61,8 @@ framework = arduino
lib_deps =
${env.lib_deps}
; Portduino is using meshtastic fork for now
https://github.com/jgromes/RadioLib.git#3df3b092ebf412bd0b26524e7b296733bd6a62f7
https://github.com/jgromes/RadioLib.git
build_flags = ${env.build_flags} -Os
# -DRADIOLIB_GODMODE
build_src_filter = ${env.build_src_filter} -<portduino/>
@@ -83,15 +85,17 @@ lib_deps =
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} -<nrf52/>
upload_speed = 921600
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

View File

@@ -10,7 +10,7 @@
#ifdef CONSOLE_MAX_BAUD
#define SERIAL_BAUD CONSOLE_MAX_BAUD
#else
#define SERIAL_BAUD 921600 // Serial debug baud rate
#define SERIAL_BAUD 115200 // Serial debug baud rate
#endif
#include "SerialConsole.h"

View File

@@ -28,6 +28,34 @@ void listDir(const char * dirname, uint8_t levels)
#endif
}
void rmDir(const char * dirname)
#ifdef FSCom
{
File root = FSCom.open(dirname);
if(!root){
return;
}
if(!root.isDirectory()){
return;
}
File file = root.openNextFile();
while(file){
if(file.isDirectory() && !String(file.name()).endsWith(".")) {
file.close();
rmDir(file.name());
FSCom.rmdir(file.name());
} else {
file.close();
FSCom.remove(file.name());
}
file.close();
file = root.openNextFile();
}
file.close();
#endif
}
void fsInit()
{
#ifdef FSCom

View File

@@ -26,4 +26,6 @@
using namespace Adafruit_LittleFS_Namespace;
#endif
void fsInit();
void fsInit();
void listDir(const char * dirname, uint8_t levels);
void rmDir(const char * dirname);

View File

@@ -5,6 +5,7 @@
#include "main.h"
#include "sleep.h"
#include "utils.h"
#include "buzz/buzz.h"
#ifdef TBEAM_V10
// FIXME. nasty hack cleanup how we load axp192
@@ -211,8 +212,12 @@ void Power::shutdown()
{
#ifdef TBEAM_V10
DEBUG_MSG("Shutting down\n");
axp.setChgLEDMode(AXP20X_LED_OFF);
axp.shutdown();
#elif NRF52_SERIES
playBeep();
ledOff(PIN_LED1);
ledOff(PIN_LED2);
doDeepSleep(DELAY_FOREVER);
#endif
}

View File

@@ -11,23 +11,23 @@
/// Should we behave as if we have AC power now?
static bool isPowered()
{
// Completely circumvents the battery / power sensing logic and assumes constant power source
if (config.power.is_always_powered) {
// Circumvent the battery sensing logic and assumes constant power if no battery pin or power mgmt IC
#if !defined(BATTERY_PIN) && !defined(AXP192_SLAVE_ADDRESS)
return true;
}
#endif
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
bool isLowPower = config.power.is_low_power || isRouter;
bool isPowerSavingMode = config.power.is_power_saving || isRouter;
/* To determine if we're externally powered, assumptions
1) If we're powered up and there's no battery, we must be getting power externally. (because we'd be dead otherwise)
2) If we detect USB power from the power management chip, we must be getting power externally.
*/
return !isLowPower && powerStatus && (!powerStatus->getHasBattery() || powerStatus->getHasUSB());
return !isPowerSavingMode && powerStatus && (!powerStatus->getHasBattery() || powerStatus->getHasUSB());
}
static void sdsEnter()
@@ -335,7 +335,7 @@ void PowerFSM_setup()
powerFSM.add_timed_transition(&stateON, &stateDARK,
config.display.screen_on_secs ? config.display.screen_on_secs
: 60 * 1000,
: 60 * 1000 * 10,
NULL, "Screen-on timeout");
// On most boards we use light-sleep to be our main state, but on NRF52 we just stay in DARK
@@ -348,9 +348,6 @@ void PowerFSM_setup()
// See: https://github.com/meshtastic/Meshtastic-device/issues/1071
if (isRouter || config.power.is_power_saving) {
// I don't think this transition is correct, turning off for now - @geeksville
// powerFSM.add_timed_transition(&stateDARK, &stateNB, getPref_phone_timeout_secs() * 1000, NULL, "Phone timeout");
powerFSM.add_timed_transition(&stateNB, &stateLS,
config.power.min_wake_secs ? config.power.min_wake_secs
: default_min_wake_secs * 1000,

View File

@@ -4,6 +4,8 @@
#include "configuration.h"
#define Port Serial
// Defaulting to the formerly removed phone_timeout_secs value of 15 minutes
#define SERIAL_CONNECTION_TIMEOUT (15 * 60) * 1000UL
SerialConsole *console;
@@ -41,13 +43,12 @@ SerialConsole::SerialConsole() : StreamAPI(&Port), RedirectablePrint(&Port)
emitRebooted();
}
// For the serial port we can't really detect if any client is on the other side, so instead just look for recent messages
bool SerialConsole::checkIsConnected()
{
uint32_t now = millis();
return (now - lastContactMsec) < config.power.phone_timeout_secs
? config.power.phone_timeout_secs
: default_phone_timeout_secs * 1000UL;
return (now - lastContactMsec) < SERIAL_CONNECTION_TIMEOUT;
}
/**

View File

@@ -25,6 +25,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#pragma once
#include <Arduino.h>
#ifdef RV3028_RTC
#include "Melopero_RV3028.h"
#endif
@@ -144,7 +145,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
//#define DISABLE_NTP
// Disable the welcome screen and allow
//#define DISABLE_WELCOME_UNSET
#define DISABLE_WELCOME_UNSET
// -----------------------------------------------------------------------------
// OLED & Input
@@ -170,6 +171,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// The older M5 Faces I2C Keyboard
#define FACESKB_ADDR 0x88
// -----------------------------------------------------------------------------
// SENSOR
// -----------------------------------------------------------------------------
#define BME_ADDR 0x76
#define BME_ADDR_ALTERNATE 0x77
#define MCP9808_ADDR 0x18
#define INA_ADDR 0x40
#define INA_ADDR_ALTERNATE 0x41
// -----------------------------------------------------------------------------
// GPS
// -----------------------------------------------------------------------------

View File

@@ -1,8 +1,27 @@
#include "../configuration.h"
#include "../main.h"
#include <Wire.h>
#include "mesh/generated/telemetry.pb.h"
#ifndef NO_WIRE
uint16_t getRegisterValue(uint8_t address, uint8_t reg, uint8_t length) {
uint16_t value = 0x00;
Wire.beginTransmission(address);
Wire.write(reg);
Wire.endTransmission();
delay(20);
Wire.requestFrom(address, length);
DEBUG_MSG("Wire.available() = %d\n", Wire.available());
if (Wire.available() == 2) {
// Read MSB, then LSB
value = (uint16_t)Wire.read() << 8;
value |= Wire.read();
} else if (Wire.available()) {
value = Wire.read();
}
return value;
}
uint8_t oled_probe(byte addr)
{
uint8_t r = 0;
@@ -34,7 +53,7 @@ uint8_t oled_probe(byte addr)
void scanI2Cdevice(void)
{
byte err, addr;
uint8_t r = 0x00;
uint16_t registerValue = 0x00;
int nDevices = 0;
for (addr = 1; addr < 127; addr++) {
Wire.beginTransmission(addr);
@@ -74,15 +93,8 @@ void scanI2Cdevice(void)
if (addr == CARDKB_ADDR) {
cardkb_found = addr;
// Do we have the RAK14006 instead?
Wire.beginTransmission(addr);
Wire.write(0x04); // SENSOR_GET_VERSION
Wire.endTransmission();
delay(20);
Wire.requestFrom((int)addr, 1);
if (Wire.available()) {
r = Wire.read();
}
if (r == 0x02) { // KEYPAD_VERSION
registerValue = getRegisterValue(addr, 0x04, 1);
if (registerValue == 0x02) { // KEYPAD_VERSION
DEBUG_MSG("RAK14004 found\n");
kb_model = 0x02;
} else {
@@ -104,6 +116,31 @@ void scanI2Cdevice(void)
DEBUG_MSG("axp192 PMU found\n");
}
#endif
if (addr == BME_ADDR || addr == BME_ADDR_ALTERNATE) {
registerValue = getRegisterValue(addr, 0xD0, 1); // GET_ID
if (registerValue == 0x61) {
DEBUG_MSG("BME-680 sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_BME680] = addr;
} else if (registerValue == 0x60) {
DEBUG_MSG("BME-280 sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_BME280] = addr;
}
}
if (addr == INA_ADDR || addr == INA_ADDR_ALTERNATE) {
registerValue = getRegisterValue(addr, 0xFE, 2);
DEBUG_MSG("Register MFG_UID: 0x%x\n", registerValue);
if (registerValue == 0x5449) {
DEBUG_MSG("INA260 sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_INA260] = addr;
} else { // Assume INA219 if INA260 ID is not found
DEBUG_MSG("INA219 sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_INA219] = addr;
}
}
if (addr == MCP9808_ADDR) {
nodeTelemetrySensorsMap[TelemetrySensorType_MCP9808] = addr;
DEBUG_MSG("MCP9808 sensor found at address 0x%x\n", (uint8_t)addr);
}
} else if (err == 4) {
DEBUG_MSG("Unknow error at address 0x%x\n", addr);
}

View File

@@ -54,7 +54,7 @@ class ESP32CryptoEngine : public CryptoEngine
static uint8_t scratch[MAX_BLOCKSIZE];
size_t nc_off = 0;
// DEBUG_MSG("ESP32 crypt fr=%x, num=%x, numBytes=%d!\n", fromNode, (uint32_t) packetId, numBytes);
DEBUG_MSG("ESP32 crypt fr=%x, num=%x, numBytes=%d!\n", fromNode, (uint32_t) packetId, numBytes);
initNonce(fromNode, packetId);
assert(numBytes <= MAX_BLOCKSIZE);
memcpy(scratch, bytes, numBytes);
@@ -68,8 +68,6 @@ class ESP32CryptoEngine : public CryptoEngine
virtual void decrypt(uint32_t fromNode, uint64_t packetId, size_t numBytes, uint8_t *bytes) override
{
// DEBUG_MSG("ESP32 decrypt!\n");
// For CTR, the implementation is the same
encrypt(fromNode, packetId, numBytes, bytes);
}

View File

@@ -31,6 +31,11 @@
//4.2 inch 300x400 - GxEPD2_420_M01
#define TECHO_DISPLAY_MODEL GxEPD2_420_M01
#elif defined(M5_COREINK)
//M5Stack CoreInk
//1.54 inch 200x200 - GxEPD2_154_M09
#define TECHO_DISPLAY_MODEL GxEPD2_154_M09
#endif
GxEPD2_BW<TECHO_DISPLAY_MODEL, TECHO_DISPLAY_MODEL::HEIGHT> *adafruitDisplay;
@@ -58,6 +63,12 @@ EInkDisplay::EInkDisplay(uint8_t address, int sda, int scl)
//GxEPD2_420_M01
setGeometry(GEOMETRY_RAWMODE, 300, 400);
#elif defined(M5_COREINK)
//M5Stack_CoreInk 200x200
//1.54 inch 200x200 - GxEPD2_154_M09
setGeometry(GEOMETRY_RAWMODE, EPD_HEIGHT, EPD_WIDTH);
#endif
// setGeometry(GEOMETRY_RAWMODE, 128, 64); // old resolution
// setGeometry(GEOMETRY_128_64); // We originally used this because I wasn't sure if rawmode worked - it does
@@ -108,7 +119,7 @@ bool EInkDisplay::forceDisplay(uint32_t msecLimit)
// 4.2 inch 300x400 - GxEPD2_420_M01
//adafruitDisplay->nextPage();
#elif defined(PCA10059)
#elif defined(PCA10059) || defined(M5_COREINK)
adafruitDisplay->nextPage();
#endif
@@ -180,35 +191,10 @@ bool EInkDisplay::connect()
adafruitDisplay->init(115200, true, 10, false, SPI1, SPISettings(4000000, MSBFIRST, SPI_MODE0));
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
adafruitDisplay->setRotation(3);
//For 1.54, 2.9 and 4.2
//adafruitDisplay->setRotation(1);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
//adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
} else {
(void)adafruitDisplay;
}
@@ -221,6 +207,12 @@ bool EInkDisplay::connect()
adafruitDisplay->setRotation(3);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
}
#elif defined(M5_COREINK)
auto lowLevel = new TECHO_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY);
adafruitDisplay = new GxEPD2_BW<TECHO_DISPLAY_MODEL, TECHO_DISPLAY_MODEL::HEIGHT>(*lowLevel);
adafruitDisplay->init(115200, true, 40, false, SPI, SPISettings(4000000, MSBFIRST, SPI_MODE0));
adafruitDisplay->setRotation(0);
adafruitDisplay->setPartialWindow(0, 0, EPD_WIDTH, EPD_HEIGHT);
#endif

View File

@@ -90,6 +90,9 @@ uint32_t serialSinceMsec;
bool axp192_found;
// Array map of sensor types (as array index) and i2c address as value we'll find in the i2c scan
uint8_t nodeTelemetrySensorsMap[12] = { 0, 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
const char *getDeviceName()
@@ -98,9 +101,15 @@ const char *getDeviceName()
getMacAddr(dmac);
// Meshtastic_ab3c
// Meshtastic_ab3c or Shortname_abcd
static char name[20];
sprintf(name, "Meshtastic_%02x%02x", dmac[4], dmac[5]);
sprintf(name, "%02x%02x", dmac[4], dmac[5]);
// if the shortname exists and is NOT the new default of ab3c, use it for BLE name.
if ((owner.short_name != NULL) && (owner.short_name != name)) {
sprintf(name, "%s_%02x%02x", owner.short_name, dmac[4], dmac[5]);
} else {
sprintf(name, "Meshtastic_%02x%02x", dmac[4], dmac[5]);
}
return name;
}

View File

@@ -1,9 +1,11 @@
#pragma once
#include <map>
#include "GPSStatus.h"
#include "NodeStatus.h"
#include "PowerStatus.h"
#include "graphics/Screen.h"
#include "mesh/generated/telemetry.pb.h"
extern uint8_t screen_found;
extern uint8_t screen_model;
@@ -17,6 +19,8 @@ extern bool axp192_found;
extern bool isCharging;
extern bool isUSBPowered;
extern uint8_t nodeTelemetrySensorsMap[12];
// Global Screen singleton.
extern graphics::Screen *screen;
// extern Observable<meshtastic::PowerStatus> newPowerStatus; //TODO: move this to main-esp32.cpp somehow or a helper class

View File

@@ -3,11 +3,7 @@
void CryptoEngine::setKey(const CryptoKey &k)
{
DEBUG_MSG("Installing AES%d key!\n", k.length * 8);
/* for(uint8_t i = 0; i < k.length; i++)
DEBUG_MSG("%02x ", k.bytes[i]);
DEBUG_MSG("\n"); */
DEBUG_MSG("Using AES%d key!\n", k.length * 8);
key = k;
}
@@ -36,6 +32,4 @@ void CryptoEngine::initNonce(uint32_t fromNode, uint64_t packetId)
// use memcpy to avoid breaking strict-aliasing
memcpy(nonce, &packetId, sizeof(uint64_t));
memcpy(nonce + sizeof(uint64_t), &fromNode, sizeof(uint32_t));
//*((uint64_t *)&nonce[0]) = packetId;
//*((uint32_t *)&nonce[8]) = fromNode;
}

View File

@@ -48,7 +48,7 @@ DeviceState versions used to be defined in the .proto file but really only this
#define here.
*/
#define DEVICESTATE_CUR_VER 11
#define DEVICESTATE_CUR_VER 13
#define DEVICESTATE_MIN_VER DEVICESTATE_CUR_VER
// FIXME - move this somewhere else
@@ -90,18 +90,17 @@ bool NodeDB::resetRadioConfig()
// radioConfig.has_preferences = true;
if (config.device.factory_reset) {
DEBUG_MSG("Performing factory reset!\n");
// first, remove the "/prefs" (this removes most prefs)
rmDir("/prefs");
// second, install default state (this will deal with the duplicate mac address issue)
installDefaultDeviceState();
// third, write to disk
saveToDisk();
#ifndef NO_ESP32
// This will erase what's in NVS including ssl keys, persistant variables and ble pairing
nvs_flash_erase();
#endif
#ifdef NRF52_SERIES
// first, remove the "/prefs" (this removes most prefs)
FSCom.rmdir_r("/prefs");
// second, install default state (this will deal with the duplicate mac address issue)
installDefaultDeviceState();
// third, write to disk
saveToDisk();
Bluefruit.begin();
DEBUG_MSG("Clearing bluetooth bonds!\n");
bond_print_list(BLE_GAP_ROLE_PERIPH);
@@ -146,6 +145,7 @@ bool NodeDB::resetRadioConfig()
void NodeDB::installDefaultConfig()
{
memset(&config, 0, sizeof(LocalConfig));
config.version = DEVICESTATE_CUR_VER;
config.has_device = true;
config.has_display = true;
config.has_lora = true;
@@ -165,6 +165,7 @@ void NodeDB::installDefaultConfig()
void NodeDB::installDefaultModuleConfig()
{
memset(&moduleConfig, 0, sizeof(ModuleConfig));
moduleConfig.version = DEVICESTATE_CUR_VER;
moduleConfig.has_canned_message = true;
moduleConfig.has_external_notification = true;
moduleConfig.has_mqtt = true;
@@ -174,21 +175,10 @@ void NodeDB::installDefaultModuleConfig()
moduleConfig.has_telemetry = true;
}
// void NodeDB::installDefaultRadioConfig()
// {
// memset(&radioConfig, 0, sizeof(radioConfig));
// radioConfig.has_preferences = true;
// resetRadioConfig();
// // for backward compat, default position flags are BAT+ALT+MSL (0x23 = 35)
// config.position.position_flags =
// (Config_PositionConfig_PositionFlags_POS_BATTERY | Config_PositionConfig_PositionFlags_POS_ALTITUDE |
// Config_PositionConfig_PositionFlags_POS_ALT_MSL);
// }
void NodeDB::installDefaultChannels()
{
memset(&channelFile, 0, sizeof(ChannelFile));
channelFile.version = DEVICESTATE_CUR_VER;
}
void NodeDB::installDefaultDeviceState()
@@ -214,8 +204,8 @@ void NodeDB::installDefaultDeviceState()
// Set default owner name
pickNewNodeNum(); // based on macaddr now
sprintf(owner.long_name, "Unknown %02x%02x", ourMacAddr[4], ourMacAddr[5]);
sprintf(owner.short_name, "?%02X", (unsigned)(myNodeInfo.my_node_num & 0xff));
sprintf(owner.long_name, "Meshtastic %02x%02x", ourMacAddr[4], ourMacAddr[5]);
sprintf(owner.short_name, "%02x%02x", ourMacAddr[4], ourMacAddr[5]);
sprintf(owner.id, "!%08x", getNodeNum()); // Default node ID now based on nodenum
memcpy(owner.macaddr, ourMacAddr, sizeof(owner.macaddr));
@@ -308,12 +298,12 @@ static const char *channelfile = "/prefs/channels.proto";
/** Load a protobuf from a file, return true for success */
bool loadProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, void *dest_struct)
{
bool okay = false;
#ifdef FSCom
// static DeviceState scratch; We no longer read into a tempbuf because this structure is 15KB of valuable RAM
auto f = FSCom.open(filename);
bool okay = false;
if (f) {
DEBUG_MSG("Loading %s\n", filename);
pb_istream_t stream = {&readcb, &f, protoSize};
@@ -346,33 +336,66 @@ void NodeDB::loadFromDisk()
if (devicestate.version < DEVICESTATE_MIN_VER) {
DEBUG_MSG("Warn: devicestate %d is old, discarding\n", devicestate.version);
installDefaultDeviceState();
#ifndef NO_ESP32
// This will erase what's in NVS including ssl keys, persistant variables and ble pairing
nvs_flash_erase();
#endif
#ifdef NRF52_SERIES
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
} else {
DEBUG_MSG("Loaded saved preferences version %d\n", devicestate.version);
DEBUG_MSG("Loaded saved devicestate version %d\n", devicestate.version);
}
}
if (!loadProto(configfile, LocalConfig_size, sizeof(LocalConfig), LocalConfig_fields, &config)) {
installDefaultConfig(); // Our in RAM copy might now be corrupt
} else {
if (config.version < DEVICESTATE_MIN_VER) {
DEBUG_MSG("Warn: config %d is old, discarding\n", config.version);
installDefaultConfig();
} else {
DEBUG_MSG("Loaded saved config version %d\n", config.version);
}
}
if (!loadProto(moduleConfigfile, LocalModuleConfig_size, sizeof(LocalModuleConfig), LocalModuleConfig_fields, &moduleConfig)) {
installDefaultModuleConfig(); // Our in RAM copy might now be corrupt
} else {
if (moduleConfig.version < DEVICESTATE_MIN_VER) {
DEBUG_MSG("Warn: moduleConfig %d is old, discarding\n", moduleConfig.version);
installDefaultModuleConfig();
} else {
DEBUG_MSG("Loaded saved moduleConfig version %d\n", moduleConfig.version);
}
}
if (!loadProto(channelfile, ChannelFile_size, sizeof(ChannelFile), ChannelFile_fields, &channelFile)) {
installDefaultChannels(); // Our in RAM copy might now be corrupt
} else {
if (channelFile.version < DEVICESTATE_MIN_VER) {
DEBUG_MSG("Warn: channelFile %d is old, discarding\n", channelFile.version);
installDefaultChannels();
} else {
DEBUG_MSG("Loaded saved channelFile version %d\n", channelFile.version);
}
}
}
/** Save a protobuf from a file, return true for success */
bool saveProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, const void *dest_struct)
{
bool okay = false;
#ifdef FSCom
// static DeviceState scratch; We no longer read into a tempbuf because this structure is 15KB of valuable RAM
String filenameTmp = filename;
filenameTmp += ".tmp";
auto f = FSCom.open(filenameTmp.c_str(), FILE_O_WRITE);
bool okay = false;
if (f) {
DEBUG_MSG("Saving %s\n", filename);
pb_ostream_t stream = {&writecb, &f, protoSize};

View File

@@ -138,7 +138,7 @@ extern NodeDB nodeDB;
/*
If is_router is set, we use a number of different default values
# FIXME - after tuning, move these params into the on-device defaults based on is_router and is_low_power
# FIXME - after tuning, move these params into the on-device defaults based on is_router and is_power_saving
# prefs.position_broadcast_secs = FIXME possibly broadcast only once an hr
prefs.wait_bluetooth_secs = 1 # Don't stay in bluetooth mode
@@ -152,7 +152,7 @@ extern NodeDB nodeDB;
# get a new GPS position once per day
prefs.gps_update_interval = oneday
prefs.is_low_power = True
prefs.is_power_saving = True
# allow up to five minutes for each new GPS lock attempt
prefs.gps_attempt_time = 300
@@ -168,7 +168,6 @@ extern NodeDB nodeDB;
#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_phone_timeout_secs 15 * 60
#define default_min_wake_secs 10

View File

@@ -112,7 +112,8 @@ 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_RADIO,
* STATE_SEND_GROUPS
STATE_SEND_CONFIG,
STATE_SEND_NODEINFO, // states progress in this order as the device sends to to the client
STATE_SEND_COMPLETE_ID,
STATE_SEND_PACKETS // send packets or debug strings
@@ -140,11 +141,53 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
myNodeInfo.has_gps = gps && gps->isConnected(); // Update with latest GPS connect info
fromRadioScratch.which_payloadVariant = FromRadio_my_info_tag;
fromRadioScratch.my_info = myNodeInfo;
state = STATE_SEND_NODEINFO;
state = STATE_SEND_CONFIG;
service.refreshMyNodeInfo(); // Update my NodeInfo because the client will be asking for it soon.
break;
case STATE_SEND_CONFIG:
fromRadioScratch.which_payloadVariant = 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;
}
// 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_lora_tag) {
state = STATE_SEND_NODEINFO;
config_state = Config_device_tag;
}
break;
case STATE_SEND_NODEINFO: {
const NodeInfo *info = nodeInfoForPhone;
nodeInfoForPhone = NULL; // We just consumed a nodeinfo, will need a new one next time
@@ -220,6 +263,9 @@ bool PhoneAPI::available()
case STATE_SEND_MY_INFO:
return true;
case STATE_SEND_CONFIG:
return true;
case STATE_SEND_NODEINFO:
if (!nodeInfoForPhone)
@@ -269,4 +315,4 @@ int PhoneAPI::onNotify(uint32_t newValue)
DEBUG_MSG("(Client not yet interested in packets)\n");
return 0;
}
}

View File

@@ -20,13 +20,10 @@ class PhoneAPI
: public Observer<uint32_t> // FIXME, we shouldn't be inheriting from Observer, instead use CallbackObserver as a member
{
enum State {
STATE_UNUSED, // (no longer used) old default state - until Android apps are all updated, uses the old BLE API
STATE_SEND_NOTHING, // (Eventual) Initial state, don't send anything until the client starts asking for config
// (disconnected)
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_GROUPS,
// STATE_SEND_RADIO, // in 1.2 we now send this as a regular mesh packet
// STATE_SEND_OWNER, no need to send Owner specially, it is just part of the nodedb
STATE_SEND_GROUPS, // new in 1.3?
STATE_SEND_CONFIG, // Replacement for the old Radioconfig
STATE_SEND_NODEINFO, // states progress in this order as the device sends to to the client
STATE_SEND_COMPLETE_ID,
STATE_SEND_PACKETS // send packets or debug strings
@@ -34,6 +31,8 @@ class PhoneAPI
State state = STATE_SEND_NOTHING;
int8_t config_state = Config_device_tag;
/**
* Each packet sent to the phone has an incrementing count
*/

View File

@@ -77,10 +77,13 @@ template <class T> class ProtobufModule : protected SinglePortModule
T *decoded = NULL;
if (mp.which_payloadVariant == 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))
if (pb_decode_from_bytes(p.payload.bytes, p.payload.size, fields, &scratch)) {
decoded = &scratch;
else
} else {
DEBUG_MSG("Error decoding protobuf module!\n");
// if we can't decode it, nobody can process it!
return ProcessMessage::STOP;
}
}
return handleReceivedProtobuf(mp, decoded) ? ProcessMessage::STOP : ProcessMessage::CONTINUE;

View File

@@ -159,61 +159,50 @@ uint32_t RadioInterface::getPacketTime(MeshPacket *p)
/** The delay to use for retransmitting dropped packets */
uint32_t RadioInterface::getRetransmissionMsec(const MeshPacket *p)
{
assert(shortPacketMsec); // Better be non zero
assert(slotTimeMsec); // Better be non zero
static uint8_t bytes[MAX_RHPACKETLEN];
size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), Data_fields, &p->decoded);
uint32_t packetAirtime = getPacketTime(numbytes + sizeof(PacketHeader));
uint32_t tCADmsec = 2 * (1 << sf) / bw; // duration of CAD is roughly 2 symbols according to SX127x datasheet
/* Make sure enough time has elapsed for this packet to be sent and an ACK is received.
* Right now we have to wait until another node floods the same packet, as that is our implicit ACK.
* TODO: Revise when want_ack will be used (right now it is always set to 0 afterwards).
*/
return 2*packetAirtime + 2*MIN_TX_WAIT_MSEC + shortPacketMsec + shortPacketMsec*2 + PROCESSING_TIME_MSEC + 2*tCADmsec;
// Make sure enough time has elapsed for this packet to be sent and an ACK is received.
// DEBUG_MSG("Waiting for flooding message with airtime %d and slotTime is %d\n", packetAirtime, slotTimeMsec);
float channelUtil = airTime->channelUtilizationPercent();
uint8_t CWsize = map(channelUtil, 0, 100, CWmin, CWmax);
// Assuming we pick max. of CWsize and there will be a receiver with SNR at half the range
return 2*packetAirtime + (pow(2, CWsize) + pow(2, int((CWmax+CWmin)/2))) * slotTimeMsec + PROCESSING_TIME_MSEC;
}
/** The delay to use when we want to send something but the ether is busy */
/** The delay to use when we want to send something */
uint32_t RadioInterface::getTxDelayMsec()
{
/** At the low end we want to pick a delay large enough that anyone who just completed sending (some other node)
* has had enough time to switch their radio back into receive mode.
*/
const uint32_t MIN_TX_WAIT_MSEC = 100;
/**
* At the high end, this value is used to spread node attempts across time so when they are replying to a packet
* they don't both check that the airwaves are clear at the same moment. As long as they are off by some amount
* one of the two will be first to start transmitting and the other will see that. I bet 500ms is more than enough
* to guarantee this.
*/
// const uint32_t MAX_TX_WAIT_MSEC = 2000; // stress test would still fail occasionally with 1000
return random((MIN_TX_WAIT_MSEC), (MIN_TX_WAIT_MSEC + shortPacketMsec));
/** We wait a random multiple of 'slotTimes' (see definition in header file) in order to avoid collisions.
The pool to take a random multiple from is the contention window (CW), which size depends on the
current channel utilization. */
float channelUtil = airTime->channelUtilizationPercent();
uint8_t CWsize = map(channelUtil, 0, 100, CWmin, CWmax);
// DEBUG_MSG("Current channel utilization is %f so setting CWsize to %d\n", channelUtil, CWsize);
return random(0, pow(2, CWsize)) * slotTimeMsec;
}
/** The delay to use when we want to send something but the ether is busy */
/** The delay to use when we want to flood a message */
uint32_t RadioInterface::getTxDelayMsecWeighted(float snr)
{
/** At the low end we want to pick a delay large enough that anyone who just completed sending (some other node)
* has had enough time to switch their radio back into receive mode.
*/
const uint32_t MIN_TX_WAIT_MSEC = 100;
// The minimum value for a LoRa SNR
const uint32_t SNR_MIN = -20;
// The maximum value for a LoRa SNR
const uint32_t SNR_MAX = 15;
// high SNR = Long Delay
// low SNR = Short Delay
// high SNR = large CW size (Long Delay)
// low SNR = small CW size (Short Delay)
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) {
delay = map(snr, SNR_MIN, SNR_MAX, MIN_TX_WAIT_MSEC, (MIN_TX_WAIT_MSEC + (shortPacketMsec / 2)));
delay = random(0, 2*CWsize) * slotTimeMsec;
DEBUG_MSG("rx_snr found in packet. As a router, setting tx delay:%d\n", delay);
} else {
delay = map(snr, SNR_MIN, SNR_MAX, MIN_TX_WAIT_MSEC + (shortPacketMsec / 2), (MIN_TX_WAIT_MSEC + shortPacketMsec * 2));
delay = random(0, pow(2, CWsize)) * slotTimeMsec;
DEBUG_MSG("rx_snr found in packet. Setting tx delay:%d\n", delay);
}
@@ -411,9 +400,14 @@ void RadioInterface::applyModemConfig()
}
power = loraConfig.tx_power;
shortPacketMsec = getPacketTime(sizeof(PacketHeader));
assert(myRegion); // Should have been found in init
if ((power == 0) || (power > myRegion->powerLimit))
power = myRegion->powerLimit;
if (power == 0)
power = 17; // Default to default power if we don't have a valid power
// Calculate the number of channels
uint32_t numChannels = floor((myRegion->freqEnd - myRegion->freqStart) / (myRegion->spacing + (bw / 1000)));
@@ -431,7 +425,7 @@ void RadioInterface::applyModemConfig()
DEBUG_MSG("Radio myRegion->numChannels: %d\n", numChannels);
DEBUG_MSG("Radio channel_num: %d\n", channel_num);
DEBUG_MSG("Radio frequency: %f\n", getFreq());
DEBUG_MSG("Short packet time: %u msec\n", shortPacketMsec);
DEBUG_MSG("Slot time: %u msec\n", slotTimeMsec);
}
/**

View File

@@ -52,8 +52,6 @@ class RadioInterface
CallbackObserver<RadioInterface, void *> notifyDeepSleepObserver =
CallbackObserver<RadioInterface, void *>(this, &RadioInterface::notifyDeepSleepCb);
/// Number of msecs we expect our shortest actual packet to be over the wire (used in retry timeout calcs)
uint32_t shortPacketMsec;
protected:
bool disabled = false;
@@ -61,10 +59,16 @@ class RadioInterface
float bw = 125;
uint8_t sf = 9;
uint8_t cr = 7;
/** Slottime is the minimum time to wait, consisting of:
- CAD duration (maximum of SX126x and SX127x);
- roundtrip air propagation time (assuming max. 30km between nodes);
- Tx/Rx turnaround time (maximum of SX126x and SX127x);
- MAC processing time (measured on T-beam) */
uint32_t slotTimeMsec = 8.5 * pow(2, sf)/bw + 0.2 + 0.4 + 7;
uint16_t preambleLength = 32; // 8 is default, but we use longer to increase the amount of sleep time when receiving
const uint32_t MIN_TX_WAIT_MSEC = 100; // minimum time to wait before transmitting after sensing the channel in ms
const uint32_t PROCESSING_TIME_MSEC = 4500; // time to construct, process and construct a packet again (empirically determined)
const uint8_t CWmin = 2; // minimum CWsize
const uint8_t CWmax = 8; // maximum CWsize
MeshPacket *sendingPacket = NULL; // The packet we are currently sending
uint32_t lastTxStart = 0L;
@@ -128,10 +132,10 @@ class RadioInterface
/** The delay to use for retransmitting dropped packets */
uint32_t getRetransmissionMsec(const MeshPacket *p);
/** The delay to use when we want to send something but the ether is busy */
/** The delay to use when we want to send something */
uint32_t getTxDelayMsec();
/** The delay to use when we want to send something but the ether is busy. Use a weighted scale based on SNR */
/** The delay to use when we want to flood a message. Use a weighted scale based on SNR */
uint32_t getTxDelayMsecWeighted(float snr);

View File

@@ -11,6 +11,8 @@
// FIXME, we default to 4MHz SPI, SPI mode 0, check if the datasheet says it can really do that
static SPISettings spiSettings(4000000, MSBFIRST, SPI_MODE0);
#ifdef PORTDUINO
void LockingModule::SPItransfer(uint8_t cmd, uint8_t reg, uint8_t *dataOut, uint8_t *dataIn, uint8_t numBytes)
{
concurrency::LockGuard g(spiLock);
@@ -18,6 +20,24 @@ void LockingModule::SPItransfer(uint8_t cmd, uint8_t reg, uint8_t *dataOut, uint
Module::SPItransfer(cmd, reg, dataOut, dataIn, numBytes);
}
#else
void LockingModule::SPIbeginTransaction()
{
spiLock->lock();
Module::SPIbeginTransaction();
}
void LockingModule::SPIendTransaction()
{
spiLock->unlock();
Module::SPIendTransaction();
}
#endif
RadioLibInterface::RadioLibInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
SPIClass &spi, PhysicalLayer *_iface)
: NotifiedWorkerThread("RadioIf"), module(cs, irq, rst, busy, spi, spiSettings), iface(_iface)
@@ -170,17 +190,11 @@ ErrorCode RadioLibInterface::send(MeshPacket *p)
}
/** radio helper thread callback.
We never immediately transmit after any operation (either rx or tx). Instead we should start receiving and
wait a random delay of 100ms to 100ms+shortPacketMsec to make sure we are not stomping on someone else. The 100ms delay
at the beginning ensures all possible listeners have had time to finish processing the previous packet and now have their
radio in RX state. The up to 100ms+shortPacketMsec random delay gives a chance for all possible senders to have high odds
of detecting that someone else started transmitting first and then they will wait until that packet finishes.
NOTE: the large flood rebroadcast delay might still be needed even with this approach. Because we might not be able to
hear other transmitters that we are potentially stomping on. Requires further thought.
FIXME, the MIN_TX_WAIT_MSEC and MAX_TX_WAIT_MSEC values should be tuned via logic analyzer later.
We never immediately transmit after any operation (either Rx or Tx). Instead we should wait a random multiple of
'slotTimes' (see definition in RadioInterface.h) taken from a contention window (CW) to lower the chance of collision.
The CW size is determined by setTransmitDelay() and depends either on the current channel utilization or SNR in case
of a flooding message. After this, we perform channel activity detection (CAD) and reset the transmit delay if it is
currently active.
*/
void RadioLibInterface::onNotify(uint32_t notification)
{

View File

@@ -40,21 +40,13 @@ class LockingModule : public Module
: Module(cs, irq, rst, gpio, spi, spiSettings)
{
}
/*!
\brief SPI single transfer method.
\param cmd SPI access command (read/write/burst/...).
\param reg Address of SPI register to transfer to/from.
\param dataOut Data that will be transfered from master to slave.
\param dataIn Data that was transfered from slave to master.
\param numBytes Number of bytes to transfer.
*/
virtual void SPItransfer(uint8_t cmd, uint8_t reg, uint8_t *dataOut, uint8_t *dataIn, uint8_t numBytes);
#ifdef PORTDUINO
void SPItransfer(uint8_t cmd, uint8_t reg, uint8_t *dataOut, uint8_t *dataIn, uint8_t numBytes) override;
#else
void SPIbeginTransaction() override;
void SPIendTransaction() override;
#endif
};
class RadioLibInterface : public RadioInterface, protected concurrency::NotifiedWorkerThread

View File

@@ -1,5 +1,5 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.5 */
/* Generated by nanopb-0.4.6 */
#include "admin.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View File

@@ -1,5 +1,5 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.5 */
/* Generated by nanopb-0.4.6 */
#ifndef PB_ADMIN_PB_H_INCLUDED
#define PB_ADMIN_PB_H_INCLUDED
@@ -38,41 +38,80 @@ 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 {
/* Set the owner for this node */
pb_size_t which_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;
/* TODO: REPLACE */
Channel get_channel_response;
/* Send the current owner data in the response to this message. */
bool get_owner_request;
/* TODO: REPLACE */
User get_owner_response;
/* Ask for the following config data to be sent */
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;
/* Set the current Config */
ModuleConfig set_module_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;
/* 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.
These messages are optional when changing the local node. */
bool confirm_set_channel;
/* TODO: REPLACE */
bool confirm_set_radio;
/* 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 message part1 in the response to this message. */
bool get_canned_message_module_part1_request;
/* TODO: REPLACE */
char get_canned_message_module_part1_response[201];
/* Get the Canned Message Module message part2 in the response to this message. */
bool get_canned_message_module_part2_request;
/* TODO: REPLACE */
char get_canned_message_module_part2_response[201];
/* Get the Canned Message Module message part3 in the response to this message. */
bool get_canned_message_module_part3_request;
/* TODO: REPLACE */
char get_canned_message_module_part3_response[201];
/* Get the Canned Message Module message part4 in the response to this message. */
bool get_canned_message_module_part4_request;
/* TODO: REPLACE */
char get_canned_message_module_part4_response[201];
/* Set the canned message module part 1 text. */
char set_canned_message_module_part1[201];
/* Set the canned message module part 2 text. */
char set_canned_message_module_part2[201];
/* Set the canned message module part 3 text. */
char set_canned_message_module_part3[201];
/* Set the canned message module part 4 text. */
char set_canned_message_module_part4[201];
/* Tell the node to shutdown in this many seconds (or <0 to cancel shutdown) */
int32_t shutdown_seconds;
};
};
} AdminMessage;

View File

@@ -1,5 +1,5 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.5 */
/* Generated by nanopb-0.4.6 */
#include "apponly.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View File

@@ -1,5 +1,5 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.5 */
/* Generated by nanopb-0.4.6 */
#ifndef PB_APPONLY_PB_H_INCLUDED
#define PB_APPONLY_PB_H_INCLUDED
@@ -20,10 +20,10 @@
typedef struct _ChannelSet {
/* Channel list with settings */
pb_size_t settings_count;
ChannelSettings settings[8];
ChannelSettings settings[8];
/* LoRa config */
bool has_lora_config;
Config_LoRaConfig lora_config;
Config_LoRaConfig lora_config;
} ChannelSet;

View File

@@ -1,5 +1,5 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.5 */
/* Generated by nanopb-0.4.6 */
#include "cannedmessages.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View File

@@ -1,5 +1,5 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.5 */
/* Generated by nanopb-0.4.6 */
#ifndef PB_CANNEDMESSAGES_PB_H_INCLUDED
#define PB_CANNEDMESSAGES_PB_H_INCLUDED
@@ -13,13 +13,13 @@
/* Canned message module configuration. */
typedef struct _CannedMessageModuleConfig {
/* Predefined messages for canned message module separated by '|' characters. */
char messagesPart1[201];
char messagesPart1[201];
/* TODO: REPLACE */
char messagesPart2[201];
char messagesPart2[201];
/* TODO: REPLACE */
char messagesPart3[201];
char messagesPart3[201];
/* TODO: REPLACE */
char messagesPart4[201];
char messagesPart4[201];
} CannedMessageModuleConfig;

View File

@@ -1,5 +1,5 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.5 */
/* Generated by nanopb-0.4.6 */
#include "channel.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View File

@@ -1,5 +1,5 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.5 */
/* Generated by nanopb-0.4.6 */
#ifndef PB_CHANNEL_PB_H_INCLUDED
#define PB_CHANNEL_PB_H_INCLUDED
@@ -38,6 +38,26 @@ 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 {
/* 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.
These psks should be treated as only minimally secure,
because they are listed in this source code.
Those bytes are mapped using the following scheme:
`0` = No crypto
`1` = The special "default" channel key: {0xd4, 0xf1, 0xbb, 0x3a, 0x20, 0x29, 0x07, 0x59, 0xf0, 0xbc, 0xff, 0xab, 0xcf, 0x4e, 0x69, 0xbf}
`2` through 10 = The default channel key, except with 1 through 9 added to the last byte.
Shown to user as simple1 through 10 */
ChannelSettings_psk_t psk;
/* A SHORT name that will be packed into the URL.
Less than 12 bytes.
Something for end users to call the channel
If this is the empty string it is assumed that this channel
is the special (minimally secure) "Default"channel.
In user interfaces it should be rendered as a local language translation of "X".
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.
@@ -56,27 +76,7 @@ typedef struct _ChannelSettings {
hash = ((hash << 5) + hash) + (unsigned char) c;
return hash;
} */
ChannelSettings_psk_t psk;
/* 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.
These psks should be treated as only minimally secure,
because they are listed in this source code.
Those bytes are mapped using the following scheme:
`0` = No crypto
`1` = The special "default" channel key: {0xd4, 0xf1, 0xbb, 0x3a, 0x20, 0x29, 0x07, 0x59, 0xf0, 0xbc, 0xff, 0xab, 0xcf, 0x4e, 0x69, 0xbf}
`2` through 10 = The default channel key, except with 1 through 9 added to the last byte.
Shown to user as simple1 through 10 */
char name[12];
/* A SHORT name that will be packed into the URL.
Less than 12 bytes.
Something for end users to call the channel
If this is the empty string it is assumed that this channel
is the special (minimally secure) "Default"channel.
In user interfaces it should be rendered as a local language translation of "X".
For channel_num hashing empty string will be treated as "X".
Where "X" is selected based on the English words listed above for ModemPreset */
uint8_t channel_num;
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)
@@ -88,11 +88,11 @@ typedef struct _ChannelSettings {
Those channels do not have a numeric id included in the settings, but instead it is pulled from
a table of well known IDs.
(see Well Known Channels FIXME) */
uint32_t id;
uint32_t id;
/* If true, messages on the mesh will be sent to the *public* internet by any gateway ndoe */
bool uplink_enabled;
bool uplink_enabled;
/* If true, messages seen on the internet will be forwarded to the local mesh. */
bool downlink_enabled;
bool downlink_enabled;
} ChannelSettings;
/* A pair of a channel number, mode and the (sharable) settings for that channel */
@@ -100,12 +100,12 @@ typedef struct _Channel {
/* The index of this channel in the channel table (from 0 to MAX_NUM_CHANNELS-1)
(Someday - not currently implemented) An index of -1 could be used to mean "set by name",
in which case the target node will find and set the channel by settings.name. */
int8_t index;
int8_t index;
/* The new settings, or NULL to disable that channel */
bool has_settings;
ChannelSettings settings;
ChannelSettings settings;
/* TODO: REPLACE */
Channel_Role role;
Channel_Role role;
} Channel;

View File

@@ -1,5 +1,5 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.5 */
/* Generated by nanopb-0.4.6 */
#include "config.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View File

@@ -1,5 +1,5 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.5 */
/* Generated by nanopb-0.4.6 */
#ifndef PB_CONFIG_PB_H_INCLUDED
#define PB_CONFIG_PB_H_INCLUDED
@@ -86,78 +86,78 @@ typedef enum _Config_LoRaConfig_ModemPreset {
/* Struct definitions */
typedef struct _Config_DeviceConfig {
Config_DeviceConfig_Role role;
bool serial_disabled;
bool factory_reset;
bool debug_log_enabled;
char ntp_server[33];
Config_DeviceConfig_Role role;
bool serial_disabled;
bool factory_reset;
bool debug_log_enabled;
char ntp_server[33];
} Config_DeviceConfig;
typedef struct _Config_DisplayConfig {
uint32_t screen_on_secs;
Config_DisplayConfig_GpsCoordinateFormat gps_format;
uint32_t auto_screen_carousel_secs;
uint32_t screen_on_secs;
Config_DisplayConfig_GpsCoordinateFormat gps_format;
uint32_t auto_screen_carousel_secs;
} Config_DisplayConfig;
typedef struct _Config_LoRaConfig {
int32_t tx_power;
Config_LoRaConfig_ModemPreset modem_preset;
uint32_t bandwidth;
uint32_t spread_factor;
uint32_t coding_rate;
float frequency_offset;
Config_LoRaConfig_RegionCode region;
uint32_t hop_limit;
bool tx_disabled;
int32_t tx_power;
Config_LoRaConfig_ModemPreset modem_preset;
uint32_t bandwidth;
uint32_t spread_factor;
uint32_t coding_rate;
float frequency_offset;
Config_LoRaConfig_RegionCode region;
uint32_t hop_limit;
bool tx_disabled;
pb_size_t ignore_incoming_count;
uint32_t ignore_incoming[3];
uint32_t ignore_incoming[3];
} Config_LoRaConfig;
typedef struct _Config_PositionConfig {
uint32_t position_broadcast_secs;
bool position_broadcast_smart_disabled;
bool fixed_position;
bool gps_disabled;
uint32_t gps_update_interval;
uint32_t gps_attempt_time;
bool gps_accept_2d;
uint32_t gps_max_dop;
uint32_t position_flags;
uint32_t position_broadcast_secs;
bool position_broadcast_smart_disabled;
bool fixed_position;
bool gps_disabled;
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_low_power;
bool is_always_powered;
uint32_t on_battery_shutdown_after_secs;
bool is_power_saving;
float adc_multiplier_override;
uint32_t wait_bluetooth_secs;
uint32_t phone_timeout_secs;
uint32_t mesh_sds_timeout_secs;
uint32_t sds_secs;
uint32_t ls_secs;
uint32_t min_wake_secs;
Config_PowerConfig_ChargeCurrent charge_current;
bool is_power_saving;
uint32_t on_battery_shutdown_after_secs;
float adc_multiplier_override;
uint32_t wait_bluetooth_secs;
uint32_t mesh_sds_timeout_secs;
uint32_t sds_secs;
uint32_t ls_secs;
uint32_t min_wake_secs;
} Config_PowerConfig;
typedef struct _Config_WiFiConfig {
char ssid[33];
char psk[64];
bool ap_mode;
bool ap_hidden;
char ssid[33];
char psk[64];
bool ap_mode;
bool ap_hidden;
} Config_WiFiConfig;
typedef struct _Config {
/* TODO: REPLACE */
pb_size_t which_payloadVariant;
union {
/* TODO: REPLACE */
Config_DeviceConfig device;
/* TODO: REPLACE */
Config_PositionConfig position;
/* TODO: REPLACE */
Config_PowerConfig power;
/* TODO: REPLACE */
Config_WiFiConfig wifi;
/* TODO: REPLACE */
Config_DisplayConfig display;
/* TODO: REPLACE */
Config_LoRaConfig lora;
} payloadVariant;
} payloadVariant;
} Config;
@@ -194,15 +194,15 @@ 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_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0}
#define Config_PowerConfig_init_default {_Config_PowerConfig_ChargeCurrent_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0}
#define Config_DisplayConfig_init_default {0, _Config_DisplayConfig_GpsCoordinateFormat_MIN, 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_init_zero {0, {Config_DeviceConfig_init_zero}}
#define Config_DeviceConfig_init_zero {_Config_DeviceConfig_Role_MIN, 0, 0, 0, ""}
#define Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0}
#define Config_PowerConfig_init_zero {_Config_PowerConfig_ChargeCurrent_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0}
#define Config_DisplayConfig_init_zero {0, _Config_DisplayConfig_GpsCoordinateFormat_MIN, 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}}
@@ -232,17 +232,12 @@ extern "C" {
#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_gps_accept_2d_tag 8
#define Config_PositionConfig_gps_max_dop_tag 9
#define Config_PositionConfig_position_flags_tag 10
#define Config_PowerConfig_charge_current_tag 1
#define Config_PowerConfig_is_low_power_tag 2
#define Config_PowerConfig_is_always_powered_tag 3
#define Config_PowerConfig_is_power_saving_tag 2
#define Config_PowerConfig_on_battery_shutdown_after_secs_tag 4
#define Config_PowerConfig_is_power_saving_tag 5
#define Config_PowerConfig_adc_multiplier_override_tag 6
#define Config_PowerConfig_wait_bluetooth_secs_tag 7
#define Config_PowerConfig_phone_timeout_secs_tag 8
#define Config_PowerConfig_mesh_sds_timeout_secs_tag 9
#define Config_PowerConfig_sds_secs_tag 10
#define Config_PowerConfig_ls_secs_tag 11
@@ -291,21 +286,16 @@ 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, BOOL, gps_accept_2d, 8) \
X(a, STATIC, SINGULAR, UINT32, gps_max_dop, 9) \
X(a, STATIC, SINGULAR, UINT32, position_flags, 10)
#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_low_power, 2) \
X(a, STATIC, SINGULAR, BOOL, is_always_powered, 3) \
X(a, STATIC, SINGULAR, BOOL, is_power_saving, 2) \
X(a, STATIC, SINGULAR, UINT32, on_battery_shutdown_after_secs, 4) \
X(a, STATIC, SINGULAR, BOOL, is_power_saving, 5) \
X(a, STATIC, SINGULAR, FLOAT, adc_multiplier_override, 6) \
X(a, STATIC, SINGULAR, UINT32, wait_bluetooth_secs, 7) \
X(a, STATIC, SINGULAR, UINT32, phone_timeout_secs, 8) \
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) \
@@ -363,8 +353,8 @@ extern const pb_msgdesc_t Config_LoRaConfig_msg;
#define Config_DeviceConfig_size 42
#define Config_DisplayConfig_size 14
#define Config_LoRaConfig_size 67
#define Config_PositionConfig_size 38
#define Config_PowerConfig_size 55
#define Config_PositionConfig_size 30
#define Config_PowerConfig_size 45
#define Config_WiFiConfig_size 103
#define Config_size 105

View File

@@ -1,5 +1,5 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.5 */
/* Generated by nanopb-0.4.6 */
#include "deviceonly.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View File

@@ -1,5 +1,5 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.5 */
/* Generated by nanopb-0.4.6 */
#ifndef PB_DEVICEONLY_PB_H_INCLUDED
#define PB_DEVICEONLY_PB_H_INCLUDED
@@ -27,7 +27,11 @@ typedef enum _ScreenFonts {
typedef struct _ChannelFile {
/* The channels our node knows about */
pb_size_t channels_count;
Channel channels[8];
Channel channels[8];
/* A version integer used to invalidate old save files when we make
incompatible changes This integer is set at build time and is private to
NodeDB.cpp in the device code. */
uint32_t version;
} ChannelFile;
/* This message is never sent over the wire, but it is used for serializing DB
@@ -38,30 +42,30 @@ typedef struct _ChannelFile {
typedef struct _DeviceState {
/* Read only settings/info about this node */
bool has_my_node;
MyNodeInfo my_node;
MyNodeInfo my_node;
/* My owner info */
bool has_owner;
User owner;
User owner;
/* TODO: REPLACE */
pb_size_t node_db_count;
NodeInfo node_db[64];
NodeInfo node_db[80];
/* Received packets saved for delivery to the phone */
pb_size_t receive_queue_count;
MeshPacket receive_queue[1];
/* A version integer used to invalidate old save files when we make
incompatible changes This integer is set at build time and is private to
NodeDB.cpp in the device code. */
bool has_rx_text_message;
MeshPacket rx_text_message;
MeshPacket receive_queue[1];
/* We keep the last received text message (only) stored in the device flash,
so we can show it on the screen.
Might be null */
uint32_t version;
bool has_rx_text_message;
MeshPacket rx_text_message;
/* A version integer used to invalidate old save files when we make
incompatible changes This integer is set at build time and is private to
NodeDB.cpp in the device code. */
uint32_t version;
/* Used only during development.
Indicates developer is testing and changes should never be saved to flash. */
bool no_save;
bool no_save;
/* Some GPSes seem to have bogus settings from the factory, so we always do one factory reset. */
bool did_gps_reset;
bool did_gps_reset;
} DeviceState;
typedef PB_BYTES_ARRAY_T(2048) OEMStore_oem_icon_bits_t;
@@ -69,15 +73,15 @@ typedef PB_BYTES_ARRAY_T(2048) OEMStore_oem_icon_bits_t;
show a secondary bootup screen with cuatom logo and text for 2.5 seconds. */
typedef struct _OEMStore {
/* The Logo width in Px */
uint32_t oem_icon_width;
uint32_t oem_icon_width;
/* The Logo height in Px */
uint32_t oem_icon_height;
uint32_t oem_icon_height;
/* The Logo in xbm bytechar format */
OEMStore_oem_icon_bits_t oem_icon_bits;
OEMStore_oem_icon_bits_t oem_icon_bits;
/* Use this font for the OEM text. */
ScreenFonts oem_font;
ScreenFonts oem_font;
/* Use this font for the OEM text. */
char oem_text[40];
char oem_text[40];
} OEMStore;
@@ -92,15 +96,16 @@ extern "C" {
#endif
/* Initializer values for message structs */
#define DeviceState_init_default {false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default}, false, MeshPacket_init_default, 0, 0, 0}
#define ChannelFile_init_default {0, {Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default}}
#define DeviceState_init_default {false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default}, false, MeshPacket_init_default, 0, 0, 0}
#define ChannelFile_init_default {0, {Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default}, 0}
#define OEMStore_init_default {0, 0, {0, {0}}, _ScreenFonts_MIN, ""}
#define DeviceState_init_zero {false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero}, false, MeshPacket_init_zero, 0, 0, 0}
#define ChannelFile_init_zero {0, {Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero}}
#define DeviceState_init_zero {false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero}, false, MeshPacket_init_zero, 0, 0, 0}
#define ChannelFile_init_zero {0, {Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero}, 0}
#define OEMStore_init_zero {0, 0, {0, {0}}, _ScreenFonts_MIN, ""}
/* Field tags (for use in manual encoding/decoding) */
#define ChannelFile_channels_tag 1
#define ChannelFile_version_tag 2
#define DeviceState_my_node_tag 2
#define DeviceState_owner_tag 3
#define DeviceState_node_db_tag 4
@@ -134,7 +139,8 @@ X(a, STATIC, SINGULAR, BOOL, did_gps_reset, 11)
#define DeviceState_rx_text_message_MSGTYPE MeshPacket
#define ChannelFile_FIELDLIST(X, a) \
X(a, STATIC, REPEATED, MESSAGE, channels, 1)
X(a, STATIC, REPEATED, MESSAGE, channels, 1) \
X(a, STATIC, SINGULAR, UINT32, version, 2)
#define ChannelFile_CALLBACK NULL
#define ChannelFile_DEFAULT NULL
#define ChannelFile_channels_MSGTYPE Channel
@@ -158,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 624
#define DeviceState_size 19184
#define ChannelFile_size 630
#define DeviceState_size 23728
#define OEMStore_size 2106
#ifdef __cplusplus

View File

@@ -1,5 +1,5 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.5 */
/* Generated by nanopb-0.4.6 */
#include "localonly.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View File

@@ -1,5 +1,5 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.5 */
/* Generated by nanopb-0.4.6 */
#ifndef PB_LOCALONLY_PB_H_INCLUDED
#define PB_LOCALONLY_PB_H_INCLUDED
@@ -13,48 +13,56 @@
/* Struct definitions */
typedef struct _LocalConfig {
/* TODO: REPLACE */
/* The part of the config that is specific to the Device */
bool has_device;
Config_DeviceConfig device;
/* TODO: REPLACE */
Config_DeviceConfig device;
/* The part of the config that is specific to the GPS Position */
bool has_position;
Config_PositionConfig position;
/* TODO: REPLACE */
Config_PositionConfig position;
/* The part of the config that is specific to the Power settings */
bool has_power;
Config_PowerConfig power;
/* TODO: REPLACE */
Config_PowerConfig power;
/* The part of the config that is specific to the Wifi Settings */
bool has_wifi;
Config_WiFiConfig wifi;
/* TODO: REPLACE */
Config_WiFiConfig wifi;
/* The part of the config that is specific to the Display */
bool has_display;
Config_DisplayConfig display;
/* TODO: REPLACE */
Config_DisplayConfig display;
/* The part of the config that is specific to the Lora Radio */
bool has_lora;
Config_LoRaConfig lora;
Config_LoRaConfig lora;
/* A version integer used to invalidate old save files when we make
incompatible changes This integer is set at build time and is private to
NodeDB.cpp in the device code. */
uint32_t version;
} LocalConfig;
typedef struct _LocalModuleConfig {
/* TODO: REPLACE */
/* The part of the config that is specific to the MQTT module */
bool has_mqtt;
ModuleConfig_MQTTConfig mqtt;
/* TODO: REPLACE */
ModuleConfig_MQTTConfig mqtt;
/* The part of the config that is specific to the Serial module */
bool has_serial;
ModuleConfig_SerialConfig serial;
/* TODO: REPLACE */
ModuleConfig_SerialConfig serial;
/* The part of the config that is specific to the ExternalNotification module */
bool has_external_notification;
ModuleConfig_ExternalNotificationConfig external_notification;
/* TODO: REPLACE */
ModuleConfig_ExternalNotificationConfig external_notification;
/* The part of the config that is specific to the Store & Forward module */
bool has_store_forward;
ModuleConfig_StoreForwardConfig store_forward;
/* TODO: REPLACE */
ModuleConfig_StoreForwardConfig store_forward;
/* The part of the config that is specific to the RangeTest module */
bool has_range_test;
ModuleConfig_RangeTestConfig range_test;
/* TODO: REPLACE */
ModuleConfig_RangeTestConfig range_test;
/* The part of the config that is specific to the Telemetry module */
bool has_telemetry;
ModuleConfig_TelemetryConfig telemetry;
/* TODO: REPLACE */
ModuleConfig_TelemetryConfig telemetry;
/* The part of the config that is specific to the Canned Message module */
bool has_canned_message;
ModuleConfig_CannedMessageConfig canned_message;
ModuleConfig_CannedMessageConfig canned_message;
/* A version integer used to invalidate old save files when we make
incompatible changes This integer is set at build time and is private to
NodeDB.cpp in the device code. */
uint32_t version;
} LocalModuleConfig;
@@ -63,10 +71,10 @@ 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}
#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}
#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}
#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}
#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, 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, 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
@@ -75,6 +83,7 @@ extern "C" {
#define LocalConfig_wifi_tag 4
#define LocalConfig_display_tag 5
#define LocalConfig_lora_tag 6
#define LocalConfig_version_tag 7
#define LocalModuleConfig_mqtt_tag 1
#define LocalModuleConfig_serial_tag 2
#define LocalModuleConfig_external_notification_tag 3
@@ -82,6 +91,7 @@ extern "C" {
#define LocalModuleConfig_range_test_tag 5
#define LocalModuleConfig_telemetry_tag 6
#define LocalModuleConfig_canned_message_tag 7
#define LocalModuleConfig_version_tag 8
/* Struct field encoding specification for nanopb */
#define LocalConfig_FIELDLIST(X, a) \
@@ -90,7 +100,8 @@ 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, display, 5) \
X(a, STATIC, OPTIONAL, MESSAGE, lora, 6)
X(a, STATIC, OPTIONAL, MESSAGE, lora, 6) \
X(a, STATIC, SINGULAR, UINT32, version, 7)
#define LocalConfig_CALLBACK NULL
#define LocalConfig_DEFAULT NULL
#define LocalConfig_device_MSGTYPE Config_DeviceConfig
@@ -107,7 +118,8 @@ X(a, STATIC, OPTIONAL, MESSAGE, external_notification, 3) \
X(a, STATIC, OPTIONAL, MESSAGE, store_forward, 4) \
X(a, STATIC, OPTIONAL, MESSAGE, range_test, 5) \
X(a, STATIC, OPTIONAL, MESSAGE, telemetry, 6) \
X(a, STATIC, OPTIONAL, MESSAGE, canned_message, 7)
X(a, STATIC, OPTIONAL, MESSAGE, canned_message, 7) \
X(a, STATIC, SINGULAR, UINT32, version, 8)
#define LocalModuleConfig_CALLBACK NULL
#define LocalModuleConfig_DEFAULT NULL
#define LocalModuleConfig_mqtt_MSGTYPE ModuleConfig_MQTTConfig
@@ -126,8 +138,8 @@ extern const pb_msgdesc_t LocalModuleConfig_msg;
#define LocalModuleConfig_fields &LocalModuleConfig_msg
/* Maximum encoded size of messages (where known) */
#define LocalConfig_size 331
#define LocalModuleConfig_size 282
#define LocalConfig_size 319
#define LocalModuleConfig_size 288
#ifdef __cplusplus
} /* extern "C" */

View File

@@ -1,5 +1,5 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.5 */
/* Generated by nanopb-0.4.6 */
#include "mesh.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View File

@@ -1,9 +1,10 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.5 */
/* Generated by nanopb-0.4.6 */
#ifndef PB_MESH_PB_H_INCLUDED
#define PB_MESH_PB_H_INCLUDED
#include <pb.h>
#include "config.pb.h"
#include "portnums.pb.h"
#include "telemetry.pb.h"
@@ -237,22 +238,22 @@ typedef enum _LogRecord_Level {
/* Struct definitions */
typedef PB_BYTES_ARRAY_T(237) Compressed_data_t;
typedef struct _Compressed {
PortNum portnum;
Compressed_data_t data;
PortNum portnum;
Compressed_data_t data;
} Compressed;
/* Location of a waypoint to associate with a message */
typedef struct _Location {
/* Id of the location */
uint32_t id;
uint32_t id;
/* latitude_i */
int32_t latitude_i;
int32_t latitude_i;
/* longitude_i */
int32_t longitude_i;
int32_t longitude_i;
/* Time the location is to expire (epoch) */
uint32_t expire;
uint32_t expire;
/* If true, only allow the original sender to update the location. */
bool locked;
bool locked;
} Location;
/* Debug output from the device.
@@ -262,13 +263,13 @@ typedef struct _Location {
and then extend as needed by emitting multiple records. */
typedef struct _LogRecord {
/* Log levels, chosen to match python logging conventions. */
char message[64];
char message[64];
/* Seconds since 1970 - or 0 for unknown/unset */
uint32_t time;
uint32_t time;
/* Usually based on thread name - if known */
char source[8];
char source[8];
/* Not yet set */
LogRecord_Level level;
LogRecord_Level level;
} LogRecord;
/* Unique local debugging info for this node
@@ -277,134 +278,134 @@ typedef struct _LogRecord {
typedef struct _MyNodeInfo {
/* Tells the phone what our node number is, default starting value is
lowbyte of macaddr, but it will be fixed if that is already in use */
uint32_t my_node_num;
uint32_t my_node_num;
/* 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. */
char firmware_version[18];
bool has_gps;
/* 0.0.5 etc... */
CriticalErrorCode error_code;
char firmware_version[18];
/* An error message we'd like to report back to the mothership through analytics.
It indicates a serious bug occurred on the device, the device coped with it,
but we still want to tell the devs about the bug.
This field will be cleared after the phone reads MyNodeInfo
(i.e. it will only be reported once)
a numeric error code to go with error message, zero means no error */
uint32_t error_address;
CriticalErrorCode error_code;
/* A numeric error address (nonzero if available) */
uint32_t error_count;
uint32_t error_address;
/* The total number of errors this node has ever encountered
(well - since the last time we discarded preferences) */
uint32_t reboot_count;
uint32_t error_count;
/* The total number of reboots this node has ever encountered
(well - since the last time we discarded preferences) */
float bitrate;
uint32_t reboot_count;
/* Calculated bitrate of the current channel (in Bytes Per Second) */
uint32_t message_timeout_msec;
float bitrate;
/* How long before we consider a message abandoned and we can clear our
caches of any messages in flight Normally quite large to handle the worst case
message delivery time, 5 minutes.
Formerly called FLOOD_EXPIRE_TIME in the device code */
uint32_t min_app_version;
uint32_t message_timeout_msec;
/* 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 max_channels;
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];
uint32_t air_period_tx[8];
/* 24 time windows of 1hr each with the airtime of valid packets for your mesh. */
pb_size_t air_period_rx_count;
uint32_t air_period_rx[8];
uint32_t air_period_rx[8];
/* Is the device wifi capable? */
bool has_wifi;
bool has_wifi;
/* Utilization for the current channel, including well formed TX, RX and malformed RX (aka noise). */
float channel_utilization;
float channel_utilization;
/* Percent of airtime for transmission used within the last hour. */
float air_util_tx;
float air_util_tx;
} MyNodeInfo;
/* a gps position */
typedef struct _Position {
/* The new preferred location encoding, divide by 1e-7 to get degrees
in floating point */
int32_t latitude_i;
int32_t latitude_i;
/* TODO: REPLACE */
int32_t longitude_i;
int32_t longitude_i;
/* In meters above MSL (but see issue #359) */
int32_t altitude;
int32_t altitude;
/* This is usually not sent over the mesh (to save space), but it is sent
from the phone so that the local device can set its RTC If it is sent over
the mesh (because there are devices on the mesh without GPS), it will only
be sent by devices which has a hardware GPS clock.
seconds since 1970 */
uint32_t time;
uint32_t time;
/* TODO: REPLACE */
Position_LocSource location_source;
Position_LocSource location_source;
/* TODO: REPLACE */
Position_AltSource altitude_source;
Position_AltSource altitude_source;
/* Positional timestamp (actual timestamp of GPS solution) in integer epoch seconds */
uint32_t pos_timestamp;
uint32_t pos_timestamp;
/* Pos. timestamp milliseconds adjustment (rarely available or required) */
int32_t pos_time_millis;
int32_t pos_time_millis;
/* HAE altitude in meters - can be used instead of MSL altitude */
int32_t altitude_hae;
int32_t altitude_hae;
/* Geoidal separation in meters */
int32_t alt_geoid_sep;
int32_t alt_geoid_sep;
/* 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,
in which case PDOP becomes redundant (PDOP=sqrt(HDOP^2 + VDOP^2))
TODO: REMOVE/INTEGRATE */
uint32_t PDOP;
uint32_t PDOP;
/* TODO: REPLACE */
uint32_t HDOP;
uint32_t HDOP;
/* TODO: REPLACE */
uint32_t VDOP;
uint32_t VDOP;
/* GPS accuracy (a hardware specific constant) in mm
multiplied with DOP to calculate positional accuracy
Default: "'bout three meters-ish" :) */
uint32_t gps_accuracy;
uint32_t gps_accuracy;
/* Ground speed in m/s and True North TRACK in 1/100 degrees
Clarification of terms:
- "track" is the direction of motion (measured in horizontal plane)
- "heading" is where the fuselage points (measured in horizontal plane)
- "yaw" indicates a relative rotation about the vertical axis
TODO: REMOVE/INTEGRATE */
uint32_t ground_speed;
uint32_t ground_speed;
/* TODO: REPLACE */
uint32_t ground_track;
uint32_t ground_track;
/* GPS fix quality (from NMEA GxGGA statement or similar) */
uint32_t fix_quality;
uint32_t fix_quality;
/* GPS fix type 2D/3D (from NMEA GxGSA statement) */
uint32_t fix_type;
uint32_t fix_type;
/* GPS "Satellites in View" number */
uint32_t sats_in_view;
uint32_t sats_in_view;
/* Sensor ID - in case multiple positioning sensors are being used */
uint32_t sensor_id;
uint32_t sensor_id;
/* Estimated/expected time (in seconds) until next update:
- 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 pos_next_update;
/* A sequence number, incremented with each Position message to help
detect lost updates if needed */
uint32_t pos_seq_number;
uint32_t pos_seq_number;
} Position;
/* A message used in our Dynamic Source Routing protocol (RFC 4728 based) */
typedef struct _RouteDiscovery {
/* The list of nodenums this packet has visited so far */
pb_size_t route_count;
uint32_t route[8];
uint32_t route[8];
} RouteDiscovery;
/* Compressed message payload */
typedef struct _ToRadio_PeerInfo {
/* PortNum to determine the how to handle the compressed payload. */
uint32_t app_version;
uint32_t app_version;
/* Compressed data. */
bool mqtt_gateway;
bool mqtt_gateway;
} ToRadio_PeerInfo;
/* Broadcast when a newly powered mesh node wants to find a node num it can use
@@ -432,35 +433,35 @@ typedef struct _User {
In the case of Signal that would mean +16504442323, for the default macaddr derived id it would be !<8 hexidecimal bytes>.
Note: app developers are encouraged to also use the following standard
node IDs "^all" (for broadcast), "^local" (for the locally connected node) */
char id[16];
char id[16];
/* A full name for this user, i.e. "Kevin Hester" */
char long_name[40];
char long_name[40];
/* A VERY short name, ideally two characters.
Suitable for a tiny OLED screen */
char short_name[5];
char short_name[5];
/* This is the addr of the radio.
Not populated by the phone, but added by the esp32 when broadcasting */
pb_byte_t macaddr[6];
pb_byte_t macaddr[6];
/* TBEAM, HELTEC, etc...
Starting in 1.2.11 moved to hw_model enum in the NodeInfo object.
Apps will still need the string here for older builds
(so OTA update can find the right image), but if the enum is available it will be used instead. */
HardwareModel hw_model;
HardwareModel hw_model;
/* In some regions Ham radio operators have different bandwidth limitations than others.
If this user is a licensed operator, set this flag.
Also, "long_name" should be their licence number. */
bool is_licensed;
bool is_licensed;
/* Transmit power at antenna connector, in decibel-milliwatt
An optional self-reported value useful in network planning, discovery
and positioning - along with ant_gain_dbi and ant_azimuth below */
uint32_t tx_power_dbm;
uint32_t tx_power_dbm;
/* Antenna gain (applicable to both Tx and Rx), in decibel-isotropic */
uint32_t ant_gain_dbi;
uint32_t ant_gain_dbi;
/* Directional antenna true azimuth *if applicable*, in degrees (0-360)
Only applicable in case of stationary nodes with a directional antenna
Zero = not applicable (mobile or omni) or not specified
(use a value of 360 to indicate an antenna azimuth of zero degrees) */
uint32_t ant_azimuth;
uint32_t ant_azimuth;
} User;
typedef PB_BYTES_ARRAY_T(237) Data_payload_t;
@@ -469,34 +470,34 @@ typedef PB_BYTES_ARRAY_T(237) Data_payload_t;
inside a radio packet (because from/to are broken out by the comms library) */
typedef struct _Data {
/* Formerly named typ and of type Type */
PortNum portnum;
PortNum portnum;
/* TODO: REPLACE */
Data_payload_t payload;
Data_payload_t payload;
/* Not normally used, but for testing a sender can request that recipient
responds in kind (i.e. if it received a position, it should unicast back it's position).
Note: that if you set this on a broadcast you will receive many replies. */
bool want_response;
bool want_response;
/* The address of the destination node.
This field is is filled in by the mesh radio device software, application
layer software should never need it.
RouteDiscovery messages _must_ populate this.
Other message types might need to if they are doing multihop routing. */
uint32_t dest;
uint32_t dest;
/* The address of the original sender for this message.
This field should _only_ be populated for reliable multihop packets (to keep
packets small). */
uint32_t source;
uint32_t source;
/* Only used in routing or response messages.
Indicates the original message ID that this message is reporting failure on. (formerly called original_id) */
uint32_t request_id;
uint32_t request_id;
/* If set, this message is intened to be a reply to a previously sent message with the defined id. */
uint32_t reply_id;
uint32_t reply_id;
/* Defaults to false. If true, then what is in the payload should be treated as an emoji like giving
a message a heart or poop emoji. */
uint32_t emoji;
uint32_t emoji;
/* Location structure */
bool has_location;
Location location;
Location location;
} Data;
/* The bluetooth to device link:
@@ -517,33 +518,36 @@ typedef struct _Data {
Full information about a node on the mesh */
typedef struct _NodeInfo {
/* The node number */
uint32_t num;
uint32_t num;
/* The user info for this node */
bool has_user;
User user;
User user;
/* This position data. Note: before 1.2.14 we would also store the last time we've heard from this node in position.time, that is no longer true.
Position.time now indicates the last time we received a POSITION from that node. */
bool has_position;
Position position;
Position position;
/* Returns the Signal-to-noise ratio (SNR) of the last received message,
as measured by the receiver. Return SNR of the last received message in dB */
float snr;
float snr;
/* Set to indicate the last time we received a packet from this node */
uint32_t last_heard;
uint32_t last_heard;
/* The latest device metrics for the node. */
bool has_device_metrics;
DeviceMetrics device_metrics;
DeviceMetrics device_metrics;
} NodeInfo;
/* A Routing control Data packet handled by the routing module */
typedef struct _Routing {
/* A route request going from the requester */
pb_size_t which_variant;
union {
/* A route request going from the requester */
RouteDiscovery route_request;
/* A route reply */
RouteDiscovery route_reply;
/* A failure in delivering a message (usually used for routing control messages, but might be provided
in addition to ack.fail_id to provide details on the type of failure). */
Routing_Error error_reason;
};
};
} Routing;
typedef PB_BYTES_ARRAY_T(256) MeshPacket_encrypted_t;
@@ -555,10 +559,10 @@ typedef struct _MeshPacket {
Note: Our crypto implementation uses this field as well.
See [crypto](/docs/developers/firmware/encryption) for details.
FIXME - really should be fixed32 instead, this encoding only hurts the ble link though. */
uint32_t from;
uint32_t from;
/* The (immediatSee Priority description for more details.y should be fixed32 instead, this encoding only
hurts the ble link though. */
uint32_t to;
uint32_t to;
/* (Usually) If set, this indicates the index in the secondary_channels table that this packet was sent/received on.
If unset, packet was on the primary channel.
A particular node might know only a subset of channels in use on the mesh.
@@ -566,15 +570,14 @@ typedef struct _MeshPacket {
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'. */
uint8_t channel;
/* TODO: REPLACE */
uint8_t channel;
pb_size_t which_payloadVariant;
union {
/* TODO: REPLACE */
Data decoded;
/* TODO: REPLACE */
MeshPacket_encrypted_t encrypted;
};
/* TODO: REPLACE */
uint32_t id;
};
/* A unique ID for this packet.
Always 0 for no-ack packets or non broadcast packets (and therefore take zero bytes of space).
Otherwise a unique ID for this packet, useful for flooding algorithms.
@@ -585,21 +588,21 @@ typedef struct _MeshPacket {
See [crypto](/docs/developers/firmware/encryption) for details.
FIXME - really should be fixed32 instead, this encoding only
hurts the ble link though. */
uint32_t rx_time;
uint32_t id;
/* The time this message was received by the esp32 (secs since 1970).
Note: this field is _never_ sent on the radio link itself (to save space) Times
are typically not sent over the mesh, but they will be added to any Packet
(chain of SubPacket) sent to the phone (so the phone can know exact time of reception) */
float rx_snr;
uint32_t rx_time;
/* *Never* sent over the radio links.
Set during reception to indicate the SNR of this packet.
Used to collect statistics on current link quality. */
uint8_t hop_limit;
float rx_snr;
/* If unset treated as zero (no forwarding, send to adjacent nodes only)
if 1, allow hopping through one node, etc...
For our usecase real world topologies probably have a max of about 3.
This field is normally placed into a few of bits in the header. */
bool want_ack;
uint8_t hop_limit;
/* This packet is being sent as a reliable message, we would prefer it to arrive at the destination.
We would like to receive a ack packet in response.
Broadcasts messages treat this flag specially: Since acks for broadcasts would
@@ -609,12 +612,14 @@ typedef struct _MeshPacket {
So FloodingRouter.cpp generates an implicit ack which is delivered to the original sender.
If after some time we don't hear anyone rebroadcast our packet, we will timeout and retransmit, using the regular resend logic.
Note: This flag is normally sent in a flag bit in the header when sent over the wire */
MeshPacket_Priority priority;
bool want_ack;
/* The priority of this message for sending.
See MeshPacket.Priority description for more details. */
int32_t rx_rssi;
MeshPacket_Priority priority;
/* rssi of received packet. Only sent to phone for dispay purposes. */
MeshPacket_Delayed delayed;
int32_t rx_rssi;
/* Describe if this message is delayed */
MeshPacket_Delayed delayed;
} MeshPacket;
/* Packets from the radio to the phone will appear on the fromRadio characteristic.
@@ -624,30 +629,58 @@ typedef struct _MeshPacket {
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;
/* Log levels, chosen to match python logging conventions. */
uint32_t id;
pb_size_t which_payloadVariant;
union {
/* 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;
/* One packet is sent for each node in the on radio DB
starts over with the first node in our DB */
NodeInfo node_info;
/* Include a part of the config (was: RadioConfig radio) */
Config config;
/* Set to send debug console output over our protobuf stream */
LogRecord log_record;
/* Sent as true once the device has finished sending all of the responses to want_config
recipient should check if this ID matches our original request nonce, if
not, it means your config responses haven't started yet.
NOTE: This ID must not change - to keep (minimal) compatibility with <1.2 version of android apps. */
uint32_t config_complete_id;
/* Sent to tell clients the radio has just rebooted.
Set to true if present.
Not used on all transports, currently just used for the serial console.
NOTE: This ID must not change - to keep (minimal) compatibility with <1.2 version of android apps. */
bool rebooted;
/* Log levels, chosen to match python logging conventions. */
MeshPacket packet;
};
};
} 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 {
/* Send this packet on the mesh */
pb_size_t which_payloadVariant;
union {
/* Send this packet on the mesh */
MeshPacket packet;
/* Information about the peer, sent after the phone sneds want_config_id.
Old clients do not send this, which is fine. */
ToRadio_PeerInfo peer_info;
/* Phone wants radio to send full node db to the phone, This is
typically the first packet sent to the radio when the phone gets a
bluetooth connection. The radio will respond by sending back a
MyNodeInfo, a owner, a radio config and a series of
FromRadio.node_infos, and config_complete
the integer you write into this field will be reported back in the
config_complete_id response this allows clients to never be confused by
a stale old partially sent config. */
uint32_t want_config_id;
/* Tell API server we are disconnecting now.
This is useful for serial links where there is no hardware/protocol based notification that the client has dropped the link.
(Sending this message is optional for clients) */
bool disconnect;
};
};
} ToRadio;
@@ -819,6 +852,7 @@ extern "C" {
#define FromRadio_id_tag 1
#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
@@ -968,6 +1002,7 @@ X(a, STATIC, SINGULAR, UENUM, level, 4)
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) \
@@ -976,6 +1011,7 @@ X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,packet,packet), 11)
#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_packet_MSGTYPE MeshPacket

View File

@@ -1,5 +1,5 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.5 */
/* Generated by nanopb-0.4.6 */
#include "module_config.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View File

@@ -1,5 +1,5 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.5 */
/* Generated by nanopb-0.4.6 */
#ifndef PB_MODULE_CONFIG_PB_H_INCLUDED
#define PB_MODULE_CONFIG_PB_H_INCLUDED
@@ -49,85 +49,91 @@ typedef enum _ModuleConfig_CannedMessageConfig_InputEventChar {
/* Struct definitions */
typedef struct _ModuleConfig_CannedMessageConfig {
bool rotary1_enabled;
uint32_t inputbroker_pin_a;
uint32_t inputbroker_pin_b;
uint32_t inputbroker_pin_press;
ModuleConfig_CannedMessageConfig_InputEventChar inputbroker_event_cw;
ModuleConfig_CannedMessageConfig_InputEventChar inputbroker_event_ccw;
ModuleConfig_CannedMessageConfig_InputEventChar inputbroker_event_press;
bool updown1_enabled;
bool enabled;
char allow_input_source[16];
bool send_bell;
bool rotary1_enabled;
uint32_t inputbroker_pin_a;
uint32_t inputbroker_pin_b;
uint32_t inputbroker_pin_press;
ModuleConfig_CannedMessageConfig_InputEventChar inputbroker_event_cw;
ModuleConfig_CannedMessageConfig_InputEventChar inputbroker_event_ccw;
ModuleConfig_CannedMessageConfig_InputEventChar inputbroker_event_press;
bool updown1_enabled;
bool enabled;
char allow_input_source[16];
bool send_bell;
} ModuleConfig_CannedMessageConfig;
typedef struct _ModuleConfig_ExternalNotificationConfig {
bool enabled;
uint32_t output_ms;
uint32_t output;
bool active;
bool alert_message;
bool alert_bell;
bool enabled;
uint32_t output_ms;
uint32_t output;
bool active;
bool alert_message;
bool alert_bell;
} ModuleConfig_ExternalNotificationConfig;
typedef struct _ModuleConfig_MQTTConfig {
bool disabled;
char address[32];
char username[32];
char password[32];
bool encryption_enabled;
bool disabled;
char address[32];
char username[32];
char password[32];
bool encryption_enabled;
} ModuleConfig_MQTTConfig;
typedef struct _ModuleConfig_RangeTestConfig {
bool enabled;
uint32_t sender;
bool save;
bool enabled;
uint32_t sender;
bool save;
} ModuleConfig_RangeTestConfig;
typedef struct _ModuleConfig_SerialConfig {
bool enabled;
bool echo;
uint32_t rxd;
uint32_t txd;
ModuleConfig_SerialConfig_Serial_Baud baud;
uint32_t timeout;
ModuleConfig_SerialConfig_Serial_Mode mode;
bool enabled;
bool echo;
uint32_t rxd;
uint32_t txd;
ModuleConfig_SerialConfig_Serial_Baud baud;
uint32_t timeout;
ModuleConfig_SerialConfig_Serial_Mode mode;
} ModuleConfig_SerialConfig;
typedef struct _ModuleConfig_StoreForwardConfig {
bool enabled;
bool heartbeat;
uint32_t records;
uint32_t history_return_max;
uint32_t history_return_window;
bool enabled;
bool heartbeat;
uint32_t records;
uint32_t history_return_max;
uint32_t history_return_window;
} ModuleConfig_StoreForwardConfig;
typedef struct _ModuleConfig_TelemetryConfig {
uint32_t device_update_interval;
uint32_t environment_update_interval;
bool environment_measurement_enabled;
bool environment_screen_enabled;
uint32_t environment_read_error_count_threshold;
uint32_t environment_recovery_interval;
bool environment_display_fahrenheit;
TelemetrySensorType environment_sensor_type;
uint32_t environment_sensor_pin;
uint32_t device_update_interval;
uint32_t environment_update_interval;
bool environment_measurement_enabled;
bool environment_screen_enabled;
uint32_t environment_read_error_count_threshold;
uint32_t environment_recovery_interval;
bool environment_display_fahrenheit;
TelemetrySensorType environment_sensor_type;
uint32_t environment_sensor_pin;
} ModuleConfig_TelemetryConfig;
/* TODO: REPLACE */
/* Module Config */
typedef struct _ModuleConfig {
/* TODO: REPLACE */
pb_size_t which_payloadVariant;
union {
/* TODO: REPLACE */
ModuleConfig_MQTTConfig mqtt;
/* TODO: REPLACE */
ModuleConfig_SerialConfig serial;
/* TODO: REPLACE */
ModuleConfig_ExternalNotificationConfig external_notification;
/* TODO: REPLACE */
ModuleConfig_StoreForwardConfig store_forward;
/* TODO: REPLACE */
ModuleConfig_RangeTestConfig range_test;
/* TODO: REPLACE */
ModuleConfig_TelemetryConfig telemetry;
/* TODO: REPLACE */
ModuleConfig_CannedMessageConfig canned_message;
} payloadVariant;
} payloadVariant;
} ModuleConfig;

View File

@@ -1,5 +1,5 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.5 */
/* Generated by nanopb-0.4.6 */
#include "mqtt.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View File

@@ -1,5 +1,5 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.5 */
/* Generated by nanopb-0.4.6 */
#ifndef PB_MQTT_PB_H_INCLUDED
#define PB_MQTT_PB_H_INCLUDED
@@ -14,13 +14,13 @@
/* This message wraps a MeshPacket with extra metadata about the sender and how it arrived. */
typedef struct _ServiceEnvelope {
/* The (probably encrypted) packet */
struct _MeshPacket *packet;
struct _MeshPacket *packet;
/* The global channel ID it was sent on */
char *channel_id;
char *channel_id;
/* The sending gateway node ID. Can we use this to authenticate/prevent fake
nodeid impersonation for senders? - i.e. use gateway/mesh id (which is authenticated) + local node id as
the globally trusted nodenum */
char *gateway_id;
char *gateway_id;
} ServiceEnvelope;

View File

@@ -1,5 +1,5 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.5 */
/* Generated by nanopb-0.4.6 */
#include "portnums.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View File

@@ -1,5 +1,5 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.5 */
/* Generated by nanopb-0.4.6 */
#ifndef PB_PORTNUMS_PB_H_INCLUDED
#define PB_PORTNUMS_PB_H_INCLUDED
@@ -48,6 +48,8 @@ typedef enum _PortNum {
PortNum_ADMIN_APP = 6,
/* Compressed TEXT_MESSAGE payloads. */
PortNum_TEXT_MESSAGE_COMPRESSED_APP = 7,
/* Waypoint payloads. */
PortNum_WAYPOINT_APP = 8,
/* Provides a 'ping' service that replies to any packet it receives.
Also serves as a small example module. */
PortNum_REPLY_APP = 32,

View File

@@ -1,5 +1,5 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.5 */
/* Generated by nanopb-0.4.6 */
#include "remote_hardware.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View File

@@ -1,5 +1,5 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.5 */
/* Generated by nanopb-0.4.6 */
#ifndef PB_REMOTE_HARDWARE_PB_H_INCLUDED
#define PB_REMOTE_HARDWARE_PB_H_INCLUDED
@@ -31,12 +31,12 @@ 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 typ;
/* What gpios are we changing. Not used for all MessageTypes, see MessageType for details */
uint64_t gpio_mask;
uint64_t gpio_mask;
/* For gpios that were listed in gpio_mask as valid, what are the signal levels for those gpios.
Not used for all MessageTypes, see MessageType for details */
uint64_t gpio_value;
uint64_t gpio_value;
} HardwareMessage;

View File

@@ -1,5 +1,5 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.5 */
/* Generated by nanopb-0.4.6 */
#include "storeforward.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View File

@@ -1,5 +1,5 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.5 */
/* Generated by nanopb-0.4.6 */
#ifndef PB_STOREFORWARD_PB_H_INCLUDED
#define PB_STOREFORWARD_PB_H_INCLUDED
@@ -28,41 +28,41 @@ typedef enum _StoreAndForward_RequestResponse {
/* Struct definitions */
typedef struct _StoreAndForward_Heartbeat {
uint32_t period;
uint32_t secondary;
uint32_t period;
uint32_t secondary;
} StoreAndForward_Heartbeat;
typedef struct _StoreAndForward_History {
uint32_t history_messages;
uint32_t window;
uint32_t last_request;
uint32_t history_messages;
uint32_t window;
uint32_t last_request;
} StoreAndForward_History;
typedef struct _StoreAndForward_Statistics {
uint32_t messages_total;
uint32_t messages_saved;
uint32_t messages_max;
uint32_t up_time;
uint32_t requests;
uint32_t requests_history;
bool heartbeat;
uint32_t return_max;
uint32_t return_window;
uint32_t messages_total;
uint32_t messages_saved;
uint32_t messages_max;
uint32_t up_time;
uint32_t requests;
uint32_t requests_history;
bool heartbeat;
uint32_t return_max;
uint32_t return_window;
} StoreAndForward_Statistics;
/* TODO: REPLACE */
typedef struct _StoreAndForward {
/* TODO: REPLACE */
StoreAndForward_RequestResponse rr;
StoreAndForward_RequestResponse rr;
/* TODO: REPLACE */
bool has_stats;
StoreAndForward_Statistics stats;
StoreAndForward_Statistics stats;
/* TODO: REPLACE */
bool has_history;
StoreAndForward_History history;
StoreAndForward_History history;
/* TODO: REPLACE */
bool has_heartbeat;
StoreAndForward_Heartbeat heartbeat;
StoreAndForward_Heartbeat heartbeat;
} StoreAndForward;

View File

@@ -1,5 +1,5 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.5 */
/* Generated by nanopb-0.4.6 */
#include "telemetry.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View File

@@ -1,5 +1,5 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.5 */
/* Generated by nanopb-0.4.6 */
#ifndef PB_TELEMETRY_PB_H_INCLUDED
#define PB_TELEMETRY_PB_H_INCLUDED
@@ -12,55 +12,59 @@
/* Enum definitions */
/* TODO: REPLACE */
typedef enum _TelemetrySensorType {
/* No external telemetry sensor */
/* No external telemetry sensor explicitly set */
TelemetrySensorType_NotSet = 0,
/* TODO: REPLACE */
/* Moderate accuracy temperature */
TelemetrySensorType_DHT11 = 1,
/* TODO: REPLACE */
/* High accuracy temperature */
TelemetrySensorType_DS18B20 = 2,
/* TODO: REPLACE */
/* Moderate accuracy temperature and humidity */
TelemetrySensorType_DHT12 = 3,
/* TODO: REPLACE */
/* Moderate accuracy temperature and humidity */
TelemetrySensorType_DHT21 = 4,
/* TODO: REPLACE */
/* Moderate accuracy temperature and humidity */
TelemetrySensorType_DHT22 = 5,
/* TODO: REPLACE */
/* High accuracy temperature, pressure, humidity */
TelemetrySensorType_BME280 = 6,
/* TODO: REPLACE */
/* High accuracy temperature, pressure, humidity, and air resistance */
TelemetrySensorType_BME680 = 7,
/* TODO: REPLACE */
/* Very high accuracy temperature */
TelemetrySensorType_MCP9808 = 8,
/* TODO: REPLACE */
TelemetrySensorType_SHTC3 = 9
/* Moderate accuracy temperature and humidity */
TelemetrySensorType_SHTC3 = 9,
/* Moderate accuracy current and voltage */
TelemetrySensorType_INA260 = 10,
/* Moderate accuracy current and voltage */
TelemetrySensorType_INA219 = 11
} TelemetrySensorType;
/* Struct definitions */
/* Key native device metrics such as battery level */
typedef struct _DeviceMetrics {
/* 1-100 (0 means powered) */
uint32_t battery_level;
uint32_t battery_level;
/* Voltage measured */
float voltage;
float voltage;
/* Utilization for the current channel, including well formed TX, RX and malformed RX (aka noise). */
float channel_utilization;
float channel_utilization;
/* Percent of airtime for transmission used within the last hour. */
float air_util_tx;
float air_util_tx;
} DeviceMetrics;
/* Weather station or other environmental metrics */
typedef struct _EnvironmentMetrics {
/* Temperature measured */
float temperature;
float temperature;
/* Relative humidity percent measured */
float relative_humidity;
float relative_humidity;
/* Barometric pressure in hPA measured */
float barometric_pressure;
float barometric_pressure;
/* Gas resistance in mOhm measured */
float gas_resistance;
float gas_resistance;
/* Voltage measured */
float voltage;
float voltage;
/* Current measured */
float current;
float current;
} EnvironmentMetrics;
/* Types of Measurements the telemetry module is equipped to handle */
@@ -70,20 +74,21 @@ typedef struct _Telemetry {
the mesh (because there are devices on the mesh without GPS), it will only
be sent by devices which has a hardware GPS clock (IE Mobile Phone).
seconds since 1970 */
uint32_t time;
/* Key native device metrics such as battery level */
uint32_t time;
pb_size_t which_variant;
union {
/* Key native device metrics such as battery level */
DeviceMetrics device_metrics;
/* Weather station or other environmental metrics */
EnvironmentMetrics environment_metrics;
} variant;
} variant;
} Telemetry;
/* Helper constants for enums */
#define _TelemetrySensorType_MIN TelemetrySensorType_NotSet
#define _TelemetrySensorType_MAX TelemetrySensorType_SHTC3
#define _TelemetrySensorType_ARRAYSIZE ((TelemetrySensorType)(TelemetrySensorType_SHTC3+1))
#define _TelemetrySensorType_MAX TelemetrySensorType_INA219
#define _TelemetrySensorType_ARRAYSIZE ((TelemetrySensorType)(TelemetrySensorType_INA219+1))
#ifdef __cplusplus

View File

@@ -716,8 +716,6 @@ void handleAdminSettings(HTTPRequest *req, HTTPResponse *res)
res->println("<tr><td><input type=checkbox></td><td>WiFi Password</td><td>false</td><td><input type=radio></td></tr>\n");
res->println(
"<tr><td><input type=checkbox></td><td>Smart Position Update</td><td>false</td><td><input type=radio></td></tr>\n");
res->println("<tr><td><input type=checkbox></td><td>is_always_powered</td><td>false</td><td><input type=radio></td></tr>\n");
res->println("<tr><td><input type=checkbox></td><td>is_always_powered</td><td>false</td><td><input type=radio></td></tr>\n");
res->println("</table>\n");
res->println("<table>\n");
res->println("<input type=submit value=Apply New Settings>\n");

View File

@@ -222,7 +222,7 @@ bool initWifi(bool forceSoftAP)
// The configurations on softAP are from the espresif library
int ok = WiFi.softAP(wifiName, wifiPsw, 1, 1, 4);
DEBUG_MSG("Starting hiddem WIFI AP: ssid=%s, ok=%d\n", wifiName, ok);
DEBUG_MSG("Starting hidden WIFI AP: ssid=%s, ok=%d\n", wifiName, ok);
} else {
int ok = WiFi.softAP(wifiName, wifiPsw);
DEBUG_MSG("Starting WIFI AP: ssid=%s, ok=%d\n", wifiName, ok);

View File

@@ -17,14 +17,6 @@ AdminModule *adminModule;
/// a change.
static const char *secretReserved = "sekrit";
/// If buf is !empty, change it to secret
static void hideSecret(char *buf)
{
if (*buf) {
strcpy(buf, secretReserved);
}
}
/// If buf is the reserved secret word, replace the buffer with currentVal
static void writeSecret(char *buf, const char *currentVal)
{
@@ -314,11 +306,10 @@ void AdminModule::handleGetConfig(const MeshPacket &req, const uint32_t configTy
break;
}
// NOTE: The phone app needs to know the ls_secs & phone_timeout value so it can properly expect sleep behavior.
// 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).
// r.get_radio_response.preferences.ls_secs = getPref_ls_secs();
// r.get_radio_response.preferences.phone_timeout_secs = getPref_phone_timeout_secs();
// 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;
@@ -371,11 +362,10 @@ void AdminModule::handleGetModuleConfig(const MeshPacket &req, const uint32_t co
break;
}
// NOTE: The phone app needs to know the ls_secs & phone_timeout value so it can properly expect sleep behavior.
// NOTE: The phone app needs to know the ls_secsvalue 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).
// r.get_radio_response.preferences.ls_secs = getPref_ls_secs();
// r.get_radio_response.preferences.phone_timeout_secs = getPref_phone_timeout_secs();
// 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;

View File

@@ -16,12 +16,17 @@
#include "Sensor/DHTSensor.h"
#include "Sensor/DallasSensor.h"
#include "Sensor/MCP9808Sensor.h"
#include "Sensor/INA260Sensor.h"
#include "Sensor/INA219Sensor.h"
BME280Sensor bme280Sensor;
BME680Sensor bme680Sensor;
DHTSensor dhtSensor;
DallasSensor dallasSensor;
MCP9808Sensor mcp9808Sensor;
INA260Sensor ina260Sensor;
INA219Sensor ina219Sensor;
#define FAILED_STATE_SENSOR_READ_MULTIPLIER 10
#define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true
@@ -45,10 +50,12 @@ MCP9808Sensor mcp9808Sensor;
int32_t EnvironmentTelemetryModule::runOnce()
{
#ifndef PORTDUINO
int32_t result = INT32_MAX;
/*
Uncomment the preferences below if you want to use the module
without having to configure it from the PythonAPI or WebUI.
*/
/*
moduleConfig.telemetry.environment_measurement_enabled = 1;
moduleConfig.telemetry.environment_screen_enabled = 1;
@@ -62,7 +69,7 @@ int32_t EnvironmentTelemetryModule::runOnce()
if (!(moduleConfig.telemetry.environment_measurement_enabled ||
moduleConfig.telemetry.environment_screen_enabled)) {
// If this module is not enabled, and the user doesn't want the display screen don't waste any OSThread time on it
return (INT32_MAX);
return result;
}
if (firstTime) {
@@ -73,32 +80,37 @@ int32_t EnvironmentTelemetryModule::runOnce()
DEBUG_MSG("Environment Telemetry: Initializing\n");
// it's possible to have this module enabled, only for displaying values on the screen.
// therefore, we should only enable the sensor loop if measurement is also enabled
switch (moduleConfig.telemetry.environment_sensor_type) {
case TelemetrySensorType_DHT11:
case TelemetrySensorType_DHT12:
case TelemetrySensorType_DHT21:
case TelemetrySensorType_DHT22:
return dhtSensor.runOnce();
case TelemetrySensorType_DS18B20:
return dallasSensor.runOnce();
case TelemetrySensorType_BME280:
return bme280Sensor.runOnce();
case TelemetrySensorType_BME680:
return bme680Sensor.runOnce();
case TelemetrySensorType_MCP9808:
return mcp9808Sensor.runOnce();
default:
DEBUG_MSG("Environment Telemetry: Invalid sensor type selected; Disabling module");
return (INT32_MAX);
case TelemetrySensorType_DHT11:
case TelemetrySensorType_DHT12:
case TelemetrySensorType_DHT21:
case TelemetrySensorType_DHT22:
result = dhtSensor.runOnce();
break;
case TelemetrySensorType_DS18B20:
result = dallasSensor.runOnce();
break;
default:
DEBUG_MSG("Environment Telemetry: No sensor type specified; Checking for detected i2c sensors\n");
break;
}
if (bme680Sensor.hasSensor())
result = bme680Sensor.runOnce();
if (bme280Sensor.hasSensor())
result = bme280Sensor.runOnce();
if (mcp9808Sensor.hasSensor())
result = mcp9808Sensor.runOnce();
if (ina260Sensor.hasSensor())
result = ina260Sensor.runOnce();
if (ina219Sensor.hasSensor())
result = ina219Sensor.runOnce();
}
return (INT32_MAX);
return result;
} else {
// if we somehow got to a second run of this module with measurement disabled, then just wait forever
if (!moduleConfig.telemetry.environment_measurement_enabled)
return (INT32_MAX);
return result;
// this is not the first time OSThread library has called this function
// so just do what we intend to do on the interval
if (sensor_read_error_count > moduleConfig.telemetry.environment_read_error_count_threshold) {
@@ -114,7 +126,7 @@ int32_t EnvironmentTelemetryModule::runOnce()
DEBUG_MSG("Environment Telemetry: DISABLED; The telemetry_module_environment_read_error_count_threshold has "
"been exceed: %d. Reads will not be retried until after device reset\n",
moduleConfig.telemetry.environment_read_error_count_threshold);
return (INT32_MAX);
return result;
} else if (sensor_read_error_count > 0) {
DEBUG_MSG("Environment Telemetry: There have been %d sensor read failures. Will retry %d more times\n",
@@ -124,23 +136,7 @@ int32_t EnvironmentTelemetryModule::runOnce()
if (!sendOurTelemetry()) {
// if we failed to read the sensor, then try again
// as soon as we can according to the maximum polling frequency
switch (moduleConfig.telemetry.environment_sensor_type) {
case TelemetrySensorType_DHT11:
case TelemetrySensorType_DHT12:
case TelemetrySensorType_DHT21:
case TelemetrySensorType_DHT22:
return (DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
case TelemetrySensorType_DS18B20:
return (DS18B20_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
case TelemetrySensorType_BME280:
case TelemetrySensorType_BME680:
return (BME_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
case TelemetrySensorType_MCP9808:
return (MCP_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
default:
return (DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
}
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
}
return getIntervalOrDefaultMs(moduleConfig.telemetry.environment_update_interval);
@@ -245,29 +241,30 @@ bool EnvironmentTelemetryModule::sendOurTelemetry(NodeNum dest, bool wantReplies
DEBUG_MSG("Environment Telemetry: Read data\n");
switch (moduleConfig.telemetry.environment_sensor_type) {
case TelemetrySensorType_DS18B20:
if (!dallasSensor.getMeasurement(&m))
sensor_read_error_count++;
break;
case TelemetrySensorType_DHT11:
case TelemetrySensorType_DHT12:
case TelemetrySensorType_DHT21:
case TelemetrySensorType_DHT22:
if (!dhtSensor.getMeasurement(&m))
sensor_read_error_count++;
break;
case TelemetrySensorType_BME280:
bme280Sensor.getMeasurement(&m);
break;
case TelemetrySensorType_BME680:
bme680Sensor.getMeasurement(&m);
break;
case TelemetrySensorType_MCP9808:
mcp9808Sensor.getMeasurement(&m);
break;
default:
DEBUG_MSG("Environment Telemetry: No external sensor type selected; Only sending internal metrics\n");
case TelemetrySensorType_DS18B20:
if (!dallasSensor.getMetrics(&m))
sensor_read_error_count++;
break;
case TelemetrySensorType_DHT11:
case TelemetrySensorType_DHT12:
case TelemetrySensorType_DHT21:
case TelemetrySensorType_DHT22:
if (!dhtSensor.getMetrics(&m))
sensor_read_error_count++;
break;
default:
DEBUG_MSG("Environment Telemetry: No specified sensor type; Trying any detected i2c sensors\n");
}
if (bme280Sensor.hasSensor())
bme280Sensor.getMetrics(&m);
if (bme680Sensor.hasSensor())
bme680Sensor.getMetrics(&m);
if (mcp9808Sensor.hasSensor())
mcp9808Sensor.getMetrics(&m);
if (ina219Sensor.hasSensor())
ina219Sensor.getMetrics(&m);
if (ina260Sensor.hasSensor())
ina260Sensor.getMetrics(&m);
DEBUG_MSG("Telemetry->time: %i\n", m.time);
DEBUG_MSG("Telemetry->barometric_pressure: %f\n", m.variant.environment_metrics.barometric_pressure);

View File

@@ -3,24 +3,26 @@
#include "TelemetrySensor.h"
#include "BME280Sensor.h"
#include <Adafruit_BME280.h>
#include <typeinfo>
BME280Sensor::BME280Sensor() : TelemetrySensor {} {
BME280Sensor::BME280Sensor() :
TelemetrySensor(TelemetrySensorType_BME280, "BME280")
{
}
int32_t BME280Sensor::runOnce() {
unsigned bme280Status;
// Default i2c address for BME280
bme280Status = bme280.begin(0x76);
if (!bme280Status) {
DEBUG_MSG("Could not find a valid BME280 sensor, check wiring, address, sensor ID!");
// TODO more verbose diagnostics
} else {
DEBUG_MSG("Telemetry: Opened BME280 on default i2c bus");
DEBUG_MSG("Init sensor: %s\n", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
return BME_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
status = bme280.begin(nodeTelemetrySensorsMap[sensorType]);
return initI2CSensor();
}
bool BME280Sensor::getMeasurement(Telemetry *measurement) {
void BME280Sensor::setup() { }
bool BME280Sensor::getMetrics(Telemetry *measurement) {
DEBUG_MSG("BME280Sensor::getMetrics\n");
measurement->variant.environment_metrics.temperature = bme280.readTemperature();
measurement->variant.environment_metrics.relative_humidity = bme280.readHumidity();
measurement->variant.environment_metrics.barometric_pressure = bme280.readPressure() / 100.0F;

View File

@@ -2,14 +2,15 @@
#include "TelemetrySensor.h"
#include <Adafruit_BME280.h>
#define BME_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
class BME280Sensor : virtual public TelemetrySensor {
private:
Adafruit_BME280 bme280;
protected:
virtual void setup() override;
public:
BME280Sensor();
virtual int32_t runOnce() override;
virtual bool getMeasurement(Telemetry *measurement) override;
virtual bool getMetrics(Telemetry *measurement) override;
};

View File

@@ -4,29 +4,31 @@
#include "BME680Sensor.h"
#include <Adafruit_BME680.h>
BME680Sensor::BME680Sensor() : TelemetrySensor {} {
BME680Sensor::BME680Sensor() :
TelemetrySensor(TelemetrySensorType_BME680, "BME680")
{
}
int32_t BME680Sensor::runOnce() {
unsigned bme680Status;
// Default i2c address for BME680
bme680Status = bme680.begin(0x76);
if (!bme680Status) {
DEBUG_MSG("Could not find a valid BME680 sensor, check wiring, address, sensor ID!");
// TODO more verbose TelemetrySensor
} else {
DEBUG_MSG("Telemetry: Opened BME680 on default i2c bus");
// Set up oversampling and filter initialization
bme680.setTemperatureOversampling(BME680_OS_8X);
bme680.setHumidityOversampling(BME680_OS_2X);
bme680.setPressureOversampling(BME680_OS_4X);
bme680.setIIRFilterSize(BME680_FILTER_SIZE_3);
bme680.setGasHeater(320, 150); // 320*C for 150 ms
DEBUG_MSG("Init sensor: %s\n", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
return (BME_680_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
status = bme680.begin(nodeTelemetrySensorsMap[sensorType]);
return initI2CSensor();
}
bool BME680Sensor::getMeasurement(Telemetry *measurement) {
void BME680Sensor::setup()
{
// Set up oversampling and filter initialization
bme680.setTemperatureOversampling(BME680_OS_8X);
bme680.setHumidityOversampling(BME680_OS_2X);
bme680.setPressureOversampling(BME680_OS_4X);
bme680.setIIRFilterSize(BME680_FILTER_SIZE_3);
bme680.setGasHeater(320, 150); // 320*C for 150 ms
}
bool BME680Sensor::getMetrics(Telemetry *measurement) {
measurement->variant.environment_metrics.temperature = bme680.readTemperature();
measurement->variant.environment_metrics.relative_humidity = bme680.readHumidity();
measurement->variant.environment_metrics.barometric_pressure = bme680.readPressure() / 100.0F;

View File

@@ -2,14 +2,15 @@
#include "TelemetrySensor.h"
#include <Adafruit_BME680.h>
#define BME_680_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
class BME680Sensor : virtual public TelemetrySensor {
private:
Adafruit_BME680 bme680;
protected:
virtual void setup() override;
public:
BME680Sensor();
virtual int32_t runOnce() override;
virtual bool getMeasurement(Telemetry *measurement) override;
virtual bool getMetrics(Telemetry *measurement) override;
};

View File

@@ -5,11 +5,14 @@
#include "configuration.h"
#include <DHT.h>
DHTSensor::DHTSensor() : TelemetrySensor{} {}
int32_t DHTSensor::runOnce()
DHTSensor::DHTSensor() :
TelemetrySensor(TelemetrySensorType_NotSet, "DHT")
{
if (TelemetrySensorType_DHT11 || TelemetrySensorType_DHT12) {
}
int32_t DHTSensor::runOnce() {
if (moduleConfig.telemetry.environment_sensor_type == TelemetrySensorType_DHT11 ||
moduleConfig.telemetry.environment_sensor_type == TelemetrySensorType_DHT12) {
dht = new DHT(moduleConfig.telemetry.environment_sensor_pin, DHT11);
} else {
dht = new DHT(moduleConfig.telemetry.environment_sensor_pin, DHT22);
@@ -17,13 +20,15 @@ int32_t DHTSensor::runOnce()
dht->begin();
dht->read();
DEBUG_MSG("Telemetry: Opened DHT11/DHT12 on pin: %d\n", moduleConfig.telemetry.environment_sensor_pin);
DEBUG_MSG("Opened DHT11/DHT12 on pin: %d\n", moduleConfig.telemetry.environment_sensor_pin);
return (DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
bool DHTSensor::getMeasurement(Telemetry *measurement)
{
void DHTSensor::setup() { }
bool DHTSensor::getMetrics(Telemetry *measurement) {
DEBUG_MSG("DHTSensor::getMetrics\n");
if (!dht->read(true)) {
DEBUG_MSG("Telemetry: FAILED TO READ DATA\n");
return false;

View File

@@ -2,14 +2,15 @@
#include "TelemetrySensor.h"
#include <DHT.h>
#define DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
class DHTSensor : virtual public TelemetrySensor {
private:
DHT *dht = NULL;
protected:
virtual void setup() override;
public:
DHTSensor();
virtual int32_t runOnce() override;
virtual bool getMeasurement(Telemetry *measurement) override;
virtual bool getMetrics(Telemetry *measurement) override;
};

View File

@@ -6,21 +6,25 @@
#include <DS18B20.h>
#include <OneWire.h>
DallasSensor::DallasSensor() : TelemetrySensor{} {}
int32_t DallasSensor::runOnce()
DallasSensor::DallasSensor() :
TelemetrySensor(TelemetrySensorType_DS18B20, "DS18B20")
{
}
int32_t DallasSensor::runOnce() {
oneWire = new OneWire(moduleConfig.telemetry.environment_sensor_pin);
ds18b20 = new DS18B20(oneWire);
ds18b20->begin();
ds18b20->setResolution(12);
ds18b20->requestTemperatures();
DEBUG_MSG("Telemetry: Opened DS18B20 on pin: %d\n", moduleConfig.telemetry.environment_sensor_pin);
return (DS18B20_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
DEBUG_MSG("Opened DS18B20 on pin: %d\n", moduleConfig.telemetry.environment_sensor_pin);
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
bool DallasSensor::getMeasurement(Telemetry *measurement)
{
void DallasSensor::setup() {}
bool DallasSensor::getMetrics(Telemetry *measurement){
DEBUG_MSG("DallasSensor::getMetrics\n");
if (ds18b20->isConversionComplete()) {
measurement->variant.environment_metrics.temperature = ds18b20->getTempC();
measurement->variant.environment_metrics.relative_humidity = 0;

View File

@@ -3,15 +3,16 @@
#include <DS18B20.h>
#include <OneWire.h>
#define DS18B20_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
class DallasSensor : virtual public TelemetrySensor {
private:
OneWire *oneWire = NULL;
DS18B20 *ds18b20 = NULL;
protected:
virtual void setup() override;
public:
DallasSensor();
virtual int32_t runOnce() override;
virtual bool getMeasurement(Telemetry *measurement) override;
virtual bool getMetrics(Telemetry *measurement) override;
};

View File

@@ -0,0 +1,30 @@
#include "../mesh/generated/telemetry.pb.h"
#include "configuration.h"
#include "TelemetrySensor.h"
#include "INA219Sensor.h"
#include <Adafruit_INA219.h>
INA219Sensor::INA219Sensor() :
TelemetrySensor(TelemetrySensorType_INA219, "INA219")
{
}
int32_t INA219Sensor::runOnce() {
DEBUG_MSG("Init sensor: %s\n", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
ina219 = Adafruit_INA219(nodeTelemetrySensorsMap[sensorType]);
status = ina219.begin();
return initI2CSensor();
}
void INA219Sensor::setup()
{
}
bool INA219Sensor::getMetrics(Telemetry *measurement) {
measurement->variant.environment_metrics.voltage = ina219.getBusVoltage_V();
measurement->variant.environment_metrics.current = ina219.getCurrent_mA();
return true;
}

View File

@@ -0,0 +1,17 @@
#include "../mesh/generated/telemetry.pb.h"
#include "TelemetrySensor.h"
#include <Adafruit_INA219.h>
class INA219Sensor : virtual public TelemetrySensor {
private:
Adafruit_INA219 ina219;
protected:
virtual void setup() override;
public:
INA219Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(Telemetry *measurement) override;
};

View File

@@ -0,0 +1,30 @@
#include "../mesh/generated/telemetry.pb.h"
#include "configuration.h"
#include "TelemetrySensor.h"
#include "INA260Sensor.h"
#include <Adafruit_INA260.h>
INA260Sensor::INA260Sensor() :
TelemetrySensor(TelemetrySensorType_INA260, "INA260")
{
}
int32_t INA260Sensor::runOnce() {
DEBUG_MSG("Init sensor: %s\n", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
status = ina260.begin(nodeTelemetrySensorsMap[sensorType]);
return initI2CSensor();
}
void INA260Sensor::setup()
{
}
bool INA260Sensor::getMetrics(Telemetry *measurement) {
// mV conversion to V
measurement->variant.environment_metrics.voltage = ina260.readBusVoltage() / 1000;
measurement->variant.environment_metrics.current = ina260.readCurrent();
return true;
}

View File

@@ -0,0 +1,17 @@
#include "../mesh/generated/telemetry.pb.h"
#include "TelemetrySensor.h"
#include <Adafruit_INA260.h>
class INA260Sensor : virtual public TelemetrySensor {
private:
Adafruit_INA260 ina260 = Adafruit_INA260();
protected:
virtual void setup() override;
public:
INA260Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(Telemetry *measurement) override;
};

View File

@@ -4,25 +4,26 @@
#include "MCP9808Sensor.h"
#include <Adafruit_MCP9808.h>
MCP9808Sensor::MCP9808Sensor() : TelemetrySensor {} {
MCP9808Sensor::MCP9808Sensor() :
TelemetrySensor(TelemetrySensorType_MCP9808, "MCP9808")
{
}
int32_t MCP9808Sensor::runOnce() {
unsigned mcp9808Status;
// Default i2c address for MCP9808
mcp9808Status = mcp9808.begin(0x18);
if (!mcp9808Status) {
DEBUG_MSG("Could not find a valid MCP9808 sensor, check wiring, address, sensor ID!");
} else {
DEBUG_MSG("TelemetrySensor: Opened MCP9808 on default i2c bus");
// Reduce resolution from 0.0625 degrees (precision) to 0.125 degrees (high).
mcp9808.setResolution(2);
DEBUG_MSG("Init sensor: %s\n", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
return (MCP_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
status = mcp9808.begin(nodeTelemetrySensorsMap[sensorType]);
return initI2CSensor();
}
bool MCP9808Sensor::getMeasurement(Telemetry *measurement) {
measurement->variant.environment_metrics.temperature = mcp9808.readTempC();
void MCP9808Sensor::setup() {
mcp9808.setResolution(2);
}
bool MCP9808Sensor::getMetrics(Telemetry *measurement) {
DEBUG_MSG("MCP9808Sensor::getMetrics\n");
measurement->variant.environment_metrics.temperature = mcp9808.readTempC();
return true;
}

View File

@@ -2,14 +2,15 @@
#include "TelemetrySensor.h"
#include <Adafruit_MCP9808.h>
#define MCP_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
class MCP9808Sensor : virtual public TelemetrySensor {
private:
Adafruit_MCP9808 mcp9808;
protected:
virtual void setup() override;
public:
MCP9808Sensor();
virtual int32_t runOnce() override;
virtual bool getMeasurement(Telemetry *measurement) override;
virtual bool getMetrics(Telemetry *measurement) override;
};

View File

@@ -0,0 +1,4 @@
#include "TelemetrySensor.h"
#include "../mesh/generated/telemetry.pb.h"
#include "NodeDB.h"
#include "main.h"

View File

@@ -1,14 +1,41 @@
#pragma once
#include "../mesh/generated/telemetry.pb.h"
#include "NodeDB.h"
#include "main.h"
#define DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
class TelemetrySensor
{
protected:
TelemetrySensor() {}
TelemetrySensor(TelemetrySensorType sensorType, const char *sensorName)
{
this->sensorName = sensorName;
this->sensorType = sensorType;
this->status = 0;
}
const char *sensorName;
TelemetrySensorType sensorType;
unsigned status;
int32_t initI2CSensor() {
if (!status) {
DEBUG_MSG("Could not connect to detected %s sensor.\n Removing from nodeTelemetrySensorsMap.\n", sensorName);
nodeTelemetrySensorsMap[sensorType] = 0;
} else {
DEBUG_MSG("Opened %s sensor on default i2c bus\n", sensorName);
setup();
}
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
virtual void setup();
public:
bool hasSensor() {
return sensorType < sizeof(nodeTelemetrySensorsMap) && nodeTelemetrySensorsMap[sensorType] > 0;
}
virtual int32_t runOnce() = 0;
virtual bool getMeasurement(Telemetry *measurement) = 0;
virtual bool getMetrics(Telemetry *measurement) = 0;
};

View File

@@ -392,7 +392,6 @@ StoreForwardModule::StoreForwardModule()
*/
moduleConfig.store_forward.enabled = 1;
config.power.is_always_powered = 1;
}
if (moduleConfig.store_forward.enabled) {

View File

@@ -225,6 +225,11 @@ void NRF52Bluetooth::setup()
Bluefruit.autoConnLed(false);
Bluefruit.begin();
// Clear existing data.
Bluefruit.Advertising.stop();
Bluefruit.Advertising.clearData();
Bluefruit.ScanResponse.clearData();
// Set the advertised device name (keep it short!)
Bluefruit.setName(getDeviceName());
@@ -276,4 +281,4 @@ void NRF52Bluetooth::clearBonds()
Bluefruit.Periph.clearBonds();
Bluefruit.Central.clearBonds();
}
}

View File

@@ -16,48 +16,31 @@ class NRF52CryptoEngine : public CryptoEngine
*/
virtual void encrypt(uint32_t fromNode, uint64_t packetId, size_t numBytes, uint8_t *bytes) override
{
// DEBUG_MSG("NRF52 encrypt!\n");
if (key.length > 16) {
DEBUG_MSG("Software encrypt fr=%x, num=%x, numBytes=%d!\n", fromNode, (uint32_t) packetId, numBytes);
AES_ctx ctx;
initNonce(fromNode, packetId);
AES_init_ctx_iv(&ctx, key.bytes, nonce);
AES_CTR_xcrypt_buffer(&ctx, bytes, numBytes);
} else if (key.length > 0) {
DEBUG_MSG("nRF52 encrypt fr=%x, num=%x, numBytes=%d!\n", fromNode, (uint32_t) packetId, numBytes);
nRFCrypto.begin();
nRFCrypto_AES ctx;
uint8_t myLen = ctx.blockLen(numBytes);
char encBuf[myLen] = {0};
memcpy(encBuf, bytes, numBytes);
initNonce(fromNode, packetId);
ctx.begin();
ctx.Process(encBuf, numBytes, nonce, key.bytes, key.length, (char*)bytes, ctx.encryptFlag, ctx.ctrMode);
ctx.Process((char*)bytes, numBytes, nonce, key.bytes, key.length, encBuf, ctx.encryptFlag, ctx.ctrMode);
ctx.end();
nRFCrypto.end();
memcpy(bytes, encBuf, numBytes);
}
}
virtual void decrypt(uint32_t fromNode, uint64_t packetId, size_t numBytes, uint8_t *bytes) override
{
// DEBUG_MSG("NRF52 decrypt!\n");
if (key.length > 16) {
AES_ctx ctx;
initNonce(fromNode, packetId);
AES_init_ctx_iv(&ctx, key.bytes, nonce);
AES_CTR_xcrypt_buffer(&ctx, bytes, numBytes);
} else if (key.length > 0) {
nRFCrypto.begin();
nRFCrypto_AES ctx;
uint8_t myLen = ctx.blockLen(numBytes);
char decBuf[myLen] = {0};
memcpy(decBuf, bytes, numBytes);
initNonce(fromNode, packetId);
ctx.begin();
ctx.Process(decBuf, numBytes, nonce, key.bytes, key.length, (char*)bytes, ctx.decryptFlag, ctx.ctrMode);
ctx.end();
nRFCrypto.end();
}
// For CTR, the implementation is the same
encrypt(fromNode, packetId, numBytes, bytes);
}
private:

View File

@@ -30,7 +30,7 @@ void powerCommandsCheck()
DEBUG_MSG("Shutting down from admin command\n");
#ifdef TBEAM_V10
if (axp192_found == true) {
// setLed(false); //TODO: FIXME: this is not working
playShutdownMelody();
power->shutdown();
}
#elif NRF52_SERIES

View File

@@ -0,0 +1,55 @@
#ifndef Pins_Arduino_h
#define Pins_Arduino_h
#include <stdint.h>
#define EXTERNAL_NUM_INTERRUPTS 16
#define NUM_DIGITAL_PINS 20
#define NUM_ANALOG_INPUTS 16
#define analogInputToDigitalPin(p) (((p)<20)?(analogChannelToDigitalPin(p)):-1)
#define digitalPinToInterrupt(p) (((p)<40)?(p):-1)
#define digitalPinHasPWM(p) (p < 34)
static const uint8_t TX = 1;
static const uint8_t RX = 3;
static const uint8_t TXD2 = 17;
static const uint8_t RXD2 = 16;
static const uint8_t SDA = 21;
static const uint8_t SCL = 22;
static const uint8_t SS = 5;
static const uint8_t MOSI = 23;
static const uint8_t MISO = 19;
static const uint8_t SCK = 18;
static const uint8_t G23 = 23;
static const uint8_t G19 = 19;
static const uint8_t G18 = 18;
static const uint8_t G3 = 3;
static const uint8_t G16 = 16;
static const uint8_t G21 = 21;
static const uint8_t G2 = 2;
static const uint8_t G12 = 12;
static const uint8_t G15 = 15;
static const uint8_t G35 = 35;
static const uint8_t G36 = 36;
static const uint8_t G25 = 25;
static const uint8_t G26 = 26;
static const uint8_t G1 = 1;
static const uint8_t G17 = 17;
static const uint8_t G22 = 22;
static const uint8_t G5 = 5;
static const uint8_t G13 = 13;
static const uint8_t G0 = 0;
static const uint8_t G34 = 34;
static const uint8_t DAC1 = 25;
static const uint8_t DAC2 = 26;
static const uint8_t ADC1 = 35;
static const uint8_t ADC2 = 36;
#endif /* Pins_Arduino_h */

View File

@@ -0,0 +1,57 @@
#ifndef Pins_Arduino_h
#define Pins_Arduino_h
#include <stdint.h>
#define EXTERNAL_NUM_INTERRUPTS 16
#define NUM_DIGITAL_PINS 40
#define NUM_ANALOG_INPUTS 16
#define analogInputToDigitalPin(p) (((p)<20)?(esp32_adc2gpio[(p)]):-1)
#define digitalPinToInterrupt(p) (((p)<40)?(p):-1)
#define digitalPinHasPWM(p) (p < 34)
#define TX2 -1
#define RX2 -1
static const uint8_t TX = 1;
static const uint8_t RX = 3;
static const uint8_t SDA = 32;
static const uint8_t SCL = 33;
static const uint8_t SS = 9;
static const uint8_t MOSI = 23;
static const uint8_t MISO = 34;
static const uint8_t SCK = 18;
static const uint8_t G26 = 26;
static const uint8_t G36 = 36;
static const uint8_t G25 = 25;
static const uint8_t G32 = 32;
static const uint8_t G33 = 33;
static const uint8_t G21 = 21;
static const uint8_t G22 = 22;
static const uint8_t G13 = 13;
static const uint8_t G14 = 14;
static const uint8_t G12 = 12;
static const uint8_t G19 = 19;
static const uint8_t G5 = 5;
static const uint8_t G10 = 10;
static const uint8_t G2 = 2;
static const uint8_t G37 = 37;
static const uint8_t G38 = 38;
static const uint8_t G39 = 39;
static const uint8_t DAC1 = 25;
static const uint8_t DAC2 = 26;
static const uint8_t ADC1 = 35;
static const uint8_t ADC2 = 36;
#endif /* Pins_Arduino_h */

View File

@@ -0,0 +1,18 @@
[env:m5stack-coreink]
extends = esp32_base
board = m5stack-coreink
build_flags =
${esp32_base.build_flags} -D M5_COREINK -I variants/m5stack_coreink
;-D RADIOLIB_VERBOSE
-Ofast
-D__MCUXPRESSO
-DEPD_HEIGHT=200
-DEPD_WIDTH=200
-DM5STACK
lib_deps =
${esp32_base.lib_deps}
zinggjm/GxEPD2@^1.4.5
lewisxhe/PCF8563_Library@^0.0.1
board_build.f_cpu = 240000000L
upload_protocol = esptool
upload_port = /dev/ttyACM*

View File

@@ -0,0 +1,49 @@
#define I2C_SDA 21 //-1
#define I2C_SCL 22 //-1
//#define LED_PIN 10
#include "pcf8563.h"
// PCF8563 RTC Module
#define PCF8563_RTC 0x51
#define BUTTON_NEED_PULLUP
#define BUTTON_PIN 5
//Wheel
// Down 37
// Push 38
// Up 39
// Top Physical Button 5
#undef RF95_SCK
#undef RF95_MISO
#undef RF95_MOSI
#undef RF95_NSS
#define USE_RF95
#define RF95_SCK 18 //13
#define RF95_MISO 34 //26
#define RF95_MOSI 23 //25
#define RF95_NSS 14
#define LORA_DIO0 25 //32 now moved from ext port
#define LORA_RESET 26 //33 now moved from ext port
#define LORA_DIO1 RADIOLIB_NC
#define LORA_DIO2 RADIOLIB_NC
#define NO_GPS
// This board has no GPS for now
#undef GPS_RX_PIN
#undef GPS_TX_PIN
#define HAS_EINK
//https://docs.m5stack.com/en/core/coreink
//https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/docs/schematic/Core/coreink/coreink_sch.pdf
#define PIN_EINK_EN -1
#define PIN_EINK_CS 9 // EPD_CS
#define PIN_EINK_BUSY 4 // EPD_BUSY
#define PIN_EINK_DC 15 // EPD_D/C
#define PIN_EINK_RES -1 // Connected to GPIO0 but no needed !!!! maybe causing issue ?
#define PIN_EINK_SCLK 18 // EPD_SCLK
#define PIN_EINK_MOSI 23 // EPD_MOSI

View File

@@ -1,4 +1,4 @@
[VERSION]
major = 1
minor = 3
build = 13
build = 21