Yes, I know that there is no way to retrieve the MAC address of a BLE peripheral found by using the CoreBluetooth package, as discussed in other questions like here.
The company I'm working for has a test setup where we have different types of iPhones which should connect to different peripherals under test. For each peripheral under test, we know the MAC address. For our tests we need a specific iPhone to connect to a specific peripheral. The peripherals do differ only in their MAC address.
Since it is possible to have consistent peripheral ids on a single iOS device by using
public func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
let id = peripheral.identifier
}
we create a mapping table for each peripheral and each iPhone. Thus, we have a function similar to this one: (we don't use this one, but you get the idea)
func getMAC(peripheralId: String, iPhoneID: String) -> String {
if iPhoneID == "iPhoneFoo" && peripheralId == "uuid-peripheralFoo-iPhoneFoo" {
return "MAC-peripheralFoo"
}
else if iPhoneID == "iPhoneFoo" && peripheralId == "uuid-peripheralBar-iPhoneFoo" {
return "MAC-peripheralBar"
}
else if iPhoneID == "iPhoneBar" && peripheralId == "uuid-peripheralFoo-iPhoneBar" {
return "MAC-peripheralFoo"
}
else if iPhoneID == "iPhoneBar" && peripheralId == "uuid-peripheralBar-iPhoneBar" {
return "MAC-peripheralBar"
}
else {
return "unkown"
}
}
We use the output of this function to check if a found peripheral matches the MAC address it should search for. As you can guess, it is very tedious to make this mapping function, especially, if new iPhones or new peripherals enter the test setup.
My question is now: Is there a way to "calculate" the peripheral Id of a device if you know the MAC address beforehand?
So something like a function, where you provide the MAC address and retrieve the uuid, as if a device was actually found by performing a BLE scan?
Thanks in advance!
No, there isn't. The Bluetooth device address can't be used alone to get the uuid device identifier. In fact, the identifier will be different depending on which phone you use to scan.
As Emil notes, the identifier will be different on different phones. It can even change on the same phone. Peripheral IDs are not promised to be stable and they do change from time to time. There is no way to uniquely identify an arbitrary device when you don't control the firmware. (And if you find a way, expect Apple to break it eventually. They hide this stuff on purpose to prevent user tracking.)
If you do control the firmware, I recommend putting identifying information in the advertising data. I personally generally put identifiers in the manufacturers data, but for your situation the Local Name is probably the most convenient (and may even be settable for firmware you don't control). There are tons of other solutions. I even advertised per-device service UUIDs in one project (this is nice because it means you can easily limit your scanForPeripherals
call to look for specific devices in the background).
If you go down this road (assuming you control your firmware), be very thoughtful about user privacy if you store an identifier in the advertising packet. Anything that doesn't change can allow your users to be tracked. There are various good solutions to this problem. I generally base mine on the IRK system that BLE uses to hide MAC addresses. (This may not impact you because this seems to be for internal testing, but I always want to warn people about the privacy concerns of long-lived identifiers.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With