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: CC2640R2F: Example project for Directed Advertiment

Part Number: CC2640R2F
Other Parts Discussed in Thread: CC2640,

Hi all,

Stack used : 3.1.1

is the any Example project available regarding how do enable directed advertisement ?

thanks!

  • Jayachandran,

    This would be a great example to have actually. I'll make it an action to try and get something like this added to the SDK.

    In the meantime, doing this yourself is pretty straight forward I believe.

    First, start out with the simple_broadcaster example and inside of simple_broadcaster.c::SimpleBLEBroadcaster_init(void) there is a section around line 345 with an #ifndef BEACON_FEATURE.

    Under that, there you can change the advType to GAP_ADTYPE_ADV_HDC_DIRECT_IND;

    and then enable advertising. Some pseudo-code below:

    uint8_t advType = GAP_ADTYPE_ADV_HDC_DIRECT_IND; // use scannable undirected adv
        uint8_t advertEnable = 0x01;
    //....
        GAPRole_SetParameter(GAPROLE_ADV_EVENT_TYPE, sizeof(uint8_t), &advType);
        GAPRole_SetParameter(GAPROLE_ADVERT_ENABLE, sizeof(uint8_t), &advType);

  • Also, this might be good to keep in mind.
    software-dl.ti.com/.../creating-a-custom-bluetooth-low-energy-application.html

    As well as the SimpleLink Academy on Scanning and Advertising: dev.ti.com/.../ble_scan_adv_basic.html
  • Hi Evan,
    I have added changes as you suggested, the advertisement changes to ADV_DIREC_IND type .
    But i can view the device in sniffer only, Central device not able to list ADV_DIREC_IND advertisement type devices .

    How i can add address of Central device(initiator) in payload to view the Directed advertisement devices by central device (initiator)?

    Is there any changes required in central side (or) broadcaster side?

    Please provide some solution.

    Thanks and Regards,

  • Jayachandran,

    So, thank you, I should have added that to the previous post. In your simple_broadcaster project, in the folder "PROFILES" under broadcaster.c you can find the following line:

    static uint8_t  gapRole_AdvDirectAddr[B_ADDR_LEN] = {0};

    Here you can insert the directed address. Please test adding this, and along side I will work to make sure there is nothing else you need to add. 

    As a side note, I'm also going to make an action to add more clear directions to our documentation around directed advertising in the future as an outcome from this thread once we get you all squared away. 

  • Hi Evan,

    I have modified the code as you suggested in the broadcaster.c file , in that i added the "MAC address of central device".

    Still i am not able to see the advertisement in Central device , but can able to see via sniffer.

    Sniffer shows both slave and initiator address.

    Attached the sniffer data here.

    Thanks and Regards,

    Jayachandran R

  • Jayachandran,

    What is your central device? If it's a phone, or potentially something else, you might want to confirm with the central provider that they support directed ADV types. Apple for instance excludes it and maybe some Android devices as well.
  • Hi Evan

    I have used iPhone(6s) and android mobile (version 7.0). i need to check weather these device are supports directed advertising.

    is the launchpad will support direct advertisement? 

    Provide some suggestion how do configure direct advertisement in launchpad..

    Thanks and regards,

    Jayachandran R

  • Jayachandran,

    Apple does not support directed advertising. As far as Android, you would have to check.

    Launchpad will support it.

    This SimpleLink Academy lab will be useful for learning scanning and advertising.

    dev.ti.com/.../ble_scan_adv_basic.html
  • If my central is another CC2640 with TI BLE Stack, how do I find out the address to direct to?
  • both TI based devices need to be bonded first and then both devices need to be disconnected.
    And in the GAPROLE_WAITING case of the peripheral role, the following sequences are needed.
    And if direct connection procedure is failed, advertising needs to get back to undirected mode.

    static uint8_t bondedDevicesNum = 0;
    static uint8_t gapRole_AdvDirectAddr[B_ADDR_LEN] = {0x00, };
    uint8_t advDirectAddrType = ADDRMODE_PUBLIC; // ADDRMODE_STATIC;
    static uint8_t high_duty_cycle = 0;
    #if (ENABLE_HDC_DIRECT_ADVERTISING_TRY == 1)
    static uint8_t high_duty_cycle_try = 0;

    #endif

    case GAPROLE_WAITING:

    HufBLEPeripheral_freeAttRsp(bleNotConnected);

    Display_print0(dispHandle, SBP_ROW_ROLESTATE, 0, "Disconnected\r\n");
    #if defined (ENABLE_HDC_DIRECT_ADVERTISING) && (ENABLE_HDC_DIRECT_ADVERTISING == 1)
    if ( high_duty_cycle == 1 )
    {
    #if (ENABLE_HDC_DIRECT_ADVERTISING_TRY == 1)
    if ( high_duty_cycle_try++ >= 10 )
    {
    high_duty_cycle_try = 0;

    #endif
    high_duty_cycle = 0;

    if ( bondedDevicesNum > 0 )
    {
    uint8_t advertEnabled = FALSE; // Turn off Advertising
    GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &advertEnabled);

    Display_print0(dispHandle, SBP_ROW_RESULT, 0, "enable undirect Advertsing");

    uint8_t advDirectType = GAP_ADTYPE_ADV_IND;
    GAPRole_SetParameter(GAPROLE_ADV_EVENT_TYPE, sizeof(uint8_t), &advDirectType);

    advertEnabled = TRUE;
    GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &advertEnabled);
    }
    #if (ENABLE_HDC_DIRECT_ADVERTISING_TRY == 1)
    }
    else
    {
    high_duty_cycle = 2;
    }

    #endif
    }
    #if (ENABLE_HDC_DIRECT_ADVERTISING_TRY == 1)
    if( high_duty_cycle == 2 )
    #else
    else

    #endif
    {
    #if defined (ENABLE_HDC_DIRECT_ADVERTISING) && (ENABLE_HDC_DIRECT_ADVERTISING == 1)
    {
    GAPBondMgr_GetParameter(GAPBOND_BOND_COUNT, &bondedDevicesNum);
    Display_print1(dispHandle, 2, 0, "bondedDevicesNum %d", bondedDevicesNum);
    if ( bondedDevicesNum > 0 )
    {
    uint8_t advDirectType = GAP_ADTYPE_ADV_HDC_DIRECT_IND;
    uint8_t idx;
    uint8_t advertEnabled = FALSE; // Turn off Advertising

    GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &advertEnabled);

    // Resolve address and find index
    idx = GAPBondMgr_ResolveAddr( advDirectAddrType, gapRole_AdvDirectAddr, NULL );
    if ( idx < GAP_BONDINGS_MAX )
    {
    high_duty_cycle = 1;

    Display_print0(dispHandle, SBP_ROW_RESULT, 0, "enable Direct HDC Advertsing");

    {
    GAPRole_SetParameter(GAPROLE_ADV_EVENT_TYPE, sizeof(uint8_t), &advDirectType);
    GAPRole_SetParameter(GAPROLE_ADV_DIRECT_ADDR, sizeof(gapRole_AdvDirectAddr), gapRole_AdvDirectAddr);
    GAPRole_SetParameter(GAPROLE_ADV_DIRECT_TYPE, sizeof(uint8_t), &advDirectAddrType);
    }
    }

    advertEnabled = TRUE; // Turn on Advertising
    GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &advertEnabled);
    }
    }

    #endif

    }

    #endif


    And in the GAP_DEVICE_INFO_EVENT of central role application,

    static uint8_t highDutyCycle = FALSE;

    case GAP_DEVICE_INFO_EVENT:
    {

    //Display_print0(dispHandle, 2, 0, "GAP_DEVICE_INFO_EVENT\r\n");
    {
    #if (defined ENABLE_PAIRING_BONDING_SUPPORT) && (ENABLE_PAIRING_BONDING_SUPPORT == 1)
    GAPBondMgr_GetParameter(GAPBOND_BOND_COUNT, &bondedDevicesNum);
    //Display_print2(dispHandle, 2, 0, "bondedDevicesNum %d of MAX_BONDED_DEVICES %d\r\n", bondedDevicesNum, MAX_BONDED_DEVICES);

    #endif

    if ( bondedDevicesNum > 0 )
    {
    #if defined (ENABLE_HDC_DIRECT_CONNECTION_REQ) && (ENABLE_HDC_DIRECT_CONNECTION_REQ == 1)
    highDutyCycle = TRUE;
    Display_print0(dispHandle, 2, 0, "HIGH_DUTY_CYCLE is on\r\n");

    #endif

    }
    }

    // if filtering device discovery results based on service UUID
    // directed advertising mode has no advertising packet. So, Service filtering should be off.
    #if defined (ENABLE_HDC_DIRECT_CONNECTION_REQ) && (ENABLE_HDC_DIRECT_CONNECTION_REQ == 1)
    if (highDutyCycle == FALSE)

    #endif
    {

    }

    case GAP_DEVICE_DISCOVERY_EVENT:
        if (scanRes > 0)
        {

          // connect to current device in scan result
          peerAddr = devList[dev].addr;
          addrType = devList[dev].addrType;

          // initiating a connection to a device
          bStatus_t status = GAPCentralRole_EstablishLink(highDutyCycle, // DEFAULT_LINK_HIGH_DUTY_CYCLE,
                                                                                                      current_link_whitelist_mode, // DEFAULT_LINK_WHITE_LIST,
                                                                                                      addrType, peerAddr);
         }


    I hope that this would be helpful for you to implement the direct connection.

    BR,
    Ji-won Lee

  • To use high duty direct connection mode, both devices know already the necessary things like address.
    And it is necessary for you to make sure only the specific devices need to be connected.
    So, after bonding procedure is completed, two devices have the address of peer device.
    And the advertising with high duty cycle directed mode is valid for a short while(within 3.5ms, as I remember), and if the connection is failed, it should be back to un-directed advertising mode.
  • Hi evan,

    Test Program : SimpleBLEPeripheral  example project.

    Peripheral role : Device CC2650R2F -> MAC  ID  [B0:91:22:65:C4:8D].

    Central Role :  Host test program with launch pad -> MAC ID [98:07:2D:41:43:80].

    I took SimpleBLEPeripheral example project and modified code for directed advertisement , i did following steps,

    1.In peripheral.c file  in  gapRole_init() function modified to gapRole_AdvEventType = GAP_ADTYPE_ADV_HDC_DIRECT_IND;

    2.In peripheral.c file  static variable   gapRole_AdvDirectAddr[B_ADDR_LEN] assigned with Initiator address (Central Role mac ID)  {0x80, 0x43, 0x41, 0x2D, 0x07, 0x98}.

    3.SimpleBLEPeripheral.c file added following code in SimpleBLEPeripheral_init function.

    uint8 desired_adv_event_type = GAP_ADTYPE_ADV_HDC_DIRECT_IND;

    uint8 desired_adv_direct_addr[] =

     {

       0x3C,

       0x2D,

       0xB7,

       0x85,

       0xEE,

       0xFE

     };

     GAPRole_SetParameter( GAPROLE_ADV_EVENT_TYPE, sizeof( uint8 ), &desired_adv_event_type );

     GAPRole_SetParameter( GAPROLE_ADV_DIRECT_ADDR, B_ADDR_LEN, desired_adv_direct_addr );

    Found Following Observation :

    1.While Sniffing the data using sniffer ,Advertisement PDU is not proper and shows FCE error at end .

       With Broadcaster example project the sniffer logs are looking good .

       Please refer sniffer data attached.

    2.Established the connection using central device , But connection is not established.

       please refer the  Btool log.

    Is code changes are correct? how i can test this code using Btool with Host test program?

    Please provide some suggestion on this .

    Thanks and regards,

    Jayachandran r

  • Jayachandran,

    Let me look into this a bit more in depth. The device that you're running Btool with is running central or host test?
  • Hi Evan,

    I used host test app!

    hex file flashed is host_test_cc2650lp_app.hex and host_test_cc2650lp_stack.hex in launchpad.

    Thanks

  • Hi Evan,

    Now the Directed Advertising is working fine.

    The problem i gave wrong peer address in ADV PDU (in reverse order), after corrected the PDU now it is working.

    But i am giving Fixed Peer Address in the ADV PDU.

    How i can change the Peer Address Dynamically? , Because Over the period of device life time i need to change central device.

    Thanks and Regards,

    Jayachandran R

  • Jayachandran,

    Thanks for updating me. My apologies for not getting back to you sooner. I've been in and out of the office this week.

    As far as changing the advertisement data, you can follow something similar to this lab (Task 2):
    dev.ti.com/.../ble_scan_adv_basic.html

    That said, you can basically just change the advertisement data when you need by the using the following function
    GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(newAdvertData), newAdvertData);

    You don't have to use the periodic event to do so, it's just used in the scope of the example above. You can define your own event if you want. 

    How do you plan on acquiring each new peer address for your new central device? What exactly is your central device? Per my comments earlier, if it's a phone, you will need to check that it supports directed advertising (iPhone I'm fairly certain does not support it).

  • Hi Evan,

    Thanks for your reply.

    Plan For acquiring new device peer address is as follow,

    1.start with general advertisement

    2.Connect Request from Central device (here the central device is launch pad)..

    3.Paring and Bonding with central device .

    4.Upon Bonding success i will get peer address of the central device and configure as a initiator address in direct adv PDU data.

    5.Advertisement change to Directed adv.

    Here my question is how i can get peer address of the bonded device ? what is is the API i need to call to get the recently bonded device mac address?

    Please help me on this .

    Thanks and regards,

    Jayachandran R

  • Jayachandran,

    Thanks for the patience. I was in a week long training last week and didn't have a chance to get on the forums that much.

    Are you using Privacy 1.2?
    If so the RPA is resolved by the Controller. Once bonded with the peer device, you will receive the public ID and it's IRK. After bonding, you can call linkDB_getInfo() to receive the peer devices public BDADDR as I understand it. Can you try this?

    Also helpful resource is the GapBondMgr and SNV sections of the BLE Stack Users Guide for CC2640R2F

    http://software-dl.ti.com/lprf/simplelink_cc2640r2_latest/docs/blestack/ble_user_guide/html/ble-stack-3.x/gapbondmngr.html?highlight=privacy#gapbondmgr-example-with-bonding-enabled

  • Hi Evan,
    Thanks For your Reply.
    I tried with linkDB_getInfo() with that i can able to get MAC address of the central device .
    I am using Privacy 1.2 and also i am not commented out the macro "GBM_GATT_NO_CLIENT" in gapbondmgr.c file .
    Is it ok do like this?
    Thanks and regards
    Jayachandran R