Compare commits

...

138 Commits

Author SHA1 Message Date
Ben Meadors
82bcd391cd Fix those refs 2022-10-26 16:50:58 -05:00
Thomas Göttgens
058689709f Merge pull request #1864 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-10-26 23:33:49 +02:00
thebentern
23c9fa0b56 [create-pull-request] automated change 2022-10-26 21:29:46 +00:00
Thomas Göttgens
eb29f10634 Merge pull request #1861 from meshtastic/lib-fix
Lib fix + NTP fix
2022-10-26 19:24:20 +02:00
Thomas Göttgens
d5a9e3114a Update ethClient.cpp 2022-10-26 18:37:51 +02:00
Thomas Göttgens
7417729482 debug removed 2022-10-26 18:37:20 +02:00
Thomas Göttgens
d5c407c098 remove accidental commit 2022-10-26 18:36:41 +02:00
Thomas Göttgens
a1256818d9 update library location 2022-10-26 18:25:31 +02:00
Thomas Göttgens
689cec14aa Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-10-26 18:15:07 +02:00
Thomas Göttgens
04225826f6 Bump ConfigDB Version.
this forces a factory reset on upgrade.
2022-10-26 18:12:31 +02:00
Thomas Göttgens
86787e60f3 Merge pull request #1860 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-10-26 17:56:41 +02:00
caveman99
0c3ec9254d [create-pull-request] automated change 2022-10-26 15:56:26 +00:00
Thomas Göttgens
c0770402ce Merge pull request #1855 from meshtastic/remove-softap
Remove Captive Portal and SoftAP Mode
2022-10-26 17:55:45 +02:00
Thomas Göttgens
d7c98062ce Merge remote-tracking branch 'remotes/origin/master' into remove-softap 2022-10-26 17:54:21 +02:00
Thomas Göttgens
497c0b7a47 don't rush failed time updates 2022-10-26 17:38:53 +02:00
Thomas Göttgens
d588dde007 Merge pull request #1842 from meshtastic/RAK13800
Rak13800
2022-10-26 11:33:22 +02:00
Thomas Göttgens
3de0a3adfc Merge branch 'RAK13800' of github.com:meshtastic/Meshtastic-device 2022-10-26 11:10:17 +02:00
Thomas Göttgens
b7ebe03ca8 API Server and DHCP Lease Management 2022-10-26 11:09:59 +02:00
Thomas Göttgens
a7fb88e293 make cppcheck happy about stuff it shouldn't care for 2022-10-26 09:16:54 +02:00
Thomas Göttgens
6e1b1e3ed7 Merge branch 'RAK13800' of github.com:meshtastic/Meshtastic-device 2022-10-26 00:07:33 +02:00
Thomas Göttgens
a66538fe55 MQTT is working over ethernet 2022-10-26 00:07:02 +02:00
Ben Meadors
b2913be086 Merge branch 'master' into RAK13800 2022-10-25 07:04:46 -05:00
Thomas Göttgens
602e65d898 fix non-ESP32 builds 2022-10-25 12:42:08 +02:00
Thomas Göttgens
338c9c1e0c Remove Captive Portal and SoftAP Mode 2022-10-25 11:53:22 +02:00
Thomas Göttgens
9fac57b713 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-10-24 23:11:56 +02:00
Ben Meadors
761804b17a Send network ping on triple-click (#1852)
* Send network ping on multi-press

* Refresh myNodeInfo before sending

* Cleanup and screen print

* Update ButtonThread.h
2022-10-24 11:03:54 -05:00
Ben Meadors
c47401d729 Remove setting fixed pin on double-click (#1851)
* Remove setting fixed pin on double-click

* Remove disablePin method
2022-10-24 07:16:13 -05:00
Thomas Göttgens
aab52f1e8d Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-10-23 16:41:04 +02:00
Ben Meadors
4d2e44d64b Merge branch 'master' into RAK13800 2022-10-22 19:56:12 -05:00
Mykhailo Lesyk
41267a42f7 [rak4630] enable 3.3v periphery before scan for i2c devices (#1847)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2022-10-22 19:55:34 -05:00
Ben Meadors
568434d0fa Use preset wiring (#1845)
* When we init default, set use_preset to true

* Only use modem_preset when we use_preset

* When we init default, set use_preset to true (#1843) (#1844)
2022-10-22 18:51:22 -05:00
Ben Meadors
2c1bbf1ac6 When we init default, set use_preset to true (#1843) 2022-10-22 15:42:21 -05:00
Thomas Göttgens
1e97dcbb4c Portduino is always special. 2022-10-22 16:53:57 +02:00
Thomas Göttgens
103c82bc2c only build on vanilla RAK4631 for now. 2022-10-22 16:42:36 +02:00
Thomas Göttgens
f3fee5f4fb first murmurs of ethernet support 2022-10-22 16:29:50 +02:00
Thomas Göttgens
564feadc0d Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-10-22 16:28:57 +02:00
Thomas Göttgens
f05e0f3a81 Merge pull request #1841 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-10-22 16:20:57 +02:00
caveman99
cb26bc3871 [create-pull-request] automated change 2022-10-22 14:18:18 +00:00
Thomas Göttgens
f6251eef27 Merge pull request #1840 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-10-22 16:17:46 +02:00
thebentern
a9d6ef5990 [create-pull-request] automated change 2022-10-22 13:28:36 +00:00
Thomas Göttgens
60da55d6dd Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-10-22 14:25:43 +02:00
Thomas Göttgens
05147c016c Merge pull request #1839 from meshtastic/pwm-notify
use PWM buzzer on notification module.
2022-10-22 14:25:32 +02:00
Thomas Göttgens
f7655f3abe fix compiler warning 2022-10-22 14:18:47 +02:00
Thomas Göttgens
62b3509009 missed one 2022-10-22 14:13:45 +02:00
Thomas Göttgens
d817889255 don't depend on EXT_NOTIFY_OUT being defined. 2022-10-22 13:45:43 +02:00
Thomas Göttgens
d4ddcdd91e use PWM buzzer on notification module. To activate set moduleConfig.external_notification.output equal to the PIN_BUZZER. If another value is set, the traditional digital mode is used 2022-10-22 13:35:34 +02:00
Thomas Göttgens
0bda4c2f76 Merge pull request #1838 from meshtastic/filebrowser-fix
fix json filebrowser in web server
2022-10-22 12:35:31 +02:00
Thomas Göttgens
be8da851a6 fix json filebrowser in web server 2022-10-22 11:55:01 +02:00
Thomas Göttgens
d4459a48b9 Merge pull request #1831 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-10-21 09:43:30 +02:00
thebentern
197bd2c3e1 [create-pull-request] automated change 2022-10-20 22:04:56 +00:00
Ben Meadors
d4ea9568ac Save devicestate (nodedb) on position config change (#1829) 2022-10-20 13:14:53 -05:00
Ben Meadors
97968213ff Factory reset should include modules and channels (#1828) 2022-10-20 07:51:52 -05:00
Thomas Göttgens
995885962d Merge pull request #1826 from meshtastic/oem-proto
wire in OEM.proto keystore
2022-10-20 09:10:01 +02:00
Ben Meadors
ddc1928bbb Merge branch 'master' into oem-proto 2022-10-19 19:22:35 -05:00
Ben Meadors
056a93f0c9 Consolidate reboots (#1827) 2022-10-19 19:19:04 -05:00
Ben Meadors
3d9845ff6d Update checkout version and release string 2022-10-19 11:43:24 -05:00
Ben Meadors
b615463981 Update download-artifiact version 2022-10-19 11:35:25 -05:00
Ben Meadors
d3540e82ff I think these tokens are extra 2022-10-19 10:44:09 -05:00
Ben Meadors
15ec8ba6a3 Whoops 2022-10-19 08:58:14 -05:00
Ben Meadors
db12eab083 Update setup-python 2022-10-19 08:51:00 -05:00
Thomas Göttgens
7d8c77a4b2 Merge branch 'master' into oem-proto 2022-10-19 15:42:21 +02:00
Thomas Göttgens
7c8c479b96 wire in OEM.proto keystore 2022-10-19 15:39:06 +02:00
Ben Meadors
e29ae1cc91 Update upload-artifact version 2022-10-19 08:11:28 -05:00
Ben Meadors
089dd5b4d7 Update github cache action version 2022-10-19 07:38:44 -05:00
Ben Meadors
06285b599c Update deprecated ::set-output commands 2022-10-19 07:35:16 -05:00
Thomas Göttgens
1b6395b4e4 Merge pull request #1825 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-10-19 13:45:12 +02:00
caveman99
2236f74a55 [create-pull-request] automated change 2022-10-19 11:44:12 +00:00
Thomas Göttgens
43c9ab1faa Merge pull request #1824 from meshtastic/caveman99-patch1
Dont retransmit packets destined for ourselves.
2022-10-19 11:56:44 +02:00
Thomas Göttgens
b56f9b3b16 Dont retransmit packets destined for ourselves.
Solves assert failed: virtual ErrorCode Router::send(MeshPacket*) Router.cpp:189 (p->to != nodeDB.getNodeNum())
2022-10-19 11:44:26 +02:00
Thomas Göttgens
303396dfc3 Merge pull request #1823 from meshtastic/json-cleanup
Json cleanup
2022-10-19 11:20:24 +02:00
Thomas Göttgens
075a53ced0 Update MQTT.cpp 2022-10-19 11:04:13 +02:00
Thomas Göttgens
18ccb38824 Update MQTT.cpp 2022-10-19 11:01:23 +02:00
Thomas Göttgens
c97831963b just for good measure, correct json type field 2022-10-19 10:58:46 +02:00
Thomas Göttgens
7c3dc076d2 only convert and send JSON topics with type 'sendtext' 2022-10-19 10:54:56 +02:00
Thomas Göttgens
b859347ecd Merge pull request #1822 from meshtastic/json-cleanup
possible fix for stuck MQTT handler.
2022-10-19 00:02:00 +02:00
Thomas Göttgens
ea87193c8f possible fix for stuck MQTT handler. 2022-10-18 21:51:40 +02:00
Thomas Göttgens
c1381b9ebd Merge pull request #1818 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-10-18 12:21:02 +02:00
caveman99
227cd93e67 [create-pull-request] automated change 2022-10-18 10:20:06 +00:00
Thomas Göttgens
f68f8e5547 Merge pull request #1817 from meshtastic/json-cleanup
fix JSON red herring error messages and Redirectable Print's new fixed buffer
2022-10-18 11:57:11 +02:00
Thomas Göttgens
943e6f02d4 Merge branch 'master' into json-cleanup 2022-10-18 11:18:34 +02:00
Thomas Göttgens
01298a7b01 Update RedirectablePrint.cpp 2022-10-18 11:18:12 +02:00
Thomas Göttgens
46aee8274f fix JSON red herring error messages and Redirectable Print's new fixed buffer. 2022-10-18 11:16:21 +02:00
Thomas Göttgens
f76a2eeb9e Merge pull request #1816 from meshtastic/wifi-disconnect-fix
If wifi credentials ever go stale, dump them.
2022-10-18 11:15:19 +02:00
Thomas Göttgens
3b7c0be842 don't irritate people with non working options 2022-10-18 10:30:50 +02:00
Thomas Göttgens
49378a9145 If wifi credentials ever go stale, dump them.
This solves the dreaded 5 - STA_DISCONNECTED / 2 - AUTH_EXPIRE loops
2022-10-18 10:16:47 +02:00
Thomas Göttgens
139f61d03e Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-10-17 16:45:28 +02:00
Ben Meadors
f10d04591d Don't make a nested json object payload (#1815) 2022-10-17 09:09:28 -05:00
Thomas Göttgens
e65d9e8ccd Add support for SX1281 on 2.4 GHz (#1809)
* Add support for SX1281 on 2.4 GHz

* only allow wide BW settings when the right chip is detected

* portduino cannot use this chip yet as it uses an old modified version of radiolib

* missed a spot

* Attempt to supress false positive

* Attempt to supress false positive

* Trying casing from the cpp-check manual

* Trying casing from the cpp-check manual

* Inline suppr should be default but...

* Maybe casting it will make the damn thing shut up

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2022-10-17 08:33:41 -05:00
Ben Meadors
1fc3c0af70 Update variant.h (#1814) 2022-10-17 08:07:18 -05:00
Thomas Göttgens
e4751e34ae missed a spot 2022-10-17 10:34:43 +02:00
Thomas Göttgens
e922169e72 Merge branch 'LORA-24' of github.com:meshtastic/Meshtastic-device 2022-10-17 10:32:35 +02:00
Thomas Göttgens
2b851ef6ae Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-10-17 10:32:05 +02:00
Thomas Göttgens
5f4b93aba2 portduino cannot use this chip yet as it uses an old modified version of radiolib 2022-10-17 10:31:29 +02:00
Thomas Göttgens
b66d1a5dab Merge branch 'master' into LORA-24 2022-10-17 10:05:15 +02:00
Thomas Göttgens
867525eff8 Merge pull request #1813 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-10-17 10:05:00 +02:00
caveman99
7dcc981a2c [create-pull-request] automated change 2022-10-17 08:04:36 +00:00
Thomas Göttgens
38fed8a61e Merge branch 'LORA-24' of github.com:meshtastic/Meshtastic-device 2022-10-17 10:00:41 +02:00
Thomas Göttgens
31c2c8a7a3 only allow wide BW settings when the right chip is detected 2022-10-17 10:00:00 +02:00
Thomas Göttgens
a081d28e36 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-10-17 09:45:39 +02:00
Ben Meadors
93bb4f84f9 Merge branch 'master' into LORA-24 2022-10-16 17:27:18 -05:00
github-actions[bot]
72e04edd7f [create-pull-request] automated change (#1812)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2022-10-16 17:26:55 -05:00
Ben Meadors
b0d05522c0 Make telemetry packets minimum priority (#1810) 2022-10-16 15:59:59 -05:00
Thomas Göttgens
f6119639bb Add support for SX1281 on 2.4 GHz 2022-10-16 19:07:58 +02:00
Ben Meadors
fc57a9daa4 Send environment telemetry every minute (#1808) 2022-10-16 11:36:38 -05:00
Thomas Göttgens
d8f44d7b1b Merge pull request #1807 from meshtastic/nmea-serial
Add NMEA output mode to serial module
2022-10-16 17:15:24 +02:00
Ben Meadors
efe2e90a03 Merge branch 'master' into nmea-serial 2022-10-16 09:59:30 -05:00
Ben Meadors
45f9dee89a Telemetry phone api guard (#1805)
* Delay start of telemetry modules

* Don't send unless our toPhoneQueue is empty

* Get wrecked, checks!
2022-10-16 09:58:58 -05:00
Thomas Göttgens
cc73d2c2f2 Sigh... 2022-10-16 16:51:17 +02:00
Thomas Göttgens
b1f789dddd fix cppcheck 2022-10-16 16:45:32 +02:00
Thomas Göttgens
d3e9dbf6a9 Add NMEA output mode (my own position, and other devices as waypoints) to serial module 2022-10-16 16:37:38 +02:00
Thomas Göttgens
44529620ad Merge pull request #1806 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-10-16 16:25:34 +02:00
caveman99
7a9673dc37 [create-pull-request] automated change 2022-10-16 14:24:27 +00:00
Thomas Göttgens
27bcf67c0c add routine to output waypoint data 2022-10-16 12:28:49 +02:00
Ben Meadors
7fde56b8ac Make telemetry logging more concise (#1804)
* Make telemetry logging more concise

* Whoops
2022-10-15 18:48:34 -05:00
Ben Meadors
6b614a2d6a Added LPS22HB (RAK-1902) sensor support (#1802) 2022-10-15 14:55:57 -05:00
Ben Meadors
1e1509fbf5 Use pio registry (#1801) 2022-10-15 12:34:52 -05:00
Ben Meadors
a3e67f8e4b SHTC3 Sensor (RAK-1901) support (#1800) 2022-10-15 09:11:05 -05:00
Ben Meadors
028b25cfe8 Change RTCQuality acceptance criteria (#1797)
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2022-10-14 19:12:55 -05:00
Ben Meadors
2555e082d6 Add nrf52 to serial module registration (#1799)
* Add nrf52 to serial module registration

* Update Modules.cpp

* Update Modules.cpp

* Update Modules.cpp
2022-10-14 11:38:56 -05:00
Thomas Göttgens
f8fa721c72 Merge pull request #1798 from meshtastic/i2cscan
Scan for I2C devices twice on all CPU's
2022-10-14 15:33:46 +02:00
Thomas Göttgens
a7e0127793 scan i2c twice for all devices, not just tbeam 2022-10-13 23:46:25 +02:00
Thomas Göttgens
603f60d86a Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-10-13 19:13:09 +02:00
Thomas Göttgens
6febf6b17c Merge pull request #1796 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-10-13 17:58:41 +02:00
thebentern
53aaf766dd [create-pull-request] automated change 2022-10-13 14:54:05 +00:00
Thomas Göttgens
4fa8d02b08 update FromRadio UUID for nRF52 devices (#1795) 2022-10-13 09:32:54 -05:00
Thomas Göttgens
efa423c8ad update FromRadio UUID for nRF52 devices 2022-10-13 16:20:27 +02:00
Thomas Göttgens
43fb0d80f1 Merge pull request #1794 from meshtastic/canned-spice
Display looks better that way...
2022-10-13 15:56:13 +02:00
Thomas Göttgens
b25ace14e5 Update CannedMessageModule.h 2022-10-13 15:44:27 +02:00
Thomas Göttgens
8734751bc4 make screen timeout work again 2022-10-13 15:31:57 +02:00
Thomas Göttgens
5559a1edb0 Display looks better that way... 2022-10-13 15:22:57 +02:00
Thomas Göttgens
bf503354f3 Merge pull request #1792 from meshtastic/atecca
Support for ATECCA608B Cryptographic Coprocessor
2022-10-13 14:34:44 +02:00
Thomas Göttgens
7b10441a28 update raspberry pi framework some more... 2022-10-13 14:21:48 +02:00
Thomas Göttgens
994e396c00 update Raspberry Pico Framework 2022-10-13 13:57:17 +02:00
Thomas Göttgens
6e22ee9061 make nRF52 happy 2022-10-13 13:31:19 +02:00
Thomas Göttgens
b5fb0f60b0 don't compile on Portduino 2022-10-13 13:01:24 +02:00
Thomas Göttgens
a7fe69ed6b Support for ATECCA608B Cryptographic Coprocessor 2022-10-13 12:55:28 +02:00
Thomas Göttgens
7f05298172 Merge pull request #1790 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-10-13 08:45:13 +02:00
thebentern
92a2505056 [create-pull-request] automated change 2022-10-12 23:42:47 +00:00
83 changed files with 1625 additions and 576 deletions

View File

@@ -57,12 +57,12 @@ jobs:
sudo apt-get install -y cppcheck sudo apt-get install -y cppcheck
- name: Setup Python - name: Setup Python
uses: actions/setup-python@v2 uses: actions/setup-python@v4
with: with:
python-version: 3.x python-version: 3.x
- name: Cache python libs - name: Cache python libs
uses: actions/cache@v1 uses: actions/cache@v3
id: cache-pip # needed in if test id: cache-pip # needed in if test
with: with:
path: ~/.cache/pip path: ~/.cache/pip
@@ -112,12 +112,12 @@ jobs:
repository: ${{github.event.pull_request.head.repo.full_name}} repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Setup Python - name: Setup Python
uses: actions/setup-python@v2 uses: actions/setup-python@v4
with: with:
python-version: 3.x python-version: 3.x
- name: Cache python libs - name: Cache python libs
uses: actions/cache@v1 uses: actions/cache@v3
id: cache-pip # needed in if test id: cache-pip # needed in if test
with: with:
path: ~/.cache/pip path: ~/.cache/pip
@@ -157,11 +157,11 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
- name: Get release version string - name: Get release version string
run: echo "::set-output name=version::$(./bin/buildinfo.py long)" run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version id: version
- name: Store binaries as an artifact - name: Store binaries as an artifact
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v3
with: with:
name: firmware-${{ matrix.board }}-${{ steps.version.outputs.version }}.zip name: firmware-${{ matrix.board }}-${{ steps.version.outputs.version }}.zip
path: | path: |
@@ -190,12 +190,12 @@ jobs:
repository: ${{github.event.pull_request.head.repo.full_name}} repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Setup Python - name: Setup Python
uses: actions/setup-python@v2 uses: actions/setup-python@v4
with: with:
python-version: 3.x python-version: 3.x
- name: Cache python libs - name: Cache python libs
uses: actions/cache@v1 uses: actions/cache@v3
id: cache-pip # needed in if test id: cache-pip # needed in if test
with: with:
path: ~/.cache/pip path: ~/.cache/pip
@@ -214,11 +214,11 @@ jobs:
run: bin/build-nrf52.sh ${{ matrix.board }} run: bin/build-nrf52.sh ${{ matrix.board }}
- name: Get release version string - name: Get release version string
run: echo "::set-output name=version::$(./bin/buildinfo.py long)" run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version id: version
- name: Store binaries as an artifact - name: Store binaries as an artifact
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v3
with: with:
name: firmware-${{ matrix.board }}-${{ steps.version.outputs.version }}.zip name: firmware-${{ matrix.board }}-${{ steps.version.outputs.version }}.zip
path: | path: |
@@ -245,12 +245,12 @@ jobs:
repository: ${{github.event.pull_request.head.repo.full_name}} repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Setup Python - name: Setup Python
uses: actions/setup-python@v2 uses: actions/setup-python@v4
with: with:
python-version: 3.x python-version: 3.x
- name: Cache python libs - name: Cache python libs
uses: actions/cache@v1 uses: actions/cache@v3
id: cache-pip # needed in if test id: cache-pip # needed in if test
with: with:
path: ~/.cache/pip path: ~/.cache/pip
@@ -269,11 +269,11 @@ jobs:
run: ./bin/build-rpi2040.sh ${{ matrix.board }} run: ./bin/build-rpi2040.sh ${{ matrix.board }}
- name: Get release version string - name: Get release version string
run: echo "::set-output name=version::$(./bin/buildinfo.py long)" run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version id: version
- name: Store binaries as an artifact - name: Store binaries as an artifact
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v3
with: with:
name: firmware-${{ matrix.board }}-${{ steps.version.outputs.version }}.zip name: firmware-${{ matrix.board }}-${{ steps.version.outputs.version }}.zip
path: | path: |
@@ -292,12 +292,12 @@ jobs:
repository: ${{github.event.pull_request.head.repo.full_name}} repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Setup Python - name: Setup Python
uses: actions/setup-python@v2 uses: actions/setup-python@v4
with: with:
python-version: 3.x python-version: 3.x
- name: Cache python libs - name: Cache python libs
uses: actions/cache@v1 uses: actions/cache@v3
id: cache-pip # needed in if test id: cache-pip # needed in if test
with: with:
path: ~/.cache/pip path: ~/.cache/pip
@@ -327,11 +327,11 @@ jobs:
run: bin/build-native.sh run: bin/build-native.sh
- name: Get release version string - name: Get release version string
run: echo "::set-output name=version::$(./bin/buildinfo.py long)" run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version id: version
- name: Store binaries as an artifact - name: Store binaries as an artifact
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v3
with: with:
name: firmware-native-${{ steps.version.outputs.version }}.zip name: firmware-native-${{ steps.version.outputs.version }}.zip
path: | path: |
@@ -360,19 +360,19 @@ jobs:
ref: ${{github.event.pull_request.head.ref}} ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}} repository: ${{github.event.pull_request.head.repo.full_name}}
- uses: actions/download-artifact@v2 - uses: actions/download-artifact@v3
with: with:
path: ./ path: ./
- name: Get release version string - name: Get release version string
run: echo "::set-output name=version::$(./bin/buildinfo.py long)" run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version id: version
- name: Move files up - name: Move files up
run: mv -b -t ./ ./*tbeam-1*/littlefs*.bin ./*tbeam-1*/bleota.bin ./**/firmware*.bin ./*t-echo*/Meshtastic_nRF52_factory_erase.uf2 ./**/firmware-*.uf2 ./**/firmware-*-ota.zip ./**/*.elf ./**/meshtasticd_linux_amd64 ./*native*/*device-*.sh ./*native*/*device-*.bat run: mv -b -t ./ ./*tbeam-1*/littlefs*.bin ./*tbeam-1*/bleota.bin ./**/firmware*.bin ./*t-echo*/Meshtastic_nRF52_factory_erase.uf2 ./**/firmware-*.uf2 ./**/firmware-*-ota.zip ./**/*.elf ./**/meshtasticd_linux_amd64 ./*native*/*device-*.sh ./*native*/*device-*.bat
- name: Repackage in single firmware zip - name: Repackage in single firmware zip
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v3
with: with:
name: firmware-${{ steps.version.outputs.version }} name: firmware-${{ steps.version.outputs.version }}
path: | path: |
@@ -384,7 +384,7 @@ jobs:
./device-*.bat ./device-*.bat
retention-days: 90 retention-days: 90
- uses: actions/download-artifact@v2 - uses: actions/download-artifact@v3
with: with:
name: firmware-${{ steps.version.outputs.version }} name: firmware-${{ steps.version.outputs.version }}
path: ./output path: ./output
@@ -402,7 +402,7 @@ jobs:
run: zip -j -r ./firmware-${{ steps.version.outputs.version }}.zip ./output run: zip -j -r ./firmware-${{ steps.version.outputs.version }}.zip ./output
- name: Repackage in single elfs zip - name: Repackage in single elfs zip
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v3
with: with:
name: debug-elfs-${{ steps.version.outputs.version }}.zip name: debug-elfs-${{ steps.version.outputs.version }}.zip
path: ./*.elf path: ./*.elf
@@ -426,18 +426,18 @@ jobs:
needs: [gather-artifacts, after-checks] needs: [gather-artifacts, after-checks]
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: Setup Python - name: Setup Python
uses: actions/setup-python@v2 uses: actions/setup-python@v4
with: with:
python-version: 3.x python-version: 3.x
- name: Get release version string - name: Get release version string
run: echo "::set-output name=version::$(./bin/buildinfo.py long)" run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version id: version
- uses: actions/download-artifact@v2 - uses: actions/download-artifact@v3
with: with:
name: firmware-${{ steps.version.outputs.version }} name: firmware-${{ steps.version.outputs.version }}
path: ./output path: ./output
@@ -450,7 +450,7 @@ jobs:
- name: Zip firmware - name: Zip firmware
run: zip -j -r ./firmware-${{ steps.version.outputs.version }}.zip ./output run: zip -j -r ./firmware-${{ steps.version.outputs.version }}.zip ./output
- uses: actions/download-artifact@v2 - uses: actions/download-artifact@v3
with: with:
name: debug-elfs-${{ steps.version.outputs.version }}.zip name: debug-elfs-${{ steps.version.outputs.version }}.zip
path: ./elfs path: ./elfs
@@ -468,7 +468,7 @@ jobs:
with: with:
draft: true draft: true
prerelease: true prerelease: true
release_name: Meshtastic Device ${{ steps.version.outputs.version }} alpha - Public Preview release_name: Meshtastic Device ${{ steps.version.outputs.version }} Alpha
tag_name: v${{ steps.version.outputs.version }} tag_name: v${{ steps.version.outputs.version }}
body: | body: |
Autogenerated by github action, developer should edit as required before publishing... Autogenerated by github action, developer should edit as required before publishing...

View File

@@ -3,7 +3,7 @@
extends = arduino_base extends = arduino_base
platform = platformio/espressif32@^5.2.0 platform = platformio/espressif32@^5.2.0
build_src_filter = build_src_filter =
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040> ${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040> -<mesh/eth/>
upload_speed = 921600 upload_speed = 921600
debug_init_break = tbreak setup debug_init_break = tbreak setup
monitor_filters = esp32_exception_decoder monitor_filters = esp32_exception_decoder
@@ -33,8 +33,7 @@ lib_deps =
${environmental_base.lib_deps} ${environmental_base.lib_deps}
https://github.com/meshtastic/esp32_https_server.git#657509856ce97e9dddeffb89a559f544faefd5cd https://github.com/meshtastic/esp32_https_server.git#657509856ce97e9dddeffb89a559f544faefd5cd
h2zero/NimBLE-Arduino@^1.4.0 h2zero/NimBLE-Arduino@^1.4.0
arduino-libraries/NTPClient@^3.1.0 https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
lib_ignore = lib_ignore =
segger_rtt segger_rtt

View File

@@ -2,7 +2,7 @@
extends = arduino_base extends = arduino_base
platform = platformio/espressif32@^5.2.0 platform = platformio/espressif32@^5.2.0
build_src_filter = build_src_filter =
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040> ${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040> -<mesh/eth/>
upload_speed = 961200 upload_speed = 961200
monitor_speed = 115200 monitor_speed = 115200
debug_init_break = tbreak setup debug_init_break = tbreak setup
@@ -33,7 +33,6 @@ lib_deps =
${environmental_base.lib_deps} ${environmental_base.lib_deps}
https://github.com/meshtastic/esp32_https_server.git#657509856ce97e9dddeffb89a559f544faefd5cd https://github.com/meshtastic/esp32_https_server.git#657509856ce97e9dddeffb89a559f544faefd5cd
h2zero/NimBLE-Arduino@^1.4.0 h2zero/NimBLE-Arduino@^1.4.0
arduino-libraries/NTPClient@^3.1.0
https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6 https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
lib_ignore = lib_ignore =

View File

@@ -8,7 +8,7 @@ build_flags =
${arduino_base.build_flags} -Wno-unused-variable ${arduino_base.build_flags} -Wno-unused-variable
-Isrc/platform/nrf52 -Isrc/platform/nrf52
build_src_filter = build_src_filter =
${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mqtt/> -<platform/rp2040> ${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mqtt/> -<platform/rp2040> -<mesh/eth/>
lib_ignore = lib_ignore =
BluetoothOTA BluetoothOTA

View File

@@ -7,7 +7,8 @@ build_src_filter =
-<platform/nrf52/> -<platform/nrf52/>
-<platform/stm32wl/> -<platform/stm32wl/>
-<platform/rp2040> -<platform/rp2040>
-<mesh/http/> -<mesh/http/>
-<mesh/eth/>
-<modules/esp32> -<modules/esp32>
-<modules/Telemetry> -<modules/Telemetry>
+<../variants/portduino> +<../variants/portduino>

View File

@@ -1,6 +1,6 @@
; Common settings for rp2040 Processor based targets ; Common settings for rp2040 Processor based targets
[rp2040_base] [rp2040_base]
platform = https://github.com/maxgerhardt/platform-raspberrypi.git platform = https://github.com/maxgerhardt/platform-raspberrypi.git#5ce1a228e7cae453f366deb8962252b9b7356bbc
extends = arduino_base extends = arduino_base
board_build.core = earlephilhower board_build.core = earlephilhower
board_build.filesystem_size = 0.5m board_build.filesystem_size = 0.5m
@@ -10,7 +10,7 @@ build_flags =
-D__PLAT_RP2040__ -D__PLAT_RP2040__
# -D _POSIX_THREADS # -D _POSIX_THREADS
build_src_filter = build_src_filter =
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mqtt/> -<platform/nrf52/> -<platform/stm32wl> ${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mqtt/> -<platform/nrf52/> -<platform/stm32wl> -<mesh/eth/>
lib_ignore = lib_ignore =
BluetoothOTA BluetoothOTA
lib_deps = lib_deps =

View File

@@ -10,7 +10,7 @@ build_flags =
# Arduino/PlatformIO framework-arduinoststm32 package does not presently have SUBGHZSPI support # Arduino/PlatformIO framework-arduinoststm32 package does not presently have SUBGHZSPI support
# -DPIN_SPI_MOSI=PINSUBGHZSPIMOSI -DPIN_SPI_MISO=PINSUBGHZSPIMISO -DPIN_SPI_SCK=PINSUBGHZSPISCK # -DPIN_SPI_MOSI=PINSUBGHZSPIMOSI -DPIN_SPI_MISO=PINSUBGHZSPIMISO -DPIN_SPI_SCK=PINSUBGHZSPISCK
build_src_filter = build_src_filter =
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mqtt/> -<graphics> -<input> -<buzz> -<modules/Telemetry> -<platform/nrf52> -<platform/portduino> -<platform/rp2040> ${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<mqtt/> -<graphics> -<input> -<buzz> -<modules/Telemetry> -<platform/nrf52> -<platform/portduino> -<platform/rp2040>
lib_deps = lib_deps =
${env.lib_deps} ${env.lib_deps}
https://github.com/kokke/tiny-AES-c.git#f06ac37fc31dfdaca2e0d9bec83f90d5663c319b https://github.com/kokke/tiny-AES-c.git#f06ac37fc31dfdaca2e0d9bec83f90d5663c319b

View File

@@ -57,6 +57,9 @@ lib_deps =
; Used for the code analysis in PIO Home / Inspect ; Used for the code analysis in PIO Home / Inspect
check_tool = cppcheck check_tool = cppcheck
check_skip_packages = yes check_skip_packages = yes
check_flags =
--common-flag
cppcheck: --enable=--inline-suppr
; Common settings for conventional (non Portduino) Arduino targets ; Common settings for conventional (non Portduino) Arduino targets
[arduino_base] [arduino_base]
@@ -65,6 +68,7 @@ lib_deps =
${env.lib_deps} ${env.lib_deps}
; Portduino is using meshtastic fork for now ; Portduino is using meshtastic fork for now
jgromes/RadioLib@5.4.1 jgromes/RadioLib@5.4.1
https://github.com/meshtastic/SparkFun_ATECCX08a_Arduino_Library.git#52b5282639d08a8cbd4b748363089eed6102dc76
build_flags = ${env.build_flags} -Os build_flags = ${env.build_flags} -Os
-DRADIOLIB_SPI_PARANOID=0 -DRADIOLIB_SPI_PARANOID=0
@@ -75,6 +79,7 @@ build_src_filter = ${env.build_src_filter} -<platform/portduino/>
[networking_base] [networking_base]
lib_deps = lib_deps =
knolleary/PubSubClient@^2.8 knolleary/PubSubClient@^2.8
arduino-libraries/NTPClient@^3.1.0
meshtastic/json11@^1.0.2 meshtastic/json11@^1.0.2
; Common libs for environmental measurements in telemetry module ; Common libs for environmental measurements in telemetry module
@@ -89,4 +94,5 @@ lib_deps =
adafruit/Adafruit MCP9808 Library@^2.0.0 adafruit/Adafruit MCP9808 Library@^2.0.0
adafruit/Adafruit INA260 Library@^1.5.0 adafruit/Adafruit INA260 Library@^1.5.0
adafruit/Adafruit INA219@^1.2.0 adafruit/Adafruit INA219@^1.2.0
adafruit/Adafruit SHTC3 Library@^1.0.0
adafruit/Adafruit LPS2X@^2.0.4

View File

@@ -7,7 +7,7 @@ const uint8_t MESH_SERVICE_UUID_16[16u] = {0xfd, 0xea, 0x73, 0xe2, 0xca, 0x5d, 0
0x1f, 0x46, 0xa8, 0x15, 0x18, 0xb2, 0xa1, 0x6b}; 0x1f, 0x46, 0xa8, 0x15, 0x18, 0xb2, 0xa1, 0x6b};
const uint8_t TORADIO_UUID_16[16u] = {0xe7, 0x01, 0x44, 0x12, 0x66, 0x78, 0xdd, 0xa1, const uint8_t TORADIO_UUID_16[16u] = {0xe7, 0x01, 0x44, 0x12, 0x66, 0x78, 0xdd, 0xa1,
0xad, 0x4d, 0x9e, 0x12, 0xd2, 0x76, 0x5c, 0xf7}; 0xad, 0x4d, 0x9e, 0x12, 0xd2, 0x76, 0x5c, 0xf7};
const uint8_t FROMRADIO_UUID_16[16u] = {0xd5, 0x54, 0xe4, 0xc5, 0x25, 0xc5, 0x31, 0xa5, const uint8_t FROMRADIO_UUID_16[16u] = {0x02, 0x00, 0x12, 0xac, 0x42, 0x02, 0x78, 0xb8,
0x55, 0x4a, 0x02, 0xee, 0xc2, 0xbc, 0xa2, 0x8b}; 0xed, 0x11, 0x93, 0x49, 0x9e, 0xe6, 0x55, 0x2c};
const uint8_t FROMNUM_UUID_16[16u] = {0x53, 0x44, 0xe3, 0x47, 0x75, 0xaa, 0x70, 0xa6, const uint8_t FROMNUM_UUID_16[16u] = {0x53, 0x44, 0xe3, 0x47, 0x75, 0xaa, 0x70, 0xa6,
0x66, 0x4f, 0x00, 0xa8, 0x8c, 0xa1, 0x9d, 0xed}; 0x66, 0x4f, 0x00, 0xa8, 0x8c, 0xa1, 0x9d, 0xed};

View File

@@ -159,21 +159,16 @@ class ButtonThread : public concurrency::OSThread
static void userButtonDoublePressed() static void userButtonDoublePressed()
{ {
#ifdef ARCH_ESP32 #if defined(USE_EINK)
disablePin();
#elif defined(USE_EINK)
digitalWrite(PIN_EINK_EN, digitalRead(PIN_EINK_EN) == LOW); digitalWrite(PIN_EINK_EN, digitalRead(PIN_EINK_EN) == LOW);
#endif #endif
} }
static void userButtonMultiPressed() static void userButtonMultiPressed()
{ {
#ifdef ARCH_ESP32 screen->print("Sent ad-hoc ping\n");
clearNVS(); service.refreshMyNodeInfo();
#endif service.sendNetworkPing(NODENUM_BROADCAST, true);
#ifdef ARCH_NRF52
clearBonds();
#endif
} }
static void userButtonPressedLongStart() static void userButtonPressedLongStart()

View File

@@ -44,10 +44,15 @@ size_t RedirectablePrint::vprintf(const char *format, va_list arg)
static char printBuf[160]; static char printBuf[160];
va_copy(copy, arg); va_copy(copy, arg);
int len = vsnprintf(printBuf, sizeof(printBuf), format, copy); size_t len = vsnprintf(printBuf, sizeof(printBuf), format, copy);
va_end(copy); va_end(copy);
if (len < 0) return 0; // If the resulting string is longer than sizeof(printBuf)-1 characters, the remaining characters are still counted for the return value
if (len > sizeof(printBuf) - 1) {
len = sizeof(printBuf) - 1;
printBuf[sizeof(printBuf) - 2] = '\n';
}
len = Print::write(printBuf, len); len = Print::write(printBuf, len);
return len; return len;
@@ -103,4 +108,4 @@ size_t RedirectablePrint::logDebug(const char *format, ...)
} }
return r; return r;
} }

View File

@@ -1,5 +1,6 @@
#include "buzz.h" #include "buzz.h"
#include "configuration.h" #include "configuration.h"
#include "NodeDB.h"
#ifndef PIN_BUZZER #ifndef PIN_BUZZER
@@ -42,17 +43,19 @@ const int DURATION_1_8 = 125; // 1/8 note
const int DURATION_1_4 = 250; // 1/4 note const int DURATION_1_4 = 250; // 1/4 note
void playTones(const ToneDuration *tone_durations, int size) { void playTones(const ToneDuration *tone_durations, int size) {
for (int i = 0; i < size; i++) { if (config.network.eth_enabled != true) {
const auto &tone_duration = tone_durations[i]; for (int i = 0; i < size; i++) {
const auto &tone_duration = tone_durations[i];
#ifdef M5STACK #ifdef M5STACK
Tone.tone(tone_duration.frequency_khz); Tone.tone(tone_duration.frequency_khz);
delay(tone_duration.duration_ms); delay(tone_duration.duration_ms);
Tone.mute(); Tone.mute();
#else #else
tone(PIN_BUZZER, tone_duration.frequency_khz, tone_duration.duration_ms); tone(PIN_BUZZER, tone_duration.frequency_khz, tone_duration.duration_ms);
#endif #endif
// to distinguish the notes, set a minimum time between them. // to distinguish the notes, set a minimum time between them.
delay(1.3 * tone_duration.duration_ms); delay(1.3 * tone_duration.duration_ms);
}
} }
} }

View File

@@ -110,6 +110,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define INA_ADDR_ALTERNATE 0x41 #define INA_ADDR_ALTERNATE 0x41
#define QMC6310_ADDR 0x1C #define QMC6310_ADDR 0x1C
#define QMI8658_ADDR 0x6B #define QMI8658_ADDR 0x6B
#define SHTC3_ADDR 0x70
#define LPS22HB_ADDR 0x5C
#define LPS22HB_ADDR_ALT 0x5D
// -----------------------------------------------------------------------------
// Security
// -----------------------------------------------------------------------------
#define ATECC608B_ADDR 0x35
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// GPS // GPS
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@@ -132,6 +142,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef HAS_WIFI #ifndef HAS_WIFI
#define HAS_WIFI 0 #define HAS_WIFI 0
#endif #endif
#ifndef HAS_ETHERNET
#define ETHERNET 0
#endif
#ifndef HAS_SCREEN #ifndef HAS_SCREEN
#define HAS_SCREEN 0 #define HAS_SCREEN 0
#endif #endif

View File

@@ -9,6 +9,41 @@
#endif #endif
#if HAS_WIRE #if HAS_WIRE
void printATECCInfo()
{
#ifndef ARCH_PORTDUINO
atecc.readConfigZone(false);
DEBUG_MSG("ATECC608B Serial Number: ");
for (int i = 0 ; i < 9 ; i++) {
DEBUG_MSG("%02x",atecc.serialNumber[i]);
}
DEBUG_MSG(", Rev Number: ");
for (int i = 0 ; i < 4 ; i++) {
DEBUG_MSG("%02x",atecc.revisionNumber[i]);
}
DEBUG_MSG("\n");
DEBUG_MSG("ATECC608B Config %s",atecc.configLockStatus ? "Locked" : "Unlocked");
DEBUG_MSG(", Data %s",atecc.dataOTPLockStatus ? "Locked" : "Unlocked");
DEBUG_MSG(", Slot 0 %s\n",atecc.slot0LockStatus ? "Locked" : "Unlocked");
if (atecc.configLockStatus && atecc.dataOTPLockStatus && atecc.slot0LockStatus) {
if (atecc.generatePublicKey() == false) {
DEBUG_MSG("ATECC608B Error generating public key\n");
} else {
DEBUG_MSG("ATECC608B Public Key: ");
for (int i = 0 ; i < 64 ; i++) {
DEBUG_MSG("%02x",atecc.publicKey64Bytes[i]);
}
DEBUG_MSG("\n");
}
}
#endif
}
uint16_t getRegisterValue(uint8_t address, uint8_t reg, uint8_t length) { uint16_t getRegisterValue(uint8_t address, uint8_t reg, uint8_t length) {
uint16_t value = 0x00; uint16_t value = 0x00;
Wire.beginTransmission(address); Wire.beginTransmission(address);
@@ -79,6 +114,17 @@ void scanI2Cdevice(void)
DEBUG_MSG("unknown display found\n"); DEBUG_MSG("unknown display found\n");
} }
} }
#ifndef ARCH_PORTDUINO
if (addr == ATECC608B_ADDR){
keystore_found = addr;
if (atecc.begin(keystore_found) == true) {
DEBUG_MSG("ATECC608B initialized\n");
} else {
DEBUG_MSG("ATECC608B initialization failed\n");
}
printATECCInfo();
}
#endif
#ifdef RV3028_RTC #ifdef RV3028_RTC
if (addr == RV3028_RTC){ if (addr == RV3028_RTC){
rtc_found = addr; rtc_found = addr;
@@ -145,14 +191,22 @@ void scanI2Cdevice(void)
nodeTelemetrySensorsMap[TelemetrySensorType_MCP9808] = addr; nodeTelemetrySensorsMap[TelemetrySensorType_MCP9808] = addr;
DEBUG_MSG("MCP9808 sensor found at address 0x%x\n", (uint8_t)addr); DEBUG_MSG("MCP9808 sensor found at address 0x%x\n", (uint8_t)addr);
} }
if(addr == QMC6310_ADDR){ if (addr == QMC6310_ADDR) {
DEBUG_MSG("QMC6310 3-Axis magnetic sensor found at address 0x%x\n", (uint8_t)addr); DEBUG_MSG("QMC6310 3-Axis magnetic sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_QMC6310] = addr; nodeTelemetrySensorsMap[TelemetrySensorType_QMC6310] = addr;
} }
if(addr == QMI8658_ADDR){ if (addr == QMI8658_ADDR) {
DEBUG_MSG("QMI8658 6-Axis inertial measurement sensor found at address 0x%x\n", (uint8_t)addr); DEBUG_MSG("QMI8658 6-Axis inertial measurement sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_QMI8658] = addr; nodeTelemetrySensorsMap[TelemetrySensorType_QMI8658] = addr;
} }
if (addr == SHTC3_ADDR) {
DEBUG_MSG("SHTC3 sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_SHTC3] = addr;
}
if (addr == LPS22HB_ADDR || addr == LPS22HB_ADDR_ALT) {
DEBUG_MSG("LPS22HB sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_LPS22] = addr;
}
} else if (err == 4) { } else if (err == 4) {
DEBUG_MSG("Unknow error at address 0x%x\n", addr); DEBUG_MSG("Unknow error at address 0x%x\n", addr);
} }

76
src/gps/NMEAWPL.cpp Normal file
View File

@@ -0,0 +1,76 @@
#include "NMEAWPL.h"
/* -------------------------------------------
* 1 2 3 4 5 6
* | | | | | |
* $--WPL,llll.ll,a,yyyyy.yy,a,c--c*hh<CR><LF>
*
* Field Number:
* 1 Latitude
* 2 N or S (North or South)
* 3 Longitude
* 4 E or W (East or West)
* 5 Waypoint name
* 6 Checksum
* -------------------------------------------
*/
uint printWPL(char *buf, const Position &pos, const char *name)
{
uint len = sprintf(buf, "$GNWPL,%07.2f,%c,%08.2f,%c,%s", pos.latitude_i * 1e-5, pos.latitude_i < 0 ? 'S' : 'N', pos.longitude_i * 1e-5, pos.longitude_i < 0 ? 'W' : 'E', name);
uint chk = 0;
for (uint i = 1; i < len; i++) {
chk ^= buf[i];
}
len += sprintf(buf + len, "*%02X\r\n", chk);
return len;
}
/* -------------------------------------------
* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
* | | | | | | | | | | | | | | |
* $--GGA,hhmmss.ss,ddmm.mm,a,ddmm.mm,a,x,xx,x.x,x.x,M,x.x,M,x.x,xxxx*hh<CR><LF>
*
* Field Number:
* 1 UTC of this position report, hh is hours, mm is minutes, ss.ss is seconds.
* 2 Latitude
* 3 N or S (North or South)
* 4 Longitude
* 5 E or W (East or West)
* 6 GPS Quality Indicator (non null)
* 7 Number of satellites in use, 00 - 12
* 8 Horizontal Dilution of precision (meters)
* 9 Antenna Altitude above/below mean-sea-level (geoid) (in meters)
* 10 Units of antenna altitude, meters
* 11 Geoidal separation, the difference between the WGS-84 earth ellipsoid and mean-sea-level (geoid), "-" means mean-sea-level below ellipsoid
* 12 Units of geoidal separation, meters
* 13 Age of differential GPS data, time in seconds since last SC104 type 1 or 9 update, null field when DGPS is not used
* 14 Differential reference station ID, 0000-1023
* 15 Checksum
* -------------------------------------------
*/
uint printGGA(char *buf, const Position &pos)
{
uint len = sprintf(buf, "$GNGGA,%06u.%03u,%07.2f,%c,%08.2f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d",
pos.time / 1000,
pos.time % 1000,
pos.latitude_i * 1e-5, pos.latitude_i < 0 ? 'S' : 'N',
pos.longitude_i * 1e-5, pos.longitude_i < 0 ? 'W' : 'E',
pos.fix_type,
pos.sats_in_view,
pos.HDOP,
pos.altitude,
'M',
pos.altitude_geoidal_separation,
'M',
0,
0);
uint chk = 0;
for (uint i = 1; i < len; i++) {
chk ^= buf[i];
}
len += sprintf(buf + len, "*%02X\r\n", chk);
return len;
}

7
src/gps/NMEAWPL.h Normal file
View File

@@ -0,0 +1,7 @@
#pragma once
#include <Arduino.h>
#include "main.h"
uint printWPL(char *buf, const Position &pos, const char *name);
uint printGGA(char *buf, const Position &pos);

View File

@@ -16,7 +16,7 @@ enum RTCQuality {
RTCQualityFromNet = 2, RTCQualityFromNet = 2,
/// Our time is based on NTP /// Our time is based on NTP
RTCQualityNTP= 3, RTCQualityNTP = 3,
/// Our time is based on our own GPS /// Our time is based on our own GPS
RTCQualityGPS = 4 RTCQualityGPS = 4

View File

@@ -84,10 +84,6 @@ static char ourId[5];
// GeoCoord object for the screen // GeoCoord object for the screen
GeoCoord geoCoord; GeoCoord geoCoord;
// OEM Config File
static const char *oemConfigFile = "/oem/oem.proto";
OEMStore oemStore;
#ifdef SHOW_REDRAWS #ifdef SHOW_REDRAWS
static bool heartbeat = false; static bool heartbeat = false;
#endif #endif
@@ -928,9 +924,6 @@ void Screen::setup()
dispdev.setDetected(screen_model); dispdev.setDetected(screen_model);
#endif #endif
// Load OEM config from Proto file if existent
loadProto(oemConfigFile, OEMStore_size, sizeof(oemConfigFile), OEMStore_fields, &oemStore);
// Initialising the UI will init the display too. // Initialising the UI will init the display too.
ui.init(); ui.init();
@@ -1397,7 +1390,6 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
{ {
#if HAS_WIFI #if HAS_WIFI
const char *wifiName = config.network.wifi_ssid; const char *wifiName = config.network.wifi_ssid;
const char *wifiPsw = config.network.wifi_psk;
displayedNodeNum = 0; // Not currently showing a node pane displayedNodeNum = 0; // Not currently showing a node pane
@@ -1406,11 +1398,7 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
// The coordinates define the left starting point of the text // The coordinates define the left starting point of the text
display->setTextAlignment(TEXT_ALIGN_LEFT); display->setTextAlignment(TEXT_ALIGN_LEFT);
if (isSoftAPForced()) { if (WiFi.status() != WL_CONNECTED) {
display->drawString(x, y, String("WiFi: Software AP (Admin)"));
} else if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT || config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN) {
display->drawString(x, y, String("WiFi: Software AP"));
} else if (WiFi.status() != WL_CONNECTED) {
display->drawString(x, y, String("WiFi: Not Connected")); display->drawString(x, y, String("WiFi: Not Connected"));
} else { } else {
display->drawString(x, y, String("WiFi: Connected")); display->drawString(x, y, String("WiFi: Connected"));
@@ -1431,25 +1419,14 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
- WL_NO_SHIELD: assigned when no WiFi shield is present; - WL_NO_SHIELD: assigned when no WiFi shield is present;
*/ */
if (WiFi.status() == WL_CONNECTED || isSoftAPForced() || config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT || config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN) { if (WiFi.status() == WL_CONNECTED) {
if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT || config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN || isSoftAPForced()) { display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "IP: " + String(WiFi.localIP().toString().c_str()));
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "IP: " + String(WiFi.softAPIP().toString().c_str()));
// Number of connections to the AP. Default max for the esp32 is 4
display->drawString(x + SCREEN_WIDTH - display->getStringWidth("(" + String(WiFi.softAPgetStationNum()) + "/4)"),
y + FONT_HEIGHT_SMALL * 1, "(" + String(WiFi.softAPgetStationNum()) + "/4)");
} else {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "IP: " + String(WiFi.localIP().toString().c_str()));
}
} else if (WiFi.status() == WL_NO_SSID_AVAIL) { } else if (WiFi.status() == WL_NO_SSID_AVAIL) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "SSID Not Found"); display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "SSID Not Found");
} else if (WiFi.status() == WL_CONNECTION_LOST) { } else if (WiFi.status() == WL_CONNECTION_LOST) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Connection Lost"); display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Connection Lost");
} else if (WiFi.status() == WL_CONNECT_FAILED) { } else if (WiFi.status() == WL_CONNECT_FAILED) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Connection Failed"); display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Connection Failed");
//} else if (WiFi.status() == WL_DISCONNECTED) {
// display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Disconnected");
} else if (WiFi.status() == WL_IDLE_STATUS) { } else if (WiFi.status() == WL_IDLE_STATUS) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Idle ... Reconnecting"); display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Idle ... Reconnecting");
} else { } else {
@@ -1516,24 +1493,8 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
} }
} }
if (isSoftAPForced()) { display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "SSID: " + String(wifiName));
if ((millis() / 10000) % 2) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "SSID: meshtasticAdmin");
} else {
display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "PWD: 12345678");
}
} else {
if (config.network.wifi_mode== Config_NetworkConfig_WiFiMode_ACCESS_POINT || config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN) {
if ((millis() / 10000) % 2) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "SSID: " + String(wifiName));
} else {
display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "PWD: " + String(wifiPsw));
}
} else {
display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "SSID: " + String(wifiName));
}
}
display->drawString(x, y + FONT_HEIGHT_SMALL * 3, "http://meshtastic.local"); display->drawString(x, y + FONT_HEIGHT_SMALL * 3, "http://meshtastic.local");
/* Display a heartbeat pixel that blinks every time the frame is redrawn */ /* Display a heartbeat pixel that blinks every time the frame is redrawn */

View File

@@ -30,6 +30,7 @@
// #include <driver/rtc_io.h> // #include <driver/rtc_io.h>
#include "mesh/http/WiFiAPClient.h" #include "mesh/http/WiFiAPClient.h"
#include "mesh/eth/ethClient.h"
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
#include "mesh/http/WebServer.h" #include "mesh/http/WebServer.h"
@@ -41,10 +42,16 @@
#include "mqtt/MQTT.h" #include "mqtt/MQTT.h"
#endif #endif
#if HAS_ETHERNET
#include "mesh/eth/ethServerAPI.h"
#include "mqtt/MQTT.h"
#endif
#include "LLCC68Interface.h" #include "LLCC68Interface.h"
#include "RF95Interface.h" #include "RF95Interface.h"
#include "SX1262Interface.h" #include "SX1262Interface.h"
#include "SX1268Interface.h" #include "SX1268Interface.h"
#include "SX1281Interface.h"
#if !HAS_RADIO && defined(ARCH_PORTDUINO) #if !HAS_RADIO && defined(ARCH_PORTDUINO)
#include "platform/portduino/SimRadio.h" #include "platform/portduino/SimRadio.h"
#endif #endif
@@ -80,6 +87,14 @@ uint8_t kb_model;
// The I2C address of the RTC Module (if found) // The I2C address of the RTC Module (if found)
uint8_t rtc_found; uint8_t rtc_found;
bool rIf_wide_lora = false;
// Keystore Chips
uint8_t keystore_found;
#ifndef ARCH_PORTDUINO
ATECCX08A atecc;
#endif
bool eink_found = true; bool eink_found = true;
uint32_t serialSinceMsec; uint32_t serialSinceMsec;
@@ -182,8 +197,6 @@ void setup()
digitalWrite(RESET_OLED, 1); digitalWrite(RESET_OLED, 1);
#endif #endif
bool forceSoftAP = 0;
#ifdef BUTTON_PIN #ifdef BUTTON_PIN
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
@@ -196,12 +209,6 @@ void setup()
delay(10); delay(10);
#endif #endif
// BUTTON_PIN is pulled high by a 12k resistor.
if (!digitalRead(BUTTON_PIN)) {
forceSoftAP = 1;
DEBUG_MSG("Setting forceSoftAP = 1\n");
}
#endif #endif
#endif #endif
@@ -233,6 +240,12 @@ void setup()
delay(1); delay(1);
#endif #endif
#ifdef RAK4630
// We need to enable 3.3V periphery in order to scan it
pinMode(PIN_3V3_EN, OUTPUT);
digitalWrite(PIN_3V3_EN, 1);
#endif
// We need to scan here to decide if we have a screen for nodeDB.init() // We need to scan here to decide if we have a screen for nodeDB.init()
scanI2Cdevice(); scanI2Cdevice();
#ifdef RAK4630 #ifdef RAK4630
@@ -263,11 +276,12 @@ void setup()
#ifdef ARCH_NRF52 #ifdef ARCH_NRF52
nrf52Setup(); nrf52Setup();
#endif #endif
playStartMelody();
// We do this as early as possible because this loads preferences from flash // 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 iniot (esp32setup), because we need the random seed set
nodeDB.init(); nodeDB.init();
playStartMelody();
// Currently only the tbeam has a PMU // Currently only the tbeam has a PMU
power = new Power(); power = new Power();
power->setStatusHandler(powerStatus); power->setStatusHandler(powerStatus);
@@ -275,12 +289,10 @@ void setup()
power->setup(); // Must be after status handler is installed, so that handler gets notified of the initial configuration power->setup(); // Must be after status handler is installed, so that handler gets notified of the initial configuration
/* /*
* Repeat the scanning for I2C devices after power initialization. * Repeat the scanning for I2C devices after power initialization or look for 'latecomers'.
* Boards with an PMU need to be powered on to correctly scan to the device address, such as t-beam-s3-core * Boards with an PMU need to be powered on to correctly scan to the device address, such as t-beam-s3-core
*/ */
if ((HW_VENDOR == HardwareModel_LILYGO_TBEAM_S3_CORE) || (HW_VENDOR == HardwareModel_TBEAM)) { scanI2Cdevice();
scanI2Cdevice();
}
// Init our SPI controller (must be before screen and lora) // Init our SPI controller (must be before screen and lora)
initSPI(); initSPI();
@@ -360,6 +372,20 @@ void setup()
} }
#endif #endif
#if defined(USE_SX1281) && !defined(ARCH_PORTDUINO)
if (!rIf) {
rIf = new SX1281Interface(SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY, SPI);
if (!rIf->init()) {
DEBUG_MSG("Warning: Failed to find SX1281 radio\n");
delete rIf;
rIf = NULL;
} else {
DEBUG_MSG("SX1281 Radio init succeeded, using SX1281 radio\n");
rIf_wide_lora = true;
}
}
#endif
#if defined(USE_SX1262) #if defined(USE_SX1262)
if (!rIf) { if (!rIf) {
rIf = new SX1262Interface(SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY, SPI); rIf = new SX1262Interface(SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY, SPI);
@@ -412,12 +438,17 @@ void setup()
} }
#endif #endif
#if HAS_WIFI #if HAS_WIFI || HAS_ETHERNET
mqttInit(); mqttInit();
#endif #endif
#ifndef ARCH_PORTDUINO
// Initialize Wifi // Initialize Wifi
initWifi(forceSoftAP); initWifi();
// Initialize Ethernet
initEthernet();
#endif
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
// Start web server thread. // Start web server thread.

View File

@@ -6,18 +6,27 @@
#include "PowerStatus.h" #include "PowerStatus.h"
#include "graphics/Screen.h" #include "graphics/Screen.h"
#include "mesh/generated/telemetry.pb.h" #include "mesh/generated/telemetry.pb.h"
#ifndef ARCH_PORTDUINO
#include <SparkFun_ATECCX08a_Arduino_Library.h>
#endif
extern uint8_t screen_found; extern uint8_t screen_found;
extern uint8_t screen_model; extern uint8_t screen_model;
extern uint8_t cardkb_found; extern uint8_t cardkb_found;
extern uint8_t kb_model; extern uint8_t kb_model;
extern uint8_t rtc_found; extern uint8_t rtc_found;
extern uint8_t keystore_found;
extern bool rIf_wide_lora;
extern bool eink_found; extern bool eink_found;
extern bool pmu_found; extern bool pmu_found;
extern bool isCharging; extern bool isCharging;
extern bool isUSBPowered; extern bool isUSBPowered;
#ifndef ARCH_PORTDUINO
extern ATECCX08A atecc;
#endif
extern uint8_t nodeTelemetrySensorsMap[TelemetrySensorType_QMI8658+1]; extern uint8_t nodeTelemetrySensorsMap[TelemetrySensorType_QMI8658+1];
extern int TCPPort; // set by Portduino extern int TCPPort; // set by Portduino

View File

@@ -62,13 +62,6 @@ Channel &Channels::fixupChannel(ChannelIndex chIndex)
// Convert the old string "Default" to our new short representation // Convert the old string "Default" to our new short representation
if (strcmp(channelSettings.name, "Default") == 0) if (strcmp(channelSettings.name, "Default") == 0)
*channelSettings.name = '\0'; *channelSettings.name = '\0';
/* Convert any old usage of the defaultpsk into our new short representation.
if (channelSettings.psk.size == sizeof(defaultpsk) &&
memcmp(channelSettings.psk.bytes, defaultpsk, sizeof(defaultpsk)) == 0) {
*channelSettings.psk.bytes = 1;
channelSettings.psk.size = 1;
} */
} }
hashes[chIndex] = generateHash(chIndex); hashes[chIndex] = generateHash(chIndex);
@@ -86,7 +79,7 @@ void Channels::initDefaultChannel(ChannelIndex chIndex)
Config_LoRaConfig &loraConfig = config.lora; Config_LoRaConfig &loraConfig = config.lora;
loraConfig.modem_preset = Config_LoRaConfig_ModemPreset_LONG_FAST; // Default to Long Range & Fast loraConfig.modem_preset = Config_LoRaConfig_ModemPreset_LONG_FAST; // Default to Long Range & Fast
loraConfig.use_preset = true;
loraConfig.tx_power = 0; // default loraConfig.tx_power = 0; // default
uint8_t defaultpskIndex = 1; uint8_t defaultpskIndex = 1;
channelSettings.psk.bytes[0] = defaultpskIndex; channelSettings.psk.bytes[0] = defaultpskIndex;
@@ -124,7 +117,22 @@ CryptoKey Channels::getKey(ChannelIndex chIndex)
DEBUG_MSG("Expanding short PSK #%d\n", pskIndex); DEBUG_MSG("Expanding short PSK #%d\n", pskIndex);
if (pskIndex == 0) if (pskIndex == 0)
k.length = 0; // Turn off encryption k.length = 0; // Turn off encryption
else { else if (oemStore.oem_aes_key.size > 1) {
// Use the OEM key
DEBUG_MSG("Using OEM Key with %d bytes\n", oemStore.oem_aes_key.size);
memcpy(k.bytes, oemStore.oem_aes_key.bytes , oemStore.oem_aes_key.size);
k.length = oemStore.oem_aes_key.size;
// Bump up the last byte of PSK as needed
uint8_t *last = k.bytes + oemStore.oem_aes_key.size - 1;
*last = *last + pskIndex - 1; // index of 1 means no change vs defaultPSK
if (k.length < 16) {
DEBUG_MSG("Warning: OEM provided a too short AES128 key - padding\n");
k.length = 16;
} else if (k.length < 32 && k.length != 16) {
DEBUG_MSG("Warning: OEM provided a too short AES256 key - padding\n");
k.length = 32;
}
} else {
memcpy(k.bytes, defaultpsk, sizeof(defaultpsk)); memcpy(k.bytes, defaultpsk, sizeof(defaultpsk));
k.length = sizeof(defaultpsk); k.length = sizeof(defaultpsk);
// Bump up the last byte of PSK as needed // Bump up the last byte of PSK as needed

View File

@@ -1,7 +1,13 @@
#include "SX126xInterface.h" #include "SX126xInterface.h"
#include "SX126xInterface.cpp" #include "SX126xInterface.cpp"
#include "SX128xInterface.h"
#include "SX128xInterface.cpp"
// We need this declaration for proper linking in derived classes // We need this declaration for proper linking in derived classes
template class SX126xInterface<SX1262>; template class SX126xInterface<SX1262>;
template class SX126xInterface<SX1268>; template class SX126xInterface<SX1268>;
template class SX126xInterface<LLCC68>; template class SX126xInterface<LLCC68>;
#if !defined(ARCH_PORTDUINO)
template class SX128xInterface<SX1281>;
#endif

View File

@@ -15,6 +15,7 @@ struct RegionInfo {
uint8_t powerLimit; // Or zero for not set uint8_t powerLimit; // Or zero for not set
bool audioPermitted; bool audioPermitted;
bool freqSwitching; bool freqSwitching;
bool wideLora;
const char *name; // EU433 etc const char *name; // EU433 etc
}; };

View File

@@ -283,3 +283,8 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
return 0; return 0;
} }
bool MeshService::isToPhoneQueueEmpty()
{
return toPhoneQueue.isEmpty();
}

View File

@@ -89,6 +89,8 @@ class MeshService
/// Send a packet to the phone /// Send a packet to the phone
void sendToPhone(MeshPacket *p); void sendToPhone(MeshPacket *p);
bool isToPhoneQueueEmpty();
private: private:
/// Called when our gps position has changed - updates nodedb and sends Location message out into the mesh /// Called when our gps position has changed - updates nodedb and sends Location message out into the mesh
/// returns 0 to allow futher processing /// returns 0 to allow futher processing

View File

@@ -38,6 +38,7 @@ MyNodeInfo &myNodeInfo = devicestate.my_node;
LocalConfig config; LocalConfig config;
LocalModuleConfig moduleConfig; LocalModuleConfig moduleConfig;
ChannelFile channelFile; ChannelFile channelFile;
OEMStore oemStore;
/** The current change # for radio settings. Starts at 0 on boot and any time the radio settings /** The current change # for radio settings. Starts at 0 on boot and any time the radio settings
* might have changed is incremented. Allows others to detect they might now be on a new channel. * might have changed is incremented. Allows others to detect they might now be on a new channel.
@@ -129,6 +130,8 @@ bool NodeDB::factoryReset()
// second, install default state (this will deal with the duplicate mac address issue) // second, install default state (this will deal with the duplicate mac address issue)
installDefaultDeviceState(); installDefaultDeviceState();
installDefaultConfig(); installDefaultConfig();
installDefaultModuleConfig();
installDefaultChannels();
// third, write everything to disk // third, write everything to disk
saveToDisk(); saveToDisk();
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
@@ -354,6 +357,8 @@ static const char *prefFileName = "/prefs/db.proto";
static const char *configFileName = "/prefs/config.proto"; static const char *configFileName = "/prefs/config.proto";
static const char *moduleConfigFileName = "/prefs/module.proto"; static const char *moduleConfigFileName = "/prefs/module.proto";
static const char *channelFileName = "/prefs/channels.proto"; static const char *channelFileName = "/prefs/channels.proto";
static const char *oemConfigFile = "/oem/oem.proto";
/** Load a protobuf from a file, return true for success */ /** Load a protobuf from a file, return true for success */
bool loadProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, void *dest_struct) bool loadProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, void *dest_struct)
@@ -433,6 +438,9 @@ void NodeDB::loadFromDisk()
DEBUG_MSG("Loaded saved channelFile version %d\n", channelFile.version); DEBUG_MSG("Loaded saved channelFile version %d\n", channelFile.version);
} }
} }
if (loadProto(oemConfigFile, OEMStore_size, sizeof(OEMStore), OEMStore_fields, &oemStore))
DEBUG_MSG("Loaded OEMStore\n");
} }
/** Save a protobuf from a file, return true for success */ /** Save a protobuf from a file, return true for success */

View File

@@ -18,7 +18,7 @@ DeviceState versions used to be defined in the .proto file but really only this
#define SEGMENT_DEVICESTATE 4 #define SEGMENT_DEVICESTATE 4
#define SEGMENT_CHANNELS 8 #define SEGMENT_CHANNELS 8
#define DEVICESTATE_CUR_VER 19 #define DEVICESTATE_CUR_VER 20
#define DEVICESTATE_MIN_VER DEVICESTATE_CUR_VER #define DEVICESTATE_MIN_VER DEVICESTATE_CUR_VER
extern DeviceState devicestate; extern DeviceState devicestate;
@@ -26,6 +26,7 @@ extern ChannelFile channelFile;
extern MyNodeInfo &myNodeInfo; extern MyNodeInfo &myNodeInfo;
extern LocalConfig config; extern LocalConfig config;
extern LocalModuleConfig moduleConfig; extern LocalModuleConfig moduleConfig;
extern OEMStore oemStore;
extern User &owner; extern User &owner;
/// Given a node, return how many seconds in the past (vs now) that we last heard from it /// Given a node, return how many seconds in the past (vs now) that we last heard from it

View File

@@ -6,15 +6,16 @@
#include "Router.h" #include "Router.h"
#include "assert.h" #include "assert.h"
#include "configuration.h" #include "configuration.h"
#include "main.h"
#include "sleep.h" #include "sleep.h"
#include <assert.h> #include <assert.h>
#include <pb_decode.h> #include <pb_decode.h>
#include <pb_encode.h> #include <pb_encode.h>
#define RDEF(name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, frequency_switching) \ #define RDEF(name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, frequency_switching, wide_lora) \
{ \ { \
Config_LoRaConfig_RegionCode_##name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, \ Config_LoRaConfig_RegionCode_##name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, \
frequency_switching, #name \ frequency_switching, wide_lora, #name \
} }
const RegionInfo regions[] = { const RegionInfo regions[] = {
@@ -22,12 +23,12 @@ const RegionInfo regions[] = {
https://link.springer.com/content/pdf/bbm%3A978-1-4842-4357-2%2F1.pdf https://link.springer.com/content/pdf/bbm%3A978-1-4842-4357-2%2F1.pdf
https://www.thethingsnetwork.org/docs/lorawan/regional-parameters/ https://www.thethingsnetwork.org/docs/lorawan/regional-parameters/
*/ */
RDEF(US, 902.0f, 928.0f, 100, 0, 30, true, false), RDEF(US, 902.0f, 928.0f, 100, 0, 30, true, false, false),
/* /*
https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
*/ */
RDEF(EU_433, 433.0f, 434.0f, 10, 0, 12, true, false), RDEF(EU_433, 433.0f, 434.0f, 10, 0, 12, true, false, false),
/* /*
https://www.thethingsnetwork.org/docs/lorawan/duty-cycle/ https://www.thethingsnetwork.org/docs/lorawan/duty-cycle/
@@ -43,23 +44,23 @@ const RegionInfo regions[] = {
(Please refer to section 4.21 in the following document) (Please refer to section 4.21 in the following document)
https://ec.europa.eu/growth/tools-databases/tris/index.cfm/ro/search/?trisaction=search.detail&year=2021&num=528&dLang=EN https://ec.europa.eu/growth/tools-databases/tris/index.cfm/ro/search/?trisaction=search.detail&year=2021&num=528&dLang=EN
*/ */
RDEF(EU_868, 869.4f, 869.65f, 10, 0, 27, false, false), RDEF(EU_868, 869.4f, 869.65f, 10, 0, 27, false, false, false),
/* /*
https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
*/ */
RDEF(CN, 470.0f, 510.0f, 100, 0, 19, true, false), RDEF(CN, 470.0f, 510.0f, 100, 0, 19, true, false, false),
/* /*
https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
*/ */
RDEF(JP, 920.8f, 927.8f, 100, 0, 16, true, false), RDEF(JP, 920.8f, 927.8f, 100, 0, 16, true, false, false),
/* /*
https://www.iot.org.au/wp/wp-content/uploads/2016/12/IoTSpectrumFactSheet.pdf https://www.iot.org.au/wp/wp-content/uploads/2016/12/IoTSpectrumFactSheet.pdf
https://iotalliance.org.nz/wp-content/uploads/sites/4/2019/05/IoT-Spectrum-in-NZ-Briefing-Paper.pdf https://iotalliance.org.nz/wp-content/uploads/sites/4/2019/05/IoT-Spectrum-in-NZ-Briefing-Paper.pdf
*/ */
RDEF(ANZ, 915.0f, 928.0f, 100, 0, 30, true, false), RDEF(ANZ, 915.0f, 928.0f, 100, 0, 30, true, false, false),
/* /*
https://digital.gov.ru/uploaded/files/prilozhenie-12-k-reshenyu-gkrch-18-46-03-1.pdf https://digital.gov.ru/uploaded/files/prilozhenie-12-k-reshenyu-gkrch-18-46-03-1.pdf
@@ -67,38 +68,44 @@ const RegionInfo regions[] = {
Note: Note:
- We do LBT, so 100% is allowed. - We do LBT, so 100% is allowed.
*/ */
RDEF(RU, 868.7f, 869.2f, 100, 0, 20, true, false), RDEF(RU, 868.7f, 869.2f, 100, 0, 20, true, false, false),
/* /*
??? ???
*/ */
RDEF(KR, 920.0f, 923.0f, 100, 0, 0, true, false), RDEF(KR, 920.0f, 923.0f, 100, 0, 0, true, false, false),
/* /*
??? ???
*/ */
RDEF(TW, 920.0f, 925.0f, 100, 0, 0, true, false), RDEF(TW, 920.0f, 925.0f, 100, 0, 0, true, false, false),
/* /*
https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
*/ */
RDEF(IN, 865.0f, 867.0f, 100, 0, 30, true, false), RDEF(IN, 865.0f, 867.0f, 100, 0, 30, true, false, false),
/* /*
https://rrf.rsm.govt.nz/smart-web/smart/page/-smart/domain/licence/LicenceSummary.wdk?id=219752 https://rrf.rsm.govt.nz/smart-web/smart/page/-smart/domain/licence/LicenceSummary.wdk?id=219752
https://iotalliance.org.nz/wp-content/uploads/sites/4/2019/05/IoT-Spectrum-in-NZ-Briefing-Paper.pdf https://iotalliance.org.nz/wp-content/uploads/sites/4/2019/05/IoT-Spectrum-in-NZ-Briefing-Paper.pdf
*/ */
RDEF(NZ_865, 864.0f, 868.0f, 100, 0, 0, true, false), RDEF(NZ_865, 864.0f, 868.0f, 100, 0, 0, true, false, false),
/* /*
https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
*/ */
RDEF(TH, 920.0f, 925.0f, 100, 0, 16, true, false), RDEF(TH, 920.0f, 925.0f, 100, 0, 16, true, false, false),
/*
2.4 GHZ WLAN Band equivalent. Only for SX128x chips.
*/
RDEF(LORA_24, 2400.0f, 2483.5f, 100, 0, 10, true, false, true),
/* /*
This needs to be last. Same as US. This needs to be last. Same as US.
*/ */
RDEF(UNSET, 902.0f, 928.0f, 100, 0, 30, true, false) RDEF(UNSET, 902.0f, 928.0f, 100, 0, 30, true, false, false)
}; };
@@ -354,40 +361,41 @@ void RadioInterface::applyModemConfig()
// Set up default configuration // Set up default configuration
// No Sync Words in LORA mode // No Sync Words in LORA mode
Config_LoRaConfig &loraConfig = config.lora; Config_LoRaConfig &loraConfig = config.lora;
if (loraConfig.spread_factor == 0) { if (loraConfig.use_preset) {
switch (loraConfig.modem_preset) { switch (loraConfig.modem_preset) {
case Config_LoRaConfig_ModemPreset_SHORT_FAST: case Config_LoRaConfig_ModemPreset_SHORT_FAST:
bw = 250; bw = (myRegion->wideLora && rIf_wide_lora) ? 800 : 250;
cr = 8; cr = 8;
sf = 7; sf = 7;
break; break;
case Config_LoRaConfig_ModemPreset_SHORT_SLOW: case Config_LoRaConfig_ModemPreset_SHORT_SLOW:
bw = 250; bw = (myRegion->wideLora && rIf_wide_lora) ? 800 : 250;
cr = 8; cr = 8;
sf = 8; sf = 8;
break; break;
case Config_LoRaConfig_ModemPreset_MEDIUM_FAST: case Config_LoRaConfig_ModemPreset_MEDIUM_FAST:
bw = 250; bw = (myRegion->wideLora && rIf_wide_lora) ? 800 : 250;
cr = 8; cr = 8;
sf = 9; sf = 9;
break; break;
case Config_LoRaConfig_ModemPreset_MEDIUM_SLOW: case Config_LoRaConfig_ModemPreset_MEDIUM_SLOW:
bw = 250; bw = (myRegion->wideLora && rIf_wide_lora) ? 800 : 250;
cr = 8; cr = 8;
sf = 10; sf = 10;
break; break;
case Config_LoRaConfig_ModemPreset_LONG_FAST: case Config_LoRaConfig_ModemPreset_LONG_FAST:
bw = 250; bw = (myRegion->wideLora && rIf_wide_lora) ? 800 : 250;
cr = 8; cr = 8;
sf = 11; sf = 11;
break; break;
case Config_LoRaConfig_ModemPreset_LONG_SLOW: case Config_LoRaConfig_ModemPreset_LONG_SLOW:
bw = 125; bw = (myRegion->wideLora && rIf_wide_lora) ? 400 : 125;
cr = 8; cr = 8;
sf = 12; sf = 12;
break; break;
case Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW: case Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW:
bw = 31.25; bw = (myRegion->wideLora && rIf_wide_lora) ? 200 : 31.25;
cr = 8; cr = 8;
sf = 12; sf = 12;
break; break;
@@ -415,7 +423,7 @@ void RadioInterface::applyModemConfig()
power = 17; // Default to default power if we don't have a valid power power = 17; // Default to default power if we don't have a valid power
// Set final tx_power back onto config // Set final tx_power back onto config
loraConfig.tx_power = power; loraConfig.tx_power = (int8_t)power; // cppcheck-suppress assignmentAddressToInteger
// Calculate the number of channels // Calculate the number of channels
uint32_t numChannels = floor((myRegion->freqEnd - myRegion->freqStart) / (myRegion->spacing + (bw / 1000))); uint32_t numChannels = floor((myRegion->freqEnd - myRegion->freqStart) / (myRegion->spacing + (bw / 1000)));

View File

@@ -63,7 +63,7 @@ bool ReliableRouter::shouldFilterReceived(MeshPacket *p)
sendAckNak(Routing_Error_NONE, getFrom(p), p->id, p->channel); sendAckNak(Routing_Error_NONE, getFrom(p), p->id, p->channel);
DEBUG_MSG("acking a repeated want_ack packet\n"); DEBUG_MSG("acking a repeated want_ack packet\n");
} }
} else if (wasSeenRecently(p, false) && p->hop_limit == HOP_RELIABLE && !MeshModule::currentReply) { } else if (wasSeenRecently(p, false) && p->hop_limit == HOP_RELIABLE && !MeshModule::currentReply && p->to != nodeDB.getNodeNum()) {
// retransmission on broadcast has hop_limit still equal to HOP_RELIABLE // retransmission on broadcast has hop_limit still equal to HOP_RELIABLE
DEBUG_MSG("Resending implicit ack for a repeated floodmsg\n"); DEBUG_MSG("Resending implicit ack for a repeated floodmsg\n");
MeshPacket *tosend = packetPool.allocCopy(*p); MeshPacket *tosend = packetPool.allocCopy(*p);

View File

@@ -0,0 +1,13 @@
#include "configuration.h"
#include "SX1281Interface.h"
#include "error.h"
#if !defined(ARCH_PORTDUINO)
SX1281Interface::SX1281Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
SPIClass &spi)
: SX128xInterface(cs, irq, rst, busy, spi)
{
}
#endif

View File

@@ -0,0 +1,17 @@
#pragma once
#include "SX128xInterface.h"
/**
* Our adapter for SX1281 radios
*/
#if !defined(ARCH_PORTDUINO)
class SX1281Interface : public SX128xInterface<SX1281>
{
public:
SX1281Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi);
};
#endif

View File

@@ -0,0 +1,247 @@
#include "configuration.h"
#include "SX128xInterface.h"
#include "error.h"
#if !defined(ARCH_PORTDUINO)
// Particular boards might define a different max power based on what their hardware can do
#ifndef SX128X_MAX_POWER
#define SX128X_MAX_POWER 22
#endif
template<typename T>
SX128xInterface<T>::SX128xInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
SPIClass &spi)
: RadioLibInterface(cs, irq, rst, busy, spi, &lora), lora(&module)
{
}
/// Initialise the Driver transport hardware and software.
/// Make sure the Driver is properly configured before calling init().
/// \return true if initialisation succeeded.
template<typename T>
bool SX128xInterface<T>::init()
{
#ifdef SX128X_POWER_EN
digitalWrite(SX128X_POWER_EN, HIGH);
pinMode(SX128X_POWER_EN, OUTPUT);
#endif
#ifdef SX128X_RXEN // set not rx or tx mode
digitalWrite(SX128X_RXEN, LOW); // Set low before becoming an output
pinMode(SX128X_RXEN, OUTPUT);
#endif
#ifdef SX128X_TXEN
digitalWrite(SX128X_TXEN, LOW);
pinMode(SX128X_TXEN, OUTPUT);
#endif
RadioLibInterface::init();
if (power == 0)
power = SX128X_MAX_POWER;
if (power > SX128X_MAX_POWER) // This chip has lower power limits than some
power = SX128X_MAX_POWER;
limitPower();
int res = lora.begin(getFreq(), bw, sf, cr, syncWord, power, preambleLength);
// \todo Display actual typename of the adapter, not just `SX128x`
DEBUG_MSG("SX128x init result %d\n", res);
DEBUG_MSG("Frequency set to %f\n", getFreq());
DEBUG_MSG("Bandwidth set to %f\n", bw);
DEBUG_MSG("Power output set to %d\n", power);
#ifdef SX128X_TXEN
// lora.begin sets Dio2 as RF switch control, which is not true if we are manually controlling RX and TX
if (res == RADIOLIB_ERR_NONE)
res = lora.setDio2AsRfSwitch(true);
#endif
if (res == RADIOLIB_ERR_NONE)
res = lora.setCRC(RADIOLIB_SX128X_LORA_CRC_ON);
if (res == RADIOLIB_ERR_NONE)
startReceive(); // start receiving
return res == RADIOLIB_ERR_NONE;
}
template<typename T>
bool SX128xInterface<T>::reconfigure()
{
RadioLibInterface::reconfigure();
// set mode to standby
setStandby();
// configure publicly accessible settings
int err = lora.setSpreadingFactor(sf);
if (err != RADIOLIB_ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING);
err = lora.setBandwidth(bw);
if (err != RADIOLIB_ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING);
err = lora.setCodingRate(cr);
if (err != RADIOLIB_ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING);
// Hmm - seems to lower SNR when the signal levels are high. Leaving off for now...
// TODO: Confirm gain registers are okay now
// err = lora.setRxGain(true);
// assert(err == RADIOLIB_ERR_NONE);
err = lora.setSyncWord(syncWord);
assert(err == RADIOLIB_ERR_NONE);
err = lora.setPreambleLength(preambleLength);
assert(err == RADIOLIB_ERR_NONE);
err = lora.setFrequency(getFreq());
if (err != RADIOLIB_ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING);
if (power > 22) // This chip has lower power limits than some
power = 22;
err = lora.setOutputPower(power);
assert(err == RADIOLIB_ERR_NONE);
startReceive(); // restart receiving
return RADIOLIB_ERR_NONE;
}
template<typename T>
void INTERRUPT_ATTR SX128xInterface<T>::disableInterrupt()
{
lora.clearDio1Action();
}
template<typename T>
void SX128xInterface<T>::setStandby()
{
checkNotification(); // handle any pending interrupts before we force standby
int err = lora.standby();
assert(err == RADIOLIB_ERR_NONE);
#ifdef SX128X_RXEN // we have RXEN/TXEN control - turn off RX and TX power
digitalWrite(SX128X_RXEN, LOW);
#endif
#ifdef SX128X_TXEN
digitalWrite(SX128X_TXEN, LOW);
#endif
isReceiving = false; // If we were receiving, not any more
disableInterrupt();
completeSending(); // If we were sending, not anymore
}
/**
* Add SNR data to received messages
*/
template<typename T>
void SX128xInterface<T>::addReceiveMetadata(MeshPacket *mp)
{
// DEBUG_MSG("PacketStatus %x\n", lora.getPacketStatus());
mp->rx_snr = lora.getSNR();
mp->rx_rssi = lround(lora.getRSSI());
}
/** We override to turn on transmitter power as needed.
*/
template<typename T>
void SX128xInterface<T>::configHardwareForSend()
{
#ifdef SX128X_TXEN // we have RXEN/TXEN control - turn on TX power / off RX power
digitalWrite(SX128X_TXEN, HIGH);
#endif
#ifdef SX128X_RXEN
digitalWrite(SX128X_RXEN, LOW);
#endif
RadioLibInterface::configHardwareForSend();
}
// For power draw measurements, helpful to force radio to stay sleeping
// #define SLEEP_ONLY
template<typename T>
void SX128xInterface<T>::startReceive()
{
#ifdef SLEEP_ONLY
sleep();
#else
setStandby();
#ifdef SX128X_RXEN // we have RXEN/TXEN control - turn on RX power / off TX power
digitalWrite(SX128X_RXEN, HIGH);
#endif
#ifdef SX128X_TXEN
digitalWrite(SX128X_TXEN, LOW);
#endif
int err = lora.startReceive();
assert(err == RADIOLIB_ERR_NONE);
isReceiving = true;
// Must be done AFTER, starting transmit, because startTransmit clears (possibly stale) interrupt pending register bits
enableInterrupt(isrRxLevel0);
#endif
}
/** Could we send right now (i.e. either not actively receving or transmitting)? */
template<typename T>
bool SX128xInterface<T>::isChannelActive()
{
// check if we can detect a LoRa preamble on the current channel
int16_t result;
setStandby();
result = lora.scanChannel();
if (result == RADIOLIB_PREAMBLE_DETECTED)
return true;
assert(result != RADIOLIB_ERR_WRONG_MODEM);
return false;
}
/** Could we send right now (i.e. either not actively receving or transmitting)? */
template<typename T>
bool SX128xInterface<T>::isActivelyReceiving()
{
return isChannelActive();
}
template<typename T>
bool SX128xInterface<T>::sleep()
{
// Not keeping config is busted - next time nrf52 board boots lora sending fails tcxo related? - see datasheet
// \todo Display actual typename of the adapter, not just `SX128x`
DEBUG_MSG("SX128x entering sleep mode (FIXME, don't keep config)\n");
setStandby(); // Stop any pending operations
// turn off TCXO if it was powered
// FIXME - this isn't correct
// lora.setTCXO(0);
// put chipset into sleep mode (we've already disabled interrupts by now)
bool keepConfig = true;
lora.sleep(keepConfig); // Note: we do not keep the config, full reinit will be needed
#ifdef SX128X_POWER_EN
digitalWrite(SX128X_POWER_EN, LOW);
#endif
return true;
}
#endif

View File

@@ -0,0 +1,75 @@
#pragma once
#if !defined(ARCH_PORTDUINO)
#include "RadioLibInterface.h"
/**
* \brief Adapter for SX128x radio family. Implements common logic for child classes.
* \tparam T RadioLib module type for SX128x: SX1281.
*/
template<class T>
class SX128xInterface : public RadioLibInterface
{
public:
SX128xInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi);
/// Initialise the Driver transport hardware and software.
/// Make sure the Driver is properly configured before calling init().
/// \return true if initialisation succeeded.
virtual bool init() override;
/// Apply any radio provisioning changes
/// Make sure the Driver is properly configured before calling init().
/// \return true if initialisation succeeded.
virtual bool reconfigure() override;
/// Prepare hardware for sleep. Call this _only_ for deep sleep, not needed for light sleep.
virtual bool sleep() override;
protected:
float currentLimit = 140; // Higher OCP limit for SX128x PA
/**
* Specific module instance
*/
T lora;
/**
* Glue functions called from ISR land
*/
virtual void disableInterrupt() override;
/**
* Enable a particular ISR callback glue function
*/
virtual void enableInterrupt(void (*callback)()) { lora.setDio1Action(callback); }
/** can we detect a LoRa preamble on the current channel? */
virtual bool isChannelActive() override;
/** are we actively receiving a packet (only called during receiving state) */
virtual bool isActivelyReceiving() override;
/**
* Start waiting to receive a message
*/
virtual void startReceive() override;
/**
* We override to turn on transmitter power as needed.
*/
virtual void configHardwareForSend() override;
/**
* Add SNR data to received messages
*/
virtual void addReceiveMetadata(MeshPacket *mp) override;
virtual void setStandby() override;
private:
};
#endif

148
src/mesh/eth/ethClient.cpp Normal file
View File

@@ -0,0 +1,148 @@
#include "mesh/eth/ethClient.h"
#include "NodeDB.h"
#include "RTC.h"
#include "concurrency/Periodic.h"
#include <SPI.h>
#include <RAK13800_W5100S.h>
#include "target_specific.h"
#include "mesh/eth/ethServerAPI.h"
#include "mqtt/MQTT.h"
#ifndef DISABLE_NTP
#include <NTPClient.h>
// NTP
EthernetUDP ntpUDP;
NTPClient timeClient(ntpUDP, config.network.ntp_server);
uint32_t ntp_renew = 0;
#endif
bool ethStartupComplete = 0;
using namespace concurrency;
static Periodic *ethEvent;
static int32_t reconnectETH()
{
if (config.network.eth_enabled) {
Ethernet.maintain();
if (!ethStartupComplete) {
// Start web server
DEBUG_MSG("... Starting network services\n");
#ifndef DISABLE_NTP
DEBUG_MSG("Starting NTP time client\n");
timeClient.begin();
timeClient.setUpdateInterval(60 * 60); // Update once an hour
#endif
// initWebServer();
initApiServer();
ethStartupComplete = true;
}
// FIXME this is kinda yucky, instead we should just have an observable for 'wifireconnected'
if (mqtt && !mqtt->connected()) {
mqtt->reconnect();
}
}
#ifndef DISABLE_NTP
if (isEthernetAvailable() && (ntp_renew < millis())) {
DEBUG_MSG("Updating NTP time from %s\n", config.network.ntp_server);
if (timeClient.update()) {
DEBUG_MSG("NTP Request Success - Setting RTCQualityNTP if needed\n");
struct timeval tv;
tv.tv_sec = timeClient.getEpochTime();
tv.tv_usec = 0;
perhapsSetRTC(RTCQualityNTP, &tv);
ntp_renew = millis() + 43200 * 1000; // success, refresh every 12 hours
} else {
DEBUG_MSG("NTP Update failed\n");
ntp_renew = millis() + 300 * 1000; // failure, retry every 5 minutes
}
}
#endif
return 5000; // every 5 seconds
}
// Startup Ethernet
bool initEthernet()
{
if (config.network.eth_enabled) {
#ifdef PIN_ETHERNET_RESET
pinMode(PIN_ETHERNET_RESET, OUTPUT);
digitalWrite(PIN_ETHERNET_RESET, LOW); // Reset Time.
delay(100);
digitalWrite(PIN_ETHERNET_RESET, HIGH); // Reset Time.
#endif
Ethernet.init( ETH_SPI_PORT, PIN_ETHERNET_SS );
uint8_t mac[6];
int status = 0;
// createSSLCert();
getMacAddr(mac); // FIXME use the BLE MAC for now...
if (config.network.eth_mode == Config_NetworkConfig_EthMode_DHCP) {
DEBUG_MSG("starting Ethernet DHCP\n");
status = Ethernet.begin(mac);
} else if (config.network.eth_mode == Config_NetworkConfig_EthMode_STATIC) {
DEBUG_MSG("starting Ethernet Static\n");
Ethernet.begin(mac, config.network.ipv4_config.ip, config.network.ipv4_config.dns, config.network.ipv4_config.subnet);
} else {
DEBUG_MSG("Ethernet Disabled\n");
return false;
}
if (status == 0) {
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
DEBUG_MSG("Ethernet shield was not found.\n");
return false;
} else if (Ethernet.linkStatus() == LinkOFF) {
DEBUG_MSG("Ethernet cable is not connected.\n");
return false;
} else{
DEBUG_MSG("Unknown Ethernet error.\n");
return false;
}
} else {
DEBUG_MSG("Local IP %u.%u.%u.%u\n",Ethernet.localIP()[0], Ethernet.localIP()[1], Ethernet.localIP()[2], Ethernet.localIP()[3]);
DEBUG_MSG("Subnet Mask %u.%u.%u.%u\n",Ethernet.subnetMask()[0], Ethernet.subnetMask()[1], Ethernet.subnetMask()[2], Ethernet.subnetMask()[3]);
DEBUG_MSG("Gateway IP %u.%u.%u.%u\n",Ethernet.gatewayIP()[0], Ethernet.gatewayIP()[1], Ethernet.gatewayIP()[2], Ethernet.gatewayIP()[3]);
DEBUG_MSG("DNS Server IP %u.%u.%u.%u\n",Ethernet.dnsServerIP()[0], Ethernet.dnsServerIP()[1], Ethernet.dnsServerIP()[2], Ethernet.dnsServerIP()[3]);
}
ethEvent = new Periodic("ethConnect", reconnectETH);
return true;
} else {
DEBUG_MSG("Not using Ethernet\n");
return false;
}
}
bool isEthernetAvailable() {
if (!config.network.eth_enabled) {
return false;
} else if (Ethernet.hardwareStatus() == EthernetNoHardware) {
return false;
} else if (Ethernet.linkStatus() == LinkOFF) {
return false;
} else {
return true;
}
}

8
src/mesh/eth/ethClient.h Normal file
View File

@@ -0,0 +1,8 @@
#pragma once
#include "configuration.h"
#include <Arduino.h>
#include <functional>
bool initEthernet();
bool isEthernetAvailable();

View File

@@ -0,0 +1,82 @@
#include "ethServerAPI.h"
#include "configuration.h"
#include <Arduino.h>
static ethServerPort *apiPort;
void initApiServer(int port)
{
// Start API server on port 4403
if (!apiPort) {
apiPort = new ethServerPort(port);
DEBUG_MSG("API server listening on TCP port %d\n", port);
apiPort->init();
}
}
ethServerAPI::ethServerAPI(EthernetClient &_client) : StreamAPI(&client), client(_client)
{
DEBUG_MSG("Incoming ethernet connection\n");
}
ethServerAPI::~ethServerAPI()
{
client.stop();
// FIXME - delete this if the client dropps the connection!
}
/// override close to also shutdown the TCP link
void ethServerAPI::close()
{
client.stop(); // drop tcp connection
StreamAPI::close();
}
/// Check the current underlying physical link to see if the client is currently connected
bool ethServerAPI::checkIsConnected()
{
return client.connected();
}
int32_t ethServerAPI::runOnce()
{
if (client.connected()) {
return StreamAPI::runOnce();
} else {
DEBUG_MSG("Client dropped connection, suspending API service\n");
enabled = false; // we no longer need to run
return 0;
}
}
/// If an api server is running, we try to spit out debug 'serial' characters there
void ethServerPort::debugOut(char c)
{
if (apiPort && apiPort->openAPI)
apiPort->openAPI->debugOut(c);
}
ethServerPort::ethServerPort(int port) : EthernetServer(port), concurrency::OSThread("ApiServer") {}
void ethServerPort::init()
{
begin();
}
int32_t ethServerPort::runOnce()
{
auto client = available();
if (client) {
// Close any previous connection (see FIXME in header file)
if (openAPI) {
DEBUG_MSG("Force closing previous TCP connection\n");
delete openAPI;
}
openAPI = new ethServerAPI(client);
}
return 100; // only check occasionally for incoming connections
}

View File

@@ -0,0 +1,58 @@
#pragma once
#include "StreamAPI.h"
#include <RAK13800_W5100S.h>
/**
* Provides both debug printing and, if the client starts sending protobufs to us, switches to send/receive protobufs
* (and starts dropping debug printing - FIXME, eventually those prints should be encapsulated in protobufs).
*/
class ethServerAPI : public StreamAPI
{
private:
EthernetClient client;
public:
explicit ethServerAPI(EthernetClient &_client);
virtual ~ethServerAPI();
/// override close to also shutdown the TCP link
virtual void close();
protected:
/// We override this method to prevent publishing EVENT_SERIAL_CONNECTED/DISCONNECTED for wifi links (we want the board to
/// stay in the POWERED state to prevent disabling wifi)
virtual void onConnectionChanged(bool connected) override {}
virtual int32_t runOnce() override; // Check for dropped client connections
/// Check the current underlying physical link to see if the client is currently connected
virtual bool checkIsConnected() override;
};
/**
* Listens for incoming connections and does accepts and creates instances of WiFiServerAPI as needed
*/
class ethServerPort : public EthernetServer, private concurrency::OSThread
{
/** The currently open port
*
* FIXME: We currently only allow one open TCP connection at a time, because we depend on the loop() call in this class to
* delegate to the worker. Once coroutines are implemented we can relax this restriction.
*/
ethServerAPI *openAPI = NULL;
public:
explicit ethServerPort(int port);
void init();
/// If an api server is running, we try to spit out debug 'serial' characters there
static void debugOut(char c);
protected:
int32_t runOnce() override;
};
void initApiServer(int port=4403);

View File

@@ -54,7 +54,7 @@ extern const pb_msgdesc_t ChannelSet_msg;
#define ChannelSet_fields &ChannelSet_msg #define ChannelSet_fields &ChannelSet_msg
/* Maximum encoded size of messages (where known) */ /* Maximum encoded size of messages (where known) */
#define ChannelSet_size 581 #define ChannelSet_size 582
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */

View File

@@ -21,6 +21,9 @@ PB_BIND(Config_PowerConfig, Config_PowerConfig, AUTO)
PB_BIND(Config_NetworkConfig, Config_NetworkConfig, AUTO) PB_BIND(Config_NetworkConfig, Config_NetworkConfig, AUTO)
PB_BIND(Config_NetworkConfig_IpV4Config, Config_NetworkConfig_IpV4Config, AUTO)
PB_BIND(Config_DisplayConfig, Config_DisplayConfig, AUTO) PB_BIND(Config_DisplayConfig, Config_DisplayConfig, AUTO)
@@ -39,3 +42,4 @@ PB_BIND(Config_BluetoothConfig, Config_BluetoothConfig, AUTO)

View File

@@ -37,6 +37,11 @@ typedef enum _Config_NetworkConfig_WiFiMode {
Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN = 2 Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN = 2
} Config_NetworkConfig_WiFiMode; } Config_NetworkConfig_WiFiMode;
typedef enum _Config_NetworkConfig_EthMode {
Config_NetworkConfig_EthMode_DHCP = 0,
Config_NetworkConfig_EthMode_STATIC = 1
} Config_NetworkConfig_EthMode;
typedef enum _Config_DisplayConfig_GpsCoordinateFormat { typedef enum _Config_DisplayConfig_GpsCoordinateFormat {
Config_DisplayConfig_GpsCoordinateFormat_DEC = 0, Config_DisplayConfig_GpsCoordinateFormat_DEC = 0,
Config_DisplayConfig_GpsCoordinateFormat_DMS = 1, Config_DisplayConfig_GpsCoordinateFormat_DMS = 1,
@@ -64,7 +69,8 @@ typedef enum _Config_LoRaConfig_RegionCode {
Config_LoRaConfig_RegionCode_RU = 9, Config_LoRaConfig_RegionCode_RU = 9,
Config_LoRaConfig_RegionCode_IN = 10, Config_LoRaConfig_RegionCode_IN = 10,
Config_LoRaConfig_RegionCode_NZ_865 = 11, Config_LoRaConfig_RegionCode_NZ_865 = 11,
Config_LoRaConfig_RegionCode_TH = 12 Config_LoRaConfig_RegionCode_TH = 12,
Config_LoRaConfig_RegionCode_LORA_24 = 13
} Config_LoRaConfig_RegionCode; } Config_LoRaConfig_RegionCode;
typedef enum _Config_LoRaConfig_ModemPreset { typedef enum _Config_LoRaConfig_ModemPreset {
@@ -116,18 +122,17 @@ typedef struct _Config_LoRaConfig {
uint32_t hop_limit; uint32_t hop_limit;
bool tx_enabled; bool tx_enabled;
int8_t tx_power; int8_t tx_power;
uint8_t channel_num; uint16_t channel_num;
pb_size_t ignore_incoming_count; pb_size_t ignore_incoming_count;
uint32_t ignore_incoming[3]; uint32_t ignore_incoming[3];
} Config_LoRaConfig; } Config_LoRaConfig;
typedef struct _Config_NetworkConfig { typedef struct _Config_NetworkConfig_IpV4Config {
bool wifi_enabled; uint32_t ip;
Config_NetworkConfig_WiFiMode wifi_mode; uint32_t gateway;
char wifi_ssid[33]; uint32_t subnet;
char wifi_psk[64]; uint32_t dns;
char ntp_server[33]; } Config_NetworkConfig_IpV4Config;
} Config_NetworkConfig;
typedef struct _Config_PositionConfig { typedef struct _Config_PositionConfig {
uint32_t position_broadcast_secs; uint32_t position_broadcast_secs;
@@ -150,6 +155,17 @@ typedef struct _Config_PowerConfig {
uint32_t min_wake_secs; uint32_t min_wake_secs;
} Config_PowerConfig; } Config_PowerConfig;
typedef struct _Config_NetworkConfig {
bool wifi_enabled;
char wifi_ssid[33];
char wifi_psk[64];
char ntp_server[33];
bool eth_enabled;
Config_NetworkConfig_EthMode eth_mode;
bool has_ipv4_config;
Config_NetworkConfig_IpV4Config ipv4_config;
} Config_NetworkConfig;
typedef struct _Config { typedef struct _Config {
pb_size_t which_payload_variant; pb_size_t which_payload_variant;
union { union {
@@ -177,6 +193,10 @@ typedef struct _Config {
#define _Config_NetworkConfig_WiFiMode_MAX Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN #define _Config_NetworkConfig_WiFiMode_MAX Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN
#define _Config_NetworkConfig_WiFiMode_ARRAYSIZE ((Config_NetworkConfig_WiFiMode)(Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN+1)) #define _Config_NetworkConfig_WiFiMode_ARRAYSIZE ((Config_NetworkConfig_WiFiMode)(Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN+1))
#define _Config_NetworkConfig_EthMode_MIN Config_NetworkConfig_EthMode_DHCP
#define _Config_NetworkConfig_EthMode_MAX Config_NetworkConfig_EthMode_STATIC
#define _Config_NetworkConfig_EthMode_ARRAYSIZE ((Config_NetworkConfig_EthMode)(Config_NetworkConfig_EthMode_STATIC+1))
#define _Config_DisplayConfig_GpsCoordinateFormat_MIN Config_DisplayConfig_GpsCoordinateFormat_DEC #define _Config_DisplayConfig_GpsCoordinateFormat_MIN Config_DisplayConfig_GpsCoordinateFormat_DEC
#define _Config_DisplayConfig_GpsCoordinateFormat_MAX Config_DisplayConfig_GpsCoordinateFormat_OSGR #define _Config_DisplayConfig_GpsCoordinateFormat_MAX Config_DisplayConfig_GpsCoordinateFormat_OSGR
#define _Config_DisplayConfig_GpsCoordinateFormat_ARRAYSIZE ((Config_DisplayConfig_GpsCoordinateFormat)(Config_DisplayConfig_GpsCoordinateFormat_OSGR+1)) #define _Config_DisplayConfig_GpsCoordinateFormat_ARRAYSIZE ((Config_DisplayConfig_GpsCoordinateFormat)(Config_DisplayConfig_GpsCoordinateFormat_OSGR+1))
@@ -186,8 +206,8 @@ typedef struct _Config {
#define _Config_DisplayConfig_DisplayUnits_ARRAYSIZE ((Config_DisplayConfig_DisplayUnits)(Config_DisplayConfig_DisplayUnits_IMPERIAL+1)) #define _Config_DisplayConfig_DisplayUnits_ARRAYSIZE ((Config_DisplayConfig_DisplayUnits)(Config_DisplayConfig_DisplayUnits_IMPERIAL+1))
#define _Config_LoRaConfig_RegionCode_MIN Config_LoRaConfig_RegionCode_UNSET #define _Config_LoRaConfig_RegionCode_MIN Config_LoRaConfig_RegionCode_UNSET
#define _Config_LoRaConfig_RegionCode_MAX Config_LoRaConfig_RegionCode_TH #define _Config_LoRaConfig_RegionCode_MAX Config_LoRaConfig_RegionCode_LORA_24
#define _Config_LoRaConfig_RegionCode_ARRAYSIZE ((Config_LoRaConfig_RegionCode)(Config_LoRaConfig_RegionCode_TH+1)) #define _Config_LoRaConfig_RegionCode_ARRAYSIZE ((Config_LoRaConfig_RegionCode)(Config_LoRaConfig_RegionCode_LORA_24+1))
#define _Config_LoRaConfig_ModemPreset_MIN Config_LoRaConfig_ModemPreset_LONG_FAST #define _Config_LoRaConfig_ModemPreset_MIN Config_LoRaConfig_ModemPreset_LONG_FAST
#define _Config_LoRaConfig_ModemPreset_MAX Config_LoRaConfig_ModemPreset_SHORT_FAST #define _Config_LoRaConfig_ModemPreset_MAX Config_LoRaConfig_ModemPreset_SHORT_FAST
@@ -207,7 +227,8 @@ extern "C" {
#define Config_DeviceConfig_init_default {_Config_DeviceConfig_Role_MIN, 0, 0} #define Config_DeviceConfig_init_default {_Config_DeviceConfig_Role_MIN, 0, 0}
#define Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0} #define Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0}
#define Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0} #define Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0}
#define Config_NetworkConfig_init_default {0, _Config_NetworkConfig_WiFiMode_MIN, "", "", ""} #define Config_NetworkConfig_init_default {0, "", "", "", 0, _Config_NetworkConfig_EthMode_MIN, false, Config_NetworkConfig_IpV4Config_init_default}
#define Config_NetworkConfig_IpV4Config_init_default {0, 0, 0, 0}
#define Config_DisplayConfig_init_default {0, _Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _Config_DisplayConfig_DisplayUnits_MIN} #define Config_DisplayConfig_init_default {0, _Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _Config_DisplayConfig_DisplayUnits_MIN}
#define Config_LoRaConfig_init_default {0, _Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, {0, 0, 0}} #define Config_LoRaConfig_init_default {0, _Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, {0, 0, 0}}
#define Config_BluetoothConfig_init_default {0, _Config_BluetoothConfig_PairingMode_MIN, 0} #define Config_BluetoothConfig_init_default {0, _Config_BluetoothConfig_PairingMode_MIN, 0}
@@ -215,7 +236,8 @@ extern "C" {
#define Config_DeviceConfig_init_zero {_Config_DeviceConfig_Role_MIN, 0, 0} #define Config_DeviceConfig_init_zero {_Config_DeviceConfig_Role_MIN, 0, 0}
#define Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0} #define Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0}
#define Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0} #define Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0}
#define Config_NetworkConfig_init_zero {0, _Config_NetworkConfig_WiFiMode_MIN, "", "", ""} #define Config_NetworkConfig_init_zero {0, "", "", "", 0, _Config_NetworkConfig_EthMode_MIN, false, Config_NetworkConfig_IpV4Config_init_zero}
#define Config_NetworkConfig_IpV4Config_init_zero {0, 0, 0, 0}
#define Config_DisplayConfig_init_zero {0, _Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _Config_DisplayConfig_DisplayUnits_MIN} #define Config_DisplayConfig_init_zero {0, _Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _Config_DisplayConfig_DisplayUnits_MIN}
#define Config_LoRaConfig_init_zero {0, _Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, {0, 0, 0}} #define Config_LoRaConfig_init_zero {0, _Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, {0, 0, 0}}
#define Config_BluetoothConfig_init_zero {0, _Config_BluetoothConfig_PairingMode_MIN, 0} #define Config_BluetoothConfig_init_zero {0, _Config_BluetoothConfig_PairingMode_MIN, 0}
@@ -245,11 +267,10 @@ extern "C" {
#define Config_LoRaConfig_tx_power_tag 10 #define Config_LoRaConfig_tx_power_tag 10
#define Config_LoRaConfig_channel_num_tag 11 #define Config_LoRaConfig_channel_num_tag 11
#define Config_LoRaConfig_ignore_incoming_tag 103 #define Config_LoRaConfig_ignore_incoming_tag 103
#define Config_NetworkConfig_wifi_enabled_tag 1 #define Config_NetworkConfig_IpV4Config_ip_tag 1
#define Config_NetworkConfig_wifi_mode_tag 2 #define Config_NetworkConfig_IpV4Config_gateway_tag 2
#define Config_NetworkConfig_wifi_ssid_tag 3 #define Config_NetworkConfig_IpV4Config_subnet_tag 3
#define Config_NetworkConfig_wifi_psk_tag 4 #define Config_NetworkConfig_IpV4Config_dns_tag 4
#define Config_NetworkConfig_ntp_server_tag 5
#define Config_PositionConfig_position_broadcast_secs_tag 1 #define Config_PositionConfig_position_broadcast_secs_tag 1
#define Config_PositionConfig_position_broadcast_smart_enabled_tag 2 #define Config_PositionConfig_position_broadcast_smart_enabled_tag 2
#define Config_PositionConfig_fixed_position_tag 3 #define Config_PositionConfig_fixed_position_tag 3
@@ -265,6 +286,13 @@ extern "C" {
#define Config_PowerConfig_sds_secs_tag 6 #define Config_PowerConfig_sds_secs_tag 6
#define Config_PowerConfig_ls_secs_tag 7 #define Config_PowerConfig_ls_secs_tag 7
#define Config_PowerConfig_min_wake_secs_tag 8 #define Config_PowerConfig_min_wake_secs_tag 8
#define Config_NetworkConfig_wifi_enabled_tag 1
#define Config_NetworkConfig_wifi_ssid_tag 3
#define Config_NetworkConfig_wifi_psk_tag 4
#define Config_NetworkConfig_ntp_server_tag 5
#define Config_NetworkConfig_eth_enabled_tag 6
#define Config_NetworkConfig_eth_mode_tag 7
#define Config_NetworkConfig_ipv4_config_tag 8
#define Config_device_tag 1 #define Config_device_tag 1
#define Config_position_tag 2 #define Config_position_tag 2
#define Config_power_tag 3 #define Config_power_tag 3
@@ -324,12 +352,23 @@ X(a, STATIC, SINGULAR, UINT32, min_wake_secs, 8)
#define Config_NetworkConfig_FIELDLIST(X, a) \ #define Config_NetworkConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, BOOL, wifi_enabled, 1) \ X(a, STATIC, SINGULAR, BOOL, wifi_enabled, 1) \
X(a, STATIC, SINGULAR, UENUM, wifi_mode, 2) \
X(a, STATIC, SINGULAR, STRING, wifi_ssid, 3) \ X(a, STATIC, SINGULAR, STRING, wifi_ssid, 3) \
X(a, STATIC, SINGULAR, STRING, wifi_psk, 4) \ X(a, STATIC, SINGULAR, STRING, wifi_psk, 4) \
X(a, STATIC, SINGULAR, STRING, ntp_server, 5) X(a, STATIC, SINGULAR, STRING, ntp_server, 5) \
X(a, STATIC, SINGULAR, BOOL, eth_enabled, 6) \
X(a, STATIC, SINGULAR, UENUM, eth_mode, 7) \
X(a, STATIC, OPTIONAL, MESSAGE, ipv4_config, 8)
#define Config_NetworkConfig_CALLBACK NULL #define Config_NetworkConfig_CALLBACK NULL
#define Config_NetworkConfig_DEFAULT NULL #define Config_NetworkConfig_DEFAULT NULL
#define Config_NetworkConfig_ipv4_config_MSGTYPE Config_NetworkConfig_IpV4Config
#define Config_NetworkConfig_IpV4Config_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, FIXED32, ip, 1) \
X(a, STATIC, SINGULAR, FIXED32, gateway, 2) \
X(a, STATIC, SINGULAR, FIXED32, subnet, 3) \
X(a, STATIC, SINGULAR, FIXED32, dns, 4)
#define Config_NetworkConfig_IpV4Config_CALLBACK NULL
#define Config_NetworkConfig_IpV4Config_DEFAULT NULL
#define Config_DisplayConfig_FIELDLIST(X, a) \ #define Config_DisplayConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UINT32, screen_on_secs, 1) \ X(a, STATIC, SINGULAR, UINT32, screen_on_secs, 1) \
@@ -369,6 +408,7 @@ extern const pb_msgdesc_t Config_DeviceConfig_msg;
extern const pb_msgdesc_t Config_PositionConfig_msg; extern const pb_msgdesc_t Config_PositionConfig_msg;
extern const pb_msgdesc_t Config_PowerConfig_msg; extern const pb_msgdesc_t Config_PowerConfig_msg;
extern const pb_msgdesc_t Config_NetworkConfig_msg; extern const pb_msgdesc_t Config_NetworkConfig_msg;
extern const pb_msgdesc_t Config_NetworkConfig_IpV4Config_msg;
extern const pb_msgdesc_t Config_DisplayConfig_msg; extern const pb_msgdesc_t Config_DisplayConfig_msg;
extern const pb_msgdesc_t Config_LoRaConfig_msg; extern const pb_msgdesc_t Config_LoRaConfig_msg;
extern const pb_msgdesc_t Config_BluetoothConfig_msg; extern const pb_msgdesc_t Config_BluetoothConfig_msg;
@@ -379,6 +419,7 @@ extern const pb_msgdesc_t Config_BluetoothConfig_msg;
#define Config_PositionConfig_fields &Config_PositionConfig_msg #define Config_PositionConfig_fields &Config_PositionConfig_msg
#define Config_PowerConfig_fields &Config_PowerConfig_msg #define Config_PowerConfig_fields &Config_PowerConfig_msg
#define Config_NetworkConfig_fields &Config_NetworkConfig_msg #define Config_NetworkConfig_fields &Config_NetworkConfig_msg
#define Config_NetworkConfig_IpV4Config_fields &Config_NetworkConfig_IpV4Config_msg
#define Config_DisplayConfig_fields &Config_DisplayConfig_msg #define Config_DisplayConfig_fields &Config_DisplayConfig_msg
#define Config_LoRaConfig_fields &Config_LoRaConfig_msg #define Config_LoRaConfig_fields &Config_LoRaConfig_msg
#define Config_BluetoothConfig_fields &Config_BluetoothConfig_msg #define Config_BluetoothConfig_fields &Config_BluetoothConfig_msg
@@ -387,11 +428,12 @@ extern const pb_msgdesc_t Config_BluetoothConfig_msg;
#define Config_BluetoothConfig_size 10 #define Config_BluetoothConfig_size 10
#define Config_DeviceConfig_size 6 #define Config_DeviceConfig_size 6
#define Config_DisplayConfig_size 20 #define Config_DisplayConfig_size 20
#define Config_LoRaConfig_size 67 #define Config_LoRaConfig_size 68
#define Config_NetworkConfig_size 137 #define Config_NetworkConfig_IpV4Config_size 20
#define Config_NetworkConfig_size 161
#define Config_PositionConfig_size 30 #define Config_PositionConfig_size 30
#define Config_PowerConfig_size 43 #define Config_PowerConfig_size 43
#define Config_size 140 #define Config_size 164
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */

View File

@@ -69,6 +69,7 @@ typedef struct _DeviceState {
} DeviceState; } DeviceState;
typedef PB_BYTES_ARRAY_T(2048) OEMStore_oem_icon_bits_t; typedef PB_BYTES_ARRAY_T(2048) OEMStore_oem_icon_bits_t;
typedef PB_BYTES_ARRAY_T(32) OEMStore_oem_aes_key_t;
/* This can be used for customizing the firmware distribution. If populated, /* This can be used for customizing the firmware distribution. If populated,
show a secondary bootup screen with cuatom logo and text for 2.5 seconds. */ show a secondary bootup screen with cuatom logo and text for 2.5 seconds. */
typedef struct _OEMStore { typedef struct _OEMStore {
@@ -82,6 +83,8 @@ typedef struct _OEMStore {
ScreenFonts oem_font; ScreenFonts oem_font;
/* Use this font for the OEM text. */ /* Use this font for the OEM text. */
char oem_text[40]; char oem_text[40];
/* The default device encryption key, 16 or 32 byte */
OEMStore_oem_aes_key_t oem_aes_key;
} OEMStore; } OEMStore;
@@ -98,10 +101,10 @@ extern "C" {
/* Initializer values for message structs */ /* Initializer values for message structs */
#define DeviceState_init_default {false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default}, false, MeshPacket_init_default, 0, 0, 0} #define DeviceState_init_default {false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default}, false, MeshPacket_init_default, 0, 0, 0}
#define ChannelFile_init_default {0, {Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default}, 0} #define ChannelFile_init_default {0, {Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default}, 0}
#define OEMStore_init_default {0, 0, {0, {0}}, _ScreenFonts_MIN, ""} #define OEMStore_init_default {0, 0, {0, {0}}, _ScreenFonts_MIN, "", {0, {0}}}
#define DeviceState_init_zero {false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero}, false, MeshPacket_init_zero, 0, 0, 0} #define DeviceState_init_zero {false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero}, false, MeshPacket_init_zero, 0, 0, 0}
#define ChannelFile_init_zero {0, {Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero}, 0} #define ChannelFile_init_zero {0, {Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero}, 0}
#define OEMStore_init_zero {0, 0, {0, {0}}, _ScreenFonts_MIN, ""} #define OEMStore_init_zero {0, 0, {0, {0}}, _ScreenFonts_MIN, "", {0, {0}}}
/* Field tags (for use in manual encoding/decoding) */ /* Field tags (for use in manual encoding/decoding) */
#define ChannelFile_channels_tag 1 #define ChannelFile_channels_tag 1
@@ -119,6 +122,7 @@ extern "C" {
#define OEMStore_oem_icon_bits_tag 3 #define OEMStore_oem_icon_bits_tag 3
#define OEMStore_oem_font_tag 4 #define OEMStore_oem_font_tag 4
#define OEMStore_oem_text_tag 5 #define OEMStore_oem_text_tag 5
#define OEMStore_oem_aes_key_tag 6
/* Struct field encoding specification for nanopb */ /* Struct field encoding specification for nanopb */
#define DeviceState_FIELDLIST(X, a) \ #define DeviceState_FIELDLIST(X, a) \
@@ -150,7 +154,8 @@ X(a, STATIC, SINGULAR, UINT32, oem_icon_width, 1) \
X(a, STATIC, SINGULAR, UINT32, oem_icon_height, 2) \ X(a, STATIC, SINGULAR, UINT32, oem_icon_height, 2) \
X(a, STATIC, SINGULAR, BYTES, oem_icon_bits, 3) \ X(a, STATIC, SINGULAR, BYTES, oem_icon_bits, 3) \
X(a, STATIC, SINGULAR, UENUM, oem_font, 4) \ X(a, STATIC, SINGULAR, UENUM, oem_font, 4) \
X(a, STATIC, SINGULAR, STRING, oem_text, 5) X(a, STATIC, SINGULAR, STRING, oem_text, 5) \
X(a, STATIC, SINGULAR, BYTES, oem_aes_key, 6)
#define OEMStore_CALLBACK NULL #define OEMStore_CALLBACK NULL
#define OEMStore_DEFAULT NULL #define OEMStore_DEFAULT NULL
@@ -166,7 +171,7 @@ extern const pb_msgdesc_t OEMStore_msg;
/* Maximum encoded size of messages (where known) */ /* Maximum encoded size of messages (where known) */
#define ChannelFile_size 638 #define ChannelFile_size 638
#define DeviceState_size 21800 #define DeviceState_size 21800
#define OEMStore_size 2106 #define OEMStore_size 2140
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */

View File

@@ -144,7 +144,7 @@ extern const pb_msgdesc_t LocalModuleConfig_msg;
#define LocalModuleConfig_fields &LocalModuleConfig_msg #define LocalModuleConfig_fields &LocalModuleConfig_msg
/* Maximum encoded size of messages (where known) */ /* Maximum encoded size of messages (where known) */
#define LocalConfig_size 334 #define LocalConfig_size 359
#define LocalModuleConfig_size 270 #define LocalModuleConfig_size 270
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -42,9 +42,6 @@ PB_BIND(FromRadio, FromRadio, 2)
PB_BIND(ToRadio, ToRadio, 2) PB_BIND(ToRadio, ToRadio, 2)
PB_BIND(ToRadio_PeerInfo, ToRadio_PeerInfo, AUTO)
PB_BIND(Compressed, Compressed, AUTO) PB_BIND(Compressed, Compressed, AUTO)

View File

@@ -243,8 +243,11 @@ typedef enum _LogRecord_Level {
/* Struct definitions */ /* Struct definitions */
typedef PB_BYTES_ARRAY_T(237) Compressed_data_t; typedef PB_BYTES_ARRAY_T(237) Compressed_data_t;
/* Compressed message payload */
typedef struct _Compressed { typedef struct _Compressed {
/* PortNum to determine the how to handle the compressed payload. */
PortNum portnum; PortNum portnum;
/* Compressed data. */
Compressed_data_t data; Compressed_data_t data;
} Compressed; } Compressed;
@@ -352,7 +355,7 @@ typedef struct _MyNodeInfo {
/* a gps position */ /* a gps position */
typedef struct _Position { typedef struct _Position {
/* The new preferred location encoding, divide by 1e-7 to get degrees /* The new preferred location encoding, multiply by 1e-7 to get degrees
in floating point */ in floating point */
int32_t latitude_i; int32_t latitude_i;
/* TODO: REPLACE */ /* TODO: REPLACE */
@@ -425,14 +428,6 @@ typedef struct _RouteDiscovery {
uint32_t route[8]; uint32_t route[8];
} RouteDiscovery; } RouteDiscovery;
/* Compressed message payload */
typedef struct _ToRadio_PeerInfo {
/* PortNum to determine the how to handle the compressed payload. */
uint32_t app_version;
/* Compressed data. */
bool mqtt_gateway;
} ToRadio_PeerInfo;
/* Broadcast when a newly powered mesh node wants to find a node num it can use /* Broadcast when a newly powered mesh node wants to find a node num it can use
Sent from the phone over bluetooth to set the user id for the owner of this node. Sent from the phone over bluetooth to set the user id for the owner of this node.
Also sent from nodes to each other when a new node signs on (so all clients can have this info) Also sent from nodes to each other when a new node signs on (so all clients can have this info)
@@ -665,9 +660,6 @@ typedef struct _ToRadio {
union { union {
/* Send this packet on the mesh */ /* Send this packet on the mesh */
MeshPacket packet; MeshPacket packet;
/* Information about the peer, sent after the phone sneds want_config_id.
Old clients do not send this, which is fine. */
ToRadio_PeerInfo peer_info;
/* Phone wants radio to send full node db to the phone, This is /* Phone wants radio to send full node db to the phone, This is
typically the first packet sent to the radio when the phone gets a typically the first packet sent to the radio when the phone gets a
bluetooth connection. The radio will respond by sending back a bluetooth connection. The radio will respond by sending back a
@@ -740,7 +732,6 @@ extern "C" {
#define LogRecord_init_default {"", 0, "", _LogRecord_Level_MIN} #define LogRecord_init_default {"", 0, "", _LogRecord_Level_MIN}
#define FromRadio_init_default {0, 0, {MeshPacket_init_default}} #define FromRadio_init_default {0, 0, {MeshPacket_init_default}}
#define ToRadio_init_default {0, {MeshPacket_init_default}} #define ToRadio_init_default {0, {MeshPacket_init_default}}
#define ToRadio_PeerInfo_init_default {0, 0}
#define Compressed_init_default {_PortNum_MIN, {0, {0}}} #define Compressed_init_default {_PortNum_MIN, {0, {0}}}
#define Position_init_zero {0, 0, 0, 0, _Position_LocSource_MIN, _Position_AltSource_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} #define Position_init_zero {0, 0, 0, 0, _Position_LocSource_MIN, _Position_AltSource_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define User_init_zero {"", "", "", {0}, _HardwareModel_MIN, 0} #define User_init_zero {"", "", "", {0}, _HardwareModel_MIN, 0}
@@ -754,7 +745,6 @@ extern "C" {
#define LogRecord_init_zero {"", 0, "", _LogRecord_Level_MIN} #define LogRecord_init_zero {"", 0, "", _LogRecord_Level_MIN}
#define FromRadio_init_zero {0, 0, {MeshPacket_init_zero}} #define FromRadio_init_zero {0, 0, {MeshPacket_init_zero}}
#define ToRadio_init_zero {0, {MeshPacket_init_zero}} #define ToRadio_init_zero {0, {MeshPacket_init_zero}}
#define ToRadio_PeerInfo_init_zero {0, 0}
#define Compressed_init_zero {_PortNum_MIN, {0, {0}}} #define Compressed_init_zero {_PortNum_MIN, {0, {0}}}
/* Field tags (for use in manual encoding/decoding) */ /* Field tags (for use in manual encoding/decoding) */
@@ -811,8 +801,6 @@ extern "C" {
#define Position_next_update_tag 21 #define Position_next_update_tag 21
#define Position_seq_number_tag 22 #define Position_seq_number_tag 22
#define RouteDiscovery_route_tag 1 #define RouteDiscovery_route_tag 1
#define ToRadio_PeerInfo_app_version_tag 1
#define ToRadio_PeerInfo_mqtt_gateway_tag 2
#define User_id_tag 1 #define User_id_tag 1
#define User_long_name_tag 2 #define User_long_name_tag 2
#define User_short_name_tag 3 #define User_short_name_tag 3
@@ -859,7 +847,6 @@ extern "C" {
#define FromRadio_moduleConfig_tag 9 #define FromRadio_moduleConfig_tag 9
#define FromRadio_channel_tag 10 #define FromRadio_channel_tag 10
#define ToRadio_packet_tag 1 #define ToRadio_packet_tag 1
#define ToRadio_peer_info_tag 2
#define ToRadio_want_config_id_tag 3 #define ToRadio_want_config_id_tag 3
#define ToRadio_disconnect_tag 4 #define ToRadio_disconnect_tag 4
@@ -1019,19 +1006,11 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,channel,channel), 10)
#define ToRadio_FIELDLIST(X, a) \ #define ToRadio_FIELDLIST(X, a) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,packet,packet), 1) \ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,packet,packet), 1) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,peer_info,peer_info), 2) \
X(a, STATIC, ONEOF, UINT32, (payload_variant,want_config_id,want_config_id), 3) \ X(a, STATIC, ONEOF, UINT32, (payload_variant,want_config_id,want_config_id), 3) \
X(a, STATIC, ONEOF, BOOL, (payload_variant,disconnect,disconnect), 4) X(a, STATIC, ONEOF, BOOL, (payload_variant,disconnect,disconnect), 4)
#define ToRadio_CALLBACK NULL #define ToRadio_CALLBACK NULL
#define ToRadio_DEFAULT NULL #define ToRadio_DEFAULT NULL
#define ToRadio_payload_variant_packet_MSGTYPE MeshPacket #define ToRadio_payload_variant_packet_MSGTYPE MeshPacket
#define ToRadio_payload_variant_peer_info_MSGTYPE ToRadio_PeerInfo
#define ToRadio_PeerInfo_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UINT32, app_version, 1) \
X(a, STATIC, SINGULAR, BOOL, mqtt_gateway, 2)
#define ToRadio_PeerInfo_CALLBACK NULL
#define ToRadio_PeerInfo_DEFAULT NULL
#define Compressed_FIELDLIST(X, a) \ #define Compressed_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UENUM, portnum, 1) \ X(a, STATIC, SINGULAR, UENUM, portnum, 1) \
@@ -1051,7 +1030,6 @@ extern const pb_msgdesc_t MyNodeInfo_msg;
extern const pb_msgdesc_t LogRecord_msg; extern const pb_msgdesc_t LogRecord_msg;
extern const pb_msgdesc_t FromRadio_msg; extern const pb_msgdesc_t FromRadio_msg;
extern const pb_msgdesc_t ToRadio_msg; extern const pb_msgdesc_t ToRadio_msg;
extern const pb_msgdesc_t ToRadio_PeerInfo_msg;
extern const pb_msgdesc_t Compressed_msg; extern const pb_msgdesc_t Compressed_msg;
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ /* Defines for backwards compatibility with code written before nanopb-0.4.0 */
@@ -1067,7 +1045,6 @@ extern const pb_msgdesc_t Compressed_msg;
#define LogRecord_fields &LogRecord_msg #define LogRecord_fields &LogRecord_msg
#define FromRadio_fields &FromRadio_msg #define FromRadio_fields &FromRadio_msg
#define ToRadio_fields &ToRadio_msg #define ToRadio_fields &ToRadio_msg
#define ToRadio_PeerInfo_fields &ToRadio_PeerInfo_msg
#define Compressed_fields &Compressed_msg #define Compressed_fields &Compressed_msg
/* Maximum encoded size of messages (where known) */ /* Maximum encoded size of messages (where known) */
@@ -1081,7 +1058,6 @@ extern const pb_msgdesc_t Compressed_msg;
#define Position_size 137 #define Position_size 137
#define RouteDiscovery_size 40 #define RouteDiscovery_size 40
#define Routing_size 42 #define Routing_size 42
#define ToRadio_PeerInfo_size 8
#define ToRadio_size 324 #define ToRadio_size 324
#define User_size 77 #define User_size 77
#define Waypoint_size 156 #define Waypoint_size 156

View File

@@ -33,7 +33,8 @@ typedef enum _ModuleConfig_SerialConfig_Serial_Mode {
ModuleConfig_SerialConfig_Serial_Mode_DEFAULT = 0, ModuleConfig_SerialConfig_Serial_Mode_DEFAULT = 0,
ModuleConfig_SerialConfig_Serial_Mode_SIMPLE = 1, ModuleConfig_SerialConfig_Serial_Mode_SIMPLE = 1,
ModuleConfig_SerialConfig_Serial_Mode_PROTO = 2, ModuleConfig_SerialConfig_Serial_Mode_PROTO = 2,
ModuleConfig_SerialConfig_Serial_Mode_TEXTMSG = 3 ModuleConfig_SerialConfig_Serial_Mode_TEXTMSG = 3,
ModuleConfig_SerialConfig_Serial_Mode_NMEA = 4
} ModuleConfig_SerialConfig_Serial_Mode; } ModuleConfig_SerialConfig_Serial_Mode;
typedef enum _ModuleConfig_CannedMessageConfig_InputEventChar { typedef enum _ModuleConfig_CannedMessageConfig_InputEventChar {
@@ -140,8 +141,8 @@ typedef struct _ModuleConfig {
#define _ModuleConfig_SerialConfig_Serial_Baud_ARRAYSIZE ((ModuleConfig_SerialConfig_Serial_Baud)(ModuleConfig_SerialConfig_Serial_Baud_BAUD_921600+1)) #define _ModuleConfig_SerialConfig_Serial_Baud_ARRAYSIZE ((ModuleConfig_SerialConfig_Serial_Baud)(ModuleConfig_SerialConfig_Serial_Baud_BAUD_921600+1))
#define _ModuleConfig_SerialConfig_Serial_Mode_MIN ModuleConfig_SerialConfig_Serial_Mode_DEFAULT #define _ModuleConfig_SerialConfig_Serial_Mode_MIN ModuleConfig_SerialConfig_Serial_Mode_DEFAULT
#define _ModuleConfig_SerialConfig_Serial_Mode_MAX ModuleConfig_SerialConfig_Serial_Mode_TEXTMSG #define _ModuleConfig_SerialConfig_Serial_Mode_MAX ModuleConfig_SerialConfig_Serial_Mode_NMEA
#define _ModuleConfig_SerialConfig_Serial_Mode_ARRAYSIZE ((ModuleConfig_SerialConfig_Serial_Mode)(ModuleConfig_SerialConfig_Serial_Mode_TEXTMSG+1)) #define _ModuleConfig_SerialConfig_Serial_Mode_ARRAYSIZE ((ModuleConfig_SerialConfig_Serial_Mode)(ModuleConfig_SerialConfig_Serial_Mode_NMEA+1))
#define _ModuleConfig_CannedMessageConfig_InputEventChar_MIN ModuleConfig_CannedMessageConfig_InputEventChar_NONE #define _ModuleConfig_CannedMessageConfig_InputEventChar_MIN ModuleConfig_CannedMessageConfig_InputEventChar_NONE
#define _ModuleConfig_CannedMessageConfig_InputEventChar_MAX ModuleConfig_CannedMessageConfig_InputEventChar_BACK #define _ModuleConfig_CannedMessageConfig_InputEventChar_MAX ModuleConfig_CannedMessageConfig_InputEventChar_BACK

View File

@@ -75,12 +75,12 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
ResourceNode *nodeAPIv1ToRadio = new ResourceNode("/api/v1/toradio", "PUT", &handleAPIv1ToRadio); ResourceNode *nodeAPIv1ToRadio = new ResourceNode("/api/v1/toradio", "PUT", &handleAPIv1ToRadio);
ResourceNode *nodeAPIv1FromRadio = new ResourceNode("/api/v1/fromradio", "GET", &handleAPIv1FromRadio); ResourceNode *nodeAPIv1FromRadio = new ResourceNode("/api/v1/fromradio", "GET", &handleAPIv1FromRadio);
ResourceNode *nodeHotspotApple = new ResourceNode("/hotspot-detect.html", "GET", &handleHotspot); // ResourceNode *nodeHotspotApple = new ResourceNode("/hotspot-detect.html", "GET", &handleHotspot);
ResourceNode *nodeHotspotAndroid = new ResourceNode("/generate_204", "GET", &handleHotspot); // ResourceNode *nodeHotspotAndroid = new ResourceNode("/generate_204", "GET", &handleHotspot);
ResourceNode *nodeAdmin = new ResourceNode("/admin", "GET", &handleAdmin); ResourceNode *nodeAdmin = new ResourceNode("/admin", "GET", &handleAdmin);
ResourceNode *nodeAdminSettings = new ResourceNode("/admin/settings", "GET", &handleAdminSettings); // ResourceNode *nodeAdminSettings = new ResourceNode("/admin/settings", "GET", &handleAdminSettings);
ResourceNode *nodeAdminSettingsApply = new ResourceNode("/admin/settings/apply", "POST", &handleAdminSettingsApply); // ResourceNode *nodeAdminSettingsApply = new ResourceNode("/admin/settings/apply", "POST", &handleAdminSettingsApply);
// ResourceNode *nodeAdminFs = new ResourceNode("/admin/fs", "GET", &handleFs); // ResourceNode *nodeAdminFs = new ResourceNode("/admin/fs", "GET", &handleFs);
// ResourceNode *nodeUpdateFs = new ResourceNode("/admin/fs/update", "POST", &handleUpdateFs); // ResourceNode *nodeUpdateFs = new ResourceNode("/admin/fs/update", "POST", &handleUpdateFs);
// ResourceNode *nodeDeleteFs = new ResourceNode("/admin/fs/delete", "GET", &handleDeleteFsContent); // ResourceNode *nodeDeleteFs = new ResourceNode("/admin/fs/delete", "GET", &handleDeleteFsContent);
@@ -100,8 +100,8 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
secureServer->registerNode(nodeAPIv1ToRadioOptions); secureServer->registerNode(nodeAPIv1ToRadioOptions);
secureServer->registerNode(nodeAPIv1ToRadio); secureServer->registerNode(nodeAPIv1ToRadio);
secureServer->registerNode(nodeAPIv1FromRadio); secureServer->registerNode(nodeAPIv1FromRadio);
secureServer->registerNode(nodeHotspotApple); // secureServer->registerNode(nodeHotspotApple);
secureServer->registerNode(nodeHotspotAndroid); // secureServer->registerNode(nodeHotspotAndroid);
secureServer->registerNode(nodeRestart); secureServer->registerNode(nodeRestart);
secureServer->registerNode(nodeFormUpload); secureServer->registerNode(nodeFormUpload);
secureServer->registerNode(nodeJsonScanNetworks); secureServer->registerNode(nodeJsonScanNetworks);
@@ -113,16 +113,16 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
// secureServer->registerNode(nodeDeleteFs); // secureServer->registerNode(nodeDeleteFs);
secureServer->registerNode(nodeAdmin); secureServer->registerNode(nodeAdmin);
// secureServer->registerNode(nodeAdminFs); // secureServer->registerNode(nodeAdminFs);
secureServer->registerNode(nodeAdminSettings); // secureServer->registerNode(nodeAdminSettings);
secureServer->registerNode(nodeAdminSettingsApply); // secureServer->registerNode(nodeAdminSettingsApply);
secureServer->registerNode(nodeRoot); // This has to be last secureServer->registerNode(nodeRoot); // This has to be last
// Insecure nodes // Insecure nodes
insecureServer->registerNode(nodeAPIv1ToRadioOptions); insecureServer->registerNode(nodeAPIv1ToRadioOptions);
insecureServer->registerNode(nodeAPIv1ToRadio); insecureServer->registerNode(nodeAPIv1ToRadio);
insecureServer->registerNode(nodeAPIv1FromRadio); insecureServer->registerNode(nodeAPIv1FromRadio);
insecureServer->registerNode(nodeHotspotApple); // insecureServer->registerNode(nodeHotspotApple);
insecureServer->registerNode(nodeHotspotAndroid); // insecureServer->registerNode(nodeHotspotAndroid);
insecureServer->registerNode(nodeRestart); insecureServer->registerNode(nodeRestart);
insecureServer->registerNode(nodeFormUpload); insecureServer->registerNode(nodeFormUpload);
insecureServer->registerNode(nodeJsonScanNetworks); insecureServer->registerNode(nodeJsonScanNetworks);
@@ -134,8 +134,8 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
// insecureServer->registerNode(nodeDeleteFs); // insecureServer->registerNode(nodeDeleteFs);
insecureServer->registerNode(nodeAdmin); insecureServer->registerNode(nodeAdmin);
// insecureServer->registerNode(nodeAdminFs); // insecureServer->registerNode(nodeAdminFs);
insecureServer->registerNode(nodeAdminSettings); // insecureServer->registerNode(nodeAdminSettings);
insecureServer->registerNode(nodeAdminSettingsApply); // insecureServer->registerNode(nodeAdminSettingsApply);
insecureServer->registerNode(nodeRoot); // This has to be last insecureServer->registerNode(nodeRoot); // This has to be last
} }
@@ -251,7 +251,7 @@ void htmlDeleteDir(const char *dirname)
std::vector<std::map<char *, char *>> *htmlListDir(std::vector<std::map<char *, char *>> *fileList, const char *dirname, std::vector<std::map<char *, char *>> *htmlListDir(std::vector<std::map<char *, char *>> *fileList, const char *dirname,
uint8_t levels) uint8_t levels)
{ {
File root = FSCom.open(dirname); File root = FSCom.open(dirname, FILE_O_READ);
if (!root) { if (!root) {
return NULL; return NULL;
} }
@@ -264,14 +264,27 @@ std::vector<std::map<char *, char *>> *htmlListDir(std::vector<std::map<char *,
while (file) { while (file) {
if (file.isDirectory() && !String(file.name()).endsWith(".")) { if (file.isDirectory() && !String(file.name()).endsWith(".")) {
if (levels) { if (levels) {
#ifdef ARCH_ESP32
htmlListDir(fileList, file.path(), levels - 1);
#else
htmlListDir(fileList, file.name(), levels - 1); htmlListDir(fileList, file.name(), levels - 1);
#endif
file.close();
} }
} else { } else {
std::map<char *, char *> thisFileMap; std::map<char *, char *> thisFileMap;
thisFileMap[strdup("size")] = strdup(String(file.size()).c_str()); thisFileMap[strdup("size")] = strdup(String(file.size()).c_str());
#ifdef ARCH_ESP32
thisFileMap[strdup("name")] = strdup(String(file.path()).substring(1).c_str());
#else
thisFileMap[strdup("name")] = strdup(String(file.name()).substring(1).c_str()); thisFileMap[strdup("name")] = strdup(String(file.name()).substring(1).c_str());
#endif
if (String(file.name()).substring(1).endsWith(".gz")) { if (String(file.name()).substring(1).endsWith(".gz")) {
#ifdef ARCH_ESP32
String modifiedFile = String(file.path()).substring(1);
#else
String modifiedFile = String(file.name()).substring(1); String modifiedFile = String(file.name()).substring(1);
#endif
modifiedFile.remove((modifiedFile.length() - 3), 3); modifiedFile.remove((modifiedFile.length() - 3), 3);
thisFileMap[strdup("nameModified")] = strdup(modifiedFile.c_str()); thisFileMap[strdup("nameModified")] = strdup(modifiedFile.c_str());
} }
@@ -291,7 +304,7 @@ void handleFsBrowseStatic(HTTPRequest *req, HTTPResponse *res)
res->setHeader("Access-Control-Allow-Methods", "GET"); res->setHeader("Access-Control-Allow-Methods", "GET");
using namespace json11; using namespace json11;
auto fileList = htmlListDir(new std::vector<std::map<char *, char *>>(), "/", 10); auto fileList = htmlListDir(new std::vector<std::map<char *, char *>>(), "/static", 10);
// create json output structure // create json output structure
Json filesystemObj = Json::object{ Json filesystemObj = Json::object{
@@ -607,12 +620,8 @@ void handleReport(HTTPRequest *req, HTTPResponse *res)
}; };
// data->wifi // data->wifi
String ipStr; String ipStr = String(WiFi.localIP().toString());
if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT || config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN || isSoftAPForced()) {
ipStr = String(WiFi.softAPIP().toString());
} else {
ipStr = String(WiFi.localIP().toString());
}
Json jsonObjWifi = Json::object{{"rssi", String(WiFi.RSSI())}, {"ip", ipStr.c_str()}}; Json jsonObjWifi = Json::object{{"rssi", String(WiFi.RSSI())}, {"ip", ipStr.c_str()}};
// data->memory // data->memory
@@ -694,8 +703,8 @@ void handleAdmin(HTTPRequest *req, HTTPResponse *res)
res->setHeader("Access-Control-Allow-Methods", "GET"); res->setHeader("Access-Control-Allow-Methods", "GET");
res->println("<h1>Meshtastic</h1>\n"); res->println("<h1>Meshtastic</h1>\n");
res->println("<a href=/admin/settings>Settings</a><br>\n"); // res->println("<a href=/admin/settings>Settings</a><br>\n");
res->println("<a href=/admin/fs>Manage Web Content</a><br>\n"); // res->println("<a href=/admin/fs>Manage Web Content</a><br>\n");
res->println("<a href=/json/report>Device Report</a><br>\n"); res->println("<a href=/json/report>Device Report</a><br>\n");
} }

View File

@@ -55,10 +55,6 @@ static void handleWebResponse()
if (isWifiAvailable()) { if (isWifiAvailable()) {
if (isWebServerReady) { if (isWebServerReady) {
// We're going to handle the DNS responder here so it
// will be ignored by the NRF boards.
handleDNSResponse();
if (secureServer) if (secureServer)
secureServer->loop(); secureServer->loop();
insecureServer->loop(); insecureServer->loop();

View File

@@ -8,7 +8,6 @@
#include "mesh/wifi/WiFiServerAPI.h" #include "mesh/wifi/WiFiServerAPI.h"
#include "mqtt/MQTT.h" #include "mqtt/MQTT.h"
#include "target_specific.h" #include "target_specific.h"
#include <DNSServer.h>
#include <ESPmDNS.h> #include <ESPmDNS.h>
#include <esp_wifi.h> #include <esp_wifi.h>
#include <WiFi.h> #include <WiFi.h>
@@ -22,9 +21,6 @@ using namespace concurrency;
static void WiFiEvent(WiFiEvent_t event); static void WiFiEvent(WiFiEvent_t event);
// DNS Server for the Captive Portal
DNSServer dnsServer;
// NTP // NTP
WiFiUDP ntpUDP; WiFiUDP ntpUDP;
@@ -37,46 +33,29 @@ uint8_t wifiDisconnectReason = 0;
// Stores our hostname // Stores our hostname
char ourHost[16]; char ourHost[16];
bool forcedSoftAP = 0;
bool APStartupComplete = 0; bool APStartupComplete = 0;
static bool needReconnect = true; // If we create our reconnector, run it once at the beginning static bool needReconnect = true; // If we create our reconnector, run it once at the beginning
// FIXME, veto light sleep if we have a TCP server running
#if 0
class WifiSleepObserver : public Observer<uint32_t> {
protected:
/// Return 0 if sleep is okay
virtual int onNotify(uint32_t newValue) {
}
};
static WifiSleepObserver wifiSleepObserver;
//preflightSleepObserver.observe(&preflightSleep);
#endif
static int32_t reconnectWiFi() static int32_t reconnectWiFi()
{ {
const char *wifiName = config.network.wifi_ssid; const char *wifiName = config.network.wifi_ssid;
const char *wifiPsw = config.network.wifi_psk; const char *wifiPsw = config.network.wifi_psk;
if (config.network.wifi_enabled && needReconnect && !WiFi.isConnected()) { if (config.network.wifi_enabled && needReconnect && !WiFi.isConnected()) {
// if (radioConfig.has_preferences && needReconnect && !WiFi.isConnected()) {
if (!*wifiPsw) // Treat empty password as no password if (!*wifiPsw) // Treat empty password as no password
wifiPsw = NULL; wifiPsw = NULL;
if (*wifiName) { if (*wifiName) {
needReconnect = false; needReconnect = false;
// Make sure we clear old connection credentials
WiFi.disconnect(false, true);
DEBUG_MSG("... Reconnecting to WiFi access point\n"); DEBUG_MSG("... Reconnecting to WiFi access point\n");
WiFi.mode(WIFI_MODE_STA); WiFi.mode(WIFI_MODE_STA);
WiFi.begin(wifiName, wifiPsw); WiFi.begin(wifiName, wifiPsw);
// Starting timeClient;
} }
} }
@@ -103,16 +82,10 @@ static int32_t reconnectWiFi()
static Periodic *wifiReconnect; static Periodic *wifiReconnect;
bool isSoftAPForced()
{
return forcedSoftAP;
}
bool isWifiAvailable() bool isWifiAvailable()
{ {
if (config.network.wifi_enabled && ((config.network.wifi_ssid[0]) || forcedSoftAP)) { if (config.network.wifi_enabled && (config.network.wifi_ssid[0])) {
return true; return true;
} else { } else {
return false; return false;
@@ -176,100 +149,48 @@ static void onNetworkConnected()
} }
// Startup WiFi // Startup WiFi
bool initWifi(bool forceSoftAP) bool initWifi()
{ {
forcedSoftAP = forceSoftAP; if (config.network.wifi_enabled && config.network.wifi_ssid[0]) {
if (config.network.wifi_enabled && ((config.network.wifi_ssid[0]) || forceSoftAP)) {
// if ((radioConfig.has_preferences && config.wifi.ssid[0]) || forceSoftAP) {
const char *wifiName = config.network.wifi_ssid; const char *wifiName = config.network.wifi_ssid;
const char *wifiPsw = config.network.wifi_psk; const char *wifiPsw = config.network.wifi_psk;
if (forceSoftAP) {
DEBUG_MSG("WiFi ... Forced AP Mode\n");
} else if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT) {
DEBUG_MSG("WiFi ... AP Mode\n");
} else if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN) {
DEBUG_MSG("WiFi ... Hidden AP Mode\n");
} else if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_CLIENT) {
DEBUG_MSG("WiFi ... Client Mode\n");
} else {
DEBUG_MSG("WiFi ... WiFi Disabled\n");
}
createSSLCert(); createSSLCert();
if (!*wifiPsw) // Treat empty password as no password if (!*wifiPsw) // Treat empty password as no password
wifiPsw = NULL; wifiPsw = NULL;
if (*wifiName || forceSoftAP) { if (*wifiName) {
if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT || config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN || forceSoftAP) { uint8_t dmac[6];
getMacAddr(dmac);
sprintf(ourHost, "Meshtastic-%02x%02x", dmac[4], dmac[5]);
IPAddress apIP(192, 168, 42, 1); WiFi.mode(WIFI_MODE_STA);
WiFi.onEvent(WiFiEvent); WiFi.setHostname(ourHost);
WiFi.mode(WIFI_AP); WiFi.onEvent(WiFiEvent);
if (forcedSoftAP) { // This is needed to improve performance.
const char *softAPssid = "meshtasticAdmin"; esp_wifi_set_ps(WIFI_PS_NONE); // Disable radio power saving
const char *softAPpasswd = "12345678";
int ok = WiFi.softAP(softAPssid, softAPpasswd);
DEBUG_MSG("Starting (Forced) WIFI AP: ssid=%s, ok=%d\n", softAPssid, ok);
} else { WiFi.onEvent(
[](WiFiEvent_t event, WiFiEventInfo_t info) {
Serial.print("\nWiFi lost connection. Reason: ");
Serial.println(info.wifi_sta_disconnected.reason);
// If AP is configured to be hidden hidden /*
if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN) { If we are disconnected from the AP for some reason,
save the error code.
// The configurations on softAP are from the espresif library For a reference to the codes:
int ok = WiFi.softAP(wifiName, wifiPsw, 1, 1, 4); https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html#wi-fi-reason-code
DEBUG_MSG("Starting hidden WIFI AP: ssid=%s, ok=%d\n", wifiName, ok); */
} else { wifiDisconnectReason = info.wifi_sta_disconnected.reason;
int ok = WiFi.softAP(wifiName, wifiPsw); },
DEBUG_MSG("Starting WIFI AP: ssid=%s, ok=%d\n", wifiName, ok); WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_DISCONNECTED);
}
int ok = WiFi.softAP(wifiName, wifiPsw);
DEBUG_MSG("Starting WIFI AP: ssid=%s, ok=%d\n", wifiName, ok);
}
WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0)); DEBUG_MSG("JOINING WIFI soon: ssid=%s\n", wifiName);
DEBUG_MSG("MY IP AP ADDRESS: %s\n", WiFi.softAPIP().toString().c_str()); wifiReconnect = new Periodic("WifiConnect", reconnectWiFi);
// This is needed to improve performance.
esp_wifi_set_ps(WIFI_PS_NONE); // Disable radio power saving
dnsServer.start(53, "*", apIP);
} else {
uint8_t dmac[6];
getMacAddr(dmac);
sprintf(ourHost, "Meshtastic-%02x%02x", dmac[4], dmac[5]);
WiFi.mode(WIFI_MODE_STA);
WiFi.setHostname(ourHost);
WiFi.onEvent(WiFiEvent);
// This is needed to improve performance.
esp_wifi_set_ps(WIFI_PS_NONE); // Disable radio power saving
WiFi.onEvent(
[](WiFiEvent_t event, WiFiEventInfo_t info) {
Serial.print("\nWiFi lost connection. Reason: ");
Serial.println(info.wifi_sta_disconnected.reason);
/*
If we are disconnected from the AP for some reason,
save the error code.
For a reference to the codes:
https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html#wi-fi-reason-code
*/
wifiDisconnectReason = info.wifi_sta_disconnected.reason;
},
WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_DISCONNECTED);
DEBUG_MSG("JOINING WIFI soon: ssid=%s\n", wifiName);
wifiReconnect = new Periodic("WifiConnect", reconnectWiFi);
}
} }
return true; return true;
} else { } else {
@@ -371,13 +292,6 @@ static void WiFiEvent(WiFiEvent_t event)
} }
} }
void handleDNSResponse()
{
if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT || config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN || isSoftAPForced()) {
dnsServer.processNextRequest();
}
}
uint8_t getWifiDisconnectReason() uint8_t getWifiDisconnectReason()
{ {
return wifiDisconnectReason; return wifiDisconnectReason;

View File

@@ -5,19 +5,14 @@
#include <functional> #include <functional>
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
#include <DNSServer.h>
#include <WiFi.h> #include <WiFi.h>
#endif #endif
/// @return true if wifi is now in use /// @return true if wifi is now in use
bool initWifi(bool forceSoftAP); bool initWifi();
void deinitWifi(); void deinitWifi();
bool isWifiAvailable(); bool isWifiAvailable();
void handleDNSResponse();
bool isSoftAPForced();
uint8_t getWifiDisconnectReason(); uint8_t getWifiDisconnectReason();

View File

@@ -101,9 +101,7 @@ bool AdminModule::handleReceivedProtobuf(const MeshPacket &mp, AdminMessage *r)
* Other * Other
*/ */
case AdminMessage_reboot_seconds_tag: { case AdminMessage_reboot_seconds_tag: {
int32_t s = r->reboot_seconds; reboot(r->reboot_seconds);
DEBUG_MSG("Rebooting in %d seconds\n", s);
rebootAtMsec = (s < 0) ? 0 : (millis() + s * 1000);
break; break;
} }
case AdminMessage_reboot_ota_seconds_tag: { case AdminMessage_reboot_ota_seconds_tag: {
@@ -135,13 +133,13 @@ bool AdminModule::handleReceivedProtobuf(const MeshPacket &mp, AdminMessage *r)
case AdminMessage_factory_reset_tag: { case AdminMessage_factory_reset_tag: {
DEBUG_MSG("Initiating factory reset\n"); DEBUG_MSG("Initiating factory reset\n");
nodeDB.factoryReset(); nodeDB.factoryReset();
rebootAtMsec = millis() + (5 * 1000); reboot(5);
break; break;
} }
case AdminMessage_nodedb_reset_tag: { case AdminMessage_nodedb_reset_tag: {
DEBUG_MSG("Initiating node-db reset\n"); DEBUG_MSG("Initiating node-db reset\n");
nodeDB.resetNodes(); nodeDB.resetNodes();
rebootAtMsec = millis() + (5 * 1000); reboot(5);
break; break;
} }
#ifdef ARCH_PORTDUINO #ifdef ARCH_PORTDUINO
@@ -196,14 +194,12 @@ void AdminModule::handleSetOwner(const User &o)
if (changed) { // If nothing really changed, don't broadcast on the network or write to flash if (changed) { // If nothing really changed, don't broadcast on the network or write to flash
service.reloadOwner(); service.reloadOwner();
DEBUG_MSG("Rebooting due to owner changes\n"); DEBUG_MSG("Rebooting due to owner changes\n");
screen->startRebootScreen(); reboot(5);
rebootAtMsec = millis() + (5 * 1000);
} }
} }
void AdminModule::handleSetConfig(const Config &c) void AdminModule::handleSetConfig(const Config &c)
{ {
bool requiresReboot = false;
bool isRouter = (config.device.role == Config_DeviceConfig_Role_ROUTER); bool isRouter = (config.device.role == Config_DeviceConfig_Role_ROUTER);
bool isRegionUnset = (config.lora.region == Config_LoRaConfig_RegionCode_UNSET); bool isRegionUnset = (config.lora.region == Config_LoRaConfig_RegionCode_UNSET);
@@ -218,12 +214,13 @@ void AdminModule::handleSetConfig(const Config &c)
nodeDB.initConfigIntervals(); nodeDB.initConfigIntervals();
nodeDB.initModuleConfigIntervals(); nodeDB.initModuleConfigIntervals();
} }
requiresReboot = true;
break; break;
case Config_position_tag: case Config_position_tag:
DEBUG_MSG("Setting config: Position\n"); DEBUG_MSG("Setting config: Position\n");
config.has_position = true; config.has_position = true;
config.position = c.payload_variant.position; config.position = c.payload_variant.position;
// Save nodedb as well in case we got a fixed position packet
nodeDB.saveToDisk(SEGMENT_DEVICESTATE);
break; break;
case Config_power_tag: case Config_power_tag:
DEBUG_MSG("Setting config: Power\n"); DEBUG_MSG("Setting config: Power\n");
@@ -234,7 +231,6 @@ void AdminModule::handleSetConfig(const Config &c)
DEBUG_MSG("Setting config: WiFi\n"); DEBUG_MSG("Setting config: WiFi\n");
config.has_network = true; config.has_network = true;
config.network = c.payload_variant.network; config.network = c.payload_variant.network;
requiresReboot = true;
break; break;
case Config_display_tag: case Config_display_tag:
DEBUG_MSG("Setting config: Display\n"); DEBUG_MSG("Setting config: Display\n");
@@ -249,23 +245,16 @@ void AdminModule::handleSetConfig(const Config &c)
config.lora.region > Config_LoRaConfig_RegionCode_UNSET) { config.lora.region > Config_LoRaConfig_RegionCode_UNSET) {
config.lora.tx_enabled = true; config.lora.tx_enabled = true;
} }
requiresReboot = true;
break; break;
case Config_bluetooth_tag: case Config_bluetooth_tag:
DEBUG_MSG("Setting config: Bluetooth\n"); DEBUG_MSG("Setting config: Bluetooth\n");
config.has_bluetooth = true; config.has_bluetooth = true;
config.bluetooth = c.payload_variant.bluetooth; config.bluetooth = c.payload_variant.bluetooth;
requiresReboot = true;
break; break;
} }
service.reloadConfig(SEGMENT_CONFIG); service.reloadConfig(SEGMENT_CONFIG);
// Reboot 5 seconds after a config that requires rebooting is set reboot(5);
if (requiresReboot) {
DEBUG_MSG("Rebooting due to config changes\n");
screen->startRebootScreen();
rebootAtMsec = millis() + (5 * 1000);
}
} }
void AdminModule::handleSetModuleConfig(const ModuleConfig &c) void AdminModule::handleSetModuleConfig(const ModuleConfig &c)
@@ -307,8 +296,9 @@ void AdminModule::handleSetModuleConfig(const ModuleConfig &c)
moduleConfig.canned_message = c.payload_variant.canned_message; moduleConfig.canned_message = c.payload_variant.canned_message;
break; break;
} }
service.reloadConfig(SEGMENT_MODULECONFIG); service.reloadConfig(SEGMENT_MODULECONFIG);
reboot(5);
} }
void AdminModule::handleSetChannel(const Channel &cc) void AdminModule::handleSetChannel(const Channel &cc)
@@ -468,6 +458,13 @@ void AdminModule::handleGetChannel(const MeshPacket &req, uint32_t channelIndex)
} }
} }
void AdminModule::reboot(int32_t seconds)
{
DEBUG_MSG("Rebooting in %d seconds\n", seconds);
screen->startRebootScreen();
rebootAtMsec = (seconds < 0) ? 0 : (millis() + seconds * 1000);
}
AdminModule::AdminModule() : ProtobufModule("Admin", PortNum_ADMIN_APP, AdminMessage_fields) AdminModule::AdminModule() : ProtobufModule("Admin", PortNum_ADMIN_APP, AdminMessage_fields)
{ {
// restrict to the admin channel for rx // restrict to the admin channel for rx

View File

@@ -37,6 +37,7 @@ class AdminModule : public ProtobufModule<AdminMessage>
void handleSetConfig(const Config &c); void handleSetConfig(const Config &c);
void handleSetModuleConfig(const ModuleConfig &c); void handleSetModuleConfig(const ModuleConfig &c);
void handleSetChannel(); void handleSetChannel();
void reboot(int32_t seconds);
}; };
extern AdminModule *adminModule; extern AdminModule *adminModule;

View File

@@ -225,7 +225,7 @@ int32_t CannedMessageModule::runOnce()
this->cursor = 0; this->cursor = 0;
this->destSelect = false; this->destSelect = false;
this->notifyObservers(&e); this->notifyObservers(&e);
} else if (((this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT)) && (millis() - this->lastTouchMillis) > INACTIVATE_AFTER_MS) { } else if (((this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT)) && ((millis() - this->lastTouchMillis) > INACTIVATE_AFTER_MS)) {
// Reset module // Reset module
DEBUG_MSG("Reset due to lack of activity.\n"); DEBUG_MSG("Reset due to lack of activity.\n");
e.frameChanged = true; e.frameChanged = true;
@@ -430,6 +430,8 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
{ {
displayedNodeNum = 0; // Not currently showing a node pane displayedNodeNum = 0; // Not currently showing a node pane
char buffer[50];
if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE) { if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE) {
display->setTextAlignment(TEXT_ALIGN_CENTER); display->setTextAlignment(TEXT_ALIGN_CENTER);
display->setFont(FONT_MEDIUM); display->setFont(FONT_MEDIUM);
@@ -445,7 +447,6 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL); display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
display->setColor(BLACK); display->setColor(BLACK);
} }
char buffer[50];
display->drawStringf(0 + x, 0 + y, buffer, "To: %s", cannedMessageModule->getNodeName(this->dest)); display->drawStringf(0 + x, 0 + y, buffer, "To: %s", cannedMessageModule->getNodeName(this->dest));
// used chars right aligned // used chars right aligned
sprintf(buffer, "%d left", Constants_DATA_PAYLOAD_LEN - this->freetext.length()); sprintf(buffer, "%d left", Constants_DATA_PAYLOAD_LEN - this->freetext.length());
@@ -456,11 +457,13 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
if (this->messagesCount > 0) { if (this->messagesCount > 0) {
display->setTextAlignment(TEXT_ALIGN_LEFT); display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(FONT_SMALL); display->setFont(FONT_SMALL);
display->drawString(0 + x, 0 + y, cannedMessageModule->getPrevMessage()); display->drawStringf(0 + x, 0 + y, buffer, "To: %s", cannedMessageModule->getNodeName(this->dest));
display->setFont(FONT_MEDIUM); display->drawString(0 + x, 0 + y + FONT_HEIGHT_SMALL, cannedMessageModule->getPrevMessage());
display->drawString(0 + x, 0 + y + FONT_HEIGHT_SMALL, cannedMessageModule->getCurrentMessage()); display->fillRect(0 + x, 0 + y + FONT_HEIGHT_SMALL * 2, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
display->setFont(FONT_SMALL); display->setColor(BLACK);
display->drawString(0 + x, 0 + y + FONT_HEIGHT_MEDIUM, cannedMessageModule->getNextMessage()); display->drawString(0 + x, 0 + y + FONT_HEIGHT_SMALL * 2, cannedMessageModule->getCurrentMessage());
display->setColor(WHITE);
display->drawString(0 + x, 0 + y + FONT_HEIGHT_SMALL * 3, cannedMessageModule->getNextMessage());
} }
} }
} }

View File

@@ -87,4 +87,4 @@ class CannedMessageModule :
}; };
extern CannedMessageModule *cannedMessageModule; extern CannedMessageModule *cannedMessageModule;
#endif #endif

View File

@@ -3,9 +3,14 @@
#include "NodeDB.h" #include "NodeDB.h"
#include "RTC.h" #include "RTC.h"
#include "Router.h" #include "Router.h"
#include "buzz/buzz.h"
#include "configuration.h" #include "configuration.h"
#include <Arduino.h> #include <Arduino.h>
#ifndef PIN_BUZZER
#define PIN_BUZZER false
#endif
//#include <assert.h> //#include <assert.h>
/* /*
@@ -44,7 +49,11 @@
*/ */
// Default configurations // Default configurations
#ifdef EXT_NOTIFY_OUT
#define EXT_NOTIFICATION_MODULE_OUTPUT EXT_NOTIFY_OUT #define EXT_NOTIFICATION_MODULE_OUTPUT EXT_NOTIFY_OUT
#else
#define EXT_NOTIFICATION_MODULE_OUTPUT 0
#endif
#define EXT_NOTIFICATION_MODULE_OUTPUT_MS 1000 #define EXT_NOTIFICATION_MODULE_OUTPUT_MS 1000
#define ASCII_BELL 0x07 #define ASCII_BELL 0x07
@@ -75,7 +84,9 @@ int32_t ExternalNotificationModule::runOnce()
: EXT_NOTIFICATION_MODULE_OUTPUT_MS) < : EXT_NOTIFICATION_MODULE_OUTPUT_MS) <
millis()) { millis()) {
DEBUG_MSG("Turning off external notification\n"); DEBUG_MSG("Turning off external notification\n");
setExternalOff(); if (output != PIN_BUZZER) {
setExternalOff();
}
} }
} }
@@ -84,27 +95,19 @@ int32_t ExternalNotificationModule::runOnce()
void ExternalNotificationModule::setExternalOn() void ExternalNotificationModule::setExternalOn()
{ {
#ifdef EXT_NOTIFY_OUT
externalCurrentState = 1; externalCurrentState = 1;
externalTurnedOn = millis(); externalTurnedOn = millis();
digitalWrite((moduleConfig.external_notification.output digitalWrite(output,
? moduleConfig.external_notification.output
: EXT_NOTIFICATION_MODULE_OUTPUT),
(moduleConfig.external_notification.active ? true : false)); (moduleConfig.external_notification.active ? true : false));
#endif
} }
void ExternalNotificationModule::setExternalOff() void ExternalNotificationModule::setExternalOff()
{ {
#ifdef EXT_NOTIFY_OUT
externalCurrentState = 0; externalCurrentState = 0;
digitalWrite((moduleConfig.external_notification.output digitalWrite(output,
? moduleConfig.external_notification.output
: EXT_NOTIFICATION_MODULE_OUTPUT),
(moduleConfig.external_notification.active ? false : true)); (moduleConfig.external_notification.active ? false : true));
#endif
} }
// -------- // --------
@@ -116,8 +119,6 @@ ExternalNotificationModule::ExternalNotificationModule()
// restrict to the admin channel for rx // restrict to the admin channel for rx
boundChannel = Channels::gpioChannel; boundChannel = Channels::gpioChannel;
#ifdef EXT_NOTIFY_OUT
/* /*
Uncomment the preferences below if you want to use the module Uncomment the preferences below if you want to use the module
without having to configure it from the PythonAPI or WebUI. without having to configure it from the PythonAPI or WebUI.
@@ -135,25 +136,27 @@ ExternalNotificationModule::ExternalNotificationModule()
DEBUG_MSG("Initializing External Notification Module\n"); DEBUG_MSG("Initializing External Notification Module\n");
// Set the direction of a pin output = moduleConfig.external_notification.output
pinMode((moduleConfig.external_notification.output ? moduleConfig.external_notification.output
? moduleConfig.external_notification.output : EXT_NOTIFICATION_MODULE_OUTPUT;
: EXT_NOTIFICATION_MODULE_OUTPUT),
OUTPUT);
// Turn off the pin if (output != PIN_BUZZER) {
setExternalOff(); // Set the direction of a pin
DEBUG_MSG("Using Pin %i in digital mode\n", output);
pinMode(output, OUTPUT);
// Turn off the pin
setExternalOff();
} else{
DEBUG_MSG("Using Pin %i in PWM mode\n", output);
}
} else { } else {
DEBUG_MSG("External Notification Module Disabled\n"); DEBUG_MSG("External Notification Module Disabled\n");
enabled = false; enabled = false;
} }
#endif
} }
ProcessMessage ExternalNotificationModule::handleReceived(const MeshPacket &mp) ProcessMessage ExternalNotificationModule::handleReceived(const MeshPacket &mp)
{ {
#ifdef EXT_NOTIFY_OUT
if (moduleConfig.external_notification.enabled) { if (moduleConfig.external_notification.enabled) {
if (getFrom(&mp) != nodeDB.getNodeNum()) { if (getFrom(&mp) != nodeDB.getNodeNum()) {
@@ -165,21 +168,28 @@ ProcessMessage ExternalNotificationModule::handleReceived(const MeshPacket &mp)
DEBUG_MSG("externalNotificationModule - Notification Bell\n"); DEBUG_MSG("externalNotificationModule - Notification Bell\n");
for (int i = 0; i < p.payload.size; i++) { for (int i = 0; i < p.payload.size; i++) {
if (p.payload.bytes[i] == ASCII_BELL) { if (p.payload.bytes[i] == ASCII_BELL) {
setExternalOn(); if (output != PIN_BUZZER) {
setExternalOn();
} else {
playBeep();
}
} }
} }
} }
if (moduleConfig.external_notification.alert_message) { if (moduleConfig.external_notification.alert_message) {
DEBUG_MSG("externalNotificationModule - Notification Module\n"); DEBUG_MSG("externalNotificationModule - Notification Module\n");
setExternalOn(); if (output != PIN_BUZZER) {
setExternalOn();
} else {
playBeep();
}
} }
} }
} else { } else {
DEBUG_MSG("External Notification Module Disabled\n"); DEBUG_MSG("External Notification Module Disabled\n");
} }
#endif
return ProcessMessage::CONTINUE; // Let others look at this message also if they want return ProcessMessage::CONTINUE; // Let others look at this message also if they want
} }

View File

@@ -12,6 +12,8 @@
*/ */
class ExternalNotificationModule : public SinglePortModule, private concurrency::OSThread class ExternalNotificationModule : public SinglePortModule, private concurrency::OSThread
{ {
uint32_t output = 0;
public: public:
ExternalNotificationModule(); ExternalNotificationModule();

View File

@@ -60,13 +60,15 @@ void setupModules()
new DeviceTelemetryModule(); new DeviceTelemetryModule();
new EnvironmentTelemetryModule(); new EnvironmentTelemetryModule();
#endif #endif
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(TTGO_T_ECHO)
new SerialModule();
#endif
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
// Only run on an esp32 based device. // Only run on an esp32 based device.
/* /*
Maintained by MC Hamster (Jm Casler) jm@casler.org Maintained by MC Hamster (Jm Casler) jm@casler.org
*/ */
new SerialModule();
new ExternalNotificationModule(); new ExternalNotificationModule();
storeForwardModule = new StoreForwardModule(); storeForwardModule = new StoreForwardModule();

View File

@@ -108,7 +108,7 @@ MeshPacket *PositionModule::allocReply()
// Strip out any time information before sending packets to other nodes - to keep the wire size small (and because other // Strip out any time information before sending packets to other nodes - to keep the wire size small (and because other
// nodes shouldn't trust it anyways) Note: we allow a device with a local GPS to include the time, so that gpsless // nodes shouldn't trust it anyways) Note: we allow a device with a local GPS to include the time, so that gpsless
// devices can get time. // devices can get time.
if (getRTCQuality() < RTCQualityGPS) { if (getRTCQuality() < RTCQualityDevice) {
DEBUG_MSG("Stripping time %u from position send\n", p.time); DEBUG_MSG("Stripping time %u from position send\n", p.time);
p.time = 0; p.time = 0;
} else } else

View File

@@ -2,6 +2,7 @@
#include "MeshService.h" #include "MeshService.h"
#include "NodeDB.h" #include "NodeDB.h"
#include "RTC.h" #include "RTC.h"
#include "NMEAWPL.h"
#include "Router.h" #include "Router.h"
#include "configuration.h" #include "configuration.h"
#include <Arduino.h> #include <Arduino.h>
@@ -40,7 +41,7 @@
KNOWN PROBLEMS KNOWN PROBLEMS
* Until the module is initilized by the startup sequence, the TX pin is in a floating * Until the module is initilized by the startup sequence, the TX pin is in a floating
state. Device connected to that pin may see this as "noise". state. Device connected to that pin may see this as "noise".
* Will not work on NRF and the Linux device targets. * Will not work on T-Echo and the Linux device targets.
*/ */
@@ -62,16 +63,19 @@ char serialStringChar[Constants_DATA_PAYLOAD_LEN];
SerialModuleRadio::SerialModuleRadio() : MeshModule("SerialModuleRadio") SerialModuleRadio::SerialModuleRadio() : MeshModule("SerialModuleRadio")
{ {
// restrict to the admin channel for rx
boundChannel = Channels::serialChannel;
switch (moduleConfig.serial.mode) switch (moduleConfig.serial.mode)
{ {
case ModuleConfig_SerialConfig_Serial_Mode_TEXTMSG: case ModuleConfig_SerialConfig_Serial_Mode_TEXTMSG:
ourPortNum = PortNum_TEXT_MESSAGE_APP; ourPortNum = PortNum_TEXT_MESSAGE_APP;
break; break;
case ModuleConfig_SerialConfig_Serial_Mode_NMEA:
ourPortNum = PortNum_POSITION_APP;
break;
default: default:
ourPortNum = PortNum_SERIAL_APP; ourPortNum = PortNum_SERIAL_APP;
// restrict to the serial channel for rx
boundChannel = Channels::serialChannel;
break; break;
} }
} }
@@ -175,15 +179,25 @@ int32_t SerialModule::runOnce()
firstTime = 0; firstTime = 0;
} else { } else {
String serialString;
while (Serial2.available()) { // in NMEA mode send out GGA every 2 seconds, Don't read from Port
serialString = Serial2.readString(); if (moduleConfig.serial.mode == ModuleConfig_SerialConfig_Serial_Mode_NMEA) {
serialString.toCharArray(serialStringChar, Constants_DATA_PAYLOAD_LEN); if (millis() - lastNmeaTime > 2000) {
lastNmeaTime = millis();
printGGA(outbuf, nodeDB.getNode(myNodeInfo.my_node_num)->position);
Serial2.printf("%s", outbuf);
}
} else {
String serialString;
serialModuleRadio->sendPayload(); while (Serial2.available()) {
serialString = Serial2.readString();
serialString.toCharArray(serialStringChar, Constants_DATA_PAYLOAD_LEN);
DEBUG_MSG("Received: %s\n", serialStringChar); serialModuleRadio->sendPayload();
DEBUG_MSG("Received: %s\n", serialStringChar);
}
} }
} }
@@ -191,7 +205,7 @@ int32_t SerialModule::runOnce()
} else { } else {
DEBUG_MSG("Serial Module Disabled\n"); DEBUG_MSG("Serial Module Disabled\n");
return (INT32_MAX); return INT32_MAX;
} }
#else #else
return INT32_MAX; return INT32_MAX;
@@ -255,6 +269,19 @@ ProcessMessage SerialModuleRadio::handleReceived(const MeshPacket &mp)
} else if (moduleConfig.serial.mode == ModuleConfig_SerialConfig_Serial_Mode_PROTO) { } else if (moduleConfig.serial.mode == ModuleConfig_SerialConfig_Serial_Mode_PROTO) {
// TODO this needs to be implemented // TODO this needs to be implemented
} else if (moduleConfig.serial.mode == ModuleConfig_SerialConfig_Serial_Mode_NMEA) {
// Decode the Payload some more
Position scratch;
Position *decoded = NULL;
if (mp.which_payload_variant == MeshPacket_decoded_tag && mp.decoded.portnum == ourPortNum) {
memset(&scratch, 0, sizeof(scratch));
if (pb_decode_from_bytes(p.payload.bytes, p.payload.size, Position_fields, &scratch)) {
decoded = &scratch;
}
// send position packet as WPL to the serial port
printWPL(outbuf, *decoded, nodeDB.getNode(getFrom(&mp))->user.long_name);
Serial2.printf("%s", outbuf);
}
} }
} }

View File

@@ -11,6 +11,8 @@
class SerialModule : private concurrency::OSThread class SerialModule : private concurrency::OSThread
{ {
bool firstTime = 1; bool firstTime = 1;
unsigned long lastNmeaTime = millis();
char outbuf[90] = "";
public: public:
SerialModule(); SerialModule();
@@ -28,6 +30,7 @@ extern SerialModule *serialModule;
class SerialModuleRadio : public MeshModule class SerialModuleRadio : public MeshModule
{ {
uint32_t lastRxID = 0; uint32_t lastRxID = 0;
char outbuf[90] = "";
public: public:
SerialModuleRadio(); SerialModuleRadio();

View File

@@ -9,17 +9,20 @@
#include "main.h" #include "main.h"
#include <OLEDDisplay.h> #include <OLEDDisplay.h>
#include <OLEDDisplayUi.h> #include <OLEDDisplayUi.h>
#include "MeshService.h"
int32_t DeviceTelemetryModule::runOnce() int32_t DeviceTelemetryModule::runOnce()
{ {
#ifndef ARCH_PORTDUINO #ifndef ARCH_PORTDUINO
uint32_t now = millis(); uint32_t now = millis();
if ((lastSentToMesh == 0 || (now - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.telemetry.device_update_interval)) if ((lastSentToMesh == 0 ||
&& airTime->channelUtilizationPercent() < max_channel_util_percent) { (now - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.telemetry.device_update_interval)) &&
airTime->channelUtilizationPercent() < max_channel_util_percent) {
sendTelemetry(); sendTelemetry();
lastSentToMesh = now; lastSentToMesh = now;
} else { } else if (service.isToPhoneQueueEmpty()) {
// Just send to phone when it's not our time to send to mesh yet // Just send to phone when it's not our time to send to mesh yet
// Only send while queue is empty (phone assumed connected)
sendTelemetry(NODENUM_BROADCAST, true); sendTelemetry(NODENUM_BROADCAST, true);
} }
return sendToPhoneIntervalMs; return sendToPhoneIntervalMs;
@@ -30,14 +33,13 @@ bool DeviceTelemetryModule::handleReceivedProtobuf(const MeshPacket &mp, Telemet
{ {
if (t->which_variant == Telemetry_device_metrics_tag) { if (t->which_variant == Telemetry_device_metrics_tag) {
const char *sender = getSenderShortName(mp); const char *sender = getSenderShortName(mp);
DEBUG_MSG("-----------------------------------------\n"); DEBUG_MSG("(Received from %s): air_util_tx=%f, channel_utilization=%f, battery_level=%i, voltage=%f\n",
DEBUG_MSG("Device Telemetry: Received data from %s\n", sender); sender,
DEBUG_MSG("Telemetry->time: %i\n", t->time); t->variant.device_metrics.air_util_tx,
DEBUG_MSG("Telemetry->air_util_tx: %f\n", t->variant.device_metrics.air_util_tx); t->variant.device_metrics.channel_utilization,
DEBUG_MSG("Telemetry->battery_level: %i\n", t->variant.device_metrics.battery_level); t->variant.device_metrics.battery_level,
DEBUG_MSG("Telemetry->channel_utilization: %f\n", t->variant.device_metrics.channel_utilization); t->variant.device_metrics.voltage);
DEBUG_MSG("Telemetry->voltage: %f\n", t->variant.device_metrics.voltage);
lastMeasurementPacket = packetPool.allocCopy(mp); lastMeasurementPacket = packetPool.allocCopy(mp);
@@ -58,26 +60,24 @@ bool DeviceTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
t.variant.device_metrics.channel_utilization = myNodeInfo.channel_utilization; t.variant.device_metrics.channel_utilization = myNodeInfo.channel_utilization;
t.variant.device_metrics.voltage = powerStatus->getBatteryVoltageMv() / 1000.0; t.variant.device_metrics.voltage = powerStatus->getBatteryVoltageMv() / 1000.0;
DEBUG_MSG("-----------------------------------------\n"); DEBUG_MSG("(Sending): air_util_tx=%f, channel_utilization=%f, battery_level=%i, voltage=%f\n",
DEBUG_MSG("Device Telemetry: Read data\n"); t.variant.device_metrics.air_util_tx,
t.variant.device_metrics.channel_utilization,
DEBUG_MSG("Telemetry->time: %i\n", t.time); t.variant.device_metrics.battery_level,
DEBUG_MSG("Telemetry->air_util_tx: %f\n", t.variant.device_metrics.air_util_tx); t.variant.device_metrics.voltage);
DEBUG_MSG("Telemetry->battery_level: %i\n", t.variant.device_metrics.battery_level);
DEBUG_MSG("Telemetry->channel_utilization: %f\n", t.variant.device_metrics.channel_utilization);
DEBUG_MSG("Telemetry->voltage: %f\n", t.variant.device_metrics.voltage);
MeshPacket *p = allocDataProtobuf(t); MeshPacket *p = allocDataProtobuf(t);
p->to = dest; p->to = dest;
p->decoded.want_response = false; p->decoded.want_response = false;
p->priority = MeshPacket_Priority_MIN;
lastMeasurementPacket = packetPool.allocCopy(*p); lastMeasurementPacket = packetPool.allocCopy(*p);
nodeDB.updateTelemetry(nodeDB.getNodeNum(), t, RX_SRC_LOCAL); nodeDB.updateTelemetry(nodeDB.getNodeNum(), t, RX_SRC_LOCAL);
if (phoneOnly) { if (phoneOnly) {
DEBUG_MSG("Device Telemetry: Sending packet to phone\n"); DEBUG_MSG("Sending packet to phone\n");
service.sendToPhone(p); service.sendToPhone(p);
} else { } else {
DEBUG_MSG("Device Telemetry: Sending packet to mesh\n"); DEBUG_MSG("Sending packet to mesh\n");
service.sendToMesh(p, RX_SRC_LOCAL, true); service.sendToMesh(p, RX_SRC_LOCAL, true);
} }
return true; return true;

View File

@@ -11,7 +11,8 @@ class DeviceTelemetryModule : private concurrency::OSThread, public ProtobufModu
DeviceTelemetryModule() DeviceTelemetryModule()
: concurrency::OSThread("DeviceTelemetryModule"), ProtobufModule("DeviceTelemetry", PortNum_TELEMETRY_APP, &Telemetry_msg) : concurrency::OSThread("DeviceTelemetryModule"), ProtobufModule("DeviceTelemetry", PortNum_TELEMETRY_APP, &Telemetry_msg)
{ {
lastMeasurementPacket = nullptr; lastMeasurementPacket = nullptr;
setIntervalFromNow(10 * 1000);
} }
virtual bool wantUIFrame() { return false; } virtual bool wantUIFrame() { return false; }

View File

@@ -9,6 +9,7 @@
#include "main.h" #include "main.h"
#include <OLEDDisplay.h> #include <OLEDDisplay.h>
#include <OLEDDisplayUi.h> #include <OLEDDisplayUi.h>
#include "MeshService.h"
// Sensors // Sensors
#include "Sensor/BMP280Sensor.h" #include "Sensor/BMP280Sensor.h"
@@ -17,6 +18,8 @@
#include "Sensor/MCP9808Sensor.h" #include "Sensor/MCP9808Sensor.h"
#include "Sensor/INA260Sensor.h" #include "Sensor/INA260Sensor.h"
#include "Sensor/INA219Sensor.h" #include "Sensor/INA219Sensor.h"
#include "Sensor/SHTC3Sensor.h"
#include "Sensor/LPS22HBSensor.h"
BMP280Sensor bmp280Sensor; BMP280Sensor bmp280Sensor;
BME280Sensor bme280Sensor; BME280Sensor bme280Sensor;
@@ -24,6 +27,8 @@ BME680Sensor bme680Sensor;
MCP9808Sensor mcp9808Sensor; MCP9808Sensor mcp9808Sensor;
INA260Sensor ina260Sensor; INA260Sensor ina260Sensor;
INA219Sensor ina219Sensor; INA219Sensor ina219Sensor;
SHTC3Sensor shtc3Sensor;
LPS22HBSensor lps22hbSensor;
#define FAILED_STATE_SENSOR_READ_MULTIPLIER 10 #define FAILED_STATE_SENSOR_READ_MULTIPLIER 10
#define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true #define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true
@@ -83,21 +88,31 @@ int32_t EnvironmentTelemetryModule::runOnce()
result = ina260Sensor.runOnce(); result = ina260Sensor.runOnce();
if (ina219Sensor.hasSensor()) if (ina219Sensor.hasSensor())
result = ina219Sensor.runOnce(); result = ina219Sensor.runOnce();
if (shtc3Sensor.hasSensor())
result = shtc3Sensor.runOnce();
if (lps22hbSensor.hasSensor()) {
result = lps22hbSensor.runOnce();
}
} }
return result; return result;
} else { } else {
// if we somehow got to a second run of this module with measurement disabled, then just wait forever // if we somehow got to a second run of this module with measurement disabled, then just wait forever
if (!moduleConfig.telemetry.environment_measurement_enabled) if (!moduleConfig.telemetry.environment_measurement_enabled)
return result; return result;
// this is not the first time OSThread library has called this function
// so just do what we intend to do on the interval uint32_t now = millis();
if (!sendOurTelemetry()) { if ((lastSentToMesh == 0 ||
// if we failed to read the sensor, then try again (now - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.telemetry.environment_update_interval)) &&
// as soon as we can according to the maximum polling frequency airTime->channelUtilizationPercent() < max_channel_util_percent) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; sendTelemetry();
lastSentToMesh = now;
} else if (service.isToPhoneQueueEmpty()) {
// Just send to phone when it's not our time to send to mesh yet
// Only send while queue is empty (phone assumed connected)
sendTelemetry(NODENUM_BROADCAST, true);
} }
} }
return getConfiguredOrDefaultMs(moduleConfig.telemetry.environment_update_interval); return sendToPhoneIntervalMs;
#endif #endif
} }
@@ -143,7 +158,7 @@ void EnvironmentTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiSt
if (!pb_decode_from_bytes(p.payload.bytes, p.payload.size, Telemetry_fields, &lastMeasurement)) { if (!pb_decode_from_bytes(p.payload.bytes, p.payload.size, Telemetry_fields, &lastMeasurement)) {
display->setFont(FONT_SMALL); display->setFont(FONT_SMALL);
display->drawString(x, y += fontHeight(FONT_MEDIUM), "Measurement Error"); display->drawString(x, y += fontHeight(FONT_MEDIUM), "Measurement Error");
DEBUG_MSG("Environment Telemetry: unable to decode last packet"); DEBUG_MSG("Unable to decode last packet");
return; return;
} }
@@ -168,15 +183,14 @@ bool EnvironmentTelemetryModule::handleReceivedProtobuf(const MeshPacket &mp, Te
if (t->which_variant == Telemetry_environment_metrics_tag) { if (t->which_variant == Telemetry_environment_metrics_tag) {
const char *sender = getSenderShortName(mp); const char *sender = getSenderShortName(mp);
DEBUG_MSG("-----------------------------------------\n"); DEBUG_MSG("(Received from %s): barometric_pressure=%f, current=%f, gas_resistance=%f, relative_humidity=%f, temperature=%f, voltage=%f\n",
DEBUG_MSG("Environment Telemetry: Received data from %s\n", sender); sender,
DEBUG_MSG("Telemetry->time: %i\n", t->time); t->variant.environment_metrics.barometric_pressure,
DEBUG_MSG("Telemetry->barometric_pressure: %f\n", t->variant.environment_metrics.barometric_pressure); t->variant.environment_metrics.current,
DEBUG_MSG("Telemetry->current: %f\n", t->variant.environment_metrics.current); t->variant.environment_metrics.gas_resistance,
DEBUG_MSG("Telemetry->gas_resistance: %f\n", t->variant.environment_metrics.gas_resistance); t->variant.environment_metrics.relative_humidity,
DEBUG_MSG("Telemetry->relative_humidity: %f\n", t->variant.environment_metrics.relative_humidity); t->variant.environment_metrics.temperature,
DEBUG_MSG("Telemetry->temperature: %f\n", t->variant.environment_metrics.temperature); t->variant.environment_metrics.voltage);
DEBUG_MSG("Telemetry->voltage: %f\n", t->variant.environment_metrics.voltage);
lastMeasurementPacket = packetPool.allocCopy(mp); lastMeasurementPacket = packetPool.allocCopy(mp);
} }
@@ -184,7 +198,7 @@ bool EnvironmentTelemetryModule::handleReceivedProtobuf(const MeshPacket &mp, Te
return false; // Let others look at this message also if they want return false; // Let others look at this message also if they want
} }
bool EnvironmentTelemetryModule::sendOurTelemetry(NodeNum dest, bool wantReplies) bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
{ {
Telemetry m; Telemetry m;
m.time = getTime(); m.time = getTime();
@@ -197,9 +211,10 @@ bool EnvironmentTelemetryModule::sendOurTelemetry(NodeNum dest, bool wantReplies
m.variant.environment_metrics.temperature = 0; m.variant.environment_metrics.temperature = 0;
m.variant.environment_metrics.voltage = 0; m.variant.environment_metrics.voltage = 0;
DEBUG_MSG("-----------------------------------------\n"); if (lps22hbSensor.hasSensor())
DEBUG_MSG("Environment Telemetry: Read data\n"); lps22hbSensor.getMetrics(&m);
if (shtc3Sensor.hasSensor())
shtc3Sensor.getMetrics(&m);
if (bmp280Sensor.hasSensor()) if (bmp280Sensor.hasSensor())
bmp280Sensor.getMetrics(&m); bmp280Sensor.getMetrics(&m);
if (bme280Sensor.hasSensor()) if (bme280Sensor.hasSensor())
@@ -213,22 +228,28 @@ bool EnvironmentTelemetryModule::sendOurTelemetry(NodeNum dest, bool wantReplies
if (ina260Sensor.hasSensor()) if (ina260Sensor.hasSensor())
ina260Sensor.getMetrics(&m); ina260Sensor.getMetrics(&m);
DEBUG_MSG("Telemetry->time: %i\n", m.time); DEBUG_MSG("(Sending): barometric_pressure=%f, current=%f, gas_resistance=%f, relative_humidity=%f, temperature=%f, voltage=%f\n",
DEBUG_MSG("Telemetry->barometric_pressure: %f\n", m.variant.environment_metrics.barometric_pressure); m.variant.environment_metrics.barometric_pressure,
DEBUG_MSG("Telemetry->current: %f\n", m.variant.environment_metrics.current); m.variant.environment_metrics.current,
DEBUG_MSG("Telemetry->gas_resistance: %f\n", m.variant.environment_metrics.gas_resistance); m.variant.environment_metrics.gas_resistance,
DEBUG_MSG("Telemetry->relative_humidity: %f\n", m.variant.environment_metrics.relative_humidity); m.variant.environment_metrics.relative_humidity,
DEBUG_MSG("Telemetry->temperature: %f\n", m.variant.environment_metrics.temperature); m.variant.environment_metrics.temperature,
DEBUG_MSG("Telemetry->voltage: %f\n", m.variant.environment_metrics.voltage); m.variant.environment_metrics.voltage);
sensor_read_error_count = 0; sensor_read_error_count = 0;
MeshPacket *p = allocDataProtobuf(m); MeshPacket *p = allocDataProtobuf(m);
p->to = dest; p->to = dest;
p->decoded.want_response = wantReplies; p->decoded.want_response = false;
p->priority = MeshPacket_Priority_MIN;
lastMeasurementPacket = packetPool.allocCopy(*p); lastMeasurementPacket = packetPool.allocCopy(*p);
DEBUG_MSG("Environment Telemetry: Sending packet to mesh"); if (phoneOnly) {
service.sendToMesh(p, RX_SRC_LOCAL, true); DEBUG_MSG("Sending packet to phone\n");
service.sendToPhone(p);
} else {
DEBUG_MSG("Sending packet to mesh\n");
service.sendToMesh(p, RX_SRC_LOCAL, true);
}
return true; return true;
} }

View File

@@ -12,7 +12,8 @@ class EnvironmentTelemetryModule : private concurrency::OSThread, public Protobu
: concurrency::OSThread("EnvironmentTelemetryModule"), : concurrency::OSThread("EnvironmentTelemetryModule"),
ProtobufModule("EnvironmentTelemetry", PortNum_TELEMETRY_APP, &Telemetry_msg) ProtobufModule("EnvironmentTelemetry", PortNum_TELEMETRY_APP, &Telemetry_msg)
{ {
lastMeasurementPacket = nullptr; lastMeasurementPacket = nullptr;
setIntervalFromNow(10 * 1000);
} }
virtual bool wantUIFrame() override; virtual bool wantUIFrame() override;
#if !HAS_SCREEN #if !HAS_SCREEN
@@ -30,11 +31,13 @@ class EnvironmentTelemetryModule : private concurrency::OSThread, public Protobu
/** /**
* Send our Telemetry into the mesh * Send our Telemetry into the mesh
*/ */
bool sendOurTelemetry(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false); bool sendTelemetry(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false);
private: private:
float CelsiusToFahrenheit(float c); float CelsiusToFahrenheit(float c);
bool firstTime = 1; bool firstTime = 1;
const MeshPacket *lastMeasurementPacket; const MeshPacket *lastMeasurementPacket;
uint32_t sendToPhoneIntervalMs = SECONDS_IN_MINUTE * 1000; // Send to phone every minute
uint32_t lastSentToMesh = 0;
uint32_t sensor_read_error_count = 0; uint32_t sensor_read_error_count = 0;
}; };

View File

@@ -0,0 +1,36 @@
#include "../mesh/generated/telemetry.pb.h"
#include "configuration.h"
#include "TelemetrySensor.h"
#include "LPS22HBSensor.h"
#include <Adafruit_LPS2X.h>
#include <Adafruit_Sensor.h>
LPS22HBSensor::LPS22HBSensor() :
TelemetrySensor(TelemetrySensorType_LPS22, "LPS22HB")
{
}
int32_t LPS22HBSensor::runOnce() {
DEBUG_MSG("Init sensor: %s\n", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
status = lps22hb.begin_I2C(nodeTelemetrySensorsMap[sensorType]);
return initI2CSensor();
}
void LPS22HBSensor::setup()
{
lps22hb.setDataRate(LPS22_RATE_10_HZ);
}
bool LPS22HBSensor::getMetrics(Telemetry *measurement) {
sensors_event_t temp;
sensors_event_t pressure;
lps22hb.getEvent(&pressure, &temp);
measurement->variant.environment_metrics.temperature = temp.temperature;
measurement->variant.environment_metrics.barometric_pressure = pressure.pressure;
return true;
}

View File

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

View File

@@ -0,0 +1,34 @@
#include "../mesh/generated/telemetry.pb.h"
#include "configuration.h"
#include "TelemetrySensor.h"
#include "SHTC3Sensor.h"
#include <Adafruit_SHTC3.h>
SHTC3Sensor::SHTC3Sensor() :
TelemetrySensor(TelemetrySensorType_SHTC3, "SHTC3")
{
}
int32_t SHTC3Sensor::runOnce() {
DEBUG_MSG("Init sensor: %s\n", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
status = shtc3.begin();
return initI2CSensor();
}
void SHTC3Sensor::setup()
{
// Set up oversampling and filter initialization
}
bool SHTC3Sensor::getMetrics(Telemetry *measurement) {
sensors_event_t humidity, temp;
shtc3.getEvent(&humidity, &temp);
measurement->variant.environment_metrics.temperature = temp.temperature;
measurement->variant.environment_metrics.relative_humidity = humidity.relative_humidity;
return true;
}

View File

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

View File

@@ -8,7 +8,9 @@
#include "mesh/generated/mqtt.pb.h" #include "mesh/generated/mqtt.pb.h"
#include "mesh/generated/telemetry.pb.h" #include "mesh/generated/telemetry.pb.h"
#include "sleep.h" #include "sleep.h"
#if HAS_WIFI
#include <WiFi.h> #include <WiFi.h>
#endif
#include <assert.h> #include <assert.h>
#include <json11.hpp> #include <json11.hpp>
@@ -27,8 +29,9 @@ void MQTT::onPublish(char *topic, byte *payload, unsigned int length)
{ {
// parsing ServiceEnvelope // parsing ServiceEnvelope
ServiceEnvelope e = ServiceEnvelope_init_default; ServiceEnvelope e = ServiceEnvelope_init_default;
if (!pb_decode_from_bytes(payload, length, ServiceEnvelope_fields, &e) && moduleConfig.mqtt.json_enabled) {
// check if this is a json payload message if (moduleConfig.mqtt.json_enabled && (strncmp(topic, jsonTopic.c_str(), jsonTopic.length()) == 0)) {
// check if this is a json payload message by comparing the topic start
using namespace json11; using namespace json11;
char payloadStr[length + 1]; char payloadStr[length + 1];
memcpy(payloadStr, payload, length); memcpy(payloadStr, payload, length);
@@ -36,36 +39,37 @@ void MQTT::onPublish(char *topic, byte *payload, unsigned int length)
std::string err; std::string err;
auto json = Json::parse(payloadStr, err); auto json = Json::parse(payloadStr, err);
if (err.empty()) { if (err.empty()) {
DEBUG_MSG("Received json payload on MQTT, parsing..\n"); DEBUG_MSG("JSON Received on MQTT, parsing..\n");
// check if it is a valid envelope // check if it is a valid envelope
if (json.object_items().count("sender") != 0 && json.object_items().count("payload") != 0) { if (json.object_items().count("sender") != 0 && json.object_items().count("payload") != 0 && json["type"].string_value().compare("sendtext") == 0) {
// this is a valid envelope // this is a valid envelope
if (json["sender"].string_value().compare(owner.id) != 0) { if (json["sender"].string_value().compare(owner.id) != 0) {
std::string jsonPayloadStr = json["payload"].dump(); std::string jsonPayloadStr = json["payload"].dump();
DEBUG_MSG("Received json payload %s, length %u\n", jsonPayloadStr.c_str(), jsonPayloadStr.length()); DEBUG_MSG("JSON payload %s, length %u\n", jsonPayloadStr.c_str(), jsonPayloadStr.length());
// FIXME Not sure we need to be doing this
// construct protobuf data packet using TEXT_MESSAGE, send it to the mesh // construct protobuf data packet using TEXT_MESSAGE, send it to the mesh
// MeshPacket *p = router->allocForSending(); MeshPacket *p = router->allocForSending();
// p->decoded.portnum = PortNum_TEXT_MESSAGE_APP; p->decoded.portnum = PortNum_TEXT_MESSAGE_APP;
// if (jsonPayloadStr.length() <= sizeof(p->decoded.payload.bytes)) { if (jsonPayloadStr.length() <= sizeof(p->decoded.payload.bytes)) {
// memcpy(p->decoded.payload.bytes, jsonPayloadStr.c_str(), jsonPayloadStr.length()); memcpy(p->decoded.payload.bytes, jsonPayloadStr.c_str(), jsonPayloadStr.length());
// p->decoded.payload.size = jsonPayloadStr.length(); p->decoded.payload.size = jsonPayloadStr.length();
// MeshPacket *packet = packetPool.allocCopy(*p); MeshPacket *packet = packetPool.allocCopy(*p);
// service.sendToMesh(packet, RX_SRC_LOCAL); service.sendToMesh(packet, RX_SRC_LOCAL);
// } else { } else {
// DEBUG_MSG("Received MQTT json payload too long, dropping\n"); DEBUG_MSG("Received MQTT json payload too long, dropping\n");
// } }
} else { } else {
DEBUG_MSG("Ignoring downlink message we originally sent.\n"); DEBUG_MSG("JSON Ignoring downlink message we originally sent.\n");
} }
} else { } else {
DEBUG_MSG("Received json payload on MQTT but not a valid envelope\n"); DEBUG_MSG("JSON Received payload on MQTT but not a valid envelope\n");
} }
} else { } else {
// no json, this is an invalid payload // no json, this is an invalid payload
DEBUG_MSG("Invalid MQTT service envelope, topic %s, len %u!\n", topic, length); DEBUG_MSG("Invalid MQTT service envelope, topic %s, len %u!\n", topic, length);
} }
} else { } else {
pb_decode_from_bytes(payload, length, ServiceEnvelope_fields, &e);
if (strcmp(e.gateway_id, owner.id) == 0) if (strcmp(e.gateway_id, owner.id) == 0)
DEBUG_MSG("Ignoring downlink message we originally sent.\n"); DEBUG_MSG("Ignoring downlink message we originally sent.\n");
else { else {
@@ -103,6 +107,11 @@ MQTT::MQTT() : concurrency::OSThread("mqtt"), pubSub(mqttClient)
// preflightSleepObserver.observe(&preflightSleep); // preflightSleepObserver.observe(&preflightSleep);
} }
bool MQTT::connected()
{
return pubSub.connected();
}
void MQTT::reconnect() void MQTT::reconnect()
{ {
if (wantsLink()) { if (wantsLink()) {
@@ -187,7 +196,13 @@ bool MQTT::wantsLink() const
} }
} }
#if HAS_WIFI
return hasChannel && WiFi.isConnected(); return hasChannel && WiFi.isConnected();
#endif
#if HAS_ETHERNET
return hasChannel && (Ethernet.linkStatus() == LinkON);
#endif
return false;
} }
int32_t MQTT::runOnce() int32_t MQTT::runOnce()
@@ -243,7 +258,7 @@ void MQTT::onSend(const MeshPacket &mp, ChannelIndex chIndex)
auto jsonString = this->downstreamPacketToJson((MeshPacket *)&mp); auto jsonString = this->downstreamPacketToJson((MeshPacket *)&mp);
if (jsonString.length() != 0) { if (jsonString.length() != 0) {
String topicJson = jsonTopic + channelId + "/" + owner.id; String topicJson = jsonTopic + channelId + "/" + owner.id;
DEBUG_MSG("publish json message to %s, %u bytes: %s\n", topicJson.c_str(), jsonString.length(), jsonString.c_str()); DEBUG_MSG("JSON publish message to %s, %u bytes: %s\n", topicJson.c_str(), jsonString.length(), jsonString.c_str());
pubSub.publish(topicJson.c_str(), jsonString.c_str(), false); pubSub.publish(topicJson.c_str(), jsonString.c_str(), false);
} }
} }
@@ -251,7 +266,7 @@ void MQTT::onSend(const MeshPacket &mp, ChannelIndex chIndex)
} }
// converts a downstream packet into a json message // converts a downstream packet into a json message
String MQTT::downstreamPacketToJson(MeshPacket *mp) std::string MQTT::downstreamPacketToJson(MeshPacket *mp)
{ {
using namespace json11; using namespace json11;
@@ -279,7 +294,7 @@ String MQTT::downstreamPacketToJson(MeshPacket *mp)
// if it isn't, then we need to create a json object // if it isn't, then we need to create a json object
// with the string as the value // with the string as the value
DEBUG_MSG("text message payload is of type plaintext\n"); DEBUG_MSG("text message payload is of type plaintext\n");
msgPayload = Json::object({{"text", payloadStr}}); msgPayload = Json::object{{"text", payloadStr}};
} }
break; break;
} }
@@ -344,9 +359,9 @@ String MQTT::downstreamPacketToJson(MeshPacket *mp)
msgPayload = Json::object{ msgPayload = Json::object{
{"time", (int)decoded->time}, {"time", (int)decoded->time},
{"pos_timestamp", (int)decoded->timestamp}, {"pos_timestamp", (int)decoded->timestamp},
{"latitude_i", decoded->latitude_i}, {"latitude_i", (int)decoded->latitude_i},
{"longitude_i", decoded->longitude_i}, {"longitude_i", (int)decoded->longitude_i},
{"altitude", decoded->altitude} {"altitude", (int)decoded->altitude}
}; };
} else { } else {
DEBUG_MSG("Error decoding protobuf for position message!\n"); DEBUG_MSG("Error decoding protobuf for position message!\n");
@@ -369,8 +384,8 @@ String MQTT::downstreamPacketToJson(MeshPacket *mp)
{"description", decoded->description}, {"description", decoded->description},
{"expire", (int)decoded->expire}, {"expire", (int)decoded->expire},
{"locked", decoded->locked}, {"locked", decoded->locked},
{"latitude_i", decoded->latitude_i}, {"latitude_i", (int)decoded->latitude_i},
{"longitude_i", decoded->longitude_i}, {"longitude_i", (int)decoded->longitude_i},
}; };
} else { } else {
DEBUG_MSG("Error decoding protobuf for position message!\n"); DEBUG_MSG("Error decoding protobuf for position message!\n");
@@ -396,8 +411,8 @@ String MQTT::downstreamPacketToJson(MeshPacket *mp)
}; };
// serialize and return it // serialize and return it
static std::string jsonStr = jsonObj.dump(); std::string jsonStr = jsonObj.dump();
DEBUG_MSG("serialized json message: %s\n", jsonStr.c_str()); DEBUG_MSG("serialized json message: %s\n", jsonStr.c_str());
return jsonStr.c_str(); return jsonStr;
} }

View File

@@ -5,7 +5,12 @@
#include "concurrency/OSThread.h" #include "concurrency/OSThread.h"
#include "mesh/Channels.h" #include "mesh/Channels.h"
#include <PubSubClient.h> #include <PubSubClient.h>
#if HAS_WIFI
#include <WiFiClient.h> #include <WiFiClient.h>
#endif
#if HAS_ETHERNET
#include <EthernetClient.h>
#endif
/** /**
* Our wrapper/singleton for sending/receiving MQTT "udp" packets. This object isolates the MQTT protocol implementation from * Our wrapper/singleton for sending/receiving MQTT "udp" packets. This object isolates the MQTT protocol implementation from
@@ -16,7 +21,12 @@ class MQTT : private concurrency::OSThread
// supposedly the current version is busted: // supposedly the current version is busted:
// http://www.iotsharing.com/2017/08/how-to-use-esp32-mqtts-with-mqtts-mosquitto-broker-tls-ssl.html // http://www.iotsharing.com/2017/08/how-to-use-esp32-mqtts-with-mqtts-mosquitto-broker-tls-ssl.html
// WiFiClientSecure wifiClient; // WiFiClientSecure wifiClient;
#if HAS_WIFI
WiFiClient mqttClient; WiFiClient mqttClient;
#endif
#if HAS_ETHERNET
EthernetClient mqttClient;
#endif
PubSubClient pubSub; PubSubClient pubSub;
// instead we supress sleep from our runOnce() callback // instead we supress sleep from our runOnce() callback
@@ -38,6 +48,8 @@ class MQTT : private concurrency::OSThread
/** Attempt to connect to server if necessary /** Attempt to connect to server if necessary
*/ */
void reconnect(); void reconnect();
bool connected();
protected: protected:
virtual int32_t runOnce() override; virtual int32_t runOnce() override;
@@ -58,7 +70,7 @@ class MQTT : private concurrency::OSThread
void onPublish(char *topic, byte *payload, unsigned int length); void onPublish(char *topic, byte *payload, unsigned int length);
/// Called when a new publish arrives from the MQTT server /// Called when a new publish arrives from the MQTT server
String downstreamPacketToJson(MeshPacket *mp); std::string downstreamPacketToJson(MeshPacket *mp);
/// Return 0 if sleep is okay, veto sleep if we are connected to pubsub server /// Return 0 if sleep is okay, veto sleep if we are connected to pubsub server
// int preflightSleepCb(void *unused = NULL) { return pubSub.connected() ? 1 : 0; } // int preflightSleepCb(void *unused = NULL) { return pubSub.connected() ? 1 : 0; }

27
src/network-stubs.cpp Normal file
View File

@@ -0,0 +1,27 @@
#include "configuration.h"
#if (HAS_WIFI == 0)
bool initWifi() {
return false;
}
void deinitWifi() {}
bool isWifiAvailable() {
return false;
}
#endif
#if (HAS_ETHERNET == 0)
bool initEthernet() {
return false;
}
bool isEthernetAvailable() {
return false;
}
#endif

View File

@@ -12,7 +12,6 @@ NimBLECharacteristic *fromNumCharacteristic;
NimBLEServer *bleServer; NimBLEServer *bleServer;
static bool passkeyShowing; static bool passkeyShowing;
static uint32_t doublepressed;
class BluetoothPhoneAPI : public PhoneAPI class BluetoothPhoneAPI : public PhoneAPI
{ {
@@ -71,12 +70,8 @@ class NimbleBluetoothServerCallback : public NimBLEServerCallbacks
{ {
virtual uint32_t onPassKeyRequest() { virtual uint32_t onPassKeyRequest() {
uint32_t passkey = config.bluetooth.fixed_pin; uint32_t passkey = config.bluetooth.fixed_pin;
if (doublepressed > 0 && (doublepressed + (30 * 1000)) > millis()) { if (config.bluetooth.mode == Config_BluetoothConfig_PairingMode_RANDOM_PIN) {
DEBUG_MSG("User has set BLE pairing mode to fixed-pin\n");
config.bluetooth.mode = Config_BluetoothConfig_PairingMode_FIXED_PIN;
nodeDB.saveToDisk(SEGMENT_CONFIG);
} else if (config.bluetooth.mode == Config_BluetoothConfig_PairingMode_RANDOM_PIN) {
DEBUG_MSG("Using random passkey\n"); DEBUG_MSG("Using random passkey\n");
// This is the passkey to be entered on peer - we pick a number >100,000 to ensure 6 digits // This is the passkey to be entered on peer - we pick a number >100,000 to ensure 6 digits
passkey = random(100000, 999999); passkey = random(100000, 999999);
@@ -202,24 +197,3 @@ void clearNVS()
ESP.restart(); ESP.restart();
#endif #endif
} }
void disablePin()
{
DEBUG_MSG("User Override, disabling bluetooth pin requirement\n");
// keep track of when it was pressed, so we know it was within X seconds
// Flash the LED
setLed(true);
delay(100);
setLed(false);
delay(100);
setLed(true);
delay(100);
setLed(false);
delay(100);
setLed(true);
delay(100);
setLed(false);
doublepressed = millis();
}

View File

@@ -15,4 +15,3 @@ class NimbleBluetooth
void setBluetoothEnable(bool on); void setBluetoothEnable(bool on);
void clearNVS(); void clearNVS();
void disablePin();

View File

@@ -1,19 +0,0 @@
//#include "mesh/wifi/WebServer.h"
#include "configuration.h"
#ifndef ARCH_ESP32
//#include "mesh/wifi/WiFiAPClient.h"
bool initWifi(bool forceSoftAP) {
return false;
}
void deinitWifi() {}
bool isWifiAvailable()
{
return false;
}
#endif

View File

@@ -59,7 +59,7 @@ static const uint8_t SCK = 33;
// https://docs.rakwireless.com/Product-Categories/WisBlock/RAK13300/ // https://docs.rakwireless.com/Product-Categories/WisBlock/RAK13300/
#define LORA_DIO0 26 // a No connect on the SX1262/SX1268 module #define LORA_DIO0 -1 // a No connect on the SX1262/SX1268 module
#define LORA_RESET WB_IO4 // RST for SX1276, and for SX1262/SX1268 #define LORA_RESET WB_IO4 // RST for SX1276, and for SX1262/SX1268
#define LORA_DIO1 WB_IO6 // IRQ for SX1262/SX1268 #define LORA_DIO1 WB_IO6 // IRQ for SX1262/SX1268
#define LORA_DIO2 WB_IO5 // BUSY for SX1262/SX1268 #define LORA_DIO2 WB_IO5 // BUSY for SX1262/SX1268

View File

@@ -3,10 +3,12 @@
extends = nrf52840_base extends = nrf52840_base
board = wiscore_rak4631 board = wiscore_rak4631
build_flags = ${nrf52840_base.build_flags} -Ivariants/rak4631 -D RAK_4631 build_flags = ${nrf52840_base.build_flags} -Ivariants/rak4631 -D RAK_4631
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/rak4631> build_src_filter = ${nrf52_base.build_src_filter} +<../variants/rak4631> +<mesh/eth/> +<mqtt/>
lib_deps = lib_deps =
${nrf52840_base.lib_deps} ${nrf52840_base.lib_deps}
${networking_base.lib_deps}
melopero/Melopero RV3028@^1.1.0 melopero/Melopero RV3028@^1.1.0
https://github.com/meshtastic/RAK13800-W5100S.git#b680706eb8006cd62c919ac74c8af1950eb82c81
debug_tool = jlink debug_tool = jlink
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm) ; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
;upload_protocol = jlink ;upload_protocol = jlink

View File

@@ -185,6 +185,9 @@ static const uint8_t SCK = PIN_SPI_SCK;
#define SX126X_RXEN (37) #define SX126X_RXEN (37)
#define SX126X_E22 // DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3 #define SX126X_E22 // DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
// enables 3.3V periphery like GPS or IO Module
#define PIN_3V3_EN (34)
// RAK1910 GPS module // RAK1910 GPS module
// If using the wisblock GPS module and pluged into Port A on WisBlock base // If using the wisblock GPS module and pluged into Port A on WisBlock base
// IO1 is hooked to PPS (pin 12 on header) = gpio 17 // IO1 is hooked to PPS (pin 12 on header) = gpio 17
@@ -192,7 +195,7 @@ static const uint8_t SCK = PIN_SPI_SCK;
// Therefore must be 1 to keep peripherals powered // Therefore must be 1 to keep peripherals powered
// Power is on the controllable 3V3_S rail // Power is on the controllable 3V3_S rail
// #define PIN_GPS_RESET (34) // #define PIN_GPS_RESET (34)
#define PIN_GPS_EN (34) #define PIN_GPS_EN PIN_3V3_EN
#define PIN_GPS_PPS (17) // Pulse per second input from the GPS #define PIN_GPS_PPS (17) // Pulse per second input from the GPS
#define GPS_RX_PIN PIN_SERIAL1_RX #define GPS_RX_PIN PIN_SERIAL1_RX
@@ -226,6 +229,12 @@ static const uint8_t SCK = PIN_SPI_SCK;
#define HAS_RTC 1 #define HAS_RTC 1
#define HAS_ETHERNET 1
#define PIN_ETHERNET_RESET 21
#define PIN_ETHERNET_SS PIN_EINK_CS
#define ETH_SPI_PORT SPI1
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -185,6 +185,9 @@ static const uint8_t SCK = PIN_SPI_SCK;
#define SX126X_RXEN (37) #define SX126X_RXEN (37)
#define SX126X_E22 // DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3 #define SX126X_E22 // DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
// enables 3.3V periphery like GPS or IO Module
#define PIN_3V3_EN (34)
// RAK1910 GPS module // RAK1910 GPS module
// If using the wisblock GPS module and pluged into Port A on WisBlock base // If using the wisblock GPS module and pluged into Port A on WisBlock base
// IO1 is hooked to PPS (pin 12 on header) = gpio 17 // IO1 is hooked to PPS (pin 12 on header) = gpio 17
@@ -192,7 +195,7 @@ static const uint8_t SCK = PIN_SPI_SCK;
// Therefore must be 1 to keep peripherals powered // Therefore must be 1 to keep peripherals powered
// Power is on the controllable 3V3_S rail // Power is on the controllable 3V3_S rail
// #define PIN_GPS_RESET (34) // #define PIN_GPS_RESET (34)
#define PIN_GPS_EN (34) #define PIN_GPS_EN PIN_3V3_EN
#define PIN_GPS_PPS (17) // Pulse per second input from the GPS #define PIN_GPS_PPS (17) // Pulse per second input from the GPS
#define GPS_RX_PIN PIN_SERIAL1_RX #define GPS_RX_PIN PIN_SERIAL1_RX

View File

@@ -1,12 +1,12 @@
[env:pico] [env:pico]
extends = rp2040_base extends = rp2040_base
board = pico board = rpipico
upload_protocol = picotool upload_protocol = picotool
# add our variants files to the include and src paths # add our variants files to the include and src paths
build_flags = ${rp2040_base.build_flags} build_flags = ${rp2040_base.build_flags}
-DPRIVATE_HW -DPRIVATE_HW
-Ivariants/pico -Ivariants/rpipico
-DARDUINO_AVR_NANO_EVERY -DARDUINO_AVR_NANO_EVERY
-DDEBUG_RP2040_WIRE -DDEBUG_RP2040_WIRE
-DDEBUG_RP2040_SPI -DDEBUG_RP2040_SPI

View File

@@ -0,0 +1,17 @@
[env:picow]
extends = rp2040_base
board = rpipicow
upload_protocol = picotool
# add our variants files to the include and src paths
build_flags = ${rp2040_base.build_flags}
-DPRIVATE_HW
-Ivariants/rpipicow
-DARDUINO_AVR_NANO_EVERY
-DDEBUG_RP2040_WIRE
-DDEBUG_RP2040_SPI
-DDEBUG_RP2040_CORE
-DDEBUG_RP2040_PORT=Serial
-DUSE_TINYUSB
lib_deps =
${rp2040_base.lib_deps}

View File

@@ -0,0 +1,52 @@
// #define RADIOLIB_CUSTOM_ARDUINO 1
// #define RADIOLIB_TONE_UNSUPPORTED 1
// #define RADIOLIB_SOFTWARE_SERIAL_UNSUPPORTED 1
#define ARDUINO_ARCH_AVR
#define CBC 0
#define CTR 1
#define ECB 0
#define NO_GPS 1
#define USE_SH1106 1
#undef GPS_SERIAL_NUM
// #define I2C_SDA 6
// #define I2C_SCL 7
#define BUTTON_PIN 17
#define EXT_NOTIFY_OUT 4
#define BATTERY_PIN 26
// ratio of voltage divider = 3.0 (R17=200k, R18=100k)
#define ADC_MULTIPLIER 3.1 // 3.0 + a bit for being optimistic
#define USE_RF95
#define USE_SX1262
#undef RF95_SCK
#undef RF95_MISO
#undef RF95_MOSI
#undef RF95_NSS
#define RF95_SCK 10
#define RF95_MISO 12
#define RF95_MOSI 11
#define RF95_NSS 3
#define LORA_DIO0 RADIOLIB_NC
#define LORA_RESET 15
#define LORA_DIO1 20
#define LORA_DIO2 2
#define LORA_DIO3 RADIOLIB_NC
#ifdef USE_SX1262
#define SX126X_CS RF95_NSS
#define SX126X_DIO1 LORA_DIO1
#define SX126X_BUSY LORA_DIO2
#define SX126X_RESET LORA_RESET
#define SX126X_E22
#endif
#include <Adafruit_TinyUSB.h>

View File

@@ -1,4 +1,4 @@
[VERSION] [VERSION]
major = 1 major = 1
minor = 3 minor = 3
build = 43 build = 48