CYW 20719 BLE Congestion Cont.

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

cross mob
rjmcc
Level 1
Level 1
First like received 10 sign-ins 5 sign-ins

As stated in a previous post (https://community.infineon.com/t5/AIROC-Bluetooth/CYW-20719-BLE-Congestion/m-p/325056), I am trying to write an application that will send a large file from a flash drive attached to a 20719B1 chip (without the eval board) to an android app, which will unpack and display the data. The BLE connection congests after about 6KB of data re sent, and the decongestion event never sends (I have waited at least 15 minutes to see if it's just heavily delayed, with no effect). Solutions and details of the problem are in the post linked above, but since then:

1) I have discovered that the app only receives the first 5 packets of data sent (each packet is at the extended MTU, with 506 bytes of data + 11 bytes of headers added by BLE). If I send a file that is larger than the 5 packets of data but small enough that it doesn't cause congestion, then the app receives the first 5 packets as they are sent, then receives the rest of the data all at once, just before the app disconnects from the B1 chip. If I put in delays between the packets, this issue is clearly visible by watching the app logs.

2) I can get a decongestion event by using the wiced_bt_l2cap_flush_channel() method on the correct LCID, but the phone still only receives the first 5 packets. I'm not sure if this method tries to send the data queued for the particular channel, or just deletes the data that's queued to free up the buffers, but this is the closest thing I've found to a solution for this problem.

I can't share all the code I have for a few reasons, but this is the snippet that is sending notifications, where it eventually congests. The congested variable used is set to 1 on a congestion event and to 0 on a decongestion event, and the transferInfo variable is a struct that keeps track of the total amount of data to send and the amount of data that's already been sent, so the board knows when to stop sending data. The file system operations are from the SEGGER emFile filesystem.

Is there something I'm doing glaringly wrong here, or any reason that the board might only send the first few notifications and simply queue the rest?

 

static uint16_t MedPatch_ReadData(uint8_t *pData, const char *file_name) {

WICED_BT_TRACE("Sending up data from file %s\r\n", file_name);
wiced_result_t result=WICED_BT_GATT_INTERNAL_ERROR;

if (transferInfo.transferMode != TRANSFER_MODE_READ)
{

return WICED_BT_GATT_WRONG_STATE;


}

uint16_t copySize=medPatchMaxMTU;

WICED_BT_TRACE("Data length: %d\r\n", transferInfo.totalDataLength);
WICED_BT_TRACE("Op length: %d\r\n", transferInfo.transferOperationLength);

if ((transferInfo.totalDataLength - transferInfo.transferOperationLength) <= medPatchMaxMTU)
{

copySize = (UINT16)(transferInfo.totalDataLength - transferInfo.transferOperationLength);

}

//Read the medstore and the patient data
if (current_file == NULL) {


WICED_BT_TRACE("Open patient file\r\n");
current_file = FS_Open(current_file_name, FILE_MODE_R);


}
MedPatch_ReadOpenFile(current_file, pData, copySize);


WICED_BT_TRACE("\r\n");

transferInfo.transferOperationLength += copySize;
WICED_BT_TRACE("Bytes sent: %d\r\n", copySize);
if (transferInfo.transferOperationLength == transferInfo.totalDataLength) {

transferInfo.transferOperationLength = 0;
transferInfo.transferDone = TRUE;
FS_Close(current_file);
current_file = NULL;

}

WICED_BT_TRACE("Sending notification: conn_id %d, copySize %d\r\n", conn_id, copySize);
wiced_bt_gatt_status_t notif_status;

notif_status = wiced_bt_gatt_send_notification(conn_id, HANDLE_MEDPATCH_SERVICE_DATA_VAL, copySize, pData);
while (notif_status != WICED_SUCCESS || congested) {


wiced_rtos_delay_milliseconds(1000, ALLOW_THREAD_TO_SLEEP);

WICED_BT_TRACE("Congestion, try again\r\n");
notif_status = wiced_bt_gatt_send_notification(conn_id, HANDLE_MEDPATCH_SERVICE_DATA_VAL, copySize, pData);


}

WICED_BT_TRACE("Notification status: %d\r\n", notif_status);


return copySize;

}

0 Likes
1 Solution
Charles_Lai
Moderator
Moderator
Moderator
500 replies posted 250 solutions authored 250 sign-ins

Hi,

  1. GATT_CONGESTION_EVT is not a BluetoothSIG-defined event in fact. You can verify this by searching through the Bluetooth Specs. It's rather an additional and applicational indication event by definition (running low in tx buffers). So it hardly tells you what really occurred at that time but only implies you to pause because the buffers were running out. I suggest you try to catch other events in L2CAP / Link Layer for better diagnosis. You may need to turn on HCI traces to do this. See:
    CypressAcademy WBT101: CH05 Debugging
  2. You seemed to be using the extended ATT MTU feature (DLE) of BLE. Could you first try to use the standard ATT MTU length? I.e., try to set the characteristic value length of your characteristic < 20 bytes and disable DLE at first because the ATT MTU size should be 23 bytes in a standard case. See:
    https://punchthrough.com/maximizing-ble-throughput-part-2-use-larger-att-mtu-2/
  3. Then you might increase the characteristic value length to a value < 244 bytes and try again with DLE enabled because the max extended ATT MTU size is usually 247 bytes. The max extended ATT MTU size could vary among different devices but 247 is safe to count on. You need to check the ATT MTU size on both peers to determine your actual characteristic value length. In the worst case that only one peer or none peer supports DLE, then you should rather keep the characteristic value length down to 20 bytes. See:
    https://punchthrough.com/maximizing-ble-throughput-part-3-data-length-extension-dle-2/
  4. I think you shouldn't try any characteristic value length larger than 244 bytes in a Notification/Indication case because a characteristic value length larger than ATT_MTU - 3 size requires active read/write methods specific to long value pairs which rely on multiple Read/Write Response Attribute Protocol messages at a time because it's too large for one PDU to carry on. However, Notification/Indication is the passive method that can only rely on one single PDU.
    In a word, the larger characteristic length (244 - 512 bytes or any numerical value > ATT_MTU - 3) should be used with caution and you should avoid it, though it is supported by BLE in some other cases, to keep Notification/Indication working in one single PDU. See:
    https://devzone.nordicsemi.com/f/nordic-q-a/22744/maximal-notification-size-in-s132
    This restriction is also noted in the Bluetooth Specs, See:
    Charles_Lai_0-1644494407064.png

     

  5. You can also try to use a sniffer to capture the air log. Try to see if any abnormal packet was running when you face the issue.
  6. You can also try to read/write the data actively on the GATT client side, using Blob Read / Queued Write, which should give you correct access to a very large ATT value pair.

Best regards

View solution in original post

0 Likes
6 Replies
DheerajPK_41
Moderator
Moderator
Moderator
750 replies posted 500 likes received 500 replies posted

Hi,

I would like to know the software version (WICED version) which you are using.

There is know known issues reported in the recent software. But I am not sure whether any related issues reported in the old versions of software. We would like to reproduce the issue and collect more details. But the problem here is, you might be using old SDK, custom embedded app and custom android app. Please correct me if I am wrong. 

 

Without sharing the code or without reproducing the issue, what we can do is to check whether any problem arises when using the API wiced_bt_gatt_send_notification() in the WICED SDK version which you are using. 

 

But I strongly recommend you to upgrade to B2 version of the chip, because B1 only support in the WICED SDK where no active development going on. Even if there is any bug in the software the fix can only be delivered to you through the latest software SDK which is Modustoolbox and BTSDK. 

https://www.infineon.com/cms/en/design-support/tools/sdk/modustoolbox-software/? 

 

Thanks,

-Dheeraj.P.K

0 Likes

Hi, thanks for the response,

To preface this, I did figure out a solution to the congestion issue. I'm not sure why that solution worked, but I suspect it's something about how the thread scheduler works. I found that if I put the notification sending on a timer, and give a few milliseconds after each notification for the processor to sit idle, it actually empties out and sends the data that piles up in the buffers. I don't know why I needed to use timers to accomplish this, but I'm guessing that the buffers are handled by a lower priority thread, and the processor doesn't run this thread unless it detects that the higher priority thread is idle. Please correct me if I'm wrong on this.

Because of the supply chain issues, we won't be able to upgrade to the B2 chip for some time. We do intend to as soon as possible, but for the next few months at least we are unfortunately stuck with the B1. I'm not sure if this congestion is an issue for the B2 chip as well, but I hope to eventually be able to test it on a B2 eval board and get back to you on that.

 

Thanks,

Ryan McCubbin

0 Likes
Charles_Lai
Moderator
Moderator
Moderator
500 replies posted 250 solutions authored 250 sign-ins

I saw that you already used "wiced_rtos_delay_milliseconds(1000, ALLOW_THREAD_TO_SLEEP)" to put the current thread to sleep. ALLOW_THREAD_TO_SLEEP can make the current thread quit the scheduler so I think it's equivalent to using a timer to do this. So I think a timer didn't actually help you out here. See:
https://infineon.github.io/btsdk-docs/BT-SDK/20719-B2_Bluetooth/API/group__threads.html#gac954748558...

But keeping the RX buffer vacant is good in helping this issue.

0 Likes

We've had issues with getting sleep to work on the board, so while I tried the delay with ALLOW_THREAD_TO_SLEEP, it's very possible that the board never actually went to sleep when that was called. I think the sleep issue is different. If it is a problem with the thread scheduler though, is there any information you can send me about how the thread scheduler operates, so I can try to avoid this kind of issue in the future?

0 Likes
Charles_Lai
Moderator
Moderator
Moderator
500 replies posted 250 solutions authored 250 sign-ins

Unfortunately we can't find the detailed insights of the thread scheduler.

Your workaround is okay if ALLOW_THREAD_TO_SLEEP is not helpful.

0 Likes
Charles_Lai
Moderator
Moderator
Moderator
500 replies posted 250 solutions authored 250 sign-ins

Hi,

  1. GATT_CONGESTION_EVT is not a BluetoothSIG-defined event in fact. You can verify this by searching through the Bluetooth Specs. It's rather an additional and applicational indication event by definition (running low in tx buffers). So it hardly tells you what really occurred at that time but only implies you to pause because the buffers were running out. I suggest you try to catch other events in L2CAP / Link Layer for better diagnosis. You may need to turn on HCI traces to do this. See:
    CypressAcademy WBT101: CH05 Debugging
  2. You seemed to be using the extended ATT MTU feature (DLE) of BLE. Could you first try to use the standard ATT MTU length? I.e., try to set the characteristic value length of your characteristic < 20 bytes and disable DLE at first because the ATT MTU size should be 23 bytes in a standard case. See:
    https://punchthrough.com/maximizing-ble-throughput-part-2-use-larger-att-mtu-2/
  3. Then you might increase the characteristic value length to a value < 244 bytes and try again with DLE enabled because the max extended ATT MTU size is usually 247 bytes. The max extended ATT MTU size could vary among different devices but 247 is safe to count on. You need to check the ATT MTU size on both peers to determine your actual characteristic value length. In the worst case that only one peer or none peer supports DLE, then you should rather keep the characteristic value length down to 20 bytes. See:
    https://punchthrough.com/maximizing-ble-throughput-part-3-data-length-extension-dle-2/
  4. I think you shouldn't try any characteristic value length larger than 244 bytes in a Notification/Indication case because a characteristic value length larger than ATT_MTU - 3 size requires active read/write methods specific to long value pairs which rely on multiple Read/Write Response Attribute Protocol messages at a time because it's too large for one PDU to carry on. However, Notification/Indication is the passive method that can only rely on one single PDU.
    In a word, the larger characteristic length (244 - 512 bytes or any numerical value > ATT_MTU - 3) should be used with caution and you should avoid it, though it is supported by BLE in some other cases, to keep Notification/Indication working in one single PDU. See:
    https://devzone.nordicsemi.com/f/nordic-q-a/22744/maximal-notification-size-in-s132
    This restriction is also noted in the Bluetooth Specs, See:
    Charles_Lai_0-1644494407064.png

     

  5. You can also try to use a sniffer to capture the air log. Try to see if any abnormal packet was running when you face the issue.
  6. You can also try to read/write the data actively on the GATT client side, using Blob Read / Queued Write, which should give you correct access to a very large ATT value pair.

Best regards

0 Likes