Enable and Disable BLE Service and/or associated Characteristic(s)

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

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.

0 Likes
7 Replies
Anonymous
Not applicable

Thanks 🙂

   

Regards,

   

-Madhu Sudhan

0 Likes
Anonymous
Not applicable

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.

0 Likes
Anonymous
Not applicable

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.

Anonymous
Not applicable

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!

0 Likes
Anonymous
Not applicable

Good luck! Let me know how it turns out

0 Likes
Anonymous
Not applicable

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

0 Likes
Anonymous
Not applicable

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