- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Solved! Go to Solution.
- Labels:
-
BLE
- Tags:
- dynamic broadcaster
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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()
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There are just two windows showing the raw data, and the data organized by field.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.)