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

Why stack doesn't point to new value after sd_ble_gatts_rw_authorize_reply

Hi, I'm trying to implement GATTS Queued Writes: App handled, no attributes require authorization variant #2 VLOC_USER.

According to the documentation values in ATT table are set to the new values after the BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST{WRITE, EXEC_WRITE_REQ_NOW}.

Ok, but how? What does "Application traverses its queue and executes the write operations(memcpy)" mean?

I thought that call to the sd_ble_gatts_rw_authorize_reply() after BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST{WRITE, EXEC_WRITE_REQ_NOW} with

reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
reply.params.write.update = 1;
reply.params.write.len = length;
reply.params.write.p_data = &data;

would do the work and ATT table would point to the new value with new length. But that doesn't make sense because this function doesn't know which attribute value to modify (because it doesn't accept attribute handle in any way). Am I right?

Then what are these .update .len .p_data for?

Why should I in process of receiving data as a response to the BLE_GATTS_EVT_RW_AUTORIZE_EQUEST{WRITE, PREP_WRITE_REQ} call sd_ble_gatts_rw_authorize_reply() with .update = 1 and .len and .p_data could be ommited?

After investigation I've realized that only way I can point ATT table to the new value is by calling sd_ble_gatts_value_set() but that isn't right according to the documented Message sequence chart.

Update:

It seemed to work unless more data came.

For clarification i'm using std::vector vec to store received data and it is also the same vector used to create char with sd_ble_gatts_characteristic_add. Naturally when I receive more data vector grows and changes it's vec.data() pointer (memory where data is stored). I've used sd_ble_gatts_value_set() to let the stack know about new pointer to the memory with

ble_gatts_value_t value;
memset(&value, 0, sizeof(value));
value.len = vec.size();
value.p_value = vec.data();
sd_ble_gatts_value_set(connHandle, charHandle, &value);

This works for 32 bytes of written data (if I perform read after write from client I can see updated data). But when I write 42 bytes everything seems to be ok except that last two bytes are modified by stack! Before call to the sd_ble_gatts_value_set() content of vec is exactly as it should be filled with new 42 bytes (sent by client). But right after call to the sd_ble_gatts_value_set() last two bytes are modified!!

Why sd_ble_gatts_value_set() modifies the source of data?

Parents Reply Children
No Data
Related