Unique identifier for peripheral BLE device - ios

So I have peripheral BLE device and I need some identifier for it to later share with another iPhone. Example I connect with iPhone 'A' to peripheral. iPhone 'A' saves peripheral's identifier to database and later I easily can take iPhone 'B' and connect to the peripheral found by this identifier.
Now there is UUID what changes for every iPhone-peripheral connection, but MAC
Address is not available. What could you suggest?

If you do not manufacture the peripheral yourself then you can not uniquely identify peripherals across different iOS devices. This is exactly how Apple wants it to be since it means that developers can't track user's locations or movement patterns based on device addresses. It would be a privacy concern.
If you manufacture the peripheral yourself then you can do pretty much whatever you want. For example: Use a custom Service uuid, add uuid to manufacturer data in advertisement, set unique advertisement names, etc etc.. But if the core purpose of all this is to track your user then I would guess that Apple might deny your submission.

I have a similar problem and many thread like this say you cannot obtain MAC address by CoreBluetooth. I want to connect to a BLE peripheral (I mean open and connectable peripheral) and store some information on a database so that a different iPhone can read the same database and use the informations when it connects to the same kind of BLE peripheral. For now I rely on the device name, obtained like this:
-(void)addDiscoveredDevice:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
NSString * name = [peripheral name];
}
because NSString * uuid = [[peripheral identifier] UUIDString]; gives me different results on different iOS devices.
Therefore, let's say my first problem is to know how many Apple Watch I have close to my iPhone, the second problem is to know if a given Apple Watch (e.g. John's Apple Watch) is close to my iPhone. Unfortunately this method doesn't work because users (e.g. John) or companies can change the name of their peripherals.
Yes I can rely on a combination of name + service uuid + characteristic uuid but for the same reasons, if the name changes it is useless.
Does anybody found a solution?

Related

Get own Bluetooth unique id

My question is how can we detect our own device's unique bluetooth ID (must be available from other device when we scan for nearby available bluetooth)
I tried this
CBUUID *myService = [CBUUID UUIDWithString: #"MyServiceID"];
but in my case this is same as device UUDI.
You can’t. Apple works hard to ensure that apps can not access any identifiers that uniquely identify a device; the Bluetooth MAC address would be such an identifier.
The Bluetooth identifiers that are reported by Core Bluetooth on another iOS device are local to that device.
You could allocate your own UUID and make that available via a characteristic. That way you would know what value the remote device would see, but it would need to connect to retrieve the value. You could also put a specific name in the advertising data.

how to get public Bluetooth Device Address using core_bluetooth

We have one bluetooth devices.Bluetooth devices have one public bluetooth device address(BDA).In android they get bluetooth like (30:03:5B:00:15:12).I can get only device name and device UUID
like this
-(void) centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
NSLog(#"Discovered peripheral %# (%#) (%#)",peripheral.name,peripheral.identifier.UUIDString); //PHARMACELL CAREOUSEL (0BEF07EA-7680-4223-2D5E-6CE159333F7E)
}
Please any one guide to us how to get BDA value
The simple answer is clearly: NO.
It is not possible (practically) to get the BDA from the seeds that generated a particular UUID. Provided that in fact the algorithm that generated your UUID did used the MAC Address of your device to generate it, and I guess you cannot guarantee that it is the case for the UUID generator you use, unless you have access to the UUID Generator code or algorithm.
As apple while generating UUID might use the MAC address of the device, other components like timestamps, hashing, UDID (iOS Devices) and also some other factors so its looks impossible to get it back from UDID also.
Android 6 has REMOVED ability to read own Device WIFI and BT MAC address, they will be hardcoded to 02:00:00:00:00:00.
This is "to protect user data" or more correctly "privacy". Too many big mall's have abused harvesting these addresses for getting user behavioral information.
On iOS it is not possible to get the MAC address of the device, it's abstracted by the CBPeripheral class and is identified internally in os by the identifier property. One way to get the MAC address, that's actually most popular, is to include the MAC address in the scan response. You could ask this feature from your BLE device manufacturer. Also the MAC address could be read from one of the GATT characteristics. Ask your BLE manufacturer for more details.

Core Bluetooth determines the peripheral device as unique

How does core bluetooth determine the new peripheral device as unique?
I have devices. Each device has services. Each service has characteristics.
When we test bluetooth-based app, it appears, that some (different) devices have same uids ( peripheral.identifiers ).
I think that it happens because of lack of advertising information on device ( devices don't advertising services and they coalescing into one peripheral.identifier )
I suppose that services can't differ (could/should be the same) among devices, the same story with characteristics.
So, which info should be enough for bluetooth to determine that new peripheral device is unique?
Our experiment
We have two devices, one with name 'oldboy' and another with name 'newone'.
Also, we have same services on each device ( services has same structure and same uuids. services uids and characteristics uids are the same across all devices )
Names are differ between devices.
Sad, devices don't advertising services and app scan for all services passing nil to appropriate method scanServices: options: instead of services uids array. It could be done but it doesn't help in background and seems very bad for energy efficiency.
Server send information about all devices that could be found.
We suppose, that uids are not generated by system and we can hardcode uid of devices and differ devices on this characteristic ( peripheral.identifier )
One iDevice have tested app with perihperal device called 'oldboy' very long.
And this iDevice should work with another device called 'newone'.
As it started to scan, it found an device with name = 'newone' and 'peripheral.identifier = peripheral(oldboy).identifier'.
Again, it can't be true, so, we disconnect all devices except 'newone' and restart experiment. Ok, same issue.
And final check was on interaction. We connect to device ('newone') and try to send command to it. Nothing happens. But when we try to send command to 'oldboy' device, we win!
I dive into this issue and found that connected 'newone' device identifier somehow equal to 'oldboy' device identifier.
It happens in didDiscoverPeripheral handler. So, before connection system recognize 'newone' peripheral device as a 'oldboy' peripheral device ( their peripheral.identifier are equal )
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
// take peripheral info ?
// check that peripheral identifier is valid for us
BOOL identifierIsOk = YES;
DDLogDebug(#"we found! peripheral: %# ", peripheral);
DDLogDebug(#"and data: %#",advertisementData);
if (identifierIsOk) {
// put peripheral into dictionary storage and try to connect and discover services and characteristics
[self centralManager:central safeConnectToPeripheral:peripheral];
}
}
BUG
Finally, we solved our troubles.
We found that MAC addresses are same on different devices!
Afterwords, I want to add this article as core bluetooth understanding tool

How to find the specific BLE 4.0 peripheral from two devices with same service UUID

For BLE 4.0, it provides API to discover peripherals with array of service UUID.
I just want to find the specific one. How to achieve this ?
If need assign the identifier to the specific device, how to do it ?
(I think my question need some context of core bluetooth of iOS. )
The process for reconnecting to known peripherals is described in the Core Bluetooth Programming Guide.
Essentially if you know the UUID of the device you want to reconnect to (which is the identifier property of the CBPeripheral object) then you can use the retrievePeripheralsWithIdentifiers: method of the CBCentralManager to obtain the CBPeripheral object and then attempt a connection -
NSUUID *pid=[[NSUUID alloc]initWithUUIDString:#"45D956BB-75E4-6CEB-C06C-D531B00174E4" ];
NSArray *peripherals=[self.centralManager retrievePeripheralsWithIdentifiers:#[pid]];
if ([peripherals count]>0)
{
CBPeripheral *peripheral=[peripherals objectAtIndex:0];
peripheral.delegate=self;
[self.connectingPeripherals addObject:peripheral];
NSLog(#"Found peripheral %# with name %#",peripheral.identifier,peripheral.name);
[self.centralManager connectPeripheral:peripheral options:nil];
}
This may not work, and you may have to scan for your peripheral as the identifier of some peripherals (iOS devices in particular) periodically change their UUID.
The programming guide notes -
Note: A peripheral device may not be available to be connected to for
a few reasons. For instance, the device may not be in the vicinity of
the central. In addition, some Bluetooth low energy devices use a
random device address that changes periodically. Therefore, even if
the device is nearby, the address of the device may have changed since
the last time it was discovered by the system, in which case the
CBPeripheral object you are trying to connect to doesn’t correspond to
the actual peripheral device. If you cannot reconnect to the
peripheral because its address has changed, you must rediscover it
using the scanForPeripheralsWithServices:options: method.
You will also have to scan the first time you encounter a peripheral.
Tell me if I'm wrong. You have 2 devices working as central role who wants to connect to one BLE peripheral.
What it is important is the UUID of the services in the BLE peripheral. From your devices in central role you should search peripherals with a wanted UUID Service. Thats all.
To develop with iOS please follow Core Bluetooth Programming Guide. You have a good tutorial there.
As an example of the Apple documentation:
[myCentralManager scanForPeripheralsWithServices:nil options:nil];
In this line of code you can add an Array of UUID objects (CBUUID) instead of nil for scanForPeripheralsWithServices:

iOS CoreBluetooth reconnecting device with UUID

I have a Bluetooth 4.0 (BLE) device using the CC2541 chipset which I am interfacing with via the iOS Core Bluetooth Framework.
I can successfully make a connection to the device using Core Bluetooth when the device is in a discoverable/advertising mode and transfer data to and from the device without any problem.
I maintain a collection of device UUIDs that I have connected with and I am now attempting to connect to one of these devices again using:
CBCentralManager
- (void)retrievePeripherals:(NSArray *)peripheralUUIDs
Calling this function appears to work and I receive a callback to my implementation of the the following function:
CBCentralManagerDelegate
- (void)centralManager:(CBCentralManager *)central didRetrievePeripherals:(NSArray *)peripherals
The device I'm attempting to connect with is the one and only peripheral listed in the peripherals array that is passed to this function.
When I then attempt to connect to this device using my connect function (shown below) the connection will not initiate and I get no callbacks at all on either the CBCentralManagerDelegate or the CBPeripheralDelegate.
- (void) connectPeripheral:(CBPeripheral *)peripheral {
NSLog(#"Connecting to peripheral with UUID : %s\r\n",[self UUIDToString:peripheral.UUID]);
activePeripheral = peripheral;
activePeripheral.delegate = self;
[CM connectPeripheral:activePeripheral options:nil];
}
I can make the connection go through successfully, as described above, if I first place the device into discoverable/advertising mode, but this is not a workable solution. The device must allow reconnection without it being placed into discoverable mode.
I did note the answer given to this question CoreBluetooth: What is the lifetime of unique UUIDs suggests I need to pair/bond the BLE device with the iOS device but that this may be dependent on the BLE chipset, the device I'm using is the CC2541. Any advice on how to go about pairing with the device would be most useful, or indeed whether this is a necessary step. I have attempted to watch WWDC 2012: Advanced Core Bluetooth which might give me some assistance, but since Apple were hacked on Thursday I'm not able to access my acccount to watch the video.
Please let me know if any more details are required. The Bluetooth device is stable, but it is being developed internally. If changes may be required to the firmware to assist with the pairing process, I can pass this information along to the electronics team.
Why dont you try this?
It specifies first you need to send a request to a GATT characteristic that requires GATT_AUTHEN_READ permission. Then your CC2541 will respond with INVALID AUTHENTICATION. This will trigger Apple's internal Bonding mechanism and ask for a key. You can enter the passkey and then if the device and CC2541 are successfully paired, it will read the characteristic value and enter your callback.
NOTE: I'm not an iOS developer, but I have worked with CC2541. If you are using the default simplePEripheral example, then a characteristic in simpleProfile characteristic5 requires authentication to read. Take a look at profiles/SimpleProfile/simpleGATTprofile.c

Resources