fix(zps): build against bundled NimBLE host stack after pioarduino migration

This commit is contained in:
Thomas Göttgens
2026-06-03 14:46:44 +02:00
parent 5e6dc43a59
commit d98bc0b4ee
4 changed files with 56 additions and 6 deletions
+39
View File
@@ -0,0 +1,39 @@
#!/usr/bin/env python3
# trunk-ignore-all(ruff/F821)
# trunk-ignore-all(flake8/F821): For SConstruct imports
import re
Import("env")
# The ZPS module scans BLE through the NimBLE *host* API ble_gap_disc(), which the
# ESP-IDF only compiles when CONFIG_BT_NIMBLE_ROLE_OBSERVER=y. The base esp32 config
# disables the observer role to save flash (see variants/esp32/esp32-common.ini), so
# re-enable it ONLY when the ZPS module is actually built. This keeps a single flag
# (-DMESHTASTIC_EXCLUDE_ZPS) driving both the C++ module and the IDF sdkconfig.
#
# This runs as a pre: script, before the arduino framework builder reads
# custom_sdkconfig (PlatformIO core runs pre-scripts before $BUILD_SCRIPT). Appending
# to custom_sdkconfig changes its hash and triggers the framework's IDF rebuild path,
# but only for ZPS-enabled envs; for every normal build this is a no-op.
flags = env.GetProjectOption("build_flags", "")
if isinstance(flags, (list, tuple)):
flags = " ".join(flags)
# Mirror the C semantics of `#if !MESHTASTIC_EXCLUDE_ZPS`:
# flag absent -> module enabled
# -DMESHTASTIC_EXCLUDE_ZPS=0 -> module enabled
# -DMESHTASTIC_EXCLUDE_ZPS or =1 (or anything else) -> module excluded
match = re.search(r"\bMESHTASTIC_EXCLUDE_ZPS\b(?:=(\S+))?", flags)
zps_enabled = (match is None) or (match.group(1) == "0")
section = "env:" + env["PIOENV"]
config = env.GetProjectConfig()
if zps_enabled and config.has_option(section, "custom_sdkconfig"):
sdkconfig = env.GetProjectOption("custom_sdkconfig")
if "CONFIG_BT_NIMBLE_ROLE_OBSERVER" not in sdkconfig:
config.set(
section,
"custom_sdkconfig",
sdkconfig.rstrip("\n") + "\n CONFIG_BT_NIMBLE_ROLE_OBSERVER=y\n",
)
print("[ZPS] module enabled -> CONFIG_BT_NIMBLE_ROLE_OBSERVER=y (IDF rebuild)")
+14 -4
View File
@@ -6,6 +6,8 @@
* Released under GPL v3 (see LICENSE file for details)
*/
#if defined(ARCH_ESP32) && !MESHTASTIC_EXCLUDE_ZPS
#include "ZPSModule.h"
#include "Default.h"
#include "MeshService.h"
@@ -18,7 +20,13 @@
#if !defined(MESHTASTIC_EXCLUDE_BLUETOOTH)
#include "NimBLEDevice.h"
// Use the bundled NimBLE host stack directly (matching src/nimble/NimbleBluetooth.cpp).
// The external h2zero NimBLE-Arduino library (NimBLEDevice.h) is in lib_ignore since the
// pioarduino / arduino-esp32 3.x migration, so we talk to the raw host APIs instead.
#include "host/ble_gap.h"
#include "host/ble_hs.h"
#include "host/ble_hs_adv.h"
#include "host/ble_hs_id.h"
#define BLE_MAX_REC 15
#define BLE_NO_RESULTS -1 // Indicates a BLE scan is in progress
@@ -256,7 +264,7 @@ int32_t ZPSModule::runOnce()
return 5000;
}
uint64_t encodeBSS(uint8_t *bssid, uint8_t chan, uint8_t absRSSI)
uint64_t encodeBSS(const uint8_t *bssid, uint8_t chan, uint8_t absRSSI)
{
uint64_t netBytes = absRSSI & 0xff;
netBytes <<= 8;
@@ -270,7 +278,7 @@ uint64_t encodeBSS(uint8_t *bssid, uint8_t chan, uint8_t absRSSI)
return netBytes;
}
uint64_t encodeBLE(uint8_t *addr, uint8_t absRSSI)
uint64_t encodeBLE(const uint8_t *addr, uint8_t absRSSI)
{
uint64_t netBytes = absRSSI & 0xff;
netBytes <<= 8;
@@ -416,4 +424,6 @@ static int ble_scan(uint32_t duration, bool passive, bool dedup)
return rc;
}
#endif // MESHTASTIC_EXCLUDE_BLUETOOTH
#endif // MESHTASTIC_EXCLUDE_BLUETOOTH
#endif // ARCH_ESP32 && !MESHTASTIC_EXCLUDE_ZPS
+2 -2
View File
@@ -20,8 +20,8 @@ enum SCANSTATE { SCAN_NONE, SCAN_BSS_RUN, SCAN_BSS_DONE, SCAN_BLE_RUN, SCAN_BLE_
* Ingest a WiFi BSSID, channel and RSSI (or BLE address and RSSI)
* and encode them into a packed uint64
*/
uint64_t encodeBSS(uint8_t *bssid, uint8_t chan, uint8_t absRSSI);
uint64_t encodeBLE(uint8_t *addr, uint8_t absRSSI);
uint64_t encodeBSS(const uint8_t *bssid, uint8_t chan, uint8_t absRSSI);
uint64_t encodeBLE(const uint8_t *addr, uint8_t absRSSI);
class ZPSModule : public SinglePortModule, private concurrency::OSThread
{
+1
View File
@@ -14,6 +14,7 @@ platform_packages =
extra_scripts =
${env.extra_scripts}
pre:extra_scripts/esp32_pre.py
pre:extra_scripts/zps_observer.py
extra_scripts/esp32_extra.py
build_src_filter =