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: CC2541 Central - Disconnecting Multiple Devices - connHandle change?

Part Number: CC2541

Tool/software:

Just wondering if anyone can confirm or helps with this.

We've had a design for while which operates as a CENTRAL and can connect up to 3 peripherals.

I been working on this build again recently trying to improve connect / disconnect.

One strange thing I've been looking at, is working through disconnect of all three peripherals. This has always been very strange,
with the third disconnect behaving differently and taking a long time.

Normally three device connected, with connHandle 0, 1, 2 assigned. These I use to reference each device and store in an array at connection time.

If I disconnect each in sequence.

0 -> 1 -> 2, the first two would Terminate with Terminate Req status 0x16 

all good :- #define LL_STATUS_ERROR_HOST_TERM                      0x16 // Connection Terminated By Local Host

the third would also take a long time and Terminate with Terminate Req 0x22

#define LL_STATUS_ERROR_LL_TIMEOUT 0x22 // Link Layer Response Timeout
#define LL_STATUS_ERROR_LL_TIMEOUT_HOST 0x22 // Link Layer Response Timeout
#define LL_STATUS_ERROR_LL_TIMEOUT_PEER 0x22 // Link Layer Response Timeout

I tried big delays between the sequence (thinking the stack was congested or something) - but even 5 seconds disconnect gaps made no difference.

Then today I tried this:

Disconnect in reverse sequence

2->1->0

This work fine and would run fast, always with Terminate Req 0x16  (Happy days!)

But is made me think, is there by some chance the BLE Stack is re-configuring connHandle's once the first is Disconnected.

This would explain why using connHandle 2 as third in the sequence always did something different?

Hence if I use sequence 0..1..2

When 0 disconnects. The remaining valid connhandles are actually to 0..1

When 1 disconnects. The remaining valid connhandle is 0

So my disconnect 2 now doesn't reference a valid connHandle.

But thus, doing it in the other direction is fine.

I sort of need to understand the workings here so I can manage correctly if one of the peripherals disconnects, do I need to correct all my connHandles which I use
to communicate with each peripheral.

Any support / answers appreciated. Can't find any info on this elsewhere :-(

Rob

  • Hi Rob !

    Are you using GAP_TerminateLinkReq to disconnect the peripherals ? Could you maybe show the snippet of code used to disconnect the peripherals ? Thanks a lot !

    Kind regards,
    Maxence

  • Hi Maxence,

    Well using GAPCentralRole_TerminateLink()   which then calls..  GAP_TerminateLinkReq()

    /**
    * @brief Terminate a link.
    *
    * Public function defined in central.h.
    */
    bStatus_t GAPCentralRole_TerminateLink( uint16 connHandle )
    {
    return GAP_TerminateLinkReq( gapCentralRoleTaskId, connHandle, HCI_DISCONNECT_REMOTE_USER_TERM ) ;
    }

    Heres my code. Where mvrDevices[id].connHandle is a copy of the connGandle when the connection was made.


    bStatus_t MVR_DeviceDisconnect( uint8 id )
    {
      bStatus_t result;
      result = FAILURE;

      if( mvrDevices[id].BLEState != BLE_STATE_IDLE && mvrDevices[id].BLEState != BLE_STATE_DISCONNECTING )
      {
         mvrDevices[id].BLEState = BLE_STATE_DISCONNECTING;
         result = GAPCentralRole_TerminateLink( mvrDevices[id].connHandle );
         _DEBUG_PRINT("H%d) T LINK - cHandle %d STATUS %d\n\r", id, mvrDevices[id].connHandle, result);
      }
      else
      {
         _DEBUG_PRINT("H%d) cHandle %d CANT DISC?? STATE\n\r", id, mvrDevices[id].connHandle, mvrDevices[id].BLEState );
      }

      return result ;

    }

    My Debug printing on terminal. (Disconnnect order 0-1-2)

    Disconnect Devices
    D0
    H0) T LINK - cHandle 0 STATUS 0
    H0) Terminate Rq 16
    H0) Terminate Event
    H0) Cleanup
    D1
    H1) T LINK - cHandle 1 STATUS 0
    H1) Terminate Rq 16
    H1) Terminate Event
    H1) Cleanup
    D2
    H2) T LINK - cHandle 2 STATUS 0  (Big delay after the Terminate has been sent, to the Terminate Rq22 being received) Like the connhandle wasn't valid.
    H2) Terminate Rq 22
    H2) Terminate Event
    H2) Cleanup

    My Debug printing on terminal. (Disconnect order 2-1-0 - works every time!)

    Disconnect Devices
    D2
    H2) T LINK - cHandle 2 STATUS 0
    H2) Terminate Rq 16
    H2) Terminate Event
    H2) Cleanup
    D1
    H1) T LINK - cHandle 1 STATUS 0
    H1) Terminate Rq 16
    H1) Terminate Event
    H1) Cleanup
    D0
    H0) T LINK - cHandle 0 STATUS 0
    H0) Terminate Rq 16
    H0) Terminate Event
    H0) Cleanup

    Best Regards


    Rob

  • Hi !

    Could you please tell me which SDK are you using ?

    Kind regards,
    Maxence

  • Hi,

    If you are disconnecting all handles at the same time, could you try to disconnect them all by calling GAPCentralRole_TerminateLink(GAP_CONNHANDLE_ALL) and tell me if there's still a delay ?

    Thank you,
    Maxence

  • Latest Version 1.5.20

  • Thats not exactly what I need to be able to do going forward. But I can try this also.

  • Also the issue with using GAP_CONNHANDLE_ALL, whilst it does disconnect all devices, the received  TERMINATE LINK RQ through the stack
    indicates the highest handle was dsiconnect: H2 - where 2 is the connHandle recieved.

    Hence this doesn't allow me to do a clean up for each individual device I have.

    Disconnect Devices
    ALL) T LINK ALL STATUS 0
    H2) Terminate Rq 16
    H2) Terminate Event
    H2) Cleanup

  • Hi !

    Could you provide sniffer logs of the events so we can try debugging it ? The SDK used is a bit old so it's difficult to actually find the root of the problem.

    Kind regards,
    Maxence

  • Hi Maxence,

    FYI - I am working on getting you some logs. 

    At the moment, what I have seen is the in the disconnect order which fails 0-1-2, it looks like the 3rd LL_TERMINATE Packet never gets sent.

    Just waiting of getting a 3rd sniffer board running to have all 3 three devices capture simultaneously.

    Br

    Rob

  • Hi Maxence,

    Is there a way I can send the sniffer logs direct to you - I don't want to share the contents on the forum as it contains our custom interface protocol.

    Br

    Rob

  • Hi,

    You can send the logs.

  • Hi Maxence,

    Did you receive the logs I sent via email?

    Br

    Rob

  • Hi,

    Yes I recieved them, but I can't seem to be able to read them with wireshark. What parser are you using to read the logs ?

    Kind regards,
    Maxence

  • Not sure if this helps but these are the plug ins setup for wireshark.

    We had to use the Nordic Sniffer setup, as the old TI Dongles didn't work reliably for connecting 3 channels.

    I didn;t set this up myself but if you provide more specific info you need I can find out.

    Br

    Rob

  • Hi,

    I'm going to try to reproduce the Nordic sniffer setup to read your sniffer logs and see if I can send it to our engineers. As the CC2541 is an older device, it's likely that the bug will take a lot of time to be resolved and for the patch to be released in the official SDK. In the mail you sent me, you mention that you've been working with the newer CC2340 devices, and I encourage you to continue in that direction, as this is your best bet to have an up-to-date BLE stack.

    In the meanwhile, using GAPCentralRole_TerminateLink(GAP_CONNHANDLE_ALL) and cleaning up all devices in your mvrDevices array might be your best solution.

    Kind regards,
    Maxence

  • Hi Maxence,

    I have a further question relating to this - as I've been looking through the captures. What seems to occur is the Central just stops the empty connection interval packets at some point.

    I can see our peripherals request a connection interval update of 15ms - 75ms. This is not processed by the Central, and the Central seems to default the connection interval to 100ms. ( I can't find where this is setup in the CC2541 Central source code headers ) - Do you know how this can be changed. 

    I am wondering if my Central can only run at 100ms, then 3 peripherals are connected who's maximum connection interval is 75ms. How should this be managed. I have read on some posts that maybe the Central should in this case run 3x faster than the slowest desired peripheral connection interval - hence 25ms. Can the central only connect to one device in a single connection interval. FYI, there is no slave latency implemented either.

    Could this possible by why in some cases especially with multiple devices connection drops out?

    PS. We won't be bringing the CC2340 online for some time as currently have 7 products in market with CC2541. I do need to stabilise this 3 connection systems.

    Best Regards


    Rob

  • Hi,

    In the simple BLE central example (located at C:\Texas Instruments\BLE-CC254x-1.5.2.0\Projects\ble\SimpleBLECentral), the connection interval settings are in the simpleBLECentral.c file and defined with the DEFAULT_UPDATE_MIN_CONN_INTERVAL and DEFAULT_UPDATE_MAX_CONN_INTERVAL macros. Those macros are used in the GAPCentralRole_UpdateLink function. You could see what parameters your project use for this function.

    If your interval connection is too high then it might cause problems. In a singular connection, the Bluetooth parameter handshake allows the central and the peripheral to both agree on a connection interval that work for both of them, but I don't know how this is done in multiple simultaneous BLE connections. You could try reducing this number and test it to see if it works.

    Kind regards,
    Maxence