10

I want to see all of proximityUUID of advertising packets programmatically. Some articles say that it is impossible on iOS but Android is possible. But I cannot believe it because I found the fantastic app "BLExplr" has the feature. I need to implement the function into my app. Does anyone knows how to do it or good examples? Any help will be appreciated.

(UPDATE 2014/1/17)

I believe @davidgyoung answer is right. Estimote beacon's proximityUUID is "B9407F30-F5F8-466E-AFF9-25556B57FE6D" but displayed my Estimote beacon's UUID on BLExplr app is another ID.

enter image description here enter image description here

zono
  • 8,366
  • 21
  • 75
  • 113
  • I found an another app "Light Blue". This app has the same features. But I still cannot find a possible solution. Do I need to read BLE raw data by using Bluetooth framework..? (I am not sure whether it is possible or not) – zono Jan 16 '14 at 14:13

3 Answers3

28

Unfortunately, you cannot to this on iOS. When you say that BLExplr and LightBlue can do this, you are confusing the Bluetooth service UUID with the iBeacon Proximity UUID. These are two very different things.

The Bluetooth service UUID is visible to iOS, but has nothing to do with an iBeacon's identifiers, and is useless for working with iBeacons. The service UUID is generated by iOS each time a bluetooth device is seen, and stays the same only for the duration of time the bluetooth device is in range. If you take a bluetooth device away and bring it back later, it will have a different service UUID.

An iBeacon's identifiers (ProximityUUID, Major, Minor) are embedded inside the body of the Bluetooth advertisement. The problem on iOS devices is that Apple's CoreBluetooth APIs disallow access to the raw advertisement body, so no third-party app is able to read these identifiers. Apple only allows access to these identifiers using the special iBeacon CoreLocation APIs, but these APIs require you to know the Proximity UUID up front.

Sorry, I know this is not the answer you want to hear! (I'm sorry about it, too!) For what it's worth, you can do this on Android, MacOS, Linux and Windows.

See details here.

davidgyoung
  • 63,876
  • 14
  • 121
  • 204
  • 1
    Thanks a lot! You are right! I attached BLExplr's screen shot. The service UUID is different from Estimote beacons's Proximity UUID. – zono Jan 18 '14 at 02:28
  • 1
    @davidgyoung Can you tell then how the Radius Networks app 'Locate' in AppStore can read my UUID and Minor and Major values without me input them? I am developing an app that needs to fetch unknown UUID to compare them to what i have in a database. Cheers – Estevex Dec 01 '14 at 15:26
  • It can't. The app is preconfigured with a dozen or so popular UUIDs. You must have a popular one on your beacon. – davidgyoung Dec 02 '14 at 00:38
  • Ok thanks. I managed to figure out how to proceed. Thank you again – Estevex Dec 02 '14 at 09:07
  • @ Estevex Did you find any solution ? I also want to know how i detect beacon devices without knowing uuid in ios. – Akhtar Aug 08 '15 at 13:00
  • @davidgyoung Can we get the UUID, major and minor data from the "kCBAdvDataManufacturerData" if it is configured in such a way that all those details can be included in it ? – subin272 Oct 16 '18 at 11:51
8

davidgyoung is partially wrong about not being able to get iBeacon info. You actually can get the proximity UUID on OS X, but not iOS.

In a CBPeripheral's advertisingData, there should be a key called kCBAdvDataManufacturerData; It is an NSData representing the iBeacon advertising information. This key is only available on OS X.

Check that the 2nd byte is equal to 0x02, the 1st two bytes are equal to 0x004c (76 in decimal), and the 4th byte (in decimal) + 4 equals the data's length (should be 25).

NSRanges (sorry for Mac syntax)
Proximity UUID: NSMakeRange(4, 16)
Major: NSMakeRange(20,2)
Minor: NSMakeRange(22,2)

To make sure you're doing it right, you can log the values as hex (use the format string %x) and make sure they match the description of the NSData from whence they came.

Nate Symer
  • 2,185
  • 1
  • 20
  • 27
  • 1
    what ibeacon's did you use for this? it doesn't seem to work for estimote beacons. `advertisementData = { kCBAdvDataIsConnectable = 1; kCBAdvDataLocalName = estimote; kCBAdvDataServiceData = { "Device Information" = <0ec9686a 05d8b60e c9686a>; }; }` – YarGnawh Jun 25 '14 at 17:02
  • YarGnawh, I'm following the iBeacon profile's outline of advertising data. It's how CoreBluetooth's peripheral manager advertises. There may be other ways of advertising with beacons. Estimote may look for kCBAdvDataServiceData and connect to the beacon, then read a characteristic to get the major and minor. – Nate Symer Jul 02 '14 at 21:56
  • 1
    Furthermore, down voting an answer that provides correct information that answers the question (especially when others just dismiss the question) is asinine. – Nate Symer Jul 02 '14 at 21:58
  • An up vote for @Nathaniel Symer for providing correct information. I think I know the reason for your comment being down voted. Probably, people that read your post might not has enough information about iBeacon. The `kCBAdvDataManufacturerData` seems to be available only on the devices that comply to **iBeacon Bluetooth Profile** (defined by apple if i'm not mistaken) the mentioned information also discussed [here](http://stackoverflow.com/questions/18906988/what-is-the-ibeacon-bluetooth-profile). – Mysteltainn Oct 13 '14 at 08:45
  • 1
    continued from above, @NathanielSymer should add a simple message like "The proximity UUID **can be found on devices that comply to iBeacon Bluetooth Profile protocol**, on `advertisementData` with `kCBAdvDataManufacturerData` key" and you should remove the "davidyoung is **completely wrong**..." because he's not, he's just partly wrong and partly right. – Mysteltainn Oct 13 '14 at 08:51
  • Correct my above comment, _davidyoung_ is not partly wrong. From the answer, he also stated Bluetooth Service Identifier vs. iBeacon's Identifier which is pretty cleared answer. @NathanielSymer has provided additional information on the iBeacon's Identifier side. – Mysteltainn Oct 13 '14 at 08:59
  • 6
    I believe this technique will work on OSX, but not on iOS. My tests show that the key mentioned above is not present on iOS for iBeacon adverts. See here: http://developer.radiusnetworks.com/2013/10/21/corebluetooth-doesnt-let-you-see-ibeacons.html – davidgyoung Nov 05 '14 at 12:03
0
NSRange uuidRange = NSMakeRange(4, 16);
NSRange majorRange = NSMakeRange(20, 2);
NSRange minorRange = NSMakeRange(22, 2);
NSRange powerRange = NSMakeRange(24, 1);

Byte uuidBytes[16];
[data getBytes:&uuidBytes range:uuidRange];
NSUUID *uuid = [[NSUUID alloc] initWithUUIDBytes:uuidBytes];

int16_t majorBytes;
[data getBytes:&majorBytes range:majorRange];
int16_t majorBytesBig = (majorBytes >> 8) | (majorBytes << 8);

int16_t minorBytes;
[data getBytes:&minorBytes range:minorRange];
int16_t minorBytesBig = (minorBytes >> 8) | (minorBytes << 8);

int8_t powerByte;
[data getBytes:&powerByte range:powerRange];



return @{ @"uuid" : uuid,
          @"major" : @(majorBytesBig),
          @"minor" : @(minorBytesBig),
          @"power" : @(powerByte)
          };

but the uuid is the DeviceUUID, not the ProximityUUID

Jeanette Müller
  • 999
  • 1
  • 11
  • 19