Compare commits

..

103 Commits

Author SHA1 Message Date
Ben Meadors
0fc5c9b0d7 Create CODE_OF_CONDUCT.md (#5225) 2024-11-02 07:57:33 -05:00
Tom Fifield
b0c924f185 Optimise GPS Baud Rate cycle (#5102)
* Optimise GPS Baud Rate cycle

Previously, our baud rate cycled through one list twice.

There were some rarer baudrates in there, so this code
separates out those into a dedicated list that is only
run through if detection fails for common bauds. We also
only run through each baud rate once.

* Fix first time around bug

Would have always reset GPS baudrate every time.

* Add support for fixing GPS_BAUDRATE

If GPS_BAUDRATE is set in variant.h, the deployer knows something we
don't about the GPS. Used especially when the GPS is soldered to a board
in a commercial product :) If we see that, we don't try other baud rates
at all.

* Don't print blank lines in GPS_DEBUG.

* Try GPS_BAUDRATE first, not only.

* Fix spelling mistakes in comments

* Only use GPS_BAUDRATE if specified in variant.h

* Modify RareSerial Speeds based on FIXED or not.
2024-11-02 07:51:12 -05:00
github-actions[bot]
8801bc5ce9 [create-pull-request] automated change (#5223)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
2024-11-02 05:58:06 -05:00
Jonathan Bennett
cf476eb87c Remove assert in mesh-pb-constants.cpp (#5207)
* Remove assert in mesh-pb-constants.cpp

* Add raw packet output to portduino trace logging.

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2024-11-02 05:38:44 -05:00
todd-herbert
ba2f25293b Fix flipped logic after move to Throttle::isWithinTimespanMs (#5221) 2024-11-02 05:36:40 -05:00
GUVWAF
2d4d36c605 Drop oldest packet from radio when queue is full (#5212)
And still notify Router

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2024-11-01 15:48:55 -05:00
Ben Meadors
cbe74009a9 Comment out unused var to get rid of warning 2024-11-01 15:46:11 -05:00
Ben Meadors
701421b50a Trunk fmt 2024-11-01 15:17:25 -05:00
Aaron.Lee
336cdc0efe Add Heltec V3 battery read pin detect function (#5196) 2024-11-01 15:12:41 -05:00
Ben Meadors
a1ac358b0a Don't try to count non-lora transmissions into airtime (or attempt to decode) (#5215)
* Don't try to count non-lora transmissions into airtime (or attempt to decode)

* Don't need to check utilization anymore
2024-11-01 13:20:11 -05:00
dependabot[bot]
8462d65f76 Bump actions/github-script from 5 to 7 in /.github/workflows (#5214)
Bumps [actions/github-script](https://github.com/actions/github-script) from 5 to 7.
- [Release notes](https://github.com/actions/github-script/releases)
- [Commits](https://github.com/actions/github-script/compare/v5...v7)

---
updated-dependencies:
- dependency-name: actions/github-script
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-01 07:50:40 -05:00
Ben Meadors
10dd8af614 Eh? 2024-11-01 06:10:42 -05:00
Ben Meadors
9c06c492d9 Use one from the other PR 2024-11-01 06:04:14 -05:00
Ben Meadors
7e3c369e87 Trunk fmt on comment 2024-11-01 05:58:48 -05:00
Ben Meadors
732cf4832a Bump version since I killed the PR 2024-11-01 05:20:00 -05:00
Jonathan Bennett
545ebf9b17 Don't skip GPS serial speeds, and always land on GPS_BAUDRATE (#5195)
* Don't skip GPS serial speeds, and always land on GPS_BAUDRATE

* Update log message to match.

* print the value instead
2024-11-01 08:44:02 +08:00
Ben Meadors
7912c214c7 Increase NimBLE stack size (#5202) 2024-10-31 15:09:27 -05:00
Alexander Begoon
600208ab0b Refactor getMacAddr function to retrieve MAC address as MAC-48 for IEEE 802.15.4 compatibility (#5208) 2024-10-31 15:07:59 -05:00
GUVWAF
462a0718cf Fix SerialModule getting packet from ourselves (#5206) 2024-10-31 11:46:00 -05:00
Thomas Göttgens
aae346aef7 Update stale_bot.yml 2024-10-30 23:02:59 +01:00
Andre K
28b469dbf0 fix: don't broadcast public keys if the user is licensed (#5190)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Jonathan Bennett <jbennett@incomsystems.biz>
2024-10-30 12:05:09 -05:00
Ben Meadors
5f6e19d971 As a Router 2024-10-30 06:02:59 -05:00
Thomas Göttgens
0726eaa678 Update stale_bot.yml 2024-10-30 10:43:08 +01:00
Thomas Göttgens
50fb575caa Update stale_bot.yml 2024-10-30 10:16:40 +01:00
Thomas Göttgens
cc59a50cba Test: mark issues as stale 2024-10-30 10:14:59 +01:00
Jonathan Bennett
b3ba23b4e8 Don't generate or populate PKC keys in licensed mode 2024-10-29 14:17:14 -05:00
Ben Meadors
936260fca3 Default rebroadcast mode for Router and Repeater to ignore problematic portnums (#5178)
* Default rebroadcast mode for Router and Repeater to ignore problematic portnums

* Verbiage

* IS_ONE_OF
2024-10-29 05:44:32 -05:00
Tom Fifield
2945b9cfbe De-duplicate Ambient LED management code (#5156)
We currently have 4 different places where we have the logic for
modifying LED state of the various types of Ambient LEDs,
ExternalNotificationModule::SetExternalOff
ExternalNotificationModule::SetExternalOn
AmbientLightingThread::setLighting
AmbientLightingThread::setLightingOff

This patch de-duplicates the methods in ExternalNotification to
a single method, using a boolean to toggle whether we're turning
things on or off.
2024-10-29 05:41:21 -05:00
Megaceryle-alcyon
ed03d28a83 Added PA1616S GPS module (#5157)
* Added GPS chip PA1616S

GPS chip PA1616S is used in some recent Adafruit GPS breakout boards.

* Update GPS.cpp

---------

Co-authored-by: picusviridis <mesh.culprit381@passmail.net>
2024-10-29 09:34:01 +01:00
Jonathan Bennett
850f61d2d0 Native config.d (#5165)
* Add support for loading yaml from a config directory

* Add waveshare hats to the new config.d approach

* Move to available.d for module inactive module configs
2024-10-28 21:48:10 -05:00
Ben Meadors
e12fd27b49 Trunkdor the burninator 2024-10-28 06:40:48 -05:00
Spiffysec
77dfc92f1e Update GPSUpdateScheduling.cpp (#5160)
* Update GPSUpdateScheduling.cpp

Default value is too short, resulting in unstable GPS locks on T1000-E (possibly others). Fix has been tested an confirmed working with no adverse effects, by multiple users. Also discussed at length on Discord

* Coerce minimum instead of hardcode

* config

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2024-10-28 06:18:03 -05:00
github-actions[bot]
c4eb9a6d7f [create-pull-request] automated change (#5176)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
2024-10-28 06:16:06 -05:00
Tom Fifield
195f109ef7 Cherrry pick bin/config-dist.yml from TFT-GUI-Work (#5168)
* support SHCHV 3.5 RPi TFT+Touchscreen

* add TZT 2.0inch ST7789 config

---------

Co-authored-by: mverch67 <manuel.verch@gmx.de>
2024-10-28 09:31:21 +01:00
Tom Fifield
3c8ca39eff cherry-pick: fix nrf builds (#5172)
* fix nrf builds

* fix rp2040 + monteops build

* Bump lovyan version

---------

Co-authored-by: mverch67 <manuel.verch@gmx.de>
2024-10-28 09:30:39 +01:00
Tom Fifield
c071eed6a3 cherry-pick: unphone support (#5174)
* unphone part 1

* Unphone support

* update HWid unphone

---------

Co-authored-by: mverch67 <manuel.verch@gmx.de>
2024-10-28 09:25:25 +01:00
Tom Fifield
d14d42ba2c diy mesh-tab initial files (#5169)
Co-authored-by: mverch67 <manuel.verch@gmx.de>
2024-10-28 09:23:49 +01:00
Jonathan Bennett
82145e0661 Cherry picks (#5166)
* fix compiler error std::find()

* fix wifi/bt connection status

* try-fix crash

* added 1200baud reset

---------

Co-authored-by: mverch67 <manuel.verch@gmx.de>
2024-10-28 10:21:57 +10:00
Ben Meadors
1334d07c6a Trunk updates 2024-10-27 06:57:11 -05:00
Muhammad Shah
bf760a44ba Icarus - Fix platform dependency version and add selection button (#5161)
* Update variant.h

* Update platformio.ini
2024-10-27 05:51:51 -05:00
mverch67
94ff67e927 fix spiLock in RadioLibInterface 2024-10-27 10:55:23 +01:00
Muhammad Shah
e37369a25f Icarus - Custom PCB (#5155)
* added Icarus

* added Icarus

* Update platformio.ini

* Fixed I2C ports

* Update variant.h
2024-10-26 19:24:30 -05:00
mverch67
a8bd1ee0da stability: add SPI lock before saving via littleFS 2024-10-26 16:01:46 +02:00
github-actions[bot]
2568d4fcd8 [create-pull-request] automated change (#5153)
Co-authored-by: caveman99 <25002+caveman99@users.noreply.github.com>
2024-10-26 15:51:28 +02:00
Thomas Göttgens
adf1bc4b0e fix tracker build (#5151)
fix tracker 1000 build
2024-10-26 14:40:10 +02:00
github-actions[bot]
ea63f035d1 [create-pull-request] automated change (#5137)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
2024-10-26 12:07:07 +02:00
Tom Fifield
e394bc6f8f De-duplicate log-level determination (#5148)
RedirectablePrint had a method, getLogLevel, which did exactly
what code in SerialConsole did. Let's use that method rather than
duplicating the code.
2024-10-26 12:06:50 +02:00
Tom Fifield
a0e468b16e Remove unused AXP debug code (#5149)
This was shuffled around a couple years ago, but hasn't been used
since, and we had two copies in the code. Delete it.
2024-10-26 12:04:46 +02:00
Thomas Göttgens
93318b4f56 T1000-E Peripherals (#5141)
* T1000-E Peripherals
- enable intelligent charge controller signals
- enable Accelerometer
- enable internal I2C bus
- provide Power to Accelerometer

* POC Accelerometer Code (wakeScreen is moot for that device, just test if the driver works)
* fix building without the sensor
2024-10-26 12:03:28 +02:00
Mark Trevor Birss
0c0da3909f Update variant.h (#5140) 2024-10-25 08:07:01 +10:00
Manuel
701293c2d3 fix missing includes (#5138) 2024-10-24 21:58:24 +02:00
github-actions[bot]
6485f037ec [create-pull-request] automated change (#5133)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
2024-10-23 21:21:49 -05:00
Ben Meadors
ca5f71f774 Add device unique id (#5092)
* Add device unique id

* Trunk

* WIP

* Esp32 implementation

* Trunk

* Check for ESP_EFUSE_OPTIONAL_UNIQUE_ID

* Comment print

* Trunk
2024-10-23 21:18:37 -05:00
panaceya
57667f1028 ADD: Configurable UPLINK_ENABLED and DOWNLINK_ENABLED in userPrefs.h (#5120) 2024-10-23 05:26:44 -05:00
Craig Bailey
3f1c86f953 Update meshtasticd.service (#5118)
Adding restart on service failure with 3 seconds between restart to stop fasst restart loops. Adding StartLimitBurst to limit it to 5 restarts in 200 seconds.
2024-10-22 16:22:10 -05:00
github-actions[bot]
4416ac57cf [create-pull-request] automated change (#5124)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
2024-10-21 16:06:56 -05:00
Robert
a4705d2c19 add RFC 3927 IP address space to private IP checks (#5115)
Add the RFC 3927 IP address block (169.254.0.0/16), also referred to as IPIPA, to the private address checks for MQTT functionality.
2024-10-21 19:25:27 +11:00
aussieklutz
5ff8c904c8 MPR121 Touch IC Based Keypad Input Module (#5103)
Implements an input driver utilising the MPR121 Touch IC and is compatible with common MPR121 keypad PCB's.

- Implements a "candybar" phone style 12-key keypad
  - multiple taps to rotate through the character set
  - longpress for navigation keys
  - keymap to allow arbitrary routing of MPR121 pin to button configuration
  - extendable to other key functions
- Integrates with the existing kbI2cBase implementation
- Works with CannedMessageModule Freetext mode
- Can be used with common MPR121 boards, such as https://www.amazon.com/MPR121-Capacitive-Keyboard-Buttons-Sensitive/dp/B083R89CHB/ref=sr_1_6
- Of use for PCB based radios, where some form of low surface area low component freetext input is required, but also without consuming too many IO pins.
- Tested on a T3S3 connected to Wire1 (Second) interface.
  - Demonstration of functionality: https://youtu.be/UI6QP6nGvhY
2024-10-21 17:53:36 +11:00
GUVWAF
09c8642aa6 Fix rebroadcasting encrypted packets when KNOWN_ONLY or LOCAL_ONLY is used (#5109) 2024-10-20 17:04:45 -05:00
Thomas Göttgens
82bcd503a3 Merge pull request #5112 from meshtastic/preamble-length
Wide_Lora uses 12 symbols to be compatible with SX1280
2024-10-20 22:06:06 +02:00
Thomas Göttgens
18ca5b4449 Wide_Lora uses 12 symbols to be compatible with SX1280 2024-10-20 21:54:07 +02:00
Tom Fifield
2ba72c154a Fix GPS_DEBUG output (#5100)
After the recent change to move logging line breaks to a central
location, GPS_DEBUG is now emitting one character per line,
making the logs unusable.

Patch uses local strings and appends to collate and then print
in the right places.

Fixes https://github.com/meshtastic/firmware/issues/5099

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2024-10-20 04:46:25 -05:00
Ben Meadors
7e3931b05d Move 115200 baud GNSS probe earlier (#5101)
* Move 115200 baud GNSS probe earlier

* Even more optimized!
2024-10-19 20:05:52 -05:00
Ben Meadors
4575352d8c Initial NODENUM_BROADCAST_NO_LORA implementation with NeighborInfo module (#5087)
* Initial NODENUM_BROADCAST_NO_LORA implementation with NeighborInfo module

* isBroadcast

* Trunkt
2024-10-19 12:48:00 -05:00
Thomas Göttgens
b1b6bce6b7 Merge pull request #5095 from meshtastic/revert-5036-caveman99-patch-1
Revert "Permanently engage !CTRL"
2024-10-19 19:06:33 +02:00
Thomas Göttgens
304f26b909 Revert "Permanently engage !CTRL" 2024-10-19 19:01:58 +02:00
madeofstown
a27f9fcdbd Add -p flag (#5093)
Add the `-p` to the `mkdir` so it doesn't fail when the folder already exists

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2024-10-18 20:19:24 -05:00
Jonathan Bennett
dfeb33d46e Add DIO2_AS_RF_SWITCH to pinedio prefilled config. 2024-10-18 12:30:46 -05:00
github-actions[bot]
b8b6894d58 [create-pull-request] automated change (#5091)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
2024-10-18 06:00:55 -05:00
Technologyman00
934be69663 Add buzzer feedback on GPS toggle (#5090)
Triple Press on buttons toggles GPS enable/disable.

This enhancement plays a triple-beep so that users of devices with buzzers can get audible feedback about whether they have turned the GPS off or on. This is especially valuable for screenless devices such as the T1000E where it may not be immediately obvious the GPS has been disabled.
2024-10-18 14:40:18 +11:00
Ben Meadors
ec9e562a77 Coerce minimum telemetry interval of 30 minutes on defaults and make new default interval one hour (#5086)
* Coerce minimum telemetry interval of 30 minutes on defaults and make new default interval one hour

* Smaller log messages
2024-10-17 13:33:52 -05:00
Johnathon Mohr
fbb6778415 Account for port specification with IP address for MQTT server. Some additional format validation. (#5084) 2024-10-17 05:05:35 -05:00
github-actions[bot]
2ea2b47690 [create-pull-request] automated change (#5085)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
2024-10-16 19:51:11 -05:00
Ben Meadors
f77c87dca8 Extra extra 2024-10-16 09:18:44 -05:00
Ben Meadors
198b62f3fc I thought these were already board level extra 2024-10-16 07:34:24 -05:00
Johnathon Mohr
3e5f129fce Ensure the MQTT address is an IPv4 before determining it's private (#5081)
* Ensure the mqtt address is an IPv4 (or at least not a domain) before determining it's private.

* check address length
2024-10-16 05:19:00 -05:00
Johnathon Mohr
ad214ea42a Add MQTT exception for private IP address server (#5072)
Determines if the given IP address is a private address, i.e. not routable on the public internet.
These are the ranges: 127.0.0.1, 10.0.0.0-10.255.255.255, 172.16.0.0-172.31.255.255, 192.168.0.0-192.168.255.255.

If so, allow MQTT publication the same as existing localhost support.
2024-10-16 11:08:49 +11:00
Jeff Epler
25b557cf46 Fix incorrect va_start calls (#5076) 2024-10-15 17:15:10 -05:00
github-actions[bot]
7fd1c334d3 [create-pull-request] automated change (#5074)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
2024-10-15 09:15:15 -05:00
Tavis
696bcc60af Ws85 updates : set want_ack, high_priority, add temperature. (#5052)
* ws85 updates

add temperature
add wantack
add high_priority

set lull to 0 if never set.

add the has_FIELD_NAME lines to ws85

* pbufs sync

* high insteaed of max reliability

* only set want_ack and high reliable if sensor_role set

* protobufs

---------

Co-authored-by: Tom Fifield <tom@tomfifield.net>
2024-10-15 05:09:18 -05:00
Andre K
af0db8a29f retain fixed_position during reset-nodedb (#5067) 2024-10-14 19:32:25 -05:00
Thomas Göttgens
ea20bb1836 Merge pull request #5061 from meshtastic/oem-proto
drop oem.proto support in favor of userprefs
2024-10-14 21:49:14 +02:00
Ben Meadors
420ab89f8d Merge branch 'master' into oem-proto 2024-10-14 14:10:31 -05:00
github-actions[bot]
1212969ff7 [create-pull-request] automated change (#5062)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
2024-10-14 14:10:19 -05:00
Thomas Göttgens
e49e584ae1 drop oem.proto support in favor of userprefs 2024-10-14 19:39:07 +02:00
Tom
89c1e041e1 Add in RF95 support to Pro-micro DIY (#5055)
* Add in RF95 support

Added in lines to enable RF95 modules. Tested on SX1262 by NomDeTom/ @Nestpebble . Tested with RA02 by Ludovic / @lboue

* Trunk
2024-10-14 07:59:38 -05:00
github-actions[bot]
655e58f424 [create-pull-request] automated change (#5058)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
2024-10-14 07:49:58 -05:00
Ludovic BOUÉ
0ec1684718 [Board]: Support for M5Stack CoreS3 (Part 1: radio) (#5049) 2024-10-14 19:13:22 +11:00
Thomas Göttgens
05e4a639a1 remove newline from logging statements. (#5022)
remove newline from logging statements in code. The LOG_* functions will now magically add it at the end.

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2024-10-14 15:11:43 +11:00
Ben Meadors
fb9f361052 Implement rebroadcast mode NONE (#5040)
* Implement rebroadcast mode none

* Correct debug message
2024-10-12 06:17:44 -05:00
github-actions[bot]
37448205b5 [create-pull-request] automated change (#5041)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
2024-10-12 06:16:53 -05:00
Thomas Göttgens
015f7335b0 enable native build stage 2024-10-12 10:34:22 +02:00
Thomas Göttgens
48d8b85a3b Merge pull request #5036 from meshtastic/caveman99-patch-1
Permanently engage !CTRL
2024-10-12 10:26:23 +02:00
mverch67
363fd8ab98 fix GPIO0 mode after I2S audio 2024-10-12 10:24:41 +02:00
Thomas Göttgens
323e7503ea trunk fmt 2024-10-12 07:09:21 +08:00
Thomas Göttgens
4e4431560e Permanently engage !CTRL
switching RXEN is not fast enough and not in sync with DIO2. This pin needs to be permanently encabled, like on RAK4631.
2024-10-12 07:09:21 +08:00
Jonathan Bennett
a8c216f4f8 Update main_matrix.yml -- re-enable x86_64 .deb builds 2024-10-11 16:41:41 -05:00
github-actions[bot]
9d0729c83f [create-pull-request] automated change (#5034)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
2024-10-11 06:29:30 -05:00
Thomas Göttgens
3c89716074 Merge pull request #5033 from markbirss/master
Fix SH1107 - Set Geometry 128x128
2024-10-11 13:05:53 +02:00
Mark Trevor Birss
ec96256bcd Update main.cpp 2024-10-11 11:39:37 +02:00
Ben Meadors
1f2d972e18 Remove waypoint and text message frames on NodeDB reset as well (#5029) 2024-10-10 19:24:37 -05:00
github-actions[bot]
cc87002a8a [create-pull-request] automated change (#5028)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
2024-10-10 18:31:20 -05:00
github-actions[bot]
8ab772221d [create-pull-request] automated change (#5027)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
2024-10-10 18:29:29 -05:00
226 changed files with 4457 additions and 2541 deletions

View File

@@ -134,8 +134,8 @@ jobs:
package-raspbian-armv7l:
uses: ./.github/workflows/package_raspbian_armv7l.yml
# package-native:
# uses: ./.github/workflows/package_amd64.yml
package-native:
uses: ./.github/workflows/package_amd64.yml
after-checks:
runs-on: ubuntu-latest
@@ -245,11 +245,12 @@ jobs:
if: ${{ github.event_name == 'workflow_dispatch' }}
outputs:
upload_url: ${{ steps.create_release.outputs.upload_url }}
needs: [
needs:
[
gather-artifacts,
package-raspbian,
package-raspbian-armv7l,
# package-native,
package-native,
]
steps:
- name: Checkout
@@ -308,15 +309,15 @@ jobs:
asset_name: meshtasticd_${{ steps.version.outputs.version }}_armhf.deb
asset_content_type: application/vnd.debian.binary-package
# - name: Add raspbian amd64 .deb
# uses: actions/upload-release-asset@v1
# env:
# GITHUB_TOKEN: ${{ github.token }}
# with:
# upload_url: ${{ steps.create_release.outputs.upload_url }}
# asset_path: ./output/meshtasticd_${{ steps.version.outputs.version }}_amd64.deb
# asset_name: meshtasticd_${{ steps.version.outputs.version }}_amd64.deb
# asset_content_type: application/vnd.debian.binary-package
- name: Add raspbian amd64 .deb
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ github.token }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./output/meshtasticd_${{ steps.version.outputs.version }}_amd64.deb
asset_name: meshtasticd_${{ steps.version.outputs.version }}_amd64.deb
asset_content_type: application/vnd.debian.binary-package
- name: Bump version.properties
run: >-

View File

@@ -50,11 +50,14 @@ jobs:
mkdir -p .debpkg/usr/share/doc/meshtasticd/web
mkdir -p .debpkg/usr/sbin
mkdir -p .debpkg/etc/meshtasticd
mkdir -p .debpkg/etc/meshtasticd/config.d
mkdir -p .debpkg/etc/meshtasticd/available.d
mkdir -p .debpkg/usr/lib/systemd/system/
tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web
gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz
cp release/meshtasticd_linux_x86_64 .debpkg/usr/sbin/meshtasticd
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml
cp bin/config.d/* .debpkg/etc/meshtasticd/available.d/
chmod +x .debpkg/usr/sbin/meshtasticd
cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service
echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles

View File

@@ -50,11 +50,14 @@ jobs:
mkdir -p .debpkg/usr/share/doc/meshtasticd/web
mkdir -p .debpkg/usr/sbin
mkdir -p .debpkg/etc/meshtasticd
mkdir -p .debpkg/etc/meshtasticd/config.d
mkdir -p .debpkg/etc/meshtasticd/available.d
mkdir -p .debpkg/usr/lib/systemd/system/
tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web
gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz
cp release/meshtasticd_linux_aarch64 .debpkg/usr/sbin/meshtasticd
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml
cp bin/config.d/* .debpkg/etc/meshtasticd/available.d/
chmod +x .debpkg/usr/sbin/meshtasticd
cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service
echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles

View File

@@ -50,11 +50,14 @@ jobs:
mkdir -p .debpkg/usr/share/doc/meshtasticd/web
mkdir -p .debpkg/usr/sbin
mkdir -p .debpkg/etc/meshtasticd
mkdir -p .debpkg/etc/meshtasticd/config.d
mkdir -p .debpkg/etc/meshtasticd/available.d
mkdir -p .debpkg/usr/lib/systemd/system/
tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web
gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz
cp release/meshtasticd_linux_armv7l .debpkg/usr/sbin/meshtasticd
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml
cp bin/config.d/* .debpkg/etc/meshtasticd/available.d/
chmod +x .debpkg/usr/sbin/meshtasticd
cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service
echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles

21
.github/workflows/stale_bot.yml vendored Normal file
View File

@@ -0,0 +1,21 @@
name: process stale Issues and PR's
on:
schedule:
- cron: 0 6 * * *
workflow_dispatch: {}
permissions:
issues: write
pull-requests: write
jobs:
stale_issues:
name: Close Stale Issues
runs-on: ubuntu-latest
steps:
- name: Stale PR+Issues
uses: actions/stale@v9.0.0
with:
exempt-issue-labels: pinned,3.0
exempt-pr-labels: pinned,3.0

43
.github/workflows/trunk_format_pr.yml vendored Normal file
View File

@@ -0,0 +1,43 @@
name: Run Trunk Fmt on PR Comment
on:
issue_comment:
types: [created]
jobs:
trunk-fmt:
if: github.event.issue.pull_request != null && contains(github.event.comment.body, 'trunk fmt')
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Install trunk
run: curl https://get.trunk.io -fsSL | bash
- name: Run Trunk Fmt
run: trunk fmt
- name: Commit and push changes
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git add .
git commit -m "Add firmware version ${{ steps.version.outputs.version }}"
git push
- name: Comment on PR
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
github.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '`trunk fmt` has been run on this PR.'
})

View File

@@ -1,22 +1,22 @@
version: 0.1
cli:
version: 1.22.6
version: 1.22.7
plugins:
sources:
- id: trunk
ref: v1.6.3
ref: v1.6.4
uri: https://github.com/trunk-io/plugins
lint:
enabled:
- trufflehog@3.82.6
- trufflehog@3.83.2
- yamllint@1.35.1
- bandit@1.7.10
- checkov@3.2.256
- terrascan@1.19.1
- trivy@0.55.2
- checkov@3.2.276
- terrascan@1.19.9
- trivy@0.56.2
#- trufflehog@3.63.2-rc0
- taplo@0.9.3
- ruff@0.6.8
- ruff@0.7.1
- isort@5.13.2
- markdownlint@0.42.0
- oxipng@9.1.2
@@ -26,9 +26,9 @@ lint:
- hadolint@2.12.0
- shfmt@3.6.0
- shellcheck@0.10.0
- black@24.8.0
- black@24.10.0
- git-diff-check
- gitleaks@8.20.0
- gitleaks@8.21.1
- clang-format@16.0.3
- prettier@3.3.3
ignore:

4
CODE_OF_CONDUCT.md Normal file
View File

@@ -0,0 +1,4 @@
# Contributor Covenant Code of Conduct
The Meshtastic Firmware project is subject to the code of conduct for the parent project, which can be found here:
https://meshtastic.org/docs/legal/conduct/

View File

@@ -31,7 +31,7 @@ build_flags =
-DCONFIG_BT_NIMBLE_ENABLED
-DCONFIG_NIMBLE_CPP_LOG_LEVEL=2
-DCONFIG_BT_NIMBLE_MAX_CCCDS=20
-DCONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=5120
-DCONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=8192
-DESP_OPENSSL_SUPPRESS_LEGACY_WARNING
-DSERIAL_BUFFER_SIZE=4096
-DLIBPAX_ARDUINO

View File

@@ -23,4 +23,5 @@ lib_deps=
rweather/Crypto@^0.4.0
lib_ignore =
BluetoothOTA
BluetoothOTA
lvgl

View File

@@ -24,7 +24,7 @@ lib_deps =
${env.lib_deps}
${networking_base.lib_deps}
rweather/Crypto@^0.4.0
lovyan03/LovyanGFX@^1.1.16
https://github.com/lovyan03/LovyanGFX.git#1401c28a47646fe00538d487adcb2eb3c72de805
build_flags =
${arduino_base.build_flags}

View File

@@ -16,8 +16,9 @@ build_src_filter =
lib_ignore =
BluetoothOTA
lvgl
lib_deps =
${arduino_base.lib_deps}
${environmental_base.lib_deps}
rweather/Crypto
rweather/Crypto

View File

@@ -1,15 +1,11 @@
### Many device configs have been moved to /etc/meshtasticd/available.d
### To activate, simply copy or link the appropriate file into /etc/meshtasticd/config.d
### Define your devices here using Broadcom pin numbering
### Uncomment the block that corresponds to your hardware
### Including the "Module:" line!
---
Lora:
# Module: sx1262 # Waveshare SX126X XXXM
# DIO2_AS_RF_SWITCH: true
# CS: 21
# IRQ: 16
# Busy: 20
# Reset: 18
# SX126X_ANT_SW: 6
# Module: sx1262 # Waveshare SX1302 LISTEN ONLY AT THIS TIME!
# CS: 7
@@ -20,6 +16,7 @@ Lora:
# CS: 0
# IRQ: 10
# Busy: 11
# DIO2_AS_RF_SWITCH: true
# spidev: spidev0.1
# Module: RF95 # Adafruit RFM9x
@@ -114,6 +111,29 @@ Display:
# Height: 320
# Rotate: true
### SHCHV 3.5 RPi TFT+Touchscreen
# Panel: ILI9486
# spidev: spidev0.0
# BusFrequency: 30000000
# DC: 24
# Reset: 25
# Width: 320
# Height: 480
# OffsetRotate: 2
### TZT 2.0 Inch TFT Display ST7789V 240RGBx320
# Panel: ST7789
# spidev: spidev0.0
# # CS: 8 # can be freely chosen
# BusFrequency: 80000000
# DC: 24 # can be freely chosen
# Width: 320
# Height: 240
# Reset: 25 # can be freely chosen
# Rotate: true
# OffsetRotate: 1
# Invert: true
### You can also specify the spi device for the display to use
# spidev: spidev0.0
@@ -154,4 +174,5 @@ Webserver:
General:
MaxNodes: 200
MaxMessageQueue: 100
MaxMessageQueue: 100
ConfigDirectory: /etc/meshtasticd/config.d/

View File

@@ -0,0 +1,18 @@
Display:
### Waveshare 2.8inch RPi LCD
Panel: ST7789
CS: 8
DC: 22 # Data/Command pin
Backlight: 18
Width: 240
Height: 320
Reset: 27
Rotate: true
Invert: true
Touchscreen:
### Note, at least for now, the touchscreen must have a CS pin defined, even if you let Linux manage the CS switching.
Module: XPT2046 # Waveshare 2.8inch
CS: 7
IRQ: 17

View File

@@ -0,0 +1,8 @@
Lora:
Module: sx1262 # Waveshare SX126X XXXM
DIO2_AS_RF_SWITCH: true
CS: 21
IRQ: 16
Busy: 20
Reset: 18
SX126X_ANT_SW: 6

View File

@@ -1,12 +1,16 @@
[Unit]
Description=Meshtastic Native Daemon
After=network-online.target
StartLimitInterval=200
StartLimitBurst=5
[Service]
User=root
Group=root
Type=simple
ExecStart=/usr/sbin/meshtasticd
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
WantedBy=multi-user.target

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
cp "release/meshtasticd_linux_$(uname -m)" /usr/sbin/meshtasticd
mkdir /etc/meshtasticd
mkdir -p /etc/meshtasticd
if [[ -f "/etc/meshtasticd/config.yaml" ]]; then
cp bin/config-dist.yaml /etc/meshtasticd/config-upgrade.yaml
else

View File

@@ -28,6 +28,8 @@
"flash_size": "8MB",
"maximum_ram_size": 327680,
"maximum_size": 8388608,
"use_1200bps_touch": true,
"wait_for_upload_port": true,
"require_upload_port": true,
"speed": 921600
},

41
boards/icarus.json Normal file
View File

@@ -0,0 +1,41 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"memory_type": "qio_opi"
},
"core": "esp32",
"extra_flags": [
"-DBOARD_HAS_PSRAM",
"-DARDUINO_USB_CDC_ON_BOOT=1",
"-DARDUINO_USB_MODE=0",
"-DARDUINO_RUNNING_CORE=1",
"-DARDUINO_EVENT_RUNNING_CORE=0"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"hwids": [["0x2886", "0x0059"]],
"mcu": "esp32s3",
"variant": "icarus"
},
"connectivity": ["wifi", "bluetooth", "lora"],
"debug": {
"default_tool": "esp-builtin",
"onboard_tools": ["esp-builtin"],
"openocd_target": "esp32s3.cfg"
},
"frameworks": ["arduino", "espidf"],
"name": "icarus",
"upload": {
"flash_size": "8MB",
"maximum_ram_size": 8388608,
"maximum_size": 8388608,
"use_1200bps_touch": true,
"wait_for_upload_port": true,
"require_upload_port": true,
"speed": 921600
},
"url": "https://icarus.azlan.works",
"vendor": "Muhammad Shah"
}

46
boards/unphone.json Normal file
View File

@@ -0,0 +1,46 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"memory_type": "qio_opi",
"partitions": "default_8MB.csv"
},
"core": "esp32",
"extra_flags": [
"-DBOARD_HAS_PSRAM",
"-DUNPHONE_SPIN=9",
"-DARDUINO_USB_CDC_ON_BOOT=1",
"-DARDUINO_USB_MODE=0",
"-DARDUINO_RUNNING_CORE=1",
"-DARDUINO_EVENT_RUNNING_CORE=1"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"hwids": [
["0x16D0", "0x1178"],
["0x303a", "0x1001"]
],
"mcu": "esp32s3",
"variant": "unphone"
},
"connectivity": ["wifi", "bluetooth", "lora"],
"debug": {
"default_tool": "esp-builtin",
"onboard_tools": ["esp-builtin"],
"openocd_target": "esp32s3.cfg"
},
"frameworks": ["arduino", "espidf"],
"name": "unPhone",
"upload": {
"flash_size": "8MB",
"maximum_ram_size": 327680,
"maximum_size": 8323072,
"use_1200bps_touch": true,
"wait_for_upload_port": true,
"require_upload_port": true,
"speed": 921600
},
"url": "https://unphone.net/",
"vendor": "University of Sheffield"
}

View File

@@ -96,7 +96,7 @@ lib_deps =
https://github.com/meshtastic/ArduinoThread.git#1ae8778c85d0a2a729f989e0b1e7d7c4dc84eef0
nanopb/Nanopb@^0.4.9
erriez/ErriezCRC32@^1.0.1
; Used for the code analysis in PIO Home / Inspect
check_tool = cppcheck
check_skip_packages = yes

View File

@@ -42,18 +42,18 @@ class AmbientLightingThread : public concurrency::OSThread
#ifdef HAS_NCP5623
_type = type;
if (_type == ScanI2C::DeviceType::NONE) {
LOG_DEBUG("AmbientLightingThread disabling due to no RGB leds found on I2C bus\n");
LOG_DEBUG("AmbientLightingThread disabling due to no RGB leds found on I2C bus");
disable();
return;
}
#endif
#if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
if (!moduleConfig.ambient_lighting.led_state) {
LOG_DEBUG("AmbientLightingThread disabling due to moduleConfig.ambient_lighting.led_state OFF\n");
LOG_DEBUG("AmbientLightingThread disabling due to moduleConfig.ambient_lighting.led_state OFF");
disable();
return;
}
LOG_DEBUG("AmbientLightingThread initializing\n");
LOG_DEBUG("AmbientLightingThread initializing");
#ifdef HAS_NCP5623
if (_type == ScanI2C::NCP5623) {
rgb.begin();
@@ -106,27 +106,27 @@ class AmbientLightingThread : public concurrency::OSThread
rgb.setRed(0);
rgb.setGreen(0);
rgb.setBlue(0);
LOG_INFO("Turn Off NCP5623 Ambient lighting.\n");
LOG_INFO("Turn Off NCP5623 Ambient lighting.");
#endif
#ifdef HAS_NEOPIXEL
pixels.clear();
pixels.show();
LOG_INFO("Turn Off NeoPixel Ambient lighting.\n");
LOG_INFO("Turn Off NeoPixel Ambient lighting.");
#endif
#ifdef RGBLED_CA
analogWrite(RGBLED_RED, 255 - 0);
analogWrite(RGBLED_GREEN, 255 - 0);
analogWrite(RGBLED_BLUE, 255 - 0);
LOG_INFO("Turn Off Ambient lighting RGB Common Anode.\n");
LOG_INFO("Turn Off Ambient lighting RGB Common Anode.");
#elif defined(RGBLED_RED)
analogWrite(RGBLED_RED, 0);
analogWrite(RGBLED_GREEN, 0);
analogWrite(RGBLED_BLUE, 0);
LOG_INFO("Turn Off Ambient lighting RGB Common Cathode.\n");
LOG_INFO("Turn Off Ambient lighting RGB Common Cathode.");
#endif
#ifdef UNPHONE
unphone.rgb(0, 0, 0);
LOG_INFO("Turn Off unPhone Ambient lighting.\n");
LOG_INFO("Turn Off unPhone Ambient lighting.");
#endif
return 0;
}
@@ -138,7 +138,7 @@ class AmbientLightingThread : public concurrency::OSThread
rgb.setRed(moduleConfig.ambient_lighting.red);
rgb.setGreen(moduleConfig.ambient_lighting.green);
rgb.setBlue(moduleConfig.ambient_lighting.blue);
LOG_DEBUG("Initializing NCP5623 Ambient lighting w/ current=%d, red=%d, green=%d, blue=%d\n",
LOG_DEBUG("Initializing NCP5623 Ambient lighting w/ current=%d, red=%d, green=%d, blue=%d",
moduleConfig.ambient_lighting.current, moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green,
moduleConfig.ambient_lighting.blue);
#endif
@@ -158,7 +158,7 @@ class AmbientLightingThread : public concurrency::OSThread
#endif
#endif
pixels.show();
LOG_DEBUG("Initializing NeoPixel Ambient lighting w/ brightness(current)=%d, red=%d, green=%d, blue=%d\n",
LOG_DEBUG("Initializing NeoPixel Ambient lighting w/ brightness(current)=%d, red=%d, green=%d, blue=%d",
moduleConfig.ambient_lighting.current, moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green,
moduleConfig.ambient_lighting.blue);
#endif
@@ -166,18 +166,18 @@ class AmbientLightingThread : public concurrency::OSThread
analogWrite(RGBLED_RED, 255 - moduleConfig.ambient_lighting.red);
analogWrite(RGBLED_GREEN, 255 - moduleConfig.ambient_lighting.green);
analogWrite(RGBLED_BLUE, 255 - moduleConfig.ambient_lighting.blue);
LOG_DEBUG("Initializing Ambient lighting RGB Common Anode w/ red=%d, green=%d, blue=%d\n",
LOG_DEBUG("Initializing Ambient lighting RGB Common Anode w/ red=%d, green=%d, blue=%d",
moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue);
#elif defined(RGBLED_RED)
analogWrite(RGBLED_RED, moduleConfig.ambient_lighting.red);
analogWrite(RGBLED_GREEN, moduleConfig.ambient_lighting.green);
analogWrite(RGBLED_BLUE, moduleConfig.ambient_lighting.blue);
LOG_DEBUG("Initializing Ambient lighting RGB Common Cathode w/ red=%d, green=%d, blue=%d\n",
LOG_DEBUG("Initializing Ambient lighting RGB Common Cathode w/ red=%d, green=%d, blue=%d",
moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue);
#endif
#ifdef UNPHONE
unphone.rgb(moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue);
LOG_DEBUG("Initializing unPhone Ambient lighting w/ red=%d, green=%d, blue=%d\n", moduleConfig.ambient_lighting.red,
LOG_DEBUG("Initializing unPhone Ambient lighting w/ red=%d, green=%d, blue=%d", moduleConfig.ambient_lighting.red,
moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue);
#endif
}

View File

@@ -36,7 +36,7 @@ ButtonThread::ButtonThread() : OSThread("Button")
#if defined(ARCH_PORTDUINO)
if (settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC) {
this->userButton = OneButton(settingsMap[user], true, true);
LOG_DEBUG("Using GPIO%02d for button\n", settingsMap[user]);
LOG_DEBUG("Using GPIO%02d for button", settingsMap[user]);
}
#elif defined(BUTTON_PIN)
int pin = config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN; // Resolved button pin
@@ -47,7 +47,7 @@ ButtonThread::ButtonThread() : OSThread("Button")
#else
this->userButton = OneButton(pin, true, true);
#endif
LOG_DEBUG("Using GPIO%02d for button\n", pin);
LOG_DEBUG("Using GPIO%02d for button", pin);
#endif
#ifdef INPUT_PULLUP_SENSE
@@ -123,7 +123,7 @@ int32_t ButtonThread::runOnce()
if (btnEvent != BUTTON_EVENT_NONE) {
switch (btnEvent) {
case BUTTON_EVENT_PRESSED: {
LOG_BUTTON("press!\n");
LOG_BUTTON("press!");
// If a nag notification is running, stop it and prevent other actions
if (moduleConfig.external_notification.enabled && (externalNotificationModule->nagCycleCutoff != UINT32_MAX)) {
externalNotificationModule->stopNow();
@@ -148,7 +148,7 @@ int32_t ButtonThread::runOnce()
}
case BUTTON_EVENT_DOUBLE_PRESSED: {
LOG_BUTTON("Double press!\n");
LOG_BUTTON("Double press!");
service->refreshLocalMeshNode();
auto sentPosition = service->trySendPosition(NODENUM_BROADCAST, true);
if (screen) {
@@ -162,7 +162,7 @@ int32_t ButtonThread::runOnce()
}
case BUTTON_EVENT_MULTI_PRESSED: {
LOG_BUTTON("Mulitipress! %hux\n", multipressClickCount);
LOG_BUTTON("Mulitipress! %hux", multipressClickCount);
switch (multipressClickCount) {
#if HAS_GPS
// 3 clicks: toggle GPS
@@ -189,7 +189,7 @@ int32_t ButtonThread::runOnce()
} // end multipress event
case BUTTON_EVENT_LONG_PRESSED: {
LOG_BUTTON("Long press!\n");
LOG_BUTTON("Long press!");
powerFSM.trigger(EVENT_PRESS);
if (screen) {
screen->startAlert("Shutting down...");
@@ -201,7 +201,7 @@ int32_t ButtonThread::runOnce()
// Do actual shutdown when button released, otherwise the button release
// may wake the board immediatedly.
case BUTTON_EVENT_LONG_RELEASED: {
LOG_INFO("Shutdown from long press\n");
LOG_INFO("Shutdown from long press");
playShutdownMelody();
delay(3000);
power->shutdown();
@@ -210,7 +210,7 @@ int32_t ButtonThread::runOnce()
#ifdef BUTTON_PIN_TOUCH
case BUTTON_EVENT_TOUCH_LONG_PRESSED: {
LOG_BUTTON("Touch press!\n");
LOG_BUTTON("Touch press!");
if (screen) {
// Wake if asleep
if (powerFSM.getState() == &stateDARK)

View File

@@ -53,7 +53,7 @@ bool lfs_assert_failed =
extern "C" void lfs_assert(const char *reason)
{
LOG_ERROR("LFS assert: %s\n", reason);
LOG_ERROR("LFS assert: %s", reason);
lfs_assert_failed = true;
}
@@ -75,19 +75,19 @@ bool copyFile(const char *from, const char *to)
r = OSFS::getFile(from, cbuffer);
if (r == notfound) {
LOG_ERROR("Failed to open source file %s\n", from);
LOG_ERROR("Failed to open source file %s", from);
return false;
} else if (r == noerr) {
r = OSFS::newFile(to, cbuffer, true);
if (r == noerr) {
return true;
} else {
LOG_ERROR("OSFS Error %d\n", r);
LOG_ERROR("OSFS Error %d", r);
return false;
}
} else {
LOG_ERROR("OSFS Error %d\n", r);
LOG_ERROR("OSFS Error %d", r);
return false;
}
return true;
@@ -97,13 +97,13 @@ bool copyFile(const char *from, const char *to)
File f1 = FSCom.open(from, FILE_O_READ);
if (!f1) {
LOG_ERROR("Failed to open source file %s\n", from);
LOG_ERROR("Failed to open source file %s", from);
return false;
}
File f2 = FSCom.open(to, FILE_O_WRITE);
if (!f2) {
LOG_ERROR("Failed to open destination file %s\n", to);
LOG_ERROR("Failed to open destination file %s", to);
return false;
}
@@ -231,7 +231,7 @@ void listDir(const char *dirname, uint8_t levels, bool del)
#ifdef ARCH_ESP32
listDir(file.path(), levels - 1, del);
if (del) {
LOG_DEBUG("Removing %s\n", file.path());
LOG_DEBUG("Removing %s", file.path());
strncpy(buffer, file.path(), sizeof(buffer));
file.close();
FSCom.rmdir(buffer);
@@ -241,7 +241,7 @@ void listDir(const char *dirname, uint8_t levels, bool del)
#elif (defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
listDir(file.name(), levels - 1, del);
if (del) {
LOG_DEBUG("Removing %s\n", file.name());
LOG_DEBUG("Removing %s", file.name());
strncpy(buffer, file.name(), sizeof(buffer));
file.close();
FSCom.rmdir(buffer);
@@ -249,7 +249,7 @@ void listDir(const char *dirname, uint8_t levels, bool del)
file.close();
}
#else
LOG_DEBUG(" %s (directory)\n", file.name());
LOG_DEBUG(" %s (directory)", file.name());
listDir(file.name(), levels - 1, del);
file.close();
#endif
@@ -257,26 +257,26 @@ void listDir(const char *dirname, uint8_t levels, bool del)
} else {
#ifdef ARCH_ESP32
if (del) {
LOG_DEBUG("Deleting %s\n", file.path());
LOG_DEBUG("Deleting %s", file.path());
strncpy(buffer, file.path(), sizeof(buffer));
file.close();
FSCom.remove(buffer);
} else {
LOG_DEBUG(" %s (%i Bytes)\n", file.path(), file.size());
LOG_DEBUG(" %s (%i Bytes)", file.path(), file.size());
file.close();
}
#elif (defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
if (del) {
LOG_DEBUG("Deleting %s\n", file.name());
LOG_DEBUG("Deleting %s", file.name());
strncpy(buffer, file.name(), sizeof(buffer));
file.close();
FSCom.remove(buffer);
} else {
LOG_DEBUG(" %s (%i Bytes)\n", file.name(), file.size());
LOG_DEBUG(" %s (%i Bytes)", file.name(), file.size());
file.close();
}
#else
LOG_DEBUG(" %s (%i Bytes)\n", file.name(), file.size());
LOG_DEBUG(" %s (%i Bytes)", file.name(), file.size());
file.close();
#endif
}
@@ -284,7 +284,7 @@ void listDir(const char *dirname, uint8_t levels, bool del)
}
#ifdef ARCH_ESP32
if (del) {
LOG_DEBUG("Removing %s\n", root.path());
LOG_DEBUG("Removing %s", root.path());
strncpy(buffer, root.path(), sizeof(buffer));
root.close();
FSCom.rmdir(buffer);
@@ -293,7 +293,7 @@ void listDir(const char *dirname, uint8_t levels, bool del)
}
#elif (defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
if (del) {
LOG_DEBUG("Removing %s\n", root.name());
LOG_DEBUG("Removing %s", root.name());
strncpy(buffer, root.name(), sizeof(buffer));
root.close();
FSCom.rmdir(buffer);
@@ -329,13 +329,13 @@ void fsInit()
{
#ifdef FSCom
if (!FSBegin()) {
LOG_ERROR("Filesystem mount Failed.\n");
LOG_ERROR("Filesystem mount Failed.");
// assert(0); This auto-formats the partition, so no need to fail here.
}
#if defined(ARCH_ESP32)
LOG_DEBUG("Filesystem files (%d/%d Bytes):\n", FSCom.usedBytes(), FSCom.totalBytes());
LOG_DEBUG("Filesystem files (%d/%d Bytes):", FSCom.usedBytes(), FSCom.totalBytes());
#else
LOG_DEBUG("Filesystem files:\n");
LOG_DEBUG("Filesystem files:");
#endif
listDir("/", 10);
#endif
@@ -350,28 +350,28 @@ void setupSDCard()
SDHandler.begin(SPI_SCK, SPI_MISO, SPI_MOSI);
if (!SD.begin(SDCARD_CS, SDHandler)) {
LOG_DEBUG("No SD_MMC card detected\n");
LOG_DEBUG("No SD_MMC card detected");
return;
}
uint8_t cardType = SD.cardType();
if (cardType == CARD_NONE) {
LOG_DEBUG("No SD_MMC card attached\n");
LOG_DEBUG("No SD_MMC card attached");
return;
}
LOG_DEBUG("SD_MMC Card Type: ");
if (cardType == CARD_MMC) {
LOG_DEBUG("MMC\n");
LOG_DEBUG("MMC");
} else if (cardType == CARD_SD) {
LOG_DEBUG("SDSC\n");
LOG_DEBUG("SDSC");
} else if (cardType == CARD_SDHC) {
LOG_DEBUG("SDHC\n");
LOG_DEBUG("SDHC");
} else {
LOG_DEBUG("UNKNOWN\n");
LOG_DEBUG("UNKNOWN");
}
uint64_t cardSize = SD.cardSize() / (1024 * 1024);
LOG_DEBUG("SD Card Size: %lu MB\n", (uint32_t)cardSize);
LOG_DEBUG("Total space: %lu MB\n", (uint32_t)(SD.totalBytes() / (1024 * 1024)));
LOG_DEBUG("Used space: %lu MB\n", (uint32_t)(SD.usedBytes() / (1024 * 1024)));
LOG_DEBUG("SD Card Size: %lu MB", (uint32_t)cardSize);
LOG_DEBUG("Total space: %lu MB", (uint32_t)(SD.totalBytes() / (1024 * 1024)));
LOG_DEBUG("Used space: %lu MB", (uint32_t)(SD.usedBytes() / (1024 * 1024)));
#endif
}

View File

@@ -51,7 +51,7 @@ class GPSStatus : public Status
{
if (config.position.fixed_position) {
#ifdef GPS_EXTRAVERBOSE
LOG_WARN("Using fixed latitude\n");
LOG_WARN("Using fixed latitude");
#endif
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum());
return node->position.latitude_i;
@@ -64,7 +64,7 @@ class GPSStatus : public Status
{
if (config.position.fixed_position) {
#ifdef GPS_EXTRAVERBOSE
LOG_WARN("Using fixed longitude\n");
LOG_WARN("Using fixed longitude");
#endif
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum());
return node->position.longitude_i;
@@ -77,7 +77,7 @@ class GPSStatus : public Status
{
if (config.position.fixed_position) {
#ifdef GPS_EXTRAVERBOSE
LOG_WARN("Using fixed altitude\n");
LOG_WARN("Using fixed altitude");
#endif
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum());
return node->position.altitude;
@@ -95,7 +95,7 @@ class GPSStatus : public Status
bool matches(const GPSStatus *newStatus) const
{
#ifdef GPS_EXTRAVERBOSE
LOG_DEBUG("GPSStatus.match() new pos@%x to old pos@%x\n", newStatus->p.timestamp, p.timestamp);
LOG_DEBUG("GPSStatus.match() new pos@%x to old pos@%x", newStatus->p.timestamp, p.timestamp);
#endif
return (newStatus->hasLock != hasLock || newStatus->isConnected != isConnected ||
newStatus->isPowerSaving != isPowerSaving || newStatus->p.latitude_i != p.latitude_i ||
@@ -112,7 +112,7 @@ class GPSStatus : public Status
if (isDirty && p.timestamp && (newStatus->p.timestamp == p.timestamp)) {
// We can NEVER be in two locations at the same time! (also PR #886)
LOG_ERROR("BUG: Positional timestamp unchanged from prev solution\n");
LOG_ERROR("BUG: Positional timestamp unchanged from prev solution");
}
initialized = true;
@@ -124,11 +124,11 @@ class GPSStatus : public Status
if (isDirty) {
if (hasLock) {
// In debug logs, identify position by @timestamp:stage (stage 3 = notify)
LOG_DEBUG("New GPS pos@%x:3 lat=%f lon=%f alt=%d pdop=%.2f track=%.2f speed=%.2f sats=%d\n", p.timestamp,
LOG_DEBUG("New GPS pos@%x:3 lat=%f lon=%f alt=%d pdop=%.2f track=%.2f speed=%.2f sats=%d", p.timestamp,
p.latitude_i * 1e-7, p.longitude_i * 1e-7, p.altitude, p.PDOP * 1e-2, p.ground_track * 1e-5,
p.ground_speed * 1e-2, p.sats_in_view);
} else {
LOG_DEBUG("No GPS lock\n");
LOG_DEBUG("No GPS lock");
}
onNewStatus.notifyObservers(this);
}

View File

@@ -12,7 +12,7 @@ void GpioVirtPin::set(bool value)
void GpioHwPin::set(bool value)
{
// if (num == 3) LOG_DEBUG("Setting pin %d to %d\n", num, value);
// if (num == 3) LOG_DEBUG("Setting pin %d to %d", num, value);
pinMode(num, OUTPUT);
digitalWrite(num, value);
}
@@ -88,7 +88,7 @@ void GpioBinaryTransformer::update()
newValue = (GpioVirtPin::PinState)(p1 && p2);
break;
case Or:
// LOG_DEBUG("Doing GPIO OR\n");
// LOG_DEBUG("Doing GPIO OR");
newValue = (GpioVirtPin::PinState)(p1 || p2);
break;
case Xor:

View File

@@ -56,7 +56,7 @@ class NodeStatus : public Status
numTotal = newStatus->getNumTotal();
}
if (isDirty || newStatus->forceUpdate) {
LOG_DEBUG("Node status update: %d online, %d total\n", numOnline, numTotal);
LOG_DEBUG("Node status update: %d online, %d total", numOnline, numTotal);
onNewStatus.notifyObservers(this);
}
return 0;

View File

@@ -154,9 +154,16 @@ static void adcEnable()
#ifdef ADC_CTRL // enable adc voltage divider when we need to read
#ifdef ADC_USE_PULLUP
pinMode(ADC_CTRL, INPUT_PULLUP);
#else
#ifdef HELTEC_V3
pinMode(ADC_CTRL, INPUT);
uint8_t adc_ctl_enable_value = !(digitalRead(ADC_CTRL));
pinMode(ADC_CTRL, OUTPUT);
digitalWrite(ADC_CTRL, adc_ctl_enable_value);
#else
pinMode(ADC_CTRL, OUTPUT);
digitalWrite(ADC_CTRL, ADC_CTRL_ENABLED);
#endif
#endif
delay(10);
#endif
@@ -167,10 +174,14 @@ static void adcDisable()
#ifdef ADC_CTRL // disable adc voltage divider when we need to read
#ifdef ADC_USE_PULLUP
pinMode(ADC_CTRL, INPUT_PULLDOWN);
#else
#ifdef HELTEC_V3
pinMode(ADC_CTRL, ANALOG);
#else
digitalWrite(ADC_CTRL, !ADC_CTRL_ENABLED);
#endif
#endif
#endif
}
#endif
@@ -240,7 +251,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !defined(HAS_PMU) && \
!MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
if (hasINA()) {
LOG_DEBUG("Using INA on I2C addr 0x%x for device battery voltage\n", config.power.device_battery_ina_address);
LOG_DEBUG("Using INA on I2C addr 0x%x for device battery voltage", config.power.device_battery_ina_address);
return getINAVoltage();
}
#endif
@@ -290,7 +301,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
last_read_value += (scaled - last_read_value) * 0.5; // Virtual LPF
}
// LOG_DEBUG("battery gpio %d raw val=%u scaled=%u filtered=%u\n", BATTERY_PIN, raw, (uint32_t)(scaled), (uint32_t)
// LOG_DEBUG("battery gpio %d raw val=%u scaled=%u filtered=%u", BATTERY_PIN, raw, (uint32_t)(scaled), (uint32_t)
// (last_read_value));
}
return last_read_value;
@@ -335,7 +346,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
raw += adc_buf;
raw_c++; // Count valid samples
} else {
LOG_DEBUG("An attempt to sample ADC2 failed\n");
LOG_DEBUG("An attempt to sample ADC2 failed");
}
}
@@ -360,7 +371,12 @@ class AnalogBatteryLevel : public HasBatteryLevel
/**
* return true if there is a battery installed in this unit
*/
// if we have a integrated device with a battery, we can assume that the battery is always connected
#ifdef BATTERY_IMMUTABLE
virtual bool isBatteryConnect() override { return true; }
#else
virtual bool isBatteryConnect() override { return getBatteryPercent() != -1; }
#endif
/// If we see a battery voltage higher than physics allows - assume charger is pumping
/// in power
@@ -495,7 +511,7 @@ bool Power::analogInit()
#endif
#ifdef BATTERY_PIN
LOG_DEBUG("Using analog input %d for battery level\n", BATTERY_PIN);
LOG_DEBUG("Using analog input %d for battery level", BATTERY_PIN);
// disable any internal pullups
pinMode(BATTERY_PIN, INPUT);
@@ -526,18 +542,18 @@ bool Power::analogInit()
esp_adc_cal_value_t val_type = esp_adc_cal_characterize(unit, atten, width, DEFAULT_VREF, adc_characs);
// show ADC characterization base
if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) {
LOG_INFO("ADCmod: ADC characterization based on Two Point values stored in eFuse\n");
LOG_INFO("ADCmod: ADC characterization based on Two Point values stored in eFuse");
} else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) {
LOG_INFO("ADCmod: ADC characterization based on reference voltage stored in eFuse\n");
LOG_INFO("ADCmod: ADC characterization based on reference voltage stored in eFuse");
}
#ifdef CONFIG_IDF_TARGET_ESP32S3
// ESP32S3
else if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP_FIT) {
LOG_INFO("ADCmod: ADC Characterization based on Two Point values and fitting curve coefficients stored in eFuse\n");
LOG_INFO("ADCmod: ADC Characterization based on Two Point values and fitting curve coefficients stored in eFuse");
}
#endif
else {
LOG_INFO("ADCmod: ADC characterization based on default reference voltage\n");
LOG_INFO("ADCmod: ADC characterization based on default reference voltage");
}
#endif // ARCH_ESP32
@@ -586,7 +602,7 @@ bool Power::setup()
void Power::shutdown()
{
LOG_INFO("Shutting down\n");
LOG_INFO("Shutting down");
#if defined(ARCH_NRF52) || defined(ARCH_ESP32) || defined(ARCH_RP2040)
#ifdef PIN_LED1
@@ -641,7 +657,7 @@ void Power::readPowerStatus()
// changes.
nrfx_power_usb_state_t nrf_usb_state = nrfx_power_usbstatus_get();
// LOG_DEBUG("NRF Power %d\n", nrf_usb_state);
// LOG_DEBUG("NRF Power %d", nrf_usb_state);
// If changed to DISCONNECTED
if (nrf_usb_state == NRFX_POWER_USB_STATE_DISCONNECTED)
@@ -654,22 +670,22 @@ void Power::readPowerStatus()
// Notify any status instances that are observing us
const PowerStatus powerStatus2 = PowerStatus(hasBattery, usbPowered, isCharging, batteryVoltageMv, batteryChargePercent);
LOG_DEBUG("Battery: usbPower=%d, isCharging=%d, batMv=%d, batPct=%d\n", powerStatus2.getHasUSB(),
powerStatus2.getIsCharging(), powerStatus2.getBatteryVoltageMv(), powerStatus2.getBatteryChargePercent());
LOG_DEBUG("Battery: usbPower=%d, isCharging=%d, batMv=%d, batPct=%d", powerStatus2.getHasUSB(), powerStatus2.getIsCharging(),
powerStatus2.getBatteryVoltageMv(), powerStatus2.getBatteryChargePercent());
newStatus.notifyObservers(&powerStatus2);
#ifdef DEBUG_HEAP
if (lastheap != memGet.getFreeHeap()) {
LOG_DEBUG("Threads running:");
std::string threadlist = "Threads running:";
int running = 0;
for (int i = 0; i < MAX_THREADS; i++) {
auto thread = concurrency::mainController.get(i);
if ((thread != nullptr) && (thread->enabled)) {
LOG_DEBUG(" %s", thread->ThreadName.c_str());
threadlist += vformat(" %s", thread->ThreadName.c_str());
running++;
}
}
LOG_DEBUG("\n");
LOG_DEBUG("Heap status: %d/%d bytes free (%d), running %d/%d threads\n", memGet.getFreeHeap(), memGet.getHeapSize(),
LOG_DEBUG(threadlist.c_str());
LOG_DEBUG("Heap status: %d/%d bytes free (%d), running %d/%d threads", memGet.getFreeHeap(), memGet.getHeapSize(),
memGet.getFreeHeap() - lastheap, running, concurrency::mainController.size(false));
lastheap = memGet.getFreeHeap();
}
@@ -702,13 +718,13 @@ void Power::readPowerStatus()
if (batteryLevel && powerStatus2.getHasBattery() && !powerStatus2.getHasUSB()) {
if (batteryLevel->getBattVoltage() < OCV[NUM_OCV_POINTS - 1]) {
low_voltage_counter++;
LOG_DEBUG("Low voltage counter: %d/10\n", low_voltage_counter);
LOG_DEBUG("Low voltage counter: %d/10", low_voltage_counter);
if (low_voltage_counter > 10) {
#ifdef ARCH_NRF52
// We can't trigger deep sleep on NRF52, it's freezing the board
LOG_DEBUG("Low voltage detected, but not triggering deep sleep\n");
LOG_DEBUG("Low voltage detected, but not triggering deep sleep");
#else
LOG_INFO("Low voltage detected, triggering deep sleep\n");
LOG_INFO("Low voltage detected, triggering deep sleep");
powerFSM.trigger(EVENT_LOW_BATTERY);
#endif
}
@@ -730,12 +746,12 @@ int32_t Power::runOnce()
PMU->getIrqStatus();
if (PMU->isVbusRemoveIrq()) {
LOG_INFO("USB unplugged\n");
LOG_INFO("USB unplugged");
powerFSM.trigger(EVENT_POWER_DISCONNECTED);
}
if (PMU->isVbusInsertIrq()) {
LOG_INFO("USB plugged In\n");
LOG_INFO("USB plugged In");
powerFSM.trigger(EVENT_POWER_CONNECTED);
}
@@ -743,21 +759,21 @@ int32_t Power::runOnce()
Other things we could check if we cared...
if (PMU->isBatChagerStartIrq()) {
LOG_DEBUG("Battery start charging\n");
LOG_DEBUG("Battery start charging");
}
if (PMU->isBatChagerDoneIrq()) {
LOG_DEBUG("Battery fully charged\n");
LOG_DEBUG("Battery fully charged");
}
if (PMU->isBatInsertIrq()) {
LOG_DEBUG("Battery inserted\n");
LOG_DEBUG("Battery inserted");
}
if (PMU->isBatRemoveIrq()) {
LOG_DEBUG("Battery removed\n");
LOG_DEBUG("Battery removed");
}
*/
#ifndef T_WATCH_S3 // FIXME - why is this triggering on the T-Watch S3?
if (PMU->isPekeyLongPressIrq()) {
LOG_DEBUG("PEK long button press\n");
LOG_DEBUG("PEK long button press");
screen->setOn(false);
}
#endif
@@ -800,22 +816,22 @@ bool Power::axpChipInit()
if (!PMU) {
PMU = new XPowersAXP2101(*w);
if (!PMU->init()) {
LOG_WARN("Failed to find AXP2101 power management\n");
LOG_WARN("Failed to find AXP2101 power management");
delete PMU;
PMU = NULL;
} else {
LOG_INFO("AXP2101 PMU init succeeded, using AXP2101 PMU\n");
LOG_INFO("AXP2101 PMU init succeeded, using AXP2101 PMU");
}
}
if (!PMU) {
PMU = new XPowersAXP192(*w);
if (!PMU->init()) {
LOG_WARN("Failed to find AXP192 power management\n");
LOG_WARN("Failed to find AXP192 power management");
delete PMU;
PMU = NULL;
} else {
LOG_INFO("AXP192 PMU init succeeded, using AXP192 PMU\n");
LOG_INFO("AXP192 PMU init succeeded, using AXP192 PMU");
}
}
@@ -972,51 +988,51 @@ bool Power::axpChipInit()
PMU->enableBattVoltageMeasure();
if (PMU->isChannelAvailable(XPOWERS_DCDC1)) {
LOG_DEBUG("DC1 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC1) ? "+" : "-",
LOG_DEBUG("DC1 : %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_DCDC1) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_DCDC1));
}
if (PMU->isChannelAvailable(XPOWERS_DCDC2)) {
LOG_DEBUG("DC2 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC2) ? "+" : "-",
LOG_DEBUG("DC2 : %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_DCDC2) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_DCDC2));
}
if (PMU->isChannelAvailable(XPOWERS_DCDC3)) {
LOG_DEBUG("DC3 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC3) ? "+" : "-",
LOG_DEBUG("DC3 : %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_DCDC3) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_DCDC3));
}
if (PMU->isChannelAvailable(XPOWERS_DCDC4)) {
LOG_DEBUG("DC4 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC4) ? "+" : "-",
LOG_DEBUG("DC4 : %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_DCDC4) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_DCDC4));
}
if (PMU->isChannelAvailable(XPOWERS_LDO2)) {
LOG_DEBUG("LDO2 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO2) ? "+" : "-",
LOG_DEBUG("LDO2 : %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_LDO2) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_LDO2));
}
if (PMU->isChannelAvailable(XPOWERS_LDO3)) {
LOG_DEBUG("LDO3 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO3) ? "+" : "-",
LOG_DEBUG("LDO3 : %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_LDO3) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_LDO3));
}
if (PMU->isChannelAvailable(XPOWERS_ALDO1)) {
LOG_DEBUG("ALDO1: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO1) ? "+" : "-",
LOG_DEBUG("ALDO1: %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_ALDO1) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_ALDO1));
}
if (PMU->isChannelAvailable(XPOWERS_ALDO2)) {
LOG_DEBUG("ALDO2: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO2) ? "+" : "-",
LOG_DEBUG("ALDO2: %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_ALDO2) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_ALDO2));
}
if (PMU->isChannelAvailable(XPOWERS_ALDO3)) {
LOG_DEBUG("ALDO3: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO3) ? "+" : "-",
LOG_DEBUG("ALDO3: %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_ALDO3) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_ALDO3));
}
if (PMU->isChannelAvailable(XPOWERS_ALDO4)) {
LOG_DEBUG("ALDO4: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO4) ? "+" : "-",
LOG_DEBUG("ALDO4: %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_ALDO4) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_ALDO4));
}
if (PMU->isChannelAvailable(XPOWERS_BLDO1)) {
LOG_DEBUG("BLDO1: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO1) ? "+" : "-",
LOG_DEBUG("BLDO1: %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_BLDO1) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_BLDO1));
}
if (PMU->isChannelAvailable(XPOWERS_BLDO2)) {
LOG_DEBUG("BLDO2: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO2) ? "+" : "-",
LOG_DEBUG("BLDO2: %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_BLDO2) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_BLDO2));
}
@@ -1124,7 +1140,7 @@ LipoBatteryLevel lipoLevel;
bool Power::lipoInit()
{
bool result = lipoLevel.runOnce();
LOG_DEBUG("Power::lipoInit lipo sensor is %s\n", result ? "ready" : "not ready yet");
LOG_DEBUG("Power::lipoInit lipo sensor is %s", result ? "ready" : "not ready yet");
if (!result)
return false;
batteryLevel = &lipoLevel;

View File

@@ -53,7 +53,7 @@ static bool isPowered()
static void sdsEnter()
{
LOG_DEBUG("Enter state: SDS\n");
LOG_DEBUG("Enter state: SDS");
// 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);
}
@@ -62,7 +62,7 @@ extern Power *power;
static void shutdownEnter()
{
LOG_DEBUG("Enter state: SHUTDOWN\n");
LOG_DEBUG("Enter state: SHUTDOWN");
power->shutdown();
}
@@ -72,16 +72,16 @@ static uint32_t secsSlept;
static void lsEnter()
{
LOG_INFO("lsEnter begin, ls_secs=%u\n", config.power.ls_secs);
LOG_INFO("lsEnter begin, ls_secs=%u", config.power.ls_secs);
screen->setOn(false);
secsSlept = 0; // How long have we been sleeping this time
// LOG_INFO("lsEnter end\n");
// LOG_INFO("lsEnter end");
}
static void lsIdle()
{
// LOG_INFO("lsIdle begin ls_secs=%u\n", getPref_ls_secs());
// LOG_INFO("lsIdle begin ls_secs=%u", getPref_ls_secs());
#ifdef ARCH_ESP32
@@ -105,7 +105,7 @@ static void lsIdle()
wakeCause2 = doLightSleep(100); // leave led on for 1ms
secsSlept += sleepTime;
// LOG_INFO("sleeping, flash led!\n");
// LOG_INFO("sleeping, flash led!");
break;
case ESP_SLEEP_WAKEUP_UART:
@@ -137,7 +137,7 @@ static void lsIdle()
} else {
// Time to stop sleeping!
ledBlink.set(false);
LOG_INFO("Reached ls_secs, servicing loop()\n");
LOG_INFO("Reached ls_secs, servicing loop()");
powerFSM.trigger(EVENT_WAKE_TIMER);
}
#endif
@@ -145,12 +145,12 @@ static void lsIdle()
static void lsExit()
{
LOG_INFO("Exit state: LS\n");
LOG_INFO("Exit state: LS");
}
static void nbEnter()
{
LOG_DEBUG("Enter state: NB\n");
LOG_DEBUG("Enter state: NB");
screen->setOn(false);
#ifdef ARCH_ESP32
// Only ESP32 should turn off bluetooth
@@ -168,7 +168,7 @@ static void darkEnter()
static void serialEnter()
{
LOG_DEBUG("Enter state: SERIAL\n");
LOG_DEBUG("Enter state: SERIAL");
setBluetoothEnable(false);
screen->setOn(true);
screen->print("Serial connected\n");
@@ -183,10 +183,10 @@ static void serialExit()
static void powerEnter()
{
// LOG_DEBUG("Enter state: POWER\n");
// LOG_DEBUG("Enter state: POWER");
if (!isPowered()) {
// If we got here, we are in the wrong state - we should be in powered, let that state ahndle things
LOG_INFO("Loss of power in Powered\n");
LOG_INFO("Loss of power in Powered");
powerFSM.trigger(EVENT_POWER_DISCONNECTED);
} else {
screen->setOn(true);
@@ -205,7 +205,7 @@ static void powerIdle()
{
if (!isPowered()) {
// If we got here, we are in the wrong state
LOG_INFO("Loss of power in Powered\n");
LOG_INFO("Loss of power in Powered");
powerFSM.trigger(EVENT_POWER_DISCONNECTED);
}
}
@@ -222,7 +222,7 @@ static void powerExit()
static void onEnter()
{
LOG_DEBUG("Enter state: ON\n");
LOG_DEBUG("Enter state: ON");
screen->setOn(true);
setBluetoothEnable(true);
}
@@ -242,7 +242,7 @@ static void screenPress()
static void bootEnter()
{
LOG_DEBUG("Enter state: BOOT\n");
LOG_DEBUG("Enter state: BOOT");
}
State stateSHUTDOWN(shutdownEnter, NULL, NULL, "SHUTDOWN");
@@ -264,7 +264,7 @@ void PowerFSM_setup()
config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR;
bool hasPower = isPowered();
LOG_INFO("PowerFSM init, USB power=%d\n", hasPower ? 1 : 0);
LOG_INFO("PowerFSM init, USB power=%d", hasPower ? 1 : 0);
powerFSM.add_timed_transition(&stateBOOT, hasPower ? &statePOWER : &stateON, 3 * 1000, NULL, "boot timeout");
// wake timer expired or a packet arrived

View File

@@ -35,7 +35,7 @@ void PowerMon::emitLog(const char *reason)
{
#ifdef USE_POWERMON
// The nrf52 printf doesn't understand 64 bit ints, so if we ever reach that point this function will need to change.
LOG_INFO("S:PM:0x%08lx,%s\n", (uint32_t)states, reason);
LOG_INFO("S:PM:0x%08lx,%s", (uint32_t)states, reason);
#endif
}

View File

@@ -91,7 +91,7 @@ class PowerStatus : public Status
isCharging = newStatus->isCharging;
}
if (isDirty) {
// LOG_DEBUG("Battery %dmV %d%%\n", batteryVoltageMv, batteryChargePercent);
// LOG_DEBUG("Battery %dmV %d%%", batteryVoltageMv, batteryChargePercent);
onNewStatus.notifyObservers(this);
}
return 0;

View File

@@ -98,81 +98,75 @@ void RedirectablePrint::log_to_serial(const char *logLevel, const char *format,
{
size_t r = 0;
// Cope with 0 len format strings, but look for new line terminator
bool hasNewline = *format && format[strlen(format) - 1] == '\n';
#ifdef ARCH_PORTDUINO
bool color = !settingsMap[ascii_logs];
#else
bool color = true;
#endif
// If we are the first message on a report, include the header
if (!isContinuationMessage) {
// include the header
if (color) {
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_DEBUG) == 0)
Print::write("\u001b[34m", 6);
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_INFO) == 0)
Print::write("\u001b[32m", 6);
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_WARN) == 0)
Print::write("\u001b[33m", 6);
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_ERROR) == 0)
Print::write("\u001b[31m", 6);
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_TRACE) == 0)
Print::write("\u001b[35m", 6);
}
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice, true); // display local time on logfile
if (rtc_sec > 0) {
long hms = rtc_sec % SEC_PER_DAY;
// hms += tz.tz_dsttime * SEC_PER_HOUR;
// hms -= tz.tz_minuteswest * SEC_PER_MIN;
// mod `hms` to ensure in positive range of [0...SEC_PER_DAY)
hms = (hms + SEC_PER_DAY) % SEC_PER_DAY;
// Tear apart hms into h:m:s
int hour = hms / SEC_PER_HOUR;
int min = (hms % SEC_PER_HOUR) / SEC_PER_MIN;
int sec = (hms % SEC_PER_HOUR) % SEC_PER_MIN; // or hms % SEC_PER_MIN
#ifdef ARCH_PORTDUINO
::printf("%s ", logLevel);
if (color) {
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_DEBUG) == 0)
Print::write("\u001b[34m", 6);
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_INFO) == 0)
Print::write("\u001b[32m", 6);
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_WARN) == 0)
Print::write("\u001b[33m", 6);
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_ERROR) == 0)
Print::write("\u001b[31m", 6);
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_TRACE) == 0)
Print::write("\u001b[35m", 6);
::printf("\u001b[0m");
}
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice, true); // display local time on logfile
if (rtc_sec > 0) {
long hms = rtc_sec % SEC_PER_DAY;
// hms += tz.tz_dsttime * SEC_PER_HOUR;
// hms -= tz.tz_minuteswest * SEC_PER_MIN;
// mod `hms` to ensure in positive range of [0...SEC_PER_DAY)
hms = (hms + SEC_PER_DAY) % SEC_PER_DAY;
// Tear apart hms into h:m:s
int hour = hms / SEC_PER_HOUR;
int min = (hms % SEC_PER_HOUR) / SEC_PER_MIN;
int sec = (hms % SEC_PER_HOUR) % SEC_PER_MIN; // or hms % SEC_PER_MIN
#ifdef ARCH_PORTDUINO
::printf("%s ", logLevel);
if (color) {
::printf("\u001b[0m");
}
::printf("| %02d:%02d:%02d %u ", hour, min, sec, millis() / 1000);
::printf("| %02d:%02d:%02d %u ", hour, min, sec, millis() / 1000);
#else
printf("%s ", logLevel);
if (color) {
printf("\u001b[0m");
}
printf("| %02d:%02d:%02d %u ", hour, min, sec, millis() / 1000);
printf("%s ", logLevel);
if (color) {
printf("\u001b[0m");
}
printf("| %02d:%02d:%02d %u ", hour, min, sec, millis() / 1000);
#endif
} else {
} else {
#ifdef ARCH_PORTDUINO
::printf("%s ", logLevel);
if (color) {
::printf("\u001b[0m");
}
::printf("| ??:??:?? %u ", millis() / 1000);
::printf("%s ", logLevel);
if (color) {
::printf("\u001b[0m");
}
::printf("| ??:??:?? %u ", millis() / 1000);
#else
printf("%s ", logLevel);
if (color) {
printf("\u001b[0m");
}
printf("| ??:??:?? %u ", millis() / 1000);
printf("%s ", logLevel);
if (color) {
printf("\u001b[0m");
}
printf("| ??:??:?? %u ", millis() / 1000);
#endif
}
auto thread = concurrency::OSThread::currentThread;
if (thread) {
print("[");
// printf("%p ", thread);
// assert(thread->ThreadName.length());
print(thread->ThreadName);
print("] ");
}
}
auto thread = concurrency::OSThread::currentThread;
if (thread) {
print("[");
// printf("%p ", thread);
// assert(thread->ThreadName.length());
print(thread->ThreadName);
print("] ");
}
r += vprintf(logLevel, format, arg);
isContinuationMessage = !hasNewline;
}
void RedirectablePrint::log_to_syslog(const char *logLevel, const char *format, va_list arg)
@@ -283,6 +277,14 @@ meshtastic_LogRecord_Level RedirectablePrint::getLogLevel(const char *logLevel)
void RedirectablePrint::log(const char *logLevel, const char *format, ...)
{
// append \n to format
size_t len = strlen(format);
char *newFormat = new char[len + 2];
strcpy(newFormat, format);
newFormat[len] = '\n';
newFormat[len + 1] = '\0';
#if ARCH_PORTDUINO
// level trace is special, two possible ways to handle it.
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_TRACE) == 0) {
@@ -295,17 +297,24 @@ void RedirectablePrint::log(const char *logLevel, const char *format, ...)
}
va_end(arg);
}
if (settingsMap[logoutputlevel] < level_trace && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_TRACE) == 0)
if (settingsMap[logoutputlevel] < level_trace && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_TRACE) == 0) {
delete[] newFormat;
return;
}
}
if (settingsMap[logoutputlevel] < level_debug && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_DEBUG) == 0)
if (settingsMap[logoutputlevel] < level_debug && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_DEBUG) == 0) {
delete[] newFormat;
return;
else if (settingsMap[logoutputlevel] < level_info && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_INFO) == 0)
} else if (settingsMap[logoutputlevel] < level_info && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_INFO) == 0) {
delete[] newFormat;
return;
else if (settingsMap[logoutputlevel] < level_warn && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_WARN) == 0)
} else if (settingsMap[logoutputlevel] < level_warn && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_WARN) == 0) {
delete[] newFormat;
return;
}
#endif
if (moduleConfig.serial.override_console_serial_port && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_DEBUG) == 0) {
delete[] newFormat;
return;
}
@@ -319,9 +328,9 @@ void RedirectablePrint::log(const char *logLevel, const char *format, ...)
va_list arg;
va_start(arg, format);
log_to_serial(logLevel, format, arg);
log_to_syslog(logLevel, format, arg);
log_to_ble(logLevel, format, arg);
log_to_serial(logLevel, newFormat, arg);
log_to_syslog(logLevel, newFormat, arg);
log_to_ble(logLevel, newFormat, arg);
va_end(arg);
#ifdef HAS_FREE_RTOS
@@ -331,17 +340,18 @@ void RedirectablePrint::log(const char *logLevel, const char *format, ...)
#endif
}
delete[] newFormat;
return;
}
void RedirectablePrint::hexDump(const char *logLevel, unsigned char *buf, uint16_t len)
{
const char alphabet[17] = "0123456789abcdef";
log(logLevel, " +------------------------------------------------+ +----------------+\n");
log(logLevel, " |.0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .a .b .c .d .e .f | | ASCII |\n");
log(logLevel, " +------------------------------------------------+ +----------------+");
log(logLevel, " |.0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .a .b .c .d .e .f | | ASCII |");
for (uint16_t i = 0; i < len; i += 16) {
if (i % 128 == 0)
log(logLevel, " +------------------------------------------------+ +----------------+\n");
log(logLevel, " +------------------------------------------------+ +----------------+");
char s[] = "| | | |\n";
uint8_t ix = 1, iy = 52;
for (uint8_t j = 0; j < 16; j++) {
@@ -363,7 +373,7 @@ void RedirectablePrint::hexDump(const char *logLevel, unsigned char *buf, uint16
log(logLevel, ".");
log(logLevel, s);
}
log(logLevel, " +------------------------------------------------+ +----------------+\n");
log(logLevel, " +------------------------------------------------+ +----------------+");
}
std::string RedirectablePrint::mt_sprintf(const std::string fmt_str, ...)

View File

@@ -15,9 +15,6 @@ class RedirectablePrint : public Print
{
Print *dest;
/// Used to allow multiple logDebug messages to appear on a single log line
bool isContinuationMessage = false;
#ifdef HAS_FREE_RTOS
SemaphoreHandle_t inDebugPrint = nullptr;
StaticSemaphore_t _MutexStorageSpace;
@@ -54,9 +51,9 @@ class RedirectablePrint : public Print
protected:
/// Subclasses can override if they need to change how we format over the serial port
virtual void log_to_serial(const char *logLevel, const char *format, va_list arg);
meshtastic_LogRecord_Level getLogLevel(const char *logLevel);
private:
void log_to_syslog(const char *logLevel, const char *format, va_list arg);
void log_to_ble(const char *logLevel, const char *format, va_list arg);
meshtastic_LogRecord_Level getLogLevel(const char *logLevel);
};

View File

@@ -59,14 +59,14 @@ bool SafeFile::close()
// brief window of risk here ;-)
if (fullAtomic && FSCom.exists(filename.c_str()) && !FSCom.remove(filename.c_str())) {
LOG_ERROR("Can't remove old pref file\n");
LOG_ERROR("Can't remove old pref file");
return false;
}
String filenameTmp = filename;
filenameTmp += ".tmp";
if (!renameFile(filenameTmp.c_str(), filename.c_str())) {
LOG_ERROR("Error: can't rename new pref file\n");
LOG_ERROR("Error: can't rename new pref file");
return false;
}
@@ -83,7 +83,7 @@ bool SafeFile::testReadback()
filenameTmp += ".tmp";
auto f2 = FSCom.open(filenameTmp.c_str(), FILE_O_READ);
if (!f2) {
LOG_ERROR("Can't open tmp file for readback\n");
LOG_ERROR("Can't open tmp file for readback");
return false;
}
@@ -95,7 +95,7 @@ bool SafeFile::testReadback()
f2.close();
if (test_hash != hash) {
LOG_ERROR("Readback failed hash mismatch\n");
LOG_ERROR("Readback failed hash mismatch");
return false;
}

View File

@@ -99,25 +99,7 @@ bool SerialConsole::handleToRadio(const uint8_t *buf, size_t len)
void SerialConsole::log_to_serial(const char *logLevel, const char *format, va_list arg)
{
if (usingProtobufs && config.security.debug_log_api_enabled) {
meshtastic_LogRecord_Level ll = meshtastic_LogRecord_Level_UNSET; // default to unset
switch (logLevel[0]) {
case 'D':
ll = meshtastic_LogRecord_Level_DEBUG;
break;
case 'I':
ll = meshtastic_LogRecord_Level_INFO;
break;
case 'W':
ll = meshtastic_LogRecord_Level_WARNING;
break;
case 'E':
ll = meshtastic_LogRecord_Level_ERROR;
break;
case 'C':
ll = meshtastic_LogRecord_Level_CRITICAL;
break;
}
meshtastic_LogRecord_Level ll = RedirectablePrint::getLogLevel(logLevel);
auto thread = concurrency::OSThread::currentThread;
emitLogRecord(ll, thread ? thread->ThreadName.c_str() : "", format, arg);
} else

View File

@@ -13,17 +13,17 @@ void AirTime::logAirtime(reportTypes reportType, uint32_t airtime_ms)
{
if (reportType == TX_LOG) {
LOG_DEBUG("Packet transmitted : %ums\n", airtime_ms);
LOG_DEBUG("Packet transmitted : %ums", airtime_ms);
this->airtimes.periodTX[0] = this->airtimes.periodTX[0] + airtime_ms;
air_period_tx[0] = air_period_tx[0] + airtime_ms;
this->utilizationTX[this->getPeriodUtilHour()] = this->utilizationTX[this->getPeriodUtilHour()] + airtime_ms;
} else if (reportType == RX_LOG) {
LOG_DEBUG("Packet received : %ums\n", airtime_ms);
LOG_DEBUG("Packet received : %ums", airtime_ms);
this->airtimes.periodRX[0] = this->airtimes.periodRX[0] + airtime_ms;
air_period_rx[0] = air_period_rx[0] + airtime_ms;
} else if (reportType == RX_ALL_LOG) {
LOG_DEBUG("Packet received (noise?) : %ums\n", airtime_ms);
LOG_DEBUG("Packet received (noise?) : %ums", airtime_ms);
this->airtimes.periodRX_ALL[0] = this->airtimes.periodRX_ALL[0] + airtime_ms;
}
@@ -50,7 +50,7 @@ void AirTime::airtimeRotatePeriod()
{
if (this->airtimes.lastPeriodIndex != this->currentPeriodIndex()) {
LOG_DEBUG("Rotating airtimes to a new period = %u\n", this->currentPeriodIndex());
LOG_DEBUG("Rotating airtimes to a new period = %u", this->currentPeriodIndex());
for (int i = PERIODS_TO_LOG - 2; i >= 0; --i) {
this->airtimes.periodTX[i + 1] = this->airtimes.periodTX[i];
@@ -105,7 +105,7 @@ float AirTime::channelUtilizationPercent()
uint32_t sum = 0;
for (uint32_t i = 0; i < CHANNEL_UTILIZATION_PERIODS; i++) {
sum += this->channelUtilization[i];
// LOG_DEBUG("ChanUtilArray %u %u\n", i, this->channelUtilization[i]);
// LOG_DEBUG("ChanUtilArray %u %u", i, this->channelUtilization[i]);
}
return (float(sum) / float(CHANNEL_UTILIZATION_PERIODS * 10 * 1000)) * 100;
@@ -127,7 +127,7 @@ bool AirTime::isTxAllowedChannelUtil(bool polite)
if (channelUtilizationPercent() < percentage) {
return true;
} else {
LOG_WARN("Channel utilization is >%d percent. Skipping this opportunity to send.\n", percentage);
LOG_WARN("Channel utilization is >%d percent. Skipping this opportunity to send.", percentage);
return false;
}
}
@@ -138,7 +138,7 @@ bool AirTime::isTxAllowedAirUtil()
if (utilizationTXPercent() < myRegion->dutyCycle * polite_duty_cycle_percent / 100) {
return true;
} else {
LOG_WARN("Tx air utilization is >%f percent. Skipping this opportunity to send.\n",
LOG_WARN("Tx air utilization is >%f percent. Skipping this opportunity to send.",
myRegion->dutyCycle * polite_duty_cycle_percent / 100);
return false;
}
@@ -209,13 +209,13 @@ int32_t AirTime::runOnce()
}
}
/*
LOG_DEBUG("utilPeriodTX %d TX Airtime %3.2f%\n", utilPeriodTX, airTime->utilizationTXPercent());
LOG_DEBUG("utilPeriodTX %d TX Airtime %3.2f%", utilPeriodTX, airTime->utilizationTXPercent());
for (uint32_t i = 0; i < MINUTES_IN_HOUR; i++) {
LOG_DEBUG(
"%d,", this->utilizationTX[i]
);
}
LOG_DEBUG("\n");
LOG_DEBUG("");
*/
return (1000 * 1);
}

View File

@@ -55,6 +55,18 @@ void playBeep()
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
}
void playGPSEnableBeep()
{
ToneDuration melody[] = {{NOTE_C3, DURATION_1_8}, {NOTE_FS3, DURATION_1_4}, {NOTE_CS4, DURATION_1_4}};
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
}
void playGPSDisableBeep()
{
ToneDuration melody[] = {{NOTE_CS4, DURATION_1_8}, {NOTE_FS3, DURATION_1_4}, {NOTE_C3, DURATION_1_4}};
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
}
void playStartMelody()
{
ToneDuration melody[] = {{NOTE_FS3, DURATION_1_8}, {NOTE_AS3, DURATION_1_8}, {NOTE_CS4, DURATION_1_4}};

View File

@@ -3,3 +3,5 @@
void playBeep();
void playStartMelody();
void playShutdownMelody();
void playGPSEnableBeep();
void playGPSDisableBeep();

View File

@@ -18,7 +18,7 @@ bool InterruptableDelay::delay(uint32_t msec)
// sem take will return false if we timed out (i.e. were not interrupted)
bool r = semaphore.take(msec);
// LOG_DEBUG("interrupt=%d\n", r);
// LOG_DEBUG("interrupt=%d", r);
return !r;
}

View File

@@ -32,12 +32,12 @@ IRAM_ATTR bool NotifiedWorkerThread::notifyCommon(uint32_t v, bool overwrite)
notification = v;
if (debugNotification) {
LOG_DEBUG("setting notification %d\n", v);
LOG_DEBUG("setting notification %d", v);
}
return true;
} else {
if (debugNotification) {
LOG_DEBUG("dropping notification %d\n", v);
LOG_DEBUG("dropping notification %d", v);
}
return false;
}
@@ -67,7 +67,7 @@ bool NotifiedWorkerThread::notifyLater(uint32_t delay, uint32_t v, bool overwrit
if (didIt) { // If we didn't already have something queued, override the delay to be larger
setIntervalFromNow(delay); // a new version of setInterval relative to the current time
if (debugNotification) {
LOG_DEBUG("delaying notification %u\n", delay);
LOG_DEBUG("delaying notification %u", delay);
}
}

View File

@@ -62,15 +62,15 @@ bool OSThread::shouldRun(unsigned long time)
bool r = Thread::shouldRun(time);
if (showRun && r) {
LOG_DEBUG("Thread %s: run\n", ThreadName.c_str());
LOG_DEBUG("Thread %s: run", ThreadName.c_str());
}
if (showWaiting && enabled && !r) {
LOG_DEBUG("Thread %s: wait %lu\n", ThreadName.c_str(), interval);
LOG_DEBUG("Thread %s: wait %lu", ThreadName.c_str(), interval);
}
if (showDisabled && !enabled) {
LOG_DEBUG("Thread %s: disabled\n", ThreadName.c_str());
LOG_DEBUG("Thread %s: disabled", ThreadName.c_str());
}
return r;
@@ -86,9 +86,9 @@ void OSThread::run()
#ifdef DEBUG_HEAP
auto newHeap = memGet.getFreeHeap();
if (newHeap < heap)
LOG_DEBUG("------ Thread %s leaked heap %d -> %d (%d) ------\n", ThreadName.c_str(), heap, newHeap, newHeap - heap);
LOG_DEBUG("------ Thread %s leaked heap %d -> %d (%d) ------", ThreadName.c_str(), heap, newHeap, newHeap - heap);
if (heap < newHeap)
LOG_DEBUG("++++++ Thread %s freed heap %d -> %d (%d) ++++++\n", ThreadName.c_str(), heap, newHeap, newHeap - heap);
LOG_DEBUG("++++++ Thread %s freed heap %d -> %d (%d) ++++++", ThreadName.c_str(), heap, newHeap, newHeap - heap);
#endif
runned();

View File

@@ -114,6 +114,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define CARDKB_ADDR 0x5F
#define TDECK_KB_ADDR 0x55
#define BBQ10_KB_ADDR 0x1F
#define MPR121_KB_ADDR 0x5A
// -----------------------------------------------------------------------------
// SENSOR
@@ -135,6 +136,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define LPS22HB_ADDR_ALT 0x5D
#define SHT31_4x_ADDR 0x44
#define PMSA0031_ADDR 0x12
#define QMA6100P_ADDR 0x12
#define AHT10_ADDR 0x38
#define RCWL9620_ADDR 0x57
#define VEML7700_ADDR 0x10
@@ -205,6 +207,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef GPS_BAUDRATE
#define GPS_BAUDRATE 9600
#define GPS_BAUDRATE_FIXED 0
#else
#define GPS_BAUDRATE_FIXED 1
#endif
/* Step #2: follow with defines common to the architecture;

View File

@@ -31,14 +31,14 @@ ScanI2C::FoundDevice ScanI2C::firstRTC() const
ScanI2C::FoundDevice ScanI2C::firstKeyboard() const
{
ScanI2C::DeviceType types[] = {CARDKB, TDECKKB, BBQ10KB, RAK14004};
return firstOfOrNONE(4, types);
ScanI2C::DeviceType types[] = {CARDKB, TDECKKB, BBQ10KB, RAK14004, MPR121KB};
return firstOfOrNONE(5, types);
}
ScanI2C::FoundDevice ScanI2C::firstAccelerometer() const
{
ScanI2C::DeviceType types[] = {MPU6050, LIS3DH, BMA423, LSM6DS3, BMX160, STK8BAXX, ICM20948};
return firstOfOrNONE(7, types);
ScanI2C::DeviceType types[] = {MPU6050, LIS3DH, BMA423, LSM6DS3, BMX160, STK8BAXX, ICM20948, QMA6100P};
return firstOfOrNONE(8, types);
}
ScanI2C::FoundDevice ScanI2C::find(ScanI2C::DeviceType) const

View File

@@ -39,6 +39,7 @@ class ScanI2C
QMC5883L,
HMC5883L,
PMSA0031,
QMA6100P,
MPU6050,
LIS3DH,
BMA423,
@@ -61,7 +62,8 @@ class ScanI2C
STK8BAXX,
ICM20948,
MAX30102,
TPS65233
TPS65233,
MPR121KB
} DeviceType;
// typedef uint8_t DeviceAddress;

View File

@@ -7,7 +7,8 @@
#include "linux/LinuxHardwareI2C.h"
#endif
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
#include "main.h" // atecc
#include "main.h" // atecc
#include "meshUtils.h" // vformat
#endif
// AXP192 and AXP2101 have the same device address, we just need to identify it in Power.cpp
@@ -71,15 +72,15 @@ ScanI2C::DeviceType ScanI2CTwoWire::probeOLED(ScanI2C::DeviceAddress addr) const
r &= 0x0f;
if (r == 0x08 || r == 0x00) {
LOG_INFO("sh1106 display found\n");
LOG_INFO("sh1106 display found");
o_probe = SCREEN_SH1106; // SH1106
} else if (r == 0x03 || r == 0x04 || r == 0x06 || r == 0x07) {
LOG_INFO("ssd1306 display found\n");
LOG_INFO("ssd1306 display found");
o_probe = SCREEN_SSD1306; // SSD1306
}
c++;
} while ((r != r_prev) && (c < 4));
LOG_DEBUG("0x%x subtype probed in %i tries \n", r, c);
LOG_DEBUG("0x%x subtype probed in %i tries ", r, c);
return o_probe;
}
@@ -88,31 +89,31 @@ void ScanI2CTwoWire::printATECCInfo() const
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
atecc.readConfigZone(false);
LOG_DEBUG("ATECC608B Serial Number: ");
std::string atecc_numbers = "ATECC608B Serial Number: ";
for (int i = 0; i < 9; i++) {
LOG_DEBUG("%02x", atecc.serialNumber[i]);
atecc_numbers += vformat("%02x", atecc.serialNumber[i]);
}
LOG_DEBUG(", Rev Number: ");
atecc_numbers += ", Rev Number: ";
for (int i = 0; i < 4; i++) {
LOG_DEBUG("%02x", atecc.revisionNumber[i]);
atecc_numbers += vformat("%02x", atecc.revisionNumber[i]);
}
LOG_DEBUG("\n");
LOG_DEBUG(atecc_numbers.c_str());
LOG_DEBUG("ATECC608B Config %s", atecc.configLockStatus ? "Locked" : "Unlocked");
LOG_DEBUG(", Data %s", atecc.dataOTPLockStatus ? "Locked" : "Unlocked");
LOG_DEBUG(", Slot 0 %s\n", atecc.slot0LockStatus ? "Locked" : "Unlocked");
LOG_DEBUG("ATECC608B Config %s, Data %s, Slot 0 %s", atecc.configLockStatus ? "Locked" : "Unlocked",
atecc.dataOTPLockStatus ? "Locked" : "Unlocked", atecc.slot0LockStatus ? "Locked" : "Unlocked");
std::string atecc_publickey = "";
if (atecc.configLockStatus && atecc.dataOTPLockStatus && atecc.slot0LockStatus) {
if (atecc.generatePublicKey() == false) {
LOG_DEBUG("ATECC608B Error generating public key\n");
atecc_publickey += "ATECC608B Error generating public key";
} else {
LOG_DEBUG("ATECC608B Public Key: ");
atecc_publickey += "ATECC608B Public Key: ";
for (int i = 0; i < 64; i++) {
LOG_DEBUG("%02x", atecc.publicKey64Bytes[i]);
atecc_publickey += vformat("%02x", atecc.publicKey64Bytes[i]);
}
LOG_DEBUG("\n");
}
LOG_DEBUG(atecc_publickey.c_str());
}
#endif
}
@@ -128,7 +129,7 @@ uint16_t ScanI2CTwoWire::getRegisterValue(const ScanI2CTwoWire::RegisterLocation
i2cBus->endTransmission();
delay(20);
i2cBus->requestFrom(registerLocation.i2cAddress.address, responseWidth);
LOG_DEBUG("Wire.available() = %d\n", i2cBus->available());
LOG_DEBUG("Wire.available() = %d", i2cBus->available());
if (i2cBus->available() == 2) {
// Read MSB, then LSB
value = (uint16_t)i2cBus->read() << 8;
@@ -149,7 +150,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
{
concurrency::LockGuard guard((concurrency::Lock *)&lock);
LOG_DEBUG("Scanning for I2C devices on port %d\n", port);
LOG_DEBUG("Scanning for I2C devices on port %d", port);
uint8_t err;
@@ -172,11 +173,20 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
}
#endif
for (addr.address = 1; addr.address < 127; addr.address++) {
// We only need to scan 112 addresses, the rest is reserved for special purposes
// 0x00 General Call
// 0x01 CBUS addresses
// 0x02 Reserved for different bus formats
// 0x03 Reserved for future purposes
// 0x04-0x07 High Speed Master Code
// 0x78-0x7B 10-bit slave addressing
// 0x7C-0x7F Reserved for future purposes
for (addr.address = 8; addr.address < 120; addr.address++) {
if (asize != 0) {
if (!in_array(address, asize, addr.address))
continue;
LOG_DEBUG("Scanning address 0x%x\n", addr.address);
LOG_DEBUG("Scanning address 0x%x", addr.address);
}
i2cBus->beginTransmission(addr.address);
#ifdef ARCH_PORTDUINO
@@ -189,7 +199,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
#endif
type = NONE;
if (err == 0) {
LOG_DEBUG("I2C device found at address 0x%x\n", addr.address);
LOG_DEBUG("I2C device found at address 0x%x", addr.address);
switch (addr.address) {
case SSD1306_ADDRESS:
@@ -205,9 +215,9 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
#endif
{
LOG_INFO("ATECC608B initialized\n");
LOG_INFO("ATECC608B initialized");
} else {
LOG_WARN("ATECC608B initialization failed\n");
LOG_WARN("ATECC608B initialization failed");
}
printATECCInfo();
break;
@@ -217,7 +227,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
case RV3028_RTC:
// foundDevices[addr] = RTC_RV3028;
type = RTC_RV3028;
LOG_INFO("RV3028 RTC found\n");
LOG_INFO("RV3028 RTC found");
rtc.initI2C(*i2cBus);
rtc.writeToRegister(0x35, 0x07); // no Clkout
rtc.writeToRegister(0x37, 0xB4);
@@ -225,7 +235,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
#endif
#ifdef PCF8563_RTC
SCAN_SIMPLE_CASE(PCF8563_RTC, RTC_PCF8563, "PCF8563 RTC found\n")
SCAN_SIMPLE_CASE(PCF8563_RTC, RTC_PCF8563, "PCF8563 RTC found")
#endif
case CARDKB_ADDR:
@@ -233,49 +243,50 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x04), 1);
if (registerValue == 0x02) {
// KEYPAD_VERSION
LOG_INFO("RAK14004 found\n");
LOG_INFO("RAK14004 found");
type = RAK14004;
} else {
LOG_INFO("m5 cardKB found\n");
LOG_INFO("m5 cardKB found");
type = CARDKB;
}
break;
SCAN_SIMPLE_CASE(TDECK_KB_ADDR, TDECKKB, "T-Deck keyboard found\n");
SCAN_SIMPLE_CASE(BBQ10_KB_ADDR, BBQ10KB, "BB Q10 keyboard found\n");
SCAN_SIMPLE_CASE(ST7567_ADDRESS, SCREEN_ST7567, "st7567 display found\n");
SCAN_SIMPLE_CASE(TDECK_KB_ADDR, TDECKKB, "T-Deck keyboard found");
SCAN_SIMPLE_CASE(BBQ10_KB_ADDR, BBQ10KB, "BB Q10 keyboard found");
SCAN_SIMPLE_CASE(ST7567_ADDRESS, SCREEN_ST7567, "st7567 display found");
#ifdef HAS_NCP5623
SCAN_SIMPLE_CASE(NCP5623_ADDR, NCP5623, "NCP5623 RGB LED found\n");
SCAN_SIMPLE_CASE(NCP5623_ADDR, NCP5623, "NCP5623 RGB LED found");
#endif
#ifdef HAS_PMU
SCAN_SIMPLE_CASE(XPOWERS_AXP192_AXP2101_ADDRESS, PMU_AXP192_AXP2101, "axp192/axp2101 PMU found\n")
SCAN_SIMPLE_CASE(XPOWERS_AXP192_AXP2101_ADDRESS, PMU_AXP192_AXP2101, "axp192/axp2101 PMU found")
#endif
case BME_ADDR:
case BME_ADDR_ALTERNATE:
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xD0), 1); // GET_ID
switch (registerValue) {
case 0x61:
LOG_INFO("BME-680 sensor found at address 0x%x\n", (uint8_t)addr.address);
LOG_INFO("BME-680 sensor found at address 0x%x", (uint8_t)addr.address);
type = BME_680;
break;
case 0x60:
LOG_INFO("BME-280 sensor found at address 0x%x\n", (uint8_t)addr.address);
LOG_INFO("BME-280 sensor found at address 0x%x", (uint8_t)addr.address);
type = BME_280;
break;
case 0x55:
LOG_INFO("BMP-085 or BMP-180 sensor found at address 0x%x\n", (uint8_t)addr.address);
LOG_INFO("BMP-085 or BMP-180 sensor found at address 0x%x", (uint8_t)addr.address);
type = BMP_085;
break;
default:
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 1); // GET_ID
switch (registerValue) {
case 0x50: // BMP-388 should be 0x50
LOG_INFO("BMP-388 sensor found at address 0x%x\n", (uint8_t)addr.address);
LOG_INFO("BMP-388 sensor found at address 0x%x", (uint8_t)addr.address);
type = BMP_3XX;
break;
case 0x58: // BMP-280 should be 0x58
default:
LOG_INFO("BMP-280 sensor found at address 0x%x\n", (uint8_t)addr.address);
LOG_INFO("BMP-280 sensor found at address 0x%x", (uint8_t)addr.address);
type = BMP_280;
break;
}
@@ -284,7 +295,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
break;
#ifndef HAS_NCP5623
case AHT10_ADDR:
LOG_INFO("AHT10 sensor found at address 0x%x\n", (uint8_t)addr.address);
LOG_INFO("AHT10 sensor found at address 0x%x", (uint8_t)addr.address);
type = AHT10;
break;
#endif
@@ -292,23 +303,23 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
case INA_ADDR_ALTERNATE:
case INA_ADDR_WAVESHARE_UPS:
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFE), 2);
LOG_DEBUG("Register MFG_UID: 0x%x\n", registerValue);
LOG_DEBUG("Register MFG_UID: 0x%x", registerValue);
if (registerValue == 0x5449) {
LOG_INFO("INA260 sensor found at address 0x%x\n", (uint8_t)addr.address);
LOG_INFO("INA260 sensor found at address 0x%x", (uint8_t)addr.address);
type = INA260;
} else { // Assume INA219 if INA260 ID is not found
LOG_INFO("INA219 sensor found at address 0x%x\n", (uint8_t)addr.address);
LOG_INFO("INA219 sensor found at address 0x%x", (uint8_t)addr.address);
type = INA219;
}
break;
case INA3221_ADDR:
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFE), 2);
LOG_DEBUG("Register MFG_UID: 0x%x\n", registerValue);
LOG_DEBUG("Register MFG_UID: 0x%x", registerValue);
if (registerValue == 0x5449) {
LOG_INFO("INA3221 sensor found at address 0x%x\n", (uint8_t)addr.address);
LOG_INFO("INA3221 sensor found at address 0x%x", (uint8_t)addr.address);
type = INA3221;
} else {
LOG_INFO("DFRobot Lark weather station found at address 0x%x\n", (uint8_t)addr.address);
LOG_INFO("DFRobot Lark weather station found at address 0x%x", (uint8_t)addr.address);
type = DFROBOT_LARK;
}
break;
@@ -320,7 +331,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 2);
if (registerValue == 0x8700) {
type = STK8BAXX;
LOG_INFO("STK8BAXX accelerometer found\n");
LOG_INFO("STK8BAXX accelerometer found");
break;
}
@@ -328,7 +339,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x07), 2);
if (registerValue == 0x0400) {
type = MCP9808;
LOG_INFO("MCP9808 sensor found\n");
LOG_INFO("MCP9808 sensor found");
break;
}
@@ -336,7 +347,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
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\n");
LOG_INFO("LIS3DH accelerometer found");
}
break;
}
@@ -344,95 +355,109 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x89), 2);
if (registerValue == 0x11a2 || registerValue == 0x11da || registerValue == 0xe9c) {
type = SHT4X;
LOG_INFO("SHT4X sensor found\n");
LOG_INFO("SHT4X sensor found");
} else if (getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x7E), 2) == 0x5449) {
type = OPT3001;
LOG_INFO("OPT3001 light sensor found\n");
LOG_INFO("OPT3001 light sensor found");
} else {
type = SHT31;
LOG_INFO("SHT31 sensor found\n");
LOG_INFO("SHT31 sensor found");
}
break;
SCAN_SIMPLE_CASE(SHTC3_ADDR, SHTC3, "SHTC3 sensor found\n")
SCAN_SIMPLE_CASE(SHTC3_ADDR, SHTC3, "SHTC3 sensor found")
case RCWL9620_ADDR:
// get MAX30102 PARTID
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFF), 1);
if (registerValue == 0x15) {
type = MAX30102;
LOG_INFO("MAX30102 Health sensor found\n");
LOG_INFO("MAX30102 Health sensor found");
break;
} else {
type = RCWL9620;
LOG_INFO("RCWL9620 sensor found\n");
LOG_INFO("RCWL9620 sensor found");
}
break;
case LPS22HB_ADDR_ALT:
SCAN_SIMPLE_CASE(LPS22HB_ADDR, LPS22HB, "LPS22HB sensor found\n")
SCAN_SIMPLE_CASE(LPS22HB_ADDR, LPS22HB, "LPS22HB sensor found")
SCAN_SIMPLE_CASE(QMC6310_ADDR, QMC6310, "QMC6310 Highrate 3-Axis magnetic sensor found\n")
SCAN_SIMPLE_CASE(QMC6310_ADDR, QMC6310, "QMC6310 Highrate 3-Axis magnetic sensor found")
case QMI8658_ADDR:
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0A), 1); // get ID
if (registerValue == 0xC0) {
type = BQ24295;
LOG_INFO("BQ24295 PMU found\n");
LOG_INFO("BQ24295 PMU found");
break;
}
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0F), 1); // get ID
if (registerValue == 0x6A) {
type = LSM6DS3;
LOG_INFO("LSM6DS3 accelerometer found at address 0x%x\n", (uint8_t)addr.address);
LOG_INFO("LSM6DS3 accelerometer found at address 0x%x", (uint8_t)addr.address);
} else {
type = QMI8658;
LOG_INFO("QMI8658 Highrate 6-Axis inertial measurement sensor found\n");
LOG_INFO("QMI8658 Highrate 6-Axis inertial measurement sensor found");
}
break;
SCAN_SIMPLE_CASE(QMC5883L_ADDR, QMC5883L, "QMC5883L Highrate 3-Axis magnetic sensor found\n")
SCAN_SIMPLE_CASE(HMC5883L_ADDR, HMC5883L, "HMC5883L 3-Axis digital compass found\n")
SCAN_SIMPLE_CASE(PMSA0031_ADDR, PMSA0031, "PMSA0031 air quality sensor found\n")
SCAN_SIMPLE_CASE(BMA423_ADDR, BMA423, "BMA423 accelerometer found\n");
SCAN_SIMPLE_CASE(LSM6DS3_ADDR, LSM6DS3, "LSM6DS3 accelerometer found at address 0x%x\n", (uint8_t)addr.address);
SCAN_SIMPLE_CASE(TCA9535_ADDR, TCA9535, "TCA9535 I2C expander found\n");
SCAN_SIMPLE_CASE(TCA9555_ADDR, TCA9555, "TCA9555 I2C expander found\n");
SCAN_SIMPLE_CASE(VEML7700_ADDR, VEML7700, "VEML7700 light sensor found\n");
SCAN_SIMPLE_CASE(TSL25911_ADDR, TSL2591, "TSL2591 light sensor found\n");
SCAN_SIMPLE_CASE(OPT3001_ADDR, OPT3001, "OPT3001 light sensor found\n");
SCAN_SIMPLE_CASE(MLX90632_ADDR, MLX90632, "MLX90632 IR temp sensor found\n");
SCAN_SIMPLE_CASE(NAU7802_ADDR, NAU7802, "NAU7802 based scale found\n");
SCAN_SIMPLE_CASE(FT6336U_ADDR, FT6336U, "FT6336U touchscreen found\n");
SCAN_SIMPLE_CASE(MAX1704X_ADDR, MAX17048, "MAX17048 lipo fuel gauge found\n");
#ifdef HAS_TPS65233
SCAN_SIMPLE_CASE(TPS65233_ADDR, TPS65233, "TPS65233 BIAS-T found\n");
SCAN_SIMPLE_CASE(QMC5883L_ADDR, QMC5883L, "QMC5883L Highrate 3-Axis magnetic sensor found")
SCAN_SIMPLE_CASE(HMC5883L_ADDR, HMC5883L, "HMC5883L 3-Axis digital compass found")
#ifdef HAS_QMA6100P
SCAN_SIMPLE_CASE(QMA6100P_ADDR, QMA6100P, "QMA6100P accelerometer found")
#else
SCAN_SIMPLE_CASE(PMSA0031_ADDR, PMSA0031, "PMSA0031 air quality sensor found")
#endif
SCAN_SIMPLE_CASE(MLX90614_ADDR_DEF, MLX90614, "MLX90614 IR temp sensor found\n");
SCAN_SIMPLE_CASE(BMA423_ADDR, BMA423, "BMA423 accelerometer found");
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(TCA9555_ADDR, TCA9555, "TCA9555 I2C expander found");
SCAN_SIMPLE_CASE(VEML7700_ADDR, VEML7700, "VEML7700 light sensor found");
SCAN_SIMPLE_CASE(TSL25911_ADDR, TSL2591, "TSL2591 light sensor found");
SCAN_SIMPLE_CASE(OPT3001_ADDR, OPT3001, "OPT3001 light sensor found");
SCAN_SIMPLE_CASE(MLX90632_ADDR, MLX90632, "MLX90632 IR temp sensor found");
SCAN_SIMPLE_CASE(NAU7802_ADDR, NAU7802, "NAU7802 based scale found");
SCAN_SIMPLE_CASE(FT6336U_ADDR, FT6336U, "FT6336U touchscreen found");
SCAN_SIMPLE_CASE(MAX1704X_ADDR, MAX17048, "MAX17048 lipo fuel gauge found");
#ifdef HAS_TPS65233
SCAN_SIMPLE_CASE(TPS65233_ADDR, TPS65233, "TPS65233 BIAS-T found");
#endif
case MLX90614_ADDR_DEF:
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0e), 1);
if (registerValue == 0x5a) {
type = MLX90614;
LOG_INFO("MLX90614 IR temp sensor found");
} else {
type = MPR121KB;
LOG_INFO("MPR121KB keyboard found");
}
break;
case ICM20948_ADDR: // same as BMX160_ADDR
case ICM20948_ADDR_ALT: // same as MPU6050_ADDR
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 1);
if (registerValue == 0xEA) {
type = ICM20948;
LOG_INFO("ICM20948 9-dof motion processor found\n");
LOG_INFO("ICM20948 9-dof motion processor found");
break;
} else if (addr.address == BMX160_ADDR) {
type = BMX160;
LOG_INFO("BMX160 accelerometer found\n");
LOG_INFO("BMX160 accelerometer found");
break;
} else {
type = MPU6050;
LOG_INFO("MPU6050 accelerometer found\n");
LOG_INFO("MPU6050 accelerometer found");
break;
}
break;
default:
LOG_INFO("Device found at address 0x%x was not able to be enumerated\n", addr.address);
LOG_INFO("Device found at address 0x%x was not able to be enumerated", addr.address);
}
} else if (err == 4) {
LOG_ERROR("Unknown error at address 0x%x\n", addr.address);
LOG_ERROR("Unknown error at address 0x%x", addr.address);
}
// Check if a type was found for the enumerated device - save, if so

View File

@@ -1,19 +0,0 @@
#if 0
// Turn off for now
uint32_t axpDebugRead()
{
axp.debugCharging();
LOG_DEBUG("vbus current %f\n", axp.getVbusCurrent());
LOG_DEBUG("charge current %f\n", axp.getBattChargeCurrent());
LOG_DEBUG("bat voltage %f\n", axp.getBattVoltage());
LOG_DEBUG("batt pct %d\n", axp.getBattPercentage());
LOG_DEBUG("is battery connected %d\n", axp.isBatteryConnect());
LOG_DEBUG("is USB connected %d\n", axp.isVBUSPlug());
LOG_DEBUG("is charging %d\n", axp.isChargeing());
return 30 * 1000;
}
Periodic axpDebugOutput(axpDebugRead);
axpDebugOutput.setup();
#endif

View File

@@ -59,9 +59,9 @@ void scanEInkDevice(void)
d_writeCommand(0x20);
eink_found = (d_waitWhileBusy(150) > 0) ? true : false;
if (eink_found)
LOG_DEBUG("EInk display found\n");
LOG_DEBUG("EInk display found");
else
LOG_DEBUG("EInk display not found\n");
LOG_DEBUG("EInk display not found");
SPI1.end();
}
#endif

View File

@@ -7,6 +7,7 @@
#include "PowerMon.h"
#include "RTC.h"
#include "Throttle.h"
#include "buzz.h"
#include "meshUtils.h"
#include "main.h" // pmu_found
@@ -19,6 +20,7 @@
#ifdef ARCH_PORTDUINO
#include "PortduinoGlue.h"
#include "meshUtils.h"
#include <algorithm>
#include <ctime>
#endif
@@ -154,7 +156,7 @@ uint8_t GPS::makeCASPacket(uint8_t class_id, uint8_t msg_id, uint8_t payload_siz
CASChecksum(UBXscratch, (payload_size + 10));
#if defined(GPS_DEBUG) && defined(DEBUG_PORT)
LOG_DEBUG("Constructed CAS packet: \n");
LOG_DEBUG("Constructed CAS packet: ");
DEBUG_PORT.hexDump(MESHTASTIC_LOG_LEVEL_DEBUG, UBXscratch, payload_size + 10);
#endif
return (payload_size + 10);
@@ -166,33 +168,33 @@ GPS_RESPONSE GPS::getACK(const char *message, uint32_t waitMillis)
uint8_t b;
int bytesRead = 0;
uint32_t startTimeout = millis() + waitMillis;
#ifdef GPS_DEBUG
std::string debugmsg = "";
#endif
while (millis() < startTimeout) {
if (_serial_gps->available()) {
b = _serial_gps->read();
#ifdef GPS_DEBUG
LOG_DEBUG("%c", (b >= 32 && b <= 126) ? b : '.');
debugmsg += vformat("%c", (b >= 32 && b <= 126) ? b : '.');
#endif
buffer[bytesRead] = b;
bytesRead++;
if ((bytesRead == 767) || (b == '\r')) {
if (strnstr((char *)buffer, message, bytesRead) != nullptr) {
#ifdef GPS_DEBUG
LOG_DEBUG("\r\nFound: %s\r\n", message); // Log the found message
LOG_DEBUG("Found: %s", message); // Log the found message
#endif
return GNSS_RESPONSE_OK;
} else {
bytesRead = 0;
#ifdef GPS_DEBUG
LOG_DEBUG("\r\n");
LOG_DEBUG(debugmsg.c_str());
#endif
}
}
}
}
#ifdef GPS_DEBUG
LOG_DEBUG("\n");
#endif
return GNSS_RESPONSE_NONE;
}
@@ -235,7 +237,7 @@ GPS_RESPONSE GPS::getACKCas(uint8_t class_id, uint8_t msg_id, uint32_t waitMilli
// Check for an ACK-ACK for the specified class and message id
if ((msg_cls == 0x05) && (msg_msg_id == 0x01) && payload_cls == class_id && payload_msg == msg_id) {
#ifdef GPS_DEBUG
LOG_INFO("Got ACK for class %02X message %02X in %d millis.\n", class_id, msg_id, millis() - startTime);
LOG_INFO("Got ACK for class %02X message %02X in %d millis.", class_id, msg_id, millis() - startTime);
#endif
return GNSS_RESPONSE_OK;
}
@@ -243,7 +245,7 @@ GPS_RESPONSE GPS::getACKCas(uint8_t class_id, uint8_t msg_id, uint32_t waitMilli
// Check for an ACK-NACK for the specified class and message id
if ((msg_cls == 0x05) && (msg_msg_id == 0x00) && payload_cls == class_id && payload_msg == msg_id) {
#ifdef GPS_DEBUG
LOG_WARN("Got NACK for class %02X message %02X in %d millis.\n", class_id, msg_id, millis() - startTime);
LOG_WARN("Got NACK for class %02X message %02X in %d millis.", class_id, msg_id, millis() - startTime);
#endif
return GNSS_RESPONSE_NAK;
}
@@ -266,6 +268,9 @@ GPS_RESPONSE GPS::getACK(uint8_t class_id, uint8_t msg_id, uint32_t waitMillis)
uint32_t startTime = millis();
const char frame_errors[] = "More than 100 frame errors";
int sCounter = 0;
#ifdef GPS_DEBUG
std::string debugmsg = "";
#endif
for (int j = 2; j < 6; j++) {
buf[8] += buf[j];
@@ -281,8 +286,8 @@ GPS_RESPONSE GPS::getACK(uint8_t class_id, uint8_t msg_id, uint32_t waitMillis)
while (Throttle::isWithinTimespanMs(startTime, waitMillis)) {
if (ack > 9) {
#ifdef GPS_DEBUG
LOG_DEBUG("\n");
LOG_INFO("Got ACK for class %02X message %02X in %d millis.\n", class_id, msg_id, millis() - startTime);
LOG_DEBUG("");
LOG_INFO("Got ACK for class %02X message %02X in %d millis.", class_id, msg_id, millis() - startTime);
#endif
return GNSS_RESPONSE_OK; // ACK received
}
@@ -291,22 +296,26 @@ GPS_RESPONSE GPS::getACK(uint8_t class_id, uint8_t msg_id, uint32_t waitMillis)
if (b == frame_errors[sCounter]) {
sCounter++;
if (sCounter == 26) {
#ifdef GPS_DEBUG
LOG_DEBUG(debugmsg.c_str());
#endif
return GNSS_RESPONSE_FRAME_ERRORS;
}
} else {
sCounter = 0;
}
#ifdef GPS_DEBUG
LOG_DEBUG("%02X", b);
debugmsg += vformat("%02X", b);
#endif
if (b == buf[ack]) {
ack++;
} else {
if (ack == 3 && b == 0x00) { // UBX-ACK-NAK message
#ifdef GPS_DEBUG
LOG_DEBUG("\n");
LOG_DEBUG(debugmsg.c_str());
#endif
LOG_WARN("Got NAK for class %02X message %02X\n", class_id, msg_id);
LOG_WARN("Got NAK for class %02X message %02X", class_id, msg_id);
return GNSS_RESPONSE_NAK; // NAK received
}
ack = 0; // Reset the acknowledgement counter
@@ -314,8 +323,8 @@ GPS_RESPONSE GPS::getACK(uint8_t class_id, uint8_t msg_id, uint32_t waitMillis)
}
}
#ifdef GPS_DEBUG
LOG_DEBUG("\n");
LOG_WARN("No response for class %02X message %02X\n", class_id, msg_id);
LOG_DEBUG(debugmsg.c_str());
LOG_WARN("No response for class %02X message %02X", class_id, msg_id);
#endif
return GNSS_RESPONSE_NONE; // No response received within timeout
}
@@ -388,7 +397,7 @@ int GPS::getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t
} else {
// return payload length
#ifdef GPS_DEBUG
LOG_INFO("Got ACK for class %02X message %02X in %d millis.\n", requestedClass, requestedID,
LOG_INFO("Got ACK for class %02X message %02X in %d millis.", requestedClass, requestedID,
millis() - startTime);
#endif
return needRead;
@@ -400,34 +409,46 @@ int GPS::getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t
}
}
}
// LOG_WARN("No response for class %02X message %02X\n", requestedClass, requestedID);
// LOG_WARN("No response for class %02X message %02X", requestedClass, requestedID);
return 0;
}
/**
* @brief Setup the GPS based on the model detected.
* We detect the GPS by cycling through a set of baud rates, first common then rare.
* For each baud rate, we run GPS::Probe to send commands and match the responses
* to known GPS responses.
* @retval Whether setup reached the end of its potential to configure the GPS.
*/
bool GPS::setup()
{
if (!didSerialInit) {
int msglen = 0;
if (tx_gpio && gnssModel == GNSS_MODEL_UNKNOWN) {
// if GPS_BAUDRATE is specified in variant (i.e. not 9600), skip to the specified rate.
if (speedSelect == 0 && GPS_BAUDRATE != serialSpeeds[speedSelect]) {
speedSelect = std::find(serialSpeeds, std::end(serialSpeeds), GPS_BAUDRATE) - serialSpeeds;
if (probeTries < 2) {
LOG_DEBUG("Probing for GPS at %d", serialSpeeds[speedSelect]);
gnssModel = probe(serialSpeeds[speedSelect]);
if (gnssModel == GNSS_MODEL_UNKNOWN) {
if (++speedSelect == sizeof(serialSpeeds) / sizeof(int)) {
speedSelect = 0;
++probeTries;
}
}
}
LOG_DEBUG("Probing for GPS at %d \n", serialSpeeds[speedSelect]);
gnssModel = probe(serialSpeeds[speedSelect]);
if (gnssModel == GNSS_MODEL_UNKNOWN) {
if (++speedSelect == sizeof(serialSpeeds) / sizeof(int)) {
speedSelect = 0;
if (--probeTries == 0) {
LOG_WARN("Giving up on GPS probe and setting to 9600.\n");
// Rare Serial Speeds
if (probeTries == 2) {
LOG_DEBUG("Probing for GPS at %d", rareSerialSpeeds[speedSelect]);
gnssModel = probe(rareSerialSpeeds[speedSelect]);
if (gnssModel == GNSS_MODEL_UNKNOWN) {
if (++speedSelect == sizeof(rareSerialSpeeds) / sizeof(int)) {
LOG_WARN("Giving up on GPS probe and setting to %d", GPS_BAUDRATE);
return true;
}
}
return false;
}
return false;
} else {
gnssModel = GNSS_MODEL_UNKNOWN;
}
@@ -467,6 +488,18 @@ bool GPS::setup()
// Switch to Fitness Mode, for running and walking purpose with low speed (<5 m/s)
_serial_gps->write("$PMTK886,1*29\r\n");
delay(250);
} else if (gnssModel == GNSS_MODEL_MTK_PA1616S) {
// PA1616S is used in some GPS breakout boards from Adafruit
// PA1616S does not have GLONASS capability. PA1616D does, but is not implemented here.
_serial_gps->write("$PMTK353,1,0,0,0,0*2A\r\n");
// Above command will reset the GPS and takes longer before it will accept new commands
delay(1000);
// Only ask for RMC and GGA (GNRMC and GNGGA)
_serial_gps->write("$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28\r\n");
delay(250);
// Enable SBAS / WAAS
_serial_gps->write("$PMTK301,2*2E\r\n");
delay(250);
} else if (gnssModel == GNSS_MODEL_ATGM336H) {
// Set the intial configuration of the device - these _should_ work for most AT6558 devices
msglen = makeCASPacket(0x06, 0x07, sizeof(_message_CAS_CFG_NAVX_CONF), _message_CAS_CFG_NAVX_CONF);
@@ -491,7 +524,7 @@ bool GPS::setup()
msglen = makeCASPacket(0x06, 0x01, sizeof(cas_cfg_msg_packet), cas_cfg_msg_packet);
_serial_gps->write(UBXscratch, msglen);
if (getACKCas(0x06, 0x01, 250) != GNSS_RESPONSE_OK) {
LOG_WARN("ATGM336H - Could not enable NMEA MSG: %d\n", fields[i]);
LOG_WARN("ATGM336H - Could not enable NMEA MSG: %d", fields[i]);
}
}
} else if (gnssModel == GNSS_MODEL_UC6580) {
@@ -551,13 +584,13 @@ bool GPS::setup()
msglen = makeUBXPacket(0x06, 0x09, sizeof(_message_SAVE), _message_SAVE);
_serial_gps->write(UBXscratch, msglen);
if (getACK(0x06, 0x09, 2000) != GNSS_RESPONSE_OK) {
LOG_WARN("Unable to save GNSS module configuration.\n");
LOG_WARN("Unable to save GNSS module configuration.");
} else {
LOG_INFO("GNSS module configuration saved!\n");
LOG_INFO("GNSS module configuration saved!");
}
} else if (IS_ONE_OF(gnssModel, GNSS_MODEL_UBLOX7, GNSS_MODEL_UBLOX8, GNSS_MODEL_UBLOX9)) {
if (gnssModel == GNSS_MODEL_UBLOX7) {
LOG_DEBUG("Setting GPS+SBAS\n");
LOG_DEBUG("Setting GPS+SBAS");
msglen = makeUBXPacket(0x06, 0x3e, sizeof(_message_GNSS_7), _message_GNSS_7);
_serial_gps->write(UBXscratch, msglen);
} else { // 8,9
@@ -567,12 +600,12 @@ bool GPS::setup()
if (getACK(0x06, 0x3e, 800) == GNSS_RESPONSE_NAK) {
// It's not critical if the module doesn't acknowledge this configuration.
LOG_INFO("reconfigure GNSS - defaults maintained. Is this module GPS-only?\n");
LOG_INFO("reconfigure GNSS - defaults maintained. Is this module GPS-only?");
} else {
if (gnssModel == GNSS_MODEL_UBLOX7) {
LOG_INFO("GNSS configured for GPS+SBAS.\n");
LOG_INFO("GNSS configured for GPS+SBAS.");
} else { // 8,9
LOG_INFO("GNSS configured for GPS+SBAS+GLONASS+Galileo.\n");
LOG_INFO("GNSS configured for GPS+SBAS+GLONASS+Galileo.");
}
// Documentation say, we need wait atleast 0.5s after reconfiguration of GNSS module, before sending next
// commands for the M8 it tends to be more... 1 sec should be enough ;>)
@@ -620,9 +653,9 @@ bool GPS::setup()
msglen = makeUBXPacket(0x06, 0x09, sizeof(_message_SAVE), _message_SAVE);
_serial_gps->write(UBXscratch, msglen);
if (getACK(0x06, 0x09, 2000) != GNSS_RESPONSE_OK) {
LOG_WARN("Unable to save GNSS module configuration.\n");
LOG_WARN("Unable to save GNSS module configuration.");
} else {
LOG_INFO("GNSS module configuration saved!\n");
LOG_INFO("GNSS module configuration saved!");
}
} else if (gnssModel == GNSS_MODEL_UBLOX10) {
delay(1000);
@@ -654,7 +687,8 @@ bool GPS::setup()
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_SBAS_BBR, "disable SBAS M10 GPS BBR", 300);
delay(750); // will cause a receiver restart so wait a bit
// Done with initialization, Now enable wanted NMEA messages in BBR layer so they will survive a periodic sleep.
// Done with initialization, Now enable wanted NMEA messages in BBR layer so they will survive a periodic
// sleep.
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_ENABLE_NMEA_BBR, "enable messages for M10 GPS BBR", 300);
delay(750);
// Next enable wanted NMEA messages in RAM layer
@@ -667,9 +701,9 @@ bool GPS::setup()
msglen = makeUBXPacket(0x06, 0x09, sizeof(_message_SAVE_10), _message_SAVE_10);
_serial_gps->write(UBXscratch, msglen);
if (getACK(0x06, 0x09, 2000) != GNSS_RESPONSE_OK) {
LOG_WARN("Unable to save GNSS module configuration.\n");
LOG_WARN("Unable to save GNSS module configuration.");
} else {
LOG_INFO("GNSS module configuration saved!\n");
LOG_INFO("GNSS module configuration saved!");
}
}
didSerialInit = true;
@@ -691,7 +725,7 @@ void GPS::setPowerState(GPSPowerState newState, uint32_t sleepTime)
// Update the stored GPSPowerstate, and create local copies
GPSPowerState oldState = powerState;
powerState = newState;
LOG_INFO("GPS power state moving from %s to %s\n", getGPSPowerStateString(oldState), getGPSPowerStateString(newState));
LOG_INFO("GPS power state moving from %s to %s", getGPSPowerStateString(oldState), getGPSPowerStateString(newState));
#ifdef HELTEC_MESH_NODE_T114
if ((oldState == GPS_OFF || oldState == GPS_HARDSLEEP) && (newState != GPS_OFF && newState != GPS_HARDSLEEP)) {
@@ -761,7 +795,7 @@ void GPS::writePinEN(bool on)
// Write and log
enablePin->set(on);
#ifdef GPS_EXTRAVERBOSE
LOG_DEBUG("Pin EN %s\n", val == HIGH ? "HIGH" : "LOW");
LOG_DEBUG("Pin EN %s", val == HIGH ? "HIGH" : "LOW");
#endif
}
@@ -783,7 +817,7 @@ void GPS::writePinStandby(bool standby)
pinMode(PIN_GPS_STANDBY, OUTPUT);
digitalWrite(PIN_GPS_STANDBY, val);
#ifdef GPS_EXTRAVERBOSE
LOG_DEBUG("Pin STANDBY %s\n", val == HIGH ? "HIGH" : "LOW");
LOG_DEBUG("Pin STANDBY %s", val == HIGH ? "HIGH" : "LOW");
#endif
#endif
}
@@ -817,7 +851,7 @@ void GPS::setPowerPMU(bool on)
}
#ifdef GPS_EXTRAVERBOSE
LOG_DEBUG("PMU %s\n", on ? "on" : "off");
LOG_DEBUG("PMU %s", on ? "on" : "off");
#endif
#endif
}
@@ -834,7 +868,7 @@ void GPS::setPowerUBLOX(bool on, uint32_t sleepMs)
gps->_serial_gps->write(0xFF);
clearBuffer(); // This often returns old data, so drop it
#ifdef GPS_EXTRAVERBOSE
LOG_DEBUG("UBLOX: wake\n");
LOG_DEBUG("UBLOX: wake");
#endif
}
@@ -869,7 +903,7 @@ void GPS::setPowerUBLOX(bool on, uint32_t sleepMs)
gps->_serial_gps->write(gps->UBXscratch, msglen);
#ifdef GPS_EXTRAVERBOSE
LOG_DEBUG("UBLOX: sleep for %dmS\n", sleepMs);
LOG_DEBUG("UBLOX: sleep for %dmS", sleepMs);
#endif
}
}
@@ -898,7 +932,7 @@ void GPS::down()
uint32_t sleepTime = scheduling.msUntilNextSearch();
uint32_t updateInterval = Default::getConfiguredOrDefaultMs(config.position.gps_update_interval);
LOG_DEBUG("%us until next search\n", sleepTime / 1000);
LOG_DEBUG("%us until next search", sleepTime / 1000);
// If update interval less than 10 seconds, no attempt to sleep
if (updateInterval <= 10 * 1000UL || sleepTime == 0)
@@ -916,12 +950,12 @@ void GPS::down()
#endif
if (softsleepSupported) {
// How long does gps_update_interval need to be, for GPS_HARDSLEEP to become more efficient than GPS_SOFTSLEEP?
// Heuristic equation. A compromise manually fitted to power observations from U-blox NEO-6M and M10050
// https://www.desmos.com/calculator/6gvjghoumr
// This is not particularly accurate, but probably an impromevement over a single, fixed threshold
// How long does gps_update_interval need to be, for GPS_HARDSLEEP to become more efficient than
// GPS_SOFTSLEEP? Heuristic equation. A compromise manually fitted to power observations from U-blox NEO-6M
// and M10050 https://www.desmos.com/calculator/6gvjghoumr This is not particularly accurate, but probably an
// improvement over a single, fixed threshold
uint32_t hardsleepThreshold = (2750 * pow(predictedSearchDuration / 1000, 1.22));
LOG_DEBUG("gps_update_interval >= %us needed to justify hardsleep\n", hardsleepThreshold / 1000);
LOG_DEBUG("gps_update_interval >= %us needed to justify hardsleep", hardsleepThreshold / 1000);
// If update interval too short: softsleep (if supported by hardware)
if (updateInterval < hardsleepThreshold) {
@@ -940,7 +974,7 @@ void GPS::publishUpdate()
shouldPublish = false;
// In debug logs, identify position by @timestamp:stage (stage 2 = publish)
LOG_DEBUG("publishing pos@%x:2, hasVal=%d, Sats=%d, GPSlock=%d\n", p.timestamp, hasValidLocation, p.sats_in_view,
LOG_DEBUG("publishing pos@%x:2, hasVal=%d, Sats=%d, GPSlock=%d", p.timestamp, hasValidLocation, p.sats_in_view,
hasLock());
// Notify any status instances that are observing us
@@ -956,7 +990,7 @@ int32_t GPS::runOnce()
{
if (!GPSInitFinished) {
if (!_serial_gps || config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT) {
LOG_INFO("GPS set to not-present. Skipping probe.\n");
LOG_INFO("GPS set to not-present. Skipping probe.");
return disable();
}
if (!setup())
@@ -968,7 +1002,7 @@ int32_t GPS::runOnce()
}
// ONCE we will factory reset the GPS for bug #327
if (!devicestate.did_gps_reset) {
LOG_WARN("GPS FactoryReset requested\n");
LOG_WARN("GPS FactoryReset requested");
if (gps->factoryReset()) { // If we don't succeed try again next time
devicestate.did_gps_reset = true;
nodeDB->saveToDisk(SEGMENT_DEVICESTATE);
@@ -991,7 +1025,7 @@ int32_t GPS::runOnce()
GNSS_MODEL_UBLOX10)) {
// reset the GPS on next bootup
if (devicestate.did_gps_reset && scheduling.elapsedSearchMs() > 60 * 1000UL && !hasFlow()) {
LOG_DEBUG("GPS is not communicating, trying factory reset on next bootup.\n");
LOG_DEBUG("GPS is not communicating, trying factory reset on next bootup.");
devicestate.did_gps_reset = false;
nodeDB->saveToDisk(SEGMENT_DEVICESTATE);
return disable(); // Stop the GPS thread as it can do nothing useful until next reboot.
@@ -1001,7 +1035,7 @@ int32_t GPS::runOnce()
// At least one GPS has a bad habit of losing its mind from time to time
if (rebootsSeen > 2) {
rebootsSeen = 0;
LOG_DEBUG("Would normally factoryReset()\n");
LOG_DEBUG("Would normally factoryReset()");
// gps->factoryReset();
}
@@ -1018,23 +1052,23 @@ int32_t GPS::runOnce()
bool gotLoc = lookForLocation();
if (gotLoc && !hasValidLocation) { // declare that we have location ASAP
LOG_DEBUG("hasValidLocation RISING EDGE\n");
LOG_DEBUG("hasValidLocation RISING EDGE");
hasValidLocation = true;
shouldPublish = true;
}
bool tooLong = scheduling.searchedTooLong();
if (tooLong)
LOG_WARN("Couldn't publish a valid location: didn't get a GPS lock in time.\n");
LOG_WARN("Couldn't publish a valid location: didn't get a GPS lock in time.");
// Once we get a location we no longer desperately want an update
// LOG_DEBUG("gotLoc %d, tooLong %d, gotTime %d\n", gotLoc, tooLong, gotTime);
// LOG_DEBUG("gotLoc %d, tooLong %d, gotTime %d", gotLoc, tooLong, gotTime);
if ((gotLoc && gotTime) || tooLong) {
if (tooLong) {
// we didn't get a location during this ack window, therefore declare loss of lock
if (hasValidLocation) {
LOG_DEBUG("hasValidLocation FALLING EDGE\n");
LOG_DEBUG("hasValidLocation FALLING EDGE");
}
p = meshtastic_Position_init_default;
hasValidLocation = false;
@@ -1066,13 +1100,13 @@ void GPS::clearBuffer()
/// Prepare the GPS for the cpu entering deep or light sleep, expect to be gone for at least 100s of msecs
int GPS::prepareDeepSleep(void *unused)
{
LOG_INFO("GPS deep sleep!\n");
LOG_INFO("GPS deep sleep!");
disable();
return 0;
}
const char *PROBE_MESSAGE = "Trying %s (%s)...\n";
const char *DETECTED_MESSAGE = "%s detected, using %s Module\n";
const char *PROBE_MESSAGE = "Trying %s (%s)...";
const char *DETECTED_MESSAGE = "%s detected, using %s Module";
#define PROBE_SIMPLE(CHIP, TOWRITE, RESPONSE, DRIVER, TIMEOUT, ...) \
LOG_DEBUG(PROBE_MESSAGE, TOWRITE, CHIP); \
@@ -1094,7 +1128,7 @@ GnssModel_t GPS::probe(int serialSpeed)
_serial_gps->begin(serialSpeed);
#else
if (_serial_gps->baudRate() != serialSpeed) {
LOG_DEBUG("Setting Baud to %i\n", serialSpeed);
LOG_DEBUG("Setting Baud to %i", serialSpeed);
_serial_gps->updateBaudRate(serialSpeed);
}
#endif
@@ -1135,6 +1169,7 @@ GnssModel_t GPS::probe(int serialSpeed)
delay(20);
PROBE_SIMPLE("L76B", "$PMTK605*31", "Quectel-L76B", GNSS_MODEL_MTK_L76B, 500);
PROBE_SIMPLE("PA1616S", "$PMTK605*31", "1616S", GNSS_MODEL_MTK_PA1616S, 500);
uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00};
UBXChecksum(cfg_rate, sizeof(cfg_rate));
@@ -1143,10 +1178,10 @@ GnssModel_t GPS::probe(int serialSpeed)
// Check that the returned response class and message ID are correct
GPS_RESPONSE response = getACK(0x06, 0x08, 750);
if (response == GNSS_RESPONSE_NONE) {
LOG_WARN("Failed to find GNSS Module (baudrate %d)\n", serialSpeed);
LOG_WARN("Failed to find GNSS Module (baudrate %d)", serialSpeed);
return GNSS_MODEL_UNKNOWN;
} else if (response == GNSS_RESPONSE_FRAME_ERRORS) {
LOG_INFO("UBlox Frame Errors (baudrate %d)\n", serialSpeed);
LOG_INFO("UBlox Frame Errors (baudrate %d)", serialSpeed);
}
memset(buffer, 0, sizeof(buffer));
@@ -1163,7 +1198,7 @@ GnssModel_t GPS::probe(int serialSpeed)
uint16_t len = getACK(buffer, sizeof(buffer), 0x0A, 0x04, 1200);
if (len) {
// LOG_DEBUG("monver reply size = %d\n", len);
// LOG_DEBUG("monver reply size = %d", len);
uint16_t position = 0;
for (int i = 0; i < 30; i++) {
info.swVersion[i] = buffer[position];
@@ -1184,12 +1219,12 @@ GnssModel_t GPS::probe(int serialSpeed)
break;
}
LOG_DEBUG("Module Info : \n");
LOG_DEBUG("Soft version: %s\n", info.swVersion);
LOG_DEBUG("Hard version: %s\n", info.hwVersion);
LOG_DEBUG("Extensions:%d\n", info.extensionNo);
LOG_DEBUG("Module Info : ");
LOG_DEBUG("Soft version: %s", info.swVersion);
LOG_DEBUG("Hard version: %s", info.hwVersion);
LOG_DEBUG("Extensions:%d", info.extensionNo);
for (int i = 0; i < info.extensionNo; i++) {
LOG_DEBUG(" %s\n", info.extension[i]);
LOG_DEBUG(" %s", info.extension[i]);
}
memset(buffer, 0, sizeof(buffer));
@@ -1202,10 +1237,10 @@ GnssModel_t GPS::probe(int serialSpeed)
char *ptr = nullptr;
memset(buffer, 0, sizeof(buffer));
strncpy((char *)buffer, &(info.extension[i][8]), sizeof(buffer));
LOG_DEBUG("Protocol Version:%s\n", (char *)buffer);
LOG_DEBUG("Protocol Version:%s", (char *)buffer);
if (strlen((char *)buffer)) {
uBloxProtocolVersion = strtoul((char *)buffer, &ptr, 10);
LOG_DEBUG("ProtVer=%d\n", uBloxProtocolVersion);
LOG_DEBUG("ProtVer=%d", uBloxProtocolVersion);
} else {
uBloxProtocolVersion = 0;
}
@@ -1228,7 +1263,7 @@ GnssModel_t GPS::probe(int serialSpeed)
return GNSS_MODEL_UBLOX10;
}
}
LOG_WARN("Failed to find GNSS Module (baudrate %d)\n", serialSpeed);
LOG_WARN("Failed to find GNSS Module (baudrate %d)", serialSpeed);
return GNSS_MODEL_UNKNOWN;
}
@@ -1271,10 +1306,12 @@ GPS *GPS::createGps()
if (!GPS_EN_ACTIVE) { // Need to invert the pin before hardware
new GpioNotTransformer(
virtPin, p); // We just leave this created object on the heap so it can stay watching virtPin and driving en_gpio
virtPin,
p); // We just leave this created object on the heap so it can stay watching virtPin and driving en_gpio
} else {
new GpioUnaryTransformer(
virtPin, p); // We just leave this created object on the heap so it can stay watching virtPin and driving en_gpio
virtPin,
p); // We just leave this created object on the heap so it can stay watching virtPin and driving en_gpio
}
}
@@ -1289,7 +1326,7 @@ GPS *GPS::createGps()
// see NMEAGPS.h
gsafixtype.begin(reader, NMEA_MSG_GXGSA, 2);
gsapdop.begin(reader, NMEA_MSG_GXGSA, 15);
LOG_DEBUG("Using " NMEA_MSG_GXGSA " for 3DFIX and PDOP\n");
LOG_DEBUG("Using " NMEA_MSG_GXGSA " for 3DFIX and PDOP");
#endif
// Make sure the GPS is awake before performing any init.
@@ -1310,8 +1347,8 @@ GPS *GPS::createGps()
// ESP32 has a special set of parameters vs other arduino ports
#if defined(ARCH_ESP32)
LOG_DEBUG("Using GPIO%d for GPS RX\n", new_gps->rx_gpio);
LOG_DEBUG("Using GPIO%d for GPS TX\n", new_gps->tx_gpio);
LOG_DEBUG("Using GPIO%d for GPS RX", new_gps->rx_gpio);
LOG_DEBUG("Using GPIO%d for GPS TX", new_gps->tx_gpio);
_serial_gps->begin(GPS_BAUDRATE, SERIAL_8N1, new_gps->rx_gpio, new_gps->tx_gpio);
#elif defined(ARCH_RP2040)
_serial_gps->setFIFOSize(256);
@@ -1369,11 +1406,11 @@ bool GPS::factoryReset()
// delay(1000);
} else if (gnssModel == GNSS_MODEL_MTK) {
// send the CAS10 to perform a factory restart of the device (and other device that support PCAS statements)
LOG_INFO("GNSS Factory Reset via PCAS10,3\n");
LOG_INFO("GNSS Factory Reset via PCAS10,3");
_serial_gps->write("$PCAS10,3*1F\r\n");
delay(100);
} else if (gnssModel == GNSS_MODEL_ATGM336H) {
LOG_INFO("Factory Reset via CAS-CFG-RST\n");
LOG_INFO("Factory Reset via CAS-CFG-RST");
uint8_t msglen = makeCASPacket(0x06, 0x02, sizeof(_message_CAS_CFG_RST_FACTORY), _message_CAS_CFG_RST_FACTORY);
_serial_gps->write(UBXscratch, msglen);
delay(100);
@@ -1382,8 +1419,8 @@ bool GPS::factoryReset()
_serial_gps->write("$PMTK104*37\r\n");
// No PMTK_ACK for this command.
delay(100);
// send the UBLOX Factory Reset Command regardless of detect state, something is very wrong, just assume it's UBLOX.
// Factory Reset
// send the UBLOX Factory Reset Command regardless of detect state, something is very wrong, just assume it's
// UBLOX. Factory Reset
byte _message_reset[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, 0xFB, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x17, 0x2B, 0x7E};
_serial_gps->write(_message_reset, sizeof(_message_reset));
@@ -1422,8 +1459,8 @@ bool GPS::lookForTime()
auto d = reader.date;
if (ti.isValid() && d.isValid()) { // Note: we don't check for updated, because we'll only be called if needed
/* Convert to unix time
The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1, 1970
(midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z).
The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1,
1970 (midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z).
*/
struct tm t;
t.tm_sec = ti.second() + round(ti.age() / 1000);
@@ -1434,7 +1471,7 @@ The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of s
t.tm_year = d.year() - 1900;
t.tm_isdst = false;
if (t.tm_mon > -1) {
LOG_DEBUG("NMEA GPS time %02d-%02d-%02d %02d:%02d:%02d age %d\n", d.year(), d.month(), t.tm_mday, t.tm_hour, t.tm_min,
LOG_DEBUG("NMEA GPS time %02d-%02d-%02d %02d:%02d:%02d age %d", d.year(), d.month(), t.tm_mday, t.tm_hour, t.tm_min,
t.tm_sec, ti.age());
perhapsSetRTC(RTCQualityGPS, t);
return true;
@@ -1478,7 +1515,7 @@ bool GPS::lookForLocation()
#ifndef TINYGPS_OPTION_NO_STATISTICS
if (reader.failedChecksum() > lastChecksumFailCount) {
LOG_WARN("%u new GPS checksum failures, for a total of %u.\n", reader.failedChecksum() - lastChecksumFailCount,
LOG_WARN("%u new GPS checksum failures, for a total of %u.", reader.failedChecksum() - lastChecksumFailCount,
reader.failedChecksum());
lastChecksumFailCount = reader.failedChecksum();
}
@@ -1486,7 +1523,7 @@ bool GPS::lookForLocation()
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
fixType = atoi(gsafixtype.value()); // will set to zero if no data
// LOG_DEBUG("FIX QUAL=%d, TYPE=%d\n", fixQual, fixType);
// LOG_DEBUG("FIX QUAL=%d, TYPE=%d", fixQual, fixType);
#endif
// check if GPS has an acceptable lock
@@ -1494,7 +1531,7 @@ bool GPS::lookForLocation()
return false;
#ifdef GPS_EXTRAVERBOSE
LOG_DEBUG("AGE: LOC=%d FIX=%d DATE=%d TIME=%d\n", reader.location.age(),
LOG_DEBUG("AGE: LOC=%d FIX=%d DATE=%d TIME=%d", reader.location.age(),
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
gsafixtype.age(),
#else
@@ -1515,7 +1552,7 @@ bool GPS::lookForLocation()
(gsafixtype.age() < GPS_SOL_EXPIRY_MS) &&
#endif
(reader.time.age() < GPS_SOL_EXPIRY_MS) && (reader.date.age() < GPS_SOL_EXPIRY_MS))) {
LOG_WARN("SOME data is TOO OLD: LOC %u, TIME %u, DATE %u\n", reader.location.age(), reader.time.age(), reader.date.age());
LOG_WARN("SOME data is TOO OLD: LOC %u, TIME %u, DATE %u", reader.location.age(), reader.time.age(), reader.date.age());
return false;
}
@@ -1525,13 +1562,13 @@ bool GPS::lookForLocation()
// Bail out EARLY to avoid overwriting previous good data (like #857)
if (toDegInt(loc.lat) > 900000000) {
#ifdef GPS_EXTRAVERBOSE
LOG_DEBUG("Bail out EARLY on LAT %i\n", toDegInt(loc.lat));
LOG_DEBUG("Bail out EARLY on LAT %i", toDegInt(loc.lat));
#endif
return false;
}
if (toDegInt(loc.lng) > 1800000000) {
#ifdef GPS_EXTRAVERBOSE
LOG_DEBUG("Bail out EARLY on LNG %i\n", toDegInt(loc.lng));
LOG_DEBUG("Bail out EARLY on LNG %i", toDegInt(loc.lng));
#endif
return false;
}
@@ -1542,7 +1579,7 @@ bool GPS::lookForLocation()
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
p.HDOP = reader.hdop.value();
p.PDOP = TinyGPSPlus::parseDecimal(gsapdop.value());
// LOG_DEBUG("PDOP=%d, HDOP=%d\n", p.PDOP, p.HDOP);
// LOG_DEBUG("PDOP=%d, HDOP=%d", p.PDOP, p.HDOP);
#else
// FIXME! naive PDOP emulation (assumes VDOP==HDOP)
// correct formula is PDOP = SQRT(HDOP^2 + VDOP^2)
@@ -1552,7 +1589,7 @@ bool GPS::lookForLocation()
// Discard incomplete or erroneous readings
if (reader.hdop.value() == 0) {
LOG_WARN("BOGUS hdop.value() REJECTED: %d\n", reader.hdop.value());
LOG_WARN("BOGUS hdop.value() REJECTED: %d", reader.hdop.value());
return false;
}
@@ -1589,7 +1626,7 @@ bool GPS::lookForLocation()
p.ground_track =
reader.course.value() * 1e3; // Scale the heading (in degrees * 10^-2) to match the expected degrees * 10^-5
} else {
LOG_WARN("BOGUS course.value() REJECTED: %d\n", reader.course.value());
LOG_WARN("BOGUS course.value() REJECTED: %d", reader.course.value());
}
}
@@ -1623,24 +1660,27 @@ bool GPS::whileActive()
{
unsigned int charsInBuf = 0;
bool isValid = false;
#ifdef GPS_DEBUG
std::string debugmsg = "";
#endif
if (powerState != GPS_ACTIVE) {
clearBuffer();
return false;
}
#ifdef SERIAL_BUFFER_SIZE
if (_serial_gps->available() >= SERIAL_BUFFER_SIZE - 1) {
LOG_WARN("GPS Buffer full with %u bytes waiting. Flushing to avoid corruption.\n", _serial_gps->available());
LOG_WARN("GPS Buffer full with %u bytes waiting. Flushing to avoid corruption.", _serial_gps->available());
clearBuffer();
}
#endif
// if (_serial_gps->available() > 0)
// LOG_DEBUG("GPS Bytes Waiting: %u\n", _serial_gps->available());
// LOG_DEBUG("GPS Bytes Waiting: %u", _serial_gps->available());
// First consume any chars that have piled up at the receiver
while (_serial_gps->available() > 0) {
int c = _serial_gps->read();
UBXscratch[charsInBuf] = c;
#ifdef GPS_DEBUG
LOG_DEBUG("%c", c);
debugmsg += vformat("%c", (c >= 32 && c <= 126) ? c : '.');
#endif
isValid |= reader.encode(c);
if (charsInBuf > sizeof(UBXscratch) - 10 || c == '\r') {
@@ -1652,6 +1692,11 @@ bool GPS::whileActive()
charsInBuf++;
}
}
#ifdef GPS_DEBUG
if (debugmsg != "") {
LOG_DEBUG(debugmsg.c_str());
}
#endif
return isValid;
}
void GPS::enable()
@@ -1679,17 +1724,19 @@ void GPS::toggleGpsMode()
{
if (config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_ENABLED) {
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_DISABLED;
LOG_INFO("User toggled GpsMode. Now DISABLED.\n");
LOG_INFO("User toggled GpsMode. Now DISABLED.");
playGPSDisableBeep();
#ifdef GNSS_AIROHA
if (powerState == GPS_ACTIVE) {
LOG_DEBUG("User power Off GPS\n");
LOG_DEBUG("User power Off GPS");
digitalWrite(PIN_GPS_EN, LOW);
}
#endif
disable();
} else if (config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_DISABLED) {
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_ENABLED;
LOG_INFO("User toggled GpsMode. Now ENABLED\n");
LOG_INFO("User toggled GpsMode. Now ENABLED");
playGPSEnableBeep();
enable();
}
}

View File

@@ -34,6 +34,7 @@ typedef enum {
GNSS_MODEL_UC6580,
GNSS_MODEL_UNKNOWN,
GNSS_MODEL_MTK_L76B,
GNSS_MODEL_MTK_PA1616S,
GNSS_MODEL_AG3335,
GNSS_MODEL_AG3352
} GnssModel_t;
@@ -75,13 +76,21 @@ class GPS : private concurrency::OSThread
uint8_t fixType = 0; // fix type from GPGSA
#endif
private:
const int serialSpeeds[6] = {9600, 4800, 38400, 57600, 115200, 9600};
#if GPS_BAUDRATE_FIXED
// if GPS_BAUDRATE is specified in variant, only try that.
const int serialSpeeds[1] = {GPS_BAUDRATE};
const int rareSerialSpeeds[1] = {GPS_BAUDRATE};
#else
const int serialSpeeds[3] = {9600, 115200, 38400};
const int rareSerialSpeeds[3] = {4800, 57600, GPS_BAUDRATE};
#endif
uint32_t lastWakeStartMsec = 0, lastSleepStartMsec = 0, lastFixStartMsec = 0;
uint32_t rx_gpio = 0;
uint32_t tx_gpio = 0;
int speedSelect = 0;
int probeTries = 2;
int probeTries = 0;
/**
* hasValidLocation - indicates that the position variables contain a complete
@@ -156,7 +165,7 @@ class GPS : private concurrency::OSThread
static const uint8_t _message_CAS_CFG_NAVX_CONF[];
static const uint8_t _message_CAS_CFG_RATE_1HZ[];
const char *ACK_SUCCESS_MESSAGE = "Get ack success!\n";
const char *ACK_SUCCESS_MESSAGE = "Get ack success!";
meshtastic_Position p = meshtastic_Position_init_default;

View File

@@ -13,7 +13,7 @@ void GPSUpdateScheduling::informSearching()
void GPSUpdateScheduling::informGotLock()
{
searchEndedMs = millis();
LOG_DEBUG("Took %us to get lock\n", (searchEndedMs - searchStartedMs) / 1000);
LOG_DEBUG("Took %us to get lock", (searchEndedMs - searchStartedMs) / 1000);
updateLockTimePrediction();
}
@@ -70,9 +70,9 @@ bool GPSUpdateScheduling::isUpdateDue()
// Have we been searching for a GPS position for too long?
bool GPSUpdateScheduling::searchedTooLong()
{
uint32_t maxSearchMs =
Default::getConfiguredOrDefaultMs(config.position.position_broadcast_secs, default_broadcast_interval_secs);
uint32_t minimumOrConfiguredSecs =
Default::getConfiguredOrMinimumValue(config.position.position_broadcast_secs, default_broadcast_interval_secs);
uint32_t maxSearchMs = Default::getConfiguredOrDefaultMs(minimumOrConfiguredSecs, default_broadcast_interval_secs);
// If broadcast interval set to max, no such thing as "too long"
if (maxSearchMs == UINT32_MAX)
return false;
@@ -108,11 +108,11 @@ void GPSUpdateScheduling::updateLockTimePrediction()
searchCount++; // Only tracked so we can diregard initial lock-times
LOG_DEBUG("Predicting %us to get next lock\n", predictedMsToGetLock / 1000);
LOG_DEBUG("Predicting %us to get next lock", predictedMsToGetLock / 1000);
}
// How long do we expect to spend searching for a lock?
uint32_t GPSUpdateScheduling::predictedSearchDurationMs()
{
return GPSUpdateScheduling::predictedMsToGetLock;
}
}

View File

@@ -46,7 +46,7 @@ void readFromRTC()
tv.tv_usec = 0;
uint32_t printableEpoch = tv.tv_sec; // Print lib only supports 32 bit but time_t can be 64 bit on some platforms
LOG_DEBUG("Read RTC time from RV3028 getTime as %02d-%02d-%02d %02d:%02d:%02d (%ld)\n", t.tm_year + 1900, t.tm_mon + 1,
LOG_DEBUG("Read RTC time from RV3028 getTime as %02d-%02d-%02d %02d:%02d:%02d (%ld)", t.tm_year + 1900, t.tm_mon + 1,
t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, printableEpoch);
timeStartMsec = now;
zeroOffsetSecs = tv.tv_sec;
@@ -77,8 +77,8 @@ void readFromRTC()
tv.tv_usec = 0;
uint32_t printableEpoch = tv.tv_sec; // Print lib only supports 32 bit but time_t can be 64 bit on some platforms
LOG_DEBUG("Read RTC time from PCF8563 getDateTime as %02d-%02d-%02d %02d:%02d:%02d (%ld)\n", t.tm_year + 1900,
t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, printableEpoch);
LOG_DEBUG("Read RTC time from PCF8563 getDateTime as %02d-%02d-%02d %02d:%02d:%02d (%ld)", t.tm_year + 1900, t.tm_mon + 1,
t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, printableEpoch);
timeStartMsec = now;
zeroOffsetSecs = tv.tv_sec;
if (currentQuality == RTCQualityNone) {
@@ -89,7 +89,7 @@ void readFromRTC()
if (!gettimeofday(&tv, NULL)) {
uint32_t now = millis();
uint32_t printableEpoch = tv.tv_sec; // Print lib only supports 32 bit but time_t can be 64 bit on some platforms
LOG_DEBUG("Read RTC time as %ld\n", printableEpoch);
LOG_DEBUG("Read RTC time as %ld", printableEpoch);
timeStartMsec = now;
zeroOffsetSecs = tv.tv_sec;
}
@@ -112,7 +112,7 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpdate)
uint32_t printableEpoch = tv->tv_sec; // Print lib only supports 32 bit but time_t can be 64 bit on some platforms
#ifdef BUILD_EPOCH
if (tv->tv_sec < BUILD_EPOCH) {
LOG_WARN("Ignoring time (%ld) before build epoch (%ld)!\n", printableEpoch, BUILD_EPOCH);
LOG_WARN("Ignoring time (%ld) before build epoch (%ld)!", printableEpoch, BUILD_EPOCH);
return false;
}
#endif
@@ -120,21 +120,21 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpdate)
bool shouldSet;
if (forceUpdate) {
shouldSet = true;
LOG_DEBUG("Overriding current RTC quality (%s) with incoming time of RTC quality of %s\n", RtcName(currentQuality),
LOG_DEBUG("Overriding current RTC quality (%s) with incoming time of RTC quality of %s", RtcName(currentQuality),
RtcName(q));
} else if (q > currentQuality) {
shouldSet = true;
LOG_DEBUG("Upgrading time to quality %s\n", RtcName(q));
LOG_DEBUG("Upgrading time to quality %s", RtcName(q));
} else if (q == RTCQualityGPS) {
shouldSet = true;
LOG_DEBUG("Reapplying GPS time: %ld secs\n", printableEpoch);
LOG_DEBUG("Reapplying GPS time: %ld secs", printableEpoch);
} else if (q == RTCQualityNTP && !Throttle::isWithinTimespanMs(lastSetMsec, (12 * 60 * 60 * 1000UL))) {
// Every 12 hrs we will slam in a new NTP or Phone GPS / NTP time, to correct for local RTC clock drift
shouldSet = true;
LOG_DEBUG("Reapplying external time to correct clock drift %ld secs\n", printableEpoch);
LOG_DEBUG("Reapplying external time to correct clock drift %ld secs", printableEpoch);
} else {
shouldSet = false;
LOG_DEBUG("Current RTC quality: %s. Ignoring time of RTC quality of %s\n", RtcName(currentQuality), RtcName(q));
LOG_DEBUG("Current RTC quality: %s. Ignoring time of RTC quality of %s", RtcName(currentQuality), RtcName(q));
}
if (shouldSet) {
@@ -158,7 +158,7 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpdate)
#endif
tm *t = gmtime(&tv->tv_sec);
rtc.setTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_wday, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
LOG_DEBUG("RV3028_RTC setTime %02d-%02d-%02d %02d:%02d:%02d (%ld)\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
LOG_DEBUG("RV3028_RTC setTime %02d-%02d-%02d %02d:%02d:%02d (%ld)", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec, printableEpoch);
}
#elif defined(PCF8563_RTC)
@@ -172,8 +172,8 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpdate)
#endif
tm *t = gmtime(&tv->tv_sec);
rtc.setDateTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
LOG_DEBUG("PCF8563_RTC setDateTime %02d-%02d-%02d %02d:%02d:%02d (%ld)\n", t->tm_year + 1900, t->tm_mon + 1,
t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, printableEpoch);
LOG_DEBUG("PCF8563_RTC setDateTime %02d-%02d-%02d %02d:%02d:%02d (%ld)", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec, printableEpoch);
}
#elif defined(ARCH_ESP32)
settimeofday(tv, NULL);
@@ -228,9 +228,9 @@ bool perhapsSetRTC(RTCQuality q, struct tm &t)
tv.tv_sec = res;
tv.tv_usec = 0; // time.centisecond() * (10 / 1000);
// LOG_DEBUG("Got time from GPS month=%d, year=%d, unixtime=%ld\n", t.tm_mon, t.tm_year, tv.tv_sec);
// LOG_DEBUG("Got time from GPS month=%d, year=%d, unixtime=%ld", t.tm_mon, t.tm_year, tv.tv_sec);
if (t.tm_year < 0 || t.tm_year >= 300) {
// LOG_DEBUG("Ignoring invalid GPS month=%d, year=%d, unixtime=%ld\n", t.tm_mon, t.tm_year, tv.tv_sec);
// LOG_DEBUG("Ignoring invalid GPS month=%d, year=%d, unixtime=%ld", t.tm_mon, t.tm_year, tv.tv_sec);
return false;
} else {
return perhapsSetRTC(q, &tv);

View File

@@ -1,4 +1,4 @@
const char *failMessage = "Unable to %s\n";
const char *failMessage = "Unable to %s";
#define SEND_UBX_PACKET(TYPE, ID, DATA, ERRMSG, TIMEOUT) \
msglen = makeUBXPacket(TYPE, ID, sizeof(DATA), DATA); \

View File

@@ -79,13 +79,13 @@ bool EInkDisplay::forceDisplay(uint32_t msecLimit)
}
// Trigger the refresh in GxEPD2
LOG_DEBUG("Updating E-Paper... ");
LOG_DEBUG("Updating E-Paper");
adafruitDisplay->nextPage();
// End the update process
endUpdate();
LOG_DEBUG("done\n");
LOG_DEBUG("done");
return true;
}
@@ -123,7 +123,7 @@ void EInkDisplay::setDetected(uint8_t detected)
// Connect to the display - variant specific
bool EInkDisplay::connect()
{
LOG_INFO("Doing EInk init\n");
LOG_INFO("Doing EInk init");
#ifdef PIN_EINK_EN
// backlight power, HIGH is backlight on, LOW is off

View File

@@ -119,7 +119,7 @@ void EInkDynamicDisplay::endOrDetach()
awaitRefresh();
else {
// Async begins
LOG_DEBUG("Async full-refresh begins (dropping frames)\n");
LOG_DEBUG("Async full-refresh begins (dropping frames)");
notifyLater(intervalPollAsyncRefresh, DUE_POLL_ASYNCREFRESH, true); // Hand-off to NotifiedWorkerThread
}
}
@@ -133,7 +133,7 @@ void EInkDynamicDisplay::endOrDetach()
if (previousRefresh == FULL || previousRefresh == FAST) { // If refresh wasn't skipped (on unspecified..)
LOG_WARN(
"GxEPD2 version has not been modified to support async refresh; using fallback behavior. Please update lib_deps in "
"variant's platformio.ini file\n");
"variant's platformio.ini file");
EInkDisplay::endUpdate();
}
#endif
@@ -170,7 +170,7 @@ bool EInkDynamicDisplay::determineMode()
checkFastRequested();
if (refresh == UNSPECIFIED)
LOG_WARN("There was a flaw in the determineMode() logic.\n");
LOG_WARN("There was a flaw in the determineMode() logic.");
// -- Decision has been reached --
applyRefreshMode();
@@ -254,7 +254,7 @@ void EInkDynamicDisplay::checkRateLimiting()
if (Throttle::isWithinTimespanMs(previousRunMs, EINK_LIMIT_RATE_RESPONSIVE_SEC * 1000)) {
refresh = SKIPPED;
reason = EXCEEDED_RATELIMIT_FAST;
LOG_DEBUG("refresh=SKIPPED, reason=EXCEEDED_RATELIMIT_FAST, frameFlags=0x%x\n", frameFlags);
LOG_DEBUG("refresh=SKIPPED, reason=EXCEEDED_RATELIMIT_FAST, frameFlags=0x%x", frameFlags);
return;
}
}
@@ -271,7 +271,7 @@ void EInkDynamicDisplay::checkCosmetic()
if (frameFlags & COSMETIC) {
refresh = FULL;
reason = FLAGGED_COSMETIC;
LOG_DEBUG("refresh=FULL, reason=FLAGGED_COSMETIC, frameFlags=0x%x\n", frameFlags);
LOG_DEBUG("refresh=FULL, reason=FLAGGED_COSMETIC, frameFlags=0x%x", frameFlags);
}
}
@@ -286,7 +286,7 @@ void EInkDynamicDisplay::checkDemandingFast()
if (frameFlags & DEMAND_FAST) {
refresh = FAST;
reason = FLAGGED_DEMAND_FAST;
LOG_DEBUG("refresh=FAST, reason=FLAGGED_DEMAND_FAST, frameFlags=0x%x\n", frameFlags);
LOG_DEBUG("refresh=FAST, reason=FLAGGED_DEMAND_FAST, frameFlags=0x%x", frameFlags);
}
}
@@ -306,7 +306,7 @@ void EInkDynamicDisplay::checkFrameMatchesPrevious()
if (frameFlags == BACKGROUND && fastRefreshCount > 0) {
refresh = FULL;
reason = REDRAW_WITH_FULL;
LOG_DEBUG("refresh=FULL, reason=REDRAW_WITH_FULL, frameFlags=0x%x\n", frameFlags);
LOG_DEBUG("refresh=FULL, reason=REDRAW_WITH_FULL, frameFlags=0x%x", frameFlags);
return;
}
#endif
@@ -314,7 +314,7 @@ void EInkDynamicDisplay::checkFrameMatchesPrevious()
// Not redrawn, not COSMETIC, not DEMAND_FAST
refresh = SKIPPED;
reason = FRAME_MATCHED_PREVIOUS;
LOG_DEBUG("refresh=SKIPPED, reason=FRAME_MATCHED_PREVIOUS, frameFlags=0x%x\n", frameFlags);
LOG_DEBUG("refresh=SKIPPED, reason=FRAME_MATCHED_PREVIOUS, frameFlags=0x%x", frameFlags);
}
// Have too many fast-refreshes occured consecutively, since last full refresh?
@@ -328,7 +328,7 @@ void EInkDynamicDisplay::checkConsecutiveFastRefreshes()
if (fastRefreshCount >= EINK_LIMIT_FASTREFRESH) {
refresh = FULL;
reason = EXCEEDED_LIMIT_FASTREFRESH;
LOG_DEBUG("refresh=FULL, reason=EXCEEDED_LIMIT_FASTREFRESH, frameFlags=0x%x\n", frameFlags);
LOG_DEBUG("refresh=FULL, reason=EXCEEDED_LIMIT_FASTREFRESH, frameFlags=0x%x", frameFlags);
}
}
@@ -343,13 +343,13 @@ void EInkDynamicDisplay::checkFastRequested()
// If we want BACKGROUND to use fast. (FULL only when a limit is hit)
refresh = FAST;
reason = BACKGROUND_USES_FAST;
LOG_DEBUG("refresh=FAST, reason=BACKGROUND_USES_FAST, fastRefreshCount=%lu, frameFlags=0x%x\n", fastRefreshCount,
LOG_DEBUG("refresh=FAST, reason=BACKGROUND_USES_FAST, fastRefreshCount=%lu, frameFlags=0x%x", fastRefreshCount,
frameFlags);
#else
// If we do want to use FULL for BACKGROUND updates
refresh = FULL;
reason = FLAGGED_BACKGROUND;
LOG_DEBUG("refresh=FULL, reason=FLAGGED_BACKGROUND\n");
LOG_DEBUG("refresh=FULL, reason=FLAGGED_BACKGROUND");
#endif
}
@@ -357,7 +357,7 @@ void EInkDynamicDisplay::checkFastRequested()
if (frameFlags & RESPONSIVE) {
refresh = FAST;
reason = NO_OBJECTIONS;
LOG_DEBUG("refresh=FAST, reason=NO_OBJECTIONS, fastRefreshCount=%lu, frameFlags=0x%x\n", fastRefreshCount, frameFlags);
LOG_DEBUG("refresh=FAST, reason=NO_OBJECTIONS, fastRefreshCount=%lu, frameFlags=0x%x", fastRefreshCount, frameFlags);
}
}
@@ -438,7 +438,7 @@ void EInkDynamicDisplay::checkExcessiveGhosting()
if (ghostPixelCount > EINK_LIMIT_GHOSTING_PX) {
refresh = FULL;
reason = EXCEEDED_GHOSTINGLIMIT;
LOG_DEBUG("refresh=FULL, reason=EXCEEDED_GHOSTINGLIMIT, frameFlags=0x%x\n", frameFlags);
LOG_DEBUG("refresh=FULL, reason=EXCEEDED_GHOSTINGLIMIT, frameFlags=0x%x", frameFlags);
}
}
@@ -469,7 +469,7 @@ void EInkDynamicDisplay::joinAsyncRefresh()
if (!asyncRefreshRunning)
return;
LOG_DEBUG("Joining an async refresh in progress\n");
LOG_DEBUG("Joining an async refresh in progress");
// Continually poll the BUSY pin
while (adafruitDisplay->epd2.isBusy())
@@ -479,7 +479,7 @@ void EInkDynamicDisplay::joinAsyncRefresh()
adafruitDisplay->endAsyncFull(); // Run the end of nextPage() code
EInkDisplay::endUpdate(); // Run base-class code to finish off update (NOT our derived class override)
asyncRefreshRunning = false; // Unset the flag
LOG_DEBUG("Refresh complete\n");
LOG_DEBUG("Refresh complete");
// Note: this code only works because of a modification to meshtastic/GxEPD2.
// It is only equipped to intercept calls to nextPage()
@@ -503,7 +503,7 @@ void EInkDynamicDisplay::pollAsyncRefresh()
adafruitDisplay->endAsyncFull(); // Run the end of nextPage() code
EInkDisplay::endUpdate(); // Run base-class code to finish off update (NOT our derived class override)
asyncRefreshRunning = false; // Unset the flag
LOG_DEBUG("Async full-refresh complete\n");
LOG_DEBUG("Async full-refresh complete");
// Note: this code only works because of a modification to meshtastic/GxEPD2.
// It is only equipped to intercept calls to nextPage()

View File

@@ -144,7 +144,7 @@ static bool haveGlyphs(const char *str)
}
}
LOG_DEBUG("haveGlyphs=%d\n", have);
LOG_DEBUG("haveGlyphs=%d", have);
return have;
}
@@ -186,56 +186,6 @@ static void drawIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDispl
display->setTextAlignment(TEXT_ALIGN_LEFT); // Restore left align, just to be kind to any other unsuspecting code
}
static void drawOEMIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
// draw an xbm image.
// Please note that everything that should be transitioned
// needs to be drawn relative to x and y
// draw centered icon left to right and centered above the one line of app text
display->drawXbm(x + (SCREEN_WIDTH - oemStore.oem_icon_width) / 2,
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - oemStore.oem_icon_height) / 2 + 2, oemStore.oem_icon_width,
oemStore.oem_icon_height, (const uint8_t *)oemStore.oem_icon_bits.bytes);
switch (oemStore.oem_font) {
case 0:
display->setFont(FONT_SMALL);
break;
case 2:
display->setFont(FONT_LARGE);
break;
default:
display->setFont(FONT_MEDIUM);
break;
}
display->setTextAlignment(TEXT_ALIGN_LEFT);
const char *title = oemStore.oem_text;
display->drawString(x + getStringCenteredX(title), y + SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM, title);
display->setFont(FONT_SMALL);
// Draw region in upper left
if (upperMsg)
display->drawString(x + 0, y + 0, upperMsg);
// Draw version and shortname in upper right
char buf[25];
snprintf(buf, sizeof(buf), "%s\n%s", xstr(APP_VERSION_SHORT), haveGlyphs(owner.short_name) ? owner.short_name : "");
display->setTextAlignment(TEXT_ALIGN_RIGHT);
display->drawString(x + SCREEN_WIDTH, y + 0, buf);
screen->forceDisplay();
display->setTextAlignment(TEXT_ALIGN_LEFT); // Restore left align, just to be kind to any other unsuspecting code
}
static void drawOEMBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
// Draw region in upper left
const char *region = myRegion ? myRegion->name : NULL;
drawOEMIconScreen(region, display, state, x, y);
}
void Screen::drawFrameText(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y, const char *message)
{
uint16_t x_offset = display->width() / 2;
@@ -292,7 +242,7 @@ static void drawWelcomeScreen(OLEDDisplay *display, OLEDDisplayUiState *state, i
// draw overlay in bottom right corner of screen to show when notifications are muted or modifier key is active
static void drawFunctionOverlay(OLEDDisplay *display, OLEDDisplayUiState *state)
{
// LOG_DEBUG("Drawing function overlay\n");
// LOG_DEBUG("Drawing function overlay");
if (functionSymbals.begin() != functionSymbals.end()) {
char buf[64];
display->setFont(FONT_SMALL);
@@ -310,7 +260,7 @@ static void drawDeepSleepScreen(OLEDDisplay *display, OLEDDisplayUiState *state,
EINK_ADD_FRAMEFLAG(display, COSMETIC);
EINK_ADD_FRAMEFLAG(display, BLOCKING);
LOG_DEBUG("Drawing deep sleep screen\n");
LOG_DEBUG("Drawing deep sleep screen");
// Display displayStr on the screen
drawIconScreen("Sleeping", display, state, x, y);
@@ -319,7 +269,7 @@ static void drawDeepSleepScreen(OLEDDisplay *display, OLEDDisplayUiState *state,
/// Used on eink displays when screen updates are paused
static void drawScreensaverOverlay(OLEDDisplay *display, OLEDDisplayUiState *state)
{
LOG_DEBUG("Drawing screensaver overlay\n");
LOG_DEBUG("Drawing screensaver overlay");
EINK_ADD_FRAMEFLAG(display, COSMETIC); // Take the opportunity for a full-refresh
@@ -385,9 +335,9 @@ static void drawModuleFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int
} else {
// otherwise, just display the module frame that's aligned with the current frame
module_frame = state->currentFrame;
// LOG_DEBUG("Screen is not in transition. Frame: %d\n\n", module_frame);
// LOG_DEBUG("Screen is not in transition. Frame: %d", module_frame);
}
// LOG_DEBUG("Drawing Module Frame %d\n\n", module_frame);
// LOG_DEBUG("Drawing Module Frame %d", module_frame);
MeshModule &pi = *moduleFrames.at(module_frame);
pi.drawFrame(display, state, x, y);
}
@@ -962,7 +912,7 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state
const meshtastic_MeshPacket &mp = devicestate.rx_text_message;
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(getFrom(&mp));
// LOG_DEBUG("drawing text message from 0x%x: %s\n", mp.from,
// LOG_DEBUG("drawing text message from 0x%x: %s", mp.from,
// mp.decoded.variant.data.decoded.bytes);
// Demo for drawStringMaxWidth:
@@ -1500,7 +1450,7 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
if (!hasNodeHeading) {
// direction to node is unknown so display question mark
// Debug info for gps lock errors
// LOG_DEBUG("ourNode %d, ourPos %d, theirPos %d\n", !!ourNode, ourNode && hasValidPosition(ourNode),
// LOG_DEBUG("ourNode %d, ourPos %d, theirPos %d", !!ourNode, ourNode && hasValidPosition(ourNode),
// hasValidPosition(node));
display->drawString(compassX - FONT_HEIGHT_SMALL / 4, compassY - FONT_HEIGHT_SMALL / 2, "?");
}
@@ -1549,7 +1499,7 @@ Screen::Screen(ScanI2C::DeviceAddress address, meshtastic_Config_DisplayConfig_O
(address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE);
#elif ARCH_PORTDUINO
if (settingsMap[displayPanel] != no_screen) {
LOG_DEBUG("Making TFTDisplay!\n");
LOG_DEBUG("Making TFTDisplay!");
dispdev = new TFTDisplay(address.address, -1, -1, geometry,
(address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE);
} else {
@@ -1596,7 +1546,7 @@ void Screen::handleSetOn(bool on, FrameCallback einkScreensaver)
if (on != screenOn) {
if (on) {
LOG_INFO("Turning on screen\n");
LOG_INFO("Turning on screen");
powerMon->setState(meshtastic_PowerMon_State_Screen_On);
#ifdef T_WATCH_S3
PMU->enablePowerOutput(XPOWERS_ALDO2);
@@ -1631,7 +1581,7 @@ void Screen::handleSetOn(bool on, FrameCallback einkScreensaver)
// eInkScreensaver parameter is usually NULL (default argument), default frame used instead
setScreensaverFrames(einkScreensaver);
#endif
LOG_INFO("Turning off screen\n");
LOG_INFO("Turning off screen");
dispdev->displayOff();
#ifdef USE_ST7789
SPI1.end();
@@ -1699,9 +1649,6 @@ void Screen::setup()
// Set the utf8 conversion function
dispdev->setFontTableLookupFunction(customFontTableLookup);
if (strlen(oemStore.oem_text) > 0)
logo_timeout *= 2;
// Add frames.
EINK_ADD_FRAMEFLAG(dispdev, DEMAND_FAST);
alertFrames[0] = [this](OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -> void {
@@ -1842,28 +1789,11 @@ int32_t Screen::runOnce()
// serialSinceMsec adjusts for additional serial wait time during nRF52 bootup
static bool showingBootScreen = true;
if (showingBootScreen && (millis() > (logo_timeout + serialSinceMsec))) {
LOG_INFO("Done with boot screen...\n");
LOG_INFO("Done with boot screen...");
stopBootScreen();
showingBootScreen = false;
}
// If we have an OEM Boot screen, toggle after logo_timeout seconds
if (strlen(oemStore.oem_text) > 0) {
static bool showingOEMBootScreen = true;
if (showingOEMBootScreen && (millis() > ((logo_timeout / 2) + serialSinceMsec))) {
LOG_INFO("Switch to OEM screen...\n");
// Change frames.
static FrameCallback bootOEMFrames[] = {drawOEMBootScreen};
static const int bootOEMFrameCount = sizeof(bootOEMFrames) / sizeof(bootOEMFrames[0]);
ui->setFrames(bootOEMFrames, bootOEMFrameCount);
ui->update();
#ifndef USE_EINK
ui->update();
#endif
showingOEMBootScreen = false;
}
}
#ifndef DISABLE_WELCOME_UNSET
if (showingNormalScreen && config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_UNSET) {
setWelcomeFrames();
@@ -1917,7 +1847,7 @@ int32_t Screen::runOnce()
free(cmd.print_text);
break;
default:
LOG_ERROR("Invalid screen cmd\n");
LOG_ERROR("Invalid screen cmd");
}
}
@@ -1955,12 +1885,12 @@ int32_t Screen::runOnce()
EINK_ADD_FRAMEFLAG(dispdev, COSMETIC);
#endif
LOG_DEBUG("LastScreenTransition exceeded %ums transitioning to next frame\n", (millis() - lastScreenTransition));
LOG_DEBUG("LastScreenTransition exceeded %ums transitioning to next frame", (millis() - lastScreenTransition));
handleOnPress();
}
}
// LOG_DEBUG("want fps %d, fixed=%d\n", targetFramerate,
// LOG_DEBUG("want fps %d, fixed=%d", targetFramerate,
// ui->getUiState()->frameState); If we are scrolling we need to be called
// soon, otherwise just 1 fps (to save CPU) We also ask to be called twice
// as fast as we really need so that any rounding errors still result with
@@ -1991,7 +1921,7 @@ void Screen::drawDebugInfoWiFiTrampoline(OLEDDisplay *display, OLEDDisplayUiStat
void Screen::setSSLFrames()
{
if (address_found.address) {
// LOG_DEBUG("showing SSL frames\n");
// LOG_DEBUG("showing SSL frames");
static FrameCallback sslFrames[] = {drawSSLScreen};
ui->setFrames(sslFrames, 1);
ui->update();
@@ -2003,7 +1933,7 @@ void Screen::setSSLFrames()
void Screen::setWelcomeFrames()
{
if (address_found.address) {
// LOG_DEBUG("showing Welcome frames\n");
// LOG_DEBUG("showing Welcome frames");
static FrameCallback frames[] = {drawWelcomeScreen};
setFrameImmediateDraw(frames);
}
@@ -2069,7 +1999,7 @@ void Screen::setFrames(FrameFocus focus)
uint8_t originalPosition = ui->getUiState()->currentFrame;
FramesetInfo fsi; // Location of specific frames, for applying focus parameter
LOG_DEBUG("showing standard frames\n");
LOG_DEBUG("showing standard frames");
showingNormalScreen = true;
#ifdef USE_EINK
@@ -2082,10 +2012,10 @@ void Screen::setFrames(FrameFocus focus)
#endif
moduleFrames = MeshModule::GetMeshModulesWithUIFrames();
LOG_DEBUG("Showing %d module frames\n", moduleFrames.size());
LOG_DEBUG("Showing %d module frames", moduleFrames.size());
#ifdef DEBUG_PORT
int totalFrameCount = MAX_NUM_NODES + NUM_EXTRA_FRAMES + moduleFrames.size();
LOG_DEBUG("Total frame count: %d\n", totalFrameCount);
LOG_DEBUG("Total frame count: %d", totalFrameCount);
#endif
// We don't show the node info of our node (if we have it yet - we should)
@@ -2119,7 +2049,7 @@ void Screen::setFrames(FrameFocus focus)
numframes++;
}
LOG_DEBUG("Added modules. numframes: %d\n", numframes);
LOG_DEBUG("Added modules. numframes: %d", numframes);
// If we have a critical fault, show it first
fsi.positions.fault = numframes;
@@ -2164,7 +2094,7 @@ void Screen::setFrames(FrameFocus focus)
#endif
fsi.frameCount = numframes; // Total framecount is used to apply FOCUS_PRESERVE
LOG_DEBUG("Finished building frames. numframes: %d\n", numframes);
LOG_DEBUG("Finished building frames. numframes: %d", numframes);
ui->setFrames(normalFrames, numframes);
ui->enableAllIndicators();
@@ -2245,13 +2175,13 @@ void Screen::dismissCurrentFrame()
bool dismissed = false;
if (currentFrame == framesetInfo.positions.textMessage && devicestate.has_rx_text_message) {
LOG_INFO("Dismissing Text Message\n");
LOG_INFO("Dismissing Text Message");
devicestate.has_rx_text_message = false;
dismissed = true;
}
else if (currentFrame == framesetInfo.positions.waypoint && devicestate.has_rx_waypoint) {
LOG_DEBUG("Dismissing Waypoint\n");
LOG_DEBUG("Dismissing Waypoint");
devicestate.has_rx_waypoint = false;
dismissed = true;
}
@@ -2263,7 +2193,7 @@ void Screen::dismissCurrentFrame()
void Screen::handleStartFirmwareUpdateScreen()
{
LOG_DEBUG("showing firmware screen\n");
LOG_DEBUG("showing firmware screen");
showingNormalScreen = false;
EINK_ADD_FRAMEFLAG(dispdev, DEMAND_FAST); // E-Ink: Explicitly use fast-refresh for next frame
@@ -2355,7 +2285,7 @@ void Screen::handlePrint(const char *text)
{
// the string passed into us probably has a newline, but that would confuse the logging system
// so strip it
LOG_DEBUG("Screen: %.*s\n", strlen(text) - 1, text);
LOG_DEBUG("Screen: %.*s", strlen(text) - 1, text);
if (!useDisplay || !showingNormalScreen)
return;
@@ -2708,7 +2638,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
int Screen::handleStatusUpdate(const meshtastic::Status *arg)
{
// LOG_DEBUG("Screen got status update %d\n", arg->getStatusType());
// LOG_DEBUG("Screen got status update %d", arg->getStatusType());
switch (arg->getStatusType()) {
case STATUS_TYPE_NODE:
if (showingNormalScreen && nodeStatus->getLastNumTotal() != nodeStatus->getNumTotal()) {

View File

@@ -380,7 +380,7 @@ class LGFX : public lgfx::LGFX_Device
_panel_instance->setBus(&_bus_instance); // set the bus on the panel.
auto cfg = _panel_instance->config(); // Gets a structure for display panel settings.
LOG_DEBUG("Height: %d, Width: %d \n", settingsMap[displayHeight], settingsMap[displayWidth]);
LOG_DEBUG("Height: %d, Width: %d ", settingsMap[displayHeight], settingsMap[displayWidth]);
cfg.pin_cs = settingsMap[displayCS]; // Pin number where CS is connected (-1 = disable)
cfg.pin_rst = settingsMap[displayReset];
cfg.panel_width = settingsMap[displayWidth]; // actual displayable width
@@ -643,7 +643,7 @@ GpioPin *TFTDisplay::backlightEnable = NULL;
TFTDisplay::TFTDisplay(uint8_t address, int sda, int scl, OLEDDISPLAY_GEOMETRY geometry, HW_I2C i2cBus)
{
LOG_DEBUG("TFTDisplay!\n");
LOG_DEBUG("TFTDisplay!");
#ifdef TFT_BL
GpioPin *p = new GpioHwPin(TFT_BL);
@@ -712,7 +712,7 @@ void TFTDisplay::sendCommand(uint8_t com)
// handle display on/off directly
switch (com) {
case DISPLAYON: {
// LOG_DEBUG("Display on\n");
// LOG_DEBUG("Display on");
backlightEnable->set(true);
#if ARCH_PORTDUINO
display(true);
@@ -736,7 +736,7 @@ void TFTDisplay::sendCommand(uint8_t com)
break;
}
case DISPLAYOFF: {
// LOG_DEBUG("Display off\n");
// LOG_DEBUG("Display off");
backlightEnable->set(false);
#if ARCH_PORTDUINO
tft->clear();
@@ -772,14 +772,14 @@ void TFTDisplay::setDisplayBrightness(uint8_t _brightness)
// todo
#else
tft->setBrightness(_brightness);
LOG_DEBUG("Brightness is set to value: %i \n", _brightness);
LOG_DEBUG("Brightness is set to value: %i ", _brightness);
#endif
}
void TFTDisplay::flipScreenVertically()
{
#if defined(T_WATCH_S3)
LOG_DEBUG("Flip TFT vertically\n"); // T-Watch S3 right-handed orientation
LOG_DEBUG("Flip TFT vertically"); // T-Watch S3 right-handed orientation
tft->setRotation(0);
#endif
}
@@ -823,7 +823,7 @@ void TFTDisplay::setDetected(uint8_t detected)
bool TFTDisplay::connect()
{
concurrency::LockGuard g(spiLock);
LOG_INFO("Doing TFT init\n");
LOG_INFO("Doing TFT init");
#ifdef RAK14014
tft = new TFT_eSPI;
#else
@@ -831,7 +831,7 @@ bool TFTDisplay::connect()
#endif
backlightEnable->set(true);
LOG_INFO("Power to TFT Backlight\n");
LOG_INFO("Power to TFT Backlight");
#ifdef UNPHONE
unphone.backlight(true); // using unPhone library

View File

@@ -233,7 +233,7 @@ void ExpressLRSFiveWay::sendAdhocPing()
// Contained as one method for easier remapping of buttons by user
void ExpressLRSFiveWay::shutdown()
{
LOG_INFO("Shutdown from long press\n");
LOG_INFO("Shutdown from long press");
powerFSM.trigger(EVENT_PRESS);
screen->startAlert("Shutting down...");
// Don't set alerting = true. We don't want to auto-dismiss this alert.

View File

@@ -0,0 +1,430 @@
// Based on the BBQ10 Keyboard
#include "MPR121Keyboard.h"
#include "configuration.h"
#include <Arduino.h>
#define _MPR121_REG_KEY 0x5a
#define _MPR121_REG_TOUCH_STATUS 0x00
#define _MPR121_REG_ELECTRODE_FILTERED_DATA
#define _MPR121_REG_BASELINE_VALUE 0x1E
// Baseline filters
#define _MPR121_REG_MAX_HALF_DELTA_RISING 0x2B
#define _MPR121_REG_NOISE_HALF_DELTA_RISING 0x2C
#define _MPR121_REG_NOISE_COUNT_LIMIT_RISING 0x2D
#define _MPR121_REG_FILTER_DELAY_COUNT_RISING 0x2E
#define _MPR121_REG_MAX_HALF_DELTA_FALLING 0x2F
#define _MPR121_REG_NOISE_HALF_DELTA_FALLING 0x30
#define _MPR121_REG_NOISE_COUNT_LIMIT_FALLING 0x31
#define _MPR121_REG_FILTER_DELAY_COUNT_FALLING 0x32
#define _MPR121_REG_NOISE_HALF_DELTA_TOUCHED 0x33
#define _MPR121_REG_NOISE_COUNT_LIMIT_TOUCHED 0x34
#define _MPR121_REG_FILTER_DELAY_COUNT_TOUCHED 0x35
#define _MPR121_REG_TOUCH_THRESHOLD 0x41 // First input, +2 for subsequent
#define _MPR121_REG_RELEASE_THRESHOLD 0x42 // First input, +2 for subsequent
#define _MPR121_REG_DEBOUNCE 0x5B
#define _MPR121_REG_CONFIG1 0x5C
#define _MPR121_REG_CONFIG2 0x5D
#define _MPR121_REG_ELECTRODE_CONFIG 0x5E
#define _MPR121_REG_SOFT_RESET 0x80
#define _KEY_MASK 0x0FFF // Key mask for the first 12 bits
#define _NUM_KEYS 12
#define ECR_CALIBRATION_TRACK_FROM_ZERO (0 << 6)
#define ECR_CALIBRATION_LOCK (1 << 6)
#define ECR_CALIBRATION_TRACK_FROM_PARTIAL_FILTER (2 << 6) // Recommended Typical Mode
#define ECR_CALIBRATION_TRACK_FROM_FULL_FILTER (3 << 6)
#define ECR_PROXIMITY_DETECTION_OFF (0 << 0) // Not using proximity detection
#define ECR_TOUCH_DETECTION_12CH (12 << 0) // Using all 12 channels
#define MPR121_NONE 0x00
#define MPR121_REBOOT 0x90
#define MPR121_LEFT 0xb4
#define MPR121_UP 0xb5
#define MPR121_DOWN 0xb6
#define MPR121_RIGHT 0xb7
#define MPR121_ESC 0x1b
#define MPR121_BSP 0x08
#define MPR121_SELECT 0x0d
#define MPR121_FN_ON 0xf1
#define MPR121_FN_OFF 0xf2
#define LONG_PRESS_THRESHOLD 2000
#define MULTI_TAP_THRESHOLD 2000
uint8_t TapMod[12] = {1, 2, 1, 13, 7, 7, 7, 7, 7, 9, 7, 9}; // Num chars per key, Modulus for rotating through characters
unsigned char MPR121_TapMap[12][13] = {{MPR121_BSP},
{'0', ' '},
{MPR121_SELECT},
{'1', '.', ',', '?', '!', ':', ';', '-', '_', '\\', '/', '(', ')'},
{'2', 'a', 'b', 'c', 'A', 'B', 'C'},
{'3', 'd', 'e', 'f', 'D', 'E', 'F'},
{'4', 'g', 'h', 'i', 'G', 'H', 'I'},
{'5', 'j', 'k', 'l', 'J', 'K', 'L'},
{'6', 'm', 'n', 'o', 'M', 'N', 'O'},
{'7', 'p', 'q', 'r', 's', 'P', 'Q', 'R', 'S'},
{'8', 't', 'u', 'v', 'T', 'U', 'V'},
{'9', 'w', 'x', 'y', 'z', 'W', 'X', 'Y', 'Z'}};
unsigned char MPR121_LongPressMap[12] = {MPR121_ESC, ' ', MPR121_NONE, MPR121_NONE, MPR121_UP, MPR121_NONE,
MPR121_LEFT, MPR121_NONE, MPR121_RIGHT, MPR121_NONE, MPR121_DOWN, MPR121_NONE};
// Translation map from left to right, top to bottom layout to a more convenient layout to manufacture, matching the
// https://www.amazon.com.au/Capacitive-Sensitive-Sensitivity-Replacement-Traditional/dp/B0CTJD5KW9/ref=pd_ci_mcx_mh_mcx_views_0_title?th=1
/*uint8_t MPR121_KeyMap[12] = {
9, 6, 3, 0,
10, 7, 4, 1,
11, 8, 5, 2
};*/
// Rotated Layout
uint8_t MPR121_KeyMap[12] = {2, 5, 8, 11, 1, 4, 7, 10, 0, 3, 6, 9};
MPR121Keyboard::MPR121Keyboard() : m_wire(nullptr), m_addr(0), readCallback(nullptr), writeCallback(nullptr)
{
// LOG_DEBUG("MPR121 @ %02x\n", m_addr);
state = Init;
last_key = -1;
last_tap = 0L;
char_idx = 0;
queue = "";
}
void MPR121Keyboard::begin(uint8_t addr, TwoWire *wire)
{
m_addr = addr;
m_wire = wire;
m_wire->begin();
reset();
}
void MPR121Keyboard::begin(i2c_com_fptr_t r, i2c_com_fptr_t w, uint8_t addr)
{
m_addr = addr;
m_wire = nullptr;
writeCallback = w;
readCallback = r;
reset();
}
void MPR121Keyboard::reset()
{
LOG_DEBUG("MPR121 Resetting...");
// Trigger a MPR121 Soft Reset
if (m_wire) {
m_wire->beginTransmission(m_addr);
m_wire->write(_MPR121_REG_SOFT_RESET);
m_wire->endTransmission();
}
if (writeCallback) {
uint8_t data = 0;
writeCallback(m_addr, _MPR121_REG_SOFT_RESET, &data, 0);
}
delay(100);
// Reset Electrode Configuration to 0x00, Stop Mode
writeRegister(_MPR121_REG_ELECTRODE_CONFIG, 0x00);
delay(100);
LOG_DEBUG("MPR121 Configuring");
// Set touch release thresholds
for (uint8_t i = 0; i < 12; i++) {
// Set touch threshold
writeRegister(_MPR121_REG_TOUCH_THRESHOLD + (i * 2), 15);
delay(20);
// Set release threshold
writeRegister(_MPR121_REG_RELEASE_THRESHOLD + (i * 2), 7);
delay(20);
}
// Configure filtering and baseline registers
writeRegister(_MPR121_REG_MAX_HALF_DELTA_RISING, 0x01);
delay(20);
writeRegister(_MPR121_REG_MAX_HALF_DELTA_FALLING, 0x01);
delay(20);
writeRegister(_MPR121_REG_NOISE_HALF_DELTA_RISING, 0x01);
delay(20);
writeRegister(_MPR121_REG_NOISE_HALF_DELTA_FALLING, 0x05);
delay(20);
writeRegister(_MPR121_REG_NOISE_HALF_DELTA_TOUCHED, 0x00);
delay(20);
writeRegister(_MPR121_REG_NOISE_COUNT_LIMIT_RISING, 0x0e);
delay(20);
writeRegister(_MPR121_REG_NOISE_COUNT_LIMIT_FALLING, 0x01);
delay(20);
writeRegister(_MPR121_REG_NOISE_COUNT_LIMIT_TOUCHED, 0x00);
delay(20);
writeRegister(_MPR121_REG_FILTER_DELAY_COUNT_RISING, 0x00);
delay(20);
writeRegister(_MPR121_REG_FILTER_DELAY_COUNT_FALLING, 0x00);
delay(20);
writeRegister(_MPR121_REG_FILTER_DELAY_COUNT_TOUCHED, 0x00);
delay(20);
// Set Debounce to 0x02
writeRegister(_MPR121_REG_DEBOUNCE, 0x00);
delay(20);
// Set Filter1 itterations and discharge current 6x and 16uA respectively (0x10)
writeRegister(_MPR121_REG_CONFIG1, 0x10);
delay(20);
// Set CDT to 0.5us, Filter2 itterations to 4x, and Sample interval = 0 (0x20)
writeRegister(_MPR121_REG_CONFIG2, 0x20);
delay(20);
// Enter run mode by Seting partial filter calibration tracking, disable proximity detection, enable 12 channels
writeRegister(_MPR121_REG_ELECTRODE_CONFIG,
ECR_CALIBRATION_TRACK_FROM_PARTIAL_FILTER | ECR_PROXIMITY_DETECTION_OFF | ECR_TOUCH_DETECTION_12CH);
delay(100);
LOG_DEBUG("MPR121 Running");
state = Idle;
}
void MPR121Keyboard::attachInterrupt(uint8_t pin, void (*func)(void)) const
{
pinMode(pin, INPUT_PULLUP);
::attachInterrupt(digitalPinToInterrupt(pin), func, RISING);
}
void MPR121Keyboard::detachInterrupt(uint8_t pin) const
{
::detachInterrupt(pin);
}
uint8_t MPR121Keyboard::status() const
{
return readRegister16(_MPR121_REG_KEY);
}
uint8_t MPR121Keyboard::keyCount() const
{
// Read the key register
uint16_t keyRegister = readRegister16(_MPR121_REG_KEY);
return keyCount(keyRegister);
}
uint8_t MPR121Keyboard::keyCount(uint16_t value) const
{
// Mask the first 12 bits
uint16_t buttonState = value & _KEY_MASK;
// Count how many bits are set to 1 (i.e., how many buttons are pressed)
uint8_t numButtonsPressed = 0;
for (uint8_t i = 0; i < 12; ++i) {
if (buttonState & (1 << i)) {
numButtonsPressed++;
}
}
return numButtonsPressed;
}
bool MPR121Keyboard::hasEvent()
{
return queue.length() > 0;
}
void MPR121Keyboard::queueEvent(char next)
{
if (next == MPR121_NONE) {
return;
}
queue.concat(next);
}
char MPR121Keyboard::dequeueEvent()
{
if (queue.length() < 1) {
return MPR121_NONE;
}
char next = queue.charAt(0);
queue.remove(0, 1);
return next;
}
void MPR121Keyboard::trigger()
{
// Intended to fire in response to an interrupt from the MPR121 or a longpress callback
// Only functional if not in Init state
if (state != Init) {
// Read the key register
uint16_t keyRegister = readRegister16(_MPR121_REG_KEY);
uint8_t keysPressed = keyCount(keyRegister);
if (keysPressed == 0) {
// No buttons pressed
if (state == Held)
released();
state = Idle;
return;
}
if (keysPressed == 1) {
// No buttons pressed
if (state == Held || state == HeldLong)
held(keyRegister);
if (state == Idle)
pressed(keyRegister);
return;
}
if (keysPressed > 1) {
// Multipress
state = Busy;
return;
}
} else {
reset();
}
}
void MPR121Keyboard::pressed(uint16_t keyRegister)
{
if (state == Init || state == Busy) {
return;
}
if (keyCount(keyRegister) != 1) {
LOG_DEBUG("Multipress");
return;
} else {
LOG_DEBUG("Pressed");
}
uint16_t buttonState = keyRegister & _KEY_MASK;
uint8_t next_pin = 0;
for (uint8_t i = 0; i < 12; ++i) {
if (buttonState & (1 << i)) {
next_pin = i;
}
}
uint8_t next_key = MPR121_KeyMap[next_pin];
LOG_DEBUG("MPR121 Pin: %i Key: %i", next_pin, next_key);
uint32_t now = millis();
int32_t tap_interval = now - last_tap;
if (tap_interval < 0) {
// long running, millis has overflowed.
last_tap = 0;
state = Busy;
return;
}
if (next_key != last_key || tap_interval > MULTI_TAP_THRESHOLD) {
char_idx = 0;
} else {
char_idx += 1;
}
last_key = next_key;
last_tap = now;
state = Held;
return;
}
void MPR121Keyboard::held(uint16_t keyRegister)
{
if (state == Init || state == Busy) {
return;
}
if (keyCount(keyRegister) != 1) {
return;
}
LOG_DEBUG("Held");
uint16_t buttonState = keyRegister & _KEY_MASK;
uint8_t next_key = 0;
for (uint8_t i = 0; i < 12; ++i) {
if (buttonState & (1 << i)) {
next_key = MPR121_KeyMap[i];
}
}
uint32_t now = millis();
int32_t held_interval = now - last_tap;
if (held_interval < 0 || next_key != last_key) {
// long running, millis has overflowed, or a key has been switched quickly...
last_tap = 0;
state = Busy;
return;
}
if (held_interval > LONG_PRESS_THRESHOLD) {
// Set state to heldlong, send a longpress, and reset the timer...
state = HeldLong; // heldlong will allow this function to still fire, but prevent a "release"
queueEvent(MPR121_LongPressMap[last_key]);
last_tap = now;
LOG_DEBUG("Long Press Key: %i Map: %i", last_key, MPR121_LongPressMap[last_key]);
}
return;
}
void MPR121Keyboard::released()
{
if (state != Held) {
return;
}
// would clear longpress callback... later.
if (last_key < 0 || last_key > _NUM_KEYS) { // reset to idle if last_key out of bounds
last_key = -1;
state = Idle;
return;
}
LOG_DEBUG("Released");
if (char_idx > 0 && TapMod[last_key] > 1) {
queueEvent(MPR121_BSP);
LOG_DEBUG("Multi Press, Backspace");
}
queueEvent(MPR121_TapMap[last_key][(char_idx % TapMod[last_key])]);
LOG_DEBUG("Key Press: %i Index:%i if %i Map: %i", last_key, char_idx, TapMod[last_key],
MPR121_TapMap[last_key][(char_idx % TapMod[last_key])]);
}
uint8_t MPR121Keyboard::readRegister8(uint8_t reg) const
{
if (m_wire) {
m_wire->beginTransmission(m_addr);
m_wire->write(reg);
m_wire->endTransmission();
m_wire->requestFrom(m_addr, (uint8_t)1);
if (m_wire->available() < 1)
return 0;
return m_wire->read();
}
if (readCallback) {
uint8_t data;
readCallback(m_addr, reg, &data, 1);
return data;
}
return 0;
}
uint16_t MPR121Keyboard::readRegister16(uint8_t reg) const
{
uint8_t data[2] = {0};
// uint8_t low = 0, high = 0;
if (m_wire) {
m_wire->beginTransmission(m_addr);
m_wire->write(reg);
m_wire->endTransmission();
m_wire->requestFrom(m_addr, (uint8_t)2);
if (m_wire->available() < 2)
return 0;
data[0] = m_wire->read();
data[1] = m_wire->read();
}
if (readCallback) {
readCallback(m_addr, reg, data, 2);
}
return (data[1] << 8) | data[0];
}
void MPR121Keyboard::writeRegister(uint8_t reg, uint8_t value)
{
uint8_t data[2];
data[0] = reg;
data[1] = value;
if (m_wire) {
m_wire->beginTransmission(m_addr);
m_wire->write(data, sizeof(uint8_t) * 2);
m_wire->endTransmission();
}
if (writeCallback) {
writeCallback(m_addr, data[0], &(data[1]), 1);
}
}

View File

@@ -0,0 +1,56 @@
// Based on the BBQ10 Keyboard
#include "concurrency/NotifiedWorkerThread.h"
#include "configuration.h"
#include <Wire.h>
#include <main.h>
class MPR121Keyboard
{
public:
typedef uint8_t (*i2c_com_fptr_t)(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint8_t len);
enum MPR121States { Init = 0, Idle, Held, HeldLong, Busy };
MPR121States state;
int8_t last_key;
uint32_t last_tap;
uint8_t char_idx;
String queue;
MPR121Keyboard();
void begin(uint8_t addr = MPR121_KB_ADDR, TwoWire *wire = &Wire);
void begin(i2c_com_fptr_t r, i2c_com_fptr_t w, uint8_t addr = MPR121_KB_ADDR);
void reset(void);
void attachInterrupt(uint8_t pin, void (*func)(void)) const;
void detachInterrupt(uint8_t pin) const;
void trigger(void);
void pressed(uint16_t value);
void held(uint16_t value);
void released(void);
uint8_t status(void) const;
uint8_t keyCount(void) const;
uint8_t keyCount(uint16_t value) const;
bool hasEvent(void);
char dequeueEvent(void);
void queueEvent(char);
uint8_t readRegister8(uint8_t reg) const;
uint16_t readRegister16(uint8_t reg) const;
void writeRegister(uint8_t reg, uint8_t value);
private:
TwoWire *m_wire;
uint8_t m_addr;
i2c_com_fptr_t readCallback;
i2c_com_fptr_t writeCallback;
};

View File

@@ -28,7 +28,7 @@ void RotaryEncoderInterruptBase::init(
this->rotaryLevelA = digitalRead(this->_pinA);
this->rotaryLevelB = digitalRead(this->_pinB);
LOG_INFO("Rotary initialized (%d, %d, %d)\n", this->_pinA, this->_pinB, pinPress);
LOG_INFO("Rotary initialized (%d, %d, %d)", this->_pinA, this->_pinB, pinPress);
}
int32_t RotaryEncoderInterruptBase::runOnce()
@@ -38,13 +38,13 @@ int32_t RotaryEncoderInterruptBase::runOnce()
e.source = this->_originName;
if (this->action == ROTARY_ACTION_PRESSED) {
LOG_DEBUG("Rotary event Press\n");
LOG_DEBUG("Rotary event Press");
e.inputEvent = this->_eventPressed;
} else if (this->action == ROTARY_ACTION_CW) {
LOG_DEBUG("Rotary event CW\n");
LOG_DEBUG("Rotary event CW");
e.inputEvent = this->_eventCw;
} else if (this->action == ROTARY_ACTION_CCW) {
LOG_DEBUG("Rotary event CCW\n");
LOG_DEBUG("Rotary event CCW");
e.inputEvent = this->_eventCcw;
}

View File

@@ -47,7 +47,7 @@ bool ScanAndSelectInput::init()
// Connect our class to the canned message module
inputBroker->registerSource(this);
LOG_INFO("Initialized 'Scan and Select' input for Canned Messages, using pin %d\n", pin);
LOG_INFO("Initialized 'Scan and Select' input for Canned Messages, using pin %d", pin);
return true; // Init succeded
}
@@ -59,7 +59,7 @@ int32_t ScanAndSelectInput::runOnce()
// If: "no messages added" alert screen currently shown
if (alertingNoMessage) {
// Dismiss the alert screen several seconds after it appears
if (now > alertingSinceMs + durationAlertMs) {
if (!Throttle::isWithinTimespanMs(alertingSinceMs, durationAlertMs)) {
alertingNoMessage = false;
screen->endAlert();
}
@@ -74,9 +74,9 @@ int32_t ScanAndSelectInput::runOnce()
// Existing press
else {
// Duration enough for long press
// Longer than shortpress window
// Long press not yet fired (prevent repeat firing while held)
if (!longPressFired && Throttle::isWithinTimespanMs(downSinceMs, durationLongMs)) {
if (!longPressFired && !Throttle::isWithinTimespanMs(downSinceMs, durationLongMs)) {
longPressFired = true;
longPress();
}
@@ -91,7 +91,9 @@ int32_t ScanAndSelectInput::runOnce()
// Button newly released
// Long press event didn't already fire
if (held && !longPressFired) {
// Duration enough for short press
// Duration within shortpress window
// - longer than durationShortPress (debounce)
// - shorter than durationLongPress
if (!Throttle::isWithinTimespanMs(downSinceMs, durationShortMs)) {
shortPress();
}

View File

@@ -52,7 +52,7 @@ int32_t SerialKeyboard::runOnce()
digitalWrite(KB_LOAD, HIGH);
digitalWrite(KB_CLK, LOW);
prevKeys = 0b1111111111111111;
LOG_DEBUG("Serial Keyboard setup\n");
LOG_DEBUG("Serial Keyboard setup");
}
if (INPUTBROKER_SERIAL_TYPE == 1) { // Chatter V1.0 & V2.0 keypads

View File

@@ -23,7 +23,7 @@ TouchScreenBase::TouchScreenBase(const char *name, uint16_t width, uint16_t heig
void TouchScreenBase::init(bool hasTouch)
{
if (hasTouch) {
LOG_INFO("TouchScreen initialized %d %d\n", TOUCH_THRESHOLD_X, TOUCH_THRESHOLD_Y);
LOG_INFO("TouchScreen initialized %d %d", TOUCH_THRESHOLD_X, TOUCH_THRESHOLD_Y);
this->setInterval(100);
} else {
disable();
@@ -68,20 +68,20 @@ int32_t TouchScreenBase::runOnce()
if (adx > ady && adx > TOUCH_THRESHOLD_X) {
if (0 > dx) { // swipe right to left
e.touchEvent = static_cast<char>(TOUCH_ACTION_LEFT);
LOG_DEBUG("action SWIPE: right to left\n");
LOG_DEBUG("action SWIPE: right to left");
} else { // swipe left to right
e.touchEvent = static_cast<char>(TOUCH_ACTION_RIGHT);
LOG_DEBUG("action SWIPE: left to right\n");
LOG_DEBUG("action SWIPE: left to right");
}
}
// swipe vertical
else if (ady > adx && ady > TOUCH_THRESHOLD_Y) {
if (0 > dy) { // swipe bottom to top
e.touchEvent = static_cast<char>(TOUCH_ACTION_UP);
LOG_DEBUG("action SWIPE: bottom to top\n");
LOG_DEBUG("action SWIPE: bottom to top");
} else { // swipe top to bottom
e.touchEvent = static_cast<char>(TOUCH_ACTION_DOWN);
LOG_DEBUG("action SWIPE: top to bottom\n");
LOG_DEBUG("action SWIPE: top to bottom");
}
}
// tap
@@ -90,7 +90,7 @@ int32_t TouchScreenBase::runOnce()
if (_tapped) {
_tapped = false;
e.touchEvent = static_cast<char>(TOUCH_ACTION_DOUBLE_TAP);
LOG_DEBUG("action DOUBLE TAP(%d/%d)\n", x, y);
LOG_DEBUG("action DOUBLE TAP(%d/%d)", x, y);
} else {
_tapped = true;
}
@@ -106,7 +106,7 @@ int32_t TouchScreenBase::runOnce()
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);
LOG_DEBUG("action TAP(%d/%d)", _last_x, _last_y);
}
// fire LONG_PRESS event without the need for release
@@ -114,7 +114,7 @@ int32_t TouchScreenBase::runOnce()
// tricky: prevent reoccurring events and another touch event when releasing
_start = millis() + 30000;
e.touchEvent = static_cast<char>(TOUCH_ACTION_LONG_PRESS);
LOG_DEBUG("action LONG PRESS(%d/%d)\n", _last_x, _last_y);
LOG_DEBUG("action LONG PRESS(%d/%d)", _last_x, _last_y);
}
if (e.touchEvent != TOUCH_ACTION_NONE) {

View File

@@ -30,7 +30,7 @@ void TrackballInterruptBase::init(uint8_t pinDown, uint8_t pinUp, uint8_t pinLef
attachInterrupt(this->_pinLeft, onIntLeft, RISING);
attachInterrupt(this->_pinRight, onIntRight, RISING);
LOG_DEBUG("Trackball GPIO initialized (%d, %d, %d, %d, %d)\n", this->_pinUp, this->_pinDown, this->_pinLeft, this->_pinRight,
LOG_DEBUG("Trackball GPIO initialized (%d, %d, %d, %d, %d)", this->_pinUp, this->_pinDown, this->_pinLeft, this->_pinRight,
pinPress);
this->setInterval(100);
@@ -42,19 +42,19 @@ int32_t TrackballInterruptBase::runOnce()
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
if (this->action == TB_ACTION_PRESSED) {
// LOG_DEBUG("Trackball event Press\n");
// LOG_DEBUG("Trackball event Press");
e.inputEvent = this->_eventPressed;
} else if (this->action == TB_ACTION_UP) {
// LOG_DEBUG("Trackball event UP\n");
// LOG_DEBUG("Trackball event UP");
e.inputEvent = this->_eventUp;
} else if (this->action == TB_ACTION_DOWN) {
// LOG_DEBUG("Trackball event DOWN\n");
// LOG_DEBUG("Trackball event DOWN");
e.inputEvent = this->_eventDown;
} else if (this->action == TB_ACTION_LEFT) {
// LOG_DEBUG("Trackball event LEFT\n");
// LOG_DEBUG("Trackball event LEFT");
e.inputEvent = this->_eventLeft;
} else if (this->action == TB_ACTION_RIGHT) {
// LOG_DEBUG("Trackball event RIGHT\n");
// LOG_DEBUG("Trackball event RIGHT");
e.inputEvent = this->_eventRight;
}

View File

@@ -23,7 +23,7 @@ void UpDownInterruptBase::init(uint8_t pinDown, uint8_t pinUp, uint8_t pinPress,
attachInterrupt(this->_pinDown, onIntDown, RISING);
attachInterrupt(this->_pinUp, onIntUp, RISING);
LOG_DEBUG("Up/down/press GPIO initialized (%d, %d, %d)\n", this->_pinUp, this->_pinDown, pinPress);
LOG_DEBUG("Up/down/press GPIO initialized (%d, %d, %d)", this->_pinUp, this->_pinDown, pinPress);
this->setInterval(100);
}
@@ -34,13 +34,13 @@ int32_t UpDownInterruptBase::runOnce()
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
if (this->action == UPDOWN_ACTION_PRESSED) {
LOG_DEBUG("GPIO event Press\n");
LOG_DEBUG("GPIO event Press");
e.inputEvent = this->_eventPressed;
} else if (this->action == UPDOWN_ACTION_UP) {
LOG_DEBUG("GPIO event Up\n");
LOG_DEBUG("GPIO event Up");
e.inputEvent = this->_eventUp;
} else if (this->action == UPDOWN_ACTION_DOWN) {
LOG_DEBUG("GPIO event Down\n");
LOG_DEBUG("GPIO event Down");
e.inputEvent = this->_eventDown;
}

View File

@@ -9,11 +9,11 @@ CardKbI2cImpl::CardKbI2cImpl() : KbI2cBase("cardKB") {}
void CardKbI2cImpl::init()
{
#if !MESHTASTIC_EXCLUDE_I2C && !defined(ARCH_PORTDUINO)
#if !MESHTASTIC_EXCLUDE_I2C && !defined(ARCH_PORTDUINO) && !defined(I2C_NO_RESCAN)
if (cardkb_found.address == 0x00) {
LOG_DEBUG("Rescanning for I2C keyboard\n");
uint8_t i2caddr_scan[] = {CARDKB_ADDR, TDECK_KB_ADDR, BBQ10_KB_ADDR};
uint8_t i2caddr_asize = 3;
LOG_DEBUG("Rescanning for I2C keyboard");
uint8_t i2caddr_scan[] = {CARDKB_ADDR, TDECK_KB_ADDR, BBQ10_KB_ADDR, MPR121_KB_ADDR};
uint8_t i2caddr_asize = 4;
auto i2cScanner = std::unique_ptr<ScanI2CTwoWire>(new ScanI2CTwoWire());
#if WIRE_INTERFACES_COUNT == 2
@@ -39,12 +39,17 @@ void CardKbI2cImpl::init()
// assign an arbitrary value to distinguish from other models
kb_model = 0x11;
break;
case ScanI2C::DeviceType::MPR121KB:
// assign an arbitrary value to distinguish from other models
kb_model = 0x37;
break;
default:
// use this as default since it's also just zero
LOG_WARN("kb_info.type is unknown(0x%02x), setting kb_model=0x00\n", kb_info.type);
LOG_WARN("kb_info.type is unknown(0x%02x), setting kb_model=0x00", kb_info.type);
kb_model = 0x00;
}
}
LOG_DEBUG("Keyboard Type: 0x%02x Model: 0x%02x Address: 0x%02x", kb_info.type, kb_model, cardkb_found.address);
if (cardkb_found.address == 0x00) {
disable();
return;

View File

@@ -34,21 +34,27 @@ int32_t KbI2cBase::runOnce()
switch (cardkb_found.port) {
case ScanI2C::WIRE1:
#if WIRE_INTERFACES_COUNT == 2
LOG_DEBUG("Using I2C Bus 1 (the second one)\n");
LOG_DEBUG("Using I2C Bus 1 (the second one)");
i2cBus = &Wire1;
if (cardkb_found.address == BBQ10_KB_ADDR) {
Q10keyboard.begin(BBQ10_KB_ADDR, &Wire1);
Q10keyboard.setBacklight(0);
}
if (cardkb_found.address == MPR121_KB_ADDR) {
MPRkeyboard.begin(MPR121_KB_ADDR, &Wire1);
}
break;
#endif
case ScanI2C::WIRE:
LOG_DEBUG("Using I2C Bus 0 (the first one)\n");
LOG_DEBUG("Using I2C Bus 0 (the first one)");
i2cBus = &Wire;
if (cardkb_found.address == BBQ10_KB_ADDR) {
Q10keyboard.begin(BBQ10_KB_ADDR, &Wire);
Q10keyboard.setBacklight(0);
}
if (cardkb_found.address == MPR121_KB_ADDR) {
MPRkeyboard.begin(MPR121_KB_ADDR, &Wire);
}
break;
case ScanI2C::NO_I2C:
default:
@@ -157,6 +163,69 @@ int32_t KbI2cBase::runOnce()
}
break;
}
case 0x37: { // MPR121
MPRkeyboard.trigger();
InputEvent e;
while (MPRkeyboard.hasEvent()) {
char nextEvent = MPRkeyboard.dequeueEvent();
e.inputEvent = ANYKEY;
e.kbchar = 0x00;
e.source = this->_originName;
switch (nextEvent) {
case 0x00: // MPR121_NONE
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
e.kbchar = 0x00;
break;
case 0x90: // MPR121_REBOOT
e.inputEvent = ANYKEY;
e.kbchar = INPUT_BROKER_MSG_REBOOT;
break;
case 0xb4: // MPR121_LEFT
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT;
e.kbchar = 0x00;
break;
case 0xb5: // MPR121_UP
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP;
e.kbchar = 0x00;
break;
case 0xb6: // MPR121_DOWN
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN;
e.kbchar = 0x00;
break;
case 0xb7: // MPR121_RIGHT
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT;
e.kbchar = 0x00;
break;
case 0x1b: // MPR121_ESC
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL;
e.kbchar = 0x1b;
break;
case 0x08: // MPR121_BSP
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_BACK;
e.kbchar = 0x08;
break;
case 0x0d: // MPR121_SELECT
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT;
e.kbchar = 0x0d;
break;
default:
if (nextEvent > 127) {
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
e.kbchar = 0x00;
break;
}
e.inputEvent = ANYKEY;
e.kbchar = nextEvent;
break;
}
if (e.inputEvent != meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE) {
LOG_DEBUG("MP121 Notifying: %i Char: %i", e.inputEvent, e.kbchar);
this->notifyObservers(&e);
}
}
break;
}
case 0x02: {
// RAK14004
uint8_t rDataBuf[8] = {0};
@@ -171,7 +240,7 @@ int32_t KbI2cBase::runOnce()
}
}
if (PrintDataBuf != 0) {
LOG_DEBUG("RAK14004 key 0x%x pressed\n", PrintDataBuf);
LOG_DEBUG("RAK14004 key 0x%x pressed", PrintDataBuf);
InputEvent e;
e.inputEvent = MATRIXKEY;
e.source = this->_originName;
@@ -326,7 +395,7 @@ int32_t KbI2cBase::runOnce()
break;
}
default:
LOG_WARN("Unknown kb_model 0x%02x\n", kb_model);
LOG_WARN("Unknown kb_model 0x%02x", kb_model);
}
return 300;
}

View File

@@ -2,6 +2,7 @@
#include "BBQ10Keyboard.h"
#include "InputBroker.h"
#include "MPR121Keyboard.h"
#include "Wire.h"
#include "concurrency/OSThread.h"
@@ -19,5 +20,6 @@ class KbI2cBase : public Observable<const InputEvent *>, public concurrency::OST
TwoWire *i2cBus = 0;
BBQ10Keyboard Q10keyboard;
MPR121Keyboard MPRkeyboard;
bool is_sym = false;
};
};

View File

@@ -70,7 +70,7 @@ int32_t KbMatrixBase::runOnce()
// debounce
if (key != prevkey) {
if (key != 0) {
LOG_DEBUG("Key 0x%x pressed\n", key);
LOG_DEBUG("Key 0x%x pressed", key);
// reset shift now that we have a keypress
InputEvent e;
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
@@ -122,7 +122,7 @@ int32_t KbMatrixBase::runOnce()
}
} else {
LOG_WARN("Unknown kb_model 0x%02x\n", INPUTBROKER_MATRIX_TYPE);
LOG_WARN("Unknown kb_model 0x%02x", INPUTBROKER_MATRIX_TYPE);
return disable();
}
return 50; // Keyscan every 50msec to avoid key bounce

View File

@@ -27,7 +27,6 @@
#include "detect/ScanI2CTwoWire.h"
#include <Wire.h>
#endif
#include "detect/axpDebug.h"
#include "detect/einkScan.h"
#include "graphics/RAKled.h"
#include "graphics/Screen.h"
@@ -238,7 +237,7 @@ void lateInitVariant() {}
*/
void printInfo()
{
LOG_INFO("S:B:%d,%s\n", HW_VENDOR, optstr(APP_VERSION));
LOG_INFO("S:B:%d,%s", HW_VENDOR, optstr(APP_VERSION));
}
#ifndef PIO_UNIT_TESTING
void setup()
@@ -267,17 +266,22 @@ void setup()
#ifdef DEBUG_PORT
consoleInit(); // Set serial baud rate and init our mesh console
#endif
#ifdef UNPHONE
unphone.printStore();
#endif
#if ARCH_PORTDUINO
struct timeval tv;
tv.tv_sec = time(NULL);
tv.tv_usec = 0;
perhapsSetRTC(RTCQualityNTP, &tv);
#endif
powerMonInit();
powerMonInit();
serialSinceMsec = millis();
LOG_INFO("\n\n//\\ E S H T /\\ S T / C\n\n");
LOG_INFO("\n\n//\\ E S H T /\\ S T / C\n");
initDeepSleep();
@@ -324,7 +328,7 @@ void setup()
#ifdef PERIPHERAL_WARMUP_MS
// Some peripherals may require additional time to stabilize after power is connected
// e.g. I2C on Heltec Vision Master
LOG_INFO("Waiting for peripherals to stabilize\n");
LOG_INFO("Waiting for peripherals to stabilize");
delay(PERIPHERAL_WARMUP_MS);
#endif
@@ -385,10 +389,10 @@ void setup()
Wire.begin(I2C_SDA, I2C_SCL);
#elif defined(ARCH_PORTDUINO)
if (settingsStrings[i2cdev] != "") {
LOG_INFO("Using %s as I2C device.\n", settingsStrings[i2cdev].c_str());
LOG_INFO("Using %s as I2C device.", settingsStrings[i2cdev].c_str());
Wire.begin(settingsStrings[i2cdev].c_str());
} else {
LOG_INFO("No I2C device configured, skipping.\n");
LOG_INFO("No I2C device configured, skipping.");
}
#elif HAS_WIRE
Wire.begin();
@@ -431,7 +435,7 @@ void setup()
// accessories
auto i2cScanner = std::unique_ptr<ScanI2CTwoWire>(new ScanI2CTwoWire());
#if HAS_WIRE
LOG_INFO("Scanning for i2c devices...\n");
LOG_INFO("Scanning for i2c devices...");
#endif
#if defined(I2C_SDA1) && defined(ARCH_RP2040)
@@ -456,7 +460,7 @@ void setup()
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE);
#elif defined(ARCH_PORTDUINO)
if (settingsStrings[i2cdev] != "") {
LOG_INFO("Scanning for i2c devices...\n");
LOG_INFO("Scanning for i2c devices...");
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE);
}
#elif HAS_WIRE
@@ -465,9 +469,9 @@ void setup()
auto i2cCount = i2cScanner->countDevices();
if (i2cCount == 0) {
LOG_INFO("No I2C devices found\n");
LOG_INFO("No I2C devices found");
} else {
LOG_INFO("%i I2C devices found\n", i2cCount);
LOG_INFO("%i I2C devices found", i2cCount);
#ifdef SENSOR_GPS_CONFLICT
sensor_detected = true;
#endif
@@ -523,9 +527,13 @@ void setup()
// assign an arbitrary value to distinguish from other models
kb_model = 0x11;
break;
case ScanI2C::DeviceType::MPR121KB:
// assign an arbitrary value to distinguish from other models
kb_model = 0x37;
break;
default:
// use this as default since it's also just zero
LOG_WARN("kb_info.type is unknown(0x%02x), setting kb_model=0x00\n", kb_info.type);
LOG_WARN("kb_info.type is unknown(0x%02x), setting kb_model=0x00", kb_info.type);
kb_model = 0x00;
}
}
@@ -561,7 +569,7 @@ void setup()
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
auto acc_info = i2cScanner->firstAccelerometer();
accelerometer_found = acc_info.type != ScanI2C::DeviceType::NONE ? acc_info.address : accelerometer_found;
LOG_DEBUG("acc_info = %i\n", acc_info.type);
LOG_DEBUG("acc_info = %i", acc_info.type);
#endif
#define STRING(S) #S
@@ -572,7 +580,7 @@ void setup()
if (found.type != ScanI2C::DeviceType::NONE) { \
nodeTelemetrySensorsMap[PB_T].first = found.address.address; \
nodeTelemetrySensorsMap[PB_T].second = i2cScanner->fetchI2CBus(found.address); \
LOG_DEBUG("found i2c sensor %s\n", STRING(PB_T)); \
LOG_DEBUG("found i2c sensor %s", STRING(PB_T)); \
} \
}
@@ -624,7 +632,7 @@ void setup()
// Hello
printInfo();
#ifdef BUILD_EPOCH
LOG_INFO("Build timestamp: %ld\n", BUILD_EPOCH);
LOG_INFO("Build timestamp: %ld", BUILD_EPOCH);
#endif
#ifdef ARCH_ESP32
@@ -639,6 +647,8 @@ void setup()
rp2040Setup();
#endif
initSPI(); // needed here before reading from littleFS
// We do this as early as possible because this loads preferences from flash
// but we need to do this after main cpu init (esp32setup), because we need the random seed set
nodeDB = new NodeDB;
@@ -661,7 +671,7 @@ void setup()
if (config.power.is_power_saving == true &&
IS_ONE_OF(config.device.role, meshtastic_Config_DeviceConfig_Role_TRACKER,
meshtastic_Config_DeviceConfig_Role_TAK_TRACKER, meshtastic_Config_DeviceConfig_Role_SENSOR))
LOG_DEBUG("Tracker/Sensor: Skipping start melody\n");
LOG_DEBUG("Tracker/Sensor: Skipping start melody");
else
playStartMelody();
@@ -671,7 +681,7 @@ void setup()
#if defined(USE_SH1107)
screen_model = meshtastic_Config_DisplayConfig_OledType_OLED_SH1107; // set dimension of 128x128
display_geometry = GEOMETRY_128_128;
screen_geometry = GEOMETRY_128_128;
#endif
#if defined(USE_SH1107_128_64)
@@ -702,7 +712,6 @@ void setup()
#endif
// Init our SPI controller (must be before screen and lora)
initSPI();
#ifdef ARCH_RP2040
#ifdef HW_SPI1_DEVICE
SPI1.setSCK(LORA_SCK);
@@ -722,7 +731,7 @@ void setup()
#else
// ESP32
SPI.begin(LORA_SCK, LORA_MISO, LORA_MOSI, LORA_CS);
LOG_DEBUG("SPI.begin(SCK=%d, MISO=%d, MOSI=%d, NSS=%d)\n", LORA_SCK, LORA_MISO, LORA_MOSI, LORA_CS);
LOG_DEBUG("SPI.begin(SCK=%d, MISO=%d, MOSI=%d, NSS=%d)", LORA_SCK, LORA_MISO, LORA_MOSI, LORA_CS);
SPI.setFrequency(4000000);
#endif
@@ -731,9 +740,9 @@ void setup()
// setup TZ prior to time actions.
#if !MESHTASTIC_EXCLUDE_TZ
LOG_DEBUG("Using compiled/slipstreamed %s\n", slipstreamTZString); // important, removing this clobbers our magic string
LOG_DEBUG("Using compiled/slipstreamed %s", slipstreamTZString); // important, removing this clobbers our magic string
if (*config.device.tzdef && config.device.tzdef[0] != 0) {
LOG_DEBUG("Saved TZ: %s \n", config.device.tzdef);
LOG_DEBUG("Saved TZ: %s ", config.device.tzdef);
setenv("TZ", config.device.tzdef, 1);
} else {
if (strncmp((const char *)slipstreamTZString, "tzpl", 4) == 0) {
@@ -744,7 +753,7 @@ void setup()
}
}
tzset();
LOG_DEBUG("Set Timezone to %s\n", getenv("TZ"));
LOG_DEBUG("Set Timezone to %s", getenv("TZ"));
#endif
readFromRTC(); // read the main CPU RTC at first (in case we can't get GPS time)
@@ -761,7 +770,7 @@ void setup()
if (gps) {
gpsStatus->observe(&gps->newStatus);
} else {
LOG_DEBUG("Running without GPS.\n");
LOG_DEBUG("Running without GPS.");
}
}
}
@@ -774,7 +783,7 @@ void setup()
nodeStatus->observe(&nodeDB->newStatus);
#ifdef HAS_I2S
LOG_DEBUG("Starting audio thread\n");
LOG_DEBUG("Starting audio thread");
audioThread = new AudioThread();
#endif
service = new MeshService();
@@ -821,63 +830,63 @@ void setup()
#ifdef ARCH_PORTDUINO
if (settingsMap[use_sx1262]) {
if (!rIf) {
LOG_DEBUG("Attempting to activate sx1262 radio on SPI port %s\n", settingsStrings[spidev].c_str());
LOG_DEBUG("Attempting to activate sx1262 radio on SPI port %s", settingsStrings[spidev].c_str());
LockingArduinoHal *RadioLibHAL =
new LockingArduinoHal(SPI, spiSettings, (settingsMap[ch341Quirk] ? settingsMap[busy] : RADIOLIB_NC));
rIf = new SX1262Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
settingsMap[busy]);
if (!rIf->init()) {
LOG_ERROR("Failed to find SX1262 radio\n");
LOG_ERROR("Failed to find SX1262 radio");
delete rIf;
exit(EXIT_FAILURE);
} else {
LOG_INFO("SX1262 Radio init succeeded, using SX1262 radio\n");
LOG_INFO("SX1262 Radio init succeeded, using SX1262 radio");
}
}
} else if (settingsMap[use_rf95]) {
if (!rIf) {
LOG_DEBUG("Attempting to activate rf95 radio on SPI port %s\n", settingsStrings[spidev].c_str());
LOG_DEBUG("Attempting to activate rf95 radio on SPI port %s", settingsStrings[spidev].c_str());
LockingArduinoHal *RadioLibHAL =
new LockingArduinoHal(SPI, spiSettings, (settingsMap[ch341Quirk] ? settingsMap[busy] : RADIOLIB_NC));
rIf = new RF95Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
settingsMap[busy]);
if (!rIf->init()) {
LOG_ERROR("Failed to find RF95 radio\n");
LOG_ERROR("Failed to find RF95 radio");
delete rIf;
rIf = NULL;
exit(EXIT_FAILURE);
} else {
LOG_INFO("RF95 Radio init succeeded, using RF95 radio\n");
LOG_INFO("RF95 Radio init succeeded, using RF95 radio");
}
}
} else if (settingsMap[use_sx1280]) {
if (!rIf) {
LOG_DEBUG("Attempting to activate sx1280 radio on SPI port %s\n", settingsStrings[spidev].c_str());
LOG_DEBUG("Attempting to activate sx1280 radio on SPI port %s", settingsStrings[spidev].c_str());
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
rIf = new SX1280Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
settingsMap[busy]);
if (!rIf->init()) {
LOG_ERROR("Failed to find SX1280 radio\n");
LOG_ERROR("Failed to find SX1280 radio");
delete rIf;
rIf = NULL;
exit(EXIT_FAILURE);
} else {
LOG_INFO("SX1280 Radio init succeeded, using SX1280 radio\n");
LOG_INFO("SX1280 Radio init succeeded, using SX1280 radio");
}
}
} else if (settingsMap[use_sx1268]) {
if (!rIf) {
LOG_DEBUG("Attempting to activate sx1268 radio on SPI port %s\n", settingsStrings[spidev].c_str());
LOG_DEBUG("Attempting to activate sx1268 radio on SPI port %s", settingsStrings[spidev].c_str());
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
rIf = new SX1268Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
settingsMap[busy]);
if (!rIf->init()) {
LOG_ERROR("Failed to find SX1268 radio\n");
LOG_ERROR("Failed to find SX1268 radio");
delete rIf;
rIf = NULL;
exit(EXIT_FAILURE);
} else {
LOG_INFO("SX1268 Radio init succeeded, using SX1268 radio\n");
LOG_INFO("SX1268 Radio init succeeded, using SX1268 radio");
}
}
}
@@ -893,11 +902,11 @@ void setup()
if (!rIf) {
rIf = new STM32WLE5JCInterface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY);
if (!rIf->init()) {
LOG_WARN("Failed to find STM32WL radio\n");
LOG_WARN("Failed to find STM32WL radio");
delete rIf;
rIf = NULL;
} else {
LOG_INFO("STM32WL Radio init succeeded, using STM32WL radio\n");
LOG_INFO("STM32WL Radio init succeeded, using STM32WL radio");
radioType = STM32WLx_RADIO;
}
}
@@ -907,11 +916,11 @@ void setup()
if (!rIf) {
rIf = new SimRadio;
if (!rIf->init()) {
LOG_WARN("Failed to find simulated radio\n");
LOG_WARN("Failed to find simulated radio");
delete rIf;
rIf = NULL;
} else {
LOG_INFO("Using SIMULATED radio!\n");
LOG_INFO("Using SIMULATED radio!");
radioType = SIM_RADIO;
}
}
@@ -921,11 +930,11 @@ void setup()
if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) {
rIf = new RF95Interface(RadioLibHAL, LORA_CS, RF95_IRQ, RF95_RESET, RF95_DIO1);
if (!rIf->init()) {
LOG_WARN("Failed to find RF95 radio\n");
LOG_WARN("Failed to find RF95 radio");
delete rIf;
rIf = NULL;
} else {
LOG_INFO("RF95 Radio init succeeded, using RF95 radio\n");
LOG_INFO("RF95 Radio init succeeded, using RF95 radio");
radioType = RF95_RADIO;
}
}
@@ -935,11 +944,11 @@ void setup()
if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) {
rIf = new SX1262Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY);
if (!rIf->init()) {
LOG_WARN("Failed to find SX1262 radio\n");
LOG_WARN("Failed to find SX1262 radio");
delete rIf;
rIf = NULL;
} else {
LOG_INFO("SX1262 Radio init succeeded, using SX1262 radio\n");
LOG_INFO("SX1262 Radio init succeeded, using SX1262 radio");
radioType = SX1262_RADIO;
}
}
@@ -950,14 +959,12 @@ void setup()
// Try using the specified TCXO voltage
rIf = new SX1262Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY);
if (!rIf->init()) {
LOG_WARN("Failed to find SX1262 radio with TCXO using DIO3 reference voltage at %f V\n", tcxoVoltage);
LOG_WARN("Failed to find SX1262 radio with TCXO, Vref %f V", tcxoVoltage);
delete rIf;
rIf = NULL;
tcxoVoltage = 0; // if it fails, set the TCXO voltage to zero for the next attempt
} else {
LOG_INFO("SX1262 Radio init succeeded, using ");
LOG_WARN("SX1262 Radio with TCXO");
LOG_INFO(", reference voltage at %f V\n", tcxoVoltage);
LOG_WARN("SX1262 Radio init succeeded, TCXO, Vref %f V", tcxoVoltage);
radioType = SX1262_RADIO;
}
}
@@ -966,14 +973,12 @@ void setup()
// If specified TCXO voltage fails, attempt to use DIO3 as a reference instea
rIf = new SX1262Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY);
if (!rIf->init()) {
LOG_WARN("Failed to find SX1262 radio with XTAL using DIO3 reference voltage at %f V\n", tcxoVoltage);
LOG_WARN("Failed to find SX1262 radio with XTAL, Vref %f V", tcxoVoltage);
delete rIf;
rIf = NULL;
tcxoVoltage = SX126X_DIO3_TCXO_VOLTAGE; // if it fails, set the TCXO voltage back for the next radio search
} else {
LOG_INFO("SX1262 Radio init succeeded, using ");
LOG_WARN("SX1262 Radio with XTAL");
LOG_INFO(", reference voltage at %f V\n", tcxoVoltage);
LOG_INFO("SX1262 Radio init succeeded, XTAL, Vref %f V", tcxoVoltage);
radioType = SX1262_RADIO;
}
}
@@ -983,11 +988,11 @@ void setup()
if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) {
rIf = new SX1268Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY);
if (!rIf->init()) {
LOG_WARN("Failed to find SX1268 radio\n");
LOG_WARN("Failed to find SX1268 radio");
delete rIf;
rIf = NULL;
} else {
LOG_INFO("SX1268 Radio init succeeded, using SX1268 radio\n");
LOG_INFO("SX1268 Radio init succeeded, using SX1268 radio");
radioType = SX1268_RADIO;
}
}
@@ -997,11 +1002,11 @@ void setup()
if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) {
rIf = new LLCC68Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY);
if (!rIf->init()) {
LOG_WARN("Failed to find LLCC68 radio\n");
LOG_WARN("Failed to find LLCC68 radio");
delete rIf;
rIf = NULL;
} else {
LOG_INFO("LLCC68 Radio init succeeded, using LLCC68 radio\n");
LOG_INFO("LLCC68 Radio init succeeded, using LLCC68 radio");
radioType = LLCC68_RADIO;
}
}
@@ -1011,11 +1016,11 @@ void setup()
if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) {
rIf = new LR1110Interface(RadioLibHAL, LR1110_SPI_NSS_PIN, LR1110_IRQ_PIN, LR1110_NRESET_PIN, LR1110_BUSY_PIN);
if (!rIf->init()) {
LOG_WARN("Failed to find LR1110 radio\n");
LOG_WARN("Failed to find LR1110 radio");
delete rIf;
rIf = NULL;
} else {
LOG_INFO("LR1110 Radio init succeeded, using LR1110 radio\n");
LOG_INFO("LR1110 Radio init succeeded, using LR1110 radio");
radioType = LR1110_RADIO;
}
}
@@ -1025,11 +1030,11 @@ void setup()
if (!rIf) {
rIf = new LR1120Interface(RadioLibHAL, LR1120_SPI_NSS_PIN, LR1120_IRQ_PIN, LR1120_NRESET_PIN, LR1120_BUSY_PIN);
if (!rIf->init()) {
LOG_WARN("Failed to find LR1120 radio\n");
LOG_WARN("Failed to find LR1120 radio");
delete rIf;
rIf = NULL;
} else {
LOG_INFO("LR1120 Radio init succeeded, using LR1120 radio\n");
LOG_INFO("LR1120 Radio init succeeded, using LR1120 radio");
radioType = LR1120_RADIO;
}
}
@@ -1039,11 +1044,11 @@ void setup()
if (!rIf) {
rIf = new LR1121Interface(RadioLibHAL, LR1121_SPI_NSS_PIN, LR1121_IRQ_PIN, LR1121_NRESET_PIN, LR1121_BUSY_PIN);
if (!rIf->init()) {
LOG_WARN("Failed to find LR1121 radio\n");
LOG_WARN("Failed to find LR1121 radio");
delete rIf;
rIf = NULL;
} else {
LOG_INFO("LR1121 Radio init succeeded, using LR1121 radio\n");
LOG_INFO("LR1121 Radio init succeeded, using LR1121 radio");
radioType = LR1121_RADIO;
}
}
@@ -1053,11 +1058,11 @@ void setup()
if (!rIf) {
rIf = new SX1280Interface(RadioLibHAL, SX128X_CS, SX128X_DIO1, SX128X_RESET, SX128X_BUSY);
if (!rIf->init()) {
LOG_WARN("Failed to find SX1280 radio\n");
LOG_WARN("Failed to find SX1280 radio");
delete rIf;
rIf = NULL;
} else {
LOG_INFO("SX1280 Radio init succeeded, using SX1280 radio\n");
LOG_INFO("SX1280 Radio init succeeded, using SX1280 radio");
radioType = SX1280_RADIO;
}
}
@@ -1065,11 +1070,11 @@ void setup()
// check if the radio chip matches the selected region
if ((config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_LORA_24) && (!rIf->wideLora())) {
LOG_WARN("Radio chip does not support 2.4GHz LoRa. Reverting to unset.\n");
LOG_WARN("Radio chip does not support 2.4GHz LoRa. Reverting to unset.");
config.lora.region = meshtastic_Config_LoRaConfig_RegionCode_UNSET;
nodeDB->saveToDisk(SEGMENT_CONFIG);
if (!rIf->reconfigure()) {
LOG_WARN("Reconfigure failed, rebooting\n");
LOG_WARN("Reconfigure failed, rebooting");
screen->startAlert("Rebooting...");
rebootAtMsec = millis() + 5000;
}
@@ -1124,9 +1129,9 @@ void setup()
router->addInterface(rIf);
// Log bit rate to debug output
LOG_DEBUG("LoRA bitrate = %f bytes / sec\n", (float(meshtastic_Constants_DATA_PAYLOAD_LEN) /
(float(rIf->getPacketTime(meshtastic_Constants_DATA_PAYLOAD_LEN)))) *
1000);
LOG_DEBUG("LoRA bitrate = %f bytes / sec", (float(meshtastic_Constants_DATA_PAYLOAD_LEN) /
(float(rIf->getPacketTime(meshtastic_Constants_DATA_PAYLOAD_LEN)))) *
1000);
}
// This must be _after_ service.init because we need our preferences loaded from flash to have proper timeout values

View File

@@ -117,13 +117,18 @@ void Channels::initDefaultChannel(ChannelIndex chIndex)
static const uint8_t defaultpsk0[] = USERPREFS_CHANNEL_0_PSK;
memcpy(channelSettings.psk.bytes, defaultpsk0, sizeof(defaultpsk0));
channelSettings.psk.size = sizeof(defaultpsk0);
#endif
#ifdef USERPREFS_CHANNEL_0_NAME
strcpy(channelSettings.name, USERPREFS_CHANNEL_0_NAME);
#endif
#ifdef USERPREFS_CHANNEL_0_PRECISION
channelSettings.module_settings.position_precision = USERPREFS_CHANNEL_0_PRECISION;
#endif
#ifdef USERPREFS_CHANNEL_0_UPLINK_ENABLED
channelSettings.uplink_enabled = USERPREFS_CHANNEL_0_UPLINK_ENABLED;
#endif
#ifdef USERPREFS_CHANNEL_0_DOWNLINK_ENABLED
channelSettings.downlink_enabled = USERPREFS_CHANNEL_0_DOWNLINK_ENABLED;
#endif
break;
case 1:
@@ -131,13 +136,18 @@ void Channels::initDefaultChannel(ChannelIndex chIndex)
static const uint8_t defaultpsk1[] = USERPREFS_CHANNEL_1_PSK;
memcpy(channelSettings.psk.bytes, defaultpsk1, sizeof(defaultpsk1));
channelSettings.psk.size = sizeof(defaultpsk1);
#endif
#ifdef USERPREFS_CHANNEL_1_NAME
strcpy(channelSettings.name, USERPREFS_CHANNEL_1_NAME);
#endif
#ifdef USERPREFS_CHANNEL_1_PRECISION
channelSettings.module_settings.position_precision = USERPREFS_CHANNEL_1_PRECISION;
#endif
#ifdef USERPREFS_CHANNEL_1_UPLINK_ENABLED
channelSettings.uplink_enabled = USERPREFS_CHANNEL_1_UPLINK_ENABLED;
#endif
#ifdef USERPREFS_CHANNEL_1_DOWNLINK_ENABLED
channelSettings.downlink_enabled = USERPREFS_CHANNEL_1_DOWNLINK_ENABLED;
#endif
break;
case 2:
@@ -145,13 +155,18 @@ void Channels::initDefaultChannel(ChannelIndex chIndex)
static const uint8_t defaultpsk2[] = USERPREFS_CHANNEL_2_PSK;
memcpy(channelSettings.psk.bytes, defaultpsk2, sizeof(defaultpsk2));
channelSettings.psk.size = sizeof(defaultpsk2);
#endif
#ifdef USERPREFS_CHANNEL_2_NAME
strcpy(channelSettings.name, USERPREFS_CHANNEL_2_NAME);
#endif
#ifdef USERPREFS_CHANNEL_2_PRECISION
channelSettings.module_settings.position_precision = USERPREFS_CHANNEL_2_PRECISION;
#endif
#ifdef USERPREFS_CHANNEL_2_UPLINK_ENABLED
channelSettings.uplink_enabled = USERPREFS_CHANNEL_2_UPLINK_ENABLED;
#endif
#ifdef USERPREFS_CHANNEL_2_DOWNLINK_ENABLED
channelSettings.downlink_enabled = USERPREFS_CHANNEL_2_DOWNLINK_ENABLED;
#endif
break;
default:
@@ -175,34 +190,19 @@ CryptoKey Channels::getKey(ChannelIndex chIndex)
k.length = channelSettings.psk.size;
if (k.length == 0) {
if (ch.role == meshtastic_Channel_Role_SECONDARY) {
LOG_DEBUG("Unset PSK for secondary channel %s. using primary key\n", ch.settings.name);
LOG_DEBUG("Unset PSK for secondary channel %s. using primary key", ch.settings.name);
k = getKey(primaryIndex);
} else {
LOG_WARN("User disabled encryption\n");
LOG_WARN("User disabled encryption");
}
} else if (k.length == 1) {
// Convert the short single byte variants of psk into variant that can be used more generally
uint8_t pskIndex = k.bytes[0];
LOG_DEBUG("Expanding short PSK #%d\n", pskIndex);
LOG_DEBUG("Expanding short PSK #%d", pskIndex);
if (pskIndex == 0)
k.length = 0; // Turn off encryption
else if (oemStore.oem_aes_key.size > 1) {
// Use the OEM key
LOG_DEBUG("Using OEM Key with %d bytes\n", oemStore.oem_aes_key.size);
memcpy(k.bytes, oemStore.oem_aes_key.bytes, oemStore.oem_aes_key.size);
k.length = oemStore.oem_aes_key.size;
// Bump up the last byte of PSK as needed
uint8_t *last = k.bytes + oemStore.oem_aes_key.size - 1;
*last = *last + pskIndex - 1; // index of 1 means no change vs defaultPSK
if (k.length < 16) {
LOG_WARN("OEM provided a too short AES128 key - padding\n");
k.length = 16;
} else if (k.length < 32 && k.length != 16) {
LOG_WARN("OEM provided a too short AES256 key - padding\n");
k.length = 32;
}
} else {
else {
memcpy(k.bytes, defaultpsk, sizeof(defaultpsk));
k.length = sizeof(defaultpsk);
// Bump up the last byte of PSK as needed
@@ -212,12 +212,12 @@ CryptoKey Channels::getKey(ChannelIndex chIndex)
} else if (k.length < 16) {
// Error! The user specified only the first few bits of an AES128 key. So by convention we just pad the rest of the
// key with zeros
LOG_WARN("User provided a too short AES128 key - padding\n");
LOG_WARN("User provided a too short AES128 key - padding");
k.length = 16;
} else if (k.length < 32 && k.length != 16) {
// Error! The user specified only the first few bits of an AES256 key. So by convention we just pad the rest of the
// key with zeros
LOG_WARN("User provided a too short AES256 key - padding\n");
LOG_WARN("User provided a too short AES256 key - padding");
k.length = 32;
}
}
@@ -267,7 +267,7 @@ void Channels::onConfigChanged()
}
#if !MESHTASTIC_EXCLUDE_MQTT
if (channels.anyMqttEnabled() && mqtt && !mqtt->isEnabled()) {
LOG_DEBUG("MQTT is enabled on at least one channel, so set MQTT thread to run immediately\n");
LOG_DEBUG("MQTT is enabled on at least one channel, so set MQTT thread to run immediately");
mqtt->start();
}
#endif
@@ -280,7 +280,7 @@ meshtastic_Channel &Channels::getByIndex(ChannelIndex chIndex)
meshtastic_Channel *ch = channelFile.channels + chIndex;
return *ch;
} else {
LOG_ERROR("Invalid channel index %d > %d, malformed packet received?\n", chIndex, channelFile.channels_count);
LOG_ERROR("Invalid channel index %d > %d, malformed packet received?", chIndex, channelFile.channels_count);
static meshtastic_Channel *ch = (meshtastic_Channel *)malloc(sizeof(meshtastic_Channel));
memset(ch, 0, sizeof(meshtastic_Channel));
@@ -384,11 +384,11 @@ bool Channels::hasDefaultChannel()
bool Channels::decryptForHash(ChannelIndex chIndex, ChannelHash channelHash)
{
if (chIndex > getNumChannels() || getHash(chIndex) != channelHash) {
// LOG_DEBUG("Skipping channel %d (hash %x) due to invalid hash/index, want=%x\n", chIndex, getHash(chIndex),
// LOG_DEBUG("Skipping channel %d (hash %x) due to invalid hash/index, want=%x", chIndex, getHash(chIndex),
// channelHash);
return false;
} else {
LOG_DEBUG("Using channel %d (hash 0x%x)\n", chIndex, channelHash);
LOG_DEBUG("Using channel %d (hash 0x%x)", chIndex, channelHash);
setCrypto(chIndex);
return true;
}

View File

@@ -18,7 +18,7 @@
*/
void CryptoEngine::generateKeyPair(uint8_t *pubKey, uint8_t *privKey)
{
LOG_DEBUG("Generating Curve25519 key pair...\n");
LOG_DEBUG("Generating Curve25519 key pair...");
Curve25519::dh1(public_key, private_key);
memcpy(pubKey, public_key, sizeof(public_key));
memcpy(privKey, private_key, sizeof(private_key));
@@ -35,14 +35,14 @@ bool CryptoEngine::regeneratePublicKey(uint8_t *pubKey, uint8_t *privKey)
if (!memfll(privKey, 0, sizeof(private_key))) {
Curve25519::eval(pubKey, privKey, 0);
if (Curve25519::isWeakPoint(pubKey)) {
LOG_ERROR("PKI key generation failed. Specified private key results in a weak\n");
LOG_ERROR("PKI key generation failed. Specified private key results in a weak");
memset(pubKey, 0, 32);
return false;
}
memcpy(private_key, privKey, sizeof(private_key));
memcpy(public_key, pubKey, sizeof(public_key));
} else {
LOG_WARN("X25519 key generation failed due to blank private key\n");
LOG_WARN("X25519 key generation failed due to blank private key");
return false;
}
return true;
@@ -68,9 +68,9 @@ bool CryptoEngine::encryptCurve25519(uint32_t toNode, uint32_t fromNode, meshtas
auth = bytesOut + numBytes;
memcpy((uint8_t *)(auth + 8), &extraNonceTmp,
sizeof(uint32_t)); // do not use dereference on potential non aligned pointers : *extraNonce = extraNonceTmp;
LOG_INFO("Random nonce value: %d\n", extraNonceTmp);
LOG_INFO("Random nonce value: %d", extraNonceTmp);
if (remotePublic.size == 0) {
LOG_DEBUG("Node %d or their public_key not found\n", toNode);
LOG_DEBUG("Node %d or their public_key not found", toNode);
return false;
}
if (!crypto->setDHPublicKey(remotePublic.bytes)) {
@@ -103,10 +103,10 @@ bool CryptoEngine::decryptCurve25519(uint32_t fromNode, meshtastic_UserLite_publ
auth = bytes + numBytes - 12;
memcpy(&extraNonce, auth + 8,
sizeof(uint32_t)); // do not use dereference on potential non aligned pointers : (uint32_t *)(auth + 8);
LOG_INFO("Random nonce value: %d\n", extraNonce);
LOG_INFO("Random nonce value: %d", extraNonce);
if (remotePublic.size == 0) {
LOG_DEBUG("Node or its public key not found in database\n");
LOG_DEBUG("Node or its public key not found in database");
return false;
}
@@ -174,7 +174,7 @@ bool CryptoEngine::setDHPublicKey(uint8_t *pubKey)
// Calculate the shared secret with the specified node's public key and our private key
// This includes an internal weak key check, which among other things looks for an all 0 public key and shared key.
if (!Curve25519::dh2(shared_key, local_priv)) {
LOG_WARN("Curve25519DH step 2 failed!\n");
LOG_WARN("Curve25519DH step 2 failed!");
return false;
}
return true;
@@ -185,7 +185,7 @@ concurrency::Lock *cryptLock;
void CryptoEngine::setKey(const CryptoKey &k)
{
LOG_DEBUG("Using AES%d key!\n", k.length * 8);
LOG_DEBUG("Using AES%d key!", k.length * 8);
key = k;
}
@@ -201,7 +201,7 @@ void CryptoEngine::encryptPacket(uint32_t fromNode, uint64_t packetId, size_t nu
if (numBytes <= MAX_BLOCKSIZE) {
encryptAESCtr(key, nonce, numBytes, bytes);
} else {
LOG_ERROR("Packet too large for crypto engine: %d. noop encryption!\n", numBytes);
LOG_ERROR("Packet too large for crypto engine: %d. noop encryption!", numBytes);
}
}
}

View File

@@ -43,6 +43,15 @@ uint32_t Default::getConfiguredOrDefaultMsScaled(uint32_t configured, uint32_t d
return getConfiguredOrDefaultMs(configured, defaultValue) * congestionScalingCoefficient(numOnlineNodes);
}
uint32_t Default::getConfiguredOrMinimumValue(uint32_t configured, uint32_t minValue)
{
// If zero, intervals should be coalesced later by getConfiguredOrDefault... methods
if (configured == 0)
return configured;
return configured < minValue ? minValue : configured;
}
uint8_t Default::getConfiguredOrDefaultHopLimit(uint8_t configured)
{
#if USERPREFS_EVENT_MODE

View File

@@ -6,8 +6,9 @@
#define THIRTY_SECONDS_MS 30 * 1000
#define FIVE_SECONDS_MS 5 * 1000
#define min_default_telemetry_interval_secs 30 * 60
#define default_gps_update_interval IF_ROUTER(ONE_DAY, 2 * 60)
#define default_telemetry_broadcast_interval_secs IF_ROUTER(ONE_DAY / 2, 30 * 60)
#define default_telemetry_broadcast_interval_secs IF_ROUTER(ONE_DAY / 2, 60 * 60)
#define default_broadcast_interval_secs IF_ROUTER(ONE_DAY / 2, 15 * 60)
#define default_wait_bluetooth_secs IF_ROUTER(1, 60)
#define default_sds_secs IF_ROUTER(ONE_DAY, UINT32_MAX) // Default to forever super deep sleep
@@ -35,6 +36,7 @@ class Default
static uint32_t getConfiguredOrDefault(uint32_t configured, uint32_t defaultValue);
static uint32_t getConfiguredOrDefaultMsScaled(uint32_t configured, uint32_t defaultValue, uint32_t numOnlineNodes);
static uint8_t getConfiguredOrDefaultHopLimit(uint8_t configured);
static uint32_t getConfiguredOrMinimumValue(uint32_t configured, uint32_t minValue);
private:
static float congestionScalingCoefficient(int numOnlineNodes)

View File

@@ -35,17 +35,23 @@ bool FloodingRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
return Router::shouldFilterReceived(p);
}
bool FloodingRouter::isRebroadcaster()
{
return config.device.role != meshtastic_Config_DeviceConfig_Role_CLIENT_MUTE &&
config.device.rebroadcast_mode != meshtastic_Config_DeviceConfig_RebroadcastMode_NONE;
}
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) && p->to != NODENUM_BROADCAST) {
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.\n");
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 (p->id != 0) {
if (config.device.role != meshtastic_Config_DeviceConfig_Role_CLIENT_MUTE) {
if (isRebroadcaster()) {
meshtastic_MeshPacket *tosend = packetPool.allocCopy(*p); // keep a copy because we will be sending it
tosend->hop_limit--; // bump down the hop count
@@ -57,15 +63,15 @@ void FloodingRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtas
}
#endif
LOG_INFO("Rebroadcasting received floodmsg\n");
LOG_INFO("Rebroadcasting received floodmsg");
// 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
Router::send(tosend);
} else {
LOG_DEBUG("Not rebroadcasting. Role = Role_ClientMute\n");
LOG_DEBUG("Not rebroadcasting: Role = CLIENT_MUTE or Rebroadcast Mode = NONE");
}
} else {
LOG_DEBUG("Ignoring 0 id broadcast\n");
LOG_DEBUG("Ignoring 0 id broadcast");
}
}
// handle the packet as normal

View File

@@ -29,6 +29,8 @@
class FloodingRouter : public Router, protected PacketHistory
{
private:
bool isRebroadcaster();
public:
/**
* Constructor

View File

@@ -35,7 +35,7 @@ LR11x0Interface<T>::LR11x0Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs
RADIOLIB_PIN_TYPE busy)
: RadioLibInterface(hal, cs, irq, rst, busy, &lora), lora(&module)
{
LOG_WARN("LR11x0Interface(cs=%d, irq=%d, rst=%d, busy=%d)\n", cs, irq, rst, busy);
LOG_WARN("LR11x0Interface(cs=%d, irq=%d, rst=%d, busy=%d)", cs, irq, rst, busy);
}
/// Initialise the Driver transport hardware and software.
@@ -54,10 +54,10 @@ template <typename T> bool LR11x0Interface<T>::init()
0; // "TCXO reference voltage to be set on DIO3. Defaults to 1.6 V, set to 0 to skip." per
// https://github.com/jgromes/RadioLib/blob/690a050ebb46e6097c5d00c371e961c1caa3b52e/src/modules/LR11x0/LR11x0.h#L471C26-L471C104
// (DIO3 is free to be used as an IRQ)
LOG_DEBUG("LR11X0_DIO3_TCXO_VOLTAGE not defined, not using DIO3 as TCXO reference voltage\n");
LOG_DEBUG("LR11X0_DIO3_TCXO_VOLTAGE not defined, not using DIO3 as TCXO reference voltage");
#else
float tcxoVoltage = LR11X0_DIO3_TCXO_VOLTAGE;
LOG_DEBUG("LR11X0_DIO3_TCXO_VOLTAGE defined, using DIO3 as TCXO reference voltage at %f V\n", LR11X0_DIO3_TCXO_VOLTAGE);
LOG_DEBUG("LR11X0_DIO3_TCXO_VOLTAGE defined, using DIO3 as TCXO reference voltage at %f V", LR11X0_DIO3_TCXO_VOLTAGE);
// (DIO3 is not free to be used as an IRQ)
#endif
@@ -67,39 +67,40 @@ template <typename T> bool LR11x0Interface<T>::init()
power = LR1110_MAX_POWER;
if ((power > LR1120_MAX_POWER) &&
(config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) // clamp again if wide freq range
(config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) { // clamp again if wide freq range
power = LR1120_MAX_POWER;
preambleLength = 12; // 12 is the default for operation above 2GHz
}
limitPower();
#ifdef LR11X0_RF_SWITCH_SUBGHZ
pinMode(LR11X0_RF_SWITCH_SUBGHZ, OUTPUT);
digitalWrite(LR11X0_RF_SWITCH_SUBGHZ, getFreq() < 1e9 ? HIGH : LOW);
LOG_DEBUG("Setting RF0 switch to %s\n", getFreq() < 1e9 ? "SubGHz" : "2.4GHz");
LOG_DEBUG("Setting RF0 switch to %s", getFreq() < 1e9 ? "SubGHz" : "2.4GHz");
#endif
#ifdef LR11X0_RF_SWITCH_2_4GHZ
pinMode(LR11X0_RF_SWITCH_2_4GHZ, OUTPUT);
digitalWrite(LR11X0_RF_SWITCH_2_4GHZ, getFreq() < 1e9 ? LOW : HIGH);
LOG_DEBUG("Setting RF1 switch to %s\n", getFreq() < 1e9 ? "SubGHz" : "2.4GHz");
LOG_DEBUG("Setting RF1 switch to %s", getFreq() < 1e9 ? "SubGHz" : "2.4GHz");
#endif
int res = lora.begin(getFreq(), bw, sf, cr, syncWord, power, preambleLength, tcxoVoltage);
// \todo Display actual typename of the adapter, not just `LR11x0`
LOG_INFO("LR11x0 init result %d\n", res);
LOG_INFO("LR11x0 init result %d", res);
if (res == RADIOLIB_ERR_CHIP_NOT_FOUND)
return false;
LR11x0VersionInfo_t version;
res = lora.getVersionInfo(&version);
if (res == RADIOLIB_ERR_NONE)
LOG_DEBUG("LR11x0 Device %d, HW %d, FW %d.%d, WiFi %d.%d, GNSS %d.%d\n", version.device, version.hardware,
version.fwMajor, version.fwMinor, version.fwMajorWiFi, version.fwMinorWiFi, version.fwGNSS,
version.almanacGNSS);
LOG_DEBUG("LR11x0 Device %d, HW %d, FW %d.%d, WiFi %d.%d, GNSS %d.%d", version.device, version.hardware, version.fwMajor,
version.fwMinor, version.fwMajorWiFi, version.fwMinorWiFi, version.fwGNSS, version.almanacGNSS);
LOG_INFO("Frequency set to %f\n", getFreq());
LOG_INFO("Bandwidth set to %f\n", bw);
LOG_INFO("Power output set to %d\n", power);
LOG_INFO("Frequency set to %f", getFreq());
LOG_INFO("Bandwidth set to %f", bw);
LOG_INFO("Power output set to %d", power);
if (res == RADIOLIB_ERR_NONE)
res = lora.setCRC(2);
@@ -121,16 +122,16 @@ template <typename T> bool LR11x0Interface<T>::init()
if (dioAsRfSwitch) {
lora.setRfSwitchTable(rfswitch_dio_pins, rfswitch_table);
LOG_DEBUG("Setting DIO RF switch\n", res);
LOG_DEBUG("Setting DIO RF switch", res);
}
if (res == RADIOLIB_ERR_NONE) {
if (config.lora.sx126x_rx_boosted_gain) { // the name is unfortunate but historically accurate
res = lora.setRxBoostedGainMode(true);
LOG_INFO("Set RX gain to boosted mode; result: %d\n", res);
LOG_INFO("Set RX gain to boosted mode; result: %d", res);
} else {
res = lora.setRxBoostedGainMode(false);
LOG_INFO("Set RX gain to power saving mode (boosted mode off); result: %d\n", res);
LOG_INFO("Set RX gain to power saving mode (boosted mode off); result: %d", res);
}
}
@@ -200,7 +201,7 @@ template <typename T> void LR11x0Interface<T>::setStandby()
int err = lora.standby();
if (err != RADIOLIB_ERR_NONE) {
LOG_DEBUG("LR11x0 standby failed with error %d\n", err);
LOG_DEBUG("LR11x0 standby failed with error %d", err);
}
assert(err == RADIOLIB_ERR_NONE);
@@ -217,7 +218,7 @@ template <typename T> void LR11x0Interface<T>::setStandby()
*/
template <typename T> void LR11x0Interface<T>::addReceiveMetadata(meshtastic_MeshPacket *mp)
{
// LOG_DEBUG("PacketStatus %x\n", lora.getPacketStatus());
// LOG_DEBUG("PacketStatus %x", lora.getPacketStatus());
mp->rx_snr = lora.getSNR();
mp->rx_rssi = lround(lora.getRSSI());
}
@@ -282,7 +283,7 @@ template <typename T> bool LR11x0Interface<T>::isActivelyReceiving()
template <typename T> bool LR11x0Interface<T>::sleep()
{
// \todo Display actual typename of the adapter, not just `LR11x0`
LOG_DEBUG("LR11x0 entering sleep mode\n");
LOG_DEBUG("LR11x0 entering sleep mode");
setStandby(); // Stop any pending operations
// turn off TCXO if it was powered

View File

@@ -55,7 +55,7 @@ meshtastic_MeshPacket *MeshModule::allocAckNak(meshtastic_Routing_Error err, Nod
p->decoded.request_id = idFrom;
p->channel = chIndex;
if (err != meshtastic_Routing_Error_NONE)
LOG_WARN("Alloc an err=%d,to=0x%x,idFrom=0x%x,id=0x%x\n", err, to, idFrom, p->id);
LOG_WARN("Alloc an err=%d,to=0x%x,idFrom=0x%x,id=0x%x", err, to, idFrom, p->id);
return p;
}
@@ -74,7 +74,7 @@ meshtastic_MeshPacket *MeshModule::allocErrorResponse(meshtastic_Routing_Error e
void MeshModule::callModules(meshtastic_MeshPacket &mp, RxSource src)
{
// LOG_DEBUG("In call modules\n");
// LOG_DEBUG("In call modules");
bool moduleFound = false;
// We now allow **encrypted** packets to pass through the modules
@@ -86,7 +86,7 @@ void MeshModule::callModules(meshtastic_MeshPacket &mp, RxSource src)
// Was this message directed to us specifically? Will be false if we are sniffing someone elses packets
auto ourNodeNum = nodeDB->getNodeNum();
bool toUs = mp.to == NODENUM_BROADCAST || isToUs(&mp);
bool toUs = isBroadcast(mp.to) || isToUs(&mp);
for (auto i = modules->begin(); i != modules->end(); ++i) {
auto &pi = **i;
@@ -104,7 +104,7 @@ void MeshModule::callModules(meshtastic_MeshPacket &mp, RxSource src)
assert(!pi.myReply); // If it is !null it means we have a bug, because it should have been sent the previous time
if (wantsPacket) {
LOG_DEBUG("Module '%s' wantsPacket=%d\n", pi.name, wantsPacket);
LOG_DEBUG("Module '%s' wantsPacket=%d", pi.name, wantsPacket);
moduleFound = true;
@@ -144,20 +144,20 @@ void MeshModule::callModules(meshtastic_MeshPacket &mp, RxSource src)
if (isDecoded && mp.decoded.want_response && toUs && (!isFromUs(&mp) || isToUs(&mp)) && !currentReply) {
pi.sendResponse(mp);
ignoreRequest = ignoreRequest || pi.ignoreRequest; // If at least one module asks it, we may ignore a request
LOG_INFO("Asked module '%s' to send a response\n", pi.name);
LOG_INFO("Asked module '%s' to send a response", pi.name);
} else {
LOG_DEBUG("Module '%s' considered\n", pi.name);
LOG_DEBUG("Module '%s' considered", pi.name);
}
// If the requester didn't ask for a response we might need to discard unused replies to prevent memory leaks
if (pi.myReply) {
LOG_DEBUG("Discarding an unneeded response\n");
LOG_DEBUG("Discarding an unneeded response");
packetPool.release(pi.myReply);
pi.myReply = NULL;
}
if (handled == ProcessMessage::STOP) {
LOG_DEBUG("Module '%s' handled and skipped other processing\n", pi.name);
LOG_DEBUG("Module '%s' handled and skipped other processing", pi.name);
break;
}
}
@@ -176,7 +176,7 @@ void MeshModule::callModules(meshtastic_MeshPacket &mp, RxSource src)
// no response reply
// No one wanted to reply to this request, tell the requster that happened
LOG_DEBUG("No one responded, send a nak\n");
LOG_DEBUG("No one responded, send a nak");
// SECURITY NOTE! I considered sending back a different error code if we didn't find the psk (i.e. !isDecoded)
// but opted NOT TO. Because it is not a good idea to let remote nodes 'probe' to find out which PSKs were "good" vs
@@ -187,8 +187,7 @@ void MeshModule::callModules(meshtastic_MeshPacket &mp, RxSource src)
}
if (!moduleFound && isDecoded) {
LOG_DEBUG("No modules interested in portnum=%d, src=%s\n", mp.decoded.portnum,
(src == RX_SRC_LOCAL) ? "LOCAL" : "REMOTE");
LOG_DEBUG("No modules interested in portnum=%d, src=%s", mp.decoded.portnum, (src == RX_SRC_LOCAL) ? "LOCAL" : "REMOTE");
}
}
@@ -211,7 +210,7 @@ void MeshModule::sendResponse(const meshtastic_MeshPacket &req)
currentReply = r;
} else {
// Ignore - this is now expected behavior for routing module (because it ignores some replies)
// LOG_WARN("Client requested response but this module did not provide\n");
// LOG_WARN("Client requested response but this module did not provide");
}
}
@@ -240,7 +239,7 @@ std::vector<MeshModule *> MeshModule::GetMeshModulesWithUIFrames()
for (auto i = modules->begin(); i != modules->end(); ++i) {
auto &pi = **i;
if (pi.wantUIFrame()) {
LOG_DEBUG("%s wants a UI Frame\n", pi.name);
LOG_DEBUG("%s wants a UI Frame", pi.name);
modulesWithUIFrames.push_back(&pi);
}
}
@@ -255,7 +254,7 @@ void MeshModule::observeUIEvents(Observer<const UIFrameEvent *> *observer)
auto &pi = **i;
Observable<const UIFrameEvent *> *observable = pi.getUIFrameObservable();
if (observable != NULL) {
LOG_DEBUG("%s wants a UI Frame\n", pi.name);
LOG_DEBUG("%s wants a UI Frame", pi.name);
observer->observe(observable);
}
}
@@ -273,7 +272,7 @@ AdminMessageHandleResult MeshModule::handleAdminMessageForAllModules(const mesht
AdminMessageHandleResult h = pi.handleAdminMessageForModule(mp, request, response);
if (h == AdminMessageHandleResult::HANDLED_WITH_RESPONSE) {
// In case we have a response it always has priority.
LOG_DEBUG("Reply prepared by module '%s' of variant: %d\n", pi.name, response->which_payload_variant);
LOG_DEBUG("Reply prepared by module '%s' of variant: %d", pi.name, response->which_payload_variant);
handled = h;
} else if ((handled != AdminMessageHandleResult::HANDLED_WITH_RESPONSE) && (h == AdminMessageHandleResult::HANDLED)) {
// In case the message is handled it should be populated, but will not overwrite

View File

@@ -80,15 +80,15 @@ int MeshService::handleFromRadio(const meshtastic_MeshPacket *mp)
nodeDB->updateFrom(*mp); // update our DB state based off sniffing every RX packet from the radio
if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag &&
mp->decoded.portnum == meshtastic_PortNum_TELEMETRY_APP && mp->decoded.request_id > 0) {
LOG_DEBUG("Received telemetry response. Skip sending our NodeInfo.\n"); // because this potentially a Repeater which will
// ignore our request for its NodeInfo
LOG_DEBUG("Received telemetry response. Skip sending our NodeInfo."); // because this potentially a Repeater which will
// ignore our request for its NodeInfo
} else if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag && !nodeDB->getMeshNode(mp->from)->has_user &&
nodeInfoModule) {
LOG_INFO("Heard new node on channel %d, sending NodeInfo and asking for a response.\n", mp->channel);
LOG_INFO("Heard new node on channel %d, sending NodeInfo and asking for a response.", mp->channel);
if (airTime->isTxAllowedChannelUtil(true)) {
nodeInfoModule->sendOurNodeInfo(mp->from, true, mp->channel);
} else {
LOG_DEBUG("Skip sending NodeInfo due to > 25 percent channel util.\n");
LOG_DEBUG("Skip sending NodeInfo due to > 25 percent channel util.");
}
}
@@ -130,7 +130,7 @@ bool MeshService::reloadConfig(int saveWhat)
/// The owner User record just got updated, update our node DB and broadcast the info into the mesh
void MeshService::reloadOwner(bool shouldSave)
{
// LOG_DEBUG("reloadOwner()\n");
// LOG_DEBUG("reloadOwner()");
// update our local data directly
nodeDB->updateUser(nodeDB->getNodeNum(), owner);
assert(nodeInfoModule);
@@ -180,7 +180,7 @@ void MeshService::handleToRadio(meshtastic_MeshPacket &p)
// Switch the port from PortNum_SIMULATOR_APP back to the original PortNum
p.decoded.portnum = decoded->portnum;
} else
LOG_ERROR("Error decoding protobuf for simulator message!\n");
LOG_ERROR("Error decoding protobuf for simulator message!");
}
// Let SimRadio receive as if it did via its LoRa chip
SimRadio::instance->startReceive(&p);
@@ -222,7 +222,7 @@ ErrorCode MeshService::sendQueueStatusToPhone(const meshtastic_QueueStatus &qs,
copied->mesh_packet_id = mesh_packet_id;
if (toPhoneQueueStatusQueue.numFree() == 0) {
LOG_INFO("tophone queue status queue is full, discarding oldest\n");
LOG_INFO("tophone queue status queue is full, discarding oldest");
meshtastic_QueueStatus *d = toPhoneQueueStatusQueue.dequeuePtr(0);
if (d)
releaseQueueStatusToPool(d);
@@ -266,14 +266,14 @@ bool MeshService::trySendPosition(NodeNum dest, bool wantReplies)
if (hasValidPosition(node)) {
#if HAS_GPS && !MESHTASTIC_EXCLUDE_GPS
if (positionModule) {
LOG_INFO("Sending position ping to 0x%x, wantReplies=%d, channel=%d\n", dest, wantReplies, node->channel);
LOG_INFO("Sending position ping to 0x%x, wantReplies=%d, channel=%d", dest, wantReplies, node->channel);
positionModule->sendOurPosition(dest, wantReplies, node->channel);
return true;
}
} else {
#endif
if (nodeInfoModule) {
LOG_INFO("Sending nodeinfo ping to 0x%x, wantReplies=%d, channel=%d\n", dest, wantReplies, node->channel);
LOG_INFO("Sending nodeinfo ping to 0x%x, wantReplies=%d, channel=%d", dest, wantReplies, node->channel);
nodeInfoModule->sendOurNodeInfo(dest, wantReplies, node->channel);
}
}
@@ -298,12 +298,12 @@ void MeshService::sendToPhone(meshtastic_MeshPacket *p)
if (toPhoneQueue.numFree() == 0) {
if (p->decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP ||
p->decoded.portnum == meshtastic_PortNum_RANGE_TEST_APP) {
LOG_WARN("ToPhone queue is full, discarding oldest\n");
LOG_WARN("ToPhone queue is full, discarding oldest");
meshtastic_MeshPacket *d = toPhoneQueue.dequeuePtr(0);
if (d)
releaseToPool(d);
} else {
LOG_WARN("ToPhone queue is full, dropping packet.\n");
LOG_WARN("ToPhone queue is full, dropping packet.");
releaseToPool(p);
fromNum++; // Make sure to notify observers in case they are reconnected so they can get the packets
return;
@@ -316,9 +316,9 @@ void MeshService::sendToPhone(meshtastic_MeshPacket *p)
void MeshService::sendMqttMessageToClientProxy(meshtastic_MqttClientProxyMessage *m)
{
LOG_DEBUG("Sending mqtt message on topic '%s' to client for proxy\n", m->topic);
LOG_DEBUG("Sending mqtt message on topic '%s' to client for proxy", m->topic);
if (toPhoneMqttProxyQueue.numFree() == 0) {
LOG_WARN("MqttClientProxyMessagePool queue is full, discarding oldest\n");
LOG_WARN("MqttClientProxyMessagePool queue is full, discarding oldest");
meshtastic_MqttClientProxyMessage *d = toPhoneMqttProxyQueue.dequeuePtr(0);
if (d)
releaseMqttClientProxyMessageToPool(d);
@@ -330,9 +330,9 @@ void MeshService::sendMqttMessageToClientProxy(meshtastic_MqttClientProxyMessage
void MeshService::sendClientNotification(meshtastic_ClientNotification *n)
{
LOG_DEBUG("Sending client notification to phone\n");
LOG_DEBUG("Sending client notification to phone");
if (toPhoneClientNotificationQueue.numFree() == 0) {
LOG_WARN("ClientNotification queue is full, discarding oldest\n");
LOG_WARN("ClientNotification queue is full, discarding oldest");
meshtastic_ClientNotification *d = toPhoneClientNotificationQueue.dequeuePtr(0);
if (d)
releaseClientNotificationToPool(d);
@@ -381,12 +381,12 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
} else {
// The GPS has lost lock
#ifdef GPS_EXTRAVERBOSE
LOG_DEBUG("onGPSchanged() - lost validLocation\n");
LOG_DEBUG("onGPSchanged() - lost validLocation");
#endif
}
// Used fixed position if configured regardless of GPS lock
if (config.position.fixed_position) {
LOG_WARN("Using fixed position\n");
LOG_WARN("Using fixed position");
pos = TypeConversions::ConvertToPosition(node->position);
}
@@ -394,7 +394,7 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
pos.time = getValidTime(RTCQualityFromNet);
// In debug logs, identify position by @timestamp:stage (stage 4 = nodeDB)
LOG_DEBUG("onGPSChanged() pos@%x time=%u lat=%d lon=%d alt=%d\n", pos.timestamp, pos.time, pos.latitude_i, pos.longitude_i,
LOG_DEBUG("onGPSChanged() pos@%x time=%u lat=%d lon=%d alt=%d", pos.timestamp, pos.time, pos.latitude_i, pos.longitude_i,
pos.altitude);
// Update our current position in the local DB

View File

@@ -57,4 +57,6 @@ bool isFromUs(const meshtastic_MeshPacket *p);
bool isToUs(const meshtastic_MeshPacket *p);
/* Some clients might not properly set priority, therefore we fix it here. */
void fixPriority(meshtastic_MeshPacket *p);
void fixPriority(meshtastic_MeshPacket *p);
bool isBroadcast(uint32_t dest);

View File

@@ -32,9 +32,14 @@
#if HAS_WIFI
#include "mesh/wifi/WiFiAPClient.h"
#endif
#include "SPILock.h"
#include "modules/StoreForwardModule.h"
#include <Preferences.h>
#include <esp_efuse.h>
#include <esp_efuse_table.h>
#include <nvs_flash.h>
#include <soc/efuse_reg.h>
#include <soc/soc.h>
#endif
#ifdef ARCH_PORTDUINO
@@ -55,8 +60,6 @@ meshtastic_MyNodeInfo &myNodeInfo = devicestate.my_node;
meshtastic_LocalConfig config;
meshtastic_LocalModuleConfig moduleConfig;
meshtastic_ChannelFile channelFile;
meshtastic_OEMStore oemStore;
static bool hasOemStore = false;
bool meshtastic_DeviceState_callback(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_iter_t *field)
{
@@ -102,7 +105,7 @@ static uint8_t ourMacAddr[6];
NodeDB::NodeDB()
{
LOG_INFO("Initializing NodeDB\n");
LOG_INFO("Initializing NodeDB");
loadFromDisk();
cleanupMeshDB();
@@ -111,6 +114,44 @@ NodeDB::NodeDB()
uint32_t channelFileCRC = crc32Buffer(&channelFile, sizeof(channelFile));
int saveWhat = 0;
bool hasUniqueId = false;
// Get device unique id
#if defined(ARCH_ESP32) && defined(ESP_EFUSE_OPTIONAL_UNIQUE_ID)
uint32_t unique_id[4];
// ESP32 factory burns a unique id in efuse for S2+ series and evidently C3+ series
// This is used for HMACs in the esp-rainmaker AIOT platform and seems to be a good choice for us
esp_err_t err = esp_efuse_read_field_blob(ESP_EFUSE_OPTIONAL_UNIQUE_ID, unique_id, sizeof(unique_id) * 8);
if (err == ESP_OK) {
memcpy(myNodeInfo.device_id.bytes, unique_id, sizeof(unique_id));
myNodeInfo.device_id.size = 16;
hasUniqueId = true;
} else {
LOG_WARN("Failed to read unique id from efuse");
}
#elif defined(ARCH_NRF52)
// Nordic applies a FIPS compliant Random ID to each chip at the factory
// We concatenate the device address to the Random ID to create a unique ID for now
// This will likely utilize a crypto module in the future
uint64_t device_id_start = ((uint64_t)NRF_FICR->DEVICEID[1] << 32) | NRF_FICR->DEVICEID[0];
uint64_t device_id_end = ((uint64_t)NRF_FICR->DEVICEADDR[1] << 32) | NRF_FICR->DEVICEADDR[0];
memcpy(myNodeInfo.device_id.bytes, &device_id_start, sizeof(device_id_start));
memcpy(myNodeInfo.device_id.bytes + sizeof(device_id_start), &device_id_end, sizeof(device_id_end));
myNodeInfo.device_id.size = 16;
// Uncomment below to print the device id
// hasUniqueId = true;
#else
// FIXME - implement for other platforms
#endif
// if (hasUniqueId) {
// std::string deviceIdHex;
// for (size_t i = 0; i < myNodeInfo.device_id.size; ++i) {
// char buf[3];
// snprintf(buf, sizeof(buf), "%02X", myNodeInfo.device_id.bytes[i]);
// deviceIdHex += buf;
// }
// LOG_DEBUG("Device ID (HEX): %s", deviceIdHex.c_str());
// }
// likewise - we always want the app requirements to come from the running appload
myNodeInfo.min_app_version = 30200; // format is Mmmss (where M is 1+the numeric major number. i.e. 30200 means 2.2.00
@@ -134,21 +175,23 @@ NodeDB::NodeDB()
}
#if !(MESHTASTIC_EXCLUDE_PKI_KEYGEN || MESHTASTIC_EXCLUDE_PKI)
bool keygenSuccess = false;
if (config.security.private_key.size == 32) {
if (crypto->regeneratePublicKey(config.security.public_key.bytes, config.security.private_key.bytes)) {
if (!owner.is_licensed) {
bool keygenSuccess = false;
if (config.security.private_key.size == 32) {
if (crypto->regeneratePublicKey(config.security.public_key.bytes, config.security.private_key.bytes)) {
keygenSuccess = true;
}
} else {
LOG_INFO("Generating new PKI keys");
crypto->generateKeyPair(config.security.public_key.bytes, config.security.private_key.bytes);
keygenSuccess = true;
}
} else {
LOG_INFO("Generating new PKI keys\n");
crypto->generateKeyPair(config.security.public_key.bytes, config.security.private_key.bytes);
keygenSuccess = true;
}
if (keygenSuccess) {
config.security.public_key.size = 32;
config.security.private_key.size = 32;
owner.public_key.size = 32;
memcpy(owner.public_key.bytes, config.security.public_key.bytes, 32);
if (keygenSuccess) {
config.security.public_key.size = 32;
config.security.private_key.size = 32;
owner.public_key.size = 32;
memcpy(owner.public_key.bytes, config.security.public_key.bytes, 32);
}
}
#elif !(MESHTASTIC_EXCLUDE_PKI)
// Calculate Curve25519 public and private keys
@@ -167,11 +210,27 @@ NodeDB::NodeDB()
preferences.begin("meshtastic", false);
myNodeInfo.reboot_count = preferences.getUInt("rebootCounter", 0);
preferences.end();
LOG_DEBUG("Number of Device Reboots: %d\n", myNodeInfo.reboot_count);
LOG_DEBUG("Number of Device Reboots: %d", myNodeInfo.reboot_count);
#endif
resetRadioConfig(); // If bogus settings got saved, then fix them
// nodeDB->LOG_DEBUG("region=%d, NODENUM=0x%x, dbsize=%d\n", config.lora.region, myNodeInfo.my_node_num, numMeshNodes);
// nodeDB->LOG_DEBUG("region=%d, NODENUM=0x%x, dbsize=%d", config.lora.region, myNodeInfo.my_node_num, numMeshNodes);
// If we are setup to broadcast on the default channel, ensure that the telemetry intervals are coerced to the minimum value
// of 30 minutes or more
if (channels.isDefaultChannel(channels.getPrimaryIndex())) {
LOG_DEBUG("Coercing telemetry to min of 30 minutes on defaults");
moduleConfig.telemetry.device_update_interval = Default::getConfiguredOrMinimumValue(
moduleConfig.telemetry.device_update_interval, min_default_telemetry_interval_secs);
moduleConfig.telemetry.environment_update_interval = Default::getConfiguredOrMinimumValue(
moduleConfig.telemetry.environment_update_interval, min_default_telemetry_interval_secs);
moduleConfig.telemetry.air_quality_interval = Default::getConfiguredOrMinimumValue(
moduleConfig.telemetry.air_quality_interval, min_default_telemetry_interval_secs);
moduleConfig.telemetry.power_update_interval = Default::getConfiguredOrMinimumValue(
moduleConfig.telemetry.power_update_interval, min_default_telemetry_interval_secs);
moduleConfig.telemetry.health_update_interval = Default::getConfiguredOrMinimumValue(
moduleConfig.telemetry.health_update_interval, min_default_telemetry_interval_secs);
}
if (devicestateCRC != crc32Buffer(&devicestate, sizeof(devicestate)))
saveWhat |= SEGMENT_DEVICESTATE;
@@ -208,6 +267,11 @@ bool isToUs(const meshtastic_MeshPacket *p)
return p->to == nodeDB->getNodeNum();
}
bool isBroadcast(uint32_t dest)
{
return dest == NODENUM_BROADCAST || dest == NODENUM_BROADCAST_NO_LORA;
}
bool NodeDB::resetRadioConfig(bool factory_reset)
{
bool didFactoryReset = false;
@@ -219,7 +283,7 @@ bool NodeDB::resetRadioConfig(bool factory_reset)
}
if (channelFile.channels_count != MAX_NUM_CHANNELS) {
LOG_INFO("Setting default channel and radio preferences!\n");
LOG_INFO("Setting default channel and radio preferences!");
channels.initDefaults();
}
@@ -240,12 +304,12 @@ bool NodeDB::resetRadioConfig(bool factory_reset)
bool NodeDB::factoryReset(bool eraseBleBonds)
{
LOG_INFO("Performing factory reset!\n");
LOG_INFO("Performing factory reset!");
// first, remove the "/prefs" (this removes most prefs)
rmDir("/prefs");
#ifdef FSCom
if (FSCom.exists("/static/rangetest.csv") && !FSCom.remove("/static/rangetest.csv")) {
LOG_ERROR("Could not remove rangetest.csv file\n");
LOG_ERROR("Could not remove rangetest.csv file");
}
#endif
// second, install default state (this will deal with the duplicate mac address issue)
@@ -256,14 +320,14 @@ bool NodeDB::factoryReset(bool eraseBleBonds)
// third, write everything to disk
saveToDisk();
if (eraseBleBonds) {
LOG_INFO("Erasing BLE bonds\n");
LOG_INFO("Erasing BLE bonds");
#ifdef ARCH_ESP32
// This will erase what's in NVS including ssl keys, persistent variables and ble pairing
nvs_flash_erase();
#endif
#ifdef ARCH_NRF52
Bluefruit.begin();
LOG_INFO("Clearing bluetooth bonds!\n");
LOG_INFO("Clearing bluetooth bonds!");
bond_print_list(BLE_GAP_ROLE_PERIPH);
bond_print_list(BLE_GAP_ROLE_CENTRAL);
Bluefruit.Periph.clearBonds();
@@ -280,7 +344,7 @@ void NodeDB::installDefaultConfig(bool preserveKey = false)
if (shouldPreserveKey) {
memcpy(private_key_temp, config.security.private_key.bytes, config.security.private_key.size);
}
LOG_INFO("Installing default LocalConfig\n");
LOG_INFO("Installing default LocalConfig");
memset(&config, 0, sizeof(meshtastic_LocalConfig));
config.version = DEVICESTATE_CUR_VER;
config.has_device = true;
@@ -418,7 +482,7 @@ void NodeDB::initConfigIntervals()
void NodeDB::installDefaultModuleConfig()
{
LOG_INFO("Installing default ModuleConfig\n");
LOG_INFO("Installing default ModuleConfig");
memset(&moduleConfig, 0, sizeof(meshtastic_ModuleConfig));
moduleConfig.version = DEVICESTATE_CUR_VER;
@@ -496,8 +560,10 @@ void NodeDB::installRoleDefaults(meshtastic_Config_DeviceConfig_Role role)
if (role == meshtastic_Config_DeviceConfig_Role_ROUTER) {
initConfigIntervals();
initModuleConfigIntervals();
config.device.rebroadcast_mode = meshtastic_Config_DeviceConfig_RebroadcastMode_CORE_PORTNUMS_ONLY;
} else if (role == meshtastic_Config_DeviceConfig_Role_REPEATER) {
config.display.screen_on_secs = 1;
config.device.rebroadcast_mode = meshtastic_Config_DeviceConfig_RebroadcastMode_CORE_PORTNUMS_ONLY;
} else if (role == meshtastic_Config_DeviceConfig_Role_SENSOR) {
moduleConfig.telemetry.environment_measurement_enabled = true;
moduleConfig.telemetry.environment_update_interval = 300;
@@ -551,16 +617,19 @@ void NodeDB::initModuleConfigIntervals()
void NodeDB::installDefaultChannels()
{
LOG_INFO("Installing default ChannelFile\n");
LOG_INFO("Installing default ChannelFile");
memset(&channelFile, 0, sizeof(meshtastic_ChannelFile));
channelFile.version = DEVICESTATE_CUR_VER;
}
void NodeDB::resetNodes()
{
clearLocalPosition();
if (!config.position.fixed_position)
clearLocalPosition();
numMeshNodes = 1;
std::fill(devicestate.node_db_lite.begin() + 1, devicestate.node_db_lite.end(), meshtastic_NodeInfoLite());
devicestate.has_rx_text_message = false;
devicestate.has_rx_waypoint = false;
saveDeviceStateToDisk();
if (neighborInfoModule && moduleConfig.neighbor_info.enabled)
neighborInfoModule->resetNeighbors();
@@ -578,7 +647,7 @@ void NodeDB::removeNodeByNum(NodeNum nodeNum)
numMeshNodes -= removed;
std::fill(devicestate.node_db_lite.begin() + numMeshNodes, devicestate.node_db_lite.begin() + numMeshNodes + 1,
meshtastic_NodeInfoLite());
LOG_DEBUG("NodeDB::removeNodeByNum purged %d entries. Saving changes...\n", removed);
LOG_DEBUG("NodeDB::removeNodeByNum purged %d entries. Saving changes...", removed);
saveDeviceStateToDisk();
}
@@ -610,12 +679,12 @@ void NodeDB::cleanupMeshDB()
numMeshNodes -= removed;
std::fill(devicestate.node_db_lite.begin() + numMeshNodes, devicestate.node_db_lite.begin() + numMeshNodes + removed,
meshtastic_NodeInfoLite());
LOG_DEBUG("cleanupMeshDB purged %d entries\n", removed);
LOG_DEBUG("cleanupMeshDB purged %d entries", removed);
}
void NodeDB::installDefaultDeviceState()
{
LOG_INFO("Installing default DeviceState\n");
LOG_INFO("Installing default DeviceState");
// memset(&devicestate, 0, sizeof(meshtastic_DeviceState));
numMeshNodes = 0;
@@ -669,11 +738,11 @@ void NodeDB::pickNewNodeNum()
NodeNum candidate = random(NUM_RESERVED, LONG_MAX); // try a new random choice
if (found)
LOG_WARN("NOTE! Our desired nodenum 0x%x is invalid or in use, by MAC ending in 0x%02x%02x vs our 0x%02x%02x, so "
"trying for 0x%x\n",
"trying for 0x%x",
nodeNum, found->user.macaddr[4], found->user.macaddr[5], ourMacAddr[4], ourMacAddr[5], candidate);
nodeNum = candidate;
}
LOG_DEBUG("Using nodenum 0x%x \n", nodeNum);
LOG_DEBUG("Using nodenum 0x%x ", nodeNum);
myNodeInfo.my_node_num = nodeNum;
}
@@ -682,7 +751,6 @@ static const char *prefFileName = "/prefs/db.proto";
static const char *configFileName = "/prefs/config.proto";
static const char *moduleConfigFileName = "/prefs/module.proto";
static const char *channelFileName = "/prefs/channels.proto";
static const char *oemConfigFile = "/oem/oem.proto";
/** Load a protobuf from a file, return LoadFileResult */
LoadFileResult NodeDB::loadProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields,
@@ -694,23 +762,23 @@ LoadFileResult NodeDB::loadProto(const char *filename, size_t protoSize, size_t
auto f = FSCom.open(filename, FILE_O_READ);
if (f) {
LOG_INFO("Loading %s\n", filename);
LOG_INFO("Loading %s", filename);
pb_istream_t stream = {&readcb, &f, protoSize};
memset(dest_struct, 0, objSize);
if (!pb_decode(&stream, fields, dest_struct)) {
LOG_ERROR("Error: can't decode protobuf %s\n", PB_GET_ERROR(&stream));
LOG_ERROR("Error: can't decode protobuf %s", PB_GET_ERROR(&stream));
state = LoadFileResult::DECODE_FAILED;
} else {
LOG_INFO("Loaded %s successfully\n", filename);
LOG_INFO("Loaded %s successfully", filename);
state = LoadFileResult::LOAD_SUCCESS;
}
f.close();
} else {
LOG_ERROR("Could not open / read %s\n", filename);
LOG_ERROR("Could not open / read %s", filename);
}
#else
LOG_ERROR("ERROR: Filesystem not implemented\n");
LOG_ERROR("ERROR: Filesystem not implemented");
state = LoadFileResult::NO_FILESYSTEM;
#endif
return state;
@@ -735,11 +803,10 @@ void NodeDB::loadFromDisk()
// installDefaultDeviceState(); // Our in RAM copy might now be corrupt
//} else {
if (devicestate.version < DEVICESTATE_MIN_VER) {
LOG_WARN("Devicestate %d is old, discarding\n", devicestate.version);
LOG_WARN("Devicestate %d is old, discarding", devicestate.version);
installDefaultDeviceState();
} else {
LOG_INFO("Loaded saved devicestate version %d, with nodecount: %d\n", devicestate.version,
devicestate.node_db_lite.size());
LOG_INFO("Loaded saved devicestate version %d, with nodecount: %d", devicestate.version, devicestate.node_db_lite.size());
meshNodes = &devicestate.node_db_lite;
numMeshNodes = devicestate.node_db_lite.size();
}
@@ -751,10 +818,10 @@ void NodeDB::loadFromDisk()
installDefaultConfig(); // Our in RAM copy might now be corrupt
} else {
if (config.version < DEVICESTATE_MIN_VER) {
LOG_WARN("config %d is old, discarding\n", config.version);
LOG_WARN("config %d is old, discarding", config.version);
installDefaultConfig(true);
} else {
LOG_INFO("Loaded saved config version %d\n", config.version);
LOG_INFO("Loaded saved config version %d", config.version);
}
}
@@ -764,10 +831,10 @@ void NodeDB::loadFromDisk()
installDefaultModuleConfig(); // Our in RAM copy might now be corrupt
} else {
if (moduleConfig.version < DEVICESTATE_MIN_VER) {
LOG_WARN("moduleConfig %d is old, discarding\n", moduleConfig.version);
LOG_WARN("moduleConfig %d is old, discarding", moduleConfig.version);
installDefaultModuleConfig();
} else {
LOG_INFO("Loaded saved moduleConfig version %d\n", moduleConfig.version);
LOG_INFO("Loaded saved moduleConfig version %d", moduleConfig.version);
}
}
@@ -777,22 +844,16 @@ void NodeDB::loadFromDisk()
installDefaultChannels(); // Our in RAM copy might now be corrupt
} else {
if (channelFile.version < DEVICESTATE_MIN_VER) {
LOG_WARN("channelFile %d is old, discarding\n", channelFile.version);
LOG_WARN("channelFile %d is old, discarding", channelFile.version);
installDefaultChannels();
} else {
LOG_INFO("Loaded saved channelFile version %d\n", channelFile.version);
LOG_INFO("Loaded saved channelFile version %d", channelFile.version);
}
}
state = loadProto(oemConfigFile, meshtastic_OEMStore_size, sizeof(meshtastic_OEMStore), &meshtastic_OEMStore_msg, &oemStore);
if (state == LoadFileResult::LOAD_SUCCESS) {
LOG_INFO("Loaded OEMStore\n");
hasOemStore = true;
}
// 2.4.X - configuration migration to update new default intervals
if (moduleConfig.version < 23) {
LOG_DEBUG("ModuleConfig version %d is stale, upgrading to new default intervals\n", moduleConfig.version);
LOG_DEBUG("ModuleConfig version %d is stale, upgrading to new default intervals", moduleConfig.version);
moduleConfig.version = DEVICESTATE_CUR_VER;
if (moduleConfig.telemetry.device_update_interval == 900)
moduleConfig.telemetry.device_update_interval = 0;
@@ -815,15 +876,18 @@ void NodeDB::loadFromDisk()
bool NodeDB::saveProto(const char *filename, size_t protoSize, const pb_msgdesc_t *fields, const void *dest_struct,
bool fullAtomic)
{
#ifdef ARCH_ESP32
concurrency::LockGuard g(spiLock);
#endif
bool okay = false;
#ifdef FSCom
auto f = SafeFile(filename, fullAtomic);
LOG_INFO("Saving %s\n", filename);
LOG_INFO("Saving %s", filename);
pb_ostream_t stream = {&writecb, static_cast<Print *>(&f), protoSize};
if (!pb_encode(&stream, fields, dest_struct)) {
LOG_ERROR("Error: can't encode protobuf %s\n", PB_GET_ERROR(&stream));
LOG_ERROR("Error: can't encode protobuf %s", PB_GET_ERROR(&stream));
} else {
okay = true;
}
@@ -831,10 +895,10 @@ bool NodeDB::saveProto(const char *filename, size_t protoSize, const pb_msgdesc_
bool writeSucceeded = f.close();
if (!okay || !writeSucceeded) {
LOG_ERROR("Can't write prefs!\n");
LOG_ERROR("Can't write prefs!");
}
#else
LOG_ERROR("ERROR: Filesystem not implemented\n");
LOG_ERROR("ERROR: Filesystem not implemented");
#endif
return okay;
}
@@ -896,11 +960,6 @@ bool NodeDB::saveToDiskNoRetry(int saveWhat)
saveProto(moduleConfigFileName, meshtastic_LocalModuleConfig_size, &meshtastic_LocalModuleConfig_msg, &moduleConfig);
}
// We might need to rewrite the OEM data if we are reformatting the FS
if ((saveWhat & SEGMENT_OEM) && hasOemStore) {
success &= saveProto(oemConfigFile, meshtastic_OEMStore_size, &meshtastic_OEMStore_msg, &oemStore);
}
if (saveWhat & SEGMENT_CHANNELS) {
success &= saveChannelsToDisk();
}
@@ -917,12 +976,10 @@ bool NodeDB::saveToDisk(int saveWhat)
bool success = saveToDiskNoRetry(saveWhat);
if (!success) {
LOG_ERROR("Failed to save to disk, retrying...\n");
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
FSCom.format();
// We need to rewrite the OEM data if we are reformatting the FS
saveWhat |= SEGMENT_OEM;
#endif
success = saveToDiskNoRetry(saveWhat);
@@ -995,7 +1052,7 @@ void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSou
if (src == RX_SRC_LOCAL) {
// Local packet, fully authoritative
LOG_INFO("updatePosition LOCAL pos@%x time=%u lat=%d lon=%d alt=%d\n", p.timestamp, p.time, p.latitude_i, p.longitude_i,
LOG_INFO("updatePosition LOCAL pos@%x time=%u lat=%d lon=%d alt=%d", p.timestamp, p.time, p.latitude_i, p.longitude_i,
p.altitude);
setLocalPosition(p);
@@ -1003,7 +1060,7 @@ void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSou
} else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.timestamp && !p.location_source) {
// FIXME SPECIAL TIME SETTING PACKET FROM EUD TO RADIO
// (stop-gap fix for issue #900)
LOG_DEBUG("updatePosition SPECIAL time setting time=%u\n", p.time);
LOG_DEBUG("updatePosition SPECIAL time setting time=%u", p.time);
info->position.time = p.time;
} else {
// Be careful to only update fields that have been set by the REMOTE sender
@@ -1011,7 +1068,7 @@ void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSou
// recorded based on the packet rxTime
//
// FIXME perhaps handle RX_SRC_USER separately?
LOG_INFO("updatePosition REMOTE node=0x%x time=%u lat=%d lon=%d\n", nodeId, p.time, p.latitude_i, p.longitude_i);
LOG_INFO("updatePosition REMOTE node=0x%x time=%u lat=%d lon=%d", nodeId, p.time, p.latitude_i, p.longitude_i);
// First, back up fields that we want to protect from overwrite
uint32_t tmp_time = info->position.time;
@@ -1041,9 +1098,9 @@ void NodeDB::updateTelemetry(uint32_t nodeId, const meshtastic_Telemetry &t, RxS
if (src == RX_SRC_LOCAL) {
// Local packet, fully authoritative
LOG_DEBUG("updateTelemetry LOCAL\n");
LOG_DEBUG("updateTelemetry LOCAL");
} else {
LOG_DEBUG("updateTelemetry REMOTE node=0x%x \n", nodeId);
LOG_DEBUG("updateTelemetry REMOTE node=0x%x ", nodeId);
}
info->device_metrics = t.variant.device_metrics;
info->has_device_metrics = true;
@@ -1060,16 +1117,16 @@ bool NodeDB::updateUser(uint32_t nodeId, meshtastic_User &p, uint8_t channelInde
return false;
}
LOG_DEBUG("old user %s/%s, channel=%d\n", info->user.long_name, info->user.short_name, info->channel);
LOG_DEBUG("old user %s/%s, channel=%d", info->user.long_name, info->user.short_name, info->channel);
#if !(MESHTASTIC_EXCLUDE_PKI)
if (p.public_key.size > 0) {
printBytes("Incoming Pubkey: ", p.public_key.bytes, 32);
if (info->user.public_key.size > 0) { // if we have a key for this user already, don't overwrite with a new one
LOG_INFO("Public Key set for node, not updating!\n");
LOG_INFO("Public Key set for node, not updating!");
// we copy the key into the incoming packet, to prevent overwrite
memcpy(p.public_key.bytes, info->user.public_key.bytes, 32);
} else {
LOG_INFO("Updating Node Pubkey!\n");
LOG_INFO("Updating Node Pubkey!");
}
}
#endif
@@ -1084,8 +1141,7 @@ bool NodeDB::updateUser(uint32_t nodeId, meshtastic_User &p, uint8_t channelInde
}
if (nodeId != getNodeNum())
info->channel = channelIndex; // Set channel we need to use to reach this node (but don't set our own channel)
LOG_DEBUG("updating changed=%d user %s/%s, channel=%d\n", changed, info->user.long_name, info->user.short_name,
info->channel);
LOG_DEBUG("updating changed=%d user %s/%s, channel=%d", changed, info->user.long_name, info->user.short_name, info->channel);
info->has_user = true;
if (changed) {
@@ -1096,7 +1152,7 @@ bool NodeDB::updateUser(uint32_t nodeId, meshtastic_User &p, uint8_t channelInde
// We just changed something about the user, store our DB
Throttle::execute(
&lastNodeDbSave, ONE_MINUTE_MS, []() { nodeDB->saveToDisk(SEGMENT_DEVICESTATE); },
[]() { LOG_DEBUG("Deferring NodeDB saveToDisk for now\n"); }); // since we saved less than a minute ago
[]() { LOG_DEBUG("Deferring NodeDB saveToDisk for now"); }); // since we saved less than a minute ago
}
return changed;
@@ -1107,7 +1163,7 @@ bool NodeDB::updateUser(uint32_t nodeId, meshtastic_User &p, uint8_t channelInde
void NodeDB::updateFrom(const meshtastic_MeshPacket &mp)
{
if (mp.which_payload_variant == meshtastic_MeshPacket_decoded_tag && mp.from) {
LOG_DEBUG("Update DB node 0x%x, rx_time=%u\n", mp.from, mp.rx_time);
LOG_DEBUG("Update DB node 0x%x, rx_time=%u", mp.from, mp.rx_time);
meshtastic_NodeInfoLite *info = getOrCreateMeshNode(getFrom(&mp));
if (!info) {
@@ -1159,7 +1215,7 @@ meshtastic_NodeInfoLite *NodeDB::getOrCreateMeshNode(NodeNum n)
if ((numMeshNodes >= MAX_NUM_NODES) || (memGet.getFreeHeap() < MINIMUM_SAFE_FREE_HEAP)) {
if (screen)
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\n", numMeshNodes,
LOG_WARN("Node database full with %i nodes and %i bytes free! Erasing oldest entry", numMeshNodes,
memGet.getFreeHeap());
// look for oldest node and erase it
uint32_t oldest = UINT32_MAX;
@@ -1195,7 +1251,7 @@ meshtastic_NodeInfoLite *NodeDB::getOrCreateMeshNode(NodeNum n)
// everything is missing except the nodenum
memset(lite, 0, sizeof(*lite));
lite->num = n;
LOG_INFO("Adding node to database with %i nodes and %i bytes free!\n", numMeshNodes, memGet.getFreeHeap());
LOG_INFO("Adding node to database with %i nodes and %i bytes free!", numMeshNodes, memGet.getFreeHeap());
}
return lite;
@@ -1209,9 +1265,9 @@ void recordCriticalError(meshtastic_CriticalErrorCode code, uint32_t address, co
if (screen)
screen->print(lcd.c_str());
if (filename) {
LOG_ERROR("NOTE! Recording critical error %d at %s:%lu\n", code, filename, address);
LOG_ERROR("NOTE! Recording critical error %d at %s:%lu", code, filename, address);
} else {
LOG_ERROR("NOTE! Recording critical error %d, address=0x%lx\n", code, address);
LOG_ERROR("NOTE! Recording critical error %d, address=0x%lx", code, address);
}
// Record error to DB

View File

@@ -21,7 +21,6 @@ DeviceState versions used to be defined in the .proto file but really only this
#define SEGMENT_MODULECONFIG 2
#define SEGMENT_DEVICESTATE 4
#define SEGMENT_CHANNELS 8
#define SEGMENT_OEM 16
#define DEVICESTATE_CUR_VER 23
#define DEVICESTATE_MIN_VER 22
@@ -31,7 +30,6 @@ extern meshtastic_ChannelFile channelFile;
extern meshtastic_MyNodeInfo &myNodeInfo;
extern meshtastic_LocalConfig config;
extern meshtastic_LocalModuleConfig moduleConfig;
extern meshtastic_OEMStore oemStore;
extern meshtastic_User &owner;
extern meshtastic_Position localPosition;
@@ -154,12 +152,12 @@ class NodeDB
void setLocalPosition(meshtastic_Position position, bool timeOnly = false)
{
if (timeOnly) {
LOG_DEBUG("Setting local position time only: time=%u timestamp=%u\n", position.time, position.timestamp);
LOG_DEBUG("Setting local position time only: time=%u timestamp=%u", position.time, position.timestamp);
localPosition.time = position.time;
localPosition.timestamp = position.timestamp > 0 ? position.timestamp : position.time;
return;
}
LOG_DEBUG("Setting local position: lat=%i lon=%i time=%u timestamp=%u\n", position.latitude_i, position.longitude_i,
LOG_DEBUG("Setting local position: lat=%i lon=%i time=%u timestamp=%u", position.latitude_i, position.longitude_i,
position.time, position.timestamp);
localPosition = position;
}

View File

@@ -19,7 +19,7 @@ PacketHistory::PacketHistory()
bool PacketHistory::wasSeenRecently(const meshtastic_MeshPacket *p, bool withUpdate)
{
if (p->id == 0) {
LOG_DEBUG("Ignoring message with zero id\n");
LOG_DEBUG("Ignoring message with zero id");
return false; // Not a floodable message ID, so we don't care
}
@@ -39,7 +39,7 @@ bool PacketHistory::wasSeenRecently(const meshtastic_MeshPacket *p, bool withUpd
}
if (seenRecently) {
LOG_DEBUG("Found existing packet record for fr=0x%x,to=0x%x,id=0x%x\n", 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);
}
if (withUpdate) {
@@ -64,7 +64,7 @@ bool PacketHistory::wasSeenRecently(const meshtastic_MeshPacket *p, bool withUpd
*/
void PacketHistory::clearExpiredRecentPackets()
{
LOG_DEBUG("recentPackets size=%ld\n", recentPackets.size());
LOG_DEBUG("recentPackets size=%ld", recentPackets.size());
for (auto it = recentPackets.begin(); it != recentPackets.end();) {
if (!Throttle::isWithinTimespanMs(it->rxTimeMsec, FLOOD_EXPIRE_TIME)) {
@@ -74,5 +74,5 @@ void PacketHistory::clearExpiredRecentPackets()
}
}
LOG_DEBUG("recentPackets size=%ld (after clearing expired packets)\n", recentPackets.size());
LOG_DEBUG("recentPackets size=%ld (after clearing expired packets)", recentPackets.size());
}

View File

@@ -55,16 +55,16 @@ void PhoneAPI::handleStartConfig()
state = STATE_SEND_MY_INFO;
pauseBluetoothLogging = true;
filesManifest = getFiles("/", 10);
LOG_DEBUG("Got %d files in manifest\n", filesManifest.size());
LOG_DEBUG("Got %d files in manifest", filesManifest.size());
LOG_INFO("Starting API client config\n");
LOG_INFO("Starting API client config");
nodeInfoForPhone.num = 0; // Don't keep returning old nodeinfos
resetReadIndex();
}
void PhoneAPI::close()
{
LOG_INFO("PhoneAPI::close()\n");
LOG_INFO("PhoneAPI::close()");
if (state != STATE_SEND_NOTHING) {
state = STATE_SEND_NOTHING;
@@ -95,7 +95,7 @@ bool PhoneAPI::checkConnectionTimeout()
if (isConnected()) {
bool newContact = checkIsConnected();
if (!newContact) {
LOG_INFO("Lost phone connection\n");
LOG_INFO("Lost phone connection");
close();
return true;
}
@@ -118,41 +118,41 @@ bool PhoneAPI::handleToRadio(const uint8_t *buf, size_t bufLength)
return handleToRadioPacket(toRadioScratch.packet);
case meshtastic_ToRadio_want_config_id_tag:
config_nonce = toRadioScratch.want_config_id;
LOG_INFO("Client wants config, nonce=%u\n", config_nonce);
LOG_INFO("Client wants config, nonce=%u", config_nonce);
handleStartConfig();
break;
case meshtastic_ToRadio_disconnect_tag:
LOG_INFO("Disconnecting from phone\n");
LOG_INFO("Disconnecting from phone");
close();
break;
case meshtastic_ToRadio_xmodemPacket_tag:
LOG_INFO("Got xmodem packet\n");
LOG_INFO("Got xmodem packet");
#ifdef FSCom
xModem.handlePacket(toRadioScratch.xmodemPacket);
#endif
break;
#if !MESHTASTIC_EXCLUDE_MQTT
case meshtastic_ToRadio_mqttClientProxyMessage_tag:
LOG_INFO("Got MqttClientProxy message\n");
LOG_INFO("Got MqttClientProxy message");
if (mqtt && moduleConfig.mqtt.proxy_to_client_enabled && moduleConfig.mqtt.enabled &&
(channels.anyMqttEnabled() || moduleConfig.mqtt.map_reporting_enabled)) {
mqtt->onClientProxyReceive(toRadioScratch.mqttClientProxyMessage);
} else {
LOG_WARN("MqttClientProxy received but proxy is not enabled, no channels have up/downlink, or map reporting "
"not enabled\n");
"not enabled");
}
break;
#endif
case meshtastic_ToRadio_heartbeat_tag:
LOG_DEBUG("Got client heartbeat\n");
LOG_DEBUG("Got client heartbeat");
break;
default:
// Ignore nop messages
// LOG_DEBUG("Error: unexpected ToRadio variant\n");
// LOG_DEBUG("Error: unexpected ToRadio variant");
break;
}
} else {
LOG_ERROR("Error: ignoring malformed toradio\n");
LOG_ERROR("Error: ignoring malformed toradio");
}
return false;
@@ -179,7 +179,7 @@ bool PhoneAPI::handleToRadio(const uint8_t *buf, size_t bufLength)
size_t PhoneAPI::getFromRadio(uint8_t *buf)
{
if (!available()) {
// LOG_DEBUG("getFromRadio=not available\n");
// LOG_DEBUG("getFromRadio=not available");
return 0;
}
// In case we send a FromRadio packet
@@ -188,11 +188,11 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
// Advance states as needed
switch (state) {
case STATE_SEND_NOTHING:
LOG_INFO("getFromRadio=STATE_SEND_NOTHING\n");
LOG_INFO("getFromRadio=STATE_SEND_NOTHING");
break;
case STATE_SEND_MY_INFO:
LOG_INFO("getFromRadio=STATE_SEND_MY_INFO\n");
LOG_INFO("getFromRadio=STATE_SEND_MY_INFO");
// If the user has specified they don't want our node to share its location, make sure to tell the phone
// app not to send locations on our behalf.
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_my_info_tag;
@@ -203,7 +203,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
break;
case STATE_SEND_OWN_NODEINFO: {
LOG_INFO("getFromRadio=STATE_SEND_OWN_NODEINFO\n");
LOG_INFO("getFromRadio=STATE_SEND_OWN_NODEINFO");
auto us = nodeDB->readNextMeshNode(readIndex);
if (us) {
nodeInfoForPhone = TypeConversions::ConvertToNodeInfo(us);
@@ -219,14 +219,14 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
}
case STATE_SEND_METADATA:
LOG_INFO("getFromRadio=STATE_SEND_METADATA\n");
LOG_INFO("getFromRadio=STATE_SEND_METADATA");
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_metadata_tag;
fromRadioScratch.metadata = getDeviceMetadata();
state = STATE_SEND_CHANNELS;
break;
case STATE_SEND_CHANNELS:
LOG_INFO("getFromRadio=STATE_SEND_CHANNELS\n");
LOG_INFO("getFromRadio=STATE_SEND_CHANNELS");
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_channel_tag;
fromRadioScratch.channel = channels.getByIndex(config_state);
config_state++;
@@ -238,7 +238,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
break;
case STATE_SEND_CONFIG:
LOG_INFO("getFromRadio=STATE_SEND_CONFIG\n");
LOG_INFO("getFromRadio=STATE_SEND_CONFIG");
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_config_tag;
switch (config_state) {
case meshtastic_Config_device_tag:
@@ -278,7 +278,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
fromRadioScratch.config.which_payload_variant = meshtastic_Config_sessionkey_tag;
break;
default:
LOG_ERROR("Unknown config type %d\n", config_state);
LOG_ERROR("Unknown config type %d", config_state);
}
// NOTE: The phone app needs to know the ls_secs value so it can properly expect sleep behavior.
// So even if we internally use 0 to represent 'use default' we still need to send the value we are
@@ -293,7 +293,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
break;
case STATE_SEND_MODULECONFIG:
LOG_INFO("getFromRadio=STATE_SEND_MODULECONFIG\n");
LOG_INFO("getFromRadio=STATE_SEND_MODULECONFIG");
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_moduleConfig_tag;
switch (config_state) {
case meshtastic_ModuleConfig_mqtt_tag:
@@ -349,7 +349,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
fromRadioScratch.moduleConfig.payload_variant.paxcounter = moduleConfig.paxcounter;
break;
default:
LOG_ERROR("Unknown module config type %d\n", config_state);
LOG_ERROR("Unknown module config type %d", config_state);
}
config_state++;
@@ -362,16 +362,16 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
break;
case STATE_SEND_OTHER_NODEINFOS: {
LOG_INFO("getFromRadio=STATE_SEND_OTHER_NODEINFOS\n");
LOG_INFO("getFromRadio=STATE_SEND_OTHER_NODEINFOS");
if (nodeInfoForPhone.num != 0) {
LOG_INFO("nodeinfo: num=0x%x, lastseen=%u, id=%s, name=%s\n", nodeInfoForPhone.num, nodeInfoForPhone.last_heard,
LOG_INFO("nodeinfo: num=0x%x, lastseen=%u, id=%s, name=%s", nodeInfoForPhone.num, nodeInfoForPhone.last_heard,
nodeInfoForPhone.user.id, nodeInfoForPhone.user.long_name);
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_node_info_tag;
fromRadioScratch.node_info = nodeInfoForPhone;
// Stay in current state until done sending nodeinfos
nodeInfoForPhone.num = 0; // We just consumed a nodeinfo, will need a new one next time
} else {
LOG_INFO("Done sending nodeinfos\n");
LOG_INFO("Done sending nodeinfos");
state = STATE_SEND_FILEMANIFEST;
// Go ahead and send that ID right now
return getFromRadio(buf);
@@ -380,7 +380,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
}
case STATE_SEND_FILEMANIFEST: {
LOG_INFO("getFromRadio=STATE_SEND_FILEMANIFEST\n");
LOG_INFO("getFromRadio=STATE_SEND_FILEMANIFEST");
// last element
if (config_state == filesManifest.size()) { // also handles an empty filesManifest
config_state = 0;
@@ -390,7 +390,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
} else {
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_fileInfo_tag;
fromRadioScratch.fileInfo = filesManifest.at(config_state);
LOG_DEBUG("File: %s (%d) bytes\n", fromRadioScratch.fileInfo.file_name, fromRadioScratch.fileInfo.size_bytes);
LOG_DEBUG("File: %s (%d) bytes", fromRadioScratch.fileInfo.file_name, fromRadioScratch.fileInfo.size_bytes);
config_state++;
}
break;
@@ -403,7 +403,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
case STATE_SEND_PACKETS:
pauseBluetoothLogging = false;
// Do we have a message from the mesh or packet from the local device?
LOG_INFO("getFromRadio=STATE_SEND_PACKETS\n");
LOG_INFO("getFromRadio=STATE_SEND_PACKETS");
if (queueStatusPacketForPhone) {
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_queueStatus_tag;
fromRadioScratch.queueStatus = *queueStatusPacketForPhone;
@@ -431,7 +431,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
break;
default:
LOG_ERROR("getFromRadio unexpected state %d\n", state);
LOG_ERROR("getFromRadio unexpected state %d", state);
}
// Do we have a message from the mesh?
@@ -441,17 +441,17 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
// VERY IMPORTANT to not print debug messages while writing to fromRadioScratch - because we use that same buffer
// for logging (when we are encapsulating with protobufs)
// LOG_DEBUG("encoding toPhone packet to phone variant=%d, %d bytes\n", fromRadioScratch.which_payload_variant, numbytes);
// LOG_DEBUG("encoding toPhone packet to phone variant=%d, %d bytes", fromRadioScratch.which_payload_variant, numbytes);
return numbytes;
}
LOG_DEBUG("no FromRadio packet available\n");
LOG_DEBUG("no FromRadio packet available");
return 0;
}
void PhoneAPI::sendConfigComplete()
{
LOG_INFO("getFromRadio=STATE_SEND_COMPLETE_ID\n");
LOG_INFO("getFromRadio=STATE_SEND_COMPLETE_ID");
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_config_complete_id_tag;
fromRadioScratch.config_complete_id = config_nonce;
config_nonce = 0;
@@ -551,11 +551,11 @@ bool PhoneAPI::available()
if (!packetForPhone)
packetForPhone = service->getForPhone();
hasPacket = !!packetForPhone;
// LOG_DEBUG("available hasPacket=%d\n", hasPacket);
// LOG_DEBUG("available hasPacket=%d", hasPacket);
return hasPacket;
}
default:
LOG_ERROR("PhoneAPI::available unexpected state %d\n", state);
LOG_ERROR("PhoneAPI::available unexpected state %d", state);
}
return false;
@@ -597,20 +597,20 @@ bool PhoneAPI::handleToRadioPacket(meshtastic_MeshPacket &p)
printPacket("PACKET FROM PHONE", &p);
if (p.id > 0 && wasSeenRecently(p.id)) {
LOG_DEBUG("Ignoring packet from phone, already seen recently\n");
LOG_DEBUG("Ignoring packet from phone, already seen recently");
return false;
}
if (p.decoded.portnum == meshtastic_PortNum_TRACEROUTE_APP && lastPortNumToRadio[p.decoded.portnum] &&
Throttle::isWithinTimespanMs(lastPortNumToRadio[p.decoded.portnum], THIRTY_SECONDS_MS)) {
LOG_WARN("Rate limiting portnum %d\n", p.decoded.portnum);
LOG_WARN("Rate limiting portnum %d", p.decoded.portnum);
sendNotification(meshtastic_LogRecord_Level_WARNING, p.id, "TraceRoute can only be sent once every 30 seconds");
meshtastic_QueueStatus qs = router->getQueueStatus();
service->sendQueueStatusToPhone(qs, 0, p.id);
return false;
} else if (p.decoded.portnum == meshtastic_PortNum_POSITION_APP && lastPortNumToRadio[p.decoded.portnum] &&
Throttle::isWithinTimespanMs(lastPortNumToRadio[p.decoded.portnum], FIVE_SECONDS_MS)) {
LOG_WARN("Rate limiting portnum %d\n", p.decoded.portnum);
LOG_WARN("Rate limiting portnum %d", p.decoded.portnum);
meshtastic_QueueStatus qs = router->getQueueStatus();
service->sendQueueStatusToPhone(qs, 0, p.id);
// FIXME: Figure out why this continues to happen
@@ -629,10 +629,10 @@ int PhoneAPI::onNotify(uint32_t newValue)
// doesn't call this from idle)
if (state == STATE_SEND_PACKETS) {
LOG_INFO("Telling client we have new packets %u\n", newValue);
LOG_INFO("Telling client we have new packets %u", newValue);
onNowHasData(newValue);
} else {
LOG_DEBUG("(Client not yet interested in packets)\n");
LOG_DEBUG("(Client not yet interested in packets)");
}
return timeout ? -1 : 0; // If we timed out, MeshService should stop iterating through observers as we just removed one

View File

@@ -47,7 +47,7 @@ template <class T> class ProtobufModule : protected SinglePortModule
p->decoded.payload.size =
pb_encode_to_bytes(p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes), fields, &payload);
// LOG_DEBUG("did encode\n");
// LOG_DEBUG("did encode");
return p;
}
@@ -82,7 +82,7 @@ template <class T> class ProtobufModule : protected SinglePortModule
// it would be better to update even if the message was destined to others.
auto &p = mp.decoded;
LOG_INFO("Received %s from=0x%0x, id=0x%x, portnum=%d, payloadlen=%d\n", name, mp.from, mp.id, p.portnum, p.payload.size);
LOG_INFO("Received %s from=0x%0x, id=0x%x, portnum=%d, payloadlen=%d", name, mp.from, mp.id, p.portnum, p.payload.size);
T scratch;
T *decoded = NULL;
@@ -91,7 +91,7 @@ template <class T> class ProtobufModule : protected SinglePortModule
if (pb_decode_from_bytes(p.payload.bytes, p.payload.size, fields, &scratch)) {
decoded = &scratch;
} else {
LOG_ERROR("Error decoding protobuf module!\n");
LOG_ERROR("Error decoding protobuf module!");
// if we can't decode it, nobody can process it!
return ProcessMessage::STOP;
}
@@ -112,7 +112,7 @@ template <class T> class ProtobufModule : protected SinglePortModule
if (pb_decode_from_bytes(p.payload.bytes, p.payload.size, fields, &scratch)) {
decoded = &scratch;
} else {
LOG_ERROR("Error decoding protobuf module!\n");
LOG_ERROR("Error decoding protobuf module!");
// if we can't decode it, nobody can process it!
return;
}

View File

@@ -82,7 +82,7 @@ RF95Interface::RF95Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIO
RADIOLIB_PIN_TYPE busy)
: RadioLibInterface(hal, cs, irq, rst, busy)
{
LOG_DEBUG("RF95Interface(cs=%d, irq=%d, rst=%d, busy=%d)\n", cs, irq, rst, busy);
LOG_DEBUG("RF95Interface(cs=%d, irq=%d, rst=%d, busy=%d)", cs, irq, rst, busy);
}
/** Some boards require GPIO control of tx vs rx paths */
@@ -176,12 +176,12 @@ bool RF95Interface::init()
setTransmitEnable(false);
int res = lora->begin(getFreq(), bw, sf, cr, syncWord, power, preambleLength);
LOG_INFO("RF95 init result %d\n", res);
LOG_INFO("Frequency set to %f\n", getFreq());
LOG_INFO("Bandwidth set to %f\n", bw);
LOG_INFO("Power output set to %d\n", power);
LOG_INFO("RF95 init result %d", res);
LOG_INFO("Frequency set to %f", getFreq());
LOG_INFO("Bandwidth set to %f", bw);
LOG_INFO("Power output set to %d", power);
#if defined(RADIOMASTER_900_BANDIT_NANO) || defined(RADIOMASTER_900_BANDIT)
LOG_INFO("DAC output set to %d\n", powerDAC);
LOG_INFO("DAC output set to %d", powerDAC);
#endif
if (res == RADIOLIB_ERR_NONE)
@@ -220,17 +220,17 @@ bool RF95Interface::reconfigure()
err = lora->setSyncWord(syncWord);
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("RF95 setSyncWord %s%d\n", radioLibErr, err);
LOG_ERROR("RF95 setSyncWord %s%d", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
err = lora->setCurrentLimit(currentLimit);
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("RF95 setCurrentLimit %s%d\n", radioLibErr, err);
LOG_ERROR("RF95 setCurrentLimit %s%d", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
err = lora->setPreambleLength(preambleLength);
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR(" RF95 setPreambleLength %s%d\n", radioLibErr, err);
LOG_ERROR(" RF95 setPreambleLength %s%d", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
err = lora->setFrequency(getFreq());
@@ -266,7 +266,7 @@ void RF95Interface::setStandby()
{
int err = lora->standby();
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("RF95 standby %s%d\n", radioLibErr, err);
LOG_ERROR("RF95 standby %s%d", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
isReceiving = false; // If we were receiving, not any more
@@ -290,7 +290,7 @@ void RF95Interface::startReceive()
setStandby();
int err = lora->startReceive();
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("RF95 startReceive %s%d\n", radioLibErr, err);
LOG_ERROR("RF95 startReceive %s%d", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
isReceiving = true;
@@ -308,14 +308,14 @@ bool RF95Interface::isChannelActive()
result = lora->scanChannel();
if (result == RADIOLIB_PREAMBLE_DETECTED) {
// LOG_DEBUG("Channel is busy!\n");
// LOG_DEBUG("Channel is busy!");
return true;
}
if (result != RADIOLIB_CHANNEL_FREE)
LOG_ERROR("RF95 isChannelActive %s%d\n", radioLibErr, result);
LOG_ERROR("RF95 isChannelActive %s%d", radioLibErr, result);
assert(result != RADIOLIB_ERR_WRONG_MODEM);
// LOG_DEBUG("Channel is free!\n");
// LOG_DEBUG("Channel is free!");
return false;
}

View File

@@ -170,11 +170,11 @@ void initRegion()
#ifdef REGULATORY_LORA_REGIONCODE
for (; r->code != meshtastic_Config_LoRaConfig_RegionCode_UNSET && r->code != REGULATORY_LORA_REGIONCODE; r++)
;
LOG_INFO("Wanted region %d, regulatory override to %s\n", config.lora.region, r->name);
LOG_INFO("Wanted region %d, regulatory override to %s", config.lora.region, r->name);
#else
for (; r->code != meshtastic_Config_LoRaConfig_RegionCode_UNSET && r->code != config.lora.region; r++)
;
LOG_INFO("Wanted region %d, using %s\n", config.lora.region, r->name);
LOG_INFO("Wanted region %d, using %s", config.lora.region, r->name);
#endif
myRegion = r;
}
@@ -234,7 +234,7 @@ uint32_t RadioInterface::getRetransmissionMsec(const meshtastic_MeshPacket *p)
size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_Data_msg, &p->decoded);
uint32_t packetAirtime = getPacketTime(numbytes + sizeof(PacketHeader));
// Make sure enough time has elapsed for this packet to be sent and an ACK is received.
// LOG_DEBUG("Waiting for flooding message with airtime %d and slotTime is %d\n", packetAirtime, slotTimeMsec);
// LOG_DEBUG("Waiting for flooding message with airtime %d and slotTime is %d", packetAirtime, slotTimeMsec);
float channelUtil = airTime->channelUtilizationPercent();
uint8_t CWsize = map(channelUtil, 0, 100, CWmin, CWmax);
// Assuming we pick max. of CWsize and there will be a client with SNR at half the range
@@ -250,7 +250,7 @@ uint32_t RadioInterface::getTxDelayMsec()
current channel utilization. */
float channelUtil = airTime->channelUtilizationPercent();
uint8_t CWsize = map(channelUtil, 0, 100, CWmin, CWmax);
// LOG_DEBUG("Current channel utilization is %f so setting CWsize to %d\n", channelUtil, CWsize);
// LOG_DEBUG("Current channel utilization is %f so setting CWsize to %d", channelUtil, CWsize);
return random(0, pow(2, CWsize)) * slotTimeMsec;
}
@@ -267,15 +267,15 @@ uint32_t RadioInterface::getTxDelayMsecWeighted(float snr)
// low SNR = small CW size (Short Delay)
uint32_t delay = 0;
uint8_t CWsize = map(snr, SNR_MIN, SNR_MAX, CWmin, CWmax);
// LOG_DEBUG("rx_snr of %f so setting CWsize to:%d\n", snr, CWsize);
// LOG_DEBUG("rx_snr of %f so setting CWsize to:%d", snr, CWsize);
if (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER ||
config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER) {
delay = random(0, 2 * CWsize) * slotTimeMsec;
LOG_DEBUG("rx_snr found in packet. As a router, setting tx delay:%d\n", delay);
LOG_DEBUG("rx_snr found in packet. Router: setting tx delay:%d", delay);
} else {
// offset the maximum delay for routers: (2 * CWmax * slotTimeMsec)
delay = (2 * CWmax * slotTimeMsec) + random(0, pow(2, CWsize)) * slotTimeMsec;
LOG_DEBUG("rx_snr found in packet. Setting tx delay:%d\n", delay);
LOG_DEBUG("rx_snr found in packet. Setting tx delay:%d", delay);
}
return delay;
@@ -329,7 +329,7 @@ void printPacket(const char *prefix, const meshtastic_MeshPacket *p)
out += DEBUG_PORT.mt_sprintf(" priority=%d", p->priority);
out += ")";
LOG_DEBUG("%s\n", out.c_str());
LOG_DEBUG("%s", out.c_str());
#endif
}
@@ -346,7 +346,7 @@ bool RadioInterface::reconfigure()
bool RadioInterface::init()
{
LOG_INFO("Starting meshradio init...\n");
LOG_INFO("Starting meshradio init...");
configChangedObserver.observe(&service->configChanged);
preflightSleepObserver.observe(&preflightSleep);
@@ -494,8 +494,7 @@ void RadioInterface::applyModemConfig()
}
if ((myRegion->freqEnd - myRegion->freqStart) < bw / 1000) {
static const char *err_string =
"Regional frequency range is smaller than bandwidth. Falling back to default preset.\n";
static const char *err_string = "Regional frequency range is smaller than bandwidth. Falling back to default preset.";
LOG_ERROR(err_string);
RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING);
@@ -556,15 +555,15 @@ void RadioInterface::applyModemConfig()
preambleTimeMsec = getPacketTime((uint32_t)0);
maxPacketTimeMsec = getPacketTime(meshtastic_Constants_DATA_PAYLOAD_LEN + sizeof(PacketHeader));
LOG_INFO("Radio freq=%.3f, config.lora.frequency_offset=%.3f\n", freq, loraConfig.frequency_offset);
LOG_INFO("Set radio: region=%s, name=%s, config=%u, ch=%d, power=%d\n", myRegion->name, channelName, loraConfig.modem_preset,
LOG_INFO("Radio freq=%.3f, config.lora.frequency_offset=%.3f", freq, loraConfig.frequency_offset);
LOG_INFO("Set radio: region=%s, name=%s, config=%u, ch=%d, power=%d", myRegion->name, channelName, loraConfig.modem_preset,
channel_num, power);
LOG_INFO("myRegion->freqStart -> myRegion->freqEnd: %f -> %f (%f MHz)\n", myRegion->freqStart, myRegion->freqEnd,
LOG_INFO("myRegion->freqStart -> myRegion->freqEnd: %f -> %f (%f MHz)", myRegion->freqStart, myRegion->freqEnd,
myRegion->freqEnd - myRegion->freqStart);
LOG_INFO("numChannels: %d x %.3fkHz\n", numChannels, bw);
LOG_INFO("channel_num: %d\n", channel_num + 1);
LOG_INFO("frequency: %f\n", getFreq());
LOG_INFO("Slot time: %u msec\n", slotTimeMsec);
LOG_INFO("numChannels: %d x %.3fkHz", numChannels, bw);
LOG_INFO("channel_num: %d", channel_num + 1);
LOG_INFO("frequency: %f", getFreq());
LOG_INFO("Slot time: %u msec", slotTimeMsec);
}
/**
@@ -579,11 +578,11 @@ void RadioInterface::limitPower()
maxPower = myRegion->powerLimit;
if ((power > maxPower) && !devicestate.owner.is_licensed) {
LOG_INFO("Lowering transmit power because of regulatory limits\n");
LOG_INFO("Lowering transmit power because of regulatory limits");
power = maxPower;
}
LOG_INFO("Set radio: final power level=%d\n", power);
LOG_INFO("Set radio: final power level=%d", power);
}
void RadioInterface::deliverToReceiver(meshtastic_MeshPacket *p)
@@ -599,7 +598,7 @@ size_t RadioInterface::beginSending(meshtastic_MeshPacket *p)
{
assert(!sendingPacket);
// LOG_DEBUG("sending queued packet on mesh (txGood=%d,rxGood=%d,rxBad=%d)\n", rf95.txGood(), rf95.rxGood(), rf95.rxBad());
// LOG_DEBUG("sending 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
lastTxStart = millis();
@@ -611,7 +610,7 @@ size_t RadioInterface::beginSending(meshtastic_MeshPacket *p)
radioBuffer.header.next_hop = 0; // *** For future use ***
radioBuffer.header.relay_node = 0; // *** For future use ***
if (p->hop_limit > HOP_MAX) {
LOG_WARN("hop limit %d is too high, setting to %d\n", p->hop_limit, HOP_RELIABLE);
LOG_WARN("hop limit %d is too high, setting to %d", p->hop_limit, HOP_RELIABLE);
p->hop_limit = HOP_RELIABLE;
}
radioBuffer.header.flags =

View File

@@ -11,6 +11,10 @@
#include <pb_decode.h>
#include <pb_encode.h>
#if ARCH_PORTDUINO
#include "PortduinoGlue.h"
#include "meshUtils.h"
#endif
void LockingArduinoHal::spiBeginTransaction()
{
spiLock->lock();
@@ -20,9 +24,9 @@ void LockingArduinoHal::spiBeginTransaction()
void LockingArduinoHal::spiEndTransaction()
{
spiLock->unlock();
ArduinoHal::spiEndTransaction();
spiLock->unlock();
}
#if ARCH_PORTDUINO
void LockingArduinoHal::spiTransfer(uint8_t *out, size_t len, uint8_t *in)
@@ -111,18 +115,18 @@ bool RadioLibInterface::canSendImmediately()
if (busyTx || busyRx) {
if (busyTx) {
LOG_WARN("Can not send yet, busyTx\n");
LOG_WARN("Can not send yet, busyTx");
}
// If we've been trying to send the same packet more than one minute and we haven't gotten a
// TX IRQ from the radio, the radio is probably broken.
if (busyTx && !Throttle::isWithinTimespanMs(lastTxStart, 60000)) {
LOG_ERROR("Hardware Failure! busyTx for more than 60s\n");
LOG_ERROR("Hardware Failure! busyTx for more than 60s");
RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_TRANSMIT_FAILED);
// reboot in 5 seconds when this condition occurs.
rebootAtMsec = lastTxStart + 65000;
}
if (busyRx) {
LOG_WARN("Can not send yet, busyRx\n");
LOG_WARN("Can not send yet, busyRx");
}
return false;
} else
@@ -139,12 +143,12 @@ bool RadioLibInterface::receiveDetected(uint16_t irq, ulong syncWordHeaderValidF
} else if (!Throttle::isWithinTimespanMs(activeReceiveStart, 2 * preambleTimeMsec) && !(irq & syncWordHeaderValidFlag)) {
// The HEADER_VALID flag should be set by now if it was really a packet, so ignore PREAMBLE_DETECTED flag
activeReceiveStart = 0;
LOG_DEBUG("Ignore false preamble detection.\n");
LOG_DEBUG("Ignore false preamble detection.");
return false;
} else if (!Throttle::isWithinTimespanMs(activeReceiveStart, maxPacketTimeMsec)) {
// We should have gotten an RX_DONE IRQ by now if it was really a packet, so ignore HEADER_VALID flag
activeReceiveStart = 0;
LOG_DEBUG("Ignore false header detection.\n");
LOG_DEBUG("Ignore false header detection.");
return false;
}
}
@@ -161,13 +165,13 @@ ErrorCode RadioLibInterface::send(meshtastic_MeshPacket *p)
if (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_UNSET) {
if (disabled || !config.lora.tx_enabled) {
LOG_WARN("send - !config.lora.tx_enabled\n");
LOG_WARN("send - !config.lora.tx_enabled");
packetPool.release(p);
return ERRNO_DISABLED;
}
} else {
LOG_WARN("send - lora tx disabled because RegionCode_Unset\n");
LOG_WARN("send - lora tx disabled because RegionCode_Unset");
packetPool.release(p);
return ERRNO_DISABLED;
}
@@ -175,7 +179,7 @@ ErrorCode RadioLibInterface::send(meshtastic_MeshPacket *p)
#else
if (disabled || !config.lora.tx_enabled) {
LOG_WARN("send - !config.lora.tx_enabled\n");
LOG_WARN("send - !config.lora.tx_enabled");
packetPool.release(p);
return ERRNO_DISABLED;
}
@@ -186,7 +190,7 @@ ErrorCode RadioLibInterface::send(meshtastic_MeshPacket *p)
#ifndef LORA_DISABLE_SENDING
printPacket("enqueuing for send", p);
LOG_DEBUG("txGood=%d,txRelay=%d,rxGood=%d,rxBad=%d\n", txGood, txRelay, rxGood, rxBad);
LOG_DEBUG("txGood=%d,txRelay=%d,rxGood=%d,rxBad=%d", txGood, txRelay, rxGood, rxBad);
ErrorCode res = txQueue.enqueue(p) ? ERRNO_OK : ERRNO_UNKNOWN;
if (res != ERRNO_OK) { // we weren't able to queue it, so we must drop it to prevent leaks
@@ -196,7 +200,7 @@ ErrorCode RadioLibInterface::send(meshtastic_MeshPacket *p)
// set (random) transmit delay to let others reconfigure their radio,
// to avoid collisions and implement timing-based flooding
// LOG_DEBUG("Set random delay before transmitting.\n");
// LOG_DEBUG("Set random delay before transmitting.");
setTransmitDelay();
return res;
@@ -221,7 +225,7 @@ bool RadioLibInterface::canSleep()
{
bool res = txQueue.empty();
if (!res) { // only print debug messages if we are vetoing sleep
LOG_DEBUG("radio wait to sleep, txEmpty=%d\n", res);
LOG_DEBUG("radio wait to sleep, txEmpty=%d", res);
}
return res;
}
@@ -234,7 +238,7 @@ bool RadioLibInterface::cancelSending(NodeNum from, PacketId id)
packetPool.release(p); // free the packet we just removed
bool result = (p != NULL);
LOG_DEBUG("cancelSending id=0x%x, removed=%d\n", id, result);
LOG_DEBUG("cancelSending id=0x%x, removed=%d", id, result);
return result;
}
@@ -251,42 +255,45 @@ void RadioLibInterface::onNotify(uint32_t notification)
case ISR_TX:
handleTransmitInterrupt();
startReceive();
// LOG_DEBUG("tx complete - starting timer\n");
// LOG_DEBUG("tx complete - starting timer");
startTransmitTimer();
break;
case ISR_RX:
handleReceiveInterrupt();
startReceive();
// LOG_DEBUG("rx complete - starting timer\n");
// LOG_DEBUG("rx complete - starting timer");
startTransmitTimer();
break;
case TRANSMIT_DELAY_COMPLETED:
// LOG_DEBUG("delay done\n");
// LOG_DEBUG("delay done");
// If we are not currently in receive mode, then restart the random delay (this can happen if the main thread
// has placed the unit into standby) FIXME, how will this work if the chipset is in sleep mode?
if (!txQueue.empty()) {
if (!canSendImmediately()) {
// LOG_DEBUG("Currently Rx/Tx-ing: set random delay\n");
// LOG_DEBUG("Currently Rx/Tx-ing: set random delay");
setTransmitDelay(); // currently Rx/Tx-ing: reset random delay
} else {
if (isChannelActive()) { // check if there is currently a LoRa packet on the channel
// LOG_DEBUG("Channel is active, try receiving first.\n");
// LOG_DEBUG("Channel is active, try receiving first.");
startReceive(); // try receiving this packet, afterwards we'll be trying to transmit again
setTransmitDelay();
} else {
// Send any outgoing packets we have ready
meshtastic_MeshPacket *txp = txQueue.dequeue();
assert(txp);
bool isLoraTx = txp->to != NODENUM_BROADCAST_NO_LORA;
startSend(txp);
// Packet has been sent, count it toward our TX airtime utilization.
uint32_t xmitMsec = getPacketTime(txp);
airTime->logAirtime(TX_LOG, xmitMsec);
if (isLoraTx) {
// Packet has been sent, count it toward our TX airtime utilization.
uint32_t xmitMsec = getPacketTime(txp);
airTime->logAirtime(TX_LOG, xmitMsec);
}
}
}
} else {
// LOG_DEBUG("done with txqueue\n");
// LOG_DEBUG("done with txqueue");
}
break;
default:
@@ -309,7 +316,7 @@ void RadioLibInterface::setTransmitDelay()
startTransmitTimer(true);
} else {
// If there is a SNR, start a timer scaled based on that SNR.
LOG_DEBUG("rx_snr found. hop_limit:%d rx_snr:%f\n", p->hop_limit, p->rx_snr);
LOG_DEBUG("rx_snr found. hop_limit:%d rx_snr:%f", p->hop_limit, p->rx_snr);
startTransmitTimerSNR(p->rx_snr);
}
}
@@ -319,7 +326,7 @@ void RadioLibInterface::startTransmitTimer(bool withDelay)
// If we have work to do and the timer wasn't already scheduled, schedule it now
if (!txQueue.empty()) {
uint32_t delay = !withDelay ? 1 : getTxDelayMsec();
// LOG_DEBUG("xmit timer %d\n", delay);
// LOG_DEBUG("xmit timer %d", delay);
notifyLater(delay, TRANSMIT_DELAY_COMPLETED, false); // This will implicitly enable
}
}
@@ -329,14 +336,14 @@ void RadioLibInterface::startTransmitTimerSNR(float snr)
// If we have work to do and the timer wasn't already scheduled, schedule it now
if (!txQueue.empty()) {
uint32_t delay = getTxDelayMsecWeighted(snr);
// LOG_DEBUG("xmit timer %d\n", delay);
// LOG_DEBUG("xmit timer %d", delay);
notifyLater(delay, TRANSMIT_DELAY_COMPLETED, false); // This will implicitly enable
}
}
void RadioLibInterface::handleTransmitInterrupt()
{
// LOG_DEBUG("handling lora TX interrupt\n");
// LOG_DEBUG("handling lora TX interrupt");
// This can be null if we forced the device to enter standby mode. In that case
// ignore the transmit interrupt
if (sendingPacket)
@@ -359,7 +366,7 @@ void RadioLibInterface::completeSending()
// We are done sending that packet, release it
packetPool.release(p);
// LOG_DEBUG("Done with send\n");
// LOG_DEBUG("Done with send");
}
}
@@ -370,7 +377,7 @@ void RadioLibInterface::handleReceiveInterrupt()
// when this is called, we should be in receive mode - if we are not, just jump out instead of bombing. Possible Race
// Condition?
if (!isReceiving) {
LOG_ERROR("handleReceiveInterrupt called when not in receive mode, which shouldn't happen.\n");
LOG_ERROR("handleReceiveInterrupt called when not in receive mode, which shouldn't happen.");
return;
}
@@ -383,15 +390,20 @@ void RadioLibInterface::handleReceiveInterrupt()
#ifndef DISABLE_WELCOME_UNSET
if (config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_UNSET) {
LOG_WARN("recv - lora rx disabled because RegionCode_Unset\n");
LOG_WARN("recv - lora rx disabled because RegionCode_Unset");
airTime->logAirtime(RX_ALL_LOG, xmitMsec);
return;
}
#endif
int state = iface->readData((uint8_t *)&radioBuffer, length);
#if ARCH_PORTDUINO
if (settingsMap[logoutputlevel] == level_trace) {
printBytes("Raw incoming packet: ", (uint8_t *)&radioBuffer, length);
}
#endif
if (state != RADIOLIB_ERR_NONE) {
LOG_ERROR("ignoring received packet due to error=%d\n", state);
LOG_ERROR("ignoring received packet due to error=%d", state);
rxBad++;
airTime->logAirtime(RX_ALL_LOG, xmitMsec);
@@ -402,14 +414,14 @@ void RadioLibInterface::handleReceiveInterrupt()
// check for short packets
if (payloadLen < 0) {
LOG_WARN("ignoring received packet too short\n");
LOG_WARN("ignoring received packet too short");
rxBad++;
airTime->logAirtime(RX_ALL_LOG, xmitMsec);
} else {
rxGood++;
// altered packet with "from == 0" can do Remote Node Administration without permission
if (radioBuffer.header.from == 0) {
LOG_WARN("ignoring received packet without sender\n");
LOG_WARN("ignoring received packet without sender");
return;
}
@@ -467,8 +479,11 @@ void RadioLibInterface::setStandby()
void RadioLibInterface::startSend(meshtastic_MeshPacket *txp)
{
printPacket("Starting low level send", txp);
if (disabled || !config.lora.tx_enabled) {
LOG_WARN("Drop Tx packet because LoRa Tx disabled\n");
if (txp->to == NODENUM_BROADCAST_NO_LORA) {
LOG_DEBUG("Drop Tx packet because dest is broadcast no-lora");
packetPool.release(txp);
} else if (disabled || !config.lora.tx_enabled) {
LOG_WARN("Drop Tx packet because LoRa Tx disabled");
packetPool.release(txp);
} else {
configHardwareForSend(); // must be after setStandby
@@ -477,7 +492,7 @@ void RadioLibInterface::startSend(meshtastic_MeshPacket *txp)
int res = iface->startTransmit((uint8_t *)&radioBuffer, numbytes);
if (res != RADIOLIB_ERR_NONE) {
LOG_ERROR("startTransmit failed, error=%d\n", res);
LOG_ERROR("startTransmit failed, error=%d", res);
RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_RADIO_SPI_BUG);
// This send failed, but make sure to 'complete' it properly

View File

@@ -197,5 +197,5 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
*/
virtual void setStandby();
const char *radioLibErr = "RadioLib err=\n";
const char *radioLibErr = "RadioLib err=";
};

View File

@@ -18,8 +18,8 @@ int16_t RadioLibRF95::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_
// current limit was removed from module' ctor
// override default value (60 mA)
state = setCurrentLimit(currentLimit);
LOG_DEBUG("Current limit set to %f\n", currentLimit);
LOG_DEBUG("Current limit set result %d\n", state);
LOG_DEBUG("Current limit set to %f", currentLimit);
LOG_DEBUG("Current limit set result %d", state);
// configure settings not accessible by API
// state = config();
@@ -73,7 +73,7 @@ bool RadioLibRF95::isReceiving()
{
// 0x0b == Look for header info valid, signal synchronized or signal detected
uint8_t reg = readReg(RADIOLIB_SX127X_REG_MODEM_STAT);
// Serial.printf("reg %x\n", reg);
// Serial.printf("reg %x", reg);
return (reg & (RH_RF95_MODEM_STATUS_SIGNAL_DETECTED | RH_RF95_MODEM_STATUS_SIGNAL_SYNCHRONIZED |
RH_RF95_MODEM_STATUS_HEADER_INFO_VALID)) != 0;
}

View File

@@ -53,14 +53,14 @@ bool ReliableRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
auto key = GlobalPacketId(getFrom(p), p->id);
auto old = findPendingPacket(key);
if (old) {
LOG_DEBUG("generating implicit ack\n");
LOG_DEBUG("generating implicit ack");
// NOTE: we do NOT check p->wantAck here because p is the INCOMING rebroadcast and that packet is not expected to be
// marked as wantAck
sendAckNak(meshtastic_Routing_Error_NONE, getFrom(p), p->id, old->packet->channel);
stopRetransmission(key);
} else {
LOG_DEBUG("didn't find pending packet\n");
LOG_DEBUG("didn't find pending packet");
}
}
@@ -79,7 +79,7 @@ bool ReliableRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
* flooding this ACK back to the original sender already adds redundancy. */
bool isRepeated = p->hop_start == 0 ? (p->hop_limit == HOP_RELIABLE) : (p->hop_start == p->hop_limit);
if (wasSeenRecently(p, false) && isRepeated && !MeshModule::currentReply && !isToUs(p)) {
LOG_DEBUG("Resending implicit ack for a repeated floodmsg\n");
LOG_DEBUG("Resending implicit ack for a repeated floodmsg");
meshtastic_MeshPacket *tosend = packetPool.allocCopy(*p);
tosend->hop_limit--; // bump down the hop count
Router::send(tosend);
@@ -105,12 +105,12 @@ void ReliableRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtas
if (isToUs(p)) { // ignore ack/nak/want_ack packets that are not address to us (we only handle 0 hop reliability)
if (p->want_ack) {
if (MeshModule::currentReply) {
LOG_DEBUG("Another module replied to this message, no need for 2nd ack\n");
LOG_DEBUG("Another module replied to this message, no need for 2nd ack");
} else if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
sendAckNak(meshtastic_Routing_Error_NONE, getFrom(p), p->id, p->channel, p->hop_start, p->hop_limit);
} else if (p->which_payload_variant == meshtastic_MeshPacket_encrypted_tag && p->channel == 0 &&
(nodeDB->getMeshNode(p->from) == nullptr || nodeDB->getMeshNode(p->from)->user.public_key.size == 0)) {
LOG_INFO("PKI packet from unknown node, send PKI_UNKNOWN_PUBKEY\n");
LOG_INFO("PKI packet from unknown node, send PKI_UNKNOWN_PUBKEY");
sendAckNak(meshtastic_Routing_Error_PKI_UNKNOWN_PUBKEY, getFrom(p), p->id, channels.getPrimaryIndex(),
p->hop_start, p->hop_limit);
} else {
@@ -134,7 +134,7 @@ void ReliableRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtas
// We intentionally don't check wasSeenRecently, because it is harmless to delete non existent retransmission records
if (ackId || nakId) {
LOG_DEBUG("Received a %s for 0x%x, stopping retransmissions\n", ackId ? "ACK" : "NAK", ackId);
LOG_DEBUG("Received a %s for 0x%x, stopping retransmissions", ackId ? "ACK" : "NAK", ackId);
if (ackId) {
stopRetransmission(p->to, ackId);
} else {
@@ -227,15 +227,15 @@ int32_t ReliableRouter::doRetransmissions()
// FIXME, handle 51 day rolloever here!!!
if (p.nextTxMsec <= now) {
if (p.numRetransmissions == 0) {
LOG_DEBUG("Reliable send failed, returning a nak for fr=0x%x,to=0x%x,id=0x%x\n", p.packet->from, p.packet->to,
LOG_DEBUG("Reliable send failed, returning a nak for fr=0x%x,to=0x%x,id=0x%x", p.packet->from, p.packet->to,
p.packet->id);
sendAckNak(meshtastic_Routing_Error_MAX_RETRANSMIT, getFrom(p.packet), p.packet->id, p.packet->channel);
// Note: we don't stop retransmission here, instead the Nak packet gets processed in sniffReceived
stopRetransmission(it->first);
stillValid = false; // just deleted it
} else {
LOG_DEBUG("Sending reliable retransmission fr=0x%x,to=0x%x,id=0x%x, tries left=%d\n", p.packet->from,
p.packet->to, p.packet->id, p.numRetransmissions);
LOG_DEBUG("Sending reliable retransmission fr=0x%x,to=0x%x,id=0x%x, tries left=%d", p.packet->from, p.packet->to,
p.packet->id, p.numRetransmissions);
// Note: we call the superclass version because we don't want to have our version of send() add a new
// retransmission record

View File

@@ -48,9 +48,9 @@ Router::Router() : concurrency::OSThread("Router"), fromRadioQueue(MAX_RX_FROMRA
{
// This is called pre main(), don't touch anything here, the following code is not safe
/* LOG_DEBUG("Size of NodeInfo %d\n", sizeof(NodeInfo));
LOG_DEBUG("Size of SubPacket %d\n", sizeof(SubPacket));
LOG_DEBUG("Size of MeshPacket %d\n", sizeof(MeshPacket)); */
/* LOG_DEBUG("Size of NodeInfo %d", sizeof(NodeInfo));
LOG_DEBUG("Size of SubPacket %d", sizeof(SubPacket));
LOG_DEBUG("Size of MeshPacket %d", sizeof(MeshPacket)); */
fromRadioQueue.setReader(this);
@@ -71,7 +71,7 @@ int32_t Router::runOnce()
perhapsHandleReceived(mp);
}
// LOG_DEBUG("sleeping forever!\n");
// LOG_DEBUG("sleeping forever!");
return INT32_MAX; // Wait a long time - until we get woken for the message queue
}
@@ -81,14 +81,17 @@ int32_t Router::runOnce()
*/
void Router::enqueueReceivedMessage(meshtastic_MeshPacket *p)
{
if (fromRadioQueue.enqueue(p, 0)) { // NOWAIT - fixme, if queue is full, delete older messages
// Nasty hack because our threading is primitive. interfaces shouldn't need to know about routers FIXME
setReceivedMessage();
} else {
printPacket("BUG! fromRadioQueue is full! Discarding!", p);
packetPool.release(p);
// Try enqueue until successful
while (!fromRadioQueue.enqueue(p, 0)) {
meshtastic_MeshPacket *old_p;
old_p = fromRadioQueue.dequeuePtr(0); // Dequeue and discard the oldest packet
if (old_p) {
printPacket("fromRadioQ full, drop oldest!", old_p);
packetPool.release(old_p);
}
}
// Nasty hack because our threading is primitive. interfaces shouldn't need to know about routers FIXME
setReceivedMessage();
}
/// Generate a unique packet id
@@ -104,14 +107,14 @@ PacketId generatePacketId()
// pick a random initial sequence number at boot (to prevent repeated reboots always starting at 0)
// Note: we mask the high order bit to ensure that we never pass a 'negative' number to random
rollingPacketId = random(UINT32_MAX & 0x7fffffff);
LOG_DEBUG("Initial packet id %u\n", rollingPacketId);
LOG_DEBUG("Initial packet id %u", rollingPacketId);
}
rollingPacketId++;
rollingPacketId &= ID_COUNTER_MASK; // Mask out the top 22 bits
PacketId id = rollingPacketId | random(UINT32_MAX & 0x7fffffff) << 10; // top 22 bits
LOG_DEBUG("Partially randomized packet id %u\n", id);
LOG_DEBUG("Partially randomized packet id %u", id);
return id;
}
@@ -141,14 +144,14 @@ void Router::sendAckNak(meshtastic_Routing_Error err, NodeNum to, PacketId idFro
void Router::abortSendAndNak(meshtastic_Routing_Error err, meshtastic_MeshPacket *p)
{
LOG_ERROR("Error=%d, returning NAK and dropping packet.\n", err);
LOG_ERROR("Error=%d, returning NAK and dropping packet.", err);
sendAckNak(err, getFrom(p), p->id, p->channel);
packetPool.release(p);
}
void Router::setReceivedMessage()
{
// LOG_DEBUG("set interval to ASAP\n");
// LOG_DEBUG("set interval to ASAP");
setInterval(0); // Run ASAP, so we can figure out our correct sleep time
runASAP = true;
}
@@ -166,7 +169,7 @@ meshtastic_QueueStatus Router::getQueueStatus()
ErrorCode Router::sendLocal(meshtastic_MeshPacket *p, RxSource src)
{
if (p->to == 0) {
LOG_ERROR("Packet received with to: of 0!\n");
LOG_ERROR("Packet received with to: of 0!");
}
// No need to deliver externally if the destination is the local node
if (isToUs(p)) {
@@ -181,7 +184,7 @@ ErrorCode Router::sendLocal(meshtastic_MeshPacket *p, RxSource src)
} else {
// If we are sending a broadcast, we also treat it as if we just received it ourself
// this allows local apps (and PCs) to see broadcasts sourced locally
if (p->to == NODENUM_BROADCAST) {
if (isBroadcast(p->to)) {
handleReceived(p, src);
}
@@ -189,7 +192,7 @@ ErrorCode Router::sendLocal(meshtastic_MeshPacket *p, RxSource src)
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(p->to);
if (node && node->user.public_key.size == 0) {
p->channel = node->channel;
LOG_DEBUG("localSend to channel %d\n", p->channel);
LOG_DEBUG("localSend to channel %d", p->channel);
}
}
@@ -205,7 +208,7 @@ ErrorCode Router::sendLocal(meshtastic_MeshPacket *p, RxSource src)
ErrorCode Router::send(meshtastic_MeshPacket *p)
{
if (isToUs(p)) {
LOG_ERROR("BUG! send() called with packet destined for local node!\n");
LOG_ERROR("BUG! send() called with packet destined for local node!");
packetPool.release(p);
return meshtastic_Routing_Error_BAD_REQUEST;
} // should have already been handled by sendLocal
@@ -216,7 +219,7 @@ ErrorCode Router::send(meshtastic_MeshPacket *p)
if (hourlyTxPercent > myRegion->dutyCycle) {
#ifdef DEBUG_PORT
uint8_t silentMinutes = airTime->getSilentMinutes(hourlyTxPercent, myRegion->dutyCycle);
LOG_WARN("Duty cycle limit exceeded. Aborting send for now, you can send again in %d minutes.\n", silentMinutes);
LOG_WARN("Duty cycle limit exceeded. Aborting send for now, you can send again in %d minutes.", silentMinutes);
meshtastic_ClientNotification *cn = clientNotificationPool.allocZeroed();
cn->has_reply_id = true;
cn->reply_id = p->id;
@@ -240,7 +243,7 @@ ErrorCode Router::send(meshtastic_MeshPacket *p)
// assert
// Never set the want_ack flag on broadcast packets sent over the air.
if (p->to == NODENUM_BROADCAST)
if (isBroadcast(p->to))
p->want_ack = false;
// Up until this point we might have been using 0 for the from address (if it started with the phone), but when we send over
@@ -309,7 +312,7 @@ bool perhapsDecode(meshtastic_MeshPacket *p)
if (config.device.rebroadcast_mode == meshtastic_Config_DeviceConfig_RebroadcastMode_KNOWN_ONLY &&
(nodeDB->getMeshNode(p->from) == NULL || !nodeDB->getMeshNode(p->from)->has_user)) {
LOG_DEBUG("Node 0x%x not in nodeDB-> Rebroadcast mode KNOWN_ONLY will ignore packet\n", p->from);
LOG_DEBUG("Node 0x%x not in nodeDB-> Rebroadcast mode KNOWN_ONLY will ignore packet", p->from);
return false;
}
@@ -318,7 +321,7 @@ bool perhapsDecode(meshtastic_MeshPacket *p)
size_t rawSize = p->encrypted.size;
if (rawSize > sizeof(bytes)) {
LOG_ERROR("Packet too large to attempt decryption! (rawSize=%d > 256)\n", rawSize);
LOG_ERROR("Packet too large to attempt decryption! (rawSize=%d > 256)", rawSize);
return false;
}
bool decrypted = false;
@@ -328,31 +331,31 @@ bool perhapsDecode(meshtastic_MeshPacket *p)
memcpy(ScratchEncrypted, p->encrypted.bytes, rawSize);
#if !(MESHTASTIC_EXCLUDE_PKI)
// Attempt PKI decryption first
if (p->channel == 0 && isToUs(p) && p->to > 0 && p->to != NODENUM_BROADCAST && nodeDB->getMeshNode(p->from) != nullptr &&
if (p->channel == 0 && isToUs(p) && p->to > 0 && !isBroadcast(p->to) && nodeDB->getMeshNode(p->from) != nullptr &&
nodeDB->getMeshNode(p->from)->user.public_key.size > 0 && nodeDB->getMeshNode(p->to)->user.public_key.size > 0 &&
rawSize > MESHTASTIC_PKC_OVERHEAD) {
LOG_DEBUG("Attempting PKI decryption\n");
LOG_DEBUG("Attempting PKI decryption");
if (crypto->decryptCurve25519(p->from, nodeDB->getMeshNode(p->from)->user.public_key, p->id, rawSize, ScratchEncrypted,
bytes)) {
LOG_INFO("PKI Decryption worked!\n");
LOG_INFO("PKI Decryption worked!");
memset(&p->decoded, 0, sizeof(p->decoded));
rawSize -= MESHTASTIC_PKC_OVERHEAD;
if (pb_decode_from_bytes(bytes, rawSize, &meshtastic_Data_msg, &p->decoded) &&
p->decoded.portnum != meshtastic_PortNum_UNKNOWN_APP) {
decrypted = true;
LOG_INFO("Packet decrypted using PKI!\n");
LOG_INFO("Packet decrypted using PKI!");
p->pki_encrypted = true;
memcpy(&p->public_key.bytes, nodeDB->getMeshNode(p->from)->user.public_key.bytes, 32);
p->public_key.size = 32;
// memcpy(bytes, ScratchEncrypted, rawSize); // TODO: Rename the bytes buffers
// chIndex = 8;
} else {
LOG_ERROR("PKC Decrypted, but pb_decode failed!\n");
LOG_ERROR("PKC Decrypted, but pb_decode failed!");
return false;
}
} else {
LOG_WARN("PKC decrypt attempted but failed!\n");
LOG_WARN("PKC decrypt attempted but failed!");
}
}
#endif
@@ -371,9 +374,9 @@ bool perhapsDecode(meshtastic_MeshPacket *p)
// Take those raw bytes and convert them back into a well structured protobuf we can understand
memset(&p->decoded, 0, sizeof(p->decoded));
if (!pb_decode_from_bytes(bytes, rawSize, &meshtastic_Data_msg, &p->decoded)) {
LOG_ERROR("Invalid protobufs in received mesh packet id=0x%08x (bad psk?)!\n", p->id);
LOG_ERROR("Invalid protobufs in received mesh packet id=0x%08x (bad psk?)!", p->id);
} else if (p->decoded.portnum == meshtastic_PortNum_UNKNOWN_APP) {
LOG_ERROR("Invalid portnum (bad psk?)!\n");
LOG_ERROR("Invalid portnum (bad psk?)!");
} else {
decrypted = true;
break;
@@ -400,7 +403,7 @@ bool perhapsDecode(meshtastic_MeshPacket *p)
decompressed_len = unishox2_decompress_simple(compressed_in, p->decoded.payload.size, decompressed_out);
// LOG_DEBUG("\n\n**\n\nDecompressed length - %d \n", decompressed_len);
// LOG_DEBUG("**Decompressed length - %d ", decompressed_len);
memcpy(p->decoded.payload.bytes, decompressed_out, decompressed_len);
@@ -410,15 +413,15 @@ bool perhapsDecode(meshtastic_MeshPacket *p)
printPacket("decoded message", p);
#if ENABLE_JSON_LOGGING
LOG_TRACE("%s\n", MeshPacketSerializer::JsonSerialize(p, false).c_str());
LOG_TRACE("%s", MeshPacketSerializer::JsonSerialize(p, false).c_str());
#elif ARCH_PORTDUINO
if (settingsStrings[traceFilename] != "" || settingsMap[logoutputlevel] == level_trace) {
LOG_TRACE("%s\n", MeshPacketSerializer::JsonSerialize(p, false).c_str());
LOG_TRACE("%s", MeshPacketSerializer::JsonSerialize(p, false).c_str());
}
#endif
return true;
} else {
LOG_WARN("No suitable channel found for decoding, hash was 0x%x!\n", p->channel);
LOG_WARN("No suitable channel found for decoding, hash was 0x%x!", p->channel);
return false;
}
}
@@ -453,20 +456,20 @@ meshtastic_Routing_Error perhapsEncode(meshtastic_MeshPacket *p)
int compressed_len;
compressed_len = unishox2_compress_simple(original_payload, p->decoded.payload.size, compressed_out);
LOG_DEBUG("Original length - %d \n", p->decoded.payload.size);
LOG_DEBUG("Compressed length - %d \n", compressed_len);
LOG_DEBUG("Original message - %s \n", p->decoded.payload.bytes);
LOG_DEBUG("Original length - %d ", p->decoded.payload.size);
LOG_DEBUG("Compressed length - %d ", compressed_len);
LOG_DEBUG("Original message - %s ", p->decoded.payload.bytes);
// If the compressed length is greater than or equal to the original size, don't use the compressed form
if (compressed_len >= p->decoded.payload.size) {
LOG_DEBUG("Not using compressing message.\n");
LOG_DEBUG("Not using compressing message.");
// Set the uncompressed payload variant anyway. Shouldn't hurt?
// p->decoded.which_payloadVariant = Data_payload_tag;
// Otherwise we use the compressor
} else {
LOG_DEBUG("Using compressed message.\n");
LOG_DEBUG("Using compressed message.");
// Copy the compressed data into the meshpacket
p->decoded.payload.size = compressed_len;
@@ -493,18 +496,18 @@ meshtastic_Routing_Error perhapsEncode(meshtastic_MeshPacket *p)
// Don't use PKC if it's not explicitly requested and a non-primary channel is requested
!(p->pki_encrypted != true && p->channel > 0) &&
// Check for valid keys and single node destination
config.security.private_key.size == 32 && p->to != NODENUM_BROADCAST && node != nullptr &&
config.security.private_key.size == 32 && !isBroadcast(p->to) && node != nullptr &&
// Check for a known public key for the destination
(node->user.public_key.size == 32) &&
// Some portnums either make no sense to send with PKC
p->decoded.portnum != meshtastic_PortNum_TRACEROUTE_APP && p->decoded.portnum != meshtastic_PortNum_NODEINFO_APP &&
p->decoded.portnum != meshtastic_PortNum_ROUTING_APP && p->decoded.portnum != meshtastic_PortNum_POSITION_APP) {
LOG_DEBUG("Using PKI!\n");
LOG_DEBUG("Using PKI!");
if (numbytes + MESHTASTIC_HEADER_LENGTH + MESHTASTIC_PKC_OVERHEAD > MAX_LORA_PAYLOAD_LEN)
return meshtastic_Routing_Error_TOO_LARGE;
if (p->pki_encrypted && !memfll(p->public_key.bytes, 0, 32) &&
memcmp(p->public_key.bytes, node->user.public_key.bytes, 32) != 0) {
LOG_WARN("Client public key differs from requested: 0x%02x, stored key begins 0x%02x\n", *p->public_key.bytes,
LOG_WARN("Client public key differs from requested: 0x%02x, stored key begins 0x%02x", *p->public_key.bytes,
*node->user.public_key.bytes);
return meshtastic_Routing_Error_PKI_FAILED;
}
@@ -586,24 +589,25 @@ void Router::handleReceived(meshtastic_MeshPacket *p, RxSource src)
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag &&
p->decoded.portnum == meshtastic_PortNum_NEIGHBORINFO_APP &&
(!moduleConfig.has_neighbor_info || !moduleConfig.neighbor_info.enabled)) {
LOG_DEBUG("Neighbor info module is disabled, ignoring neighbor packet\n");
LOG_DEBUG("Neighbor info module is disabled, ignoring neighbor packet");
cancelSending(p->from, p->id);
skipHandle = true;
}
bool shouldIgnoreNonstandardPorts =
config.device.rebroadcast_mode == meshtastic_Config_DeviceConfig_RebroadcastMode_CORE_PORTNUMS_ONLY;
#if USERPREFS_EVENT_MODE
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag &&
(p->decoded.portnum == meshtastic_PortNum_ATAK_FORWARDER || p->decoded.portnum == meshtastic_PortNum_ATAK_PLUGIN ||
p->decoded.portnum == meshtastic_PortNum_PAXCOUNTER_APP || p->decoded.portnum == meshtastic_PortNum_IP_TUNNEL_APP ||
p->decoded.portnum == meshtastic_PortNum_AUDIO_APP || p->decoded.portnum == meshtastic_PortNum_PRIVATE_APP ||
p->decoded.portnum == meshtastic_PortNum_DETECTION_SENSOR_APP ||
p->decoded.portnum == meshtastic_PortNum_RANGE_TEST_APP ||
p->decoded.portnum == meshtastic_PortNum_REMOTE_HARDWARE_APP)) {
LOG_DEBUG("Ignoring packet on blacklisted portnum during event\n");
shouldIgnoreNonstandardPorts = true;
#endif
if (shouldIgnoreNonstandardPorts && p->which_payload_variant == meshtastic_MeshPacket_decoded_tag &&
IS_ONE_OF(p->decoded.portnum, meshtastic_PortNum_ATAK_FORWARDER, meshtastic_PortNum_ATAK_PLUGIN,
meshtastic_PortNum_PAXCOUNTER_APP, meshtastic_PortNum_IP_TUNNEL_APP, meshtastic_PortNum_AUDIO_APP,
meshtastic_PortNum_PRIVATE_APP, meshtastic_PortNum_DETECTION_SENSOR_APP, meshtastic_PortNum_RANGE_TEST_APP,
meshtastic_PortNum_REMOTE_HARDWARE_APP)) {
LOG_DEBUG("Ignoring packet on blacklisted portnum for CORE_PORTNUMS_ONLY");
cancelSending(p->from, p->id);
skipHandle = true;
}
#endif
} else {
printPacket("packet decoding failed or skipped (no PSK?)", p);
}
@@ -615,7 +619,7 @@ void Router::handleReceived(meshtastic_MeshPacket *p, RxSource src)
#if !MESHTASTIC_EXCLUDE_MQTT
// Mark as pki_encrypted if it is not yet decoded and MQTT encryption is also enabled, hash matches and it's a DM not to
// us (because we would be able to decrypt it)
if (!decoded && moduleConfig.mqtt.encryption_enabled && p->channel == 0x00 && p->to != NODENUM_BROADCAST && !isToUs(p))
if (!decoded && moduleConfig.mqtt.encryption_enabled && p->channel == 0x00 && !isBroadcast(p->to) && !isToUs(p))
p_encrypted->pki_encrypted = true;
// After potentially altering it, publish received message to MQTT if we're not the original transmitter of the packet
if ((decoded || p_encrypted->pki_encrypted) && moduleConfig.mqtt.enabled && !isFromUs(p) && mqtt)
@@ -631,35 +635,35 @@ void Router::perhapsHandleReceived(meshtastic_MeshPacket *p)
#if ENABLE_JSON_LOGGING
// Even ignored packets get logged in the trace
p->rx_time = getValidTime(RTCQualityFromNet); // store the arrival timestamp for the phone
LOG_TRACE("%s\n", MeshPacketSerializer::JsonSerializeEncrypted(p).c_str());
LOG_TRACE("%s", MeshPacketSerializer::JsonSerializeEncrypted(p).c_str());
#elif ARCH_PORTDUINO
// Even ignored packets get logged in the trace
if (settingsStrings[traceFilename] != "" || settingsMap[logoutputlevel] == level_trace) {
p->rx_time = getValidTime(RTCQualityFromNet); // store the arrival timestamp for the phone
LOG_TRACE("%s\n", MeshPacketSerializer::JsonSerializeEncrypted(p).c_str());
LOG_TRACE("%s", MeshPacketSerializer::JsonSerializeEncrypted(p).c_str());
}
#endif
// assert(radioConfig.has_preferences);
if (is_in_repeated(config.lora.ignore_incoming, p->from)) {
LOG_DEBUG("Ignoring msg, 0x%x is in our ignore list\n", p->from);
LOG_DEBUG("Ignoring msg, 0x%x is in our ignore list", p->from);
packetPool.release(p);
return;
}
if (p->from == NODENUM_BROADCAST) {
LOG_DEBUG("Ignoring msg from broadcast address\n");
LOG_DEBUG("Ignoring msg from broadcast address");
packetPool.release(p);
return;
}
if (config.lora.ignore_mqtt && p->via_mqtt) {
LOG_DEBUG("Msg came in via MQTT from 0x%x\n", p->from);
LOG_DEBUG("Msg came in via MQTT from 0x%x", p->from);
packetPool.release(p);
return;
}
if (shouldFilterReceived(p)) {
LOG_DEBUG("Incoming msg was filtered from 0x%x\n", p->from);
LOG_DEBUG("Incoming msg was filtered from 0x%x", p->from);
packetPool.release(p);
return;
}

View File

@@ -27,11 +27,11 @@ bool STM32WLE5JCInterface::init()
int res = lora.begin(getFreq(), bw, sf, cr, syncWord, power, preambleLength, tcxoVoltage);
LOG_INFO("STM32WLx init result %d\n", res);
LOG_INFO("STM32WLx init result %d", res);
LOG_INFO("Frequency set to %f\n", getFreq());
LOG_INFO("Bandwidth set to %f\n", bw);
LOG_INFO("Power output set to %d\n", power);
LOG_INFO("Frequency set to %f", getFreq());
LOG_INFO("Bandwidth set to %f", bw);
LOG_INFO("Power output set to %d", power);
if (res == RADIOLIB_ERR_NONE)
startReceive(); // start receiving

View File

@@ -20,7 +20,7 @@ SX126xInterface<T>::SX126xInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs
RADIOLIB_PIN_TYPE busy)
: RadioLibInterface(hal, cs, irq, rst, busy, &lora), lora(&module)
{
LOG_DEBUG("SX126xInterface(cs=%d, irq=%d, rst=%d, busy=%d)\n", cs, irq, rst, busy);
LOG_DEBUG("SX126xInterface(cs=%d, irq=%d, rst=%d, busy=%d)", cs, irq, rst, busy);
}
/// Initialise the Driver transport hardware and software.
@@ -68,9 +68,9 @@ template <typename T> bool SX126xInterface<T>::init()
// (DIO3 is not free to be used as an IRQ)
#endif
if (tcxoVoltage == 0)
LOG_DEBUG("SX126X_DIO3_TCXO_VOLTAGE not defined, not using DIO3 as TCXO reference voltage\n");
LOG_DEBUG("SX126X_DIO3_TCXO_VOLTAGE not defined, not using DIO3 as TCXO reference voltage");
else
LOG_DEBUG("SX126X_DIO3_TCXO_VOLTAGE defined, using DIO3 as TCXO reference voltage at %f V\n", tcxoVoltage);
LOG_DEBUG("SX126X_DIO3_TCXO_VOLTAGE defined, using DIO3 as TCXO reference voltage at %f V", tcxoVoltage);
// FIXME: May want to set depending on a definition, currently all SX126x variant files use the DC-DC regulator option
bool useRegulatorLDO = false; // Seems to depend on the connection to pin 9/DCC_SW - if an inductor DCDC?
@@ -84,13 +84,13 @@ template <typename T> bool SX126xInterface<T>::init()
int res = lora.begin(getFreq(), bw, sf, cr, syncWord, power, preambleLength, tcxoVoltage, useRegulatorLDO);
// \todo Display actual typename of the adapter, not just `SX126x`
LOG_INFO("SX126x init result %d\n", res);
LOG_INFO("SX126x init result %d", res);
if (res == RADIOLIB_ERR_CHIP_NOT_FOUND)
return false;
LOG_INFO("Frequency set to %f\n", getFreq());
LOG_INFO("Bandwidth set to %f\n", bw);
LOG_INFO("Power output set to %d\n", power);
LOG_INFO("Frequency set to %f", getFreq());
LOG_INFO("Bandwidth set to %f", bw);
LOG_INFO("Power output set to %d", power);
// Overriding current limit
// (https://github.com/jgromes/RadioLib/blob/690a050ebb46e6097c5d00c371e961c1caa3b52e/src/modules/SX126x/SX126x.cpp#L85) using
@@ -101,8 +101,8 @@ template <typename T> bool SX126xInterface<T>::init()
// FIXME: Not ideal to increase SX1261 current limit above 60mA as it can only transmit max 15dBm, should probably only do it
// if using SX1262 or SX1268
res = lora.setCurrentLimit(currentLimit);
LOG_DEBUG("Current limit set to %f\n", currentLimit);
LOG_DEBUG("Current limit set result %d\n", res);
LOG_DEBUG("Current limit set to %f", currentLimit);
LOG_DEBUG("Current limit set result %d", res);
if (res == RADIOLIB_ERR_NONE) {
#ifdef SX126X_DIO2_AS_RF_SWITCH
@@ -116,36 +116,36 @@ template <typename T> bool SX126xInterface<T>::init()
bool dio2AsRfSwitch = false;
#endif
res = lora.setDio2AsRfSwitch(dio2AsRfSwitch);
LOG_DEBUG("Set DIO2 as %sRF switch, result: %d\n", dio2AsRfSwitch ? "" : "not ", res);
LOG_DEBUG("Set DIO2 as %sRF switch, result: %d", dio2AsRfSwitch ? "" : "not ", res);
}
// If a pin isn't defined, we set it to RADIOLIB_NC, it is safe to always do external RF switching with RADIOLIB_NC as it has
// no effect
#if ARCH_PORTDUINO
if (res == RADIOLIB_ERR_NONE) {
LOG_DEBUG("Using MCU pin %i as RXEN and pin %i as TXEN to control RF switching\n", settingsMap[rxen], settingsMap[txen]);
LOG_DEBUG("Using MCU pin %i as RXEN and pin %i as TXEN to control RF switching", settingsMap[rxen], settingsMap[txen]);
lora.setRfSwitchPins(settingsMap[rxen], settingsMap[txen]);
}
#else
#ifndef SX126X_RXEN
#define SX126X_RXEN RADIOLIB_NC
LOG_DEBUG("SX126X_RXEN not defined, defaulting to RADIOLIB_NC\n");
LOG_DEBUG("SX126X_RXEN not defined, defaulting to RADIOLIB_NC");
#endif
#ifndef SX126X_TXEN
#define SX126X_TXEN RADIOLIB_NC
LOG_DEBUG("SX126X_TXEN not defined, defaulting to RADIOLIB_NC\n");
LOG_DEBUG("SX126X_TXEN not defined, defaulting to RADIOLIB_NC");
#endif
if (res == RADIOLIB_ERR_NONE) {
LOG_DEBUG("Using MCU pin %i as RXEN and pin %i as TXEN to control RF switching\n", SX126X_RXEN, SX126X_TXEN);
LOG_DEBUG("Using MCU pin %i as RXEN and pin %i as TXEN to control RF switching", SX126X_RXEN, SX126X_TXEN);
lora.setRfSwitchPins(SX126X_RXEN, SX126X_TXEN);
}
#endif
if (config.lora.sx126x_rx_boosted_gain) {
uint16_t result = lora.setRxBoostedGainMode(true);
LOG_INFO("Set RX gain to boosted mode; result: %d\n", result);
LOG_INFO("Set RX gain to boosted mode; result: %d", result);
} else {
uint16_t result = lora.setRxBoostedGainMode(false);
LOG_INFO("Set RX gain to power saving mode (boosted mode off); result: %d\n", result);
LOG_INFO("Set RX gain to power saving mode (boosted mode off); result: %d", result);
}
#if 0
@@ -203,17 +203,17 @@ template <typename T> bool SX126xInterface<T>::reconfigure()
err = lora.setSyncWord(syncWord);
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("SX126X setSyncWord %s%d\n", radioLibErr, err);
LOG_ERROR("SX126X setSyncWord %s%d", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
err = lora.setCurrentLimit(currentLimit);
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("SX126X setCurrentLimit %s%d\n", radioLibErr, err);
LOG_ERROR("SX126X setCurrentLimit %s%d", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
err = lora.setPreambleLength(preambleLength);
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("SX126X setPreambleLength %s%d\n", radioLibErr, err);
LOG_ERROR("SX126X setPreambleLength %s%d", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
err = lora.setFrequency(getFreq());
@@ -225,7 +225,7 @@ template <typename T> bool SX126xInterface<T>::reconfigure()
err = lora.setOutputPower(power);
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("SX126X setOutputPower %s%d\n", radioLibErr, err);
LOG_ERROR("SX126X setOutputPower %s%d", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
startReceive(); // restart receiving
@@ -245,7 +245,7 @@ template <typename T> void SX126xInterface<T>::setStandby()
int err = lora.standby();
if (err != RADIOLIB_ERR_NONE)
LOG_DEBUG("SX126x standby %s%d\n", radioLibErr, err);
LOG_DEBUG("SX126x standby %s%d", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
isReceiving = false; // If we were receiving, not any more
@@ -260,7 +260,7 @@ template <typename T> void SX126xInterface<T>::setStandby()
*/
template <typename T> void SX126xInterface<T>::addReceiveMetadata(meshtastic_MeshPacket *mp)
{
// LOG_DEBUG("PacketStatus %x\n", lora.getPacketStatus());
// LOG_DEBUG("PacketStatus %x", lora.getPacketStatus());
mp->rx_snr = lora.getSNR();
mp->rx_rssi = lround(lora.getRSSI());
}
@@ -287,7 +287,7 @@ template <typename T> void SX126xInterface<T>::startReceive()
// Furthermore, we need the PREAMBLE_DETECTED and HEADER_VALID IRQ flag to detect whether we are actively receiving
int err = lora.startReceiveDutyCycleAuto(preambleLength, 8, RADIOLIB_IRQ_RX_DEFAULT_FLAGS | RADIOLIB_IRQ_PREAMBLE_DETECTED);
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("SX126X startReceiveDutyCycleAuto %s%d\n", radioLibErr, err);
LOG_ERROR("SX126X startReceiveDutyCycleAuto %s%d", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
RadioLibInterface::startReceive();
@@ -308,7 +308,7 @@ template <typename T> bool SX126xInterface<T>::isChannelActive()
if (result == RADIOLIB_LORA_DETECTED)
return true;
if (result != RADIOLIB_CHANNEL_FREE)
LOG_ERROR("SX126X scanChannel %s%d\n", radioLibErr, result);
LOG_ERROR("SX126X scanChannel %s%d", radioLibErr, result);
assert(result != RADIOLIB_ERR_WRONG_MODEM);
return false;
@@ -326,8 +326,8 @@ template <typename T> bool SX126xInterface<T>::sleep()
{
// Not keeping config is busted - next time nrf52 board boots lora sending fails tcxo related? - see datasheet
// \todo Display actual typename of the adapter, not just `SX126x`
LOG_DEBUG("SX126x entering sleep mode\n"); // (FIXME, don't keep config)
setStandby(); // Stop any pending operations
LOG_DEBUG("SX126x entering sleep mode"); // (FIXME, don't keep config)
setStandby(); // Stop any pending operations
// turn off TCXO if it was powered
// FIXME - this isn't correct

View File

@@ -19,7 +19,7 @@ SX128xInterface<T>::SX128xInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs
RADIOLIB_PIN_TYPE busy)
: RadioLibInterface(hal, cs, irq, rst, busy, &lora), lora(&module)
{
LOG_DEBUG("SX128xInterface(cs=%d, irq=%d, rst=%d, busy=%d)\n", cs, irq, rst, busy);
LOG_DEBUG("SX128xInterface(cs=%d, irq=%d, rst=%d, busy=%d)", cs, irq, rst, busy);
}
/// Initialise the Driver transport hardware and software.
@@ -68,10 +68,10 @@ template <typename T> bool SX128xInterface<T>::init()
int res = lora.begin(getFreq(), bw, sf, cr, syncWord, power, preambleLength);
// \todo Display actual typename of the adapter, not just `SX128x`
LOG_INFO("SX128x init result %d\n", res);
LOG_INFO("SX128x init result %d", res);
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.\n");
LOG_WARN("Radio chip only supports 2.4GHz LoRa. Adjusting Region and rebooting.");
config.lora.region = meshtastic_Config_LoRaConfig_RegionCode_LORA_24;
nodeDB->saveToDisk(SEGMENT_CONFIG);
delay(2000);
@@ -80,13 +80,13 @@ template <typename T> bool SX128xInterface<T>::init()
#elif defined(ARCH_NRF52)
NVIC_SystemReset();
#else
LOG_ERROR("FIXME implement reboot for this platform. Skipping for now.\n");
LOG_ERROR("FIXME implement reboot for this platform. Skipping for now.");
#endif
}
LOG_INFO("Frequency set to %f\n", getFreq());
LOG_INFO("Bandwidth set to %f\n", bw);
LOG_INFO("Power output set to %d\n", power);
LOG_INFO("Frequency set to %f", getFreq());
LOG_INFO("Bandwidth set to %f", bw);
LOG_INFO("Power output set to %d", power);
#if defined(SX128X_TXEN) && (SX128X_TXEN != RADIOLIB_NC) && defined(SX128X_RXEN) && (SX128X_RXEN != RADIOLIB_NC)
if (res == RADIOLIB_ERR_NONE) {
@@ -129,12 +129,12 @@ template <typename T> bool SX128xInterface<T>::reconfigure()
err = lora.setSyncWord(syncWord);
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("SX128X setSyncWord %s%d\n", radioLibErr, err);
LOG_ERROR("SX128X setSyncWord %s%d", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
err = lora.setPreambleLength(preambleLength);
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("SX128X setPreambleLength %s%d\n", radioLibErr, err);
LOG_ERROR("SX128X setPreambleLength %s%d", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
err = lora.setFrequency(getFreq());
@@ -146,7 +146,7 @@ template <typename T> bool SX128xInterface<T>::reconfigure()
err = lora.setOutputPower(power);
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("SX128X setOutputPower %s%d\n", radioLibErr, err);
LOG_ERROR("SX128X setOutputPower %s%d", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
startReceive(); // restart receiving
@@ -171,7 +171,7 @@ template <typename T> void SX128xInterface<T>::setStandby()
int err = lora.standby();
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("SX128x standby %s%d\n", radioLibErr, err);
LOG_ERROR("SX128x standby %s%d", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
#if ARCH_PORTDUINO
if (settingsMap[rxen] != RADIOLIB_NC) {
@@ -200,7 +200,7 @@ template <typename T> void SX128xInterface<T>::setStandby()
*/
template <typename T> void SX128xInterface<T>::addReceiveMetadata(meshtastic_MeshPacket *mp)
{
// LOG_DEBUG("PacketStatus %x\n", lora.getPacketStatus());
// LOG_DEBUG("PacketStatus %x", lora.getPacketStatus());
mp->rx_snr = lora.getSNR();
mp->rx_rssi = lround(lora.getRSSI());
}
@@ -261,7 +261,7 @@ template <typename T> void SX128xInterface<T>::startReceive()
int err = lora.startReceive(RADIOLIB_SX128X_RX_TIMEOUT_INF, RADIOLIB_IRQ_RX_DEFAULT_FLAGS | RADIOLIB_IRQ_PREAMBLE_DETECTED);
if (err != RADIOLIB_ERR_NONE)
LOG_ERROR("SX128X startReceive %s%d\n", radioLibErr, err);
LOG_ERROR("SX128X startReceive %s%d", radioLibErr, err);
assert(err == RADIOLIB_ERR_NONE);
RadioLibInterface::startReceive();
@@ -282,7 +282,7 @@ template <typename T> bool SX128xInterface<T>::isChannelActive()
if (result == RADIOLIB_LORA_DETECTED)
return true;
if (result != RADIOLIB_CHANNEL_FREE)
LOG_ERROR("SX128X scanChannel %s%d\n", radioLibErr, result);
LOG_ERROR("SX128X scanChannel %s%d", radioLibErr, result);
assert(result != RADIOLIB_ERR_WRONG_MODEM);
return false;
@@ -298,8 +298,8 @@ template <typename T> bool SX128xInterface<T>::sleep()
{
// Not keeping config is busted - next time nrf52 board boots lora sending fails tcxo related? - see datasheet
// \todo Display actual typename of the adapter, not just `SX128x`
LOG_DEBUG("SX128x entering sleep mode\n"); // (FIXME, don't keep config)
setStandby(); // Stop any pending operations
LOG_DEBUG("SX128x entering sleep mode"); // (FIXME, don't keep config)
setStandby(); // Stop any pending operations
// turn off TCXO if it was powered
// FIXME - this isn't correct

View File

@@ -115,7 +115,7 @@ void StreamAPI::emitRebooted()
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_rebooted_tag;
fromRadioScratch.rebooted = true;
// LOG_DEBUG("Emitting reboot packet for serial shell\n");
// LOG_DEBUG("Emitting reboot packet for serial shell");
emitTxBuffer(pb_encode_to_bytes(txBuf + HEADER_LEN, meshtastic_FromRadio_size, &meshtastic_FromRadio_msg, &fromRadioScratch));
}

View File

@@ -5,7 +5,7 @@
template <typename T>
ServerAPI<T>::ServerAPI(T &_client) : StreamAPI(&client), concurrency::OSThread("ServerAPI"), client(_client)
{
LOG_INFO("Incoming API connection\n");
LOG_INFO("Incoming API connection");
}
template <typename T> ServerAPI<T>::~ServerAPI()
@@ -30,7 +30,7 @@ template <class T> int32_t ServerAPI<T>::runOnce()
if (client.connected()) {
return StreamAPI::runOncePart();
} else {
LOG_INFO("Client dropped connection, suspending API service\n");
LOG_INFO("Client dropped connection, suspending API service");
enabled = false; // we no longer need to run
return 0;
}
@@ -63,11 +63,11 @@ template <class T, class U> int32_t APIServerPort<T, U>::runOnce()
// Reconnections are delayed by full wait time
if (waitTime < 400) {
waitTime *= 2;
LOG_INFO("Previous TCP connection still open, trying again in %dms\n", waitTime);
LOG_INFO("Previous TCP connection still open, trying again in %dms", waitTime);
return waitTime;
}
#endif
LOG_INFO("Force closing previous TCP connection\n");
LOG_INFO("Force closing previous TCP connection");
delete openAPI;
}

View File

@@ -11,7 +11,7 @@ void initApiServer(int port)
// Start API server on port 4403
if (!apiPort) {
apiPort = new WiFiServerPort(port);
LOG_INFO("API server listening on TCP port %d\n", port);
LOG_INFO("API server listening on TCP port %d", port);
apiPort->init();
}
}
@@ -22,7 +22,7 @@ void deInitApiServer()
WiFiServerAPI::WiFiServerAPI(WiFiClient &_client) : ServerAPI(_client)
{
LOG_INFO("Incoming wifi connection\n");
LOG_INFO("Incoming wifi connection");
}
WiFiServerPort::WiFiServerPort(int port) : APIServerPort(port) {}

View File

@@ -12,14 +12,14 @@ void initApiServer(int port)
// Start API server on port 4403
if (!apiPort) {
apiPort = new ethServerPort(port);
LOG_INFO("API server listening on TCP port %d\n", port);
LOG_INFO("API server listening on TCP port %d", port);
apiPort->init();
}
}
ethServerAPI::ethServerAPI(EthernetClient &_client) : ServerAPI(_client)
{
LOG_INFO("Incoming ethernet connection\n");
LOG_INFO("Incoming ethernet connection");
}
ethServerPort::ethServerPort(int port) : APIServerPort(port) {}

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