Compare commits

...

102 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
Thomas Göttgens
f6119639bb Add support for SX1281 on 2.4 GHz 2022-10-16 19:07:58 +02:00
57 changed files with 1134 additions and 486 deletions

View File

@@ -57,12 +57,12 @@ jobs:
sudo apt-get install -y cppcheck
- name: Setup Python
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.x
- name: Cache python libs
uses: actions/cache@v1
uses: actions/cache@v3
id: cache-pip # needed in if test
with:
path: ~/.cache/pip
@@ -112,12 +112,12 @@ jobs:
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Setup Python
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.x
- name: Cache python libs
uses: actions/cache@v1
uses: actions/cache@v3
id: cache-pip # needed in if test
with:
path: ~/.cache/pip
@@ -157,11 +157,11 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }}
- 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
- name: Store binaries as an artifact
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: firmware-${{ matrix.board }}-${{ steps.version.outputs.version }}.zip
path: |
@@ -190,12 +190,12 @@ jobs:
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Setup Python
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.x
- name: Cache python libs
uses: actions/cache@v1
uses: actions/cache@v3
id: cache-pip # needed in if test
with:
path: ~/.cache/pip
@@ -214,11 +214,11 @@ jobs:
run: bin/build-nrf52.sh ${{ matrix.board }}
- 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
- name: Store binaries as an artifact
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: firmware-${{ matrix.board }}-${{ steps.version.outputs.version }}.zip
path: |
@@ -245,12 +245,12 @@ jobs:
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Setup Python
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.x
- name: Cache python libs
uses: actions/cache@v1
uses: actions/cache@v3
id: cache-pip # needed in if test
with:
path: ~/.cache/pip
@@ -269,11 +269,11 @@ jobs:
run: ./bin/build-rpi2040.sh ${{ matrix.board }}
- 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
- name: Store binaries as an artifact
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: firmware-${{ matrix.board }}-${{ steps.version.outputs.version }}.zip
path: |
@@ -292,12 +292,12 @@ jobs:
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Setup Python
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.x
- name: Cache python libs
uses: actions/cache@v1
uses: actions/cache@v3
id: cache-pip # needed in if test
with:
path: ~/.cache/pip
@@ -327,11 +327,11 @@ jobs:
run: bin/build-native.sh
- 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
- name: Store binaries as an artifact
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: firmware-native-${{ steps.version.outputs.version }}.zip
path: |
@@ -360,19 +360,19 @@ jobs:
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- uses: actions/download-artifact@v2
- uses: actions/download-artifact@v3
with:
path: ./
- 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
- 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
- name: Repackage in single firmware zip
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: firmware-${{ steps.version.outputs.version }}
path: |
@@ -384,7 +384,7 @@ jobs:
./device-*.bat
retention-days: 90
- uses: actions/download-artifact@v2
- uses: actions/download-artifact@v3
with:
name: firmware-${{ steps.version.outputs.version }}
path: ./output
@@ -402,7 +402,7 @@ jobs:
run: zip -j -r ./firmware-${{ steps.version.outputs.version }}.zip ./output
- name: Repackage in single elfs zip
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: debug-elfs-${{ steps.version.outputs.version }}.zip
path: ./*.elf
@@ -426,18 +426,18 @@ jobs:
needs: [gather-artifacts, after-checks]
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Setup Python
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.x
- 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
- uses: actions/download-artifact@v2
- uses: actions/download-artifact@v3
with:
name: firmware-${{ steps.version.outputs.version }}
path: ./output
@@ -450,7 +450,7 @@ jobs:
- name: Zip firmware
run: zip -j -r ./firmware-${{ steps.version.outputs.version }}.zip ./output
- uses: actions/download-artifact@v2
- uses: actions/download-artifact@v3
with:
name: debug-elfs-${{ steps.version.outputs.version }}.zip
path: ./elfs
@@ -468,7 +468,7 @@ jobs:
with:
draft: 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 }}
body: |
Autogenerated by github action, developer should edit as required before publishing...

View File

@@ -3,7 +3,7 @@
extends = arduino_base
platform = platformio/espressif32@^5.2.0
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
debug_init_break = tbreak setup
monitor_filters = esp32_exception_decoder
@@ -33,8 +33,7 @@ lib_deps =
${environmental_base.lib_deps}
https://github.com/meshtastic/esp32_https_server.git#657509856ce97e9dddeffb89a559f544faefd5cd
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 =
segger_rtt

View File

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

View File

@@ -8,7 +8,7 @@ build_flags =
${arduino_base.build_flags} -Wno-unused-variable
-Isrc/platform/nrf52
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 =
BluetoothOTA

View File

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

View File

@@ -10,7 +10,7 @@ build_flags =
-D__PLAT_RP2040__
# -D _POSIX_THREADS
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 =
BluetoothOTA
lib_deps =

View File

@@ -10,7 +10,7 @@ build_flags =
# Arduino/PlatformIO framework-arduinoststm32 package does not presently have SUBGHZSPI support
# -DPIN_SPI_MOSI=PINSUBGHZSPIMOSI -DPIN_SPI_MISO=PINSUBGHZSPIMISO -DPIN_SPI_SCK=PINSUBGHZSPISCK
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 =
${env.lib_deps}
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
check_tool = cppcheck
check_skip_packages = yes
check_flags =
--common-flag
cppcheck: --enable=--inline-suppr
; Common settings for conventional (non Portduino) Arduino targets
[arduino_base]
@@ -65,7 +68,7 @@ lib_deps =
${env.lib_deps}
; Portduino is using meshtastic fork for now
jgromes/RadioLib@5.4.1
https://github.com/caveman99/SparkFun_ATECCX08a_Arduino_Library.git#008e7f9d40bad66b2f7a0074aaac05b7c424339d
https://github.com/meshtastic/SparkFun_ATECCX08a_Arduino_Library.git#52b5282639d08a8cbd4b748363089eed6102dc76
build_flags = ${env.build_flags} -Os
-DRADIOLIB_SPI_PARANOID=0
@@ -76,6 +79,7 @@ build_src_filter = ${env.build_src_filter} -<platform/portduino/>
[networking_base]
lib_deps =
knolleary/PubSubClient@^2.8
arduino-libraries/NTPClient@^3.1.0
meshtastic/json11@^1.0.2
; Common libs for environmental measurements in telemetry module

View File

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

View File

@@ -44,10 +44,15 @@ size_t RedirectablePrint::vprintf(const char *format, va_list arg)
static char printBuf[160];
va_copy(copy, arg);
int len = vsnprintf(printBuf, sizeof(printBuf), format, copy);
size_t len = vsnprintf(printBuf, sizeof(printBuf), format, 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);
return len;
@@ -103,4 +108,4 @@ size_t RedirectablePrint::logDebug(const char *format, ...)
}
return r;
}
}

View File

@@ -1,5 +1,6 @@
#include "buzz.h"
#include "configuration.h"
#include "NodeDB.h"
#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
void playTones(const ToneDuration *tone_durations, int size) {
for (int i = 0; i < size; i++) {
const auto &tone_duration = tone_durations[i];
if (config.network.eth_enabled != true) {
for (int i = 0; i < size; i++) {
const auto &tone_duration = tone_durations[i];
#ifdef M5STACK
Tone.tone(tone_duration.frequency_khz);
delay(tone_duration.duration_ms);
Tone.mute();
Tone.tone(tone_duration.frequency_khz);
delay(tone_duration.duration_ms);
Tone.mute();
#else
tone(PIN_BUZZER, tone_duration.frequency_khz, tone_duration.duration_ms);
tone(PIN_BUZZER, tone_duration.frequency_khz, tone_duration.duration_ms);
#endif
// to distinguish the notes, set a minimum time between them.
delay(1.3 * tone_duration.duration_ms);
// to distinguish the notes, set a minimum time between them.
delay(1.3 * tone_duration.duration_ms);
}
}
}

View File

@@ -142,6 +142,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef HAS_WIFI
#define HAS_WIFI 0
#endif
#ifndef HAS_ETHERNET
#define ETHERNET 0
#endif
#ifndef HAS_SCREEN
#define HAS_SCREEN 0
#endif

View File

@@ -84,10 +84,6 @@ static char ourId[5];
// GeoCoord object for the screen
GeoCoord geoCoord;
// OEM Config File
static const char *oemConfigFile = "/oem/oem.proto";
OEMStore oemStore;
#ifdef SHOW_REDRAWS
static bool heartbeat = false;
#endif
@@ -928,9 +924,6 @@ void Screen::setup()
dispdev.setDetected(screen_model);
#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.
ui.init();
@@ -1397,7 +1390,6 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
{
#if HAS_WIFI
const char *wifiName = config.network.wifi_ssid;
const char *wifiPsw = config.network.wifi_psk;
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
display->setTextAlignment(TEXT_ALIGN_LEFT);
if (isSoftAPForced()) {
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) {
if (WiFi.status() != WL_CONNECTED) {
display->drawString(x, y, String("WiFi: Not Connected"));
} else {
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;
*/
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 (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.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()));
}
if (WiFi.status() == WL_CONNECTED) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "IP: " + String(WiFi.localIP().toString().c_str()));
} else if (WiFi.status() == WL_NO_SSID_AVAIL) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "SSID Not Found");
} else if (WiFi.status() == WL_CONNECTION_LOST) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Connection Lost");
} else if (WiFi.status() == WL_CONNECT_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) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Idle ... Reconnecting");
} else {
@@ -1516,24 +1493,8 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
}
}
if (isSoftAPForced()) {
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");
}
display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "SSID: " + String(wifiName));
} 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 a heartbeat pixel that blinks every time the frame is redrawn */

View File

@@ -30,6 +30,7 @@
// #include <driver/rtc_io.h>
#include "mesh/http/WiFiAPClient.h"
#include "mesh/eth/ethClient.h"
#ifdef ARCH_ESP32
#include "mesh/http/WebServer.h"
@@ -41,10 +42,16 @@
#include "mqtt/MQTT.h"
#endif
#if HAS_ETHERNET
#include "mesh/eth/ethServerAPI.h"
#include "mqtt/MQTT.h"
#endif
#include "LLCC68Interface.h"
#include "RF95Interface.h"
#include "SX1262Interface.h"
#include "SX1268Interface.h"
#include "SX1281Interface.h"
#if !HAS_RADIO && defined(ARCH_PORTDUINO)
#include "platform/portduino/SimRadio.h"
#endif
@@ -80,6 +87,8 @@ uint8_t kb_model;
// The I2C address of the RTC Module (if found)
uint8_t rtc_found;
bool rIf_wide_lora = false;
// Keystore Chips
uint8_t keystore_found;
#ifndef ARCH_PORTDUINO
@@ -188,8 +197,6 @@ void setup()
digitalWrite(RESET_OLED, 1);
#endif
bool forceSoftAP = 0;
#ifdef BUTTON_PIN
#ifdef ARCH_ESP32
@@ -202,12 +209,6 @@ void setup()
delay(10);
#endif
// BUTTON_PIN is pulled high by a 12k resistor.
if (!digitalRead(BUTTON_PIN)) {
forceSoftAP = 1;
DEBUG_MSG("Setting forceSoftAP = 1\n");
}
#endif
#endif
@@ -239,6 +240,12 @@ void setup()
delay(1);
#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()
scanI2Cdevice();
#ifdef RAK4630
@@ -269,11 +276,12 @@ void setup()
#ifdef ARCH_NRF52
nrf52Setup();
#endif
playStartMelody();
// 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
nodeDB.init();
playStartMelody();
// Currently only the tbeam has a PMU
power = new Power();
power->setStatusHandler(powerStatus);
@@ -364,6 +372,20 @@ void setup()
}
#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 (!rIf) {
rIf = new SX1262Interface(SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY, SPI);
@@ -416,12 +438,17 @@ void setup()
}
#endif
#if HAS_WIFI
#if HAS_WIFI || HAS_ETHERNET
mqttInit();
#endif
#ifndef ARCH_PORTDUINO
// Initialize Wifi
initWifi(forceSoftAP);
initWifi();
// Initialize Ethernet
initEthernet();
#endif
#ifdef ARCH_ESP32
// Start web server thread.

View File

@@ -17,6 +17,7 @@ extern uint8_t kb_model;
extern uint8_t rtc_found;
extern uint8_t keystore_found;
extern bool rIf_wide_lora;
extern bool eink_found;
extern bool pmu_found;
extern bool isCharging;

View File

@@ -62,13 +62,6 @@ Channel &Channels::fixupChannel(ChannelIndex chIndex)
// Convert the old string "Default" to our new short representation
if (strcmp(channelSettings.name, "Default") == 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);
@@ -86,7 +79,7 @@ void Channels::initDefaultChannel(ChannelIndex chIndex)
Config_LoRaConfig &loraConfig = config.lora;
loraConfig.modem_preset = Config_LoRaConfig_ModemPreset_LONG_FAST; // Default to Long Range & Fast
loraConfig.use_preset = true;
loraConfig.tx_power = 0; // default
uint8_t defaultpskIndex = 1;
channelSettings.psk.bytes[0] = defaultpskIndex;
@@ -124,7 +117,22 @@ CryptoKey Channels::getKey(ChannelIndex chIndex)
DEBUG_MSG("Expanding short PSK #%d\n", pskIndex);
if (pskIndex == 0)
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));
k.length = sizeof(defaultpsk);
// Bump up the last byte of PSK as needed

View File

@@ -1,7 +1,13 @@
#include "SX126xInterface.h"
#include "SX126xInterface.cpp"
#include "SX128xInterface.h"
#include "SX128xInterface.cpp"
// We need this declaration for proper linking in derived classes
template class SX126xInterface<SX1262>;
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
bool audioPermitted;
bool freqSwitching;
bool wideLora;
const char *name; // EU433 etc
};

View File

@@ -38,6 +38,7 @@ MyNodeInfo &myNodeInfo = devicestate.my_node;
LocalConfig config;
LocalModuleConfig moduleConfig;
ChannelFile channelFile;
OEMStore oemStore;
/** 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.
@@ -129,6 +130,8 @@ bool NodeDB::factoryReset()
// second, install default state (this will deal with the duplicate mac address issue)
installDefaultDeviceState();
installDefaultConfig();
installDefaultModuleConfig();
installDefaultChannels();
// third, write everything to disk
saveToDisk();
#ifdef ARCH_ESP32
@@ -354,6 +357,8 @@ static const char *prefFileName = "/prefs/db.proto";
static const char *configFileName = "/prefs/config.proto";
static const char *moduleConfigFileName = "/prefs/module.proto";
static const char *channelFileName = "/prefs/channels.proto";
static const char *oemConfigFile = "/oem/oem.proto";
/** Load a protobuf from a file, return true for success */
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);
}
}
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 */

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_CHANNELS 8
#define DEVICESTATE_CUR_VER 19
#define DEVICESTATE_CUR_VER 20
#define DEVICESTATE_MIN_VER DEVICESTATE_CUR_VER
extern DeviceState devicestate;
@@ -26,6 +26,7 @@ extern ChannelFile channelFile;
extern MyNodeInfo &myNodeInfo;
extern LocalConfig config;
extern LocalModuleConfig moduleConfig;
extern OEMStore oemStore;
extern User &owner;
/// 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 "assert.h"
#include "configuration.h"
#include "main.h"
#include "sleep.h"
#include <assert.h>
#include <pb_decode.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, \
frequency_switching, #name \
frequency_switching, wide_lora, #name \
}
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://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
*/
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/
@@ -43,23 +44,23 @@ const RegionInfo regions[] = {
(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
*/
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
*/
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
*/
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://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
@@ -67,38 +68,44 @@ const RegionInfo regions[] = {
Note:
- 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
*/
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://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
*/
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.
*/
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
// No Sync Words in LORA mode
Config_LoRaConfig &loraConfig = config.lora;
if (loraConfig.spread_factor == 0) {
if (loraConfig.use_preset) {
switch (loraConfig.modem_preset) {
case Config_LoRaConfig_ModemPreset_SHORT_FAST:
bw = 250;
bw = (myRegion->wideLora && rIf_wide_lora) ? 800 : 250;
cr = 8;
sf = 7;
break;
case Config_LoRaConfig_ModemPreset_SHORT_SLOW:
bw = 250;
bw = (myRegion->wideLora && rIf_wide_lora) ? 800 : 250;
cr = 8;
sf = 8;
break;
case Config_LoRaConfig_ModemPreset_MEDIUM_FAST:
bw = 250;
bw = (myRegion->wideLora && rIf_wide_lora) ? 800 : 250;
cr = 8;
sf = 9;
break;
case Config_LoRaConfig_ModemPreset_MEDIUM_SLOW:
bw = 250;
bw = (myRegion->wideLora && rIf_wide_lora) ? 800 : 250;
cr = 8;
sf = 10;
break;
case Config_LoRaConfig_ModemPreset_LONG_FAST:
bw = 250;
bw = (myRegion->wideLora && rIf_wide_lora) ? 800 : 250;
cr = 8;
sf = 11;
break;
case Config_LoRaConfig_ModemPreset_LONG_SLOW:
bw = 125;
bw = (myRegion->wideLora && rIf_wide_lora) ? 400 : 125;
cr = 8;
sf = 12;
break;
case Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW:
bw = 31.25;
bw = (myRegion->wideLora && rIf_wide_lora) ? 200 : 31.25;
cr = 8;
sf = 12;
break;
@@ -415,7 +423,7 @@ void RadioInterface::applyModemConfig()
power = 17; // Default to default power if we don't have a valid power
// 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
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);
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
DEBUG_MSG("Resending implicit ack for a repeated floodmsg\n");
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
/* Maximum encoded size of messages (where known) */
#define ChannelSet_size 581
#define ChannelSet_size 582
#ifdef __cplusplus
} /* 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_IpV4Config, Config_NetworkConfig_IpV4Config, 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;
typedef enum _Config_NetworkConfig_EthMode {
Config_NetworkConfig_EthMode_DHCP = 0,
Config_NetworkConfig_EthMode_STATIC = 1
} Config_NetworkConfig_EthMode;
typedef enum _Config_DisplayConfig_GpsCoordinateFormat {
Config_DisplayConfig_GpsCoordinateFormat_DEC = 0,
Config_DisplayConfig_GpsCoordinateFormat_DMS = 1,
@@ -64,7 +69,8 @@ typedef enum _Config_LoRaConfig_RegionCode {
Config_LoRaConfig_RegionCode_RU = 9,
Config_LoRaConfig_RegionCode_IN = 10,
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;
typedef enum _Config_LoRaConfig_ModemPreset {
@@ -116,18 +122,17 @@ typedef struct _Config_LoRaConfig {
uint32_t hop_limit;
bool tx_enabled;
int8_t tx_power;
uint8_t channel_num;
uint16_t channel_num;
pb_size_t ignore_incoming_count;
uint32_t ignore_incoming[3];
} Config_LoRaConfig;
typedef struct _Config_NetworkConfig {
bool wifi_enabled;
Config_NetworkConfig_WiFiMode wifi_mode;
char wifi_ssid[33];
char wifi_psk[64];
char ntp_server[33];
} Config_NetworkConfig;
typedef struct _Config_NetworkConfig_IpV4Config {
uint32_t ip;
uint32_t gateway;
uint32_t subnet;
uint32_t dns;
} Config_NetworkConfig_IpV4Config;
typedef struct _Config_PositionConfig {
uint32_t position_broadcast_secs;
@@ -150,6 +155,17 @@ typedef struct _Config_PowerConfig {
uint32_t min_wake_secs;
} 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 {
pb_size_t which_payload_variant;
union {
@@ -177,6 +193,10 @@ typedef struct _Config {
#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_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_MAX Config_DisplayConfig_GpsCoordinateFormat_OSGR
#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_LoRaConfig_RegionCode_MIN Config_LoRaConfig_RegionCode_UNSET
#define _Config_LoRaConfig_RegionCode_MAX Config_LoRaConfig_RegionCode_TH
#define _Config_LoRaConfig_RegionCode_ARRAYSIZE ((Config_LoRaConfig_RegionCode)(Config_LoRaConfig_RegionCode_TH+1))
#define _Config_LoRaConfig_RegionCode_MAX Config_LoRaConfig_RegionCode_LORA_24
#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_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_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_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_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}
@@ -215,7 +236,8 @@ extern "C" {
#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_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_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}
@@ -245,11 +267,10 @@ extern "C" {
#define Config_LoRaConfig_tx_power_tag 10
#define Config_LoRaConfig_channel_num_tag 11
#define Config_LoRaConfig_ignore_incoming_tag 103
#define Config_NetworkConfig_wifi_enabled_tag 1
#define Config_NetworkConfig_wifi_mode_tag 2
#define Config_NetworkConfig_wifi_ssid_tag 3
#define Config_NetworkConfig_wifi_psk_tag 4
#define Config_NetworkConfig_ntp_server_tag 5
#define Config_NetworkConfig_IpV4Config_ip_tag 1
#define Config_NetworkConfig_IpV4Config_gateway_tag 2
#define Config_NetworkConfig_IpV4Config_subnet_tag 3
#define Config_NetworkConfig_IpV4Config_dns_tag 4
#define Config_PositionConfig_position_broadcast_secs_tag 1
#define Config_PositionConfig_position_broadcast_smart_enabled_tag 2
#define Config_PositionConfig_fixed_position_tag 3
@@ -265,6 +286,13 @@ extern "C" {
#define Config_PowerConfig_sds_secs_tag 6
#define Config_PowerConfig_ls_secs_tag 7
#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_position_tag 2
#define Config_power_tag 3
@@ -324,12 +352,23 @@ X(a, STATIC, SINGULAR, UINT32, min_wake_secs, 8)
#define Config_NetworkConfig_FIELDLIST(X, a) \
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_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_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) \
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_PowerConfig_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_LoRaConfig_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_PowerConfig_fields &Config_PowerConfig_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_LoRaConfig_fields &Config_LoRaConfig_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_DeviceConfig_size 6
#define Config_DisplayConfig_size 20
#define Config_LoRaConfig_size 67
#define Config_NetworkConfig_size 137
#define Config_LoRaConfig_size 68
#define Config_NetworkConfig_IpV4Config_size 20
#define Config_NetworkConfig_size 161
#define Config_PositionConfig_size 30
#define Config_PowerConfig_size 43
#define Config_size 140
#define Config_size 164
#ifdef __cplusplus
} /* extern "C" */

View File

@@ -69,6 +69,7 @@ typedef struct _DeviceState {
} DeviceState;
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,
show a secondary bootup screen with cuatom logo and text for 2.5 seconds. */
typedef struct _OEMStore {
@@ -82,6 +83,8 @@ typedef struct _OEMStore {
ScreenFonts oem_font;
/* Use this font for the OEM text. */
char oem_text[40];
/* The default device encryption key, 16 or 32 byte */
OEMStore_oem_aes_key_t oem_aes_key;
} OEMStore;
@@ -98,10 +101,10 @@ extern "C" {
/* 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 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 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) */
#define ChannelFile_channels_tag 1
@@ -119,6 +122,7 @@ extern "C" {
#define OEMStore_oem_icon_bits_tag 3
#define OEMStore_oem_font_tag 4
#define OEMStore_oem_text_tag 5
#define OEMStore_oem_aes_key_tag 6
/* Struct field encoding specification for nanopb */
#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, BYTES, oem_icon_bits, 3) \
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_DEFAULT NULL
@@ -166,7 +171,7 @@ extern const pb_msgdesc_t OEMStore_msg;
/* Maximum encoded size of messages (where known) */
#define ChannelFile_size 638
#define DeviceState_size 21800
#define OEMStore_size 2106
#define OEMStore_size 2140
#ifdef __cplusplus
} /* extern "C" */

View File

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

View File

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

View File

@@ -243,8 +243,11 @@ typedef enum _LogRecord_Level {
/* Struct definitions */
typedef PB_BYTES_ARRAY_T(237) Compressed_data_t;
/* Compressed message payload */
typedef struct _Compressed {
/* PortNum to determine the how to handle the compressed payload. */
PortNum portnum;
/* Compressed data. */
Compressed_data_t data;
} Compressed;
@@ -352,7 +355,7 @@ typedef struct _MyNodeInfo {
/* a gps 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 */
int32_t latitude_i;
/* TODO: REPLACE */
@@ -425,14 +428,6 @@ typedef struct _RouteDiscovery {
uint32_t route[8];
} 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
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)
@@ -665,9 +660,6 @@ typedef struct _ToRadio {
union {
/* Send this packet on the mesh */
MeshPacket packet;
/* Information about the peer, sent after the phone sneds want_config_id.
Old clients do not send this, which is fine. */
ToRadio_PeerInfo peer_info;
/* Phone wants radio to send full node db to the phone, This is
typically the first packet sent to the radio when the phone gets a
bluetooth connection. The radio will respond by sending back a
@@ -740,7 +732,6 @@ extern "C" {
#define LogRecord_init_default {"", 0, "", _LogRecord_Level_MIN}
#define FromRadio_init_default {0, 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 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}
@@ -754,7 +745,6 @@ extern "C" {
#define LogRecord_init_zero {"", 0, "", _LogRecord_Level_MIN}
#define FromRadio_init_zero {0, 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}}}
/* Field tags (for use in manual encoding/decoding) */
@@ -811,8 +801,6 @@ extern "C" {
#define Position_next_update_tag 21
#define Position_seq_number_tag 22
#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_long_name_tag 2
#define User_short_name_tag 3
@@ -859,7 +847,6 @@ extern "C" {
#define FromRadio_moduleConfig_tag 9
#define FromRadio_channel_tag 10
#define ToRadio_packet_tag 1
#define ToRadio_peer_info_tag 2
#define ToRadio_want_config_id_tag 3
#define ToRadio_disconnect_tag 4
@@ -1019,19 +1006,11 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,channel,channel), 10)
#define ToRadio_FIELDLIST(X, a) \
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, BOOL, (payload_variant,disconnect,disconnect), 4)
#define ToRadio_CALLBACK NULL
#define ToRadio_DEFAULT NULL
#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) \
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 FromRadio_msg;
extern const pb_msgdesc_t ToRadio_msg;
extern const pb_msgdesc_t ToRadio_PeerInfo_msg;
extern const pb_msgdesc_t Compressed_msg;
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
@@ -1067,7 +1045,6 @@ extern const pb_msgdesc_t Compressed_msg;
#define LogRecord_fields &LogRecord_msg
#define FromRadio_fields &FromRadio_msg
#define ToRadio_fields &ToRadio_msg
#define ToRadio_PeerInfo_fields &ToRadio_PeerInfo_msg
#define Compressed_fields &Compressed_msg
/* Maximum encoded size of messages (where known) */
@@ -1081,7 +1058,6 @@ extern const pb_msgdesc_t Compressed_msg;
#define Position_size 137
#define RouteDiscovery_size 40
#define Routing_size 42
#define ToRadio_PeerInfo_size 8
#define ToRadio_size 324
#define User_size 77
#define Waypoint_size 156

View File

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

View File

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

View File

@@ -8,7 +8,6 @@
#include "mesh/wifi/WiFiServerAPI.h"
#include "mqtt/MQTT.h"
#include "target_specific.h"
#include <DNSServer.h>
#include <ESPmDNS.h>
#include <esp_wifi.h>
#include <WiFi.h>
@@ -22,9 +21,6 @@ using namespace concurrency;
static void WiFiEvent(WiFiEvent_t event);
// DNS Server for the Captive Portal
DNSServer dnsServer;
// NTP
WiFiUDP ntpUDP;
@@ -37,46 +33,29 @@ uint8_t wifiDisconnectReason = 0;
// Stores our hostname
char ourHost[16];
bool forcedSoftAP = 0;
bool APStartupComplete = 0;
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()
{
const char *wifiName = config.network.wifi_ssid;
const char *wifiPsw = config.network.wifi_psk;
if (config.network.wifi_enabled && needReconnect && !WiFi.isConnected()) {
// if (radioConfig.has_preferences && needReconnect && !WiFi.isConnected()) {
if (!*wifiPsw) // Treat empty password as no password
wifiPsw = NULL;
if (*wifiName) {
needReconnect = false;
// Make sure we clear old connection credentials
WiFi.disconnect(false, true);
DEBUG_MSG("... Reconnecting to WiFi access point\n");
WiFi.mode(WIFI_MODE_STA);
WiFi.begin(wifiName, wifiPsw);
// Starting timeClient;
}
}
@@ -103,16 +82,10 @@ static int32_t reconnectWiFi()
static Periodic *wifiReconnect;
bool isSoftAPForced()
{
return forcedSoftAP;
}
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;
} else {
return false;
@@ -176,100 +149,48 @@ static void onNetworkConnected()
}
// 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 *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();
if (!*wifiPsw) // Treat empty password as no password
wifiPsw = NULL;
if (*wifiName || forceSoftAP) {
if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT || config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN || forceSoftAP) {
if (*wifiName) {
uint8_t dmac[6];
getMacAddr(dmac);
sprintf(ourHost, "Meshtastic-%02x%02x", dmac[4], dmac[5]);
IPAddress apIP(192, 168, 42, 1);
WiFi.onEvent(WiFiEvent);
WiFi.mode(WIFI_AP);
WiFi.mode(WIFI_MODE_STA);
WiFi.setHostname(ourHost);
WiFi.onEvent(WiFiEvent);
if (forcedSoftAP) {
const char *softAPssid = "meshtasticAdmin";
const char *softAPpasswd = "12345678";
int ok = WiFi.softAP(softAPssid, softAPpasswd);
DEBUG_MSG("Starting (Forced) WIFI AP: ssid=%s, ok=%d\n", softAPssid, ok);
// This is needed to improve performance.
esp_wifi_set_ps(WIFI_PS_NONE); // Disable radio power saving
} 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
int ok = WiFi.softAP(wifiName, wifiPsw, 1, 1, 4);
DEBUG_MSG("Starting hidden WIFI AP: ssid=%s, ok=%d\n", wifiName, ok);
} else {
int ok = WiFi.softAP(wifiName, wifiPsw);
DEBUG_MSG("Starting WIFI AP: ssid=%s, ok=%d\n", wifiName, ok);
}
int ok = WiFi.softAP(wifiName, wifiPsw);
DEBUG_MSG("Starting WIFI AP: ssid=%s, ok=%d\n", wifiName, ok);
}
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);
WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
DEBUG_MSG("MY IP AP ADDRESS: %s\n", WiFi.softAPIP().toString().c_str());
// 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);
}
DEBUG_MSG("JOINING WIFI soon: ssid=%s\n", wifiName);
wifiReconnect = new Periodic("WifiConnect", reconnectWiFi);
}
return true;
} 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()
{
return wifiDisconnectReason;

View File

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

View File

@@ -101,9 +101,7 @@ bool AdminModule::handleReceivedProtobuf(const MeshPacket &mp, AdminMessage *r)
* Other
*/
case AdminMessage_reboot_seconds_tag: {
int32_t s = r->reboot_seconds;
DEBUG_MSG("Rebooting in %d seconds\n", s);
rebootAtMsec = (s < 0) ? 0 : (millis() + s * 1000);
reboot(r->reboot_seconds);
break;
}
case AdminMessage_reboot_ota_seconds_tag: {
@@ -135,13 +133,13 @@ bool AdminModule::handleReceivedProtobuf(const MeshPacket &mp, AdminMessage *r)
case AdminMessage_factory_reset_tag: {
DEBUG_MSG("Initiating factory reset\n");
nodeDB.factoryReset();
rebootAtMsec = millis() + (5 * 1000);
reboot(5);
break;
}
case AdminMessage_nodedb_reset_tag: {
DEBUG_MSG("Initiating node-db reset\n");
nodeDB.resetNodes();
rebootAtMsec = millis() + (5 * 1000);
reboot(5);
break;
}
#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
service.reloadOwner();
DEBUG_MSG("Rebooting due to owner changes\n");
screen->startRebootScreen();
rebootAtMsec = millis() + (5 * 1000);
reboot(5);
}
}
void AdminModule::handleSetConfig(const Config &c)
{
bool requiresReboot = false;
bool isRouter = (config.device.role == Config_DeviceConfig_Role_ROUTER);
bool isRegionUnset = (config.lora.region == Config_LoRaConfig_RegionCode_UNSET);
@@ -218,12 +214,13 @@ void AdminModule::handleSetConfig(const Config &c)
nodeDB.initConfigIntervals();
nodeDB.initModuleConfigIntervals();
}
requiresReboot = true;
break;
case Config_position_tag:
DEBUG_MSG("Setting config: Position\n");
config.has_position = true;
config.position = c.payload_variant.position;
// Save nodedb as well in case we got a fixed position packet
nodeDB.saveToDisk(SEGMENT_DEVICESTATE);
break;
case Config_power_tag:
DEBUG_MSG("Setting config: Power\n");
@@ -234,7 +231,6 @@ void AdminModule::handleSetConfig(const Config &c)
DEBUG_MSG("Setting config: WiFi\n");
config.has_network = true;
config.network = c.payload_variant.network;
requiresReboot = true;
break;
case Config_display_tag:
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.tx_enabled = true;
}
requiresReboot = true;
break;
case Config_bluetooth_tag:
DEBUG_MSG("Setting config: Bluetooth\n");
config.has_bluetooth = true;
config.bluetooth = c.payload_variant.bluetooth;
requiresReboot = true;
break;
}
service.reloadConfig(SEGMENT_CONFIG);
// Reboot 5 seconds after a config that requires rebooting is set
if (requiresReboot) {
DEBUG_MSG("Rebooting due to config changes\n");
screen->startRebootScreen();
rebootAtMsec = millis() + (5 * 1000);
}
reboot(5);
}
void AdminModule::handleSetModuleConfig(const ModuleConfig &c)
@@ -307,8 +296,9 @@ void AdminModule::handleSetModuleConfig(const ModuleConfig &c)
moduleConfig.canned_message = c.payload_variant.canned_message;
break;
}
service.reloadConfig(SEGMENT_MODULECONFIG);
reboot(5);
}
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)
{
// restrict to the admin channel for rx

View File

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

View File

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

View File

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

View File

@@ -5,7 +5,12 @@
#include "concurrency/OSThread.h"
#include "mesh/Channels.h"
#include <PubSubClient.h>
#if HAS_WIFI
#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
@@ -16,7 +21,12 @@ class MQTT : private concurrency::OSThread
// supposedly the current version is busted:
// http://www.iotsharing.com/2017/08/how-to-use-esp32-mqtts-with-mqtts-mosquitto-broker-tls-ssl.html
// WiFiClientSecure wifiClient;
#if HAS_WIFI
WiFiClient mqttClient;
#endif
#if HAS_ETHERNET
EthernetClient mqttClient;
#endif
PubSubClient pubSub;
// instead we supress sleep from our runOnce() callback
@@ -38,6 +48,8 @@ class MQTT : private concurrency::OSThread
/** Attempt to connect to server if necessary
*/
void reconnect();
bool connected();
protected:
virtual int32_t runOnce() override;
@@ -58,7 +70,7 @@ class MQTT : private concurrency::OSThread
void onPublish(char *topic, byte *payload, unsigned int length);
/// 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
// 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;
static bool passkeyShowing;
static uint32_t doublepressed;
class BluetoothPhoneAPI : public PhoneAPI
{
@@ -71,12 +70,8 @@ class NimbleBluetoothServerCallback : public NimBLEServerCallbacks
{
virtual uint32_t onPassKeyRequest() {
uint32_t passkey = config.bluetooth.fixed_pin;
if (doublepressed > 0 && (doublepressed + (30 * 1000)) > millis()) {
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) {
if (config.bluetooth.mode == Config_BluetoothConfig_PairingMode_RANDOM_PIN) {
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
passkey = random(100000, 999999);
@@ -202,24 +197,3 @@ void clearNVS()
ESP.restart();
#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 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/
#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_DIO1 WB_IO6 // IRQ for SX1262/SX1268
#define LORA_DIO2 WB_IO5 // BUSY for SX1262/SX1268

View File

@@ -3,10 +3,12 @@
extends = nrf52840_base
board = wiscore_rak4631
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 =
${nrf52840_base.lib_deps}
${networking_base.lib_deps}
melopero/Melopero RV3028@^1.1.0
https://github.com/meshtastic/RAK13800-W5100S.git#b680706eb8006cd62c919ac74c8af1950eb82c81
debug_tool = jlink
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
;upload_protocol = jlink

View File

@@ -185,6 +185,9 @@ static const uint8_t SCK = PIN_SPI_SCK;
#define SX126X_RXEN (37)
#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
// 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
@@ -192,7 +195,7 @@ static const uint8_t SCK = PIN_SPI_SCK;
// Therefore must be 1 to keep peripherals powered
// Power is on the controllable 3V3_S rail
// #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 GPS_RX_PIN PIN_SERIAL1_RX
@@ -226,6 +229,12 @@ static const uint8_t SCK = PIN_SPI_SCK;
#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
}
#endif

View File

@@ -185,6 +185,9 @@ static const uint8_t SCK = PIN_SPI_SCK;
#define SX126X_RXEN (37)
#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
// 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
@@ -192,7 +195,7 @@ static const uint8_t SCK = PIN_SPI_SCK;
// Therefore must be 1 to keep peripherals powered
// Power is on the controllable 3V3_S rail
// #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 GPS_RX_PIN PIN_SERIAL1_RX

View File

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