Lukáš Kubánek
Lukáš Kubánek

Reputation: 1150

Accessing raw advertisement data for custom BLE device on iOS 8 using Core Bluetooth

I'd like to ask whether it is possible to access the raw advertisement data from a custom BLE device built using a Raspberry Pi from the Core Bluetooth API?

The use case is to broadcast constantly changed data from the Raspberry Pi to multiple iOS devices in the proximity and consume them in an iOS app. See the topology description in this article.

I already found out that the iBeacon advertisements are filtered out from the Core Bluetooth API and are only accessible from the Core Location API only, which requires the knowledge of the UUID. Due to the constantly changed data a custom iBeacon wouldn't work for this particular use case anyway. But I am unsure whether I could achieve that with Core Bluetooth?

Upvotes: 3

Views: 9784

Answers (2)

davidgyoung
davidgyoung

Reputation: 64995

You can do what you want if you change the Raspberry Pi to transmit a non-iBeacon format. CoreBluetooth only filters out the raw bytes of advertisements if they are iBeacon advertisements. See here: Obtaining Bluetooth LE scan response data with iOS

A simple solution is to change your iBeacon advertisement to an open-source AltBeacon advertisement. CoreLocation will no longer pick it up, but CoreBluetooth will.

Here's an example of what you get in the advertisementData NSDictionary in the CoreBluetooth centralManager:didDiscoverPeripheral:advertisementData:RSSI: callback. This example is the result of detecting an AltBeacon advertisement (an open-source beacon standard), with identifiers 2F234454-CF6D-4A0F-ADF2-F4911BA9FFA6 1 2:

{
    kCBAdvDataIsConnectable = 0;
    kCBAdvDataManufacturerData = <1801beac 2f234454 cf6d4a0f adf2f491 1ba9ffa6 00010002 be00>;
}

You can see how to decode the above bytes by looking at the AltBeacon spec here. Note that the above are the actual contents of the NSDictionary for a detected advertisement on iOS8 that were printed to the console using an NSLog statement.

Upvotes: 3

l0gg3r
l0gg3r

Reputation: 8954

Quick answer is "there is no direct way".

Why:
Because CoreBluetooth filters out advertisement data, except kCBAdvDataServiceUUIDs, kCBAdvDataLocalName, so there is now way to pass custom data from peripheral to central via advertising.

How can we workaround:
Peripheral
1) Holds some custom service (let's name it 'BeaconService').
2) BeaconService contains Beacon's UUID, major, minor characteristics.
3) Advertises BeaconService UUID (via kCBAdvDataServiceUUIDs key).

Central
1) Scans for peripherals that have BeaconService UUID.
2) Found peripherals are queued.
3) Connection is opened to queued peripherals, and the iBeacon information is read from BeaconService.
4) Read values can be used to start CoreLocation beacon monitoring/ranging.

So by this way you can make bridge from CoreBluetooth to CoreLocation.

Upvotes: 2

Related Questions