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

Connection timeout at central

Hi,

I'm using the example "ble_central/ble_app_uart_c" of nRF5_SDK_17.0.2. Connection to peripheral workes fine.

If the central re-starts while a connection is established, the peripheral get a "disconnect" event and wait for a new connection.

If the peripheral re-starts while a connection is established, the central get no "disconnect" event and runs into fatal error.

So, how to set up central, to handle a "disconnect" by timeout?

Thanks for helping!

Parents
  • Hello,

    I'm using the example "ble_central/ble_app_uart_c" of nRF5_SDK_17.0.2.

    Have you made any changes to the central example? If so, what changes have you made?

    the central get no "disconnect" event and runs into fatal error.

    That sounds strange - the central should resume scanning for a peripheral device when a link is broken.
    Could you make sure to have DEBUG defined in your preprocessor defines, like shown in the included image?

    This will make a detailed error message be outputted to your logger whenever a non-NRF_SUCCESS error code is passed to an APP_ERROR_CHECK. Please do this, and let me know what this error message says when the device resets.

    Looking forward to resolving this issue together!

    Best regards,
    Karl

  • Hello Karl,

    thank you for your soon response. First the error message:

    <info> app_timer: RTC: initialized.
    <info> app: BLE UART central example started.
    <info> app: Connecting to target 340D3750ACE0
    <info> app: ATT MTU exchange completed.
    <info> app: Ble NUS max data length set to 0xF4(244)
    <info> app: Discovery complete.
    <info> app: Connected to device with Nordic UART Service.
    <error> nrf_ble_gq: SD GATT procedure (1) failed on connection handle 0 with error: 0x00000013.
    <error> app: ERROR 19 [NRF_ERROR_RESOURCES] at C:\Projekte\MyCompany\0288_TT_BLE_Modul\nRF5_SDK_17.0.2_d674dde\examples\ble_central\ble_app_uart_c\main.c:123
    PC at: 0x0002F57D
    <error> app: End of error report

    I have made some "small" changes in main.c:

    • set ECHOBACK_BLE_UART_DATA to 0
    • in void uart_event_handle(app_uart_evt_t * p_event):
      Check connection state befor sending data
          if (m_ble_nus_c.conn_handle != BLE_CONN_HANDLE_INVALID)
          {
              switch (p_event->evt_type)
              {
                  case APP_UART_DATA_READY:
                      ...
              }
          }

    Here is some background information:

    The BLE module is connected to our µC (STM32) via UART. This STM32 sends a heartbeat every 250ms via uart -> BLE to the peripheral - indipending of a BLE connection state. If there is no connection established, the central runs into a fatal error. Therefore we have checked the connection handle before sending the data via BLE.

Reply
  • Hello Karl,

    thank you for your soon response. First the error message:

    <info> app_timer: RTC: initialized.
    <info> app: BLE UART central example started.
    <info> app: Connecting to target 340D3750ACE0
    <info> app: ATT MTU exchange completed.
    <info> app: Ble NUS max data length set to 0xF4(244)
    <info> app: Discovery complete.
    <info> app: Connected to device with Nordic UART Service.
    <error> nrf_ble_gq: SD GATT procedure (1) failed on connection handle 0 with error: 0x00000013.
    <error> app: ERROR 19 [NRF_ERROR_RESOURCES] at C:\Projekte\MyCompany\0288_TT_BLE_Modul\nRF5_SDK_17.0.2_d674dde\examples\ble_central\ble_app_uart_c\main.c:123
    PC at: 0x0002F57D
    <error> app: End of error report

    I have made some "small" changes in main.c:

    • set ECHOBACK_BLE_UART_DATA to 0
    • in void uart_event_handle(app_uart_evt_t * p_event):
      Check connection state befor sending data
          if (m_ble_nus_c.conn_handle != BLE_CONN_HANDLE_INVALID)
          {
              switch (p_event->evt_type)
              {
                  case APP_UART_DATA_READY:
                      ...
              }
          }

    Here is some background information:

    The BLE module is connected to our µC (STM32) via UART. This STM32 sends a heartbeat every 250ms via uart -> BLE to the peripheral - indipending of a BLE connection state. If there is no connection established, the central runs into a fatal error. Therefore we have checked the connection handle before sending the data via BLE.

Children
  • Hello,

    Andi_Frueh said:
    thank you for your soon response.

    No problem at all, I am happy to help!

    Andi_Frueh said:
    Here is some background information:

    Thank you for the elaboration, this is helpful for me to know.

    <error> app: ERROR 19 [NRF_ERROR_RESOURCES] at C:\Projekte\MyCompany\0288_TT_BLE_Modul\nRF5_SDK_17.0.2_d674dde\examples\ble_central\ble_app_uart_c\main.c:123
    PC at: 0x0002F57D
    <error> app: End of error report

    Which function returned the error code passed to the APP_ERROR_CHECK on line 123 of main.c?

    Best regards,
    Karl

  • The function which passed this error is

    static void nus_error_handler(uint32_t nrf_error)
    {
        APP_ERROR_HANDLER(nrf_error);
    }

    In the call stack I see, that function "ble_nus_c_string_send" was called prior, which is called by the funtion "uart_event_handle(app_uart_evt_t * p_event)". So, the reason for the error seem to be clear: the BLE stack knows, that the connection has broken. Unfortunatelly there is no BLE_GAP_EVT_DISCONNECTED event to invalidate the connection handle!

    void uart_event_handle(app_uart_evt_t * p_event)
    {
        static uint8_t data_array[BLE_NUS_MAX_DATA_LEN];
        static uint16_t index = 0;
        uint32_t ret_val;
    
        
        if (m_ble_nus_c.conn_handle != BLE_CONN_HANDLE_INVALID)
        {
            switch (p_event->evt_type)
            {
                /**@snippet [Handling data from UART] */
                case APP_UART_DATA_READY:
                    UNUSED_VARIABLE(app_uart_get(&data_array[index]));
                    index++;
        
                    if ((data_array[index - 1] == '\n') ||
                        (data_array[index - 1] == '\r') ||
                        (index >= (m_ble_nus_max_data_len)))
                    {
                        NRF_LOG_DEBUG("Ready to send data over BLE NUS");
                        NRF_LOG_HEXDUMP_DEBUG(data_array, index);
        
                        data_array[index - 1] = '\r';
        
                        do
                        {
    /*******************/
                            ret_val = ble_nus_c_string_send(&m_ble_nus_c, data_array, index);
    /*******************/
                            if ( (ret_val != NRF_ERROR_INVALID_STATE) && (ret_val != NRF_ERROR_RESOURCES) )
                            {
                                APP_ERROR_CHECK(ret_val);
                            }
                        } while (ret_val == NRF_ERROR_RESOURCES);
        
                        index = 0;
                    }
                    break;
        
                /**@snippet [Handling data from UART] */
                case APP_UART_COMMUNICATION_ERROR:
                    NRF_LOG_ERROR("Communication error occurred while handling UART.");
                    APP_ERROR_HANDLER(p_event->data.error_communication);
                    break;
        
                case APP_UART_FIFO_ERROR:
                    NRF_LOG_ERROR("Error occurred in FIFO module used by UART.");
                    APP_ERROR_HANDLER(p_event->data.error_code);
                    break;
        
                default:
                    break;
            }
        }
    }

  • Hello,

    Andi_Frueh said:
    So, the reason for the error seem to be clear: the BLE stack knows, that the connection has broken. Unfortunatelly there is no BLE_GAP_EVT_DISCONNECTED event to invalidate the connection handle!

    No, I do not think that this is the right conclusion.
    In the case you describe - trying to call ble_nus_data_send when not in a connection - you would be getting an NRF_ERROR_INVALID_STATE error. In your error log you are getting NRF_ERROR_RESOURCES, which I think stems from too many notifications being queued for sending. The explanation of the error code from the function's API reads:

    NRF_ERROR_RESOURCES Too many notifications queued. Wait for a BLE_GATTS_EVT_HVN_TX_COMPLETE event and retry.

    To fix this you could for example increase your hvn queue size and connection event length to send multiple notifications each connection event.
    How many notifications are you attempting to queue per connection event?

    Best regards,
    Karl

  • Hi Karl,

    we had different problems.

    One of them was that our controller sends data cyclically - regardless of whether there is a BLE connection or not. When we debug the BLE module, the situation arises that the BLE stack is not yet fully set up while the STM32 is already trying to send data via UART. This leads to an APP_ERROR_HANDLER.

    The disconnect event is generally recognized. However, an APP_ERROR_HANDLER was previously executed. We have to intercept this troubleshooting in a different way than has been done up to now. When we do this, it works to disconnect and reconnect the two devices.

    It may be that our queue is too small, but we currently cannot simply increase it.

    Many thanks for your support!

    Regards,

    Andi

  • Hello again Andi,

    Andi_Frueh said:
    the BLE stack is not yet fully set up while the STM32 is already trying to send data via UART. This leads to an APP_ERROR_HANDLER.

    The initialization and enabling of the BLE stack does not take very long, and the nRF52833 can still receive over UART regardless of the BLE stack status. Which error is generated, and from which function, when the STM32 sends data too soon?

    Andi_Frueh said:
    The disconnect event is generally recognized. However, an APP_ERROR_HANDLER was previously executed. We have to intercept this troubleshooting in a different way than has been done up to now. When we do this, it works to disconnect and reconnect the two devices.

    I am sorry, but I do not understand what you mean to say here fully. Are you saying that you do not see the DISCONNECTED event when a APP_ERROR_HANDLER execution has just finished? Have you implemented specific error handling in the APP_ERROR_HANDLER, or are you using the default which is to reset the device?
    Please elaborate on what you mean with this paragraph so I may better advice you on how to resolve the issue. 

    Andi_Frueh said:
    It may be that our queue is too small, but we currently cannot simply increase it.

    I do not understand what you mean by this. Why can you simply not increase the queue, if this is what is causing your NRF_ERROR_RESOURCES?
    The only alternative to increasing the queue to avoid the NRF_ERROR_RESOURCES would be to queue notifications less frequently. For example, only after receiving a BLE_GATTS_EVT_HVN_TX_COMPLETE event.

    Best regards,
    Karl

Related