CC2340R5: Invalid response length after calling GATT_DiscAllChars

Part Number: CC2340R5

Tool/software:

Hi,

Chipset: CC2340R5

sdk:

Hi I am currently using one CC2340R5 EVK (Central EVK)for development and I am running the EVK in central role, Basic ble sdk is used as a base project.

I am using another CC2340R5 EVK(Peripheral EVK) in peripheral  mode, the basic ble sdk code is used as a base project.

I have The gatt table of the evk running in peripheral role using nrf connect and it is attached below. After collecting this info, I disconnect the peripheral device from nRF connect.

 

Now, using the "Central EVK" I connect to the "Peripheral EVK". After the connection is successful, I initiate a service discovery call as shown below:

I have used the Log_printf function to print the response for the service discovery, and it is as follows:

I have saved the service discovery response in a queue. 

Later,  I call retrieve the service discovery response from the queue and call the  "GATT_DiscAllChars" APIas shown below.

I get a "ATT_READ_BY_GRP_TYPE_RSP" rsp and after parsing, I have printed the contents of " attReadByGrpTypeRsp_t" below.

as you can see, the dataLen field contains a very huge number. 

What could be the issue here? I am not able to proceed further due to this, Please help me resolve this. 

In addition, I have also added the logic that I have used to parse the "attReadByGrpTypeRsp_t" structure.

  • Hello,

    You shouldn't be getting an ATT_READ_BY_GRP_TYPE_RSP, since GATT_DiscAllChars returns ATT_READ_BY_TYPE_RSP which uses a different structure.

    https://dev.ti.com/tirex/content/simplelink_lowpower_f3_sdk_8_10_01_02/docs/ble5stack/ble_user_guide/doxygen/ble/html/group___a_t_t___g_a_t_t.html#gac824af509fbd28c84ae6a1d1d4a1ba11

    Are you receiving ATT_READ_BY_GRP_TYPE_RSP instead of ATT_READ_BY_TYPE_RSP? Do you mind sending over your handler code so I can review it?

    Best,

    Nima Behmanesh

  • Hi Nima, 

    Thanks for pointing out the mistake. I posted the wrong snippets. Please find my GATT_EvenHandler below.

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    static void GATT_EventHandler(uint32 event, BLEAppUtil_msgHdr_t *pMsgData)
    {
    gattMsgEvent_t *gattMsg = ( gattMsgEvent_t * )pMsgData;
    switch ( gattMsg->method )
    {
    case ATT_FLOW_CTRL_VIOLATED_EVENT:
    {
    MenuModule_printf(APP_MENU_PROFILE_STATUS_LINE, 0, "GATT status: ATT flow control is violated");
    }
    break;
    case ATT_MTU_UPDATED_EVENT:
    {
    MenuModule_printf(APP_MENU_PROFILE_STATUS_LINE, 0, "GATT status: ATT MTU update to %d",
    gattMsg->msg.mtuEvt.MTU);
    Log_printf(LogModule_App1, Log_INFO, "MTU updated to: %d", gattMsg->msg.mtuEvt.MTU);
    }
    break;
    case ATT_READ_BY_GRP_TYPE_RSP:
    {
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    I am receiving "ATT_READ_BY_TYPE_RSP" The parsing logic is present in the above code snippet.

    I print the contents of "attReadByTypeRsp_t" structure and get  a very value for the  datalength field. 

    I have also printed the raw data contents of "attReadByTypeRsp_t" below, the below contents are results of a different handle search.

    gattMsg->msg.readByTypeRsp.len = 7;
    gattMsg->msg.readByTypeRsp.numPairs = 0x05;
    gattMsg->msg.readByTypeRsp.pDataList = 0xC3, 0x43, 0x00, 0x20; 
    gattMsg->msg.readByTypeRsp.dataLen = 0xEB11; // Very large

    0x05, 0x00,  0x07, 0x00, 0xC3, 0x43, 0x00, 0x20, 0x11, 0xEB

  • Hi,

    This is definitely, strange by reading the attReadbyTypeRsp_t structure, you may not need this field.

    For instance, here is how I parse it:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    display_index += 1;
    attReadByTypeRsp_t *response = (attReadByTypeRsp_t *)&(gattMsg->msg.readByTypeRsp);
    MenuModule_printf(display_index, 0, "GATT status: Read by type %d", response->numPairs);
    for (int i = 0; i < response->numPairs; i++)
    {
    uint16_t attributeHandle = BUILD_UINT16(response->pDataList[i * response->len + 0],
    response->pDataList[i * response->len + 1]);
    uint16_t endHandle = BUILD_UINT16(response->pDataList[i * response->len + 2],
    response->pDataList[i * response->len + 3]);
    display_index += 1;
    MenuModule_printf(display_index, 0, "GATT status: Read by type: Handle: %x | %x", attributeHandle, endHandle);
    }
    break;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Can you try this and let me know the results?

    Best,
    Nima Behmanesh

  • Hi Nima, 

    I will be back to office tomorrow, I will try this an keep you posted. But it very strange to get such huge values, Could you check what could be the reason for this?

  • Hi Sandeep,

    I will need to contact R&D and reproduce the issue on my side as well. What SDK version are you using? I believe it was missing from your original post.

    Best,
    Nima Behmanesh

  • Hi Nima, 

    The SDK version that I am currently using is "simplelink_lowpower_f3_sdk_8_10_01_02".

  • Hello,

    Thanks! I'll try it and get back to you.

    Best,
    Nima Behmanesh

  • Hi Sandeep,

    I'm still looking into this, and will get back to you no later than Friday.

    Best,
    Nima Behmanesh

  • Hi Sandeep,

    Do the holidays, my responses will be a little bit delayed. Thank you for your patience in resolving this issue.

    Best,
    Nima Behmanesh

  • Thank you for keeping me posted. I Hope that we can find a solution soon.

  • Hi Sandeep,

    Do you mind testing on the latest SDK to see if the issue still persists?

    Best,
    Nima Behmanesh

  • Hi Nima, 

    The below image shows that the SDK is compatible for CC27 chipsets. I have a CC27 board with me and I have loaded the above code on to it as well. I see the same issue being replicated on the CC27 board as well. Could this really be an SDK issue?

  • Hi Sandeep,

    Were you able to try the code snippet pasted above?

    Best,

    Nima Behmanesh

  • Hi Nima, 

    The above approach might not be a feasible solution in our use case as we wish to send the received data to a task and handle the processing there. 

  • Hi Sandeep,

    The way the information is parsed is specified by the Bluetooth Core Specification. If you need to handle the data in a different task, I'd suggest possibly formatting the information the way I have it above, and placing it in within a struct that can be shared between the tasks.

    Best,

    Nima Behmanesh

  • HI Nima,

    You are absolutely right when you say "The way the information is parsed is specified by the Bluetooth Core Specification". Since the strcut has a pointer field (pDataList) and a datalen field, It was my understanding that the the datalen would tell how many bytes to read from the pDataList.

    Also, given the code snippet that you have shared earlier, Is it right to assume that "response->numPairs * 4" captures the entire contents of pDataList? 

  • Hi Sandeep,

    I believe this is correct. Though I believe you can copy the code snippet directly, and this should capture all of the pairs of attribute handles.

    Best,

    Nima Behmanesh

  • Hi Nima,

    Got it. So is it right to assume that for this particular event, the numPairs must be used to decode the data and the length field has an un usually high value because it is a default setting?

  • Hi Nima, 

     On the peripheral I have 1 service and five characteristics as shown below.

    I have taken the reference of the code snippet above and have extracted data from it. The numpairs is 5 and the length of each pair is 7.

    The data is shown below.

    0x02,0x00, 0x18,0x03, 0x00, 0x01,0xE0,
    0x06,0x00, 0x18,0x07, 0x00, 0x02,0xE0,
    0x0A,0x00, 0x18,0x0B, 0x00, 0x03,0xE0,
    0x0E,0x00, 0x18,0x0F, 0x00, 0x04,0xE0,
    0x12,0x00, 0x18,0x13, 0x00, 0x05,0xE0

    The code snippet used to extract the above data :

    From what I understand, The First 2 bytes are start handles, bytes- 3 and 4 are end handles. Since I know the UUID of my device I can confidently say that the last 2 bytes are UUIDs.

    I see that the end handles are not in sync with start handles. Since the datalen field has an invalid value, could it be possible that the rest of the fields are also improper? is this data which I have received from the stack the correct one?

  • Hi Sandeep,

    Do you mind reattaching the picture of the services? It isn't loading for me.

    I see that the end handles are not in sync with start handles.

    Do you mind elaborating what you mean by they are not in sync?

    Best,

    Nima Behmanesh

  • Hi Sandeep,

    After looking into this and trying some things on my end, I see where the confusion is coming from, and so I feel the need to step back and start from scratch.

    First, the code I had written before isn't totally correct. To understand why, we need to look at the spec.

    1. Let's take a look at the ATT_READ_BY_TYPE_RSP

    So, there are only two fields here that we care about, Length and the Attribute Data List. This maps to two fields in the attReadByTypeRsp_t struct that we are parsing through.

    Length = attReadByTypeRsp_t.len

    Attribute Data List = attReadByTypeRsp_t.pDataList

    Moving forward, these are the only two fields we need from the struct. Ignore dataLen completely (to be honest, it shouldn't even be there).

    Also note that we are getting attribute handle-value pairs. We aren't getting start handles and end handles. What we are getting is a handle to the attribute, and the value of that attribute. This is important, because now we must look at GATT.

    2. Part G. Generic Attribute Profile Section 3.3.1

    Here we see what that value portion of the attReadByTypeRsp_t actually looks like:

    We are also doing little endian, so we will need to reverse the order of the pDataList that we are retrieving:

     

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    case ATT_READ_BY_TYPE_RSP:
    {
    attReadByTypeRsp_t att = (attReadByTypeRsp_t)gattMsg->msg.readByTypeRsp;
    MenuModule_printf(APP_MENU_PROFILE_STATUS_LINE + display_index, 0, "ATT_READ_BY_TYPE_RSP len: %d numPairs: %d", att.len, att.numPairs);
    display_index++;
    for (uint8_t i = 0; i < att.numPairs; i++)
    {
    /* This is the Attribute Handle */
    uint16_t attHandle = BUILD_UINT16(att.pDataList[i * att.len + 0], att.pDataList[i * att.len + 1]);
    MenuModule_printf(APP_MENU_PROFILE_STATUS_LINE + display_index, 0,"ATT Handle: %x", attHandle);
    display_index++;
    /* This is the index to the beginning of the value data AFTER the attribute handle */
    uint8_t index = i * att.len + 2;
    /* The characteristic value data */
    uint8_t data1 = att.pDataList[index]; // Bit field of characteristic properties
    uint8_t data2 = att.pDataList[index + 1]; // Second Byte of Characteristic Value Handle
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    I tried this on the device info service (UUID 0x180A) and this was the output:

    This makes sense, especially if we consider our ATT_MTU size of 27bytes (len is 7, we have 3 pairs, so 27bytes in total). The ATT_MTU size may be different in your application. I've also verified that the properties and UUIDs I expect are what I'm getting.

    Lastly, I'll parse through the image you attached:

    Attribute Handle: 0x0002, Properties: 0x18 (GATT_PROP_WRITE | GATT_PROP_NOTIFY), Value Handle: 0x0003, UUID: 0xE001

    I hope that helps, and please let me know if you have any questions!

    Best,

    Nima Behmanesh

  • Hi Nima, 

    Thanks a lot for the detailed explanation about the packet type. It was very informative as well. I tested the above sequence in my code and I am able to make sense out of it now. With this, I should be able to close the client implementation.

    Once again thanks a bunch,

    Sandeep