iBeacon has been quite a buzzword since the release of iOS 7 when Apple enabled all their iPhones since the 4S with this new BLE technology.
The iBeacon is simply a protocol that takes advantage of the new Bluetooth Low Energy technologies. It has been easy for companies, aside from Apple, to emulate similar protocols such as estimote or AltBeacon. As a result, we thought iBeacon and PubNub could fit together in some pretty cool ways.
In this article, we will explain how the iBeacon protocol works by taking a closer look at how the emitted data is actually structured. We will move onto how to use the iOS sdk to detect and emit beacons. Finally we will try to see if we can use other protocols on iOS devices.
What an iBeacon’s Advertisement Looks Like
According to the Bluetooth v4 specification, a beacon advertises a data package called the Scan Response Data.
This Data can be up to 31 bytes. If we create a smaller scan response, the remaining bytes will be filled with as many 0s.
The scan response is divided into what are called AD structures. They are sequences of bytes of various size, with a predefined structure that goes as follows:
- The first byte represents the number of bytes left to the end of the AD structure. This allows a receiver of this structure to know when it ends and when a new AD structure starts.
- The second byte is the ID of an AD structure type.
- The rest of the bytes are data that is structured in a predefined way depending on what AD type was defined by the previous byte.
That’s all there is to it. Just a succession of AD structures.
Most beacon protocols have only 2 AD structures, which are as follows.
The first one has 3 bytes:
- The first byte will be: 0x02 because we only count the following bytes.
- The second byte is: 0x01 which indicates we have a “Flag” AD type.
- The last byte represents theses flags. These flags express whether the emitting device is, in “Limited Discoverable Mode”, “General Discoverable Mode”, etc… The byte is computed the following way:
The 5 flags are represented by the first 5 bits of a byte. The value of these bits defines whether the flag is ON or OFF. The binary number is then written as a hexadecimal value which will be advertised. An example may clear things up:
|bit 0||OFF||LE Limited Discoverable Mode|
|bit 1||ON||LE General Discoverable Mode|
|bit 2||OFF||BR/EDR Supported|
|bit 3||ON||Simultaneous LE and BR/EDR to same Device Capable (controller)|
|bit 4||ON||Simultaneous LE and BR/EDR to same Device Capable (host)|
The resulting binary value hence becomes: b00011010 Converted into a hex, we get: 0x1A
That’s all there is to the first AD structure! Let’s look into the second one, which contains most of the information we need!
The second structure can be of a different size according to the protocol. Let’s look at the detected scan response emitted by an iPhone.
- First byte is 0x1A (26 in hexadecimal).
- The next byte is always 0xFF which means we have a “Manufacturer Specific” type of AD structure.
- As a result, the 2 following bytes represent the company identifier as defined on bluetooth.org. For an iOS device, the manufacturer is “Apple Inc.” whose company ID is 76. In hexadecimal value, this is equal 0x004C. The ID, written as little endian, takes up 2 bytes. Here it will be 0x04C 0x00 in this order.
- The rest is Manufacturer specific data.
For the iBeacon protocol, the 2 first bytes of the manufacturer specific data are always 0x02 0x15. The next 16 bytes are a UUID representing the advertiser’s organizational unit and the 4 following bytes are going to be the major and the minor. They are 2 bytes long numbers.
There is a final byte at the end of the data structure called the TX Power, which represents the device’s signal reference intensity a meter away from it. This value is held into a single byte which is the two’s complement of the signal’s intensity in dB.
Computing the distance to a Beacon
When a scan response is detected by a device, it also determines the intensity of the received signal. Hence the iBeacon protocol uses the reference value held in the TX Power byte and compares it to the intensity of the signal effectively received. This allows iBeacons to compute an estimation of the distance to the emitting beacon. This is a great quality of iBeacons, but note that the intensity of the signal depends vastly on existing obstacles or simply on the geometry of the room. As a result Apple does not recommend to use iBeacons to determine precise locations.
The algorithm used to compute the distance is not open-source, although others have tried to emulate matching ones.
How to Use Apple’s SDK for iBeacon
Emitting or detecting iBeacon data is organized around iBeacon regions.
These regions are instantiated with optional initial values such as the UUID, major or minor. In the case of detecting an iBeacon, this region object defines what type of beacon scan response should be detected. For example, if you provide a UUID, only the beacons with matching UUIDs will be detected, regardless of the major and minor. If you also provide these values, you’ll detect only beacons matching all three of these values.
When emitting an iBeacon signal, the region object based on the values of the UUID, major and minor generates the data structure to be advertised.
However, it also makes things much more difficult when you are trying to use a protocol different from iBeacon! Let’s look into that immediately.
Using Apple’s SDK for AltBeacon or Estimote
We have seen how complicated the scan response can be, and how Apple simplified the SDK so that we just need to enter the UUID, major and minor to set it up. However, with other beacon protocols, the scan response has a different structure which Apple makes hard for us to tweak.
Detecting other beacons
When detecting iBeacons, the locationManager:didRangeBeacons:InRegion: method is called on the event of a detected signal. However, this is very specific to iBeacons. When detecting another BLE signal, you must not use a CLLocationManager instance, but a CBPeripheralManager which detects ANY BLE advertisement EXCEPT iBeacons, which will be blocked.
The callback that will be triggered upon detection is centralManager:didDiscoverPeripheral:advertisementData:RSSI: . The advertisement data that is returned is a dictionary holding 2 objects; one for each data structure of the scan response. Here is a sample response from an AltBeacon.
kCBAdvDataIsConnectable = 0;
kCBAdvDataManufacturerData = <1801beac 0cf052c2 97ca407c 84f8b62a ac4e9020 00090006 c5>;
The top element represents the first, three bytes long, “Flag” data structure. The second one represents the manufacturer specific data following the bytes describing the size and type of the data structure.
This is good news for us, and means we can detect any beacon information!
Emitting another beacon
We have found things are much trickier when it comes to advertising custom beacon scan responses. We can try to build an NSDictionnary similar to the one detected and try to advertise it using the startAdvertising method.
However the advertisement data keys available for detection are limited to only CBAdvertisementDataLocalNameKey and CBAdvertisementDataServiceUUIDsKey when it comes to advertising the data. It is Apple’s way of preventing us from building manufacturer specific data outside of the iBeacon protocol.
So there you have it! We went through apple’s iBeacon protocol, looked at how we could detect other beacons and apple’s restrictions to advertising data. We have some working examples and tutorials to build an iBeacon app on Swift – check out our beacon emitter and beacon detector tutorials, which allow you to get the best out of iBeacons by establishing a two-way communication which beacons aren’t usually capable of. The reason why we think it’s great is that we use PubNub to enhance beacons’ capabilities while still keeping their low energy consumption asset! Sweet, right?
- Bluetooth Specification
- Bluetooth Company identifiers
- Apple’s Advertisement Data Keys
- Apple’s CoreBluetooth Peripheral Manager Documentation stating only 2 keys can be used in the advertised data dictionary.
- Swift and iBeacon two-way communication tutorial
Norvan Sahiner and Sunny Gleason wrote this tutorial series on behalf of PubNub, a platform that allows you to build and scale realtime apps for connected devices.