CainaSouza
CainaSouza

Reputation: 1437

Wrong proximity UUID

I'm working on an app where I need to present a list of bluetooth devices around me where the proximity UUID contains a certain substring. I cloned the repo https://github.com/mlwelles/BeaconScanner and ran the app on my computer and it finds correctly the two beacons I have. They use the code below to parse the advertising data.

+(HGBeacon *)beaconWithManufacturerAdvertisementData:(NSData *)data {
    if ([data length] != 25) {
        return nil;
    }

    u_int16_t companyIdentifier,major,minor = 0;

    int8_t measuredPower,dataType, dataLength = 0;
    char uuidBytes[17] = {0};

    NSRange companyIDRange = NSMakeRange(0,2);
    [data getBytes:&companyIdentifier range:companyIDRange];
    if (companyIdentifier != 0x4C) {
        return nil;
    }
    NSRange dataTypeRange = NSMakeRange(2,1);
    [data getBytes:&dataType range:dataTypeRange];
    if (dataType != 0x02) {
        return nil;
    }
    NSRange dataLengthRange = NSMakeRange(3,1);
    [data getBytes:&dataLength range:dataLengthRange];
    if (dataLength != 0x15) {
        return nil;
    }

    NSRange uuidRange = NSMakeRange(4, 16);
    NSRange majorRange = NSMakeRange(20, 2);
    NSRange minorRange = NSMakeRange(22, 2);
    NSRange powerRange = NSMakeRange(24, 1);
    [data getBytes:&uuidBytes range:uuidRange];
    NSUUID *proximityUUID = [[NSUUID alloc] initWithUUIDBytes:(const unsigned char*)&uuidBytes];
    [data getBytes:&major range:majorRange];
    major = (major >> 8) | (major << 8);
    [data getBytes:&minor range:minorRange];
    minor = (minor >> 8) | (minor << 8);
    [data getBytes:&measuredPower range:powerRange];
    HGBeacon *beaconAdvertisementData = [[HGBeacon alloc] initWithProximityUUID:proximityUUID
                                                                          major:[NSNumber numberWithUnsignedInteger:major]
                                                                          minor:[NSNumber numberWithUnsignedInteger:minor]
                                                                  measuredPower:[NSNumber numberWithShort:measuredPower]];
    return beaconAdvertisementData;
}

I took this fragment of code, adapted accordingly, and included on my iOS code, but the UUID from the devices found are completely different from the ones presented on the MacOS app.

Does anyone know if there's any kind of difference on the advertising data between iOS and MacOS?

Thanks

Upvotes: 0

Views: 276

Answers (1)

davidgyoung
davidgyoung

Reputation: 64941

The NSData you are reading on iOS is likely not the manufacturer advertisement data associated with your beacon. Apple actually blocks delivery of this data on iOS if the byte pattern matches an iBeacon frame. See my blog post about that here.

Are you sure that is the exact code you are running on iOS? Because if so, I would expect it would never find the 4c 02 15 byte sequence that is needed to get to the bottom of the method and parse the ProximityUUID.

If somehow you have code that bypasses those checks on iOS, it may be that you are parsing some other arbitrary packet that is not an iBeacon frame at all.

Upvotes: 1

Related Questions