This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Usage of Queued Read and Write

Hello everyone,

I am using the SDK 17.1 with the NRF52832 chip. My current project is created based on the multirole example. My first step was to implement writing and reading out the characteristic values of my custom service. Its working really good but I have a problem now. I worked with delays between the function call of e.g sd_ble_gattc_read() and the event response. With this method I was able to test the general functionality. But I cannot use this method in my real software because I get sometimes the error code "NRF_ERROR_BUSY". From my understanding I get this error because of a overload of the softdevice. Is there any possibility to fix this issue and get a stable and fast data exchange?

Currently I am trying to implement the Queued Read and Write. I try to implement it according to the BLE GATT QUEUE MSC and DIS Client. But I dont get the complete picture and the sequence. I am able to trigger the event but the data within the Event is wrong. My MTU is 247 and the character which I want to read has 500 Bytes. With the sd_ble_gattc_read() function I was able to work with offset and it worked really well. How can I read the complete character? It looks like with the Queue read method I am able to read without offset that means maximum MTU size?

I am a little bit confused and I hope you can support me to implement the writing and reading in the best way.

ret_code_t ble_hrs_c_read(ble_hrs_c_t * p_ble_hrs_c)
{
    ret_code_t       err_code;
    nrf_ble_gq_req_t hrs_c_req;

    VERIFY_PARAM_NOT_NULL(p_ble_hrs_c);

    memset(&hrs_c_req, 0, sizeof(hrs_c_req));
    hrs_c_req.type                     = NRF_BLE_GQ_REQ_GATTC_READ;
    hrs_c_req.error_handler.cb         = gatt_error_handler;
    hrs_c_req.error_handler.p_ctx      = p_ble_hrs_c;
    hrs_c_req.params.gattc_read.handle = p_ble_hrs_c->peer_hrs_db.hrm_handle;

    err_code = nrf_ble_gq_item_add(p_ble_hrs_c->p_gatt_queue, &hrs_c_req, p_ble_hrs_c->conn_handle);
    return err_code;
}

Best Regards

Hani

  • Hi Hani,

    If the read is longer than the max MTU size then you need to use the offset field and keep track of how much data you already read.The code you used is good for the first read but you need to extend this some thing like below in the event handler. Please note that i just wrote the code and have not compiled it, so use this as a logic and not as a solution in itself

    static uint32_t remaining_read_count = 500;
    
    static void current_time_read(ble_hrs_c_t * p_ble_hrs_c, ble_evt_t const * p_ble_evt)
    {
        ble_cts_c_evt_t evt;
        uint32_t        err_code = NRF_SUCCESS;
    
        // Check whether the event is on the same connection as this HRS instance
        if (p_ble_hrs_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle)
        {
            return;
        }
    	else
    	{
    		uint8_t len = p_ble_evt->evt.gattc_evt.params.read_rsp.len;
    		memcpy(&YOUR_DATA_STORAAGE[500-remaining_read_count], p_ble_evt->evt.gattc_evt.params.read_rsp.data, len);
    		remaining_read_count = remaining_read_count - len;
    		if(remaining_read_count)
    		{
    			// initiate another read with offset set to len
    			    nrf_ble_gq_req_t hrs_c_req;
    
    				VERIFY_PARAM_NOT_NULL(p_ble_hrs_c);
    
    				memset(&hrs_c_req, 0, sizeof(hrs_c_req));
    				hrs_c_req.type                     = NRF_BLE_GQ_REQ_GATTC_READ;
    				hrs_c_req.error_handler.cb         = gatt_error_handler;
    				hrs_c_req.error_handler.p_ctx      = p_ble_hrs_c;
    				hrs_c_req.params.gattc_read.handle = p_ble_hrs_c->peer_hrs_db.hrm_handle;
    				hrs_c_req.params.gattc_read.offset = len;  
    
    				err_code = nrf_ble_gq_item_add(p_ble_hrs_c->p_gatt_queue, &hrs_c_req, p_ble_hrs_c->conn_handle);
    				// Handle errors if any
    		}
    	}
    }
    
    void ble_hrs_c_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
    {
        ble_hrs_c_t * p_ble_hrs_c = (ble_hrs_c_t *)p_context;
        NRF_LOG_DEBUG("BLE event handler called with event 0x%x", p_ble_evt->header.evt_id);
    
        switch (p_ble_evt->header.evt_id)
        {
            case BLE_GATTC_EVT_READ_RSP:
                handle_read(p_ble_hrs_c, p_ble_evt);
                break;
    
            case BLE_GATTC_EVT_HVX:
                on_hvx(p_ble_hrs_c, p_ble_evt);
                break;
    
            case BLE_GAP_EVT_DISCONNECTED:
                on_disconnected(p_ble_hrs_c, p_ble_evt);
                break;
    
            default:
                break;
        }
    	
    }

Related