Advertiser and Scanner
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
Hello. Here is an example app that is capable of swapping between advertising and scanning.
Advertisement
BLE advertisement packets consists of 31 bytes. Each field (i.e. appearance, name, service UUID or similar) has a header of 2 bytes (length and type), meaning that the maximum user payload is 29 bytes. That means the more fields that are packed into one advertisement packet, there are less bytes freed for user payload.
Here's an example of advertisement data(AD) from Bluetooth SIG documentation. (pdf attached)
You can view all the different data types and formats in the documentation attached.
Advertisement Field
In our SDK, each field is represented by BLE_ADV_FIELD data structure. Here's the definition:
typedef PACKED struct
{
UINT8 len; //length of field
UINT8 val; //value of field
UINT8 data[ADV_LEN_MAX-2]; // This is the data and the biggest one is 31-2 = 29
} BLE_ADV_FIELD;
Notice the length, value, and the actual data in the struct corresponds to how AD is formatted in the example above.
You can change the advertisement packet by defining the fields in an array and initializing them.
BLE_ADV_FIELD adv[2];
// Format advertisement data. Data consists of 2 fields. Standard Advertisement flags
// and Broadcom Vendor specific data. The vendor specific data consists of
// 16 byte UUID and a message "Hello"
// flags
adv[0].len = 1 + 1; // 1 (data length) + 1 (value)
adv[0].val = ADV_FLAGS;
adv[0].data[0] = LE_GENERAL_DISCOVERABLE | BR_EDR_NOT_SUPPORTED;
adv[1].len = 23 + 1; // 23 (data length) + (value)
adv[1].val = ADV_MANUFACTURER_DATA; // (AD_TYPE == 0xff)
adv[1].data[0] = 0x0f; // Broadcom (Company Identifier 2 bytes)
adv[1].data[1] = 0x00;
// Set UUID
BT_MEMCPY(&adv[1].data[2], mybeacon_uuid, 16);
// Set "Hello" message
BT_MEMCPY(&adv[1].data[18], msg, 5);
Here are the field values:
// ADV flag values enum ble_adv_flag_value { ADV_FLAGS = 0x01, ADV_SERVICE_UUID16_MORE = 0x02, ADV_SERVICE_UUID16_COMP = 0x03, ADV_SERVICE_UUID32_MORE = 0x04, ADV_SERVICE_UUID32_COMP = 0x05, ADV_SERVICE_UUID128_MORE = 0x06, ADV_SERVICE_UUID128_COMP = 0x07, ADV_LOCAL_NAME_SHORT = 0x08, ADV_LOCAL_NAME_COMP = 0x09, ADV_TX_POWER_LEVEL = 0x0A, ADV_CLASS_OF_DEVICE = 0x0D, ADV_SIMPLE_PAIRING_HASH_C = 0x0E, ADV_SIMPLE_PAIRING_RANDOMIZER_R = 0x0F, ADV_TK_VALUE = 0x10, ADV_OOB_FLAGS = 0x11, ADV_SLAVE_CONNECTION_INTERVAL_RANGE = 0x12, ADV_SERVICE_SOLICITATION_UUID16 = 0x14, ADV_SERVICE_SOLICITATION_UUID128 = 0x15, ADV_SERVICE_DATA = 0x16, ADV_TARGET_PUBLIC_ADR = 0x17, ADV_TARGET_RANDOM_ADR = 0x18, ADV_APPEARANCE = 0x19, ADV_ADVERTISING_INTERVAL = 0x1A, ADV_SERVICE_SOLICITATION_UUID32 = 0x1F, ADV_SERVICE_DATA_UUID32 = 0x20, ADV_SERVICE_DATA_UUID128 = 0x21, ADV_SECURE_CONNECTION_CONF_VALUE = 0x22, ADV_SECURE_CONNECTION_RANDOM_VALUE = 0x23, ADV_INDOOR_POSITION = 0x24, ADV_3D_INFORMATION_DATA = 0x3D, ADV_MANUFACTURER_DATA = 0xFF, };
Then, you'll have to call bleprofile_GenerateADVData function to actually generate the AD.
bleprofile_GenerateADVData(adv, 2);
where the first parameter is the array to BLE_ADV_FIELD and the second is the number of fields.
Starting Advertisement
You can start advertising in few different ways.
If you have the BLE_PROFILE_CFG defined for the app, then you can simply start by calling:
bleprofile_Discoverable(HIGH_UNDIRECTED_DISCOVERABLE, NULL);
Or you can start advertising by setting up the advertisement parameters yourself.
blecm_startAdv(
HCIULP_ADV_NONCONNECTABLE_EVENT, // non-connectable undirected advertisement
160, // adv interval 100 msec
HCIULP_ADV_CHANNEL_MAP_MASK, // all channels
HCIULP_PUBLIC_ADDRESS, // int advAdrType,
HCIULP_ADV_FILTER_POLICY_WHITE_LIST_NOT_USED, // int advFilterPolicy,
HCIULP_PUBLIC_ADDRESS, // int initiatorAdrType,
NULL);
Advertisement packets have different types.
The first argument to this function, blecm_startAdv defines the type of the advertisement.
Value Passed | Advertisement Type |
---|---|
0x00 | ADV_IND |
0x02 | ADV_DISCOVER_IND |
0x03 | ADV_NONCONN_IND |
You can refer to the "auto-generated API" for more details on this function.
Scanning
In order to start scanning, you simply need to call blecen_Scan function.
blecen_Scan(HIGH_SCAN);
Or to turn it off:
blecen_Scan(NO_SCAN);
Advertisement Handler
You need to register a handler if you want to do anything with the advertisement packet in the app create function.
void advertisement_handler(HCIULP_ADV_PACKET_REPORT_WDATA *evt);
...
void basic_create(void)
{
...
// register to process peripheral advertisements
blecm_RegleAdvReportCb((BLECM_FUNC_WITH_PARAM) advertisement_handler);
...
}
Swapping between Advertiser and Scanner
I have made an example app that swaps its role between advertising and scanning. The files are attached as adv.h and adv.c
The app first starts scanning, but you can change its role by pushing the button on the board. It has a minimum RSSI value, so you'll need to have advertising device close to the scanner in order for the scanner to pick up the advertisement.
I was able to put the code into two Tag 3 boards and test their functions.
Here's the app in action.
Both apps started:
One of them starts advertising:
Roles switched:
AD in detail:
Notice how the advertisement data corresponds to how we set the BLE_ADV_FIELD array above.
James
- Subscribe to RSS Feed
- Mark Article as New
- Mark Article as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
Hi jamesle1,
Thanks for the explanation.
Is there any other way to turn on or off scanning despite of blecen_Scan() function?
Because this API is included in blecen.h, but I cannot find this head file in SDK 1.1. If I want to use older version of SDK, how can I control scanning?
Thanks
Jingdong
- Subscribe to RSS Feed
- Mark Article as New
- Mark Article as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
Why must you use SDK 1.1 and the older 20732 with A0 firmware? It is highly recommended that you change to the A1 based 20736/37.
The support is better.
- Subscribe to RSS Feed
- Mark Article as New
- Mark Article as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
Hi,
My concern is the boot time. I am currently using the latest 2.2.1 version, the application needs more than 2 seconds to boot up. I heard that the boot time may be reduced to around 1 second if using previous version of SDK.
I know SDK 1.1.0 is too old for BCM20737, so I may need to try SDK 2.1.0 first to see whether boot time can be shortened or not.
Still if BCM20737 needs seconds to boot up, it may not be an option for us in the end.
Thanks
Jingdong
- Subscribe to RSS Feed
- Mark Article as New
- Mark Article as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
It appears that this topic has already been discussed at some length here: Wake up time from sleep/deep sleep and here: Boot Time of WICED Smart Tag Board (BCM20737)
-
This widget could not be displayed.Anonymous