ESP32 HCI Mode: Solving Reconnection & Pairing Loss

by Admin 52 views
ESP32 HCI Mode: Solving Reconnection & Pairing Loss

Hey everyone,

We've been wrestling with a tricky issue involving the ESP32 and NINA-W106 module in Controller-only HCI mode, specifically dealing with reconnection and pairing problems. I wanted to share the details and see if anyone has encountered something similar or has insights to offer. Let's dive in!

The Setup

  • Module: u-blox NINA-W106 (ESP32)
  • Mode: Controller-only HCI over UART (H4)
  • Host: Raspberry Pi running BlueZ
  • Use Case: Bluetooth Classic (BR/EDR) for SPP/RFCOMM with an Android app

Our ESP32 firmware is based on the controller_hci_uart_demo example, but with a few key tweaks:

  • CTS/RTS flow control is enabled.
  • We're using a fixed baudrate of 921600.
  • No sleep or power management is enabled to keep things stable.
  • The BD_ADDR is fixed, read directly from the eFuse and not modified.

While the HCI-UART transport itself seems stable now, we're still running into a frustrating issue with reconnection and pairing.

The Problem: Reconnection and Pairing Woes

Here's the scenario that keeps tripping us up:

  1. Initial pairing between the Android tablet and the Raspberry Pi (via the NINA module) works perfectly. We can establish an SPP connection and transfer data without a hitch.
  2. However, when the Android app is closed and then reopened, it tries to reconnect automatically.
  3. This is where things go south. btmon shows the following sequence:
    • Link Key Request comes in.
    • Followed immediately by a Link Key Request Negative Reply because the host doesn't seem to have the key.
    • The Android device then initiates re-pairing.
    • But the host responds with an IO Capability Request Negative Reply (Pairing Not Allowed 0x18).
    • The end result is a Simple Pairing Complete – Authentication Failure (0x05).
  4. To add insult to injury, the Android device then automatically removes the device from its paired devices list.

The really puzzling part is that the ESP32 isn't reset at any point during this process. Only the Android app is closed and reopened. Yet, the host (BlueZ) appears to lose the link key, which causes the reconnection to fail. This is a major headache for us.

Verified Configuration

We've already double-checked a few things to rule out the obvious:

  • Baudrate and flow control: We're definitely running at 921600 with CTS/RTS enabled.
  • No resets: We're not calling esp_bt_controller_disable() or resetting the controller between sessions.
  • Fixed BD_ADDR: The Bluetooth address is consistent, read from the eFuse.
  • Interface status: The hci0 interface remains UP and active throughout the test.

Interestingly, this problem doesn't occur when we use CSR/WT11-based dongles with the same host and Android app. This points to something specific to the ESP32 or its interaction with BlueZ in HCI mode.

Is Link Key Persistence the Culprit?

We've stumbled upon a potential clue in ESP-IDF issue #12650. It seems several users have reported that link keys aren't being stored or persisted in the ESP32 context, particularly in Controller-only HCI mode. This aligns perfectly with what we're seeing: the host requests a link key that's no longer there, leading to the authentication failure.

Our analysis suggests that the Controller-only HCI mode on the ESP32 might not be retaining or keeping BR/EDR link keys valid between sessions. This would explain why the host is missing the key upon reconnection.

Questions for the Espressif Team

We're hoping the Espressif team can shed some light on this. Specifically, we'd like to know:

  1. Official Support: Is there currently any official support for BR/EDR link key persistence in HCI Controller-only mode? This is crucial for our use case.
  2. API or Vendor Command: If not, is there any API or vendor command that would allow us to intercept or restore link keys from the controller side? We need a way to manage these keys.
  3. Future Fixes: Are there any plans for a future fix, such as automatic NVS storage of link keys? Knowing the roadmap would help us plan our development.
  4. Event Interception: Is there a supported method to intercept Link Key Notification / Link Key Request HCI events from the controller in ESP-IDF? This would allow us to potentially handle the key exchange ourselves.

Project Context and Constraints

To give you some background, we're using the NINA-W106 module as part of a custom Bluetooth dongle in an industrial production environment. These dongles are integrated with Linux-based self-service terminals.

Unfortunately, we can't modify the Raspberry Pi or BlueZ host software. Any solution needs to be implemented entirely on the ESP32 firmware side. This limits our options and makes finding a workaround even more critical.

Why Link Key Persistence Matters

Link key persistence is the cornerstone of a seamless and secure Bluetooth experience. Without it, devices are forced to re-pair every time a connection is re-established, leading to a frustrating user experience. In industrial settings, this is simply unacceptable. Imagine a self-service terminal requiring customers to re-pair their devices every single time they use it. That's a non-starter.

Security is also a major concern. Frequent re-pairing increases the window of opportunity for potential security breaches. Each pairing process involves exchanging sensitive information, and the more often this happens, the higher the risk. A robust solution must ensure that link keys are securely stored and managed to minimize these risks.

From a technical perspective, link key persistence simplifies the connection process and reduces the overhead on both the client and server devices. It eliminates the need for repeated authentication and encryption key negotiation, resulting in faster and more efficient connections. This is especially important in resource-constrained environments like embedded systems, where processing power and memory are limited.

Ultimately, link key persistence is about providing a reliable and user-friendly Bluetooth experience. It's about ensuring that devices can seamlessly connect and communicate without the need for constant intervention. This is essential for building robust and scalable Bluetooth solutions that can meet the demands of modern industrial applications.

Diving Deep into HCI Controller-Only Mode

HCI Controller-Only Mode is a specific configuration where the ESP32 acts solely as a Bluetooth controller, offloading the host processing to an external device, in our case, the Raspberry Pi. This mode is often chosen for its simplicity and efficiency, but it also comes with its own set of challenges.

One of the main challenges is managing the communication and coordination between the controller and the host. The controller is responsible for handling the low-level Bluetooth protocol, while the host is responsible for higher-level functions like security and application logic. Ensuring seamless communication between these two components is crucial for a stable and reliable Bluetooth connection.

In the context of link key persistence, HCI Controller-Only Mode presents a unique set of considerations. Since the controller is not directly involved in the security aspects of the connection, it relies on the host to manage the link keys. This means that the host must be able to securely store and retrieve the link keys, and it must be able to communicate these keys to the controller when needed.

Another challenge is the limited resources available on the controller side. The ESP32 has limited memory and processing power, which can make it difficult to implement complex security algorithms or store large amounts of data. This means that the link key persistence solution must be lightweight and efficient, minimizing the overhead on the controller.

Despite these challenges, HCI Controller-Only Mode can be a viable option for Bluetooth applications, especially when combined with a robust and well-designed link key persistence solution. By carefully considering the trade-offs and challenges involved, it is possible to build reliable and secure Bluetooth connections that meet the demands of modern industrial environments.

Any guidance or clarification on BR/EDR link key persistence in controller-only HCI mode would be greatly appreciated. We're really hoping to find a solution that works within our constraints.

Thanks a bunch for your time and expertise!