Is there a way to discover BLE peripheral service faster?
Asked Answered
H

2

5

I find that my implementation of the BLE protocol in iOS7 to be very slow in the start up phase. The startup sequence amounts to ~68% of the whole execution time in my app.

What can I do to make it faster?

I've timed it, and here's what I get.

     t     dt   
37.598          [BLE] Discovered peripheral at RSSI -27 with UUID:XYZ
37.599  0.001   [BLE] Connecting to peripheral                                                                            
37.602  0.003   [BLE] Scanning stopped                                                                                           
37.685  0.083   [BLE] Peripheral connected                                                                                
38.48   0.795   [BLE] Discovered service  
38.599  0.119   [BLE] Discovered characteristic    

As you can see there's a huge bottle neck before discovering the service.

My startup code simplified:

- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
    switch (central.state) {
        case CBCentralManagerStatePoweredOn:
            [central scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:kServiceUuid]]
                                            options:@{CBCentralManagerScanOptionAllowDuplicatesKey : @YES}];
            break;
        case CBCentralManagerStatePoweredOff:
            [central stopScan];
            break;
        default:
            break;
    }
}

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
    if (self.discoveredPeripheral != peripheral) {
        self.discoveredPeripheral = peripheral; // Save a local copy of the peripheral, so CoreBluetooth doesn't get rid of it
        [central connectPeripheral:peripheral options:nil];
        [central stopScan];
    }
}

- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
    [peripheral discoverServices:@[[CBUUID UUIDWithString:kServiceUuid]]];
}

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
    for (CBService *service in peripheral.services) {
        [peripheral discoverCharacteristics:@[array of characteristics]
                                 forService:service];
    }
}

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error {
    ...
}

EDIT

I've learned that similar apps on Android does this ten times faster (making the Android app feel snappier -> better user experience) so I'm curious if it's my implementation, BLE layer or hardware that's the bottleneck. It's tested on an iPhone 4S.

Hubblebubble answered 16/10, 2013 at 13:16 Comment(5)
I am curious on how long did you take to discover the peripheral. My guess is the time for discovering peripherals and theirs services is related to their hardware implementation.Hume
In my experience that peripherals which advertise itself at a higher rate will take shorter time for discovering services. Maybe coincidence though, as I have got only a few peripherals to play with. Also the longest time I take to discover services of a peripheral is ~0.5s, which is acceptable for me.Hume
I've tested again two completely different (hardware wise) peripherals and the results are the same (give or take 50 ms). I'm not sure how to measure the time before discovering the peripheral? Still the delta time between discover peripheral and discover service is pretty significant as it makes the app feel more sluggish than it could be.Hubblebubble
what type of devices you used..? i tried with CiragoBLE BT8000 dongle.. but it's not detecting.. Please list me some bluetooth dongle for detecting in ios. Thanks in advance!Baxley
I'm not using a dongle, I'm using a separate BLE peripheral built specifically to communicate with BLE devices (not only iOS devices). Have you tried detecting your dongle using LightBlue? itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/…Hubblebubble
G
4

When you encrypt the connection, iOS should cache the GATT database. Therefore, subsequent discovery calls after the first one should happen instantaneously.

Since iOS 7, even characteristic values are cached, meaning that you can read static values like a "Device name" through the characteristic's value property. If you want to update them, you still have to issue a Read Characteristic Value request.

For details regarding the caching behavior, check WWDC 2013 session 703 from slide 48 (should probably watch the corresponding part in the video).

For connection and discovery time, it's mainly the advertisement interval. There are a couple of advertisement intervals that are recommended by Apple for best performance in the Bluetooth Accessory Design Guidelines For Apple Products (section 3.5 Advertising Interval). Also, you should disable scanning when you connect, as scanning slows down the connection process by about 55x.

Note that the iOS based limitations on the number of packets sent per connection event should not affect discovery time noticeably (unless you have a giant GATT database and are querying the whole thing). Those limitations should only become visible for "Write Without Response" and "Characteristic Value Notification", as per the LE protocol design.

Gobbledegook answered 26/10, 2013 at 11:58 Comment(2)
The links you posted of WWDC 2013 session 703 is broken, update it for this one: developer.apple.com/videos/wwdc/2013/?id=703Racemose
@Gobbledegook Are you able to cite a source for this statement Also, you should disable scanning when you connect, as scanning slows down the connection process by about 55x? I would like to learn more from the source materialMinard
B
1

There's no framework-level API to improve the discovery speed. BTLE is co-existing with Classic Bluetooth (at the system framework level) and Wi-Fi (at the antenna level), so the maximum time on antenna is limited by the system.

Beestings answered 24/10, 2013 at 1:41 Comment(2)
So this is hardware dependant then? Then that would explain the quicker Android application.Hubblebubble
More or less, yes. I imagine that across Android phones you may see some variability in responsiveness as well: different chipsets and antenna layouts will dictate different coexistence requirements.Beestings

© 2022 - 2024 — McMap. All rights reserved.