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

How to give response after client writes to characteristic?

I am going to have streaming data come through a characteristic on an S110 device. When the client writes to the characteristic, my peripheral device will read the characteristic value into a buffer and then send the response/ack back to the client. This will tell the client to send a new characteristic. I cannot find how to send a write response. Is this something that happens automatically in the BLE stack? Is it possible to implement a device in this manner?

Thanks

  • I hope you know that there are quite a few layers in BLE, see this figure.

    In a connection, all packets will be acknowledged in the link layer.

    In the Generic Attribute Profile (GATT) you have several procedures for a characteristic value write. See Bluetooth Specification 4.1, Vol. 3, Part G, Section 4.9, for details.

    Write Without Response and Signed Write Without Response use the Attribute Protocol (ATT) Write Command, and are not acknowledged by the GATT server, they are simply commands.

    Write Characteristic Value uses ATT Write Request and the ATT Write Response. The GATT server acknowledges a write request with a write response.

    The GATT server can perform these procedures without the application knowing, or in terms of BLE, without the application authorizing the procedure. Authorization is a confirmation by the application to continue with the procedure. You want the application to authorize the write request. In the SDK we call this GATTS Write Request with Authorization, see this message sequence chart.

    Which procedures that need authorization must be set on the particular characteristic value or descriptor. Read and/or write authorization can be set. One can set the write authorization on the character value like this:

    attr_md.rd_auth    = 0;
    attr_md.wr_auth    = 1;
    

    Whenever a authorization is required the BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event is sent to the application. This is a common event for read and write, characteristic values and descriptors.

    Then one would typically check if it is a read or write procedure (p_ble_evt->evt.gatts_evt.params.authorize_request.type) and that the UUID is correct (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.context.char_uuid.uuid).

    One replies to the authorization request with sd_ble_gatts_rw_authorize_reply(...), with a ble_gatts_rw_authorize_reply_params_t as an argument. In it, one must set the authorization type (BLE_GATTS_AUTHORIZE_TYPE_WRITE) and the GATT status for the operation. To authorize a set the GATT status to (BLE_GATT_STATUS_SUCCESS), to not authorize set it to (BLE_GATT_STATUS_ATTERR_WRITE_NOT_PERMITTED).

    Please add a comment if anything is unclear, and I will try to modify my answer.

  • And then, what is the function to retrieve the Characteristic Value from the ATT Table (on the server side)? Using vloc = BLE_GATTS_VLOC_STACK. Thx!

  • The value is available in the authorize request struct when you get the BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event. Or you can get it with sd_ble_gatts_value_get().

  • is there any example code for BLEnano slave talking to BLEnano central, in the same context.

Related