17
votes

I'm creating an app that gets the UUID of all BLE devices within range. I've gotten it working fine in Android, where it gives me the advertisement data as a byte array. Now I'm trying to do the same in iOS.

I'm running a scan and it's detecting the device, and in the callback there's an NSDictionary called advertisementData. But the only information in it is as follows:

kCBAdvDataChannel = 39;
kCBAdvDataIsConnectable = 1;
kCBAdvDataLocalName = jaalee;
kCBAdvDataTxPowerLevel = 0;

Am I right in thinking I should be getting the entirety of the advertising packet? If not, how can I get it?

2
You can't, except if the BLE device explicitly add others info in its advertisement data. Core-Bluetooth provides a high-level implementation. What other information do you want?Larme
Corebluetooth provides the CBPeripheral object. The identity property provides the UUID, which is equivalent to, but is not, the MAC address. The UUID can also change periodically, particularly if the peripheral is an iOS devicePaulw11
Also, I notice that you tagged your question [ibeacon] - Are you trying to gather BLE peripherals or iBeacons - on iOS the former are handled by the CoreBluetooth framework and the latter by the CoreLocation frameworkPaulw11
This is meant for all BLE devices, including iBeacons. The CBPeripheral object doesn't have an identity property- it has an identifier property, but that's just a temporary identifier internal to iOS. I need what the BLE device is broadcasting in it's advertisement.user2564511
Basically, on iOS you can't do "all BLE devices, including iBeacons" - you have to use different APIs for generic connectable devices with services vs. advertise-only iBeacons.Chris Stratton

2 Answers

18
votes

Unfortunately, iOS does not allow you to access the raw advertisement data. I wrote a blog post demonstrating this. While the post is specifically about iBeacons, it applies to any BLE advertisement.

EDIT: To clarify, you can read the raw manufacturer data bytes or service data bytes of non-iBeacon advertisements. It is only the iBeacon advertisements that have their manufacturer data bytes hidden by CoreLocation. See here: Obtaining Bluetooth LE scan response data with iOS

The equivalent MacOS CoreLocation methods do allow this, so it is probably an intentional security or power saving restriction on iOS.

17
votes

Based on official documentation from Apple iOS and my personal experience:

YES, iOS does not allow you to access the RAW advertisement data.

BUT

If your intention is to put information in advertising packet and read them from the iOS app without connect with the peripheral, this is possible to do. Here is described how:

1) in the peripheral firmware you have to insert your manufacturer specifica data in the advertising packet, with the data type GAP_ADTYPE_MANUFACTURER_SPECIFIC (0xFF) Remember that in the Manufacturer Specific Data, first 2 octets contain the Company Identifier Code followed by the additional manufacturer specific data

2) in the iOS

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI

You can see the manufacturer specific data in advertisementData dictionary with key:

CBAdvertisementDataManufacturerDataKey

3) if you want that in your App receive a callback notification every advertising packet sent by peripheral to iOS, remember to change the scan option to YES. Look at this post about that: Core Bluetooth - constant RSSI updates of in-range devices

In my blog post will be soon a tutorial: http://www.megabri.com/