Disable sd_ble_gatts_rw_authorize_reply ATT table cache

FormerMember
FormerMember

I'm using a relatively large GATT db that has rd_auth and wr_auth set to true for every characteristic. This prevents the stack from automatically replying with cached values, therefore ensuring that the app can handle the read and write events by itself.

I'm a bit confused when I check the message sequence charts.

It seems that the value passed to sd_ble_gatts_rw_authorize_reply is copied to an intermediate ATT table cache before being sent to the central.

I assume that this makes use of the buffers given in sd_ble_gatts_characteristic_add.

Since I want to handle all reads and writes dynamically in the app, I would like to opt out of this buffering behaviour because it eats way too much memory if the maximum size for each characteristic needs to be allocated in advance.

  • What is the proper way to call sd_ble_gatts_characteristic_add without specifying a buffer, and handle all requests on-demand?

  • If there is none: Is it possible to specify the same buffer to all characteristics? Since BLE only allows one read / write at a time, I don't see a way how the buffer may become corrupted between calling sd_ble_gatts_rw_authorize_reply ant the data being effectively sent to the central.

Parents
  • Hi Ethan,

    I have not tried this solution, but what you could try is to use

    attr_md.vloc = 1;
    

    and pass the same pointer (p_data) to the data for all characteristics.

    When you receive the BLE_GATTS_RW_AUTHORIZE_EVENT

    ble_gatts_read_authorize_params_t rw_authorize_reply_params;
    memcpy(p_data+offset, p_replydata, length);
    rw_authorize_reply_params.params.read.gatt_status = BLE_GATT_STATUS_SUCCESS;
    rw_authorize_reply_params.params.read.update = 0;
    rw_authorize_reply_params.params.read.len = length;
    rw_authorize_reply_params.params.read.offset = offset;
    rw_authorize_reply_params.params.read.p_data= NULL;
    rw_authorize_reply_params.type = BLE_GATTS_AUTHORIZE_TYPE_READ;
    sd_ble_gatts_rw_authorize_reply(conn_handle, &rw_authorize_reply_params)
    

    This reduce the number of memcpy done at least.

Reply
  • Hi Ethan,

    I have not tried this solution, but what you could try is to use

    attr_md.vloc = 1;
    

    and pass the same pointer (p_data) to the data for all characteristics.

    When you receive the BLE_GATTS_RW_AUTHORIZE_EVENT

    ble_gatts_read_authorize_params_t rw_authorize_reply_params;
    memcpy(p_data+offset, p_replydata, length);
    rw_authorize_reply_params.params.read.gatt_status = BLE_GATT_STATUS_SUCCESS;
    rw_authorize_reply_params.params.read.update = 0;
    rw_authorize_reply_params.params.read.len = length;
    rw_authorize_reply_params.params.read.offset = offset;
    rw_authorize_reply_params.params.read.p_data= NULL;
    rw_authorize_reply_params.type = BLE_GATTS_AUTHORIZE_TYPE_READ;
    sd_ble_gatts_rw_authorize_reply(conn_handle, &rw_authorize_reply_params)
    

    This reduce the number of memcpy done at least.

Children
Related