cancel
Showing results for 
Search instead for 
Did you mean: 

PSoC 4 MCU

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
Reply
7 Replies
Anonymous
Not applicable

Thanks 🙂

   

Regards,

   

-Madhu Sudhan

0 Likes
Reply
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
Reply
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
Reply
Anonymous
Not applicable

Good luck! Let me know how it turns out

0 Likes
Reply
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
Reply
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