diff --git a/.github/workflows/build_one_arch.yml b/.github/workflows/build_one_arch.yml index 6d9134941..9c57f8b7d 100644 --- a/.github/workflows/build_one_arch.yml +++ b/.github/workflows/build_one_arch.yml @@ -88,62 +88,6 @@ jobs: if: ${{ !contains(github.ref_name, 'event/') && github.event_name != 'workflow_dispatch' || !contains(github.ref_name, 'event/') && inputs.arch == 'native' }} uses: ./.github/workflows/test_native.yml - docker-deb-amd64: - if: ${{ github.event_name != 'workflow_dispatch' || inputs.arch == 'native' }} - uses: ./.github/workflows/docker_build.yml - with: - distro: debian - platform: linux/amd64 - runs-on: ubuntu-24.04 - push: false - - docker-deb-amd64-tft: - if: ${{ github.event_name != 'workflow_dispatch' || inputs.arch == 'native' }} - uses: ./.github/workflows/docker_build.yml - with: - distro: debian - platform: linux/amd64 - runs-on: ubuntu-24.04 - push: false - pio_env: native-tft - - docker-alp-amd64: - if: ${{ github.event_name != 'workflow_dispatch' || inputs.arch == 'native' }} - uses: ./.github/workflows/docker_build.yml - with: - distro: alpine - platform: linux/amd64 - runs-on: ubuntu-24.04 - push: false - - docker-alp-amd64-tft: - if: ${{ github.event_name != 'workflow_dispatch' || inputs.arch == 'native' }} - uses: ./.github/workflows/docker_build.yml - with: - distro: alpine - platform: linux/amd64 - runs-on: ubuntu-24.04 - push: false - pio_env: native-tft - - docker-deb-arm64: - if: ${{ github.event_name != 'workflow_dispatch' || inputs.arch == 'native' }} - uses: ./.github/workflows/docker_build.yml - with: - distro: debian - platform: linux/arm64 - runs-on: ubuntu-24.04-arm - push: false - - docker-deb-armv7: - if: ${{ github.event_name != 'workflow_dispatch' || inputs.arch == 'native' }} - uses: ./.github/workflows/docker_build.yml - with: - distro: debian - platform: linux/arm/v7 - runs-on: ubuntu-24.04-arm - push: false - gather-artifacts: permissions: contents: write diff --git a/.github/workflows/build_one_target.yml b/.github/workflows/build_one_target.yml index ba1d5080f..15b3fdba9 100644 --- a/.github/workflows/build_one_target.yml +++ b/.github/workflows/build_one_target.yml @@ -106,62 +106,6 @@ jobs: if: ${{ !contains(github.ref_name, 'event/') && github.event_name != 'workflow_dispatch' || !contains(github.ref_name, 'event/') && inputs.arch == 'native' && inputs.target != '' }} uses: ./.github/workflows/test_native.yml - docker-deb-amd64: - if: ${{ inputs.target != '' && inputs.arch == 'native' }} - uses: ./.github/workflows/docker_build.yml - with: - distro: debian - platform: linux/amd64 - runs-on: ubuntu-24.04 - push: false - - docker-deb-amd64-tft: - if: ${{ inputs.target != '' && inputs.arch == 'native' }} - uses: ./.github/workflows/docker_build.yml - with: - distro: debian - platform: linux/amd64 - runs-on: ubuntu-24.04 - push: false - pio_env: native-tft - - docker-alp-amd64: - if: ${{ inputs.target != '' && inputs.arch == 'native' }} - uses: ./.github/workflows/docker_build.yml - with: - distro: alpine - platform: linux/amd64 - runs-on: ubuntu-24.04 - push: false - - docker-alp-amd64-tft: - if: ${{ inputs.target != '' && inputs.arch == 'native' }} - uses: ./.github/workflows/docker_build.yml - with: - distro: alpine - platform: linux/amd64 - runs-on: ubuntu-24.04 - push: false - pio_env: native-tft - - docker-deb-arm64: - if: ${{ inputs.target != '' && inputs.arch == 'native' }} - uses: ./.github/workflows/docker_build.yml - with: - distro: debian - platform: linux/arm64 - runs-on: ubuntu-24.04-arm - push: false - - docker-deb-armv7: - if: ${{ inputs.target != '' && inputs.arch == 'native' }} - uses: ./.github/workflows/docker_build.yml - with: - distro: debian - platform: linux/arm/v7 - runs-on: ubuntu-24.04-arm - push: false - gather-artifacts: permissions: contents: write diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index 812990eca..02a4c23b8 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -27,7 +27,6 @@ on: jobs: setup: - if: github.repository == 'meshtastic/firmware' strategy: fail-fast: true matrix: @@ -42,10 +41,6 @@ jobs: python-version: 3.x cache: pip - run: pip install -U platformio - - name: Uncomment build epoch - shell: bash - run: | - sed -i 's/#-DBUILD_EPOCH=$UNIX_TIME/-DBUILD_EPOCH=$UNIX_TIME/' platformio.ini - name: Generate matrix id: jsonStep run: | @@ -62,7 +57,6 @@ jobs: check: ${{ steps.jsonStep.outputs.check }} version: - if: github.repository == 'meshtastic/firmware' runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 @@ -125,60 +119,26 @@ jobs: if: ${{ !contains(github.ref_name, 'event/') && github.repository == 'meshtastic/firmware' }} uses: ./.github/workflows/test_native.yml - docker-deb-amd64: - if: github.repository == 'meshtastic/firmware' + docker: + strategy: + fail-fast: false + matrix: + distro: [debian, alpine] + platform: [linux/amd64, linux/arm64, linux/arm/v7] + pio_env: [native, native-tft] + exclude: + - distro: alpine + platform: linux/arm/v7 + - pio_env: native-tft + platform: linux/arm64 + - pio_env: native-tft + platform: linux/arm/v7 uses: ./.github/workflows/docker_build.yml with: - distro: debian - platform: linux/amd64 - runs-on: ubuntu-24.04 - push: false - - docker-deb-amd64-tft: - if: github.repository == 'meshtastic/firmware' - uses: ./.github/workflows/docker_build.yml - with: - distro: debian - platform: linux/amd64 - runs-on: ubuntu-24.04 - push: false - pio_env: native-tft - - docker-alp-amd64: - if: github.repository == 'meshtastic/firmware' - uses: ./.github/workflows/docker_build.yml - with: - distro: alpine - platform: linux/amd64 - runs-on: ubuntu-24.04 - push: false - - docker-alp-amd64-tft: - if: github.repository == 'meshtastic/firmware' - uses: ./.github/workflows/docker_build.yml - with: - distro: alpine - platform: linux/amd64 - runs-on: ubuntu-24.04 - push: false - pio_env: native-tft - - docker-deb-arm64: - if: github.repository == 'meshtastic/firmware' - uses: ./.github/workflows/docker_build.yml - with: - distro: debian - platform: linux/arm64 - runs-on: ubuntu-24.04-arm - push: false - - docker-deb-armv7: - if: github.repository == 'meshtastic/firmware' - uses: ./.github/workflows/docker_build.yml - with: - distro: debian - platform: linux/arm/v7 - runs-on: ubuntu-24.04-arm + distro: ${{ matrix.distro }} + platform: ${{ matrix.platform }} + runs-on: ${{ contains(matrix.platform, 'arm') && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }} + pio_env: ${{ matrix.pio_env }} push: false gather-artifacts: diff --git a/.github/workflows/merge_queue.yml b/.github/workflows/merge_queue.yml index 79e8b0803..e8c3d3450 100644 --- a/.github/workflows/merge_queue.yml +++ b/.github/workflows/merge_queue.yml @@ -99,54 +99,26 @@ jobs: if: ${{ !contains(github.ref_name, 'event/') }} uses: ./.github/workflows/test_native.yml - docker-deb-amd64: + docker: + strategy: + fail-fast: false + matrix: + distro: [debian, alpine] + platform: [linux/amd64, linux/arm64, linux/arm/v7] + pio_env: [native, native-tft] + exclude: + - distro: alpine + platform: linux/arm/v7 + - pio_env: native-tft + platform: linux/arm64 + - pio_env: native-tft + platform: linux/arm/v7 uses: ./.github/workflows/docker_build.yml with: - distro: debian - platform: linux/amd64 - runs-on: ubuntu-24.04 - push: false - - docker-deb-amd64-tft: - uses: ./.github/workflows/docker_build.yml - with: - distro: debian - platform: linux/amd64 - runs-on: ubuntu-24.04 - push: false - pio_env: native-tft - - docker-alp-amd64: - uses: ./.github/workflows/docker_build.yml - with: - distro: alpine - platform: linux/amd64 - runs-on: ubuntu-24.04 - push: false - - docker-alp-amd64-tft: - uses: ./.github/workflows/docker_build.yml - with: - distro: alpine - platform: linux/amd64 - runs-on: ubuntu-24.04 - push: false - pio_env: native-tft - - docker-deb-arm64: - uses: ./.github/workflows/docker_build.yml - with: - distro: debian - platform: linux/arm64 - runs-on: ubuntu-24.04-arm - push: false - - docker-deb-armv7: - uses: ./.github/workflows/docker_build.yml - with: - distro: debian - platform: linux/arm/v7 - runs-on: ubuntu-24.04-arm + distro: ${{ matrix.distro }} + platform: ${{ matrix.platform }} + runs-on: ${{ contains(matrix.platform, 'arm') && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }} + pio_env: ${{ matrix.pio_env }} push: false gather-artifacts: diff --git a/.github/workflows/sec_sast_semgrep_cron.yml b/.github/workflows/sec_sast_semgrep_cron.yml index 96c993cba..2059fde2c 100644 --- a/.github/workflows/sec_sast_semgrep_cron.yml +++ b/.github/workflows/sec_sast_semgrep_cron.yml @@ -41,7 +41,7 @@ jobs: # step 4 - name: publish code scanning alerts - uses: github/codeql-action/upload-sarif@v3 + uses: github/codeql-action/upload-sarif@v4 with: sarif_file: report.sarif category: semgrep diff --git a/Dockerfile b/Dockerfile index b1e151ac7..111dd69fc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ # trunk-ignore-all(hadolint/DL3008): Do not pin apt package versions # trunk-ignore-all(hadolint/DL3013): Do not pin pip package versions -FROM python:3.13-slim-trixie AS builder +FROM python:3.14-slim-trixie AS builder ARG PIO_ENV=native ENV DEBIAN_FRONTEND=noninteractive ENV TZ=Etc/UTC diff --git a/alpine.Dockerfile b/alpine.Dockerfile index 670736241..0469874e4 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.22 AS builder +FROM python:3.14-alpine3.22 AS builder ARG PIO_ENV=native ENV PIP_ROOT_USER_ACTION=ignore diff --git a/arch/esp32/esp32.ini b/arch/esp32/esp32.ini index d2c933461..810c9780e 100644 --- a/arch/esp32/esp32.ini +++ b/arch/esp32/esp32.ini @@ -31,6 +31,7 @@ build_flags = -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL -DAXP_DEBUG_PORT=Serial -DCONFIG_BT_NIMBLE_ENABLED + -DCONFIG_BT_NIMBLE_MAX_BONDS=6 # default is 3 -DCONFIG_NIMBLE_CPP_LOG_LEVEL=2 -DCONFIG_BT_NIMBLE_MAX_CCCDS=20 -DCONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=8192 @@ -56,7 +57,7 @@ lib_deps = # renovate: datasource=git-refs depName=libpax packageName=https://github.com/dbinfrago/libpax gitBranch=master https://github.com/dbinfrago/libpax/archive/3cdc0371c375676a97967547f4065607d4c53fd1.zip # renovate: datasource=github-tags depName=XPowersLib packageName=lewisxhe/XPowersLib - https://github.com/lewisxhe/XPowersLib/archive/v0.3.0.zip + https://github.com/lewisxhe/XPowersLib/archive/v0.3.1.zip # renovate: datasource=git-refs depName=meshtastic-ESP32_Codec2 packageName=https://github.com/meshtastic/ESP32_Codec2 gitBranch=master https://github.com/meshtastic/ESP32_Codec2/archive/633326c78ac251c059ab3a8c430fcdf25b41672f.zip # renovate: datasource=custom.pio depName=rweather/Crypto packageName=rweather/library/Crypto diff --git a/arch/esp32/esp32c6.ini b/arch/esp32/esp32c6.ini index 1afb9b547..7b06f4cd8 100644 --- a/arch/esp32/esp32c6.ini +++ b/arch/esp32/esp32c6.ini @@ -28,7 +28,7 @@ lib_deps = ${environmental_extra.lib_deps} ${radiolib_base.lib_deps} # renovate: datasource=custom.pio depName=XPowersLib packageName=lewisxhe/library/XPowersLib - lewisxhe/XPowersLib@0.3.0 + lewisxhe/XPowersLib@0.3.1 # renovate: datasource=git-refs depName=meshtastic-ESP32_Codec2 packageName=https://github.com/meshtastic/ESP32_Codec2 gitBranch=master https://github.com/meshtastic/ESP32_Codec2/archive/633326c78ac251c059ab3a8c430fcdf25b41672f.zip # renovate: datasource=custom.pio depName=rweather/Crypto packageName=rweather/library/Crypto diff --git a/bin/org.meshtastic.meshtasticd.metainfo.xml b/bin/org.meshtastic.meshtasticd.metainfo.xml index 3505f1940..6fc5e8597 100644 --- a/bin/org.meshtastic.meshtasticd.metainfo.xml +++ b/bin/org.meshtastic.meshtasticd.metainfo.xml @@ -87,6 +87,9 @@ + + https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.13 + https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.12 diff --git a/debian/changelog b/debian/changelog index 8bd053b25..e124f8929 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +meshtasticd (2.7.13.0) unstable; urgency=medium + + * Version 2.7.13 + + -- GitHub Actions Sat, 11 Oct 2025 15:27:28 +0000 + meshtasticd (2.7.12.0) unstable; urgency=medium [ Austin Lane ] diff --git a/platformio.ini b/platformio.ini index 2e101a8a2..7121f00b7 100644 --- a/platformio.ini +++ b/platformio.ini @@ -120,7 +120,7 @@ lib_deps = [device-ui_base] lib_deps = # renovate: datasource=git-refs depName=meshtastic/device-ui packageName=https://github.com/meshtastic/device-ui gitBranch=master - https://github.com/meshtastic/device-ui/archive/e564d78ae1a7e9a225aaf4a73b1cb84c549f510f.zip + https://github.com/meshtastic/device-ui/archive/6d8cc228298a1ecd9913aed757187e9527c1facc.zip ; Common libs for environmental measurements in telemetry module [environmental_base] diff --git a/src/Power.cpp b/src/Power.cpp index 7de82b8d6..39d47610b 100644 --- a/src/Power.cpp +++ b/src/Power.cpp @@ -691,6 +691,16 @@ bool Power::setup() #ifdef NRF_APM found = true; #endif +#ifdef EXT_PWR_DETECT + attachInterrupt( + EXT_PWR_DETECT, + []() { + power->setIntervalFromNow(0); + runASAP = true; + BaseType_t higherWake = 0; + }, + CHANGE); +#endif enabled = found; low_voltage_counter = 0; diff --git a/src/configuration.h b/src/configuration.h index e67f0b8e5..b6b1c1e5e 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -33,6 +33,9 @@ along with this program. If not, see . #include "pcf8563.h" #endif +/* Offer chance for variant-specific defines */ +#include "variant.h" + // ----------------------------------------------------------------------------- // Version // ----------------------------------------------------------------------------- @@ -123,6 +126,11 @@ along with this program. If not, see . #define TX_GAIN_LORA 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 9, 9, 8, 7 #endif +#ifdef STATION_G2 +#define NUM_PA_POINTS 19 +#define TX_GAIN_LORA 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 19, 19, 18, 18 +#endif + // Default system gain to 0 if not defined #ifndef TX_GAIN_LORA #define TX_GAIN_LORA 0 @@ -260,9 +268,6 @@ along with this program. If not, see . // convert 24-bit color to 16-bit (56K) #define COLOR565(r, g, b) (((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3)) -/* Step #1: offer chance for variant-specific defines */ -#include "variant.h" - #if defined(VEXT_ENABLE) && !defined(VEXT_ON_VALUE) // Older variant.h files might not be defining this value, so stay with the old default #define VEXT_ON_VALUE LOW diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 4485ca7a3..767f97eed 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -1428,6 +1428,9 @@ int Screen::handleStatusUpdate(const meshtastic::Status *arg) } nodeDB->updateGUI = false; break; + case STATUS_TYPE_POWER: + forceDisplay(true); + break; } return 0; diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp index 210e0ba06..e8dc9843c 100644 --- a/src/mesh/PhoneAPI.cpp +++ b/src/mesh/PhoneAPI.cpp @@ -431,7 +431,6 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf) break; case STATE_SEND_OTHER_NODEINFOS: { - LOG_DEBUG("Send known nodes"); if (nodeInfoForPhone.num != 0) { // Just in case we stored a different user.id in the past, but should never happen going forward sprintf(nodeInfoForPhone.user.id, "!%08x", nodeInfoForPhone.num); @@ -592,6 +591,7 @@ bool PhoneAPI::available() nodeInfoForPhone.snr = isUs ? 0 : nodeInfoForPhone.snr; nodeInfoForPhone.via_mqtt = isUs ? false : nodeInfoForPhone.via_mqtt; nodeInfoForPhone.is_favorite = nodeInfoForPhone.is_favorite || isUs; // Our node is always a favorite + onNowHasData(0); } } @@ -734,7 +734,7 @@ int PhoneAPI::onNotify(uint32_t newValue) LOG_INFO("Tell client we have new packets %u", newValue); onNowHasData(newValue); } else { - LOG_DEBUG("(Client not yet interested in packets)"); + LOG_DEBUG("Client not yet interested in packets (state=%d)", state); } return timeout ? -1 : 0; // If we timed out, MeshService should stop iterating through observers as we just removed one diff --git a/src/mesh/wifi/WiFiAPClient.cpp b/src/mesh/wifi/WiFiAPClient.cpp index 7d210dd33..18f67706a 100644 --- a/src/mesh/wifi/WiFiAPClient.cpp +++ b/src/mesh/wifi/WiFiAPClient.cpp @@ -95,10 +95,12 @@ static void onNetworkConnected() #ifdef ARCH_ESP32 MDNS.addServiceTxt("meshtastic", "tcp", "shortname", String(owner.short_name)); MDNS.addServiceTxt("meshtastic", "tcp", "id", String(nodeDB->getNodeId().c_str())); + MDNS.addServiceTxt("meshtastic", "tcp", "pio_env", optstr(APP_ENV)); // ESP32 prints obtained IP address in WiFiEvent #elif defined(ARCH_RP2040) MDNS.addServiceTxt("meshtastic", "shortname", owner.short_name); MDNS.addServiceTxt("meshtastic", "id", nodeDB->getNodeId().c_str()); + MDNS.addServiceTxt("meshtastic", "pio_env", optstr(APP_ENV)); LOG_INFO("Obtained IP address: %s", WiFi.localIP().toString().c_str()); #endif } diff --git a/src/nimble/NimbleBluetooth.cpp b/src/nimble/NimbleBluetooth.cpp index 5524765f3..0b3009d39 100644 --- a/src/nimble/NimbleBluetooth.cpp +++ b/src/nimble/NimbleBluetooth.cpp @@ -31,11 +31,8 @@ class BluetoothPhoneAPI : public PhoneAPI, public concurrency::OSThread std::vector nimble_queue; std::mutex nimble_mutex; uint8_t queue_size = 0; - bool has_fromRadio = false; uint8_t fromRadioBytes[meshtastic_FromRadio_size] = {0}; size_t numBytes = 0; - bool hasChecked = false; - bool phoneWants = false; protected: virtual int32_t runOnce() override @@ -48,10 +45,7 @@ class BluetoothPhoneAPI : public PhoneAPI, public concurrency::OSThread LOG_DEBUG("Queue_size %u", queue_size); queue_size = 0; } - if (hasChecked == false && phoneWants == true) { - numBytes = getFromRadio(fromRadioBytes); - hasChecked = true; - } + // Note: phoneWants/hasChecked logic removed since onRead() handles getFromRadio() directly // the run is triggered via NimbleBluetoothToRadioCallback and NimbleBluetoothFromRadioCallback return INT32_MAX; @@ -120,21 +114,17 @@ class NimbleBluetoothFromRadioCallback : public NimBLECharacteristicCallbacks virtual void onRead(NimBLECharacteristic *pCharacteristic) #endif { - int tries = 0; - bluetoothPhoneAPI->phoneWants = true; - while (!bluetoothPhoneAPI->hasChecked && tries < 100) { - bluetoothPhoneAPI->setIntervalFromNow(0); - delay(20); - tries++; - } std::lock_guard guard(bluetoothPhoneAPI->nimble_mutex); + + // Get fresh data immediately when client reads + bluetoothPhoneAPI->numBytes = bluetoothPhoneAPI->getFromRadio(bluetoothPhoneAPI->fromRadioBytes); + + // Set the characteristic value with whatever data we have pCharacteristic->setValue(bluetoothPhoneAPI->fromRadioBytes, bluetoothPhoneAPI->numBytes); if (bluetoothPhoneAPI->numBytes != 0) // if we did send something, queue it up right away to reload bluetoothPhoneAPI->setIntervalFromNow(0); bluetoothPhoneAPI->numBytes = 0; - bluetoothPhoneAPI->hasChecked = false; - bluetoothPhoneAPI->phoneWants = false; } }; @@ -243,8 +233,6 @@ class NimbleBluetoothServerCallback : public NimBLEServerCallbacks if (bluetoothPhoneAPI) { std::lock_guard guard(bluetoothPhoneAPI->nimble_mutex); bluetoothPhoneAPI->close(); - bluetoothPhoneAPI->hasChecked = false; - bluetoothPhoneAPI->phoneWants = false; bluetoothPhoneAPI->numBytes = 0; bluetoothPhoneAPI->queue_size = 0; } diff --git a/version.properties b/version.properties index 5c84a8e65..f33f0f1cb 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 2 minor = 7 -build = 12 +build = 13