This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

HID over GATT on Android disconnects after 30 seconds

I am using nrf51822 with PCA 10001, SoftDevice S110 6.0 and SDK 5.2. I modified the HID example to send media keys, basically I just changed the report map and added a few functions for sending media keys. This all works great on iOS 7, I am able to connect and can send the media keys just fine. The iOS device will stay connected indefinitely.

However, on Android, I am seeing disconnection issues. I can connect just fine, and things work for about 30 seconds, but then it just disconnects. It does not matter if I press buttons (send media keys) or not, the connection is always lost after roughly 30 seconds. I looked at the ble_evt_t on disconnect and the reason code for disconnect is 8. As far as I can tell, that is HCI timeout.

I tried disabling the battery service, just to see if that helped. It didn't.

I tried using the sniffer application to capture the events. However, I must not be using it properly because nothing is captured once the android phone connects. I see the advertisements before the connection, but as soon as I connect, nothing. When the disconnect happens, I see hundreds of advertisements packets flood in from the nrf51822 to the Android phone, but I don't see anything while the connection is established.

Is there something different I need to do with Android to avoid this disconnection? Is there something else I can do to debug the problem? Right now, I am sort of stuck as I am not sure how to get more information about the problem. Please let me know. Thanks

  • Anyone have insight here? I have tried setting the connection parameters to various things based on a different post, but that didn't help. I am quite stuck here and cannot proceed. iOS still works fine. Android will always disconnect after some period of time, even though it works properly while connected.

  • Got the same issue, but with BlueZ on Linux (so same)

  • UPDATE TO THE UPDATE: I found a way to sniff HCI packets from the Android side. By looking at the trace, as far as I can see, the Disconnect event is coming from the nrf51822. I see nothing in the logs, and then there is one packet:

    • HCI Packet Type: 0x04 (HCI Event)
    • Event Code: (0x05) Disconnect Complete
    • Parameter Total Length: 4
    • Status: 0x00 Success
    • Connection Handle: 0x0002
    • Reason: 0x08 Connection Timeout

    So the nrf51822 is initiating the disconnect it seems. How can I catch this from the nrf51822 side before it sends that packet? I have the normal event handlers set up for ble events with breakpoints, but it doesn't get caught there. Where can I catch the reason the chip is sending that packet?

    UPDATE: I set the next_conn_params_update_delay parameter in the ble_conn_params_init_t structure to a ridiculously high value. Once I do that, I can basically keep the Anrdoid phone connected nearly indefinitely. However, it doesn't solve the problem entirely. If I wait a long period of time (10 minutes or so) and then I send a media key, it does go through (the action registers on the phone), but then sometimes it will disconnect right after and sometimes it will stay connected. So it seems that there is still some kind of issue when packets go back and forth, the connection parameter update may have just been exacerbating the problem because packets were going back and forth every 30 seconds when the slave requested new parameters. By turning that off, I am using less packets and hence less chance of a disconnect.

    I am trying to investigate. Anyone from Nordic have any thoughts in this issue?

    Original: I played around with this a bit more. If I turn the Wifi off on the Android phone, it will stay connected a lot longer. I read in a few places that Android had an issue at one point that it would reject incoming connection parameter update requests if Wifi is on. However, it was supposed to be resolved in Android 4.4.

    So turning Wifi off does help, but it doesn't entirely solve the problem because it will still disconnect after some time, but it's more like 5 minutes. At this point, I am starting to think that this has something to do with the Android phone missing connection events or not handling connect parameter updates properly. I am playing around with the NEXT_CONN_PARAMS_UPDATE_DELAY parameter to see if it helps. Is there a way (or is it a good idea) to never update the connection parameters once connected?

    The thing is, I have used other BLE modules with this chip (like the RFDuino) and they maintain the connection indefinitely. So even if it is an issue with Android, there must be a way to work around it from the nrf51822.

    The other annoying part is, when the phone disconnects, the nrf51822 isn't going back to advertise state. In some way, it is still connected to the Android phone. I have to unpair the two, turn off Bluetooth in Android and then re-scan and reconnect. So it takes a while just to debug/test.

  • Hi,

    You could try to set the disconnect_on_fail menber of ble_conn_params_init_t to false, and see if that helps. Then the application should not disconnect even if it is not satisfied with the connection parameters from the master.

    BR, Øyvind

  • Thanks for the response. Yes, I already had it set to false, and I don't think it is directly related to the connection parameter update.

    I am keeping the interval between connection parameter updates extremely high. If I do that, and I have Wifi turned off in the Android phone, it will stay connected for a very long time. However, if I wait a few minutes press a button and send a HID key, there is about a 50% chance it will disconnect. Also, if I turn on Wifi in the Android handset, it will likely disconnect without any other action. So disconnects are happening outside of just connection parameter updates.

    I have tried the RFDuino, which is using nrf51822 and a custom service on GATT as far as I can tell, with this exact phone. It will stay connected forever even with Wifi on. So there must be a way to keep the connection up. Is there an Android specific example provided by Nordic?

Related