-
Notifications
You must be signed in to change notification settings - Fork 7k
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
Two classic BT HID devices connecting at the same time fail with ERR_SDP (BT_SDP: process_service_attr_rsp occurs after ESP_HIDH_OPEN_EVENT). (IDFGH-9100) #10504
Comments
Hi @benryves, Thanks for reporting!
Do the two procedures have the same result(ERR_SDP)? And can you always reproduce the issue? I can't reproduce the issue as you described. So please help enable the following config:
The crash may be caused by referring to the NULL pointer in the hidh_callback function, please check the pointer before using it. |
Thank you for your reply, @boblane1! Both procedures have the same ERR_SDP error. Having both remotes connected and then resetting the ESP32 is the easier way to trigger the issue as it is more likely that they try to connect at the same time, but it is also possible to trigger the error manually by switching on the Wii remotes at the same time. Staggering their I don't really understand what's going on internally but what stands out to me is when the Wii remotes connect successfully I get a message from BT_SDP: process_service_attr_rsp before BT_HIDH opens the device. When I switch them on at the same time the BT_SDP: process_service_attr_rsp comes after the BT_HIDH failure. I tried to dig my way into the code to see why these would appear to happen out of order but it's all a bit beyond me, sorry! I changed the configuration options as requested, here is the log of a failed connection:
After failing both Wii remotes sit with their "connecting..." LEDs flashing, but they never time out (which is also what happens when they connect successfully, but you need to send a HID report to switch the LEDs off, and as the BT_HIDH open fails I never get access to the device to switch the LEDs off). |
Hi @benryves, I am glad you have tried to find out the reason by yourself. The root reason is that the Bluetooth stack on ESP32 only supports one SDP procedure each time. In your case, the second HID connection is occurred while the first SDP procedure has not been finished. You can work around the issue by either staggering the two reconnection or adding the additional reconnection procedures when the previous reconnection is failed. If you choose the second solution, please apply the following patch first. |
Hi @boblane1, Thank you very much for your advice and the patch. Unfortunately, this is all a bit beyond me - I find it extremely difficult to follow the Bluedroid code as a lot of it is indirect (e.g. via callback tables), not to mention the sheer volume of it, so I'm not really sure where I'd go to fix this. I've spent a few hours digging through the code but not really closer to a proper solution. My workaround is to count the number of successfully connected and opened devices. If an incoming connection fails to open and there are no known successfully opened devices, I wait one second then deinit() and then re-init() all Bluetooth components. By doing this the devices that failed to open do get disconnected properly (and so you can try to reconnect them without having to pull their batteries out). It's all a bit of a hack but I'm not really sure what the proper way to handle this is, but as far as user experience is concerned this at least masks the problem a bit better than before. |
Hi @benryves, Maybe the deinit and re-init procedure is unnecessary. I think it's better to initiate the reconnection procedure directly, since it will not break the established connection. I will handle like the following comments. void hidh_callback(void *handler_args, esp_event_base_t base, int32_t id, void *event_data)
{
...
case ESP_HIDH_OPEN_EVENT: {
if (param->open.status == ESP_OK) {
const uint8_t *bda = esp_hidh_dev_bda_get(param->open.dev);
ESP_LOGI(TAG, ESP_BD_ADDR_STR " OPEN: %s", ESP_BD_ADDR_HEX(bda), esp_hidh_dev_name_get(param->open.dev));
esp_hidh_dev_dump(param->open.dev, stdout);
} else {
ESP_LOGE(TAG, " OPEN failed!");
// push the bda to your own task work queue
}
break;
}
...
}
your_own_app_task()
{
// 1. fetch from the work queue and check if it is reconnection event
// 2. delay some time
// 3. call `esp_hidh_dev_open` to trigger the reconnection
} |
Hi @boblane1, Thank you for the suggestion, that would certainly seem like the easiest answer. How would you know the BDA of the device that failed to connect? I'm not initiating the connection myself, the Wii remote is reconnecting automatically. I don't call |
Hi @boblane1, I've made some changes to a couple of files to copy the BDA to the If the
If I then press some buttons on the controller I get similar error messages about the device not being found:
Similar to before, it's as if the controller is connected successfully but something is not properly associated internally. I then tried applying your earlier patch, and this does change things but not for the better - this time after the reconnection attempt with the previously-received BDA I just get an I spent some time digging through Unfortunately, only one of the Wii remotes gets reopened. When two devices attempt to connect simultaneously both are registered (e.g. with At this point, I'm not sure what the best solution is, short of exposing more of the inner guts of There is also one other solution, which is to crash and trigger a reset. By doing this the Wii remotes don't know they were intentionally disconnected (as they do from an deinit()/init() cycle) and so will automatically try to reconnect when the device comes back up instead of switching themselves off. This is a pretty awful solution, but certainly the easiest... |
Hi @benryves, When the HID connection procedure fails for SDP error, the stack doesn't destroy the L2CAP layer connection. Try the following patch again and reconnect, please let me know if the issue is solved, thanks! |
Hi @boblane1, Thank you very much for putting that together, unfortunately after applying those patches I still get stuck in an endless
(In this case the "trying to reconnect" message appears when the connection fails, "reconnecting 00:22:d7:6a:4b:bc..." appears when the pending connection is successfully queued for later retrieval by a task, "re-opening 00:22:d7:6a:4b:bc" appears in the reconnection task when |
Hi @benryves, In the previous patch, when the open operation failed, it comes with both |
Hi @boblane1 Thanks for the feedback, previously I was only using the patch you supplied in fix_hidh_connection_bug_20230130.zip, I reset to a clean version of 5.0 and then applied fix_hidh_connection_bug.zip and then the later patch. After applying both patches I now see the When the
Would it be useful if I was to try to put together the smallest program I can that demonstrates the issue? (You'd need at least two Wii remotes and a push button to perform the initial sync, then once they're paired you could reset the ESP32 until they both tried to reconnect at the same time and triggered the issue). |
Hi @benryves,
|
Thank you for the confirmation, @boblane1! My previous solution was to de-init and re-init the Bluetooth stack on error, this cleanly disconnects the Wii remotes and allows them to be reconnected by pressing a button on them to wake them up (when they encounter an error otherwise they get stuck in an unresponsive state unless you hold the power button down or pull a battery out). I think I may stick to that solution, as it's the least confusing for the user. |
Answers checklist.
IDF version.
v5.0
Operating System used.
Windows
How did you build your project?
VS Code IDE
If you are using Windows, please specify command line type.
PowerShell
Development Kit.
DOIT ESP32 DEVKIT V1
Power Supply used.
USB
What is the expected behavior?
I am attempting to connect two Wii remotes (which are classic Bluetooth HID devices) to an ESP32. The Wii remotes have previously been successfully paired individually (after searching for them and sending the appropriate PIN using the BT GAP API before using the HIDH API to open the device).
If the ESP32 is reset the Wii remotes will reconnect to it automatically, with no need to search for them again via GAP API or by using the HIDH API to open the device. If only one Wii remote is switched on at a time, then both connect successfully. Ideally this should also happen if both Wii remotes are switched on at the same time.
What is the actual behavior?
If both Wii remotes are switched on at the same time then they will both fail to connect with ERR_SDP. If a Wii remote is then switched off (resulting in bta_hh_co_close being called) then BT_HIDH generates a Device Not Found and CLOSE ERROR: NO_CONNECTION and the ESP32 crashes and reboots.
The only thing I can see that indicates what the issue might be is that when the Wii remotes connect successfully the log shows two events from BT_SDP: process_service_attr_rsp before the HIDH open callback is invoked. When the connections fail these BT_SDP: process_service_attr_rsp events come after the HIDH open callback.
Steps to reproduce.
Debug Logs.
More Information.
No response
The text was updated successfully, but these errors were encountered: