BLE Write Payload Best Practice

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

cross mob
Anonymous
Not applicable

What is the best way to get the entire payload of a BLE write request or BLE write command? 

   

I was looking at the FindMe example and it shows that you can get the complete value of the payload by saving the data byte-by-byte into an array. Assuming that Cypress doesn't provide an API to just get the data in a variable directly, this seems logical. However, in the loop they use handleValPair.value.len instead of handleValPair.value.actualLen. My understanding is that .len will return the length that is defined for that Characteristic, and .actualLen will return the length of the data payload that got sent. For example, if you set the device_name Characteristic to 20 bytes, then .len will return 20 and .actualLen will return the actual length of the string that got sent over. 

   

Can anyone verify that I'm understanding this correctly, and if there's a reason you would want to loop through the entire length, instead of just the number of bytes that came in from the BLE write? Perhaps it is because the changed_name variable is the full length of the attribute so you would want to read it all to make sure you fill up the array so you don't have any bytes that are 'left over' from a previous usage?

   

 

   

Here's the code from the FindMe example:

   

char8 changed_name[14];

   

// lots of code skipped here when I pasted this example....

   

case CYBLE_EVT_GATTS_WRITE_REQ:
        wrReqParam = (CYBLE_GATTS_WRITE_REQ_PARAM_T *) eventParam;
        if(wrReqParam->handleValPair.attrHandle == 0x03)  // this is the BLE standard device name Characteristic
        {
            for(i=0;i<wrReqParam->handleValPair.value.len;i++)
                changed_name = wrReqParam->handleValPair.value.val;
        }
        CyBle_GapSetLocalName(changed_name);
        CyBle_GattsWriteAttributeValue(&wrReqParam->handleValPair,0,&cyBle_connHandle,CYBLE_GATT_DB_PEER_INITIATED);
        CyBle_GattsWriteRsp(cyBle_connHandle);
        break;

0 Likes
2 Replies
GyanC_36
Employee
Employee
250 replies posted 100 replies posted 50 replies posted

Hi Alex,

   

->I understood that you mean  the 'actualLen' is the length of packet that physical layer is transmitting over the air?  Am i right? If yes,then the 'actualLen' is not the length of packet that physical layer is transmitting over the air and it is also related to the GATT attribute size only.

   

For Example:If the attribute length is 30 octects and the MTU is 23 octets, then only first 22 octets can be sent by GATT, therefore actual length('actualLen') will be 22 (MTU-1). However, if the GATT MTU is configured to be 54 for example, all 30 octets can be transmitted and the actual length will be 30.

   

So,Actual length('actualLen') can be less than or equal to the 'len' parameter value.

   

Regards,

   

Gyan

0 Likes
Anonymous
Not applicable

Hi Gyan,

   

It was more of a question, than a statement. I put some debug UART statements in and foud that the actualLen seems to always be 8192 even when the .len is only 1 byte long. I'm not sure if maybe I'm not outputting it to UART properly or if something else is amiss...

   

This prints out "8192"

   

 

   

sprintf(OutputString, "%i", write_request->handleValPair.value.actualLen);
UART_UartPutString(OutputString);

0 Likes