enable bluetooth privacy on esp32 to counter ios/esp bug

android on official app needs a manual BT bond
This commit is contained in:
liquidraver
2026-04-16 13:02:12 +02:00
parent 54eebee9e8
commit e71c3894a2
3 changed files with 213 additions and 210 deletions
+2 -3
View File
@@ -6,9 +6,8 @@
* Pairing is triggered reactively by ATT_ERR_AUTHENTICATION on secured GATT
* attributes (Apple §55 compliant — no proactive Security Request on connect).
*
* Advertising: Public identity address (CONFIG_BT_PRIVACY disabled).
* Android's Flutter BLE plugin fails to connectGatt() to RPA-advertised devices
* from app context. Arduino MeshCore also uses public addresses.
* Advertising: ESP32 enables CONFIG_BT_PRIVACY in esp32_common.conf; nRF uses public identity.
* Android Flutter may fail connect-from-app to RPA unless bonded; Arduino MeshCore uses public.
*/
#include <stdio.h>
+4
View File
@@ -8,6 +8,10 @@
# DLE managed internally by Espressif blob — no CONFIG_BT_CTLR_DATA_LENGTH_MAX
# TX power managed internally by Espressif blob — no CONFIG_BT_CTLR_TX_PWR_*
# Host privacy: required for reliable iOS SMP on Espressif controller (Zephyr #84182-class).
# Android MeshCore may need in-app bond or system pairing when using RPA.
CONFIG_BT_PRIVACY=y
# BLE thread stacks — ESP32 software BLE controller needs larger stacks
CONFIG_BT_TX_PROCESSOR_STACK_SIZE=2048
+207 -207
View File
@@ -1,207 +1,207 @@
# ZephCore Common Configuration
# Included by ALL boards regardless of MCU (nRF52, nRF54L, ESP32, MG24, etc.)
# Contains application-level settings and platform-agnostic BLE/storage/radio config.
#
# Platform-specific configs (nrf52_common.conf, esp32_common.conf, etc.) only
# contain overrides and additions unique to that platform.
# ========== Core Settings ==========
CONFIG_MAIN_STACK_SIZE=8192
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=8192
CONFIG_EVENTS=y
CONFIG_CPP=y
CONFIG_STD_CPP17=y
# ========== Printf Formatting ==========
# Enable floating point support in printf/sprintf (required for CLI)
CONFIG_CBPRINTF_FP_SUPPORT=y
# ========== Crypto (PSA) ==========
# Required for mesh encryption (AES-ECB, SHA256, HMAC)
CONFIG_MBEDTLS=y
CONFIG_MBEDTLS_PSA_CRYPTO_C=y
CONFIG_PSA_WANT_ALG_SHA_256=y
CONFIG_PSA_WANT_ALG_ECB_NO_PADDING=y
CONFIG_PSA_WANT_KEY_TYPE_AES=y
CONFIG_PSA_WANT_ALG_HMAC=y
CONFIG_PSA_WANT_KEY_TYPE_HMAC=y
# ========== Stack Protection ==========
CONFIG_HW_STACK_PROTECTION=y
CONFIG_THREAD_NAME=y
# ========== Hardware Basics ==========
CONFIG_ADC=y
CONFIG_HWINFO=y
CONFIG_REBOOT=y
# ========== LoRa ==========
CONFIG_LORA=y
CONFIG_LORA_MODULE_BACKEND_NATIVE=y
CONFIG_REGULATOR=y
# ========== Display Subsystem ==========
# Display and CFB are auto-enabled by ZEPHCORE_UI_DISPLAY (Kconfig select)
# when "zephyr,display" chosen node exists in the board's devicetree.
# No need to set CONFIG_DISPLAY or CONFIG_CHARACTER_FRAMEBUFFER here.
# Heap baseline — display boards override for larger framebuffers.
CONFIG_HEAP_MEM_POOL_SIZE=2048
# ========== Sensor Subsystem ==========
# Sensors are auto-detected at runtime via I2C scan
CONFIG_SENSOR=y
CONFIG_I2C=y
# ========== GNSS Subsystem ==========
# Driver auto-selected from board DTS compatible (zero overhead if no GNSS in DT):
# quectel,lc76g -> Quectel LCx6G driver
# luatos,air530z -> LuatOS Air530Z driver
# gnss-nmea-generic -> passive NMEA parser
CONFIG_GNSS=y
CONFIG_MODEM_MODULES=y
# ========== BLE Stack (common to ALL platforms) ==========
CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_ZEPHYR_NUS=y
CONFIG_BT_ZEPHYR_NUS_DEFAULT_INSTANCE=n
CONFIG_BT_DEVICE_NAME="MeshCore"
CONFIG_BT_DEVICE_NAME_DYNAMIC=y
CONFIG_BT_DEVICE_NAME_MAX=29
CONFIG_BT_DEVICE_NAME_GATT_WRITABLE=y
CONFIG_BT_DEVICE_APPEARANCE=0
CONFIG_BT_MAX_CONN=1
# SMP: MITM passkey, bonding, enforce bonding
CONFIG_BT_SMP=y
CONFIG_BT_SMP_ENFORCE_MITM=y
CONFIG_BT_APP_PASSKEY=y
CONFIG_BT_BONDABLE=y
CONFIG_BT_BONDING_REQUIRED=y
CONFIG_BT_MAX_PAIRED=5
CONFIG_BT_KEYS_OVERWRITE_OLDEST=y
# Connection parameter update — disabled because we apply conn params
# manually after initial sync completes (zephcore_ble_conn_params_ready).
# The auto-update would fire too early and disrupt channel/contact sync.
CONFIG_BT_GAP_AUTO_UPDATE_CONN_PARAMS=n
# MTU max (controller limit 251, L2CAP MTU 247, ATT payload 244)
CONFIG_BT_BUF_ACL_RX_SIZE=251
CONFIG_BT_BUF_ACL_TX_SIZE=251
CONFIG_BT_L2CAP_TX_MTU=247
# BLE TX buffers — default 3 is too low, causes system workqueue deadlock
# when BLE activity bursts (DLE + param update + ATT) exhaust all buffers
# and bt_hci_cmd_alloc(K_FOREVER) blocks the cooperative syswq forever.
CONFIG_BT_BUF_ACL_TX_COUNT=7
CONFIG_BT_L2CAP_TX_BUF_COUNT=7
CONFIG_BT_CONN_TX_MAX=7
# BLE RX thread stack — default 1200 too small for ATT handlers + logging + asserts
CONFIG_BT_RX_STACK_SIZE=2048
# Data Length Extension update support (host side)
CONFIG_BT_USER_DATA_LEN_UPDATE=y
# PHY update callback — lets us log the negotiated PHY and sequence DLE
# after the PHY procedure completes (avoids LL procedure collision).
#
# NOTE: BT_USER_PHY_UPDATE disables BT_AUTO_PHY_UPDATE (Kconfig default).
# We intentionally do NOT set BT_AUTO_PHY_UPDATE — peripheral-initiated
# PHY updates cause iOS disconnects. The phone (central) initiates PHY
# update and le_phy_updated fires regardless. Coded PHY can be requested
# manually after security is established (future enhancement).
CONFIG_BT_USER_PHY_UPDATE=y
# Privacy disabled — Android's Flutter BLE plugin fails to connect to
# RPA-advertised devices from app context (system BT settings works fine).
# Arduino MeshCore doesn't use RPA either. Actual link security comes from
# SMP pairing (passkey + SC + MITM + bonding), not address privacy.
# CONFIG_BT_PRIVACY=y
# NOTE: SC_PAIR_ONLY intentionally NOT set — Windows can't handle SC passkey
# pairing (never prompts for PIN). Allowing both Legacy and SC lets Windows
# pair with Legacy while iOS/Android use SC.
# Disable Extended Advertising (ALL boards)
# Some controllers (MG24, ESP32) auto-select ext adv PDUs.
# Web Bluetooth (Chrome) can't discover devices using ext adv PDUs.
# Legacy ADV_IND works universally with all BLE scanners and web apps.
CONFIG_BT_EXT_ADV=n
# Device Information Service (Apple requirement)
CONFIG_BT_DIS=y
CONFIG_BT_DIS_MANUF_NAME=y
CONFIG_BT_DIS_MANUF_NAME_STR="ZephCore"
CONFIG_BT_DIS_MODEL_NUMBER=y
CONFIG_BT_DIS_MODEL_NUMBER_STR="ZephCore"
CONFIG_BT_DIS_FW_REV=y
CONFIG_BT_DIS_FW_REV_STR="1.13.0"
CONFIG_BT_DIS_SW_REV=y
CONFIG_BT_DIS_SW_REV_STR="Zephyr"
CONFIG_BT_DIS_PNP=n
# Disable GATT Caching (Robust Caching / Database Hash)
# With caching enabled (Kconfig default), Zephyr silently drops ATT requests
# from "change-unaware" clients after the GATT database changes. This breaks
# service discovery on phones that enable Robust Caching (modern iOS/Android).
# Arduino SoftDevice has no GATT caching — disabling matches that behavior.
CONFIG_BT_GATT_CACHING=n
# Persistent bonds (NVS)
CONFIG_BT_SETTINGS=y
CONFIG_SETTINGS_RUNTIME=y
# ========== Flash & Storage (common to ALL platforms) ==========
CONFIG_FLASH=y
CONFIG_FLASH_MAP=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_SETTINGS=y
# BLE bonds via file-based settings on LittleFS (all platforms)
CONFIG_NVS=n
CONFIG_SETTINGS_NVS=n
CONFIG_SETTINGS_FILE=y
CONFIG_SETTINGS_FILE_PATH="/lfs/settings"
# LittleFS for DataStore
CONFIG_FILE_SYSTEM=y
CONFIG_FILE_SYSTEM_LITTLEFS=y
CONFIG_FS_LITTLEFS_NUM_FILES=8
CONFIG_FS_LITTLEFS_NUM_DIRS=4
CONFIG_FS_LITTLEFS_CACHE_SIZE=256
CONFIG_FILE_SYSTEM_MKFS=y
# ========== Input Subsystem ==========
CONFIG_INPUT=y
CONFIG_INPUT_EVENT_DUMP=n
# Synchronous mode: callbacks run in reporting context (GPIO ISR / syswq)
# instead of a dedicated 1KB input thread. Saves a thread stack.
CONFIG_INPUT_MODE_SYNCHRONOUS=y
# ========== Logging ==========
# RTT log backend: DROP mode (not BLOCK) — when no RTT host is connected the
# buffer is always full; BLOCK mode sleeps 20ms per message with irq_lock held,
# disrupting BLE timing and cascading into buffer exhaustion deadlocks.
CONFIG_LOG_BACKEND_RTT_MODE_DROP=y
# Silence USB CH9 control-transfer spam (dozens of INF lines during enumeration).
# WRN keeps real USB errors visible.
CONFIG_USBD_LOG_LEVEL_WRN=y
# ========== Power Management ==========
CONFIG_POWEROFF=y
# ========== LoRa Power Saving ==========
# RX duty cycle defaults are in Kconfig:
# ON for companion + SX1262/LLCC68 (safe, saves 60-70% RX current)
# OFF for repeaters (latency > battery) and LR1110 (mid-preamble bug)
# Override at runtime via CLI "set rxduty on/off".
# ========== ZephCore Log Levels ==========
# Defaults are INF for all modules (Kconfig default — no explicit =y needed).
# Override per-module on command line if needed:
# -DCONFIG_ZEPHCORE_BLE_LOG_LEVEL_DBG=y (BLE adapter only)
# -DCONFIG_ZEPHCORE_MAIN_LOG_LEVEL_DBG=y (mesh, companion, basechat, utils)
# ZephCore Common Configuration
# Included by ALL boards regardless of MCU (nRF52, nRF54L, ESP32, MG24, etc.)
# Contains application-level settings and platform-agnostic BLE/storage/radio config.
#
# Platform-specific configs (nrf52_common.conf, esp32_common.conf, etc.) only
# contain overrides and additions unique to that platform.
# ========== Core Settings ==========
CONFIG_MAIN_STACK_SIZE=8192
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=8192
CONFIG_EVENTS=y
CONFIG_CPP=y
CONFIG_STD_CPP17=y
# ========== Printf Formatting ==========
# Enable floating point support in printf/sprintf (required for CLI)
CONFIG_CBPRINTF_FP_SUPPORT=y
# ========== Crypto (PSA) ==========
# Required for mesh encryption (AES-ECB, SHA256, HMAC)
CONFIG_MBEDTLS=y
CONFIG_MBEDTLS_PSA_CRYPTO_C=y
CONFIG_PSA_WANT_ALG_SHA_256=y
CONFIG_PSA_WANT_ALG_ECB_NO_PADDING=y
CONFIG_PSA_WANT_KEY_TYPE_AES=y
CONFIG_PSA_WANT_ALG_HMAC=y
CONFIG_PSA_WANT_KEY_TYPE_HMAC=y
# ========== Stack Protection ==========
CONFIG_HW_STACK_PROTECTION=y
CONFIG_THREAD_NAME=y
# ========== Hardware Basics ==========
CONFIG_ADC=y
CONFIG_HWINFO=y
CONFIG_REBOOT=y
# ========== LoRa ==========
CONFIG_LORA=y
CONFIG_LORA_MODULE_BACKEND_NATIVE=y
CONFIG_REGULATOR=y
# ========== Display Subsystem ==========
# Display and CFB are auto-enabled by ZEPHCORE_UI_DISPLAY (Kconfig select)
# when "zephyr,display" chosen node exists in the board's devicetree.
# No need to set CONFIG_DISPLAY or CONFIG_CHARACTER_FRAMEBUFFER here.
# Heap baseline — display boards override for larger framebuffers.
CONFIG_HEAP_MEM_POOL_SIZE=2048
# ========== Sensor Subsystem ==========
# Sensors are auto-detected at runtime via I2C scan
CONFIG_SENSOR=y
CONFIG_I2C=y
# ========== GNSS Subsystem ==========
# Driver auto-selected from board DTS compatible (zero overhead if no GNSS in DT):
# quectel,lc76g -> Quectel LCx6G driver
# luatos,air530z -> LuatOS Air530Z driver
# gnss-nmea-generic -> passive NMEA parser
CONFIG_GNSS=y
CONFIG_MODEM_MODULES=y
# ========== BLE Stack (common to ALL platforms) ==========
CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_ZEPHYR_NUS=y
CONFIG_BT_ZEPHYR_NUS_DEFAULT_INSTANCE=n
CONFIG_BT_DEVICE_NAME="MeshCore"
CONFIG_BT_DEVICE_NAME_DYNAMIC=y
CONFIG_BT_DEVICE_NAME_MAX=29
CONFIG_BT_DEVICE_NAME_GATT_WRITABLE=y
CONFIG_BT_DEVICE_APPEARANCE=0
CONFIG_BT_MAX_CONN=1
# SMP: MITM passkey, bonding, enforce bonding
CONFIG_BT_SMP=y
CONFIG_BT_SMP_ENFORCE_MITM=y
CONFIG_BT_APP_PASSKEY=y
CONFIG_BT_BONDABLE=y
CONFIG_BT_BONDING_REQUIRED=y
CONFIG_BT_MAX_PAIRED=5
CONFIG_BT_KEYS_OVERWRITE_OLDEST=y
# Connection parameter update — disabled because we apply conn params
# manually after initial sync completes (zephcore_ble_conn_params_ready).
# The auto-update would fire too early and disrupt channel/contact sync.
CONFIG_BT_GAP_AUTO_UPDATE_CONN_PARAMS=n
# MTU max (controller limit 251, L2CAP MTU 247, ATT payload 244)
CONFIG_BT_BUF_ACL_RX_SIZE=251
CONFIG_BT_BUF_ACL_TX_SIZE=251
CONFIG_BT_L2CAP_TX_MTU=247
# BLE TX buffers — default 3 is too low, causes system workqueue deadlock
# when BLE activity bursts (DLE + param update + ATT) exhaust all buffers
# and bt_hci_cmd_alloc(K_FOREVER) blocks the cooperative syswq forever.
CONFIG_BT_BUF_ACL_TX_COUNT=12
CONFIG_BT_L2CAP_TX_BUF_COUNT=12
CONFIG_BT_CONN_TX_MAX=12
# BLE RX thread stack — default 1200 too small for ATT handlers + logging + asserts
CONFIG_BT_RX_STACK_SIZE=2048
# Data Length Extension update support (host side)
CONFIG_BT_USER_DATA_LEN_UPDATE=y
# PHY update callback — lets us log the negotiated PHY and sequence DLE
# after the PHY procedure completes (avoids LL procedure collision).
#
# NOTE: BT_USER_PHY_UPDATE disables BT_AUTO_PHY_UPDATE (Kconfig default).
# We intentionally do NOT set BT_AUTO_PHY_UPDATE — peripheral-initiated
# PHY updates cause iOS disconnects. The phone (central) initiates PHY
# update and le_phy_updated fires regardless. Coded PHY can be requested
# manually after security is established (future enhancement).
CONFIG_BT_USER_PHY_UPDATE=y
# Privacy disabled — Android's Flutter BLE plugin fails to connect to
# RPA-advertised devices from app context (system BT settings works fine).
# Arduino MeshCore doesn't use RPA either. Actual link security comes from
# SMP pairing (passkey + SC + MITM + bonding), not address privacy.
# CONFIG_BT_PRIVACY=y
# NOTE: SC_PAIR_ONLY intentionally NOT set — Windows can't handle SC passkey
# pairing (never prompts for PIN). Allowing both Legacy and SC lets Windows
# pair with Legacy while iOS/Android use SC.
# Disable Extended Advertising (ALL boards)
# Some controllers (MG24, ESP32) auto-select ext adv PDUs.
# Web Bluetooth (Chrome) can't discover devices using ext adv PDUs.
# Legacy ADV_IND works universally with all BLE scanners and web apps.
CONFIG_BT_EXT_ADV=n
# Device Information Service (Apple requirement)
CONFIG_BT_DIS=y
CONFIG_BT_DIS_MANUF_NAME=y
CONFIG_BT_DIS_MANUF_NAME_STR="ZephCore"
CONFIG_BT_DIS_MODEL_NUMBER=y
CONFIG_BT_DIS_MODEL_NUMBER_STR="ZephCore"
CONFIG_BT_DIS_FW_REV=y
CONFIG_BT_DIS_FW_REV_STR="1.13.0"
CONFIG_BT_DIS_SW_REV=y
CONFIG_BT_DIS_SW_REV_STR="Zephyr"
CONFIG_BT_DIS_PNP=n
# Disable GATT Caching (Robust Caching / Database Hash)
# With caching enabled (Kconfig default), Zephyr silently drops ATT requests
# from "change-unaware" clients after the GATT database changes. This breaks
# service discovery on phones that enable Robust Caching (modern iOS/Android).
# Arduino SoftDevice has no GATT caching — disabling matches that behavior.
CONFIG_BT_GATT_CACHING=n
# Persistent bonds (NVS)
CONFIG_BT_SETTINGS=y
CONFIG_SETTINGS_RUNTIME=y
# ========== Flash & Storage (common to ALL platforms) ==========
CONFIG_FLASH=y
CONFIG_FLASH_MAP=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_SETTINGS=y
# BLE bonds via file-based settings on LittleFS (all platforms)
CONFIG_NVS=n
CONFIG_SETTINGS_NVS=n
CONFIG_SETTINGS_FILE=y
CONFIG_SETTINGS_FILE_PATH="/lfs/settings"
# LittleFS for DataStore
CONFIG_FILE_SYSTEM=y
CONFIG_FILE_SYSTEM_LITTLEFS=y
CONFIG_FS_LITTLEFS_NUM_FILES=8
CONFIG_FS_LITTLEFS_NUM_DIRS=4
CONFIG_FS_LITTLEFS_CACHE_SIZE=256
CONFIG_FILE_SYSTEM_MKFS=y
# ========== Input Subsystem ==========
CONFIG_INPUT=y
CONFIG_INPUT_EVENT_DUMP=n
# Synchronous mode: callbacks run in reporting context (GPIO ISR / syswq)
# instead of a dedicated 1KB input thread. Saves a thread stack.
CONFIG_INPUT_MODE_SYNCHRONOUS=y
# ========== Logging ==========
# RTT log backend: DROP mode (not BLOCK) — when no RTT host is connected the
# buffer is always full; BLOCK mode sleeps 20ms per message with irq_lock held,
# disrupting BLE timing and cascading into buffer exhaustion deadlocks.
CONFIG_LOG_BACKEND_RTT_MODE_DROP=y
# Silence USB CH9 control-transfer spam (dozens of INF lines during enumeration).
# WRN keeps real USB errors visible.
CONFIG_USBD_LOG_LEVEL_WRN=y
# ========== Power Management ==========
CONFIG_POWEROFF=y
# ========== LoRa Power Saving ==========
# RX duty cycle defaults are in Kconfig:
# ON for companion + SX1262/LLCC68 (safe, saves 60-70% RX current)
# OFF for repeaters (latency > battery) and LR1110 (mid-preamble bug)
# Override at runtime via CLI "set rxduty on/off".
# ========== ZephCore Log Levels ==========
# Defaults are INF for all modules (Kconfig default — no explicit =y needed).
# Override per-module on command line if needed:
# -DCONFIG_ZEPHCORE_BLE_LOG_LEVEL_DBG=y (BLE adapter only)
# -DCONFIG_ZEPHCORE_MAIN_LOG_LEVEL_DBG=y (mesh, companion, basechat, utils)