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.

BLE still in advertising state when connected to central in CC2650DK HeartRate example

Expert 1340 points
Other Parts Discussed in Thread: CC2650

I see some odd behavior in that when the CC2650 (peripeheral) is connected (to a central), GAPRole_GetParameter(GAPROLE_ADVERT_ENABLED, &advState); returns advState==1. This is proven by:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
static void HeartRate_stateChangeEvt(gaprole_States_t newState)
{
  // If no change to the GAP Role state has occurred
  if (gapProfileState == newState)
  {
    return;
  }
  // If connected
  if (newState == GAPROLE_CONNECTED)
  {
    // Get connection handle.
    GAPRole_GetParameter(GAPROLE_CONNHANDLE, &gapConnHandle);
    PINCC26XX_setOutputValue(Board_LED1, 0);
    configSensors();
    // FIXME
    uint8_t advState;
    GAPRole_GetParameter(GAPROLE_ADVERT_ENABLED, &advState);
    if (advState)
        PINCC26XX_setOutputValue(Board_LED2, 1);
    //END FIXME
  }
  // If disconnected
  else if (gapProfileState == GAPROLE_CONNECTED &&
           newState != GAPROLE_CONNECTED)
  {
    // Stop periodic measurement of heart rate.
//    Util_stopClock(&measPerClock);
//    TIADS1298_stop();
    // FIXME
    uint8_t advState;
    GAPRole_GetParameter(GAPROLE_ADVERT_ENABLED, &advState);
    if (advState)
        PINCC26XX_setOutputValue(Board_LED3, 1);
    //END FIXME
    if (newState == GAPROLE_WAITING_AFTER_TIMEOUT)
    {
      // Link loss timeout-- use fast advertising
      GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MIN, DEFAULT_FAST_ADV_INTERVAL);
      GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MAX, DEFAULT_FAST_ADV_INTERVAL);
      GAP_SetParamValue(TGAP_GEN_DISC_ADV_MIN, DEFAULT_FAST_ADV_DURATION);
    }
    else
    {
      // Else use slow advertising
      GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MIN, DEFAULT_SLOW_ADV_INTERVAL);
      GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MAX, DEFAULT_SLOW_ADV_INTERVAL);
      GAP_SetParamValue(TGAP_GEN_DISC_ADV_MIN, DEFAULT_SLOW_ADV_DURATION);
    }
    // Enable advertising.
    HeartRate_toggleAdvertising();  // FIXME advstate is true (even though it's not advertising; why?) when this is called, so advertising doesn't start
  }
...
}

In these two if and if-else sections, the LEDs become lit when I connect and disconnect from the device, and the last HeartRate_toggleAdvertising() does not restart advertising since advState==1 when HeartRate_toggleAdvertising() is enetered. Please clarify why this is the case. Thanks!

I'm back to looking at this advertising issue and am able to properly step through and hit breakpoints now (I disable optimizations, but not sure if that would be why it's working now). Anyhow I still see some odd behavior in that when the CC2650 is connected, GAPRole_GetParameter(GAPROLE_ADVERT_ENABLED, &advState); returns advState==1. This is proven by:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
static void HeartRate_stateChangeEvt(gaprole_States_t newState)
{
  // If no change to the GAP Role state has occurred
  if (gapProfileState == newState)
  {
    return;
  }
  // If connected
  if (newState == GAPROLE_CONNECTED)
  {
    // Get connection handle.
    GAPRole_GetParameter(GAPROLE_CONNHANDLE, &gapConnHandle);
    PINCC26XX_setOutputValue(Board_LED1, 0);
    configSensors();
    // FIXME
    uint8_t advState;
    GAPRole_GetParameter(GAPROLE_ADVERT_ENABLED, &advState);
    if (advState)
        PINCC26XX_setOutputValue(Board_LED2, 1);
    //END FIXME
  }
  // If disconnected
  else if (gapProfileState == GAPROLE_CONNECTED &&
           newState != GAPROLE_CONNECTED)
  {
    // Stop periodic measurement of heart rate.
//    Util_stopClock(&measPerClock);
//    TIADS1298_stop();
    // FIXME
    uint8_t advState;
    GAPRole_GetParameter(GAPROLE_ADVERT_ENABLED, &advState);
    if (advState)
        PINCC26XX_setOutputValue(Board_LED3, 1);
    //END FIXME
    if (newState == GAPROLE_WAITING_AFTER_TIMEOUT)
    {
      // Link loss timeout-- use fast advertising
      GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MIN, DEFAULT_FAST_ADV_INTERVAL);
      GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MAX, DEFAULT_FAST_ADV_INTERVAL);
      GAP_SetParamValue(TGAP_GEN_DISC_ADV_MIN, DEFAULT_FAST_ADV_DURATION);
    }
    else
    {
      // Else use slow advertising
      GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MIN, DEFAULT_SLOW_ADV_INTERVAL);
      GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MAX, DEFAULT_SLOW_ADV_INTERVAL);
      GAP_SetParamValue(TGAP_GEN_DISC_ADV_MIN, DEFAULT_SLOW_ADV_DURATION);
    }
    // Enable advertising.
    HeartRate_toggleAdvertising();  // FIXME advstate is true (even though it's not advertising; why?) when this is called, so advertising doesn't start
  }
...
}

In these two if and if-else sections, the LEDs become lit when I connect and disconnect from the device, and the last HeartRate_toggleAdvertising() does not restart advertising since advState==1 when HeartRate_toggleAdvertising() is enetered. Please clarify why this is the case. Thanks!

  • Hi Tosa,

    It's important to note that GAPROLE_ADVERT_ENABLED and GAPROLE_state are not the same. The former is used to inform the stack that the App wants to (or disable) Advertise. Whether the device actually advertises is based on the GAPROLE_state. You can easily trace this logic in the GAPRole task (peripheral.c). Refer to use of the 'gapRole_AdvEnabled' state variable.

    Best wishes
  • I understand that GAPROLE_ADVERT_ENABLED used in GAPRole_SetParameter() can start advertising:

    case GAPROLE_ADVERT_ENABLED:
          if (len == sizeof(uint8_t))
          {
            // Non-connectable advertising must be disabled.
            if (gapRole_AdvNonConnEnabled != TRUE)
            {
              uint8_t oldAdvEnabled = gapRole_AdvEnabled;
              gapRole_AdvEnabled = *((uint8_t*)pValue);
    
              if ((oldAdvEnabled) && (gapRole_AdvEnabled == FALSE))
              {
                // Turn off advertising.
                if ((gapRole_state == GAPROLE_ADVERTISING)
                    || (gapRole_state == GAPROLE_WAITING_AFTER_TIMEOUT))
                {
                  VOID GAP_EndDiscoverable(selfEntity);
                }
              }
              else if ((oldAdvEnabled == FALSE) && (gapRole_AdvEnabled))
              {
                // Turn on advertising.
                if ((gapRole_state == GAPROLE_STARTED)
                    || (gapRole_state == GAPROLE_WAITING)
                    || (gapRole_state == GAPROLE_WAITING_AFTER_TIMEOUT))
                {
                  gapRole_setEvent(START_ADVERTISING_EVT);
                }
              }
            }

    What I don't understand is why GAPROLE_ADVERT_ENABLED used in GAPRole_GetParameter() returns true when the CC2650 has gone to the connected state:

    if (newState == GAPROLE_CONNECTED)
      {
        // Get connection handle.
        GAPRole_GetParameter(GAPROLE_CONNHANDLE, &gapConnHandle);
        PINCC26XX_setOutputValue(Board_LED1, 0);
        configSensors();
        // FIXME
    	uint8_t advState;
    	GAPRole_GetParameter(GAPROLE_ADVERT_ENABLED, &advState);
    	if (advState)
    		PINCC26XX_setOutputValue(Board_LED2, 1);
    	//END FIXME
      }

    It seems that the state variable gapRole_AdvEnabled in Peripheral.c is not updated when the CC2650 goes to connection mode. The CC2650 is no longer advertising when connected right?

  • Correct, it is not updated by design; advertising stops as soon as the connection is formed. This behavior is as per the BT Core Specification. You can confirm likewise on a air sniffer.

    The state variable gapRole_AdvEnabled is used to control when / if Adv should resume after the connection ends, and thus does not reflect if the device is advertising or not.

    Best wishes