6 Replies Latest reply on Jun 21, 2016 10:50 PM by abdullah.cinar_1528391

    Read Characteristic from Server


      Hi, i'm trying to read a characteristic from server(peripheral). I found the CyBle_GattcReadUsingCharacteristicUuid function in API Document. Is there any example implementation of it? I'm getting CYBLE_ERROR_INVALID_PARAMETER error when i call that function. Can anyone give me an example project or something about this? I do not need notifications, write etc. Just wanna read a characteristic( which i know the uuid of it) from a server. Below is the code fragment which gave me the CYBLE_ERROR_INVALID_PARAMETER error:








      readByTypeReqParam.uuid = 0x2A29u;                           // Characteristic UUID for Manufacturer Name String at Device Information Service
      readByTypeReqParam.uuidFormat = 0x01;                      // 16 Bit UUID Format
      apiResult = CyBle_GattcReadUsingCharacteristicUuid(connHandle,&readByTypeReqParam);







        • 1. Re: Read Characteristic from Server

          I also created a case for this situation but it takes a little long to get an answer. I need to get this work, can anyone help me please? 

          • 2. Re: Read Characteristic from Server

            Finally i got this work. It took much time because i could not find an example project about this. I added some part of the code to below, so maybe someone needs this too.




            CYBLE_GATTC_READ_BY_TYPE_REQ_T          readByTypeReqParam;
            CYBLE_GATTC_READ_BY_TYPE_RSP_PARAM_T    readResponse;
            CYBLE_GATT_ATTR_HANDLE_RANGE_T          range;
            CYBLE_UUID_T                            uuid;
            CYBLE_API_RESULT_T                      apiResult;


                        printf("\r\nDiscovery complete.\r\n");
                        range.startHandle   = 0x0001;
                        range.endHandle     = 0x0030;
                        uuid.uuid16         = 0x2A00; 


                        readByTypeReqParam.range = range;
                        readByTypeReqParam.uuid = uuid;
                        readByTypeReqParam.uuidFormat = 0x01;


                        apiResult = CyBle_GattcReadUsingCharacteristicUuid(connHandle,&readByTypeReqParam);
                        if ( apiResult == CYBLE_ERROR_OK )


                    case CYBLE_EVT_GATTC_READ_BY_TYPE_RSP:
                        readResponse = *(CYBLE_GATTC_READ_BY_TYPE_RSP_PARAM_T *) eventParam;
                        for( i=2 ; i < readResponse.attrData.length; i++)

            • 3. Re: Read Characteristic from Server





              This code snippet was helpful for me to, so I would like to say thanks!


              What was a principle of defining following values:


               range.startHandle   = 0x0001;
               range.endHandle     = 0x0030;

              • 4. Re: Read Characteristic from Server

                Your welcome, I'm glad that it helped you out!


                Handles are the way the server knows it's services&characteristics. It does not call them with their UUID, it calls them with the handles instead. When you add a service&characteristic to your BLE Component. PSOC Creator generates the necessary files for it which also contains the attribute handle definitions.


                After the end of discovery, startHandle and endHandle specifies which interval will be searched inside of the discovered database. If you use it like this:




                range.startHandle   = 0x0001;
                range.endHandle     = 0xFFFF;


                Now the client will search the entire database of the server, after the discovery. You can narrow down the search interval if you know the handle number of the characteristic which you want to scan. You can find the handles of characteristics for the server database in "CYBLE.h" or "BLE.h" files from generated sources. For example, I have a custom characteristic in my project. The characteristic handle for the custom characteristic is in the "CYBLE_Custom.h" file, like below:




                #define CYBLE_CONTAINER_ID_READSTATE_CHAR_HANDLE   (0x0019u) /* Handle of readState characteristic */




                I had wanted to be sure about I'm scanning for the right interval. So I searched for the entire database, but I guess I could scan that characteristic like below code snippet too:




                 range.startHandle   = 0x0019;
                 range.endHandle     = 0x0019;


                Note that this code snippet runs in the central side which scans the server of the peripheral device. You must find the attribute handle from the server(peripheral project) and scan it in the central project.

                • 5. Re: Read Characteristic from Server



                  I'm facing the exact same problem. I have created a custom profile all I want is to read. My UUID is 128 bit. Data I'm trying to read is utf8s.


                  I'll be glad if you could help.





                  • 6. Re: Read Characteristic from Server

                    After you connect to the peer device, the ble subsystem updates the ble state as CYBLE_EVT_GAP_DEVICE_CONNECTED. You need to start discovering the peripheral device server. After the discovery ends, the ble subsystem updates the ble state as CYBLE_EVT_GATTC_DISCOVERY_COMPLETE. Now you have the information of the server of the peripheral device. Note that the client or peripheral identifies the database(services, characteristics etc.) with their handles. So if you want to read a characteristic after the discovery ends, you can specify a handle range to let the client(your central device) search that range in the server. You can find the corresponding handle numbers in the CYBLE_Custom.h file of the peripheral project for each characteristic of the peripheral device. Something like this:




                    #define CYBLE_CUSTOMCHAR1_CHAR_HANDLE   (0x0019u) /* Handle of CUSTOMCHAR1 characteristic


                    Now you know the handle of the characteristic which you want to read. So you can go to the CYBLE_EVT_GATTC_DISCOVERY_COMPLETE case in the ble event handler of your central device project and specify the handle range. Finally, you get the CYBLE_EVT_GATTC_READ_BY_TYPE_RSP event whenever the peripheral device responses to the reading operation. Below is the example of my read operation. It searches for the entire database instead of one handle. And I am reading a characteristic using the UUID of the characteristic.




                    case CYBLE_EVT_GAP_DEVICE_CONNECTED:


                    printf("\r\nDEVICE CONNECTED.\r\n");




                    /*Start to dicovery the servioes of the serve after connection*/








                    case CYBLE_EVT_GATTC_DISCOVERY_COMPLETE:


                    printf("\r\nDiscovery complete.\r\n");




                    range.startHandle   = 0x0001;


                    range.endHandle     = 0xFFFF;


                    uuid.uuid16         = 0x2223;       //uuid of the characteristic to be read.




                    readByTypeReqParam.range = range;


                    readByTypeReqParam.uuid = uuid;


                    readByTypeReqParam.uuidFormat = 0x01;




                    apiResult = CyBle_GattcReadUsingCharacteristicUuid(cyBle_connHandle,&readByTypeReqParam);


                    if ( apiResult != CYBLE_ERROR_OK )


                    printf("\r\nReading Operation is Failed\r\n");








                    case CYBLE_EVT_GATTC_READ_BY_TYPE_RSP:


                    printf("\r\nReading Operation is Successful.\r\n");




                    readResponse = *(CYBLE_GATTC_READ_BY_TYPE_RSP_PARAM_T *) eventParam;


                    printf("\r\nLength of Characteristic is: %d\r\n",readResponse.attrData.length );




                    printf("Characteristic is: %s\r\n",readResponse.attrData.attrValue);