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

NRF_ERROR_INVALID_STATE when calling ble_nus_data_send after connection is established

SDK version: nRF5_SDK_15.0.0_a53641a

Softdevice version: s132_nrf52_6.0.0_softdevice

PDK: PCA10040

  I am using the PCA10040 as a peripheral. When a connection is established with the central, I want to call ble_nus_data_send to send data to the central device.

I receive the following the following three ble events in the ble_evt_handler, once a connection is established:

BLE_GAP_EVT_CONNECTED (ble evt 10)
BLE_GAP_EVT_SEC_REQUEST (ble evt 24)
BLE_GATTC_EVT_EXCHANGE_MTU_RSP (ble evt 3a)

In the gatt_evt_handler I see the following event:

NRF_BLE_GATT_EVT_ATT_MTU_UPDATED

Once the NRF_BLE_GATT_EVT_ATT_MTU_UPDATED is received in the gatt_evt_handler, I find that I need to wait approx 2000ms before I can call ble_nus_data_send.

If I call ble_nus_data_send, for example 500ms after NRF_BLE_GATT_EVT_ATT_MTU_UPDATED, I get  NRF_ERROR_INVALID_STATE error response. If I wait for ~2000ms after NRF_BLE_GATT_EVT_ATT_MTU_UPDATED and then call  ble_nus_data_send I get a success response.

What could be the reason for this 2 second wait delay for the state change to occur after NRF_BLE_GATT_EVT_ATT_MTU_UPDATED? Is there any way to reduce this wait time? Also is there any way to know that the state change (any event indication) is complete instead of waiting a certain duration?

Parents
  • Hi,

    Looking at the implementation of ble_nus_data_send() you can see that it returns NRF_ERROR_INVALID_STATE if notification has not been enabled. Probably the peer device (GATT client) takes some time before enabling notification (for some reason), which then leads to this error. It would have been illegal to send a notification before it has been enabled by the client. Is this what is happening?

  • Hi,

       Thank you for your response,  delay in peer device (GATT client) enabling notification maybe the cause. But at present I am unsure how to validate if that is the cause. Is there any gatt event generated for me to know when notifications was enabled. Presently the Central device enables the notification immediately after the connection, but I dont see any event in the gatt event handler.

    I only see the following two events:

    NRF_BLE_GATT_EVT_DATA_LENGTH_UPDATED

    NRF_BLE_GATT_EVT_ATT_MTU_UPDATED

    Is there a way for me to know when enabling notifications was received?

  • Hey,

    The "nus_dat_handler" has an event "BLE_NUS_EVT_COMM_STARTED" which is generated when notifications is enabled. Perhaps you can check that?

  • Hi,

    The simplest way of knowing if notifications are enabled is by adding a bit of logging in the NUS implementation as shown in this diff of ble_nus.c (SDK 15.2 but it should be the same for 15.0):

    diff --git a/components/ble/ble_services/ble_nus/ble_nus.c b/components/ble/ble_services/ble_nus/ble_nus.c
    index 7567bbf..169fcb5 100644
    --- a/components/ble/ble_services/ble_nus/ble_nus.c
    +++ b/components/ble/ble_services/ble_nus/ble_nus.c
    @@ -100,6 +100,8 @@ static void on_connect(ble_nus_t * p_nus, ble_evt_t const * p_ble_evt)
             (p_nus->data_handler != NULL) &&
             ble_srv_is_notification_enabled(gatts_val.p_value))
         {
    +        NRF_LOG_INFO("Notification enabled at connection establishment (enabled in previous connection with bonded peer).");
    +
             if (p_client != NULL)
             {
                 p_client->is_notification_enabled = true;
    @@ -149,11 +151,13 @@ static void on_write(ble_nus_t * p_nus, ble_evt_t const * p_ble_evt)
             {
                 if (ble_srv_is_notification_enabled(p_evt_write->data))
                 {
    +                NRF_LOG_INFO("Notification enabled.");
                     p_client->is_notification_enabled = true;
                     evt.type                          = BLE_NUS_EVT_COMM_STARTED;
                 }
                 else
                 {
    +                NRF_LOG_INFO("Notification disabled.");
                     p_client->is_notification_enabled = false;
                     evt.type                          = BLE_NUS_EVT_COMM_STOPPED;
                 }
    

    You also have to set BLE_NUS_CONFIG_LOG_ENABLED to 1 in your projects sdk_config.h and make sure that logging is enabled.

    EDIT: 's suggestion was better and simpler, but I didn't see it before posting the above. I suggest you go for that Slight smile

  • Hi,

      Thank you for clarifying, this does resolve my issue and questions that I had. Please feel free to close the issue.

Reply Children
No Data
Related