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
How to Access the Accelerometer from the Apple Watch
How to Add Firebase to Today Extension iOS
Objective C- Trouble Updating UI on Main Thread
What Is the Use of Singleton Class in Objective-C
Xamarin "The Executable Was Signed with Invalid Entitlements"
Build Information in iOS Application (Date/Time App Was Built)
How to Tell If an iOS Device Has a Gps
How to Separate Emojis Entered (Through Default Keyboard) on Textfield
Installing Openssl Library for Xcode
Geofire Query on User Location
Which Phassetcollection to Use for Saving an Image
How to Create a Uiimage with Uibezierpath
Swift 3- How to Get Button in Uicollectionviewcell Work
Fbsopenapplicationerrordomain Code=3