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

When can sd_ble_gattc_primary_services_discover be called? NRF_ERROR_BUSY

Hi,

I've had a product that's been out there for years. In it, we call `sd_ble_gattc_primary_services_discover` a few milliseconds after we've received `BLE_GAP_EVT_CONNECTED`. That has been working great.

However, recently we increased the MTU from the default to 53 bytes.

Now, if I call `sd_ble_gattc_primary_services_discover` at exactly the same point, I receive an NRF_ERROR_BUSY error. Instead, I have to delay it for ~500ms before it works.

Looking at what events are received, I see:

BLE_GAP_EVT_ADV_REPORT
BLE_GAP_EVT_CONNECTED
sd_ble_gattc_primary_services_discover here fails with error
BLE_GATTC_EVT_EXCHANGE_MTU_RSP
BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST
BLE_EVT_DATA_LENGTH_CHANGED

// or this works
BLE_GAP_EVT_ADV_REPORT
BLE_GAP_EVT_CONNECTED
BLE_GATTC_EVT_EXCHANGE_MTU_RSP
BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST
BLE_EVT_DATA_LENGTH_CHANGED
sd_ble_gattc_primary_services_discover works here

// but on an older firmware with the normal 23 byte MTU

BLE_GAP_EVT_ADV_REPORT
BLE_GAP_EVT_CONNECTED
BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST
sd_ble_gattc_primary_services_discover works here



So my question is, how do I know when the connection is actually ready to use (eg when sd_ble_gattc_primary_services_discover can be called)? I've seen a few other posts asking about this and the solution suggested is to delay calling it by 3s, but I feel like that's not a desperately robust solution, and it also adds an extra 3 whole second delay to the connection procedure.

Background: This is for Espruino, a JS interpreter. When connected we call the user's code (where they can do what they want, including requesting services). If we get BLE_GAP_EVT_CONNECTED but the connection isn't actually ready to use, I could really do with delaying the callback so the user only gets the 'connected' event at the point that things are ready to go.

Thanks!

Parents
  • Hi Gordon, 
    I would suggest to use a sniffer trace and check what occurred right after the connect request. 

    I think you can wait until you receive BLE_EVT_DATA_LENGTH_CHANGED event before you start doing service discovery. But you should also use a timer to make sure service discovery is executed. Just in case if initially the Data length already matched with your setting so the event BLE_EVT_DATA_LENGTH_CHANGED may not even come. 

  • Ok, thanks! Although this doesn't seem like a very robust solution? I guess the softdevice must know that it is busy since it can report NRF_ERROR_BUSY right away. Is there any way of querying the softdevice?

    My thinking at the moment is *if* sd_ble_gattc_primary_services_discover fails with an error, I maybe just delay for a second and try again. It just seems like a bit of a hack.

  • Hi Gordon, 
    Yes when you receive a NRF_ERROR_BUSY you can retry after a period of time and can do that multiple times. Most of the configuration activity would be performed at the very few first seconds of the connection. So if you wait for a few second it should be ready. 

    The way to query if the softdevice is busy or not, is actually just to send the sd_ble_gattc_primary_services_discover (). We don't have a dedicated function to check if the softdevice is busy or not. 

Reply
  • Hi Gordon, 
    Yes when you receive a NRF_ERROR_BUSY you can retry after a period of time and can do that multiple times. Most of the configuration activity would be performed at the very few first seconds of the connection. So if you wait for a few second it should be ready. 

    The way to query if the softdevice is busy or not, is actually just to send the sd_ble_gattc_primary_services_discover (). We don't have a dedicated function to check if the softdevice is busy or not. 

Children
Related