Obtaining Bluetooth Le Scan Response Data with iOS

Obtaining Bluetooth LE scan response data with iOS

Yes, you can use CoreBluetooth to read the full manufacturer data or service data bytes of a BLE advertisement as long as it is NOT an iBeacon advertisement. If it is an iBeacon advertisement, CoreBluetooth will block your ability to see the bytes. The callback you use is as follows:

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

The raw service data or manufacturer data bytes will be present inside the NSDictionary *advertisementData. But they key holding those data will be removed by the operating system for iBeacons.

Here's an example of what you get in the advertisementData NSDictionary in the callback. This example is for 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.

For more details about why you can't read iBeacon data along with additional code showing how you set this up, see here:

http://developer.radiusnetworks.com/2013/10/21/corebluetooth-doesnt-let-you-see-ibeacons.html

Using CoreBluetooth is it possible to get the raw scan record of a Bluetooth LE device

EDIT: iOS does let you access the raw data for any Bluetooth advertisement that does not match the iBeacon format.

Unfortunately, iOS blocks access to the raw data of all BLE advertisements, including those of iBeacons. This makes it impossible to access the iBeacon identifiers with CoreBluetooth.

See details in this blog post.

Get advertisement data for BLE in iOS

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.

iOS and Android Max BLE advertise and scan bytes

Per Apple's Best Practices for Setting Up Your Local Device as a Peripheral:

Although advertising packets in general can hold a variety of
information about the peripheral device, you may advertise only your
device’s local name and the UUIDs of any services you want to
advertise. That is, when you create your advertising dictionary, you
may specify only the following two keys:
CBAdvertisementDataLocalNameKey and
CBAdvertisementDataServiceUUIDsKey. You receive an error if you
specify any other keys.

There are also limits as to how much space you can use when
advertising data. When your app is in the foreground, it can use up to
28 bytes of space in the initial advertisement data for any
combination of the two supported advertising data keys. If this space
is used up, there are an additional 10 bytes of space in the scan
response that can be used only for the local name. Any service UUIDs
that do not fit in the allotted space are added to a special
“overflow” area; they can be discovered only by an iOS device that is
explicitly scanning for them. While your app is in the background, the
local name is not advertised and all service UUIDs are place in the
overflow area.

Note: These sizes do not include the 2 bytes of header information
that are required for each new data type. The exact format of
advertising and response data is defined in the Bluetooth 4.0
specification, Volume 3, Part C, Section 11

If you use an unregistered 16 byte service UUID, I think that's going to give you about 12 bytes of data.

Available bytes in an advertising packet will differ from available bytes in a payload packet.

Bluetooth Low Energy: when scanning for advertisements, how are scan responses identified?

I assume you ask question about non-extended advertising.

See Spec, in chapter 6.B.2.3. Then:

  • Advertisement packet (ADV_IND) contains Advertiser 48-bit bluetooth address (AdvA) and Advertisement data (AdvData).
  • Scan request packet (SCAN_REQ) contains Scanner 48-bit bluetooth address (ScanA) and targetted Advertiser 48-bit bluetooth address (AdvA).
  • Scan response packet (SCAN_RSP) contains Advertiser 48-bit bluetooth address (AdvA) and Scan response data (ScanRspData).

Both AdvData and ScanRspData share the same format, but should not repeat the same contents. They should add-up. Whether to put a given Advertisement Data (AD) in advertisement or in scan response is a matter of optimization tradeoff between max length of advertisement packet and latency for scanning.

Some AD types have restrictions about where they should appear, see Core Specification Supplement for more info.



Related Topics



Leave a reply



Submit