SD GATT procedure failed on Central device.

Hi All,

         I am using NRF52840 in my project and working on SDK 17.0.2. I have one central device and 2 Peripherals. The peripherals are connected to the central properly after power ON. Now let's say I Power OFF the central device for sometime. The peripherals are still kept ON and they keep advertising continuously. Let's say after after sometime I powered ON the central device, it should be able to connect to both the peripherals. What I am observing is sometimes it goes for connection but it gets "SD GATT procedure failed on Central device." and disconnects from that peripheral. The log I observed on central device is as follows:-

00> <error> nrf_ble_gq: SD GATT procedure (2) failed on connection handle 1 with error: 0x0000000D.
00>
00> <info> app: BLE_GATTC_EVT_TIMEOUT
00>
00> <info> app: CENTRAL: Disconnected, handle: 1, reason: 0x16

Also when a peripheral is disconnected it gets hanged and I have to reboot it to connect again.

Is this central device firmware issue or the peripheral device firmware issue? How to solve this issue?

Thanks & Regards,

Snehal Bundele.

Parents
  • Hi Snehal,

    How are you setting up the GATT Writes on your central?

    Does this error happen a while after the connection is established, or during connection establishment?

    00> <error> nrf_ble_gq: SD GATT procedure (2) failed on connection handle 1 with error: 0x0000000D.

    This line says that a GATT Write procedure timed out. Do you have any idea what write procedure is happening here?

    Could it be that you initiate the write too early/before the connection is fully established, such as along with the function to connect?

    Hieu

  • Hi Hieu,

               This error happens during connection establishment. My Gatt initialization is as follows:-

    void gatt_evt_handler(nrf_ble_gatt_t * p_gatt, nrf_ble_gatt_evt_t const * p_evt)
    {
        if ((m_conn_handle == p_evt->conn_handle) && (p_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED))
        {        
            sys_set_peripheral_mtu(p_evt->params.att_mtu_effective - OPCODE_LENGTH - HANDLE_LENGTH);
    
            NRF_LOG_INFO("Data len is set to 0x%X(%d)", sys_get_peripheral_mtu(), sys_get_peripheral_mtu());
            NRF_LOG_PROCESS();
        }
        NRF_LOG_INFO("ATT MTU exchange completed. central 0x%x peripheral 0x%x",
                      p_gatt->att_mtu_desired_central,
                      p_gatt->att_mtu_desired_periph);
        NRF_LOG_PROCESS();
    }
    
    
    
    /**@brief Function for initializing the GATT module. */
    static void gatt_init(void)
    {
        ret_code_t err_code = nrf_ble_gatt_init(&m_gatt, gatt_evt_handler);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_ble_gatt_att_mtu_central_set(&m_gatt, NRF_SDH_BLE_GATT_MAX_MTU_SIZE);
        APP_ERROR_CHECK(err_code);
    }
    

    After successful connection the sensors send the device status to the central.

    Could it be that you initiate the write too early/before the connection is fully established, such as along with the function to connect?

    >> But then why does one sensor connect and the other fails?? If writes are performed too early then the central should get disconnected for both I guess.

    Also I have a scan filter in central firmware. It scans from the stored list of names to get connected to the devices nearby. 

    Thanks & Regards,

    Snehal

  • That is not easy to answer without knowing why the other peripheral does not connect. Do you have any error code when the central sends a connect request or is it just a connect request timed out?

    Are you sending the connect request from the central on receiving the adv packet or is there different logic on how you send the connect request?

  • Hi Susheel,

    Actually I have identified the issue. I have set scan name filter in my central firmware. Name filter includes 2 peripheral devices. Now the problem is when the scanning starts, the central device scans both and tries to connect to both of them at a time. During this process some packets of one of the peripheral device  are lost and it doesn't complete full cycle of connection due to this only pne peripheral is connected properly. In the central logs it shows me that both peripherals initiated connection but no packets are received from the peripheral 2. I can see only peripheral 1 packets. 

    Can we handle this? Can we set some interval somewhere so that connection to peripherals happen one by one?

    Thanks & Regards,

    Snehal

  • sne_333 said:
    Can we handle this? Can we set some interval somewhere so that connection to peripherals happen one by one?

    When two devices are connected then the connection events will be multiplexed over time. Also it should not be possible to lose packets in a connection in BLE. So the main question here is that if the central 2 is transmitting the data in the connection2 and the peripheral2 is not able to process it or if the central2 is not able to transmit data at all?

    You need to see the sniffer log to get the answer to the above questions.

    If the central2 is transmitting data, then there is some issue with the context in which peripheral2 is processing data. Maybe there is a deadlock or peripheral1 data processing is startving peripheral2 data processing? 

  • Hi Susheel,

                Unfortunately I won't be able to capture sniffer logs for some reason. I also feel that there is some issue with function "nrf_ble_scan_connect_with_target".

    static void nrf_ble_scan_connect_with_target(nrf_ble_scan_t           const * const p_scan_ctx,
                                                 ble_gap_evt_adv_report_t const * const p_adv_report)
    {
        ret_code_t err_code;
        scan_evt_t scan_evt;
    
        // For readability.
        ble_gap_addr_t const        * p_addr        = &p_adv_report->peer_addr;
        ble_gap_scan_params_t const * p_scan_params = &p_scan_ctx->scan_params;
        ble_gap_conn_params_t const * p_conn_params = &p_scan_ctx->conn_params;
        uint8_t                       con_cfg_tag   = p_scan_ctx->conn_cfg_tag;
    
        // Return if the automatic connection is disabled.
        if (!p_scan_ctx->connect_if_match)
        {
            return;
        }
    
        // Stop scanning.
        nrf_ble_scan_stop(); 
    
        memset(&scan_evt, 0, sizeof(scan_evt));
    
        // Establish connection.
        err_code = sd_ble_gap_connect(p_addr,
                                      p_scan_params,
                                      p_conn_params,
                                      con_cfg_tag);
    
        NRF_LOG_INFO("Connecting");
    
        scan_evt.scan_evt_id                    = NRF_BLE_SCAN_EVT_CONNECTING_ERROR;
        scan_evt.params.connecting_err.err_code = err_code;
    
        NRF_LOG_INFO("Connection status: %d", err_code);
    
        // If an error occurred, send an event to the event handler.
        if ((err_code != NRF_SUCCESS) && (p_scan_ctx->evt_handler != NULL))
        {
            p_scan_ctx->evt_handler(&scan_evt);
        }
    
    }
    

    Here in this function nrf_ble_scan_stop() is called. My doubt is when peripheral-1 is detected, the central goes into this function and nrf_ble_scan_stop() is called and it connects to peripheral-1. Now as nrf_ble_scan_stop is called the central device does not look for the peripheral-2 and does not connect to it. Am I right?

    Thanks & Regards,

    Snehal

  • Hi , Can you please reply? Is there any way to implement reconnect mechanism?

Reply Children
Related