I understand that you have a server established with a characteristic that supports 'read'. And you want to ensure that the characteristic is updated with new data so that Client (CySmart) can read the updated data. Right?
Unlike Write requests from Client, Read requests do not generate an event on Server side and are handled automatically by BLE Stack. This is good in a way as the application should not be frequently interrupted for multiple but redundant reads (think about someone continuously tapping "Read" on the CySmart).
Rather, application on server can update the GATT database whenever it has a new data and then leave it on to stack to send this data whenever a read request arrives. Use API CyBle_GattsWriteAttributeValue() whenever you have a new data that you want the Client to read.
Yes, you understood me correctly. my device is server, and is reading sensors that it needs to report to Client (CySmart in this case) via read.
I did see the CyBle_GattsWriteAttributeValue(), but that that was for write events.
Do you have an example on how to call this routine to put my data in the stack?
CyBle_GattsWriteAttributeValue() is used under Write Events for those characteristics that support both Write and Read. In this case, the data obtained from Write request is updated as the read data of the same characteristic. This way, your characteristic will see the same data that was written to it. If this is not done, then the Characteristic will always show 0 as the read value.
You can refer the CY8CKIT-042-BLE example projects, especially the one on RGB LED. It is something like this:
rgbHandle.attrHandle = RGB_LED_CHAR_HANDLE /*attribute handle of the characteristic*/;
rgbHandle.value.val = RGBledData; /* uint8 pointer to the array from where the updated data is to be taken*/
rgbHandle.value.len = RGB_CHAR_DATA_LEN /* length of the data*/;
/* Send updated RGB control handle as attribute for read by central device, so that
* Client reads the new RGB color data */
The GATT model is that the GATT server (PSoC BLE in your case) maintains a list of the current values for all attributes. It uses this to return the value to all read requests from the GATT client (e.g. CySmart). Read requests are not routed to the actual application therefore.
So either you do polling (your client asks for the current value) or use notifications. The latter will push the changes from the GATT server to the GATT client.
thanks for the pointers, but I still am not seeing how data from my application gets into the "list of the current values for all attributes"
I studied the RGB example, which seems straight forward, but the RGB data is the only value read. I'm my project, I have several, and its not clear to me how to get my data into the array.
I asked some people at a Cypress BLE seminar the other day, none of them could help me either.
MidwestPDS do you have a response of your last question. I've a similar curiosity (still not satisfied).
I have a similar situation a custom profile on a PRoC that is a GATT server, my custom profile has multiple characteristics, and part of the problem is that the tool generates a specific set of API's for example open any of the example projects, that have a known profile as defined by bluetooth SIG, (for example battery level) the tool generates the characteristic tables, enumerates values, and creates API functions like CyBle_BassGetCharacteristicValue, CyBle_BassSetCharacteristicValue, CyBle_BassGetCharacteristicDescriptor, CyBle_BassSetCharacteristicDescriptor, CyBle_BassWriteEventHandler, CyBle_BassSendNotification.
part of the problem is the tool does not do this for the custom interface, I can see partly because there is an unlimited number of ways to define a custom interface, so compare the example project to the RGB LED project you will see the API is not generated for a custom profile.
So really what is required is that you have to duplicate this API process done for a known example and modify using your own settings, to fit a custom profile. Beware, do not write any of your code into the files BLE_custom.c (normally where API goes) as soon as you do a clean and build the files get regenerated and it erases all your efforts.
so you need to write your own Get / Set API Notify API that ultimately calls the Read and Write to GATT server. You also have to create your own characteristic structures, etc.
For instance just using the battery service profile, / example project, the tool generates, BLE_bas.c where the API is located, and likewise BLE_bas.h where the data structures are defined. then you have to write what they label as the call back function, and then you also have to write your application that does data scaling, data conversion, and data algorithm, then in this application, you then call the API to Get / Set values, or to do Notify.
It's a good suggestion, Jetro, I'll look better on examples projects from SIG profile.
About PSoc BLE (and family) I think the examples to follow are few for central/client solutions.
It is unfortunate that there is no way to route the READ request in the firmware. I can think of many security related applications where this would be useful. Instead, I will have the firmware write 0x00...to all of the characteristics that need to be 'secured' when a central device disconnects, and then 'load' all of the characteristics when a new central authorizes itself.