- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The information below is for those who would like to enable and disable a BLE Service and/or an associated Characteristic (value), and possible Characteristic Configuration (e.g. for Notify), using the Cypress BLE API functions CyBle_GattsEnableAttribute() and CyBle_GattsDisableAttribute():
The defined constants below are as generated by Cypress in BLE_custom.h for a Custom Service having a Custom Characteristic (value) and a Custom Characteristic Configuration, with no Custom Descriptor:
#define CYBLE_CUSTOM_SERVICE_SERVICE_HANDLE (0x000Cu) /* Handle of Custom Service service */
#define CYBLE_CUSTOM_SERVICE_CUSTOM_CHARACTERISTIC_CHAR_HANDLE (0x000Eu) /* Handle of Custom Characteristic characteristic */
#define CYBLE_CUSTOM_SERVICE_CUSTOM_CHARACTERISTIC_CUSTOM_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE (0x000Fu) /* Handle of Custom Characteristic Configuration descriptor */
A Service is enabled/disabled by utilizing the Service Handle (e.g. CYBLE_CUSTOM_SERVICE_SERVICE_HANDLE) with the functions CyBle_GattsEnableAttribute() and CyBle_GattsDisableAttribute().
However, to enable/disable only a Characteristic (of a Service), the required "Characteristic Declaration Handle" is produced by subtracting 1 from the "Characteristic Value Handle" (e.g. CYBLE_CUSTOM_SERVICE_CUSTOM_CHARACTERISTIC_CHAR_HANDLE) and any Characteristic Configuration (e.g. handle of CYBLE_CUSTOM_SERVICE_CUSTOM_CHARACTERISTIC_CUSTOM_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE) associated with that Characteristic Value will also be enabled/disabled when calling CyBle_GattsEnableAttribute() and CyBle_GattsDisableAttribute() with the "Characteristic Declaration Handle".
Therefore, for the defined constants generated by Cypress above, the entire Service (and Characteristics) is enabled/disabled by calling CyBle_GattsEnableAttribute()/CyBle_GattsDisableAttribute() with the handle CYBLE_CUSTOM_SERVICE_SERVICE_HANDLE.
The Service Characteristic (value) and associated Characteristic Configuration is enabled/disabled by calling CyBle_GattsEnableAttribute()/CyBle_GattsDisableAttribute() with a handle value of CYBLE_CUSTOM_SERVICE_CUSTOM_CHARACTERISTIC_CHAR_HANDLE - 1 (e.g. 0x000Eu - 1 = 0x000Du) which is not defined anywhere by Cypress.
- Labels:
-
BLE
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks 🙂
Regards,
-Madhu Sudhan
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi tdbconsulting_1416776. I am also using the disable/enable service API on two of the Services to enable one and disable the other with respect to certain conditions. What I do is a do-while loop as shown below:
if (condition1)
{
do {
error1 = CyBle_GattsDisableAttribute(Service 1);
error2 = CyBle_GattsEnableAttribute(Service 2);
} while (disErr != CYBLE_GATT_ERR_NONE && enErr != CYBLE_GATT_ERR_NONE);
Perform processes();
}
else if (condition2)
{
do {
error1 = CyBle_GattsDisableAttribute(Service 2);
error2 = CyBle_GattsEnableAttribute(Service 1);
} while (disErr != CYBLE_GATT_ERR_NONE && enErr != CYBLE_GATT_ERR_NONE);
Perform processes();
}
However, I noticed that the disabling/enabling is something that CANNOT be easily done (code seems stuck inside the do-while loop) and sometimes is successful and sometimes NOT. How do I correctly handle the disabling/enabling of Services? Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I would do something like this:
if (condition1)
{
error1 = CyBle_GattsDisableAttribute(Service 1);
error2 = CyBle_GattsEnableAttribute(Service 2);
if(error1 != CYBLE_ERROR_OK && error2 != CYBLE_ERROR_OK) {
//Handle Failed enable/disable here
//Retry or continue onwards?
}
Perform processes();
}
else if (condition2)
{
error1 = CyBle_GattsDisableAttribute(Service 2);
error2 = CyBle_GattsEnableAttribute(Service 1);
if(error1 != CYBLE_ERROR_OK && error2 != CYBLE_ERROR_OK) {
//Handle Failed enable/disable here
//Retry or continue onwards?
}
Perform processes();
}
Most likely the failure to enable/disable the service is due to the unit actively scanning, advertising, or being connected at a guess. The BLESS tends to prefer not to have anything change while active, otherwise it gets errors/crashes.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'll give that a try, e.pratt_1639216. You're right. I think the errors come from the fact that the BLESS is active, and then I'm trying the disabling/enabling stuffs. I'll handle that. Thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Good luck! Let me know how it turns out
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi e.pratt_1639216! Here's what I did and I think it's somehow working already.
1. when BLE receives a command that requires switching between 2 services, a function is called that does the ff:
a. check the current state of the BLE (CyBle_GetState())
b. if advertising, CyBle_GappStopAdvertisement(); if connected, CyBle_GapDisconnect()
c. once BLE's state is already CYBLE_STATE_DISCONNECTED, call the disabling/enabling attributes APIs
d. connect back to previously connected device
2. BLE will resume performing the functions/commands
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
capardogracielle_2279656 Sweet!
Sounds like the active BLESS was the issue then.
Relatively simple to add some code to handle the state/transitions.
Congrats,
Elijah