I'm a new developer developing a BLE service on iOS and Android. Currently there is a problem that I am facing, that the device address on iOS is the UUID mapped from the mac address, and on Android it is the mac address of the device. So now is there a way on iOS, from the mac address I received can get the corresponding UUID? Thanks everyone!
I am not sure how to do it.
the device address on iOS is the UUID mapped from the mac address
This is incorrect. The peripheral ID is not "from" the MAC address. It's just a random UUID. It's not even stable (it can, and does, change over time, though not quickly). There is no way on iOS to get the MAC address of a BLE device, or even to absolutely uniquely identify a BLE device unless you control the firmware. If you do control the firmware, then you can provide some mechanism to uniquely identify the device over a protocol of your own design.
As a broad rule, you can use the peripheral ID to identify or connect to a device you've connected to before. This isn't 100%, because the ID does change sometimes. But for the most part it does work (and it's intended to work, so Apple won't just break this arbitrarily). But you cannot otherwise identify the device.
As a corollary, the peripheral ID on one iPhone is completely unrelated to the peripheral ID on another phone for the same device. This is intentional.
You will have to adjust your design to deal with these facts.
Related
I'm trying to use the ESP32 to check if my iPhone is in the house using the bluetooth.
The problem is that when I scan near devices with the ESP32's bluetooth, the iPhone only sends two things:
Mac address
Service UUID
The Mac address changes every 15 minutes more or less, so it's useless.
And the UUID is not unique.
I find other devices with the same UUID (strange)
Someone knows how can I workaround these limitations and recognise if my iPhone is near or not?
Thank you all!
This is all by design of Bluetooth. Bluetooth intentionally makes tracking unpaired devices difficult. See Bluetooth Technology
Protecting Your Privacy for a very high-level overview of how this works.
If you pair with the phone, you can get the IRK (Identity Resolution Key), and with that you get resolve the "real" MAC address and identify the phone. That said, if you're using esp-idf, the code indicates that it doesn't support RPA (Resolvable Private Address). See also BLE generating and resolving random mac addresses does not work correctly where they also suggest this is a limitation of the ESP32.
That said, iPhones do advertise a LocalName, and if this is just for use in your house, and you control your phone's device name, you can just look for that in the advertising packet. Note that the local name may be truncated or eliminated if it is long or there are other things the phone needs to advertise. If it's not advertising it, you can connect and read it from GAP. See How do you get the actual name of a bluetooth low energy device?
In iOS not possible to get mac address of CBPeripheral object.
Now I have no. of BLE devices with different UUIDs but with same peripheral name. User has to first register to that BLE device by registration command to that BLE device whose MAC address will get at the time of QR code scanning. But how can I get that to which device user is doing registration as in iOS I am not getting MAC address in peripheral?
As Dorian Roy notes, a good basic approach is to encode the MAC into the manufacturer specific data in the advertising packet. The MAC is 6 bytes, so you generally should have room if you're not already storing too much there. You can usually get away with the lower 3 bytes if all your devices have the same OUI (the manufacturer prefix).
I've actually designed systems that just advertise the last byte of the MAC, and then double-check by connecting to fetch the full MAC. You've got better than a 50% chance of no collisions until there's about 20 devices advertising in the same room. If there are likely fewer than 3 devices in the same room, then there's less than a 2% chance of collision (but remember, that means 1 in 50 situations will have a collision, so you can't ignore it). Obviously the more bytes you include, the better.
There is a subtle corner case with this design that may or may not matter to you. The device may already be BLE connected to the phone. This can happen due to another app (such as LightBlue), but also due to your own app. Say you connect to a device, and then your app dies and you're relaunched. The device may still be connected to the phone's BLE system, and it won't advertise. The way you discover that device is with retrieveConnectedPeripherals. But in that case, you'll never see an advertising packet. If this MAC-check is a one-time event, then this situation may not be a major issue for you, but it's something to remember if customers complain that your app can't find the device. (The easiest solution is to reboot the device, and if that's not possible, to reboot the phone.)
Paul's suggestion of exposing your MAC via a characteristic is a necessary piece, but it's comparatively slow, and a bit complicated in practice since there may be multiple devices advertising. I typically would start with the advertising packet if you can, and only connect to likely correct devices, and then check their characteristic. Connecting is expensive. Only connect if there's a good chance you're right.
I would like to get the MAC address of the device my iOS device connects to via BLE, but I can see only the UUID.
I've understood from searching the issue over the web that's it's not possible to get the MAC, but only in UUID. I've also understood that the UUID is generated by the iOS and that the device doesn't "know" it...however the posts i've found were old (2-3 years old) so I was wondering if anything has changed? Is there a way to get the MAC rather than the UUID, or at least reproduce the process that iOS does to convert UUID back to MAC address?
Thanks in advance
In iOS not possible to get mac address of CBPeripheral object. If CBPeripheral object advertisement mac address in "kCBAdvDataServiceData" value then convert to mac address, otherwise not possible. In iOS unique id is UUID for CBPeripheral. Every diff. iOS device shows diff. UUID of same CBPeripheral. If differentiate two or more CBPeripheral object then use RSSI range/value.
I'm working on an application for iOS (Objective-C).
I'm looking for a way to connect to a BLE device so that you can specify the MAC or UUID of this device.
Currently I have two BLE devices with the same name so the app is not able to differentiate between the two , which gives many problems (these devices do not have the same functions).
Is there any way to specify the MAC or UUID when connected to BLE device?
RSSI signal strength discover the differentiate two or more device.
If once time UUID get from peripheral then also differentiate peripheral.
Note: iOS doesn't give permission to read MAC address of peripheral.
The MAC of the device is not available, nor is any other particularly useful identifier. However, since "these devices do not have the same functions," they should have different services that they advertise. When calling scanForPeripherals(withServices:options:) you should be passing the specific service or services you're interested in. This is much better for performance, and also will automatically filter out devices you are not interested in. Passing nil for serviceUUIDs should only be done for a generic BLE scanner.
If you control the device firmware, you can add services to identify the type of device, or add information in the manufacturer's advertising data to distinguish the devices during scanning.
If these devices advertise the same services and are otherwise identical, then you will need to connect to both and query them to determine which device you wanted. You still will not receive a MAC, however, unless the device provides it via some characteristic.
Typically, a given device will continue to have the same CBPeripheral UUID, and this can be used to reconnect to previously known devices. However, if the device never pairs securely, this UUID is not always stable, either.
Why folks are using OpenUDID and not Mac address in iOS for identification? It would be straightforward to use Mac address. All mobil devices have Mac address, it is well known, and it is unique.
MAC Address contains network device's information, which may cause security breaches, tracking, etc. Using a meaningless OpenUDID protects the device and its owner.
You should never ever use the a device specific identifier to detect a device.
Devices change owner and this would mean that you if use sells his device the new user could end up with the data of the previous owner.