2 of 2 people found this helpful
Ok, I've solved by myself.
Here my solution: I hope it will be useful for someone.
It was not easy, because the documentation is unclear, there are poor explained examples and I'm new on BLE development.
Anyway, I wrote a simple function for my Custom Characteristic value.
I'm using a float32 (4 bytes long) for Custom Chacteristic, so the function need to be modified as needed.
void SetmyCustomAttributeValue ( float32 valore, uint16 handler)
CYBLE_GATT_ERR_CODE_T apiGattErrCode = 0;
handleValuePair.value.val = (uint8 *)&valore;
handleValuePair.value.len = sizeof(valore);
handleValuePair.attrHandle = handler;
/* To register the service change in the Database of the GATT Server */
apiGattErrCode = CyBle_GattsWriteAttributeValue(&handleValuePair, 0u, NULL,CYBLE_GATT_DB_LOCALLY_INITIATED);
if (apiGattErrCode != 0)
DBG_PRINTF ("Service Changed Attribute DB write failed\r\n");
DBG_PRINTF ("Service Changed Attribute DB write success\r\n\n");
The CyBle_GattsWriteAttributeValue() function is called with NULL as connection handler, this because I want to initialize my attribute value even without any connection.
Because I'm operating in a local GATT DB (from the server side, not from remote client) the parameter CYBLE_GATT_DB_LOCALLY_INITIATED was used as 4th value.
Pay attention to the right initalization of CYBLE_GATT_HANDLE_VALUE_PAIR_T structure.
Thanks for posting this. It is helpful to know that if you pass NULL in as the connection handle that it will work and update the database without failing.
Do you know what the difference between the two options for the last parameter of CyBle_GattsWriteAttributeValue is?
CYBLE_GATT_DB_LOCALLY_INITIATED and CYBLE_GATT_DB_PEER_INITIATED?
I believe the two options for the last parameter are flags to indicate which case to allow for updating the database value (I might be wrong).
If both are set, then it will always write it, if only one of them is set, then it will only write it if the corresponding side of the bluetooth connection initiated the write.
At least, that is what it seems like from reading the comments in the files and forum posts elsewhere.
CYBLE_GATT_DB_LOCALLY_INITIATED should be used when the server is updating its own GATT DB. CYBLE_GATT_DB_PEER_INITIATED should be used when a client is trying to write to the server's GATT DB.
Coming to the difference, when the CYBLE_GATT_DB_LOCALLY_INITIATED is passed as the last parameter, the CyBle_GattsWriteAttributeValue() does not check for permissions and will blindly update the GATT DB. On the contrary, when the last parameters is set to CYBLE_GATT_DB_PEER_INITIATED, CyBle_GattsWriteAttributeValue() will check for permissions (authentication required, encryption required) and will either write to the GATT DB or return a GATT error.
CyBle_GattsWriteAttributeValue() returns CYBLE_GATT_ERR_CODE_T, which is the GATT error code. In case of CYBLE_GATT_DB_LOCALLY_INITIATED, there will never be any error. In case of CYBLE_GATT_DB_PEER_INITIATED, the API might return gatt error if permissions are not met by the client.
Thanks yssu, that clears up the confusion I had with the different flags.
I found this extremely helpful. Thanks for posting Fabrizio. The answer should be accepted so others can see it easily.