简体   繁体   中英

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 (eg "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 (ie 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).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM