espruino / Espruino

The Espruino JavaScript interpreter - Official Repo
http://www.espruino.com/
Other
2.8k stars 749 forks source link

nRF52 HID fails after reconnection #1101

Closed jgorsica closed 6 years ago

jgorsica commented 7 years ago

Using the Puck.js as a HID device, when connecting to an Android device or Chromebook, it works properly the first time. If I disconnect and try to reconnect the Puck, I get this error message when sending first NRF.sendHIDReport command:

in function called from system Uncaught Error: BLE HID error code 0x3401

I believe this is due to not properly storing and retrieving the CCCD values on disconnect and connect via sd_ble_sys_attr_get and sd_ble_sys_attr_set.

gfwilliams commented 7 years ago

Thanks - I just tried here and can reproduce - although strangely not with an iPad.

just for reference 0x3401 = BLE_ERROR_GATTS_SYS_ATTR_MISSING

Do you have any more information about this, or a fix? The only use of sd_ble_gatts_sys_attr_set I have is in BLE_GATTS_EVT_SYS_ATTR_MISSING

jgorsica commented 7 years ago

Well I found this: https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.s132.api.v2.0.0%2Fgroup_b_leg_a_t_t_s___f_u_n_c_t_i_o_n_s.html I'm no expert, but it sounds like you would store the address of the client device when you connect and then when you disconnect, you would use the "get" function to get the CCCD info and store it (ram?, flash?), and then if you connect again and the client device is the same, you would restore the CCCD info with the "set" command, prior to sending a HID report.

The get and set commands require connection handles and characteristic handles that aren't exposed through the js apis, so I assume this would need to be managed at a lower level. The call of NRF.setServices with the hid option is probably the place to enable tracking of the connected device.

gfwilliams commented 7 years ago

So, you're saying that the state of the notifications on the HID endpoint should be stored, even after a connect/disconnect?

The thing is, pretty much all the HID stuff is handled by a Nordic-provided library: https://github.com/espruino/Espruino/blob/059eb0a3e6031e065dea5bc1101561d4b95b8e9c/targetlibs/nrf5x/components/ble/ble_services/ble_hids/ble_hids.c

And that has specific code to handle disconnect and connect events, so I'd have thought that should really be handling this sort of thing. I guess I'll have to try with Nordic's ble_app_hids_keyboard example and see if that hits the same problems

gfwilliams commented 7 years ago

Looking at this, it seems it'll be fixed with the peer_manager branch. I'm just waiting on Nordic to help with an INTERNAL_ERROR that comes from the softdevice on disconnect

gfwilliams commented 6 years ago

Using peer manager now, so this should be fine.