mirror of
https://github.com/meshtastic/firmware.git
synced 2026-01-08 19:07:26 +00:00
Compare commits
108 Commits
v1.2.50.41
...
v1.2.52.b6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b63802cef3 | ||
|
|
f9ff06b296 | ||
|
|
ad038b07b6 | ||
|
|
2e4b777625 | ||
|
|
a8f1115c05 | ||
|
|
f26bb6467e | ||
|
|
c1ee1265ab | ||
|
|
ad31d558a1 | ||
|
|
1b81b155d6 | ||
|
|
4a036db612 | ||
|
|
2e0cd7ce4a | ||
|
|
4ddc113ed6 | ||
|
|
47935aab98 | ||
|
|
0a43be6f8c | ||
|
|
053a00ec6c | ||
|
|
5392a83e33 | ||
|
|
1adca4e992 | ||
|
|
1e247f154e | ||
|
|
f302166832 | ||
|
|
51743f751a | ||
|
|
b22cc1a964 | ||
|
|
bd3688d21d | ||
|
|
465ff3dd25 | ||
|
|
2ee1155c78 | ||
|
|
6506d54859 | ||
|
|
6843ffe452 | ||
|
|
1fe4b95fe5 | ||
|
|
398a5baa90 | ||
|
|
fcd3170a0f | ||
|
|
95f2d0c933 | ||
|
|
e2d1cce1bb | ||
|
|
01f1b33eec | ||
|
|
94246a1fbc | ||
|
|
abae99f577 | ||
|
|
f221bc6275 | ||
|
|
706d6e2671 | ||
|
|
2857fafa81 | ||
|
|
17dfb7d152 | ||
|
|
dff219a037 | ||
|
|
1c63d2d334 | ||
|
|
b6eb927ad2 | ||
|
|
9d8a1b3522 | ||
|
|
9bc9d37596 | ||
|
|
76d0ad2907 | ||
|
|
3a17822893 | ||
|
|
da7ca98f44 | ||
|
|
841bc97a47 | ||
|
|
dbdbe75e9f | ||
|
|
d5fc905402 | ||
|
|
c366d81510 | ||
|
|
e9f01de051 | ||
|
|
f9905ea416 | ||
|
|
a8d10329f8 | ||
|
|
1157419e05 | ||
|
|
12f1fda934 | ||
|
|
cb0073f6fa | ||
|
|
da5bc9d9d9 | ||
|
|
38baebe48f | ||
|
|
97ad7a1825 | ||
|
|
1f9b1e2828 | ||
|
|
796d05e89e | ||
|
|
063d7a7d81 | ||
|
|
6d0368b13d | ||
|
|
b2011a1889 | ||
|
|
893472e36a | ||
|
|
4d82a0146b | ||
|
|
8569595249 | ||
|
|
88281dbbf1 | ||
|
|
dd3e8af4c0 | ||
|
|
a0d3d1dc89 | ||
|
|
9a87ec7353 | ||
|
|
3857dd7e52 | ||
|
|
690cb0c77a | ||
|
|
5d4f039b3e | ||
|
|
676e840b5b | ||
|
|
c00c2744bf | ||
|
|
83293a5f4d | ||
|
|
0812094f35 | ||
|
|
7dfe596bcb | ||
|
|
749d127281 | ||
|
|
dd464896ae | ||
|
|
00ff013799 | ||
|
|
415ded1f4d | ||
|
|
924069f9ad | ||
|
|
ad784532b7 | ||
|
|
de1d5d61ff | ||
|
|
af8f70e9ae | ||
|
|
c135a59787 | ||
|
|
333b195804 | ||
|
|
40f1a7bcaf | ||
|
|
432854ce31 | ||
|
|
6e706e0585 | ||
|
|
4ca8846c2f | ||
|
|
69e1985eda | ||
|
|
475348489e | ||
|
|
c8aec324f5 | ||
|
|
90f5fade84 | ||
|
|
df75182bcf | ||
|
|
6cb4900e0c | ||
|
|
8bbdfe4538 | ||
|
|
f53fdf1628 | ||
|
|
a16dcbe9d0 | ||
|
|
20497335c2 | ||
|
|
e24a2116d8 | ||
|
|
9c7121df3e | ||
|
|
c531ea8601 | ||
|
|
0a4659b605 | ||
|
|
654558abcd |
24
.github/workflows/update_protobufs.yml
vendored
Normal file
24
.github/workflows/update_protobufs.yml
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
name: "Update protobufs"
|
||||||
|
on: workflow_dispatch
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
update-protobufs:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
submodules: true
|
||||||
|
|
||||||
|
- name: Update Submodule
|
||||||
|
run: |
|
||||||
|
git pull --recurse-submodules
|
||||||
|
git submodule update --remote --recursive
|
||||||
|
- name: Commit update
|
||||||
|
run: |
|
||||||
|
git config --global user.name 'github-actions'
|
||||||
|
git config --global user.email 'bot@noreply.github.com'
|
||||||
|
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}
|
||||||
|
git add proto
|
||||||
|
git commit -m "Update protobuf submodule" && git push || echo "No changes to commit"
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -23,3 +23,6 @@ flash.uf2
|
|||||||
cmake-build*
|
cmake-build*
|
||||||
__pycache__
|
__pycache__
|
||||||
|
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|||||||
Binary file not shown.
@@ -1,11 +1,11 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
VERSION=`bin/buildinfo.py long`
|
VERSION=`bin/buildinfo.py long`
|
||||||
SHORT_VERSION=`bin/buildinfo.py short`
|
SHORT_VERSION=`bin/buildinfo.py short`
|
||||||
|
|
||||||
BOARDS_ESP32="tlora-v2 tlora-v1 tlora_v1_3 tlora-v2-1-1.6 tbeam heltec-v2.0 heltec-v2.1 tbeam0.7 meshtastic-diy-v1"
|
BOARDS_ESP32="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"
|
||||||
#BOARDS_ESP32=tbeam
|
#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
|
# FIXME note nrf52840dk build is for some reason only generating a BIN file but not a HEX file nrf52840dk-geeksville is fine
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
arm-none-eabi-readelf -s -e .pio/build/nrf52dk/firmware.elf | head -80
|
arm-none-eabi-readelf -s -e .pio/build/nrf52dk/firmware.elf | head -80
|
||||||
|
|
||||||
nm -CSr --size-sort .pio/build/nrf52dk/firmware.elf | grep '^200'
|
nm -CSr --size-sort .pio/build/nrf52dk/firmware.elf | grep '^200'
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/python2
|
#!/usr/bin/env python2
|
||||||
|
|
||||||
# This is a layout for 4MB of flash
|
# This is a layout for 4MB of flash
|
||||||
# Name, Type, SubType, Offset, Size, Flags
|
# Name, Type, SubType, Offset, Size, Flags
|
||||||
@@ -38,4 +38,4 @@ app0, app, ota_0, , 0x{app:x},
|
|||||||
app1, app, ota_1, , 0x{app:x},
|
app1, app, ota_1, , 0x{app:x},
|
||||||
spiffs, data, spiffs, , 0x{spi:x} """.format(**locals())
|
spiffs, data, spiffs, , 0x{spi:x} """.format(**locals())
|
||||||
|
|
||||||
print(table)
|
print(table)
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# You probably don't want to use this script, it programs a custom bootloader build onto a nrf52 board
|
# You probably don't want to use this script, it programs a custom bootloader build onto a nrf52 board
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# You probably don't want to use this script, it programs a custom bootloader build onto a nrf52 board
|
# You probably don't want to use this script, it programs a custom bootloader build onto a nrf52 board
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
mosquitto_sub -h mqtt.meshtastic.org -v -t \$SYS/\# -t msh/+/stat/\# -t msh/+/json/\#
|
mosquitto_sub -h mqtt.meshtastic.org -v -t \$SYS/\# -t msh/+/stat/\# -t msh/+/json/\#
|
||||||
# mosquitto_sub -h test.mosquitto.org -v -t mesh/\# -F "%j"
|
# mosquitto_sub -h test.mosquitto.org -v -t mesh/\# -F "%j"
|
||||||
|
|||||||
@@ -1 +1,3 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
mosquitto_pub -h mqtt.meshtastic.org -u meshdev -P large4cats -t msh/1/stat/FakeNode -m online -d
|
mosquitto_pub -h mqtt.meshtastic.org -u meshdev -P large4cats -t msh/1/stat/FakeNode -m online -d
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
pio run --environment native
|
pio run --environment native
|
||||||
gdbserver --once localhost:2345 .pio/build/native/program "$@"
|
gdbserver --once localhost:2345 .pio/build/native/program "$@"
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
pio run --environment native
|
pio run --environment native
|
||||||
.pio/build/native/program "$@"
|
.pio/build/native/program "$@"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# JLinkRTTViewer
|
# JLinkRTTViewer
|
||||||
JLinkRTTClient
|
JLinkRTTClient
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
JLinkGDBServerCLExe -if SWD -select USB -port 2331 -device NRF52832_XXAA
|
JLinkGDBServerCLExe -if SWD -select USB -port 2331 -device NRF52832_XXAA
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
JLinkGDBServerCLExe -if SWD -select USB -port 2331 -device NRF52833_XXAA
|
JLinkGDBServerCLExe -if SWD -select USB -port 2331 -device NRF52833_XXAA
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
JLinkGDBServerCLExe -if SWD -select USB -port 2331 -device NRF52840_XXAA -SuppressInfoUpdateFW -DisableAutoUpdateFW -rtos GDBServer/RTOSPlugin_FreeRTOS
|
JLinkGDBServerCLExe -if SWD -select USB -port 2331 -device NRF52840_XXAA -SuppressInfoUpdateFW -DisableAutoUpdateFW -rtos GDBServer/RTOSPlugin_FreeRTOS
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
esptool.py --baud 921600 write_flash 0x10000 release/archive/old/firmware-tbeam-EU865-1.0.0.bin
|
esptool.py --baud 921600 write_flash 0x10000 release/archive/old/firmware-tbeam-EU865-1.0.0.bin
|
||||||
echo "Erasing the otadata partition, which will turn off flash flippy-flop and force the first image to be used"
|
echo "Erasing the otadata partition, which will turn off flash flippy-flop and force the first image to be used"
|
||||||
esptool.py --baud 921600 erase_region 0xe000 0x2000
|
esptool.py --baud 921600 erase_region 0xe000 0x2000
|
||||||
|
|||||||
@@ -1 +1,3 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
esptool.py --baud 921600 write_flash 0x10000 release/archive/old/firmware-tbeam-1.1.50.bin
|
esptool.py --baud 921600 write_flash 0x10000 release/archive/old/firmware-tbeam-1.1.50.bin
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
echo "This script is only for developers who are publishing new builds on github. Most users don't need it"
|
echo "This script is only for developers who are publishing new builds on github. Most users don't need it"
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# You probably don't need this - it is a basic test of the serial flash on the TTGO eink board
|
# You probably don't need this - it is a basic test of the serial flash on the TTGO eink board
|
||||||
|
|
||||||
nrfjprog --qspiini nrf52/ttgo_eink_qpsi.ini --qspieraseall
|
nrfjprog --qspiini nrf52/ttgo_eink_qpsi.ini --qspieraseall
|
||||||
|
|||||||
@@ -1 +1,3 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
esptool.py --baud 921600 read_flash 0x1000 0xf000 system-info.img
|
esptool.py --baud 921600 read_flash 0x1000 0xf000 system-info.img
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
@@ -12,4 +12,4 @@ cd proto
|
|||||||
|
|
||||||
#echo "Regenerating protobuf documentation - if you see an error message"
|
#echo "Regenerating protobuf documentation - if you see an error message"
|
||||||
#echo "you can ignore it unless doing a new protobuf release to github."
|
#echo "you can ignore it unless doing a new protobuf release to github."
|
||||||
#bin/regen-docs.sh
|
#bin/regen-docs.sh
|
||||||
|
|||||||
@@ -1 +1,3 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
pio run --upload-port /dev/ttyUSB0 -t upload -t monitor
|
pio run --upload-port /dev/ttyUSB0 -t upload -t monitor
|
||||||
|
|||||||
@@ -1 +1,3 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
pio run --upload-port /dev/ttyUSB1 -t upload -t monitor
|
pio run --upload-port /dev/ttyUSB1 -t upload -t monitor
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
echo uploading to usb1
|
echo uploading to usb1
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
TARG=tbeam
|
TARG=tbeam
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# /home/kevinh/.platformio/packages/tool-openocd-esp32/bin/openocd -s /home/kevinh/.platformio/packages/tool-openocd-esp32 -c gdb_port pipe; tcl_port disabled; telnet_port disabled -s /home/kevinh/.platformio/packages/tool-openocd-esp32/share/openocd/scripts -f interface/jlink.cfg -f board/esp-wroom-32.cfg
|
# /home/kevinh/.platformio/packages/tool-openocd-esp32/bin/openocd -s /home/kevinh/.platformio/packages/tool-openocd-esp32 -c gdb_port pipe; tcl_port disabled; telnet_port disabled -s /home/kevinh/.platformio/packages/tool-openocd-esp32/share/openocd/scripts -f interface/jlink.cfg -f board/esp-wroom-32.cfg
|
||||||
/home/kevinh/.platformio/packages/tool-openocd-esp32/bin/openocd -s /home/kevinh/.platformio/packages/tool-openocd-esp32 -s /home/kevinh/.platformio/packages/tool-openocd-esp32/share/openocd/scripts -f interface/jlink.cfg -f ./lora32-openocd.cfg
|
/home/kevinh/.platformio/packages/tool-openocd-esp32/bin/openocd -s /home/kevinh/.platformio/packages/tool-openocd-esp32 -s /home/kevinh/.platformio/packages/tool-openocd-esp32/share/openocd/scripts -f interface/jlink.cfg -f ./lora32-openocd.cfg
|
||||||
|
|||||||
@@ -1 +1,3 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
pio device monitor -b 921600
|
pio device monitor -b 921600
|
||||||
|
|||||||
@@ -1 +1,3 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
pio device monitor -p /dev/ttyUSB1 -b 921600
|
pio device monitor -p /dev/ttyUSB1 -b 921600
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
echo "Starting simulator"
|
echo "Starting simulator"
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
echo "building for t-echo"
|
echo "building for t-echo"
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
echo "Converting to uf2 for NRF52 Adafruit bootloader"
|
echo "Converting to uf2 for NRF52 Adafruit bootloader"
|
||||||
|
|||||||
@@ -1 +1,3 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
pio run --upload-port /dev/ttyUSB1 -t upload
|
pio run --upload-port /dev/ttyUSB1 -t upload
|
||||||
|
|||||||
@@ -1,2 +1,4 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
echo using amap tool to display memory map
|
echo using amap tool to display memory map
|
||||||
amap .pio/build/output.map
|
amap .pio/build/output.map
|
||||||
|
|||||||
@@ -12,6 +12,8 @@
|
|||||||
default_envs = tbeam
|
default_envs = tbeam
|
||||||
;default_envs = tbeam0.7
|
;default_envs = tbeam0.7
|
||||||
;default_envs = heltec-v2.0
|
;default_envs = heltec-v2.0
|
||||||
|
;default_envs = heltec-v1
|
||||||
|
;default_envs = tlora-v1
|
||||||
;default_envs = tlora-v1
|
;default_envs = tlora-v1
|
||||||
;default_envs = tlora_v1_3
|
;default_envs = tlora_v1_3
|
||||||
;default_envs = tlora-v2
|
;default_envs = tlora-v2
|
||||||
@@ -102,9 +104,13 @@ src_filter =
|
|||||||
${arduino_base.src_filter} -<nrf52/>
|
${arduino_base.src_filter} -<nrf52/>
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
debug_init_break = tbreak setup
|
debug_init_break = tbreak setup
|
||||||
|
|
||||||
|
# Remove -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL for low level BLE logging.
|
||||||
|
# See library directory for BLE logging possible values: .pio/libdeps/tbeam/NimBLE-Arduino/src/log_common/log_common.h
|
||||||
|
# This overrides the BLE logging default of LOG_LEVEL_INFO (1) from: .pio/libdeps/tbeam/NimBLE-Arduino/src/esp_nimble_cfg.h
|
||||||
build_flags =
|
build_flags =
|
||||||
${arduino_base.build_flags} -Wall -Wextra -Isrc/esp32 -Isrc/esp32-mfix-esp32-psram-cache-issue -lnimble -std=c++11
|
${arduino_base.build_flags} -Wall -Wextra -Isrc/esp32 -Isrc/esp32-mfix-esp32-psram-cache-issue -lnimble -std=c++11
|
||||||
-DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
|
-DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL
|
||||||
-DAXP_DEBUG_PORT=Serial
|
-DAXP_DEBUG_PORT=Serial
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${arduino_base.lib_deps}
|
${arduino_base.lib_deps}
|
||||||
@@ -113,7 +119,10 @@ lib_deps =
|
|||||||
adafruit/Adafruit Unified Sensor@^1.1.4
|
adafruit/Adafruit Unified Sensor@^1.1.4
|
||||||
paulstoffregen/OneWire@^2.3.5
|
paulstoffregen/OneWire@^2.3.5
|
||||||
robtillaart/DS18B20@^0.1.11
|
robtillaart/DS18B20@^0.1.11
|
||||||
h2zero/NimBLE-Arduino@1.3.1
|
h2zero/NimBLE-Arduino@1.3.4
|
||||||
|
tobozo/ESP32-targz@^1.1.4
|
||||||
|
arduino-libraries/NTPClient#531eff39d9fbc831f3d03f706a161739203fbe2a
|
||||||
|
|
||||||
# Hmm - this doesn't work yet
|
# Hmm - this doesn't work yet
|
||||||
# board_build.ldscript = linker/esp32.extram.bss.ld
|
# board_build.ldscript = linker/esp32.extram.bss.ld
|
||||||
lib_ignore =
|
lib_ignore =
|
||||||
@@ -158,6 +167,13 @@ board = ttgo-t-beam
|
|||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags} -D TBEAM_V07
|
${esp32_base.build_flags} -D TBEAM_V07
|
||||||
|
|
||||||
|
[env:heltec-v1]
|
||||||
|
;build_type = debug ; to make it possible to step through our jtag debugger
|
||||||
|
extends = esp32_base
|
||||||
|
board = heltec_wifi_lora_32
|
||||||
|
build_flags =
|
||||||
|
${esp32_base.build_flags} -D HELTEC_V1
|
||||||
|
|
||||||
[env:heltec-v2.0]
|
[env:heltec-v2.0]
|
||||||
;build_type = debug ; to make it possible to step through our jtag debugger
|
;build_type = debug ; to make it possible to step through our jtag debugger
|
||||||
extends = esp32_base
|
extends = esp32_base
|
||||||
|
|||||||
2
proto
2
proto
Submodule proto updated: 1d3b4806ab...18fc4cdb52
@@ -1,8 +1,8 @@
|
|||||||
#include "configuration.h"
|
|
||||||
#include "PowerFSM.h"
|
#include "PowerFSM.h"
|
||||||
#include "GPS.h"
|
#include "GPS.h"
|
||||||
#include "MeshService.h"
|
#include "MeshService.h"
|
||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
|
#include "configuration.h"
|
||||||
#include "graphics/Screen.h"
|
#include "graphics/Screen.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
@@ -15,7 +15,7 @@ static bool isPowered()
|
|||||||
if (radioConfig.preferences.is_always_powered) {
|
if (radioConfig.preferences.is_always_powered) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isRouter = radioConfig.preferences.is_router;
|
bool isRouter = radioConfig.preferences.is_router;
|
||||||
|
|
||||||
// If we are not a router and we already have AC power go to POWER state after init, otherwise go to ON
|
// If we are not a router and we already have AC power go to POWER state after init, otherwise go to ON
|
||||||
@@ -221,7 +221,8 @@ static void screenPress()
|
|||||||
screen->onPress();
|
screen->onPress();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bootEnter() {
|
static void bootEnter()
|
||||||
|
{
|
||||||
DEBUG_MSG("Enter state: BOOT\n");
|
DEBUG_MSG("Enter state: BOOT\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,8 +249,10 @@ void PowerFSM_setup()
|
|||||||
// if we are a router node, we go to NB (no need for bluetooth) otherwise we go to DARK (so we can send message to phone)
|
// if we are a router node, we go to NB (no need for bluetooth) otherwise we go to DARK (so we can send message to phone)
|
||||||
powerFSM.add_transition(&stateLS, isRouter ? &stateNB : &stateDARK, EVENT_WAKE_TIMER, NULL, "Wake timer");
|
powerFSM.add_transition(&stateLS, isRouter ? &stateNB : &stateDARK, EVENT_WAKE_TIMER, NULL, "Wake timer");
|
||||||
|
|
||||||
// We need this transition, because we might not transition if we were waiting to enter light-sleep, because when we wake from light sleep we _always_ transition to NB or dark and
|
// We need this transition, because we might not transition if we were waiting to enter light-sleep, because when we wake from
|
||||||
powerFSM.add_transition(&stateLS, isRouter ? &stateNB : &stateDARK, EVENT_PACKET_FOR_PHONE, NULL, "Received packet, exiting light sleep");
|
// light sleep we _always_ transition to NB or dark and
|
||||||
|
powerFSM.add_transition(&stateLS, isRouter ? &stateNB : &stateDARK, EVENT_PACKET_FOR_PHONE, NULL,
|
||||||
|
"Received packet, exiting light sleep");
|
||||||
powerFSM.add_transition(&stateNB, &stateNB, EVENT_PACKET_FOR_PHONE, NULL, "Received packet, resetting win wake");
|
powerFSM.add_transition(&stateNB, &stateNB, EVENT_PACKET_FOR_PHONE, NULL, "Received packet, resetting win wake");
|
||||||
|
|
||||||
// Handle press events - note: we ignore button presses when in API mode
|
// Handle press events - note: we ignore button presses when in API mode
|
||||||
@@ -334,15 +337,23 @@ void PowerFSM_setup()
|
|||||||
#ifndef NRF52_SERIES
|
#ifndef NRF52_SERIES
|
||||||
// We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally)
|
// We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally)
|
||||||
|
|
||||||
// I don't think this transition is correct, turning off for now - @geeksville
|
// See: https://github.com/meshtastic/Meshtastic-device/issues/1071
|
||||||
// powerFSM.add_timed_transition(&stateDARK, &stateNB, getPref_phone_timeout_secs() * 1000, NULL, "Phone timeout");
|
if (isRouter || radioConfig.preferences.is_power_saving) {
|
||||||
|
|
||||||
|
// I don't think this transition is correct, turning off for now - @geeksville
|
||||||
|
// powerFSM.add_timed_transition(&stateDARK, &stateNB, getPref_phone_timeout_secs() * 1000, NULL, "Phone timeout");
|
||||||
|
powerFSM.add_timed_transition(&stateNB, &stateLS, getPref_min_wake_secs() * 1000, NULL, "Min wake timeout");
|
||||||
|
powerFSM.add_timed_transition(&stateDARK, &stateLS, getPref_wait_bluetooth_secs() * 1000, NULL, "Bluetooth timeout");
|
||||||
|
meshSds = getPref_mesh_sds_timeout_secs();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
meshSds = UINT32_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
powerFSM.add_timed_transition(&stateNB, &stateLS, getPref_min_wake_secs() * 1000, NULL, "Min wake timeout");
|
|
||||||
powerFSM.add_timed_transition(&stateDARK, &stateLS, getPref_wait_bluetooth_secs() * 1000, NULL, "Bluetooth timeout");
|
|
||||||
meshSds = getPref_mesh_sds_timeout_secs();
|
|
||||||
#else
|
#else
|
||||||
lowPowerState = &stateDARK;
|
lowPowerState = &stateDARK;
|
||||||
meshSds = UINT32_MAX; //Workaround for now: Don't go into deep sleep on the RAK4631
|
meshSds = UINT32_MAX; // Workaround for now: Don't go into deep sleep on the RAK4631
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (meshSds != UINT32_MAX)
|
if (meshSds != UINT32_MAX)
|
||||||
|
|||||||
@@ -84,6 +84,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#define BUTTON_PIN_ALT PIN_BUTTON2
|
#define BUTTON_PIN_ALT PIN_BUTTON2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef PIN_BUTTON_TOUCH
|
||||||
|
#define BUTTON_PIN_TOUCH PIN_BUTTON_TOUCH
|
||||||
|
#endif
|
||||||
|
|
||||||
// FIXME, use variant.h defs for all of this!!! (even on the ESP32 targets)
|
// FIXME, use variant.h defs for all of this!!! (even on the ESP32 targets)
|
||||||
#elif defined(CubeCell_BoardPlus)
|
#elif defined(CubeCell_BoardPlus)
|
||||||
|
|
||||||
@@ -244,6 +248,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
|
|
||||||
#define BUTTON_PIN 39 // The middle button GPIO on the T-Beam
|
#define BUTTON_PIN 39 // The middle button GPIO on the T-Beam
|
||||||
#define EXT_NOTIFY_OUT 12 // Overridden default pin to use for Ext Notify Plugin (#975).
|
#define EXT_NOTIFY_OUT 12 // Overridden default pin to use for Ext Notify Plugin (#975).
|
||||||
|
#define LED_PIN 2 // add status LED (compatible with core-pcb and DIY targets)
|
||||||
|
|
||||||
#define LORA_DIO0 26 // a No connect on the SX1262/SX1268 module
|
#define LORA_DIO0 26 // a No connect on the SX1262/SX1268 module
|
||||||
#define LORA_RESET 23 // RST for SX1276, and for SX1262/SX1268
|
#define LORA_RESET 23 // RST for SX1276, and for SX1262/SX1268
|
||||||
@@ -323,6 +328,41 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#elif defined(ARDUINO_HELTEC_WIFI_LORA_32)
|
||||||
|
|
||||||
|
// the default ESP32 Pin of 15 is the Oled SCL, set to 36 and 37 and works fine.
|
||||||
|
// Tested on Neo6m module.
|
||||||
|
#undef GPS_RX_PIN
|
||||||
|
#undef GPS_TX_PIN
|
||||||
|
#define GPS_RX_PIN 36
|
||||||
|
#define GPS_TX_PIN 37
|
||||||
|
|
||||||
|
#ifndef USE_JTAG // gpio15 is TDO for JTAG, so no I2C on this board while doing jtag
|
||||||
|
#define I2C_SDA 4 // I2C pins for this board
|
||||||
|
#define I2C_SCL 15
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define RESET_OLED 16 // If defined, this pin will be used to reset the display controller
|
||||||
|
|
||||||
|
#define LED_PIN 25 // If defined we will blink this LED
|
||||||
|
#define BUTTON_PIN 0 // If defined, this will be used for user button presses
|
||||||
|
|
||||||
|
#define USE_RF95
|
||||||
|
#define LORA_DIO0 26 // a No connect on the SX1262 module
|
||||||
|
#ifndef USE_JTAG
|
||||||
|
#define LORA_RESET 14
|
||||||
|
#endif
|
||||||
|
#define LORA_DIO1 33 // Not really used
|
||||||
|
#define LORA_DIO2 32 // Not really used
|
||||||
|
|
||||||
|
// ratio of voltage divider = 3.20 (R1=100k, R2=220k)
|
||||||
|
#define ADC_MULTIPLIER 3.2
|
||||||
|
|
||||||
|
// This string must exactly match the case used in release file names or the android updater won't work
|
||||||
|
#define HW_VENDOR HardwareModel_HELTEC_V1
|
||||||
|
|
||||||
|
#define BATTERY_PIN 13 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
|
||||||
|
|
||||||
#elif defined(TLORA_V1)
|
#elif defined(TLORA_V1)
|
||||||
// This string must exactly match the case used in release file names or the android updater won't work
|
// This string must exactly match the case used in release file names or the android updater won't work
|
||||||
#define HW_VENDOR HardwareModel_TLORA_V1
|
#define HW_VENDOR HardwareModel_TLORA_V1
|
||||||
|
|||||||
@@ -43,8 +43,8 @@ void esp32Setup()
|
|||||||
nvs_stats_t nvs_stats;
|
nvs_stats_t nvs_stats;
|
||||||
auto res = nvs_get_stats(NULL, &nvs_stats);
|
auto res = nvs_get_stats(NULL, &nvs_stats);
|
||||||
assert(res == ESP_OK);
|
assert(res == ESP_OK);
|
||||||
DEBUG_MSG("NVS: UsedEntries %d, FreeEntries %d, AllEntries %d\n", nvs_stats.used_entries, nvs_stats.free_entries,
|
DEBUG_MSG("NVS: UsedEntries %d, FreeEntries %d, AllEntries %d, NameSpaces %d\n", nvs_stats.used_entries, nvs_stats.free_entries,
|
||||||
nvs_stats.total_entries);
|
nvs_stats.total_entries, nvs_stats.namespace_count);
|
||||||
|
|
||||||
DEBUG_MSG("Setup Preferences in Flash Storage\n");
|
DEBUG_MSG("Setup Preferences in Flash Storage\n");
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,11 @@ enum RTCQuality {
|
|||||||
/// Some other node gave us a time we can use
|
/// Some other node gave us a time we can use
|
||||||
RTCQualityFromNet = 1,
|
RTCQualityFromNet = 1,
|
||||||
|
|
||||||
|
/// Our time is based on NTP
|
||||||
|
RTCQualityNTP= 2,
|
||||||
|
|
||||||
/// Our time is based on our own GPS
|
/// Our time is based on our own GPS
|
||||||
RTCQualityGPS = 2
|
RTCQualityGPS = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
RTCQuality getRTCQuality();
|
RTCQuality getRTCQuality();
|
||||||
|
|||||||
60
src/main.cpp
60
src/main.cpp
@@ -187,6 +187,9 @@ class ButtonThread : public OSThread
|
|||||||
#endif
|
#endif
|
||||||
#ifdef BUTTON_PIN_ALT
|
#ifdef BUTTON_PIN_ALT
|
||||||
OneButton userButtonAlt;
|
OneButton userButtonAlt;
|
||||||
|
#endif
|
||||||
|
#ifdef BUTTON_PIN_TOUCH
|
||||||
|
OneButton userButtonTouch;
|
||||||
#endif
|
#endif
|
||||||
static bool shutdown_on_long_stop;
|
static bool shutdown_on_long_stop;
|
||||||
|
|
||||||
@@ -205,6 +208,7 @@ class ButtonThread : public OSThread
|
|||||||
userButton.attachClick(userButtonPressed);
|
userButton.attachClick(userButtonPressed);
|
||||||
userButton.attachDuringLongPress(userButtonPressedLong);
|
userButton.attachDuringLongPress(userButtonPressedLong);
|
||||||
userButton.attachDoubleClick(userButtonDoublePressed);
|
userButton.attachDoubleClick(userButtonDoublePressed);
|
||||||
|
userButton.attachMultiClick(userButtonMultiPressed);
|
||||||
userButton.attachLongPressStart(userButtonPressedLongStart);
|
userButton.attachLongPressStart(userButtonPressedLongStart);
|
||||||
userButton.attachLongPressStop(userButtonPressedLongStop);
|
userButton.attachLongPressStop(userButtonPressedLongStop);
|
||||||
wakeOnIrq(BUTTON_PIN, FALLING);
|
wakeOnIrq(BUTTON_PIN, FALLING);
|
||||||
@@ -222,6 +226,21 @@ class ButtonThread : public OSThread
|
|||||||
userButtonAlt.attachLongPressStop(userButtonPressedLongStop);
|
userButtonAlt.attachLongPressStop(userButtonPressedLongStop);
|
||||||
wakeOnIrq(BUTTON_PIN_ALT, FALLING);
|
wakeOnIrq(BUTTON_PIN_ALT, FALLING);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef BUTTON_PIN_TOUCH
|
||||||
|
userButtonTouch = OneButton(BUTTON_PIN_TOUCH, true, true);
|
||||||
|
#ifdef INPUT_PULLUP_SENSE
|
||||||
|
// Some platforms (nrf52) have a SENSE variant which allows wake from sleep - override what OneButton did
|
||||||
|
pinMode(BUTTON_PIN_TOUCH, INPUT_PULLUP_SENSE);
|
||||||
|
#endif
|
||||||
|
userButtonTouch.attachClick(touchPressed);
|
||||||
|
userButtonTouch.attachDuringLongPress(touchPressedLong);
|
||||||
|
userButtonTouch.attachDoubleClick(touchDoublePressed);
|
||||||
|
userButtonTouch.attachLongPressStart(touchPressedLongStart);
|
||||||
|
userButtonTouch.attachLongPressStop(touchPressedLongStop);
|
||||||
|
wakeOnIrq(BUTTON_PIN_TOUCH, FALLING);
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -237,6 +256,10 @@ class ButtonThread : public OSThread
|
|||||||
#ifdef BUTTON_PIN_ALT
|
#ifdef BUTTON_PIN_ALT
|
||||||
userButtonAlt.tick();
|
userButtonAlt.tick();
|
||||||
canSleep &= userButtonAlt.isIdle();
|
canSleep &= userButtonAlt.isIdle();
|
||||||
|
#endif
|
||||||
|
#ifdef BUTTON_PIN_TOUCH
|
||||||
|
userButtonTouch.tick();
|
||||||
|
canSleep &= userButtonTouch.isIdle();
|
||||||
#endif
|
#endif
|
||||||
// if (!canSleep) DEBUG_MSG("Supressing sleep!\n");
|
// if (!canSleep) DEBUG_MSG("Supressing sleep!\n");
|
||||||
// else DEBUG_MSG("sleep ok\n");
|
// else DEBUG_MSG("sleep ok\n");
|
||||||
@@ -245,6 +268,33 @@ class ButtonThread : public OSThread
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static void touchPressed()
|
||||||
|
{
|
||||||
|
screen->forceDisplay();
|
||||||
|
DEBUG_MSG("touch press!\n");
|
||||||
|
}
|
||||||
|
static void touchDoublePressed()
|
||||||
|
{
|
||||||
|
DEBUG_MSG("touch double press!\n");
|
||||||
|
}
|
||||||
|
static void touchPressedLong()
|
||||||
|
{
|
||||||
|
DEBUG_MSG("touch press long!\n");
|
||||||
|
}
|
||||||
|
static void touchDoublePressedLong()
|
||||||
|
{
|
||||||
|
DEBUG_MSG("touch double pressed!\n");
|
||||||
|
}
|
||||||
|
static void touchPressedLongStart()
|
||||||
|
{
|
||||||
|
DEBUG_MSG("touch long press start!\n");
|
||||||
|
}
|
||||||
|
static void touchPressedLongStop()
|
||||||
|
{
|
||||||
|
DEBUG_MSG("touch long press stop!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void userButtonPressed()
|
static void userButtonPressed()
|
||||||
{
|
{
|
||||||
// DEBUG_MSG("press!\n");
|
// DEBUG_MSG("press!\n");
|
||||||
@@ -287,6 +337,14 @@ class ButtonThread : public OSThread
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void userButtonMultiPressed()
|
||||||
|
{
|
||||||
|
#ifndef NO_ESP32
|
||||||
|
clearNVS();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void userButtonPressedLongStart()
|
static void userButtonPressedLongStart()
|
||||||
{
|
{
|
||||||
DEBUG_MSG("Long press start!\n");
|
DEBUG_MSG("Long press start!\n");
|
||||||
@@ -339,6 +397,8 @@ void setup()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
DEBUG_MSG("\n\n//\\ E S H T /\\ S T / C\n\n");
|
||||||
|
|
||||||
initDeepSleep();
|
initDeepSleep();
|
||||||
|
|
||||||
#ifdef VEXT_ENABLE
|
#ifdef VEXT_ENABLE
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ void MeshPlugin::callPlugins(const MeshPacket &mp, RxSource src)
|
|||||||
assert(!pi.myReply); // If it is !null it means we have a bug, because it should have been sent the previous time
|
assert(!pi.myReply); // If it is !null it means we have a bug, because it should have been sent the previous time
|
||||||
|
|
||||||
if (wantsPacket) {
|
if (wantsPacket) {
|
||||||
DEBUG_MSG("Plugin %s wantsPacket=%d\n", pi.name, wantsPacket);
|
DEBUG_MSG("Plugin '%s' wantsPacket=%d\n", pi.name, wantsPacket);
|
||||||
|
|
||||||
pluginFound = true;
|
pluginFound = true;
|
||||||
|
|
||||||
@@ -109,7 +109,10 @@ void MeshPlugin::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
|
/// 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.
|
/// to be able to fetch the initial admin packets without yet knowing any channels.
|
||||||
|
|
||||||
bool rxChannelOk = !pi.boundChannel || (mp.from == 0) || (ch && (strcmp(ch->settings.name, pi.boundChannel) == 0));
|
bool rxChannelOk = !pi.boundChannel || (mp.from == 0) ||
|
||||||
|
!ch ||
|
||||||
|
strlen(ch->settings.name) > 0 ||
|
||||||
|
strcmp(ch->settings.name, pi.boundChannel);
|
||||||
|
|
||||||
if (!rxChannelOk) {
|
if (!rxChannelOk) {
|
||||||
// no one should have already replied!
|
// no one should have already replied!
|
||||||
@@ -134,9 +137,9 @@ void MeshPlugin::callPlugins(const MeshPacket &mp, RxSource src)
|
|||||||
// any other node.
|
// any other node.
|
||||||
if (mp.decoded.want_response && toUs && (getFrom(&mp) != ourNodeNum || mp.to == ourNodeNum) && !currentReply) {
|
if (mp.decoded.want_response && toUs && (getFrom(&mp) != ourNodeNum || mp.to == ourNodeNum) && !currentReply) {
|
||||||
pi.sendResponse(mp);
|
pi.sendResponse(mp);
|
||||||
DEBUG_MSG("Plugin %s sent a response\n", pi.name);
|
DEBUG_MSG("Plugin '%s' sent a response\n", pi.name);
|
||||||
} else {
|
} else {
|
||||||
DEBUG_MSG("Plugin %s considered\n", pi.name);
|
DEBUG_MSG("Plugin '%s' considered\n", pi.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the requester didn't ask for a response we might need to discard unused replies to prevent memory leaks
|
// If the requester didn't ask for a response we might need to discard unused replies to prevent memory leaks
|
||||||
@@ -147,7 +150,7 @@ void MeshPlugin::callPlugins(const MeshPacket &mp, RxSource src)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (handled == ProcessMessage::STOP) {
|
if (handled == ProcessMessage::STOP) {
|
||||||
DEBUG_MSG("Plugin %s handled and skipped other processing\n", pi.name);
|
DEBUG_MSG("Plugin '%s' handled and skipped other processing\n", pi.name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include "mesh/http/WiFiAPClient.h"
|
#include "mesh/http/WiFiAPClient.h"
|
||||||
#include "plugins/esp32/StoreForwardPlugin.h"
|
#include "plugins/esp32/StoreForwardPlugin.h"
|
||||||
#include <Preferences.h>
|
#include <Preferences.h>
|
||||||
|
#include <nvs_flash.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NodeDB nodeDB;
|
NodeDB nodeDB;
|
||||||
@@ -86,6 +87,10 @@ bool NodeDB::resetRadioConfig()
|
|||||||
if (radioConfig.preferences.factory_reset) {
|
if (radioConfig.preferences.factory_reset) {
|
||||||
DEBUG_MSG("Performing factory reset!\n");
|
DEBUG_MSG("Performing factory reset!\n");
|
||||||
installDefaultDeviceState();
|
installDefaultDeviceState();
|
||||||
|
#ifndef NO_ESP32
|
||||||
|
// This will erase what's in NVS including ssl keys, persistant variables and ble pairing
|
||||||
|
nvs_flash_erase();
|
||||||
|
#endif
|
||||||
didFactoryReset = true;
|
didFactoryReset = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -93,7 +93,8 @@ bool RadioLibInterface::canSendImmediately()
|
|||||||
/// bluetooth comms code. If the txmit queue is empty it might return an error
|
/// bluetooth comms code. If the txmit queue is empty it might return an error
|
||||||
ErrorCode RadioLibInterface::send(MeshPacket *p)
|
ErrorCode RadioLibInterface::send(MeshPacket *p)
|
||||||
{
|
{
|
||||||
if (disabled) {
|
if (disabled || radioConfig.preferences.is_lora_tx_disabled) {
|
||||||
|
DEBUG_MSG("send - lora_tx_disabled\n");
|
||||||
packetPool.release(p);
|
packetPool.release(p);
|
||||||
return ERRNO_DISABLED;
|
return ERRNO_DISABLED;
|
||||||
}
|
}
|
||||||
@@ -101,7 +102,6 @@ ErrorCode RadioLibInterface::send(MeshPacket *p)
|
|||||||
// Sometimes when testing it is useful to be able to never turn on the xmitter
|
// Sometimes when testing it is useful to be able to never turn on the xmitter
|
||||||
#ifndef LORA_DISABLE_SENDING
|
#ifndef LORA_DISABLE_SENDING
|
||||||
printPacket("enqueuing for send", p);
|
printPacket("enqueuing for send", p);
|
||||||
uint32_t xmitMsec = getPacketTime(p);
|
|
||||||
|
|
||||||
DEBUG_MSG("txGood=%d,rxGood=%d,rxBad=%d\n", txGood, rxGood, rxBad);
|
DEBUG_MSG("txGood=%d,rxGood=%d,rxBad=%d\n", txGood, rxGood, rxBad);
|
||||||
ErrorCode res = txQueue.enqueue(p) ? ERRNO_OK : ERRNO_UNKNOWN;
|
ErrorCode res = txQueue.enqueue(p) ? ERRNO_OK : ERRNO_UNKNOWN;
|
||||||
@@ -111,10 +111,6 @@ ErrorCode RadioLibInterface::send(MeshPacket *p)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Count the packet toward our TX airtime utilization.
|
|
||||||
// We only count it if it can be added to the TX queue.
|
|
||||||
airTime->logAirtime(TX_LOG, xmitMsec);
|
|
||||||
|
|
||||||
// We want all sending/receiving to be done by our daemon thread, We use a delay here because this packet might have been sent
|
// We want all sending/receiving to be done by our daemon thread, We use a delay here because this packet might have been sent
|
||||||
// in response to a packet we just received. So we want to make sure the other side has had a chance to reconfigure its radio
|
// in response to a packet we just received. So we want to make sure the other side has had a chance to reconfigure its radio
|
||||||
startTransmitTimer(true);
|
startTransmitTimer(true);
|
||||||
@@ -188,6 +184,10 @@ void RadioLibInterface::onNotify(uint32_t notification)
|
|||||||
MeshPacket *txp = txQueue.dequeue();
|
MeshPacket *txp = txQueue.dequeue();
|
||||||
assert(txp);
|
assert(txp);
|
||||||
startSend(txp);
|
startSend(txp);
|
||||||
|
|
||||||
|
// Packet has been sent, count it toward our TX airtime utilization.
|
||||||
|
uint32_t xmitMsec = getPacketTime(txp);
|
||||||
|
airTime->logAirtime(TX_LOG, xmitMsec);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// DEBUG_MSG("done with txqueue\n");
|
// DEBUG_MSG("done with txqueue\n");
|
||||||
@@ -301,7 +301,7 @@ void RadioLibInterface::handleReceiveInterrupt()
|
|||||||
void RadioLibInterface::startSend(MeshPacket *txp)
|
void RadioLibInterface::startSend(MeshPacket *txp)
|
||||||
{
|
{
|
||||||
printPacket("Starting low level send", txp);
|
printPacket("Starting low level send", txp);
|
||||||
if (disabled) {
|
if (disabled || radioConfig.preferences.is_lora_tx_disabled) {
|
||||||
DEBUG_MSG("startSend is dropping tx packet because we are disabled\n");
|
DEBUG_MSG("startSend is dropping tx packet because we are disabled\n");
|
||||||
packetPool.release(txp);
|
packetPool.release(txp);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#define RADIOLIB_SOFTWARE_SERIAL_UNSUPPORTED
|
#define RADIOLIB_SOFTWARE_SERIAL_UNSUPPORTED
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define RADIOLIB_EXCLUDE_HTTP
|
||||||
#include <RadioLib.h>
|
#include <RadioLib.h>
|
||||||
|
|
||||||
// ESP32 has special rules about ISR code
|
// ESP32 has special rules about ISR code
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
#define PB_ADMIN_PB_H_INCLUDED
|
#define PB_ADMIN_PB_H_INCLUDED
|
||||||
#include <pb.h>
|
#include <pb.h>
|
||||||
#include "channel.pb.h"
|
#include "channel.pb.h"
|
||||||
#include "radioconfig.pb.h"
|
|
||||||
#include "mesh.pb.h"
|
#include "mesh.pb.h"
|
||||||
|
#include "radioconfig.pb.h"
|
||||||
|
|
||||||
#if PB_PROTO_HEADER_VERSION != 40
|
#if PB_PROTO_HEADER_VERSION != 40
|
||||||
#error Regenerate this file with the current version of nanopb generator.
|
#error Regenerate this file with the current version of nanopb generator.
|
||||||
@@ -86,7 +86,7 @@ extern const pb_msgdesc_t AdminMessage_msg;
|
|||||||
#define AdminMessage_fields &AdminMessage_msg
|
#define AdminMessage_fields &AdminMessage_msg
|
||||||
|
|
||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
#define AdminMessage_size 529
|
#define AdminMessage_size 535
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ typedef enum _HardwareModel {
|
|||||||
HardwareModel_TLORA_V1_1p3 = 8,
|
HardwareModel_TLORA_V1_1p3 = 8,
|
||||||
HardwareModel_RAK4631 = 9,
|
HardwareModel_RAK4631 = 9,
|
||||||
HardwareModel_HELTEC_V2_1 = 10,
|
HardwareModel_HELTEC_V2_1 = 10,
|
||||||
|
HardwareModel_HELTEC_V1 = 11,
|
||||||
HardwareModel_LORA_RELAY_V1 = 32,
|
HardwareModel_LORA_RELAY_V1 = 32,
|
||||||
HardwareModel_NRF52840DK = 33,
|
HardwareModel_NRF52840DK = 33,
|
||||||
HardwareModel_PPR = 34,
|
HardwareModel_PPR = 34,
|
||||||
|
|||||||
@@ -155,6 +155,8 @@ typedef struct _RadioConfig_UserPreferences {
|
|||||||
uint32_t hop_limit;
|
uint32_t hop_limit;
|
||||||
char mqtt_username[32];
|
char mqtt_username[32];
|
||||||
char mqtt_password[32];
|
char mqtt_password[32];
|
||||||
|
bool is_lora_tx_disabled;
|
||||||
|
bool is_power_saving;
|
||||||
} RadioConfig_UserPreferences;
|
} RadioConfig_UserPreferences;
|
||||||
|
|
||||||
typedef struct _RadioConfig {
|
typedef struct _RadioConfig {
|
||||||
@@ -199,9 +201,9 @@ extern "C" {
|
|||||||
|
|
||||||
/* Initializer values for message structs */
|
/* Initializer values for message structs */
|
||||||
#define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default}
|
#define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default}
|
||||||
#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", ""}
|
#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, 0}
|
||||||
#define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero}
|
#define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero}
|
||||||
#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", ""}
|
#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, 0}
|
||||||
|
|
||||||
/* Field tags (for use in manual encoding/decoding) */
|
/* Field tags (for use in manual encoding/decoding) */
|
||||||
#define RadioConfig_UserPreferences_position_broadcast_secs_tag 1
|
#define RadioConfig_UserPreferences_position_broadcast_secs_tag 1
|
||||||
@@ -272,6 +274,8 @@ extern "C" {
|
|||||||
#define RadioConfig_UserPreferences_hop_limit_tag 154
|
#define RadioConfig_UserPreferences_hop_limit_tag 154
|
||||||
#define RadioConfig_UserPreferences_mqtt_username_tag 155
|
#define RadioConfig_UserPreferences_mqtt_username_tag 155
|
||||||
#define RadioConfig_UserPreferences_mqtt_password_tag 156
|
#define RadioConfig_UserPreferences_mqtt_password_tag 156
|
||||||
|
#define RadioConfig_UserPreferences_is_lora_tx_disabled_tag 157
|
||||||
|
#define RadioConfig_UserPreferences_is_power_saving_tag 158
|
||||||
#define RadioConfig_preferences_tag 1
|
#define RadioConfig_preferences_tag 1
|
||||||
|
|
||||||
/* Struct field encoding specification for nanopb */
|
/* Struct field encoding specification for nanopb */
|
||||||
@@ -349,7 +353,9 @@ X(a, STATIC, SINGULAR, UINT32, auto_screen_carousel_secs, 152) \
|
|||||||
X(a, STATIC, SINGULAR, UINT32, on_battery_shutdown_after_secs, 153) \
|
X(a, STATIC, SINGULAR, UINT32, on_battery_shutdown_after_secs, 153) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, hop_limit, 154) \
|
X(a, STATIC, SINGULAR, UINT32, hop_limit, 154) \
|
||||||
X(a, STATIC, SINGULAR, STRING, mqtt_username, 155) \
|
X(a, STATIC, SINGULAR, STRING, mqtt_username, 155) \
|
||||||
X(a, STATIC, SINGULAR, STRING, mqtt_password, 156)
|
X(a, STATIC, SINGULAR, STRING, mqtt_password, 156) \
|
||||||
|
X(a, STATIC, SINGULAR, BOOL, is_lora_tx_disabled, 157) \
|
||||||
|
X(a, STATIC, SINGULAR, BOOL, is_power_saving, 158)
|
||||||
#define RadioConfig_UserPreferences_CALLBACK NULL
|
#define RadioConfig_UserPreferences_CALLBACK NULL
|
||||||
#define RadioConfig_UserPreferences_DEFAULT NULL
|
#define RadioConfig_UserPreferences_DEFAULT NULL
|
||||||
|
|
||||||
@@ -361,8 +367,8 @@ extern const pb_msgdesc_t RadioConfig_UserPreferences_msg;
|
|||||||
#define RadioConfig_UserPreferences_fields &RadioConfig_UserPreferences_msg
|
#define RadioConfig_UserPreferences_fields &RadioConfig_UserPreferences_msg
|
||||||
|
|
||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
#define RadioConfig_size 526
|
#define RadioConfig_size 532
|
||||||
#define RadioConfig_UserPreferences_size 523
|
#define RadioConfig_UserPreferences_size 529
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "airtime.h"
|
#include "airtime.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "mesh/http/ContentHelper.h"
|
#include "mesh/http/ContentHelper.h"
|
||||||
|
#include "mesh/http/WebServer.h"
|
||||||
#include "mesh/http/WiFiAPClient.h"
|
#include "mesh/http/WiFiAPClient.h"
|
||||||
#include "power.h"
|
#include "power.h"
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
@@ -41,6 +42,13 @@ using namespace httpsserver;
|
|||||||
|
|
||||||
#include "mesh/http/ContentHandler.h"
|
#include "mesh/http/ContentHandler.h"
|
||||||
|
|
||||||
|
#include <HTTPClient.h>
|
||||||
|
#include <WiFiClientSecure.h>
|
||||||
|
HTTPClient httpClient;
|
||||||
|
|
||||||
|
#define DEST_FS_USES_SPIFFS
|
||||||
|
#include <ESP32-targz.h>
|
||||||
|
|
||||||
// We need to specify some content-type mapping, so the resources get delivered with the
|
// We need to specify some content-type mapping, so the resources get delivered with the
|
||||||
// right content type and are displayed correctly in the browser
|
// right content type and are displayed correctly in the browser
|
||||||
char contentTypes[][2][32] = {{".txt", "text/plain"}, {".html", "text/html"},
|
char contentTypes[][2][32] = {{".txt", "text/plain"}, {".html", "text/html"},
|
||||||
@@ -50,9 +58,59 @@ char contentTypes[][2][32] = {{".txt", "text/plain"}, {".html", "text/html"}
|
|||||||
{".css", "text/css"}, {".ico", "image/vnd.microsoft.icon"},
|
{".css", "text/css"}, {".ico", "image/vnd.microsoft.icon"},
|
||||||
{".svg", "image/svg+xml"}, {"", ""}};
|
{".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.
|
// Our API to handle messages to and from the radio.
|
||||||
HttpAPI webAPI;
|
HttpAPI webAPI;
|
||||||
|
|
||||||
|
WiFiClient *getTarHTTPClientPtr(WiFiClientSecure *client, const char *url, const char *cert = NULL)
|
||||||
|
{
|
||||||
|
if (cert == NULL) {
|
||||||
|
// New versions don't have setInsecure
|
||||||
|
// client->setInsecure();
|
||||||
|
} else {
|
||||||
|
client->setCACert(cert);
|
||||||
|
}
|
||||||
|
const char *UserAgent = "ESP32-HTTP-GzUpdater-Client";
|
||||||
|
httpClient.setReuse(true); // handle 301 redirects gracefully
|
||||||
|
httpClient.setUserAgent(UserAgent);
|
||||||
|
httpClient.setConnectTimeout(10000); // 10s timeout = 10000
|
||||||
|
if (!httpClient.begin(*client, url)) {
|
||||||
|
log_e("Can't open url %s", url);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
const char *headerKeys[] = {"location", "redirect", "Content-Type", "Content-Length", "Content-Disposition"};
|
||||||
|
const size_t numberOfHeaders = 5;
|
||||||
|
httpClient.collectHeaders(headerKeys, numberOfHeaders);
|
||||||
|
int httpCode = httpClient.GET();
|
||||||
|
// file found at server
|
||||||
|
if (httpCode == HTTP_CODE_FOUND || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
|
||||||
|
String newlocation = "";
|
||||||
|
String headerLocation = httpClient.header("location");
|
||||||
|
String headerRedirect = httpClient.header("redirect");
|
||||||
|
if (headerLocation != "") {
|
||||||
|
newlocation = headerLocation;
|
||||||
|
Serial.printf("302 (location): %s => %s\n", url, headerLocation.c_str());
|
||||||
|
} else if (headerRedirect != "") {
|
||||||
|
Serial.printf("301 (redirect): %s => %s\n", url, headerLocation.c_str());
|
||||||
|
newlocation = headerRedirect;
|
||||||
|
}
|
||||||
|
httpClient.end();
|
||||||
|
if (newlocation != "") {
|
||||||
|
log_w("Found 302/301 location header: %s", newlocation.c_str());
|
||||||
|
return getTarHTTPClientPtr(client, newlocation.c_str(), cert);
|
||||||
|
} else {
|
||||||
|
log_e("Empty redirect !!");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (httpCode != 200)
|
||||||
|
return nullptr;
|
||||||
|
return httpClient.getStreamPtr();
|
||||||
|
}
|
||||||
|
|
||||||
void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
|
void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -66,6 +124,13 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
|
|||||||
ResourceNode *nodeHotspotApple = new ResourceNode("/hotspot-detect.html", "GET", &handleHotspot);
|
ResourceNode *nodeHotspotApple = new ResourceNode("/hotspot-detect.html", "GET", &handleHotspot);
|
||||||
ResourceNode *nodeHotspotAndroid = new ResourceNode("/generate_204", "GET", &handleHotspot);
|
ResourceNode *nodeHotspotAndroid = new ResourceNode("/generate_204", "GET", &handleHotspot);
|
||||||
|
|
||||||
|
ResourceNode *nodeAdmin = new ResourceNode("/admin", "GET", &handleAdmin);
|
||||||
|
ResourceNode *nodeAdminSettings = new ResourceNode("/admin/settings", "GET", &handleAdminSettings);
|
||||||
|
ResourceNode *nodeAdminSettingsApply = new ResourceNode("/admin/settings/apply", "POST", &handleAdminSettingsApply);
|
||||||
|
ResourceNode *nodeAdminSPIFFS = new ResourceNode("/admin/spiffs", "GET", &handleSPIFFS);
|
||||||
|
ResourceNode *nodeUpdateSPIFFS = new ResourceNode("/admin/spiffs/update", "POST", &handleUpdateSPIFFS);
|
||||||
|
ResourceNode *nodeDeleteSPIFFS = new ResourceNode("/admin/spiffs/delete", "GET", &handleDeleteSPIFFSContent);
|
||||||
|
|
||||||
ResourceNode *nodeRestart = new ResourceNode("/restart", "POST", &handleRestart);
|
ResourceNode *nodeRestart = new ResourceNode("/restart", "POST", &handleRestart);
|
||||||
ResourceNode *nodeFormUpload = new ResourceNode("/upload", "POST", &handleFormUpload);
|
ResourceNode *nodeFormUpload = new ResourceNode("/upload", "POST", &handleFormUpload);
|
||||||
|
|
||||||
@@ -75,6 +140,7 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
|
|||||||
ResourceNode *nodeJsonSpiffsBrowseStatic = new ResourceNode("/json/spiffs/browse/static", "GET", &handleSpiffsBrowseStatic);
|
ResourceNode *nodeJsonSpiffsBrowseStatic = new ResourceNode("/json/spiffs/browse/static", "GET", &handleSpiffsBrowseStatic);
|
||||||
ResourceNode *nodeJsonDelete = new ResourceNode("/json/spiffs/delete/static", "DELETE", &handleSpiffsDeleteStatic);
|
ResourceNode *nodeJsonDelete = new ResourceNode("/json/spiffs/delete/static", "DELETE", &handleSpiffsDeleteStatic);
|
||||||
|
|
||||||
|
|
||||||
ResourceNode *nodeRoot = new ResourceNode("/*", "GET", &handleStatic);
|
ResourceNode *nodeRoot = new ResourceNode("/*", "GET", &handleStatic);
|
||||||
|
|
||||||
// Secure nodes
|
// Secure nodes
|
||||||
@@ -90,7 +156,13 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
|
|||||||
secureServer->registerNode(nodeJsonSpiffsBrowseStatic);
|
secureServer->registerNode(nodeJsonSpiffsBrowseStatic);
|
||||||
secureServer->registerNode(nodeJsonDelete);
|
secureServer->registerNode(nodeJsonDelete);
|
||||||
secureServer->registerNode(nodeJsonReport);
|
secureServer->registerNode(nodeJsonReport);
|
||||||
secureServer->registerNode(nodeRoot);
|
secureServer->registerNode(nodeUpdateSPIFFS);
|
||||||
|
secureServer->registerNode(nodeDeleteSPIFFS);
|
||||||
|
secureServer->registerNode(nodeAdmin);
|
||||||
|
secureServer->registerNode(nodeAdminSPIFFS);
|
||||||
|
secureServer->registerNode(nodeAdminSettings);
|
||||||
|
secureServer->registerNode(nodeAdminSettingsApply);
|
||||||
|
secureServer->registerNode(nodeRoot); // This has to be last
|
||||||
|
|
||||||
// Insecure nodes
|
// Insecure nodes
|
||||||
insecureServer->registerNode(nodeAPIv1ToRadioOptions);
|
insecureServer->registerNode(nodeAPIv1ToRadioOptions);
|
||||||
@@ -105,13 +177,19 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
|
|||||||
insecureServer->registerNode(nodeJsonSpiffsBrowseStatic);
|
insecureServer->registerNode(nodeJsonSpiffsBrowseStatic);
|
||||||
insecureServer->registerNode(nodeJsonDelete);
|
insecureServer->registerNode(nodeJsonDelete);
|
||||||
insecureServer->registerNode(nodeJsonReport);
|
insecureServer->registerNode(nodeJsonReport);
|
||||||
insecureServer->registerNode(nodeRoot);
|
insecureServer->registerNode(nodeUpdateSPIFFS);
|
||||||
|
insecureServer->registerNode(nodeDeleteSPIFFS);
|
||||||
|
insecureServer->registerNode(nodeAdmin);
|
||||||
|
insecureServer->registerNode(nodeAdminSPIFFS);
|
||||||
|
insecureServer->registerNode(nodeAdminSettings);
|
||||||
|
insecureServer->registerNode(nodeAdminSettingsApply);
|
||||||
|
insecureServer->registerNode(nodeRoot); // This has to be last
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleAPIv1FromRadio(HTTPRequest *req, HTTPResponse *res)
|
void handleAPIv1FromRadio(HTTPRequest *req, HTTPResponse *res)
|
||||||
{
|
{
|
||||||
|
|
||||||
DEBUG_MSG("+++++++++++++++ webAPI handleAPIv1FromRadio\n");
|
DEBUG_MSG("webAPI handleAPIv1FromRadio\n");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
For documentation, see:
|
For documentation, see:
|
||||||
@@ -156,12 +234,12 @@ void handleAPIv1FromRadio(HTTPRequest *req, HTTPResponse *res)
|
|||||||
res->write(txBuf, len);
|
res->write(txBuf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_MSG("--------------- webAPI handleAPIv1FromRadio, len %d\n", len);
|
DEBUG_MSG("webAPI handleAPIv1FromRadio, len %d\n", len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleAPIv1ToRadio(HTTPRequest *req, HTTPResponse *res)
|
void handleAPIv1ToRadio(HTTPRequest *req, HTTPResponse *res)
|
||||||
{
|
{
|
||||||
DEBUG_MSG("+++++++++++++++ webAPI handleAPIv1ToRadio\n");
|
DEBUG_MSG("webAPI handleAPIv1ToRadio\n");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
For documentation, see:
|
For documentation, see:
|
||||||
@@ -188,7 +266,7 @@ void handleAPIv1ToRadio(HTTPRequest *req, HTTPResponse *res)
|
|||||||
webAPI.handleToRadio(buffer, s);
|
webAPI.handleToRadio(buffer, s);
|
||||||
|
|
||||||
res->write(buffer, s);
|
res->write(buffer, s);
|
||||||
DEBUG_MSG("--------------- webAPI handleAPIv1ToRadio\n");
|
DEBUG_MSG("webAPI handleAPIv1ToRadio\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleSpiffsBrowseStatic(HTTPRequest *req, HTTPResponse *res)
|
void handleSpiffsBrowseStatic(HTTPRequest *req, HTTPResponse *res)
|
||||||
@@ -297,14 +375,21 @@ void handleStatic(HTTPRequest *req, HTTPResponse *res)
|
|||||||
file = SPIFFS.open(filenameGzip.c_str());
|
file = SPIFFS.open(filenameGzip.c_str());
|
||||||
res->setHeader("Content-Encoding", "gzip");
|
res->setHeader("Content-Encoding", "gzip");
|
||||||
if (!file.available()) {
|
if (!file.available()) {
|
||||||
DEBUG_MSG("File not available\n");
|
DEBUG_MSG("File not available - %s\n", filenameGzip.c_str());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
has_set_content_type = true;
|
has_set_content_type = true;
|
||||||
filenameGzip = "/static/index.html.gz";
|
filenameGzip = "/static/index.html.gz";
|
||||||
file = SPIFFS.open(filenameGzip.c_str());
|
file = SPIFFS.open(filenameGzip.c_str());
|
||||||
res->setHeader("Content-Encoding", "gzip");
|
|
||||||
res->setHeader("Content-Type", "text/html");
|
res->setHeader("Content-Type", "text/html");
|
||||||
|
if (!file.available()) {
|
||||||
|
DEBUG_MSG("File not available - %s\n", filenameGzip.c_str());
|
||||||
|
res->println("Web server is running.<br><br>The content you are looking for can't be found. Please see: <a "
|
||||||
|
"href=https://meshtastic.org/docs/getting-started/faq#wifi--web-browser>FAQ</a>.<br><br><a "
|
||||||
|
"href=/admin>admin</a>");
|
||||||
|
} else {
|
||||||
|
res->setHeader("Content-Encoding", "gzip");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res->setHeader("Content-Length", httpsserver::intToString(file.size()));
|
res->setHeader("Content-Length", httpsserver::intToString(file.size()));
|
||||||
@@ -576,6 +661,7 @@ void handleReport(HTTPRequest *req, HTTPResponse *res)
|
|||||||
res->println("},");
|
res->println("},");
|
||||||
|
|
||||||
res->println("\"device\": {");
|
res->println("\"device\": {");
|
||||||
|
res->printf("\"channel_utilization\": %3.2f%,\n", airTime->channelUtilizationPercent());
|
||||||
res->printf("\"reboot_counter\": %d\n", myNodeInfo.reboot_count);
|
res->printf("\"reboot_counter\": %d\n", myNodeInfo.reboot_count);
|
||||||
res->println("},");
|
res->println("},");
|
||||||
|
|
||||||
@@ -612,16 +698,189 @@ void handleHotspot(HTTPRequest *req, HTTPResponse *res)
|
|||||||
res->println("<meta http-equiv=\"refresh\" content=\"0;url=/\" />\n");
|
res->println("<meta http-equiv=\"refresh\" content=\"0;url=/\" />\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handleUpdateSPIFFS(HTTPRequest *req, HTTPResponse *res)
|
||||||
|
{
|
||||||
|
res->setHeader("Content-Type", "text/html");
|
||||||
|
res->setHeader("Access-Control-Allow-Origin", "*");
|
||||||
|
// res->setHeader("Access-Control-Allow-Methods", "POST");
|
||||||
|
|
||||||
|
res->println("<h1>Meshtastic</h1>\n");
|
||||||
|
res->println("Downloading Meshtastic Web Content...");
|
||||||
|
|
||||||
|
WiFiClientSecure *client = new WiFiClientSecure;
|
||||||
|
Stream *streamptr = getTarHTTPClientPtr(client, tarURL, certificate);
|
||||||
|
|
||||||
|
delay(5); // Let other network operations run
|
||||||
|
|
||||||
|
if (streamptr != nullptr) {
|
||||||
|
DEBUG_MSG("Connection to content server ... success!\n");
|
||||||
|
|
||||||
|
File root = SPIFFS.open("/");
|
||||||
|
File file = root.openNextFile();
|
||||||
|
|
||||||
|
DEBUG_MSG("Deleting files from /static : \n");
|
||||||
|
|
||||||
|
while (file) {
|
||||||
|
String filePath = String(file.name());
|
||||||
|
if (filePath.indexOf("/static") == 0) {
|
||||||
|
DEBUG_MSG(" %s\n", file.name());
|
||||||
|
SPIFFS.remove(file.name());
|
||||||
|
}
|
||||||
|
file = root.openNextFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
delay(5); // Let other network operations run
|
||||||
|
|
||||||
|
TarUnpacker *TARUnpacker = new TarUnpacker();
|
||||||
|
TARUnpacker->haltOnError(false); // stop on fail (manual restart/reset required)
|
||||||
|
TARUnpacker->setTarVerify(false); // true = enables health checks but slows down the overall process
|
||||||
|
TARUnpacker->setupFSCallbacks(targzTotalBytesFn, targzFreeBytesFn); // prevent the partition from exploding, recommended
|
||||||
|
TARUnpacker->setLoggerCallback(BaseUnpacker::targzPrintLoggerCallback); // gz log verbosity
|
||||||
|
TARUnpacker->setTarProgressCallback(
|
||||||
|
BaseUnpacker::defaultProgressCallback); // prints the untarring progress for each individual file
|
||||||
|
TARUnpacker->setTarStatusProgressCallback(
|
||||||
|
BaseUnpacker::defaultTarStatusProgressCallback); // print the filenames as they're expanded
|
||||||
|
TARUnpacker->setTarMessageCallback(BaseUnpacker::targzPrintLoggerCallback); // tar log verbosity
|
||||||
|
|
||||||
|
String contentLengthStr = httpClient.header("Content-Length");
|
||||||
|
contentLengthStr.trim();
|
||||||
|
int64_t streamSize = -1;
|
||||||
|
if (contentLengthStr != "") {
|
||||||
|
streamSize = atoi(contentLengthStr.c_str());
|
||||||
|
Serial.printf("Stream size %d\n", streamSize);
|
||||||
|
res->printf("Stream size %d<br><br>\n", streamSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TARUnpacker->tarStreamExpander(streamptr, streamSize, SPIFFS, "/static")) {
|
||||||
|
res->printf("tarStreamExpander failed with return code #%d\n", TARUnpacker->tarGzGetError());
|
||||||
|
Serial.printf("tarStreamExpander failed with return code #%d\n", TARUnpacker->tarGzGetError());
|
||||||
|
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
// print leftover bytes if any (probably zero-fill from the server)
|
||||||
|
while (httpClient.connected()) {
|
||||||
|
size_t streamSize = streamptr->available();
|
||||||
|
if (streamSize) {
|
||||||
|
Serial.printf("%02x ", streamptr->read());
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
res->printf("Failed to establish http connection\n");
|
||||||
|
Serial.println("Failed to establish http connection");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
res->println("Done! Restarting the device. <a href=/>Click this in 10 seconds</a>");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is a work around for a bug where we run out of memory.
|
||||||
|
* TODO: Fixme!
|
||||||
|
*/
|
||||||
|
// ESP.restart();
|
||||||
|
webServerThread->requestRestart = (millis() / 1000) + 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleDeleteSPIFFSContent(HTTPRequest *req, HTTPResponse *res)
|
||||||
|
{
|
||||||
|
res->setHeader("Content-Type", "text/html");
|
||||||
|
res->setHeader("Access-Control-Allow-Origin", "*");
|
||||||
|
res->setHeader("Access-Control-Allow-Methods", "GET");
|
||||||
|
|
||||||
|
res->println("<h1>Meshtastic</h1>\n");
|
||||||
|
res->println("Deleting SPIFFS Content in /static/*");
|
||||||
|
|
||||||
|
File root = SPIFFS.open("/");
|
||||||
|
File file = root.openNextFile();
|
||||||
|
|
||||||
|
DEBUG_MSG("Deleting files from /static : \n");
|
||||||
|
|
||||||
|
while (file) {
|
||||||
|
String filePath = String(file.name());
|
||||||
|
if (filePath.indexOf("/static") == 0) {
|
||||||
|
DEBUG_MSG(" %s\n", file.name());
|
||||||
|
SPIFFS.remove(file.name());
|
||||||
|
}
|
||||||
|
file = root.openNextFile();
|
||||||
|
}
|
||||||
|
res->println("<p><hr><p><a href=/admin>Back to admin</a>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleAdmin(HTTPRequest *req, HTTPResponse *res)
|
||||||
|
{
|
||||||
|
res->setHeader("Content-Type", "text/html");
|
||||||
|
res->setHeader("Access-Control-Allow-Origin", "*");
|
||||||
|
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/spiffs>Manage Web Content</a><br>\n");
|
||||||
|
res->println("<a href=/json/report>Device Report</a><br>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleAdminSettings(HTTPRequest *req, HTTPResponse *res)
|
||||||
|
{
|
||||||
|
res->setHeader("Content-Type", "text/html");
|
||||||
|
res->setHeader("Access-Control-Allow-Origin", "*");
|
||||||
|
res->setHeader("Access-Control-Allow-Methods", "GET");
|
||||||
|
|
||||||
|
res->println("<h1>Meshtastic</h1>\n");
|
||||||
|
res->println("This isn't done.\n");
|
||||||
|
res->println("<form action=/admin/settings/apply method=post>\n");
|
||||||
|
res->println("<table border=1>\n");
|
||||||
|
res->println("<tr><td>Set?</td><td>Setting</td><td>current value</td><td>new value</td></tr>\n");
|
||||||
|
res->println("<tr><td><input type=checkbox></td><td>WiFi SSID</td><td>false</td><td><input type=radio></td></tr>\n");
|
||||||
|
res->println("<tr><td><input type=checkbox></td><td>WiFi Password</td><td>false</td><td><input type=radio></td></tr>\n");
|
||||||
|
res->println("<tr><td><input type=checkbox></td><td>Smart Position Update</td><td>false</td><td><input type=radio></td></tr>\n");
|
||||||
|
res->println("<tr><td><input type=checkbox></td><td>is_always_powered</td><td>false</td><td><input type=radio></td></tr>\n");
|
||||||
|
res->println("<tr><td><input type=checkbox></td><td>is_always_powered</td><td>false</td><td><input type=radio></td></tr>\n");
|
||||||
|
res->println("</table>\n");
|
||||||
|
res->println("<table>\n");
|
||||||
|
res->println("<input type=submit value=Apply New Settings>\n");
|
||||||
|
res->println("<form>\n");
|
||||||
|
res->println("<p><hr><p><a href=/admin>Back to admin</a>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleAdminSettingsApply(HTTPRequest *req, HTTPResponse *res)
|
||||||
|
{
|
||||||
|
res->setHeader("Content-Type", "text/html");
|
||||||
|
res->setHeader("Access-Control-Allow-Origin", "*");
|
||||||
|
res->setHeader("Access-Control-Allow-Methods", "POST");
|
||||||
|
res->println("<h1>Meshtastic</h1>\n");
|
||||||
|
res->println(
|
||||||
|
"<html><head><meta http-equiv=\"refresh\" content=\"1;url=/admin/settings\" /><title>Settings Applied. </title>");
|
||||||
|
|
||||||
|
res->println("Settings Applied. Please wait.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void handleSPIFFS(HTTPRequest *req, HTTPResponse *res)
|
||||||
|
{
|
||||||
|
res->setHeader("Content-Type", "text/html");
|
||||||
|
res->setHeader("Access-Control-Allow-Origin", "*");
|
||||||
|
res->setHeader("Access-Control-Allow-Methods", "GET");
|
||||||
|
|
||||||
|
res->println("<h1>Meshtastic</h1>\n");
|
||||||
|
res->println("<a href=/admin/spiffs/delete>Delete Web Content</a><p><form action=/admin/spiffs/update "
|
||||||
|
"method=post><input type=submit value=UPDATE_WEB_CONTENT></form>Be patient!");
|
||||||
|
res->println("<p><hr><p><a href=/admin>Back to admin</a>\n");
|
||||||
|
}
|
||||||
|
|
||||||
void handleRestart(HTTPRequest *req, HTTPResponse *res)
|
void handleRestart(HTTPRequest *req, HTTPResponse *res)
|
||||||
{
|
{
|
||||||
res->setHeader("Content-Type", "text/html");
|
res->setHeader("Content-Type", "text/html");
|
||||||
res->setHeader("Access-Control-Allow-Origin", "*");
|
res->setHeader("Access-Control-Allow-Origin", "*");
|
||||||
res->setHeader("Access-Control-Allow-Methods", "GET");
|
res->setHeader("Access-Control-Allow-Methods", "GET");
|
||||||
|
|
||||||
DEBUG_MSG("***** Restarted on HTTP(s) Request *****\n");
|
res->println("<h1>Meshtastic</h1>\n");
|
||||||
res->println("Restarting");
|
res->println("Restarting");
|
||||||
|
|
||||||
ESP.restart();
|
DEBUG_MSG("***** Restarted on HTTP(s) Request *****\n");
|
||||||
|
webServerThread->requestRestart = (millis() / 1000) + 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleBlinkLED(HTTPRequest *req, HTTPResponse *res)
|
void handleBlinkLED(HTTPRequest *req, HTTPResponse *res)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer);
|
void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer);
|
||||||
|
|
||||||
// Declare some handler functions for the various URLs on the server
|
// Declare some handler functions for the various URLs on the server
|
||||||
@@ -14,9 +15,13 @@ void handleSpiffsBrowseStatic(HTTPRequest *req, HTTPResponse *res);
|
|||||||
void handleSpiffsDeleteStatic(HTTPRequest *req, HTTPResponse *res);
|
void handleSpiffsDeleteStatic(HTTPRequest *req, HTTPResponse *res);
|
||||||
void handleBlinkLED(HTTPRequest *req, HTTPResponse *res);
|
void handleBlinkLED(HTTPRequest *req, HTTPResponse *res);
|
||||||
void handleReport(HTTPRequest *req, HTTPResponse *res);
|
void handleReport(HTTPRequest *req, HTTPResponse *res);
|
||||||
|
void handleUpdateSPIFFS(HTTPRequest *req, HTTPResponse *res);
|
||||||
|
void handleDeleteSPIFFSContent(HTTPRequest *req, HTTPResponse *res);
|
||||||
|
void handleSPIFFS(HTTPRequest *req, HTTPResponse *res);
|
||||||
|
void handleAdmin(HTTPRequest *req, HTTPResponse *res);
|
||||||
|
void handleAdminSettings(HTTPRequest *req, HTTPResponse *res);
|
||||||
|
void handleAdminSettingsApply(HTTPRequest *req, HTTPResponse *res);
|
||||||
|
|
||||||
void middlewareSpeedUp240(HTTPRequest *req, HTTPResponse *res, std::function<void()> next);
|
|
||||||
void middlewareSpeedUp160(HTTPRequest *req, HTTPResponse *res, std::function<void()> next);
|
|
||||||
|
|
||||||
// Interface to the PhoneAPI to access the protobufs with messages
|
// Interface to the PhoneAPI to access the protobufs with messages
|
||||||
class HttpAPI : public PhoneAPI
|
class HttpAPI : public PhoneAPI
|
||||||
|
|||||||
@@ -175,6 +175,10 @@ int32_t WebServerThread::runOnce()
|
|||||||
// DEBUG_MSG("WebServerThread::runOnce()\n");
|
// DEBUG_MSG("WebServerThread::runOnce()\n");
|
||||||
handleWebResponse();
|
handleWebResponse();
|
||||||
|
|
||||||
|
if (requestRestart && (millis() / 1000) > requestRestart) {
|
||||||
|
ESP.restart();
|
||||||
|
}
|
||||||
|
|
||||||
// Loop every 5ms.
|
// Loop every 5ms.
|
||||||
return (5);
|
return (5);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ class WebServerThread : private concurrency::OSThread
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
WebServerThread();
|
WebServerThread();
|
||||||
|
uint32_t requestRestart = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int32_t runOnce();
|
virtual int32_t runOnce();
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
#include "mesh/http/WiFiAPClient.h"
|
#include "mesh/http/WiFiAPClient.h"
|
||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
|
#include "RTC.h"
|
||||||
#include "concurrency/Periodic.h"
|
#include "concurrency/Periodic.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "mqtt/MQTT.h"
|
|
||||||
#include "mesh/http/WebServer.h"
|
#include "mesh/http/WebServer.h"
|
||||||
#include "mesh/wifi/WiFiServerAPI.h"
|
#include "mesh/wifi/WiFiServerAPI.h"
|
||||||
|
#include "mqtt/MQTT.h"
|
||||||
#include "target_specific.h"
|
#include "target_specific.h"
|
||||||
#include <DNSServer.h>
|
#include <DNSServer.h>
|
||||||
#include <ESPmDNS.h>
|
#include <ESPmDNS.h>
|
||||||
|
#include <NTPClient.h>
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
|
#include <WiFiUdp.h>
|
||||||
|
|
||||||
using namespace concurrency;
|
using namespace concurrency;
|
||||||
|
|
||||||
@@ -18,6 +21,10 @@ static void WiFiEvent(WiFiEvent_t event);
|
|||||||
// DNS Server for the Captive Portal
|
// DNS Server for the Captive Portal
|
||||||
DNSServer dnsServer;
|
DNSServer dnsServer;
|
||||||
|
|
||||||
|
// NTP
|
||||||
|
WiFiUDP ntpUDP;
|
||||||
|
NTPClient timeClient(ntpUDP, "0.pool.ntp.org");
|
||||||
|
|
||||||
uint8_t wifiDisconnectReason = 0;
|
uint8_t wifiDisconnectReason = 0;
|
||||||
|
|
||||||
// Stores our hostname
|
// Stores our hostname
|
||||||
@@ -46,10 +53,10 @@ static WifiSleepObserver wifiSleepObserver;
|
|||||||
|
|
||||||
static int32_t reconnectWiFi()
|
static int32_t reconnectWiFi()
|
||||||
{
|
{
|
||||||
if (radioConfig.has_preferences && needReconnect) {
|
const char *wifiName = radioConfig.preferences.wifi_ssid;
|
||||||
|
const char *wifiPsw = radioConfig.preferences.wifi_password;
|
||||||
|
|
||||||
const char *wifiName = radioConfig.preferences.wifi_ssid;
|
if (radioConfig.has_preferences && needReconnect && !WiFi.isConnected()) {
|
||||||
const char *wifiPsw = radioConfig.preferences.wifi_password;
|
|
||||||
|
|
||||||
if (!*wifiPsw) // Treat empty password as no password
|
if (!*wifiPsw) // Treat empty password as no password
|
||||||
wifiPsw = NULL;
|
wifiPsw = NULL;
|
||||||
@@ -60,6 +67,26 @@ static int32_t reconnectWiFi()
|
|||||||
DEBUG_MSG("... Reconnecting to WiFi access point\n");
|
DEBUG_MSG("... Reconnecting to WiFi access point\n");
|
||||||
WiFi.mode(WIFI_MODE_STA);
|
WiFi.mode(WIFI_MODE_STA);
|
||||||
WiFi.begin(wifiName, wifiPsw);
|
WiFi.begin(wifiName, wifiPsw);
|
||||||
|
|
||||||
|
|
||||||
|
// Starting timeClient;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (*wifiName) {
|
||||||
|
if (WiFi.isConnected()) {
|
||||||
|
DEBUG_MSG("Updating NTP time\n");
|
||||||
|
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);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
DEBUG_MSG("NTP Update failed\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,34 +155,38 @@ static void onNetworkConnected()
|
|||||||
MDNS.addService("https", "tcp", 443);
|
MDNS.addService("https", "tcp", 443);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEBUG_MSG("Starting NTP time client\n");
|
||||||
|
timeClient.begin();
|
||||||
|
timeClient.setUpdateInterval(60*60); // Update once an hour
|
||||||
|
|
||||||
initWebServer();
|
initWebServer();
|
||||||
initApiServer();
|
initApiServer();
|
||||||
|
|
||||||
APStartupComplete = true;
|
APStartupComplete = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME this is kinda yucky, instead we should just have an observable for 'wifireconnected'
|
// FIXME this is kinda yucky, instead we should just have an observable for 'wifireconnected'
|
||||||
if(mqtt)
|
if (mqtt)
|
||||||
mqtt->reconnect();
|
mqtt->reconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Startup WiFi
|
// Startup WiFi
|
||||||
bool initWifi(bool forceSoftAP)
|
bool initWifi(bool forceSoftAP)
|
||||||
{
|
{
|
||||||
if (forceSoftAP) {
|
|
||||||
DEBUG_MSG("WiFi ... Forced AP Mode\n");
|
|
||||||
} else if (radioConfig.preferences.wifi_ap_mode) {
|
|
||||||
DEBUG_MSG("WiFi ... AP Mode\n");
|
|
||||||
} else {
|
|
||||||
DEBUG_MSG("WiFi ... Client Mode\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
forcedSoftAP = forceSoftAP;
|
forcedSoftAP = forceSoftAP;
|
||||||
|
|
||||||
if ((radioConfig.has_preferences && radioConfig.preferences.wifi_ssid[0]) || forceSoftAP) {
|
if ((radioConfig.has_preferences && radioConfig.preferences.wifi_ssid[0]) || forceSoftAP) {
|
||||||
const char *wifiName = radioConfig.preferences.wifi_ssid;
|
const char *wifiName = radioConfig.preferences.wifi_ssid;
|
||||||
const char *wifiPsw = radioConfig.preferences.wifi_password;
|
const char *wifiPsw = radioConfig.preferences.wifi_password;
|
||||||
|
|
||||||
|
if (forceSoftAP) {
|
||||||
|
DEBUG_MSG("WiFi ... Forced AP Mode\n");
|
||||||
|
} else if (radioConfig.preferences.wifi_ap_mode) {
|
||||||
|
DEBUG_MSG("WiFi ... AP Mode\n");
|
||||||
|
} else {
|
||||||
|
DEBUG_MSG("WiFi ... Client Mode\n");
|
||||||
|
}
|
||||||
|
|
||||||
createSSLCert();
|
createSSLCert();
|
||||||
|
|
||||||
if (!*wifiPsw) // Treat empty password as no password
|
if (!*wifiPsw) // Treat empty password as no password
|
||||||
@@ -176,7 +207,6 @@ bool initWifi(bool forceSoftAP)
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
DEBUG_MSG("Starting WIFI AP: ssid=%s, ok=%d\n", wifiName, WiFi.softAP(wifiName, wifiPsw));
|
DEBUG_MSG("Starting WIFI AP: ssid=%s, ok=%d\n", wifiName, WiFi.softAP(wifiName, wifiPsw));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
|
WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ void MQTT::reconnect()
|
|||||||
}
|
}
|
||||||
pubSub.setServer(serverAddr, serverPort);
|
pubSub.setServer(serverAddr, serverPort);
|
||||||
|
|
||||||
DEBUG_MSG("Connecting to MQTT server %s, port: %d, username: %s, password %s\n", serverAddr, serverPort, mqttUsername, mqttPassword);
|
DEBUG_MSG("Connecting to MQTT server %s, port: %d, username: %s, password: %s\n", serverAddr, serverPort, mqttUsername, mqttPassword);
|
||||||
auto myStatus = (statusTopic + owner.id);
|
auto myStatus = (statusTopic + owner.id);
|
||||||
bool connected = pubSub.connect(owner.id, mqttUsername, mqttPassword, myStatus.c_str(), 1, true, "offline");
|
bool connected = pubSub.connect(owner.id, mqttUsername, mqttPassword, myStatus.c_str(), 1, true, "offline");
|
||||||
if (connected) {
|
if (connected) {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#ifndef NO_ESP32
|
#ifndef NO_ESP32
|
||||||
#include "mesh/http/WiFiAPClient.h"
|
#include "mesh/http/WiFiAPClient.h"
|
||||||
|
#include <nvs_flash.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static bool pinShowing;
|
static bool pinShowing;
|
||||||
@@ -484,7 +485,24 @@ void disablePin()
|
|||||||
doublepressed = millis();
|
doublepressed = millis();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This should go somewhere else.
|
||||||
|
void clearNVS()
|
||||||
|
{
|
||||||
|
#ifndef NO_ESP32
|
||||||
|
|
||||||
|
// As soon as the LED flashing from double click is done, immediately do a tripple click to
|
||||||
|
// erase nvs memory.
|
||||||
|
if (doublepressed > (millis() - 2000)) {
|
||||||
|
DEBUG_MSG("Clearing NVS memory\n");
|
||||||
|
|
||||||
|
// This will erase ble pairings, ssl key and persistent preferences.
|
||||||
|
nvs_flash_erase();
|
||||||
|
|
||||||
|
DEBUG_MSG("Restarting...\n");
|
||||||
|
ESP.restart();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// This routine is called multiple times, once each time we come back from sleep
|
// This routine is called multiple times, once each time we come back from sleep
|
||||||
void reinitBluetooth()
|
void reinitBluetooth()
|
||||||
@@ -556,8 +574,7 @@ void setBluetoothEnable(bool on)
|
|||||||
|
|
||||||
bluetoothOn = on;
|
bluetoothOn = on;
|
||||||
if (on) {
|
if (on) {
|
||||||
if (! isWifiAvailable() )
|
if (!isWifiAvailable()) {
|
||||||
{
|
|
||||||
Serial.printf("Pre BT: %u heap size\n", ESP.getFreeHeap());
|
Serial.printf("Pre BT: %u heap size\n", ESP.getFreeHeap());
|
||||||
// ESP_ERROR_CHECK( heap_trace_start(HEAP_TRACE_LEAKS) );
|
// ESP_ERROR_CHECK( heap_trace_start(HEAP_TRACE_LEAKS) );
|
||||||
reinitBluetooth();
|
reinitBluetooth();
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ void deinitBLE();
|
|||||||
void loopBLE();
|
void loopBLE();
|
||||||
void reinitBluetooth();
|
void reinitBluetooth();
|
||||||
void disablePin();
|
void disablePin();
|
||||||
|
void clearNVS();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A helper function that implements simple read and write handling for a uint32_t
|
* A helper function that implements simple read and write handling for a uint32_t
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
#include "RTC.h"
|
#include "RTC.h"
|
||||||
#include "Router.h"
|
#include "Router.h"
|
||||||
|
#include "airtime.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "mesh-pb-constants.h"
|
#include "mesh-pb-constants.h"
|
||||||
#include "mesh/generated/storeforward.pb.h"
|
#include "mesh/generated/storeforward.pb.h"
|
||||||
@@ -22,20 +23,29 @@ int32_t StoreForwardPlugin::runOnce()
|
|||||||
|
|
||||||
if (radioConfig.preferences.is_router) {
|
if (radioConfig.preferences.is_router) {
|
||||||
|
|
||||||
|
// Send out the message queue.
|
||||||
if (this->busy) {
|
if (this->busy) {
|
||||||
// Send out the message queue.
|
|
||||||
|
|
||||||
// DEBUG_MSG("--- --- --- In busy loop 1 %d\n", this->packetHistoryTXQueue_index);
|
// Only send packets if the channel is less than 25% utilized.
|
||||||
storeForwardPlugin->sendPayload(this->busyTo, this->packetHistoryTXQueue_index);
|
if (airTime->channelUtilizationPercent() < 25) {
|
||||||
|
|
||||||
if (this->packetHistoryTXQueue_index == packetHistoryTXQueue_size) {
|
// DEBUG_MSG("--- --- --- In busy loop 1 %d\n", this->packetHistoryTXQueue_index);
|
||||||
strcpy(this->routerMessage, "** S&F - Done");
|
storeForwardPlugin->sendPayload(this->busyTo, this->packetHistoryTXQueue_index);
|
||||||
storeForwardPlugin->sendMessage(this->busyTo, this->routerMessage);
|
|
||||||
// DEBUG_MSG("--- --- --- In busy loop - Done \n");
|
if (this->packetHistoryTXQueue_index == packetHistoryTXQueue_size) {
|
||||||
this->packetHistoryTXQueue_index = 0;
|
strcpy(this->routerMessage, "** S&F - Done");
|
||||||
this->busy = false;
|
storeForwardPlugin->sendMessage(this->busyTo, this->routerMessage);
|
||||||
|
|
||||||
|
// DEBUG_MSG("--- --- --- In busy loop - Done \n");
|
||||||
|
this->packetHistoryTXQueue_index = 0;
|
||||||
|
this->busy = false;
|
||||||
|
} else {
|
||||||
|
this->packetHistoryTXQueue_index++;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
this->packetHistoryTXQueue_index++;
|
DEBUG_MSG("Channel utilization is too high. Skipping this opportunity to send and will retry later.\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DEBUG_MSG("SF myNodeInfo.bitrate = %f bytes / sec\n", myNodeInfo.bitrate);
|
DEBUG_MSG("SF myNodeInfo.bitrate = %f bytes / sec\n", myNodeInfo.bitrate);
|
||||||
@@ -414,9 +424,6 @@ StoreForwardPlugin::StoreForwardPlugin()
|
|||||||
// Popupate PSRAM with our data structures.
|
// Popupate PSRAM with our data structures.
|
||||||
this->populatePSRAM();
|
this->populatePSRAM();
|
||||||
|
|
||||||
// this->packetTimeMax = 2000;
|
|
||||||
// DEBUG_MSG("SF Time to Transmit maxPacketSize (%d bytes) %d ms\n", maxPacketSize, this->packetTimeMax);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
DEBUG_MSG("Device has less than 1M of PSRAM free. Aborting startup.\n");
|
DEBUG_MSG("Device has less than 1M of PSRAM free. Aborting startup.\n");
|
||||||
DEBUG_MSG("Store & Forward Plugin - Aborting Startup.\n");
|
DEBUG_MSG("Store & Forward Plugin - Aborting Startup.\n");
|
||||||
|
|||||||
@@ -65,7 +65,11 @@ void setCPUFast(bool on)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setCpuFrequencyMhz(on ? 240 : 80);
|
// The Heltec LORA32 V1 runs at 26 MHz base frequency and doesn't react well to switching to 80 MHz...
|
||||||
|
#ifndef ARDUINO_HELTEC_WIFI_LORA_32
|
||||||
|
setCpuFrequencyMhz(on ? 240 : 80);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
#define PIN_BUTTON1 (32 + 10)
|
#define PIN_BUTTON1 (32 + 10)
|
||||||
#define PIN_BUTTON2 (0 + 18) // 0.18 is labeled on the board as RESET but we configure it in the bootloader as a regular GPIO
|
#define PIN_BUTTON2 (0 + 18) // 0.18 is labeled on the board as RESET but we configure it in the bootloader as a regular GPIO
|
||||||
|
#define PIN_BUTTON_TOUCH (0 + 11) // 0.11 is the soft touch button on T-Echo
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Analog pins
|
* Analog pins
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
[VERSION]
|
[VERSION]
|
||||||
major = 1
|
major = 1
|
||||||
minor = 2
|
minor = 2
|
||||||
build = 50
|
build = 52
|
||||||
|
|||||||
Reference in New Issue
Block a user