-
-
Notifications
You must be signed in to change notification settings - Fork 163
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
Windows reconnect error - ESP32-BLE-Gamepad #850
Comments
Thanks @lemmingDev, I will try to test this soon. In the meantime maybe @afpineda has some ideas? |
If you don't have the time to read through the linked thread, this is the only difference, when enabling the "info" flags in the nimconfig.h: I NimBLEServer: subscribe event; attr_handle=39, subscribed: true On re-connect, this line is missing. And what's weird: You can flash an extremely simple BLE-Gamepad button sketch, but let it tell Windows it would have 20+ buttons (not actually setting them up). Thanks in advance for looking into this! |
Hmmm, that sounds like the cccd isn't being saved, maybe need to increase |
Set it to 32, but didn't fix the issue unfortunately |
Thanks @lemmingDev @RaazP, I was able to reproduce this and have found that the error originates in the stack, some error with the storage of the subscription state when windows subscribes to a characteristic, instead of 1 or 2 as is should be, the value is 128. Please bare with me while I troubleshoot, this area of the code is not easy to navigate. |
Thanks for the update! In my own testing just now, with some sketches working on reconnect, and others not, only difference I could really see in the error log was: In a sketch where reconnecting worked:
and then went on to respond to button presses logging the following output for each:
But when it didn't work correctly on reconnection, it looked pretty much the same, except it seemed to be missing:
and then no Gatt Read events were logged Basically exactly the same as what @RaazP found |
In fact, I was already aware of this bug. Regarding this issue, please note that input reports are not fully implemented according to the HID over GATT specification. |
In case you are wondering, adding the /*
* Descriptor 2902 is required by the HID over GATT spec
* (input reports only), but it works without it.
*/
NimBLEDescriptor *p2902 = inputReportChr->createDescriptor(
hidReport2902DscUuid,
NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::WRITE_ENC,
2);
uint8_t desc2_val[] = {0b01, 0}; // Notifications enabled by default
p2902->setValue(desc2_val, 2); |
For me, adding this descriptor kind of works. When I additionally restart Bluetooth on the Windows side after ESP32 was rebooted, I have working connection again, but it is still not the fix for me. |
It's a well known fact that Windows caches the HID descriptor both in USB and BLE. It's not reloaded each time the device is connected. |
This probably didn't work because NimBLE needs to create the descriptor, just adding the |
I know. The input report characteristic is created adding that property, but the host computer can choose not to receive notifications and/or indications using the The full code follows (this is "what if" code, not production code): NimBLECharacteristic *NimBLEHIDDeviceFix::getInputReport(uint8_t reportId)
{
NimBLECharacteristic *inputReportChr =
getHidService()->createCharacteristic(
hidReportChrUuid,
NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY | NIMBLE_PROPERTY::READ_ENC);
NimBLEDescriptor *inputReportDsc =
inputReportChr->createDescriptor(
hidReportChrDscUuid,
NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::READ_ENC,
2);
uint8_t desc1_val[] = {reportId, 0x01};
inputReportDsc->setValue(desc1_val, 2);
/*
* Descriptor 2902 is required by the HID over GATT spec
* (input reports only), but it works without it.
* Uncomment the following lines if you want to add it.
*/
NimBLEDescriptor *p2902 = inputReportChr->createDescriptor(
hidReport2902DscUuid,
NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::WRITE_ENC,
2);
uint8_t desc2_val[] = {0b01, 0}; // Notifications enabled by default
p2902->setValue(desc2_val, 2);
return inputReportChr;
} |
@h2zero, This excerpt from your migration guide was unknown to me:
So, is the 0x2902 descriptor already there ? Update: It should be created here : NimBLECharacteristic::NimBLECharacteristic(const NimBLEUUID& uuid, uint16_t properties, uint16_t maxLen, NimBLEService* pService)
: NimBLELocalValueAttribute{uuid, 0, maxLen}, m_pCallbacks{&defaultCallback}, m_pService{pService} {
setProperties(properties);
} // NimBLECharacteristic It should check for void setProperties(uint16_t properties) { m_properties = properties; } I'm lost here. I can confirm that any attempt to create the descriptor is blocked, so my previous code is useless: NimBLEDescriptor::NimBLEDescriptor(const NimBLEUUID& uuid, uint16_t properties, uint16_t max_len, NimBLECharacteristic* pCharacteristic)
: NimBLELocalValueAttribute{uuid, 0, max_len}, m_pCallbacks{&defaultCallbacks}, m_pCharacteristic{pCharacteristic} {
// Check if this is the client configuration descriptor and set to removed if true.
if (uuid == NimBLEUUID((uint16_t)0x2902)) {
NIMBLE_LOGW(LOG_TAG, "Manually created 2902 descriptor has no functionality; please remove.");
setRemoved(NIMBLE_ATT_REMOVE_HIDE);
}
... |
@afpineda The descriptor is created automatically in the NimBLE Host, not in this wrapper. All that is is required is to add NIMBLE_PROPERTY::NOTIFY to the characteristic |
Original issue should be resolved in lemmingDev/ESP32-BLE-Gamepad#257 This is an upstream oversight that I will pursue a long term solution to, the workaround in the above PR seems to be satisfactory for now. |
I confirm that calling |
Hi @h2zero
The latest NimBLE-Arduino 2.1.3 is working with ESP32-BLE-Gamepad after a couple of users added some patches to the library
One issue we seem to have now is that on Windows (tested on Windows 10 and 11), it works fine when you pair it the first time, however when you power the board down and it automatically reconnects, gamepad input no longer works.
The main loop seems to be working as any serial output or LEDs modified in the sketch still update.
Android and perhaps Linux seem to work fine still
If you've got the time; any advice on what might need to be changed?
There is a thread with some testing feedback here: lemmingDev/ESP32-BLE-Gamepad#251
Thanks
The text was updated successfully, but these errors were encountered: