Compare commits

...

141 Commits

Author SHA1 Message Date
Thomas Göttgens
282cc0b16a Merge pull request #2737 from meshtastic/BBQ10Kb-Fix
Bbq10 kb fix
2023-08-26 11:22:35 +02:00
Thomas Göttgens
4ab67f3668 IGOR! Fetch me the brain! 2023-08-25 16:44:39 +02:00
Thomas Göttgens
312028b161 Possble fix ESC 2023-08-25 09:27:09 +02:00
Ben Meadors
ecd48db69c Merge branch 'master' into BBQ10Kb-Fix 2023-08-24 19:57:49 -05:00
Ben Meadors
03dc36ea12 Use fixed position regardless of gps lock (#2744) 2023-08-24 10:55:49 -05:00
Mark Trevor Birss
c2ae38405e Update architecture.h (#2746) 2023-08-24 07:58:24 -05:00
Thomas Göttgens
2a1d8c40b4 add TAB and ESC handling 2023-08-24 14:24:26 +02:00
Ben Meadors
e2441c425a Merge branch 'master' into BBQ10Kb-Fix 2023-08-24 07:06:42 -05:00
Mark Trevor Birss
00ffe73ebd Heltec ESP32-C3 HT-CT62 support (#2741)
* Add files via upload

* Update platformio.ini

* Update variant.h

* Update platformio.ini

* Switch to our new HW_MODEL

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Ben Meadors <thebentern@tuta.io>
2023-08-23 07:59:21 -05:00
Thomas Göttgens
3355019de3 Merge branch 'master' into BBQ10Kb-Fix 2023-08-23 09:45:06 +02:00
Thomas Göttgens
5bb207d88b reset sym after second keypress
also remove debug print and non-working scancodes.
2023-08-23 09:44:20 +02:00
github-actions[bot]
5453e4d123 [create-pull-request] automated change (#2742)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-08-22 17:11:22 -05:00
Thomas Göttgens
7f1b58a222 trunk fmt 2023-08-22 21:23:37 +02:00
Thomas Göttgens
39357b2686 Merge branch 'BBQ10Kb-Fix' of github.com:meshtastic/firmware into BBQ10Kb-Fix 2023-08-22 21:23:00 +02:00
Thomas Göttgens
d6b629ae04 update SYM Scancode 2023-08-22 21:19:51 +02:00
Thomas Göttgens
7b1aeb60cd Try manual scancode for SYM 2023-08-22 21:19:51 +02:00
Thomas Göttgens
5c7c1cd253 silence compiler warnings 2023-08-22 21:19:51 +02:00
Thomas Göttgens
8cfe130df3 update SYM Scancode 2023-08-22 21:11:19 +02:00
Thomas Göttgens
feef86942d Merge pull request #2738 from meshtastic/neighbourinfo-fix
fix crash and Debug logging in NeighbourInfo
2023-08-22 16:27:52 +02:00
Thomas Göttgens
5f3a8b4924 fix crash and Debug logging in NeighbourInfo 2023-08-22 15:43:21 +02:00
Thomas Göttgens
0fcaaf39b0 Try manual scancode for SYM 2023-08-22 11:23:19 +02:00
Thomas Göttgens
a55eac5c20 silence compiler warnings 2023-08-22 10:58:54 +02:00
github-actions[bot]
b47c9c165a [create-pull-request] automated change (#2733)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-08-19 18:06:33 -05:00
Thomas Göttgens
ecceb10910 different debug print 2023-08-19 21:28:02 +02:00
Thomas Göttgens
6fc76103a0 temporarily Enable debug print 2023-08-19 20:55:50 +02:00
Ben Meadors
f35c7be917 Just putting back DELAYED_INTERVAL for reliability. Ran into problems 2023-08-19 09:45:48 -05:00
Ben Meadors
364364263b Remove range_test goalie from drawing frames 2023-08-19 09:44:40 -05:00
Manuel
ef957bfac5 support BB Q10 keyboard (#2703)
* support BB Q10 keyboard

* remove debug code

* fix wrong logic

* fix left/right keys for cardkb

* Try to enable Q10 kb after all

* cppcheck

* Only fire on Key release and assume 0x0a is a enter as well

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2023-08-19 08:37:42 -05:00
Ben Meadors
5d78795065 Portnum promiscuity for text messages from other modules (#2732)
* Add interested portnums to TextMessageModule

* Send Detection Sensor Module messages on its own portnum

* Add to Ext. Notification and consolidate logic

* RANGE_TEST_APP portnum for RangeTestModule
2023-08-19 07:46:34 -05:00
github-actions[bot]
2dbdda204f [create-pull-request] automated change (#2731)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-08-18 10:17:55 -05:00
Jonathan Bennett
4767bd5497 Rename utils.h to avoid collision with library. (#2730) 2023-08-17 20:22:34 -05:00
Thomas Göttgens
05efd68097 Merge pull request #2729 from meshtastic/trunk-fmt
update trunk to latest version
2023-08-17 13:46:44 +02:00
Thomas Göttgens
a90eef432f update trunk to latest version 2023-08-17 12:17:36 +02:00
Ben Meadors
929b8f6209 Fix thread to use getConfiguredOrDefaultMs (#2727)
* WIP

* Updates

* Move it out of the macro guard so portduino can build

* Changes from feedback

* Use minimum_broadcast_secs as interval if we just broadcasted to avoid wasting cpu cycles

* Fmt

* Merge conflict resolution boogered me up

* Missed a spot

* getConfiguredOrDefaultMs

* Get the minimum interval
2023-08-16 15:08:06 -05:00
Thomas Göttgens
5d76771fab Permanently Enable Canned Messages on T-Deck and Picomputer (#2728)
* - Permanently Enable Canned Messages on T-Deck and Picomputer
- picomputer has a really dark TFT; switch color to white for better UX.

* well, you know... bullock...
2023-08-16 15:07:22 -05:00
Thomas Göttgens
91eb64d7b7 Fix warning about init order (#2725) 2023-08-15 20:17:15 -05:00
Ben Meadors
03fe4c629a Dection Sensor module duty cycle interval optimization (#2723)
* WIP

* Updates

* Move it out of the macro guard so portduino can build

* Changes from feedback

* Use minimum_broadcast_secs as interval if we just broadcasted to avoid wasting cpu cycles

* Fmt

* Merge conflict resolution boogered me up

* Missed a spot
2023-08-15 12:23:07 -05:00
Ben Meadors
144dfe9805 Initial Detection sensor module feature (#2722)
* WIP

* Updates

* Doh!

* Move it out of the macro guard so portduino can build

* Changes from feedback
2023-08-14 19:00:51 -05:00
rcarteraz
18899fd168 Update variant.h (#2719)
remove HAS_GPS 0 so users can add gps

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-08-13 23:45:23 -05:00
code8buster
fcfd83bc89 Remove auto GPS shutoff for fixed position nodes (#2720) 2023-08-13 15:56:49 -05:00
github-actions[bot]
a3d2b6166c [create-pull-request] automated change (#2716)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-08-12 20:49:42 -05:00
Manuel
fb5f2e48a5 fix T-Deck trackball crashes (#2714)
* try-fix: nodenum crash during boot

* Revert "try-fix: nodenum crash during boot"

This reverts commit 632012e197.

* fix/workaround: trackball interrupt crashes

* trunk fmt

* add OSThread to trackballInterrupt
2023-08-12 19:44:05 -05:00
Jonathan Bennett
d29c975e3c Comment out extra-chatty debug message (#2715) 2023-08-12 13:51:31 -05:00
Jonathan Bennett
c44986127e More GPS work (#2711)
Increase GPS buffer on esp32
Check for and flush GPS buffer when overfilled and corrupted.

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-08-12 09:29:44 -05:00
Ben Meadors
6e0b6684ee Extend node max to 100 and remove mesh_sds_timeout_secs (#2713)
* Extend node max to 100 and remove mesh_sds_timeout_secs

* Const pointers for you and you and you

* Fixes and supressions

* Missed it

* uint

* Resize

* Derp
2023-08-12 09:29:19 -05:00
Manuel
84ddfea491 try-fix: max nodes crash during boot (#2712)
* try-fix: nodenum crash during boot

* Revert "try-fix: nodenum crash during boot"

This reverts commit 632012e197.

* try-fix: max nodes crash during boot

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-08-12 09:28:58 -05:00
Ben Meadors
3d6fb13f9a Stop failing on low severity styling issues 2023-08-12 06:43:13 -05:00
Manuel
54c48329c8 Merge pull request #2710 from meshtastic/fix-screen-setup
fix repeater crash during screen setup
2023-08-12 10:46:07 +02:00
mverch67
ede31a2080 fix repeater crash 2023-08-11 19:41:21 +02:00
Jonathan Bennett
9470d4694b Pickier parsing of NMEA to detect an L76K chip (#2699)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-08-10 11:21:35 -05:00
github-actions[bot]
2074c76780 [create-pull-request] automated change (#2697)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-08-10 05:53:55 -05:00
Thomas Göttgens
9f6584bd67 Merge pull request #2694 from mverch67/t-watch-fixes
T-Watch S3 fixes
2023-08-08 22:49:37 +02:00
mverch67
dd69de9f32 trunk fmt 2023-08-08 20:21:20 +02:00
mverch67
616553ed72 doing the math :) 2023-08-08 20:14:12 +02:00
mverch67
1986267d65 check payload size 2023-08-08 20:02:29 +02:00
mverch67
1d0ac2caf7 trunk fmt 2023-08-08 18:55:00 +02:00
mverch67
746d7268a2 fix picomputer 2023-08-08 18:51:11 +02:00
Manuel
9a7777dbdb Merge branch 'master' into t-watch-fixes 2023-08-08 18:21:57 +02:00
mverch67
0fe99b0caa T-Watch fixes 2023-08-08 18:06:39 +02:00
Ben Meadors
f9798b7dda Bump to 2.2 2023-08-08 08:05:43 -05:00
Ben Meadors
23fb377fd7 Don't cancel sending "seen" messages on MQTT enabled nodes (#2690) 2023-08-08 06:27:26 -05:00
Thomas Göttgens
4808a5c57f also update other boards with those (#2691) 2023-08-07 23:22:17 +00:00
Thomas Göttgens
d25c368985 Try enabling the secondary I2C bus on Heltec V3 (#2689)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-08-07 15:17:26 -05:00
GUVWAF
a5f3dea40b Clarify that when rebooting is not implemented some settings may not apply (#2688)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-08-07 15:16:56 -05:00
Thomas Göttgens
f026c3308c add picomputer 2023-08-07 21:34:01 +02:00
Thomas Göttgens
ed4e7a4cee Change Target Name 2023-08-07 21:33:42 +02:00
Thomas Göttgens
95f67d70ea Merge pull request #2493 from meshtastic/picomputer-s3
Add variant an plumbing for #2468
2023-08-07 21:17:24 +02:00
Thomas Göttgens
e3260c1d19 Merge branch 'master' into picomputer-s3 2023-08-07 20:27:44 +02:00
Thomas Göttgens
98f3be0665 Merge pull request #2647 from meshtastic/2.2-working-changes
2.2 Changes
2023-08-07 20:27:05 +02:00
Ben Meadors
dc31024764 Merge remote-tracking branch 'origin/master' into 2.2-working-changes 2023-08-07 13:24:10 -05:00
Ben Meadors
5bbcb40f7a Updated protos 2023-08-07 13:23:21 -05:00
Thomas Göttgens
8218a729e0 Merge branch 'picomputer-s3' of github.com:meshtastic/firmware into picomputer-s3 2023-08-07 19:58:48 +02:00
Thomas Göttgens
cbc3e605dd fix building for other platforms 2023-08-07 19:57:47 +02:00
Thomas Göttgens
94c41a4fed Merge branch 'master' into picomputer-s3 2023-08-07 19:47:29 +02:00
caveman99
1afe9f75bd [create-pull-request] automated change 2023-08-07 19:46:28 +02:00
Thomas Göttgens
402f8ba524 Let's see what this breaks... 2023-08-07 19:34:42 +02:00
Thomas Göttgens
0084c0881d Merge branch 'picomputer-s3' of github.com:meshtastic/firmware into picomputer-s3 2023-08-06 16:57:03 +02:00
Thomas Göttgens
8552cc44b9 Merge branch 'master' into picomputer-s3 2023-08-06 16:55:28 +02:00
Thomas Göttgens
b238aebe38 Merge branch 'picomputer-s3' of github.com:meshtastic/firmware into picomputer-s3 2023-08-03 09:37:32 +02:00
GUVWAF
e05c8e60d9 Save Neighbors to flash 2023-08-02 20:56:24 +02:00
Ben Meadors
f1bcc300d9 Merge branch 'master' into 2.2-working-changes 2023-08-02 12:58:32 -05:00
Ben Meadors
11be856507 Merge branch 'master' into 2.2-working-changes 2023-08-01 21:00:58 -05:00
Ben Meadors
c4474a7b99 Merge branch 'master' into picomputer-s3 2023-07-31 18:59:50 -05:00
Ben Meadors
0821cff1c8 Merge remote-tracking branch 'origin/master' into 2.2-working-changes 2023-07-31 18:54:53 -05:00
Ben Meadors
90ec8eae6c Backmerge master protos 2023-07-31 18:28:27 -05:00
Thomas Göttgens
ba172aae32 Merge branch 'picomputer-s3' of github.com:meshtastic/firmware into picomputer-s3 2023-07-31 22:28:04 +02:00
Thomas Göttgens
26338b8f2b Merge branch 'master' into picomputer-s3 2023-07-31 22:27:24 +02:00
GUVWAF
297708a50b Manually update protos 2023-07-30 17:27:43 +02:00
GUVWAF
a61a4fad3e Merge pull request #2667 from GUVWAF/removeNeighbors
Remove neighbors after twice their broadcast interval
2023-07-30 17:17:17 +02:00
GUVWAF
c66b68b0cc Remove neighbors after twice their broadcast interval 2023-07-30 16:54:39 +02:00
Ben Meadors
04cba45c60 Merge branch 'master' into 2.2-working-changes 2023-07-30 07:54:11 -05:00
Ben Meadors
5aedd84c7d Merge branch 'master' into 2.2-working-changes 2023-07-29 08:15:17 -05:00
Ben Meadors
38c9a1ea07 neighborInfo->node_broadcast_interval_secs 2023-07-28 10:36:44 -05:00
Ben Meadors
0eefd0912f Move node_broadcast_interval_secs 2023-07-28 10:28:14 -05:00
Ben Meadors
0cda8e6087 Start plumbing node_broadcast_interval_secs 2023-07-28 06:58:28 -05:00
Ben Meadors
2cf648928a Add node_broadcast_interval_secs to Neighbor 2023-07-28 06:43:21 -05:00
Andre K
3cd7d8d6af update min_app_version to 2.2.0 2023-07-28 06:22:16 -03:00
Ben Meadors
702a83b525 Bumb device state version 2023-07-27 16:03:57 -05:00
GUVWAF
32246850aa Convert protobuf values that are unsigned properly to uint in JSON (#2659) 2023-07-27 13:53:20 -05:00
Ben Meadors
74650ca276 Words are important 2023-07-27 13:23:18 -05:00
Ben Meadors
0141bbe772 Regen 2023-07-27 12:59:06 -05:00
Ben Meadors
049c587ca2 Add phoneapi plumbing. Need to regen protos on my other machine 2023-07-27 12:51:31 -05:00
Ben Meadors
1a28225cd5 Merge branch 'master' into 2.2-working-changes 2023-07-27 08:55:48 -05:00
Ben Meadors
4fd756acd8 Merge branch 'master' into 2.2-working-changes 2023-07-27 06:42:02 -05:00
Thomas Göttgens
ff11506922 Merge pull request #2649 from meshtastic/neighborinfo
add Neighborinfo
2023-07-26 13:07:01 +02:00
Ben Meadors
f35b422365 Trunk 2023-07-25 20:54:01 -05:00
Ben Meadors
08f1ac785a Gut NodeDb and remove deprecated protos 2023-07-25 19:13:19 -05:00
Ben Meadors
146ed067a1 Merge branch 'master' into neighborinfo 2023-07-25 16:14:50 -05:00
Ben Meadors
2e7c95a110 Merge branch 'master' into neighborinfo 2023-07-24 07:24:34 -05:00
Ben Meadors
3a24882e76 Merge branch 'master' into neighborinfo 2023-07-22 08:46:27 -05:00
Ben Meadors
41b07de5a2 Merge branch 'master' into neighborinfo 2023-07-17 09:21:08 -05:00
Thomas Göttgens
1745722dac Merge branch 'picomputer-s3' of github.com:meshtastic/firmware into picomputer-s3 2023-06-28 09:12:10 +02:00
Ben Meadors
849599cd8e Merge branch 'master' into picomputer-s3 2023-06-27 15:40:13 -05:00
Thomas Göttgens
bfc567ad89 Add variant an plumbing for #2468 2023-06-27 18:11:58 +02:00
Thomas Göttgens
b665786c77 Merge branch 'master' into neighborinfo 2023-06-27 18:00:20 +02:00
GUVWAF
e60a5f1cf2 Setter for NeighborInfo 2023-06-25 15:41:19 +02:00
GUVWAF
6bdf67c9be Conversion to NodeInfoLite 2023-06-25 15:41:06 +02:00
Ben Meadors
bbfd62c47e Merge branch 'master' into neighborinfo 2023-06-21 21:11:06 -05:00
Ben Meadors
a07e30544d Merge branch 'master' into neighborinfo 2023-06-19 06:16:42 -05:00
Ben Meadors
9716bd8bec Merge branch 'master' into neighborinfo 2023-06-13 05:44:48 -05:00
Ben Meadors
c2168dd450 Merge branch 'master' into neighborinfo 2023-06-09 19:51:22 -05:00
GUVWAF
66c71250b8 Update last_sent_by_id in FloodingRouter 2023-06-08 20:59:09 +02:00
Ben Meadors
5c438ae792 Merge branch 'master' into neighborinfo 2023-06-06 19:29:59 -05:00
GUVWAF
cdf44ce7fa Move module init out of repeater clause 2023-06-06 21:07:12 +02:00
GUVWAF
d70bd23260 Use float print specifier for SNR 2023-06-06 21:06:19 +02:00
Ben Meadors
b42ead4400 Merge branch 'master' into neighborinfo 2023-06-02 06:46:45 -05:00
Ben Meadors
b2704a0082 Merge branch 'master' into neighborinfo 2023-06-01 06:02:42 -05:00
Ben Meadors
9b94701699 Merge branch 'master' into neighborinfo 2023-05-31 20:08:50 -05:00
Thomas Göttgens
61661aed50 Broadcast neighbor info
also update trunk
2023-05-31 13:18:43 +02:00
Thomas Göttgens
3a25d6d3b3 Merge branch 'picomputer-s3' of github.com:meshtastic/firmware into picomputer-s3 2023-05-30 14:52:24 +02:00
Ben Meadors
fd4e9daa7f Merge branch 'master' into picomputer-s3 2023-05-30 07:36:53 -05:00
Thomas Göttgens
b6f7b7fa47 Merge branch 'picomputer-s3' of github.com:meshtastic/firmware into picomputer-s3 2023-05-30 13:07:29 +02:00
Thomas Göttgens
a92a960682 Merge branch 'master' into picomputer-s3 2023-05-30 09:55:33 +02:00
Thomas Göttgens
5d2ab65a81 Merge branch 'picomputer-s3' of github.com:meshtastic/firmware into picomputer-s3 2023-05-27 13:08:57 +02:00
Thomas Göttgens
f3b7f7251c Add variant an plumbing for #2468 2023-05-27 13:08:27 +02:00
Thomas Göttgens
2f60bbe5f2 Merge branch 'picomputer-s3' of github.com:meshtastic/firmware into picomputer-s3 2023-05-24 01:48:44 +02:00
Thomas Göttgens
0261754269 Add variant an plumbing for #2468 2023-05-24 01:48:01 +02:00
Thomas Göttgens
e6fc2af21f Merge branch 'picomputer-s3' of github.com:meshtastic/firmware into picomputer-s3 2023-05-17 20:28:49 +02:00
Ben Meadors
ae41944a89 Merge branch 'master' into picomputer-s3 2023-05-16 10:38:12 -05:00
Thomas Göttgens
62259583e6 Add variant an plumbing for #2468 2023-05-15 17:18:06 +02:00
Thomas Göttgens
c5d87fe581 Add variant an plumbing for #2468 2023-05-15 17:17:14 +02:00
90 changed files with 1846 additions and 472 deletions

View File

@@ -95,6 +95,7 @@ jobs:
- board: tlora-t3s3-v1
- board: t-watch-s3
- board: t-deck
- board: picomputer-s3
uses: ./.github/workflows/build_esp32_s3.yml
with:
board: ${{ matrix.board }}

2
.trunk/.gitignore vendored
View File

@@ -5,4 +5,4 @@
plugins
user_trunk.yaml
user.yaml
shims
tools

View File

@@ -1,37 +1,42 @@
version: 0.1
cli:
version: 1.9.1
version: 1.13.0
plugins:
sources:
- id: trunk
ref: v0.0.17
ref: v1.1.1
uri: https://github.com/trunk-io/plugins
lint:
enabled:
- taplo@0.7.0
- ruff@0.0.265
- yamllint@1.31.0
- bandit@1.7.5
- checkov@2.4.1
- terrascan@1.18.3
- trivy@0.44.1
- trufflehog@3.48.0
- taplo@0.8.1
- ruff@0.0.284
- yamllint@1.32.0
- isort@5.12.0
- markdownlint@0.34.0
- markdownlint@0.35.0
- oxipng@8.0.0
- svgo@3.0.2
- actionlint@1.6.24
- flake8@6.0.0
- actionlint@1.6.25
- flake8@6.1.0
- hadolint@2.12.0
- shfmt@3.5.0
- shfmt@3.6.0
- shellcheck@0.9.0
- black@23.3.0
- black@23.7.0
- git-diff-check
- gitleaks@8.16.3
- clang-format@14.0.0
- prettier@2.8.8
- gitleaks@8.17.0
- clang-format@16.0.3
- prettier@3.0.2
disabled:
- taplo@0.7.0
- taplo@0.8.1
- shellcheck@0.9.0
- shfmt@3.5.0
- shfmt@3.6.0
- oxipng@8.0.0
- actionlint@1.6.22
- markdownlint@0.34.0
- markdownlint@0.35.0
- hadolint@2.12.0
- svgo@3.0.2
runtimes:

View File

@@ -30,6 +30,7 @@ build_flags =
-DCONFIG_BT_NIMBLE_MAX_CCCDS=20
-DCONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=5120
-DESP_OPENSSL_SUPPRESS_LEGACY_WARNING
-DSERIAL_BUFFER_SIZE=4096
;-DDEBUG_HEAP
lib_deps =

View File

@@ -4,23 +4,23 @@
set -e
VERSION=`bin/buildinfo.py long`
VERSION=$(bin/buildinfo.py long)
# The shell vars the build tool expects to find
export APP_VERSION=$VERSION
if [[ $# -gt 0 ]]; then
# can override which environment by passing arg
BOARDS="$@"
# can override which environment by passing arg
BOARDS="$@"
else
BOARDS="tlora-v2 tlora-v1 tlora_v1_3 tlora-v2-1-1.6 tbeam heltec-v1 heltec-v2.0 heltec-v2.1 tbeam0.7 meshtastic-diy-v1 rak4631 rak4631_eink rak11200 t-echo pca10059_diy_eink"
BOARDS="tlora-v2 tlora-v1 tlora_v1_3 tlora-v2-1-1.6 tbeam heltec-v1 heltec-v2.0 heltec-v2.1 tbeam0.7 meshtastic-diy-v1 rak4631 rak4631_eink rak11200 t-echo pca10059_diy_eink"
fi
echo "BOARDS:${BOARDS}"
CHECK=""
for BOARD in $BOARDS; do
CHECK="${CHECK} -e ${BOARD}"
CHECK="${CHECK} -e ${BOARD}"
done
pio check --flags "-DAPP_VERSION=${APP_VERSION} --suppressions-list=suppressions.txt" $CHECK --skip-packages --pattern="src/" --fail-on-defect=low --fail-on-defect=medium --fail-on-defect=high
pio check --flags "-DAPP_VERSION=${APP_VERSION} --suppressions-list=suppressions.txt" $CHECK --skip-packages --pattern="src/" --fail-on-defect=medium --fail-on-defect=high

View File

@@ -28,8 +28,6 @@
"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
},

View File

@@ -15,7 +15,7 @@
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "dio",
"hwids": [["0X303A", "0x1001"]],
"hwids": [["0x303A", "0x1001"]],
"mcu": "esp32s3",
"variant": "t-watch-s3"
},

View File

@@ -16,8 +16,8 @@
#include "buzz/buzz.h"
#include "configuration.h"
#include "main.h"
#include "meshUtils.h"
#include "sleep.h"
#include "utils.h"
#ifdef DEBUG_HEAP_MQTT
#include "mqtt/MQTT.h"
@@ -221,10 +221,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
/**
* return true if there is a battery installed in this unit
*/
virtual bool isBatteryConnect() override
{
return getBatteryPercent() != -1;
}
virtual bool isBatteryConnect() override { return getBatteryPercent() != -1; }
/// If we see a battery voltage higher than physics allows - assume charger is pumping
/// in power
@@ -245,10 +242,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
/// Assume charging if we have a battery and external power is connected.
/// we can't be smart enough to say 'full'?
virtual bool isCharging() override
{
return isBatteryConnect() && isVbusIn();
}
virtual bool isCharging() override { return isBatteryConnect() && isVbusIn(); }
private:
/// If we see a battery voltage higher than physics allows - assume charger is pumping

View File

@@ -177,7 +177,7 @@ static void serialExit()
static void powerEnter()
{
LOG_DEBUG("Enter state: POWER\n");
// LOG_DEBUG("Enter state: POWER\n");
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");
@@ -297,7 +297,8 @@ void PowerFSM_setup()
powerFSM.add_transition(&stateLS, &stateON, EVENT_INPUT, NULL, "Input Device");
powerFSM.add_transition(&stateNB, &stateON, EVENT_INPUT, NULL, "Input Device");
powerFSM.add_transition(&stateDARK, &stateON, EVENT_INPUT, NULL, "Input Device");
powerFSM.add_transition(&stateON, &stateON, EVENT_INPUT, NULL, "Input Device"); // restarts the sleep timer
powerFSM.add_transition(&stateON, &stateON, EVENT_INPUT, NULL, "Input Device"); // restarts the sleep timer
powerFSM.add_transition(&statePOWER, &statePOWER, EVENT_INPUT, NULL, "Input Device"); // restarts the sleep timer
powerFSM.add_transition(&stateDARK, &stateON, EVENT_BLUETOOTH_PAIR, NULL, "Bluetooth pairing");
powerFSM.add_transition(&stateON, &stateON, EVENT_BLUETOOTH_PAIR, NULL, "Bluetooth pairing");

View File

@@ -21,7 +21,7 @@ class PowerFSMThread : public OSThread
/// If we are in power state we force the CPU to wake every 10ms to check for serial characters (we don't yet wake
/// cpu for serial rx - FIXME)
auto state = powerFSM.getState();
const auto state = powerFSM.getState();
canSleep = (state != &statePOWER) && (state != &stateSERIAL);
if (powerStatus->getHasUSB()) {

View File

@@ -101,6 +101,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// I2C Keyboards (M5Stack, RAK14004, T-Deck)
#define CARDKB_ADDR 0x5F
#define TDECK_KB_ADDR 0x55
#define BBQ10_KB_ADDR 0x1F
// -----------------------------------------------------------------------------
// SENSOR
@@ -147,6 +148,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define GPS_THREAD_INTERVAL 100
#endif
// convert 24-bit color to 16-bit (56K)
#define COLOR565(r, g, b) (((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3))
/* Step #1: offer chance for variant-specific defines */
#include "variant.h"

View File

@@ -30,8 +30,8 @@ ScanI2C::FoundDevice ScanI2C::firstRTC() const
ScanI2C::FoundDevice ScanI2C::firstKeyboard() const
{
ScanI2C::DeviceType types[] = {CARDKB, TDECKKB, RAK14004};
return firstOfOrNONE(3, types);
ScanI2C::DeviceType types[] = {CARDKB, TDECKKB, BBQ10KB, RAK14004};
return firstOfOrNONE(4, types);
}
ScanI2C::FoundDevice ScanI2C::firstAccelerometer() const

View File

@@ -17,6 +17,7 @@ class ScanI2C
RTC_PCF8563,
CARDKB,
TDECKKB,
BBQ10KB,
RAK14004,
PMU_AXP192_AXP2101,
BME_680,

View File

@@ -213,6 +213,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port)
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");
#ifdef HAS_NCP5623
SCAN_SIMPLE_CASE(NCP5623_ADDR, NCP5623, "NCP5623 RGB LED found\n");

View File

@@ -174,7 +174,7 @@ bool GPS::setupGPS()
#ifdef ARCH_ESP32
// In esp32 framework, setRxBufferSize needs to be initialized before Serial
_serial_gps->setRxBufferSize(2048); // the default is 256
_serial_gps->setRxBufferSize(SERIAL_BUFFER_SIZE); // the default is 256
#endif
// if the overrides are not dialled in, set them from the board definitions, if they exist
@@ -805,15 +805,6 @@ int32_t GPS::runOnce()
// If state has changed do a publish
publishUpdate();
if (!(fixeddelayCtr >= 20) && config.position.fixed_position && hasValidLocation) {
fixeddelayCtr++;
// LOG_DEBUG("Our delay counter is %d\n", fixeddelayCtr);
if (fixeddelayCtr >= 20) {
doGPSpowersave(false);
forceWake(false);
}
}
// 9600bps is approx 1 byte per msec, so considering our buffer size we never need to wake more often than 200ms
// if not awake we can run super infrquently (once every 5 secs?) to see if we need to wake.
return isAwake ? GPS_THREAD_INTERVAL : 5000;
@@ -834,6 +825,14 @@ void GPS::forceWake(bool on)
}
}
// clear the GPS rx buffer as quickly as possible
void GPS::clearBuffer()
{
int x = _serial_gps->available();
while (x--)
_serial_gps->read();
}
/// Prepare the GPS for the cpu entering deep or light sleep, expect to be gone for at least 100s of msecs
int GPS::prepareSleep(void *unused)
{
@@ -884,7 +883,7 @@ GnssModel_t GPS::probe()
int index = ver.indexOf("$");
if (index != -1) {
ver = ver.substring(index);
if (ver.startsWith("$GPTXT,01,01,02")) {
if (ver.startsWith("$GPTXT,01,01,02,SW=")) {
LOG_INFO("L76K GNSS init succeeded, using L76K GNSS Module\n");
return GNSS_MODEL_MTK;
}

View File

@@ -91,6 +91,9 @@ class GPS : private concurrency::OSThread
// Some GPS modules (ublock) require factory reset
virtual bool factoryReset() { return true; }
// Empty the input buffer as quickly as possible
void clearBuffer();
protected:
/// Do gps chipset specific init, return true for success
virtual bool setupGPS();

View File

@@ -253,6 +253,12 @@ bool NMEAGPS::hasFlow()
bool NMEAGPS::whileIdle()
{
bool isValid = 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());
clearBuffer();
}
#endif
// if (_serial_gps->available() > 0)
// LOG_DEBUG("GPS Bytes Waiting: %u\n", _serial_gps->available());
// First consume any chars that have piled up at the receiver
@@ -263,4 +269,4 @@ bool NMEAGPS::whileIdle()
}
return isValid;
}
}

View File

@@ -36,11 +36,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "mesh-pb-constants.h"
#include "mesh/Channels.h"
#include "mesh/generated/meshtastic/deviceonly.pb.h"
#include "meshUtils.h"
#include "modules/ExternalNotificationModule.h"
#include "modules/TextMessageModule.h"
#include "sleep.h"
#include "target_specific.h"
#include "utils.h"
#ifdef ARCH_ESP32
#include "esp_task_wdt.h"
@@ -365,7 +365,7 @@ static void drawCriticalFaultFrame(OLEDDisplay *display, OLEDDisplayUiState *sta
// Ignore messages originating from phone (from the current node 0x0) unless range test or store and forward module are enabled
static bool shouldDrawMessage(const meshtastic_MeshPacket *packet)
{
return packet->from != 0 && !moduleConfig.range_test.enabled && !moduleConfig.store_forward.enabled;
return packet->from != 0 && !moduleConfig.store_forward.enabled;
}
/// Draw the last text message we received
@@ -374,7 +374,7 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state
// the max length of this buffer is much longer than we can possibly print
static char tempBuf[237];
meshtastic_MeshPacket &mp = devicestate.rx_text_message;
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,
// mp.decoded.variant.data.decoded.bytes);
@@ -490,7 +490,7 @@ static void drawBattery(OLEDDisplay *display, int16_t x, int16_t y, uint8_t *img
}
// Draw nodes status
static void drawNodes(OLEDDisplay *display, int16_t x, int16_t y, NodeStatus *nodeStatus)
static void drawNodes(OLEDDisplay *display, int16_t x, int16_t y, const NodeStatus *nodeStatus)
{
char usersString[20];
snprintf(usersString, sizeof(usersString), "%d/%d", nodeStatus->getNumOnline(), nodeStatus->getNumTotal());
@@ -858,14 +858,14 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
bool hasNodeHeading = false;
if (ourNode && hasValidPosition(ourNode)) {
meshtastic_PositionLite &op = ourNode->position;
const meshtastic_PositionLite &op = ourNode->position;
float myHeading = estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i));
drawCompassNorth(display, compassX, compassY, myHeading);
if (hasValidPosition(node)) {
// display direction toward node
hasNodeHeading = true;
meshtastic_PositionLite &p = node->position;
const meshtastic_PositionLite &p = node->position;
float d =
GeoCoord::latLongToMeter(DegD(p.latitude_i), DegD(p.longitude_i), DegD(op.latitude_i), DegD(op.longitude_i));
@@ -1058,7 +1058,8 @@ void Screen::setup()
nodeStatusObserver.observe(&nodeStatus->onNewStatus);
if (textMessageModule)
textMessageObserver.observe(textMessageModule);
inputObserver.observe(inputBroker);
if (inputBroker)
inputObserver.observe(inputBroker);
// Modules can notify screen about refresh
MeshModule::observeUIEvents(&uiFrameEventObserver);
@@ -1900,7 +1901,7 @@ int Screen::handleUIFrameEvent(const UIFrameEvent *event)
int Screen::handleInputEvent(const InputEvent *event)
{
if (showingNormalScreen && moduleFrames.size() == 0) {
LOG_DEBUG("Screen::handleInputEvent from %s\n", event->source);
// LOG_DEBUG("Screen::handleInputEvent from %s\n", event->source);
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) {
showPrevFrame();
} else if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT)) {

View File

@@ -4,9 +4,9 @@
#define TFT_BACKLIGHT_ON HIGH
#endif
// convert 24-bit color to 16-bit (56K)
#define COLOR565(r, g, b) (((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3))
#ifndef TFT_MESH
#define TFT_MESH COLOR565(0x67, 0xEA, 0x94)
#endif
#if defined(ST7735S)
#include <LovyanGFX.hpp> // Graphics and font library for ST7735 driver chip
@@ -108,10 +108,12 @@ class LGFX : public lgfx::LGFX_Device
lgfx::Panel_ST7789 _panel_instance;
lgfx::Bus_SPI _bus_instance;
lgfx::Light_PWM _light_instance;
#if HAS_TOUCHSCREEN
#ifdef T_WATCH_S3
lgfx::Touch_FT5x06 _touch_instance;
#else
lgfx::Touch_GT911 _touch_instance;
#endif
#endif
public:
@@ -126,13 +128,14 @@ class LGFX : public lgfx::LGFX_Device
cfg.freq_write = SPI_FREQUENCY; // SPI clock for transmission (up to 80MHz, rounded to the value obtained by dividing
// 80MHz by an integer)
cfg.freq_read = SPI_READ_FREQUENCY; // SPI clock when receiving
cfg.spi_3wire = false; // Set to true if reception is done on the MOSI pin
cfg.use_lock = true; // Set to true to use transaction locking
cfg.dma_channel = SPI_DMA_CH_AUTO; // SPI_DMA_CH_AUTO; // Set DMA channel to use (0=not use DMA / 1=1ch / 2=ch /
cfg.pin_sclk = ST7789_SCK; // Set SPI SCLK pin number
cfg.pin_mosi = ST7789_SDA; // Set SPI MOSI pin number
cfg.pin_miso = ST7789_MISO; // Set SPI MISO pin number (-1 = disable)
cfg.pin_dc = ST7789_RS; // Set SPI DC pin number (-1 = disable)
cfg.spi_3wire = false;
cfg.use_lock = true; // Set to true to use transaction locking
cfg.dma_channel = SPI_DMA_CH_AUTO; // SPI_DMA_CH_AUTO; // Set DMA channel to use (0=not use DMA / 1=1ch / 2=ch /
// SPI_DMA_CH_AUTO=auto setting)
cfg.pin_sclk = ST7789_SCK; // Set SPI SCLK pin number
cfg.pin_mosi = ST7789_SDA; // Set SPI MOSI pin number
cfg.pin_miso = ST7789_MISO; // Set SPI MISO pin number (-1 = disable)
cfg.pin_dc = ST7789_RS; // Set SPI DC pin number (-1 = disable)
_bus_instance.config(cfg); // applies the set value to the bus.
_panel_instance.setBus(&_bus_instance); // set the bus on the panel.
@@ -148,16 +151,16 @@ class LGFX : public lgfx::LGFX_Device
// The following setting values are general initial values for each panel, so please comment out any
// unknown items and try them.
cfg.panel_width = TFT_WIDTH; // actual displayable width
cfg.panel_height = TFT_HEIGHT; // actual displayable height
cfg.offset_x = TFT_OFFSET_X; // Panel offset amount in X direction
cfg.offset_y = TFT_OFFSET_Y; // Panel offset amount in Y direction
cfg.offset_rotation = 0; // Rotation direction value offset 0~7 (4~7 is mirrored)
cfg.dummy_read_pixel = 9; // Number of bits for dummy read before pixel readout
cfg.dummy_read_bits = 1; // Number of bits for dummy read before non-pixel data read
cfg.readable = true; // Set to true if data can be read
cfg.invert = true; // Set to true if the light/darkness of the panel is reversed
cfg.rgb_order = false; // Set to true if the panel's red and blue are swapped
cfg.panel_width = TFT_WIDTH; // actual displayable width
cfg.panel_height = TFT_HEIGHT; // actual displayable height
cfg.offset_x = TFT_OFFSET_X; // Panel offset amount in X direction
cfg.offset_y = TFT_OFFSET_Y; // Panel offset amount in Y direction
cfg.offset_rotation = TFT_OFFSET_ROTATION; // Rotation direction value offset 0~7 (4~7 is mirrored)
cfg.dummy_read_pixel = 9; // Number of bits for dummy read before pixel readout
cfg.dummy_read_bits = 1; // Number of bits for dummy read before non-pixel data read
cfg.readable = true; // Set to true if data can be read
cfg.invert = true; // Set to true if the light/darkness of the panel is reversed
cfg.rgb_order = false; // Set to true if the panel's red and blue are swapped
cfg.dlen_16bit =
false; // Set to true for panels that transmit data length in 16-bit units with 16-bit parallel or SPI
cfg.bus_shared = true; // If the bus is shared with the SD card, set to true (bus control with drawJpgFile etc.)
@@ -181,6 +184,7 @@ class LGFX : public lgfx::LGFX_Device
_panel_instance.setLight(&_light_instance); // Set the backlight on the panel.
}
#if HAS_TOUCHSCREEN
// Configure settings for touch screen control.
{
auto cfg = _touch_instance.config();
@@ -192,7 +196,7 @@ class LGFX : public lgfx::LGFX_Device
cfg.y_max = TFT_WIDTH - 1;
cfg.pin_int = SCREEN_TOUCH_INT;
cfg.bus_shared = true;
cfg.offset_rotation = 0;
cfg.offset_rotation = TFT_OFFSET_ROTATION;
// cfg.freq = 2500000;
// I2C
@@ -210,6 +214,7 @@ class LGFX : public lgfx::LGFX_Device
_touch_instance.config(cfg);
_panel_instance.setTouch(&_touch_instance);
}
#endif
setPanel(&_panel_instance); // Sets the panel to use.
}
@@ -389,6 +394,14 @@ void TFTDisplay::sendCommand(uint8_t com)
// Drop all other commands to device (we just update the buffer)
}
void TFTDisplay::flipScreenVertically()
{
#if defined(T_WATCH_S3)
LOG_DEBUG("Flip TFT vertically\n"); // T-Watch S3 right-handed orientation
tft.setRotation(0);
#endif
}
bool TFTDisplay::hasTouch(void)
{
#ifndef M5STACK
@@ -424,10 +437,12 @@ bool TFTDisplay::connect()
#endif
tft.init();
#if defined(T_DECK)
tft.setRotation(1); // M5Stack/T-Deck have the TFT in landscape
#elif defined(M5STACK) || defined(T_WATCH_S3)
tft.setRotation(0); // T-Watch S3 has the TFT in portrait
#if defined(M5STACK)
tft.setRotation(0);
#elif defined(T_DECK) || defined(PICOMPUTER_S3)
tft.setRotation(1); // T-Deck has the TFT in landscape
#elif defined(T_WATCH_S3)
tft.setRotation(2); // T-Watch S3 left-handed orientation
#else
tft.setRotation(3); // Orient horizontal and wide underneath the silkscreen name label
#endif

View File

@@ -22,6 +22,9 @@ class TFTDisplay : public OLEDDisplay
// Write the buffer to the display memory
virtual void display(void) override;
// Turn the display upside down
virtual void flipScreenVertically();
// Touch screen (static handlers)
static bool hasTouch(void);
static bool getTouch(int16_t *x, int16_t *y);

181
src/input/BBQ10Keyboard.cpp Normal file
View File

@@ -0,0 +1,181 @@
// Based on arturo182 arduino_bbq10kbd library https://github.com/arturo182/arduino_bbq10kbd
#include <Arduino.h>
#include "BBQ10Keyboard.h"
#define _REG_VER 1
#define _REG_CFG 2
#define _REG_INT 3
#define _REG_KEY 4
#define _REG_BKL 5
#define _REG_DEB 6
#define _REG_FRQ 7
#define _REG_RST 8
#define _REG_FIF 9
#define _WRITE_MASK (1 << 7)
#define CFG_OVERFLOW_ON (1 << 0)
#define CFG_OVERFLOW_INT (1 << 1)
#define CFG_CAPSLOCK_INT (1 << 2)
#define CFG_NUMLOCK_INT (1 << 3)
#define CFG_KEY_INT (1 << 4)
#define CFG_PANIC_INT (1 << 5)
#define CFG_REPORT_MODS (1 << 6)
#define CFG_USE_MODS (1 << 7)
#define INT_OVERFLOW (1 << 0)
#define INT_CAPSLOCK (1 << 1)
#define INT_NUMLOCK (1 << 2)
#define INT_KEY (1 << 3)
#define INT_PANIC (1 << 4)
#define KEY_CAPSLOCK (1 << 5)
#define KEY_NUMLOCK (1 << 6)
#define KEY_COUNT_MASK (0x1F)
BBQ10Keyboard::BBQ10Keyboard() : m_wire(nullptr), m_addr(0), readCallback(nullptr), writeCallback(nullptr) {}
void BBQ10Keyboard::begin(uint8_t addr, TwoWire *wire)
{
m_addr = addr;
m_wire = wire;
m_wire->begin();
reset();
}
void BBQ10Keyboard::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 BBQ10Keyboard::reset()
{
if (m_wire) {
m_wire->beginTransmission(m_addr);
m_wire->write(_REG_RST);
m_wire->endTransmission();
}
if (writeCallback) {
uint8_t data = 0;
writeCallback(m_addr, _REG_RST, &data, 0);
}
delay(100);
writeRegister(_REG_CFG, readRegister8(_REG_CFG) | CFG_REPORT_MODS);
delay(100);
}
void BBQ10Keyboard::attachInterrupt(uint8_t pin, void (*func)(void)) const
{
pinMode(pin, INPUT_PULLUP);
::attachInterrupt(digitalPinToInterrupt(pin), func, RISING);
}
void BBQ10Keyboard::detachInterrupt(uint8_t pin) const
{
::detachInterrupt(pin);
}
void BBQ10Keyboard::clearInterruptStatus()
{
writeRegister(_REG_INT, 0x00);
}
uint8_t BBQ10Keyboard::status() const
{
return readRegister8(_REG_KEY);
}
uint8_t BBQ10Keyboard::keyCount() const
{
return status() & KEY_COUNT_MASK;
}
BBQ10Keyboard::KeyEvent BBQ10Keyboard::keyEvent() const
{
KeyEvent event = {.key = '\0', .state = StateIdle};
if (keyCount() == 0)
return event;
const uint16_t buf = readRegister16(_REG_FIF);
event.key = buf >> 8;
event.state = KeyState(buf & 0xFF);
return event;
}
float BBQ10Keyboard::backlight() const
{
return readRegister8(_REG_BKL) / 255.0f;
}
void BBQ10Keyboard::setBacklight(float value)
{
writeRegister(_REG_BKL, value * 255);
}
uint8_t BBQ10Keyboard::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 BBQ10Keyboard::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 BBQ10Keyboard::writeRegister(uint8_t reg, uint8_t value)
{
uint8_t data[2];
data[0] = reg | _WRITE_MASK;
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);
}
}

51
src/input/BBQ10Keyboard.h Normal file
View File

@@ -0,0 +1,51 @@
// Based on arturo182 arduino_bbq10kbd library https://github.com/arturo182/arduino_bbq10kbd
#include "configuration.h"
#include <Wire.h>
#define KEY_MOD_ALT (0x1A)
#define KEY_MOD_SHL (0x1B)
#define KEY_MOD_SHR (0x1C)
#define KEY_MOD_SYM (0x1D)
class BBQ10Keyboard
{
public:
typedef uint8_t (*i2c_com_fptr_t)(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint8_t len);
enum KeyState { StateIdle = 0, StatePress, StateLongPress, StateRelease };
struct KeyEvent {
char key;
KeyState state;
};
BBQ10Keyboard();
void begin(uint8_t addr = BBQ10_KB_ADDR, TwoWire *wire = &Wire);
void begin(i2c_com_fptr_t r, i2c_com_fptr_t w, uint8_t addr = BBQ10_KB_ADDR);
void reset(void);
void attachInterrupt(uint8_t pin, void (*func)(void)) const;
void detachInterrupt(uint8_t pin) const;
void clearInterruptStatus(void);
uint8_t status(void) const;
uint8_t keyCount(void) const;
KeyEvent keyEvent(void) const;
float backlight() const;
void setBacklight(float value);
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

@@ -40,13 +40,13 @@ int32_t TouchScreenBase::runOnce()
int16_t x, y;
bool touched = getTouch(x, y);
if (touched) {
hapticFeedback();
this->setInterval(20);
_last_x = x;
_last_y = y;
}
if (touched != _touchedOld) {
if (touched) {
hapticFeedback();
_state = TOUCH_EVENT_OCCURRED;
_start = millis();
_first_x = x;

View File

@@ -1,5 +1,6 @@
#include "TouchScreenImpl1.h"
#include "InputBroker.h"
#include "PowerFSM.h"
#include "configuration.h"
TouchScreenImpl1 *touchScreenImpl1;
@@ -61,6 +62,10 @@ void TouchScreenImpl1::onEvent(const TouchEvent &event)
e.inputEvent = static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL);
break;
}
case TOUCH_ACTION_TAP: {
powerFSM.trigger(EVENT_INPUT);
break;
}
default:
return;
}

View File

@@ -1,10 +1,7 @@
#include "TrackballInterruptBase.h"
#include "configuration.h"
TrackballInterruptBase::TrackballInterruptBase(const char *name)
{
this->_originName = name;
}
TrackballInterruptBase::TrackballInterruptBase(const char *name) : concurrency::OSThread(name), _originName(name) {}
void TrackballInterruptBase::init(uint8_t pinDown, uint8_t pinUp, uint8_t pinLeft, uint8_t pinRight, uint8_t pinPress,
char eventDown, char eventUp, char eventLeft, char eventRight, char eventPressed,
@@ -35,44 +32,64 @@ void TrackballInterruptBase::init(uint8_t pinDown, uint8_t pinUp, uint8_t pinLef
LOG_DEBUG("Trackball GPIO initialized (%d, %d, %d, %d, %d)\n", this->_pinUp, this->_pinDown, this->_pinLeft, this->_pinRight,
pinPress);
this->setInterval(100);
}
int32_t TrackballInterruptBase::runOnce()
{
InputEvent e;
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
if (this->action == TB_ACTION_PRESSED) {
// LOG_DEBUG("Trackball event Press\n");
e.inputEvent = this->_eventPressed;
} else if (this->action == TB_ACTION_UP) {
// LOG_DEBUG("Trackball event UP\n");
e.inputEvent = this->_eventUp;
} else if (this->action == TB_ACTION_DOWN) {
// LOG_DEBUG("Trackball event DOWN\n");
e.inputEvent = this->_eventDown;
} else if (this->action == TB_ACTION_LEFT) {
// LOG_DEBUG("Trackball event LEFT\n");
e.inputEvent = this->_eventLeft;
} else if (this->action == TB_ACTION_RIGHT) {
// LOG_DEBUG("Trackball event RIGHT\n");
e.inputEvent = this->_eventRight;
}
if (e.inputEvent != meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE) {
e.source = this->_originName;
e.kbchar = 0x00;
this->notifyObservers(&e);
}
this->action = TB_ACTION_NONE;
return 100;
}
void TrackballInterruptBase::intPressHandler()
{
InputEvent e;
e.source = this->_originName;
e.inputEvent = this->_eventPressed;
this->notifyObservers(&e);
this->action = TB_ACTION_PRESSED;
}
void TrackballInterruptBase::intDownHandler()
{
InputEvent e;
e.source = this->_originName;
e.inputEvent = this->_eventDown;
this->notifyObservers(&e);
this->action = TB_ACTION_DOWN;
}
void TrackballInterruptBase::intUpHandler()
{
InputEvent e;
e.source = this->_originName;
e.inputEvent = this->_eventUp;
this->notifyObservers(&e);
this->action = TB_ACTION_UP;
}
void TrackballInterruptBase::intLeftHandler()
{
InputEvent e;
e.source = this->_originName;
e.inputEvent = this->_eventLeft;
this->notifyObservers(&e);
this->action = TB_ACTION_LEFT;
}
void TrackballInterruptBase::intRightHandler()
{
InputEvent e;
e.source = this->_originName;
e.inputEvent = this->_eventRight;
this->notifyObservers(&e);
this->action = TB_ACTION_RIGHT;
}

View File

@@ -3,7 +3,7 @@
#include "InputBroker.h"
#include "mesh/NodeDB.h"
class TrackballInterruptBase : public Observable<const InputEvent *>
class TrackballInterruptBase : public Observable<const InputEvent *>, public concurrency::OSThread
{
public:
explicit TrackballInterruptBase(const char *name);
@@ -16,6 +16,20 @@ class TrackballInterruptBase : public Observable<const InputEvent *>
void intLeftHandler();
void intRightHandler();
virtual int32_t runOnce() override;
protected:
enum TrackballInterruptBaseActionType {
TB_ACTION_NONE,
TB_ACTION_PRESSED,
TB_ACTION_UP,
TB_ACTION_DOWN,
TB_ACTION_LEFT,
TB_ACTION_RIGHT
};
volatile TrackballInterruptBaseActionType action = TB_ACTION_NONE;
private:
uint8_t _pinDown = 0;
uint8_t _pinUp = 0;

View File

@@ -7,7 +7,7 @@ CardKbI2cImpl::CardKbI2cImpl() : KbI2cBase("cardKB") {}
void CardKbI2cImpl::init()
{
if (cardkb_found.address != CARDKB_ADDR && cardkb_found.address != TDECK_KB_ADDR) {
if (cardkb_found.address == 0x00) {
disable();
return;
}

View File

@@ -28,20 +28,9 @@ uint8_t read_from_14004(TwoWire *i2cBus, uint8_t reg, uint8_t *data, uint8_t len
return readflag;
}
// Unused for now - flagging it off
#if 0
void write_to_14004(const TwoWire * i2cBus, uint8_t reg, uint8_t data)
{
i2cBus->beginTransmission(CARDKB_ADDR);
i2cBus->write(reg);
i2cBus->write(data);
i2cBus->endTransmission(); // stop transmitting
}
#endif
int32_t KbI2cBase::runOnce()
{
if (cardkb_found.address != CARDKB_ADDR && cardkb_found.address != TDECK_KB_ADDR) {
if (cardkb_found.address == 0x00) {
// Input device is not detected.
return INT32_MAX;
}
@@ -52,11 +41,19 @@ int32_t KbI2cBase::runOnce()
#ifdef I2C_SDA1
LOG_DEBUG("Using I2C Bus 1 (the second one)\n");
i2cBus = &Wire1;
if (cardkb_found.address == BBQ10_KB_ADDR) {
Q10keyboard.begin(BBQ10_KB_ADDR, &Wire1);
Q10keyboard.setBacklight(0);
}
break;
#endif
case ScanI2C::WIRE:
LOG_DEBUG("Using I2C Bus 0 (the first one)\n");
i2cBus = &Wire;
if (cardkb_found.address == BBQ10_KB_ADDR) {
Q10keyboard.begin(BBQ10_KB_ADDR, &Wire);
Q10keyboard.setBacklight(0);
}
break;
case ScanI2C::NO_I2C:
default:
@@ -64,7 +61,105 @@ int32_t KbI2cBase::runOnce()
}
}
if (kb_model == 0x02) {
switch (kb_model) {
case 0x11: { // BB Q10
int keyCount = Q10keyboard.keyCount();
while (keyCount--) {
const BBQ10Keyboard::KeyEvent key = Q10keyboard.keyEvent();
if ((key.key != 0x00) && (key.state == BBQ10Keyboard::StateRelease)) {
InputEvent e;
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
e.source = this->_originName;
switch (key.key) {
case 'p': // TAB
case 't': // TAB as well
if (is_sym) {
e.inputEvent = ANYKEY;
e.kbchar = 0x09; // TAB Scancode
is_sym = false; // reset sym state after second keypress
} else {
e.inputEvent = ANYKEY;
e.kbchar = key.key;
}
break;
case 'q': // ESC
if (is_sym) {
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL;
e.kbchar = 0x1b;
is_sym = false; // reset sym state after second keypress
} else {
e.inputEvent = ANYKEY;
e.kbchar = key.key;
}
break;
case 0x08: // Back
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_BACK;
e.kbchar = key.key;
break;
case 'e': // sym e
if (is_sym) {
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP;
e.kbchar = 0xb5;
is_sym = false; // reset sym state after second keypress
} else {
e.inputEvent = ANYKEY;
e.kbchar = key.key;
}
break;
case 'x': // sym x
if (is_sym) {
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN;
e.kbchar = 0xb6;
is_sym = false; // reset sym state after second keypress
} else {
e.inputEvent = ANYKEY;
e.kbchar = key.key;
}
break;
case 's': // sym s
if (is_sym) {
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT;
e.kbchar = 0x00; // tweak for destSelect
is_sym = false; // reset sym state after second keypress
} else {
e.inputEvent = ANYKEY;
e.kbchar = key.key;
}
break;
case 'f': // sym f
if (is_sym) {
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT;
e.kbchar = 0x00; // tweak for destSelect
is_sym = false; // reset sym state after second keypress
} else {
e.inputEvent = ANYKEY;
e.kbchar = key.key;
}
break;
case 0x13: // Code scanner says the SYM key is 0x13
is_sym = !is_sym;
break;
case 0x0a: // apparently Enter on Q10 is a line feed instead of carriage return
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT;
break;
case 0x00: // nopress
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
break;
default: // all other keys
e.inputEvent = ANYKEY;
e.kbchar = key.key;
is_sym = false; // reset sym state after second keypress
break;
}
if (e.inputEvent != meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE) {
this->notifyObservers(&e);
}
}
}
break;
}
case 0x02: {
// RAK14004
uint8_t rDataBuf[8] = {0};
uint8_t PrintDataBuf = 0;
@@ -85,9 +180,12 @@ int32_t KbI2cBase::runOnce()
e.kbchar = PrintDataBuf;
this->notifyObservers(&e);
}
} else if (kb_model == 0x00 || kb_model == 0x10) {
// m5 cardkb and T-Deck
i2cBus->requestFrom(kb_model == 0x00 ? CARDKB_ADDR : TDECK_KB_ADDR, 1);
break;
}
case 0x00: // CARDKB
case 0x10: { // T-DECK
i2cBus->requestFrom((int)cardkb_found.address, 1);
while (i2cBus->available()) {
char c = i2cBus->read();
@@ -104,17 +202,19 @@ int32_t KbI2cBase::runOnce()
break;
case 0xb5: // Up
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP;
e.kbchar = 0xb5;
break;
case 0xb6: // Down
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN;
e.kbchar = 0xb6;
break;
case 0xb4: // Left
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT;
e.kbchar = c;
e.kbchar = 0xb4;
break;
case 0xb7: // Right
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT;
e.kbchar = c;
e.kbchar = 0xb7;
break;
case 0x0d: // Enter
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT;
@@ -132,7 +232,9 @@ int32_t KbI2cBase::runOnce()
this->notifyObservers(&e);
}
}
} else {
break;
}
default:
LOG_WARN("Unknown kb_model 0x%02x\n", kb_model);
}
return 300;

View File

@@ -1,5 +1,6 @@
#pragma once
#include "BBQ10Keyboard.h"
#include "InputBroker.h"
#include "Wire.h"
#include "concurrency/OSThread.h"
@@ -16,4 +17,7 @@ class KbI2cBase : public Observable<const InputEvent *>, public concurrency::OST
const char *_originName;
TwoWire *i2cBus = 0;
BBQ10Keyboard Q10keyboard;
bool is_sym = false;
};

131
src/input/kbMatrixBase.cpp Normal file
View File

@@ -0,0 +1,131 @@
#include "kbMatrixBase.h"
#include "configuration.h"
#ifdef INPUTBROKER_MATRIX_TYPE
const byte keys_cols[] = KEYS_COLS;
const byte keys_rows[] = KEYS_ROWS;
#if INPUTBROKER_MATRIX_TYPE == 1
unsigned char KeyMap[3][sizeof(keys_rows)][sizeof(keys_cols)] = {{{' ', '.', 'm', 'n', 'b', 0xb6},
{0x0d, 'l', 'k', 'j', 'h', 0xb4},
{'p', 'o', 'i', 'u', 'y', 0xb5},
{0x08, 'z', 'x', 'c', 'v', 0xb7},
{'a', 's', 'd', 'f', 'g', 0x09},
{'q', 'w', 'e', 'r', 't', 0x1a}},
{// SHIFT
{':', ';', 'M', 'N', 'B', 0xb6},
{0x0d, 'L', 'K', 'J', 'H', 0xb4},
{'P', 'O', 'I', 'U', 'Y', 0xb5},
{0x08, 'Z', 'X', 'C', 'V', 0xb7},
{'A', 'S', 'D', 'F', 'G', 0x09},
{'Q', 'W', 'E', 'R', 'T', 0x1a}},
{// SHIFT-SHIFT
{'_', ',', '>', '<', '"', '{'},
{'~', '-', '*', '&', '+', '['},
{'0', '9', '8', '7', '6', '}'},
{'=', '(', ')', '?', '/', ']'},
{'!', '@', '#', '$', '%', '\\'},
{'1', '2', '3', '4', '5', 0x1a}}};
#endif
KbMatrixBase::KbMatrixBase(const char *name) : concurrency::OSThread(name)
{
this->_originName = name;
}
int32_t KbMatrixBase::runOnce()
{
if (!INPUTBROKER_MATRIX_TYPE) {
// Input device is not requested.
return disable();
}
if (firstTime) {
// This is the first time the OSThread library has called this function, so do port setup
firstTime = 0;
for (byte i = 0; i < sizeof(keys_rows); i++) {
pinMode(keys_rows[i], OUTPUT);
digitalWrite(keys_rows[i], HIGH);
}
for (byte i = 0; i < sizeof(keys_cols); i++) {
pinMode(keys_cols[i], INPUT_PULLUP);
}
}
key = 0;
if (INPUTBROKER_MATRIX_TYPE == 1) {
// scan for keypresses
for (byte i = 0; i < sizeof(keys_rows); i++) {
digitalWrite(keys_rows[i], LOW);
for (byte j = 0; j < sizeof(keys_cols); j++) {
if (digitalRead(keys_cols[j]) == LOW) {
key = KeyMap[shift][i][j];
}
}
digitalWrite(keys_rows[i], HIGH);
}
// debounce
if (key != prevkey) {
if (key != 0) {
LOG_DEBUG("Key 0x%x pressed\n", key);
// reset shift now that we have a keypress
InputEvent e;
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
e.source = this->_originName;
switch (key) {
case 0x1b: // ESC
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL;
break;
case 0x08: // Back
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_BACK;
e.kbchar = key;
break;
case 0xb5: // Up
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP;
break;
case 0xb6: // Down
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN;
break;
case 0xb4: // Left
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT;
e.kbchar = key;
break;
case 0xb7: // Right
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT;
e.kbchar = key;
break;
case 0x0d: // Enter
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT;
break;
case 0x00: // nopress
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
break;
case 0x1a: // Shift
shift++;
if (shift > 2) {
shift = 0;
}
break;
default: // all other keys
e.inputEvent = ANYKEY;
e.kbchar = key;
break;
}
if (e.inputEvent != meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE) {
this->notifyObservers(&e);
}
}
prevkey = key;
}
} else {
LOG_WARN("Unknown kb_model 0x%02x\n", INPUTBROKER_MATRIX_TYPE);
return disable();
}
return 50; // Keyscan every 50msec to avoid key bounce
}
#endif // INPUTBROKER_MATRIX_TYPE

20
src/input/kbMatrixBase.h Normal file
View File

@@ -0,0 +1,20 @@
#pragma once
#include "InputBroker.h"
#include "concurrency/OSThread.h"
class KbMatrixBase : public Observable<const InputEvent *>, public concurrency::OSThread
{
public:
explicit KbMatrixBase(const char *name);
protected:
virtual int32_t runOnce() override;
private:
const char *_originName;
bool firstTime = 1;
int shift = 0;
char key = 0;
char prevkey = 0;
};

View File

@@ -0,0 +1,20 @@
#include "kbMatrixImpl.h"
#include "InputBroker.h"
#ifdef INPUTBROKER_MATRIX_TYPE
KbMatrixImpl *kbMatrixImpl;
KbMatrixImpl::KbMatrixImpl() : KbMatrixBase("matrixKB") {}
void KbMatrixImpl::init()
{
if (!INPUTBROKER_MATRIX_TYPE) {
disable();
return;
}
inputBroker->registerSource(this);
}
#endif // INPUTBROKER_MATRIX_TYPE

19
src/input/kbMatrixImpl.h Normal file
View File

@@ -0,0 +1,19 @@
#pragma once
#include "kbMatrixBase.h"
#include "main.h"
/**
* @brief The idea behind this class to have static methods for the event handlers.
* Check attachInterrupt() at RotaryEncoderInteruptBase.cpp
* Technically you can have as many rotary encoders hardver attached
* to your device as you wish, but you always need to have separate event
* handlers, thus you need to have a RotaryEncoderInterrupt implementation.
*/
class KbMatrixImpl : public KbMatrixBase
{
public:
KbMatrixImpl();
void init();
};
extern KbMatrixImpl *kbMatrixImpl;

View File

@@ -387,6 +387,10 @@ void setup()
// assign an arbitrary value to distinguish from other models
kb_model = 0x10;
break;
case ScanI2C::DeviceType::BBQ10KB:
// assign an arbitrary value to distinguish from other models
kb_model = 0x11;
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);
@@ -480,7 +484,7 @@ void setup()
#endif
// We do this as early as possible because this loads preferences from flash
// but we need to do this after main cpu iniot (esp32setup), because we need the random seed set
// but we need to do this after main cpu init (esp32setup), because we need the random seed set
nodeDB.init();
// If we're taking on the repeater role, use flood router
@@ -545,6 +549,7 @@ void setup()
#else
// ESP32
SPI.begin(RF95_SCK, RF95_MISO, RF95_MOSI, RF95_NSS);
LOG_WARN("SPI.begin(SCK=%d, MISO=%d, MOSI=%d, NSS=%d)\n", RF95_SCK, RF95_MISO, RF95_MOSI, RF95_NSS);
SPI.setFrequency(4000000);
#endif

View File

@@ -21,7 +21,7 @@ bool FloodingRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
{
if (wasSeenRecently(p)) { // Note: this will also add a recent packet record
printPacket("Ignoring incoming msg, because we've already seen it", p);
if (config.device.role != meshtastic_Config_DeviceConfig_Role_ROUTER &&
if (!moduleConfig.mqtt.enabled && config.device.role != meshtastic_Config_DeviceConfig_Role_ROUTER &&
config.device.role != meshtastic_Config_DeviceConfig_Role_ROUTER_CLIENT &&
config.device.role != meshtastic_Config_DeviceConfig_Role_REPEATER) {
// cancel rebroadcast of this message *if* there was already one, unless we're a router/repeater!
@@ -49,10 +49,13 @@ void FloodingRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtas
tosend->hop_limit--; // bump down the hop count
// If it is a traceRoute request, update the route that it went via me
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag && traceRouteModule &&
traceRouteModule->wantPacket(p)) {
traceRouteModule->updateRoute(tosend);
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
// If it is a traceRoute request, update the route that it went via me
if (traceRouteModule && traceRouteModule->wantPacket(p))
traceRouteModule->updateRoute(tosend);
// If it is a neighborInfo packet, update last_sent_by_id
if (neighborInfoModule && neighborInfoModule->wantPacket(p))
neighborInfoModule->updateLastSentById(tosend);
}
LOG_INFO("Rebroadcasting received floodmsg to neighbors\n");

View File

@@ -2,6 +2,7 @@
#include "PacketHistory.h"
#include "Router.h"
#include "modules/NeighborInfoModule.h"
#include "modules/TraceRouteModule.h"
/**
@@ -57,4 +58,4 @@ class FloodingRouter : public Router, protected PacketHistory
* Look for broadcasts we need to rebroadcast
*/
virtual void sniffReceived(const meshtastic_MeshPacket *p, const meshtastic_Routing *c) override;
};
};

View File

@@ -320,22 +320,22 @@ meshtastic_NodeInfoLite *MeshService::refreshLocalMeshNode()
int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
{
// Update our local node info with our position (even if we don't decide to update anyone else)
meshtastic_NodeInfoLite *node = refreshLocalMeshNode();
const meshtastic_NodeInfoLite *node = refreshLocalMeshNode();
meshtastic_Position pos = meshtastic_Position_init_default;
if (newStatus->getHasLock()) {
// load data from GPS object, will add timestamp + battery further down
pos = gps->p;
} else {
// The GPS has lost lock, if we are fixed position we should just keep using
// the old position
// The GPS has lost lock
#ifdef GPS_EXTRAVERBOSE
LOG_DEBUG("onGPSchanged() - lost validLocation\n");
#endif
if (config.position.fixed_position) {
LOG_WARN("Using fixed position\n");
pos = ConvertToPosition(node->position);
}
}
// Used fixed position if configured regalrdless of GPS lock
if (config.position.fixed_position) {
LOG_WARN("Using fixed position\n");
pos = ConvertToPosition(node->position);
}
// Finally add a fresh timestamp and battery level reading

View File

@@ -48,6 +48,14 @@ class MeshService
uint32_t oldFromNum = 0;
public:
static bool isTextPayload(const meshtastic_MeshPacket *p)
{
if (moduleConfig.range_test.enabled && p->decoded.portnum == meshtastic_PortNum_RANGE_TEST_APP) {
return true;
}
return p->decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP ||
p->decoded.portnum == meshtastic_PortNum_DETECTION_SENSOR_APP;
}
/// Called when some new packets have arrived from one of the radios
Observable<uint32_t> fromNumChanged;

View File

@@ -15,6 +15,7 @@
#include "error.h"
#include "main.h"
#include "mesh-pb-constants.h"
#include "modules/NeighborInfoModule.h"
#include <ErriezCRC32.h>
#include <pb_decode.h>
#include <pb_encode.h>
@@ -63,11 +64,7 @@ uint32_t error_address = 0;
static uint8_t ourMacAddr[6];
NodeDB::NodeDB()
: nodes(devicestate.node_db), numNodes(&devicestate.node_db_count), meshNodes(devicestate.node_db_lite),
numMeshNodes(&devicestate.node_db_lite_count)
{
}
NodeDB::NodeDB() : meshNodes(devicestate.node_db_lite), numMeshNodes(&devicestate.node_db_lite_count) {}
/**
* Most (but not always) of the time we want to treat packets 'from' the local phone (where from == 0), as if they originated on
@@ -248,6 +245,14 @@ void NodeDB::installDefaultModuleConfig()
strncpy(moduleConfig.mqtt.username, default_mqtt_username, sizeof(moduleConfig.mqtt.username));
strncpy(moduleConfig.mqtt.password, default_mqtt_password, sizeof(moduleConfig.mqtt.password));
moduleConfig.has_neighbor_info = true;
moduleConfig.neighbor_info.enabled = false;
moduleConfig.has_detection_sensor = true;
moduleConfig.detection_sensor.enabled = false;
moduleConfig.detection_sensor.detection_triggered_high = true;
moduleConfig.detection_sensor.minimum_broadcast_secs = 45;
initModuleConfigIntervals();
}
@@ -271,6 +276,7 @@ void NodeDB::initModuleConfigIntervals()
moduleConfig.telemetry.device_update_interval = default_broadcast_interval_secs;
moduleConfig.telemetry.environment_update_interval = default_broadcast_interval_secs;
moduleConfig.telemetry.air_quality_interval = default_broadcast_interval_secs;
moduleConfig.neighbor_info.update_interval = default_broadcast_interval_secs;
}
void NodeDB::installDefaultChannels()
@@ -282,12 +288,11 @@ void NodeDB::installDefaultChannels()
void NodeDB::resetNodes()
{
devicestate.node_db_count = 0;
memset(devicestate.node_db, 0, sizeof(devicestate.node_db));
devicestate.node_db_lite_count = 0;
memset(devicestate.node_db_lite, 0, sizeof(devicestate.node_db_lite));
saveDeviceStateToDisk();
if (neighborInfoModule && moduleConfig.neighbor_info.enabled)
neighborInfoModule->resetNeighbors();
}
void NodeDB::installDefaultDeviceState()
@@ -295,12 +300,11 @@ void NodeDB::installDefaultDeviceState()
LOG_INFO("Installing default DeviceState\n");
memset(&devicestate, 0, sizeof(meshtastic_DeviceState));
*numNodes = 0;
*numMeshNodes = 0;
// init our devicestate with valid flags so protobuf writing/reading will work
devicestate.has_my_node = true;
devicestate.has_owner = true;
devicestate.node_db_count = 0;
devicestate.node_db_lite_count = 0;
devicestate.version = DEVICESTATE_CUR_VER;
devicestate.receive_queue_count = 0; // Not yet implemented FIXME
@@ -328,11 +332,9 @@ void NodeDB::init()
int saveWhat = 0;
// likewise - we always want the app requirements to come from the running appload
myNodeInfo.min_app_version = 20300; // format is Mmmss (where M is 1+the numeric major number. i.e. 20120 means 1.1.20
myNodeInfo.max_channels = MAX_NUM_CHANNELS; // tell others the max # of channels we can understand
myNodeInfo.min_app_version = 30200; // format is Mmmss (where M is 1+the numeric major number. i.e. 30200 means 2.2.00
// Note! We do this after loading saved settings, so that if somehow an invalid nodenum was stored in preferences we won't
// keep using that nodenum forever. Crummy guess at our nodenum (but we will check against the nodedb to avoid conflicts)
strncpy(myNodeInfo.firmware_version, optstr(APP_VERSION), sizeof(myNodeInfo.firmware_version));
pickNewNodeNum();
// Set our board type so we can share it with others
@@ -343,19 +345,6 @@ void NodeDB::init()
info->user = owner;
info->has_user = true;
if (*numNodes > 0) {
LOG_DEBUG("Legacy NodeDB detected... Migrating to NodeDBLite\n");
uint32_t readIndex = 0;
const meshtastic_NodeInfo *oldNodeInfo = nodeDB.readNextNodeInfo(readIndex);
while (oldNodeInfo != NULL) {
migrateToNodeInfoLite(oldNodeInfo);
oldNodeInfo = nodeDB.readNextNodeInfo(readIndex);
}
LOG_DEBUG("Migration complete! Clearing out legacy NodeDB...\n");
devicestate.node_db_count = 0;
memset(devicestate.node_db, 0, sizeof(devicestate.node_db));
}
#ifdef ARCH_ESP32
Preferences preferences;
preferences.begin("meshtastic", false);
@@ -365,7 +354,7 @@ void NodeDB::init()
#endif
resetRadioConfig(); // If bogus settings got saved, then fix them
LOG_DEBUG("region=%d, NODENUM=0x%x, dbsize=%d\n", config.lora.region, myNodeInfo.my_node_num, *numNodes);
LOG_DEBUG("region=%d, NODENUM=0x%x, dbsize=%d\n", config.lora.region, myNodeInfo.my_node_num, *numMeshNodes);
if (devicestateCRC != crc32Buffer(&devicestate, sizeof(devicestate)))
saveWhat |= SEGMENT_DEVICESTATE;
@@ -611,14 +600,6 @@ void NodeDB::saveToDisk(int saveWhat)
}
}
const meshtastic_NodeInfo *NodeDB::readNextNodeInfo(uint32_t &readIndex)
{
if (readIndex < *numNodes)
return &nodes[readIndex++];
else
return NULL;
}
const meshtastic_NodeInfoLite *NodeDB::readNextMeshNode(uint32_t &readIndex)
{
if (readIndex < *numMeshNodes)
@@ -789,24 +770,13 @@ void NodeDB::updateFrom(const meshtastic_MeshPacket &mp)
uint8_t NodeDB::getMeshNodeChannel(NodeNum n)
{
meshtastic_NodeInfoLite *info = getMeshNode(n);
const meshtastic_NodeInfoLite *info = getMeshNode(n);
if (!info) {
return 0; // defaults to PRIMARY
}
return info->channel;
}
/// Find a node in our DB, return null for missing
/// NOTE: This function might be called from an ISR
meshtastic_NodeInfo *NodeDB::getNodeInfo(NodeNum n)
{
for (int i = 0; i < *numNodes; i++)
if (nodes[i].num == n)
return &nodes[i];
return NULL;
}
/// Find a node in our DB, return null for missing
/// NOTE: This function might be called from an ISR
meshtastic_NodeInfoLite *NodeDB::getMeshNode(NodeNum n)
@@ -825,7 +795,8 @@ meshtastic_NodeInfoLite *NodeDB::getOrCreateMeshNode(NodeNum n)
if (!lite) {
if ((*numMeshNodes >= MAX_NUM_NODES) || (memGet.getFreeHeap() < meshtastic_NodeInfoLite_size * 3)) {
screen->print("warning: node_db_lite full! erasing oldest entry\n");
if (screen)
screen->print("warning: node_db_lite full! erasing oldest entry\n");
// look for oldest node and erase it
uint32_t oldest = UINT32_MAX;
int oldestIndex = -1;
@@ -852,57 +823,6 @@ meshtastic_NodeInfoLite *NodeDB::getOrCreateMeshNode(NodeNum n)
return lite;
}
void NodeDB::migrateToNodeInfoLite(const meshtastic_NodeInfo *node)
{
meshtastic_NodeInfoLite *lite = getMeshNode(node->num);
if (!lite) {
if ((*numMeshNodes >= MAX_NUM_NODES) || (memGet.getFreeHeap() < meshtastic_NodeInfoLite_size * 3)) {
screen->print("warning: node_db_lite full! erasing oldest entry\n");
// look for oldest node and erase it
uint32_t oldest = UINT32_MAX;
int oldestIndex = -1;
for (int i = 0; i < *numMeshNodes; i++) {
if (meshNodes[i].last_heard < oldest) {
oldest = meshNodes[i].last_heard;
oldestIndex = i;
}
}
// Shove the remaining nodes down the chain
for (int i = oldestIndex; i < *numMeshNodes - 1; i++) {
meshNodes[i] = meshNodes[i + 1];
}
(*numMeshNodes)--;
}
// add the node at the end
lite = &meshNodes[(*numMeshNodes)++];
// everything is missing except the nodenum
memset(lite, 0, sizeof(*lite));
lite->num = node->num;
lite->snr = node->snr;
lite->last_heard = node->last_heard;
lite->channel = node->channel;
if (node->has_position) {
lite->has_position = true;
lite->position.latitude_i = node->position.latitude_i;
lite->position.longitude_i = node->position.longitude_i;
lite->position.altitude = node->position.altitude;
lite->position.location_source = node->position.location_source;
lite->position.time = node->position.time;
}
if (node->has_user) {
lite->has_user = true;
lite->user = node->user;
}
if (node->has_device_metrics) {
lite->has_device_metrics = true;
lite->device_metrics = node->device_metrics;
}
}
}
/// Record an error that should be reported via analytics
void recordCriticalError(meshtastic_CriticalErrorCode code, uint32_t address, const char *filename)
{

View File

@@ -19,7 +19,7 @@ DeviceState versions used to be defined in the .proto file but really only this
#define SEGMENT_DEVICESTATE 4
#define SEGMENT_CHANNELS 8
#define DEVICESTATE_CUR_VER 20
#define DEVICESTATE_CUR_VER 22
#define DEVICESTATE_MIN_VER DEVICESTATE_CUR_VER
extern meshtastic_DeviceState devicestate;
@@ -45,9 +45,6 @@ class NodeDB
// Eventually use a smarter datastructure
// HashMap<NodeNum, NodeInfo> nodes;
// Note: these two references just point into our static array we serialize to/from disk
meshtastic_NodeInfo *nodes;
pb_size_t *numNodes;
meshtastic_NodeInfoLite *meshNodes;
pb_size_t *numMeshNodes;
@@ -137,18 +134,6 @@ class NodeDB
private:
/// Find a node in our DB, create an empty NodeInfoLite if missing
meshtastic_NodeInfoLite *getOrCreateMeshNode(NodeNum n);
void migrateToNodeInfoLite(const meshtastic_NodeInfo *node);
/// Find a node in our DB, return null for missing
meshtastic_NodeInfo *getNodeInfo(NodeNum n);
/// Allow the bluetooth layer to read our next nodeinfo record, or NULL if done reading
const meshtastic_NodeInfo *readNextNodeInfo(uint32_t &readIndex);
size_t getNumNodes() { return *numNodes; }
meshtastic_NodeInfo *getNodeByIndex(size_t x)
{
assert(x < *numNodes);
return &nodes[x];
}
/// Notify observers of changes to the DB
void notifyObservers(bool forceUpdate = false)
@@ -226,10 +211,6 @@ inline uint32_t getConfiguredOrDefaultMs(uint32_t configuredInterval, uint32_t d
/// Sometimes we will have Position objects that only have a time, so check for
/// valid lat/lon
static inline bool hasValidPosition(const meshtastic_NodeInfo *n)
{
return n->has_position && (n->position.latitude_i != 0 || n->position.longitude_i != 0);
}
static inline bool hasValidPosition(const meshtastic_NodeInfoLite *n)
{
return n->has_position && (n->position.latitude_i != 0 || n->position.longitude_i != 0);

View File

@@ -279,6 +279,14 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_remote_hardware_tag;
fromRadioScratch.moduleConfig.payload_variant.remote_hardware = moduleConfig.remote_hardware;
break;
case meshtastic_ModuleConfig_neighbor_info_tag:
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_neighbor_info_tag;
fromRadioScratch.moduleConfig.payload_variant.neighbor_info = moduleConfig.neighbor_info;
break;
case meshtastic_ModuleConfig_detection_sensor_tag:
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_detection_sensor_tag;
fromRadioScratch.moduleConfig.payload_variant.detection_sensor = moduleConfig.detection_sensor;
break;
default:
LOG_ERROR("Unknown module config type %d\n", config_state);
}

View File

@@ -55,7 +55,11 @@ typedef enum _meshtastic_AdminMessage_ModuleConfigType {
/* TODO: REPLACE */
meshtastic_AdminMessage_ModuleConfigType_REMOTEHARDWARE_CONFIG = 8,
/* TODO: REPLACE */
meshtastic_AdminMessage_ModuleConfigType_AMBIENTLIGHTING_CONFIG = 10
meshtastic_AdminMessage_ModuleConfigType_NEIGHBORINFO_CONFIG = 9,
/* TODO: REPLACE */
meshtastic_AdminMessage_ModuleConfigType_AMBIENTLIGHTING_CONFIG = 10,
/* TODO: REPLACE */
meshtastic_AdminMessage_ModuleConfigType_DETECTIONSENSOR_CONFIG = 11
} meshtastic_AdminMessage_ModuleConfigType;
/* Struct definitions */
@@ -174,8 +178,8 @@ extern "C" {
#define _meshtastic_AdminMessage_ConfigType_ARRAYSIZE ((meshtastic_AdminMessage_ConfigType)(meshtastic_AdminMessage_ConfigType_BLUETOOTH_CONFIG+1))
#define _meshtastic_AdminMessage_ModuleConfigType_MIN meshtastic_AdminMessage_ModuleConfigType_MQTT_CONFIG
#define _meshtastic_AdminMessage_ModuleConfigType_MAX meshtastic_AdminMessage_ModuleConfigType_AMBIENTLIGHTING_CONFIG
#define _meshtastic_AdminMessage_ModuleConfigType_ARRAYSIZE ((meshtastic_AdminMessage_ModuleConfigType)(meshtastic_AdminMessage_ModuleConfigType_AMBIENTLIGHTING_CONFIG+1))
#define _meshtastic_AdminMessage_ModuleConfigType_MAX meshtastic_AdminMessage_ModuleConfigType_DETECTIONSENSOR_CONFIG
#define _meshtastic_AdminMessage_ModuleConfigType_ARRAYSIZE ((meshtastic_AdminMessage_ModuleConfigType)(meshtastic_AdminMessage_ModuleConfigType_DETECTIONSENSOR_CONFIG+1))
#define meshtastic_AdminMessage_payload_variant_get_config_request_ENUMTYPE meshtastic_AdminMessage_ConfigType
#define meshtastic_AdminMessage_payload_variant_get_module_config_request_ENUMTYPE meshtastic_AdminMessage_ModuleConfigType

View File

@@ -269,7 +269,7 @@ typedef struct _meshtastic_Config_PositionConfig {
uint32_t tx_gpio;
/* The minimum distance in meters traveled (since the last send) before we can send a position to the mesh if position_broadcast_smart_enabled */
uint32_t broadcast_smart_minimum_distance;
/* The minumum number of seconds (since the last send) before we can send a position to the mesh if position_broadcast_smart_enabled */
/* The minimum number of seconds (since the last send) before we can send a position to the mesh if position_broadcast_smart_enabled */
uint32_t broadcast_smart_minimum_interval_secs;
} meshtastic_Config_PositionConfig;
@@ -292,12 +292,6 @@ typedef struct _meshtastic_Config_PowerConfig {
The number of seconds for to wait before turning off BLE in No Bluetooth states
0 for default of 1 minute */
uint32_t wait_bluetooth_secs;
/* Deprecated in 2.1.X
Mesh Super Deep Sleep Timeout Seconds
While in Light Sleep if this value is exceeded we will lower into super deep sleep
for sds_secs (default 1 year) or a button press
0 for default of two hours, MAXUINT for disabled */
uint32_t mesh_sds_timeout_secs;
/* Super Deep Sleep Seconds
While in Light Sleep if mesh_sds_timeout_secs is exceeded we will lower into super deep sleep
for this value (default 1 year) or a button press
@@ -537,7 +531,7 @@ extern "C" {
#define meshtastic_Config_init_default {0, {meshtastic_Config_DeviceConfig_init_default}}
#define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0}
#define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_Config_NetworkConfig_init_default {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_default, ""}
#define meshtastic_Config_NetworkConfig_IpV4Config_init_default {0, 0, 0, 0}
#define meshtastic_Config_DisplayConfig_init_default {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0}
@@ -546,7 +540,7 @@ extern "C" {
#define meshtastic_Config_init_zero {0, {meshtastic_Config_DeviceConfig_init_zero}}
#define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0}
#define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_Config_NetworkConfig_init_zero {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_zero, ""}
#define meshtastic_Config_NetworkConfig_IpV4Config_init_zero {0, 0, 0, 0}
#define meshtastic_Config_DisplayConfig_init_zero {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0}
@@ -578,7 +572,6 @@ extern "C" {
#define meshtastic_Config_PowerConfig_on_battery_shutdown_after_secs_tag 2
#define meshtastic_Config_PowerConfig_adc_multiplier_override_tag 3
#define meshtastic_Config_PowerConfig_wait_bluetooth_secs_tag 4
#define meshtastic_Config_PowerConfig_mesh_sds_timeout_secs_tag 5
#define meshtastic_Config_PowerConfig_sds_secs_tag 6
#define meshtastic_Config_PowerConfig_ls_secs_tag 7
#define meshtastic_Config_PowerConfig_min_wake_secs_tag 8
@@ -683,7 +676,6 @@ X(a, STATIC, SINGULAR, BOOL, is_power_saving, 1) \
X(a, STATIC, SINGULAR, UINT32, on_battery_shutdown_after_secs, 2) \
X(a, STATIC, SINGULAR, FLOAT, adc_multiplier_override, 3) \
X(a, STATIC, SINGULAR, UINT32, wait_bluetooth_secs, 4) \
X(a, STATIC, SINGULAR, UINT32, mesh_sds_timeout_secs, 5) \
X(a, STATIC, SINGULAR, UINT32, sds_secs, 6) \
X(a, STATIC, SINGULAR, UINT32, ls_secs, 7) \
X(a, STATIC, SINGULAR, UINT32, min_wake_secs, 8) \
@@ -781,7 +773,7 @@ extern const pb_msgdesc_t meshtastic_Config_BluetoothConfig_msg;
#define meshtastic_Config_NetworkConfig_IpV4Config_size 20
#define meshtastic_Config_NetworkConfig_size 195
#define meshtastic_Config_PositionConfig_size 54
#define meshtastic_Config_PowerConfig_size 46
#define meshtastic_Config_PowerConfig_size 40
#define meshtastic_Config_size 198
#ifdef __cplusplus

File diff suppressed because one or more lines are too long

View File

@@ -75,6 +75,12 @@ typedef struct _meshtastic_LocalModuleConfig {
/* The part of the config that is specific to the Neighbor Info module */
bool has_neighbor_info;
meshtastic_ModuleConfig_NeighborInfoConfig neighbor_info;
/* The part of the config that is specific to the Ambient Lighting module */
bool has_ambient_lighting;
meshtastic_ModuleConfig_AmbientLightingConfig ambient_lighting;
/* The part of the config that is specific to the Detection Sensor module */
bool has_detection_sensor;
meshtastic_ModuleConfig_DetectionSensorConfig detection_sensor;
} meshtastic_LocalModuleConfig;
@@ -84,9 +90,9 @@ extern "C" {
/* Initializer values for message structs */
#define meshtastic_LocalConfig_init_default {false, meshtastic_Config_DeviceConfig_init_default, false, meshtastic_Config_PositionConfig_init_default, false, meshtastic_Config_PowerConfig_init_default, false, meshtastic_Config_NetworkConfig_init_default, false, meshtastic_Config_DisplayConfig_init_default, false, meshtastic_Config_LoRaConfig_init_default, false, meshtastic_Config_BluetoothConfig_init_default, 0}
#define meshtastic_LocalModuleConfig_init_default {false, meshtastic_ModuleConfig_MQTTConfig_init_default, false, meshtastic_ModuleConfig_SerialConfig_init_default, false, meshtastic_ModuleConfig_ExternalNotificationConfig_init_default, false, meshtastic_ModuleConfig_StoreForwardConfig_init_default, false, meshtastic_ModuleConfig_RangeTestConfig_init_default, false, meshtastic_ModuleConfig_TelemetryConfig_init_default, false, meshtastic_ModuleConfig_CannedMessageConfig_init_default, 0, false, meshtastic_ModuleConfig_AudioConfig_init_default, false, meshtastic_ModuleConfig_RemoteHardwareConfig_init_default, false, meshtastic_ModuleConfig_NeighborInfoConfig_init_default}
#define meshtastic_LocalModuleConfig_init_default {false, meshtastic_ModuleConfig_MQTTConfig_init_default, false, meshtastic_ModuleConfig_SerialConfig_init_default, false, meshtastic_ModuleConfig_ExternalNotificationConfig_init_default, false, meshtastic_ModuleConfig_StoreForwardConfig_init_default, false, meshtastic_ModuleConfig_RangeTestConfig_init_default, false, meshtastic_ModuleConfig_TelemetryConfig_init_default, false, meshtastic_ModuleConfig_CannedMessageConfig_init_default, 0, false, meshtastic_ModuleConfig_AudioConfig_init_default, false, meshtastic_ModuleConfig_RemoteHardwareConfig_init_default, false, meshtastic_ModuleConfig_NeighborInfoConfig_init_default, false, meshtastic_ModuleConfig_AmbientLightingConfig_init_default, false, meshtastic_ModuleConfig_DetectionSensorConfig_init_default}
#define meshtastic_LocalConfig_init_zero {false, meshtastic_Config_DeviceConfig_init_zero, false, meshtastic_Config_PositionConfig_init_zero, false, meshtastic_Config_PowerConfig_init_zero, false, meshtastic_Config_NetworkConfig_init_zero, false, meshtastic_Config_DisplayConfig_init_zero, false, meshtastic_Config_LoRaConfig_init_zero, false, meshtastic_Config_BluetoothConfig_init_zero, 0}
#define meshtastic_LocalModuleConfig_init_zero {false, meshtastic_ModuleConfig_MQTTConfig_init_zero, false, meshtastic_ModuleConfig_SerialConfig_init_zero, false, meshtastic_ModuleConfig_ExternalNotificationConfig_init_zero, false, meshtastic_ModuleConfig_StoreForwardConfig_init_zero, false, meshtastic_ModuleConfig_RangeTestConfig_init_zero, false, meshtastic_ModuleConfig_TelemetryConfig_init_zero, false, meshtastic_ModuleConfig_CannedMessageConfig_init_zero, 0, false, meshtastic_ModuleConfig_AudioConfig_init_zero, false, meshtastic_ModuleConfig_RemoteHardwareConfig_init_zero, false, meshtastic_ModuleConfig_NeighborInfoConfig_init_zero}
#define meshtastic_LocalModuleConfig_init_zero {false, meshtastic_ModuleConfig_MQTTConfig_init_zero, false, meshtastic_ModuleConfig_SerialConfig_init_zero, false, meshtastic_ModuleConfig_ExternalNotificationConfig_init_zero, false, meshtastic_ModuleConfig_StoreForwardConfig_init_zero, false, meshtastic_ModuleConfig_RangeTestConfig_init_zero, false, meshtastic_ModuleConfig_TelemetryConfig_init_zero, false, meshtastic_ModuleConfig_CannedMessageConfig_init_zero, 0, false, meshtastic_ModuleConfig_AudioConfig_init_zero, false, meshtastic_ModuleConfig_RemoteHardwareConfig_init_zero, false, meshtastic_ModuleConfig_NeighborInfoConfig_init_zero, false, meshtastic_ModuleConfig_AmbientLightingConfig_init_zero, false, meshtastic_ModuleConfig_DetectionSensorConfig_init_zero}
/* Field tags (for use in manual encoding/decoding) */
#define meshtastic_LocalConfig_device_tag 1
@@ -108,6 +114,8 @@ extern "C" {
#define meshtastic_LocalModuleConfig_audio_tag 9
#define meshtastic_LocalModuleConfig_remote_hardware_tag 10
#define meshtastic_LocalModuleConfig_neighbor_info_tag 11
#define meshtastic_LocalModuleConfig_ambient_lighting_tag 12
#define meshtastic_LocalModuleConfig_detection_sensor_tag 13
/* Struct field encoding specification for nanopb */
#define meshtastic_LocalConfig_FIELDLIST(X, a) \
@@ -140,7 +148,9 @@ X(a, STATIC, OPTIONAL, MESSAGE, canned_message, 7) \
X(a, STATIC, SINGULAR, UINT32, version, 8) \
X(a, STATIC, OPTIONAL, MESSAGE, audio, 9) \
X(a, STATIC, OPTIONAL, MESSAGE, remote_hardware, 10) \
X(a, STATIC, OPTIONAL, MESSAGE, neighbor_info, 11)
X(a, STATIC, OPTIONAL, MESSAGE, neighbor_info, 11) \
X(a, STATIC, OPTIONAL, MESSAGE, ambient_lighting, 12) \
X(a, STATIC, OPTIONAL, MESSAGE, detection_sensor, 13)
#define meshtastic_LocalModuleConfig_CALLBACK NULL
#define meshtastic_LocalModuleConfig_DEFAULT NULL
#define meshtastic_LocalModuleConfig_mqtt_MSGTYPE meshtastic_ModuleConfig_MQTTConfig
@@ -153,6 +163,8 @@ X(a, STATIC, OPTIONAL, MESSAGE, neighbor_info, 11)
#define meshtastic_LocalModuleConfig_audio_MSGTYPE meshtastic_ModuleConfig_AudioConfig
#define meshtastic_LocalModuleConfig_remote_hardware_MSGTYPE meshtastic_ModuleConfig_RemoteHardwareConfig
#define meshtastic_LocalModuleConfig_neighbor_info_MSGTYPE meshtastic_ModuleConfig_NeighborInfoConfig
#define meshtastic_LocalModuleConfig_ambient_lighting_MSGTYPE meshtastic_ModuleConfig_AmbientLightingConfig
#define meshtastic_LocalModuleConfig_detection_sensor_MSGTYPE meshtastic_ModuleConfig_DetectionSensorConfig
extern const pb_msgdesc_t meshtastic_LocalConfig_msg;
extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg;
@@ -162,8 +174,8 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg;
#define meshtastic_LocalModuleConfig_fields &meshtastic_LocalModuleConfig_msg
/* Maximum encoded size of messages (where known) */
#define meshtastic_LocalConfig_size 461
#define meshtastic_LocalModuleConfig_size 547
#define meshtastic_LocalConfig_size 455
#define meshtastic_LocalModuleConfig_size 609
#ifdef __cplusplus
} /* extern "C" */

View File

@@ -61,6 +61,8 @@ typedef enum _meshtastic_HardwareModel {
meshtastic_HardwareModel_NANO_G1_EXPLORER = 17,
/* B&Q Consulting Nano G2 Ultra: https://wiki.uniteng.com/en/meshtastic/nano-g2-ultra */
meshtastic_HardwareModel_NANO_G2_ULTRA = 18,
/* LoRAType device: https://loratype.org/ */
meshtastic_HardwareModel_LORA_TYPE = 19,
/* B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station */
meshtastic_HardwareModel_STATION_G1 = 25,
/* RAK11310 (RP2040 + SX1262) */
@@ -103,10 +105,14 @@ typedef enum _meshtastic_HardwareModel {
meshtastic_HardwareModel_HELTEC_WIRELESS_TRACKER = 48,
/* Heltec Wireless Paper with ESP32-S3 CPU and E-Ink display */
meshtastic_HardwareModel_HELTEC_WIRELESS_PAPER = 49,
/* LilyGo T-Deck with ESP32-S3 CPU, Keyboard, and IPS display */
/* LilyGo T-Deck with ESP32-S3 CPU, Keyboard and IPS display */
meshtastic_HardwareModel_T_DECK = 50,
/* LilyGo T-Watch S3 with ESP32-S3 CPU and IPS display */
meshtastic_HardwareModel_T_WATCH_S3 = 51,
/* Bobricius Picomputer with ESP32-S3 CPU, Keyboard and IPS display */
meshtastic_HardwareModel_PICOMPUTER_S3 = 52,
/* Heltec HT-CT62 with ESP32-C3 CPU and SX1262 LoRa */
meshtastic_HardwareModel_HELTEC_HT62 = 53,
/* ------------------------------------------------------------------------------------------------------------------------------------------
Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits.
------------------------------------------------------------------------------------------------------------------------------------------ */
@@ -149,7 +155,7 @@ typedef enum _meshtastic_CriticalErrorCode {
/* Radio transmit hardware failure. We sent data to the radio chip, but it didn't
reply with an interrupt. */
meshtastic_CriticalErrorCode_TRANSMIT_FAILED = 8,
/* We detected that the main CPU voltage dropped below the minumum acceptable value */
/* We detected that the main CPU voltage dropped below the minimum acceptable value */
meshtastic_CriticalErrorCode_BROWNOUT = 9,
/* Selftest of SX1262 radio chip failed */
meshtastic_CriticalErrorCode_SX1262_FAILURE = 10,
@@ -605,60 +611,12 @@ typedef struct _meshtastic_MyNodeInfo {
/* Tells the phone what our node number is, default starting value is
lowbyte of macaddr, but it will be fixed if that is already in use */
uint32_t my_node_num;
/* Deprecated in 2.1.x (Source from device_metadata)
Note: This flag merely means we detected a hardware GPS in our node.
Not the same as UserPreferences.location_sharing */
bool has_gps;
/* Deprecated in 2.1.x
The maximum number of 'software' channels that can be set on this node. */
uint32_t max_channels;
/* Deprecated in 2.1.x (Source from device_metadata)
0.0.5 etc... */
char firmware_version[18];
/* An error message we'd like to report back to the mothership through analytics.
It indicates a serious bug occurred on the device, the device coped with it,
but we still want to tell the devs about the bug.
This field will be cleared after the phone reads MyNodeInfo
(i.e. it will only be reported once)
a numeric error code to go with error message, zero means no error */
meshtastic_CriticalErrorCode error_code;
/* A numeric error address (nonzero if available) */
uint32_t error_address;
/* The total number of errors this node has ever encountered
(well - since the last time we discarded preferences) */
uint32_t error_count;
/* The total number of reboots this node has ever encountered
(well - since the last time we discarded preferences) */
uint32_t reboot_count;
/* Deprecated in 2.1.x
Calculated bitrate of the current channel (in Bytes Per Second) */
float bitrate;
/* Deprecated in 2.1.x
How long before we consider a message abandoned and we can clear our
caches of any messages in flight Normally quite large to handle the worst case
message delivery time, 5 minutes.
Formerly called FLOOD_EXPIRE_TIME in the device code */
uint32_t message_timeout_msec;
/* The minimum app version that can talk to this device.
Phone/PC apps should compare this to their build number and if too low tell the user they must update their app */
uint32_t min_app_version;
/* Deprecated in 2.1.x (Only used on device to keep track of utilization)
24 time windows of 1hr each with the airtime transmitted out of the device per hour. */
pb_size_t air_period_tx_count;
uint32_t air_period_tx[8];
/* Deprecated in 2.1.x (Only used on device to keep track of utilization)
24 time windows of 1hr each with the airtime of valid packets for your mesh. */
pb_size_t air_period_rx_count;
uint32_t air_period_rx[8];
/* Deprecated in 2.1.x (Source from DeviceMetadata instead)
Is the device wifi capable? */
bool has_wifi;
/* Deprecated in 2.1.x (Source from DeviceMetrics telemetry payloads)
Utilization for the current channel, including well formed TX, RX and malformed RX (aka noise). */
float channel_utilization;
/* Deprecated in 2.1.x (Source from DeviceMetrics telemetry payloads)
Percent of airtime for transmission used within the last hour. */
float air_util_tx;
} meshtastic_MyNodeInfo;
/* Debug output from the device.
@@ -729,6 +687,12 @@ typedef struct _meshtastic_Neighbor {
uint32_t node_id;
/* SNR of last heard message */
float snr;
/* Reception time (in secs since 1970) of last message that was last sent by this ID.
Note: this is for local storage only and will not be sent out over the mesh. */
uint32_t last_rx_time;
/* Broadcast interval of this neighbor (in seconds).
Note: this is for local storage only and will not be sent out over the mesh. */
uint32_t node_broadcast_interval_secs;
} meshtastic_Neighbor;
/* Full info on edges for a single node */
@@ -737,6 +701,8 @@ typedef struct _meshtastic_NeighborInfo {
uint32_t node_id;
/* Field to pass neighbor info for the next sending cycle */
uint32_t last_sent_by_id;
/* Broadcast interval of the represented node (in seconds) */
uint32_t node_broadcast_interval_secs;
/* The list of out edges from this node */
pb_size_t neighbors_count;
meshtastic_Neighbor neighbors[10];
@@ -871,7 +837,6 @@ extern "C" {
#define meshtastic_MeshPacket_delayed_ENUMTYPE meshtastic_MeshPacket_Delayed
#define meshtastic_MyNodeInfo_error_code_ENUMTYPE meshtastic_CriticalErrorCode
#define meshtastic_LogRecord_level_ENUMTYPE meshtastic_LogRecord_Level
@@ -896,14 +861,14 @@ extern "C" {
#define meshtastic_MqttClientProxyMessage_init_default {"", 0, {{0, {0}}}, 0}
#define meshtastic_MeshPacket_init_default {0, 0, 0, 0, {meshtastic_Data_init_default}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN}
#define meshtastic_NodeInfo_init_default {0, false, meshtastic_User_init_default, false, meshtastic_Position_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0}
#define meshtastic_MyNodeInfo_init_default {0, 0, 0, "", _meshtastic_CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}
#define meshtastic_MyNodeInfo_init_default {0, 0, 0}
#define meshtastic_LogRecord_init_default {"", 0, "", _meshtastic_LogRecord_Level_MIN}
#define meshtastic_QueueStatus_init_default {0, 0, 0, 0}
#define meshtastic_FromRadio_init_default {0, 0, {meshtastic_MeshPacket_init_default}}
#define meshtastic_ToRadio_init_default {0, {meshtastic_MeshPacket_init_default}}
#define meshtastic_Compressed_init_default {_meshtastic_PortNum_MIN, {0, {0}}}
#define meshtastic_NeighborInfo_init_default {0, 0, 0, {meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default}}
#define meshtastic_Neighbor_init_default {0, 0}
#define meshtastic_NeighborInfo_init_default {0, 0, 0, 0, {meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default, meshtastic_Neighbor_init_default}}
#define meshtastic_Neighbor_init_default {0, 0, 0, 0}
#define meshtastic_DeviceMetadata_init_default {"", 0, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_Role_MIN, 0, _meshtastic_HardwareModel_MIN, 0}
#define meshtastic_Position_init_zero {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN, _meshtastic_Position_AltSource_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_User_init_zero {"", "", "", {0}, _meshtastic_HardwareModel_MIN, 0}
@@ -914,14 +879,14 @@ extern "C" {
#define meshtastic_MqttClientProxyMessage_init_zero {"", 0, {{0, {0}}}, 0}
#define meshtastic_MeshPacket_init_zero {0, 0, 0, 0, {meshtastic_Data_init_zero}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN}
#define meshtastic_NodeInfo_init_zero {0, false, meshtastic_User_init_zero, false, meshtastic_Position_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0}
#define meshtastic_MyNodeInfo_init_zero {0, 0, 0, "", _meshtastic_CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}
#define meshtastic_MyNodeInfo_init_zero {0, 0, 0}
#define meshtastic_LogRecord_init_zero {"", 0, "", _meshtastic_LogRecord_Level_MIN}
#define meshtastic_QueueStatus_init_zero {0, 0, 0, 0}
#define meshtastic_FromRadio_init_zero {0, 0, {meshtastic_MeshPacket_init_zero}}
#define meshtastic_ToRadio_init_zero {0, {meshtastic_MeshPacket_init_zero}}
#define meshtastic_Compressed_init_zero {_meshtastic_PortNum_MIN, {0, {0}}}
#define meshtastic_NeighborInfo_init_zero {0, 0, 0, {meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero}}
#define meshtastic_Neighbor_init_zero {0, 0}
#define meshtastic_NeighborInfo_init_zero {0, 0, 0, 0, {meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero, meshtastic_Neighbor_init_zero}}
#define meshtastic_Neighbor_init_zero {0, 0, 0, 0}
#define meshtastic_DeviceMetadata_init_zero {"", 0, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_Role_MIN, 0, _meshtastic_HardwareModel_MIN, 0}
/* Field tags (for use in manual encoding/decoding) */
@@ -998,21 +963,8 @@ extern "C" {
#define meshtastic_NodeInfo_device_metrics_tag 6
#define meshtastic_NodeInfo_channel_tag 7
#define meshtastic_MyNodeInfo_my_node_num_tag 1
#define meshtastic_MyNodeInfo_has_gps_tag 2
#define meshtastic_MyNodeInfo_max_channels_tag 3
#define meshtastic_MyNodeInfo_firmware_version_tag 4
#define meshtastic_MyNodeInfo_error_code_tag 5
#define meshtastic_MyNodeInfo_error_address_tag 6
#define meshtastic_MyNodeInfo_error_count_tag 7
#define meshtastic_MyNodeInfo_reboot_count_tag 8
#define meshtastic_MyNodeInfo_bitrate_tag 9
#define meshtastic_MyNodeInfo_message_timeout_msec_tag 10
#define meshtastic_MyNodeInfo_min_app_version_tag 11
#define meshtastic_MyNodeInfo_air_period_tx_tag 12
#define meshtastic_MyNodeInfo_air_period_rx_tag 13
#define meshtastic_MyNodeInfo_has_wifi_tag 14
#define meshtastic_MyNodeInfo_channel_utilization_tag 15
#define meshtastic_MyNodeInfo_air_util_tx_tag 16
#define meshtastic_LogRecord_message_tag 1
#define meshtastic_LogRecord_time_tag 2
#define meshtastic_LogRecord_source_tag 3
@@ -1030,9 +982,12 @@ extern "C" {
#define meshtastic_Compressed_data_tag 2
#define meshtastic_Neighbor_node_id_tag 1
#define meshtastic_Neighbor_snr_tag 2
#define meshtastic_Neighbor_last_rx_time_tag 3
#define meshtastic_Neighbor_node_broadcast_interval_secs_tag 4
#define meshtastic_NeighborInfo_node_id_tag 1
#define meshtastic_NeighborInfo_last_sent_by_id_tag 2
#define meshtastic_NeighborInfo_neighbors_tag 3
#define meshtastic_NeighborInfo_node_broadcast_interval_secs_tag 3
#define meshtastic_NeighborInfo_neighbors_tag 4
#define meshtastic_DeviceMetadata_firmware_version_tag 1
#define meshtastic_DeviceMetadata_device_state_version_tag 2
#define meshtastic_DeviceMetadata_canShutdown_tag 3
@@ -1175,21 +1130,8 @@ X(a, STATIC, SINGULAR, UINT32, channel, 7)
#define meshtastic_MyNodeInfo_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UINT32, my_node_num, 1) \
X(a, STATIC, SINGULAR, BOOL, has_gps, 2) \
X(a, STATIC, SINGULAR, UINT32, max_channels, 3) \
X(a, STATIC, SINGULAR, STRING, firmware_version, 4) \
X(a, STATIC, SINGULAR, UENUM, error_code, 5) \
X(a, STATIC, SINGULAR, UINT32, error_address, 6) \
X(a, STATIC, SINGULAR, UINT32, error_count, 7) \
X(a, STATIC, SINGULAR, UINT32, reboot_count, 8) \
X(a, STATIC, SINGULAR, FLOAT, bitrate, 9) \
X(a, STATIC, SINGULAR, UINT32, message_timeout_msec, 10) \
X(a, STATIC, SINGULAR, UINT32, min_app_version, 11) \
X(a, STATIC, REPEATED, UINT32, air_period_tx, 12) \
X(a, STATIC, REPEATED, UINT32, air_period_rx, 13) \
X(a, STATIC, SINGULAR, BOOL, has_wifi, 14) \
X(a, STATIC, SINGULAR, FLOAT, channel_utilization, 15) \
X(a, STATIC, SINGULAR, FLOAT, air_util_tx, 16)
X(a, STATIC, SINGULAR, UINT32, min_app_version, 11)
#define meshtastic_MyNodeInfo_CALLBACK NULL
#define meshtastic_MyNodeInfo_DEFAULT NULL
@@ -1259,14 +1201,17 @@ X(a, STATIC, SINGULAR, BYTES, data, 2)
#define meshtastic_NeighborInfo_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UINT32, node_id, 1) \
X(a, STATIC, SINGULAR, UINT32, last_sent_by_id, 2) \
X(a, STATIC, REPEATED, MESSAGE, neighbors, 3)
X(a, STATIC, SINGULAR, UINT32, node_broadcast_interval_secs, 3) \
X(a, STATIC, REPEATED, MESSAGE, neighbors, 4)
#define meshtastic_NeighborInfo_CALLBACK NULL
#define meshtastic_NeighborInfo_DEFAULT NULL
#define meshtastic_NeighborInfo_neighbors_MSGTYPE meshtastic_Neighbor
#define meshtastic_Neighbor_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UINT32, node_id, 1) \
X(a, STATIC, SINGULAR, FLOAT, snr, 2)
X(a, STATIC, SINGULAR, FLOAT, snr, 2) \
X(a, STATIC, SINGULAR, FIXED32, last_rx_time, 3) \
X(a, STATIC, SINGULAR, UINT32, node_broadcast_interval_secs, 4)
#define meshtastic_Neighbor_CALLBACK NULL
#define meshtastic_Neighbor_DEFAULT NULL
@@ -1331,9 +1276,9 @@ extern const pb_msgdesc_t meshtastic_DeviceMetadata_msg;
#define meshtastic_LogRecord_size 81
#define meshtastic_MeshPacket_size 321
#define meshtastic_MqttClientProxyMessage_size 501
#define meshtastic_MyNodeInfo_size 179
#define meshtastic_NeighborInfo_size 142
#define meshtastic_Neighbor_size 11
#define meshtastic_MyNodeInfo_size 18
#define meshtastic_NeighborInfo_size 258
#define meshtastic_Neighbor_size 22
#define meshtastic_NodeInfo_size 261
#define meshtastic_Position_size 137
#define meshtastic_QueueStatus_size 23

View File

@@ -18,6 +18,9 @@ PB_BIND(meshtastic_ModuleConfig_RemoteHardwareConfig, meshtastic_ModuleConfig_Re
PB_BIND(meshtastic_ModuleConfig_NeighborInfoConfig, meshtastic_ModuleConfig_NeighborInfoConfig, AUTO)
PB_BIND(meshtastic_ModuleConfig_DetectionSensorConfig, meshtastic_ModuleConfig_DetectionSensorConfig, AUTO)
PB_BIND(meshtastic_ModuleConfig_AudioConfig, meshtastic_ModuleConfig_AudioConfig, AUTO)

View File

@@ -125,6 +125,33 @@ typedef struct _meshtastic_ModuleConfig_NeighborInfoConfig {
uint32_t update_interval;
} meshtastic_ModuleConfig_NeighborInfoConfig;
/* Detection Sensor Module Config */
typedef struct _meshtastic_ModuleConfig_DetectionSensorConfig {
/* Whether the Module is enabled */
bool enabled;
/* Interval in seconds of how often we can send a message to the mesh when a state change is detected */
uint32_t minimum_broadcast_secs;
/* Interval in seconds of how often we should send a message to the mesh with the current state regardless of changes
When set to 0, only state changes will be broadcasted
Works as a sort of status heartbeat for peace of mind */
uint32_t state_broadcast_secs;
/* Send ASCII bell with alert message
Useful for triggering ext. notification on bell */
bool send_bell;
/* Friendly name used to format message sent to mesh
Example: A name "Motion" would result in a message "Motion detected"
Maximum length of 20 characters */
char name[20];
/* GPIO pin to monitor for state changes */
uint8_t monitor_pin;
/* Whether or not the GPIO pin state detection is triggered on HIGH (1)
Otherwise LOW (0) */
bool detection_triggered_high;
/* Whether or not use INPUT_PULLUP mode for GPIO pin
Only applicable if the board uses pull-up resistors on the pin */
bool use_pullup;
} meshtastic_ModuleConfig_DetectionSensorConfig;
/* Audio Config for codec2 voice */
typedef struct _meshtastic_ModuleConfig_AudioConfig {
/* Whether Audio is enabled */
@@ -342,6 +369,8 @@ typedef struct _meshtastic_ModuleConfig {
meshtastic_ModuleConfig_NeighborInfoConfig neighbor_info;
/* TODO: REPLACE */
meshtastic_ModuleConfig_AmbientLightingConfig ambient_lighting;
/* TODO: REPLACE */
meshtastic_ModuleConfig_DetectionSensorConfig detection_sensor;
} payload_variant;
} meshtastic_ModuleConfig;
@@ -375,6 +404,7 @@ extern "C" {
#define meshtastic_ModuleConfig_AudioConfig_bitrate_ENUMTYPE meshtastic_ModuleConfig_AudioConfig_Audio_Baud
#define meshtastic_ModuleConfig_SerialConfig_baud_ENUMTYPE meshtastic_ModuleConfig_SerialConfig_Serial_Baud
@@ -397,6 +427,7 @@ extern "C" {
#define meshtastic_ModuleConfig_MQTTConfig_init_default {0, "", "", "", 0, 0, 0, "", 0}
#define meshtastic_ModuleConfig_RemoteHardwareConfig_init_default {0, 0, 0, {meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default}}
#define meshtastic_ModuleConfig_NeighborInfoConfig_init_default {0, 0}
#define meshtastic_ModuleConfig_DetectionSensorConfig_init_default {0, 0, 0, 0, "", 0, 0, 0}
#define meshtastic_ModuleConfig_AudioConfig_init_default {0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0}
#define meshtastic_ModuleConfig_SerialConfig_init_default {0, 0, 0, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MIN, 0}
#define meshtastic_ModuleConfig_ExternalNotificationConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
@@ -410,6 +441,7 @@ extern "C" {
#define meshtastic_ModuleConfig_MQTTConfig_init_zero {0, "", "", "", 0, 0, 0, "", 0}
#define meshtastic_ModuleConfig_RemoteHardwareConfig_init_zero {0, 0, 0, {meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero}}
#define meshtastic_ModuleConfig_NeighborInfoConfig_init_zero {0, 0}
#define meshtastic_ModuleConfig_DetectionSensorConfig_init_zero {0, 0, 0, 0, "", 0, 0, 0}
#define meshtastic_ModuleConfig_AudioConfig_init_zero {0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0}
#define meshtastic_ModuleConfig_SerialConfig_init_zero {0, 0, 0, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MIN, 0}
#define meshtastic_ModuleConfig_ExternalNotificationConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
@@ -432,6 +464,14 @@ extern "C" {
#define meshtastic_ModuleConfig_MQTTConfig_proxy_to_client_enabled_tag 9
#define meshtastic_ModuleConfig_NeighborInfoConfig_enabled_tag 1
#define meshtastic_ModuleConfig_NeighborInfoConfig_update_interval_tag 2
#define meshtastic_ModuleConfig_DetectionSensorConfig_enabled_tag 1
#define meshtastic_ModuleConfig_DetectionSensorConfig_minimum_broadcast_secs_tag 2
#define meshtastic_ModuleConfig_DetectionSensorConfig_state_broadcast_secs_tag 3
#define meshtastic_ModuleConfig_DetectionSensorConfig_send_bell_tag 4
#define meshtastic_ModuleConfig_DetectionSensorConfig_name_tag 5
#define meshtastic_ModuleConfig_DetectionSensorConfig_monitor_pin_tag 6
#define meshtastic_ModuleConfig_DetectionSensorConfig_detection_triggered_high_tag 7
#define meshtastic_ModuleConfig_DetectionSensorConfig_use_pullup_tag 8
#define meshtastic_ModuleConfig_AudioConfig_codec2_enabled_tag 1
#define meshtastic_ModuleConfig_AudioConfig_ptt_pin_tag 2
#define meshtastic_ModuleConfig_AudioConfig_bitrate_tag 3
@@ -509,6 +549,7 @@ extern "C" {
#define meshtastic_ModuleConfig_remote_hardware_tag 9
#define meshtastic_ModuleConfig_neighbor_info_tag 10
#define meshtastic_ModuleConfig_ambient_lighting_tag 11
#define meshtastic_ModuleConfig_detection_sensor_tag 12
/* Struct field encoding specification for nanopb */
#define meshtastic_ModuleConfig_FIELDLIST(X, a) \
@@ -522,7 +563,8 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,canned_message,payload_varia
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,audio,payload_variant.audio), 8) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,remote_hardware,payload_variant.remote_hardware), 9) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,neighbor_info,payload_variant.neighbor_info), 10) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,ambient_lighting,payload_variant.ambient_lighting), 11)
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,ambient_lighting,payload_variant.ambient_lighting), 11) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,detection_sensor,payload_variant.detection_sensor), 12)
#define meshtastic_ModuleConfig_CALLBACK NULL
#define meshtastic_ModuleConfig_DEFAULT NULL
#define meshtastic_ModuleConfig_payload_variant_mqtt_MSGTYPE meshtastic_ModuleConfig_MQTTConfig
@@ -536,6 +578,7 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,ambient_lighting,payload_var
#define meshtastic_ModuleConfig_payload_variant_remote_hardware_MSGTYPE meshtastic_ModuleConfig_RemoteHardwareConfig
#define meshtastic_ModuleConfig_payload_variant_neighbor_info_MSGTYPE meshtastic_ModuleConfig_NeighborInfoConfig
#define meshtastic_ModuleConfig_payload_variant_ambient_lighting_MSGTYPE meshtastic_ModuleConfig_AmbientLightingConfig
#define meshtastic_ModuleConfig_payload_variant_detection_sensor_MSGTYPE meshtastic_ModuleConfig_DetectionSensorConfig
#define meshtastic_ModuleConfig_MQTTConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, BOOL, enabled, 1) \
@@ -564,6 +607,18 @@ X(a, STATIC, SINGULAR, UINT32, update_interval, 2)
#define meshtastic_ModuleConfig_NeighborInfoConfig_CALLBACK NULL
#define meshtastic_ModuleConfig_NeighborInfoConfig_DEFAULT NULL
#define meshtastic_ModuleConfig_DetectionSensorConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, BOOL, enabled, 1) \
X(a, STATIC, SINGULAR, UINT32, minimum_broadcast_secs, 2) \
X(a, STATIC, SINGULAR, UINT32, state_broadcast_secs, 3) \
X(a, STATIC, SINGULAR, BOOL, send_bell, 4) \
X(a, STATIC, SINGULAR, STRING, name, 5) \
X(a, STATIC, SINGULAR, UINT32, monitor_pin, 6) \
X(a, STATIC, SINGULAR, BOOL, detection_triggered_high, 7) \
X(a, STATIC, SINGULAR, BOOL, use_pullup, 8)
#define meshtastic_ModuleConfig_DetectionSensorConfig_CALLBACK NULL
#define meshtastic_ModuleConfig_DetectionSensorConfig_DEFAULT NULL
#define meshtastic_ModuleConfig_AudioConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, BOOL, codec2_enabled, 1) \
X(a, STATIC, SINGULAR, UINT32, ptt_pin, 2) \
@@ -667,6 +722,7 @@ extern const pb_msgdesc_t meshtastic_ModuleConfig_msg;
extern const pb_msgdesc_t meshtastic_ModuleConfig_MQTTConfig_msg;
extern const pb_msgdesc_t meshtastic_ModuleConfig_RemoteHardwareConfig_msg;
extern const pb_msgdesc_t meshtastic_ModuleConfig_NeighborInfoConfig_msg;
extern const pb_msgdesc_t meshtastic_ModuleConfig_DetectionSensorConfig_msg;
extern const pb_msgdesc_t meshtastic_ModuleConfig_AudioConfig_msg;
extern const pb_msgdesc_t meshtastic_ModuleConfig_SerialConfig_msg;
extern const pb_msgdesc_t meshtastic_ModuleConfig_ExternalNotificationConfig_msg;
@@ -682,6 +738,7 @@ extern const pb_msgdesc_t meshtastic_RemoteHardwarePin_msg;
#define meshtastic_ModuleConfig_MQTTConfig_fields &meshtastic_ModuleConfig_MQTTConfig_msg
#define meshtastic_ModuleConfig_RemoteHardwareConfig_fields &meshtastic_ModuleConfig_RemoteHardwareConfig_msg
#define meshtastic_ModuleConfig_NeighborInfoConfig_fields &meshtastic_ModuleConfig_NeighborInfoConfig_msg
#define meshtastic_ModuleConfig_DetectionSensorConfig_fields &meshtastic_ModuleConfig_DetectionSensorConfig_msg
#define meshtastic_ModuleConfig_AudioConfig_fields &meshtastic_ModuleConfig_AudioConfig_msg
#define meshtastic_ModuleConfig_SerialConfig_fields &meshtastic_ModuleConfig_SerialConfig_msg
#define meshtastic_ModuleConfig_ExternalNotificationConfig_fields &meshtastic_ModuleConfig_ExternalNotificationConfig_msg
@@ -696,6 +753,7 @@ extern const pb_msgdesc_t meshtastic_RemoteHardwarePin_msg;
#define meshtastic_ModuleConfig_AmbientLightingConfig_size 14
#define meshtastic_ModuleConfig_AudioConfig_size 19
#define meshtastic_ModuleConfig_CannedMessageConfig_size 49
#define meshtastic_ModuleConfig_DetectionSensorConfig_size 44
#define meshtastic_ModuleConfig_ExternalNotificationConfig_size 40
#define meshtastic_ModuleConfig_MQTTConfig_size 222
#define meshtastic_ModuleConfig_NeighborInfoConfig_size 8

View File

@@ -25,73 +25,101 @@
typedef enum _meshtastic_PortNum {
/* Deprecated: do not use in new code (formerly called OPAQUE)
A message sent from a device outside of the mesh, in a form the mesh does not understand
NOTE: This must be 0, because it is documented in IMeshService.aidl to be so */
NOTE: This must be 0, because it is documented in IMeshService.aidl to be so
ENCODING: binary undefined */
meshtastic_PortNum_UNKNOWN_APP = 0,
/* A simple UTF-8 text message, which even the little micros in the mesh
can understand and show on their screen eventually in some circumstances
even signal might send messages in this form (see below) */
even signal might send messages in this form (see below)
ENCODING: UTF-8 Plaintext (?) */
meshtastic_PortNum_TEXT_MESSAGE_APP = 1,
/* Reserved for built-in GPIO/example app.
See remote_hardware.proto/HardwareMessage for details on the message sent/received to this port number */
See remote_hardware.proto/HardwareMessage for details on the message sent/received to this port number
ENCODING: Protobuf */
meshtastic_PortNum_REMOTE_HARDWARE_APP = 2,
/* The built-in position messaging app.
Payload is a [Position](/docs/developers/protobufs/api#position) message */
Payload is a [Position](/docs/developers/protobufs/api#position) message
ENCODING: Protobuf */
meshtastic_PortNum_POSITION_APP = 3,
/* The built-in user info app.
Payload is a [User](/docs/developers/protobufs/api#user) message */
Payload is a [User](/docs/developers/protobufs/api#user) message
ENCODING: Protobuf */
meshtastic_PortNum_NODEINFO_APP = 4,
/* Protocol control packets for mesh protocol use.
Payload is a [Routing](/docs/developers/protobufs/api#routing) message */
Payload is a [Routing](/docs/developers/protobufs/api#routing) message
ENCODING: Protobuf */
meshtastic_PortNum_ROUTING_APP = 5,
/* Admin control packets.
Payload is a [AdminMessage](/docs/developers/protobufs/api#adminmessage) message */
Payload is a [AdminMessage](/docs/developers/protobufs/api#adminmessage) message
ENCODING: Protobuf */
meshtastic_PortNum_ADMIN_APP = 6,
/* Compressed TEXT_MESSAGE payloads. */
/* Compressed TEXT_MESSAGE payloads.
ENCODING: UTF-8 Plaintext (?) with Unishox2 Compression
NOTE: The Device Firmware converts a TEXT_MESSAGE_APP to TEXT_MESSAGE_COMPRESSED_APP if the compressed
payload is shorter. There's no need for app developers to do this themselves. Also the firmware will decompress
any incoming TEXT_MESSAGE_COMPRESSED_APP payload and convert to TEXT_MESSAGE_APP. */
meshtastic_PortNum_TEXT_MESSAGE_COMPRESSED_APP = 7,
/* Waypoint payloads.
Payload is a [Waypoint](/docs/developers/protobufs/api#waypoint) message */
Payload is a [Waypoint](/docs/developers/protobufs/api#waypoint) message
ENCODING: Protobuf */
meshtastic_PortNum_WAYPOINT_APP = 8,
/* Audio Payloads.
Encapsulated codec2 packets. On 2.4 GHZ Bandwidths only for now */
Encapsulated codec2 packets. On 2.4 GHZ Bandwidths only for now
ENCODING: codec2 audio frames
NOTE: audio frames contain a 3 byte header (0xc0 0xde 0xc2) and a one byte marker for the decompressed bitrate.
This marker comes from the 'moduleConfig.audio.bitrate' enum minus one. */
meshtastic_PortNum_AUDIO_APP = 9,
/* Same as Text Message but originating from Detection Sensor Module. */
meshtastic_PortNum_DETECTION_SENSOR_APP = 10,
/* Provides a 'ping' service that replies to any packet it receives.
Also serves as a small example module. */
Also serves as a small example module.
ENCODING: ASCII Plaintext */
meshtastic_PortNum_REPLY_APP = 32,
/* Used for the python IP tunnel feature */
/* Used for the python IP tunnel feature
ENCODING: IP Packet. Handled by the python API, firmware ignores this one and pases on. */
meshtastic_PortNum_IP_TUNNEL_APP = 33,
/* Provides a hardware serial interface to send and receive from the Meshtastic network.
Connect to the RX/TX pins of a device with 38400 8N1. Packets received from the Meshtastic
network is forwarded to the RX pin while sending a packet to TX will go out to the Mesh network.
Maximum packet size of 240 bytes.
Module is disabled by default can be turned on by setting SERIAL_MODULE_ENABLED = 1 in SerialPlugh.cpp. */
Module is disabled by default can be turned on by setting SERIAL_MODULE_ENABLED = 1 in SerialPlugh.cpp.
ENCODING: binary undefined */
meshtastic_PortNum_SERIAL_APP = 64,
/* STORE_FORWARD_APP (Work in Progress)
Maintained by Jm Casler (MC Hamster) : jm@casler.org */
Maintained by Jm Casler (MC Hamster) : jm@casler.org
ENCODING: Protobuf */
meshtastic_PortNum_STORE_FORWARD_APP = 65,
/* Optional port for messages for the range test module. */
/* Optional port for messages for the range test module.
ENCODING: ASCII Plaintext */
meshtastic_PortNum_RANGE_TEST_APP = 66,
/* Provides a format to send and receive telemetry data from the Meshtastic network.
Maintained by Charles Crossan (crossan007) : crossan007@gmail.com */
Maintained by Charles Crossan (crossan007) : crossan007@gmail.com
ENCODING: Protobuf */
meshtastic_PortNum_TELEMETRY_APP = 67,
/* Experimental tools for estimating node position without a GPS
Maintained by Github user a-f-G-U-C (a Meshtastic contributor)
Project files at https://github.com/a-f-G-U-C/Meshtastic-ZPS */
Project files at https://github.com/a-f-G-U-C/Meshtastic-ZPS
ENCODING: arrays of int64 fields */
meshtastic_PortNum_ZPS_APP = 68,
/* Used to let multiple instances of Linux native applications communicate
as if they did using their LoRa chip.
Maintained by GitHub user GUVWAF.
Project files at https://github.com/GUVWAF/Meshtasticator */
Project files at https://github.com/GUVWAF/Meshtasticator
ENCODING: Protobuf (?) */
meshtastic_PortNum_SIMULATOR_APP = 69,
/* Provides a traceroute functionality to show the route a packet towards
a certain destination would take on the mesh. */
a certain destination would take on the mesh.
ENCODING: Protobuf */
meshtastic_PortNum_TRACEROUTE_APP = 70,
/* Aggregates edge info for the network by sending out a list of each node's neighbors */
/* Aggregates edge info for the network by sending out a list of each node's neighbors
ENCODING: Protobuf */
meshtastic_PortNum_NEIGHBORINFO_APP = 71,
/* Private applications should use portnums >= 256.
To simplify initial development and testing you can use "PRIVATE_APP"
in your code without needing to rebuild protobuf files (via [regen-protos.sh](https://github.com/meshtastic/firmware/blob/master/bin/regen-protos.sh)) */
meshtastic_PortNum_PRIVATE_APP = 256,
/* ATAK Forwarder Module https://github.com/paulmandal/atak-forwarder */
/* ATAK Forwarder Module https://github.com/paulmandal/atak-forwarder
ENCODING: libcotshrink */
meshtastic_PortNum_ATAK_FORWARDER = 257,
/* Currently we limit port nums to no higher than this value */
meshtastic_PortNum_MAX = 511

View File

@@ -402,7 +402,6 @@ void handleStatic(HTTPRequest *req, HTTPResponse *res)
"href=/admin>admin</a>");
return;
} else {
res->setHeader("Content-Encoding", "gzip");
}
@@ -438,7 +437,6 @@ void handleStatic(HTTPRequest *req, HTTPResponse *res)
file.close();
return;
} else {
LOG_ERROR("This should not have happened...\n");
res->println("ERROR: This should not have happened...");
@@ -467,7 +465,7 @@ void handleFormUpload(HTTPRequest *req, HTTPResponse *res)
// first semicolon, if one exists:
size_t semicolonPos = contentType.find(";");
if (semicolonPos != std::string::npos) {
contentType = contentType.substr(0, semicolonPos);
contentType.resize(semicolonPos);
}
// Now, we can decide based on the content type:
@@ -581,7 +579,6 @@ void handleReport(HTTPRequest *req, HTTPResponse *res)
res->setHeader("Content-Type", "application/json");
res->setHeader("Access-Control-Allow-Origin", "*");
res->setHeader("Access-Control-Allow-Methods", "GET");
} else {
res->setHeader("Content-Type", "text/html");
res->println("<pre>");
@@ -857,4 +854,4 @@ void handleScanNetworks(HTTPRequest *req, HTTPResponse *res)
JSONValue *value = new JSONValue(jsonObjOuter);
res->print(value->Stringify().c_str());
delete value;
}
}

View File

@@ -16,7 +16,7 @@
#define MAX_RX_TOPHONE 32
/// max number of nodes allowed in the mesh
#define MAX_NUM_NODES (member_size(meshtastic_DeviceState, node_db) / member_size(meshtastic_DeviceState, node_db[0]))
#define MAX_NUM_NODES (member_size(meshtastic_DeviceState, node_db_lite) / member_size(meshtastic_DeviceState, node_db_lite[0]))
/// Max number of channels allowed
#define MAX_NUM_CHANNELS (member_size(meshtastic_ChannelFile, channels) / member_size(meshtastic_ChannelFile, channels[0]))

View File

@@ -368,6 +368,16 @@ void AdminModule::handleSetModuleConfig(const meshtastic_ModuleConfig &c)
moduleConfig.has_remote_hardware = true;
moduleConfig.remote_hardware = c.payload_variant.remote_hardware;
break;
case meshtastic_ModuleConfig_neighbor_info_tag:
LOG_INFO("Setting module config: Neighbor Info\n");
moduleConfig.has_neighbor_info = true;
moduleConfig.neighbor_info = c.payload_variant.neighbor_info;
break;
case meshtastic_ModuleConfig_detection_sensor_tag:
LOG_INFO("Setting module config: Detection Sensor\n");
moduleConfig.has_detection_sensor = true;
moduleConfig.detection_sensor = c.payload_variant.detection_sensor;
break;
}
saveChanges(SEGMENT_MODULECONFIG);
@@ -503,6 +513,16 @@ void AdminModule::handleGetModuleConfig(const meshtastic_MeshPacket &req, const
res.get_module_config_response.which_payload_variant = meshtastic_ModuleConfig_remote_hardware_tag;
res.get_module_config_response.payload_variant.remote_hardware = moduleConfig.remote_hardware;
break;
case meshtastic_AdminMessage_ModuleConfigType_NEIGHBORINFO_CONFIG:
LOG_INFO("Getting module config: Neighbor Info\n");
res.get_module_config_response.which_payload_variant = meshtastic_ModuleConfig_neighbor_info_tag;
res.get_module_config_response.payload_variant.neighbor_info = moduleConfig.neighbor_info;
break;
case meshtastic_AdminMessage_ModuleConfigType_DETECTIONSENSOR_CONFIG:
LOG_INFO("Getting module config: Detection Sensor\n");
res.get_module_config_response.which_payload_variant = meshtastic_ModuleConfig_detection_sensor_tag;
res.get_module_config_response.payload_variant.detection_sensor = moduleConfig.detection_sensor;
break;
}
// NOTE: The phone app needs to know the ls_secsvalue so it can properly expect sleep behavior.
@@ -663,4 +683,4 @@ AdminModule::AdminModule() : ProtobufModule("Admin", meshtastic_PortNum_ADMIN_AP
{
// restrict to the admin channel for rx
boundChannel = Channels::adminChannel;
}
}

View File

@@ -10,6 +10,10 @@
#include "main.h" // for cardkb_found
#ifndef INPUTBROKER_MATRIX_TYPE
#define INPUTBROKER_MATRIX_TYPE 0
#endif
#ifdef OLED_RU
#include "graphics/fonts/OLEDDisplayFontsRU.h"
#endif
@@ -59,10 +63,10 @@ CannedMessageModule *cannedMessageModule;
CannedMessageModule::CannedMessageModule()
: SinglePortModule("canned", meshtastic_PortNum_TEXT_MESSAGE_APP), concurrency::OSThread("CannedMessageModule")
{
if (moduleConfig.canned_message.enabled) {
if (moduleConfig.canned_message.enabled || CANNED_MESSAGE_MODULE_ENABLE) {
this->loadProtoForModule();
if ((this->splitConfiguredMessages() <= 0) && (cardkb_found.address != CARDKB_ADDR) &&
(cardkb_found.address != TDECK_KB_ADDR)) {
if ((this->splitConfiguredMessages() <= 0) && (cardkb_found.address == 0x00) && !INPUTBROKER_MATRIX_TYPE &&
!CANNED_MESSAGE_MODULE_ENABLE) {
LOG_INFO("CannedMessageModule: No messages are configured. Module is disabled\n");
this->runState = CANNED_MESSAGE_RUN_STATE_DISABLED;
disable();
@@ -137,12 +141,12 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
bool validEvent = false;
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP)) {
LOG_DEBUG("Canned message event UP\n");
// LOG_DEBUG("Canned message event UP\n");
this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_UP;
validEvent = true;
}
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN)) {
LOG_DEBUG("Canned message event DOWN\n");
// LOG_DEBUG("Canned message event DOWN\n");
this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_DOWN;
validEvent = true;
}
@@ -166,7 +170,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
if ((event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_BACK)) ||
(event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) ||
(event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT))) {
LOG_DEBUG("Canned message event (%x)\n", event->kbchar);
// LOG_DEBUG("Canned message event (%x)\n", event->kbchar);
// tweak for left/right events generated via trackball/touch with empty kbchar
if (!event->kbchar) {
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) {
@@ -191,6 +195,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
this->runState = CANNED_MESSAGE_RUN_STATE_FREETEXT;
}
// pass the pressed key
// LOG_DEBUG("Canned message ANYKEY (%x)\n", event->kbchar);
this->payload = event->kbchar;
this->lastTouchMillis = millis();
validEvent = true;
@@ -220,9 +225,9 @@ void CannedMessageModule::sendText(NodeNum dest, const char *message, bool wantR
p->want_ack = true;
p->decoded.payload.size = strlen(message);
memcpy(p->decoded.payload.bytes, message, p->decoded.payload.size);
if (moduleConfig.canned_message.send_bell) {
p->decoded.payload.bytes[p->decoded.payload.size - 1] = 7; // Bell character
p->decoded.payload.bytes[p->decoded.payload.size] = '\0'; // Bell character
if (moduleConfig.canned_message.send_bell && p->decoded.payload.size < meshtastic_Constants_DATA_PAYLOAD_LEN) {
p->decoded.payload.bytes[p->decoded.payload.size] = 7; // Bell character
p->decoded.payload.bytes[p->decoded.payload.size + 1] = '\0'; // Bell character
p->decoded.payload.size++;
}
@@ -233,8 +238,8 @@ void CannedMessageModule::sendText(NodeNum dest, const char *message, bool wantR
int32_t CannedMessageModule::runOnce()
{
if ((!moduleConfig.canned_message.enabled) || (this->runState == CANNED_MESSAGE_RUN_STATE_DISABLED) ||
(this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE)) {
if (((!moduleConfig.canned_message.enabled) && !CANNED_MESSAGE_MODULE_ENABLE) ||
(this->runState == CANNED_MESSAGE_RUN_STATE_DISABLED) || (this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE)) {
return INT32_MAX;
}
// LOG_DEBUG("Check status\n");
@@ -394,9 +399,10 @@ int32_t CannedMessageModule::runOnce()
this->freetext.substring(0, this->cursor) + this->payload + this->freetext.substring(this->cursor);
}
this->cursor += 1;
if (this->freetext.length() > meshtastic_Constants_DATA_PAYLOAD_LEN) {
this->cursor = meshtastic_Constants_DATA_PAYLOAD_LEN;
this->freetext = this->freetext.substring(0, meshtastic_Constants_DATA_PAYLOAD_LEN);
uint16_t maxChars = meshtastic_Constants_DATA_PAYLOAD_LEN - (moduleConfig.canned_message.send_bell ? 1 : 0);
if (this->freetext.length() > maxChars) {
this->cursor = maxChars;
this->freetext = this->freetext.substring(0, maxChars);
}
break;
}
@@ -449,7 +455,7 @@ const char *CannedMessageModule::getNodeName(NodeNum node)
bool CannedMessageModule::shouldDraw()
{
if (!moduleConfig.canned_message.enabled) {
if (!moduleConfig.canned_message.enabled && !CANNED_MESSAGE_MODULE_ENABLE) {
return false;
}
return (currentMessageIndex != -1) || (this->runState != CANNED_MESSAGE_RUN_STATE_INACTIVE);
@@ -495,7 +501,9 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
}
display->drawStringf(0 + x, 0 + y, buffer, "To: %s", cannedMessageModule->getNodeName(this->dest));
// used chars right aligned
snprintf(buffer, sizeof(buffer), "%d left", meshtastic_Constants_DATA_PAYLOAD_LEN - this->freetext.length());
uint16_t charsLeft =
meshtastic_Constants_DATA_PAYLOAD_LEN - this->freetext.length() - (moduleConfig.canned_message.send_bell ? 1 : 0);
snprintf(buffer, sizeof(buffer), "%d left", charsLeft);
display->drawString(x + display->getWidth() - display->getStringWidth(buffer), y + 0, buffer);
if (this->destSelect) {
display->drawString(x + display->getWidth() - display->getStringWidth(buffer) - 1, y + 0, buffer);
@@ -642,4 +650,4 @@ String CannedMessageModule::drawWithCursor(String text, int cursor)
return result;
}
#endif
#endif

View File

@@ -20,6 +20,10 @@ enum cannedMessageModuleRunState {
*/
#define CANNED_MESSAGE_MODULE_MESSAGES_SIZE 800
#ifndef CANNED_MESSAGE_MODULE_ENABLE
#define CANNED_MESSAGE_MODULE_ENABLE 0
#endif
class CannedMessageModule : public SinglePortModule, public Observable<const UIFrameEvent *>, private concurrency::OSThread
{
CallbackObserver<CannedMessageModule, const InputEvent *> inputObserver =

View File

@@ -0,0 +1,102 @@
#include "DetectionSensorModule.h"
#include "MeshService.h"
#include "NodeDB.h"
#include "PowerFSM.h"
#include "configuration.h"
#include "main.h"
DetectionSensorModule *detectionSensorModule;
#define GPIO_POLLING_INTERVAL 100
#define DELAYED_INTERVAL 1000
int32_t DetectionSensorModule::runOnce()
{
/*
Uncomment the preferences below if you want to use the module
without having to configure it from the PythonAPI or WebUI.
*/
// moduleConfig.detection_sensor.enabled = true;
// moduleConfig.detection_sensor.monitor_pin = 10; // WisBlock PIR IO6
// moduleConfig.detection_sensor.monitor_pin = 21; // WisBlock RAK12013 Radar IO6
// moduleConfig.detection_sensor.minimum_broadcast_secs = 30;
// moduleConfig.detection_sensor.state_broadcast_secs = 120;
// moduleConfig.detection_sensor.detection_triggered_high = true;
// strcpy(moduleConfig.detection_sensor.name, "Motion");
if (moduleConfig.detection_sensor.enabled == false)
return disable();
if (firstTime) {
// This is the first time the OSThread library has called this function, so do some setup
firstTime = false;
if (moduleConfig.detection_sensor.monitor_pin > 0) {
pinMode(moduleConfig.detection_sensor.monitor_pin, moduleConfig.detection_sensor.use_pullup ? INPUT_PULLUP : INPUT);
} else {
LOG_WARN("Detection Sensor Module: Set to enabled but no monitor pin is set. Disabling module...\n");
return disable();
}
LOG_INFO("Detection Sensor Module: Initializing\n");
return DELAYED_INTERVAL;
}
// LOG_DEBUG("Detection Sensor Module: Current pin state: %i\n", digitalRead(moduleConfig.detection_sensor.monitor_pin));
if ((millis() - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.detection_sensor.minimum_broadcast_secs) &&
hasDetectionEvent()) {
sendDetectionMessage();
return DELAYED_INTERVAL;
}
// Even if we haven't detected an event, broadcast our current state to the mesh on the scheduled interval as a sort
// of heartbeat. We only do this if the minimum broadcast interval is greater than zero, otherwise we'll only broadcast state
// change detections.
else if (moduleConfig.detection_sensor.state_broadcast_secs > 0 &&
(millis() - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.detection_sensor.state_broadcast_secs)) {
sendCurrentStateMessage();
return DELAYED_INTERVAL;
}
return GPIO_POLLING_INTERVAL;
}
void DetectionSensorModule::sendDetectionMessage()
{
LOG_DEBUG("Detected event observed. Sending message\n");
char *message = new char[40];
sprintf(message, "%s detected", moduleConfig.detection_sensor.name);
meshtastic_MeshPacket *p = allocDataPacket();
p->want_ack = false;
p->decoded.payload.size = strlen(message);
memcpy(p->decoded.payload.bytes, message, p->decoded.payload.size);
if (moduleConfig.detection_sensor.send_bell && p->decoded.payload.size < meshtastic_Constants_DATA_PAYLOAD_LEN) {
p->decoded.payload.bytes[p->decoded.payload.size] = 7; // Bell character
p->decoded.payload.bytes[p->decoded.payload.size + 1] = '\0'; // Bell character
p->decoded.payload.size++;
}
LOG_INFO("Sending message id=%d, dest=%x, msg=%.*s\n", p->id, p->to, p->decoded.payload.size, p->decoded.payload.bytes);
lastSentToMesh = millis();
service.sendToMesh(p);
delete[] message;
}
void DetectionSensorModule::sendCurrentStateMessage()
{
char *message = new char[40];
sprintf(message, "%s state: %i", moduleConfig.detection_sensor.name, hasDetectionEvent());
meshtastic_MeshPacket *p = allocDataPacket();
p->want_ack = false;
p->decoded.payload.size = strlen(message);
memcpy(p->decoded.payload.bytes, message, p->decoded.payload.size);
LOG_INFO("Sending message id=%d, dest=%x, msg=%.*s\n", p->id, p->to, p->decoded.payload.size, p->decoded.payload.bytes);
lastSentToMesh = millis();
service.sendToMesh(p);
delete[] message;
}
bool DetectionSensorModule::hasDetectionEvent()
{
bool currentState = digitalRead(moduleConfig.detection_sensor.monitor_pin);
// LOG_DEBUG("Detection Sensor Module: Current state: %i\n", currentState);
return moduleConfig.detection_sensor.detection_triggered_high ? currentState : !currentState;
}

View File

@@ -0,0 +1,23 @@
#pragma once
#include "SinglePortModule.h"
class DetectionSensorModule : public SinglePortModule, private concurrency::OSThread
{
public:
DetectionSensorModule()
: SinglePortModule("detection", meshtastic_PortNum_DETECTION_SENSOR_APP), OSThread("DetectionSensorModule")
{
}
protected:
virtual int32_t runOnce() override;
private:
bool firstTime = true;
uint32_t lastSentToMesh = 0;
void sendDetectionMessage();
void sendCurrentStateMessage();
bool hasDetectionEvent();
};
extern DetectionSensorModule *detectionSensorModule;

View File

@@ -128,6 +128,11 @@ int32_t ExternalNotificationModule::runOnce()
}
}
bool ExternalNotificationModule::wantPacket(const meshtastic_MeshPacket *p)
{
return MeshService::isTextPayload(p);
}
/**
* Sets the external notification on for the specified index.
*
@@ -212,8 +217,8 @@ void ExternalNotificationModule::stopNow()
}
ExternalNotificationModule::ExternalNotificationModule()
: SinglePortModule("ExternalNotificationModule", meshtastic_PortNum_TEXT_MESSAGE_APP), concurrency::OSThread(
"ExternalNotificationModule")
: SinglePortModule("ExternalNotificationModule", meshtastic_PortNum_TEXT_MESSAGE_APP),
concurrency::OSThread("ExternalNotificationModule")
{
/*
Uncomment the preferences below if you want to use the module

View File

@@ -52,6 +52,8 @@ class ExternalNotificationModule : public SinglePortModule, private concurrency:
virtual int32_t runOnce() override;
virtual bool wantPacket(const meshtastic_MeshPacket *p) override;
bool isNagging = false;
virtual AdminMessageHandleResult handleAdminMessageForModule(const meshtastic_MeshPacket &mp,
@@ -59,4 +61,4 @@ class ExternalNotificationModule : public SinglePortModule, private concurrency:
meshtastic_AdminMessage *response) override;
};
extern ExternalNotificationModule *externalNotificationModule;
extern ExternalNotificationModule *externalNotificationModule;

View File

@@ -4,8 +4,11 @@
#include "input/TrackballInterruptImpl1.h"
#include "input/UpDownInterruptImpl1.h"
#include "input/cardKbI2cImpl.h"
#include "input/kbMatrixImpl.h"
#include "modules/AdminModule.h"
#include "modules/CannedMessageModule.h"
#include "modules/DetectionSensorModule.h"
#include "modules/NeighborInfoModule.h"
#include "modules/NodeInfoModule.h"
#include "modules/PositionModule.h"
#include "modules/RemoteHardwareModule.h"
@@ -47,6 +50,8 @@ void setupModules()
waypointModule = new WaypointModule();
textMessageModule = new TextMessageModule();
traceRouteModule = new TraceRouteModule();
neighborInfoModule = new NeighborInfoModule();
detectionSensorModule = new DetectionSensorModule();
// Note: if the rest of meshtastic doesn't need to explicitly use your module, you do not need to assign the instance
// to a global variable.
@@ -60,7 +65,11 @@ void setupModules()
upDownInterruptImpl1->init();
cardKbI2cImpl = new CardKbI2cImpl();
cardKbI2cImpl->init();
#endif
#ifdef INPUTBROKER_MATRIX_TYPE
kbMatrixImpl = new KbMatrixImpl();
kbMatrixImpl->init();
#endif // INPUTBROKER_MATRIX_TYPE
#endif // HAS_BUTTON
#if HAS_TRACKBALL
trackballInterruptImpl1 = new TrackballInterruptImpl1();
trackballInterruptImpl1->init();

View File

@@ -0,0 +1,319 @@
#include "NeighborInfoModule.h"
#include "MeshService.h"
#include "NodeDB.h"
#include "RTC.h"
#define MAX_NUM_NEIGHBORS 10 // also defined in NeighborInfo protobuf options
NeighborInfoModule *neighborInfoModule;
static const char *neighborInfoConfigFile = "/prefs/neighbors.proto";
/*
Prints a single neighbor info packet and associated neighbors
Uses LOG_DEBUG, which equates to Console.log
NOTE: For debugging only
*/
void NeighborInfoModule::printNeighborInfo(const char *header, const meshtastic_NeighborInfo *np)
{
LOG_DEBUG("%s NEIGHBORINFO PACKET from Node 0x%x to Node 0x%x (last sent by 0x%x)\n", header, np->node_id,
nodeDB.getNodeNum(), np->last_sent_by_id);
LOG_DEBUG("----------------\n");
LOG_DEBUG("Packet contains %d neighbors\n", np->neighbors_count);
for (int i = 0; i < np->neighbors_count; i++) {
LOG_DEBUG("Neighbor %d: node_id=0x%x, snr=%.2f\n", i, np->neighbors[i].node_id, np->neighbors[i].snr);
}
LOG_DEBUG("----------------\n");
}
/*
Prints the nodeDB nodes so we can see whose nodeInfo we have
NOTE: for debugging only
*/
void NeighborInfoModule::printNodeDBNodes(const char *header)
{
int num_nodes = nodeDB.getNumMeshNodes();
LOG_DEBUG("%s NODEDB SELECTION from Node 0x%x:\n", header, nodeDB.getNodeNum());
LOG_DEBUG("----------------\n");
LOG_DEBUG("DB contains %d nodes\n", num_nodes);
for (int i = 0; i < num_nodes; i++) {
const meshtastic_NodeInfoLite *dbEntry = nodeDB.getMeshNodeByIndex(i);
LOG_DEBUG(" Node %d: node_id=0x%x, snr=%.2f\n", i, dbEntry->num, dbEntry->snr);
}
LOG_DEBUG("----------------\n");
}
/*
Prints the nodeDB neighbors
NOTE: for debugging only
*/
void NeighborInfoModule::printNodeDBNeighbors(const char *header)
{
int num_neighbors = getNumNeighbors();
LOG_DEBUG("%s NODEDB SELECTION from Node 0x%x:\n", header, nodeDB.getNodeNum());
LOG_DEBUG("----------------\n");
LOG_DEBUG("DB contains %d neighbors\n", num_neighbors);
for (int i = 0; i < num_neighbors; i++) {
const meshtastic_Neighbor *dbEntry = getNeighborByIndex(i);
LOG_DEBUG(" Node %d: node_id=0x%x, snr=%.2f\n", i, dbEntry->node_id, dbEntry->snr);
}
LOG_DEBUG("----------------\n");
}
/*
Prints the nodeDB with selectors for the neighbors we've chosen to send (inefficiently)
Uses LOG_DEBUG, which equates to Console.log
NOTE: For debugging only
*/
void NeighborInfoModule::printNodeDBSelection(const char *header, const meshtastic_NeighborInfo *np)
{
int num_neighbors = getNumNeighbors();
LOG_DEBUG("%s NODEDB SELECTION from Node 0x%x:\n", header, nodeDB.getNodeNum());
LOG_DEBUG("----------------\n");
LOG_DEBUG("Selected %d neighbors of %d DB neighbors\n", np->neighbors_count, num_neighbors);
for (int i = 0; i < num_neighbors; i++) {
meshtastic_Neighbor *dbEntry = getNeighborByIndex(i);
bool chosen = false;
for (int j = 0; j < np->neighbors_count; j++) {
if (np->neighbors[j].node_id == dbEntry->node_id) {
chosen = true;
}
}
if (!chosen) {
LOG_DEBUG(" Node %d: neighbor=0x%x, snr=%.2f\n", i, dbEntry->node_id, dbEntry->snr);
} else {
LOG_DEBUG("---> Node %d: neighbor=0x%x, snr=%.2f\n", i, dbEntry->node_id, dbEntry->snr);
}
}
LOG_DEBUG("----------------\n");
}
/* Send our initial owner announcement 35 seconds after we start (to give network time to setup) */
NeighborInfoModule::NeighborInfoModule()
: ProtobufModule("neighborinfo", meshtastic_PortNum_NEIGHBORINFO_APP, &meshtastic_NeighborInfo_msg),
concurrency::OSThread("NeighborInfoModule"), neighbors(neighborState.neighbors),
numNeighbors(&neighborState.neighbors_count)
{
ourPortNum = meshtastic_PortNum_NEIGHBORINFO_APP;
if (moduleConfig.neighbor_info.enabled) {
this->loadProtoForModule();
setIntervalFromNow(35 * 1000);
} else {
LOG_DEBUG("NeighborInfoModule is disabled\n");
disable();
}
}
/*
Allocate a zeroed neighbor info packet
*/
meshtastic_NeighborInfo *NeighborInfoModule::allocateNeighborInfoPacket()
{
meshtastic_NeighborInfo *neighborInfo = (meshtastic_NeighborInfo *)malloc(sizeof(meshtastic_NeighborInfo));
memset(neighborInfo, 0, sizeof(meshtastic_NeighborInfo));
return neighborInfo;
}
/*
Collect neighbor info from the nodeDB's history, capping at a maximum number of entries and max time
Assumes that the neighborInfo packet has been allocated
@returns the number of entries collected
*/
uint32_t NeighborInfoModule::collectNeighborInfo(meshtastic_NeighborInfo *neighborInfo)
{
uint my_node_id = nodeDB.getNodeNum();
neighborInfo->node_id = my_node_id;
neighborInfo->last_sent_by_id = my_node_id;
neighborInfo->node_broadcast_interval_secs = moduleConfig.neighbor_info.update_interval;
int num_neighbors = cleanUpNeighbors();
for (int i = 0; i < num_neighbors; i++) {
meshtastic_Neighbor *dbEntry = getNeighborByIndex(i);
if ((neighborInfo->neighbors_count < MAX_NUM_NEIGHBORS) && (dbEntry->node_id != my_node_id)) {
neighborInfo->neighbors[neighborInfo->neighbors_count].node_id = dbEntry->node_id;
neighborInfo->neighbors[neighborInfo->neighbors_count].snr = dbEntry->snr;
// Note: we don't set the last_rx_time and node_broadcast_intervals_secs here, because we don't want to send this over
// the mesh
neighborInfo->neighbors_count++;
}
}
printNodeDBNodes("DBSTATE");
printNodeDBNeighbors("NEIGHBORS");
printNodeDBSelection("COLLECTED", neighborInfo);
return neighborInfo->neighbors_count;
}
/*
Remove neighbors from the database that we haven't heard from in a while
@returns new number of neighbors
*/
size_t NeighborInfoModule::cleanUpNeighbors()
{
uint32_t now = getTime();
int num_neighbors = getNumNeighbors();
NodeNum my_node_id = nodeDB.getNodeNum();
// Find neighbors to remove
std::vector<int> indices_to_remove;
for (int i = 0; i < num_neighbors; i++) {
meshtastic_Neighbor *dbEntry = getNeighborByIndex(i);
// We will remove a neighbor if we haven't heard from them in twice the broadcast interval
if ((now - dbEntry->last_rx_time > dbEntry->node_broadcast_interval_secs * 2) && (dbEntry->node_id != my_node_id)) {
indices_to_remove.push_back(i);
}
}
// Update the neighbor list
for (uint i = 0; i < indices_to_remove.size(); i++) {
int index = indices_to_remove[i];
LOG_DEBUG("Removing neighbor with node ID 0x%x\n", neighbors[index].node_id);
for (int j = index; j < num_neighbors - 1; j++) {
neighbors[j] = neighbors[j + 1];
}
(*numNeighbors)--;
}
// Save the neighbor list if we removed any neighbors
if (indices_to_remove.size() > 0) {
saveProtoForModule();
}
return *numNeighbors;
}
/* Send neighbor info to the mesh */
void NeighborInfoModule::sendNeighborInfo(NodeNum dest, bool wantReplies)
{
meshtastic_NeighborInfo *neighborInfo = allocateNeighborInfoPacket();
collectNeighborInfo(neighborInfo);
meshtastic_MeshPacket *p = allocDataProtobuf(*neighborInfo);
// send regardless of whether or not we have neighbors in our DB,
// because we want to get neighbors for the next cycle
p->to = dest;
p->decoded.want_response = wantReplies;
printNeighborInfo("SENDING", neighborInfo);
service.sendToMesh(p, RX_SRC_LOCAL, true);
}
/*
Encompasses the full construction and sending packet to mesh
Will be used for broadcast.
*/
int32_t NeighborInfoModule::runOnce()
{
bool requestReplies = false;
sendNeighborInfo(NODENUM_BROADCAST, requestReplies);
return getConfiguredOrDefaultMs(moduleConfig.neighbor_info.update_interval, default_broadcast_interval_secs);
}
/*
Collect a recieved neighbor info packet from another node
Pass it to an upper client; do not persist this data on the mesh
*/
bool NeighborInfoModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_NeighborInfo *np)
{
printNeighborInfo("RECEIVED", np);
updateNeighbors(mp, np);
// Allow others to handle this packet
return false;
}
/*
Copy the content of a current NeighborInfo packet into a new one and update the last_sent_by_id to our NodeNum
*/
void NeighborInfoModule::updateLastSentById(meshtastic_MeshPacket *p)
{
auto &incoming = p->decoded;
meshtastic_NeighborInfo scratch;
meshtastic_NeighborInfo *updated = NULL;
memset(&scratch, 0, sizeof(scratch));
pb_decode_from_bytes(incoming.payload.bytes, incoming.payload.size, &meshtastic_NeighborInfo_msg, &scratch);
updated = &scratch;
updated->last_sent_by_id = nodeDB.getNodeNum();
// Set updated last_sent_by_id to the payload of the to be flooded packet
p->decoded.payload.size =
pb_encode_to_bytes(p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes), &meshtastic_NeighborInfo_msg, updated);
}
void NeighborInfoModule::resetNeighbors()
{
*numNeighbors = 0;
neighborState.neighbors_count = 0;
memset(neighborState.neighbors, 0, sizeof(neighborState.neighbors));
saveProtoForModule();
}
void NeighborInfoModule::updateNeighbors(const meshtastic_MeshPacket &mp, const meshtastic_NeighborInfo *np)
{
// The last sent ID will be 0 if the packet is from the phone, which we don't count as
// an edge. So we assume that if it's zero, then this packet is from our node.
if (mp.which_payload_variant == meshtastic_MeshPacket_decoded_tag && mp.from) {
getOrCreateNeighbor(mp.from, np->last_sent_by_id, np->node_broadcast_interval_secs, mp.rx_snr);
}
}
meshtastic_Neighbor *NeighborInfoModule::getOrCreateNeighbor(NodeNum originalSender, NodeNum n,
uint32_t node_broadcast_interval_secs, float snr)
{
// our node and the phone are the same node (not neighbors)
if (n == 0) {
n = nodeDB.getNodeNum();
}
// look for one in the existing list
for (int i = 0; i < (*numNeighbors); i++) {
meshtastic_Neighbor *nbr = &neighbors[i];
if (nbr->node_id == n) {
// if found, update it
nbr->snr = snr;
nbr->last_rx_time = getTime();
// Only if this is the original sender, the broadcast interval corresponds to it
if (originalSender == n)
nbr->node_broadcast_interval_secs = node_broadcast_interval_secs;
saveProtoForModule(); // Save the updated neighbor
return nbr;
}
}
// otherwise, allocate one and assign data to it
// TODO: max memory for the database should take neighbors into account, but currently doesn't
if (*numNeighbors < MAX_NUM_NODES) {
(*numNeighbors)++;
}
meshtastic_Neighbor *new_nbr = &neighbors[((*numNeighbors) - 1)];
new_nbr->node_id = n;
new_nbr->snr = snr;
new_nbr->last_rx_time = getTime();
// Only if this is the original sender, the broadcast interval corresponds to it
if (originalSender == n)
new_nbr->node_broadcast_interval_secs = node_broadcast_interval_secs;
saveProtoForModule(); // Save the new neighbor
return new_nbr;
}
void NeighborInfoModule::loadProtoForModule()
{
if (!nodeDB.loadProto(neighborInfoConfigFile, meshtastic_NeighborInfo_size, sizeof(meshtastic_NeighborInfo),
&meshtastic_NeighborInfo_msg, &neighborState)) {
neighborState = meshtastic_NeighborInfo_init_zero;
}
}
/**
* @brief Save the module config to file.
*
* @return true On success.
* @return false On error.
*/
bool NeighborInfoModule::saveProtoForModule()
{
bool okay = true;
#ifdef FS
FS.mkdir("/prefs");
#endif
okay &= nodeDB.saveProto(neighborInfoConfigFile, meshtastic_NeighborInfo_size, &meshtastic_NeighborInfo_msg, &neighborState);
return okay;
}

View File

@@ -0,0 +1,84 @@
#pragma once
#include "ProtobufModule.h"
/*
* Neighborinfo module for sending info on each node's 0-hop neighbors to the mesh
*/
class NeighborInfoModule : public ProtobufModule<meshtastic_NeighborInfo>, private concurrency::OSThread
{
meshtastic_Neighbor *neighbors;
pb_size_t *numNeighbors;
public:
/*
* Expose the constructor
*/
NeighborInfoModule();
/* Reset neighbor info after clearing nodeDB*/
void resetNeighbors();
bool saveProtoForModule();
// Let FloodingRouter call updateLastSentById upon rebroadcasting a NeighborInfo packet
friend class FloodingRouter;
protected:
// Note: this holds our local info.
meshtastic_NeighborInfo neighborState;
/*
* Called to handle a particular incoming message
* @return true if you've guaranteed you've handled this message and no other handlers should be considered for it
*/
virtual bool handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_NeighborInfo *nb) override;
/*
* Collect neighbor info from the nodeDB's history, capping at a maximum number of entries and max time
* @return the number of entries collected
*/
uint32_t collectNeighborInfo(meshtastic_NeighborInfo *neighborInfo);
/*
Remove neighbors from the database that we haven't heard from in a while
@returns new number of neighbors
*/
size_t cleanUpNeighbors();
/* Allocate a new NeighborInfo packet */
meshtastic_NeighborInfo *allocateNeighborInfoPacket();
// Find a neighbor in our DB, create an empty neighbor if missing
meshtastic_Neighbor *getOrCreateNeighbor(NodeNum originalSender, NodeNum n, uint32_t node_broadcast_interval_secs, float snr);
/*
* Send info on our node's neighbors into the mesh
*/
void sendNeighborInfo(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false);
size_t getNumNeighbors() { return *numNeighbors; }
meshtastic_Neighbor *getNeighborByIndex(size_t x)
{
assert(x < *numNeighbors);
return &neighbors[x];
}
/* update neighbors with subpacket sniffed from network */
void updateNeighbors(const meshtastic_MeshPacket &mp, const meshtastic_NeighborInfo *np);
/* update a NeighborInfo packet with our NodeNum as last_sent_by_id */
void updateLastSentById(meshtastic_MeshPacket *p);
void loadProtoForModule();
/* Does our periodic broadcast */
int32_t runOnce() override;
/* These are for debugging only */
void printNeighborInfo(const char *header, const meshtastic_NeighborInfo *np);
void printNodeDBNodes(const char *header);
void printNodeDBNeighbors(const char *header);
void printNodeDBSelection(const char *header, const meshtastic_NeighborInfo *np);
};
extern NeighborInfoModule *neighborInfoModule;

View File

@@ -185,7 +185,7 @@ int32_t PositionModule::runOnce()
} else if (config.position.position_broadcast_smart_enabled) {
// Only send packets if the channel is less than 25% utilized or we're a tracker.
if (airTime->isTxAllowedChannelUtil(config.device.role != meshtastic_Config_DeviceConfig_Role_TRACKER)) {
meshtastic_NodeInfoLite *node2 = service.refreshLocalMeshNode(); // should guarantee there is now a position
const meshtastic_NodeInfoLite *node2 = service.refreshLocalMeshNode(); // should guarantee there is now a position
if (hasValidPosition(node2)) {
// The minimum distance to travel before we are able to send a new position packet.

View File

@@ -29,7 +29,7 @@ class RangeTestModuleRadio : public SinglePortModule
uint32_t lastRxID = 0;
public:
RangeTestModuleRadio() : SinglePortModule("RangeTestModuleRadio", meshtastic_PortNum_TEXT_MESSAGE_APP)
RangeTestModuleRadio() : SinglePortModule("RangeTestModuleRadio", meshtastic_PortNum_RANGE_TEST_APP)
{
loopbackOk = true; // Allow locally generated messages to loop back to the client
}

View File

@@ -217,7 +217,7 @@ meshtastic_MeshPacket *SerialModuleRadio::allocReply()
*/
void SerialModuleRadio::sendPayload(NodeNum dest, bool wantReplies)
{
meshtastic_Channel *ch = (boundChannel != NULL) ? &channels.getByName(boundChannel) : NULL;
const meshtastic_Channel *ch = (boundChannel != NULL) ? &channels.getByName(boundChannel) : NULL;
meshtastic_MeshPacket *p = allocReply();
p->to = dest;
if (ch != NULL) {

View File

@@ -1,4 +1,5 @@
#include "TextMessageModule.h"
#include "MeshService.h"
#include "NodeDB.h"
#include "PowerFSM.h"
#include "configuration.h"
@@ -22,3 +23,8 @@ ProcessMessage TextMessageModule::handleReceived(const meshtastic_MeshPacket &mp
return ProcessMessage::CONTINUE; // Let others look at this message also if they want
}
bool TextMessageModule::wantPacket(const meshtastic_MeshPacket *p)
{
return MeshService::isTextPayload(p);
}

View File

@@ -20,6 +20,7 @@ class TextMessageModule : public SinglePortModule, public Observable<const mesht
it
*/
virtual ProcessMessage handleReceived(const meshtastic_MeshPacket &mp) override;
virtual bool wantPacket(const meshtastic_MeshPacket *p) override;
};
extern TextMessageModule *textMessageModule;
extern TextMessageModule *textMessageModule;

View File

@@ -66,7 +66,7 @@ meshtastic_MeshPacket *TraceRouteModule::allocReply()
// Copy the payload of the current request
auto req = *currentRequest;
auto &p = req.decoded;
const auto &p = req.decoded;
meshtastic_RouteDiscovery scratch;
meshtastic_RouteDiscovery *updated = NULL;
memset(&scratch, 0, sizeof(scratch));

View File

@@ -227,7 +227,7 @@ void StoreForwardModule::sendPayload(NodeNum dest, uint32_t packetHistory_index)
* @param dest The destination node number.
* @param payload The message payload to be sent.
*/
void StoreForwardModule::sendMessage(NodeNum dest, meshtastic_StoreAndForward &payload)
void StoreForwardModule::sendMessage(NodeNum dest, const meshtastic_StoreAndForward &payload)
{
meshtastic_MeshPacket *p = allocDataProtobuf(payload);

View File

@@ -57,7 +57,7 @@ class StoreForwardModule : private concurrency::OSThread, public ProtobufModule<
* Send our payload into the mesh
*/
void sendPayload(NodeNum dest = NODENUM_BROADCAST, uint32_t packetHistory_index = 0);
void sendMessage(NodeNum dest, meshtastic_StoreAndForward &payload);
void sendMessage(NodeNum dest, const meshtastic_StoreAndForward &payload);
void sendMessage(NodeNum dest, meshtastic_StoreAndForward_RequestResponse rr);
virtual meshtastic_MeshPacket *allocReply() override;

View File

@@ -363,6 +363,19 @@ JSONValue::JSONValue(int m_integer_value)
number_value = (double)m_integer_value;
}
/**
* Basic constructor for creating a JSON Value of type Number
*
* @access public
*
* @param uint m_integer_value The number to use as the value
*/
JSONValue::JSONValue(uint m_integer_value)
{
type = JSONType_Number;
number_value = (double)m_integer_value;
}
/**
* Basic constructor for creating a JSON Value of type Array
*
@@ -874,4 +887,4 @@ std::string JSONValue::Indent(size_t depth)
depth ? --depth : 0;
std::string indentStr(depth * indent_step, ' ');
return indentStr;
}
}

View File

@@ -45,6 +45,7 @@ class JSONValue
JSONValue(bool m_bool_value);
JSONValue(double m_number_value);
JSONValue(int m_integer_value);
JSONValue(uint m_integer_value);
JSONValue(const JSONArray &m_array_value);
JSONValue(const JSONObject &m_object_value);
JSONValue(const JSONValue &m_source);
@@ -91,4 +92,4 @@ class JSONValue
};
};
#endif
#endif

View File

@@ -333,7 +333,7 @@ void MQTT::sendSubscriptions()
#ifdef HAS_NETWORKING
size_t numChan = channels.getNumChannels();
for (size_t i = 0; i < numChan; i++) {
auto &ch = channels.getByIndex(i);
const auto &ch = channels.getByIndex(i);
if (ch.settings.downlink_enabled) {
std::string topic = cryptTopic + channels.getGlobalId(i) + "/#";
LOG_INFO("Subscribing to %s\n", topic.c_str());
@@ -356,7 +356,7 @@ bool MQTT::wantsLink() const
// No need for link if no channel needed it
size_t numChan = channels.getNumChannels();
for (size_t i = 0; i < numChan; i++) {
auto &ch = channels.getByIndex(i);
const auto &ch = channels.getByIndex(i);
if (ch.settings.uplink_enabled || ch.settings.downlink_enabled) {
hasChannel = true;
break;
@@ -541,7 +541,7 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_Telemetry_msg, &scratch)) {
decoded = &scratch;
if (decoded->which_variant == meshtastic_Telemetry_device_metrics_tag) {
msgPayload["battery_level"] = new JSONValue((int)decoded->variant.device_metrics.battery_level);
msgPayload["battery_level"] = new JSONValue((uint)decoded->variant.device_metrics.battery_level);
msgPayload["voltage"] = new JSONValue(decoded->variant.device_metrics.voltage);
msgPayload["channel_utilization"] = new JSONValue(decoded->variant.device_metrics.channel_utilization);
msgPayload["air_util_tx"] = new JSONValue(decoded->variant.device_metrics.air_util_tx);
@@ -588,10 +588,10 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_Position_msg, &scratch)) {
decoded = &scratch;
if ((int)decoded->time) {
msgPayload["time"] = new JSONValue((int)decoded->time);
msgPayload["time"] = new JSONValue((uint)decoded->time);
}
if ((int)decoded->timestamp) {
msgPayload["timestamp"] = new JSONValue((int)decoded->timestamp);
msgPayload["timestamp"] = new JSONValue((uint)decoded->timestamp);
}
msgPayload["latitude_i"] = new JSONValue((int)decoded->latitude_i);
msgPayload["longitude_i"] = new JSONValue((int)decoded->longitude_i);
@@ -599,13 +599,13 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
msgPayload["altitude"] = new JSONValue((int)decoded->altitude);
}
if ((int)decoded->ground_speed) {
msgPayload["ground_speed"] = new JSONValue((int)decoded->ground_speed);
msgPayload["ground_speed"] = new JSONValue((uint)decoded->ground_speed);
}
if (int(decoded->ground_track)) {
msgPayload["ground_track"] = new JSONValue((int)decoded->ground_track);
msgPayload["ground_track"] = new JSONValue((uint)decoded->ground_track);
}
if (int(decoded->sats_in_view)) {
msgPayload["sats_in_view"] = new JSONValue((int)decoded->sats_in_view);
msgPayload["sats_in_view"] = new JSONValue((uint)decoded->sats_in_view);
}
if ((int)decoded->PDOP) {
msgPayload["PDOP"] = new JSONValue((int)decoded->PDOP);
@@ -632,11 +632,11 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
memset(&scratch, 0, sizeof(scratch));
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_Waypoint_msg, &scratch)) {
decoded = &scratch;
msgPayload["id"] = new JSONValue((int)decoded->id);
msgPayload["id"] = new JSONValue((uint)decoded->id);
msgPayload["name"] = new JSONValue(decoded->name);
msgPayload["description"] = new JSONValue(decoded->description);
msgPayload["expire"] = new JSONValue((int)decoded->expire);
msgPayload["locked_to"] = new JSONValue((int)decoded->locked_to);
msgPayload["expire"] = new JSONValue((uint)decoded->expire);
msgPayload["locked_to"] = new JSONValue((uint)decoded->locked_to);
msgPayload["latitude_i"] = new JSONValue((int)decoded->latitude_i);
msgPayload["longitude_i"] = new JSONValue((int)decoded->longitude_i);
jsonObj["payload"] = new JSONValue(msgPayload);
@@ -646,16 +646,34 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
};
break;
}
case meshtastic_PortNum_NEIGHBORINFO_APP: {
msgType = "neighborinfo";
meshtastic_NeighborInfo scratch;
meshtastic_NeighborInfo *decoded = NULL;
if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
memset(&scratch, 0, sizeof(scratch));
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_NeighborInfo_msg,
&scratch)) {
decoded = &scratch;
msgPayload["node_id"] = new JSONValue((uint)decoded->node_id);
msgPayload["neighbors_count"] = new JSONValue(decoded->neighbors_count);
msgPayload["neighbors"] = new JSONValue(decoded->neighbors);
} else {
LOG_ERROR("Error decoding protobuf for neighborinfo message!\n");
}
};
break;
}
// add more packet types here if needed
default:
break;
}
jsonObj["id"] = new JSONValue((int)mp->id);
jsonObj["timestamp"] = new JSONValue((int)mp->rx_time);
jsonObj["to"] = new JSONValue((int)mp->to);
jsonObj["from"] = new JSONValue((int)mp->from);
jsonObj["channel"] = new JSONValue((int)mp->channel);
jsonObj["id"] = new JSONValue((uint)mp->id);
jsonObj["timestamp"] = new JSONValue((uint)mp->rx_time);
jsonObj["to"] = new JSONValue((uint)mp->to);
jsonObj["from"] = new JSONValue((uint)mp->from);
jsonObj["channel"] = new JSONValue((uint)mp->channel);
jsonObj["type"] = new JSONValue(msgType.c_str());
jsonObj["sender"] = new JSONValue(owner.id);

View File

@@ -117,6 +117,10 @@
#define HW_VENDOR meshtastic_HardwareModel_NANO_G1_EXPLORER
#elif defined(BETAFPV_900_TX_NANO)
#define HW_VENDOR meshtastic_HardwareModel_BETAFPV_900_NANO_TX
#elif defined(PICOMPUTER_S3)
#define HW_VENDOR meshtastic_HardwareModel_PICOMPUTER_S3
#elif defined(HELTEC_HT62)
#define HW_VENDOR meshtastic_HardwareModel_HELTEC_HT62
#endif
//
@@ -147,4 +151,4 @@
#define RF95_NSS 18
#endif
#define SERIAL0_RX_GPIO 3 // Always GPIO3 on ESP32
#define SERIAL0_RX_GPIO 3 // Always GPIO3 on ESP32

View File

@@ -9,10 +9,10 @@
#include "BleOta.h"
#include "mesh/http/WiFiAPClient.h"
#include "meshUtils.h"
#include "sleep.h"
#include "soc/rtc.h"
#include "target_specific.h"
#include "utils.h"
#include <Preferences.h>
#include <driver/rtc_io.h>
#include <nvs.h>
@@ -220,4 +220,4 @@ void cpuDeepSleep(uint32_t msecToWake)
esp_sleep_enable_timer_wakeup(msecToWake * 1000ULL); // call expects usecs
esp_deep_sleep_start(); // TBD mA sleep current (battery)
}
}

View File

@@ -16,7 +16,7 @@ void powerCommandsCheck()
rp2040.reboot();
#else
rebootAtMsec = -1;
LOG_WARN("FIXME implement reboot for this platform. Skipping for now.\n");
LOG_WARN("FIXME implement reboot for this platform. Note that some settings require a restart to be applied.\n");
#endif
}

View File

@@ -28,6 +28,9 @@ useInitializationList
//unreadVariable:src/graphics/Screen.cpp
unreadVariable
// I don't want to go back and cast function pointers just to appease a tools insatiable thirst for immutability
constParameterCallback
redundantInitialization
//cstyleCast:src/mesh/MemoryPool.h:71
@@ -46,4 +49,4 @@ virtualCallInConstructor
passedByValue:*/RedirectablePrint.h
internalAstError:*/CrossPlatformCryptoEngine.cpp
internalAstError:*/CrossPlatformCryptoEngine.cpp

View File

@@ -0,0 +1,32 @@
#ifndef Pins_Arduino_h
#define Pins_Arduino_h
#include <stdint.h>
#define EXTERNAL_NUM_INTERRUPTS 22
#define NUM_DIGITAL_PINS 22
#define NUM_ANALOG_INPUTS 6
#define analogInputToDigitalPin(p) (((p) < NUM_ANALOG_INPUTS) ? (esp32_adc2gpio[(p)]) : -1)
#define digitalPinToInterrupt(p) (((p) < NUM_DIGITAL_PINS) ? (p) : -1)
#define digitalPinHasPWM(p) (p < EXTERNAL_NUM_INTERRUPTS)
static const uint8_t TX = 21;
static const uint8_t RX = 20;
static const uint8_t SDA = 1;
static const uint8_t SCL = 0;
static const uint8_t SS = 8;
static const uint8_t MOSI = 7;
static const uint8_t MISO = 6;
static const uint8_t SCK = 10;
static const uint8_t A0 = 0;
static const uint8_t A1 = 1;
static const uint8_t A2 = 2;
static const uint8_t A3 = 3;
static const uint8_t A4 = 4;
static const uint8_t A5 = 5;
#endif /* Pins_Arduino_h */

View File

@@ -0,0 +1,12 @@
[env:heltec-ht62-esp32c3-sx1262]
extends = esp32c3_base
board = esp32-c3-devkitm-1
board_level = extra
build_flags =
${esp32_base.build_flags}
-D HELTEC_HT62
-I variants/heltec_esp32c3
monitor_speed = 115200
upload_protocol = esptool
upload_port = /dev/ttyUSB0
upload_speed = 921600

View File

@@ -0,0 +1,36 @@
#define I2C_SDA 1
#define I2C_SCL 0
#define BUTTON_PIN 9
#define BUTTON_NEED_PULLUP
// LED flashes brighter
// https://resource.heltec.cn/download/HT-CT62/HT-CT62_Reference_Design.pdf
#define LED_PIN 18 // LED
#define LED_INVERTED 1
#define HAS_SCREEN 0
#define HAS_GPS 0
#undef GPS_RX_PIN
#undef GPS_TX_PIN
#undef RF95_SCK
#undef RF95_MISO
#undef RF95_MOSI
#undef RF95_NSS
#define USE_SX1262
#define RF95_SCK 10
#define RF95_MISO 6
#define RF95_MOSI 7
#define RF95_NSS 8
#define LORA_DIO0 RADIOLIB_NC
#define LORA_RESET 5
#define LORA_DIO1 3
#define LORA_DIO2 RADIOLIB_NC
#define LORA_BUSY 4
#define SX126X_CS RF95_NSS
#define SX126X_DIO1 LORA_DIO1
#define SX126X_BUSY LORA_BUSY
#define SX126X_RESET LORA_RESET
#define SX126X_E22

View File

@@ -4,6 +4,10 @@
#define I2C_SDA SDA_OLED // I2C pins for this board
#define I2C_SCL SCL_OLED
// Enable secondary bus for external periherals
#define I2C_SDA1 SDA
#define I2C_SCL1 SCL
#define VEXT_ENABLE Vext // active low, powers the oled display and the lora antenna boost
#define BUTTON_PIN 0

View File

@@ -1,5 +1,9 @@
#define LED_PIN 18
// Enable bus for external periherals
#define I2C_SDA SDA
#define I2C_SCL SCL
#define USE_EINK
/*
* eink display pins

View File

@@ -1,5 +1,5 @@
#define I2C_SCL 47
#define I2C_SDA 48
#define I2C_SCL SCL
#define I2C_SDA SDA
#define LED_PIN LED

View File

@@ -0,0 +1,30 @@
#ifndef Pins_Arduino_h
#define Pins_Arduino_h
#include <stdint.h>
#define USB_VID 0x303a
#define USB_PID 0x1001
#define EXTERNAL_NUM_INTERRUPTS 46
#define NUM_DIGITAL_PINS 48
#define NUM_ANALOG_INPUTS 20
#define analogInputToDigitalPin(p) (((p) < 20) ? (analogChannelToDigitalPin(p)) : -1)
#define digitalPinToInterrupt(p) (((p) < 48) ? (p) : -1)
#define digitalPinHasPWM(p) (p < 46)
static const uint8_t TX = 43;
static const uint8_t RX = 44;
// The default Wire will be mapped to PMU and RTC
static const uint8_t SDA = 8;
static const uint8_t SCL = 9;
// Default SPI
static const uint8_t MISO = 39;
static const uint8_t SCK = 21;
static const uint8_t MOSI = 38;
static const uint8_t SS = 40;
#endif /* Pins_Arduino_h */

View File

@@ -0,0 +1,17 @@
[env:picomputer-s3]
extends = esp32s3_base
board = bpi_picow_esp32_s3
board_level = extra
;OpenOCD flash method
;upload_protocol = esp-builtin
;Normal method
upload_protocol = esptool
build_flags =
${esp32s3_base.build_flags}
-DPICOMPUTER_S3
-I variants/picomputer-s3
lib_deps =
${esp32s3_base.lib_deps}
lovyan03/LovyanGFX@^1.1.8

View File

@@ -0,0 +1,60 @@
#undef GPS_RX_PIN
#undef GPS_TX_PIN
#define BUTTON_PIN 0
#define PIN_BUZZER 43
#define HAS_GPS 0
#define HAS_WIRE 0
#define USE_RF95 // RFM95/SX127x
#define RF95_SCK SCK // 21
#define RF95_MISO MISO // 39
#define RF95_MOSI MOSI // 38
#define RF95_NSS SS // 40
#define LORA_RESET RADIOLIB_NC
// per SX1276_Receive_Interrupt/utilities.h
#define LORA_DIO0 10
#define LORA_DIO1 RADIOLIB_NC
#define LORA_DIO2 RADIOLIB_NC
// Default SPI1 will be mapped to the display
#define ST7789_SDA 4
#define ST7789_SCK 3
#define ST7789_CS 6
#define ST7789_RS 1
#define ST7789_BL 5
#define ST7789_RESET -1
#define ST7789_MISO -1
#define ST7789_BUSY -1
#define ST7789_SPI_HOST SPI3_HOST
#define ST7789_BACKLIGHT_EN 5
#define SPI_FREQUENCY 40000000
#define SPI_READ_FREQUENCY 16000000
#define TFT_HEIGHT 320
#define TFT_WIDTH 240
#define TFT_OFFSET_X 0
#define TFT_OFFSET_Y 0
#define TFT_OFFSET_ROTATION 0
#define SCREEN_ROTATE
#define SCREEN_TRANSITION_FRAMERATE 5
// Picomputer gets a white on black display
#define TFT_MESH COLOR565(0xFF, 0xFF, 0xFF)
#define CANNED_MESSAGE_MODULE_ENABLE 1
#define INPUTBROKER_MATRIX_TYPE 1
#define KEYS_COLS \
{ \
44, 47, 17, 15, 13, 41 \
}
#define KEYS_ROWS \
{ \
12, 16, 42, 18, 14, 7 \
}

View File

@@ -15,6 +15,7 @@
#define TFT_WIDTH 240
#define TFT_OFFSET_X 0
#define TFT_OFFSET_Y 0
#define TFT_OFFSET_ROTATION 0
#define SCREEN_ROTATE
#define SCREEN_TRANSITION_FRAMERATE 5
@@ -26,7 +27,6 @@
#define BUTTON_PIN 0
// #define BUTTON_NEED_PULLUP
#define HAS_GPS 0
#undef GPS_RX_PIN
#undef GPS_TX_PIN
@@ -49,6 +49,7 @@
#define KB_POWERON 10 // must be set to HIGH
#define KB_SLAVE_ADDRESS TDECK_KB_ADDR // 0x55
#define KB_BL_PIN 46 // not used for now
#define CANNED_MESSAGE_MODULE_ENABLE 1
// trackball
#define HAS_TRACKBALL 1
@@ -85,4 +86,4 @@
#define SX126X_RESET LORA_RESET
#define SX126X_E22 // Not really an E22 but TTGO seems to be trying to clone that
// Internally the TTGO module hooks the SX1262-DIO2 in to control the TX/RX switch (which is the default for the sx1262interface
// code)
// code)

View File

@@ -15,6 +15,7 @@
#define TFT_WIDTH 240
#define TFT_OFFSET_X 0
#define TFT_OFFSET_Y 0
#define TFT_OFFSET_ROTATION 2
#define SCREEN_ROTATE
#define SCREEN_TRANSITION_FRAMERATE 5 // fps

View File

@@ -1,4 +1,4 @@
[VERSION]
major = 2
minor = 1
build = 23
minor = 2
build = 3