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.

Reply
  • 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.

Children
Related