iOS: Bluetooth Low Energy: One physical device, different services for different connections -> Trouble? - ios

I am having an issue concerning Bluetooth Low Energy. I am using an iPhone (iOS 6.1) and an Nordic board using the nRF51822 chip.
I am currently developing a system where the iPhone and the nRF51822 connect using certain services, then disconnect and reconnect again. However, on the second connection, the nRF51822 uses different services from the first connection.
The problem is that on the second connection, the iPhone discovers the former services of the first connection. I have tested with a TI CC2540 development board and it discovers the new services well. The only solution I have found is to put the central manager to nil and allocate it again to make it work. Nevertheless, it seems kind of a dirty solution, is there a standard (clean) way to deal with this kind of situation?

If you don't do any bonding, but only pairing, then you would not have this issue.
If you do require bonding, then the best way to solve this problem is to use the Bond-manager that is in the SDK. If you are not using the bond manager, you could try to use the Service Changed functionallity and set the start handle to 0x000C, and end handle to 0xFFFF. This would most likely trigger a rediscovery from the iOS, thus finding your new services and characteristics. The iOS would always look for service changed, and enable this in the peripheral.
If you have any Nordic related question, then you could post them at the Q&A forum located at https://devzone.nordicsemi.com/
BR
Pål

Services and characteristics are cached on the iOS side when you initiate a pairing request with a ble device and discover services/characteristics. Don't do the pairing request if you're concerned about that. Then just pass in the array of services you actually want to discover (not nil).
(Side note: The whole thing of having the ble device controlling which services are seen to the iOS device seems really muddled..you should control that on the iOS side.)

Related

iOS: scanForPeripheralsWithServices can't find device while nRF Connect app is able to find it

I have a BLE peripheral running on Raspberry Pi with gobbledegook.
In parallel, I have an iOS app working as BLE central which does a scanForPeripheralsWithServices with nil in order to detect all the devices around.
I'm able to detect a few devices, but not the one running on Raspberry Pi.
However, when scanning with the nRF Connect app on iOS, I'm able to see it.
How is that possible? (I assume that nRF Connect is also using Core Bluetooth...)
You're likely doing something (such as using the nRF Connect app) to connect to the device, causing it to stop advertising. Most BLE platforms stop advertising when they are connected to.
Use retrieveConnectedPeripherals(withServices:) to detect devices that are already connected. You must provide a list of services; there is no way to detect all devices currently connected.
Since this is on a Pi, you can also verify on that side whether the system is really currently advertising and whether it has any connections. Core Bluetooth does extensive caching, which can lead to things appearing to be happen that actually are coming out of cache. I haven't recently dug into the nRF app to verify how much it relies on the cache. I recommend also testing with LightBlue, and testing with multiple devices simultaneously (I typically use multiple apps on iOS, Android, and Mac, and occasionally an Ubertooth, to verify what I'm seeing is true).
Note also that once you've seen an advertisement from a device once, you won't see any more during that scan unless you set CBCentralManagerScanOptionAllowDuplicatesKey to true in you scan options. That flag is ignored in the background. This probably isn't the issue in this case, but often trips people up who are used to other platforms. Similarly it is almost always faster and more reliable to scan for specific services rather than nil unless you're building a generic BLE scanner. (Again, I doubt that's the problem in this case.)

General questions about Bluetooth

I have been fiddling with Bluetooth lately and I feel as if there is some elusive thing I am missing, anyways here are some of my questions. What I want is to have my Bluetooth enabled laptop running Windows, communicate with my iOS and later Android devices.
Is Bluetooth LE compatible with older Bluetooth technologies?
-My believe is that Bluetooth LE is the same as other Bluetooth versions
only that of course, as the name implies, it is low power. My confusion arises from the fact that on the iOS page they refer to some of the schemes as GAT servers , and what I am guessing is another protocol, ATT. Upon reading the article posted Here there is no mention of these two only L2CAP. As well as there is no mention of those in the Bluetooth API for windows Programming with Windows sockets The protocol that this article mentions is RFCOMM
-How is a connection between the two devices started?
I know that there are service ID's which can be published in an internal Service Description server according to the article previously referenced. However there is no concrete mentioning on the iOS bluetooth pages. They mention peripherals advertising bundles of data and the central device connecting to it. No mention of SDP, unsure if the windows docs do. And I' am bit confused about how the process flows, do the two devices connect first and then one device checks what services are available and the other one subscribes? Here by services I mean which applications are running, and by connection I mean as in establishing a connection from say (in iOS) Settings>Bluetooth and then starting the application on your phone, and then it is able to scan, or can the process of enabling Bluetooth and establishing a connection be done in the application itself. Same for windows, do I have to start the Bluetooth device by Settings>Bluetooth or can it be triggered within the Bluetooth enabled application?
-Is it pivotal to assign which device is the central and which is the peripheral?
Since at the end of the day they are able to both exchange data. In my case I want to have my computer running windows communicate with my iOS 7 device. Now as mentioned there are two roles that you could choose from in iOS: Peripheral and Central. It makes sense to me that the phone should be a peripheral since the main application will run on my computer, and I want my computer to enter the listening state before the device, and have the device connect afterwards. But it makes sense to have my computer advertise its services and then letting the iOS application choose the correct one. If someone could give me some pointers on what the best practices are and how to tackle this problem, I'd appreciate it.

Why, sometimes, do I need to restart the iOS Bluetooth (using the system button) to make my central manager able to connect successfully?

I'm developing an application on iOS and OS X Yosemite which is using CoreBluetooth on iOS and IOBluetooth on Mac.
The iOS app plays the "central" role while the Mac app is playing the "peripheral" role.
Basically, the iOS app (the central) starts a scan to find peripherals and when it finds a Mac advertising peripherals data, the central connects to it and can discover its services and characteristics.
My problem is that sometimes, I don't know why, the iOS app starts a scan to find a Mac advertising and when it finds it (this step work all the time), it tries to connect to it but never succeed.
To make it able to connect successfully to the peripheral again, I need to turn off and then turn on the Bluetooth from the iOS button.
Another strange thing is : imagine the central is in the same situation (trying to connect with no success). On OS X if I click on the Network icon (with the Wifi symbol) in the system status bar, then it will display the list of all available Wifi networks, and when it adds to the list my iPhone as a "Personal hotspot", at this time the central (which is on the iPhone) manages to connect to the peripheral (the Mac).
With this problem, the app usage is a lot compromised because randomly the iPhone will not be able to connect to the Mac.
I spent a lot of days on the internet (Google, Stackoverflow, ...) to find similar cases. I read a lot of articles and tried a lot of things like stopping the scan and starting it again if the connection didn't succeed after 10 seconds for example.
Don't hesitate to tell me if my question is not clear. I will update it if needed.
Thanks a lot in advance for your help.
I really need to find a way to fix this.
I don't have an answer (and not enough rep to comment) but I have been experiencing a very similar problem for months now. My iOS app which is playing the central role sometimes fails to discover services on the peripheral (linux) which can only be fixed by power cycling the bluetooth radio on my iOS device via settings/bluetooth. After bouncing the bluetooth radio, peripheral discovery appears to works perfectly.
I've found two reproducible cases: (1) If on my peripheral I completely swap out the service being advertised (i.e. change the service UUID and all characteristics) then the iOS peripheral will detect the peripheral with this new service during the scan, but service discovery fails. I find that peripheral:didDiscoverServices gets invoked, but the list of services is empty for this peripheral. (2) If on my peripheral, I modify the list of characteristics in any way (add a new one, remove one) the iOS app does not notice this change at all. During characteristics discovery, the same list of characteristics (prior to modification) is presented. Again, power-cycling the bluetooth radio on the iOS device appears to be the only thing that fixes this.
It appears as though iOS is caching BTLE peripheral services and characteristics upon discovering a new peripheral and the only way to flush this cache is to power cycle the bluetooth radio.

Core Bluetooth unable to discover peripheral

I am working with hardware that is in the process of being developed. The board uses a TI CC2541 as the bluetooth chip.
Prior to a test the board is discoverable by two devices and I am able to connect to the board and perform a test where I write and read characteristics (GATT). I perform the test again, everything goes fine until I reconnect to the device and attempt to discover its services. At that point, the board is offline and neither lightblue nor my own app can detect the device. I did a factory reset on one of the iOS devices (iPads) and it is still unable to recognize the board.
Should a factory reset remove all corebluetooth caching that has happened on the device, allowing iOS to re-cache and rediscover the board?
Can this possibly be a corebluetooth problem or a problem with my app?
Your problem seems to be related to the external peripheral. Factory reset will remove any cached data from the iOS device so as long as the peripheral behaves correctly, the rediscovery should happen as planned. This is all I can tell from the info you shared.
This issue seems to be related to hanging / adding characteristics on a peripheral during development.
I have had a similar issue and instead of clearing the cache on the iOS device, I change the Bluetooth address of the peripheral. This allows the discovery to work as expected.

Bluetooth Communication between OSX and iOS

I'm working on an application that does does lots of iOS <--> OSX communication. For the most part I have this solved.
I'm using CocoaPort to do the communication. Over Wifi this worked nicely and was plenty fast.
I'm using Bonjour to find my server. This required publishing the service with a modded DNSSDObjects-style net service on iOS. Apparently services published over Bluetooth on OSX cannot be seen by iOS, but the other way round works nicely, except that you need to keep the devices paired and connected.
Now my question is, how can I improve the speed of the Bluetooth connection? I'm getting maybe 100kb/s max and that seems to just stop after about 1 minute even though the connection is still open.
I think I need to use the AMP/HS stuff in Bluetooth 3.0 to get a fast connection. My understanding is this creates an AdHoc wireless network between my devices (MBP retina and iPad3, so should be capable of a decent speed.)
According to Wiki, Bluetooth 4.0 includes the HS spec in Bluetooth 3.0 and according to Bluetooth Explorer, the iPad is 4.0 spec. Is there a way, maybe via IOBluetooth, to request a high speed connection?
According to an engineer # Apple, this is not currently feasible. The best you can do is Bluetooth Classic, which is probably the speed I'm getting.
If you want this feature, consider opening a feature request at bugreporter.apple.com.

Resources