1

I'm building several BLE apps, and have encountered this problem with my BLE protocols as well as external vendors. For the most part, BLE works as intended, but sometimes it will fail to discover services for a specific peripheral and will not work again until I restart or reset my phone.

Has anyone else experienced this problem?

When I'm done with my peripheral, the manager will call the closePeripheralConnection method. The relevant code:

// Disconnect from peripheral
- (void)closePeripheralConnection
{
    NSLog(@"== closePeripheralConnection ==");
    // If the peripheral is connected
    if (self.peripheral.state == CBPeripheralStateConnected && self.peripheral != nil) {
        // Cancel connection
        [self.manager cancelPeripheralConnection:self.peripheral];
    } else {
        [self clearPeripheralSettings];
    }
}

// Clear peripheral settings
- (void)clearPeripheralSettings
{
    // Clear peripheral variables
    self.peripheral = 0;
    // Clear services
    self.service = 0;
    // Clear characteristic values
    self.data = 0;
    self.notifyCharacteristic = 0;
}

- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
    [self clearPeripheralSettings];
}
abriggs
  • 744
  • 7
  • 16
  • Please describe your usage scenarios in more detail. The iOS BLE stack, however, easily can get in the "limbo" and stop working completely. – allprog Oct 29 '13 at 23:34
  • @allprog As I'm developing, I'm connecting/disconnecting my peripheral often. The peripheral contains changing data that it feeds the app when the user initiates the connection from the peripheral. The manager (an object in one view of my app) will keep the session with the peripheral until it is done receiving the data. At this point, I cancel the connection and perform a minor cleanup. Please see my updated question for how the manager tears down the session. – abriggs Oct 30 '13 at 12:14
  • @abriggs: Did you got solution for above problem? – Arun Gupta May 08 '17 at 15:51
  • @ArunGupta at the time, I was given a BLE debugging profile from Apple. The tool never revealed what the underlying issue was. The problem was intermittent and the BLE technology was pretty new. Additionally, the manufacturer of the device had a poor understanding of Apple's implementation. Granted, this was back in 2013. Assuming you are working against iOS 10+, you will want to refer to the current official docs https://developer.apple.com/reference/corebluetooth. Scroll to the bottom of the API reference for an official guide. – abriggs May 10 '17 at 22:01

2 Answers2

2

Based on the code and your comment you are not doing anything bad. It's still the instability of the Core Bluetooth framework that hinders your work. With iOS 6 such issues were more common than with iOS 7 but serious stress can still blow things up. The Apple Developer Forum and the bluetooth-dev mailing list is full of similar reports. If the kind of usage you do while testing is not common for every day usage, then the problem may not be so relevant for end users. (Though still annoying for sure.)

I suggest you try to collect statistics. Register the number of times you call each API and try to establish some proof for Apple to show that the framework is still unstable. Storing the stats in NSUserDefaults may be the easiest solution.

Anyway if you have strong data that can serve as evidence for malfunction, then report the bug to Apple, post in the developer forum, send mail to the bluetooth-dev list. Make your sound be heard by as many people as possible.

allprog
  • 16,540
  • 9
  • 56
  • 97
  • 1
    +1, thanks for the advice. It's a shame that Apple still cannot get BLE working properly. At the very least, they should give us the ability to have more control over the BLE stack. I did not mark your answer as accepted yet since I am optimistically looking for a possible solution, but if further consensus proves no solution, I will give you props. – abriggs Oct 30 '13 at 13:25
  • I've been poking around with BLE for quite a while (ever since it became available) and I would be the happiest if you could find any alternative solution. – allprog Oct 30 '13 at 14:06
  • Cool. Well, I used one of my TSI with Apple. I'll update when they get back to me. – abriggs Oct 30 '13 at 15:51
  • Apple got back to me last night with a CoreBluetooth Diagnostic Mode profile for debugging the problem. It's supposed to log any problems BLE encounters, so I'll have to wait till this bug happens again. Just to confirm, Apple speculates that this is a bug in CoreBluetooth. I'll update once Apple replies to my bug report. As the issue sporadically happens, I probably won't have any updates for a while. – abriggs Oct 31 '13 at 15:57
  • Is the profile distributable? The more people collect data, the better, isn't it? Or we should simply suggest others to duplicate your request? – allprog Oct 31 '13 at 16:04
  • With or without the profile you would still need to open a ticket to talk with someone from Apple. I'll try to sort this problem out, but anyone else experiencing this issue should open a TSI through their [iOS dev center](https://developer.apple.com). – abriggs Oct 31 '13 at 16:46
  • This might be a dumb question, but is their a way to check programatically when the BLE stack crashed so I can push users to restart their phone? – Gilles Lesire Jul 10 '14 at 08:27
  • @GillesLesire You can build some heuristics but there is no definitive way to detect it. A heuristic can be, for example, that the after the connected callback, you receive an immediate disconnect for other reasons than time out. If this happens 3-4 times in a row you can be sure that something went wrong as the peripheral is available and you suppose it is operable too. You can probably elaborate similar symptoms and create your own logic to detect those. – allprog Jul 10 '14 at 11:26
0

When do you call this method? - closePeripheralConnection

You might probably want to add this to ask for the peripheral to discover its services upon its connection in one the the central manager callback delegates

- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {

    NSLog(@"peripheral: %@ state: %@", peripheral.name, peripheral.state == CBPeripheralStateConnected ? @"Connected" : @"Disconnected");

    if (peripheral.state == CBPeripheralStateConnected) {
        peripheral.delegate = self;
        [peripheral discoverServices:nil];
    }

}
eNeF
  • 3,241
  • 2
  • 18
  • 41