Compare commits

...

279 Commits

Author SHA1 Message Date
Ben Meadors
8146e84200 Merge pull request #1926 from GUVWAF/master
Set preamble length back to 32
2022-11-09 14:29:54 -06:00
GUVWAF
1213ec2d57 Set preamble length back to 32 2022-11-09 21:21:50 +01:00
Ben Meadors
f0279e7f92 Merge pull request #1923 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-11-09 07:33:27 -06:00
Ben Meadors
1a50181ace Merge branch 'master' into create-pull-request/patch 2022-11-09 07:33:02 -06:00
Ben Meadors
d77bc239c1 Changed retention policy 2022-11-09 07:20:53 -06:00
Ben Meadors
cb283f4c57 Build cleanup and update deprecated platformio cmd 2022-11-09 07:14:08 -06:00
thebentern
728fc8cbad [create-pull-request] automated change 2022-11-08 22:51:44 +00:00
Thomas Göttgens
ad05b91f89 Merge pull request #1922 from meshtastic/develop
fix #1916
2022-11-08 23:15:04 +01:00
Thomas Göttgens
671e6cde44 Merge branch 'master' into develop 2022-11-08 22:33:38 +01:00
Thomas Göttgens
7a3ad0afba fix #1916 2022-11-08 22:32:53 +01:00
Ben Meadors
d9f1704e36 Merge pull request #1921 from meshtastic/update-phoneapi
Updated admin module and protobufs
2022-11-08 15:32:20 -06:00
Ben Meadors
32223a818c Updated admin module and protobufs 2022-11-08 15:04:24 -06:00
Thomas Göttgens
31e13d4de3 Merge pull request #1920 from meshtastic/develop
rename wifi_mode to eth_mode
2022-11-08 21:55:06 +01:00
Thomas Göttgens
815bd6321b Merge branch 'master' into develop 2022-11-08 21:54:38 +01:00
Thomas Göttgens
9f9bd40343 rename wifi_mode to eth_mode 2022-11-08 21:53:44 +01:00
Ben Meadors
2331226bb6 Bump version 2022-11-08 07:27:48 -06:00
Ben Meadors
80ff118f0f Merge pull request #1918 from meshtastic/develop
Develop to master
2022-11-08 07:26:14 -06:00
Ben Meadors
d6eeda7136 Merge pull request #1917 from meshtastic/master
Master Rollup
2022-11-08 07:25:40 -06:00
Ben Meadors
fb92e498f0 Merge pull request #1902 from GUVWAF/develop
Change preambleLength to 8 symbols to reduce airtime
2022-11-08 07:25:02 -06:00
Ben Meadors
bf8d8886fd Merge branch 'develop' into master 2022-11-08 07:20:29 -06:00
Ben Meadors
a695726f2a Merge pull request #1912 from meshtastic/docker-compose
Added docker compose multiple nodes example
2022-11-08 07:12:36 -06:00
Ben Meadors
6dc4172110 Merge branch 'master' into docker-compose 2022-11-08 07:12:21 -06:00
Thomas Göttgens
25a9ee8eb6 Merge branch 'master' of github.com:meshtastic/firmware 2022-11-08 13:40:07 +01:00
Ben Meadors
e122232761 Removed defunct line 2022-11-07 13:29:34 -06:00
Ben Meadors
b13eaee6b3 More fun 2022-11-07 13:28:37 -06:00
Ben Meadors
f0f5107a5d Added docker compose 4 nodes example 2022-11-06 19:22:20 -06:00
Ben Meadors
0832cc50a8 Add a docker-compose 2022-11-06 13:19:49 -06:00
Thomas Göttgens
962a3d0c55 Merge pull request #1911 from meshtastic/caveman99-patch-1
Fix assert
2022-11-06 19:06:26 +01:00
Thomas Göttgens
6934e0bce7 Fix assert 2022-11-06 18:36:17 +01:00
Ben Meadors
3492d64177 Alpine 2022-11-06 18:22:52 +01:00
Thomas Göttgens
057109dcac Reduce retention to 30 days. 2022-11-06 18:22:52 +01:00
Ben Meadors
12fa08007d Docker is back 2022-11-06 18:22:52 +01:00
Ben Meadors
3562d34555 Remove flag 2022-11-06 18:22:52 +01:00
Ben Meadors
3ca6f645d4 Portduino build flags 2022-11-06 18:22:52 +01:00
Ben Meadors
6694d31d07 Somehow I still missed one :-| 2022-11-06 18:22:52 +01:00
Ben Meadors
d15edf1955 Update NMEAWPL.h 2022-11-06 18:22:52 +01:00
Ben Meadors
e1ce037550 Update NMEAWPL.cpp 2022-11-06 18:22:52 +01:00
Ben Meadors
f9c376a524 Update NMEAWPL.cpp 2022-11-06 18:22:52 +01:00
Ben Meadors
26a907444c Fix for alpine linux builds 2022-11-06 18:22:52 +01:00
Ben Meadors
5c214bf4d8 Merge pull request #1908 from meshtastic/docker-returns
Docker is back
2022-11-06 09:31:24 -06:00
Ben Meadors
5151a5641e Merge branch 'master' into docker-returns 2022-11-06 09:31:02 -06:00
Ben Meadors
9513209b70 Alpine 2022-11-06 09:30:46 -06:00
Thomas Göttgens
f1416ac9f7 Reduce retention to 30 days. 2022-11-06 14:49:02 +01:00
Thomas Göttgens
631db56a44 Next try, plus change cppcheck defines back. 2022-11-06 14:32:02 +01:00
Thomas Göttgens
7b378d36cc try to make cppcheck happy again 2022-11-06 13:29:01 +01:00
Thomas Göttgens
8ab269e1b3 revert BME680 to default settings, they are working good. Our init was just replicating what's in the lib anyway. 2022-11-06 10:52:54 +01:00
Thomas Göttgens
7652253b8d optimize BME680 usage 2022-11-06 10:37:14 +01:00
Ben Meadors
9805319940 Docker is back 2022-11-05 21:08:29 -05:00
Ben Meadors
e1e607cba3 Remove flag 2022-11-05 19:09:04 -05:00
Ben Meadors
d74bcd3583 Portduino build flags 2022-11-05 18:21:35 -05:00
Ben Meadors
9c0483975c Somehow I still missed one :-| 2022-11-05 15:34:54 -05:00
Ben Meadors
2fb85dc129 Merge pull request #1906 from meshtastic/thebentern-patch-1
Fix for alpine linux builds
2022-11-05 15:30:10 -05:00
Ben Meadors
d641adc0fc Update NMEAWPL.h 2022-11-05 15:20:09 -05:00
Ben Meadors
a7a020f431 Update NMEAWPL.cpp 2022-11-05 15:14:08 -05:00
Ben Meadors
a08ac5a47e Update NMEAWPL.cpp 2022-11-05 15:11:11 -05:00
Ben Meadors
30e5706eaa Fix for alpine linux builds 2022-11-05 15:10:43 -05:00
Thomas Göttgens
16444c190d Ignore Band power limits for licensed HAMs 2022-11-05 20:13:47 +01:00
Thomas Göttgens
3d9633a56c Different Sensor access, should prevent overheating/wrong measurements. 2022-11-05 20:12:41 +01:00
GUVWAF
c0e630522c Merge branch 'meshtastic:develop' into develop 2022-11-05 19:09:36 +01:00
Ben Meadors
9422d31f55 Merge pull request #1905 from meshtastic/trying-again
Trying again
2022-11-05 09:35:51 -05:00
Ben Meadors
087c7c19af Update protos 2022-11-05 09:34:33 -05:00
Ben Meadors
3476b35fca Merge remote-tracking branch 'origin/master' into trying-again 2022-11-05 09:33:39 -05:00
Ben Meadors
950d5defda Master to develop (resolves conflicts) (#1903)
* Rearranging deck chairs, 900M22S working, 30S not

* We do have wire, just not where it's expected

* Put more of the module specific pins in their blocks

* tryfix compile with NO_SCREEN

* Portduino only: don't continue to try rebooting (#1887)

Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>

* Support for TLORA 2.1-1.8

* Don't allow arbitrary channel name for admin (#1886)

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>

* Experimental DIY nrf52840 feather support (#1884)

* Experimental DIY nrf52840 feather support

* Fix target

* sx1262 wiring

* Remove lib

* Don't consider Response as ACK for FloodingRouter (#1885)

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>

* Fix feather diy (#1892)

* Fix variant

* Fix feather diy target

* [modules][external notifications] allow select channel to listen to

* Fix feather diy pin mapping (#1894)

Thanks to @markbirss

* [create-pull-request] automated change

* Override Screen Autodtect

* Maybe fix crash of this board.

* Fixes reset loop with new espressif32 platform on tlora-v2

 Sending a pulse to the OLED_RESET Pin 16 results in a reset loop using recent version of the espressif32 platform.

* Experiment with self hosted action runner

* Fix MQTT on ETH

* revert the tryfix

* Cheating

* Cleanup artifacts older than 1 month

* Update cleanup_artifacts.yml

* Update cleanup_artifacts.yml

* Update cleanup_artifacts.yml

* Delete cleanup_artifacts.yml

* fix: use RF95_IRQ for wakeup source in doLightSleep (#1899)

Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>

* Update protos

* Update protos

Co-authored-by: code8buster <communismisgreat@national.shitposting.agency>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
Co-authored-by: GUVWAF <78759985+GUVWAF@users.noreply.github.com>
Co-authored-by: Mykhailo Lesyk <m@lesyk.org>
Co-authored-by: Mykhailo Lesyk <lesykm@users.noreply.github.com>
Co-authored-by: caveman99 <caveman99@users.noreply.github.com>
Co-authored-by: he-leon <he-leon@users.noreply.github.com>
Co-authored-by: Lars Weber <weber@weber-software.com>
2022-11-05 09:28:41 -05:00
Ben Meadors
c6f060a24f Add develop to CI 2022-11-05 09:21:51 -05:00
Thomas Göttgens
1716c4d6f9 Allow static IP for WLAN
and portentially fix reconnect issues
2022-11-05 15:02:06 +01:00
Ben Meadors
cda7a60734 Update protos 2022-11-05 08:43:44 -05:00
Lars Weber
ed26ab801c fix: use RF95_IRQ for wakeup source in doLightSleep (#1899)
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2022-11-05 08:37:00 -05:00
Thomas Göttgens
8874a6e488 update protos 2022-11-05 14:18:57 +01:00
Thomas Göttgens
657ae44b6f Merge branch 'master' of github.com:meshtastic/firmware 2022-11-05 14:11:19 +01:00
Ben Meadors
01381057c5 Delete cleanup_artifacts.yml 2022-11-05 08:06:28 -05:00
Ben Meadors
3dc6ed5672 Update cleanup_artifacts.yml 2022-11-05 06:57:47 -05:00
Ben Meadors
764b48e04a Update cleanup_artifacts.yml 2022-11-05 06:47:00 -05:00
Ben Meadors
4c931967c7 Update cleanup_artifacts.yml 2022-11-05 06:44:08 -05:00
Ben Meadors
a547a791ba Cleanup artifacts older than 1 month 2022-11-05 06:42:53 -05:00
GUVWAF
176072801b Change preambleLength to 8 symbols to reduce airtime 2022-11-05 09:58:10 +01:00
Thomas Göttgens
b941c51cf7 Merge pull request #1900 from meshtastic/mqtt-eth
Mqtt eth
2022-11-04 23:13:18 +01:00
Thomas Göttgens
8a9fd6846e Merge branch 'master' into mqtt-eth 2022-11-04 22:44:42 +01:00
Ben Meadors
a49355133c Cheating 2022-11-04 14:23:22 -05:00
Thomas Göttgens
09cdc20440 manual merge of changes from Master 2022-11-04 19:56:44 +01:00
Thomas Göttgens
1c0dfe47c8 Merge branch 'master' of github.com:meshtastic/firmware 2022-11-04 19:51:22 +01:00
Thomas Göttgens
66623693eb Merge branch 'master' into mqtt-eth 2022-11-04 19:48:57 +01:00
Thomas Göttgens
7c692444e5 revert the tryfix 2022-11-04 19:48:28 +01:00
Thomas Göttgens
4ccb4393c5 Fix MQTT on ETH 2022-11-04 19:44:45 +01:00
Ben Meadors
b2e540b114 Experiment with self hosted action runner 2022-11-04 13:43:16 -05:00
Thomas Göttgens
a5d1165c54 Merge branch 'master' of github.com:meshtastic/firmware 2022-11-04 19:34:35 +01:00
Thomas Göttgens
aa321e06dd Merge pull request #1898 from he-leon/patch-1
Fixes reset loop with new espressif32 platform on tlora-v2
2022-11-04 19:26:16 +01:00
he-leon
8b84ac8a6c Fixes reset loop with new espressif32 platform on tlora-v2
Sending a pulse to the OLED_RESET Pin 16 results in a reset loop using recent version of the espressif32 platform.
2022-11-04 16:48:49 +01:00
Thomas Göttgens
6c07fbfc12 Merge pull request #1896 from meshtastic/oled-config
Oled config
2022-11-03 23:05:09 +01:00
Thomas Göttgens
04a478a5ad Maybe fix crash of this board. 2022-11-03 22:50:54 +01:00
Thomas Göttgens
acfa186d44 Override Screen Autodtect 2022-11-03 22:44:22 +01:00
Thomas Göttgens
3db504c470 Merge branch 'master' of github.com:meshtastic/firmware 2022-11-03 22:38:05 +01:00
Thomas Göttgens
3e5955be44 Merge pull request #1895 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-11-03 22:36:16 +01:00
caveman99
f1afbf2c0f [create-pull-request] automated change 2022-11-03 21:35:06 +00:00
Thomas Göttgens
20c559382d Merge branch 'master' of github.com:meshtastic/firmware 2022-11-03 22:32:27 +01:00
Thomas Göttgens
a3f1c02347 Merge pull request #1882 from lesykm/ext_notification_channel
[modules][external notifications] allow select channel to listen to
2022-11-03 22:21:43 +01:00
Ben Meadors
f5945d429e Merge branch 'master' into ext_notification_channel 2022-11-03 14:29:15 -05:00
Ben Meadors
a3eced53bb Fix feather diy pin mapping (#1894)
Thanks to @markbirss
2022-11-03 14:28:49 -05:00
Thomas Göttgens
20686cc66a Show boot logo / OEM Logo longer - 5 seconds each now. 2022-11-03 09:46:32 +01:00
Thomas Göttgens
5608fa32f7 Merge branch 'master' of github.com:meshtastic/firmware 2022-11-03 08:29:28 +01:00
Mykhailo Lesyk
a0c5defda6 Merge branch 'master' into ext_notification_channel 2022-11-02 20:34:23 -07:00
Mykhailo Lesyk
25a3a09d5f [modules][external notifications] allow select channel to listen to 2022-11-02 20:31:28 -07:00
Ben Meadors
593301146e Fix feather diy (#1892)
* Fix variant

* Fix feather diy target
2022-11-02 15:57:47 -05:00
GUVWAF
5715ddc361 Don't consider Response as ACK for FloodingRouter (#1885)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2022-11-02 14:32:18 -05:00
Thomas Göttgens
09ddde177c codec2 Audio Support for SX1280 (untested) 2022-11-02 18:23:41 +01:00
Ben Meadors
ef18b173cd Experimental DIY nrf52840 feather support (#1884)
* Experimental DIY nrf52840 feather support

* Fix target

* sx1262 wiring

* Remove lib
2022-11-02 18:19:09 +01:00
GUVWAF
ac4e88e0d2 Don't allow arbitrary channel name for admin (#1886)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2022-11-02 18:19:09 +01:00
Thomas Göttgens
3e82cd7dd4 Support for TLORA 2.1-1.8 2022-11-02 18:19:09 +01:00
GUVWAF
b1f2025558 Portduino only: don't continue to try rebooting (#1887)
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2022-11-02 18:19:09 +01:00
Thomas Göttgens
57ca5fea81 tryfix compile with NO_SCREEN 2022-11-02 18:19:09 +01:00
code8buster
0ce018cf97 Put more of the module specific pins in their blocks 2022-11-02 18:19:09 +01:00
code8buster
15a8710e69 We do have wire, just not where it's expected 2022-11-02 18:19:09 +01:00
code8buster
cae75dcb6d Rearranging deck chairs, 900M22S working, 30S not 2022-11-02 18:19:09 +01:00
Thomas Göttgens
d5e2b70b71 Merge pull request #1888 from meshtastic/TLORA-18
Support for TLORA 2.1-1.8
2022-11-02 18:16:44 +01:00
Thomas Göttgens
05b9fd04c6 switch submodule branch to develop 2022-11-02 15:08:49 +01:00
Thomas Göttgens
4650989774 Merge branch 'master' into TLORA-18 2022-11-02 15:01:40 +01:00
Thomas Göttgens
bcc77efb88 Merge branch 'master' of github.com:meshtastic/firmware 2022-11-02 14:13:04 +01:00
Ben Meadors
39c1637030 Experimental DIY nrf52840 feather support (#1884)
* Experimental DIY nrf52840 feather support

* Fix target

* sx1262 wiring

* Remove lib
2022-11-02 07:48:14 -05:00
Ben Meadors
6d3028f213 Merge branch 'master' into TLORA-18 2022-11-02 07:20:39 -05:00
GUVWAF
b2969b2faf Don't allow arbitrary channel name for admin (#1886)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2022-11-02 07:18:15 -05:00
Thomas Göttgens
d07350e4a4 Merge branch 'master' into TLORA-18 2022-11-02 13:14:51 +01:00
Thomas Göttgens
12df55c3d4 Support for TLORA 2.1-1.8 2022-11-02 13:12:15 +01:00
GUVWAF
85b541bfd9 Portduino only: don't continue to try rebooting (#1887)
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2022-11-02 06:58:14 -05:00
Thomas Göttgens
a9c6d6a80c Merge pull request #1878 from code8buster/master
Making meshtastic-dr-dev E22-900M22S/M30S work alternately
2022-11-02 10:34:08 +01:00
Thomas Göttgens
32ad8aaa4e tryfix compile with NO_SCREEN 2022-11-02 10:17:59 +01:00
code8buster
3d8e6aead2 Put more of the module specific pins in their blocks 2022-10-31 21:54:05 -04:00
code8buster
2747600a3a Merge branch 'meshtastic:master' into master 2022-11-01 01:35:34 +00:00
Thomas Göttgens
b7ef63230b new location of ota firmware 2022-10-31 14:50:31 +01:00
Ben Meadors
b4d6c8f37b Update verbiage 2022-10-31 08:32:21 -05:00
Ben Meadors
6a907348b4 Merge branch 'master' into master 2022-10-31 08:17:37 -05:00
Ben Meadors
18ab8749ff Update protobuf ref 2022-10-31 08:09:22 -05:00
Ben Meadors
a1ed5cdffc 2.0 (To be merged Nov 1) (#1870)
* 2.0

* Catch the right version of the common files
2022-10-31 07:51:44 -05:00
Ben Meadors
760d463bf5 Merge branch 'master' into master 2022-10-31 06:12:16 -05:00
Sacha Weatherstone
5ed2a4e8bb Merge pull request #1879 from meshtastic/update-repo-links
Update links
2022-10-31 20:09:37 +11:00
Sacha Weatherstone
60e95ef3bd Fix typo 2022-10-31 18:54:47 +10:00
Sacha Weatherstone
5b648be2a5 More renaming 2022-10-31 18:47:10 +10:00
Sacha Weatherstone
0149171e1a update repobeats url 2022-10-31 18:21:10 +10:00
Sacha Weatherstone
b24caa1e06 Update links 2022-10-31 17:32:38 +10:00
code8buster
8fa71afb72 We do have wire, just not where it's expected 2022-10-30 22:30:33 -04:00
code8buster
309a3d5396 Rearranging deck chairs, 900M22S working, 30S not 2022-10-30 22:28:25 -04:00
Ben Meadors
afafb3ba32 Fixing a number of T-Beam poweroff display issues (#1876) 2022-10-30 20:40:30 -05:00
Ben Meadors
311835a231 Implement extended device metadata (#1874)
* Implement extended device metadata

* HAS_BLUETOOTH should be global
2022-10-30 10:02:11 -05:00
code8buster
1f9db0a8fe Disaster.radio dev board support update (#1873)
* Bringing changes from 1.2-legacy over to the new structure in 1.3/2.0

* Add meshtastic-dr-dev to CI artifact workflow
2022-10-29 16:37:27 -05:00
Ben Meadors
d6c9327aef Opposite logic for use_preset based channel name (#1871) 2022-10-29 11:40:05 -05:00
Thomas Göttgens
0091863888 Merge pull request #1867 from t413/techo-shutdown-backlight
Powers off eink backlights before shutdown
2022-10-28 11:23:05 +02:00
Ben Meadors
051ce5e09f Merge branch 'master' into techo-shutdown-backlight 2022-10-27 20:17:31 -05:00
timo
6146b773cf Better #define guard for PIN_EINK_EN 2022-10-27 17:59:53 -07:00
Thomas Göttgens
8a4341fec4 use new lora.use_preset bool (#1868) 2022-10-27 19:15:16 -05:00
Tim O'Brien
154b7d256c Powers off eink backlights before shutdown
- t-echo boards in particular need this
- follows the existing defines structure
2022-10-27 11:03:27 -07:00
Thomas Göttgens
548b0d0b53 Merge pull request #1866 from markbirss/master
Enable RAK14000 2.13 inch b/w E-Ink partial update support
2022-10-27 11:36:06 +02:00
Mark Trevor Birss
e59361425f Merge branch 'master' into master 2022-10-27 09:06:38 +02:00
Thomas Göttgens
713e0f4260 Merge pull request #1865 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-10-27 09:06:22 +02:00
Mark Trevor Birss
8a1bf8cd86 RAK14000 2.13" b/w E-Ink partial update support
Changed from GxEPD2_213_B74 (which was not going to give partial update support on this display) to GxEPD2_213_BN - RAK14000 2.13 inch b/w 250x122
2022-10-27 08:59:39 +02:00
Mark Trevor Birss
f474953b51 RAK14000 2.13 inch b/w E-Ink partial update support
Changed from GxEPD2_213_B74 (which was not going to give partial update support on this display) to GxEPD2_213_BN - RAK14000 2.13 inch b/w 250x122
2022-10-27 08:56:04 +02:00
thebentern
d5ded53f05 [create-pull-request] automated change 2022-10-26 22:21:43 +00:00
Ben Meadors
82bcd391cd Fix those refs 2022-10-26 16:50:58 -05:00
Thomas Göttgens
058689709f Merge pull request #1864 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-10-26 23:33:49 +02:00
thebentern
23c9fa0b56 [create-pull-request] automated change 2022-10-26 21:29:46 +00:00
Thomas Göttgens
eb29f10634 Merge pull request #1861 from meshtastic/lib-fix
Lib fix + NTP fix
2022-10-26 19:24:20 +02:00
Thomas Göttgens
d5a9e3114a Update ethClient.cpp 2022-10-26 18:37:51 +02:00
Thomas Göttgens
7417729482 debug removed 2022-10-26 18:37:20 +02:00
Thomas Göttgens
d5c407c098 remove accidental commit 2022-10-26 18:36:41 +02:00
Thomas Göttgens
a1256818d9 update library location 2022-10-26 18:25:31 +02:00
Thomas Göttgens
689cec14aa Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-10-26 18:15:07 +02:00
Thomas Göttgens
04225826f6 Bump ConfigDB Version.
this forces a factory reset on upgrade.
2022-10-26 18:12:31 +02:00
Thomas Göttgens
86787e60f3 Merge pull request #1860 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-10-26 17:56:41 +02:00
caveman99
0c3ec9254d [create-pull-request] automated change 2022-10-26 15:56:26 +00:00
Thomas Göttgens
c0770402ce Merge pull request #1855 from meshtastic/remove-softap
Remove Captive Portal and SoftAP Mode
2022-10-26 17:55:45 +02:00
Thomas Göttgens
d7c98062ce Merge remote-tracking branch 'remotes/origin/master' into remove-softap 2022-10-26 17:54:21 +02:00
Thomas Göttgens
497c0b7a47 don't rush failed time updates 2022-10-26 17:38:53 +02:00
Thomas Göttgens
d588dde007 Merge pull request #1842 from meshtastic/RAK13800
Rak13800
2022-10-26 11:33:22 +02:00
Thomas Göttgens
3de0a3adfc Merge branch 'RAK13800' of github.com:meshtastic/Meshtastic-device 2022-10-26 11:10:17 +02:00
Thomas Göttgens
b7ebe03ca8 API Server and DHCP Lease Management 2022-10-26 11:09:59 +02:00
Thomas Göttgens
a7fb88e293 make cppcheck happy about stuff it shouldn't care for 2022-10-26 09:16:54 +02:00
Thomas Göttgens
6e1b1e3ed7 Merge branch 'RAK13800' of github.com:meshtastic/Meshtastic-device 2022-10-26 00:07:33 +02:00
Thomas Göttgens
a66538fe55 MQTT is working over ethernet 2022-10-26 00:07:02 +02:00
Ben Meadors
b2913be086 Merge branch 'master' into RAK13800 2022-10-25 07:04:46 -05:00
Thomas Göttgens
602e65d898 fix non-ESP32 builds 2022-10-25 12:42:08 +02:00
Thomas Göttgens
338c9c1e0c Remove Captive Portal and SoftAP Mode 2022-10-25 11:53:22 +02:00
Thomas Göttgens
9fac57b713 Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-10-24 23:11:56 +02:00
Ben Meadors
761804b17a Send network ping on triple-click (#1852)
* Send network ping on multi-press

* Refresh myNodeInfo before sending

* Cleanup and screen print

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

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

* Only use modem_preset when we use_preset

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

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

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

* missed a spot

* Attempt to supress false positive

* Attempt to supress false positive

* Trying casing from the cpp-check manual

* Trying casing from the cpp-check manual

* Inline suppr should be default but...

* Maybe casting it will make the damn thing shut up

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

* Don't send unless our toPhoneQueue is empty

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

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

* Update Modules.cpp

* Update Modules.cpp

* Update Modules.cpp
2022-10-14 11:38:56 -05:00
Thomas Göttgens
f8fa721c72 Merge pull request #1798 from meshtastic/i2cscan
Scan for I2C devices twice on all CPU's
2022-10-14 15:33:46 +02:00
Thomas Göttgens
a7e0127793 scan i2c twice for all devices, not just tbeam 2022-10-13 23:46:25 +02:00
Thomas Göttgens
603f60d86a Merge branch 'master' of github.com:meshtastic/Meshtastic-device 2022-10-13 19:13:09 +02:00
Thomas Göttgens
6febf6b17c Merge pull request #1796 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2022-10-13 17:58:41 +02:00
thebentern
53aaf766dd [create-pull-request] automated change 2022-10-13 14:54:05 +00:00
Thomas Göttgens
efa423c8ad update FromRadio UUID for nRF52 devices 2022-10-13 16:20:27 +02:00
117 changed files with 2395 additions and 837 deletions

View File

@@ -2,14 +2,14 @@ name: CI
on:
# # Triggers the workflow on push but only for the master branch
push:
branches: [master]
branches: [master, develop]
paths-ignore:
- "**.md"
- "version.properties"
# Note: This is different from "pull_request". Need to specify ref when doing checkouts.
pull_request_target:
branches: [master]
branches: [master, develop]
paths-ignore:
- "**.md"
#- "**.yml"
@@ -33,6 +33,7 @@ jobs:
- board: heltec-v2.1
- board: tbeam0.7
- board: meshtastic-diy-v1
- board: meshtastic-dr-dev
- board: rak4631
- board: rak4631_eink
- board: t-echo
@@ -41,8 +42,9 @@ jobs:
- board: m5stack-core
- board: m5stack-coreink
- board: tbeam-s3-core
- board: feather_diy
# - board: pico
runs-on: ubuntu-latest
steps:
- name: Checkout code
@@ -57,12 +59,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
@@ -96,6 +98,7 @@ jobs:
- board: heltec-v2.1
- board: tbeam0.7
- board: meshtastic-diy-v1
- board: meshtastic-dr-dev
- board: nano-g1
- board: station-g1
- board: m5stack-core
@@ -112,12 +115,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
@@ -131,11 +134,11 @@ jobs:
- name: Upgrade platformio
run: |
pio upgrade
- name: Pull web ui
uses: dsaltares/fetch-gh-release-asset@master
with:
repo: "meshtastic/meshtastic-web"
repo: "meshtastic/web"
file: "build.tar"
target: "build.tar"
token: ${{ secrets.GITHUB_TOKEN }}
@@ -147,27 +150,27 @@ jobs:
- name: Build ESP32
run: bin/build-esp32.sh ${{ matrix.board }}
- name: Pull OTA Firmware
uses: dsaltares/fetch-gh-release-asset@master
with:
repo: "meshtastic/Meshtastic-OTA"
repo: "meshtastic/firmware-ota"
file: "firmware.bin"
target: "release/bleota.bin"
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: |
release/*.bin
release/*.elf
retention-days: 90
retention-days: 30
build-nrf52:
strategy:
@@ -179,6 +182,7 @@ jobs:
- board: rak4631_eink
- board: t-echo
- board: pca10059_diy_eink
- board: feather_diy
runs-on: ubuntu-latest
steps:
@@ -190,12 +194,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,18 +218,18 @@ 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: |
release/*.uf2
release/*.elf
release/*.zip
retention-days: 90
retention-days: 30
build-rpi2040:
strategy:
@@ -245,12 +249,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,17 +273,17 @@ 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: |
release/*.uf2
release/*.elf
retention-days: 90
retention-days: 30
build-native:
runs-on: ubuntu-latest
@@ -292,12 +296,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,18 +331,18 @@ 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: |
release/meshtasticd_linux_amd64
release/device-*.sh
release/device-*.bat
retention-days: 90
retention-days: 30
after-checks:
runs-on: ubuntu-latest
@@ -360,19 +364,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
run: mv -b -t ./ ./*tbeam-2*/littlefs*.bin ./*tbeam-2*/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 +388,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
@@ -392,7 +396,7 @@ jobs:
# For diagnostics
- name: Show artifacts
run: ls -lR
- name: Device scripts permissions
run: |
chmod +x ./output/device-install.sh
@@ -402,11 +406,11 @@ 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
retention-days: 90
retention-days: 30
- name: Create request artifacts
if: ${{ github.event_name == 'pull_request_target' || github.event_name == 'pull_request' }}
@@ -426,22 +430,22 @@ 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
- name: Device scripts permissions
run: |
chmod +x ./output/device-install.sh
@@ -450,11 +454,11 @@ 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
- name: Zip Elfs
run: zip -j -r ./debug-elfs-${{ steps.version.outputs.version }}.zip ./elfs
@@ -468,7 +472,7 @@ jobs:
with:
draft: true
prerelease: true
release_name: Meshtastic Device ${{ steps.version.outputs.version }} alpha - Public Preview
release_name: Meshtastic Firmware ${{ steps.version.outputs.version }}
tag_name: v${{ steps.version.outputs.version }}
body: |
Autogenerated by github action, developer should edit as required before publishing...
@@ -498,10 +502,9 @@ jobs:
- name: Bump version.properties
run: >-
bin/bump_version.py
- name: Create version.properties pull request
uses: peter-evans/create-pull-request@v3
with:
add-paths: |
version.properties

3
.gitmodules vendored
View File

@@ -1,3 +1,4 @@
[submodule "protobufs"]
path = protobufs
url = https://github.com/meshtastic/Meshtastic-protobufs.git
url = https://github.com/meshtastic/protobufs.git
branch = develop

15
Dockerfile Normal file
View File

@@ -0,0 +1,15 @@
FROM debian:bullseye-slim AS builder
RUN apt-get update
RUN DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install wget python3 g++ zip python3-venv git vim
RUN wget https://raw.githubusercontent.com/platformio/platformio-core-installer/master/get-platformio.py -O get-platformio.py; chmod +x get-platformio.py
RUN python3 get-platformio.py
RUN git clone https://github.com/meshtastic/firmware --recurse-submodules
RUN cd firmware
RUN chmod +x ./firmware/bin/build-native.sh
RUN . ~/.platformio/penv/bin/activate; cd firmware; sh ./bin/build-native.sh
FROM frolvlad/alpine-glibc
WORKDIR /root/
COPY --from=builder /firmware/release/meshtasticd_linux_amd64 ./
RUN apk --update add --no-cache g++
CMD sh -cx "./meshtasticd_linux_amd64 --hwid '$RANDOM'"

View File

@@ -1,8 +1,8 @@
# Meshtastic Firmware
![GitHub release downloads](https://img.shields.io/github/downloads/meshtastic/meshtastic-device/total)
[![CI](https://img.shields.io/github/workflow/status/meshtastic/Meshtastic-device/CI?label=actions&logo=github&color=yellow)](https://github.com/meshtastic/repo/actions/workflows/main_matrix.yml)
[![CLA assistant](https://cla-assistant.io/readme/badge/meshtastic/Meshtastic-device)](https://cla-assistant.io/meshtastic/Meshtastic-device)
![GitHub release downloads](https://img.shields.io/github/downloads/meshtastic/firmware/total)
[![CI](https://img.shields.io/github/workflow/status/meshtastic/firmware/CI?label=actions&logo=github&color=yellow)](https://github.com/meshtastic/firmware/actions/workflows/main_matrix.yml)
[![CLA assistant](https://cla-assistant.io/readme/badge/meshtastic/firmware)](https://cla-assistant.io/meshtastic/firmware)
[![Fiscal Contributors](https://opencollective.com/meshtastic/tiers/badge.svg?label=Fiscal%20Contributors&color=deeppink)](https://opencollective.com/meshtastic/)
[![Vercel](https://img.shields.io/static/v1?label=Powered%20by&message=Vercel&style=flat&logo=vercel&color=000000)](https://vercel.com?utm_source=meshtastic&utm_campaign=oss)
@@ -10,10 +10,9 @@
This repository contains the device firmware for the Meshtastic project.
**[Building Instructions](https://meshtastic.org/docs/developers/Firmware/build)**
**[Flashing Instructions](https://meshtastic.org/docs/getting-started/flashing-firmware/)**
## Stats
![Alt](https://repobeats.axiom.co/api/embed/99a2cf5622bb4807f9e8c3b86589f1133cce58a2.svg 'Repobeats analytics image')
![Alt](https://repobeats.axiom.co/api/embed/a92f097d9197ae853e780ec53d7d126e545629ab.svg "Repobeats analytics image")

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

@@ -1,109 +0,0 @@
#!/usr/bin/env bash
set -e
VERSION=`bin/buildinfo.py long`
SHORT_VERSION=`bin/buildinfo.py short`
BOARDS_ESP32="rak11200 tlora-v2 tlora-v1 tlora_v1_3 tlora-v2-1-1.6 tbeam heltec-v1 heltec-v2.0 heltec-v2.1 tbeam0.7 meshtastic-diy-v1 nano-g1 station-g1 m5stack-core m5stack-coreink"
#BOARDS_ESP32=tbeam
# FIXME note nrf52840dk build is for some reason only generating a BIN file but not a HEX file nrf52840dk-geeksville is fine
BOARDS_NRF52="rak4631 rak4631_eink t-echo pca10059_diy_eink"
#BOARDS_NRF52=""
OUTDIR=release/latest
# We keep all old builds (and their map files in the archive dir)
ARCHIVEDIR=release/archive
rm -f $OUTDIR/firmware*
mkdir -p $OUTDIR/bins $ARCHIVEDIR
rm -r $OUTDIR/bins/* || true
mkdir -p $OUTDIR/bins/universal $OUTDIR/elfs/universal
# build the named environment and copy the bins to the release directory
function do_build() {
BOARD=$1
isNrf=$3
echo "Building for $BOARD ($isNrf) with $PLATFORMIO_BUILD_FLAGS"
rm -f .pio/build/$BOARD/firmware.*
# The shell vars the build tool expects to find
export APP_VERSION=$VERSION
basename=universal/firmware-$BOARD-$VERSION
pio run --environment $BOARD # -v
SRCELF=.pio/build/$BOARD/firmware.elf
cp $SRCELF $OUTDIR/elfs/$basename.elf
if [ "$isNrf" = "false" ]
then
echo "Copying ESP32 bin file"
SRCBIN=.pio/build/$BOARD/firmware.bin
cp $SRCBIN $OUTDIR/bins/$basename.bin
else
echo "Generating NRF52 uf2 file"
SRCHEX=.pio/build/$BOARD/firmware.hex
bin/uf2conv.py $SRCHEX -c -o $OUTDIR/bins/$basename.uf2 -f 0xADA52840
fi
}
function do_boards() {
declare boards=$1
declare isNrf=$2
for board in $boards; do
# Build universal
echo "about to build $board $isNrf"
do_build $board "" "$isNrf"
done
}
# Make sure our submodules are current
git submodule update
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
platformio lib update
do_boards "$BOARDS_ESP32" "false"
do_boards "$BOARDS_NRF52" "true"
pio run --environment native
cp .pio/build/native/program $OUTDIR/bins/universal/meshtasticd_linux_amd64
echo "Building Filesystem for ESP32 targets"
pio run --environment tbeam -t buildfs
cp .pio/build/tbeam/spiffs.bin $OUTDIR/bins/universal/littlefs-$VERSION.bin
# keep the bins in archive also
cp $OUTDIR/bins/universal/littlefs* $OUTDIR/bins/universal/firmware* $OUTDIR/elfs/universal/firmware* $ARCHIVEDIR
echo Updating android bins $OUTDIR/forandroid
rm -rf $OUTDIR/forandroid
mkdir -p $OUTDIR/forandroid
cp -a $OUTDIR/bins/universal/*.bin $OUTDIR/forandroid/
cat >$OUTDIR/curfirmwareversion.xml <<XML
<?xml version="1.0" encoding="utf-8"?>
<!-- This file is kept in source control because it reflects the last stable
release. It is used by the android app for forcing software updates. Do not edit.
Generated by bin/buildall.sh -->
<resources>
<string name="cur_firmware_version" translatable="false">$VERSION</string>
<string name="short_firmware_version" translatable="false">$SHORT_VERSION</string>
</resources>
XML
echo Generating $ARCHIVEDIR/firmware-$VERSION.zip
rm -f $ARCHIVEDIR/firmware-$VERSION.zip
zip --junk-paths $ARCHIVEDIR/firmware-$VERSION.zip $ARCHIVEDIR/littlefs-$VERSION.bin $OUTDIR/bins/universal/firmware-*-$VERSION.* $OUTDIR/bins/universal/meshtasticd* images/system-info.bin bin/device-install.* bin/device-update.*
echo Generating $ARCHIVEDIR/elfs-$VERSION.zip
rm -f $ARCHIVEDIR/elfs-$VERSION.zip
zip --junk-paths $ARCHIVEDIR/elfs-$VERSION.zip $OUTDIR/elfs/universal/firmware-*-$VERSION.*
echo BUILT ALL

View File

@@ -14,7 +14,7 @@ rm -r $OUTDIR/* || true
git submodule update
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
platformio lib update
platformio pkg update
echo "Building for $1 with $PLATFORMIO_BUILD_FLAGS"
rm -f .pio/build/$1/firmware.*

View File

@@ -16,7 +16,7 @@ rm -r $OUTDIR/* || true
git submodule update
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
platformio lib update
platformio pkg update
pio run --environment native
cp .pio/build/native/program $OUTDIR/meshtasticd_linux_amd64

View File

@@ -14,7 +14,7 @@ rm -r $OUTDIR/* || true
git submodule update
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
platformio lib update
platformio pkg update
echo "Building for $1 with $PLATFORMIO_BUILD_FLAGS"
rm -f .pio/build/$1/firmware.*

View File

@@ -14,7 +14,7 @@ rm -r $OUTDIR/* || true
git submodule update
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
platformio lib update
platformio pkg update
echo "Building for $1 with $PLATFORMIO_BUILD_FLAGS"
rm -f .pio/build/$1/firmware.*

View File

@@ -9,9 +9,6 @@ VERSION=`bin/buildinfo.py long`
# Must have a V prefix to trigger github
git tag "v${VERSION}"
# Commented out per https://github.com/meshtastic/Meshtastic-device/issues/947
#git push root "v${VERSION}" # push the tag
git push origin "v${VERSION}" # push the tag
echo "Tag ${VERSION} pushed to github, github actions should now be building the draft release. If it seems good, click to publish it"

View File

@@ -3,7 +3,7 @@
set -e
echo "This script requires https://jpa.kapsi.fi/nanopb/download/ version 0.4.6 to be located in the"
echo "meshtastic-device root directory if the following step fails, you should download the correct"
echo "firmware root directory if the following step fails, you should download the correct"
echo "prebuilt binaries for your computer into nanopb-0.4.6"
# the nanopb tool seems to require that the .options file be in the current directory!

13
docker-compose.yml Normal file
View File

@@ -0,0 +1,13 @@
version: "3.7"
services:
meshtastic-node:
build: .
deploy:
mode: replicated
replicas: 80
networks:
- mesh
networks:
mesh:

View File

@@ -22,6 +22,7 @@
;default_envs = pca10059_diy_eink
;default_envs = meshtastic-diy-v1
;default_envs = meshtastic-diy-v1.1
;default_envs = meshtastic-dr-dev
;default_envs = m5stack-coreink
;default_envs = rak4631
@@ -57,6 +58,9 @@ lib_deps =
; Used for the code analysis in PIO Home / Inspect
check_tool = cppcheck
check_skip_packages = yes
check_flags =
-DAPP_VERSION=1.0.0
--suppressions-list=suppressions.txt
; Common settings for conventional (non Portduino) Arduino targets
[arduino_base]
@@ -65,7 +69,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 +80,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
@@ -90,4 +95,5 @@ lib_deps =
adafruit/Adafruit MCP9808 Library@^2.0.0
adafruit/Adafruit INA260 Library@^1.5.0
adafruit/Adafruit INA219@^1.2.0
adafruit/Adafruit SHTC3 Library@^1.0.0
adafruit/Adafruit LPS2X@^2.0.4

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) && defined(PIN_EINK_EN)
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

@@ -233,11 +233,14 @@ bool Power::setup()
void Power::shutdown()
{
screen->setOn(false);
#if defined(USE_EINK) && defined(PIN_EINK_EN)
digitalWrite(PIN_EINK_EN, LOW); //power off backlight first
#endif
#ifdef HAS_PMU
DEBUG_MSG("Shutting down\n");
if(PMU){
if(PMU) {
PMU->setChargingLedMode(XPOWERS_CHG_LED_OFF);
PMU->shutdown();
}
@@ -312,7 +315,7 @@ int32_t Power::runOnce()
#ifdef HAS_PMU
// WE no longer use the IRQ line to wake the CPU (due to false wakes from sleep), but we do poll
// the IRQ status by reading the registers over I2C
if(PMU){
if(PMU) {
PMU->getIrqStatus();
@@ -341,10 +344,11 @@ int32_t Power::runOnce()
if (PMU->isBatRemoveIrq()) {
DEBUG_MSG("Battery removed\n");
}
if (PMU->isPekeyShortPressIrq()) {
DEBUG_MSG("PEK short button press\n");
}
*/
if (PMU->isPekeyLongPressIrq()) {
DEBUG_MSG("PEK long button press\n");
screen->setOn(false);
}
PMU->clearIrqStatus();
}
@@ -451,7 +455,6 @@ bool Power::axpChipInit()
// Set constant current charging current
PMU->setChargerConstantCurr(XPOWERS_AXP192_CHG_CUR_450MA);
} else if (PMU->getChipModel() == XPOWERS_AXP2101) {
// t-beam s3 core

View File

@@ -337,7 +337,7 @@ void PowerFSM_setup()
#ifdef ARCH_ESP32
// We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally)
// See: https://github.com/meshtastic/Meshtastic-device/issues/1071
// See: https://github.com/meshtastic/firmware/issues/1071
if (isRouter || config.power.is_power_saving) {
powerFSM.add_timed_transition(&stateNB, &stateLS, getConfiguredOrDefaultMs(config.power.min_wake_secs, default_min_wake_secs), NULL, "Min wake timeout");
powerFSM.add_timed_transition(&stateDARK, &stateLS, getConfiguredOrDefaultMs(config.power.wait_bluetooth_secs, default_wait_bluetooth_secs), NULL, "Bluetooth timeout");

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

@@ -110,6 +110,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define INA_ADDR_ALTERNATE 0x41
#define QMC6310_ADDR 0x1C
#define QMI8658_ADDR 0x6B
#define SHTC3_ADDR 0x70
#define LPS22HB_ADDR 0x5C
#define LPS22HB_ADDR_ALT 0x5D
// -----------------------------------------------------------------------------
// Security
@@ -139,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 HAS_ETHERNET 0
#endif
#ifndef HAS_SCREEN
#define HAS_SCREEN 0
#endif
@@ -160,6 +166,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef HAS_RTC
#define HAS_RTC 0
#endif
#ifndef HAS_CPU_SHUTDOWN
#define HAS_CPU_SHUTDOWN 0
#endif
#ifndef HAS_BLUETOOTH
#define HAS_BLUETOOTH 0
#endif
#include "RF95Configuration.h"
#include "DebugConfiguration.h"

View File

@@ -191,14 +191,22 @@ void scanI2Cdevice(void)
nodeTelemetrySensorsMap[TelemetrySensorType_MCP9808] = addr;
DEBUG_MSG("MCP9808 sensor found at address 0x%x\n", (uint8_t)addr);
}
if(addr == QMC6310_ADDR){
if (addr == QMC6310_ADDR) {
DEBUG_MSG("QMC6310 3-Axis magnetic sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_QMC6310] = addr;
}
if(addr == QMI8658_ADDR){
if (addr == QMI8658_ADDR) {
DEBUG_MSG("QMI8658 6-Axis inertial measurement sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_QMI8658] = addr;
}
if (addr == SHTC3_ADDR) {
DEBUG_MSG("SHTC3 sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_SHTC3] = addr;
}
if (addr == LPS22HB_ADDR || addr == LPS22HB_ADDR_ALT) {
DEBUG_MSG("LPS22HB sensor found at address 0x%x\n", (uint8_t)addr);
nodeTelemetrySensorsMap[TelemetrySensorType_LPS22] = addr;
}
} else if (err == 4) {
DEBUG_MSG("Unknow error at address 0x%x\n", addr);
}

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

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

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

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

View File

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

View File

@@ -14,8 +14,8 @@
#define TECHO_DISPLAY_MODEL GxEPD2_154_D67
#elif defined(RAK4630)
//GxEPD2_213_B74 - RAK14000 2.13 inch b/w 250x128
#define TECHO_DISPLAY_MODEL GxEPD2_213_B74
//GxEPD2_213_BN - RAK14000 2.13 inch b/w 250x122 - changed from GxEPD2_213_B74 - which was not going to give partial update support
#define TECHO_DISPLAY_MODEL GxEPD2_213_BN
//4.2 inch 300x400 - GxEPD2_420_M01
//#define TECHO_DISPLAY_MODEL GxEPD2_420_M01
@@ -46,9 +46,9 @@ EInkDisplay::EInkDisplay(uint8_t address, int sda, int scl)
setGeometry(GEOMETRY_RAWMODE, TECHO_DISPLAY_MODEL::WIDTH, TECHO_DISPLAY_MODEL::HEIGHT);
#elif defined(RAK4630)
//GxEPD2_213_B74 - RAK14000 2.13 inch b/w 250x128
//GxEPD2_213_BN - RAK14000 2.13 inch b/w 250x122
setGeometry(GEOMETRY_RAWMODE, 250, 122);
//GxEPD2_420_M01
//setGeometry(GEOMETRY_RAWMODE, 300, 400);
@@ -110,14 +110,17 @@ bool EInkDisplay::forceDisplay(uint32_t msecLimit)
adafruitDisplay->display(false); // FIXME, use partial update mode
#elif defined(RAK4630)
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
adafruitDisplay->display(false); // FIXME, use partial update mode
//RAK14000 2.13 inch b/w 250x122 actually now does support partial updates
//Full update mode (slow)
//adafruitDisplay->display(false); // FIXME, use partial update mode
//Only enable for e-Paper with support for partial updates and comment out above adafruitDisplay->display(false);
// 1.54 inch 200x200 - GxEPD2_154_M09
// 2.13 inch 250x122 - GxEPD2_213_BN
// 2.9 inch 296x128 - GxEPD2_290_T5D
// 4.2 inch 300x400 - GxEPD2_420_M01
//adafruitDisplay->nextPage();
adafruitDisplay->nextPage();
#elif defined(PCA10059) || defined(M5_COREINK)
adafruitDisplay->nextPage();
@@ -190,11 +193,11 @@ bool EInkDisplay::connect()
adafruitDisplay->init(115200, true, 10, false, SPI1, SPISettings(4000000, MSBFIRST, SPI_MODE0));
//RAK14000 2.13 inch b/w 250x122 does not support partial updates
//RAK14000 2.13 inch b/w 250x122 does actually now support partial updates
adafruitDisplay->setRotation(3);
//For 1.54, 2.9 and 4.2
//Partial update support for 1.54, 2.13 RAK14000 b/w , 2.9 and 4.2
//adafruitDisplay->setRotation(1);
//adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
} else {
(void)adafruitDisplay;
}

View File

@@ -50,8 +50,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
using namespace meshtastic; /** @todo remove */
extern bool loadProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, void *dest_struct);
namespace graphics
{
@@ -67,6 +65,8 @@ namespace graphics
static FrameCallback normalFrames[MAX_NUM_NODES + NUM_EXTRA_FRAMES];
static uint32_t targetFramerate = IDLE_FRAMERATE;
static char btPIN[16] = "888888";
uint32_t logo_timeout = 5000; // 4 seconds for EACH logo
// This image definition is here instead of images.h because it's modified dynamically by the drawBattery function
uint8_t imgBattery[16] = {0xFF, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xE7, 0x3C};
@@ -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();
@@ -951,6 +944,9 @@ void Screen::setup()
// Set the utf8 conversion function
dispdev.setFontTableLookupFunction(customFontTableLookup);
if (strlen(oemStore.oem_text) > 0)
logo_timeout *= 2;
// Add frames.
static FrameCallback bootFrames[] = {drawBootScreen};
static const int bootFrameCount = sizeof(bootFrames) / sizeof(bootFrames[0]);
@@ -1019,26 +1015,28 @@ int32_t Screen::runOnce()
return RUN_SAME;
}
// Show boot screen for first 5 seconds, then switch to normal operation.
// Show boot screen for first logo_timeout seconds, then switch to normal operation.
// serialSinceMsec adjusts for additional serial wait time during nRF52 bootup
static bool showingBootScreen = true;
if (showingBootScreen && (millis() > (5000 + serialSinceMsec))) {
if (showingBootScreen && (millis() > (logo_timeout + serialSinceMsec))) {
DEBUG_MSG("Done with boot screen...\n");
stopBootScreen();
showingBootScreen = false;
}
// If we have an OEM Boot screen, toggle after 2,5 seconds
// If we have an OEM Boot screen, toggle after logo_timeout seconds
if (strlen(oemStore.oem_text) > 0) {
static bool showingOEMBootScreen = true;
if (showingOEMBootScreen && (millis() > (2500 + serialSinceMsec))) {
if (showingOEMBootScreen && (millis() > ((logo_timeout / 2) + serialSinceMsec))) {
DEBUG_MSG("Switch to OEM screen...\n");
// Change frames.
static FrameCallback bootOEMFrames[] = {drawOEMBootScreen};
static const int bootOEMFrameCount = sizeof(bootOEMFrames) / sizeof(bootOEMFrames[0]);
ui.setFrames(bootOEMFrames, bootOEMFrameCount);
ui.update();
#ifndef USE_EINK
ui.update();
#endif
showingOEMBootScreen = false;
}
}
@@ -1397,7 +1395,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 +1403,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 +1424,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 +1498,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

@@ -10,7 +10,7 @@ namespace graphics
class Screen
{
public:
Screen(char){}
explicit Screen(char){}
void onPress() {}
void setup() {}
void setOn(bool) {}
@@ -131,8 +131,7 @@ class Screen : public concurrency::OSThread
void setOn(bool on)
{
if (!on)
handleSetOn(
false); // We handle off commands immediately, because they might be called because the CPU is shutting down
handleSetOn(false); // We handle off commands immediately, because they might be called because the CPU is shutting down
else
enqueueCmd(ScreenCmd{.cmd = on ? Cmd::SET_ON : Cmd::SET_OFF});
}

View File

@@ -30,21 +30,28 @@
// #include <driver/rtc_io.h>
#include "mesh/http/WiFiAPClient.h"
#include "mesh/eth/ethClient.h"
#ifdef ARCH_ESP32
#include "mesh/http/WebServer.h"
#include "nimble/NimbleBluetooth.h"
#endif
#if HAS_WIFI || defined(ARCH_PORTDUINO)
#if HAS_WIFI
#include "mesh/wifi/WiFiServerAPI.h"
#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 "SX1280Interface.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);
@@ -281,12 +289,14 @@ void setup()
power->setup(); // Must be after status handler is installed, so that handler gets notified of the initial configuration
/*
* Repeat the scanning for I2C devices after power initialization.
* Repeat the scanning for I2C devices after power initialization or look for 'latecomers'.
* Boards with an PMU need to be powered on to correctly scan to the device address, such as t-beam-s3-core
*/
if ((HW_VENDOR == HardwareModel_LILYGO_TBEAM_S3_CORE) || (HW_VENDOR == HardwareModel_TBEAM)) {
scanI2Cdevice();
}
scanI2Cdevice();
// fixed screen override?
if (config.display.oled != Config_DisplayConfig_OledType_OLED_AUTO)
screen_model = config.display.oled;
// Init our SPI controller (must be before screen and lora)
initSPI();
@@ -366,6 +376,20 @@ void setup()
}
#endif
#if defined(USE_SX1280) && !defined(ARCH_PORTDUINO)
if (!rIf) {
rIf = new SX1280Interface(SX128X_CS, SX128X_DIO1, SX128X_RESET, SX128X_BUSY, SPI);
if (!rIf->init()) {
DEBUG_MSG("Warning: Failed to find SX1280 radio\n");
delete rIf;
rIf = NULL;
} else {
DEBUG_MSG("SX1280 Radio init succeeded, using SX1280 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);
@@ -418,12 +442,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
@@ -210,9 +218,7 @@ const char *Channels::getName(size_t chIndex)
// Per mesh.proto spec, if bandwidth is specified we must ignore modemPreset enum, we assume that in that case
// the app fucked up and forgot to set channelSettings.name
if (config.lora.bandwidth != 0)
channelName = "Custom";
else
if (config.lora.use_preset) {
switch (config.lora.modem_preset) {
case Config_LoRaConfig_ModemPreset_SHORT_SLOW:
channelName = "ShortSlow";
@@ -239,6 +245,10 @@ const char *Channels::getName(size_t chIndex)
channelName = "Invalid";
break;
}
}
else {
channelName = "Custom";
}
}
return channelName;
@@ -257,7 +267,7 @@ their nodes
*
* This function will also need to be implemented in GUI apps that talk to the radio.
*
* https://github.com/meshtastic/Meshtastic-device/issues/269
* https://github.com/meshtastic/firmware/issues/269
*/
const char *Channels::getPrimaryName()
{

View File

@@ -74,7 +74,7 @@ class Channels
*
* This function will also need to be implemented in GUI apps that talk to the radio.
*
* https://github.com/meshtastic/Meshtastic-device/issues/269
* https://github.com/meshtastic/firmware/issues/269
*/
const char *getPrimaryName();

View File

@@ -29,8 +29,8 @@ bool FloodingRouter::shouldFilterReceived(MeshPacket *p)
void FloodingRouter::sniffReceived(const MeshPacket *p, const Routing *c)
{
PacketId ackId = ((c && c->error_reason == Routing_Error_NONE) || !c) ? p->decoded.request_id : 0;
if (ackId && p->to != getNodeNum()) {
bool isAck = ((c && c->error_reason == Routing_Error_NONE)); // consider only ROUTING_APP message without error as ACK
if (isAck && p->to != getNodeNum()) {
// do not flood direct message that is ACKed
DEBUG_MSG("Receiving an ACK not for me, but don't need to rebroadcast this direct message anymore.\n");
Router::cancelSending(p->to, p->decoded.request_id); // cancel rebroadcast for this DM

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<SX1280>;
#endif

View File

@@ -109,10 +109,7 @@ void MeshModule::callPlugins(const MeshPacket &mp, RxSource src)
/// Also: if a packet comes in on the local PC interface, we don't check for bound channels, because it is TRUSTED and it needs to
/// to be able to fetch the initial admin packets without yet knowing any channels.
bool rxChannelOk = !pi.boundChannel || (mp.from == 0) ||
!ch ||
strlen(ch->settings.name) > 0 ||
(strcasecmp(ch->settings.name, pi.boundChannel) == 0);
bool rxChannelOk = !pi.boundChannel || (mp.from == 0) || (strcasecmp(ch->settings.name, pi.boundChannel) == 0);
if (!rxChannelOk) {
// no one should have already replied!

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

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

View File

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

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

@@ -249,11 +249,15 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_canned_message_tag;
fromRadioScratch.moduleConfig.payload_variant.canned_message = moduleConfig.canned_message;
break;
case ModuleConfig_audio_tag:
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_audio_tag;
fromRadioScratch.moduleConfig.payload_variant.audio = moduleConfig.audio;
break;
}
config_state++;
// Advance when we have sent all of our ModuleConfig objects
if (config_state > ModuleConfig_canned_message_tag) {
if (config_state > ModuleConfig_audio_tag) {
state = STATE_SEND_COMPLETE_ID;
config_state = 0;
}

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;
@@ -408,14 +416,14 @@ void RadioInterface::applyModemConfig()
power = loraConfig.tx_power;
assert(myRegion); // Should have been found in init
if ((power == 0) || (power > myRegion->powerLimit))
if ((power == 0) || ((power > myRegion->powerLimit) && !devicestate.owner.is_licensed))
power = myRegion->powerLimit;
if (power == 0)
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)));
@@ -452,7 +460,7 @@ void RadioInterface::limitPower()
if (myRegion->powerLimit)
maxPower = myRegion->powerLimit;
if (power > maxPower) {
if ((power > maxPower) && !devicestate.owner.is_licensed) {
DEBUG_MSG("Lowering transmit power because of regulatory limits\n");
power = maxPower;
}

View File

@@ -317,7 +317,13 @@ ErrorCode RadioLibInterface::send(MeshPacket *p)
void RadioLibInterface::handleReceiveInterrupt()
{
uint32_t xmitMsec;
assert(isReceiving);
// when this is called, we should be in receive mode - if we are not, just jump out instead of bombing. Possible Race Condition?
if (!isReceiving) {
DEBUG_MSG("*** WAS_ASSERT *** handleReceiveInterrupt called when not in receive mode\n");
return;
}
isReceiving = false;
// read the number of actually received bytes

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

@@ -11,7 +11,7 @@ extern "C" {
#include "mesh/compression/unishox2.h"
}
#if HAS_WIFI
#if HAS_WIFI || HAS_ETHERNET
#include "mqtt/MQTT.h"
#endif
@@ -209,7 +209,7 @@ ErrorCode Router::send(MeshPacket *p)
if (p->which_payload_variant == MeshPacket_decoded_tag) {
ChannelIndex chIndex = p->channel; // keep as a local because we are about to change it
#if HAS_WIFI
#if HAS_WIFI || HAS_ETHERNET
// check if we should send decrypted packets to mqtt
// truth table:
@@ -240,7 +240,7 @@ ErrorCode Router::send(MeshPacket *p)
return encodeResult; // FIXME - this isn't a valid ErrorCode
}
#if HAS_WIFI
#if HAS_WIFI || HAS_ETHERNET
// the packet is now encrypted.
// check if we should send encrypted packets to mqtt
if (mqtt && shouldActuallyEncrypt)

View File

@@ -0,0 +1,13 @@
#include "configuration.h"
#include "SX1280Interface.h"
#include "error.h"
#if !defined(ARCH_PORTDUINO)
SX1280Interface::SX1280Interface(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 SX1280 radios
*/
#if !defined(ARCH_PORTDUINO)
class SX1280Interface : public SX128xInterface<SX1280>
{
public:
SX1280Interface(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: SX1280.
*/
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

@@ -32,7 +32,8 @@ typedef enum _AdminMessage_ModuleConfigType {
AdminMessage_ModuleConfigType_STOREFORWARD_CONFIG = 3,
AdminMessage_ModuleConfigType_RANGETEST_CONFIG = 4,
AdminMessage_ModuleConfigType_TELEMETRY_CONFIG = 5,
AdminMessage_ModuleConfigType_CANNEDMSG_CONFIG = 6
AdminMessage_ModuleConfigType_CANNEDMSG_CONFIG = 6,
AdminMessage_ModuleConfigType_AUDIO_CONFIG = 7
} AdminMessage_ModuleConfigType;
/* Struct definitions */
@@ -116,8 +117,8 @@ typedef struct _AdminMessage {
#define _AdminMessage_ConfigType_ARRAYSIZE ((AdminMessage_ConfigType)(AdminMessage_ConfigType_BLUETOOTH_CONFIG+1))
#define _AdminMessage_ModuleConfigType_MIN AdminMessage_ModuleConfigType_MQTT_CONFIG
#define _AdminMessage_ModuleConfigType_MAX AdminMessage_ModuleConfigType_CANNEDMSG_CONFIG
#define _AdminMessage_ModuleConfigType_ARRAYSIZE ((AdminMessage_ModuleConfigType)(AdminMessage_ModuleConfigType_CANNEDMSG_CONFIG+1))
#define _AdminMessage_ModuleConfigType_MAX AdminMessage_ModuleConfigType_AUDIO_CONFIG
#define _AdminMessage_ModuleConfigType_ARRAYSIZE ((AdminMessage_ModuleConfigType)(AdminMessage_ModuleConfigType_AUDIO_CONFIG+1))
#ifdef __cplusplus

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

@@ -31,11 +31,10 @@ typedef enum _Config_PositionConfig_PositionFlags {
Config_PositionConfig_PositionFlags_SPEED = 512
} Config_PositionConfig_PositionFlags;
typedef enum _Config_NetworkConfig_WiFiMode {
Config_NetworkConfig_WiFiMode_CLIENT = 0,
Config_NetworkConfig_WiFiMode_ACCESS_POINT = 1,
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,
@@ -51,6 +50,12 @@ typedef enum _Config_DisplayConfig_DisplayUnits {
Config_DisplayConfig_DisplayUnits_IMPERIAL = 1
} Config_DisplayConfig_DisplayUnits;
typedef enum _Config_DisplayConfig_OledType {
Config_DisplayConfig_OledType_OLED_AUTO = 0,
Config_DisplayConfig_OledType_OLED_SSD1306 = 1,
Config_DisplayConfig_OledType_OLED_SH1106 = 2
} Config_DisplayConfig_OledType;
typedef enum _Config_LoRaConfig_RegionCode {
Config_LoRaConfig_RegionCode_UNSET = 0,
Config_LoRaConfig_RegionCode_US = 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 {
@@ -103,6 +109,7 @@ typedef struct _Config_DisplayConfig {
bool compass_north_top;
bool flip_screen;
Config_DisplayConfig_DisplayUnits units;
Config_DisplayConfig_OledType oled;
} Config_DisplayConfig;
typedef struct _Config_LoRaConfig {
@@ -116,18 +123,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 +156,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 {
@@ -173,9 +190,9 @@ typedef struct _Config {
#define _Config_PositionConfig_PositionFlags_MAX Config_PositionConfig_PositionFlags_SPEED
#define _Config_PositionConfig_PositionFlags_ARRAYSIZE ((Config_PositionConfig_PositionFlags)(Config_PositionConfig_PositionFlags_SPEED+1))
#define _Config_NetworkConfig_WiFiMode_MIN Config_NetworkConfig_WiFiMode_CLIENT
#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
@@ -185,9 +202,13 @@ typedef struct _Config {
#define _Config_DisplayConfig_DisplayUnits_MAX Config_DisplayConfig_DisplayUnits_IMPERIAL
#define _Config_DisplayConfig_DisplayUnits_ARRAYSIZE ((Config_DisplayConfig_DisplayUnits)(Config_DisplayConfig_DisplayUnits_IMPERIAL+1))
#define _Config_DisplayConfig_OledType_MIN Config_DisplayConfig_OledType_OLED_AUTO
#define _Config_DisplayConfig_OledType_MAX Config_DisplayConfig_OledType_OLED_SH1106
#define _Config_DisplayConfig_OledType_ARRAYSIZE ((Config_DisplayConfig_OledType)(Config_DisplayConfig_OledType_OLED_SH1106+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,16 +228,18 @@ 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_DisplayConfig_init_default {0, _Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _Config_DisplayConfig_DisplayUnits_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, _Config_DisplayConfig_OledType_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}
#define Config_init_zero {0, {Config_DeviceConfig_init_zero}}
#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_DisplayConfig_init_zero {0, _Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _Config_DisplayConfig_DisplayUnits_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, _Config_DisplayConfig_OledType_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}
@@ -233,6 +256,7 @@ extern "C" {
#define Config_DisplayConfig_compass_north_top_tag 4
#define Config_DisplayConfig_flip_screen_tag 5
#define Config_DisplayConfig_units_tag 6
#define Config_DisplayConfig_oled_tag 7
#define Config_LoRaConfig_use_preset_tag 1
#define Config_LoRaConfig_modem_preset_tag 2
#define Config_LoRaConfig_bandwidth_tag 3
@@ -245,11 +269,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 +288,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 +354,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) \
@@ -337,7 +378,8 @@ X(a, STATIC, SINGULAR, UENUM, gps_format, 2) \
X(a, STATIC, SINGULAR, UINT32, auto_screen_carousel_secs, 3) \
X(a, STATIC, SINGULAR, BOOL, compass_north_top, 4) \
X(a, STATIC, SINGULAR, BOOL, flip_screen, 5) \
X(a, STATIC, SINGULAR, UENUM, units, 6)
X(a, STATIC, SINGULAR, UENUM, units, 6) \
X(a, STATIC, SINGULAR, UENUM, oled, 7)
#define Config_DisplayConfig_CALLBACK NULL
#define Config_DisplayConfig_DEFAULT NULL
@@ -369,6 +411,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 +422,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
@@ -386,12 +430,13 @@ extern const pb_msgdesc_t Config_BluetoothConfig_msg;
/* Maximum encoded size of messages (where known) */
#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_DisplayConfig_size 22
#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

@@ -16,6 +16,14 @@ typedef struct _DeviceMetadata {
char firmware_version[18];
/* Device state version */
uint32_t device_state_version;
/* Indicates whether the device can shutdown CPU natively or via power management chip */
bool canShutdown;
/* Indicates that the device has native wifi capability */
bool hasWifi;
/* Indicates that the device has native bluetooth capability */
bool hasBluetooth;
/* Indicates that the device has an ethernet peripheral */
bool hasEthernet;
} DeviceMetadata;
@@ -24,17 +32,25 @@ extern "C" {
#endif
/* Initializer values for message structs */
#define DeviceMetadata_init_default {"", 0}
#define DeviceMetadata_init_zero {"", 0}
#define DeviceMetadata_init_default {"", 0, 0, 0, 0, 0}
#define DeviceMetadata_init_zero {"", 0, 0, 0, 0, 0}
/* Field tags (for use in manual encoding/decoding) */
#define DeviceMetadata_firmware_version_tag 1
#define DeviceMetadata_device_state_version_tag 2
#define DeviceMetadata_canShutdown_tag 3
#define DeviceMetadata_hasWifi_tag 4
#define DeviceMetadata_hasBluetooth_tag 5
#define DeviceMetadata_hasEthernet_tag 6
/* Struct field encoding specification for nanopb */
#define DeviceMetadata_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, STRING, firmware_version, 1) \
X(a, STATIC, SINGULAR, UINT32, device_state_version, 2)
X(a, STATIC, SINGULAR, UINT32, device_state_version, 2) \
X(a, STATIC, SINGULAR, BOOL, canShutdown, 3) \
X(a, STATIC, SINGULAR, BOOL, hasWifi, 4) \
X(a, STATIC, SINGULAR, BOOL, hasBluetooth, 5) \
X(a, STATIC, SINGULAR, BOOL, hasEthernet, 6)
#define DeviceMetadata_CALLBACK NULL
#define DeviceMetadata_DEFAULT NULL
@@ -44,7 +60,7 @@ extern const pb_msgdesc_t DeviceMetadata_msg;
#define DeviceMetadata_fields &DeviceMetadata_msg
/* Maximum encoded size of messages (where known) */
#define DeviceMetadata_size 25
#define DeviceMetadata_size 33
#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

@@ -66,6 +66,9 @@ typedef struct _LocalModuleConfig {
incompatible changes This integer is set at build time and is private to
NodeDB.cpp in the device code. */
uint32_t version;
/* The part of the config that is specific to the Audio module */
bool has_audio;
ModuleConfig_AudioConfig audio;
} LocalModuleConfig;
@@ -75,9 +78,9 @@ extern "C" {
/* Initializer values for message structs */
#define LocalConfig_init_default {false, Config_DeviceConfig_init_default, false, Config_PositionConfig_init_default, false, Config_PowerConfig_init_default, false, Config_NetworkConfig_init_default, false, Config_DisplayConfig_init_default, false, Config_LoRaConfig_init_default, false, Config_BluetoothConfig_init_default, 0}
#define LocalModuleConfig_init_default {false, ModuleConfig_MQTTConfig_init_default, false, ModuleConfig_SerialConfig_init_default, false, ModuleConfig_ExternalNotificationConfig_init_default, false, ModuleConfig_StoreForwardConfig_init_default, false, ModuleConfig_RangeTestConfig_init_default, false, ModuleConfig_TelemetryConfig_init_default, false, ModuleConfig_CannedMessageConfig_init_default, 0}
#define LocalModuleConfig_init_default {false, ModuleConfig_MQTTConfig_init_default, false, ModuleConfig_SerialConfig_init_default, false, ModuleConfig_ExternalNotificationConfig_init_default, false, ModuleConfig_StoreForwardConfig_init_default, false, ModuleConfig_RangeTestConfig_init_default, false, ModuleConfig_TelemetryConfig_init_default, false, ModuleConfig_CannedMessageConfig_init_default, 0, false, ModuleConfig_AudioConfig_init_default}
#define LocalConfig_init_zero {false, Config_DeviceConfig_init_zero, false, Config_PositionConfig_init_zero, false, Config_PowerConfig_init_zero, false, Config_NetworkConfig_init_zero, false, Config_DisplayConfig_init_zero, false, Config_LoRaConfig_init_zero, false, Config_BluetoothConfig_init_zero, 0}
#define LocalModuleConfig_init_zero {false, ModuleConfig_MQTTConfig_init_zero, false, ModuleConfig_SerialConfig_init_zero, false, ModuleConfig_ExternalNotificationConfig_init_zero, false, ModuleConfig_StoreForwardConfig_init_zero, false, ModuleConfig_RangeTestConfig_init_zero, false, ModuleConfig_TelemetryConfig_init_zero, false, ModuleConfig_CannedMessageConfig_init_zero, 0}
#define LocalModuleConfig_init_zero {false, ModuleConfig_MQTTConfig_init_zero, false, ModuleConfig_SerialConfig_init_zero, false, ModuleConfig_ExternalNotificationConfig_init_zero, false, ModuleConfig_StoreForwardConfig_init_zero, false, ModuleConfig_RangeTestConfig_init_zero, false, ModuleConfig_TelemetryConfig_init_zero, false, ModuleConfig_CannedMessageConfig_init_zero, 0, false, ModuleConfig_AudioConfig_init_zero}
/* Field tags (for use in manual encoding/decoding) */
#define LocalConfig_device_tag 1
@@ -96,6 +99,7 @@ extern "C" {
#define LocalModuleConfig_telemetry_tag 6
#define LocalModuleConfig_canned_message_tag 7
#define LocalModuleConfig_version_tag 8
#define LocalModuleConfig_audio_tag 9
/* Struct field encoding specification for nanopb */
#define LocalConfig_FIELDLIST(X, a) \
@@ -125,7 +129,8 @@ X(a, STATIC, OPTIONAL, MESSAGE, store_forward, 4) \
X(a, STATIC, OPTIONAL, MESSAGE, range_test, 5) \
X(a, STATIC, OPTIONAL, MESSAGE, telemetry, 6) \
X(a, STATIC, OPTIONAL, MESSAGE, canned_message, 7) \
X(a, STATIC, SINGULAR, UINT32, version, 8)
X(a, STATIC, SINGULAR, UINT32, version, 8) \
X(a, STATIC, OPTIONAL, MESSAGE, audio, 9)
#define LocalModuleConfig_CALLBACK NULL
#define LocalModuleConfig_DEFAULT NULL
#define LocalModuleConfig_mqtt_MSGTYPE ModuleConfig_MQTTConfig
@@ -135,6 +140,7 @@ X(a, STATIC, SINGULAR, UINT32, version, 8)
#define LocalModuleConfig_range_test_MSGTYPE ModuleConfig_RangeTestConfig
#define LocalModuleConfig_telemetry_MSGTYPE ModuleConfig_TelemetryConfig
#define LocalModuleConfig_canned_message_MSGTYPE ModuleConfig_CannedMessageConfig
#define LocalModuleConfig_audio_MSGTYPE ModuleConfig_AudioConfig
extern const pb_msgdesc_t LocalConfig_msg;
extern const pb_msgdesc_t LocalModuleConfig_msg;
@@ -144,8 +150,8 @@ extern const pb_msgdesc_t LocalModuleConfig_msg;
#define LocalModuleConfig_fields &LocalModuleConfig_msg
/* Maximum encoded size of messages (where known) */
#define LocalConfig_size 334
#define LocalModuleConfig_size 270
#define LocalConfig_size 361
#define LocalModuleConfig_size 294
#ifdef __cplusplus
} /* extern "C" */

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

@@ -52,6 +52,8 @@ typedef enum _HardwareModel {
HardwareModel_RAK11200 = 13,
/* B&Q Consulting Nano Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:nano */
HardwareModel_NANO_G1 = 14,
/* TODO: REPLACE */
HardwareModel_TLORA_V2_1_1P8 = 15,
/* B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station */
HardwareModel_STATION_G1 = 25,
/* Less common/prototype boards listed here (needs one more byte over the air) */
@@ -243,8 +245,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 +357,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 +430,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)
@@ -504,7 +501,7 @@ typedef PB_BYTES_ARRAY_T(256) MeshPacket_encrypted_t;
typedef struct _MeshPacket {
/* The sending node number.
Note: Our crypto implementation uses this field as well.
See [crypto](/docs/developers/firmware/encryption) for details.
See [crypto](/docs/about/overview/encryption) for details.
FIXME - really should be fixed32 instead, this encoding only hurts the ble link though. */
uint32_t from;
/* The (immediatSee Priority description for more details.y should be fixed32 instead, this encoding only
@@ -532,7 +529,7 @@ typedef struct _MeshPacket {
needs to be unique for a few minutes (long enough to last for the length of
any ACK or the completion of a mesh broadcast flood).
Note: Our crypto implementation uses this id as well.
See [crypto](/docs/developers/firmware/encryption) for details.
See [crypto](/docs/about/overview/encryption) for details.
FIXME - really should be fixed32 instead, this encoding only
hurts the ble link though. */
uint32_t id;
@@ -665,9 +662,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 +734,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 +747,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 +803,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 +849,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 +1008,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 +1032,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 +1047,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 +1060,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

@@ -12,6 +12,9 @@ PB_BIND(ModuleConfig, ModuleConfig, AUTO)
PB_BIND(ModuleConfig_MQTTConfig, ModuleConfig_MQTTConfig, AUTO)
PB_BIND(ModuleConfig_AudioConfig, ModuleConfig_AudioConfig, AUTO)
PB_BIND(ModuleConfig_SerialConfig, ModuleConfig_SerialConfig, AUTO)
@@ -34,3 +37,4 @@ PB_BIND(ModuleConfig_CannedMessageConfig, ModuleConfig_CannedMessageConfig, AUTO

View File

@@ -10,6 +10,18 @@
#endif
/* Enum definitions */
typedef enum _ModuleConfig_AudioConfig_Audio_Baud {
ModuleConfig_AudioConfig_Audio_Baud_CODEC2_DEFAULT = 0,
ModuleConfig_AudioConfig_Audio_Baud_CODEC2_3200 = 1,
ModuleConfig_AudioConfig_Audio_Baud_CODEC2_2400 = 2,
ModuleConfig_AudioConfig_Audio_Baud_CODEC2_1600 = 3,
ModuleConfig_AudioConfig_Audio_Baud_CODEC2_1400 = 4,
ModuleConfig_AudioConfig_Audio_Baud_CODEC2_1300 = 5,
ModuleConfig_AudioConfig_Audio_Baud_CODEC2_1200 = 6,
ModuleConfig_AudioConfig_Audio_Baud_CODEC2_700 = 7,
ModuleConfig_AudioConfig_Audio_Baud_CODEC2_700B = 8
} ModuleConfig_AudioConfig_Audio_Baud;
typedef enum _ModuleConfig_SerialConfig_Serial_Baud {
ModuleConfig_SerialConfig_Serial_Baud_BAUD_DEFAULT = 0,
ModuleConfig_SerialConfig_Serial_Baud_BAUD_110 = 1,
@@ -33,7 +45,8 @@ typedef enum _ModuleConfig_SerialConfig_Serial_Mode {
ModuleConfig_SerialConfig_Serial_Mode_DEFAULT = 0,
ModuleConfig_SerialConfig_Serial_Mode_SIMPLE = 1,
ModuleConfig_SerialConfig_Serial_Mode_PROTO = 2,
ModuleConfig_SerialConfig_Serial_Mode_TEXTMSG = 3
ModuleConfig_SerialConfig_Serial_Mode_TEXTMSG = 3,
ModuleConfig_SerialConfig_Serial_Mode_NMEA = 4
} ModuleConfig_SerialConfig_Serial_Mode;
typedef enum _ModuleConfig_CannedMessageConfig_InputEventChar {
@@ -48,6 +61,14 @@ typedef enum _ModuleConfig_CannedMessageConfig_InputEventChar {
} ModuleConfig_CannedMessageConfig_InputEventChar;
/* Struct definitions */
typedef struct _ModuleConfig_AudioConfig {
bool codec2_enabled;
uint32_t mic_chan;
uint32_t amp_pin;
uint32_t ptt_pin;
ModuleConfig_AudioConfig_Audio_Baud bitrate;
} ModuleConfig_AudioConfig;
typedef struct _ModuleConfig_CannedMessageConfig {
bool rotary1_enabled;
uint32_t inputbroker_pin_a;
@@ -130,18 +151,24 @@ typedef struct _ModuleConfig {
ModuleConfig_TelemetryConfig telemetry;
/* TODO: REPLACE */
ModuleConfig_CannedMessageConfig canned_message;
/* TODO: REPLACE */
ModuleConfig_AudioConfig audio;
} payload_variant;
} ModuleConfig;
/* Helper constants for enums */
#define _ModuleConfig_AudioConfig_Audio_Baud_MIN ModuleConfig_AudioConfig_Audio_Baud_CODEC2_DEFAULT
#define _ModuleConfig_AudioConfig_Audio_Baud_MAX ModuleConfig_AudioConfig_Audio_Baud_CODEC2_700B
#define _ModuleConfig_AudioConfig_Audio_Baud_ARRAYSIZE ((ModuleConfig_AudioConfig_Audio_Baud)(ModuleConfig_AudioConfig_Audio_Baud_CODEC2_700B+1))
#define _ModuleConfig_SerialConfig_Serial_Baud_MIN ModuleConfig_SerialConfig_Serial_Baud_BAUD_DEFAULT
#define _ModuleConfig_SerialConfig_Serial_Baud_MAX ModuleConfig_SerialConfig_Serial_Baud_BAUD_921600
#define _ModuleConfig_SerialConfig_Serial_Baud_ARRAYSIZE ((ModuleConfig_SerialConfig_Serial_Baud)(ModuleConfig_SerialConfig_Serial_Baud_BAUD_921600+1))
#define _ModuleConfig_SerialConfig_Serial_Mode_MIN ModuleConfig_SerialConfig_Serial_Mode_DEFAULT
#define _ModuleConfig_SerialConfig_Serial_Mode_MAX ModuleConfig_SerialConfig_Serial_Mode_TEXTMSG
#define _ModuleConfig_SerialConfig_Serial_Mode_ARRAYSIZE ((ModuleConfig_SerialConfig_Serial_Mode)(ModuleConfig_SerialConfig_Serial_Mode_TEXTMSG+1))
#define _ModuleConfig_SerialConfig_Serial_Mode_MAX ModuleConfig_SerialConfig_Serial_Mode_NMEA
#define _ModuleConfig_SerialConfig_Serial_Mode_ARRAYSIZE ((ModuleConfig_SerialConfig_Serial_Mode)(ModuleConfig_SerialConfig_Serial_Mode_NMEA+1))
#define _ModuleConfig_CannedMessageConfig_InputEventChar_MIN ModuleConfig_CannedMessageConfig_InputEventChar_NONE
#define _ModuleConfig_CannedMessageConfig_InputEventChar_MAX ModuleConfig_CannedMessageConfig_InputEventChar_BACK
@@ -155,6 +182,7 @@ extern "C" {
/* Initializer values for message structs */
#define ModuleConfig_init_default {0, {ModuleConfig_MQTTConfig_init_default}}
#define ModuleConfig_MQTTConfig_init_default {0, "", "", "", 0, 0}
#define ModuleConfig_AudioConfig_init_default {0, 0, 0, 0, _ModuleConfig_AudioConfig_Audio_Baud_MIN}
#define ModuleConfig_SerialConfig_init_default {0, 0, 0, 0, _ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _ModuleConfig_SerialConfig_Serial_Mode_MIN}
#define ModuleConfig_ExternalNotificationConfig_init_default {0, 0, 0, 0, 0, 0}
#define ModuleConfig_StoreForwardConfig_init_default {0, 0, 0, 0, 0}
@@ -163,6 +191,7 @@ extern "C" {
#define ModuleConfig_CannedMessageConfig_init_default {0, 0, 0, 0, _ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _ModuleConfig_CannedMessageConfig_InputEventChar_MIN, 0, 0, "", 0}
#define ModuleConfig_init_zero {0, {ModuleConfig_MQTTConfig_init_zero}}
#define ModuleConfig_MQTTConfig_init_zero {0, "", "", "", 0, 0}
#define ModuleConfig_AudioConfig_init_zero {0, 0, 0, 0, _ModuleConfig_AudioConfig_Audio_Baud_MIN}
#define ModuleConfig_SerialConfig_init_zero {0, 0, 0, 0, _ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _ModuleConfig_SerialConfig_Serial_Mode_MIN}
#define ModuleConfig_ExternalNotificationConfig_init_zero {0, 0, 0, 0, 0, 0}
#define ModuleConfig_StoreForwardConfig_init_zero {0, 0, 0, 0, 0}
@@ -171,6 +200,11 @@ extern "C" {
#define ModuleConfig_CannedMessageConfig_init_zero {0, 0, 0, 0, _ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _ModuleConfig_CannedMessageConfig_InputEventChar_MIN, 0, 0, "", 0}
/* Field tags (for use in manual encoding/decoding) */
#define ModuleConfig_AudioConfig_codec2_enabled_tag 1
#define ModuleConfig_AudioConfig_mic_chan_tag 2
#define ModuleConfig_AudioConfig_amp_pin_tag 3
#define ModuleConfig_AudioConfig_ptt_pin_tag 4
#define ModuleConfig_AudioConfig_bitrate_tag 5
#define ModuleConfig_CannedMessageConfig_rotary1_enabled_tag 1
#define ModuleConfig_CannedMessageConfig_inputbroker_pin_a_tag 2
#define ModuleConfig_CannedMessageConfig_inputbroker_pin_b_tag 3
@@ -221,6 +255,7 @@ extern "C" {
#define ModuleConfig_range_test_tag 5
#define ModuleConfig_telemetry_tag 6
#define ModuleConfig_canned_message_tag 7
#define ModuleConfig_audio_tag 8
/* Struct field encoding specification for nanopb */
#define ModuleConfig_FIELDLIST(X, a) \
@@ -230,7 +265,8 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,external_notification,payloa
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,store_forward,payload_variant.store_forward), 4) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,range_test,payload_variant.range_test), 5) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,telemetry,payload_variant.telemetry), 6) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,canned_message,payload_variant.canned_message), 7)
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,canned_message,payload_variant.canned_message), 7) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,audio,payload_variant.audio), 8)
#define ModuleConfig_CALLBACK NULL
#define ModuleConfig_DEFAULT NULL
#define ModuleConfig_payload_variant_mqtt_MSGTYPE ModuleConfig_MQTTConfig
@@ -240,6 +276,7 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,canned_message,payload_varia
#define ModuleConfig_payload_variant_range_test_MSGTYPE ModuleConfig_RangeTestConfig
#define ModuleConfig_payload_variant_telemetry_MSGTYPE ModuleConfig_TelemetryConfig
#define ModuleConfig_payload_variant_canned_message_MSGTYPE ModuleConfig_CannedMessageConfig
#define ModuleConfig_payload_variant_audio_MSGTYPE ModuleConfig_AudioConfig
#define ModuleConfig_MQTTConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, BOOL, enabled, 1) \
@@ -251,6 +288,15 @@ X(a, STATIC, SINGULAR, BOOL, json_enabled, 6)
#define ModuleConfig_MQTTConfig_CALLBACK NULL
#define ModuleConfig_MQTTConfig_DEFAULT NULL
#define ModuleConfig_AudioConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, BOOL, codec2_enabled, 1) \
X(a, STATIC, SINGULAR, UINT32, mic_chan, 2) \
X(a, STATIC, SINGULAR, UINT32, amp_pin, 3) \
X(a, STATIC, SINGULAR, UINT32, ptt_pin, 4) \
X(a, STATIC, SINGULAR, UENUM, bitrate, 5)
#define ModuleConfig_AudioConfig_CALLBACK NULL
#define ModuleConfig_AudioConfig_DEFAULT NULL
#define ModuleConfig_SerialConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, BOOL, enabled, 1) \
X(a, STATIC, SINGULAR, BOOL, echo, 2) \
@@ -314,6 +360,7 @@ X(a, STATIC, SINGULAR, BOOL, send_bell, 11)
extern const pb_msgdesc_t ModuleConfig_msg;
extern const pb_msgdesc_t ModuleConfig_MQTTConfig_msg;
extern const pb_msgdesc_t ModuleConfig_AudioConfig_msg;
extern const pb_msgdesc_t ModuleConfig_SerialConfig_msg;
extern const pb_msgdesc_t ModuleConfig_ExternalNotificationConfig_msg;
extern const pb_msgdesc_t ModuleConfig_StoreForwardConfig_msg;
@@ -324,6 +371,7 @@ extern const pb_msgdesc_t ModuleConfig_CannedMessageConfig_msg;
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
#define ModuleConfig_fields &ModuleConfig_msg
#define ModuleConfig_MQTTConfig_fields &ModuleConfig_MQTTConfig_msg
#define ModuleConfig_AudioConfig_fields &ModuleConfig_AudioConfig_msg
#define ModuleConfig_SerialConfig_fields &ModuleConfig_SerialConfig_msg
#define ModuleConfig_ExternalNotificationConfig_fields &ModuleConfig_ExternalNotificationConfig_msg
#define ModuleConfig_StoreForwardConfig_fields &ModuleConfig_StoreForwardConfig_msg
@@ -332,6 +380,7 @@ extern const pb_msgdesc_t ModuleConfig_CannedMessageConfig_msg;
#define ModuleConfig_CannedMessageConfig_fields &ModuleConfig_CannedMessageConfig_msg
/* Maximum encoded size of messages (where known) */
#define ModuleConfig_AudioConfig_size 22
#define ModuleConfig_CannedMessageConfig_size 49
#define ModuleConfig_ExternalNotificationConfig_size 20
#define ModuleConfig_MQTTConfig_size 105

View File

@@ -51,6 +51,9 @@ typedef enum _PortNum {
/* Waypoint payloads.
Payload is a [Waypoint](/docs/developers/protobufs/api#waypoint) message */
PortNum_WAYPOINT_APP = 8,
/* Audio Payloads.
Encapsulated codec2 packets. On 2.4 GHZ Bandwidths only for now */
PortNum_AUDIO_APP = 9,
/* Provides a 'ping' service that replies to any packet it receives.
Also serves as a small example module. */
PortNum_REPLY_APP = 32,
@@ -81,7 +84,7 @@ typedef enum _PortNum {
PortNum_SIMULATOR_APP = 69,
/* Private applications should use portnums >= 256.
To simplify initial development and testing you can use "PRIVATE_APP"
in your code without needing to rebuild protobuf files (via [regen-protos.sh](https://github.com/meshtastic/Meshtastic-device/blob/master/bin/regen-protos.sh)) */
in your code without needing to rebuild protobuf files (via [regen-protos.sh](https://github.com/meshtastic/firmware/blob/master/bin/regen-protos.sh)) */
PortNum_PRIVATE_APP = 256,
/* ATAK Forwarder Module https://github.com/paulmandal/atak-forwarder */
PortNum_ATAK_FORWARDER = 257,

View File

@@ -58,8 +58,6 @@ char contentTypes[][2][32] = {{".txt", "text/plain"}, {".html", "text/html"}
{".css", "text/css"}, {".ico", "image/vnd.microsoft.icon"},
{".svg", "image/svg+xml"}, {"", ""}};
// const char *tarURL = "https://www.casler.org/temp/meshtastic-web.tar";
// const char *tarURL = "https://api-production-871d.up.railway.app/mirror/webui";
// const char *certificate = NULL; // change this as needed, leave as is for no TLS check (yolo security)
// Our API to handle messages to and from the radio.
@@ -75,12 +73,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 +98,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 +111,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 +132,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
}
@@ -160,7 +158,7 @@ void handleAPIv1FromRadio(HTTPRequest *req, HTTPResponse *res)
res->setHeader("Content-Type", "application/x-protobuf");
res->setHeader("Access-Control-Allow-Origin", "*");
res->setHeader("Access-Control-Allow-Methods", "GET");
res->setHeader("X-Protobuf-Schema", "https://raw.githubusercontent.com/meshtastic/Meshtastic-protobufs/master/mesh.proto");
res->setHeader("X-Protobuf-Schema", "https://raw.githubusercontent.com/meshtastic/protobufs/master/mesh.proto");
uint8_t txBuf[MAX_STREAM_BUF_SIZE];
uint32_t len = 1;
@@ -204,7 +202,7 @@ void handleAPIv1ToRadio(HTTPRequest *req, HTTPResponse *res)
res->setHeader("Access-Control-Allow-Headers", "Content-Type");
res->setHeader("Access-Control-Allow-Origin", "*");
res->setHeader("Access-Control-Allow-Methods", "PUT, OPTIONS");
res->setHeader("X-Protobuf-Schema", "https://raw.githubusercontent.com/meshtastic/Meshtastic-protobufs/master/mesh.proto");
res->setHeader("X-Protobuf-Schema", "https://raw.githubusercontent.com/meshtastic/protobufs/master/mesh.proto");
if (req->getMethod() == "OPTIONS") {
res->setStatusCode(204); // Success with no content
@@ -251,7 +249,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 +262,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 +302,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 +618,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 +701,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,57 @@ 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);
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);
} else {
// If AP is configured to be hidden hidden
if (config.network.wifi_mode == Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN) {
// 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);
}
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);
WiFi.mode(WIFI_MODE_STA);
WiFi.setHostname(ourHost);
WiFi.onEvent(WiFiEvent);
WiFi.setAutoReconnect(true);
WiFi.setSleep(false);
if (config.network.eth_mode == Config_NetworkConfig_EthMode_STATIC && config.network.ipv4_config.ip != 0) {
WiFi.config(config.network.ipv4_config.ip,
config.network.ipv4_config.gateway,
config.network.ipv4_config.subnet,
config.network.ipv4_config.dns,
config.network.ipv4_config.dns); // Wifi wants two DNS servers... set both to the same value
}
// This is needed to improve performance.
esp_wifi_set_ps(WIFI_PS_NONE); // Disable radio power saving
WiFi.onEvent(
[](WiFiEvent_t event, WiFiEventInfo_t info) {
Serial.print("\nWiFi lost connection. Reason: ");
Serial.println(info.wifi_sta_disconnected.reason);
/*
If we are disconnected from the AP for some reason,
save the error code.
For a reference to the codes:
https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html#wi-fi-reason-code
*/
wifiDisconnectReason = info.wifi_sta_disconnected.reason;
},
WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_DISCONNECTED);
DEBUG_MSG("JOINING WIFI soon: ssid=%s\n", wifiName);
wifiReconnect = new Periodic("WifiConnect", reconnectWiFi);
}
return true;
} else {
@@ -301,8 +231,6 @@ static void WiFiEvent(WiFiEvent_t event)
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
DEBUG_MSG("Disconnected from WiFi access point\n");
// Event 5
needReconnect = true;
break;
case SYSTEM_EVENT_STA_AUTHMODE_CHANGE:
@@ -315,6 +243,7 @@ static void WiFiEvent(WiFiEvent_t event)
break;
case SYSTEM_EVENT_STA_LOST_IP:
DEBUG_MSG("Lost IP address and IP address is reset to 0\n");
needReconnect = true;
break;
case SYSTEM_EVENT_STA_WPS_ER_SUCCESS:
DEBUG_MSG("WiFi Protected Setup (WPS): succeeded in enrollee mode\n");
@@ -330,7 +259,6 @@ static void WiFiEvent(WiFiEvent_t event)
break;
case SYSTEM_EVENT_AP_START:
DEBUG_MSG("WiFi access point started\n");
onNetworkConnected();
break;
case SYSTEM_EVENT_AP_STOP:
@@ -371,13 +299,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)
@@ -306,9 +295,15 @@ void AdminModule::handleSetModuleConfig(const ModuleConfig &c)
moduleConfig.has_canned_message = true;
moduleConfig.canned_message = c.payload_variant.canned_message;
break;
case ModuleConfig_audio_tag:
DEBUG_MSG("Setting module config: Audio\n");
moduleConfig.has_audio = true;
moduleConfig.audio = c.payload_variant.audio;
break;
}
service.reloadConfig(SEGMENT_MODULECONFIG);
reboot(5);
}
void AdminModule::handleSetChannel(const Channel &cc)
@@ -431,6 +426,11 @@ void AdminModule::handleGetModuleConfig(const MeshPacket &req, const uint32_t co
res.get_module_config_response.which_payload_variant = ModuleConfig_canned_message_tag;
res.get_module_config_response.payload_variant.canned_message = moduleConfig.canned_message;
break;
case AdminMessage_ModuleConfigType_AUDIO_CONFIG:
DEBUG_MSG("Getting module config: Audio\n");
res.get_module_config_response.which_payload_variant = ModuleConfig_audio_tag;
res.get_module_config_response.payload_variant.audio = moduleConfig.audio;
break;
}
// NOTE: The phone app needs to know the ls_secsvalue so it can properly expect sleep behavior.
@@ -451,6 +451,10 @@ void AdminModule::handleGetDeviceMetadata(const MeshPacket &req) {
DeviceMetadata deviceMetadata;
strncpy(deviceMetadata.firmware_version, myNodeInfo.firmware_version, 18);
deviceMetadata.device_state_version = DEVICESTATE_CUR_VER;
deviceMetadata.canShutdown = pmu_found || HAS_CPU_SHUTDOWN;
deviceMetadata.hasBluetooth = HAS_BLUETOOTH;
deviceMetadata.hasWifi = HAS_WIFI;
deviceMetadata.hasEthernet = HAS_ETHERNET;
r.get_device_metadata_response = deviceMetadata;
r.which_payload_variant = AdminMessage_get_device_metadata_response_tag;
@@ -468,6 +472,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,18 +3,23 @@
#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>
/*
Documentation:
https://github.com/meshtastic/Meshtastic-device/blob/master/docs/software/modules/ExternalNotificationModule.md
https://github.com/meshtastic/firmware/blob/master/docs/software/modules/ExternalNotificationModule.md
This module supports:
https://github.com/meshtastic/Meshtastic-device/issues/654
https://github.com/meshtastic/firmware/issues/654
Quick reference:
@@ -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
}
// --------
@@ -113,11 +116,6 @@ ExternalNotificationModule::ExternalNotificationModule()
: SinglePortModule("ExternalNotificationModule", PortNum_TEXT_MESSAGE_APP), concurrency::OSThread(
"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.
@@ -130,30 +128,37 @@ ExternalNotificationModule::ExternalNotificationModule()
// moduleConfig.external_notification.alert_bell = 1;
// moduleConfig.external_notification.output_ms = 1000;
// moduleConfig.external_notification.output = 13;
if (moduleConfig.external_notification.alert_message) {
// restrict to the gpio channel for rx
boundChannel = Channels::gpioChannel;
}
if (moduleConfig.external_notification.enabled) {
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 +170,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

@@ -19,6 +19,9 @@
#ifdef ARCH_ESP32
#include "modules/esp32/RangeTestModule.h"
#include "modules/esp32/StoreForwardModule.h"
#ifdef USE_SX1280
#include "modules/esp32/AudioModule.h"
#endif
#endif
#if defined(ARCH_ESP32) || defined(ARCH_NRF52)
#include "modules/ExternalNotificationModule.h"
@@ -60,20 +63,21 @@ void setupModules()
new DeviceTelemetryModule();
new EnvironmentTelemetryModule();
#endif
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(TTGO_T_ECHO)
new SerialModule();
#endif
#ifdef ARCH_ESP32
// Only run on an esp32 based device.
/*
Maintained by MC Hamster (Jm Casler) jm@casler.org
*/
new SerialModule();
#ifdef USE_SX1280
new AudioModule();
#endif
new ExternalNotificationModule();
storeForwardModule = new StoreForwardModule();
new RangeTestModule();
#elif defined(ARCH_NRF52)
new ExternalNotificationModule();
new ExternalNotificationModule();
#endif
// NOTE! This module must be added LAST because it likes to check for replies from other modules and avoid sending extra acks

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -16,6 +16,14 @@ int32_t BME280Sensor::runOnce() {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
status = bme280.begin(nodeTelemetrySensorsMap[sensorType]);
bme280.setSampling( Adafruit_BME280::MODE_FORCED,
Adafruit_BME280::SAMPLING_X1, // Temp. oversampling
Adafruit_BME280::SAMPLING_X1, // Pressure oversampling
Adafruit_BME280::SAMPLING_X1, // Humidity oversampling
Adafruit_BME280::FILTER_OFF,
Adafruit_BME280::STANDBY_MS_1000);
return initI2CSensor();
}
@@ -23,6 +31,7 @@ void BME280Sensor::setup() { }
bool BME280Sensor::getMetrics(Telemetry *measurement) {
DEBUG_MSG("BME280Sensor::getMetrics\n");
bme280.takeForcedMeasurement();
measurement->variant.environment_metrics.temperature = bme280.readTemperature();
measurement->variant.environment_metrics.relative_humidity = bme280.readHumidity();
measurement->variant.environment_metrics.barometric_pressure = bme280.readPressure() / 100.0F;

View File

@@ -14,25 +14,19 @@ int32_t BME680Sensor::runOnce() {
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
status = bme680.begin(nodeTelemetrySensorsMap[sensorType]);
status = bme680.begin(nodeTelemetrySensorsMap[sensorType]);
return initI2CSensor();
}
void BME680Sensor::setup()
{
// Set up oversampling and filter initialization
bme680.setTemperatureOversampling(BME680_OS_8X);
bme680.setHumidityOversampling(BME680_OS_2X);
bme680.setPressureOversampling(BME680_OS_4X);
bme680.setIIRFilterSize(BME680_FILTER_SIZE_3);
bme680.setGasHeater(320, 150); // 320*C for 150 ms
}
void BME680Sensor::setup() { }
bool BME680Sensor::getMetrics(Telemetry *measurement) {
measurement->variant.environment_metrics.temperature = bme680.readTemperature();
measurement->variant.environment_metrics.relative_humidity = bme680.readHumidity();
measurement->variant.environment_metrics.barometric_pressure = bme680.readPressure() / 100.0F;
measurement->variant.environment_metrics.gas_resistance = bme680.readGas() / 1000.0;
bme680.performReading();
measurement->variant.environment_metrics.temperature = bme680.temperature;
measurement->variant.environment_metrics.relative_humidity = bme680.humidity;
measurement->variant.environment_metrics.barometric_pressure = bme680.pressure / 100.0F;
measurement->variant.environment_metrics.gas_resistance = bme680.gas_resistance / 1000.0;
return true;
}

View File

@@ -16,6 +16,13 @@ int32_t BMP280Sensor::runOnce() {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
status = bmp280.begin(nodeTelemetrySensorsMap[sensorType]);
bmp280.setSampling( Adafruit_BMP280::MODE_FORCED,
Adafruit_BMP280::SAMPLING_X1, // Temp. oversampling
Adafruit_BMP280::SAMPLING_X1, // Pressure oversampling
Adafruit_BMP280::FILTER_OFF,
Adafruit_BMP280::STANDBY_MS_1000);
return initI2CSensor();
}
@@ -23,6 +30,7 @@ void BMP280Sensor::setup() { }
bool BMP280Sensor::getMetrics(Telemetry *measurement) {
DEBUG_MSG("BMP280Sensor::getMetrics\n");
bmp280.takeForcedMeasurement();
measurement->variant.environment_metrics.temperature = bmp280.readTemperature();
measurement->variant.environment_metrics.barometric_pressure = bmp280.readPressure() / 100.0F;

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,240 @@
#include "configuration.h"
#include "AudioModule.h"
#include "MeshService.h"
#include "NodeDB.h"
#include "RTC.h"
#include "Router.h"
#include "FSCommon.h"
#include <assert.h>
/*
AudioModule
A interface to send raw codec2 audio data over the mesh network. Based on the example code from the ESP32_codec2 project.
https://github.com/deulis/ESP32_Codec2
Codec 2 is a low-bitrate speech audio codec (speech coding)
that is patent free and open source develop by David Grant Rowe.
http://www.rowetel.com/ and https://github.com/drowe67/codec2
Basic Usage:
1) Enable the module by setting audio.codec2_enabled to 1.
2) Set the pins (audio.mic_pin / audio.amp_pin) for your preferred microphone and amplifier GPIO pins.
On tbeam, recommend to use:
audio.mic_chan 7 (GPIO 35)
audio.amp_pin 25 (GPIO 25)
3) Set audio.timeout to the amount of time to wait before we consider
your voice stream as "done".
4) Set audio.bitrate to the desired codec2 rate (CODEC2_3200, CODEC2_2400, CODEC2_1600, CODEC2_1400, CODEC2_1300, CODEC2_1200, CODEC2_700, CODEC2_700B)
KNOWN PROBLEMS
* Until the module is initilized by the startup sequence, the amp_pin pin is in a floating
state. This may produce a bit of "noise".
* Will not work on NRF and the Linux device targets.
*/
#define AMIC 7
#define AAMP 25
#define PTT_PIN 39
#define AUDIO_MODULE_RX_BUFFER 128
#define AUDIO_MODULE_DATA_MAX Constants_DATA_PAYLOAD_LEN
#define AUDIO_MODULE_MODE 7 // 700B
#define AUDIO_MODULE_ACK 1
#if defined(ARCH_ESP32) && defined(USE_SX1280)
AudioModule *audioModule;
ButterworthFilter hp_filter(240, 8000, ButterworthFilter::ButterworthFilter::Highpass, 1);
//int16_t 1KHz sine test tone
int16_t Sine1KHz[8] = { -21210 , -30000, -21210, 0 , 21210 , 30000 , 21210, 0 };
int Sine1KHz_index = 0;
uint8_t rx_raw_audio_value = 127;
AudioModule::AudioModule() : SinglePortModule("AudioModule", PortNum_AUDIO_APP), concurrency::OSThread("AudioModule") {
audio_fifo.init();
}
void AudioModule::run_codec2()
{
if (state == State::tx)
{
for (int i = 0; i < ADC_BUFFER_SIZE; i++)
speech[i] = (int16_t)hp_filter.Update((float)speech[i]);
codec2_encode(codec2_state, tx_encode_frame + tx_encode_frame_index, speech);
//increment the pointer where the encoded frame must be saved
tx_encode_frame_index += 8;
//If it is the 5th time then we have a ready trasnmission frame
if (tx_encode_frame_index == ENCODE_FRAME_SIZE)
{
tx_encode_frame_index = 0;
//Transmit it
sendPayload();
}
}
if (state == State::rx) //Receiving
{
//Make a cycle to get each codec2 frame from the received frame
for (int i = 0; i < ENCODE_FRAME_SIZE; i += 8)
{
//Decode the codec2 frame
codec2_decode(codec2_state, output_buffer, rx_encode_frame + i);
// Add to the audio buffer the 320 samples resulting of the decode of the codec2 frame.
for (int g = 0; g < ADC_BUFFER_SIZE; g++)
audio_fifo.put(output_buffer[g]);
}
}
state = State::standby;
}
void AudioModule::handleInterrupt()
{
audioModule->onTimer();
}
void AudioModule::onTimer()
{
if (state == State::tx) {
adc_buffer[adc_buffer_index++] = (16 * adc1_get_raw(mic_chan)) - 32768;
//If you want to test with a 1KHz tone, comment the line above and descomment the three lines below
// adc_buffer[adc_buffer_index++] = Sine1KHz[Sine1KHz_index++];
// if (Sine1KHz_index >= 8)
// Sine1KHz_index = 0;
if (adc_buffer_index == ADC_BUFFER_SIZE) {
adc_buffer_index = 0;
memcpy((void*)speech, (void*)adc_buffer, 2 * ADC_BUFFER_SIZE);
audioModule->setIntervalFromNow(0); // process buffer immediately
}
} else if (state == State::rx) {
int16_t v;
//Get a value from audio_fifo and convert it to 0 - 255 to play it in the ADC
//If none value is available the DAC will play the last one that was read, that's
//why the rx_raw_audio_value variable is a global one.
if (audio_fifo.get(&v))
rx_raw_audio_value = (uint8_t)((v + 32768) / 256);
//Play
dacWrite(moduleConfig.audio.amp_pin ? moduleConfig.audio.amp_pin : AAMP, rx_raw_audio_value);
}
}
int32_t AudioModule::runOnce()
{
if (moduleConfig.audio.codec2_enabled) {
if (firstTime) {
DEBUG_MSG("Initializing ADC on Channel %u\n", moduleConfig.audio.mic_chan ? moduleConfig.audio.mic_chan : AMIC);
mic_chan = moduleConfig.audio.mic_chan ? (adc1_channel_t)(int)moduleConfig.audio.mic_chan : (adc1_channel_t)AMIC;
adc1_config_width(ADC_WIDTH_12Bit);
adc1_config_channel_atten(mic_chan, ADC_ATTEN_DB_6);
// Start a timer at 8kHz to sample the ADC and play the audio on the DAC.
uint32_t cpufreq = getCpuFrequencyMhz();
switch (cpufreq){
case 160:
adcTimer = timerBegin(3, 1000, true); // 160 MHz / 1000 = 160KHz
break;
case 240:
adcTimer = timerBegin(3, 1500, true); // 240 MHz / 1500 = 160KHz
break;
case 320:
adcTimer = timerBegin(3, 2000, true); // 320 MHz / 2000 = 160KHz
break;
case 80:
default:
adcTimer = timerBegin(3, 500, true); // 80 MHz / 500 = 160KHz
break;
}
timerAttachInterrupt(adcTimer, &AudioModule::handleInterrupt, true);
timerAlarmWrite(adcTimer, 20, true); // Interrupts when counter == 20, 8.000 times a second
timerAlarmEnable(adcTimer);
DEBUG_MSG("Initializing DAC on Pin %u\n", moduleConfig.audio.amp_pin ? moduleConfig.audio.amp_pin : AAMP);
DEBUG_MSG("Initializing PTT on Pin %u\n", moduleConfig.audio.ptt_pin ? moduleConfig.audio.ptt_pin : PTT_PIN);
// Configure PTT input
pinMode(moduleConfig.audio.ptt_pin ? moduleConfig.audio.ptt_pin : PTT_PIN, INPUT_PULLUP);
state = State::rx;
DEBUG_MSG("Setting up codec2 in mode %u\n", moduleConfig.audio.bitrate ? moduleConfig.audio.bitrate : AUDIO_MODULE_MODE);
codec2_state = codec2_create(moduleConfig.audio.bitrate ? moduleConfig.audio.bitrate : AUDIO_MODULE_MODE);
codec2_set_lpc_post_filter(codec2_state, 1, 0, 0.8, 0.2);
firstTime = 0;
} else {
// Check if we have a PTT press
if (digitalRead(moduleConfig.audio.ptt_pin ? moduleConfig.audio.ptt_pin : PTT_PIN) == LOW) {
// PTT pressed, recording
state = State::tx;
}
if (state != State::standby) {
run_codec2();
}
}
return 100;
} else {
DEBUG_MSG("Audio Module Disabled\n");
return INT32_MAX;
}
}
MeshPacket *AudioModule::allocReply()
{
auto reply = allocDataPacket(); // Allocate a packet for sending
return reply;
}
void AudioModule::sendPayload(NodeNum dest, bool wantReplies)
{
MeshPacket *p = allocReply();
p->to = dest;
p->decoded.want_response = wantReplies;
p->want_ack = AUDIO_MODULE_ACK;
p->decoded.payload.size = ENCODE_FRAME_SIZE;
memcpy(p->decoded.payload.bytes, tx_encode_frame, p->decoded.payload.size);
service.sendToMesh(p);
}
ProcessMessage AudioModule::handleReceived(const MeshPacket &mp)
{
if (moduleConfig.audio.codec2_enabled) {
auto &p = mp.decoded;
if (getFrom(&mp) != nodeDB.getNodeNum()) {
if (p.payload.size == ENCODE_FRAME_SIZE) {
memcpy(rx_encode_frame, p.payload.bytes, p.payload.size);
state = State::rx;
audioModule->setIntervalFromNow(0);
run_codec2();
} else {
DEBUG_MSG("Invalid payload size %u != %u\n", p.payload.size, ENCODE_FRAME_SIZE);
}
}
}
return ProcessMessage::CONTINUE;
}
#endif

View File

@@ -0,0 +1,68 @@
#pragma once
#include "SinglePortModule.h"
#include "concurrency/OSThread.h"
#include "configuration.h"
#include "NodeDB.h"
#include <Arduino.h>
#include <driver/adc.h>
#include <functional>
#if defined(ARCH_ESP32) && defined(USE_SX1280)
#include <codec2.h>
#include <ButterworthFilter.h>
#include <FastAudioFIFO.h>
#endif
#define ADC_BUFFER_SIZE 320 // 40ms of voice in 8KHz sampling frequency
#define ENCODE_FRAME_SIZE 40 // 5 codec2 frames of 8 bytes each
class AudioModule : public SinglePortModule, private concurrency::OSThread
{
#if defined(ARCH_ESP32) && defined(USE_SX1280)
bool firstTime = 1;
hw_timer_t* adcTimer = NULL;
uint16_t adc_buffer[ADC_BUFFER_SIZE] = {};
int16_t speech[ADC_BUFFER_SIZE] = {};
int16_t output_buffer[ADC_BUFFER_SIZE] = {};
unsigned char rx_encode_frame[ENCODE_FRAME_SIZE] = {};
unsigned char tx_encode_frame[ENCODE_FRAME_SIZE] = {};
int tx_encode_frame_index = 0;
FastAudioFIFO audio_fifo;
uint16_t adc_buffer_index = 0;
adc1_channel_t mic_chan = (adc1_channel_t)0;
struct CODEC2* codec2_state = NULL;
enum State
{
standby, rx, tx
};
volatile State state = State::tx;
public:
AudioModule();
/**
* Send our payload into the mesh
*/
void sendPayload(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false);
protected:
virtual int32_t runOnce() override;
static void handleInterrupt();
void onTimer();
void run_codec2();
virtual MeshPacket *allocReply() override;
/** Called to handle a particular incoming message
* @return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered for it
*/
virtual ProcessMessage handleReceived(const MeshPacket &mp) override;
#endif
};
extern AudioModule *audioModule;

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,51 +39,55 @@ 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 {
if (strcmp(e.gateway_id, owner.id) == 0)
DEBUG_MSG("Ignoring downlink message we originally sent.\n");
else {
if (e.packet) {
DEBUG_MSG("Received MQTT topic %s, len=%u\n", topic, length);
MeshPacket *p = packetPool.allocCopy(*e.packet);
if (!pb_decode_from_bytes(payload, length, ServiceEnvelope_fields, &e)) {
DEBUG_MSG("Invalid MQTT service envelope, topic %s, len %u!\n", topic, length);
return;
}else {
if (strcmp(e.gateway_id, owner.id) == 0)
DEBUG_MSG("Ignoring downlink message we originally sent.\n");
else {
if (e.packet) {
DEBUG_MSG("Received MQTT topic %s, len=%u\n", topic, length);
MeshPacket *p = packetPool.allocCopy(*e.packet);
// ignore messages sent by us or if we don't have the channel key
if (router && p->from != nodeDB.getNodeNum() && perhapsDecode(p))
router->enqueueReceivedMessage(p);
else
packetPool.release(p);
// ignore messages sent by us or if we don't have the channel key
if (router && p->from != nodeDB.getNodeNum() && perhapsDecode(p))
router->enqueueReceivedMessage(p);
else
packetPool.release(p);
}
}
}
// make sure to free both strings and the MeshPacket (passing in NULL is acceptable)
free(e.channel_id);
free(e.gateway_id);
@@ -103,6 +110,11 @@ MQTT::MQTT() : concurrency::OSThread("mqtt"), pubSub(mqttClient)
// preflightSleepObserver.observe(&preflightSleep);
}
bool MQTT::connected()
{
return pubSub.connected();
}
void MQTT::reconnect()
{
if (wantsLink()) {
@@ -187,7 +199,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 +261,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 +269,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 +297,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 +362,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 +387,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 +414,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();

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