This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

iOS scanForPeripheralsWithServices with UUID doesn't work for HRM etc

I'm trying to write an iOS app that scans for a specific UUID being advertised

e.g.

NSDictionary* options = [[NSDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithBool:YES], CBCentralManagerScanOptionAllowDuplicatesKey, nil];
CBUUID *hrmUUID = [CBUUID UUIDWithString:@"F5FF81D0-A7EE-367A-1583-B0A44AA94B23"];
CBUUID *watchUUID = [CBUUID UUIDWithString:@"0CC23A32-D8E2-BFFD-093B-B91BCB35E12C"];
            
            
[self.centralManager scanForPeripheralsWithServices:[NSArray arrayWithObjects:hrmUUID,watchUUID,nil] options:options];

However this does not work for the HRM (hrs) example, or the beacon example.

The UUID's I'm using were taken from the UUID's that the callback from scanning with nil passed as the UUID array (hence it finds all UUIDS)

I've checked these iDS in other programs like LightBlue etc on the iPad and the UUIDs are correct.

Both the HRM and the Smart Watch, both have services and are connectable. The Nordic toolbox finds and connects to the HRM

The Smartwatch's proprietary app will connect to it

So at the moment I'm stumpted about what I need to pass to the UUID array or what additional advertising data that the HRM etc need to send, for IOS to be able to scan for them.

I did take a look at the Nordic toolbox, but strangely the UUID is defined as 00001809-0000-1000-8000-00805F9B34FB

But this is not the value reported by iOS and also if I try using that value, it still doesn't work

I also tried searching for just one UUID

[self.centralManager scanForPeripheralsWithServices:[NSArray arrayWithObject:hrmUUID] options:nil];

But that didn't work either ;-(

Parents
  • I have realised that the UUID you can search for is not the UUID that is advertised, its basically the 16 bit Service ID plus some other unknown data

    So you can search for any devices that have the Heart Rate service ID 0x180D and the scan will return all devices that advertise this service ID.

    You can specify a full 128 bit UUID including the 0x180D service ID, and that also works if the whole 128 bits are correct.

    At the moment I have not worked out what the other data in the 128 bit service ID should be, as this ID works

    0000180D-0000-1000-8000-00805F9B34FB
    

    But changing the last digit from FB to F0 stops the scan finding the HRM

    The I'm not sure retainer of the 128 service UUID contains

    0000-1000-8000-00805F9B34FB

    And I found this list

    sviluppomobile.blogspot.com.au/.../bluetooth-services-uuids.html

    But they were all the same for the last 96 bits

    I'm not sure if this data e.g. the 00805F9B34FB can be set in the API, but even if it can, no one seems to change it

    So I'm just going to search for a specific 16 bit Service ID and ignore the remaining 96 bits, as this seems to work

  • Just to close off this subject

    I had not fully read the Bluetooth spec, and the advertising packet can contain either 16 bit or 128 bit service ID's

    Normally only 16 bits are used,and the other 96 bits are effectively defaulted to the code I listed above.

    Using 16 bit service ID's saves 14 bytes of precious space in the advertising data, so they are generally used in preference to 128 bit service IDs, as it leaves space in the advertising packet for the Name etc.

    Looking at various BLE devices e.g. Smart watches, they advertise multiple custom 16 bit service ID's e.g.0x5554

    But there are some instances where, you may not want your custom service to be confused with another custom service, in which case you should probably use the 128 bit service. But this doesnt leave much room for a name, or any other data to be sent as part of the advertisment

Reply
  • Just to close off this subject

    I had not fully read the Bluetooth spec, and the advertising packet can contain either 16 bit or 128 bit service ID's

    Normally only 16 bits are used,and the other 96 bits are effectively defaulted to the code I listed above.

    Using 16 bit service ID's saves 14 bytes of precious space in the advertising data, so they are generally used in preference to 128 bit service IDs, as it leaves space in the advertising packet for the Name etc.

    Looking at various BLE devices e.g. Smart watches, they advertise multiple custom 16 bit service ID's e.g.0x5554

    But there are some instances where, you may not want your custom service to be confused with another custom service, in which case you should probably use the 128 bit service. But this doesnt leave much room for a name, or any other data to be sent as part of the advertisment

Children
No Data
Related