Help with Dynamic Broadcaster

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

I have seen the day 9 project, Dynamic Broadcaster, but still need assistance with its implementation. This partly may be a C Language issue but an understanding of the use of CyBle_GapUpdateAdvData is also lacking.

I successfully enter broadcasting mode (Broadcaster shows up under scan by CySmart 1.2), but with dynamic broadcasting I want to add and modify the Scan Response Packet each time.  Not only with this snippet of code do I NOT create a Scan Response Packet (cannot be seen under CySmart 1.2 scan response data tab) but I also lose my Broadcaster Label - Public identifier-and revert to the Advertiser Label of BLE Serial.

Note that both my ScanData.scanRspDataLen variable and ScanData.scanRspData array fill out with the correct data.

void DynamicADVPayloadUpdate(char *p, uint16 DataLength)

{

    uint16  i;

    CYBLE_GAPP_SCAN_RSP_DATA_T ScanData;

    uint8 test;

    memset(ScanData.scanRspData,0,N_COUNT);

    ScanData.scanRspDataLen = DataLength;

    for(i=0; i < ScanData.scanRspDataLen; i++)

        ScanData.scanRspData = *(p+i);

    

    if(CyBle_GetBleSsState() == CYBLE_BLESS_STATE_EVENT_CLOSE)

    {

     CyBle_GapUpdateAdvData(cyBle_discoveryModeInfo.advData, &ScanData);

     test = 1;

   

    }//end if(CyBle_GetBleSsState()

}

*****************************************

If I replace the code above with this code, I resolve the issue having to do with losing the broadcaster label, but I still see nothing under the Scan Response Data Tab.

void DynamicADVPayloadUpdate(char *p, uint16 DataLength)

{

    uint16  i;

    CYBLE_GAPP_SCAN_RSP_DATA_T ScanData;

    uint8 test;

 

         memset(ScanData.scanRspData,0,31);

  

    ScanData.scanRspDataLen = DataLength;

   // for(i=0; i < ScanData.scanRspDataLen; i++)

   //     ScanData.scanRspData = *(p+i);

     

     

      /* Define the Broadcast advertisement parameters - including the BD address,

     * advertisement type, advertisement interval etc.

     */

   CYBLE_GAPP_DISC_PARAM_T myAdvParameters =

    {

        // Minimum Advertisement interval = 100 ms

        CYBLE_GAP_ADV_ADVERT_INTERVAL_NONCON_MIN,

     

        // Maximum Advertisement interval = Minimum = 100 ms

        CYBLE_GAP_ADV_ADVERT_INTERVAL_NONCON_MIN,

     

        // Advertisement type - Non-connectable undirected (broadcasting)

        CYBLE_GAPP_NON_CONNECTABLE_UNDIRECTED_ADV,

     

        // Own BD address type - Public

        CYBLE_GAP_ADDR_TYPE_PUBLIC,

     

        // Address type of peer for directed advertisement - not applicable

        CYBLE_GAP_ADDR_TYPE_PUBLIC,

     

        // Address for directed advertisement - not applicable

        {0},     

     

        // Channel map - advertise on all 3 channels

        0x07,    

     

        // Advertisement filter policy - not applicable

        0        

    };

    // Define the advertisement data for the broadcast - this includes the

    // advertisement flags and the device name advertised. The device name

    // used for Broadcasting is different from the device name used when

    // we want to connect to another device.

    //

    CYBLE_GAPP_DISC_DATA_T myAdvData =

    {

        {

            2,      // Length for Flags field - Counts as 1 Byte

            1,      // Identifier that following data is Flags field - Counts as 1 Byte

            4,      // Advertisement Flags - BR/EDR not supported - Counts as 1 Byte

            12,     // Length for Complete Name field - Counts as 1 Byte

            0x09,   // Identifier that following data is Complete Name field - plus 12

         

            // Name

            'B', 'r', 'o', 'a', 'd', 'c', 'a', 's', 't', 'e', 'r'

        },

        16          // Total bytes in the advertisement packet

    };

 

    // There is no scan response data configured for this broadcast

    CYBLE_GAPP_SCAN_RSP_DATA_T myScanRespData =

    {

        {*p,*(p+1),*(p+2),*(p+3),*(p+4),*(p+5),*(p+6),*(p+7),*(p+8),*(p+9),*(p+10),*(p+11),*(p+12),\

        *(p+13),*(p+14),*(p+15),*(p+16),*(p+18),*(p+19),*(p+20),*(p+21),*(p+22),*(p+23),*(p+24),*(p+25),\

        *(p+26),*(p+27),*(p+28),*(p+29),*(p+30),*(p+31)},        // Scan response packet

        ScanData.scanRspDataLen           // Length of the scan response packet

    };

 

    // Top level structure for holding all advertisement parameters

    CYBLE_GAPP_DISC_MODE_INFO_T discoveryModeInfo =

    {

        CYBLE_GAPP_NONE_DISC_BROADCAST_MODE,   // Discoverable mode

        &myAdvParameters,                      // Advertisement parameters

        &myAdvData,                            // Advertisement data

        &myScanRespData,                       // Scan response data

        0                                      // Advertisement timeout: none

    }; 

      

    if(CyBle_GetBleSsState() == CYBLE_BLESS_STATE_EVENT_CLOSE)

    {

     CyBle_GapUpdateAdvData(discoveryModeInfo.advData,discoveryModeInfo.scanRspData);

       //CyBle_GapUpdateAdvData(cyBle_discoveryModeInfo.advData,&ScanData);

    test = 1;

     

    }//end if(CyBle_GetBleSsState()

}

*****************************

I think I see one of the mistakes I am making.   The Scan Response Packet is not a blind 31 byte field.  It needs to be cast in one of the categories provided, like Manufacturer Specific Data.  Correct?  If this is the case, how do assign the data array to the Manufacturing Index?  Your example requires only a single byte assignment to the manufacturing index.  (eg, advPayload[MANUFACTURER_SPECIFIC_DYNAMIC_DATA_INDEX] = dynamicPayload++;, < 255).   However, the ScanRespPayload will contain an array of data.

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

OK, that helped. Thanks! I see the raw data but do not see it formatted as you suggested

//DataLength

ScanData.scanRspDataLen = DataLength + 3;

memset(ScanData.scanRspData,0,31);

//Data Must be correctly parsed

ScanData.scanRspData[0] = 0xFF; //Indicates Manufacturer Specific Data

ScanData.scanRspData[1] = 0x31; //Next Two Bytes Point to Cypress Semi

ScanData.scanRspData[2] = 0x01;

for (i=3; i < ScanData.scanRspDataLen; i++)

ScanData.scanRspData = *(p+i-3);

View solution in original post

0 Likes
11 Replies
Anonymous
Not applicable

BLEScanResponseDataPacketExample.PNG

The above image is an example of the scan response data array of data as seen from the BLE component editor.

The value and indices on the right are the ones you are looking for/need to set/change for programmatically updating the advertisement data.

CYBLE_GAPP_SCAN_RSP_DATA_T scanrsp; //declaration of scan response data array

CYBLE_GAPP_DISC_MODE_INFO_T Mode;

CYBLE_GAPP_DISC_PARAM_T Param;

Param.advChannelMap = 7;//Use all three channels

Param.advFilterPolicy = CYBLE_GAPP_SCAN_ANY_CONN_ANY;

Param.advIntvMax = cyBle_discoveryModeInfo.advParam->advIntvMax;

Param.advIntvMin = cyBle_discoveryModeInfo.advParam->advIntvMin;

Param.advType = 00;

memset(Param.directAddr, 0x00, 6);

Param.ownAddrType = CYBLE_GAP_ADDR_TYPE_PUBLIC;

Mode.advData = &advrsp;

Mode.advParam = &BondingParam;

Mode.advTo = 00;

Mode.discMode = CYBLE_GAPP_GEN_DISC_MODE;

Mode.scanRspData = &scanrsp;

scanrsp.scanRspData[0] = 0x05;//protocol defines that the first byte is the length of the advertisement field

scanrsp.scanRspData[1] = 0x09;//Protocol defined constant that signifies which formate/service the data is

scanrsp.scanRspData[2] = 'T';//Our advertisement data

scanrsp.scanRspData[3] = 'E';

scanrsp.scanRspData[4] = 'S';

scanrsp.scanRspData[5] = 'T';

scanrsp.scanRspDataLen = 6; //length of the raw number of bytes in the array of data

The above code snippet shows the data structures and data initialization for the advertisement packets; Of course you will want to change the actual data and the location of the different parts for your needs.

Let me know if you have questions on parts of the code; I grabbed some of it from cypress examples/code and didn't bother to comment them due to the comments in the API libraries being sufficient.

Regards,

Epratt

0 Likes
Anonymous
Not applicable

Can I use the Scan Response packet as a free 31 byte array for data, or must the data be caste in the framework of categories, such as Local Address, Manufacturer Specific Data, etc.?

0 Likes
Anonymous
Not applicable

You don't have to use the data structure for working with the array iirc. But, you will want to use the length and type bytes at the beginning of the field in order for other bluetooth devices to properly parse your data for reading/usage.

If you are developing both halves of the connection, then you can probably get away without using categories, but otherwise I would strongly recommend following the category format to allow other devices to interpret the data.

0 Likes
Anonymous
Not applicable

My code is not much different than what you provided. However, a key difference is that I do not tailor the Scan Response Packet to pre-existing categories, and this is what might be hurting me. I am simply sending, for example, the string ABC, so while my ScanRespPacket sees this string and get the packet length correct, the data may not be allocated correctly. I do not see anything under Cysmart 1.2, with the ScanResponseData tab.

If I am to assign data to manufacturing data, how do I go about this? Let’s say I am using Cypress as the ID (28u). I want to pass ‘ABC’ to that manufacturer with index 28. What would the structure of code look like?

Thanks

void DynamicADVPayloadUpdate(char *p, uint16 DataLength)

{

uint16 i;

CYBLE_GAPP_SCAN_RSP_DATA_T ScanData;

uint8 test;

// for(i=0; i < ScanData.scanRspDataLen; i++)

// ScanData.scanRspData = *(p+i);

/* Define the Broadcast advertisement parameters - including the BD address,

  • advertisement type, advertisement interval etc.

*/

CYBLE_GAPP_DISC_PARAM_T myAdvParameters =

{

// Minimum Advertisement interval = 100 ms

CYBLE_GAP_ADV_ADVERT_INTERVAL_NONCON_MIN,

// Maximum Advertisement interval = Minimum = 100 ms

CYBLE_GAP_ADV_ADVERT_INTERVAL_NONCON_MIN,

// Advertisement type - Non-connectable undirected (broadcasting)

//CYBLE_GAPP_NON_CONNECTABLE_UNDIRECTED_ADV,

CYBLE_GAPP_SCANNABLE_UNDIRECTED_ADV,

// Own BD address type - Public

CYBLE_GAP_ADDR_TYPE_PUBLIC,

// Address type of peer for directed advertisement - not applicable

CYBLE_GAP_ADDR_TYPE_PUBLIC,

// Address for directed advertisement - not applicable

{0},

// Channel map - advertise on all 3 channels

0x07,

// Advertisement filter policy - not applicable

0

};

// Define the advertisement data for the broadcast - this includes the

// advertisement flags and the device name advertised. The device name

// used for Broadcasting is different from the device name used when

// we want to connect to another device.

//

CYBLE_GAPP_DISC_DATA_T myAdvData =

{

{

2, // Length for Flags field - Counts as 1 Byte

1, // Identifier that following data is Flags field - Counts as 1 Byte

4, // Advertisement Flags - BR/EDR not supported - Counts as 1 Byte

12, // Length for Complete Name field - Counts as 1 Byte

0x09, // Identifier that following data is Complete Name field - plus 12

// Name

'B', 'r', 'o', 'a', 'd', 'c', 'a', 's', 't', 'e', 'r'

},

16 // Total bytes in the advertisement packet

};

memset(ScanData.scanRspData,0,31);

for(i=0; i < ScanData.scanRspDataLen; i++)

ScanData.scanRspData = *(p+i);

ScanData.scanRspDataLen = DataLength;

// Top level structure for holding all advertisement parameters

CYBLE_GAPP_DISC_MODE_INFO_T discoveryModeInfo =

{

CYBLE_GAPP_NONE_DISC_BROADCAST_MODE, // Discoverable mode

&myAdvParameters, // Advertisement parameters

&myAdvData, // Advertisement data

&ScanData, // Scan response data

0 // Advertisement timeout: none

};

if(CyBle_GetBleSsState() == CYBLE_BLESS_STATE_EVENT_CLOSE)

{

CyBle_GapUpdateAdvData(discoveryModeInfo.advData,discoveryModeInfo.scanRspData);

//CyBle_GapUpdateAdvData(cyBle_discoveryModeInfo.advData,&ScanData);

test = 1;

}//end if(CyBle_GetBleSsState()

}

0 Likes
Anonymous
Not applicable

The CySmart app uses the category bytes to format the output; You can still see the raw scan response packet data, but it will only show up in the "raw data" window of the CySmart app.

Ideally, the manufacturing category would be the best use for having custom data/format/fields. That way other devices won't expect it to be, say, a local name or something else and interpret it as such.

For setting up a manufacturer specific field:

<Length Byte>

<0xFF> (signifies a manufacturer specific data)

<2-Byte company ID> (0xFF,0xFF is the "Other" field)

Then follow with the custom data you have.

If you only have this field, you can get 28 bytes of data for the Custom Manufacturer Data Field. Otherwise, there will be lost bytes to overhead for each designated field. (I'm not sure if regular bluetooth has larger advertising packets or not).

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

OK, that helped. Thanks! I see the raw data but do not see it formatted as you suggested

//DataLength

ScanData.scanRspDataLen = DataLength + 3;

memset(ScanData.scanRspData,0,31);

//Data Must be correctly parsed

ScanData.scanRspData[0] = 0xFF; //Indicates Manufacturer Specific Data

ScanData.scanRspData[1] = 0x31; //Next Two Bytes Point to Cypress Semi

ScanData.scanRspData[2] = 0x01;

for (i=3; i < ScanData.scanRspDataLen; i++)

ScanData.scanRspData = *(p+i-3);

0 Likes
Anonymous
Not applicable

FormatvsRawData.PNG

There are just two windows showing the raw data, and the data organized by field.

0 Likes
Anonymous
Not applicable

To be more precise, I see the advertisement data as raw AND formatted, but only see the raw scan data (no formatting). But I believe you said that is what I should expect.

0 Likes
Anonymous
Not applicable

Ah; So you are referring to the Scan response data window. I don't remember how the window normally looks. I think it should be showing up formatting if you use the example cypress peripheral programs; Otherwise, just going off of the custom data formats, I don't think it would be showing up in the formatted/description section.

Regards,

Epratt

0 Likes
Anonymous
Not applicable

One more question about cysmart. I appears that if I send successive broadcasts, the Cysmart does not automatically refresh the raw data field. It appears that I need to re-scan and then click again on my Device field to get updated values. Does this make sense to you?

0 Likes
Anonymous
Not applicable

The advertisement data is only physically received from the device while the scanning is active; Once you click Stop Scan the dongle will no longer update the advertisement data last seen for the device.

(Also of note, but not directly related I think is the setting under Configure Master Settings->Scan Parameters->Duplicate Filter Policy; Turning this off will allow multiple advertisement packets with the same data to show up in the Log at the bottom of the screen.)

0 Likes