Compare commits

...

324 Commits

Author SHA1 Message Date
Ben Meadors
c725a6b65f Bump for next tech preview release 2022-06-29 20:17:51 -05:00
Ben Meadors
9c6da233b9 Phoneapi moduleconfig (#1538) 2022-06-29 19:41:43 -05:00
github-actions[bot]
0f2aa7660d [create-pull-request] automated change (#1537)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2022-06-29 19:09:38 -05:00
Thomas Göttgens
9f78dff25f Merge pull request #1532 from meshtastic/patch-1
avoid BLE device names like a123_a123
2022-06-22 15:44:25 +02:00
Thomas Göttgens
e7dfd14917 Change recursive delete to be recursive 2022-06-22 15:33:53 +02:00
Thomas Göttgens
bc47dd574b avoid BLE device names like a123_a123 2022-06-22 14:26:33 +02:00
Thomas Göttgens
41d5ccc29f Merge pull request #1531 from meshtastic/patch-1
Small fixes and inprovements
2022-06-22 12:36:46 +02:00
Thomas Göttgens
aead7a23f9 - Put Modemconfig in logical order and fix typo
- non-zero config.lora.bandwidth means a custom radio config, not 'Unknown'
- Enable 'this is a new device, set region' screen again now we can actually set region.
2022-06-22 09:52:08 +02:00
Thomas Göttgens
c9fd591942 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-22 09:44:59 +02:00
Jm Casler
c81fbd867d Merge pull request #1530 from mc-hamster/master
Add debug to monitor radio reconfiguration for #1014
2022-06-21 22:18:13 -07:00
Jm Casler
cfb76290cb Merge branch 'master' into master 2022-06-21 21:52:55 -07:00
Jm Casler
46e13d23d9 Add debug to monitor radio reconfiguration for #1014 - 2022-06-21 21:51:45 -07:00
Jm Casler
45b2c169aa Merge pull request #1529 from mc-hamster/master
Fix typo in the modem presets
2022-06-21 19:34:37 -07:00
Jm Casler
90baf9d8a0 Fix typo in the modem presets 2022-06-21 19:23:07 -07:00
Jm Casler
a390fc7ea8 Merge pull request #1528 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-06-21 19:07:36 -07:00
mc-hamster
e0f912ab2a [create-pull-request] automated change 2022-06-22 02:06:51 +00:00
Thomas Göttgens
646d6f5615 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-21 10:09:22 +02:00
Jm Casler
cf00ac593f Update to 1.3.21 2022-06-20 16:44:33 -07:00
Thomas Göttgens
ff9f973a1d Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-20 20:33:43 +02:00
Ben Meadors
7a50ab4de2 Re-init config_state after we switch to nodeinfo (#1526) 2022-06-20 13:28:50 -05:00
Thomas Göttgens
c80f260fba Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-20 20:26:13 +02: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
Thomas Göttgens
089c91a7ac Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-18 09:48:22 +02:00
Ben Meadors
9a5ff935f9 Bump to 1.3.20 2022-06-17 16:40:33 -05:00
Thomas Göttgens
515a411e8c Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-17 22:37:55 +02: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
cf380e6cb6 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-17 09:01:14 +02: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
Thomas Göttgens
74e926ef00 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-16 20:44:43 +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
Thomas Göttgens
af335e9c06 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-06-16 09:46:17 +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
Ben Meadors
71a43a97cc Bump to 13 2022-06-01 06:06:40 -05: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
Thomas Göttgens
32245a1a8d Merge pull request #1477 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-05-30 21:40:52 +02:00
Thomas Göttgens
f6982ca726 fix building with new peotobuf structure. 2022-05-30 21:12:27 +02:00
caveman99
03bbc5eff4 [create-pull-request] automated change 2022-05-30 19:00:01 +00:00
Ben Meadors
0767c0b0e8 Converted to jgromes/RadioLib upstream and pegged to latest ref (#1472)
* Converted to jgromes/RadioLib upstream and pegged to latest ref
2022-05-29 19:30:20 -05:00
Thomas Göttgens
0d574e35c6 Merge pull request #1473 from meshtastic/LocalConfig
fixed typo in AdminModule
2022-05-29 16:40:14 +02:00
Thomas Göttgens
b88e75cf2a Fixed Typo in get Config 2022-05-29 16:31:30 +02:00
Jm Casler
6306c53bfe Bump to .12 2022-05-27 12:21:59 -07:00
Jm Casler
8db57601bf Merge pull request #1471 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-05-27 12:20:31 -07:00
mc-hamster
1b8830e7df [create-pull-request] automated change 2022-05-27 19:19:57 +00:00
Jm Casler
0411401184 Bump to .11 2022-05-25 20:47:48 -07:00
Ben Meadors
2ee003f2a1 Merge branch 'master' into sketch 2022-05-25 06:33:42 -05:00
Jm Casler
5678221ead Merge pull request #1429 from mc-hamster/compression
Compression
2022-05-24 18:19:11 -07:00
Jm Casler
c5f3cad0f9 Fixed missing brackets 2022-05-24 18:06:53 -07:00
Jm Casler
f3c15eb6cc Completed compression. Tested between two devices. 2022-05-24 17:42:46 -07:00
Jm Casler
e218bba87e Merge branch 'meshtastic:master' into compression 2022-05-24 16:48:28 -07:00
Jm Casler
c04d62158b Merge pull request #1469 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-05-24 08:38:31 -07:00
Thomas Göttgens
03affc9e73 Merge branch 'master' into create-pull-request/patch 2022-05-24 10:54:38 +02:00
Thomas Göttgens
25bf97316d Merge pull request #1468 from meshtastic/LocalConfig
make sure all segments are enabled and saved
2022-05-24 10:26:26 +02:00
Jm Casler
1ef70a2489 Merge branch 'master' into sketch 2022-05-24 00:23:17 -07:00
Jm Casler
76ef240a3d Merge branch 'master' into LocalConfig 2022-05-24 00:21:46 -07:00
Jm Casler
3f171b29f7 Merge pull request #1466 from LucyHosking/master
Implemented hidden SSID
2022-05-24 00:21:32 -07:00
Jm Casler
dca6c27c9d Update from config.payloadVariant to config.wifi 2022-05-23 22:08:33 -07:00
Jm Casler
2631a9324e Update from radioConfig.preferences to config.lora 2022-05-23 22:06:38 -07:00
Jm Casler
c64f4bbb11 Merge pull request #97 from meshtastic/new-compression
Update compression branch
2022-05-23 21:19:11 -07:00
Jm Casler
94f7e7037d Merge branch 'compression' into new-compression 2022-05-23 21:18:45 -07:00
mc-hamster
a0b4b4efa1 [create-pull-request] automated change 2022-05-24 04:10:51 +00:00
Ben Meadors
d68d85590b Merge branch 'master' into master 2022-05-22 07:50:32 -05:00
Thomas Göttgens
800a4200ef make sure all segments are enabled and saved 2022-05-22 13:54:24 +02:00
Thomas Göttgens
9c50a76ea2 Merge pull request #1464 from meshtastic/LocalConfig
Segemented config works for me (TM)
2022-05-22 13:41:47 +02:00
Thomas Göttgens
4a41694ec5 Merge branch 'LocalConfig' of github.com:meshtastic/Meshtastic-device 2022-05-22 13:28:32 +02:00
Thomas Göttgens
6bb3861e95 Moduleconfig also changed to localConfig Model. 2022-05-22 13:27:56 +02:00
Thomas Göttgens
e8262540d4 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-05-22 13:06:08 +02:00
Thomas Göttgens
2b6f632a50 Merge branch 'master' into master 2022-05-22 13:03:13 +02:00
Thomas Göttgens
bddab68110 Merge pull request #1467 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-05-22 13:01:45 +02:00
caveman99
c4f69cbcc0 [create-pull-request] automated change 2022-05-22 10:59:47 +00:00
Thomas Göttgens
85f5c7a40b Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-05-22 12:17:09 +02:00
LucyHosking
e0c5e4d441 Implemented hidden SSID
https://github.com/meshtastic/Meshtastic-device/issues/1308
2022-05-21 20:10:36 -07:00
Sacha Weatherstone
8dfdc11af9 Merge branch 'master' into LocalConfig 2022-05-22 12:57:26 +10:00
Jm Casler
ba1937de39 Merge pull request #1465 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-05-21 19:14:23 -07:00
mc-hamster
2e45d4f0fd [create-pull-request] automated change 2022-05-22 00:44:37 +00:00
Jm Casler
b1f309545e Delete proto 2022-05-21 17:39:50 -07:00
Jm Casler
22764425f7 updating proto submodule to latest 2022-05-21 17:10:24 -07:00
Thomas Göttgens
5e8d49d24b missed one 2022-05-21 22:51:34 +02:00
Thomas Göttgens
53e9f4df46 Segemented config works for me (TM)
Small GPS Fix that cropped up while testing included.
2022-05-21 22:38:33 +02:00
Garth Vander Houwen
33938f73a6 Merge pull request #1463 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-05-21 13:01:09 -07:00
caveman99
e4484270b1 [create-pull-request] automated change 2022-05-21 19:46:36 +00:00
Garth Vander Houwen
964510ef52 Merge pull request #1462 from meshtastic/garthvh-patch-1
Update GitHub action Submodule
2022-05-21 12:45:50 -07:00
Garth Vander Houwen
b108540b08 Update GitHub action 2022-05-21 12:24:50 -07:00
Thomas Göttgens
db35b92b6f Merge pull request #1461 from meshtastic/UBXFIX
remove duplicate GPS setting
2022-05-21 21:05:14 +02:00
Thomas Göttgens
5d22efd8a8 remove duplicate GPS setting 2022-05-21 20:52:43 +02:00
Thomas Göttgens
49ccb77e43 Merge pull request #1457 from meshtastic/UBXFIX
Streamline GPS Init
2022-05-18 18:13:40 +01:00
Thomas Göttgens
3d0d45a695 More UBX stuff from 1.2 2022-05-18 18:29:26 +02:00
Thomas Göttgens
2e39900f78 Merge branch 'UBXFIX' of github.com:meshtastic/Meshtastic-device 2022-05-18 18:18:32 +02:00
Thomas Göttgens
5e82423331 More UBX fixes 2022-05-18 18:16:23 +02:00
Thomas Göttgens
dd8111e737 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-05-18 18:13:51 +02:00
Thomas Göttgens
9b02841506 Merge branch 'master' into UBXFIX 2022-05-18 15:19:27 +01:00
Thomas Göttgens
3c5a096873 Streamline GPS Init 2022-05-18 16:16:59 +02:00
Thomas Göttgens
93521f7b39 Merge pull request #1454 from meshtastic/t-echo
fix GPS and Buttons on T-Echo and log UBX (1.3)
2022-05-17 20:10:42 +01:00
Thomas Göttgens
bdcdc1485c Merge branch 't-echo' of github.com:meshtastic/Meshtastic-device 2022-05-17 20:55:29 +02:00
Thomas Göttgens
fdc10acfdd Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-05-17 20:54:17 +02:00
Thomas Göttgens
ac93e3196e Don't try to be too smart 2022-05-17 20:53:57 +02:00
Thomas Göttgens
e5439c21ab Merge branch 'master' into t-echo 2022-05-17 18:55:35 +01:00
Thomas Göttgens
7f9bb5748e log UBX Init 2022-05-17 19:54:29 +02:00
Thomas Göttgens
894b091553 Fix ubox gps too or at least log errors 2022-05-17 19:48:48 +02:00
Thomas Göttgens
7576270423 switch GPS back to 9600 baud, seems to work better now we only use the 2 sentences 2022-05-17 19:09:12 +02:00
Thomas Göttgens
6b8f83cd71 don't wake t-echo through the touch button 2022-05-17 13:01:15 +02:00
Thomas Göttgens
fdc3a6e432 Merge pull request #1453 from meshtastic/PIO6-fix
Make PIO6 happy again
2022-05-17 10:42:46 +01:00
Thomas Göttgens
49d8c581bd missed one here as well... 2022-05-17 11:26:03 +02:00
Thomas Göttgens
c15da3c104 Make PIO6 happy again 2022-05-17 11:14:21 +02:00
Sacha Weatherstone
12c46ced45 update protobufs 2022-05-13 10:41:05 +10:00
Sacha Weatherstone
3ed9a05ac6 Update max channels in protos & remove batt_lvl from position flags 2022-05-13 10:30:01 +10:00
Sacha Weatherstone
3b4c8ad0e2 fix max message sizes for unused protobufs 2022-05-12 23:12:37 +10:00
Sacha Weatherstone
d9e2e09149 Fix NTP server initialization 2022-05-12 23:05:06 +10:00
Sacha Weatherstone
97713b2daa Increased NTP update frequency to 12 hours 2022-05-12 22:45:27 +10:00
Sacha Weatherstone
7799e1b7e6 Increased NTP update frequency to 1024 seconds 2022-05-12 22:06:36 +10:00
Sacha Weatherstone
38913bb661 Consistency fixes & repo cleanup 2022-05-12 20:45:30 +10:00
Sacha Weatherstone
14cbc439ab Update README.md 2022-05-12 20:04:10 +10:00
Sacha Weatherstone
6d15b9b82a Update main_matrix.yml 2022-05-12 20:03:53 +10:00
Sacha Weatherstone
2035ddf5a9 Add ntp server config option, remove old region logic 2022-05-11 18:30:29 +10:00
Thomas Göttgens
e91dedaab5 Merge pull request #1447 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-05-10 11:03:24 +01:00
Thomas Göttgens
54bf02352f Merge branch 'master' into create-pull-request/patch 2022-05-10 10:46:36 +01:00
Thomas Göttgens
3f415e3e8e Merge pull request #1448 from meshtastic/M5STACK
Make M5Stack Canon Hardware
2022-05-10 10:45:47 +01:00
Thomas Göttgens
7133e6e89b Use canon HW Identifier for M5 2022-05-10 11:10:32 +02:00
Thomas Göttgens
e1d49a3632 Buzzer Support for M5Stack 2022-05-10 11:07:49 +02:00
caveman99
f26fb9408e [create-pull-request] automated change 2022-05-10 08:20:52 +00:00
Thomas Göttgens
1e48989e2d Merge pull request #1446 from meshtastic/RAK14006
Support detecting RAK14006 KB
2022-05-09 20:29:29 +01:00
Thomas Göttgens
e48285a33a Support detecting RAK14006 KB 2022-05-09 20:12:49 +02:00
Thomas Göttgens
7f0fd642ec Merge pull request #1445 from meshtastic/M5Stack
Support M5Stack
2022-05-09 19:05:46 +01:00
Thomas Göttgens
5ee8c56c94 Support M5Stack with LORA868 (RA01H) Module and TFT Display (PRIVATE_HW, Canon Hardware TBD) 2022-05-09 19:50:39 +02:00
Sacha Weatherstone
4940822ae8 Merge pull request #1444 from GUVWAF/master
Optimize retransmission timer
2022-05-09 09:33:16 +10:00
Sacha Weatherstone
8b42b78033 Merge branch 'master' into master 2022-05-08 00:23:18 +10:00
GUVWAF
a7f4263db4 Optimize retransmission timer
Based on airtime of packet + transmit, processing and CAD delays
2022-05-07 15:43:35 +02:00
GUVWAF
348e78718d Call cancelSending in stopRetransmission
This also removes pending packet from txQueue if it was already in there
2022-05-07 15:39:14 +02:00
Sacha Weatherstone
0ec6771cf7 Fix build when BATTERY_PIN is set 2022-05-07 20:47:52 +10:00
Sacha Weatherstone
5e7b372345 Satisfy cppcheck 2022-05-07 20:36:15 +10:00
Sacha Weatherstone
6b0ce6b729 Finish config transition 2022-05-07 20:31:21 +10:00
Sacha Weatherstone
c07976438b fix old submodule 2022-05-07 13:37:58 +10:00
Sacha Weatherstone
eb6dd6b53d Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-05-07 13:34:36 +10:00
Sacha Weatherstone
ea86f76393 Move LoRa config out of primary channel 2022-05-07 13:34:06 +10:00
Thomas Göttgens
b699e5e6cd Merge pull request #1441 from meshtastic/patch-1-1
Enable Malloc Support in nanopb
2022-05-06 21:26:38 +01:00
Thomas Göttgens
4fb0cfa909 Enable Malloc Support in nanopb 2022-05-06 22:16:51 +02:00
Thomas Göttgens
bb5b10eef3 Merge pull request #1440 from meshtastic/NO-SCREEN
Make #define NO_SCREEN work again
2022-05-06 14:50:54 +01:00
Thomas Göttgens
b5cc304336 Make #define NO_SCREEN work again 2022-05-06 15:41:37 +02:00
Thomas Göttgens
1812843363 Merge pull request #1439 from meshtastic/RAK18001
RAK18001 Buzzer Support
2022-05-06 13:31:37 +01:00
Thomas Göttgens
628740d6d1 Support Buzzer in Slot C 2022-05-06 14:20:46 +02:00
Thomas Göttgens
251365dca7 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-05-06 14:05:51 +02:00
Ben Meadors
223c706e91 Use meshtastic fork of arduino thread lib 2022-05-05 13:54:21 -05:00
Rockwell Schrock
5e109d9648 Fix typo in calculation of NUM_ONLINE_SECS constant (#1436)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2022-05-05 13:46:39 -05:00
Ben Meadors
2b769279ae Moving platform-native into meshtastic fork (#1437) 2022-05-05 13:20:16 -05:00
Thomas Göttgens
8f8eff6f95 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-05-05 08:33:03 +02:00
Thomas Göttgens
02fe597f3f Merge pull request #1432 from meshtastic/patch-1
Forgot the readFromRTC for PCF8563 (T-Echo)
2022-05-04 16:25:47 +01:00
Thomas Göttgens
4d611ba2f0 Forgot the readFromRTC for PCF8563 (T-Echo) 2022-05-04 17:06:06 +02:00
Thomas Göttgens
403a0b2ddc Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-05-04 09:17:06 +02:00
Sacha Weatherstone
211273cc08 Fix expected values in config setters 2022-05-04 12:52:44 +10:00
Sacha Weatherstone
8ba0a9bf87 Fix config switch 2022-05-03 22:16:50 +10:00
Sacha Weatherstone
f84286d138 Split config structure in two 2022-05-02 22:00:24 +10:00
Jm Casler
b980f3e311 Merge branch 'meshtastic:master' into compression 2022-05-01 21:02:07 -07:00
Sacha Weatherstone
399e053ebd workaround for undefined payload type on phoneapi 2022-05-02 13:04:05 +10:00
Jm Casler
d6b20ea623 Merge branch 'meshtastic:master' into compression 2022-05-01 19:35:26 -07:00
Ben Meadors
caac2ecb83 Compute config size and account for reloadconfig (#1428)
* Compute config size and account for reloadconfig

* Reload config and config_size
2022-05-01 20:30:19 -05:00
Sacha Weatherstone
7ae8601ba5 fix warnings 2022-05-02 10:24:28 +10:00
Sacha Weatherstone
8f038ced15 add handleSetConfig, remove team 2022-05-02 08:53:44 +10:00
Sacha Weatherstone
3a1f20821e Remove team and provision set_config 2022-05-02 08:35:31 +10:00
Sacha Weatherstone
057131b459 Merge pull request #1427 from meshtastic/radioconfig-refactor-telemetry
Radioconfig refactor telemetry
2022-05-02 08:16:06 +10:00
Ben Meadors
1040b0988a Removed unused members causing warnings 2022-05-01 15:37:34 -05:00
Ben Meadors
2ca0290662 Admin message implementation 2022-05-01 15:35:01 -05:00
Ben Meadors
163774bb1f Moved refactored prefs 2022-05-01 14:26:05 -05:00
Ben Meadors
6a8724213e Adafruit bus io is now required for sensor libs 2022-05-01 14:22:04 -05:00
Ben Meadors
cf64da21fb Move adc multiplier code into battery pin region to surpress warning 2022-05-01 14:21:30 -05:00
Sacha Weatherstone
c0d40895f8 Config rework - Init GetConfigResponse 2022-05-01 16:12:48 +10:00
Sacha Weatherstone
50326fbb6b Config rework - Init getConfig 2022-05-01 12:41:26 +10:00
Sacha Weatherstone
98cd19ea0f Config rework - Init getConfig 2022-05-01 12:39:48 +10: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
Mark Trevor Birss
8e996e3e63 Enable TXEN and RXEN for Waveshare LoRa Module (#1422)
This change enables RXEN TXEN for the use of the Waveshare Core1262-868M Anti-Interference SX1262 LoRa Module, EU868 Band
https://www.waveshare.com/core1262-868m.htm
2022-04-29 14:23:17 -05:00
Ben Meadors
53cc090814 Move sx1262 fixes upstream (#1421) 2022-04-29 07:46:44 -05:00
Thomas Göttgens
bfc2d30a46 Merge pull request #1419 from meshtastic/PCF8563
RTC Module support for T-Echo and others with PCF8563
2022-04-28 08:29:07 +02:00
Thomas Göttgens
516dff5b09 RTC Module support for T-Echo and others with PCF8563 2022-04-28 08:18:03 +02:00
mkinney
4df0e910b8 Update main_matrix.yml
add nano-g1
2022-04-27 10:23:20 -07:00
mkinney
3a5f492106 add nano_g1 to build (#1417) 2022-04-27 12:20:10 -05:00
Thomas Göttgens
2dbb9075a3 Merge pull request #1408 from Pedestrian11/patch-1
TTGO_T_ECHO to use batteries, PIN_EINK_PWR_ON must be set to high
2022-04-27 15:45:01 +02:00
Thomas Göttgens
e5715a0048 Merge branch 'master' into patch-1 2022-04-27 15:32:05 +02:00
Thomas Göttgens
629db8c718 Fix build errors and add a bit of failsafe 2022-04-27 15:30:27 +02:00
Ben Meadors
cc2a84afcd Bump version for release 2022-04-27 07:03:09 -05:00
Thomas Göttgens
6c1dc0d71a Merge pull request #1415 from meshtastic/RAK12002
I2C RTC Support (RAK12002)
2022-04-27 11:17:31 +02:00
Thomas Göttgens
9e97fac252 - implement generic support for on-device battery powered RTC Modules.
- implement support for I2C RV-3028 based RTC modules like the RAK12002
- pretty print some debug timestamps
2022-04-27 11:05:08 +02:00
Thomas Göttgens
3a9086dfc5 We may have RAK modules in Slot D pulling IO5 to Low permanently (like the RAK12002 RTC Module). React to assumed Long presses of the device button only 30 seconds after bootup to prevent a reboot loop. This is Particularly important for button-less RAK19003 Baseboard. 2022-04-27 11:02:45 +02:00
Thomas Göttgens
a0f34a8d0a Make Debug Log less spammy 2022-04-27 11:00:26 +02:00
Ben Meadors
359b41d869 Position fwd phone (#1413)
* Correct factory reset code for NRF (from 1.2)

* Changes from 1.2

* Update proto ref

* Whoops

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2022-04-26 19:40:24 -05:00
Thomas Göttgens
04723bd1a0 Merge pull request #1412 from meshtastic/nrf-softcrypt
use a tiny software AES lib if user wants AES-256
2022-04-26 21:45:54 +02:00
Thomas Göttgens
89d6990a92 Merge branch 'nrf-softcrypt' of github.com:meshtastic/Meshtastic-device into nrf-softcrypt 2022-04-26 21:30:21 +02:00
Thomas Göttgens
96f20287ff fix scope error 2022-04-26 21:30:14 +02:00
Thomas Göttgens
d8ba25747b Merge branch 'master' into nrf-softcrypt 2022-04-26 21:25:01 +02:00
Thomas Göttgens
e66c01f0e6 Merge branch 'nrf-softcrypt' of github.com:meshtastic/Meshtastic-device into nrf-softcrypt 2022-04-26 21:24:29 +02:00
Thomas Göttgens
aaea2e7456 make cppcheck happy 2022-04-26 21:24:21 +02:00
Thomas Göttgens
4de5944474 Merge branch 'master' into nrf-softcrypt 2022-04-26 17:52:33 +02:00
Thomas Göttgens
76e48178c8 use a tiny software AES lib if user needs AES-256 2022-04-26 17:50:50 +02:00
Pedestrian
13fa7c1628 TTGO_T_ECHO to use batteries, PIN_EINK_PWR_ON must be set to high 2022-04-26 17:43:32 +08:00
Thomas Göttgens
b957001629 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-04-25 21:38:28 +02:00
Jm Casler
9b6b224af4 Merge branch 'meshtastic:master' into compression 2022-04-25 08:04:51 -07:00
Jm Casler
4785367915 Temp work on compression 2022-04-25 08:02:51 -07:00
Thomas Göttgens
7c12234a9c Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-04-23 10:12:32 +02:00
Thomas Göttgens
c6a2e26876 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-04-20 09:51:35 +02:00
Thomas Göttgens
06aae85e45 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-04-06 13:06:15 +02:00
Thomas Göttgens
a2df441e1f Merge branch 'master' of github.com:meshtastic/Meshtastic-device
# Conflicts:
#	variants/heltec_v1/variant.h
2022-04-05 11:03:51 +02:00
Thomas Göttgens
d246c31548 GPS Pin Changes on V 2.0 and V1 too. 2022-04-02 12:16:42 +02:00
Thomas Göttgens
19589bf12d Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-04-02 12:05:30 +02:00
Thomas Göttgens
ba984aebfa Varaible GPS Thread Timing, keep default of 100 msec 2022-04-02 12:05:07 +02:00
173 changed files with 4676 additions and 3093 deletions

View File

@@ -1,11 +0,0 @@
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.162.0/containers/ubuntu/.devcontainer/base.Dockerfile
# [Choice] Ubuntu version: bionic, focal
ARG VARIANT="focal"
FROM mcr.microsoft.com/vscode/devcontainers/base:0-${VARIANT}
# [Optional] Uncomment this section to install additional OS packages.
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& apt-get -y install python3-distutils python3-pip
RUN pip3 install platformio meshtastic adafruit-nrfutil
RUN wget https://github.com/protocolbuffers/protobuf/releases/download/v3.15.8/protoc-3.15.8-linux-x86_64.zip -O /tmp/protoc.zip && cd /tmp && unzip protoc.zip && chmod a+x bin/protoc && cp bin/protoc /usr/local/bin

View File

@@ -1,32 +0,0 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.162.0/containers/ubuntu
{
"name": "Ubuntu",
"build": {
"dockerfile": "Dockerfile",
// Update 'VARIANT' to pick an Ubuntu version: focal, bionic
"args": { "VARIANT": "focal" }
},
// Set *default* container specific settings.json values on container create.
"settings": {
"terminal.integrated.shell.linux": "/bin/bash"
},
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"platformio.platformio-ide",
"xaver.clang-format"
],
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "uname -a",
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
"remoteUser": "vscode",
"postCreateCommand": "git submodule update --init"
}

View File

@@ -1,146 +0,0 @@
name: Continuous Integration (Legacy serial build)
on:
# Triggers the workflow on push or pull request events but only for the master branch
workflow_dispatch:
jobs:
ci-check:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
submodules: "recursive"
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Install cppcheck
run: |
sudo apt-get install -y cppcheck
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: 3.x
- name: Cache python libs
uses: actions/cache@v1
id: cache-pip # needed in if test
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip
- name: Upgrade python tools and install platformio
run: |
python -m pip install --upgrade pip
pip install -U platformio
- name: Upgrade platformio
run: |
pio upgrade
- name: Check everything
run: bin/check-all.sh
ci-build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
submodules: "recursive"
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: 3.x
- name: Cache python libs
uses: actions/cache@v1
id: cache-pip # needed in if test
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip
- name: Upgrade python tools
# We actually want to run this every time
# if: steps.cache-pip.outputs.cache-hit != 'true'
run: |
python -m pip install --upgrade pip
pip install -U platformio meshtastic adafruit-nrfutil
# - name: Cache platformio
# uses: actions/cache@v1
# id: cache-platformio # needed in if test
# with:
# path: ~/.platformio
# key: ${{ runner.os }}-platformio
- name: Upgrade platformio
run: |
pio upgrade
- name: Pull web ui
uses: dsaltares/fetch-gh-release-asset@master
with:
repo: "meshtastic/meshtastic-web"
file: "build.tar"
target: "build.tar"
token: ${{ secrets.GITHUB_TOKEN }}
- name: Unpack web ui
run: |
tar -xf build.tar -C data/static
rm build.tar
# We now run integration test before other build steps (to quickly see runtime failures)
- name: Build for native
run: platformio run -e native
- name: Integration test
run: |
.pio/build/native/program &
sleep 20 # 5 seconds was not enough
echo "Simulator started, launching python test..."
python3 -c 'from meshtastic.test import testSimulator; testSimulator()'
- name: Cat bin/build-all.sh
run: |
cat bin/build-all.sh
- name: Build everything
run: bin/build-all.sh
- name: Get release version string
run: echo "::set-output name=version::$(./bin/buildinfo.py long)"
id: version
- name: Store binaries as an artifact
uses: actions/upload-artifact@v2
with:
name: firmware-${{ steps.version.outputs.version }}.zip
path: release/archive/firmware-${{ steps.version.outputs.version }}.zip
retention-days: 90
- name: Store debugging elf files as an artifact
uses: actions/upload-artifact@v2
with:
name: debug-elfs
path: release/archive/elfs-*.zip
retention-days: 7
- name: Download firmware.zip
uses: actions/download-artifact@master
with:
name: firmware-${{ steps.version.outputs.version }}.zip
path: ./
- name: Pull request artifacts
if: ${{ github.event_name == 'pull_request_target' || github.event_name == 'pull_request' }}
uses: gavv/pull-request-artifacts@v1.0.0
with:
commit: ${{ (github.event.pull_request_target || github.event.pull_request).head.sha }}
repo-token: ${{ secrets.GITHUB_TOKEN }}
artifacts-branch: artifacts
artifacts: ./firmware-${{ steps.version.outputs.version }}.zip

View File

@@ -1,4 +1,4 @@
name: Continuous Integration
name: CI
on:
# # Triggers the workflow on push but only for the master branch
push:
@@ -37,7 +37,10 @@ jobs:
- board: rak4631
- board: rak4631_eink
- board: t-echo
- board: nano-g1
- board: m5stack-core
- board: m5stack-coreink
runs-on: ubuntu-latest
steps:
- name: Checkout code
@@ -91,6 +94,9 @@ jobs:
- board: heltec-v2.1
- board: tbeam0.7
- board: meshtastic-diy-v1
- board: nano-g1
- board: m5stack-core
- board: m5stack-coreink
runs-on: ubuntu-latest
steps:

View File

@@ -13,13 +13,13 @@ jobs:
- name: Update submodule
run: |
git submodule update --remote proto
git submodule update --remote protobufs
- 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: |
@@ -29,5 +29,5 @@ jobs:
uses: peter-evans/create-pull-request@v3
with:
add-paths: |
proto
protobufs
src/mesh

7
.gitmodules vendored
View File

@@ -1,6 +1,3 @@
[submodule "proto"]
path = proto
[submodule "protobufs"]
path = protobufs
url = https://github.com/meshtastic/Meshtastic-protobufs.git
[submodule "design"]
path = design
url = https://github.com/meshtastic/meshtastic-design.git

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",
@@ -73,10 +74,5 @@
"cmake.configureOnOpen": true,
"protoc": {
"compile_on_save": false,
"compile_all_path": "/home/kevinh/development/meshtastic/meshtastic-esp32/proto",
"options": [
"--java_out=/tmp",
"-I=/home/kevinh/development/meshtastic/meshtastic-esp32/proto"
]
}
}

View File

@@ -1,16 +0,0 @@
FROM ubuntu
MAINTAINER Kevin Hester <kevinh@geeksville.com>
RUN apt-get update
RUN DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install wget python3 g++ zip python3-venv git vim
RUN wget https://raw.githubusercontent.com/platformio/platformio-core-installer/master/get-platformio.py -O get-platformio.py; chmod +x get-platformio.py
RUN python3 get-platformio.py
RUN git clone https://github.com/meshtastic/Meshtastic-device.git
RUN cd Meshtastic-device; git submodule update --init --recursive
# only build the simulator
RUN sed -i 's/^BOARDS_ESP32.*/BOARDS_ESP32=""/' Meshtastic-device/bin/build-all.sh
RUN sed -i 's/^BOARDS_NRF52.*/BOARDS_NRF52=""/' Meshtastic-device/bin/build-all.sh
RUN sed -i 's/echo "Building Filesystem.*/exit/' Meshtastic-device/bin/build-all.sh
RUN . ~/.platformio/penv/bin/activate; cd Meshtastic-device; ./bin/build-all.sh
CMD ["/Meshtastic-device/release/latest/bins/universal/meshtasticd_linux_amd64"]

View File

@@ -1,23 +1,18 @@
# Meshtastic-device
[![Open in Visual Studio Code](https://open.vscode.dev/badges/open-in-vscode.svg)](https://open.vscode.dev/meshtastic/Meshtastic-device)
[![Continuous Integration](https://github.com/meshtastic/Meshtastic-device/actions/workflows/main_matrix.yml/badge.svg)](https://github.com/meshtastic/Meshtastic-device/actions/workflows/main_matrix.yml)
![GitHub all releases](https://img.shields.io/github/downloads/meshtastic/meshtastic-device/total)
# Meshtastic Firmware
![GitHub release downloads](https://img.shields.io/github/downloads/meshtastic/meshtastic-device/total)
[![CI](https://img.shields.io/github/workflow/status/meshtastic/Meshtastic-device/CI?label=actions&logo=github&color=yellow)](https://github.com/meshtastic/repo/actions/workflows/main_matrix.yml)
[![CLA assistant](https://cla-assistant.io/readme/badge/meshtastic/Meshtastic-device)](https://cla-assistant.io/meshtastic/Meshtastic-device)
[![Fiscal Contributors](https://opencollective.com/meshtastic/tiers/badge.svg)](https://opencollective.com/meshtastic/)
[![Fiscal Contributors](https://opencollective.com/meshtastic/tiers/badge.svg?label=Fiscal%20Contributors&color=deeppink)](https://opencollective.com/meshtastic/)
[![Vercel](https://img.shields.io/static/v1?label=Powered%20by&message=Vercel&style=flat&logo=vercel&color=000000)](https://vercel.com?utm_source=meshtastic&utm_campaign=oss)
## This repository contains the device firmware used in the [Meshtastic](https://meshtastic.org) project.
## Overview
Update Instructions
This repository contains the device firmware for the Meshtastic project.
[Using Meshtastic Flasher](https://meshtastic.org/docs/getting-started/meshtastic-flasher)
Manual Method
[For ESP32 devices click here](https://meshtastic.org/docs/getting-started/flashing-esp32)
[For nRF52 devices click here](https://meshtastic.org/docs/getting-started/flashing-nrf52)
For developer information and specific building instructions, please see the [developer documentation](https://meshtastic.org/docs/developers)
**[Building Instructions](https://meshtastic.org/docs/developers/Firmware/build)**
**[Flashing Instructions](https://meshtastic.org/docs/getting-started/flashing-firmware/)**
## Stats

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"
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 proto && ..\nanopb-0.4.5\generator-bin\protoc.exe --nanopb_out=-v:..\src\mesh\generated -I=..\proto *.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 proto
../nanopb-0.4.5/generator-bin/protoc --nanopb_out=-v:../src/mesh/generated -I=../proto *.proto
cd protobufs
../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."

1
design

Submodule design deleted from 73ba05ceef

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
@@ -35,24 +36,20 @@ build_flags = -Wno-missing-field-initializers
-Isrc -Isrc/mesh -Isrc/gps -Isrc/buzz -Wl,-Map,.pio/build/output.map
-DUSE_THREAD_NAMES
-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
mathertel/OneButton@^2.0.3 ; OneButton library for non-blocking button debounce
1202 ; CRC32, explicitly needed because dependency is missing in the ble ota update lib
https://github.com/meshtastic/arduino-fsm.git
https://github.com/meshtastic/SparkFun_Ublox_Arduino_Library.git#31015a55e630a2df77d9d714669c621a5bf355ad
https://github.com/meshtastic/RadioLib.git#5582ac30578ff3f53f20630a00b2a8a4b8f92c74
https://github.com/meshtastic/TinyGPSPlus.git
https://github.com/meshtastic/AXP202X_Library.git#8404abb6d4b486748636bc6ad72d2a47baaf5460
Wire ; explicitly needed here because the AXP202 library forgets to add it
SPI
https://github.com/geeksville/ArduinoThread.git#72921ac222eed6f526ba1682023cee290d9aa1b3
PubSubClient
https://github.com/meshtastic/ArduinoThread.git#72921ac222eed6f526ba1682023cee290d9aa1b3
nanopb/Nanopb@^0.4.6
meshtastic/json11@^1.0.2
; Used for the code analysis in PIO Home / Inspect
check_tool = cppcheck
@@ -63,13 +60,24 @@ check_skip_packages = yes
framework = arduino
lib_deps =
${env.lib_deps}
; Portduino is using meshtastic fork for now
https://github.com/jgromes/RadioLib.git
build_flags = ${env.build_flags} -Os
# -DRADIOLIB_GODMODE
src_filter = ${env.src_filter} -<portduino/>
build_src_filter = ${env.build_src_filter} -<portduino/>
; Common libs for environmental measurements (not included in native / portduino)
[environmental]
; Common libs for communicating over TCP/IP networks such as MQTT
[networking_base]
lib_deps =
PubSubClient
meshtastic/json11@^1.0.2
; Common libs for environmental measurements in telemetry module
; (not included in native / portduino)
[environmental_base]
lib_deps =
adafruit/Adafruit BusIO@^1.11.4
adafruit/DHT sensor library@^1.4.1
adafruit/Adafruit Unified Sensor@^1.1.4
paulstoffregen/OneWire@^2.3.5
@@ -77,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
src_filter =
${arduino_base.src_filter} -<nrf52/>
upload_speed = 921600
build_src_filter =
${arduino_base.build_src_filter} -<nrf52/>
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
@@ -96,11 +106,14 @@ build_flags =
-DAXP_DEBUG_PORT=Serial -DUSE_NEW_ESP32_BLUETOOTH
lib_deps =
${arduino_base.lib_deps}
${environmental.lib_deps}
${networking_base.lib_deps}
${environmental_base.lib_deps}
https://github.com/meshtastic/esp32_https_server.git
h2zero/NimBLE-Arduino@1.3.7
arduino-libraries/NTPClient@^3.1.0
lorol/LittleFS_esp32@^1.0.6
https://github.com/meshtastic/AXP202X_Library.git#8404abb6d4b486748636bc6ad72d2a47baaf5460
lib_ignore =
segger_rtt
ESP32 BLE Arduino
@@ -130,8 +143,8 @@ build_type = debug ; I'm debugging with ICE a lot now
build_flags =
${arduino_base.build_flags} -Wno-unused-variable
-Isrc/nrf52
src_filter =
${arduino_base.src_filter} -<esp32/> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mqtt/>
build_src_filter =
${arduino_base.build_src_filter} -<esp32/> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mqtt/>
lib_ignore =
BluetoothOTA
@@ -140,7 +153,7 @@ extends = nrf52_base
build_flags = ${nrf52_base.build_flags}
lib_deps =
${arduino_base.lib_deps}
${environmental.lib_deps}
${environmental_base.lib_deps}
https://github.com/Kongduino/Adafruit_nRFCrypto.git
; Note: By default no lora device is created for this build - it uses a simulated interface

1
proto

Submodule proto deleted from a578453b3c

1
protobufs Submodule

Submodule protobufs added at c63a16c32f

View File

@@ -1,10 +1,10 @@
#include "configuration.h"
#include "concurrency/OSThread.h"
#include "PowerFSM.h"
#include "RadioLibInterface.h"
#include "buzz.h"
#include "concurrency/OSThread.h"
#include "configuration.h"
#include "graphics/Screen.h"
#include "power.h"
#include "buzz.h"
#include <OneButton.h>
#ifndef NO_ESP32
@@ -78,14 +78,9 @@ class ButtonThread : public concurrency::OSThread
#ifdef BUTTON_PIN_TOUCH
userButtonTouch = OneButton(BUTTON_PIN_TOUCH, true, true);
#ifdef INPUT_PULLUP_SENSE
// Some platforms (nrf52) have a SENSE variant which allows wake from sleep - override what OneButton did
pinMode(BUTTON_PIN_TOUCH, INPUT_PULLUP_SENSE);
#endif
userButtonTouch.attachClick(touchPressed);
wakeOnIrq(BUTTON_PIN_TOUCH, FALLING);
#endif
}
protected:
@@ -114,16 +109,17 @@ class ButtonThread : public concurrency::OSThread
private:
static void touchPressed()
{
{
screen->forceDisplay();
DEBUG_MSG("touch press!\n");
DEBUG_MSG("touch press!\n");
}
static void userButtonPressed()
{
// DEBUG_MSG("press!\n");
#ifdef BUTTON_PIN
if ((BUTTON_PIN != radioConfig.preferences.inputbroker_pin_press) || !radioConfig.preferences.canned_message_module_enabled) {
if ((BUTTON_PIN != moduleConfig.canned_message.inputbroker_pin_press) ||
!moduleConfig.canned_message.enabled) {
powerFSM.trigger(EVENT_PRESS);
}
#endif
@@ -135,7 +131,7 @@ class ButtonThread : public concurrency::OSThread
screen->adjustBrightness();
#endif
// If user button is held down for 5 seconds, shutdown the device.
if (millis() - longPressTime > 5 * 1000) {
if ((millis() - longPressTime > 5 * 1000) && (longPressTime > 0)) {
#ifdef TBEAM_V10
if (axp192_found == true) {
setLed(false);
@@ -144,7 +140,7 @@ class ButtonThread : public concurrency::OSThread
#elif NRF52_SERIES
// Do actual shutdown when button released, otherwise the button release
// may wake the board immediatedly.
if (!shutdown_on_long_stop) {
if ((!shutdown_on_long_stop) && (millis() > 30 * 1000)) {
screen->startShutdownScreen();
DEBUG_MSG("Shutdown from long press");
playBeep();
@@ -163,7 +159,7 @@ class ButtonThread : public concurrency::OSThread
#ifndef NO_ESP32
disablePin();
#elif defined(HAS_EINK)
digitalWrite(PIN_EINK_EN,digitalRead(PIN_EINK_EN) == LOW);
digitalWrite(PIN_EINK_EN, digitalRead(PIN_EINK_EN) == LOW);
#endif
}
@@ -177,23 +173,26 @@ class ButtonThread : public concurrency::OSThread
#endif
}
static void userButtonPressedLongStart()
{
DEBUG_MSG("Long press start!\n");
longPressTime = millis();
if (millis() > 30 * 1000) {
DEBUG_MSG("Long press start!\n");
longPressTime = millis();
}
}
static void userButtonPressedLongStop()
{
DEBUG_MSG("Long press stop!\n");
longPressTime = 0;
if (shutdown_on_long_stop) {
playShutdownMelody();
delay(3000);
power->shutdown();
if (millis() > 30 * 1000) {
DEBUG_MSG("Long press stop!\n");
longPressTime = 0;
if (shutdown_on_long_stop) {
playShutdownMelody();
delay(3000);
power->shutdown();
}
}
}
};
}
} // namespace concurrency

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

@@ -2,8 +2,8 @@
#include "FSCommon.h"
void listDir(const char * dirname, uint8_t levels)
#ifdef FSCom
{
#ifdef FSCom
File root = FSCom.open(dirname);
if(!root){
return;
@@ -28,6 +28,46 @@ void listDir(const char * dirname, uint8_t levels)
#endif
}
void rmDir(const char * dirname)
{
#ifdef FSCom
File file = FSCom.open(dirname);
if(!file){
return;
}
if(!file.isDirectory()){
file.close();
FSCom.remove(file.name());
// DEBUG_MSG("Remove FILE %s\n", file.name());
return;
}
file.rewindDirectory();
while (true) {
File entry = file.openNextFile();
if (!entry) {
break;
}
char dirpath[100]; // array to hold the result.
strcpy(dirpath, dirname); // copy string one into the result.
strcat(dirpath,"/"); // append string two to the result.
strcat(dirpath,entry.name()); // append string two to the result.
if(entry.isDirectory() && !String(entry.name()).endsWith(".")) {
entry.close();
// DEBUG_MSG("Descend DIR %s\n", dirpath);
rmDir(dirpath);
} else {
entry.close();
// DEBUG_MSG("Remove FILE %s\n", entry.name());
FSCom.remove(entry.name());
}
}
FSCom.rmdir(dirname);
// DEBUG_MSG("Remove DIR %s\n", dirname);
file.close();
#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

@@ -1,7 +1,7 @@
#pragma once
#include "NodeDB.h"
#include "Status.h"
#include "configuration.h"
#include "NodeDB.h"
#include <Arduino.h>
extern NodeDB nodeDB;
@@ -17,8 +17,8 @@ class GPSStatus : public Status
CallbackObserver<GPSStatus, const GPSStatus *> statusObserver =
CallbackObserver<GPSStatus, const GPSStatus *>(this, &GPSStatus::updateStatus);
bool hasLock = false; // default to false, until we complete our first read
bool isConnected = false; // Do we have a GPS we are talking to
bool hasLock = false; // default to false, until we complete our first read
bool isConnected = false; // Do we have a GPS we are talking to
Position p = Position_init_default;
@@ -42,8 +42,7 @@ class GPSStatus : public Status
}
// preferred method
GPSStatus(bool hasLock, bool isConnected, const Position& pos)
: Status()
GPSStatus(bool hasLock, bool isConnected, const Position &pos) : Status()
{
this->hasLock = hasLock;
this->isConnected = isConnected;
@@ -61,8 +60,9 @@ class GPSStatus : public Status
bool getIsConnected() const { return isConnected; }
int32_t getLatitude() const {
if (radioConfig.preferences.fixed_position){
int32_t getLatitude() const
{
if (config.position.fixed_position) {
#ifdef GPS_EXTRAVERBOSE
DEBUG_MSG("WARNING: Using fixed latitude\n");
#endif
@@ -73,8 +73,9 @@ class GPSStatus : public Status
}
}
int32_t getLongitude() const {
if (radioConfig.preferences.fixed_position){
int32_t getLongitude() const
{
if (config.position.fixed_position) {
#ifdef GPS_EXTRAVERBOSE
DEBUG_MSG("WARNING: Using fixed longitude\n");
#endif
@@ -85,8 +86,9 @@ class GPSStatus : public Status
}
}
int32_t getAltitude() const {
if (radioConfig.preferences.fixed_position){
int32_t getAltitude() const
{
if (config.position.fixed_position) {
#ifdef GPS_EXTRAVERBOSE
DEBUG_MSG("WARNING: Using fixed altitude\n");
#endif
@@ -106,17 +108,12 @@ class GPSStatus : public Status
bool matches(const GPSStatus *newStatus) const
{
#ifdef GPS_EXTRAVERBOSE
DEBUG_MSG("GPSStatus.match() new pos@%x to old pos@%x\n",
newStatus->p.pos_timestamp, p.pos_timestamp);
DEBUG_MSG("GPSStatus.match() new pos@%x to old pos@%x\n", newStatus->p.pos_timestamp, p.pos_timestamp);
#endif
return (newStatus->hasLock != hasLock ||
newStatus->isConnected != isConnected ||
newStatus->p.latitude_i != p.latitude_i ||
newStatus->p.longitude_i != p.longitude_i ||
newStatus->p.altitude != p.altitude ||
newStatus->p.altitude_hae != p.altitude_hae ||
newStatus->p.PDOP != p.PDOP ||
newStatus->p.ground_track != p.ground_track ||
return (newStatus->hasLock != hasLock || newStatus->isConnected != isConnected ||
newStatus->p.latitude_i != p.latitude_i || newStatus->p.longitude_i != p.longitude_i ||
newStatus->p.altitude != p.altitude || newStatus->p.altitude_hae != p.altitude_hae ||
newStatus->p.PDOP != p.PDOP || newStatus->p.ground_track != p.ground_track ||
newStatus->p.sats_in_view != p.sats_in_view);
}
@@ -125,8 +122,7 @@ class GPSStatus : public Status
// Only update the status if values have actually changed
bool isDirty = matches(newStatus);
if (isDirty && p.pos_timestamp &&
(newStatus->p.pos_timestamp == p.pos_timestamp)) {
if (isDirty && p.pos_timestamp && (newStatus->p.pos_timestamp == p.pos_timestamp)) {
// We can NEVER be in two locations at the same time! (also PR #886)
DEBUG_MSG("BUG!! positional timestamp unchanged from prev solution\n");
}
@@ -140,11 +136,9 @@ class GPSStatus : public Status
if (isDirty) {
if (hasLock) {
// In debug logs, identify position by @timestamp:stage (stage 3 = notify)
DEBUG_MSG("New GPS pos@%x:3 lat=%f, lon=%f, alt=%d, pdop=%.2f, track=%.2f, sats=%d\n",
p.pos_timestamp,
p.latitude_i * 1e-7, p.longitude_i * 1e-7,
p.altitude, p.PDOP * 1e-2, p.ground_track * 1e-5,
p.sats_in_view);
DEBUG_MSG("New GPS pos@%x:3 lat=%f, lon=%f, alt=%d, pdop=%.2f, track=%.2f, sats=%d\n", p.pos_timestamp,
p.latitude_i * 1e-7, p.longitude_i * 1e-7, p.altitude, p.PDOP * 1e-2, p.ground_track * 1e-5,
p.sats_in_view);
} else
DEBUG_MSG("No GPS lock\n");
onNewStatus.notifyObservers(this);

View File

@@ -1,10 +1,11 @@
#include "configuration.h"
#include "power.h"
#include "NodeDB.h"
#include "PowerFSM.h"
#include "configuration.h"
#include "main.h"
#include "sleep.h"
#include "utils.h"
#include "buzz/buzz.h"
#ifdef TBEAM_V10
// FIXME. nasty hack cleanup how we load axp192
@@ -13,27 +14,28 @@
AXP20X_Class axp;
#else
// Copy of the base class defined in axp20x.h.
// Copy of the base class defined in axp20x.h.
// I'd rather not inlude axp20x.h as it brings Wire dependency.
class HasBatteryLevel {
public:
/**
* Battery state of charge, from 0 to 100 or -1 for unknown
*/
virtual int getBattPercentage() { return -1; }
class HasBatteryLevel
{
public:
/**
* Battery state of charge, from 0 to 100 or -1 for unknown
*/
virtual int getBattPercentage() { return -1; }
/**
* The raw voltage of the battery or NAN if unknown
*/
virtual float getBattVoltage() { return NAN; }
/**
* The raw voltage of the battery or NAN if unknown
*/
virtual float getBattVoltage() { return NAN; }
/**
* return true if there is a battery installed in this unit
*/
virtual bool isBatteryConnect() { return false; }
/**
* return true if there is a battery installed in this unit
*/
virtual bool isBatteryConnect() { return false; }
virtual bool isVBUSPlug() { return false; }
virtual bool isChargeing() { return false; }
virtual bool isVBUSPlug() { return false; }
virtual bool isChargeing() { return false; }
};
#endif
@@ -99,24 +101,24 @@ class AnalogBatteryLevel : public HasBatteryLevel
#ifndef ADC_MULTIPLIER
#define ADC_MULTIPLIER 2.0
#endif
// Override variant or default ADC_MULTIPLIER if we have the override pref
float operativeAdcMultiplier = radioConfig.preferences.adc_multiplier_override > 0 ?
radioConfig.preferences.adc_multiplier_override :
ADC_MULTIPLIER;
#endif
#ifdef BATTERY_PIN
// Do not call analogRead() often.
// Override variant or default ADC_MULTIPLIER if we have the override pref
float operativeAdcMultiplier = config.power.adc_multiplier_override > 0
? config.power.adc_multiplier_override
: ADC_MULTIPLIER;
// Do not call analogRead() often.
const uint32_t min_read_interval = 5000;
if (millis() - last_read_time_ms > min_read_interval) {
last_read_time_ms = millis();
uint32_t raw = analogRead(BATTERY_PIN);
float scaled;
#ifndef VBAT_RAW_TO_SCALED
#ifndef VBAT_RAW_TO_SCALED
scaled = 1000.0 * operativeAdcMultiplier * (AREF_VOLTAGE / 1024.0) * raw;
#else
scaled = VBAT_RAW_TO_SCALED(raw); //defined in variant.h
#endif
#else
scaled = VBAT_RAW_TO_SCALED(raw); // defined in variant.h
#endif
// DEBUG_MSG("battery gpio %d raw val=%u scaled=%u\n", BATTERY_PIN, raw, (uint32_t)(scaled));
last_read_value = scaled;
return scaled;
@@ -153,7 +155,8 @@ class AnalogBatteryLevel : public HasBatteryLevel
AnalogBatteryLevel analogLevel;
Power::Power() : OSThread("Power") {
Power::Power() : OSThread("Power")
{
statusHandler = {};
low_voltage_counter = 0;
}
@@ -172,7 +175,7 @@ bool Power::analogInit()
#endif
#ifdef NRF52_SERIES
#ifdef VBAT_AR_INTERNAL
analogReference(VBAT_AR_INTERNAL);
analogReference(VBAT_AR_INTERNAL);
#else
analogReference(AR_INTERNAL); // 3.6V
#endif
@@ -181,9 +184,10 @@ bool Power::analogInit()
#ifndef BATTERY_SENSE_RESOLUTION_BITS
#define BATTERY_SENSE_RESOLUTION_BITS 10
#endif
// adcStart(BATTERY_PIN);
analogReadResolution(BATTERY_SENSE_RESOLUTION_BITS); // Default of 12 is not very linear. Recommended to use 10 or 11 depending on needed resolution.
analogReadResolution(BATTERY_SENSE_RESOLUTION_BITS); // Default of 12 is not very linear. Recommended to use 10 or 11
// depending on needed resolution.
batteryLevel = &analogLevel;
return true;
#else
@@ -208,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
}
@@ -246,24 +254,23 @@ void Power::readPowerStatus()
powerStatus2.getIsCharging(), powerStatus2.getBatteryVoltageMv(), powerStatus2.getBatteryChargePercent());
newStatus.notifyObservers(&powerStatus2);
// If we have a battery at all and it is less than 10% full, force deep sleep if we have more than 3 low readings in a row
// Supect fluctuating voltage on the RAK4631 to force it to deep sleep even if battery is at 85% after only a few days
#ifdef NRF52_SERIES
if (powerStatus2.getHasBattery() && !powerStatus2.getHasUSB()){
if (batteryLevel->getBattVoltage() < MIN_BAT_MILLIVOLTS){
// If we have a battery at all and it is less than 10% full, force deep sleep if we have more than 3 low readings in a row
// Supect fluctuating voltage on the RAK4631 to force it to deep sleep even if battery is at 85% after only a few days
#ifdef NRF52_SERIES
if (powerStatus2.getHasBattery() && !powerStatus2.getHasUSB()) {
if (batteryLevel->getBattVoltage() < MIN_BAT_MILLIVOLTS) {
low_voltage_counter++;
if (low_voltage_counter>3)
if (low_voltage_counter > 3)
powerFSM.trigger(EVENT_LOW_BATTERY);
} else {
low_voltage_counter = 0;
}
}
#else
#else
// If we have a battery at all and it is less than 10% full, force deep sleep
if (powerStatus2.getHasBattery() && !powerStatus2.getHasUSB() && batteryLevel->getBattVoltage() < MIN_BAT_MILLIVOLTS)
powerFSM.trigger(EVENT_LOW_BATTERY);
#endif
#endif
} else {
// No power sensing on this board - tell everyone else we have no idea what is happening
const PowerStatus powerStatus3 = PowerStatus(OptUnknown, OptUnknown, OptUnknown, -1, -1);
@@ -355,40 +362,58 @@ bool Power::axp192Init()
DEBUG_MSG("DCDC3: %s\n", axp.isDCDC3Enable() ? "ENABLE" : "DISABLE");
DEBUG_MSG("Exten: %s\n", axp.isExtenEnable() ? "ENABLE" : "DISABLE");
if (radioConfig.preferences.charge_current == ChargeCurrent_MAUnset) {
switch (config.power.charge_current) {
case Config_PowerConfig_ChargeCurrent_MAUnset:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_450MA);
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA100) {
break;
case Config_PowerConfig_ChargeCurrent_MA100:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_100MA);
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA190) {
break;
case Config_PowerConfig_ChargeCurrent_MA190:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_190MA);
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA280) {
break;
case Config_PowerConfig_ChargeCurrent_MA280:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_280MA);
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA360) {
break;
case Config_PowerConfig_ChargeCurrent_MA360:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_360MA);
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA450) {
break;
case Config_PowerConfig_ChargeCurrent_MA450:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_450MA);
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA550) {
break;
case Config_PowerConfig_ChargeCurrent_MA550:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_550MA);
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA630) {
break;
case Config_PowerConfig_ChargeCurrent_MA630:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_630MA);
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA700) {
break;
case Config_PowerConfig_ChargeCurrent_MA700:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_700MA);
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA780) {
break;
case Config_PowerConfig_ChargeCurrent_MA780:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_780MA);
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA880) {
break;
case Config_PowerConfig_ChargeCurrent_MA880:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_880MA);
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA960) {
break;
case Config_PowerConfig_ChargeCurrent_MA960:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_960MA);
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA1000) {
break;
case Config_PowerConfig_ChargeCurrent_MA1000:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_1000MA);
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA1080) {
break;
case Config_PowerConfig_ChargeCurrent_MA1080:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_1080MA);
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA1160) {
break;
case Config_PowerConfig_ChargeCurrent_MA1160:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_1160MA);
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA1240) {
break;
case Config_PowerConfig_ChargeCurrent_MA1240:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_1240MA);
} else if (radioConfig.preferences.charge_current == ChargeCurrent_MA1320) {
break;
case Config_PowerConfig_ChargeCurrent_MA1320:
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_1320MA);
break;
}
#if 0

View File

@@ -11,30 +11,30 @@
/// 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 (radioConfig.preferences.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 = (radioConfig.preferences.role == Role_Router ? 1 : 0);
bool isRouter = (config.device.role == Config_DeviceConfig_Role_Router ? 1 : 0);
// If we are not a router and we already have AC power go to POWER state after init, otherwise go to ON
// We assume routers might be powered all the time, but from a low current (solar) source
bool isLowPower = radioConfig.preferences.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()
{
DEBUG_MSG("Enter state: SDS\n");
// FIXME - make sure GPS and LORA radio are off first - because we want close to zero current draw
doDeepSleep(getPref_sds_secs() * 1000LL);
doDeepSleep(config.power.sds_secs ? config.power.sds_secs : default_sds_secs * 1000LL);
}
extern Power *power;
@@ -51,7 +51,8 @@ static uint32_t secsSlept;
static void lsEnter()
{
DEBUG_MSG("lsEnter begin, ls_secs=%u\n", getPref_ls_secs());
DEBUG_MSG("lsEnter begin, ls_secs=%u\n",
config.power.ls_secs ? config.power.ls_secs : default_ls_secs);
screen->setOn(false);
secsSlept = 0; // How long have we been sleeping this time
@@ -65,7 +66,7 @@ static void lsIdle()
#ifndef NO_ESP32
// Do we have more sleeping to do?
if (secsSlept < getPref_ls_secs()) {
if (secsSlept < config.power.ls_secs ? config.power.ls_secs : default_ls_secs * 1000) {
// Briefly come out of sleep long enough to blink the led once every few seconds
uint32_t sleepTime = 30;
@@ -78,7 +79,7 @@ static void lsIdle()
case ESP_SLEEP_WAKEUP_TIMER:
// Normal case: timer expired, we should just go back to sleep ASAP
setLed(true); // briefly turn on led
setLed(true); // briefly turn on led
wakeCause2 = doLightSleep(1); // leave led on for 1ms
secsSlept += sleepTime;
@@ -238,7 +239,7 @@ Fsm powerFSM(&stateBOOT);
void PowerFSM_setup()
{
bool isRouter = (radioConfig.preferences.role == Role_Router ? 1 : 0);
bool isRouter = (config.device.role == Config_DeviceConfig_Role_Router ? 1 : 0);
bool hasPower = isPowered();
DEBUG_MSG("PowerFSM init, USB power=%d\n", hasPower);
@@ -332,7 +333,10 @@ void PowerFSM_setup()
powerFSM.add_transition(&stateDARK, &stateON, EVENT_FIRMWARE_UPDATE, NULL, "Got firmware update");
powerFSM.add_transition(&stateON, &stateON, EVENT_FIRMWARE_UPDATE, NULL, "Got firmware update");
powerFSM.add_timed_transition(&stateON, &stateDARK, getPref_screen_on_secs() * 1000, NULL, "Screen-on timeout");
powerFSM.add_timed_transition(&stateON, &stateDARK,
config.display.screen_on_secs ? config.display.screen_on_secs
: 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
State *lowPowerState = &stateLS;
@@ -343,13 +347,18 @@ void PowerFSM_setup()
// We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally)
// See: https://github.com/meshtastic/Meshtastic-device/issues/1071
if (isRouter || radioConfig.preferences.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, getPref_min_wake_secs() * 1000, NULL, "Min wake timeout");
powerFSM.add_timed_transition(&stateDARK, &stateLS, getPref_wait_bluetooth_secs() * 1000, NULL, "Bluetooth timeout");
meshSds = getPref_mesh_sds_timeout_secs();
if (isRouter || config.power.is_power_saving) {
powerFSM.add_timed_transition(&stateNB, &stateLS,
config.power.min_wake_secs ? config.power.min_wake_secs
: default_min_wake_secs * 1000,
NULL, "Min wake timeout");
powerFSM.add_timed_transition(&stateDARK, &stateLS,
config.power.wait_bluetooth_secs
? config.power.wait_bluetooth_secs
: default_wait_bluetooth_secs * 1000,
NULL, "Bluetooth timeout");
meshSds = config.power.mesh_sds_timeout_secs ? config.power.mesh_sds_timeout_secs
: default_mesh_sds_timeout_secs;
} else {

View File

@@ -1,9 +1,9 @@
#include "configuration.h"
#include "concurrency/OSThread.h"
#include "main.h"
#include "PowerFSM.h"
#include "power.h"
#include "NodeDB.h"
#include "PowerFSM.h"
#include "concurrency/OSThread.h"
#include "configuration.h"
#include "main.h"
#include "power.h"
namespace concurrency
{
@@ -26,13 +26,16 @@ class PowerFSMThread : public OSThread
if (powerStatus->getHasUSB()) {
timeLastPowered = millis();
} else if (radioConfig.preferences.on_battery_shutdown_after_secs > 0 &&
millis() > timeLastPowered + (1000 * radioConfig.preferences.on_battery_shutdown_after_secs)) { //shutdown after 30 minutes unpowered
} else if (config.power.on_battery_shutdown_after_secs > 0 &&
millis() >
timeLastPowered +
(1000 *
config.power.on_battery_shutdown_after_secs)) { // shutdown after 30 minutes unpowered
powerFSM.trigger(EVENT_SHUTDOWN);
}
return 10;
}
};
}
} // namespace concurrency

View File

@@ -72,7 +72,7 @@ size_t RedirectablePrint::logDebug(const char *format, ...)
// If we are the first message on a report, include the header
if (!isContinuationMessage) {
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityFromNet);
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice);
if (rtc_sec > 0) {
long hms = rtc_sec % SEC_PER_DAY;
// hms += tz.tz_dsttime * SEC_PER_HOUR;

View File

@@ -1,9 +1,11 @@
#include "configuration.h"
#include "SerialConsole.h"
#include "NodeDB.h"
#include "PowerFSM.h"
#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,11 +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) < getPref_phone_timeout_secs() * 1000UL;
return (now - lastContactMsec) < SERIAL_CONNECTION_TIMEOUT;
}
/**
@@ -55,10 +58,9 @@ bool SerialConsole::checkIsConnected()
bool SerialConsole::handleToRadio(const uint8_t *buf, size_t len)
{
// Turn off debug serial printing once the API is activated, because other threads could print and corrupt packets
if (!radioConfig.preferences.debug_log_enabled)
if (!config.device.debug_log_enabled)
setDestination(&noopPrint);
canWrite = true;
return StreamAPI::handleToRadio(buf, len);
}

View File

@@ -1,10 +1,6 @@
#include "buzz.h"
#include "configuration.h"
#ifdef NRF52_SERIES
#include "variant.h"
#endif
#ifndef PIN_BUZZER
// Noop methods for boards w/o buzzer
@@ -12,8 +8,13 @@ void playBeep(){};
void playStartMelody(){};
void playShutdownMelody(){};
#else
#ifdef M5STACK
#include "Speaker.h"
TONE Tone;
#else
#include "Tone.h"
#endif
extern "C" void delay(uint32_t dwMs);
@@ -42,13 +43,26 @@ const int DURATION_1_4 = 250; // 1/4 note
void playTones(const ToneDuration *tone_durations, int size) {
for (int i = 0; i < size; i++) {
const auto &tone_duration = tone_durations[i];
#ifdef M5STACK
Tone.tone(tone_duration.frequency_khz);
delay(tone_duration.duration_ms);
Tone.mute();
#else
tone(PIN_BUZZER, tone_duration.frequency_khz, tone_duration.duration_ms);
#endif
// to distinguish the notes, set a minimum time between them.
delay(1.3 * tone_duration.duration_ms);
}
}
#ifdef M5STACK
void playBeep() {
ToneDuration melody[] = {{NOTE_B3, DURATION_1_4}};
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
}
#else
void playBeep() { tone(PIN_BUZZER, NOTE_B3, DURATION_1_4); }
#endif
void playStartMelody() {
ToneDuration melody[] = {{NOTE_B3, DURATION_1_4},

View File

@@ -25,6 +25,14 @@ 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
#ifdef PCF8563_RTC
#include "pcf8563.h"
#endif
// -----------------------------------------------------------------------------
// Version
// -----------------------------------------------------------------------------
@@ -100,10 +108,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define GPS_TX_PIN 12
#endif
#ifndef TTGO_T_ECHO
#define GPS_UBLOX
#endif
// -----------------------------------------------------------------------------
// LoRa SPI
// -----------------------------------------------------------------------------
@@ -118,6 +122,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#endif
#ifndef TTGO_T_ECHO
#define GPS_UBLOX
#endif
//
// Standard definitions for !ESP32 targets
//
@@ -134,7 +142,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// -----------------------------------------------------------------------------
// Disable use of the NTP library and related features
//#define DISABLE_NTP
// #define DISABLE_NTP
// Disable the welcome screen and allow
// #define DISABLE_WELCOME_UNSET
@@ -163,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
// -----------------------------------------------------------------------------
@@ -262,6 +279,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define HW_VENDOR HardwareModel_NRF52840_PCA10059
#elif defined(M5STACK)
#define HW_VENDOR HardwareModel_M5STACK
#elif NRF52_SERIES
#define HW_VENDOR HardwareModel_NRF52_UNKNOWN

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,6 +53,7 @@ uint8_t oled_probe(byte addr)
void scanI2Cdevice(void)
{
byte err, addr;
uint16_t registerValue = 0x00;
int nDevices = 0;
for (addr = 1; addr < 127; addr++) {
Wire.beginTransmission(addr);
@@ -54,10 +74,33 @@ void scanI2Cdevice(void)
DEBUG_MSG("unknown display found\n");
}
}
#ifdef RV3028_RTC
if (addr == RV3028_RTC){
rtc_found = addr;
DEBUG_MSG("RV3028 RTC found\n");
Melopero_RV3028 rtc;
rtc.initI2C();
rtc.writeToRegister(0x35,0x07); // no Clkout
rtc.writeToRegister(0x37,0xB4);
}
#endif
#ifdef PCF8563_RTC
if (addr == PCF8563_RTC){
rtc_found = addr;
DEBUG_MSG("PCF8563 RTC found\n");
}
#endif
if (addr == CARDKB_ADDR) {
cardkb_found = addr;
DEBUG_MSG("m5 cardKB found\n");
// Do we have the RAK14006 instead?
registerValue = getRegisterValue(addr, 0x04, 1);
if (registerValue == 0x02) { // KEYPAD_VERSION
DEBUG_MSG("RAK14004 found\n");
kb_model = 0x02;
} else {
DEBUG_MSG("m5 cardKB found\n");
kb_model = 0x00;
}
}
if (addr == FACESKB_ADDR) {
faceskb_found = addr;
@@ -73,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);
}
@@ -81,7 +149,7 @@ void scanI2Cdevice(void)
if (nDevices == 0)
DEBUG_MSG("No I2C devices found\n");
else
DEBUG_MSG("done\n");
DEBUG_MSG("%i I2C devices found\n",nDevices);
}
#else
void scanI2Cdevice(void) {}

View File

@@ -23,9 +23,6 @@
// proccess at once
// static uint8_t trBytes[_max(_max(_max(_max(ToRadio_size, RadioConfig_size), User_size), MyNodeInfo_size), FromRadio_size)];
static uint8_t fromRadioBytes[FromRadio_size];
static uint8_t toRadioBytes[ToRadio_size];
static bool bleConnected;
NimBLECharacteristic *FromNumCharacteristic;
NimBLEServer *bleServer;

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

@@ -1,7 +1,7 @@
#include "configuration.h"
#include "GPS.h"
#include "NodeDB.h"
#include "RTC.h"
#include "configuration.h"
#include "sleep.h"
#include <assert.h>
@@ -22,6 +22,43 @@ GPS *gps;
/// only init that port once.
static bool didSerialInit;
bool GPS::getACK(uint8_t c, uint8_t i) {
uint8_t b;
uint8_t ack = 0;
const uint8_t ackP[2] = {c, i};
uint8_t buf[10] = {0xB5, 0x62, 0x05, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned long startTime = millis();
for (int j = 2; j < 6; j++) {
buf[8] += buf[j];
buf[9] += buf[8];
}
for (int j = 0; j < 2; j++) {
buf[6 + j] = ackP[j];
buf[8] += buf[6 + j];
buf[9] += buf[8];
}
while (1) {
if (ack > 9) {
return true;
}
if (millis() - startTime > 1000) {
return false;
}
if (_serial_gps->available()) {
b = _serial_gps->read();
if (b == buf[ack]) {
ack++;
}
else {
ack = 0;
}
}
}
}
bool GPS::setupGPS()
{
if (_serial_gps && !didSerialInit) {
@@ -37,13 +74,17 @@ bool GPS::setupGPS()
_serial_gps->setRxBufferSize(2048); // the default is 256
#endif
#ifdef TTGO_T_ECHO
// Switch to 4800 baud, then close and reopen port
_serial_gps->write("$PCAS01,0*1C\r\n");
delay(250);
// Switch to 9600 baud, then close and reopen port
_serial_gps->end();
delay(250);
_serial_gps->begin(4800);
delay(250);
_serial_gps->write("$PCAS01,1*1D\r\n");
delay(250);
_serial_gps->end();
delay(250);
_serial_gps->begin(9600);
delay(250);
// Initialize the L76K Chip, use GPS + GLONASS
_serial_gps->write("$PCAS04,5*1C\r\n");
delay(250);
@@ -53,57 +94,62 @@ bool GPS::setupGPS()
// Switch to Vehicle Mode, since SoftRF enables Aviation < 2g
_serial_gps->write("$PCAS11,3*1E\r\n");
delay(250);
#endif
#ifdef GPS_UBLOX
// Set the UART port to output NMEA only
byte _message_nmea[] = {0xB5, 0x62, 0x06, 0x00, 0x14, 0x00,
0x01, 0x00, 0x00, 0x00, 0xC0, 0x08, 0x00, 0x00, 0x80, 0x25, 0x00, 0x00, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
0x91, 0xAF};
_serial_gps->write(_message_nmea,sizeof(_message_nmea));
delay(250);
// Set the UART port to output NMEA only
byte _message_nmea[] = {0xB5, 0x62, 0x06, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0xC0, 0x08, 0x00, 0x00,
0x80, 0x25, 0x00, 0x00, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0xAF};
_serial_gps->write(_message_nmea, sizeof(_message_nmea));
if (!getACK(0x06, 0x00)) {
DEBUG_MSG("WARNING: Unable to enable NMEA Mode.\n");
return true;
}
// disable GGL
byte _message_GGL[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00,
0xF0, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
0x05,0x3A};
_serial_gps->write(_message_GGL,sizeof(_message_GGL));
delay(250);
byte _message_GGL[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x05, 0x3A};
_serial_gps->write(_message_GGL, sizeof(_message_GGL));
if (!getACK(0x06, 0x01)) {
DEBUG_MSG("WARNING: Unable to disable NMEA GGL.\n");
return true;
}
// disable GSA
byte _message_GSA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00,
0xF0, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
0x06,0x41};
_serial_gps->write(_message_GSA,sizeof(_message_GSA));
delay(250);
byte _message_GSA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x06, 0x41};
_serial_gps->write(_message_GSA, sizeof(_message_GSA));
if (!getACK(0x06, 0x01)) {
DEBUG_MSG("WARNING: Unable to disable NMEA GSA.\n");
return true;
}
// disable GSV
byte _message_GSV[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00,
0xF0, 0x03, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
0x07,0x48};
_serial_gps->write(_message_GSV,sizeof(_message_GSV));
delay(250);
byte _message_GSV[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x03, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x07, 0x48};
_serial_gps->write(_message_GSV, sizeof(_message_GSV));
if (!getACK(0x06, 0x01)) {
DEBUG_MSG("WARNING: Unable to disable NMEA GSV.\n");
return true;
}
// disable VTG
byte _message_VTG[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00,
0xF0, 0x05, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
0x09,0x56};
_serial_gps->write(_message_VTG,sizeof(_message_VTG));
delay(250);
byte _message_VTG[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x05, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x09, 0x56};
_serial_gps->write(_message_VTG, sizeof(_message_VTG));
if (!getACK(0x06, 0x01)) {
DEBUG_MSG("WARNING: Unable to disable NMEA VTG.\n");
return true;
}
// enable RMC
byte _message_RMC[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00,
0xF0, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x09,0x54};
_serial_gps->write(_message_RMC,sizeof(_message_RMC));
delay(250);
byte _message_RMC[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x09, 0x54};
_serial_gps->write(_message_RMC, sizeof(_message_RMC));
if (!getACK(0x06, 0x01)) {
DEBUG_MSG("WARNING: Unable to enable NMEA RMC.\n");
return true;
}
// enable GGA
byte _message_GGA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00,
0xF0, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x05, 0x38};
_serial_gps->write(_message_GGA,sizeof(_message_GGA));
delay(250);
byte _message_GGA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x05, 0x38};
_serial_gps->write(_message_GGA, sizeof(_message_GGA));
if (!getACK(0x06, 0x01)) DEBUG_MSG("WARNING: Unable to enable NMEA GGA.\n");
#endif
}
@@ -143,7 +189,15 @@ GPS::~GPS()
notifyDeepSleepObserver.unobserve(&notifyDeepSleep);
}
bool GPS::hasLock() { return hasValidLocation; }
bool GPS::hasLock()
{
return hasValidLocation;
}
bool GPS::hasFlow()
{
return hasGPS;
}
// Allow defining the polarity of the WAKE output. default is active high
#ifndef GPS_WAKE_ACTIVE
@@ -213,14 +267,16 @@ void GPS::setAwake(bool on)
*/
uint32_t GPS::getWakeTime() const
{
uint32_t t = radioConfig.preferences.gps_attempt_time;
uint32_t t = config.position.gps_attempt_time;
if (t == UINT32_MAX)
return t; // already maxint
if (t == 0)
t = (radioConfig.preferences.role == Role_Router) ? 5 * 60 : 15 * 60; // Allow up to 15 mins for each attempt (probably will be much
// less if we can find sats) or less if a router
t = (config.device.role == Config_DeviceConfig_Role_Router)
? 5 * 60
: 15 * 60; // Allow up to 15 mins for each attempt (probably will be much
// less if we can find sats) or less if a router
t *= 1000; // msecs
@@ -231,18 +287,18 @@ uint32_t GPS::getWakeTime() const
*/
uint32_t GPS::getSleepTime() const
{
uint32_t t = radioConfig.preferences.gps_update_interval;
bool gps_disabled = radioConfig.preferences.gps_disabled;
bool loc_share_disabled = radioConfig.preferences.location_share_disabled;
uint32_t t = config.position.gps_update_interval;
bool gps_disabled = config.position.gps_disabled;
if (gps_disabled || loc_share_disabled)
if (gps_disabled)
t = UINT32_MAX; // Sleep forever now
if (t == UINT32_MAX)
return t; // already maxint
if (t == 0) // default - unset in preferences
t = (radioConfig.preferences.role == Role_Router) ? 24 * 60 * 60 : 2 * 60; // 2 mins or once per day for routers
if (t == 0) // default - unset in preferences
t = (config.device.role == Config_DeviceConfig_Role_Router) ? 24 * 60 * 60
: 2 * 60; // 2 mins or once per day for routers
t *= 1000;
@@ -255,12 +311,10 @@ void GPS::publishUpdate()
shouldPublish = false;
// In debug logs, identify position by @timestamp:stage (stage 2 = publish)
DEBUG_MSG("publishing pos@%x:2, hasVal=%d, GPSlock=%d\n",
p.pos_timestamp, hasValidLocation, hasLock());
DEBUG_MSG("publishing pos@%x:2, hasVal=%d, GPSlock=%d\n", p.pos_timestamp, hasValidLocation, hasLock());
// Notify any status instances that are observing us
const meshtastic::GPSStatus status =
meshtastic::GPSStatus(hasValidLocation, isConnected(), p);
const meshtastic::GPSStatus status = meshtastic::GPSStatus(hasValidLocation, isConnected(), p);
newStatus.notifyObservers(&status);
}
}
@@ -270,6 +324,15 @@ int32_t GPS::runOnce()
if (whileIdle()) {
// if we have received valid NMEA claim we are connected
setConnected();
} else {
#ifdef GPS_UBLOX
// reset the GPS on next bootup
if(devicestate.did_gps_reset && (millis() > 60000) && !hasFlow()) {
DEBUG_MSG("GPS is not communicating, trying factory reset on next bootup.\n");
devicestate.did_gps_reset = false;
nodeDB.saveToDisk();
}
#endif
}
// If we are overdue for an update, turn on the GPS and at least publish the current status
@@ -379,7 +442,7 @@ GPS *createGps()
#ifdef NO_GPS
return nullptr;
#else
if (!radioConfig.preferences.gps_disabled){
if (!config.position.gps_disabled) {
#ifdef GPS_ALTITUDE_HAE
DEBUG_MSG("Using HAE altitude model\n");
#else

View File

@@ -57,6 +57,9 @@ class GPS : private concurrency::OSThread
/// Returns true if we have acquired GPS lock.
virtual bool hasLock();
/// Returns true if there's valid data flow with the chip.
virtual bool hasFlow();
/// Return true if we are connected to a GPS
bool isConnected() const { return hasGPS; }
@@ -135,6 +138,8 @@ class GPS : private concurrency::OSThread
*/
uint32_t getSleepTime() const;
bool getACK(uint8_t c, uint8_t i);
/**
* Tell users we have new GPS readings
*/

View File

@@ -17,6 +17,19 @@ static int32_t toDegInt(RawDegrees d)
return r;
}
bool NMEAGPS::factoryReset()
{
#ifdef GPS_UBLOX
// Factory Reset
byte _message_reset[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF,
0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0x00, 0x00, 0x17, 0x2B, 0x7E};
_serial_gps->write(_message_reset,sizeof(_message_reset));
delay(1000);
#endif
return true;
}
bool NMEAGPS::setupGPS()
{
GPS::setupGPS();
@@ -65,7 +78,7 @@ The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of s
t.tm_year = d.year() - 1900;
t.tm_isdst = false;
if (t.tm_mon > -1){
DEBUG_MSG("NMEA GPS time %d-%d-%d %d:%d:%d\n", d.year(), d.month(), t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
DEBUG_MSG("NMEA GPS time %02d-%02d-%02d %02d:%02d:%02d\n", d.year(), d.month(), t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
perhapsSetRTC(RTCQualityGPS, t);
return true;
} else
@@ -222,6 +235,10 @@ bool NMEAGPS::hasLock()
return false;
}
bool NMEAGPS::hasFlow()
{
return reader.passedChecksum() > 0;
}
bool NMEAGPS::whileIdle()
{

View File

@@ -25,6 +25,8 @@ class NMEAGPS : public GPS
public:
virtual bool setupGPS() override;
virtual bool factoryReset() override;
protected:
/** Subclasses should look for serial rx characters here and feed it to their GPS parser
*
@@ -49,4 +51,6 @@ class NMEAGPS : public GPS
virtual bool lookForLocation() override;
virtual bool hasLock() override;
virtual bool hasFlow() override;
};

View File

@@ -1,5 +1,6 @@
#include "RTC.h"
#include "configuration.h"
#include "main.h"
#include <sys/time.h>
#include <time.h>
@@ -18,14 +19,57 @@ static uint64_t zeroOffsetSecs; // GPS based time in secs since 1970 - only upda
void readFromRTC()
{
struct timeval tv; /* btw settimeofday() is helpfull here too*/
#ifdef RV3028_RTC
if(rtc_found == RV3028_RTC) {
uint32_t now = millis();
Melopero_RV3028 rtc;
rtc.initI2C();
tm t;
t.tm_year = rtc.getYear() - 1900;
t.tm_mon = rtc.getMonth() - 1;
t.tm_mday = rtc.getDate();
t.tm_hour = rtc.getHour();
t.tm_min = rtc.getMinute();
t.tm_sec = rtc.getSecond();
tv.tv_sec = mktime(&t);
tv.tv_usec = 0;
DEBUG_MSG("Read RTC time from RV3028 as %ld\n", tv.tv_sec);
timeStartMsec = now;
zeroOffsetSecs = tv.tv_sec;
if (currentQuality == RTCQualityNone) {
currentQuality = RTCQualityDevice;
}
}
#elif defined(PCF8563_RTC)
if(rtc_found == PCF8563_RTC) {
uint32_t now = millis();
PCF8563_Class rtc;
rtc.begin();
auto tc = rtc.getDateTime();
tm t;
t.tm_year = tc.year;
t.tm_mon = tc.month;
t.tm_mday = tc.day;
t.tm_hour = tc.hour;
t.tm_min = tc.minute;
t.tm_sec = tc.second;
tv.tv_sec = mktime(&t);
tv.tv_usec = 0;
DEBUG_MSG("Read RTC time from PCF8563 as %ld\n", tv.tv_sec);
timeStartMsec = now;
zeroOffsetSecs = tv.tv_sec;
if (currentQuality == RTCQualityNone) {
currentQuality = RTCQualityDevice;
}
}
#else
if (!gettimeofday(&tv, NULL)) {
uint32_t now = millis();
DEBUG_MSG("Read RTC time as %ld (cur millis %u) quality=%d\n", tv.tv_sec, now, currentQuality);
DEBUG_MSG("Read RTC time as %ld\n", tv.tv_sec);
timeStartMsec = now;
zeroOffsetSecs = tv.tv_sec;
}
#endif
}
/// If we haven't yet set our RTC this boot, set it from a GPS derived time
@@ -55,12 +99,28 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
zeroOffsetSecs = tv->tv_sec;
// If this platform has a setable RTC, set it
#ifndef NO_ESP32
#ifdef RV3028_RTC
if(rtc_found == RV3028_RTC) {
Melopero_RV3028 rtc;
rtc.initI2C();
tm *t = localtime(&tv->tv_sec);
rtc.setTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_wday, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
DEBUG_MSG("RV3028_RTC setTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec);
}
#elif defined(PCF8563_RTC)
if(rtc_found == PCF8563_RTC) {
PCF8563_Class rtc;
rtc.begin();
tm *t = localtime(&tv->tv_sec);
rtc.setDateTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_wday, t->tm_hour, t->tm_min, t->tm_sec);
DEBUG_MSG("PCF8563_RTC setDateTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec);
}
#elif !defined(NO_ESP32)
settimeofday(tv, NULL);
#endif
// nrf52 doesn't have a readable RTC (yet - software not written)
#if defined(PORTDUINO) || !defined(NO_ESP32)
#if defined(PORTDUINO) || !defined(NO_ESP32) || defined(RV3028_RTC) || defined(PCF8563_RTC)
readFromRTC();
#endif

View File

@@ -5,17 +5,21 @@
#include <Arduino.h>
enum RTCQuality {
/// We haven't had our RTC set yet
RTCQualityNone = 0,
/// We got time from an onboard peripheral after boot.
RTCQualityDevice = 1,
/// Some other node gave us a time we can use
RTCQualityFromNet = 1,
RTCQualityFromNet = 2,
/// Our time is based on NTP
RTCQualityNTP= 2,
RTCQualityNTP= 3,
/// Our time is based on our own GPS
RTCQualityGPS = 3
RTCQualityGPS = 4
};
RTCQuality getRTCQuality();

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

@@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "configuration.h"
#ifndef NO_SCREEN
#include <OLEDDisplay.h>
#include "GPS.h"
@@ -31,8 +32,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "graphics/images.h"
#include "main.h"
#include "mesh-pb-constants.h"
#include "mesh/generated/deviceonly.pb.h"
#include "mesh/Channels.h"
#include "mesh/generated/deviceonly.pb.h"
#include "modules/TextMessageModule.h"
#include "sleep.h"
#include "target_specific.h"
@@ -93,7 +94,7 @@ static uint16_t displayWidth, displayHeight;
#define SCREEN_WIDTH displayWidth
#define SCREEN_HEIGHT displayHeight
#ifdef HAS_EINK
#if defined(HAS_EINK) || defined(ILI9341_DRIVER)
// The screen is bigger so use bigger fonts
#define FONT_SMALL ArialMT_Plain_16
#define FONT_MEDIUM ArialMT_Plain_24
@@ -162,21 +163,22 @@ static void drawOEMIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDi
// needs to be drawn relative to x and y
// draw centered icon left to right and centered above the one line of app text
display->drawXbm(x + (SCREEN_WIDTH - oemStore.oem_icon_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - oemStore.oem_icon_height) / 2 + 2,
oemStore.oem_icon_width, oemStore.oem_icon_height, (const uint8_t *)oemStore.oem_icon_bits.bytes);
display->drawXbm(x + (SCREEN_WIDTH - oemStore.oem_icon_width) / 2,
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - oemStore.oem_icon_height) / 2 + 2, oemStore.oem_icon_width,
oemStore.oem_icon_height, (const uint8_t *)oemStore.oem_icon_bits.bytes);
switch(oemStore.oem_font){
case 0:
display->setFont(FONT_SMALL);
switch (oemStore.oem_font) {
case 0:
display->setFont(FONT_SMALL);
break;
case 2:
display->setFont(FONT_LARGE);
case 2:
display->setFont(FONT_LARGE);
break;
default:
display->setFont(FONT_MEDIUM);
default:
display->setFont(FONT_MEDIUM);
break;
}
display->setTextAlignment(TEXT_ALIGN_LEFT);
const char *title = oemStore.oem_text;
display->drawString(x + getStringCenteredX(title), y + SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM, title);
@@ -351,8 +353,8 @@ static void drawCriticalFaultFrame(OLEDDisplay *display, OLEDDisplayUiState *sta
// Ignore messages orginating from phone (from the current node 0x0) unless range test or store and forward module are enabled
static bool shouldDrawMessage(const MeshPacket *packet)
{
return packet->from != 0 && !radioConfig.preferences.range_test_module_enabled &&
!radioConfig.preferences.store_forward_module_enabled;
return packet->from != 0 && !moduleConfig.range_test.enabled &&
!moduleConfig.store_forward.enabled;
}
/// Draw the last text message we received
@@ -466,7 +468,7 @@ static void drawNodes(OLEDDisplay *display, int16_t x, int16_t y, NodeStatus *no
// Draw GPS status summary
static void drawGPS(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus *gps)
{
if (radioConfig.preferences.fixed_position) {
if (config.position.fixed_position) {
// GPS coordinates are currently fixed
display->drawString(x - 1, y - 2, "Fixed GPS");
return;
@@ -505,10 +507,10 @@ static void drawGPS(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus
static void drawGPSAltitude(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus *gps)
{
String displayLine = "";
if (!gps->getIsConnected() && !radioConfig.preferences.fixed_position) {
if (!gps->getIsConnected() && !config.position.fixed_position) {
// displayLine = "No GPS Module";
// display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(displayLine))) / 2, y, displayLine);
} else if (!gps->getHasLock() && !radioConfig.preferences.fixed_position) {
} else if (!gps->getHasLock() && !config.position.fixed_position) {
// displayLine = "No GPS Lock";
// display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(displayLine))) / 2, y, displayLine);
} else {
@@ -521,32 +523,32 @@ static void drawGPSAltitude(OLEDDisplay *display, int16_t x, int16_t y, const GP
// Draw GPS status coordinates
static void drawGPScoordinates(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus *gps)
{
auto gpsFormat = radioConfig.preferences.gps_format;
auto gpsFormat = config.display.gps_format;
String displayLine = "";
if (!gps->getIsConnected() && !radioConfig.preferences.fixed_position) {
if (!gps->getIsConnected() && !config.position.fixed_position) {
displayLine = "No GPS Module";
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(displayLine))) / 2, y, displayLine);
} else if (!gps->getHasLock() && !radioConfig.preferences.fixed_position) {
} else if (!gps->getHasLock() && !config.position.fixed_position) {
displayLine = "No GPS Lock";
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(displayLine))) / 2, y, displayLine);
} else {
if (gpsFormat != GpsCoordinateFormat_GpsFormatDMS) {
if (gpsFormat != Config_DisplayConfig_GpsCoordinateFormat_GpsFormatDMS) {
char coordinateLine[22];
geoCoord.updateCoords(int32_t(gps->getLatitude()), int32_t(gps->getLongitude()), int32_t(gps->getAltitude()));
if (gpsFormat == GpsCoordinateFormat_GpsFormatDec) { // Decimal Degrees
if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_GpsFormatDec) { // Decimal Degrees
sprintf(coordinateLine, "%f %f", geoCoord.getLatitude() * 1e-7, geoCoord.getLongitude() * 1e-7);
} else if (gpsFormat == GpsCoordinateFormat_GpsFormatUTM) { // Universal Transverse Mercator
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_GpsFormatUTM) { // Universal Transverse Mercator
sprintf(coordinateLine, "%2i%1c %06u %07u", geoCoord.getUTMZone(), geoCoord.getUTMBand(),
geoCoord.getUTMEasting(), geoCoord.getUTMNorthing());
} else if (gpsFormat == GpsCoordinateFormat_GpsFormatMGRS) { // Military Grid Reference System
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_GpsFormatMGRS) { // Military Grid Reference System
sprintf(coordinateLine, "%2i%1c %1c%1c %05u %05u", geoCoord.getMGRSZone(), geoCoord.getMGRSBand(),
geoCoord.getMGRSEast100k(), geoCoord.getMGRSNorth100k(), geoCoord.getMGRSEasting(),
geoCoord.getMGRSNorthing());
} else if (gpsFormat == GpsCoordinateFormat_GpsFormatOLC) { // Open Location Code
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_GpsFormatOLC) { // Open Location Code
geoCoord.getOLCCode(coordinateLine);
} else if (gpsFormat == GpsCoordinateFormat_GpsFormatOSGR) { // Ordnance Survey Grid Reference
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_GpsFormatOSGR) { // Ordnance Survey Grid Reference
if (geoCoord.getOSGRE100k() == 'I' || geoCoord.getOSGRN100k() == 'I') // OSGR is only valid around the UK region
sprintf(coordinateLine, "%s", "Out of Boundary");
else
@@ -555,7 +557,7 @@ static void drawGPScoordinates(OLEDDisplay *display, int16_t x, int16_t y, const
}
// If fixed position, display text "Fixed GPS" alternating with the coordinates.
if (radioConfig.preferences.fixed_position) {
if (config.position.fixed_position) {
if ((millis() / 10000) % 2) {
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(coordinateLine))) / 2, y, coordinateLine);
} else {
@@ -816,7 +818,8 @@ void _screen_header()
#endif
// #ifdef RAK4630
// Screen::Screen(uint8_t address, int sda, int scl) : OSThread("Screen"), cmdQueue(32), dispdev(address, sda, scl), dispdev_oled(address, sda, scl), ui(&dispdev)
// Screen::Screen(uint8_t address, int sda, int scl) : OSThread("Screen"), cmdQueue(32), dispdev(address, sda, scl),
// dispdev_oled(address, sda, scl), ui(&dispdev)
// {
// address_found = address;
// cmdQueue.setReader(this);
@@ -976,7 +979,7 @@ int32_t Screen::runOnce()
}
// If we have an OEM Boot screen, toggle after 2,5 seconds
if(strlen(oemStore.oem_text) > 0){
if (strlen(oemStore.oem_text) > 0) {
static bool showingOEMBootScreen = true;
if (showingOEMBootScreen && (millis() > (2500 + serialSinceMsec))) {
DEBUG_MSG("Switch to OEM screen...\n");
@@ -991,7 +994,7 @@ int32_t Screen::runOnce()
}
#ifndef DISABLE_WELCOME_UNSET
if (showingNormalScreen && radioConfig.preferences.region == RegionCode_Unset) {
if (showingNormalScreen && config.lora.region == Config_LoRaConfig_RegionCode_Unset) {
setWelcomeFrames();
}
#endif
@@ -1064,8 +1067,8 @@ int32_t Screen::runOnce()
// standard screen switching is stopped.
if (showingNormalScreen) {
// standard screen loop handling here
if (radioConfig.preferences.auto_screen_carousel_secs > 0 &&
(millis() - lastScreenTransition) > (radioConfig.preferences.auto_screen_carousel_secs * 1000)) {
if (config.display.auto_screen_carousel_secs > 0 &&
(millis() - lastScreenTransition) > (config.display.auto_screen_carousel_secs * 1000)) {
DEBUG_MSG("LastScreenTransition exceeded %ums transitioning to next frame\n", (millis() - lastScreenTransition));
handleOnPress();
}
@@ -1340,8 +1343,8 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
#ifdef HAS_WIFI
const char *wifiName = radioConfig.preferences.wifi_ssid;
const char *wifiPsw = radioConfig.preferences.wifi_password;
const char *wifiName = config.wifi.ssid;
const char *wifiPsw = config.wifi.psk;
displayedNodeNum = 0; // Not currently showing a node pane
@@ -1352,7 +1355,7 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
if (isSoftAPForced()) {
display->drawString(x, y, String("WiFi: Software AP (Admin)"));
} else if (radioConfig.preferences.wifi_ap_mode) {
} else if (config.wifi.ap_mode) {
display->drawString(x, y, String("WiFi: Software AP"));
} else if (WiFi.status() != WL_CONNECTED) {
display->drawString(x, y, String("WiFi: Not Connected"));
@@ -1375,8 +1378,8 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
- WL_NO_SHIELD: assigned when no WiFi shield is present;
*/
if (WiFi.status() == WL_CONNECTED || isSoftAPForced() || radioConfig.preferences.wifi_ap_mode) {
if (radioConfig.preferences.wifi_ap_mode || isSoftAPForced()) {
if (WiFi.status() == WL_CONNECTED || isSoftAPForced() || config.wifi.ap_mode) {
if (config.wifi.ap_mode || isSoftAPForced()) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "IP: " + String(WiFi.softAPIP().toString().c_str()));
// Number of connections to the AP. Default max for the esp32 is 4
@@ -1468,7 +1471,7 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
}
} else {
if (radioConfig.preferences.wifi_ap_mode) {
if (config.wifi.ap_mode) {
if ((millis() / 10000) % 2) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "SSID: " + String(wifiName));
} else {
@@ -1515,22 +1518,31 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
auto mode = "";
if (channels.getPrimary().modem_config == 0) {
mode = "VLongSlow";
} else if (channels.getPrimary().modem_config == 1) {
mode = "LongSlow";
} else if (channels.getPrimary().modem_config == 2) {
mode = "LongFast";
} else if (channels.getPrimary().modem_config == 3) {
mode = "MidSlow";
} else if (channels.getPrimary().modem_config == 4) {
mode = "MidFast";
} else if (channels.getPrimary().modem_config == 5) {
mode = "ShortSlow";
} else if (channels.getPrimary().modem_config == 6) {
mode = "ShortFast";
} else {
switch (config.lora.modem_preset) {
case Config_LoRaConfig_ModemPreset_ShortSlow:
mode = "ShortS";
break;
case Config_LoRaConfig_ModemPreset_ShortFast:
mode = "ShortF";
break;
case Config_LoRaConfig_ModemPreset_MedSlow:
mode = "MedS";
break;
case Config_LoRaConfig_ModemPreset_MedFast:
mode = "MedF";
break;
case Config_LoRaConfig_ModemPreset_LongSlow:
mode = "LongS";
break;
case Config_LoRaConfig_ModemPreset_LongFast:
mode = "LongF";
break;
case Config_LoRaConfig_ModemPreset_VLongSlow:
mode = "VeryL";
break;
default:
mode = "Custom";
break;
}
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(mode), y, mode);
@@ -1557,7 +1569,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
else
uptime += String(seconds) + "s ";
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityFromNet);
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice);
if (rtc_sec > 0) {
long hms = rtc_sec % SEC_PER_DAY;
// hms += tz.tz_dsttime * SEC_PER_HOUR;
@@ -1583,7 +1595,8 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(chUtil), y + FONT_HEIGHT_SMALL * 1, chUtil);
// Line 3
if (radioConfig.preferences.gps_format != GpsCoordinateFormat_GpsFormatDMS) // if DMS then don't draw altitude
if (config.display.gps_format !=
Config_DisplayConfig_GpsCoordinateFormat_GpsFormatDMS) // if DMS then don't draw altitude
drawGPSAltitude(display, x, y + FONT_HEIGHT_SMALL * 2, gpsStatus);
// Line 4
@@ -1652,3 +1665,4 @@ int Screen::handleUIFrameEvent(const UIFrameEvent *event)
}
} // namespace graphics
#endif // NO_SCREEN

View File

@@ -1,6 +1,7 @@
#pragma once
#ifdef NO_SCREEN
#include "power.h"
namespace graphics
{
// Noop class for boards without screen.
@@ -15,6 +16,8 @@ class Screen
void adjustBrightness(){}
void doDeepSleep() {}
void forceDisplay() {}
void startBluetoothPinScreen(uint32_t pin) {}
void stopBluetoothPinScreen() {}
};
}
@@ -310,7 +313,7 @@ class Screen : public concurrency::OSThread
SH1106Wire dispdev;
#elif defined(USE_SSD1306)
SSD1306Wire dispdev;
#elif defined(ST7735_CS)
#elif defined(ST7735_CS) || defined(ILI9341_DRIVER)
TFTDisplay dispdev;
#elif defined(HAS_EINK)
EInkDisplay dispdev;

View File

@@ -1,6 +1,6 @@
#include "configuration.h"
#ifdef ST7735_CS
#if defined(ST7735_CS) || defined(ILI9341_DRIVER)
#include "SPILock.h"
#include "TFTDisplay.h"
#include <SPI.h>
@@ -10,7 +10,11 @@ static TFT_eSPI tft = TFT_eSPI(); // Invoke library, pins defined in User_Setup.
TFTDisplay::TFTDisplay(uint8_t address, int sda, int scl)
{
setGeometry(GEOMETRY_RAWMODE, 160, 80);
#ifdef SCREEN_ROTATE
setGeometry(GEOMETRY_RAWMODE, TFT_HEIGHT, TFT_WIDTH);
#else
setGeometry(GEOMETRY_RAWMODE, TFT_WIDTH, TFT_HEIGHT);
#endif
}
// Write the buffer to the display memory
@@ -20,12 +24,10 @@ void TFTDisplay::display(void)
// FIXME - only draw bits have changed (use backbuf similar to the other displays)
// tft.drawBitmap(0, 0, buffer, 128, 64, TFT_YELLOW, TFT_BLACK);
for (uint8_t y = 0; y < displayHeight; y++) {
for (uint8_t x = 0; x < displayWidth; x++) {
for (uint16_t y = 0; y < displayHeight; y++) {
for (uint16_t x = 0; x < displayWidth; x++) {
// get src pixel in the page based ordering the OLED lib uses FIXME, super inefficent
auto b = buffer[x + (y / 8) * displayWidth];
auto isset = b & (1 << (y & 7));
auto isset = buffer[x + (y / 8) * displayWidth] & (1 << (y & 7));
tft.drawPixel(x, y, isset ? TFT_WHITE : TFT_BLACK);
}
}
@@ -38,21 +40,34 @@ void TFTDisplay::sendCommand(uint8_t com)
// Drop all commands to device (we just update the buffer)
}
void TFTDisplay::setDetected(uint8_t detected)
{
(void)detected;
}
// Connect to the display
bool TFTDisplay::connect()
{
concurrency::LockGuard g(spiLock);
DEBUG_MSG("Doing TFT init\n");
#ifdef TFT_BL
digitalWrite(TFT_BL, HIGH);
pinMode(TFT_BL, OUTPUT);
#endif
#ifdef ST7735_BACKLIGHT_EN
digitalWrite(ST7735_BACKLIGHT_EN, HIGH);
pinMode(ST7735_BACKLIGHT_EN, OUTPUT);
#endif
tft.init();
#ifdef M5STACK
tft.setRotation(1); // M5Stack has the TFT in landscape
#else
tft.setRotation(3); // Orient horizontal and wide underneath the silkscreen name label
#endif
tft.fillScreen(TFT_BLACK);
// tft.drawRect(0, 0, 40, 10, TFT_PURPLE); // wide rectangle in upper left
return true;
}

View File

@@ -22,6 +22,12 @@ class TFTDisplay : public OLEDDisplay
// Write the buffer to the display memory
virtual void display(void) override;
/**
* shim to make the abstraction happy
*
*/
void setDetected(uint8_t detected);
protected:
// the header size of the buffer used, e.g. for the SPI command header

View File

@@ -1,17 +1,14 @@
#include "configuration.h"
#include "RotaryEncoderInterruptBase.h"
#include "configuration.h"
RotaryEncoderInterruptBase::RotaryEncoderInterruptBase(
const char *name) :
concurrency::OSThread(name)
RotaryEncoderInterruptBase::RotaryEncoderInterruptBase(const char *name) : concurrency::OSThread(name)
{
this->_originName = name;
}
void RotaryEncoderInterruptBase::init(
uint8_t pinA, uint8_t pinB, uint8_t pinPress,
char eventCw, char eventCcw, char eventPressed,
// std::function<void(void)> onIntA, std::function<void(void)> onIntB, std::function<void(void)> onIntPress) :
uint8_t pinA, uint8_t pinB, uint8_t pinPress, char eventCw, char eventCcw, char eventPressed,
// std::function<void(void)> onIntA, std::function<void(void)> onIntB, std::function<void(void)> onIntPress) :
void (*onIntA)(), void (*onIntB)(), void (*onIntPress)())
{
this->_pinA = pinA;
@@ -24,42 +21,34 @@ void RotaryEncoderInterruptBase::init(
pinMode(this->_pinA, INPUT_PULLUP);
pinMode(this->_pinB, INPUT_PULLUP);
// attachInterrupt(pinPress, onIntPress, RISING);
// attachInterrupt(pinPress, onIntPress, RISING);
attachInterrupt(pinPress, onIntPress, RISING);
attachInterrupt(this->_pinA, onIntA, CHANGE);
attachInterrupt(this->_pinB, onIntB, CHANGE);
this->rotaryLevelA = digitalRead(this->_pinA);
this->rotaryLevelB = digitalRead(this->_pinB);
DEBUG_MSG("Rotary initialized (%d, %d, %d)\n",
this->_pinA, this->_pinB, pinPress);
DEBUG_MSG("Rotary initialized (%d, %d, %d)\n", this->_pinA, this->_pinB, pinPress);
}
int32_t RotaryEncoderInterruptBase::runOnce()
{
InputEvent e;
e.inputEvent = InputEventChar_KEY_NONE;
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE;
e.source = this->_originName;
if (this->action == ROTARY_ACTION_PRESSED)
{
if (this->action == ROTARY_ACTION_PRESSED) {
DEBUG_MSG("Rotary event Press\n");
e.inputEvent = this->_eventPressed;
}
else if (this->action == ROTARY_ACTION_CW)
{
} else if (this->action == ROTARY_ACTION_CW) {
DEBUG_MSG("Rotary event CW\n");
e.inputEvent = this->_eventCw;
}
else if (this->action == ROTARY_ACTION_CCW)
{
} else if (this->action == ROTARY_ACTION_CCW) {
DEBUG_MSG("Rotary event CCW\n");
e.inputEvent = this->_eventCcw;
}
if (e.inputEvent != InputEventChar_KEY_NONE)
{
if (e.inputEvent != ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE) {
this->notifyObservers(&e);
}
@@ -68,7 +57,6 @@ int32_t RotaryEncoderInterruptBase::runOnce()
return 30000; // TODO: technically this can be MAX_INT
}
void RotaryEncoderInterruptBase::intPressHandler()
{
this->action = ROTARY_ACTION_PRESSED;
@@ -79,66 +67,47 @@ void RotaryEncoderInterruptBase::intAHandler()
{
// CW rotation (at least on most common rotary encoders)
int currentLevelA = digitalRead(this->_pinA);
if (this->rotaryLevelA == currentLevelA)
{
if (this->rotaryLevelA == currentLevelA) {
return;
}
this->rotaryLevelA = currentLevelA;
this->rotaryStateCCW = intHandler(
currentLevelA == HIGH,
this->rotaryLevelB,
ROTARY_ACTION_CCW,
this->rotaryStateCCW);
this->rotaryStateCCW = intHandler(currentLevelA == HIGH, this->rotaryLevelB, ROTARY_ACTION_CCW, this->rotaryStateCCW);
}
void RotaryEncoderInterruptBase::intBHandler()
{
// CW rotation (at least on most common rotary encoders)
int currentLevelB = digitalRead(this->_pinB);
if (this->rotaryLevelB == currentLevelB)
{
if (this->rotaryLevelB == currentLevelB) {
return;
}
this->rotaryLevelB = currentLevelB;
this->rotaryStateCW = intHandler(
currentLevelB == HIGH,
this->rotaryLevelA,
ROTARY_ACTION_CW,
this->rotaryStateCW);
this->rotaryStateCW = intHandler(currentLevelB == HIGH, this->rotaryLevelA, ROTARY_ACTION_CW, this->rotaryStateCW);
}
/**
* @brief Rotary action implementation.
* We assume, the following pin setup:
* A --||
* GND --||]========
* GND --||]========
* B --||
*
*
* @return The new state for rotary pin.
*/
RotaryEncoderInterruptBaseStateType RotaryEncoderInterruptBase::intHandler(
bool actualPinRaising,
int otherPinLevel,
RotaryEncoderInterruptBaseActionType action,
RotaryEncoderInterruptBaseStateType state)
RotaryEncoderInterruptBaseStateType RotaryEncoderInterruptBase::intHandler(bool actualPinRaising, int otherPinLevel,
RotaryEncoderInterruptBaseActionType action,
RotaryEncoderInterruptBaseStateType state)
{
RotaryEncoderInterruptBaseStateType newState =
state;
if (actualPinRaising && (otherPinLevel == LOW))
{
if (state == ROTARY_EVENT_CLEARED)
{
RotaryEncoderInterruptBaseStateType newState = state;
if (actualPinRaising && (otherPinLevel == LOW)) {
if (state == ROTARY_EVENT_CLEARED) {
newState = ROTARY_EVENT_OCCURRED;
if ((this->action != ROTARY_ACTION_PRESSED)
&& (this->action != action))
{
if ((this->action != ROTARY_ACTION_PRESSED) && (this->action != action)) {
this->action = action;
DEBUG_MSG("Rotary action\n");
}
}
}
else if (!actualPinRaising && (otherPinLevel == HIGH))
{
} else if (!actualPinRaising && (otherPinLevel == HIGH)) {
// Logic to prevent bouncing.
newState = ROTARY_EVENT_CLEARED;
}

View File

@@ -1,45 +1,28 @@
#pragma once
#include "SinglePortModule.h" // TODO: what header file to include?
#include "InputBroker.h"
#include "SinglePortModule.h" // TODO: what header file to include?
enum RotaryEncoderInterruptBaseStateType
{
ROTARY_EVENT_OCCURRED,
ROTARY_EVENT_CLEARED
};
enum RotaryEncoderInterruptBaseStateType { ROTARY_EVENT_OCCURRED, ROTARY_EVENT_CLEARED };
enum RotaryEncoderInterruptBaseActionType
{
ROTARY_ACTION_NONE,
ROTARY_ACTION_PRESSED,
ROTARY_ACTION_CW,
ROTARY_ACTION_CCW
};
enum RotaryEncoderInterruptBaseActionType { ROTARY_ACTION_NONE, ROTARY_ACTION_PRESSED, ROTARY_ACTION_CW, ROTARY_ACTION_CCW };
class RotaryEncoderInterruptBase :
public Observable<const InputEvent *>,
private concurrency::OSThread
class RotaryEncoderInterruptBase : public Observable<const InputEvent *>, private concurrency::OSThread
{
public:
explicit RotaryEncoderInterruptBase(
const char *name);
void init(
uint8_t pinA, uint8_t pinB, uint8_t pinPress,
char eventCw, char eventCcw, char eventPressed,
// std::function<void(void)> onIntA, std::function<void(void)> onIntB, std::function<void(void)> onIntPress);
void (*onIntA)(), void (*onIntB)(), void (*onIntPress)());
explicit RotaryEncoderInterruptBase(const char *name);
void init(uint8_t pinA, uint8_t pinB, uint8_t pinPress, char eventCw, char eventCcw, char eventPressed,
// std::function<void(void)> onIntA, std::function<void(void)> onIntB, std::function<void(void)> onIntPress);
void (*onIntA)(), void (*onIntB)(), void (*onIntPress)());
void intPressHandler();
void intAHandler();
void intBHandler();
protected:
virtual int32_t runOnce() override;
RotaryEncoderInterruptBaseStateType intHandler(
bool actualPinRaising,
int otherPinLevel,
RotaryEncoderInterruptBaseActionType action,
RotaryEncoderInterruptBaseStateType state);
RotaryEncoderInterruptBaseStateType intHandler(bool actualPinRaising, int otherPinLevel,
RotaryEncoderInterruptBaseActionType action,
RotaryEncoderInterruptBaseStateType state);
volatile RotaryEncoderInterruptBaseStateType rotaryStateCW = ROTARY_EVENT_CLEARED;
volatile RotaryEncoderInterruptBaseStateType rotaryStateCCW = ROTARY_EVENT_CLEARED;
@@ -50,8 +33,8 @@ class RotaryEncoderInterruptBase :
private:
uint8_t _pinA = 0;
uint8_t _pinB = 0;
char _eventCw = InputEventChar_KEY_NONE;
char _eventCcw = InputEventChar_KEY_NONE;
char _eventPressed = InputEventChar_KEY_NONE;
char _eventCw = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE;
char _eventCcw = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE;
char _eventPressed = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE;
const char *_originName;
};

View File

@@ -3,37 +3,26 @@
RotaryEncoderInterruptImpl1 *rotaryEncoderInterruptImpl1;
RotaryEncoderInterruptImpl1::RotaryEncoderInterruptImpl1() :
RotaryEncoderInterruptBase(
"rotEnc1")
{
}
RotaryEncoderInterruptImpl1::RotaryEncoderInterruptImpl1() : RotaryEncoderInterruptBase("rotEnc1") {}
void RotaryEncoderInterruptImpl1::init()
{
if (!radioConfig.preferences.rotary1_enabled)
{
if (!moduleConfig.canned_message.rotary1_enabled) {
// Input device is disabled.
return;
}
uint8_t pinA = radioConfig.preferences.inputbroker_pin_a;
uint8_t pinB = radioConfig.preferences.inputbroker_pin_b;
uint8_t pinPress = radioConfig.preferences.inputbroker_pin_press;
char eventCw =
static_cast<char>(radioConfig.preferences.inputbroker_event_cw);
char eventCcw =
static_cast<char>(radioConfig.preferences.inputbroker_event_ccw);
char eventPressed =
static_cast<char>(radioConfig.preferences.inputbroker_event_press);
uint8_t pinA = moduleConfig.canned_message.inputbroker_pin_a;
uint8_t pinB = moduleConfig.canned_message.inputbroker_pin_b;
uint8_t pinPress = moduleConfig.canned_message.inputbroker_pin_press;
char eventCw = static_cast<char>(moduleConfig.canned_message.inputbroker_event_cw);
char eventCcw = static_cast<char>(moduleConfig.canned_message.inputbroker_event_ccw);
char eventPressed = static_cast<char>(moduleConfig.canned_message.inputbroker_event_press);
//radioConfig.preferences.ext_notification_module_output
RotaryEncoderInterruptBase::init(
pinA, pinB, pinPress,
eventCw, eventCcw, eventPressed,
RotaryEncoderInterruptImpl1::handleIntA,
RotaryEncoderInterruptImpl1::handleIntB,
RotaryEncoderInterruptImpl1::handleIntPressed);
// moduleConfig.canned_message.ext_notification_module_output
RotaryEncoderInterruptBase::init(pinA, pinB, pinPress, eventCw, eventCcw, eventPressed,
RotaryEncoderInterruptImpl1::handleIntA, RotaryEncoderInterruptImpl1::handleIntB,
RotaryEncoderInterruptImpl1::handleIntPressed);
inputBroker->registerSource(this);
}

View File

@@ -1,18 +1,14 @@
#pragma once
#include "SinglePortModule.h" // TODO: what header file to include?
#include "InputBroker.h"
#include "SinglePortModule.h" // TODO: what header file to include?
class UpDownInterruptBase :
public Observable<const InputEvent *>
class UpDownInterruptBase : public Observable<const InputEvent *>
{
public:
explicit UpDownInterruptBase(
const char *name);
void init(
uint8_t pinDown, uint8_t pinUp, uint8_t pinPress,
char eventDown, char eventUp, char eventPressed,
void (*onIntDown)(), void (*onIntUp)(), void (*onIntPress)());
explicit UpDownInterruptBase(const char *name);
void init(uint8_t pinDown, uint8_t pinUp, uint8_t pinPress, char eventDown, char eventUp, char eventPressed,
void (*onIntDown)(), void (*onIntUp)(), void (*onIntPress)());
void intPressHandler();
void intDownHandler();
void intUpHandler();
@@ -20,8 +16,8 @@ class UpDownInterruptBase :
private:
uint8_t _pinDown = 0;
uint8_t _pinUp = 0;
char _eventDown = InputEventChar_KEY_NONE;
char _eventUp = InputEventChar_KEY_NONE;
char _eventPressed = InputEventChar_KEY_NONE;
char _eventDown = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE;
char _eventUp = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE;
char _eventPressed = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE;
const char *_originName;
};

View File

@@ -3,38 +3,26 @@
UpDownInterruptImpl1 *upDownInterruptImpl1;
UpDownInterruptImpl1::UpDownInterruptImpl1() :
UpDownInterruptBase(
"upDown1")
{
}
UpDownInterruptImpl1::UpDownInterruptImpl1() : UpDownInterruptBase("upDown1") {}
void UpDownInterruptImpl1::init()
{
if (!radioConfig.preferences.updown1_enabled)
{
if (!moduleConfig.canned_message.updown1_enabled) {
// Input device is disabled.
return;
}
uint8_t pinUp = radioConfig.preferences.inputbroker_pin_a;
uint8_t pinDown = radioConfig.preferences.inputbroker_pin_b;
uint8_t pinPress = radioConfig.preferences.inputbroker_pin_press;
uint8_t pinUp = moduleConfig.canned_message.inputbroker_pin_a;
uint8_t pinDown = moduleConfig.canned_message.inputbroker_pin_b;
uint8_t pinPress = moduleConfig.canned_message.inputbroker_pin_press;
char eventDown =
static_cast<char>(InputEventChar_KEY_DOWN);
char eventUp =
static_cast<char>(InputEventChar_KEY_UP);
char eventPressed =
static_cast<char>(InputEventChar_KEY_SELECT);
char eventDown = static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_KEY_DOWN);
char eventUp = static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_KEY_UP);
char eventPressed = static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_KEY_SELECT);
UpDownInterruptBase::init(
pinDown, pinUp, pinPress,
eventDown, eventUp, eventPressed,
UpDownInterruptImpl1::handleIntDown,
UpDownInterruptImpl1::handleIntUp,
UpDownInterruptImpl1::handleIntPressed);
UpDownInterruptBase::init(pinDown, pinUp, pinPress, eventDown, eventUp, eventPressed, UpDownInterruptImpl1::handleIntDown,
UpDownInterruptImpl1::handleIntUp, UpDownInterruptImpl1::handleIntPressed);
inputBroker->registerSource(this);
}

View File

@@ -1,5 +1,5 @@
#include "configuration.h"
#include "kbI2cBase.h"
#include "configuration.h"
#include <Wire.h>
KbI2cBase::KbI2cBase(const char *name) : concurrency::OSThread(name)
@@ -10,40 +10,39 @@ KbI2cBase::KbI2cBase(const char *name) : concurrency::OSThread(name)
int32_t KbI2cBase::runOnce()
{
InputEvent e;
e.inputEvent = InputEventChar_KEY_NONE;
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE;
e.source = this->_originName;
Wire.requestFrom(CARDKB_ADDR, 1);
while(Wire.available()) {
while (Wire.available()) {
char c = Wire.read();
switch(c) {
switch (c) {
case 0x1b: // ESC
e.inputEvent = InputEventChar_KEY_CANCEL;
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_CANCEL;
break;
case 0x08: // Back
e.inputEvent = InputEventChar_KEY_BACK;
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_BACK;
break;
case 0xb5: // Up
e.inputEvent = InputEventChar_KEY_UP;
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_UP;
break;
case 0xb6: // Down
e.inputEvent = InputEventChar_KEY_DOWN;
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_DOWN;
break;
case 0xb4: // Left
e.inputEvent = InputEventChar_KEY_LEFT;
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_LEFT;
break;
case 0xb7: // Right
e.inputEvent = InputEventChar_KEY_RIGHT;
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_RIGHT;
break;
case 0x0d: // Enter
e.inputEvent = InputEventChar_KEY_SELECT;
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_KEY_SELECT;
break;
}
}
if (e.inputEvent != InputEventChar_KEY_NONE)
{
if (e.inputEvent != ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE) {
this->notifyObservers(&e);
}
return 500;

View File

@@ -1,4 +1,3 @@
#include "configuration.h"
#include "GPS.h"
#include "MeshRadio.h"
#include "MeshService.h"
@@ -6,6 +5,7 @@
#include "PowerFSM.h"
#include "airtime.h"
#include "buzz.h"
#include "configuration.h"
#include "error.h"
#include "power.h"
// #include "rom/rtc.h"
@@ -17,28 +17,28 @@
#include "SPILock.h"
#include "concurrency/OSThread.h"
#include "concurrency/Periodic.h"
#include "debug/axpDebug.h"
#include "debug/einkScan.h"
#include "debug/i2cScan.h"
#include "graphics/Screen.h"
#include "main.h"
#include "modules/Modules.h"
#include "sleep.h"
#include "shutdown.h"
#include "sleep.h"
#include "target_specific.h"
#include "debug/i2cScan.h"
#include "debug/einkScan.h"
#include "debug/axpDebug.h"
#include <Wire.h>
// #include <driver/rtc_io.h>
#include "mesh/http/WiFiAPClient.h"
#ifndef NO_ESP32
#include "mesh/http/WebServer.h"
#include "mesh/http/WebServer.h"
#ifdef USE_NEW_ESP32_BLUETOOTH
#include "esp32/ESP32Bluetooth.h"
#else
#include "nimble/BluetoothUtil.h"
#endif
#ifdef USE_NEW_ESP32_BLUETOOTH
#include "esp32/ESP32Bluetooth.h"
#else
#include "nimble/BluetoothUtil.h"
#endif
#endif
@@ -47,10 +47,10 @@
#include "mqtt/MQTT.h"
#endif
#include "LLCC68Interface.h"
#include "RF95Interface.h"
#include "SX1262Interface.h"
#include "SX1268Interface.h"
#include "LLCC68Interface.h"
#include "ButtonThread.h"
#include "PowerFSMThread.h"
@@ -75,16 +75,24 @@ uint8_t screen_model;
// The I2C address of the cardkb or RAK14004 (if found)
uint8_t cardkb_found;
// 0x02 for RAK14004 and 0x00 for cardkb
uint8_t kb_model;
// The I2C address of the Faces Keyboard (if found)
uint8_t faceskb_found;
// The I2C address of the RTC Module (if found)
uint8_t rtc_found;
bool eink_found = true;
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()
@@ -93,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) && (strcmp(owner.short_name, name) != 0)) {
sprintf(name, "%s_%02x%02x", owner.short_name, dmac[4], dmac[5]);
} else {
sprintf(name, "Meshtastic_%02x%02x", dmac[4], dmac[5]);
}
return name;
}
@@ -123,7 +137,8 @@ RadioInterface *rIf = NULL;
/**
* Some platforms (nrf52) might provide an alterate version that supresses calling delay from sleep.
*/
__attribute__ ((weak, noinline)) bool loopCanSleep() {
__attribute__((weak, noinline)) bool loopCanSleep()
{
return true;
}
@@ -142,17 +157,23 @@ void setup()
#endif
#ifdef DEBUG_PORT
if (!radioConfig.preferences.serial_disabled) {
if (!config.device.serial_disabled) {
consoleInit(); // Set serial baud rate and init our mesh console
}
#endif
serialSinceMsec = millis();
DEBUG_MSG("\n\n//\\ E S H T /\\ S T / C\n\n");
initDeepSleep();
// Testing this fix für erratic T-Echo boot behaviour
#if defined(TTGO_T_ECHO) && defined(PIN_EINK_PWR_ON)
pinMode(PIN_EINK_PWR_ON, OUTPUT);
digitalWrite(PIN_EINK_PWR_ON, HIGH);
#endif
#ifdef VEXT_ENABLE
pinMode(VEXT_ENABLE, OUTPUT);
digitalWrite(VEXT_ENABLE, 0); // turn on the display power
@@ -192,7 +213,7 @@ void setup()
fsInit();
//router = new DSRRouter();
// router = new DSRRouter();
router = new ReliableRouter();
#ifdef I2C_SDA
@@ -285,7 +306,7 @@ void setup()
// Don't call screen setup until after nodedb is setup (because we need
// the current region name)
#if defined(ST7735_CS) || defined(HAS_EINK)
#if defined(ST7735_CS) || defined(HAS_EINK) || defined(ILI9341_DRIVER)
screen->setup();
#else
if (screen_found)
@@ -298,6 +319,7 @@ void setup()
// ONCE we will factory reset the GPS for bug #327
if (gps && !devicestate.did_gps_reset) {
DEBUG_MSG("GPS FactoryReset requested\n");
if (gps->factoryReset()) { // If we don't succeed try again next time
devicestate.did_gps_reset = true;
nodeDB.saveToDisk();
@@ -398,14 +420,12 @@ void setup()
if (!rIf)
RECORD_CRITICALERROR(CriticalErrorCode_NoRadio);
else{
else {
router->addInterface(rIf);
// Calculate and save the bit rate to myNodeInfo
// TODO: This needs to be added what ever method changes the channel from the phone.
myNodeInfo.bitrate = (float(Constants_DATA_PAYLOAD_LEN) /
(float(rIf->getPacketTime(Constants_DATA_PAYLOAD_LEN)))
) * 1000;
myNodeInfo.bitrate = (float(Constants_DATA_PAYLOAD_LEN) / (float(rIf->getPacketTime(Constants_DATA_PAYLOAD_LEN)))) * 1000;
DEBUG_MSG("myNodeInfo.bitrate = %f bytes / sec\n", myNodeInfo.bitrate);
}
@@ -417,7 +437,7 @@ void setup()
setCPUFast(false); // 80MHz is fine for our slow peripherals
}
uint32_t rebootAtMsec; // If not zero we will reboot at this time (used to reboot shortly after the update completes)
uint32_t rebootAtMsec; // If not zero we will reboot at this time (used to reboot shortly after the update completes)
uint32_t shutdownAtMsec; // If not zero we will shutdown at this time (used to shutdown from python or mobile client)
// If a thread does something that might need for it to be rescheduled ASAP it can set this flag

View File

@@ -1,20 +1,26 @@
#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;
extern uint8_t cardkb_found;
extern uint8_t kb_model;
extern uint8_t faceskb_found;
extern uint8_t rtc_found;
extern bool eink_found;
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

@@ -1,7 +1,7 @@
#include "configuration.h"
#include "Channels.h"
#include "CryptoEngine.h"
#include "NodeDB.h"
#include "configuration.h"
#include <assert.h>
@@ -83,10 +83,11 @@ void Channels::initDefaultChannel(ChannelIndex chIndex)
{
Channel &ch = getByIndex(chIndex);
ChannelSettings &channelSettings = ch.settings;
Config_LoRaConfig &loraConfig = config.lora;
channelSettings.modem_config = ChannelSettings_ModemConfig_LongFast; // Default to Long Range & Fast
loraConfig.modem_preset = Config_LoRaConfig_ModemPreset_LongFast; // Default to Long Range & Fast
channelSettings.tx_power = 0; // default
loraConfig.tx_power = 0; // default
uint8_t defaultpskIndex = 1;
channelSettings.psk.bytes[0] = defaultpskIndex;
channelSettings.psk.size = 1;
@@ -206,33 +207,33 @@ const char *Channels::getName(size_t chIndex)
const ChannelSettings &channelSettings = getByIndex(chIndex).settings;
const char *channelName = channelSettings.name;
if (!*channelName) { // emptystring
// Per mesh.proto spec, if bandwidth is specified we must ignore modemConfig enum, we assume that in that case
// Per mesh.proto spec, if bandwidth is specified we must ignore modemPreset enum, we assume that in that case
// the app fucked up and forgot to set channelSettings.name
if (channelSettings.bandwidth != 0)
channelName = "Unset";
if (config.lora.bandwidth != 0)
channelName = "Custom";
else
switch (channelSettings.modem_config) {
case ChannelSettings_ModemConfig_ShortSlow:
channelName = "ShortSlow";
switch (config.lora.modem_preset) {
case Config_LoRaConfig_ModemPreset_ShortSlow:
channelName = "ShortS";
break;
case ChannelSettings_ModemConfig_ShortFast:
channelName = "ShortFast";
case Config_LoRaConfig_ModemPreset_ShortFast:
channelName = "ShortF";
break;
case ChannelSettings_ModemConfig_MidSlow:
channelName = "MediumSlow";
case Config_LoRaConfig_ModemPreset_MedSlow:
channelName = "MedS";
break;
case ChannelSettings_ModemConfig_MidFast:
channelName = "MediumFast";
case Config_LoRaConfig_ModemPreset_MedFast:
channelName = "MedF";
break;
case ChannelSettings_ModemConfig_LongFast:
channelName = "LongFast";
case Config_LoRaConfig_ModemPreset_LongSlow:
channelName = "LongS";
break;
case ChannelSettings_ModemConfig_LongSlow:
channelName = "LongSlow";
case Config_LoRaConfig_ModemPreset_LongFast:
channelName = "LongF";
break;
case ChannelSettings_ModemConfig_VLongSlow:
channelName = "VLongSlow";
case Config_LoRaConfig_ModemPreset_VLongSlow:
channelName = "VeryL";
break;
default:
channelName = "Invalid";

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

@@ -32,7 +32,7 @@ void FloodingRouter::sniffReceived(const MeshPacket *p, const Routing *c)
if ((p->to == NODENUM_BROADCAST) && (p->hop_limit > 0) && (getFrom(p) != getNodeNum())) {
if (p->id != 0) {
if (radioConfig.preferences.role != Role_ClientMute) {
if (config.device.role != Config_DeviceConfig_Role_ClientMute) {
MeshPacket *tosend = packetPool.allocCopy(*p); // keep a copy because we will be sending it
tosend->hop_limit--; // bump down the hop count

View File

@@ -7,7 +7,7 @@
// Map from old region names to new region enums
struct RegionInfo {
RegionCode code;
Config_LoRaConfig_RegionCode code;
float freqStart;
float freqEnd;
float dutyCycle;

View File

@@ -71,17 +71,7 @@ int MeshService::handleFromRadio(const MeshPacket *mp)
printPacket("Forwarding to phone", mp);
nodeDB.updateFrom(*mp); // update our DB state based off sniffing every RX packet from the radio
fromNum++;
if (toPhoneQueue.numFree() == 0) {
DEBUG_MSG("NOTE: tophone queue is full, discarding oldest\n");
MeshPacket *d = toPhoneQueue.dequeuePtr(0);
if (d)
releaseToPool(d);
}
MeshPacket *copied = packetPool.allocCopy(*mp);
assert(toPhoneQueue.enqueue(copied, 0)); // FIXME, instead of failing for full queue, delete the oldest mssages
sendToPhone((MeshPacket *)mp);
return 0;
}
@@ -161,12 +151,16 @@ bool MeshService::cancelSending(PacketId id)
return router->cancelSending(nodeDB.getNodeNum(), id);
}
void MeshService::sendToMesh(MeshPacket *p, RxSource src)
void MeshService::sendToMesh(MeshPacket *p, RxSource src, bool ccToPhone)
{
nodeDB.updateFrom(*p); // update our local DB for this packet (because phone might have sent position packets etc...)
// Note: We might return !OK if our fifo was full, at that point the only option we have is to drop it
router->sendLocal(p, src);
if (ccToPhone) {
sendToPhone(p);
}
}
void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
@@ -187,6 +181,21 @@ void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
}
}
void MeshService::sendToPhone(MeshPacket *p)
{
if (toPhoneQueue.numFree() == 0) {
DEBUG_MSG("NOTE: tophone queue is full, discarding oldest\n");
MeshPacket *d = toPhoneQueue.dequeuePtr(0);
if (d)
releaseToPool(d);
}
MeshPacket *copied = packetPool.allocCopy(*p);
perhapsDecode(copied);
assert(toPhoneQueue.enqueue(copied, 0)); // FIXME, instead of failing for full queue, delete the oldest mssages
fromNum++;
}
NodeInfo *MeshService::refreshMyNodeInfo()
{
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
@@ -227,7 +236,7 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
#ifdef GPS_EXTRAVERBOSE
DEBUG_MSG("onGPSchanged() - lost validLocation\n");
#endif
if (radioConfig.preferences.fixed_position) {
if (config.position.fixed_position) {
DEBUG_MSG("WARNING: Using fixed position\n");
pos = node->position;
}
@@ -239,8 +248,8 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
pos.time = getValidTime(RTCQualityGPS);
// In debug logs, identify position by @timestamp:stage (stage 4 = nodeDB)
DEBUG_MSG("onGPSChanged() pos@%x, time=%u, lat=%d, lon=%d, alt=%d\n",
pos.pos_timestamp, pos.time, pos.latitude_i, pos.longitude_i, pos.altitude);
DEBUG_MSG("onGPSChanged() pos@%x, time=%u, lat=%d, lon=%d, alt=%d\n", pos.pos_timestamp, pos.time, pos.latitude_i,
pos.longitude_i, pos.altitude);
// Update our current position in the local DB
nodeDB.updatePosition(nodeDB.getNodeNum(), pos, RX_SRC_LOCAL);

View File

@@ -75,7 +75,7 @@ class MeshService
/// Send a packet into the mesh - note p must have been allocated from packetPool. We will return it to that pool after
/// sending. This is the ONLY function you should use for sending messages into the mesh, because it also updates the nodedb
/// cache
void sendToMesh(MeshPacket *p, RxSource src = RX_SRC_LOCAL);
void sendToMesh(MeshPacket *p, RxSource src = RX_SRC_LOCAL, bool ccToPhone = false);
/** Attempt to cancel a previously sent packet from this _local_ node. Returns true if a packet was found we could cancel */
bool cancelSending(PacketId id);
@@ -83,6 +83,9 @@ class MeshService
/// Pull the latest power and time info into my nodeinfo
NodeInfo *refreshMyNodeInfo();
/// Send a packet to the phone
void sendToPhone(MeshPacket *p);
private:
/// Called when our gps position has changed - updates nodedb and sends Location message out into the mesh
/// returns 0 to allow futher processing

View File

@@ -34,7 +34,8 @@ NodeDB nodeDB;
// we have plenty of ram so statically alloc this tempbuf (for now)
EXT_RAM_ATTR DeviceState devicestate;
MyNodeInfo &myNodeInfo = devicestate.my_node;
RadioConfig radioConfig;
LocalConfig config;
LocalModuleConfig moduleConfig;
ChannelFile channelFile;
/** The current change # for radio settings. Starts at 0 on boot and any time the radio settings
@@ -47,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
@@ -86,21 +87,20 @@ bool NodeDB::resetRadioConfig()
radioGeneration++;
radioConfig.has_preferences = true;
if (radioConfig.preferences.factory_reset) {
// 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);
@@ -125,11 +125,11 @@ bool NodeDB::resetRadioConfig()
DEBUG_MSG("***** DEVELOPMENT MODE - DO NOT RELEASE *****\n");
// Sleep quite frequently to stress test the BLE comms, broadcast position every 6 mins
radioConfig.preferences.screen_on_secs = 10;
radioConfig.preferences.wait_bluetooth_secs = 10;
radioConfig.preferences.position_broadcast_secs = 6 * 60;
radioConfig.preferences.ls_secs = 60;
radioConfig.preferences.region = RegionCode_TW;
config.display.screen_on_secs = 10;
config.power.wait_bluetooth_secs = 10;
config.position.position_broadcast_secs = 6 * 60;
config.power.ls_secs = 60;
config.lora.region = Config_LoRaConfig_RegionCode_TW;
// Enter super deep sleep soon and stay there not very long
// radioConfig.preferences.mesh_sds_timeout_secs = 10;
@@ -142,30 +142,48 @@ bool NodeDB::resetRadioConfig()
return didFactoryReset;
}
void NodeDB::installDefaultRadioConfig()
void NodeDB::installDefaultConfig()
{
memset(&radioConfig, 0, sizeof(radioConfig));
radioConfig.has_preferences = true;
memset(&config, 0, sizeof(LocalConfig));
config.version = DEVICESTATE_CUR_VER;
config.has_device = true;
config.has_display = true;
config.has_lora = true;
config.has_position = true;
config.has_power = true;
config.has_wifi = true;
config.lora.region = Config_LoRaConfig_RegionCode_Unset;
config.lora.modem_preset = Config_LoRaConfig_ModemPreset_LongFast;
resetRadioConfig();
strncpy(config.device.ntp_server, "0.pool.ntp.org", 32);
// for backward compat, default position flags are ALT+MSL
config.position.position_flags =
(Config_PositionConfig_PositionFlags_POS_ALTITUDE | Config_PositionConfig_PositionFlags_POS_ALT_MSL);
}
// for backward compat, default position flags are BAT+ALT+MSL (0x23 = 35)
radioConfig.preferences.position_flags = (PositionFlags_POS_BATTERY |
PositionFlags_POS_ALTITUDE | PositionFlags_POS_ALT_MSL);
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;
moduleConfig.has_range_test = true;
moduleConfig.has_serial = true;
moduleConfig.has_store_forward = true;
moduleConfig.has_telemetry = true;
}
void NodeDB::installDefaultChannels()
{
memset(&channelFile, 0, sizeof(channelFile));
memset(&channelFile, 0, sizeof(ChannelFile));
channelFile.version = DEVICESTATE_CUR_VER;
}
void NodeDB::installDefaultDeviceState()
{
// We try to preserve the region setting because it will really bum users out if we discard it
String oldRegion = myNodeInfo.region;
RegionCode oldRegionCode = radioConfig.preferences.region;
memset(&devicestate, 0, sizeof(devicestate));
memset(&devicestate, 0, sizeof(DeviceState));
*numNodes = 0; // Forget node DB
@@ -186,20 +204,14 @@ 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));
// Restore region if possible
if (oldRegionCode != RegionCode_Unset)
radioConfig.preferences.region = oldRegionCode;
if (oldRegion.length()) // If the old style region was set, try to keep it up-to-date
strcpy(myNodeInfo.region, oldRegion.c_str());
installDefaultChannels();
installDefaultRadioConfig();
installDefaultConfig();
}
void NodeDB::init()
@@ -241,14 +253,14 @@ void NodeDB::init()
DEBUG_MSG("Number of Device Reboots: %d\n", myNodeInfo.reboot_count);
/* The ESP32 has a wifi radio. This will need to be modified at some point so
* the test isn't so simplistic.
*/
* the test isn't so simplistic.
*/
myNodeInfo.has_wifi = true;
#endif
resetRadioConfig(); // If bogus settings got saved, then fix them
DEBUG_MSG("region=%d, NODENUM=0x%x, dbsize=%d\n", radioConfig.preferences.region, myNodeInfo.my_node_num, *numNodes);
DEBUG_MSG("region=%d, NODENUM=0x%x, dbsize=%d\n", config.lora.region, myNodeInfo.my_node_num, *numNodes);
}
// We reserve a few nodenums for future use
@@ -279,18 +291,19 @@ void NodeDB::pickNewNodeNum()
}
static const char *preffile = "/prefs/db.proto";
static const char *radiofile = "/prefs/radio.proto";
static const char *configfile = "/prefs/config.proto";
static const char *moduleConfigfile = "/prefs/module.proto";
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};
@@ -323,29 +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(radiofile, RadioConfig_size, sizeof(RadioConfig), RadioConfig_fields, &radioConfig)) {
installDefaultRadioConfig(); // Our in RAM copy might now be corrupt
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};
@@ -359,7 +409,7 @@ bool saveProto(const char *filename, size_t protoSize, size_t objSize, const pb_
f.close();
// brief window of risk here ;-)
if (!FSCom.remove(filename))
if (FSCom.exists(filename) && !FSCom.remove(filename))
DEBUG_MSG("Warning: Can't remove old pref file\n");
if (!FSCom.rename(filenameTmp.c_str(), filename))
DEBUG_MSG("Error: can't rename new pref file\n");
@@ -389,7 +439,25 @@ void NodeDB::saveToDisk()
FSCom.mkdir("/prefs");
#endif
saveProto(preffile, DeviceState_size, sizeof(devicestate), DeviceState_fields, &devicestate);
saveProto(radiofile, RadioConfig_size, sizeof(RadioConfig), RadioConfig_fields, &radioConfig);
// save all config segments
config.has_device = true;
config.has_display = true;
config.has_lora = true;
config.has_position = true;
config.has_power = true;
config.has_wifi = true;
saveProto(configfile, LocalConfig_size, sizeof(LocalConfig), LocalConfig_fields, &config);
moduleConfig.has_canned_message = true;
moduleConfig.has_external_notification = true;
moduleConfig.has_mqtt = true;
moduleConfig.has_range_test = true;
moduleConfig.has_serial = true;
moduleConfig.has_store_forward = true;
moduleConfig.has_telemetry = true;
saveProto(moduleConfigfile, LocalModuleConfig_size, sizeof(LocalModuleConfig), LocalModuleConfig_fields, &moduleConfig);
saveChannelsToDisk();
} else {
@@ -417,7 +485,7 @@ uint32_t sinceLastSeen(const NodeInfo *n)
return delta;
}
#define NUM_ONLINE_SECS (60 & 60 * 2) // 2 hrs to consider someone offline
#define NUM_ONLINE_SECS (60 * 60 * 2) // 2 hrs to consider someone offline
size_t NodeDB::getNumOnlineNodes()
{
@@ -444,12 +512,11 @@ void NodeDB::updatePosition(uint32_t nodeId, const Position &p, RxSource src)
if (src == RX_SRC_LOCAL) {
// Local packet, fully authoritative
DEBUG_MSG("updatePosition LOCAL pos@%x, time=%u, latI=%d, lonI=%d, alt=%d\n",
p.pos_timestamp, p.time, p.latitude_i, p.longitude_i, p.altitude);
DEBUG_MSG("updatePosition LOCAL pos@%x, time=%u, latI=%d, lonI=%d, alt=%d\n", p.pos_timestamp, p.time, p.latitude_i,
p.longitude_i, p.altitude);
info->position = p;
} else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.pos_timestamp &&
!p.location_source) {
} else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.pos_timestamp && !p.location_source) {
// FIXME SPECIAL TIME SETTING PACKET FROM EUD TO RADIO
// (stop-gap fix for issue #900)
DEBUG_MSG("updatePosition SPECIAL time setting time=%u\n", p.time);
@@ -461,8 +528,7 @@ void NodeDB::updatePosition(uint32_t nodeId, const Position &p, RxSource src)
// recorded based on the packet rxTime
//
// FIXME perhaps handle RX_SRC_USER separately?
DEBUG_MSG("updatePosition REMOTE node=0x%x time=%u, latI=%d, lonI=%d\n",
nodeId, p.time, p.latitude_i, p.longitude_i);
DEBUG_MSG("updatePosition REMOTE node=0x%x time=%u, latI=%d, lonI=%d\n", nodeId, p.time, p.latitude_i, p.longitude_i);
// First, back up fields that we want to protect from overwrite
uint32_t tmp_time = info->position.time;
@@ -471,7 +537,7 @@ void NodeDB::updatePosition(uint32_t nodeId, const Position &p, RxSource src)
info->position = p;
// Last, restore any fields that may have been overwritten
if (! info->position.time)
if (!info->position.time)
info->position.time = tmp_time;
}
info->has_position = true;
@@ -479,7 +545,6 @@ void NodeDB::updatePosition(uint32_t nodeId, const Position &p, RxSource src)
notifyObservers(true); // Force an update whether or not our node counts have changed
}
/** Update telemetry info for this node based on received metrics
* We only care about device telemetry here
*/
@@ -591,7 +656,7 @@ void recordCriticalError(CriticalErrorCode code, uint32_t address, const char *f
// Print error to screen and serial port
String lcd = String("Critical error ") + code + "!\n";
screen->print(lcd.c_str());
if(filename)
if (filename)
DEBUG_MSG("NOTE! Recording critical error %d at %s:%lx\n", code, filename, address);
else
DEBUG_MSG("NOTE! Recording critical error %d, address=%lx\n", code, address);

View File

@@ -11,7 +11,8 @@
extern DeviceState devicestate;
extern ChannelFile channelFile;
extern MyNodeInfo &myNodeInfo;
extern RadioConfig radioConfig;
extern LocalConfig config;
extern LocalModuleConfig moduleConfig;
extern User &owner;
/// Given a node, return how many seconds in the past (vs now) that we last heard from it
@@ -63,7 +64,7 @@ class NodeDB
/** Update telemetry info for this node based on received metrics
*/
void updateTelemetry(uint32_t nodeId, const Telemetry &t, RxSource src = RX_SRC_RADIO);
void updateTelemetry(uint32_t nodeId, const Telemetry &t, RxSource src = RX_SRC_RADIO);
/** Update user info for this node based on received user data
*/
@@ -122,7 +123,8 @@ class NodeDB
void loadFromDisk();
/// Reinit device state from scratch (not loading from disk)
void installDefaultDeviceState(), installDefaultRadioConfig(), installDefaultChannels();
void installDefaultDeviceState(), installDefaultChannels(), installDefaultConfig(),
installDefaultModuleConfig();
};
/**
@@ -136,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
@@ -146,11 +148,11 @@ extern NodeDB nodeDB;
prefs.ls_secs = oneday
prefs.position_broadcast_secs = 12 hours # send either position or owner every 12hrs
# 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
@@ -159,33 +161,26 @@ extern NodeDB nodeDB;
// Our delay functions check for this for times that should never expire
#define NODE_DELAY_FOREVER 0xffffffff
#define IF_ROUTER(routerVal, normalVal) ((radioConfig.preferences.role == Role_Router) ? (routerVal) : (normalVal))
#define IF_ROUTER(routerVal, normalVal) ((config.device.role == Config_DeviceConfig_Role_Router) ? (routerVal) : (normalVal))
#define PREF_GET(name, defaultVal) \
inline uint32_t getPref_##name() { return radioConfig.preferences.name ? radioConfig.preferences.name : (defaultVal); }
PREF_GET(position_broadcast_secs, IF_ROUTER(12 * 60 * 60, 15 * 60))
// Defaulting Telemetry to the same as position interval for now
PREF_GET(telemetry_module_device_update_interval, IF_ROUTER(12 * 60 * 60, 15 * 60))
PREF_GET(telemetry_module_environment_update_interval, IF_ROUTER(12 * 60 * 60, 15 * 60))
#define default_broadcast_interval_secs IF_ROUTER(12 * 60 * 60, 15 * 60)
#define default_wait_bluetooth_secs IF_ROUTER(1, 60)
#define default_mesh_sds_timeout_secs IF_ROUTER(NODE_DELAY_FOREVER, 2 * 60 * 60)
#define default_sds_secs 365 * 24 * 60 * 60
#define default_ls_secs IF_ROUTER(24 * 60 * 60, 5 * 60)
#define default_min_wake_secs 10
// Each time we wake into the DARK state allow 1 minute to send and receive BLE packets to the phone
PREF_GET(wait_bluetooth_secs, IF_ROUTER(1, 60))
inline uint32_t getIntervalOrDefaultMs(uint32_t interval)
{
if (interval > 0)
return interval * 1000;
return default_broadcast_interval_secs * 1000;
}
PREF_GET(screen_on_secs, 60)
PREF_GET(mesh_sds_timeout_secs, IF_ROUTER(NODE_DELAY_FOREVER, 2 * 60 * 60))
PREF_GET(sds_secs, 365 * 24 * 60 * 60)
// We default to sleeping (with bluetooth off for 5 minutes at a time). This seems to be a good tradeoff between
// latency for the user sending messages and power savings because of not having to run (expensive) ESP32 bluetooth
PREF_GET(ls_secs, IF_ROUTER(24 * 60 * 60, 5 * 60))
PREF_GET(phone_timeout_secs, 15 * 60)
PREF_GET(min_wake_secs, 10)
/** The current change # for radio settings. Starts at 0 on boot and any time the radio settings
/** The current change # for radio settings. Starts at 0 on boot and any time the radio settings
* might have changed is incremented. Allows others to detect they might now be on a new channel.
*/
extern uint32_t radioGeneration;
#define Module_Config_size (ModuleConfig_CannedMessageConfig_size + ModuleConfig_ExternalNotificationConfig_size + ModuleConfig_MQTTConfig_size + ModuleConfig_RangeTestConfig_size + ModuleConfig_SerialConfig_size + ModuleConfig_StoreForwardConfig_size + ModuleConfig_TelemetryConfig_size + ModuleConfig_size)

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,89 @@ 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_MODULECONFIG;
config_state = ModuleConfig_mqtt_tag;
}
break;
case STATE_SEND_MODULECONFIG:
fromRadioScratch.which_payloadVariant = FromRadio_moduleConfig_tag;
switch (config_state) {
case ModuleConfig_mqtt_tag:
fromRadioScratch.moduleConfig.which_payloadVariant = ModuleConfig_mqtt_tag;
fromRadioScratch.moduleConfig.payloadVariant.mqtt = moduleConfig.mqtt;
break;
case ModuleConfig_serial_tag:
fromRadioScratch.moduleConfig.which_payloadVariant = ModuleConfig_serial_tag;
fromRadioScratch.moduleConfig.payloadVariant.serial = moduleConfig.serial;
break;
case ModuleConfig_external_notification_tag:
fromRadioScratch.moduleConfig.which_payloadVariant = ModuleConfig_external_notification_tag;
fromRadioScratch.moduleConfig.payloadVariant.external_notification = moduleConfig.external_notification;
break;
case ModuleConfig_range_test_tag:
fromRadioScratch.moduleConfig.which_payloadVariant = ModuleConfig_range_test_tag;
fromRadioScratch.moduleConfig.payloadVariant.range_test = moduleConfig.range_test;
break;
case ModuleConfig_telemetry_tag:
fromRadioScratch.moduleConfig.which_payloadVariant = ModuleConfig_telemetry_tag;
fromRadioScratch.moduleConfig.payloadVariant.telemetry = moduleConfig.telemetry;
break;
case ModuleConfig_canned_message_tag:
fromRadioScratch.moduleConfig.which_payloadVariant = ModuleConfig_canned_message_tag;
fromRadioScratch.moduleConfig.payloadVariant.canned_message = moduleConfig.canned_message;
break;
}
config_state++;
// Advance when we have sent all of our ModuleConfig objects
if (config_state > ModuleConfig_canned_message_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 +299,12 @@ bool PhoneAPI::available()
case STATE_SEND_MY_INFO:
return true;
case STATE_SEND_CONFIG:
return true;
case STATE_SEND_MODULECONFIG:
return true;
case STATE_SEND_NODEINFO:
if (!nodeInfoForPhone)
@@ -269,4 +354,4 @@ int PhoneAPI::onNotify(uint32_t newValue)
DEBUG_MSG("(Client not yet interested in packets)\n");
return 0;
}
}

View File

@@ -20,13 +20,11 @@ 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_MODULECONFIG, // Send Module specific 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
@@ -34,6 +32,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

@@ -70,19 +70,23 @@ bool RF95Interface::init()
int res = lora->begin(getFreq(), bw, sf, cr, syncWord, power, currentLimit, preambleLength);
DEBUG_MSG("RF95 init result %d\n", res);
DEBUG_MSG("Frequency set to %f\n", getFreq());
DEBUG_MSG("Bandwidth set to %f\n", bw);
DEBUG_MSG("Power output set to %d\n", power);
// current limit was removed from module' ctor
// override default value (60 mA)
res = lora->setCurrentLimit(currentLimit);
DEBUG_MSG("Current limit set to %f\n", currentLimit);
DEBUG_MSG("Current limit set result %d\n", res);
if (res == ERR_NONE)
res = lora->setCRC(SX126X_LORA_CRC_ON);
if (res == RADIOLIB_ERR_NONE)
res = lora->setCRC(RADIOLIB_SX126X_LORA_CRC_ON);
if (res == ERR_NONE)
if (res == RADIOLIB_ERR_NONE)
startReceive(); // start receiving
return res == ERR_NONE;
return res == RADIOLIB_ERR_NONE;
}
void INTERRUPT_ATTR RF95Interface::disableInterrupt()
@@ -99,39 +103,39 @@ bool RF95Interface::reconfigure()
// configure publicly accessible settings
int err = lora->setSpreadingFactor(sf);
if (err != ERR_NONE)
if (err != RADIOLIB_ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
err = lora->setBandwidth(bw);
if (err != ERR_NONE)
if (err != RADIOLIB_ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
err = lora->setCodingRate(cr);
if (err != ERR_NONE)
if (err != RADIOLIB_ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
err = lora->setSyncWord(syncWord);
assert(err == ERR_NONE);
assert(err == RADIOLIB_ERR_NONE);
err = lora->setCurrentLimit(currentLimit);
assert(err == ERR_NONE);
assert(err == RADIOLIB_ERR_NONE);
err = lora->setPreambleLength(preambleLength);
assert(err == ERR_NONE);
assert(err == RADIOLIB_ERR_NONE);
err = lora->setFrequency(getFreq());
if (err != ERR_NONE)
if (err != RADIOLIB_ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
if (power > MAX_POWER) // This chip has lower power limits than some
power = MAX_POWER;
err = lora->setOutputPower(power);
if (err != ERR_NONE)
if (err != RADIOLIB_ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
startReceive(); // restart receiving
return ERR_NONE;
return RADIOLIB_ERR_NONE;
}
/**
@@ -147,7 +151,7 @@ void RF95Interface::addReceiveMetadata(MeshPacket *mp)
void RF95Interface::setStandby()
{
int err = lora->standby();
assert(err == ERR_NONE);
assert(err == RADIOLIB_ERR_NONE);
isReceiving = false; // If we were receiving, not any more
disableInterrupt();
@@ -168,7 +172,7 @@ void RF95Interface::startReceive()
setTransmitEnable(false);
setStandby();
int err = lora->startReceive();
assert(err == ERR_NONE);
assert(err == RADIOLIB_ERR_NONE);
isReceiving = true;
@@ -184,12 +188,11 @@ bool RF95Interface::isChannelActive()
setStandby(); // needed for smooth transition
result = lora->scanChannel();
if (result == PREAMBLE_DETECTED) {
if (result == RADIOLIB_PREAMBLE_DETECTED) {
// DEBUG_MSG("Channel is busy!\n");
return true;
}
assert(result != ERR_WRONG_MODEM);
assert(result != RADIOLIB_ERR_WRONG_MODEM);
// DEBUG_MSG("Channel is free!\n");
return false;

View File

@@ -13,8 +13,9 @@ class RF95Interface : public RadioLibInterface
public:
RF95Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, SPIClass &spi);
bool isIRQPending() override { return lora->getPendingIRQ(); }
//TODO: Verify that this irq flag works with RFM95 / SX1276 radios the way it used to
bool isIRQPending() override { return lora->getIRQFlags() & RADIOLIB_SX127X_MASK_IRQ_FLAG_VALID_HEADER; }
/// Initialise the Driver transport hardware and software.
/// Make sure the Driver is properly configured before calling init().

View File

@@ -13,7 +13,8 @@
#define RDEF(name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, frequency_switching) \
{ \
RegionCode_##name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, frequency_switching, #name \
Config_LoRaConfig_RegionCode_##name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, \
frequency_switching, #name \
}
const RegionInfo regions[] = {
@@ -76,15 +77,15 @@ const RegionInfo regions[] = {
*/
RDEF(IN, 865.0f, 867.0f, 100, 0, 30, true, false),
/*
https://rrf.rsm.govt.nz/smart-web/smart/page/-smart/domain/licence/LicenceSummary.wdk?id=219752
https://iotalliance.org.nz/wp-content/uploads/sites/4/2019/05/IoT-Spectrum-in-NZ-Briefing-Paper.pdf
*/
/*
https://rrf.rsm.govt.nz/smart-web/smart/page/-smart/domain/licence/LicenceSummary.wdk?id=219752
https://iotalliance.org.nz/wp-content/uploads/sites/4/2019/05/IoT-Spectrum-in-NZ-Briefing-Paper.pdf
*/
RDEF(NZ865, 864.0f, 868.0f, 100, 0, 0, true, false),
/*
https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
*/
/*
https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
*/
RDEF(TH, 920.0f, 925.0f, 100, 0, 16, true, false),
/*
@@ -99,10 +100,10 @@ const RegionInfo *myRegion;
void initRegion()
{
const RegionInfo *r = regions;
for (; r->code != RegionCode_Unset && r->code != radioConfig.preferences.region; r++)
for (; r->code != Config_LoRaConfig_RegionCode_Unset && r->code != config.lora.region; r++)
;
myRegion = r;
DEBUG_MSG("Wanted region %d, using %s\n", radioConfig.preferences.region, r->name);
DEBUG_MSG("Wanted region %d, using %s\n", config.lora.region, r->name);
}
/**
@@ -158,59 +159,53 @@ 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
// was 20 and 22 secs respectively, but now with shortPacketMsec as 2269, this should give the same range
return random(9 * shortPacketMsec, 10 * shortPacketMsec);
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));
// 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;
if (radioConfig.preferences.role == Role_Router || radioConfig.preferences.role == Role_RouterClient) {
delay = map(snr, SNR_MIN, SNR_MAX, MIN_TX_WAIT_MSEC, (MIN_TX_WAIT_MSEC + (shortPacketMsec / 2)));
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 = 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);
}
return delay;
}
@@ -251,7 +246,7 @@ void printPacket(const char *prefix, const MeshPacket *p)
DEBUG_MSG(" rxSNR=%g", p->rx_snr);
}
if (p->rx_rssi != 0) {
DEBUG_MSG(" rxSNR=%g", p->rx_rssi);
DEBUG_MSG(" rxRSSI=%g", p->rx_rssi);
}
if (p->priority != 0)
DEBUG_MSG(" priority=%d", p->priority);
@@ -351,41 +346,41 @@ void RadioInterface::applyModemConfig()
{
// Set up default configuration
// No Sync Words in LORA mode
Config_LoRaConfig &loraConfig = config.lora;
auto channelSettings = channels.getPrimary();
if (channelSettings.spread_factor == 0) {
switch (channelSettings.modem_config) {
case ChannelSettings_ModemConfig_ShortFast:
if (loraConfig.spread_factor == 0) {
switch (loraConfig.modem_preset) {
case Config_LoRaConfig_ModemPreset_ShortFast:
bw = 250;
cr = 8;
sf = 7;
break;
case ChannelSettings_ModemConfig_ShortSlow:
case Config_LoRaConfig_ModemPreset_ShortSlow:
bw = 250;
cr = 8;
sf = 8;
break;
case ChannelSettings_ModemConfig_MidFast:
case Config_LoRaConfig_ModemPreset_MedFast:
bw = 250;
cr = 8;
sf = 9;
break;
case ChannelSettings_ModemConfig_MidSlow:
case Config_LoRaConfig_ModemPreset_MedSlow:
bw = 250;
cr = 8;
sf = 10;
break;
case ChannelSettings_ModemConfig_LongFast:
case Config_LoRaConfig_ModemPreset_LongFast:
bw = 250;
cr = 8;
sf = 11;
break;
case ChannelSettings_ModemConfig_LongSlow:
case Config_LoRaConfig_ModemPreset_LongSlow:
bw = 125;
cr = 8;
sf = 12;
break;
case ChannelSettings_ModemConfig_VLongSlow:
case Config_LoRaConfig_ModemPreset_VLongSlow:
bw = 31.25;
cr = 8;
sf = 12;
@@ -394,9 +389,9 @@ void RadioInterface::applyModemConfig()
assert(0); // Unknown enum
}
} else {
sf = channelSettings.spread_factor;
cr = channelSettings.coding_rate;
bw = channelSettings.bandwidth;
sf = loraConfig.spread_factor;
cr = loraConfig.coding_rate;
bw = loraConfig.bandwidth;
if (bw == 31) // This parameter is not an integer
bw = 31.25;
@@ -404,10 +399,15 @@ void RadioInterface::applyModemConfig()
bw = 62.5;
}
power = channelSettings.tx_power;
shortPacketMsec = getPacketTime(sizeof(PacketHeader));
power = loraConfig.tx_power;
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)));
@@ -419,13 +419,13 @@ void RadioInterface::applyModemConfig()
saveChannelNum(channel_num);
saveFreq(freq);
DEBUG_MSG("Set radio: name=%s, config=%u, ch=%d, power=%d\n", channelName, channelSettings.modem_config, channel_num, power);
DEBUG_MSG("Set radio: name=%s, config=%u, ch=%d, power=%d\n", channelName, loraConfig.modem_preset, channel_num, power);
DEBUG_MSG("Radio myRegion->freqStart / myRegion->freqEnd: %f -> %f (%f mhz)\n", myRegion->freqStart, myRegion->freqEnd,
myRegion->freqEnd - myRegion->freqStart);
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,8 +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 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;
@@ -126,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)
@@ -93,278 +113,291 @@ bool RadioLibInterface::canSendImmediately()
/// bluetooth comms code. If the txmit queue is empty it might return an error
ErrorCode RadioLibInterface::send(MeshPacket *p)
{
if (radioConfig.preferences.region != RegionCode_Unset) {
if (disabled || radioConfig.preferences.is_lora_tx_disabled) {
DEBUG_MSG("send - lora_tx_disabled\n");
packetPool.release(p);
return ERRNO_DISABLED;
}
} else {
DEBUG_MSG("send - lora_tx_disabled because RegionCode_Unset\n");
#ifndef DISABLE_WELCOME_UNSET
if (config.lora.region != Config_LoRaConfig_RegionCode_Unset) {
if (disabled || config.lora.tx_disabled) {
if (config.lora.region != Config_LoRaConfig_RegionCode_Unset) {
if (disabled || config.lora.tx_disabled) {
DEBUG_MSG("send - lora_tx_disabled\n");
packetPool.release(p);
return ERRNO_DISABLED;
}
} else {
DEBUG_MSG("send - lora_tx_disabled because RegionCode_Unset\n");
packetPool.release(p);
return ERRNO_DISABLED;
}
}
}
#else
if (disabled || config.lora.tx_disabled) {
DEBUG_MSG("send - lora_tx_disabled\n");
packetPool.release(p);
return ERRNO_DISABLED;
}
// Sometimes when testing it is useful to be able to never turn on the xmitter
#endif
// Sometimes when testing it is useful to be able to never turn on the xmitter
#ifndef LORA_DISABLE_SENDING
printPacket("enqueuing for send", p);
printPacket("enqueuing for send", p);
DEBUG_MSG("txGood=%d,rxGood=%d,rxBad=%d\n", txGood, rxGood, rxBad);
ErrorCode res = txQueue.enqueue(p) ? ERRNO_OK : ERRNO_UNKNOWN;
DEBUG_MSG("txGood=%d,rxGood=%d,rxBad=%d\n", txGood, rxGood, rxBad);
ErrorCode res = txQueue.enqueue(p) ? ERRNO_OK : ERRNO_UNKNOWN;
if (res != ERRNO_OK) { // we weren't able to queue it, so we must drop it to prevent leaks
packetPool.release(p);
return res;
}
// set (random) transmit delay to let others reconfigure their radio,
// to avoid collisions and implement timing-based flooding
// DEBUG_MSG("Set random delay before transmitting.\n");
setTransmitDelay();
if (res != ERRNO_OK) { // we weren't able to queue it, so we must drop it to prevent leaks
packetPool.release(p);
return res;
}
// set (random) transmit delay to let others reconfigure their radio,
// to avoid collisions and implement timing-based flooding
// DEBUG_MSG("Set random delay before transmitting.\n");
setTransmitDelay();
return res;
#else
packetPool.release(p);
return ERRNO_DISABLED;
#endif
}
}
bool RadioLibInterface::canSleep()
{
bool res = txQueue.empty();
if (!res) // only print debug messages if we are vetoing sleep
DEBUG_MSG("radio wait to sleep, txEmpty=%d\n", res);
bool RadioLibInterface::canSleep()
{
bool res = txQueue.empty();
if (!res) // only print debug messages if we are vetoing sleep
DEBUG_MSG("radio wait to sleep, txEmpty=%d\n", res);
return res;
}
return res;
}
/** Attempt to cancel a previously sent packet. Returns true if a packet was found we could cancel */
bool RadioLibInterface::cancelSending(NodeNum from, PacketId id)
{
auto p = txQueue.remove(from, id);
if (p)
packetPool.release(p); // free the packet we just removed
/** Attempt to cancel a previously sent packet. Returns true if a packet was found we could cancel */
bool RadioLibInterface::cancelSending(NodeNum from, PacketId id)
{
auto p = txQueue.remove(from, id);
if (p)
packetPool.release(p); // free the packet we just removed
bool result = (p != NULL);
DEBUG_MSG("cancelSending id=0x%x, removed=%d\n", id, result);
return result;
}
bool result = (p != NULL);
DEBUG_MSG("cancelSending id=0x%x, removed=%d\n", id, result);
return result;
}
/** radio helper thread callback.
/** radio helper thread callback.
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)
{
switch (notification) {
case ISR_TX:
handleTransmitInterrupt();
startReceive();
// DEBUG_MSG("tx complete - starting timer\n");
startTransmitTimer();
break;
case ISR_RX:
handleReceiveInterrupt();
startReceive();
// DEBUG_MSG("rx complete - starting timer\n");
startTransmitTimer();
break;
case TRANSMIT_DELAY_COMPLETED:
// DEBUG_MSG("delay done\n");
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.
*/
void RadioLibInterface::onNotify(uint32_t notification)
{
switch (notification) {
case ISR_TX:
handleTransmitInterrupt();
startReceive();
// DEBUG_MSG("tx complete - starting timer\n");
startTransmitTimer();
break;
case ISR_RX:
handleReceiveInterrupt();
startReceive();
// DEBUG_MSG("rx complete - starting timer\n");
startTransmitTimer();
break;
case TRANSMIT_DELAY_COMPLETED:
// DEBUG_MSG("delay done\n");
// If we are not currently in receive mode, then restart the random delay (this can happen if the main thread
// has placed the unit into standby) FIXME, how will this work if the chipset is in sleep mode?
if (!txQueue.empty()) {
if (!canSendImmediately()) {
// DEBUG_MSG("Currently Rx/Tx-ing: set random delay\n");
setTransmitDelay(); // currently Rx/Tx-ing: reset random delay
} else {
if (isChannelActive()) { // check if there is currently a LoRa packet on the channel
// DEBUG_MSG("Channel is active: set random delay\n");
setTransmitDelay(); // reset random delay
// If we are not currently in receive mode, then restart the random delay (this can happen if the main thread
// has placed the unit into standby) FIXME, how will this work if the chipset is in sleep mode?
if (!txQueue.empty()) {
if (!canSendImmediately()) {
// DEBUG_MSG("Currently Rx/Tx-ing: set random delay\n");
setTransmitDelay(); // currently Rx/Tx-ing: reset random delay
} else {
// Send any outgoing packets we have ready
MeshPacket *txp = txQueue.dequeue();
assert(txp);
startSend(txp);
if (isChannelActive()) { // check if there is currently a LoRa packet on the channel
// DEBUG_MSG("Channel is active: set random delay\n");
setTransmitDelay(); // reset random delay
} else {
// Send any outgoing packets we have ready
MeshPacket *txp = txQueue.dequeue();
assert(txp);
startSend(txp);
// Packet has been sent, count it toward our TX airtime utilization.
uint32_t xmitMsec = getPacketTime(txp);
airTime->logAirtime(TX_LOG, xmitMsec);
// Packet has been sent, count it toward our TX airtime utilization.
uint32_t xmitMsec = getPacketTime(txp);
airTime->logAirtime(TX_LOG, xmitMsec);
}
}
} else {
// DEBUG_MSG("done with txqueue\n");
}
} else {
// DEBUG_MSG("done with txqueue\n");
}
break;
default:
assert(0); // We expected to receive a valid notification from the ISR
}
}
void RadioLibInterface::setTransmitDelay()
{
MeshPacket *p = txQueue.getFront();
// We want all sending/receiving to be done by our daemon thread.
// We use a delay here because this packet might have been sent in response to a packet we just received.
// So we want to make sure the other side has had a chance to reconfigure its radio.
/* We assume if rx_snr = 0 and rx_rssi = 0, the packet was generated locally.
* This assumption is valid because of the offset generated by the radio to account for the noise
* floor.
*/
if (p->rx_snr == 0 && p->rx_rssi == 0) {
startTransmitTimer(true);
} else {
// If there is a SNR, start a timer scaled based on that SNR.
DEBUG_MSG("rx_snr found. hop_limit:%d rx_snr:%f\n", p->hop_limit, p->rx_snr);
startTransmitTimerSNR(p->rx_snr);
}
}
void RadioLibInterface::startTransmitTimer(bool withDelay)
{
// If we have work to do and the timer wasn't already scheduled, schedule it now
if (!txQueue.empty()) {
uint32_t delay = !withDelay ? 1 : getTxDelayMsec();
// DEBUG_MSG("xmit timer %d\n", delay);
notifyLater(delay, TRANSMIT_DELAY_COMPLETED, false); // This will implicitly enable
}
}
void RadioLibInterface::startTransmitTimerSNR(float snr)
{
// If we have work to do and the timer wasn't already scheduled, schedule it now
if (!txQueue.empty()) {
uint32_t delay = getTxDelayMsecWeighted(snr);
// DEBUG_MSG("xmit timer %d\n", delay);
notifyLater(delay, TRANSMIT_DELAY_COMPLETED, false); // This will implicitly enable
}
}
void RadioLibInterface::handleTransmitInterrupt()
{
// DEBUG_MSG("handling lora TX interrupt\n");
// This can be null if we forced the device to enter standby mode. In that case
// ignore the transmit interrupt
if (sendingPacket)
completeSending();
}
void RadioLibInterface::completeSending()
{
// We are careful to clear sending packet before calling printPacket because
// that can take a long time
auto p = sendingPacket;
sendingPacket = NULL;
if (p) {
txGood++;
printPacket("Completed sending", p);
// We are done sending that packet, release it
packetPool.release(p);
// DEBUG_MSG("Done with send\n");
}
}
void RadioLibInterface::handleReceiveInterrupt()
{
uint32_t xmitMsec;
assert(isReceiving);
isReceiving = false;
// read the number of actually received bytes
size_t length = iface->getPacketLength();
xmitMsec = getPacketTime(length);
int state = iface->readData(radiobuf, length);
if (state != ERR_NONE) {
DEBUG_MSG("ignoring received packet due to error=%d\n", state);
rxBad++;
airTime->logAirtime(RX_ALL_LOG, xmitMsec);
} else {
// Skip the 4 headers that are at the beginning of the rxBuf
int32_t payloadLen = length - sizeof(PacketHeader);
const uint8_t *payload = radiobuf + sizeof(PacketHeader);
// check for short packets
if (payloadLen < 0) {
DEBUG_MSG("ignoring received packet too short\n");
rxBad++;
airTime->logAirtime(RX_ALL_LOG, xmitMsec);
} else {
const PacketHeader *h = (PacketHeader *)radiobuf;
rxGood++;
// Note: we deliver _all_ packets to our router (i.e. our interface is intentionally promiscuous).
// This allows the router and other apps on our node to sniff packets (usually routing) between other
// nodes.
MeshPacket *mp = packetPool.allocZeroed();
mp->from = h->from;
mp->to = h->to;
mp->id = h->id;
mp->channel = h->channel;
assert(HOP_MAX <= PACKET_FLAGS_HOP_MASK); // If hopmax changes, carefully check this code
mp->hop_limit = h->flags & PACKET_FLAGS_HOP_MASK;
mp->want_ack = !!(h->flags & PACKET_FLAGS_WANT_ACK_MASK);
addReceiveMetadata(mp);
mp->which_payloadVariant = MeshPacket_encrypted_tag; // Mark that the payload is still encrypted at this point
assert(((uint32_t)payloadLen) <= sizeof(mp->encrypted.bytes));
memcpy(mp->encrypted.bytes, payload, payloadLen);
mp->encrypted.size = payloadLen;
printPacket("Lora RX", mp);
// xmitMsec = getPacketTime(mp);
airTime->logAirtime(RX_LOG, xmitMsec);
deliverToReceiver(mp);
break;
default:
assert(0); // We expected to receive a valid notification from the ISR
}
}
}
/** start an immediate transmit */
void RadioLibInterface::startSend(MeshPacket *txp)
{
printPacket("Starting low level send", txp);
if (disabled || radioConfig.preferences.is_lora_tx_disabled) {
DEBUG_MSG("startSend is dropping tx packet because we are disabled\n");
packetPool.release(txp);
} else {
setStandby(); // Cancel any already in process receives
void RadioLibInterface::setTransmitDelay()
{
MeshPacket *p = txQueue.getFront();
// We want all sending/receiving to be done by our daemon thread.
// We use a delay here because this packet might have been sent in response to a packet we just received.
// So we want to make sure the other side has had a chance to reconfigure its radio.
configHardwareForSend(); // must be after setStandby
/* We assume if rx_snr = 0 and rx_rssi = 0, the packet was generated locally.
* This assumption is valid because of the offset generated by the radio to account for the noise
* floor.
*/
if (p->rx_snr == 0 && p->rx_rssi == 0) {
startTransmitTimer(true);
} else {
// If there is a SNR, start a timer scaled based on that SNR.
DEBUG_MSG("rx_snr found. hop_limit:%d rx_snr:%f\n", p->hop_limit, p->rx_snr);
startTransmitTimerSNR(p->rx_snr);
}
}
size_t numbytes = beginSending(txp);
void RadioLibInterface::startTransmitTimer(bool withDelay)
{
// If we have work to do and the timer wasn't already scheduled, schedule it now
if (!txQueue.empty()) {
uint32_t delay = !withDelay ? 1 : getTxDelayMsec();
// DEBUG_MSG("xmit timer %d\n", delay);
notifyLater(delay, TRANSMIT_DELAY_COMPLETED, false); // This will implicitly enable
}
}
int res = iface->startTransmit(radiobuf, numbytes);
if (res != ERR_NONE) {
RECORD_CRITICALERROR(CriticalErrorCode_RadioSpiBug);
void RadioLibInterface::startTransmitTimerSNR(float snr)
{
// If we have work to do and the timer wasn't already scheduled, schedule it now
if (!txQueue.empty()) {
uint32_t delay = getTxDelayMsecWeighted(snr);
// DEBUG_MSG("xmit timer %d\n", delay);
notifyLater(delay, TRANSMIT_DELAY_COMPLETED, false); // This will implicitly enable
}
}
// This send failed, but make sure to 'complete' it properly
void RadioLibInterface::handleTransmitInterrupt()
{
// DEBUG_MSG("handling lora TX interrupt\n");
// This can be null if we forced the device to enter standby mode. In that case
// ignore the transmit interrupt
if (sendingPacket)
completeSending();
startReceive(); // Restart receive mode (because startTransmit failed to put us in xmit mode)
}
// Must be done AFTER, starting transmit, because startTransmit clears (possibly stale) interrupt pending register bits
enableInterrupt(isrTxLevel0);
}
}
void RadioLibInterface::completeSending()
{
// We are careful to clear sending packet before calling printPacket because
// that can take a long time
auto p = sendingPacket;
sendingPacket = NULL;
if (p) {
txGood++;
printPacket("Completed sending", p);
// We are done sending that packet, release it
packetPool.release(p);
// DEBUG_MSG("Done with send\n");
}
}
void RadioLibInterface::handleReceiveInterrupt()
{
uint32_t xmitMsec;
assert(isReceiving);
isReceiving = false;
// read the number of actually received bytes
size_t length = iface->getPacketLength();
xmitMsec = getPacketTime(length);
int state = iface->readData(radiobuf, length);
if (state != RADIOLIB_ERR_NONE) {
DEBUG_MSG("ignoring received packet due to error=%d\n", state);
rxBad++;
airTime->logAirtime(RX_ALL_LOG, xmitMsec);
} else {
// Skip the 4 headers that are at the beginning of the rxBuf
int32_t payloadLen = length - sizeof(PacketHeader);
const uint8_t *payload = radiobuf + sizeof(PacketHeader);
// check for short packets
if (payloadLen < 0) {
DEBUG_MSG("ignoring received packet too short\n");
rxBad++;
airTime->logAirtime(RX_ALL_LOG, xmitMsec);
} else {
const PacketHeader *h = (PacketHeader *)radiobuf;
rxGood++;
// Note: we deliver _all_ packets to our router (i.e. our interface is intentionally promiscuous).
// This allows the router and other apps on our node to sniff packets (usually routing) between other
// nodes.
MeshPacket *mp = packetPool.allocZeroed();
mp->from = h->from;
mp->to = h->to;
mp->id = h->id;
mp->channel = h->channel;
assert(HOP_MAX <= PACKET_FLAGS_HOP_MASK); // If hopmax changes, carefully check this code
mp->hop_limit = h->flags & PACKET_FLAGS_HOP_MASK;
mp->want_ack = !!(h->flags & PACKET_FLAGS_WANT_ACK_MASK);
addReceiveMetadata(mp);
mp->which_payloadVariant = MeshPacket_encrypted_tag; // Mark that the payload is still encrypted at this point
assert(((uint32_t)payloadLen) <= sizeof(mp->encrypted.bytes));
memcpy(mp->encrypted.bytes, payload, payloadLen);
mp->encrypted.size = payloadLen;
printPacket("Lora RX", mp);
// xmitMsec = getPacketTime(mp);
airTime->logAirtime(RX_LOG, xmitMsec);
deliverToReceiver(mp);
}
}
}
/** start an immediate transmit */
void RadioLibInterface::startSend(MeshPacket * txp)
{
printPacket("Starting low level send", txp);
if (disabled || config.lora.tx_disabled) {
DEBUG_MSG("startSend is dropping tx packet because we are disabled\n");
packetPool.release(txp);
} else {
setStandby(); // Cancel any already in process receives
configHardwareForSend(); // must be after setStandby
size_t numbytes = beginSending(txp);
int res = iface->startTransmit(radiobuf, numbytes);
if (res != RADIOLIB_ERR_NONE) {
RECORD_CRITICALERROR(CriticalErrorCode_RadioSpiBug);
// This send failed, but make sure to 'complete' it properly
completeSending();
startReceive(); // Restart receive mode (because startTransmit failed to put us in xmit mode)
}
// Must be done AFTER, starting transmit, because startTransmit clears (possibly stale) interrupt pending register
// bits
enableInterrupt(isrTxLevel0);
}
}

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) override;
#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

@@ -15,7 +15,7 @@ int16_t RadioLibRF95::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_
{
// execute common part
int16_t state = SX127x::begin(RF95_CHIP_VERSION, syncWord, preambleLength);
if (state != ERR_NONE)
if (state != RADIOLIB_ERR_NONE)
state = SX127x::begin(RF95_ALT_VERSION, syncWord, preambleLength);
RADIOLIB_ASSERT(state);
@@ -30,7 +30,7 @@ int16_t RadioLibRF95::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_
RADIOLIB_ASSERT(state);
#ifdef RF95_TCXO
state = _mod->SPIsetRegValue(SX127X_REG_TCXO, 0x10 | _mod->SPIgetRegValue(SX127X_REG_TCXO));
state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_TCXO, 0x10 | _mod->SPIgetRegValue(RADIOLIB_SX127X_REG_TCXO));
RADIOLIB_ASSERT(state);
#endif
@@ -72,7 +72,7 @@ int16_t RadioLibRF95::setFrequency(float freq)
bool RadioLibRF95::isReceiving()
{
// 0x0b == Look for header info valid, signal synchronized or signal detected
uint8_t reg = readReg(SX127X_REG_MODEM_STAT);
uint8_t reg = readReg(RADIOLIB_SX127X_REG_MODEM_STAT);
// Serial.printf("reg %x\n", reg);
return (reg & (RH_RF95_MODEM_STATUS_SIGNAL_DETECTED | RH_RF95_MODEM_STATUS_SIGNAL_SYNCHRONIZED |
RH_RF95_MODEM_STATUS_HEADER_INFO_VALID)) != 0;

View File

@@ -43,7 +43,7 @@ class RadioLibRF95: public SX1278 {
\returns \ref status_codes
*/
int16_t begin(float freq = 915.0, float bw = 125.0, uint8_t sf = 9, uint8_t cr = 7, uint8_t syncWord = SX127X_SYNC_WORD, int8_t power = 17, uint16_t preambleLength = 8, uint8_t gain = 0);
int16_t begin(float freq = 915.0, float bw = 125.0, uint8_t sf = 9, uint8_t cr = 7, uint8_t syncWord = RADIOLIB_SX127X_SYNC_WORD, int8_t power = 17, uint16_t preambleLength = 8, uint8_t gain = 0);
// configuration methods

View File

@@ -1,7 +1,7 @@
#include "configuration.h"
#include "ReliableRouter.h"
#include "MeshModule.h"
#include "MeshTypes.h"
#include "configuration.h"
#include "mesh-pb-constants.h"
// ReliableRouter::ReliableRouter() {}
@@ -14,11 +14,11 @@ ErrorCode ReliableRouter::send(MeshPacket *p)
{
if (p->want_ack) {
// If someone asks for acks on broadcast, we need the hop limit to be at least one, so that first node that receives our
// message will rebroadcast. But asking for hop_limit 0 in that context means the client app has no preference on hop counts
// and we want this message to get through the whole mesh, so use the default.
// message will rebroadcast. But asking for hop_limit 0 in that context means the client app has no preference on hop
// counts and we want this message to get through the whole mesh, so use the default.
if (p->to == NODENUM_BROADCAST && p->hop_limit == 0) {
if (radioConfig.preferences.hop_limit && radioConfig.preferences.hop_limit <= HOP_MAX) {
p->hop_limit = (radioConfig.preferences.hop_limit >= HOP_MAX) ? HOP_MAX : radioConfig.preferences.hop_limit;
if (config.lora.hop_limit && config.lora.hop_limit <= HOP_MAX) {
p->hop_limit = (config.lora.hop_limit >= HOP_MAX) ? HOP_MAX : config.lora.hop_limit;
} else {
p->hop_limit = HOP_RELIABLE;
}
@@ -41,9 +41,9 @@ bool ReliableRouter::shouldFilterReceived(MeshPacket *p)
// If this is the first time we saw this, cancel any retransmissions we have queued up and generate an internal ack for
// the original sending process.
// FIXME - we might want to turn off this "optimization", it does save lots of airtime but it assumes that once we've heard one
// one adjacent node hear our packet that a) probably other adjacent nodes heard it and b) we can trust those nodes to reach
// our destination. Both of which might be incorrect.
// FIXME - we might want to turn off this "optimization", it does save lots of airtime but it assumes that once we've
// heard one one adjacent node hear our packet that a) probably other adjacent nodes heard it and b) we can trust those
// nodes to reach our destination. Both of which might be incorrect.
auto key = GlobalPacketId(getFrom(p), p->id);
auto old = findPendingPacket(key);
if (old) {
@@ -53,8 +53,7 @@ bool ReliableRouter::shouldFilterReceived(MeshPacket *p)
sendAckNak(Routing_Error_NONE, getFrom(p), p->id, old->packet->channel);
stopRetransmission(key);
}
else {
} else {
DEBUG_MSG("didn't find pending packet\n");
}
}
@@ -151,7 +150,7 @@ bool ReliableRouter::stopRetransmission(GlobalPacketId key)
if (old) {
auto numErased = pending.erase(key);
assert(numErased == 1);
packetPool.release(old->packet);
cancelSending(getFrom(old->packet), old->packet->id);
return true;
} else
return false;

View File

@@ -118,8 +118,8 @@ MeshPacket *Router::allocForSending()
p->which_payloadVariant = MeshPacket_decoded_tag; // Assume payload is decoded at start.
p->from = nodeDB.getNodeNum();
p->to = NODENUM_BROADCAST;
if (radioConfig.preferences.hop_limit && radioConfig.preferences.hop_limit <= HOP_MAX) {
p->hop_limit = (radioConfig.preferences.hop_limit >= HOP_MAX) ? HOP_MAX : radioConfig.preferences.hop_limit;
if (config.lora.hop_limit && config.lora.hop_limit <= HOP_MAX) {
p->hop_limit = (config.lora.hop_limit >= HOP_MAX) ? HOP_MAX : config.lora.hop_limit;
} else {
p->hop_limit = HOP_RELIABLE;
}
@@ -227,7 +227,7 @@ ErrorCode Router::send(MeshPacket *p)
*/
bool shouldActuallyEncrypt = true;
if (*radioConfig.preferences.mqtt_server && !radioConfig.preferences.mqtt_encryption_enabled) {
if (*moduleConfig.mqtt.address && !moduleConfig.mqtt.encryption_enabled) {
shouldActuallyEncrypt = false;
}
@@ -274,6 +274,9 @@ void Router::sniffReceived(const MeshPacket *p, const Routing *c)
bool perhapsDecode(MeshPacket *p)
{
// DEBUG_MSG("\n\n** perhapsDecode payloadVariant - %d\n\n", p->which_payloadVariant);
if (p->which_payloadVariant == MeshPacket_decoded_tag)
return true; // If packet was already decoded just return
@@ -304,12 +307,32 @@ bool perhapsDecode(MeshPacket *p)
p->which_payloadVariant = MeshPacket_decoded_tag; // change type to decoded
p->channel = chIndex; // change to store the index instead of the hash
/*
if (p->decoded.portnum == PortNum_TEXT_MESSAGE_APP) {
DEBUG_MSG("\n\n** TEXT_MESSAGE_APP\n");
} else if (p->decoded.portnum == PortNum_TEXT_MESSAGE_COMPRESSED_APP) {
DEBUG_MSG("\n\n** PortNum_TEXT_MESSAGE_COMPRESSED_APP\n");
}
*/
// Decompress if needed. jm
if (p->decoded.which_payloadVariant == Data_payload_compressed_tag) {
// Decompress the file
}
if (p->decoded.portnum == PortNum_TEXT_MESSAGE_COMPRESSED_APP) {
// Decompress the payload
char compressed_in[Constants_DATA_PAYLOAD_LEN] = {};
char decompressed_out[Constants_DATA_PAYLOAD_LEN] = {};
int decompressed_len;
memcpy(compressed_in, p->decoded.payload.bytes, p->decoded.payload.size);
decompressed_len = unishox2_decompress_simple(compressed_in, p->decoded.payload.size, decompressed_out);
// DEBUG_MSG("\n\n**\n\nDecompressed length - %d \n", decompressed_len);
memcpy(p->decoded.payload.bytes, decompressed_out, decompressed_len);
// Switch the port from PortNum_TEXT_MESSAGE_COMPRESSED_APP to PortNum_TEXT_MESSAGE_APP
p->decoded.portnum = PortNum_TEXT_MESSAGE_APP;
}
printPacket("decoded message", p);
return true;
@@ -341,41 +364,28 @@ Routing_Error perhapsEncode(MeshPacket *p)
char compressed_out[Constants_DATA_PAYLOAD_LEN] = {0};
int compressed_len;
// compressed_len = unishox2_compress_simple(original_payload, p->decoded.payload.size, compressed_out);
compressed_len = unishox2_compress_simple(original_payload, p->decoded.payload.size, compressed_out);
Serial.print("Original length - ");
Serial.println(p->decoded.payload.size);
Serial.print("Compressed length - ");
Serial.println(compressed_len);
// Serial.println(compressed_out);
DEBUG_MSG("Original length - %d \n", p->decoded.payload.size);
DEBUG_MSG("Compressed length - %d \n", compressed_len);
DEBUG_MSG("Original message - %s \n", p->decoded.payload.bytes);
// If the compressed length is greater than or equal to the original size, don't use the compressed form
if (compressed_len >= p->decoded.payload.size) {
DEBUG_MSG("Not compressing message. Not enough benefit from doing so.\n");
DEBUG_MSG("Not using compressing message.\n");
// Set the uncompressed payload varient anyway. Shouldn't hurt?
p->decoded.which_payloadVariant = Data_payload_tag;
// p->decoded.which_payloadVariant = Data_payload_tag;
// Otherwise we use the compressor
} else {
DEBUG_MSG("Compressing message.\n");
DEBUG_MSG("Using compressed message.\n");
// Copy the compressed data into the meshpacket
//p->decoded.payload_compressed.size = compressed_len;
//memcpy(p->decoded.payload_compressed.bytes, compressed_out, compressed_len);
//p->decoded.which_payloadVariant = Data_payload_compressed_tag;
}
p->decoded.payload.size = compressed_len;
memcpy(p->decoded.payload.bytes, compressed_out, compressed_len);
if (0) {
char decompressed_out[Constants_DATA_PAYLOAD_LEN] = {};
int decompressed_len;
// decompressed_len = unishox2_decompress_simple(compressed_out, compressed_len, decompressed_out);
Serial.print("Decompressed length - ");
Serial.println(decompressed_len);
Serial.println(decompressed_out);
p->decoded.portnum = PortNum_TEXT_MESSAGE_COMPRESSED_APP;
}
}
@@ -437,8 +447,8 @@ void Router::handleReceived(MeshPacket *p, RxSource src)
void Router::perhapsHandleReceived(MeshPacket *p)
{
assert(radioConfig.has_preferences);
bool ignore = is_in_repeated(radioConfig.preferences.ignore_incoming, p->from);
// assert(radioConfig.has_preferences);
bool ignore = is_in_repeated(config.lora.ignore_incoming, p->from);
if (ignore)
DEBUG_MSG("Ignoring incoming message, 0x%x is in our ignore list\n", p->from);

View File

@@ -56,6 +56,10 @@ bool SX126xInterface<T>::init()
// \todo Display actual typename of the adapter, not just `SX126x`
DEBUG_MSG("SX126x init result %d\n", res);
DEBUG_MSG("Frequency set to %f\n", getFreq());
DEBUG_MSG("Bandwidth set to %f\n", bw);
DEBUG_MSG("Power output set to %d\n", power);
// current limit was removed from module' ctor
// override default value (60 mA)
res = lora.setCurrentLimit(currentLimit);
@@ -64,15 +68,15 @@ bool SX126xInterface<T>::init()
#ifdef SX126X_TXEN
// lora.begin sets Dio2 as RF switch control, which is not true if we are manually controlling RX and TX
if (res == ERR_NONE)
res = lora.setDio2AsRfSwitch(false);
if (res == RADIOLIB_ERR_NONE)
res = lora.setDio2AsRfSwitch(true);
#endif
#if 0
// Read/write a register we are not using (only used for FSK mode) to test SPI comms
uint8_t crcLSB = 0;
int err = lora.readRegister(SX126X_REG_CRC_POLYNOMIAL_LSB, &crcLSB, 1);
if(err != ERR_NONE)
if(err != RADIOLIB_ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_SX1262Failure);
//if(crcLSB != 0x0f)
@@ -80,11 +84,11 @@ bool SX126xInterface<T>::init()
crcLSB = 0x5a;
err = lora.writeRegister(SX126X_REG_CRC_POLYNOMIAL_LSB, &crcLSB, 1);
if(err != ERR_NONE)
if(err != RADIOLIB_ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_SX1262Failure);
err = lora.readRegister(SX126X_REG_CRC_POLYNOMIAL_LSB, &crcLSB, 1);
if(err != ERR_NONE)
if(err != RADIOLIB_ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_SX1262Failure);
if(crcLSB != 0x5a)
@@ -92,13 +96,13 @@ bool SX126xInterface<T>::init()
// If we got this far register accesses (and therefore SPI comms) are good
#endif
if (res == ERR_NONE)
res = lora.setCRC(SX126X_LORA_CRC_ON);
if (res == RADIOLIB_ERR_NONE)
res = lora.setCRC(RADIOLIB_SX126X_LORA_CRC_ON);
if (res == ERR_NONE)
if (res == RADIOLIB_ERR_NONE)
startReceive(); // start receiving
return res == ERR_NONE;
return res == RADIOLIB_ERR_NONE;
}
template<typename T>
@@ -111,42 +115,43 @@ bool SX126xInterface<T>::reconfigure()
// configure publicly accessible settings
int err = lora.setSpreadingFactor(sf);
if (err != ERR_NONE)
if (err != RADIOLIB_ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
err = lora.setBandwidth(bw);
if (err != ERR_NONE)
if (err != RADIOLIB_ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
err = lora.setCodingRate(cr);
if (err != ERR_NONE)
if (err != RADIOLIB_ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
// Hmm - seems to lower SNR when the signal levels are high. Leaving off for now...
err = lora.setRxGain(true);
assert(err == ERR_NONE);
// TODO: Confirm gain registers are okay now
// err = lora.setRxGain(true);
// assert(err == RADIOLIB_ERR_NONE);
err = lora.setSyncWord(syncWord);
assert(err == ERR_NONE);
assert(err == RADIOLIB_ERR_NONE);
err = lora.setCurrentLimit(currentLimit);
assert(err == ERR_NONE);
assert(err == RADIOLIB_ERR_NONE);
err = lora.setPreambleLength(preambleLength);
assert(err == ERR_NONE);
assert(err == RADIOLIB_ERR_NONE);
err = lora.setFrequency(getFreq());
if (err != ERR_NONE)
if (err != RADIOLIB_ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
if (power > 22) // This chip has lower power limits than some
power = 22;
err = lora.setOutputPower(power);
assert(err == ERR_NONE);
assert(err == RADIOLIB_ERR_NONE);
startReceive(); // restart receiving
return ERR_NONE;
return RADIOLIB_ERR_NONE;
}
template<typename T>
@@ -161,7 +166,7 @@ void SX126xInterface<T>::setStandby()
checkNotification(); // handle any pending interrupts before we force standby
int err = lora.standby();
assert(err == ERR_NONE);
assert(err == RADIOLIB_ERR_NONE);
#ifdef SX126X_RXEN // we have RXEN/TXEN control - turn off RX and TX power
digitalWrite(SX126X_RXEN, LOW);
@@ -194,6 +199,9 @@ void SX126xInterface<T>::configHardwareForSend()
#ifdef SX126X_TXEN // we have RXEN/TXEN control - turn on TX power / off RX power
digitalWrite(SX126X_TXEN, HIGH);
#endif
#ifdef SX126X_RXEN
digitalWrite(SX126X_RXEN, LOW);
#endif
RadioLibInterface::configHardwareForSend();
}
@@ -213,11 +221,14 @@ void SX126xInterface<T>::startReceive()
#ifdef SX126X_RXEN // we have RXEN/TXEN control - turn on RX power / off TX power
digitalWrite(SX126X_RXEN, HIGH);
#endif
#ifdef SX126X_TXEN
digitalWrite(SX126X_TXEN, LOW);
#endif
// int err = lora.startReceive();
int err = lora.startReceiveDutyCycleAuto(); // We use a 32 bit preamble so this should save some power by letting radio sit in
// standby mostly.
assert(err == ERR_NONE);
assert(err == RADIOLIB_ERR_NONE);
isReceiving = true;
@@ -235,10 +246,10 @@ bool SX126xInterface<T>::isChannelActive()
setStandby();
result = lora.scanChannel();
if (result == PREAMBLE_DETECTED)
if (result == RADIOLIB_PREAMBLE_DETECTED)
return true;
assert(result != ERR_WRONG_MODEM);
assert(result != RADIOLIB_ERR_WRONG_MODEM);
return false;
}
@@ -253,7 +264,7 @@ bool SX126xInterface<T>::isActivelyReceiving()
// never even get a valid header, so we don't want preamble to get set and stay set due to noise on the network.
uint16_t irq = lora.getIrqStatus();
bool hasPreamble = (irq & SX126X_IRQ_HEADER_VALID);
bool hasPreamble = (irq & RADIOLIB_SX126X_IRQ_HEADER_VALID);
// this is not correct - often always true - need to add an extra conditional
// size_t bytesPending = lora.getPacketLength();
@@ -283,4 +294,4 @@ bool SX126xInterface<T>::sleep()
#endif
return true;
}
}

View File

@@ -1,12 +1,14 @@
/* 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
#error Regenerate this file with the current version of nanopb generator.
#endif
PB_BIND(AdminMessage, AdminMessage, 2)
PB_BIND(AdminMessage, AdminMessage, AUTO)

View File

@@ -1,73 +1,153 @@
/* 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
#include <pb.h>
#include "channel.pb.h"
#include "config.pb.h"
#include "mesh.pb.h"
#include "radioconfig.pb.h"
#include "module_config.pb.h"
#if PB_PROTO_HEADER_VERSION != 40
#error Regenerate this file with the current version of nanopb generator.
#endif
/* Enum definitions */
typedef enum _AdminMessage_ConfigType {
AdminMessage_ConfigType_DEVICE_CONFIG = 0,
AdminMessage_ConfigType_POSITION_CONFIG = 1,
AdminMessage_ConfigType_POWER_CONFIG = 2,
AdminMessage_ConfigType_WIFI_CONFIG = 3,
AdminMessage_ConfigType_DISPLAY_CONFIG = 4,
AdminMessage_ConfigType_LORA_CONFIG = 5
} AdminMessage_ConfigType;
typedef enum _AdminMessage_ModuleConfigType {
AdminMessage_ModuleConfigType_MQTT_CONFIG = 0,
AdminMessage_ModuleConfigType_SERIAL_CONFIG = 1,
AdminMessage_ModuleConfigType_EXTNOTIF_CONFIG = 2,
AdminMessage_ModuleConfigType_STOREFORWARD_CONFIG = 3,
AdminMessage_ModuleConfigType_RANGETEST_CONFIG = 4,
AdminMessage_ModuleConfigType_TELEMETRY_CONFIG = 5,
AdminMessage_ModuleConfigType_CANNEDMSG_CONFIG = 6
} AdminMessage_ModuleConfigType;
/* Struct definitions */
/* This message is handled by the Admin module and is responsible for all settings/channel read/write operations.
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 radio provisioning for this node */
pb_size_t which_variant;
union {
RadioConfig set_radio;
/* 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;
bool get_radio_request;
RadioConfig get_radio_response;
/* 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;
/* Helper constants for enums */
#define _AdminMessage_ConfigType_MIN AdminMessage_ConfigType_DEVICE_CONFIG
#define _AdminMessage_ConfigType_MAX AdminMessage_ConfigType_LORA_CONFIG
#define _AdminMessage_ConfigType_ARRAYSIZE ((AdminMessage_ConfigType)(AdminMessage_ConfigType_LORA_CONFIG+1))
#define _AdminMessage_ModuleConfigType_MIN AdminMessage_ModuleConfigType_MQTT_CONFIG
#define _AdminMessage_ModuleConfigType_MAX AdminMessage_ModuleConfigType_CANNEDMSG_CONFIG
#define _AdminMessage_ModuleConfigType_ARRAYSIZE ((AdminMessage_ModuleConfigType)(AdminMessage_ModuleConfigType_CANNEDMSG_CONFIG+1))
#ifdef __cplusplus
extern "C" {
#endif
/* Initializer values for message structs */
#define AdminMessage_init_default {0, {RadioConfig_init_default}}
#define AdminMessage_init_zero {0, {RadioConfig_init_zero}}
#define AdminMessage_init_default {0, {User_init_default}}
#define AdminMessage_init_zero {0, {User_init_zero}}
/* Field tags (for use in manual encoding/decoding) */
#define AdminMessage_set_radio_tag 1
#define AdminMessage_set_owner_tag 2
#define AdminMessage_set_channel_tag 3
#define AdminMessage_get_radio_request_tag 4
#define AdminMessage_get_radio_response_tag 5
#define AdminMessage_get_channel_request_tag 6
#define AdminMessage_get_channel_response_tag 7
#define AdminMessage_get_owner_request_tag 8
#define AdminMessage_get_owner_response_tag 9
#define AdminMessage_get_config_request_tag 10
#define AdminMessage_get_config_response_tag 11
#define AdminMessage_set_config_tag 12
#define AdminMessage_confirm_set_config_tag 13
#define AdminMessage_get_module_config_request_tag 14
#define AdminMessage_get_module_config_response_tag 15
#define AdminMessage_set_module_config_tag 16
#define AdminMessage_confirm_set_module_config_tag 17
#define AdminMessage_confirm_set_channel_tag 32
#define AdminMessage_confirm_set_radio_tag 33
#define AdminMessage_exit_simulator_tag 34
@@ -88,15 +168,20 @@ extern "C" {
/* Struct field encoding specification for nanopb */
#define AdminMessage_FIELDLIST(X, a) \
X(a, STATIC, ONEOF, MESSAGE, (variant,set_radio,set_radio), 1) \
X(a, STATIC, ONEOF, MESSAGE, (variant,set_owner,set_owner), 2) \
X(a, STATIC, ONEOF, MESSAGE, (variant,set_channel,set_channel), 3) \
X(a, STATIC, ONEOF, BOOL, (variant,get_radio_request,get_radio_request), 4) \
X(a, STATIC, ONEOF, MESSAGE, (variant,get_radio_response,get_radio_response), 5) \
X(a, STATIC, ONEOF, UINT32, (variant,get_channel_request,get_channel_request), 6) \
X(a, STATIC, ONEOF, MESSAGE, (variant,get_channel_response,get_channel_response), 7) \
X(a, STATIC, ONEOF, BOOL, (variant,get_owner_request,get_owner_request), 8) \
X(a, STATIC, ONEOF, MESSAGE, (variant,get_owner_response,get_owner_response), 9) \
X(a, STATIC, ONEOF, UENUM, (variant,get_config_request,get_config_request), 10) \
X(a, STATIC, ONEOF, MESSAGE, (variant,get_config_response,get_config_response), 11) \
X(a, STATIC, ONEOF, MESSAGE, (variant,set_config,set_config), 12) \
X(a, STATIC, ONEOF, BOOL, (variant,confirm_set_config,confirm_set_config), 13) \
X(a, STATIC, ONEOF, UENUM, (variant,get_module_config_request,get_module_config_request), 14) \
X(a, STATIC, ONEOF, MESSAGE, (variant,get_module_config_response,get_module_config_response), 15) \
X(a, STATIC, ONEOF, MESSAGE, (variant,set_module_config,set_module_config), 16) \
X(a, STATIC, ONEOF, BOOL, (variant,confirm_set_module_config,confirm_set_module_config), 17) \
X(a, STATIC, ONEOF, BOOL, (variant,confirm_set_channel,confirm_set_channel), 32) \
X(a, STATIC, ONEOF, BOOL, (variant,confirm_set_radio,confirm_set_radio), 33) \
X(a, STATIC, ONEOF, BOOL, (variant,exit_simulator,exit_simulator), 34) \
@@ -116,12 +201,14 @@ X(a, STATIC, ONEOF, STRING, (variant,set_canned_message_module_part4,set_
X(a, STATIC, ONEOF, INT32, (variant,shutdown_seconds,shutdown_seconds), 51)
#define AdminMessage_CALLBACK NULL
#define AdminMessage_DEFAULT NULL
#define AdminMessage_variant_set_radio_MSGTYPE RadioConfig
#define AdminMessage_variant_set_owner_MSGTYPE User
#define AdminMessage_variant_set_channel_MSGTYPE Channel
#define AdminMessage_variant_get_radio_response_MSGTYPE RadioConfig
#define AdminMessage_variant_get_channel_response_MSGTYPE Channel
#define AdminMessage_variant_get_owner_response_MSGTYPE User
#define AdminMessage_variant_get_config_response_MSGTYPE Config
#define AdminMessage_variant_set_config_MSGTYPE Config
#define AdminMessage_variant_get_module_config_response_MSGTYPE ModuleConfig
#define AdminMessage_variant_set_module_config_MSGTYPE ModuleConfig
extern const pb_msgdesc_t AdminMessage_msg;
@@ -129,7 +216,7 @@ extern const pb_msgdesc_t AdminMessage_msg;
#define AdminMessage_fields &AdminMessage_msg
/* Maximum encoded size of messages (where known) */
#define AdminMessage_size 598
#define AdminMessage_size 204
#ifdef __cplusplus
} /* extern "C" */

View File

@@ -1,12 +1,12 @@
/* 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
#error Regenerate this file with the current version of nanopb generator.
#endif
PB_BIND(ChannelSet, ChannelSet, AUTO)
PB_BIND(ChannelSet, ChannelSet, 2)

View File

@@ -1,10 +1,11 @@
/* 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
#include <pb.h>
#include "channel.pb.h"
#include "config.pb.h"
#if PB_PROTO_HEADER_VERSION != 40
#error Regenerate this file with the current version of nanopb generator.
@@ -17,8 +18,12 @@
No DISABLED channels are included.
This abstraction is used only on the the 'app side' of the world (ie python, javascript and android etc) to show a group of Channels as a (long) URL */
typedef struct _ChannelSet {
/* TODO: REPLACE */
pb_callback_t settings;
/* Channel list with settings */
pb_size_t settings_count;
ChannelSettings settings[8];
/* LoRa config */
bool has_lora_config;
Config_LoRaConfig lora_config;
} ChannelSet;
@@ -27,18 +32,21 @@ extern "C" {
#endif
/* Initializer values for message structs */
#define ChannelSet_init_default {{{NULL}, NULL}}
#define ChannelSet_init_zero {{{NULL}, NULL}}
#define ChannelSet_init_default {0, {ChannelSettings_init_default, ChannelSettings_init_default, ChannelSettings_init_default, ChannelSettings_init_default, ChannelSettings_init_default, ChannelSettings_init_default, ChannelSettings_init_default, ChannelSettings_init_default}, false, Config_LoRaConfig_init_default}
#define ChannelSet_init_zero {0, {ChannelSettings_init_zero, ChannelSettings_init_zero, ChannelSettings_init_zero, ChannelSettings_init_zero, ChannelSettings_init_zero, ChannelSettings_init_zero, ChannelSettings_init_zero, ChannelSettings_init_zero}, false, Config_LoRaConfig_init_zero}
/* Field tags (for use in manual encoding/decoding) */
#define ChannelSet_settings_tag 1
#define ChannelSet_lora_config_tag 2
/* Struct field encoding specification for nanopb */
#define ChannelSet_FIELDLIST(X, a) \
X(a, CALLBACK, REPEATED, MESSAGE, settings, 1)
#define ChannelSet_CALLBACK pb_default_field_callback
X(a, STATIC, REPEATED, MESSAGE, settings, 1) \
X(a, STATIC, OPTIONAL, MESSAGE, lora_config, 2)
#define ChannelSet_CALLBACK NULL
#define ChannelSet_DEFAULT NULL
#define ChannelSet_settings_MSGTYPE ChannelSettings
#define ChannelSet_lora_config_MSGTYPE Config_LoRaConfig
extern const pb_msgdesc_t ChannelSet_msg;
@@ -46,7 +54,7 @@ extern const pb_msgdesc_t ChannelSet_msg;
#define ChannelSet_fields &ChannelSet_msg
/* Maximum encoded size of messages (where known) */
/* ChannelSet_size depends on runtime parameters */
#define ChannelSet_size 573
#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 "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
@@ -14,4 +14,3 @@ PB_BIND(Channel, Channel, AUTO)

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
@@ -10,16 +10,6 @@
#endif
/* Enum definitions */
typedef enum _ChannelSettings_ModemConfig {
ChannelSettings_ModemConfig_VLongSlow = 0,
ChannelSettings_ModemConfig_LongSlow = 1,
ChannelSettings_ModemConfig_LongFast = 2,
ChannelSettings_ModemConfig_MidSlow = 3,
ChannelSettings_ModemConfig_MidFast = 4,
ChannelSettings_ModemConfig_ShortSlow = 5,
ChannelSettings_ModemConfig_ShortFast = 6
} ChannelSettings_ModemConfig;
typedef enum _Channel_Role {
Channel_Role_DISABLED = 0,
Channel_Role_PRIMARY = 1,
@@ -48,28 +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 {
/* If zero then, use default max legal continuous power (ie. something that won't
burn out the radio hardware)
In most cases you should use zero here.
Units are in dBm. */
int8_t tx_power;
/* Note: This is the 'old' mechanism for specifying channel parameters.
Either modem_config or bandwidth/spreading/coding will be specified - NOT BOTH.
As a heuristic: If bandwidth is specified, do not use modem_config.
Because protobufs take ZERO space when the value is zero this works out nicely.
This value is replaced by bandwidth/spread_factor/coding_rate.
If you'd like to experiment with other options add them to MeshRadio.cpp in the device code. */
ChannelSettings_ModemConfig modem_config;
/* Bandwidth in MHz
Certain bandwidth numbers are 'special' and will be converted to the
appropriate floating point value: 31 -> 31.25MHz */
ChannelSettings_psk_t psk;
/* A number from 7 to 12.
Indicates number of chirps per symbol as 1<<spread_factor. */
char name[12];
/* The denominator of the coding rate.
ie for 4/8, the value is 8. 5/8 the value is 5. */
uint16_t bandwidth;
/* 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.
@@ -88,27 +76,7 @@ typedef struct _ChannelSettings {
hash = ((hash << 5) + hash) + (unsigned char) c;
return hash;
} */
uint32_t spread_factor;
/* 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 */
uint8_t coding_rate;
/* 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 ModemConfig */
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)
@@ -120,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 */
@@ -132,20 +100,16 @@ 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;
/* Helper constants for enums */
#define _ChannelSettings_ModemConfig_MIN ChannelSettings_ModemConfig_VLongSlow
#define _ChannelSettings_ModemConfig_MAX ChannelSettings_ModemConfig_ShortFast
#define _ChannelSettings_ModemConfig_ARRAYSIZE ((ChannelSettings_ModemConfig)(ChannelSettings_ModemConfig_ShortFast+1))
#define _Channel_Role_MIN Channel_Role_DISABLED
#define _Channel_Role_MAX Channel_Role_SECONDARY
#define _Channel_Role_ARRAYSIZE ((Channel_Role)(Channel_Role_SECONDARY+1))
@@ -156,19 +120,14 @@ extern "C" {
#endif
/* Initializer values for message structs */
#define ChannelSettings_init_default {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, "", 0, 0, 0, 0, 0, 0, 0}
#define ChannelSettings_init_default {{0, {0}}, "", 0, 0, 0, 0}
#define Channel_init_default {0, false, ChannelSettings_init_default, _Channel_Role_MIN}
#define ChannelSettings_init_zero {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, "", 0, 0, 0, 0, 0, 0, 0}
#define ChannelSettings_init_zero {{0, {0}}, "", 0, 0, 0, 0}
#define Channel_init_zero {0, false, ChannelSettings_init_zero, _Channel_Role_MIN}
/* Field tags (for use in manual encoding/decoding) */
#define ChannelSettings_tx_power_tag 1
#define ChannelSettings_modem_config_tag 3
#define ChannelSettings_psk_tag 4
#define ChannelSettings_name_tag 5
#define ChannelSettings_bandwidth_tag 6
#define ChannelSettings_spread_factor_tag 7
#define ChannelSettings_coding_rate_tag 8
#define ChannelSettings_channel_num_tag 9
#define ChannelSettings_id_tag 10
#define ChannelSettings_uplink_enabled_tag 16
@@ -179,13 +138,8 @@ extern "C" {
/* Struct field encoding specification for nanopb */
#define ChannelSettings_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, INT32, tx_power, 1) \
X(a, STATIC, SINGULAR, UENUM, modem_config, 3) \
X(a, STATIC, SINGULAR, BYTES, psk, 4) \
X(a, STATIC, SINGULAR, STRING, name, 5) \
X(a, STATIC, SINGULAR, UINT32, bandwidth, 6) \
X(a, STATIC, SINGULAR, UINT32, spread_factor, 7) \
X(a, STATIC, SINGULAR, UINT32, coding_rate, 8) \
X(a, STATIC, SINGULAR, UINT32, channel_num, 9) \
X(a, STATIC, SINGULAR, FIXED32, id, 10) \
X(a, STATIC, SINGULAR, BOOL, uplink_enabled, 16) \
@@ -209,8 +163,8 @@ extern const pb_msgdesc_t Channel_msg;
#define Channel_fields &Channel_msg
/* Maximum encoded size of messages (where known) */
#define ChannelSettings_size 87
#define Channel_size 102
#define ChannelSettings_size 61
#define Channel_size 76
#ifdef __cplusplus
} /* extern "C" */

View File

@@ -0,0 +1,36 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.6 */
#include "config.pb.h"
#if PB_PROTO_HEADER_VERSION != 40
#error Regenerate this file with the current version of nanopb generator.
#endif
PB_BIND(Config, Config, AUTO)
PB_BIND(Config_DeviceConfig, Config_DeviceConfig, AUTO)
PB_BIND(Config_PositionConfig, Config_PositionConfig, AUTO)
PB_BIND(Config_PowerConfig, Config_PowerConfig, AUTO)
PB_BIND(Config_WiFiConfig, Config_WiFiConfig, AUTO)
PB_BIND(Config_DisplayConfig, Config_DisplayConfig, AUTO)
PB_BIND(Config_LoRaConfig, Config_LoRaConfig, 2)

View File

@@ -0,0 +1,361 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.6 */
#ifndef PB_CONFIG_PB_H_INCLUDED
#define PB_CONFIG_PB_H_INCLUDED
#include <pb.h>
#if PB_PROTO_HEADER_VERSION != 40
#error Regenerate this file with the current version of nanopb generator.
#endif
/* Enum definitions */
typedef enum _Config_DeviceConfig_Role {
Config_DeviceConfig_Role_Client = 0,
Config_DeviceConfig_Role_ClientMute = 1,
Config_DeviceConfig_Role_Router = 2,
Config_DeviceConfig_Role_RouterClient = 3
} Config_DeviceConfig_Role;
typedef enum _Config_PositionConfig_PositionFlags {
Config_PositionConfig_PositionFlags_POS_UNDEFINED = 0,
Config_PositionConfig_PositionFlags_POS_ALTITUDE = 1,
Config_PositionConfig_PositionFlags_POS_ALT_MSL = 2,
Config_PositionConfig_PositionFlags_POS_GEO_SEP = 4,
Config_PositionConfig_PositionFlags_POS_DOP = 8,
Config_PositionConfig_PositionFlags_POS_HVDOP = 16,
Config_PositionConfig_PositionFlags_POS_SATINVIEW = 32,
Config_PositionConfig_PositionFlags_POS_SEQ_NOS = 64,
Config_PositionConfig_PositionFlags_POS_TIMESTAMP = 128,
Config_PositionConfig_PositionFlags_POS_HEADING = 256,
Config_PositionConfig_PositionFlags_POS_SPEED = 512
} Config_PositionConfig_PositionFlags;
typedef enum _Config_PowerConfig_ChargeCurrent {
Config_PowerConfig_ChargeCurrent_MAUnset = 0,
Config_PowerConfig_ChargeCurrent_MA100 = 1,
Config_PowerConfig_ChargeCurrent_MA190 = 2,
Config_PowerConfig_ChargeCurrent_MA280 = 3,
Config_PowerConfig_ChargeCurrent_MA360 = 4,
Config_PowerConfig_ChargeCurrent_MA450 = 5,
Config_PowerConfig_ChargeCurrent_MA550 = 6,
Config_PowerConfig_ChargeCurrent_MA630 = 7,
Config_PowerConfig_ChargeCurrent_MA700 = 8,
Config_PowerConfig_ChargeCurrent_MA780 = 9,
Config_PowerConfig_ChargeCurrent_MA880 = 10,
Config_PowerConfig_ChargeCurrent_MA960 = 11,
Config_PowerConfig_ChargeCurrent_MA1000 = 12,
Config_PowerConfig_ChargeCurrent_MA1080 = 13,
Config_PowerConfig_ChargeCurrent_MA1160 = 14,
Config_PowerConfig_ChargeCurrent_MA1240 = 15,
Config_PowerConfig_ChargeCurrent_MA1320 = 16
} Config_PowerConfig_ChargeCurrent;
typedef enum _Config_DisplayConfig_GpsCoordinateFormat {
Config_DisplayConfig_GpsCoordinateFormat_GpsFormatDec = 0,
Config_DisplayConfig_GpsCoordinateFormat_GpsFormatDMS = 1,
Config_DisplayConfig_GpsCoordinateFormat_GpsFormatUTM = 2,
Config_DisplayConfig_GpsCoordinateFormat_GpsFormatMGRS = 3,
Config_DisplayConfig_GpsCoordinateFormat_GpsFormatOLC = 4,
Config_DisplayConfig_GpsCoordinateFormat_GpsFormatOSGR = 5
} Config_DisplayConfig_GpsCoordinateFormat;
typedef enum _Config_LoRaConfig_RegionCode {
Config_LoRaConfig_RegionCode_Unset = 0,
Config_LoRaConfig_RegionCode_US = 1,
Config_LoRaConfig_RegionCode_EU433 = 2,
Config_LoRaConfig_RegionCode_EU868 = 3,
Config_LoRaConfig_RegionCode_CN = 4,
Config_LoRaConfig_RegionCode_JP = 5,
Config_LoRaConfig_RegionCode_ANZ = 6,
Config_LoRaConfig_RegionCode_KR = 7,
Config_LoRaConfig_RegionCode_TW = 8,
Config_LoRaConfig_RegionCode_RU = 9,
Config_LoRaConfig_RegionCode_IN = 10,
Config_LoRaConfig_RegionCode_NZ865 = 11,
Config_LoRaConfig_RegionCode_TH = 12
} Config_LoRaConfig_RegionCode;
typedef enum _Config_LoRaConfig_ModemPreset {
Config_LoRaConfig_ModemPreset_LongFast = 0,
Config_LoRaConfig_ModemPreset_LongSlow = 1,
Config_LoRaConfig_ModemPreset_VLongSlow = 2,
Config_LoRaConfig_ModemPreset_MedSlow = 3,
Config_LoRaConfig_ModemPreset_MedFast = 4,
Config_LoRaConfig_ModemPreset_ShortSlow = 5,
Config_LoRaConfig_ModemPreset_ShortFast = 6
} Config_LoRaConfig_ModemPreset;
/* 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;
typedef struct _Config_DisplayConfig {
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;
pb_size_t ignore_incoming_count;
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;
uint32_t position_flags;
} Config_PositionConfig;
typedef struct _Config_PowerConfig {
Config_PowerConfig_ChargeCurrent charge_current;
bool is_power_saving;
uint32_t on_battery_shutdown_after_secs;
float adc_multiplier_override;
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;
} Config_WiFiConfig;
typedef struct _Config {
pb_size_t which_payloadVariant;
union {
Config_DeviceConfig device;
Config_PositionConfig position;
Config_PowerConfig power;
Config_WiFiConfig wifi;
Config_DisplayConfig display;
Config_LoRaConfig lora;
} payloadVariant;
} Config;
/* Helper constants for enums */
#define _Config_DeviceConfig_Role_MIN Config_DeviceConfig_Role_Client
#define _Config_DeviceConfig_Role_MAX Config_DeviceConfig_Role_RouterClient
#define _Config_DeviceConfig_Role_ARRAYSIZE ((Config_DeviceConfig_Role)(Config_DeviceConfig_Role_RouterClient+1))
#define _Config_PositionConfig_PositionFlags_MIN Config_PositionConfig_PositionFlags_POS_UNDEFINED
#define _Config_PositionConfig_PositionFlags_MAX Config_PositionConfig_PositionFlags_POS_SPEED
#define _Config_PositionConfig_PositionFlags_ARRAYSIZE ((Config_PositionConfig_PositionFlags)(Config_PositionConfig_PositionFlags_POS_SPEED+1))
#define _Config_PowerConfig_ChargeCurrent_MIN Config_PowerConfig_ChargeCurrent_MAUnset
#define _Config_PowerConfig_ChargeCurrent_MAX Config_PowerConfig_ChargeCurrent_MA1320
#define _Config_PowerConfig_ChargeCurrent_ARRAYSIZE ((Config_PowerConfig_ChargeCurrent)(Config_PowerConfig_ChargeCurrent_MA1320+1))
#define _Config_DisplayConfig_GpsCoordinateFormat_MIN Config_DisplayConfig_GpsCoordinateFormat_GpsFormatDec
#define _Config_DisplayConfig_GpsCoordinateFormat_MAX Config_DisplayConfig_GpsCoordinateFormat_GpsFormatOSGR
#define _Config_DisplayConfig_GpsCoordinateFormat_ARRAYSIZE ((Config_DisplayConfig_GpsCoordinateFormat)(Config_DisplayConfig_GpsCoordinateFormat_GpsFormatOSGR+1))
#define _Config_LoRaConfig_RegionCode_MIN Config_LoRaConfig_RegionCode_Unset
#define _Config_LoRaConfig_RegionCode_MAX Config_LoRaConfig_RegionCode_TH
#define _Config_LoRaConfig_RegionCode_ARRAYSIZE ((Config_LoRaConfig_RegionCode)(Config_LoRaConfig_RegionCode_TH+1))
#define _Config_LoRaConfig_ModemPreset_MIN Config_LoRaConfig_ModemPreset_LongFast
#define _Config_LoRaConfig_ModemPreset_MAX Config_LoRaConfig_ModemPreset_ShortFast
#define _Config_LoRaConfig_ModemPreset_ARRAYSIZE ((Config_LoRaConfig_ModemPreset)(Config_LoRaConfig_ModemPreset_ShortFast+1))
#ifdef __cplusplus
extern "C" {
#endif
/* 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}
#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}
#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}}
/* Field tags (for use in manual encoding/decoding) */
#define Config_DeviceConfig_role_tag 1
#define Config_DeviceConfig_serial_disabled_tag 2
#define Config_DeviceConfig_factory_reset_tag 3
#define Config_DeviceConfig_debug_log_enabled_tag 4
#define Config_DeviceConfig_ntp_server_tag 5
#define Config_DisplayConfig_screen_on_secs_tag 1
#define Config_DisplayConfig_gps_format_tag 2
#define Config_DisplayConfig_auto_screen_carousel_secs_tag 3
#define Config_LoRaConfig_tx_power_tag 1
#define Config_LoRaConfig_modem_preset_tag 2
#define Config_LoRaConfig_bandwidth_tag 3
#define Config_LoRaConfig_spread_factor_tag 4
#define Config_LoRaConfig_coding_rate_tag 5
#define Config_LoRaConfig_frequency_offset_tag 6
#define Config_LoRaConfig_region_tag 7
#define Config_LoRaConfig_hop_limit_tag 8
#define Config_LoRaConfig_tx_disabled_tag 9
#define Config_LoRaConfig_ignore_incoming_tag 103
#define Config_PositionConfig_position_broadcast_secs_tag 1
#define Config_PositionConfig_position_broadcast_smart_disabled_tag 2
#define Config_PositionConfig_fixed_position_tag 3
#define Config_PositionConfig_gps_disabled_tag 5
#define Config_PositionConfig_gps_update_interval_tag 6
#define Config_PositionConfig_gps_attempt_time_tag 7
#define Config_PositionConfig_position_flags_tag 10
#define Config_PowerConfig_charge_current_tag 1
#define Config_PowerConfig_is_power_saving_tag 2
#define Config_PowerConfig_on_battery_shutdown_after_secs_tag 4
#define Config_PowerConfig_adc_multiplier_override_tag 6
#define Config_PowerConfig_wait_bluetooth_secs_tag 7
#define Config_PowerConfig_mesh_sds_timeout_secs_tag 9
#define Config_PowerConfig_sds_secs_tag 10
#define Config_PowerConfig_ls_secs_tag 11
#define Config_PowerConfig_min_wake_secs_tag 12
#define Config_WiFiConfig_ssid_tag 1
#define Config_WiFiConfig_psk_tag 2
#define Config_WiFiConfig_ap_mode_tag 3
#define Config_WiFiConfig_ap_hidden_tag 4
#define Config_device_tag 1
#define Config_position_tag 2
#define Config_power_tag 3
#define Config_wifi_tag 4
#define Config_display_tag 5
#define Config_lora_tag 6
/* Struct field encoding specification for nanopb */
#define Config_FIELDLIST(X, a) \
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,device,payloadVariant.device), 1) \
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,position,payloadVariant.position), 2) \
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,power,payloadVariant.power), 3) \
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,wifi,payloadVariant.wifi), 4) \
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,display,payloadVariant.display), 5) \
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,lora,payloadVariant.lora), 6)
#define Config_CALLBACK NULL
#define Config_DEFAULT NULL
#define Config_payloadVariant_device_MSGTYPE Config_DeviceConfig
#define Config_payloadVariant_position_MSGTYPE Config_PositionConfig
#define Config_payloadVariant_power_MSGTYPE Config_PowerConfig
#define Config_payloadVariant_wifi_MSGTYPE Config_WiFiConfig
#define Config_payloadVariant_display_MSGTYPE Config_DisplayConfig
#define Config_payloadVariant_lora_MSGTYPE Config_LoRaConfig
#define Config_DeviceConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UENUM, role, 1) \
X(a, STATIC, SINGULAR, BOOL, serial_disabled, 2) \
X(a, STATIC, SINGULAR, BOOL, factory_reset, 3) \
X(a, STATIC, SINGULAR, BOOL, debug_log_enabled, 4) \
X(a, STATIC, SINGULAR, STRING, ntp_server, 5)
#define Config_DeviceConfig_CALLBACK NULL
#define Config_DeviceConfig_DEFAULT NULL
#define Config_PositionConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UINT32, position_broadcast_secs, 1) \
X(a, STATIC, SINGULAR, BOOL, position_broadcast_smart_disabled, 2) \
X(a, STATIC, SINGULAR, BOOL, fixed_position, 3) \
X(a, STATIC, SINGULAR, BOOL, gps_disabled, 5) \
X(a, STATIC, SINGULAR, UINT32, gps_update_interval, 6) \
X(a, STATIC, SINGULAR, UINT32, gps_attempt_time, 7) \
X(a, STATIC, SINGULAR, UINT32, position_flags, 10)
#define Config_PositionConfig_CALLBACK NULL
#define Config_PositionConfig_DEFAULT NULL
#define Config_PowerConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UENUM, charge_current, 1) \
X(a, STATIC, SINGULAR, BOOL, is_power_saving, 2) \
X(a, STATIC, SINGULAR, UINT32, on_battery_shutdown_after_secs, 4) \
X(a, STATIC, SINGULAR, FLOAT, adc_multiplier_override, 6) \
X(a, STATIC, SINGULAR, UINT32, wait_bluetooth_secs, 7) \
X(a, STATIC, SINGULAR, UINT32, mesh_sds_timeout_secs, 9) \
X(a, STATIC, SINGULAR, UINT32, sds_secs, 10) \
X(a, STATIC, SINGULAR, UINT32, ls_secs, 11) \
X(a, STATIC, SINGULAR, UINT32, min_wake_secs, 12)
#define Config_PowerConfig_CALLBACK NULL
#define Config_PowerConfig_DEFAULT NULL
#define Config_WiFiConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, STRING, ssid, 1) \
X(a, STATIC, SINGULAR, STRING, psk, 2) \
X(a, STATIC, SINGULAR, BOOL, ap_mode, 3) \
X(a, STATIC, SINGULAR, BOOL, ap_hidden, 4)
#define Config_WiFiConfig_CALLBACK NULL
#define Config_WiFiConfig_DEFAULT NULL
#define Config_DisplayConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UINT32, screen_on_secs, 1) \
X(a, STATIC, SINGULAR, UENUM, gps_format, 2) \
X(a, STATIC, SINGULAR, UINT32, auto_screen_carousel_secs, 3)
#define Config_DisplayConfig_CALLBACK NULL
#define Config_DisplayConfig_DEFAULT NULL
#define Config_LoRaConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, INT32, tx_power, 1) \
X(a, STATIC, SINGULAR, UENUM, modem_preset, 2) \
X(a, STATIC, SINGULAR, UINT32, bandwidth, 3) \
X(a, STATIC, SINGULAR, UINT32, spread_factor, 4) \
X(a, STATIC, SINGULAR, UINT32, coding_rate, 5) \
X(a, STATIC, SINGULAR, FLOAT, frequency_offset, 6) \
X(a, STATIC, SINGULAR, UENUM, region, 7) \
X(a, STATIC, SINGULAR, UINT32, hop_limit, 8) \
X(a, STATIC, SINGULAR, BOOL, tx_disabled, 9) \
X(a, STATIC, REPEATED, UINT32, ignore_incoming, 103)
#define Config_LoRaConfig_CALLBACK NULL
#define Config_LoRaConfig_DEFAULT NULL
extern const pb_msgdesc_t Config_msg;
extern const pb_msgdesc_t Config_DeviceConfig_msg;
extern const pb_msgdesc_t Config_PositionConfig_msg;
extern const pb_msgdesc_t Config_PowerConfig_msg;
extern const pb_msgdesc_t Config_WiFiConfig_msg;
extern const pb_msgdesc_t Config_DisplayConfig_msg;
extern const pb_msgdesc_t Config_LoRaConfig_msg;
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
#define Config_fields &Config_msg
#define Config_DeviceConfig_fields &Config_DeviceConfig_msg
#define Config_PositionConfig_fields &Config_PositionConfig_msg
#define Config_PowerConfig_fields &Config_PowerConfig_msg
#define Config_WiFiConfig_fields &Config_WiFiConfig_msg
#define Config_DisplayConfig_fields &Config_DisplayConfig_msg
#define Config_LoRaConfig_fields &Config_LoRaConfig_msg
/* Maximum encoded size of messages (where known) */
#define Config_DeviceConfig_size 42
#define Config_DisplayConfig_size 14
#define Config_LoRaConfig_size 67
#define Config_PositionConfig_size 30
#define Config_PowerConfig_size 45
#define Config_WiFiConfig_size 103
#define Config_size 105
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif

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 832
#define DeviceState_size 19327
#define ChannelFile_size 630
#define DeviceState_size 23728
#define OEMStore_size 2106
#ifdef __cplusplus

View File

@@ -1,24 +1,15 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.5 */
/* Generated by nanopb-0.4.6 */
#include "radioconfig.pb.h"
#include "localonly.pb.h"
#if PB_PROTO_HEADER_VERSION != 40
#error Regenerate this file with the current version of nanopb generator.
#endif
PB_BIND(RadioConfig, RadioConfig, 2)
PB_BIND(RadioConfig_UserPreferences, RadioConfig_UserPreferences, 2)
PB_BIND(LocalConfig, LocalConfig, 2)
PB_BIND(LocalModuleConfig, LocalModuleConfig, 2)

View File

@@ -0,0 +1,148 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.6 */
#ifndef PB_LOCALONLY_PB_H_INCLUDED
#define PB_LOCALONLY_PB_H_INCLUDED
#include <pb.h>
#include "config.pb.h"
#include "module_config.pb.h"
#if PB_PROTO_HEADER_VERSION != 40
#error Regenerate this file with the current version of nanopb generator.
#endif
/* Struct definitions */
typedef struct _LocalConfig {
/* The part of the config that is specific to the Device */
bool has_device;
Config_DeviceConfig device;
/* The part of the config that is specific to the GPS Position */
bool has_position;
Config_PositionConfig position;
/* The part of the config that is specific to the Power settings */
bool has_power;
Config_PowerConfig power;
/* The part of the config that is specific to the Wifi Settings */
bool has_wifi;
Config_WiFiConfig wifi;
/* The part of the config that is specific to the Display */
bool has_display;
Config_DisplayConfig display;
/* The part of the config that is specific to the Lora Radio */
bool has_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 {
/* The part of the config that is specific to the MQTT module */
bool has_mqtt;
ModuleConfig_MQTTConfig mqtt;
/* The part of the config that is specific to the Serial module */
bool has_serial;
ModuleConfig_SerialConfig serial;
/* The part of the config that is specific to the ExternalNotification module */
bool has_external_notification;
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;
/* The part of the config that is specific to the RangeTest module */
bool has_range_test;
ModuleConfig_RangeTestConfig range_test;
/* The part of the config that is specific to the Telemetry module */
bool has_telemetry;
ModuleConfig_TelemetryConfig telemetry;
/* The part of the config that is specific to the Canned Message module */
bool has_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;
#ifdef __cplusplus
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, 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
#define LocalConfig_position_tag 2
#define LocalConfig_power_tag 3
#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
#define LocalModuleConfig_store_forward_tag 4
#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) \
X(a, STATIC, OPTIONAL, MESSAGE, device, 1) \
X(a, STATIC, OPTIONAL, MESSAGE, position, 2) \
X(a, STATIC, OPTIONAL, MESSAGE, power, 3) \
X(a, STATIC, OPTIONAL, MESSAGE, wifi, 4) \
X(a, STATIC, OPTIONAL, MESSAGE, display, 5) \
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
#define LocalConfig_position_MSGTYPE Config_PositionConfig
#define LocalConfig_power_MSGTYPE Config_PowerConfig
#define LocalConfig_wifi_MSGTYPE Config_WiFiConfig
#define LocalConfig_display_MSGTYPE Config_DisplayConfig
#define LocalConfig_lora_MSGTYPE Config_LoRaConfig
#define LocalModuleConfig_FIELDLIST(X, a) \
X(a, STATIC, OPTIONAL, MESSAGE, mqtt, 1) \
X(a, STATIC, OPTIONAL, MESSAGE, serial, 2) \
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, SINGULAR, UINT32, version, 8)
#define LocalModuleConfig_CALLBACK NULL
#define LocalModuleConfig_DEFAULT NULL
#define LocalModuleConfig_mqtt_MSGTYPE ModuleConfig_MQTTConfig
#define LocalModuleConfig_serial_MSGTYPE ModuleConfig_SerialConfig
#define LocalModuleConfig_external_notification_MSGTYPE ModuleConfig_ExternalNotificationConfig
#define LocalModuleConfig_store_forward_MSGTYPE ModuleConfig_StoreForwardConfig
#define LocalModuleConfig_range_test_MSGTYPE ModuleConfig_RangeTestConfig
#define LocalModuleConfig_telemetry_MSGTYPE ModuleConfig_TelemetryConfig
#define LocalModuleConfig_canned_message_MSGTYPE ModuleConfig_CannedMessageConfig
extern const pb_msgdesc_t LocalConfig_msg;
extern const pb_msgdesc_t LocalModuleConfig_msg;
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
#define LocalConfig_fields &LocalConfig_msg
#define LocalModuleConfig_fields &LocalModuleConfig_msg
/* Maximum encoded size of messages (where known) */
#define LocalConfig_size 319
#define LocalModuleConfig_size 288
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif

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
@@ -45,6 +45,8 @@ PB_BIND(ToRadio, ToRadio, 2)
PB_BIND(ToRadio_PeerInfo, ToRadio_PeerInfo, AUTO)
PB_BIND(Compressed, Compressed, AUTO)

View File

@@ -1,9 +1,11 @@
/* 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 "module_config.pb.h"
#include "portnums.pb.h"
#include "telemetry.pb.h"
@@ -65,45 +67,14 @@ typedef enum _HardwareModel {
HardwareModel_NANO_G1 = 41,
/* nRF52840 Dongle : https://www.nordicsemi.com/Products/Development-hardware/nrf52840-dongle/ */
HardwareModel_NRF52840_PCA10059 = 42,
/* Custom Disaster Radio esp32 v3 device https://github.com/sudomesh/disaster-radio/tree/master/hardware/board_esp32_v3 */
HardwareModel_DR_DEV = 43,
/* M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, Paper) https://m5stack.com/ */
HardwareModel_M5STACK = 44,
/* Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits. */
HardwareModel_PRIVATE_HW = 255
} HardwareModel;
/* The team colors are based on the names of "friendly teams" in ATAK:
https://github.com/deptofdefense/AndroidTacticalAssaultKit-CIV/blob/master/atak/ATAK/app/src/main/assets/filters/team_filters.xml */
typedef enum _Team {
/* the default (unset) is "achromatic" (unaffiliated) */
Team_CLEAR = 0,
/* TODO: REPLACE */
Team_CYAN = 1,
/* TODO: REPLACE */
Team_WHITE = 2,
/* TODO: REPLACE */
Team_YELLOW = 3,
/* TODO: REPLACE */
Team_ORANGE = 4,
/* TODO: REPLACE */
Team_MAGENTA = 5,
/* TODO: REPLACE */
Team_RED = 6,
/* TODO: REPLACE */
Team_MAROON = 7,
/* TODO: REPLACE */
Team_PURPLE = 8,
/* TODO: REPLACE */
Team_DARK_BLUE = 9,
/* TODO: REPLACE */
Team_BLUE = 10,
/* TODO: REPLACE */
Team_TEAL = 11,
/* TODO: REPLACE */
Team_GREEN = 12,
/* TODO: REPLACE */
Team_DARK_GREEN = 13,
/* TODO: REPLACE */
Team_BROWN = 14
} Team;
/* Shared constants between device and phone */
typedef enum _Constants {
/* First enum must be zero, and we are just using this enum to
@@ -164,18 +135,17 @@ typedef enum _Position_LocSource {
Position_LocSource_LOCSRC_GPS_EXTERNAL = 3
} Position_LocSource;
/* The team colors are based on the names of "friendly teams" in ATAK:
https://github.com/deptofdefense/AndroidTacticalAssaultKit-CIV/blob/master/atak/ATAK/app/src/main/assets/filters/team_filters.xml */
/* Shared constants between device and phone */
typedef enum _Position_AltSource {
/* the default (unset) is "achromatic" (unaffiliated) */
/* First enum must be zero, and we are just using this enum to
pass int constants between two very different environments */
Position_AltSource_ALTSRC_UNSPECIFIED = 0,
/* TODO: REPLACE */
/* From mesh.options
note: this payload length is ONLY the bytes that are sent inside of the Data protobuf (excluding protobuf overhead). The 16 byte header is
outside of this envelope */
Position_AltSource_ALTSRC_MANUAL_ENTRY = 1,
/* TODO: REPLACE */
Position_AltSource_ALTSRC_GPS_INTERNAL = 2,
/* TODO: REPLACE */
Position_AltSource_ALTSRC_GPS_EXTERNAL = 3,
/* TODO: REPLACE */
Position_AltSource_ALTSRC_BAROMETRIC = 4
} Position_AltSource;
@@ -232,14 +202,15 @@ typedef enum _MeshPacket_Priority {
MeshPacket_Priority_MAX = 127
} MeshPacket_Priority;
/* The team colors are based on the names of "friendly teams" in ATAK:
https://github.com/deptofdefense/AndroidTacticalAssaultKit-CIV/blob/master/atak/ATAK/app/src/main/assets/filters/team_filters.xml */
/* Shared constants between device and phone */
typedef enum _MeshPacket_Delayed {
/* the default (unset) is "achromatic" (unaffiliated) */
/* First enum must be zero, and we are just using this enum to
pass int constants between two very different environments */
MeshPacket_Delayed_NO_DELAY = 0,
/* TODO: REPLACE */
/* From mesh.options
note: this payload length is ONLY the bytes that are sent inside of the Data protobuf (excluding protobuf overhead). The 16 byte header is
outside of this envelope */
MeshPacket_Delayed_DELAYED_BROADCAST = 1,
/* TODO: REPLACE */
MeshPacket_Delayed_DELAYED_DIRECT = 2
} MeshPacket_Delayed;
@@ -266,18 +237,24 @@ typedef enum _LogRecord_Level {
} LogRecord_Level;
/* Struct definitions */
typedef PB_BYTES_ARRAY_T(237) Compressed_data_t;
typedef struct _Compressed {
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.
@@ -287,13 +264,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
@@ -302,139 +279,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 region[12];
/* Deprecated! ONLY USED IN DEVICE CODE (for upgrading old 1.0 firmwares) DO NOT READ ELSEWHERE.
The region code for my radio (US, CN, etc...)
Note: This string is deprecated.
The 1.0 builds populate it based on the flashed firmware name.
But for newer builds this string will be unpopulated (missing/null).
For those builds you should instead look at the new read/write region enum in UserSettings
The format of this string was 1.0-US or 1.0-CN etc.. Or empty string if unset. */
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 {
uint32_t app_version;
bool mqtt_gateway;
/* PortNum to determine the how to handle the compressed payload. */
uint32_t app_version;
/* Compressed data. */
bool mqtt_gateway;
} ToRadio_PeerInfo;
/* Broadcast when a newly powered mesh node wants to find a node num it can use
@@ -462,82 +434,71 @@ 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;
/* Participants in the same network can self-group into different teams.
Short-term this can be used to visually differentiate them on the map;
in the longer term it could also help users to semi-automatically
select or ignore messages according to team affiliation.
In total, 14 teams are defined (encoded in 4 bits) */
Team team;
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;
typedef PB_BYTES_ARRAY_T(237) Data_payload_compressed_t;
/* (Formerly called SubPacket)
The payload portion fo a packet, this is the actual bytes that are sent
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 */
pb_size_t which_payloadVariant;
union {
Data_payload_t payload;
Data_payload_compressed_t payload_compressed;
};
/* TODO: REPLACE */
bool want_response;
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. */
uint32_t dest;
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 source;
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 request_id;
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 reply_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 emoji;
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;
/* Location structure */
bool has_location;
Location location;
Location location;
} Data;
/* The bluetooth to device link:
@@ -558,33 +519,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;
@@ -596,10 +560,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.
@@ -607,15 +571,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.
@@ -626,21 +589,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
@@ -650,12 +613,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.
@@ -665,30 +630,60 @@ 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;
/* Include module config */
ModuleConfig moduleConfig;
/* 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;
@@ -697,10 +692,6 @@ typedef struct _ToRadio {
#define _HardwareModel_MAX HardwareModel_PRIVATE_HW
#define _HardwareModel_ARRAYSIZE ((HardwareModel)(HardwareModel_PRIVATE_HW+1))
#define _Team_MIN Team_CLEAR
#define _Team_MAX Team_BROWN
#define _Team_ARRAYSIZE ((Team)(Team_BROWN+1))
#define _Constants_MIN Constants_Unused
#define _Constants_MAX Constants_DATA_PAYLOAD_LEN
#define _Constants_ARRAYSIZE ((Constants)(Constants_DATA_PAYLOAD_LEN+1))
@@ -740,33 +731,37 @@ extern "C" {
/* Initializer values for message structs */
#define Position_init_default {0, 0, 0, 0, _Position_LocSource_MIN, _Position_AltSource_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define User_init_default {"", "", "", {0}, _HardwareModel_MIN, 0, _Team_MIN, 0, 0, 0}
#define User_init_default {"", "", "", {0}, _HardwareModel_MIN, 0, 0, 0, 0}
#define RouteDiscovery_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}}
#define Routing_init_default {0, {RouteDiscovery_init_default}}
#define Data_init_default {_PortNum_MIN, 0, {{0, {0}}}, 0, 0, 0, 0, 0, 0, false, Location_init_default}
#define Data_init_default {_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, Location_init_default}
#define Location_init_default {0, 0, 0, 0, 0}
#define MeshPacket_init_default {0, 0, 0, 0, {Data_init_default}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN, 0, _MeshPacket_Delayed_MIN}
#define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0, 0, false, DeviceMetrics_init_default}
#define MyNodeInfo_init_default {0, 0, "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}
#define MyNodeInfo_init_default {0, 0, "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}
#define LogRecord_init_default {"", 0, "", _LogRecord_Level_MIN}
#define FromRadio_init_default {0, 0, {MyNodeInfo_init_default}}
#define ToRadio_init_default {0, {MeshPacket_init_default}}
#define ToRadio_PeerInfo_init_default {0, 0}
#define Compressed_init_default {_PortNum_MIN, {0, {0}}}
#define Position_init_zero {0, 0, 0, 0, _Position_LocSource_MIN, _Position_AltSource_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define User_init_zero {"", "", "", {0}, _HardwareModel_MIN, 0, _Team_MIN, 0, 0, 0}
#define User_init_zero {"", "", "", {0}, _HardwareModel_MIN, 0, 0, 0, 0}
#define RouteDiscovery_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}}
#define Routing_init_zero {0, {RouteDiscovery_init_zero}}
#define Data_init_zero {_PortNum_MIN, 0, {{0, {0}}}, 0, 0, 0, 0, 0, 0, false, Location_init_zero}
#define Data_init_zero {_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, Location_init_zero}
#define Location_init_zero {0, 0, 0, 0, 0}
#define MeshPacket_init_zero {0, 0, 0, 0, {Data_init_zero}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN, 0, _MeshPacket_Delayed_MIN}
#define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0, 0, false, DeviceMetrics_init_zero}
#define MyNodeInfo_init_zero {0, 0, "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}
#define MyNodeInfo_init_zero {0, 0, "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}
#define LogRecord_init_zero {"", 0, "", _LogRecord_Level_MIN}
#define FromRadio_init_zero {0, 0, {MyNodeInfo_init_zero}}
#define ToRadio_init_zero {0, {MeshPacket_init_zero}}
#define ToRadio_PeerInfo_init_zero {0, 0}
#define Compressed_init_zero {_PortNum_MIN, {0, {0}}}
/* Field tags (for use in manual encoding/decoding) */
#define Compressed_portnum_tag 1
#define Compressed_data_tag 2
#define Location_id_tag 1
#define Location_latitude_i_tag 2
#define Location_longitude_i_tag 3
@@ -778,7 +773,6 @@ extern "C" {
#define LogRecord_level_tag 4
#define MyNodeInfo_my_node_num_tag 1
#define MyNodeInfo_has_gps_tag 2
#define MyNodeInfo_region_tag 4
#define MyNodeInfo_firmware_version_tag 6
#define MyNodeInfo_error_code_tag 7
#define MyNodeInfo_error_address_tag 8
@@ -824,13 +818,11 @@ extern "C" {
#define User_macaddr_tag 4
#define User_hw_model_tag 6
#define User_is_licensed_tag 7
#define User_team_tag 8
#define User_tx_power_dbm_tag 10
#define User_ant_gain_dbi_tag 11
#define User_ant_azimuth_tag 12
#define Data_portnum_tag 1
#define Data_payload_tag 2
#define Data_payload_compressed_tag 10
#define Data_want_response_tag 3
#define Data_dest_tag 4
#define Data_source_tag 5
@@ -863,9 +855,11 @@ 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
#define FromRadio_moduleConfig_tag 10
#define FromRadio_packet_tag 11
#define ToRadio_packet_tag 2
#define ToRadio_peer_info_tag 3
@@ -906,7 +900,6 @@ X(a, STATIC, SINGULAR, STRING, short_name, 3) \
X(a, STATIC, SINGULAR, FIXED_LENGTH_BYTES, macaddr, 4) \
X(a, STATIC, SINGULAR, UENUM, hw_model, 6) \
X(a, STATIC, SINGULAR, BOOL, is_licensed, 7) \
X(a, STATIC, SINGULAR, UENUM, team, 8) \
X(a, STATIC, SINGULAR, UINT32, tx_power_dbm, 10) \
X(a, STATIC, SINGULAR, UINT32, ant_gain_dbi, 11) \
X(a, STATIC, SINGULAR, UINT32, ant_azimuth, 12)
@@ -929,15 +922,14 @@ X(a, STATIC, ONEOF, UENUM, (variant,error_reason,error_reason), 3)
#define Data_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UENUM, portnum, 1) \
X(a, STATIC, ONEOF, BYTES, (payloadVariant,payload,payload), 2) \
X(a, STATIC, SINGULAR, BYTES, payload, 2) \
X(a, STATIC, SINGULAR, BOOL, want_response, 3) \
X(a, STATIC, SINGULAR, FIXED32, dest, 4) \
X(a, STATIC, SINGULAR, FIXED32, source, 5) \
X(a, STATIC, SINGULAR, FIXED32, request_id, 6) \
X(a, STATIC, SINGULAR, FIXED32, reply_id, 7) \
X(a, STATIC, SINGULAR, FIXED32, emoji, 8) \
X(a, STATIC, OPTIONAL, MESSAGE, location, 9) \
X(a, STATIC, ONEOF, BYTES, (payloadVariant,payload_compressed,payload_compressed), 10)
X(a, STATIC, OPTIONAL, MESSAGE, location, 9)
#define Data_CALLBACK NULL
#define Data_DEFAULT NULL
#define Data_location_MSGTYPE Location
@@ -985,7 +977,6 @@ X(a, STATIC, OPTIONAL, MESSAGE, device_metrics, 6)
#define MyNodeInfo_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UINT32, my_node_num, 1) \
X(a, STATIC, SINGULAR, BOOL, has_gps, 2) \
X(a, STATIC, SINGULAR, STRING, region, 4) \
X(a, STATIC, SINGULAR, STRING, firmware_version, 6) \
X(a, STATIC, SINGULAR, UENUM, error_code, 7) \
X(a, STATIC, SINGULAR, UINT32, error_address, 8) \
@@ -1015,15 +1006,19 @@ 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) \
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,moduleConfig,moduleConfig), 10) \
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,packet,packet), 11)
#define FromRadio_CALLBACK NULL
#define FromRadio_DEFAULT NULL
#define FromRadio_payloadVariant_my_info_MSGTYPE MyNodeInfo
#define FromRadio_payloadVariant_node_info_MSGTYPE NodeInfo
#define FromRadio_payloadVariant_config_MSGTYPE Config
#define FromRadio_payloadVariant_log_record_MSGTYPE LogRecord
#define FromRadio_payloadVariant_moduleConfig_MSGTYPE ModuleConfig
#define FromRadio_payloadVariant_packet_MSGTYPE MeshPacket
#define ToRadio_FIELDLIST(X, a) \
@@ -1042,6 +1037,12 @@ X(a, STATIC, SINGULAR, BOOL, mqtt_gateway, 2)
#define ToRadio_PeerInfo_CALLBACK NULL
#define ToRadio_PeerInfo_DEFAULT NULL
#define Compressed_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UENUM, portnum, 1) \
X(a, STATIC, SINGULAR, BYTES, data, 2)
#define Compressed_CALLBACK NULL
#define Compressed_DEFAULT NULL
extern const pb_msgdesc_t Position_msg;
extern const pb_msgdesc_t User_msg;
extern const pb_msgdesc_t RouteDiscovery_msg;
@@ -1055,6 +1056,7 @@ extern const pb_msgdesc_t LogRecord_msg;
extern const pb_msgdesc_t FromRadio_msg;
extern const pb_msgdesc_t ToRadio_msg;
extern const pb_msgdesc_t ToRadio_PeerInfo_msg;
extern const pb_msgdesc_t Compressed_msg;
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
#define Position_fields &Position_msg
@@ -1070,21 +1072,23 @@ extern const pb_msgdesc_t ToRadio_PeerInfo_msg;
#define FromRadio_fields &FromRadio_msg
#define ToRadio_fields &ToRadio_msg
#define ToRadio_PeerInfo_fields &ToRadio_PeerInfo_msg
#define Compressed_fields &Compressed_msg
/* Maximum encoded size of messages (where known) */
#define Compressed_size 243
#define Data_size 296
#define FromRadio_size 356
#define Location_size 24
#define LogRecord_size 81
#define MeshPacket_size 347
#define MyNodeInfo_size 210
#define NodeInfo_size 283
#define MyNodeInfo_size 197
#define NodeInfo_size 281
#define Position_size 142
#define RouteDiscovery_size 40
#define Routing_size 42
#define ToRadio_PeerInfo_size 8
#define ToRadio_size 350
#define User_size 97
#define User_size 95
#ifdef __cplusplus
} /* extern "C" */

View File

@@ -0,0 +1,36 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.6 */
#include "module_config.pb.h"
#if PB_PROTO_HEADER_VERSION != 40
#error Regenerate this file with the current version of nanopb generator.
#endif
PB_BIND(ModuleConfig, ModuleConfig, AUTO)
PB_BIND(ModuleConfig_MQTTConfig, ModuleConfig_MQTTConfig, AUTO)
PB_BIND(ModuleConfig_SerialConfig, ModuleConfig_SerialConfig, AUTO)
PB_BIND(ModuleConfig_ExternalNotificationConfig, ModuleConfig_ExternalNotificationConfig, AUTO)
PB_BIND(ModuleConfig_StoreForwardConfig, ModuleConfig_StoreForwardConfig, AUTO)
PB_BIND(ModuleConfig_RangeTestConfig, ModuleConfig_RangeTestConfig, AUTO)
PB_BIND(ModuleConfig_TelemetryConfig, ModuleConfig_TelemetryConfig, AUTO)
PB_BIND(ModuleConfig_CannedMessageConfig, ModuleConfig_CannedMessageConfig, AUTO)

View File

@@ -0,0 +1,357 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.6 */
#ifndef PB_MODULE_CONFIG_PB_H_INCLUDED
#define PB_MODULE_CONFIG_PB_H_INCLUDED
#include <pb.h>
#include "telemetry.pb.h"
#if PB_PROTO_HEADER_VERSION != 40
#error Regenerate this file with the current version of nanopb generator.
#endif
/* Enum definitions */
typedef enum _ModuleConfig_SerialConfig_Serial_Baud {
ModuleConfig_SerialConfig_Serial_Baud_BAUD_Default = 0,
ModuleConfig_SerialConfig_Serial_Baud_BAUD_110 = 1,
ModuleConfig_SerialConfig_Serial_Baud_BAUD_300 = 2,
ModuleConfig_SerialConfig_Serial_Baud_BAUD_600 = 3,
ModuleConfig_SerialConfig_Serial_Baud_BAUD_1200 = 4,
ModuleConfig_SerialConfig_Serial_Baud_BAUD_2400 = 5,
ModuleConfig_SerialConfig_Serial_Baud_BAUD_4800 = 6,
ModuleConfig_SerialConfig_Serial_Baud_BAUD_9600 = 7,
ModuleConfig_SerialConfig_Serial_Baud_BAUD_19200 = 8,
ModuleConfig_SerialConfig_Serial_Baud_BAUD_38400 = 9,
ModuleConfig_SerialConfig_Serial_Baud_BAUD_57600 = 10,
ModuleConfig_SerialConfig_Serial_Baud_BAUD_115200 = 11,
ModuleConfig_SerialConfig_Serial_Baud_BAUD_230400 = 12,
ModuleConfig_SerialConfig_Serial_Baud_BAUD_460800 = 13,
ModuleConfig_SerialConfig_Serial_Baud_BAUD_576000 = 14,
ModuleConfig_SerialConfig_Serial_Baud_BAUD_921600 = 15
} ModuleConfig_SerialConfig_Serial_Baud;
typedef enum _ModuleConfig_SerialConfig_Serial_Mode {
ModuleConfig_SerialConfig_Serial_Mode_MODE_Default = 0,
ModuleConfig_SerialConfig_Serial_Mode_MODE_SIMPLE = 1,
ModuleConfig_SerialConfig_Serial_Mode_MODE_PROTO = 2
} ModuleConfig_SerialConfig_Serial_Mode;
typedef enum _ModuleConfig_CannedMessageConfig_InputEventChar {
ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE = 0,
ModuleConfig_CannedMessageConfig_InputEventChar_KEY_UP = 17,
ModuleConfig_CannedMessageConfig_InputEventChar_KEY_DOWN = 18,
ModuleConfig_CannedMessageConfig_InputEventChar_KEY_LEFT = 19,
ModuleConfig_CannedMessageConfig_InputEventChar_KEY_RIGHT = 20,
ModuleConfig_CannedMessageConfig_InputEventChar_KEY_SELECT = 10,
ModuleConfig_CannedMessageConfig_InputEventChar_KEY_BACK = 27,
ModuleConfig_CannedMessageConfig_InputEventChar_KEY_CANCEL = 24
} ModuleConfig_CannedMessageConfig_InputEventChar;
/* 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;
} ModuleConfig_CannedMessageConfig;
typedef struct _ModuleConfig_ExternalNotificationConfig {
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;
} ModuleConfig_MQTTConfig;
typedef struct _ModuleConfig_RangeTestConfig {
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;
} ModuleConfig_SerialConfig;
typedef struct _ModuleConfig_StoreForwardConfig {
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;
} ModuleConfig_TelemetryConfig;
/* Module Config */
typedef struct _ModuleConfig {
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;
} ModuleConfig;
/* Helper constants for enums */
#define _ModuleConfig_SerialConfig_Serial_Baud_MIN ModuleConfig_SerialConfig_Serial_Baud_BAUD_Default
#define _ModuleConfig_SerialConfig_Serial_Baud_MAX ModuleConfig_SerialConfig_Serial_Baud_BAUD_921600
#define _ModuleConfig_SerialConfig_Serial_Baud_ARRAYSIZE ((ModuleConfig_SerialConfig_Serial_Baud)(ModuleConfig_SerialConfig_Serial_Baud_BAUD_921600+1))
#define _ModuleConfig_SerialConfig_Serial_Mode_MIN ModuleConfig_SerialConfig_Serial_Mode_MODE_Default
#define _ModuleConfig_SerialConfig_Serial_Mode_MAX ModuleConfig_SerialConfig_Serial_Mode_MODE_PROTO
#define _ModuleConfig_SerialConfig_Serial_Mode_ARRAYSIZE ((ModuleConfig_SerialConfig_Serial_Mode)(ModuleConfig_SerialConfig_Serial_Mode_MODE_PROTO+1))
#define _ModuleConfig_CannedMessageConfig_InputEventChar_MIN ModuleConfig_CannedMessageConfig_InputEventChar_KEY_NONE
#define _ModuleConfig_CannedMessageConfig_InputEventChar_MAX ModuleConfig_CannedMessageConfig_InputEventChar_KEY_BACK
#define _ModuleConfig_CannedMessageConfig_InputEventChar_ARRAYSIZE ((ModuleConfig_CannedMessageConfig_InputEventChar)(ModuleConfig_CannedMessageConfig_InputEventChar_KEY_BACK+1))
#ifdef __cplusplus
extern "C" {
#endif
/* Initializer values for message structs */
#define ModuleConfig_init_default {0, {ModuleConfig_MQTTConfig_init_default}}
#define ModuleConfig_MQTTConfig_init_default {0, "", "", "", 0}
#define ModuleConfig_SerialConfig_init_default {0, 0, 0, 0, _ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _ModuleConfig_SerialConfig_Serial_Mode_MIN}
#define ModuleConfig_ExternalNotificationConfig_init_default {0, 0, 0, 0, 0, 0}
#define ModuleConfig_StoreForwardConfig_init_default {0, 0, 0, 0, 0}
#define ModuleConfig_RangeTestConfig_init_default {0, 0, 0}
#define ModuleConfig_TelemetryConfig_init_default {0, 0, 0, 0, 0, 0, 0, _TelemetrySensorType_MIN, 0}
#define ModuleConfig_CannedMessageConfig_init_default {0, 0, 0, 0, _ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _ModuleConfig_CannedMessageConfig_InputEventChar_MIN, 0, 0, "", 0}
#define ModuleConfig_init_zero {0, {ModuleConfig_MQTTConfig_init_zero}}
#define ModuleConfig_MQTTConfig_init_zero {0, "", "", "", 0}
#define ModuleConfig_SerialConfig_init_zero {0, 0, 0, 0, _ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _ModuleConfig_SerialConfig_Serial_Mode_MIN}
#define ModuleConfig_ExternalNotificationConfig_init_zero {0, 0, 0, 0, 0, 0}
#define ModuleConfig_StoreForwardConfig_init_zero {0, 0, 0, 0, 0}
#define ModuleConfig_RangeTestConfig_init_zero {0, 0, 0}
#define ModuleConfig_TelemetryConfig_init_zero {0, 0, 0, 0, 0, 0, 0, _TelemetrySensorType_MIN, 0}
#define ModuleConfig_CannedMessageConfig_init_zero {0, 0, 0, 0, _ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _ModuleConfig_CannedMessageConfig_InputEventChar_MIN, 0, 0, "", 0}
/* Field tags (for use in manual encoding/decoding) */
#define ModuleConfig_CannedMessageConfig_rotary1_enabled_tag 1
#define ModuleConfig_CannedMessageConfig_inputbroker_pin_a_tag 2
#define ModuleConfig_CannedMessageConfig_inputbroker_pin_b_tag 3
#define ModuleConfig_CannedMessageConfig_inputbroker_pin_press_tag 4
#define ModuleConfig_CannedMessageConfig_inputbroker_event_cw_tag 5
#define ModuleConfig_CannedMessageConfig_inputbroker_event_ccw_tag 6
#define ModuleConfig_CannedMessageConfig_inputbroker_event_press_tag 7
#define ModuleConfig_CannedMessageConfig_updown1_enabled_tag 8
#define ModuleConfig_CannedMessageConfig_enabled_tag 9
#define ModuleConfig_CannedMessageConfig_allow_input_source_tag 10
#define ModuleConfig_CannedMessageConfig_send_bell_tag 11
#define ModuleConfig_ExternalNotificationConfig_enabled_tag 1
#define ModuleConfig_ExternalNotificationConfig_output_ms_tag 2
#define ModuleConfig_ExternalNotificationConfig_output_tag 3
#define ModuleConfig_ExternalNotificationConfig_active_tag 4
#define ModuleConfig_ExternalNotificationConfig_alert_message_tag 5
#define ModuleConfig_ExternalNotificationConfig_alert_bell_tag 6
#define ModuleConfig_MQTTConfig_disabled_tag 1
#define ModuleConfig_MQTTConfig_address_tag 2
#define ModuleConfig_MQTTConfig_username_tag 3
#define ModuleConfig_MQTTConfig_password_tag 4
#define ModuleConfig_MQTTConfig_encryption_enabled_tag 5
#define ModuleConfig_RangeTestConfig_enabled_tag 1
#define ModuleConfig_RangeTestConfig_sender_tag 2
#define ModuleConfig_RangeTestConfig_save_tag 3
#define ModuleConfig_SerialConfig_enabled_tag 1
#define ModuleConfig_SerialConfig_echo_tag 2
#define ModuleConfig_SerialConfig_rxd_tag 3
#define ModuleConfig_SerialConfig_txd_tag 4
#define ModuleConfig_SerialConfig_baud_tag 5
#define ModuleConfig_SerialConfig_timeout_tag 6
#define ModuleConfig_SerialConfig_mode_tag 7
#define ModuleConfig_StoreForwardConfig_enabled_tag 1
#define ModuleConfig_StoreForwardConfig_heartbeat_tag 2
#define ModuleConfig_StoreForwardConfig_records_tag 3
#define ModuleConfig_StoreForwardConfig_history_return_max_tag 4
#define ModuleConfig_StoreForwardConfig_history_return_window_tag 5
#define ModuleConfig_TelemetryConfig_device_update_interval_tag 1
#define ModuleConfig_TelemetryConfig_environment_update_interval_tag 2
#define ModuleConfig_TelemetryConfig_environment_measurement_enabled_tag 3
#define ModuleConfig_TelemetryConfig_environment_screen_enabled_tag 4
#define ModuleConfig_TelemetryConfig_environment_read_error_count_threshold_tag 5
#define ModuleConfig_TelemetryConfig_environment_recovery_interval_tag 6
#define ModuleConfig_TelemetryConfig_environment_display_fahrenheit_tag 7
#define ModuleConfig_TelemetryConfig_environment_sensor_type_tag 8
#define ModuleConfig_TelemetryConfig_environment_sensor_pin_tag 9
#define ModuleConfig_mqtt_tag 1
#define ModuleConfig_serial_tag 2
#define ModuleConfig_external_notification_tag 3
#define ModuleConfig_store_forward_tag 4
#define ModuleConfig_range_test_tag 5
#define ModuleConfig_telemetry_tag 6
#define ModuleConfig_canned_message_tag 7
/* Struct field encoding specification for nanopb */
#define ModuleConfig_FIELDLIST(X, a) \
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,mqtt,payloadVariant.mqtt), 1) \
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,serial,payloadVariant.serial), 2) \
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,external_notification,payloadVariant.external_notification), 3) \
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,store_forward,payloadVariant.store_forward), 4) \
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,range_test,payloadVariant.range_test), 5) \
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,telemetry,payloadVariant.telemetry), 6) \
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,canned_message,payloadVariant.canned_message), 7)
#define ModuleConfig_CALLBACK NULL
#define ModuleConfig_DEFAULT NULL
#define ModuleConfig_payloadVariant_mqtt_MSGTYPE ModuleConfig_MQTTConfig
#define ModuleConfig_payloadVariant_serial_MSGTYPE ModuleConfig_SerialConfig
#define ModuleConfig_payloadVariant_external_notification_MSGTYPE ModuleConfig_ExternalNotificationConfig
#define ModuleConfig_payloadVariant_store_forward_MSGTYPE ModuleConfig_StoreForwardConfig
#define ModuleConfig_payloadVariant_range_test_MSGTYPE ModuleConfig_RangeTestConfig
#define ModuleConfig_payloadVariant_telemetry_MSGTYPE ModuleConfig_TelemetryConfig
#define ModuleConfig_payloadVariant_canned_message_MSGTYPE ModuleConfig_CannedMessageConfig
#define ModuleConfig_MQTTConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, BOOL, disabled, 1) \
X(a, STATIC, SINGULAR, STRING, address, 2) \
X(a, STATIC, SINGULAR, STRING, username, 3) \
X(a, STATIC, SINGULAR, STRING, password, 4) \
X(a, STATIC, SINGULAR, BOOL, encryption_enabled, 5)
#define ModuleConfig_MQTTConfig_CALLBACK NULL
#define ModuleConfig_MQTTConfig_DEFAULT NULL
#define ModuleConfig_SerialConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, BOOL, enabled, 1) \
X(a, STATIC, SINGULAR, BOOL, echo, 2) \
X(a, STATIC, SINGULAR, UINT32, rxd, 3) \
X(a, STATIC, SINGULAR, UINT32, txd, 4) \
X(a, STATIC, SINGULAR, UENUM, baud, 5) \
X(a, STATIC, SINGULAR, UINT32, timeout, 6) \
X(a, STATIC, SINGULAR, UENUM, mode, 7)
#define ModuleConfig_SerialConfig_CALLBACK NULL
#define ModuleConfig_SerialConfig_DEFAULT NULL
#define ModuleConfig_ExternalNotificationConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, BOOL, enabled, 1) \
X(a, STATIC, SINGULAR, UINT32, output_ms, 2) \
X(a, STATIC, SINGULAR, UINT32, output, 3) \
X(a, STATIC, SINGULAR, BOOL, active, 4) \
X(a, STATIC, SINGULAR, BOOL, alert_message, 5) \
X(a, STATIC, SINGULAR, BOOL, alert_bell, 6)
#define ModuleConfig_ExternalNotificationConfig_CALLBACK NULL
#define ModuleConfig_ExternalNotificationConfig_DEFAULT NULL
#define ModuleConfig_StoreForwardConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, BOOL, enabled, 1) \
X(a, STATIC, SINGULAR, BOOL, heartbeat, 2) \
X(a, STATIC, SINGULAR, UINT32, records, 3) \
X(a, STATIC, SINGULAR, UINT32, history_return_max, 4) \
X(a, STATIC, SINGULAR, UINT32, history_return_window, 5)
#define ModuleConfig_StoreForwardConfig_CALLBACK NULL
#define ModuleConfig_StoreForwardConfig_DEFAULT NULL
#define ModuleConfig_RangeTestConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, BOOL, enabled, 1) \
X(a, STATIC, SINGULAR, UINT32, sender, 2) \
X(a, STATIC, SINGULAR, BOOL, save, 3)
#define ModuleConfig_RangeTestConfig_CALLBACK NULL
#define ModuleConfig_RangeTestConfig_DEFAULT NULL
#define ModuleConfig_TelemetryConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UINT32, device_update_interval, 1) \
X(a, STATIC, SINGULAR, UINT32, environment_update_interval, 2) \
X(a, STATIC, SINGULAR, BOOL, environment_measurement_enabled, 3) \
X(a, STATIC, SINGULAR, BOOL, environment_screen_enabled, 4) \
X(a, STATIC, SINGULAR, UINT32, environment_read_error_count_threshold, 5) \
X(a, STATIC, SINGULAR, UINT32, environment_recovery_interval, 6) \
X(a, STATIC, SINGULAR, BOOL, environment_display_fahrenheit, 7) \
X(a, STATIC, SINGULAR, UENUM, environment_sensor_type, 8) \
X(a, STATIC, SINGULAR, UINT32, environment_sensor_pin, 9)
#define ModuleConfig_TelemetryConfig_CALLBACK NULL
#define ModuleConfig_TelemetryConfig_DEFAULT NULL
#define ModuleConfig_CannedMessageConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, BOOL, rotary1_enabled, 1) \
X(a, STATIC, SINGULAR, UINT32, inputbroker_pin_a, 2) \
X(a, STATIC, SINGULAR, UINT32, inputbroker_pin_b, 3) \
X(a, STATIC, SINGULAR, UINT32, inputbroker_pin_press, 4) \
X(a, STATIC, SINGULAR, UENUM, inputbroker_event_cw, 5) \
X(a, STATIC, SINGULAR, UENUM, inputbroker_event_ccw, 6) \
X(a, STATIC, SINGULAR, UENUM, inputbroker_event_press, 7) \
X(a, STATIC, SINGULAR, BOOL, updown1_enabled, 8) \
X(a, STATIC, SINGULAR, BOOL, enabled, 9) \
X(a, STATIC, SINGULAR, STRING, allow_input_source, 10) \
X(a, STATIC, SINGULAR, BOOL, send_bell, 11)
#define ModuleConfig_CannedMessageConfig_CALLBACK NULL
#define ModuleConfig_CannedMessageConfig_DEFAULT NULL
extern const pb_msgdesc_t ModuleConfig_msg;
extern const pb_msgdesc_t ModuleConfig_MQTTConfig_msg;
extern const pb_msgdesc_t ModuleConfig_SerialConfig_msg;
extern const pb_msgdesc_t ModuleConfig_ExternalNotificationConfig_msg;
extern const pb_msgdesc_t ModuleConfig_StoreForwardConfig_msg;
extern const pb_msgdesc_t ModuleConfig_RangeTestConfig_msg;
extern const pb_msgdesc_t ModuleConfig_TelemetryConfig_msg;
extern const pb_msgdesc_t ModuleConfig_CannedMessageConfig_msg;
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
#define ModuleConfig_fields &ModuleConfig_msg
#define ModuleConfig_MQTTConfig_fields &ModuleConfig_MQTTConfig_msg
#define ModuleConfig_SerialConfig_fields &ModuleConfig_SerialConfig_msg
#define ModuleConfig_ExternalNotificationConfig_fields &ModuleConfig_ExternalNotificationConfig_msg
#define ModuleConfig_StoreForwardConfig_fields &ModuleConfig_StoreForwardConfig_msg
#define ModuleConfig_RangeTestConfig_fields &ModuleConfig_RangeTestConfig_msg
#define ModuleConfig_TelemetryConfig_fields &ModuleConfig_TelemetryConfig_msg
#define ModuleConfig_CannedMessageConfig_fields &ModuleConfig_CannedMessageConfig_msg
/* Maximum encoded size of messages (where known) */
#define ModuleConfig_CannedMessageConfig_size 49
#define ModuleConfig_ExternalNotificationConfig_size 20
#define ModuleConfig_MQTTConfig_size 103
#define ModuleConfig_RangeTestConfig_size 10
#define ModuleConfig_SerialConfig_size 26
#define ModuleConfig_StoreForwardConfig_size 22
#define ModuleConfig_TelemetryConfig_size 38
#define ModuleConfig_size 105
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif

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
@@ -29,8 +29,7 @@ typedef enum _PortNum {
PortNum_UNKNOWN_APP = 0,
/* A simple UTF-8 text message, which even the little micros in the mesh
can understand and show on their screen eventually in some circumstances
even signal might send messages in this form (see below)
Formerly called CLEAR_TEXT */
even signal might send messages in this form (see below) */
PortNum_TEXT_MESSAGE_APP = 1,
/* Reserved for built-in GPIO/example app.
See remote_hardware.proto/HardwareMessage for details on the message sent/received to this port number */
@@ -47,6 +46,10 @@ typedef enum _PortNum {
/* Admin control packets.
Payload is a [AdminMessage](/docs/developers/protobufs/api#adminmessage) message */
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,606 +0,0 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.5 */
#ifndef PB_RADIOCONFIG_PB_H_INCLUDED
#define PB_RADIOCONFIG_PB_H_INCLUDED
#include <pb.h>
#if PB_PROTO_HEADER_VERSION != 40
#error Regenerate this file with the current version of nanopb generator.
#endif
/* Enum definitions */
/* The frequency/regulatory region the user has selected.
Note: In 1.0 builds (which must still be supported by the android app for a
long time) this field will be unpopulated.
If firmware is ever upgraded from an old 1.0ish build, the old
MyNodeInfo.region string will be used to set UserPreferences.region and the
old value will be no longer set. */
typedef enum _RegionCode {
/* TODO: REPLACE */
RegionCode_Unset = 0,
/* TODO: REPLACE */
RegionCode_US = 1,
/* TODO: REPLACE */
RegionCode_EU433 = 2,
/* TODO: REPLACE */
RegionCode_EU868 = 3,
/* TODO: REPLACE */
RegionCode_CN = 4,
/* TODO: REPLACE */
RegionCode_JP = 5,
/* TODO: REPLACE */
RegionCode_ANZ = 6,
/* TODO: REPLACE */
RegionCode_KR = 7,
/* TODO: REPLACE */
RegionCode_TW = 8,
/* TODO: REPLACE */
RegionCode_RU = 9,
/* TODO: REPLACE */
RegionCode_IN = 10,
/* TODO: REPLACE */
RegionCode_NZ865 = 11,
/* TODO: REPLACE */
RegionCode_TH = 12
} RegionCode;
/* Defines the device's role on the Mesh network
unset
Behave normally.
Router
Functions as a router */
typedef enum _Role {
/* Client device role */
Role_Client = 0,
/* ClientMute device role
This is like the client but packets will not hop over this node. Would be
useful if you want to save power by not contributing to the mesh. */
Role_ClientMute = 1,
/* Router device role.
Uses an agressive algirithem for the flood networking so packets will
prefer to be routed over this node. Also assume that this will be generally
unattended and so will turn off the wifi/ble radio as well as the oled screen. */
Role_Router = 2,
/* RouterClient device role
Uses an agressive algirithem for the flood networking so packets will
prefer to be routed over this node. Similiar power management as a regular
client, so the RouterClient can be used as both a Router and a Client. Useful
as a well placed base station that you could also use to send messages. */
Role_RouterClient = 3
} Role;
/* Sets the charge control current of devices with a battery charger that can be
configured. This is passed into the axp power management chip like on the tbeam. */
typedef enum _ChargeCurrent {
/* TODO: REPLACE */
ChargeCurrent_MAUnset = 0,
/* TODO: REPLACE */
ChargeCurrent_MA100 = 1,
/* TODO: REPLACE */
ChargeCurrent_MA190 = 2,
/* TODO: REPLACE */
ChargeCurrent_MA280 = 3,
/* TODO: REPLACE */
ChargeCurrent_MA360 = 4,
/* TODO: REPLACE */
ChargeCurrent_MA450 = 5,
/* TODO: REPLACE */
ChargeCurrent_MA550 = 6,
/* TODO: REPLACE */
ChargeCurrent_MA630 = 7,
/* TODO: REPLACE */
ChargeCurrent_MA700 = 8,
/* TODO: REPLACE */
ChargeCurrent_MA780 = 9,
/* TODO: REPLACE */
ChargeCurrent_MA880 = 10,
/* TODO: REPLACE */
ChargeCurrent_MA960 = 11,
/* TODO: REPLACE */
ChargeCurrent_MA1000 = 12,
/* TODO: REPLACE */
ChargeCurrent_MA1080 = 13,
/* TODO: REPLACE */
ChargeCurrent_MA1160 = 14,
/* TODO: REPLACE */
ChargeCurrent_MA1240 = 15,
/* TODO: REPLACE */
ChargeCurrent_MA1320 = 16
} ChargeCurrent;
/* How the GPS coordinates are displayed on the OLED screen. */
typedef enum _GpsCoordinateFormat {
/* GPS coordinates are displayed in the normal decimal degrees format:
DD.DDDDDD DDD.DDDDDD */
GpsCoordinateFormat_GpsFormatDec = 0,
/* GPS coordinates are displayed in the degrees minutes seconds format:
DD°MM'SS"C DDD°MM'SS"C, where C is the compass point representing the locations quadrant */
GpsCoordinateFormat_GpsFormatDMS = 1,
/* GPS coordinates are displayed in Universal Transverse Mercator format:
ZZB EEEEEE NNNNNNN, where Z is zone, B is band, E is easting, N is northing */
GpsCoordinateFormat_GpsFormatUTM = 2,
/* GPS coordinates are displayed in Military Grid Reference System format:
ZZB CD EEEEE NNNNN, where Z is zone, B is band, C is the east 100k square, D is the north 100k square,
E is easting, N is northing */
GpsCoordinateFormat_GpsFormatMGRS = 3,
/* GPS coordinates are displayed in Open Location Code (aka Plus Codes). */
GpsCoordinateFormat_GpsFormatOLC = 4,
/* GPS coordinates are displayed in Ordnance Survey Grid Reference (the National Grid System of the UK).
Format: AB EEEEE NNNNN, where A is the east 100k square, B is the north 100k square, E is the easting,
N is the northing */
GpsCoordinateFormat_GpsFormatOSGR = 5
} GpsCoordinateFormat;
/* Bit field of boolean configuration options, indicating which optional
fields to include when assembling POSITION messages
Longitude and latitude are always included (also time if GPS-synced)
NOTE: the more fields are included, the larger the message will be -
leading to longer airtime and a higher risk of packet loss */
typedef enum _PositionFlags {
/* Required for compilation */
PositionFlags_POS_UNDEFINED = 0,
/* Include an altitude value (if available) */
PositionFlags_POS_ALTITUDE = 1,
/* Altitude value is MSL */
PositionFlags_POS_ALT_MSL = 2,
/* Include geoidal separation */
PositionFlags_POS_GEO_SEP = 4,
/* Include the DOP value ; PDOP used by default, see below */
PositionFlags_POS_DOP = 8,
/* If POS_DOP set, send separate HDOP / VDOP values instead of PDOP */
PositionFlags_POS_HVDOP = 16,
/* Include battery level */
PositionFlags_POS_BATTERY = 32,
/* Include number of "satellites in view" */
PositionFlags_POS_SATINVIEW = 64,
/* Include a sequence number incremented per packet */
PositionFlags_POS_SEQ_NOS = 128,
/* Include positional timestamp (from GPS solution) */
PositionFlags_POS_TIMESTAMP = 256
} PositionFlags;
/* TODO: REPLACE */
typedef enum _InputEventChar {
/* TODO: REPLACE */
InputEventChar_KEY_NONE = 0,
/* TODO: REPLACE */
InputEventChar_KEY_UP = 17,
/* TODO: REPLACE */
InputEventChar_KEY_DOWN = 18,
/* TODO: REPLACE */
InputEventChar_KEY_LEFT = 19,
/* TODO: REPLACE */
InputEventChar_KEY_RIGHT = 20,
/* '\n' */
InputEventChar_KEY_SELECT = 10,
/* TODO: REPLACE */
InputEventChar_KEY_BACK = 27,
/* TODO: REPLACE */
InputEventChar_KEY_CANCEL = 24
} InputEventChar;
/* The frequency/regulatory region the user has selected.
Note: In 1.0 builds (which must still be supported by the android app for a
long time) this field will be unpopulated.
If firmware is ever upgraded from an old 1.0ish build, the old
MyNodeInfo.region string will be used to set UserPreferences.region and the
old value will be no longer set. */
typedef enum _RadioConfig_UserPreferences_Serial_Baud {
/* TODO: REPLACE */
RadioConfig_UserPreferences_Serial_Baud_BAUD_Default = 0,
/* TODO: REPLACE */
RadioConfig_UserPreferences_Serial_Baud_BAUD_2400 = 1,
/* TODO: REPLACE */
RadioConfig_UserPreferences_Serial_Baud_BAUD_4800 = 2,
/* TODO: REPLACE */
RadioConfig_UserPreferences_Serial_Baud_BAUD_9600 = 3,
/* TODO: REPLACE */
RadioConfig_UserPreferences_Serial_Baud_BAUD_19200 = 4,
/* TODO: REPLACE */
RadioConfig_UserPreferences_Serial_Baud_BAUD_38400 = 5,
/* TODO: REPLACE */
RadioConfig_UserPreferences_Serial_Baud_BAUD_57600 = 6,
/* TODO: REPLACE */
RadioConfig_UserPreferences_Serial_Baud_BAUD_115200 = 7,
/* TODO: REPLACE */
RadioConfig_UserPreferences_Serial_Baud_BAUD_230400 = 8,
/* TODO: REPLACE */
RadioConfig_UserPreferences_Serial_Baud_BAUD_460800 = 9,
/* TODO: REPLACE */
RadioConfig_UserPreferences_Serial_Baud_BAUD_576000 = 10,
/* TODO: REPLACE */
RadioConfig_UserPreferences_Serial_Baud_BAUD_921600 = 11,
/* TODO: REPLACE */
RadioConfig_UserPreferences_Serial_Baud_BAUD_110 = 12,
RadioConfig_UserPreferences_Serial_Baud_BAUD_300 = 13,
RadioConfig_UserPreferences_Serial_Baud_BAUD_600 = 14,
RadioConfig_UserPreferences_Serial_Baud_BAUD_1200 = 15
} RadioConfig_UserPreferences_Serial_Baud;
/* Defines the device's role on the Mesh network
unset
Behave normally.
Router
Functions as a router */
typedef enum _RadioConfig_UserPreferences_Serial_Mode {
/* Client device role */
RadioConfig_UserPreferences_Serial_Mode_MODE_Default = 0,
/* ClientMute device role
This is like the client but packets will not hop over this node. Would be
useful if you want to save power by not contributing to the mesh. */
RadioConfig_UserPreferences_Serial_Mode_MODE_SIMPLE = 1,
/* Router device role.
Uses an agressive algirithem for the flood networking so packets will
prefer to be routed over this node. Also assume that this will be generally
unattended and so will turn off the wifi/ble radio as well as the oled screen. */
RadioConfig_UserPreferences_Serial_Mode_MODE_PROTO = 2
} RadioConfig_UserPreferences_Serial_Mode;
/* Sets the charge control current of devices with a battery charger that can be
configured. This is passed into the axp power management chip like on the tbeam. */
typedef enum _RadioConfig_UserPreferences_TelemetrySensorType {
/* TODO: REPLACE */
RadioConfig_UserPreferences_TelemetrySensorType_None = 0,
/* TODO: REPLACE */
RadioConfig_UserPreferences_TelemetrySensorType_DHT11 = 1,
/* TODO: REPLACE */
RadioConfig_UserPreferences_TelemetrySensorType_DS18B20 = 2,
/* TODO: REPLACE */
RadioConfig_UserPreferences_TelemetrySensorType_DHT12 = 3,
/* TODO: REPLACE */
RadioConfig_UserPreferences_TelemetrySensorType_DHT21 = 4,
/* TODO: REPLACE */
RadioConfig_UserPreferences_TelemetrySensorType_DHT22 = 5,
/* TODO: REPLACE */
RadioConfig_UserPreferences_TelemetrySensorType_BME280 = 6,
/* TODO: REPLACE */
RadioConfig_UserPreferences_TelemetrySensorType_BME680 = 7,
/* TODO: REPLACE */
RadioConfig_UserPreferences_TelemetrySensorType_MCP9808 = 8,
/* TODO: REPLACE */
RadioConfig_UserPreferences_TelemetrySensorType_SHTC3 = 9
} RadioConfig_UserPreferences_TelemetrySensorType;
/* Struct definitions */
typedef struct _RadioConfig_UserPreferences {
uint32_t position_broadcast_secs;
uint32_t wait_bluetooth_secs;
uint32_t screen_on_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;
char wifi_ssid[33];
char wifi_password[64];
bool wifi_ap_mode;
RegionCode region;
ChargeCurrent charge_current;
bool position_broadcast_smart_disabled;
Role role;
bool location_share_disabled;
bool gps_disabled;
uint32_t gps_update_interval;
uint32_t gps_attempt_time;
bool is_low_power;
bool fixed_position;
bool serial_disabled;
float frequency_offset;
char mqtt_server[32];
bool mqtt_disabled;
GpsCoordinateFormat gps_format;
bool gps_accept_2d;
uint32_t gps_max_dop;
bool factory_reset;
bool debug_log_enabled;
pb_size_t ignore_incoming_count;
uint32_t ignore_incoming[3];
bool serial_module_enabled;
bool serial_module_echo;
uint32_t serial_module_rxd;
uint32_t serial_module_txd;
uint32_t serial_module_timeout;
RadioConfig_UserPreferences_Serial_Mode serial_module_mode;
bool ext_notification_module_enabled;
uint32_t ext_notification_module_output_ms;
uint32_t ext_notification_module_output;
bool ext_notification_module_active;
bool ext_notification_module_alert_message;
bool ext_notification_module_alert_bell;
bool range_test_module_enabled;
uint32_t range_test_module_sender;
bool range_test_module_save;
uint32_t store_forward_module_records;
uint32_t store_forward_module_history_return_max;
uint32_t store_forward_module_history_return_window;
bool telemetry_module_environment_measurement_enabled;
bool telemetry_module_environment_screen_enabled;
uint32_t telemetry_module_environment_read_error_count_threshold;
uint32_t telemetry_module_device_update_interval;
uint32_t telemetry_module_environment_recovery_interval;
bool telemetry_module_environment_display_fahrenheit;
RadioConfig_UserPreferences_TelemetrySensorType telemetry_module_environment_sensor_type;
uint32_t telemetry_module_environment_sensor_pin;
bool store_forward_module_enabled;
bool store_forward_module_heartbeat;
uint32_t position_flags;
bool is_always_powered;
uint32_t auto_screen_carousel_secs;
uint32_t on_battery_shutdown_after_secs;
uint32_t hop_limit;
char mqtt_username[32];
char mqtt_password[32];
bool is_lora_tx_disabled;
bool is_power_saving;
bool rotary1_enabled;
uint32_t inputbroker_pin_a;
uint32_t inputbroker_pin_b;
uint32_t inputbroker_pin_press;
InputEventChar inputbroker_event_cw;
InputEventChar inputbroker_event_ccw;
InputEventChar inputbroker_event_press;
bool updown1_enabled;
bool canned_message_module_enabled;
char canned_message_module_allow_input_source[16];
bool canned_message_module_send_bell;
bool mqtt_encryption_enabled;
float adc_multiplier_override;
RadioConfig_UserPreferences_Serial_Baud serial_module_baud;
uint32_t telemetry_module_environment_update_interval;
} RadioConfig_UserPreferences;
/* The entire set of user settable/readable settings for our radio device.
Includes both the current channel settings and any preferences the user has
set for behavior of their node */
typedef struct _RadioConfig {
/* TODO: REPLACE */
bool has_preferences;
RadioConfig_UserPreferences preferences;
} RadioConfig;
/* Helper constants for enums */
#define _RegionCode_MIN RegionCode_Unset
#define _RegionCode_MAX RegionCode_TH
#define _RegionCode_ARRAYSIZE ((RegionCode)(RegionCode_TH+1))
#define _Role_MIN Role_Client
#define _Role_MAX Role_RouterClient
#define _Role_ARRAYSIZE ((Role)(Role_RouterClient+1))
#define _ChargeCurrent_MIN ChargeCurrent_MAUnset
#define _ChargeCurrent_MAX ChargeCurrent_MA1320
#define _ChargeCurrent_ARRAYSIZE ((ChargeCurrent)(ChargeCurrent_MA1320+1))
#define _GpsCoordinateFormat_MIN GpsCoordinateFormat_GpsFormatDec
#define _GpsCoordinateFormat_MAX GpsCoordinateFormat_GpsFormatOSGR
#define _GpsCoordinateFormat_ARRAYSIZE ((GpsCoordinateFormat)(GpsCoordinateFormat_GpsFormatOSGR+1))
#define _PositionFlags_MIN PositionFlags_POS_UNDEFINED
#define _PositionFlags_MAX PositionFlags_POS_TIMESTAMP
#define _PositionFlags_ARRAYSIZE ((PositionFlags)(PositionFlags_POS_TIMESTAMP+1))
#define _InputEventChar_MIN InputEventChar_KEY_NONE
#define _InputEventChar_MAX InputEventChar_KEY_BACK
#define _InputEventChar_ARRAYSIZE ((InputEventChar)(InputEventChar_KEY_BACK+1))
#define _RadioConfig_UserPreferences_Serial_Baud_MIN RadioConfig_UserPreferences_Serial_Baud_BAUD_Default
#define _RadioConfig_UserPreferences_Serial_Baud_MAX RadioConfig_UserPreferences_Serial_Baud_BAUD_1200
#define _RadioConfig_UserPreferences_Serial_Baud_ARRAYSIZE ((RadioConfig_UserPreferences_Serial_Baud)(RadioConfig_UserPreferences_Serial_Baud_BAUD_1200+1))
#define _RadioConfig_UserPreferences_Serial_Mode_MIN RadioConfig_UserPreferences_Serial_Mode_MODE_Default
#define _RadioConfig_UserPreferences_Serial_Mode_MAX RadioConfig_UserPreferences_Serial_Mode_MODE_PROTO
#define _RadioConfig_UserPreferences_Serial_Mode_ARRAYSIZE ((RadioConfig_UserPreferences_Serial_Mode)(RadioConfig_UserPreferences_Serial_Mode_MODE_PROTO+1))
#define _RadioConfig_UserPreferences_TelemetrySensorType_MIN RadioConfig_UserPreferences_TelemetrySensorType_None
#define _RadioConfig_UserPreferences_TelemetrySensorType_MAX RadioConfig_UserPreferences_TelemetrySensorType_SHTC3
#define _RadioConfig_UserPreferences_TelemetrySensorType_ARRAYSIZE ((RadioConfig_UserPreferences_TelemetrySensorType)(RadioConfig_UserPreferences_TelemetrySensorType_SHTC3+1))
#ifdef __cplusplus
extern "C" {
#endif
/* Initializer values for message structs */
#define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default}
#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _Role_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_Serial_Mode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_TelemetrySensorType_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, 0, 0, 0, 0, 0, _InputEventChar_MIN, _InputEventChar_MIN, _InputEventChar_MIN, 0, 0, "", 0, 0, 0, _RadioConfig_UserPreferences_Serial_Baud_MIN, 0}
#define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero}
#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _Role_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_Serial_Mode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_TelemetrySensorType_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, 0, 0, 0, 0, 0, _InputEventChar_MIN, _InputEventChar_MIN, _InputEventChar_MIN, 0, 0, "", 0, 0, 0, _RadioConfig_UserPreferences_Serial_Baud_MIN, 0}
/* Field tags (for use in manual encoding/decoding) */
#define RadioConfig_UserPreferences_position_broadcast_secs_tag 1
#define RadioConfig_UserPreferences_wait_bluetooth_secs_tag 4
#define RadioConfig_UserPreferences_screen_on_secs_tag 5
#define RadioConfig_UserPreferences_phone_timeout_secs_tag 6
#define RadioConfig_UserPreferences_mesh_sds_timeout_secs_tag 8
#define RadioConfig_UserPreferences_sds_secs_tag 9
#define RadioConfig_UserPreferences_ls_secs_tag 10
#define RadioConfig_UserPreferences_min_wake_secs_tag 11
#define RadioConfig_UserPreferences_wifi_ssid_tag 12
#define RadioConfig_UserPreferences_wifi_password_tag 13
#define RadioConfig_UserPreferences_wifi_ap_mode_tag 14
#define RadioConfig_UserPreferences_region_tag 15
#define RadioConfig_UserPreferences_charge_current_tag 16
#define RadioConfig_UserPreferences_position_broadcast_smart_disabled_tag 17
#define RadioConfig_UserPreferences_role_tag 18
#define RadioConfig_UserPreferences_location_share_disabled_tag 32
#define RadioConfig_UserPreferences_gps_disabled_tag 33
#define RadioConfig_UserPreferences_gps_update_interval_tag 34
#define RadioConfig_UserPreferences_gps_attempt_time_tag 36
#define RadioConfig_UserPreferences_is_low_power_tag 38
#define RadioConfig_UserPreferences_fixed_position_tag 39
#define RadioConfig_UserPreferences_serial_disabled_tag 40
#define RadioConfig_UserPreferences_frequency_offset_tag 41
#define RadioConfig_UserPreferences_mqtt_server_tag 42
#define RadioConfig_UserPreferences_mqtt_disabled_tag 43
#define RadioConfig_UserPreferences_gps_format_tag 44
#define RadioConfig_UserPreferences_gps_accept_2d_tag 45
#define RadioConfig_UserPreferences_gps_max_dop_tag 46
#define RadioConfig_UserPreferences_factory_reset_tag 100
#define RadioConfig_UserPreferences_debug_log_enabled_tag 101
#define RadioConfig_UserPreferences_ignore_incoming_tag 103
#define RadioConfig_UserPreferences_serial_module_enabled_tag 120
#define RadioConfig_UserPreferences_serial_module_echo_tag 121
#define RadioConfig_UserPreferences_serial_module_rxd_tag 122
#define RadioConfig_UserPreferences_serial_module_txd_tag 123
#define RadioConfig_UserPreferences_serial_module_timeout_tag 124
#define RadioConfig_UserPreferences_serial_module_mode_tag 125
#define RadioConfig_UserPreferences_ext_notification_module_enabled_tag 126
#define RadioConfig_UserPreferences_ext_notification_module_output_ms_tag 127
#define RadioConfig_UserPreferences_ext_notification_module_output_tag 128
#define RadioConfig_UserPreferences_ext_notification_module_active_tag 129
#define RadioConfig_UserPreferences_ext_notification_module_alert_message_tag 130
#define RadioConfig_UserPreferences_ext_notification_module_alert_bell_tag 131
#define RadioConfig_UserPreferences_range_test_module_enabled_tag 132
#define RadioConfig_UserPreferences_range_test_module_sender_tag 133
#define RadioConfig_UserPreferences_range_test_module_save_tag 134
#define RadioConfig_UserPreferences_store_forward_module_records_tag 137
#define RadioConfig_UserPreferences_store_forward_module_history_return_max_tag 138
#define RadioConfig_UserPreferences_store_forward_module_history_return_window_tag 139
#define RadioConfig_UserPreferences_telemetry_module_environment_measurement_enabled_tag 140
#define RadioConfig_UserPreferences_telemetry_module_environment_screen_enabled_tag 141
#define RadioConfig_UserPreferences_telemetry_module_environment_read_error_count_threshold_tag 142
#define RadioConfig_UserPreferences_telemetry_module_device_update_interval_tag 143
#define RadioConfig_UserPreferences_telemetry_module_environment_recovery_interval_tag 144
#define RadioConfig_UserPreferences_telemetry_module_environment_display_fahrenheit_tag 145
#define RadioConfig_UserPreferences_telemetry_module_environment_sensor_type_tag 146
#define RadioConfig_UserPreferences_telemetry_module_environment_sensor_pin_tag 147
#define RadioConfig_UserPreferences_store_forward_module_enabled_tag 148
#define RadioConfig_UserPreferences_store_forward_module_heartbeat_tag 149
#define RadioConfig_UserPreferences_position_flags_tag 150
#define RadioConfig_UserPreferences_is_always_powered_tag 151
#define RadioConfig_UserPreferences_auto_screen_carousel_secs_tag 152
#define RadioConfig_UserPreferences_on_battery_shutdown_after_secs_tag 153
#define RadioConfig_UserPreferences_hop_limit_tag 154
#define RadioConfig_UserPreferences_mqtt_username_tag 155
#define RadioConfig_UserPreferences_mqtt_password_tag 156
#define RadioConfig_UserPreferences_is_lora_tx_disabled_tag 157
#define RadioConfig_UserPreferences_is_power_saving_tag 158
#define RadioConfig_UserPreferences_rotary1_enabled_tag 160
#define RadioConfig_UserPreferences_inputbroker_pin_a_tag 161
#define RadioConfig_UserPreferences_inputbroker_pin_b_tag 162
#define RadioConfig_UserPreferences_inputbroker_pin_press_tag 163
#define RadioConfig_UserPreferences_inputbroker_event_cw_tag 164
#define RadioConfig_UserPreferences_inputbroker_event_ccw_tag 165
#define RadioConfig_UserPreferences_inputbroker_event_press_tag 166
#define RadioConfig_UserPreferences_updown1_enabled_tag 167
#define RadioConfig_UserPreferences_canned_message_module_enabled_tag 170
#define RadioConfig_UserPreferences_canned_message_module_allow_input_source_tag 171
#define RadioConfig_UserPreferences_canned_message_module_send_bell_tag 173
#define RadioConfig_UserPreferences_mqtt_encryption_enabled_tag 174
#define RadioConfig_UserPreferences_adc_multiplier_override_tag 175
#define RadioConfig_UserPreferences_serial_module_baud_tag 176
#define RadioConfig_UserPreferences_telemetry_module_environment_update_interval_tag 177
#define RadioConfig_preferences_tag 1
/* Struct field encoding specification for nanopb */
#define RadioConfig_FIELDLIST(X, a) \
X(a, STATIC, OPTIONAL, MESSAGE, preferences, 1)
#define RadioConfig_CALLBACK NULL
#define RadioConfig_DEFAULT NULL
#define RadioConfig_preferences_MSGTYPE RadioConfig_UserPreferences
#define RadioConfig_UserPreferences_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UINT32, position_broadcast_secs, 1) \
X(a, STATIC, SINGULAR, UINT32, wait_bluetooth_secs, 4) \
X(a, STATIC, SINGULAR, UINT32, screen_on_secs, 5) \
X(a, STATIC, SINGULAR, UINT32, phone_timeout_secs, 6) \
X(a, STATIC, SINGULAR, UINT32, mesh_sds_timeout_secs, 8) \
X(a, STATIC, SINGULAR, UINT32, sds_secs, 9) \
X(a, STATIC, SINGULAR, UINT32, ls_secs, 10) \
X(a, STATIC, SINGULAR, UINT32, min_wake_secs, 11) \
X(a, STATIC, SINGULAR, STRING, wifi_ssid, 12) \
X(a, STATIC, SINGULAR, STRING, wifi_password, 13) \
X(a, STATIC, SINGULAR, BOOL, wifi_ap_mode, 14) \
X(a, STATIC, SINGULAR, UENUM, region, 15) \
X(a, STATIC, SINGULAR, UENUM, charge_current, 16) \
X(a, STATIC, SINGULAR, BOOL, position_broadcast_smart_disabled, 17) \
X(a, STATIC, SINGULAR, UENUM, role, 18) \
X(a, STATIC, SINGULAR, BOOL, location_share_disabled, 32) \
X(a, STATIC, SINGULAR, BOOL, gps_disabled, 33) \
X(a, STATIC, SINGULAR, UINT32, gps_update_interval, 34) \
X(a, STATIC, SINGULAR, UINT32, gps_attempt_time, 36) \
X(a, STATIC, SINGULAR, BOOL, is_low_power, 38) \
X(a, STATIC, SINGULAR, BOOL, fixed_position, 39) \
X(a, STATIC, SINGULAR, BOOL, serial_disabled, 40) \
X(a, STATIC, SINGULAR, FLOAT, frequency_offset, 41) \
X(a, STATIC, SINGULAR, STRING, mqtt_server, 42) \
X(a, STATIC, SINGULAR, BOOL, mqtt_disabled, 43) \
X(a, STATIC, SINGULAR, UENUM, gps_format, 44) \
X(a, STATIC, SINGULAR, BOOL, gps_accept_2d, 45) \
X(a, STATIC, SINGULAR, UINT32, gps_max_dop, 46) \
X(a, STATIC, SINGULAR, BOOL, factory_reset, 100) \
X(a, STATIC, SINGULAR, BOOL, debug_log_enabled, 101) \
X(a, STATIC, REPEATED, UINT32, ignore_incoming, 103) \
X(a, STATIC, SINGULAR, BOOL, serial_module_enabled, 120) \
X(a, STATIC, SINGULAR, BOOL, serial_module_echo, 121) \
X(a, STATIC, SINGULAR, UINT32, serial_module_rxd, 122) \
X(a, STATIC, SINGULAR, UINT32, serial_module_txd, 123) \
X(a, STATIC, SINGULAR, UINT32, serial_module_timeout, 124) \
X(a, STATIC, SINGULAR, UENUM, serial_module_mode, 125) \
X(a, STATIC, SINGULAR, BOOL, ext_notification_module_enabled, 126) \
X(a, STATIC, SINGULAR, UINT32, ext_notification_module_output_ms, 127) \
X(a, STATIC, SINGULAR, UINT32, ext_notification_module_output, 128) \
X(a, STATIC, SINGULAR, BOOL, ext_notification_module_active, 129) \
X(a, STATIC, SINGULAR, BOOL, ext_notification_module_alert_message, 130) \
X(a, STATIC, SINGULAR, BOOL, ext_notification_module_alert_bell, 131) \
X(a, STATIC, SINGULAR, BOOL, range_test_module_enabled, 132) \
X(a, STATIC, SINGULAR, UINT32, range_test_module_sender, 133) \
X(a, STATIC, SINGULAR, BOOL, range_test_module_save, 134) \
X(a, STATIC, SINGULAR, UINT32, store_forward_module_records, 137) \
X(a, STATIC, SINGULAR, UINT32, store_forward_module_history_return_max, 138) \
X(a, STATIC, SINGULAR, UINT32, store_forward_module_history_return_window, 139) \
X(a, STATIC, SINGULAR, BOOL, telemetry_module_environment_measurement_enabled, 140) \
X(a, STATIC, SINGULAR, BOOL, telemetry_module_environment_screen_enabled, 141) \
X(a, STATIC, SINGULAR, UINT32, telemetry_module_environment_read_error_count_threshold, 142) \
X(a, STATIC, SINGULAR, UINT32, telemetry_module_device_update_interval, 143) \
X(a, STATIC, SINGULAR, UINT32, telemetry_module_environment_recovery_interval, 144) \
X(a, STATIC, SINGULAR, BOOL, telemetry_module_environment_display_fahrenheit, 145) \
X(a, STATIC, SINGULAR, UENUM, telemetry_module_environment_sensor_type, 146) \
X(a, STATIC, SINGULAR, UINT32, telemetry_module_environment_sensor_pin, 147) \
X(a, STATIC, SINGULAR, BOOL, store_forward_module_enabled, 148) \
X(a, STATIC, SINGULAR, BOOL, store_forward_module_heartbeat, 149) \
X(a, STATIC, SINGULAR, UINT32, position_flags, 150) \
X(a, STATIC, SINGULAR, BOOL, is_always_powered, 151) \
X(a, STATIC, SINGULAR, UINT32, auto_screen_carousel_secs, 152) \
X(a, STATIC, SINGULAR, UINT32, on_battery_shutdown_after_secs, 153) \
X(a, STATIC, SINGULAR, UINT32, hop_limit, 154) \
X(a, STATIC, SINGULAR, STRING, mqtt_username, 155) \
X(a, STATIC, SINGULAR, STRING, mqtt_password, 156) \
X(a, STATIC, SINGULAR, BOOL, is_lora_tx_disabled, 157) \
X(a, STATIC, SINGULAR, BOOL, is_power_saving, 158) \
X(a, STATIC, SINGULAR, BOOL, rotary1_enabled, 160) \
X(a, STATIC, SINGULAR, UINT32, inputbroker_pin_a, 161) \
X(a, STATIC, SINGULAR, UINT32, inputbroker_pin_b, 162) \
X(a, STATIC, SINGULAR, UINT32, inputbroker_pin_press, 163) \
X(a, STATIC, SINGULAR, UENUM, inputbroker_event_cw, 164) \
X(a, STATIC, SINGULAR, UENUM, inputbroker_event_ccw, 165) \
X(a, STATIC, SINGULAR, UENUM, inputbroker_event_press, 166) \
X(a, STATIC, SINGULAR, BOOL, updown1_enabled, 167) \
X(a, STATIC, SINGULAR, BOOL, canned_message_module_enabled, 170) \
X(a, STATIC, SINGULAR, STRING, canned_message_module_allow_input_source, 171) \
X(a, STATIC, SINGULAR, BOOL, canned_message_module_send_bell, 173) \
X(a, STATIC, SINGULAR, BOOL, mqtt_encryption_enabled, 174) \
X(a, STATIC, SINGULAR, FLOAT, adc_multiplier_override, 175) \
X(a, STATIC, SINGULAR, UENUM, serial_module_baud, 176) \
X(a, STATIC, SINGULAR, UINT32, telemetry_module_environment_update_interval, 177)
#define RadioConfig_UserPreferences_CALLBACK NULL
#define RadioConfig_UserPreferences_DEFAULT NULL
extern const pb_msgdesc_t RadioConfig_msg;
extern const pb_msgdesc_t RadioConfig_UserPreferences_msg;
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
#define RadioConfig_fields &RadioConfig_msg
#define RadioConfig_UserPreferences_fields &RadioConfig_UserPreferences_msg
/* Maximum encoded size of messages (where known) */
#define RadioConfig_UserPreferences_size 592
#define RadioConfig_size 595
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif

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