How long central manager scan for peripherals? - ios

I start working with CoreBluetooth for a week, but I dont know how to reconnect to the peripheral after losing connection.
For example, my CBCentralManager connect to peripheral A, the real manager on iPhone said 'Connected', then I go away for awhile, the CBCentralManager lost connection to the peripheral A, the real manager on iPhone said 'Not Connected'. Then I go back, the CBCentralManager doesn't reconnect to peripheral A, but the real manager on iPhone said 'Connected'.
How can I make my CBCentralManager reconnect automatically?
Sorry for my bad English.

Related

Bluetooth Peripheral detect connected state

I created a function which turns an iPad without gps chip into a bluetooth peripheral and any device (iPhone or iPad) with gps chip into a broadcaster.
These 2 devices then connect with each other without asking to pair (as intended). (see this post for the code I wrote)
However I want to show the connected state in both the peripheral and broadcaster. The broadcaster has a function to check the connection state. The peripheral doesn't seem to have this.
Does anyone know of a way to determine at the peripheral side if the connection is still connected or not.

Failed to retrieve services of a CBPeripheral after restart the peripheral

I have a problem while trying to reconnect with a paired peripheral, it connects but I can not find the services.
The steps are as follows.
Turn on the peripheral device and open app.
Find the peripheral after scan. OK
Connect to the peripheral. OK
Save peripheral id for future reconnection.
Find the services / Characteristics. OK
Now I disabled the bluetooth from IOS and turned it on again to test the reconnection.
Find the peripheral after scan. OK
Connect to the peripheral with saved id. OK
Find the services / Characteristics. OK
Now I closed the app and reopen to test again.
Find the peripheral after scan. OK
Connect to the peripheral with saved id. OK
Find the services / Characteristics. OK
Now turn off the peripheral and then turn on again.
Find the peripheral after scan. OK
Connect to the peripheral with saved id. OK
Find the services / Characteristics. DOES NOT WORK NEVER MORE.
After step 4 if i repeat steps 1,2 and 3 they will not find services, the problem is when I restart the peripheral.
I'm setting the self.manager.delegate=self and implementing CBCentralManagerDelegate and CBPeripheralDelegate correctly, and I'm using self.manager.retrievePeripherals (withIdentifiers: [UUID]) to connect to the paired peripheral.
Any idea? I will be very grateful.

Disconnect time for iOS BLE

I've noticed that when you disconnect for a bluetooth device in an application the iOS device will continue to hold that connection for around 10 seconds. I've attempted to get around this by writing to a characteristic that causes the bluetooth module to cancel the connection with the iOS device instead but that isn't working (mostly because I changed the module and the iOS doesn't see the change because I assume the device is cached somewhere). Is there a way to make it disconnect instantly in code? I am using the swift command
manager.cancelPeripheralConnection(peripheral) currently.
Unfortunately, there isn't. The only way to tell the system to disconnect a peripheral is via the cancelPeripheralConnection method that you are already using. Yet, if you call this method it doesn't necessarily mean that the peripheral will be disconnect.
Background
On iOS the whole BLE connection management is maintained by the operating system. That means that no single application "owns" a connection. All BLE functionality is multiplexed to allow more than one application to gain access to centrals and peripherals.
For example, if you have installed a fitness application that tracks data from your heart rate sensor in the background then you can also "connect" to the heart rate sensor in your app but you will be unable to trigger a real disconnect as long as the fitness app maintains a connection.
The disconnect delay you have noticed is basically an optimization of the operating system. If no application holds a connection to the peripheral anymore it will wait for some time (to avoid unnecessary connect/disconnect cycles) and then trigger the disconnect on the bluetooth chip.
Hope that helps.
In iOS when you call the CBCentralManager method cancelPeripheralConnection(CBPeripheral), it does not always immediately terminate the connection. As Apple's documentation states:
Because other apps may still have a connection to the peripheral, canceling
a local connection does not guarantee that the underlying physical link is
immediately disconnected. From the app’s perspective, however, the
peripheral is considered disconnected, and the central manager object calls
the centralManager:didDisconnectPeripheral:error: method of its delegate
object.
If you have a need to immediately terminate a connection programmatically, say to free up the peripheral to be connected from another central device or to reset one's own security layer, then you need to follow the procedure described in the following StackOverflow thread:
iOS 6 - Bluetooth LE disconnect
which is for the app to send your own proprietary command to the peripheral that tells the peripheral to disconnect through normal means (e.g. "GAPRole_TerminateConnection" or "GAP_TerminateLinkReq" or "LL_Disconnect" or "HCI_Disconnect[_*]" with reason HCI_DISCONNECT_REMOTE_USER_TERM). This always works and is not delayed by the connection supervision timeout because it is a formal disconnection notifying the central device (i.e. iOS). The supervision timeout (up to 6 seconds in iOS; on Android the default is 20 seconds) only comes into play if the disconnection is unplanned as with going out of range or if the peripheral does a disconnect without notifying the remote device as with "LL_EXT_DisconnectImmed" (only available in some BLE peripheral implementations).

CoreBluetooth:Disconnect peripheral Connection from application

My application related to bluetooth communication with the peripheral device.Every functionality is working fine right from discovering to connecting .While coming to disconnecting the peripheral from the application i have written code like this
-(void) disconnect
{
if (_selectedPeripheral != nil &&
_selectedPeripheral.state != CBPeripheralStateDisconnected)
{
NSLog(#"Peripheral disconnecting");
[_centralManager cancelPeripheralConnection:_selectedPeripheral];
_selectedPeripheral = nil;
}
}
When i click button this above method is calling and app showing that peripheral is disconnected and when i came out of the application and look into settings /bluetooth/ .Peripheral is showing connected.How to stop connection the peripheral in the device level i.e in the settings .Please help me with the proper solution.
You are unable to guarantee a system level disconnect from the peripheral.
This is a link directly from the CBCentralManager documentation:
cancelPeripheralConnection:
Discussion
This method is nonblocking, and any CBPeripheral class
commands that are still pending to peripheral may or may not complete.
Because other apps may still have a connection to the peripheral,
canceling a local connection does not guarantee that the underlying
physical link is immediately disconnected. From the app’s perspective,
however, the peripheral is considered disconnected, and the central
manager object calls the centralManager:didDisconnectPeripheral:error:
method of its delegate object.
In my experience the physical link is disconnected quickly if you are the only application using the peripheral, but if you potentially are not as Apple clearly states there is a potential for other applications to be maintaining a persisted connection which would cause the physical link to not disconnect even though it is stating to you it has.
We were facing the same issue but we managed to workaround this nasty bug (or API design flaw) by using
Objective C
[peripheral writeValue:x forCharacteristic:y type:CBCharacteristicWriteWithResponse];
Swift
peripheral.writeValue(x, for: y, type: .withResponse)
It's strange that iOS doesn't cancel the physical connection to the peripheral we implemented in the peripheral to perform the disconnect, so we send a string indicating a disconnection should happen.
We used
Objective C
[peripheral writeValue:x forCharacteristic:y type:CBCharacteristicWriteWithoutResponse];
Swift
peripheral.writeValue(x, for: y, type: .withResponse)
and the peripheral disconnects as expected.
Hope this helps anyone facing the same issue by this CoreBluetooth API flaw.
x is the specific cmd supported in your peripheral device (i.e Firmware)
y is the specific characteristic you want to send the value
I know this is an old thread, but I figured I'd add a potential solution here for others.
What you could do is issue a command that causes the peripheral to reboot, resetting the Bluetooth connection. If your device has such a command that you can issue through Bluetooth, you're in luck, otherwise, you'll need access to the firmware for the peripheral in order to add a new command that does this. I'm not a firmware guy, so I can't tell you what exactly you need to do; all I know is the device I'm working with has such a command (it is a proprietary command specifically for our device, not part of the Bluetooth protocol) and that allowed the disconnect to be guaranteed as long as I issue it before calling cancelPeripheralConnection.

What, exactly, is a BLE connected device on iOS?

The CBCentralManager retrieveConnectedPeripherals method says it gets "the list of the peripherals currently connected to the system." The definition of system is a bit ambiguous here.
Does this mean I get a list of peripherals connected to my app, or a list of peripherals connected to any app?
If I can get peripherals connected to another app, does this also mean multiple apps can connect to the same peripheral?
Can this only happen if the app is in the foreground, or do I need to allow for the possibility that a background app is sending commands to a peripheral I think my app owns?
BLE 4.0 enabled devices are usually connected with CBCentralManager unboundly. What is bounded and unbounded connection, you can know from this link.
One BLE 4.0 enabled device can be connected with only one master device thus enhancing secured connectivity. You should follow this link.
Whether in foreground of background, if the connection exists, the BLE slave device won't get connected with another app or device.

Resources