mirror of
https://github.com/meshtastic/firmware.git
synced 2025-06-21 20:44:47 +00:00
Merge branch 'meshtastic:master' into master
This commit is contained in:
commit
888a8d05c4
32
.github/workflows/main_matrix.yml
vendored
32
.github/workflows/main_matrix.yml
vendored
@ -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"
|
||||
@ -23,22 +23,15 @@ jobs:
|
||||
matrix:
|
||||
include:
|
||||
- board: rak11200
|
||||
- board: tlora-v2
|
||||
- board: tlora-v1
|
||||
- board: tlora_v1_3
|
||||
- board: tlora-v2-1-1.6
|
||||
- board: tbeam
|
||||
- board: heltec-v1
|
||||
- board: heltec-v2.0
|
||||
- board: heltec-v2.1
|
||||
- board: tbeam0.7
|
||||
- board: meshtastic-diy-v1
|
||||
- board: rak4631
|
||||
- board: rak4631_eink
|
||||
- board: t-echo
|
||||
- board: nano-g1
|
||||
- board: station-g1
|
||||
- board: m5stack-core
|
||||
- board: m5stack-coreink
|
||||
- board: tbeam-s3-core
|
||||
# - board: pico
|
||||
@ -96,6 +89,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
|
||||
@ -135,7 +129,7 @@ jobs:
|
||||
- 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 }}
|
||||
@ -151,7 +145,7 @@ jobs:
|
||||
- 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 }}
|
||||
@ -167,7 +161,7 @@ jobs:
|
||||
path: |
|
||||
release/*.bin
|
||||
release/*.elf
|
||||
retention-days: 90
|
||||
retention-days: 30
|
||||
|
||||
build-nrf52:
|
||||
strategy:
|
||||
@ -179,6 +173,7 @@ jobs:
|
||||
- board: rak4631_eink
|
||||
- board: t-echo
|
||||
- board: pca10059_diy_eink
|
||||
- board: feather_diy
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@ -225,7 +220,7 @@ jobs:
|
||||
release/*.uf2
|
||||
release/*.elf
|
||||
release/*.zip
|
||||
retention-days: 90
|
||||
retention-days: 30
|
||||
|
||||
build-rpi2040:
|
||||
strategy:
|
||||
@ -279,7 +274,7 @@ jobs:
|
||||
path: |
|
||||
release/*.uf2
|
||||
release/*.elf
|
||||
retention-days: 90
|
||||
retention-days: 30
|
||||
|
||||
build-native:
|
||||
runs-on: ubuntu-latest
|
||||
@ -338,7 +333,7 @@ jobs:
|
||||
release/meshtasticd_linux_amd64
|
||||
release/device-*.sh
|
||||
release/device-*.bat
|
||||
retention-days: 90
|
||||
retention-days: 30
|
||||
|
||||
after-checks:
|
||||
runs-on: ubuntu-latest
|
||||
@ -369,7 +364,7 @@ jobs:
|
||||
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@v3
|
||||
@ -406,7 +401,7 @@ jobs:
|
||||
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' }}
|
||||
@ -468,7 +463,7 @@ jobs:
|
||||
with:
|
||||
draft: true
|
||||
prerelease: true
|
||||
release_name: Meshtastic Device ${{ steps.version.outputs.version }} Alpha
|
||||
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...
|
||||
@ -504,4 +499,3 @@ jobs:
|
||||
with:
|
||||
add-paths: |
|
||||
version.properties
|
||||
|
||||
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -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
15
Dockerfile
Normal 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'"
|
@ -1,8 +1,8 @@
|
||||
# Meshtastic Firmware
|
||||
|
||||

|
||||
[](https://github.com/meshtastic/repo/actions/workflows/main_matrix.yml)
|
||||
[](https://cla-assistant.io/meshtastic/Meshtastic-device)
|
||||

|
||||
[](https://github.com/meshtastic/firmware/actions/workflows/main_matrix.yml)
|
||||
[](https://cla-assistant.io/meshtastic/firmware)
|
||||
[](https://opencollective.com/meshtastic/)
|
||||
[](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
|
||||
|
||||

|
||||

|
||||
|
@ -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
|
||||
|
@ -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 =
|
||||
|
@ -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
|
||||
|
||||
|
@ -8,6 +8,7 @@ build_src_filter =
|
||||
-<platform/stm32wl/>
|
||||
-<platform/rp2040>
|
||||
-<mesh/http/>
|
||||
-<mesh/eth/>
|
||||
-<modules/esp32>
|
||||
-<modules/Telemetry>
|
||||
+<../variants/portduino>
|
||||
|
@ -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 =
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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.*
|
||||
|
@ -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
|
||||
|
@ -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.*
|
||||
|
@ -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.*
|
||||
|
@ -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"
|
||||
|
@ -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
13
docker-compose.yml
Normal file
@ -0,0 +1,13 @@
|
||||
version: "3.7"
|
||||
|
||||
services:
|
||||
meshtastic-node:
|
||||
build: .
|
||||
deploy:
|
||||
mode: replicated
|
||||
replicas: 80
|
||||
networks:
|
||||
- mesh
|
||||
|
||||
networks:
|
||||
mesh:
|
@ -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
|
||||
|
||||
@ -58,8 +59,8 @@ lib_deps =
|
||||
check_tool = cppcheck
|
||||
check_skip_packages = yes
|
||||
check_flags =
|
||||
--common-flag
|
||||
cppcheck: --enable=--inline-suppr
|
||||
-DAPP_VERSION=1.0.0
|
||||
--suppressions-list=suppressions.txt
|
||||
|
||||
; Common settings for conventional (non Portduino) Arduino targets
|
||||
[arduino_base]
|
||||
@ -68,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
|
||||
@ -79,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
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit d0559bfa3c31023ed2f2aa3807b6a0a1da9a6feb
|
||||
Subproject commit 5b892e4c196f8620f2009cdef219eb2c237cc636
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
@ -44,11 +44,9 @@ 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) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,6 +142,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#ifndef HAS_WIFI
|
||||
#define HAS_WIFI 0
|
||||
#endif
|
||||
#ifndef HAS_ETHERNET
|
||||
#define HAS_ETHERNET 0
|
||||
#endif
|
||||
#ifndef HAS_SCREEN
|
||||
#define HAS_SCREEN 0
|
||||
#endif
|
||||
@ -163,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"
|
||||
|
@ -15,11 +15,11 @@
|
||||
* -------------------------------------------
|
||||
*/
|
||||
|
||||
uint printWPL(char *buf, const Position &pos, const char *name)
|
||||
uint32_t printWPL(char *buf, const Position &pos, const char *name)
|
||||
{
|
||||
uint len = sprintf(buf, "$GNWPL,%07.2f,%c,%08.2f,%c,%s", pos.latitude_i * 1e-5, pos.latitude_i < 0 ? 'S' : 'N', pos.longitude_i * 1e-5, pos.longitude_i < 0 ? 'W' : 'E', name);
|
||||
uint chk = 0;
|
||||
for (uint i = 1; i < len; i++) {
|
||||
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);
|
||||
@ -50,9 +50,9 @@ uint printWPL(char *buf, const Position &pos, const char *name)
|
||||
* -------------------------------------------
|
||||
*/
|
||||
|
||||
uint printGGA(char *buf, const Position &pos)
|
||||
uint32_t printGGA(char *buf, const Position &pos)
|
||||
{
|
||||
uint len = sprintf(buf, "$GNGGA,%06u.%03u,%07.2f,%c,%08.2f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d",
|
||||
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',
|
||||
@ -67,8 +67,8 @@ uint printGGA(char *buf, const Position &pos)
|
||||
0,
|
||||
0);
|
||||
|
||||
uint chk = 0;
|
||||
for (uint i = 1; i < len; i++) {
|
||||
uint32_t chk = 0;
|
||||
for (uint32_t i = 1; i < len; i++) {
|
||||
chk ^= buf[i];
|
||||
}
|
||||
len += sprintf(buf + len, "*%02X\r\n", chk);
|
||||
|
@ -3,5 +3,5 @@
|
||||
#include <Arduino.h>
|
||||
#include "main.h"
|
||||
|
||||
uint printWPL(char *buf, const Position &pos, const char *name);
|
||||
uint printGGA(char *buf, const Position &pos);
|
||||
uint32_t printWPL(char *buf, const Position &pos, const char *name);
|
||||
uint32_t printGGA(char *buf, const Position &pos);
|
||||
|
@ -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,7 +46,7 @@ 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
|
||||
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
{
|
||||
|
||||
@ -68,6 +66,8 @@ 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};
|
||||
|
||||
@ -944,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]);
|
||||
@ -1012,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;
|
||||
}
|
||||
}
|
||||
@ -1390,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
|
||||
|
||||
@ -1399,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"));
|
||||
@ -1424,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 {
|
||||
@ -1509,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 */
|
||||
|
@ -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});
|
||||
}
|
||||
|
48
src/main.cpp
48
src/main.cpp
@ -30,22 +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 "SX1281Interface.h"
|
||||
#include "SX1280Interface.h"
|
||||
#if !HAS_RADIO && defined(ARCH_PORTDUINO)
|
||||
#include "platform/portduino/SimRadio.h"
|
||||
#endif
|
||||
@ -191,8 +197,6 @@ void setup()
|
||||
digitalWrite(RESET_OLED, 1);
|
||||
#endif
|
||||
|
||||
bool forceSoftAP = 0;
|
||||
|
||||
#ifdef BUTTON_PIN
|
||||
#ifdef ARCH_ESP32
|
||||
|
||||
@ -205,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
|
||||
|
||||
@ -242,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()
|
||||
// In T-Beam-S3-core, the I2C device cannot be scanned before power initialization, otherwise the device will be stuck
|
||||
if ((HW_VENDOR != HardwareModel_LILYGO_TBEAM_S3_CORE)) {
|
||||
@ -276,11 +280,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);
|
||||
@ -293,6 +298,10 @@ void setup()
|
||||
*/
|
||||
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();
|
||||
#ifndef ARCH_ESP32
|
||||
@ -371,15 +380,15 @@ void setup()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USE_SX1281) && !defined(ARCH_PORTDUINO)
|
||||
#if defined(USE_SX1280) && !defined(ARCH_PORTDUINO)
|
||||
if (!rIf) {
|
||||
rIf = new SX1281Interface(SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY, SPI);
|
||||
rIf = new SX1280Interface(SX128X_CS, SX128X_DIO1, SX128X_RESET, SX128X_BUSY, SPI);
|
||||
if (!rIf->init()) {
|
||||
DEBUG_MSG("Warning: Failed to find SX1281 radio\n");
|
||||
DEBUG_MSG("Warning: Failed to find SX1280 radio\n");
|
||||
delete rIf;
|
||||
rIf = NULL;
|
||||
} else {
|
||||
DEBUG_MSG("SX1281 Radio init succeeded, using SX1281 radio\n");
|
||||
DEBUG_MSG("SX1280 Radio init succeeded, using SX1280 radio\n");
|
||||
rIf_wide_lora = true;
|
||||
}
|
||||
}
|
||||
@ -437,12 +446,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.
|
||||
|
@ -79,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;
|
||||
@ -218,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";
|
||||
@ -247,6 +245,10 @@ const char *Channels::getName(size_t chIndex)
|
||||
channelName = "Invalid";
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
channelName = "Custom";
|
||||
}
|
||||
}
|
||||
|
||||
return channelName;
|
||||
@ -265,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()
|
||||
{
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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
|
||||
|
@ -9,5 +9,5 @@ template class SX126xInterface<SX1268>;
|
||||
template class SX126xInterface<LLCC68>;
|
||||
|
||||
#if !defined(ARCH_PORTDUINO)
|
||||
template class SX128xInterface<SX1281>;
|
||||
template class SX128xInterface<SX1280>;
|
||||
#endif
|
@ -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!
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -361,7 +361,7 @@ 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:
|
||||
@ -416,7 +416,7 @@ 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)
|
||||
@ -460,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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -1,10 +1,10 @@
|
||||
#include "configuration.h"
|
||||
#include "SX1281Interface.h"
|
||||
#include "SX1280Interface.h"
|
||||
#include "error.h"
|
||||
|
||||
#if !defined(ARCH_PORTDUINO)
|
||||
|
||||
SX1281Interface::SX1281Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
|
||||
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)
|
||||
{
|
@ -3,15 +3,15 @@
|
||||
#include "SX128xInterface.h"
|
||||
|
||||
/**
|
||||
* Our adapter for SX1281 radios
|
||||
* Our adapter for SX1280 radios
|
||||
*/
|
||||
|
||||
#if !defined(ARCH_PORTDUINO)
|
||||
|
||||
class SX1281Interface : public SX128xInterface<SX1281>
|
||||
class SX1280Interface : public SX128xInterface<SX1280>
|
||||
{
|
||||
public:
|
||||
SX1281Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi);
|
||||
SX1280Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi);
|
||||
};
|
||||
|
||||
#endif
|
@ -6,7 +6,7 @@
|
||||
|
||||
/**
|
||||
* \brief Adapter for SX128x radio family. Implements common logic for child classes.
|
||||
* \tparam T RadioLib module type for SX128x: SX1281.
|
||||
* \tparam T RadioLib module type for SX128x: SX1280.
|
||||
*/
|
||||
template<class T>
|
||||
class SX128xInterface : public RadioLibInterface
|
||||
|
148
src/mesh/eth/ethClient.cpp
Normal file
148
src/mesh/eth/ethClient.cpp
Normal 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
8
src/mesh/eth/ethClient.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "configuration.h"
|
||||
#include <Arduino.h>
|
||||
#include <functional>
|
||||
|
||||
bool initEthernet();
|
||||
bool isEthernetAvailable();
|
82
src/mesh/eth/ethServerAPI.cpp
Normal file
82
src/mesh/eth/ethServerAPI.cpp
Normal 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
|
||||
}
|
58
src/mesh/eth/ethServerAPI.h
Normal file
58
src/mesh/eth/ethServerAPI.h
Normal 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);
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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,
|
||||
@ -104,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 {
|
||||
@ -122,13 +128,12 @@ typedef struct _Config_LoRaConfig {
|
||||
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;
|
||||
@ -151,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 {
|
||||
@ -174,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
|
||||
@ -186,6 +202,10 @@ 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_LORA_24
|
||||
#define _Config_LoRaConfig_RegionCode_ARRAYSIZE ((Config_LoRaConfig_RegionCode)(Config_LoRaConfig_RegionCode_LORA_24+1))
|
||||
@ -208,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}
|
||||
|
||||
@ -234,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
|
||||
@ -246,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
|
||||
@ -266,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
|
||||
@ -325,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) \
|
||||
@ -338,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
|
||||
|
||||
@ -370,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;
|
||||
@ -380,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
|
||||
@ -387,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_DisplayConfig_size 22
|
||||
#define Config_LoRaConfig_size 68
|
||||
#define Config_NetworkConfig_size 137
|
||||
#define Config_NetworkConfig_IpV4Config_size 20
|
||||
#define Config_NetworkConfig_size 161
|
||||
#define Config_PositionConfig_size 30
|
||||
#define Config_PowerConfig_size 43
|
||||
#define Config_size 140
|
||||
#define Config_size 164
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -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" */
|
||||
|
@ -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 335
|
||||
#define LocalModuleConfig_size 270
|
||||
#define LocalConfig_size 361
|
||||
#define LocalModuleConfig_size 294
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
@ -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/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/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
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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,
|
||||
@ -49,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;
|
||||
@ -131,11 +151,17 @@ 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))
|
||||
@ -156,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}
|
||||
@ -164,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}
|
||||
@ -172,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
|
||||
@ -222,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) \
|
||||
@ -231,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
|
||||
@ -241,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) \
|
||||
@ -252,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) \
|
||||
@ -315,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;
|
||||
@ -325,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
|
||||
@ -333,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
|
||||
|
@ -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,
|
||||
|
@ -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,8 +73,8 @@ 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);
|
||||
@ -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);
|
||||
@ -121,8 +119,8 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
|
||||
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);
|
||||
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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,8 +33,6 @@ 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
|
||||
@ -88,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;
|
||||
@ -161,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 {
|
||||
@ -286,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:
|
||||
@ -300,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");
|
||||
@ -315,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:
|
||||
@ -356,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;
|
||||
|
@ -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();
|
||||
|
@ -295,6 +295,11 @@ 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);
|
||||
@ -421,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.
|
||||
@ -441,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;
|
||||
|
@ -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.
|
||||
@ -131,29 +129,36 @@ ExternalNotificationModule::ExternalNotificationModule()
|
||||
// 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
|
||||
}
|
||||
|
@ -12,6 +12,8 @@
|
||||
*/
|
||||
class ExternalNotificationModule : public SinglePortModule, private concurrency::OSThread
|
||||
{
|
||||
uint32_t output = 0;
|
||||
|
||||
public:
|
||||
ExternalNotificationModule();
|
||||
|
||||
|
@ -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"
|
||||
@ -65,17 +68,16 @@ void setupModules()
|
||||
#endif
|
||||
#ifdef ARCH_ESP32
|
||||
// Only run on an esp32 based device.
|
||||
|
||||
/*
|
||||
Maintained by MC Hamster (Jm Casler) jm@casler.org
|
||||
*/
|
||||
#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
|
||||
|
@ -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;
|
||||
|
@ -15,24 +15,18 @@ int32_t BME680Sensor::runOnce() {
|
||||
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
|
||||
}
|
||||
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;
|
||||
}
|
@ -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;
|
||||
|
||||
|
240
src/modules/esp32/AudioModule.cpp
Normal file
240
src/modules/esp32/AudioModule.cpp
Normal 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
|
68
src/modules/esp32/AudioModule.h
Normal file
68
src/modules/esp32/AudioModule.h
Normal 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;
|
||||
|
@ -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>
|
||||
|
||||
@ -67,22 +69,25 @@ void MQTT::onPublish(char *topic, byte *payload, unsigned int length)
|
||||
DEBUG_MSG("Invalid MQTT service envelope, topic %s, len %u!\n", topic, length);
|
||||
}
|
||||
} else {
|
||||
pb_decode_from_bytes(payload, length, ServiceEnvelope_fields, &e);
|
||||
if (strcmp(e.gateway_id, owner.id) == 0)
|
||||
DEBUG_MSG("Ignoring downlink message we originally sent.\n");
|
||||
else {
|
||||
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);
|
||||
@ -105,6 +110,11 @@ MQTT::MQTT() : concurrency::OSThread("mqtt"), pubSub(mqttClient)
|
||||
// preflightSleepObserver.observe(&preflightSleep);
|
||||
}
|
||||
|
||||
bool MQTT::connected()
|
||||
{
|
||||
return pubSub.connected();
|
||||
}
|
||||
|
||||
void MQTT::reconnect()
|
||||
{
|
||||
if (wantsLink()) {
|
||||
@ -189,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()
|
||||
@ -346,9 +362,9 @@ std::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");
|
||||
@ -371,8 +387,8 @@ std::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");
|
||||
|
@ -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
|
||||
@ -39,6 +49,8 @@ class MQTT : private concurrency::OSThread
|
||||
*/
|
||||
void reconnect();
|
||||
|
||||
bool connected();
|
||||
|
||||
protected:
|
||||
virtual int32_t runOnce() override;
|
||||
|
||||
|
27
src/network-stubs.cpp
Normal file
27
src/network-stubs.cpp
Normal 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
|
@ -12,7 +12,6 @@ NimBLECharacteristic *fromNumCharacteristic;
|
||||
NimBLEServer *bleServer;
|
||||
|
||||
static bool passkeyShowing;
|
||||
static uint32_t doublepressed;
|
||||
|
||||
class BluetoothPhoneAPI : public PhoneAPI
|
||||
{
|
||||
@ -72,11 +71,7 @@ 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();
|
||||
}
|
||||
|
@ -15,4 +15,3 @@ class NimbleBluetooth
|
||||
|
||||
void setBluetoothEnable(bool on);
|
||||
void clearNVS();
|
||||
void disablePin();
|
||||
|
@ -70,6 +70,8 @@
|
||||
#define HW_VENDOR HardwareModel_TLORA_V1_1P3
|
||||
#elif defined(TLORA_V2_1_16)
|
||||
#define HW_VENDOR HardwareModel_TLORA_V2_1_1P6
|
||||
#elif defined(TLORA_V2_1_18)
|
||||
#define HW_VENDOR HardwareModel_TLORA_V2_1_1P8
|
||||
#elif defined(GENIEBLOCKS)
|
||||
#define HW_VENDOR HardwareModel_GENIEBLOCKS
|
||||
#elif defined(PRIVATE_HW)
|
||||
@ -80,6 +82,8 @@
|
||||
#define HW_VENDOR HardwareModel_M5STACK
|
||||
#elif defined(STATION_G1)
|
||||
#define HW_VENDOR HardwareModel_STATION_G1
|
||||
#elif defined(DR_DEV)
|
||||
#define HW_VENDOR HardwareModel_DR_DEV
|
||||
#endif
|
||||
|
||||
//
|
||||
|
@ -26,6 +26,9 @@
|
||||
#ifndef HAS_RADIO
|
||||
#define HAS_RADIO 1
|
||||
#endif
|
||||
#ifdef HAS_CPU_SHUTDOWN
|
||||
#define HAS_CPU_SHUTDOWN 1
|
||||
#endif
|
||||
|
||||
//
|
||||
// set HW_VENDOR
|
||||
@ -42,7 +45,7 @@
|
||||
#define HW_VENDOR HardwareModel_T_ECHO
|
||||
#elif defined(NORDIC_PCA10059)
|
||||
#define HW_VENDOR HardwareModel_NRF52840_PCA10059
|
||||
#elif defined(PRIVATE_HW)
|
||||
#elif defined(PRIVATE_HW) || defined(FEATHER_DIY)
|
||||
#define HW_VENDOR HardwareModel_PRIVATE_HW
|
||||
#else
|
||||
#define HW_VENDOR HardwareModel_NRF52_UNKNOWN
|
||||
|
@ -13,11 +13,12 @@ void powerCommandsCheck()
|
||||
#elif defined(ARCH_NRF52)
|
||||
NVIC_SystemReset();
|
||||
#else
|
||||
DEBUG_MSG("FIXME implement reboot for this platform");
|
||||
rebootAtMsec = -1;
|
||||
DEBUG_MSG("FIXME implement reboot for this platform. Skipping for now.\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(ARCH_NRF52)
|
||||
#if defined(ARCH_NRF52) || defined(HAS_PMU)
|
||||
if (shutdownAtMsec) {
|
||||
screen->startShutdownScreen();
|
||||
playBeep();
|
||||
|
@ -263,8 +263,8 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r
|
||||
#ifdef BUTTON_PIN
|
||||
gpio_wakeup_enable((gpio_num_t)BUTTON_PIN, GPIO_INTR_LOW_LEVEL); // when user presses, this button goes low
|
||||
#endif
|
||||
#ifdef RF95_IRQ_GPIO
|
||||
gpio_wakeup_enable((gpio_num_t)RF95_IRQ_GPIO, GPIO_INTR_HIGH_LEVEL); // RF95 interrupt, active high
|
||||
#ifdef RF95_IRQ
|
||||
gpio_wakeup_enable((gpio_num_t)RF95_IRQ, GPIO_INTR_HIGH_LEVEL); // RF95 interrupt, active high
|
||||
#endif
|
||||
#ifdef PMU_IRQ
|
||||
// wake due to PMU can happen repeatedly if there is no battery installed or the battery fills
|
||||
|
@ -1,19 +0,0 @@
|
||||
//#include "mesh/wifi/WebServer.h"
|
||||
#include "configuration.h"
|
||||
|
||||
#ifndef ARCH_ESP32
|
||||
|
||||
//#include "mesh/wifi/WiFiAPClient.h"
|
||||
|
||||
bool initWifi(bool forceSoftAP) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void deinitWifi() {}
|
||||
|
||||
bool isWifiAvailable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
71
variants/diy/dr-dev/variant.h
Normal file
71
variants/diy/dr-dev/variant.h
Normal file
@ -0,0 +1,71 @@
|
||||
// Initialize i2c bus on sd_dat and esp_led pins, respectively. We need a bus to not hang on boot
|
||||
#define HAS_SCREEN 0
|
||||
#define I2C_SDA 4
|
||||
#define I2C_SCL 5
|
||||
|
||||
// GPS
|
||||
#undef GPS_RX_PIN
|
||||
#define GPS_RX_PIN NOT_A_PIN
|
||||
#define HAS_GPS 0
|
||||
|
||||
#define BUTTON_PIN 13 // The middle button GPIO on the T-Beam
|
||||
#define BUTTON_NEED_PULLUP
|
||||
#define EXT_NOTIFY_OUT 12 // Overridden default pin to use for Ext Notify Module (#975).
|
||||
|
||||
#define LORA_DIO0 NOT_A_PIN // a No connect on the SX1262/SX1268 module
|
||||
#define LORA_RESET NOT_A_PIN // RST for SX1276, and for SX1262/SX1268
|
||||
#define LORA_DIO3 NOT_A_PIN // Not connected on PCB, but internally on the SX1262/SX1268, if DIO3 is high the TXCO is enabled
|
||||
|
||||
// In transmitting, set TXEN as high communication level,RXEN pin is low level;
|
||||
// In receiving, set RXEN as high communication level, TXEN is lowlevel;
|
||||
// Before powering off, set TXEN、RXEN as low level.
|
||||
|
||||
#undef RF95_SCK
|
||||
#define RF95_SCK 18
|
||||
#undef RF95_MISO
|
||||
#define RF95_MISO 19
|
||||
#undef RF95_MOSI
|
||||
#define RF95_MOSI 23
|
||||
|
||||
// PINS FOR THE 900M22S
|
||||
|
||||
#define LORA_DIO1 26 // IRQ for SX1262/SX1268
|
||||
#define LORA_DIO2 22 // BUSY for SX1262/SX1268
|
||||
#define LORA_TXEN NOT_A_PIN // Input - RF switch TX control, connecting external MCU IO or DIO2, valid in high level
|
||||
#define LORA_RXEN 17 // Input - RF switch RX control, connecting external MCU IO, valid in high level
|
||||
#undef RF95_NSS
|
||||
#define RF95_NSS 16
|
||||
#define SX126X_BUSY 22
|
||||
#define SX126X_CS 16
|
||||
|
||||
|
||||
// PINS FOR THE 900M30S
|
||||
/*
|
||||
#define LORA_DIO1 27 // IRQ for SX1262/SX1268
|
||||
#define LORA_DIO2 35 // BUSY for SX1262/SX1268
|
||||
#define LORA_TXEN NOT_A_PIN // Input - RF switch TX control, connecting external MCU IO or DIO2, valid in high level
|
||||
#define LORA_RXEN 21 // Input - RF switch RX control, connecting external MCU IO, valid in high level
|
||||
#undef RF95_NSS
|
||||
#define RF95_NSS 33
|
||||
#define SX126X_BUSY 35
|
||||
#define SX126X_CS 33
|
||||
*/
|
||||
|
||||
// RX/TX for RFM95/SX127x
|
||||
#define RF95_RXEN LORA_RXEN
|
||||
#define RF95_TXEN LORA_TXEN
|
||||
// #define RF95_TCXO <GPIO#>
|
||||
|
||||
// common pinouts for SX126X modules
|
||||
|
||||
#define SX126X_DIO1 LORA_DIO1
|
||||
#define SX126X_RESET LORA_RESET
|
||||
#define SX126X_RXEN LORA_RXEN
|
||||
#define SX126X_TXEN LORA_TXEN
|
||||
|
||||
// supported modules list
|
||||
//#define USE_RF95 // RFM95/SX127x
|
||||
#define USE_SX1262
|
||||
//#define USE_SX1268
|
||||
//#define USE_LLCC68
|
||||
#define SX126X_E22
|
11
variants/feather_diy/platformio.ini
Normal file
11
variants/feather_diy/platformio.ini
Normal file
@ -0,0 +1,11 @@
|
||||
; The very slick RAK wireless RAK 4631 / 4630 board - Unified firmware for 5005/19003, with or without OLED RAK 1921
|
||||
[env:feather_diy]
|
||||
extends = nrf52840_base
|
||||
board = adafruit_feather_nrf52840
|
||||
build_flags = ${nrf52840_base.build_flags} -Ivariants/feather_diy -Dfeather_diy
|
||||
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/feather_diy>
|
||||
lib_deps =
|
||||
${nrf52840_base.lib_deps}
|
||||
debug_tool = jlink
|
||||
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
|
||||
;upload_protocol = jlink
|
24
variants/feather_diy/variant.cpp
Normal file
24
variants/feather_diy/variant.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
|
||||
Copyright (c) 2016 Sandeep Mistry All right reserved.
|
||||
Copyright (c) 2018, Adafruit Industries (adafruit.com)
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "variant.h"
|
||||
#include "nrf.h"
|
||||
#include "wiring_constants.h"
|
||||
#include "wiring_digital.h"
|
119
variants/feather_diy/variant.h
Normal file
119
variants/feather_diy/variant.h
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
|
||||
Copyright (c) 2016 Sandeep Mistry All right reserved.
|
||||
Copyright (c) 2018, Adafruit Industries (adafruit.com)
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Lesser General Public License for more details.
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _VARIANT_FEATHER_DIY_
|
||||
#define _VARIANT_FEATHER_DIY_
|
||||
|
||||
/** Master clock frequency */
|
||||
#define VARIANT_MCK (64000000ul)
|
||||
|
||||
#define USE_LFXO // Board uses 32khz crystal for LF
|
||||
// define USE_LFRC // Board uses RC for LF
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "WVariant.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
// Number of pins defined in PinDescription array
|
||||
#define PINS_COUNT (48)
|
||||
#define NUM_DIGITAL_PINS (48)
|
||||
#define NUM_ANALOG_INPUTS (6)
|
||||
#define NUM_ANALOG_OUTPUTS (0)
|
||||
|
||||
#define WIRE_INTERFACES_COUNT 1
|
||||
|
||||
#define PIN_WIRE_SDA (0 + 12) //P0.12 22
|
||||
#define PIN_WIRE_SCL (0 + 11) //P0.12 23
|
||||
|
||||
#define PIN_LED1 (32 + 15) //P1.15 3
|
||||
#define PIN_LED2 (32 + 10) //P1.10 4
|
||||
|
||||
#define LED_BUILTIN PIN_LED1
|
||||
|
||||
#define LED_GREEN PIN_LED2 // Actually red
|
||||
#define LED_BLUE PIN_LED1
|
||||
|
||||
#define LED_STATE_ON 1 // State when LED is litted
|
||||
|
||||
#define BUTTON_PIN (32 + 2) //P1.02 7
|
||||
|
||||
/*
|
||||
* Serial interfaces
|
||||
*/
|
||||
#define PIN_SERIAL1_RX (0 + 24) //P0.24 1
|
||||
#define PIN_SERIAL1_TX (0 + 25) //P0.25 0
|
||||
|
||||
#define PIN_SERIAL2_RX (-1)
|
||||
#define PIN_SERIAL2_TX (-1)
|
||||
|
||||
#define SPI_INTERFACES_COUNT 1
|
||||
|
||||
#define PIN_SPI_MISO (0 + 15) //P0.15 24
|
||||
#define PIN_SPI_MOSI (0 + 13) //P0.13 25
|
||||
#define PIN_SPI_SCK (0 + 14) //P0.14 26
|
||||
|
||||
#define SS 2
|
||||
|
||||
#define LORA_DIO0 -1 // a No connect on the SX1262/SX1268 module
|
||||
#define LORA_RESET (32 + 9) //P1.09 13 // RST for SX1276, and for SX1262/SX1268
|
||||
#define LORA_DIO1 (0 + 6) //P0.06 11 // IRQ for SX1262/SX1268
|
||||
#define LORA_DIO2 (0 + 8) //P0.08 12 // BUSY for SX1262/SX1268
|
||||
#define LORA_DIO3 // Not connected on PCB, but internally on the TTGO SX1262/SX1268, if DIO3 is high the TXCO is enabled
|
||||
|
||||
#define RF95_SCK SCK
|
||||
#define RF95_MISO MI
|
||||
#define RF95_MOSI MO
|
||||
#define RF95_NSS SS
|
||||
|
||||
// enables 3.3V periphery like GPS or IO Module
|
||||
#define PIN_3V3_EN (-1)
|
||||
|
||||
#undef USE_EINK
|
||||
|
||||
// supported modules list
|
||||
#define USE_SX1262
|
||||
|
||||
// common pinouts for SX126X modules
|
||||
#define SX126X_CS RF95_NSS // NSS for SX126X
|
||||
#define SX126X_DIO1 LORA_DIO1
|
||||
#define SX126X_BUSY LORA_DIO2
|
||||
#define SX126X_RESET LORA_RESET
|
||||
#define SX126X_RXEN (0 + 27) //P0.27 10
|
||||
#define SX126X_TXEN (0 + 26) //P0.26 9
|
||||
|
||||
#ifdef EBYTE_E22
|
||||
// Internally the TTGO module hooks the SX126x-DIO2 in to control the TX/RX switch
|
||||
// (which is the default for the sx1262interface code)
|
||||
#define SX126X_E22
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Arduino objects - C++ only
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#endif
|
@ -3,10 +3,12 @@
|
||||
extends = nrf52840_base
|
||||
board = wiscore_rak4631
|
||||
build_flags = ${nrf52840_base.build_flags} -Ivariants/rak4631 -D RAK_4631
|
||||
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/rak4631>
|
||||
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/rak4631> +<mesh/eth/> +<mqtt/>
|
||||
lib_deps =
|
||||
${nrf52840_base.lib_deps}
|
||||
${networking_base.lib_deps}
|
||||
melopero/Melopero RV3028@^1.1.0
|
||||
https://github.com/meshtastic/RAK13800-W5100S.git#b680706eb8006cd62c919ac74c8af1950eb82c81
|
||||
debug_tool = jlink
|
||||
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
|
||||
;upload_protocol = jlink
|
@ -185,6 +185,9 @@ static const uint8_t SCK = PIN_SPI_SCK;
|
||||
#define SX126X_RXEN (37)
|
||||
#define SX126X_E22 // DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
|
||||
|
||||
// enables 3.3V periphery like GPS or IO Module
|
||||
#define PIN_3V3_EN (34)
|
||||
|
||||
// RAK1910 GPS module
|
||||
// If using the wisblock GPS module and pluged into Port A on WisBlock base
|
||||
// IO1 is hooked to PPS (pin 12 on header) = gpio 17
|
||||
@ -192,7 +195,7 @@ static const uint8_t SCK = PIN_SPI_SCK;
|
||||
// Therefore must be 1 to keep peripherals powered
|
||||
// Power is on the controllable 3V3_S rail
|
||||
// #define PIN_GPS_RESET (34)
|
||||
#define PIN_GPS_EN (34)
|
||||
#define PIN_GPS_EN PIN_3V3_EN
|
||||
#define PIN_GPS_PPS (17) // Pulse per second input from the GPS
|
||||
|
||||
#define GPS_RX_PIN PIN_SERIAL1_RX
|
||||
@ -226,6 +229,12 @@ static const uint8_t SCK = PIN_SPI_SCK;
|
||||
|
||||
#define HAS_RTC 1
|
||||
|
||||
#define HAS_ETHERNET 1
|
||||
|
||||
#define PIN_ETHERNET_RESET 21
|
||||
#define PIN_ETHERNET_SS PIN_EINK_CS
|
||||
#define ETH_SPI_PORT SPI1
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -185,6 +185,9 @@ static const uint8_t SCK = PIN_SPI_SCK;
|
||||
#define SX126X_RXEN (37)
|
||||
#define SX126X_E22 // DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
|
||||
|
||||
// enables 3.3V periphery like GPS or IO Module
|
||||
#define PIN_3V3_EN (34)
|
||||
|
||||
// RAK1910 GPS module
|
||||
// If using the wisblock GPS module and pluged into Port A on WisBlock base
|
||||
// IO1 is hooked to PPS (pin 12 on header) = gpio 17
|
||||
@ -192,7 +195,7 @@ static const uint8_t SCK = PIN_SPI_SCK;
|
||||
// Therefore must be 1 to keep peripherals powered
|
||||
// Power is on the controllable 3V3_S rail
|
||||
// #define PIN_GPS_RESET (34)
|
||||
#define PIN_GPS_EN (34)
|
||||
#define PIN_GPS_EN PIN_3V3_EN
|
||||
#define PIN_GPS_PPS (17) // Pulse per second input from the GPS
|
||||
|
||||
#define GPS_RX_PIN PIN_SERIAL1_RX
|
||||
|
@ -8,8 +8,6 @@
|
||||
#define I2C_SDA 21 // I2C pins for this board
|
||||
#define I2C_SCL 22
|
||||
|
||||
#define RESET_OLED 16 // If defined, this pin will be used to reset the display controller
|
||||
|
||||
#define VEXT_ENABLE 21 // active low, powers the oled display and the lora antenna boost
|
||||
#define LED_PIN 25 // If defined we will blink this LED
|
||||
#define BUTTON_PIN \
|
||||
|
8
variants/tlora_v2_1_18/platformio.ini
Normal file
8
variants/tlora_v2_1_18/platformio.ini
Normal file
@ -0,0 +1,8 @@
|
||||
[env:tlora-v2-1-1.8]
|
||||
extends = esp32_base
|
||||
board = ttgo-lora32-v21
|
||||
lib_deps =
|
||||
${esp32_base.lib_deps}
|
||||
caveman99/ESP32 Codec2@^1.0.1
|
||||
build_flags =
|
||||
${esp32_base.build_flags} -D TLORA_V2_1_18 -I variants/tlora_v2_1_18
|
33
variants/tlora_v2_1_18/variant.h
Normal file
33
variants/tlora_v2_1_18/variant.h
Normal file
@ -0,0 +1,33 @@
|
||||
#undef GPS_RX_PIN
|
||||
#undef GPS_TX_PIN
|
||||
#define GPS_RX_PIN 15 // per @der_bear on the forum, 36 is incorrect for this board type and 15 is a better pick
|
||||
#define GPS_TX_PIN 13
|
||||
|
||||
#define EXT_NOTIFY_OUT 2 // Default pin to use for Ext Notify Module.
|
||||
|
||||
#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
|
||||
// ratio of voltage divider = 2.0 (R42=100k, R43=100k)
|
||||
#define ADC_MULTIPLIER 2.11 // 2.0 + 10% for correction of display undervoltage.
|
||||
|
||||
#define I2C_SDA 21 // I2C pins for this board
|
||||
#define I2C_SCL 22
|
||||
|
||||
// #define RESET_OLED 16 // If defined, this pin will be used to reset the display controller. Crashes on newer ESP-IDF and not needed per schematic
|
||||
|
||||
#define VEXT_ENABLE 21 // active low, powers the oled display and the lora antenna boost
|
||||
#define LED_PIN 25 // If defined we will blink this LED
|
||||
#define BUTTON_PIN 12 // If defined, this will be used for user button presses,
|
||||
|
||||
#define BUTTON_NEED_PULLUP
|
||||
|
||||
#define USE_SX1280
|
||||
#define LORA_DIO0 26 // a No connect on the SX1262 module
|
||||
#define LORA_RESET 23
|
||||
|
||||
#define SX128X_CS 18 // FIXME - we really should define LORA_CS instead
|
||||
#define SX128X_DIO1 33
|
||||
#define SX128X_BUSY 32
|
||||
#define SX128X_RESET LORA_RESET
|
||||
#define SX128X_E22 // Not really an E22 but TTGO seems to be trying to clone that
|
||||
// Internally the TTGO module hooks the SX1280-DIO2 in to control the TX/RX switch (which is the default for the sx1280interface
|
||||
// code)
|
@ -1,4 +1,4 @@
|
||||
[VERSION]
|
||||
major = 1
|
||||
minor = 3
|
||||
build = 47
|
||||
major = 2
|
||||
minor = 0
|
||||
build = 3
|
||||
|
Loading…
Reference in New Issue
Block a user