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

Getting data from BLE_GATTS_AUTHORIZE_TYPE_WRITE event

I am trying to use read/write authorisation on a characteristic in order to get/set a connection specific value of a characteristic

I am am having issues getting the new characteristic value from the BLE_GATTS_AUTHORIZE_TYPE_WRITE event

I write a value, for example 0x2FCD1000 using the NRF Connect app but when I read it, I receive a value with the top two bytes wrong, for example 0x2FCDD484

my function for handling a BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event is as follows

static void on_rw_auth_request(ble_my_data_t * p_my_data, ble_evt_t * p_ble_evt)
{
    ble_gatts_evt_rw_authorize_request_t  req = p_ble_evt->evt.gatts_evt.params.authorize_request;
    
    if(req.type == BLE_GATTS_AUTHORIZE_TYPE_READ && 
      ( req.request.read.handle == p_my_data->my_char_handles.value_handle))
    {
        ble_gatts_rw_authorize_reply_params_t auth_reply;
        auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ;
        auth_reply.params.read.gatt_status = BLE_GATT_STATUS_SUCCESS;
        auth_reply.params.read.update = 0;
        auth_reply.params.read.offset = 0;
        auth_reply.params.read.len = sizeof(p_my_data->my_char);
        auth_reply.params.read.p_data = (uint8_t*)&p_my_data->my_char;
        sd_ble_gatts_rw_authorize_reply(p_ble_evt->evt.gatts_evt.conn_handle, &auth_reply);
    }
    else if(req.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE && 
      ( req.request.write.handle == p_my_data->my_char_handles.value_handle))
    {
        TRACE("WRITE\r\n");
        TRACE("HANDL %d\r\n", req.request.write.handle);
        TRACE("OFFSET %d\r\n", req.request.write.offset);
        TRACE("LEN %d\r\n", req.request.write.len);
        
        ble_gatts_rw_authorize_reply_params_t auth_reply;
        memset(&auth_reply, 0, sizeof(auth_reply));
        auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
        auth_reply.params.write.update = 1;
        
        if(req.request.write.len == sizeof(p_my_data->my_char))
        {
            p_my_data->my_char = *(uint32_t *)req.request.write.data;
            TRACE("DATA 0x%x\r\n", p_my_data->my_char);
            auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
            auth_reply.params.write.offset = req.request.write.offset;
            auth_reply.params.write.len = req.request.write.len;
            auth_reply.params.write.p_data = req.request.write.data;
        }
        else 
        {
           auth_reply.params.write.gatt_status = BLE_GATT_STATUS_ATTERR_INVALID_ATT_VAL_LENGTH;
        }
        uint32_t err_code = sd_ble_gatts_rw_authorize_reply(p_ble_evt->evt.gatts_evt.conn_handle, &auth_reply);
        TRACE("ERR %d\r\n", err_code);
        ble_gatts_value_t p_value;
        uint32_t d;
        p_value.len = 4;
        p_value.offset = 0;
        p_value.p_value = (uint8_t*)&d;
        err_code = sd_ble_gatts_value_get(p_ble_evt->evt.gatts_evt.conn_handle, req.request.write.handle, &p_value);
        TRACE("ERR %d\r\n", err_code);
        TRACE("GET 0x%x\r\n", d);
    }
}

The trace is as follows

  • WRITE
  • HANDL 19
  • OFFSET 0
  • LEN 4
  • DATA 0x84D4CD2F
  • ERR 0
  • ERR 0
  • GET 0x84D4CD2F

what am I doing wrong? The characteristic is set up to have a length of 4 bytes and it works perfectly when I don't enable read/write authorisation

I'm using an NRF52 S332 and SDK13.0

  • p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.data is a variable length array.

    ble_gatts_evt_rw_authorize_request_t req = p_ble_evt->evt.gatts_evt.params.authorize_request; is only going to assign sizeof(ble_gatts_evt_rw_authorize_request_t) bytes but since data is defined as only 1 byte long, this isn't going to copy everything.

    had I used ble_gatts_evt_rw_authorize_request_t * req = &p_ble_evt->evt.gatts_evt.params.authorize_request; instead, everything would have worked as I had a pointer to req.request.write.data, not an incomplete copy

Related