diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml
index 693a2284d..1f13c1ee7 100644
--- a/.trunk/trunk.yaml
+++ b/.trunk/trunk.yaml
@@ -9,7 +9,7 @@ plugins:
lint:
enabled:
- checkov@3.2.436
- - renovate@40.41.0
+ - renovate@40.42.2
- prettier@3.5.3
- trufflehog@3.88.35
- yamllint@1.37.1
diff --git a/alpine.Dockerfile b/alpine.Dockerfile
index bf7cad6d4..670736241 100644
--- a/alpine.Dockerfile
+++ b/alpine.Dockerfile
@@ -3,7 +3,7 @@
# trunk-ignore-all(hadolint/DL3018): Do not pin apk package versions
# trunk-ignore-all(hadolint/DL3013): Do not pin pip package versions
-FROM python:3.13-alpine3.21 AS builder
+FROM python:3.13-alpine3.22 AS builder
ARG PIO_ENV=native
ENV PIP_ROOT_USER_ACTION=ignore
@@ -27,7 +27,7 @@ RUN bash ./bin/build-native.sh "$PIO_ENV" && \
# ##### PRODUCTION BUILD #############
-FROM alpine:3.21
+FROM alpine:3.22
LABEL org.opencontainers.image.title="Meshtastic" \
org.opencontainers.image.description="Alpine Meshtastic daemon" \
org.opencontainers.image.url="https://meshtastic.org" \
diff --git a/arch/esp32/esp32.ini b/arch/esp32/esp32.ini
index a6eff7bf9..cba84181b 100644
--- a/arch/esp32/esp32.ini
+++ b/arch/esp32/esp32.ini
@@ -4,7 +4,7 @@ extends = arduino_base
custom_esp32_kind = esp32
platform =
# renovate: datasource=custom.pio depName=platformio/espressif32 packageName=platformio/platform/espressif32
- platformio/espressif32@6.10.0
+ platformio/espressif32@6.11.0
build_src_filter =
${arduino_base.build_src_filter} - - - - -
diff --git a/bin/device-install.sh b/bin/device-install.sh
index 76765bb5f..2250db4fc 100755
--- a/bin/device-install.sh
+++ b/bin/device-install.sh
@@ -33,47 +33,47 @@ BIGDB_16MB=(
"ESP32-S3-Pico"
"m5stack-cores3"
"station-g2"
- "t-eth-elite"
- "t-watch-s3"
+ "t-eth-elite"
+ "t-watch-s3"
)
S3_VARIANTS=(
- "s3"
- "-v3"
- "t-deck"
- "wireless-paper"
- "wireless-tracker"
- "station-g2"
- "unphone"
- "t-eth-elite"
- "mesh-tab"
- "dreamcatcher"
- "ESP32-S3-Pico"
- "seeed-sensecap-indicator"
- "heltec_capsule_sensor_v3"
- "vision-master"
- "icarus"
- "tracksenger"
- "elecrow-adv"
+ "s3"
+ "-v3"
+ "t-deck"
+ "wireless-paper"
+ "wireless-tracker"
+ "station-g2"
+ "unphone"
+ "t-eth-elite"
+ "mesh-tab"
+ "dreamcatcher"
+ "ESP32-S3-Pico"
+ "seeed-sensecap-indicator"
+ "heltec_capsule_sensor_v3"
+ "vision-master"
+ "icarus"
+ "tracksenger"
+ "elecrow-adv"
)
# Determine the correct esptool command to use
if "$PYTHON" -m esptool version >/dev/null 2>&1; then
- ESPTOOL_CMD="$PYTHON -m esptool"
+ ESPTOOL_CMD="$PYTHON -m esptool"
elif command -v esptool >/dev/null 2>&1; then
- ESPTOOL_CMD="esptool"
+ ESPTOOL_CMD="esptool"
elif command -v esptool.py >/dev/null 2>&1; then
- ESPTOOL_CMD="esptool.py"
+ ESPTOOL_CMD="esptool.py"
else
- echo "Error: esptool not found"
- exit 1
+ echo "Error: esptool not found"
+ exit 1
fi
set -e
# Usage info
show_help() {
- cat <&2
- exit 1
- ;;
- esac
- shift # Move to the next argument
+ case "$1" in
+ -h | --help)
+ show_help
+ exit 0
+ ;;
+ -p)
+ ESPTOOL_CMD="$ESPTOOL_CMD --port $2"
+ shift
+ ;;
+ -P)
+ PYTHON="$2"
+ shift
+ ;;
+ -f)
+ FILENAME="$2"
+ shift
+ ;;
+ --web)
+ WEB_APP=true
+ ;;
+ --1200bps-reset)
+ BPS_RESET=true
+ ;;
+ --) # Stop parsing options
+ shift
+ break
+ ;;
+ *)
+ echo "Unknown argument: $1" >&2
+ exit 1
+ ;;
+ esac
+ shift # Move to the next argument
done
if [[ $BPS_RESET == true ]]; then
@@ -127,100 +127,100 @@ if [[ $BPS_RESET == true ]]; then
exit 0
fi
-[ -z "$FILENAME" -a -n "$1" ] && {
- FILENAME=$1
- shift
+[ -z "$FILENAME" ] && [ -n "$1" ] && {
+ FILENAME="$1"
+ shift
}
-if [[ $FILENAME != firmware-* ]]; then
+if [[ "$FILENAME" != firmware-* ]]; then
echo "Filename must be a firmware-* file."
exit 1
fi
# 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//-tft-/}" != "$FILENAME" ]]; then
+ TFT_BUILD=true
+ if [[ $WEB_APP == true ]] && [[ $TFT_BUILD == true ]]; then
+ echo "Cannot enable WebUI (--web) and MUI."
+ exit 1
+ fi
fi
# Extract BASENAME from %FILENAME% for later use.
BASENAME="${FILENAME/firmware-/}"
if [ -f "${FILENAME}" ] && [ -n "${FILENAME##*"update"*}" ]; then
- # Default littlefs* offset (--web).
- OFFSET=0x300000
+ # Default littlefs* offset (--web).
+ OFFSET=0x300000
- # Default OTA Offset
- OTA_OFFSET=0x260000
+ # Default OTA Offset
+ OTA_OFFSET=0x260000
- # littlefs* offset for BigDB 8mb and OTA OFFSET.
- for variant in "${BIGDB_8MB[@]}"; do
- if [ -z "${FILENAME##*"$variant"*}" ]; then
- OFFSET=0x670000
- OTA_OFFSET=0x340000
- fi
- done
+ # littlefs* offset for BigDB 8mb and OTA OFFSET.
+ for variant in "${BIGDB_8MB[@]}"; do
+ if [ -z "${FILENAME##*"$variant"*}" ]; then
+ OFFSET=0x670000
+ OTA_OFFSET=0x340000
+ fi
+ done
- # littlefs* offset for BigDB 16mb and OTA OFFSET.
- for variant in "${BIGDB_16MB[@]}"; do
- if [ -z "${FILENAME##*"$variant"*}" ]; then
- OFFSET=0xc90000
- OTA_OFFSET=0x650000
- fi
- done
+ # littlefs* offset for BigDB 16mb and OTA OFFSET.
+ for variant in "${BIGDB_16MB[@]}"; do
+ if [ -z "${FILENAME##*"$variant"*}" ]; then
+ OFFSET=0xc90000
+ OTA_OFFSET=0x650000
+ fi
+ done
- # Account for S3 board's different OTA partition
- # FIXME: Use PlatformIO info to determine MCU type, this is unmaintainable
- for variant in "${S3_VARIANTS[@]}"; do
- if [ -z "${FILENAME##*"$variant"*}" ]; then
- MCU="esp32s3"
- fi
- done
+ # Account for S3 board's different OTA partition
+ # FIXME: Use PlatformIO info to determine MCU type, this is unmaintainable
+ for variant in "${S3_VARIANTS[@]}"; do
+ if [ -z "${FILENAME##*"$variant"*}" ]; then
+ MCU="esp32s3"
+ fi
+ done
- if [ "$MCU" != "esp32s3" ]; then
- if [ -n "${FILENAME##*"esp32c3"*}" ]; then
- OTAFILE=bleota.bin
- else
- OTAFILE=bleota-c3.bin
- fi
- else
- OTAFILE=bleota-s3.bin
- fi
+ if [ "$MCU" != "esp32s3" ]; then
+ if [ -n "${FILENAME##*"esp32c3"*}" ]; then
+ OTAFILE=bleota.bin
+ else
+ OTAFILE=bleota-c3.bin
+ fi
+ else
+ OTAFILE=bleota-s3.bin
+ fi
- # Check if WEB_APP (--web) is enabled and add "littlefswebui-" to BASENAME else "littlefs-".
- if [ "$WEB_APP" = true ]; then
- SPIFFSFILE=littlefswebui-${BASENAME}
- else
- SPIFFSFILE=littlefs-${BASENAME}
- fi
+ # Check if WEB_APP (--web) is enabled and add "littlefswebui-" to BASENAME else "littlefs-".
+ if [ "$WEB_APP" = true ]; then
+ SPIFFSFILE=littlefswebui-${BASENAME}
+ else
+ SPIFFSFILE=littlefs-${BASENAME}
+ fi
- if [[ ! -f $FILENAME ]]; then
- echo "Error: file ${FILENAME} wasn't found. Terminating."
- exit 1
- fi
- if [[ ! -f $OTAFILE ]]; then
- echo "Error: file ${OTAFILE} wasn't found. Terminating."
- exit 1
- fi
- if [[ ! -f $SPIFFSFILE ]]; then
- echo "Error: file ${SPIFFSFILE} wasn't found. Terminating."
- exit 1
- fi
+ if [[ ! -f "$FILENAME" ]]; then
+ echo "Error: file ${FILENAME} wasn't found. Terminating."
+ exit 1
+ fi
+ if [[ ! -f "$OTAFILE" ]]; then
+ echo "Error: file ${OTAFILE} wasn't found. Terminating."
+ exit 1
+ fi
+ if [[ ! -f "$SPIFFSFILE" ]]; then
+ echo "Error: file ${SPIFFSFILE} wasn't found. Terminating."
+ exit 1
+ fi
- echo "Trying to flash ${FILENAME}, but first erasing and writing system information"
- $ESPTOOL_CMD erase_flash
- $ESPTOOL_CMD write_flash 0x00 "${FILENAME}"
- echo "Trying to flash ${OTAFILE} at offset ${OTA_OFFSET}"
- $ESPTOOL_CMD write_flash $OTA_OFFSET "${OTAFILE}"
- echo "Trying to flash ${SPIFFSFILE}, at offset ${OFFSET}"
- $ESPTOOL_CMD write_flash $OFFSET "${SPIFFSFILE}"
+ echo "Trying to flash ${FILENAME}, but first erasing and writing system information"
+ $ESPTOOL_CMD erase_flash
+ $ESPTOOL_CMD write_flash 0x00 "${FILENAME}"
+ echo "Trying to flash ${OTAFILE} at offset ${OTA_OFFSET}"
+ $ESPTOOL_CMD write_flash $OTA_OFFSET "${OTAFILE}"
+ echo "Trying to flash ${SPIFFSFILE}, at offset ${OFFSET}"
+ $ESPTOOL_CMD write_flash $OFFSET "${SPIFFSFILE}"
else
- show_help
- echo "Invalid file: ${FILENAME}"
+ show_help
+ echo "Invalid file: ${FILENAME}"
fi
exit 0
diff --git a/bin/device-update.sh b/bin/device-update.sh
index c32b953e6..6adfe4e0e 100755
--- a/bin/device-update.sh
+++ b/bin/device-update.sh
@@ -18,8 +18,8 @@ fi
# Usage info
show_help() {
cat << EOF
-Usage: $(basename $0) [-h] [-p ESPTOOL_PORT] [-P PYTHON] [-f FILENAME|FILENAME] [--change-mode]
-Flash image file to device, leave existing system intact.
+Usage: $(basename "$0") [-h] [-p ESPTOOL_PORT] [-P PYTHON] [-f FILENAME|FILENAME] [--change-mode]
+Flash image file to device, leave existing system intact."
-h Display this help and exit
-p ESPTOOL_PORT Set the environment variable for ESPTOOL_PORT. If not set, ESPTOOL iterates all ports (Dangerous).
@@ -38,7 +38,7 @@ while getopts ":hp:P:f:" opt; do
exit 0
;;
p) ESPTOOL_CMD="$ESPTOOL_CMD --port ${OPTARG}"
- ;;
+ ;;
P) PYTHON=${OPTARG}
;;
f) FILENAME=${OPTARG}
@@ -47,7 +47,7 @@ while getopts ":hp:P:f:" opt; do
CHANGE_MODE=true
;;
*)
- echo "Invalid flag."
+ echo "Invalid flag."
show_help >&2
exit 1
;;
@@ -60,17 +60,17 @@ if [[ $CHANGE_MODE == true ]]; then
exit 0
fi
-[ -z "$FILENAME" -a -n "$1" ] && {
- FILENAME=$1
+[ -z "$FILENAME" ] && [ -n "$1" ] && {
+ FILENAME="$1"
shift
}
if [ -f "${FILENAME}" ] && [ -z "${FILENAME##*"update"*}" ]; then
- printf "Trying to flash update ${FILENAME}"
- $ESPTOOL_CMD --baud 115200 write_flash 0x10000 ${FILENAME}
+ echo "Trying to flash update ${FILENAME}"
+ $ESPTOOL_CMD --baud 115200 write_flash 0x10000 "${FILENAME}"
else
- show_help
- echo "Invalid file: ${FILENAME}"
+ show_help
+ echo "Invalid file: ${FILENAME}"
fi
exit 0
diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp
index 8cdcc2dd0..84091a4f0 100644
--- a/src/mesh/NodeDB.cpp
+++ b/src/mesh/NodeDB.cpp
@@ -499,9 +499,25 @@ void NodeDB::installDefaultConfig(bool preserveKey = false)
true; // FIXME: maybe false in the future, and setting region to enable it. (unset region forces it off)
config.lora.override_duty_cycle = false;
config.lora.config_ok_to_mqtt = false;
+
#if HAS_TFT // For the devices that support MUI, default to that
config.display.displaymode = meshtastic_Config_DisplayConfig_DisplayMode_COLOR;
#endif
+
+#ifdef USERPREFS_CONFIG_DEVICE_ROLE
+ // Restrict ROUTER*, LOST AND FOUND, and REPEATER roles for security reasons
+ if (IS_ONE_OF(USERPREFS_CONFIG_DEVICE_ROLE, meshtastic_Config_DeviceConfig_Role_ROUTER,
+ meshtastic_Config_DeviceConfig_Role_ROUTER_LATE, meshtastic_Config_DeviceConfig_Role_REPEATER,
+ meshtastic_Config_DeviceConfig_Role_LOST_AND_FOUND)) {
+ LOG_WARN("ROUTER roles are restricted, falling back to CLIENT role");
+ config.device.role = meshtastic_Config_DeviceConfig_Role_CLIENT;
+ } else {
+ config.device.role = USERPREFS_CONFIG_DEVICE_ROLE;
+ }
+#else
+ config.device.role = meshtastic_Config_DeviceConfig_Role_CLIENT; // Default to client.
+#endif
+
#ifdef USERPREFS_CONFIG_LORA_REGION
config.lora.region = USERPREFS_CONFIG_LORA_REGION;
#else
@@ -674,6 +690,11 @@ void NodeDB::installDefaultConfig(bool preserveKey = false)
}
#endif
+#ifdef USERPREFS_CONFIG_DEVICE_ROLE
+ // Apply role-specific defaults when role is set via user preferences
+ installRoleDefaults(config.device.role);
+#endif
+
initConfigIntervals();
}
@@ -1819,4 +1840,4 @@ void recordCriticalError(meshtastic_CriticalErrorCode code, uint32_t address, co
LOG_ERROR("A critical failure occurred, portduino is exiting");
exit(2);
#endif
-}
\ No newline at end of file
+}