I'm investigating the maximal amount of service UUIDs which can be scanned in background by Central manager.
It seems, a background scanning doesn't work for UUIDs count > 8. Which means, if I pass any number of UUIDs (e.g. 50 / 100 / 200 / 500), only the first 8 are discovered. (tested a lot)
In the Console.app, bluetoothd
complains that UUID count is more than 9. It's an [info] log. As I understand, it's just a private undocumented logic:
The central code:
func registerForScanning() {
// generate IDs
let services = pregeneratedUUIDs.map { CBUUID(string: $0) }
// start scanning
centralManager.scanForPeripherals(withServices: services, options: nil)
}
The peripheral code:
func generateNextService() {
let cbUUID = CBUUID(string: pregeneratedUUIDs[pregeneratedUUIDsIndex])
let service = CBMutableService(type: cbUUID, primary: true)
peripheralManager.removeAllServices()
peripheralManager.add(service)
pregeneratedUUIDsIndex = (pregeneratedUUIDsIndex 1) % pregeneratedUUIDs.count
}
The questions:
- Is a maximum allowed amount documented somewhere (I haven't found)
- Why 9: are there any hardware limitations to scan e.g. for 100 UUIDs?
- Have anyone met the same behaviour?
- Is there another way to scan for 50/100/200 UUIDs in background?
CodePudding user response:
Having a large list of UUIDs require a lot of RAM in the Bluetooth controller. If every advertisement must be checked against this list, that might also require too much realtime CPU time. I would assume the firmware developers mainly put this restriction to make it easy for themselves because it's a very unlikely use case to match against this many UUIDs. There are also similar (small) limits of the number of concurrently connected devices, the white list size, the resolvable address list etc. All of these limits are not documented or queryable through Apple's API.