Compare commits

...

154 Commits

Author SHA1 Message Date
Thomas Göttgens
b97ca2c834 Merge branch 'master' into apollo 2024-11-24 15:53:58 +01:00
Thomas Göttgens
ad9d7a4972 fixes https://github.com/meshtastic/firmware/issues/5434 (#5435)
* update libpax
* fix interval init
2024-11-24 14:28:36 +01:00
jake-b
932966b896 Support for the ClimateGuard RadSens Geiger-Muller tube (#5425) 2024-11-24 13:53:52 +01:00
github-actions[bot]
4d69159e75 [create-pull-request] automated change (#5431)
Co-authored-by: caveman99 <25002+caveman99@users.noreply.github.com>
2024-11-24 12:29:17 +01:00
Ben Meadors
f2ee0df015 Remove BMA-423 and STK8X by default (#5429)
* Remove BMA-423 by default

* STK

* Wrong macro

* Helps if you include the file
2024-11-23 17:18:22 -06:00
Thomas Göttgens
fcfb197571 try to detect dfrobot station to tell it apart from an ublox gps. (#5393) 2024-11-23 16:56:40 +01:00
Mictronics
dd7140b7a1 Fix admin key loading from userPrefs.h (#5417)
* Fix LED pinout for T-Echo board marked v1.0, date 2021-6-28

* Merge PR #420

* Fixed double and missing Default class.

* Use correct format specifier and fixed typo.

* Removed duplicate code.

* Fix error: #if with no expression

* Fix warning: extra tokens at end of #endif directive.

* Fix antenna switching logic. Complementary-pin control logic is required on the rp2040-lora board.

* Fix deprecated macros.

* Set RP2040 in dormant mode when deep sleep is triggered.

* Fix array out of bounds read.

* Admin key count needs to be set otherwise the key will be zero loaded after reset.

* Don't reset the admin key size when loading defaults. Preserve an existing key in config if possible.

* Remove log spam when reading INA voltage sensor.

* Remove static declaration for admin keys from userPrefs.h. Load hard coded admin keys in case config file has empty slots.

* Removed newlines from log.

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2024-11-23 09:08:18 -06:00
Christopher Hoover
fadcbd597f Cleans up visibility in GPS.h (#5426)
Signed-off-by: Christopher Hoover <ch@murgatroid.com>
2024-11-23 06:10:09 -06:00
madeofstown
14b9a1a929 Update build-native.sh (#5415)
* Update build-native.sh

Device-install.sh and device-update.sh are not used on native platform, skip copying to release directory after build and copy native-install.sh and native-run.sh instead.

* Update build-native.sh

Skip native-run.sh copy
2024-11-23 18:06:31 +08:00
dylanli
c51a7b98bd add canned message and keyboard in indicator board (#5410)
* add canned message and keyboard in indicator board

* Added virtual keyboard macro and enabled for Indicator

* Cleanup macros by applying USE_VIRTUAL_KEYBOARD and DISPLAY_CLOCK_FRAME

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2024-11-22 18:54:06 -06:00
Ben Meadors
fdec95f9c1 Cherry pick tdeck fixes (#5422)
* Try-fix (workaround) T-Deck audio crash

* set T-Deck audio to unused 48 (mem mclk)

* swap mclk to gpio 21

* dreamcatcher: assign GPIO44 to audio mclk

---------

Co-authored-by: mverch67 <manuel.verch@gmx.de>
2024-11-22 14:25:09 -06:00
Jonathan Bennett
e6fb6b115a Seems like the last DIY board that's not "extra" (#5420) 2024-11-22 05:32:35 -06:00
Ben Meadors
d5bb32ff93 Temetry can respond to want-response for LocalStats variant (#5414) 2024-11-21 15:11:19 -06:00
Ben Meadors
f5058a9cbb Check for OkToMqtt flag presence before uplinking to MQTT (#5413)
* Check for oktomqtt flag presence before uplinking to MQTT

* Move to mqtt->onSend
2024-11-21 14:52:54 -06:00
GUVWAF
dbc5ec27f7 Temporarily disable MDNS when MQTT is enabled (#5418)
Leads to a panic
2024-11-21 14:11:50 -06:00
Michael Gjelsø
1089469f82 --web littlefswebui-* typo fix (#5416)
* Add --web

* Update device-install.bat

Forgot a "-" a few places.

* Typo fix.

* Typo fix

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: GUVWAF <78759985+GUVWAF@users.noreply.github.com>
2024-11-21 13:27:26 -06:00
Ben Meadors
fd98e9f553 Fixed NMEA sentence issue in CalTopo as well as bug with no printing all of the nodes (#5412) 2024-11-21 20:13:30 +08:00
dylanli
ccfc9e5dd9 add GPS in indicator board (#5411) 2024-11-21 19:14:35 +08:00
Michael Gjelsø
1752caaf19 --web added to device-install(.sh/.bat) (#5405)
* Add --web

* Update device-install.bat

Forgot a "-" a few places.

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2024-11-21 07:21:06 +08:00
GUVWAF
364dead3aa Update platform-raspberrypi also (#5407)
* Update arduino-pico core to fix sporadic hangs

* Update platform-raspberrypi also
2024-11-20 14:53:36 -06:00
GUVWAF
154864dfbf Update arduino-pico core to fix sporadic hangs (#5406) 2024-11-20 13:18:27 -06:00
Ben Meadors
2ca3cdf837 Fix RTC time injection and consolidate position logic (#5396)
* Fix RTC time injection and consolidate position logic

* Comment out unused var warning

* Backerds
2024-11-20 07:52:39 -06:00
Ben Meadors
485c371de4 Create a specific hw_model for WisMesh Tap (#5400)
* Create a specific hw_model for WisMesh Tap

* Trunk

* HAS_ETHERNET

* Remove it altogether

* Don't need these either
2024-11-20 12:57:46 +08:00
jcyrio
a255da3cf5 Make heart emoji usable (#5403) 2024-11-20 11:31:46 +08:00
Catalin Patulea
d65dc497f2 /api/v1/fromradio: add OPTIONS handler for CORS. (#5386)
This avoids hitting the 404 Not Found handler, which breaks connection
keep-alive, so this change fixes a big performance regression for Web Client in
Chrome: https://github.com/meshtastic/firmware/issues/5385

Tested on Heltec V3.

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2024-11-19 14:33:44 -06:00
github-actions[bot]
c641bfd53c [create-pull-request] automated change (#5399)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
2024-11-19 12:53:54 -06:00
jcyrio
b947b123fc fix 'symbal' typo (#5395) 2024-11-19 06:52:20 -06:00
Daniel.Cao
df1f66a6b9 Anable trace route function on wismeshtap platform (#5389) 2024-11-19 05:42:29 -06:00
jcyrio
70336f7f4f add smiley emoji (#5391)
* add smiley emoji

* clang-formatted
2024-11-19 13:25:11 +08:00
github-actions[bot]
de76caca32 [create-pull-request] automated change (#5388)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
2024-11-17 19:29:43 -06:00
Michael Gjelsø
89469fcb88 Allows all 3 PKI keys to be added to userPrefs.h (#4969) and a tool. (#5368)
* more userPrefs.h

Added PKI Admin keys to userPrefs.h

* Update userPrefs.h

Allows all 3 PKI keys to be added to userPrefs.h (#4969)

* Update NodeDB.cpp

Trunk

* Update userPrefs.h

Changed wording

* Create base64_to_hex.py

A little tool for converting base64 PKI Keys to decoded byte that userPrefs.h can understand.

* more userPrefs.h

Added PKI Admin keys to userPrefs.h

* Update userPrefs.h

Allows all 3 PKI keys to be added to userPrefs.h (#4969)

* Update NodeDB.cpp

Trunk

* Update userPrefs.h

Changed wording

* Create base64_to_hex.py

A little tool for converting base64 PKI Keys to decoded byte that userPrefs.h can understand.
2024-11-17 12:36:41 -06:00
github-actions[bot]
a8357ebd52 [create-pull-request] automated change (#5380)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
2024-11-17 10:51:11 -06:00
GUVWAF
0d1f9e915f Move some actions to after startTransmit() (#5383)
To minimize the time between channel scan and actual transmit
2024-11-17 10:51:01 -06:00
Ben Meadors
1a06f88dfb Cleanup static files from bad Web UI bundle on 2.5.13 release (#5376)
* Cleanup static files from bad Web UI bundle on 2.5.13 release

* Check existence first

* Esp32 is the only one we care about
2024-11-17 07:57:59 -06:00
Michael Gjelsø
a174ec7cf9 Bug fixed in ExternalNotificationModule (#5375)
While `nagging` setExternalState wasn't written to Buzzer & Vibra so output was never toggled.

Possible fix for #5348
2024-11-17 07:36:06 -06:00
Ben Meadors
37b29f6899 Add littlefswebui 2024-11-16 19:36:55 -06:00
Ben Meadors
74d0c58576 Diag 2024-11-16 06:24:10 -06:00
Ben Meadors
ca3d8da128 version tags 2024-11-16 06:22:08 -06:00
Ben Meadors
be6348388e Separate littlefs bundle 2024-11-16 06:12:45 -06:00
Ben Meadors
fdc473e5fa Trunk 2024-11-16 06:01:07 -06:00
Ben Meadors
add70b5229 Rework some things 2024-11-16 05:58:07 -06:00
Tom Fifield
1b99543a15 Typo fix in build_raspbian.yml (#5365)
s/sudp/sudo :(:(:(
2024-11-16 12:48:15 +08:00
Tom Fifield
90a3050c1f Add sudo to apt-get commands for Raspbian Build (#5364)
Without sudo, inadequate permissions to runs the commands meant
the build was failing.
2024-11-16 12:01:41 +08:00
GUVWAF
9545a10361 RP2040: Update core; add mDNS support (#5355)
* Update arduino-pico core

* RP2040: Add mDNS support

* SimpleMDNS `begin` now returns a bool

* Add `-g` option to `debug_build_flags` to link files for gdb

* RAK11310 needs old platform as well

* Change defines to specific architecture

* Core version 4.2.1 is out
2024-11-16 08:20:20 +08:00
Michael Gjelsø
d4d89447bd Adds fixed GPS, BUTTON_PIN and BLE code to userPrefs.h (#5341)
* userPrefs.h

Added FixedGPS
Added Fixed Bluetooth PIN

* Update NodeDB.cpp

Removed some un-used LOG_INFO

* Added BUTTON_PIN

* Trunk

* Variable re-naming.

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2024-11-14 06:56:22 -06:00
github-actions[bot]
81172574a4 [create-pull-request] automated change (#5347)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
2024-11-14 04:54:56 -06:00
Ben Meadors
295278bb12 Update version.properties 2024-11-13 18:47:46 -06:00
Ben Meadors
ec6949fdc0 Migrate NRF52 devices max nodes down to 80 for now to prevent brownouts (#5346) 2024-11-13 18:44:35 -06:00
github-actions[bot]
f4908fadd6 [create-pull-request] automated change (#5344)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
2024-11-13 13:18:57 -06:00
Mictronics
528e177c62 Remove log spam when reading INA sensor. (#5345)
* Fix LED pinout for T-Echo board marked v1.0, date 2021-6-28

* Merge PR #420

* Fixed double and missing Default class.

* Use correct format specifier and fixed typo.

* Removed duplicate code.

* Fix error: #if with no expression

* Fix warning: extra tokens at end of #endif directive.

* Fix antenna switching logic. Complementary-pin control logic is required on the rp2040-lora board.

* Fix deprecated macros.

* Set RP2040 in dormant mode when deep sleep is triggered.

* Fix array out of bounds read.

* Admin key count needs to be set otherwise the key will be zero loaded after reset.

* Don't reset the admin key size when loading defaults. Preserve an existing key in config if possible.

* Remove log spam when reading INA voltage sensor.

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2024-11-13 13:18:38 -06:00
Ben Meadors
73430cb582 Update version.properties (#5343) 2024-11-13 11:00:23 -06:00
Ben Meadors
3a66c738bd Revert "Decrease max nodes for NRF52 to 80 as workaround to prevent FS blowou…" (#5340)
This reverts commit ea150c32f3.
2024-11-13 10:21:55 -06:00
Ben Meadors
ea150c32f3 Decrease max nodes for NRF52 to 80 as workaround to prevent FS blowouts (#5338)
* Decrease max nodes for NRF52 to 80 as workaround to prevent FS blowouts

* Don't redefine

* Newline
2024-11-13 07:43:05 -06:00
Ben Meadors
ac804818de Only allow 30 seconds minimum for power.on_battery_shutdown_after_secs (#5337) 2024-11-13 05:39:15 -06:00
Blake-Latchford
8fcfe7f28b Read voltage during init fixes #5276 (#5332)
Power::readPowerStatus is called on startup,
but AnalogBatteryLevel::getBattVoltage
skips the read because 5 seconds have not
elapsed since last_read_time_ms, which
is initialized to zero.

`batMv=3100` is reported because
AnalogBatteryLevel::last_read_value is
initialized as:
```
float last_read_value = (OCV[NUM_OCV_POINTS - 1] * NUM_CELLS);
```
2024-11-13 04:13:55 -06:00
GUVWAF
e866734a25 Handle repeated packet after potentially canceling previous Tx (#5330)
* Revert "Fix sending duplicate packets to PhoneAPI/MQTT (#5315)"

This reverts commit 40bc04b521.

* Handle repeated packet after potentially canceling previous Tx
2024-11-12 15:23:32 -06:00
Matthijs De Smedt
2ec3958cd8 Add support for ignoring nodes with is_ignored field in NodeInfo (#5319)
* Add support for is_ignored bool in NodeInfo

* is_ignored is not a boring node either

* Clean out metrics and position

* Clear the key too

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2024-11-12 13:27:44 -06:00
GUVWAF
f4b0e19a65 Fix another heap leak (#5328) 2024-11-12 10:59:29 -06:00
Ben Meadors
a49f080bd2 Revert "Portduino packaging: Move meshtastic/web out of /usr/share/doc (#5323)" (#5325)
This reverts commit 762ccdc1b9.
2024-11-12 06:40:46 -06:00
Ben Meadors
e65a754430 Remove board level extra from wismesh tap 2024-11-12 06:20:42 -06:00
Ben Meadors
a84324c4fa Don't attempt to save NodeDB on low-batt shutdown to prevent FS corruption (#5312) 2024-11-12 06:17:26 -06:00
Daniel.Cao
ff33a27789 Reduce the flash usage of wismeshtap platform (#5322)
* Reduce the flash usage of wismeshtap platform

* fix STOREFORWARD twice

* Reduce the flash usage of wismeshtap platform

* fix STOREFORWARD twice

* add range test

* Update platformio.ini

remove
-DMESHTASTIC_EXCLUDE_PAXCOUNTER=1
-DMESHTASTIC_EXCLUDE_AUDIO=1

* Update platformio.ini

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2024-11-12 06:16:40 -06:00
Ben Meadors
51ea7ac627 Trunk toolchain versions 2024-11-12 06:12:09 -06:00
Ben Meadors
606c2e8eb0 Exclude paxcounter 2024-11-12 05:50:30 -06:00
Austin
762ccdc1b9 Portduino packaging: Move meshtastic/web out of /usr/share/doc (#5323)
* Portduino: Move meshtastic/web out of `doc`

* Remove /usr/share/doc/meshtasticd before linking
2024-11-12 16:14:12 +08:00
Michael Gjelsø
0acccdfe2d Don't send to public channel (#5310)
* Don't send to public channel

`p->to` wasn't set and had the same value as broadcast, it's now set to our own NodeNum.

* Trunk

* Update DetectionSensorModule.cpp

Take 3

* Revert NodeNum()
2024-11-11 19:11:54 -06:00
github-actions[bot]
0e4f7003c7 [create-pull-request] automated change (#5320)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
2024-11-11 18:55:02 -06:00
GUVWAF
40bc04b521 Fix sending duplicate packets to PhoneAPI/MQTT (#5315)
* Fix potential duplicate packets to PhoneAPI/MQTT

* Fix include error for STM32

* Fix cppcheck error
2024-11-12 07:54:05 +08:00
Thomas Göttgens
b78978156e Merge branch 'master' into apollo 2024-11-11 16:06:48 +01:00
Thomas Göttgens
eb8d38a7e9 radiolib update (#5246)
* update radiolib to 7.1.0
* stay at 7.0.2 for STM32, also remove unused board from ESP32 arch
---------
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2024-11-11 16:05:48 +01:00
Ben Meadors
3d5eb34c5c Add back some details to the PhoneAPI logs (#5313) 2024-11-11 07:01:29 -06:00
Ben Meadors
3a9a4bbb92 Coerce minimum neighborinfo interval on startup (#5314) 2024-11-11 07:00:56 -06:00
Daniel.Cao
6eba2789d0 rak10701 (rak wismeshtap) optimization (#5280)
* Improve the processing speed of virtual keyboards
* Remove the disable GPS feature, as it would interfere with the normal use of TFT
* Changed the default screen sleep time to 30s
* Rename platform rak10701 -> rak wismeshtap
* Fixed rak wismeshtap turned off gps caused the screen not to display
* Reduce the size of the flash, otherwise uf2 will not work

Co-authored-by: Daniel Cao <daniel.cao@rakwireless.com>
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Tom Fifield <tom@tomfifield.net>
2024-11-11 13:37:43 +01:00
GUVWAF
9b4c260a92 Fix memory leak in MQTT (#5311) 2024-11-11 13:22:22 +01:00
Ben Meadors
667b4ef0f2 Exclude some niche modules by default and populate exclude_modules (#5300)
* Exclude some niche modules by default

* Start of intelligently excluding modules

---------

Co-authored-by: Tom Fifield <tom@tomfifield.net>
2024-11-10 13:36:49 -06:00
Tom Fifield
db76561930 Package file move - include dotfiles (#5303)
Adds shopt -s dotglob nullglob to ensure we get 'hidden' files in
our move command.
2024-11-10 20:56:44 +08:00
Tom Fifield
7bad070891 Fix syntax error with package builds (#5302)
test (]) and its parameters need a space between them.
2024-11-10 06:13:58 -06:00
Tom Fifield
6365fcfdc6 Update dependency versions (#5299)
Using platformio pkg outdated, discover that some versions are not
up-to-date. Update all apart from RadioLib (existing pull) and
SensorLib (doesn't compile).

Also, trunk formatted platformio.ini

Package                   Current    Wanted     Latest     Type     Environments
------------------------  ---------  ---------  ---------  -------  --------------------------
Adafruit BME280 Library   2.2.2      2.2.2      2.2.4      Library  tracker-t1000-e
Adafruit INA260 Library   1.5.0      1.5.0      1.5.2      Library  tracker-t1000-e
Adafruit LPS2X            2.0.4      2.0.4      2.0.6      Library  tracker-t1000-e
Adafruit LSM6DS           4.7.2      4.7.2      4.7.3      Library  tracker-t1000-e
Adafruit MCP9808 Library  2.0.0      2.0.0      2.0.2      Library  tracker-t1000-e
Adafruit MPU6050          2.2.4      2.2.4      2.2.6      Library  tracker-t1000-e
Adafruit SHT4x Library    1.0.4      1.0.4      1.0.5      Library  tracker-t1000-e
Adafruit Unified Sensor   1.1.11     1.1.11     1.1.14     Library  tracker-t1000-e
BME68x Sensor library     1.1.40407  1.1.40407  1.2.40408  Library  tracker-t1000-e
QMC5883LCompass           1.2.0      1.2.0      1.2.3      Library  tracker-t1000-e
RadioLib                  7.0.2      7.0.2      7.1.0      Library  wio-sdk-wm1110
SensorLib                 0.2.0      0.2.0      0.2.2      Library  tbeam
2024-11-10 06:13:31 -06:00
Tom Fifield
ab2cbada75 Web now(?) comes in a /build subdirector in the tar (#5301)
* Web now(?) comes in a /build subdirector in the tar

So let's move everything to where it's expected and cleanup before
trying to unzip.

* Add checks to avoid running unneeded commands

stops this failing in the event the build subdir goes away.
2024-11-10 19:58:06 +08:00
Jonathan Bennett
875b8641d3 Pin library versions in platform.io (#5293)
* Pin library versions in platform.io

This has been a constant source of headache. This moves to only updating libraries manually. Will eliminate the random build failures, and make rebuilding specific release versions possible.

* Bump ina219 to latest library version

* More lib version bumps
2024-11-09 16:06:17 -06:00
Jonathan Bennett
67c2c516a0 Use sudo for building armv7 2024-11-09 12:44:06 -06:00
Tom Fifield
623203ca3b Remove scary warning about full NodeDB (#5292)
NodeDB becoming full at 100 entries and cycling out old entries is normal behaviour. The user doesn't need to take any action and shouldn't be concerned when this happens.

Remove the warning from the screen and reduce loglevel to info.
2024-11-09 07:30:04 -06:00
github-actions[bot]
f28f0a9d90 [create-pull-request] automated change (#5290)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
2024-11-09 05:31:09 -06:00
GUVWAF
893efe4f11 Always set the channel corresponding to a node (#5287) 2024-11-09 11:30:12 +08:00
GUVWAF
2c2213ef9b Add setting to transmit NeighborInfo over LoRa (#5286)
* Add setting to transmit NeighborInfo over LoRa
Only if not using the default channel

* Bump minimum broadcast interval for NeighborInfo to 4 hours
2024-11-09 09:38:48 +08:00
github-actions[bot]
439c1dec08 [create-pull-request] automated change (#5284)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
2024-11-08 07:53:55 -06:00
Tavis
aa184e6d8b copy the has_relative_humidity value to telem packet from AHTX0 packet (#5277)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2024-11-08 07:59:36 +08:00
Marco Veneziano
2eea412f1c Fixed compile error when using GPS_DEBUG (#5275) 2024-11-07 16:19:31 -06:00
Thomas Göttgens
b0a5a26f58 fix wio-tracker-dev sensor scan (#5274) 2024-11-07 18:01:58 +01:00
Thomas Göttgens
a815a770b4 Sync up ESP32 build variants 2024-11-07 15:03:05 +01:00
Austin
286f3c6458 uClibc compatibility (#5270)
* uclibc compatibility

Adds compatibility with uclibc, the officially supported toolchain of the luckfox pico

* Explicitly link stdc++fs for std::filesystem

Bringing this over from buildroot-meshtastic
2024-11-07 14:23:08 +01:00
github-actions[bot]
b506f6dcb0 [create-pull-request] automated change (#5272)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
2024-11-07 07:17:23 -06:00
Jeremiah K
bd3755bb33 Fix device flashing scripts so they work with esptool when it's installed via pipx (#5269)
* Try esptool.py in device flashing scripts for pipx compatibility

* esptool detection fixes in device flashing .bat's
2024-11-07 09:43:34 +08:00
Ben Meadors
73e2e25eb1 Smarter traffic scaling (#5264) 2024-11-06 15:00:53 -06:00
GUVWAF
3bd3911913 Only PKC encrypt when packet originates from us (#5267) 2024-11-06 22:00:26 +01:00
Ben Meadors
982190936d More log reductions. I'll probably stop now ;-) (#5263) 2024-11-06 21:03:25 +08:00
Ben Meadors
8498b175e7 Add exception for RTC to not strip time from position (#5262)
* Add exception for RTC to not strip time from position

* t
2024-11-06 10:06:43 +08:00
github-actions[bot]
255713d23d [create-pull-request] automated change (#5258)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
2024-11-05 19:33:20 -06:00
Thomas Göttgens
6860717c68 fix RP2040 builds 2024-11-03 15:08:01 +01:00
Thomas Göttgens
7d9b2ef3c4 Merge branch 'master' into apollo 2024-11-02 16:44:21 +01:00
Thomas Göttgens
7a3f30f99e Merge branch 'master' into apollo 2024-10-26 12:21:55 +02:00
Thomas Göttgens
02e258d5e9 Merge branch 'master' into apollo 2024-10-16 12:38:14 +02:00
Thomas Göttgens
19bcb60120 woopsie 2024-10-08 13:53:51 +02:00
Thomas Göttgens
f0c97b8806 Merge branch 'master' into apollo
# Conflicts:
#	arch/esp32/esp32.ini
#	arch/nrf52/nrf52.ini
#	arch/portduino/portduino.ini
#	arch/stm32/stm32.ini
#	protobufs
#	src/gps/GPS.cpp
#	src/main.cpp
#	src/mesh/StreamAPI.cpp
#	src/modules/ExternalNotificationModule.h
#	src/modules/NeighborInfoModule.cpp
2024-10-08 13:45:56 +02:00
Thomas Göttgens
047b8a587d Merge branch 'master' into apollo 2024-09-04 14:39:57 +02:00
Thomas Göttgens
c1a493fb35 update apollo toolchain 2024-09-02 17:16:51 +02:00
Thomas Göttgens
0e93470e34 Merge remote-tracking branch 'remotes/origin/master' into apollo 2024-09-02 17:00:03 +02:00
Thomas Göttgens
074ccbaa0c Merge branch 'master' into apollo 2024-06-19 21:38:29 +02:00
Andrew Litt
3765b9f3af Get apollo3 building again (#4141) 2024-06-19 11:22:35 -05:00
Thomas Göttgens
652441fcc0 Merge branch 'master' into apollo 2024-06-16 11:54:32 +02:00
Thomas Göttgens
688385fd75 Merge branch 'master' into apollo 2024-06-13 22:22:58 +02:00
Thomas Göttgens
f2116a06a7 Merge branch 'master' into apollo 2024-05-27 08:42:25 +02:00
Thomas Göttgens
7cbf66949b Merge branch 'master' into apollo 2024-05-18 15:36:50 +02:00
Thomas Göttgens
ed9bdf0e05 Merge branch 'master' into apollo 2024-05-17 11:49:28 +02:00
Thomas Göttgens
011cff2fe1 Merge branch 'master' into apollo 2024-04-23 13:01:08 +02:00
Thomas Göttgens
f50f61a52d Merge branch 'master' into apollo 2024-03-28 15:29:55 +01:00
Thomas Göttgens
72664b04f1 add FS macro guards 2024-03-18 15:09:23 +01:00
Thomas Göttgens
9be3b7bdc5 make apollo decent again 2024-03-18 15:02:23 +01:00
Thomas Göttgens
93d7f24d74 Merge branch 'master' into apollo 2024-03-18 12:03:44 +01:00
Thomas Göttgens
a7c0109349 trunk fmt 2024-03-08 13:22:06 +01:00
Thomas Göttgens
a9fc31c026 Merge branch 'master' into apollo 2024-03-05 10:09:45 +01:00
Thomas Göttgens
4996e2aace Merge branch 'master' into apollo 2024-02-23 11:03:38 +01:00
Ben Meadors
b2a313780f Merge branch 'master' into apollo 2023-12-12 17:39:18 -06:00
Thomas Göttgens
55a75d2f58 Making progress with OSFS, still WIP 2023-12-08 15:38:50 +01:00
Thomas Göttgens
dcae45d287 Merge remote-tracking branch 'remotes/origin/master' into apollo
# Conflicts:
#	arch/nrf52/nrf52.ini
#	arch/portduino/portduino.ini
#	arch/rp2040/rp2040.ini
#	arch/stm32/stm32wl5e.ini
2023-12-04 09:02:48 +01:00
Thomas Göttgens
7d5716d3af trunk fmt 2023-12-01 21:25:24 +01:00
Thomas Göttgens
81a783291d Merge branch 'master' into apollo 2023-12-01 18:28:00 +01:00
Thomas Göttgens
47b522fae4 Merge branch 'master' into apollo 2023-11-16 15:09:26 +01:00
Thomas Göttgens
c29b49f320 Merge branch 'master' into apollo 2023-10-31 14:10:07 +01:00
Thomas Göttgens
71645c029f Merge branch 'master' into apollo 2023-09-28 09:30:09 +02:00
Ben Meadors
acbbc95ebf Merge branch 'master' into apollo 2023-08-31 08:31:26 -05:00
Thomas Göttgens
a7bf7f47b5 trunk fmt 2023-08-17 12:24:43 +02:00
Thomas Göttgens
2b074e60d9 Merge branch 'master' into apollo 2023-08-17 10:06:19 +02:00
Ben Meadors
c31476d3e8 Merge branch 'master' into apollo 2023-08-08 06:27:45 -05:00
Ben Meadors
b6b52d89df Merge branch 'master' into apollo 2023-07-31 18:58:53 -05:00
Thomas Göttgens
534845450b Merge branch 'apollo' of github.com:meshtastic/firmware into apollo 2023-07-31 22:44:56 +02:00
Thomas Göttgens
7e2d729434 revert overcommit 2023-07-31 22:44:43 +02:00
Thomas Göttgens
de21b31ab0 Merge branch 'master' into apollo 2023-07-31 22:41:44 +02:00
Thomas Göttgens
db9cb3325f Merge branch 'apollo' of github.com:meshtastic/firmware into apollo 2023-07-31 22:35:39 +02:00
Thomas Göttgens
b8965d27bb Apollo3 WIP 2023-07-31 22:30:53 +02:00
Thomas Göttgens
72b1fa3889 Merge branch 'master' into apollo 2023-07-31 22:18:02 +02:00
Ben Meadors
ed432749e2 Merge branch 'master' into apollo 2023-07-30 07:54:27 -05:00
Thomas Göttgens
1369630292 Merge branch 'master' into apollo 2023-07-24 10:59:50 +02:00
Thomas Göttgens
b467ee09b8 Merge branch 'master' into apollo 2023-07-01 12:32:11 +02:00
Ben Meadors
8e088df363 Merge branch 'master' into apollo 2023-06-25 08:17:54 -05:00
Thomas Göttgens
9a79d34bce Merge branch 'master' into apollo 2023-06-12 15:33:20 +02:00
Thomas Göttgens
784381bae8 Merge branch 'master' into apollo 2023-05-10 17:12:50 +02:00
Thomas Göttgens
f826a85b0a Merge branch 'master' into apollo 2023-05-08 10:32:16 +02:00
Thomas Göttgens
a54ad6ba75 update apollo platform files and exclude from building other platforms 2023-04-24 17:09:47 +02:00
Thomas Göttgens
4b053ddd73 Merge branch 'apollo' of github.com:meshtastic/firmware into apollo 2023-04-24 16:43:02 +02:00
Ben Meadors
681377cc97 Moar 2023-04-24 14:57:56 +02:00
Ben Meadors
1eff8fdba8 WIP scaffolding 2023-04-24 14:57:56 +02:00
Ben Meadors
516fc5ceed Moar 2023-04-15 09:16:18 +02:00
Ben Meadors
a7f9e5ddb4 WIP scaffolding 2023-04-15 09:16:18 +02:00
159 changed files with 2527 additions and 591 deletions

View File

@@ -51,6 +51,7 @@ runs:
file: build.tar file: build.tar
target: build.tar target: build.tar
token: ${{ inputs.github_token }} token: ${{ inputs.github_token }}
version: tags/v2.5.3
- name: Unpack web ui - name: Unpack web ui
if: inputs.include-web-ui == 'true' if: inputs.include-web-ui == 'true'

View File

@@ -7,6 +7,8 @@ on:
required: true required: true
type: string type: string
permissions: read-all
jobs: jobs:
build-esp32: build-esp32:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -24,6 +26,7 @@ jobs:
./arch/esp32/esp32s2.ini ./arch/esp32/esp32s2.ini
./arch/esp32/esp32s3.ini ./arch/esp32/esp32s3.ini
./arch/esp32/esp32c3.ini ./arch/esp32/esp32c3.ini
./arch/esp32/esp32c6.ini
build-script-path: bin/build-esp32.sh build-script-path: bin/build-esp32.sh
ota-firmware-source: firmware.bin ota-firmware-source: firmware.bin
ota-firmware-target: release/bleota.bin ota-firmware-target: release/bleota.bin

View File

@@ -26,10 +26,12 @@ jobs:
./arch/esp32/esp32s2.ini ./arch/esp32/esp32s2.ini
./arch/esp32/esp32s3.ini ./arch/esp32/esp32s3.ini
./arch/esp32/esp32c3.ini ./arch/esp32/esp32c3.ini
./arch/esp32/esp32c6.ini
build-script-path: bin/build-esp32.sh build-script-path: bin/build-esp32.sh
ota-firmware-source: firmware-c3.bin ota-firmware-source: firmware-c3.bin
ota-firmware-target: release/bleota-c3.bin ota-firmware-target: release/bleota-c3.bin
artifact-paths: | artifact-paths: |
release/*.bin release/*.bin
release/*.elf release/*.elf
include-web-ui: true
arch: esp32c3 arch: esp32c3

View File

@@ -33,4 +33,5 @@ jobs:
artifact-paths: | artifact-paths: |
release/*.bin release/*.bin
release/*.elf release/*.elf
include-web-ui: true
arch: esp32c6 arch: esp32c6

View File

@@ -7,6 +7,8 @@ on:
required: true required: true
type: string type: string
permissions: read-all
jobs: jobs:
build-esp32-s3: build-esp32-s3:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -24,6 +26,7 @@ jobs:
./arch/esp32/esp32s2.ini ./arch/esp32/esp32s2.ini
./arch/esp32/esp32s3.ini ./arch/esp32/esp32s3.ini
./arch/esp32/esp32c3.ini ./arch/esp32/esp32c3.ini
./arch/esp32/esp32c6.ini
build-script-path: bin/build-esp32.sh build-script-path: bin/build-esp32.sh
ota-firmware-source: firmware-s3.bin ota-firmware-source: firmware-s3.bin
ota-firmware-target: release/bleota-s3.bin ota-firmware-target: release/bleota-s3.bin

View File

@@ -13,8 +13,8 @@ jobs:
- name: Install libbluetooth - name: Install libbluetooth
shell: bash shell: bash
run: | run: |
apt-get update -y --fix-missing sudo apt-get update -y --fix-missing
apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v4

View File

@@ -13,8 +13,8 @@ jobs:
- name: Install libbluetooth - name: Install libbluetooth
shell: bash shell: bash
run: | run: |
apt-get update -y --fix-missing sudo apt-get update -y --fix-missing
apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v4

View File

@@ -203,6 +203,7 @@ jobs:
./device-*.sh ./device-*.sh
./device-*.bat ./device-*.bat
./littlefs-*.bin ./littlefs-*.bin
./littlefswebui-*.bin
./bleota*bin ./bleota*bin
./Meshtastic_nRF52_factory_erase*.uf2 ./Meshtastic_nRF52_factory_erase*.uf2
retention-days: 30 retention-days: 30

View File

@@ -54,6 +54,10 @@ jobs:
mkdir -p .debpkg/etc/meshtasticd/available.d mkdir -p .debpkg/etc/meshtasticd/available.d
mkdir -p .debpkg/usr/lib/systemd/system/ mkdir -p .debpkg/usr/lib/systemd/system/
tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web
shopt -s dotglob nullglob
if [ -d .debpkg/usr/share/doc/meshtasticd/web/build ]; then mv .debpkg/usr/share/doc/meshtasticd/web/build/* .debpkg/usr/share/doc/meshtasticd/web/; fi
if [ -d .debpkg/usr/share/doc/meshtasticd/web/build ]; then rmdir .debpkg/usr/share/doc/meshtasticd/web/build; fi
if [ -d .debpkg/usr/share/doc/meshtasticd/web/.DS_Store]; then rm -f .debpkg/usr/share/doc/meshtasticd/web/.DS_Store; fi
gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz
cp release/meshtasticd_linux_x86_64 .debpkg/usr/sbin/meshtasticd cp release/meshtasticd_linux_x86_64 .debpkg/usr/sbin/meshtasticd
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml

View File

@@ -54,6 +54,10 @@ jobs:
mkdir -p .debpkg/etc/meshtasticd/available.d mkdir -p .debpkg/etc/meshtasticd/available.d
mkdir -p .debpkg/usr/lib/systemd/system/ mkdir -p .debpkg/usr/lib/systemd/system/
tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web
shopt -s dotglob nullglob
if [ -d .debpkg/usr/share/doc/meshtasticd/web/build ]; then mv .debpkg/usr/share/doc/meshtasticd/web/build/* .debpkg/usr/share/doc/meshtasticd/web/; fi
if [ -d .debpkg/usr/share/doc/meshtasticd/web/build ]; then rmdir .debpkg/usr/share/doc/meshtasticd/web/build; fi
if [ -d .debpkg/usr/share/doc/meshtasticd/web/.DS_Store]; then rm -f .debpkg/usr/share/doc/meshtasticd/web/.DS_Store; fi
gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz
cp release/meshtasticd_linux_aarch64 .debpkg/usr/sbin/meshtasticd cp release/meshtasticd_linux_aarch64 .debpkg/usr/sbin/meshtasticd
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml

View File

@@ -54,6 +54,10 @@ jobs:
mkdir -p .debpkg/etc/meshtasticd/available.d mkdir -p .debpkg/etc/meshtasticd/available.d
mkdir -p .debpkg/usr/lib/systemd/system/ mkdir -p .debpkg/usr/lib/systemd/system/
tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web
shopt -s dotglob nullglob
if [ -d .debpkg/usr/share/doc/meshtasticd/web/build ]; then mv .debpkg/usr/share/doc/meshtasticd/web/build/* .debpkg/usr/share/doc/meshtasticd/web/; fi
if [ -d .debpkg/usr/share/doc/meshtasticd/web/build ]; then rmdir .debpkg/usr/share/doc/meshtasticd/web/build; fi
if [ -d .debpkg/usr/share/doc/meshtasticd/web/.DS_Store]; then rm -f .debpkg/usr/share/doc/meshtasticd/web/.DS_Store; fi
gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz
cp release/meshtasticd_linux_armv7l .debpkg/usr/sbin/meshtasticd cp release/meshtasticd_linux_armv7l .debpkg/usr/sbin/meshtasticd
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml

View File

@@ -1,6 +1,6 @@
version: 0.1 version: 0.1
cli: cli:
version: 1.22.7 version: 1.22.8
plugins: plugins:
sources: sources:
- id: trunk - id: trunk
@@ -8,20 +8,20 @@ plugins:
uri: https://github.com/trunk-io/plugins uri: https://github.com/trunk-io/plugins
lint: lint:
enabled: enabled:
- trufflehog@3.83.2 - trufflehog@3.83.6
- yamllint@1.35.1 - yamllint@1.35.1
- bandit@1.7.10 - bandit@1.7.10
- checkov@3.2.277 - checkov@3.2.287
- terrascan@1.19.9 - terrascan@1.19.9
- trivy@0.56.2 - trivy@0.56.2
#- trufflehog@3.63.2-rc0 #- trufflehog@3.63.2-rc0
- taplo@0.9.3 - taplo@0.9.3
- ruff@0.7.2 - ruff@0.7.3
- isort@5.13.2 - isort@5.13.2
- markdownlint@0.42.0 - markdownlint@0.42.0
- oxipng@9.1.2 - oxipng@9.1.2
- svgo@3.3.2 - svgo@3.3.2
- actionlint@1.7.3 - actionlint@1.7.4
- flake8@7.1.1 - flake8@7.1.1
- hadolint@2.12.0 - hadolint@2.12.0
- shfmt@3.6.0 - shfmt@3.6.0

View File

@@ -2,9 +2,8 @@
// See http://go.microsoft.com/fwlink/?LinkId=827846 // See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format // for the documentation about the extensions.json format
"recommendations": [ "recommendations": [
"platformio.platformio-ide" "ms-vscode.cpptools",
"platformio.platformio-ide",
"trunk.io"
], ],
"unwantedRecommendations": [
"ms-vscode.cpptools-extension-pack"
]
} }

33
arch/apollo3/apollo3.ini Normal file
View File

@@ -0,0 +1,33 @@
[apollo3_base]
extends = arduino_base
platform = https://github.com/nigelb/platform-apollo3blue.git#2e8a9895cf82f2836c483885e6f89b3f83d3ade4
platform_packages=framework-arduinoapollo3@https://github.com/sparkfun/Arduino_Apollo3#a0d99c5fc9b1112d46a9d11c1339898d01e586c9
build_type = debug
build_flags =
${arduino_base.build_flags}
-Isrc/platform/apollo3 -g
-I"${platformio.packages_dir}/framework-arduinoapollo3/libraries/SPI/src"
-DRADIOLIB_EEPROM_UNSUPPORTED
-DMESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
build_src_filter =
${arduino_base.build_src_filter}
-<platform/nrf52>
-<platform/esp32/>
-<platform/rp2040>
-<platform/portduino>
-<platform/stm32wl>
-<nimble/>
-<mesh/api/>
-<mesh/http/>
-<mesh/wifi/>
-<modules/esp32>
-<mesh/eth/>
-<input>
-<buzz>
-<modules/Telemetry>
lib_deps =
${env.lib_deps}
charlesbaynham/OSFS@^1.2.3
rweather/Crypto
lib_ignore =
mathertel/OneButton

View File

@@ -5,7 +5,13 @@ custom_esp32_kind = esp32
platform = platformio/espressif32@6.9.0 platform = platformio/espressif32@6.9.0
build_src_filter = build_src_filter =
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2xx0> -<mesh/eth/> -<mesh/raspihttp> ${arduino_base.build_src_filter}
-<platform/nrf52/>
-<platform/stm32wl>
-<platform/rp2xx0>
-<platform/apollo3>
-<mesh/eth/>
-<mesh/raspihttp>
upload_speed = 921600 upload_speed = 921600
debug_init_break = tbreak setup debug_init_break = tbreak setup
@@ -43,9 +49,10 @@ lib_deps =
${arduino_base.lib_deps} ${arduino_base.lib_deps}
${networking_base.lib_deps} ${networking_base.lib_deps}
${environmental_base.lib_deps} ${environmental_base.lib_deps}
${radiolib_base.lib_deps}
https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2 https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2
h2zero/NimBLE-Arduino@^1.4.2 h2zero/NimBLE-Arduino@^1.4.2
https://github.com/dbSuS/libpax.git#7bcd3fcab75037505be9b122ab2b24cc5176b587 https://github.com/dbinfrago/libpax.git#3cdc0371c375676a97967547f4065607d4c53fd1
lewisxhe/XPowersLib@^0.2.6 lewisxhe/XPowersLib@^0.2.6
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
rweather/Crypto@^0.4.0 rweather/Crypto@^0.4.0

View File

@@ -1,5 +1,6 @@
[esp32c3_base] [esp32c3_base]
extends = esp32_base extends = esp32_base
custom_esp32_kind = esp32c3 custom_esp32_kind = esp32c3
monitor_speed = 115200 monitor_speed = 115200

View File

@@ -23,6 +23,7 @@ lib_deps =
${arduino_base.lib_deps} ${arduino_base.lib_deps}
${networking_base.lib_deps} ${networking_base.lib_deps}
${environmental_base.lib_deps} ${environmental_base.lib_deps}
${radiolib_base.lib_deps}
lewisxhe/XPowersLib@^0.2.6 lewisxhe/XPowersLib@^0.2.6
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
rweather/Crypto@^0.4.0 rweather/Crypto@^0.4.0

View File

@@ -1,6 +1,6 @@
[esp32s3_base] [esp32s3_base]
extends = esp32_base extends = esp32_base
custom_esp32_kind = esp32s3 custom_esp32_kind = esp32s3
monitor_speed = 115200 monitor_speed = 115200

View File

@@ -14,12 +14,27 @@ build_flags =
-Wno-unused-variable -Wno-unused-variable
-Isrc/platform/nrf52 -Isrc/platform/nrf52
-DLFS_NO_ASSERT ; Disable LFS assertions , see https://github.com/meshtastic/firmware/pull/3818 -DLFS_NO_ASSERT ; Disable LFS assertions , see https://github.com/meshtastic/firmware/pull/3818
-DMESHTASTIC_EXCLUDE_AUDIO=1
-DMESHTASTIC_EXCLUDE_PAXCOUNTER=1
-DMAX_NUM_NODES=80
build_src_filter = build_src_filter =
${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/wifi/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<platform/rp2xx0> -<mesh/eth/> -<mesh/raspihttp> ${arduino_base.build_src_filter}
-<platform/esp32/>
-<platform/stm32wl>
-<nimble/>
-<mesh/wifi/>
-<mesh/api/>
-<mesh/http/>
-<modules/esp32>
-<platform/rp2xx0>
-<mesh/eth/>
-<mesh/raspihttp>
-<platform/apollo3>
lib_deps= lib_deps=
${arduino_base.lib_deps} ${arduino_base.lib_deps}
${radiolib_base.lib_deps}
rweather/Crypto@^0.4.0 rweather/Crypto@^0.4.0
lib_ignore = lib_ignore =

View File

@@ -10,6 +10,7 @@ build_src_filter =
-<platform/nrf52/> -<platform/nrf52/>
-<platform/stm32wl/> -<platform/stm32wl/>
-<platform/rp2xx0> -<platform/rp2xx0>
-<platform/apollo3>
-<mesh/wifi/> -<mesh/wifi/>
-<mesh/http/> -<mesh/http/>
+<mesh/raspihttp/> +<mesh/raspihttp/>
@@ -23,6 +24,7 @@ build_src_filter =
lib_deps = lib_deps =
${env.lib_deps} ${env.lib_deps}
${networking_base.lib_deps} ${networking_base.lib_deps}
${radiolib_base.lib_deps}
rweather/Crypto@^0.4.0 rweather/Crypto@^0.4.0
https://github.com/lovyan03/LovyanGFX.git#1401c28a47646fe00538d487adcb2eb3c72de805 https://github.com/lovyan03/LovyanGFX.git#1401c28a47646fe00538d487adcb2eb3c72de805
@@ -32,6 +34,7 @@ build_flags =
-Isrc/platform/portduino -Isrc/platform/portduino
-DRADIOLIB_EEPROM_UNSUPPORTED -DRADIOLIB_EEPROM_UNSUPPORTED
-DPORTDUINO_LINUX_HARDWARE -DPORTDUINO_LINUX_HARDWARE
-lstdc++fs
-lbluetooth -lbluetooth
-lgpiod -lgpiod
-lyaml-cpp -lyaml-cpp

View File

@@ -1,8 +1,8 @@
; Common settings for rp2040 Processor based targets ; Common settings for rp2040 Processor based targets
[rp2040_base] [rp2040_base]
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#v1.2.0-gcc12 platform = https://github.com/maxgerhardt/platform-raspberrypi.git#19e30129fb1428b823be585c787dcb4ac0d9014c ; For arduino-pico 4.2.1
extends = arduino_base extends = arduino_base
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#4.0.3 platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#996c3bfab9758f12c07aa20cc6d352e630c16987 ; 4.2.1 with fix for sporadic hangs
board_build.core = earlephilhower board_build.core = earlephilhower
board_build.filesystem_size = 0.5m board_build.filesystem_size = 0.5m
@@ -14,7 +14,7 @@ build_flags =
-D__PLAT_RP2040__ -D__PLAT_RP2040__
# -D _POSIX_THREADS # -D _POSIX_THREADS
build_src_filter = build_src_filter =
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<modules/esp32> -<platform/nrf52/> -<platform/stm32wl> -<mesh/eth/> -<mesh/wifi/> -<mesh/http/> -<mesh/raspihttp> ${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<modules/esp32> -<platform/nrf52/> -<platform/apollo3> -<platform/stm32wl> -<mesh/eth/> -<mesh/wifi/> -<mesh/http/> -<mesh/raspihttp>
lib_ignore = lib_ignore =
BluetoothOTA BluetoothOTA
@@ -22,4 +22,5 @@ lib_ignore =
lib_deps = lib_deps =
${arduino_base.lib_deps} ${arduino_base.lib_deps}
${environmental_base.lib_deps} ${environmental_base.lib_deps}
${radiolib_base.lib_deps}
rweather/Crypto rweather/Crypto

View File

@@ -1,8 +1,8 @@
; Common settings for rp2040 Processor based targets ; Common settings for rp2040 Processor based targets
[rp2350_base] [rp2350_base]
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#9e55f6db5c56b9867c69fe473f388beea4546672 platform = https://github.com/maxgerhardt/platform-raspberrypi.git#19e30129fb1428b823be585c787dcb4ac0d9014c ; For arduino-pico 4.2.1
extends = arduino_base extends = arduino_base
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#a6ab6e1f95bc1428d667d55ea7173c0744acc03c ; 4.0.2+ platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#96c3bfab9758f12c07aa20cc6d352e630c16987 ; 4.2.1 with fix for sporadic hangs
board_build.core = earlephilhower board_build.core = earlephilhower
board_build.filesystem_size = 0.5m board_build.filesystem_size = 0.5m
@@ -12,7 +12,17 @@ build_flags =
-D__PLAT_RP2040__ -D__PLAT_RP2040__
# -D _POSIX_THREADS # -D _POSIX_THREADS
build_src_filter = build_src_filter =
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<modules/esp32> -<platform/nrf52/> -<platform/stm32wl> -<mesh/eth/> -<mesh/wifi/> -<mesh/http/> -<mesh/raspihttp> ${arduino_base.build_src_filter}
-<platform/esp32/>
-<nimble/>
-<modules/esp32>
-<platform/nrf52/>
-<platform/stm32wl>
-<mesh/eth/>
-<mesh/wifi/>
-<mesh/http/>
-<platform/apollo3>
-<mesh/raspihttp>
lib_ignore = lib_ignore =
BluetoothOTA BluetoothOTA
@@ -21,4 +31,5 @@ lib_ignore =
lib_deps = lib_deps =
${arduino_base.lib_deps} ${arduino_base.lib_deps}
${environmental_base.lib_deps} ${environmental_base.lib_deps}
rweather/Crypto ${radiolib_base.lib_deps}
rweather/Crypto

View File

@@ -22,7 +22,7 @@ build_flags =
-fdata-sections -fdata-sections
build_src_filter = build_src_filter =
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<input> -<buzz> -<modules/RemoteHardwareModule.cpp> -<platform/nrf52> -<platform/portduino> -<platform/rp2xx0> -<mesh/raspihttp> ${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<input> -<buzz> -<modules/RemoteHardwareModule.cpp> -<platform/nrf52> -<platform/portduino> -<platform/rp2xx0> -<platform/apollo3> -<mesh/raspihttp>
board_upload.offset_address = 0x08000000 board_upload.offset_address = 0x08000000
upload_protocol = stlink upload_protocol = stlink
@@ -30,8 +30,9 @@ upload_protocol = stlink
lib_deps = lib_deps =
${env.lib_deps} ${env.lib_deps}
charlesbaynham/OSFS@^1.2.3 charlesbaynham/OSFS@^1.2.3
jgromes/RadioLib@7.0.2
https://github.com/caveman99/Crypto.git#f61ae26a53f7a2d0ba5511625b8bf8eff3a35d5e https://github.com/caveman99/Crypto.git#f61ae26a53f7a2d0ba5511625b8bf8eff3a35d5e
lib_ignore = lib_ignore =
mathertel/OneButton@~2.6.1 mathertel/OneButton@2.6.1
Wire Wire

33
bin/base64_to_hex.py Normal file
View File

@@ -0,0 +1,33 @@
import sys
import base64
def base64_to_hex_string(b64_string):
try:
# Decode the Base64 string to raw bytes
decoded_bytes = base64.b64decode(b64_string)
except Exception as e:
raise ValueError(f"Invalid Base64 input: {e}")
# Check if the decoded result is exactly 32 bytes
if len(decoded_bytes) != 32:
raise ValueError("Decoded Base64 input must be exactly 32 bytes.")
# Convert each byte to its hex representation
hex_values = [f"0x{byte:02x}" for byte in decoded_bytes]
# Join the formatted hex values with commas
formatted_output = "{ " + ", ".join(hex_values) + " };"
return formatted_output
if __name__ == "__main__":
# Check if a Base64 string was provided in command line arguments
if len(sys.argv) != 2:
print("Usage: python script.py <base64-string>")
sys.exit(1)
b64_string = sys.argv[1]
try:
formatted_hex = base64_to_hex_string(b64_string)
print(formatted_hex)
except ValueError as e:
print(e)

View File

@@ -35,6 +35,11 @@ cp $SRCBIN $OUTDIR/$basename-update.bin
echo "Building Filesystem for ESP32 targets" echo "Building Filesystem for ESP32 targets"
pio run --environment $1 -t buildfs pio run --environment $1 -t buildfs
cp .pio/build/$1/littlefs.bin $OUTDIR/littlefswebui-$VERSION.bin
# Remove webserver files from the filesystem and rebuild
ls -l data/static # Diagnostic list of files
rm -rf data/static
pio run --environment $1 -t buildfs
cp .pio/build/$1/littlefs.bin $OUTDIR/littlefs-$VERSION.bin cp .pio/build/$1/littlefs.bin $OUTDIR/littlefs-$VERSION.bin
cp bin/device-install.* $OUTDIR cp bin/device-install.* $OUTDIR
cp bin/device-update.* $OUTDIR cp bin/device-update.* $OUTDIR

View File

@@ -27,5 +27,4 @@ rm -r $OUTDIR/* || true
platformio pkg update --environment native || platformioFailed platformio pkg update --environment native || platformioFailed
pio run --environment native || platformioFailed pio run --environment native || platformioFailed
cp .pio/build/native/program "$OUTDIR/meshtasticd_linux_$(uname -m)" cp .pio/build/native/program "$OUTDIR/meshtasticd_linux_$(uname -m)"
cp bin/device-install.* $OUTDIR cp bin/native-install.* $OUTDIR
cp bin/device-update.* $OUTDIR

View File

@@ -1,16 +1,26 @@
@ECHO OFF @ECHO OFF
set PYTHON=python set PYTHON=python
set WEB_APP=0
:: Determine the correct esptool command to use
where esptool >nul 2>&1
if %ERRORLEVEL% EQU 0 (
set "ESPTOOL_CMD=esptool"
) else (
set "ESPTOOL_CMD=%PYTHON% -m esptool"
)
goto GETOPTS goto GETOPTS
:HELP :HELP
echo Usage: %~nx0 [-h] [-p ESPTOOL_PORT] [-P PYTHON] [-f FILENAME^|FILENAME] echo Usage: %~nx0 [-h] [-p ESPTOOL_PORT] [-P PYTHON] [-f FILENAME^|FILENAME] [--web]
echo Flash image file to device, but first erasing and writing system information echo Flash image file to device, but first erasing and writing system information
echo. echo.
echo -h Display this help and exit echo -h Display this help and exit
echo -p ESPTOOL_PORT Set the environment variable for ESPTOOL_PORT. If not set, ESPTOOL iterates all ports (Dangerrous). echo -p ESPTOOL_PORT Set the environment variable for ESPTOOL_PORT. If not set, ESPTOOL iterates all ports (Dangerrous).
echo -P PYTHON Specify alternate python interpreter to use to invoke esptool. (Default: %PYTHON%) echo -P PYTHON Specify alternate python interpreter to use to invoke esptool. (Default: %PYTHON%)
echo -f FILENAME The .bin file to flash. Custom to your device type and region. echo -f FILENAME The .bin file to flash. Custom to your device type and region.
echo --web Flash WEB APP.
goto EOF goto EOF
:GETOPTS :GETOPTS
@@ -19,37 +29,44 @@ if /I "%1"=="--help" goto HELP
if /I "%1"=="-F" set "FILENAME=%2" & SHIFT if /I "%1"=="-F" set "FILENAME=%2" & SHIFT
if /I "%1"=="-p" set ESPTOOL_PORT=%2 & SHIFT if /I "%1"=="-p" set ESPTOOL_PORT=%2 & SHIFT
if /I "%1"=="-P" set PYTHON=%2 & SHIFT if /I "%1"=="-P" set PYTHON=%2 & SHIFT
if /I "%1"=="--web" set WEB_APP=1 & SHIFT
SHIFT SHIFT
IF NOT "__%1__"=="____" goto GETOPTS IF NOT "__%1__"=="____" goto GETOPTS
IF "__%FILENAME%__" == "____" ( IF "__%FILENAME%__" == "____" (
echo "Missing FILENAME" echo "Missing FILENAME"
goto HELP goto HELP
) )
IF EXIST %FILENAME% IF x%FILENAME:update=%==x%FILENAME% ( IF EXIST %FILENAME% IF x%FILENAME:update=%==x%FILENAME% (
echo Trying to flash update %FILENAME%, but first erasing and writing system information" echo Trying to flash update %FILENAME%, but first erasing and writing system information"
%PYTHON% -m esptool --baud 115200 erase_flash %ESPTOOL_CMD% --baud 115200 erase_flash
%PYTHON% -m esptool --baud 115200 write_flash 0x00 %FILENAME% %ESPTOOL_CMD% --baud 115200 write_flash 0x00 %FILENAME%
@REM Account for S3 and C3 board's different OTA partition @REM Account for S3 and C3 board's different OTA partition
IF x%FILENAME:s3=%==x%FILENAME% IF x%FILENAME:v3=%==x%FILENAME% IF x%FILENAME:t-deck=%==x%FILENAME% IF x%FILENAME:wireless-paper=%==x%FILENAME% IF x%FILENAME:wireless-tracker=%==x%FILENAME% IF x%FILENAME:station-g2=%==x%FILENAME% IF x%FILENAME:unphone=%==x%FILENAME% ( IF x%FILENAME:s3=%==x%FILENAME% IF x%FILENAME:v3=%==x%FILENAME% IF x%FILENAME:t-deck=%==x%FILENAME% IF x%FILENAME:wireless-paper=%==x%FILENAME% IF x%FILENAME:wireless-tracker=%==x%FILENAME% IF x%FILENAME:station-g2=%==x%FILENAME% IF x%FILENAME:unphone=%==x%FILENAME% (
IF x%FILENAME:esp32c3=%==x%FILENAME% ( IF x%FILENAME:esp32c3=%==x%FILENAME% (
%PYTHON% -m esptool --baud 115200 write_flash 0x260000 bleota.bin %ESPTOOL_CMD% --baud 115200 write_flash 0x260000 bleota.bin
) else ( ) else (
%PYTHON% -m esptool --baud 115200 write_flash 0x260000 bleota-c3.bin %ESPTOOL_CMD% --baud 115200 write_flash 0x260000 bleota-c3.bin
) )
) else ( ) else (
%PYTHON% -m esptool --baud 115200 write_flash 0x260000 bleota-s3.bin %ESPTOOL_CMD% --baud 115200 write_flash 0x260000 bleota-s3.bin
) )
for %%f in (littlefs-*.bin) do ( IF %WEB_APP%==1 (
%PYTHON% -m esptool --baud 115200 write_flash 0x300000 %%f for %%f in (littlefswebui-*.bin) do (
%ESPTOOL_CMD% --baud 115200 write_flash 0x300000 %%f
)
) else (
for %%f in (littlefs-*.bin) do (
%ESPTOOL_CMD% --baud 115200 write_flash 0x300000 %%f
)
) )
) else ( ) else (
echo "Invalid file: %FILENAME%" echo "Invalid file: %FILENAME%"
goto HELP goto HELP
) else ( ) else (
echo "Invalid file: %FILENAME%" echo "Invalid file: %FILENAME%"
goto HELP goto HELP
) )
:EOF :EOF

View File

@@ -1,22 +1,45 @@
#!/bin/sh #!/bin/sh
PYTHON=${PYTHON:-$(which python3 python | head -n 1)} PYTHON=${PYTHON:-$(which python3 python | head -n 1)}
WEB_APP=false
# Determine the correct esptool command to use
if "$PYTHON" -m esptool version >/dev/null 2>&1; then
ESPTOOL_CMD="$PYTHON -m esptool"
elif command -v esptool >/dev/null 2>&1; then
ESPTOOL_CMD="esptool"
elif command -v esptool.py >/dev/null 2>&1; then
ESPTOOL_CMD="esptool.py"
else
echo "Error: esptool not found"
exit 1
fi
set -e set -e
# Usage info # Usage info
show_help() { show_help() {
cat <<EOF cat <<EOF
Usage: $(basename $0) [-h] [-p ESPTOOL_PORT] [-P PYTHON] [-f FILENAME|FILENAME] Usage: $(basename $0) [-h] [-p ESPTOOL_PORT] [-P PYTHON] [-f FILENAME|FILENAME] [--web]
Flash image file to device, but first erasing and writing system information" Flash image file to device, but first erasing and writing system information"
-h Display this help and exit -h Display this help and exit
-p ESPTOOL_PORT Set the environment variable for ESPTOOL_PORT. If not set, ESPTOOL iterates all ports (Dangerous). -p ESPTOOL_PORT Set the environment variable for ESPTOOL_PORT. If not set, ESPTOOL iterates all ports (Dangerous).
-P PYTHON Specify alternate python interpreter to use to invoke esptool. (Default: "$PYTHON") -P PYTHON Specify alternate python interpreter to use to invoke esptool. (Default: "$PYTHON")
-f FILENAME The .bin file to flash. Custom to your device type and region. -f FILENAME The .bin file to flash. Custom to your device type and region.
--web Flash WEB APP.
EOF EOF
} }
# Preprocess long options like --web
for arg in "$@"; do
case "$arg" in
--web)
WEB_APP=true
shift # Remove this argument from the list
;;
esac
done
while getopts ":hp:P:f:" opt; do while getopts ":hp:P:f:" opt; do
case "${opt}" in case "${opt}" in
@@ -49,19 +72,23 @@ shift "$((OPTIND - 1))"
if [ -f "${FILENAME}" ] && [ -n "${FILENAME##*"update"*}" ]; then if [ -f "${FILENAME}" ] && [ -n "${FILENAME##*"update"*}" ]; then
echo "Trying to flash ${FILENAME}, but first erasing and writing system information" echo "Trying to flash ${FILENAME}, but first erasing and writing system information"
"$PYTHON" -m esptool erase_flash $ESPTOOL_CMD erase_flash
"$PYTHON" -m esptool write_flash 0x00 ${FILENAME} $ESPTOOL_CMD write_flash 0x00 ${FILENAME}
# Account for S3 board's different OTA partition # Account for S3 board's different OTA partition
if [ -n "${FILENAME##*"s3"*}" ] && [ -n "${FILENAME##*"-v3"*}" ] && [ -n "${FILENAME##*"t-deck"*}" ] && [ -n "${FILENAME##*"wireless-paper"*}" ] && [ -n "${FILENAME##*"wireless-tracker"*}" ] && [ -n "${FILENAME##*"station-g2"*}" ] && [ -n "${FILENAME##*"unphone"*}" ]; then if [ -n "${FILENAME##*"s3"*}" ] && [ -n "${FILENAME##*"-v3"*}" ] && [ -n "${FILENAME##*"t-deck"*}" ] && [ -n "${FILENAME##*"wireless-paper"*}" ] && [ -n "${FILENAME##*"wireless-tracker"*}" ] && [ -n "${FILENAME##*"station-g2"*}" ] && [ -n "${FILENAME##*"unphone"*}" ]; then
if [ -n "${FILENAME##*"esp32c3"*}" ]; then if [ -n "${FILENAME##*"esp32c3"*}" ]; then
"$PYTHON" -m esptool write_flash 0x260000 bleota.bin $ESPTOOL_CMD write_flash 0x260000 bleota.bin
else else
"$PYTHON" -m esptool write_flash 0x260000 bleota-c3.bin $ESPTOOL_CMD write_flash 0x260000 bleota-c3.bin
fi fi
else else
"$PYTHON" -m esptool write_flash 0x260000 bleota-s3.bin $ESPTOOL_CMD write_flash 0x260000 bleota-s3.bin
fi
if [ "$WEB_APP" = true ]; then
$ESPTOOL_CMD write_flash 0x300000 littlefswebui-*.bin
else
$ESPTOOL_CMD write_flash 0x300000 littlefs-*.bin
fi fi
"$PYTHON" -m esptool write_flash 0x300000 littlefs-*.bin
else else
show_help show_help

View File

@@ -2,6 +2,14 @@
set PYTHON=python set PYTHON=python
:: Determine the correct esptool command to use
where esptool >nul 2>&1
if %ERRORLEVEL% EQU 0 (
set "ESPTOOL_CMD=esptool"
) else (
set "ESPTOOL_CMD=%PYTHON% -m esptool"
)
goto GETOPTS goto GETOPTS
:HELP :HELP
echo Usage: %~nx0 [-h] [-p ESPTOOL_PORT] [-P PYTHON] [-f FILENAME^|FILENAME] echo Usage: %~nx0 [-h] [-p ESPTOOL_PORT] [-P PYTHON] [-f FILENAME^|FILENAME]
@@ -24,17 +32,17 @@ IF NOT "__%1__"=="____" goto GETOPTS
IF "__%FILENAME%__" == "____" ( IF "__%FILENAME%__" == "____" (
echo "Missing FILENAME" echo "Missing FILENAME"
goto HELP goto HELP
) )
IF EXIST %FILENAME% IF NOT x%FILENAME:update=%==x%FILENAME% ( IF EXIST %FILENAME% IF NOT x%FILENAME:update=%==x%FILENAME% (
echo Trying to flash update %FILENAME% echo Trying to flash update %FILENAME%
%PYTHON% -m esptool --baud 115200 write_flash 0x10000 %FILENAME% %ESPTOOL_CMD% --baud 115200 write_flash 0x10000 %FILENAME%
) else ( ) else (
echo "Invalid file: %FILENAME%" echo "Invalid file: %FILENAME%"
goto HELP goto HELP
) else ( ) else (
echo "Invalid file: %FILENAME%" echo "Invalid file: %FILENAME%"
goto HELP goto HELP
) )
:EOF :EOF

View File

@@ -2,6 +2,18 @@
PYTHON=${PYTHON:-$(which python3 python|head -n 1)} PYTHON=${PYTHON:-$(which python3 python|head -n 1)}
# Determine the correct esptool command to use
if "$PYTHON" -m esptool version >/dev/null 2>&1; then
ESPTOOL_CMD="$PYTHON -m esptool"
elif command -v esptool >/dev/null 2>&1; then
ESPTOOL_CMD="esptool"
elif command -v esptool.py >/dev/null 2>&1; then
ESPTOOL_CMD="esptool.py"
else
echo "Error: esptool not found"
exit 1
fi
# Usage info # Usage info
show_help() { show_help() {
cat << EOF cat << EOF
@@ -9,7 +21,7 @@ Usage: $(basename $0) [-h] [-p ESPTOOL_PORT] [-P PYTHON] [-f FILENAME|FILENAME]
Flash image file to device, leave existing system intact." Flash image file to device, leave existing system intact."
-h Display this help and exit -h Display this help and exit
-p ESPTOOL_PORT Set the environment variable for ESPTOOL_PORT. If not set, ESPTOOL iterates all ports (Dangerrous). -p ESPTOOL_PORT Set the environment variable for ESPTOOL_PORT. If not set, ESPTOOL iterates all ports (Dangerous).
-P PYTHON Specify alternate python interpreter to use to invoke esptool. (Default: "$PYTHON") -P PYTHON Specify alternate python interpreter to use to invoke esptool. (Default: "$PYTHON")
-f FILENAME The *update.bin file to flash. Custom to your device type. -f FILENAME The *update.bin file to flash. Custom to your device type.
@@ -30,7 +42,7 @@ while getopts ":hp:P:f:" opt; do
f) FILENAME=${OPTARG} f) FILENAME=${OPTARG}
;; ;;
*) *)
echo "Invalid flag." echo "Invalid flag."
show_help >&2 show_help >&2
exit 1 exit 1
;; ;;
@@ -45,7 +57,7 @@ shift "$((OPTIND-1))"
if [ -f "${FILENAME}" ] && [ -z "${FILENAME##*"update"*}" ]; then if [ -f "${FILENAME}" ] && [ -z "${FILENAME##*"update"*}" ]; then
printf "Trying to flash update ${FILENAME}" printf "Trying to flash update ${FILENAME}"
$PYTHON -m esptool --baud 115200 write_flash 0x10000 ${FILENAME} $ESPTOOL_CMD --baud 115200 write_flash 0x10000 ${FILENAME}
else else
show_help show_help
echo "Invalid file: ${FILENAME}" echo "Invalid file: ${FILENAME}"

View File

@@ -0,0 +1,45 @@
{
"build": {
"cpu": "cortex-m4",
"f_cpu": "48000000L",
"mcu": "AMA3B1KK",
"part": "apollo3",
"fabi": "hard",
"specs": "nosys.specs",
"framework": {
"arduino": {
"v1": {
"variant": "artemis",
"extra_flags": "-DSFE_ARTEMIS"
},
"v2": {
"variant": "rak11720",
"extra_flags": "-DARDUINO_RAK_11720_MODULE"
}
},
"ambiqsdk-sfe": {
"variant": ["boards_sfe", "artemis_module"],
"extra_flags": "",
"variant_lib_src_filter": ""
}
}
},
"debug": {
"jlink_device": "AMA3B1KK-KBR",
"svd_path": "apollo3.svd",
"swo_freq": 12000000,
"init": {
"break": "tbreak setup"
}
},
"frameworks": ["arduino", "ambiqsdk-sfe"],
"name": "WisCore RAK11720 Board",
"upload": {
"maximum_ram_size": 393216,
"maximum_size": 983040,
"protocol": "svl",
"protocols": ["svl", "asb", "jlink"]
},
"url": "https://www.rakwireless.com",
"vendor": "RAKwireless"
}

View File

@@ -29,7 +29,7 @@ default_envs = tbeam
;default_envs = rak4631 ;default_envs = rak4631
;default_envs = rak4631_eth_gw ;default_envs = rak4631_eth_gw
;default_envs = rak2560 ;default_envs = rak2560
;default_envs = rak10701 ;default_envs = rak_wismeshtap
;default_envs = wio-e5 ;default_envs = wio-e5
;default_envs = radiomaster_900_bandit_nano ;default_envs = radiomaster_900_bandit_nano
;default_envs = radiomaster_900_bandit_micro ;default_envs = radiomaster_900_bandit_micro
@@ -39,128 +39,126 @@ default_envs = tbeam
;default_envs = heltec_vision_master_e213 ;default_envs = heltec_vision_master_e213
;default_envs = heltec_vision_master_e290 ;default_envs = heltec_vision_master_e290
;default_envs = heltec_mesh_node_t114 ;default_envs = heltec_mesh_node_t114
extra_configs = extra_configs =
arch/*/*.ini arch/*/*.ini
variants/*/platformio.ini variants/*/platformio.ini
description = Meshtastic
[env] [env]
test_build_src = true test_build_src = true
extra_scripts = bin/platformio-custom.py extra_scripts = bin/platformio-custom.py
; note: we add src to our include search path so that lmic_project_config can override ; note: we add src to our include search path so that lmic_project_config can override
; note: TINYGPS_OPTION_NO_CUSTOM_FIELDS is VERY important. We don't use custom fields and somewhere in that pile ; note: TINYGPS_OPTION_NO_CUSTOM_FIELDS is VERY important. We don't use custom fields and somewhere in that pile
; of code is a heap corruption bug! ; of code is a heap corruption bug!
; FIXME: fix lib/BluetoothOTA dependency back on src/ so we can remove -Isrc ; FIXME: fix lib/BluetoothOTA dependency back on src/ so we can remove -Isrc
; The Radiolib stuff will speed up building considerably. Exclud all the stuff we dont need. ; The Radiolib stuff will speed up building considerably. Exclud all the stuff we dont need.
build_flags = -Wno-missing-field-initializers build_flags = -Wno-missing-field-initializers
-Wno-format
-Isrc -Isrc/mesh -Isrc/mesh/generated -Isrc/gps -Isrc/buzz -Wl,-Map,.pio/build/output.map -Wno-format
-DUSE_THREAD_NAMES -Isrc -Isrc/mesh -Isrc/mesh/generated -Isrc/gps -Isrc/buzz -Wl,-Map,.pio/build/output.map
-DTINYGPS_OPTION_NO_CUSTOM_FIELDS -DUSE_THREAD_NAMES
-DPB_ENABLE_MALLOC=1 -DTINYGPS_OPTION_NO_CUSTOM_FIELDS
-DRADIOLIB_EXCLUDE_CC1101=1 -DPB_ENABLE_MALLOC=1
-DRADIOLIB_EXCLUDE_NRF24=1 -DRADIOLIB_EXCLUDE_CC1101=1
-DRADIOLIB_EXCLUDE_RF69=1 -DRADIOLIB_EXCLUDE_NRF24=1
-DRADIOLIB_EXCLUDE_SX1231=1 -DRADIOLIB_EXCLUDE_RF69=1
-DRADIOLIB_EXCLUDE_SX1233=1 -DRADIOLIB_EXCLUDE_SX1231=1
-DRADIOLIB_EXCLUDE_SI443X=1 -DRADIOLIB_EXCLUDE_SX1233=1
-DRADIOLIB_EXCLUDE_RFM2X=1 -DRADIOLIB_EXCLUDE_SI443X=1
-DRADIOLIB_EXCLUDE_AFSK=1 -DRADIOLIB_EXCLUDE_RFM2X=1
-DRADIOLIB_EXCLUDE_BELL=1 -DRADIOLIB_EXCLUDE_AFSK=1
-DRADIOLIB_EXCLUDE_HELLSCHREIBER=1 -DRADIOLIB_EXCLUDE_BELL=1
-DRADIOLIB_EXCLUDE_MORSE=1 -DRADIOLIB_EXCLUDE_HELLSCHREIBER=1
-DRADIOLIB_EXCLUDE_RTTY=1 -DRADIOLIB_EXCLUDE_MORSE=1
-DRADIOLIB_EXCLUDE_SSTV=1 -DRADIOLIB_EXCLUDE_RTTY=1
-DRADIOLIB_EXCLUDE_AX25=1 -DRADIOLIB_EXCLUDE_SSTV=1
-DRADIOLIB_EXCLUDE_DIRECT_RECEIVE=1 -DRADIOLIB_EXCLUDE_AX25=1
-DRADIOLIB_EXCLUDE_BELL=1 -DRADIOLIB_EXCLUDE_DIRECT_RECEIVE=1
-DRADIOLIB_EXCLUDE_PAGER=1 -DRADIOLIB_EXCLUDE_BELL=1
-DRADIOLIB_EXCLUDE_FSK4=1 -DRADIOLIB_EXCLUDE_PAGER=1
-DRADIOLIB_EXCLUDE_APRS=1 -DRADIOLIB_EXCLUDE_FSK4=1
-DRADIOLIB_EXCLUDE_LORAWAN=1 -DRADIOLIB_EXCLUDE_APRS=1
-DMESHTASTIC_EXCLUDE_DROPZONE=1 -DRADIOLIB_EXCLUDE_LORAWAN=1
-DMESHTASTIC_EXCLUDE_REMOTEHARDWARE=1 -DMESHTASTIC_EXCLUDE_DROPZONE=1
#-DBUILD_EPOCH=$UNIX_TIME -DMESHTASTIC_EXCLUDE_REMOTEHARDWARE=1
;-D OLED_PL -DMESHTASTIC_EXCLUDE_POWERSTRESS=1 ; exclude power stress test module from main firmware
#-DBUILD_EPOCH=$UNIX_TIME
;-D OLED_PL
monitor_speed = 115200 monitor_speed = 115200
monitor_filters = direct monitor_filters = direct
lib_deps = lib_deps =
jgromes/RadioLib@~7.0.2 https://github.com/meshtastic/esp8266-oled-ssd1306.git#e16cee124fe26490cb14880c679321ad8ac89c95
https://github.com/meshtastic/esp8266-oled-ssd1306.git#e16cee124fe26490cb14880c679321ad8ac89c95 ; ESP8266_SSD1306 mathertel/OneButton@2.6.1
mathertel/OneButton@~2.6.1 ; OneButton library for non-blocking button debounce https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159 https://github.com/meshtastic/TinyGPSPlus.git#71a82db35f3b973440044c476d4bcdc673b104f4
https://github.com/meshtastic/TinyGPSPlus.git#71a82db35f3b973440044c476d4bcdc673b104f4 https://github.com/meshtastic/ArduinoThread.git#1ae8778c85d0a2a729f989e0b1e7d7c4dc84eef0
https://github.com/meshtastic/ArduinoThread.git#1ae8778c85d0a2a729f989e0b1e7d7c4dc84eef0 nanopb/Nanopb@0.4.9
nanopb/Nanopb@^0.4.9 erriez/ErriezCRC32@1.0.1
erriez/ErriezCRC32@^1.0.1
; Used for the code analysis in PIO Home / Inspect ; Used for the code analysis in PIO Home / Inspect
check_tool = cppcheck check_tool = cppcheck
check_skip_packages = yes check_skip_packages = yes
check_flags = check_flags =
-DAPP_VERSION=1.0.0 -DAPP_VERSION=1.0.0
--suppressions-list=suppressions.txt --suppressions-list=suppressions.txt
--inline-suppr --inline-suppr
; Common settings for conventional (non Portduino) Arduino targets ; Common settings for conventional (non Portduino) Arduino targets
[arduino_base] [arduino_base]
framework = arduino framework = arduino
lib_deps = lib_deps =
${env.lib_deps} ${env.lib_deps}
end2endzone/NonBlockingRTTTL@^1.3.0 end2endzone/NonBlockingRTTTL@1.3.0
https://github.com/meshtastic/SparkFun_ATECCX08a_Arduino_Library.git#5cf62b36c6f30bc72a07bdb2c11fc9a22d1e31da https://github.com/meshtastic/SparkFun_ATECCX08a_Arduino_Library.git#5cf62b36c6f30bc72a07bdb2c11fc9a22d1e31da
build_flags = ${env.build_flags} -Os build_flags = ${env.build_flags} -Os
build_src_filter = ${env.build_src_filter} -<platform/portduino/> build_src_filter = ${env.build_src_filter} -<platform/portduino/>
; Common libs for communicating over TCP/IP networks such as MQTT ; Common libs for communicating over TCP/IP networks such as MQTT
[networking_base] [networking_base]
lib_deps = lib_deps =
knolleary/PubSubClient@^2.8 knolleary/PubSubClient@2.8
arduino-libraries/NTPClient@^3.1.0 arduino-libraries/NTPClient@3.1.0
arcao/Syslog@^2.0.0 arcao/Syslog@2.0.0
[radiolib_base]
lib_deps =
jgromes/RadioLib@7.1.0
; Common libs for environmental measurements in telemetry module ; Common libs for environmental measurements in telemetry module
; (not included in native / portduino) ; (not included in native / portduino)
[environmental_base] [environmental_base]
lib_deps = lib_deps =
adafruit/Adafruit BusIO@^1.16.1 adafruit/Adafruit BusIO@1.16.2
adafruit/Adafruit Unified Sensor@^1.1.11 adafruit/Adafruit Unified Sensor@1.1.14
adafruit/Adafruit BMP280 Library@^2.6.8 adafruit/Adafruit BMP280 Library@2.6.8
adafruit/Adafruit BMP085 Library@^1.2.4 adafruit/Adafruit BMP085 Library@1.2.4
adafruit/Adafruit BME280 Library@^2.2.2 adafruit/Adafruit BME280 Library@2.2.4
adafruit/Adafruit BMP3XX Library@^2.1.5 adafruit/Adafruit BMP3XX Library@2.1.5
adafruit/Adafruit MCP9808 Library@^2.0.0 adafruit/Adafruit MCP9808 Library@2.0.2
adafruit/Adafruit INA260 Library@^1.5.0 adafruit/Adafruit INA260 Library@1.5.2
adafruit/Adafruit INA219@^1.2.0 adafruit/Adafruit INA219@1.2.3
adafruit/Adafruit MAX1704X@^1.0.3 adafruit/Adafruit MAX1704X@1.0.3
adafruit/Adafruit SHTC3 Library@^1.0.0 adafruit/Adafruit SHTC3 Library@1.0.1
adafruit/Adafruit LPS2X@^2.0.4 adafruit/Adafruit LPS2X@2.0.6
adafruit/Adafruit SHT31 Library@^2.2.2 adafruit/Adafruit SHT31 Library@2.2.2
adafruit/Adafruit PM25 AQI Sensor@^1.1.1 adafruit/Adafruit PM25 AQI Sensor@1.1.1
adafruit/Adafruit MPU6050@^2.2.4 adafruit/Adafruit MPU6050@2.2.6
adafruit/Adafruit LIS3DH@^1.3.0 adafruit/Adafruit LIS3DH@1.3.0
adafruit/Adafruit AHTX0@^2.0.5 adafruit/Adafruit AHTX0@2.0.5
adafruit/Adafruit LSM6DS@^4.7.2 adafruit/Adafruit LSM6DS@4.7.3
adafruit/Adafruit VEML7700 Library@^2.1.6 adafruit/Adafruit VEML7700 Library@2.1.6
adafruit/Adafruit SHT4x Library@^1.0.4 adafruit/Adafruit SHT4x Library@1.0.5
adafruit/Adafruit TSL2591 Library@^1.4.5 adafruit/Adafruit TSL2591 Library@1.4.5
sparkfun/SparkFun Qwiic Scale NAU7802 Arduino Library@^1.0.5 sparkfun/SparkFun Qwiic Scale NAU7802 Arduino Library@1.0.6
sparkfun/SparkFun 9DoF IMU Breakout - ICM 20948 - Arduino Library@^1.2.13 sparkfun/SparkFun 9DoF IMU Breakout - ICM 20948 - Arduino Library@1.2.13
ClosedCube OPT3001@^1.1.2 ClosedCube OPT3001@1.1.2
emotibit/EmotiBit MLX90632@^1.0.8 emotibit/EmotiBit MLX90632@1.0.8
dfrobot/DFRobot_RTU@^1.0.3 sparkfun/SparkFun MAX3010x Pulse and Proximity Sensor Library@1.1.2
sparkfun/SparkFun MAX3010x Pulse and Proximity Sensor Library@^1.1.2 adafruit/Adafruit MLX90614 Library@2.1.5
adafruit/Adafruit MLX90614 Library@^2.1.5 https://github.com/boschsensortec/Bosch-BSEC2-Library#v1.7.2502
boschsensortec/BME68x Sensor Library@1.1.40407
https://github.com/boschsensortec/Bosch-BSEC2-Library#v1.7.2502 https://github.com/KodinLanewave/INA3221@1.0.1
boschsensortec/BME68x Sensor Library@^1.1.40407 mprograms/QMC5883LCompass@1.2.3
https://github.com/KodinLanewave/INA3221@^1.0.1 dfrobot/DFRobot_RTU@1.0.3
lewisxhe/SensorLib@0.2.0 https://github.com/meshtastic/DFRobot_LarkWeatherStation#4de3a9cadef0f6a5220a8a906cf9775b02b0040d
mprograms/QMC5883LCompass@^1.2.0
https://github.com/meshtastic/DFRobot_LarkWeatherStation#4de3a9cadef0f6a5220a8a906cf9775b02b0040d
https://github.com/gjelsoe/STK8xxx-Accelerometer.git#v0.1.1

View File

@@ -1 +0,0 @@
curfirmwareversion.xml

View File

@@ -64,7 +64,7 @@ class AudioThread : public concurrency::OSThread
void initOutput() void initOutput()
{ {
audioOut = new AudioOutputI2S(1, AudioOutputI2S::EXTERNAL_I2S); audioOut = new AudioOutputI2S(1, AudioOutputI2S::EXTERNAL_I2S);
audioOut->SetPinout(DAC_I2S_BCK, DAC_I2S_WS, DAC_I2S_DOUT); audioOut->SetPinout(DAC_I2S_BCK, DAC_I2S_WS, DAC_I2S_DOUT, DAC_I2S_MCLK);
audioOut->SetGain(0.2); audioOut->SetGain(0.2);
}; };

View File

@@ -1,4 +1,5 @@
#include "ButtonThread.h" #include "ButtonThread.h"
#include "../userPrefs.h"
#include "configuration.h" #include "configuration.h"
#if !MESHTASTIC_EXCLUDE_GPS #if !MESHTASTIC_EXCLUDE_GPS
#include "GPS.h" #include "GPS.h"
@@ -26,12 +27,12 @@ using namespace concurrency;
ButtonThread *buttonThread; // Declared extern in header ButtonThread *buttonThread; // Declared extern in header
volatile ButtonThread::ButtonEventType ButtonThread::btnEvent = ButtonThread::BUTTON_EVENT_NONE; volatile ButtonThread::ButtonEventType ButtonThread::btnEvent = ButtonThread::BUTTON_EVENT_NONE;
#if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO) #if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO) || defined(USERPREFS_BUTTON_PIN)
OneButton ButtonThread::userButton; // Get reference to static member OneButton ButtonThread::userButton; // Get reference to static member
#endif #endif
ButtonThread::ButtonThread() : OSThread("Button") ButtonThread::ButtonThread() : OSThread("Button")
{ {
#if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO) #if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO) || defined(USERPREFS_BUTTON_PIN)
#if defined(ARCH_PORTDUINO) #if defined(ARCH_PORTDUINO)
if (settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC) { if (settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC) {
@@ -39,7 +40,12 @@ ButtonThread::ButtonThread() : OSThread("Button")
LOG_DEBUG("Use GPIO%02d for button", settingsMap[user]); LOG_DEBUG("Use GPIO%02d for button", settingsMap[user]);
} }
#elif defined(BUTTON_PIN) #elif defined(BUTTON_PIN)
int pin = config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN; // Resolved button pin #if !defined(USERPREFS_BUTTON_PIN)
int pin = config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN; // Resolved button pin
#endif
#ifdef USERPREFS_BUTTON_PIN
int pin = config.device.button_gpio ? config.device.button_gpio : USERPREFS_BUTTON_PIN; // Resolved button pin
#endif
#if defined(HELTEC_CAPSULE_SENSOR_V3) #if defined(HELTEC_CAPSULE_SENSOR_V3)
this->userButton = OneButton(pin, false, false); this->userButton = OneButton(pin, false, false);
#elif defined(BUTTON_ACTIVE_LOW) #elif defined(BUTTON_ACTIVE_LOW)
@@ -59,7 +65,7 @@ ButtonThread::ButtonThread() : OSThread("Button")
#endif #endif
#endif #endif
#if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO) #if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO) || defined(USERPREFS_BUTTON_PIN)
userButton.attachClick(userButtonPressed); userButton.attachClick(userButtonPressed);
userButton.setClickMs(BUTTON_CLICK_MS); userButton.setClickMs(BUTTON_CLICK_MS);
userButton.setPressMs(BUTTON_LONGPRESS_MS); userButton.setPressMs(BUTTON_LONGPRESS_MS);
@@ -102,7 +108,7 @@ int32_t ButtonThread::runOnce()
// If the button is pressed we suppress CPU sleep until release // If the button is pressed we suppress CPU sleep until release
canSleep = true; // Assume we should not keep the board awake canSleep = true; // Assume we should not keep the board awake
#if defined(BUTTON_PIN) #if defined(BUTTON_PIN) || defined(USERPREFS_BUTTON_PIN)
userButton.tick(); userButton.tick();
canSleep &= userButton.isIdle(); canSleep &= userButton.isIdle();
#elif defined(ARCH_PORTDUINO) #elif defined(ARCH_PORTDUINO)
@@ -130,7 +136,12 @@ int32_t ButtonThread::runOnce()
return 50; return 50;
} }
#ifdef BUTTON_PIN #ifdef BUTTON_PIN
#if !defined(USERPREFS_BUTTON_PIN)
if (((config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN) != if (((config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN) !=
#endif
#if defined(USERPREFS_BUTTON_PIN)
if (((config.device.button_gpio ? config.device.button_gpio : USERPREFS_BUTTON_PIN) !=
#endif
moduleConfig.canned_message.inputbroker_pin_press) || moduleConfig.canned_message.inputbroker_pin_press) ||
!(moduleConfig.canned_message.updown1_enabled || moduleConfig.canned_message.rotary1_enabled) || !(moduleConfig.canned_message.updown1_enabled || moduleConfig.canned_message.rotary1_enabled) ||
!moduleConfig.canned_message.enabled) { !moduleConfig.canned_message.enabled) {
@@ -244,7 +255,12 @@ void ButtonThread::attachButtonInterrupts()
#elif defined(BUTTON_PIN) #elif defined(BUTTON_PIN)
// Interrupt for user button, during normal use. Improves responsiveness. // Interrupt for user button, during normal use. Improves responsiveness.
attachInterrupt( attachInterrupt(
#if !defined(USERPREFS_BUTTON_PIN)
config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN,
#endif
#if defined(USERPREFS_BUTTON_PIN)
config.device.button_gpio ? config.device.button_gpio : USERPREFS_BUTTON_PIN,
#endif
[]() { []() {
ButtonThread::userButton.tick(); ButtonThread::userButton.tick();
runASAP = true; runASAP = true;
@@ -273,8 +289,13 @@ void ButtonThread::detachButtonInterrupts()
if (settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC) if (settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC)
detachInterrupt(settingsMap[user]); detachInterrupt(settingsMap[user]);
#elif defined(BUTTON_PIN) #elif defined(BUTTON_PIN)
#if !defined(USERPREFS_BUTTON_PIN)
detachInterrupt(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN); detachInterrupt(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN);
#endif #endif
#if defined(USERPREFS_BUTTON_PIN)
detachInterrupt(config.device.button_gpio ? config.device.button_gpio : USERPREFS_BUTTON_PIN);
#endif
#endif
#ifdef BUTTON_PIN_ALT #ifdef BUTTON_PIN_ALT
detachInterrupt(BUTTON_PIN_ALT); detachInterrupt(BUTTON_PIN_ALT);
@@ -315,7 +336,7 @@ void ButtonThread::userButtonMultiPressed(void *callerThread)
// Non-static method, runs during callback. Grabs info while still valid // Non-static method, runs during callback. Grabs info while still valid
void ButtonThread::storeClickCount() void ButtonThread::storeClickCount()
{ {
#ifdef BUTTON_PIN #if defined(BUTTON_PIN) || defined(USERPREFS_BUTTON_PIN)
multipressClickCount = userButton.getNumberClicks(); multipressClickCount = userButton.getNumberClicks();
#endif #endif
} }

View File

@@ -38,7 +38,7 @@ class ButtonThread : public concurrency::OSThread
void storeClickCount(); void storeClickCount();
private: private:
#if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO) #if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO) || defined(USERPREFS_BUTTON_PIN)
static OneButton userButton; // Static - accessed from an interrupt static OneButton userButton; // Static - accessed from an interrupt
#endif #endif
#ifdef BUTTON_PIN_ALT #ifdef BUTTON_PIN_ALT

View File

@@ -24,11 +24,16 @@ SPIClass SPI1(HSPI);
#endif // HAS_SDCARD #endif // HAS_SDCARD
#if defined(ARCH_STM32WL) #if defined(ARCH_APOLLO3)
// Apollo series 2 Kbytes (8 rows of 256 bytes)
uint16_t OSFS::startOfEEPROM = 1; uint16_t OSFS::startOfEEPROM = 1;
uint16_t OSFS::endOfEEPROM = 2048; uint16_t OSFS::endOfEEPROM = 2048;
// Useful consts
const OSFS::result noerr = OSFS::result::NO_ERROR;
const OSFS::result notfound = OSFS::result::FILE_NOT_FOUND;
// 3) How do I read from the medium? // 3) How do I read from the medium?
void OSFS::readNBytes(uint16_t address, unsigned int num, byte *output) void OSFS::readNBytes(uint16_t address, unsigned int num, byte *output)
{ {
@@ -66,7 +71,7 @@ extern "C" void lfs_assert(const char *reason)
*/ */
bool copyFile(const char *from, const char *to) bool copyFile(const char *from, const char *to)
{ {
#ifdef ARCH_STM32WL #if defined(ARCH_STM32WL) || defined(ARCH_APOLLO3)
unsigned char cbuffer[2048]; unsigned char cbuffer[2048];
// Var to hold the result of actions // Var to hold the result of actions
@@ -129,7 +134,7 @@ bool copyFile(const char *from, const char *to)
*/ */
bool renameFile(const char *pathFrom, const char *pathTo) bool renameFile(const char *pathFrom, const char *pathTo)
{ {
#ifdef ARCH_STM32WL #if defined(ARCH_STM32WL) || defined(ARCH_APOLLO3)
if (copyFile(pathFrom, pathTo) && (OSFS::deleteFile(pathFrom) == OSFS::result::NO_ERROR)) { if (copyFile(pathFrom, pathTo) && (OSFS::deleteFile(pathFrom) == OSFS::result::NO_ERROR)) {
return true; return true;
} else { } else {
@@ -329,7 +334,7 @@ void fsInit()
{ {
#ifdef FSCom #ifdef FSCom
if (!FSBegin()) { if (!FSBegin()) {
LOG_ERROR("Filesystem mount Failed."); LOG_ERROR("Filesystem mount failed");
// assert(0); This auto-formats the partition, so no need to fail here. // assert(0); This auto-formats the partition, so no need to fail here.
} }
#if defined(ARCH_ESP32) #if defined(ARCH_ESP32)

View File

@@ -24,6 +24,25 @@ const OSFS::result noerr = OSFS::result::NO_ERROR;
const OSFS::result notfound = OSFS::result::FILE_NOT_FOUND; const OSFS::result notfound = OSFS::result::FILE_NOT_FOUND;
#endif #endif
#if defined(ARCH_APOLLO3)
// Apollo series 2 Kbytes (8 rows of 256 bytes)
#include <EEPROM.h>
#include <OSFS.h>
extern uint16_t OSFS::startOfEEPROM;
extern uint16_t OSFS::endOfEEPROM;
// Useful consts
extern const OSFS::result noerr;
extern const OSFS::result notfound;
// 3) How do I read from the medium?
void OSFS::readNBytes(uint16_t address, unsigned int num, byte *output);
// 4) How to I write to the medium?
void OSFS::writeNBytes(uint16_t address, unsigned int num, const byte *input);
#endif
#if defined(ARCH_RP2040) #if defined(ARCH_RP2040)
// RP2040 // RP2040
#include "LittleFS.h" #include "LittleFS.h"

View File

@@ -251,7 +251,6 @@ class AnalogBatteryLevel : public HasBatteryLevel
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !defined(HAS_PMU) && \ #if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !defined(HAS_PMU) && \
!MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
if (hasINA()) { if (hasINA()) {
LOG_DEBUG("Use INA on I2C addr 0x%x for device battery voltage", config.power.device_battery_ina_address);
return getINAVoltage(); return getINAVoltage();
} }
#endif #endif
@@ -271,7 +270,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
config.power.adc_multiplier_override > 0 ? config.power.adc_multiplier_override : ADC_MULTIPLIER; config.power.adc_multiplier_override > 0 ? config.power.adc_multiplier_override : ADC_MULTIPLIER;
// Do not call analogRead() often. // Do not call analogRead() often.
const uint32_t min_read_interval = 5000; const uint32_t min_read_interval = 5000;
if (!Throttle::isWithinTimespanMs(last_read_time_ms, min_read_interval)) { if (!initial_read_done || !Throttle::isWithinTimespanMs(last_read_time_ms, min_read_interval)) {
last_read_time_ms = millis(); last_read_time_ms = millis();
uint32_t raw = 0; uint32_t raw = 0;
@@ -614,7 +613,7 @@ void Power::shutdown()
#ifdef PIN_LED3 #ifdef PIN_LED3
ledOff(PIN_LED3); ledOff(PIN_LED3);
#endif #endif
doDeepSleep(DELAY_FOREVER, false); doDeepSleep(DELAY_FOREVER, false, false);
#endif #endif
} }

View File

@@ -55,9 +55,14 @@ static void sdsEnter()
{ {
LOG_DEBUG("State: SDS"); LOG_DEBUG("State: SDS");
// FIXME - make sure GPS and LORA radio are off first - because we want close to zero current draw // FIXME - make sure GPS and LORA radio are off first - because we want close to zero current draw
doDeepSleep(Default::getConfiguredOrDefaultMs(config.power.sds_secs), false); doDeepSleep(Default::getConfiguredOrDefaultMs(config.power.sds_secs), false, false);
} }
static void lowBattSDSEnter()
{
LOG_DEBUG("State: Lower batt SDS");
doDeepSleep(Default::getConfiguredOrDefaultMs(config.power.sds_secs), false, true);
}
extern Power *power; extern Power *power;
static void shutdownEnter() static void shutdownEnter()
@@ -247,6 +252,7 @@ static void bootEnter()
State stateSHUTDOWN(shutdownEnter, NULL, NULL, "SHUTDOWN"); State stateSHUTDOWN(shutdownEnter, NULL, NULL, "SHUTDOWN");
State stateSDS(sdsEnter, NULL, NULL, "SDS"); State stateSDS(sdsEnter, NULL, NULL, "SDS");
State stateLowBattSDS(lowBattSDSEnter, NULL, NULL, "SDS");
State stateLS(lsEnter, lsIdle, lsExit, "LS"); State stateLS(lsEnter, lsIdle, lsExit, "LS");
State stateNB(nbEnter, NULL, NULL, "NB"); State stateNB(nbEnter, NULL, NULL, "NB");
State stateDARK(darkEnter, NULL, NULL, "DARK"); State stateDARK(darkEnter, NULL, NULL, "DARK");
@@ -291,12 +297,12 @@ void PowerFSM_setup()
"Press"); // Allow button to work while in serial API "Press"); // Allow button to work while in serial API
// Handle critically low power battery by forcing deep sleep // Handle critically low power battery by forcing deep sleep
powerFSM.add_transition(&stateBOOT, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat"); powerFSM.add_transition(&stateBOOT, &stateLowBattSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
powerFSM.add_transition(&stateLS, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat"); powerFSM.add_transition(&stateLS, &stateLowBattSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
powerFSM.add_transition(&stateNB, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat"); powerFSM.add_transition(&stateNB, &stateLowBattSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
powerFSM.add_transition(&stateDARK, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat"); powerFSM.add_transition(&stateDARK, &stateLowBattSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
powerFSM.add_transition(&stateON, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat"); powerFSM.add_transition(&stateON, &stateLowBattSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
powerFSM.add_transition(&stateSERIAL, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat"); powerFSM.add_transition(&stateSERIAL, &stateLowBattSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
// Handle being told to power off // Handle being told to power off
powerFSM.add_transition(&stateBOOT, &stateSHUTDOWN, EVENT_SHUTDOWN, NULL, "Shutdown"); powerFSM.add_transition(&stateBOOT, &stateSHUTDOWN, EVENT_SHUTDOWN, NULL, "Shutdown");

View File

@@ -1,8 +1,8 @@
#include "RedirectablePrint.h" #include "RedirectablePrint.h"
#include "NodeDB.h" #include "NodeDB.h"
#include "RTC.h"
#include "concurrency/OSThread.h" #include "concurrency/OSThread.h"
#include "configuration.h" #include "configuration.h"
#include "gps/RTC.h"
#include "main.h" #include "main.h"
#include "mesh/generated/meshtastic/mesh.pb.h" #include "mesh/generated/meshtastic/mesh.pb.h"
#include <assert.h> #include <assert.h>

View File

@@ -13,17 +13,17 @@ void AirTime::logAirtime(reportTypes reportType, uint32_t airtime_ms)
{ {
if (reportType == TX_LOG) { if (reportType == TX_LOG) {
LOG_DEBUG("Packet transmitted : %ums", airtime_ms); LOG_DEBUG("Packet TX: %ums", airtime_ms);
this->airtimes.periodTX[0] = this->airtimes.periodTX[0] + airtime_ms; this->airtimes.periodTX[0] = this->airtimes.periodTX[0] + airtime_ms;
air_period_tx[0] = air_period_tx[0] + airtime_ms; air_period_tx[0] = air_period_tx[0] + airtime_ms;
this->utilizationTX[this->getPeriodUtilHour()] = this->utilizationTX[this->getPeriodUtilHour()] + airtime_ms; this->utilizationTX[this->getPeriodUtilHour()] = this->utilizationTX[this->getPeriodUtilHour()] + airtime_ms;
} else if (reportType == RX_LOG) { } else if (reportType == RX_LOG) {
LOG_DEBUG("Packet received : %ums", airtime_ms); LOG_DEBUG("Packet RX: %ums", airtime_ms);
this->airtimes.periodRX[0] = this->airtimes.periodRX[0] + airtime_ms; this->airtimes.periodRX[0] = this->airtimes.periodRX[0] + airtime_ms;
air_period_rx[0] = air_period_rx[0] + airtime_ms; air_period_rx[0] = air_period_rx[0] + airtime_ms;
} else if (reportType == RX_ALL_LOG) { } else if (reportType == RX_ALL_LOG) {
LOG_DEBUG("Packet received (noise?) : %ums", airtime_ms); LOG_DEBUG("Packet RX (noise?) : %ums", airtime_ms);
this->airtimes.periodRX_ALL[0] = this->airtimes.periodRX_ALL[0] + airtime_ms; this->airtimes.periodRX_ALL[0] = this->airtimes.periodRX_ALL[0] + airtime_ms;
} }
@@ -126,7 +126,7 @@ bool AirTime::isTxAllowedChannelUtil(bool polite)
if (channelUtilizationPercent() < percentage) { if (channelUtilizationPercent() < percentage) {
return true; return true;
} else { } else {
LOG_WARN("Channel utilization is >%d percent. Skip opportunity to send.", percentage); LOG_WARN("Ch. util >%d%%. Skip send", percentage);
return false; return false;
} }
} }
@@ -137,8 +137,7 @@ bool AirTime::isTxAllowedAirUtil()
if (utilizationTXPercent() < myRegion->dutyCycle * polite_duty_cycle_percent / 100) { if (utilizationTXPercent() < myRegion->dutyCycle * polite_duty_cycle_percent / 100) {
return true; return true;
} else { } else {
LOG_WARN("Tx air utilization is >%f percent. Skip opportunity to send.", LOG_WARN("TX air util. >%f%%. Skip send", myRegion->dutyCycle * polite_duty_cycle_percent / 100);
myRegion->dutyCycle * polite_duty_cycle_percent / 100);
return false; return false;
} }
} }

View File

@@ -148,13 +148,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define NAU7802_ADDR 0x2A #define NAU7802_ADDR 0x2A
#define MAX30102_ADDR 0x57 #define MAX30102_ADDR 0x57
#define MLX90614_ADDR_DEF 0x5A #define MLX90614_ADDR_DEF 0x5A
#define CGRADSENS_ADDR 0x66
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// ACCELEROMETER // ACCELEROMETER
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#define MPU6050_ADDR 0x68 #define MPU6050_ADDR 0x68
#define STK8BXX_ADR 0x18 #define STK8BXX_ADDR 0x18
#define LIS3DH_ADR 0x18 #define LIS3DH_ADDR 0x18
#define LIS3DH_ADDR_ALT 0x19
#define BMA423_ADDR 0x19 #define BMA423_ADDR 0x19
#define LSM6DS3_ADDR 0x6A #define LSM6DS3_ADDR 0x6A
#define BMX160_ADDR 0x69 #define BMX160_ADDR 0x69

View File

@@ -63,7 +63,8 @@ class ScanI2C
ICM20948, ICM20948,
MAX30102, MAX30102,
TPS65233, TPS65233,
MPR121KB MPR121KB,
CGRADSENS
} DeviceType; } DeviceType;
// typedef uint8_t DeviceAddress; // typedef uint8_t DeviceAddress;

View File

@@ -86,7 +86,7 @@ ScanI2C::DeviceType ScanI2CTwoWire::probeOLED(ScanI2C::DeviceAddress addr) const
} }
void ScanI2CTwoWire::printATECCInfo() const void ScanI2CTwoWire::printATECCInfo() const
{ {
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !defined(ARCH_APOLLO3)
atecc.readConfigZone(false); atecc.readConfigZone(false);
std::string atecc_numbers = "ATECC608B Serial Number: "; std::string atecc_numbers = "ATECC608B Serial Number: ";
@@ -206,7 +206,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
type = probeOLED(addr); type = probeOLED(addr);
break; break;
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !defined(ARCH_APOLLO3)
case ATECC608B_ADDR: case ATECC608B_ADDR:
#ifdef RP2040_SLOW_CLOCK #ifdef RP2040_SLOW_CLOCK
if (atecc.begin(addr.address, Wire, Serial2) == true) if (atecc.begin(addr.address, Wire, Serial2) == true)
@@ -314,19 +314,34 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
break; break;
case INA3221_ADDR: case INA3221_ADDR:
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFE), 2); registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFE), 2);
LOG_DEBUG("Register MFG_UID: 0x%x", registerValue); LOG_DEBUG("Register MFG_UID FE: 0x%x", registerValue);
if (registerValue == 0x5449) { if (registerValue == 0x5449) {
LOG_INFO("INA3221 sensor found at address 0x%x", (uint8_t)addr.address); LOG_INFO("INA3221 sensor found at address 0x%x", (uint8_t)addr.address);
type = INA3221; type = INA3221;
} else { } else {
LOG_INFO("DFRobot Lark weather station found at address 0x%x", (uint8_t)addr.address); /* check the first 2 bytes of the 6 byte response register
type = DFROBOT_LARK; LARK FW 1.0 should return:
RESPONSE_STATUS STATUS_SUCCESS (0x53)
RESPONSE_CMD CMD_GET_VERSION (0x05)
RESPONSE_LEN_L 0x02
RESPONSE_LEN_H 0x00
RESPONSE_PAYLOAD 0x01
RESPONSE_PAYLOAD+1 0x00
*/
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x05), 2);
LOG_DEBUG("Register MFG_UID 05: 0x%x", registerValue);
if (registerValue == 0x5305) {
LOG_INFO("DFRobot Lark weather station found at address 0x%x", (uint8_t)addr.address);
type = DFROBOT_LARK;
}
// else: probably a RAK12500/UBLOX GPS on I2C
} }
break; break;
case MCP9808_ADDR: case MCP9808_ADDR:
// We need to check for STK8BAXX first, since register 0x07 is new data flag for the z-axis and can produce some // We need to check for STK8BAXX first, since register 0x07 is new data flag for the z-axis and can produce some
// weird result. and register 0x00 doesn't seems to be colliding with MCP9808 and LIS3DH chips. // weird result. and register 0x00 doesn't seems to be colliding with MCP9808 and LIS3DH chips.
{ {
#ifdef HAS_STK8XXX
// Check register 0x00 for 0x8700 response to ID STK8BA53 chip. // Check register 0x00 for 0x8700 response to ID STK8BA53 chip.
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 2); registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 2);
if (registerValue == 0x8700) { if (registerValue == 0x8700) {
@@ -334,6 +349,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
LOG_INFO("STK8BAXX accelerometer found"); LOG_INFO("STK8BAXX accelerometer found");
break; break;
} }
#endif
// Check register 0x07 for 0x0400 response to ID MCP9808 chip. // Check register 0x07 for 0x0400 response to ID MCP9808 chip.
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x07), 2); registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x07), 2);
@@ -409,7 +425,17 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
#else #else
SCAN_SIMPLE_CASE(PMSA0031_ADDR, PMSA0031, "PMSA0031 air quality sensor found") SCAN_SIMPLE_CASE(PMSA0031_ADDR, PMSA0031, "PMSA0031 air quality sensor found")
#endif #endif
SCAN_SIMPLE_CASE(BMA423_ADDR, BMA423, "BMA423 accelerometer found"); case BMA423_ADDR: // this can also be LIS3DH_ADDR_ALT
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0F), 2);
if (registerValue == 0x3300 || registerValue == 0x3333) { // RAK4631 WisBlock has LIS3DH register at 0x3333
type = LIS3DH;
LOG_INFO("LIS3DH accelerometer found");
} else {
type = BMA423;
LOG_INFO("BMA423 accelerometer found");
}
break;
SCAN_SIMPLE_CASE(LSM6DS3_ADDR, LSM6DS3, "LSM6DS3 accelerometer found at address 0x%x", (uint8_t)addr.address); SCAN_SIMPLE_CASE(LSM6DS3_ADDR, LSM6DS3, "LSM6DS3 accelerometer found at address 0x%x", (uint8_t)addr.address);
SCAN_SIMPLE_CASE(TCA9535_ADDR, TCA9535, "TCA9535 I2C expander found"); SCAN_SIMPLE_CASE(TCA9535_ADDR, TCA9535, "TCA9535 I2C expander found");
SCAN_SIMPLE_CASE(TCA9555_ADDR, TCA9555, "TCA9555 I2C expander found"); SCAN_SIMPLE_CASE(TCA9555_ADDR, TCA9555, "TCA9555 I2C expander found");
@@ -453,6 +479,16 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
} }
break; break;
case CGRADSENS_ADDR:
// Register 0x00 of the RadSens sensor contains is product identifier 0x7D
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 1);
if (registerValue == 0x7D) {
type = CGRADSENS;
LOG_INFO("ClimateGuard RadSens Geiger-Muller Sensor found");
break;
}
break;
default: default:
LOG_INFO("Device found at address 0x%x was not able to be enumerated", addr.address); LOG_INFO("Device found at address 0x%x was not able to be enumerated", addr.address);
} }

View File

@@ -788,13 +788,14 @@ void GPS::setPowerState(GPSPowerState newState, uint32_t sleepTime)
void GPS::writePinEN(bool on) void GPS::writePinEN(bool on)
{ {
// Abort: if conflict with Canned Messages when using Wisblock(?) // Abort: if conflict with Canned Messages when using Wisblock(?)
if (HW_VENDOR == meshtastic_HardwareModel_RAK4631 && (rotaryEncoderInterruptImpl1 || upDownInterruptImpl1)) if ((HW_VENDOR == meshtastic_HardwareModel_RAK4631 || HW_VENDOR == meshtastic_HardwareModel_WISMESH_TAP) &&
(rotaryEncoderInterruptImpl1 || upDownInterruptImpl1))
return; return;
// Write and log // Write and log
enablePin->set(on); enablePin->set(on);
#ifdef GPS_DEBUG #ifdef GPS_DEBUG
LOG_DEBUG("Pin EN %s", val == HIGH ? "HI" : "LOW"); LOG_DEBUG("Pin EN %s", on == HIGH ? "HI" : "LOW");
#endif #endif
} }
@@ -1112,7 +1113,7 @@ const char *DETECTED_MESSAGE = "%s detected, using %s Module";
GnssModel_t GPS::probe(int serialSpeed) GnssModel_t GPS::probe(int serialSpeed)
{ {
#if defined(ARCH_NRF52) || defined(ARCH_PORTDUINO) || defined(ARCH_STM32WL) #if defined(ARCH_NRF52) || defined(ARCH_PORTDUINO) || defined(ARCH_STM32WL) || defined(ARCH_APOLLO3)
_serial_gps->end(); _serial_gps->end();
_serial_gps->begin(serialSpeed); _serial_gps->begin(serialSpeed);
#elif defined(ARCH_RP2040) #elif defined(ARCH_RP2040)

View File

@@ -64,6 +64,95 @@ const char *getDOPString(uint32_t dop);
*/ */
class GPS : private concurrency::OSThread class GPS : private concurrency::OSThread
{ {
public:
meshtastic_Position p = meshtastic_Position_init_default;
/** This is normally bound to config.position.gps_en_gpio but some rare boards (like heltec tracker) need more advanced
* implementations. Those boards will set this public variable to a custom implementation.
*
* Normally set by GPS::createGPS()
*/
GpioVirtPin *enablePin = NULL;
virtual ~GPS();
/** We will notify this observable anytime GPS state has changed meaningfully */
Observable<const meshtastic::GPSStatus *> newStatus;
/**
* Returns true if we succeeded
*/
virtual bool setup();
// re-enable the thread
void enable();
// Disable the thread
int32_t disable() override;
// toggle between enabled/disabled
void toggleGpsMode();
// Change the power state of the GPS - for power saving / shutdown
void setPowerState(GPSPowerState newState, uint32_t sleepMs = 0);
/// 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; }
bool isPowerSaving() const { return config.position.gps_mode != meshtastic_Config_PositionConfig_GpsMode_ENABLED; }
// Empty the input buffer as quickly as possible
void clearBuffer();
virtual bool factoryReset();
// Creates an instance of the GPS class.
// Returns the new instance or null if the GPS is not present.
static GPS *createGps();
// Wake the GPS hardware - ready for an update
void up();
// Let the GPS hardware save power between updates
void down();
protected:
/// Record that we have a GPS
void setConnected();
/** Subclasses should look for serial rx characters here and feed it to their GPS parser
*
* Return true if we received a valid message from the GPS
*/
virtual bool whileActive();
/**
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
* Override this method to check for new locations
*
* @return true if we've acquired a time
*/
virtual bool lookForTime();
/**
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
* Override this method to check for new locations
*
* @return true if we've acquired a new location
*/
virtual bool lookForLocation();
GnssModel_t gnssModel = GNSS_MODEL_UNKNOWN;
private:
GPS() : concurrency::OSThread("GPS") {}
TinyGPSPlus reader; TinyGPSPlus reader;
uint8_t fixQual = 0; // fix quality from GPGGA uint8_t fixQual = 0; // fix quality from GPGGA
uint32_t lastChecksumFailCount = 0; uint32_t lastChecksumFailCount = 0;
@@ -75,7 +164,6 @@ class GPS : private concurrency::OSThread
TinyGPSCustom gsapdop; // custom extract PDOP from GPGSA TinyGPSCustom gsapdop; // custom extract PDOP from GPGSA
uint8_t fixType = 0; // fix type from GPGSA uint8_t fixType = 0; // fix type from GPGSA
#endif #endif
private:
#if GPS_BAUDRATE_FIXED #if GPS_BAUDRATE_FIXED
// if GPS_BAUDRATE is specified in variant, only try that. // if GPS_BAUDRATE is specified in variant, only try that.
const int serialSpeeds[1] = {GPS_BAUDRATE}; const int serialSpeeds[1] = {GPS_BAUDRATE};
@@ -113,7 +201,6 @@ class GPS : private concurrency::OSThread
CallbackObserver<GPS, void *> notifyDeepSleepObserver = CallbackObserver<GPS, void *>(this, &GPS::prepareDeepSleep); CallbackObserver<GPS, void *> notifyDeepSleepObserver = CallbackObserver<GPS, void *>(this, &GPS::prepareDeepSleep);
public:
/** If !NULL we will use this serial port to construct our GPS */ /** If !NULL we will use this serial port to construct our GPS */
#if defined(ARCH_RP2040) #if defined(ARCH_RP2040)
static SerialUART *_serial_gps; static SerialUART *_serial_gps;
@@ -167,53 +254,6 @@ class GPS : private concurrency::OSThread
const char *ACK_SUCCESS_MESSAGE = "Get ack success!"; const char *ACK_SUCCESS_MESSAGE = "Get ack success!";
meshtastic_Position p = meshtastic_Position_init_default;
/** This is normally bound to config.position.gps_en_gpio but some rare boards (like heltec tracker) need more advanced
* implementations. Those boards will set this public variable to a custom implementation.
*
* Normally set by GPS::createGPS()
*/
GpioVirtPin *enablePin = NULL;
GPS() : concurrency::OSThread("GPS") {}
virtual ~GPS();
/** We will notify this observable anytime GPS state has changed meaningfully */
Observable<const meshtastic::GPSStatus *> newStatus;
/**
* Returns true if we succeeded
*/
virtual bool setup();
// re-enable the thread
void enable();
// Disable the thread
int32_t disable() override;
// toggle between enabled/disabled
void toggleGpsMode();
// Change the power state of the GPS - for power saving / shutdown
void setPowerState(GPSPowerState newState, uint32_t sleepMs = 0);
/// 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; }
bool isPowerSaving() const { return config.position.gps_mode != meshtastic_Config_PositionConfig_GpsMode_ENABLED; }
// Empty the input buffer as quickly as possible
void clearBuffer();
// Create a ublox packet for editing in memory // Create a ublox packet for editing in memory
uint8_t makeUBXPacket(uint8_t class_id, uint8_t msg_id, uint8_t payload_size, const uint8_t *msg); uint8_t makeUBXPacket(uint8_t class_id, uint8_t msg_id, uint8_t payload_size, const uint8_t *msg);
uint8_t makeCASPacket(uint8_t class_id, uint8_t msg_id, uint8_t payload_size, const uint8_t *msg); uint8_t makeCASPacket(uint8_t class_id, uint8_t msg_id, uint8_t payload_size, const uint8_t *msg);
@@ -229,59 +269,6 @@ class GPS : private concurrency::OSThread
GPS_RESPONSE getACKCas(uint8_t class_id, uint8_t msg_id, uint32_t waitMillis); GPS_RESPONSE getACKCas(uint8_t class_id, uint8_t msg_id, uint32_t waitMillis);
virtual bool factoryReset();
// Creates an instance of the GPS class.
// Returns the new instance or null if the GPS is not present.
static GPS *createGps();
// Wake the GPS hardware - ready for an update
void up();
// Let the GPS hardware save power between updates
void down();
protected:
/**
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
* Override this method to check for new locations
*
* @return true if we've acquired a time
*/
/**
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
* Override this method to check for new locations
*
* @return true if we've acquired a new location
*/
/// Record that we have a GPS
void setConnected();
/** Subclasses should look for serial rx characters here and feed it to their GPS parser
*
* Return true if we received a valid message from the GPS
*/
virtual bool whileActive();
/**
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
* Override this method to check for new locations
*
* @return true if we've acquired a time
*/
virtual bool lookForTime();
/**
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
* Override this method to check for new locations
*
* @return true if we've acquired a new location
*/
virtual bool lookForLocation();
private:
/// Prepare the GPS for the cpu entering deep sleep, expect to be gone for at least 100s of msecs /// Prepare the GPS for the cpu entering deep sleep, expect to be gone for at least 100s of msecs
/// always returns 0 to indicate okay to sleep /// always returns 0 to indicate okay to sleep
int prepareDeepSleep(void *unused); int prepareDeepSleep(void *unused);
@@ -320,10 +307,7 @@ class GPS : private concurrency::OSThread
uint8_t fixeddelayCtr = 0; uint8_t fixeddelayCtr = 0;
const char *powerStateToString(); const char *powerStateToString();
protected:
GnssModel_t gnssModel = GNSS_MODEL_UNKNOWN;
}; };
extern GPS *gps; extern GPS *gps;
#endif // Exclude GPS #endif // Exclude GPS

View File

@@ -23,7 +23,7 @@ uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_PositionLite &pos, c
{ {
GeoCoord geoCoord(pos.latitude_i, pos.longitude_i, pos.altitude); GeoCoord geoCoord(pos.latitude_i, pos.longitude_i, pos.altitude);
char type = isCaltopoMode ? 'P' : 'N'; char type = isCaltopoMode ? 'P' : 'N';
uint32_t len = snprintf(buf, bufsz, "$G%cWPL,%02d%07.4f,%c,%03d%07.4f,%c,%s", type, geoCoord.getDMSLatDeg(), uint32_t len = snprintf(buf, bufsz, "\r\n$G%cWPL,%02d%07.4f,%c,%03d%07.4f,%c,%s", type, geoCoord.getDMSLatDeg(),
(abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6, geoCoord.getDMSLatCP(), (abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6, geoCoord.getDMSLatCP(),
geoCoord.getDMSLonDeg(), (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6, geoCoord.getDMSLonDeg(), (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6,
geoCoord.getDMSLonCP(), name); geoCoord.getDMSLonCP(), name);

View File

@@ -170,7 +170,7 @@ bool EInkDynamicDisplay::determineMode()
checkFastRequested(); checkFastRequested();
if (refresh == UNSPECIFIED) if (refresh == UNSPECIFIED)
LOG_WARN("There was a flaw in the determineMode() logic."); LOG_WARN("There was a flaw in the determineMode() logic");
// -- Decision has been reached -- // -- Decision has been reached --
applyRefreshMode(); applyRefreshMode();

View File

@@ -101,9 +101,9 @@ std::vector<MeshModule *> moduleFrames;
static char ourId[5]; static char ourId[5];
// vector where symbols (string) are displayed in bottom corner of display. // vector where symbols (string) are displayed in bottom corner of display.
std::vector<std::string> functionSymbals; std::vector<std::string> functionSymbol;
// string displayed in bottom right corner of display. Created from elements in functionSymbals vector // string displayed in bottom right corner of display. Created from elements in functionSymbol vector
std::string functionSymbalString = ""; std::string functionSymbolString = "";
#if HAS_GPS #if HAS_GPS
// GeoCoord object for the screen // GeoCoord object for the screen
@@ -243,10 +243,10 @@ static void drawWelcomeScreen(OLEDDisplay *display, OLEDDisplayUiState *state, i
static void drawFunctionOverlay(OLEDDisplay *display, OLEDDisplayUiState *state) static void drawFunctionOverlay(OLEDDisplay *display, OLEDDisplayUiState *state)
{ {
// LOG_DEBUG("Draw function overlay"); // LOG_DEBUG("Draw function overlay");
if (functionSymbals.begin() != functionSymbals.end()) { if (functionSymbol.begin() != functionSymbol.end()) {
char buf[64]; char buf[64];
display->setFont(FONT_SMALL); display->setFont(FONT_SMALL);
snprintf(buf, sizeof(buf), "%s", functionSymbalString.c_str()); snprintf(buf, sizeof(buf), "%s", functionSymbolString.c_str());
display->drawString(SCREEN_WIDTH - display->getStringWidth(buf), SCREEN_HEIGHT - FONT_HEIGHT_SMALL, buf); display->drawString(SCREEN_WIDTH - display->getStringWidth(buf), SCREEN_HEIGHT - FONT_HEIGHT_SMALL, buf);
} }
} }
@@ -396,7 +396,7 @@ static void drawBattery(OLEDDisplay *display, int16_t x, int16_t y, uint8_t *img
display->drawFastImage(x, y, 16, 8, imgBuffer); display->drawFastImage(x, y, 16, 8, imgBuffer);
} }
#ifdef T_WATCH_S3 #if defined(DISPLAY_CLOCK_FRAME)
void Screen::drawWatchFaceToggleButton(OLEDDisplay *display, int16_t x, int16_t y, bool digitalMode, float scale) void Screen::drawWatchFaceToggleButton(OLEDDisplay *display, int16_t x, int16_t y, bool digitalMode, float scale)
{ {
@@ -958,55 +958,65 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state
display->setColor(WHITE); display->setColor(WHITE);
#ifndef EXCLUDE_EMOJI #ifndef EXCLUDE_EMOJI
if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), "\U0001F44D") == 0) { const char *msg = reinterpret_cast<const char *>(mp.decoded.payload.bytes);
if (strcmp(msg, "\U0001F44D") == 0) {
display->drawXbm(x + (SCREEN_WIDTH - thumbs_width) / 2, display->drawXbm(x + (SCREEN_WIDTH - thumbs_width) / 2,
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - thumbs_height) / 2 + 2 + 5, thumbs_width, thumbs_height, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - thumbs_height) / 2 + 2 + 5, thumbs_width, thumbs_height,
thumbup); thumbup);
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), "\U0001F44E") == 0) { } else if (strcmp(msg, "\U0001F44E") == 0) {
display->drawXbm(x + (SCREEN_WIDTH - thumbs_width) / 2, display->drawXbm(x + (SCREEN_WIDTH - thumbs_width) / 2,
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - thumbs_height) / 2 + 2 + 5, thumbs_width, thumbs_height, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - thumbs_height) / 2 + 2 + 5, thumbs_width, thumbs_height,
thumbdown); thumbdown);
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), "") == 0) { } else if (strcmp(msg, "\U0001F60A") == 0 || strcmp(msg, "\U0001F600") == 0 || strcmp(msg, "\U0001F642") == 0 ||
strcmp(msg, "\U0001F609") == 0 ||
strcmp(msg, "\U0001F601") == 0) { // matches 5 different common smileys, so that the phone user doesn't have to
// remember which one is compatible
display->drawXbm(x + (SCREEN_WIDTH - smiley_width) / 2,
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - smiley_height) / 2 + 2 + 5, smiley_width, smiley_height,
smiley);
} else if (strcmp(msg, "") == 0) {
display->drawXbm(x + (SCREEN_WIDTH - question_width) / 2, display->drawXbm(x + (SCREEN_WIDTH - question_width) / 2,
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - question_height) / 2 + 2 + 5, question_width, question_height, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - question_height) / 2 + 2 + 5, question_width, question_height,
question); question);
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), "‼️") == 0) { } else if (strcmp(msg, "‼️") == 0) {
display->drawXbm(x + (SCREEN_WIDTH - bang_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - bang_height) / 2 + 2 + 5, display->drawXbm(x + (SCREEN_WIDTH - bang_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - bang_height) / 2 + 2 + 5,
bang_width, bang_height, bang); bang_width, bang_height, bang);
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), "\U0001F4A9") == 0) { } else if (strcmp(msg, "\U0001F4A9") == 0) {
display->drawXbm(x + (SCREEN_WIDTH - poo_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - poo_height) / 2 + 2 + 5, display->drawXbm(x + (SCREEN_WIDTH - poo_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - poo_height) / 2 + 2 + 5,
poo_width, poo_height, poo); poo_width, poo_height, poo);
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), "\xf0\x9f\xa4\xa3") == 0) { } else if (strcmp(msg, "\U0001F923") == 0) {
display->drawXbm(x + (SCREEN_WIDTH - haha_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - haha_height) / 2 + 2 + 5, display->drawXbm(x + (SCREEN_WIDTH - haha_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - haha_height) / 2 + 2 + 5,
haha_width, haha_height, haha); haha_width, haha_height, haha);
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), "\U0001F44B") == 0) { } else if (strcmp(msg, "\U0001F44B") == 0) {
display->drawXbm(x + (SCREEN_WIDTH - wave_icon_width) / 2, display->drawXbm(x + (SCREEN_WIDTH - wave_icon_width) / 2,
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - wave_icon_height) / 2 + 2 + 5, wave_icon_width, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - wave_icon_height) / 2 + 2 + 5, wave_icon_width,
wave_icon_height, wave_icon); wave_icon_height, wave_icon);
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), "\U0001F920") == 0) { } else if (strcmp(msg, "\U0001F920") == 0) {
display->drawXbm(x + (SCREEN_WIDTH - cowboy_width) / 2, display->drawXbm(x + (SCREEN_WIDTH - cowboy_width) / 2,
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - cowboy_height) / 2 + 2 + 5, cowboy_width, cowboy_height, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - cowboy_height) / 2 + 2 + 5, cowboy_width, cowboy_height,
cowboy); cowboy);
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), "\U0001F42D") == 0) { } else if (strcmp(msg, "\U0001F42D") == 0) {
display->drawXbm(x + (SCREEN_WIDTH - deadmau5_width) / 2, display->drawXbm(x + (SCREEN_WIDTH - deadmau5_width) / 2,
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - deadmau5_height) / 2 + 2 + 5, deadmau5_width, deadmau5_height, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - deadmau5_height) / 2 + 2 + 5, deadmau5_width, deadmau5_height,
deadmau5); deadmau5);
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), "\xE2\x98\x80\xEF\xB8\x8F") == 0) { } else if (strcmp(msg, "\xE2\x98\x80\xEF\xB8\x8F") == 0) {
display->drawXbm(x + (SCREEN_WIDTH - sun_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - sun_height) / 2 + 2 + 5, display->drawXbm(x + (SCREEN_WIDTH - sun_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - sun_height) / 2 + 2 + 5,
sun_width, sun_height, sun); sun_width, sun_height, sun);
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), "\u2614") == 0) { } else if (strcmp(msg, "\u2614") == 0) {
display->drawXbm(x + (SCREEN_WIDTH - rain_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - rain_height) / 2 + 2 + 10, display->drawXbm(x + (SCREEN_WIDTH - rain_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - rain_height) / 2 + 2 + 10,
rain_width, rain_height, rain); rain_width, rain_height, rain);
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), "☁️") == 0) { } else if (strcmp(msg, "☁️") == 0) {
display->drawXbm(x + (SCREEN_WIDTH - cloud_width) / 2, display->drawXbm(x + (SCREEN_WIDTH - cloud_width) / 2,
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - cloud_height) / 2 + 2 + 5, cloud_width, cloud_height, cloud); y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - cloud_height) / 2 + 2 + 5, cloud_width, cloud_height, cloud);
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), "🌫️") == 0) { } else if (strcmp(msg, "🌫️") == 0) {
display->drawXbm(x + (SCREEN_WIDTH - fog_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - fog_height) / 2 + 2 + 5, display->drawXbm(x + (SCREEN_WIDTH - fog_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - fog_height) / 2 + 2 + 5,
fog_width, fog_height, fog); fog_width, fog_height, fog);
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), "\xf0\x9f\x98\x88") == 0) { } else if (strcmp(msg, "\U0001F608") == 0) {
display->drawXbm(x + (SCREEN_WIDTH - devil_width) / 2, display->drawXbm(x + (SCREEN_WIDTH - devil_width) / 2,
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - devil_height) / 2 + 2 + 5, devil_width, devil_height, devil); y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - devil_height) / 2 + 2 + 5, devil_width, devil_height, devil);
} else if (strcmp(reinterpret_cast<const char *>(mp.decoded.payload.bytes), "♥️") == 0) { } else if (strcmp(msg, "♥️") == 0 || strcmp(msg, "\U0001F9E1") == 0 || strcmp(msg, "\U00002763") == 0 ||
strcmp(msg, "\U00002764") == 0 || strcmp(msg, "\U0001F495") == 0 || strcmp(msg, "\U0001F496") == 0 ||
strcmp(msg, "\U0001F497") == 0 || strcmp(msg, "\U0001F496") == 0) {
display->drawXbm(x + (SCREEN_WIDTH - heart_width) / 2, display->drawXbm(x + (SCREEN_WIDTH - heart_width) / 2,
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - heart_height) / 2 + 2 + 5, heart_width, heart_height, heart); y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - heart_height) / 2 + 2 + 5, heart_width, heart_height, heart);
} else { } else {
@@ -1789,7 +1799,7 @@ int32_t Screen::runOnce()
// serialSinceMsec adjusts for additional serial wait time during nRF52 bootup // serialSinceMsec adjusts for additional serial wait time during nRF52 bootup
static bool showingBootScreen = true; static bool showingBootScreen = true;
if (showingBootScreen && (millis() > (logo_timeout + serialSinceMsec))) { if (showingBootScreen && (millis() > (logo_timeout + serialSinceMsec))) {
LOG_INFO("Done with boot screen..."); LOG_INFO("Done with boot screen");
stopBootScreen(); stopBootScreen();
showingBootScreen = false; showingBootScreen = false;
} }
@@ -2058,7 +2068,7 @@ void Screen::setFrames(FrameFocus focus)
focus = FOCUS_FAULT; // Change our "focus" parameter, to ensure we show the fault frame focus = FOCUS_FAULT; // Change our "focus" parameter, to ensure we show the fault frame
} }
#ifdef T_WATCH_S3 #if defined(DISPLAY_CLOCK_FRAME)
normalFrames[numframes++] = screen->digitalWatchFace ? &Screen::drawDigitalClockFrame : &Screen::drawAnalogClockFrame; normalFrames[numframes++] = screen->digitalWatchFace ? &Screen::drawDigitalClockFrame : &Screen::drawAnalogClockFrame;
#endif #endif
@@ -2242,24 +2252,24 @@ void Screen::decreaseBrightness()
/* TO DO: add little popup in center of screen saying what brightness level it is set to*/ /* TO DO: add little popup in center of screen saying what brightness level it is set to*/
} }
void Screen::setFunctionSymbal(std::string sym) void Screen::setFunctionSymbol(std::string sym)
{ {
if (std::find(functionSymbals.begin(), functionSymbals.end(), sym) == functionSymbals.end()) { if (std::find(functionSymbol.begin(), functionSymbol.end(), sym) == functionSymbol.end()) {
functionSymbals.push_back(sym); functionSymbol.push_back(sym);
functionSymbalString = ""; functionSymbolString = "";
for (auto symbol : functionSymbals) { for (auto symbol : functionSymbol) {
functionSymbalString = symbol + " " + functionSymbalString; functionSymbolString = symbol + " " + functionSymbolString;
} }
setFastFramerate(); setFastFramerate();
} }
} }
void Screen::removeFunctionSymbal(std::string sym) void Screen::removeFunctionSymbol(std::string sym)
{ {
functionSymbals.erase(std::remove(functionSymbals.begin(), functionSymbals.end(), sym), functionSymbals.end()); functionSymbol.erase(std::remove(functionSymbol.begin(), functionSymbol.end(), sym), functionSymbol.end());
functionSymbalString = ""; functionSymbolString = "";
for (auto symbol : functionSymbals) { for (auto symbol : functionSymbol) {
functionSymbalString = symbol + " " + functionSymbalString; functionSymbolString = symbol + " " + functionSymbolString;
} }
setFastFramerate(); setFastFramerate();
} }
@@ -2689,7 +2699,7 @@ int Screen::handleUIFrameEvent(const UIFrameEvent *event)
int Screen::handleInputEvent(const InputEvent *event) int Screen::handleInputEvent(const InputEvent *event)
{ {
#ifdef T_WATCH_S3 #if defined(DISPLAY_CLOCK_FRAME)
// For the T-Watch, intercept touches to the 'toggle digital/analog watch face' button // For the T-Watch, intercept touches to the 'toggle digital/analog watch face' button
uint8_t watchFaceFrame = error_code ? 1 : 0; uint8_t watchFaceFrame = error_code ? 1 : 0;
@@ -2747,4 +2757,4 @@ int Screen::handleAdminMessage(const meshtastic_AdminMessage *arg)
} // namespace graphics } // namespace graphics
#else #else
graphics::Screen::Screen(ScanI2C::DeviceAddress, meshtastic_Config_DisplayConfig_OledType, OLEDDISPLAY_GEOMETRY) {} graphics::Screen::Screen(ScanI2C::DeviceAddress, meshtastic_Config_DisplayConfig_OledType, OLEDDISPLAY_GEOMETRY) {}
#endif // HAS_SCREEN #endif // HAS_SCREEN

View File

@@ -24,8 +24,8 @@ class Screen
void startFirmwareUpdateScreen() {} void startFirmwareUpdateScreen() {}
void increaseBrightness() {} void increaseBrightness() {}
void decreaseBrightness() {} void decreaseBrightness() {}
void setFunctionSymbal(std::string) {} void setFunctionSymbol(std::string) {}
void removeFunctionSymbal(std::string) {} void removeFunctionSymbol(std::string) {}
void startAlert(const char *) {} void startAlert(const char *) {}
void endAlert() {} void endAlert() {}
}; };
@@ -282,8 +282,8 @@ class Screen : public concurrency::OSThread
void increaseBrightness(); void increaseBrightness();
void decreaseBrightness(); void decreaseBrightness();
void setFunctionSymbal(std::string sym); void setFunctionSymbol(std::string sym);
void removeFunctionSymbal(std::string sym); void removeFunctionSymbol(std::string sym);
/// Stops showing the boot screen. /// Stops showing the boot screen.
void stopBootScreen() { enqueueCmd(ScreenCmd{.cmd = Cmd::STOP_BOOT_SCREEN}); } void stopBootScreen() { enqueueCmd(ScreenCmd{.cmd = Cmd::STOP_BOOT_SCREEN}); }
@@ -554,7 +554,7 @@ class Screen : public concurrency::OSThread
static void drawDebugInfoWiFiTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y); static void drawDebugInfoWiFiTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
#ifdef T_WATCH_S3 #if defined(DISPLAY_CLOCK_FRAME)
static void drawAnalogClockFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y); static void drawAnalogClockFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
static void drawDigitalClockFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y); static void drawDigitalClockFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
@@ -605,4 +605,4 @@ class Screen : public concurrency::OSThread
} // namespace graphics } // namespace graphics
#endif #endif

View File

@@ -14,7 +14,7 @@ const uint8_t imgUser[] PROGMEM = {0x3C, 0x42, 0x99, 0xA5, 0xA5, 0x99, 0x42, 0x3
const uint8_t imgPositionEmpty[] PROGMEM = {0x20, 0x30, 0x28, 0x24, 0x42, 0xFF}; const uint8_t imgPositionEmpty[] PROGMEM = {0x20, 0x30, 0x28, 0x24, 0x42, 0xFF};
const uint8_t imgPositionSolid[] PROGMEM = {0x20, 0x30, 0x38, 0x3C, 0x7E, 0xFF}; const uint8_t imgPositionSolid[] PROGMEM = {0x20, 0x30, 0x38, 0x3C, 0x7E, 0xFF};
#ifdef T_WATCH_S3 #if defined(DISPLAY_CLOCK_FRAME)
const uint8_t bluetoothConnectedIcon[36] PROGMEM = {0xfe, 0x01, 0xff, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0xe3, 0x1f, const uint8_t bluetoothConnectedIcon[36] PROGMEM = {0xfe, 0x01, 0xff, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0xe3, 0x1f,
0xf3, 0x3f, 0x33, 0x30, 0x33, 0x33, 0x33, 0x33, 0x03, 0x33, 0xff, 0x33, 0xf3, 0x3f, 0x33, 0x30, 0x33, 0x33, 0x33, 0x33, 0x03, 0x33, 0xff, 0x33,
0xfe, 0x31, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0xf0, 0x3f, 0xe0, 0x1f}; 0xfe, 0x31, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0xf0, 0x3f, 0xe0, 0x1f};
@@ -56,6 +56,16 @@ static unsigned char thumbdown[] PROGMEM = {
0x80, 0x09, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x80, 0x09, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00,
}; };
#define smiley_height 30
#define smiley_width 30
static unsigned char smiley[] PROGMEM = {
0x00, 0xfe, 0x0f, 0x00, 0x80, 0x01, 0x30, 0x00, 0x40, 0x00, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x02,
0x08, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x10, 0x02, 0x0e, 0x0e, 0x10, 0x02, 0x09, 0x12, 0x10,
0x01, 0x09, 0x12, 0x20, 0x01, 0x0f, 0x1e, 0x20, 0x01, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x20,
0x01, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x20, 0x81, 0x00, 0x20, 0x20,
0x82, 0x00, 0x20, 0x10, 0x02, 0x01, 0x10, 0x10, 0x04, 0x02, 0x08, 0x08, 0x04, 0xfc, 0x07, 0x08, 0x08, 0x00, 0x00, 0x04,
0x10, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x01, 0x40, 0x00, 0xc0, 0x00, 0x80, 0x01, 0x30, 0x00, 0x00, 0xfe, 0x0f, 0x00};
#define question_height 25 #define question_height 25
#define question_width 25 #define question_width 25
static unsigned char question[] PROGMEM = { static unsigned char question[] PROGMEM = {

View File

@@ -116,7 +116,7 @@ void MPR121Keyboard::begin(i2c_com_fptr_t r, i2c_com_fptr_t w, uint8_t addr)
void MPR121Keyboard::reset() void MPR121Keyboard::reset()
{ {
LOG_DEBUG("MPR121 Reset..."); LOG_DEBUG("MPR121 Reset");
// Trigger a MPR121 Soft Reset // Trigger a MPR121 Soft Reset
if (m_wire) { if (m_wire) {
m_wire->beginTransmission(m_addr); m_wire->beginTransmission(m_addr);

View File

@@ -1,6 +1,10 @@
#include "TouchScreenBase.h" #include "TouchScreenBase.h"
#include "main.h" #include "main.h"
#if defined(RAK14014) && !defined(MESHTASTIC_EXCLUDE_CANNEDMESSAGES)
#include "modules/CannedMessageModule.h"
#endif
#ifndef TIME_LONG_PRESS #ifndef TIME_LONG_PRESS
#define TIME_LONG_PRESS 400 #define TIME_LONG_PRESS 400
#endif #endif
@@ -102,12 +106,30 @@ int32_t TouchScreenBase::runOnce()
} }
_touchedOld = touched; _touchedOld = touched;
#if defined RAK14014
// Speed up the processing speed of the keyboard in virtual keyboard mode
auto state = cannedMessageModule->getRunState();
if (state == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
if (_tapped) {
_tapped = false;
e.touchEvent = static_cast<char>(TOUCH_ACTION_TAP);
LOG_DEBUG("action TAP(%d/%d)\n", _last_x, _last_y);
}
} else {
if (_tapped && (time_t(millis()) - _start) > TIME_LONG_PRESS - 50) {
_tapped = false;
e.touchEvent = static_cast<char>(TOUCH_ACTION_TAP);
LOG_DEBUG("action TAP(%d/%d)\n", _last_x, _last_y);
}
}
#else
// fire TAP event when no 2nd tap occured within time // fire TAP event when no 2nd tap occured within time
if (_tapped && (time_t(millis()) - _start) > TIME_LONG_PRESS - 50) { if (_tapped && (time_t(millis()) - _start) > TIME_LONG_PRESS - 50) {
_tapped = false; _tapped = false;
e.touchEvent = static_cast<char>(TOUCH_ACTION_TAP); e.touchEvent = static_cast<char>(TOUCH_ACTION_TAP);
LOG_DEBUG("action TAP(%d/%d)", _last_x, _last_y); LOG_DEBUG("action TAP(%d/%d)", _last_x, _last_y);
} }
#endif
// fire LONG_PRESS event without the need for release // fire LONG_PRESS event without the need for release
if (touched && (time_t(millis()) - _start) > TIME_LONG_PRESS) { if (touched && (time_t(millis()) - _start) > TIME_LONG_PRESS) {

View File

@@ -14,13 +14,13 @@
#include "FSCommon.h" #include "FSCommon.h"
#include "Led.h" #include "Led.h"
#include "RTC.h"
#include "SPILock.h" #include "SPILock.h"
#include "Throttle.h" #include "Throttle.h"
#include "concurrency/OSThread.h" #include "concurrency/OSThread.h"
#include "concurrency/Periodic.h" #include "concurrency/Periodic.h"
#include "detect/ScanI2C.h" #include "detect/ScanI2C.h"
#include "error.h" #include "error.h"
#include "gps/RTC.h"
#include "power.h" #include "power.h"
#if !MESHTASTIC_EXCLUDE_I2C #if !MESHTASTIC_EXCLUDE_I2C
@@ -28,6 +28,7 @@
#include <Wire.h> #include <Wire.h>
#endif #endif
#include "detect/einkScan.h" #include "detect/einkScan.h"
#include "gps/RTC.h"
#include "graphics/RAKled.h" #include "graphics/RAKled.h"
#include "graphics/Screen.h" #include "graphics/Screen.h"
#include "main.h" #include "main.h"
@@ -103,7 +104,7 @@ NRF52Bluetooth *nrf52Bluetooth = nullptr;
#include "AmbientLightingThread.h" #include "AmbientLightingThread.h"
#include "PowerFSMThread.h" #include "PowerFSMThread.h"
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C && !defined(ARCH_APOLLO3)
#include "motion/AccelerometerThread.h" #include "motion/AccelerometerThread.h"
AccelerometerThread *accelerometerThread = nullptr; AccelerometerThread *accelerometerThread = nullptr;
#endif #endif
@@ -150,7 +151,7 @@ ScanI2C::DeviceAddress accelerometer_found = ScanI2C::ADDRESS_NONE;
// The I2C address of the RGB LED (if found) // The I2C address of the RGB LED (if found)
ScanI2C::FoundDevice rgb_found = ScanI2C::FoundDevice(ScanI2C::DeviceType::NONE, ScanI2C::ADDRESS_NONE); ScanI2C::FoundDevice rgb_found = ScanI2C::FoundDevice(ScanI2C::DeviceType::NONE, ScanI2C::ADDRESS_NONE);
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !defined(ARCH_APOLLO3)
ATECCX08A atecc; ATECCX08A atecc;
#endif #endif
@@ -435,7 +436,7 @@ void setup()
// accessories // accessories
auto i2cScanner = std::unique_ptr<ScanI2CTwoWire>(new ScanI2CTwoWire()); auto i2cScanner = std::unique_ptr<ScanI2CTwoWire>(new ScanI2CTwoWire());
#if HAS_WIRE #if HAS_WIRE
LOG_INFO("Scan for i2c devices..."); LOG_INFO("Scan for i2c devices");
#endif #endif
#if defined(I2C_SDA1) && defined(ARCH_RP2040) #if defined(I2C_SDA1) && defined(ARCH_RP2040)
@@ -460,7 +461,7 @@ void setup()
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE); i2cScanner->scanPort(ScanI2C::I2CPort::WIRE);
#elif defined(ARCH_PORTDUINO) #elif defined(ARCH_PORTDUINO)
if (settingsStrings[i2cdev] != "") { if (settingsStrings[i2cdev] != "") {
LOG_INFO("Scan for i2c devices..."); LOG_INFO("Scan for i2c devices");
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE); i2cScanner->scanPort(ScanI2C::I2CPort::WIRE);
} }
#elif HAS_WIRE #elif HAS_WIRE
@@ -614,6 +615,7 @@ void setup()
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::DFROBOT_LARK, meshtastic_TelemetrySensorType_DFROBOT_LARK) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::DFROBOT_LARK, meshtastic_TelemetrySensorType_DFROBOT_LARK)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::ICM20948, meshtastic_TelemetrySensorType_ICM20948) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::ICM20948, meshtastic_TelemetrySensorType_ICM20948)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::MAX30102, meshtastic_TelemetrySensorType_MAX30102) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::MAX30102, meshtastic_TelemetrySensorType_MAX30102)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::CGRADSENS, meshtastic_TelemetrySensorType_RADSENS)
i2cScanner.reset(); i2cScanner.reset();
#endif #endif
@@ -689,7 +691,7 @@ void setup()
#endif #endif
#if !MESHTASTIC_EXCLUDE_I2C #if !MESHTASTIC_EXCLUDE_I2C
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !defined(ARCH_APOLLO3)
if (acc_info.type != ScanI2C::DeviceType::NONE) { if (acc_info.type != ScanI2C::DeviceType::NONE) {
accelerometerThread = new AccelerometerThread(acc_info.type); accelerometerThread = new AccelerometerThread(acc_info.type);
} }
@@ -697,7 +699,7 @@ void setup()
#if defined(HAS_NEOPIXEL) || defined(UNPHONE) || defined(RGBLED_RED) #if defined(HAS_NEOPIXEL) || defined(UNPHONE) || defined(RGBLED_RED)
ambientLightingThread = new AmbientLightingThread(ScanI2C::DeviceType::NONE); ambientLightingThread = new AmbientLightingThread(ScanI2C::DeviceType::NONE);
#elif !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) #elif !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !defined(ARCH_APOLLO3)
if (rgb_found.type != ScanI2C::DeviceType::NONE) { if (rgb_found.type != ScanI2C::DeviceType::NONE) {
ambientLightingThread = new AmbientLightingThread(rgb_found.type); ambientLightingThread = new AmbientLightingThread(rgb_found.type);
} }
@@ -1161,6 +1163,31 @@ extern meshtastic_DeviceMetadata getDeviceMetadata()
deviceMetadata.hw_model = HW_VENDOR; deviceMetadata.hw_model = HW_VENDOR;
deviceMetadata.hasRemoteHardware = moduleConfig.remote_hardware.enabled; deviceMetadata.hasRemoteHardware = moduleConfig.remote_hardware.enabled;
deviceMetadata.excluded_modules = meshtastic_ExcludedModules_EXCLUDED_NONE; deviceMetadata.excluded_modules = meshtastic_ExcludedModules_EXCLUDED_NONE;
#if MESHTASTIC_EXCLUDE_REMOTEHARDWARE
deviceMetadata.excluded_modules |= meshtastic_ExcludedModules_REMOTEHARDWARE_CONFIG;
#endif
#if MESHTASTIC_EXCLUDE_AUDIO
deviceMetadata.excluded_modules |= meshtastic_ExcludedModules_AUDIO_CONFIG;
#endif
#if !HAS_SCREEN || NO_EXT_GPIO
deviceMetadata.excluded_modules |= meshtastic_ExcludedModules_CANNEDMSG_CONFIG | meshtastic_ExcludedModules_EXTNOTIF_CONFIG;
#endif
// Only edge case here is if we apply this a device with built in Accelerometer and want to detect interrupts
// We'll have to macro guard against those targets potentially
#if NO_EXT_GPIO
deviceMetadata.excluded_modules |= meshtastic_ExcludedModules_DETECTIONSENSOR_CONFIG;
#endif
// If we don't have any GPIO and we don't have GPS, no purpose in having serial config
#if NO_EXT_GPIO && NO_GPS
deviceMetadata.excluded_modules |= meshtastic_ExcludedModules_SERIAL_CONFIG;
#endif
#ifndef ARCH_ESP32
deviceMetadata.excluded_modules |= meshtastic_ExcludedModules_PAXCOUNTER_CONFIG;
#endif
#if !defined(HAS_NCP5623) && !defined(RGBLED_RED) && !defined(HAS_NEOPIXEL) && !defined(UNPHONE) && !RAK_4631
deviceMetadata.excluded_modules |= meshtastic_ExcludedModules_AMBIENTLIGHTING_CONFIG;
#endif
#if !(MESHTASTIC_EXCLUDE_PKI) #if !(MESHTASTIC_EXCLUDE_PKI)
deviceMetadata.hasPKC = true; deviceMetadata.hasPKC = true;
#endif #endif

View File

@@ -10,7 +10,7 @@
#include "mesh/generated/meshtastic/telemetry.pb.h" #include "mesh/generated/meshtastic/telemetry.pb.h"
#include <SPI.h> #include <SPI.h>
#include <map> #include <map>
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !defined(ARCH_APOLLO3)
#include <SparkFun_ATECCX08a_Arduino_Library.h> #include <SparkFun_ATECCX08a_Arduino_Library.h>
#endif #endif
#if defined(ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32S2) #if defined(ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32S2)
@@ -39,7 +39,7 @@ extern bool pmu_found;
extern bool isCharging; extern bool isCharging;
extern bool isUSBPowered; extern bool isUSBPowered;
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !defined(ARCH_APOLLO3)
extern ATECCX08A atecc; extern ATECCX08A atecc;
#endif #endif

View File

@@ -1,5 +1,6 @@
#include "Default.h" #include "Default.h"
#include "../userPrefs.h" #include "../userPrefs.h"
#include "meshUtils.h"
uint32_t Default::getConfiguredOrDefaultMs(uint32_t configuredInterval, uint32_t defaultInterval) uint32_t Default::getConfiguredOrDefaultMs(uint32_t configuredInterval, uint32_t defaultInterval)
{ {
@@ -40,6 +41,10 @@ uint32_t Default::getConfiguredOrDefaultMsScaled(uint32_t configured, uint32_t d
if (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER) if (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER)
return getConfiguredOrDefaultMs(configured, defaultValue); return getConfiguredOrDefaultMs(configured, defaultValue);
// Additionally if we're a tracker or sensor, we want priority to send position and telemetry
if (IS_ONE_OF(config.device.role, meshtastic_Config_DeviceConfig_Role_SENSOR, meshtastic_Config_DeviceConfig_Role_TRACKER))
return getConfiguredOrDefaultMs(configured, defaultValue);
return getConfiguredOrDefaultMs(configured, defaultValue) * congestionScalingCoefficient(numOnlineNodes); return getConfiguredOrDefaultMs(configured, defaultValue) * congestionScalingCoefficient(numOnlineNodes);
} }

View File

@@ -1,6 +1,7 @@
#pragma once #pragma once
#include <NodeDB.h> #include <NodeDB.h>
#include <cstdint> #include <cstdint>
#include <meshUtils.h>
#define ONE_DAY 24 * 60 * 60 #define ONE_DAY 24 * 60 * 60
#define ONE_MINUTE_MS 60 * 1000 #define ONE_MINUTE_MS 60 * 1000
#define THIRTY_SECONDS_MS 30 * 1000 #define THIRTY_SECONDS_MS 30 * 1000
@@ -18,7 +19,7 @@
#define default_node_info_broadcast_secs 3 * 60 * 60 #define default_node_info_broadcast_secs 3 * 60 * 60
#define default_neighbor_info_broadcast_secs 6 * 60 * 60 #define default_neighbor_info_broadcast_secs 6 * 60 * 60
#define min_node_info_broadcast_secs 60 * 60 // No regular broadcasts of more than once an hour #define min_node_info_broadcast_secs 60 * 60 // No regular broadcasts of more than once an hour
#define min_neighbor_info_broadcast_secs 2 * 60 * 60 #define min_neighbor_info_broadcast_secs 4 * 60 * 60
#define default_mqtt_address "mqtt.meshtastic.org" #define default_mqtt_address "mqtt.meshtastic.org"
#define default_mqtt_username "meshdev" #define default_mqtt_username "meshdev"
@@ -41,12 +42,30 @@ class Default
private: private:
static float congestionScalingCoefficient(int numOnlineNodes) static float congestionScalingCoefficient(int numOnlineNodes)
{ {
if (numOnlineNodes <= 40) { // Increase frequency of broadcasts for small networks regardless of preset
return 1.0; // No scaling for 40 or fewer nodes if (numOnlineNodes <= 10) {
return 0.6;
} else if (numOnlineNodes <= 20) {
return 0.7;
} else if (numOnlineNodes <= 30) {
return 0.8;
} else if (numOnlineNodes <= 40) {
return 1.0;
} else { } else {
// Sscaling based on number of nodes over 40 float throttlingFactor = 0.075;
if (config.lora.use_preset && config.lora.modem_preset == meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW)
throttlingFactor = 0.04;
else if (config.lora.use_preset && config.lora.modem_preset == meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST)
throttlingFactor = 0.02;
else if (config.lora.use_preset && config.lora.modem_preset == meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW)
throttlingFactor = 0.01;
else if (config.lora.use_preset &&
IS_ONE_OF(config.lora.modem_preset, meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST,
meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO))
return 1.0; // Don't bother throttling for highest bandwidth presets
// Scaling up traffic based on number of nodes over 40
int nodesOverForty = (numOnlineNodes - 40); int nodesOverForty = (numOnlineNodes - 40);
return 1.0 + (nodesOverForty * 0.075); // Each number of online node scales by 0.075 return 1.0 + (nodesOverForty * throttlingFactor); // Each number of online node scales by 0.075 (default)
} }
} }
}; };

View File

@@ -29,6 +29,17 @@ bool FloodingRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
if (Router::cancelSending(p->from, p->id)) if (Router::cancelSending(p->from, p->id))
txRelayCanceled++; txRelayCanceled++;
} }
/* If the original transmitter is doing retransmissions (hopStart equals hopLimit) for a reliable transmission, e.g., when
the ACK got lost, we will handle the packet again to make sure it gets an ACK to its packet. */
bool isRepeated = p->hop_start > 0 && p->hop_start == p->hop_limit;
if (isRepeated) {
LOG_DEBUG("Repeated reliable tx");
if (!perhapsRebroadcast(p) && isToUs(p) && p->want_ack) {
sendAckNak(meshtastic_Routing_Error_NONE, getFrom(p), p->id, p->channel, 0);
}
}
return true; return true;
} }
@@ -41,14 +52,8 @@ bool FloodingRouter::isRebroadcaster()
config.device.rebroadcast_mode != meshtastic_Config_DeviceConfig_RebroadcastMode_NONE; config.device.rebroadcast_mode != meshtastic_Config_DeviceConfig_RebroadcastMode_NONE;
} }
void FloodingRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtastic_Routing *c) bool FloodingRouter::perhapsRebroadcast(const meshtastic_MeshPacket *p)
{ {
bool isAckorReply = (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) && (p->decoded.request_id != 0);
if (isAckorReply && !isToUs(p) && !isBroadcast(p->to)) {
// do not flood direct message that is ACKed or replied to
LOG_DEBUG("Rxd an ACK/reply not for me, cancel rebroadcast");
Router::cancelSending(p->to, p->decoded.request_id); // cancel rebroadcast for this DM
}
if (!isToUs(p) && (p->hop_limit > 0) && !isFromUs(p)) { if (!isToUs(p) && (p->hop_limit > 0) && !isFromUs(p)) {
if (p->id != 0) { if (p->id != 0) {
if (isRebroadcaster()) { if (isRebroadcaster()) {
@@ -67,6 +72,8 @@ void FloodingRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtas
// Note: we are careful to resend using the original senders node id // Note: we are careful to resend using the original senders node id
// We are careful not to call our hooked version of send() - because we don't want to check this again // We are careful not to call our hooked version of send() - because we don't want to check this again
Router::send(tosend); Router::send(tosend);
return true;
} else { } else {
LOG_DEBUG("No rebroadcast: Role = CLIENT_MUTE or Rebroadcast Mode = NONE"); LOG_DEBUG("No rebroadcast: Role = CLIENT_MUTE or Rebroadcast Mode = NONE");
} }
@@ -74,6 +81,21 @@ void FloodingRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtas
LOG_DEBUG("Ignore 0 id broadcast"); LOG_DEBUG("Ignore 0 id broadcast");
} }
} }
return false;
}
void FloodingRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtastic_Routing *c)
{
bool isAckorReply = (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) && (p->decoded.request_id != 0);
if (isAckorReply && !isToUs(p) && !isBroadcast(p->to)) {
// do not flood direct message that is ACKed or replied to
LOG_DEBUG("Rxd an ACK/reply not for me, cancel rebroadcast");
Router::cancelSending(p->to, p->decoded.request_id); // cancel rebroadcast for this DM
}
perhapsRebroadcast(p);
// handle the packet as normal // handle the packet as normal
Router::sniffReceived(p, c); Router::sniffReceived(p, c);
} }

View File

@@ -31,6 +31,10 @@ class FloodingRouter : public Router, protected PacketHistory
private: private:
bool isRebroadcaster(); bool isRebroadcaster();
/** Check if we should rebroadcast this packet, and do so if needed
* @return true if rebroadcasted */
bool perhapsRebroadcast(const meshtastic_MeshPacket *p);
public: public:
/** /**
* Constructor * Constructor

View File

@@ -9,8 +9,8 @@
#include "MeshService.h" #include "MeshService.h"
#include "NodeDB.h" #include "NodeDB.h"
#include "PowerFSM.h" #include "PowerFSM.h"
#include "RTC.h"
#include "TypeConversions.h" #include "TypeConversions.h"
#include "gps/RTC.h"
#include "main.h" #include "main.h"
#include "mesh-pb-constants.h" #include "mesh-pb-constants.h"
#include "meshUtils.h" #include "meshUtils.h"

View File

@@ -12,11 +12,11 @@
#include "NodeDB.h" #include "NodeDB.h"
#include "PacketHistory.h" #include "PacketHistory.h"
#include "PowerFSM.h" #include "PowerFSM.h"
#include "RTC.h"
#include "Router.h" #include "Router.h"
#include "SafeFile.h" #include "SafeFile.h"
#include "TypeConversions.h" #include "TypeConversions.h"
#include "error.h" #include "error.h"
#include "gps/RTC.h"
#include "main.h" #include "main.h"
#include "mesh-pb-constants.h" #include "mesh-pb-constants.h"
#include "meshUtils.h" #include "meshUtils.h"
@@ -61,6 +61,16 @@ meshtastic_LocalConfig config;
meshtastic_LocalModuleConfig moduleConfig; meshtastic_LocalModuleConfig moduleConfig;
meshtastic_ChannelFile channelFile; meshtastic_ChannelFile channelFile;
#ifdef USERPREFS_USE_ADMIN_KEY_0
static unsigned char userprefs_admin_key_0[] = USERPREFS_USE_ADMIN_KEY_0;
#endif
#ifdef USERPREFS_USE_ADMIN_KEY_1
static unsigned char userprefs_admin_key_1[] = USERPREFS_USE_ADMIN_KEY_1;
#endif
#ifdef USERPREFS_USE_ADMIN_KEY_2
static unsigned char userprefs_admin_key_2[] = USERPREFS_USE_ADMIN_KEY_2;
#endif
bool meshtastic_DeviceState_callback(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_iter_t *field) bool meshtastic_DeviceState_callback(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_iter_t *field)
{ {
if (ostream) { if (ostream) {
@@ -114,7 +124,7 @@ NodeDB::NodeDB()
uint32_t channelFileCRC = crc32Buffer(&channelFile, sizeof(channelFile)); uint32_t channelFileCRC = crc32Buffer(&channelFile, sizeof(channelFile));
int saveWhat = 0; int saveWhat = 0;
bool hasUniqueId = false; // bool hasUniqueId = false;
// Get device unique id // Get device unique id
#if defined(ARCH_ESP32) && defined(ESP_EFUSE_OPTIONAL_UNIQUE_ID) #if defined(ARCH_ESP32) && defined(ESP_EFUSE_OPTIONAL_UNIQUE_ID)
uint32_t unique_id[4]; uint32_t unique_id[4];
@@ -231,6 +241,9 @@ NodeDB::NodeDB()
moduleConfig.telemetry.health_update_interval = Default::getConfiguredOrMinimumValue( moduleConfig.telemetry.health_update_interval = Default::getConfiguredOrMinimumValue(
moduleConfig.telemetry.health_update_interval, min_default_telemetry_interval_secs); moduleConfig.telemetry.health_update_interval, min_default_telemetry_interval_secs);
} }
// Ensure that the neighbor info update interval is coerced to the minimum
moduleConfig.neighbor_info.update_interval =
Default::getConfiguredOrMinimumValue(moduleConfig.neighbor_info.update_interval, min_neighbor_info_broadcast_secs);
if (devicestateCRC != crc32Buffer(&devicestate, sizeof(devicestate))) if (devicestateCRC != crc32Buffer(&devicestate, sizeof(devicestate)))
saveWhat |= SEGMENT_DEVICESTATE; saveWhat |= SEGMENT_DEVICESTATE;
@@ -243,6 +256,31 @@ NodeDB::NodeDB()
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_ENABLED; config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_ENABLED;
config.position.gps_enabled = 0; config.position.gps_enabled = 0;
} }
#ifdef USERPREFS_FIXED_GPS
if (myNodeInfo.reboot_count == 1) { // Check if First boot ever or after Factory Reset.
meshtastic_Position fixedGPS = meshtastic_Position_init_default;
#ifdef USERPREFS_FIXED_GPS_LAT
fixedGPS.latitude_i = (int32_t)(USERPREFS_FIXED_GPS_LAT * 1e7);
fixedGPS.has_latitude_i = true;
#endif
#ifdef USERPREFS_FIXED_GPS_LON
fixedGPS.longitude_i = (int32_t)(USERPREFS_FIXED_GPS_LON * 1e7);
fixedGPS.has_longitude_i = true;
#endif
#ifdef USERPREFS_FIXED_GPS_ALT
fixedGPS.altitude = USERPREFS_FIXED_GPS_ALT;
fixedGPS.has_altitude = true;
#endif
#if defined(USERPREFS_FIXED_GPS_LAT) && defined(USERPREFS_FIXED_GPS_LON)
fixedGPS.location_source = meshtastic_Position_LocSource_LOC_MANUAL;
config.has_position = true;
info->has_position = true;
info->position = TypeConversions::ConvertToPositionLite(fixedGPS);
nodeDB->setLocalPosition(fixedGPS);
config.position.fixed_position = true;
#endif
}
#endif
saveToDisk(saveWhat); saveToDisk(saveWhat);
} }
@@ -378,11 +416,37 @@ void NodeDB::installDefaultConfig(bool preserveKey = false)
#else #else
config.lora.ignore_mqtt = false; config.lora.ignore_mqtt = false;
#endif #endif
#ifdef USERPREFS_USE_ADMIN_KEY // Initialize admin_key_count to zero
memcpy(config.security.admin_key[0].bytes, USERPREFS_ADMIN_KEY, 32); byte numAdminKeys = 0;
config.security.admin_key[0].size = 32;
config.security.admin_key_count = 1; #ifdef USERPREFS_USE_ADMIN_KEY_0
// Check if USERPREFS_ADMIN_KEY_0 is non-empty
if (sizeof(userprefs_admin_key_0) > 0) {
memcpy(config.security.admin_key[0].bytes, userprefs_admin_key_0, 32);
config.security.admin_key[0].size = 32;
numAdminKeys++;
}
#endif #endif
#ifdef USERPREFS_USE_ADMIN_KEY_1
// Check if USERPREFS_ADMIN_KEY_1 is non-empty
if (sizeof(userprefs_admin_key_1) > 0) {
memcpy(config.security.admin_key[1].bytes, userprefs_admin_key_1, 32);
config.security.admin_key[1].size = 32;
numAdminKeys++;
}
#endif
#ifdef USERPREFS_USE_ADMIN_KEY_2
// Check if USERPREFS_ADMIN_KEY_2 is non-empty
if (sizeof(userprefs_admin_key_2) > 0) {
memcpy(config.security.admin_key[2].bytes, userprefs_admin_key_2, 32);
config.security.admin_key[2].size = 32;
numAdminKeys++;
}
#endif
config.security.admin_key_count = numAdminKeys;
if (shouldPreserveKey) { if (shouldPreserveKey) {
config.security.private_key.size = 32; config.security.private_key.size = 32;
memcpy(config.security.private_key.bytes, private_key_temp, config.security.private_key.size); memcpy(config.security.private_key.bytes, private_key_temp, config.security.private_key.size);
@@ -435,8 +499,13 @@ void NodeDB::installDefaultConfig(bool preserveKey = false)
#else #else
bool hasScreen = screen_found.port != ScanI2C::I2CPort::NO_I2C; bool hasScreen = screen_found.port != ScanI2C::I2CPort::NO_I2C;
#endif #endif
#ifdef USERPREFS_FIXED_BLUETOOTH
config.bluetooth.fixed_pin = USERPREFS_FIXED_BLUETOOTH;
config.bluetooth.mode = meshtastic_Config_BluetoothConfig_PairingMode_FIXED_PIN;
#else
config.bluetooth.mode = hasScreen ? meshtastic_Config_BluetoothConfig_PairingMode_RANDOM_PIN config.bluetooth.mode = hasScreen ? meshtastic_Config_BluetoothConfig_PairingMode_RANDOM_PIN
: meshtastic_Config_BluetoothConfig_PairingMode_FIXED_PIN; : meshtastic_Config_BluetoothConfig_PairingMode_FIXED_PIN;
#endif
// for backward compat, default position flags are ALT+MSL // for backward compat, default position flags are ALT+MSL
config.position.position_flags = config.position.position_flags =
(meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE | meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE_MSL | (meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE | meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE_MSL |
@@ -449,7 +518,7 @@ void NodeDB::installDefaultConfig(bool preserveKey = false)
#ifdef RAK4630 #ifdef RAK4630
config.display.wake_on_tap_or_motion = true; config.display.wake_on_tap_or_motion = true;
#endif #endif
#ifdef T_WATCH_S3 #if defined(T_WATCH_S3) || defined(SENSECAP_INDICATOR)
config.display.screen_on_secs = 30; config.display.screen_on_secs = 30;
config.display.wake_on_tap_or_motion = true; config.display.wake_on_tap_or_motion = true;
#endif #endif
@@ -473,7 +542,7 @@ void NodeDB::initConfigIntervals()
config.display.screen_on_secs = default_screen_on_secs; config.display.screen_on_secs = default_screen_on_secs;
#if defined(T_WATCH_S3) || defined(T_DECK) #if defined(T_WATCH_S3) || defined(T_DECK) || defined(RAK14014) || defined(SENSECAP_INDICATOR)
config.power.is_power_saving = true; config.power.is_power_saving = true;
config.display.screen_on_secs = 30; config.display.screen_on_secs = 30;
config.power.wait_bluetooth_secs = 30; config.power.wait_bluetooth_secs = 30;
@@ -647,7 +716,7 @@ void NodeDB::removeNodeByNum(NodeNum nodeNum)
numMeshNodes -= removed; numMeshNodes -= removed;
std::fill(devicestate.node_db_lite.begin() + numMeshNodes, devicestate.node_db_lite.begin() + numMeshNodes + 1, std::fill(devicestate.node_db_lite.begin() + numMeshNodes, devicestate.node_db_lite.begin() + numMeshNodes + 1,
meshtastic_NodeInfoLite()); meshtastic_NodeInfoLite());
LOG_DEBUG("NodeDB::removeNodeByNum purged %d entries. Save changes...", removed); LOG_DEBUG("NodeDB::removeNodeByNum purged %d entries. Save changes", removed);
saveDeviceStateToDisk(); saveDeviceStateToDisk();
} }
@@ -790,8 +859,13 @@ void NodeDB::loadFromDisk()
0; // Mark the current device state as completely unusable, so that if we fail reading the entire file from 0; // Mark the current device state as completely unusable, so that if we fail reading the entire file from
// disk we will still factoryReset to restore things. // disk we will still factoryReset to restore things.
#ifdef ARCH_ESP32
if (FSCom.exists("/static/static"))
rmDir("/static/static"); // Remove bad static web files bundle from initial 2.5.13 release
#endif
// static DeviceState scratch; We no longer read into a tempbuf because this structure is 15KB of valuable RAM // static DeviceState scratch; We no longer read into a tempbuf because this structure is 15KB of valuable RAM
auto state = loadProto(prefFileName, sizeof(meshtastic_DeviceState) + MAX_NUM_NODES * sizeof(meshtastic_NodeInfo), auto state = loadProto(prefFileName, sizeof(meshtastic_DeviceState) + MAX_NUM_NODES_FS * sizeof(meshtastic_NodeInfo),
sizeof(meshtastic_DeviceState), &meshtastic_DeviceState_msg, &devicestate); sizeof(meshtastic_DeviceState), &meshtastic_DeviceState_msg, &devicestate);
// See https://github.com/meshtastic/firmware/issues/4184#issuecomment-2269390786 // See https://github.com/meshtastic/firmware/issues/4184#issuecomment-2269390786
@@ -810,6 +884,10 @@ void NodeDB::loadFromDisk()
meshNodes = &devicestate.node_db_lite; meshNodes = &devicestate.node_db_lite;
numMeshNodes = devicestate.node_db_lite.size(); numMeshNodes = devicestate.node_db_lite.size();
} }
if (numMeshNodes > MAX_NUM_NODES) {
LOG_WARN("Node count %d exceeds MAX_NUM_NODES %d, truncating", numMeshNodes, MAX_NUM_NODES);
numMeshNodes = MAX_NUM_NODES;
}
meshNodes->resize(MAX_NUM_NODES); meshNodes->resize(MAX_NUM_NODES);
state = loadProto(configFileName, meshtastic_LocalConfig_size, sizeof(meshtastic_LocalConfig), &meshtastic_LocalConfig_msg, state = loadProto(configFileName, meshtastic_LocalConfig_size, sizeof(meshtastic_LocalConfig), &meshtastic_LocalConfig_msg,
@@ -825,6 +903,54 @@ void NodeDB::loadFromDisk()
} }
} }
// Make sure we load hard coded admin keys even when the configuration file has none.
// Initialize admin_key_count to zero
byte numAdminKeys = 0;
uint16_t sum = 0;
#ifdef USERPREFS_USE_ADMIN_KEY_0
for (uint8_t b = 0; b < 32; b++) {
sum += config.security.admin_key[0].bytes[b];
}
if (sum == 0) {
numAdminKeys += 1;
LOG_INFO("Admin 0 key zero. Loading hard coded key from user preferences.");
memcpy(config.security.admin_key[0].bytes, userprefs_admin_key_0, 32);
config.security.admin_key[0].size = 32;
config.security.admin_key_count = numAdminKeys;
saveToDisk(SEGMENT_CONFIG);
}
#endif
#ifdef USERPREFS_USE_ADMIN_KEY_1
sum = 0;
for (uint8_t b = 0; b < 32; b++) {
sum += config.security.admin_key[1].bytes[b];
}
if (sum == 0) {
numAdminKeys += 1;
LOG_INFO("Admin 1 key zero. Loading hard coded key from user preferences.");
memcpy(config.security.admin_key[1].bytes, userprefs_admin_key_1, 32);
config.security.admin_key[1].size = 32;
config.security.admin_key_count = numAdminKeys;
saveToDisk(SEGMENT_CONFIG);
}
#endif
#ifdef USERPREFS_USE_ADMIN_KEY_2
sum = 0;
for (uint8_t b = 0; b < 32; b++) {
sum += config.security.admin_key[2].bytes[b];
}
if (sum == 0) {
numAdminKeys += 1;
LOG_INFO("Admin 2 key zero. Loading hard coded key from user preferences.");
memcpy(config.security.admin_key[2].bytes, userprefs_admin_key_2, 32);
config.security.admin_key[2].size = 32;
config.security.admin_key_count = numAdminKeys;
saveToDisk(SEGMENT_CONFIG);
}
#endif
state = loadProto(moduleConfigFileName, meshtastic_LocalModuleConfig_size, sizeof(meshtastic_LocalModuleConfig), state = loadProto(moduleConfigFileName, meshtastic_LocalModuleConfig_size, sizeof(meshtastic_LocalModuleConfig),
&meshtastic_LocalModuleConfig_msg, &moduleConfig); &meshtastic_LocalModuleConfig_msg, &moduleConfig);
if (state != LoadFileResult::LOAD_SUCCESS) { if (state != LoadFileResult::LOAD_SUCCESS) {
@@ -976,7 +1102,7 @@ bool NodeDB::saveToDisk(int saveWhat)
bool success = saveToDiskNoRetry(saveWhat); bool success = saveToDiskNoRetry(saveWhat);
if (!success) { if (!success) {
LOG_ERROR("Failed to save to disk, retrying..."); LOG_ERROR("Failed to save to disk, retrying");
#ifdef ARCH_NRF52 // @geeksville is not ready yet to say we should do this on other platforms. See bug #4184 discussion #ifdef ARCH_NRF52 // @geeksville is not ready yet to say we should do this on other platforms. See bug #4184 discussion
FSCom.format(); FSCom.format();
@@ -1152,7 +1278,7 @@ bool NodeDB::updateUser(uint32_t nodeId, meshtastic_User &p, uint8_t channelInde
// We just changed something about the user, store our DB // We just changed something about the user, store our DB
Throttle::execute( Throttle::execute(
&lastNodeDbSave, ONE_MINUTE_MS, []() { nodeDB->saveToDisk(SEGMENT_DEVICESTATE); }, &lastNodeDbSave, ONE_MINUTE_MS, []() { nodeDB->saveToDisk(SEGMENT_DEVICESTATE); },
[]() { LOG_DEBUG("Deferring NodeDB saveToDisk for now"); }); // since we saved less than a minute ago []() { LOG_DEBUG("Defer NodeDB saveToDisk for now"); }); // since we saved less than a minute ago
} }
return changed; return changed;
@@ -1219,9 +1345,7 @@ meshtastic_NodeInfoLite *NodeDB::getOrCreateMeshNode(NodeNum n)
if (!lite) { if (!lite) {
if (isFull()) { if (isFull()) {
if (screen) LOG_INFO("Node database full with %i nodes and %i bytes free. Erasing oldest entry", numMeshNodes,
screen->print("Warn: node database full!\nErasing oldest entry\n");
LOG_WARN("Node database full with %i nodes and %i bytes free! Erasing oldest entry", numMeshNodes,
memGet.getFreeHeap()); memGet.getFreeHeap());
// look for oldest node and erase it // look for oldest node and erase it
uint32_t oldest = UINT32_MAX; uint32_t oldest = UINT32_MAX;
@@ -1230,12 +1354,12 @@ meshtastic_NodeInfoLite *NodeDB::getOrCreateMeshNode(NodeNum n)
int oldestBoringIndex = -1; int oldestBoringIndex = -1;
for (int i = 1; i < numMeshNodes; i++) { for (int i = 1; i < numMeshNodes; i++) {
// Simply the oldest non-favorite node // Simply the oldest non-favorite node
if (!meshNodes->at(i).is_favorite && meshNodes->at(i).last_heard < oldest) { if (!meshNodes->at(i).is_favorite && !meshNodes->at(i).is_ignored && meshNodes->at(i).last_heard < oldest) {
oldest = meshNodes->at(i).last_heard; oldest = meshNodes->at(i).last_heard;
oldestIndex = i; oldestIndex = i;
} }
// The oldest "boring" node // The oldest "boring" node
if (!meshNodes->at(i).is_favorite && meshNodes->at(i).user.public_key.size == 0 && if (!meshNodes->at(i).is_favorite && !meshNodes->at(i).is_ignored && meshNodes->at(i).user.public_key.size == 0 &&
meshNodes->at(i).last_heard < oldestBoring) { meshNodes->at(i).last_heard < oldestBoring) {
oldestBoring = meshNodes->at(i).last_heard; oldestBoring = meshNodes->at(i).last_heard;
oldestBoringIndex = i; oldestBoringIndex = i;
@@ -1282,7 +1406,7 @@ void recordCriticalError(meshtastic_CriticalErrorCode code, uint32_t address, co
// Currently portuino is mostly used for simulation. Make sure the user notices something really bad happened // Currently portuino is mostly used for simulation. Make sure the user notices something really bad happened
#ifdef ARCH_PORTDUINO #ifdef ARCH_PORTDUINO
LOG_ERROR("A critical failure occurred, portduino is exiting..."); LOG_ERROR("A critical failure occurred, portduino is exiting");
exit(2); exit(2);
#endif #endif
} }

View File

@@ -38,13 +38,6 @@ bool PacketHistory::wasSeenRecently(const meshtastic_MeshPacket *p, bool withUpd
seenRecently = false; seenRecently = false;
} }
/* If the original transmitter is doing retransmissions (hopStart equals hopLimit) for a reliable transmission, e.g., when the
ACK got lost, we will handle the packet again to make sure it gets an ACK/response to its packet. */
if (seenRecently && p->hop_start > 0 && p->hop_start == p->hop_limit) {
LOG_DEBUG("Repeated reliable tx");
seenRecently = false;
}
if (seenRecently) { if (seenRecently) {
LOG_DEBUG("Found existing packet record for fr=0x%x,to=0x%x,id=0x%x", p->from, p->to, p->id); LOG_DEBUG("Found existing packet record for fr=0x%x,to=0x%x,id=0x%x", p->from, p->to, p->id);
} }

View File

@@ -218,62 +218,70 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
} }
case STATE_SEND_METADATA: case STATE_SEND_METADATA:
LOG_DEBUG("Send Metadata"); LOG_DEBUG("Send device metadata");
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_metadata_tag; fromRadioScratch.which_payload_variant = meshtastic_FromRadio_metadata_tag;
fromRadioScratch.metadata = getDeviceMetadata(); fromRadioScratch.metadata = getDeviceMetadata();
state = STATE_SEND_CHANNELS; state = STATE_SEND_CHANNELS;
break; break;
case STATE_SEND_CHANNELS: case STATE_SEND_CHANNELS:
LOG_DEBUG("Send Channels");
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_channel_tag; fromRadioScratch.which_payload_variant = meshtastic_FromRadio_channel_tag;
fromRadioScratch.channel = channels.getByIndex(config_state); fromRadioScratch.channel = channels.getByIndex(config_state);
config_state++; config_state++;
// Advance when we have sent all of our Channels // Advance when we have sent all of our Channels
if (config_state >= MAX_NUM_CHANNELS) { if (config_state >= MAX_NUM_CHANNELS) {
LOG_DEBUG("Send channels %d", config_state);
state = STATE_SEND_CONFIG; state = STATE_SEND_CONFIG;
config_state = _meshtastic_AdminMessage_ConfigType_MIN + 1; config_state = _meshtastic_AdminMessage_ConfigType_MIN + 1;
} }
break; break;
case STATE_SEND_CONFIG: case STATE_SEND_CONFIG:
LOG_DEBUG("Send Radio config");
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_config_tag; fromRadioScratch.which_payload_variant = meshtastic_FromRadio_config_tag;
switch (config_state) { switch (config_state) {
case meshtastic_Config_device_tag: case meshtastic_Config_device_tag:
LOG_DEBUG("Send config: device");
fromRadioScratch.config.which_payload_variant = meshtastic_Config_device_tag; fromRadioScratch.config.which_payload_variant = meshtastic_Config_device_tag;
fromRadioScratch.config.payload_variant.device = config.device; fromRadioScratch.config.payload_variant.device = config.device;
break; break;
case meshtastic_Config_position_tag: case meshtastic_Config_position_tag:
LOG_DEBUG("Send config: position");
fromRadioScratch.config.which_payload_variant = meshtastic_Config_position_tag; fromRadioScratch.config.which_payload_variant = meshtastic_Config_position_tag;
fromRadioScratch.config.payload_variant.position = config.position; fromRadioScratch.config.payload_variant.position = config.position;
break; break;
case meshtastic_Config_power_tag: case meshtastic_Config_power_tag:
LOG_DEBUG("Send config: power");
fromRadioScratch.config.which_payload_variant = meshtastic_Config_power_tag; fromRadioScratch.config.which_payload_variant = meshtastic_Config_power_tag;
fromRadioScratch.config.payload_variant.power = config.power; fromRadioScratch.config.payload_variant.power = config.power;
fromRadioScratch.config.payload_variant.power.ls_secs = default_ls_secs; fromRadioScratch.config.payload_variant.power.ls_secs = default_ls_secs;
break; break;
case meshtastic_Config_network_tag: case meshtastic_Config_network_tag:
LOG_DEBUG("Send config: network");
fromRadioScratch.config.which_payload_variant = meshtastic_Config_network_tag; fromRadioScratch.config.which_payload_variant = meshtastic_Config_network_tag;
fromRadioScratch.config.payload_variant.network = config.network; fromRadioScratch.config.payload_variant.network = config.network;
break; break;
case meshtastic_Config_display_tag: case meshtastic_Config_display_tag:
LOG_DEBUG("Send config: display");
fromRadioScratch.config.which_payload_variant = meshtastic_Config_display_tag; fromRadioScratch.config.which_payload_variant = meshtastic_Config_display_tag;
fromRadioScratch.config.payload_variant.display = config.display; fromRadioScratch.config.payload_variant.display = config.display;
break; break;
case meshtastic_Config_lora_tag: case meshtastic_Config_lora_tag:
LOG_DEBUG("Send config: lora");
fromRadioScratch.config.which_payload_variant = meshtastic_Config_lora_tag; fromRadioScratch.config.which_payload_variant = meshtastic_Config_lora_tag;
fromRadioScratch.config.payload_variant.lora = config.lora; fromRadioScratch.config.payload_variant.lora = config.lora;
break; break;
case meshtastic_Config_bluetooth_tag: case meshtastic_Config_bluetooth_tag:
LOG_DEBUG("Send config: bluetooth");
fromRadioScratch.config.which_payload_variant = meshtastic_Config_bluetooth_tag; fromRadioScratch.config.which_payload_variant = meshtastic_Config_bluetooth_tag;
fromRadioScratch.config.payload_variant.bluetooth = config.bluetooth; fromRadioScratch.config.payload_variant.bluetooth = config.bluetooth;
break; break;
case meshtastic_Config_security_tag: case meshtastic_Config_security_tag:
LOG_DEBUG("Send config: security");
fromRadioScratch.config.which_payload_variant = meshtastic_Config_security_tag; fromRadioScratch.config.which_payload_variant = meshtastic_Config_security_tag;
fromRadioScratch.config.payload_variant.security = config.security; fromRadioScratch.config.payload_variant.security = config.security;
break; break;
case meshtastic_Config_sessionkey_tag: case meshtastic_Config_sessionkey_tag:
LOG_DEBUG("Send config: sessionkey");
fromRadioScratch.config.which_payload_variant = meshtastic_Config_sessionkey_tag; fromRadioScratch.config.which_payload_variant = meshtastic_Config_sessionkey_tag;
break; break;
default: default:
@@ -292,58 +300,70 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
break; break;
case STATE_SEND_MODULECONFIG: case STATE_SEND_MODULECONFIG:
LOG_DEBUG("Send Module Config");
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_moduleConfig_tag; fromRadioScratch.which_payload_variant = meshtastic_FromRadio_moduleConfig_tag;
switch (config_state) { switch (config_state) {
case meshtastic_ModuleConfig_mqtt_tag: case meshtastic_ModuleConfig_mqtt_tag:
LOG_DEBUG("Send module config: mqtt");
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_mqtt_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_mqtt_tag;
fromRadioScratch.moduleConfig.payload_variant.mqtt = moduleConfig.mqtt; fromRadioScratch.moduleConfig.payload_variant.mqtt = moduleConfig.mqtt;
break; break;
case meshtastic_ModuleConfig_serial_tag: case meshtastic_ModuleConfig_serial_tag:
LOG_DEBUG("Send module config: serial");
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_serial_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_serial_tag;
fromRadioScratch.moduleConfig.payload_variant.serial = moduleConfig.serial; fromRadioScratch.moduleConfig.payload_variant.serial = moduleConfig.serial;
break; break;
case meshtastic_ModuleConfig_external_notification_tag: case meshtastic_ModuleConfig_external_notification_tag:
LOG_DEBUG("Send module config: ext notification");
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_external_notification_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_external_notification_tag;
fromRadioScratch.moduleConfig.payload_variant.external_notification = moduleConfig.external_notification; fromRadioScratch.moduleConfig.payload_variant.external_notification = moduleConfig.external_notification;
break; break;
case meshtastic_ModuleConfig_store_forward_tag: case meshtastic_ModuleConfig_store_forward_tag:
LOG_DEBUG("Send module config: store forward");
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_store_forward_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_store_forward_tag;
fromRadioScratch.moduleConfig.payload_variant.store_forward = moduleConfig.store_forward; fromRadioScratch.moduleConfig.payload_variant.store_forward = moduleConfig.store_forward;
break; break;
case meshtastic_ModuleConfig_range_test_tag: case meshtastic_ModuleConfig_range_test_tag:
LOG_DEBUG("Send module config: range test");
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_range_test_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_range_test_tag;
fromRadioScratch.moduleConfig.payload_variant.range_test = moduleConfig.range_test; fromRadioScratch.moduleConfig.payload_variant.range_test = moduleConfig.range_test;
break; break;
case meshtastic_ModuleConfig_telemetry_tag: case meshtastic_ModuleConfig_telemetry_tag:
LOG_DEBUG("Send module config: telemetry");
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_telemetry_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_telemetry_tag;
fromRadioScratch.moduleConfig.payload_variant.telemetry = moduleConfig.telemetry; fromRadioScratch.moduleConfig.payload_variant.telemetry = moduleConfig.telemetry;
break; break;
case meshtastic_ModuleConfig_canned_message_tag: case meshtastic_ModuleConfig_canned_message_tag:
LOG_DEBUG("Send module config: canned message");
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_canned_message_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_canned_message_tag;
fromRadioScratch.moduleConfig.payload_variant.canned_message = moduleConfig.canned_message; fromRadioScratch.moduleConfig.payload_variant.canned_message = moduleConfig.canned_message;
break; break;
case meshtastic_ModuleConfig_audio_tag: case meshtastic_ModuleConfig_audio_tag:
LOG_DEBUG("Send module config: audio");
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_audio_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_audio_tag;
fromRadioScratch.moduleConfig.payload_variant.audio = moduleConfig.audio; fromRadioScratch.moduleConfig.payload_variant.audio = moduleConfig.audio;
break; break;
case meshtastic_ModuleConfig_remote_hardware_tag: case meshtastic_ModuleConfig_remote_hardware_tag:
LOG_DEBUG("Send module config: remote hardware");
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_remote_hardware_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_remote_hardware_tag;
fromRadioScratch.moduleConfig.payload_variant.remote_hardware = moduleConfig.remote_hardware; fromRadioScratch.moduleConfig.payload_variant.remote_hardware = moduleConfig.remote_hardware;
break; break;
case meshtastic_ModuleConfig_neighbor_info_tag: case meshtastic_ModuleConfig_neighbor_info_tag:
LOG_DEBUG("Send module config: neighbor info");
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_neighbor_info_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_neighbor_info_tag;
fromRadioScratch.moduleConfig.payload_variant.neighbor_info = moduleConfig.neighbor_info; fromRadioScratch.moduleConfig.payload_variant.neighbor_info = moduleConfig.neighbor_info;
break; break;
case meshtastic_ModuleConfig_detection_sensor_tag: case meshtastic_ModuleConfig_detection_sensor_tag:
LOG_DEBUG("Send module config: detection sensor");
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_detection_sensor_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_detection_sensor_tag;
fromRadioScratch.moduleConfig.payload_variant.detection_sensor = moduleConfig.detection_sensor; fromRadioScratch.moduleConfig.payload_variant.detection_sensor = moduleConfig.detection_sensor;
break; break;
case meshtastic_ModuleConfig_ambient_lighting_tag: case meshtastic_ModuleConfig_ambient_lighting_tag:
LOG_DEBUG("Send module config: ambient lighting");
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_ambient_lighting_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_ambient_lighting_tag;
fromRadioScratch.moduleConfig.payload_variant.ambient_lighting = moduleConfig.ambient_lighting; fromRadioScratch.moduleConfig.payload_variant.ambient_lighting = moduleConfig.ambient_lighting;
break; break;
case meshtastic_ModuleConfig_paxcounter_tag: case meshtastic_ModuleConfig_paxcounter_tag:
LOG_DEBUG("Send module config: paxcounter");
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_paxcounter_tag; fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_paxcounter_tag;
fromRadioScratch.moduleConfig.payload_variant.paxcounter = moduleConfig.paxcounter; fromRadioScratch.moduleConfig.payload_variant.paxcounter = moduleConfig.paxcounter;
break; break;
@@ -443,7 +463,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
return numbytes; return numbytes;
} }
LOG_DEBUG("no FromRadio packet available"); LOG_DEBUG("No FromRadio packet available");
return 0; return 0;
} }

View File

@@ -230,7 +230,7 @@ bool RF95Interface::reconfigure()
err = lora->setPreambleLength(preambleLength); err = lora->setPreambleLength(preambleLength);
if (err != RADIOLIB_ERR_NONE) if (err != RADIOLIB_ERR_NONE)
LOG_ERROR(" RF95 setPreambleLength %s%d", radioLibErr, err); LOG_ERROR("RF95 setPreambleLength %s%d", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE); assert(err == RADIOLIB_ERR_NONE);
err = lora->setFrequency(getFreq()); err = lora->setFrequency(getFreq());

View File

@@ -601,8 +601,6 @@ size_t RadioInterface::beginSending(meshtastic_MeshPacket *p)
// LOG_DEBUG("Send queued packet on mesh (txGood=%d,rxGood=%d,rxBad=%d)", rf95.txGood(), rf95.rxGood(), rf95.rxBad()); // LOG_DEBUG("Send queued packet on mesh (txGood=%d,rxGood=%d,rxBad=%d)", rf95.txGood(), rf95.rxGood(), rf95.rxBad());
assert(p->which_payload_variant == meshtastic_MeshPacket_encrypted_tag); // It should have already been encoded by now assert(p->which_payload_variant == meshtastic_MeshPacket_encrypted_tag); // It should have already been encoded by now
lastTxStart = millis();
radioBuffer.header.from = p->from; radioBuffer.header.from = p->from;
radioBuffer.header.to = p->to; radioBuffer.header.to = p->to;
radioBuffer.header.id = p->id; radioBuffer.header.id = p->id;

View File

@@ -278,7 +278,8 @@ void RadioLibInterface::onNotify(uint32_t notification)
startReceive(); // try receiving this packet, afterwards we'll be trying to transmit again startReceive(); // try receiving this packet, afterwards we'll be trying to transmit again
setTransmitDelay(); setTransmitDelay();
} else { } else {
// Send any outgoing packets we have ready // Send any outgoing packets we have ready as fast as possible to keep the time between channel scan and
// actual transmission as short as possible
meshtastic_MeshPacket *txp = txQueue.dequeue(); meshtastic_MeshPacket *txp = txQueue.dequeue();
assert(txp); assert(txp);
bool sent = startSend(txp); bool sent = startSend(txp);
@@ -470,7 +471,8 @@ void RadioLibInterface::setStandby()
/** start an immediate transmit */ /** start an immediate transmit */
bool RadioLibInterface::startSend(meshtastic_MeshPacket *txp) bool RadioLibInterface::startSend(meshtastic_MeshPacket *txp)
{ {
printPacket("Start low level send", txp); /* NOTE: Minimize the actions before startTransmit() to keep the time between
channel scan and actual transmit as low as possible to avoid collisions. */
if (disabled || !config.lora.tx_enabled) { if (disabled || !config.lora.tx_enabled) {
LOG_WARN("Drop Tx packet because LoRa Tx disabled"); LOG_WARN("Drop Tx packet because LoRa Tx disabled");
packetPool.release(txp); packetPool.release(txp);
@@ -489,6 +491,9 @@ bool RadioLibInterface::startSend(meshtastic_MeshPacket *txp)
completeSending(); completeSending();
powerMon->clearState(meshtastic_PowerMon_State_Lora_TXOn); // Transmitter off now powerMon->clearState(meshtastic_PowerMon_State_Lora_TXOn); // Transmitter off now
startReceive(); // Restart receive mode (because startTransmit failed to put us in xmit mode) startReceive(); // Restart receive mode (because startTransmit failed to put us in xmit mode)
} else {
lastTxStart = millis();
printPacket("Started Tx", txp);
} }
// Must be done AFTER, starting transmit, because startTransmit clears (possibly stale) interrupt pending register // Must be done AFTER, starting transmit, because startTransmit clears (possibly stale) interrupt pending register

View File

@@ -176,9 +176,9 @@ bool ReliableRouter::stopRetransmission(GlobalPacketId key)
if (old->numRetransmissions < NUM_RETRANSMISSIONS - 1) { if (old->numRetransmissions < NUM_RETRANSMISSIONS - 1) {
// remove the 'original' (identified by originator and packet->id) from the txqueue and free it // remove the 'original' (identified by originator and packet->id) from the txqueue and free it
cancelSending(getFrom(p), p->id); cancelSending(getFrom(p), p->id);
// now free the pooled copy for retransmission too
packetPool.release(p);
} }
// now free the pooled copy for retransmission too
packetPool.release(p);
auto numErased = pending.erase(key); auto numErased = pending.erase(key);
assert(numErased == 1); assert(numErased == 1);
return true; return true;

View File

@@ -4,8 +4,8 @@
#include "MeshRadio.h" #include "MeshRadio.h"
#include "MeshService.h" #include "MeshService.h"
#include "NodeDB.h" #include "NodeDB.h"
#include "RTC.h"
#include "configuration.h" #include "configuration.h"
#include "gps/RTC.h"
#include "main.h" #include "main.h"
#include "mesh-pb-constants.h" #include "mesh-pb-constants.h"
#include "meshUtils.h" #include "meshUtils.h"
@@ -187,9 +187,10 @@ ErrorCode Router::sendLocal(meshtastic_MeshPacket *p, RxSource src)
handleReceived(p, src); handleReceived(p, src);
} }
if (!p->channel && !p->pki_encrypted) { // don't override if a channel was requested // don't override if a channel was requested and no need to set it when PKI is enforced
if (!p->channel && !p->pki_encrypted) {
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(p->to); meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(p->to);
if (node && node->user.public_key.size == 0) { if (node) {
p->channel = node->channel; p->channel = node->channel;
LOG_DEBUG("localSend to channel %d", p->channel); LOG_DEBUG("localSend to channel %d", p->channel);
} }
@@ -489,7 +490,8 @@ meshtastic_Routing_Error perhapsEncode(meshtastic_MeshPacket *p)
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(p->to); meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(p->to);
// We may want to retool things so we can send a PKC packet when the client specifies a key and nodenum, even if the node // We may want to retool things so we can send a PKC packet when the client specifies a key and nodenum, even if the node
// is not in the local nodedb // is not in the local nodedb
if ( // First, only PKC encrypt packets we are originating
if (isFromUs(p) &&
// Don't use PKC with Ham mode // Don't use PKC with Ham mode
!owner.is_licensed && !owner.is_licensed &&
// Don't use PKC if it's not explicitly requested and a non-primary channel is requested // Don't use PKC if it's not explicitly requested and a non-primary channel is requested
@@ -649,6 +651,13 @@ void Router::perhapsHandleReceived(meshtastic_MeshPacket *p)
return; return;
} }
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(p->from);
if (node != NULL && node->is_ignored) {
LOG_DEBUG("Ignore msg, 0x%x is ignored", p->from);
packetPool.release(p);
return;
}
if (p->from == NODENUM_BROADCAST) { if (p->from == NODENUM_BROADCAST) {
LOG_DEBUG("Ignore msg from broadcast address"); LOG_DEBUG("Ignore msg from broadcast address");
packetPool.release(p); packetPool.release(p);
@@ -671,4 +680,4 @@ void Router::perhapsHandleReceived(meshtastic_MeshPacket *p)
// cache/learn of the existence of nodes (i.e. FloodRouter) that they should not // cache/learn of the existence of nodes (i.e. FloodRouter) that they should not
handleReceived(p); handleReceived(p);
packetPool.release(p); packetPool.release(p);
} }

View File

@@ -71,7 +71,7 @@ template <typename T> bool SX128xInterface<T>::init()
LOG_INFO("SX128x init result %d", res); LOG_INFO("SX128x init result %d", res);
if ((config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24) && (res == RADIOLIB_ERR_INVALID_FREQUENCY)) { if ((config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24) && (res == RADIOLIB_ERR_INVALID_FREQUENCY)) {
LOG_WARN("Radio chip only supports 2.4GHz LoRa. Adjusting Region and rebooting."); LOG_WARN("Radio only supports 2.4GHz LoRa. Adjusting Region and rebooting");
config.lora.region = meshtastic_Config_LoRaConfig_RegionCode_LORA_24; config.lora.region = meshtastic_Config_LoRaConfig_RegionCode_LORA_24;
nodeDB->saveToDisk(SEGMENT_CONFIG); nodeDB->saveToDisk(SEGMENT_CONFIG);
delay(2000); delay(2000);
@@ -80,7 +80,7 @@ template <typename T> bool SX128xInterface<T>::init()
#elif defined(ARCH_NRF52) #elif defined(ARCH_NRF52)
NVIC_SystemReset(); NVIC_SystemReset();
#else #else
LOG_ERROR("FIXME implement reboot for this platform. Skip for now."); LOG_ERROR("FIXME implement reboot for this platform. Skip for now");
#endif #endif
} }

View File

@@ -1,8 +1,7 @@
#include "StreamAPI.h" #include "StreamAPI.h"
#include "PowerFSM.h" #include "PowerFSM.h"
#include "RTC.h"
#include "Throttle.h" #include "Throttle.h"
#include "configuration.h" #include "gps/RTC.h"
#define START1 0x94 #define START1 0x94
#define START2 0xc3 #define START2 0xc3

View File

@@ -3,6 +3,7 @@
#include "PhoneAPI.h" #include "PhoneAPI.h"
#include "Stream.h" #include "Stream.h"
#include "concurrency/OSThread.h" #include "concurrency/OSThread.h"
#include <cstdarg>
// A To/FromRadio packet + our 32 bit header // A To/FromRadio packet + our 32 bit header
#define MAX_STREAM_BUF_SIZE (MAX_TO_FROM_RADIO_SIZE + sizeof(uint32_t)) #define MAX_STREAM_BUF_SIZE (MAX_TO_FROM_RADIO_SIZE + sizeof(uint32_t))

View File

@@ -12,6 +12,7 @@ meshtastic_NodeInfo TypeConversions::ConvertToNodeInfo(const meshtastic_NodeInfo
info.channel = lite->channel; info.channel = lite->channel;
info.via_mqtt = lite->via_mqtt; info.via_mqtt = lite->via_mqtt;
info.is_favorite = lite->is_favorite; info.is_favorite = lite->is_favorite;
info.is_ignored = lite->is_ignored;
if (lite->has_hops_away) { if (lite->has_hops_away) {
info.has_hops_away = true; info.has_hops_away = true;

View File

@@ -141,13 +141,13 @@ bool initEthernet()
if (status == 0) { if (status == 0) {
if (Ethernet.hardwareStatus() == EthernetNoHardware) { if (Ethernet.hardwareStatus() == EthernetNoHardware) {
LOG_ERROR("Ethernet shield was not found."); LOG_ERROR("Ethernet shield was not found");
return false; return false;
} else if (Ethernet.linkStatus() == LinkOFF) { } else if (Ethernet.linkStatus() == LinkOFF) {
LOG_ERROR("Ethernet cable is not connected."); LOG_ERROR("Ethernet cable is not connected");
return false; return false;
} else { } else {
LOG_ERROR("Unknown Ethernet error."); LOG_ERROR("Unknown Ethernet error");
return false; return false;
} }
} else { } else {

View File

@@ -180,6 +180,10 @@ typedef struct _meshtastic_AdminMessage {
meshtastic_DeviceUIConfig get_ui_config_response; meshtastic_DeviceUIConfig get_ui_config_response;
/* Tell the node to store UI data persistently. */ /* Tell the node to store UI data persistently. */
meshtastic_DeviceUIConfig store_ui_config; meshtastic_DeviceUIConfig store_ui_config;
/* Set specified node-num to be ignored on the NodeDB on the device */
uint32_t set_ignored_node;
/* Set specified node-num to be un-ignored on the NodeDB on the device */
uint32_t remove_ignored_node;
/* Begins an edit transaction for config, module config, owner, and channel settings changes /* Begins an edit transaction for config, module config, owner, and channel settings changes
This will delay the standard *implicit* save to the file system and subsequent reboot behavior until committed (commit_edit_settings) */ This will delay the standard *implicit* save to the file system and subsequent reboot behavior until committed (commit_edit_settings) */
bool begin_edit_settings; bool begin_edit_settings;
@@ -279,6 +283,8 @@ extern "C" {
#define meshtastic_AdminMessage_get_ui_config_request_tag 44 #define meshtastic_AdminMessage_get_ui_config_request_tag 44
#define meshtastic_AdminMessage_get_ui_config_response_tag 45 #define meshtastic_AdminMessage_get_ui_config_response_tag 45
#define meshtastic_AdminMessage_store_ui_config_tag 46 #define meshtastic_AdminMessage_store_ui_config_tag 46
#define meshtastic_AdminMessage_set_ignored_node_tag 47
#define meshtastic_AdminMessage_remove_ignored_node_tag 48
#define meshtastic_AdminMessage_begin_edit_settings_tag 64 #define meshtastic_AdminMessage_begin_edit_settings_tag 64
#define meshtastic_AdminMessage_commit_edit_settings_tag 65 #define meshtastic_AdminMessage_commit_edit_settings_tag 65
#define meshtastic_AdminMessage_factory_reset_device_tag 94 #define meshtastic_AdminMessage_factory_reset_device_tag 94
@@ -329,6 +335,8 @@ X(a, STATIC, ONEOF, FIXED32, (payload_variant,set_time_only,set_time_only)
X(a, STATIC, ONEOF, BOOL, (payload_variant,get_ui_config_request,get_ui_config_request), 44) \ X(a, STATIC, ONEOF, BOOL, (payload_variant,get_ui_config_request,get_ui_config_request), 44) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,get_ui_config_response,get_ui_config_response), 45) \ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,get_ui_config_response,get_ui_config_response), 45) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,store_ui_config,store_ui_config), 46) \ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,store_ui_config,store_ui_config), 46) \
X(a, STATIC, ONEOF, UINT32, (payload_variant,set_ignored_node,set_ignored_node), 47) \
X(a, STATIC, ONEOF, UINT32, (payload_variant,remove_ignored_node,remove_ignored_node), 48) \
X(a, STATIC, ONEOF, BOOL, (payload_variant,begin_edit_settings,begin_edit_settings), 64) \ X(a, STATIC, ONEOF, BOOL, (payload_variant,begin_edit_settings,begin_edit_settings), 64) \
X(a, STATIC, ONEOF, BOOL, (payload_variant,commit_edit_settings,commit_edit_settings), 65) \ X(a, STATIC, ONEOF, BOOL, (payload_variant,commit_edit_settings,commit_edit_settings), 65) \
X(a, STATIC, ONEOF, INT32, (payload_variant,factory_reset_device,factory_reset_device), 94) \ X(a, STATIC, ONEOF, INT32, (payload_variant,factory_reset_device,factory_reset_device), 94) \

View File

@@ -49,6 +49,8 @@ typedef enum _meshtastic_Language {
meshtastic_Language_DUTCH = 12, meshtastic_Language_DUTCH = 12,
/* Greek */ /* Greek */
meshtastic_Language_GREEK = 13, meshtastic_Language_GREEK = 13,
/* Norwegian */
meshtastic_Language_NORWEGIAN = 14,
/* Simplified Chinese (experimental) */ /* Simplified Chinese (experimental) */
meshtastic_Language_SIMPLIFIED_CHINESE = 30, meshtastic_Language_SIMPLIFIED_CHINESE = 30,
/* Traditional Chinese (experimental) */ /* Traditional Chinese (experimental) */
@@ -84,6 +86,7 @@ typedef struct _meshtastic_NodeHighlight {
char node_name[16]; char node_name[16];
} meshtastic_NodeHighlight; } meshtastic_NodeHighlight;
typedef PB_BYTES_ARRAY_T(16) meshtastic_DeviceUIConfig_calibration_data_t;
typedef struct _meshtastic_DeviceUIConfig { typedef struct _meshtastic_DeviceUIConfig {
/* A version integer used to invalidate saved files when we make incompatible changes. */ /* A version integer used to invalidate saved files when we make incompatible changes. */
uint32_t version; uint32_t version;
@@ -109,6 +112,8 @@ typedef struct _meshtastic_DeviceUIConfig {
/* Node list highlightening */ /* Node list highlightening */
bool has_node_highlight; bool has_node_highlight;
meshtastic_NodeHighlight node_highlight; meshtastic_NodeHighlight node_highlight;
/* 8 integers for screen calibration data */
meshtastic_DeviceUIConfig_calibration_data_t calibration_data;
} meshtastic_DeviceUIConfig; } meshtastic_DeviceUIConfig;
@@ -132,10 +137,10 @@ extern "C" {
/* Initializer values for message structs */ /* Initializer values for message structs */
#define meshtastic_DeviceUIConfig_init_default {0, 0, 0, 0, 0, 0, _meshtastic_Theme_MIN, 0, 0, 0, _meshtastic_Language_MIN, false, meshtastic_NodeFilter_init_default, false, meshtastic_NodeHighlight_init_default} #define meshtastic_DeviceUIConfig_init_default {0, 0, 0, 0, 0, 0, _meshtastic_Theme_MIN, 0, 0, 0, _meshtastic_Language_MIN, false, meshtastic_NodeFilter_init_default, false, meshtastic_NodeHighlight_init_default, {0, {0}}}
#define meshtastic_NodeFilter_init_default {0, 0, 0, 0, 0, ""} #define meshtastic_NodeFilter_init_default {0, 0, 0, 0, 0, ""}
#define meshtastic_NodeHighlight_init_default {0, 0, 0, 0, ""} #define meshtastic_NodeHighlight_init_default {0, 0, 0, 0, ""}
#define meshtastic_DeviceUIConfig_init_zero {0, 0, 0, 0, 0, 0, _meshtastic_Theme_MIN, 0, 0, 0, _meshtastic_Language_MIN, false, meshtastic_NodeFilter_init_zero, false, meshtastic_NodeHighlight_init_zero} #define meshtastic_DeviceUIConfig_init_zero {0, 0, 0, 0, 0, 0, _meshtastic_Theme_MIN, 0, 0, 0, _meshtastic_Language_MIN, false, meshtastic_NodeFilter_init_zero, false, meshtastic_NodeHighlight_init_zero, {0, {0}}}
#define meshtastic_NodeFilter_init_zero {0, 0, 0, 0, 0, ""} #define meshtastic_NodeFilter_init_zero {0, 0, 0, 0, 0, ""}
#define meshtastic_NodeHighlight_init_zero {0, 0, 0, 0, ""} #define meshtastic_NodeHighlight_init_zero {0, 0, 0, 0, ""}
@@ -164,6 +169,7 @@ extern "C" {
#define meshtastic_DeviceUIConfig_language_tag 11 #define meshtastic_DeviceUIConfig_language_tag 11
#define meshtastic_DeviceUIConfig_node_filter_tag 12 #define meshtastic_DeviceUIConfig_node_filter_tag 12
#define meshtastic_DeviceUIConfig_node_highlight_tag 13 #define meshtastic_DeviceUIConfig_node_highlight_tag 13
#define meshtastic_DeviceUIConfig_calibration_data_tag 14
/* Struct field encoding specification for nanopb */ /* Struct field encoding specification for nanopb */
#define meshtastic_DeviceUIConfig_FIELDLIST(X, a) \ #define meshtastic_DeviceUIConfig_FIELDLIST(X, a) \
@@ -179,7 +185,8 @@ X(a, STATIC, SINGULAR, BOOL, banner_enabled, 9) \
X(a, STATIC, SINGULAR, UINT32, ring_tone_id, 10) \ X(a, STATIC, SINGULAR, UINT32, ring_tone_id, 10) \
X(a, STATIC, SINGULAR, UENUM, language, 11) \ X(a, STATIC, SINGULAR, UENUM, language, 11) \
X(a, STATIC, OPTIONAL, MESSAGE, node_filter, 12) \ X(a, STATIC, OPTIONAL, MESSAGE, node_filter, 12) \
X(a, STATIC, OPTIONAL, MESSAGE, node_highlight, 13) X(a, STATIC, OPTIONAL, MESSAGE, node_highlight, 13) \
X(a, STATIC, SINGULAR, BYTES, calibration_data, 14)
#define meshtastic_DeviceUIConfig_CALLBACK NULL #define meshtastic_DeviceUIConfig_CALLBACK NULL
#define meshtastic_DeviceUIConfig_DEFAULT NULL #define meshtastic_DeviceUIConfig_DEFAULT NULL
#define meshtastic_DeviceUIConfig_node_filter_MSGTYPE meshtastic_NodeFilter #define meshtastic_DeviceUIConfig_node_filter_MSGTYPE meshtastic_NodeFilter
@@ -215,7 +222,7 @@ extern const pb_msgdesc_t meshtastic_NodeHighlight_msg;
/* Maximum encoded size of messages (where known) */ /* Maximum encoded size of messages (where known) */
#define MESHTASTIC_MESHTASTIC_DEVICE_UI_PB_H_MAX_SIZE meshtastic_DeviceUIConfig_size #define MESHTASTIC_MESHTASTIC_DEVICE_UI_PB_H_MAX_SIZE meshtastic_DeviceUIConfig_size
#define meshtastic_DeviceUIConfig_size 99 #define meshtastic_DeviceUIConfig_size 117
#define meshtastic_NodeFilter_size 36 #define meshtastic_NodeFilter_size 36
#define meshtastic_NodeHighlight_size 25 #define meshtastic_NodeHighlight_size 25

View File

@@ -81,12 +81,17 @@ typedef struct _meshtastic_NodeInfoLite {
uint8_t channel; uint8_t channel;
/* True if we witnessed the node over MQTT instead of LoRA transport */ /* True if we witnessed the node over MQTT instead of LoRA transport */
bool via_mqtt; bool via_mqtt;
/* Number of hops away from us this node is (0 if adjacent) */ /* Number of hops away from us this node is (0 if direct neighbor) */
bool has_hops_away; bool has_hops_away;
uint8_t hops_away; uint8_t hops_away;
/* True if node is in our favorites list /* True if node is in our favorites list
Persists between NodeDB internal clean ups */ Persists between NodeDB internal clean ups */
bool is_favorite; bool is_favorite;
/* True if node is in our ignored list
Persists between NodeDB internal clean ups */
bool is_ignored;
/* Last byte of the node number of the node that should be used as the next hop to reach this node. */
uint8_t next_hop;
} meshtastic_NodeInfoLite; } meshtastic_NodeInfoLite;
/* This message is never sent over the wire, but it is used for serializing DB /* This message is never sent over the wire, but it is used for serializing DB
@@ -150,12 +155,12 @@ extern "C" {
/* Initializer values for message structs */ /* Initializer values for message structs */
#define meshtastic_PositionLite_init_default {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN} #define meshtastic_PositionLite_init_default {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN}
#define meshtastic_UserLite_init_default {{0}, "", "", _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}} #define meshtastic_UserLite_init_default {{0}, "", "", _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}}
#define meshtastic_NodeInfoLite_init_default {0, false, meshtastic_UserLite_init_default, false, meshtastic_PositionLite_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0, 0, false, 0, 0} #define meshtastic_NodeInfoLite_init_default {0, false, meshtastic_UserLite_init_default, false, meshtastic_PositionLite_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0, 0, false, 0, 0, 0, 0}
#define meshtastic_DeviceState_init_default {false, meshtastic_MyNodeInfo_init_default, false, meshtastic_User_init_default, 0, {meshtastic_MeshPacket_init_default}, false, meshtastic_MeshPacket_init_default, 0, 0, 0, false, meshtastic_MeshPacket_init_default, 0, {meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default}, {0}} #define meshtastic_DeviceState_init_default {false, meshtastic_MyNodeInfo_init_default, false, meshtastic_User_init_default, 0, {meshtastic_MeshPacket_init_default}, false, meshtastic_MeshPacket_init_default, 0, 0, 0, false, meshtastic_MeshPacket_init_default, 0, {meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default}, {0}}
#define meshtastic_ChannelFile_init_default {0, {meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default}, 0} #define meshtastic_ChannelFile_init_default {0, {meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default}, 0}
#define meshtastic_PositionLite_init_zero {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN} #define meshtastic_PositionLite_init_zero {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN}
#define meshtastic_UserLite_init_zero {{0}, "", "", _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}} #define meshtastic_UserLite_init_zero {{0}, "", "", _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}}
#define meshtastic_NodeInfoLite_init_zero {0, false, meshtastic_UserLite_init_zero, false, meshtastic_PositionLite_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0, 0, false, 0, 0} #define meshtastic_NodeInfoLite_init_zero {0, false, meshtastic_UserLite_init_zero, false, meshtastic_PositionLite_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0, 0, false, 0, 0, 0, 0}
#define meshtastic_DeviceState_init_zero {false, meshtastic_MyNodeInfo_init_zero, false, meshtastic_User_init_zero, 0, {meshtastic_MeshPacket_init_zero}, false, meshtastic_MeshPacket_init_zero, 0, 0, 0, false, meshtastic_MeshPacket_init_zero, 0, {meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero}, {0}} #define meshtastic_DeviceState_init_zero {false, meshtastic_MyNodeInfo_init_zero, false, meshtastic_User_init_zero, 0, {meshtastic_MeshPacket_init_zero}, false, meshtastic_MeshPacket_init_zero, 0, 0, 0, false, meshtastic_MeshPacket_init_zero, 0, {meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero}, {0}}
#define meshtastic_ChannelFile_init_zero {0, {meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero}, 0} #define meshtastic_ChannelFile_init_zero {0, {meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero}, 0}
@@ -182,6 +187,8 @@ extern "C" {
#define meshtastic_NodeInfoLite_via_mqtt_tag 8 #define meshtastic_NodeInfoLite_via_mqtt_tag 8
#define meshtastic_NodeInfoLite_hops_away_tag 9 #define meshtastic_NodeInfoLite_hops_away_tag 9
#define meshtastic_NodeInfoLite_is_favorite_tag 10 #define meshtastic_NodeInfoLite_is_favorite_tag 10
#define meshtastic_NodeInfoLite_is_ignored_tag 11
#define meshtastic_NodeInfoLite_next_hop_tag 12
#define meshtastic_DeviceState_my_node_tag 2 #define meshtastic_DeviceState_my_node_tag 2
#define meshtastic_DeviceState_owner_tag 3 #define meshtastic_DeviceState_owner_tag 3
#define meshtastic_DeviceState_receive_queue_tag 5 #define meshtastic_DeviceState_receive_queue_tag 5
@@ -226,7 +233,9 @@ X(a, STATIC, OPTIONAL, MESSAGE, device_metrics, 6) \
X(a, STATIC, SINGULAR, UINT32, channel, 7) \ X(a, STATIC, SINGULAR, UINT32, channel, 7) \
X(a, STATIC, SINGULAR, BOOL, via_mqtt, 8) \ X(a, STATIC, SINGULAR, BOOL, via_mqtt, 8) \
X(a, STATIC, OPTIONAL, UINT32, hops_away, 9) \ X(a, STATIC, OPTIONAL, UINT32, hops_away, 9) \
X(a, STATIC, SINGULAR, BOOL, is_favorite, 10) X(a, STATIC, SINGULAR, BOOL, is_favorite, 10) \
X(a, STATIC, SINGULAR, BOOL, is_ignored, 11) \
X(a, STATIC, SINGULAR, UINT32, next_hop, 12)
#define meshtastic_NodeInfoLite_CALLBACK NULL #define meshtastic_NodeInfoLite_CALLBACK NULL
#define meshtastic_NodeInfoLite_DEFAULT NULL #define meshtastic_NodeInfoLite_DEFAULT NULL
#define meshtastic_NodeInfoLite_user_MSGTYPE meshtastic_UserLite #define meshtastic_NodeInfoLite_user_MSGTYPE meshtastic_UserLite
@@ -279,7 +288,7 @@ extern const pb_msgdesc_t meshtastic_ChannelFile_msg;
/* meshtastic_DeviceState_size depends on runtime parameters */ /* meshtastic_DeviceState_size depends on runtime parameters */
#define MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_MAX_SIZE meshtastic_ChannelFile_size #define MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_MAX_SIZE meshtastic_ChannelFile_size
#define meshtastic_ChannelFile_size 718 #define meshtastic_ChannelFile_size 718
#define meshtastic_NodeInfoLite_size 183 #define meshtastic_NodeInfoLite_size 188
#define meshtastic_PositionLite_size 28 #define meshtastic_PositionLite_size 28
#define meshtastic_UserLite_size 96 #define meshtastic_UserLite_size 96

View File

@@ -188,7 +188,7 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg;
/* Maximum encoded size of messages (where known) */ /* Maximum encoded size of messages (where known) */
#define MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_MAX_SIZE meshtastic_LocalConfig_size #define MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_MAX_SIZE meshtastic_LocalConfig_size
#define meshtastic_LocalConfig_size 735 #define meshtastic_LocalConfig_size 735
#define meshtastic_LocalModuleConfig_size 697 #define meshtastic_LocalModuleConfig_size 699
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */

View File

@@ -212,6 +212,9 @@ typedef enum _meshtastic_HardwareModel {
meshtastic_HardwareModel_MS24SF1 = 82, meshtastic_HardwareModel_MS24SF1 = 82,
/* Lilygo TLora-C6 with the new ESP32-C6 MCU */ /* Lilygo TLora-C6 with the new ESP32-C6 MCU */
meshtastic_HardwareModel_TLORA_C6 = 83, meshtastic_HardwareModel_TLORA_C6 = 83,
/* WisMesh Tap
RAK-4631 w/ TFT in injection modled case */
meshtastic_HardwareModel_WISMESH_TAP = 84,
/* ------------------------------------------------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------------------------------------------------
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. 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.
------------------------------------------------------------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------------------------------------------------------------ */
@@ -720,7 +723,7 @@ typedef struct _meshtastic_MeshPacket {
Set during reception to indicate the SNR of this packet. Set during reception to indicate the SNR of this packet.
Used to collect statistics on current link quality. */ Used to collect statistics on current link quality. */
float rx_snr; float rx_snr;
/* If unset treated as zero (no forwarding, send to adjacent nodes only) /* If unset treated as zero (no forwarding, send to direct neighbor nodes only)
if 1, allow hopping through one node, etc... if 1, allow hopping through one node, etc...
For our usecase real world topologies probably have a max of about 3. 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. */ This field is normally placed into a few of bits in the header. */
@@ -751,6 +754,12 @@ typedef struct _meshtastic_MeshPacket {
meshtastic_MeshPacket_public_key_t public_key; meshtastic_MeshPacket_public_key_t public_key;
/* Indicates whether the packet was en/decrypted using PKI */ /* Indicates whether the packet was en/decrypted using PKI */
bool pki_encrypted; bool pki_encrypted;
/* Last byte of the node number of the node that should be used as the next hop in routing.
Set by the firmware internally, clients are not supposed to set this. */
uint8_t next_hop;
/* Last byte of the node number of the node that will relay/relayed this packet.
Set by the firmware internally, clients are not supposed to set this. */
uint8_t relay_node;
} meshtastic_MeshPacket; } meshtastic_MeshPacket;
/* The bluetooth to device link: /* The bluetooth to device link:
@@ -791,12 +800,15 @@ typedef struct _meshtastic_NodeInfo {
uint8_t channel; uint8_t channel;
/* True if we witnessed the node over MQTT instead of LoRA transport */ /* True if we witnessed the node over MQTT instead of LoRA transport */
bool via_mqtt; bool via_mqtt;
/* Number of hops away from us this node is (0 if adjacent) */ /* Number of hops away from us this node is (0 if direct neighbor) */
bool has_hops_away; bool has_hops_away;
uint8_t hops_away; uint8_t hops_away;
/* True if node is in our favorites list /* True if node is in our favorites list
Persists between NodeDB internal clean ups */ Persists between NodeDB internal clean ups */
bool is_favorite; bool is_favorite;
/* True if node is in our ignored list
Persists between NodeDB internal clean ups */
bool is_ignored;
} meshtastic_NodeInfo; } meshtastic_NodeInfo;
typedef PB_BYTES_ARRAY_T(16) meshtastic_MyNodeInfo_device_id_t; typedef PB_BYTES_ARRAY_T(16) meshtastic_MyNodeInfo_device_id_t;
@@ -1156,8 +1168,8 @@ extern "C" {
#define meshtastic_Data_init_default {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0} #define meshtastic_Data_init_default {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0}
#define meshtastic_Waypoint_init_default {0, false, 0, false, 0, 0, 0, "", "", 0} #define meshtastic_Waypoint_init_default {0, false, 0, false, 0, 0, 0, "", "", 0}
#define meshtastic_MqttClientProxyMessage_init_default {"", 0, {{0, {0}}}, 0} #define meshtastic_MqttClientProxyMessage_init_default {"", 0, {{0, {0}}}, 0}
#define meshtastic_MeshPacket_init_default {0, 0, 0, 0, {meshtastic_Data_init_default}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0} #define meshtastic_MeshPacket_init_default {0, 0, 0, 0, {meshtastic_Data_init_default}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0, 0, 0}
#define meshtastic_NodeInfo_init_default {0, false, meshtastic_User_init_default, false, meshtastic_Position_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0, 0, false, 0, 0} #define meshtastic_NodeInfo_init_default {0, false, meshtastic_User_init_default, false, meshtastic_Position_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0, 0, false, 0, 0, 0}
#define meshtastic_MyNodeInfo_init_default {0, 0, 0, {0, {0}}, ""} #define meshtastic_MyNodeInfo_init_default {0, 0, 0, {0, {0}}, ""}
#define meshtastic_LogRecord_init_default {"", 0, "", _meshtastic_LogRecord_Level_MIN} #define meshtastic_LogRecord_init_default {"", 0, "", _meshtastic_LogRecord_Level_MIN}
#define meshtastic_QueueStatus_init_default {0, 0, 0, 0} #define meshtastic_QueueStatus_init_default {0, 0, 0, 0}
@@ -1181,8 +1193,8 @@ extern "C" {
#define meshtastic_Data_init_zero {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0} #define meshtastic_Data_init_zero {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0}
#define meshtastic_Waypoint_init_zero {0, false, 0, false, 0, 0, 0, "", "", 0} #define meshtastic_Waypoint_init_zero {0, false, 0, false, 0, 0, 0, "", "", 0}
#define meshtastic_MqttClientProxyMessage_init_zero {"", 0, {{0, {0}}}, 0} #define meshtastic_MqttClientProxyMessage_init_zero {"", 0, {{0, {0}}}, 0}
#define meshtastic_MeshPacket_init_zero {0, 0, 0, 0, {meshtastic_Data_init_zero}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0} #define meshtastic_MeshPacket_init_zero {0, 0, 0, 0, {meshtastic_Data_init_zero}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0, 0, 0}
#define meshtastic_NodeInfo_init_zero {0, false, meshtastic_User_init_zero, false, meshtastic_Position_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0, 0, false, 0, 0} #define meshtastic_NodeInfo_init_zero {0, false, meshtastic_User_init_zero, false, meshtastic_Position_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0, 0, false, 0, 0, 0}
#define meshtastic_MyNodeInfo_init_zero {0, 0, 0, {0, {0}}, ""} #define meshtastic_MyNodeInfo_init_zero {0, 0, 0, {0, {0}}, ""}
#define meshtastic_LogRecord_init_zero {"", 0, "", _meshtastic_LogRecord_Level_MIN} #define meshtastic_LogRecord_init_zero {"", 0, "", _meshtastic_LogRecord_Level_MIN}
#define meshtastic_QueueStatus_init_zero {0, 0, 0, 0} #define meshtastic_QueueStatus_init_zero {0, 0, 0, 0}
@@ -1277,6 +1289,8 @@ extern "C" {
#define meshtastic_MeshPacket_hop_start_tag 15 #define meshtastic_MeshPacket_hop_start_tag 15
#define meshtastic_MeshPacket_public_key_tag 16 #define meshtastic_MeshPacket_public_key_tag 16
#define meshtastic_MeshPacket_pki_encrypted_tag 17 #define meshtastic_MeshPacket_pki_encrypted_tag 17
#define meshtastic_MeshPacket_next_hop_tag 18
#define meshtastic_MeshPacket_relay_node_tag 19
#define meshtastic_NodeInfo_num_tag 1 #define meshtastic_NodeInfo_num_tag 1
#define meshtastic_NodeInfo_user_tag 2 #define meshtastic_NodeInfo_user_tag 2
#define meshtastic_NodeInfo_position_tag 3 #define meshtastic_NodeInfo_position_tag 3
@@ -1287,6 +1301,7 @@ extern "C" {
#define meshtastic_NodeInfo_via_mqtt_tag 8 #define meshtastic_NodeInfo_via_mqtt_tag 8
#define meshtastic_NodeInfo_hops_away_tag 9 #define meshtastic_NodeInfo_hops_away_tag 9
#define meshtastic_NodeInfo_is_favorite_tag 10 #define meshtastic_NodeInfo_is_favorite_tag 10
#define meshtastic_NodeInfo_is_ignored_tag 11
#define meshtastic_MyNodeInfo_my_node_num_tag 1 #define meshtastic_MyNodeInfo_my_node_num_tag 1
#define meshtastic_MyNodeInfo_reboot_count_tag 8 #define meshtastic_MyNodeInfo_reboot_count_tag 8
#define meshtastic_MyNodeInfo_min_app_version_tag 11 #define meshtastic_MyNodeInfo_min_app_version_tag 11
@@ -1470,7 +1485,9 @@ X(a, STATIC, SINGULAR, UENUM, delayed, 13) \
X(a, STATIC, SINGULAR, BOOL, via_mqtt, 14) \ X(a, STATIC, SINGULAR, BOOL, via_mqtt, 14) \
X(a, STATIC, SINGULAR, UINT32, hop_start, 15) \ X(a, STATIC, SINGULAR, UINT32, hop_start, 15) \
X(a, STATIC, SINGULAR, BYTES, public_key, 16) \ X(a, STATIC, SINGULAR, BYTES, public_key, 16) \
X(a, STATIC, SINGULAR, BOOL, pki_encrypted, 17) X(a, STATIC, SINGULAR, BOOL, pki_encrypted, 17) \
X(a, STATIC, SINGULAR, UINT32, next_hop, 18) \
X(a, STATIC, SINGULAR, UINT32, relay_node, 19)
#define meshtastic_MeshPacket_CALLBACK NULL #define meshtastic_MeshPacket_CALLBACK NULL
#define meshtastic_MeshPacket_DEFAULT NULL #define meshtastic_MeshPacket_DEFAULT NULL
#define meshtastic_MeshPacket_payload_variant_decoded_MSGTYPE meshtastic_Data #define meshtastic_MeshPacket_payload_variant_decoded_MSGTYPE meshtastic_Data
@@ -1485,7 +1502,8 @@ X(a, STATIC, OPTIONAL, MESSAGE, device_metrics, 6) \
X(a, STATIC, SINGULAR, UINT32, channel, 7) \ X(a, STATIC, SINGULAR, UINT32, channel, 7) \
X(a, STATIC, SINGULAR, BOOL, via_mqtt, 8) \ X(a, STATIC, SINGULAR, BOOL, via_mqtt, 8) \
X(a, STATIC, OPTIONAL, UINT32, hops_away, 9) \ X(a, STATIC, OPTIONAL, UINT32, hops_away, 9) \
X(a, STATIC, SINGULAR, BOOL, is_favorite, 10) X(a, STATIC, SINGULAR, BOOL, is_favorite, 10) \
X(a, STATIC, SINGULAR, BOOL, is_ignored, 11)
#define meshtastic_NodeInfo_CALLBACK NULL #define meshtastic_NodeInfo_CALLBACK NULL
#define meshtastic_NodeInfo_DEFAULT NULL #define meshtastic_NodeInfo_DEFAULT NULL
#define meshtastic_NodeInfo_user_MSGTYPE meshtastic_User #define meshtastic_NodeInfo_user_MSGTYPE meshtastic_User
@@ -1719,12 +1737,12 @@ extern const pb_msgdesc_t meshtastic_ChunkedPayloadResponse_msg;
#define meshtastic_FromRadio_size 510 #define meshtastic_FromRadio_size 510
#define meshtastic_Heartbeat_size 0 #define meshtastic_Heartbeat_size 0
#define meshtastic_LogRecord_size 426 #define meshtastic_LogRecord_size 426
#define meshtastic_MeshPacket_size 367 #define meshtastic_MeshPacket_size 375
#define meshtastic_MqttClientProxyMessage_size 501 #define meshtastic_MqttClientProxyMessage_size 501
#define meshtastic_MyNodeInfo_size 77 #define meshtastic_MyNodeInfo_size 77
#define meshtastic_NeighborInfo_size 258 #define meshtastic_NeighborInfo_size 258
#define meshtastic_Neighbor_size 22 #define meshtastic_Neighbor_size 22
#define meshtastic_NodeInfo_size 317 #define meshtastic_NodeInfo_size 319
#define meshtastic_NodeRemoteHardwarePin_size 29 #define meshtastic_NodeRemoteHardwarePin_size 29
#define meshtastic_Position_size 144 #define meshtastic_Position_size 144
#define meshtastic_QueueStatus_size 23 #define meshtastic_QueueStatus_size 23

View File

@@ -153,8 +153,11 @@ typedef struct _meshtastic_ModuleConfig_NeighborInfoConfig {
/* Whether the Module is enabled */ /* Whether the Module is enabled */
bool enabled; bool enabled;
/* Interval in seconds of how often we should try to send our /* Interval in seconds of how often we should try to send our
Neighbor Info to the mesh */ Neighbor Info (minimum is 14400, i.e., 4 hours) */
uint32_t update_interval; uint32_t update_interval;
/* Whether in addition to sending it to MQTT and the PhoneAPI, our NeighborInfo should be transmitted over LoRa.
Note that this is not available on a channel with default key and name. */
bool transmit_over_lora;
} meshtastic_ModuleConfig_NeighborInfoConfig; } meshtastic_ModuleConfig_NeighborInfoConfig;
/* Detection Sensor Module Config */ /* Detection Sensor Module Config */
@@ -501,7 +504,7 @@ extern "C" {
#define meshtastic_ModuleConfig_MQTTConfig_init_default {0, "", "", "", 0, 0, 0, "", 0, 0, false, meshtastic_ModuleConfig_MapReportSettings_init_default} #define meshtastic_ModuleConfig_MQTTConfig_init_default {0, "", "", "", 0, 0, 0, "", 0, 0, false, meshtastic_ModuleConfig_MapReportSettings_init_default}
#define meshtastic_ModuleConfig_MapReportSettings_init_default {0, 0} #define meshtastic_ModuleConfig_MapReportSettings_init_default {0, 0}
#define meshtastic_ModuleConfig_RemoteHardwareConfig_init_default {0, 0, 0, {meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default}} #define meshtastic_ModuleConfig_RemoteHardwareConfig_init_default {0, 0, 0, {meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default}}
#define meshtastic_ModuleConfig_NeighborInfoConfig_init_default {0, 0} #define meshtastic_ModuleConfig_NeighborInfoConfig_init_default {0, 0, 0}
#define meshtastic_ModuleConfig_DetectionSensorConfig_init_default {0, 0, 0, 0, "", 0, _meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_MIN, 0} #define meshtastic_ModuleConfig_DetectionSensorConfig_init_default {0, 0, 0, 0, "", 0, _meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_MIN, 0}
#define meshtastic_ModuleConfig_AudioConfig_init_default {0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0} #define meshtastic_ModuleConfig_AudioConfig_init_default {0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0}
#define meshtastic_ModuleConfig_PaxcounterConfig_init_default {0, 0, 0, 0} #define meshtastic_ModuleConfig_PaxcounterConfig_init_default {0, 0, 0, 0}
@@ -517,7 +520,7 @@ extern "C" {
#define meshtastic_ModuleConfig_MQTTConfig_init_zero {0, "", "", "", 0, 0, 0, "", 0, 0, false, meshtastic_ModuleConfig_MapReportSettings_init_zero} #define meshtastic_ModuleConfig_MQTTConfig_init_zero {0, "", "", "", 0, 0, 0, "", 0, 0, false, meshtastic_ModuleConfig_MapReportSettings_init_zero}
#define meshtastic_ModuleConfig_MapReportSettings_init_zero {0, 0} #define meshtastic_ModuleConfig_MapReportSettings_init_zero {0, 0}
#define meshtastic_ModuleConfig_RemoteHardwareConfig_init_zero {0, 0, 0, {meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero}} #define meshtastic_ModuleConfig_RemoteHardwareConfig_init_zero {0, 0, 0, {meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero}}
#define meshtastic_ModuleConfig_NeighborInfoConfig_init_zero {0, 0} #define meshtastic_ModuleConfig_NeighborInfoConfig_init_zero {0, 0, 0}
#define meshtastic_ModuleConfig_DetectionSensorConfig_init_zero {0, 0, 0, 0, "", 0, _meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_MIN, 0} #define meshtastic_ModuleConfig_DetectionSensorConfig_init_zero {0, 0, 0, 0, "", 0, _meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_MIN, 0}
#define meshtastic_ModuleConfig_AudioConfig_init_zero {0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0} #define meshtastic_ModuleConfig_AudioConfig_init_zero {0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0}
#define meshtastic_ModuleConfig_PaxcounterConfig_init_zero {0, 0, 0, 0} #define meshtastic_ModuleConfig_PaxcounterConfig_init_zero {0, 0, 0, 0}
@@ -546,6 +549,7 @@ extern "C" {
#define meshtastic_ModuleConfig_MQTTConfig_map_report_settings_tag 11 #define meshtastic_ModuleConfig_MQTTConfig_map_report_settings_tag 11
#define meshtastic_ModuleConfig_NeighborInfoConfig_enabled_tag 1 #define meshtastic_ModuleConfig_NeighborInfoConfig_enabled_tag 1
#define meshtastic_ModuleConfig_NeighborInfoConfig_update_interval_tag 2 #define meshtastic_ModuleConfig_NeighborInfoConfig_update_interval_tag 2
#define meshtastic_ModuleConfig_NeighborInfoConfig_transmit_over_lora_tag 3
#define meshtastic_ModuleConfig_DetectionSensorConfig_enabled_tag 1 #define meshtastic_ModuleConfig_DetectionSensorConfig_enabled_tag 1
#define meshtastic_ModuleConfig_DetectionSensorConfig_minimum_broadcast_secs_tag 2 #define meshtastic_ModuleConfig_DetectionSensorConfig_minimum_broadcast_secs_tag 2
#define meshtastic_ModuleConfig_DetectionSensorConfig_state_broadcast_secs_tag 3 #define meshtastic_ModuleConfig_DetectionSensorConfig_state_broadcast_secs_tag 3
@@ -709,7 +713,8 @@ X(a, STATIC, REPEATED, MESSAGE, available_pins, 3)
#define meshtastic_ModuleConfig_NeighborInfoConfig_FIELDLIST(X, a) \ #define meshtastic_ModuleConfig_NeighborInfoConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, BOOL, enabled, 1) \ X(a, STATIC, SINGULAR, BOOL, enabled, 1) \
X(a, STATIC, SINGULAR, UINT32, update_interval, 2) X(a, STATIC, SINGULAR, UINT32, update_interval, 2) \
X(a, STATIC, SINGULAR, BOOL, transmit_over_lora, 3)
#define meshtastic_ModuleConfig_NeighborInfoConfig_CALLBACK NULL #define meshtastic_ModuleConfig_NeighborInfoConfig_CALLBACK NULL
#define meshtastic_ModuleConfig_NeighborInfoConfig_DEFAULT NULL #define meshtastic_ModuleConfig_NeighborInfoConfig_DEFAULT NULL
@@ -884,7 +889,7 @@ extern const pb_msgdesc_t meshtastic_RemoteHardwarePin_msg;
#define meshtastic_ModuleConfig_ExternalNotificationConfig_size 42 #define meshtastic_ModuleConfig_ExternalNotificationConfig_size 42
#define meshtastic_ModuleConfig_MQTTConfig_size 254 #define meshtastic_ModuleConfig_MQTTConfig_size 254
#define meshtastic_ModuleConfig_MapReportSettings_size 12 #define meshtastic_ModuleConfig_MapReportSettings_size 12
#define meshtastic_ModuleConfig_NeighborInfoConfig_size 8 #define meshtastic_ModuleConfig_NeighborInfoConfig_size 10
#define meshtastic_ModuleConfig_PaxcounterConfig_size 30 #define meshtastic_ModuleConfig_PaxcounterConfig_size 30
#define meshtastic_ModuleConfig_RangeTestConfig_size 10 #define meshtastic_ModuleConfig_RangeTestConfig_size 10
#define meshtastic_ModuleConfig_RemoteHardwareConfig_size 96 #define meshtastic_ModuleConfig_RemoteHardwareConfig_size 96

View File

@@ -77,7 +77,9 @@ typedef enum _meshtastic_TelemetrySensorType {
/* MLX90614 non-contact IR temperature sensor */ /* MLX90614 non-contact IR temperature sensor */
meshtastic_TelemetrySensorType_MLX90614 = 31, meshtastic_TelemetrySensorType_MLX90614 = 31,
/* SCD40/SCD41 CO2, humidity, temperature sensor */ /* SCD40/SCD41 CO2, humidity, temperature sensor */
meshtastic_TelemetrySensorType_SCD4X = 32 meshtastic_TelemetrySensorType_SCD4X = 32,
/* ClimateGuard RadSens, radiation, Geiger-Muller Tube */
meshtastic_TelemetrySensorType_RADSENS = 33
} meshtastic_TelemetrySensorType; } meshtastic_TelemetrySensorType;
/* Struct definitions */ /* Struct definitions */
@@ -155,6 +157,9 @@ typedef struct _meshtastic_EnvironmentMetrics {
/* Wind lull in m/s */ /* Wind lull in m/s */
bool has_wind_lull; bool has_wind_lull;
float wind_lull; float wind_lull;
/* Radiation in µR/h */
bool has_radiation;
float radiation;
} meshtastic_EnvironmentMetrics; } meshtastic_EnvironmentMetrics;
/* Power Metrics (voltage / current / etc) */ /* Power Metrics (voltage / current / etc) */
@@ -299,8 +304,8 @@ extern "C" {
/* Helper constants for enums */ /* Helper constants for enums */
#define _meshtastic_TelemetrySensorType_MIN meshtastic_TelemetrySensorType_SENSOR_UNSET #define _meshtastic_TelemetrySensorType_MIN meshtastic_TelemetrySensorType_SENSOR_UNSET
#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_SCD4X #define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_RADSENS
#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_SCD4X+1)) #define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_RADSENS+1))
@@ -313,7 +318,7 @@ extern "C" {
/* Initializer values for message structs */ /* Initializer values for message structs */
#define meshtastic_DeviceMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0} #define meshtastic_DeviceMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_EnvironmentMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0} #define meshtastic_EnvironmentMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_PowerMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0} #define meshtastic_PowerMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_AirQualityMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0} #define meshtastic_AirQualityMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_LocalStats_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} #define meshtastic_LocalStats_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
@@ -321,7 +326,7 @@ extern "C" {
#define meshtastic_Telemetry_init_default {0, 0, {meshtastic_DeviceMetrics_init_default}} #define meshtastic_Telemetry_init_default {0, 0, {meshtastic_DeviceMetrics_init_default}}
#define meshtastic_Nau7802Config_init_default {0, 0} #define meshtastic_Nau7802Config_init_default {0, 0}
#define meshtastic_DeviceMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0} #define meshtastic_DeviceMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_EnvironmentMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0} #define meshtastic_EnvironmentMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_PowerMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0} #define meshtastic_PowerMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_AirQualityMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0} #define meshtastic_AirQualityMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_LocalStats_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} #define meshtastic_LocalStats_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
@@ -352,6 +357,7 @@ extern "C" {
#define meshtastic_EnvironmentMetrics_weight_tag 15 #define meshtastic_EnvironmentMetrics_weight_tag 15
#define meshtastic_EnvironmentMetrics_wind_gust_tag 16 #define meshtastic_EnvironmentMetrics_wind_gust_tag 16
#define meshtastic_EnvironmentMetrics_wind_lull_tag 17 #define meshtastic_EnvironmentMetrics_wind_lull_tag 17
#define meshtastic_EnvironmentMetrics_radiation_tag 18
#define meshtastic_PowerMetrics_ch1_voltage_tag 1 #define meshtastic_PowerMetrics_ch1_voltage_tag 1
#define meshtastic_PowerMetrics_ch1_current_tag 2 #define meshtastic_PowerMetrics_ch1_current_tag 2
#define meshtastic_PowerMetrics_ch2_voltage_tag 3 #define meshtastic_PowerMetrics_ch2_voltage_tag 3
@@ -422,7 +428,8 @@ X(a, STATIC, OPTIONAL, UINT32, wind_direction, 13) \
X(a, STATIC, OPTIONAL, FLOAT, wind_speed, 14) \ X(a, STATIC, OPTIONAL, FLOAT, wind_speed, 14) \
X(a, STATIC, OPTIONAL, FLOAT, weight, 15) \ X(a, STATIC, OPTIONAL, FLOAT, weight, 15) \
X(a, STATIC, OPTIONAL, FLOAT, wind_gust, 16) \ X(a, STATIC, OPTIONAL, FLOAT, wind_gust, 16) \
X(a, STATIC, OPTIONAL, FLOAT, wind_lull, 17) X(a, STATIC, OPTIONAL, FLOAT, wind_lull, 17) \
X(a, STATIC, OPTIONAL, FLOAT, radiation, 18)
#define meshtastic_EnvironmentMetrics_CALLBACK NULL #define meshtastic_EnvironmentMetrics_CALLBACK NULL
#define meshtastic_EnvironmentMetrics_DEFAULT NULL #define meshtastic_EnvironmentMetrics_DEFAULT NULL
@@ -521,12 +528,12 @@ extern const pb_msgdesc_t meshtastic_Nau7802Config_msg;
#define MESHTASTIC_MESHTASTIC_TELEMETRY_PB_H_MAX_SIZE meshtastic_Telemetry_size #define MESHTASTIC_MESHTASTIC_TELEMETRY_PB_H_MAX_SIZE meshtastic_Telemetry_size
#define meshtastic_AirQualityMetrics_size 78 #define meshtastic_AirQualityMetrics_size 78
#define meshtastic_DeviceMetrics_size 27 #define meshtastic_DeviceMetrics_size 27
#define meshtastic_EnvironmentMetrics_size 85 #define meshtastic_EnvironmentMetrics_size 91
#define meshtastic_HealthMetrics_size 11 #define meshtastic_HealthMetrics_size 11
#define meshtastic_LocalStats_size 60 #define meshtastic_LocalStats_size 60
#define meshtastic_Nau7802Config_size 16 #define meshtastic_Nau7802Config_size 16
#define meshtastic_PowerMetrics_size 30 #define meshtastic_PowerMetrics_size 30
#define meshtastic_Telemetry_size 92 #define meshtastic_Telemetry_size 98
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */

View File

@@ -74,6 +74,7 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
ResourceNode *nodeAPIv1ToRadioOptions = new ResourceNode("/api/v1/toradio", "OPTIONS", &handleAPIv1ToRadio); ResourceNode *nodeAPIv1ToRadioOptions = new ResourceNode("/api/v1/toradio", "OPTIONS", &handleAPIv1ToRadio);
ResourceNode *nodeAPIv1ToRadio = new ResourceNode("/api/v1/toradio", "PUT", &handleAPIv1ToRadio); ResourceNode *nodeAPIv1ToRadio = new ResourceNode("/api/v1/toradio", "PUT", &handleAPIv1ToRadio);
ResourceNode *nodeAPIv1FromRadioOptions = new ResourceNode("/api/v1/fromradio", "OPTIONS", &handleAPIv1FromRadio);
ResourceNode *nodeAPIv1FromRadio = new ResourceNode("/api/v1/fromradio", "GET", &handleAPIv1FromRadio); ResourceNode *nodeAPIv1FromRadio = new ResourceNode("/api/v1/fromradio", "GET", &handleAPIv1FromRadio);
// ResourceNode *nodeHotspotApple = new ResourceNode("/hotspot-detect.html", "GET", &handleHotspot); // ResourceNode *nodeHotspotApple = new ResourceNode("/hotspot-detect.html", "GET", &handleHotspot);
@@ -100,6 +101,7 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
// Secure nodes // Secure nodes
secureServer->registerNode(nodeAPIv1ToRadioOptions); secureServer->registerNode(nodeAPIv1ToRadioOptions);
secureServer->registerNode(nodeAPIv1ToRadio); secureServer->registerNode(nodeAPIv1ToRadio);
secureServer->registerNode(nodeAPIv1FromRadioOptions);
secureServer->registerNode(nodeAPIv1FromRadio); secureServer->registerNode(nodeAPIv1FromRadio);
// secureServer->registerNode(nodeHotspotApple); // secureServer->registerNode(nodeHotspotApple);
// secureServer->registerNode(nodeHotspotAndroid); // secureServer->registerNode(nodeHotspotAndroid);
@@ -121,6 +123,7 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
// Insecure nodes // Insecure nodes
insecureServer->registerNode(nodeAPIv1ToRadioOptions); insecureServer->registerNode(nodeAPIv1ToRadioOptions);
insecureServer->registerNode(nodeAPIv1ToRadio); insecureServer->registerNode(nodeAPIv1ToRadio);
insecureServer->registerNode(nodeAPIv1FromRadioOptions);
insecureServer->registerNode(nodeAPIv1FromRadio); insecureServer->registerNode(nodeAPIv1FromRadio);
// insecureServer->registerNode(nodeHotspotApple); // insecureServer->registerNode(nodeHotspotApple);
// insecureServer->registerNode(nodeHotspotAndroid); // insecureServer->registerNode(nodeHotspotAndroid);
@@ -163,6 +166,12 @@ void handleAPIv1FromRadio(HTTPRequest *req, HTTPResponse *res)
res->setHeader("Access-Control-Allow-Methods", "GET"); res->setHeader("Access-Control-Allow-Methods", "GET");
res->setHeader("X-Protobuf-Schema", "https://raw.githubusercontent.com/meshtastic/protobufs/master/meshtastic/mesh.proto"); res->setHeader("X-Protobuf-Schema", "https://raw.githubusercontent.com/meshtastic/protobufs/master/meshtastic/mesh.proto");
if (req->getMethod() == "OPTIONS") {
res->setStatusCode(204); // Success with no content
// res->print(""); @todo remove
return;
}
uint8_t txBuf[MAX_STREAM_BUF_SIZE]; uint8_t txBuf[MAX_STREAM_BUF_SIZE];
uint32_t len = 1; uint32_t len = 1;
@@ -441,8 +450,8 @@ void handleStatic(HTTPRequest *req, HTTPResponse *res)
return; return;
} else { } else {
LOG_ERROR("This should not have happened..."); LOG_ERROR("This should not have happened");
res->println("ERROR: This should not have happened..."); res->println("ERROR: This should not have happened");
} }
} }

View File

@@ -95,7 +95,7 @@ static void taskCreateCert(void *parameter)
LOG_DEBUG("Retrieved Certificate: %d Bytes", cert->getCertLength()); LOG_DEBUG("Retrieved Certificate: %d Bytes", cert->getCertLength());
} else { } else {
LOG_INFO("Creating the certificate. This may take a while. Please wait..."); LOG_INFO("Creating the certificate. This may take a while. Please wait");
yield(); yield();
cert = new SSLCert(); cert = new SSLCert();
yield(); yield();
@@ -189,7 +189,7 @@ int32_t WebServerThread::runOnce()
void initWebServer() void initWebServer()
{ {
LOG_DEBUG("Init Web Server..."); LOG_DEBUG("Init Web Server");
// We can now use the new certificate to setup our server as usual. // We can now use the new certificate to setup our server as usual.
secureServer = new HTTPSServer(cert); secureServer = new HTTPSServer(cert);
@@ -198,10 +198,10 @@ void initWebServer()
registerHandlers(insecureServer, secureServer); registerHandlers(insecureServer, secureServer);
if (secureServer) { if (secureServer) {
LOG_INFO("Start Secure Web Server..."); LOG_INFO("Start Secure Web Server");
secureServer->start(); secureServer->start();
} }
LOG_INFO("Start Insecure Web Server..."); LOG_INFO("Start Insecure Web Server");
insecureServer->start(); insecureServer->start();
if (insecureServer->isRunning()) { if (insecureServer->isRunning()) {
LOG_INFO("Web Servers Ready! :-) "); LOG_INFO("Web Servers Ready! :-) ");

View File

@@ -23,6 +23,8 @@
#define MAX_NUM_NODES 100 #define MAX_NUM_NODES 100
#endif #endif
#define MAX_NUM_NODES_FS 100
/// Max number of channels allowed /// Max number of channels allowed
#define MAX_NUM_CHANNELS (member_size(meshtastic_ChannelFile, channels) / member_size(meshtastic_ChannelFile, channels[0])) #define MAX_NUM_CHANNELS (member_size(meshtastic_ChannelFile, channels) / member_size(meshtastic_ChannelFile, channels[0]))

View File

@@ -20,6 +20,8 @@
#include <ESPmDNS.h> #include <ESPmDNS.h>
#include <esp_wifi.h> #include <esp_wifi.h>
static void WiFiEvent(WiFiEvent_t event); static void WiFiEvent(WiFiEvent_t event);
#elif defined(ARCH_RP2040)
#include <SimpleMDNS.h>
#endif #endif
#ifndef DISABLE_NTP #ifndef DISABLE_NTP
@@ -59,19 +61,25 @@ static void onNetworkConnected()
// Start web server // Start web server
LOG_INFO("Start WiFi network services"); LOG_INFO("Start WiFi network services");
#ifdef ARCH_ESP32
// start mdns // start mdns
if (!MDNS.begin("Meshtastic")) { if (
#ifdef ARCH_RP2040
!moduleConfig.mqtt.enabled && // MDNS is not supported when MQTT is enabled on ARCH_RP2040
#endif
!MDNS.begin("Meshtastic")) {
LOG_ERROR("Error setting up MDNS responder!"); LOG_ERROR("Error setting up MDNS responder!");
} else { } else {
LOG_INFO("mDNS responder started");
LOG_INFO("mDNS Host: Meshtastic.local"); LOG_INFO("mDNS Host: Meshtastic.local");
#ifdef ARCH_ESP32
MDNS.addService("http", "tcp", 80); MDNS.addService("http", "tcp", 80);
MDNS.addService("https", "tcp", 443); MDNS.addService("https", "tcp", 443);
} #elif defined(ARCH_RP2040)
#else // ESP32 handles this in WiFiEvent // ARCH_RP2040 does not support HTTPS, create a "meshtastic" service
LOG_INFO("Obtained IP address: %s", WiFi.localIP().toString().c_str()); MDNS.addService("meshtastic", "tcp", 4403);
// ESP32 handles this in WiFiEvent
LOG_INFO("Obtained IP address: %s", WiFi.localIP().toString().c_str());
#endif #endif
}
#ifndef DISABLE_NTP #ifndef DISABLE_NTP
LOG_INFO("Start NTP time client"); LOG_INFO("Start NTP time client");
@@ -129,7 +137,7 @@ static int32_t reconnectWiFi()
// Make sure we clear old connection credentials // Make sure we clear old connection credentials
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
WiFi.disconnect(false, true); WiFi.disconnect(false, true);
#else #elif defined(ARCH_RP2040)
WiFi.disconnect(false); WiFi.disconnect(false);
#endif #endif
LOG_INFO("Reconnecting to WiFi access point %s", wifiName); LOG_INFO("Reconnecting to WiFi access point %s", wifiName);
@@ -193,7 +201,7 @@ void deinitWifi()
if (isWifiAvailable()) { if (isWifiAvailable()) {
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
WiFi.disconnect(true, false); WiFi.disconnect(true, false);
#else #elif defined(ARCH_RP2040)
WiFi.disconnect(true); WiFi.disconnect(true);
#endif #endif
WiFi.mode(WIFI_OFF); WiFi.mode(WIFI_OFF);
@@ -229,15 +237,15 @@ bool initWifi()
if (config.network.address_mode == meshtastic_Config_NetworkConfig_AddressMode_STATIC && if (config.network.address_mode == meshtastic_Config_NetworkConfig_AddressMode_STATIC &&
config.network.ipv4_config.ip != 0) { config.network.ipv4_config.ip != 0) {
#ifndef ARCH_RP2040 #ifdef ARCH_ESP32
WiFi.config(config.network.ipv4_config.ip, config.network.ipv4_config.gateway, config.network.ipv4_config.subnet, WiFi.config(config.network.ipv4_config.ip, config.network.ipv4_config.gateway, config.network.ipv4_config.subnet,
config.network.ipv4_config.dns); config.network.ipv4_config.dns);
#else #elif defined(ARCH_RP2040)
WiFi.config(config.network.ipv4_config.ip, config.network.ipv4_config.dns, config.network.ipv4_config.gateway, WiFi.config(config.network.ipv4_config.ip, config.network.ipv4_config.dns, config.network.ipv4_config.gateway,
config.network.ipv4_config.subnet); config.network.ipv4_config.subnet);
#endif #endif
} }
#ifndef ARCH_RP2040 #ifdef ARCH_ESP32
WiFi.onEvent(WiFiEvent); WiFi.onEvent(WiFiEvent);
WiFi.setAutoReconnect(true); WiFi.setAutoReconnect(true);
WiFi.setSleep(false); WiFi.setSleep(false);

View File

@@ -3,7 +3,7 @@
#include "MeshService.h" #include "MeshService.h"
#include "NodeDB.h" #include "NodeDB.h"
#include "PowerFSM.h" #include "PowerFSM.h"
#include "RTC.h" #include "gps/RTC.h"
#include "meshUtils.h" #include "meshUtils.h"
#include <FSCommon.h> #include <FSCommon.h>
#if defined(ARCH_ESP32) && !MESHTASTIC_EXCLUDE_BLUETOOTH #if defined(ARCH_ESP32) && !MESHTASTIC_EXCLUDE_BLUETOOTH
@@ -283,6 +283,28 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
} }
break; break;
} }
case meshtastic_AdminMessage_set_ignored_node_tag: {
LOG_INFO("Client received set_ignored_node command");
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(r->set_ignored_node);
if (node != NULL) {
node->is_ignored = true;
node->has_device_metrics = false;
node->has_position = false;
node->user.public_key.size = 0;
node->user.public_key.bytes[0] = 0;
saveChanges(SEGMENT_DEVICESTATE, false);
}
break;
}
case meshtastic_AdminMessage_remove_ignored_node_tag: {
LOG_INFO("Client received remove_ignored_node command");
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(r->remove_ignored_node);
if (node != NULL) {
node->is_ignored = false;
saveChanges(SEGMENT_DEVICESTATE, false);
}
break;
}
case meshtastic_AdminMessage_set_fixed_position_tag: { case meshtastic_AdminMessage_set_fixed_position_tag: {
LOG_INFO("Client received set_fixed_position command"); LOG_INFO("Client received set_fixed_position command");
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum()); meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum());
@@ -369,7 +391,7 @@ void AdminModule::handleGetModuleConfigResponse(const meshtastic_MeshPacket &mp,
// Skip if it's disabled or no pins are exposed // Skip if it's disabled or no pins are exposed
if (!r->get_module_config_response.payload_variant.remote_hardware.enabled || if (!r->get_module_config_response.payload_variant.remote_hardware.enabled ||
r->get_module_config_response.payload_variant.remote_hardware.available_pins_count == 0) { r->get_module_config_response.payload_variant.remote_hardware.available_pins_count == 0) {
LOG_DEBUG("Remote hardware module disabled or no available_pins. Skip..."); LOG_DEBUG("Remote hardware module disabled or no available_pins. Skip");
return; return;
} }
for (uint8_t i = 0; i < devicestate.node_remote_hardware_pins_count; i++) { for (uint8_t i = 0; i < devicestate.node_remote_hardware_pins_count; i++) {
@@ -504,6 +526,11 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c)
requiresReboot = false; requiresReboot = false;
} }
config.power = c.payload_variant.power; config.power = c.payload_variant.power;
if (c.payload_variant.power.on_battery_shutdown_after_secs > 0 &&
c.payload_variant.power.on_battery_shutdown_after_secs < 30) {
LOG_WARN("Tried to set on_battery_shutdown_after_secs too low, set to min 30 seconds");
config.power.on_battery_shutdown_after_secs = 30;
}
break; break;
case meshtastic_Config_network_tag: case meshtastic_Config_network_tag:
LOG_INFO("Set config: WiFi"); LOG_INFO("Set config: WiFi");

View File

@@ -55,7 +55,7 @@ CannedMessageModule::CannedMessageModule()
LOG_INFO("CannedMessageModule is enabled"); LOG_INFO("CannedMessageModule is enabled");
// T-Watch interface currently has no way to select destination type, so default to 'node' // T-Watch interface currently has no way to select destination type, so default to 'node'
#if defined(T_WATCH_S3) || defined(RAK14014) #if defined(USE_VIRTUAL_KEYBOARD)
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NODE; this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NODE;
#endif #endif
@@ -81,7 +81,7 @@ int CannedMessageModule::splitConfiguredMessages()
String canned_messages = cannedMessageModuleConfig.messages; String canned_messages = cannedMessageModuleConfig.messages;
#if defined(T_WATCH_S3) || defined(RAK14014) #if defined(USE_VIRTUAL_KEYBOARD)
String separator = canned_messages.length() ? "|" : ""; String separator = canned_messages.length() ? "|" : "";
canned_messages = "[---- Free Text ----]" + separator + canned_messages; canned_messages = "[---- Free Text ----]" + separator + canned_messages;
@@ -150,7 +150,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
} }
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT)) { if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT)) {
#if defined(T_WATCH_S3) || defined(RAK14014) #if defined(USE_VIRTUAL_KEYBOARD)
if (this->currentMessageIndex == 0) { if (this->currentMessageIndex == 0) {
this->runState = CANNED_MESSAGE_RUN_STATE_FREETEXT; this->runState = CANNED_MESSAGE_RUN_STATE_FREETEXT;
@@ -177,7 +177,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
e.action = UIFrameEvent::Action::REGENERATE_FRAMESET; // We want to change the list of frames shown on-screen e.action = UIFrameEvent::Action::REGENERATE_FRAMESET; // We want to change the list of frames shown on-screen
this->currentMessageIndex = -1; this->currentMessageIndex = -1;
#if !defined(T_WATCH_S3) && !defined(RAK14014) #if !defined(T_WATCH_S3) && !defined(RAK14014) && !defined(USE_VIRTUAL_KEYBOARD)
this->freetext = ""; // clear freetext this->freetext = ""; // clear freetext
this->cursor = 0; this->cursor = 0;
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE; this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
@@ -190,7 +190,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
(event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) || (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) ||
(event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT))) { (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT))) {
#if defined(T_WATCH_S3) || defined(RAK14014) #if defined(USE_VIRTUAL_KEYBOARD)
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) { if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) {
this->payload = INPUT_BROKER_MSG_LEFT; this->payload = INPUT_BROKER_MSG_LEFT;
} else if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT)) { } else if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT)) {
@@ -234,13 +234,13 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
screen->decreaseBrightness(); screen->decreaseBrightness();
LOG_DEBUG("Decrease Screen Brightness"); LOG_DEBUG("Decrease Screen Brightness");
break; break;
case INPUT_BROKER_MSG_FN_SYMBOL_ON: // draw modifier (function) symbal case INPUT_BROKER_MSG_FN_SYMBOL_ON: // draw modifier (function) symbol
if (screen) if (screen)
screen->setFunctionSymbal("Fn"); screen->setFunctionSymbol("Fn");
break; break;
case INPUT_BROKER_MSG_FN_SYMBOL_OFF: // remove modifier (function) symbal case INPUT_BROKER_MSG_FN_SYMBOL_OFF: // remove modifier (function) symbol
if (screen) if (screen)
screen->removeFunctionSymbal("Fn"); screen->removeFunctionSymbol("Fn");
break; break;
// mute (switch off/toggle) external notifications on fn+m // mute (switch off/toggle) external notifications on fn+m
case INPUT_BROKER_MSG_MUTE_TOGGLE: case INPUT_BROKER_MSG_MUTE_TOGGLE:
@@ -249,13 +249,13 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
externalNotificationModule->setMute(false); externalNotificationModule->setMute(false);
showTemporaryMessage("Notifications \nEnabled"); showTemporaryMessage("Notifications \nEnabled");
if (screen) if (screen)
screen->removeFunctionSymbal("M"); // remove the mute symbol from the bottom right corner screen->removeFunctionSymbol("M"); // remove the mute symbol from the bottom right corner
} else { } else {
externalNotificationModule->stopNow(); // this will turn off all GPIO and sounds and idle the loop externalNotificationModule->stopNow(); // this will turn off all GPIO and sounds and idle the loop
externalNotificationModule->setMute(true); externalNotificationModule->setMute(true);
showTemporaryMessage("Notifications \nDisabled"); showTemporaryMessage("Notifications \nDisabled");
if (screen) if (screen)
screen->setFunctionSymbal("M"); // add the mute symbol to the bottom right corner screen->setFunctionSymbol("M"); // add the mute symbol to the bottom right corner
} }
} }
break; break;
@@ -308,11 +308,11 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
break; break;
} }
if (screen && (event->kbchar != INPUT_BROKER_MSG_FN_SYMBOL_ON)) { if (screen && (event->kbchar != INPUT_BROKER_MSG_FN_SYMBOL_ON)) {
screen->removeFunctionSymbal("Fn"); // remove modifier (function) symbal screen->removeFunctionSymbol("Fn"); // remove modifier (function) symbol
} }
} }
#if defined(T_WATCH_S3) || defined(RAK14014) #if defined(USE_VIRTUAL_KEYBOARD)
if (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) { if (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
String keyTapped = keyForCoordinates(event->touchX, event->touchY); String keyTapped = keyForCoordinates(event->touchX, event->touchY);
@@ -325,7 +325,9 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
this->shift = !this->shift; this->shift = !this->shift;
} else if (keyTapped == "") { } else if (keyTapped == "") {
#ifndef RAK14014
this->highlight = keyTapped[0]; this->highlight = keyTapped[0];
#endif
this->payload = 0x08; this->payload = 0x08;
@@ -341,7 +343,9 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
validEvent = true; validEvent = true;
} else if (keyTapped == " ") { } else if (keyTapped == " ") {
#ifndef RAK14014
this->highlight = keyTapped[0]; this->highlight = keyTapped[0];
#endif
this->payload = keyTapped[0]; this->payload = keyTapped[0];
@@ -361,7 +365,9 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
this->shift = false; this->shift = false;
} else if (keyTapped != "") { } else if (keyTapped != "") {
#ifndef RAK14014
this->highlight = keyTapped[0]; this->highlight = keyTapped[0];
#endif
this->payload = this->shift ? keyTapped[0] : std::tolower(keyTapped[0]); this->payload = this->shift ? keyTapped[0] : std::tolower(keyTapped[0]);
@@ -440,7 +446,7 @@ int32_t CannedMessageModule::runOnce()
this->freetext = ""; // clear freetext this->freetext = ""; // clear freetext
this->cursor = 0; this->cursor = 0;
#if !defined(T_WATCH_S3) && !defined(RAK14014) #if !defined(T_WATCH_S3) && !defined(RAK14014) && !defined(SENSECAP_INDICATOR)
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE; this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
#endif #endif
@@ -453,7 +459,7 @@ int32_t CannedMessageModule::runOnce()
this->freetext = ""; // clear freetext this->freetext = ""; // clear freetext
this->cursor = 0; this->cursor = 0;
#if !defined(T_WATCH_S3) && !defined(RAK14014) #if !defined(T_WATCH_S3) && !defined(RAK14014) && !defined(USE_VIRTUAL_KEYBOARD)
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE; this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
#endif #endif
@@ -473,7 +479,7 @@ int32_t CannedMessageModule::runOnce()
powerFSM.trigger(EVENT_PRESS); powerFSM.trigger(EVENT_PRESS);
return INT32_MAX; return INT32_MAX;
} else { } else {
#if defined(T_WATCH_S3) || defined(RAK14014) #if defined(USE_VIRTUAL_KEYBOARD)
sendText(this->dest, indexChannels[this->channel], this->messages[this->currentMessageIndex], true); sendText(this->dest, indexChannels[this->channel], this->messages[this->currentMessageIndex], true);
#else #else
sendText(NODENUM_BROADCAST, channels.getPrimaryIndex(), this->messages[this->currentMessageIndex], true); sendText(NODENUM_BROADCAST, channels.getPrimaryIndex(), this->messages[this->currentMessageIndex], true);
@@ -490,7 +496,7 @@ int32_t CannedMessageModule::runOnce()
this->freetext = ""; // clear freetext this->freetext = ""; // clear freetext
this->cursor = 0; this->cursor = 0;
#if !defined(T_WATCH_S3) && !defined(RAK14014) #if !defined(T_WATCH_S3) && !defined(RAK14014) && !defined(USE_VIRTUAL_KEYBOARD)
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE; this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
#endif #endif
@@ -507,7 +513,7 @@ int32_t CannedMessageModule::runOnce()
this->freetext = ""; // clear freetext this->freetext = ""; // clear freetext
this->cursor = 0; this->cursor = 0;
#if !defined(T_WATCH_S3) && !defined(RAK14014) #if !defined(T_WATCH_S3) && !defined(RAK14014) && !defined(USE_VIRTUAL_KEYBOARD)
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE; this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
#endif #endif
@@ -520,7 +526,7 @@ int32_t CannedMessageModule::runOnce()
this->freetext = ""; // clear freetext this->freetext = ""; // clear freetext
this->cursor = 0; this->cursor = 0;
#if !defined(T_WATCH_S3) && !defined(RAK14014) #if !defined(T_WATCH_S3) && !defined(RAK14014) && !defined(USE_VIRTUAL_KEYBOARD)
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE; this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
#endif #endif
@@ -666,7 +672,7 @@ int32_t CannedMessageModule::runOnce()
break; break;
} }
if (screen) if (screen)
screen->removeFunctionSymbal("Fn"); screen->removeFunctionSymbol("Fn");
} }
this->lastTouchMillis = millis(); this->lastTouchMillis = millis();
@@ -763,7 +769,7 @@ void CannedMessageModule::showTemporaryMessage(const String &message)
setIntervalFromNow(2000); setIntervalFromNow(2000);
} }
#if defined(T_WATCH_S3) || defined(RAK14014) #if defined(USE_VIRTUAL_KEYBOARD)
String CannedMessageModule::keyForCoordinates(uint x, uint y) String CannedMessageModule::keyForCoordinates(uint x, uint y)
{ {
@@ -830,6 +836,11 @@ void CannedMessageModule::drawKeyboard(OLEDDisplay *display, OLEDDisplayUiState
Letter updatedLetter = {letter.character, letter.width, xOffset, yOffset, cellWidth, cellHeight}; Letter updatedLetter = {letter.character, letter.width, xOffset, yOffset, cellWidth, cellHeight};
#ifdef RAK14014 // Optimize the touch range of the virtual keyboard in the bottom row
if (outerIndex == outerSize - 1) {
updatedLetter.rectHeight = 240 - yOffset;
}
#endif
this->keyboard[this->charSet][outerIndex][innerIndex] = updatedLetter; this->keyboard[this->charSet][outerIndex][innerIndex] = updatedLetter;
float characterOffset = ((cellWidth / 2) - (letter.width / 2)); float characterOffset = ((cellWidth / 2) - (letter.width / 2));
@@ -1044,7 +1055,7 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
display->drawString(10 + x, 0 + y + FONT_HEIGHT_SMALL, "Canned Message\nModule disabled."); display->drawString(10 + x, 0 + y + FONT_HEIGHT_SMALL, "Canned Message\nModule disabled.");
} else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) { } else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
requestFocus(); // Tell Screen::setFrames to move to our module's frame requestFocus(); // Tell Screen::setFrames to move to our module's frame
#if defined(T_WATCH_S3) || defined(RAK14014) #if defined(USE_VIRTUAL_KEYBOARD)
drawKeyboard(display, state, 0, 0); drawKeyboard(display, state, 0, 0);
#else #else

View File

@@ -68,6 +68,10 @@ class CannedMessageModule : public SinglePortModule, public Observable<const UIF
String drawWithCursor(String text, int cursor); String drawWithCursor(String text, int cursor);
#ifdef RAK14014
cannedMessageModuleRunState getRunState() const { return runState; }
#endif
/* /*
-Override the wantPacket method. We need the Routing Messages to look for ACKs. -Override the wantPacket method. We need the Routing Messages to look for ACKs.
*/ */
@@ -98,7 +102,7 @@ class CannedMessageModule : public SinglePortModule, public Observable<const UIF
int getNextIndex(); int getNextIndex();
int getPrevIndex(); int getPrevIndex();
#if defined(T_WATCH_S3) || defined(RAK14014) #if defined(USE_VIRTUAL_KEYBOARD)
void drawKeyboard(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y); void drawKeyboard(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
String keyForCoordinates(uint x, uint y); String keyForCoordinates(uint x, uint y);
bool shift = false; bool shift = false;
@@ -152,7 +156,7 @@ class CannedMessageModule : public SinglePortModule, public Observable<const UIF
unsigned long lastTouchMillis = 0; unsigned long lastTouchMillis = 0;
String temporaryMessage; String temporaryMessage;
#if defined(T_WATCH_S3) || defined(RAK14014) #if defined(USE_VIRTUAL_KEYBOARD)
Letter keyboard[2][4][10] = {{{{"Q", 20, 0, 0, 0, 0}, Letter keyboard[2][4][10] = {{{{"Q", 20, 0, 0, 0, 0},
{"W", 22, 0, 0, 0, 0}, {"W", 22, 0, 0, 0, 0},
{"E", 17, 0, 0, 0, 0}, {"E", 17, 0, 0, 0, 0},

View File

@@ -58,7 +58,7 @@ int32_t DetectionSensorModule::runOnce()
// moduleConfig.detection_sensor.minimum_broadcast_secs = 30; // moduleConfig.detection_sensor.minimum_broadcast_secs = 30;
// moduleConfig.detection_sensor.state_broadcast_secs = 120; // moduleConfig.detection_sensor.state_broadcast_secs = 120;
// moduleConfig.detection_sensor.detection_trigger_type = // moduleConfig.detection_sensor.detection_trigger_type =
// meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_LOGIC_HIGH; // meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_LOGIC_HIGH;
// strcpy(moduleConfig.detection_sensor.name, "Motion"); // strcpy(moduleConfig.detection_sensor.name, "Motion");
if (moduleConfig.detection_sensor.enabled == false) if (moduleConfig.detection_sensor.enabled == false)
@@ -76,7 +76,7 @@ int32_t DetectionSensorModule::runOnce()
if (moduleConfig.detection_sensor.monitor_pin > 0) { if (moduleConfig.detection_sensor.monitor_pin > 0) {
pinMode(moduleConfig.detection_sensor.monitor_pin, moduleConfig.detection_sensor.use_pullup ? INPUT_PULLUP : INPUT); pinMode(moduleConfig.detection_sensor.monitor_pin, moduleConfig.detection_sensor.use_pullup ? INPUT_PULLUP : INPUT);
} else { } else {
LOG_WARN("Detection Sensor Module: Set to enabled but no monitor pin is set. Disable module..."); LOG_WARN("Detection Sensor Module: Set to enabled but no monitor pin is set. Disable module");
return disable(); return disable();
} }
LOG_INFO("Detection Sensor Module: init"); LOG_INFO("Detection Sensor Module: init");
@@ -130,9 +130,12 @@ void DetectionSensorModule::sendDetectionMessage()
p->decoded.payload.bytes[p->decoded.payload.size + 1] = '\0'; // Bell character p->decoded.payload.bytes[p->decoded.payload.size + 1] = '\0'; // Bell character
p->decoded.payload.size++; p->decoded.payload.size++;
} }
LOG_INFO("Send message id=%d, dest=%x, msg=%.*s", p->id, p->to, p->decoded.payload.size, p->decoded.payload.bytes);
lastSentToMesh = millis(); lastSentToMesh = millis();
service->sendToMesh(p); if (!channels.isDefaultChannel(0)) {
LOG_INFO("Send message id=%d, dest=%x, msg=%.*s", p->id, p->to, p->decoded.payload.size, p->decoded.payload.bytes);
service->sendToMesh(p);
} else
LOG_ERROR("Message not allow on Public channel");
delete[] message; delete[] message;
} }
@@ -140,14 +143,16 @@ void DetectionSensorModule::sendCurrentStateMessage(bool state)
{ {
char *message = new char[40]; char *message = new char[40];
sprintf(message, "%s state: %i", moduleConfig.detection_sensor.name, state); sprintf(message, "%s state: %i", moduleConfig.detection_sensor.name, state);
meshtastic_MeshPacket *p = allocDataPacket(); meshtastic_MeshPacket *p = allocDataPacket();
p->want_ack = false; p->want_ack = false;
p->decoded.payload.size = strlen(message); p->decoded.payload.size = strlen(message);
memcpy(p->decoded.payload.bytes, message, p->decoded.payload.size); memcpy(p->decoded.payload.bytes, message, p->decoded.payload.size);
LOG_INFO("Send message id=%d, dest=%x, msg=%.*s", p->id, p->to, p->decoded.payload.size, p->decoded.payload.bytes);
lastSentToMesh = millis(); lastSentToMesh = millis();
service->sendToMesh(p); if (!channels.isDefaultChannel(0)) {
LOG_INFO("Send message id=%d, dest=%x, msg=%.*s", p->id, p->to, p->decoded.payload.size, p->decoded.payload.bytes);
service->sendToMesh(p);
} else
LOG_ERROR("Message not allow on Public channel");
delete[] message; delete[] message;
} }
@@ -156,4 +161,4 @@ bool DetectionSensorModule::hasDetectionEvent()
bool currentState = digitalRead(moduleConfig.detection_sensor.monitor_pin); bool currentState = digitalRead(moduleConfig.detection_sensor.monitor_pin);
// LOG_DEBUG("Detection Sensor Module: Current state: %i", currentState); // LOG_DEBUG("Detection Sensor Module: Current state: %i", currentState);
return (moduleConfig.detection_sensor.detection_trigger_type & 1) ? currentState : !currentState; return (moduleConfig.detection_sensor.detection_trigger_type & 1) ? currentState : !currentState;
} }

View File

@@ -119,12 +119,13 @@ int32_t ExternalNotificationModule::runOnce()
if (externalTurnedOn[1] + (moduleConfig.external_notification.output_ms ? moduleConfig.external_notification.output_ms if (externalTurnedOn[1] + (moduleConfig.external_notification.output_ms ? moduleConfig.external_notification.output_ms
: EXT_NOTIFICATION_MODULE_OUTPUT_MS) < : EXT_NOTIFICATION_MODULE_OUTPUT_MS) <
millis()) { millis()) {
setExternalState(0, !getExternal(1)); setExternalState(1, !getExternal(1));
} }
if (externalTurnedOn[2] + (moduleConfig.external_notification.output_ms ? moduleConfig.external_notification.output_ms if (externalTurnedOn[2] + (moduleConfig.external_notification.output_ms ? moduleConfig.external_notification.output_ms
: EXT_NOTIFICATION_MODULE_OUTPUT_MS) < : EXT_NOTIFICATION_MODULE_OUTPUT_MS) <
millis()) { millis()) {
setExternalState(0, !getExternal(2)); LOG_DEBUG("EXTERNAL 2 %d compared to %d", externalTurnedOn[2]+moduleConfig.external_notification.output_ms, millis());
setExternalState(2, !getExternal(2));
} }
#if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE) #if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
red = (colorState & 4) ? brightnessValues[brightnessIndex] : 0; // Red enabled on colorState = 4,5,6,7 red = (colorState & 4) ? brightnessValues[brightnessIndex] : 0; // Red enabled on colorState = 4,5,6,7

View File

@@ -3,7 +3,7 @@
#include "SinglePortModule.h" #include "SinglePortModule.h"
#include "concurrency/OSThread.h" #include "concurrency/OSThread.h"
#include "configuration.h" #include "configuration.h"
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !defined(CONFIG_IDF_TARGET_ESP32C6) #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !defined(ARCH_APOLLO3) && !defined(CONFIG_IDF_TARGET_ESP32C6)
#include <NonBlockingRtttl.h> #include <NonBlockingRtttl.h>
#else #else
// Noop class for portduino. // Noop class for portduino.

View File

@@ -2,7 +2,7 @@
#include "Default.h" #include "Default.h"
#include "MeshService.h" #include "MeshService.h"
#include "NodeDB.h" #include "NodeDB.h"
#include "RTC.h" #include "gps/RTC.h"
#include <Throttle.h> #include <Throttle.h>
NeighborInfoModule *neighborInfoModule; NeighborInfoModule *neighborInfoModule;
@@ -121,7 +121,12 @@ Will be used for broadcast.
*/ */
int32_t NeighborInfoModule::runOnce() int32_t NeighborInfoModule::runOnce()
{ {
sendNeighborInfo(NODENUM_BROADCAST_NO_LORA, false); if (moduleConfig.neighbor_info.transmit_over_lora && !channels.isDefaultChannel(channels.getPrimaryIndex()) &&
airTime->isTxAllowedChannelUtil(true) && airTime->isTxAllowedAirUtil()) {
sendNeighborInfo(NODENUM_BROADCAST, false);
} else {
sendNeighborInfo(NODENUM_BROADCAST_NO_LORA, false);
}
return Default::getConfiguredOrDefaultMs(moduleConfig.neighbor_info.update_interval, default_neighbor_info_broadcast_secs); return Default::getConfiguredOrDefaultMs(moduleConfig.neighbor_info.update_interval, default_neighbor_info_broadcast_secs);
} }

View File

@@ -70,11 +70,11 @@ meshtastic_MeshPacket *NodeInfoModule::allocReply()
} }
// If we sent our NodeInfo less than 5 min. ago, don't send it again as it may be still underway. // If we sent our NodeInfo less than 5 min. ago, don't send it again as it may be still underway.
if (!shorterTimeout && lastSentToMesh && Throttle::isWithinTimespanMs(lastSentToMesh, 5 * 60 * 1000)) { if (!shorterTimeout && lastSentToMesh && Throttle::isWithinTimespanMs(lastSentToMesh, 5 * 60 * 1000)) {
LOG_DEBUG("Skip send NodeInfo since we sent it <5 mins ago."); LOG_DEBUG("Skip send NodeInfo since we sent it <5min ago");
ignoreRequest = true; // Mark it as ignored for MeshModule ignoreRequest = true; // Mark it as ignored for MeshModule
return NULL; return NULL;
} else if (shorterTimeout && lastSentToMesh && Throttle::isWithinTimespanMs(lastSentToMesh, 60 * 1000)) { } else if (shorterTimeout && lastSentToMesh && Throttle::isWithinTimespanMs(lastSentToMesh, 60 * 1000)) {
LOG_DEBUG("Skip send requested NodeInfo since we sent it <60s ago."); LOG_DEBUG("Skip send NodeInfo since we sent it <60s ago");
ignoreRequest = true; // Mark it as ignored for MeshModule ignoreRequest = true; // Mark it as ignored for MeshModule
return NULL; return NULL;
} else { } else {

View File

@@ -4,22 +4,19 @@
#include "GPS.h" #include "GPS.h"
#include "MeshService.h" #include "MeshService.h"
#include "NodeDB.h" #include "NodeDB.h"
#include "RTC.h"
#include "Router.h" #include "Router.h"
#include "TypeConversions.h" #include "TypeConversions.h"
#include "airtime.h" #include "airtime.h"
#include "configuration.h" #include "configuration.h"
#include "gps/GeoCoord.h" #include "gps/GeoCoord.h"
#include "gps/RTC.h"
#include "main.h" #include "main.h"
#include "mesh/compression/unishox2.h" #include "mesh/compression/unishox2.h"
#include "meshUtils.h" #include "meshUtils.h"
#include "meshtastic/atak.pb.h" #include "meshtastic/atak.pb.h"
#include "sleep.h" #include "sleep.h"
#include "target_specific.h" #include "target_specific.h"
extern "C" {
#include <Throttle.h> #include <Throttle.h>
}
PositionModule *positionModule; PositionModule *positionModule;
@@ -149,11 +146,20 @@ bool PositionModule::hasQualityTimesource()
#if MESHTASTIC_EXCLUDE_GPS #if MESHTASTIC_EXCLUDE_GPS
bool hasGpsOrRtc = (rtc_found.address != ScanI2C::ADDRESS_NONE.address); bool hasGpsOrRtc = (rtc_found.address != ScanI2C::ADDRESS_NONE.address);
#else #else
bool hasGpsOrRtc = (gps && gps->isConnected()) || (rtc_found.address != ScanI2C::ADDRESS_NONE.address); bool hasGpsOrRtc = hasGPS() || (rtc_found.address != ScanI2C::ADDRESS_NONE.address);
#endif #endif
return hasGpsOrRtc || setFromPhoneOrNtpToday; return hasGpsOrRtc || setFromPhoneOrNtpToday;
} }
bool PositionModule::hasGPS()
{
#if MESHTASTIC_EXCLUDE_GPS
return false;
#else
return gps && gps->isConnected();
#endif
}
meshtastic_MeshPacket *PositionModule::allocReply() meshtastic_MeshPacket *PositionModule::allocReply()
{ {
if (precision == 0) { if (precision == 0) {
@@ -197,10 +203,21 @@ meshtastic_MeshPacket *PositionModule::allocReply()
p.precision_bits = precision; p.precision_bits = precision;
p.has_latitude_i = true; p.has_latitude_i = true;
p.has_longitude_i = true; p.has_longitude_i = true;
p.time = getValidTime(RTCQualityNTP) > 0 ? getValidTime(RTCQualityNTP) : localPosition.time; // Always use NTP / GPS time if available
if (getValidTime(RTCQualityNTP) > 0) {
p.time = getValidTime(RTCQualityNTP);
} else if (rtc_found.address != ScanI2C::ADDRESS_NONE.address) {
LOG_INFO("Use RTC time for position");
p.time = getValidTime(RTCQualityDevice);
} else if (getRTCQuality() < RTCQualityNTP) {
LOG_INFO("Strip low RTCQuality (%d) time from position", getRTCQuality());
p.time = 0;
}
if (config.position.fixed_position) { if (config.position.fixed_position) {
p.location_source = meshtastic_Position_LocSource_LOC_MANUAL; p.location_source = meshtastic_Position_LocSource_LOC_MANUAL;
} else {
p.location_source = localPosition.location_source;
} }
if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE) { if (pos_flags & meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE) {
@@ -245,17 +262,6 @@ meshtastic_MeshPacket *PositionModule::allocReply()
p.has_ground_speed = true; p.has_ground_speed = true;
} }
// Strip out any time information before sending packets to other nodes - to keep the wire size small (and because other
// nodes shouldn't trust it anyways) Note: we allow a device with a local GPS or NTP to include the time, so that devices
// without can get time.
if (getRTCQuality() < RTCQualityNTP) {
LOG_INFO("Strip time %u from position send", p.time);
p.time = 0;
} else {
p.time = getValidTime(RTCQualityNTP);
LOG_INFO("Provide time to mesh %u", p.time);
}
LOG_INFO("Position reply: time=%i lat=%i lon=%i", p.time, p.latitude_i, p.longitude_i); LOG_INFO("Position reply: time=%i lat=%i lon=%i", p.time, p.latitude_i, p.longitude_i);
// TAK Tracker devices should send their position in a TAK packet over the ATAK port // TAK Tracker devices should send their position in a TAK packet over the ATAK port
@@ -364,7 +370,7 @@ int32_t PositionModule::runOnce()
sleepOnNextExecution = false; sleepOnNextExecution = false;
uint32_t nightyNightMs = Default::getConfiguredOrDefaultMs(config.position.position_broadcast_secs); uint32_t nightyNightMs = Default::getConfiguredOrDefaultMs(config.position.position_broadcast_secs);
LOG_DEBUG("Sleep for %ims, then awaking to send position again", nightyNightMs); LOG_DEBUG("Sleep for %ims, then awaking to send position again", nightyNightMs);
doDeepSleep(nightyNightMs, false); doDeepSleep(nightyNightMs, false, false);
} }
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum()); meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum());

View File

@@ -61,6 +61,7 @@ class PositionModule : public ProtobufModule<meshtastic_Position>, private concu
uint32_t precision; uint32_t precision;
void sendLostAndFoundText(); void sendLostAndFoundText();
bool hasQualityTimesource(); bool hasQualityTimesource();
bool hasGPS();
const uint32_t minimumTimeThreshold = const uint32_t minimumTimeThreshold =
Default::getConfiguredOrDefaultMs(config.position.broadcast_smart_minimum_interval_secs, 30); Default::getConfiguredOrDefaultMs(config.position.broadcast_smart_minimum_interval_secs, 30);

View File

@@ -111,7 +111,7 @@ int32_t PowerStressModule::runOnce()
setBluetoothEnable(true); setBluetoothEnable(true);
break; break;
case meshtastic_PowerStressMessage_Opcode_CPU_DEEPSLEEP: case meshtastic_PowerStressMessage_Opcode_CPU_DEEPSLEEP:
doDeepSleep(sleep_msec, true); doDeepSleep(sleep_msec, true, true);
break; break;
case meshtastic_PowerStressMessage_Opcode_CPU_FULLON: { case meshtastic_PowerStressMessage_Opcode_CPU_FULLON: {
uint32_t start_msec = millis(); uint32_t start_msec = millis();

View File

@@ -204,9 +204,11 @@ int32_t SerialModule::runOnce()
lastNmeaTime = millis(); lastNmeaTime = millis();
uint32_t readIndex = 0; uint32_t readIndex = 0;
const meshtastic_NodeInfoLite *tempNodeInfo = nodeDB->readNextMeshNode(readIndex); const meshtastic_NodeInfoLite *tempNodeInfo = nodeDB->readNextMeshNode(readIndex);
while (tempNodeInfo != NULL && tempNodeInfo->has_user && hasValidPosition(tempNodeInfo)) { while (tempNodeInfo != NULL) {
printWPL(outbuf, sizeof(outbuf), tempNodeInfo->position, tempNodeInfo->user.long_name, true); if (tempNodeInfo->has_user && hasValidPosition(tempNodeInfo)) {
serialPrint->printf("%s", outbuf); printWPL(outbuf, sizeof(outbuf), tempNodeInfo->position, tempNodeInfo->user.long_name, true);
serialPrint->printf("%s", outbuf);
}
tempNodeInfo = nodeDB->readNextMeshNode(readIndex); tempNodeInfo = nodeDB->readNextMeshNode(readIndex);
} }
} }

View File

@@ -77,9 +77,10 @@ meshtastic_MeshPacket *DeviceTelemetryModule::allocReply()
// Check for a request for device metrics // Check for a request for device metrics
if (decoded->which_variant == meshtastic_Telemetry_device_metrics_tag) { if (decoded->which_variant == meshtastic_Telemetry_device_metrics_tag) {
LOG_INFO("Device telemetry reply to request"); LOG_INFO("Device telemetry reply to request");
return allocDataProtobuf(getDeviceTelemetry());
meshtastic_Telemetry telemetry = getDeviceTelemetry(); } else if (decoded->which_variant == meshtastic_Telemetry_local_stats_tag) {
return allocDataProtobuf(telemetry); LOG_INFO("Device telemetry reply w/ LocalStats to request");
return allocDataProtobuf(getLocalStatsTelemetry());
} }
} }
return NULL; return NULL;
@@ -112,7 +113,7 @@ meshtastic_Telemetry DeviceTelemetryModule::getDeviceTelemetry()
return t; return t;
} }
void DeviceTelemetryModule::sendLocalStatsToPhone() meshtastic_Telemetry DeviceTelemetryModule::getLocalStatsTelemetry()
{ {
meshtastic_Telemetry telemetry = meshtastic_Telemetry_init_zero; meshtastic_Telemetry telemetry = meshtastic_Telemetry_init_zero;
telemetry.which_variant = meshtastic_Telemetry_local_stats_tag; telemetry.which_variant = meshtastic_Telemetry_local_stats_tag;
@@ -142,7 +143,12 @@ void DeviceTelemetryModule::sendLocalStatsToPhone()
LOG_INFO("num_packets_tx=%i, num_packets_rx=%i, num_packets_rx_bad=%i", telemetry.variant.local_stats.num_packets_tx, LOG_INFO("num_packets_tx=%i, num_packets_rx=%i, num_packets_rx_bad=%i", telemetry.variant.local_stats.num_packets_tx,
telemetry.variant.local_stats.num_packets_rx, telemetry.variant.local_stats.num_packets_rx_bad); telemetry.variant.local_stats.num_packets_rx, telemetry.variant.local_stats.num_packets_rx_bad);
meshtastic_MeshPacket *p = allocDataProtobuf(telemetry); return telemetry;
}
void DeviceTelemetryModule::sendLocalStatsToPhone()
{
meshtastic_MeshPacket *p = allocDataProtobuf(getLocalStatsTelemetry());
p->to = NODENUM_BROADCAST; p->to = NODENUM_BROADCAST;
p->decoded.want_response = false; p->decoded.want_response = false;
p->priority = meshtastic_MeshPacket_Priority_BACKGROUND; p->priority = meshtastic_MeshPacket_Priority_BACKGROUND;

View File

@@ -42,6 +42,8 @@ class DeviceTelemetryModule : private concurrency::OSThread, public ProtobufModu
private: private:
meshtastic_Telemetry getDeviceTelemetry(); meshtastic_Telemetry getDeviceTelemetry();
meshtastic_Telemetry getLocalStatsTelemetry();
void sendLocalStatsToPhone(); void sendLocalStatsToPhone();
uint32_t sendToPhoneIntervalMs = SECONDS_IN_MINUTE * 1000; // Send to phone every minute uint32_t sendToPhoneIntervalMs = SECONDS_IN_MINUTE * 1000; // Send to phone every minute
uint32_t sendStatsToPhoneIntervalMs = 15 * SECONDS_IN_MINUTE * 1000; // Send stats to phone every 15 minutes uint32_t sendStatsToPhoneIntervalMs = 15 * SECONDS_IN_MINUTE * 1000; // Send stats to phone every 15 minutes

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