2

I'm using the scanForPeripherals method to retrieve UUIDs from devices near me.

I am able to list UUIDs, however, they are not similar with the UUIDs discovered using nRF Connect application. I tried various testing scenarios, in which I've configure a specific UUID for a peripheral (in another app, installed on a different phone) and tried to discover it using my code, but this too proved unsuccessful (yes, the nRF Connect managed to see the right UUID).

Please see this simplified version of the code:

class ViewController: UIViewController {
    var centralManager      : CBCentralManager!
    var peripherals         : [CBPeripheral] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //Initialise CoreBluetooth Central Manager
        centralManager = CBCentralManager(delegate: self, queue: DispatchQueue.main)
    }
}

extension ViewController: CBCentralManagerDelegate {
    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        if (central.state == .poweredOn){
            self.centralManager?.scanForPeripherals(withServices: nil, options: nil)
        }
        else {
            // do something like alert the user that ble is not on
        }
    }
    
    func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
        peripherals.append(peripheral)
        print(peripheral.identifier.uuidString)
    }
}

I would like to know why the UUID's appear to be different, and what can I do to discover the same UUIDs as nRF Connect.

  • Which UUID are you describing that nRF Connect reads? I don't see any device-specific UUIDs in nRF Connect's output (perhaps this is a Nordic-specific feature? I'm testing with non-Nordic devices.) The standard identifier for BLE devices is their MAC, not a UUID. `peripheral.identifier` is generated by the OS, and is not related to anything on the device. In general there is no way to get a stable identifier in iOS for a BLE device that is consistent across centrals. – Rob Napier Jul 27 '20 at 14:06
  • A good place to start is looking at the `advertisementData` section. It's possible there's a Nordic-specific piece of information being advertised. The UUID you have in mind may also be a Service UUID (which can be used by devices to identify themselves, even though that's not its primary purpose), in which case you'd find it by discovering services. – Rob Napier Jul 27 '20 at 14:16
  • Thank you, your suggestion shed some light! I was indeed referring to Service UUID. – Stefan Mihai Jul 27 '20 at 19:57
  • If you can, please, post an answer to accept it. – Stefan Mihai Jul 27 '20 at 20:04

1 Answers1

2

BLE devices generally do not have a UUID themselves. The CBPeripheral.identifier is an internal identifier created by the OS just for internal usage. The UUID you're looking for is a Service UUID, which may be available through the advertising packet, or may only be available by discovery. (There should never be a UUID in the advertising packet that isn't available through discovery, but I did run into a device with buggy firmware just last week where this happened, so it's possible.)

If the Service UUID is being advertised, then you can limit your scan to just devices that include that UUID by passing it to scanForPeripherals. This is the preferred way to scan. You can fetch the list of advertised services from the advertisementData dictionary using the CBAdvertisementDataServiceUUIDsKey key.

If the service is not advertised, then you'll need to call discoverServices. When didDiscoverServices is called back, you'll find the list of services in the peripheral.services property.

Rob Napier
  • 286,113
  • 34
  • 456
  • 610