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.

CCS/LAUNCHXL-CC2650: LaunchXL CC2650 Multi Role disconnects from phone after ~30 seconds

Part Number: LAUNCHXL-CC2650
Other Parts Discussed in Thread: CC2650

Tool/software: Code Composer Studio

Hello

I am trying to connect LaunchXL CC2650 multi role to a phone and to another multi role.

When I advertise with the multi role and connect to it from the phone, it works for around 30 seconds, in which I can read and write to my GATT profile from the phone, but after 30 seconds it disconnects.

It seems the connection is not really completed:

Advertise ->
Advertising
Connected!
Connected to 1

0x64ACBC4EEFF2
Advertising
Cxn 0 pairing started
Passcode: 123456
Cxn 0 pairing fail: 23
Connected to 0
Disconnected!

When I connect from another multi role it works fine:

Advertise ->
Advertising
Connected!
Connected to 1

0x247189084481
Advertising
Cxn 0 pairing started
Simple Svc Found
Cxn 0 pairing success
Cxn 0 bond save success

1. It seems something is missing for the phone, like an acknowledgement or something like that. Anyone?

2. How can I prevent GATT services until the connection is completed?

Thanks

Amit

  • Hi Amit,

    Based on the ability to do ATT operations and the consistent timeout, it's most likely due to a control procedure timeout.

    A sniffer capture would quickly show you which request wasn't responded too - is it possible for you to get one?

    My best guess is that it's a connection parameter update request, but that should automatically be handled for you by the GAPRole. Which version of the stack are you using?

    Regards,
    Rebel
  • Hey Rebel,

    What is a sniffer capture? How do I get it?

    The version found in icall_startup.c:
    Release Name: ble_sdk_2_02_01_18
    Release Date: 2016-10-26 15:20:04

    Thanks
    Amit
  • A sniffer capture can be done with something like a frontline BLE sniffer or Ellisys BLE sniffer - these devices capture over the air traffic and records what happened for analysis.

    If this is an timeout issue, a sniffer will capture which procedure cause the timeout (eg, if one side sends an ATT request, and the other side never sends an ATT response, this will show up)

    Regards,

    Rebel

  • Hey Rebel

    I don't have such equipment.

    I'd expect it to be a common problem. Any other ideas?

    Amit
  • A potential Option is instead of using a phone, use BTool with a launchpad as your central device.

    And try attaching the log on here? 

    A sniffer is extremely useful for BLE development - I highly recommend getting one or you'll get stuck on these issues for days.

    Regards,

    Rebel

  • Hey Rebel,

    I have tried to connect my phone to the original code of multi role and the connection also failed after 30 seconds.
    I believe there is a problem with the original code. I'd appreciate it if you could just try to connect a phone (I use BLE Scanner app) to it and see for yourself.

    Thanks
    Amit
  • Hi Amit,

    I just tried the example and had no problems connecting and remaining connected. 

    Have you taken a look at the read me? 

    Regards,

    Rebel

  • Hey Rebel,

    I have advertised with multi role, then scanned with my phone. Pressed connect on the phone, pressed the passcode (written on the UART).
    Then the connection was good for only 30 seconds. During that time I was able to use the phone to read and write to the multi role.

    Is that what you did and it worked for you?

    I did not get Cxn 0 bonding success UART message, and after 30 seconds I got this:
    Cxn 0 pairing fail: 23
    Connected to 0
    Disconnected!

    Thanks
    Amit
  • Hi Amit,

    That's exactly what I did - it worked as it should.

    Sounds like the root cause of the issue might be that your phone didn't send back a response to the pairing request?

    Again, without a log or sniffer it's difficult to say

    Regards,

    Rebel

  • Hey Rebel,

    It makes sense.
    I am using BLE Scanner, I haven't seen any definitions or settings about the response on that app.

    What app did you use on your phone?

    Thanks
    Amit
  • Hi Amit,

    I used BLE Scanner as well - I've also done BTool + host_test and had no issues

    Regards,
    Rebel
  • Hey Rebel,

    I have tried this with several phones, including Samsung, IPhone and LG and it didn't work (on the original code of the multi role).

    So I tried to uninstall BLE Scanner on my phone and re-install it, and then something weird happened:

    For the first time I've tried, there was a connection success (bond save success).

    Then I've tried again to make sure it works, but from that point on it didn't work.

    Is it possible that the phone remembers the device so after the pass code is sent the phone doesn't proceed the connection protocol?

    I think the phones are not sending the response but how come all the different phones fail?

    Thanks

    Amit

  • Anything new?
  • Hi Amit,

    There's really nothing we can do without more information at this point.

    Could you purchase a sniffer? It'd at least give us more information on where the possible failures are (and for BLE development, sniffers are essential!)

    Regards,

    Rebel

  • Hey Rebel,

    For now, what version of CCS are you using? BLE stack? Compiler? Maybe it will help

    Amit
  • Hi Amit,

    is your device stops advertising after 30 seconds or it will still advertises after the disconnection..?

    Best Regards 

    Atul

  • Hey Atul,

    The device continues to advertise after the disconnection.
    The connection drops 30 seconds after I enter the passcode on the phone.

    Thanks
    Amit
  • Hey Amit,

    Can you share the initialization part of you application...?

    Regards,
    Atul
  • Hey Atul,

    The code is the original Multi role files. This is the initialization function:

    static void multi_role_init(void)
    {
    // ******************************************************************
    // N0 STACK API CALLS CAN OCCUR BEFORE THIS CALL TO ICall_registerApp
    // ******************************************************************
    // Register the current thread as an ICall dispatcher application
    // so that the application can send and receive messages.
    ICall_registerApp(&selfEntity, &sem);

    // Create an RTOS queue for message from profile to be sent to app.
    appMsgQueue = Util_constructQueue(&appMsg);

    //init keys and LCD
    Board_initKeys(multi_role_keyChangeHandler);
    // Open Display.
    dispHandle = Display_open(SBC_DISPLAY_TYPE, NULL);

    // Setup the GAP
    {
    /*-------------------PERIPHERAL-------------------*/
    // set advertising interval the same for all scenarios
    uint16_t advInt = DEFAULT_ADVERTISING_INTERVAL;
    GAP_SetParamValue(TGAP_LIM_DISC_ADV_INT_MIN, advInt);
    GAP_SetParamValue(TGAP_LIM_DISC_ADV_INT_MAX, advInt);
    GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MIN, advInt);
    GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MAX, advInt);
    GAP_SetParamValue(TGAP_CONN_ADV_INT_MIN, advInt);
    GAP_SetParamValue(TGAP_CONN_ADV_INT_MAX, advInt);
    /*-------------------CENTRAL-------------------*/
    // set scan duration
    GAP_SetParamValue(TGAP_GEN_DISC_SCAN, DEFAULT_SCAN_DURATION);
    // scan interval and window the same for all scenarios
    GAP_SetParamValue(TGAP_CONN_SCAN_INT, DEFAULT_SCAN_INT);
    GAP_SetParamValue(TGAP_CONN_SCAN_WIND, DEFAULT_SCAN_WIND);
    GAP_SetParamValue(TGAP_CONN_HIGH_SCAN_INT, DEFAULT_SCAN_INT);
    GAP_SetParamValue(TGAP_CONN_HIGH_SCAN_WIND, DEFAULT_SCAN_WIND);
    GAP_SetParamValue(TGAP_GEN_DISC_SCAN_INT, DEFAULT_SCAN_INT);
    GAP_SetParamValue(TGAP_GEN_DISC_SCAN_WIND, DEFAULT_SCAN_WIND);
    GAP_SetParamValue(TGAP_LIM_DISC_SCAN_INT, DEFAULT_SCAN_INT);
    GAP_SetParamValue(TGAP_LIM_DISC_SCAN_WIND, DEFAULT_SCAN_WIND);
    GAP_SetParamValue(TGAP_CONN_EST_SCAN_INT, DEFAULT_SCAN_INT);
    GAP_SetParamValue(TGAP_CONN_EST_SCAN_WIND, DEFAULT_SCAN_WIND);
    // set connection parameters
    GAP_SetParamValue(TGAP_CONN_EST_INT_MIN, DEFAULT_CONN_INT);
    GAP_SetParamValue(TGAP_CONN_EST_INT_MAX, DEFAULT_CONN_INT);
    GAP_SetParamValue(TGAP_CONN_EST_SUPERV_TIMEOUT, DEFAULT_CONN_TIMEOUT);
    GAP_SetParamValue(TGAP_CONN_EST_LATENCY, DEFAULT_CONN_LATENCY);

    //register to receive GAP and HCI messages
    GAP_RegisterForMsgs(selfEntity);
    }

    // Setup the GAP Role Profile
    {
    /*--------PERIPHERAL-------------*/
    uint8_t initialAdvertEnable = TRUE;
    uint16_t advertOffTime = 0;
    uint16_t desiredMinInterval = DEFAULT_DESIRED_MIN_CONN_INTERVAL;
    uint16_t desiredMaxInterval = DEFAULT_DESIRED_MAX_CONN_INTERVAL;
    uint16_t desiredSlaveLatency = DEFAULT_DESIRED_SLAVE_LATENCY;
    uint16_t desiredConnTimeout = DEFAULT_DESIRED_CONN_TIMEOUT;

    // device starts advertising upon initialization
    GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
    &initialAdvertEnable, NULL);
    // By setting this to zero, the device will go into the waiting state after
    // being discoverable for 30.72 second, and will not being advertising again
    // until the enabler is set back to TRUE
    GAPRole_SetParameter(GAPROLE_ADVERT_OFF_TIME, sizeof(uint16_t),
    &advertOffTime, NULL);
    // set scan response data
    GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData),
    scanRspData, NULL);
    // set advertising data
    GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData, NULL);
    // set connection parameters
    GAPRole_SetParameter(GAPROLE_MIN_CONN_INTERVAL, sizeof(uint16_t),
    &desiredMinInterval, NULL);
    GAPRole_SetParameter(GAPROLE_MAX_CONN_INTERVAL, sizeof(uint16_t),
    &desiredMaxInterval, NULL);
    GAPRole_SetParameter(GAPROLE_SLAVE_LATENCY, sizeof(uint16_t),
    &desiredSlaveLatency, NULL);
    GAPRole_SetParameter(GAPROLE_TIMEOUT_MULTIPLIER, sizeof(uint16_t),
    &desiredConnTimeout, NULL);
    /*--------------CENTRAL-----------------*/
    uint8_t scanRes = DEFAULT_MAX_SCAN_RES;
    //set the max amount of scan responses
    GAPRole_SetParameter(GAPROLE_MAX_SCAN_RES, sizeof(uint8_t),
    &scanRes, NULL);

    // Start the GAPRole and negotiate max number of connections
    VOID GAPRole_StartDevice(&multi_role_gapRoleCBs, &maxNumBleConns);

    //allocate memory for index to connection handle map
    if (connHandleMap = ICall_malloc(sizeof(uint16_t) * maxNumBleConns))
    {
    // init index to connection handle map to 0's
    for (uint8_t i = 0; i < maxNumBleConns; i++)
    {
    connHandleMap[i] = INVALID_CONNHANDLE;
    }
    }

    //allocate memory for per connection discovery information
    if (discInfo = ICall_malloc(sizeof(discInfo_t) * maxNumBleConns))
    {
    // init index to connection handle map to 0's
    for (uint8_t i = 0; i < maxNumBleConns; i++)
    {
    discInfo[i].charHdl = 0;
    discInfo[i].discState = BLE_DISC_STATE_IDLE;
    discInfo[i].svcEndHdl = 0;
    discInfo[i].svcStartHdl = 0;
    }
    }
    }

    //GATT
    {
    /*---------------------SERVER------------------------*/
    // Set the GAP Characteristics
    GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName);

    // Initialize GATT Server Services
    GGS_AddService(GATT_ALL_SERVICES); // GAP
    GATTServApp_AddService(GATT_ALL_SERVICES); // GATT attributes
    DevInfo_AddService(); // Device Information Service
    SimpleProfile_AddService(GATT_ALL_SERVICES); // Simple GATT Profile

    // Setup Profile Characteristic Values
    {
    uint8_t charValue1 = 1;
    uint8_t charValue2 = 2;
    uint8_t charValue3 = 3;
    uint8_t charValue4 = 4;
    uint8_t charValue5[SIMPLEPROFILE_CHAR5_LEN] = { 1, 2, 3, 4, 5 };

    SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR1, sizeof(uint8_t),
    &charValue1);
    SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR2, sizeof(uint8_t),
    &charValue2);
    SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR3, sizeof(uint8_t),
    &charValue3);
    SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, sizeof(uint8_t),
    &charValue4);
    SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR5, SIMPLEPROFILE_CHAR5_LEN,
    charValue5);
    }

    // Register callback with SimpleGATTprofile
    SimpleProfile_RegisterAppCBs(&multi_role_simpleProfileCBs);

    /*-----------------CLIENT------------------*/
    // Initialize GATT Client
    VOID GATT_InitClient();

    // Register for GATT local events and ATT Responses pending for transmission
    GATT_RegisterForMsgs(selfEntity);

    // Register to receive incoming ATT Indications/Notifications
    GATT_RegisterForInd(selfEntity);
    }

    // Setup the GAP Bond Manager
    {
    uint8_t pairMode = GAPBOND_PAIRING_MODE_INITIATE;
    uint8_t mitm = TRUE;
    uint8_t ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;
    uint8_t bonding = TRUE;

    // set pairing mode
    GAPBondMgr_SetParameter(GAPBOND_PAIRING_MODE, sizeof(uint8_t), &pairMode);
    // set authentication requirements
    GAPBondMgr_SetParameter(GAPBOND_MITM_PROTECTION, sizeof(uint8_t), &mitm);
    // set i/o capabilities
    GAPBondMgr_SetParameter(GAPBOND_IO_CAPABILITIES, sizeof(uint8_t), &ioCap);
    // set bonding requirements
    GAPBondMgr_SetParameter(GAPBOND_BONDING_ENABLED, sizeof(uint8_t), &bonding);

    // Register and start Bond Manager
    VOID GAPBondMgr_Register(&multi_role_BondMgrCBs);
    }

    Display_print0(dispHandle, 0, 0, "Scan ->");
    Display_print0(dispHandle, 0, 0, "<- Next Option");
    }

    As I've mentioned before, the pairing is started when I press connect from the phone, and then I am requested to type the passcode on the phone.
    The pairing fails exactly 30 seconds after I type the passcode on the phone.
    During this time I am capable of doing read\write to the simple profile characteristics in the multi role (I'd expect the program to prevent that for as long as the connection is not complete).

    Connections between 2 multi role units (without any phone involved) works fine though.

    If there are other parts of the code you'd like me to share here just let me know.

    Thanks
    Amit

  • Hey Amit,

    i Wanted to see the initialization at the top where libraries and predecessor's are defined..!
  • This is the multi_role.c file, the original version from the BLE examplesmulti_role.c

  • Anyone?

    This is extremely absurd.

    I've been working on the LaunchXL CC2650 for the past months, facing a lot of issues and way too many problems but this one is by far the most annoying. And there haven't been any progress on it or any solution from TI since I've opened this thread on 3rd July (!)

    Connecting the launch pad from the phone is supposed be the most basic feature of the program, yet it doesn't work properly on the Multi Role. Using the original Code!

    I'd appreciate if anyone from TI can please try to:

    1. Upload the Multi Role code on the LaunchXL CC2650 unit

    2. Connect to it from the phone (with BLE Scanner) and insert the Pass Code.

    3. Wait more than 30 seconds, making sure it doesn't disconnect.

    4. Turn it all off.

    5. If there were no problems, repeat and connect again for the 2nd time, to make sure it works.

    If it worked, please post here the version of CCS you have used, compiler version, which BLE Scanner program you used, and which phone did you use.

    Thanks

    Amit

  • Hi Amit,

    Can you try it By commenting the passcode section once...?

    Regards
    Atul
  • Hey Atul,

    I've commented line 945 in the code

     case MR_PASSCODE_NEEDED_EVT:

    //    multi_role_processPasscode((gapPasskeyNeededEvent_t*)pMsg->pData);    // 14.8.17

       ICall_free(pMsg->pData);

       break;

    This is the putty output:

    It connected (without any other messages about the bond etc.) and then disconnected after 30 seconds.

    Thanks

    Amit

  • Hi Amit,

    I just tried it again, no problems on my end -

    CCS Version: 7.2.0.00013 (This shouldn't matter, as long as it supports TI ARM Compiler v5.2.6 )

    TI ARM Compiler: v5.2.6

    For the phone, I used an HTC One m8 running BLE Scanner v3.12

    Again, I highly recommend getting a BLE sniffer capture of the connection. You're shooting in the dark until you can find out what's really going on - effectively wasting your time!

    Regards,

    Rebel