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

BLE_GAP_EVT_DISCONNECTED taking too long after BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION

Hi,

I'm having trouble with the BLE_GAP_EVT_DISCONNECTED event. I have an nRF 52832 running the SDK 15.2 as peripheral and have tried several devices as centrals (not simultaneously): W10 PC with BLE 4.0 dongle, android phone with BLE 4.x running nRF connect, DK 52840 running from a W10 PC with nRF connect and a W10 laptop with native BLE 5.0. What I've found is that if I attempt to disconnect from the peripheral nRF running the following code

for ( uint32_t i = 0; i < handle_list.len; ++i ) {
	( void ) sd_ble_gap_disconnect( handle_list.conn_handles[i], BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION );
}

most of the time, the event BLE_GAP_EVT_DISCONNECTED comes about very fast, like 100-400 ms. But some times, it takes much more time, around 10s. It's almost exactly 10s, which makes me think that it's probably a timeout and the nRF never got the confirmation of the disconnection from the central device. This behavior only happens with the W10 laptop that has native BLE 5.0. All other devices seem to disconnect right away. 

This behavior causes all sorts of problems for the peripheral device, because it has to notify to other uCs that the disconnection occurred and 10s is way too long. The other uCs have already assumed an error has occurred. I'm kind of at a loss here, I'm not sure where to start looking for the problem. Any ideas?

Thanks

Federico

  • Hi,

    nRF never got the confirmation of the disconnection from the central device

    Yes, you're right, this is most likely what happens. I was able to consistently reproduce the same behavior now on my Windows 10 as well. Turns out the PC just terminates the link as soon as it receives the disconnect PDU without acknowledging the request first. The peripheral is required to send the LL_TERMINATE_IND until an acknowledgement is received or until the supervision timeout expires. Although, the peripheral can't really re-send any more packets as the central is responsible for opening of the connection events.

    Sniffer trace when disconnecting from Windows PC

    And same when connected to an iPhone for comparison

    This behavior causes all sorts of problems for the peripheral device, because it has to notify to other uCs that the disconnection occurred and 10s is way too long.

     For the application logic, could you maybe consider the link as terminated after you have called sd_ble_gap_disconnect() instead of waiting for the disconnect event to come through?

    Best regards,

    Vidar

  • Hi Vidar, thank you for the answer. Sorry for reviving this, but only now do I have time to look into it again.

    I've considered what you said, but I want to be sure we won't run into any other issues because of this. So I have a couple of questions:

    1. Is there anything that cannot be done or won't work if done before the disconnect event? For our application, I don't think that considering the link disconnected before the actual event is a problem, there is not much logic around the disconnection, what concerns me is that the SoftDevice and SDK functions keep working in the same way... or if they don't, I'd like to know what we should do. 

    2. The only path where this change could impact our application is when reconfiguring the nRF from an external command. When this happens, the external uC commands the nRF to disconnect from all devices and stop advertising. Here, it would usually wait for the disconnection event before proceeding.

      If it were to keep executing, it would call the following functions, before the disconnect event, to re-start the communication. Is it a problem to call any of these functions before the disconnect event? Could this pending disconnection affect the re-initialization of the device or the establishment of new links after the device has re-initialized ?

      1. sd_ble_gap_device_name_set
      2. sd_ble_gap_appearance_set
      3. sd_ble_gap_ppcp_set
      4. nrf_ble_gatt_init
      5. nrf_ble_gatt_att_mtu_periph_set
      6. nrf_ble_gatt_data_length_set
      7. pm_sec_params_set
      8. ble_advertising_init
      9. ble_advertising_conn_cfg_tag_set
      10. sd_ble_gap_tx_power_set
      11. ble_conn_params_init
      12. ble_advertising_start

    Thanks again, any help is really appreciated.

  • No problem. Have you had a chance to test this now? The only potential problem that I can think of is that sd_ble_gap_adv_start() may return NRF_ERROR_CONN_COUNT if you start connectable advertising during pending disconnect. The solution to this can either be to wait for the disconnect event like before, or configure the application to support more connections.

Related