-
-
Notifications
You must be signed in to change notification settings - Fork 161
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NimBLE esp32 server bonding to a 2nd client breaks bond info from the 1st client? #782
Comments
What is happening is that you have reached the limit of the bonds / cccds available, when this happens the oldest bond is deleted from NVS to make room for the new one. This is adjustable here: NimBLE-Arduino/src/nimconfig.h Line 119 in 6e89afc
I would suggest also fully erasing the flash before uploading to clear all of the stored bonds and start again. |
Thanks, I updated src/nimconfig.h to set CONFIG_BT_NIMBLE_MAX_BONDS to 5 and CONFIG_BT_NIMBLE_MAX_CCCDS to 20. But it is still not working. Do I need to do anything else to rebuild the NimBLE library? It seems like Arduino IDE rebuilds it. What I'm seeing now is that once I have bonded from my iPhone, and then from my mac, I can still connect from my iPhone without re-pairing, but after connecting from my phone, connections from my mac are broken, and can not read or get notifications. Thanks for your help, and for any further ideas you might have. |
Did you erase the flash? Also close and reopen the IDE to clear the data. |
Thanks! I did erase the flash, and restarted the IDE, and updated to Arduino 2.3.4 and NimBLE-Arduino 1.4.3, but no change. Reconnecting to the iPhone breaks the bond/pair connection to the mac, and re-pairing to the mac breaks the iPhone bond. I can try to put together a complete, minimal example showing the problem. |
I just tested with my phone and an esp32 client and have no issues switching connection back and forth and reading data works as expected with no pairing prompt. |
Thank you for your help. I'm running my ESP32 as a composite HID device that contains just one child device which presents as an XBox game controller. It's based off of the ESP32-BLE-CompisiteHID project, but I've modified it to simplify and remove some unneeded device classes. I don't think I actually need to be using a CompositeHID, so I think I'll try unwrapping the controller device, and using that directly. If that still doesn't work for me, I'll add a minimal project showing the problem, so we can discuss the same exact code. Thanks again. |
This issue I'm seeing is actually that after creating a 2nd bond, and then connecting back to the first device again, the first device sees only empty services with no characteristics. Similar to some comments in issue #651 |
@benjie-git please try flashing your device with this: https://github.com/Edzelf/ESP32-Show_nvs_keys after each bond so we can see what the NVS state is. |
@h2zero I wouldn’t want esp to delete anything by itself if some limits are reached. Is there a way to disallow bonding of new device once we know that we have X number of bonded devices? |
The low level callback is global and overridable, have a look at NimBLEDevice::init |
@h2zero Here's the output from Show_nvs_keys after bonding to one device, and then after bonding to a 2nd device.
|
All looks good there, both bonds are stored... |
I've been able to partially reproduce this with an esp32c6 and using esp idf with esp-nimble-cpp. what I found is that this appears to be an apple bug, in order to get the services to show again I had to turn bluetooth off and on again, then connect. |
@h2zero in my case it was an android phone which was connecting and was showing no characteristics.. however that was a plain esp32.. With a C3 I could not reproduce the issue. |
@h2zero Thanks. I've been restarting Bluetooth on both the mac and the iPhone too, but unfortunately that hasn't helped. |
There seems to be a trend with the HID devices, though I am currently testing with an HID device firmware at the moment as well. |
It would seem we need a common code to use for troubleshooting this, here is what I am using now:
Other than the Apple weirdness it seems to work perfectly with 2 paired devices. What does happen though is that when HID devices are automatically reconnected to whichever device is fastest to establish, preference is given to the last successfully connected peer. In this case both the Mac and iPhone are trying to connect when the device starts advertising, the last one connected to it wins, the other stays in a state of connection but unconfirmed so no access to the services is provided. Details: A device advertises, 2 devices looking for it try to connect, the device that last connected to the advertiser is given preference by the BLE stack, which makes sense. The way BLE connections work is there is the initial connect command sent, then the confirmation via command, unfortunately this is problem as there is no confirmation event, the only confirmation is sending a command and getting a response. So if the 2 devices in question send the connect command at the same time the last device to successfully connect will connect and the other device will sit in a "connected", but not confirmed state, so no services etc. are available. Testing has shown me that the only way for this to work is to have the connection parameters set with loose enough connection parameters that 2 devices can remain connected, which reduces performance. Also connecting 1 HID device to multiple peers seems problematic at best, which device is being controlled? The problem here I would suggest is that, because this is and HID device, Apple, and probably every other manufacturer, once bonded will always look for the device in order to connect as fast as possible and in the background, before any apps connect. On my phone the BLE stack in the phone connected before the app could even get a scan result from it, low level action. |
Thank you @h2zero
|
@h2zero After a bit of cleanup based on your example code, I'm realizing that the ESP32's multiple bonds do seem fine. It turns out that a different part of my testing process is to blame for most of my problem. Turning the Mac's main Bluetooth switch off, and then later back on, seems to break something about the Mac's pairing info. I was turning that off to release the connection from the Mac, so that I could connect from the iPhone without rushing. But I'm testing now without turning off the Mac's Bluetooth, and I'm able to connect back and forth between the Mac and the iPhone, and the bond continues to work fine, and all services populate with characteristics. The remaining problem is minor. It's just that turning off the Mac's bluetooth entirely seems to corrupt something about the connection, and no amount of rebooting the ESP32 or connecting and disconnecting seems to help, until I re-pair. I think the bond itself is actually ok, because it connects and I am not seeing this problem with your example HID code -- only with my own. So I feel that there is likely still room for improvement on my end. |
Glad you're making progress, strange issue for sure. |
Wow, I think my main remaining issue was just setting my connection params too tight. I was using:
and calling notify on my HID input characteristic every 8ms, and was having lots of trouble with reconnection. When I switch to:
and sending updates every 15ms, those weird problems seem to have resolved themselves. I haven't run any overnight tests yet, but it's looking fine so far. |
@benjie-git Yes, connection parameters are SUPER important. Hope it works well. |
Another related question: My HID descriptor is large at 283 bytes. Edit: I'll start a new issue about this one. |
Sorry to be hijacking the thread. Where exactly do u call this? Upon connection or during a connection is established? |
@sanastasiou I'm calling this in my onConnect() callback |
I'm setting up an ESP32-S3 as a peripheral/server connecting to one client at a time. It uses bonding, but I'm having the following problem: My first client can connect, and bonds/pairs fine, and can re-connect fine without re-pairing, but then after I disconnect, and pair to a 2nd client, the 1st client can no longer connect properly.
When the first client is a Mac, after another device pairs and disconnects, the Mac can still partially connect, but receives no data. I believe that it is failing to authenticate.
When the first client is an iPhone, after another device pairs and disconnects, the iPhone is no longer able to authenticate, and so quickly disconnects.
I'm developing in Arduino IDE 2.3.3, with esp32 3.0.7, and NimBLE-Arduino 1.4.2.
my server callbacks include:
Am I missing something that I need to do to convince the esp32 to keep bonding info for multiple clients?
Thank you for your help!
The text was updated successfully, but these errors were encountered: