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

delayed disconnect with sd_ble_gap_disconnect()?

Hello,

Are there any conditions where the sd_ble_gap_disconnect() will not immediately terminate the link?

My Setup: Nrf52, SDK 13.0.0, own board, based from HRM code(exteeeensive modification).

On initial bootup, I fast advertise. Once I get a connection to the central, I utilize the CTS to get time, pull a few packets of data onto the peripheral, shut down the connection and stop advertising.

a few minutes later via external interrupt, I start advertising( do I need to reinitialize the advertising code again??) connect to the central and pull in time to the peripheral using the CTS. This time, when I call the sd_ble_gap_disconnect, the m_conn_handle keeps it value of 0x0 instead of doing the expected disconnect value of 0xFFFF. I monitor m_conn_handle with a WHILE loop, so when it doesn't change to the expected 0xFFFF, I camp there and softdevice faults me to a halt.

So, the first time around, it works like a charm. The second time through, it doesn't look like it releases the link. What would cause the sd_ble_gap_disconnect() function to hold onto the link?

Thanks for looking!

  • Hi Hung, Sorry, I thought that I answered that question from Martin. Anyhow, Yes, It does hit the BLE_GAP_EVT_DISCONNECTED within on_ble_evt() the second time. As to how 'immediate' it is, that is difficult for me to quantify due to not being able to step through the code whilst Softdevice is active ( as you know). It SEEMS close to immediate, because it happens within 1 second of obtaining time from the server. The disconnect is programmatically planned, so other than setting GPIOs to determine actual timing, I cannot guarantee the timing immediacy. However it does happen soon after the command to disconnect from the central.

    I was counting on the m_conn_handle to be reset to 0xFFFF the second time, but after I get out of the switch statement containing the BLE_GAP_EVT_DISCONNECTED code, my m_conn_handle still is 0x0;

  • I don't really understand it.

    Could you verify that you have the code m_conn_handle = BLE_CONN_HANDLE_INVALID; inside BLE_GAP_EVT_DISCONNECTED event handler inside ble_evt_handler() ?

    After that command the m_conn_handle should be 0xFFFF. Are you saying the line of code doesn't have any effect on m_conn_handle?

    If it's not, then it must be assigned somewhere else, most likely because the central tried to connect again ?

    It's pretty easy to find how long it would take to get BLE_GAP_EVT_DISCONNECTED event, simply print out some text on UART/RTT when you receive the event, I suggest to also do the same with BLE_GAP_EVT_CONNECTED

  • HI Hung,

    Yes, I have the line m_conn_handle = BLE_CONN_HANDLE_INVALID; inside BLE_GAP_EVT_DISCONNECTED event handler inside on_ble_evt().  (I don't have a function explicitly named ble_evt_handler().) 

    so if I call sd_ble_gap_disconnect() then immediately printout the value of m_conn_handle, I see that it has a value ( of 0, verifying its not 0xFFFF).

    Putting in a few more checks, I see I hit the BLE_GAP_EVT_DISCONNECTED in about 4 seconds. The disconnect reason is a 34 (0x22). I check the value of m_conn_handle after that, and its the expected value of 0xFFFF.

    Could there possibly be some sort of negotiation going on between the peripheral and central? Maybe I am not sending some expected parameters OR maybe I am missing some sort of disconnect data from the central?

    Is there some way to see if the softdevice is waiting on some response from the central or maybe there is a timer somewhere that needs handling?

    Thanks!

  • Hi Ben,

     

    Great to get back after 8 months :) 

    I think I know what's wrong here. What kind of central device do you have ? 

    Disconnect event 0x22 means BLE_HCI_STATUS_CODE_LMP_RESPONSE_TIMEOUT. This happens when the central stopped communication for too long end the connection terminated because of the timeout. So when the peripheral send connection terminate request ( because of sd_ble_gap_disconnect() ) it would expect an ACK from the central before it actually stop the connection and throw BLE_GAP_EVT_DISCONNECTED event back to the application. 

    But in this case, it seemed that the central stopped immediately after it receive the connection terminate request. It forgot to send the last ACK packet back to the peripheral. This results in the peripheral kept waiting for that ACK until timeout. 

    (Or it could be that the last ACK was lost and the peripheral never receive it, and there is no retransmission, of course)

     

Related