fix android could not connect from app for ESP

This commit is contained in:
liquidraver
2026-06-15 22:39:50 +02:00
parent 1970231553
commit a0222fe12b
2 changed files with 29 additions and 12 deletions
+13 -3
View File
@@ -6,8 +6,12 @@
* Pairing is triggered reactively by ATT_ERR_AUTHENTICATION on secured GATT
* attributes (Apple §55 compliant — no proactive Security Request on connect).
*
* 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.
* Advertising: always uses the identity address (BT_LE_ADV_OPT_USE_IDENTITY in
* start_adv). On ESP32, CONFIG_BT_PRIVACY=y is load-bearing (the Espressif
* controller's privacy-OFF Secure-Connections path MIC-fails against iOS — see
* findings.md Issue #34), but USE_IDENTITY keeps us off the RPA so the Android
* companion's "connect from app" still works. nRF/MG24 keep privacy OFF and
* already advertise identity, so USE_IDENTITY is a no-op there.
*/
#include <stdio.h>
@@ -1224,9 +1228,15 @@ static void start_adv(void)
uint16_t interval = fast_adv_active ? BT_ADV_FAST_INTERVAL : BT_ADV_INTERVAL;
/* USE_IDENTITY: advertise the stable identity address instead of an RPA,
* even when CONFIG_BT_PRIVACY=y. Keeps the controller in its (working)
* privacy-enabled SC encryption path for iOS while exposing a fixed address
* so the Android companion app's "connect from app" flow works. See
* findings.md Issue #34 iOS-privacy capture (controller MIC failure 0x3d on
* the privacy-off SC path). */
struct bt_le_adv_param adv_param = {
.id = BT_ID_DEFAULT,
.options = BT_LE_ADV_OPT_CONN,
.options = BT_LE_ADV_OPT_CONN | BT_LE_ADV_OPT_USE_IDENTITY,
.interval_min = interval,
.interval_max = interval,
};
+16 -9
View File
@@ -8,16 +8,23 @@
# 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: ESP32-only override. Required for reliable iOS SMP on the
# Espressif controller (Zephyr #84182-class). nRF/MG24 keep privacy off
# because it breaks Android companion "connect from app" (manual pairing
# from system BT settings works, but the app flow silently fails).
# Host privacy: ESP32-only override. Load-bearing for iOS on the Espressif
# controller (Zephyr #84182-class). nRF/MG24 keep privacy OFF.
#
# Re-confirmed 2026-06-15 on shipping blob 19f979cfe6: privacy OFF still breaks
# iOS. iOS *system* pairing completes (PIN prompt, shows as paired) but the
# companion app's GATT connection drops immediately — the #84182 initial-pairing
# breakage the blob did NOT fix. Privacy stays ON; the Android "connect from
# app" tradeoff remains.
# Root cause pinned 2026-06-15 by firmware BLE/SMP debug capture on shipping
# blob 19f979cfe6 (xiao_esp32s3, real iOS): with privacy OFF the SC pairing
# completes the full passkey + DHKey-check phase, the host hands the controller
# a valid LTK (HCI LTK Request Reply, status 0x00), then the controller fails
# to start link encryption — HCI Disconnect reason 0x3d (MIC failure), Encrypt
# Change status 0x1f. It is a bug in the Espressif controller's privacy-OFF
# Secure-Connections path (closed blob); the host did everything right (nRF runs
# the identical host SMP code and bonds with iOS privacy-OFF fine). Privacy ON
# keeps the controller on its working privacy-enabled SC path.
#
# Android "connect from app" is NOT sacrificed: ZephyrBLE advertises with
# BT_LE_ADV_OPT_USE_IDENTITY, so even with privacy ON we expose the stable
# identity address (no RPA) — the thing the Android companion needs. HW-
# confirmed: iOS pairs + syncs, normal disconnect 0x13.
CONFIG_BT_PRIVACY=y
# BLE thread stacks — ESP32 software BLE controller needs larger stacks.