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.

CC2642R: Directed Adv with public address issue, SDK 2.40.00.81

Part Number: CC2642R
Other Parts Discussed in Thread: CC2652R

Hi,

 

it looks like that there is problem when using directed advertisement with public address.

If the first two bits of the address are zero, GapAdv_enable(Handle, GAP_ADV_ENABLE_OPTIONS_USE_MAX, 0) will return with error code 18 (bleIncorrectMode). The address type is PEER_ADDRTYPE_PUBLIC_OR_PUBLIC_ID.

For me it looks like that stack is analyzing these two bits although address type is PEER_ADDRTYPE_PUBLIC_OR_PUBLIC_ID.

As soon as an address is used that have any of these two bits is set to 1, the error is gone.

 

Cheers.........tobias.

  • Hi Tobias,

    I am not able to reproduce, I just get a lot of success. Can you provide some steps to reproduce with simple_central / simple_peripheral?

    Best regards,
    Aslak
  • Hi Aslak,

    I have attached patches for simple_peripheral example that is included in SDK 2.40.00.81 and a Ellisys capture that shows the pairing of my Intel chip with the Launchpad CC2652R.

    The GapBondMgr has two new properties that enable the read of the bonding address as well as the bonding address type.

    The application is changed so that directed advertisement is used after reset whenever a bonding is available.

    When GapAdv_enable() is called for directed advertisement, it'll return with 0x12 (=bleIncorrectMode).

    Simple peripheral is configured to ADDRMODE_PUBLIC and the peerAddrType is public, too (I verified in debugger).

    --- F:\ti\simplelink_cc13x2_26x2_sdk_2_40_00_81_original\examples\rtos\CC26X2R1_LAUNCHXL\ble5stack\simple_peripheral\src\app\simple_peripheral.c	Fri Jan 18 18:12:10 2019 UTC
    +++ F:\ti\simplelink_cc13x2_26x2_sdk_2_40_00_81\examples\rtos\CC26X2R1_LAUNCHXL\ble5stack\simple_peripheral\src\app\simple_peripheral.c	Fri Mar 22 10:37:50 2019 UTC
    @@ -103,7 +103,7 @@
     // Note: When using the DEFAULT_ADDRESS_MODE as ADDRMODE_RANDOM or 
     // ADDRMODE_RP_WITH_RANDOM_ID, GAP_DeviceInit() should be called with 
     // it's last parameter set to a static random address
    -#define DEFAULT_ADDRESS_MODE                  ADDRMODE_RP_WITH_PUBLIC_ID
    +#define DEFAULT_ADDRESS_MODE                  ADDRMODE_PUBLIC
     
     // General discoverable mode: advertise indefinitely
     #define DEFAULT_DISCOVERABLE_MODE             GAP_ADTYPE_FLAGS_GENERAL
    @@ -1100,6 +1100,10 @@
     
             Display_printf(dispHandle, SP_ROW_STATUS_1, 0, "Initialized");
     
    +
    +        uint8_t bondCnt = 0;
    +        GAPBondMgr_GetParameter(GAPBOND_BOND_COUNT, &bondCnt);
    +
             // Setup and start Advertising
             // For more information, see the GAP section in the User's Guide:
             // http://software-dl.ti.com/lprf/ble5stack-latest/
    @@ -1108,6 +1112,21 @@
             // by the GapAdv module
             GapAdv_params_t advParamLegacy = GAPADV_PARAMS_LEGACY_SCANN_CONN;
     
    +        // Use directed advertisement if bonding is available
    +        if(bondCnt)
    +        {
    +            // Get address of bonded peer device
    +            uint8_t addr[B_ADDR_LEN * GAP_BONDINGS_MAX];
    +            GAP_Peer_Addr_Types_t addrType[GAP_BONDINGS_MAX];
    +            GAPBondMgr_GetParameter(GAPBOND_DIRECTED_ADV_ADDR, addr);
    +            GAPBondMgr_GetParameter(GAPBOND_DIRECTED_ADV_ADDRTYPE, addrType);
    +
    +            advParamLegacy.eventProps = GAP_ADV_PROP_DIRECTED | GAP_ADV_PROP_HDC | GAP_ADV_PROP_CONNECTABLE | GAP_ADV_PROP_LEGACY;
    +            advParamLegacy.peerAddrType = addrType[0];
    +            memcpy(advParamLegacy.peerAddr, addr, B_ADDR_LEN);
    +            advParamLegacy.filterPolicy = GAP_ADV_WL_POLICY_ANY_REQ;
    +        }
    +
             // Create Advertisement set #1 and assign handle
             status = GapAdv_create(&SimplePeripheral_advCallback, &advParamLegacy,
                                    &advHandleLegacy);
    
    --- F:\ti\simplelink_cc13x2_26x2_sdk_2_40_00_81_original\source\ti\ble5stack\host\gapbondmgr.c	Fri Jan 18 18:12:10 2019 UTC
    +++ F:\ti\simplelink_cc13x2_26x2_sdk_2_40_00_81\source\ti\ble5stack\host\gapbondmgr.c	Fri Mar 22 09:51:39 2019 UTC
    @@ -911,6 +911,28 @@
           *((uint8_t *)pValue) = gapBond_removeLRUBond;
           break;
     
    +    case GAPBOND_DIRECTED_ADV_ADDR:
    +    {
    +      uint8_t *dst = ((uint8_t *)pValue);
    +      for (int_fast8_t idx = 0; idx < GAP_BONDINGS_MAX; idx++)
    +      {
    +        osal_memcpy(dst, bonds[idx].addr, B_ADDR_LEN);
    +        dst += B_ADDR_LEN;
    +      }
    +      break;
    +    }
    +
    +    case GAPBOND_DIRECTED_ADV_ADDRTYPE:
    +    {
    +      uint8_t *dst = ((uint8_t *)pValue);
    +      for (int_fast8_t idx = 0; idx < GAP_BONDINGS_MAX; idx++)
    +      {
    +        osal_memcpy(dst, &bonds[idx].addrType, sizeof(GAP_Peer_Addr_Types_t));
    +        dst += sizeof(GAP_Peer_Addr_Types_t);
    +      }
    +      break;
    +    }
    +
         default:
           ret = INVALIDPARAMETER;
           break;
    
    
    
    --- F:\ti\simplelink_cc13x2_26x2_sdk_2_40_00_81_original\source\ti\ble5stack\inc\gapbondmgr.h	Fri Jan 18 18:12:10 2019 UTC
    +++ F:\ti\simplelink_cc13x2_26x2_sdk_2_40_00_81\source\ti\ble5stack\inc\gapbondmgr.h	Fri Mar 22 07:11:01 2019 UTC
    @@ -321,6 +321,19 @@
     #define GAPBOND_LRU_BOND_REPLACEMENT  0x418
     
     /**
    + * @brief Get directed advertise address
    + *
    + * Returns the directed advertise address for bonding stored at the index.
    + *
    + * size: uint8_t[B_ADDR_LEN * GAP_BONDINGS_MAX]
    + *
    + * default: NULLed array
    + *
    + * range:
    + */
    +#define GAPBOND_DIRECTED_ADV_ADDR     0x419
    +
    +/**
      * Erase Local NV Info (Write-only)
      *
      * Erase local IRK, CSRK, address mode, LRU list, random address.
    @@ -329,6 +342,19 @@
      *
      */
     #define GAPBOND_ERASE_LOCAL_INFO      0x41A
    +
    +/**
    + * @brief Get directed advertise address types
    + *
    + * Returns the directed advertise address types for stored bondings.
    + *
    + * size: GAP_Peer_Addr_Types_t[GAP_BONDINGS_MAX]
    + *
    + * default: NULLed array
    + *
    + * range:
    + */
    +#define GAPBOND_DIRECTED_ADV_ADDRTYPE 0x41C
     /** @} End GAPBondMgr_Params */
     
     /**
    

    sp_pairing_intel00.zip

  • Hi again,

    after a deep-dive into LL-Privacy and the stack sources, I think that it may be a problem because CAR is not supported by my Intel chip.
    As CAR is not supported, gapBondMgr_SupportsCentAddrRes() will return FALSE and therefore bleIncorrectMode is raised.

    Spec Vol 6, Part B, Section 6.2.2 (it's mentioned in the sources) prescribes that ADDR_TYPE_RANDOM must be used, when LL-Privacy is available and the IRK is valid.
    So by implication directed advertisement with central's public address must be possible when IRK is wiped out, mustn't it?

    But even when there is no IRK available, bleIncorrectMode will be raised due to the missing CAR feature.
    As far as I have understand from spec, if there is no IRK, there won't be the need for CAR and therefore directed advertisement with central's public address should be possible.

    I added a short if-block to gapBondMgr_SupportsCentAddrRes() to change the behaviour.

    Regards.......tobias.

  • Hi Tobias,

    It's annoying that you found this yourself because that was going to be my guess at where it failed once I could reproduce. I consistently got success because simple_central does have CAR.

    Yes this seems like a bug, and your fix seems appropriate. However, if the central device has the RPAO characteristic, my reading is that you are not allowed to use the public address even if you want to, so should probably add something like if(gapBondMgrGetStateFlags(idx) & GAP_BONDED_STATE_RPA_ONLY && address mode is public) return error;

    Best regards,
    Aslak
  • Will there be more investigations on your side?
  • Sorry, I forgot to mention; after finally reproducing the issue and agreeing that it seems to be a bug, I created an internal bug ticket for the development team. From our side the case is pending review for the Q2 release planning. I will try to update this thread when the ticket is updated.

    However I was not able to reproduce the two bits being high vs low having any effect. The CAR required issue seems independent of this, as long as the device with the offending address is bonded with the peripheral.

    Best regards,
    Aslak
  • Hi Aslak,

    Aslak N. said:
    However I was not able to reproduce the two bits being high vs low having any effect. The CAR required issue seems independent of this, as long as the device with the offending address is bonded with the peripheral.

    This two bit explanation/test were wrong.

    The behaviour was different, because the address was not found in GapBondMgr anymore

    ....of course, so as soon as one bit is set/changed, behaviour will be different.

    Best Regards, Tobias

  • What's TI's workaround or interim solution? I can reproduce this in TI-to-TI environment with host_test.
  • This is my workaround. I modified gapBondMgr_SupportsCentAddrRes() as follows:

    static uint8_t gapBondMgr_SupportsCentAddrRes(uint8_t *pPeerAddr,
                                                  GAP_Peer_Addr_Types_t addrType)
    {
      uint8_t idx;
    
      // Check for valid input address
      if(pPeerAddr == NULL)
      {
        return FALSE;
      }
    
      // Try to find this device in the resolving list to see if an RPA will be
      // used
      if(MAP_LL_PRIV_FindPeerInRL(resolvingList, addrType, pPeerAddr) !=
         INVALID_RESOLVE_LIST_INDEX)
      {
        // Device was found with a valid IRK. If the IRK is not all zeros,
        // RPA will be used. So, check to see if the device supports central address
        // resolution (i.e. it has the CAR char).
        // First, find the bonding table index:
        if(GAPBondMgr_FindAddr(pPeerAddr, addrType,
                               &idx, NULL, NULL) == SUCCESS)
        {
          // Read the IRK from NV
          uint8_t tempIRK[KEYLEN];
          osal_snv_read(DEV_IRK_NV_ID(idx), KEYLEN, tempIRK);
          
          // Check if the device has CAR enabled or the IRK is all zeros
          if((gapBondMgrGetStateFlags(idx) & GAP_BONDED_STATE_CAR) ||
             osal_isbufset(tempIRK, 0x00, KEYLEN))
          {
            // Device has CAR enabled or doesn't have to have it,
            // so OK to use RPA or IDA
            return TRUE;
          }
          else
          {
            // Device doesn't have CAR enabled so can't use RPA
            return FALSE;
          }
        }
        else
        {
          // Device wasn't found in bonding table. This means that the device was
          // manually added to the resolving list by the application and it is the
          // application's responsibility to check the CAR.
          return TRUE;
        }
      }
      else
      {
        // An RPA won't be used so no need to check for CAR char
        return TRUE;
      }
    }
    

    The workaround works on a TI Peripheral which is trying directed advertising towards TI Central initialized with ADDRMODE_PUBLIC and paired with the TI Peripheral.

    Can somebody from TI please confirm if the idea makes sense?

    - Cetri