mirror of
https://github.com/meshtastic/firmware.git
synced 2025-10-28 15:22:55 +00:00
Merge pull request #7862 from meshtastic/master
Some checks are pending
CI / setup (check) (push) Waiting to run
CI / setup (esp32) (push) Waiting to run
CI / setup (esp32c3) (push) Waiting to run
CI / setup (esp32c6) (push) Waiting to run
CI / setup (esp32s3) (push) Waiting to run
CI / setup (nrf52840) (push) Waiting to run
CI / setup (rp2040) (push) Waiting to run
CI / setup (rp2350) (push) Waiting to run
CI / setup (stm32) (push) Waiting to run
CI / version (push) Waiting to run
CI / check (push) Blocked by required conditions
CI / build-esp32 (push) Blocked by required conditions
CI / build-esp32s3 (push) Blocked by required conditions
CI / build-esp32c3 (push) Blocked by required conditions
CI / build-esp32c6 (push) Blocked by required conditions
CI / build-nrf52840 (push) Blocked by required conditions
CI / build-rp2040 (push) Blocked by required conditions
CI / build-rp2350 (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-deb-amd64 (push) Waiting to run
CI / docker-deb-amd64-tft (push) Waiting to run
CI / docker-alp-amd64 (push) Waiting to run
CI / docker-alp-amd64-tft (push) Waiting to run
CI / docker-deb-arm64 (push) Waiting to run
CI / docker-deb-armv7 (push) Waiting to run
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 (rp2350) (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 (rp2350) (push) Blocked by required conditions
CI / release-firmware (stm32) (push) Blocked by required conditions
CI / publish-firmware (push) Blocked by required conditions
Some checks are pending
CI / setup (check) (push) Waiting to run
CI / setup (esp32) (push) Waiting to run
CI / setup (esp32c3) (push) Waiting to run
CI / setup (esp32c6) (push) Waiting to run
CI / setup (esp32s3) (push) Waiting to run
CI / setup (nrf52840) (push) Waiting to run
CI / setup (rp2040) (push) Waiting to run
CI / setup (rp2350) (push) Waiting to run
CI / setup (stm32) (push) Waiting to run
CI / version (push) Waiting to run
CI / check (push) Blocked by required conditions
CI / build-esp32 (push) Blocked by required conditions
CI / build-esp32s3 (push) Blocked by required conditions
CI / build-esp32c3 (push) Blocked by required conditions
CI / build-esp32c6 (push) Blocked by required conditions
CI / build-nrf52840 (push) Blocked by required conditions
CI / build-rp2040 (push) Blocked by required conditions
CI / build-rp2350 (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-deb-amd64 (push) Waiting to run
CI / docker-deb-amd64-tft (push) Waiting to run
CI / docker-alp-amd64 (push) Waiting to run
CI / docker-alp-amd64-tft (push) Waiting to run
CI / docker-deb-arm64 (push) Waiting to run
CI / docker-deb-armv7 (push) Waiting to run
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 (rp2350) (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 (rp2350) (push) Blocked by required conditions
CI / release-firmware (stm32) (push) Blocked by required conditions
CI / publish-firmware (push) Blocked by required conditions
Backmerge from Master into develop
This commit is contained in:
commit
227d0fa7dc
2
.github/actions/setup-base/action.yml
vendored
2
.github/actions/setup-base/action.yml
vendored
@ -23,7 +23,7 @@ runs:
|
|||||||
sudo apt-get install -y cppcheck libbluetooth-dev libgpiod-dev libyaml-cpp-dev lsb-release
|
sudo apt-get install -y cppcheck libbluetooth-dev libgpiod-dev libyaml-cpp-dev lsb-release
|
||||||
|
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v6
|
||||||
with:
|
with:
|
||||||
python-version: 3.x
|
python-version: 3.x
|
||||||
cache: pip
|
cache: pip
|
||||||
|
|||||||
8
.github/workflows/main_matrix.yml
vendored
8
.github/workflows/main_matrix.yml
vendored
@ -43,7 +43,7 @@ jobs:
|
|||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v5
|
||||||
- uses: actions/setup-python@v5
|
- uses: actions/setup-python@v6
|
||||||
with:
|
with:
|
||||||
python-version: 3.x
|
python-version: 3.x
|
||||||
cache: pip
|
cache: pip
|
||||||
@ -374,7 +374,7 @@ jobs:
|
|||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v6
|
||||||
with:
|
with:
|
||||||
python-version: 3.x
|
python-version: 3.x
|
||||||
|
|
||||||
@ -443,7 +443,7 @@ jobs:
|
|||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v6
|
||||||
with:
|
with:
|
||||||
python-version: 3.x
|
python-version: 3.x
|
||||||
|
|
||||||
@ -498,7 +498,7 @@ jobs:
|
|||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v6
|
||||||
with:
|
with:
|
||||||
python-version: 3.x
|
python-version: 3.x
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/package_pio_deps.yml
vendored
2
.github/workflows/package_pio_deps.yml
vendored
@ -31,7 +31,7 @@ jobs:
|
|||||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||||
|
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v6
|
||||||
with:
|
with:
|
||||||
python-version: 3.x
|
python-version: 3.x
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/pr_enforce_labels.yml
vendored
2
.github/workflows/pr_enforce_labels.yml
vendored
@ -13,7 +13,7 @@ jobs:
|
|||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
steps:
|
steps:
|
||||||
- name: Check for PR labels
|
- name: Check for PR labels
|
||||||
uses: actions/github-script@v7
|
uses: actions/github-script@v8
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
const labels = context.payload.pull_request.labels.map(label => label.name);
|
const labels = context.payload.pull_request.labels.map(label => label.name);
|
||||||
|
|||||||
2
.github/workflows/pr_tests.yml
vendored
2
.github/workflows/pr_tests.yml
vendored
@ -177,7 +177,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Comment test results on PR
|
- name: Comment test results on PR
|
||||||
if: github.event_name == 'pull_request' && needs.native-tests.result != 'skipped'
|
if: github.event_name == 'pull_request' && needs.native-tests.result != 'skipped'
|
||||||
uses: actions/github-script@v7
|
uses: actions/github-script@v8
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
|||||||
2
.github/workflows/release_channels.yml
vendored
2
.github/workflows/release_channels.yml
vendored
@ -63,7 +63,7 @@ jobs:
|
|||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v6
|
||||||
with:
|
with:
|
||||||
python-version: 3.x
|
python-version: 3.x
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/stale_bot.yml
vendored
2
.github/workflows/stale_bot.yml
vendored
@ -17,7 +17,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Stale PR+Issues
|
- name: Stale PR+Issues
|
||||||
uses: actions/stale@v9.1.0
|
uses: actions/stale@v10.0.0
|
||||||
with:
|
with:
|
||||||
days-before-stale: 45
|
days-before-stale: 45
|
||||||
exempt-issue-labels: pinned,3.0
|
exempt-issue-labels: pinned,3.0
|
||||||
|
|||||||
2
.github/workflows/tests.yml
vendored
2
.github/workflows/tests.yml
vendored
@ -47,7 +47,7 @@ jobs:
|
|||||||
pio upgrade
|
pio upgrade
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v5
|
||||||
with:
|
with:
|
||||||
node-version: 22
|
node-version: 22
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/trunk_format_pr.yml
vendored
2
.github/workflows/trunk_format_pr.yml
vendored
@ -39,7 +39,7 @@ jobs:
|
|||||||
git push
|
git push
|
||||||
|
|
||||||
- name: Comment on PR
|
- name: Comment on PR
|
||||||
uses: actions/github-script@v7
|
uses: actions/github-script@v8
|
||||||
with:
|
with:
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
script: |
|
script: |
|
||||||
|
|||||||
@ -9,12 +9,12 @@ plugins:
|
|||||||
lint:
|
lint:
|
||||||
enabled:
|
enabled:
|
||||||
- checkov@3.2.469
|
- checkov@3.2.469
|
||||||
- renovate@41.93.2
|
- renovate@41.94.0
|
||||||
- prettier@3.6.2
|
- prettier@3.6.2
|
||||||
- trufflehog@3.90.5
|
- trufflehog@3.90.5
|
||||||
- yamllint@1.37.1
|
- yamllint@1.37.1
|
||||||
- bandit@1.8.6
|
- bandit@1.8.6
|
||||||
- trivy@0.65.0
|
- trivy@0.66.0
|
||||||
- taplo@0.10.0
|
- taplo@0.10.0
|
||||||
- ruff@0.12.11
|
- ruff@0.12.11
|
||||||
- isort@6.0.1
|
- isort@6.0.1
|
||||||
@ -23,7 +23,7 @@ lint:
|
|||||||
- svgo@4.0.0
|
- svgo@4.0.0
|
||||||
- actionlint@1.7.7
|
- actionlint@1.7.7
|
||||||
- flake8@7.3.0
|
- flake8@7.3.0
|
||||||
- hadolint@2.12.1-beta
|
- hadolint@2.13.1
|
||||||
- shfmt@3.6.0
|
- shfmt@3.6.0
|
||||||
- shellcheck@0.11.0
|
- shellcheck@0.11.0
|
||||||
- black@25.1.0
|
- black@25.1.0
|
||||||
|
|||||||
@ -119,11 +119,10 @@ IF NOT "__%PYTHON%__"=="____" (
|
|||||||
|
|
||||||
CALL :LOG_MESSAGE DEBUG "Checking esptool command !ESPTOOL_CMD!..."
|
CALL :LOG_MESSAGE DEBUG "Checking esptool command !ESPTOOL_CMD!..."
|
||||||
!ESPTOOL_CMD! >nul 2>&1
|
!ESPTOOL_CMD! >nul 2>&1
|
||||||
IF %ERRORLEVEL% GEQ 2 (
|
IF %ERRORLEVEL% EQU 9009 (
|
||||||
@REM esptool exits with code 1 if help is displayed.
|
@REM 9009 = command not found on Windows
|
||||||
CALL :LOG_MESSAGE ERROR "esptool not found: !ESPTOOL_CMD!"
|
CALL :LOG_MESSAGE ERROR "esptool not found: !ESPTOOL_CMD!"
|
||||||
EXIT /B 1
|
EXIT /B 1
|
||||||
GOTO eof
|
|
||||||
)
|
)
|
||||||
IF %DEBUG% EQU 1 (
|
IF %DEBUG% EQU 1 (
|
||||||
CALL :LOG_MESSAGE DEBUG "Skipping ESPTOOL_CMD steps."
|
CALL :LOG_MESSAGE DEBUG "Skipping ESPTOOL_CMD steps."
|
||||||
|
|||||||
@ -5,6 +5,10 @@ BPS_RESET=false
|
|||||||
TFT_BUILD=false
|
TFT_BUILD=false
|
||||||
MCU=""
|
MCU=""
|
||||||
|
|
||||||
|
# Constants
|
||||||
|
RESET_BAUD=1200
|
||||||
|
FIRMWARE_OFFSET=0x00
|
||||||
|
|
||||||
# Variant groups
|
# Variant groups
|
||||||
BIGDB_8MB=(
|
BIGDB_8MB=(
|
||||||
"picomputer-s3"
|
"picomputer-s3"
|
||||||
@ -121,7 +125,7 @@ while [ $# -gt 0 ]; do
|
|||||||
done
|
done
|
||||||
|
|
||||||
if [[ $BPS_RESET == true ]]; then
|
if [[ $BPS_RESET == true ]]; then
|
||||||
$ESPTOOL_CMD --baud 1200 --after no_reset read_flash_status
|
$ESPTOOL_CMD --baud $RESET_BAUD --after no_reset read_flash_status
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -202,7 +206,7 @@ if [ -f "${FILENAME}" ] && [ -n "${FILENAME##*"update"*}" ]; then
|
|||||||
|
|
||||||
echo "Trying to flash ${FILENAME}, but first erasing and writing system information"
|
echo "Trying to flash ${FILENAME}, but first erasing and writing system information"
|
||||||
$ESPTOOL_CMD erase-flash
|
$ESPTOOL_CMD erase-flash
|
||||||
$ESPTOOL_CMD write-flash 0x00 "${FILENAME}"
|
$ESPTOOL_CMD write-flash $FIRMWARE_OFFSET "${FILENAME}"
|
||||||
echo "Trying to flash ${OTAFILE} at offset ${OTA_OFFSET}"
|
echo "Trying to flash ${OTAFILE} at offset ${OTA_OFFSET}"
|
||||||
$ESPTOOL_CMD write-flash $OTA_OFFSET "${OTAFILE}"
|
$ESPTOOL_CMD write-flash $OTA_OFFSET "${OTAFILE}"
|
||||||
echo "Trying to flash ${SPIFFSFILE}, at offset ${OFFSET}"
|
echo "Trying to flash ${SPIFFSFILE}, at offset ${OFFSET}"
|
||||||
|
|||||||
@ -6,6 +6,8 @@ SET "SCRIPT_NAME=%~nx0"
|
|||||||
SET "DEBUG=0"
|
SET "DEBUG=0"
|
||||||
SET "PYTHON="
|
SET "PYTHON="
|
||||||
SET "ESPTOOL_BAUD=115200"
|
SET "ESPTOOL_BAUD=115200"
|
||||||
|
SET "RESET_BAUD=1200"
|
||||||
|
SET "UPDATE_OFFSET=0x10000"
|
||||||
SET "ESPTOOL_CMD="
|
SET "ESPTOOL_CMD="
|
||||||
SET "LOGCOUNTER=0"
|
SET "LOGCOUNTER=0"
|
||||||
SET "CHANGE_MODE=0"
|
SET "CHANGE_MODE=0"
|
||||||
@ -85,14 +87,13 @@ IF "!FILENAME:update=!"=="!FILENAME!" (
|
|||||||
)
|
)
|
||||||
|
|
||||||
:skip-filename
|
:skip-filename
|
||||||
SET "ESPTOOL_BAUD=1200"
|
|
||||||
|
|
||||||
CALL :LOG_MESSAGE DEBUG "Determine the correct esptool command to use..."
|
CALL :LOG_MESSAGE DEBUG "Determine the correct esptool command to use..."
|
||||||
IF NOT "__%PYTHON%__"=="____" (
|
IF NOT "__%PYTHON%__"=="____" (
|
||||||
SET "ESPTOOL_CMD=!PYTHON! -m esptool"
|
SET "ESPTOOL_CMD=""!PYTHON!"" -m esptool"
|
||||||
CALL :LOG_MESSAGE DEBUG "Python interpreter supplied."
|
CALL :LOG_MESSAGE DEBUG "Python interpreter supplied."
|
||||||
) ELSE (
|
) ELSE (
|
||||||
CALL :LOG_MESSAGE DEBUG "Python interpreter NOT supplied. Looking for esptool...
|
CALL :LOG_MESSAGE DEBUG "Python interpreter NOT supplied. Looking for esptool..."
|
||||||
WHERE esptool >nul 2>&1
|
WHERE esptool >nul 2>&1
|
||||||
IF %ERRORLEVEL% EQU 0 (
|
IF %ERRORLEVEL% EQU 0 (
|
||||||
@REM WHERE exits with code 0 if esptool is found.
|
@REM WHERE exits with code 0 if esptool is found.
|
||||||
@ -105,11 +106,11 @@ IF NOT "__%PYTHON%__"=="____" (
|
|||||||
|
|
||||||
CALL :LOG_MESSAGE DEBUG "Checking esptool command !ESPTOOL_CMD!..."
|
CALL :LOG_MESSAGE DEBUG "Checking esptool command !ESPTOOL_CMD!..."
|
||||||
!ESPTOOL_CMD! >nul 2>&1
|
!ESPTOOL_CMD! >nul 2>&1
|
||||||
IF %ERRORLEVEL% GEQ 2 (
|
CALL :LOG_MESSAGE DEBUG "esptool exit code: %ERRORLEVEL%"
|
||||||
@REM esptool exits with code 1 if help is displayed.
|
IF %ERRORLEVEL% EQU 9009 (
|
||||||
|
@REM 9009 = command not found on Windows
|
||||||
CALL :LOG_MESSAGE ERROR "esptool not found: !ESPTOOL_CMD!"
|
CALL :LOG_MESSAGE ERROR "esptool not found: !ESPTOOL_CMD!"
|
||||||
EXIT /B 1
|
EXIT /B 1
|
||||||
GOTO eof
|
|
||||||
)
|
)
|
||||||
IF %DEBUG% EQU 1 (
|
IF %DEBUG% EQU 1 (
|
||||||
CALL :LOG_MESSAGE DEBUG "Skipping ESPTOOL_CMD steps."
|
CALL :LOG_MESSAGE DEBUG "Skipping ESPTOOL_CMD steps."
|
||||||
@ -127,13 +128,13 @@ CALL :LOG_MESSAGE INFO "Using esptool baud: !ESPTOOL_BAUD!."
|
|||||||
|
|
||||||
IF %CHANGE_MODE% EQU 1 (
|
IF %CHANGE_MODE% EQU 1 (
|
||||||
@REM Attempt to change mode via 1200bps Reset.
|
@REM Attempt to change mode via 1200bps Reset.
|
||||||
CALL :RUN_ESPTOOL !ESPTOOL_BAUD! --after no_reset read_flash_status
|
CALL :RUN_ESPTOOL !RESET_BAUD! --after no_reset read_flash_status
|
||||||
GOTO eof
|
GOTO eof
|
||||||
)
|
)
|
||||||
|
|
||||||
@REM Flashing operations.
|
@REM Flashing operations.
|
||||||
CALL :LOG_MESSAGE INFO "Trying to flash update "!FILENAME!" at OFFSET 0x10000..."
|
CALL :LOG_MESSAGE INFO "Trying to flash update "!FILENAME!" at OFFSET !UPDATE_OFFSET!..."
|
||||||
CALL :RUN_ESPTOOL !ESPTOOL_BAUD! write-flash 0x10000 "!FILENAME!" || GOTO eof
|
CALL :RUN_ESPTOOL !ESPTOOL_BAUD! write-flash !UPDATE_OFFSET! "!FILENAME!" || GOTO eof
|
||||||
|
|
||||||
CALL :LOG_MESSAGE INFO "Script complete!."
|
CALL :LOG_MESSAGE INFO "Script complete!."
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,11 @@
|
|||||||
PYTHON=${PYTHON:-$(which python3 python|head -n 1)}
|
PYTHON=${PYTHON:-$(which python3 python|head -n 1)}
|
||||||
CHANGE_MODE=false
|
CHANGE_MODE=false
|
||||||
|
|
||||||
|
# Constants
|
||||||
|
FLASH_BAUD=115200
|
||||||
|
RESET_BAUD=1200
|
||||||
|
UPDATE_OFFSET=0x10000
|
||||||
|
|
||||||
# Determine the correct esptool command to use
|
# Determine the correct esptool command to use
|
||||||
if "$PYTHON" -m esptool version >/dev/null 2>&1; then
|
if "$PYTHON" -m esptool version >/dev/null 2>&1; then
|
||||||
ESPTOOL_CMD="$PYTHON -m esptool"
|
ESPTOOL_CMD="$PYTHON -m esptool"
|
||||||
@ -64,7 +69,7 @@ done
|
|||||||
shift "$((OPTIND-1))"
|
shift "$((OPTIND-1))"
|
||||||
|
|
||||||
if [ "$CHANGE_MODE" = true ]; then
|
if [ "$CHANGE_MODE" = true ]; then
|
||||||
$ESPTOOL_CMD --baud 1200 --after no_reset read_flash_status
|
$ESPTOOL_CMD --baud $RESET_BAUD --after no_reset read_flash_status
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -75,7 +80,7 @@ fi
|
|||||||
|
|
||||||
if [ -f "${FILENAME}" ] && [ -z "${FILENAME##*"update"*}" ]; then
|
if [ -f "${FILENAME}" ] && [ -z "${FILENAME##*"update"*}" ]; then
|
||||||
echo "Trying to flash update ${FILENAME}"
|
echo "Trying to flash update ${FILENAME}"
|
||||||
$ESPTOOL_CMD --baud 115200 write-flash 0x10000 "${FILENAME}"
|
$ESPTOOL_CMD --baud $FLASH_BAUD write-flash $UPDATE_OFFSET "${FILENAME}"
|
||||||
else
|
else
|
||||||
show_help
|
show_help
|
||||||
echo "Invalid file: ${FILENAME}"
|
echo "Invalid file: ${FILENAME}"
|
||||||
|
|||||||
@ -833,16 +833,25 @@ void Power::readPowerStatus()
|
|||||||
newStatus.notifyObservers(&powerStatus2);
|
newStatus.notifyObservers(&powerStatus2);
|
||||||
#ifdef DEBUG_HEAP
|
#ifdef DEBUG_HEAP
|
||||||
if (lastheap != memGet.getFreeHeap()) {
|
if (lastheap != memGet.getFreeHeap()) {
|
||||||
std::string threadlist = "Threads running:";
|
// Use stack-allocated buffer to avoid heap allocations in monitoring code
|
||||||
|
char threadlist[256] = "Threads running:";
|
||||||
|
int threadlistLen = strlen(threadlist);
|
||||||
int running = 0;
|
int running = 0;
|
||||||
for (int i = 0; i < MAX_THREADS; i++) {
|
for (int i = 0; i < MAX_THREADS; i++) {
|
||||||
auto thread = concurrency::mainController.get(i);
|
auto thread = concurrency::mainController.get(i);
|
||||||
if ((thread != nullptr) && (thread->enabled)) {
|
if ((thread != nullptr) && (thread->enabled)) {
|
||||||
threadlist += vformat(" %s", thread->ThreadName.c_str());
|
// Use snprintf to safely append to stack buffer without heap allocation
|
||||||
|
int remaining = sizeof(threadlist) - threadlistLen - 1;
|
||||||
|
if (remaining > 0) {
|
||||||
|
int written = snprintf(threadlist + threadlistLen, remaining, " %s", thread->ThreadName.c_str());
|
||||||
|
if (written > 0 && written < remaining) {
|
||||||
|
threadlistLen += written;
|
||||||
|
}
|
||||||
|
}
|
||||||
running++;
|
running++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG_DEBUG(threadlist.c_str());
|
LOG_DEBUG(threadlist);
|
||||||
LOG_DEBUG("Heap status: %d/%d bytes free (%d), running %d/%d threads", memGet.getFreeHeap(), memGet.getHeapSize(),
|
LOG_DEBUG("Heap status: %d/%d bytes free (%d), running %d/%d threads", memGet.getFreeHeap(), memGet.getHeapSize(),
|
||||||
memGet.getFreeHeap() - lastheap, running, concurrency::mainController.size(false));
|
memGet.getFreeHeap() - lastheap, running, concurrency::mainController.size(false));
|
||||||
lastheap = memGet.getFreeHeap();
|
lastheap = memGet.getFreeHeap();
|
||||||
@ -856,15 +865,19 @@ void Power::readPowerStatus()
|
|||||||
sprintf(mac, "!%02x%02x%02x%02x", dmac[2], dmac[3], dmac[4], dmac[5]);
|
sprintf(mac, "!%02x%02x%02x%02x", dmac[2], dmac[3], dmac[4], dmac[5]);
|
||||||
|
|
||||||
auto newHeap = memGet.getFreeHeap();
|
auto newHeap = memGet.getFreeHeap();
|
||||||
std::string heapTopic =
|
// Use stack-allocated buffers to avoid heap allocations in monitoring code
|
||||||
(*moduleConfig.mqtt.root ? moduleConfig.mqtt.root : "msh") + std::string("/2/heap/") + std::string(mac);
|
char heapTopic[128];
|
||||||
std::string heapString = std::to_string(newHeap);
|
snprintf(heapTopic, sizeof(heapTopic), "%s/2/heap/%s", (*moduleConfig.mqtt.root ? moduleConfig.mqtt.root : "msh"), mac);
|
||||||
mqtt->pubSub.publish(heapTopic.c_str(), heapString.c_str(), false);
|
char heapString[16];
|
||||||
|
snprintf(heapString, sizeof(heapString), "%u", newHeap);
|
||||||
|
mqtt->pubSub.publish(heapTopic, heapString, false);
|
||||||
|
|
||||||
auto wifiRSSI = WiFi.RSSI();
|
auto wifiRSSI = WiFi.RSSI();
|
||||||
std::string wifiTopic =
|
char wifiTopic[128];
|
||||||
(*moduleConfig.mqtt.root ? moduleConfig.mqtt.root : "msh") + std::string("/2/wifi/") + std::string(mac);
|
snprintf(wifiTopic, sizeof(wifiTopic), "%s/2/wifi/%s", (*moduleConfig.mqtt.root ? moduleConfig.mqtt.root : "msh"), mac);
|
||||||
std::string wifiString = std::to_string(wifiRSSI);
|
char wifiString[16];
|
||||||
mqtt->pubSub.publish(wifiTopic.c_str(), wifiString.c_str(), false);
|
snprintf(wifiString, sizeof(wifiString), "%d", wifiRSSI);
|
||||||
|
mqtt->pubSub.publish(wifiTopic, wifiString, false);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@ -1128,6 +1128,15 @@ TFTDisplay::TFTDisplay(uint8_t address, int sda, int scl, OLEDDISPLAY_GEOMETRY g
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TFTDisplay::~TFTDisplay()
|
||||||
|
{
|
||||||
|
// Clean up allocated line pixel buffer to prevent memory leak
|
||||||
|
if (linePixelBuffer != nullptr) {
|
||||||
|
free(linePixelBuffer);
|
||||||
|
linePixelBuffer = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Write the buffer to the display memory
|
// Write the buffer to the display memory
|
||||||
void TFTDisplay::display(bool fromBlank)
|
void TFTDisplay::display(bool fromBlank)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -20,6 +20,9 @@ class TFTDisplay : public OLEDDisplay
|
|||||||
*/
|
*/
|
||||||
TFTDisplay(uint8_t, int, int, OLEDDISPLAY_GEOMETRY, HW_I2C);
|
TFTDisplay(uint8_t, int, int, OLEDDISPLAY_GEOMETRY, HW_I2C);
|
||||||
|
|
||||||
|
// Destructor to clean up allocated memory
|
||||||
|
~TFTDisplay();
|
||||||
|
|
||||||
// Write the buffer to the display memory
|
// Write the buffer to the display memory
|
||||||
virtual void display() override { display(false); };
|
virtual void display() override { display(false); };
|
||||||
virtual void display(bool fromBlank);
|
virtual void display(bool fromBlank);
|
||||||
|
|||||||
@ -70,7 +70,7 @@ int32_t RotaryEncoderImpl::runOnce()
|
|||||||
this->notifyObservers(&e);
|
this->notifyObservers(&e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 20;
|
return 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -74,10 +74,11 @@ void NextHopRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtast
|
|||||||
if (p->from != 0) {
|
if (p->from != 0) {
|
||||||
meshtastic_NodeInfoLite *origTx = nodeDB->getMeshNode(p->from);
|
meshtastic_NodeInfoLite *origTx = nodeDB->getMeshNode(p->from);
|
||||||
if (origTx) {
|
if (origTx) {
|
||||||
// Either relayer of ACK was also a relayer of the packet, or we were the relayer and the ACK came directly from
|
// Either relayer of ACK was also a relayer of the packet, or we were the *only* relayer and the ACK came directly
|
||||||
// the destination
|
// from the destination
|
||||||
if (wasRelayer(p->relay_node, p->decoded.request_id, p->to) ||
|
if (wasRelayer(p->relay_node, p->decoded.request_id, p->to) ||
|
||||||
(wasRelayer(ourRelayID, p->decoded.request_id, p->to) && p->hop_start != 0 && p->hop_start == p->hop_limit)) {
|
(p->hop_start != 0 && p->hop_start == p->hop_limit &&
|
||||||
|
wasSoleRelayer(ourRelayID, p->decoded.request_id, p->to))) {
|
||||||
if (origTx->next_hop != p->relay_node) { // Not already set
|
if (origTx->next_hop != p->relay_node) { // Not already set
|
||||||
LOG_INFO("Update next hop of 0x%x to 0x%x based on ACK/reply", p->from, p->relay_node);
|
LOG_INFO("Update next hop of 0x%x to 0x%x based on ACK/reply", p->from, p->relay_node);
|
||||||
origTx->next_hop = p->relay_node;
|
origTx->next_hop = p->relay_node;
|
||||||
|
|||||||
@ -294,7 +294,7 @@ void PacketHistory::insert(const PacketRecord &r)
|
|||||||
|
|
||||||
/* Check if a certain node was a relayer of a packet in the history given an ID and sender
|
/* Check if a certain node was a relayer of a packet in the history given an ID and sender
|
||||||
* @return true if node was indeed a relayer, false if not */
|
* @return true if node was indeed a relayer, false if not */
|
||||||
bool PacketHistory::wasRelayer(const uint8_t relayer, const uint32_t id, const NodeNum sender)
|
bool PacketHistory::wasRelayer(const uint8_t relayer, const uint32_t id, const NodeNum sender, bool *wasSole)
|
||||||
{
|
{
|
||||||
if (!initOk()) {
|
if (!initOk()) {
|
||||||
LOG_ERROR("PacketHistory - wasRelayer: NOT INITIALIZED!");
|
LOG_ERROR("PacketHistory - wasRelayer: NOT INITIALIZED!");
|
||||||
@ -322,27 +322,42 @@ bool PacketHistory::wasRelayer(const uint8_t relayer, const uint32_t id, const N
|
|||||||
found->sender, found->id, found->next_hop, millis() - found->rxTimeMsec, found->relayed_by[0], found->relayed_by[1],
|
found->sender, found->id, found->next_hop, millis() - found->rxTimeMsec, found->relayed_by[0], found->relayed_by[1],
|
||||||
found->relayed_by[2], relayer);
|
found->relayed_by[2], relayer);
|
||||||
#endif
|
#endif
|
||||||
return wasRelayer(relayer, *found);
|
return wasRelayer(relayer, *found, wasSole);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if a certain node was a relayer of a packet in the history given iterator
|
/* Check if a certain node was a relayer of a packet in the history given iterator
|
||||||
* @return true if node was indeed a relayer, false if not */
|
* @return true if node was indeed a relayer, false if not */
|
||||||
bool PacketHistory::wasRelayer(const uint8_t relayer, const PacketRecord &r)
|
bool PacketHistory::wasRelayer(const uint8_t relayer, const PacketRecord &r, bool *wasSole)
|
||||||
{
|
{
|
||||||
for (uint8_t i = 0; i < NUM_RELAYERS; i++) {
|
bool found = false;
|
||||||
|
bool other_present = false;
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < NUM_RELAYERS; ++i) {
|
||||||
if (r.relayed_by[i] == relayer) {
|
if (r.relayed_by[i] == relayer) {
|
||||||
#if VERBOSE_PACKET_HISTORY
|
found = true;
|
||||||
LOG_DEBUG("Packet History - was rel.PR.: s=%08x id=%08x rls=%02x %02x %02x / rl=%02x? YES", r.sender, r.id,
|
} else if (r.relayed_by[i] != 0) {
|
||||||
r.relayed_by[0], r.relayed_by[1], r.relayed_by[2], relayer);
|
other_present = true;
|
||||||
#endif
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wasSole) {
|
||||||
|
*wasSole = (found && !other_present);
|
||||||
|
}
|
||||||
|
|
||||||
#if VERBOSE_PACKET_HISTORY
|
#if VERBOSE_PACKET_HISTORY
|
||||||
LOG_DEBUG("Packet History - was rel.PR.: s=%08x id=%08x rls=%02x %02x %02x / rl=%02x? NO", r.sender, r.id, r.relayed_by[0],
|
LOG_DEBUG("Packet History - was rel.PR.: s=%08x id=%08x rls=%02x %02x %02x / rl=%02x? NO", r.sender, r.id, r.relayed_by[0],
|
||||||
r.relayed_by[1], r.relayed_by[2], relayer);
|
r.relayed_by[1], r.relayed_by[2], relayer);
|
||||||
#endif
|
#endif
|
||||||
return false;
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if a certain node was the *only* relayer of a packet in the history given an ID and sender
|
||||||
|
bool PacketHistory::wasSoleRelayer(const uint8_t relayer, const uint32_t id, const NodeNum sender)
|
||||||
|
{
|
||||||
|
bool wasSole = false;
|
||||||
|
wasRelayer(relayer, id, sender, &wasSole);
|
||||||
|
return wasSole;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove a relayer from the list of relayers of a packet in the history given an ID and sender
|
// Remove a relayer from the list of relayers of a packet in the history given an ID and sender
|
||||||
|
|||||||
@ -34,8 +34,9 @@ class PacketHistory
|
|||||||
void insert(const PacketRecord &r); // Insert or replace a packet record in the history
|
void insert(const PacketRecord &r); // Insert or replace a packet record in the history
|
||||||
|
|
||||||
/* Check if a certain node was a relayer of a packet in the history given iterator
|
/* Check if a certain node was a relayer of a packet in the history given iterator
|
||||||
|
* If wasSole is not nullptr, it will be set to true if the relayer was the only relayer of that packet
|
||||||
* @return true if node was indeed a relayer, false if not */
|
* @return true if node was indeed a relayer, false if not */
|
||||||
bool wasRelayer(const uint8_t relayer, const PacketRecord &r);
|
bool wasRelayer(const uint8_t relayer, const PacketRecord &r, bool *wasSole = nullptr);
|
||||||
|
|
||||||
PacketHistory(const PacketHistory &); // non construction-copyable
|
PacketHistory(const PacketHistory &); // non construction-copyable
|
||||||
PacketHistory &operator=(const PacketHistory &); // non copyable
|
PacketHistory &operator=(const PacketHistory &); // non copyable
|
||||||
@ -54,8 +55,12 @@ class PacketHistory
|
|||||||
bool *weWereNextHop = nullptr);
|
bool *weWereNextHop = nullptr);
|
||||||
|
|
||||||
/* Check if a certain node was a relayer of a packet in the history given an ID and sender
|
/* Check if a certain node was a relayer of a packet in the history given an ID and sender
|
||||||
|
* If wasSole is not nullptr, it will be set to true if the relayer was the only relayer of that packet
|
||||||
* @return true if node was indeed a relayer, false if not */
|
* @return true if node was indeed a relayer, false if not */
|
||||||
bool wasRelayer(const uint8_t relayer, const uint32_t id, const NodeNum sender);
|
bool wasRelayer(const uint8_t relayer, const uint32_t id, const NodeNum sender, bool *wasSole = nullptr);
|
||||||
|
|
||||||
|
// Check if a certain node was the *only* relayer of a packet in the history given an ID and sender
|
||||||
|
bool wasSoleRelayer(const uint8_t relayer, const uint32_t id, const NodeNum sender);
|
||||||
|
|
||||||
// Remove a relayer from the list of relayers of a packet in the history given an ID and sender
|
// Remove a relayer from the list of relayers of a packet in the history given an ID and sender
|
||||||
void removeRelayer(const uint8_t relayer, const uint32_t id, const NodeNum sender);
|
void removeRelayer(const uint8_t relayer, const uint32_t id, const NodeNum sender);
|
||||||
|
|||||||
@ -64,7 +64,12 @@ typedef enum _meshtastic_Config_DeviceConfig_Role {
|
|||||||
in areas not already covered by other routers, or to bridge around problematic terrain,
|
in areas not already covered by other routers, or to bridge around problematic terrain,
|
||||||
but should not be given priority over other routers in order to avoid unnecessaraily
|
but should not be given priority over other routers in order to avoid unnecessaraily
|
||||||
consuming hops. */
|
consuming hops. */
|
||||||
meshtastic_Config_DeviceConfig_Role_ROUTER_LATE = 11
|
meshtastic_Config_DeviceConfig_Role_ROUTER_LATE = 11,
|
||||||
|
/* Description: Treats packets from or to favorited nodes as ROUTER, and all other packets as CLIENT.
|
||||||
|
Technical Details: Used for stronger attic/roof nodes to distribute messages more widely
|
||||||
|
from weaker, indoor, or less-well-positioned nodes. Recommended for users with multiple nodes
|
||||||
|
where one CLIENT_BASE acts as a more powerful base station, such as an attic/roof node. */
|
||||||
|
meshtastic_Config_DeviceConfig_Role_CLIENT_BASE = 12
|
||||||
} meshtastic_Config_DeviceConfig_Role;
|
} meshtastic_Config_DeviceConfig_Role;
|
||||||
|
|
||||||
/* Defines the device's behavior for how messages are rebroadcast */
|
/* Defines the device's behavior for how messages are rebroadcast */
|
||||||
@ -646,8 +651,8 @@ extern "C" {
|
|||||||
|
|
||||||
/* Helper constants for enums */
|
/* Helper constants for enums */
|
||||||
#define _meshtastic_Config_DeviceConfig_Role_MIN meshtastic_Config_DeviceConfig_Role_CLIENT
|
#define _meshtastic_Config_DeviceConfig_Role_MIN meshtastic_Config_DeviceConfig_Role_CLIENT
|
||||||
#define _meshtastic_Config_DeviceConfig_Role_MAX meshtastic_Config_DeviceConfig_Role_ROUTER_LATE
|
#define _meshtastic_Config_DeviceConfig_Role_MAX meshtastic_Config_DeviceConfig_Role_CLIENT_BASE
|
||||||
#define _meshtastic_Config_DeviceConfig_Role_ARRAYSIZE ((meshtastic_Config_DeviceConfig_Role)(meshtastic_Config_DeviceConfig_Role_ROUTER_LATE+1))
|
#define _meshtastic_Config_DeviceConfig_Role_ARRAYSIZE ((meshtastic_Config_DeviceConfig_Role)(meshtastic_Config_DeviceConfig_Role_CLIENT_BASE+1))
|
||||||
|
|
||||||
#define _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN meshtastic_Config_DeviceConfig_RebroadcastMode_ALL
|
#define _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN meshtastic_Config_DeviceConfig_RebroadcastMode_ALL
|
||||||
#define _meshtastic_Config_DeviceConfig_RebroadcastMode_MAX meshtastic_Config_DeviceConfig_RebroadcastMode_CORE_PORTNUMS_ONLY
|
#define _meshtastic_Config_DeviceConfig_RebroadcastMode_MAX meshtastic_Config_DeviceConfig_RebroadcastMode_CORE_PORTNUMS_ONLY
|
||||||
|
|||||||
@ -272,6 +272,8 @@ typedef enum _meshtastic_HardwareModel {
|
|||||||
meshtastic_HardwareModel_HELTEC_MESH_SOLAR = 108,
|
meshtastic_HardwareModel_HELTEC_MESH_SOLAR = 108,
|
||||||
/* Lilygo T-Echo Lite */
|
/* Lilygo T-Echo Lite */
|
||||||
meshtastic_HardwareModel_T_ECHO_LITE = 109,
|
meshtastic_HardwareModel_T_ECHO_LITE = 109,
|
||||||
|
/* New Heltec LoRA32 with ESP32-S3 CPU */
|
||||||
|
meshtastic_HardwareModel_HELTEC_V4 = 110,
|
||||||
/* ------------------------------------------------------------------------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits.
|
Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits.
|
||||||
------------------------------------------------------------------------------------------------------------------------------------------ */
|
------------------------------------------------------------------------------------------------------------------------------------------ */
|
||||||
|
|||||||
@ -342,6 +342,11 @@ void handleFsBrowseStatic(HTTPRequest *req, HTTPResponse *res)
|
|||||||
res->print(value->Stringify().c_str());
|
res->print(value->Stringify().c_str());
|
||||||
|
|
||||||
delete value;
|
delete value;
|
||||||
|
|
||||||
|
// Clean up the fileList to prevent memory leak
|
||||||
|
for (auto *val : fileList) {
|
||||||
|
delete val;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleFsDeleteStatic(HTTPRequest *req, HTTPResponse *res)
|
void handleFsDeleteStatic(HTTPRequest *req, HTTPResponse *res)
|
||||||
@ -610,33 +615,38 @@ void handleReport(HTTPRequest *req, HTTPResponse *res)
|
|||||||
res->println("<pre>");
|
res->println("<pre>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper lambda to create JSON array and clean up memory properly
|
||||||
|
auto createJSONArrayFromLog = [](uint32_t *logArray, int count) -> JSONValue * {
|
||||||
|
JSONArray tempArray;
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
tempArray.push_back(new JSONValue((int)logArray[i]));
|
||||||
|
}
|
||||||
|
JSONValue *result = new JSONValue(tempArray);
|
||||||
|
// Clean up original array to prevent memory leak
|
||||||
|
for (auto *val : tempArray) {
|
||||||
|
delete val;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
// data->airtime->tx_log
|
// data->airtime->tx_log
|
||||||
JSONArray txLogValues;
|
|
||||||
uint32_t *logArray;
|
uint32_t *logArray;
|
||||||
logArray = airTime->airtimeReport(TX_LOG);
|
logArray = airTime->airtimeReport(TX_LOG);
|
||||||
for (int i = 0; i < airTime->getPeriodsToLog(); i++) {
|
JSONValue *txLogJsonValue = createJSONArrayFromLog(logArray, airTime->getPeriodsToLog());
|
||||||
txLogValues.push_back(new JSONValue((int)logArray[i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
// data->airtime->rx_log
|
// data->airtime->rx_log
|
||||||
JSONArray rxLogValues;
|
|
||||||
logArray = airTime->airtimeReport(RX_LOG);
|
logArray = airTime->airtimeReport(RX_LOG);
|
||||||
for (int i = 0; i < airTime->getPeriodsToLog(); i++) {
|
JSONValue *rxLogJsonValue = createJSONArrayFromLog(logArray, airTime->getPeriodsToLog());
|
||||||
rxLogValues.push_back(new JSONValue((int)logArray[i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
// data->airtime->rx_all_log
|
// data->airtime->rx_all_log
|
||||||
JSONArray rxAllLogValues;
|
|
||||||
logArray = airTime->airtimeReport(RX_ALL_LOG);
|
logArray = airTime->airtimeReport(RX_ALL_LOG);
|
||||||
for (int i = 0; i < airTime->getPeriodsToLog(); i++) {
|
JSONValue *rxAllLogJsonValue = createJSONArrayFromLog(logArray, airTime->getPeriodsToLog());
|
||||||
rxAllLogValues.push_back(new JSONValue((int)logArray[i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
// data->airtime
|
// data->airtime
|
||||||
JSONObject jsonObjAirtime;
|
JSONObject jsonObjAirtime;
|
||||||
jsonObjAirtime["tx_log"] = new JSONValue(txLogValues);
|
jsonObjAirtime["tx_log"] = txLogJsonValue;
|
||||||
jsonObjAirtime["rx_log"] = new JSONValue(rxLogValues);
|
jsonObjAirtime["rx_log"] = rxLogJsonValue;
|
||||||
jsonObjAirtime["rx_all_log"] = new JSONValue(rxAllLogValues);
|
jsonObjAirtime["rx_all_log"] = rxAllLogJsonValue;
|
||||||
jsonObjAirtime["channel_utilization"] = new JSONValue(airTime->channelUtilizationPercent());
|
jsonObjAirtime["channel_utilization"] = new JSONValue(airTime->channelUtilizationPercent());
|
||||||
jsonObjAirtime["utilization_tx"] = new JSONValue(airTime->utilizationTXPercent());
|
jsonObjAirtime["utilization_tx"] = new JSONValue(airTime->utilizationTXPercent());
|
||||||
jsonObjAirtime["seconds_since_boot"] = new JSONValue(int(airTime->getSecondsSinceBoot()));
|
jsonObjAirtime["seconds_since_boot"] = new JSONValue(int(airTime->getSecondsSinceBoot()));
|
||||||
@ -765,6 +775,11 @@ void handleNodes(HTTPRequest *req, HTTPResponse *res)
|
|||||||
JSONValue *value = new JSONValue(jsonObjOuter);
|
JSONValue *value = new JSONValue(jsonObjOuter);
|
||||||
res->print(value->Stringify().c_str());
|
res->print(value->Stringify().c_str());
|
||||||
delete value;
|
delete value;
|
||||||
|
|
||||||
|
// Clean up the nodesArray to prevent memory leak
|
||||||
|
for (auto *val : nodesArray) {
|
||||||
|
delete val;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -955,5 +970,10 @@ void handleScanNetworks(HTTPRequest *req, HTTPResponse *res)
|
|||||||
JSONValue *value = new JSONValue(jsonObjOuter);
|
JSONValue *value = new JSONValue(jsonObjOuter);
|
||||||
res->print(value->Stringify().c_str());
|
res->print(value->Stringify().c_str());
|
||||||
delete value;
|
delete value;
|
||||||
|
|
||||||
|
// Clean up the networkObjs to prevent memory leak
|
||||||
|
for (auto *val : networkObjs) {
|
||||||
|
delete val;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -431,15 +431,6 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r
|
|||||||
gpio_wakeup_enable((gpio_num_t)PMU_IRQ, GPIO_INTR_LOW_LEVEL); // pmu irq
|
gpio_wakeup_enable((gpio_num_t)PMU_IRQ, GPIO_INTR_LOW_LEVEL); // pmu irq
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef T_LORA_PAGER
|
|
||||||
LOG_DEBUG("power down XL9555 io");
|
|
||||||
io.digitalWrite(EXPANDS_DRV_EN, LOW);
|
|
||||||
io.digitalWrite(EXPANDS_AMP_EN, LOW);
|
|
||||||
io.digitalWrite(EXPANDS_KB_EN, LOW);
|
|
||||||
io.digitalWrite(EXPANDS_SD_EN, LOW);
|
|
||||||
io.digitalWrite(EXPANDS_GPIO_EN, LOW);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
auto res = esp_sleep_enable_gpio_wakeup();
|
auto res = esp_sleep_enable_gpio_wakeup();
|
||||||
if (res != ESP_OK) {
|
if (res != ESP_OK) {
|
||||||
LOG_ERROR("esp_sleep_enable_gpio_wakeup result %d", res);
|
LOG_ERROR("esp_sleep_enable_gpio_wakeup result %d", res);
|
||||||
@ -480,14 +471,6 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r
|
|||||||
gpio_wakeup_disable((gpio_num_t)RF95_IRQ);
|
gpio_wakeup_disable((gpio_num_t)RF95_IRQ);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef T_LORA_PAGER
|
|
||||||
LOG_DEBUG("power up XL9555 io");
|
|
||||||
io.digitalWrite(EXPANDS_DRV_EN, HIGH);
|
|
||||||
io.digitalWrite(EXPANDS_AMP_EN, HIGH);
|
|
||||||
io.digitalWrite(EXPANDS_KB_EN, HIGH);
|
|
||||||
io.digitalWrite(EXPANDS_SD_EN, HIGH);
|
|
||||||
io.digitalWrite(EXPANDS_GPIO_EN, HIGH);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
|
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
|
||||||
notifyLightSleepEnd.notifyObservers(cause); // Button interrupts are reattached here
|
notifyLightSleepEnd.notifyObservers(cause); // Button interrupts are reattached here
|
||||||
|
|||||||
12
variants/esp32/diy/9m2ibr_aprs_lora_tracker/platformio.ini
Normal file
12
variants/esp32/diy/9m2ibr_aprs_lora_tracker/platformio.ini
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
; 9M2IBR APRS LoRa Tracker: ESP32-WROOM-32 + EBYTE E22-400M30S
|
||||||
|
; https://shopee.com.my/product/1095224/21692283917
|
||||||
|
[env:9m2ibr_aprs_lora_tracker]
|
||||||
|
extends = esp32_base
|
||||||
|
board = esp32doit-devkit-v1
|
||||||
|
board_level = extra
|
||||||
|
build_flags =
|
||||||
|
${esp32_base.build_flags}
|
||||||
|
-D PRIVATE_HW
|
||||||
|
-D EBYTE_E22
|
||||||
|
-D EBYTE_E22_900M30S ; Assume Tx power curve is identical to 900M30S as there is no documentation
|
||||||
|
-I variants/esp32/diy/9m2ibr_aprs_lora_tracker
|
||||||
74
variants/esp32/diy/9m2ibr_aprs_lora_tracker/variant.h
Normal file
74
variants/esp32/diy/9m2ibr_aprs_lora_tracker/variant.h
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
9M2IBR APRS LoRa Tracker: ESP32-WROOM-32 + EBYTE E22-400M30S
|
||||||
|
https://shopee.com.my/product/1095224/21692283917
|
||||||
|
|
||||||
|
Originally developed for LoRa_APRS_iGate and GPIO is similar to
|
||||||
|
https://github.com/richonguzman/LoRa_APRS_iGate/blob/main/variants/ESP32_DIY_1W_LoRa_Mesh_V1_2/board_pinout.h
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// OLED (may be different controllers depending on screen size)
|
||||||
|
#define I2C_SDA 21
|
||||||
|
#define I2C_SCL 22
|
||||||
|
#define HAS_SCREEN 1 // Generates randomized BLE pin
|
||||||
|
|
||||||
|
// GNSS: Ai-Thinker GP-02 BDS/GNSS module
|
||||||
|
#define GPS_RX_PIN 16
|
||||||
|
#define GPS_TX_PIN 17
|
||||||
|
|
||||||
|
// Button
|
||||||
|
#define BUTTON_PIN 15 // Right side button - if not available, set device.button_gpio to 0 from Meshtastic client
|
||||||
|
|
||||||
|
// LEDs
|
||||||
|
#define LED_PIN 13 // Tx LED
|
||||||
|
#define USER_LED 2 // Rx LED
|
||||||
|
|
||||||
|
// Buzzer
|
||||||
|
#define PIN_BUZZER 33
|
||||||
|
|
||||||
|
// Battery sense
|
||||||
|
#define BATTERY_PIN 35
|
||||||
|
#define ADC_MULTIPLIER 2.01 // 100k + 100k, and add 1% tolerance
|
||||||
|
#define ADC_CHANNEL ADC1_GPIO35_CHANNEL
|
||||||
|
#define BATTERY_SENSE_RESOLUTION_BITS ADC_RESOLUTION
|
||||||
|
|
||||||
|
// SPI
|
||||||
|
#define LORA_SCK 18
|
||||||
|
#define LORA_MISO 19
|
||||||
|
#define LORA_MOSI 23
|
||||||
|
|
||||||
|
// LoRa
|
||||||
|
#define LORA_CS 5
|
||||||
|
#define LORA_DIO0 26 // a No connect on the SX1262/SX1268 module
|
||||||
|
#define LORA_RESET 27 // RST for SX1276, and for SX1262/SX1268
|
||||||
|
#define LORA_DIO1 12 // IRQ for SX1262/SX1268
|
||||||
|
#define LORA_DIO2 RADIOLIB_NC // BUSY for SX1262/SX1268
|
||||||
|
#define LORA_DIO3 // NC, but used as TCXO supply by E22 module
|
||||||
|
#define LORA_RXEN 32 // RF switch RX (and E22 LNA) control by ESP32 GPIO
|
||||||
|
#define LORA_TXEN 25 // RF switch TX (and E22 PA) control by ESP32 GPIO
|
||||||
|
|
||||||
|
// 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_CS 5
|
||||||
|
#define SX126X_DIO1 LORA_DIO1
|
||||||
|
#define SX126X_BUSY LORA_DIO2
|
||||||
|
#define SX126X_RESET LORA_RESET
|
||||||
|
#define SX126X_RXEN LORA_RXEN
|
||||||
|
#define SX126X_TXEN LORA_TXEN
|
||||||
|
|
||||||
|
// Support alternative modules if soldered in place of E22
|
||||||
|
#define USE_RF95 // RFM95/SX127x
|
||||||
|
#define USE_SX1262
|
||||||
|
#define USE_SX1268
|
||||||
|
#define USE_LLCC68
|
||||||
|
|
||||||
|
// E22 TCXO support
|
||||||
|
#ifdef EBYTE_E22
|
||||||
|
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
|
||||||
|
#define TCXO_OPTIONAL // make it so that the firmware can try both TCXO and XTAL
|
||||||
|
#endif
|
||||||
@ -1,6 +1,7 @@
|
|||||||
[env:heltec-wireless-bridge]
|
[env:heltec-wireless-bridge]
|
||||||
;build_type = debug ; to make it possible to step through our jtag debugger
|
;build_type = debug ; to make it possible to step through our jtag debugger
|
||||||
extends = esp32_base
|
extends = esp32_base
|
||||||
|
board_level = extra
|
||||||
board = heltec_wifi_lora_32
|
board = heltec_wifi_lora_32
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags}
|
${esp32_base.build_flags}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
[env:trackerd]
|
[env:trackerd]
|
||||||
extends = esp32_base
|
extends = esp32_base
|
||||||
|
board_level = extra
|
||||||
board = pico32
|
board = pico32
|
||||||
board_build.f_flash = 80000000L
|
board_build.f_flash = 80000000L
|
||||||
|
|
||||||
|
|||||||
@ -26,7 +26,7 @@ lib_deps = ${esp32s3_base.lib_deps}
|
|||||||
lewisxhe/SensorLib@0.3.1
|
lewisxhe/SensorLib@0.3.1
|
||||||
https://github.com/pschatzmann/arduino-audio-driver/archive/refs/tags/v0.1.3.zip
|
https://github.com/pschatzmann/arduino-audio-driver/archive/refs/tags/v0.1.3.zip
|
||||||
https://github.com/mverch67/BQ27220/archive/07d92be846abd8a0258a50c23198dac0858b22ed.zip
|
https://github.com/mverch67/BQ27220/archive/07d92be846abd8a0258a50c23198dac0858b22ed.zip
|
||||||
https://github.com/mverch67/RotaryEncoder
|
https://github.com/mverch67/RotaryEncoder/archive/25a59d5745a6645536f921427d80b08e78f886d4.zip
|
||||||
|
|
||||||
[env:tlora-pager-tft]
|
[env:tlora-pager-tft]
|
||||||
board_level = extra
|
board_level = extra
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
; The very slick RAK wireless RAK 4631 / 4630 board - Unified firmware for 5005/19003, with or without OLED RAK 1921
|
; The very slick RAK wireless RAK 4631 / 4630 board - Unified firmware for 5005/19003, with or without OLED RAK 1921
|
||||||
[env:gat562_mesh_trial_tracker]
|
[env:gat562_mesh_trial_tracker]
|
||||||
extends = nrf52840_base
|
extends = nrf52840_base
|
||||||
|
board_level = extra
|
||||||
board = gat562_mesh_trial_tracker
|
board = gat562_mesh_trial_tracker
|
||||||
board_check = true
|
board_check = true
|
||||||
build_flags = ${nrf52840_base.build_flags}
|
build_flags = ${nrf52840_base.build_flags}
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
[env:meshlink]
|
[env:meshlink]
|
||||||
extends = nrf52840_base
|
extends = nrf52840_base
|
||||||
board = meshlink
|
board = meshlink
|
||||||
|
board_level = extra
|
||||||
;board_check = true
|
;board_check = true
|
||||||
build_flags = ${nrf52840_base.build_flags}
|
build_flags = ${nrf52840_base.build_flags}
|
||||||
-I variants/nrf52840/meshlink
|
-I variants/nrf52840/meshlink
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
[env:meshlink_eink]
|
[env:meshlink_eink]
|
||||||
extends = nrf52840_base
|
extends = nrf52840_base
|
||||||
board = meshlink
|
board = meshlink
|
||||||
|
board_level = extra
|
||||||
;board_check = true
|
;board_check = true
|
||||||
build_flags = ${nrf52840_base.build_flags}
|
build_flags = ${nrf52840_base.build_flags}
|
||||||
-I variants/nrf52840/meshlink_eink
|
-I variants/nrf52840/meshlink_eink
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
[env:catsniffer]
|
[env:catsniffer]
|
||||||
extends = rp2040_base
|
extends = rp2040_base
|
||||||
board = rpipico
|
board = rpipico
|
||||||
|
board_level = extra
|
||||||
upload_protocol = picotool
|
upload_protocol = picotool
|
||||||
build_flags =
|
build_flags =
|
||||||
${rp2040_base.build_flags}
|
${rp2040_base.build_flags}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user