So I've got this long characteristic which takes several read operations with offsets to read it completely. Idea is to have it refreshed only after the client has read it.
Is there a mechanism for figuring this out?
EDIT - This is the way Ulrich suggested doing it:
void ble_pem_hum_data_on_ble_evt(pem_hum_data_t *pem_hum_data, ble_evt_t *p_ble_evt)
{
switch (p_ble_evt->header.evt_id)
{
...
case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
{
on_rw_auth_req(pem_hum_data, p_ble_evt);
} break;
...
}
}
static uint8_t data_buffer[ARRAY_SIZE_MAX] = {0};
static void on_rw_auth_req(my_service_t *my_service, ble_evt_t *p_ble_evt)
{
ble_gatts_evt_rw_authorize_request_t *p_evt_rw_auth_req = &p_ble_evt->evt.gatts_evt.params.authorize_request;
if (p_evt_rw_auth_req->type == BLE_GATTS_AUTHORIZE_TYPE_READ)
{
if (p_evt_rw_auth_req->request.read.handle == my_service->data_array_char_handles.value_handle)
{
uint16_t p_len;
sd_ble_gatts_value_get(p_evt_rw_auth_req->request.read.handle,
p_evt_rw_auth_req->request.read.offset,
&p_len, data_buffer);
ble_gatts_rw_authorize_reply_params_t p_rw_authorize_reply_params;
p_rw_authorize_reply_params.type = BLE_GATTS_AUTHORIZE_TYPE_READ;
p_rw_authorize_reply_params.params.read.gatt_status = BLE_GATT_STATUS_SUCCESS;
p_rw_authorize_reply_params.params.read.update = 1;
p_rw_authorize_reply_params.params.read.len = p_len;
p_rw_authorize_reply_params.params.read.p_data = (uint8_t *)&data_buffer[0];
p_rw_authorize_reply_params.params.read.offset = p_evt_rw_auth_req->request.read.offset;
sd_ble_gatts_rw_authorize_reply(my_service->conn_handle, &p_rw_authorize_reply_params);
}
}
}
It does seems to work, but there are two issues with it:
-
To respond to the read request with data, I can't just get a pointer from sd_ble_gatts_value_get() and pass it to sd_ble_gatts_rw_authorize_reply(), I have to get a complete copy in data_buffer and then pass that. Seems kinda wasteful. Is there a way around that?
-
I assumed that I'd have to manually manage the way data is transferred - given an offset by a client, pass that to sd_ble_gatts_value_get(), if length received in p_len is more than 20, truncate the data and send only the first 20 bytes, but it seems to work even when I pass the whole characteristic to sd_ble_gatts_rw_authorize_reply() at once - 126 bytes! Is there some mechanism which handles the data for me or am I completely misunderstanding this?