BLE different peripheral name on different devices - ios

I am trying to connect BLE device using his hex number written on his peripheral name. but the peripheral name is different for some reason on different devices.
What could be the reason for that?
also i tried to find it inside advertisementData but without success.
thanks

Your device might have the shortened name in the advertisement data but have the longer one in the scan response.
If you're scanning while the app is in the foreground, you'll get the full scan response data, so it might not matter in your app. You just might have to ignore the first callback that doesn't have scan response data.

Related

How to send data through central mode to peripheral?

I'm developing an application where Client App starts BLE scanning in "Central" mode and there is a scanner App which Acts as "Peripheral",client will keep scanning for Scanners (Beacons) with specific id (where the Scanners are advertising the same id) when that both id match data is sent over BLE to the scanner app I have an example code which works perfectly from peripheral to central but i don't have idea about my case how it work.
The Demo which you are following is the correct one for a beginner. In this Demo, app is sending text data from TextView. The text data is passed in octet form, in iOS it is considered as Data (.utf8).
Now, question is, which type of data you want to send from Central to Peripheral.
The General flow is:
1. Central will proximate peripheral so that other Bluetooth manager can scan it.
2. Once anyone try to connect with that peripheral, then on successful connection, it will return available Services and Characteristics inside of those each services.
3. Based on characteristic, you can write your own logic to send text, images, audio, video or anyother data from Central to Peripheral.
Just follow the Demo link which you are following. Thanks.

Bluetooth LE iOS unable to scan in background

Setup, uniqueness of the situation, and success scanning in foreground
I am trying to pick up bluetooth readings from a CBPeripheral device. What is interesting about this particular device is that it sends out UUIDs that are embedding information in them directly. (This seems strange, but I don't know enough about BLE to know whether or not that's typical. There is no actual connection occurring in the end - only advertisements are being sent out.)
In the foreground, I am able to identify which readings are mine because [peripheral name] remains constant. So I'm able to pick up the readings that are relevant by doing the following check inside of didDiscoverPeripheral:
if ([[peripheral name] isEqualToString:#"UNIQUE_IDENTIFIER"]) {
NSLog(#"*** Got a reading ***");
}
This is working nicely in the foreground - I am running
[self.centralManager scanForPeripheralsWithServices:nil options:nil];
in a loop (details there seem irrelevant) and the code is able to print out all of the readings that I expect it to print.
Trouble scanning in background and attempts to solve
My app's Info.plist contains the following entry:
I have also check the (what I think is) the appropriate field in the Capabilities tab in XCode:
Neither of these things have turned out to be useful. didDiscoverPeripheral is called perfectly up until the point where I close my application, at which point it stops immediately.
One other thing that I read on the internet was that background processing still won't happen when scanForPeripheralsWithServices is called with nil, however if a non-empty array of services is passed instead, then it should succeed. I'm not sure if this is correct. The problem is, I have only been able to find examples of calling scanForPeripheralsWithServices where the services are identified by their UUIDs, for example
NSArray *services = #[[CBUUID UUIDWithString: #"2456f1b9-26e2-8f83-e744-f34f01e9d701"]];
[self.centralManager scanForPeripheralsWithServices:services options:nil];
but not their name property.
The question
So I guess my question, after all of this, would be: Would providing an array of name filters (instead of UUIDs) help the application to run in the background, and if so, how would I write that in code? If not, what am I missing such that my app still only works in the foreground?
EDIT: I had previously used the terminology "identifier" when I think I meant to say "name", so I went back and changed those. From the documentation, here is the name value that I would like to scan for in the background https://developer.apple.com/documentation/corebluetooth/cbperipheral/1519029-name?language=objc
In order to scan for new devices in the background you must specify the UUIDs of the service(s) that you are interested in. The documentation is quite clear on this.
The identifier for a device is a value locally determined by iOS, not the device itself and will vary for different iOS devices connecting to the same peripheral. If you know the identifier for a device that you have previously discovered then you can use the identifier to connect to the device but you can’t scan for an identifier.
It is possible for a peripheral to include data in its service advertisement and perhaps this is what your peripheral is doing. If so, then you will not be able to get readings in the background since duplicate device discovery events are not delivered when your app is in the background.
You can discover and connect to a new device in the background as long as you know the service that it is advertising but any subsequent data transfers will require the device to issue a notify on a changed characteristic. It cannot use the manufacturer data portion of the advertising frame.

iOS - corebluetooth retrieveConnectedPeripheralsWithServices: - how to get Advertisement Data?

I'm writing a suite of Bluetooth Low-Energy app for iOS 7.
When the app launches, there's a fair chance the peripheral I'm interested in is still connected to the iOS device, and to avoid scanning for the peripheral it would be great to connect immediately. retrieveConnectedPeripheralsWithServices: looks perfect for this, and indeed seems to work as advertised: I get a list of CBPeripherals which are connected to the device via some backgrounded app.
So far so good, but here's the issue:
There's information in the AdvertisementData which I want, but I don't know how to get the AdvertisementData when going this route.
As far as I can see, advertisementData is only available as a result of scanning.
So my question is this:
* Given a CBPeripheral returned by retrieveConnectedPeripheralsWithServices:, how can I get the associated advertisementData for that peripheral ?
One workaround would take advantage of the fact that the device was likely connected to another of the apps in my own suite, so I could persist the advertisement data myself in storage shared between the apps, but this is neither clean nor ideal, because there's a chance the device was connected to someone else's app, and so I'd have no insight into the advertisement data in that scenario, and would need to resort to a scan.
Unfortunately, the advertisement data is available only if you scan. It is not possible to retrieve it from Core Bluetooth or any other framework in any other way. You should revise your design if the advertisement is so important and rather go along the scanning route.

Bluetooth Low Energy Background Data (iBeacons)

I am currently writing an application that uses BTLE to pass small strings of data between 2 or more phones.
Currently in the foreground I am passing though: CBAdvertisementDataLocalNameKey and CBAdvertisementDataServiceUUIDsKey. I am able to recover (via NSLog) the string passed through the CBAdvertisementDataLocalNameKey when the app is in the foreground.
However when the app is in the background, the CBAdvertisementDataLocalNameKey is not passed through. The BTLE UUID is still passed through along with the RSSI integer, the CBAdvDataChannel and the CBAdvDataIsConnectable.
After combing through what seems to be an unending circle called Apple Documentation, I have found no way to pass a small string while the app is in the background. It seems to me that they wouldn't allow BTLE in the background if there was no way to pass data.
My question is does anyone know a workaround to pass data in the background with BTLE or a method that may allow me to do so? Any help or tips would be appreciated.
Edit: I should make clear that the Library I am trying this with is called Vicinity https://github.com/Instrument/Vicinity which uses CoreBluetooth to get around the background limitations of CoreLocation.
You might get some use out of this project, which lets devices share arrays of strings (such as userIDs) over Bluetooth LE, even while backgrounded: SimpleShare
It can still share data while the app is in the background because it only sends the data when a device subscribes to the advertised bluetooth characteristic by changing the characteristic's value to send each piece of data. You don't need the name key to transfer the information.
Hope that helps!
iBeacons are not made for transmitting data between two devices. BLE beacons are used to determine the current location of an iDevice. to unique identify the beacon it broadcasts the advertising data, wich contains an uuid(32 hexdigits), a major(4 hexdigits) and a minor number(4 hexdigits). thats all. if you want to transfer data you have to use any other service.

bluetooth low energy advertising packet and topology

I want to advertise a single id lets say "stackoverflow1" on a ble device. So people close to the sensor can get this message (welcome to wwdc2012) as popups on the iPhone. That's it! meaning that there is no update on the value or anything else in other words I just want to know which room I came in. In another room there's another sensor adversing "stackoverflow2".
Now the question is, should I put the rooms' sensor (advertiser) as Peripherals and visitors' iPhones as Centrals?
If your answer is yes, can I send this Id in advertising packet? i.e. can I skip connection to the room's peripheral? Please guide me a little but on this
Thanks
Yes, the iPhones should be centrals and the in-room device should be a peripheral. It's perfectly fine to put enough data in the advertisement that the iOS app can do something useful after simply seeing the peripheral advertised without actually connecting to it. That way, multiple centrals/phones can detect proximity at once without a single phone tying up an exclusive connection to the device. Instead of specifying the room in the service name, you should be able to put it in the advertisement data for the device, giving them all the same service name. That way the iOS app doesn't need to know the completely list of rooms (i.e. services) in advance and they can be added to without changing the app.
In short, the gist of what you described should work fine, and seems like a sound approach to me.
You can include information in the advertisement from the peripheral as "Manufacturer Specific" data. Then the iOS application can get it from the advertisement data dictionary using the CBAdvertisementDataManufacturerDataKey.

Resources