This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2541: Android Connection Issues

Part Number: CC2541
Other Parts Discussed in Thread: BLE-STACK

Customer is having problems connecting to newer Android phones using CC2541 running SDK 1.2.1.  The CC2541 is configured as a BLE peripheral connecting to a phone or tablet acting as the central.  We've suggested migrating to SDK v1.4.2 as there were improvements made to pairing with newer Android devices.  Specifically “TI recommends using BLE-Stack v1.4.1 or later to ensure pairing compatibility with Android 6.0 (Marshmallow) devices”.  Included below are details on the failure.  Do you think migrating to SDK 1.4.1 will resolve the issue?  Any other suggestions?

Customer problem analysis below:
We've traced the root cause of customers Android-specific connection issues to the LL_ProcessEvent task being blocked and missing multiple connection events and therefore the CC2541 discards the connection and a GAP_LINK_TERMINATED_EVENT happens with an error code of LL_STATUS_ERROR_CONN_FAILED_TO_BE_ESTABLISHED. This behavior seems to match the "Limit Application Processing During BLE Activity" section from the CC2541 Software Developer's Reference Guide (section 7.2.6).

However, after further investigation into exactly which task is causing the issue we were a little surprised and we're curious if this is an issue lots of devices are running into on Android. It turns out that the GAPBondMgr_ProcessEvent task is blocking the processor for multiple connection events even though the aforementioned 'Limit Application Processing During BLE Activity' seems to insinuate the TI stack layers are set up to avoid this issue (unless I am just misunderstanding the text). Regardless, the Bond Manager task blocks for ~20 ms right after the customer Android app automatically and immediately subscribes to notifications on a characteristic, and while the connection interval is still only 7.5 ms (which is automatically and unavoidably set by Android during GATT Service Discovery). This is exactly when the LL_ProcessEvent is starved and the connection termination happens. The duration of the Bond Manager task blocking is directly related to the size of the Bonded Device list (GAP_BONDINGS_MAX) and firmware was set to the seemingly default value of 10. The CC2541 firmware is configured to allow pairing and bonding but never initiates it, nor does it's GATT database have any permissions that would require pairing so we do not need the Bonded Device list at all. The vast majority of time spent in this Bond Manager task is apparently due to reading from internal flash GAP_BONDINGS_MAX number of times in gapBondMgrResolvePrivateAddr in gapbondmgr.c.

Here are some of my questions:

  • Does this identification of this as the core issue make sense to you guys? Have others run up against this exact same issue? I see on the forums others have hit this same LL_ProcessEvent starvation issue but usually due to excessive UART communication and logging in their own application blocking the OS.
  • Should the GAP Bond Manager task, as part of the TI SDK/stack, be allowed to block the Link Layer task and cause this connection failure or is this something the application developer needs to modify TI stack code to protect itself against?
  • Reducing the size of the Bonded Device list from 10 to 1 seems to eradicate the problem since the processing/blocking time is reduced from ~20 ms to ~2ms, which gives the Link Layer task enough time to process connection events even when the connection interval is at the minimum of 7.5 ms. However, if we do not need security at all, what is the best way to remove this altogether with as little TI stack modification as possible? Setting GAP_BONDINGS_MAX to 0 results in compilation errors, but is doing that and resolving those errors the best approach? Is there a single API we can remove safely to rid ourselves of any unnecessary Bond Manager code? We still need the GAP Bond Manager task in some fashion correct?

I can provide more context or detail and logic analyzer captures with task and radio timing to illustrate the exact behavior in failure and success cases if needed to better understand the issue, just let me know!

Thanks,
Mark

  • Hello Mark,
    Let me investigate. I glanced at the the release notes for version 1.4.0 which state:
    - Bonding was unstable at short connection intervals. This is now fixed.

    I will dig for more details to verify if this will fix your described issue. We advice the customer to upgrade to the latest (BLE-CC254x-1.4.2.2).
  • Hello Mark,
    I have read through this once more and if I understand you correctly they do not need Bonding or security at all, correct?
    Or is security initiated on each connection?

    There is no available API to remove the GAP Bond Manager which would be needed to remove manually. I will check with some colleagues that will be back from holiday this week with regards advice on the best approach to remove this.

    Did they measure the duration of gapBondMgrResolvePrivateAddr?
    Is it called multiple times immediately after the connection is formed?
  • Hi Eirik,

    Customer is not using security.

    Will advise on duration of gapBondMgrResolvePrivateAddr.

    Regards,
    Mark

  • Hello Mark,
    The time it takes to run osal_snv.c::findItem will increase with the number of items stored in SNV. Also if the SNV page is almost full, it is more likely that a forced ‘compaction’ will occur, where valid items are copied from PG1 to PG2 and PG1 is erased. Erasing takes ~20ms and locks the CPU completely. There are suggested improvements for the findItem() function in the porting guide for BLEv1.x:
    processors.wiki.ti.com/.../LPRF_BLE_Porting_Projects

    The compaction issue is solved in Version 1.3.1.
    Excerpt from release note:
    Version 1.3.1
    April 18, 2013

    - During bonding, connection failures would occasionally occur due to the
    OSAL Simple NV driver performing a page compaction and halting the CPU for
    longer than the time required for the link layer to maintain proper
    connection timing. To prevent this from occurring, the simple NV driver now
    has any API to force a page compaction if the page is full beyond a specified
    threshold. The bond manager calls this API every time a connection is
    terminated to ensure that compaction occurs before the next connection is set
    up.

    Refer to osal_snv_compact() in BLEv1.3 or later that is called on each link termination in GAPBondMgr_LinkTerm().

    The complete list of CC254x release notes is here:
    processors.wiki.ti.com/.../CC254X_Release_Notes