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.

CC2640R2F: Multi-Role project stops advertising after App connects to it and disconnects

Part Number: CC2640R2F
Other Parts Discussed in Thread: CC2640, , BLE-STACK

Hi,

I am using the 2.40.0.32 SDK.

I am facing a weird issue. I need to ensure that only one device/App can connect to the CC2640 LP at a time. I also need connectable advertising to be continuous. To achieve this, I did the following:

1. I changed the value of MAX_NUM_BLE_CONNS to 1. This is to ensure only one active connection to the CC2640 at any given time.

2. Did some slight changes in the code where, during link establishment, it checks if connections are > than MAX_NUM_BLE_CONNS, advertising and scanning are disabled. So, I removed this code, so that the advertising is not stopped.

However, after making the above changes, I am still facing the issue.

Issue-1: For MAX_NUM_BLE_CONNS = 1, after I connect my App to the LP and disconnect, the advertising stops.

Issue-2: For MAX_NUM_BLE_CONNS = 2, after I connect one App to the LP and disconnect, the advertising continues. But if I connect the 2 Apps(two phones) to the LP at the same time, it gets connected. But after two connections established, advertising just stops.

From my analysis, somewhere, the value MAX_NUM_BLE_CONNS is affecting the advertising. I check all aspects of code but unable to find where this is happening.

Any help would be appreciated. 

Cheers

Vinay

  • Hi Vinay,

    I don't understand your application. You say you need to ensure that only one device can connect to the CC2640R2F LP at a time. You also say you need connectable advertising to be continuous.

    If your device is advertising connectable, devices can connect to it. So to me it doesn't make sense to use connectable advertising. You should use some other form of advertising. Please see the Bluetooth Scanning and Advertising SimpleLink Academy lab ( dev.ti.com/.../overview.html )
  • Ok, to clarify. What I am trying to do is. I set maxNumBleConns to 1.

    When I connect from my App to the LP. GAP_LINK_ESTABLISHED_EVENT is generated. In the GAP_LINK_ESTABLISHED_EVENT case, I add the following code to start non-connectable advertising as shown below.

    
    
                // Advertising will stop after connection formed as slave
                if ((pPkt->connRole) == GAP_PROFILE_PERIPHERAL)
                {
                    gapRole_AdvEnabled = FALSE;
                    uint8_t AdvNonConnEnabled = TRUE;
    
                    /* Turn ON Non-connectable advertising */
                    GAPRole_SetParameter(GAPROLE_ADV_NONCONN_ENABLED, sizeof(uint8_t), &AdvNonConnEnabled, NULL);
                }

    Once the App disconnects from the LP, I want to restart the connectable advertisement. And this doesn't seem to be working. I have added the below code in the GAP_LINK_TERMINATED_EVENT case to do this.

        // Connection terminated
        case GAP_LINK_TERMINATED_EVENT:
        {
            gapTerminateLinkEvent_t *pPkt = (gapTerminateLinkEvent_t *)pMsg;
    
            linkDBInfo_t pInfo;
            linkDB_GetInfo(pPkt->connectionHandle, &pInfo);
    
            // notify bond manager
            GAPBondMgr_LinkTerm(pPkt->connectionHandle);
    
            /* Turn back ON connectable advertising */
            uint8_t advertEnabled = TRUE;
            gapRole_AdvNonConnEnabled = FALSE;
            GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &advertEnabled, NULL);
    
    
            notify = TRUE;
        }

    After the above, I expect the LP to start connectable advertising which is not happening, instead, it still remains in non-connectable advertising mode.

    The main idea behind this is when the LP is in the connected state, It should still broadcast the ibeacon but not accept any connections. Once it disconnects, it should broadcast as well as accept connections.

    I hope this makes sense.

  • Hi Vinay,

    Can you try disabling non-connectable advertising  before enabling the connectable advertising? (So use GAPRole_SetParameter two times)

  • That was the first thing I had tried as shown below:

        case GAP_LINK_TERMINATED_EVENT:
        {
            gapTerminateLinkEvent_t *pPkt = (gapTerminateLinkEvent_t *)pMsg;
    
            linkDBInfo_t pInfo;
            linkDB_GetInfo(pPkt->connectionHandle, &pInfo);
    
            // notify bond manager
            GAPBondMgr_LinkTerm(pPkt->connectionHandle);
    
            /* Turn OFF the Non-connectable advertising */
            uint8_t AdvNonConnEnabled = FALSE;
            GAPRole_SetParameter(GAPROLE_ADV_NONCONN_ENABLED, sizeof(uint8_t), &AdvNonConnEnabled, NULL);
    
            /* Turn ON the connectable advertising */
            uint8_t advertEnabled = TRUE;
            GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &advertEnabled, NULL);
    
            notify = TRUE;
        }
        break;

    But it does not work i.e. After the disconnect, the LP remains in non-connectable advertising mode.

    After some trying, the below method seems to work where I call GAP_EndDiscoverable(selfEntity) on gap terminate event. Then on an end discoverable event, I re-start the advertising in connectable mode from fresh. All shown below:

    // Connection terminated
        case GAP_LINK_TERMINATED_EVENT:
        {
            gapTerminateLinkEvent_t *pPkt = (gapTerminateLinkEvent_t *)pMsg;
    
            linkDBInfo_t pInfo;
            linkDB_GetInfo(pPkt->connectionHandle, &pInfo);
    
            // notify bond manager
            GAPBondMgr_LinkTerm(pPkt->connectionHandle);
    
            /* End advertising to make a fresh start */
            GAP_EndDiscoverable(selfEntity);
            gapRole_AdvEnabled = FALSE;
            gapRole_AdvNonConnEnabled = FALSE;
    
            notify = TRUE;
        }

        // Advertising ended
        case GAP_END_DISCOVERABLE_DONE_EVENT:
        {
            /* Re-start the connectable advertising */
            uint8_t adv;
            uint8_t adv_status;
            GAPRole_GetParameter(GAPROLE_ADVERT_ENABLED, &adv_status, NULL);
            if (!adv_status)
            {
                adv = TRUE;
                GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &adv, NULL);
            }
    
        }
        break;

    The above works, but I wonder why it works this way and why not the other/actual way? 

  • Hi Vinay,

    Sorry yes this has to do with the events going back and forth between your application and the GAPRole (peripheral.c). You can try to implement callbacks from the GAP_LINK_TERMINATED_EVENT to achieve the same thing.
  • The GAPRole_createTask() has higher priority than the multi_role_createTask() task. So, the event first hits the GAP role task and then goes to the multi-role task. In your answer, you seem to just advise on implement callbacks from the GAP_LINK_TERMINATED_EVENT which doesn't help much.

    Could you please shed some light on why this will solve the above problem?

    and how to approach this solution?

    and what do the events going back and forth between the application and the GAPRole (multi.c) has anything to do with the above not working?

  • Hi Vinay,

    Events coming from the BLE-Stack (e.g. GAP_LINK_TERMINATED_EVENT) first go into the GAPRole task (multi.c). It's processed in gapRole_processGAPMsg(), then forwarded to the application thread by calling the application GAPRole callback (multi_role_eventCB, this is called by the GAPRole). Then it's posted as an event from the application to the application (multi_role_eventCB). However it's still the same message pMsg).

    The first call to GAPRole_SetParameter() transfers the control from the application task, to the GAPRole task. When the GAPRole_SetParameter() has run with GAPROLE_ADVERT_ENABLED, it will call GAP_EndDiscoverable or set an event ( START_ADVERTISING_EVT). Instead of returning to the application task, the BLE-Stack (GAP_EndDiscoverable) or the GAPRole will run (START_ADVERTISING_EVT).

    In the case of START_ADVERTISING_EVT, the GAPRole will call the BLE-Stack (GAP_MakeDiscoverable).

    GAP_EndDiscoverable will post GAP_END_DISCOVERABLE_DONE_EVENT. GAP_MakeDiscoverable will post GAP_MAKE_DISCOVERABLE_DONE_EVENT. In both cases, the event will go through the GAPRole ( gapRole_processGAPMsg) then be forwarded to the application.

    So, at this point the application task is ready to run. Do you now see that it's better call the GAPRole_SetParameter() to enable advertising after the device is done disabling advertising? I.e. in GAP_END_DISCOVERABLE_DONE_EVENT.
  • Yes indeed. Thanks.