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

Client unable to receive notification after 0x3002 from SoftDevice

Hi,

I am having a problem where the client is unable to receive notification from a peripheral after the softdevice in the peripheral returns 0x3002 after a disconnect. The peripheral is running a modified "ble_app_uart" example with the following modifications/design specs

1. PCA10040

2. SDK_17.0.2

3. SoftDevice 7.2.0

4. Modified Nordic Uart Service: Data Length Extension, MTU SIZE = 247, Connection Length Interval Enabled, HW UART functionality removed, min connection interval = max connection interval = 15 (18.75ms)

5. 32-bit timer set to send a random 244 byte packet every 20ms using the "ble_nus_data_send()" as follows

do
{
    err_code = ble_nus_data_send(&m_nus, (uint8_t*)ble_queue[blerdptr], &nus_data_length, m_conn_handle);
} while (err_code == NRF_ERROR_RESOURCES);

if(err_code != NRF_SUCCESS)
{
    //err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0);
    //NRF_LOG_INFO("BLE_ERROR_GATTS_SYS_ATTR_MISSING_LOOP");

    NRF_LOG_INFO("ERROR_CODE IS %u", err_code);
};

6. Timer does not send packets until it receives a 'b' character from the client from its RX interface. Also, timer stops sending packets when peripheral receives a disconnection event.

7. Client is a modified "ble_app_uart_c" running on another PCA10040 to support the modifications from the peripheral or an Android App using modified NUS services.

The above setup works fine and we are able to transfer our 244 byte payload in the 20ms interval without any issues. The problem arises when there is a disconnection. For the most part, If we suddenly disconnect the client (kill Android App or disconnect usb cable of PCA10040 running "ble_app_uart_c") the SoftDevice returns 0x0005 and when we reconnect back to the peripheral everything is fine and we can continue streaming. In a few cases, SoftDevice returns 0x3002. In this particular case after reconnecting with the peripheral, we cannot receive any notification from the peripheral although the peripheral receives commands from the client. Also, the "ble_nus_data_send()" function returns "NRF_SUCCESS" and the "BLE_NUS_EVT_TX_RDY" event is also triggered. I tried enabling/disabling notifications using the nrfConnect App without success.

My questions are as follows:

1. How do I recover from an 0x3002 error such that when there is a reconnection and we can continue to stream data just like in the 0x0005 error case?

2. Is there a better way to send data from the peripheral such that data is not sent when there is a disconnect so as to avoid error 0x3002?

3. Is there a clean up that needs to be done when there is a disconnect from the client using NUS?

4. Is there a better way to use/modify NUS than what we have done?

Thanks You

Parents
  • Hi,

    I assume 0x3002 means BLE_ERROR_INVALID_CONN_HANDLE.

    That seem to indicate that m_conn_handle has changed between the two connections, which it may do. Can you make sure that m_conn_handle is updated/correct before calling ble_nus_data_send()?

    Typically you want to have a global flag of some sort, that make sure you don't call ble_nus_data_send() unless you are in a connection (with a valid m_conn_handle).

    Kenneth

  • Hi Kenneth,

    Thanks for the suggestion. In our current implementation, we do have a global flag that we use to make sure we have a valid connection. That test is right above the call to "ble_nus_data_send()" in the "do" loop but this is not shown in the code snippet above. 

    We still get the same behavior with or without the test for a valid connection. Most of the time, we are able to recover because the err_code is 0x0005. But in a few times, we get the 0x3002 err_code. Only when this happens that we have problems getting notifications after a reconnect and no errors are generated by the Softdevice.

  • I will try to do an on-air sniffer log as suggested. To clarify some more, we observed the same behavior when using our custom app, our modified "ble_app_uart_c" on a PCA10040, the nrfConnect App on a phone or desktop with PCA10040. Once the peripheral returns the 0x3002 error during our disconnection/re-connection testing, no notifications can be received from the peripheral using any type of central device. Any central device can still connect and send commands using the RX characteristic, but notifications associated with the TX characteristic cannot be received on the central device.

    From the snippet of code I sent above with our usage of the "ble_nus_data_send()" function, we trap error codes not equal to "NRF_SUCCESS". Also, we have an "NRG_LOG()" in our "nus_data_handler()" to log the "BLE_NUS_EVT_TX_RDY" events. The logs indicate that the "ble_nus_data_send()" function returns "NRF_SUCCESS" and triggers the "BLE_NUS_EVT_TX_RDY" event as well. I can even use the nrfConnect app to disable the notification of the TX characteristic in which case the "ble_nus_data_send()" function now returns an error.

    When the softdevice returns error 0x3002, is there some clean/re-initialization of a sub-system that needs to happen?

    I will report back with info on the use of the on-air sniffer.

  • aghogho obi said:

    When the softdevice returns error 0x3002, is there some clean/re-initialization of a sub-system that needs to happen?

    I will report back with info on the use of the on-air sniffer.

    There shouldn't be, so hopefully that on-air sniffer log will provide some more information.

    Kenneth

  • I was able to get some logs from the use of the nRF sniffer. I acquired logs before/after the occurrence of the 0x3002 error. The file before the error is

    no_err_code1_sniffer.pcapng

    while the logs after the error is

    err_code1_sniffer.pcapng

    Our use case involves advertising, connection and then initiating notification on the RX characteristic. I did notice that the logs after the error indicate that the RX characteristic is smaller in size when compared to a case with no 0x3002 error. Do let me know if the files reveal other information about the state of the BLE link after the 0x3002 error.

  • Thanks for the log, I will check internally and let you know.

    Some questions from the team:

    When you declared the characteristric, did you set variable attribute lenght?
    https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.s140.api.v7.2.0/structble__gatts__attr__md__t.html#a921e414734cd784e0c3b7309d3a14f39

    Our best guess that something happened with attribute database on disconnect so the attribute in question becomes zero length. Note that the length you provide in sd_ble_gatts_hvx is not necessary the length of value sent on air. For fixed size attribute length will be taken from attribute database. App can check ble_gatts_hvx_params_t::p_len on return from sd_ble_gatts_hvx to see how many bytes were actually written. For more info see p_hvx_params parameter description here https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.s140.api.v7.2.0%2Fstructble__gatts__hvx__params__t.html&anchor=a8b0b2dadb3128b0838c71235661f8174

    Kenneth

  • In addition to my previous reply, the team have a working theory:

    • the attribute is variable sized
    • on disconnect sd_ble_gatts_hvx returns error code and thus ble_gatts_hvx_params_t::p_len is set to 0 by SD
    • on the next iteration application does not update value of ble_gatts_hvx_params_t::p_len so attribute size is set to 0 in the attribute database

    Can you check if that is the case?
    Kenneth

Reply
  • In addition to my previous reply, the team have a working theory:

    • the attribute is variable sized
    • on disconnect sd_ble_gatts_hvx returns error code and thus ble_gatts_hvx_params_t::p_len is set to 0 by SD
    • on the next iteration application does not update value of ble_gatts_hvx_params_t::p_len so attribute size is set to 0 in the attribute database

    Can you check if that is the case?
    Kenneth

Children
Related