DEVELOPERS BLOG

Where’s My Beacon? Using Beacon Technology in Mobile App Development

CASCADES / 05.07.14 / jcmurray2012
beacon_1
Image: “Wave and Beacon” courtesy of Evgeni Dinev / FreeDigitalPhotos.net.

Lighthouses, or beacons, have always played a key role in ocean navigation and safety at sea. They are built at key locations so that they – or their light – can be seen by distant ships. They can identify safe havens or dangerous shoals by different sequences of flashing lights as well as sounds, and seafarers can use them to triangulate the position of their vessel.

It’s not surprising that a parallel digital technology has evolved to help users of mobile devices navigate through the world of streets, buildings and a host of other locations.

Apple introduced iBeacon™ technology that operates over Bluetooth Low Energy as a vehicle for extending location services. It’s caught the imagination of people as a real, tangible example of the “Internet of Things,” and there are now many manufacturers of such iBeacon technology.

Martin (@mdwrim) and I managed to acquire several such beacons from the kind people at Estimote. My first thought was, how can I write a BlackBerry 10 application to interact with these Estimote beacons?

Never one to turn down a challenge, I developed a simple BlackBerry 10 application to do just that – this is the story.

Background on iBeacon

estimote

Figure 1: An Estimote Beacon (courtesy Estimote)

Estimote beacons are just a few centimetres in size and can be adhered to almost any surface. A battery that powers a Bluetooth Low Energy device is the key to how beacons work. For an ordinary individual using a mobile smartphone, interacting with a beacon is a passive experience. Just like a lighthouse, the beacon periodically advertises its presence using a Bluetooth Low Energy Advertisement. Lighthouses “flash” every few seconds; iBeacon devices advertise about every 100 milliseconds. For a beacon to be useful, mobile applications need to be aware of the various beacons around it, just in the same way a ship at sea would be aware of the lighthouses around it.

So, what does an iBeacon advertisement contain? Bluetooth Low Energy advertisements are defined by the Bluetooth Low Energy Specification from the Bluetooth Special Interest Group. There’s not a lot of room in an advertisement packet but it’s possible to shoe-horn some information into the Manufacturer field. The original intent of the Manufacturer field is to allow the manufacturer of a Bluetooth Low Energy device to add additional identification information about their device. In defining iBeacon, Apple used this field to add additional information to the advertisement without compromising the Bluetooth Specification. Apple has not made the content of this field public, although the specification is now available through a program that requires signing an NDA with Apple. However, the Web is replete with details from people who have reverse-engineered the field’s content (for example here: Estimote Advertising Packet).  It looks like this:

  • A 128-bit UUID field (such as B9407F30-F5F8-466E-AFF9-2555-6B57FE6D)
  • A 16-bit unsigned integer field called Major Number (such as 12654)
  • A 16-bit unsigned integer field called Minor Number (such as 32456)
  • An 8-bit signed integer field called Calibrated Signal Strength (such as -74)

You may ask how these values get programmed into a beacon in the first place. In practical terms, each manufacturer adds additional Bluetooth Low Energy services to their beacons to allow the management of these values – but we’re not interested in that here. In fact, Martin will write about this in our next blog post on beacons.

So what do these numbers mean? Do they conform to any set of standards for their assignment? The short answer is no. It’s entirely up to a beacon infrastructure implementation to assign meaning to these values. However, just as an example, here’s how a supermarket chain (let’s call it Exco for sake of argument) might make use of such beacons:

  • Exco decides to use a single unique UUID for their beacons across all its stores. This allows them to easily determine if their mobile application on a smartphone when the device is in beacon-range of one of their stores.
  • They decide to assign different Major numbers to each of their stores. This allows the mobile application to know in which store the smartphone is currently located.
  • They decide to assign Minor numbers to each department so that the smartphone application now knows which department within the store it’s located.

The concept is elegant in its simplicity. There is no need to use GPS to figure out where the smartphone is located. Once the application knows that it’s close to the bakery department, it can offer special deals to the user. How it does this is application dependent. It could periodically download offers and store them locally, or fetch them each time.

The Calibrated Signal Strength field represents the strength of the signal from the beacon in dBm as measured and calibrated at a distance of 1 meter from the device and is a constant value that was set when the beacon was configured. The value allows you to compare this value with the actual power, the Received Signal Strength Indication (RSSI), detected at the smartphone to figure out a “path loss,” in dB, between the beacon and the handset. A large path loss means the beacon is further away or obstructed by walls that may absorb the radiated power. All other things being equal, you will be closest to the beacon that has the smallest path loss. If the beacon calibration is accurate, you should see a path loss of 0 dB when the handset and beacon are 1 meter apart.

The BlackBerry 10 Application

This is just a simple application that demonstrates how to detect and parse iBeacon data, including the Bluetooth MAC address, UUID, Major, Minor and Calibrated Signal Strength values, and also calculates the path loss. Figure 2 shows how to initialize Bluetooth and enable the call-back, btLeAdvertisements(), that will be called whenever any Bluetooth Low Energy device advertises. I’ve also set the Bluetooth Low Energy scan parameters (using le_set_scan_params()) so the call-back won’t be swamped by advertisement events every 100 milliseconds; rather, it should trigger every second or so.

The BT_LE_ADVERT_SCAN_PASSIVE option indicates that we’ll simply listen for advertisements rather than actively scan for them. The “interval” value of 1000 indicates that we’ll start listening every 1000 milliseconds (1 second) and the “window” value of 100 indicates that when we start listening, we’ll listen for 100 milliseconds. The value of 100 milliseconds is chosen because that’s the value of the default iBeacon advertisement interval.

bt_le_callbacks_t leCallbacks = { btLeAdvertisementCb, NULL, NULL };
void ApplicationUI::initBluetooth()
{
 _model->clear();
if (bt_device_init(btEvent) == EOK) {
 qDebug() << "BBBB bt_device_init() OK" << endl;
 } else {
 qDebug() << "BBBB bt_device_init() FAIL " << strerror(errno) << endl;
 return;
 }
if (bt_le_init(&leCallbacks) == EOK) {
 qDebug() << "BBBB bt_le_init() OK" << endl;
 } else {
 qDebug() << "BBBB bt_le_init() FAIL " << strerror(errno) << endl;
 return;
 }
 if (bt_le_set_scan_params(1000, 100, BT_LE_ADVERT_SCAN_PASSIVE ) == EOK) {
 qDebug() << "BBBB bt_le_set_scan_params() OK" << endl;
 } else {
 qDebug() << "BBBB bt_le_set_scan_params() FAIL " << strerror(errno) << endl;
 return;
 }
if (bt_le_add_scan_device(BT_LE_BDADDR_ANY, NULL) == EOK) {
 qDebug() << "BBBB bt_le_add_scan_device() OK" << endl;
 } else {
 qDebug() << "BBBB bt_le_add_scan_device() FAIL " << strerror(errno) << endl;
 }
}
Figure 2: Initialize Callback for Advertisements

Every time an advertisement is detected, it gets parsed as shown in Figure 3. What this is doing is running through the advertisement data looking for a Manufacturer field (0xff) and for an Apple specific field in particular (0x4c, 0x00) which itself contains iBeacon data (0x02) which is of a fixed length (0x15).

Once we’ve located the iBeacon data the UUID, Major, Minor and Calibrated Strength fields can easily be extracted, taking care with integers for the sake of endian-ness.

bool BtleAdvertData::parse(const QByteArray &advertData)
{
 if (advertData.length() < 27) { // quick sanity check 27 is minimal length of iBeacon advertisment
 _hasBeaconData = false;
 return true;
 }
 int i = 0;
 do {
 uint8_t entryLen = advertData.at(i);
 uint8_t entryType = advertData.at(i+1);
if (entryType == 0xff) {
 int j = i+2;
 if (((uint8_t)advertData.at(j) == 0x4c) && 
 ((uint8_t)advertData.at(j+1) == 0x00) && 
 ((uint8_t)advertData.at(j+2) == 0x02) && 
 ((uint8_t)advertData.at(j+3) == 0x15)) 
 {
 _hasBeaconData = true;
 _beaconUuid.clear();
 for (int k=0; k<16; k++) {
 _beaconUuid.append(advertData.at(k+j+4));
 }
 j += 20;
 _beaconMajor = 0;
 _beaconMajor = (uint16_t)((uint8_t)advertData.at(j+1) & 0xff);
 _beaconMajor += (uint16_t)(((uint8_t)advertData.at(j) & 0xff) << 8);
 j += 2;
 _beaconMinor = 0;
 _beaconMinor = (uint16_t)((uint8_t)advertData.at(j+1) & 0xff);
 _beaconMinor += (uint16_t)(((uint8_t)advertData.at(j) & 0xff) << 8);
 j += 2;
 _calibratedStrength = 0;
 _calibratedStrength = (int8_t) (advertData.at(j) & 0xff);
return true;
 }
 }
 i += (entryLen+1);
 } while (i < advertData.length());
_hasBeaconData = false;
 return true;
}
Figure 3: How to parse the Advertisement Field

Here’s a screenshot of the application running having detected three Estimote beacons, each with a distinct Bluetooth MAC address. Estimote beacons are all configured to have exactly the same UUID, so this is a way to identify them as I’ve done in Figure 4. You can see the Major and Minor numbers for each beacon, as well as the Calibrated Signal Strength for each, which is -74 dBm. The calculated path loss is also shown for each beacon. If the BlackBerry 10 device is moved around, this value will change depending on the proximity of the handset to each of the beacons. In this case, you can see that my device is closest to the second beacon with a path loss of 3 dB.

Just click the “Start” button to have the application collect advertisements from all beacons in the vicinity and “Stop” to stop it. It’s a simple application and you can probably see the opportunities for expansion. Perhaps add a GUI element to show visually the distances of the various beacons?

If you like this application, then use the “About” page to share it with others on social media.

wheresmybeacon

Figure 4: Three Estimote beacons detected

The source code for this application is on GitHub. Watch out for follow-up articles from me and my colleague Martin Woolley on this subject. We will look at related products and how to take this simple BlackBerry 10 application and turn it into a robust, “real world” Internet of Things application.

Feel free to contact me or Martin via Twitter if you need any help on anything Bluetooth Low Energy related.

Resources

About jcmurray2012