Summary
In my article entitled “PSoC4 BLE Central Custom Profile w/LED & CapSense” a reader named Doug posted a question which asked about BLE Writes and the events that are created in PSoC 4 BLE. This article attempts to answer those questions. The bottom line is that the BLE Spec specifies four ways for a GATT Client to write to a GATT Server. Each of those write types either have a response or not. Inside of the PSoC BLE Stack each of them generate a different event.
Here is a summary of the BLE Write Events from my WICED BLE textbook chapter 4D.4
[EDIT: The above table is incorrect. 3.4.5.1 is ATT_WRITE_REQ which requires a 3.4.5.2 an ATT_WRITE_RSP. And 3.4.5.3 is ATT_WRITE_CMD which requires no response.]
Inside of the PSoC Stack it will generate the following events:
Request | Event | PSoC 4 Response API |
---|---|---|
Write Request | CYBLE_EVT_GATTS_WRITE_REQ | CyBle_GattsWriteRsp or CyBle_GattsErrorRsp |
Write Command | CYBLE_EVT_GATTS_WRITE_CMD_REQ | No Response |
Signed Write | CYBLE_EVT_GATTS_DATA_SIGNED_CMD_REQ | CyBle_GattsWriteRsp or CyBle_GattsErrorRsp |
Prepare Write | CYBLE_EVT_GATTS_PREP_WRITE_REQ | Out of scope for today |
Execute Write | CYBLE_EVT_GATTS_EXEC_WRITE_REQ | Out of scope for today |
Question(s)
Here are the original question(s):
Hi, I am having some problems understanding “write without response” setup.
In the “capsenseled” server project “CYBLE_EVT_GATTS_WRITE_REQ” is used instead of “CYBLE_EVT_GATTS_WRITE_CMD_REQ” in the event handler, but “write without response” is selected in the component setup.
According to this other project I am looking at ( https://www.digikey.com/eewiki/pages/viewpage.action?pageId=55574662 ) both are used with comments as follows
case CYBLE_EVT_GATTS_WRITE_REQ: //Write with response
case CYBLE_EVT_GATTS_WRITE_CMD_REQ: //Write without response
Why is “CYBLE_EVT_GATTS_WRITE_CMD_REQ” NOT used in the capsenseled project, and does “CYBLE_EVT_GATTS_WRITE_REQ” still function in a write without response setup?
Am I misunderstanding the definition of a response?
Is the “response” referring to an event that occurs within the server device, or is a response defined as a reply from the client device?
I am trying to set up a low power single button remote to report the state of the button, to be handled by the client which is connected to a larger power source and will possibly count edges, measure button press duration, or both, etc. Ideally the remote would be asleep except for when it needs to tell the client that the button has changed states, and would not spend any energy processing a response from the client.
BLE Spec
When you declare a Characteristic, you have a 1-byte bit field to specify the Characteristic Properties, that tells the GATT Client how it can write to the Characteristic. Here is a screenshot from section 3.3.1 of the Bluetooth core spec:
And the legal values for the Characteristic Properties are in section 3.3.1.1
This table says that it is perfectly legal to perform a “Write without response” (which is really called “Write Command” in section 3.4.5.3) or a “Write” (which is really called “Write Request” in section 3.4.5.1) as long as you send a legal response (or none). If you look at the project which is referenced in the Digikey article, you can see that the author did just that for the Characteristic “Number_Write”.
Write Command a.k.a. Write Without Response”
As I looked around at the spec for this article I discovered something which I did not previously know. Specifically, a Write Command must fit in one packet… which means that the data written to the Characteristic must be no more than the ATT MTU – 3. Here is the spec:
Write Request
A Write Request is a two sided request, meaning the GATT Server must either send a “Write Response” or an “Error Response” Here is a screenshot from the spec.
Write Response
A Write Response is a stupid simple packet with just one possible value… 0x13 meaning that the write worked. In the PSoC, you generate this packet by calling “CyBle_GattsWriteRsp” with the connection handle as the only parameter.
Error Response
The more interesting response is an error where you are allowed to send more information. To generate an error response in PSoC you call CyBle_GattsErrorRsp with the connection handle and the error code.
The spec gives a list of legal error codes. Here is a snapshot from the spec with a FEW of them.
The interesting thing about these error codes is that you are allowed to create you own “Application Errors” which will have your application semantics.
PSoC Creator has an enumerated list for the error codes (here is a short section from the BLE Component Datasheet)
Answers
OK… so that leaves me with giving specific answers to his questions. My answer are embedded in bold:
Hi, I am having some problems understanding “write without response” setup.
In the “capsenseled” server project “CYBLE_EVT_GATTS_WRITE_REQ” is used instead of “CYBLE_EVT_GATTS_WRITE_CMD_REQ” in the event handler, but “write without response” is selected in the component setup.
According to this other project I am looking at ( https://www.digikey.com/eewiki/pages/viewpage.action?pageId=55574662 ) both are used with comments as follows
case CYBLE_EVT_GATTS_WRITE_REQ: //Write with response
case CYBLE_EVT_GATTS_WRITE_CMD_REQ: //Write without response
Why is “CYBLE_EVT_GATTS_WRITE_CMD_REQ” NOT used in the capsenseled project,
When I wrote that project originally I chose to only support no responses to writes. There is no need to support both. As the application developer you can choose to do either or both.
and does “CYBLE_EVT_GATTS_WRITE_REQ” still function in a write without response setup?
If the GATT Client sends you a CYBLE_EVT_GATTS_WRITE_REQ and you send a response it might turn out badly and you should not do that.
Am I misunderstanding the definition of a response?
Is the “response” referring to an event that occurs within the server device, or is a response defined as a reply from the client device?
Well.. sounds like the answer was yes… but hopefully it is no now.
I am trying to set up a low power single button remote to report the state of the button, to be handled by the client which is connected to a larger power source and will possibly count edges, measure button press duration, or both, etc. Ideally the remote would be asleep except for when it needs to tell the client that the button has changed states, and would not spend any energy processing a response from the client.
Sounds like “Write without response” is perfect for your application.
4 Comments
You mixed up Write Command and WriteRequest in the first tables!
The WriteRequest is the one which expects a WriteResponse. the WriteCommand does NOT!
Yes… you are correct. Also the section is wrong… it should be 3.4.5.1 as 3.4.5.3 is att_write_cmd
Also I notice that at some point they added “att_” to the names of those operations. Must have been in the 5.2 spec
Alan
Hi,
In signed write command why we use authentication flag as it was already encrypted and authenticated by smp
I dont know