-
Notifications
You must be signed in to change notification settings - Fork 98
Description
Hi @jgriffiths and @JamieDriver,
I am providing a comprehensive root cause analysis for the connectivity issues affecting DIY Jade devices (TTGO/ESP32/ESP32S3) on iOS 18 (Issues #185 and Blockstream/green_ios#70).
Our investigation has isolated a "Perfect Storm" of three compounding regressions that render generic ESP32 hardware unusable on iOS 18, starting from Firmware v1.0.31 and Green iOS v4.0.38.
1. Firmware Regression: The Upgrade (IDF 5.1 -> 5.4)
Diffing main/idf_component.yml between v1.0.30 and v1.0.34 reveals a massive jump in the underlying OS:
- version: "==5.1.3"
+ version: "==5.4"Jumping to ESP-IDF 5.4 brings a completely new NimBLE stack implementation and stricter PHY/Radio calibration timings. Generic hardware (like TTGO T-Display) often relies on "loose" tolerances that worked in IDF 5.1 but fail under the stricter requirements of IDF 5.4's BLE stack.
2. Firmware Logic: The Negotiation Blocker
Coinciding with the IDF upgrade, main/ble/ble.c was modified to explicitly reject the Central's connection parameters in favor of hardcoded values.
Code Diff (main/ble/ble.c):
+ case BLE_GAP_EVENT_CONN_UPDATE_REQ:
+ // The firmware now FORCES its own preferred intervals, overriding iOS suggestions
+ event->conn_update_req.self_params->itvl_min = BLE_GAP_INITIAL_CONN_ITVL_MIN;
+ event->conn_update_req.self_params->itvl_max = BLE_GAP_INITIAL_CONN_ITVL_MAX;
+ // ...
+ return 0;By forcing self_params, the firmware prevents iOS from negotiating a stable interval. If the DIY board's crystal oscillator drifts slightly (common in generic hardware), this forced interval causes a supervision timeout.
Additionally, a "busy wait" was introduced in ble_writer, switching from portMAX_DELAY to polling every 100ms, introducing unnecessary CPU jitter during connection events.
3. Client-Side Trigger: GDK Overhead
On the iOS side (Green v4.0.38), Cargo.lock analysis shows GDK updated bitcoin to v0.32.4 (breaking change) and futures to v0.3.31. This heavier stack likely increased processing latency on the client side.
The Conclusion
The combination of IDF 5.4's strictness + Forced Parameters in ble.c + GDK Latency creates a scenario where generic hardware cannot reply fast enough or precisely enough for the iOS 18 Bluetooth Supervisor, resulting in immediate BLE_HS_ECONTROLLER (531) errors.
Proposed Fix:
To restore DIY compatibility without affecting official hardware:
- Critical: Remove or comment out the explicit parameter override block in
BLE_GAP_EVENT_CONN_UPDATE_REQwithinmain/ble/ble.c. This reverts to the v1.0.30 behavior, allowing iOS to dictate the connection parameters. - Alternatively: If these values are defined in
main/ble/ble.h, they should be exposed via Kconfig (sdkconfig) so DIY builds can relax the timings without modifying source code.