Compare commits

...

19 Commits

Author SHA1 Message Date
Ben Meadors
77f1998524
Merge branch 'master' into master 2025-03-20 15:04:15 -05:00
Mike
31c0e8fa2c
Support WiFi OTA (#6352)
Some checks failed
CI / build-esp32-c3 (push) Blocked by required conditions
CI / build-esp32-c6 (push) Blocked by required conditions
CI / build-nrf52 (push) Blocked by required conditions
CI / build-rpi2040 (push) Blocked by required conditions
CI / build-stm32 (push) Blocked by required conditions
CI / build-debian-src (push) Waiting to run
CI / package-pio-deps-native-tft (push) Waiting to run
CI / test-native (push) Waiting to run
CI / docker-debian-amd64 (push) Waiting to run
CI / docker-alpine-amd64 (push) Waiting to run
CI / docker-debian-arm64 (push) Waiting to run
CI / docker-debian-armv7 (push) Waiting to run
CI / after-checks (push) Blocked by required conditions
CI / gather-artifacts (esp32) (push) Blocked by required conditions
CI / gather-artifacts (esp32c3) (push) Blocked by required conditions
CI / gather-artifacts (esp32c6) (push) Blocked by required conditions
CI / gather-artifacts (esp32s3) (push) Blocked by required conditions
CI / gather-artifacts (nrf52840) (push) Blocked by required conditions
CI / gather-artifacts (rp2040) (push) Blocked by required conditions
CI / gather-artifacts (stm32) (push) Blocked by required conditions
CI / release-artifacts (push) Blocked by required conditions
CI / release-firmware (esp32) (push) Blocked by required conditions
CI / release-firmware (esp32c3) (push) Blocked by required conditions
CI / release-firmware (esp32c6) (push) Blocked by required conditions
CI / release-firmware (esp32s3) (push) Blocked by required conditions
CI / release-firmware (nrf52840) (push) Blocked by required conditions
CI / release-firmware (rp2040) (push) Blocked by required conditions
CI / release-firmware (stm32) (push) Blocked by required conditions
Nightly / Trunk Check and Upload (push) Has been cancelled
Nightly / Trunk Upgrade (PR) (push) Has been cancelled
* Support WiFi OTA

* Fix trunk warnings

* Make getVersion() check for project name too

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2025-03-20 13:39:33 -05:00
raulperdomo
0d95b1afcc
Added bounds checking to memcpy and use memory-safe strlcpy (#6351)
Some checks failed
CI / build-debian-src (push) Waiting to run
CI / package-pio-deps-native-tft (push) Waiting to run
CI / test-native (push) Waiting to run
CI / docker-debian-amd64 (push) Waiting to run
CI / docker-alpine-amd64 (push) Waiting to run
CI / docker-debian-arm64 (push) Waiting to run
CI / docker-debian-armv7 (push) Waiting to run
CI / after-checks (push) Blocked by required conditions
CI / gather-artifacts (esp32) (push) Blocked by required conditions
CI / gather-artifacts (esp32c3) (push) Blocked by required conditions
CI / gather-artifacts (esp32c6) (push) Blocked by required conditions
CI / gather-artifacts (esp32s3) (push) Blocked by required conditions
CI / gather-artifacts (nrf52840) (push) Blocked by required conditions
CI / gather-artifacts (rp2040) (push) Blocked by required conditions
CI / gather-artifacts (stm32) (push) Blocked by required conditions
CI / release-artifacts (push) Blocked by required conditions
CI / release-firmware (esp32) (push) Blocked by required conditions
CI / release-firmware (esp32c3) (push) Blocked by required conditions
CI / release-firmware (esp32c6) (push) Blocked by required conditions
CI / release-firmware (esp32s3) (push) Blocked by required conditions
CI / release-firmware (nrf52840) (push) Blocked by required conditions
CI / release-firmware (rp2040) (push) Blocked by required conditions
CI / release-firmware (stm32) (push) Blocked by required conditions
Daily Packaging / docker-multiarch (push) Has been cancelled
Daily Packaging / package-ppa (jammy) (push) Has been cancelled
Daily Packaging / package-ppa (noble) (push) Has been cancelled
Daily Packaging / package-ppa (oracular) (push) Has been cancelled
Daily Packaging / package-ppa (plucky) (push) Has been cancelled
Daily Packaging / package-obs (push) Has been cancelled
Daily Packaging / hook-copr (push) Has been cancelled
* Added bounds checking to memcpy and use memory-safe strlcpy for reading serial data in processWXSerial() function.

* Fixed linting with trunk
2025-03-20 10:40:13 -05:00
Austin
46235f6f8b
RP2xx0: Add UDP Multicast support (#6327) 2025-03-20 08:49:28 -05:00
Jorropo
d1068fd1e4
Add UDP multicast support on linux. (#6342)
* Add UDP multicast support on linux.

Closes #6326

We tested it an it works.

This is really hacky to say the least.

* Add libuv to Linux packaging

* Trunkadunk

* Correct ref

* Add libuv1-dev to setup-native

---------

Co-authored-by: vidplace7 <vidplace7@gmail.com>
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2025-03-20 08:47:39 -05:00
Jorropo
f41afb14b1
raise the multicast UDP TTL limit (#6343)
Since 96ba94843b we don't spray packets to all machines on the network.

So we can allow ourself to raise the TTL limit, this allows users who run L3 IGMP Routing infrastructure to pass meshtastic frames over UDP.

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2025-03-20 05:41:29 -05:00
Ben Meadors
f8ad02aab3
Update version.properties
Some checks are pending
CI / build-esp32 (push) Blocked by required conditions
CI / build-esp32-s3 (push) Blocked by required conditions
CI / build-esp32-c3 (push) Blocked by required conditions
CI / build-esp32-c6 (push) Blocked by required conditions
CI / build-nrf52 (push) Blocked by required conditions
CI / build-rpi2040 (push) Blocked by required conditions
CI / build-stm32 (push) Blocked by required conditions
CI / build-debian-src (push) Waiting to run
CI / package-pio-deps-native-tft (push) Waiting to run
CI / test-native (push) Waiting to run
CI / docker-debian-amd64 (push) Waiting to run
CI / docker-alpine-amd64 (push) Waiting to run
CI / docker-debian-arm64 (push) Waiting to run
CI / docker-debian-armv7 (push) Waiting to run
CI / after-checks (push) Blocked by required conditions
CI / gather-artifacts (esp32) (push) Blocked by required conditions
CI / gather-artifacts (esp32c3) (push) Blocked by required conditions
CI / gather-artifacts (esp32c6) (push) Blocked by required conditions
CI / gather-artifacts (esp32s3) (push) Blocked by required conditions
CI / gather-artifacts (nrf52840) (push) Blocked by required conditions
CI / gather-artifacts (rp2040) (push) Blocked by required conditions
CI / gather-artifacts (stm32) (push) Blocked by required conditions
CI / release-artifacts (push) Blocked by required conditions
CI / release-firmware (esp32) (push) Blocked by required conditions
CI / release-firmware (esp32c3) (push) Blocked by required conditions
CI / release-firmware (esp32c6) (push) Blocked by required conditions
CI / release-firmware (esp32s3) (push) Blocked by required conditions
CI / release-firmware (nrf52840) (push) Blocked by required conditions
CI / release-firmware (rp2040) (push) Blocked by required conditions
CI / release-firmware (stm32) (push) Blocked by required conditions
2025-03-19 06:20:50 -05:00
github-actions[bot]
077759e15d
Upgrade trunk (#6347)
Co-authored-by: sachaw <11172820+sachaw@users.noreply.github.com>
2025-03-19 05:11:42 -05:00
Bob Reese
22aa2d7582
Fixed UF2 generation problem with sys.executable path has spaces in it (#6346)
Some checks are pending
CI / build-esp32 (push) Blocked by required conditions
CI / build-esp32-s3 (push) Blocked by required conditions
CI / build-esp32-c3 (push) Blocked by required conditions
CI / build-esp32-c6 (push) Blocked by required conditions
CI / build-nrf52 (push) Blocked by required conditions
CI / build-rpi2040 (push) Blocked by required conditions
CI / build-stm32 (push) Blocked by required conditions
CI / build-debian-src (push) Waiting to run
CI / package-pio-deps-native-tft (push) Waiting to run
CI / test-native (push) Waiting to run
CI / docker-debian-amd64 (push) Waiting to run
CI / docker-alpine-amd64 (push) Waiting to run
CI / docker-debian-arm64 (push) Waiting to run
CI / docker-debian-armv7 (push) Waiting to run
CI / after-checks (push) Blocked by required conditions
CI / gather-artifacts (esp32) (push) Blocked by required conditions
CI / gather-artifacts (esp32c3) (push) Blocked by required conditions
CI / gather-artifacts (esp32c6) (push) Blocked by required conditions
CI / gather-artifacts (esp32s3) (push) Blocked by required conditions
CI / gather-artifacts (nrf52840) (push) Blocked by required conditions
CI / gather-artifacts (rp2040) (push) Blocked by required conditions
CI / gather-artifacts (stm32) (push) Blocked by required conditions
CI / release-artifacts (push) Blocked by required conditions
CI / release-firmware (esp32) (push) Blocked by required conditions
CI / release-firmware (esp32c3) (push) Blocked by required conditions
CI / release-firmware (esp32c6) (push) Blocked by required conditions
CI / release-firmware (esp32s3) (push) Blocked by required conditions
CI / release-firmware (nrf52840) (push) Blocked by required conditions
CI / release-firmware (rp2040) (push) Blocked by required conditions
CI / release-firmware (stm32) (push) Blocked by required conditions
2025-03-18 20:20:15 -05:00
Austin
6673cb9292
Increase MAX_NUM_NODES on high-flash ESP32_S3 (#6311) 2025-03-18 20:19:51 -05:00
Kalle Lilja
8efc9702d3
device-install/update: fix esptool --port (#6341)
Some checks are pending
CI / build-esp32 (push) Blocked by required conditions
CI / build-esp32-s3 (push) Blocked by required conditions
CI / build-esp32-c3 (push) Blocked by required conditions
CI / build-esp32-c6 (push) Blocked by required conditions
CI / build-nrf52 (push) Blocked by required conditions
CI / build-rpi2040 (push) Blocked by required conditions
CI / build-stm32 (push) Blocked by required conditions
CI / build-debian-src (push) Waiting to run
CI / package-pio-deps-native-tft (push) Waiting to run
CI / test-native (push) Waiting to run
CI / docker-debian-amd64 (push) Waiting to run
CI / docker-alpine-amd64 (push) Waiting to run
CI / docker-debian-arm64 (push) Waiting to run
CI / docker-debian-armv7 (push) Waiting to run
CI / after-checks (push) Blocked by required conditions
CI / gather-artifacts (esp32) (push) Blocked by required conditions
CI / gather-artifacts (esp32c3) (push) Blocked by required conditions
CI / gather-artifacts (esp32c6) (push) Blocked by required conditions
CI / gather-artifacts (esp32s3) (push) Blocked by required conditions
CI / gather-artifacts (nrf52840) (push) Blocked by required conditions
CI / gather-artifacts (rp2040) (push) Blocked by required conditions
CI / gather-artifacts (stm32) (push) Blocked by required conditions
CI / release-artifacts (push) Blocked by required conditions
CI / release-firmware (esp32) (push) Blocked by required conditions
CI / release-firmware (esp32c3) (push) Blocked by required conditions
CI / release-firmware (esp32c6) (push) Blocked by required conditions
CI / release-firmware (esp32s3) (push) Blocked by required conditions
CI / release-firmware (nrf52840) (push) Blocked by required conditions
CI / release-firmware (rp2040) (push) Blocked by required conditions
CI / release-firmware (stm32) (push) Blocked by required conditions
* fix errorlevel check

* add esptool --port if supplied

* match device-install

* add --port if supplied

* update logmessage

* bump version

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2025-03-17 20:16:16 -05:00
Austin
2876eec7ed
MeshToad - USB 1W 'MeshStick' (#6339) 2025-03-17 20:14:01 -05:00
Ben Meadors
9cc13e628a Stubbed out backup / restore methods for now and fixed bug 2025-03-17 19:24:47 -05:00
Jorropo
af8b64e84e
pass pointer to UDP multicast packet to protobuf decoder (#6333)
Some checks failed
CI / package-pio-deps-native-tft (push) Has been cancelled
CI / test-native (push) Has been cancelled
CI / docker-debian-amd64 (push) Has been cancelled
CI / docker-alpine-amd64 (push) Has been cancelled
CI / docker-debian-arm64 (push) Has been cancelled
CI / docker-debian-armv7 (push) Has been cancelled
CI / check (push) Has been cancelled
CI / build-esp32 (push) Has been cancelled
CI / build-esp32-s3 (push) Has been cancelled
CI / build-esp32-c3 (push) Has been cancelled
CI / build-esp32-c6 (push) Has been cancelled
CI / build-nrf52 (push) Has been cancelled
CI / build-rpi2040 (push) Has been cancelled
CI / build-stm32 (push) Has been cancelled
CI / after-checks (push) Has been cancelled
CI / gather-artifacts (esp32) (push) Has been cancelled
CI / gather-artifacts (esp32c3) (push) Has been cancelled
CI / gather-artifacts (esp32c6) (push) Has been cancelled
CI / gather-artifacts (esp32s3) (push) Has been cancelled
CI / gather-artifacts (nrf52840) (push) Has been cancelled
CI / gather-artifacts (rp2040) (push) Has been cancelled
CI / gather-artifacts (stm32) (push) Has been cancelled
CI / release-artifacts (push) Has been cancelled
CI / release-firmware (esp32) (push) Has been cancelled
CI / release-firmware (esp32c3) (push) Has been cancelled
CI / release-firmware (esp32c6) (push) Has been cancelled
CI / release-firmware (esp32s3) (push) Has been cancelled
CI / release-firmware (nrf52840) (push) Has been cancelled
CI / release-firmware (rp2040) (push) Has been cancelled
CI / release-firmware (stm32) (push) Has been cancelled
The packet.readBytes API is not available on all targets:
- RP2040 & RP2340
- yet to be written portduino API

Instead pass the data buffer as-is.
It also removes a memcpy which do not need to exists.

I've tested it successfully on a tbeam.

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2025-03-16 19:36:33 -05:00
Jorropo
96ba94843b
Send UDP packets to multicast address rather than broadcast address (#6331)
A smart router or switch is able to snoop the multicast address to
only send the packets to nodes listening on the multicast address.

Before all machines reachable on the L2 layer would receive the packet.
2025-03-16 19:36:02 -05:00
Thomas Göttgens
2d565c2921 trunk'd
Some checks are pending
CI / build-esp32 (push) Blocked by required conditions
CI / build-esp32-s3 (push) Blocked by required conditions
CI / build-esp32-c3 (push) Blocked by required conditions
CI / build-esp32-c6 (push) Blocked by required conditions
CI / build-nrf52 (push) Blocked by required conditions
CI / build-rpi2040 (push) Blocked by required conditions
CI / build-stm32 (push) Blocked by required conditions
CI / build-debian-src (push) Waiting to run
CI / package-pio-deps-native-tft (push) Waiting to run
CI / test-native (push) Waiting to run
CI / docker-debian-amd64 (push) Waiting to run
CI / docker-alpine-amd64 (push) Waiting to run
CI / docker-debian-arm64 (push) Waiting to run
CI / docker-debian-armv7 (push) Waiting to run
CI / after-checks (push) Blocked by required conditions
CI / gather-artifacts (esp32) (push) Blocked by required conditions
CI / gather-artifacts (esp32c3) (push) Blocked by required conditions
CI / gather-artifacts (esp32c6) (push) Blocked by required conditions
CI / gather-artifacts (esp32s3) (push) Blocked by required conditions
CI / gather-artifacts (nrf52840) (push) Blocked by required conditions
CI / gather-artifacts (rp2040) (push) Blocked by required conditions
CI / gather-artifacts (stm32) (push) Blocked by required conditions
CI / release-artifacts (push) Blocked by required conditions
CI / release-firmware (esp32) (push) Blocked by required conditions
CI / release-firmware (esp32c3) (push) Blocked by required conditions
CI / release-firmware (esp32c6) (push) Blocked by required conditions
CI / release-firmware (esp32s3) (push) Blocked by required conditions
CI / release-firmware (nrf52840) (push) Blocked by required conditions
CI / release-firmware (rp2040) (push) Blocked by required conditions
CI / release-firmware (stm32) (push) Blocked by required conditions
2025-03-16 16:18:12 +01:00
HarukiToreda
2525111c39
E-ink partial refresh limitation removed for free text screen (#6201) 2025-03-16 16:15:33 +01:00
dylanli
64b9cfe199
update seeed-xiao-nrf52840-kit board defination (#6318)
- Due to the lack of pins, we have temporarily removed the button. There are some technical solutions that can solve this problem, and we are currently exploring and researching them
2025-03-16 16:04:24 +01:00
Ben Meadors
dc100e4d3e Cleanup 2025-03-16 08:19:46 -05:00
71 changed files with 673 additions and 265 deletions

View File

@ -29,6 +29,7 @@ RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
gpg \
gnupg2 \
libusb-1.0-0-dev \
libuv1-dev \
libi2c-dev \
libxcb-xkb-dev \
libxkbcommon-dev \

View File

@ -11,4 +11,4 @@ runs:
- name: Install libs needed for native build
shell: bash
run: |
sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev libusb-1.0-0-dev libi2c-dev
sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev libusb-1.0-0-dev libi2c-dev libuv1-dev

View File

@ -9,14 +9,14 @@ plugins:
lint:
enabled:
- prettier@3.5.3
- trufflehog@3.88.16
- yamllint@1.36.0
- trufflehog@3.88.17
- yamllint@1.36.2
- bandit@1.8.3
- checkov@3.2.384
- checkov@3.2.386
- terrascan@1.19.9
- trivy@0.60.0
- taplo@0.9.3
- ruff@0.9.10
- ruff@0.11.0
- isort@6.0.1
- markdownlint@0.44.0
- oxipng@9.1.4

View File

@ -13,7 +13,7 @@ ENV TZ=Etc/UTC
ENV PIP_ROOT_USER_ACTION=ignore
RUN apt-get update && apt-get install --no-install-recommends -y \
wget g++ zip git ca-certificates \
libgpiod-dev libyaml-cpp-dev libbluetooth-dev libi2c-dev \
libgpiod-dev libyaml-cpp-dev libbluetooth-dev libi2c-dev libuv1-dev \
libusb-1.0-0-dev libulfius-dev liborcania-dev libssl-dev pkg-config \
&& apt-get clean && rm -rf /var/lib/apt/lists/* \
&& pip install --no-cache-dir -U platformio \
@ -38,7 +38,7 @@ ENV TZ=Etc/UTC
USER root
RUN apt-get update && apt-get --no-install-recommends -y install \
libc-bin libc6 libgpiod2 libyaml-cpp0.7 libi2c0 libulfius2.7 libusb-1.0-0-dev liborcania2.3 libssl3 \
libc-bin libc6 libgpiod2 libyaml-cpp0.7 libi2c0 libuv1 libusb-1.0-0-dev liborcania2.3 libulfius2.7 libssl3 \
&& apt-get clean && rm -rf /var/lib/apt/lists/* \
&& mkdir -p /var/lib/meshtasticd \
&& mkdir -p /etc/meshtasticd/config.d \

View File

@ -9,7 +9,7 @@ FROM python:3.13-alpine3.21 AS builder
ENV PIP_ROOT_USER_ACTION=ignore
RUN apk --no-cache add \
bash g++ libstdc++-dev linux-headers zip git ca-certificates libgpiod-dev yaml-cpp-dev bluez-dev \
libusb-dev i2c-tools-dev openssl-dev pkgconf argp-standalone \
libusb-dev i2c-tools-dev libuv-dev openssl-dev pkgconf argp-standalone \
&& rm -rf /var/cache/apk/* \
&& pip install --no-cache-dir -U platformio \
&& mkdir /tmp/firmware
@ -32,7 +32,7 @@ FROM alpine:3.21
USER root
RUN apk --no-cache add \
libstdc++ libgpiod yaml-cpp libusb i2c-tools \
libstdc++ libgpiod yaml-cpp libusb i2c-tools libuv \
&& rm -rf /var/cache/apk/* \
&& mkdir -p /var/lib/meshtasticd \
&& mkdir -p /etc/meshtasticd/config.d \

View File

@ -17,7 +17,6 @@ build_flags =
-DLFS_NO_ASSERT ; Disable LFS assertions , see https://github.com/meshtastic/firmware/pull/3818
-DMESHTASTIC_EXCLUDE_AUDIO=1
-DMESHTASTIC_EXCLUDE_PAXCOUNTER=1
-DMAX_NUM_NODES=80
build_src_filter =
${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/wifi/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<platform/rp2xx0> -<mesh/eth/> -<mesh/raspihttp>

View File

@ -1,6 +1,6 @@
; The Portduino based 'native' environment. Currently supported on Linux targets with real LoRa hardware (or simulated).
[portduino_base]
platform = https://github.com/meshtastic/platform-native.git#562d189828f09fbf4c4093b3c0104bae9d8e9ff9
platform = https://github.com/meshtastic/platform-native.git#df71ed0040e9aad767a002829330965b78fc452a
framework = arduino
build_src_filter =
@ -34,10 +34,12 @@ build_flags =
-Isrc/platform/portduino
-DRADIOLIB_EEPROM_UNSUPPORTED
-DPORTDUINO_LINUX_HARDWARE
-DHAS_UDP_MULTICAST
-lpthread
-lstdc++fs
-lbluetooth
-lgpiod
-lyaml-cpp
-li2c
-luv
-std=c++17

View File

@ -0,0 +1,17 @@
Lora:
Module: sx1262
CS: 0
IRQ: 6
Reset: 2
Busy: 4
RXen: 1
DIO2_AS_RF_SWITCH: true
DIO3_TCXO_VOLTAGE: true
spidev: ch341
USB_PID: 0x5512
USB_VID: 0x1A86
# Optional: Reduce power to 10 dBm to
# avoid over-drawing the USB port
# SX126X_MAX_POWER: 10
# Optional: Set the serial number for multi-radio support
# USB_Serialnum: 13374201

View File

@ -7,12 +7,19 @@ SET "DEBUG=0"
SET "PYTHON="
SET "WEB_APP=0"
SET "TFT_BUILD=0"
SET "TFT8=0"
SET "TFT16=0"
SET "BIGDB8=0"
SET "BIGDB16=0"
SET "ESPTOOL_BAUD=115200"
SET "ESPTOOL_CMD="
SET "LOGCOUNTER=0"
@REM FIXME: Determine mcu from PlatformIO variant, this is unmaintainable.
SET "S3=s3 v3 t-deck wireless-paper wireless-tracker station-g2 unphone"
SET "C3=esp32c3"
@REM FIXME: Determine flash size from PlatformIO variant, this is unmaintainable.
SET "BIGDB_8MB=picomputer-s3 unphone seeed-sensecap-indicator crowpanel-esp32s3 heltec_capsule_sensor_v3 heltec-v3 heltec-vision-master-e213 heltec-vision-master-e290 heltec-vision-master-t190 heltec-wireless-paper heltec-wireless-tracker heltec-wsl-v3 icarus seeed-xiao-s3 tbeam-s3-core tracksenger"
SET "BIGDB_16MB=t-deck mesh-tab t-energy-s3 dreamcatcher ESP32-S3-Pico m5stack-cores3 station-g2 t-eth-elite t-watch-s3"
GOTO getopts
:help
ECHO Flash image file to device, but first erasing and writing system information.
@ -34,7 +41,7 @@ ECHO Example: %SCRIPT_NAME% -f firmware-unphone-2.6.0.0b106d4.bin -p COM11 --web
GOTO eof
:version
ECHO %SCRIPT_NAME% [Version 2.6.0]
ECHO %SCRIPT_NAME% [Version 2.6.1]
ECHO Meshtastic
GOTO eof
@ -106,7 +113,7 @@ IF NOT "__%PYTHON%__"=="____" (
CALL :LOG_MESSAGE DEBUG "Checking esptool command !ESPTOOL_CMD!..."
!ESPTOOL_CMD! >nul 2>&1
IF %ERRORLEVEL% GTR 2 (
IF %ERRORLEVEL% GEQ 2 (
@REM esptool exits with code 1 if help is displayed.
CALL :LOG_MESSAGE ERROR "esptool not found: !ESPTOOL_CMD!"
EXIT /B 1
@ -121,6 +128,7 @@ CALL :LOG_MESSAGE DEBUG "Using esptool command: !ESPTOOL_CMD!"
IF "__!ESPTOOL_PORT!__" == "____" (
CALL :LOG_MESSAGE WARN "Using esptool port: UNSET."
) ELSE (
SET "ESPTOOL_CMD=!ESPTOOL_CMD! --port !ESPTOOL_PORT!"
CALL :LOG_MESSAGE INFO "Using esptool port: !ESPTOOL_PORT!."
)
CALL :LOG_MESSAGE INFO "Using esptool baud: !ESPTOOL_BAUD!."
@ -133,44 +141,36 @@ IF NOT "!FILENAME:-tft-=!"=="!FILENAME!" (
CALL :LOG_MESSAGE ERROR "Cannot enable WebUI (--web) and MUI." & GOTO eof
)
SET "TFT_BUILD=1"
GOTO tft
) ELSE (
CALL :LOG_MESSAGE DEBUG "We are NOT working with a *-tft-* file. !FILENAME!"
GOTO no_tft
)
:tft
SET "TFT8MB=picomputer-s3 unphone seeed-sensecap-indicator"
FOR %%a IN (%TFT8MB%) DO (
FOR %%a IN (%BIGDB_8MB%) DO (
IF NOT "!FILENAME:%%a=!"=="!FILENAME!" (
@REM We are working with any of %TFT8MB%.
SET "TFT8=1"
GOTO end_loop_tft8mb
@REM We are working with any of %BIGDB_8MB%.
SET "BIGDB8=1"
GOTO end_loop_bigdb_8mb
)
)
:end_loop_tft8mb
:end_loop_bigdb_8mb
SET "TFT16MB=t-deck"
FOR %%a IN (%TFT16MB%) DO (
FOR %%a IN (%BIGDB_16MB%) DO (
IF NOT "!FILENAME:%%a=!"=="!FILENAME!" (
@REM We are working with any of %TFT16MB%.
SET "TFT16=1"
GOTO end_loop_tft16mb
@REM We are working with any of %BIGDB_16MB%.
SET "BIGDB16=1"
GOTO end_loop_bigdb_16mb
)
)
:end_loop_tft16mb
:end_loop_bigdb_16mb
IF %TFT8% EQU 1 CALL :LOG_MESSAGE INFO "tft and MUI 8mb selected."
IF %TFT16% EQU 1 CALL :LOG_MESSAGE INFO "tft and MUI 16mb selected."
:no_tft
IF %BIGDB8% EQU 1 CALL :LOG_MESSAGE INFO "BigDB 8mb partition selected."
IF %BIGDB16% EQU 1 CALL :LOG_MESSAGE INFO "BigDB 16mb partition selected."
@REM Extract BASENAME from %FILENAME% for later use.
SET "BASENAME=!FILENAME:firmware-=!"
CALL :LOG_MESSAGE DEBUG "Computed firmware basename: !BASENAME!"
@REM Account for S3 and C3 board's different OTA partition.
SET "S3=s3 v3 t-deck wireless-paper wireless-tracker station-g2 unphone"
FOR %%a IN (%S3%) DO (
IF NOT "!FILENAME:%%a=!"=="!FILENAME!" (
@REM We are working with any of %S3%.
@ -179,7 +179,6 @@ FOR %%a IN (%S3%) DO (
)
)
SET "C3=esp32c3"
FOR %%a IN (%C3%) DO (
IF NOT "!FILENAME:%%a=!"=="!FILENAME!" (
@REM We are working with any of %C3%.
@ -208,14 +207,14 @@ CALL :LOG_MESSAGE DEBUG "Set SPIFFS_FILENAME to: !SPIFFS_FILENAME!"
SET "OTA_OFFSET=0x260000"
SET "SPIFFS_OFFSET=0x300000"
@REM Offsets for MUI 8mb.
IF %TFT8% EQU 1 IF %TFT_BUILD% EQU 1 (
@REM Offsets for BigDB 8mb.
IF %BIGDB8% EQU 1 (
SET "OTA_OFFSET=0x340000"
SET "SPIFFS_OFFSET=0x670000"
)
@REM Offsets for MUI 16mb.
IF %TFT16% EQU 1 IF %TFT_BUILD% EQU 1 (
@REM Offsets for BigDB 16mb.
IF %BIGDB16% EQU 1 (
SET "OTA_OFFSET=0x650000"
SET "SPIFFS_OFFSET=0xc90000"
)

View File

@ -2,9 +2,48 @@
PYTHON=${PYTHON:-$(which python3 python | head -n 1)}
WEB_APP=false
TFT8=false
TFT16=false
TFT_BUILD=false
MCU=""
# Variant groups
BIGDB_8MB=(
"picomputer-s3"
"unphone"
"seeed-sensecap-indicator"
"crowpanel-esp32s3"
"heltec_capsule_sensor_v3"
"heltec-v3"
"heltec-vision-master-e213"
"heltec-vision-master-e290"
"heltec-vision-master-t190"
"heltec-wireless-paper"
"heltec-wireless-tracker"
"heltec-wsl-v3"
"icarus"
"seeed-xiao-s3"
"tbeam-s3-core"
"tracksenger"
)
BIGDB_16MB=(
"t-deck"
"mesh-tab"
"t-energy-s3"
"dreamcatcher"
"ESP32-S3-Pico"
"m5stack-cores3"
"station-g2"
"t-eth-elite"
"t-watch-s3"
)
S3_VARIANTS=(
"s3"
"-v3"
"t-deck"
"wireless-paper"
"wireless-tracker"
"station-g2"
"unphone"
)
# Determine the correct esptool command to use
if "$PYTHON" -m esptool version >/dev/null 2>&1; then
@ -42,8 +81,8 @@ while [ $# -gt 0 ]; do
exit 0
;;
-p)
ESPTOOL_PORT="$2"
shift # Shift past the option argument
ESPTOOL_CMD="$ESPTOOL_CMD --port $2"
shift
;;
-P)
PYTHON="$2"
@ -78,21 +117,13 @@ if [[ $FILENAME != firmware-* ]]; then
exit 1
fi
# Check if FILENAME contains "-tft-" and set target partitionScheme accordingly.
# Check if FILENAME contains "-tft-" and prevent web/mui comingling.
if [[ ${FILENAME//-tft-/} != "$FILENAME" ]]; then
TFT_BUILD=true
if [[ $WEB_APP == true ]] && [[ $TFT_BUILD == true ]]; then
echo "Cannot enable WebUI (--web) and MUI."
exit 1
fi
if [[ $FILENAME == *"picomputer-s3"* || $FILENAME == *"unphone"* || $FILENAME == *"seeed-sensecap-indicator"* ]]; then
TFT8=true
fi
if [[ $FILENAME == *"t-deck"* ]]; then
TFT16=true
fi
fi
# Extract BASENAME from %FILENAME% for later use.
@ -105,20 +136,31 @@ if [ -f "${FILENAME}" ] && [ -n "${FILENAME##*"update"*}" ]; then
# Default OTA Offset
OTA_OFFSET=0x260000
# littlefs* offset for MUI 8mb and OTA OFFSET.
if [ "$TFT8" = true ] && [ "$TFT_BUILD" = true ]; then
OFFSET=0x670000
OTA_OFFSET=0x340000
fi
# littlefs* offset for BigDB 8mb and OTA OFFSET.
for variant in "${BIGDB_8MB[@]}"; do
if [ -n "${FILENAME##*"$variant"*}" ]; then
OFFSET=0x670000
OTA_OFFSET=0x340000
fi
done
# littlefs* offset for MUI 16mb and OTA OFFSET.
if [ "$TFT16" = true ] && [ "$TFT_BUILD" = true ]; then
OFFSET=0xc90000
OTA_OFFSET=0x650000
fi
# littlefs* offset for BigDB 16mb and OTA OFFSET.
for variant in "${BIGDB_16MB[@]}"; do
if [ -n "${FILENAME##*"$variant"*}" ]; then
OFFSET=0xc90000
OTA_OFFSET=0x650000
fi
done
# Account for S3 board's different OTA partition
if [ -n "${FILENAME##*"s3"*}" ] && [ -n "${FILENAME##*"-v3"*}" ] && [ -n "${FILENAME##*"t-deck"*}" ] && [ -n "${FILENAME##*"wireless-paper"*}" ] && [ -n "${FILENAME##*"wireless-tracker"*}" ] && [ -n "${FILENAME##*"station-g2"*}" ] && [ -n "${FILENAME##*"unphone"*}" ]; then
# FIXME: Use PlatformIO info to determine MCU type, this is unmaintainable
for variant in "${S3_VARIANTS[@]}"; do
if [ -n "${FILENAME##*"$variant"*}" ]; then
MCU="esp32s3"
fi
done
if [ "$MCU" != "esp32s3" ]; then
if [ -n "${FILENAME##*"esp32c3"*}" ]; then
OTAFILE=bleota.bin
else

View File

@ -16,7 +16,7 @@ ECHO.
ECHO Usage: %SCRIPT_NAME% -f filename [-p PORT] [-P python]
ECHO.
ECHO Options:
ECHO -f filename The .bin file to flash. Custom to your device type and region. (required)
ECHO -f filename The update .bin file to flash. Custom to your device type and region. (required)
ECHO The file must be located in this current directory.
ECHO -p PORT Set the environment variable for ESPTOOL_PORT.
ECHO If not set, ESPTOOL iterates all ports (Dangerous).
@ -28,7 +28,7 @@ ECHO Example: %SCRIPT_NAME% -f firmware-t-deck-tft-2.6.0.0b106d4-update.bin -p C
GOTO eof
:version
ECHO %SCRIPT_NAME% [Version 2.6.0]
ECHO %SCRIPT_NAME% [Version 2.6.1]
ECHO Meshtastic
GOTO eof
@ -53,6 +53,7 @@ IF "__!FILENAME!__"=="____" (
CALL :LOG_MESSAGE DEBUG "Missing -f filename input."
GOTO help
) ELSE (
CALL :LOG_MESSAGE DEBUG "Filename: !FILENAME!"
IF NOT "__!FILENAME: =!__"=="__!FILENAME!__" (
CALL :LOG_MESSAGE ERROR "Filename containing spaces are not supported."
GOTO help
@ -62,7 +63,6 @@ IF "__!FILENAME!__"=="____" (
SET "FILENAME=!FILENAME:./=!"
)
CALL :LOG_MESSAGE DEBUG "Filename: !FILENAME!"
CALL :LOG_MESSAGE DEBUG "Checking if !FILENAME! exists..."
IF NOT EXIST !FILENAME! (
CALL :LOG_MESSAGE ERROR "File does not exist: !FILENAME!. Terminating."
@ -71,7 +71,7 @@ IF NOT EXIST !FILENAME! (
IF "!FILENAME:update=!"=="!FILENAME!" (
CALL :LOG_MESSAGE DEBUG "We are NOT working with a *update* file. !FILENAME!"
CALL :LOG_MESSAGE INFO "Use script device-install.bat to flash update !FILENAME!."
CALL :LOG_MESSAGE INFO "Use script device-install.bat to flash !FILENAME!."
GOTO eof
) ELSE (
CALL :LOG_MESSAGE DEBUG "We are working with a *update* file. !FILENAME!"
@ -95,7 +95,7 @@ IF NOT "__%PYTHON%__"=="____" (
CALL :LOG_MESSAGE DEBUG "Checking esptool command !ESPTOOL_CMD!..."
!ESPTOOL_CMD! >nul 2>&1
IF %ERRORLEVEL% GTR 2 (
IF %ERRORLEVEL% GEQ 2 (
@REM esptool exits with code 1 if help is displayed.
CALL :LOG_MESSAGE ERROR "esptool not found: !ESPTOOL_CMD!"
EXIT /B 1
@ -110,6 +110,7 @@ CALL :LOG_MESSAGE DEBUG "Using esptool command: !ESPTOOL_CMD!"
IF "__!ESPTOOL_PORT!__" == "____" (
CALL :LOG_MESSAGE WARN "Using esptool port: UNSET."
) ELSE (
SET "ESPTOOL_CMD=!ESPTOOL_CMD! --port !ESPTOOL_PORT!"
CALL :LOG_MESSAGE INFO "Using esptool port: !ESPTOOL_PORT!."
)
CALL :LOG_MESSAGE INFO "Using esptool baud: !ESPTOOL_BAUD!."

View File

@ -35,8 +35,8 @@ while getopts ":hp:P:f:" opt; do
show_help
exit 0
;;
p) export ESPTOOL_PORT=${OPTARG}
;;
p) ESPTOOL_CMD="$ESPTOOL_CMD --port ${OPTARG}"
;;
P) PYTHON=${OPTARG}
;;
f) FILENAME=${OPTARG}

View File

@ -83,7 +83,7 @@ if platform.name == "espressif32":
if platform.name == "nordicnrf52":
env.AddPostAction("$BUILD_DIR/${PROGNAME}.hex",
env.VerboseAction(f"{sys.executable} ./bin/uf2conv.py $BUILD_DIR/firmware.hex -c -f 0xADA52840 -o $BUILD_DIR/firmware.uf2",
env.VerboseAction(f"\"{sys.executable}\" ./bin/uf2conv.py $BUILD_DIR/firmware.hex -c -f 0xADA52840 -o $BUILD_DIR/firmware.uf2",
"Generating UF2 file"))
Import("projenv")

1
debian/control vendored
View File

@ -17,6 +17,7 @@ Build-Depends: debhelper-compat (= 13),
libbluetooth-dev,
libusb-1.0-0-dev,
libi2c-dev,
libuv1-dev,
openssl,
libssl-dev,
libulfius-dev,

View File

@ -36,6 +36,7 @@ BuildRequires: pkgconfig(libgpiod)
BuildRequires: pkgconfig(bluez)
BuildRequires: pkgconfig(libusb-1.0)
BuildRequires: libi2c-devel
BuildRequires: pkgconfig(libuv)
# Web components:
BuildRequires: pkgconfig(openssl)
BuildRequires: pkgconfig(liborcania)

View File

@ -11,12 +11,18 @@ static File openFile(const char *filename, bool fullAtomic)
FSCom.remove(filename);
return FSCom.open(filename, FILE_O_WRITE);
#endif
if (!fullAtomic)
if (!fullAtomic) {
FSCom.remove(filename); // Nuke the old file to make space (ignore if it !exists)
}
String filenameTmp = filename;
filenameTmp += ".tmp";
// FIXME: If we are doing a full atomic write, we may need to remove the old tmp file now
// if (fullAtomic) {
// FSCom.remove(filename);
// }
// clear any previous LFS errors
return FSCom.open(filenameTmp.c_str(), FILE_O_WRITE);
}

View File

@ -324,6 +324,14 @@ void EInkDynamicDisplay::checkConsecutiveFastRefreshes()
if (refresh != UNSPECIFIED)
return;
// Bypass limit if UNLIMITED_FAST mode is active
if (frameFlags & UNLIMITED_FAST) {
refresh = FAST;
reason = NO_OBJECTIONS;
LOG_DEBUG("refresh=FAST, reason=UNLIMITED_FAST_MODE_ACTIVE, frameFlags=0x%x", frameFlags);
return;
}
// If too many FAST refreshes consecutively - force a FULL refresh
if (fastRefreshCount >= EINK_LIMIT_FASTREFRESH) {
refresh = FULL;

View File

@ -23,6 +23,10 @@ class EInkDynamicDisplay : public EInkDisplay, protected concurrency::NotifiedWo
EInkDynamicDisplay(uint8_t address, int sda, int scl, OLEDDISPLAY_GEOMETRY geometry, HW_I2C i2cBus);
~EInkDynamicDisplay();
// Methods to enable or disable unlimited fast refresh mode
void enableUnlimitedFastMode() { addFrameFlag(UNLIMITED_FAST); }
void disableUnlimitedFastMode() { frameFlags = (frameFlagTypes)(frameFlags & ~UNLIMITED_FAST); }
// What kind of frame is this
enum frameFlagTypes : uint8_t {
BACKGROUND = (1 << 0), // For frames via display()
@ -30,6 +34,7 @@ class EInkDynamicDisplay : public EInkDisplay, protected concurrency::NotifiedWo
COSMETIC = (1 << 2), // For splashes
DEMAND_FAST = (1 << 3), // Special case only
BLOCKING = (1 << 4), // Modifier - block while refresh runs
UNLIMITED_FAST = (1 << 5)
};
void addFrameFlag(frameFlagTypes flag);

View File

@ -826,6 +826,11 @@ void setup()
#ifdef HAS_UDP_MULTICAST
LOG_DEBUG("Start multicast thread");
udpThread = new UdpMulticastThread();
#ifdef ARCH_PORTDUINO
// FIXME: portduino does not ever call onNetworkConnected so call it here because I don't know what happen if I call
// onNetworkConnected there
udpThread->start();
#endif
#endif
service = new MeshService();
service->init();

View File

@ -125,17 +125,15 @@ void MeshService::loop()
}
/// The radioConfig object just changed, call this to force the hw to change to the new settings
bool MeshService::reloadConfig(int saveWhat)
void MeshService::reloadConfig(int saveWhat)
{
// If we can successfully set this radio to these settings, save them to disk
// This will also update the region as needed
bool didReset = nodeDB->resetRadioConfig(); // Don't let the phone send us fatally bad settings
nodeDB->resetRadioConfig(); // Don't let the phone send us fatally bad settings
configChanged.notifyObservers(NULL); // This will cause radio hardware to change freqs etc
nodeDB->saveToDisk(saveWhat);
return didReset;
}
/// The owner User record just got updated, update our node DB and broadcast the info into the mesh

View File

@ -118,7 +118,7 @@ class MeshService
/** The radioConfig object just changed, call this to force the hw to change to the new settings
* @return true if client devices should be sent a new set of radio configs
*/
bool reloadConfig(int saveWhat = SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS);
void reloadConfig(int saveWhat = SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS);
/// The owner User record just got updated, update our node DB and broadcast the info into the mesh
void reloadOwner(bool shouldSave = true);

View File

@ -51,6 +51,10 @@
#include <utility/bonding.h>
#endif
#if defined(ARCH_ESP32) && !MESHTASTIC_EXCLUDE_WIFI
#include <WiFiOTA.h>
#endif
NodeDB *nodeDB = nullptr;
// we have plenty of ram so statically alloc this tempbuf (for now)
@ -400,18 +404,12 @@ bool isBroadcast(uint32_t dest)
return dest == NODENUM_BROADCAST || dest == NODENUM_BROADCAST_NO_LORA;
}
bool NodeDB::resetRadioConfig(bool factory_reset, bool is_fresh_install)
void NodeDB::resetRadioConfig(bool is_fresh_install)
{
bool didFactoryReset = false;
if (is_fresh_install) {
radioGeneration++;
}
if (factory_reset) {
didFactoryReset = factoryReset();
}
if (channelFile.channels_count != MAX_NUM_CHANNELS) {
LOG_INFO("Set default channel and radio preferences!");
@ -422,14 +420,6 @@ bool NodeDB::resetRadioConfig(bool factory_reset, bool is_fresh_install)
// Update the global myRegion
initRegion();
if (didFactoryReset) {
LOG_INFO("Reboot due to factory reset");
screen->startAlert("Rebooting...");
rebootAtMsec = millis() + (5 * 1000);
}
return didFactoryReset;
}
bool NodeDB::factoryReset(bool eraseBleBonds)
@ -591,7 +581,7 @@ void NodeDB::installDefaultConfig(bool preserveKey = false)
config.device.node_info_broadcast_secs = default_node_info_broadcast_secs;
config.security.serial_enabled = true;
config.security.admin_channel_enabled = false;
resetRadioConfig(false, true); // This also triggers NodeInfo/Position requests since we're fresh
resetRadioConfig(true); // This also triggers NodeInfo/Position requests since we're fresh
strncpy(config.network.ntp_server, "meshtastic.pool.ntp.org", 32);
#if (defined(T_DECK) || defined(T_WATCH_S3) || defined(UNPHONE) || defined(PICOMPUTER_S3) || defined(SENSECAP_INDICATOR)) && \
@ -649,6 +639,12 @@ void NodeDB::installDefaultConfig(bool preserveKey = false)
config.display.wake_on_tap_or_motion = true;
#endif
#if defined(ARCH_ESP32) && !MESHTASTIC_EXCLUDE_WIFI
if (WiFiOTA::isUpdated()) {
WiFiOTA::recoverConfig(&config.network);
}
#endif
initConfigIntervals();
}
@ -1612,6 +1608,94 @@ UserLicenseStatus NodeDB::getLicenseStatus(uint32_t nodeNum)
return info->user.is_licensed ? UserLicenseStatus::Licensed : UserLicenseStatus::NotLicensed;
}
bool NodeDB::backupPreferences(meshtastic_AdminMessage_BackupLocation location)
{
bool success = false;
lastBackupAttempt = millis();
#ifdef FSCom
if (location == meshtastic_AdminMessage_BackupLocation_FLASH) {
meshtastic_BackupPreferences backup = meshtastic_BackupPreferences_init_zero;
backup.version = DEVICESTATE_CUR_VER;
backup.timestamp = getValidTime(RTCQuality::RTCQualityDevice, false);
backup.has_config = true;
backup.config = config;
backup.has_module_config = true;
backup.module_config = moduleConfig;
backup.has_channels = true;
backup.channels = channelFile;
backup.has_owner = true;
backup.owner = owner;
size_t backupSize;
pb_get_encoded_size(&backupSize, meshtastic_BackupPreferences_fields, &backup);
spiLock->lock();
FSCom.mkdir("/backups");
spiLock->unlock();
success = saveProto(backupFileName, backupSize, &meshtastic_BackupPreferences_msg, &backup);
if (success) {
LOG_INFO("Saved backup preferences");
} else {
LOG_ERROR("Failed to save backup preferences to file");
}
} else if (location == meshtastic_AdminMessage_BackupLocation_SD) {
// TODO: After more mainline SD card support
}
#endif
return success;
}
bool NodeDB::restorePreferences(meshtastic_AdminMessage_BackupLocation location, int restoreWhat)
{
bool success = false;
#ifdef FSCom
if (location == meshtastic_AdminMessage_BackupLocation_FLASH) {
spiLock->lock();
if (!FSCom.exists(backupFileName)) {
spiLock->unlock();
LOG_WARN("Could not restore. No backup file found");
return false;
} else {
spiLock->unlock();
}
meshtastic_BackupPreferences backup = meshtastic_BackupPreferences_init_zero;
success = loadProto(backupFileName, meshtastic_BackupPreferences_size, sizeof(meshtastic_BackupPreferences),
&meshtastic_BackupPreferences_msg, &backup);
if (success) {
if (restoreWhat & SEGMENT_CONFIG) {
config = backup.config;
LOG_DEBUG("Restored config");
}
if (restoreWhat & SEGMENT_MODULECONFIG) {
moduleConfig = backup.module_config;
LOG_DEBUG("Restored module config");
}
if (restoreWhat & SEGMENT_DEVICESTATE) {
devicestate.owner = backup.owner;
LOG_DEBUG("Restored device state");
}
if (restoreWhat & SEGMENT_CHANNELS) {
channelFile = backup.channels;
LOG_DEBUG("Restored channels");
}
success = saveToDisk(restoreWhat);
if (success) {
LOG_INFO("Restored preferences from backup");
} else {
LOG_ERROR("Failed to save restored preferences to flash");
}
} else {
LOG_ERROR("Failed to restore preferences from backup file");
}
} else if (location == meshtastic_AdminMessage_BackupLocation_SD) {
// TODO: After more mainline SD card support
}
return success;
#endif
}
/// Record an error that should be reported via analytics
void recordCriticalError(meshtastic_CriticalErrorCode code, uint32_t address, const char *filename)
{

View File

@ -48,6 +48,7 @@ static constexpr const char *configFileName = "/prefs/config.proto";
static constexpr const char *uiconfigFileName = "/prefs/uiconfig.proto";
static constexpr const char *moduleConfigFileName = "/prefs/module.proto";
static constexpr const char *channelFileName = "/prefs/channels.proto";
static constexpr const char *backupFileName = "/backups/backup.proto";
/// Given a node, return how many seconds in the past (vs now) that we last heard from it
uint32_t sinceLastSeen(const meshtastic_NodeInfoLite *n);
@ -103,7 +104,7 @@ class NodeDB
* @param is_fresh_install set to true after a fresh install, to trigger NodeInfo/Position requests
* @return true if the config was completely reset, in that case, we should send it back to the client
*/
bool resetRadioConfig(bool factory_reset = false, bool is_fresh_install = false);
void resetRadioConfig(bool is_fresh_install = false);
/// given a subpacket sniffed from the network, update our DB state
/// we updateGUI and updateGUIforNode if we think our this change is big enough for a redraw
@ -202,8 +203,13 @@ class NodeDB
bool hasValidPosition(const meshtastic_NodeInfoLite *n);
bool backupPreferences(meshtastic_AdminMessage_BackupLocation location);
bool restorePreferences(meshtastic_AdminMessage_BackupLocation location,
int restoreWhat = SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS);
private:
uint32_t lastNodeDbSave = 0; // when we last saved our db to flash
uint32_t lastNodeDbSave = 0; // when we last saved our db to flash
uint32_t lastBackupAttempt = 0; // when we last tried a backup automatically or manually
/// Find a node in our DB, create an empty NodeInfoLite if missing
meshtastic_NodeInfoLite *getOrCreateMeshNode(NodeNum n);

View File

@ -656,7 +656,7 @@ size_t RadioInterface::beginSending(meshtastic_MeshPacket *p)
// if the sender nodenum is zero, that means uninitialized
assert(radioBuffer.header.from);
assert(p->encrypted.size <= sizeof(radioBuffer.payload));
memcpy(radioBuffer.payload, p->encrypted.bytes, p->encrypted.size);
sendingPacket = p;

View File

@ -198,6 +198,14 @@ ErrorCode Router::sendLocal(meshtastic_MeshPacket *p, RxSource src)
return send(p);
}
}
/**
* Send a packet on a suitable interface.
*/
ErrorCode Router::rawSend(meshtastic_MeshPacket *p)
{
assert(iface); // This should have been detected already in sendLocal (or we just received a packet from outside)
return iface->send(p);
}
/**
* Send a packet on a suitable interface. This routine will
@ -319,27 +327,27 @@ void Router::sniffReceived(const meshtastic_MeshPacket *p, const meshtastic_Rout
// FIXME, update nodedb here for any packet that passes through us
}
bool perhapsDecode(meshtastic_MeshPacket *p)
DecodeState perhapsDecode(meshtastic_MeshPacket *p)
{
concurrency::LockGuard g(cryptLock);
if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER &&
config.device.rebroadcast_mode == meshtastic_Config_DeviceConfig_RebroadcastMode_ALL_SKIP_DECODING)
return false;
return DecodeState::DECODE_FAILURE;
if (config.device.rebroadcast_mode == meshtastic_Config_DeviceConfig_RebroadcastMode_KNOWN_ONLY &&
(nodeDB->getMeshNode(p->from) == NULL || !nodeDB->getMeshNode(p->from)->has_user)) {
LOG_DEBUG("Node 0x%x not in nodeDB-> Rebroadcast mode KNOWN_ONLY will ignore packet", p->from);
return false;
return DecodeState::DECODE_FAILURE;
}
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag)
return true; // If packet was already decoded just return
return DecodeState::DECODE_SUCCESS; // If packet was already decoded just return
size_t rawSize = p->encrypted.size;
if (rawSize > sizeof(bytes)) {
LOG_ERROR("Packet too large to attempt decryption! (rawSize=%d > 256)", rawSize);
return false;
return DecodeState::DECODE_FATAL;
}
bool decrypted = false;
ChannelIndex chIndex = 0;
@ -353,18 +361,22 @@ bool perhapsDecode(meshtastic_MeshPacket *p)
if (crypto->decryptCurve25519(p->from, nodeDB->getMeshNode(p->from)->user.public_key, p->id, rawSize, p->encrypted.bytes,
bytes)) {
LOG_INFO("PKI Decryption worked!");
memset(&p->decoded, 0, sizeof(p->decoded));
meshtastic_Data decodedtmp;
memset(&decodedtmp, 0, sizeof(decodedtmp));
rawSize -= MESHTASTIC_PKC_OVERHEAD;
if (pb_decode_from_bytes(bytes, rawSize, &meshtastic_Data_msg, &p->decoded) &&
p->decoded.portnum != meshtastic_PortNum_UNKNOWN_APP) {
if (pb_decode_from_bytes(bytes, rawSize, &meshtastic_Data_msg, &decodedtmp) &&
decodedtmp.portnum != meshtastic_PortNum_UNKNOWN_APP) {
decrypted = true;
LOG_INFO("Packet decrypted using PKI!");
p->pki_encrypted = true;
memcpy(&p->public_key.bytes, nodeDB->getMeshNode(p->from)->user.public_key.bytes, 32);
p->public_key.size = 32;
p->decoded = decodedtmp;
p->which_payload_variant = meshtastic_MeshPacket_decoded_tag; // change type to decoded
} else {
LOG_ERROR("PKC Decrypted, but pb_decode failed!");
return false;
return DecodeState::DECODE_FAILURE;
}
} else {
LOG_WARN("PKC decrypt attempted but failed!");
@ -387,12 +399,15 @@ bool perhapsDecode(meshtastic_MeshPacket *p)
// printBytes("plaintext", bytes, p->encrypted.size);
// Take those raw bytes and convert them back into a well structured protobuf we can understand
memset(&p->decoded, 0, sizeof(p->decoded));
if (!pb_decode_from_bytes(bytes, rawSize, &meshtastic_Data_msg, &p->decoded)) {
meshtastic_Data decodedtmp;
memset(&decodedtmp, 0, sizeof(decodedtmp));
if (!pb_decode_from_bytes(bytes, rawSize, &meshtastic_Data_msg, &decodedtmp)) {
LOG_ERROR("Invalid protobufs in received mesh packet id=0x%08x (bad psk?)!", p->id);
} else if (p->decoded.portnum == meshtastic_PortNum_UNKNOWN_APP) {
} else if (decodedtmp.portnum == meshtastic_PortNum_UNKNOWN_APP) {
LOG_ERROR("Invalid portnum (bad psk?)!");
} else {
p->decoded = decodedtmp;
p->which_payload_variant = meshtastic_MeshPacket_decoded_tag; // change type to decoded
decrypted = true;
break;
}
@ -401,8 +416,7 @@ bool perhapsDecode(meshtastic_MeshPacket *p)
}
if (decrypted) {
// parsing was successful
p->which_payload_variant = meshtastic_MeshPacket_decoded_tag; // change type to decoded
p->channel = chIndex; // change to store the index instead of the hash
p->channel = chIndex; // change to store the index instead of the hash
if (p->decoded.has_bitfield)
p->decoded.want_response |= p->decoded.bitfield & BITFIELD_WANT_RESPONSE_MASK;
@ -434,10 +448,10 @@ bool perhapsDecode(meshtastic_MeshPacket *p)
LOG_TRACE("%s", MeshPacketSerializer::JsonSerialize(p, false).c_str());
}
#endif
return true;
return DecodeState::DECODE_SUCCESS;
} else {
LOG_WARN("No suitable channel found for decoding, hash was 0x%x!", p->channel);
return false;
return DecodeState::DECODE_FAILURE;
}
}
@ -592,8 +606,13 @@ void Router::handleReceived(meshtastic_MeshPacket *p, RxSource src)
meshtastic_MeshPacket *p_encrypted = packetPool.allocCopy(*p);
// Take those raw bytes and convert them back into a well structured protobuf we can understand
bool decoded = perhapsDecode(p);
if (decoded) {
auto decodedState = perhapsDecode(p);
if (decodedState == DecodeState::DECODE_FATAL) {
// Fatal decoding error, we can't do anything with this packet
LOG_WARN("Fatal decode error, dropping packet");
cancelSending(p->from, p->id);
skipHandle = true;
} else if (decodedState == DecodeState::DECODE_SUCCESS) {
// parsing was successful, queue for our recipient
if (src == RX_SRC_LOCAL)
printPacket("handleReceived(LOCAL)", p);
@ -636,10 +655,12 @@ void Router::handleReceived(meshtastic_MeshPacket *p, RxSource src)
#if !MESHTASTIC_EXCLUDE_MQTT
// Mark as pki_encrypted if it is not yet decoded and MQTT encryption is also enabled, hash matches and it's a DM not to
// us (because we would be able to decrypt it)
if (!decoded && moduleConfig.mqtt.encryption_enabled && p->channel == 0x00 && !isBroadcast(p->to) && !isToUs(p))
if (decodedState == DecodeState::DECODE_FAILURE && moduleConfig.mqtt.encryption_enabled && p->channel == 0x00 &&
!isBroadcast(p->to) && !isToUs(p))
p_encrypted->pki_encrypted = true;
// After potentially altering it, publish received message to MQTT if we're not the original transmitter of the packet
if ((decoded || p_encrypted->pki_encrypted) && moduleConfig.mqtt.enabled && !isFromUs(p) && mqtt)
if ((decodedState == DecodeState::DECODE_SUCCESS || p_encrypted->pki_encrypted) && moduleConfig.mqtt.enabled &&
!isFromUs(p) && mqtt)
mqtt->onSend(*p_encrypted, *p, p->channel);
#endif
}

View File

@ -85,6 +85,7 @@ class Router : protected concurrency::OSThread, protected PacketHistory
* NOTE: This method will free the provided packet (even if we return an error code)
*/
virtual ErrorCode send(meshtastic_MeshPacket *p);
virtual ErrorCode rawSend(meshtastic_MeshPacket *p);
/* Statistics for the amount of duplicate received packets and the amount of times we cancel a relay because someone did it
before us */
@ -139,12 +140,14 @@ class Router : protected concurrency::OSThread, protected PacketHistory
void abortSendAndNak(meshtastic_Routing_Error err, meshtastic_MeshPacket *p);
};
enum DecodeState { DECODE_SUCCESS, DECODE_FAILURE, DECODE_FATAL };
/** FIXME - move this into a mesh packet class
* Remove any encryption and decode the protobufs inside this packet (if necessary).
*
* @return true for success, false for corrupt packet.
*/
bool perhapsDecode(meshtastic_MeshPacket *p);
DecodeState perhapsDecode(meshtastic_MeshPacket *p);
/** Return 0 for success or a Routing_Error code for failure
*/

View File

@ -18,10 +18,30 @@
#define MAX_RX_TOPHONE 32
#endif
/// max number of nodes allowed in the mesh
/// max number of nodes allowed in the nodeDB
#ifndef MAX_NUM_NODES
#if defined(ARCH_STM32WL)
#define MAX_NUM_NODES 10
#elif defined(ARCH_NRF52)
#define MAX_NUM_NODES 80
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
#include "Esp.h"
static inline int get_max_num_nodes()
{
uint32_t flash_size = ESP.getFlashChipSize() / (1024 * 1024); // Convert Bytes to MB
if (flash_size >= 15) {
return 250;
} else if (flash_size >= 7) {
return 200;
} else {
return 100;
}
}
#define MAX_NUM_NODES get_max_num_nodes()
#else
#define MAX_NUM_NODES 100
#endif
#endif
/// Max number of channels allowed
#define MAX_NUM_CHANNELS (member_size(meshtastic_ChannelFile, channels) / member_size(meshtastic_ChannelFile, channels[0]))

View File

@ -22,8 +22,13 @@ class UdpMulticastThread : public concurrency::OSThread
void start()
{
if (udp.listenMulticast(udpIpAddress, UDP_MULTICAST_DEFAUL_PORT)) {
if (udp.listenMulticast(udpIpAddress, UDP_MULTICAST_DEFAUL_PORT, 64)) {
#if !defined(ARCH_PORTDUINO)
// FIXME(PORTDUINO): arduino lacks IPAddress::toString()
LOG_DEBUG("UDP Listening on IP: %s", WiFi.localIP().toString().c_str());
#else
LOG_DEBUG("UDP Listening");
#endif
udp.onPacket([this](AsyncUDPPacket packet) { onReceive(packet); });
} else {
LOG_DEBUG("Failed to listen on UDP");
@ -33,12 +38,13 @@ class UdpMulticastThread : public concurrency::OSThread
void onReceive(AsyncUDPPacket packet)
{
size_t packetLength = packet.length();
#ifndef ARCH_PORTDUINO
// FIXME(PORTDUINO): arduino lacks IPAddress::toString()
LOG_DEBUG("UDP broadcast from: %s, len=%u", packet.remoteIP().toString().c_str(), packetLength);
#endif
meshtastic_MeshPacket mp;
uint8_t bytes[meshtastic_MeshPacket_size]; // Allocate buffer for the data
size_t packetSize = packet.readBytes(bytes, packet.length());
LOG_DEBUG("Decoding MeshPacket from UDP len=%u", packetSize);
bool isPacketDecoded = pb_decode_from_bytes(bytes, packetLength, &meshtastic_MeshPacket_msg, &mp);
LOG_DEBUG("Decoding MeshPacket from UDP len=%u", packetLength);
bool isPacketDecoded = pb_decode_from_bytes(packet.data(), packetLength, &meshtastic_MeshPacket_msg, &mp);
if (isPacketDecoded && router) {
UniquePacketPoolPacket p = packetPool.allocUniqueCopy(mp);
// Unset received SNR/RSSI
@ -50,13 +56,18 @@ class UdpMulticastThread : public concurrency::OSThread
bool onSend(const meshtastic_MeshPacket *mp)
{
if (!mp || WiFi.status() != WL_CONNECTED) {
if (!mp || !udp) {
return false;
}
#if !defined(ARCH_PORTDUINO)
if (WiFi.status() != WL_CONNECTED) {
return false;
}
#endif
LOG_DEBUG("Broadcasting packet over UDP (id=%u)", mp->id);
uint8_t buffer[meshtastic_MeshPacket_size];
size_t encodedLength = pb_encode_to_bytes(buffer, sizeof(buffer), &meshtastic_MeshPacket_msg, mp);
udp.broadcastTo(buffer, encodedLength, UDP_MULTICAST_DEFAUL_PORT);
udp.writeTo(buffer, encodedLength, udpIpAddress, UDP_MULTICAST_DEFAUL_PORT);
return true;
}
@ -72,4 +83,4 @@ class UdpMulticastThread : public concurrency::OSThread
IPAddress udpIpAddress;
AsyncUDP udp;
};
#endif // ARCH_ESP32
#endif // HAS_UDP_MULTICAST

View File

@ -10,6 +10,9 @@
#if defined(ARCH_ESP32) && !MESHTASTIC_EXCLUDE_BLUETOOTH
#include "BleOta.h"
#endif
#if defined(ARCH_ESP32) && !MESHTASTIC_EXCLUDE_WIFI
#include "WiFiOTA.h"
#endif
#include "Router.h"
#include "configuration.h"
#include "main.h"
@ -194,19 +197,23 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
}
case meshtastic_AdminMessage_reboot_ota_seconds_tag: {
int32_t s = r->reboot_ota_seconds;
#if defined(ARCH_ESP32) && !MESHTASTIC_EXCLUDE_BLUETOOTH
if (BleOta::getOtaAppVersion().isEmpty()) {
LOG_INFO("No OTA firmware available, scheduling regular reboot in %d seconds", s);
screen->startAlert("Rebooting...");
} else {
#if defined(ARCH_ESP32)
#if !MESHTASTIC_EXCLUDE_BLUETOOTH
if (!BleOta::getOtaAppVersion().isEmpty()) {
screen->startFirmwareUpdateScreen();
BleOta::switchToOtaApp();
LOG_INFO("Reboot to OTA in %d seconds", s);
LOG_INFO("Rebooting to BLE OTA");
}
#else
LOG_INFO("Not on ESP32, scheduling regular reboot in %d seconds", s);
screen->startAlert("Rebooting...");
#endif
#if !MESHTASTIC_EXCLUDE_WIFI
if (WiFiOTA::trySwitchToOTA()) {
screen->startFirmwareUpdateScreen();
WiFiOTA::saveConfig(&config.network);
LOG_INFO("Rebooting to WiFi OTA");
}
#endif
#endif
LOG_INFO("Reboot in %d seconds", s);
rebootAtMsec = (s < 0) ? 0 : (millis() + s * 1000);
break;
}
@ -370,6 +377,42 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
LOG_DEBUG("Failed to delete file");
}
spiLock->unlock();
#endif
break;
}
case meshtastic_AdminMessage_backup_preferences_tag: {
LOG_INFO("Client requesting to backup preferences");
if (nodeDB->backupPreferences(r->backup_preferences)) {
myReply = allocErrorResponse(meshtastic_Routing_Error_NONE, &mp);
} else {
myReply = allocErrorResponse(meshtastic_Routing_Error_BAD_REQUEST, &mp);
}
break;
}
case meshtastic_AdminMessage_restore_preferences_tag: {
LOG_INFO("Client requesting to restore preferences");
if (nodeDB->restorePreferences(r->backup_preferences,
SEGMENT_DEVICESTATE | SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_CHANNELS)) {
myReply = allocErrorResponse(meshtastic_Routing_Error_NONE, &mp);
LOG_DEBUG("Rebooting after successful restore of preferences");
reboot(1000);
disableBluetooth();
} else {
myReply = allocErrorResponse(meshtastic_Routing_Error_BAD_REQUEST, &mp);
}
break;
}
case meshtastic_AdminMessage_remove_backup_preferences_tag: {
LOG_INFO("Client requesting to remove backup preferences");
#ifdef FSCom
if (r->remove_backup_preferences == meshtastic_AdminMessage_BackupLocation_FLASH) {
spiLock->lock();
FSCom.remove(backupFileName);
spiLock->unlock();
} else if (r->remove_backup_preferences == meshtastic_AdminMessage_BackupLocation_SD) {
// TODO: After more mainline SD card support
LOG_ERROR("SD backup removal not implemented yet");
}
#endif
break;
}

View File

@ -1057,6 +1057,11 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
display->drawString(10 + x, 0 + y + FONT_HEIGHT_SMALL, "Canned Message\nModule disabled.");
} else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
requestFocus(); // Tell Screen::setFrames to move to our module's frame
#if defined(USE_EINK) && defined(USE_EINK_DYNAMICDISPLAY)
EInkDynamicDisplay *einkDisplay = static_cast<EInkDynamicDisplay *>(display);
einkDisplay->enableUnlimitedFastMode(); // Enable unlimited fast refresh while typing
#endif
#if defined(USE_VIRTUAL_KEYBOARD)
drawKeyboard(display, state, 0, 0);
#else

View File

@ -46,11 +46,6 @@ meshtastic_MeshPacket *RoutingModule::allocReply()
return NULL;
assert(currentRequest);
// We only consider making replies if the request was a legit routing packet (not just something we were sniffing)
if (currentRequest->decoded.portnum == meshtastic_PortNum_ROUTING_APP) {
assert(0); // 1.2 refactoring fixme, Not sure if anything needs this yet?
// return allocDataProtobuf(u);
}
return NULL;
}

View File

@ -468,81 +468,83 @@ void SerialModule::processWXSerial()
// Extract the current line
char line[meshtastic_Constants_DATA_PAYLOAD_LEN];
memset(line, '\0', sizeof(line));
memcpy(line, &serialBytes[lineStart], lineEnd - lineStart);
if (strstr(line, "Wind") != NULL) // we have a wind line
{
gotwind = true;
// Find the positions of "=" signs in the line
char *windDirPos = strstr(line, "WindDir = ");
char *windSpeedPos = strstr(line, "WindSpeed = ");
char *windGustPos = strstr(line, "WindGust = ");
if (lineEnd - lineStart < sizeof(line) - 1) {
memcpy(line, &serialBytes[lineStart], lineEnd - lineStart);
if (strstr(line, "Wind") != NULL) // we have a wind line
{
gotwind = true;
// Find the positions of "=" signs in the line
char *windDirPos = strstr(line, "WindDir = ");
char *windSpeedPos = strstr(line, "WindSpeed = ");
char *windGustPos = strstr(line, "WindGust = ");
if (windDirPos != NULL) {
// Extract data after "=" for WindDir
strcpy(windDir, windDirPos + 15); // Add 15 to skip "WindDir = "
double radians = GeoCoord::toRadians(strtof(windDir, nullptr));
dir_sum_sin += sin(radians);
dir_sum_cos += cos(radians);
dirCount++;
} else if (windSpeedPos != NULL) {
// Extract data after "=" for WindSpeed
strcpy(windVel, windSpeedPos + 15); // Add 15 to skip "WindSpeed = "
float newv = strtof(windVel, nullptr);
velSum += newv;
velCount++;
if (newv < lull || lull == -1)
lull = newv;
if (windDirPos != NULL) {
// Extract data after "=" for WindDir
strlcpy(windDir, windDirPos + 15, sizeof(windDir)); // Add 15 to skip "WindDir = "
double radians = GeoCoord::toRadians(strtof(windDir, nullptr));
dir_sum_sin += sin(radians);
dir_sum_cos += cos(radians);
dirCount++;
} else if (windSpeedPos != NULL) {
// Extract data after "=" for WindSpeed
strlcpy(windVel, windSpeedPos + 15, sizeof(windVel)); // Add 15 to skip "WindSpeed = "
float newv = strtof(windVel, nullptr);
velSum += newv;
velCount++;
if (newv < lull || lull == -1)
lull = newv;
} else if (windGustPos != NULL) {
strcpy(windGust, windGustPos + 15); // Add 15 to skip "WindSpeed = "
float newg = strtof(windGust, nullptr);
if (newg > gust)
gust = newg;
}
} else if (windGustPos != NULL) {
strlcpy(windGust, windGustPos + 15, sizeof(windGust)); // Add 15 to skip "WindSpeed = "
float newg = strtof(windGust, nullptr);
if (newg > gust)
gust = newg;
}
// these are also voltage data we care about possibly
} else if (strstr(line, "BatVoltage") != NULL) { // we have a battVoltage line
char *batVoltagePos = strstr(line, "BatVoltage = ");
if (batVoltagePos != NULL) {
strcpy(batVoltage, batVoltagePos + 17); // 18 for ws 80, 17 for ws85
batVoltageF = strtof(batVoltage, nullptr);
break; // last possible data we want so break
}
} else if (strstr(line, "CapVoltage") != NULL) { // we have a cappVoltage line
char *capVoltagePos = strstr(line, "CapVoltage = ");
if (capVoltagePos != NULL) {
strcpy(capVoltage, capVoltagePos + 17); // 18 for ws 80, 17 for ws85
capVoltageF = strtof(capVoltage, nullptr);
}
// GXTS04Temp = 24.4
} else if (strstr(line, "GXTS04Temp") != NULL) { // we have a temperature line
char *tempPos = strstr(line, "GXTS04Temp = ");
if (tempPos != NULL) {
strcpy(temperature, tempPos + 15); // 15 spaces for ws85
temperatureF = strtof(temperature, nullptr);
}
// these are also voltage data we care about possibly
} else if (strstr(line, "BatVoltage") != NULL) { // we have a battVoltage line
char *batVoltagePos = strstr(line, "BatVoltage = ");
if (batVoltagePos != NULL) {
strlcpy(batVoltage, batVoltagePos + 17, sizeof(batVoltage)); // 18 for ws 80, 17 for ws85
batVoltageF = strtof(batVoltage, nullptr);
break; // last possible data we want so break
}
} else if (strstr(line, "CapVoltage") != NULL) { // we have a cappVoltage line
char *capVoltagePos = strstr(line, "CapVoltage = ");
if (capVoltagePos != NULL) {
strlcpy(capVoltage, capVoltagePos + 17, sizeof(capVoltage)); // 18 for ws 80, 17 for ws85
capVoltageF = strtof(capVoltage, nullptr);
}
// GXTS04Temp = 24.4
} else if (strstr(line, "GXTS04Temp") != NULL) { // we have a temperature line
char *tempPos = strstr(line, "GXTS04Temp = ");
if (tempPos != NULL) {
strlcpy(temperature, tempPos + 15, sizeof(temperature)); // 15 spaces for ws85
temperatureF = strtof(temperature, nullptr);
}
} else if (strstr(line, "RainIntSum") != NULL) { // we have a rainsum line
// LOG_INFO(line);
char *pos = strstr(line, "RainIntSum = ");
if (pos != NULL) {
strcpy(rainStr, pos + 17); // 17 spaces for ws85
rainSum = int(strtof(rainStr, nullptr));
}
} else if (strstr(line, "Rain") != NULL) { // we have a rain line
if (strstr(line, "WaveRain") == NULL) { // skip WaveRain lines though.
} else if (strstr(line, "RainIntSum") != NULL) { // we have a rainsum line
// LOG_INFO(line);
char *pos = strstr(line, "Rain = ");
char *pos = strstr(line, "RainIntSum = ");
if (pos != NULL) {
strcpy(rainStr, pos + 17); // 17 spaces for ws85
rain = strtof(rainStr, nullptr);
strlcpy(rainStr, pos + 17, sizeof(rainStr)); // 17 spaces for ws85
rainSum = int(strtof(rainStr, nullptr));
}
} else if (strstr(line, "Rain") != NULL) { // we have a rain line
if (strstr(line, "WaveRain") == NULL) { // skip WaveRain lines though.
// LOG_INFO(line);
char *pos = strstr(line, "Rain = ");
if (pos != NULL) {
strlcpy(rainStr, pos + 17, sizeof(rainStr)); // 17 spaces for ws85
rain = strtof(rainStr, nullptr);
}
}
}
}
// Update lineStart for the next line
lineStart = lineEnd + 1;
// Update lineStart for the next line
lineStart = lineEnd + 1;
}
}
}
break;

View File

@ -117,7 +117,8 @@ inline void onReceiveProto(char *topic, byte *payload, size_t length)
// likely they discovered each other via a channel we have downlink enabled for
if (isToUs(p.get()) || (tx && tx->has_user && rx && rx->has_user))
router->enqueueReceivedMessage(p.release());
} else if (router && perhapsDecode(p.get())) // ignore messages if we don't have the channel key
} else if (router &&
perhapsDecode(p.get()) == DecodeState::DECODE_SUCCESS) // ignore messages if we don't have the channel key
router->enqueueReceivedMessage(p.release());
}

View File

@ -0,0 +1,92 @@
#include "WiFiOTA.h"
#include "configuration.h"
#include <Preferences.h>
#include <esp_ota_ops.h>
namespace WiFiOTA
{
static const char *nvsNamespace = "ota-wifi";
static const char *appProjectName = "OTA-WiFi";
static bool updated = false;
bool isUpdated()
{
return updated;
}
void initialize()
{
Preferences prefs;
prefs.begin(nvsNamespace);
if (prefs.getBool("updated")) {
LOG_INFO("First boot after OTA update");
updated = true;
prefs.putBool("updated", false);
}
prefs.end();
}
void recoverConfig(meshtastic_Config_NetworkConfig *network)
{
LOG_INFO("Recovering WiFi settings after OTA update");
Preferences prefs;
prefs.begin(nvsNamespace, true);
String ssid = prefs.getString("ssid");
String psk = prefs.getString("psk");
prefs.end();
network->wifi_enabled = true;
strncpy(network->wifi_ssid, ssid.c_str(), sizeof(network->wifi_ssid));
strncpy(network->wifi_psk, psk.c_str(), sizeof(network->wifi_psk));
}
void saveConfig(meshtastic_Config_NetworkConfig *network)
{
LOG_INFO("Saving WiFi settings for upcoming OTA update");
Preferences prefs;
prefs.begin(nvsNamespace);
prefs.putString("ssid", network->wifi_ssid);
prefs.putString("psk", network->wifi_psk);
prefs.putBool("updated", false);
prefs.end();
}
const esp_partition_t *getAppPartition()
{
return esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_1, NULL);
}
bool getAppDesc(const esp_partition_t *part, esp_app_desc_t *app_desc)
{
if (esp_ota_get_partition_description(part, app_desc) != ESP_OK)
return false;
if (strcmp(app_desc->project_name, appProjectName) != 0)
return false;
return true;
}
bool trySwitchToOTA()
{
const esp_partition_t *part = getAppPartition();
esp_app_desc_t app_desc;
if (!getAppDesc(part, &app_desc))
return false;
if (esp_ota_set_boot_partition(part) != ESP_OK)
return false;
return true;
}
String getVersion()
{
const esp_partition_t *part = getAppPartition();
esp_app_desc_t app_desc;
if (!getAppDesc(part, &app_desc))
return String();
return String(app_desc.version);
}
} // namespace WiFiOTA

View File

@ -0,0 +1,18 @@
#ifndef WIFIOTA_H
#define WIFIOTA_H
#include "mesh-pb-constants.h"
#include <Arduino.h>
namespace WiFiOTA
{
void initialize();
bool isUpdated();
void recoverConfig(meshtastic_Config_NetworkConfig *network);
void saveConfig(meshtastic_Config_NetworkConfig *network);
bool trySwitchToOTA();
String getVersion();
} // namespace WiFiOTA
#endif // WIFIOTA_H

View File

@ -9,6 +9,8 @@
#include "nimble/NimbleBluetooth.h"
#endif
#include <WiFiOTA.h>
#if HAS_WIFI
#include "mesh/wifi/WiFiAPClient.h"
#endif
@ -139,12 +141,19 @@ void esp32Setup()
#if !MESHTASTIC_EXCLUDE_BLUETOOTH
String BLEOTA = BleOta::getOtaAppVersion();
if (BLEOTA.isEmpty()) {
LOG_INFO("No OTA firmware available");
LOG_INFO("No BLE OTA firmware available");
} else {
LOG_INFO("OTA firmware version %s", BLEOTA.c_str());
LOG_INFO("BLE OTA firmware version %s", BLEOTA.c_str());
}
#else
LOG_INFO("No OTA firmware available");
#endif
#if !MESHTASTIC_EXCLUDE_WIFI
String version = WiFiOTA::getVersion();
if (version.isEmpty()) {
LOG_INFO("No WiFi OTA firmware available");
} else {
LOG_INFO("WiFi OTA firmware version %s", version.c_str());
}
WiFiOTA::initialize();
#endif
// enableModemSleep();

View File

@ -14,7 +14,6 @@ Do not expect a working Meshtastic device with this target.
#define _VARIANT_EBYTE_E77_
#define USE_STM32WLx
#define MAX_NUM_NODES 10
#define LED_PIN PB4 // LED1
// #define LED_PIN PB3 // LED2

View File

@ -5,6 +5,7 @@ board_build.flash_mode = qio
board_build.psram_type = opi
board_upload.flash_size = 8MB
board_upload.maximum_size = 8388608
board_build.partitions = default_8MB.csv
board = esp32-s3-devkitc-1
;upload_port = /dev/ttyUSB0
board_level = extra
@ -32,6 +33,7 @@ board_build.flash_mode = qio
board_build.psram_type = opi
board_upload.flash_size = 8MB
board_upload.maximum_size = 8388608
board_build.partitions = default_8MB.csv
board = esp32-s3-devkitc-1
;upload_port = /dev/ttyUSB0
board_level = extra
@ -59,6 +61,7 @@ board_build.flash_mode = qio
board_build.psram_type = opi
board_upload.flash_size = 8MB
board_upload.maximum_size = 8388608
board_build.partitions = default_8MB.csv
board = esp32-s3-devkitc-1
;upload_port = /dev/ttyUSB0
board_level = extra

View File

@ -88,6 +88,7 @@ debug_tool = jlink
[env:t-energy-s3_e22]
extends = esp32s3_base
board = esp32-s3-devkitc-1
board_build.partitions = default_16MB.csv
board_level = extra
board_upload.flash_size = 16MB ;Specify the FLASH capacity as 16MB
board_build.arduino.memory_type = qio_opi ;Enable internal PSRAM

View File

@ -1,6 +1,7 @@
[env:dreamcatcher] ; 2301, latest revision
extends = esp32s3_base
board = esp32s3box
board_build.partitions = default_16MB.csv
board_level = extra
build_flags =
@ -8,7 +9,7 @@ build_flags =
-D PRIVATE_HW
-D OTHERNET_DC_REV=2301
-I variants/dreamcatcher
-DARDUINO_USB_CDC_ON_BOOT=1
-D ARDUINO_USB_CDC_ON_BOOT=1
lib_deps = ${esp32s3_base.lib_deps}
earlephilhower/ESP8266Audio@^1.9.9
@ -17,6 +18,7 @@ lib_deps = ${esp32s3_base.lib_deps}
[env:dreamcatcher-2206]
extends = esp32s3_base
board = esp32s3box
board_build.partitions = default_16MB.csv
board_level = extra
build_flags =
@ -24,4 +26,4 @@ build_flags =
-D PRIVATE_HW
-D OTHERNET_DC_REV=2206
-I variants/dreamcatcher
-DARDUINO_USB_CDC_ON_BOOT=1
-D ARDUINO_USB_CDC_ON_BOOT=1

View File

@ -4,6 +4,7 @@ board_level = extra
extends = esp32s3_base
upload_protocol = esptool
board = esp32-s3-pico
board_build.partitions = default_16MB.csv
board_upload.use_1200bps_touch = yes
board_upload.wait_for_upload_port = yes

View File

@ -2,7 +2,7 @@
extends = esp32s3_base
board = heltec_wifi_lora_32_V3
board_check = true
board_build.partitions = default_8MB.csv
build_flags =
${esp32s3_base.build_flags} -I variants/heltec_capsule_sensor_v3
-D HELTEC_CAPSULE_SENSOR_V3

View File

@ -2,7 +2,7 @@
extends = esp32s3_base
board = heltec_wifi_lora_32_V3
board_check = true
# Temporary until espressif creates a release with this new target
board_build.partitions = default_8MB.csv
build_flags =
${esp32s3_base.build_flags} -D HELTEC_V3 -I variants/heltec_v3
-DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
-D GPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.

View File

@ -1,6 +1,7 @@
[env:heltec-vision-master-e213]
extends = esp32s3_base
board = heltec_vision_master_e213
board_build.partitions = default_8MB.csv
build_flags =
${esp32s3_base.build_flags}
-Ivariants/heltec_vision_master_e213
@ -22,6 +23,7 @@ upload_speed = 115200
[env:heltec-vision-master-e213-inkhud]
extends = esp32s3_base, inkhud
board = heltec_vision_master_e213
board_build.partitions = default_8MB.csv
build_src_filter =
${esp32_base.build_src_filter}
${inkhud.build_src_filter}

View File

@ -2,6 +2,7 @@
[env:heltec-vision-master-e290]
extends = esp32s3_base
board = heltec_vision_master_e290
board_build.partitions = default_8MB.csv
build_flags =
${esp32s3_base.build_flags}
-I variants/heltec_vision_master_e290
@ -26,6 +27,7 @@ upload_speed = 115200
[env:heltec-vision-master-e290-inkhud]
extends = esp32s3_base, inkhud
board = heltec_vision_master_e290
board_build.partitions = default_8MB.csv
build_src_filter =
${esp32_base.build_src_filter}
${inkhud.build_src_filter}

View File

@ -1,11 +1,11 @@
[env:heltec-vision-master-t190]
extends = esp32s3_base
board = heltec_vision_master_t190
board_build.partitions = default_8MB.csv
build_flags =
${esp32s3_base.build_flags}
-Ivariants/heltec_vision_master_t190
-DHELTEC_VISION_MASTER_T190
; -D PRIVATE_HW
lib_deps =
${esp32s3_base.lib_deps}
lewisxhe/PCF8563_Library@^1.0.1

View File

@ -2,6 +2,7 @@
[env:heltec-wireless-paper]
extends = esp32s3_base
board = heltec_wifi_lora_32_V3
board_build.partitions = default_8MB.csv
build_flags =
${esp32s3_base.build_flags}
-I variants/heltec_wireless_paper
@ -23,6 +24,7 @@ upload_speed = 115200
[env:heltec-wireless-paper-inkhud]
extends = esp32s3_base, inkhud
board = heltec_wifi_lora_32_V3
board_build.partitions = default_8MB.csv
build_src_filter =
${esp32_base.build_src_filter}
${inkhud.build_src_filter}

View File

@ -2,6 +2,7 @@
extends = esp32s3_base
board_level = extra
board = heltec_wifi_lora_32_V3
board_build.partitions = default_8MB.csv
build_flags =
${esp32s3_base.build_flags}
-I variants/heltec_wireless_paper_v1

View File

@ -1,6 +1,7 @@
[env:heltec-wireless-tracker]
extends = esp32s3_base
board = heltec_wireless_tracker
board_build.partitions = default_8MB.csv
upload_protocol = esptool
build_flags =

View File

@ -2,6 +2,7 @@
extends = esp32s3_base
board_level = extra
board = heltec_wireless_tracker
board_build.partitions = default_8MB.csv
upload_protocol = esptool
build_flags =
${esp32s3_base.build_flags} -I variants/heltec_wireless_tracker_V1_0

View File

@ -1,7 +1,8 @@
[env:heltec-wsl-v3]
extends = esp32s3_base
board = heltec_wifi_lora_32_V3
board_build.partitions = default_8MB.csv
# Temporary until espressif creates a release with this new target
build_flags =
${esp32s3_base.build_flags} -D HELTEC_WSL_V3 -I variants/heltec_wsl_v3
-DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
-D GPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.

View File

@ -4,6 +4,7 @@ board = icarus
board_level = extra
board_check = true
board_build.mcu = esp32s3
board_build.partitions = default_8MB.csv
upload_protocol = esptool
upload_speed = 921600
platform_packages = platformio/framework-arduinoespressif32@https://github.com/PowerFeather/powerfeather-meshtastic-arduino-lib/releases/download/2.0.16a/esp32-2.0.16.zip
@ -15,5 +16,4 @@ build_unflags =
build_flags =
${esp32s3_base.build_flags} -D PRIVATE_HW -I variants/icarus
-DBOARD_HAS_PSRAM
-DARDUINO_USB_MODE=0

View File

@ -3,6 +3,7 @@
extends = esp32s3_base
board = m5stack-cores3
board_check = true
board_build.partitions = default_16MB.csv
upload_protocol = esptool
build_flags = ${esp32_base.build_flags}

View File

@ -28,7 +28,6 @@ build_flags = ${esp32s3_base.build_flags}
-D USE_LOG_DEBUG
-D LOG_DEBUG_INC=\"DebugConfiguration.h\"
-D RADIOLIB_SPI_PARANOID=0
-D MAX_NUM_NODES=250
-D MAX_THREADS=40
-D HAS_SCREEN=0
-D HAS_TFT=1

View File

@ -2,6 +2,7 @@
extends = esp32s3_base
board = bpi_picow_esp32_s3
board_check = true
board_build.partitions = default_8MB.csv
;OpenOCD flash method
;upload_protocol = esp-builtin
;Normal method
@ -22,7 +23,6 @@ build_src_filter =
[env:picomputer-s3-tft]
extends = env:picomputer-s3
board_build.partitions = default_8MB.csv ; just for test
build_flags =
${env:picomputer-s3.build_flags}
@ -35,7 +35,6 @@ build_flags =
-D INPUTDRIVER_MATRIX_TYPE=1
-D USE_PIN_BUZZER=PIN_BUZZER
-D USE_SX127x
-D MAX_NUM_NODES=200
-D HAS_SCREEN=0
-D HAS_TFT=1
-D RAM_SIZE=1024

View File

@ -7,6 +7,5 @@ Do not expect a working Meshtastic device with this target.
#define _VARIANT_RAK3172_
#define USE_STM32WLx
#define MAX_NUM_NODES 10
#endif

View File

@ -23,6 +23,7 @@ build_flags = ${rp2350_base.build_flags}
-DHAS_WIFI=1
-L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/cortex-m33"
-fexceptions # for exception handling in MQTT
-DHAS_UDP_MULTICAST=1
build_src_filter = ${rp2350_base.build_src_filter} +<mesh/wifi/>
lib_deps =
${rp2350_base.lib_deps}

View File

@ -10,6 +10,7 @@ build_flags = ${rp2040_base.build_flags}
-DHW_SPI1_DEVICE
-L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/cortex-m0plus"
-fexceptions # for exception handling in MQTT
-DHAS_UDP_MULTICAST=1
build_src_filter = ${rp2040_base.build_src_filter} +<mesh/wifi/>
lib_deps =
${rp2040_base.lib_deps}

View File

@ -6,6 +6,7 @@ platform_packages =
board = seeed-sensecap-indicator
board_check = true
board_build.partitions = default_8MB.csv
upload_protocol = esptool
build_flags = ${esp32_base.build_flags}
@ -32,7 +33,6 @@ lib_deps = ${esp32s3_base.lib_deps}
extends = env:seeed-sensecap-indicator
board_level = main
upload_speed = 460800
board_build.partitions = default_8MB.csv ; must be here for some reason, board.json is not enough !?
build_flags =
${env:seeed-sensecap-indicator.build_flags}
@ -46,7 +46,6 @@ build_flags =
-D INPUTDRIVER_BUTTON_TYPE=38
-D HAS_TELEMETRY=0
-D CONFIG_DISABLE_HAL_LOCKS=1
-D MAX_NUM_NODES=250
-D HAS_SCREEN=0
-D HAS_TFT=1
-D DISPLAY_SET_RESOLUTION

View File

@ -1,8 +1,8 @@
#include "variant.h"
#include "configuration.h"
#include "nrf.h"
#include "wiring_constants.h"
#include "wiring_digital.h"
#include "configuration.h"
#include <map>
#include <memory>
#include <stddef.h>
@ -58,8 +58,6 @@ const uint32_t g_ADigitalPinMap[] = {
31, // D32 is P0.10 (VBAT)
};
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
Copyright (c) 2016 Sandeep Mistry All right reserved.
@ -80,7 +78,6 @@ const uint32_t g_ADigitalPinMap[] = {
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
void initVariant()
{
// LED1 & LED2

View File

@ -43,7 +43,6 @@ extern "C" {
* Buttons
*/
// Digital PINs
#define D0 (0ul)
#define D1 (1ul)
@ -57,11 +56,15 @@ extern "C" {
#define D9 (9ul)
#define D10 (10ul)
/*Due to the lack of pins,and have to make sure gps standby work well we have temporarily removed the button.
There are some technical solutions that can solve this problem,
and we are currently exploring and researching them*/
// #define BUTTON_PIN D0 // This is the Program Button
// // #define BUTTON_NEED_PULLUP 1
// #define BUTTON_ACTIVE_LOW true
// #define BUTTON_ACTIVE_PULLUP false
#define BUTTON_PIN D0 // This is the Program Button
// #define BUTTON_NEED_PULLUP 1
#define BUTTON_ACTIVE_LOW true
#define BUTTON_ACTIVE_PULLUP false
/*
* Analog pins
*/
@ -82,7 +85,6 @@ static const uint8_t A4 = PIN_A4;
static const uint8_t A5 = PIN_A5;
#define ADC_RESOLUTION 12
#define PIN_SERIAL2_RX (-1)
#define PIN_SERIAL2_TX (-1)
@ -95,7 +97,6 @@ static const uint8_t A5 = PIN_A5;
#define PIN_SPI_MOSI (10)
#define PIN_SPI_SCK (8)
static const uint8_t SS = D4;
static const uint8_t MOSI = PIN_SPI_MOSI;
static const uint8_t MISO = PIN_SPI_MISO;
@ -113,40 +114,36 @@ static const uint8_t SCK = PIN_SPI_SCK;
#define SX126X_TXEN RADIOLIB_NC
#define SX126X_RXEN D4
#define SX126X_DIO2_AS_RF_SWITCH // DIO2 is used to control the RF switch really necessary!!!
#define SX126X_DIO2_AS_RF_SWITCH // DIO2 is used to control the RF switch really necessary!!!
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
/*
* Wire Interfaces
*/
#define I2C_NO_RESCAN // I2C is a bit finicky, don't scan too much
#define I2C_NO_RESCAN // I2C is a bit finicky, don't scan too much
#define WIRE_INTERFACES_COUNT 1 // 2
#define PIN_WIRE_SDA (24) //change to use the correct pins if needed
#define PIN_WIRE_SCL (25) //change to use the correct pins if needed
#define PIN_WIRE_SDA (24) // change to use the correct pins if needed
#define PIN_WIRE_SCL (25) // change to use the correct pins if needed
static const uint8_t SDA = PIN_WIRE_SDA;
static const uint8_t SCL = PIN_WIRE_SCL;
// GPS L76KB
#define GPS_L76K
#ifdef GPS_L76K
#define PIN_GPS_RX 32+12 // 44
#define PIN_GPS_TX 32+11 // 43
#define PIN_GPS_RX D6
#define PIN_GPS_TX D7
#define HAS_GPS 1
#define GPS_BAUDRATE 9600
#define GPS_THREAD_INTERVAL 50
#define PIN_SERIAL1_RX PIN_GPS_TX
#define PIN_SERIAL1_TX PIN_GPS_RX
#define PIN_GPS_STANDBY 2
#define PIN_GPS_STANDBY D0
#endif
// Battery
#define BAT_READ \

View File

@ -2,7 +2,7 @@
extends = esp32s3_base
board = seeed-xiao-s3
board_check = true
board_build.mcu = esp32s3
board_build.partitions = default_8MB.csv
upload_protocol = esptool
upload_speed = 921600
lib_deps =

View File

@ -2,6 +2,7 @@
extends = esp32s3_base
board = station-g2
board_check = true
board_build.partitions = default_16MB.csv
board_build.mcu = esp32s3
upload_protocol = esptool
;upload_port = /dev/ttyACM0

View File

@ -3,6 +3,7 @@
extends = esp32s3_base
board = t-deck
board_check = true
board_build.partitions = default_16MB.csv
upload_protocol = esptool
build_flags = ${esp32s3_base.build_flags}
@ -20,7 +21,6 @@ lib_deps = ${esp32s3_base.lib_deps}
[env:t-deck-tft]
extends = env:t-deck
board_build.partitions = default_16MB.csv
build_flags =
${env:t-deck.build_flags}
@ -38,7 +38,6 @@ build_flags =
-D INPUTDRIVER_ENCODER_DOWN=15
-D INPUTDRIVER_ENCODER_BTN=0
-D INPUTDRIVER_BUTTON_TYPE=0
-D MAX_NUM_NODES=250
-D HAS_SDCARD
-D HAS_SCREEN=0
-D HAS_TFT=1

View File

@ -2,11 +2,12 @@
extends = esp32s3_base
board = esp32s3box
board_check = true
board_build.partitions = default_16MB.csv
build_flags =
${esp32s3_base.build_flags}
-D T_ETH_ELITE
-I variants/t-eth-elite
-DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
-D GPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
lib_ignore =
Ethernet

View File

@ -3,6 +3,7 @@
extends = esp32s3_base
board = t-watch-s3
board_check = true
board_build.partitions = default_16MB.csv
upload_protocol = esptool
build_flags = ${esp32_base.build_flags}

View File

@ -2,6 +2,7 @@
[env:tbeam-s3-core]
extends = esp32s3_base
board = tbeam-s3-core
board_build.partitions = default_8MB.csv
board_check = true
lib_deps =

View File

@ -1,6 +1,7 @@
[env:tracksenger]
extends = esp32s3_base
board = heltec_wireless_tracker
board_build.partitions = default_8MB.csv
upload_protocol = esp-builtin
build_flags =
@ -16,6 +17,7 @@ lib_deps =
[env:tracksenger-lcd]
extends = esp32s3_base
board = heltec_wireless_tracker
board_build.partitions = default_8MB.csv
upload_protocol = esp-builtin
build_flags =
@ -31,6 +33,7 @@ lib_deps =
[env:tracksenger-oled]
extends = esp32s3_base
board = heltec_wireless_tracker
board_build.partitions = default_8MB.csv
upload_protocol = esp-builtin
build_flags =

View File

@ -3,6 +3,7 @@
[env:unphone]
extends = esp32s3_base
board = unphone
board_build.partitions = default_8MB.csv
upload_speed = 921600
monitor_speed = 115200
monitor_filters = esp32_exception_decoder
@ -32,7 +33,6 @@ lib_deps = ${esp32s3_base.lib_deps}
[env:unphone-tft]
extends = env:unphone
board_build.partitions = default_8MB.csv
build_flags =
${env:unphone.build_flags}
-D MESHTASTIC_EXCLUDE_CANNEDMESSAGES=1
@ -42,7 +42,6 @@ build_flags =
-D MESHTASTIC_EXCLUDE_SERIAL=1
-D MESHTASTIC_EXCLUDE_SOCKETAPI=1
-D INPUTDRIVER_BUTTON_TYPE=21
-D MAX_NUM_NODES=200
-D MAX_THREADS=40
-D HAS_SCREEN=0
-D HAS_TFT=1

View File

@ -13,7 +13,6 @@ Do not expect a working Meshtastic device with this target.
#define _VARIANT_WIOE5_
#define USE_STM32WLx
#define MAX_NUM_NODES 10
#define LED_PIN PB5
#define LED_STATE_ON 1

View File

@ -1,4 +1,4 @@
[VERSION]
major = 2
minor = 6
build = 1
build = 2