dev
dev

Reputation: 65

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.

Upvotes: 4

Views: 13487

Answers (3)

Rizwan Mehboob
Rizwan Mehboob

Reputation: 1373

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

Upvotes: 2

tayoung
tayoung

Reputation: 463

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.

Upvotes: 1

Robert Haworth
Robert Haworth

Reputation: 448

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.

Upvotes: 8

Related Questions